[WIN32K:NTUSER] Correctly delete menus in failure cases in MENU_GetSystemMenu. CORE...
[reactos.git] / win32ss / gdi / gdi32 / main / dllmain.c
1 /*
2 * dllmain.c
3 */
4
5 #include <precomp.h>
6
7 extern HGDIOBJ stock_objects[];
8 BOOL SetStockObjects = FALSE;
9 PDEVCAPS GdiDevCaps = NULL;
10 PGDIHANDLECACHE GdiHandleCache = NULL;
11 BOOL gbLpk = FALSE;
12 RTL_CRITICAL_SECTION semLocal;
13 extern CRITICAL_SECTION gcsClientObjLinks;
14
15 /*
16 * GDI32.DLL does have an entry point for disable threadlibrarycall,. The initialization is done by a call
17 * to GdiDllInitialize(). This call is done from the entry point of USER32.DLL.
18 */
19 BOOL
20 WINAPI
21 DllMain(
22 HANDLE hDll,
23 DWORD dwReason,
24 LPVOID lpReserved)
25 {
26 switch (dwReason)
27 {
28 case DLL_PROCESS_ATTACH :
29 DisableThreadLibraryCalls(hDll);
30 break;
31
32 default:
33 break;
34 }
35 return TRUE;
36 }
37
38
39 VOID
40 WINAPI
41 GdiProcessSetup(VOID)
42 {
43 hProcessHeap = GetProcessHeap();
44
45 /* map the gdi handle table to user space */
46 GdiHandleTable = NtCurrentTeb()->ProcessEnvironmentBlock->GdiSharedHandleTable;
47 GdiSharedHandleTable = NtCurrentTeb()->ProcessEnvironmentBlock->GdiSharedHandleTable;
48 GdiDevCaps = &GdiSharedHandleTable->DevCaps;
49 CurrentProcessId = NtCurrentTeb()->ClientId.UniqueProcess;
50 GDI_BatchLimit = (DWORD) NtCurrentTeb()->ProcessEnvironmentBlock->GdiDCAttributeList;
51 GdiHandleCache = (PGDIHANDLECACHE)NtCurrentTeb()->ProcessEnvironmentBlock->GdiHandleBuffer;
52 RtlInitializeCriticalSection(&semLocal);
53 InitializeCriticalSection(&gcsClientObjLinks);
54 }
55
56 VOID
57 WINAPI
58 GdiProcessShutdown(VOID)
59 {
60 DeleteCriticalSection(&gcsClientObjLinks);
61 RtlDeleteCriticalSection(&semLocal);
62 }
63
64
65 /*
66 * @implemented
67 */
68 BOOL
69 WINAPI
70 GdiDllInitialize(
71 HANDLE hDll,
72 DWORD dwReason,
73 LPVOID lpReserved)
74 {
75 switch (dwReason)
76 {
77 case DLL_PROCESS_ATTACH:
78 {
79 /* Don't bother us for each thread */
80 // DisableThreadLibraryCalls(hDll);
81
82 /* Initialize the kernel part of GDI first */
83 if (!NtGdiInit()) return FALSE;
84
85 /* Now initialize ourselves */
86 GdiProcessSetup();
87 break;
88 }
89
90 case DLL_THREAD_ATTACH:
91 {
92 NtCurrentTeb()->GdiTebBatch.Offset = 0;
93 NtCurrentTeb()->GdiBatchCount = 0;
94 break;
95 }
96
97 case DLL_PROCESS_DETACH:
98 {
99 /* Cleanup */
100 GdiProcessShutdown();
101 return TRUE;
102 }
103
104 default:
105 return FALSE;
106 }
107
108 /* Very simple, the list will fill itself as it is needed */
109 if (!SetStockObjects)
110 {
111 RtlZeroMemory(&stock_objects, NB_STOCK_OBJECTS); // Assume ROS is dirty
112 SetStockObjects = TRUE;
113 }
114
115 return TRUE;
116 }
117
118 /* EOF */