3 #include <wine/debug.h>
4 WINE_DEFAULT_DEBUG_CHANNEL(user32
);
6 #define KEY_LENGTH 1024
8 static ULONG User32TlsIndex
;
9 HINSTANCE User32Instance
;
11 PPROCESSINFO g_ppi
= NULL
;
12 PUSER_HANDLE_TABLE gHandleTable
= NULL
;
13 PUSER_HANDLE_ENTRY gHandleEntries
= NULL
;
14 PSERVERINFO gpsi
= NULL
;
15 ULONG_PTR g_ulSharedDelta
;
16 BOOL gfServerProcess
= FALSE
;
18 WCHAR szAppInit
[KEY_LENGTH
];
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 for (i
= 0; i
< KEY_LENGTH
; ++ i
)
141 if(buffer
[i
] == L
' ' || buffer
[i
] == L
',')
145 for (i
= 0; i
< KEY_LENGTH
; )
162 if (szAppInit
[0] != UNICODE_NULL
)
164 WCHAR buffer
[KEY_LENGTH
];
169 RtlCopyMemory(buffer
, szAppInit
, KEY_LENGTH
);
171 for (i
= 0; i
< KEY_LENGTH
; ++ i
)
173 if(buffer
[i
] == L
' ' || buffer
[i
] == L
',')
177 for (i
= 0; i
< KEY_LENGTH
; )
185 hModule
= GetModuleHandleW(ptr
);
186 FreeLibrary(hModule
);
195 PUSER32_THREAD_DATA ThreadData
;
197 ThreadData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
198 sizeof(USER32_THREAD_DATA
));
199 if (ThreadData
== NULL
)
201 if (!TlsSetValue(User32TlsIndex
, ThreadData
))
209 PUSER32_THREAD_DATA ThreadData
;
211 ThreadData
= (PUSER32_THREAD_DATA
)TlsGetValue(User32TlsIndex
);
212 HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY
, ThreadData
);
213 TlsSetValue(User32TlsIndex
, 0);
221 /* Set up the kernel callbacks. */
222 NtCurrentPeb()->KernelCallbackTable
[USER32_CALLBACK_WINDOWPROC
] =
223 (PVOID
)User32CallWindowProcFromKernel
;
224 NtCurrentPeb()->KernelCallbackTable
[USER32_CALLBACK_SENDASYNCPROC
] =
225 (PVOID
)User32CallSendAsyncProcForKernel
;
226 NtCurrentPeb()->KernelCallbackTable
[USER32_CALLBACK_LOADSYSMENUTEMPLATE
] =
227 (PVOID
)User32LoadSysMenuTemplateForKernel
;
228 NtCurrentPeb()->KernelCallbackTable
[USER32_CALLBACK_LOADDEFAULTCURSORS
] =
229 (PVOID
)User32SetupDefaultCursors
;
230 NtCurrentPeb()->KernelCallbackTable
[USER32_CALLBACK_HOOKPROC
] =
231 (PVOID
)User32CallHookProcFromKernel
;
232 NtCurrentPeb()->KernelCallbackTable
[USER32_CALLBACK_EVENTPROC
] =
233 (PVOID
)User32CallEventProcFromKernel
;
234 NtCurrentPeb()->KernelCallbackTable
[USER32_CALLBACK_LOADMENU
] =
235 (PVOID
)User32CallLoadMenuFromKernel
;
236 NtCurrentPeb()->KernelCallbackTable
[USER32_CALLBACK_CLIENTTHREADSTARTUP
] =
237 (PVOID
)User32CallClientThreadSetupFromKernel
;
239 NtUserProcessConnect( NtCurrentProcess(),
241 sizeof(USERCONNECT
));
243 g_ppi
= GetWin32ClientInfo()->ppi
; // Snapshot PI, used as pointer only!
244 g_ulSharedDelta
= UserCon
.siClient
.ulSharedDelta
;
245 gpsi
= SharedPtrToUser(UserCon
.siClient
.psi
);
246 gHandleTable
= SharedPtrToUser(UserCon
.siClient
.aheList
);
247 gHandleEntries
= SharedPtrToUser(gHandleTable
->handles
);
249 RtlInitializeCriticalSection(&gcsUserApiHook
);
250 gfServerProcess
= TRUE
; // FIXME HAX! Used in CsrClientConnectToServer(,,,,&gfServerProcess);
252 //ERR("1 SI 0x%x : HT 0x%x : D 0x%x\n", UserCon.siClient.psi, UserCon.siClient.aheList, g_ulSharedDelta);
254 /* Allocate an index for user32 thread local data. */
255 User32TlsIndex
= TlsAlloc();
256 if (User32TlsIndex
!= TLS_OUT_OF_INDEXES
)
262 InitializeCriticalSection(&U32AccelCacheLock
);
263 GdiDllInitialize(NULL
, DLL_PROCESS_ATTACH
, NULL
);
271 TlsFree(User32TlsIndex
);
280 DeleteCriticalSection(&U32AccelCacheLock
);
283 DeleteFrameBrushes();
285 GdiDllInitialize(NULL
, DLL_PROCESS_DETACH
, NULL
);
286 TlsFree(User32TlsIndex
);
291 IN PVOID hInstanceDll
,
297 case DLL_PROCESS_ATTACH
:
298 User32Instance
= hInstanceDll
;
299 if (!RegisterClientPFN())
312 /* Initialize message spying */
313 if (!SPY_Init()) return FALSE
;
317 case DLL_THREAD_ATTACH
:
322 case DLL_THREAD_DETACH
:
326 case DLL_PROCESS_DETACH
:
327 if (hImmInstance
) FreeLibrary(hImmInstance
);
342 // ERR("GetConnected\n");
344 if ((PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
== NULL
)
345 NtUserGetThreadState(THREADSTATE_GETTHREADINFO
);
347 if (gpsi
&& g_ppi
) return;
348 // FIXME HAX: Due to the "Dll Initialization Bug" we have to call this too.
349 GdiDllInitialize(NULL
, DLL_PROCESS_ATTACH
, NULL
);
351 NtUserProcessConnect( NtCurrentProcess(),
353 sizeof(USERCONNECT
));
355 g_ppi
= GetWin32ClientInfo()->ppi
;
356 g_ulSharedDelta
= UserCon
.siClient
.ulSharedDelta
;
357 gpsi
= SharedPtrToUser(UserCon
.siClient
.psi
);
358 gHandleTable
= SharedPtrToUser(UserCon
.siClient
.aheList
);
359 gHandleEntries
= SharedPtrToUser(gHandleTable
->handles
);
365 User32CallClientThreadSetupFromKernel(PVOID Arguments
, ULONG ArgumentLength
)
367 ERR("GetConnected\n");
368 return ZwCallbackReturn(NULL
, 0, STATUS_SUCCESS
);