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.rbu... ============================================================================== --- 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/cl... ============================================================================== --- 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/wi... ============================================================================== --- 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; }