add a read buffer of one cluster for each file

svn path=/trunk/; revision=230
This commit is contained in:
jean 1999-02-15 11:25:23 +00:00
parent 36714219d9
commit 2f1849aae9

View file

@ -617,12 +617,16 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
} }
TempFcb.Buffer=NULL;
if (Parent==NULL) if (Parent==NULL)
{ {
memset(&TempFcb,0,sizeof(VfatFCB)); memset(&TempFcb,0,sizeof(VfatFCB));
memset(TempFcb.entry.Filename,' ',11); memset(TempFcb.entry.Filename,' ',11);
TempFcb.entry.FileSize=DeviceExt->rootDirectorySectors*BLOCKSIZE; TempFcb.entry.FileSize=DeviceExt->rootDirectorySectors*BLOCKSIZE;
TempFcb.entry.Attrib=FILE_ATTRIBUTE_DIRECTORY; TempFcb.entry.Attrib=FILE_ATTRIBUTE_DIRECTORY;
TempFcb.Buffer=ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
TempFcb.Cluster=0xFFFFFFFF;
TempFcb.Flags=0;
if (DeviceExt->FatType == FAT32) if (DeviceExt->FatType == FAT32)
TempFcb.entry.FirstCluster=2; TempFcb.entry.FirstCluster=2;
else else
@ -650,11 +654,13 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
memcpy(&Fcb->entry,&FatEntry,sizeof(FATDirEntry)); memcpy(&Fcb->entry,&FatEntry,sizeof(FATDirEntry));
vfat_wcsncpy(Fcb->ObjectName,name,MAX_PATH); vfat_wcsncpy(Fcb->ObjectName,name,MAX_PATH);
if(Entry) *Entry=i; if(Entry) *Entry=i;
if(TempFcb.Buffer) ExFreePool(TempFcb.Buffer);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
} }
} }
if(Entry) *Entry=i; if(Entry) *Entry=i;
if(TempFcb.Buffer) ExFreePool(TempFcb.Buffer);
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
@ -667,8 +673,11 @@ NTSTATUS FsdCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
PVfatFCB pFcb; PVfatFCB pFcb;
PVfatCCB pCcb; PVfatCCB pCcb;
//FIXME : update entry in directory ? //FIXME : update entry in directory ?
assert(FileObject);
pCcb = (PVfatCCB)(FileObject->FsContext2); pCcb = (PVfatCCB)(FileObject->FsContext2);
if(!pCcb) return STATUS_UNSUCCESSFUL;
pFcb = pCcb->pFcb; pFcb = pCcb->pFcb;
assert(pFcb);
pFcb->RefCount--; pFcb->RefCount--;
if(pFcb->RefCount<=0) if(pFcb->RefCount<=0)
{ {
@ -678,6 +687,7 @@ NTSTATUS FsdCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
pFirstFcb=pFcb->nextFcb; pFirstFcb=pFcb->nextFcb;
if(pFcb->nextFcb) if(pFcb->nextFcb)
pFcb->nextFcb->prevFcb=pFcb->prevFcb; pFcb->nextFcb->prevFcb=pFcb->prevFcb;
ExFreePool(pFcb->Buffer);
ExFreePool(pFcb); ExFreePool(pFcb);
} }
ExFreePool(pCcb); ExFreePool(pCcb);
@ -707,7 +717,6 @@ NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
// treat relative name // treat relative name
if(FileObject->RelatedFileObject) if(FileObject->RelatedFileObject)
{ {
DbgPrint("try related for %w\n",FileName);
pRelFileObject=FileObject->RelatedFileObject; pRelFileObject=FileObject->RelatedFileObject;
pRelCcb=pRelFileObject->FsContext2; pRelCcb=pRelFileObject->FsContext2;
assert(pRelCcb); assert(pRelCcb);
@ -753,12 +762,20 @@ DbgPrint("try related for %w\n",FileName);
Fcb = ExAllocatePool(NonPagedPool, sizeof(VfatFCB)); Fcb = ExAllocatePool(NonPagedPool, sizeof(VfatFCB));
memset(Fcb,0,sizeof(VfatFCB)); memset(Fcb,0,sizeof(VfatFCB));
Fcb->ObjectName=Fcb->PathName; Fcb->ObjectName=Fcb->PathName;
Fcb->Buffer=ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
Fcb->Cluster=0xFFFFFFFF;
Fcb->Flags=0;
next = &string[0]; next = &string[0];
current = next+1; current = next+1;
if(*next==0) // root if(*next==0) // root
{ {
Status = FindFile(DeviceExt,Fcb,ParentFcb,next,NULL); memset(Fcb->entry.Filename,' ',11);
Fcb->entry.FileSize=DeviceExt->rootDirectorySectors*BLOCKSIZE;
Fcb->entry.Attrib=FILE_ATTRIBUTE_DIRECTORY;
if (DeviceExt->FatType == FAT32)
Fcb->entry.FirstCluster=2;
else Fcb->entry.FirstCluster=1;//FIXME : is 1 the good value for mark root?
ParentFcb=Fcb; ParentFcb=Fcb;
Fcb=NULL; Fcb=NULL;
} }
@ -786,6 +803,9 @@ DbgPrint("try related for %w\n",FileName);
Fcb = ExAllocatePool(NonPagedPool,sizeof(VfatFCB)); Fcb = ExAllocatePool(NonPagedPool,sizeof(VfatFCB));
memset(Fcb,0,sizeof(VfatFCB)); memset(Fcb,0,sizeof(VfatFCB));
Fcb->ObjectName=Fcb->PathName; Fcb->ObjectName=Fcb->PathName;
Fcb->Buffer=ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
Fcb->Cluster=0xFFFFFFFF;
Fcb->Flags=0;
} }
else Fcb = ParentFcb; else Fcb = ParentFcb;
ParentFcb = Temp; ParentFcb = Temp;
@ -799,12 +819,18 @@ DbgPrint("try related for %w\n",FileName);
newCCB->PtrFileObject=FileObject; newCCB->PtrFileObject=FileObject;
ParentFcb->RefCount++; ParentFcb->RefCount++;
//FIXME : initialize all fields in FCB and CCB //FIXME : initialize all fields in FCB and CCB
ParentFcb->Cluster=0xFFFFFFFF;
ParentFcb->Flags=0;
ParentFcb->nextFcb=pFirstFcb; ParentFcb->nextFcb=pFirstFcb;
pFirstFcb=ParentFcb; pFirstFcb=ParentFcb;
vfat_wcsncpy(ParentFcb->PathName,FileName,MAX_PATH); vfat_wcsncpy(ParentFcb->PathName,FileName,MAX_PATH);
ParentFcb->ObjectName=ParentFcb->PathName+(current-FileName); ParentFcb->ObjectName=ParentFcb->PathName+(current-FileName);
ParentFcb->pDevExt=DeviceExt; ParentFcb->pDevExt=DeviceExt;
if(Fcb) ExFreePool(Fcb); if(Fcb)
{
ExFreePool(Fcb->Buffer);
ExFreePool(Fcb);
}
if(AbsFileName)ExFreePool(AbsFileName); if(AbsFileName)ExFreePool(AbsFileName);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
@ -922,12 +948,14 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
ULONG CurrentCluster; ULONG CurrentCluster;
ULONG FileOffset; ULONG FileOffset;
ULONG FirstCluster; ULONG FirstCluster;
PVOID Temp; // PVOID Temp;
ULONG TempLength; ULONG TempLength;
/* PRECONDITION */ /* PRECONDITION */
assert(DeviceExt != NULL); assert(DeviceExt != NULL);
assert(DeviceExt->BytesPerCluster != 0); assert(DeviceExt->BytesPerCluster != 0);
assert(Fcb);
assert(Fcb->Buffer != NULL);
if (DeviceExt->FatType == FAT32) if (DeviceExt->FatType == FAT32)
CurrentCluster = Fcb->entry.FirstCluster CurrentCluster = Fcb->entry.FirstCluster
@ -946,9 +974,6 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
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);
if(!Temp) return STATUS_UNSUCCESSFUL;
if (FirstCluster==1) if (FirstCluster==1)
{ //root of FAT16 or FAT12 { //root of FAT16 or FAT12
CurrentCluster=DeviceExt->rootStart+ReadOffset CurrentCluster=DeviceExt->rootStart+ReadOffset
@ -964,19 +989,23 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
{ {
if (FirstCluster==1) if (FirstCluster==1)
{ {
VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster if(CurrentCluster!=Fcb->Cluster)
,DeviceExt->Boot->SectorsPerCluster,Temp); VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster
,DeviceExt->Boot->SectorsPerCluster,Fcb->Buffer);
Fcb->Cluster=CurrentCluster;
CurrentCluster += DeviceExt->Boot->SectorsPerCluster; CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
} }
else else
{ {
VFATLoadCluster(DeviceExt,Temp,CurrentCluster); if(CurrentCluster!=Fcb->Cluster)
VFATLoadCluster(DeviceExt,Fcb->Buffer,CurrentCluster);
Fcb->Cluster=CurrentCluster;
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster); CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
} }
TempLength = min(Length,DeviceExt->BytesPerCluster - TempLength = min(Length,DeviceExt->BytesPerCluster -
(ReadOffset % DeviceExt->BytesPerCluster)); (ReadOffset % DeviceExt->BytesPerCluster));
memcpy(Buffer, Temp + ReadOffset % DeviceExt->BytesPerCluster, memcpy(Buffer, Fcb->Buffer + ReadOffset % DeviceExt->BytesPerCluster,
TempLength); TempLength);
(*LengthRead) = (*LengthRead) + TempLength; (*LengthRead) = (*LengthRead) + TempLength;
@ -987,42 +1016,49 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
{ {
if (FirstCluster==1) if (FirstCluster==1)
{ {
VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster if(CurrentCluster!=Fcb->Cluster)
,DeviceExt->Boot->SectorsPerCluster,Buffer); VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster
,DeviceExt->Boot->SectorsPerCluster,Fcb->Buffer);
Fcb->Cluster=CurrentCluster;
CurrentCluster += DeviceExt->Boot->SectorsPerCluster; CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
} }
else else
{ {
VFATLoadCluster(DeviceExt,Buffer,CurrentCluster); if(CurrentCluster!=Fcb->Cluster)
VFATLoadCluster(DeviceExt,Fcb->Buffer,CurrentCluster);
Fcb->Cluster=CurrentCluster;
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster); CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
} }
if (CurrentCluster == 0xffffffff) memcpy(Buffer, Fcb->Buffer, DeviceExt->BytesPerCluster);
if (CurrentCluster == 0xffffffff)
{ {
ExFreePool(Temp);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
(*LengthRead) = (*LengthRead) + DeviceExt->BytesPerCluster; (*LengthRead) = (*LengthRead) + DeviceExt->BytesPerCluster;
Buffer = Buffer + DeviceExt->BytesPerCluster; Buffer = Buffer + DeviceExt->BytesPerCluster;
Length = Length - DeviceExt->BytesPerCluster; Length = Length - DeviceExt->BytesPerCluster;
} }
if (Length > 0) if (Length > 0)
{ {
(*LengthRead) = (*LengthRead) + Length; (*LengthRead) = (*LengthRead) + Length;
if (FirstCluster==1) if (FirstCluster==1)
{ {
if(CurrentCluster!=Fcb->Cluster)
VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster
,DeviceExt->Boot->SectorsPerCluster,Temp); ,DeviceExt->Boot->SectorsPerCluster,Fcb->Buffer);
CurrentCluster += DeviceExt->Boot->SectorsPerCluster; Fcb->Cluster=CurrentCluster;
} CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
}
else else
{ {
VFATLoadCluster(DeviceExt,Temp,CurrentCluster); if(CurrentCluster!=Fcb->Cluster)
VFATLoadCluster(DeviceExt,Fcb->Buffer,CurrentCluster);
Fcb->Cluster=CurrentCluster;
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster); CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
} }
memcpy(Buffer, Temp, Length); memcpy(Buffer, Fcb->Buffer, Length);
} }
ExFreePool(Temp);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
@ -1035,7 +1071,6 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
ULONG CurrentCluster; ULONG CurrentCluster;
ULONG FileOffset; ULONG FileOffset;
ULONG FirstCluster; ULONG FirstCluster;
PVOID Temp;
ULONG TempLength,Length2=Length; ULONG TempLength,Length2=Length;
CHECKPOINT; CHECKPOINT;
@ -1053,10 +1088,6 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
else else
CurrentCluster = Fcb->entry.FirstCluster; CurrentCluster = Fcb->entry.FirstCluster;
FirstCluster=CurrentCluster; FirstCluster=CurrentCluster;
/* Allocate a buffer to hold 1 cluster of data */
Temp = ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
assert(Temp);
/* Find the cluster according to the offset in the file */ /* Find the cluster according to the offset in the file */
@ -1095,26 +1126,29 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
TempLength = min(Length,DeviceExt->BytesPerCluster - TempLength = min(Length,DeviceExt->BytesPerCluster -
(WriteOffset % DeviceExt->BytesPerCluster)); (WriteOffset % DeviceExt->BytesPerCluster));
/* Read in the existing cluster data */ /* Read in the existing cluster data */
if (FirstCluster==1) if(CurrentCluster!=Fcb->Cluster)
VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster {
,DeviceExt->Boot->SectorsPerCluster,Temp); if (FirstCluster==1)
else VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster
VFATLoadCluster(DeviceExt,Temp,CurrentCluster); ,DeviceExt->Boot->SectorsPerCluster,Fcb->Buffer);
else
VFATLoadCluster(DeviceExt,Fcb->Buffer,CurrentCluster);
Fcb->Cluster=CurrentCluster;
}
/* Overwrite the last parts of the data as necessary */ /* Overwrite the last parts of the data as necessary */
memcpy(Temp + (WriteOffset % DeviceExt->BytesPerCluster), Buffer, memcpy(Fcb->Buffer + (WriteOffset % DeviceExt->BytesPerCluster), Buffer,
TempLength); TempLength);
/* Write the cluster back */ /* Write the cluster back */
if (FirstCluster==1) if (FirstCluster==1)
{ {
VFATWriteSectors(DeviceExt->StorageDevice,CurrentCluster VFATWriteSectors(DeviceExt->StorageDevice,CurrentCluster
,DeviceExt->Boot->SectorsPerCluster,Temp); ,DeviceExt->Boot->SectorsPerCluster,Fcb->Buffer);
CurrentCluster += DeviceExt->Boot->SectorsPerCluster; CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
} }
else else
{ {
VFATWriteCluster(DeviceExt,Temp,CurrentCluster); VFATWriteCluster(DeviceExt,Fcb->Buffer,CurrentCluster);
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster); CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
} }
Length2 -= TempLength; Length2 -= TempLength;
@ -1129,18 +1163,21 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
CHECKPOINT; CHECKPOINT;
if (CurrentCluster == 0) if (CurrentCluster == 0)
{ {
ExFreePool(Temp);
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
if (FirstCluster==1) if (FirstCluster==1)
{ {
VFATWriteSectors(DeviceExt->StorageDevice,CurrentCluster VFATWriteSectors(DeviceExt->StorageDevice,CurrentCluster
,DeviceExt->Boot->SectorsPerCluster,Buffer); ,DeviceExt->Boot->SectorsPerCluster,Buffer);
Fcb->Cluster=CurrentCluster;
memcpy(Fcb->Buffer,Buffer,DeviceExt->Boot->SectorsPerCluster);
CurrentCluster += DeviceExt->Boot->SectorsPerCluster; CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
} }
else else
{ {
VFATWriteCluster(DeviceExt,Buffer,CurrentCluster); VFATWriteCluster(DeviceExt,Buffer,CurrentCluster);
Fcb->Cluster=CurrentCluster;
memcpy(Fcb->Buffer,Buffer,DeviceExt->Boot->SectorsPerCluster);
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster); CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
} }
Buffer = Buffer + DeviceExt->BytesPerCluster; Buffer = Buffer + DeviceExt->BytesPerCluster;
@ -1154,23 +1191,26 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
{ {
if (CurrentCluster == 0) if (CurrentCluster == 0)
{ {
ExFreePool(Temp);
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
/* Read in the existing cluster data */ /* Read in the existing cluster data */
if (FirstCluster==1) if(CurrentCluster!=Fcb->Cluster)
VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster {
,DeviceExt->Boot->SectorsPerCluster,Temp); if (FirstCluster==1)
else VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster
VFATLoadCluster(DeviceExt,Temp,CurrentCluster); ,DeviceExt->Boot->SectorsPerCluster,Fcb->Buffer);
memcpy(Temp, Buffer, Length2); else
VFATLoadCluster(DeviceExt,Fcb->Buffer,CurrentCluster);
Fcb->Cluster=CurrentCluster;
}
memcpy(Fcb->Buffer, Buffer, Length2);
if (FirstCluster==1) if (FirstCluster==1)
{ {
VFATWriteSectors(DeviceExt->StorageDevice,CurrentCluster VFATWriteSectors(DeviceExt->StorageDevice,CurrentCluster
,DeviceExt->Boot->SectorsPerCluster,Temp); ,DeviceExt->Boot->SectorsPerCluster,Fcb->Buffer);
} }
else else
VFATWriteCluster(DeviceExt,Temp,CurrentCluster); VFATWriteCluster(DeviceExt,Fcb->Buffer,CurrentCluster);
} }
//FIXME : set last write time and date //FIXME : set last write time and date
if(Fcb->entry.FileSize<WriteOffset+Length if(Fcb->entry.FileSize<WriteOffset+Length
@ -1180,7 +1220,6 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
// update entry in directory // update entry in directory
updEntry(DeviceExt,Fcb); updEntry(DeviceExt,Fcb);
} }
ExFreePool(Temp);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
@ -1283,6 +1322,7 @@ NTSTATUS FsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
ExReleaseResourceForThreadLite(&(DeviceExt->Resource),ExGetCurrentResourceThread()); ExReleaseResourceForThreadLite(&(DeviceExt->Resource),ExGetCurrentResourceThread());
DbgPrint("open, Status=%x\n",Status);
return Status; return Status;
} }
@ -1345,9 +1385,9 @@ NTSTATUS FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
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);
assert(FileObject->FsContext2 != NULL); assert(FileObject->FsContext2 != NULL);
pFcb = ((PVfatCCB)(FileObject->FsContext2))->pFcb; pFcb = ((PVfatCCB)(FileObject->FsContext2))->pFcb;
assert(pFcb);
Status = FsdReadFile(DeviceExt,pFcb,Buffer,Length,Offset, Status = FsdReadFile(DeviceExt,pFcb,Buffer,Length,Offset,
&LengthRead); &LengthRead);
@ -1512,7 +1552,7 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
UNICODE_STRING ustr; UNICODE_STRING ustr;
ANSI_STRING astr; ANSI_STRING astr;
DbgPrint("VFAT 0.0.6\n"); DbgPrint("VFAT 0.0.7\n");
pFirstFcb=NULL; pFirstFcb=NULL;
VFATDriverObject = _DriverObject; VFATDriverObject = _DriverObject;