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:
Thomas Bluemel 2007-11-16 21:56:23 +00:00
parent 2348eeb813
commit 7033c976bb
3 changed files with 277 additions and 212 deletions

View file

@ -14,6 +14,7 @@
<library>advapi32</library>
<library>imm32</library>
<library>win32ksys</library>
<library>pseh</library>
<directory name="include">
<pch>user32.h</pch>

View file

@ -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;
}

View file

@ -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;
}