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 GdiInitializeLanguagePack(0); 55 } 56 57 VOID 58 WINAPI 59 GdiProcessShutdown(VOID) 60 { 61 DeleteCriticalSection(&gcsClientObjLinks); 62 RtlDeleteCriticalSection(&semLocal); 63 } 64 65 66 /* 67 * @implemented 68 */ 69 BOOL 70 WINAPI 71 GdiDllInitialize( 72 HANDLE hDll, 73 DWORD dwReason, 74 LPVOID lpReserved) 75 { 76 switch (dwReason) 77 { 78 case DLL_PROCESS_ATTACH: 79 { 80 /* Don't bother us for each thread */ 81 // DisableThreadLibraryCalls(hDll); 82 83 /* Initialize the kernel part of GDI first */ 84 if (!NtGdiInit()) return FALSE; 85 86 /* Now initialize ourselves */ 87 GdiProcessSetup(); 88 break; 89 } 90 91 case DLL_THREAD_ATTACH: 92 { 93 NtCurrentTeb()->GdiTebBatch.Offset = 0; 94 NtCurrentTeb()->GdiBatchCount = 0; 95 break; 96 } 97 98 case DLL_PROCESS_DETACH: 99 { 100 /* Cleanup */ 101 GdiProcessShutdown(); 102 return TRUE; 103 } 104 105 default: 106 return FALSE; 107 } 108 109 /* Very simple, the list will fill itself as it is needed */ 110 if (!SetStockObjects) 111 { 112 RtlZeroMemory(&stock_objects, NB_STOCK_OBJECTS); // Assume ROS is dirty 113 SetStockObjects = TRUE; 114 } 115 116 return TRUE; 117 } 118 119 /* EOF */ 120