mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 13:33:04 +00:00
- [Win32k] More work on classes. Fixed SEH abuse and implemented NtUserGetWOWClass. Minor bug fixes and modifications that help function compatibility based on wine.
- Tested wine (some improvements and losses): Msi seems to be fixed, did not test before these changes. My guess is Jeffrey Morlan fixed it in 42163, so a Big Thank You!!! Tested Firefox 1.15.xx and AbiWord 2.6.8. svn path=/trunk/; revision=42168
This commit is contained in:
parent
1a67e2e700
commit
9fd89d0e43
5 changed files with 264 additions and 130 deletions
|
@ -25,6 +25,7 @@ GetClassInfoExA(
|
||||||
{
|
{
|
||||||
UNICODE_STRING ClassName = {0};
|
UNICODE_STRING ClassName = {0};
|
||||||
BOOL Ret;
|
BOOL Ret;
|
||||||
|
LPCSTR pszMenuName;
|
||||||
|
|
||||||
TRACE("%p class/atom: %s/%04x %p\n", hInstance,
|
TRACE("%p class/atom: %s/%04x %p\n", hInstance,
|
||||||
IS_ATOM(lpszClass) ? NULL : lpszClass,
|
IS_ATOM(lpszClass) ? NULL : lpszClass,
|
||||||
|
@ -62,8 +63,13 @@ GetClassInfoExA(
|
||||||
Ret = NtUserGetClassInfo(hInstance,
|
Ret = NtUserGetClassInfo(hInstance,
|
||||||
&ClassName,
|
&ClassName,
|
||||||
(LPWNDCLASSEXW)lpwcx,
|
(LPWNDCLASSEXW)lpwcx,
|
||||||
NULL,
|
(LPWSTR *)&pszMenuName,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
if (Ret)
|
||||||
|
{
|
||||||
|
lpwcx->lpszClassName = lpszClass;
|
||||||
|
// lpwcx->lpszMenuName = pszMenuName;
|
||||||
|
}
|
||||||
|
|
||||||
if (!IS_ATOM(lpszClass))
|
if (!IS_ATOM(lpszClass))
|
||||||
{
|
{
|
||||||
|
@ -85,6 +91,8 @@ GetClassInfoExW(
|
||||||
LPWNDCLASSEXW lpwcx)
|
LPWNDCLASSEXW lpwcx)
|
||||||
{
|
{
|
||||||
UNICODE_STRING ClassName = {0};
|
UNICODE_STRING ClassName = {0};
|
||||||
|
BOOL Ret;
|
||||||
|
LPWSTR pszMenuName;
|
||||||
|
|
||||||
TRACE("%p class/atom: %S/%04x %p\n", hInstance,
|
TRACE("%p class/atom: %S/%04x %p\n", hInstance,
|
||||||
IS_ATOM(lpszClass) ? NULL : lpszClass,
|
IS_ATOM(lpszClass) ? NULL : lpszClass,
|
||||||
|
@ -115,11 +123,17 @@ GetClassInfoExW(
|
||||||
lpszClass);
|
lpszClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NtUserGetClassInfo(hInstance,
|
Ret = NtUserGetClassInfo( hInstance,
|
||||||
&ClassName,
|
&ClassName,
|
||||||
lpwcx,
|
lpwcx,
|
||||||
NULL,
|
&pszMenuName,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
if (Ret)
|
||||||
|
{
|
||||||
|
lpwcx->lpszClassName = lpszClass;
|
||||||
|
// lpwcx->lpszMenuName = pszMenuName;
|
||||||
|
}
|
||||||
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -238,7 +252,7 @@ GetClassLongA(HWND hWnd, int nIndex)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GCL_MENUNAME:
|
case GCL_MENUNAME:
|
||||||
Ret = (ULONG_PTR)Class->AnsiMenuName;
|
Ret = (ULONG_PTR)Class->lpszClientAnsiMenuName;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GCL_STYLE:
|
case GCL_STYLE:
|
||||||
|
@ -351,7 +365,7 @@ GetClassLongW ( HWND hWnd, int nIndex )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GCL_MENUNAME:
|
case GCL_MENUNAME:
|
||||||
Ret = (ULONG_PTR)Class->MenuName;
|
Ret = (ULONG_PTR)Class->lpszClientUnicodeMenuName;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GCL_STYLE:
|
case GCL_STYLE:
|
||||||
|
|
|
@ -970,7 +970,7 @@ static void DefWndPrint( HWND hwnd, HDC hdc, ULONG uFlags)
|
||||||
* Client area
|
* Client area
|
||||||
*/
|
*/
|
||||||
if ( uFlags & PRF_CLIENT)
|
if ( uFlags & PRF_CLIENT)
|
||||||
SendMessageW(hwnd, WM_PRINTCLIENT, (WPARAM)hdc, PRF_CLIENT);
|
SendMessageW(hwnd, WM_PRINTCLIENT, (WPARAM)hdc, uFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL CALLBACK
|
static BOOL CALLBACK
|
||||||
|
|
|
@ -116,8 +116,8 @@ typedef struct _CLS
|
||||||
struct _DESKTOP *rpdeskParent;
|
struct _DESKTOP *rpdeskParent;
|
||||||
PVOID pdce;
|
PVOID pdce;
|
||||||
DWORD CSF_flags;
|
DWORD CSF_flags;
|
||||||
PSTR lpszClientAnsiMenuName;
|
PSTR lpszClientAnsiMenuName; // For client use
|
||||||
PWSTR lpszClientUnicodeMenuName;
|
PWSTR lpszClientUnicodeMenuName; // " " "
|
||||||
PCALLPROC spcpdFirst;
|
PCALLPROC spcpdFirst;
|
||||||
struct _CLS *pclsBase;
|
struct _CLS *pclsBase;
|
||||||
struct _CLS *pclsClone;
|
struct _CLS *pclsClone;
|
||||||
|
@ -135,11 +135,11 @@ typedef struct _CLS
|
||||||
HANDLE hIcon; /* FIXME - Use pointer! */
|
HANDLE hIcon; /* FIXME - Use pointer! */
|
||||||
HANDLE hCursor; /* FIXME - Use pointer! */
|
HANDLE hCursor; /* FIXME - Use pointer! */
|
||||||
HBRUSH hbrBackground;
|
HBRUSH hbrBackground;
|
||||||
PWSTR MenuName;
|
PWSTR lpszMenuName; // kernel use
|
||||||
PSTR AnsiMenuName;
|
PSTR lpszAnsiClassName; // "
|
||||||
HANDLE hIconSm; /* FIXME - Use pointer! */
|
HANDLE hIconSm; /* FIXME - Use pointer! */
|
||||||
|
|
||||||
UINT Destroying : 1;
|
UINT Destroying : 1; // CSF_WOWDEFERDESTROY
|
||||||
UINT Unicode : 1;
|
UINT Unicode : 1;
|
||||||
UINT System : 1; // CSF_SYSTEMCLASS
|
UINT System : 1; // CSF_SYSTEMCLASS
|
||||||
UINT Global : 1; // CS_GLOBALCLASS
|
UINT Global : 1; // CS_GLOBALCLASS
|
||||||
|
@ -1962,11 +1962,11 @@ NtUserGetWindowPlacement(
|
||||||
HWND hWnd,
|
HWND hWnd,
|
||||||
WINDOWPLACEMENT *lpwndpl);
|
WINDOWPLACEMENT *lpwndpl);
|
||||||
|
|
||||||
DWORD
|
PCLS
|
||||||
NTAPI
|
NTAPI
|
||||||
NtUserGetWOWClass(
|
NtUserGetWOWClass(
|
||||||
DWORD Unknown0,
|
HINSTANCE hInstance,
|
||||||
DWORD Unknown1);
|
PUNICODE_STRING ClassName);
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
NTAPI
|
NTAPI
|
||||||
|
|
|
@ -63,11 +63,11 @@ static VOID
|
||||||
IntFreeClassMenuName(IN OUT PCLS Class)
|
IntFreeClassMenuName(IN OUT PCLS Class)
|
||||||
{
|
{
|
||||||
/* free the menu name, if it was changed and allocated */
|
/* free the menu name, if it was changed and allocated */
|
||||||
if (Class->MenuName != NULL && Class->MenuNameIsString)
|
if (Class->lpszClientUnicodeMenuName != NULL && Class->MenuNameIsString)
|
||||||
{
|
{
|
||||||
UserHeapFree(Class->MenuName);
|
UserHeapFree(Class->lpszClientUnicodeMenuName);
|
||||||
Class->MenuName = NULL;
|
Class->lpszClientUnicodeMenuName = NULL;
|
||||||
Class->AnsiMenuName = NULL;
|
Class->lpszClientAnsiMenuName = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -891,30 +891,31 @@ IntCreateClass(IN CONST WNDCLASSEXW* lpwcx,
|
||||||
Class->hCursor = lpwcx->hCursor; /* FIXME */
|
Class->hCursor = lpwcx->hCursor; /* FIXME */
|
||||||
Class->hbrBackground = lpwcx->hbrBackground;
|
Class->hbrBackground = lpwcx->hbrBackground;
|
||||||
|
|
||||||
|
|
||||||
/* make a copy of the string */
|
/* make a copy of the string */
|
||||||
if (pszMenuNameBuffer != NULL)
|
if (pszMenuNameBuffer != NULL)
|
||||||
{
|
{
|
||||||
Class->MenuNameIsString = TRUE;
|
Class->MenuNameIsString = TRUE;
|
||||||
|
|
||||||
Class->MenuName = pszMenuNameBuffer;
|
Class->lpszClientUnicodeMenuName = pszMenuNameBuffer;
|
||||||
RtlCopyMemory(Class->MenuName,
|
RtlCopyMemory(Class->lpszClientUnicodeMenuName,
|
||||||
MenuName->Buffer,
|
MenuName->Buffer,
|
||||||
MenuName->Length);
|
MenuName->Length);
|
||||||
Class->MenuName[MenuName->Length / sizeof(WCHAR)] = UNICODE_NULL;
|
Class->lpszClientUnicodeMenuName[MenuName->Length / sizeof(WCHAR)] = UNICODE_NULL;
|
||||||
|
|
||||||
pszMenuNameBuffer += (MenuName->Length / sizeof(WCHAR)) + 1;
|
pszMenuNameBuffer += (MenuName->Length / sizeof(WCHAR)) + 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Class->MenuName = MenuName->Buffer;
|
Class->lpszClientUnicodeMenuName = MenuName->Buffer;
|
||||||
|
|
||||||
/* save an ansi copy of the string */
|
/* save an ansi copy of the string */
|
||||||
if (pszMenuNameBuffer != NULL)
|
if (pszMenuNameBuffer != NULL)
|
||||||
{
|
{
|
||||||
ANSI_STRING AnsiString;
|
ANSI_STRING AnsiString;
|
||||||
|
|
||||||
Class->AnsiMenuName = (PSTR)pszMenuNameBuffer;
|
Class->lpszClientAnsiMenuName = (PSTR)pszMenuNameBuffer;
|
||||||
AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(MenuName);
|
AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(MenuName);
|
||||||
AnsiString.Buffer = Class->AnsiMenuName;
|
AnsiString.Buffer = Class->lpszClientAnsiMenuName;
|
||||||
Status = RtlUnicodeStringToAnsiString(&AnsiString,
|
Status = RtlUnicodeStringToAnsiString(&AnsiString,
|
||||||
MenuName,
|
MenuName,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
@ -927,7 +928,11 @@ IntCreateClass(IN CONST WNDCLASSEXW* lpwcx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Class->AnsiMenuName = (PSTR)MenuName->Buffer;
|
Class->lpszClientAnsiMenuName = (PSTR)MenuName->Buffer;
|
||||||
|
|
||||||
|
/* Save kernel use menu name and ansi class name */
|
||||||
|
Class->lpszMenuName = Class->lpszClientUnicodeMenuName; // Fixme!
|
||||||
|
//Class->lpszAnsiClassName = Fixme!
|
||||||
|
|
||||||
if (!(dwFlags & CSF_ANSIPROC))
|
if (!(dwFlags & CSF_ANSIPROC))
|
||||||
Class->Unicode = TRUE;
|
Class->Unicode = TRUE;
|
||||||
|
@ -1467,9 +1472,9 @@ UserGetClassLongPtr(IN PCLS Class,
|
||||||
case GCLP_MENUNAME:
|
case GCLP_MENUNAME:
|
||||||
/* NOTE: Returns pointer in kernel heap! */
|
/* NOTE: Returns pointer in kernel heap! */
|
||||||
if (Ansi)
|
if (Ansi)
|
||||||
Ret = (ULONG_PTR)Class->AnsiMenuName;
|
Ret = (ULONG_PTR)Class->lpszClientAnsiMenuName;
|
||||||
else
|
else
|
||||||
Ret = (ULONG_PTR)Class->MenuName;
|
Ret = (ULONG_PTR)Class->lpszClientUnicodeMenuName;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GCL_STYLE:
|
case GCL_STYLE:
|
||||||
|
@ -1547,16 +1552,16 @@ IntSetClassMenuName(IN PCLS Class,
|
||||||
{
|
{
|
||||||
/* update the base class */
|
/* update the base class */
|
||||||
IntFreeClassMenuName(Class);
|
IntFreeClassMenuName(Class);
|
||||||
Class->MenuName = strBufW;
|
Class->lpszClientUnicodeMenuName = strBufW;
|
||||||
Class->AnsiMenuName = AnsiString.Buffer;
|
Class->lpszClientAnsiMenuName = AnsiString.Buffer;
|
||||||
Class->MenuNameIsString = TRUE;
|
Class->MenuNameIsString = TRUE;
|
||||||
|
|
||||||
/* update the clones */
|
/* update the clones */
|
||||||
Class = Class->pclsClone;
|
Class = Class->pclsClone;
|
||||||
while (Class != NULL)
|
while (Class != NULL)
|
||||||
{
|
{
|
||||||
Class->MenuName = strBufW;
|
Class->lpszClientUnicodeMenuName = strBufW;
|
||||||
Class->AnsiMenuName = AnsiString.Buffer;
|
Class->lpszClientAnsiMenuName = AnsiString.Buffer;
|
||||||
Class->MenuNameIsString = TRUE;
|
Class->MenuNameIsString = TRUE;
|
||||||
|
|
||||||
Class = Class->pclsNext;
|
Class = Class->pclsNext;
|
||||||
|
@ -1577,16 +1582,16 @@ IntSetClassMenuName(IN PCLS Class,
|
||||||
|
|
||||||
/* update the base class */
|
/* update the base class */
|
||||||
IntFreeClassMenuName(Class);
|
IntFreeClassMenuName(Class);
|
||||||
Class->MenuName = MenuName->Buffer;
|
Class->lpszClientUnicodeMenuName = MenuName->Buffer;
|
||||||
Class->AnsiMenuName = (PSTR)MenuName->Buffer;
|
Class->lpszClientAnsiMenuName = (PSTR)MenuName->Buffer;
|
||||||
Class->MenuNameIsString = FALSE;
|
Class->MenuNameIsString = FALSE;
|
||||||
|
|
||||||
/* update the clones */
|
/* update the clones */
|
||||||
Class = Class->pclsClone;
|
Class = Class->pclsClone;
|
||||||
while (Class != NULL)
|
while (Class != NULL)
|
||||||
{
|
{
|
||||||
Class->MenuName = MenuName->Buffer;
|
Class->lpszClientUnicodeMenuName = MenuName->Buffer;
|
||||||
Class->AnsiMenuName = (PSTR)MenuName->Buffer;
|
Class->lpszClientAnsiMenuName = (PSTR)MenuName->Buffer;
|
||||||
Class->MenuNameIsString = FALSE;
|
Class->MenuNameIsString = FALSE;
|
||||||
|
|
||||||
Class = Class->pclsNext;
|
Class = Class->pclsNext;
|
||||||
|
@ -1810,18 +1815,31 @@ UserGetClassInfo(IN PCLS Class,
|
||||||
lpwcx->hIcon = Class->hIcon; /* FIXME - get handle from pointer */
|
lpwcx->hIcon = Class->hIcon; /* FIXME - get handle from pointer */
|
||||||
lpwcx->hCursor = Class->hCursor; /* FIXME - get handle from pointer */
|
lpwcx->hCursor = Class->hCursor; /* FIXME - get handle from pointer */
|
||||||
lpwcx->hbrBackground = Class->hbrBackground;
|
lpwcx->hbrBackground = Class->hbrBackground;
|
||||||
|
/*
|
||||||
|
FIXME!
|
||||||
|
Cls: lpszMenuName and lpszAnsiClassName should be used by kernel space.
|
||||||
|
lpszClientXxxMenuName should already be mapped to user space.
|
||||||
|
*/
|
||||||
if (Ansi)
|
if (Ansi)
|
||||||
((PWNDCLASSEXA)lpwcx)->lpszMenuName = Class->AnsiMenuName;
|
((PWNDCLASSEXA)lpwcx)->lpszMenuName = Class->lpszClientAnsiMenuName;
|
||||||
else
|
else
|
||||||
lpwcx->lpszMenuName = Class->MenuName;
|
lpwcx->lpszMenuName = Class->lpszClientUnicodeMenuName;
|
||||||
|
|
||||||
|
if ( Class->lpszClientUnicodeMenuName != NULL &&
|
||||||
|
Class->MenuNameIsString)
|
||||||
|
{
|
||||||
|
lpwcx->lpszMenuName = UserHeapAddressToUser(Ansi ?
|
||||||
|
(PVOID)Class->lpszClientAnsiMenuName :
|
||||||
|
(PVOID)Class->lpszClientUnicodeMenuName);
|
||||||
|
}
|
||||||
|
|
||||||
if (hInstance == hModClient)
|
if (hInstance == hModClient)
|
||||||
lpwcx->hInstance = NULL;
|
lpwcx->hInstance = NULL;
|
||||||
else
|
else
|
||||||
lpwcx->hInstance = hInstance;
|
lpwcx->hInstance = hInstance;
|
||||||
|
|
||||||
lpwcx->lpszClassName = (LPCWSTR)((ULONG_PTR)Class->atomClassName); /* FIXME - return the string? */
|
/* FIXME - return the string? Okay! This is performed in User32!*/
|
||||||
|
//lpwcx->lpszClassName = (LPCWSTR)((ULONG_PTR)Class->atomClassName);
|
||||||
|
|
||||||
lpwcx->hIconSm = Class->hIconSm; /* FIXME - get handle from pointer */
|
lpwcx->hIconSm = Class->hIconSm; /* FIXME - get handle from pointer */
|
||||||
|
|
||||||
|
@ -2010,7 +2028,6 @@ InvalidParameter:
|
||||||
&CapturedMenuName,
|
&CapturedMenuName,
|
||||||
wpExtra,
|
wpExtra,
|
||||||
Flags);
|
Flags);
|
||||||
|
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
|
@ -2146,6 +2163,9 @@ NtUserSetClassWord(
|
||||||
INT nIndex,
|
INT nIndex,
|
||||||
WORD wNewWord)
|
WORD wNewWord)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* NOTE: Obsoleted in 32-bit windows
|
||||||
|
*/
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2195,7 +2215,6 @@ InvalidParameter:
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
|
|
||||||
UserLeave();
|
UserLeave();
|
||||||
|
|
||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2208,107 +2227,134 @@ NtUserGetClassInfo(
|
||||||
LPWSTR *ppszMenuName,
|
LPWSTR *ppszMenuName,
|
||||||
BOOL Ansi)
|
BOOL Ansi)
|
||||||
{
|
{
|
||||||
UNICODE_STRING CapturedClassName;
|
UNICODE_STRING CapturedClassName, SafeClassName;
|
||||||
PCLS Class;
|
WNDCLASSEXW Safewcexw;
|
||||||
RTL_ATOM ClassAtom;
|
PCLS Class;
|
||||||
PPROCESSINFO pi;
|
RTL_ATOM ClassAtom = 0;
|
||||||
BOOL Ret = FALSE;
|
PPROCESSINFO pi;
|
||||||
|
BOOL Ret = TRUE;
|
||||||
|
|
||||||
/* NOTE: need exclusive lock because getting the wndproc might require the
|
/* NOTE: need exclusive lock because getting the wndproc might require the
|
||||||
creation of a call procedure handle */
|
creation of a call procedure handle */
|
||||||
UserEnterExclusive();
|
UserEnterExclusive();
|
||||||
|
|
||||||
pi = GetW32ProcessInfo();
|
pi = GetW32ProcessInfo();
|
||||||
if (pi == NULL)
|
if (pi == NULL)
|
||||||
{
|
{
|
||||||
ERR("GetW32ProcessInfo() returned NULL!\n");
|
ERR("GetW32ProcessInfo() returned NULL!\n");
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
_SEH2_TRY
|
|
||||||
{
|
|
||||||
/* probe the paramters */
|
|
||||||
CapturedClassName = ProbeForReadUnicodeString(ClassName);
|
|
||||||
|
|
||||||
if (CapturedClassName.Length == 0)
|
_SEH2_TRY
|
||||||
TRACE("hInst %p atom %04X lpWndClassEx %p Ansi %d\n", hInstance, CapturedClassName.Buffer, lpWndClassEx, Ansi);
|
{
|
||||||
else
|
/* probe the paramters */
|
||||||
TRACE("hInst %p class %wZ lpWndClassEx %p Ansi %d\n", hInstance, &CapturedClassName, lpWndClassEx, Ansi);
|
CapturedClassName = ProbeForReadUnicodeString(ClassName);
|
||||||
|
|
||||||
if (CapturedClassName.Length & 1)
|
if (CapturedClassName.Length == 0)
|
||||||
{
|
TRACE("hInst %p atom %04X lpWndClassEx %p Ansi %d\n", hInstance, CapturedClassName.Buffer, lpWndClassEx, Ansi);
|
||||||
|
else
|
||||||
|
TRACE("hInst %p class %wZ lpWndClassEx %p Ansi %d\n", hInstance, &CapturedClassName, lpWndClassEx, Ansi);
|
||||||
|
|
||||||
|
if (CapturedClassName.Length & 1)
|
||||||
|
{
|
||||||
|
goto InvalidParameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CapturedClassName.Length != 0)
|
||||||
|
{
|
||||||
|
ProbeForRead( CapturedClassName.Buffer,
|
||||||
|
CapturedClassName.Length,
|
||||||
|
sizeof(WCHAR));
|
||||||
|
|
||||||
|
RtlInitUnicodeString( &SafeClassName, CapturedClassName.Buffer);
|
||||||
|
|
||||||
|
SafeClassName.Buffer = ExAllocatePoolWithTag( PagedPool,
|
||||||
|
SafeClassName.MaximumLength,
|
||||||
|
TAG_STRING);
|
||||||
|
RtlCopyMemory( SafeClassName.Buffer,
|
||||||
|
CapturedClassName.Buffer,
|
||||||
|
SafeClassName.MaximumLength);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!IS_ATOM(CapturedClassName.Buffer))
|
||||||
|
{
|
||||||
|
ERR("NtUserGetClassInfo() got ClassName instead of Atom!\n");
|
||||||
goto InvalidParameter;
|
goto InvalidParameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CapturedClassName.Length != 0)
|
SafeClassName.Buffer = CapturedClassName.Buffer;
|
||||||
{
|
SafeClassName.Length = 0;
|
||||||
ProbeForRead(CapturedClassName.Buffer,
|
SafeClassName.MaximumLength = 0;
|
||||||
CapturedClassName.Length,
|
}
|
||||||
sizeof(WCHAR));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!IS_ATOM(CapturedClassName.Buffer))
|
|
||||||
{
|
|
||||||
ERR("NtUserGetClassInfo() got ClassName instead of Atom!\n");
|
|
||||||
goto InvalidParameter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ProbeForReadUint(&lpWndClassEx->cbSize) != sizeof(WNDCLASSEXW))
|
if (ProbeForReadUint(&lpWndClassEx->cbSize) != sizeof(WNDCLASSEXW))
|
||||||
{
|
{
|
||||||
InvalidParameter:
|
InvalidParameter:
|
||||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||||
_SEH2_LEAVE;
|
Ret = FALSE;
|
||||||
}
|
_SEH2_LEAVE;
|
||||||
|
}
|
||||||
|
|
||||||
ProbeForWrite(lpWndClassEx,
|
ProbeForWrite( lpWndClassEx, sizeof(WNDCLASSEXW), sizeof(ULONG));
|
||||||
sizeof(WNDCLASSEXW),
|
|
||||||
sizeof(ULONG));
|
|
||||||
|
|
||||||
ClassAtom = IntGetClassAtom(&CapturedClassName,
|
RtlCopyMemory( &Safewcexw, lpWndClassEx, sizeof(WNDCLASSEXW));
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
|
||||||
|
Ret = FALSE;
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
|
if (Ret)
|
||||||
|
{
|
||||||
|
ClassAtom = IntGetClassAtom( &SafeClassName,
|
||||||
hInstance,
|
hInstance,
|
||||||
pi,
|
pi,
|
||||||
&Class,
|
&Class,
|
||||||
NULL);
|
NULL);
|
||||||
if (ClassAtom != (RTL_ATOM)0)
|
if (ClassAtom != (RTL_ATOM)0)
|
||||||
{
|
{
|
||||||
if (hInstance == NULL)
|
if (hInstance == NULL) hInstance = hModClient;
|
||||||
hInstance = hModClient;
|
|
||||||
|
|
||||||
Ret = UserGetClassInfo(Class,
|
Ret = UserGetClassInfo( Class,
|
||||||
lpWndClassEx,
|
&Safewcexw,
|
||||||
Ansi,
|
Ansi,
|
||||||
hInstance);
|
hInstance);
|
||||||
|
}
|
||||||
if (Ret)
|
else
|
||||||
{
|
{
|
||||||
lpWndClassEx->lpszClassName = CapturedClassName.Buffer;
|
|
||||||
/* FIXME - handle Class->Desktop == NULL!!!!! */
|
|
||||||
|
|
||||||
if (Class->MenuName != NULL && Class->MenuNameIsString)
|
|
||||||
{
|
|
||||||
lpWndClassEx->lpszMenuName = UserHeapAddressToUser(Ansi ?
|
|
||||||
(PVOID)Class->AnsiMenuName :
|
|
||||||
(PVOID)Class->MenuName);
|
|
||||||
}
|
|
||||||
// From Wine:
|
|
||||||
/* We must return the atom of the class here instead of just TRUE. */
|
|
||||||
/* Undocumented behavior! Return the class atom as a BOOL! */
|
|
||||||
Ret = (BOOL)ClassAtom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
|
|
||||||
}
|
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
||||||
{
|
|
||||||
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
|
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
|
||||||
}
|
Ret = FALSE;
|
||||||
_SEH2_END;
|
}
|
||||||
|
}
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
if (Ret)
|
||||||
|
{
|
||||||
|
/* Emulate Function. */
|
||||||
|
if (ppszMenuName) *ppszMenuName = (LPWSTR)Safewcexw.lpszMenuName;
|
||||||
|
|
||||||
|
RtlCopyMemory(lpWndClassEx, &Safewcexw, sizeof(WNDCLASSEXW));
|
||||||
|
|
||||||
|
// From Wine:
|
||||||
|
/* We must return the atom of the class here instead of just TRUE. */
|
||||||
|
/* Undocumented behavior! Return the class atom as a BOOL! */
|
||||||
|
Ret = (BOOL)ClassAtom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
|
||||||
|
Ret = FALSE;
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
Cleanup:
|
Cleanup:
|
||||||
UserLeave();
|
if (SafeClassName.Length) ExFreePoolWithTag(SafeClassName.Buffer, TAG_STRING);
|
||||||
return Ret;
|
UserLeave();
|
||||||
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2355,11 +2401,85 @@ NtUserGetClassName (IN HWND hWnd,
|
||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD APIENTRY
|
/* Return Pointer to Class structure. */
|
||||||
NtUserGetWOWClass(DWORD Unknown0,
|
PCLS APIENTRY
|
||||||
DWORD Unknown1)
|
NtUserGetWOWClass(HINSTANCE hInstance,
|
||||||
|
PUNICODE_STRING ClassName)
|
||||||
{
|
{
|
||||||
return(0);
|
UNICODE_STRING SafeClassName;
|
||||||
|
PPROCESSINFO pi;
|
||||||
|
PCLS Class = NULL;
|
||||||
|
RTL_ATOM ClassAtom = 0;
|
||||||
|
BOOL Hit = FALSE;
|
||||||
|
|
||||||
|
UserEnterExclusive();
|
||||||
|
|
||||||
|
pi = GetW32ProcessInfo();
|
||||||
|
if (pi == NULL)
|
||||||
|
{
|
||||||
|
ERR("GetW32ProcessInfo() returned NULL!\n");
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
if (ClassName->Length != 0)
|
||||||
|
{
|
||||||
|
ProbeForRead( ClassName->Buffer,
|
||||||
|
ClassName->Length,
|
||||||
|
sizeof(WCHAR));
|
||||||
|
|
||||||
|
RtlInitUnicodeString( &SafeClassName, ClassName->Buffer);
|
||||||
|
|
||||||
|
SafeClassName.Buffer = ExAllocatePoolWithTag( PagedPool,
|
||||||
|
SafeClassName.MaximumLength,
|
||||||
|
TAG_STRING);
|
||||||
|
RtlCopyMemory( SafeClassName.Buffer,
|
||||||
|
ClassName->Buffer,
|
||||||
|
SafeClassName.MaximumLength);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!IS_ATOM(ClassName->Buffer))
|
||||||
|
{
|
||||||
|
ERR("NtUserGetWOWClass() got ClassName instead of Atom!\n");
|
||||||
|
Hit = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SafeClassName.Buffer = ClassName->Buffer;
|
||||||
|
SafeClassName.Length = 0;
|
||||||
|
SafeClassName.MaximumLength = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
|
||||||
|
Hit = TRUE;
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
|
if (!Hit)
|
||||||
|
{
|
||||||
|
ClassAtom = IntGetClassAtom( &SafeClassName,
|
||||||
|
hInstance,
|
||||||
|
pi,
|
||||||
|
&Class,
|
||||||
|
NULL);
|
||||||
|
if (!ClassAtom)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Cleanup:
|
||||||
|
if (SafeClassName.Length) ExFreePoolWithTag(SafeClassName.Buffer, TAG_STRING);
|
||||||
|
UserLeave();
|
||||||
|
//
|
||||||
|
// Don't forget to use DesktopPtrToUser( ? ) with return pointer in user space.
|
||||||
|
//
|
||||||
|
return Class;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -1838,7 +1838,7 @@ AllocErr:
|
||||||
{
|
{
|
||||||
UNICODE_STRING MenuName;
|
UNICODE_STRING MenuName;
|
||||||
|
|
||||||
RtlInitUnicodeString( &MenuName, Wnd->pcls->MenuName);
|
RtlInitUnicodeString( &MenuName, Wnd->pcls->lpszMenuName);
|
||||||
|
|
||||||
hMenu = co_IntCallLoadMenu( Wnd->pcls->hModule, &MenuName);
|
hMenu = co_IntCallLoadMenu( Wnd->pcls->hModule, &MenuName);
|
||||||
if (hMenu) IntSetMenu(Window, hMenu, &MenuChanged);
|
if (hMenu) IntSetMenu(Window, hMenu, &MenuChanged);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue