[ros-diffs] [weiden] 30490: Optimize GetWindowText(Length)A/W and WM_GETTEXT(LENGTH)

weiden at svn.reactos.org weiden at svn.reactos.org
Fri Nov 16 03:37:15 CET 2007


Author: weiden
Date: Fri Nov 16 05:37:14 2007
New Revision: 30490

URL: http://svn.reactos.org/svn/reactos?rev=30490&view=rev
Log:
Optimize GetWindowText(Length)A/W and WM_GETTEXT(LENGTH)

Modified:
    trunk/reactos/dll/win32/user32/windows/defwnd.c
    trunk/reactos/dll/win32/user32/windows/window.c
    trunk/reactos/include/reactos/win32k/ntuser.h
    trunk/reactos/subsystems/win32/win32k/include/window.h
    trunk/reactos/subsystems/win32/win32k/ntuser/class.c
    trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c
    trunk/reactos/subsystems/win32/win32k/ntuser/focus.c
    trunk/reactos/subsystems/win32/win32k/ntuser/message.c
    trunk/reactos/subsystems/win32/win32k/ntuser/painting.c
    trunk/reactos/subsystems/win32/win32k/ntuser/windc.c
    trunk/reactos/subsystems/win32/win32k/ntuser/window.c

Modified: trunk/reactos/dll/win32/user32/windows/defwnd.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/defwnd.c?rev=30490&r1=30489&r2=30490&view=diff
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/defwnd.c (original)
+++ trunk/reactos/dll/win32/user32/windows/defwnd.c Fri Nov 16 05:37:14 2007
@@ -1602,6 +1602,7 @@
 	       LPARAM lParam)
 {
     LRESULT Result = 0;
+    PWINDOW Wnd;
 
     SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam);
     switch (Msg)
@@ -1630,33 +1631,57 @@
 
         case WM_GETTEXTLENGTH:
         {
-            Result = (LRESULT)NtUserInternalGetWindowText(hWnd, NULL, 0);
+            PWSTR buf;
+            ULONG len;
+
+            Wnd = ValidateHwnd(hWnd);
+            if (Wnd != NULL && Wnd->WindowName.Length != 0)
+            {
+                buf = DesktopPtrToUser(Wnd->WindowName.Buffer);
+                if (buf != NULL &&
+                    NT_SUCCESS(RtlUnicodeToMultiByteSize(&len,
+                                                         buf,
+                                                         Wnd->WindowName.Length)))
+                {
+                    Result = (LRESULT)len;
+                }
+            }
             break;
         }
 
         case WM_GETTEXT:
         {
-            LPWSTR Buffer;
-            LPSTR AnsiBuffer = (LPSTR)lParam;
-            INT Length;
-
-            Buffer = HeapAlloc(GetProcessHeap(), 0, wParam * sizeof(WCHAR));
-            if (!Buffer)
-            {
-                Result = 0;
-                break;
-            }
-            Length = NtUserInternalGetWindowText(hWnd, Buffer, wParam);
-            if (Length > 0 && wParam > 0 &&
-                !WideCharToMultiByte(CP_ACP, 0, Buffer, -1,
-                AnsiBuffer, wParam, NULL, NULL))
-            {
-                AnsiBuffer[0] = '\0';
-            }
-
-            HeapFree(GetProcessHeap(), 0, Buffer);
-
-            Result = (LRESULT)Length;
+            PWSTR buf = NULL;
+            PSTR outbuf = (PSTR)lParam;
+            UINT copy;
+
+            Wnd = ValidateHwnd(hWnd);
+            if (Wnd != NULL && wParam != 0)
+            {
+                if (Wnd->WindowName.Buffer != NULL)
+                    buf = DesktopPtrToUser(Wnd->WindowName.Buffer);
+                else
+                    outbuf[0] = L'\0';
+
+                if (buf != NULL)
+                {
+                    if (Wnd->WindowName.Length != 0)
+                    {
+                        copy = min(Wnd->WindowName.Length / sizeof(WCHAR), wParam - 1);
+                        Result = WideCharToMultiByte(CP_ACP,
+                                                     0,
+                                                     buf,
+                                                     copy,
+                                                     outbuf,
+                                                     wParam,
+                                                     NULL,
+                                                     NULL);
+                        outbuf[Result] = '\0';
+                    }
+                    else
+                        outbuf[0] = '\0';
+                }
+            }
             break;
         }
 
