Fix the USER32 DLL initialization and cleanup routines to prevent memory/resource leaks and check for allocation errors.
Modified: trunk/reactos/lib/user32/include/menu.h
Modified: trunk/reactos/lib/user32/include/message.h
Modified: trunk/reactos/lib/user32/include/user32p.h
Modified: trunk/reactos/lib/user32/misc/dllmain.c
Modified: trunk/reactos/lib/user32/windows/menu.c
Modified: trunk/reactos/lib/user32/windows/message.c

Modified: trunk/reactos/lib/user32/include/menu.h
--- trunk/reactos/lib/user32/include/menu.h	2005-12-12 20:01:44 UTC (rev 20109)
+++ trunk/reactos/lib/user32/include/menu.h	2005-12-12 20:15:23 UTC (rev 20110)
@@ -13,6 +13,8 @@
 BOOL
 MenuInit(VOID);
 VOID
+MenuCleanup(VOID);
+VOID
 MenuTrackMouseMenuBar(HWND hWnd, ULONG Ht, POINT Pt);
 VOID
 MenuTrackKbdMenuBar(HWND hWnd, ULONG wParam, ULONG Key);

Modified: trunk/reactos/lib/user32/include/message.h
--- trunk/reactos/lib/user32/include/message.h	2005-12-12 20:01:44 UTC (rev 20109)
+++ trunk/reactos/lib/user32/include/message.h	2005-12-12 20:15:23 UTC (rev 20110)
@@ -10,5 +10,6 @@
 #define LIB_USER32_INCLUDE_MESSAGE_H
 
 BOOL FASTCALL MessageInit(VOID);
+VOID FASTCALL MessageCleanup(VOID);
 
 #endif /* LIB_USER32_INCLUDE_MESSAGE_H */

Modified: trunk/reactos/lib/user32/include/user32p.h
--- trunk/reactos/lib/user32/include/user32p.h	2005-12-12 20:01:44 UTC (rev 20109)
+++ trunk/reactos/lib/user32/include/user32p.h	2005-12-12 20:15:23 UTC (rev 20110)
@@ -127,5 +127,10 @@
 STDCALL
 GdiConvertToDevmodeW(DEVMODEA *dm);
 
+/* FIXME: Belongs to some header. */
+BOOL STDCALL GdiDllInitialize(HANDLE, DWORD, LPVOID);
+void InitStockObjects(void);
+VOID DeleteFrameBrushes(VOID);
+
 #endif
 /* EOF */

Modified: trunk/reactos/lib/user32/misc/dllmain.c
--- trunk/reactos/lib/user32/misc/dllmain.c	2005-12-12 20:01:44 UTC (rev 20109)
+++ trunk/reactos/lib/user32/misc/dllmain.c	2005-12-12 20:15:23 UTC (rev 20110)
@@ -2,106 +2,121 @@
 #define NDEBUG
 #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;
 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;
+   PUSER32_THREAD_DATA ThreadData;
 
-  ThreadData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-			 sizeof(USER32_THREAD_DATA));
-  TlsSetValue(User32TlsIndex, 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;
+   /* 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();
+   /* 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();
 
-  MenuInit();
-  MessageInit();
+            return TRUE;
+         }
+         MessageCleanup();
+      }
+      TlsFree(User32TlsIndex);
+   }
 
-  InitializeCriticalSection(&U32AccelCacheLock);
-  InitializeCriticalSection(&gcsMPH);
-
-  GdiDllInitialize(NULL, DLL_PROCESS_ATTACH, NULL);
-  InitStockObjects();
+   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;
 }

Modified: trunk/reactos/lib/user32/windows/menu.c
--- trunk/reactos/lib/user32/windows/menu.c	2005-12-12 20:01:44 UTC (rev 20109)
+++ trunk/reactos/lib/user32/windows/menu.c	2005-12-12 20:15:23 UTC (rev 20110)
@@ -1077,6 +1077,8 @@
     if(hMenuFontBold == NULL)
     {
       DbgPrint("MenuInit(): CreateFontIndirectW(hMenuFontBold) failed!\n");
+      DeleteObject(hMenuFont);
+      hMenuFont = NULL;
       return FALSE;
     }
   }
@@ -1085,6 +1087,24 @@
 }
 
 
+VOID
+MenuCleanup(VOID)
+{
+  if (hMenuFont)
+  {
+    DeleteObject(hMenuFont);
+    hMenuFont = NULL;
+  }
+
+  if (hMenuFontBold)
+  {
+    DeleteObject(hMenuFontBold);
+    hMenuFontBold = NULL;
+  }
+}
+
+
+
 /***********************************************************************
  *           MenuCalcItemSize
  *

Modified: trunk/reactos/lib/user32/windows/message.c
--- trunk/reactos/lib/user32/windows/message.c	2005-12-12 20:01:44 UTC (rev 20109)
+++ trunk/reactos/lib/user32/windows/message.c	2005-12-12 20:15:23 UTC (rev 20110)
@@ -2107,14 +2107,22 @@
 }
 
 
-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
  *