diff --git a/reactos/dll/win32/user32/include/user32p.h b/reactos/dll/win32/user32/include/user32p.h index 182068413f1..4dec7cbd1f4 100644 --- a/reactos/dll/win32/user32/include/user32p.h +++ b/reactos/dll/win32/user32/include/user32p.h @@ -76,6 +76,9 @@ #define NtUserSetCaretBlinkTime(uMSeconds) \ (BOOL)NtUserCallOneParam((DWORD)uMSeconds, ONEPARAM_ROUTINE_SETCARETBLINKTIME) +#define NtUserRegisterUserModule(hInstance) \ + (BOOL)NtUserCallOneParam((DWORD)hInstance, ONEPARAM_ROUTINE_REGISTERUSERMODULE) + /* #define NtUserEnumClipboardFormats(format) \ (UINT)NtUserCallOneParam(format, ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS) diff --git a/reactos/dll/win32/user32/misc/dllmain.c b/reactos/dll/win32/user32/misc/dllmain.c index 41b40d88438..f37b36b66e9 100644 --- a/reactos/dll/win32/user32/misc/dllmain.c +++ b/reactos/dll/win32/user32/misc/dllmain.c @@ -93,6 +93,9 @@ DllMain( { case DLL_PROCESS_ATTACH: User32Instance = hInstanceDll; + if (!NtUserRegisterUserModule(hInstanceDll)) + return FALSE; + hProcessHeap = RtlGetProcessHeap(); if (!Init()) return FALSE; diff --git a/reactos/include/reactos/win32k/ntuser.h b/reactos/include/reactos/win32k/ntuser.h index 150d8c94ae5..ed7c1f2118f 100644 --- a/reactos/include/reactos/win32k/ntuser.h +++ b/reactos/include/reactos/win32k/ntuser.h @@ -60,6 +60,7 @@ typedef struct _WINDOWCLASS typedef struct _W32PROCESSINFO { PVOID UserHandleTable; + HINSTANCE hModUser; PWINDOWCLASS LocalClassList; PWINDOWCLASS GlobalClassList; PWINDOWCLASS SystemClassList; @@ -458,7 +459,8 @@ NtUserCallNoParam( #define ONEPARAM_ROUTINE_MSQSETWAKEMASK 0x27 #define ONEPARAM_ROUTINE_GETKEYBOARDTYPE 0x28 #define ONEPARAM_ROUTINE_GETKEYBOARDLAYOUT 0x29 -#define ONEPARAM_ROUTINE_SHOWCURSOR 0x30 +#define ONEPARAM_ROUTINE_SHOWCURSOR 0x30 +#define ONEPARAM_ROUTINE_REGISTERUSERMODULE 0x31 DWORD NTAPI NtUserCallOneParam( diff --git a/reactos/subsystems/win32/win32k/ntuser/class.c b/reactos/subsystems/win32/win32k/ntuser/class.c index 9ade435dec3..41ecd39255b 100644 --- a/reactos/subsystems/win32/win32k/ntuser/class.c +++ b/reactos/subsystems/win32/win32k/ntuser/class.c @@ -592,7 +592,7 @@ IntDereferenceClass(IN OUT PWINDOWCLASS Class, while (*PrevLink != BaseClass) { - ASSERT(BaseClass != NULL); + ASSERT(*PrevLink != NULL); PrevLink = &BaseClass->Next; } @@ -1112,7 +1112,27 @@ IntGetClassAtom(IN PUNICODE_STRING ClassName, goto FoundClass; } - /* Step 3: try to find a system class */ + /* Step 3: try to find any local class registered by user32 */ + Class = IntFindClass(Atom, + pi->hModUser, + &pi->LocalClassList, + Link); + if (Class != NULL) + { + goto FoundClass; + } + + /* Step 4: try to find any global class registered by user32 */ + Class = IntFindClass(Atom, + pi->hModUser, + &pi->GlobalClassList, + Link); + if (Class != NULL) + { + goto FoundClass; + } + + /* Step 5: try to find a system class */ Class = IntFindClass(Atom, NULL, &pi->SystemClassList, @@ -1771,10 +1791,13 @@ UserGetClassInfo(IN PWINDOWCLASS Class, IN BOOL Ansi, HINSTANCE hInstance) { + PW32PROCESSINFO pi; + lpwcx->style = Class->Style; + pi = GetW32ProcessInfo(); lpwcx->lpfnWndProc = IntGetClassWndProc(Class, - GetW32ProcessInfo(), + pi, Ansi, FALSE); @@ -1789,9 +1812,7 @@ UserGetClassInfo(IN PWINDOWCLASS Class, else lpwcx->lpszMenuName = Class->MenuName; - if (hInstance) - lpwcx->hInstance = hInstance; - else if (Class->Global) + if (Class->hInstance == pi->hModUser) lpwcx->hInstance = NULL; else lpwcx->hInstance = Class->hInstance; @@ -2119,7 +2140,7 @@ NtUserGetClassInfo( /* probe the paramters */ CapturedClassName = ProbeForReadUnicodeString(ClassName); - if (IS_ATOM(CapturedClassName.Buffer)) + if (CapturedClassName.Length == 0) TRACE("hInst %p atom %04X lpWndClassEx %p Ansi %d\n", hInstance, CapturedClassName.Buffer, lpWndClassEx, Ansi); else TRACE("hInst %p class %wZ lpWndClassEx %p Ansi %d\n", hInstance, &CapturedClassName, lpWndClassEx, Ansi); @@ -2162,6 +2183,9 @@ InvalidParameter: NULL); if (ClassAtom != (RTL_ATOM)0) { + if (hInstance == NULL) + hInstance = pi->hModUser; + Ret = UserGetClassInfo(Class, lpWndClassEx, Ansi, @@ -2186,7 +2210,10 @@ InvalidParameter: if (!(Class->Global || Class->System) && hInstance == NULL) { - WARN("Tried to get information of a non-existing class\n"); + if (CapturedClassName.Length == 0) + WARN("Tried to get information of a non-existing class atom 0x%p\n", CapturedClassName.Buffer); + else + WARN("Tried to get information of a non-existing class \"%wZ\"\n", &CapturedClassName); SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST); Ret = FALSE; } @@ -2194,7 +2221,10 @@ InvalidParameter: } else { - WARN("Tried to get information of a non-existing class\n"); + if (CapturedClassName.Length == 0) + WARN("Tried to get information of a non-existing class atom 0x%p\n", CapturedClassName.Buffer); + else + WARN("Tried to get information of a non-existing class \"%wZ\"\n", &CapturedClassName); SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST); } } diff --git a/reactos/subsystems/win32/win32k/ntuser/misc.c b/reactos/subsystems/win32/win32k/ntuser/misc.c index 019d61104be..38cf5d0bb83 100644 --- a/reactos/subsystems/win32/win32k/ntuser/misc.c +++ b/reactos/subsystems/win32/win32k/ntuser/misc.c @@ -407,6 +407,26 @@ NtUserCallOneParam( case ONEPARAM_ROUTINE_GETKEYBOARDLAYOUT: RETURN( (DWORD)UserGetKeyboardLayout(Param)); + + case ONEPARAM_ROUTINE_REGISTERUSERMODULE: + { + PW32THREADINFO ti; + + ti = GetW32ThreadInfo(); + if (ti == NULL) + { + DPRINT1("Cannot register user32 module instance!\n"); + SetLastWin32Error(ERROR_INVALID_PARAMETER); + RETURN(FALSE); + } + + if (InterlockedCompareExchangePointer(&ti->kpi->hModUser, + (HINSTANCE)Param, + NULL) == NULL) + { + RETURN(TRUE); + } + } } DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n", Routine, Param);