* 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
This commit is contained in:
Hartmut Birr 2002-11-11 21:49:18 +00:00
parent 4ba36f62e4
commit 62eac3dcff
13 changed files with 552 additions and 723 deletions

View file

@ -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;
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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, &currentPage))
{
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, &currentPage))
{
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, &currentPage))
{
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;
}

View file

@ -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);

View file

@ -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,
&currentDirEntry);
status = vfatGetNextDirEntry(&Context,
&Page,
pDirectoryFCB,
&directoryIndex,
currentLongName,
&currentDirEntry,
&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 (&currentDirEntry)
&& !vfatIsDirEntryVolume(&currentDirEntry))
if (!vfatIsDirEntryVolume(&currentDirEntry))
{
if (currentLongName [0] != L'\0' && wstrcmpjoki (currentLongName, pFileToFind))
{
@ -427,8 +521,10 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt,
pDirectoryFCB,
currentLongName,
&currentDirEntry,
directoryIndex - 1,
startIndex,
directoryIndex,
pFoundFCB);
CcUnpinData(Context);
return status;
}
else
@ -443,12 +539,15 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt,
pDirectoryFCB,
currentLongName,
&currentDirEntry,
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");

View file

@ -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:

View file

@ -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)

View file

@ -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);
}

View file

@ -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));

View file

@ -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)
{

View file

@ -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<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 ?)

View file

@ -1,4 +1,4 @@
/* $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>
@ -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,