b32f9f3ca0a8d0127e4cc5762704cb8e8701a5bb
[reactos.git] / reactos / lib / user32 / misc / dllmain.c
1 #include <user32.h>
2 #define NDEBUG
3 #include <debug.h>
4
5 /* FIXME: Belongs to some header. */
6 BOOL STDCALL GdiDllInitialize(HANDLE, DWORD, LPVOID);
7 void InitStockObjects(void);
8 VOID DeleteFrameBrushes(VOID);
9
10 extern CRITICAL_SECTION gcsMPH;
11 static ULONG User32TlsIndex;
12 HINSTANCE User32Instance;
13 HWINSTA ProcessWindowStation;
14
15 PUSER32_THREAD_DATA
16 User32GetThreadData()
17 {
18 return((PUSER32_THREAD_DATA)TlsGetValue(User32TlsIndex));
19 }
20
21 VOID
22 InitThread(VOID)
23 {
24 PUSER32_THREAD_DATA ThreadData;
25
26 ThreadData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
27 sizeof(USER32_THREAD_DATA));
28 TlsSetValue(User32TlsIndex, ThreadData);
29 }
30
31 VOID
32 CleanupThread(VOID)
33 {
34 PUSER32_THREAD_DATA ThreadData;
35
36 ThreadData = (PUSER32_THREAD_DATA)TlsGetValue(User32TlsIndex);
37 HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, ThreadData);
38 TlsSetValue(User32TlsIndex, 0);
39 }
40
41 VOID
42 Init(VOID)
43 {
44 /* Set up the kernel callbacks. */
45 NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_WINDOWPROC] =
46 (PVOID)User32CallWindowProcFromKernel;
47 NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_SENDASYNCPROC] =
48 (PVOID)User32CallSendAsyncProcForKernel;
49 NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_LOADSYSMENUTEMPLATE] =
50 (PVOID)User32LoadSysMenuTemplateForKernel;
51 NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_LOADDEFAULTCURSORS] =
52 (PVOID)User32SetupDefaultCursors;
53 NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_HOOKPROC] =
54 (PVOID)User32CallHookProcFromKernel;
55
56 /* Allocate an index for user32 thread local data. */
57 User32TlsIndex = TlsAlloc();
58
59 MenuInit();
60 MessageInit();
61
62 InitializeCriticalSection(&U32AccelCacheLock);
63 InitializeCriticalSection(&gcsMPH);
64
65 GdiDllInitialize(NULL, DLL_PROCESS_ATTACH, NULL);
66 InitStockObjects();
67 }
68
69 VOID
70 Cleanup(VOID)
71 {
72 GdiDllInitialize(NULL, DLL_PROCESS_DETACH, NULL);
73
74 TlsFree(User32TlsIndex);
75 }
76
77
78
79 INT STDCALL
80 DllMain(
81 PVOID hinstDll,
82 ULONG dwReason,
83 PVOID reserved
84 )
85 {
86 switch (dwReason)
87 {
88 case DLL_PROCESS_ATTACH:
89 User32Instance = hinstDll;
90 hProcessHeap = RtlGetProcessHeap();
91 Init();
92 InitThread();
93 break;
94 case DLL_THREAD_ATTACH:
95 InitThread();
96 break;
97 case DLL_THREAD_DETACH:
98 CleanupThread();
99 break;
100 case DLL_PROCESS_DETACH:
101 DeleteFrameBrushes();
102 CleanupThread();
103 Cleanup();
104 break;
105 }
106 return(1);
107 }