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 BOOLEAN gfLogonProcess
= FALSE
;
17 BOOLEAN gfServerProcess
= FALSE
;
19 WCHAR szAppInit
[KEY_LENGTH
];
25 OBJECT_ATTRIBUTES Attributes
;
30 PKEY_VALUE_PARTIAL_INFORMATION kvpInfo
= NULL
;
32 UNICODE_STRING szKeyName
= RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows");
33 UNICODE_STRING szLoadName
= RTL_CONSTANT_STRING(L
"LoadAppInit_DLLs");
34 UNICODE_STRING szDllsName
= RTL_CONSTANT_STRING(L
"AppInit_DLLs");
36 InitializeObjectAttributes(&Attributes
, &szKeyName
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
37 Status
= NtOpenKey(&hKey
, KEY_READ
, &Attributes
);
38 if (NT_SUCCESS(Status
))
40 dwSize
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + sizeof(DWORD
);
41 kvpInfo
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
45 Status
= NtQueryValueKey(hKey
,
47 KeyValuePartialInformation
,
51 if (!NT_SUCCESS(Status
))
58 HeapFree(GetProcessHeap(), 0, kvpInfo
);
63 Status
= NtQueryValueKey(hKey
,
65 KeyValuePartialInformation
,
69 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
72 kvpInfo
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
76 Status
= NtQueryValueKey(hKey
,
78 KeyValuePartialInformation
,
82 if (NT_SUCCESS(Status
))
84 LPWSTR lpBuffer
= (LPWSTR
)kvpInfo
->Data
;
85 if (*lpBuffer
!= UNICODE_NULL
)
87 INT bytesToCopy
, nullPos
;
89 bytesToCopy
= min(kvpInfo
->DataLength
, KEY_LENGTH
* sizeof(WCHAR
));
93 RtlMoveMemory(szAppInit
,
97 nullPos
= (bytesToCopy
/ sizeof(WCHAR
)) - 1;
99 /* ensure string is terminated */
100 szAppInit
[nullPos
] = UNICODE_NULL
;
114 HeapFree(GetProcessHeap(), 0, kvpInfo
);
123 szAppInit
[0] = UNICODE_NULL
;
127 WCHAR buffer
[KEY_LENGTH
];
131 RtlCopyMemory(buffer
, szAppInit
, KEY_LENGTH
);
133 for (i
= 0; i
< KEY_LENGTH
; ++ i
)
135 if(buffer
[i
] == L
' ' || buffer
[i
] == L
',')
139 for (i
= 0; i
< KEY_LENGTH
; )
156 if (szAppInit
[0] != UNICODE_NULL
)
158 WCHAR buffer
[KEY_LENGTH
];
163 RtlCopyMemory(buffer
, szAppInit
, KEY_LENGTH
* sizeof(WCHAR
));
165 for (i
= 0; i
< KEY_LENGTH
; ++ i
)
167 if(buffer
[i
] == L
' ' || buffer
[i
] == L
',')
171 for (i
= 0; i
< KEY_LENGTH
; )
179 hModule
= GetModuleHandleW(ptr
);
180 FreeLibrary(hModule
);
201 PVOID
*KernelCallbackTable
;
203 /* Set up the kernel callbacks. */
204 KernelCallbackTable
= NtCurrentPeb()->KernelCallbackTable
;
205 KernelCallbackTable
[USER32_CALLBACK_WINDOWPROC
] =
206 (PVOID
)User32CallWindowProcFromKernel
;
207 KernelCallbackTable
[USER32_CALLBACK_SENDASYNCPROC
] =
208 (PVOID
)User32CallSendAsyncProcForKernel
;
209 KernelCallbackTable
[USER32_CALLBACK_LOADSYSMENUTEMPLATE
] =
210 (PVOID
)User32LoadSysMenuTemplateForKernel
;
211 KernelCallbackTable
[USER32_CALLBACK_LOADDEFAULTCURSORS
] =
212 (PVOID
)User32SetupDefaultCursors
;
213 KernelCallbackTable
[USER32_CALLBACK_HOOKPROC
] =
214 (PVOID
)User32CallHookProcFromKernel
;
215 KernelCallbackTable
[USER32_CALLBACK_EVENTPROC
] =
216 (PVOID
)User32CallEventProcFromKernel
;
217 KernelCallbackTable
[USER32_CALLBACK_LOADMENU
] =
218 (PVOID
)User32CallLoadMenuFromKernel
;
219 KernelCallbackTable
[USER32_CALLBACK_CLIENTTHREADSTARTUP
] =
220 (PVOID
)User32CallClientThreadSetupFromKernel
;
221 KernelCallbackTable
[USER32_CALLBACK_CLIENTLOADLIBRARY
] =
222 (PVOID
)User32CallClientLoadLibraryFromKernel
;
223 KernelCallbackTable
[USER32_CALLBACK_GETCHARSETINFO
] =
224 (PVOID
)User32CallGetCharsetInfo
;
226 NtUserProcessConnect( NtCurrentProcess(),
228 sizeof(USERCONNECT
));
230 g_ppi
= GetWin32ClientInfo()->ppi
; // Snapshot PI, used as pointer only!
231 g_ulSharedDelta
= UserCon
.siClient
.ulSharedDelta
;
232 gpsi
= SharedPtrToUser(UserCon
.siClient
.psi
);
233 gHandleTable
= SharedPtrToUser(UserCon
.siClient
.aheList
);
234 gHandleEntries
= SharedPtrToUser(gHandleTable
->handles
);
236 RtlInitializeCriticalSection(&gcsUserApiHook
);
237 gfServerProcess
= FALSE
; // FIXME HAX! Used in CsrClientConnectToServer(,,,,&gfServerProcess);
239 //CsrClientConnectToServer(L"\\Windows", 0, NULL, 0, &gfServerProcess);
240 //ERR("1 SI 0x%x : HT 0x%x : D 0x%x\n", UserCon.siClient.psi, UserCon.siClient.aheList, g_ulSharedDelta);
242 /* Allocate an index for user32 thread local data. */
243 User32TlsIndex
= TlsAlloc();
244 if (User32TlsIndex
!= TLS_OUT_OF_INDEXES
)
250 InitializeCriticalSection(&U32AccelCacheLock
);
251 GdiDllInitialize(NULL
, DLL_PROCESS_ATTACH
, NULL
);
258 TlsFree(User32TlsIndex
);
267 DeleteCriticalSection(&U32AccelCacheLock
);
270 DeleteFrameBrushes();
272 GdiDllInitialize(NULL
, DLL_PROCESS_DETACH
, NULL
);
273 TlsFree(User32TlsIndex
);
278 IN PVOID hInstanceDll
,
284 case DLL_PROCESS_ATTACH
:
285 User32Instance
= hInstanceDll
;
286 if (!RegisterClientPFN())
299 /* Initialize message spying */
300 if (!SPY_Init()) return FALSE
;
304 case DLL_THREAD_ATTACH
:
309 case DLL_THREAD_DETACH
:
313 case DLL_PROCESS_DETACH
:
314 if (hImmInstance
) FreeLibrary(hImmInstance
);
329 // ERR("GetConnected\n");
331 if ((PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
== NULL
)
332 NtUserGetThreadState(THREADSTATE_GETTHREADINFO
);
334 if (gpsi
&& g_ppi
) return;
335 // FIXME HAX: Due to the "Dll Initialization Bug" we have to call this too.
336 GdiDllInitialize(NULL
, DLL_PROCESS_ATTACH
, NULL
);
338 NtUserProcessConnect( NtCurrentProcess(),
340 sizeof(USERCONNECT
));
342 g_ppi
= GetWin32ClientInfo()->ppi
;
343 g_ulSharedDelta
= UserCon
.siClient
.ulSharedDelta
;
344 gpsi
= SharedPtrToUser(UserCon
.siClient
.psi
);
345 gHandleTable
= SharedPtrToUser(UserCon
.siClient
.aheList
);
346 gHandleEntries
= SharedPtrToUser(gHandleTable
->handles
);
352 User32CallClientThreadSetupFromKernel(PVOID Arguments
, ULONG ArgumentLength
)
354 ERR("GetConnected\n");
355 return ZwCallbackReturn(NULL
, 0, STATUS_SUCCESS
);
360 User32CallGetCharsetInfo(PVOID Arguments
, ULONG ArgumentLength
)
363 PGET_CHARSET_INFO pgci
= (PGET_CHARSET_INFO
)Arguments
;
365 TRACE("GetCharsetInfo\n");
367 Ret
= TranslateCharsetInfo((DWORD
*)pgci
->Locale
, &pgci
->Cs
, TCI_SRCLOCALE
);
369 return ZwCallbackReturn(Arguments
, ArgumentLength
, Ret
? STATUS_SUCCESS
: STATUS_UNSUCCESSFUL
);