- [Win32k] Class rewrite

- This is part 1, tested with Wine user32 class, Seamonkey, FireFox and AbiWord.
- Please refer to bug report 4778.

svn path=/trunk/; revision=43010
This commit is contained in:
James Tabor 2009-09-07 04:55:00 +00:00
parent f5617658a3
commit 5221d11896
21 changed files with 1045 additions and 877 deletions

View file

@ -1,9 +1,8 @@
/* $Id$
*
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS User32
* PURPOSE: Built-in control registration
* FILE: lib/user32/controls/regcontrol.c
* FILE: dll/win32/user32/controls/regcontrol.c
* PROGRAMER: Ge van Geldorp (ge@gse.nl)
* REVISION HISTORY: 2003/06/16 GvG Created
* NOTES: Adapted from Wine
@ -12,57 +11,76 @@
#include <user32.h>
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(user32);
DWORD RegisterDefaultClasses = FALSE;
static PFNCLIENT pfnClientA;
static PFNCLIENT pfnClientW;
static PFNCLIENTWORKER pfnClientWorker;
//
// FIXME!
// These are not "System Classes" but Global Classes that are registered
// every time a process is created, so these can be unregistered as the msdn
// documents states.
//
static const struct
{
const struct builtin_class_descr *desc;
UINT ClsId;
WORD fnid;
WORD ClsId;
} g_SysClasses[] =
{
{ &DIALOG_builtin_class, FNID_DIALOG },
{ &POPUPMENU_builtin_class, FNID_MENU },
{ &COMBO_builtin_class, FNID_COMBOBOX },
{ &COMBOLBOX_builtin_class, FNID_COMBOLBOX },
{ &MDICLIENT_builtin_class, FNID_MDICLIENT },
{ &DIALOG_builtin_class, FNID_DIALOG, ICLS_DIALOG},
/* { &POPUPMENU_builtin_class, FNID_MENU, ICLS_MENU}, // moved to win32k */
{ &COMBO_builtin_class, FNID_COMBOBOX, ICLS_COMBOBOX},
{ &COMBOLBOX_builtin_class, FNID_COMBOLBOX, ICLS_COMBOLBOX},
{ &MDICLIENT_builtin_class, FNID_MDICLIENT, ICLS_MDICLIENT},
#if 0
{ &MENU_builtin_class, FNID_MENU },
{ &MENU_builtin_class, FNID_MENU, ICLS_MENU},
#endif
{ &SCROLL_builtin_class, FNID_SCROLLBAR },
{ &BUTTON_builtin_class, FNID_BUTTON },
{ &LISTBOX_builtin_class, FNID_LISTBOX },
{ &EDIT_builtin_class, FNID_EDIT },
{ &ICONTITLE_builtin_class, FNID_ICONTITLE },
{ &STATIC_builtin_class, FNID_STATIC },
/* { &SCROLL_builtin_class, FNID_SCROLLBAR, ICLS_SCROLLBAR}, // moved to win32k */
{ &BUTTON_builtin_class, FNID_BUTTON, ICLS_BUTTON},
{ &LISTBOX_builtin_class, FNID_LISTBOX, ICLS_LISTBOX},
{ &EDIT_builtin_class, FNID_EDIT, ICLS_EDIT},
/* { &ICONTITLE_builtin_class, FNID_ICONTITLE, ICLS_ICONTITLE}, // moved to win32k */
{ &STATIC_builtin_class, FNID_STATIC, ICLS_STATIC},
};
BOOL WINAPI RegisterSystemControls(VOID)
{
REGISTER_SYSCLASS cls[sizeof(g_SysClasses) / sizeof(g_SysClasses[0])];
WNDCLASSEXW WndClass;
UINT i;
ATOM atom;
ZeroMemory(cls, sizeof(cls));
if (RegisterDefaultClasses) return TRUE;
for (i = 0; i != sizeof(cls) / sizeof(cls[0]); i++)
ZeroMemory(&WndClass, sizeof(WndClass));
WndClass.cbSize = sizeof(WndClass);
for (i = 0; i != sizeof(g_SysClasses) / sizeof(g_SysClasses[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);
WndClass.lpszClassName = g_SysClasses[i].desc->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;
// Set Global bit!
WndClass.style = g_SysClasses[i].desc->style|CS_GLOBALCLASS;
WndClass.lpfnWndProc = g_SysClasses[i].desc->procW;
WndClass.cbWndExtra = g_SysClasses[i].desc->extra;
WndClass.hCursor = LoadCursorW(NULL, g_SysClasses[i].desc->cursor);
WndClass.hbrBackground= g_SysClasses[i].desc->brush;
atom = RegisterClassExWOWW( &WndClass,
0,
g_SysClasses[i].fnid,
0,
FALSE);
if (atom)
RegisterDefaultClasses |= ICLASS_TO_MASK(g_SysClasses[i].ClsId);
}
return NtUserRegisterSystemClasses(sizeof(cls) / sizeof(cls[0]), cls);
return TRUE;
}
LRESULT

View file

@ -26,6 +26,7 @@ struct builtin_class_descr
HBRUSH brush; /* brush or system color */
};
extern DWORD RegisterDefaultClasses;
BOOL WINAPI RegisterSystemControls(VOID);
extern const struct builtin_class_descr BUTTON_builtin_class;
@ -42,4 +43,6 @@ extern const struct builtin_class_descr MENU_builtin_class;
extern const struct builtin_class_descr SCROLL_builtin_class;
extern const struct builtin_class_descr STATIC_builtin_class;
ATOM WINAPI RegisterClassExWOWW(WNDCLASSEXW *,LPDWORD,WORD,DWORD,BOOL);
#endif /* ROS_REGCONTROL_H */

View file

@ -117,9 +117,6 @@
#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;
extern HINSTANCE hImmInstance;

View file

@ -65,3 +65,4 @@ User32CreateWindowEx(DWORD dwExStyle,
BOOL Unicode);
HWND* WIN_ListChildren (HWND hWndparent);
ULONG_PTR FASTCALL IntGetWndProc(PWND, BOOL);

View file

@ -291,8 +291,7 @@ DllMain(
{
case DLL_PROCESS_ATTACH:
User32Instance = hInstanceDll;
if (!RegisterClientPFN() ||
!RegisterSystemControls())
if (!RegisterClientPFN())
{
return FALSE;
}

View file

@ -46,6 +46,12 @@ GetClassInfoExA(
return FALSE;
}
if (!RegisterDefaultClasses)
{
ERR("GetClassInfoExA RegisterSystemControls\n");
RegisterSystemControls();
}
if (IS_ATOM(lpszClass))
{
ClassName.Buffer = (PWSTR)((ULONG_PTR)lpszClass);
@ -113,6 +119,12 @@ GetClassInfoExW(
return FALSE;
}
if (!RegisterDefaultClasses)
{
ERR("GetClassInfoExW RegisterSystemControls\n");
RegisterSystemControls();
}
if (IS_ATOM(lpszClass))
{
ClassName.Buffer = (PWSTR)((ULONG_PTR)lpszClass);
@ -198,6 +210,126 @@ GetClassInfoW(
return retval;
}
//
// Based on find_winproc... Fixes many whine tests......
//
ULONG_PTR FASTCALL
IntGetClsWndProc(PWND pWnd, PCLS Class, BOOL Ansi)
{
INT i;
ULONG_PTR gcpd, Ret = 0;
// If server side, sweep through proc list and return the client side proc.
if (Class->CSF_flags & CSF_SERVERSIDEPROC)
{ // Always scan through the list due to wine class "deftest".
for ( i = FNID_FIRST; i <= FNID_SWITCH; i++)
{
if (GETPFNSERVER(i) == Class->lpfnWndProc)
{
if (Ansi)
Ret = (ULONG_PTR)GETPFNCLIENTA(i);
else
Ret = (ULONG_PTR)GETPFNCLIENTW(i);
}
}
return Ret;
}
// Set return proc.
Ret = (ULONG_PTR)Class->lpfnWndProc;
// Return the proc if one of the FnId default class type.
if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON)
{
if (Ansi)
{ // If match return the right proc by type.
if (GETPFNCLIENTW(Class->fnid) == Class->lpfnWndProc)
Ret = (ULONG_PTR)GETPFNCLIENTA(Class->fnid);
}
else
{
if (GETPFNCLIENTA(Class->fnid) == Class->lpfnWndProc)
Ret = (ULONG_PTR)GETPFNCLIENTW(Class->fnid);
}
}
// Return on change or Ansi/Unicode proc equal.
if ( Ret != (ULONG_PTR)Class->lpfnWndProc ||
Ansi == !!(Class->CSF_flags & CSF_ANSIPROC) )
return Ret;
/* We have an Ansi and Unicode swap! If Ansi create Unicode proc handle.
This will force CallWindowProc to deal with it. */
gcpd = NtUserGetCPD( UserHMGetHandle(pWnd),
(Ansi ? UserGetCPDA2U : UserGetCPDU2A )|UserGetCPDWndtoCls,
Ret);
return (gcpd ? gcpd : Ret);
}
//
// Based on IntGetClsWndProc
//
ULONG_PTR FASTCALL
IntGetWndProc(PWND pWnd, BOOL Ansi)
{
INT i;
ULONG_PTR gcpd, Ret = 0;
PCLS Class = DesktopPtrToUser(pWnd->pcls);
if (!Class) return Ret;
if (pWnd->state & WNDS_SERVERSIDEWINDOWPROC)
{
for ( i = FNID_FIRST; i <= FNID_SWITCH; i++)
{
if (GETPFNSERVER(i) == pWnd->lpfnWndProc)
{
if (Ansi)
Ret = (ULONG_PTR)GETPFNCLIENTA(i);
else
Ret = (ULONG_PTR)GETPFNCLIENTW(i);
}
}
return Ret;
}
// Wine Class tests:
/* Edit controls are special - they return a wndproc handle when
GetWindowLongPtr is called with a different A/W.
On the other hand there is no W->A->W conversion so this control
is treated specially.
*/
if (Class->fnid == FNID_EDIT)
Ret = (ULONG_PTR)pWnd->lpfnWndProc;
else
{
// Set return proc.
Ret = (ULONG_PTR)pWnd->lpfnWndProc;
if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON)
{
if (Ansi)
{
if (GETPFNCLIENTW(Class->fnid) == pWnd->lpfnWndProc)
Ret = (ULONG_PTR)GETPFNCLIENTA(Class->fnid);
}
else
{
if (GETPFNCLIENTA(Class->fnid) == pWnd->lpfnWndProc)
Ret = (ULONG_PTR)GETPFNCLIENTW(Class->fnid);
}
}
// Return on the change.
if ( Ret != (ULONG_PTR)pWnd->lpfnWndProc)
return Ret;
}
if ( Ansi == !!(pWnd->state & WNDS_ANSIWINDOWPROC) )
return Ret;
gcpd = NtUserGetCPD( UserHMGetHandle(pWnd),
(Ansi ? UserGetCPDA2U : UserGetCPDU2A )|UserGetCPDWindow,
Ret);
return (gcpd ? gcpd : Ret);
}
/*
* @implemented
*/
@ -248,6 +380,7 @@ GetClassLongA(HWND hWnd, int nIndex)
break;
case GCL_HMODULE:
//ERR("Cls 0x%x GCL_HMODULE 0x%x\n", Wnd->pcls, Class->hModule);
Ret = (ULONG_PTR)Class->hModule;
break;
@ -279,9 +412,7 @@ GetClassLongA(HWND hWnd, int nIndex)
break;
case GCLP_WNDPROC:
/* We need to make a call to win32k as it may be required to
create a callproc handle */
Wnd = NULL;
Ret = IntGetClsWndProc(Wnd, Class, TRUE);
break;
default:
@ -392,9 +523,7 @@ GetClassLongW ( HWND hWnd, int nIndex )
break;
case GCLP_WNDPROC:
/* We need to make a call to win32k as it may be required to
create a callproc handle */
Wnd = NULL;
Ret = IntGetClsWndProc(Wnd, Class, FALSE);
break;
default:
@ -523,7 +652,6 @@ GetWindowLongA ( HWND hWnd, int nIndex )
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
return *((LONG *)((PCHAR)(Wnd + 1) + nIndex));
}
else
@ -548,9 +676,12 @@ GetWindowLongA ( HWND hWnd, int nIndex )
return (LONG)parent;
}
case GWL_WNDPROC:
/* Call win32k for this as a callproc handle may need
to be created */
return NtUserGetWindowLong(hWnd, nIndex, TRUE);
if (!TestWindowProcess(Wnd))
{
SetLastError(ERROR_ACCESS_DENIED);
return 0;
}
return IntGetWndProc(Wnd, TRUE);
default:
SetLastError(ERROR_INVALID_PARAMETER);
@ -580,7 +711,6 @@ GetWindowLongW(HWND hWnd, int nIndex)
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
return *((LONG *)((PCHAR)(Wnd + 1) + nIndex));
}
else
@ -605,9 +735,12 @@ GetWindowLongW(HWND hWnd, int nIndex)
return (LONG)parent;
}
case GWL_WNDPROC:
/* Call win32k for this as a callproc handle may need
to be created */
return NtUserGetWindowLong(hWnd, nIndex, FALSE);
if (!TestWindowProcess(Wnd))
{
SetLastError(ERROR_ACCESS_DENIED);
return 0;
}
return IntGetWndProc(Wnd, FALSE);
default:
SetLastError(ERROR_INVALID_PARAMETER);
@ -834,7 +967,8 @@ ATOM WINAPI
RegisterClassExWOWW(WNDCLASSEXW *lpwcx,
LPDWORD pdwWowData,
WORD fnID,
DWORD dwFlags)
DWORD dwFlags,
BOOL ChkRegCls)
{
ATOM Atom;
WNDCLASSEXW WndClass;
@ -847,16 +981,31 @@ RegisterClassExWOWW(WNDCLASSEXW *lpwcx,
lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
lpwcx->lpszClassName == NULL)
{
ERR("RegisterClassExWOWW Invalid Parameter Error!\n");
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (ChkRegCls)
{
if (!RegisterDefaultClasses) RegisterSystemControls();
}
/*
* 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
GetWin32ClientInfo()->dwExpWinVer & (WINVER == 0x400)
*/
if (lpwcx->hInstance == User32Instance)
{
ERR("RegisterClassExWOWW User32Instance!\n");
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
/* Yes, this is correct. We should modify the passed structure. */
if (lpwcx->hInstance == NULL)
((WNDCLASSEXW*)lpwcx)->hInstance = GetModuleHandleW(NULL);
@ -875,11 +1024,13 @@ RegisterClassExWOWW(WNDCLASSEXW *lpwcx,
if (WndClass.lpszMenuName[0])
{
RtlInitUnicodeString(&MenuName, WndClass.lpszMenuName);
RtlUnicodeStringToAnsiString( &AnsiMenuName, &MenuName, TRUE);
}
}
else
{
MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
AnsiMenuName.Buffer = (PCHAR)WndClass.lpszMenuName;
}
}
@ -894,8 +1045,6 @@ RegisterClassExWOWW(WNDCLASSEXW *lpwcx,
RtlInitUnicodeString(&ClassName, WndClass.lpszClassName);
}
RtlUnicodeStringToAnsiString( &AnsiMenuName, &MenuName, TRUE);
clsMenuName.pszClientAnsiMenuName = AnsiMenuName.Buffer;
clsMenuName.pwszClientUnicodeMenuName = MenuName.Buffer;
clsMenuName.pusMenuName = &MenuName;
@ -922,89 +1071,42 @@ ATOM WINAPI
RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
{
RTL_ATOM Atom;
WNDCLASSEXA WndClass;
UNICODE_STRING ClassName;
UNICODE_STRING MenuName = {0};
CLSMENUNAME clsMenuName;
ANSI_STRING AnsiMenuName;
if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXA) ||
lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
lpwcx->lpszClassName == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (lpwcx->hInstance == User32Instance)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
/* Yes, this is correct. We should modify the passed structure. */
if (lpwcx->hInstance == NULL)
((WNDCLASSEXA*)lpwcx)->hInstance = GetModuleHandleW(NULL);
WNDCLASSEXW WndClass;
WCHAR mname[MAX_BUFFER_LEN];
WCHAR cname[MAX_BUFFER_LEN];
RtlCopyMemory(&WndClass, lpwcx, sizeof(WNDCLASSEXA));
if (NULL == WndClass.hIconSm)
{
WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon);
}
if (WndClass.lpszMenuName != NULL)
{
if (!IS_INTRESOURCE(WndClass.lpszMenuName))
{
if (WndClass.lpszMenuName[0])
{
RtlCreateUnicodeStringFromAsciiz(&MenuName, WndClass.lpszMenuName);
if (!MultiByteToWideChar( CP_ACP, 0, lpwcx->lpszMenuName, -1, mname, MAX_ATOM_LEN + 1 )) return 0;
WndClass.lpszMenuName = mname;
}
}
else
{
MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
}
}
if (IS_ATOM(WndClass.lpszClassName))
if (!IS_ATOM(WndClass.lpszClassName))
{
ClassName.Length =
ClassName.MaximumLength = 0;
ClassName.Buffer = (LPWSTR)WndClass.lpszClassName;
}
else
{
RtlCreateUnicodeStringFromAsciiz(&ClassName, WndClass.lpszClassName);
if (!MultiByteToWideChar( CP_ACP, 0, lpwcx->lpszClassName, -1, cname, MAX_ATOM_LEN + 1 )) return 0;
WndClass.lpszClassName = cname;
}
RtlUnicodeStringToAnsiString( &AnsiMenuName, &MenuName, TRUE);
clsMenuName.pszClientAnsiMenuName = AnsiMenuName.Buffer;
clsMenuName.pwszClientUnicodeMenuName = MenuName.Buffer;
clsMenuName.pusMenuName = &MenuName;
Atom = NtUserRegisterClassExWOW( (WNDCLASSEXW*)&WndClass,
&ClassName,
NULL, //PUNICODE_STRING ClsNVersion,
&clsMenuName,
0,
CSF_ANSIPROC,
0);
Atom = RegisterClassExWOWW( &WndClass,
0,
0,
CSF_ANSIPROC,
TRUE);
TRACE("A atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
Atom, lpwcx->lpfnWndProc, lpwcx->hInstance, lpwcx->hbrBackground,
lpwcx->style, lpwcx->cbClsExtra, lpwcx->cbWndExtra, WndClass);
if (!IS_INTRESOURCE(WndClass.lpszMenuName))
{
RtlFreeUnicodeString(&MenuName);
RtlFreeAnsiString(&AnsiMenuName);
}
if (!IS_ATOM(WndClass.lpszClassName))
RtlFreeUnicodeString(&ClassName);
return (ATOM)Atom;
}
@ -1015,90 +1117,12 @@ ATOM WINAPI
RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
{
ATOM Atom;
WNDCLASSEXW WndClass;
UNICODE_STRING ClassName;
UNICODE_STRING MenuName = {0};
CLSMENUNAME clsMenuName;
ANSI_STRING AnsiMenuName;
if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXW) ||
lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
lpwcx->lpszClassName == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
Atom = RegisterClassExWOWW( (WNDCLASSEXW *)lpwcx, 0, 0, 0, TRUE);
/*
* 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
GetWin32ClientInfo()->ulWindowsVersion & (WINVER == 400)
*/
if (lpwcx->hInstance == User32Instance)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
/* Yes, this is correct. We should modify the passed structure. */
if (lpwcx->hInstance == NULL)
((WNDCLASSEXW*)lpwcx)->hInstance = GetModuleHandleW(NULL);
RtlCopyMemory(&WndClass, lpwcx, sizeof(WNDCLASSEXW));
if (NULL == WndClass.hIconSm)
{
WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon);
}
if (WndClass.lpszMenuName != NULL)
{
if (!IS_INTRESOURCE(WndClass.lpszMenuName))
{
if (WndClass.lpszMenuName[0])
{
RtlInitUnicodeString(&MenuName, WndClass.lpszMenuName);
}
}
else
{
MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
}
}
if (IS_ATOM(WndClass.lpszClassName))
{
ClassName.Length =
ClassName.MaximumLength = 0;
ClassName.Buffer = (LPWSTR)WndClass.lpszClassName;
}
else
{
RtlInitUnicodeString(&ClassName, WndClass.lpszClassName);
}
RtlUnicodeStringToAnsiString( &AnsiMenuName, &MenuName, TRUE);
clsMenuName.pszClientAnsiMenuName = AnsiMenuName.Buffer;
clsMenuName.pwszClientUnicodeMenuName = MenuName.Buffer;
clsMenuName.pusMenuName = &MenuName;
Atom = NtUserRegisterClassExWOW( &WndClass,
&ClassName,
NULL, //PUNICODE_STRING ClsNVersion,
&clsMenuName,
0,
0,
0);
TRACE("W atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
TRACE("W atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d\n",
Atom, lpwcx->lpfnWndProc, lpwcx->hInstance, lpwcx->hbrBackground,
lpwcx->style, lpwcx->cbClsExtra, lpwcx->cbWndExtra, WndClass);
lpwcx->style, lpwcx->cbClsExtra, lpwcx->cbWndExtra);
return Atom;
}
@ -1153,8 +1177,6 @@ SetClassLongA (HWND hWnd,
BOOL Allocated = FALSE;
DWORD Ret;
TRACE("%p %d %lx\n", hWnd, nIndex, dwNewLong);
/* FIXME - portability!!!! */
if (nIndex == GCL_MENUNAME && lpStr != NULL)

View file

@ -1221,6 +1221,58 @@ IntCallWindowProcA(BOOL IsAnsiProc,
}
static LRESULT WINAPI
IntCallMessageProc(IN PWND Wnd, IN HWND hWnd, IN UINT Msg, IN WPARAM wParam, IN LPARAM lParam, IN BOOL Ansi)
{
WNDPROC WndProc;
BOOL IsAnsi;
PCLS Class;
Class = DesktopPtrToUser(Wnd->pcls);
WndProc = NULL;
/*
This is the message exchange for user32. If there's a need to monitor messages,
do it here!
*/
TRACE("HWND 0x%x, MSG %d, WPARAM 0x%x, LPARAM 0x%x, Ansi &d\n",hWnd,Msg,wParam,lParam,Ansi);
// if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON )
if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_FIRST )
{
if (Ansi)
{
if (GETPFNCLIENTW(Class->fnid) == Wnd->lpfnWndProc)
WndProc = GETPFNCLIENTA(Class->fnid);
}
else
{
if (GETPFNCLIENTA(Class->fnid) == Wnd->lpfnWndProc)
WndProc = GETPFNCLIENTW(Class->fnid);
}
IsAnsi = Ansi;
if (!WndProc)
{
IsAnsi = !Wnd->Unicode;
WndProc = Wnd->lpfnWndProc;
}
}
else
{
IsAnsi = !Wnd->Unicode;
WndProc = Wnd->lpfnWndProc;
}
/*
Message caller can be Ansi/Unicode and the receiver can be Unicode/Ansi or
the same.
*/
if (!Ansi)
return IntCallWindowProcW(IsAnsi, WndProc, hWnd, Msg, wParam, lParam);
else
return IntCallWindowProcA(IsAnsi, WndProc, hWnd, Msg, wParam, lParam);
}
/*
* @implemented
*/
@ -1246,8 +1298,12 @@ CallWindowProcA(WNDPROC lpPrevWndFunc,
CallProc = ValidateCallProc((HANDLE)lpPrevWndFunc);
if (CallProc != NULL)
{
return IntCallWindowProcA(!CallProc->Unicode, CallProc->pfnClientPrevious,
hWnd, Msg, wParam, lParam);
return IntCallWindowProcA(!(CallProc->wType & UserGetCPDA2U),
CallProc->pfnClientPrevious,
hWnd,
Msg,
wParam,
lParam);
}
else
{
@ -1284,8 +1340,12 @@ CallWindowProcW(WNDPROC lpPrevWndFunc,
CallProc = ValidateCallProc((HANDLE)lpPrevWndFunc);
if (CallProc != NULL)
{
return IntCallWindowProcW(!CallProc->Unicode, CallProc->pfnClientPrevious,
hWnd, Msg, wParam, lParam);
return IntCallWindowProcW(!(CallProc->wType & UserGetCPDA2U),
CallProc->pfnClientPrevious,
hWnd,
Msg,
wParam,
lParam);
}
else
{
@ -1296,30 +1356,6 @@ CallWindowProcW(WNDPROC lpPrevWndFunc,
}
static LRESULT WINAPI
IntCallMessageProc(IN PWND Wnd, IN HWND hWnd, IN UINT Msg, IN WPARAM wParam, IN LPARAM lParam, IN BOOL Ansi)
{
WNDPROC WndProc;
BOOL IsAnsi;
if (Wnd->IsSystem)
{
WndProc = (Ansi ? Wnd->WndProcExtra : Wnd->lpfnWndProc);
IsAnsi = Ansi;
}
else
{
WndProc = Wnd->lpfnWndProc;
IsAnsi = !Wnd->Unicode;
}
if (!Ansi)
return IntCallWindowProcW(IsAnsi, WndProc, hWnd, Msg, wParam, lParam);
else
return IntCallWindowProcA(IsAnsi, WndProc, hWnd, Msg, wParam, lParam);
}
/*
* @implemented
*/
@ -1353,8 +1389,7 @@ DispatchMessageA(CONST MSG *lpmsg)
}
else if (Wnd != NULL)
{
// FIXME Need to test for calling proc inside win32k!
if ( (lpmsg->message != WM_PAINT) ) // && !(Wnd->state & WNDS_SERVERSIDEWINDOWPROC) )
if ( (lpmsg->message != WM_PAINT) && !(Wnd->state & WNDS_SERVERSIDEWINDOWPROC) )
{
Ret = IntCallMessageProc(Wnd,
lpmsg->hwnd,
@ -1414,8 +1449,7 @@ DispatchMessageW(CONST MSG *lpmsg)
}
else if (Wnd != NULL)
{
// FIXME Need to test for calling proc inside win32k!
if ( (lpmsg->message != WM_PAINT) ) // && !(Wnd->state & WNDS_SERVERSIDEWINDOWPROC) )
if ( (lpmsg->message != WM_PAINT) && !(Wnd->state & WNDS_SERVERSIDEWINDOWPROC) )
{
Ret = IntCallMessageProc(Wnd,
lpmsg->hwnd,
@ -2328,9 +2362,12 @@ User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
{
}
CallbackArgs->Result = IntCallWindowProcW(CallbackArgs->IsAnsiProc, CallbackArgs->Proc,
UMMsg.hwnd, UMMsg.message,
UMMsg.wParam, UMMsg.lParam);
CallbackArgs->Result = IntCallWindowProcW( CallbackArgs->IsAnsiProc,
CallbackArgs->Proc,
UMMsg.hwnd,
UMMsg.message,
UMMsg.wParam,
UMMsg.lParam);
if (! MsgiKMToUMReply(&KMMsg, &UMMsg, &CallbackArgs->Result))
{

View file

@ -174,6 +174,12 @@ User32CreateWindowEx(DWORD dwExStyle,
DbgPrint("[window] User32CreateWindowEx style %d, exstyle %d, parent %d\n", dwStyle, dwExStyle, hWndParent);
#endif
if (!RegisterDefaultClasses)
{
ERR("User32CreateWindowEx RegisterSystemControls\n");
RegisterSystemControls();
}
if (IS_ATOM(lpClassName))
{
RtlInitUnicodeString(&ClassName, NULL);
@ -281,6 +287,12 @@ CreateWindowExA(DWORD dwExStyle,
MDICREATESTRUCTA mdi;
HWND hwnd;
if (!RegisterDefaultClasses)
{
ERR("CreateWindowExA RegisterSystemControls\n");
RegisterSystemControls();
}
if (dwExStyle & WS_EX_MDICHILD)
{
POINT mPos[2];
@ -387,6 +399,12 @@ CreateWindowExW(DWORD dwExStyle,
MDICREATESTRUCTW mdi;
HWND hwnd;
if (!RegisterDefaultClasses)
{
ERR("CreateWindowExW RegisterSystemControls\n");
RegisterSystemControls();
}
if (dwExStyle & WS_EX_MDICHILD)
{
POINT mPos[2];

View file

@ -167,14 +167,14 @@ typedef struct _REGISTER_SYSCLASS
{
/* This is a reactos specific class used to initialize the
system window classes during user32 initialization */
UNICODE_STRING ClassName;
PWSTR ClassName;
UINT Style;
WNDPROC ProcW;
WNDPROC ProcA;
UINT ExtraBytes;
HICON hCursor;
HBRUSH hBrush;
UINT ClassId;
WORD fiId;
WORD iCls;
} REGISTER_SYSCLASS, *PREGISTER_SYSCLASS;
typedef struct _CLSMENUNAME
@ -201,8 +201,8 @@ typedef struct tagSBINFO
typedef enum _GETCPD
{
UserGetCPDU2A = 0x01,
UserGetCPDA2U = 0X02,
UserGetCPDA2U = 0x01, // " Unicode "
UserGetCPDU2A = 0X02, // " Ansi "
UserGetCPDClass = 0X10,
UserGetCPDWindow = 0X20,
UserGetCPDDialog = 0X40,
@ -214,11 +214,7 @@ typedef struct _CALLPROCDATA
PROCDESKHEAD head;
struct _CALLPROCDATA *spcpdNext;
WNDPROC pfnClientPrevious;
union
{
GETCPD wType;
UINT Unicode : 1;
};
GETCPD wType;
} CALLPROCDATA, *PCALLPROCDATA;
#define CSF_SERVERSIDEPROC 0x0001
@ -247,11 +243,6 @@ typedef struct _CLS
ULONG cWndReferenceCount;
UINT style;
WNDPROC lpfnWndProc;
union
{
WNDPROC WndProcExtra;
PCALLPROCDATA CallProc;
};
INT cbclsExtra;
INT cbwndExtra;
HINSTANCE hModule;
@ -265,12 +256,10 @@ typedef struct _CLS
HANDLE hIconSm; /* FIXME - Use pointer! */
//PCURSOR spicnSm;
UINT Destroying : 1; // CSF_WOWDEFERDESTROY
UINT Unicode : 1; // !CSF_ANSIPROC
UINT System : 1; // CSF_SYSTEMCLASS
UINT Global : 1; // CS_GLOBALCLASS
UINT Global : 1; // CS_GLOBALCLASS or CSF_SERVERSIDEPROC
UINT MenuNameIsString : 1;
UINT NotUsed : 27;
UINT NotUsed : 29;
} CLS, *PCLS;
@ -342,10 +331,12 @@ typedef struct _CLS
/* Non SDK ExStyles */
#define WS_EX_MAKEVISIBLEWHENUNGHOSTED 0x00000800
#define WS_EX_FORCELEGACYRESIZENCMETR 0x00800000
#define WS_EX_UISTATEACTIVE 0x04000000
#define WS_EX_REDIRECTED 0X20000000
#define WS_EX_UISTATEKBACCELHIDDEN 0X40000000
#define WS_EX_UISTATEFOCUSRECTHIDDEN 0X80000000
#define WS_EX_SETANSICREATOR 0x80000000 // For WNDS_ANSICREATOR
/* Non SDK Styles */
#define WS_MAXIMIZED WS_MAXIMIZE
@ -385,14 +376,6 @@ typedef struct _WND
RECT rcWindow;
RECT rcClient;
WNDPROC lpfnWndProc;
union
{
/* Pointer to a call procedure handle */
PCALLPROCDATA CallProc;
/* Extra Wnd proc (windows of system classes) */
WNDPROC WndProcExtra;
};
/* Pointer to the window class. */
PCLS pcls;
HRGN hrgnUpdate;
@ -431,7 +414,6 @@ typedef struct _WND
UINT Unicode : 1; // !(WNDS_ANSICREATOR|WNDS_ANSIWINDOWPROC) ?
/* Indicates whether the window is derived from a system class */
UINT IsSystem : 1; // System class ?
UINT InternalPosInitialized : 1;
UINT HideFocus : 1; // WS_EX_UISTATEFOCUSRECTHIDDEN ?
UINT HideAccel : 1; // WS_EX_UISTATEKBACCELHIDDEN ?
@ -525,10 +507,21 @@ typedef LONG_PTR (NTAPI *PFN_FNID)(PWND, UINT, WPARAM, LPARAM, ULONG_PTR);
#define FNID_LAST 0x02B9
#define FNID_NUM FNID_LAST - FNID_FIRST + 1
#define FNID_NUMSERVERPROC FNID_SWITCH - FNID_FIRST + 1
#define FNID_DDEML 0x2000 // Registers DDEML
#define FNID_DESTROY 0x4000 // This is sent when WM_NCDESTROY or in the support routine.
// Seen during WM_CREATE on error exit too.
#define FNID_FREED 0x8000 // Window being Freed...
#define ICLASS_TO_MASK(iCls) (1 << ((iCls)))
#define GETPFNCLIENTA(fnid)\
(WNDPROC)(*(((ULONG_PTR *)&gpsi->apfnClientA) + (fnid - FNID_FIRST)))
#define GETPFNCLIENTW(fnid)\
(WNDPROC)(*(((ULONG_PTR *)&gpsi->apfnClientW) + (fnid - FNID_FIRST)))
#define GETPFNSERVER(fnid) gpsi->aStoCidPfn[fnid - FNID_FIRST]
// ICLS's for NtUserGetClassName FNID to ICLS, NtUserInitializeClientPfnArrays
#define ICLS_BUTTON 0
@ -641,7 +634,7 @@ typedef struct tagSERVERINFO
DWORD dwSRVIFlags;
ULONG_PTR cHandleEntries;
PFN_FNID mpFnidPfn[FNID_NUM];
WNDPROC aStoCidPfn[7];
WNDPROC aStoCidPfn[FNID_NUMSERVERPROC];
USHORT mpFnid_serverCBWndProc[FNID_NUM];
PFNCLIENT apfnClientA;
PFNCLIENT apfnClientW;
@ -1374,7 +1367,7 @@ NtUserCreateWindowEx(
HWND
NTAPI
NtUserCreateWindowEx(
DWORD dwExStyle,
DWORD dwExStyle, // |= 0x80000000 == Ansi used to set WNDS_ANSICREATOR
PLARGE_STRING plstrClassName,
PLARGE_STRING plstrClsVesrion,
PLARGE_STRING plstrWindowName,
@ -1387,7 +1380,7 @@ NtUserCreateWindowEx(
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam,
DWORD dwFlags, // |= 1 == Ansi
DWORD dwFlags,
PVOID acbiBuffer);
#endif
@ -3053,7 +3046,6 @@ typedef struct tagKMDDELPARAM
#define TWOPARAM_ROUTINE_REGISTERLOGONPROC 0xfffd0062
#define TWOPARAM_ROUTINE_ROS_ISACTIVEICON 0x1001
#define TWOPARAM_ROUTINE_ROS_NCDESTROY 0x1002
#define TWOPARAM_ROUTINE_ROS_REGSYSCLASSES 0x1003
#define TWOPARAM_ROUTINE_ROS_UPDATEUISTATE 0x1004
DWORD

View file

@ -58,13 +58,13 @@ RTL_ATOM
UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx,
IN PUNICODE_STRING ClassName,
IN PUNICODE_STRING MenuName,
IN WNDPROC wpExtra,
IN DWORD fnID,
IN DWORD dwFlags);
BOOL
UserUnregisterClass(IN PUNICODE_STRING ClassName,
IN HINSTANCE hInstance);
IN HINSTANCE hInstance,
OUT PCLSMENUNAME pClassMenuName);
ULONG_PTR
UserGetClassLongPtr(IN PCLS Class,
@ -83,20 +83,12 @@ FASTCALL
IntCreateClass(IN CONST WNDCLASSEXW* lpwcx,
IN PUNICODE_STRING ClassName,
IN PUNICODE_STRING MenuName,
IN WNDPROC wpExtra,
IN DWORD fnID,
IN DWORD dwFlags,
IN PDESKTOP Desktop,
IN PPROCESSINFO pi);
PCALLPROCDATA
UserFindCallProc(IN PCLS Class,
IN WNDPROC WndProc,
IN BOOL bUnicode);
BOOL
UserRegisterSystemClasses(IN ULONG Count,
IN PREGISTER_SYSCLASS SystemClasses);
BOOL FASTCALL UserRegisterSystemClasses(VOID);
VOID
UserAddCallProcToClass(IN OUT PCLS Class,
@ -110,6 +102,10 @@ BOOL
IntCheckProcessDesktopClasses(IN PDESKTOP Desktop,
IN BOOL FreeOnFailure);
BOOL FASTCALL LookupFnIdToiCls(int, int * );
WNDPROC FASTCALL IntGetClassWndProc(PCLS, BOOL);
ULONG_PTR FASTCALL UserGetCPD(PVOID,GETCPD,ULONG_PTR);
#endif /* _WIN32K_CLASS_H */
/* EOF */

View file

@ -31,6 +31,37 @@
#define W32PF_MANUALGUICHECK (0x02000000)
#define W32PF_CREATEDWINORDC (0x04000000)
/* THREADINFO Flags */
#define TIF_INCLEANUP 0x00000001
#define TIF_16BIT 0x00000002
#define TIF_SYSTEMTHREAD 0x00000004
#define TIF_CSRSSTHREAD 0x00000008
#define TIF_TRACKRECTVISIBLE 0x00000010
#define TIF_ALLOWFOREGROUNDACTIVATE 0x00000020
#define TIF_DONTATTACHQUEUE 0x00000040
#define TIF_DONTJOURNALATTACH 0x00000080
#define TIF_WOW64 0x00000100
#define TIF_INACTIVATEAPPMSG 0x00000200
#define TIF_SPINNING 0x00000400
#define TIF_PALETTEAWARE 0x00000800
#define TIF_SHAREDWOW 0x00001000
#define TIF_FIRSTIDLE 0x00002000
#define TIF_WAITFORINPUTIDLE 0x00004000
#define TIF_MOVESIZETRACKING 0x00008000
#define TIF_VDMAPP 0x00010000
#define TIF_DOSEMULATOR 0x00020000
#define TIF_GLOBALHOOKER 0x00040000
#define TIF_DELAYEDEVENT 0x00080000
#define TIF_MSGPOSCHANGED 0x00100000
#define TIF_SHUTDOWNCOMPLETE 0x00200000
#define TIF_IGNOREPLAYBACKDELAY 0x00400000
#define TIF_ALLOWOTHERACCOUNTHOOK 0x00800000
#define TIF_GUITHREADINITIALIZED 0x02000000
#define TIF_DISABLEIME 0x04000000
#define TIF_INGETTEXTLENGTH 0x08000000
#define TIF_ANSILENGTH 0x10000000
#define TIF_DISABLEHOOKS 0x20000000
extern BOOL ClientPfnInit;
extern HINSTANCE hModClient;
extern HANDLE hModuleWin; // This Win32k Instance.
@ -86,7 +117,7 @@ typedef struct _THREADINFO
/* ReactOS */
LIST_ENTRY WindowListHead;
LIST_ENTRY W32CallbackListHead;
BOOLEAN IsExiting;
BOOLEAN IsExiting; // Use TIF_INCLEANUP
SINGLE_LIST_ENTRY ReferencesList;
} THREADINFO;
@ -135,7 +166,7 @@ typedef struct _PROCESSINFO
LIST_ENTRY PrivateFontListHead;
FAST_MUTEX DriverObjListLock;
LIST_ENTRY DriverObjListHead;
struct _KBL* KeyboardLayout;
struct _KBL* KeyboardLayout; // THREADINFO only
W32HEAP_USER_MAPPING HeapMappings;
} PROCESSINFO;

View file

@ -67,14 +67,14 @@ typedef struct _WINDOW_OBJECT
} WINDOW_OBJECT; /* PWINDOW_OBJECT already declared at top of file */
/* Window flags. */
#define WINDOWOBJECT_NEED_SIZE (0x00000001)
#define WINDOWOBJECT_NEED_ERASEBKGND (0x00000002)
#define WINDOWOBJECT_NEED_NCPAINT (0x00000004)
#define WINDOWOBJECT_NEED_INTERNALPAINT (0x00000008)
#define WINDOWOBJECT_NEED_SIZE (0x00000001) // WNDS_SENDSIZEMOVEMSGS?
#define WINDOWOBJECT_NEED_ERASEBKGND (0x00000002) // WNDS_ERASEBACKGROUND
#define WINDOWOBJECT_NEED_NCPAINT (0x00000004) // WNDS_SENDNCPAINT
#define WINDOWOBJECT_NEED_INTERNALPAINT (0x00000008) // WNDS_INTERNALPAINT
#define WINDOWOBJECT_RESTOREMAX (0x00000020)
#define WINDOWSTATUS_DESTROYING (0x1)
#define WINDOWSTATUS_DESTROYED (0x2)
#define WINDOWSTATUS_DESTROYING (0x1) // WNDS2_INDESTROY
#define WINDOWSTATUS_DESTROYED (0x2) // WNDS_DESTROYED
#define HAS_DLGFRAME(Style, ExStyle) \
(((ExStyle) & WS_EX_DLGMODALFRAME) || \
@ -172,6 +172,8 @@ IntDefWindowProc( PWINDOW_OBJECT Window, UINT Msg, WPARAM wParam, LPARAM lParam,
VOID FASTCALL IntNotifyWinEvent(DWORD, PWND, LONG, LONG);
PWND APIENTRY co_IntCreateWindowEx(DWORD,PUNICODE_STRING,PUNICODE_STRING,DWORD,LONG,LONG,LONG,LONG,HWND,HMENU,HINSTANCE,LPVOID,DWORD,BOOL);
WNDPROC FASTCALL IntGetWindowProc(PWND,BOOL);
#endif /* _WIN32K_WINDOW_H */
/* EOF */

View file

@ -384,7 +384,7 @@ DriverEntry (
}
hModuleWin = MmPageEntireDriver(DriverEntry);
DPRINT("Win32k hInstance 0x%x!\n",hModuleWin);
/*
* Register Object Manager Callbacks
*/

View file

@ -50,7 +50,7 @@ CloneCallProc(IN PDESKTOPINFO Desktop,
{
NewCallProc->head.h = Handle;
NewCallProc->pfnClientPrevious = CallProc->pfnClientPrevious;
NewCallProc->Unicode = CallProc->Unicode;
NewCallProc->wType = CallProc->wType;
NewCallProc->spcpdNext = NULL;
}
@ -75,7 +75,7 @@ CreateCallProc(IN PDESKTOPINFO Desktop,
{
NewCallProc->head.h = Handle;
NewCallProc->pfnClientPrevious = WndProc;
NewCallProc->Unicode = Unicode;
NewCallProc->wType |= Unicode ? UserGetCPDA2U : UserGetCPDU2A ;
NewCallProc->spcpdNext = NULL;
}
@ -106,7 +106,7 @@ UserGetCallProcInfo(IN HANDLE hCallProc,
}*/
wpInfo->WindowProc = CallProc->pfnClientPrevious;
wpInfo->IsUnicode = CallProc->Unicode;
wpInfo->IsUnicode = !!(CallProc->wType & UserGetCPDA2U);
return TRUE;
}
@ -164,7 +164,7 @@ UserGetCPD(
{
CallProc = CreateCallProc( NULL,
(WNDPROC)ProcIn,
(Flags & UserGetCPDU2A),
!!(Flags & UserGetCPDA2U),
pti->ppi);
if (CallProc)
{

File diff suppressed because it is too large Load diff

View file

@ -912,10 +912,7 @@ NtUserCreateDesktop(
HWINSTA hWindowStation = NULL ;
PUNICODE_STRING lpszDesktopName = NULL;
UNICODE_STRING ClassName, WindowName, MenuName;
PPROCESSINFO pi = GetW32ProcessInfo();
WNDCLASSEXW wc;
PCLS Class;
PWND pWnd;
PWND pWnd = NULL;
DECLARE_RETURN(HDESK);
DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName);
@ -1112,44 +1109,11 @@ NtUserCreateDesktop(
Based on wine/server/window.c in get_desktop_window.
*/
ClassName.Buffer = ((PWSTR)((ULONG_PTR)(WORD)(AtomMessage)));
ClassName.Buffer = ((PWSTR)((ULONG_PTR)(WORD)(gpsi->atomSysClass[ICLS_HWNDMESSAGE])));
ClassName.Length = 0;
RtlZeroMemory(&MenuName, sizeof(MenuName));
RtlZeroMemory(&WindowName, sizeof(WindowName));
wc.cbSize = sizeof(wc);
wc.style = 0;
wc.lpfnWndProc = gpsi->apfnClientW.pfnMessageWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hModClient;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = 0;
wc.lpszMenuName = NULL;
wc.lpszClassName = ClassName.Buffer;
wc.hIconSm = NULL;
Class = IntCreateClass( &wc,
&ClassName,
&MenuName,
NULL,
FNID_MESSAGEWND,
CSF_SYSTEMCLASS,
NULL,
pi);
if (Class != NULL)
{
ASSERT(Class->System);
Class->pclsNext = SystemClassList;
(void)InterlockedExchangePointer((PVOID*)&SystemClassList,
Class);
}
else
{
DPRINT1("!!! Registering Message system class failed!\n");
}
pWnd = co_IntCreateWindowEx( 0,
&ClassName,
&WindowName,

View file

@ -303,6 +303,7 @@ IntCallWndProc
co_HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, SameThread, (LPARAM)&CWP );
}
}
static
VOID
FASTCALL
@ -1535,9 +1536,13 @@ co_IntSendMessageTimeoutSingle(HWND hWnd,
RETURN( FALSE);
}
Result = (ULONG_PTR)co_IntCallWindowProc(Window->Wnd->lpfnWndProc, !Window->Wnd->Unicode, hWnd, Msg, wParam,
lParamPacked,lParamBufferSize);
Result = (ULONG_PTR)co_IntCallWindowProc( Window->Wnd->lpfnWndProc,
!Window->Wnd->Unicode,
hWnd,
Msg,
wParam,
lParamPacked,
lParamBufferSize);
if(uResult)
{
*uResult = Result;
@ -1744,18 +1749,10 @@ co_IntDoSendMessage(HWND hWnd,
IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
if (Window->Wnd->IsSystem)
{
Info.Proc = (!Info.Ansi ? Window->Wnd->lpfnWndProc : Window->Wnd->WndProcExtra);
}
else
{
Info.Ansi = !Window->Wnd->Unicode;
Info.Proc = Window->Wnd->lpfnWndProc;
}
Info.Ansi = !Window->Wnd->Unicode;
Info.Proc = Window->Wnd->lpfnWndProc;
IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, &Result);
}
else
{

View file

@ -195,7 +195,6 @@ IntAttachMonitor(IN PDEVOBJ *pGdiDevice,
PMONITOR_OBJECT p;
DPRINT("Additional monitor is beeing attached\n");
for (p = gMonitorList; p->Next != NULL; p = p->Next)
;
{
p->Next = Monitor;
}

View file

@ -368,6 +368,10 @@ NtUserInitializeClientPfnArrays(
RtlCopyMemory(&gpsi->apfnClientW, pfnClientW, sizeof(PFNCLIENT));
RtlCopyMemory(&gpsi->apfnClientWorker, pfnClientWorker, sizeof(PFNCLIENTWORKER));
//// FIXME! HAX! Temporary until server side is finished.
//// Copy the client side procs for now.
RtlCopyMemory(&gpsi->aStoCidPfn, pfnClientW, sizeof(gpsi->aStoCidPfn));
hModClient = hmodUser;
ClientPfnInit = TRUE;
}

View file

@ -520,34 +520,6 @@ NtUserCallTwoParam(
case TWOPARAM_ROUTINE_REGISTERLOGONPROC:
RETURN( (DWORD)co_IntRegisterLogonProcess((HANDLE)Param1, (BOOL)Param2));
case TWOPARAM_ROUTINE_ROS_REGSYSCLASSES:
{
DWORD Ret = 0;
DWORD Count = Param1;
PREGISTER_SYSCLASS RegSysClassArray = (PREGISTER_SYSCLASS)Param2;
if (Count != 0 && RegSysClassArray != NULL)
{
_SEH2_TRY
{
ProbeArrayForRead(RegSysClassArray,
sizeof(RegSysClassArray[0]),
Count,
2);
Ret = (DWORD)UserRegisterSystemClasses(Count,
RegSysClassArray);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastNtError(_SEH2_GetExceptionCode());
}
_SEH2_END;
}
RETURN( Ret);
}
}
DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n",
Routine, Param1, Param2);

View file

@ -432,6 +432,7 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
/* from now on no messages can be sent to this window anymore */
Window->Status |= WINDOWSTATUS_DESTROYED;
Wnd->state |= WNDS_DESTROYED;
Wnd->fnid |= FNID_FREED;
/* don't remove the WINDOWSTATUS_DESTROYING bit */
@ -539,64 +540,148 @@ IntGetWindowBorderMeasures(PWINDOW_OBJECT Window, UINT *cx, UINT *cy)
}
}
static WNDPROC
IntGetWindowProc(IN PWINDOW_OBJECT Window,
IN BOOL Ansi)
//
// Same as User32:IntGetWndProc.
//
WNDPROC FASTCALL
IntGetWindowProc(PWND pWnd,
BOOL Ansi)
{
PWND Wnd = Window->Wnd;
INT i;
PCLS Class;
WNDPROC gcpd, Ret = 0;
ASSERT(UserIsEnteredExclusive() == TRUE);
ASSERT(UserIsEnteredExclusive() == TRUE);
if (Wnd->IsSystem)
{
return (Ansi ? Wnd->WndProcExtra : Wnd->lpfnWndProc);
}
else
{
if (!Ansi == Wnd->Unicode)
{
return Wnd->lpfnWndProc;
}
else
{
if (Wnd->CallProc != NULL)
{
return GetCallProcHandle(Wnd->CallProc);
}
/* BUGBOY Comments: Maybe theres something Im not undestanding here, but why would a CallProc be created
on a function that I thought is only suppose to return the current Windows Proc? */
Class = pWnd->pcls;
if (pWnd->state & WNDS_SERVERSIDEWINDOWPROC)
{
for ( i = FNID_FIRST; i <= FNID_SWITCH; i++)
{
if (GETPFNSERVER(i) == pWnd->lpfnWndProc)
{
if (Ansi)
Ret = GETPFNCLIENTA(i);
else
{
PCALLPROCDATA NewCallProc, CallProc;
Ret = GETPFNCLIENTW(i);
}
}
return Ret;
}
NewCallProc = UserFindCallProc(Wnd->pcls,
Wnd->lpfnWndProc,
Wnd->Unicode);
if (NewCallProc == NULL)
{
NewCallProc = CreateCallProc(Wnd->head.pti->pDeskInfo,
Wnd->lpfnWndProc,
Wnd->Unicode,
Wnd->head.pti->ppi);
if (NewCallProc == NULL)
{
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
}
if (Class->fnid == FNID_EDIT)
Ret = pWnd->lpfnWndProc;
else
{
Ret = pWnd->lpfnWndProc;
UserAddCallProcToClass(Wnd->pcls,
NewCallProc);
}
if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON)
{
if (Ansi)
{
if (GETPFNCLIENTW(Class->fnid) == pWnd->lpfnWndProc)
Ret = GETPFNCLIENTA(Class->fnid);
}
else
{
if (GETPFNCLIENTA(Class->fnid) == pWnd->lpfnWndProc)
Ret = GETPFNCLIENTW(Class->fnid);
}
}
if ( Ret != pWnd->lpfnWndProc)
return Ret;
}
if ( Ansi == !!(pWnd->state & WNDS_ANSIWINDOWPROC) )
return Ret;
CallProc = Wnd->CallProc;
Wnd->CallProc = NewCallProc;
gcpd = (WNDPROC)UserGetCPD(
pWnd,
(Ansi ? UserGetCPDA2U : UserGetCPDU2A )|UserGetCPDWindow,
(ULONG_PTR)Ret);
return GetCallProcHandle((CallProc == NULL ? NewCallProc : CallProc));
}
}
}
return (gcpd ? gcpd : Ret);
}
static WNDPROC
IntSetWindowProc(PWND pWnd,
WNDPROC NewWndProc,
BOOL Ansi)
{
INT i;
PCALLPROCDATA CallProc;
PCLS Class;
WNDPROC Ret, chWndProc = NULL;
// Retrieve previous window proc.
Ret = IntGetWindowProc(pWnd, Ansi);
Class = pWnd->pcls;
if (IsCallProcHandle(NewWndProc))
{
CallProc = UserGetObject(gHandleTable, NewWndProc, otCallProc);
if (CallProc)
{ // Reset new WndProc.
NewWndProc = CallProc->pfnClientPrevious;
// Reset Ansi from CallProc handle. This is expected with wine "deftest".
Ansi = !!(CallProc->wType & UserGetCPDU2A);
}
}
// Switch from Client Side call to Server Side call if match. Ref: "deftest".
for ( i = FNID_FIRST; i <= FNID_SWITCH; i++)
{
if (GETPFNCLIENTW(i) == NewWndProc)
{
chWndProc = GETPFNSERVER(i);
break;
}
if (GETPFNCLIENTA(i) == NewWndProc)
{
chWndProc = GETPFNSERVER(i);
break;
}
}
// If match, set/reset to Server Side and clear ansi.
if (chWndProc)
{
pWnd->lpfnWndProc = chWndProc;
pWnd->Unicode = TRUE;
pWnd->state &= ~WNDS_ANSIWINDOWPROC;
pWnd->state |= WNDS_SERVERSIDEWINDOWPROC;
}
else
{
pWnd->Unicode = !Ansi;
// Handle the state change in here.
if (Ansi)
pWnd->state |= WNDS_ANSIWINDOWPROC;
else
pWnd->state &= ~WNDS_ANSIWINDOWPROC;
if (pWnd->state & WNDS_SERVERSIDEWINDOWPROC)
pWnd->state &= ~WNDS_SERVERSIDEWINDOWPROC;
if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON)
{
if (Ansi)
{
if (GETPFNCLIENTW(Class->fnid) == NewWndProc)
chWndProc = GETPFNCLIENTA(Class->fnid);
}
else
{
if (GETPFNCLIENTA(Class->fnid) == NewWndProc)
chWndProc = GETPFNCLIENTW(Class->fnid);
}
}
// Now set the new window proc.
pWnd->lpfnWndProc = (chWndProc ? chWndProc : NewWndProc);
}
return Ret;
}
// Move this to user space!
BOOL FASTCALL
IntGetWindowInfo(PWINDOW_OBJECT Window, PWINDOWINFO pwi)
{
@ -1026,7 +1111,7 @@ co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
if (IntIsChildWindow(Wnd, WndNewParent))
{
SetLastWin32Error( ERROR_INVALID_PARAMETER );
return 0;
return NULL;
}
/*
@ -1582,8 +1667,16 @@ co_IntCreateWindowEx(DWORD dwExStyle,
ParentWindowHandle = pti->Desktop->DesktopWindow;
}
if ( !(pti->ppi->W32PF_flags & W32PF_CLASSESREGISTERED ))
{
UserRegisterSystemClasses();
}
OwnerWindowHandle = NULL;
DPRINT("co_IntCreateWindowEx %wZ\n", ClassName);
if (hWndParent == HWND_MESSAGE)
{
/*
@ -1633,6 +1726,8 @@ co_IntCreateWindowEx(DWORD dwExStyle,
/* Check the class. */
DPRINT("Class %wZ\n", ClassName);
ClassAtom = IntGetClassAtom(ClassName,
hInstance,
ti->ppi,
@ -1653,7 +1748,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
SetLastWin32Error(ERROR_CANNOT_FIND_WND_CLASS);
RETURN((PWND)0);
}
DPRINT("ClassAtom %x\n", ClassAtom);
Class = IntReferenceClass(Class,
ClassLink,
pti->Desktop);
@ -1683,6 +1778,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
sizeof(WND) + Class->cbwndExtra);
Window->Wnd->head.h = hWnd;
Wnd = Window->Wnd;
Wnd->fnid = 0;
Wnd->head.pti = ti;
Wnd->head.rpdesk = pti->Desktop;
@ -1747,27 +1843,68 @@ AllocErr:
Wnd->dwUserData = 0;
Wnd->IsSystem = Wnd->pcls->System;
if (Wnd->pcls->CSF_flags & CSF_SERVERSIDEPROC)
Wnd->state |= WNDS_SERVERSIDEWINDOWPROC;
/* BugBoy Comments: Comment below say that System classes are always created as UNICODE.
In windows, creating a window with the ANSI version of CreateWindow sets the window
to ansi as verified by testing with IsUnicodeWindow API.
/* BugBoy Comments: Comment below say that System classes are always created
as UNICODE. In windows, creating a window with the ANSI version of CreateWindow
sets the window to ansi as verified by testing with IsUnicodeWindow API.
No where can I see in code or through testing does the window change back to ANSI
after being created as UNICODE in ROS. I didnt do more testing to see what problems this would cause.*/
// See NtUserDefSetText! We convert to Unicode all the time and never use Mix. (jt)
if (Wnd->pcls->System)
No where can I see in code or through testing does the window change back
to ANSI after being created as UNICODE in ROS. I didnt do more testing to
see what problems this would cause.*/
// Set WndProc from Class.
Wnd->lpfnWndProc = Wnd->pcls->lpfnWndProc;
// GetWindowProc, test for non server side default classes and set WndProc.
if ( Wnd->pcls->fnid <= FNID_GHOST && Wnd->pcls->fnid >= FNID_BUTTON )
{
if (bUnicodeWindow)
{
if (GETPFNCLIENTA(Wnd->pcls->fnid) == Wnd->lpfnWndProc)
Wnd->lpfnWndProc = GETPFNCLIENTW(Wnd->pcls->fnid);
}
else
{
if (GETPFNCLIENTW(Wnd->pcls->fnid) == Wnd->lpfnWndProc)
Wnd->lpfnWndProc = GETPFNCLIENTA(Wnd->pcls->fnid);
}
}
// If not an Unicode caller, set Ansi creator bit.
if (!bUnicodeWindow) Wnd->state |= WNDS_ANSICREATOR;
// Clone Class Ansi/Unicode proc type.
if (Wnd->pcls->CSF_flags & CSF_ANSIPROC)
{
/* NOTE: Always create a unicode window for system classes! */
Wnd->Unicode = TRUE;
Wnd->lpfnWndProc = Wnd->pcls->lpfnWndProc;
Wnd->WndProcExtra = Wnd->pcls->WndProcExtra;
Wnd->state |= WNDS_ANSIWINDOWPROC;
Wnd->Unicode = FALSE;
}
else
{
Wnd->Unicode = Wnd->pcls->Unicode;
Wnd->lpfnWndProc = Wnd->pcls->lpfnWndProc;
Wnd->CallProc = NULL;
{ /*
It seems there can be both an Ansi creator and Unicode Class Window
WndProc, unless the following overriding conditions occur:
*/
if ( !bUnicodeWindow &&
( ClassAtom == gpsi->atomSysClass[ICLS_BUTTON] ||
ClassAtom == gpsi->atomSysClass[ICLS_COMBOBOX] ||
ClassAtom == gpsi->atomSysClass[ICLS_COMBOLBOX] ||
ClassAtom == gpsi->atomSysClass[ICLS_DIALOG] ||
ClassAtom == gpsi->atomSysClass[ICLS_EDIT] ||
ClassAtom == gpsi->atomSysClass[ICLS_IME] ||
ClassAtom == gpsi->atomSysClass[ICLS_LISTBOX] ||
ClassAtom == gpsi->atomSysClass[ICLS_MDICLIENT] ||
ClassAtom == gpsi->atomSysClass[ICLS_STATIC] ) )
{ // Override Class and set the window Ansi WndProc.
Wnd->state |= WNDS_ANSIWINDOWPROC;
Wnd->Unicode = FALSE;
}
else
{ // Set the window Unicode WndProc.
Wnd->state &= ~WNDS_ANSIWINDOWPROC;
Wnd->Unicode = TRUE;
}
}
Window->OwnerThread = PsGetCurrentThread();
@ -2270,8 +2407,6 @@ AllocErr:
else
{
UserAddCallProcToClass(Wnd->pcls, CallProc);
Wnd->CallProc = CallProc;
Wnd->IsSystem = FALSE;
}
}
@ -2435,6 +2570,8 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
if (!Wnd) return TRUE; // FIXME: Need to finish object rewrite or lock the thread when killing the window!
DPRINT("co_UserDestroyWindow \n");
/* Check for owner thread */
if ((Window->OwnerThread != PsGetCurrentThread()))
{
@ -2557,8 +2694,6 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
}
/*
* @implemented
*/
@ -2992,8 +3127,6 @@ PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type)
return WndAncestor;
}
/*
* @implemented
*/
@ -3222,8 +3355,6 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
return( hWndOldParent);
}
/*
* NtUserSetParent
*
@ -3269,8 +3400,6 @@ CLEANUP:
END_CLEANUP;
}
/*
* UserGetShellWindow
*
@ -3493,9 +3622,6 @@ CLEANUP:
END_CLEANUP;
}
HWND FASTCALL
UserGetWindow(HWND hWnd, UINT Relationship)
{
@ -3548,8 +3674,6 @@ UserGetWindow(HWND hWnd, UINT Relationship)
return hWndResult;
}
/*
* NtUserGetWindow
*
@ -3576,9 +3700,6 @@ CLEANUP:
END_CLEANUP;
}
/*
* NtUserGetWindowLong
*
@ -3638,8 +3759,7 @@ UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
break;
case GWL_WNDPROC:
Result = (LONG)IntGetWindowProc(Window,
Ansi);
Result = (LONG)IntGetWindowProc(Wnd, Ansi);
break;
case GWL_HINSTANCE:
@ -3676,9 +3796,6 @@ UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
return Result;
}
/*
* NtUserGetWindowLong
*
@ -3706,102 +3823,6 @@ CLEANUP:
END_CLEANUP;
}
static WNDPROC
IntSetWindowProc(PWINDOW_OBJECT Window,
WNDPROC NewWndProc,
BOOL Ansi)
{
WNDPROC Ret;
PCALLPROCDATA CallProc;
PWND Wnd = Window->Wnd;
/* resolve any callproc handle if possible */
if (IsCallProcHandle(NewWndProc))
{
WNDPROC_INFO wpInfo;
if (UserGetCallProcInfo((HANDLE)NewWndProc,
&wpInfo))
{
NewWndProc = wpInfo.WindowProc;
/* FIXME - what if wpInfo.IsUnicode doesn't match Ansi? */
}
}
/* attempt to get the previous window proc */
if (Wnd->IsSystem)
{
Ret = (Ansi ? Wnd->WndProcExtra : Wnd->lpfnWndProc);
}
else
{
if (!Ansi == Wnd->Unicode)
{
Ret = Wnd->lpfnWndProc;
}
else
{
CallProc = UserFindCallProc(Wnd->pcls,
Wnd->lpfnWndProc,
Wnd->Unicode);
if (CallProc == NULL)
{
CallProc = CreateCallProc(NULL,
Wnd->lpfnWndProc,
Wnd->Unicode,
Wnd->head.pti->ppi);
if (CallProc == NULL)
{
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
}
UserAddCallProcToClass(Wnd->pcls,
CallProc);
}
/* BugBoy Comments: Added this if else, see below comments */
if (!Wnd->CallProc)
{
Ret = Wnd->lpfnWndProc;
}
else
{
Ret = GetCallProcHandle(Wnd->CallProc);
}
Wnd->CallProc = CallProc;
/* BugBoy Comments: Above sets the current CallProc for the
window and below we set the Ret value to it.
SetWindowLong for WNDPROC should return the previous proc
Ret = GetCallProcHandle(Wnd->CallProc); */
}
}
if (Wnd->pcls->System)
{
/* check if the new procedure matches with the one in the
window class. If so, we need to restore both procedures! */
Wnd->IsSystem = (NewWndProc == Wnd->pcls->lpfnWndProc ||
NewWndProc == Wnd->pcls->WndProcExtra);
if (Wnd->IsSystem)
{
Wnd->lpfnWndProc = Wnd->pcls->lpfnWndProc;
Wnd->WndProcExtra = Wnd->pcls->WndProcExtra;
Wnd->Unicode = !Ansi;
return Ret;
}
}
ASSERT(!Wnd->IsSystem);
/* update the window procedure */
Wnd->lpfnWndProc = NewWndProc;
Wnd->Unicode = !Ansi;
return Ret;
}
LONG FASTCALL
@ -3835,7 +3856,17 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return( 0);
}
OldValue = *((LONG *)((PCHAR)(Wnd + 1) + Index));
/*
if ( Index == DWLP_DLGPROC && Wnd->state & WNDS_DIALOGWINDOW)
{
OldValue = (LONG)IntSetWindowProc( Wnd,
(WNDPROC)NewValue,
Ansi);
if (!OldValue) return 0;
}
*/
*((LONG *)((PCHAR)(Wnd + 1) + Index)) = NewValue;
}
else
@ -3873,8 +3904,13 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
case GWL_WNDPROC:
{
/* FIXME: should check if window belongs to current process */
OldValue = (LONG)IntSetWindowProc(Window,
if ( Wnd->head.pti->ppi != PsGetCurrentProcessWin32Process() ||
Wnd->fnid & FNID_FREED)
{
SetLastWin32Error(ERROR_ACCESS_DENIED);
return( 0);
}
OldValue = (LONG)IntSetWindowProc(Wnd,
(WNDPROC)NewValue,
Ansi);
break;
@ -3914,8 +3950,6 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
return( OldValue);
}
/*
* NtUserSetWindowLong
*