[ros-diffs] [weiden] 30513: Protect GetClassLong() and GetWindowText() with SEH as they're following pointers in the desktop heap

weiden at svn.reactos.org weiden at svn.reactos.org
Fri Nov 16 22:56:24 CET 2007


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.rbuild?rev=30513&r1=30512&r2=30513&view=diff
==============================================================================
--- 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/class.c?rev=30513&r1=30512&r2=30513&view=diff
==============================================================================
--- 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/window.c?rev=30513&r1=30512&r2=30513&view=diff
==============================================================================
--- 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;
 }




More information about the Ros-diffs mailing list