mirror of
https://github.com/reactos/reactos.git
synced 2025-08-12 10:15:30 +00:00
[FASTFAT] Only initialize directory cache on use.
This avoids initializing cache directly on directory open/create. The advantage is we reduce the load on cache manager and on memory manager by avoiding creating everytime a stream file object, and initializing cache for it. This will avoid initializing cache for started applications 'current directory' which is just opened for having a valid handle but no read/write is performed in it, by default. This is a step forward for autochk. CORE-14629
This commit is contained in:
parent
f20bdf1994
commit
3c3ebe3320
9 changed files with 181 additions and 80 deletions
|
@ -88,7 +88,7 @@ VfatCleanupFile(
|
||||||
|
|
||||||
if (BooleanFlagOn(pFcb->Flags, FCB_IS_DIRTY))
|
if (BooleanFlagOn(pFcb->Flags, FCB_IS_DIRTY))
|
||||||
{
|
{
|
||||||
VfatUpdateEntry (pFcb, vfatVolumeIsFatX(DeviceExt));
|
VfatUpdateEntry (DeviceExt, pFcb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BooleanFlagOn(pFcb->Flags, FCB_DELETE_PENDING) &&
|
if (BooleanFlagOn(pFcb->Flags, FCB_DELETE_PENDING) &&
|
||||||
|
|
|
@ -951,7 +951,7 @@ VfatCreateFile(
|
||||||
&pFcb->entry.Fat.UpdateTime);
|
&pFcb->entry.Fat.UpdateTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
VfatUpdateEntry(pFcb, vfatVolumeIsFatX(DeviceExt));
|
VfatUpdateEntry(DeviceExt, pFcb);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExAcquireResourceExclusiveLite(&(pFcb->MainResource), TRUE);
|
ExAcquireResourceExclusiveLite(&(pFcb->MainResource), TRUE);
|
||||||
|
|
|
@ -599,6 +599,7 @@ DoQuery(
|
||||||
|
|
||||||
DPRINT("Buffer=%p tofind=%wZ\n", Buffer, &pCcb->SearchPattern);
|
DPRINT("Buffer=%p tofind=%wZ\n", Buffer, &pCcb->SearchPattern);
|
||||||
|
|
||||||
|
DirContext.DeviceExt = IrpContext->DeviceExt;
|
||||||
DirContext.LongNameU.Buffer = LongNameBuffer;
|
DirContext.LongNameU.Buffer = LongNameBuffer;
|
||||||
DirContext.LongNameU.MaximumLength = sizeof(LongNameBuffer);
|
DirContext.LongNameU.MaximumLength = sizeof(LongNameBuffer);
|
||||||
DirContext.ShortNameU.Buffer = ShortNameBuffer;
|
DirContext.ShortNameU.Buffer = ShortNameBuffer;
|
||||||
|
|
|
@ -41,12 +41,14 @@ vfatDirEntryGetFirstCluster(
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
FATIsDirectoryEmpty(
|
FATIsDirectoryEmpty(
|
||||||
|
PDEVICE_EXTENSION DeviceExt,
|
||||||
PVFATFCB Fcb)
|
PVFATFCB Fcb)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER FileOffset;
|
LARGE_INTEGER FileOffset;
|
||||||
PVOID Context = NULL;
|
PVOID Context = NULL;
|
||||||
PFAT_DIR_ENTRY FatDirEntry;
|
PFAT_DIR_ENTRY FatDirEntry;
|
||||||
ULONG Index, MaxIndex;
|
ULONG Index, MaxIndex;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
if (vfatFCBIsRoot(Fcb))
|
if (vfatFCBIsRoot(Fcb))
|
||||||
{
|
{
|
||||||
|
@ -60,6 +62,12 @@ FATIsDirectoryEmpty(
|
||||||
FileOffset.QuadPart = 0;
|
FileOffset.QuadPart = 0;
|
||||||
MaxIndex = Fcb->RFCB.FileSize.u.LowPart / sizeof(FAT_DIR_ENTRY);
|
MaxIndex = Fcb->RFCB.FileSize.u.LowPart / sizeof(FAT_DIR_ENTRY);
|
||||||
|
|
||||||
|
Status = vfatFCBInitializeCacheFromVolume(DeviceExt, Fcb);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
while (Index < MaxIndex)
|
while (Index < MaxIndex)
|
||||||
{
|
{
|
||||||
if (Context == NULL || (Index % FAT_ENTRIES_PER_PAGE) == 0)
|
if (Context == NULL || (Index % FAT_ENTRIES_PER_PAGE) == 0)
|
||||||
|
@ -109,16 +117,24 @@ FATIsDirectoryEmpty(
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
FATXIsDirectoryEmpty(
|
FATXIsDirectoryEmpty(
|
||||||
|
PDEVICE_EXTENSION DeviceExt,
|
||||||
PVFATFCB Fcb)
|
PVFATFCB Fcb)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER FileOffset;
|
LARGE_INTEGER FileOffset;
|
||||||
PVOID Context = NULL;
|
PVOID Context = NULL;
|
||||||
PFATX_DIR_ENTRY FatXDirEntry;
|
PFATX_DIR_ENTRY FatXDirEntry;
|
||||||
ULONG Index = 0, MaxIndex;
|
ULONG Index = 0, MaxIndex;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
FileOffset.QuadPart = 0;
|
FileOffset.QuadPart = 0;
|
||||||
MaxIndex = Fcb->RFCB.FileSize.u.LowPart / sizeof(FATX_DIR_ENTRY);
|
MaxIndex = Fcb->RFCB.FileSize.u.LowPart / sizeof(FATX_DIR_ENTRY);
|
||||||
|
|
||||||
|
Status = vfatFCBInitializeCacheFromVolume(DeviceExt, Fcb);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
while (Index < MaxIndex)
|
while (Index < MaxIndex)
|
||||||
{
|
{
|
||||||
if (Context == NULL || (Index % FATX_ENTRIES_PER_PAGE) == 0)
|
if (Context == NULL || (Index % FATX_ENTRIES_PER_PAGE) == 0)
|
||||||
|
@ -186,12 +202,20 @@ FATGetNextDirEntry(
|
||||||
BOOLEAN Valid = TRUE;
|
BOOLEAN Valid = TRUE;
|
||||||
BOOLEAN Back = FALSE;
|
BOOLEAN Back = FALSE;
|
||||||
|
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
DirContext->LongNameU.Length = 0;
|
DirContext->LongNameU.Length = 0;
|
||||||
DirContext->LongNameU.Buffer[0] = UNICODE_NULL;
|
DirContext->LongNameU.Buffer[0] = UNICODE_NULL;
|
||||||
|
|
||||||
FileOffset.u.HighPart = 0;
|
FileOffset.u.HighPart = 0;
|
||||||
FileOffset.u.LowPart = ROUND_DOWN(DirContext->DirIndex * sizeof(FAT_DIR_ENTRY), PAGE_SIZE);
|
FileOffset.u.LowPart = ROUND_DOWN(DirContext->DirIndex * sizeof(FAT_DIR_ENTRY), PAGE_SIZE);
|
||||||
|
|
||||||
|
Status = vfatFCBInitializeCacheFromVolume(DirContext->DeviceExt, pDirFcb);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
if (*pContext == NULL || (DirContext->DirIndex % FAT_ENTRIES_PER_PAGE) == 0)
|
if (*pContext == NULL || (DirContext->DirIndex % FAT_ENTRIES_PER_PAGE) == 0)
|
||||||
{
|
{
|
||||||
if (*pContext != NULL)
|
if (*pContext != NULL)
|
||||||
|
@ -461,6 +485,7 @@ FATXGetNextDirEntry(
|
||||||
PFATX_DIR_ENTRY fatxDirEntry;
|
PFATX_DIR_ENTRY fatxDirEntry;
|
||||||
OEM_STRING StringO;
|
OEM_STRING StringO;
|
||||||
ULONG DirIndex = DirContext->DirIndex;
|
ULONG DirIndex = DirContext->DirIndex;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
FileOffset.u.HighPart = 0;
|
FileOffset.u.HighPart = 0;
|
||||||
|
|
||||||
|
@ -498,6 +523,12 @@ FATXGetNextDirEntry(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status = vfatFCBInitializeCacheFromVolume(DirContext->DeviceExt, pDirFcb);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
if (*pContext == NULL || (DirIndex % FATX_ENTRIES_PER_PAGE) == 0)
|
if (*pContext == NULL || (DirIndex % FATX_ENTRIES_PER_PAGE) == 0)
|
||||||
{
|
{
|
||||||
if (*pContext != NULL)
|
if (*pContext != NULL)
|
||||||
|
|
|
@ -16,23 +16,105 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#ifdef KDBG
|
||||||
|
extern UNICODE_STRING DebugFile;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
vfatFCBInitializeCacheFromVolume(
|
||||||
|
PVCB vcb,
|
||||||
|
PVFATFCB fcb)
|
||||||
|
{
|
||||||
|
PFILE_OBJECT fileObject;
|
||||||
|
PVFATCCB newCCB;
|
||||||
|
NTSTATUS status;
|
||||||
|
BOOLEAN Acquired;
|
||||||
|
|
||||||
|
/* Don't re-initialize if already done */
|
||||||
|
if (BooleanFlagOn(fcb->Flags, FCB_CACHE_INITIALIZED))
|
||||||
|
{
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(vfatFCBIsDirectory(fcb));
|
||||||
|
|
||||||
|
Acquired = FALSE;
|
||||||
|
if (!ExIsResourceAcquiredExclusive(&vcb->DirResource))
|
||||||
|
{
|
||||||
|
ExAcquireResourceExclusiveLite(&vcb->DirResource, TRUE);
|
||||||
|
Acquired = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileObject = IoCreateStreamFileObject (NULL, vcb->StorageDevice);
|
||||||
|
|
||||||
|
#ifdef KDBG
|
||||||
|
if (DebugFile.Buffer != NULL && FsRtlIsNameInExpression(&DebugFile, &fcb->LongNameU, FALSE, NULL))
|
||||||
|
{
|
||||||
|
DPRINT1("Attaching %p to %p (%d)\n", fcb, fileObject, fcb->RefCount);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
|
||||||
|
if (newCCB == NULL)
|
||||||
|
{
|
||||||
|
ObDereferenceObject(fileObject);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
RtlZeroMemory(newCCB, sizeof (VFATCCB));
|
||||||
|
|
||||||
|
fileObject->SectionObjectPointer = &fcb->SectionObjectPointers;
|
||||||
|
fileObject->FsContext = fcb;
|
||||||
|
fileObject->FsContext2 = newCCB;
|
||||||
|
fileObject->Vpb = vcb->IoVPB;
|
||||||
|
fcb->FileObject = fileObject;
|
||||||
|
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
CcInitializeCacheMap(fileObject,
|
||||||
|
(PCC_FILE_SIZES)(&fcb->RFCB.AllocationSize),
|
||||||
|
TRUE,
|
||||||
|
&VfatGlobalData->CacheMgrCallbacks,
|
||||||
|
fcb);
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
status = _SEH2_GetExceptionCode();
|
||||||
|
fcb->FileObject = NULL;
|
||||||
|
ExFreeToNPagedLookasideList(&VfatGlobalData->CcbLookasideList, newCCB);
|
||||||
|
ObDereferenceObject(fileObject);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
|
vfatGrabFCB(vcb, fcb);
|
||||||
|
SetFlag(fcb->Flags, FCB_CACHE_INITIALIZED);
|
||||||
|
|
||||||
|
if (Acquired)
|
||||||
|
{
|
||||||
|
ExReleaseResourceLite(&vcb->DirResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* update an existing FAT entry
|
* update an existing FAT entry
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
VfatUpdateEntry(
|
VfatUpdateEntry(
|
||||||
IN PVFATFCB pFcb,
|
IN PDEVICE_EXTENSION DeviceExt,
|
||||||
IN BOOLEAN IsFatX)
|
IN PVFATFCB pFcb)
|
||||||
{
|
{
|
||||||
PVOID Context;
|
PVOID Context;
|
||||||
PDIR_ENTRY PinEntry;
|
PDIR_ENTRY PinEntry;
|
||||||
LARGE_INTEGER Offset;
|
LARGE_INTEGER Offset;
|
||||||
ULONG SizeDirEntry;
|
ULONG SizeDirEntry;
|
||||||
ULONG dirIndex;
|
ULONG dirIndex;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
ASSERT(pFcb);
|
ASSERT(pFcb);
|
||||||
|
|
||||||
if (IsFatX)
|
if (vfatVolumeIsFatX(DeviceExt))
|
||||||
{
|
{
|
||||||
SizeDirEntry = sizeof(FATX_DIR_ENTRY);
|
SizeDirEntry = sizeof(FATX_DIR_ENTRY);
|
||||||
dirIndex = pFcb->startIndex;
|
dirIndex = pFcb->startIndex;
|
||||||
|
@ -52,6 +134,12 @@ VfatUpdateEntry(
|
||||||
|
|
||||||
ASSERT(pFcb->parentFcb);
|
ASSERT(pFcb->parentFcb);
|
||||||
|
|
||||||
|
Status = vfatFCBInitializeCacheFromVolume(DeviceExt, pFcb->parentFcb);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
Offset.u.HighPart = 0;
|
Offset.u.HighPart = 0;
|
||||||
Offset.u.LowPart = dirIndex * SizeDirEntry;
|
Offset.u.LowPart = dirIndex * SizeDirEntry;
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
|
@ -91,6 +179,12 @@ vfatRenameEntry(
|
||||||
|
|
||||||
DPRINT("vfatRenameEntry(%p, %p, %wZ, %d)\n", DeviceExt, pFcb, FileName, CaseChangeOnly);
|
DPRINT("vfatRenameEntry(%p, %p, %wZ, %d)\n", DeviceExt, pFcb, FileName, CaseChangeOnly);
|
||||||
|
|
||||||
|
Status = vfatFCBInitializeCacheFromVolume(DeviceExt, pFcb->parentFcb);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
if (vfatVolumeIsFatX(DeviceExt))
|
if (vfatVolumeIsFatX(DeviceExt))
|
||||||
{
|
{
|
||||||
VFAT_DIRENTRY_CONTEXT DirContext;
|
VFAT_DIRENTRY_CONTEXT DirContext;
|
||||||
|
@ -120,6 +214,7 @@ vfatRenameEntry(
|
||||||
pDirEntry->FilenameLength = (unsigned char)NameA.Length;
|
pDirEntry->FilenameLength = (unsigned char)NameA.Length;
|
||||||
|
|
||||||
/* Update FCB */
|
/* Update FCB */
|
||||||
|
DirContext.DeviceExt = DeviceExt;
|
||||||
DirContext.ShortNameU.Length = 0;
|
DirContext.ShortNameU.Length = 0;
|
||||||
DirContext.ShortNameU.MaximumLength = 0;
|
DirContext.ShortNameU.MaximumLength = 0;
|
||||||
DirContext.ShortNameU.Buffer = NULL;
|
DirContext.ShortNameU.Buffer = NULL;
|
||||||
|
@ -169,6 +264,12 @@ vfatFindDirSpace(
|
||||||
else
|
else
|
||||||
SizeDirEntry = sizeof(FAT_DIR_ENTRY);
|
SizeDirEntry = sizeof(FAT_DIR_ENTRY);
|
||||||
|
|
||||||
|
Status = vfatFCBInitializeCacheFromVolume(DeviceExt, pDirFcb);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
count = pDirFcb->RFCB.FileSize.u.LowPart / SizeDirEntry;
|
count = pDirFcb->RFCB.FileSize.u.LowPart / SizeDirEntry;
|
||||||
size = DeviceExt->FatInfo.BytesPerCluster / SizeDirEntry;
|
size = DeviceExt->FatInfo.BytesPerCluster / SizeDirEntry;
|
||||||
for (i = 0; i < count; i++, pFatEntry = (PDIR_ENTRY)((ULONG_PTR)pFatEntry + SizeDirEntry))
|
for (i = 0; i < count; i++, pFatEntry = (PDIR_ENTRY)((ULONG_PTR)pFatEntry + SizeDirEntry))
|
||||||
|
@ -343,6 +444,7 @@ FATAddEntry(
|
||||||
NameA.Length = 0;
|
NameA.Length = 0;
|
||||||
NameA.MaximumLength = sizeof(aName);
|
NameA.MaximumLength = sizeof(aName);
|
||||||
|
|
||||||
|
DirContext.DeviceExt = DeviceExt;
|
||||||
DirContext.ShortNameU.Buffer = ShortNameBuffer;
|
DirContext.ShortNameU.Buffer = ShortNameBuffer;
|
||||||
DirContext.ShortNameU.Length = 0;
|
DirContext.ShortNameU.Length = 0;
|
||||||
DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer);
|
DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer);
|
||||||
|
@ -359,6 +461,7 @@ FATAddEntry(
|
||||||
needTilde = TRUE;
|
needTilde = TRUE;
|
||||||
needLong = TRUE;
|
needLong = TRUE;
|
||||||
RtlZeroMemory(&NameContext, sizeof(GENERATE_NAME_CONTEXT));
|
RtlZeroMemory(&NameContext, sizeof(GENERATE_NAME_CONTEXT));
|
||||||
|
SearchContext.DeviceExt = DeviceExt;
|
||||||
SearchContext.LongNameU.Buffer = LongNameBuffer;
|
SearchContext.LongNameU.Buffer = LongNameBuffer;
|
||||||
SearchContext.LongNameU.MaximumLength = sizeof(LongNameBuffer);
|
SearchContext.LongNameU.MaximumLength = sizeof(LongNameBuffer);
|
||||||
SearchContext.ShortNameU.Buffer = ShortSearchName;
|
SearchContext.ShortNameU.Buffer = ShortSearchName;
|
||||||
|
@ -577,6 +680,8 @@ FATAddEntry(
|
||||||
DirContext.DirEntry.Fat.FirstCluster = (unsigned short)CurrentCluster;
|
DirContext.DirEntry.Fat.FirstCluster = (unsigned short)CurrentCluster;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* No need to init cache here, vfatFindDirSpace() will have done it for us */
|
||||||
|
|
||||||
i = DeviceExt->FatInfo.BytesPerCluster / sizeof(FAT_DIR_ENTRY);
|
i = DeviceExt->FatInfo.BytesPerCluster / sizeof(FAT_DIR_ENTRY);
|
||||||
FileOffset.u.HighPart = 0;
|
FileOffset.u.HighPart = 0;
|
||||||
FileOffset.u.LowPart = DirContext.StartIndex * sizeof(FAT_DIR_ENTRY);
|
FileOffset.u.LowPart = DirContext.StartIndex * sizeof(FAT_DIR_ENTRY);
|
||||||
|
@ -659,6 +764,12 @@ FATAddEntry(
|
||||||
|
|
||||||
if (IsDirectory)
|
if (IsDirectory)
|
||||||
{
|
{
|
||||||
|
Status = vfatFCBInitializeCacheFromVolume(DeviceExt, (*Fcb));
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
FileOffset.QuadPart = 0;
|
FileOffset.QuadPart = 0;
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
|
@ -741,6 +852,7 @@ FATXAddEntry(
|
||||||
DirContext.ShortNameU.Buffer = 0;
|
DirContext.ShortNameU.Buffer = 0;
|
||||||
DirContext.ShortNameU.Length = 0;
|
DirContext.ShortNameU.Length = 0;
|
||||||
DirContext.ShortNameU.MaximumLength = 0;
|
DirContext.ShortNameU.MaximumLength = 0;
|
||||||
|
DirContext.DeviceExt = DeviceExt;
|
||||||
RtlZeroMemory(&DirContext.DirEntry.FatX, sizeof(FATX_DIR_ENTRY));
|
RtlZeroMemory(&DirContext.DirEntry.FatX, sizeof(FATX_DIR_ENTRY));
|
||||||
memset(DirContext.DirEntry.FatX.Filename, 0xff, 42);
|
memset(DirContext.DirEntry.FatX.Filename, 0xff, 42);
|
||||||
/* Use cluster, if moving */
|
/* Use cluster, if moving */
|
||||||
|
@ -784,6 +896,8 @@ FATXAddEntry(
|
||||||
DirContext.DirEntry.FatX.FileSize = MoveContext->FileSize;
|
DirContext.DirEntry.FatX.FileSize = MoveContext->FileSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* No need to init cache here, vfatFindDirSpace() will have done it for us */
|
||||||
|
|
||||||
/* add entry into parent directory */
|
/* add entry into parent directory */
|
||||||
FileOffset.u.HighPart = 0;
|
FileOffset.u.HighPart = 0;
|
||||||
FileOffset.u.LowPart = Index * sizeof(FATX_DIR_ENTRY);
|
FileOffset.u.LowPart = Index * sizeof(FATX_DIR_ENTRY);
|
||||||
|
@ -829,10 +943,17 @@ FATDelEntry(
|
||||||
PVOID Context = NULL;
|
PVOID Context = NULL;
|
||||||
LARGE_INTEGER Offset;
|
LARGE_INTEGER Offset;
|
||||||
PFAT_DIR_ENTRY pDirEntry = NULL;
|
PFAT_DIR_ENTRY pDirEntry = NULL;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
ASSERT(pFcb);
|
ASSERT(pFcb);
|
||||||
ASSERT(pFcb->parentFcb);
|
ASSERT(pFcb->parentFcb);
|
||||||
|
|
||||||
|
Status = vfatFCBInitializeCacheFromVolume(DeviceExt, pFcb->parentFcb);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
DPRINT("delEntry PathName \'%wZ\'\n", &pFcb->PathNameU);
|
DPRINT("delEntry PathName \'%wZ\'\n", &pFcb->PathNameU);
|
||||||
DPRINT("delete entry: %u to %u\n", pFcb->startIndex, pFcb->dirIndex);
|
DPRINT("delete entry: %u to %u\n", pFcb->startIndex, pFcb->dirIndex);
|
||||||
Offset.u.HighPart = 0;
|
Offset.u.HighPart = 0;
|
||||||
|
@ -910,6 +1031,7 @@ FATXDelEntry(
|
||||||
LARGE_INTEGER Offset;
|
LARGE_INTEGER Offset;
|
||||||
PFATX_DIR_ENTRY pDirEntry;
|
PFATX_DIR_ENTRY pDirEntry;
|
||||||
ULONG StartIndex;
|
ULONG StartIndex;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
ASSERT(pFcb);
|
ASSERT(pFcb);
|
||||||
ASSERT(pFcb->parentFcb);
|
ASSERT(pFcb->parentFcb);
|
||||||
|
@ -917,6 +1039,12 @@ FATXDelEntry(
|
||||||
|
|
||||||
StartIndex = pFcb->startIndex;
|
StartIndex = pFcb->startIndex;
|
||||||
|
|
||||||
|
Status = vfatFCBInitializeCacheFromVolume(DeviceExt, pFcb->parentFcb);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
DPRINT("delEntry PathName \'%wZ\'\n", &pFcb->PathNameU);
|
DPRINT("delEntry PathName \'%wZ\'\n", &pFcb->PathNameU);
|
||||||
DPRINT("delete entry: %u\n", StartIndex);
|
DPRINT("delete entry: %u\n", StartIndex);
|
||||||
Offset.u.HighPart = 0;
|
Offset.u.HighPart = 0;
|
||||||
|
@ -1004,8 +1132,8 @@ VfatMoveEntry(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern BOOLEAN FATXIsDirectoryEmpty(PVFATFCB Fcb);
|
extern BOOLEAN FATXIsDirectoryEmpty(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb);
|
||||||
extern BOOLEAN FATIsDirectoryEmpty(PVFATFCB Fcb);
|
extern BOOLEAN FATIsDirectoryEmpty(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb);
|
||||||
extern NTSTATUS FATGetNextDirEntry(PVOID *pContext, PVOID *pPage, PVFATFCB pDirFcb, PVFAT_DIRENTRY_CONTEXT DirContext, BOOLEAN First);
|
extern NTSTATUS FATGetNextDirEntry(PVOID *pContext, PVOID *pPage, PVFATFCB pDirFcb, PVFAT_DIRENTRY_CONTEXT DirContext, BOOLEAN First);
|
||||||
extern NTSTATUS FATXGetNextDirEntry(PVOID *pContext, PVOID *pPage, PVFATFCB pDirFcb, PVFAT_DIRENTRY_CONTEXT DirContext, BOOLEAN First);
|
extern NTSTATUS FATXGetNextDirEntry(PVOID *pContext, PVOID *pPage, PVFATFCB pDirFcb, PVFAT_DIRENTRY_CONTEXT DirContext, BOOLEAN First);
|
||||||
|
|
||||||
|
|
|
@ -640,62 +640,6 @@ vfatGrabFCBFromTable(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
NTSTATUS
|
|
||||||
vfatFCBInitializeCacheFromVolume(
|
|
||||||
PVCB vcb,
|
|
||||||
PVFATFCB fcb)
|
|
||||||
{
|
|
||||||
PFILE_OBJECT fileObject;
|
|
||||||
PVFATCCB newCCB;
|
|
||||||
NTSTATUS status;
|
|
||||||
|
|
||||||
fileObject = IoCreateStreamFileObject (NULL, vcb->StorageDevice);
|
|
||||||
|
|
||||||
#ifdef KDBG
|
|
||||||
if (DebugFile.Buffer != NULL && FsRtlIsNameInExpression(&DebugFile, &fcb->LongNameU, FALSE, NULL))
|
|
||||||
{
|
|
||||||
DPRINT1("Attaching %p to %p (%d)\n", fcb, fileObject, fcb->RefCount);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
|
|
||||||
if (newCCB == NULL)
|
|
||||||
{
|
|
||||||
ObDereferenceObject(fileObject);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
RtlZeroMemory(newCCB, sizeof (VFATCCB));
|
|
||||||
|
|
||||||
fileObject->SectionObjectPointer = &fcb->SectionObjectPointers;
|
|
||||||
fileObject->FsContext = fcb;
|
|
||||||
fileObject->FsContext2 = newCCB;
|
|
||||||
fileObject->Vpb = vcb->IoVPB;
|
|
||||||
fcb->FileObject = fileObject;
|
|
||||||
|
|
||||||
_SEH2_TRY
|
|
||||||
{
|
|
||||||
CcInitializeCacheMap(fileObject,
|
|
||||||
(PCC_FILE_SIZES)(&fcb->RFCB.AllocationSize),
|
|
||||||
TRUE,
|
|
||||||
&VfatGlobalData->CacheMgrCallbacks,
|
|
||||||
fcb);
|
|
||||||
}
|
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
||||||
{
|
|
||||||
status = _SEH2_GetExceptionCode();
|
|
||||||
fcb->FileObject = NULL;
|
|
||||||
ExFreeToNPagedLookasideList(&VfatGlobalData->CcbLookasideList, newCCB);
|
|
||||||
ObDereferenceObject(fileObject);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
_SEH2_END;
|
|
||||||
|
|
||||||
vfatGrabFCB(vcb, fcb);
|
|
||||||
SetFlag(fcb->Flags, FCB_CACHE_INITIALIZED);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVFATFCB
|
PVFATFCB
|
||||||
vfatMakeRootFCB(
|
vfatMakeRootFCB(
|
||||||
PDEVICE_EXTENSION pVCB)
|
PDEVICE_EXTENSION pVCB)
|
||||||
|
@ -788,16 +732,6 @@ vfatMakeFCBFromDirEntry(
|
||||||
vfatInitFCBFromDirEntry(vcb, rcFCB, DirContext);
|
vfatInitFCBFromDirEntry(vcb, rcFCB, DirContext);
|
||||||
|
|
||||||
rcFCB->RefCount = 1;
|
rcFCB->RefCount = 1;
|
||||||
if (vfatFCBIsDirectory(rcFCB))
|
|
||||||
{
|
|
||||||
Status = vfatFCBInitializeCacheFromVolume(vcb, rcFCB);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
vfatReleaseFCB(vcb, rcFCB);
|
|
||||||
ExFreePoolWithTag(NameU.Buffer, TAG_FCB);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rcFCB->parentFcb = directoryFCB;
|
rcFCB->parentFcb = directoryFCB;
|
||||||
InsertTailList(&directoryFCB->ParentListHead, &rcFCB->ParentListEntry);
|
InsertTailList(&directoryFCB->ParentListHead, &rcFCB->ParentListEntry);
|
||||||
vfatAddFCBToTable(vcb, rcFCB);
|
vfatAddFCBToTable(vcb, rcFCB);
|
||||||
|
@ -880,6 +814,7 @@ vfatDirFindFile(
|
||||||
DirContext.ShortNameU.Buffer = ShortNameBuffer;
|
DirContext.ShortNameU.Buffer = ShortNameBuffer;
|
||||||
DirContext.ShortNameU.Length = 0;
|
DirContext.ShortNameU.Length = 0;
|
||||||
DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer);
|
DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer);
|
||||||
|
DirContext.DeviceExt = pDeviceExt;
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
|
|
|
@ -265,7 +265,7 @@ VfatSetBasicInformation(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VfatUpdateEntry(FCB, vfatVolumeIsFatX(DeviceExt));
|
VfatUpdateEntry(DeviceExt, FCB);
|
||||||
|
|
||||||
if (NotifyFilter != 0)
|
if (NotifyFilter != 0)
|
||||||
{
|
{
|
||||||
|
@ -1407,7 +1407,7 @@ VfatSetAllocationSizeInformation(
|
||||||
Fcb->Flags |= FCB_IS_DIRTY;
|
Fcb->Flags |= FCB_IS_DIRTY;
|
||||||
if (AllocSizeChanged)
|
if (AllocSizeChanged)
|
||||||
{
|
{
|
||||||
VfatUpdateEntry(Fcb, vfatVolumeIsFatX(DeviceExt));
|
VfatUpdateEntry(DeviceExt, Fcb);
|
||||||
|
|
||||||
vfatReportChange(DeviceExt, Fcb, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED);
|
vfatReportChange(DeviceExt, Fcb, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ VfatFlushFile(
|
||||||
|
|
||||||
if (BooleanFlagOn(Fcb->Flags, FCB_IS_DIRTY))
|
if (BooleanFlagOn(Fcb->Flags, FCB_IS_DIRTY))
|
||||||
{
|
{
|
||||||
Status = VfatUpdateEntry(Fcb, vfatVolumeIsFatX(DeviceExt));
|
Status = VfatUpdateEntry(DeviceExt, Fcb);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
IoStatus.Status = Status;
|
IoStatus.Status = Status;
|
||||||
|
|
|
@ -281,7 +281,7 @@ typedef NTSTATUS (*PGET_NEXT_CLUSTER)(PDEVICE_EXTENSION,ULONG,PULONG);
|
||||||
typedef NTSTATUS (*PFIND_AND_MARK_AVAILABLE_CLUSTER)(PDEVICE_EXTENSION,PULONG);
|
typedef NTSTATUS (*PFIND_AND_MARK_AVAILABLE_CLUSTER)(PDEVICE_EXTENSION,PULONG);
|
||||||
typedef NTSTATUS (*PWRITE_CLUSTER)(PDEVICE_EXTENSION,ULONG,ULONG,PULONG);
|
typedef NTSTATUS (*PWRITE_CLUSTER)(PDEVICE_EXTENSION,ULONG,ULONG,PULONG);
|
||||||
|
|
||||||
typedef BOOLEAN (*PIS_DIRECTORY_EMPTY)(struct _VFATFCB*);
|
typedef BOOLEAN (*PIS_DIRECTORY_EMPTY)(PDEVICE_EXTENSION,struct _VFATFCB*);
|
||||||
typedef NTSTATUS (*PADD_ENTRY)(PDEVICE_EXTENSION,PUNICODE_STRING,struct _VFATFCB**,struct _VFATFCB*,ULONG,UCHAR,struct _VFAT_MOVE_CONTEXT*);
|
typedef NTSTATUS (*PADD_ENTRY)(PDEVICE_EXTENSION,PUNICODE_STRING,struct _VFATFCB**,struct _VFATFCB*,ULONG,UCHAR,struct _VFAT_MOVE_CONTEXT*);
|
||||||
typedef NTSTATUS (*PDEL_ENTRY)(PDEVICE_EXTENSION,struct _VFATFCB*,struct _VFAT_MOVE_CONTEXT*);
|
typedef NTSTATUS (*PDEL_ENTRY)(PDEVICE_EXTENSION,struct _VFATFCB*,struct _VFAT_MOVE_CONTEXT*);
|
||||||
typedef NTSTATUS (*PGET_NEXT_DIR_ENTRY)(PVOID*,PVOID*,struct _VFATFCB*,struct _VFAT_DIRENTRY_CONTEXT*,BOOLEAN);
|
typedef NTSTATUS (*PGET_NEXT_DIR_ENTRY)(PVOID*,PVOID*,struct _VFATFCB*,struct _VFAT_DIRENTRY_CONTEXT*,BOOLEAN);
|
||||||
|
@ -352,7 +352,7 @@ BOOLEAN
|
||||||
VfatIsDirectoryEmpty(PDEVICE_EXTENSION DeviceExt,
|
VfatIsDirectoryEmpty(PDEVICE_EXTENSION DeviceExt,
|
||||||
struct _VFATFCB* Fcb)
|
struct _VFATFCB* Fcb)
|
||||||
{
|
{
|
||||||
return DeviceExt->Dispatch.IsDirectoryEmpty(Fcb);
|
return DeviceExt->Dispatch.IsDirectoryEmpty(DeviceExt, Fcb);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
|
@ -570,6 +570,7 @@ typedef struct _VFAT_DIRENTRY_CONTEXT
|
||||||
DIR_ENTRY DirEntry;
|
DIR_ENTRY DirEntry;
|
||||||
UNICODE_STRING LongNameU;
|
UNICODE_STRING LongNameU;
|
||||||
UNICODE_STRING ShortNameU;
|
UNICODE_STRING ShortNameU;
|
||||||
|
PDEVICE_EXTENSION DeviceExt;
|
||||||
} VFAT_DIRENTRY_CONTEXT, *PVFAT_DIRENTRY_CONTEXT;
|
} VFAT_DIRENTRY_CONTEXT, *PVFAT_DIRENTRY_CONTEXT;
|
||||||
|
|
||||||
typedef struct _VFAT_MOVE_CONTEXT
|
typedef struct _VFAT_MOVE_CONTEXT
|
||||||
|
@ -736,10 +737,15 @@ vfatDirEntryGetFirstCluster(
|
||||||
|
|
||||||
/* dirwr.c */
|
/* dirwr.c */
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
vfatFCBInitializeCacheFromVolume(
|
||||||
|
PVCB vcb,
|
||||||
|
PVFATFCB fcb);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
VfatUpdateEntry(
|
VfatUpdateEntry(
|
||||||
PVFATFCB pFcb,
|
IN PDEVICE_EXTENSION DeviceExt,
|
||||||
IN BOOLEAN IsFatX);
|
PVFATFCB pFcb);
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
vfatFindDirSpace(
|
vfatFindDirSpace(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue