mirror of
https://github.com/reactos/reactos.git
synced 2024-10-04 08:25:53 +00:00
Protect GetClassLong() and GetWindowText() with SEH as they're following pointers in the desktop heap
svn path=/trunk/; revision=30513
This commit is contained in:
parent
2348eeb813
commit
7033c976bb
|
@ -14,6 +14,7 @@
|
|||
<library>advapi32</library>
|
||||
<library>imm32</library>
|
||||
<library>win32ksys</library>
|
||||
<library>pseh</library>
|
||||
|
||||
<directory name="include">
|
||||
<pch>user32.h</pch>
|
||||
|
|
|
@ -199,80 +199,101 @@ GetClassLongA(HWND hWnd, int nIndex)
|
|||
if (!Wnd)
|
||||
return 0;
|
||||
|
||||
Class = DesktopPtrToUser(Wnd->Class);
|
||||
ASSERT(Class != NULL);
|
||||
|
||||
if (nIndex >= 0)
|
||||
_SEH_TRY
|
||||
{
|
||||
if (nIndex + sizeof(ULONG_PTR) < nIndex ||
|
||||
nIndex + sizeof(ULONG_PTR) > Class->ClsExtra)
|
||||
Class = DesktopPtrToUser(Wnd->Class);
|
||||
if (Class != NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
if (nIndex >= 0)
|
||||
{
|
||||
if (nIndex + sizeof(ULONG_PTR) < nIndex ||
|
||||
nIndex + sizeof(ULONG_PTR) > Class->ClsExtra)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
}
|
||||
else
|
||||
Ret = *(PULONG_PTR)((ULONG_PTR)(Class + 1) + nIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (nIndex)
|
||||
{
|
||||
case GCL_CBWNDEXTRA:
|
||||
Ret = (ULONG_PTR)Class->WndExtra;
|
||||
break;
|
||||
|
||||
case GCL_CBCLSEXTRA:
|
||||
Ret = (ULONG_PTR)Class->ClsExtra;
|
||||
break;
|
||||
|
||||
case GCL_HBRBACKGROUND:
|
||||
Ret = (ULONG_PTR)Class->hbrBackground;
|
||||
if (Ret != 0 && Ret < 0x4000)
|
||||
Ret = (ULONG_PTR)GetSysColorBrush((ULONG)Ret - 1);
|
||||
break;
|
||||
|
||||
case GCL_HMODULE:
|
||||
Ret = (ULONG_PTR)Class->hInstance;
|
||||
break;
|
||||
|
||||
case GCL_MENUNAME:
|
||||
Ret = (ULONG_PTR)Class->AnsiMenuName;
|
||||
break;
|
||||
|
||||
case GCL_STYLE:
|
||||
Ret = (ULONG_PTR)Class->Style;
|
||||
break;
|
||||
|
||||
case GCW_ATOM:
|
||||
Ret = (ULONG_PTR)Class->Atom;
|
||||
break;
|
||||
|
||||
case GCLP_HCURSOR:
|
||||
/* FIXME - get handle from pointer to CURSOR object */
|
||||
Ret = (ULONG_PTR)Class->hCursor;
|
||||
break;
|
||||
|
||||
case GCLP_HICON:
|
||||
/* FIXME - get handle from pointer to ICON object */
|
||||
Ret = (ULONG_PTR)Class->hIcon;
|
||||
break;
|
||||
|
||||
case GCLP_HICONSM:
|
||||
/* FIXME - get handle from pointer to ICON object */
|
||||
Ret = (ULONG_PTR)Class->hIconSm;
|
||||
break;
|
||||
|
||||
case GCLP_WNDPROC:
|
||||
/* We need to make a call to win32k as it may be required to
|
||||
create a callproc handle */
|
||||
Wnd = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
SetLastError(ERROR_INVALID_INDEX);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ret = *(PULONG_PTR)((ULONG_PTR)(Class + 1) + nIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (nIndex)
|
||||
else
|
||||
{
|
||||
case GCL_CBWNDEXTRA:
|
||||
Ret = (ULONG_PTR)Class->WndExtra;
|
||||
break;
|
||||
/* This is a race condition! Call win32k to make sure we're getting
|
||||
the correct result */
|
||||
Wnd = NULL; /* Make sure we call NtUserGetClassLong */
|
||||
|
||||
case GCL_CBCLSEXTRA:
|
||||
Ret = (ULONG_PTR)Class->ClsExtra;
|
||||
break;
|
||||
|
||||
case GCL_HBRBACKGROUND:
|
||||
Ret = (ULONG_PTR)Class->hbrBackground;
|
||||
if (Ret != 0 && Ret < 0x4000)
|
||||
Ret = (ULONG_PTR)GetSysColorBrush((ULONG)Ret - 1);
|
||||
break;
|
||||
|
||||
case GCL_HMODULE:
|
||||
Ret = (ULONG_PTR)Class->hInstance;
|
||||
break;
|
||||
|
||||
case GCL_MENUNAME:
|
||||
Ret = (ULONG_PTR)Class->AnsiMenuName;
|
||||
break;
|
||||
|
||||
case GCL_STYLE:
|
||||
Ret = (ULONG_PTR)Class->Style;
|
||||
break;
|
||||
|
||||
case GCW_ATOM:
|
||||
Ret = (ULONG_PTR)Class->Atom;
|
||||
break;
|
||||
|
||||
case GCLP_HCURSOR:
|
||||
/* FIXME - get handle from pointer to CURSOR object */
|
||||
Ret = (ULONG_PTR)Class->hCursor;
|
||||
break;
|
||||
|
||||
case GCLP_HICON:
|
||||
/* FIXME - get handle from pointer to ICON object */
|
||||
Ret = (ULONG_PTR)Class->hIcon;
|
||||
break;
|
||||
|
||||
case GCLP_HICONSM:
|
||||
/* FIXME - get handle from pointer to ICON object */
|
||||
Ret = (ULONG_PTR)Class->hIconSm;
|
||||
break;
|
||||
|
||||
case GCLP_WNDPROC:
|
||||
/* We need to make a call to win32k as it may be required to
|
||||
create a callproc handle */
|
||||
return NtUserGetClassLong(hWnd, nIndex, TRUE);
|
||||
|
||||
default:
|
||||
SetLastError(ERROR_INVALID_INDEX);
|
||||
WARN("Invalid class for hwnd 0x%p!\n", hWnd);
|
||||
}
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Wnd = NULL; /* Make sure we call NtUserGetClassLong */
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
return Ret;
|
||||
if (Wnd == NULL)
|
||||
Ret = NtUserGetClassLong(hWnd, nIndex, TRUE);
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -291,80 +312,101 @@ GetClassLongW ( HWND hWnd, int nIndex )
|
|||
if (!Wnd)
|
||||
return 0;
|
||||
|
||||
Class = DesktopPtrToUser(Wnd->Class);
|
||||
ASSERT(Class != NULL);
|
||||
|
||||
if (nIndex >= 0)
|
||||
_SEH_TRY
|
||||
{
|
||||
if (nIndex + sizeof(ULONG_PTR) < nIndex ||
|
||||
nIndex + sizeof(ULONG_PTR) > Class->ClsExtra)
|
||||
Class = DesktopPtrToUser(Wnd->Class);
|
||||
if (Class != NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
if (nIndex >= 0)
|
||||
{
|
||||
if (nIndex + sizeof(ULONG_PTR) < nIndex ||
|
||||
nIndex + sizeof(ULONG_PTR) > Class->ClsExtra)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
}
|
||||
else
|
||||
Ret = *(PULONG_PTR)((ULONG_PTR)(Class + 1) + nIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (nIndex)
|
||||
{
|
||||
case GCL_CBWNDEXTRA:
|
||||
Ret = (ULONG_PTR)Class->WndExtra;
|
||||
break;
|
||||
|
||||
case GCL_CBCLSEXTRA:
|
||||
Ret = (ULONG_PTR)Class->ClsExtra;
|
||||
break;
|
||||
|
||||
case GCL_HBRBACKGROUND:
|
||||
Ret = (ULONG_PTR)Class->hbrBackground;
|
||||
if (Ret != 0 && Ret < 0x4000)
|
||||
Ret = (ULONG_PTR)GetSysColorBrush((ULONG)Ret - 1);
|
||||
break;
|
||||
|
||||
case GCL_HMODULE:
|
||||
Ret = (ULONG_PTR)Class->hInstance;
|
||||
break;
|
||||
|
||||
case GCL_MENUNAME:
|
||||
Ret = (ULONG_PTR)Class->MenuName;
|
||||
break;
|
||||
|
||||
case GCL_STYLE:
|
||||
Ret = (ULONG_PTR)Class->Style;
|
||||
break;
|
||||
|
||||
case GCW_ATOM:
|
||||
Ret = (ULONG_PTR)Class->Atom;
|
||||
break;
|
||||
|
||||
case GCLP_HCURSOR:
|
||||
/* FIXME - get handle from pointer to CURSOR object */
|
||||
Ret = (ULONG_PTR)Class->hCursor;
|
||||
break;
|
||||
|
||||
case GCLP_HICON:
|
||||
/* FIXME - get handle from pointer to ICON object */
|
||||
Ret = (ULONG_PTR)Class->hIcon;
|
||||
break;
|
||||
|
||||
case GCLP_HICONSM:
|
||||
/* FIXME - get handle from pointer to ICON object */
|
||||
Ret = (ULONG_PTR)Class->hIconSm;
|
||||
break;
|
||||
|
||||
case GCLP_WNDPROC:
|
||||
/* We need to make a call to win32k as it may be required to
|
||||
create a callproc handle */
|
||||
Wnd = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
SetLastError(ERROR_INVALID_INDEX);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ret = *(PULONG_PTR)((ULONG_PTR)(Class + 1) + nIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (nIndex)
|
||||
else
|
||||
{
|
||||
case GCL_CBWNDEXTRA:
|
||||
Ret = (ULONG_PTR)Class->WndExtra;
|
||||
break;
|
||||
/* This is a race condition! Call win32k to make sure we're getting
|
||||
the correct result */
|
||||
Wnd = NULL; /* Make sure we call NtUserGetClassLong */
|
||||
|
||||
case GCL_CBCLSEXTRA:
|
||||
Ret = (ULONG_PTR)Class->ClsExtra;
|
||||
break;
|
||||
|
||||
case GCL_HBRBACKGROUND:
|
||||
Ret = (ULONG_PTR)Class->hbrBackground;
|
||||
if (Ret != 0 && Ret < 0x4000)
|
||||
Ret = (ULONG_PTR)GetSysColorBrush((ULONG)Ret - 1);
|
||||
break;
|
||||
|
||||
case GCL_HMODULE:
|
||||
Ret = (ULONG_PTR)Class->hInstance;
|
||||
break;
|
||||
|
||||
case GCL_MENUNAME:
|
||||
Ret = (ULONG_PTR)Class->MenuName;
|
||||
break;
|
||||
|
||||
case GCL_STYLE:
|
||||
Ret = (ULONG_PTR)Class->Style;
|
||||
break;
|
||||
|
||||
case GCW_ATOM:
|
||||
Ret = (ULONG_PTR)Class->Atom;
|
||||
break;
|
||||
|
||||
case GCLP_HCURSOR:
|
||||
/* FIXME - get handle from pointer to CURSOR object */
|
||||
Ret = (ULONG_PTR)Class->hCursor;
|
||||
break;
|
||||
|
||||
case GCLP_HICON:
|
||||
/* FIXME - get handle from pointer to ICON object */
|
||||
Ret = (ULONG_PTR)Class->hIcon;
|
||||
break;
|
||||
|
||||
case GCLP_HICONSM:
|
||||
/* FIXME - get handle from pointer to ICON object */
|
||||
Ret = (ULONG_PTR)Class->hIconSm;
|
||||
break;
|
||||
|
||||
case GCLP_WNDPROC:
|
||||
/* We need to make a call to win32k as it may be required to
|
||||
create a callproc handle */
|
||||
return NtUserGetClassLong(hWnd, nIndex, FALSE);
|
||||
|
||||
default:
|
||||
SetLastError(ERROR_INVALID_INDEX);
|
||||
WARN("Invalid class for hwnd 0x%p!\n", hWnd);
|
||||
}
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Wnd = NULL; /* Make sure we call NtUserGetClassLong */
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
return Ret;
|
||||
if (Wnd == NULL)
|
||||
Ret = NtUserGetClassLong(hWnd, nIndex, FALSE);
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1027,55 +1027,67 @@ GetWindowRect(HWND hWnd,
|
|||
int STDCALL
|
||||
GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount)
|
||||
{
|
||||
PWINDOW Wnd;
|
||||
PCWSTR Buffer;
|
||||
PWINDOW Wnd;
|
||||
PCWSTR Buffer;
|
||||
INT Length = 0;
|
||||
|
||||
if (lpString == NULL)
|
||||
return 0;
|
||||
if (lpString == NULL)
|
||||
return 0;
|
||||
|
||||
Wnd = ValidateHwnd(hWnd);
|
||||
if (!Wnd)
|
||||
return 0;
|
||||
Wnd = ValidateHwnd(hWnd);
|
||||
if (!Wnd)
|
||||
return 0;
|
||||
|
||||
if (Wnd->pi != g_kpi)
|
||||
{
|
||||
INT Length;
|
||||
_SEH_TRY
|
||||
{
|
||||
if (Wnd->pi != g_kpi)
|
||||
{
|
||||
if (nMaxCount > 0)
|
||||
{
|
||||
/* do not send WM_GETTEXT messages to other processes */
|
||||
Length = Wnd->WindowName.Length / sizeof(WCHAR);
|
||||
if (Length != 0)
|
||||
{
|
||||
Buffer = DesktopPtrToUser(Wnd->WindowName.Buffer);
|
||||
if (Buffer != NULL)
|
||||
{
|
||||
if (!WideCharToMultiByte(CP_ACP,
|
||||
0,
|
||||
Buffer,
|
||||
Length + 1,
|
||||
lpString,
|
||||
nMaxCount,
|
||||
NULL,
|
||||
NULL))
|
||||
{
|
||||
lpString[nMaxCount - 1] = '\0';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Length = 0;
|
||||
lpString[0] = '\0';
|
||||
}
|
||||
}
|
||||
else
|
||||
lpString[0] = '\0';
|
||||
}
|
||||
|
||||
if (nMaxCount <= 0)
|
||||
return 0;
|
||||
Wnd = NULL; /* Don't send a message */
|
||||
}
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
lpString[0] = '\0';
|
||||
Length = 0;
|
||||
Wnd = NULL; /* Don't send a message */
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
/* do not send WM_GETTEXT messages to other processes */
|
||||
Length = Wnd->WindowName.Length / sizeof(WCHAR);
|
||||
if (Length != 0)
|
||||
{
|
||||
Buffer = DesktopPtrToUser(Wnd->WindowName.Buffer);
|
||||
if (Buffer != NULL)
|
||||
{
|
||||
if (!WideCharToMultiByte(CP_ACP,
|
||||
0,
|
||||
Buffer,
|
||||
Length + 1,
|
||||
lpString,
|
||||
nMaxCount,
|
||||
NULL,
|
||||
NULL))
|
||||
{
|
||||
lpString[nMaxCount - 1] = '\0';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Length = 0;
|
||||
lpString[0] = '\0';
|
||||
}
|
||||
}
|
||||
else
|
||||
lpString[0] = '\0';
|
||||
if (Wnd != NULL)
|
||||
Length = SendMessageA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
|
||||
|
||||
return (LRESULT)Length;
|
||||
}
|
||||
|
||||
return SendMessageA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
|
||||
return Length;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1105,47 +1117,59 @@ GetWindowTextLengthW(HWND hWnd)
|
|||
int STDCALL
|
||||
GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
|
||||
{
|
||||
PWINDOW Wnd;
|
||||
PCWSTR Buffer;
|
||||
PWINDOW Wnd;
|
||||
PCWSTR Buffer;
|
||||
INT Length = 0;
|
||||
|
||||
if (lpString == NULL)
|
||||
return 0;
|
||||
if (lpString == NULL)
|
||||
return 0;
|
||||
|
||||
Wnd = ValidateHwnd(hWnd);
|
||||
if (!Wnd)
|
||||
return 0;
|
||||
Wnd = ValidateHwnd(hWnd);
|
||||
if (!Wnd)
|
||||
return 0;
|
||||
|
||||
if (Wnd->pi != g_kpi)
|
||||
{
|
||||
INT Length;
|
||||
_SEH_TRY
|
||||
{
|
||||
if (Wnd->pi != g_kpi)
|
||||
{
|
||||
if (nMaxCount > 0)
|
||||
{
|
||||
/* do not send WM_GETTEXT messages to other processes */
|
||||
Length = Wnd->WindowName.Length / sizeof(WCHAR);
|
||||
if (Length != 0)
|
||||
{
|
||||
Buffer = DesktopPtrToUser(Wnd->WindowName.Buffer);
|
||||
if (Buffer != NULL)
|
||||
{
|
||||
RtlCopyMemory(lpString,
|
||||
Buffer,
|
||||
(Length + 1) * sizeof(WCHAR));
|
||||
}
|
||||
else
|
||||
{
|
||||
Length = 0;
|
||||
lpString[0] = '\0';
|
||||
}
|
||||
}
|
||||
else
|
||||
lpString[0] = '\0';
|
||||
}
|
||||
|
||||
if (nMaxCount <= 0)
|
||||
return 0;
|
||||
Wnd = NULL; /* Don't send a message */
|
||||
}
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
lpString[0] = '\0';
|
||||
Length = 0;
|
||||
Wnd = NULL; /* Don't send a message */
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
/* do not send WM_GETTEXT messages to other processes */
|
||||
Length = Wnd->WindowName.Length / sizeof(WCHAR);
|
||||
if (Length != 0)
|
||||
{
|
||||
Buffer = DesktopPtrToUser(Wnd->WindowName.Buffer);
|
||||
if (Buffer != NULL)
|
||||
{
|
||||
RtlCopyMemory(lpString,
|
||||
Buffer,
|
||||
(Length + 1) * sizeof(WCHAR));
|
||||
}
|
||||
else
|
||||
{
|
||||
Length = 0;
|
||||
lpString[0] = L'\0';
|
||||
}
|
||||
}
|
||||
else
|
||||
lpString[0] = L'\0';
|
||||
if (Wnd != NULL)
|
||||
Length = SendMessageW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
|
||||
|
||||
return (LRESULT)Length;
|
||||
}
|
||||
|
||||
return SendMessageW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
|
||||
return Length;
|
||||
}
|
||||
|
||||
DWORD STDCALL
|
||||
|
@ -1187,9 +1211,7 @@ IsIconic(HWND hWnd)
|
|||
PWINDOW Wnd = ValidateHwnd(hWnd);
|
||||
|
||||
if (Wnd != NULL)
|
||||
{
|
||||
return (Wnd->Style & WS_MINIMIZE) != 0;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue