- [Win32k] Update class and window structures.

- Rewritten Set/GetWindowContextHelpId.
- Removed NtUserRegisterClassEx, replaced it with NtUserRegisterClassExWOW.
- Updated all related files and functions.


svn path=/trunk/; revision=42128
This commit is contained in:
James Tabor 2009-07-22 04:11:06 +00:00
parent 9144a1bbf6
commit 0485c0c365
17 changed files with 314 additions and 257 deletions

View file

@ -230,6 +230,8 @@ Init(VOID)
(PVOID)User32CallHookProcFromKernel;
NtCurrentPeb()->KernelCallbackTable[USER32_CALLBACK_EVENTPROC] =
(PVOID)User32CallEventProcFromKernel;
NtCurrentPeb()->KernelCallbackTable[USER32_CALLBACK_LOADMENU] =
(PVOID)User32CallLoadMenuFromKernel;
NtUserProcessConnect( NtCurrentProcess(),
&UserCon,

View file

@ -826,8 +826,83 @@ RegisterClassExWOWW(WNDCLASSEXW *lpwcx,
WORD fnID,
DWORD dwFlags)
{
RTL_ATOM Atom = 0;
return (ATOM)Atom;
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;
}
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,
fnID,
dwFlags,
pdwWowData);
TRACE("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);
return Atom;
}
/*
@ -840,7 +915,8 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
WNDCLASSEXA WndClass;
UNICODE_STRING ClassName;
UNICODE_STRING MenuName = {0};
HMENU hMenu = NULL;
CLSMENUNAME clsMenuName;
ANSI_STRING AnsiMenuName;
if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXA) ||
lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
@ -850,14 +926,6 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
return 0;
}
/*
* 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);
@ -888,9 +956,6 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
{
MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
}
if (MenuName.Buffer != NULL)
hMenu = LoadMenuA(WndClass.hInstance, WndClass.lpszMenuName);
}
if (IS_ATOM(WndClass.lpszClassName))
@ -904,19 +969,29 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
RtlCreateUnicodeStringFromAsciiz(&ClassName, WndClass.lpszClassName);
}
Atom = NtUserRegisterClassEx((WNDCLASSEXW*)&WndClass,
&ClassName,
&MenuName,
NULL,
REGISTERCLASS_ANSI,
hMenu);
RtlUnicodeStringToAnsiString( &AnsiMenuName, &MenuName, TRUE);
TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
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);
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);
@ -933,7 +1008,8 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
WNDCLASSEXW WndClass;
UNICODE_STRING ClassName;
UNICODE_STRING MenuName = {0};
HMENU hMenu = NULL;
CLSMENUNAME clsMenuName;
ANSI_STRING AnsiMenuName;
if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXW) ||
lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
@ -950,6 +1026,8 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
* 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)
{
@ -981,9 +1059,6 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
{
MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
}
if (MenuName.Buffer != NULL)
hMenu = LoadMenuW(WndClass.hInstance, WndClass.lpszMenuName);
}
if (IS_ATOM(WndClass.lpszClassName))
@ -997,14 +1072,21 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
RtlInitUnicodeString(&ClassName, WndClass.lpszClassName);
}
Atom = (ATOM)NtUserRegisterClassEx(&WndClass,
&ClassName,
&MenuName,
NULL,
0,
hMenu);
RtlUnicodeStringToAnsiString( &AnsiMenuName, &MenuName, TRUE);
TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
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",
Atom, lpwcx->lpfnWndProc, lpwcx->hInstance, lpwcx->hbrBackground,
lpwcx->style, lpwcx->cbClsExtra, lpwcx->cbWndExtra, WndClass);

View file

@ -3945,6 +3945,19 @@ MenuSetItemData(
return TRUE;
}
NTSTATUS WINAPI
User32CallLoadMenuFromKernel(PVOID Arguments, ULONG ArgumentLength)
{
PLOADMENU_CALLBACK_ARGUMENTS Common;
LRESULT Result;
Common = (PLOADMENU_CALLBACK_ARGUMENTS) Arguments;
Result = (LRESULT)LoadMenuW(Common->hModule, (LPCWSTR)&Common->MenuName);
return ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS);
}
/* FUNCTIONS *****************************************************************/

