mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +00:00
The VFAT filesystem driver now goes through the cache for reads, writing
is disabled. svn path=/trunk/; revision=1490
This commit is contained in:
parent
9e386e114c
commit
240c9da1da
10 changed files with 438 additions and 84 deletions
|
@ -27,7 +27,7 @@ NTSTATUS MinixRequestCacheBlock(PDEVICE_OBJECT DeviceObject,
|
|||
{
|
||||
BOOLEAN UptoDate;
|
||||
|
||||
CcRequestCachePage(Bcb,
|
||||
CcRequestCacheSegment(Bcb,
|
||||
FileOffset,
|
||||
BaseAddress,
|
||||
&UptoDate,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: create.c,v 1.10 2000/12/29 23:17:12 dwelch Exp $
|
||||
/* $Id: create.c,v 1.11 2001/01/01 04:42:11 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -392,6 +392,7 @@ FsdOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
|||
short i, j;
|
||||
PLIST_ENTRY current_entry;
|
||||
KIRQL oldIrql;
|
||||
ULONG BytesPerCluster;
|
||||
|
||||
DPRINT ("FsdOpenFile(%08lx, %08lx, %S)\n", DeviceExt, FileObject, FileName);
|
||||
|
||||
|
@ -579,7 +580,17 @@ FsdOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
|||
vfat_wcsncpy (ParentFcb->PathName, FileName, MAX_PATH);
|
||||
ParentFcb->ObjectName = ParentFcb->PathName + (current - FileName);
|
||||
ParentFcb->pDevExt = DeviceExt;
|
||||
Status = CcInitializeFileCache(FileObject, &ParentFcb->RFCB.Bcb);
|
||||
BytesPerCluster = DeviceExt->Boot->SectorsPerCluster * BLOCKSIZE;
|
||||
if (BytesPerCluster >= PAGESIZE)
|
||||
{
|
||||
Status = CcInitializeFileCache(FileObject, &ParentFcb->RFCB.Bcb,
|
||||
BytesPerCluster);
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = CcInitializeFileCache(FileObject, &ParentFcb->RFCB.Bcb,
|
||||
PAGESIZE);
|
||||
}
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DbgPrint("CcInitializeFileCache failed\n");
|
||||
|
@ -642,10 +653,14 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
|| RequestedDisposition == FILE_SUPERSEDE)
|
||||
{
|
||||
CHECKPOINT;
|
||||
#if 0
|
||||
Status =
|
||||
addEntry (DeviceExt, FileObject, RequestedOptions,
|
||||
(Stack->Parameters.
|
||||
Create.FileAttributes & FILE_ATTRIBUTE_VALID_FLAGS));
|
||||
#else
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
#endif
|
||||
if (NT_SUCCESS (Status))
|
||||
Irp->IoStatus.Information = FILE_CREATED;
|
||||
/* FIXME set size if AllocationSize requested */
|
||||
|
@ -677,7 +692,7 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
Cluster = pFcb->entry.FirstCluster;
|
||||
pFcb->entry.FirstCluster = 0;
|
||||
pFcb->entry.FirstClusterHigh = 0;
|
||||
updEntry (DeviceExt, FileObject);
|
||||
// updEntry (DeviceExt, FileObject);
|
||||
while (Cluster != 0xffffffff && Cluster > 1)
|
||||
{
|
||||
NextCluster = GetNextCluster (DeviceExt, Cluster);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: dirwr.c,v 1.14 2000/12/29 23:17:12 dwelch Exp $
|
||||
/* $Id: dirwr.c,v 1.15 2001/01/01 04:42:11 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "vfat.h"
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Copies a file name into a directory slot (long file name entry)
|
||||
* and fills trailing slot space with 0xFFFF. This keeps scandisk
|
||||
|
@ -458,5 +458,6 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
|
|||
DPRINT ("addentry ok\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: iface.c,v 1.45 2000/12/29 23:17:12 dwelch Exp $
|
||||
/* $Id: iface.c,v 1.46 2001/01/01 04:42:11 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -91,10 +91,23 @@ VfatMountDevice (PDEVICE_EXTENSION DeviceExt, PDEVICE_OBJECT DeviceToMount)
|
|||
DeviceExt->FATEntriesPerSector = DeviceExt->Boot->BytesPerSector / 32;
|
||||
DeviceExt->BytesPerCluster = DeviceExt->Boot->SectorsPerCluster *
|
||||
DeviceExt->Boot->BytesPerSector;
|
||||
|
||||
if (DeviceExt->BytesPerCluster >= PAGESIZE &&
|
||||
(DeviceExt->BytesPerCluster % PAGESIZE) != 0)
|
||||
{
|
||||
DbgPrint("Invalid cluster size\n");
|
||||
KeBugCheck(0);
|
||||
}
|
||||
else if (DeviceExt->BytesPerCluster < PAGESIZE &&
|
||||
(PAGESIZE % DeviceExt->BytesPerCluster) != 0)
|
||||
{
|
||||
DbgPrint("Invalid cluster size2\n");
|
||||
KeBugCheck(0);
|
||||
}
|
||||
|
||||
if (strncmp (DeviceExt->Boot->SysType, "FAT12", 5) == 0)
|
||||
{
|
||||
DeviceExt->FatType = FAT12;
|
||||
DeviceExt->FatType = FAT12;
|
||||
}
|
||||
else
|
||||
if (strncmp
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: makefile,v 1.24 2000/12/29 13:45:01 ekohl Exp $
|
||||
# $Id: makefile,v 1.25 2001/01/01 04:42:12 dwelch Exp $
|
||||
#
|
||||
#
|
||||
PATH_TO_TOP = ../../..
|
||||
|
@ -9,7 +9,7 @@ OBJECTS = blockdev.o close.o create.o dir.o dirwr.o iface.o string.o fat.o \
|
|||
rw.o finfo.o volume.o shutdown.o $(TARGET).coff
|
||||
LIBS = ../../../ntoskrnl/ntoskrnl.a
|
||||
|
||||
CFLAGS =
|
||||
CFLAGS = -g
|
||||
|
||||
all: $(TARGET).nostrip.sys $(TARGET).sys
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: rw.c,v 1.12 2000/12/29 23:17:12 dwelch Exp $
|
||||
/* $Id: rw.c,v 1.13 2001/01/01 04:42:12 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -19,11 +19,42 @@
|
|||
|
||||
#include "vfat.h"
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
|
||||
#define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
ULONG
|
||||
OffsetToCluster(PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG FirstCluster,
|
||||
ULONG FileOffset)
|
||||
{
|
||||
ULONG CurrentCluster;
|
||||
ULONG i;
|
||||
|
||||
CurrentCluster = FirstCluster;
|
||||
if (FirstCluster == 1)
|
||||
{
|
||||
/* root of FAT16 or FAT12 */
|
||||
CurrentCluster = DeviceExt->rootStart + FileOffset
|
||||
/ (DeviceExt->BytesPerCluster) * DeviceExt->Boot->SectorsPerCluster;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < FileOffset / DeviceExt->BytesPerCluster; i++)
|
||||
{
|
||||
CurrentCluster = GetNextCluster (DeviceExt, CurrentCluster);
|
||||
}
|
||||
}
|
||||
return(CurrentCluster);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||
PVOID Buffer, ULONG Length, ULONG ReadOffset, PULONG LengthRead)
|
||||
VfatReadFileNoCache (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||
PVOID Buffer, ULONG Length, ULONG ReadOffset,
|
||||
PULONG LengthRead)
|
||||
/*
|
||||
* FUNCTION: Reads data from a file
|
||||
*/
|
||||
|
@ -45,15 +76,21 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
|||
"Length %d, ReadOffset %d)\n", DeviceExt, FileObject, Buffer,
|
||||
Length, ReadOffset);
|
||||
|
||||
Fcb = ((PVFATCCB) (FileObject->FsContext2))->pFcb;
|
||||
Fcb = ((PVFATCCB)FileObject->FsContext2)->pFcb;
|
||||
|
||||
/*
|
||||
* Find the first cluster
|
||||
*/
|
||||
if (DeviceExt->FatType == FAT32)
|
||||
CurrentCluster = Fcb->entry.FirstCluster
|
||||
CurrentCluster = Fcb->entry.FirstCluster
|
||||
+ Fcb->entry.FirstClusterHigh * 65536;
|
||||
else
|
||||
CurrentCluster = Fcb->entry.FirstCluster;
|
||||
FirstCluster = CurrentCluster;
|
||||
DPRINT ("DeviceExt->BytesPerCluster %x\n", DeviceExt->BytesPerCluster);
|
||||
|
||||
|
||||
/*
|
||||
* Truncate the read if necessary
|
||||
*/
|
||||
if (!(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
if (ReadOffset >= Fcb->entry.FileSize)
|
||||
|
@ -65,14 +102,25 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
|||
Length = Fcb->entry.FileSize - ReadOffset;
|
||||
}
|
||||
}
|
||||
CHECKPOINT;
|
||||
|
||||
|
||||
*LengthRead = 0;
|
||||
/* FIXME: optimize by remembering the last cluster read and using if possible */
|
||||
|
||||
/*
|
||||
* Allocate a buffer to hold partial clusters
|
||||
*/
|
||||
Temp = ExAllocatePool (NonPagedPool, DeviceExt->BytesPerCluster);
|
||||
if (!Temp)
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
|
||||
/*
|
||||
* Find the cluster to start the read from
|
||||
* FIXME: Optimize by remembering the last cluster read and using if
|
||||
* possible.
|
||||
*/
|
||||
if (FirstCluster == 1)
|
||||
{ //root of FAT16 or FAT12
|
||||
{
|
||||
/* root of FAT16 or FAT12 */
|
||||
CurrentCluster = DeviceExt->rootStart + ReadOffset
|
||||
/ (DeviceExt->BytesPerCluster) * DeviceExt->Boot->SectorsPerCluster;
|
||||
}
|
||||
|
@ -82,7 +130,11 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
|||
{
|
||||
CurrentCluster = GetNextCluster (DeviceExt, CurrentCluster);
|
||||
}
|
||||
CHECKPOINT;
|
||||
|
||||
/*
|
||||
* If the read doesn't begin on a cluster boundary then read a full
|
||||
* cluster and copy it.
|
||||
*/
|
||||
if ((ReadOffset % DeviceExt->BytesPerCluster) != 0)
|
||||
{
|
||||
if (FirstCluster == 1)
|
||||
|
@ -154,6 +206,270 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
|||
return (STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
VfatRawReadCluster (PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG FirstCluster,
|
||||
PULONG CurrentCluster,
|
||||
PVOID Destination)
|
||||
{
|
||||
if (FirstCluster == 1)
|
||||
{
|
||||
VFATReadSectors (DeviceExt->StorageDevice,
|
||||
(*CurrentCluster),
|
||||
DeviceExt->Boot->SectorsPerCluster,
|
||||
Destination);
|
||||
(*CurrentCluster) += DeviceExt->Boot->SectorsPerCluster;
|
||||
}
|
||||
else
|
||||
{
|
||||
VFATLoadCluster (DeviceExt, Destination, (*CurrentCluster));
|
||||
(*CurrentCluster) = GetNextCluster (DeviceExt, (*CurrentCluster));
|
||||
}
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
VfatReadCluster(PDEVICE_EXTENSION DeviceExt,
|
||||
PVFATFCB Fcb,
|
||||
ULONG StartOffset,
|
||||
ULONG FirstCluster,
|
||||
PULONG CurrentCluster,
|
||||
PVOID Destination,
|
||||
ULONG Cached)
|
||||
{
|
||||
ULONG BytesPerCluster;
|
||||
BOOLEAN Valid;
|
||||
PVOID BaseAddress;
|
||||
PCACHE_SEGMENT CacheSeg;
|
||||
NTSTATUS Status;
|
||||
|
||||
BytesPerCluster = DeviceExt->Boot->SectorsPerCluster * BLOCKSIZE;
|
||||
|
||||
if (BytesPerCluster >= PAGESIZE)
|
||||
{
|
||||
/*
|
||||
* In this case the size of a cache segment is the same as a cluster
|
||||
*/
|
||||
Status = CcRequestCacheSegment(Fcb->RFCB.Bcb,
|
||||
StartOffset,
|
||||
&BaseAddress,
|
||||
&Valid,
|
||||
&CacheSeg);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
if (!Valid)
|
||||
{
|
||||
/*
|
||||
* If necessary read the cluster from the disk
|
||||
*/
|
||||
Status = VfatRawReadCluster(DeviceExt, FirstCluster, CurrentCluster,
|
||||
BaseAddress);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, FALSE);
|
||||
return(Status);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Otherwise go on to the next cluster
|
||||
*/
|
||||
if (FirstCluster == 1)
|
||||
{
|
||||
(*CurrentCluster) += DeviceExt->Boot->SectorsPerCluster;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*CurrentCluster) = GetNextCluster(DeviceExt, (*CurrentCluster));
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copy the data from the cache to the caller
|
||||
*/
|
||||
memcpy(Destination, BaseAddress, BytesPerCluster);
|
||||
CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ULONG i;
|
||||
ULONG ReadOffset;
|
||||
ULONG InternalOffset;
|
||||
|
||||
ReadOffset = ROUND_DOWN(StartOffset, PAGESIZE);
|
||||
InternalOffset = StartOffset % PAGESIZE;
|
||||
Status = CcRequestCacheSegment(Fcb->RFCB.Bcb,
|
||||
ReadOffset,
|
||||
&BaseAddress,
|
||||
&Valid,
|
||||
&CacheSeg);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
/*
|
||||
* If necessary read all the data for the page
|
||||
*/
|
||||
if (!Valid)
|
||||
{
|
||||
ULONG StartCluster;
|
||||
|
||||
StartCluster = OffsetToCluster(DeviceExt, FirstCluster, ReadOffset);
|
||||
|
||||
for (i = 0; i < (PAGESIZE / BytesPerCluster); i++)
|
||||
{
|
||||
Status = VfatRawReadCluster(DeviceExt,
|
||||
FirstCluster,
|
||||
&StartCluster,
|
||||
BaseAddress + (i * BytesPerCluster));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, FALSE);
|
||||
return(Status);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Go on to the next cluster
|
||||
*/
|
||||
if (FirstCluster == 1)
|
||||
{
|
||||
(*CurrentCluster) += DeviceExt->Boot->SectorsPerCluster;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*CurrentCluster) = GetNextCluster(DeviceExt, (*CurrentCluster));
|
||||
}
|
||||
/*
|
||||
* Copy the data from the cache to the caller
|
||||
*/
|
||||
memcpy(Destination, BaseAddress + InternalOffset, BytesPerCluster);
|
||||
CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, TRUE);
|
||||
}
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||
PVOID Buffer, ULONG Length, ULONG ReadOffset,
|
||||
PULONG LengthRead)
|
||||
/*
|
||||
* FUNCTION: Reads data from a file
|
||||
*/
|
||||
{
|
||||
ULONG CurrentCluster;
|
||||
ULONG FileOffset;
|
||||
ULONG FirstCluster;
|
||||
PVFATFCB Fcb;
|
||||
PVOID Temp;
|
||||
ULONG TempLength;
|
||||
|
||||
/* PRECONDITION */
|
||||
assert (DeviceExt != NULL);
|
||||
assert (DeviceExt->BytesPerCluster != 0);
|
||||
assert (FileObject != NULL);
|
||||
assert (FileObject->FsContext != NULL);
|
||||
|
||||
DPRINT ("FsdReadFile(DeviceExt %x, FileObject %x, Buffer %x, "
|
||||
"Length %d, ReadOffset %d)\n", DeviceExt, FileObject, Buffer,
|
||||
Length, ReadOffset);
|
||||
|
||||
Fcb = ((PVFATCCB)FileObject->FsContext2)->pFcb;
|
||||
|
||||
/*
|
||||
* Find the first cluster
|
||||
*/
|
||||
if (DeviceExt->FatType == FAT32)
|
||||
CurrentCluster = Fcb->entry.FirstCluster
|
||||
+ Fcb->entry.FirstClusterHigh * 65536;
|
||||
else
|
||||
CurrentCluster = Fcb->entry.FirstCluster;
|
||||
FirstCluster = CurrentCluster;
|
||||
|
||||
/*
|
||||
* Truncate the read if necessary
|
||||
*/
|
||||
if (!(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
if (ReadOffset >= Fcb->entry.FileSize)
|
||||
{
|
||||
return (STATUS_END_OF_FILE);
|
||||
}
|
||||
if ((ReadOffset + Length) > Fcb->entry.FileSize)
|
||||
{
|
||||
Length = Fcb->entry.FileSize - ReadOffset;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
*LengthRead = 0;
|
||||
|
||||
/*
|
||||
* Allocate a buffer to hold partial clusters
|
||||
*/
|
||||
Temp = ExAllocatePool (NonPagedPool, DeviceExt->BytesPerCluster);
|
||||
if (!Temp)
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
|
||||
/*
|
||||
* Find the cluster to start the read from
|
||||
* FIXME: Optimize by remembering the last cluster read and using if
|
||||
* possible.
|
||||
*/
|
||||
CurrentCluster = OffsetToCluster(DeviceExt, FirstCluster, ReadOffset);
|
||||
|
||||
/*
|
||||
* If the read doesn't begin on a cluster boundary then read a full
|
||||
* cluster and copy it.
|
||||
*/
|
||||
if ((ReadOffset % DeviceExt->BytesPerCluster) != 0)
|
||||
{
|
||||
VfatReadCluster(DeviceExt, Fcb,
|
||||
ROUND_DOWN(ReadOffset, DeviceExt->BytesPerCluster),
|
||||
FirstCluster, &CurrentCluster, Temp, 1);
|
||||
TempLength = min (Length, DeviceExt->BytesPerCluster -
|
||||
(ReadOffset % DeviceExt->BytesPerCluster));
|
||||
|
||||
memcpy (Buffer, Temp + ReadOffset % DeviceExt->BytesPerCluster,
|
||||
TempLength);
|
||||
|
||||
(*LengthRead) = (*LengthRead) + TempLength;
|
||||
Length = Length - TempLength;
|
||||
Buffer = Buffer + TempLength;
|
||||
ReadOffset = ReadOffset + TempLength;
|
||||
}
|
||||
|
||||
while (Length >= DeviceExt->BytesPerCluster)
|
||||
{
|
||||
VfatReadCluster(DeviceExt, Fcb, ReadOffset,
|
||||
FirstCluster, &CurrentCluster, Buffer, 1);
|
||||
if (CurrentCluster == 0xffffffff)
|
||||
{
|
||||
ExFreePool (Temp);
|
||||
return (STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
(*LengthRead) = (*LengthRead) + DeviceExt->BytesPerCluster;
|
||||
Buffer = Buffer + DeviceExt->BytesPerCluster;
|
||||
Length = Length - DeviceExt->BytesPerCluster;
|
||||
ReadOffset = ReadOffset + DeviceExt->BytesPerCluster;
|
||||
}
|
||||
|
||||
if (Length > 0)
|
||||
{
|
||||
VfatReadCluster(DeviceExt, Fcb, ReadOffset,
|
||||
FirstCluster, &CurrentCluster, Temp, 1);
|
||||
(*LengthRead) = (*LengthRead) + Length;
|
||||
memcpy (Buffer, Temp, Length);
|
||||
}
|
||||
ExFreePool (Temp);
|
||||
return (STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
#if 0
|
||||
NTSTATUS
|
||||
VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||
PVOID Buffer, ULONG Length, ULONG WriteOffset)
|
||||
|
@ -361,6 +677,7 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
|||
ExFreePool (Temp);
|
||||
return (STATUS_SUCCESS);
|
||||
}
|
||||
#endif
|
||||
|
||||
NTSTATUS STDCALL
|
||||
VfatWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
|
@ -382,7 +699,8 @@ VfatWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
|
||||
Offset = Stack->Parameters.Write.ByteOffset.u.LowPart;
|
||||
|
||||
Status = VfatWriteFile (DeviceExt, FileObject, Buffer, Length, Offset);
|
||||
/* Status = VfatWriteFile (DeviceExt, FileObject, Buffer, Length, Offset); */
|
||||
Status = STATUS_MEDIA_WRITE_PROTECTED;
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = Length;
|
||||
|
|
|
@ -1,54 +1,44 @@
|
|||
#ifndef __INCLUDE_DDK_NTIFS_H
|
||||
#define __INCLUDE_DDK_NTIFS_H
|
||||
|
||||
#if 0
|
||||
typedef struct
|
||||
{
|
||||
BOOLEAN Replace;
|
||||
HANDLE RootDir;
|
||||
ULONG FileNameLength;
|
||||
WCHAR FileName[1];
|
||||
} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION;
|
||||
#endif
|
||||
|
||||
typedef struct _BCB
|
||||
{
|
||||
LIST_ENTRY CacheSegmentListHead;
|
||||
PFILE_OBJECT FileObject;
|
||||
KSPIN_LOCK BcbLock;
|
||||
LIST_ENTRY CacheSegmentListHead;
|
||||
PFILE_OBJECT FileObject;
|
||||
KSPIN_LOCK BcbLock;
|
||||
ULONG CacheSegmentSize;
|
||||
} BCB, *PBCB;
|
||||
|
||||
#define CACHE_SEGMENT_SIZE (0x1000)
|
||||
|
||||
struct _MEMORY_AREA;
|
||||
|
||||
typedef struct _CACHE_SEGMENT
|
||||
{
|
||||
PVOID BaseAddress;
|
||||
struct _MEMORY_AREA* MemoryArea;
|
||||
BOOLEAN Valid;
|
||||
LIST_ENTRY ListEntry;
|
||||
ULONG FileOffset;
|
||||
KEVENT Lock;
|
||||
ULONG ReferenceCount;
|
||||
PBCB Bcb;
|
||||
PVOID BaseAddress;
|
||||
struct _MEMORY_AREA* MemoryArea;
|
||||
BOOLEAN Valid;
|
||||
LIST_ENTRY ListEntry;
|
||||
ULONG FileOffset;
|
||||
KEVENT Lock;
|
||||
ULONG ReferenceCount;
|
||||
PBCB Bcb;
|
||||
} CACHE_SEGMENT, *PCACHE_SEGMENT;
|
||||
|
||||
NTSTATUS STDCALL
|
||||
CcFlushCachePage (PCACHE_SEGMENT CacheSeg);
|
||||
CcFlushCacheSegment (PCACHE_SEGMENT CacheSeg);
|
||||
NTSTATUS STDCALL
|
||||
CcReleaseCachePage (PBCB Bcb,
|
||||
CcReleaseCacheSegment (PBCB Bcb,
|
||||
PCACHE_SEGMENT CacheSeg,
|
||||
BOOLEAN Valid);
|
||||
NTSTATUS STDCALL
|
||||
CcRequestCachePage (PBCB Bcb,
|
||||
ULONG FileOffset,
|
||||
PVOID* BaseAddress,
|
||||
PBOOLEAN UptoDate,
|
||||
PCACHE_SEGMENT* CacheSeg);
|
||||
CcRequestCacheSegment (PBCB Bcb,
|
||||
ULONG FileOffset,
|
||||
PVOID* BaseAddress,
|
||||
PBOOLEAN UptoDate,
|
||||
PCACHE_SEGMENT* CacheSeg);
|
||||
NTSTATUS STDCALL
|
||||
CcInitializeFileCache (PFILE_OBJECT FileObject,
|
||||
PBCB* Bcb);
|
||||
PBCB* Bcb,
|
||||
ULONG CacheSegmentSize);
|
||||
NTSTATUS STDCALL
|
||||
CcReleaseFileCache (PFILE_OBJECT FileObject,
|
||||
PBCB Bcb);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 2000, 1999, 1998 David Welch <welch@cwcom.net>
|
||||
|
@ -16,7 +17,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: view.c,v 1.12 2000/12/23 02:37:38 dwelch Exp $
|
||||
/* $Id: view.c,v 1.13 2001/01/01 04:42:11 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -59,10 +60,15 @@
|
|||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
|
||||
#define ROUND_DOWN(N, S) (ROUND_UP(N, S) - S)
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
NTSTATUS STDCALL
|
||||
CcFlushCachePage(PCACHE_SEGMENT CacheSeg)
|
||||
CcFlushCacheSegment(PCACHE_SEGMENT CacheSeg)
|
||||
/*
|
||||
* FUNCTION: Asks the FSD to flush the contents of the page back to disk
|
||||
*/
|
||||
|
@ -78,9 +84,9 @@ CcFlushCachePage(PCACHE_SEGMENT CacheSeg)
|
|||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
CcReleaseCachePage(PBCB Bcb,
|
||||
PCACHE_SEGMENT CacheSeg,
|
||||
BOOLEAN Valid)
|
||||
CcReleaseCacheSegment(PBCB Bcb,
|
||||
PCACHE_SEGMENT CacheSeg,
|
||||
BOOLEAN Valid)
|
||||
{
|
||||
DPRINT("CcReleaseCachePage(Bcb %x, CacheSeg %x, Valid %d)\n",
|
||||
Bcb, CacheSeg, Valid);
|
||||
|
@ -95,11 +101,11 @@ CcReleaseCachePage(PBCB Bcb,
|
|||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
CcRequestCachePage(PBCB Bcb,
|
||||
ULONG FileOffset,
|
||||
PVOID* BaseAddress,
|
||||
PBOOLEAN UptoDate,
|
||||
PCACHE_SEGMENT* CacheSeg)
|
||||
CcRequestCacheSegment(PBCB Bcb,
|
||||
ULONG FileOffset,
|
||||
PVOID* BaseAddress,
|
||||
PBOOLEAN UptoDate,
|
||||
PCACHE_SEGMENT* CacheSeg)
|
||||
/*
|
||||
* FUNCTION: Request a page mapping for a BCB
|
||||
*/
|
||||
|
@ -107,7 +113,13 @@ CcRequestCachePage(PBCB Bcb,
|
|||
KIRQL oldirql;
|
||||
PLIST_ENTRY current_entry;
|
||||
PCACHE_SEGMENT current;
|
||||
ULONG i;
|
||||
|
||||
if ((FileOffset % Bcb->CacheSegmentSize) != 0)
|
||||
{
|
||||
KeBugCheck(0);
|
||||
}
|
||||
|
||||
DPRINT("CcRequestCachePage(Bcb %x, FileOffset %x, BaseAddress %x, "
|
||||
"UptoDate %x, CacheSeg %x)\n", Bcb, FileOffset, BaseAddress,
|
||||
UptoDate, CacheSeg);
|
||||
|
@ -118,7 +130,7 @@ CcRequestCachePage(PBCB Bcb,
|
|||
while (current_entry != &Bcb->CacheSegmentListHead)
|
||||
{
|
||||
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, ListEntry);
|
||||
if (current->FileOffset == PAGE_ROUND_DOWN(FileOffset))
|
||||
if (current->FileOffset == FileOffset)
|
||||
{
|
||||
DPRINT("Found existing segment at %x\n", current);
|
||||
current->ReferenceCount++;
|
||||
|
@ -145,14 +157,14 @@ CcRequestCachePage(PBCB Bcb,
|
|||
current = ExAllocatePool(NonPagedPool, sizeof(CACHE_SEGMENT));
|
||||
current->BaseAddress = NULL;
|
||||
MmCreateMemoryArea(KernelMode,
|
||||
NULL,
|
||||
MmGetKernelAddressSpace(),
|
||||
MEMORY_AREA_CACHE_SEGMENT,
|
||||
¤t->BaseAddress,
|
||||
CACHE_SEGMENT_SIZE,
|
||||
Bcb->CacheSegmentSize,
|
||||
PAGE_READWRITE,
|
||||
(PMEMORY_AREA*)¤t->MemoryArea);
|
||||
current->Valid = FALSE;
|
||||
current->FileOffset = PAGE_ROUND_DOWN(FileOffset);
|
||||
current->FileOffset = FileOffset;
|
||||
current->Bcb = Bcb;
|
||||
KeInitializeEvent(¤t->Lock, SynchronizationEvent, FALSE);
|
||||
current->ReferenceCount = 1;
|
||||
|
@ -160,10 +172,13 @@ CcRequestCachePage(PBCB Bcb,
|
|||
*UptoDate = current->Valid;
|
||||
*BaseAddress = current->BaseAddress;
|
||||
*CacheSeg = current;
|
||||
MmCreateVirtualMapping(NULL,
|
||||
current->BaseAddress,
|
||||
PAGE_READWRITE,
|
||||
(ULONG)MmAllocPage(0));
|
||||
for (i = 0; i < (Bcb->CacheSegmentSize / PAGESIZE); i++)
|
||||
{
|
||||
MmCreateVirtualMapping(NULL,
|
||||
current->BaseAddress + (i * PAGESIZE),
|
||||
PAGE_READWRITE,
|
||||
(ULONG)MmAllocPage(0));
|
||||
}
|
||||
|
||||
|
||||
DPRINT("Returning %x (BaseAddress %x)\n", current, *BaseAddress);
|
||||
|
@ -180,7 +195,7 @@ CcFreeCacheSegment(PBCB Bcb,
|
|||
{
|
||||
MmFreeMemoryArea(NULL,
|
||||
CacheSeg->BaseAddress,
|
||||
CACHE_SEGMENT_SIZE,
|
||||
Bcb->CacheSegmentSize,
|
||||
TRUE);
|
||||
ExFreePool(CacheSeg);
|
||||
return(STATUS_SUCCESS);
|
||||
|
@ -217,7 +232,8 @@ CcReleaseFileCache(PFILE_OBJECT FileObject,
|
|||
|
||||
NTSTATUS STDCALL
|
||||
CcInitializeFileCache(PFILE_OBJECT FileObject,
|
||||
PBCB* Bcb)
|
||||
PBCB* Bcb,
|
||||
ULONG CacheSegmentSize)
|
||||
/*
|
||||
* FUNCTION: Initializes a BCB for a file object
|
||||
*/
|
||||
|
@ -233,7 +249,8 @@ CcInitializeFileCache(PFILE_OBJECT FileObject,
|
|||
(*Bcb)->FileObject = FileObject;
|
||||
InitializeListHead(&(*Bcb)->CacheSegmentListHead);
|
||||
KeInitializeSpinLock(&(*Bcb)->BcbLock);
|
||||
|
||||
(*Bcb)->CacheSegmentSize = CacheSegmentSize;
|
||||
|
||||
DPRINT("Finished CcInitializeFileCache() = %x\n", *Bcb);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
|
@ -260,7 +277,7 @@ VOID STDCALL
|
|||
CcMdlReadCompleteDev (IN PMDL MdlChain,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
; $Id: ntoskrnl.def,v 1.91 2000/12/30 01:41:52 ekohl Exp $
|
||||
; $Id: ntoskrnl.def,v 1.92 2001/01/01 04:42:11 dwelch Exp $
|
||||
;
|
||||
; reactos/ntoskrnl/ntoskrnl.def
|
||||
;
|
||||
; ReactOS Operating System
|
||||
;
|
||||
EXPORTS
|
||||
CcInitializeFileCache@8
|
||||
CcInitializeFileCache@12
|
||||
CcMdlReadComplete@8
|
||||
CcRequestCachePage@20
|
||||
CcReleaseCachePage@12
|
||||
CcRequestCacheSegment@20
|
||||
CcReleaseCacheSegment@12
|
||||
CcReleaseFileCache@8
|
||||
DbgBreakPoint@0
|
||||
DbgBreakPointWithStatus@4
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
; $Id: ntoskrnl.edf,v 1.78 2000/12/30 01:41:52 ekohl Exp $
|
||||
; $Id: ntoskrnl.edf,v 1.79 2001/01/01 04:42:11 dwelch Exp $
|
||||
;
|
||||
; reactos/ntoskrnl/ntoskrnl.def
|
||||
;
|
||||
; ReactOS Operating System
|
||||
;
|
||||
EXPORTS
|
||||
CcInitializeFileCache=CcInitializeFileCache@8
|
||||
CcInitializeFileCache=CcInitializeFileCache@12
|
||||
CcMdlReadComplete=CcMdlReadComplete@8
|
||||
CcRequestCachePage=CcRequestCachePage@20
|
||||
CcReleaseCachePage=CcReleaseCachePage@12
|
||||
CcRequestCacheSegment=CcRequestCacheSegment@20
|
||||
CcReleaseCacheSegment=CcReleaseCacheSegment@12
|
||||
CcReleaseFileCache=CcReleaseFileCache@8
|
||||
DbgBreakPoint=DbgBreakPoint@0
|
||||
DbgBreakPointWithStatus=DbgBreakPointWithStatus@4
|
||||
|
|
Loading…
Reference in a new issue