@@ -1711,6 +1736,7 @@
 	       LPARAM lParam)
 {
     LRESULT Result = 0;
+    PWINDOW Wnd;
 
     SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam);
     switch (Msg)
@@ -1732,13 +1758,51 @@
 
         case WM_GETTEXTLENGTH:
         {
-            Result = (LRESULT)NtUserInternalGetWindowText(hWnd, NULL, 0);
+            PWSTR buf;
+            ULONG len;
+
+            Wnd = ValidateHwnd(hWnd);
+            if (Wnd != NULL && Wnd->WindowName.Length != 0)
+            {
+                buf = DesktopPtrToUser(Wnd->WindowName.Buffer);
+                if (buf != NULL &&
+                    NT_SUCCESS(RtlUnicodeToMultiByteSize(&len,
+                                                         buf,
+                                                         Wnd->WindowName.Length)))
+                {
+                    Result = (LRESULT)len;
+                }
+            }
             break;
         }
 
         case WM_GETTEXT:
         {
-            Result = (LRESULT)NtUserInternalGetWindowText(hWnd, (PWSTR)lParam, wParam);
+            PWSTR buf = NULL;
+            PWSTR outbuf = (PWSTR)lParam;
+
+            Wnd = ValidateHwnd(hWnd);
+            if (Wnd != NULL && wParam != 0)
+            {
+                if (Wnd->WindowName.Buffer != NULL)
+                    buf = DesktopPtrToUser(Wnd->WindowName.Buffer);
+                else
+                    outbuf[0] = L'\0';
+
+                if (buf != NULL)
+                {
+                    if (Wnd->WindowName.Length != 0)
+                    {
+                        Result = min(Wnd->WindowName.Length / sizeof(WCHAR), wParam - 1);
+                        RtlCopyMemory(outbuf,
+                                      buf,
+                                      Result * sizeof(WCHAR));
+                        outbuf[Result] = L'\0';
+                    }
+                    else
+                        outbuf[0] = L'\0';
+                }
+            }
             break;
         }
 

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=30490&r1=30489&r2=30490&view=diff
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/window.c (original)
+++ trunk/reactos/dll/win32/user32/windows/window.c Fri Nov 16 05:37:14 2007
@@ -1035,31 +1035,50 @@
 int STDCALL
 GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount)
 {
-   DWORD ProcessId;
+   PWINDOW Wnd;
+   PCWSTR Buffer;
 
    if (lpString == NULL)
       return 0;
 
-   if (!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
-      return 0;
-
-   if (ProcessId != GetCurrentProcessId())
+   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 */
-      LPWSTR Buffer;
-      INT Length;
-
-      Buffer = HeapAlloc(GetProcessHeap(), 0, nMaxCount * sizeof(WCHAR));
-      if (!Buffer)
-         return FALSE;
-      Length = NtUserInternalGetWindowText(hWnd, Buffer, nMaxCount);
-      if (Length > 0 && nMaxCount > 0 &&
-          !WideCharToMultiByte(CP_ACP, 0, Buffer, -1,
-          lpString, nMaxCount, NULL, NULL))
+      Length = Wnd->WindowName.Length / sizeof(WCHAR);
+      if (Length != 0)
       {
-         lpString[0] = '\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';
+          }
       }
-      HeapFree(GetProcessHeap(), 0, Buffer);
+      else
+          lpString[0] = '\0';
 
       return (LRESULT)Length;
    }
@@ -1074,19 +1093,7 @@
 int STDCALL
 GetWindowTextLengthA(HWND hWnd)
 {
-  DWORD ProcessId;
-  if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
-  {
-    return 0;
-  }
-
-  if(ProcessId == GetCurrentProcessId())
-  {
     return(SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0));
-  }
-
-  /* do not send WM_GETTEXT messages to other processes */
-  return (LRESULT)NtUserInternalGetWindowText(hWnd, NULL, 0);
 }
 
 
