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