* Used look aside lists to allocate memory for VFATFCB, VFATCCB and VFAT_IRP_CONTEXT.

* Removed IsLastEntry, IsVolEntry, IsDeletedEntry, vfat_wstrlen, vfatGrabFCB,
  vfat_initstr, vfat_wcsncat, vfat_wcsncpy, vfat_movestr, wstrcmpi and replaced
  this functions with existing equivalents or functions from ntoskrnl.
* Merged GetEntryName into vfatGetNextDirEntry for reducing some overhead.
* Implemented a file name cache to speed up the searching for existing fcb.
* Removed some calls to FsdDosDateTimeToFileTime.
* Moved the call to CcZeroData behind the initializing of the cache (in VfatWrite).
* Using existing fcbs in FindFile if there is no '*?' within the search name.

svn path=/trunk/; revision=3740
This commit is contained in:
Hartmut Birr 2002-11-11 21:49:18 +00:00
parent 4ba36f62e4
commit 62eac3dcff
13 changed files with 552 additions and 723 deletions

View file

@ -1,4 +1,4 @@
/* $Id: close.c,v 1.14 2002/09/30 20:48:43 hbirr Exp $ /* $Id: close.c,v 1.15 2002/11/11 21:49:17 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * 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;
} }

View file

@ -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,45 +100,40 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb)
pFcb = vfatOpenRootFCB (DeviceExt); pFcb = vfatOpenRootFCB (DeviceExt);
FileOffset.QuadPart = 0;
if (CcMapData(pFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&Entry))
{
while (TRUE) while (TRUE)
{ {
if (Context == NULL || Offset == ENTRIES_PER_PAGE) if (vfatIsDirEntryVolume(Entry))
{ {
if (Offset == ENTRIES_PER_PAGE) /* copy volume label */
{ vfat8Dot3ToVolumeLabel (Entry->Filename, Entry->Ext, Vpb->VolumeLabel);
Offset = 0; Vpb->VolumeLabelLength = wcslen (Vpb->VolumeLabel) * sizeof(WCHAR);
break;
} }
if (Context) if (vfatIsDirEntryEndMarker(Entry))
{
break;
}
DirIndex++;
Entry++;
if ((DirIndex % ENTRIES_PER_PAGE) == 0)
{ {
CcUnpinData(Context); CcUnpinData(Context);
} FileOffset.u.LowPart += PAGE_SIZE;
FileOffset.u.HighPart = 0;
FileOffset.u.LowPart = (DirIndex - Offset) * sizeof(FATDirEntry);
if (!CcMapData(pFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&Entry)) if (!CcMapData(pFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&Entry))
{ {
Context = NULL; Context = NULL;
break; 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) if (Context)
{ {
CcUnpinData(Context); CcUnpinData(Context);
} }
}
vfatReleaseFCB (DeviceExt, pFcb); vfatReleaseFCB (DeviceExt, pFcb);
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -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);
@ -388,39 +235,58 @@ 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 (Status == STATUS_NO_MORE_ENTRIES)
{ {
if (Offset == ENTRIES_PER_PAGE)
Offset = 0;
if (Context)
{
CcUnpinData(Context);
}
FileOffset.QuadPart = (DirIndex - Offset) * sizeof(FATDirEntry);
if (!CcMapData(Parent->FileObject, &FileOffset, PAGE_SIZE, TRUE,
&Context, (PVOID*)&block))
{
Context = NULL;
break; break;
} }
} if (vfatIsDirEntryVolume(&fatDirEntry))
if (vfatIsDirEntryVolume(&((FATDirEntry*)block)[Offset]))
{ {
Offset++;
DirIndex++; DirIndex++;
continue; continue;
} }
Status = GetEntryName (&Context, (PVOID*)&block, Parent->FileObject, name, vfat8Dot3ToString(fatDirEntry.Filename, fatDirEntry.Ext, name2);
&DirIndex, pDirIndex2);
if (Status == STATUS_NO_MORE_ENTRIES)
break;
Offset = DirIndex % ENTRIES_PER_PAGE;
if (NT_SUCCESS(Status))
{
vfat8Dot3ToString(((FATDirEntry *) block)[Offset].Filename,((FATDirEntry *) block)[Offset].Ext, name2);
if (wstrcmpjoki (name, FileToFind) || wstrcmpjoki (name2, FileToFind)) if (wstrcmpjoki (name, FileToFind) || wstrcmpjoki (name2, FileToFind))
{ {
if (Parent && Parent->PathName) if (Parent && Parent->PathName)
@ -441,25 +307,25 @@ FindFile (PDEVICE_EXTENSION DeviceExt,
Fcb->ObjectName[0]='\\'; Fcb->ObjectName[0]='\\';
Fcb->ObjectName=&Fcb->ObjectName[1]; Fcb->ObjectName=&Fcb->ObjectName[1];
} }
memcpy(&Fcb->entry, &fatDirEntry, sizeof(FATDirEntry));
memcpy (&Fcb->entry, &((FATDirEntry *) block)[Offset], wcsncpy(Fcb->ObjectName, *name == 0 ? name2 : name, MAX_PATH);
sizeof (FATDirEntry));
vfat_wcsncpy (Fcb->ObjectName, name, MAX_PATH);
if (pDirIndex) if (pDirIndex)
*pDirIndex = DirIndex; *pDirIndex = DirIndex;
DPRINT("FindFile: new Pathname %S, new Objectname %S, DirIndex %d\n",Fcb->PathName, Fcb->ObjectName, DirIndex); DPRINT("FindFile: new Pathname %S, new Objectname %S, DirIndex %d\n",Fcb->PathName, Fcb->ObjectName, DirIndex);
if (Context) if (Context)
CcUnpinData(Context); CcUnpinData(Context);
return STATUS_SUCCESS; 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);

View file

@ -1,5 +1,5 @@
/* /*
* $Id: dir.c,v 1.26 2002/09/08 10:22:12 chorns Exp $ * $Id: dir.c,v 1.27 2002/11/11 21:49:18 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * 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;
} }

View file

@ -1,4 +1,4 @@
/* $Id: direntry.c,v 1.9 2002/10/01 19:27:17 chorns Exp $ /* $Id: direntry.c,v 1.10 2002/11/11 21:49:18 hbirr Exp $
* *
* *
* FILE: DirEntry.c * 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,127 +71,126 @@ 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, &currentPage))
if (*pContext == NULL || (*pDirIndex % ENTRIES_PER_PAGE) == 0)
{ {
return STATUS_UNSUCCESSFUL; if (*pContext != NULL)
{
CcUnpinData(*pContext);
}
if (!CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage))
{
*pContext = NULL;
return STATUS_NO_MORE_ENTRIES;
}
}
fatDirEntry = (FATDirEntry*)(*pPage) + *pDirIndex % ENTRIES_PER_PAGE;
longNameEntry = (slot*) fatDirEntry;
dirMap = 0;
if (pStartIndex)
{
*pStartIndex = *pDirIndex;
} }
while (TRUE) while (TRUE)
{ {
fatDirEntry = (FATDirEntry *) currentPage; if (vfatIsDirEntryEndMarker(fatDirEntry))
if (vfatIsDirEntryEndMarker (&fatDirEntry [indexInPage]))
{ {
DPRINT ("end of directory, returning no more entries\n"); CcUnpinData(*pContext);
CcUnpinData(Context); *pContext = NULL;
return STATUS_NO_MORE_ENTRIES; return STATUS_NO_MORE_ENTRIES;
} }
else if (vfatIsDirEntryLongName (&fatDirEntry [indexInPage])
&& !vfatIsDirEntryDeleted (&fatDirEntry [indexInPage])) if (vfatIsDirEntryDeleted (fatDirEntry))
{ {
DPRINT (" long name entry found at %d\n", *pDirectoryIndex); dirMap = 0;
longNameEntry = (slot *) currentPage; *pFileName = 0;
if (pStartIndex)
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)++; *pStartIndex = *pDirIndex + 1;
indexInPage++;
if (indexInPage == ENTRIES_PER_CACHEPAGE(pDeviceExt))
{
indexInPage = 0;
pageNumber++;
CcUnpinData(Context);
FileOffset.QuadPart = pageNumber * CACHEPAGESIZE(pDeviceExt);
if (!CcMapData(pDirectoryFCB->FileObject, &FileOffset,
CACHEPAGESIZE(pDeviceExt), TRUE, &Context, &currentPage))
{
return STATUS_UNSUCCESSFUL;
}
longNameEntry = (slot *) currentPage;
}
DPRINT (" index %d\n", *pDirectoryIndex);
DPRINT (" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n",
5, longNameEntry [indexInPage].name0_4,
6, longNameEntry [indexInPage].name5_10,
2, longNameEntry [indexInPage].name11_12);
cpos++;
vfat_movstr (pLongFileName, 13, 0, cpos * 13);
vfat_wcsncpy (pLongFileName, longNameEntry [indexInPage].name0_4, 5);
vfat_wcsncat (pLongFileName, longNameEntry [indexInPage].name5_10, 5, 6);
vfat_wcsncat (pLongFileName, longNameEntry [indexInPage].name11_12, 11, 2);
DPRINT (" longName: [%S]\n", pLongFileName);
}
(*pDirectoryIndex)++;
indexInPage++;
if (indexInPage == ENTRIES_PER_CACHEPAGE(pDeviceExt))
{
indexInPage = 0;
pageNumber++;
CcUnpinData(Context);
FileOffset.QuadPart = pageNumber * CACHEPAGESIZE(pDeviceExt);
if (!CcMapData(pDirectoryFCB->FileObject, &FileOffset,
CACHEPAGESIZE(pDeviceExt), TRUE, &Context, &currentPage))
{
return STATUS_UNSUCCESSFUL;
}
} }
} }
else else
{ {
memcpy (pDirEntry, &fatDirEntry [indexInPage], sizeof (FAT_DIR_ENTRY)); if (vfatIsDirEntryLongName (fatDirEntry))
(*pDirectoryIndex)++; {
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; break;
} }
} }
CcUnpinData(Context); (*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; return STATUS_SUCCESS;
} }
@ -204,3 +198,6 @@ vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,

View file

@ -1,4 +1,4 @@
/* $Id: dirwr.c,v 1.31 2002/10/01 19:27:18 chorns Exp $ /* $Id: dirwr.c,v 1.32 2002/11/11 21:49:18 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * 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);

View file

@ -1,4 +1,4 @@
/* $Id: fcb.c,v 1.21 2002/10/01 19:27:18 chorns Exp $ /* $Id: fcb.c,v 1.22 2002/11/11 21:49:18 hbirr Exp $
* *
* *
* FILE: fcb.c * 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)
{
rcFCB = CONTAINING_RECORD (current_entry, VFATFCB, FcbListEntry);
if (wstrcmpi (pFileName, rcFCB->PathName)) while (entry)
{
if (entry->Hash == Hash)
{
rcFCB = entry->self;
if (rcFCB->Hash.Hash == Hash)
{
/* compare the long name */
if (!_wcsicmp(pFileName, rcFCB->PathName))
{ {
rcFCB->RefCount++; rcFCB->RefCount++;
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
return rcFCB; return rcFCB;
} }
}
else
{
len = rcFCB->ObjectName - rcFCB->PathName + 1;
if (ObjectName == NULL)
{
ObjectName = wcsrchr(pFileName, L'\\');
if (ObjectName == NULL)
{
ObjectName = pFileName;
}
else
{
ObjectName++;
}
}
//FIXME: need to compare against short name in FCB here /* compare the short name and the directory */
if (!_wcsicmp(ObjectName, rcFCB->ShortName) && !_wcsnicmp(pFileName, rcFCB->PathName, len))
current_entry = current_entry->Flink; {
rcFCB->RefCount++;
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
return rcFCB;
}
}
}
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,
&Page,
pDirectoryFCB, pDirectoryFCB,
&directoryIndex, &directoryIndex,
currentLongName, currentLongName,
&currentDirEntry); &currentDirEntry,
&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 (&currentDirEntry) if (!vfatIsDirEntryVolume(&currentDirEntry))
&& !vfatIsDirEntryVolume(&currentDirEntry))
{ {
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,
&currentDirEntry, &currentDirEntry,
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,
&currentDirEntry, &currentDirEntry,
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,7 +583,13 @@ 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"\\");
@ -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");

View file

@ -1,4 +1,4 @@
/* $Id: finfo.c,v 1.21 2002/09/30 20:47:28 hbirr Exp $ /* $Id: finfo.c,v 1.22 2002/11/11 21:49:18 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * 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:

View file

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

View file

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

View file

@ -1,4 +1,4 @@
/* $Id: misc.c,v 1.3 2002/09/30 20:49:44 hbirr Exp $ /* $Id: misc.c,v 1.4 2002/11/11 21:49:18 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * 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));

View file

@ -1,5 +1,5 @@
/* $Id: rw.c,v 1.49 2002/10/01 19:27:18 chorns Exp $ /* $Id: rw.c,v 1.50 2002/11/11 21:49:18 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * 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)
{ {

View file

@ -1,4 +1,4 @@
/* $Id: string.c,v 1.8 2001/07/05 01:51:53 rex Exp $ /* $Id: string.c,v 1.9 2002/11/11 21:49:18 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * 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 ?)

View file

@ -1,4 +1,4 @@
/* $Id: vfat.h,v 1.47 2002/09/08 10:22:13 chorns Exp $ */ /* $Id: vfat.h,v 1.48 2002/11/11 21:49:18 hbirr Exp $ */
#include <ddk/ntifs.h> #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,