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