From 62eac3dcff35fceb5d6ebb00b54cd244577afac6 Mon Sep 17 00:00:00 2001 From: Hartmut Birr Date: Mon, 11 Nov 2002 21:49:18 +0000 Subject: [PATCH] * Used look aside lists to allocate memory for VFATFCB, VFATCCB and VFAT_IRP_CONTEXT. * Removed IsLastEntry, IsVolEntry, IsDeletedEntry, vfat_wstrlen, vfatGrabFCB, vfat_initstr, vfat_wcsncat, vfat_wcsncpy, vfat_movestr, wstrcmpi and replaced this functions with existing equivalents or functions from ntoskrnl. * Merged GetEntryName into vfatGetNextDirEntry for reducing some overhead. * Implemented a file name cache to speed up the searching for existing fcb. * Removed some calls to FsdDosDateTimeToFileTime. * Moved the call to CcZeroData behind the initializing of the cache (in VfatWrite). * Using existing fcbs in FindFile if there is no '*?' within the search name. svn path=/trunk/; revision=3740 --- reactos/drivers/fs/vfat/close.c | 8 +- reactos/drivers/fs/vfat/create.c | 424 ++++++++++------------------- reactos/drivers/fs/vfat/dir.c | 84 ++---- reactos/drivers/fs/vfat/direntry.c | 233 ++++++++-------- reactos/drivers/fs/vfat/dirwr.c | 14 +- reactos/drivers/fs/vfat/fcb.c | 259 ++++++++++++------ reactos/drivers/fs/vfat/finfo.c | 43 +-- reactos/drivers/fs/vfat/fsctl.c | 8 +- reactos/drivers/fs/vfat/iface.c | 8 +- reactos/drivers/fs/vfat/misc.c | 6 +- reactos/drivers/fs/vfat/rw.c | 14 +- reactos/drivers/fs/vfat/string.c | 98 +------ reactos/drivers/fs/vfat/vfat.h | 76 +++--- 13 files changed, 552 insertions(+), 723 deletions(-) diff --git a/reactos/drivers/fs/vfat/close.c b/reactos/drivers/fs/vfat/close.c index ccd49cec67e..823f32758cd 100644 --- a/reactos/drivers/fs/vfat/close.c +++ b/reactos/drivers/fs/vfat/close.c @@ -1,4 +1,4 @@ -/* $Id: close.c,v 1.14 2002/09/30 20:48:43 hbirr Exp $ +/* $Id: close.c,v 1.15 2002/11/11 21:49:17 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -72,10 +72,8 @@ VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject) else FileObject->FsContext2 = NULL; - if (pCcb->DirectorySearchPattern) - ExFreePool(pCcb->DirectorySearchPattern); - ExFreePool (pCcb); - + vfatDestroyCCB(pCcb); + return Status; } diff --git a/reactos/drivers/fs/vfat/create.c b/reactos/drivers/fs/vfat/create.c index 5cfb7b0c781..6d4a74dbf90 100644 --- a/reactos/drivers/fs/vfat/create.c +++ b/reactos/drivers/fs/vfat/create.c @@ -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.47 2002/10/01 19:27:17 chorns Exp $ +/* $Id: create.c,v 1.48 2002/11/11 21:49:17 hbirr Exp $ * * PROJECT: ReactOS kernel * FILE: services/fs/vfat/create.c @@ -42,39 +42,6 @@ /* FUNCTIONS *****************************************************************/ -BOOLEAN -IsLastEntry (PVOID Block, ULONG Offset) -/* - * FUNCTION: Determine if the given directory entry is the last - */ -{ - return (((FATDirEntry *) Block)[Offset].Filename[0] == 0); -} - -BOOLEAN -IsVolEntry (PVOID Block, ULONG Offset) -/* - * FUNCTION: Determine if the given directory entry is a vol entry - */ -{ - if ((((FATDirEntry *) Block)[Offset].Attrib) == 0x28) - return TRUE; - else - return FALSE; -} - -BOOLEAN -IsDeletedEntry (PVOID Block, ULONG Offset) -/* - * FUNCTION: Determines if the given entry is a deleted one - */ -{ - /* Checks special character */ - - return ((((FATDirEntry *) Block)[Offset].Filename[0] == 0xe5) || - (((FATDirEntry *) Block)[Offset].Filename[0] == 0)); -} - void vfat8Dot3ToString (PCHAR pBasename, PCHAR pExtension, PWSTR pName) { int fromIndex, toIndex; @@ -116,121 +83,6 @@ static void vfat8Dot3ToVolumeLabel (PCHAR pBasename, PCHAR pExtension, PWSTR pN pName [toIndex] = L'\0'; } -NTSTATUS -GetEntryName(PVOID *pContext, - PVOID *Block, - PFILE_OBJECT FileObject, - PWSTR Name, - PULONG pIndex, - PULONG pIndex2) -/* - * FUNCTION: Retrieves the file name, be it in short or long file name format - */ -{ - NTSTATUS Status; - FATDirEntry * test; - slot * test2; - ULONG cpos; - ULONG Offset = *pIndex % ENTRIES_PER_PAGE; - ULONG Read; - LARGE_INTEGER FileOffset; - - *Name = 0; - while (TRUE) - { - test = (FATDirEntry *) *Block; - test2 = (slot *) *Block; - if (vfatIsDirEntryEndMarker(&test[Offset])) - { - return STATUS_NO_MORE_ENTRIES; - } - if (test2[Offset].attr == 0x0f && !vfatIsDirEntryDeleted(&test[Offset])) - { - *Name = 0; - if (pIndex2) - *pIndex2 = *pIndex; // start of dir entry - - DPRINT (" long name entry found at %d\n", *pIndex); - - DPRINT (" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n", - 5, test2 [Offset].name0_4, - 6, test2 [Offset].name5_10, - 2, test2 [Offset].name11_12); - - vfat_initstr (Name, 255); - 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); - - DPRINT (" longName: [%S]\n", Name); - cpos = 0; - while ((test2[Offset].id != 0x41) && (test2[Offset].id != 0x01) && - (test2[Offset].attr > 0)) - { - (*pIndex)++; - Offset++; - - if (Offset == ENTRIES_PER_PAGE) - { - Offset = 0; - CcUnpinData(*pContext); - FileOffset.QuadPart = *pIndex * sizeof(FATDirEntry); - if(!CcMapData(FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, Block)) - { - *pContext = NULL; - return STATUS_NO_MORE_ENTRIES; - } - test2 = (slot *) *Block; - } - DPRINT (" long name entry found at %d\n", *pIndex); - - DPRINT (" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n", - 5, test2 [Offset].name0_4, - 6, test2 [Offset].name5_10, - 2, test2 [Offset].name11_12); - - 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); - - DPRINT (" longName: [%S]\n", Name); - } - (*pIndex)++; - Offset++; - if (Offset == ENTRIES_PER_PAGE) - { - Offset = 0; - CcUnpinData(*pContext); - FileOffset.QuadPart = *pIndex * sizeof(FATDirEntry); - if(!CcMapData(FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, Block)) - { - *pContext = NULL; - return STATUS_NO_MORE_ENTRIES; - } - test2 = (slot *) *Block; - test = (FATDirEntry*) *Block; - } - } - else - { - if (vfatIsDirEntryEndMarker(&test[Offset])) - return STATUS_NO_MORE_ENTRIES; - if (vfatIsDirEntryDeleted(&test[Offset])) - return STATUS_UNSUCCESSFUL; - if (*Name == 0) - { - vfat8Dot3ToString (test[Offset].Filename, test[Offset].Ext, Name); - if (pIndex2) - *pIndex2 = *pIndex; - } - break; - } - } - return STATUS_SUCCESS; -} - NTSTATUS ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb) /* @@ -238,7 +90,6 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb) */ { PVOID Context = NULL; - ULONG Offset = 0; ULONG DirIndex = 0; FATDirEntry* Entry; PVFATFCB pFcb; @@ -249,44 +100,39 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb) pFcb = vfatOpenRootFCB (DeviceExt); - while (TRUE) + FileOffset.QuadPart = 0; + if (CcMapData(pFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&Entry)) { - if (Context == NULL || Offset == ENTRIES_PER_PAGE) - { - if (Offset == ENTRIES_PER_PAGE) - { - Offset = 0; - } - if (Context) - { - CcUnpinData(Context); - } - FileOffset.u.HighPart = 0; - FileOffset.u.LowPart = (DirIndex - Offset) * sizeof(FATDirEntry); - if (!CcMapData(pFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&Entry)) - { - Context = NULL; - break; - } - } - if (IsVolEntry(Entry, Offset)) - { - /* copy volume label */ - vfat8Dot3ToVolumeLabel (Entry[Offset].Filename, Entry[Offset].Ext, Vpb->VolumeLabel); - Vpb->VolumeLabelLength = wcslen (Vpb->VolumeLabel) * sizeof(WCHAR); - break; - } - if (IsLastEntry(Entry, Offset)) - { - break; - } - Offset++; - DirIndex++; - } - - if (Context) - { - CcUnpinData(Context); + while (TRUE) + { + if (vfatIsDirEntryVolume(Entry)) + { + /* copy volume label */ + vfat8Dot3ToVolumeLabel (Entry->Filename, Entry->Ext, Vpb->VolumeLabel); + Vpb->VolumeLabelLength = wcslen (Vpb->VolumeLabel) * sizeof(WCHAR); + break; + } + if (vfatIsDirEntryEndMarker(Entry)) + { + break; + } + DirIndex++; + Entry++; + if ((DirIndex % ENTRIES_PER_PAGE) == 0) + { + CcUnpinData(Context); + FileOffset.u.LowPart += PAGE_SIZE; + if (!CcMapData(pFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&Entry)) + { + Context = NULL; + break; + } + } + } + if (Context) + { + CcUnpinData(Context); + } } vfatReleaseFCB (DeviceExt, pFcb); @@ -306,17 +152,18 @@ FindFile (PDEVICE_EXTENSION DeviceExt, { WCHAR name[256]; WCHAR name2[14]; - char * block; WCHAR TempStr[2]; NTSTATUS Status; ULONG len; ULONG DirIndex; - ULONG Offset; ULONG FirstCluster; ULONG Read; BOOL isRoot; - LARGE_INTEGER FileOffset; PVOID Context = NULL; + PVOID Page; + PVFATFCB rcFcb; + + FATDirEntry fatDirEntry; DPRINT ("FindFile(Parent %x, FileToFind '%S', DirIndex: %d)\n", Parent, FileToFind, pDirIndex ? *pDirIndex : 0); DPRINT ("FindFile: old Pathname %x, old Objectname %x)\n",Fcb->PathName, Fcb->ObjectName); @@ -355,30 +202,30 @@ FindFile (PDEVICE_EXTENSION DeviceExt, if (FileToFind[0] == 0 || (FileToFind[0] == '\\' && FileToFind[1] == 0) || (FileToFind[0] == '.' && FileToFind[1] == 0)) - { - /* it's root : complete essentials fields then return ok */ - CHECKPOINT; - memset (Fcb, 0, sizeof (VFATFCB)); - memset (Fcb->entry.Filename, ' ', 11); - CHECKPOINT; - Fcb->PathName[0]='\\'; - Fcb->ObjectName = &Fcb->PathName[1]; - Fcb->entry.FileSize = DeviceExt->FatInfo.rootDirectorySectors * DeviceExt->FatInfo.BytesPerSector; - Fcb->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY; - if (DeviceExt->FatInfo.FatType == FAT32) - { - Fcb->entry.FirstCluster = ((PUSHORT)FirstCluster)[0]; - Fcb->entry.FirstClusterHigh = ((PUSHORT)FirstCluster)[1]; - } - else - Fcb->entry.FirstCluster = 1; - if (pDirIndex) - *pDirIndex = 0; - if (pDirIndex2) - *pDirIndex2 = 0; - DPRINT("FindFile: new Pathname %S, new Objectname %S)\n",Fcb->PathName, Fcb->ObjectName); - return (STATUS_SUCCESS); - } + { + /* it's root : complete essentials fields then return ok */ + CHECKPOINT; + memset (Fcb, 0, sizeof (VFATFCB)); + memset (Fcb->entry.Filename, ' ', 11); + CHECKPOINT; + Fcb->PathName[0]='\\'; + Fcb->ObjectName = &Fcb->PathName[1]; + Fcb->entry.FileSize = DeviceExt->FatInfo.rootDirectorySectors * DeviceExt->FatInfo.BytesPerSector; + Fcb->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY; + if (DeviceExt->FatInfo.FatType == FAT32) + { + Fcb->entry.FirstCluster = ((PUSHORT)FirstCluster)[0]; + Fcb->entry.FirstClusterHigh = ((PUSHORT)FirstCluster)[1]; + } + else + Fcb->entry.FirstCluster = 1; + if (pDirIndex) + *pDirIndex = 0; + if (pDirIndex2) + *pDirIndex2 = 0; + DPRINT("FindFile: new Pathname %S, new Objectname %S)\n",Fcb->PathName, Fcb->ObjectName); + return (STATUS_SUCCESS); + } } else { @@ -388,78 +235,97 @@ FindFile (PDEVICE_EXTENSION DeviceExt, if (pDirIndex && (*pDirIndex)) DirIndex = *pDirIndex; - Offset = DirIndex % ENTRIES_PER_PAGE; + if (NULL == wcschr(FileToFind, L'?') && NULL == wcschr(FileToFind, L'*')) + { + /* if there is no '*?' in the search name, than look first for an existing fcb */ + len = wcslen(Parent->PathName); + memcpy(name, Parent->PathName, len * sizeof(WCHAR)); + if (!vfatFCBIsRoot(Parent)) + { + name[len++] = L'\\'; + } + wcscpy(name + len, FileToFind); + rcFcb = vfatGrabFCBFromTable(DeviceExt, name); + if (rcFcb) + { + if(rcFcb->startIndex >= DirIndex) + { + wcscpy(Fcb->PathName, name); + Fcb->ObjectName = &Fcb->PathName[len]; + memcpy(&Fcb->entry, &rcFcb->entry, sizeof(FATDirEntry)); + if (pDirIndex) + { + *pDirIndex = rcFcb->dirIndex; + } + if (pDirIndex2) + { + *pDirIndex2 = rcFcb->startIndex; + } + DPRINT("FindFile: new Pathname %S, new Objectname %S, DirIndex %d (%d)\n",Fcb->PathName, Fcb->ObjectName, rcFcb->dirIndex, rcFcb->startIndex); + vfatReleaseFCB(DeviceExt, rcFcb); + return STATUS_SUCCESS; + } + else + { + vfatReleaseFCB(DeviceExt, rcFcb); + return STATUS_UNSUCCESSFUL; + } + vfatReleaseFCB(DeviceExt, rcFcb); + } + } + while(TRUE) { - if (Context == NULL || Offset == ENTRIES_PER_PAGE) - { - if (Offset == ENTRIES_PER_PAGE) - Offset = 0; - if (Context) - { - CcUnpinData(Context); - } - FileOffset.QuadPart = (DirIndex - Offset) * sizeof(FATDirEntry); - if (!CcMapData(Parent->FileObject, &FileOffset, PAGE_SIZE, TRUE, - &Context, (PVOID*)&block)) - { - Context = NULL; - break; - } - } - if (vfatIsDirEntryVolume(&((FATDirEntry*)block)[Offset])) - { - Offset++; - DirIndex++; - continue; - } - Status = GetEntryName (&Context, (PVOID*)&block, Parent->FileObject, name, - &DirIndex, pDirIndex2); + Status = vfatGetNextDirEntry(&Context, &Page, Parent, &DirIndex, name, &fatDirEntry, pDirIndex2); if (Status == STATUS_NO_MORE_ENTRIES) - break; - Offset = DirIndex % ENTRIES_PER_PAGE; - if (NT_SUCCESS(Status)) - { - vfat8Dot3ToString(((FATDirEntry *) block)[Offset].Filename,((FATDirEntry *) block)[Offset].Ext, name2); - if (wstrcmpjoki (name, FileToFind) || wstrcmpjoki (name2, FileToFind)) - { - if (Parent && Parent->PathName) - { - len = wcslen(Parent->PathName); - CHECKPOINT; - memcpy(Fcb->PathName, Parent->PathName, len*sizeof(WCHAR)); - Fcb->ObjectName=&Fcb->PathName[len]; - if (len != 1 || Fcb->PathName[0] != '\\') - { - Fcb->ObjectName[0] = '\\'; - Fcb->ObjectName = &Fcb->ObjectName[1]; - } - } - else - { - Fcb->ObjectName=Fcb->PathName; - Fcb->ObjectName[0]='\\'; - Fcb->ObjectName=&Fcb->ObjectName[1]; - } - - memcpy (&Fcb->entry, &((FATDirEntry *) block)[Offset], - sizeof (FATDirEntry)); - vfat_wcsncpy (Fcb->ObjectName, name, MAX_PATH); - if (pDirIndex) - *pDirIndex = DirIndex; - DPRINT("FindFile: new Pathname %S, new Objectname %S, DirIndex %d\n",Fcb->PathName, Fcb->ObjectName, DirIndex); - if (Context) - CcUnpinData(Context); - return STATUS_SUCCESS; - } + { + break; + } + if (vfatIsDirEntryVolume(&fatDirEntry)) + { + DirIndex++; + continue; + } + vfat8Dot3ToString(fatDirEntry.Filename, fatDirEntry.Ext, name2); + if (wstrcmpjoki (name, FileToFind) || wstrcmpjoki (name2, FileToFind)) + { + if (Parent && Parent->PathName) + { + len = wcslen(Parent->PathName); + CHECKPOINT; + memcpy(Fcb->PathName, Parent->PathName, len*sizeof(WCHAR)); + Fcb->ObjectName=&Fcb->PathName[len]; + if (len != 1 || Fcb->PathName[0] != '\\') + { + Fcb->ObjectName[0] = '\\'; + Fcb->ObjectName = &Fcb->ObjectName[1]; + } + } + else + { + Fcb->ObjectName=Fcb->PathName; + Fcb->ObjectName[0]='\\'; + Fcb->ObjectName=&Fcb->ObjectName[1]; + } + memcpy(&Fcb->entry, &fatDirEntry, sizeof(FATDirEntry)); + wcsncpy(Fcb->ObjectName, *name == 0 ? name2 : name, MAX_PATH); + if (pDirIndex) + *pDirIndex = DirIndex; + DPRINT("FindFile: new Pathname %S, new Objectname %S, DirIndex %d\n",Fcb->PathName, Fcb->ObjectName, DirIndex); + + if (Context) + CcUnpinData(Context); + + return STATUS_SUCCESS; } - Offset++; DirIndex++; } if (pDirIndex) - *pDirIndex = DirIndex; + *pDirIndex = DirIndex; + if (Context) - CcUnpinData(Context); + CcUnpinData(Context); + return (STATUS_UNSUCCESSFUL); } @@ -692,7 +558,7 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) return(STATUS_NOT_A_DIRECTORY); } pFcb = DeviceExt->VolumeFcb; - pCcb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB); + pCcb = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList); if (pCcb == NULL) { return (STATUS_INSUFFICIENT_RESOURCES); diff --git a/reactos/drivers/fs/vfat/dir.c b/reactos/drivers/fs/vfat/dir.c index dac049d85d3..10049c3dc59 100644 --- a/reactos/drivers/fs/vfat/dir.c +++ b/reactos/drivers/fs/vfat/dir.c @@ -1,5 +1,5 @@ /* - * $Id: dir.c,v 1.26 2002/09/08 10:22:12 chorns Exp $ + * $Id: dir.c,v 1.27 2002/11/11 21:49:18 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -75,32 +75,14 @@ FsdFileTimeToDosDateTime (TIME * FileTime, WORD * pwDosDate, WORD * pwDosTime) } - -unsigned long -vfat_wstrlen (PWSTR s) -{ - WCHAR c = ' '; - unsigned int len = 0; - - while (c != 0) - { - c = *s; - s++; - len++; - }; - s -= len; - - return len - 1; -} - -#define DWORD_ROUND_UP(x) ( (((ULONG)(x))%32) ? ((((ULONG)x)&(~0x1f))+0x20) : ((ULONG)x) ) +#define DWORD_ROUND_UP(x) ROUND_UP((x), (sizeof(DWORD))) NTSTATUS VfatGetFileNameInformation (PVFATFCB pFcb, PFILE_NAMES_INFORMATION pInfo, ULONG BufferLength) { ULONG Length; - Length = vfat_wstrlen (pFcb->ObjectName) * sizeof(WCHAR); + Length = wcslen (pFcb->ObjectName) * sizeof(WCHAR); if ((sizeof (FILE_DIRECTORY_INFORMATION) + Length) > BufferLength) return STATUS_BUFFER_OVERFLOW; pInfo->FileNameLength = Length; @@ -116,9 +98,8 @@ VfatGetFileDirectoryInformation (PVFATFCB pFcb, PFILE_DIRECTORY_INFORMATION pInfo, ULONG BufferLength) { - unsigned long long AllocSize; ULONG Length; - Length = vfat_wstrlen (pFcb->ObjectName) * sizeof(WCHAR); + Length = wcslen (pFcb->ObjectName) * sizeof(WCHAR); if ((sizeof (FILE_DIRECTORY_INFORMATION) + Length) > BufferLength) return STATUS_BUFFER_OVERFLOW; pInfo->FileNameLength = Length; @@ -132,13 +113,12 @@ VfatGetFileDirectoryInformation (PVFATFCB pFcb, &pInfo->LastAccessTime); FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime, &pInfo->LastWriteTime); - FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime, - &pInfo->ChangeTime); - pInfo->EndOfFile = RtlConvertUlongToLargeInteger (pFcb->entry.FileSize); + pInfo->ChangeTime = pInfo->LastWriteTime; + pInfo->EndOfFile.u.HighPart = 0; + pInfo->EndOfFile.u.LowPart = pFcb->entry.FileSize; /* Make allocsize a rounded up multiple of BytesPerCluster */ - AllocSize = ((pFcb->entry.FileSize + DeviceExt->FatInfo.BytesPerCluster - 1) / - DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.BytesPerCluster; - pInfo->AllocationSize.QuadPart = AllocSize; + pInfo->AllocationSize.u.HighPart = 0; + pInfo->AllocationSize.u.LowPart = ROUND_UP(pFcb->entry.FileSize, DeviceExt->FatInfo.BytesPerCluster); pInfo->FileAttributes = pFcb->entry.Attrib; return STATUS_SUCCESS; @@ -150,9 +130,8 @@ VfatGetFileFullDirectoryInformation (PVFATFCB pFcb, PFILE_FULL_DIRECTORY_INFORMATION pInfo, ULONG BufferLength) { - unsigned long long AllocSize; ULONG Length; - Length = vfat_wstrlen (pFcb->ObjectName) * sizeof(WCHAR); + Length = wcslen (pFcb->ObjectName) * sizeof(WCHAR); if ((sizeof (FILE_FULL_DIRECTORY_INFORMATION) + Length) > BufferLength) return STATUS_BUFFER_OVERFLOW; pInfo->FileNameLength = Length; @@ -166,13 +145,12 @@ VfatGetFileFullDirectoryInformation (PVFATFCB pFcb, &pInfo->LastAccessTime); FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime, &pInfo->LastWriteTime); - FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime, - &pInfo->ChangeTime); - pInfo->EndOfFile = RtlConvertUlongToLargeInteger (pFcb->entry.FileSize); + pInfo->ChangeTime = pInfo->LastWriteTime; + pInfo->EndOfFile.u.HighPart = 0; + pInfo->EndOfFile.u.LowPart = pFcb->entry.FileSize; /* Make allocsize a rounded up multiple of BytesPerCluster */ - AllocSize = ((pFcb->entry.FileSize + DeviceExt->FatInfo.BytesPerCluster - 1) / - DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.BytesPerCluster; - pInfo->AllocationSize.QuadPart = AllocSize; + pInfo->AllocationSize.u.HighPart = 0; + pInfo->AllocationSize.u.LowPart = ROUND_UP(pFcb->entry.FileSize, DeviceExt->FatInfo.BytesPerCluster); pInfo->FileAttributes = pFcb->entry.Attrib; // pInfo->EaSize=; return STATUS_SUCCESS; @@ -184,15 +162,19 @@ VfatGetFileBothInformation (PVFATFCB pFcb, PFILE_BOTH_DIRECTORY_INFORMATION pInfo, ULONG BufferLength) { - short i; - unsigned long long AllocSize; ULONG Length; - Length = vfat_wstrlen (pFcb->ObjectName) * sizeof(WCHAR); + Length = wcslen (pFcb->ObjectName) * sizeof(WCHAR); if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length) > BufferLength) return STATUS_BUFFER_OVERFLOW; pInfo->FileNameLength = Length; - pInfo->NextEntryOffset = + pInfo->NextEntryOffset = DWORD_ROUND_UP (sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length); + /* + * vfatGetDirEntryName must be called befor the long name is copyed. + * The terminating null will overwrite the first character from long name. + */ + vfatGetDirEntryName(&pFcb->entry, pInfo->ShortName); + pInfo->ShortNameLength = wcslen(pInfo->ShortName) * sizeof(WCHAR); memcpy (pInfo->FileName, pFcb->ObjectName, Length); // pInfo->FileIndex=; FsdDosDateTimeToFileTime (pFcb->entry.CreationDate, @@ -201,24 +183,14 @@ VfatGetFileBothInformation (PVFATFCB pFcb, &pInfo->LastAccessTime); FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime, &pInfo->LastWriteTime); - FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime, - &pInfo->ChangeTime); - pInfo->EndOfFile = RtlConvertUlongToLargeInteger (pFcb->entry.FileSize); + pInfo->ChangeTime = pInfo->LastWriteTime; + pInfo->EndOfFile.u.HighPart = 0; + pInfo->EndOfFile.u.LowPart = pFcb->entry.FileSize; /* Make allocsize a rounded up multiple of BytesPerCluster */ - AllocSize = ((pFcb->entry.FileSize + DeviceExt->FatInfo.BytesPerCluster - 1) / - DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.BytesPerCluster; - pInfo->AllocationSize.QuadPart = AllocSize; + pInfo->AllocationSize.u.HighPart = 0; + pInfo->AllocationSize.u.LowPart = ROUND_UP(pFcb->entry.FileSize, DeviceExt->FatInfo.BytesPerCluster); pInfo->FileAttributes = pFcb->entry.Attrib; // pInfo->EaSize=; - for (i = 0; i < 8 && (pFcb->entry.Filename[i] != ' '); i++) - pInfo->ShortName[i] = pFcb->entry.Filename[i]; - pInfo->ShortNameLength = i; - pInfo->ShortName[i] = '.'; - for (i = 0; i < 3 && (pFcb->entry.Ext[i] != ' '); i++) - pInfo->ShortName[i + 1 + pInfo->ShortNameLength] = pFcb->entry.Ext[i]; - if (i) - pInfo->ShortNameLength += (i + 1); - pInfo->ShortNameLength *= sizeof(WCHAR); return STATUS_SUCCESS; } diff --git a/reactos/drivers/fs/vfat/direntry.c b/reactos/drivers/fs/vfat/direntry.c index f33b548350e..172008ab575 100644 --- a/reactos/drivers/fs/vfat/direntry.c +++ b/reactos/drivers/fs/vfat/direntry.c @@ -1,4 +1,4 @@ -/* $Id: direntry.c,v 1.9 2002/10/01 19:27:17 chorns Exp $ +/* $Id: direntry.c,v 1.10 2002/11/11 21:49:18 hbirr Exp $ * * * FILE: DirEntry.c @@ -20,12 +20,7 @@ #include "vfat.h" -#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->FatInfo.BytesPerCluster > PAGE_SIZE ? \ - (pDeviceExt)->FatInfo.BytesPerCluster : PAGE_SIZE) - -#define ENTRIES_PER_CACHEPAGE(pDeviceExt) (ENTRIES_PER_SECTOR * \ - (CACHEPAGESIZE(pDeviceExt) / ((pDeviceExt)->FatInfo.BytesPerSector))) - +#define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof (FATDirEntry)) ULONG vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt, @@ -76,131 +71,133 @@ vfatGetDirEntryName (PFAT_DIR_ENTRY dirEntry, PWSTR entryName) vfat8Dot3ToString (dirEntry->Filename, dirEntry->Ext, entryName); } -NTSTATUS -vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt, - PVFATFCB pDirectoryFCB, - ULONG * pDirectoryIndex, - PWSTR pLongFileName, - PFAT_DIR_ENTRY pDirEntry) + +NTSTATUS vfatGetNextDirEntry(PVOID * pContext, + PVOID * pPage, + IN PVFATFCB pDirFcb, + IN OUT PULONG pDirIndex, + OUT PWSTR pFileName, + OUT PFAT_DIR_ENTRY pDirEntry, + OUT PULONG pStartIndex) { - ULONG indexInPage = *pDirectoryIndex % ENTRIES_PER_CACHEPAGE(pDeviceExt); - ULONG pageNumber = *pDirectoryIndex / ENTRIES_PER_CACHEPAGE(pDeviceExt); - PVOID currentPage = NULL; - FATDirEntry * fatDirEntry; - slot * longNameEntry; - ULONG cpos; - LARGE_INTEGER FileOffset; - PVOID Context; + ULONG dirMap; + PWCHAR pName; + LARGE_INTEGER FileOffset; + FATDirEntry * fatDirEntry; + slot * longNameEntry; + ULONG index; - DPRINT ("vfatGetNextDirEntry (%x,%x,%d,%x,%x)\n", - pDeviceExt, - pDirectoryFCB, - *pDirectoryIndex, - pLongFileName, - pDirEntry); + DPRINT ("vfatGetNextDirEntry (%x,%x,%d,%x,%x)\n", + DeviceExt, + pDirFcb, + *pDirIndex, + pFileName, + pDirEntry); - *pLongFileName = 0; + *pFileName = 0; - FileOffset.QuadPart = pageNumber * CACHEPAGESIZE(pDeviceExt); - if (!CcMapData(pDirectoryFCB->FileObject, &FileOffset, - CACHEPAGESIZE(pDeviceExt), TRUE, &Context, ¤tPage)) - { - return STATUS_UNSUCCESSFUL; - } + FileOffset.u.HighPart = 0; + FileOffset.u.LowPart = ROUND_DOWN(*pDirIndex * sizeof(FATDirEntry), PAGE_SIZE); - while (TRUE) - { - fatDirEntry = (FATDirEntry *) currentPage; - - if (vfatIsDirEntryEndMarker (&fatDirEntry [indexInPage])) + if (*pContext == NULL || (*pDirIndex % ENTRIES_PER_PAGE) == 0) { - DPRINT ("end of directory, returning no more entries\n"); - CcUnpinData(Context); - return STATUS_NO_MORE_ENTRIES; + if (*pContext != NULL) + { + CcUnpinData(*pContext); + } + if (!CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage)) + { + *pContext = NULL; + return STATUS_NO_MORE_ENTRIES; + } } - else if (vfatIsDirEntryLongName (&fatDirEntry [indexInPage]) - && !vfatIsDirEntryDeleted (&fatDirEntry [indexInPage])) + + + fatDirEntry = (FATDirEntry*)(*pPage) + *pDirIndex % ENTRIES_PER_PAGE; + longNameEntry = (slot*) fatDirEntry; + dirMap = 0; + + if (pStartIndex) { - DPRINT (" long name entry found at %d\n", *pDirectoryIndex); - longNameEntry = (slot *) currentPage; - - DPRINT (" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n", - 5, longNameEntry [indexInPage].name0_4, - 6, longNameEntry [indexInPage].name5_10, - 2, longNameEntry [indexInPage].name11_12); - - vfat_initstr (pLongFileName, 256); - vfat_wcsncpy (pLongFileName, longNameEntry [indexInPage].name0_4, 5); - vfat_wcsncat (pLongFileName, longNameEntry [indexInPage].name5_10, 5, 6); - vfat_wcsncat (pLongFileName, longNameEntry [indexInPage].name11_12, 11, 2); - - DPRINT (" longName: [%S]\n", pLongFileName); - - cpos = 0; - while ((longNameEntry [indexInPage].id != 0x41) && - (longNameEntry [indexInPage].id != 0x01) && - (longNameEntry [indexInPage].attr > 0)) - { - (*pDirectoryIndex)++; - indexInPage++; - if (indexInPage == ENTRIES_PER_CACHEPAGE(pDeviceExt)) - { - indexInPage = 0; - pageNumber++; - - CcUnpinData(Context); - FileOffset.QuadPart = pageNumber * CACHEPAGESIZE(pDeviceExt); - if (!CcMapData(pDirectoryFCB->FileObject, &FileOffset, - CACHEPAGESIZE(pDeviceExt), TRUE, &Context, ¤tPage)) - { - return STATUS_UNSUCCESSFUL; - } - longNameEntry = (slot *) currentPage; - } - DPRINT (" index %d\n", *pDirectoryIndex); - - DPRINT (" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n", - 5, longNameEntry [indexInPage].name0_4, - 6, longNameEntry [indexInPage].name5_10, - 2, longNameEntry [indexInPage].name11_12); - - cpos++; - vfat_movstr (pLongFileName, 13, 0, cpos * 13); - vfat_wcsncpy (pLongFileName, longNameEntry [indexInPage].name0_4, 5); - vfat_wcsncat (pLongFileName, longNameEntry [indexInPage].name5_10, 5, 6); - vfat_wcsncat (pLongFileName, longNameEntry [indexInPage].name11_12, 11, 2); - - DPRINT (" longName: [%S]\n", pLongFileName); - - } - (*pDirectoryIndex)++; - indexInPage++; - if (indexInPage == ENTRIES_PER_CACHEPAGE(pDeviceExt)) - { - indexInPage = 0; - pageNumber++; - - CcUnpinData(Context); - FileOffset.QuadPart = pageNumber * CACHEPAGESIZE(pDeviceExt); - if (!CcMapData(pDirectoryFCB->FileObject, &FileOffset, - CACHEPAGESIZE(pDeviceExt), TRUE, &Context, ¤tPage)) - { - return STATUS_UNSUCCESSFUL; - } - } + *pStartIndex = *pDirIndex; } - else + + while (TRUE) { - memcpy (pDirEntry, &fatDirEntry [indexInPage], sizeof (FAT_DIR_ENTRY)); - (*pDirectoryIndex)++; - break; + if (vfatIsDirEntryEndMarker(fatDirEntry)) + { + CcUnpinData(*pContext); + *pContext = NULL; + return STATUS_NO_MORE_ENTRIES; + } + + if (vfatIsDirEntryDeleted (fatDirEntry)) + { + dirMap = 0; + *pFileName = 0; + if (pStartIndex) + { + *pStartIndex = *pDirIndex + 1; + } + } + else + { + if (vfatIsDirEntryLongName (fatDirEntry)) + { + if (dirMap == 0) + { + DPRINT (" long name entry found at %d\n", *pDirIndex); + memset(pFileName, 0, 256 * sizeof(WCHAR)); + } + + DPRINT (" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n", + 5, longNameEntry->name0_4, + 6, longNameEntry->name5_10, + 2, longNameEntry->name11_12); + + index = (longNameEntry->id & 0x1f) - 1; + dirMap |= 1 << index; + pName = pFileName + 13 * index; + + memcpy(pName, longNameEntry->name0_4, 5 * sizeof(WCHAR)); + memcpy(pName + 5, longNameEntry->name5_10, 6 * sizeof(WCHAR)); + memcpy(pName + 11, longNameEntry->name11_12, 2 * sizeof(WCHAR)); + + DPRINT (" longName: [%S]\n", pFileName); + } + else + { + memcpy (pDirEntry, fatDirEntry, sizeof (FAT_DIR_ENTRY)); + break; + } + } + (*pDirIndex)++; + if ((*pDirIndex % ENTRIES_PER_PAGE) == 0) + { + CcUnpinData(*pContext); + FileOffset.u.LowPart += PAGE_SIZE; + if (!CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage)) + { + CHECKPOINT; + *pContext = NULL; + return STATUS_NO_MORE_ENTRIES; + } + fatDirEntry = (FATDirEntry*)*pPage; + longNameEntry = (slot*) *pPage; + } + else + { + fatDirEntry++; + longNameEntry++; + } } - } - CcUnpinData(Context); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } + + + diff --git a/reactos/drivers/fs/vfat/dirwr.c b/reactos/drivers/fs/vfat/dirwr.c index 27d75c81347..bad894f6d3c 100644 --- a/reactos/drivers/fs/vfat/dirwr.c +++ b/reactos/drivers/fs/vfat/dirwr.c @@ -1,4 +1,4 @@ -/* $Id: dirwr.c,v 1.31 2002/10/01 19:27:18 chorns Exp $ +/* $Id: dirwr.c,v 1.32 2002/11/11 21:49:18 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -427,6 +427,16 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt, /* set dates and times */ KeQuerySystemTime (&SystemTime); ExSystemTimeToLocalTime (&SystemTime, &LocalTime); +#if 0 + { + TIME_FIELDS tf; + RtlTimeToTimeFields (&LocalTime, &tf); + DPRINT1("%d.%d.%d %02d:%02d:%02d.%03d '%S'\n", + tf.Day, tf.Month, tf.Year, tf.Hour, + tf.Minute, tf.Second, tf.Milliseconds, + pFileObject->FileName.Buffer); + } +#endif FsdFileTimeToDosDateTime ((TIME *) & LocalTime, &pEntry->CreationDate, &pEntry->CreationTime); pEntry->UpdateDate = pEntry->CreationDate; @@ -522,7 +532,7 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt, // FEXME: check status vfatMakeFCBFromDirEntry (DeviceExt, pDirFcb, FileName, pEntry, - start + nbSlots - 1, &newFCB); + start, start + nbSlots - 1, &newFCB); vfatAttachFCBToFileObject (DeviceExt, newFCB, pFileObject); DPRINT ("new : entry=%11.11s\n", newFCB->entry.Filename); diff --git a/reactos/drivers/fs/vfat/fcb.c b/reactos/drivers/fs/vfat/fcb.c index 647dcd358d7..79f7360733e 100644 --- a/reactos/drivers/fs/vfat/fcb.c +++ b/reactos/drivers/fs/vfat/fcb.c @@ -1,4 +1,4 @@ -/* $Id: fcb.c,v 1.21 2002/10/01 19:27:18 chorns Exp $ +/* $Id: fcb.c,v 1.22 2002/11/11 21:49:18 hbirr Exp $ * * * FILE: fcb.c @@ -29,30 +29,52 @@ /* -------------------------------------------------------- PUBLICS */ +ULONG vfatNameHash(ULONG hash, PWCHAR name) +{ + WCHAR c; + while(c = *name++) + { + c = towlower(c); + hash = (hash + (c << 4) + (c >> 4)) * 11; + } + return hash; +} + PVFATFCB vfatNewFCB(PWCHAR pFileName) { PVFATFCB rcFCB; - rcFCB = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATFCB), TAG_FCB); + rcFCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->FcbLookasideList); memset (rcFCB, 0, sizeof (VFATFCB)); if (pFileName) { wcscpy (rcFCB->PathName, pFileName); - if (wcsrchr (rcFCB->PathName, '\\') != 0) - { - rcFCB->ObjectName = wcsrchr (rcFCB->PathName, '\\'); - } - else + rcFCB->ObjectName = wcsrchr(rcFCB->PathName, L'\\'); + if (rcFCB->ObjectName == NULL) { rcFCB->ObjectName = rcFCB->PathName; } + rcFCB->Hash.Hash = vfatNameHash(0, rcFCB->PathName); + DPRINT("%08x (%03x) '%S'\n", rcFCB->Hash.Hash, rcFCB->Hash.Hash % FCB_HASH_TABLE_SIZE, pFileName); } + rcFCB->Hash.self = rcFCB; + rcFCB->ShortHash.self = rcFCB; ExInitializeResourceLite(&rcFCB->PagingIoResource); ExInitializeResourceLite(&rcFCB->MainResource); return rcFCB; } +VOID +vfatDestroyCCB(PVFATCCB pCcb) +{ + if (pCcb->DirectorySearchPattern) + { + ExFreePool(pCcb->DirectorySearchPattern); + } + ExFreeToNPagedLookasideList(&VfatGlobalData->CcbLookasideList, pCcb); +} + VOID vfatDestroyFCB(PVFATFCB pFCB) { @@ -60,11 +82,11 @@ vfatDestroyFCB(PVFATFCB pFCB) ExDeleteResourceLite(&pFCB->MainResource); if ((pFCB->Flags & FCB_IS_PAGE_FILE) && pFCB->FatChainSize) ExFreePool(pFCB->FatChain); - ExFreePool (pFCB); + ExFreeToNPagedLookasideList(&VfatGlobalData->FcbLookasideList, pFCB); } BOOL -vfatFCBIsDirectory(PDEVICE_EXTENSION pVCB, PVFATFCB FCB) +vfatFCBIsDirectory(PVFATFCB FCB) { return FCB->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY; } @@ -72,44 +94,63 @@ vfatFCBIsDirectory(PDEVICE_EXTENSION pVCB, PVFATFCB FCB) BOOL vfatFCBIsRoot(PVFATFCB FCB) { - return wcscmp (FCB->PathName, L"\\") == 0; -} - -VOID -vfatGrabFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB) -{ - KIRQL oldIrql; - - DPRINT ("grabbing FCB at %x: %S, refCount:%d\n", - pFCB, - pFCB->PathName, - pFCB->RefCount); - - KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql); - pFCB->RefCount++; - KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); + return FCB->PathName[0] == L'\\' && FCB->PathName[1] == 0 ? TRUE : FALSE; } VOID vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB) { KIRQL oldIrql; + HASHENTRY* entry; + ULONG Index; + ULONG ShortIndex; DPRINT ("releasing FCB at %x: %S, refCount:%d\n", pFCB, pFCB->PathName, pFCB->RefCount); + Index = pFCB->Hash.Hash % FCB_HASH_TABLE_SIZE; + ShortIndex = pFCB->ShortHash.Hash % FCB_HASH_TABLE_SIZE; KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql); pFCB->RefCount--; - if (pFCB->RefCount <= 0 && (!vfatFCBIsDirectory (pVCB, pFCB) || pFCB->Flags & FCB_DELETE_PENDING)) + if (pFCB->RefCount <= 0 && (!vfatFCBIsDirectory (pFCB) || pFCB->Flags & FCB_DELETE_PENDING)) { - RemoveEntryList (&pFCB->FcbListEntry); + RemoveEntryList (&pFCB->FcbListEntry); + if (pFCB->Hash.Hash != pFCB->ShortHash.Hash) + { + entry = pVCB->FcbHashTable[ShortIndex]; + if (entry->self == pFCB) + { + pVCB->FcbHashTable[ShortIndex] = entry->next; + } + else + { + while (entry->next->self != pFCB) + { + entry = entry->next; + } + entry->next = pFCB->ShortHash.next; + } + } + entry = pVCB->FcbHashTable[Index]; + if (entry->self == pFCB) + { + pVCB->FcbHashTable[Index] = entry->next; + } + else + { + while (entry->next->self != pFCB) + { + entry = entry->next; + } + entry->next = pFCB->Hash.next; + } KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); - if (vfatFCBIsDirectory(pVCB, pFCB)) + if (vfatFCBIsDirectory(pFCB)) { CcRosReleaseFileCache(pFCB->FileObject, pFCB->RFCB.Bcb); - ExFreePool(pFCB->FileObject->FsContext2); + vfatDestroyCCB(pFCB->FileObject->FsContext2); pFCB->FileObject->FsContext2 = NULL; ObDereferenceObject(pFCB->FileObject); } @@ -123,10 +164,22 @@ VOID vfatAddFCBToTable(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB) { KIRQL oldIrql; + ULONG Index; + ULONG ShortIndex; + Index = pFCB->Hash.Hash % FCB_HASH_TABLE_SIZE; + ShortIndex = pFCB->ShortHash.Hash % FCB_HASH_TABLE_SIZE; KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql); pFCB->pDevExt = pVCB; InsertTailList (&pVCB->FcbListHead, &pFCB->FcbListEntry); + + pFCB->Hash.next = pVCB->FcbHashTable[Index]; + pVCB->FcbHashTable[Index] = &pFCB->Hash; + if (pFCB->Hash.Hash != pFCB->ShortHash.Hash) + { + pFCB->ShortHash.next = pVCB->FcbHashTable[ShortIndex]; + pVCB->FcbHashTable[ShortIndex] = &pFCB->ShortHash; + } KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); } @@ -136,23 +189,60 @@ vfatGrabFCBFromTable(PDEVICE_EXTENSION pVCB, PWSTR pFileName) KIRQL oldIrql; PVFATFCB rcFCB; PLIST_ENTRY current_entry; + ULONG Hash; + PWCHAR ObjectName = NULL; + ULONG len; + ULONG index; + ULONG currentindex; + + HASHENTRY* entry; + + Hash = vfatNameHash(0, pFileName); KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql); - current_entry = pVCB->FcbListHead.Flink; - while (current_entry != &pVCB->FcbListHead) + entry = pVCB->FcbHashTable[Hash % FCB_HASH_TABLE_SIZE]; + + while (entry) { - rcFCB = CONTAINING_RECORD (current_entry, VFATFCB, FcbListEntry); + if (entry->Hash == Hash) + { + rcFCB = entry->self; + if (rcFCB->Hash.Hash == Hash) + { + /* compare the long name */ + if (!_wcsicmp(pFileName, rcFCB->PathName)) + { + rcFCB->RefCount++; + KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); + return rcFCB; + } + } + else + { + len = rcFCB->ObjectName - rcFCB->PathName + 1; + if (ObjectName == NULL) + { + ObjectName = wcsrchr(pFileName, L'\\'); + if (ObjectName == NULL) + { + ObjectName = pFileName; + } + else + { + ObjectName++; + } + } - if (wstrcmpi (pFileName, rcFCB->PathName)) - { - rcFCB->RefCount++; - KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); - return rcFCB; - } - - //FIXME: need to compare against short name in FCB here - - current_entry = current_entry->Flink; + /* compare the short name and the directory */ + if (!_wcsicmp(ObjectName, rcFCB->ShortName) && !_wcsnicmp(pFileName, rcFCB->PathName, len)) + { + rcFCB->RefCount++; + KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); + return rcFCB; + } + } + } + entry = entry->next; } KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); @@ -169,15 +259,14 @@ vfatFCBInitializeCacheFromVolume (PVCB vcb, PVFATFCB fcb) fileObject = IoCreateStreamFileObject (NULL, vcb->StorageDevice); - newCCB = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB); + newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList); if (newCCB == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } memset (newCCB, 0, sizeof (VFATCCB)); - fileObject->Flags = fileObject->Flags | FO_FCB_IS_VALID | - FO_DIRECT_CACHE_PAGING_READ; + fileObject->Flags |= FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ; fileObject->SectionObjectPointers = &fcb->SectionObjectPointers; fileObject->FsContext = (PVOID) &fcb->RFCB; fileObject->FsContext2 = newCCB; @@ -213,6 +302,9 @@ vfatMakeRootFCB(PDEVICE_EXTENSION pVCB) FCB = vfatNewFCB(L"\\"); memset(FCB->entry.Filename, ' ', 11); + FCB->ShortName[0] = L'\\'; + FCB->ShortName[1] = 0; + FCB->ShortHash.Hash = FCB->Hash.Hash; FCB->entry.FileSize = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector; FCB->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY; if (pVCB->FatInfo.FatType == FAT32) @@ -233,7 +325,7 @@ vfatMakeRootFCB(PDEVICE_EXTENSION pVCB) FCB->entry.FirstCluster = 1; Size = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector; } - FCB->RefCount = 1; + FCB->RefCount = 2; FCB->dirIndex = 0; FCB->RFCB.FileSize.QuadPart = Size; FCB->RFCB.ValidDataLength.QuadPart = Size; @@ -241,7 +333,6 @@ vfatMakeRootFCB(PDEVICE_EXTENSION pVCB) vfatFCBInitializeCacheFromVolume(pVCB, FCB); vfatAddFCBToTable(pVCB, FCB); - vfatGrabFCB(pVCB, FCB); return(FCB); } @@ -265,12 +356,16 @@ vfatMakeFCBFromDirEntry(PVCB vcb, PVFATFCB directoryFCB, PWSTR longName, PFAT_DIR_ENTRY dirEntry, + ULONG startIndex, ULONG dirIndex, PVFATFCB* fileFCB) { PVFATFCB rcFCB; WCHAR pathName [MAX_PATH]; + WCHAR entryName [14]; ULONG Size; + ULONG hash; + if (longName [0] != 0 && wcslen (directoryFCB->PathName) + sizeof(WCHAR) + wcslen (longName) > MAX_PATH) { @@ -281,21 +376,22 @@ vfatMakeFCBFromDirEntry(PVCB vcb, { wcscat (pathName, L"\\"); } + hash = vfatNameHash(0, pathName); + vfatGetDirEntryName (dirEntry, entryName); if (longName [0] != 0) { wcscat (pathName, longName); } else { - WCHAR entryName [MAX_PATH]; - - vfatGetDirEntryName (dirEntry, entryName); wcscat (pathName, entryName); } rcFCB = vfatNewFCB (pathName); memcpy (&rcFCB->entry, dirEntry, sizeof (FAT_DIR_ENTRY)); - - if (vfatFCBIsDirectory(vcb, rcFCB)) + wcscpy(rcFCB->ShortName, entryName); + rcFCB->ShortHash.Hash = vfatNameHash(hash, entryName); + + if (vfatFCBIsDirectory(rcFCB)) { ULONG FirstCluster, CurrentCluster; NTSTATUS Status; @@ -320,11 +416,12 @@ vfatMakeFCBFromDirEntry(PVCB vcb, Size = rcFCB->entry.FileSize; } rcFCB->dirIndex = dirIndex; + rcFCB->startIndex = startIndex; rcFCB->RFCB.FileSize.QuadPart = Size; rcFCB->RFCB.ValidDataLength.QuadPart = Size; rcFCB->RFCB.AllocationSize.QuadPart = ROUND_UP(Size, vcb->FatInfo.BytesPerCluster); rcFCB->RefCount++; - if (vfatFCBIsDirectory(vcb, rcFCB)) + if (vfatFCBIsDirectory(rcFCB)) { vfatFCBInitializeCacheFromVolume(vcb, rcFCB); } @@ -342,7 +439,7 @@ vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb, NTSTATUS status; PVFATCCB newCCB; - newCCB = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB); + newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList); if (newCCB == NULL) { return STATUS_INSUFFICIENT_RESOURCES; @@ -368,13 +465,15 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt, PWSTR pFileToFind, PVFATFCB * pFoundFCB) { - BOOL finishedScanningDirectory; ULONG directoryIndex; + ULONG startIndex; NTSTATUS status; WCHAR defaultFileName [2]; WCHAR currentLongName [256]; FAT_DIR_ENTRY currentDirEntry; WCHAR currentEntryName [256]; + PVOID Context = NULL; + PVOID Page; assert (pDeviceExt); assert (pDirectoryFCB); @@ -395,30 +494,25 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt, } directoryIndex = 0; - finishedScanningDirectory = FALSE; - while (!finishedScanningDirectory) + while (TRUE) { - status = vfatGetNextDirEntry (pDeviceExt, - pDirectoryFCB, - &directoryIndex, - currentLongName, - ¤tDirEntry); + status = vfatGetNextDirEntry(&Context, + &Page, + pDirectoryFCB, + &directoryIndex, + currentLongName, + ¤tDirEntry, + &startIndex); if (status == STATUS_NO_MORE_ENTRIES) { - finishedScanningDirectory = TRUE; - continue; - } - else if (!NT_SUCCESS(status)) - { - return status; + return STATUS_OBJECT_NAME_NOT_FOUND; } DPRINT (" Index:%d longName:%S\n", directoryIndex, currentLongName); - if (!vfatIsDirEntryDeleted (¤tDirEntry) - && !vfatIsDirEntryVolume(¤tDirEntry)) + if (!vfatIsDirEntryVolume(¤tDirEntry)) { if (currentLongName [0] != L'\0' && wstrcmpjoki (currentLongName, pFileToFind)) { @@ -427,8 +521,10 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt, pDirectoryFCB, currentLongName, ¤tDirEntry, - directoryIndex - 1, + startIndex, + directoryIndex, pFoundFCB); + CcUnpinData(Context); return status; } else @@ -443,12 +539,15 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt, pDirectoryFCB, currentLongName, ¤tDirEntry, - directoryIndex - 1, + startIndex, + directoryIndex, pFoundFCB); + CcUnpinData(Context); return status; } } } + directoryIndex++; } return STATUS_OBJECT_NAME_NOT_FOUND; @@ -484,11 +583,17 @@ vfatGetFCBForFile (PDEVICE_EXTENSION pVCB, return (FCB != NULL) ? STATUS_SUCCESS : STATUS_OBJECT_PATH_NOT_FOUND; } - else + + currentElement = wcsrchr(pFileName, L'\\'); + wcsncpy(pathName, pFileName, currentElement - pFileName); + currentElement++; + + FCB = vfatGrabFCBFromTable(pVCB, pathName); + if (FCB == NULL) { - currentElement = pFileName + 1; - wcscpy (pathName, L"\\"); - FCB = vfatOpenRootFCB (pVCB); + currentElement = pFileName + 1; + wcscpy (pathName, L"\\"); + FCB = vfatOpenRootFCB (pVCB); } parentFCB = NULL; @@ -512,7 +617,7 @@ vfatGetFCBForFile (PDEVICE_EXTENSION pVCB, parentFCB = 0; } // fail if element in FCB is not a directory - if (!vfatFCBIsDirectory (pVCB, FCB)) + if (!vfatFCBIsDirectory (FCB)) { DPRINT ("Element in requested path is not a directory\n"); diff --git a/reactos/drivers/fs/vfat/finfo.c b/reactos/drivers/fs/vfat/finfo.c index 27d5139b963..050df169052 100644 --- a/reactos/drivers/fs/vfat/finfo.c +++ b/reactos/drivers/fs/vfat/finfo.c @@ -1,4 +1,4 @@ -/* $Id: finfo.c,v 1.21 2002/09/30 20:47:28 hbirr Exp $ +/* $Id: finfo.c,v 1.22 2002/11/11 21:49:18 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -22,22 +22,17 @@ static NTSTATUS VfatGetStandardInformation(PVFATFCB FCB, - PDEVICE_OBJECT DeviceObject, PFILE_STANDARD_INFORMATION StandardInfo, PULONG BufferLength) /* * FUNCTION: Retrieve the standard file information */ { - PDEVICE_EXTENSION DeviceExtension; if (*BufferLength < sizeof(FILE_STANDARD_INFORMATION)) return STATUS_BUFFER_OVERFLOW; - DeviceExtension = DeviceObject->DeviceExtension; /* PRECONDITION */ - assert (DeviceExtension != NULL); - assert (DeviceExtension->FatInfo.BytesPerCluster != 0); assert (StandardInfo != NULL); assert (FCB != NULL); @@ -56,8 +51,6 @@ VfatGetStandardInformation(PVFATFCB FCB, static NTSTATUS VfatSetPositionInformation(PFILE_OBJECT FileObject, - PVFATFCB FCB, - PDEVICE_OBJECT DeviceObject, PFILE_POSITION_INFORMATION PositionInfo) { DPRINT ("FsdSetPositionInformation()\n"); @@ -113,9 +106,7 @@ VfatGetBasicInformation(PFILE_OBJECT FileObject, FsdDosDateTimeToFileTime(FCB->entry.UpdateDate, FCB->entry.UpdateTime, &BasicInfo->LastWriteTime); - FsdDosDateTimeToFileTime(FCB->entry.UpdateDate, - FCB->entry.UpdateTime, - &BasicInfo->ChangeTime); + BasicInfo->ChangeTime = BasicInfo->LastWriteTime; BasicInfo->FileAttributes = FCB->entry.Attrib; DPRINT("Getting attributes %x\n", BasicInfo->FileAttributes); @@ -165,7 +156,7 @@ VfatSetDispositionInformation(PFILE_OBJECT FileObject, } KeReleaseSpinLock(&DeviceExt->FcbListLock, oldIrql); DPRINT("RefCount:%d\n", count); - if (NT_SUCCESS(Status) && vfatFCBIsDirectory(DeviceExt, FCB)) + if (NT_SUCCESS(Status) && vfatFCBIsDirectory(FCB)) { memset (&tmpFcb, 0, sizeof(VFATFCB)); tmpFcb.ObjectName = tmpFcb.PathName; @@ -208,16 +199,13 @@ VfatGetNameInformation(PFILE_OBJECT FileObject, assert (FCB != NULL); NameLength = wcslen(FCB->PathName) * sizeof(WCHAR); - if (*BufferLength < sizeof(FILE_NAME_INFORMATION) + NameLength) + if (*BufferLength < sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR)) return STATUS_BUFFER_OVERFLOW; NameInfo->FileNameLength = NameLength; - memcpy(NameInfo->FileName, - FCB->PathName, - NameLength + sizeof(WCHAR)); + memcpy(NameInfo->FileName, FCB->PathName, NameLength + sizeof(WCHAR)); - *BufferLength -= - (sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR)); + *BufferLength -= (sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR)); return STATUS_SUCCESS; } @@ -262,9 +250,7 @@ VfatGetNetworkOpenInformation(PVFATFCB Fcb, FsdDosDateTimeToFileTime(Fcb->entry.UpdateDate, Fcb->entry.UpdateTime, &NetworkInfo->LastWriteTime); - FsdDosDateTimeToFileTime(Fcb->entry.UpdateDate, - Fcb->entry.UpdateTime, - &NetworkInfo->ChangeTime); + NetworkInfo->ChangeTime = NetworkInfo->LastWriteTime; NetworkInfo->AllocationSize = Fcb->RFCB.AllocationSize; NetworkInfo->EndOfFile = Fcb->RFCB.FileSize; NetworkInfo->FileAttributes = Fcb->entry.Attrib; @@ -289,7 +275,7 @@ VfatGetAllInformation(PFILE_OBJECT FileObject, assert (Fcb); NameLength = wcslen(Fcb->PathName) * sizeof(WCHAR); - if (*BufferLength < sizeof(FILE_ALL_INFORMATION) + NameLength) + if (*BufferLength < sizeof(FILE_ALL_INFORMATION) + NameLength + sizeof(WCHAR)) return(STATUS_BUFFER_OVERFLOW); /* Basic Information */ @@ -302,9 +288,7 @@ VfatGetAllInformation(PFILE_OBJECT FileObject, FsdDosDateTimeToFileTime(Fcb->entry.UpdateDate, Fcb->entry.UpdateTime, &Info->BasicInformation.LastWriteTime); - FsdDosDateTimeToFileTime(Fcb->entry.UpdateDate, - Fcb->entry.UpdateTime, - &Info->BasicInformation.ChangeTime); + Info->BasicInformation.ChangeTime = Info->BasicInformation.LastWriteTime; Info->BasicInformation.FileAttributes = Fcb->entry.Attrib; /* Standard Information */ @@ -335,9 +319,7 @@ VfatGetAllInformation(PFILE_OBJECT FileObject, /* Name Information */ Info->NameInformation.FileNameLength = NameLength; - RtlCopyMemory(Info->NameInformation.FileName, - Fcb->PathName, - NameLength + sizeof(WCHAR)); + RtlCopyMemory(Info->NameInformation.FileName, Fcb->PathName, NameLength + sizeof(WCHAR)); *BufferLength -= (sizeof(FILE_ALL_INFORMATION) + NameLength + sizeof(WCHAR)); @@ -451,7 +433,7 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject, Cluster = NCluster; } } - if (!vfatFCBIsDirectory(DeviceExt, Fcb)) + if (!vfatFCBIsDirectory(Fcb)) { Fcb->entry.FileSize = NewSize; } @@ -512,7 +494,6 @@ NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext) { case FileStandardInformation: RC = VfatGetStandardInformation(FCB, - IrpContext->DeviceObject, SystemBuffer, &BufferLength); break; @@ -621,8 +602,6 @@ NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext) { case FilePositionInformation: RC = VfatSetPositionInformation(IrpContext->FileObject, - FCB, - IrpContext->DeviceObject, SystemBuffer); break; case FileDispositionInformation: diff --git a/reactos/drivers/fs/vfat/fsctl.c b/reactos/drivers/fs/vfat/fsctl.c index 13925ed954f..6039fa04a34 100644 --- a/reactos/drivers/fs/vfat/fsctl.c +++ b/reactos/drivers/fs/vfat/fsctl.c @@ -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.11 2002/10/01 19:27:18 chorns Exp $ +/* $Id: fsctl.c,v 1.12 2002/11/11 21:49:18 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -291,7 +291,7 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext) Status = STATUS_INSUFFICIENT_RESOURCES; goto ByeBye; } - Ccb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB); + Ccb = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList); if (Ccb == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; @@ -367,9 +367,9 @@ ByeBye: if (DeviceExt && DeviceExt->FATFileObject) ObDereferenceObject (DeviceExt->FATFileObject); if (Fcb) - ExFreePool(Fcb); + vfatDestroyFCB(Fcb); if (Ccb) - ExFreePool(Ccb); + vfatDestroyCCB(Ccb); if (DeviceObject) IoDeleteDevice(DeviceObject); if (VolumeFcb) diff --git a/reactos/drivers/fs/vfat/iface.c b/reactos/drivers/fs/vfat/iface.c index f39f0a50ac5..05cba8fbb4f 100644 --- a/reactos/drivers/fs/vfat/iface.c +++ b/reactos/drivers/fs/vfat/iface.c @@ -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: iface.c,v 1.65 2002/08/20 20:37:07 hyperion Exp $ +/* $Id: iface.c,v 1.66 2002/11/11 21:49:18 hbirr Exp $ * * PROJECT: ReactOS kernel * FILE: services/fs/vfat/iface.c @@ -88,6 +88,12 @@ DriverEntry(PDRIVER_OBJECT DriverObject, DriverObject->DriverUnload = NULL; + ExInitializeNPagedLookasideList(&VfatGlobalData->FcbLookasideList, + NULL, NULL, 0, sizeof(VFATFCB), TAG_FCB, 0); + ExInitializeNPagedLookasideList(&VfatGlobalData->CcbLookasideList, + NULL, NULL, 0, sizeof(VFATCCB), TAG_CCB, 0); + ExInitializeNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList, + NULL, NULL, 0, sizeof(VFAT_IRP_CONTEXT), TAG_IRP, 0); IoRegisterFileSystem(DeviceObject); return(STATUS_SUCCESS); } diff --git a/reactos/drivers/fs/vfat/misc.c b/reactos/drivers/fs/vfat/misc.c index 4c13eb6ae75..8a0266b55d9 100644 --- a/reactos/drivers/fs/vfat/misc.c +++ b/reactos/drivers/fs/vfat/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.3 2002/09/30 20:49:44 hbirr Exp $ +/* $Id: misc.c,v 1.4 2002/11/11 21:49:18 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -94,7 +94,7 @@ NTSTATUS STDCALL VfatBuildRequest ( VOID VfatFreeIrpContext (PVFAT_IRP_CONTEXT IrpContext) { assert (IrpContext); - ExFreePool(IrpContext); + ExFreeToNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList, IrpContext); } PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject, PIRP Irp) @@ -107,7 +107,7 @@ PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject, PIRP Irp) assert (DeviceObject); assert (Irp); - IrpContext = ExAllocatePool (NonPagedPool, sizeof(VFAT_IRP_CONTEXT)); + IrpContext = ExAllocateFromNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList); if (IrpContext) { RtlZeroMemory(IrpContext, sizeof(IrpContext)); diff --git a/reactos/drivers/fs/vfat/rw.c b/reactos/drivers/fs/vfat/rw.c index 6fd18242314..7bf4c471724 100644 --- a/reactos/drivers/fs/vfat/rw.c +++ b/reactos/drivers/fs/vfat/rw.c @@ -1,5 +1,5 @@ -/* $Id: rw.c,v 1.49 2002/10/01 19:27:18 chorns Exp $ +/* $Id: rw.c,v 1.50 2002/11/11 21:49:18 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -945,10 +945,6 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext) } } - if (ByteOffset.QuadPart > OldFileSize.QuadPart) - { - CcZeroData(IrpContext->FileObject, &OldFileSize, &ByteOffset, TRUE); - } if (!(IrpContext->Irp->Flags & (IRP_NOCACHE|IRP_PAGING_IO)) && !(Fcb->Flags & (FCB_IS_PAGE_FILE|FCB_IS_VOLUME))) @@ -973,6 +969,10 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext) } CcRosInitializeFileCache(IrpContext->FileObject, &Fcb->RFCB.Bcb, CacheSize); } + if (ByteOffset.QuadPart > OldFileSize.QuadPart) + { + CcZeroData(IrpContext->FileObject, &OldFileSize, &ByteOffset, TRUE); + } if (CcCopyWrite(IrpContext->FileObject, &ByteOffset, Length, 1 /*IrpContext->Flags & IRPCONTEXT_CANWAIT*/, Buffer)) { @@ -990,6 +990,10 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext) // non cached write CHECKPOINT; + if (ByteOffset.QuadPart > OldFileSize.QuadPart) + { + CcZeroData(IrpContext->FileObject, &OldFileSize, &ByteOffset, TRUE); + } Buffer = VfatGetUserBuffer(IrpContext->Irp); if (!Buffer) { diff --git a/reactos/drivers/fs/vfat/string.c b/reactos/drivers/fs/vfat/string.c index b3a8c8a58e4..ce3514c00c9 100644 --- a/reactos/drivers/fs/vfat/string.c +++ b/reactos/drivers/fs/vfat/string.c @@ -1,4 +1,4 @@ -/* $Id: string.c,v 1.8 2001/07/05 01:51:53 rex Exp $ +/* $Id: string.c,v 1.9 2002/11/11 21:49:18 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -20,102 +20,6 @@ /* FUNCTIONS ****************************************************************/ -void vfat_initstr(wchar_t *wstr, ULONG wsize) -/* - * FUNCTION: Initialize a string for use with a long file name - */ -{ - int i; - wchar_t nc=0; - for(i=0; i @@ -122,6 +122,16 @@ typedef struct struct _VFATFCB; +typedef struct _HASHENTRY +{ + ULONG Hash; + struct _VFATFCB* self; + struct _HASHENTRY* next; +} +HASHENTRY; + +#define FCB_HASH_TABLE_SIZE 1024 + typedef struct { ERESOURCE DirResource; @@ -138,6 +148,7 @@ typedef struct BOOLEAN AvailableClustersValid; ULONG Flags; struct _VFATFCB * VolumeFcb; + struct _HASHENTRY* FcbHashTable[FCB_HASH_TABLE_SIZE]; } DEVICE_EXTENSION, *PDEVICE_EXTENSION, VCB, *PVCB; typedef struct @@ -145,6 +156,9 @@ typedef struct PDRIVER_OBJECT DriverObject; PDEVICE_OBJECT DeviceObject; ULONG Flags; + NPAGED_LOOKASIDE_LIST FcbLookasideList; + NPAGED_LOOKASIDE_LIST CcbLookasideList; + NPAGED_LOOKASIDE_LIST IrpContextLookasideList; } VFAT_GLOBAL_DATA, *PVFAT_GLOBAL_DATA; extern PVFAT_GLOBAL_DATA VfatGlobalData; @@ -165,6 +179,7 @@ typedef struct _VFATFCB WCHAR *ObjectName; /* path+filename 260 max */ WCHAR PathName[MAX_PATH]; + WCHAR ShortName[14]; LONG RefCount; PDEVICE_EXTENSION pDevExt; LIST_ENTRY FcbListEntry; @@ -172,10 +187,13 @@ typedef struct _VFATFCB ULONG Flags; PFILE_OBJECT FileObject; ULONG dirIndex; + ULONG startIndex; ERESOURCE PagingIoResource; ERESOURCE MainResource; ULONG TimerCount; SHARE_ACCESS FCBShareAccess; + HASHENTRY Hash; + HASHENTRY ShortHash; /* Structure members used only for paging files. */ ULONG FatChainSize; @@ -197,9 +215,13 @@ typedef struct _VFATCCB } VFATCCB, *PVFATCCB; +#ifndef TAG #define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24)) +#endif #define TAG_CCB TAG('V', 'C', 'C', 'B') +#define TAG_FCB TAG('V', 'F', 'C', 'B') +#define TAG_IRP TAG('V', 'I', 'R', 'P') #define ENTRIES_PER_SECTOR (BLOCKSIZE / sizeof(FATDirEntry)) @@ -350,26 +372,6 @@ NTSTATUS delEntry(PDEVICE_EXTENSION, /* -------------------------------------------------------- string.c */ -VOID vfat_initstr (wchar_t *wstr, - ULONG wsize); - -wchar_t* vfat_wcsncat (wchar_t * dest, - const wchar_t * src, - size_t wstart, - size_t wcount); - -wchar_t* vfat_wcsncpy (wchar_t * dest, - const wchar_t *src, - size_t wcount); - -wchar_t* vfat_movstr (wchar_t *src, - ULONG dpos, - ULONG spos, - ULONG len); - -BOOLEAN wstrcmpi (PWSTR s1, - PWSTR s2); - BOOLEAN wstrcmpjoki (PWSTR s1, PWSTR s2); @@ -420,11 +422,13 @@ BOOL vfatIsDirEntryEndMarker (FATDirEntry * pFatDirEntry); VOID vfatGetDirEntryName (PFAT_DIR_ENTRY pDirEntry, PWSTR pEntryName); -NTSTATUS vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt, - PVFATFCB pDirectoryFCB, - ULONG * pDirectoryIndex, - PWSTR pLongFileName, - PFAT_DIR_ENTRY pDirEntry); +NTSTATUS vfatGetNextDirEntry(PVOID * pContext, + PVOID * pPage, + IN PVFATFCB pDirFcb, + IN OUT PULONG pDirIndex, + OUT PWSTR pFileName, + OUT PFAT_DIR_ENTRY pDirEntry, + OUT PULONG pStartIndex); /* ----------------------------------------------------------- fcb.c */ @@ -448,8 +452,7 @@ PVFATFCB vfatMakeRootFCB (PDEVICE_EXTENSION pVCB); PVFATFCB vfatOpenRootFCB (PDEVICE_EXTENSION pVCB); -BOOL vfatFCBIsDirectory (PDEVICE_EXTENSION pVCB, - PVFATFCB FCB); +BOOL vfatFCBIsDirectory (PVFATFCB FCB); NTSTATUS vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb, PVFATFCB fcb, @@ -469,6 +472,7 @@ NTSTATUS vfatMakeFCBFromDirEntry (PVCB vcb, PVFATFCB directoryFCB, PWSTR longName, PFAT_DIR_ENTRY dirEntry, + ULONG startIndex, ULONG dirIndex, PVFATFCB * fileFCB); @@ -478,22 +482,6 @@ NTSTATUS VfatRead (PVFAT_IRP_CONTEXT IrpContext); NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext); -NTSTATUS VfatWriteFile (PDEVICE_EXTENSION DeviceExt, - PFILE_OBJECT FileObject, - PVOID Buffer, - ULONG Length, - ULONG WriteOffset, - BOOLEAN NoCache, - BOOLEAN PageIo); - - -NTSTATUS VfatReadFile (PDEVICE_EXTENSION DeviceExt, - PFILE_OBJECT FileObject, - PVOID Buffer, ULONG Length, - ULONG ReadOffset, - PULONG LengthRead, - ULONG NoCache); - NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb, ULONG FirstCluster,