Author: weiden
Date: Sat Nov 17 00:56:23 2007
New Revision: 30513
URL:
http://svn.reactos.org/svn/reactos?rev=30513&view=rev
Log:
Protect GetClassLong() and GetWindowText() with SEH as they're following pointers in
the desktop heap
Modified:
trunk/reactos/dll/win32/user32/user32.rbuild
trunk/reactos/dll/win32/user32/windows/class.c
trunk/reactos/dll/win32/user32/windows/window.c
Modified: trunk/reactos/dll/win32/user32/user32.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/user32.rb…
==============================================================================
--- trunk/reactos/dll/win32/user32/user32.rbuild (original)
+++ trunk/reactos/dll/win32/user32/user32.rbuild Sat Nov 17 00:56:23 2007
@@ -14,6 +14,7 @@
<library>advapi32</library>
<library>imm32</library>
<library>win32ksys</library>
+ <library>pseh</library>
<directory name="include">
<pch>user32.h</pch>
Modified: trunk/reactos/dll/win32/user32/windows/class.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/c…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/class.c (original)
+++ trunk/reactos/dll/win32/user32/windows/class.c Sat Nov 17 00:56:23 2007
@@ -199,80 +199,101 @@
if (!Wnd)
return 0;
- Class = DesktopPtrToUser(Wnd->Class);
- ASSERT(Class != NULL);
-
- if (nIndex >= 0)
- {
- if (nIndex + sizeof(ULONG_PTR) < nIndex ||
- nIndex + sizeof(ULONG_PTR) > Class->ClsExtra)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- 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 */
- return NtUserGetClassLong(hWnd, nIndex, TRUE);
-
- default:
- SetLastError(ERROR_INVALID_INDEX);
- }
- }
-
- return Ret;
+ _SEH_TRY
+ {
+ Class = DesktopPtrToUser(Wnd->Class);
+ if (Class != NULL)
+ {
+ 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;
+ }
+ }
+ }
+ else
+ {
+ /* This is a race condition! Call win32k to make sure we're getting
+ the correct result */
+ Wnd = NULL; /* Make sure we call NtUserGetClassLong */
+
+ WARN("Invalid class for hwnd 0x%p!\n", hWnd);
+ }
+ }
+ _SEH_HANDLE
+ {
+ Wnd = NULL; /* Make sure we call NtUserGetClassLong */
+ }
+ _SEH_END;
+
+ if (Wnd == NULL)
+ Ret = NtUserGetClassLong(hWnd, nIndex, TRUE);
+
+ return Ret;
}
/*
@@ -291,80 +312,101 @@
if (!Wnd)
return 0;
- Class = DesktopPtrToUser(Wnd->Class);
- ASSERT(Class != NULL);
-
- if (nIndex >= 0)
- {
- if (nIndex + sizeof(ULONG_PTR) < nIndex ||
- nIndex + sizeof(ULONG_PTR) > Class->ClsExtra)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- 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 */
- return NtUserGetClassLong(hWnd, nIndex, FALSE);
-
- default:
- SetLastError(ERROR_INVALID_INDEX);
- }
- }
-
- return Ret;
+ _SEH_TRY
+ {
+ Class = DesktopPtrToUser(Wnd->Class);
+ if (Class != NULL)
+ {
+ 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;
+ }
+ }
+ }
+ else
+ {
+ /* This is a race condition! Call win32k to make sure we're getting
+ the correct result */
+ Wnd = NULL; /* Make sure we call NtUserGetClassLong */
+
+ WARN("Invalid class for hwnd 0x%p!\n", hWnd);
+ }
+ }
+ _SEH_HANDLE
+ {
+ Wnd = NULL; /* Make sure we call NtUserGetClassLong */
+ }
+ _SEH_END;
+
+ if (Wnd == NULL)
+ Ret = NtUserGetClassLong(hWnd, nIndex, FALSE);
+
+ return Ret;
}
Modified: trunk/reactos/dll/win32/user32/windows/window.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/w…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/window.c (original)
+++ trunk/reactos/dll/win32/user32/windows/window.c Sat Nov 17 00:56:23 2007
@@ -1027,55 +1027,67 @@
int STDCALL
GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount)
{
- PWINDOW Wnd;
- PCWSTR Buffer;
-
- if (lpString == NULL)
- return 0;
-
- Wnd = ValidateHwnd(hWnd);
- if (!Wnd)
- return 0;
-
- if (Wnd->pi != g_kpi)
- {
- INT Length;
-
- if (nMaxCount <= 0)
- return 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';
-
- return (LRESULT)Length;
- }
-
- return SendMessageA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
+ PWINDOW Wnd;
+ PCWSTR Buffer;
+ INT Length = 0;
+
+ if (lpString == NULL)
+ return 0;
+
+ Wnd = ValidateHwnd(hWnd);
+ if (!Wnd)
+ return 0;
+
+ _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';
+ }
+
+ Wnd = NULL; /* Don't send a message */
+ }
+ }
+ _SEH_HANDLE
+ {
+ lpString[0] = '\0';
+ Length = 0;
+ Wnd = NULL; /* Don't send a message */
+ }
+ _SEH_END;
+
+ if (Wnd != NULL)
+ Length = SendMessageA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
+
+ return Length;
}
@@ -1105,47 +1117,59 @@
int STDCALL
GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
{
- PWINDOW Wnd;
- PCWSTR Buffer;
-
- if (lpString == NULL)
- return 0;
-
- Wnd = ValidateHwnd(hWnd);
- if (!Wnd)
- return 0;
-
- if (Wnd->pi != g_kpi)
- {
- INT Length;
-
- if (nMaxCount <= 0)
- return 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] = L'\0';
- }
- }
- else
- lpString[0] = L'\0';
-
- return (LRESULT)Length;
- }
-
- return SendMessageW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
+ PWINDOW Wnd;
+ PCWSTR Buffer;
+ INT Length = 0;
+
+ if (lpString == NULL)
+ return 0;
+
+ Wnd = ValidateHwnd(hWnd);
+ if (!Wnd)
+ return 0;
+
+ _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';
+ }
+
+ Wnd = NULL; /* Don't send a message */
+ }
+ }
+ _SEH_HANDLE
+ {
+ lpString[0] = '\0';
+ Length = 0;
+ Wnd = NULL; /* Don't send a message */
+ }
+ _SEH_END;
+
+ if (Wnd != NULL)
+ Length = SendMessageW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
+
+ return Length;
}
DWORD STDCALL
@@ -1187,9 +1211,7 @@
PWINDOW Wnd = ValidateHwnd(hWnd);
if (Wnd != NULL)
- {
return (Wnd->Style & WS_MINIMIZE) != 0;
- }
return FALSE;
}