[WIN32K:NTUSER] Correctly delete menus in failure cases in MENU_GetSystemMenu. CORE...
[reactos.git] / win32ss / gdi / gdi32 / main / dllmain.c
index c3a42a6..0e34df2 100644 (file)
@@ -10,6 +10,7 @@ PDEVCAPS GdiDevCaps = NULL;
 PGDIHANDLECACHE GdiHandleCache = NULL;
 BOOL gbLpk = FALSE;
 RTL_CRITICAL_SECTION semLocal;
+extern CRITICAL_SECTION gcsClientObjLinks;
 
 /*
  * GDI32.DLL does have an entry point for disable threadlibrarycall,. The initialization is done by a call
@@ -17,7 +18,7 @@ RTL_CRITICAL_SECTION semLocal;
  */
 BOOL
 WINAPI
-DllMain (
+DllMain(
     HANDLE  hDll,
     DWORD   dwReason,
     LPVOID  lpReserved)
@@ -37,7 +38,7 @@ DllMain (
 
 VOID
 WINAPI
-GdiProcessSetup (VOID)
+GdiProcessSetup(VOID)
 {
     hProcessHeap = GetProcessHeap();
 
@@ -49,6 +50,15 @@ GdiProcessSetup (VOID)
     GDI_BatchLimit = (DWORD) NtCurrentTeb()->ProcessEnvironmentBlock->GdiDCAttributeList;
     GdiHandleCache = (PGDIHANDLECACHE)NtCurrentTeb()->ProcessEnvironmentBlock->GdiHandleBuffer;
     RtlInitializeCriticalSection(&semLocal);
+    InitializeCriticalSection(&gcsClientObjLinks);
+}
+
+VOID
+WINAPI
+GdiProcessShutdown(VOID)
+{
+    DeleteCriticalSection(&gcsClientObjLinks);
+    RtlDeleteCriticalSection(&semLocal);
 }
 
 
@@ -57,30 +67,48 @@ GdiProcessSetup (VOID)
  */
 BOOL
 WINAPI
-GdiDllInitialize (
+GdiDllInitialize(
     HANDLE hDll,
     DWORD dwReason,
     LPVOID lpReserved)
 {
     switch (dwReason)
     {
-    case DLL_PROCESS_ATTACH:
-        GdiProcessSetup ();
-        break;
+        case DLL_PROCESS_ATTACH:
+        {
+            /* Don't bother us for each thread */
+            // DisableThreadLibraryCalls(hDll);
 
-    case DLL_THREAD_ATTACH:
-        NtCurrentTeb()->GdiTebBatch.Offset = 0;
-        NtCurrentTeb()->GdiBatchCount = 0;
-        break;
+            /* Initialize the kernel part of GDI first */
+            if (!NtGdiInit()) return FALSE;
 
-    default:
-        return FALSE;
+            /* Now initialize ourselves */
+            GdiProcessSetup();
+            break;
+        }
+
+        case DLL_THREAD_ATTACH:
+        {
+            NtCurrentTeb()->GdiTebBatch.Offset = 0;
+            NtCurrentTeb()->GdiBatchCount = 0;
+            break;
+        }
+
+        case DLL_PROCESS_DETACH:
+        {
+            /* Cleanup */
+            GdiProcessShutdown();
+            return TRUE;
+        }
+
+        default:
+            return FALSE;
     }
 
-    // Very simple, the list will fill itself as it is needed.
-    if(!SetStockObjects)
+    /* Very simple, the list will fill itself as it is needed */
+    if (!SetStockObjects)
     {
-        RtlZeroMemory( &stock_objects, NB_STOCK_OBJECTS); //Assume Ros is dirty.
+        RtlZeroMemory(&stock_objects, NB_STOCK_OBJECTS); // Assume ROS is dirty
         SetStockObjects = TRUE;
     }