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