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/d…
==============================================================================
--- 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/w…
==============================================================================
--- 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/ntu…
==============================================================================
--- 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/in…
==============================================================================
--- 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/nt…
==============================================================================
--- 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/nt…
==============================================================================
--- 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/nt…
==============================================================================
--- 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/nt…
==============================================================================
--- 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/nt…
==============================================================================
--- 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/nt…
==============================================================================
--- 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/nt…
==============================================================================
--- 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);