xref: /reactos/win32ss/gdi/gdi32/main/dllmain.c (revision c2c66aff)
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 */
119