mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 16:01:53 +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};
|
||||
BOOL Ret;
|
||||
LPCSTR pszMenuName;
|
||||
|
||||
TRACE("%p class/atom: %s/%04x %p\n", hInstance,
|
||||
IS_ATOM(lpszClass) ? NULL : lpszClass,
|
||||
|
@ -62,8 +63,13 @@ GetClassInfoExA(
|
|||
Ret = NtUserGetClassInfo(hInstance,
|
||||
&ClassName,
|
||||
(LPWNDCLASSEXW)lpwcx,
|
||||
NULL,
|
||||
(LPWSTR *)&pszMenuName,
|
||||
TRUE);
|
||||
if (Ret)
|
||||
{
|
||||
lpwcx->lpszClassName = lpszClass;
|
||||
// lpwcx->lpszMenuName = pszMenuName;
|
||||
}
|
||||
|
||||
if (!IS_ATOM(lpszClass))
|
||||
{
|
||||
|
@ -85,6 +91,8 @@ GetClassInfoExW(
|
|||
LPWNDCLASSEXW lpwcx)
|
||||
{
|
||||
UNICODE_STRING ClassName = {0};
|
||||
BOOL Ret;
|
||||
LPWSTR pszMenuName;
|
||||
|
||||
TRACE("%p class/atom: %S/%04x %p\n", hInstance,
|
||||
IS_ATOM(lpszClass) ? NULL : lpszClass,
|
||||
|
@ -115,11 +123,17 @@ GetClassInfoExW(
|
|||
lpszClass);
|
||||
}
|
||||
|
||||
return NtUserGetClassInfo(hInstance,
|
||||
Ret = NtUserGetClassInfo( hInstance,
|
||||
&ClassName,
|
||||
lpwcx,
|
||||
NULL,
|
||||
&pszMenuName,
|
||||
FALSE);
|
||||
if (Ret)
|
||||
{
|
||||
lpwcx->lpszClassName = lpszClass;
|
||||
// lpwcx->lpszMenuName = pszMenuName;
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -238,7 +252,7 @@ GetClassLongA(HWND hWnd, int nIndex)
|
|||
break;
|
||||
|
||||
case GCL_MENUNAME:
|
||||
Ret = (ULONG_PTR)Class->AnsiMenuName;
|
||||
Ret = (ULONG_PTR)Class->lpszClientAnsiMenuName;
|
||||
break;
|
||||
|
||||
case GCL_STYLE:
|
||||
|
@ -351,7 +365,7 @@ GetClassLongW ( HWND hWnd, int nIndex )
|
|||
break;
|
||||
|
||||
case GCL_MENUNAME:
|
||||
Ret = (ULONG_PTR)Class->MenuName;
|
||||
Ret = (ULONG_PTR)Class->lpszClientUnicodeMenuName;
|
||||
break;
|
||||
|
||||
case GCL_STYLE:
|
||||
|
|
|
@ -970,7 +970,7 @@ static void DefWndPrint( HWND hwnd, HDC hdc, ULONG uFlags)
|
|||
* Client area
|
||||
*/
|
||||
if ( uFlags & PRF_CLIENT)
|
||||
SendMessageW(hwnd, WM_PRINTCLIENT, (WPARAM)hdc, PRF_CLIENT);
|
||||
SendMessageW(hwnd, WM_PRINTCLIENT, (WPARAM)hdc, uFlags);
|
||||
}
|
||||
|
||||
static BOOL CALLBACK
|
||||
|
|
|
@ -116,8 +116,8 @@ typedef struct _CLS
|
|||
struct _DESKTOP *rpdeskParent;
|
||||
PVOID pdce;
|
||||
DWORD CSF_flags;
|
||||
PSTR lpszClientAnsiMenuName;
|
||||
PWSTR lpszClientUnicodeMenuName;
|
||||
PSTR lpszClientAnsiMenuName; // For client use
|
||||
PWSTR lpszClientUnicodeMenuName; // " " "
|
||||
PCALLPROC spcpdFirst;
|
||||
struct _CLS *pclsBase;
|
||||
struct _CLS *pclsClone;
|
||||
|
@ -135,11 +135,11 @@ typedef struct _CLS
|
|||
HANDLE hIcon; /* FIXME - Use pointer! */
|
||||
HANDLE hCursor; /* FIXME - Use pointer! */
|
||||
HBRUSH hbrBackground;
|
||||
PWSTR MenuName;
|
||||
PSTR AnsiMenuName;
|
||||
PWSTR lpszMenuName; // kernel use
|
||||
PSTR lpszAnsiClassName; // "
|
||||
HANDLE hIconSm; /* FIXME - Use pointer! */
|
||||
|
||||
UINT Destroying : 1;
|
||||
UINT Destroying : 1; // CSF_WOWDEFERDESTROY
|
||||
UINT Unicode : 1;
|
||||
UINT System : 1; // CSF_SYSTEMCLASS
|
||||
UINT Global : 1; // CS_GLOBALCLASS
|
||||
|
@ -1962,11 +1962,11 @@ NtUserGetWindowPlacement(
|
|||
HWND hWnd,
|
||||
WINDOWPLACEMENT *lpwndpl);
|
||||
|
||||
DWORD
|
||||
PCLS
|
||||
NTAPI
|
||||
NtUserGetWOWClass(
|
||||
DWORD Unknown0,
|
||||
DWORD Unknown1);
|
||||
HINSTANCE hInstance,
|
||||
PUNICODE_STRING ClassName);
|
||||
|
||||
DWORD
|
||||
NTAPI
|
||||
|
|
|
@ -63,11 +63,11 @@ static VOID
|
|||
IntFreeClassMenuName(IN OUT PCLS Class)
|
||||
{
|
||||
/* 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);
|
||||
Class->MenuName = NULL;
|
||||
Class->AnsiMenuName = NULL;
|
||||
UserHeapFree(Class->lpszClientUnicodeMenuName);
|
||||
Class->lpszClientUnicodeMenuName = NULL;
|
||||
Class->lpszClientAnsiMenuName = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -891,30 +891,31 @@ IntCreateClass(IN CONST WNDCLASSEXW* lpwcx,
|
|||
Class->hCursor = lpwcx->hCursor; /* FIXME */
|
||||
Class->hbrBackground = lpwcx->hbrBackground;
|
||||
|
||||
|
||||
/* make a copy of the string */
|
||||
if (pszMenuNameBuffer != NULL)
|
||||
{
|
||||
Class->MenuNameIsString = TRUE;
|
||||
|
||||
Class->MenuName = pszMenuNameBuffer;
|
||||
RtlCopyMemory(Class->MenuName,
|
||||
Class->lpszClientUnicodeMenuName = pszMenuNameBuffer;
|
||||
RtlCopyMemory(Class->lpszClientUnicodeMenuName,
|
||||
MenuName->Buffer,
|
||||
MenuName->Length);
|
||||
Class->MenuName[MenuName->Length / sizeof(WCHAR)] = UNICODE_NULL;
|
||||
Class->lpszClientUnicodeMenuName[MenuName->Length / sizeof(WCHAR)] = UNICODE_NULL;
|
||||
|
||||
pszMenuNameBuffer += (MenuName->Length / sizeof(WCHAR)) + 1;
|
||||
}
|
||||
else
|
||||
Class->MenuName = MenuName->Buffer;
|
||||
Class->lpszClientUnicodeMenuName = MenuName->Buffer;
|
||||
|
||||
/* save an ansi copy of the string */
|
||||
if (pszMenuNameBuffer != NULL)
|
||||
{
|
||||
ANSI_STRING AnsiString;
|
||||
|
||||
Class->AnsiMenuName = (PSTR)pszMenuNameBuffer;
|
||||
Class->lpszClientAnsiMenuName = (PSTR)pszMenuNameBuffer;
|
||||
AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(MenuName);
|
||||
AnsiString.Buffer = Class->AnsiMenuName;
|
||||
AnsiString.Buffer = Class->lpszClientAnsiMenuName;
|
||||
Status = RtlUnicodeStringToAnsiString(&AnsiString,
|
||||
MenuName,
|
||||
FALSE);
|
||||
|
@ -927,7 +928,11 @@ IntCreateClass(IN CONST WNDCLASSEXW* lpwcx,
|
|||
}
|
||||
}
|
||||
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))
|
||||
Class->Unicode = TRUE;
|
||||
|
@ -1467,9 +1472,9 @@ UserGetClassLongPtr(IN PCLS Class,
|
|||
case GCLP_MENUNAME:
|
||||
/* NOTE: Returns pointer in kernel heap! */
|
||||
if (Ansi)
|
||||
Ret = (ULONG_PTR)Class->AnsiMenuName;
|
||||
Ret = (ULONG_PTR)Class->lpszClientAnsiMenuName;
|
||||
else
|
||||
Ret = (ULONG_PTR)Class->MenuName;
|
||||
Ret = (ULONG_PTR)Class->lpszClientUnicodeMenuName;
|
||||
break;
|
||||
|
||||
case GCL_STYLE:
|
||||
|
@ -1547,16 +1552,16 @@ IntSetClassMenuName(IN PCLS Class,
|
|||
{
|
||||
/* update the base class */
|
||||
IntFreeClassMenuName(Class);
|
||||
Class->MenuName = strBufW;
|
||||
Class->AnsiMenuName = AnsiString.Buffer;
|
||||
Class->lpszClientUnicodeMenuName = strBufW;
|
||||
Class->lpszClientAnsiMenuName = AnsiString.Buffer;
|
||||
Class->MenuNameIsString = TRUE;
|
||||
|
||||
/* update the clones */
|
||||
Class = Class->pclsClone;
|
||||
while (Class != NULL)
|
||||
{
|
||||
Class->MenuName = strBufW;
|
||||
Class->AnsiMenuName = AnsiString.Buffer;
|
||||
Class->lpszClientUnicodeMenuName = strBufW;
|
||||
Class->lpszClientAnsiMenuName = AnsiString.Buffer;
|
||||
Class->MenuNameIsString = TRUE;
|
||||
|
||||
Class = Class->pclsNext;
|
||||
|
@ -1577,16 +1582,16 @@ IntSetClassMenuName(IN PCLS Class,
|
|||
|
||||
/* update the base class */
|
||||
IntFreeClassMenuName(Class);
|
||||
Class->MenuName = MenuName->Buffer;
|
||||
Class->AnsiMenuName = (PSTR)MenuName->Buffer;
|
||||
Class->lpszClientUnicodeMenuName = MenuName->Buffer;
|
||||
Class->lpszClientAnsiMenuName = (PSTR)MenuName->Buffer;
|
||||
Class->MenuNameIsString = FALSE;
|
||||
|
||||
/* update the clones */
|
||||
Class = Class->pclsClone;
|
||||
while (Class != NULL)
|
||||
{
|
||||
Class->MenuName = MenuName->Buffer;
|
||||
Class->AnsiMenuName = (PSTR)MenuName->Buffer;
|
||||
Class->lpszClientUnicodeMenuName = MenuName->Buffer;
|
||||
Class->lpszClientAnsiMenuName = (PSTR)MenuName->Buffer;
|
||||
Class->MenuNameIsString = FALSE;
|
||||
|
||||
Class = Class->pclsNext;
|
||||
|
@ -1810,18 +1815,31 @@ UserGetClassInfo(IN PCLS Class,
|
|||
lpwcx->hIcon = Class->hIcon; /* FIXME - get handle from pointer */
|
||||
lpwcx->hCursor = Class->hCursor; /* FIXME - get handle from pointer */
|
||||
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)
|
||||
((PWNDCLASSEXA)lpwcx)->lpszMenuName = Class->AnsiMenuName;
|
||||
((PWNDCLASSEXA)lpwcx)->lpszMenuName = Class->lpszClientAnsiMenuName;
|
||||
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)
|
||||
lpwcx->hInstance = NULL;
|
||||
else
|
||||
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 */
|
||||
|
||||
|
@ -2010,7 +2028,6 @@ InvalidParameter:
|
|||
&CapturedMenuName,
|
||||
wpExtra,
|
||||
Flags);
|
||||
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
|
@ -2146,6 +2163,9 @@ NtUserSetClassWord(
|
|||
INT nIndex,
|
||||
WORD wNewWord)
|
||||
{
|
||||
/*
|
||||
* NOTE: Obsoleted in 32-bit windows
|
||||
*/
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -2195,7 +2215,6 @@ InvalidParameter:
|
|||
_SEH2_END;
|
||||
|
||||
UserLeave();
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
@ -2208,107 +2227,134 @@ NtUserGetClassInfo(
|
|||
LPWSTR *ppszMenuName,
|
||||
BOOL Ansi)
|
||||
{
|
||||
UNICODE_STRING CapturedClassName;
|
||||
PCLS Class;
|
||||
RTL_ATOM ClassAtom;
|
||||
PPROCESSINFO pi;
|
||||
BOOL Ret = FALSE;
|
||||
UNICODE_STRING CapturedClassName, SafeClassName;
|
||||
WNDCLASSEXW Safewcexw;
|
||||
PCLS Class;
|
||||
RTL_ATOM ClassAtom = 0;
|
||||
PPROCESSINFO pi;
|
||||
BOOL Ret = TRUE;
|
||||
|
||||
/* NOTE: need exclusive lock because getting the wndproc might require the
|
||||
creation of a call procedure handle */
|
||||
UserEnterExclusive();
|
||||
/* NOTE: need exclusive lock because getting the wndproc might require the
|
||||
creation of a call procedure handle */
|
||||
UserEnterExclusive();
|
||||
|
||||
pi = GetW32ProcessInfo();
|
||||
if (pi == NULL)
|
||||
{
|
||||
ERR("GetW32ProcessInfo() returned NULL!\n");
|
||||
goto Cleanup;
|
||||
}
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* probe the paramters */
|
||||
CapturedClassName = ProbeForReadUnicodeString(ClassName);
|
||||
pi = GetW32ProcessInfo();
|
||||
if (pi == NULL)
|
||||
{
|
||||
ERR("GetW32ProcessInfo() returned NULL!\n");
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
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);
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* probe the paramters */
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (CapturedClassName.Length != 0)
|
||||
{
|
||||
ProbeForRead(CapturedClassName.Buffer,
|
||||
CapturedClassName.Length,
|
||||
sizeof(WCHAR));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!IS_ATOM(CapturedClassName.Buffer))
|
||||
{
|
||||
ERR("NtUserGetClassInfo() got ClassName instead of Atom!\n");
|
||||
goto InvalidParameter;
|
||||
}
|
||||
}
|
||||
SafeClassName.Buffer = CapturedClassName.Buffer;
|
||||
SafeClassName.Length = 0;
|
||||
SafeClassName.MaximumLength = 0;
|
||||
}
|
||||
|
||||
if (ProbeForReadUint(&lpWndClassEx->cbSize) != sizeof(WNDCLASSEXW))
|
||||
{
|
||||
if (ProbeForReadUint(&lpWndClassEx->cbSize) != sizeof(WNDCLASSEXW))
|
||||
{
|
||||
InvalidParameter:
|
||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||
Ret = FALSE;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
ProbeForWrite(lpWndClassEx,
|
||||
sizeof(WNDCLASSEXW),
|
||||
sizeof(ULONG));
|
||||
ProbeForWrite( lpWndClassEx, 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,
|
||||
pi,
|
||||
&Class,
|
||||
&Class,
|
||||
NULL);
|
||||
if (ClassAtom != (RTL_ATOM)0)
|
||||
{
|
||||
if (hInstance == NULL)
|
||||
hInstance = hModClient;
|
||||
if (ClassAtom != (RTL_ATOM)0)
|
||||
{
|
||||
if (hInstance == NULL) hInstance = hModClient;
|
||||
|
||||
Ret = UserGetClassInfo(Class,
|
||||
lpWndClassEx,
|
||||
Ansi,
|
||||
hInstance);
|
||||
|
||||
if (Ret)
|
||||
{
|
||||
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)
|
||||
{
|
||||
Ret = UserGetClassInfo( Class,
|
||||
&Safewcexw,
|
||||
Ansi,
|
||||
hInstance);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
|
||||
}
|
||||
_SEH2_END;
|
||||
Ret = FALSE;
|
||||
}
|
||||
}
|
||||
_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:
|
||||
UserLeave();
|
||||
return Ret;
|
||||
if (SafeClassName.Length) ExFreePoolWithTag(SafeClassName.Buffer, TAG_STRING);
|
||||
UserLeave();
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2355,11 +2401,85 @@ NtUserGetClassName (IN HWND hWnd,
|
|||
return Ret;
|
||||
}
|
||||
|
||||
DWORD APIENTRY
|
||||
NtUserGetWOWClass(DWORD Unknown0,
|
||||
DWORD Unknown1)
|
||||
/* Return Pointer to Class structure. */
|
||||
PCLS APIENTRY
|
||||
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 */
|
||||
|
|
|
@ -1838,7 +1838,7 @@ AllocErr:
|
|||
{
|
||||
UNICODE_STRING MenuName;
|
||||
|
||||
RtlInitUnicodeString( &MenuName, Wnd->pcls->MenuName);
|
||||
RtlInitUnicodeString( &MenuName, Wnd->pcls->lpszMenuName);
|
||||
|
||||
hMenu = co_IntCallLoadMenu( Wnd->pcls->hModule, &MenuName);
|
||||
if (hMenu) IntSetMenu(Window, hMenu, &MenuChanged);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue