7 extern HGDIOBJ stock_objects
[];
8 BOOL SetStockObjects
= FALSE
;
9 PDEVCAPS GdiDevCaps
= NULL
;
10 PGDIHANDLECACHE GdiHandleCache
= NULL
;
12 RTL_CRITICAL_SECTION semLocal
;
13 extern CRITICAL_SECTION gcsClientObjLinks
;
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.
28 case DLL_PROCESS_ATTACH
:
29 DisableThreadLibraryCalls(hDll
);
43 hProcessHeap
= GetProcessHeap();
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
);
58 GdiProcessShutdown(VOID
)
60 DeleteCriticalSection(&gcsClientObjLinks
);
61 RtlDeleteCriticalSection(&semLocal
);
77 case DLL_PROCESS_ATTACH
:
79 /* Don't bother us for each thread */
80 // DisableThreadLibraryCalls(hDll);
82 /* Initialize the kernel part of GDI first */
83 if (!NtGdiInit()) return FALSE
;
85 /* Now initialize ourselves */
90 case DLL_THREAD_ATTACH
:
92 NtCurrentTeb()->GdiTebBatch
.Offset
= 0;
93 NtCurrentTeb()->GdiBatchCount
= 0;
97 case DLL_PROCESS_DETACH
:
100 GdiProcessShutdown();
108 /* Very simple, the list will fill itself as it is needed */
109 if (!SetStockObjects
)
111 RtlZeroMemory(&stock_objects
, NB_STOCK_OBJECTS
); // Assume ROS is dirty
112 SetStockObjects
= TRUE
;