-/* $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
else
FileObject->FsContext2 = NULL;
- if (pCcb->DirectorySearchPattern)
- ExFreePool(pCcb->DirectorySearchPattern);
- ExFreePool (pCcb);
-
+ vfatDestroyCCB(pCcb);
+
return Status;
}
* 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
/* 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;
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)
/*
*/
{
PVOID Context = NULL;
- ULONG Offset = 0;
ULONG DirIndex = 0;
FATDirEntry* Entry;
PVFATFCB pFcb;
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);
{
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);
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
{
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)
+ Status = vfatGetNextDirEntry(&Context, &Page, Parent, &DirIndex, name, &fatDirEntry, pDirIndex2);
+ if (Status == STATUS_NO_MORE_ENTRIES)
{
- 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;
- }
+ break;
}
- if (vfatIsDirEntryVolume(&((FATDirEntry*)block)[Offset]))
+ if (vfatIsDirEntryVolume(&fatDirEntry))
{
- Offset++;
DirIndex++;
- continue;
+ continue;
}
- Status = GetEntryName (&Context, (PVOID*)&block, Parent->FileObject, name,
- &DirIndex, 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))
+ 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] != '\\')
{
- 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;
+ 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);
}
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);
/*
- * $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
}
-
-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;
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;
&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;
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;
&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;
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,
&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;
}
-/* $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
#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,
vfat8Dot3ToString (dirEntry->Filename, dirEntry->Ext, entryName);
}
-NTSTATUS
-vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
- PVFATFCB pDirectoryFCB,
- ULONG * pDirectoryIndex,
- PWSTR pLongFileName,
- PFAT_DIR_ENTRY pDirEntry)
-{
- 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;
-
- DPRINT ("vfatGetNextDirEntry (%x,%x,%d,%x,%x)\n",
- pDeviceExt,
- pDirectoryFCB,
- *pDirectoryIndex,
- pLongFileName,
- pDirEntry);
-
- *pLongFileName = 0;
-
- FileOffset.QuadPart = pageNumber * CACHEPAGESIZE(pDeviceExt);
- if (!CcMapData(pDirectoryFCB->FileObject, &FileOffset,
- CACHEPAGESIZE(pDeviceExt), TRUE, &Context, ¤tPage))
- {
- return STATUS_UNSUCCESSFUL;
- }
-
- while (TRUE)
- {
- fatDirEntry = (FATDirEntry *) currentPage;
- if (vfatIsDirEntryEndMarker (&fatDirEntry [indexInPage]))
+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 dirMap;
+ PWCHAR pName;
+ LARGE_INTEGER FileOffset;
+ FATDirEntry * fatDirEntry;
+ slot * longNameEntry;
+ ULONG index;
+
+ DPRINT ("vfatGetNextDirEntry (%x,%x,%d,%x,%x)\n",
+ DeviceExt,
+ pDirFcb,
+ *pDirIndex,
+ pFileName,
+ pDirEntry);
+
+ *pFileName = 0;
+
+ FileOffset.u.HighPart = 0;
+ FileOffset.u.LowPart = ROUND_DOWN(*pDirIndex * sizeof(FATDirEntry), PAGE_SIZE);
+
+ 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;
}
+
+
+
-/* $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
/* 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;
// 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);
-/* $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
/* -------------------------------------------------------- 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)
{
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;
}
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);
}
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);
}
KIRQL oldIrql;
PVFATFCB rcFCB;
PLIST_ENTRY current_entry;
+ ULONG Hash;
+ PWCHAR ObjectName = NULL;
+ ULONG len;
+ ULONG index;
+ ULONG currentindex;
+
+ HASHENTRY* entry;
- KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql);
- current_entry = pVCB->FcbListHead.Flink;
- while (current_entry != &pVCB->FcbListHead)
- {
- rcFCB = CONTAINING_RECORD (current_entry, VFATFCB, FcbListEntry);
-
- if (wstrcmpi (pFileName, rcFCB->PathName))
- {
- rcFCB->RefCount++;
- KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
- return rcFCB;
- }
+ Hash = vfatNameHash(0, pFileName);
- //FIXME: need to compare against short name in FCB here
+ KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql);
+ entry = pVCB->FcbHashTable[Hash % FCB_HASH_TABLE_SIZE];
- current_entry = current_entry->Flink;
+ while (entry)
+ {
+ 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++;
+ }
+ }
+
+ /* 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);
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;
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)
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;
vfatFCBInitializeCacheFromVolume(pVCB, FCB);
vfatAddFCBToTable(pVCB, FCB);
- vfatGrabFCB(pVCB, FCB);
return(FCB);
}
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)
{
{
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;
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);
}
NTSTATUS status;
PVFATCCB newCCB;
- newCCB = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
+ newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
if (newCCB == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
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);
}
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))
{
pDirectoryFCB,
currentLongName,
¤tDirEntry,
- directoryIndex - 1,
+ startIndex,
+ directoryIndex,
pFoundFCB);
+ CcUnpinData(Context);
return status;
}
else
pDirectoryFCB,
currentLongName,
¤tDirEntry,
- directoryIndex - 1,
+ startIndex,
+ directoryIndex,
pFoundFCB);
+ CcUnpinData(Context);
return status;
}
}
}
+ directoryIndex++;
}
return STATUS_OBJECT_NAME_NOT_FOUND;
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;
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");
-/* $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
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);
static NTSTATUS
VfatSetPositionInformation(PFILE_OBJECT FileObject,
- PVFATFCB FCB,
- PDEVICE_OBJECT DeviceObject,
PFILE_POSITION_INFORMATION PositionInfo)
{
DPRINT ("FsdSetPositionInformation()\n");
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);
}
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;
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;
}
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;
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 */
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 */
/* 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));
Cluster = NCluster;
}
}
- if (!vfatFCBIsDirectory(DeviceExt, Fcb))
+ if (!vfatFCBIsDirectory(Fcb))
{
Fcb->entry.FileSize = NewSize;
}
{
case FileStandardInformation:
RC = VfatGetStandardInformation(FCB,
- IrpContext->DeviceObject,
SystemBuffer,
&BufferLength);
break;
{
case FilePositionInformation:
RC = VfatSetPositionInformation(IrpContext->FileObject,
- FCB,
- IrpContext->DeviceObject,
SystemBuffer);
break;
case FileDispositionInformation:
* 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
Status = STATUS_INSUFFICIENT_RESOURCES;
goto ByeBye;
}
- Ccb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
+ Ccb = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
if (Ccb == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
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)
* 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
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);
}
-/* $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
VOID VfatFreeIrpContext (PVFAT_IRP_CONTEXT IrpContext)
{
assert (IrpContext);
- ExFreePool(IrpContext);
+ ExFreeToNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList, IrpContext);
}
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));
-/* $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
}
}
- 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)))
}
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))
{
// non cached write
CHECKPOINT;
+ if (ByteOffset.QuadPart > OldFileSize.QuadPart)
+ {
+ CcZeroData(IrpContext->FileObject, &OldFileSize, &ByteOffset, TRUE);
+ }
Buffer = VfatGetUserBuffer(IrpContext->Irp);
if (!Buffer)
{
-/* $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
/* 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<wsize; i++)
- {
- *wstr=nc;
- wstr++;
- }
- wstr=wstr-wsize;
-}
-
-wchar_t * vfat_wcsncat(wchar_t * dest, const wchar_t * src,size_t wstart, size_t wcount)
-/*
- * FUNCTION: Append a string for use with a long file name
- */
-{
- int i;
-
- dest+=wstart;
- for(i=0; i<wcount; i++)
- {
- *dest=src[i];
- dest++;
- }
- dest=dest-(wcount+wstart);
-
- return dest;
-}
-
-wchar_t * vfat_wcsncpy(wchar_t * dest, const wchar_t *src,size_t wcount)
-/*
- * FUNCTION: Copy a string for use with long file names
- */
-{
- int i;
-
- for (i=0;i<wcount;i++)
- {
- dest[i]=src[i];
- if(!dest[i]) break;
- }
- return(dest);
-}
-
-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
- * string
- */
-{
- int i;
-
- if(dpos<=spos)
- {
- for(i=0; i<len; i++)
- {
- src[dpos++]=src[spos++];
- }
- }
- else
- {
- dpos+=len-1;
- spos+=len-1;
- for(i=0; i<len; i++)
- {
- src[dpos--]=src[spos--];
- }
- }
-
- return(src);
-}
-
-BOOLEAN wstrcmpi(PWSTR s1, PWSTR s2)
-/*
- * FUNCTION: Compare to wide character strings
- * return TRUE if s1==s2
- */
-{
- while (towlower(*s1)==towlower(*s2))
- {
- if ((*s1)==0 && (*s2)==0)
- {
- return(TRUE);
- }
-
- s1++;
- s2++;
- }
- return(FALSE);
-}
-
BOOLEAN wstrcmpjoki(PWSTR s1, PWSTR s2)
/*
* FUNCTION: Compare two wide character strings, s2 with jokers (* or ?)
-/* $Id: vfat.h,v 1.47 2002/09/08 10:22:13 chorns Exp $ */
+/* $Id: vfat.h,v 1.48 2002/11/11 21:49:18 hbirr Exp $ */
#include <ddk/ntifs.h>
struct _VFATFCB;
+typedef struct _HASHENTRY
+{
+ ULONG Hash;
+ struct _VFATFCB* self;
+ struct _HASHENTRY* next;
+}
+HASHENTRY;
+
+#define FCB_HASH_TABLE_SIZE 1024
+
typedef struct
{
ERESOURCE DirResource;
BOOLEAN AvailableClustersValid;
ULONG Flags;
struct _VFATFCB * VolumeFcb;
+ struct _HASHENTRY* FcbHashTable[FCB_HASH_TABLE_SIZE];
} DEVICE_EXTENSION, *PDEVICE_EXTENSION, VCB, *PVCB;
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;
WCHAR *ObjectName;
/* path+filename 260 max */
WCHAR PathName[MAX_PATH];
+ WCHAR ShortName[14];
LONG RefCount;
PDEVICE_EXTENSION pDevExt;
LIST_ENTRY FcbListEntry;
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;
} 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))
/* -------------------------------------------------------- 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);
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 */
PVFATFCB vfatOpenRootFCB (PDEVICE_EXTENSION pVCB);
-BOOL vfatFCBIsDirectory (PDEVICE_EXTENSION pVCB,
- PVFATFCB FCB);
+BOOL vfatFCBIsDirectory (PVFATFCB FCB);
NTSTATUS vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb,
PVFATFCB fcb,
PVFATFCB directoryFCB,
PWSTR longName,
PFAT_DIR_ENTRY dirEntry,
+ ULONG startIndex,
ULONG dirIndex,
PVFATFCB * fileFCB);
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,