@@ -1096,19 +1103,7 @@
 int STDCALL
 GetWindowTextLengthW(HWND hWnd)
 {
-  DWORD ProcessId;
-  if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
-  {
-    return 0;
-  }
-
-  if(ProcessId == GetCurrentProcessId())
-  {
     return(SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, 0));
-  }
-
-  /* do not send WM_GETTEXT messages to other processes */
-  return (LRESULT)NtUserInternalGetWindowText(hWnd, NULL, 0);
 }
 
 
@@ -1118,18 +1113,47 @@
 int STDCALL
 GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
 {
-   DWORD ProcessId;
+   PWINDOW Wnd;
+   PCWSTR Buffer;
 
    if (lpString == NULL)
       return 0;
 
-   if (!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
-      return 0;
-
-   if (ProcessId == GetCurrentProcessId())
-      return SendMessageW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
-
-   return NtUserInternalGetWindowText(hWnd, lpString, nMaxCount);
+   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);
 }
 
 DWORD STDCALL
@@ -1643,7 +1667,10 @@
 STDCALL
 InternalGetWindowText(HWND hWnd, LPWSTR lpString, int nMaxCount)
 {
-  return NtUserInternalGetWindowText(hWnd, lpString, nMaxCount);
+    INT Ret = NtUserInternalGetWindowText(hWnd, lpString, nMaxCount);
+    if (Ret == 0)
+        *lpString = L'\0';
+    return Ret;
 }
 
 /*

Modified: trunk/reactos/include/reactos/win32k/ntuser.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntuser.h?rev=30490&r1=30489&r2=30490&view=diff
==============================================================================
--- trunk/reactos/include/reactos/win32k/ntuser.h (original)
+++ trunk/reactos/include/reactos/win32k/ntuser.h Fri Nov 16 05:37:14 2007
@@ -77,6 +77,10 @@
     /* Window menu handle or window id */
     UINT IDMenu;
     LONG UserData;
+    /* Pointer to the window class. */
+    PWINDOWCLASS Class;
+    /* Window name. */
+    UNICODE_STRING WindowName;
 } WINDOW, *PWINDOW;
 
 typedef struct _W32PROCESSINFO

Modified: trunk/reactos/subsystems/win32/win32k/include/window.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/window.h?rev=30490&r1=30489&r2=30490&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/window.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/window.h Fri Nov 16 05:37:14 2007
@@ -45,10 +45,6 @@
   };
   /* Indicates whether the window is derived from a system class */
   BOOL IsSystem;
