From 0eb69122962440bdd9d7e5ea104c2bd51187c7c6 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Sat, 1 Oct 2022 10:47:18 +0100 Subject: [PATCH] sys: FspSiloEnumerate, FspDriverFinalizeDevicesForUnload --- src/sys/driver.c | 12 ++++++++++- src/sys/driver.h | 4 ++++ src/sys/silo.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ tools/deploy.bat | 1 + 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/src/sys/driver.c b/src/sys/driver.c index a8608d12..a6fcddd8 100644 --- a/src/sys/driver.c +++ b/src/sys/driver.c @@ -26,6 +26,7 @@ static DRIVER_UNLOAD DriverUnload; static VOID FspDriverMultiVersionInitialize(VOID); static NTSTATUS FspDriverInitializeDevices(VOID); static VOID FspDriverFinalizeDevices(VOID); +static VOID FspDriverFinalizeDevicesForUnload(VOID); static VOID FspDriverFinalizeDevicesEx(BOOLEAN DeleteDevices); NTSTATUS FspDriverUnload( PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); @@ -36,6 +37,7 @@ NTSTATUS FspDriverUnload( #pragma alloc_text(INIT, FspDriverMultiVersionInitialize) #pragma alloc_text(PAGE, FspDriverInitializeDevices) #pragma alloc_text(PAGE, FspDriverFinalizeDevices) +#pragma alloc_text(PAGE, FspDriverFinalizeDevicesForUnload) #pragma alloc_text(PAGE, FspDriverFinalizeDevicesEx) #pragma alloc_text(PAGE, FspDriverUnload) #endif @@ -406,6 +408,13 @@ static VOID FspDriverFinalizeDevices(VOID) FspDriverFinalizeDevicesEx(TRUE); } +static VOID FspDriverFinalizeDevicesForUnload(VOID) +{ + PAGED_CODE(); + + FspDriverFinalizeDevicesEx(FALSE); +} + static VOID FspDriverFinalizeDevicesEx(BOOLEAN DeleteDevices) { PAGED_CODE(); @@ -510,7 +519,8 @@ NTSTATUS FspDriverUnload( if (!NT_SUCCESS(Result)) goto exit; - FspDriverFinalizeDevicesEx(FALSE); + FspSiloEnumerate(FspDriverFinalizeDevicesForUnload); + FspDriverFinalizeDevicesForUnload(); Result = FspDeviceCopyList(&DeviceObjects, &DeviceObjectCount); if (NT_SUCCESS(Result)) diff --git a/src/sys/driver.h b/src/sys/driver.h index d63d5b73..498ddccc 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -751,6 +751,8 @@ PUNICODE_STRING FspSxsSuffix(VOID); /* silos */ typedef struct { + PVOID Silo; + LIST_ENTRY ListEntry; PDEVICE_OBJECT FsctlDiskDeviceObject; PDEVICE_OBJECT FsctlNetDeviceObject; PDEVICE_OBJECT FsmupDeviceObject; @@ -760,6 +762,7 @@ typedef struct } FSP_SILO_GLOBALS; typedef NTSTATUS (*FSP_SILO_INIT_CALLBACK)(VOID); typedef VOID (*FSP_SILO_FINI_CALLBACK)(VOID); +typedef VOID (*FSP_SILO_ENUM_CALLBACK)(VOID); BOOLEAN FspSiloIsHost(VOID); NTSTATUS FspSiloGetGlobals(FSP_SILO_GLOBALS **PGlobals); VOID FspSiloDereferenceGlobals(FSP_SILO_GLOBALS *Globals); @@ -767,6 +770,7 @@ VOID FspSiloGetContainerId(GUID *ContainerId); NTSTATUS FspSiloInitialize(FSP_SILO_INIT_CALLBACK Init, FSP_SILO_FINI_CALLBACK Fini); NTSTATUS FspSiloPostInitialize(VOID); VOID FspSiloFinalize(VOID); +VOID FspSiloEnumerate(FSP_SILO_ENUM_CALLBACK EnumFn); /* process buffers */ #define FspProcessBufferSizeMax (64 * 1024) diff --git a/src/sys/silo.c b/src/sys/silo.c index 0dfb6d41..d72ba1a4 100644 --- a/src/sys/silo.c +++ b/src/sys/silo.c @@ -110,6 +110,9 @@ static FSP_SILO_INIT_CALLBACK FspSiloInitCallback; static FSP_SILO_FINI_CALLBACK FspSiloFiniCallback; static BOOLEAN FspSiloInitDone = FALSE; +static FAST_MUTEX FspSiloListMutex; +static LIST_ENTRY FspSiloList; + static FSP_SILO_GLOBALS FspSiloHostGlobals; #define FSP_SILO_MONITOR_REGISTRATION_VERSION 1 @@ -196,6 +199,7 @@ static NTSTATUS NTAPI FspSiloMonitorCreateCallback(FSP_PESILO Silo) if (!NT_SUCCESS(Result)) goto exit; RtlZeroMemory(Globals, sizeof(FSP_SILO_GLOBALS)); + Globals->Silo = Silo; /* PsInsertSiloContext adds reference to Globals */ Result = CALL(PsInsertSiloContext)(Silo, ContextSlot, Globals); @@ -203,6 +207,8 @@ static NTSTATUS NTAPI FspSiloMonitorCreateCallback(FSP_PESILO Silo) goto exit; Inserted = TRUE; + ExAcquireFastMutexUnsafe(&FspSiloListMutex); + if (0 != FspSiloInitCallback) { FSP_PESILO PreviousSilo = CALL(PsAttachSiloToCurrentThread)(Silo); @@ -210,6 +216,11 @@ static NTSTATUS NTAPI FspSiloMonitorCreateCallback(FSP_PESILO Silo) CALL(PsDetachSiloFromCurrentThread)(PreviousSilo); } + if (NT_SUCCESS(Result)) + InsertTailList(&FspSiloList, &Globals->ListEntry); + + ExReleaseFastMutexUnsafe(&FspSiloListMutex); + exit: if (!NT_SUCCESS(Result)) { @@ -244,6 +255,10 @@ static VOID NTAPI FspSiloMonitorTerminateCallback(FSP_PESILO Silo) Result = CALL(PsGetSiloContext)(Silo, ContextSlot, &Globals); if (!NT_SUCCESS(Result)) return; + + ExAcquireFastMutexUnsafe(&FspSiloListMutex); + + RemoveEntryList(&Globals->ListEntry); CALL(PsDereferenceSiloContext)(Globals); Globals = 0; @@ -254,6 +269,8 @@ static VOID NTAPI FspSiloMonitorTerminateCallback(FSP_PESILO Silo) CALL(PsDetachSiloFromCurrentThread)(PreviousSilo); } + ExReleaseFastMutexUnsafe(&FspSiloListMutex); + /* PsRemoveSiloContext removes reference to Globals (possibly freeing it) */ CALL(PsRemoveSiloContext)(Silo, ContextSlot, 0); } @@ -300,6 +317,9 @@ NTSTATUS FspSiloInitialize(FSP_SILO_INIT_CALLBACK Init, FSP_SILO_FINI_CALLBACK F if (!NT_SUCCESS(Result)) goto exit; + ExInitializeFastMutex(&FspSiloListMutex); + InitializeListHead(&FspSiloList); + FspSiloMonitor = Monitor; FspSiloInitCallback = Init; FspSiloFiniCallback = Fini; @@ -334,8 +354,43 @@ VOID FspSiloFinalize(VOID) CALL(PsUnregisterSiloMonitor)(FspSiloMonitor); +#if DBG + ExAcquireFastMutexUnsafe(&FspSiloListMutex); + ASSERT(IsListEmpty(&FspSiloList)); + ExReleaseFastMutexUnsafe(&FspSiloListMutex); +#endif + FspSiloMonitor = 0; FspSiloInitCallback = 0; FspSiloFiniCallback = 0; FspSiloInitDone = FALSE; } + +VOID FspSiloEnumerate(FSP_SILO_ENUM_CALLBACK EnumFn) +{ + KAPC_STATE ApcState; + PLIST_ENTRY ListEntry; + FSP_SILO_GLOBALS *Globals; + + ExAcquireFastMutexUnsafe(&FspSiloListMutex); + + if (!IsListEmpty(&FspSiloList)) + { + KeStackAttachProcess(PsInitialSystemProcess, &ApcState); + + for (ListEntry = FspSiloList.Flink; + &FspSiloList != ListEntry; + ListEntry = ListEntry->Flink) + { + Globals = CONTAINING_RECORD(ListEntry, FSP_SILO_GLOBALS, ListEntry); + + FSP_PESILO PreviousSilo = CALL(PsAttachSiloToCurrentThread)(Globals->Silo); + EnumFn(); + CALL(PsDetachSiloFromCurrentThread)(PreviousSilo); + } + + KeUnstackDetachProcess(&ApcState); + } + + ExReleaseFastMutexUnsafe(&FspSiloListMutex); +} diff --git a/tools/deploy.bat b/tools/deploy.bat index 5777d22d..8da2ea75 100755 --- a/tools/deploy.bat +++ b/tools/deploy.bat @@ -27,6 +27,7 @@ for %%f in ( winfsp-%Suffix%.dll winfsp-tests-%Suffix%.exe memfs-%Suffix%.exe + fsptool-%Suffix%.exe deploy-setup.bat docker-run.bat ) do (