diff --git a/src/sys/device.c b/src/sys/device.c index 4dfef85a..d91ae7f8 100644 --- a/src/sys/device.c +++ b/src/sys/device.c @@ -45,7 +45,7 @@ VOID FspFsvolDeviceLockContextTable(PDEVICE_OBJECT DeviceObject); VOID FspFsvolDeviceUnlockContextTable(PDEVICE_OBJECT DeviceObject); NTSTATUS FspFsvolDeviceCopyContextByNameList(PDEVICE_OBJECT DeviceObject, PVOID **PContexts, PULONG PContextCount); -VOID FspFsvolDeviceDeleteContextByNameList(PVOID *Contexts, ULONG ContextCount); +VOID FspFsvolDeviceDeleteContextList(PVOID *Contexts, ULONG ContextCount); PVOID FspFsvolDeviceEnumerateContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName, BOOLEAN NextFlag, FSP_DEVICE_CONTEXT_BY_NAME_TABLE_RESTART_KEY *RestartKey); PVOID FspFsvolDeviceLookupContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName); @@ -81,7 +81,7 @@ VOID FspDeviceDeleteAll(VOID); #pragma alloc_text(PAGE, FspFsvolDeviceLockContextTable) #pragma alloc_text(PAGE, FspFsvolDeviceUnlockContextTable) #pragma alloc_text(PAGE, FspFsvolDeviceCopyContextByNameList) -#pragma alloc_text(PAGE, FspFsvolDeviceDeleteContextByNameList) +#pragma alloc_text(PAGE, FspFsvolDeviceDeleteContextList) #pragma alloc_text(PAGE, FspFsvolDeviceEnumerateContextByName) #pragma alloc_text(PAGE, FspFsvolDeviceLookupContextByName) #pragma alloc_text(PAGE, FspFsvolDeviceInsertContextByName) @@ -373,6 +373,7 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject) /* initialize our context table */ ExInitializeResourceLite(&FsvolDeviceExtension->FileRenameResource); ExInitializeResourceLite(&FsvolDeviceExtension->ContextTableResource); + InitializeListHead(&FsvolDeviceExtension->ContextList); RtlInitializeGenericTableAvl(&FsvolDeviceExtension->ContextByNameTable, FspFsvolDeviceCompareContextByName, FspFsvolDeviceAllocateContextByName, @@ -620,7 +621,7 @@ NTSTATUS FspFsvolDeviceCopyContextByNameList(PDEVICE_OBJECT DeviceObject, return STATUS_SUCCESS; } -VOID FspFsvolDeviceDeleteContextByNameList(PVOID *Contexts, ULONG ContextCount) +VOID FspFsvolDeviceDeleteContextList(PVOID *Contexts, ULONG ContextCount) { PAGED_CODE(); diff --git a/src/sys/driver.h b/src/sys/driver.h index 7629246f..7b034142 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -1025,6 +1025,7 @@ typedef struct BOOLEAN ExpirationInProgress; ERESOURCE FileRenameResource; ERESOURCE ContextTableResource; + LIST_ENTRY ContextList; RTL_AVL_TABLE ContextByNameTable; PVOID ContextByNameTableElementStorage; UNICODE_STRING VolumeName; @@ -1067,7 +1068,7 @@ VOID FspFsvolDeviceLockContextTable(PDEVICE_OBJECT DeviceObject); VOID FspFsvolDeviceUnlockContextTable(PDEVICE_OBJECT DeviceObject); NTSTATUS FspFsvolDeviceCopyContextByNameList(PDEVICE_OBJECT DeviceObject, PVOID **PContexts, PULONG PContextCount); -VOID FspFsvolDeviceDeleteContextByNameList(PVOID *Contexts, ULONG ContextCount); +VOID FspFsvolDeviceDeleteContextList(PVOID *Contexts, ULONG ContextCount); PVOID FspFsvolDeviceEnumerateContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName, BOOLEAN NextFlag, FSP_DEVICE_CONTEXT_BY_NAME_TABLE_RESTART_KEY *RestartKey); PVOID FspFsvolDeviceLookupContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName); @@ -1169,11 +1170,13 @@ typedef struct FSP_FILE_NODE LONG RefCount; UINT32 DeletePending; /* locked under FSP_FSVOL_DEVICE_EXTENSION::ContextTableResource */ + LONG ActiveCount; /* CREATE w/o CLOSE count */ LONG OpenCount; /* ContextTable ref count */ LONG HandleCount; /* HANDLE count (CREATE/CLEANUP) */ SHARE_ACCESS ShareAccess; ULONG MainFileDenyDeleteCount; /* number of times main file is denying delete */ ULONG StreamDenyDeleteCount; /* number of times open streams are denying delete */ + LIST_ENTRY ActiveEntry; FSP_DEVICE_CONTEXT_BY_NAME_TABLE_ELEMENT ContextByNameElementStorage; /* locked under FSP_FSVOL_DEVICE_EXTENSION::FileRenameResource or Header.Resource */ UNICODE_STRING FileName; diff --git a/src/sys/file.c b/src/sys/file.c index 0c108bee..2fd49d7b 100644 --- a/src/sys/file.c +++ b/src/sys/file.c @@ -256,7 +256,7 @@ VOID FspFileNodeDeleteList(FSP_FILE_NODE **FileNodes, ULONG FileNodeCount) for (Index = 0; FileNodeCount > Index; Index++) FspFileNodeDereference(FileNodes[Index]); - FspFsvolDeviceDeleteContextByNameList(FileNodes, FileNodeCount); + FspFsvolDeviceDeleteContextList(FileNodes, FileNodeCount); } NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject, @@ -692,6 +692,14 @@ exit: if (0 != OpenedFileNode) { FspFileNodeReference(OpenedFileNode); + + ASSERT(0 <= OpenedFileNode->ActiveCount); + ASSERT(0 <= OpenedFileNode->OpenCount); + ASSERT(0 <= OpenedFileNode->HandleCount); + + if (0 == OpenedFileNode->ActiveCount++) + InsertTailList(&FspFsvolDeviceExtension(FsvolDeviceObject)->ContextList, + &FileNode->ActiveEntry); OpenedFileNode->OpenCount++; OpenedFileNode->HandleCount++; } @@ -776,6 +784,7 @@ VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject IoRemoveShareAccess(FileObject, &FileNode->ShareAccess); + ASSERT(0 < FileNode->HandleCount); if (0 == --FileNode->HandleCount) { DeletePending = 0 != FileNode->DeletePending; @@ -908,6 +917,15 @@ VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, ASSERT(DeletedFromContextTable); } + ASSERT(0 < FileNode->ActiveCount); + if (0 == --FileNode->ActiveCount) + { + ASSERT(0 == FileNode->OpenCount); + ASSERT(0 == FileNode->HandleCount); + + RemoveEntryList(&FileNode->ActiveEntry); + } + FspFsvolDeviceUnlockContextTable(FsvolDeviceObject); if (DeletedFromContextTable)