mirror of
https://github.com/reactos/reactos.git
synced 2024-12-26 17:14:41 +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
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: direntry.c,v 1.9 2002/10/01 19:27:17 chorns Exp $
|
||||
/* $Id: direntry.c,v 1.10 2002/11/11 21:49:18 hbirr Exp $
|
||||
*
|
||||
*
|
||||
* FILE: DirEntry.c
|
||||
|
@ -20,12 +20,7 @@
|
|||
|
||||
#include "vfat.h"
|
||||
|
||||
#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->FatInfo.BytesPerCluster > PAGE_SIZE ? \
|
||||
(pDeviceExt)->FatInfo.BytesPerCluster : PAGE_SIZE)
|
||||
|
||||
#define ENTRIES_PER_CACHEPAGE(pDeviceExt) (ENTRIES_PER_SECTOR * \
|
||||
(CACHEPAGESIZE(pDeviceExt) / ((pDeviceExt)->FatInfo.BytesPerSector)))
|
||||
|
||||
#define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof (FATDirEntry))
|
||||
|
||||
ULONG
|
||||
vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
|
||||
|
@ -76,131 +71,133 @@ vfatGetDirEntryName (PFAT_DIR_ENTRY dirEntry, PWSTR entryName)
|
|||
vfat8Dot3ToString (dirEntry->Filename, dirEntry->Ext, entryName);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
|
||||
PVFATFCB pDirectoryFCB,
|
||||
ULONG * pDirectoryIndex,
|
||||
PWSTR pLongFileName,
|
||||
PFAT_DIR_ENTRY pDirEntry)
|
||||
|
||||
NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
|
||||
PVOID * pPage,
|
||||
IN PVFATFCB pDirFcb,
|
||||
IN OUT PULONG pDirIndex,
|
||||
OUT PWSTR pFileName,
|
||||
OUT PFAT_DIR_ENTRY pDirEntry,
|
||||
OUT PULONG pStartIndex)
|
||||
{
|
||||
ULONG indexInPage = *pDirectoryIndex % ENTRIES_PER_CACHEPAGE(pDeviceExt);
|
||||
ULONG pageNumber = *pDirectoryIndex / ENTRIES_PER_CACHEPAGE(pDeviceExt);
|
||||
PVOID currentPage = NULL;
|
||||
FATDirEntry * fatDirEntry;
|
||||
slot * longNameEntry;
|
||||
ULONG cpos;
|
||||
LARGE_INTEGER FileOffset;
|
||||
PVOID Context;
|
||||
ULONG dirMap;
|
||||
PWCHAR pName;
|
||||
LARGE_INTEGER FileOffset;
|
||||
FATDirEntry * fatDirEntry;
|
||||
slot * longNameEntry;
|
||||
ULONG index;
|
||||
|
||||
DPRINT ("vfatGetNextDirEntry (%x,%x,%d,%x,%x)\n",
|
||||
pDeviceExt,
|
||||
pDirectoryFCB,
|
||||
*pDirectoryIndex,
|
||||
pLongFileName,
|
||||
pDirEntry);
|
||||
DPRINT ("vfatGetNextDirEntry (%x,%x,%d,%x,%x)\n",
|
||||
DeviceExt,
|
||||
pDirFcb,
|
||||
*pDirIndex,
|
||||
pFileName,
|
||||
pDirEntry);
|
||||
|
||||
*pLongFileName = 0;
|
||||
*pFileName = 0;
|
||||
|
||||
FileOffset.QuadPart = pageNumber * CACHEPAGESIZE(pDeviceExt);
|
||||
if (!CcMapData(pDirectoryFCB->FileObject, &FileOffset,
|
||||
CACHEPAGESIZE(pDeviceExt), TRUE, &Context, ¤tPage))
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
FileOffset.u.HighPart = 0;
|
||||
FileOffset.u.LowPart = ROUND_DOWN(*pDirIndex * sizeof(FATDirEntry), PAGE_SIZE);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
fatDirEntry = (FATDirEntry *) currentPage;
|
||||
|
||||
if (vfatIsDirEntryEndMarker (&fatDirEntry [indexInPage]))
|
||||
if (*pContext == NULL || (*pDirIndex % ENTRIES_PER_PAGE) == 0)
|
||||
{
|
||||
DPRINT ("end of directory, returning no more entries\n");
|
||||
CcUnpinData(Context);
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
if (*pContext != NULL)
|
||||
{
|
||||
CcUnpinData(*pContext);
|
||||
}
|
||||
if (!CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage))
|
||||
{
|
||||
*pContext = NULL;
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
}
|
||||
else if (vfatIsDirEntryLongName (&fatDirEntry [indexInPage])
|
||||
&& !vfatIsDirEntryDeleted (&fatDirEntry [indexInPage]))
|
||||
|
||||
|
||||
fatDirEntry = (FATDirEntry*)(*pPage) + *pDirIndex % ENTRIES_PER_PAGE;
|
||||
longNameEntry = (slot*) fatDirEntry;
|
||||
dirMap = 0;
|
||||
|
||||
if (pStartIndex)
|
||||
{
|
||||
DPRINT (" long name entry found at %d\n", *pDirectoryIndex);
|
||||
longNameEntry = (slot *) currentPage;
|
||||
|
||||
DPRINT (" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n",
|
||||
5, longNameEntry [indexInPage].name0_4,
|
||||
6, longNameEntry [indexInPage].name5_10,
|
||||
2, longNameEntry [indexInPage].name11_12);
|
||||
|
||||
vfat_initstr (pLongFileName, 256);
|
||||
vfat_wcsncpy (pLongFileName, longNameEntry [indexInPage].name0_4, 5);
|
||||
vfat_wcsncat (pLongFileName, longNameEntry [indexInPage].name5_10, 5, 6);
|
||||
vfat_wcsncat (pLongFileName, longNameEntry [indexInPage].name11_12, 11, 2);
|
||||
|
||||
DPRINT (" longName: [%S]\n", pLongFileName);
|
||||
|
||||
cpos = 0;
|
||||
while ((longNameEntry [indexInPage].id != 0x41) &&
|
||||
(longNameEntry [indexInPage].id != 0x01) &&
|
||||
(longNameEntry [indexInPage].attr > 0))
|
||||
{
|
||||
(*pDirectoryIndex)++;
|
||||
indexInPage++;
|
||||
if (indexInPage == ENTRIES_PER_CACHEPAGE(pDeviceExt))
|
||||
{
|
||||
indexInPage = 0;
|
||||
pageNumber++;
|
||||
|
||||
CcUnpinData(Context);
|
||||
FileOffset.QuadPart = pageNumber * CACHEPAGESIZE(pDeviceExt);
|
||||
if (!CcMapData(pDirectoryFCB->FileObject, &FileOffset,
|
||||
CACHEPAGESIZE(pDeviceExt), TRUE, &Context, ¤tPage))
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
longNameEntry = (slot *) currentPage;
|
||||
}
|
||||
DPRINT (" index %d\n", *pDirectoryIndex);
|
||||
|
||||
DPRINT (" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n",
|
||||
5, longNameEntry [indexInPage].name0_4,
|
||||
6, longNameEntry [indexInPage].name5_10,
|
||||
2, longNameEntry [indexInPage].name11_12);
|
||||
|
||||
cpos++;
|
||||
vfat_movstr (pLongFileName, 13, 0, cpos * 13);
|
||||
vfat_wcsncpy (pLongFileName, longNameEntry [indexInPage].name0_4, 5);
|
||||
vfat_wcsncat (pLongFileName, longNameEntry [indexInPage].name5_10, 5, 6);
|
||||
vfat_wcsncat (pLongFileName, longNameEntry [indexInPage].name11_12, 11, 2);
|
||||
|
||||
DPRINT (" longName: [%S]\n", pLongFileName);
|
||||
|
||||
}
|
||||
(*pDirectoryIndex)++;
|
||||
indexInPage++;
|
||||
if (indexInPage == ENTRIES_PER_CACHEPAGE(pDeviceExt))
|
||||
{
|
||||
indexInPage = 0;
|
||||
pageNumber++;
|
||||
|
||||
CcUnpinData(Context);
|
||||
FileOffset.QuadPart = pageNumber * CACHEPAGESIZE(pDeviceExt);
|
||||
if (!CcMapData(pDirectoryFCB->FileObject, &FileOffset,
|
||||
CACHEPAGESIZE(pDeviceExt), TRUE, &Context, ¤tPage))
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
*pStartIndex = *pDirIndex;
|
||||
}
|
||||
else
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
memcpy (pDirEntry, &fatDirEntry [indexInPage], sizeof (FAT_DIR_ENTRY));
|
||||
(*pDirectoryIndex)++;
|
||||
break;
|
||||
if (vfatIsDirEntryEndMarker(fatDirEntry))
|
||||
{
|
||||
CcUnpinData(*pContext);
|
||||
*pContext = NULL;
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
|
||||
if (vfatIsDirEntryDeleted (fatDirEntry))
|
||||
{
|
||||
dirMap = 0;
|
||||
*pFileName = 0;
|
||||
if (pStartIndex)
|
||||
{
|
||||
*pStartIndex = *pDirIndex + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vfatIsDirEntryLongName (fatDirEntry))
|
||||
{
|
||||
if (dirMap == 0)
|
||||
{
|
||||
DPRINT (" long name entry found at %d\n", *pDirIndex);
|
||||
memset(pFileName, 0, 256 * sizeof(WCHAR));
|
||||
}
|
||||
|
||||
DPRINT (" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n",
|
||||
5, longNameEntry->name0_4,
|
||||
6, longNameEntry->name5_10,
|
||||
2, longNameEntry->name11_12);
|
||||
|
||||
index = (longNameEntry->id & 0x1f) - 1;
|
||||
dirMap |= 1 << index;
|
||||
pName = pFileName + 13 * index;
|
||||
|
||||
memcpy(pName, longNameEntry->name0_4, 5 * sizeof(WCHAR));
|
||||
memcpy(pName + 5, longNameEntry->name5_10, 6 * sizeof(WCHAR));
|
||||
memcpy(pName + 11, longNameEntry->name11_12, 2 * sizeof(WCHAR));
|
||||
|
||||
DPRINT (" longName: [%S]\n", pFileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (pDirEntry, fatDirEntry, sizeof (FAT_DIR_ENTRY));
|
||||
break;
|
||||
}
|
||||
}
|
||||
(*pDirIndex)++;
|
||||
if ((*pDirIndex % ENTRIES_PER_PAGE) == 0)
|
||||
{
|
||||
CcUnpinData(*pContext);
|
||||
FileOffset.u.LowPart += PAGE_SIZE;
|
||||
if (!CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage))
|
||||
{
|
||||
CHECKPOINT;
|
||||
*pContext = NULL;
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
fatDirEntry = (FATDirEntry*)*pPage;
|
||||
longNameEntry = (slot*) *pPage;
|
||||
}
|
||||
else
|
||||
{
|
||||
fatDirEntry++;
|
||||
longNameEntry++;
|
||||
}
|
||||
}
|
||||
}
|
||||
CcUnpinData(Context);
|
||||
return STATUS_SUCCESS;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: fcb.c,v 1.21 2002/10/01 19:27:18 chorns Exp $
|
||||
/* $Id: fcb.c,v 1.22 2002/11/11 21:49:18 hbirr Exp $
|
||||
*
|
||||
*
|
||||
* FILE: fcb.c
|
||||
|
@ -29,30 +29,52 @@
|
|||
|
||||
/* -------------------------------------------------------- PUBLICS */
|
||||
|
||||
ULONG vfatNameHash(ULONG hash, PWCHAR name)
|
||||
{
|
||||
WCHAR c;
|
||||
while(c = *name++)
|
||||
{
|
||||
c = towlower(c);
|
||||
hash = (hash + (c << 4) + (c >> 4)) * 11;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
PVFATFCB
|
||||
vfatNewFCB(PWCHAR pFileName)
|
||||
{
|
||||
PVFATFCB rcFCB;
|
||||
|
||||
rcFCB = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATFCB), TAG_FCB);
|
||||
rcFCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->FcbLookasideList);
|
||||
memset (rcFCB, 0, sizeof (VFATFCB));
|
||||
if (pFileName)
|
||||
{
|
||||
wcscpy (rcFCB->PathName, pFileName);
|
||||
if (wcsrchr (rcFCB->PathName, '\\') != 0)
|
||||
{
|
||||
rcFCB->ObjectName = wcsrchr (rcFCB->PathName, '\\');
|
||||
}
|
||||
else
|
||||
rcFCB->ObjectName = wcsrchr(rcFCB->PathName, L'\\');
|
||||
if (rcFCB->ObjectName == NULL)
|
||||
{
|
||||
rcFCB->ObjectName = rcFCB->PathName;
|
||||
}
|
||||
rcFCB->Hash.Hash = vfatNameHash(0, rcFCB->PathName);
|
||||
DPRINT("%08x (%03x) '%S'\n", rcFCB->Hash.Hash, rcFCB->Hash.Hash % FCB_HASH_TABLE_SIZE, pFileName);
|
||||
}
|
||||
rcFCB->Hash.self = rcFCB;
|
||||
rcFCB->ShortHash.self = rcFCB;
|
||||
ExInitializeResourceLite(&rcFCB->PagingIoResource);
|
||||
ExInitializeResourceLite(&rcFCB->MainResource);
|
||||
return rcFCB;
|
||||
}
|
||||
|
||||
VOID
|
||||
vfatDestroyCCB(PVFATCCB pCcb)
|
||||
{
|
||||
if (pCcb->DirectorySearchPattern)
|
||||
{
|
||||
ExFreePool(pCcb->DirectorySearchPattern);
|
||||
}
|
||||
ExFreeToNPagedLookasideList(&VfatGlobalData->CcbLookasideList, pCcb);
|
||||
}
|
||||
|
||||
VOID
|
||||
vfatDestroyFCB(PVFATFCB pFCB)
|
||||
{
|
||||
|
@ -60,11 +82,11 @@ vfatDestroyFCB(PVFATFCB pFCB)
|
|||
ExDeleteResourceLite(&pFCB->MainResource);
|
||||
if ((pFCB->Flags & FCB_IS_PAGE_FILE) && pFCB->FatChainSize)
|
||||
ExFreePool(pFCB->FatChain);
|
||||
ExFreePool (pFCB);
|
||||
ExFreeToNPagedLookasideList(&VfatGlobalData->FcbLookasideList, pFCB);
|
||||
}
|
||||
|
||||
BOOL
|
||||
vfatFCBIsDirectory(PDEVICE_EXTENSION pVCB, PVFATFCB FCB)
|
||||
vfatFCBIsDirectory(PVFATFCB FCB)
|
||||
{
|
||||
return FCB->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY;
|
||||
}
|
||||
|
@ -72,44 +94,63 @@ vfatFCBIsDirectory(PDEVICE_EXTENSION pVCB, PVFATFCB FCB)
|
|||
BOOL
|
||||
vfatFCBIsRoot(PVFATFCB FCB)
|
||||
{
|
||||
return wcscmp (FCB->PathName, L"\\") == 0;
|
||||
}
|
||||
|
||||
VOID
|
||||
vfatGrabFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
|
||||
{
|
||||
KIRQL oldIrql;
|
||||
|
||||
DPRINT ("grabbing FCB at %x: %S, refCount:%d\n",
|
||||
pFCB,
|
||||
pFCB->PathName,
|
||||
pFCB->RefCount);
|
||||
|
||||
KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql);
|
||||
pFCB->RefCount++;
|
||||
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
|
||||
return FCB->PathName[0] == L'\\' && FCB->PathName[1] == 0 ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
VOID
|
||||
vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
|
||||
{
|
||||
KIRQL oldIrql;
|
||||
HASHENTRY* entry;
|
||||
ULONG Index;
|
||||
ULONG ShortIndex;
|
||||
|
||||
DPRINT ("releasing FCB at %x: %S, refCount:%d\n",
|
||||
pFCB,
|
||||
pFCB->PathName,
|
||||
pFCB->RefCount);
|
||||
|
||||
Index = pFCB->Hash.Hash % FCB_HASH_TABLE_SIZE;
|
||||
ShortIndex = pFCB->ShortHash.Hash % FCB_HASH_TABLE_SIZE;
|
||||
KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql);
|
||||
pFCB->RefCount--;
|
||||
if (pFCB->RefCount <= 0 && (!vfatFCBIsDirectory (pVCB, pFCB) || pFCB->Flags & FCB_DELETE_PENDING))
|
||||
if (pFCB->RefCount <= 0 && (!vfatFCBIsDirectory (pFCB) || pFCB->Flags & FCB_DELETE_PENDING))
|
||||
{
|
||||
RemoveEntryList (&pFCB->FcbListEntry);
|
||||
RemoveEntryList (&pFCB->FcbListEntry);
|
||||
if (pFCB->Hash.Hash != pFCB->ShortHash.Hash)
|
||||
{
|
||||
entry = pVCB->FcbHashTable[ShortIndex];
|
||||
if (entry->self == pFCB)
|
||||
{
|
||||
pVCB->FcbHashTable[ShortIndex] = entry->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (entry->next->self != pFCB)
|
||||
{
|
||||
entry = entry->next;
|
||||
}
|
||||
entry->next = pFCB->ShortHash.next;
|
||||
}
|
||||
}
|
||||
entry = pVCB->FcbHashTable[Index];
|
||||
if (entry->self == pFCB)
|
||||
{
|
||||
pVCB->FcbHashTable[Index] = entry->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (entry->next->self != pFCB)
|
||||
{
|
||||
entry = entry->next;
|
||||
}
|
||||
entry->next = pFCB->Hash.next;
|
||||
}
|
||||
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
|
||||
if (vfatFCBIsDirectory(pVCB, pFCB))
|
||||
if (vfatFCBIsDirectory(pFCB))
|
||||
{
|
||||
CcRosReleaseFileCache(pFCB->FileObject, pFCB->RFCB.Bcb);
|
||||
ExFreePool(pFCB->FileObject->FsContext2);
|
||||
vfatDestroyCCB(pFCB->FileObject->FsContext2);
|
||||
pFCB->FileObject->FsContext2 = NULL;
|
||||
ObDereferenceObject(pFCB->FileObject);
|
||||
}
|
||||
|
@ -123,10 +164,22 @@ VOID
|
|||
vfatAddFCBToTable(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
|
||||
{
|
||||
KIRQL oldIrql;
|
||||
ULONG Index;
|
||||
ULONG ShortIndex;
|
||||
|
||||
Index = pFCB->Hash.Hash % FCB_HASH_TABLE_SIZE;
|
||||
ShortIndex = pFCB->ShortHash.Hash % FCB_HASH_TABLE_SIZE;
|
||||
KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql);
|
||||
pFCB->pDevExt = pVCB;
|
||||
InsertTailList (&pVCB->FcbListHead, &pFCB->FcbListEntry);
|
||||
|
||||
pFCB->Hash.next = pVCB->FcbHashTable[Index];
|
||||
pVCB->FcbHashTable[Index] = &pFCB->Hash;
|
||||
if (pFCB->Hash.Hash != pFCB->ShortHash.Hash)
|
||||
{
|
||||
pFCB->ShortHash.next = pVCB->FcbHashTable[ShortIndex];
|
||||
pVCB->FcbHashTable[ShortIndex] = &pFCB->ShortHash;
|
||||
}
|
||||
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
|
||||
}
|
||||
|
||||
|
@ -136,23 +189,60 @@ vfatGrabFCBFromTable(PDEVICE_EXTENSION pVCB, PWSTR pFileName)
|
|||
KIRQL oldIrql;
|
||||
PVFATFCB rcFCB;
|
||||
PLIST_ENTRY current_entry;
|
||||
ULONG Hash;
|
||||
PWCHAR ObjectName = NULL;
|
||||
ULONG len;
|
||||
ULONG index;
|
||||
ULONG currentindex;
|
||||
|
||||
HASHENTRY* entry;
|
||||
|
||||
Hash = vfatNameHash(0, pFileName);
|
||||
|
||||
KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql);
|
||||
current_entry = pVCB->FcbListHead.Flink;
|
||||
while (current_entry != &pVCB->FcbListHead)
|
||||
entry = pVCB->FcbHashTable[Hash % FCB_HASH_TABLE_SIZE];
|
||||
|
||||
while (entry)
|
||||
{
|
||||
rcFCB = CONTAINING_RECORD (current_entry, VFATFCB, FcbListEntry);
|
||||
if (entry->Hash == Hash)
|
||||
{
|
||||
rcFCB = entry->self;
|
||||
if (rcFCB->Hash.Hash == Hash)
|
||||
{
|
||||
/* compare the long name */
|
||||
if (!_wcsicmp(pFileName, rcFCB->PathName))
|
||||
{
|
||||
rcFCB->RefCount++;
|
||||
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
|
||||
return rcFCB;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
len = rcFCB->ObjectName - rcFCB->PathName + 1;
|
||||
if (ObjectName == NULL)
|
||||
{
|
||||
ObjectName = wcsrchr(pFileName, L'\\');
|
||||
if (ObjectName == NULL)
|
||||
{
|
||||
ObjectName = pFileName;
|
||||
}
|
||||
else
|
||||
{
|
||||
ObjectName++;
|
||||
}
|
||||
}
|
||||
|
||||
if (wstrcmpi (pFileName, rcFCB->PathName))
|
||||
{
|
||||
rcFCB->RefCount++;
|
||||
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
|
||||
return rcFCB;
|
||||
}
|
||||
|
||||
//FIXME: need to compare against short name in FCB here
|
||||
|
||||
current_entry = current_entry->Flink;
|
||||
/* compare the short name and the directory */
|
||||
if (!_wcsicmp(ObjectName, rcFCB->ShortName) && !_wcsnicmp(pFileName, rcFCB->PathName, len))
|
||||
{
|
||||
rcFCB->RefCount++;
|
||||
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
|
||||
return rcFCB;
|
||||
}
|
||||
}
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
|
||||
|
||||
|
@ -169,15 +259,14 @@ vfatFCBInitializeCacheFromVolume (PVCB vcb, PVFATFCB fcb)
|
|||
|
||||
fileObject = IoCreateStreamFileObject (NULL, vcb->StorageDevice);
|
||||
|
||||
newCCB = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
|
||||
newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
|
||||
if (newCCB == NULL)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
memset (newCCB, 0, sizeof (VFATCCB));
|
||||
|
||||
fileObject->Flags = fileObject->Flags | FO_FCB_IS_VALID |
|
||||
FO_DIRECT_CACHE_PAGING_READ;
|
||||
fileObject->Flags |= FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ;
|
||||
fileObject->SectionObjectPointers = &fcb->SectionObjectPointers;
|
||||
fileObject->FsContext = (PVOID) &fcb->RFCB;
|
||||
fileObject->FsContext2 = newCCB;
|
||||
|
@ -213,6 +302,9 @@ vfatMakeRootFCB(PDEVICE_EXTENSION pVCB)
|
|||
|
||||
FCB = vfatNewFCB(L"\\");
|
||||
memset(FCB->entry.Filename, ' ', 11);
|
||||
FCB->ShortName[0] = L'\\';
|
||||
FCB->ShortName[1] = 0;
|
||||
FCB->ShortHash.Hash = FCB->Hash.Hash;
|
||||
FCB->entry.FileSize = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
|
||||
FCB->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY;
|
||||
if (pVCB->FatInfo.FatType == FAT32)
|
||||
|
@ -233,7 +325,7 @@ vfatMakeRootFCB(PDEVICE_EXTENSION pVCB)
|
|||
FCB->entry.FirstCluster = 1;
|
||||
Size = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
|
||||
}
|
||||
FCB->RefCount = 1;
|
||||
FCB->RefCount = 2;
|
||||
FCB->dirIndex = 0;
|
||||
FCB->RFCB.FileSize.QuadPart = Size;
|
||||
FCB->RFCB.ValidDataLength.QuadPart = Size;
|
||||
|
@ -241,7 +333,6 @@ vfatMakeRootFCB(PDEVICE_EXTENSION pVCB)
|
|||
|
||||
vfatFCBInitializeCacheFromVolume(pVCB, FCB);
|
||||
vfatAddFCBToTable(pVCB, FCB);
|
||||
vfatGrabFCB(pVCB, FCB);
|
||||
|
||||
return(FCB);
|
||||
}
|
||||
|
@ -265,12 +356,16 @@ vfatMakeFCBFromDirEntry(PVCB vcb,
|
|||
PVFATFCB directoryFCB,
|
||||
PWSTR longName,
|
||||
PFAT_DIR_ENTRY dirEntry,
|
||||
ULONG startIndex,
|
||||
ULONG dirIndex,
|
||||
PVFATFCB* fileFCB)
|
||||
{
|
||||
PVFATFCB rcFCB;
|
||||
WCHAR pathName [MAX_PATH];
|
||||
WCHAR entryName [14];
|
||||
ULONG Size;
|
||||
ULONG hash;
|
||||
|
||||
if (longName [0] != 0 && wcslen (directoryFCB->PathName) +
|
||||
sizeof(WCHAR) + wcslen (longName) > MAX_PATH)
|
||||
{
|
||||
|
@ -281,21 +376,22 @@ vfatMakeFCBFromDirEntry(PVCB vcb,
|
|||
{
|
||||
wcscat (pathName, L"\\");
|
||||
}
|
||||
hash = vfatNameHash(0, pathName);
|
||||
vfatGetDirEntryName (dirEntry, entryName);
|
||||
if (longName [0] != 0)
|
||||
{
|
||||
wcscat (pathName, longName);
|
||||
}
|
||||
else
|
||||
{
|
||||
WCHAR entryName [MAX_PATH];
|
||||
|
||||
vfatGetDirEntryName (dirEntry, entryName);
|
||||
wcscat (pathName, entryName);
|
||||
}
|
||||
rcFCB = vfatNewFCB (pathName);
|
||||
memcpy (&rcFCB->entry, dirEntry, sizeof (FAT_DIR_ENTRY));
|
||||
|
||||
if (vfatFCBIsDirectory(vcb, rcFCB))
|
||||
wcscpy(rcFCB->ShortName, entryName);
|
||||
rcFCB->ShortHash.Hash = vfatNameHash(hash, entryName);
|
||||
|
||||
if (vfatFCBIsDirectory(rcFCB))
|
||||
{
|
||||
ULONG FirstCluster, CurrentCluster;
|
||||
NTSTATUS Status;
|
||||
|
@ -320,11 +416,12 @@ vfatMakeFCBFromDirEntry(PVCB vcb,
|
|||
Size = rcFCB->entry.FileSize;
|
||||
}
|
||||
rcFCB->dirIndex = dirIndex;
|
||||
rcFCB->startIndex = startIndex;
|
||||
rcFCB->RFCB.FileSize.QuadPart = Size;
|
||||
rcFCB->RFCB.ValidDataLength.QuadPart = Size;
|
||||
rcFCB->RFCB.AllocationSize.QuadPart = ROUND_UP(Size, vcb->FatInfo.BytesPerCluster);
|
||||
rcFCB->RefCount++;
|
||||
if (vfatFCBIsDirectory(vcb, rcFCB))
|
||||
if (vfatFCBIsDirectory(rcFCB))
|
||||
{
|
||||
vfatFCBInitializeCacheFromVolume(vcb, rcFCB);
|
||||
}
|
||||
|
@ -342,7 +439,7 @@ vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb,
|
|||
NTSTATUS status;
|
||||
PVFATCCB newCCB;
|
||||
|
||||
newCCB = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
|
||||
newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
|
||||
if (newCCB == NULL)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
@ -368,13 +465,15 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt,
|
|||
PWSTR pFileToFind,
|
||||
PVFATFCB * pFoundFCB)
|
||||
{
|
||||
BOOL finishedScanningDirectory;
|
||||
ULONG directoryIndex;
|
||||
ULONG startIndex;
|
||||
NTSTATUS status;
|
||||
WCHAR defaultFileName [2];
|
||||
WCHAR currentLongName [256];
|
||||
FAT_DIR_ENTRY currentDirEntry;
|
||||
WCHAR currentEntryName [256];
|
||||
PVOID Context = NULL;
|
||||
PVOID Page;
|
||||
|
||||
assert (pDeviceExt);
|
||||
assert (pDirectoryFCB);
|
||||
|
@ -395,30 +494,25 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt,
|
|||
}
|
||||
|
||||
directoryIndex = 0;
|
||||
finishedScanningDirectory = FALSE;
|
||||
while (!finishedScanningDirectory)
|
||||
while (TRUE)
|
||||
{
|
||||
status = vfatGetNextDirEntry (pDeviceExt,
|
||||
pDirectoryFCB,
|
||||
&directoryIndex,
|
||||
currentLongName,
|
||||
¤tDirEntry);
|
||||
status = vfatGetNextDirEntry(&Context,
|
||||
&Page,
|
||||
pDirectoryFCB,
|
||||
&directoryIndex,
|
||||
currentLongName,
|
||||
¤tDirEntry,
|
||||
&startIndex);
|
||||
if (status == STATUS_NO_MORE_ENTRIES)
|
||||
{
|
||||
finishedScanningDirectory = TRUE;
|
||||
continue;
|
||||
}
|
||||
else if (!NT_SUCCESS(status))
|
||||
{
|
||||
return status;
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
DPRINT (" Index:%d longName:%S\n",
|
||||
directoryIndex,
|
||||
currentLongName);
|
||||
|
||||
if (!vfatIsDirEntryDeleted (¤tDirEntry)
|
||||
&& !vfatIsDirEntryVolume(¤tDirEntry))
|
||||
if (!vfatIsDirEntryVolume(¤tDirEntry))
|
||||
{
|
||||
if (currentLongName [0] != L'\0' && wstrcmpjoki (currentLongName, pFileToFind))
|
||||
{
|
||||
|
@ -427,8 +521,10 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt,
|
|||
pDirectoryFCB,
|
||||
currentLongName,
|
||||
¤tDirEntry,
|
||||
directoryIndex - 1,
|
||||
startIndex,
|
||||
directoryIndex,
|
||||
pFoundFCB);
|
||||
CcUnpinData(Context);
|
||||
return status;
|
||||
}
|
||||
else
|
||||
|
@ -443,12 +539,15 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt,
|
|||
pDirectoryFCB,
|
||||
currentLongName,
|
||||
¤tDirEntry,
|
||||
directoryIndex - 1,
|
||||
startIndex,
|
||||
directoryIndex,
|
||||
pFoundFCB);
|
||||
CcUnpinData(Context);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
directoryIndex++;
|
||||
}
|
||||
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
@ -484,11 +583,17 @@ vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
|
|||
|
||||
return (FCB != NULL) ? STATUS_SUCCESS : STATUS_OBJECT_PATH_NOT_FOUND;
|
||||
}
|
||||
else
|
||||
|
||||
currentElement = wcsrchr(pFileName, L'\\');
|
||||
wcsncpy(pathName, pFileName, currentElement - pFileName);
|
||||
currentElement++;
|
||||
|
||||
FCB = vfatGrabFCBFromTable(pVCB, pathName);
|
||||
if (FCB == NULL)
|
||||
{
|
||||
currentElement = pFileName + 1;
|
||||
wcscpy (pathName, L"\\");
|
||||
FCB = vfatOpenRootFCB (pVCB);
|
||||
currentElement = pFileName + 1;
|
||||
wcscpy (pathName, L"\\");
|
||||
FCB = vfatOpenRootFCB (pVCB);
|
||||
}
|
||||
parentFCB = NULL;
|
||||
|
||||
|
@ -512,7 +617,7 @@ vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
|
|||
parentFCB = 0;
|
||||
}
|
||||
// fail if element in FCB is not a directory
|
||||
if (!vfatFCBIsDirectory (pVCB, FCB))
|
||||
if (!vfatFCBIsDirectory (FCB))
|
||||
{
|
||||
DPRINT ("Element in requested path is not a directory\n");
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 ?)
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue