From bb946d5a3a042d2f05b9549985eb91fbf2cf12fd Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Sun, 8 May 2016 16:22:07 -0700 Subject: [PATCH] dll: streamline DLL_PROCESS_ATTACH, DLL_PROCESS_DETACH handling --- src/dll/eventlog.c | 18 ++++++++++++++++++ src/dll/fs.c | 23 ++++++++++++----------- src/dll/library.c | 33 ++++++++++++++++++++++++++++++--- src/dll/library.h | 14 ++++++++------ src/dll/ntstatus.c | 10 +++++++--- src/dll/service.c | 8 ++++++++ 6 files changed, 83 insertions(+), 23 deletions(-) diff --git a/src/dll/eventlog.c b/src/dll/eventlog.c index a409b702..3efed0cb 100644 --- a/src/dll/eventlog.c +++ b/src/dll/eventlog.c @@ -26,6 +26,24 @@ static INIT_ONCE FspEventLogInitOnce = INIT_ONCE_STATIC_INIT; static BOOL WINAPI FspEventLogRegisterEventSource( PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context); +VOID FspEventLogInitialize(BOOLEAN Dynamic) +{ +} + +VOID FspEventLogFinalize(BOOLEAN Dynamic) +{ + /* + * This function is called during DLL_PROCESS_DETACH. We must therefore keep + * finalization tasks to a minimum. + * + * We must deregister our event source (if any). We only do so if the library + * is being explicitly unloaded (rather than the process exiting). + */ + + if (Dynamic && 0 != FspEventLogHandle) + DeregisterEventSource(FspEventLogHandle); +} + FSP_API VOID FspEventLog(ULONG Type, PWSTR Format, ...) { va_list ap; diff --git a/src/dll/fs.c b/src/dll/fs.c index 9b358936..a5b5b5bd 100644 --- a/src/dll/fs.c +++ b/src/dll/fs.c @@ -27,11 +27,11 @@ static FSP_FILE_SYSTEM_INTERFACE FspFileSystemNullInterface; static CRITICAL_SECTION FspFileSystemMountListGuard; static LIST_ENTRY FspFileSystemMountList = { &FspFileSystemMountList, &FspFileSystemMountList }; -VOID FspFileSystemInitialize(VOID) +VOID FspFileSystemInitialize(BOOLEAN Dynamic) { /* - * This function is called during DLL_PROCESS_ATTACH. We must therefore keep initialization - * tasks to a minimum. + * This function is called during DLL_PROCESS_ATTACH. We must therefore keep + * initialization tasks to a minimum. * * Initialization of synchronization objects is allowed! See: * https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971(v=vs.85).aspx @@ -40,16 +40,11 @@ VOID FspFileSystemInitialize(VOID) InitializeCriticalSection(&FspFileSystemMountListGuard); } -VOID FspFileSystemFinalize(VOID) +VOID FspFileSystemFinalize(BOOLEAN Dynamic) { /* - * This function is called during DLL_PROCESS_DETACH. We must therefore keep finalization - * tasks to a minimum. - * - * Very few things can be safely done during DLL_PROCESS_DETACH. See: - * https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971(v=vs.85).aspx - * https://blogs.msdn.microsoft.com/oldnewthing/20070503-00/?p=27003/ - * https://blogs.msdn.microsoft.com/oldnewthing/20100122-00/?p=15193/ + * This function is called during DLL_PROCESS_DETACH. We must therefore keep + * finalization tasks to a minimum. * * We enter our FspFileSystemMountListGuard critical section here and then attempt to cleanup * our mount points using DefineDosDeviceW. On Vista and later orphaned critical sections @@ -60,6 +55,9 @@ VOID FspFileSystemFinalize(VOID) * out to CSRSS, which is probably not the safest thing to do when in DllMain! There is also * some evidence that it may attempt to load DLL's under some circumstances, which is a * definite no-no as we are under the loader lock! + * + * We only delete the criticaly section when being dynamically unloaded. On process exit the + * OS will clean it up for us. */ FSP_FILE_SYSTEM *FileSystem; @@ -79,6 +77,9 @@ VOID FspFileSystemFinalize(VOID) } LeaveCriticalSection(&FspFileSystemMountListGuard); + + if (Dynamic) + DeleteCriticalSection(&FspFileSystemMountListGuard); } FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath, diff --git a/src/dll/library.c b/src/dll/library.c index 82dfa28c..aa2863dd 100644 --- a/src/dll/library.c +++ b/src/dll/library.c @@ -22,6 +22,8 @@ HANDLE ProcessHeap; BOOL WINAPI DllMain(HINSTANCE Instance, DWORD Reason, PVOID Reserved) { + BOOLEAN Dynamic; + switch (Reason) { case DLL_PROCESS_ATTACH: @@ -29,11 +31,36 @@ BOOL WINAPI DllMain(HINSTANCE Instance, DWORD Reason, PVOID Reserved) ProcessHeap = GetProcessHeap(); if (0 == ProcessHeap) return FALSE; - FspNtStatusInitialize(); - FspFileSystemInitialize(); + + /* + * These functions are called during DLL_PROCESS_ATTACH. We must therefore keep + * initialization tasks to a minimum. + * + * See the DLL best practices document: + * https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971(v=vs.85).aspx + */ + Dynamic = 0 == Reserved; + FspNtStatusInitialize(Dynamic); + FspEventLogInitialize(Dynamic); + FspFileSystemInitialize(Dynamic); + FspServiceInitialize(Dynamic); break; + case DLL_PROCESS_DETACH: - FspFileSystemFinalize(); + /* + * These functions are called during DLL_PROCESS_DETACH. We must therefore keep + * finalization tasks to a minimum. + * + * See the following documents: + * https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971(v=vs.85).aspx + * https://blogs.msdn.microsoft.com/oldnewthing/20070503-00/?p=27003/ + * https://blogs.msdn.microsoft.com/oldnewthing/20100122-00/?p=15193/ + */ + Dynamic = 0 == Reserved; + FspServiceFinalize(Dynamic); + FspFileSystemFinalize(Dynamic); + FspEventLogFinalize(Dynamic); + FspNtStatusFinalize(Dynamic); break; } diff --git a/src/dll/library.h b/src/dll/library.h index 113840b8..bc9ec55a 100644 --- a/src/dll/library.h +++ b/src/dll/library.h @@ -103,17 +103,19 @@ BOOLEAN RemoveEntryList(PLIST_ENTRY Entry) return Flink == Blink; } -VOID FspNtStatusInitialize(VOID); - -VOID FspFileSystemInitialize(VOID); -VOID FspFileSystemFinalize(VOID); +VOID FspNtStatusInitialize(BOOLEAN Dynamic); +VOID FspNtStatusFinalize(BOOLEAN Dynamic); +VOID FspEventLogInitialize(BOOLEAN Dynamic); +VOID FspEventLogFinalize(BOOLEAN Dynamic); +VOID FspFileSystemInitialize(BOOLEAN Dynamic); +VOID FspFileSystemFinalize(BOOLEAN Dynamic); +VOID FspServiceInitialize(BOOLEAN Dynamic); +VOID FspServiceFinalize(BOOLEAN Dynamic); NTSTATUS FspFsctlRegister(VOID); NTSTATUS FspFsctlUnregister(VOID); - NTSTATUS FspNpRegister(VOID); NTSTATUS FspNpUnregister(VOID); - NTSTATUS FspEventLogRegister(VOID); NTSTATUS FspEventLogUnregister(VOID); diff --git a/src/dll/ntstatus.c b/src/dll/ntstatus.c index 25a78167..6c802fc4 100644 --- a/src/dll/ntstatus.c +++ b/src/dll/ntstatus.c @@ -19,11 +19,11 @@ static ULONG (WINAPI *FspRtlNtStatusToDosError)(NTSTATUS Status); -VOID FspNtStatusInitialize(VOID) +VOID FspNtStatusInitialize(BOOLEAN Dynamic) { /* - * This function is called during DLL_PROCESS_ATTACH. We must therefore keep initialization - * tasks to a minimum. + * This function is called during DLL_PROCESS_ATTACH. We must therefore keep + * initialization tasks to a minimum. * * GetModuleHandle/GetProcAddress is allowed (because they are kernel32 API's)! See: * https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971(v=vs.85).aspx @@ -36,6 +36,10 @@ VOID FspNtStatusInitialize(VOID) FspRtlNtStatusToDosError = (PVOID)GetProcAddress(Handle, "RtlNtStatusToDosError"); } +VOID FspNtStatusFinalize(BOOLEAN Dynamic) +{ +} + FSP_API NTSTATUS FspNtStatusFromWin32(DWORD Error) { switch (Error) diff --git a/src/dll/service.c b/src/dll/service.c index ed74be19..67738a04 100644 --- a/src/dll/service.c +++ b/src/dll/service.c @@ -46,6 +46,14 @@ static DWORD WINAPI FspServiceStopRoutine(PVOID Context); static DWORD WINAPI FspServiceInteractiveThread(PVOID Context); static BOOL WINAPI FspServiceConsoleCtrlHandler(DWORD CtrlType); +VOID FspServiceInitialize(BOOLEAN Dynamic) +{ +} + +VOID FspServiceFinalize(BOOLEAN Dynamic) +{ +} + static inline FSP_SERVICE *FspServiceFromTable(VOID) { FSP_SERVICE *Service = 0;