3 #include <wine/debug.h>
4 WINE_DEFAULT_DEBUG_CHANNEL(user32
);
6 #define KEY_LENGTH 1024
8 static ULONG User32TlsIndex
;
9 HINSTANCE User32Instance
;
10 PUSER_HANDLE_TABLE gHandleTable
= NULL
;
11 PUSER_HANDLE_ENTRY gHandleEntries
= NULL
;
12 PW32PROCESSINFO g_pi
= NULL
; /* User Mode Pointer */
13 PW32PROCESSINFO g_kpi
= NULL
; /* Kernel Mode Pointer */
14 PSERVERINFO g_psi
= NULL
;
15 WCHAR szAppInit
[KEY_LENGTH
];
18 GetW32ProcessInfo(VOID
);
23 return ((PUSER32_THREAD_DATA
)TlsGetValue(User32TlsIndex
));
31 OBJECT_ATTRIBUTES Attributes
;
36 PKEY_VALUE_PARTIAL_INFORMATION kvpInfo
= NULL
;
38 UNICODE_STRING szKeyName
= RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows");
39 UNICODE_STRING szLoadName
= RTL_CONSTANT_STRING(L
"LoadAppInit_DLLs");
40 UNICODE_STRING szDllsName
= RTL_CONSTANT_STRING(L
"AppInit_DLLs");
42 InitializeObjectAttributes(&Attributes
, &szKeyName
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
43 Status
= NtOpenKey(&hKey
, KEY_READ
, &Attributes
);
44 if (NT_SUCCESS(Status
))
46 dwSize
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + sizeof(DWORD
);
47 kvpInfo
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
51 Status
= NtQueryValueKey(hKey
,
53 KeyValuePartialInformation
,
57 if (!NT_SUCCESS(Status
))
64 HeapFree(GetProcessHeap(), 0, kvpInfo
);
69 Status
= NtQueryValueKey(hKey
,
71 KeyValuePartialInformation
,
75 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
78 kvpInfo
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
82 Status
= NtQueryValueKey(hKey
,
84 KeyValuePartialInformation
,
88 if (NT_SUCCESS(Status
))
90 LPWSTR lpBuffer
= (LPWSTR
)kvpInfo
->Data
;
91 if (*lpBuffer
!= UNICODE_NULL
)
93 INT bytesToCopy
, nullPos
;
95 bytesToCopy
= min(kvpInfo
->DataLength
, KEY_LENGTH
* sizeof(WCHAR
));
99 RtlMoveMemory(szAppInit
,
103 nullPos
= (bytesToCopy
/ sizeof(WCHAR
)) - 1;
105 /* ensure string is terminated */
106 szAppInit
[nullPos
] = UNICODE_NULL
;
120 HeapFree(GetProcessHeap(), 0, kvpInfo
);
129 szAppInit
[0] = UNICODE_NULL
;
133 WCHAR buffer
[KEY_LENGTH
];
137 RtlCopyMemory(buffer
, szAppInit
, KEY_LENGTH
);;
139 ptr
= wcstok(buffer
, seps
);
143 ptr
= wcstok(NULL
, seps
);
151 if (szAppInit
[0] != UNICODE_NULL
)
153 WCHAR buffer
[KEY_LENGTH
];
158 RtlCopyMemory(buffer
, szAppInit
, KEY_LENGTH
);
160 ptr
= wcstok(buffer
, seps
);
163 hModule
= GetModuleHandleW(ptr
);
164 FreeLibrary(hModule
);
165 ptr
= wcstok(NULL
, seps
);
173 PUSER32_THREAD_DATA ThreadData
;
175 ThreadData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
176 sizeof(USER32_THREAD_DATA
));
177 if (ThreadData
== NULL
)
179 if (!TlsSetValue(User32TlsIndex
, ThreadData
))
187 PUSER32_THREAD_DATA ThreadData
;
189 ThreadData
= (PUSER32_THREAD_DATA
)TlsGetValue(User32TlsIndex
);
190 HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY
, ThreadData
);
191 TlsSetValue(User32TlsIndex
, 0);
197 /* Set up the kernel callbacks. */
198 NtCurrentTeb()->ProcessEnvironmentBlock
->KernelCallbackTable
[USER32_CALLBACK_WINDOWPROC
] =
199 (PVOID
)User32CallWindowProcFromKernel
;
200 NtCurrentTeb()->ProcessEnvironmentBlock
->KernelCallbackTable
[USER32_CALLBACK_SENDASYNCPROC
] =
201 (PVOID
)User32CallSendAsyncProcForKernel
;
202 NtCurrentTeb()->ProcessEnvironmentBlock
->KernelCallbackTable
[USER32_CALLBACK_LOADSYSMENUTEMPLATE
] =
203 (PVOID
)User32LoadSysMenuTemplateForKernel
;
204 NtCurrentTeb()->ProcessEnvironmentBlock
->KernelCallbackTable
[USER32_CALLBACK_LOADDEFAULTCURSORS
] =
205 (PVOID
)User32SetupDefaultCursors
;
206 NtCurrentTeb()->ProcessEnvironmentBlock
->KernelCallbackTable
[USER32_CALLBACK_HOOKPROC
] =
207 (PVOID
)User32CallHookProcFromKernel
;
208 NtCurrentTeb()->ProcessEnvironmentBlock
->KernelCallbackTable
[USER32_CALLBACK_EVENTPROC
] =
209 (PVOID
)User32CallEventProcFromKernel
;
211 g_pi
= GetW32ProcessInfo();
212 g_kpi
= SharedPtrToKernel(g_pi
);
213 g_psi
= SharedPtrToUser(g_pi
->psi
);
214 gHandleTable
= SharedPtrToUser(g_pi
->UserHandleTable
);
215 gHandleEntries
= SharedPtrToUser(gHandleTable
->handles
);
217 /* Allocate an index for user32 thread local data. */
218 User32TlsIndex
= TlsAlloc();
219 if (User32TlsIndex
!= TLS_OUT_OF_INDEXES
)
225 InitializeCriticalSection(&U32AccelCacheLock
);
226 GdiDllInitialize(NULL
, DLL_PROCESS_ATTACH
, NULL
);
234 TlsFree(User32TlsIndex
);
243 DeleteCriticalSection(&U32AccelCacheLock
);
246 DeleteFrameBrushes();
248 GdiDllInitialize(NULL
, DLL_PROCESS_DETACH
, NULL
);
249 TlsFree(User32TlsIndex
);
254 IN PVOID hInstanceDll
,
260 case DLL_PROCESS_ATTACH
:
261 User32Instance
= hInstanceDll
;
262 if (!NtUserRegisterUserModule(hInstanceDll
) ||
263 !RegisterSystemControls())
276 /* Initialize message spying */
277 if (!SPY_Init()) return FALSE
;
281 case DLL_THREAD_ATTACH
:
286 case DLL_THREAD_DETACH
:
290 case DLL_PROCESS_DETACH
:
306 if ((PW32THREADINFO
)NtCurrentTeb()->Win32ThreadInfo
== NULL
)
307 NtUserGetThreadState(THREADSTATE_GETTHREADINFO
);
309 if (g_pi
&& g_kpi
&& g_psi
) return;
311 pi
= GetW32ProcessInfo();
312 if (!g_pi
) g_pi
= pi
;
313 if (!g_kpi
) g_kpi
= SharedPtrToKernel(pi
);
314 if (!g_psi
) g_psi
= SharedPtrToUser(pi
->psi
);
315 if (!g_psi
) { WARN("Global Share Information has not been initialized!\n"); }
316 if (!gHandleTable
) gHandleTable
= SharedPtrToUser(pi
->UserHandleTable
);
317 if (!gHandleEntries
) gHandleEntries
= SharedPtrToUser(gHandleTable
->handles
);