mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
Optimize GetWindowText(Length)A/W and WM_GETTEXT(LENGTH)
svn path=/trunk/; revision=30490
This commit is contained in:
parent
99767a3b59
commit
fdb8bd5a53
11 changed files with 318 additions and 151 deletions
|
@ -1602,6 +1602,7 @@ DefWindowProcA(HWND hWnd,
|
|||
LPARAM lParam)
|
||||
{
|
||||
LRESULT Result = 0;
|
||||
PWINDOW Wnd;
|
||||
|
||||
SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam);
|
||||
switch (Msg)
|
||||
|
@ -1630,33 +1631,57 @@ DefWindowProcA(HWND hWnd,
|
|||
|
||||
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;
|
||||
PWSTR buf = NULL;
|
||||
PSTR outbuf = (PSTR)lParam;
|
||||
UINT copy;
|
||||
|
||||
Buffer = HeapAlloc(GetProcessHeap(), 0, wParam * sizeof(WCHAR));
|
||||
if (!Buffer)
|
||||
Wnd = ValidateHwnd(hWnd);
|
||||
if (Wnd != NULL && wParam != 0)
|
||||
{
|
||||
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';
|
||||
}
|
||||
if (Wnd->WindowName.Buffer != NULL)
|
||||
buf = DesktopPtrToUser(Wnd->WindowName.Buffer);
|
||||
else
|
||||
outbuf[0] = L'\0';
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, Buffer);
|
||||
|
||||
Result = (LRESULT)Length;
|
||||
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 @@ DefWindowProcW(HWND hWnd,
|
|||
LPARAM lParam)
|
||||
{
|
||||
LRESULT Result = 0;
|
||||
PWINDOW Wnd;
|
||||
|
||||
SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam);
|
||||
switch (Msg)
|
||||
|
@ -1732,13 +1758,51 @@ DefWindowProcW(HWND hWnd,
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1035,31 +1035,50 @@ GetWindowRect(HWND hWnd,
|
|||
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;
|
||||
Wnd = ValidateHwnd(hWnd);
|
||||
if (!Wnd)
|
||||
return 0;
|
||||
|
||||
if (ProcessId != GetCurrentProcessId())
|
||||
if (Wnd->pi != g_kpi)
|
||||
{
|
||||
/* 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))
|
||||
if (nMaxCount <= 0)
|
||||
return 0;
|
||||
|
||||
/* do not send WM_GETTEXT messages to other processes */
|
||||
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 @@ GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount)
|
|||
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 @@ GetWindowTextLengthA(HWND hWnd)
|
|||
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 @@ GetWindowTextLengthW(HWND hWnd)
|
|||
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;
|
||||
Wnd = ValidateHwnd(hWnd);
|
||||
if (!Wnd)
|
||||
return 0;
|
||||
|
||||
if (ProcessId == GetCurrentProcessId())
|
||||
return SendMessageW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
|
||||
if (Wnd->pi != g_kpi)
|
||||
{
|
||||
INT Length;
|
||||
|
||||
return NtUserInternalGetWindowText(hWnd, lpString, nMaxCount);
|
||||
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 @@ int
|
|||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -77,6 +77,10 @@ typedef struct _WINDOW
|
|||
/* 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
|
||||
|
|
|
@ -45,10 +45,6 @@ typedef struct _WINDOW_OBJECT
|
|||
};
|
||||
/* 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. */
|
||||
|
|
|
@ -1927,11 +1927,11 @@ NtUserGetClassLong(IN HWND hWnd,
|
|||
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 @@ InvalidParameter:
|
|||
dwNewLong = (ULONG_PTR)&Value;
|
||||
}
|
||||
|
||||
Ret = UserSetClassLongPtr(Window->Class,
|
||||
Ret = UserSetClassLongPtr(Window->Wnd->Class,
|
||||
Offset,
|
||||
dwNewLong,
|
||||
Ansi);
|
||||
|
@ -2218,7 +2218,7 @@ NtUserGetClassName (IN HWND hWnd,
|
|||
CapturedClassName = *ClassName;
|
||||
|
||||
/* get the class name */
|
||||
Ret = UserGetClassName(Window->Class,
|
||||
Ret = UserGetClassName(Window->Wnd->Class,
|
||||
&CapturedClassName,
|
||||
Ansi);
|
||||
|
||||
|
|
|
@ -1357,7 +1357,7 @@ NtUserPaintDesktop(HDC hDC)
|
|||
RETURN(FALSE);
|
||||
}
|
||||
|
||||
DesktopBrush = (HBRUSH)UserGetClassLongPtr(WndDesktop->Class, GCL_HBRBACKGROUND, FALSE);
|
||||
DesktopBrush = (HBRUSH)UserGetClassLongPtr(WndDesktop->Wnd->Class, GCL_HBRBACKGROUND, FALSE);
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -152,7 +152,6 @@ co_IntSetForegroundAndFocusWindow(PWINDOW_OBJECT Window, PWINDOW_OBJECT FocusWin
|
|||
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 @@ NtUserSetActiveWindow(HWND hWnd)
|
|||
RETURN( 0);
|
||||
}
|
||||
|
||||
DPRINT("(%wZ)\n", &Window->WindowName);
|
||||
|
||||
ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetCurrentThreadWin32Thread()->MessageQueue;
|
||||
|
||||
if (Window->MessageQueue != ThreadQueue)
|
||||
|
|
|
@ -603,7 +603,7 @@ co_IntTranslateMouseMessage(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, USHORT *
|
|||
{
|
||||
/* 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;
|
||||
|
|
|
@ -1528,12 +1528,12 @@ UserDrawSysMenuButton(
|
|||
|
||||
/* 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 @@ BOOL UserDrawCaption(
|
|||
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,
|
||||
|
|
|
@ -401,7 +401,7 @@ UserGetDCEx(PWINDOW_OBJECT Window OPTIONAL, HANDLE ClipRegion, ULONG Flags)
|
|||
|
||||
if (!(Flags & DCX_WINDOW))
|
||||
{
|
||||
if (Window->Class->Style & CS_PARENTDC)
|
||||
if (Wnd->Class->Style & CS_PARENTDC)
|
||||
{
|
||||
Flags |= DCX_PARENTCLIP;
|
||||
}
|
||||
|
@ -739,7 +739,7 @@ DceFreeWindowDCE(PWINDOW_OBJECT Window)
|
|||
{
|
||||
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;
|
||||
|
|
|
@ -296,6 +296,7 @@ static VOID
|
|||
UserFreeWindowInfo(PW32THREADINFO ti, PWINDOW_OBJECT WindowObject)
|
||||
{
|
||||
PW32CLIENTINFO ClientInfo = GetWin32ClientInfo();
|
||||
PWINDOW Wnd = WindowObject->Wnd;
|
||||
|
||||
if (ClientInfo->pvWND == DesktopHeapAddressToUser(WindowObject->Wnd))
|
||||
{
|
||||
|
@ -303,7 +304,16 @@ UserFreeWindowInfo(PW32THREADINFO ti, PWINDOW_OBJECT WindowObject)
|
|||
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,18 +463,16 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
|
|||
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 @@ static WNDPROC
|
|||
IntGetWindowProc(IN PWINDOW_OBJECT Window,
|
||||
IN BOOL Ansi)
|
||||
{
|
||||
PWINDOW Wnd = Window->Wnd;
|
||||
|
||||
ASSERT(UserIsEnteredExclusive() == TRUE);
|
||||
|
||||
if (Window->IsSystem)
|
||||
|
@ -529,22 +539,22 @@ IntGetWindowProc(IN PWINDOW_OBJECT Window,
|
|||
{
|
||||
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 @@ IntGetWindowInfo(PWINDOW_OBJECT Window, PWINDOWINFO pwi)
|
|||
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 @@ AllocErr:
|
|||
* 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 @@ AllocErr:
|
|||
Window->hSelf = hWnd;
|
||||
|
||||
if (!hMenu)
|
||||
hMenu = Window->Class->hMenu;
|
||||
hMenu = Wnd->Class->hMenu;
|
||||
|
||||
if (0 != (dwStyle & WS_CHILD))
|
||||
{
|
||||
|
@ -1634,18 +1644,18 @@ AllocErr:
|
|||
|
||||
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 @@ AllocErr:
|
|||
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)
|
||||
if (NULL != WindowName->Buffer && WindowName->Length > 0)
|
||||
{
|
||||
Window->WindowName.MaximumLength = WindowName->MaximumLength;
|
||||
Window->WindowName.Length = WindowName->Length;
|
||||
Window->WindowName.Buffer = ExAllocatePoolWithTag(PagedPool, WindowName->MaximumLength,
|
||||
TAG_STRING);
|
||||
if (NULL == Window->WindowName.Buffer)
|
||||
Wnd->WindowName.Buffer = DesktopHeapAlloc(Wnd->ti->Desktop,
|
||||
WindowName->Length + sizeof(UNICODE_NULL));
|
||||
if (Wnd->WindowName.Buffer == NULL)
|
||||
{
|
||||
DPRINT1("Failed to allocate mem for window name\n");
|
||||
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
||||
RETURN( NULL);
|
||||
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
|
||||
RETURN( (HWND)0);
|
||||
}
|
||||
RtlCopyMemory(Window->WindowName.Buffer, WindowName->Buffer, WindowName->MaximumLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlInitUnicodeString(&Window->WindowName, NULL);
|
||||
|
||||
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 @@ IntFindWindow(PWINDOW_OBJECT Parent,
|
|||
/* 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 @@ NtUserFindWindowEx(HWND hwndParent,
|
|||
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 @@ IntSetWindowProc(PWINDOW_OBJECT Window,
|
|||
{
|
||||
WNDPROC Ret;
|
||||
PCALLPROC CallProc;
|
||||
PWINDOW Wnd = Window->Wnd;
|
||||
|
||||
/* resolve any callproc handle if possible */
|
||||
if (IsCallProcHandle(NewWndProc))
|
||||
|
@ -3601,7 +3619,7 @@ IntSetWindowProc(PWINDOW_OBJECT Window,
|
|||
}
|
||||
else
|
||||
{
|
||||
CallProc = UserFindCallProc(Window->Class,
|
||||
CallProc = UserFindCallProc(Wnd->Class,
|
||||
Window->WndProc,
|
||||
Window->Unicode);
|
||||
if (CallProc == NULL)
|
||||
|
@ -3609,14 +3627,14 @@ IntSetWindowProc(PWINDOW_OBJECT Window,
|
|||
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 @@ IntSetWindowProc(PWINDOW_OBJECT Window,
|
|||
}
|
||||
}
|
||||
|
||||
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,49 +4640,109 @@ BOOL STDCALL
|
|||
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);
|
||||
UserLeave();
|
||||
return FALSE;
|
||||
}
|
||||
Wnd = Window->Wnd;
|
||||
|
||||
if(WindowText)
|
||||
if(SafeText.Length != 0)
|
||||
{
|
||||
Status = IntSafeCopyUnicodeString(&SafeText, WindowText);
|
||||
if(!NT_SUCCESS(Status))
|
||||
_SEH_TRY
|
||||
{
|
||||
SetLastNtError(Status);
|
||||
RETURN( FALSE);
|
||||
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);
|
||||
Wnd->WindowName.Length = 0;
|
||||
if (Wnd->WindowName.Buffer != NULL)
|
||||
Wnd->WindowName.Buffer[0] = L'\0';
|
||||
}
|
||||
|
||||
/* FIXME - do this thread-safe! otherwise one could crash here! */
|
||||
RtlFreeUnicodeString(&Window->WindowName);
|
||||
|
||||
Window->WindowName = SafeText;
|
||||
|
||||
/* Send shell notifications */
|
||||
if (!IntGetOwner(Window) && !IntGetParent(Window))
|
||||
{
|
||||
co_IntShellHookNotify(HSHELL_REDRAW, (LPARAM) hWnd);
|
||||
}
|
||||
|
||||
RETURN( TRUE);
|
||||
Ret = TRUE;
|
||||
|
||||
CLEANUP:
|
||||
DPRINT("Leave NtUserDefSetText, ret=%i\n",_ret_);
|
||||
DPRINT("Leave NtUserDefSetText, ret=%i\n", Ret);
|
||||
UserLeave();
|
||||
END_CLEANUP;
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4678,6 +4756,7 @@ INT STDCALL
|
|||
NtUserInternalGetWindowText(HWND hWnd, LPWSTR lpString, INT nMaxCount)
|
||||
{
|
||||
PWINDOW_OBJECT Window;
|
||||
PWINDOW Wnd;
|
||||
NTSTATUS Status;
|
||||
INT Result;
|
||||
DECLARE_RETURN(INT);
|
||||
|
@ -4695,9 +4774,9 @@ NtUserInternalGetWindowText(HWND hWnd, LPWSTR lpString, INT nMaxCount)
|
|||
{
|
||||
RETURN( 0);
|
||||
}
|
||||
Wnd = Window->Wnd;
|
||||
|
||||
/* FIXME - do this thread-safe! otherwise one could crash here! */
|
||||
Result = Window->WindowName.Length / sizeof(WCHAR);
|
||||
Result = Wnd->WindowName.Length / sizeof(WCHAR);
|
||||
if(lpString)
|
||||
{
|
||||
const WCHAR Terminator = L'\0';
|
||||
|
@ -4707,7 +4786,7 @@ NtUserInternalGetWindowText(HWND hWnd, LPWSTR lpString, INT nMaxCount)
|
|||
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);
|
||||
|
|
Loading…
Reference in a new issue