dll: convert all initialization to the initonce pattern

This commit is contained in:
Bill Zissimopoulos 2016-06-16 12:17:38 -07:00
parent b695ef8ad8
commit 68d79b0c3b
13 changed files with 53 additions and 124 deletions

View File

@ -21,13 +21,14 @@
#define FSP_EVENTLOG_NAME LIBRARY_NAME #define FSP_EVENTLOG_NAME LIBRARY_NAME
static HANDLE FspEventLogHandle;
static INIT_ONCE FspEventLogInitOnce = INIT_ONCE_STATIC_INIT; static INIT_ONCE FspEventLogInitOnce = INIT_ONCE_STATIC_INIT;
static BOOL WINAPI FspEventLogRegisterEventSource( static HANDLE FspEventLogHandle;
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context);
VOID FspEventLogInitialize(BOOLEAN Dynamic) static BOOL WINAPI FspEventLogInitialize(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
{ {
FspEventLogHandle = RegisterEventSourceW(0, L"" FSP_EVENTLOG_NAME);
return TRUE;
} }
VOID FspEventLogFinalize(BOOLEAN Dynamic) VOID FspEventLogFinalize(BOOLEAN Dynamic)
@ -55,7 +56,7 @@ FSP_API VOID FspEventLog(ULONG Type, PWSTR Format, ...)
FSP_API VOID FspEventLogV(ULONG Type, PWSTR Format, va_list ap) FSP_API VOID FspEventLogV(ULONG Type, PWSTR Format, va_list ap)
{ {
InitOnceExecuteOnce(&FspEventLogInitOnce, FspEventLogRegisterEventSource, 0, 0); InitOnceExecuteOnce(&FspEventLogInitOnce, FspEventLogInitialize, 0, 0);
if (0 == FspEventLogHandle) if (0 == FspEventLogHandle)
return; return;
@ -85,13 +86,6 @@ FSP_API VOID FspEventLogV(ULONG Type, PWSTR Format, va_list ap)
ReportEventW(FspEventLogHandle, (WORD)Type, 0, EventId, 0, 1, 0, Strings, 0); ReportEventW(FspEventLogHandle, (WORD)Type, 0, EventId, 0, 1, 0, Strings, 0);
} }
static BOOL WINAPI FspEventLogRegisterEventSource(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
{
FspEventLogHandle = RegisterEventSourceW(0, L"" FSP_EVENTLOG_NAME);
return TRUE;
}
NTSTATUS FspEventLogRegister(VOID) NTSTATUS FspEventLogRegister(VOID)
{ {
extern HINSTANCE DllInstance; extern HINSTANCE DllInstance;

View File

@ -24,20 +24,16 @@ enum
static FSP_FILE_SYSTEM_INTERFACE FspFileSystemNullInterface; static FSP_FILE_SYSTEM_INTERFACE FspFileSystemNullInterface;
static INIT_ONCE FspFileSystemInitOnce = INIT_ONCE_STATIC_INIT;
static BOOLEAN FspFileSystemInitialized;
static CRITICAL_SECTION FspFileSystemMountListGuard; static CRITICAL_SECTION FspFileSystemMountListGuard;
static LIST_ENTRY FspFileSystemMountList = { &FspFileSystemMountList, &FspFileSystemMountList }; static LIST_ENTRY FspFileSystemMountList = { &FspFileSystemMountList, &FspFileSystemMountList };
VOID FspFileSystemInitialize(BOOLEAN Dynamic) static BOOL WINAPI FspFileSystemInitialize(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
{ {
/*
* 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
*/
InitializeCriticalSection(&FspFileSystemMountListGuard); InitializeCriticalSection(&FspFileSystemMountListGuard);
return FspFileSystemInitialized = TRUE;
} }
VOID FspFileSystemFinalize(BOOLEAN Dynamic) VOID FspFileSystemFinalize(BOOLEAN Dynamic)
@ -60,6 +56,9 @@ VOID FspFileSystemFinalize(BOOLEAN Dynamic)
* OS will clean it up for us. * OS will clean it up for us.
*/ */
if (!FspFileSystemInitialized)
return;
FSP_FILE_SYSTEM *FileSystem; FSP_FILE_SYSTEM *FileSystem;
PLIST_ENTRY MountEntry; PLIST_ENTRY MountEntry;
@ -95,6 +94,10 @@ FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
if (0 == Interface) if (0 == Interface)
Interface = &FspFileSystemNullInterface; Interface = &FspFileSystemNullInterface;
InitOnceExecuteOnce(&FspFileSystemInitOnce, FspFileSystemInitialize, 0, 0);
if (!FspFileSystemInitialized)
return STATUS_INSUFFICIENT_RESOURCES;
FileSystem = MemAlloc(sizeof *FileSystem); FileSystem = MemAlloc(sizeof *FileSystem);
if (0 == FileSystem) if (0 == FileSystem)
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;

View File

@ -100,8 +100,8 @@ static struct fuse_opt fsp_fuse_core_opts[] =
FUSE_OPT_END, FUSE_OPT_END,
}; };
static INIT_ONCE fsp_fuse_initonce = INIT_ONCE_STATIC_INIT;
static DWORD fsp_fuse_tlskey = TLS_OUT_OF_INDEXES; static DWORD fsp_fuse_tlskey = TLS_OUT_OF_INDEXES;
static INIT_ONCE fsp_fuse_initonce_v = INIT_ONCE_STATIC_INIT;
struct fsp_fuse_obj_hdr struct fsp_fuse_obj_hdr
{ {
@ -129,8 +129,11 @@ static inline void fsp_fuse_obj_free(void *obj)
hdr->dtor(hdr); hdr->dtor(hdr);
} }
VOID fsp_fuse_initialize(BOOLEAN Dynamic) static BOOL WINAPI fsp_fuse_initialize(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
{ {
fsp_fuse_tlskey = TlsAlloc();
return TRUE;
} }
VOID fsp_fuse_finalize(BOOLEAN Dynamic) VOID fsp_fuse_finalize(BOOLEAN Dynamic)
@ -171,18 +174,6 @@ VOID fsp_fuse_finalize_thread(VOID)
} }
} }
static BOOL WINAPI fsp_fuse_initonce_f(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
{
fsp_fuse_tlskey = TlsAlloc();
return TRUE;
}
static inline VOID fsp_fuse_initonce(VOID)
{
InitOnceExecuteOnce(&fsp_fuse_initonce_v, fsp_fuse_initonce_f, 0, 0);
}
FSP_FUSE_API int fsp_fuse_version(struct fsp_fuse_env *env) FSP_FUSE_API int fsp_fuse_version(struct fsp_fuse_env *env)
{ {
return FUSE_VERSION; return FUSE_VERSION;
@ -606,7 +597,7 @@ FSP_FUSE_API struct fuse_context *fsp_fuse_get_context(struct fsp_fuse_env *env)
{ {
struct fuse_context *context; struct fuse_context *context;
fsp_fuse_initonce(); InitOnceExecuteOnce(&fsp_fuse_initonce, fsp_fuse_initialize, 0, 0);
if (TLS_OUT_OF_INDEXES == fsp_fuse_tlskey) if (TLS_OUT_OF_INDEXES == fsp_fuse_tlskey)
return 0; return 0;

View File

@ -18,7 +18,6 @@
#include <dll/library.h> #include <dll/library.h>
HINSTANCE DllInstance; HINSTANCE DllInstance;
HANDLE ProcessHeap;
BOOL WINAPI DllMain(HINSTANCE Instance, DWORD Reason, PVOID Reserved) BOOL WINAPI DllMain(HINSTANCE Instance, DWORD Reason, PVOID Reserved)
{ {
@ -28,24 +27,6 @@ BOOL WINAPI DllMain(HINSTANCE Instance, DWORD Reason, PVOID Reserved)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
DllInstance = Instance; DllInstance = Instance;
ProcessHeap = GetProcessHeap();
if (0 == ProcessHeap)
return FALSE;
/*
* 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);
FspPosixInitialize(Dynamic);
FspEventLogInitialize(Dynamic);
FspFileSystemInitialize(Dynamic);
FspServiceInitialize(Dynamic);
fsp_fuse_initialize(Dynamic);
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
@ -64,7 +45,6 @@ BOOL WINAPI DllMain(HINSTANCE Instance, DWORD Reason, PVOID Reserved)
FspFileSystemFinalize(Dynamic); FspFileSystemFinalize(Dynamic);
FspEventLogFinalize(Dynamic); FspEventLogFinalize(Dynamic);
FspPosixFinalize(Dynamic); FspPosixFinalize(Dynamic);
FspNtStatusFinalize(Dynamic);
break; break;
case DLL_THREAD_DETACH: case DLL_THREAD_DETACH:

View File

@ -36,17 +36,10 @@
#define DEBUGLOGSD(fmt, SD) ((void)0) #define DEBUGLOGSD(fmt, SD) ((void)0)
#endif #endif
VOID FspNtStatusInitialize(BOOLEAN Dynamic);
VOID FspNtStatusFinalize(BOOLEAN Dynamic);
VOID FspPosixInitialize(BOOLEAN Dynamic);
VOID FspPosixFinalize(BOOLEAN Dynamic); VOID FspPosixFinalize(BOOLEAN Dynamic);
VOID FspEventLogInitialize(BOOLEAN Dynamic);
VOID FspEventLogFinalize(BOOLEAN Dynamic); VOID FspEventLogFinalize(BOOLEAN Dynamic);
VOID FspFileSystemInitialize(BOOLEAN Dynamic);
VOID FspFileSystemFinalize(BOOLEAN Dynamic); VOID FspFileSystemFinalize(BOOLEAN Dynamic);
VOID FspServiceInitialize(BOOLEAN Dynamic);
VOID FspServiceFinalize(BOOLEAN Dynamic); VOID FspServiceFinalize(BOOLEAN Dynamic);
VOID fsp_fuse_initialize(BOOLEAN Dynamic);
VOID fsp_fuse_finalize(BOOLEAN Dynamic); VOID fsp_fuse_finalize(BOOLEAN Dynamic);
VOID fsp_fuse_finalize_thread(VOID); VOID fsp_fuse_finalize_thread(VOID);

View File

@ -464,10 +464,9 @@ typedef struct
static inline BOOLEAN FspNpValidateEnum(FSP_NP_ENUM *Enum) static inline BOOLEAN FspNpValidateEnum(FSP_NP_ENUM *Enum)
{ {
#if 0 #if 0
extern HANDLE ProcessHeap;
return return
0 != Enum && 0 != Enum &&
HeapValidate(ProcessHeap, 0, Enum) && HeapValidate(GetProcessHeap(), 0, Enum) &&
'munE' == Enum->Signature; 'munE' == Enum->Signature;
#else #else
return return

View File

@ -17,27 +17,19 @@
#include <dll/library.h> #include <dll/library.h>
static INIT_ONCE FspNtStatusInitOnce = INIT_ONCE_STATIC_INIT;
static ULONG (WINAPI *FspRtlNtStatusToDosError)(NTSTATUS Status); static ULONG (WINAPI *FspRtlNtStatusToDosError)(NTSTATUS Status);
VOID FspNtStatusInitialize(BOOLEAN Dynamic) static BOOL WINAPI FspNtStatusInitialize(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
{ {
/*
* 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
*/
HANDLE Handle; HANDLE Handle;
Handle = GetModuleHandleW(L"ntdll.dll"); Handle = GetModuleHandleW(L"ntdll.dll");
if (0 != Handle) if (0 != Handle)
FspRtlNtStatusToDosError = (PVOID)GetProcAddress(Handle, "RtlNtStatusToDosError"); FspRtlNtStatusToDosError = (PVOID)GetProcAddress(Handle, "RtlNtStatusToDosError");
}
VOID FspNtStatusFinalize(BOOLEAN Dynamic) return TRUE;
{
} }
FSP_API NTSTATUS FspNtStatusFromWin32(DWORD Error) FSP_API NTSTATUS FspNtStatusFromWin32(DWORD Error)
@ -53,6 +45,7 @@ FSP_API NTSTATUS FspNtStatusFromWin32(DWORD Error)
FSP_API DWORD FspWin32FromNtStatus(NTSTATUS Status) FSP_API DWORD FspWin32FromNtStatus(NTSTATUS Status)
{ {
InitOnceExecuteOnce(&FspNtStatusInitOnce, FspNtStatusInitialize, 0, 0);
if (0 == FspRtlNtStatusToDosError) if (0 == FspRtlNtStatusToDosError)
return ERROR_MR_MID_NOT_FOUND; return ERROR_MR_MID_NOT_FOUND;

View File

@ -35,28 +35,10 @@
static PISID FspPosixCreateSid(BYTE Authority, ULONG Count, ...); static PISID FspPosixCreateSid(BYTE Authority, ULONG Count, ...);
static INIT_ONCE FspPosixInitOnceV = INIT_ONCE_STATIC_INIT; static INIT_ONCE FspPosixInitOnce = INIT_ONCE_STATIC_INIT;
static PISID FspAccountDomainSid, FspPrimaryDomainSid; static PISID FspAccountDomainSid, FspPrimaryDomainSid;
VOID FspPosixInitialize(BOOLEAN Dynamic) static BOOL WINAPI FspPosixInitialize(
{
}
VOID FspPosixFinalize(BOOLEAN Dynamic)
{
/*
* This function is called during DLL_PROCESS_DETACH. We must therefore keep
* finalization tasks to a minimum.
*/
if (Dynamic)
{
MemFree(FspAccountDomainSid);
MemFree(FspPrimaryDomainSid);
}
}
static BOOL WINAPI FspPosixInitOnceF(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
{ {
static LSA_OBJECT_ATTRIBUTES Obja; static LSA_OBJECT_ATTRIBUTES Obja;
@ -106,6 +88,20 @@ exit:
return TRUE; return TRUE;
} }
VOID FspPosixFinalize(BOOLEAN Dynamic)
{
/*
* This function is called during DLL_PROCESS_DETACH. We must therefore keep
* finalization tasks to a minimum.
*/
if (Dynamic)
{
MemFree(FspAccountDomainSid);
MemFree(FspPrimaryDomainSid);
}
}
FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid) FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid)
{ {
*PSid = 0; *PSid = 0;
@ -161,7 +157,7 @@ FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid)
*/ */
else if (0x30000 <= Uid && Uid < 0x40000) else if (0x30000 <= Uid && Uid < 0x40000)
{ {
InitOnceExecuteOnce(&FspPosixInitOnceV, FspPosixInitOnceF, 0, 0); InitOnceExecuteOnce(&FspPosixInitOnce, FspPosixInitialize, 0, 0);
if (0 != FspAccountDomainSid && if (0 != FspAccountDomainSid &&
5 == FspAccountDomainSid->IdentifierAuthority.Value[5] && 5 == FspAccountDomainSid->IdentifierAuthority.Value[5] &&
@ -177,7 +173,7 @@ FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid)
} }
else if (0x100000 <= Uid && Uid < 0x200000) else if (0x100000 <= Uid && Uid < 0x200000)
{ {
InitOnceExecuteOnce(&FspPosixInitOnceV, FspPosixInitOnceF, 0, 0); InitOnceExecuteOnce(&FspPosixInitOnce, FspPosixInitialize, 0, 0);
if (0 != FspPrimaryDomainSid && if (0 != FspPrimaryDomainSid &&
5 == FspPrimaryDomainSid->IdentifierAuthority.Value[5] && 5 == FspPrimaryDomainSid->IdentifierAuthority.Value[5] &&
@ -278,7 +274,7 @@ FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid)
*/ */
else if (5 <= Count && 21 == SubAuthority0) else if (5 <= Count && 21 == SubAuthority0)
{ {
InitOnceExecuteOnce(&FspPosixInitOnceV, FspPosixInitOnceF, 0, 0); InitOnceExecuteOnce(&FspPosixInitOnce, FspPosixInitialize, 0, 0);
/* /*
* The order is important! A server that is also a domain controller * The order is important! A server that is also a domain controller

View File

@ -52,10 +52,6 @@ BOOL WINAPI FspServiceConsoleCtrlHandler(DWORD CtrlType);
(FSP_SERVICE *)((PUINT8)FspServiceTable[0].lpServiceName - FIELD_OFFSET(FSP_SERVICE, ServiceName)) :\ (FSP_SERVICE *)((PUINT8)FspServiceTable[0].lpServiceName - FIELD_OFFSET(FSP_SERVICE, ServiceName)) :\
0) 0)
VOID FspServiceInitialize(BOOLEAN Dynamic)
{
}
VOID FspServiceFinalize(BOOLEAN Dynamic) VOID FspServiceFinalize(BOOLEAN Dynamic)
{ {
/* /*

View File

@ -21,7 +21,7 @@
static INIT_ONCE FspDiagIdentInitOnce = INIT_ONCE_STATIC_INIT; static INIT_ONCE FspDiagIdentInitOnce = INIT_ONCE_STATIC_INIT;
static WCHAR FspDiagIdentBuf[20] = L"UNKNOWN"; static WCHAR FspDiagIdentBuf[20] = L"UNKNOWN";
static BOOL WINAPI FspDiagIdentInit( static BOOL WINAPI FspDiagIdentInitialize(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
{ {
WCHAR ModuleFileName[MAX_PATH]; WCHAR ModuleFileName[MAX_PATH];
@ -55,7 +55,7 @@ PWSTR FspDiagIdent(VOID)
{ {
/* internal only: get a diagnostic identifier (eventlog, debug) */ /* internal only: get a diagnostic identifier (eventlog, debug) */
InitOnceExecuteOnce(&FspDiagIdentInitOnce, FspDiagIdentInit, 0, 0); InitOnceExecuteOnce(&FspDiagIdentInitOnce, FspDiagIdentInitialize, 0, 0);
return FspDiagIdentBuf; return FspDiagIdentBuf;
} }

View File

@ -276,16 +276,9 @@ void wmainCRTStartup(void)
DWORD Argc; DWORD Argc;
PWSTR *Argv; PWSTR *Argv;
extern HANDLE ProcessHeap;
ProcessHeap = GetProcessHeap();
if (0 == ProcessHeap)
ExitProcess(GetLastError());
Argv = CommandLineToArgvW(GetCommandLineW(), &Argc); Argv = CommandLineToArgvW(GetCommandLineW(), &Argc);
if (0 == Argv) if (0 == Argv)
ExitProcess(GetLastError()); ExitProcess(GetLastError());
ExitProcess(wmain(Argc, Argv)); ExitProcess(wmain(Argc, Argv));
} }
HANDLE ProcessHeap;

View File

@ -981,12 +981,5 @@ int wmain(int argc, wchar_t **argv)
void wmainCRTStartup(void) void wmainCRTStartup(void)
{ {
extern HANDLE ProcessHeap;
ProcessHeap = GetProcessHeap();
if (0 == ProcessHeap)
ExitProcess(GetLastError());
ExitProcess(wmain(0, 0)); ExitProcess(wmain(0, 0));
} }
HANDLE ProcessHeap;

View File

@ -67,14 +67,12 @@ void *memset(void *dst, int val, size_t siz)
static inline void *MemAlloc(size_t Size) static inline void *MemAlloc(size_t Size)
{ {
extern HANDLE ProcessHeap; return HeapAlloc(GetProcessHeap(), 0, Size);
return HeapAlloc(ProcessHeap, 0, Size);
} }
static inline void MemFree(void *Pointer) static inline void MemFree(void *Pointer)
{ {
extern HANDLE ProcessHeap;
if (0 != Pointer) if (0 != Pointer)
HeapFree(ProcessHeap, 0, Pointer); HeapFree(GetProcessHeap(), 0, Pointer);
} }
static FORCEINLINE static FORCEINLINE