From edda3b622fc1fd1de1e781d09b3366d13a3c8a82 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Mon, 12 Dec 2005 20:15:23 +0000 Subject: [PATCH] Fix the USER32 DLL initialization and cleanup routines to prevent memory/resource leaks and check for allocation errors. svn path=/trunk/; revision=20110 --- reactos/lib/user32/include/menu.h | 2 + reactos/lib/user32/include/message.h | 1 + reactos/lib/user32/include/user32p.h | 5 + reactos/lib/user32/misc/dllmain.c | 159 +++++++++++++++------------ reactos/lib/user32/windows/menu.c | 20 ++++ reactos/lib/user32/windows/message.c | 10 +- 6 files changed, 124 insertions(+), 73 deletions(-) diff --git a/reactos/lib/user32/include/menu.h b/reactos/lib/user32/include/menu.h index 503da0cbeb4..6421250b562 100644 --- a/reactos/lib/user32/include/menu.h +++ b/reactos/lib/user32/include/menu.h @@ -13,6 +13,8 @@ MenuDrawMenuBar(HDC hDC, LPRECT Rect, HWND hWnd, BOOL Draw); BOOL MenuInit(VOID); VOID +MenuCleanup(VOID); +VOID MenuTrackMouseMenuBar(HWND hWnd, ULONG Ht, POINT Pt); VOID MenuTrackKbdMenuBar(HWND hWnd, ULONG wParam, ULONG Key); diff --git a/reactos/lib/user32/include/message.h b/reactos/lib/user32/include/message.h index 39ad489e703..133c77c568b 100644 --- a/reactos/lib/user32/include/message.h +++ b/reactos/lib/user32/include/message.h @@ -10,5 +10,6 @@ #define LIB_USER32_INCLUDE_MESSAGE_H BOOL FASTCALL MessageInit(VOID); +VOID FASTCALL MessageCleanup(VOID); #endif /* LIB_USER32_INCLUDE_MESSAGE_H */ diff --git a/reactos/lib/user32/include/user32p.h b/reactos/lib/user32/include/user32p.h index c981b3fbc07..e4d9f0326c3 100644 --- a/reactos/lib/user32/include/user32p.h +++ b/reactos/lib/user32/include/user32p.h @@ -127,5 +127,10 @@ DEVMODEW * STDCALL GdiConvertToDevmodeW(DEVMODEA *dm); +/* FIXME: Belongs to some header. */ +BOOL STDCALL GdiDllInitialize(HANDLE, DWORD, LPVOID); +void InitStockObjects(void); +VOID DeleteFrameBrushes(VOID); + #endif /* EOF */ diff --git a/reactos/lib/user32/misc/dllmain.c b/reactos/lib/user32/misc/dllmain.c index b32f9f3ca0a..a1d8a6f2550 100644 --- a/reactos/lib/user32/misc/dllmain.c +++ b/reactos/lib/user32/misc/dllmain.c @@ -2,106 +2,121 @@ #define NDEBUG #include -/* FIXME: Belongs to some header. */ -BOOL STDCALL GdiDllInitialize(HANDLE, DWORD, LPVOID); -void InitStockObjects(void); -VOID DeleteFrameBrushes(VOID); - -extern CRITICAL_SECTION gcsMPH; static ULONG User32TlsIndex; HINSTANCE User32Instance; -HWINSTA ProcessWindowStation; PUSER32_THREAD_DATA User32GetThreadData() { - return((PUSER32_THREAD_DATA)TlsGetValue(User32TlsIndex)); + return ((PUSER32_THREAD_DATA)TlsGetValue(User32TlsIndex)); } -VOID +BOOL InitThread(VOID) { - PUSER32_THREAD_DATA ThreadData; - - ThreadData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(USER32_THREAD_DATA)); - TlsSetValue(User32TlsIndex, ThreadData); + PUSER32_THREAD_DATA ThreadData; + + ThreadData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(USER32_THREAD_DATA)); + if (ThreadData == NULL) + return FALSE; + if (!TlsSetValue(User32TlsIndex, ThreadData)) + return FALSE; + return TRUE; } VOID CleanupThread(VOID) { - PUSER32_THREAD_DATA ThreadData; + PUSER32_THREAD_DATA ThreadData; - ThreadData = (PUSER32_THREAD_DATA)TlsGetValue(User32TlsIndex); - HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, ThreadData); - TlsSetValue(User32TlsIndex, 0); + ThreadData = (PUSER32_THREAD_DATA)TlsGetValue(User32TlsIndex); + HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, ThreadData); + TlsSetValue(User32TlsIndex, 0); } -VOID +BOOL Init(VOID) { - /* Set up the kernel callbacks. */ - NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_WINDOWPROC] = - (PVOID)User32CallWindowProcFromKernel; - NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_SENDASYNCPROC] = - (PVOID)User32CallSendAsyncProcForKernel; - NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_LOADSYSMENUTEMPLATE] = - (PVOID)User32LoadSysMenuTemplateForKernel; - NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_LOADDEFAULTCURSORS] = - (PVOID)User32SetupDefaultCursors; - NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_HOOKPROC] = - (PVOID)User32CallHookProcFromKernel; - - /* Allocate an index for user32 thread local data. */ - User32TlsIndex = TlsAlloc(); - - MenuInit(); - MessageInit(); - - InitializeCriticalSection(&U32AccelCacheLock); - InitializeCriticalSection(&gcsMPH); - - GdiDllInitialize(NULL, DLL_PROCESS_ATTACH, NULL); - InitStockObjects(); + /* Set up the kernel callbacks. */ + NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_WINDOWPROC] = + (PVOID)User32CallWindowProcFromKernel; + NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_SENDASYNCPROC] = + (PVOID)User32CallSendAsyncProcForKernel; + NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_LOADSYSMENUTEMPLATE] = + (PVOID)User32LoadSysMenuTemplateForKernel; + NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_LOADDEFAULTCURSORS] = + (PVOID)User32SetupDefaultCursors; + NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_HOOKPROC] = + (PVOID)User32CallHookProcFromKernel; + + /* Allocate an index for user32 thread local data. */ + User32TlsIndex = TlsAlloc(); + if (User32TlsIndex != TLS_OUT_OF_INDEXES) + { + if (MessageInit()) + { + if (MenuInit()) + { + InitializeCriticalSection(&U32AccelCacheLock); + GdiDllInitialize(NULL, DLL_PROCESS_ATTACH, NULL); + InitStockObjects(); + + return TRUE; + } + MessageCleanup(); + } + TlsFree(User32TlsIndex); + } + + return FALSE; } VOID Cleanup(VOID) { - GdiDllInitialize(NULL, DLL_PROCESS_DETACH, NULL); - - TlsFree(User32TlsIndex); + DeleteCriticalSection(&U32AccelCacheLock); + MenuCleanup(); + MessageCleanup(); + DeleteFrameBrushes(); + GdiDllInitialize(NULL, DLL_PROCESS_DETACH, NULL); + TlsFree(User32TlsIndex); } - - INT STDCALL DllMain( - PVOID hinstDll, - ULONG dwReason, - PVOID reserved - ) + IN PVOID hInstanceDll, + IN ULONG dwReason, + IN PVOID reserved) { - switch (dwReason) - { - case DLL_PROCESS_ATTACH: - User32Instance = hinstDll; - hProcessHeap = RtlGetProcessHeap(); - Init(); - InitThread(); - break; - case DLL_THREAD_ATTACH: - InitThread(); - break; - case DLL_THREAD_DETACH: - CleanupThread(); - break; - case DLL_PROCESS_DETACH: - DeleteFrameBrushes(); - CleanupThread(); - Cleanup(); - break; - } - return(1); + switch (dwReason) + { + case DLL_PROCESS_ATTACH: + User32Instance = hInstanceDll; + hProcessHeap = RtlGetProcessHeap(); + if (!Init()) + return FALSE; + if (!InitThread()) + { + Cleanup(); + return FALSE; + } + break; + + case DLL_THREAD_ATTACH: + if (!InitThread()) + return FALSE; + break; + + case DLL_THREAD_DETACH: + CleanupThread(); + break; + + case DLL_PROCESS_DETACH: + CleanupThread(); + Cleanup(); + break; + } + + return TRUE; } diff --git a/reactos/lib/user32/windows/menu.c b/reactos/lib/user32/windows/menu.c index e19d6666988..65d174989c6 100644 --- a/reactos/lib/user32/windows/menu.c +++ b/reactos/lib/user32/windows/menu.c @@ -1077,6 +1077,8 @@ MenuInit(VOID) if(hMenuFontBold == NULL) { DbgPrint("MenuInit(): CreateFontIndirectW(hMenuFontBold) failed!\n"); + DeleteObject(hMenuFont); + hMenuFont = NULL; return FALSE; } } @@ -1085,6 +1087,24 @@ MenuInit(VOID) } +VOID +MenuCleanup(VOID) +{ + if (hMenuFont) + { + DeleteObject(hMenuFont); + hMenuFont = NULL; + } + + if (hMenuFontBold) + { + DeleteObject(hMenuFontBold); + hMenuFontBold = NULL; + } +} + + + /*********************************************************************** * MenuCalcItemSize * diff --git a/reactos/lib/user32/windows/message.c b/reactos/lib/user32/windows/message.c index 28772856b6e..31693089148 100644 --- a/reactos/lib/user32/windows/message.c +++ b/reactos/lib/user32/windows/message.c @@ -2107,14 +2107,22 @@ MsgWaitForMultipleObjects( } -BOOL FASTCALL MessageInit() +BOOL FASTCALL MessageInit(VOID) { InitializeCriticalSection(&DdeCrst); InitializeCriticalSection(&MsgConversionCrst); + InitializeCriticalSection(&gcsMPH); return TRUE; } +VOID FASTCALL MessageCleanup(VOID) +{ + DeleteCriticalSection(&DdeCrst); + DeleteCriticalSection(&MsgConversionCrst); + DeleteCriticalSection(&gcsMPH); +} + /*********************************************************************** * map_wparam_AtoW * -- 2.17.1