View file

@ -241,7 +241,7 @@ User32CreateWindowEx(DWORD dwExStyle,
hInstance,
lpParam,
SW_SHOW,
FALSE,
Unicode,
0);
#if 0
@ -1762,13 +1762,7 @@ SetWindowContextHelpId(HWND hwnd,
DWORD WINAPI
GetWindowContextHelpId(HWND hwnd)
{
PWINDOW Wnd = ValidateHwnd(hwnd);
if (Wnd != NULL)
{
return Wnd->ContextHelpId;
}
return 0;
return NtUserCallHwnd(hwnd, HWND_ROUTINE_GETWNDCONTEXTHLPID);
}
/*

View file

@ -7,7 +7,8 @@
#define USER32_CALLBACK_LOADDEFAULTCURSORS (3)
#define USER32_CALLBACK_HOOKPROC (4)
#define USER32_CALLBACK_EVENTPROC (5)
#define USER32_CALLBACK_MAXIMUM (5)
#define USER32_CALLBACK_LOADMENU (6)
#define USER32_CALLBACK_MAXIMUM (6)
typedef struct _WINDOWPROC_CALLBACK_ARGUMENTS
{
@ -63,6 +64,12 @@ typedef struct _EVENTPROC_CALLBACK_ARGUMENTS
WINEVENTPROC Proc;
} EVENTPROC_CALLBACK_ARGUMENTS, *PEVENTPROC_CALLBACK_ARGUMENTS;
typedef struct _LOADMENU_CALLBACK_ARGUMENTS
{
HINSTANCE hModule;
WCHAR MenuName[1];
} LOADMENU_CALLBACK_ARGUMENTS, *PLOADMENU_CALLBACK_ARGUMENTS;
NTSTATUS WINAPI
User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength);
NTSTATUS WINAPI
@ -75,5 +82,7 @@ NTSTATUS WINAPI
User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength);
NTSTATUS WINAPI
User32CallEventProcFromKernel(PVOID Arguments, ULONG ArgumentLength);
NTSTATUS WINAPI
User32CallLoadMenuFromKernel(PVOID Arguments, ULONG ArgumentLength);
#endif /* __INCLUDE_USER32_CALLBACK_H */

View file

@ -118,7 +118,6 @@ typedef struct _WINDOWCLASS
DWORD CSF_flags;
PSTR lpszClientAnsiMenuName;
PWSTR lpszClientUnicodeMenuName;
HANDLE hMenu; /* FIXME - Use pointer! */
PCALLPROC spcpdFirst;
struct _WINDOWCLASS *pclsBase;
struct _WINDOWCLASS *pclsClone;
@ -283,7 +282,7 @@ typedef struct _WINDOW
LIST_ENTRY PropListHead;
ULONG PropListItems;
/* Window menu handle or window id */
UINT IDMenu;
UINT IDMenu; // Use spmenu
//PMENU spmenuSys;
//PMENU spmenu;
HRGN hrgnClip;
@ -300,9 +299,6 @@ typedef struct _WINDOW
struct _WINDOW *spwndClipboardListener;
DWORD ExStyle2;
/* Context help id */
DWORD ContextHelpId;
struct
{
RECT NormalRect;
@ -310,7 +306,7 @@ typedef struct _WINDOW
POINT MaxPos;
} InternalPos;
UINT Unicode : 1; // !WNDS_ANSICREATOR ?
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;
@ -1344,7 +1340,7 @@ NtUserCreateWindowEx(
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam,
DWORD dwFlags,
DWORD dwFlags, // |= 1 == Ansi
PVOID acbiBuffer);
#endif
@ -2993,7 +2989,6 @@ typedef struct tagKMDDELPARAM
#define ONEPARAM_ROUTINE_CREATECURICONHANDLE 0xfffe0025 // CREATE_EMPTY_CURSOR_OBJECT ?
#define ONEPARAM_ROUTINE_MSQSETWAKEMASK 0xfffe0027
#define ONEPARAM_ROUTINE_REGISTERUSERMODULE 0xfffe0031
#define ONEPARAM_ROUTINE_GETWNDCONTEXTHLPID 0xfffe0047 // use HWND_ROUTINE_GETWNDCONTEXTHLPID
#define ONEPARAM_ROUTINE_GETCURSORPOSITION 0xfffe0048 // use ONEPARAM_ or TWOPARAM routine ?
#define TWOPARAM_ROUTINE_GETWINDOWRGNBOX 0xfffd0048 // user mode
#define TWOPARAM_ROUTINE_GETWINDOWRGN 0xfffd0049 // user mode
@ -3165,22 +3160,6 @@ NtUserMonitorFromWindow(
IN DWORD dwFlags);
/* FIXME: These flag constans aren't what Windows uses. */
#define REGISTERCLASS_ANSI 2
#define REGISTERCLASS_ALL (REGISTERCLASS_ANSI)
RTL_ATOM
NTAPI
NtUserRegisterClassEx( // Need to use NtUserRegisterClassExWOW.
CONST WNDCLASSEXW* lpwcx,
PUNICODE_STRING ClassName,
PUNICODE_STRING MenuName,
WNDPROC wpExtra,
DWORD Flags,
HMENU hMenu);
typedef struct tagNTUSERSENDMESSAGEINFO
{
BOOL HandledByKernel;

View file

@ -54,4 +54,6 @@ IntCbAllocateMemory(ULONG Size);
VOID FASTCALL
IntCbFreeMemory(PVOID Data);
HMENU APIENTRY co_IntCallLoadMenu(HINSTANCE,PUNICODE_STRING);
#endif /* _WIN32K_CALLBACK_H */

View file

@ -58,7 +58,6 @@ RTL_ATOM
UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx,
IN PUNICODE_STRING ClassName,
IN PUNICODE_STRING MenuName,
IN HANDLE hMenu,
IN WNDPROC wpExtra,
IN DWORD dwFlags);
@ -78,8 +77,6 @@ IntGetClassAtom(IN PUNICODE_STRING ClassName,
OUT PWINDOWCLASS *BaseClass OPTIONAL,
OUT PWINDOWCLASS **Link OPTIONAL);
#define REGISTERCLASS_SYSTEM 0x4
PWINDOWCLASS
FASTCALL
IntCreateClass(IN CONST WNDCLASSEXW* lpwcx,

View file

@ -1,6 +1,9 @@
#ifndef _WIN32K_PROP_H
#define _WIN32K_PROP_H
PPROPERTY FASTCALL IntGetProp(PWINDOW_OBJECT,ATOM);
BOOL FASTCALL IntRemoveProp(PWINDOW_OBJECT,ATOM);
BOOL FASTCALL IntSetProp(PWINDOW_OBJECT, ATOM, HANDLE);
#endif /* _WIN32K_PROP_H */

View file

@ -666,4 +666,57 @@ co_IntCallEventProc(HWINEVENTHOOK hook,
return Result;
}
//
// Callback Load Menu and results.
//
HMENU
APIENTRY
co_IntCallLoadMenu( HINSTANCE hModule,
PUNICODE_STRING pMenuName )
{
LRESULT Result = 0;
NTSTATUS Status;
PLOADMENU_CALLBACK_ARGUMENTS Common;
ULONG ArgumentLength, ResultLength;
PVOID Argument, ResultPointer;
ArgumentLength = sizeof(LOADMENU_CALLBACK_ARGUMENTS);
ArgumentLength += pMenuName->Length + sizeof(WCHAR);
Argument = IntCbAllocateMemory(ArgumentLength);
if (NULL == Argument)
{
DPRINT1("EventProc callback failed: out of memory\n");
return 0;
}
Common = (PLOADMENU_CALLBACK_ARGUMENTS) Argument;
Common->hModule = hModule;
RtlCopyMemory(&Common->MenuName, pMenuName->Buffer, pMenuName->Length);
ResultPointer = NULL;
ResultLength = sizeof(LRESULT);
UserLeaveCo();
Status = KeUserModeCallback(USER32_CALLBACK_LOADMENU,
Argument,
ArgumentLength,
&ResultPointer,
&ResultLength);
UserEnterCo();
IntCbFreeMemory(Argument);
if (!NT_SUCCESS(Status))
{
return 0;
}
return (HMENU)Result;
}
/* EOF */

View file

@ -892,9 +892,9 @@ IntCreateClass(IN CONST WNDCLASSEXW* lpwcx,
Class->pclsBase = Class;
Class->atomClassName = Atom;
if (dwFlags & REGISTERCLASS_SYSTEM)
if (dwFlags & CSF_SYSTEMCLASS)
{
dwFlags &= ~REGISTERCLASS_ANSI;
dwFlags &= ~CSF_ANSIPROC;
Class->WndProcExtra = wpExtra;
Class->System = TRUE;
}
@ -954,7 +954,7 @@ IntCreateClass(IN CONST WNDCLASSEXW* lpwcx,
else
Class->AnsiMenuName = (PSTR)MenuName->Buffer;
if (!(dwFlags & REGISTERCLASS_ANSI))
if (!(dwFlags & CSF_ANSIPROC))
Class->Unicode = TRUE;
if (Class->style & CS_GLOBALCLASS)
@ -1177,7 +1177,6 @@ RTL_ATOM
UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx,
IN PUNICODE_STRING ClassName,
IN PUNICODE_STRING MenuName,
IN HANDLE hMenu, /* FIXME */
IN WNDPROC wpExtra,
IN DWORD dwFlags)
{
@ -1239,9 +1238,6 @@ UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx,
{
PWINDOWCLASS *List;
/* FIXME - pass the PMENU pointer to IntCreateClass instead! */
Class->hMenu = hMenu;
/* Register the class */
if (Class->System)
List = &pi->SystemClassList;
@ -1901,7 +1897,7 @@ UserRegisterSystemClasses(IN ULONG Count,
&ClassName,
&MenuName,
SystemClasses[i].ProcA,
REGISTERCLASS_SYSTEM,
CSF_SYSTEMCLASS,
NULL,
pi);
if (Class != NULL)
@ -1933,15 +1929,16 @@ UserRegisterSystemClasses(IN ULONG Count,
/* SYSCALLS *****************************************************************/
RTL_ATOM APIENTRY
NtUserRegisterClassEx(IN CONST WNDCLASSEXW* lpwcx,
IN PUNICODE_STRING ClassName,
IN PUNICODE_STRING MenuName,
IN WNDPROC wpExtra,
IN DWORD Flags,
IN HMENU hMenu)
RTL_ATOM
APIENTRY
NtUserRegisterClassExWOW(
WNDCLASSEXW* lpwcx,
PUNICODE_STRING ClassName,
PUNICODE_STRING ClsNVersion,
PCLSMENUNAME pClassMenuName,
DWORD fnID,
DWORD Flags,
LPDWORD pWow)
/*
* FUNCTION:
* Registers a new class with the window manager
@ -1949,7 +1946,6 @@ NtUserRegisterClassEx(IN CONST WNDCLASSEXW* lpwcx,
* lpwcx = Win32 extended window class structure
* bUnicodeClass = Whether to send ANSI or unicode strings
* to window procedures
* wpExtra = Extra window procedure, if this is not null, its used for the second window procedure for standard controls.
* RETURNS:
* Atom identifying the new class
*/
@ -1957,8 +1953,9 @@ NtUserRegisterClassEx(IN CONST WNDCLASSEXW* lpwcx,
WNDCLASSEXW CapturedClassInfo = {0};
UNICODE_STRING CapturedName = {0}, CapturedMenuName = {0};
RTL_ATOM Ret = (RTL_ATOM)0;
WNDPROC wpExtra = NULL;
if (Flags & ~REGISTERCLASS_ALL)
if (Flags & ~(CSF_ANSIPROC))
{
SetLastWin32Error(ERROR_INVALID_FLAGS);
return Ret;
@ -1982,14 +1979,22 @@ NtUserRegisterClassEx(IN CONST WNDCLASSEXW* lpwcx,
sizeof(WNDCLASSEXW));
CapturedName = ProbeForReadUnicodeString(ClassName);
CapturedMenuName = ProbeForReadUnicodeString(MenuName);
if (CapturedName.Length & 1 || CapturedMenuName.Length & 1 ||
CapturedClassInfo.cbClsExtra < 0 ||
CapturedClassInfo.cbClsExtra + CapturedName.Length +
CapturedMenuName.Length + sizeof(WINDOWCLASS) < CapturedClassInfo.cbClsExtra ||
CapturedClassInfo.cbWndExtra < 0 ||
CapturedClassInfo.hInstance == NULL)
ProbeForRead(pClassMenuName,
sizeof(CLSMENUNAME),
1);
CapturedMenuName = ProbeForReadUnicodeString(pClassMenuName->pusMenuName);
if ( CapturedName.Length & 1 ||
CapturedMenuName.Length & 1 ||
CapturedClassInfo.cbClsExtra < 0 ||
CapturedClassInfo.cbClsExtra +
CapturedName.Length +
CapturedMenuName.Length +
sizeof(WINDOWCLASS) < CapturedClassInfo.cbClsExtra ||
CapturedClassInfo.cbWndExtra < 0 ||
CapturedClassInfo.hInstance == NULL)
{
goto InvalidParameter;
}
@ -2021,12 +2026,10 @@ InvalidParameter:
SetLastWin32Error(ERROR_INVALID_PARAMETER);
_SEH2_LEAVE;
}
/* Register the class */
Ret = UserRegisterClass(&CapturedClassInfo,
&CapturedName,
&CapturedMenuName,
hMenu, /* FIXME - pass pointer */
wpExtra,
Flags);
@ -2042,113 +2045,6 @@ InvalidParameter:
return Ret;
}
RTL_ATOM
APIENTRY
NtUserRegisterClassExWOW(
WNDCLASSEXW* lpwcx,
PUNICODE_STRING ClassName,
PUNICODE_STRING ClsNVersion,
PCLSMENUNAME pClassMenuName,
DWORD fnID,
DWORD Flags,
LPDWORD pWow)
{
WNDCLASSEXW CapturedClassInfo = {0};
UNICODE_STRING CapturedName = {0}, ClassnametoVersion = {0};
RTL_ATOM Ret = (RTL_ATOM)0;
UserEnterExclusive();
_SEH2_TRY
{
/* Probe the parameters and basic parameter checks */
if (ProbeForReadUint(&lpwcx->cbSize) != sizeof(WNDCLASSEXW))
{
goto InvalidParameter;
}
if (!pClassMenuName)
{
goto InvalidParameter;
}
ProbeForRead(lpwcx,
sizeof(WNDCLASSEXW),
sizeof(ULONG));
RtlCopyMemory(&CapturedClassInfo,
lpwcx,
sizeof(WNDCLASSEXW));
/*
Need to watch this. When UnregisterClass is called these pointers
are freed by the caller in user space. So, we just probe the data
for now and pass it on and copy it to the shared class structure.
*/
ProbeForRead(pClassMenuName,
sizeof(CLSMENUNAME),
sizeof(ULONG));
CapturedName = ProbeForReadUnicodeString(ClassName);
ClassnametoVersion = ProbeForReadUnicodeString(ClsNVersion);
if (CapturedName.Length & 1 || ClassnametoVersion.Length & 1 ||
CapturedClassInfo.cbClsExtra < 0 ||
CapturedClassInfo.cbClsExtra + CapturedName.Length +
ClassnametoVersion.Length + sizeof(WINDOWCLASS) < CapturedClassInfo.cbClsExtra ||
CapturedClassInfo.cbWndExtra < 0 ||
CapturedClassInfo.hInstance == NULL)
{
goto InvalidParameter;
}
if (CapturedName.Length != 0)
{
ProbeForRead(CapturedName.Buffer,
CapturedName.Length,
sizeof(WCHAR));
}
else
{
if (!IS_ATOM(CapturedName.Buffer))
{
goto InvalidParameter;
}
}
if (ClassnametoVersion.Length != 0)
{
ProbeForRead(ClassnametoVersion.Buffer,
ClassnametoVersion.Length,
sizeof(WCHAR));
}
else if (ClassnametoVersion.Buffer != NULL &&
!IS_INTRESOURCE(ClassnametoVersion.Buffer))
{
InvalidParameter:
SetLastWin32Error(ERROR_INVALID_PARAMETER);
_SEH2_LEAVE;
}
/* Register the class */
// Ret = UserRegisterClass(&CapturedClassInfo,
// &CapturedName,
// &ClassnametoVersion,
// hMenu, /* FIXME - pass pointer */
// wpExtra,
// Flags);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastNtError(_SEH2_GetExceptionCode());
}
_SEH2_END;
UserLeave();
return Ret;
}
ULONG_PTR APIENTRY
NtUserGetClassLong(IN HWND hWnd,
IN INT Offset,

View file

@ -1134,7 +1134,7 @@ NtUserCreateDesktop(
&ClassName,
&MenuName,
NULL,
REGISTERCLASS_SYSTEM,
CSF_SYSTEMCLASS,
NULL,
pi);
if (Class != NULL)

View file

@ -37,10 +37,12 @@ InitUserAtoms(VOID)
gpsi->atomSysClass[ICLS_ICONTITLE] = 32772;
gpsi->atomSysClass[ICLS_TOOLTIPS] = 32774;
/* System Message Atom */
AtomMessage = IntAddGlobalAtom(L"Message", TRUE);
gpsi->atomSysClass[ICLS_HWNDMESSAGE] = AtomMessage;
DPRINT("AtomMessage -> %x\n", AtomMessage);
/* System Context Help Id Atom */
gpsi->atomContextHelpIdProp = IntAddGlobalAtom(L"SysCH", TRUE);
return STATUS_SUCCESS;
}

View file

@ -34,9 +34,6 @@
/* STATIC FUNCTIONS **********************************************************/
/* FUNCTIONS *****************************************************************/
static
PPROPERTY FASTCALL
IntGetProp(PWINDOW_OBJECT Window, ATOM Atom)
{
@ -56,6 +53,49 @@ IntGetProp(PWINDOW_OBJECT Window, ATOM Atom)
return(NULL);
}
BOOL FASTCALL
IntRemoveProp(PWINDOW_OBJECT Window, ATOM Atom)
{
PPROPERTY Prop;
HANDLE Data;
Prop = IntGetProp(Window, Atom);
if (Prop == NULL)
{
return FALSE;
}
Data = Prop->Data;
RemoveEntryList(&Prop->PropListEntry);
UserHeapFree(Prop);
Window->Wnd->PropListItems--;
return TRUE;
}
BOOL FASTCALL
IntSetProp(PWINDOW_OBJECT pWnd, ATOM Atom, HANDLE Data)
{
PPROPERTY Prop;
Prop = IntGetProp(pWnd, Atom);
if (Prop == NULL)
{
Prop = UserHeapAlloc(sizeof(PROPERTY));
if (Prop == NULL)
{
return FALSE;
}
Prop->Atom = Atom;
InsertTailList(&pWnd->Wnd->PropListHead, &Prop->PropListEntry);
pWnd->Wnd->PropListItems++;
}
Prop->Data = Data;
return TRUE;
}
/* FUNCTIONS *****************************************************************/
NTSTATUS APIENTRY
NtUserBuildPropList(HWND hWnd,
LPVOID Buffer,
@ -164,32 +204,6 @@ CLEANUP:
END_CLEANUP;
}
static
BOOL FASTCALL
IntSetProp(PWINDOW_OBJECT pWnd, ATOM Atom, HANDLE Data)
{
PPROPERTY Prop;
Prop = IntGetProp(pWnd, Atom);
if (Prop == NULL)
{
Prop = UserHeapAlloc(sizeof(PROPERTY));
if (Prop == NULL)
{
return FALSE;
}
Prop->Atom = Atom;
InsertTailList(&pWnd->Wnd->PropListHead, &Prop->PropListEntry);
pWnd->Wnd->PropListItems++;
}
Prop->Data = Data;
return TRUE;
}
BOOL APIENTRY
NtUserSetProp(HWND hWnd, ATOM Atom, HANDLE Data)
{

View file

@ -210,22 +210,6 @@ NtUserCallOneParam(
case ONEPARAM_ROUTINE_WINDOWFROMDC:
RETURN( (DWORD)IntWindowFromDC((HDC)Param));
case ONEPARAM_ROUTINE_GETWNDCONTEXTHLPID:
{
PWINDOW_OBJECT Window;
DWORD Result;
Window = UserGetWindowObject((HWND)Param);
if(!Window)
{
RETURN( FALSE);
}
Result = Window->Wnd->ContextHelpId;
RETURN( Result);
}
case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON:
{
DWORD Result;
@ -556,7 +540,10 @@ NtUserCallTwoParam(
RETURN( (DWORD)FALSE);
}
Window->Wnd->ContextHelpId = Param2;
if ( Param2 )
IntSetProp(Window, gpsi->atomContextHelpIdProp, (HANDLE)Param2);
else
IntRemoveProp(Window, gpsi->atomContextHelpIdProp);
RETURN( (DWORD)TRUE);
@ -786,6 +773,27 @@ NtUserCallHwnd(
{
switch (Routine)
{
case HWND_ROUTINE_GETWNDCONTEXTHLPID:
{
PWINDOW_OBJECT Window;
PPROPERTY HelpId;
USER_REFERENCE_ENTRY Ref;
UserEnterExclusive();
if (!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd)
{
UserLeave();
return 0;
}
UserRefObjectCo(Window, &Ref);
HelpId = IntGetProp(Window, gpsi->atomContextHelpIdProp);
UserDerefObjectCo(Window);
UserLeave();
return (DWORD)HelpId;
}
case HWND_ROUTINE_REGISTERSHELLHOOKWINDOW:
if (IntIsWindow(hWnd))
return IntRegisterShellHookWindow(hWnd);

View file

@ -1706,7 +1706,6 @@ AllocErr:
Class = NULL;
Window->SystemMenu = (HMENU)0;
Wnd->ContextHelpId = 0;
Wnd->IDMenu = 0;
Wnd->hModule = hInstance;
Window->hSelf = hWnd;
@ -1835,14 +1834,19 @@ AllocErr:
{
if (hMenu)
IntSetMenu(Window, hMenu, &MenuChanged);
else
else // Take it from the parent.
{
hMenu = Wnd->pcls->hMenu;
UNICODE_STRING MenuName;
RtlInitUnicodeString( &MenuName, Wnd->pcls->MenuName);
hMenu = co_IntCallLoadMenu( Wnd->pcls->hModule, &MenuName);
if (hMenu) IntSetMenu(Window, hMenu, &MenuChanged);
if (MenuName.Buffer) RtlFreeUnicodeString(&MenuName);
}
}
else
Wnd->IDMenu = (UINT) hMenu;
else // Not a child
Wnd->IDMenu = (UINT) hMenu;
/* Insert the window into the thread's window list. */
InsertTailList (&pti->WindowListHead, &Window->ThreadListEntry);

View file

@ -696,7 +696,6 @@ NtUserMenuInfo 3
NtUserMenuItemInfo 5
NtUserMonitorFromPoint 3
NtUserMonitorFromRect 2
NtUserRegisterClassEx 6
NtUserMonitorFromWindow 2
NtUserSendMessage 5
NtUserSendMessageTimeout 8