Added file and directory caching.

Improved verify support.
Fixed a joliet filename bug.

svn path=/trunk/; revision=2945
This commit is contained in:
Eric Kohl 2002-05-09 15:53:02 +00:00
parent e37bad87b8
commit 5e4527aff7
8 changed files with 175 additions and 97 deletions

View file

@ -144,6 +144,7 @@ typedef struct
KSPIN_LOCK FcbListLock;
LIST_ENTRY FcbListHead;
PVPB Vpb;
PDEVICE_OBJECT StorageDevice;
PFILE_OBJECT StreamFileObject;
@ -154,6 +155,8 @@ typedef struct
#define FCB_CACHE_INITIALIZED 0x0001
#define FCB_IS_VOLUME_STREAM 0x0002
#define FCB_IS_VOLUME 0x0004
typedef struct _FCB
{
@ -230,6 +233,19 @@ NTSTATUS STDCALL
CdfsClose(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
/* common.c */
NTSTATUS
CdfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN OUT PUCHAR Buffer);
NTSTATUS
CdfsReadRawSectors(IN PDEVICE_OBJECT DeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN OUT PUCHAR Buffer);
/* create.c */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: common.c,v 1.3 2002/04/26 23:21:28 ekohl Exp $
/* $Id: common.c,v 1.4 2002/05/09 15:53:02 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -118,4 +118,77 @@ CdfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
return(STATUS_SUCCESS);
}
NTSTATUS
CdfsReadRawSectors(IN PDEVICE_OBJECT DeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN OUT PUCHAR Buffer)
{
PIO_STACK_LOCATION Stack;
IO_STATUS_BLOCK IoStatus;
LARGE_INTEGER Offset;
ULONG BlockSize;
KEVENT Event;
PIRP Irp;
NTSTATUS Status;
KeInitializeEvent(&Event,
NotificationEvent,
FALSE);
Offset.u.LowPart = DiskSector << 11;
Offset.u.HighPart = DiskSector >> 21;
BlockSize = BLOCKSIZE * SectorCount;
DPRINT("CdfsReadSectors(DeviceObject %x, DiskSector %d, Buffer %x)\n",
DeviceObject, DiskSector, Buffer);
DPRINT("Offset %I64x BlockSize %ld\n",
Offset.QuadPart,
BlockSize);
DPRINT("Building synchronous FSD Request...\n");
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
DeviceObject,
Buffer,
BlockSize,
&Offset,
&Event,
&IoStatus);
if (Irp == NULL)
{
DPRINT("IoBuildSynchronousFsdRequest failed\n");
return(STATUS_INSUFFICIENT_RESOURCES);
}
// Stack = IoGetCurrentIrpStackLocation(Irp);
// Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
DPRINT("Calling IO Driver... with irp %x\n", Irp);
Status = IoCallDriver(DeviceObject, Irp);
DPRINT("Waiting for IO Operation for %x\n", Irp);
if (Status == STATUS_PENDING)
{
DPRINT("Operation pending\n");
KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
DPRINT("Getting IO Status... for %x\n", Irp);
Status = IoStatus.Status;
}
if (!NT_SUCCESS(Status))
{
DPRINT("CdfsReadSectors() failed (Status %x)\n", Status);
DPRINT("(DeviceObject %x, DiskSector %x, Buffer %x, Offset 0x%I64x)\n",
DeviceObject, DiskSector, Buffer,
Offset.QuadPart);
return(Status);
}
DPRINT("Block request succeeded for %x\n", Irp);
return(STATUS_SUCCESS);
}
/* EOF */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: create.c,v 1.2 2002/05/01 13:15:42 ekohl Exp $
/* $Id: create.c,v 1.3 2002/05/09 15:53:02 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -189,6 +189,13 @@ CdfsCreateFile(PDEVICE_OBJECT DeviceObject,
FileObject = Stack->FileObject;
if (RequestedDisposition == FILE_CREATE ||
RequestedDisposition == FILE_OVERWRITE_IF ||
RequestedDisposition == FILE_SUPERSEDE)
{
return(STATUS_ACCESS_DENIED);
}
Status = CdfsOpenFile(DeviceExt,
FileObject,
FileObject->FileName.Buffer);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: dirctl.c,v 1.3 2002/05/01 13:15:42 ekohl Exp $
/* $Id: dirctl.c,v 1.4 2002/05/09 15:53:02 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -123,23 +123,19 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
*/
{
WCHAR name[256];
char * block;
WCHAR TempStr[2];
PVOID Block;
NTSTATUS Status;
ULONG len;
ULONG DirIndex;
ULONG Offset;
ULONG FirstSector;
ULONG Read;
BOOLEAN IsRoot;
LARGE_INTEGER FileOffset;
PVOID Context = NULL;
ULONG DirSize;
ULONG BufferSize;
ULONG SectorCount;
PUCHAR Ptr;
PDIR_RECORD Record;
LARGE_INTEGER StreamOffset;
DPRINT("FindFile(Parent %x, FileToFind '%S', DirIndex: %d)\n",
Parent, FileToFind, pDirIndex ? *pDirIndex : 0);
@ -158,8 +154,7 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
if (Parent)
{
FirstSector = Parent->Entry.ExtentLocationL;
if (FirstSector == DeviceExt->CdInfo.RootStart)
if (Parent->Entry.ExtentLocationL == DeviceExt->CdInfo.RootStart)
{
IsRoot = TRUE;
}
@ -171,7 +166,7 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
if (IsRoot == TRUE)
{
FirstSector = DeviceExt->CdInfo.RootStart;
StreamOffset.QuadPart = (LONGLONG)DeviceExt->CdInfo.RootStart * (LONGLONG)BLOCKSIZE;
DirSize = DeviceExt->CdInfo.RootSize;
@ -197,35 +192,22 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
}
else
{
FirstSector = Parent->Entry.ExtentLocationL;
StreamOffset.QuadPart = (LONGLONG)Parent->Entry.ExtentLocationL * (LONGLONG)BLOCKSIZE;
DirSize = Parent->Entry.DataLengthL;
}
DPRINT("FirstSector %lu DirSize %lu\n", FirstSector, DirSize);
DPRINT("StreamOffset %I64u DirSize %lu\n", StreamOffset.QuadPart, DirSize);
if (pDirIndex && (*pDirIndex))
DirIndex = *pDirIndex;
BufferSize = ROUND_UP(DirSize, BLOCKSIZE);
SectorCount = BufferSize / BLOCKSIZE;
if(!CcMapData(DeviceExt->StreamFileObject, &StreamOffset,
DirSize, TRUE, &Context, &Block))
{
return(STATUS_UNSUCCESSFUL);
}
DPRINT("FirstSector %lu DirSize %lu BufferSize %lu SectorCount %lu\n",
FirstSector, DirSize, BufferSize, SectorCount);
block = ExAllocatePool(NonPagedPool, BufferSize);
Status = CdfsReadSectors(DeviceExt->StorageDevice,
FirstSector,
SectorCount,
block);
if (!NT_SUCCESS(Status))
{
DPRINT("Reading directory extent failed (Status %lx)\n", Status);
ExFreePool(block);
return(Status);
}
Ptr = (PUCHAR)block;
Ptr = (PUCHAR)Block;
while(TRUE)
{
Record = (PDIR_RECORD)Ptr;
@ -238,7 +220,7 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
DPRINT("RecordLength %u ExtAttrRecordLength %u NameLength %u\n",
Record->RecordLength, Record->ExtAttrRecordLength, Record->FileIdLength);
Status = CdfsGetEntryName(DeviceExt, block, DirSize, (PVOID*)&Ptr, name, &DirIndex, pDirIndex2);
Status = CdfsGetEntryName(DeviceExt, Block, DirSize, (PVOID*)&Ptr, name, &DirIndex, pDirIndex2);
if (Status == STATUS_NO_MORE_ENTRIES)
{
break;
@ -276,7 +258,7 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
DPRINT("FindFile: new Pathname %S, new Objectname %S, DirIndex %d\n",
Fcb->PathName, Fcb->ObjectName, DirIndex);
ExFreePool(block);
CcUnpinData(Context);
return(STATUS_SUCCESS);
}
@ -285,14 +267,14 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
Ptr = Ptr + Record->RecordLength;
DirIndex++;
if (((ULONG)Ptr - (ULONG)block) >= DirSize)
if (((ULONG)Ptr - (ULONG)Block) >= DirSize)
{
DPRINT("Stopped!\n");
break;
}
}
ExFreePool(block);
CcUnpinData(Context);
if (pDirIndex)
*pDirIndex = DirIndex;

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: fcb.c,v 1.4 2002/05/01 13:15:42 ekohl Exp $
/* $Id: fcb.c,v 1.5 2002/05/09 15:53:02 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -442,15 +442,16 @@ CdfsDirFindFile(PDEVICE_EXTENSION DeviceExt,
{
WCHAR TempName[2];
WCHAR Name[256];
PUCHAR Block;
PVOID Block;
ULONG FirstSector;
ULONG DirSize;
ULONG BufferSize;
ULONG SectorCount;
PDIR_RECORD Record;
ULONG Offset;
NTSTATUS Status;
LARGE_INTEGER StreamOffset;
PVOID Context;
assert(DeviceExt);
assert(DirectoryFcb);
assert(FileToFind);
@ -469,27 +470,14 @@ CdfsDirFindFile(PDEVICE_EXTENSION DeviceExt,
FileToFind = TempName;
}
FirstSector = DirectoryFcb->Entry.ExtentLocationL;
DirSize = DirectoryFcb->Entry.DataLengthL;
StreamOffset.QuadPart = (LONGLONG)DirectoryFcb->Entry.ExtentLocationL * (LONGLONG)BLOCKSIZE;
BufferSize = ROUND_UP(DirSize, BLOCKSIZE);
SectorCount = BufferSize / BLOCKSIZE;
DPRINT("FirstSector %lu DirSize %lu BufferSize %lu SectorCount %lu\n",
FirstSector, DirSize, BufferSize, SectorCount);
Block = ExAllocatePool(NonPagedPool, BufferSize);
Status = CdfsReadSectors(DeviceExt->StorageDevice,
FirstSector,
SectorCount,
Block);
if (!NT_SUCCESS(Status))
{
DPRINT("Reading directory extent failed (Status %lx)\n", Status);
ExFreePool(Block);
return(Status);
}
if(!CcMapData(DeviceExt->StreamFileObject, &StreamOffset,
DirSize, TRUE, &Context, &Block))
{
return(STATUS_UNSUCCESSFUL);
}
Offset = 0;
Record = (PDIR_RECORD)Block;
@ -516,7 +504,7 @@ CdfsDirFindFile(PDEVICE_EXTENSION DeviceExt,
Record,
FoundFCB);
ExFreePool(Block);
CcUnpinData(Context);
return(Status);
}
@ -529,12 +517,11 @@ CdfsDirFindFile(PDEVICE_EXTENSION DeviceExt,
Record = (PDIR_RECORD)(Block + Offset);
}
// if (Offset >= BufferSize)
if (Offset >= DirSize)
break;
}
ExFreePool(Block);
CcUnpinData(Context);
return(STATUS_OBJECT_NAME_NOT_FOUND);
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: fsctl.c,v 1.3 2002/05/01 13:15:42 ekohl Exp $
/* $Id: fsctl.c,v 1.4 2002/05/09 15:53:02 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -155,10 +155,10 @@ CdfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
do
{
/* Read the Primary Volume Descriptor (PVD) */
Status = CdfsReadSectors(DeviceObject,
Sector,
1,
Buffer);
Status = CdfsReadRawSectors(DeviceObject,
Sector,
1,
Buffer);
if (!NT_SUCCESS(Status))
return(Status);
@ -220,10 +220,10 @@ CdfsHasFileSystem(PDEVICE_OBJECT DeviceToMount)
DPRINT("CDFS: Checking on mount of device %08x\n", DeviceToMount);
Status = CdfsReadSectors(DeviceToMount,
CDFS_PRIMARY_DESCRIPTOR_LOCATION,
1,
Buffer);
Status = CdfsReadRawSectors(DeviceToMount,
CDFS_PRIMARY_DESCRIPTOR_LOCATION,
1,
Buffer);
if (!NT_SUCCESS(Status))
{
return(Status);
@ -255,6 +255,7 @@ CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
PIO_STACK_LOCATION Stack;
PFCB Fcb = NULL;
PCCB Ccb = NULL;
PVPB Vpb;
NTSTATUS Status;
DPRINT("CdfsMountVolume() called\n");
@ -267,6 +268,7 @@ CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
Stack = IoGetCurrentIrpStackLocation(Irp);
DeviceToMount = Stack->Parameters.MountVolume.DeviceObject;
Vpb = Stack->Parameters.MountVolume.Vpb;
Status = CdfsHasFileSystem(DeviceToMount);
if (!NT_SUCCESS(Status))
@ -278,6 +280,7 @@ CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
sizeof(DEVICE_EXTENSION),
NULL,
FILE_DEVICE_FILE_SYSTEM,
// FILE_DEVICE_DISK_FILE_SYSTEM,
0,
FALSE,
&NewDeviceObject);
@ -294,6 +297,15 @@ CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
if (!NT_SUCCESS(Status))
goto ByeBye;
#if 0
NewDeviceObject->StackSize = DeviceToMount->StackSize;
Vpb->DeviceObject = NewDeviceObject;
DeviceExt->Vpb = Vpb;
DeviceExt->StorageDevice = DeviceToMount;
#endif
NewDeviceObject->Vpb = DeviceToMount->Vpb;
NewDeviceObject->Vpb->Flags |= VPB_MOUNTED;
DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(NewDeviceObject,
@ -324,12 +336,14 @@ CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
DeviceExt->StreamFileObject->FsContext2 = Ccb;
DeviceExt->StreamFileObject->SectionObjectPointers = &Fcb->SectionObjectPointers;
DeviceExt->StreamFileObject->PrivateCacheMap = NULL;
DeviceExt->StreamFileObject->Vpb = NewDeviceObject->Vpb;
DeviceExt->StreamFileObject->Vpb = DeviceExt->Vpb;
Ccb->Fcb = Fcb;
Ccb->PtrFileObject = DeviceExt->StreamFileObject;
Fcb->FileObject = DeviceExt->StreamFileObject;
Fcb->DevExt = (PDEVICE_EXTENSION)DeviceExt->StorageDevice;
Fcb->Flags = FCB_IS_VOLUME_STREAM;
Fcb->RFCB.FileSize.QuadPart = DeviceExt->CdInfo.VolumeSpaceSize * BLOCKSIZE;
Fcb->RFCB.ValidDataLength.QuadPart = DeviceExt->CdInfo.VolumeSpaceSize * BLOCKSIZE;
Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP(DeviceExt->CdInfo.VolumeSpaceSize * BLOCKSIZE, PAGESIZE);
@ -374,7 +388,7 @@ ByeBye:
static NTSTATUS
CdfsVerifyVolume(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
PIRP Irp)
{
PDEVICE_OBJECT DeviceToVerify;
PIO_STACK_LOCATION Stack;
@ -389,16 +403,21 @@ CdfsVerifyVolume(PDEVICE_OBJECT DeviceObject,
UCHAR Part[4];
} Serial;
DPRINT("CdfsVerifyVolume() called\n");
DPRINT1("CdfsVerifyVolume() called\n");
#if 0
if (DeviceObject != CdfsGlobalData->DeviceObject)
{
DPRINT1("DeviceObject != CdfsGlobalData->DeviceObject\n");
return(STATUS_INVALID_DEVICE_REQUEST);
}
#endif
Stack = IoGetCurrentIrpStackLocation(Irp);
DeviceToVerify = Stack->Parameters.VerifyVolume.DeviceObject;
DPRINT("Device object %p Device to verify %p\n", DeviceObject, DeviceToVerify);
Sector = CDFS_PRIMARY_DESCRIPTOR_LOCATION;
Buffer = ExAllocatePool(NonPagedPool,
@ -408,15 +427,14 @@ CdfsVerifyVolume(PDEVICE_OBJECT DeviceObject,
return(STATUS_INSUFFICIENT_RESOURCES);
}
Status = STATUS_WRONG_VOLUME;
do
{
/* Read the Primary Volume Descriptor (PVD) */
Status = CdfsReadSectors(DeviceToVerify,
Sector,
1,
Buffer);
Status = CdfsReadRawSectors(DeviceToVerify,
Sector,
1,
Buffer);
DPRINT("CdfsReadRawSectors() status %lx\n", Status);
if (!NT_SUCCESS(Status))
{
goto ByeBye;
@ -439,6 +457,7 @@ CdfsVerifyVolume(PDEVICE_OBJECT DeviceObject,
if (Buffer[0] == 255)
goto ByeBye;
Status = STATUS_WRONG_VOLUME;
/* Calculate the volume serial number */
Serial.Value = 0;
@ -458,12 +477,8 @@ CdfsVerifyVolume(PDEVICE_OBJECT DeviceObject,
Status = STATUS_SUCCESS;
ByeBye:
ExFreePool(Buffer);
// Status = STATUS_INVALID_DEVICE_REQUEST;
DPRINT("CdfsVerifyVolume() done (Status: %lx)\n", Status);
return(Status);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: misc.c,v 1.1 2002/05/01 13:15:42 ekohl Exp $
/* $Id: misc.c,v 1.2 2002/05/09 15:53:02 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -93,6 +93,8 @@ CdfsSwapString(PWCHAR Out,
{
t[i] = In[i+1];
t[i+1] = In[i];
if (t[i+1] == 0 && t[i] == ';')
break;
}
t[i] = 0;
t[i+1] = 0;

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: rw.c,v 1.2 2002/05/01 21:52:05 ekohl Exp $
/* $Id: rw.c,v 1.3 2002/05/09 15:53:02 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -51,6 +51,7 @@ CdfsReadFile(PDEVICE_EXTENSION DeviceExt,
PUCHAR Buffer,
ULONG Length,
ULONG ReadOffset,
ULONG IrpFlags,
PULONG LengthRead)
/*
* FUNCTION: Reads data from a file
@ -80,13 +81,14 @@ CdfsReadFile(PDEVICE_EXTENSION DeviceExt,
if (Length == 0)
return(STATUS_UNSUCCESSFUL);
#if 0
if ((FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING) == 0)
if (!(IrpFlags & (IRP_NOCACHE|IRP_PAGING_IO)))
{
LARGE_INTEGER FileOffset;
IO_STATUS_BLOCK IoStatus;
FileOffset.QuadPart = ReadOffset;
DPRINT1("Try caching!\n");
FileOffset.QuadPart = (LONGLONG)ReadOffset;
CcCopyRead(FileObject,
&FileOffset,
Length,
@ -97,7 +99,6 @@ CdfsReadFile(PDEVICE_EXTENSION DeviceExt,
return(IoStatus.Status);
}
#endif
if ((ReadOffset % BLOCKSIZE) != 0)
{
@ -174,12 +175,6 @@ CdfsRead(PDEVICE_OBJECT DeviceObject,
DPRINT("CdfsRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
if (Irp->Flags & IRP_PAGING_IO)
{
Status = STATUS_NOT_SUPPORTED;
goto ByeBye;
}
DeviceExt = DeviceObject->DeviceExtension;
Stack = IoGetCurrentIrpStackLocation(Irp);
FileObject = Stack->FileObject;
@ -193,6 +188,7 @@ CdfsRead(PDEVICE_OBJECT DeviceObject,
Buffer,
ReadLength,
ReadOffset.u.LowPart,
Irp->Flags,
&ReturnedReadLength);
ByeBye: