Fix the USER32 DLL initialization and cleanup routines to prevent memory/resource leaks and check for allocation errors.

svn path=/trunk/; revision=20110
This commit is contained in:
Filip Navara 2005-12-12 20:15:23 +00:00
parent 8462e43fb5
commit edda3b622f
6 changed files with 120 additions and 69 deletions

View file

@ -13,6 +13,8 @@ MenuDrawMenuBar(HDC hDC, LPRECT Rect, HWND hWnd, BOOL Draw);
BOOL BOOL
MenuInit(VOID); MenuInit(VOID);
VOID VOID
MenuCleanup(VOID);
VOID
MenuTrackMouseMenuBar(HWND hWnd, ULONG Ht, POINT Pt); MenuTrackMouseMenuBar(HWND hWnd, ULONG Ht, POINT Pt);
VOID VOID
MenuTrackKbdMenuBar(HWND hWnd, ULONG wParam, ULONG Key); MenuTrackKbdMenuBar(HWND hWnd, ULONG wParam, ULONG Key);

View file

@ -10,5 +10,6 @@
#define LIB_USER32_INCLUDE_MESSAGE_H #define LIB_USER32_INCLUDE_MESSAGE_H
BOOL FASTCALL MessageInit(VOID); BOOL FASTCALL MessageInit(VOID);
VOID FASTCALL MessageCleanup(VOID);
#endif /* LIB_USER32_INCLUDE_MESSAGE_H */ #endif /* LIB_USER32_INCLUDE_MESSAGE_H */

View file

@ -127,5 +127,10 @@ DEVMODEW *
STDCALL STDCALL
GdiConvertToDevmodeW(DEVMODEA *dm); GdiConvertToDevmodeW(DEVMODEA *dm);
/* FIXME: Belongs to some header. */
BOOL STDCALL GdiDllInitialize(HANDLE, DWORD, LPVOID);
void InitStockObjects(void);
VOID DeleteFrameBrushes(VOID);
#endif #endif
/* EOF */ /* EOF */

View file

@ -2,106 +2,121 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
/* FIXME: Belongs to some header. */
BOOL STDCALL GdiDllInitialize(HANDLE, DWORD, LPVOID);
void InitStockObjects(void);
VOID DeleteFrameBrushes(VOID);
extern CRITICAL_SECTION gcsMPH;
static ULONG User32TlsIndex; static ULONG User32TlsIndex;
HINSTANCE User32Instance; HINSTANCE User32Instance;
HWINSTA ProcessWindowStation;
PUSER32_THREAD_DATA PUSER32_THREAD_DATA
User32GetThreadData() User32GetThreadData()
{ {
return((PUSER32_THREAD_DATA)TlsGetValue(User32TlsIndex)); return ((PUSER32_THREAD_DATA)TlsGetValue(User32TlsIndex));
} }
VOID BOOL
InitThread(VOID) InitThread(VOID)
{ {
PUSER32_THREAD_DATA ThreadData; PUSER32_THREAD_DATA ThreadData;
ThreadData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ThreadData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(USER32_THREAD_DATA)); sizeof(USER32_THREAD_DATA));
TlsSetValue(User32TlsIndex, ThreadData); if (ThreadData == NULL)
return FALSE;
if (!TlsSetValue(User32TlsIndex, ThreadData))
return FALSE;
return TRUE;
} }
VOID VOID
CleanupThread(VOID) CleanupThread(VOID)
{ {
PUSER32_THREAD_DATA ThreadData; PUSER32_THREAD_DATA ThreadData;
ThreadData = (PUSER32_THREAD_DATA)TlsGetValue(User32TlsIndex); ThreadData = (PUSER32_THREAD_DATA)TlsGetValue(User32TlsIndex);
HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, ThreadData); HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, ThreadData);
TlsSetValue(User32TlsIndex, 0); TlsSetValue(User32TlsIndex, 0);
} }
VOID BOOL
Init(VOID) Init(VOID)
{ {
/* Set up the kernel callbacks. */ /* Set up the kernel callbacks. */
NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_WINDOWPROC] = NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_WINDOWPROC] =
(PVOID)User32CallWindowProcFromKernel; (PVOID)User32CallWindowProcFromKernel;
NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_SENDASYNCPROC] = NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_SENDASYNCPROC] =
(PVOID)User32CallSendAsyncProcForKernel; (PVOID)User32CallSendAsyncProcForKernel;
NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_LOADSYSMENUTEMPLATE] = NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_LOADSYSMENUTEMPLATE] =
(PVOID)User32LoadSysMenuTemplateForKernel; (PVOID)User32LoadSysMenuTemplateForKernel;
NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_LOADDEFAULTCURSORS] = NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_LOADDEFAULTCURSORS] =
(PVOID)User32SetupDefaultCursors; (PVOID)User32SetupDefaultCursors;
NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_HOOKPROC] = NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_HOOKPROC] =
(PVOID)User32CallHookProcFromKernel; (PVOID)User32CallHookProcFromKernel;
/* Allocate an index for user32 thread local data. */ /* Allocate an index for user32 thread local data. */
User32TlsIndex = TlsAlloc(); User32TlsIndex = TlsAlloc();
if (User32TlsIndex != TLS_OUT_OF_INDEXES)
{
if (MessageInit())
{
if (MenuInit())
{
InitializeCriticalSection(&U32AccelCacheLock);
GdiDllInitialize(NULL, DLL_PROCESS_ATTACH, NULL);
InitStockObjects();
MenuInit(); return TRUE;
MessageInit(); }
MessageCleanup();
}
TlsFree(User32TlsIndex);
}
InitializeCriticalSection(&U32AccelCacheLock); return FALSE;
InitializeCriticalSection(&gcsMPH);
GdiDllInitialize(NULL, DLL_PROCESS_ATTACH, NULL);
InitStockObjects();
} }
VOID VOID
Cleanup(VOID) Cleanup(VOID)
{ {
GdiDllInitialize(NULL, DLL_PROCESS_DETACH, NULL); DeleteCriticalSection(&U32AccelCacheLock);
MenuCleanup();
TlsFree(User32TlsIndex); MessageCleanup();
DeleteFrameBrushes();
GdiDllInitialize(NULL, DLL_PROCESS_DETACH, NULL);
TlsFree(User32TlsIndex);
} }
INT STDCALL INT STDCALL
DllMain( DllMain(
PVOID hinstDll, IN PVOID hInstanceDll,
ULONG dwReason, IN ULONG dwReason,
PVOID reserved IN PVOID reserved)
)
{ {
switch (dwReason) switch (dwReason)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
User32Instance = hinstDll; User32Instance = hInstanceDll;
hProcessHeap = RtlGetProcessHeap(); hProcessHeap = RtlGetProcessHeap();
Init(); if (!Init())
InitThread(); return FALSE;
break; if (!InitThread())
case DLL_THREAD_ATTACH: {
InitThread(); Cleanup();
break; return FALSE;
case DLL_THREAD_DETACH: }
CleanupThread(); break;
break;
case DLL_PROCESS_DETACH: case DLL_THREAD_ATTACH:
DeleteFrameBrushes(); if (!InitThread())
CleanupThread(); return FALSE;
Cleanup(); break;
break;
} case DLL_THREAD_DETACH:
return(1); CleanupThread();
break;
case DLL_PROCESS_DETACH:
CleanupThread();
Cleanup();
break;
}
return TRUE;
} }

View file

@ -1077,6 +1077,8 @@ MenuInit(VOID)
if(hMenuFontBold == NULL) if(hMenuFontBold == NULL)
{ {
DbgPrint("MenuInit(): CreateFontIndirectW(hMenuFontBold) failed!\n"); DbgPrint("MenuInit(): CreateFontIndirectW(hMenuFontBold) failed!\n");
DeleteObject(hMenuFont);
hMenuFont = NULL;
return FALSE; return FALSE;
} }
} }
@ -1085,6 +1087,24 @@ MenuInit(VOID)
} }
VOID
MenuCleanup(VOID)
{
if (hMenuFont)
{
DeleteObject(hMenuFont);
hMenuFont = NULL;
}
if (hMenuFontBold)
{
DeleteObject(hMenuFontBold);
hMenuFontBold = NULL;
}
}
/*********************************************************************** /***********************************************************************
* MenuCalcItemSize * MenuCalcItemSize
* *

View file

@ -2107,14 +2107,22 @@ MsgWaitForMultipleObjects(
} }
BOOL FASTCALL MessageInit() BOOL FASTCALL MessageInit(VOID)
{ {
InitializeCriticalSection(&DdeCrst); InitializeCriticalSection(&DdeCrst);
InitializeCriticalSection(&MsgConversionCrst); InitializeCriticalSection(&MsgConversionCrst);
InitializeCriticalSection(&gcsMPH);
return TRUE; return TRUE;
} }
VOID FASTCALL MessageCleanup(VOID)
{
DeleteCriticalSection(&DdeCrst);
DeleteCriticalSection(&MsgConversionCrst);
DeleteCriticalSection(&gcsMPH);
}
/*********************************************************************** /***********************************************************************
* map_wparam_AtoW * map_wparam_AtoW
* *