Author: weiden
Date: Fri Nov 16 10:12:59 2007
New Revision: 30492
URL:
http://svn.reactos.org/svn/reactos?rev=30492&view=rev
Log:
Make registration of system window classes a bit more robust
Modified:
trunk/reactos/dll/win32/user32/controls/regcontrol.c
trunk/reactos/dll/win32/user32/include/regcontrol.h
trunk/reactos/dll/win32/user32/include/user32p.h
trunk/reactos/dll/win32/user32/misc/dllmain.c
trunk/reactos/dll/win32/user32/windows/class.c
trunk/reactos/dll/win32/user32/windows/window.c
trunk/reactos/include/reactos/win32k/ntuser.h
trunk/reactos/subsystems/win32/win32k/include/class.h
trunk/reactos/subsystems/win32/win32k/ntuser/class.c
trunk/reactos/subsystems/win32/win32k/ntuser/misc.c
Modified: trunk/reactos/dll/win32/user32/controls/regcontrol.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/controls/…
==============================================================================
--- trunk/reactos/dll/win32/user32/controls/regcontrol.c (original)
+++ trunk/reactos/dll/win32/user32/controls/regcontrol.c Fri Nov 16 10:12:59 2007
@@ -13,110 +13,51 @@
#include <wine/debug.h>
-static void RegisterBuiltinClass(const struct builtin_class_descr *Descr)
+static const struct
{
- WNDCLASSEXW wc;
- UNICODE_STRING ClassName;
- UNICODE_STRING MenuName;
+ const struct builtin_class_descr *desc;
+ UINT ClsId;
+} g_SysClasses[] =
+{
+ { &DIALOG_builtin_class, CLASS_DIALOG },
+ { &POPUPMENU_builtin_class, CLASS_POPUPMENU },
+ { &COMBO_builtin_class, CLASS_COMBO },
+ { &COMBOLBOX_builtin_class, CLASS_COMBOLBOX },
+ { &DESKTOP_builtin_class, CLASS_DESKTOP },
+ { &MDICLIENT_builtin_class, CLASS_MDICLIENT },
+#if 0
+ { &MENU_builtin_class, CLASS_MENU },
+#endif
+ { &SCROLL_builtin_class, CLASS_SCROLL },
+ { &BUTTON_builtin_class, CLASS_BUTTON },
+ { &LISTBOX_builtin_class, CLASS_LISTBOX },
+ { &EDIT_builtin_class, CLASS_EDIT },
+ { &ICONTITLE_builtin_class, CLASS_ICONTITLE },
+ { &STATIC_builtin_class, CLASS_STATIC },
+};
- wc.cbSize = sizeof(WNDCLASSEXW);
- wc.lpszClassName = Descr->name;
- wc.lpfnWndProc = Descr->procW;
- wc.style = Descr->style;
- wc.hInstance = User32Instance;
- wc.hIcon = NULL;
- wc.hIconSm = NULL;
- wc.hCursor = LoadCursorW(NULL, Descr->cursor);
- wc.hbrBackground = Descr->brush;
- wc.lpszMenuName = NULL;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = Descr->extra;
+BOOL WINAPI RegisterSystemControls(VOID)
+{
+ REGISTER_SYSCLASS cls[sizeof(g_SysClasses) / sizeof(g_SysClasses[0])];
+ UINT i;
- MenuName.Length =
- MenuName.MaximumLength = 0;
- MenuName.Buffer = NULL;
+ ZeroMemory(cls, sizeof(cls));
- if (IS_ATOM(Descr->name))
- {
- ClassName.Length =
- ClassName.MaximumLength = 0;
- ClassName.Buffer = (LPWSTR)Descr->name;
- } else
- {
- RtlInitUnicodeString(&ClassName, Descr->name);
- }
+ for (i = 0; i != sizeof(cls) / sizeof(cls[0]); i++)
+ {
+ if (IS_ATOM(g_SysClasses[i].desc->name))
+ cls[i].ClassName.Buffer = (PWSTR)((ULONG_PTR)g_SysClasses[i].desc->name);
+ else
+ RtlInitUnicodeString(&cls[i].ClassName, g_SysClasses[i].desc->name);
- NtUserRegisterClassEx(
- &wc,
- &ClassName,
- &MenuName,
- Descr->procA,
- REGISTERCLASS_SYSTEM,
- NULL);
-}
-
-/***********************************************************************
- * ControlsInit
- *
- * Register the classes for the builtin controls
- */
-BOOL FASTCALL
-ControlsInit(LPCWSTR ClassName)
-{
- static const struct builtin_class_descr *ClassDescriptions[] =
- {
- &DIALOG_builtin_class,
- &POPUPMENU_builtin_class,
- &COMBO_builtin_class,
- &COMBOLBOX_builtin_class,
- &DESKTOP_builtin_class,
- &MDICLIENT_builtin_class,
-#if 0
- &MENU_builtin_class,
-#endif
- &SCROLL_builtin_class,
- &BUTTON_builtin_class,
- &LISTBOX_builtin_class,
- &EDIT_builtin_class,
- &ICONTITLE_builtin_class,
- &STATIC_builtin_class
- };
- unsigned i;
- BOOL Register;
-
- Register = FALSE;
- if (IS_ATOM(ClassName))
- {
- for (i = 0;
- ! Register && i < sizeof(ClassDescriptions) /
sizeof(ClassDescriptions[0]);
- i++)
- {
- if (IS_ATOM(ClassDescriptions[i]->name))
- {
- Register = (ClassName == ClassDescriptions[i]->name);
- }
- }
- }
- else
- {
- for (i = 0;
- ! Register && i < sizeof(ClassDescriptions) /
sizeof(ClassDescriptions[0]);
- i++)
- {
- if (! IS_ATOM(ClassDescriptions[i]->name))
- {
- Register = (0 == _wcsicmp(ClassName, ClassDescriptions[i]->name));
- }
- }
+ cls[i].Style = g_SysClasses[i].desc->style;
+ cls[i].ProcW = g_SysClasses[i].desc->procW;
+ cls[i].ProcA = g_SysClasses[i].desc->procA;
+ cls[i].ExtraBytes = g_SysClasses[i].desc->extra;
+ cls[i].hCursor = LoadCursorW(NULL, g_SysClasses[i].desc->cursor);
+ cls[i].hBrush = g_SysClasses[i].desc->brush;
+ cls[i].ClassId = g_SysClasses[i].ClsId;
}
- if (Register)
- {
- for (i = 0; i < sizeof(ClassDescriptions) / sizeof(ClassDescriptions[0]); i++)
- {
- RegisterBuiltinClass(ClassDescriptions[i]);
- }
- }
-
- return Register;
+ return NtUserRegisterSystemClasses(sizeof(cls) / sizeof(cls[0]), cls);
}
Modified: trunk/reactos/dll/win32/user32/include/regcontrol.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/include/r…
==============================================================================
--- trunk/reactos/dll/win32/user32/include/regcontrol.h (original)
+++ trunk/reactos/dll/win32/user32/include/regcontrol.h Fri Nov 16 10:12:59 2007
@@ -26,7 +26,7 @@
HBRUSH brush; /* brush or system color */
};
-extern BOOL FASTCALL ControlsInit(LPCWSTR ClassName);
+BOOL WINAPI RegisterSystemControls(VOID);
extern const struct builtin_class_descr BUTTON_builtin_class;
extern const struct builtin_class_descr COMBO_builtin_class;
Modified: trunk/reactos/dll/win32/user32/include/user32p.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/include/u…
==============================================================================
--- trunk/reactos/dll/win32/user32/include/user32p.h (original)
+++ trunk/reactos/dll/win32/user32/include/user32p.h Fri Nov 16 10:12:59 2007
@@ -129,6 +129,8 @@
#define HideCaret(hwnd) \
NtUserHideCaret(hwnd)
+#define NtUserRegisterSystemClasses(Count,SysClasses) \
+ (BOOL)NtUserCallTwoParam((DWORD)Count, (DWORD)SysClasses,
TWOPARAM_ROUTINE_ROS_REGSYSCLASSES)
/* Internal Thread Data */
extern HINSTANCE User32Instance;
Modified: trunk/reactos/dll/win32/user32/misc/dllmain.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/misc/dllm…
==============================================================================
--- trunk/reactos/dll/win32/user32/misc/dllmain.c (original)
+++ trunk/reactos/dll/win32/user32/misc/dllmain.c Fri Nov 16 10:12:59 2007
@@ -105,8 +105,11 @@
{
case DLL_PROCESS_ATTACH:
User32Instance = hInstanceDll;
- if (!NtUserRegisterUserModule(hInstanceDll))
+ if (!NtUserRegisterUserModule(hInstanceDll) ||
+ !RegisterSystemControls())
+ {
return FALSE;
+ }
hProcessHeap = RtlGetProcessHeap();
if (!Init())
Modified: trunk/reactos/dll/win32/user32/windows/class.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/c…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/class.c (original)
+++ trunk/reactos/dll/win32/user32/windows/class.c Fri Nov 16 10:12:59 2007
@@ -14,8 +14,6 @@
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(user32);
-extern BOOL ControlsInitialized;
-
/*
* @implemented
*/
@@ -62,12 +60,6 @@
}
}
- /* Register built-in controls if not already done */
- if (! ControlsInitialized)
- {
- ControlsInitialized = ControlsInit(ClassName.Buffer);
- }
-
Ret = NtUserGetClassInfo(hInstance,
&ClassName,
(LPWNDCLASSEXW)lpwcx,
@@ -121,12 +113,6 @@
{
RtlInitUnicodeString(&ClassName,
lpszClass);
- }
-
- /* Register built-in controls if not already done */
- if (! ControlsInitialized)
- {
- ControlsInitialized = ControlsInit(ClassName.Buffer);
}
return NtUserGetClassInfo(hInstance,
Modified: trunk/reactos/dll/win32/user32/windows/window.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/w…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/window.c (original)
+++ trunk/reactos/dll/win32/user32/windows/window.c Fri Nov 16 10:12:59 2007
@@ -15,8 +15,6 @@
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(user32);
-
-BOOL ControlsInitialized = FALSE;
LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active);
void MDI_CalcDefaultChildPos( HWND hwndClient, INT total, LPPOINT lpPos, INT delta, UINT
*id );
@@ -185,12 +183,6 @@
return (HWND)0;
}
}
- }
-
- /* Register built-in controls if not already done */
- if (! ControlsInitialized)
- {
- ControlsInitialized = ControlsInit(ClassName.Buffer);
}
if (Unicode)
Modified: trunk/reactos/include/reactos/win32k/ntuser.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntu…
==============================================================================
--- trunk/reactos/include/reactos/win32k/ntuser.h (original)
+++ trunk/reactos/include/reactos/win32k/ntuser.h Fri Nov 16 10:12:59 2007
@@ -3,6 +3,20 @@
struct _W32PROCESSINFO;
struct _W32THREADINFO;
+
+typedef struct _REGISTER_SYSCLASS
+{
+ /* This is a reactos specific class used to initialize the
+ system window classes during user32 initialization */
+ UNICODE_STRING ClassName;
+ UINT Style;
+ WNDPROC ProcW;
+ WNDPROC ProcA;
+ UINT ExtraBytes;
+ HICON hCursor;
+ HBRUSH hBrush;
+ UINT ClassId;
+} REGISTER_SYSCLASS, *PREGISTER_SYSCLASS;
typedef struct _DESKTOP
{
@@ -54,6 +68,23 @@
UINT System : 1;
UINT Global : 1;
UINT MenuNameIsString : 1;
+
+#define CLASS_DEFAULT 0x0
+#define CLASS_DESKTOP 0x1
+#define CLASS_DIALOG 0x2
+#define CLASS_POPUPMENU 0x3
+#define CLASS_COMBO 0x4
+#define CLASS_COMBOLBOX 0x5
+#define CLASS_MDICLIENT 0x6
+#define CLASS_MENU 0x7
+#define CLASS_SCROLL 0x8
+#define CLASS_BUTTON 0x9
+#define CLASS_LISTBOX 0xA
+#define CLASS_EDIT 0xB
+#define CLASS_ICONTITLE 0xC
+#define CLASS_STATIC 0xD
+ UINT ClassId : 4;
+
} WINDOWCLASS, *PWINDOWCLASS;
typedef struct _WINDOW
@@ -92,6 +123,9 @@
PWINDOWCLASS LocalClassList;
PWINDOWCLASS GlobalClassList;
PWINDOWCLASS SystemClassList;
+
+ UINT RegisteredSysClasses : 1;
+
} W32PROCESSINFO, *PW32PROCESSINFO;
typedef struct _W32THREADINFO
@@ -590,6 +624,7 @@
#define TWOPARAM_ROUTINE_ROS_SHOWWINDOW 0x1000
#define TWOPARAM_ROUTINE_ROS_ISACTIVEICON 0x1001
#define TWOPARAM_ROUTINE_ROS_NCDESTROY 0x1002
+#define TWOPARAM_ROUTINE_ROS_REGSYSCLASSES 0x1003
DWORD
NTAPI
NtUserCallTwoParam(
@@ -1761,8 +1796,7 @@
/* FIXME: These flag constans aren't what Windows uses. */
#define REGISTERCLASS_ANSI 2
-#define REGISTERCLASS_SYSTEM 4
-#define REGISTERCLASS_ALL (REGISTERCLASS_ANSI | REGISTERCLASS_SYSTEM)
+#define REGISTERCLASS_ALL (REGISTERCLASS_ANSI)
RTL_ATOM NTAPI
NtUserRegisterClassEx(
Modified: trunk/reactos/subsystems/win32/win32k/include/class.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/class.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/class.h Fri Nov 16 10:12:59 2007
@@ -74,6 +74,10 @@
IN WNDPROC WndProc,
IN BOOL bUnicode);
+BOOL
+UserRegisterSystemClasses(IN ULONG Count,
+ IN PREGISTER_SYSCLASS SystemClasses);
+
VOID
UserAddCallProcToClass(IN OUT PWINDOWCLASS Class,
IN PCALLPROC CallProc);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/class.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/class.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/class.c Fri Nov 16 10:12:59 2007
@@ -38,6 +38,8 @@
/* WINDOWCLASS ***************************************************************/
+#define REGISTERCLASS_SYSTEM 0x4
+
static VOID
IntFreeClassMenuName(IN OUT PWINDOWCLASS Class)
{
@@ -1042,9 +1044,11 @@
{
RTL_ATOM Atom = (RTL_ATOM)0;
+ ASSERT(BaseClass != NULL);
+
if (IntGetAtomFromStringOrAtom(ClassName,
&Atom) &&
- BaseClass != NULL && Atom != (RTL_ATOM)0)
+ Atom != (RTL_ATOM)0)
{
PWINDOWCLASS Class;
@@ -1098,7 +1102,6 @@
NULL,
&pi->SystemClassList,
Link);
-
if (Class == NULL)
{
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
@@ -1129,7 +1132,7 @@
/* NOTE: Accessing the buffers in ClassName and MenuName may raise exceptions! */
ti = GetW32ThreadInfo();
- if (ti == NULL)
+ if (ti == NULL || !ti->kpi->RegisteredSysClasses)
{
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return (RTL_ATOM)0;
@@ -1792,6 +1795,74 @@
lpwcx->hIconSm = Class->hIconSm; /* FIXME - get handle from pointer */
return TRUE;
+}
+
+BOOL
+UserRegisterSystemClasses(IN ULONG Count,
+ IN PREGISTER_SYSCLASS SystemClasses)
+{
+ /* NOTE: This routine may raise exceptions! */
+ UINT i;
+ UNICODE_STRING ClassName, MenuName;
+ PW32PROCESSINFO pi = GetW32ProcessInfo();
+ WNDCLASSEXW wc;
+ PWINDOWCLASS Class;
+ BOOL Ret = TRUE;
+
+ if (pi->RegisteredSysClasses || pi->hModUser == NULL)
+ return FALSE;
+
+ RtlZeroMemory(&MenuName, sizeof(MenuName));
+
+ for (i = 0; i != Count; i++)
+ {
+ ClassName = ProbeForReadUnicodeString(&SystemClasses[i].ClassName);
+ if (ClassName.Length != 0)
+ {
+ ProbeForRead(ClassName.Buffer,
+ ClassName.Length,
+ sizeof(WCHAR));
+ }
+
+ wc.cbSize = sizeof(wc);
+ wc.style = SystemClasses[i].Style;
+ wc.lpfnWndProc = SystemClasses[i].ProcW;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = SystemClasses[i].ExtraBytes;
+ wc.hInstance = pi->hModUser;
+ wc.hIcon = NULL;
+ wc.hCursor = SystemClasses[i].hCursor;
+ wc.hbrBackground = SystemClasses[i].hBrush;
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = ClassName.Buffer;
+ wc.hIconSm = NULL;
+
+ Class = IntCreateClass(&wc,
+ &ClassName,
+ &MenuName,
+ SystemClasses[i].ProcA,
+ REGISTERCLASS_SYSTEM,
+ NULL,
+ pi);
+ if (Class != NULL)
+ {
+ Class->ClassId = SystemClasses[i].ClassId;
+
+ ASSERT(Class->System);
+ Class->Next = pi->SystemClassList;
+ (void)InterlockedExchangePointer(&pi->SystemClassList,
+ Class);
+ }
+ else
+ {
+ WARN("!!! Registering system class failed!\n");
+ Ret = FALSE;
+ }
+ }
+
+ if (Ret)
+ pi->RegisteredSysClasses = TRUE;
+ return Ret;
}
/* SYSCALLS *****************************************************************/
@@ -2179,9 +2250,9 @@
else
{
if (CapturedClassName.Length == 0)
- WARN("Tried to get information of a non-existing class atom
0x%p\n", CapturedClassName.Buffer);
+ WARN("Tried to get information of a non-existing class atom 0x%p
process 0x%p init: 0x%x\n", CapturedClassName.Buffer, PsGetCurrentProcessId(),
pi->RegisteredSysClasses);
else
- WARN("Tried to get information of a non-existing class
\"%wZ\"\n", &CapturedClassName);
+ WARN("Tried to get information of a non-existing class
\"%wZ\" process 0x%p init: 0x%x\n", &CapturedClassName,
PsGetCurrentProcessId(), pi->RegisteredSysClasses);
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
}
}
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/misc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/misc.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/misc.c Fri Nov 16 10:12:59 2007
@@ -765,6 +765,33 @@
RETURN( Ret);
}
+ case TWOPARAM_ROUTINE_ROS_REGSYSCLASSES:
+ {
+ DWORD Ret = 0;
+ DWORD Count = Param1;
+ PREGISTER_SYSCLASS RegSysClassArray = (PREGISTER_SYSCLASS)Param2;
+
+ if (Count != 0 && RegSysClassArray != NULL)
+ {
+ _SEH_TRY
+ {
+ ProbeArrayForRead(RegSysClassArray,
+ sizeof(RegSysClassArray[0]),
+ Count,
+ 2);
+
+ Ret = (DWORD)UserRegisterSystemClasses(Count,
+ RegSysClassArray);
+ }
+ _SEH_HANDLE
+ {
+ SetLastNtError(_SEH_GetExceptionCode());
+ }
+ _SEH_END;
+ }
+
+ RETURN( Ret);
+ }
}
DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x
Parm2=0x%x\n",
Routine, Param1, Param2);