-  /* Pointer to the window class. */
-  PWINDOWCLASS Class;
-  /* Window name. */
-  UNICODE_STRING WindowName;
   /* Context help id */
   DWORD ContextHelpId;
   /* system menu handle. */

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/class.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/class.c?rev=30490&r1=30489&r2=30490&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/class.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/class.c Fri Nov 16 05:37:14 2007
@@ -1927,11 +1927,11 @@
     Window = UserGetWindowObject(hWnd);
     if (Window != NULL)
     {
-        Ret = UserGetClassLongPtr(Window->Class,
+        Ret = UserGetClassLongPtr(Window->Wnd->Class,
                                   Offset,
                                   Ansi);
 
-        if (Ret != 0 && Offset == GCLP_MENUNAME && Window->Class->MenuNameIsString)
+        if (Ret != 0 && Offset == GCLP_MENUNAME && Window->Wnd->Class->MenuNameIsString)
         {
             Ret = (ULONG_PTR)UserHeapAddressToUser((PVOID)Ret);
         }
@@ -2005,7 +2005,7 @@
                 dwNewLong = (ULONG_PTR)&Value;
             }
 
-            Ret = UserSetClassLongPtr(Window->Class,
+            Ret = UserSetClassLongPtr(Window->Wnd->Class,
                                       Offset,
                                       dwNewLong,
                                       Ansi);
@@ -2218,7 +2218,7 @@
             CapturedClassName = *ClassName;
 
             /* get the class name */
-            Ret = UserGetClassName(Window->Class,
+            Ret = UserGetClassName(Window->Wnd->Class,
                                    &CapturedClassName,
                                    Ansi);
 

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c?rev=30490&r1=30489&r2=30490&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c Fri Nov 16 05:37:14 2007
@@ -1357,7 +1357,7 @@
       RETURN(FALSE);
    }
 
-   DesktopBrush = (HBRUSH)UserGetClassLongPtr(WndDesktop->Class, GCL_HBRBACKGROUND, FALSE);
+   DesktopBrush = (HBRUSH)UserGetClassLongPtr(WndDesktop->Wnd->Class, GCL_HBRBACKGROUND, FALSE);
 
 
    /*

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/focus.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/focus.c?rev=30490&r1=30489&r2=30490&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/focus.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/focus.c Fri Nov 16 05:37:14 2007
@@ -152,7 +152,6 @@
    ASSERT_REFS_CO(Window);
 
    DPRINT("IntSetForegroundAndFocusWindow(%x, %x, %s)\n", hWnd, hWndFocus, MouseActivate ? "TRUE" : "FALSE");
-   DPRINT("(%wZ)\n", &Window->WindowName);
 
    Wnd = Window->Wnd;
 
@@ -426,8 +425,6 @@
          RETURN( 0);
       }
 
-      DPRINT("(%wZ)\n", &Window->WindowName);
-
       ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetCurrentThreadWin32Thread()->MessageQueue;
 
       if (Window->MessageQueue != ThreadQueue)

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/message.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/message.c?rev=30490&r1=30489&r2=30490&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/message.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/message.c Fri Nov 16 05:37:14 2007
@@ -603,7 +603,7 @@
    {
       /* generate double click messages, if necessary */
       if ((((*HitTest) != HTCLIENT) ||
-            (Window->Class->Style & CS_DBLCLKS)) &&
+            (Window->Wnd->Class->Style & CS_DBLCLKS)) &&
             MsqIsDblClk(Msg, Remove))
       {
          Msg->message += WM_LBUTTONDBLCLK - WM_LBUTTONDOWN;

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/painting.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/painting.c?rev=30490&r1=30489&r2=30490&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/painting.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/painting.c Fri Nov 16 05:37:14 2007
@@ -1528,12 +1528,12 @@
 
    /* Get the icon to draw. We don't care about WM_GETICON here. */
 
-   hIcon = pWnd->Class->hIconSm;
+   hIcon = pWnd->Wnd->Class->hIconSm;
 
    if(!hIcon)
    {
       DPRINT("Wnd class has no small icon.\n");
-      hIcon = pWnd->Class->hIcon;
+      hIcon = pWnd->Wnd->Class->hIcon;
    }
 
    if(!hIcon)
@@ -1864,7 +1864,7 @@
       if (str)
          UserDrawCaptionText(hMemDc, str, &r, uFlags);
 	  else if (pWnd != NULL)
-	     UserDrawCaptionText(hMemDc, &pWnd->WindowName, &r, uFlags);
+	     UserDrawCaptionText(hMemDc, &pWnd->Wnd->WindowName, &r, uFlags);
    }
 
    if(!NtGdiBitBlt(hDc, lpRc->left, lpRc->top,

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/windc.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/windc.c?rev=30490&r1=30489&r2=30490&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/windc.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/windc.c Fri Nov 16 05:37:14 2007
@@ -401,7 +401,7 @@
 
       if (!(Flags & DCX_WINDOW))
       {
-         if (Window->Class->Style & CS_PARENTDC)
+         if (Wnd->Class->Style & CS_PARENTDC)
          {
             Flags |= DCX_PARENTCLIP;
          }
@@ -739,7 +739,7 @@
       {
          if (pDCE == Window->Dce) /* owned or Class DCE*/
          {
-            if (Window->Class->Style & CS_OWNDC) /* owned DCE*/
+            if (Window->Wnd->Class->Style & CS_OWNDC) /* owned DCE*/
             {
                pDCE = DceFreeDCE(pDCE, FALSE);
                Window->Dce = NULL;

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/window.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/window.c?rev=30490&r1=30489&r2=30490&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/window.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/window.c Fri Nov 16 05:37:14 2007
@@ -296,6 +296,7 @@
 UserFreeWindowInfo(PW32THREADINFO ti, PWINDOW_OBJECT WindowObject)
 {
     PW32CLIENTINFO ClientInfo = GetWin32ClientInfo();
+    PWINDOW Wnd = WindowObject->Wnd;
 
     if (ClientInfo->pvWND == DesktopHeapAddressToUser(WindowObject->Wnd))
     {
@@ -303,7 +304,16 @@
         ClientInfo->pvWND = NULL;
     }
 
-    DesktopHeapFree(ti->Desktop, WindowObject->Wnd);
+   if (Wnd->WindowName.Buffer != NULL)
+   {
+       Wnd->WindowName.Length = 0;
+       Wnd->WindowName.MaximumLength = 0;
+       DesktopHeapFree(Wnd->ti->Desktop,
+                       Wnd->WindowName.Buffer);
+       Wnd->WindowName.Buffer = NULL;
+   }
+
+    DesktopHeapFree(ti->Desktop, Wnd);
     WindowObject->Wnd = NULL;
 }
 
@@ -453,17 +463,15 @@
    IntDestroyScrollBars(Window);
 
    /* dereference the class */
-   IntDereferenceClass(Window->Class,
+   IntDereferenceClass(Wnd->Class,
                        Window->ti->Desktop,
                        Window->ti->kpi);
-   Window->Class = NULL;
+   Wnd->Class = NULL;
 
    if(Window->WindowRegion)
    {
       NtGdiDeleteObject(Window->WindowRegion);
    }
-
-   RtlFreeUnicodeString(&Window->WindowName);
 
    ASSERT(Window->Wnd != NULL);
    UserFreeWindowInfo(Window->ti, Window);
@@ -507,6 +515,8 @@
 IntGetWindowProc(IN PWINDOW_OBJECT Window,
                  IN BOOL Ansi)
 {
+    PWINDOW Wnd = Window->Wnd;
+
     ASSERT(UserIsEnteredExclusive() == TRUE);
 
     if (Window->IsSystem)
@@ -529,22 +539,22 @@
             {
                 PCALLPROC NewCallProc, CallProc;
 
-                NewCallProc = UserFindCallProc(Window->Class,
+                NewCallProc = UserFindCallProc(Wnd->Class,
                                                Window->WndProc,
                                                Window->Unicode);
                 if (NewCallProc == NULL)
                 {
-                    NewCallProc = CreateCallProc(Window->ti->Desktop,
+                    NewCallProc = CreateCallProc(Wnd->ti->Desktop,
                                                  Window->WndProc,
                                                  Window->Unicode,
-                                                 Window->ti->kpi);
+                                                 Wnd->ti->kpi);
                     if (NewCallProc == NULL)
                     {
                         SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
                         return NULL;
                     }
 
-                    UserAddCallProcToClass(Window->Class,
+                    UserAddCallProcToClass(Wnd->Class,
                                            NewCallProc);
                 }
 
@@ -569,7 +579,7 @@
    pwi->dwExStyle = Wnd->ExStyle;
    pwi->dwWindowStatus = (UserGetForegroundWindow() == Window->hSelf); /* WS_ACTIVECAPTION */
    IntGetWindowBorderMeasures(Window, &pwi->cxWindowBorders, &pwi->cyWindowBorders);
-   pwi->atomWindowType = (Window->Class ? Window->Class->Atom : 0);
+   pwi->atomWindowType = (Wnd->Class ? Wnd->Class->Atom : 0);
    pwi->wCreatorVersion = 0x400; /* FIXME - return a real version number */
    return TRUE;
 }
@@ -1596,7 +1606,7 @@
     * Fill out the structure describing it.
     */
    Window->ti = ti;
-   Window->Class = Class;
+   Wnd->Class = Class;
    Class = NULL;
 
    Window->SystemMenu = (HMENU)0;
@@ -1606,7 +1616,7 @@
    Window->hSelf = hWnd;
 
    if (!hMenu)
-       hMenu = Window->Class->hMenu;
+       hMenu = Wnd->Class->hMenu;
 
    if (0 != (dwStyle & WS_CHILD))
    {
@@ -1634,18 +1644,18 @@
 
    Wnd->UserData = 0;
 
-   Window->IsSystem = Window->Class->System;
-   if (Window->Class->System)
+   Window->IsSystem = Wnd->Class->System;
+   if (Wnd->Class->System)
    {
        /* NOTE: Always create a unicode window for system classes! */
        Window->Unicode = TRUE;
-       Window->WndProc = Window->Class->WndProc;
-       Window->WndProcExtra = Window->Class->WndProcExtra;
+       Window->WndProc = Wnd->Class->WndProc;
+       Window->WndProcExtra = Wnd->Class->WndProcExtra;
    }
    else
    {
-       Window->Unicode = Window->Class->Unicode;
-       Window->WndProc = Window->Class->WndProc;
+       Window->Unicode = Wnd->Class->Unicode;
+       Window->WndProc = Wnd->Class->WndProc;
        Window->CallProc = NULL;
    }
 
@@ -1654,28 +1664,35 @@
    Window->LastChild = NULL;
    Window->PrevSibling = NULL;
    Window->NextSibling = NULL;
-   Wnd->ExtraDataSize = Window->Class->WndExtra;
+   Wnd->ExtraDataSize = Wnd->Class->WndExtra;
 
    InitializeListHead(&Window->PropListHead);
    InitializeListHead(&Window->WndObjListHead);
 
-   if (NULL != WindowName->Buffer)
-   {
-      Window->WindowName.MaximumLength = WindowName->MaximumLength;
-      Window->WindowName.Length = WindowName->Length;
-      Window->WindowName.Buffer = ExAllocatePoolWithTag(PagedPool, WindowName->MaximumLength,
-                                  TAG_STRING);
-      if (NULL == Window->WindowName.Buffer)
-      {
-         DPRINT1("Failed to allocate mem for window name\n");
-         SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
-         RETURN( NULL);
-      }
-      RtlCopyMemory(Window->WindowName.Buffer, WindowName->Buffer, WindowName->MaximumLength);
-   }
-   else
-   {
-      RtlInitUnicodeString(&Window->WindowName, NULL);
+   if (NULL != WindowName->Buffer && WindowName->Length > 0)
+   {
+      Wnd->WindowName.Buffer = DesktopHeapAlloc(Wnd->ti->Desktop,
+                                                WindowName->Length + sizeof(UNICODE_NULL));
+      if (Wnd->WindowName.Buffer == NULL)
+      {
+          SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
+          RETURN( (HWND)0);
+      }
+
+      Wnd->WindowName.Buffer[WindowName->Length / sizeof(WCHAR)] = L'\0';
+      _SEH_TRY
+      {
+          RtlCopyMemory(Wnd->WindowName.Buffer,
+                        WindowName->Buffer,
+                        WindowName->Length);
+          Wnd->WindowName.Length = WindowName->Length;
+      }
+      _SEH_HANDLE
+      {
+          WindowName->Length = 0;
+          Wnd->WindowName.Buffer[0] = L'\0';
+      }
+      _SEH_END;
    }
 
    /*
@@ -2459,8 +2476,8 @@
          /* Do not send WM_GETTEXT messages in the kernel mode version!
             The user mode version however calls GetWindowText() which will
             send WM_GETTEXT messages to windows belonging to its processes */
-         if((!CheckWindowName || !RtlCompareUnicodeString(WindowName, &(Child->WindowName), TRUE)) &&
-               (!ClassAtom || Child->Class->Atom == ClassAtom))
+         if((!CheckWindowName || !RtlCompareUnicodeString(WindowName, &(Child->Wnd->WindowName), TRUE)) &&
+               (!ClassAtom || Child->Wnd->Class->Atom == ClassAtom))
          {
             Ret = Child->hSelf;
             break;
@@ -2633,9 +2650,9 @@
                    The user mode version however calls GetWindowText() which will
                    send WM_GETTEXT messages to windows belonging to its processes */
                 WindowMatches = !CheckWindowName || !RtlCompareUnicodeString(
-                                   &WindowName, &TopLevelWindow->WindowName, TRUE);
+                                   &WindowName, &TopLevelWindow->Wnd->WindowName, TRUE);
                 ClassMatches = (ClassAtom == (RTL_ATOM)0) ||
-                               ClassAtom == TopLevelWindow->Class->Atom;
+                               ClassAtom == TopLevelWindow->Wnd->Class->Atom;
 
                 if (WindowMatches && ClassMatches)
                 {
@@ -3574,6 +3591,7 @@
 {
     WNDPROC Ret;
     PCALLPROC CallProc;
+    PWINDOW Wnd = Window->Wnd;
 
     /* resolve any callproc handle if possible */
     if (IsCallProcHandle(NewWndProc))
@@ -3601,7 +3619,7 @@
         }
         else
         {
-            CallProc = UserFindCallProc(Window->Class,
+            CallProc = UserFindCallProc(Wnd->Class,
                                         Window->WndProc,
                                         Window->Unicode);
             if (CallProc == NULL)
@@ -3609,14 +3627,14 @@
                 CallProc = CreateCallProc(NULL,
                                           Window->WndProc,
                                           Window->Unicode,
-                                          Window->ti->kpi);
+                                          Wnd->ti->kpi);
                 if (CallProc == NULL)
                 {
                     SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
                     return NULL;
                 }
 
-                UserAddCallProcToClass(Window->Class,
+                UserAddCallProcToClass(Wnd->Class,
                                        CallProc);
             }
 
@@ -3626,17 +3644,17 @@
         }
     }
 
-    if (Window->Class->System)
+    if (Wnd->Class->System)
     {
         /* check if the new procedure matches with the one in the
            window class. If so, we need to restore both procedures! */
-        Window->IsSystem = (NewWndProc == Window->Class->WndProc ||
-                            NewWndProc == Window->Class->WndProcExtra);
+        Window->IsSystem = (NewWndProc == Wnd->Class->WndProc ||
+                            NewWndProc == Wnd->Class->WndProcExtra);
 
         if (Window->IsSystem)
         {
-            Window->WndProc = Window->Class->WndProc;
-            Window->WndProcExtra = Window->Class->WndProcExtra;
+            Window->WndProc = Wnd->Class->WndProc;
+            Window->WndProcExtra = Wnd->Class->WndProcExtra;
             Window->Unicode = !Ansi;
             return Ret;
         }
@@ -4622,36 +4640,97 @@
 NtUserDefSetText(HWND hWnd, PUNICODE_STRING WindowText)
 {
    PWINDOW_OBJECT Window;
+   PWINDOW Wnd;
    UNICODE_STRING SafeText;
-   NTSTATUS Status;
-   DECLARE_RETURN(INT);
+   BOOL Ret = TRUE;
 
    DPRINT("Enter NtUserDefSetText\n");
+
+   RtlInitUnicodeString(&SafeText, NULL);
+   if (WindowText != NULL)
+   {
+       _SEH_TRY
+       {
+           SafeText = ProbeForReadUnicodeString(WindowText);
+       }
+       _SEH_HANDLE
+       {
+           Ret = FALSE;
+           SetLastNtError(_SEH_GetExceptionCode());
+       }
+       _SEH_END;
+
+       if (!Ret)
+           return FALSE;
+   }
+
    UserEnterExclusive();
 
    if(!(Window = UserGetWindowObject(hWnd)))
    {
-      RETURN( FALSE);
-   }
-
-   if(WindowText)
-   {
-      Status = IntSafeCopyUnicodeString(&SafeText, WindowText);
-      if(!NT_SUCCESS(Status))
-      {
-         SetLastNtError(Status);
-         RETURN( FALSE);
-      }
+      UserLeave();
+      return FALSE;
+   }
+   Wnd = Window->Wnd;
+
+   if(SafeText.Length != 0)
+   {
+      _SEH_TRY
+      {
+          if (Wnd->WindowName.MaximumLength > 0 &&
+              SafeText.Length <= Wnd->WindowName.MaximumLength - sizeof(UNICODE_NULL))
+          {
+              ASSERT(Wnd->WindowName.Buffer != NULL);
+
+              Wnd->WindowName.Length = SafeText.Length;
+              Wnd->WindowName.Buffer[SafeText.Length / sizeof(WCHAR)] = L'\0';
+              RtlCopyMemory(Wnd->WindowName.Buffer,
+                            SafeText.Buffer,
+                            SafeText.Length);
+          }
+          else
+          {
+              PWCHAR buf;
+              Wnd->WindowName.MaximumLength = Wnd->WindowName.Length = 0;
+              buf = Wnd->WindowName.Buffer;
+              Wnd->WindowName.Buffer = NULL;
+              if (buf != NULL)
+              {
+                  DesktopHeapFree(Wnd->ti->Desktop,
+                                  buf);
+              }
+
+              Wnd->WindowName.Buffer = DesktopHeapAlloc(Wnd->ti->Desktop,
+                                                        SafeText.Length + sizeof(UNICODE_NULL));
+              if (Wnd->WindowName.Buffer != NULL)
+              {
+                  Wnd->WindowName.Buffer[SafeText.Length / sizeof(WCHAR)] = L'\0';
+                  RtlCopyMemory(Wnd->WindowName.Buffer,
+                                SafeText.Buffer,
+                                SafeText.Length);
+                  Wnd->WindowName.MaximumLength = SafeText.Length + sizeof(UNICODE_NULL);
+                  Wnd->WindowName.Length = SafeText.Length;
+              }
+              else
+              {
+                  SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+                  Ret = FALSE;
+              }
+          }
+      }
+      _SEH_HANDLE
+      {
+           SetLastNtError(_SEH_GetExceptionCode());
+           Ret = FALSE;
+      }
+      _SEH_END;
    }
    else
    {
-      RtlInitUnicodeString(&SafeText, NULL);
-   }
-
-   /* FIXME - do this thread-safe! otherwise one could crash here! */
-   RtlFreeUnicodeString(&Window->WindowName);
-
-   Window->WindowName = SafeText;
+      Wnd->WindowName.Length = 0;
+      if (Wnd->WindowName.Buffer != NULL)
+          Wnd->WindowName.Buffer[0] = L'\0';
+   }
 
    /* Send shell notifications */
    if (!IntGetOwner(Window) && !IntGetParent(Window))
@@ -4659,12 +4738,11 @@
       co_IntShellHookNotify(HSHELL_REDRAW, (LPARAM) hWnd);
    }
 
-   RETURN( TRUE);
-
-CLEANUP:
-   DPRINT("Leave NtUserDefSetText, ret=%i\n",_ret_);
+   Ret = TRUE;
+
+   DPRINT("Leave NtUserDefSetText, ret=%i\n", Ret);
    UserLeave();
-   END_CLEANUP;
+   return Ret;
 }
 
 /*
@@ -4678,6 +4756,7 @@
 NtUserInternalGetWindowText(HWND hWnd, LPWSTR lpString, INT nMaxCount)
 {
    PWINDOW_OBJECT Window;
+   PWINDOW Wnd;
    NTSTATUS Status;
    INT Result;
    DECLARE_RETURN(INT);
@@ -4695,9 +4774,9 @@
    {
       RETURN( 0);
    }
-
-   /* FIXME - do this thread-safe! otherwise one could crash here! */
-   Result = Window->WindowName.Length / sizeof(WCHAR);
+   Wnd = Window->Wnd;
+
+   Result = Wnd->WindowName.Length / sizeof(WCHAR);
    if(lpString)
    {
       const WCHAR Terminator = L'\0';
@@ -4707,7 +4786,7 @@
       Copy = min(nMaxCount - 1, Result);
       if(Copy > 0)
       {
-         Status = MmCopyToCaller(Buffer, Window->WindowName.Buffer, Copy * sizeof(WCHAR));
+         Status = MmCopyToCaller(Buffer, Wnd->WindowName.Buffer, Copy * sizeof(WCHAR));
          if(!NT_SUCCESS(Status))
          {
             SetLastNtError(Status);




More information about the Ros-diffs mailing list