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