diff --git a/reactos/drivers/fs/vfat/iface.c b/reactos/drivers/fs/vfat/iface.c index cb4421806a2..acf76df8d29 100644 --- a/reactos/drivers/fs/vfat/iface.c +++ b/reactos/drivers/fs/vfat/iface.c @@ -1,5 +1,4 @@ - /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -33,7 +32,6 @@ #include "vfat.h" -//#include "dbgpool.c" /* GLOBALS *****************************************************************/ @@ -75,7 +73,6 @@ ULONG Fat16GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster) CurrentCluster = Block[CurrentCluster]; if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff) CurrentCluster = 0xffffffff; - DPRINT("Returning %x\n",CurrentCluster); return(CurrentCluster); } @@ -100,10 +97,8 @@ ULONG Fat12GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster) Entry = (CBlock[FATOffset] >> 4); Entry |= (CBlock[FATOffset+1] << 4); } - DPRINT("Entry %x\n",Entry); if (Entry >= 0xff8 && Entry <= 0xfff) Entry = 0xffffffff; - DPRINT("Returning %x\n",Entry); return(Entry); } @@ -113,8 +108,6 @@ ULONG GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster) */ { - DPRINT("GetNextCluster(DeviceExt %x, CurrentCluster %x)\n", - DeviceExt,CurrentCluster); if (DeviceExt->FatType == FAT16) return(Fat16GetNextCluster(DeviceExt, CurrentCluster)); else if (DeviceExt->FatType == FAT32) @@ -313,9 +306,7 @@ ULONG GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster) */ { ULONG LastCluster, NewCluster; - DPRINT("GetNextWriteCluster(DeviceExt %x, CurrentCluster %x)\n", - DeviceExt,CurrentCluster); - + UCHAR *Buffer2; /* Find out what was happening in the last cluster's AU */ LastCluster=GetNextCluster(DeviceExt,CurrentCluster); /* Check to see if we must append or overwrite */ @@ -335,6 +326,11 @@ ULONG GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster) found AU */ if(CurrentCluster) WriteCluster(DeviceExt, CurrentCluster, NewCluster); + // fill cluster with zero : essential for directories, not for file + Buffer2=ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster); + memset(Buffer2,0,DeviceExt->BytesPerCluster); + VFATWriteCluster(DeviceExt,Buffer2,NewCluster); + ExFreePool(Buffer2); /* Return NewCluster as CurrentCluster */ return NewCluster; } @@ -436,7 +432,7 @@ wchar_t * vfat_wcsncpy(wchar_t * dest, const wchar_t *src,size_t wcount) return(dest); } -wchar_t * vfat_movstr(const wchar_t *src, ULONG dpos, +wchar_t * vfat_movstr(wchar_t *src, ULONG dpos, ULONG spos, ULONG len) /* * FUNCTION: Move the characters in a string to a new position in the same @@ -465,109 +461,87 @@ wchar_t * vfat_movstr(const wchar_t *src, ULONG dpos, return(src); } -BOOLEAN IsLastEntry(PVOID Block, ULONG Offset) +BOOLEAN IsLastEntry(FATDirEntry *pEntry) /* * FUNCTION: Determine if the given directory entry is the last */ { - return(((FATDirEntry *)Block)[Offset].Filename[0] == 0); + return(pEntry->Filename[0] == 0); } -BOOLEAN IsVolEntry(PVOID Block, ULONG Offset) +BOOLEAN IsVolEntry(FATDirEntry *pEntry) /* * FUNCTION: Determine if the given directory entry is a vol entry */ { - if( (((FATDirEntry *)Block)[Offset].Attrib)==0x28 ) return TRUE; + if( (pEntry->Attrib)==0x28 ) return TRUE; else return FALSE; } -BOOLEAN IsDeletedEntry(PVOID Block, ULONG Offset) +BOOLEAN IsDeletedEntry(FATDirEntry *pEntry) /* * FUNCTION: Determines if the given entry is a deleted one */ { /* Checks special character */ - - return ((((FATDirEntry *)Block)[Offset].Filename[0] == 0xe5)); + return (pEntry->Filename[0] == 0xe5); } -BOOLEAN GetEntryName(PVOID Block, PULONG _Offset, PWSTR Name, PULONG _jloop, - PDEVICE_EXTENSION DeviceExt, ULONG * _StartingSector) +BOOLEAN GetEntryName(PDEVICE_EXTENSION DeviceExt,PVfatFCB pFcb,PULONG pEntry + , PWSTR Name,FATDirEntry *pFatEntry) /* * FUNCTION: Retrieves the file name, be it in short or long file name format */ { - FATDirEntry* test; - slot* test2; - ULONG Offset = *_Offset; - ULONG StartingSector = *_StartingSector; - ULONG jloop = *_jloop; - ULONG cpos; - WCHAR tmp[256]; + slot* test2; + ULONG cpos,LengthRead; + NTSTATUS Status; - test = (FATDirEntry *)Block; - test2 = (slot *)Block; + test2 = (slot *)pFatEntry; *Name = 0; - if (IsDeletedEntry(Block,Offset)) - { - return(FALSE); - } + if (IsDeletedEntry(pFatEntry)) + { + return(FALSE); + } - if(test2[Offset].attr == 0x0f) + if(test2->attr == 0x0f) + { // long name : we read the long name, then we read the entry + vfat_initstr(Name, 256); + vfat_wcsncpy(Name,test2->name0_4,5); + vfat_wcsncat(Name,test2->name5_10,5,6); + vfat_wcsncat(Name,test2->name11_12,11,2); + + cpos=0; + while((test2->id!=0x41) && (test2->id!=0x01) && + (test2->attr>0)) { - vfat_initstr(Name, 256); - vfat_wcsncpy(Name,test2[Offset].name0_4,5); - vfat_wcsncat(Name,test2[Offset].name5_10,5,6); - vfat_wcsncat(Name,test2[Offset].name11_12,11,2); - - cpos=0; - while((test2[Offset].id!=0x41) && (test2[Offset].id!=0x01) && - (test2[Offset].attr>0)) - { - Offset++; - if(Offset==ENTRIES_PER_SECTOR) { - Offset=0; - StartingSector++;//FIXME : nor always the next sector - jloop++; - VFATReadSectors(DeviceExt->StorageDevice,StartingSector,1,Block); - test2 = (slot *)Block; - } - cpos++; - vfat_movstr(Name, 13, 0, cpos*13); - vfat_wcsncpy(Name, test2[Offset].name0_4, 5); - vfat_wcsncat(Name,test2[Offset].name5_10,5,6); - vfat_wcsncat(Name,test2[Offset].name11_12,11,2); - - } - - if (IsDeletedEntry(Block,Offset+1)) - { - Offset++; - *_Offset = Offset; - *_jloop = jloop; - *_StartingSector = StartingSector; + (*pEntry)++; + Status=FsdReadFile(DeviceExt,pFcb,pFatEntry,sizeof(FATDirEntry) + ,(*pEntry)*sizeof(FATDirEntry),&LengthRead); + if(!(NT_SUCCESS(Status))) return FALSE; + cpos++; + vfat_movstr(Name, 13, 0, cpos*13); + vfat_wcsncpy(Name,test2->name0_4, 5); + vfat_wcsncat(Name,test2->name5_10,5,6); + vfat_wcsncat(Name,test2->name11_12,11,2); + } + // now read the entry + (*pEntry)++; + Status=FsdReadFile(DeviceExt,pFcb,pFatEntry,sizeof(FATDirEntry) + ,(*pEntry)*sizeof(FATDirEntry),&LengthRead); + if (IsDeletedEntry(pFatEntry)) return(FALSE); - } - - *_Offset = Offset; - *_jloop = jloop; - *_StartingSector = StartingSector; - - return(TRUE); - } + return(TRUE); + } - RtlAnsiToUnicode(Name,test[Offset].Filename,8); - if (test[Offset].Ext[0]!=' ') - { - RtlCatAnsiToUnicode(Name,".",1); - } - RtlCatAnsiToUnicode(Name,test[Offset].Ext,3); - - *_Offset = Offset; - + RtlAnsiToUnicode(Name,pFatEntry->Filename,8); + if (pFatEntry->Ext[0]!=' ') + { + RtlCatAnsiToUnicode(Name,".",1); + } + RtlCatAnsiToUnicode(Name,pFatEntry->Ext,3); return(TRUE); } @@ -615,39 +589,22 @@ BOOLEAN wstrcmpjoki(PWSTR s1, PWSTR s2) } NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb, - PVfatFCB Parent, PWSTR FileToFind,ULONG *StartSector,ULONG *Entry) + PVfatFCB Parent, PWSTR FileToFind,ULONG *Entry) /* * FUNCTION: Find a file */ { - ULONG i, j; + ULONG i; ULONG Size; - char* block; WCHAR name[256]; - ULONG StartingSector; - ULONG NextCluster; - WCHAR TempStr[2]; - - DPRINT("FindFile(Parent %x, FileToFind '%w')\n",Parent,FileToFind); - - if (wcslen(FileToFind)==0) - { - TempStr[0] = (WCHAR)'.'; - TempStr[1] = 0; - FileToFind=&TempStr; - } - if (Parent != NULL) - { - DPRINT("Parent->entry.FirstCluster %d\n",Parent->entry.FirstCluster); - } - + FATDirEntry FatEntry; + NTSTATUS Status; + ULONG LengthRead; + VfatFCB TempFcb; if (Parent == NULL||Parent->entry.FirstCluster==1) { Size = DeviceExt->rootDirectorySectors;//FIXME : in fat32, no limit - StartingSector = DeviceExt->rootStart; - NextCluster=0; - if(FileToFind[0]==0 ||(FileToFind[0]=='\\' && FileToFind[1]==0) || - (FileToFind[0]=='.' && FileToFind[1]==0)) + if(FileToFind[0]==0 ||(FileToFind[0]=='\\' && FileToFind[1]==0)) {// it's root : complete essentials fields then return ok memset(Fcb,0,sizeof(VfatFCB)); memset(Fcb->entry.Filename,' ',11); @@ -656,96 +613,47 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb, if (DeviceExt->FatType == FAT32) Fcb->entry.FirstCluster=2; else Fcb->entry.FirstCluster=1;//FIXME : is 1 the good value for mark root? - if(StartSector) *StartSector=StartingSector; if(Entry) *Entry=0; return(STATUS_SUCCESS); } } - else + if (Parent==NULL) { - DPRINT("Parent->entry.FileSize %x\n",Parent->entry.FileSize); - - Size = ULONG_MAX; - if (DeviceExt->FatType == FAT32) - NextCluster = Parent->entry.FirstCluster - +Parent->entry.FirstClusterHigh*65536; - else - NextCluster = Parent->entry.FirstCluster; - StartingSector = ClusterToSector(DeviceExt, NextCluster); - if(Parent->entry.FirstCluster==1 && DeviceExt->FatType!=FAT32) - {// read of root directory in FAT16 or FAT12 - StartingSector=DeviceExt->rootStart; - } + memset(&TempFcb,0,sizeof(VfatFCB)); + memset(TempFcb.entry.Filename,' ',11); + TempFcb.entry.FileSize=DeviceExt->rootDirectorySectors*BLOCKSIZE; + TempFcb.entry.Attrib=FILE_ATTRIBUTE_DIRECTORY; + if (DeviceExt->FatType == FAT32) + TempFcb.entry.FirstCluster=2; + else + TempFcb.entry.FirstCluster=1;//FIXME : is 1 the good value for mark root? + Parent=&TempFcb; } - block = ExAllocatePool(NonPagedPool,BLOCKSIZE); - if (StartSector && (*StartSector)) StartingSector=*StartSector; i=(Entry)?(*Entry):0; - DPRINT("FindFile : start at sector %lx, entry %ld\n",StartingSector,i); - for (j=0; jStorageDevice,StartingSector,1,block); - - for (i=(Entry)?(*Entry):0; iStorageDevice,StartingSector,1,block); - i=0; - } - memcpy(&Fcb->entry,&((FATDirEntry *)block)[i], - sizeof(FATDirEntry)); - vfat_wcsncpy(Fcb->ObjectName,name,MAX_PATH); - ExFreePool(block); - if(StartSector) *StartSector=StartingSector; - if(Entry) *Entry=i; - return(STATUS_SUCCESS); - } - } + if(Entry) *Entry=i; + return(STATUS_UNSUCCESSFUL); } - // not found in this sector, try next : - - /* directory can be fragmented although it is best to keep them - unfragmented */ - if(Entry) *Entry=0; - StartingSector++; - if ((Parent != NULL && Parent->entry.FirstCluster!=1) - || DeviceExt->FatType ==FAT32) + if (GetEntryName(DeviceExt,Parent,&i,name,&FatEntry)) { - if(StartingSector==ClusterToSector(DeviceExt,NextCluster+1)) + if (wstrcmpjoki(name,FileToFind)) { - NextCluster = GetNextCluster(DeviceExt,NextCluster); - if (NextCluster == 0||NextCluster==0xffffffff) - { - if(StartSector) *StartSector=StartingSector; - if(Entry) *Entry=i; - ExFreePool(block); - return(STATUS_UNSUCCESSFUL); - } - StartingSector = ClusterToSector(DeviceExt,NextCluster); + memcpy(&Fcb->entry,&FatEntry,sizeof(FATDirEntry)); + vfat_wcsncpy(Fcb->ObjectName,name,MAX_PATH); + if(Entry) *Entry=i; + return(STATUS_SUCCESS); } } } - ExFreePool(block); - if(StartSector) *StartSector=StartingSector; if(Entry) *Entry=i; return(STATUS_UNSUCCESSFUL); } @@ -758,21 +666,9 @@ NTSTATUS FsdCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject) { PVfatFCB pFcb; PVfatCCB pCcb; - - DPRINT("FsdCloseFile(DeviceExt %x, FileObject %x)\n", - DeviceExt,FileObject); - //FIXME : update entry in directory ? pCcb = (PVfatCCB)(FileObject->FsContext2); - - DPRINT("pCcb %x\n",pCcb); - if (pCcb == NULL) - { - return(STATUS_SUCCESS); - } - pFcb = pCcb->pFcb; - pFcb->RefCount--; if(pFcb->RefCount<=0) { @@ -805,13 +701,10 @@ NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, PFILE_OBJECT pRelFileObject; PWSTR AbsFileName=NULL; short i,j; - - DPRINT("FsdOpenFile(%08lx, %08lx, %w)\n", - DeviceExt, - FileObject, - FileName); - - //FIXME : treat relative name + if(FileObject->FileName.Length>0 + && FileName[FileObject->FileName.Length-1]=='\\') + FileName[FileObject->FileName.Length-1]=0; + // treat relative name if(FileObject->RelatedFileObject) { DbgPrint("try related for %w\n",FileName); @@ -828,7 +721,7 @@ DbgPrint("try related for %w\n",FileName); return Status; } // construct absolute path name - AbsFileName=ExAllocatePool(NonPagedPool,MAX_PATH); + AbsFileName=ExAllocatePool(NonPagedPool,MAX_PATH*sizeof(WCHAR)); for (i=0;pRelFcb->PathName[i];i++) AbsFileName[i]=pRelFcb->PathName[i]; AbsFileName[i++]='\\'; @@ -860,60 +753,63 @@ DbgPrint("try related for %w\n",FileName); Fcb = ExAllocatePool(NonPagedPool, sizeof(VfatFCB)); memset(Fcb,0,sizeof(VfatFCB)); Fcb->ObjectName=Fcb->PathName; - next = &string[0]; - + next = &string[0]; + current = next+1; + + if(*next==0) // root + { + Status = FindFile(DeviceExt,Fcb,ParentFcb,next,NULL); + ParentFcb=Fcb; + Fcb=NULL; + } + else while (next!=NULL) { *next = '\\'; current = next+1; next = wcschr(next+1,'\\'); if (next!=NULL) - { - *next=0; - } - DPRINT("current '%w'\n",current); - Status = FindFile(DeviceExt,Fcb,ParentFcb,current,NULL,NULL); - if (Status != STATUS_SUCCESS) - { - if (Fcb != NULL) - ExFreePool(Fcb); - if (ParentFcb != NULL) - ExFreePool(ParentFcb); - if(AbsFileName)ExFreePool(AbsFileName); - return(Status); - } - Temp = Fcb; - if (ParentFcb == NULL) - { - Fcb = ExAllocatePool(NonPagedPool,sizeof(VfatFCB)); - memset(Fcb,0,sizeof(VfatFCB)); - Fcb->ObjectName=Fcb->PathName; - } - else Fcb = ParentFcb; - ParentFcb = Temp; + *next=0; + Status = FindFile(DeviceExt,Fcb,ParentFcb,current,NULL); + if (Status != STATUS_SUCCESS) + { + if (Fcb != NULL) + ExFreePool(Fcb); + if (ParentFcb != NULL) + ExFreePool(ParentFcb); + if(AbsFileName)ExFreePool(AbsFileName); + return(Status); + } + Temp = Fcb; + if (ParentFcb == NULL) + { + Fcb = ExAllocatePool(NonPagedPool,sizeof(VfatFCB)); + memset(Fcb,0,sizeof(VfatFCB)); + Fcb->ObjectName=Fcb->PathName; + } + else Fcb = ParentFcb; + ParentFcb = Temp; } - FileObject->FsContext =(PVOID) &ParentFcb->NTRequiredFCB; - newCCB = ExAllocatePool(NonPagedPool,sizeof(VfatCCB)); - memset(newCCB,0,sizeof(VfatCCB)); - FileObject->FsContext2 = newCCB; - newCCB->pFcb=ParentFcb; - newCCB->PtrFileObject=FileObject; - ParentFcb->RefCount++; - //FIXME : initialize all fields in FCB and CCB - ParentFcb->nextFcb=pFirstFcb; - pFirstFcb=ParentFcb; + CHECKPOINT; + FileObject->FsContext =(PVOID) &ParentFcb->NTRequiredFCB; + newCCB = ExAllocatePool(NonPagedPool,sizeof(VfatCCB)); + memset(newCCB,0,sizeof(VfatCCB)); + FileObject->FsContext2 = newCCB; + newCCB->pFcb=ParentFcb; + newCCB->PtrFileObject=FileObject; + ParentFcb->RefCount++; + //FIXME : initialize all fields in FCB and CCB + ParentFcb->nextFcb=pFirstFcb; + pFirstFcb=ParentFcb; vfat_wcsncpy(ParentFcb->PathName,FileName,MAX_PATH); - ParentFcb->ObjectName=ParentFcb->PathName+(current-FileName); - ParentFcb->pDevExt=DeviceExt; - DPRINT("file open, fcb=%x\n",ParentFcb); - DPRINT("FileSize %d\n",ParentFcb->entry.FileSize); - if(Fcb) ExFreePool(Fcb); - if(AbsFileName)ExFreePool(AbsFileName); + ParentFcb->ObjectName=ParentFcb->PathName+(current-FileName); + ParentFcb->pDevExt=DeviceExt; + if(Fcb) ExFreePool(Fcb); + if(AbsFileName)ExFreePool(AbsFileName); return(STATUS_SUCCESS); - } - - - BOOLEAN FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount) +} + +BOOLEAN FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount) /* * FUNCTION: Tests if the device contains a filesystem that can be mounted * by this fsd @@ -921,7 +817,7 @@ DbgPrint("try related for %w\n",FileName); { BootSector* Boot; - Boot = ExAllocatePool(NonPagedPool,512); + Boot = ExAllocatePool(NonPagedPool,BLOCKSIZE); VFATReadSectors(DeviceToMount, 0, 1, (UCHAR *)Boot); @@ -944,8 +840,7 @@ NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt, { DPRINT("Mounting VFAT device..."); DPRINT("DeviceExt %x\n",DeviceExt); - - DeviceExt->Boot = ExAllocatePool(NonPagedPool,512); + DeviceExt->Boot = ExAllocatePool(NonPagedPool,BLOCKSIZE); VFATReadSectors(DeviceToMount, 0, 1, (UCHAR *)DeviceExt->Boot); DPRINT("DeviceExt->Boot->BytesPerSector %x\n", @@ -995,10 +890,6 @@ void VFATLoadCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster) */ { ULONG Sector; - - DPRINT("VFATLoadCluster(DeviceExt %x, Buffer %x, Cluster %d)\n", - DeviceExt,Buffer,Cluster); - Sector = ClusterToSector(DeviceExt, Cluster); VFATReadSectors(DeviceExt->StorageDevice, @@ -1013,9 +904,6 @@ void VFATWriteCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster) */ { ULONG Sector; - DPRINT("VFATWriteCluster(DeviceExt %x, Buffer %x, Cluster %d)\n", - DeviceExt,Buffer,Cluster); - Sector = ClusterToSector(DeviceExt, Cluster); VFATWriteSectors(DeviceExt->StorageDevice, @@ -1024,7 +912,7 @@ void VFATWriteCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster) Buffer); } -NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, +NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb, PVOID Buffer, ULONG Length, ULONG ReadOffset, PULONG LengthRead) /* @@ -1034,29 +922,19 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, 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; if (DeviceExt->FatType == FAT32) CurrentCluster = Fcb->entry.FirstCluster +Fcb->entry.FirstClusterHigh*65536; else CurrentCluster = Fcb->entry.FirstCluster; FirstCluster=CurrentCluster; - DPRINT("DeviceExt->BytesPerCluster %x\n",DeviceExt->BytesPerCluster); - if (ReadOffset >= Fcb->entry.FileSize && !(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)) { @@ -1082,7 +960,6 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, { CurrentCluster = GetNextCluster(DeviceExt,CurrentCluster); } - CHECKPOINT; if ((ReadOffset % DeviceExt->BytesPerCluster)!=0) { if (FirstCluster==1) @@ -1106,7 +983,6 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, Length = Length - TempLength; Buffer = Buffer + TempLength; } - CHECKPOINT; while (Length >= DeviceExt->BytesPerCluster) { if (FirstCluster==1) @@ -1130,7 +1006,6 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, Buffer = Buffer + DeviceExt->BytesPerCluster; Length = Length - DeviceExt->BytesPerCluster; } - CHECKPOINT; if (Length > 0) { (*LengthRead) = (*LengthRead) + Length; @@ -1151,7 +1026,7 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, return(STATUS_SUCCESS); } -NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, +NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb, PVOID Buffer, ULONG Length, ULONG WriteOffset) /* * FUNCTION: Writes data to file @@ -1160,17 +1035,19 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, ULONG CurrentCluster; ULONG FileOffset; ULONG FirstCluster; - PVfatFCB Fcb; - PVfatCCB pCcb; PVOID Temp; ULONG TempLength,Length2=Length; + CHECKPOINT; /* Locate the first cluster of the file */ - assert(FileObject); - pCcb=(PVfatCCB)(FileObject->FsContext2); - assert(pCcb); - Fcb = pCcb->pFcb; assert(Fcb); + if(WriteOffset==FILE_WRITE_TO_END_OF_FILE) + WriteOffset=Fcb->entry.FileSize; + if(!(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY) && WriteOffset>Fcb->entry.FileSize) + { + //FIXME : we must extend the file with null bytes then write buffer + return STATUS_UNSUCCESSFUL; + } if (DeviceExt->FatType == FAT32) CurrentCluster = Fcb->entry.FirstCluster+Fcb->entry.FirstClusterHigh*65536; else @@ -1275,22 +1152,18 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, if (Length2 > 0) { - CHECKPOINT; if (CurrentCluster == 0) { ExFreePool(Temp); return(STATUS_UNSUCCESSFUL); } - CHECKPOINT; /* Read in the existing cluster data */ if (FirstCluster==1) VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster ,DeviceExt->Boot->SectorsPerCluster,Temp); else VFATLoadCluster(DeviceExt,Temp,CurrentCluster); - CHECKPOINT; memcpy(Temp, Buffer, Length2); - CHECKPOINT; if (FirstCluster==1) { VFATWriteSectors(DeviceExt->StorageDevice,CurrentCluster @@ -1299,14 +1172,13 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, else VFATWriteCluster(DeviceExt,Temp,CurrentCluster); } - CHECKPOINT; //FIXME : set last write time and date if(Fcb->entry.FileSizeentry.Attrib &FILE_ATTRIBUTE_DIRECTORY)) { Fcb->entry.FileSize=WriteOffset+Length; // update entry in directory - updEntry(DeviceExt,FileObject); + updEntry(DeviceExt,Fcb); } ExFreePool(Temp); return(STATUS_SUCCESS); @@ -1322,8 +1194,6 @@ NTSTATUS FsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp) PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; NTSTATUS Status; - DPRINT("FsdClose(DeviceObject %x, Irp %x)\n",DeviceObject, Irp); - Status = FsdCloseFile(DeviceExtension,FileObject); Irp->IoStatus.Status = Status; @@ -1345,7 +1215,6 @@ NTSTATUS FsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp) ULONG RequestedDisposition,RequestedOptions; PVfatCCB pCcb; PVfatFCB pFcb; - assert(DeviceObject); assert(Irp); if(DeviceObject->Size==sizeof(DEVICE_OBJECT)) @@ -1430,6 +1299,7 @@ NTSTATUS FsdWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp) PFILE_OBJECT FileObject = Stack->FileObject; PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension; NTSTATUS Status; + PVfatFCB pFcb; DPRINT("FsdWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp); @@ -1437,7 +1307,9 @@ NTSTATUS FsdWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp) Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress); Offset = GET_LARGE_INTEGER_LOW_PART(Stack->Parameters.Write.ByteOffset); - Status = FsdWriteFile(DeviceExt,FileObject,Buffer,Length,Offset); + assert(FileObject->FsContext2 != NULL); + pFcb = ((PVfatCCB)(FileObject->FsContext2))->pFcb; + Status = FsdWriteFile(DeviceExt,pFcb,Buffer,Length,Offset); Irp->IoStatus.Status = Status; Irp->IoStatus.Information = Length; @@ -1459,9 +1331,8 @@ NTSTATUS FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp) PDEVICE_EXTENSION DeviceExt; NTSTATUS Status; ULONG LengthRead; + PVfatFCB pFcb; - DPRINT("FsdRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp); - /* Precondition / Initialization */ assert(Irp != NULL); Stack = IoGetCurrentIrpStackLocation(Irp); @@ -1475,7 +1346,9 @@ NTSTATUS FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp) Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress); Offset = GET_LARGE_INTEGER_LOW_PART(Stack->Parameters.Read.ByteOffset); - Status = FsdReadFile(DeviceExt,FileObject,Buffer,Length,Offset, + assert(FileObject->FsContext2 != NULL); + pFcb = ((PVfatCCB)(FileObject->FsContext2))->pFcb; + Status = FsdReadFile(DeviceExt,pFcb,Buffer,Length,Offset, &LengthRead); Irp->IoStatus.Status = Status; @@ -1539,7 +1412,6 @@ NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); return(Status); }