Window Class handling fixes:

- Corrected styles/names for builtin classes.
- Make NtUserRegisterClassExWOW a bit more like in windows.
- More Windows-like handling of hInstance in RegisterClassEx[AW].
- Very basic work on global vs. local window classes.

svn path=/trunk/; revision=9417
This commit is contained in:
Filip Navara 2004-05-16 19:31:09 +00:00
parent 192d918fb4
commit eb9fa5b0a5
19 changed files with 434 additions and 355 deletions

View file

@ -459,7 +459,7 @@ NtUserQueryWindow 2
NtUserReleaseDC 2
NtUserRealChildWindowFromPoint 3
NtUserRedrawWindow 4
NtUserRegisterClassExWOW 5
NtUserRegisterClassExWOW 7
NtUserRegisterHotKey 4
NtUserRegisterTasklist 1
NtUserRegisterWindowMessage 1

View file

@ -1,4 +1,4 @@
/* $Id: regcontrol.h,v 1.7 2003/12/07 23:02:57 gvg Exp $
/* $Id: regcontrol.h,v 1.8 2004/05/16 19:31:06 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS User32
@ -14,9 +14,6 @@
#define IS_ATOM(x) \
(((ULONG_PTR)(x) > 0x0) && ((ULONG_PTR)(x) < 0x10000))
/* Built-in class names (see _Undocumented_Windows_ p.418) */
#define ICONTITLE_CLASS_ATOM MAKEINTATOMA(32772) /* IconTitle */
/* Built-in class descriptor */
struct builtin_class_descr
{

View file

@ -1115,13 +1115,20 @@ NtUserRedrawWindow
UINT flags
);
RTL_ATOM
STDCALL
NtUserRegisterClassExWOW(CONST WNDCLASSEXW* lpwcx,
BOOL bUnicodeClass,
WNDPROC wpExtra,
DWORD Unknown4,
DWORD Unknown5);
/* FIXME: These flag constans aren't what Windows uses. */
#define REGISTERCLASS_ANSI 2
#define REGISTERCLASS_SYSTEM 4
#define REGISTERCLASS_ALL (REGISTERCLASS_ANSI | REGISTERCLASS_SYSTEM)
RTL_ATOM STDCALL
NtUserRegisterClassExWOW(
CONST WNDCLASSEXW* lpwcx,
PUNICODE_STRING ClassName,
PUNICODE_STRING ClassNameCopy,
PUNICODE_STRING MenuName,
WNDPROC wpExtra,
DWORD Flags,
DWORD Unknown7);
BOOL
STDCALL

View file

@ -112,7 +112,7 @@ const struct builtin_class_descr BUTTON_builtin_class =
{
#ifdef __REACTOS__
L"Button", /* name */
CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC, /* style */
CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC, /* style */
ButtonWndProcW, /* procW */
ButtonWndProcA, /* procA */
NB_EXTRA_BYTES, /* extra */

View file

@ -85,7 +85,7 @@ static LRESULT WINAPI ComboWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM
const struct builtin_class_descr COMBO_builtin_class =
{
L"ComboBox", /* name */
CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, /* style */
CS_PARENTDC | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS, /* style */
(WNDPROC) ComboWndProcW, /* procW */
(WNDPROC) ComboWndProcA, /* procA */
sizeof(HEADCOMBO *), /* extra */

View file

@ -293,7 +293,7 @@ const struct builtin_class_descr EDIT_builtin_class =
{
#ifdef __REACTOS__
L"Edit", /* name */
CS_GLOBALCLASS | CS_DBLCLKS | CS_PARENTDC, /* style */
CS_DBLCLKS | CS_PARENTDC, /* style */
(WNDPROC)EditWndProcW, /* procW */
(WNDPROC)EditWndProcA, /* procA */
sizeof(EDITSTATE *), /* extra */

View file

@ -38,18 +38,21 @@ static HFONT hIconTitleFont;
static LRESULT CALLBACK IconTitleWndProcW( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
static LRESULT CALLBACK IconTitleWndProcA( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
#define MAKEINTATOMW(atom) ((LPCWSTR)((ULONG_PTR)((WORD)(atom))))
#define ICONTITLE_CLASS_ATOM MAKEINTATOMW(32772)
/*********************************************************************
* icon title class descriptor
*/
const struct builtin_class_descr ICONTITLE_builtin_class =
{
L"ICONTITLE_CLASS_ATOM", /* name */
CS_GLOBALCLASS, /* style */
ICONTITLE_CLASS_ATOM, /* name */
0, /* style */
(WNDPROC) IconTitleWndProcW, /* procW */
(WNDPROC) IconTitleWndProcA, /* procA */
0, /* extra */
0, /* extra */
(LPCWSTR) IDC_ARROW, /* cursor */ /* FIXME Wine uses IDC_ARROWA */
0 /* brush */
0 /* brush */
};
@ -57,6 +60,7 @@ const struct builtin_class_descr ICONTITLE_builtin_class =
/***********************************************************************
* ICONTITLE_Create
*/
#ifndef __REACTOS__
HWND ICONTITLE_Create( HWND owner )
{
HWND hWnd;
@ -77,6 +81,7 @@ HWND ICONTITLE_Create( HWND owner )
GetWindowLongW( hWnd, GWL_STYLE ) & ~(WS_CAPTION | WS_BORDER) );
return hWnd;
}
#endif
/***********************************************************************
* ICONTITLE_SetTitlePos

View file

@ -1,4 +1,4 @@
/* $Id: listbox.c,v 1.16 2004/04/09 20:03:13 navaraf Exp $
/* $Id: listbox.c,v 1.17 2004/05/16 19:31:06 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS User32
@ -136,7 +136,7 @@ static LRESULT LISTBOX_GetItemRect( LB_DESCR *descr, INT index, RECT *rect );
const struct builtin_class_descr LISTBOX_builtin_class =
{
L"ListBox", /* name */
CS_GLOBALCLASS | CS_DBLCLKS /*| CS_PARENTDC*/, /* style */
CS_DBLCLKS /*| CS_PARENTDC*/, /* style */
(WNDPROC)ListBoxWndProcW, /* procW */
(WNDPROC)ListBoxWndProcA, /* procA */
sizeof(LB_DESCR *), /* extra */
@ -151,7 +151,7 @@ const struct builtin_class_descr LISTBOX_builtin_class =
const struct builtin_class_descr COMBOLBOX_builtin_class =
{
L"ComboLBox", /* name */
CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS, /* style */
CS_DBLCLKS | CS_SAVEBITS, /* style */
(WNDPROC)ComboLBWndProcW, /* procW */
(WNDPROC)ComboLBWndProcA, /* procA */
sizeof(LB_DESCR *), /* extra */

View file

@ -1,4 +1,4 @@
/* $Id: regcontrol.c,v 1.18 2004/03/27 10:46:32 gvg Exp $
/* $Id: regcontrol.c,v 1.19 2004/05/16 19:31:06 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS User32
@ -11,38 +11,51 @@
#include <windows.h>
#include <wchar.h>
#include <user32.h>
#include "user32/regcontrol.h"
#include "win32k/ntuser.h"
static void RegisterBuiltinClass(const struct builtin_class_descr *Descr)
{
WNDCLASSEXW wc;
ATOM Class;
WNDCLASSEXW wc;
UNICODE_STRING ClassName;
UNICODE_STRING MenuName;
wc.cbSize = sizeof(WNDCLASSEXW);
wc.lpszClassName = Descr->name;
wc.lpfnWndProc = Descr->procW;
wc.style = Descr->style;
wc.hInstance = NULL;
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;
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;
MenuName.Length =
MenuName.MaximumLength = 0;
MenuName.Buffer = NULL;
#if 0
if(IS_ATOM(wc.lpszClassName))
DbgPrint("Registering built-in class atom=0x%x\n", wc.lpszClassName);
else
DbgPrint("Registering built-in class %wS\n", wc.lpszClassName);
#endif
Class = NtUserRegisterClassExWOW(&wc,TRUE,Descr->procA,0,0);
#if 0
DbgPrint("RegisterClassW = %d\n", Class);
#endif
if (IS_ATOM(Descr->name))
{
ClassName.Length =
ClassName.MaximumLength = 0;
ClassName.Buffer = (LPWSTR)Descr->name;
} else
{
RtlInitUnicodeString(&ClassName, Descr->name);
}
NtUserRegisterClassExWOW(
&wc,
&ClassName,
&ClassName,
&MenuName,
Descr->procA,
REGISTERCLASS_SYSTEM,
0);
}
/***********************************************************************

View file

@ -1,4 +1,4 @@
/* $Id: static.c,v 1.12 2004/03/10 23:21:56 navaraf Exp $
/* $Id: static.c,v 1.13 2004/05/16 19:31:06 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS User32
@ -60,7 +60,7 @@ static pfPaint staticPaintFunc[SS_TYPEMASK+1] =
const struct builtin_class_descr STATIC_builtin_class =
{
L"Static", /* name */
CS_GLOBALCLASS | CS_DBLCLKS, /* style */
CS_DBLCLKS | CS_PARENTDC, /* style */
(WNDPROC) StaticWndProcW, /* procW */
(WNDPROC) StaticWndProcA, /* procA */
STATIC_EXTRA_BYTES, /* extra */

View file

@ -7,6 +7,8 @@
#include <windows.h>
#include <win32k/win32k.h>
extern HINSTANCE User32Instance;
typedef struct _USER32_THREAD_DATA
{
MSG LastMessage;

View file

@ -21,6 +21,7 @@ DWORD DebugTraceLevel = MIN_TRACE;
extern CRITICAL_SECTION gcsMPH;
static ULONG User32TlsIndex;
HINSTANCE User32Instance;
/* To make the linker happy */
VOID STDCALL KeBugCheck (ULONG BugCheckCode) {}
@ -108,6 +109,7 @@ DllMain(
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
User32Instance = hinstDll;
hProcessHeap = RtlGetProcessHeap();
Init();
InitThread();

View file

@ -1,4 +1,4 @@
/* $Id: class.c,v 1.47 2004/05/10 12:21:22 gvg Exp $
/* $Id: class.c,v 1.48 2004/05/16 19:31:07 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll
@ -399,135 +399,164 @@ RealGetWindowClassA(
return GetClassNameA(hwnd,pszType,cchType);
}
/*
* @implemented
*/
ATOM
STDCALL
RegisterClassA(CONST WNDCLASSA *lpWndClass)
{
WNDCLASSEXA Class;
if ( !lpWndClass )
return 0;
RtlCopyMemory ( &Class.style, lpWndClass, sizeof(WNDCLASSA) );
Class.cbSize = sizeof(WNDCLASSEXA);
Class.hIconSm = NULL;
return RegisterClassExA ( &Class );
}
/*
* @implemented
*/
ATOM STDCALL
RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
{
RTL_ATOM Atom;
WNDCLASSEXW wndclass;
NTSTATUS Status;
LPWSTR ClassName = NULL;
LPWSTR MenuName = NULL;
RTL_ATOM Atom;
WNDCLASSEXA WndClass;
UNICODE_STRING ClassName;
UNICODE_STRING MenuName;
if ( !lpwcx || (lpwcx->cbSize != sizeof(WNDCLASSEXA)) )
return 0;
if ( !lpwcx->lpszClassName )
return 0;
RtlCopyMemory ( &wndclass, lpwcx, sizeof(WNDCLASSEXW) );
if ( !IS_ATOM(lpwcx->lpszClassName) )
{
Status = HEAP_strdupAtoW ( &ClassName, (LPCSTR)lpwcx->lpszClassName, NULL );
if ( !NT_SUCCESS (Status) )
{
SetLastError (RtlNtStatusToDosError(Status));
if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXW) ||
lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
lpwcx->lpszClassName == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
wndclass.lpszClassName = ClassName;
}
}
if ( !IS_INTRESOURCE(lpwcx->lpszMenuName) )
{
Status = HEAP_strdupAtoW ( &MenuName, (LPCSTR)lpwcx->lpszMenuName, NULL );
if ( !NT_SUCCESS (Status) )
{
if ( ClassName )
HEAP_free ( ClassName );
SetLastError (RtlNtStatusToDosError(Status));
/*
* On real Windows this looks more like:
* if (lpwcx->hInstance == User32Instance &&
* *(PULONG)((ULONG_PTR)NtCurrentTeb() + 0x6D4) & 0x400)
* But since I have no idea what the magic field in the
* TEB structure means, I rather decided to omit that.
* -- Filip Navara
*/
if (lpwcx->hInstance == User32Instance)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
wndclass.lpszMenuName = MenuName;
}
}
Atom = NtUserRegisterClassExWOW ( &wndclass, FALSE, (WNDPROC)0, 0, 0 );
/* Yes, this is correct. We should modify the passed structure. */
if (lpwcx->hInstance == NULL)
((WNDCLASSEXA*)lpwcx)->hInstance = GetModuleHandleW(NULL);
RtlCopyMemory(&WndClass, lpwcx, sizeof(WNDCLASSEXW));
/* free strings if neccessary */
if ( MenuName ) HEAP_free ( MenuName );
if ( ClassName ) HEAP_free ( ClassName );
if (IS_ATOM(lpwcx->lpszMenuName))
{
MenuName.Length =
MenuName.MaximumLength = 0;
MenuName.Buffer = (LPWSTR)lpwcx->lpszClassName;
} else
{
RtlCreateUnicodeStringFromAsciiz(&MenuName, lpwcx->lpszMenuName);
}
return (ATOM)Atom;
if (IS_ATOM(lpwcx->lpszClassName))
{
ClassName.Length =
ClassName.MaximumLength = 0;
ClassName.Buffer = (LPWSTR)lpwcx->lpszClassName;
} else
{
RtlCreateUnicodeStringFromAsciiz(&ClassName, lpwcx->lpszClassName);
}
Atom = NtUserRegisterClassExWOW(
(WNDCLASSEXW*)&WndClass,
&ClassName,
&ClassName,
&MenuName,
NULL,
REGISTERCLASS_ANSI,
0);
RtlFreeUnicodeString(&MenuName);
RtlFreeUnicodeString(&ClassName);
return (ATOM)Atom;
}
/*
* @implemented
*/
ATOM STDCALL
RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
{
RTL_ATOM Atom;
HANDLE hHeap;
WNDCLASSEXW wndclass;
LPWSTR ClassName = NULL;
LPWSTR MenuName = NULL;
WNDCLASSEXW WndClass;
UNICODE_STRING ClassName;
UNICODE_STRING MenuName;
if ( !lpwcx || (lpwcx->cbSize != sizeof(WNDCLASSEXA)) )
return 0;
if ( !lpwcx->lpszClassName )
return 0;
hHeap = GetProcessHeap();
RtlCopyMemory ( &wndclass, lpwcx, sizeof(WNDCLASSEXW) );
/* copy strings if needed */
if ( !IS_ATOM(lpwcx->lpszClassName) )
{
ClassName = HEAP_strdupW ( lpwcx->lpszClassName, lstrlenW(lpwcx->lpszClassName) );
if ( !ClassName )
{
SetLastError(RtlNtStatusToDosError(STATUS_NO_MEMORY));
if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXW) ||
lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
lpwcx->lpszClassName == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
wndclass.lpszClassName = ClassName;
}
}
if ( !IS_INTRESOURCE(lpwcx->lpszMenuName) )
{
MenuName = HEAP_strdupW ( lpwcx->lpszMenuName, lstrlenW(lpwcx->lpszMenuName) );
if ( !MenuName )
{
if ( ClassName )
HEAP_free ( MenuName );
SetLastError(RtlNtStatusToDosError(STATUS_NO_MEMORY));
/*
* On real Windows this looks more like:
* if (lpwcx->hInstance == User32Instance &&
* *(PULONG)((ULONG_PTR)NtCurrentTeb() + 0x6D4) & 0x400)
* But since I have no idea what the magic field in the
* TEB structure means, I rather decided to omit that.
* -- Filip Navara
*/
if (lpwcx->hInstance == User32Instance)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
wndclass.lpszMenuName = MenuName;
}
}
Atom = NtUserRegisterClassExWOW ( &wndclass, TRUE, (WNDPROC)0, 0, 0 );
/* Yes, this is correct. We should modify the passed structure. */
if (lpwcx->hInstance == NULL)
((WNDCLASSEXW*)lpwcx)->hInstance = GetModuleHandleW(NULL);
/* free strings if neccessary */
if ( MenuName ) HEAP_free ( MenuName );
if ( ClassName ) HEAP_free ( ClassName );
RtlCopyMemory(&WndClass, lpwcx, sizeof(WNDCLASSEXW));
return (ATOM)Atom;
if (IS_ATOM(lpwcx->lpszMenuName))
{
MenuName.Length =
MenuName.MaximumLength = 0;
MenuName.Buffer = (LPWSTR)lpwcx->lpszClassName;
} else
{
RtlInitUnicodeString(&MenuName, lpwcx->lpszMenuName);
}
if (IS_ATOM(lpwcx->lpszClassName))
{
ClassName.Length =
ClassName.MaximumLength = 0;
ClassName.Buffer = (LPWSTR)lpwcx->lpszClassName;
} else
{
RtlInitUnicodeString(&ClassName, lpwcx->lpszClassName);
}
return (ATOM)NtUserRegisterClassExWOW(
&WndClass,
&ClassName,
&ClassName,
&MenuName,
NULL,
0,
0);
}
/*
* @implemented
*/
ATOM STDCALL
RegisterClassA(CONST WNDCLASSA *lpWndClass)
{
WNDCLASSEXA Class;
if (lpWndClass == NULL)
return 0;
RtlCopyMemory(&Class.style, lpWndClass, sizeof(WNDCLASSA));
Class.cbSize = sizeof(WNDCLASSEXA);
Class.hIconSm = NULL;
return RegisterClassExA(&Class);
}
/*
@ -536,17 +565,16 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
ATOM STDCALL
RegisterClassW(CONST WNDCLASSW *lpWndClass)
{
WNDCLASSEXW Class;
WNDCLASSEXW Class;
if ( !lpWndClass )
return 0;
if (lpWndClass == NULL)
return 0;
RtlCopyMemory ( &Class.style, lpWndClass, sizeof(WNDCLASSW) );
RtlCopyMemory(&Class.style, lpWndClass, sizeof(WNDCLASSW));
Class.cbSize = sizeof(WNDCLASSEXW);
Class.hIconSm = NULL;
Class.cbSize = sizeof(WNDCLASSEXW);
Class.hIconSm = NULL;
return RegisterClassExW ( &Class );
return RegisterClassExW(&Class);
}
/*

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: dialog.c,v 1.25 2004/04/09 20:03:14 navaraf Exp $
/* $Id: dialog.c,v 1.26 2004/05/16 19:31:07 navaraf Exp $
*
* PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/dialog.c
@ -134,7 +134,7 @@ typedef struct
const struct builtin_class_descr DIALOG_builtin_class =
{
DIALOG_CLASS_ATOMW, /* name */
CS_GLOBALCLASS | CS_SAVEBITS | CS_DBLCLKS, /* style */
CS_SAVEBITS | CS_DBLCLKS, /* style */
(WNDPROC) DefDlgProcW, /* procW */
(WNDPROC) DefDlgProcA, /* procA */
DWL_INIT + sizeof(LONG), /* extra */

View file

@ -213,23 +213,13 @@ static void MDI_PostUpdate(HWND hwnd, MDICLIENTINFO* ci, WORD recalc)
*/
const struct builtin_class_descr MDICLIENT_builtin_class =
{
#ifdef __REACTOS__
L"MDIClient", /* name */
CS_GLOBALCLASS, /* style */
0, /* style */
MDIClientWndProcW, /* procW */
MDIClientWndProcA, /* procA */
sizeof(MDICLIENTINFO *), /* extra */
IDC_ARROW, /* cursor */
(HBRUSH)(COLOR_APPWORKSPACE+1) /* brush */
#else
"MDIClient", /* name */
CS_GLOBALCLASS, /* style */
MDIClientWndProcW, /* procW */
MDIClientWndProcA, /* procA */
sizeof(MDICLIENTINFO), /* extra */
IDC_ARROW, /* cursor */
(HBRUSH)(COLOR_APPWORKSPACE+1) /* brush */
#endif
};

View file

@ -21,7 +21,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: menu.c,v 1.67 2004/05/15 08:53:06 navaraf Exp $
/* $Id: menu.c,v 1.68 2004/05/16 19:31:07 navaraf Exp $
*
* PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/menu.c
@ -120,12 +120,12 @@ static LRESULT WINAPI PopupMenuWndProcW(HWND hwnd, UINT message, WPARAM wParam,
const struct builtin_class_descr POPUPMENU_builtin_class =
{
POPUPMENU_CLASS_ATOMW, /* name */
CS_GLOBALCLASS | CS_SAVEBITS | CS_DBLCLKS, /* style */
CS_SAVEBITS | CS_DBLCLKS, /* style */
(WNDPROC) PopupMenuWndProcW, /* FIXME - procW */
(WNDPROC) NULL, /* FIXME - procA */
sizeof(MENUINFO *), /* extra */
(LPCWSTR) IDC_ARROW, /* cursor */
(HBRUSH)(COLOR_MENU + 1) /* brush */
(LPCWSTR) IDC_ARROW, /* cursor */
(HBRUSH)(COLOR_MENU + 1) /* brush */
};

View file

@ -25,6 +25,7 @@ typedef struct _WNDCLASS_OBJECT
RTL_ATOM Atom;
HICON hIconSm;
BOOL Unicode;
BOOL Global;
LIST_ENTRY ListEntry;
PCHAR ExtraData;
} WNDCLASS_OBJECT, *PWNDCLASS_OBJECT;
@ -41,22 +42,24 @@ CleanupClassImpl(VOID);
#define IntUnLockProcessClasses(W32Process) \
ExReleaseFastMutex(&W32Process->ClassListLock)
NTSTATUS STDCALL
ClassReferenceClassByName(PWNDCLASS_OBJECT *Class,
LPCWSTR ClassName);
BOOL FASTCALL
ClassReferenceClassByAtom(
PWNDCLASS_OBJECT* Class,
RTL_ATOM Atom,
HINSTANCE hInstance);
NTSTATUS FASTCALL
ClassReferenceClassByAtom(PWNDCLASS_OBJECT *Class,
RTL_ATOM ClassAtom);
BOOL FASTCALL
ClassReferenceClassByName(
PWNDCLASS_OBJECT *Class,
LPCWSTR ClassName,
HINSTANCE hInstance);
BOOL FASTCALL
ClassReferenceClassByNameOrAtom(
PWNDCLASS_OBJECT *Class,
LPCWSTR ClassNameOrAtom,
HINSTANCE hInstance);
NTSTATUS FASTCALL
ClassReferenceClassByNameOrAtom(PWNDCLASS_OBJECT *Class,
LPCWSTR ClassNameOrAtom);
PWNDCLASS_OBJECT FASTCALL
IntCreateClass(CONST WNDCLASSEXW *lpwcx,
BOOL bUnicodeClass,
WNDPROC wpExtra,
RTL_ATOM Atom);
struct _WINDOW_OBJECT;
ULONG FASTCALL
IntGetClassLong(struct _WINDOW_OBJECT *WindowObject, ULONG Offset, BOOL Ansi);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: class.c,v 1.53 2004/05/13 20:10:15 navaraf Exp $
/* $Id: class.c,v 1.54 2004/05/16 19:31:09 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -47,127 +47,139 @@ CleanupClassImpl(VOID)
return(STATUS_SUCCESS);
}
NTSTATUS FASTCALL
ClassReferenceClassByAtom(PWNDCLASS_OBJECT* Class,
RTL_ATOM Atom)
BOOL FASTCALL
ClassReferenceClassByAtom(
PWNDCLASS_OBJECT* Class,
RTL_ATOM Atom,
HINSTANCE hInstance)
{
PWNDCLASS_OBJECT Current;
PLIST_ENTRY CurrentEntry;
PW32PROCESS Process = PsGetWin32Process();
PWNDCLASS_OBJECT Current, BestMatch = NULL;
PLIST_ENTRY CurrentEntry;
PW32PROCESS Process = PsGetWin32Process();
IntLockProcessClasses(Process);
CurrentEntry = Process->ClassListHead.Flink;
while (CurrentEntry != &Process->ClassListHead)
{
Current = CONTAINING_RECORD(CurrentEntry, WNDCLASS_OBJECT, ListEntry);
IntLockProcessClasses(Process);
CurrentEntry = Process->ClassListHead.Flink;
while (CurrentEntry != &Process->ClassListHead)
{
Current = CONTAINING_RECORD(CurrentEntry, WNDCLASS_OBJECT, ListEntry);
if (Current->Atom == Atom)
{
*Class = Current;
ObmReferenceObject(Current);
IntUnLockProcessClasses(Process);
return(STATUS_SUCCESS);
}
if (Current->Atom == Atom && Current->hInstance == hInstance)
{
*Class = Current;
ObmReferenceObject(Current);
IntUnLockProcessClasses(Process);
return TRUE;
}
CurrentEntry = CurrentEntry->Flink;
}
IntUnLockProcessClasses(Process);
if (Current->Atom == Atom && Current->Global)
BestMatch = Current;
CurrentEntry = CurrentEntry->Flink;
}
IntUnLockProcessClasses(Process);
if (BestMatch != NULL)
{
*Class = BestMatch;
ObmReferenceObject(BestMatch);
return TRUE;
}
return(STATUS_NOT_FOUND);
return FALSE;
}
NTSTATUS STDCALL
ClassReferenceClassByName(PWNDCLASS_OBJECT *Class,
LPCWSTR ClassName)
BOOL FASTCALL
ClassReferenceClassByName(
PWNDCLASS_OBJECT *Class,
LPCWSTR ClassName,
HINSTANCE hInstance)
{
PWINSTATION_OBJECT WinStaObject;
NTSTATUS Status;
RTL_ATOM ClassAtom;
PWINSTATION_OBJECT WinStaObject;
NTSTATUS Status;
BOOL Found;
RTL_ATOM ClassAtom;
if (!ClassName)
{
return(STATUS_INVALID_PARAMETER);
}
if (!ClassName)
return FALSE;
Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
KernelMode,
0,
&WinStaObject);
if (!NT_SUCCESS(Status))
{
Status = IntValidateWindowStationHandle(
PROCESS_WINDOW_STATION(),
KernelMode,
0,
&WinStaObject);
if (!NT_SUCCESS(Status))
{
DPRINT("Validation of window station handle (0x%X) failed\n",
PROCESS_WINDOW_STATION());
return(STATUS_UNSUCCESSFUL);
}
return FALSE;
}
Status = RtlLookupAtomInAtomTable(WinStaObject->AtomTable,
(LPWSTR)ClassName,
&ClassAtom);
Status = RtlLookupAtomInAtomTable(
WinStaObject->AtomTable,
(LPWSTR)ClassName,
&ClassAtom);
if (!NT_SUCCESS(Status))
{
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(WinStaObject);
return(Status);
}
Status = ClassReferenceClassByAtom(Class,
ClassAtom);
ObDereferenceObject(WinStaObject);
return(Status);
return FALSE;
}
Found = ClassReferenceClassByAtom(Class, ClassAtom, hInstance);
ObDereferenceObject(WinStaObject);
return Found;
}
NTSTATUS FASTCALL
ClassReferenceClassByNameOrAtom(PWNDCLASS_OBJECT *Class,
LPCWSTR ClassNameOrAtom)
BOOL FASTCALL
ClassReferenceClassByNameOrAtom(
PWNDCLASS_OBJECT *Class,
LPCWSTR ClassNameOrAtom,
HINSTANCE hInstance)
{
NTSTATUS Status;
BOOL Found;
if (IS_ATOM(ClassNameOrAtom))
{
Status = ClassReferenceClassByAtom(Class,
(RTL_ATOM)((ULONG_PTR)ClassNameOrAtom));
}
else
{
Status = ClassReferenceClassByName(Class,
ClassNameOrAtom);
}
if (IS_ATOM(ClassNameOrAtom))
Found = ClassReferenceClassByAtom(Class, (RTL_ATOM)((ULONG_PTR)ClassNameOrAtom), hInstance);
else
Found = ClassReferenceClassByName(Class, ClassNameOrAtom, hInstance);
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
}
return(Status);
return Found;
}
DWORD STDCALL
NtUserGetClassInfo(HINSTANCE hInstance, LPCWSTR lpClassName,
LPWNDCLASSEXW lpWndClassEx, BOOL Ansi, DWORD unknown3)
NtUserGetClassInfo(
HINSTANCE hInstance,
LPCWSTR lpClassName,
LPWNDCLASSEXW lpWndClassEx,
BOOL Ansi,
DWORD unknown3)
{
PWNDCLASS_OBJECT Class;
NTSTATUS Status;
RTL_ATOM Atom;
DPRINT("NtUserGetClassInfo(%S)\n", lpClassName);
Status = ClassReferenceClassByNameOrAtom(&Class, lpClassName);
if (!NT_SUCCESS(Status))
if (IS_ATOM(lpClassName))
DPRINT("NtUserGetClassInfo - %x (%lx)\n", lpClassName, hInstance);
else
DPRINT("NtUserGetClassInfo - %S (%lx)\n", lpClassName, hInstance);
if (!ClassReferenceClassByNameOrAtom(&Class, lpClassName, hInstance))
{
DPRINT("Error (%x)\n", Status);
SetLastNtError(Status);
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
return 0;
}
lpWndClassEx->cbSize = sizeof(LPWNDCLASSEXW);
lpWndClassEx->style = Class->style;
if (Ansi)
lpWndClassEx->lpfnWndProc = Class->lpfnWndProcA;
else
lpWndClassEx->lpfnWndProc = Class->lpfnWndProcW;
DPRINT("%x\n", lpWndClassEx->lpfnWndProc);
lpWndClassEx->cbClsExtra = Class->cbClsExtra;
lpWndClassEx->cbWndExtra = Class->cbWndExtra;
lpWndClassEx->hInstance = Class->hInstance;
/* This is not typo, we're really not going to use Class->hInstance here. */
lpWndClassEx->hInstance = hInstance;
lpWndClassEx->hIcon = Class->hIcon;
lpWndClassEx->hCursor = Class->hCursor;
lpWndClassEx->hbrBackground = Class->hbrBackground;
@ -260,24 +272,35 @@ NtUserGetWOWClass(DWORD Unknown0,
}
PWNDCLASS_OBJECT FASTCALL
IntCreateClass(CONST WNDCLASSEXW *lpwcx,
BOOL bUnicodeClass,
WNDPROC wpExtra,
RTL_ATOM Atom)
IntCreateClass(
CONST WNDCLASSEXW *lpwcx,
DWORD Flags,
WNDPROC wpExtra,
PUNICODE_STRING MenuName,
RTL_ATOM Atom)
{
PWNDCLASS_OBJECT ClassObject;
ULONG objectSize;
NTSTATUS Status;
BOOL Global;
Global = !(Flags & REGISTERCLASS_SYSTEM) ? ClassObject->style & CS_GLOBALCLASS : TRUE;
/* Check for double registration of the class. */
if (PsGetWin32Process() != NULL)
{
Status = ClassReferenceClassByAtom(&ClassObject, Atom);
if (NT_SUCCESS(Status))
if (ClassReferenceClassByAtom(&ClassObject, Atom, lpwcx->hInstance))
{
ObmDereferenceObject(ClassObject);
SetLastWin32Error(ERROR_CLASS_ALREADY_EXISTS);
return(NULL);
/*
* NOTE: We may also get a global class from
* ClassReferenceClassByAtom. This simple check
* prevents that we fail valid request.
*/
if (ClassObject->hInstance == lpwcx->hInstance)
{
SetLastWin32Error(ERROR_CLASS_ALREADY_EXISTS);
ObmDereferenceObject(ClassObject);
return(NULL);
}
}
}
@ -297,40 +320,41 @@ IntCreateClass(CONST WNDCLASSEXW *lpwcx,
ClassObject->hIcon = lpwcx->hIcon;
ClassObject->hCursor = lpwcx->hCursor;
ClassObject->hbrBackground = lpwcx->hbrBackground;
ClassObject->Unicode = bUnicodeClass;
ClassObject->Unicode = !(Flags & REGISTERCLASS_ANSI);
ClassObject->Global = Global;
ClassObject->hIconSm = lpwcx->hIconSm;
ClassObject->Atom = Atom;
if (wpExtra == 0) {
if (bUnicodeClass)
{
ClassObject->lpfnWndProcW = lpwcx->lpfnWndProc;
ClassObject->lpfnWndProcA = (WNDPROC)IntAddWndProcHandle(lpwcx->lpfnWndProc,TRUE);
}
else
{
ClassObject->lpfnWndProcA = lpwcx->lpfnWndProc;
if (wpExtra == NULL) {
if (Flags & REGISTERCLASS_ANSI)
{
ClassObject->lpfnWndProcA = lpwcx->lpfnWndProc;
ClassObject->lpfnWndProcW = (WNDPROC)IntAddWndProcHandle(lpwcx->lpfnWndProc,FALSE);
}
} else {
if (bUnicodeClass)
else
{
ClassObject->lpfnWndProcW = lpwcx->lpfnWndProc;
ClassObject->lpfnWndProcA = wpExtra;
ClassObject->lpfnWndProcA = (WNDPROC)IntAddWndProcHandle(lpwcx->lpfnWndProc,TRUE);
}
else
} else {
if (Flags & REGISTERCLASS_ANSI)
{
ClassObject->lpfnWndProcA = lpwcx->lpfnWndProc;
ClassObject->lpfnWndProcW = wpExtra;
}
else
{
ClassObject->lpfnWndProcW = lpwcx->lpfnWndProc;
ClassObject->lpfnWndProcA = wpExtra;
}
}
if (IS_INTRESOURCE(lpwcx->lpszMenuName))
if (MenuName->Length == 0)
{
ClassObject->lpszMenuName = (PUNICODE_STRING)lpwcx->lpszMenuName;
ClassObject->lpszMenuName = (PUNICODE_STRING)MenuName->Buffer;
}
else
{
ClassObject->lpszMenuName = ExAllocatePoolWithTag(NonPagedPool,sizeof(UNICODE_STRING), TAG_STRING);
RtlCreateUnicodeString(ClassObject->lpszMenuName,(LPWSTR)lpwcx->lpszMenuName);
ClassObject->lpszMenuName = ExAllocatePoolWithTag(NonPagedPool, sizeof(UNICODE_STRING), TAG_STRING);
RtlCreateUnicodeString(ClassObject->lpszMenuName, MenuName->Buffer);
}
/* Extra class data */
if (ClassObject->cbClsExtra != 0)
@ -348,11 +372,13 @@ IntCreateClass(CONST WNDCLASSEXW *lpwcx,
RTL_ATOM STDCALL
NtUserRegisterClassExWOW(
CONST WNDCLASSEXW *lpwcx,
BOOL bUnicodeClass,
WNDPROC wpExtra,
DWORD Unknown4,
DWORD Unknown5)
CONST WNDCLASSEXW* lpwcx,
PUNICODE_STRING ClassName,
PUNICODE_STRING ClassNameCopy,
PUNICODE_STRING MenuName,
WNDPROC wpExtra, /* FIXME: Windows uses this parameter for something different. */
DWORD Flags,
DWORD Unknown7)
/*
* FUNCTION:
@ -366,31 +392,37 @@ NtUserRegisterClassExWOW(
* Atom identifying the new class
*/
{
WNDCLASSEXW SafeClass;
PWINSTATION_OBJECT WinStaObject;
PWNDCLASS_OBJECT ClassObject;
NTSTATUS Status;
RTL_ATOM Atom;
WNDCLASSEXW SafeClass;
PWINSTATION_OBJECT WinStaObject;
PWNDCLASS_OBJECT ClassObject;
NTSTATUS Status;
RTL_ATOM Atom;
if(!lpwcx)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return (RTL_ATOM)0;
}
if (!lpwcx)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return (RTL_ATOM)0;
}
if (Flags & ~REGISTERCLASS_ALL)
{
SetLastWin32Error(ERROR_INVALID_FLAGS);
return (RTL_ATOM)0;
}
Status = MmCopyFromCaller(&SafeClass, lpwcx, sizeof(WNDCLASSEXW));
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return (RTL_ATOM)0;
}
Status = MmCopyFromCaller(&SafeClass, lpwcx, sizeof(WNDCLASSEXW));
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return (RTL_ATOM)0;
}
/* Deny negative sizes */
if(lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return (RTL_ATOM)0;
}
/* Deny negative sizes */
if (lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return (RTL_ATOM)0;
}
DPRINT("About to open window station handle (0x%X)\n",
PROCESS_WINDOW_STATION());
@ -404,30 +436,30 @@ NtUserRegisterClassExWOW(
PROCESS_WINDOW_STATION());
return((RTL_ATOM)0);
}
if (!IS_ATOM(SafeClass.lpszClassName))
if (ClassName->Length)
{
DPRINT("NtUserRegisterClassExWOW(%S)\n", SafeClass.lpszClassName);
DPRINT("NtUserRegisterClassExWOW(%S)\n", ClassName->Buffer);
/* FIXME - Safely copy/verify the buffer first!!! */
Status = RtlAddAtomToAtomTable(WinStaObject->AtomTable,
(LPWSTR)SafeClass.lpszClassName,
ClassName->Buffer,
&Atom);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(WinStaObject);
DPRINT("Failed adding class name (%wS) to atom table\n",
lpwcx->lpszClassName);
DPRINT("Failed adding class name (%S) to atom table\n",
ClassName->Buffer);
SetLastNtError(Status);
return((RTL_ATOM)0);
}
}
else
{
Atom = (RTL_ATOM)(ULONG)SafeClass.lpszClassName;
Atom = (RTL_ATOM)(ULONG)ClassName->Buffer;
}
ClassObject = IntCreateClass(&SafeClass, bUnicodeClass, wpExtra, Atom);
ClassObject = IntCreateClass(&SafeClass, Flags, wpExtra, MenuName, Atom);
if (ClassObject == NULL)
{
if (!IS_ATOM(SafeClass.lpszClassName))
if (ClassName->Length)
{
RtlDeleteAtomFromAtomTable(WinStaObject->AtomTable, Atom);
}
@ -654,8 +686,7 @@ NtUserUnregisterClass(
return FALSE;
}
Status = ClassReferenceClassByNameOrAtom(&Class, ClassNameOrAtom);
if (!NT_SUCCESS(Status))
if (!ClassReferenceClassByNameOrAtom(&Class, ClassNameOrAtom, hInstance))
{
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
return FALSE;

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: window.c,v 1.232 2004/05/14 16:50:16 navaraf Exp $
/* $Id: window.c,v 1.233 2004/05/16 19:31:09 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -1413,6 +1413,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
CBT_CREATEWNDW CbtCreate;
LRESULT Result;
BOOL MenuChanged;
BOOL ClassFound;
LPWSTR OrigWindowName = NULL;
DPRINT("NtUserCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight);
@ -1488,16 +1489,16 @@ NtUserCreateWindowEx(DWORD dwExStyle,
/* FIXME: parent must belong to the current process */
/* Check the class. */
Status = ClassReferenceClassByNameOrAtom(&ClassObject, lpClassName->Buffer);
if (!NT_SUCCESS(Status))
{
RtlFreeUnicodeString(&WindowName);
if (NULL != ParentWindow)
{
IntReleaseWindowObject(ParentWindow);
}
return((HWND)0);
}
ClassFound = ClassReferenceClassByNameOrAtom(&ClassObject, lpClassName->Buffer, hInstance);
if (!ClassFound)
{
RtlFreeUnicodeString(&WindowName);
if (NULL != ParentWindow)
{
IntReleaseWindowObject(ParentWindow);
}
return((HWND)0);
}
/* Check the window station. */
DPRINT("IoGetCurrentProcess() %X\n", IoGetCurrentProcess());
@ -2304,6 +2305,7 @@ NtUserFindWindowEx(HWND hwndParent,
NTSTATUS Status;
HWND Desktop, Ret = NULL;
PWNDCLASS_OBJECT ClassObject = NULL;
BOOL ClassFound;
Desktop = IntGetDesktopWindow();
@ -2373,15 +2375,14 @@ NtUserFindWindowEx(HWND hwndParent,
if(ClassName.Buffer)
{
/* this expects the string in ClassName to be NULL-terminated! */
Status = ClassReferenceClassByNameOrAtom(&ClassObject, ClassName.Buffer);
if(!NT_SUCCESS(Status))
ClassFound = ClassReferenceClassByNameOrAtom(&ClassObject, ClassName.Buffer, NULL);
if(!ClassFound)
{
if (IS_ATOM(ClassName.Buffer))
DPRINT1("Window class not found (%lx)\n", (ULONG_PTR)ClassName.Buffer);
else
DPRINT1("Window class not found (%S)\n", ClassName.Buffer);
/* windows returns ERROR_FILE_NOT_FOUND !? */
SetLastWin32Error(ERROR_FILE_NOT_FOUND);
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
goto Cleanup;
}
}