mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
* 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:
parent
4ba36f62e4
commit
62eac3dcff
13 changed files with 552 additions and 723 deletions
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -72,9 +72,7 @@ VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
|
||||||
else
|
else
|
||||||
FileObject->FsContext2 = NULL;
|
FileObject->FsContext2 = NULL;
|
||||||
|
|
||||||
if (pCcb->DirectorySearchPattern)
|
vfatDestroyCCB(pCcb);
|
||||||
ExFreePool(pCcb->DirectorySearchPattern);
|
|
||||||
ExFreePool (pCcb);
|
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: services/fs/vfat/create.c
|
* FILE: services/fs/vfat/create.c
|
||||||
|
@ -42,39 +42,6 @@
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* 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)
|
void vfat8Dot3ToString (PCHAR pBasename, PCHAR pExtension, PWSTR pName)
|
||||||
{
|
{
|
||||||
int fromIndex, toIndex;
|
int fromIndex, toIndex;
|
||||||
|
@ -116,121 +83,6 @@ static void vfat8Dot3ToVolumeLabel (PCHAR pBasename, PCHAR pExtension, PWSTR pN
|
||||||
pName [toIndex] = L'\0';
|
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
|
NTSTATUS
|
||||||
ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb)
|
ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb)
|
||||||
/*
|
/*
|
||||||
|
@ -238,7 +90,6 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb)
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PVOID Context = NULL;
|
PVOID Context = NULL;
|
||||||
ULONG Offset = 0;
|
|
||||||
ULONG DirIndex = 0;
|
ULONG DirIndex = 0;
|
||||||
FATDirEntry* Entry;
|
FATDirEntry* Entry;
|
||||||
PVFATFCB pFcb;
|
PVFATFCB pFcb;
|
||||||
|
@ -249,44 +100,39 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb)
|
||||||
|
|
||||||
pFcb = vfatOpenRootFCB (DeviceExt);
|
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)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
if (Offset == ENTRIES_PER_PAGE)
|
if (vfatIsDirEntryVolume(Entry))
|
||||||
{
|
{
|
||||||
Offset = 0;
|
/* copy volume label */
|
||||||
}
|
vfat8Dot3ToVolumeLabel (Entry->Filename, Entry->Ext, Vpb->VolumeLabel);
|
||||||
if (Context)
|
Vpb->VolumeLabelLength = wcslen (Vpb->VolumeLabel) * sizeof(WCHAR);
|
||||||
{
|
break;
|
||||||
CcUnpinData(Context);
|
}
|
||||||
}
|
if (vfatIsDirEntryEndMarker(Entry))
|
||||||
FileOffset.u.HighPart = 0;
|
{
|
||||||
FileOffset.u.LowPart = (DirIndex - Offset) * sizeof(FATDirEntry);
|
break;
|
||||||
if (!CcMapData(pFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&Entry))
|
}
|
||||||
{
|
DirIndex++;
|
||||||
Context = NULL;
|
Entry++;
|
||||||
break;
|
if ((DirIndex % ENTRIES_PER_PAGE) == 0)
|
||||||
}
|
{
|
||||||
}
|
CcUnpinData(Context);
|
||||||
if (IsVolEntry(Entry, Offset))
|
FileOffset.u.LowPart += PAGE_SIZE;
|
||||||
{
|
if (!CcMapData(pFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&Entry))
|
||||||
/* copy volume label */
|
{
|
||||||
vfat8Dot3ToVolumeLabel (Entry[Offset].Filename, Entry[Offset].Ext, Vpb->VolumeLabel);
|
Context = NULL;
|
||||||
Vpb->VolumeLabelLength = wcslen (Vpb->VolumeLabel) * sizeof(WCHAR);
|
break;
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
if (IsLastEntry(Entry, Offset))
|
}
|
||||||
{
|
if (Context)
|
||||||
break;
|
{
|
||||||
}
|
CcUnpinData(Context);
|
||||||
Offset++;
|
}
|
||||||
DirIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Context)
|
|
||||||
{
|
|
||||||
CcUnpinData(Context);
|
|
||||||
}
|
}
|
||||||
vfatReleaseFCB (DeviceExt, pFcb);
|
vfatReleaseFCB (DeviceExt, pFcb);
|
||||||
|
|
||||||
|
@ -306,17 +152,18 @@ FindFile (PDEVICE_EXTENSION DeviceExt,
|
||||||
{
|
{
|
||||||
WCHAR name[256];
|
WCHAR name[256];
|
||||||
WCHAR name2[14];
|
WCHAR name2[14];
|
||||||
char * block;
|
|
||||||
WCHAR TempStr[2];
|
WCHAR TempStr[2];
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG len;
|
ULONG len;
|
||||||
ULONG DirIndex;
|
ULONG DirIndex;
|
||||||
ULONG Offset;
|
|
||||||
ULONG FirstCluster;
|
ULONG FirstCluster;
|
||||||
ULONG Read;
|
ULONG Read;
|
||||||
BOOL isRoot;
|
BOOL isRoot;
|
||||||
LARGE_INTEGER FileOffset;
|
|
||||||
PVOID Context = NULL;
|
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(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);
|
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)
|
if (FileToFind[0] == 0 || (FileToFind[0] == '\\' && FileToFind[1] == 0)
|
||||||
|| (FileToFind[0] == '.' && FileToFind[1] == 0))
|
|| (FileToFind[0] == '.' && FileToFind[1] == 0))
|
||||||
{
|
{
|
||||||
/* it's root : complete essentials fields then return ok */
|
/* it's root : complete essentials fields then return ok */
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
memset (Fcb, 0, sizeof (VFATFCB));
|
memset (Fcb, 0, sizeof (VFATFCB));
|
||||||
memset (Fcb->entry.Filename, ' ', 11);
|
memset (Fcb->entry.Filename, ' ', 11);
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
Fcb->PathName[0]='\\';
|
Fcb->PathName[0]='\\';
|
||||||
Fcb->ObjectName = &Fcb->PathName[1];
|
Fcb->ObjectName = &Fcb->PathName[1];
|
||||||
Fcb->entry.FileSize = DeviceExt->FatInfo.rootDirectorySectors * DeviceExt->FatInfo.BytesPerSector;
|
Fcb->entry.FileSize = DeviceExt->FatInfo.rootDirectorySectors * DeviceExt->FatInfo.BytesPerSector;
|
||||||
Fcb->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY;
|
Fcb->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY;
|
||||||
if (DeviceExt->FatInfo.FatType == FAT32)
|
if (DeviceExt->FatInfo.FatType == FAT32)
|
||||||
{
|
{
|
||||||
Fcb->entry.FirstCluster = ((PUSHORT)FirstCluster)[0];
|
Fcb->entry.FirstCluster = ((PUSHORT)FirstCluster)[0];
|
||||||
Fcb->entry.FirstClusterHigh = ((PUSHORT)FirstCluster)[1];
|
Fcb->entry.FirstClusterHigh = ((PUSHORT)FirstCluster)[1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Fcb->entry.FirstCluster = 1;
|
Fcb->entry.FirstCluster = 1;
|
||||||
if (pDirIndex)
|
if (pDirIndex)
|
||||||
*pDirIndex = 0;
|
*pDirIndex = 0;
|
||||||
if (pDirIndex2)
|
if (pDirIndex2)
|
||||||
*pDirIndex2 = 0;
|
*pDirIndex2 = 0;
|
||||||
DPRINT("FindFile: new Pathname %S, new Objectname %S)\n",Fcb->PathName, Fcb->ObjectName);
|
DPRINT("FindFile: new Pathname %S, new Objectname %S)\n",Fcb->PathName, Fcb->ObjectName);
|
||||||
return (STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -388,78 +235,97 @@ FindFile (PDEVICE_EXTENSION DeviceExt,
|
||||||
if (pDirIndex && (*pDirIndex))
|
if (pDirIndex && (*pDirIndex))
|
||||||
DirIndex = *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)
|
while(TRUE)
|
||||||
{
|
{
|
||||||
if (Context == NULL || Offset == ENTRIES_PER_PAGE)
|
Status = vfatGetNextDirEntry(&Context, &Page, Parent, &DirIndex, name, &fatDirEntry, pDirIndex2);
|
||||||
{
|
|
||||||
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);
|
|
||||||
if (Status == STATUS_NO_MORE_ENTRIES)
|
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||||
break;
|
{
|
||||||
Offset = DirIndex % ENTRIES_PER_PAGE;
|
break;
|
||||||
if (NT_SUCCESS(Status))
|
}
|
||||||
{
|
if (vfatIsDirEntryVolume(&fatDirEntry))
|
||||||
vfat8Dot3ToString(((FATDirEntry *) block)[Offset].Filename,((FATDirEntry *) block)[Offset].Ext, name2);
|
{
|
||||||
if (wstrcmpjoki (name, FileToFind) || wstrcmpjoki (name2, FileToFind))
|
DirIndex++;
|
||||||
{
|
continue;
|
||||||
if (Parent && Parent->PathName)
|
}
|
||||||
{
|
vfat8Dot3ToString(fatDirEntry.Filename, fatDirEntry.Ext, name2);
|
||||||
len = wcslen(Parent->PathName);
|
if (wstrcmpjoki (name, FileToFind) || wstrcmpjoki (name2, FileToFind))
|
||||||
CHECKPOINT;
|
{
|
||||||
memcpy(Fcb->PathName, Parent->PathName, len*sizeof(WCHAR));
|
if (Parent && Parent->PathName)
|
||||||
Fcb->ObjectName=&Fcb->PathName[len];
|
{
|
||||||
if (len != 1 || Fcb->PathName[0] != '\\')
|
len = wcslen(Parent->PathName);
|
||||||
{
|
CHECKPOINT;
|
||||||
Fcb->ObjectName[0] = '\\';
|
memcpy(Fcb->PathName, Parent->PathName, len*sizeof(WCHAR));
|
||||||
Fcb->ObjectName = &Fcb->ObjectName[1];
|
Fcb->ObjectName=&Fcb->PathName[len];
|
||||||
}
|
if (len != 1 || Fcb->PathName[0] != '\\')
|
||||||
}
|
{
|
||||||
else
|
Fcb->ObjectName[0] = '\\';
|
||||||
{
|
Fcb->ObjectName = &Fcb->ObjectName[1];
|
||||||
Fcb->ObjectName=Fcb->PathName;
|
}
|
||||||
Fcb->ObjectName[0]='\\';
|
}
|
||||||
Fcb->ObjectName=&Fcb->ObjectName[1];
|
else
|
||||||
}
|
{
|
||||||
|
Fcb->ObjectName=Fcb->PathName;
|
||||||
memcpy (&Fcb->entry, &((FATDirEntry *) block)[Offset],
|
Fcb->ObjectName[0]='\\';
|
||||||
sizeof (FATDirEntry));
|
Fcb->ObjectName=&Fcb->ObjectName[1];
|
||||||
vfat_wcsncpy (Fcb->ObjectName, name, MAX_PATH);
|
}
|
||||||
if (pDirIndex)
|
memcpy(&Fcb->entry, &fatDirEntry, sizeof(FATDirEntry));
|
||||||
*pDirIndex = DirIndex;
|
wcsncpy(Fcb->ObjectName, *name == 0 ? name2 : name, MAX_PATH);
|
||||||
DPRINT("FindFile: new Pathname %S, new Objectname %S, DirIndex %d\n",Fcb->PathName, Fcb->ObjectName, DirIndex);
|
if (pDirIndex)
|
||||||
if (Context)
|
*pDirIndex = DirIndex;
|
||||||
CcUnpinData(Context);
|
DPRINT("FindFile: new Pathname %S, new Objectname %S, DirIndex %d\n",Fcb->PathName, Fcb->ObjectName, DirIndex);
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
if (Context)
|
||||||
|
CcUnpinData(Context);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
Offset++;
|
|
||||||
DirIndex++;
|
DirIndex++;
|
||||||
}
|
}
|
||||||
if (pDirIndex)
|
if (pDirIndex)
|
||||||
*pDirIndex = DirIndex;
|
*pDirIndex = DirIndex;
|
||||||
|
|
||||||
if (Context)
|
if (Context)
|
||||||
CcUnpinData(Context);
|
CcUnpinData(Context);
|
||||||
|
|
||||||
return (STATUS_UNSUCCESSFUL);
|
return (STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,7 +558,7 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
return(STATUS_NOT_A_DIRECTORY);
|
return(STATUS_NOT_A_DIRECTORY);
|
||||||
}
|
}
|
||||||
pFcb = DeviceExt->VolumeFcb;
|
pFcb = DeviceExt->VolumeFcb;
|
||||||
pCcb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
|
pCcb = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
|
||||||
if (pCcb == NULL)
|
if (pCcb == NULL)
|
||||||
{
|
{
|
||||||
return (STATUS_INSUFFICIENT_RESOURCES);
|
return (STATUS_INSUFFICIENT_RESOURCES);
|
||||||
|
|
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -75,32 +75,14 @@ FsdFileTimeToDosDateTime (TIME * FileTime, WORD * pwDosDate, WORD * pwDosTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define DWORD_ROUND_UP(x) ROUND_UP((x), (sizeof(DWORD)))
|
||||||
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) )
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
VfatGetFileNameInformation (PVFATFCB pFcb,
|
VfatGetFileNameInformation (PVFATFCB pFcb,
|
||||||
PFILE_NAMES_INFORMATION pInfo, ULONG BufferLength)
|
PFILE_NAMES_INFORMATION pInfo, ULONG BufferLength)
|
||||||
{
|
{
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
Length = vfat_wstrlen (pFcb->ObjectName) * sizeof(WCHAR);
|
Length = wcslen (pFcb->ObjectName) * sizeof(WCHAR);
|
||||||
if ((sizeof (FILE_DIRECTORY_INFORMATION) + Length) > BufferLength)
|
if ((sizeof (FILE_DIRECTORY_INFORMATION) + Length) > BufferLength)
|
||||||
return STATUS_BUFFER_OVERFLOW;
|
return STATUS_BUFFER_OVERFLOW;
|
||||||
pInfo->FileNameLength = Length;
|
pInfo->FileNameLength = Length;
|
||||||
|
@ -116,9 +98,8 @@ VfatGetFileDirectoryInformation (PVFATFCB pFcb,
|
||||||
PFILE_DIRECTORY_INFORMATION pInfo,
|
PFILE_DIRECTORY_INFORMATION pInfo,
|
||||||
ULONG BufferLength)
|
ULONG BufferLength)
|
||||||
{
|
{
|
||||||
unsigned long long AllocSize;
|
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
Length = vfat_wstrlen (pFcb->ObjectName) * sizeof(WCHAR);
|
Length = wcslen (pFcb->ObjectName) * sizeof(WCHAR);
|
||||||
if ((sizeof (FILE_DIRECTORY_INFORMATION) + Length) > BufferLength)
|
if ((sizeof (FILE_DIRECTORY_INFORMATION) + Length) > BufferLength)
|
||||||
return STATUS_BUFFER_OVERFLOW;
|
return STATUS_BUFFER_OVERFLOW;
|
||||||
pInfo->FileNameLength = Length;
|
pInfo->FileNameLength = Length;
|
||||||
|
@ -132,13 +113,12 @@ VfatGetFileDirectoryInformation (PVFATFCB pFcb,
|
||||||
&pInfo->LastAccessTime);
|
&pInfo->LastAccessTime);
|
||||||
FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime,
|
FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime,
|
||||||
&pInfo->LastWriteTime);
|
&pInfo->LastWriteTime);
|
||||||
FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime,
|
pInfo->ChangeTime = pInfo->LastWriteTime;
|
||||||
&pInfo->ChangeTime);
|
pInfo->EndOfFile.u.HighPart = 0;
|
||||||
pInfo->EndOfFile = RtlConvertUlongToLargeInteger (pFcb->entry.FileSize);
|
pInfo->EndOfFile.u.LowPart = pFcb->entry.FileSize;
|
||||||
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
||||||
AllocSize = ((pFcb->entry.FileSize + DeviceExt->FatInfo.BytesPerCluster - 1) /
|
pInfo->AllocationSize.u.HighPart = 0;
|
||||||
DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.BytesPerCluster;
|
pInfo->AllocationSize.u.LowPart = ROUND_UP(pFcb->entry.FileSize, DeviceExt->FatInfo.BytesPerCluster);
|
||||||
pInfo->AllocationSize.QuadPart = AllocSize;
|
|
||||||
pInfo->FileAttributes = pFcb->entry.Attrib;
|
pInfo->FileAttributes = pFcb->entry.Attrib;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -150,9 +130,8 @@ VfatGetFileFullDirectoryInformation (PVFATFCB pFcb,
|
||||||
PFILE_FULL_DIRECTORY_INFORMATION pInfo,
|
PFILE_FULL_DIRECTORY_INFORMATION pInfo,
|
||||||
ULONG BufferLength)
|
ULONG BufferLength)
|
||||||
{
|
{
|
||||||
unsigned long long AllocSize;
|
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
Length = vfat_wstrlen (pFcb->ObjectName) * sizeof(WCHAR);
|
Length = wcslen (pFcb->ObjectName) * sizeof(WCHAR);
|
||||||
if ((sizeof (FILE_FULL_DIRECTORY_INFORMATION) + Length) > BufferLength)
|
if ((sizeof (FILE_FULL_DIRECTORY_INFORMATION) + Length) > BufferLength)
|
||||||
return STATUS_BUFFER_OVERFLOW;
|
return STATUS_BUFFER_OVERFLOW;
|
||||||
pInfo->FileNameLength = Length;
|
pInfo->FileNameLength = Length;
|
||||||
|
@ -166,13 +145,12 @@ VfatGetFileFullDirectoryInformation (PVFATFCB pFcb,
|
||||||
&pInfo->LastAccessTime);
|
&pInfo->LastAccessTime);
|
||||||
FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime,
|
FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime,
|
||||||
&pInfo->LastWriteTime);
|
&pInfo->LastWriteTime);
|
||||||
FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime,
|
pInfo->ChangeTime = pInfo->LastWriteTime;
|
||||||
&pInfo->ChangeTime);
|
pInfo->EndOfFile.u.HighPart = 0;
|
||||||
pInfo->EndOfFile = RtlConvertUlongToLargeInteger (pFcb->entry.FileSize);
|
pInfo->EndOfFile.u.LowPart = pFcb->entry.FileSize;
|
||||||
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
||||||
AllocSize = ((pFcb->entry.FileSize + DeviceExt->FatInfo.BytesPerCluster - 1) /
|
pInfo->AllocationSize.u.HighPart = 0;
|
||||||
DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.BytesPerCluster;
|
pInfo->AllocationSize.u.LowPart = ROUND_UP(pFcb->entry.FileSize, DeviceExt->FatInfo.BytesPerCluster);
|
||||||
pInfo->AllocationSize.QuadPart = AllocSize;
|
|
||||||
pInfo->FileAttributes = pFcb->entry.Attrib;
|
pInfo->FileAttributes = pFcb->entry.Attrib;
|
||||||
// pInfo->EaSize=;
|
// pInfo->EaSize=;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -184,15 +162,19 @@ VfatGetFileBothInformation (PVFATFCB pFcb,
|
||||||
PFILE_BOTH_DIRECTORY_INFORMATION pInfo,
|
PFILE_BOTH_DIRECTORY_INFORMATION pInfo,
|
||||||
ULONG BufferLength)
|
ULONG BufferLength)
|
||||||
{
|
{
|
||||||
short i;
|
|
||||||
unsigned long long AllocSize;
|
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
Length = vfat_wstrlen (pFcb->ObjectName) * sizeof(WCHAR);
|
Length = wcslen (pFcb->ObjectName) * sizeof(WCHAR);
|
||||||
if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length) > BufferLength)
|
if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length) > BufferLength)
|
||||||
return STATUS_BUFFER_OVERFLOW;
|
return STATUS_BUFFER_OVERFLOW;
|
||||||
pInfo->FileNameLength = Length;
|
pInfo->FileNameLength = Length;
|
||||||
pInfo->NextEntryOffset =
|
pInfo->NextEntryOffset =
|
||||||
DWORD_ROUND_UP (sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length);
|
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);
|
memcpy (pInfo->FileName, pFcb->ObjectName, Length);
|
||||||
// pInfo->FileIndex=;
|
// pInfo->FileIndex=;
|
||||||
FsdDosDateTimeToFileTime (pFcb->entry.CreationDate,
|
FsdDosDateTimeToFileTime (pFcb->entry.CreationDate,
|
||||||
|
@ -201,24 +183,14 @@ VfatGetFileBothInformation (PVFATFCB pFcb,
|
||||||
&pInfo->LastAccessTime);
|
&pInfo->LastAccessTime);
|
||||||
FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime,
|
FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime,
|
||||||
&pInfo->LastWriteTime);
|
&pInfo->LastWriteTime);
|
||||||
FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime,
|
pInfo->ChangeTime = pInfo->LastWriteTime;
|
||||||
&pInfo->ChangeTime);
|
pInfo->EndOfFile.u.HighPart = 0;
|
||||||
pInfo->EndOfFile = RtlConvertUlongToLargeInteger (pFcb->entry.FileSize);
|
pInfo->EndOfFile.u.LowPart = pFcb->entry.FileSize;
|
||||||
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
||||||
AllocSize = ((pFcb->entry.FileSize + DeviceExt->FatInfo.BytesPerCluster - 1) /
|
pInfo->AllocationSize.u.HighPart = 0;
|
||||||
DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.BytesPerCluster;
|
pInfo->AllocationSize.u.LowPart = ROUND_UP(pFcb->entry.FileSize, DeviceExt->FatInfo.BytesPerCluster);
|
||||||
pInfo->AllocationSize.QuadPart = AllocSize;
|
|
||||||
pInfo->FileAttributes = pFcb->entry.Attrib;
|
pInfo->FileAttributes = pFcb->entry.Attrib;
|
||||||
// pInfo->EaSize=;
|
// 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;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
* FILE: DirEntry.c
|
||||||
|
@ -20,12 +20,7 @@
|
||||||
|
|
||||||
#include "vfat.h"
|
#include "vfat.h"
|
||||||
|
|
||||||
#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->FatInfo.BytesPerCluster > PAGE_SIZE ? \
|
#define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof (FATDirEntry))
|
||||||
(pDeviceExt)->FatInfo.BytesPerCluster : PAGE_SIZE)
|
|
||||||
|
|
||||||
#define ENTRIES_PER_CACHEPAGE(pDeviceExt) (ENTRIES_PER_SECTOR * \
|
|
||||||
(CACHEPAGESIZE(pDeviceExt) / ((pDeviceExt)->FatInfo.BytesPerSector)))
|
|
||||||
|
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
|
vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
|
||||||
|
@ -76,131 +71,133 @@ vfatGetDirEntryName (PFAT_DIR_ENTRY dirEntry, PWSTR entryName)
|
||||||
vfat8Dot3ToString (dirEntry->Filename, dirEntry->Ext, entryName);
|
vfat8Dot3ToString (dirEntry->Filename, dirEntry->Ext, entryName);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
|
NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
|
||||||
PVFATFCB pDirectoryFCB,
|
PVOID * pPage,
|
||||||
ULONG * pDirectoryIndex,
|
IN PVFATFCB pDirFcb,
|
||||||
PWSTR pLongFileName,
|
IN OUT PULONG pDirIndex,
|
||||||
PFAT_DIR_ENTRY pDirEntry)
|
OUT PWSTR pFileName,
|
||||||
|
OUT PFAT_DIR_ENTRY pDirEntry,
|
||||||
|
OUT PULONG pStartIndex)
|
||||||
{
|
{
|
||||||
ULONG indexInPage = *pDirectoryIndex % ENTRIES_PER_CACHEPAGE(pDeviceExt);
|
ULONG dirMap;
|
||||||
ULONG pageNumber = *pDirectoryIndex / ENTRIES_PER_CACHEPAGE(pDeviceExt);
|
PWCHAR pName;
|
||||||
PVOID currentPage = NULL;
|
LARGE_INTEGER FileOffset;
|
||||||
FATDirEntry * fatDirEntry;
|
FATDirEntry * fatDirEntry;
|
||||||
slot * longNameEntry;
|
slot * longNameEntry;
|
||||||
ULONG cpos;
|
ULONG index;
|
||||||
LARGE_INTEGER FileOffset;
|
|
||||||
PVOID Context;
|
|
||||||
|
|
||||||
DPRINT ("vfatGetNextDirEntry (%x,%x,%d,%x,%x)\n",
|
DPRINT ("vfatGetNextDirEntry (%x,%x,%d,%x,%x)\n",
|
||||||
pDeviceExt,
|
DeviceExt,
|
||||||
pDirectoryFCB,
|
pDirFcb,
|
||||||
*pDirectoryIndex,
|
*pDirIndex,
|
||||||
pLongFileName,
|
pFileName,
|
||||||
pDirEntry);
|
pDirEntry);
|
||||||
|
|
||||||
*pLongFileName = 0;
|
*pFileName = 0;
|
||||||
|
|
||||||
FileOffset.QuadPart = pageNumber * CACHEPAGESIZE(pDeviceExt);
|
FileOffset.u.HighPart = 0;
|
||||||
if (!CcMapData(pDirectoryFCB->FileObject, &FileOffset,
|
FileOffset.u.LowPart = ROUND_DOWN(*pDirIndex * sizeof(FATDirEntry), PAGE_SIZE);
|
||||||
CACHEPAGESIZE(pDeviceExt), TRUE, &Context, ¤tPage))
|
|
||||||
{
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (TRUE)
|
if (*pContext == NULL || (*pDirIndex % ENTRIES_PER_PAGE) == 0)
|
||||||
{
|
|
||||||
fatDirEntry = (FATDirEntry *) currentPage;
|
|
||||||
|
|
||||||
if (vfatIsDirEntryEndMarker (&fatDirEntry [indexInPage]))
|
|
||||||
{
|
{
|
||||||
DPRINT ("end of directory, returning no more entries\n");
|
if (*pContext != NULL)
|
||||||
CcUnpinData(Context);
|
{
|
||||||
return STATUS_NO_MORE_ENTRIES;
|
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);
|
*pStartIndex = *pDirIndex;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
while (TRUE)
|
||||||
{
|
{
|
||||||
memcpy (pDirEntry, &fatDirEntry [indexInPage], sizeof (FAT_DIR_ENTRY));
|
if (vfatIsDirEntryEndMarker(fatDirEntry))
|
||||||
(*pDirectoryIndex)++;
|
{
|
||||||
break;
|
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++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return STATUS_SUCCESS;
|
||||||
CcUnpinData(Context);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -427,6 +427,16 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||||
/* set dates and times */
|
/* set dates and times */
|
||||||
KeQuerySystemTime (&SystemTime);
|
KeQuerySystemTime (&SystemTime);
|
||||||
ExSystemTimeToLocalTime (&SystemTime, &LocalTime);
|
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,
|
FsdFileTimeToDosDateTime ((TIME *) & LocalTime, &pEntry->CreationDate,
|
||||||
&pEntry->CreationTime);
|
&pEntry->CreationTime);
|
||||||
pEntry->UpdateDate = pEntry->CreationDate;
|
pEntry->UpdateDate = pEntry->CreationDate;
|
||||||
|
@ -522,7 +532,7 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||||
|
|
||||||
// FEXME: check status
|
// FEXME: check status
|
||||||
vfatMakeFCBFromDirEntry (DeviceExt, pDirFcb, FileName, pEntry,
|
vfatMakeFCBFromDirEntry (DeviceExt, pDirFcb, FileName, pEntry,
|
||||||
start + nbSlots - 1, &newFCB);
|
start, start + nbSlots - 1, &newFCB);
|
||||||
vfatAttachFCBToFileObject (DeviceExt, newFCB, pFileObject);
|
vfatAttachFCBToFileObject (DeviceExt, newFCB, pFileObject);
|
||||||
|
|
||||||
DPRINT ("new : entry=%11.11s\n", newFCB->entry.Filename);
|
DPRINT ("new : entry=%11.11s\n", newFCB->entry.Filename);
|
||||||
|
|
|
@ -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
|
* FILE: fcb.c
|
||||||
|
@ -29,30 +29,52 @@
|
||||||
|
|
||||||
/* -------------------------------------------------------- PUBLICS */
|
/* -------------------------------------------------------- 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
|
PVFATFCB
|
||||||
vfatNewFCB(PWCHAR pFileName)
|
vfatNewFCB(PWCHAR pFileName)
|
||||||
{
|
{
|
||||||
PVFATFCB rcFCB;
|
PVFATFCB rcFCB;
|
||||||
|
|
||||||
rcFCB = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATFCB), TAG_FCB);
|
rcFCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->FcbLookasideList);
|
||||||
memset (rcFCB, 0, sizeof (VFATFCB));
|
memset (rcFCB, 0, sizeof (VFATFCB));
|
||||||
if (pFileName)
|
if (pFileName)
|
||||||
{
|
{
|
||||||
wcscpy (rcFCB->PathName, pFileName);
|
wcscpy (rcFCB->PathName, pFileName);
|
||||||
if (wcsrchr (rcFCB->PathName, '\\') != 0)
|
rcFCB->ObjectName = wcsrchr(rcFCB->PathName, L'\\');
|
||||||
{
|
if (rcFCB->ObjectName == NULL)
|
||||||
rcFCB->ObjectName = wcsrchr (rcFCB->PathName, '\\');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
rcFCB->ObjectName = rcFCB->PathName;
|
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->PagingIoResource);
|
||||||
ExInitializeResourceLite(&rcFCB->MainResource);
|
ExInitializeResourceLite(&rcFCB->MainResource);
|
||||||
return rcFCB;
|
return rcFCB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
vfatDestroyCCB(PVFATCCB pCcb)
|
||||||
|
{
|
||||||
|
if (pCcb->DirectorySearchPattern)
|
||||||
|
{
|
||||||
|
ExFreePool(pCcb->DirectorySearchPattern);
|
||||||
|
}
|
||||||
|
ExFreeToNPagedLookasideList(&VfatGlobalData->CcbLookasideList, pCcb);
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
vfatDestroyFCB(PVFATFCB pFCB)
|
vfatDestroyFCB(PVFATFCB pFCB)
|
||||||
{
|
{
|
||||||
|
@ -60,11 +82,11 @@ vfatDestroyFCB(PVFATFCB pFCB)
|
||||||
ExDeleteResourceLite(&pFCB->MainResource);
|
ExDeleteResourceLite(&pFCB->MainResource);
|
||||||
if ((pFCB->Flags & FCB_IS_PAGE_FILE) && pFCB->FatChainSize)
|
if ((pFCB->Flags & FCB_IS_PAGE_FILE) && pFCB->FatChainSize)
|
||||||
ExFreePool(pFCB->FatChain);
|
ExFreePool(pFCB->FatChain);
|
||||||
ExFreePool (pFCB);
|
ExFreeToNPagedLookasideList(&VfatGlobalData->FcbLookasideList, pFCB);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
vfatFCBIsDirectory(PDEVICE_EXTENSION pVCB, PVFATFCB FCB)
|
vfatFCBIsDirectory(PVFATFCB FCB)
|
||||||
{
|
{
|
||||||
return FCB->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY;
|
return FCB->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY;
|
||||||
}
|
}
|
||||||
|
@ -72,44 +94,63 @@ vfatFCBIsDirectory(PDEVICE_EXTENSION pVCB, PVFATFCB FCB)
|
||||||
BOOL
|
BOOL
|
||||||
vfatFCBIsRoot(PVFATFCB FCB)
|
vfatFCBIsRoot(PVFATFCB FCB)
|
||||||
{
|
{
|
||||||
return wcscmp (FCB->PathName, L"\\") == 0;
|
return FCB->PathName[0] == L'\\' && FCB->PathName[1] == 0 ? TRUE : FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
|
vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
|
||||||
{
|
{
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
HASHENTRY* entry;
|
||||||
|
ULONG Index;
|
||||||
|
ULONG ShortIndex;
|
||||||
|
|
||||||
DPRINT ("releasing FCB at %x: %S, refCount:%d\n",
|
DPRINT ("releasing FCB at %x: %S, refCount:%d\n",
|
||||||
pFCB,
|
pFCB,
|
||||||
pFCB->PathName,
|
pFCB->PathName,
|
||||||
pFCB->RefCount);
|
pFCB->RefCount);
|
||||||
|
|
||||||
|
Index = pFCB->Hash.Hash % FCB_HASH_TABLE_SIZE;
|
||||||
|
ShortIndex = pFCB->ShortHash.Hash % FCB_HASH_TABLE_SIZE;
|
||||||
KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql);
|
KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql);
|
||||||
pFCB->RefCount--;
|
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);
|
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
|
||||||
if (vfatFCBIsDirectory(pVCB, pFCB))
|
if (vfatFCBIsDirectory(pFCB))
|
||||||
{
|
{
|
||||||
CcRosReleaseFileCache(pFCB->FileObject, pFCB->RFCB.Bcb);
|
CcRosReleaseFileCache(pFCB->FileObject, pFCB->RFCB.Bcb);
|
||||||
ExFreePool(pFCB->FileObject->FsContext2);
|
vfatDestroyCCB(pFCB->FileObject->FsContext2);
|
||||||
pFCB->FileObject->FsContext2 = NULL;
|
pFCB->FileObject->FsContext2 = NULL;
|
||||||
ObDereferenceObject(pFCB->FileObject);
|
ObDereferenceObject(pFCB->FileObject);
|
||||||
}
|
}
|
||||||
|
@ -123,10 +164,22 @@ VOID
|
||||||
vfatAddFCBToTable(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
|
vfatAddFCBToTable(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
|
||||||
{
|
{
|
||||||
KIRQL oldIrql;
|
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);
|
KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql);
|
||||||
pFCB->pDevExt = pVCB;
|
pFCB->pDevExt = pVCB;
|
||||||
InsertTailList (&pVCB->FcbListHead, &pFCB->FcbListEntry);
|
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);
|
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,23 +189,60 @@ vfatGrabFCBFromTable(PDEVICE_EXTENSION pVCB, PWSTR pFileName)
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
PVFATFCB rcFCB;
|
PVFATFCB rcFCB;
|
||||||
PLIST_ENTRY current_entry;
|
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);
|
KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql);
|
||||||
current_entry = pVCB->FcbListHead.Flink;
|
entry = pVCB->FcbHashTable[Hash % FCB_HASH_TABLE_SIZE];
|
||||||
while (current_entry != &pVCB->FcbListHead)
|
|
||||||
|
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))
|
/* compare the short name and the directory */
|
||||||
{
|
if (!_wcsicmp(ObjectName, rcFCB->ShortName) && !_wcsnicmp(pFileName, rcFCB->PathName, len))
|
||||||
rcFCB->RefCount++;
|
{
|
||||||
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
|
rcFCB->RefCount++;
|
||||||
return rcFCB;
|
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
|
||||||
}
|
return rcFCB;
|
||||||
|
}
|
||||||
//FIXME: need to compare against short name in FCB here
|
}
|
||||||
|
}
|
||||||
current_entry = current_entry->Flink;
|
entry = entry->next;
|
||||||
}
|
}
|
||||||
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
|
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
|
||||||
|
|
||||||
|
@ -169,15 +259,14 @@ vfatFCBInitializeCacheFromVolume (PVCB vcb, PVFATFCB fcb)
|
||||||
|
|
||||||
fileObject = IoCreateStreamFileObject (NULL, vcb->StorageDevice);
|
fileObject = IoCreateStreamFileObject (NULL, vcb->StorageDevice);
|
||||||
|
|
||||||
newCCB = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
|
newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
|
||||||
if (newCCB == NULL)
|
if (newCCB == NULL)
|
||||||
{
|
{
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
memset (newCCB, 0, sizeof (VFATCCB));
|
memset (newCCB, 0, sizeof (VFATCCB));
|
||||||
|
|
||||||
fileObject->Flags = fileObject->Flags | FO_FCB_IS_VALID |
|
fileObject->Flags |= FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ;
|
||||||
FO_DIRECT_CACHE_PAGING_READ;
|
|
||||||
fileObject->SectionObjectPointers = &fcb->SectionObjectPointers;
|
fileObject->SectionObjectPointers = &fcb->SectionObjectPointers;
|
||||||
fileObject->FsContext = (PVOID) &fcb->RFCB;
|
fileObject->FsContext = (PVOID) &fcb->RFCB;
|
||||||
fileObject->FsContext2 = newCCB;
|
fileObject->FsContext2 = newCCB;
|
||||||
|
@ -213,6 +302,9 @@ vfatMakeRootFCB(PDEVICE_EXTENSION pVCB)
|
||||||
|
|
||||||
FCB = vfatNewFCB(L"\\");
|
FCB = vfatNewFCB(L"\\");
|
||||||
memset(FCB->entry.Filename, ' ', 11);
|
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.FileSize = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
|
||||||
FCB->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY;
|
FCB->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY;
|
||||||
if (pVCB->FatInfo.FatType == FAT32)
|
if (pVCB->FatInfo.FatType == FAT32)
|
||||||
|
@ -233,7 +325,7 @@ vfatMakeRootFCB(PDEVICE_EXTENSION pVCB)
|
||||||
FCB->entry.FirstCluster = 1;
|
FCB->entry.FirstCluster = 1;
|
||||||
Size = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
|
Size = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
|
||||||
}
|
}
|
||||||
FCB->RefCount = 1;
|
FCB->RefCount = 2;
|
||||||
FCB->dirIndex = 0;
|
FCB->dirIndex = 0;
|
||||||
FCB->RFCB.FileSize.QuadPart = Size;
|
FCB->RFCB.FileSize.QuadPart = Size;
|
||||||
FCB->RFCB.ValidDataLength.QuadPart = Size;
|
FCB->RFCB.ValidDataLength.QuadPart = Size;
|
||||||
|
@ -241,7 +333,6 @@ vfatMakeRootFCB(PDEVICE_EXTENSION pVCB)
|
||||||
|
|
||||||
vfatFCBInitializeCacheFromVolume(pVCB, FCB);
|
vfatFCBInitializeCacheFromVolume(pVCB, FCB);
|
||||||
vfatAddFCBToTable(pVCB, FCB);
|
vfatAddFCBToTable(pVCB, FCB);
|
||||||
vfatGrabFCB(pVCB, FCB);
|
|
||||||
|
|
||||||
return(FCB);
|
return(FCB);
|
||||||
}
|
}
|
||||||
|
@ -265,12 +356,16 @@ vfatMakeFCBFromDirEntry(PVCB vcb,
|
||||||
PVFATFCB directoryFCB,
|
PVFATFCB directoryFCB,
|
||||||
PWSTR longName,
|
PWSTR longName,
|
||||||
PFAT_DIR_ENTRY dirEntry,
|
PFAT_DIR_ENTRY dirEntry,
|
||||||
|
ULONG startIndex,
|
||||||
ULONG dirIndex,
|
ULONG dirIndex,
|
||||||
PVFATFCB* fileFCB)
|
PVFATFCB* fileFCB)
|
||||||
{
|
{
|
||||||
PVFATFCB rcFCB;
|
PVFATFCB rcFCB;
|
||||||
WCHAR pathName [MAX_PATH];
|
WCHAR pathName [MAX_PATH];
|
||||||
|
WCHAR entryName [14];
|
||||||
ULONG Size;
|
ULONG Size;
|
||||||
|
ULONG hash;
|
||||||
|
|
||||||
if (longName [0] != 0 && wcslen (directoryFCB->PathName) +
|
if (longName [0] != 0 && wcslen (directoryFCB->PathName) +
|
||||||
sizeof(WCHAR) + wcslen (longName) > MAX_PATH)
|
sizeof(WCHAR) + wcslen (longName) > MAX_PATH)
|
||||||
{
|
{
|
||||||
|
@ -281,21 +376,22 @@ vfatMakeFCBFromDirEntry(PVCB vcb,
|
||||||
{
|
{
|
||||||
wcscat (pathName, L"\\");
|
wcscat (pathName, L"\\");
|
||||||
}
|
}
|
||||||
|
hash = vfatNameHash(0, pathName);
|
||||||
|
vfatGetDirEntryName (dirEntry, entryName);
|
||||||
if (longName [0] != 0)
|
if (longName [0] != 0)
|
||||||
{
|
{
|
||||||
wcscat (pathName, longName);
|
wcscat (pathName, longName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WCHAR entryName [MAX_PATH];
|
|
||||||
|
|
||||||
vfatGetDirEntryName (dirEntry, entryName);
|
|
||||||
wcscat (pathName, entryName);
|
wcscat (pathName, entryName);
|
||||||
}
|
}
|
||||||
rcFCB = vfatNewFCB (pathName);
|
rcFCB = vfatNewFCB (pathName);
|
||||||
memcpy (&rcFCB->entry, dirEntry, sizeof (FAT_DIR_ENTRY));
|
memcpy (&rcFCB->entry, dirEntry, sizeof (FAT_DIR_ENTRY));
|
||||||
|
wcscpy(rcFCB->ShortName, entryName);
|
||||||
|
rcFCB->ShortHash.Hash = vfatNameHash(hash, entryName);
|
||||||
|
|
||||||
if (vfatFCBIsDirectory(vcb, rcFCB))
|
if (vfatFCBIsDirectory(rcFCB))
|
||||||
{
|
{
|
||||||
ULONG FirstCluster, CurrentCluster;
|
ULONG FirstCluster, CurrentCluster;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
@ -320,11 +416,12 @@ vfatMakeFCBFromDirEntry(PVCB vcb,
|
||||||
Size = rcFCB->entry.FileSize;
|
Size = rcFCB->entry.FileSize;
|
||||||
}
|
}
|
||||||
rcFCB->dirIndex = dirIndex;
|
rcFCB->dirIndex = dirIndex;
|
||||||
|
rcFCB->startIndex = startIndex;
|
||||||
rcFCB->RFCB.FileSize.QuadPart = Size;
|
rcFCB->RFCB.FileSize.QuadPart = Size;
|
||||||
rcFCB->RFCB.ValidDataLength.QuadPart = Size;
|
rcFCB->RFCB.ValidDataLength.QuadPart = Size;
|
||||||
rcFCB->RFCB.AllocationSize.QuadPart = ROUND_UP(Size, vcb->FatInfo.BytesPerCluster);
|
rcFCB->RFCB.AllocationSize.QuadPart = ROUND_UP(Size, vcb->FatInfo.BytesPerCluster);
|
||||||
rcFCB->RefCount++;
|
rcFCB->RefCount++;
|
||||||
if (vfatFCBIsDirectory(vcb, rcFCB))
|
if (vfatFCBIsDirectory(rcFCB))
|
||||||
{
|
{
|
||||||
vfatFCBInitializeCacheFromVolume(vcb, rcFCB);
|
vfatFCBInitializeCacheFromVolume(vcb, rcFCB);
|
||||||
}
|
}
|
||||||
|
@ -342,7 +439,7 @@ vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb,
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
PVFATCCB newCCB;
|
PVFATCCB newCCB;
|
||||||
|
|
||||||
newCCB = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
|
newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
|
||||||
if (newCCB == NULL)
|
if (newCCB == NULL)
|
||||||
{
|
{
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
@ -368,13 +465,15 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt,
|
||||||
PWSTR pFileToFind,
|
PWSTR pFileToFind,
|
||||||
PVFATFCB * pFoundFCB)
|
PVFATFCB * pFoundFCB)
|
||||||
{
|
{
|
||||||
BOOL finishedScanningDirectory;
|
|
||||||
ULONG directoryIndex;
|
ULONG directoryIndex;
|
||||||
|
ULONG startIndex;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
WCHAR defaultFileName [2];
|
WCHAR defaultFileName [2];
|
||||||
WCHAR currentLongName [256];
|
WCHAR currentLongName [256];
|
||||||
FAT_DIR_ENTRY currentDirEntry;
|
FAT_DIR_ENTRY currentDirEntry;
|
||||||
WCHAR currentEntryName [256];
|
WCHAR currentEntryName [256];
|
||||||
|
PVOID Context = NULL;
|
||||||
|
PVOID Page;
|
||||||
|
|
||||||
assert (pDeviceExt);
|
assert (pDeviceExt);
|
||||||
assert (pDirectoryFCB);
|
assert (pDirectoryFCB);
|
||||||
|
@ -395,30 +494,25 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt,
|
||||||
}
|
}
|
||||||
|
|
||||||
directoryIndex = 0;
|
directoryIndex = 0;
|
||||||
finishedScanningDirectory = FALSE;
|
while (TRUE)
|
||||||
while (!finishedScanningDirectory)
|
|
||||||
{
|
{
|
||||||
status = vfatGetNextDirEntry (pDeviceExt,
|
status = vfatGetNextDirEntry(&Context,
|
||||||
pDirectoryFCB,
|
&Page,
|
||||||
&directoryIndex,
|
pDirectoryFCB,
|
||||||
currentLongName,
|
&directoryIndex,
|
||||||
¤tDirEntry);
|
currentLongName,
|
||||||
|
¤tDirEntry,
|
||||||
|
&startIndex);
|
||||||
if (status == STATUS_NO_MORE_ENTRIES)
|
if (status == STATUS_NO_MORE_ENTRIES)
|
||||||
{
|
{
|
||||||
finishedScanningDirectory = TRUE;
|
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (!NT_SUCCESS(status))
|
|
||||||
{
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT (" Index:%d longName:%S\n",
|
DPRINT (" Index:%d longName:%S\n",
|
||||||
directoryIndex,
|
directoryIndex,
|
||||||
currentLongName);
|
currentLongName);
|
||||||
|
|
||||||
if (!vfatIsDirEntryDeleted (¤tDirEntry)
|
if (!vfatIsDirEntryVolume(¤tDirEntry))
|
||||||
&& !vfatIsDirEntryVolume(¤tDirEntry))
|
|
||||||
{
|
{
|
||||||
if (currentLongName [0] != L'\0' && wstrcmpjoki (currentLongName, pFileToFind))
|
if (currentLongName [0] != L'\0' && wstrcmpjoki (currentLongName, pFileToFind))
|
||||||
{
|
{
|
||||||
|
@ -427,8 +521,10 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt,
|
||||||
pDirectoryFCB,
|
pDirectoryFCB,
|
||||||
currentLongName,
|
currentLongName,
|
||||||
¤tDirEntry,
|
¤tDirEntry,
|
||||||
directoryIndex - 1,
|
startIndex,
|
||||||
|
directoryIndex,
|
||||||
pFoundFCB);
|
pFoundFCB);
|
||||||
|
CcUnpinData(Context);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -443,12 +539,15 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt,
|
||||||
pDirectoryFCB,
|
pDirectoryFCB,
|
||||||
currentLongName,
|
currentLongName,
|
||||||
¤tDirEntry,
|
¤tDirEntry,
|
||||||
directoryIndex - 1,
|
startIndex,
|
||||||
|
directoryIndex,
|
||||||
pFoundFCB);
|
pFoundFCB);
|
||||||
|
CcUnpinData(Context);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
directoryIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
|
@ -484,11 +583,17 @@ vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
|
||||||
|
|
||||||
return (FCB != NULL) ? STATUS_SUCCESS : STATUS_OBJECT_PATH_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;
|
currentElement = pFileName + 1;
|
||||||
wcscpy (pathName, L"\\");
|
wcscpy (pathName, L"\\");
|
||||||
FCB = vfatOpenRootFCB (pVCB);
|
FCB = vfatOpenRootFCB (pVCB);
|
||||||
}
|
}
|
||||||
parentFCB = NULL;
|
parentFCB = NULL;
|
||||||
|
|
||||||
|
@ -512,7 +617,7 @@ vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
|
||||||
parentFCB = 0;
|
parentFCB = 0;
|
||||||
}
|
}
|
||||||
// fail if element in FCB is not a directory
|
// 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");
|
DPRINT ("Element in requested path is not a directory\n");
|
||||||
|
|
||||||
|
|
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -22,22 +22,17 @@
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
VfatGetStandardInformation(PVFATFCB FCB,
|
VfatGetStandardInformation(PVFATFCB FCB,
|
||||||
PDEVICE_OBJECT DeviceObject,
|
|
||||||
PFILE_STANDARD_INFORMATION StandardInfo,
|
PFILE_STANDARD_INFORMATION StandardInfo,
|
||||||
PULONG BufferLength)
|
PULONG BufferLength)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Retrieve the standard file information
|
* FUNCTION: Retrieve the standard file information
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PDEVICE_EXTENSION DeviceExtension;
|
|
||||||
|
|
||||||
if (*BufferLength < sizeof(FILE_STANDARD_INFORMATION))
|
if (*BufferLength < sizeof(FILE_STANDARD_INFORMATION))
|
||||||
return STATUS_BUFFER_OVERFLOW;
|
return STATUS_BUFFER_OVERFLOW;
|
||||||
|
|
||||||
DeviceExtension = DeviceObject->DeviceExtension;
|
|
||||||
/* PRECONDITION */
|
/* PRECONDITION */
|
||||||
assert (DeviceExtension != NULL);
|
|
||||||
assert (DeviceExtension->FatInfo.BytesPerCluster != 0);
|
|
||||||
assert (StandardInfo != NULL);
|
assert (StandardInfo != NULL);
|
||||||
assert (FCB != NULL);
|
assert (FCB != NULL);
|
||||||
|
|
||||||
|
@ -56,8 +51,6 @@ VfatGetStandardInformation(PVFATFCB FCB,
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
VfatSetPositionInformation(PFILE_OBJECT FileObject,
|
VfatSetPositionInformation(PFILE_OBJECT FileObject,
|
||||||
PVFATFCB FCB,
|
|
||||||
PDEVICE_OBJECT DeviceObject,
|
|
||||||
PFILE_POSITION_INFORMATION PositionInfo)
|
PFILE_POSITION_INFORMATION PositionInfo)
|
||||||
{
|
{
|
||||||
DPRINT ("FsdSetPositionInformation()\n");
|
DPRINT ("FsdSetPositionInformation()\n");
|
||||||
|
@ -113,9 +106,7 @@ VfatGetBasicInformation(PFILE_OBJECT FileObject,
|
||||||
FsdDosDateTimeToFileTime(FCB->entry.UpdateDate,
|
FsdDosDateTimeToFileTime(FCB->entry.UpdateDate,
|
||||||
FCB->entry.UpdateTime,
|
FCB->entry.UpdateTime,
|
||||||
&BasicInfo->LastWriteTime);
|
&BasicInfo->LastWriteTime);
|
||||||
FsdDosDateTimeToFileTime(FCB->entry.UpdateDate,
|
BasicInfo->ChangeTime = BasicInfo->LastWriteTime;
|
||||||
FCB->entry.UpdateTime,
|
|
||||||
&BasicInfo->ChangeTime);
|
|
||||||
|
|
||||||
BasicInfo->FileAttributes = FCB->entry.Attrib;
|
BasicInfo->FileAttributes = FCB->entry.Attrib;
|
||||||
DPRINT("Getting attributes %x\n", BasicInfo->FileAttributes);
|
DPRINT("Getting attributes %x\n", BasicInfo->FileAttributes);
|
||||||
|
@ -165,7 +156,7 @@ VfatSetDispositionInformation(PFILE_OBJECT FileObject,
|
||||||
}
|
}
|
||||||
KeReleaseSpinLock(&DeviceExt->FcbListLock, oldIrql);
|
KeReleaseSpinLock(&DeviceExt->FcbListLock, oldIrql);
|
||||||
DPRINT("RefCount:%d\n", count);
|
DPRINT("RefCount:%d\n", count);
|
||||||
if (NT_SUCCESS(Status) && vfatFCBIsDirectory(DeviceExt, FCB))
|
if (NT_SUCCESS(Status) && vfatFCBIsDirectory(FCB))
|
||||||
{
|
{
|
||||||
memset (&tmpFcb, 0, sizeof(VFATFCB));
|
memset (&tmpFcb, 0, sizeof(VFATFCB));
|
||||||
tmpFcb.ObjectName = tmpFcb.PathName;
|
tmpFcb.ObjectName = tmpFcb.PathName;
|
||||||
|
@ -208,16 +199,13 @@ VfatGetNameInformation(PFILE_OBJECT FileObject,
|
||||||
assert (FCB != NULL);
|
assert (FCB != NULL);
|
||||||
|
|
||||||
NameLength = wcslen(FCB->PathName) * sizeof(WCHAR);
|
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;
|
return STATUS_BUFFER_OVERFLOW;
|
||||||
|
|
||||||
NameInfo->FileNameLength = NameLength;
|
NameInfo->FileNameLength = NameLength;
|
||||||
memcpy(NameInfo->FileName,
|
memcpy(NameInfo->FileName, FCB->PathName, NameLength + sizeof(WCHAR));
|
||||||
FCB->PathName,
|
|
||||||
NameLength + sizeof(WCHAR));
|
|
||||||
|
|
||||||
*BufferLength -=
|
*BufferLength -= (sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR));
|
||||||
(sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR));
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -262,9 +250,7 @@ VfatGetNetworkOpenInformation(PVFATFCB Fcb,
|
||||||
FsdDosDateTimeToFileTime(Fcb->entry.UpdateDate,
|
FsdDosDateTimeToFileTime(Fcb->entry.UpdateDate,
|
||||||
Fcb->entry.UpdateTime,
|
Fcb->entry.UpdateTime,
|
||||||
&NetworkInfo->LastWriteTime);
|
&NetworkInfo->LastWriteTime);
|
||||||
FsdDosDateTimeToFileTime(Fcb->entry.UpdateDate,
|
NetworkInfo->ChangeTime = NetworkInfo->LastWriteTime;
|
||||||
Fcb->entry.UpdateTime,
|
|
||||||
&NetworkInfo->ChangeTime);
|
|
||||||
NetworkInfo->AllocationSize = Fcb->RFCB.AllocationSize;
|
NetworkInfo->AllocationSize = Fcb->RFCB.AllocationSize;
|
||||||
NetworkInfo->EndOfFile = Fcb->RFCB.FileSize;
|
NetworkInfo->EndOfFile = Fcb->RFCB.FileSize;
|
||||||
NetworkInfo->FileAttributes = Fcb->entry.Attrib;
|
NetworkInfo->FileAttributes = Fcb->entry.Attrib;
|
||||||
|
@ -289,7 +275,7 @@ VfatGetAllInformation(PFILE_OBJECT FileObject,
|
||||||
assert (Fcb);
|
assert (Fcb);
|
||||||
|
|
||||||
NameLength = wcslen(Fcb->PathName) * sizeof(WCHAR);
|
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);
|
return(STATUS_BUFFER_OVERFLOW);
|
||||||
|
|
||||||
/* Basic Information */
|
/* Basic Information */
|
||||||
|
@ -302,9 +288,7 @@ VfatGetAllInformation(PFILE_OBJECT FileObject,
|
||||||
FsdDosDateTimeToFileTime(Fcb->entry.UpdateDate,
|
FsdDosDateTimeToFileTime(Fcb->entry.UpdateDate,
|
||||||
Fcb->entry.UpdateTime,
|
Fcb->entry.UpdateTime,
|
||||||
&Info->BasicInformation.LastWriteTime);
|
&Info->BasicInformation.LastWriteTime);
|
||||||
FsdDosDateTimeToFileTime(Fcb->entry.UpdateDate,
|
Info->BasicInformation.ChangeTime = Info->BasicInformation.LastWriteTime;
|
||||||
Fcb->entry.UpdateTime,
|
|
||||||
&Info->BasicInformation.ChangeTime);
|
|
||||||
Info->BasicInformation.FileAttributes = Fcb->entry.Attrib;
|
Info->BasicInformation.FileAttributes = Fcb->entry.Attrib;
|
||||||
|
|
||||||
/* Standard Information */
|
/* Standard Information */
|
||||||
|
@ -335,9 +319,7 @@ VfatGetAllInformation(PFILE_OBJECT FileObject,
|
||||||
|
|
||||||
/* Name Information */
|
/* Name Information */
|
||||||
Info->NameInformation.FileNameLength = NameLength;
|
Info->NameInformation.FileNameLength = NameLength;
|
||||||
RtlCopyMemory(Info->NameInformation.FileName,
|
RtlCopyMemory(Info->NameInformation.FileName, Fcb->PathName, NameLength + sizeof(WCHAR));
|
||||||
Fcb->PathName,
|
|
||||||
NameLength + sizeof(WCHAR));
|
|
||||||
|
|
||||||
*BufferLength -= (sizeof(FILE_ALL_INFORMATION) + NameLength + sizeof(WCHAR));
|
*BufferLength -= (sizeof(FILE_ALL_INFORMATION) + NameLength + sizeof(WCHAR));
|
||||||
|
|
||||||
|
@ -451,7 +433,7 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
|
||||||
Cluster = NCluster;
|
Cluster = NCluster;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!vfatFCBIsDirectory(DeviceExt, Fcb))
|
if (!vfatFCBIsDirectory(Fcb))
|
||||||
{
|
{
|
||||||
Fcb->entry.FileSize = NewSize;
|
Fcb->entry.FileSize = NewSize;
|
||||||
}
|
}
|
||||||
|
@ -512,7 +494,6 @@ NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
|
||||||
{
|
{
|
||||||
case FileStandardInformation:
|
case FileStandardInformation:
|
||||||
RC = VfatGetStandardInformation(FCB,
|
RC = VfatGetStandardInformation(FCB,
|
||||||
IrpContext->DeviceObject,
|
|
||||||
SystemBuffer,
|
SystemBuffer,
|
||||||
&BufferLength);
|
&BufferLength);
|
||||||
break;
|
break;
|
||||||
|
@ -621,8 +602,6 @@ NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
|
||||||
{
|
{
|
||||||
case FilePositionInformation:
|
case FilePositionInformation:
|
||||||
RC = VfatSetPositionInformation(IrpContext->FileObject,
|
RC = VfatSetPositionInformation(IrpContext->FileObject,
|
||||||
FCB,
|
|
||||||
IrpContext->DeviceObject,
|
|
||||||
SystemBuffer);
|
SystemBuffer);
|
||||||
break;
|
break;
|
||||||
case FileDispositionInformation:
|
case FileDispositionInformation:
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -291,7 +291,7 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
goto ByeBye;
|
goto ByeBye;
|
||||||
}
|
}
|
||||||
Ccb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
|
Ccb = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
|
||||||
if (Ccb == NULL)
|
if (Ccb == NULL)
|
||||||
{
|
{
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
@ -367,9 +367,9 @@ ByeBye:
|
||||||
if (DeviceExt && DeviceExt->FATFileObject)
|
if (DeviceExt && DeviceExt->FATFileObject)
|
||||||
ObDereferenceObject (DeviceExt->FATFileObject);
|
ObDereferenceObject (DeviceExt->FATFileObject);
|
||||||
if (Fcb)
|
if (Fcb)
|
||||||
ExFreePool(Fcb);
|
vfatDestroyFCB(Fcb);
|
||||||
if (Ccb)
|
if (Ccb)
|
||||||
ExFreePool(Ccb);
|
vfatDestroyCCB(Ccb);
|
||||||
if (DeviceObject)
|
if (DeviceObject)
|
||||||
IoDeleteDevice(DeviceObject);
|
IoDeleteDevice(DeviceObject);
|
||||||
if (VolumeFcb)
|
if (VolumeFcb)
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: services/fs/vfat/iface.c
|
* FILE: services/fs/vfat/iface.c
|
||||||
|
@ -88,6 +88,12 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
|
||||||
|
|
||||||
DriverObject->DriverUnload = NULL;
|
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);
|
IoRegisterFileSystem(DeviceObject);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -94,7 +94,7 @@ NTSTATUS STDCALL VfatBuildRequest (
|
||||||
VOID VfatFreeIrpContext (PVFAT_IRP_CONTEXT IrpContext)
|
VOID VfatFreeIrpContext (PVFAT_IRP_CONTEXT IrpContext)
|
||||||
{
|
{
|
||||||
assert (IrpContext);
|
assert (IrpContext);
|
||||||
ExFreePool(IrpContext);
|
ExFreeToNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList, IrpContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
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 (DeviceObject);
|
||||||
assert (Irp);
|
assert (Irp);
|
||||||
|
|
||||||
IrpContext = ExAllocatePool (NonPagedPool, sizeof(VFAT_IRP_CONTEXT));
|
IrpContext = ExAllocateFromNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList);
|
||||||
if (IrpContext)
|
if (IrpContext)
|
||||||
{
|
{
|
||||||
RtlZeroMemory(IrpContext, sizeof(IrpContext));
|
RtlZeroMemory(IrpContext, sizeof(IrpContext));
|
||||||
|
|
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* 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)) &&
|
if (!(IrpContext->Irp->Flags & (IRP_NOCACHE|IRP_PAGING_IO)) &&
|
||||||
!(Fcb->Flags & (FCB_IS_PAGE_FILE|FCB_IS_VOLUME)))
|
!(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);
|
CcRosInitializeFileCache(IrpContext->FileObject, &Fcb->RFCB.Bcb, CacheSize);
|
||||||
}
|
}
|
||||||
|
if (ByteOffset.QuadPart > OldFileSize.QuadPart)
|
||||||
|
{
|
||||||
|
CcZeroData(IrpContext->FileObject, &OldFileSize, &ByteOffset, TRUE);
|
||||||
|
}
|
||||||
if (CcCopyWrite(IrpContext->FileObject, &ByteOffset, Length,
|
if (CcCopyWrite(IrpContext->FileObject, &ByteOffset, Length,
|
||||||
1 /*IrpContext->Flags & IRPCONTEXT_CANWAIT*/, Buffer))
|
1 /*IrpContext->Flags & IRPCONTEXT_CANWAIT*/, Buffer))
|
||||||
{
|
{
|
||||||
|
@ -990,6 +990,10 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext)
|
||||||
// non cached write
|
// non cached write
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
|
|
||||||
|
if (ByteOffset.QuadPart > OldFileSize.QuadPart)
|
||||||
|
{
|
||||||
|
CcZeroData(IrpContext->FileObject, &OldFileSize, &ByteOffset, TRUE);
|
||||||
|
}
|
||||||
Buffer = VfatGetUserBuffer(IrpContext->Irp);
|
Buffer = VfatGetUserBuffer(IrpContext->Irp);
|
||||||
if (!Buffer)
|
if (!Buffer)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -20,102 +20,6 @@
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* 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)
|
BOOLEAN wstrcmpjoki(PWSTR s1, PWSTR s2)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Compare two wide character strings, s2 with jokers (* or ?)
|
* FUNCTION: Compare two wide character strings, s2 with jokers (* or ?)
|
||||||
|
|
|
@ -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>
|
#include <ddk/ntifs.h>
|
||||||
|
|
||||||
|
@ -122,6 +122,16 @@ typedef struct
|
||||||
|
|
||||||
struct _VFATFCB;
|
struct _VFATFCB;
|
||||||
|
|
||||||
|
typedef struct _HASHENTRY
|
||||||
|
{
|
||||||
|
ULONG Hash;
|
||||||
|
struct _VFATFCB* self;
|
||||||
|
struct _HASHENTRY* next;
|
||||||
|
}
|
||||||
|
HASHENTRY;
|
||||||
|
|
||||||
|
#define FCB_HASH_TABLE_SIZE 1024
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ERESOURCE DirResource;
|
ERESOURCE DirResource;
|
||||||
|
@ -138,6 +148,7 @@ typedef struct
|
||||||
BOOLEAN AvailableClustersValid;
|
BOOLEAN AvailableClustersValid;
|
||||||
ULONG Flags;
|
ULONG Flags;
|
||||||
struct _VFATFCB * VolumeFcb;
|
struct _VFATFCB * VolumeFcb;
|
||||||
|
struct _HASHENTRY* FcbHashTable[FCB_HASH_TABLE_SIZE];
|
||||||
} DEVICE_EXTENSION, *PDEVICE_EXTENSION, VCB, *PVCB;
|
} DEVICE_EXTENSION, *PDEVICE_EXTENSION, VCB, *PVCB;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -145,6 +156,9 @@ typedef struct
|
||||||
PDRIVER_OBJECT DriverObject;
|
PDRIVER_OBJECT DriverObject;
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
ULONG Flags;
|
ULONG Flags;
|
||||||
|
NPAGED_LOOKASIDE_LIST FcbLookasideList;
|
||||||
|
NPAGED_LOOKASIDE_LIST CcbLookasideList;
|
||||||
|
NPAGED_LOOKASIDE_LIST IrpContextLookasideList;
|
||||||
} VFAT_GLOBAL_DATA, *PVFAT_GLOBAL_DATA;
|
} VFAT_GLOBAL_DATA, *PVFAT_GLOBAL_DATA;
|
||||||
|
|
||||||
extern PVFAT_GLOBAL_DATA VfatGlobalData;
|
extern PVFAT_GLOBAL_DATA VfatGlobalData;
|
||||||
|
@ -165,6 +179,7 @@ typedef struct _VFATFCB
|
||||||
WCHAR *ObjectName;
|
WCHAR *ObjectName;
|
||||||
/* path+filename 260 max */
|
/* path+filename 260 max */
|
||||||
WCHAR PathName[MAX_PATH];
|
WCHAR PathName[MAX_PATH];
|
||||||
|
WCHAR ShortName[14];
|
||||||
LONG RefCount;
|
LONG RefCount;
|
||||||
PDEVICE_EXTENSION pDevExt;
|
PDEVICE_EXTENSION pDevExt;
|
||||||
LIST_ENTRY FcbListEntry;
|
LIST_ENTRY FcbListEntry;
|
||||||
|
@ -172,10 +187,13 @@ typedef struct _VFATFCB
|
||||||
ULONG Flags;
|
ULONG Flags;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
ULONG dirIndex;
|
ULONG dirIndex;
|
||||||
|
ULONG startIndex;
|
||||||
ERESOURCE PagingIoResource;
|
ERESOURCE PagingIoResource;
|
||||||
ERESOURCE MainResource;
|
ERESOURCE MainResource;
|
||||||
ULONG TimerCount;
|
ULONG TimerCount;
|
||||||
SHARE_ACCESS FCBShareAccess;
|
SHARE_ACCESS FCBShareAccess;
|
||||||
|
HASHENTRY Hash;
|
||||||
|
HASHENTRY ShortHash;
|
||||||
|
|
||||||
/* Structure members used only for paging files. */
|
/* Structure members used only for paging files. */
|
||||||
ULONG FatChainSize;
|
ULONG FatChainSize;
|
||||||
|
@ -197,9 +215,13 @@ typedef struct _VFATCCB
|
||||||
|
|
||||||
} VFATCCB, *PVFATCCB;
|
} VFATCCB, *PVFATCCB;
|
||||||
|
|
||||||
|
#ifndef TAG
|
||||||
#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
|
#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_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))
|
#define ENTRIES_PER_SECTOR (BLOCKSIZE / sizeof(FATDirEntry))
|
||||||
|
|
||||||
|
@ -350,26 +372,6 @@ NTSTATUS delEntry(PDEVICE_EXTENSION,
|
||||||
|
|
||||||
/* -------------------------------------------------------- string.c */
|
/* -------------------------------------------------------- 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,
|
BOOLEAN wstrcmpjoki (PWSTR s1,
|
||||||
PWSTR s2);
|
PWSTR s2);
|
||||||
|
|
||||||
|
@ -420,11 +422,13 @@ BOOL vfatIsDirEntryEndMarker (FATDirEntry * pFatDirEntry);
|
||||||
VOID vfatGetDirEntryName (PFAT_DIR_ENTRY pDirEntry,
|
VOID vfatGetDirEntryName (PFAT_DIR_ENTRY pDirEntry,
|
||||||
PWSTR pEntryName);
|
PWSTR pEntryName);
|
||||||
|
|
||||||
NTSTATUS vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
|
NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
|
||||||
PVFATFCB pDirectoryFCB,
|
PVOID * pPage,
|
||||||
ULONG * pDirectoryIndex,
|
IN PVFATFCB pDirFcb,
|
||||||
PWSTR pLongFileName,
|
IN OUT PULONG pDirIndex,
|
||||||
PFAT_DIR_ENTRY pDirEntry);
|
OUT PWSTR pFileName,
|
||||||
|
OUT PFAT_DIR_ENTRY pDirEntry,
|
||||||
|
OUT PULONG pStartIndex);
|
||||||
|
|
||||||
/* ----------------------------------------------------------- fcb.c */
|
/* ----------------------------------------------------------- fcb.c */
|
||||||
|
|
||||||
|
@ -448,8 +452,7 @@ PVFATFCB vfatMakeRootFCB (PDEVICE_EXTENSION pVCB);
|
||||||
|
|
||||||
PVFATFCB vfatOpenRootFCB (PDEVICE_EXTENSION pVCB);
|
PVFATFCB vfatOpenRootFCB (PDEVICE_EXTENSION pVCB);
|
||||||
|
|
||||||
BOOL vfatFCBIsDirectory (PDEVICE_EXTENSION pVCB,
|
BOOL vfatFCBIsDirectory (PVFATFCB FCB);
|
||||||
PVFATFCB FCB);
|
|
||||||
|
|
||||||
NTSTATUS vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb,
|
NTSTATUS vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb,
|
||||||
PVFATFCB fcb,
|
PVFATFCB fcb,
|
||||||
|
@ -469,6 +472,7 @@ NTSTATUS vfatMakeFCBFromDirEntry (PVCB vcb,
|
||||||
PVFATFCB directoryFCB,
|
PVFATFCB directoryFCB,
|
||||||
PWSTR longName,
|
PWSTR longName,
|
||||||
PFAT_DIR_ENTRY dirEntry,
|
PFAT_DIR_ENTRY dirEntry,
|
||||||
|
ULONG startIndex,
|
||||||
ULONG dirIndex,
|
ULONG dirIndex,
|
||||||
PVFATFCB * fileFCB);
|
PVFATFCB * fileFCB);
|
||||||
|
|
||||||
|
@ -478,22 +482,6 @@ NTSTATUS VfatRead (PVFAT_IRP_CONTEXT IrpContext);
|
||||||
|
|
||||||
NTSTATUS VfatWrite (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,
|
NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
PVFATFCB Fcb,
|
PVFATFCB Fcb,
|
||||||
ULONG FirstCluster,
|
ULONG FirstCluster,
|
||||||
|
|
Loading…
Reference in a new issue