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