diff --git a/src/sys/device.c b/src/sys/device.c index d91ae7f8..f3eadb22 100644 --- a/src/sys/device.c +++ b/src/sys/device.c @@ -43,6 +43,8 @@ VOID FspFsvolDeviceFileRenameRelease(PDEVICE_OBJECT DeviceObject); VOID FspFsvolDeviceFileRenameReleaseOwner(PDEVICE_OBJECT DeviceObject, PVOID Owner); VOID FspFsvolDeviceLockContextTable(PDEVICE_OBJECT DeviceObject); VOID FspFsvolDeviceUnlockContextTable(PDEVICE_OBJECT DeviceObject); +NTSTATUS FspFsvolDeviceCopyContextList(PDEVICE_OBJECT DeviceObject, + PVOID **PContexts, PULONG PContextCount); NTSTATUS FspFsvolDeviceCopyContextByNameList(PDEVICE_OBJECT DeviceObject, PVOID **PContexts, PULONG PContextCount); VOID FspFsvolDeviceDeleteContextList(PVOID *Contexts, ULONG ContextCount); @@ -80,6 +82,7 @@ VOID FspDeviceDeleteAll(VOID); #pragma alloc_text(PAGE, FspFsvolDeviceFileRenameReleaseOwner) #pragma alloc_text(PAGE, FspFsvolDeviceLockContextTable) #pragma alloc_text(PAGE, FspFsvolDeviceUnlockContextTable) +#pragma alloc_text(PAGE, FspFsvolDeviceCopyContextList) #pragma alloc_text(PAGE, FspFsvolDeviceCopyContextByNameList) #pragma alloc_text(PAGE, FspFsvolDeviceDeleteContextList) #pragma alloc_text(PAGE, FspFsvolDeviceEnumerateContextByName) @@ -587,6 +590,50 @@ VOID FspFsvolDeviceUnlockContextTable(PDEVICE_OBJECT DeviceObject) ExReleaseResourceLite(&FsvolDeviceExtension->ContextTableResource); } +NTSTATUS FspFsvolDeviceCopyContextList(PDEVICE_OBJECT DeviceObject, + PVOID **PContexts, PULONG PContextCount) +{ + PAGED_CODE(); + + FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject); + PVOID *Contexts; + ULONG ContextCount, Index; + + *PContexts = 0; + *PContextCount = 0; + + ContextCount = 0; + for ( + PLIST_ENTRY Head = &FsvolDeviceExtension->ContextList, Entry = Head->Flink; + Head != Entry; + Entry = Entry->Flink) + { + ContextCount++; + } + + /* if ContextCount == 0 allocate an empty Context list */ + Contexts = FspAlloc(sizeof(PVOID) * (0 != ContextCount ? ContextCount : 1)); + if (0 == Contexts) + return STATUS_INSUFFICIENT_RESOURCES; + + Index = 0; + for ( + PLIST_ENTRY Head = &FsvolDeviceExtension->ContextList, Entry = Head->Flink; + Head != Entry; + Entry = Entry->Flink) + { + ASSERT(Index < ContextCount); + Contexts[Index++] = CONTAINING_RECORD(Entry, FSP_FILE_NODE, ActiveEntry); + /* assume that Contexts can only be FSP_FILE_NODE's */ + } + ASSERT(Index == ContextCount); + + *PContexts = Contexts; + *PContextCount = Index; + + return STATUS_SUCCESS; +} + NTSTATUS FspFsvolDeviceCopyContextByNameList(PDEVICE_OBJECT DeviceObject, PVOID **PContexts, PULONG PContextCount) { diff --git a/src/sys/driver.h b/src/sys/driver.h index 7b034142..12fdf824 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -1066,6 +1066,8 @@ VOID FspFsvolDeviceFileRenameRelease(PDEVICE_OBJECT DeviceObject); VOID FspFsvolDeviceFileRenameReleaseOwner(PDEVICE_OBJECT DeviceObject, PVOID Owner); VOID FspFsvolDeviceLockContextTable(PDEVICE_OBJECT DeviceObject); VOID FspFsvolDeviceUnlockContextTable(PDEVICE_OBJECT DeviceObject); +NTSTATUS FspFsvolDeviceCopyContextList(PDEVICE_OBJECT DeviceObject, + PVOID **PContexts, PULONG PContextCount); NTSTATUS FspFsvolDeviceCopyContextByNameList(PDEVICE_OBJECT DeviceObject, PVOID **PContexts, PULONG PContextCount); VOID FspFsvolDeviceDeleteContextList(PVOID *Contexts, ULONG ContextCount); @@ -1236,7 +1238,9 @@ typedef struct HANDLE MainFileHandle; PFILE_OBJECT MainFileObject; } FSP_FILE_DESC; -NTSTATUS FspFileNodeCopyList(PDEVICE_OBJECT DeviceObject, +NTSTATUS FspFileNodeCopyActiveList(PDEVICE_OBJECT DeviceObject, + FSP_FILE_NODE ***PFileNodes, PULONG PFileNodeCount); +NTSTATUS FspFileNodeCopyOpenList(PDEVICE_OBJECT DeviceObject, FSP_FILE_NODE ***PFileNodes, PULONG PFileNodeCount); VOID FspFileNodeDeleteList(FSP_FILE_NODE **FileNodes, ULONG FileNodeCount); NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject, diff --git a/src/sys/file.c b/src/sys/file.c index 2fd49d7b..8102408f 100644 --- a/src/sys/file.c +++ b/src/sys/file.c @@ -17,7 +17,9 @@ #include -NTSTATUS FspFileNodeCopyList(PDEVICE_OBJECT DeviceObject, +NTSTATUS FspFileNodeCopyActiveList(PDEVICE_OBJECT DeviceObject, + FSP_FILE_NODE ***PFileNodes, PULONG PFileNodeCount); +NTSTATUS FspFileNodeCopyOpenList(PDEVICE_OBJECT DeviceObject, FSP_FILE_NODE ***PFileNodes, PULONG PFileNodeCount); VOID FspFileNodeDeleteList(FSP_FILE_NODE **FileNodes, ULONG FileNodeCount); NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject, @@ -100,7 +102,8 @@ VOID FspFileNodeOplockPrepare(PVOID Context, PIRP Irp); VOID FspFileNodeOplockComplete(PVOID Context, PIRP Irp); #ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, FspFileNodeCopyList) +#pragma alloc_text(PAGE, FspFileNodeCopyActiveList) +#pragma alloc_text(PAGE, FspFileNodeCopyOpenList) #pragma alloc_text(PAGE, FspFileNodeDeleteList) #pragma alloc_text(PAGE, FspFileNodeCreate) #pragma alloc_text(PAGE, FspFileNodeDelete) @@ -227,7 +230,27 @@ VOID FspFileNodeOplockComplete(PVOID Context, PIRP Irp); FspFree(DescendantFileNodes); \ ((VOID)0) -NTSTATUS FspFileNodeCopyList(PDEVICE_OBJECT DeviceObject, +NTSTATUS FspFileNodeCopyActiveList(PDEVICE_OBJECT DeviceObject, + FSP_FILE_NODE ***PFileNodes, PULONG PFileNodeCount) +{ + PAGED_CODE(); + + NTSTATUS Result; + ULONG Index; + + FspFsvolDeviceLockContextTable(DeviceObject); + Result = FspFsvolDeviceCopyContextList(DeviceObject, PFileNodes, PFileNodeCount); + if (NT_SUCCESS(Result)) + { + for (Index = 0; *PFileNodeCount > Index; Index++) + FspFileNodeReference((*PFileNodes)[Index]); + } + FspFsvolDeviceUnlockContextTable(DeviceObject); + + return Result; +} + +NTSTATUS FspFileNodeCopyOpenList(PDEVICE_OBJECT DeviceObject, FSP_FILE_NODE ***PFileNodes, PULONG PFileNodeCount) { PAGED_CODE(); diff --git a/src/sys/flush.c b/src/sys/flush.c index bcb5108c..56c3ae9b 100644 --- a/src/sys/flush.c +++ b/src/sys/flush.c @@ -58,7 +58,7 @@ static NTSTATUS FspFsvolFlushBuffers( */ if (!FspFileNodeIsValid(FileNode) || FileNode->IsRootDirectory) { - Result = FspFileNodeCopyList(FsvolDeviceObject, &FileNodes, &FileNodeCount); + Result = FspFileNodeCopyOpenList(FsvolDeviceObject, &FileNodes, &FileNodeCount); if (!NT_SUCCESS(Result)) return Result; diff --git a/src/sys/volume.c b/src/sys/volume.c index 6d1173c9..6719be33 100644 --- a/src/sys/volume.c +++ b/src/sys/volume.c @@ -294,9 +294,9 @@ VOID FspVolumeDelete( FspDeviceGlobalUnlock(); /* - * Call MmForceSectionClosed on open files to ensure that Mm removes them from Standby List. + * Call MmForceSectionClosed on active files to ensure that Mm removes them from Standby List. */ - Result = FspFileNodeCopyList(FsvolDeviceObject, &FileNodes, &FileNodeCount); + Result = FspFileNodeCopyActiveList(FsvolDeviceObject, &FileNodes, &FileNodeCount); if (NT_SUCCESS(Result)) { for (Index = FileNodeCount - 1; FileNodeCount > Index; Index--)