dll: streamline DLL_PROCESS_ATTACH, DLL_PROCESS_DETACH handling

This commit is contained in:
Bill Zissimopoulos 2016-05-08 16:22:07 -07:00
parent 27a16e5c54
commit bb946d5a3a
6 changed files with 83 additions and 23 deletions

View File

@ -26,6 +26,24 @@ static INIT_ONCE FspEventLogInitOnce = INIT_ONCE_STATIC_INIT;
static BOOL WINAPI FspEventLogRegisterEventSource( static BOOL WINAPI FspEventLogRegisterEventSource(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context); 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, ...) FSP_API VOID FspEventLog(ULONG Type, PWSTR Format, ...)
{ {
va_list ap; va_list ap;

View File

@ -27,11 +27,11 @@ static FSP_FILE_SYSTEM_INTERFACE FspFileSystemNullInterface;
static CRITICAL_SECTION FspFileSystemMountListGuard; static CRITICAL_SECTION FspFileSystemMountListGuard;
static LIST_ENTRY FspFileSystemMountList = { &FspFileSystemMountList, &FspFileSystemMountList }; 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 * This function is called during DLL_PROCESS_ATTACH. We must therefore keep
* tasks to a minimum. * initialization tasks to a minimum.
* *
* Initialization of synchronization objects is allowed! See: * Initialization of synchronization objects is allowed! See:
* https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971(v=vs.85).aspx * https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971(v=vs.85).aspx
@ -40,16 +40,11 @@ VOID FspFileSystemInitialize(VOID)
InitializeCriticalSection(&FspFileSystemMountListGuard); InitializeCriticalSection(&FspFileSystemMountListGuard);
} }
VOID FspFileSystemFinalize(VOID) VOID FspFileSystemFinalize(BOOLEAN Dynamic)
{ {
/* /*
* This function is called during DLL_PROCESS_DETACH. We must therefore keep finalization * This function is called during DLL_PROCESS_DETACH. We must therefore keep
* tasks to a minimum. * 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/
* *
* We enter our FspFileSystemMountListGuard critical section here and then attempt to cleanup * We enter our FspFileSystemMountListGuard critical section here and then attempt to cleanup
* our mount points using DefineDosDeviceW. On Vista and later orphaned critical sections * 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 * 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 * 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! * 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; FSP_FILE_SYSTEM *FileSystem;
@ -79,6 +77,9 @@ VOID FspFileSystemFinalize(VOID)
} }
LeaveCriticalSection(&FspFileSystemMountListGuard); LeaveCriticalSection(&FspFileSystemMountListGuard);
if (Dynamic)
DeleteCriticalSection(&FspFileSystemMountListGuard);
} }
FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath, FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,

View File

@ -22,6 +22,8 @@ HANDLE ProcessHeap;
BOOL WINAPI DllMain(HINSTANCE Instance, DWORD Reason, PVOID Reserved) BOOL WINAPI DllMain(HINSTANCE Instance, DWORD Reason, PVOID Reserved)
{ {
BOOLEAN Dynamic;
switch (Reason) switch (Reason)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
@ -29,11 +31,36 @@ BOOL WINAPI DllMain(HINSTANCE Instance, DWORD Reason, PVOID Reserved)
ProcessHeap = GetProcessHeap(); ProcessHeap = GetProcessHeap();
if (0 == ProcessHeap) if (0 == ProcessHeap)
return FALSE; 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; break;
case DLL_PROCESS_DETACH: 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; break;
} }

View File

@ -103,17 +103,19 @@ BOOLEAN RemoveEntryList(PLIST_ENTRY Entry)
return Flink == Blink; return Flink == Blink;
} }
VOID FspNtStatusInitialize(VOID); VOID FspNtStatusInitialize(BOOLEAN Dynamic);
VOID FspNtStatusFinalize(BOOLEAN Dynamic);
VOID FspFileSystemInitialize(VOID); VOID FspEventLogInitialize(BOOLEAN Dynamic);
VOID FspFileSystemFinalize(VOID); VOID FspEventLogFinalize(BOOLEAN Dynamic);
VOID FspFileSystemInitialize(BOOLEAN Dynamic);
VOID FspFileSystemFinalize(BOOLEAN Dynamic);
VOID FspServiceInitialize(BOOLEAN Dynamic);
VOID FspServiceFinalize(BOOLEAN Dynamic);
NTSTATUS FspFsctlRegister(VOID); NTSTATUS FspFsctlRegister(VOID);
NTSTATUS FspFsctlUnregister(VOID); NTSTATUS FspFsctlUnregister(VOID);
NTSTATUS FspNpRegister(VOID); NTSTATUS FspNpRegister(VOID);
NTSTATUS FspNpUnregister(VOID); NTSTATUS FspNpUnregister(VOID);
NTSTATUS FspEventLogRegister(VOID); NTSTATUS FspEventLogRegister(VOID);
NTSTATUS FspEventLogUnregister(VOID); NTSTATUS FspEventLogUnregister(VOID);

View File

@ -19,11 +19,11 @@
static ULONG (WINAPI *FspRtlNtStatusToDosError)(NTSTATUS Status); 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 * This function is called during DLL_PROCESS_ATTACH. We must therefore keep
* tasks to a minimum. * initialization tasks to a minimum.
* *
* GetModuleHandle/GetProcAddress is allowed (because they are kernel32 API's)! See: * 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 * 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"); FspRtlNtStatusToDosError = (PVOID)GetProcAddress(Handle, "RtlNtStatusToDosError");
} }
VOID FspNtStatusFinalize(BOOLEAN Dynamic)
{
}
FSP_API NTSTATUS FspNtStatusFromWin32(DWORD Error) FSP_API NTSTATUS FspNtStatusFromWin32(DWORD Error)
{ {
switch (Error) switch (Error)

View File

@ -46,6 +46,14 @@ static DWORD WINAPI FspServiceStopRoutine(PVOID Context);
static DWORD WINAPI FspServiceInteractiveThread(PVOID Context); static DWORD WINAPI FspServiceInteractiveThread(PVOID Context);
static BOOL WINAPI FspServiceConsoleCtrlHandler(DWORD CtrlType); static BOOL WINAPI FspServiceConsoleCtrlHandler(DWORD CtrlType);
VOID FspServiceInitialize(BOOLEAN Dynamic)
{
}
VOID FspServiceFinalize(BOOLEAN Dynamic)
{
}
static inline FSP_SERVICE *FspServiceFromTable(VOID) static inline FSP_SERVICE *FspServiceFromTable(VOID)
{ {
FSP_SERVICE *Service = 0; FSP_SERVICE *Service = 0;