redo changes in 1.9 from Rex.

correct bug on fragmented directories.

svn path=/trunk/; revision=153
This commit is contained in:
jean 1999-01-05 12:04:08 +00:00
parent 36902d624f
commit 1e09a4813f

View file

@ -73,7 +73,7 @@ ULONG Fat16GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
Block=(PUSHORT)DeviceExt->FAT; Block=(PUSHORT)DeviceExt->FAT;
CurrentCluster = Block[CurrentCluster]; CurrentCluster = Block[CurrentCluster];
if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff) if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
CurrentCluster = 0xffffffff; CurrentCluster = 0xffffffff;
DPRINT("Returning %x\n",CurrentCluster); DPRINT("Returning %x\n",CurrentCluster);
return(CurrentCluster); return(CurrentCluster);
} }
@ -623,17 +623,19 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
ULONG NextCluster; ULONG NextCluster;
DPRINT("FindFile(Parent %x, FileToFind %w)\n",Parent,FileToFind); DPRINT("FindFile(Parent %x, FileToFind %w)\n",Parent,FileToFind);
if (Parent == NULL) if (Parent == NULL||Parent->entry.FirstCluster==1)
{ {
Size = DeviceExt->rootDirectorySectors;//FIXME : in fat32, no limit Size = DeviceExt->rootDirectorySectors;//FIXME : in fat32, no limit
StartingSector = DeviceExt->rootStart; StartingSector = DeviceExt->rootStart;
NextCluster=0;
if(FileToFind[0]==0 ||(FileToFind[0]=='\\' && FileToFind[1]==0)) if(FileToFind[0]==0 ||(FileToFind[0]=='\\' && FileToFind[1]==0))
{// it's root : complete essentials fields then return ok {// it's root : complete essentials fields then return ok
memset(Fcb,0,sizeof(VfatFCB)); memset(Fcb,0,sizeof(VfatFCB));
memset(Fcb->entry.Filename,' ',11); memset(Fcb->entry.Filename,' ',11);
Fcb->entry.FileSize=DeviceExt->rootDirectorySectors*BLOCKSIZE;
if (DeviceExt->FatType == FAT32) if (DeviceExt->FatType == FAT32)
Fcb->entry.FirstCluster=2; Fcb->entry.FirstCluster=2;
else Fcb->entry.FirstCluster=1;//FIXME : is 1 the good value ? else Fcb->entry.FirstCluster=1;//FIXME : is 1 the good value for mark root?
if(StartSector) *StartSector=StartingSector; if(StartSector) *StartSector=StartingSector;
if(Entry) *Entry=0; if(Entry) *Entry=0;
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
@ -645,7 +647,8 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
Size = ULONG_MAX; Size = ULONG_MAX;
if (DeviceExt->FatType == FAT32) if (DeviceExt->FatType == FAT32)
NextCluster = Parent->entry.FirstCluster+Parent->entry.FirstClusterHigh*65536; NextCluster = Parent->entry.FirstCluster
+Parent->entry.FirstClusterHigh*65536;
else else
NextCluster = Parent->entry.FirstCluster; NextCluster = Parent->entry.FirstCluster;
StartingSector = ClusterToSector(DeviceExt, NextCluster); StartingSector = ClusterToSector(DeviceExt, NextCluster);
@ -707,29 +710,26 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
} }
// not found in this sector, try next : // not found in this sector, try next :
/* It seems that directory sectors cannot be fragmented and therefore, /* directory can be fragmented although it is best to keep them
they only have a first cluster, but the one's after it are marked unfragmented */
with 0xffff. This theory is still not 100% certain, so the following
lines are commented and not removed */
StartingSector++;
if(Entry) *Entry=0; if(Entry) *Entry=0;
/* if (Parent == NULL) StartingSector++;
if ((Parent != NULL && Parent->entry.FirstCluster!=1)
|| DeviceExt->FatType ==FAT32)
{ {
StartingSector++; if(StartingSector==ClusterToSector(DeviceExt,NextCluster+1))
}
else
{
NextCluster = GetNextCluster(DeviceExt,NextCluster);
if (NextCluster == 0||NextCluster==0xffffffff)
{ {
if(StartSector) *StartSector=StartingSector; NextCluster = GetNextCluster(DeviceExt,NextCluster);
if(Entry) *Entry=i; if (NextCluster == 0||NextCluster==0xffffffff)
ExFreePool(block); {
return(STATUS_UNSUCCESSFUL); if(StartSector) *StartSector=StartingSector;
if(Entry) *Entry=i;
ExFreePool(block);
return(STATUS_UNSUCCESSFUL);
}
StartingSector = ClusterToSector(DeviceExt,NextCluster);
} }
StartingSector = ClusterToSector(DeviceExt,NextCluster); }
} */
} }
ExFreePool(block); ExFreePool(block);
if(StartSector) *StartSector=StartingSector; if(StartSector) *StartSector=StartingSector;
@ -870,7 +870,7 @@ BOOLEAN FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount)
*/ */
{ {
BootSector* Boot; BootSector* Boot;
Boot = ExAllocatePool(NonPagedPool,512); Boot = ExAllocatePool(NonPagedPool,512);
VFATReadSectors(DeviceToMount, 0, 1, (UCHAR *)Boot); VFATReadSectors(DeviceToMount, 0, 1, (UCHAR *)Boot);
@ -988,6 +988,12 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
PVOID Temp; PVOID Temp;
ULONG TempLength; 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, " DPRINT("FsdReadFile(DeviceExt %x, FileObject %x, Buffer %x, "
"Length %d, ReadOffset %d)\n",DeviceExt,FileObject,Buffer, "Length %d, ReadOffset %d)\n",DeviceExt,FileObject,Buffer,
Length,ReadOffset); Length,ReadOffset);
@ -995,7 +1001,8 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
FirstCluster = ReadOffset / DeviceExt->BytesPerCluster; FirstCluster = ReadOffset / DeviceExt->BytesPerCluster;
Fcb = ((PVfatCCB)(FileObject->FsContext2))->pFcb; Fcb = ((PVfatCCB)(FileObject->FsContext2))->pFcb;
if (DeviceExt->FatType == FAT32) if (DeviceExt->FatType == FAT32)
CurrentCluster = Fcb->entry.FirstCluster+Fcb->entry.FirstClusterHigh*65536; CurrentCluster = Fcb->entry.FirstCluster
+Fcb->entry.FirstClusterHigh*65536;
else else
CurrentCluster = Fcb->entry.FirstCluster; CurrentCluster = Fcb->entry.FirstCluster;
if (CurrentCluster<2) if (CurrentCluster<2)
@ -1011,6 +1018,7 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
Length = Fcb->entry.FileSize - ReadOffset; Length = Fcb->entry.FileSize - ReadOffset;
} }
*LengthRead = 0; *LengthRead = 0;
/* FIXME: optimize by remembering the last cluster read and using if possible */
Temp = ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster); Temp = ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
if(!Temp) return STATUS_UNSUCCESSFUL; if(!Temp) return STATUS_UNSUCCESSFUL;
for (FileOffset=0; FileOffset < FirstCluster; FileOffset++) for (FileOffset=0; FileOffset < FirstCluster; FileOffset++)
@ -1248,14 +1256,23 @@ NTSTATUS FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
ULONG Length; ULONG Length;
PVOID Buffer; PVOID Buffer;
ULONG Offset; ULONG Offset;
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp); PIO_STACK_LOCATION Stack;
PFILE_OBJECT FileObject = Stack->FileObject; PFILE_OBJECT FileObject;
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension; PDEVICE_EXTENSION DeviceExt;
NTSTATUS Status; NTSTATUS Status;
ULONG LengthRead; ULONG LengthRead;
DPRINT("FsdRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp); DPRINT("FsdRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
/* Precondition / Initialization */
assert(Irp != NULL);
Stack = IoGetCurrentIrpStackLocation(Irp);
assert(Stack != NULL);
FileObject = Stack->FileObject;
assert(FileObject != NULL);
DeviceExt = DeviceObject->DeviceExtension;
assert(DeviceExt != NULL);
Length = Stack->Parameters.Read.Length; Length = Stack->Parameters.Read.Length;
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress); Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
Offset = GET_LARGE_INTEGER_LOW_PART(Stack->Parameters.Read.ByteOffset); Offset = GET_LARGE_INTEGER_LOW_PART(Stack->Parameters.Read.ByteOffset);
@ -1309,6 +1326,8 @@ NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
DPRINT("VFAT FSC\n"); DPRINT("VFAT FSC\n");
/* FIXME: should make sure that this is actually a mount request! */
if (FsdHasFileSystem(DeviceToMount)) if (FsdHasFileSystem(DeviceToMount))
{ {
Status = FsdMount(DeviceToMount); Status = FsdMount(DeviceToMount);
@ -1333,9 +1352,16 @@ NTSTATUS FsdGetStandardInformation(PVfatFCB FCB, PDEVICE_OBJECT DeviceObject,
* FUNCTION: Retrieve the standard file information * FUNCTION: Retrieve the standard file information
*/ */
{ {
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; PDEVICE_EXTENSION DeviceExtension;
unsigned long AllocSize; unsigned long AllocSize;
DeviceExtension = DeviceObject->DeviceExtension;
/* PRECONDITION */
assert(DeviceExtension != NULL);
assert(DeviceExtension->BytesPerCluster != 0);
assert(StandardInfo != NULL);
assert(FCB != NULL);
RtlZeroMemory(StandardInfo, sizeof(FILE_STANDARD_INFORMATION)); RtlZeroMemory(StandardInfo, sizeof(FILE_STANDARD_INFORMATION));
/* Make allocsize a rounded up multiple of BytesPerCluster */ /* Make allocsize a rounded up multiple of BytesPerCluster */
@ -1371,12 +1397,24 @@ NTSTATUS FsdQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
NTSTATUS RC = STATUS_SUCCESS; NTSTATUS RC = STATUS_SUCCESS;
void *SystemBuffer; void *SystemBuffer;
/* PRECONDITION */
assert(DeviceObject != NULL);
assert(Irp != NULL);
/* INITIALIZATION */
Stack = IoGetCurrentIrpStackLocation(Irp);
FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
FileObject = Stack->FileObject; FileObject = Stack->FileObject;
// CCB = (PVfatCCB)(FileObject->FsContext2); // CCB = (PVfatCCB)(FileObject->FsContext2);
// FCB = CCB->Buffer; // Should be CCB->FCB??? // FCB = CCB->Buffer; // Should be CCB->FCB???
FCB = ((PVfatCCB)(FileObject->FsContext2))->pFcb; FCB = ((PVfatCCB)(FileObject->FsContext2))->pFcb;
SystemBuffer = Irp->AssociatedIrp.SystemBuffer; // FIXME : determine Buffer for result :
if (Irp->MdlAddress)
SystemBuffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
else
SystemBuffer = Irp->UserBuffer;
// SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
switch(FileInformationClass) { switch(FileInformationClass) {
case FileStandardInformation: case FileStandardInformation:
@ -1417,7 +1455,7 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
return(ret); return(ret);
} }
DeviceObject->Flags=0; DeviceObject->Flags = DO_DIRECT_IO;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsdClose; DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsdClose;
DriverObject->MajorFunction[IRP_MJ_CREATE] = FsdCreate; DriverObject->MajorFunction[IRP_MJ_CREATE] = FsdCreate;
DriverObject->MajorFunction[IRP_MJ_READ] = FsdRead; DriverObject->MajorFunction[IRP_MJ_READ] = FsdRead;