diff --git a/reactos/include/funcs.h b/reactos/include/funcs.h index f650e836578..8c5acbb632f 100644 --- a/reactos/include/funcs.h +++ b/reactos/include/funcs.h @@ -4478,7 +4478,7 @@ EndTask( WINBOOL fForce ); -DWORD +int STDCALL InternalGetWindowText( HWND hWnd, diff --git a/reactos/include/win32k/ntuser.h b/reactos/include/win32k/ntuser.h index ad51638f620..8042f65e6ec 100644 --- a/reactos/include/win32k/ntuser.h +++ b/reactos/include/win32k/ntuser.h @@ -365,7 +365,7 @@ NtUserDeferWindowPos(HDWP WinPosInfo, int cy, UINT Flags); BOOL STDCALL -NtUserDefSetText(HWND WindowHandle, PANSI_STRING Text); +NtUserDefSetText(HWND WindowHandle, PUNICODE_STRING WindowText); BOOLEAN STDCALL @@ -865,12 +865,12 @@ NtUserInitTask( DWORD Unknown9, DWORD Unknown10); -DWORD +INT STDCALL NtUserInternalGetWindowText( HWND hWnd, LPWSTR lpString, - int nMaxCount); + INT nMaxCount); DWORD STDCALL diff --git a/reactos/lib/user32/windows/defwnd.c b/reactos/lib/user32/windows/defwnd.c index 03a2fcc93ac..d8cab1de28f 100644 --- a/reactos/lib/user32/windows/defwnd.c +++ b/reactos/lib/user32/windows/defwnd.c @@ -1,4 +1,4 @@ -/* $Id: defwnd.c,v 1.132 2004/04/09 20:03:14 navaraf Exp $ +/* $Id: defwnd.c,v 1.133 2004/04/13 16:48:44 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -1482,42 +1482,50 @@ DefWindowProcA(HWND hWnd, case WM_GETTEXTLENGTH: { - return InternalGetWindowText(hWnd, NULL, 0); + return (LRESULT)NtUserInternalGetWindowText(hWnd, NULL, 0); } case WM_GETTEXT: { - UNICODE_STRING UnicodeString; + LPWSTR Buffer; LPSTR AnsiBuffer = (LPSTR)lParam; - BOOL Result; + INT Length; if (wParam > 1) { *((PWSTR)lParam) = '\0'; } - UnicodeString.Length = UnicodeString.MaximumLength = - wParam * sizeof(WCHAR); - UnicodeString.Buffer = HeapAlloc(GetProcessHeap(), 0, - UnicodeString.Length); - if (!UnicodeString.Buffer) + Buffer = HeapAlloc(GetProcessHeap(), 0, wParam * sizeof(WCHAR)); + if (!Buffer) return FALSE; - Result = InternalGetWindowText(hWnd, UnicodeString.Buffer, wParam); - if (wParam > 0 && - !WideCharToMultiByte(CP_ACP, 0, UnicodeString.Buffer, -1, + Length = NtUserInternalGetWindowText(hWnd, Buffer, wParam); + if (Length > 0 && wParam > 0 && + !WideCharToMultiByte(CP_ACP, 0, Buffer, -1, AnsiBuffer, wParam, NULL, NULL)) { - AnsiBuffer[wParam - 1] = 0; + AnsiBuffer[0] = '\0'; } - HeapFree(GetProcessHeap(), 0, UnicodeString.Buffer); - return Result; + HeapFree(GetProcessHeap(), 0, Buffer); + + return (LRESULT)Length; } case WM_SETTEXT: { ANSI_STRING AnsiString; - RtlInitAnsiString(&AnsiString, (LPSTR)lParam); - NtUserDefSetText(hWnd, &AnsiString); + UNICODE_STRING UnicodeString; + + if(lParam) + { + RtlInitAnsiString(&AnsiString, (LPSTR)lParam); + RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE); + NtUserDefSetText(hWnd, &UnicodeString); + RtlFreeUnicodeString(&UnicodeString); + } + else + NtUserDefSetText(hWnd, NULL); + if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION) { DefWndNCPaint(hWnd, (HRGN)1); @@ -1557,29 +1565,27 @@ DefWindowProcW(HWND hWnd, case WM_GETTEXTLENGTH: { - return InternalGetWindowText(hWnd, NULL, 0); + return (LRESULT)NtUserInternalGetWindowText(hWnd, NULL, 0); } case WM_GETTEXT: { - DWORD Result; if (wParam > 1) { *((PWSTR)lParam) = '\0'; } - Result = InternalGetWindowText(hWnd, (PWSTR)lParam, wParam); - return Result; + return (LRESULT)NtUserInternalGetWindowText(hWnd, (PWSTR)lParam, wParam); } case WM_SETTEXT: { UNICODE_STRING UnicodeString; - ANSI_STRING AnsiString; - RtlInitUnicodeString(&UnicodeString, (LPWSTR)lParam); - RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, TRUE); - NtUserDefSetText(hWnd, &AnsiString); - RtlFreeAnsiString(&AnsiString); + if(lParam) + RtlInitUnicodeString(&UnicodeString, (LPWSTR)lParam); + + NtUserDefSetText(hWnd, (lParam ? &UnicodeString : NULL)); + if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION) { DefWndNCPaint(hWnd, (HRGN)1); diff --git a/reactos/lib/user32/windows/window.c b/reactos/lib/user32/windows/window.c index dc830ddbbca..05c631349cc 100644 --- a/reactos/lib/user32/windows/window.c +++ b/reactos/lib/user32/windows/window.c @@ -1,4 +1,4 @@ -/* $Id: window.c,v 1.109 2004/04/10 07:37:28 navaraf Exp $ +/* $Id: window.c,v 1.110 2004/04/13 16:48:45 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -1464,7 +1464,7 @@ GetWindowContextHelpId(HWND hwnd) /* * @implemented */ -INT +int STDCALL InternalGetWindowText(HWND hWnd, LPWSTR lpString, int nMaxCount) { diff --git a/reactos/subsys/win32k/ntuser/window.c b/reactos/subsys/win32k/ntuser/window.c index e5daa0286da..ec3fc9e57f0 100644 --- a/reactos/subsys/win32k/ntuser/window.c +++ b/reactos/subsys/win32k/ntuser/window.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: window.c,v 1.211 2004/04/10 07:37:28 navaraf Exp $ +/* $Id: window.c,v 1.212 2004/04/13 16:48:45 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -54,6 +54,7 @@ #include #include #include +#include #define NDEBUG #include @@ -425,6 +426,11 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window, NtGdiDeleteObject(Window->WindowRegion); } + if(Window->WindowName.Buffer) + { + ExFreePool(Window->WindowName.Buffer); + } + IntReleaseWindowObject(Window); return 0; @@ -1343,14 +1349,18 @@ NtUserCreateWindowEx(DWORD dwExStyle, BOOL MenuChanged; DPRINT("NtUserCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight); - - if (! RtlCreateUnicodeString(&WindowName, - NULL == lpWindowName->Buffer ? - L"" : lpWindowName->Buffer)) + + if(lpWindowName) + { + Status = IntSafeCopyUnicodeString(&WindowName, lpWindowName); + if (!NT_SUCCESS(Status)) { - SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); + SetLastNtError(Status); return((HWND)0); } + } + else + RtlInitUnicodeString(&WindowName, NULL); ParentWindowHandle = PsGetWin32Thread()->Desktop->DesktopWindow; OwnerWindowHandle = NULL; @@ -1511,8 +1521,8 @@ NtUserCreateWindowEx(DWORD dwExStyle, ExInitializeFastMutex(&WindowObject->PropListLock); ExInitializeFastMutex(&WindowObject->RelativesLock); ExInitializeFastMutex(&WindowObject->UpdateLock); - - RtlInitUnicodeString(&WindowObject->WindowName, WindowName.Buffer); + + WindowObject->WindowName = WindowName; /* Correct the window style. */ if (!(dwStyle & WS_CHILD)) @@ -3708,76 +3718,112 @@ NtUserWindowFromPoint(LONG X, LONG Y) * Undocumented function that is called from DefWindowProc to set * window text. * - * FIXME: Call this from user32.dll! - * * Status - * @unimplemented + * @implemented */ BOOL STDCALL -NtUserDefSetText(HWND WindowHandle, PANSI_STRING Text) +NtUserDefSetText(HWND WindowHandle, PUNICODE_STRING WindowText) { - PWINDOW_OBJECT WindowObject; - UNICODE_STRING NewWindowName; - BOOL Result = FALSE; - - WindowObject = IntGetWindowObject(WindowHandle); - if (!WindowObject) - { - SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); + PWINDOW_OBJECT WindowObject; + UNICODE_STRING SafeText; + NTSTATUS Status; + + WindowObject = IntGetWindowObject(WindowHandle); + if(!WindowObject) + { + SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); + return FALSE; + } + + if(WindowText) + { + Status = IntSafeCopyUnicodeString(&SafeText, WindowText); + if(!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + IntReleaseWindowObject(WindowObject); return FALSE; - } - - if (NT_SUCCESS(RtlAnsiStringToUnicodeString(&NewWindowName, Text, TRUE))) - { - RtlFreeUnicodeString(&WindowObject->WindowName); - WindowObject->WindowName.Buffer = NewWindowName.Buffer; - WindowObject->WindowName.Length = NewWindowName.Length; - WindowObject->WindowName.MaximumLength = NewWindowName.MaximumLength; - Result = TRUE; - } - - IntReleaseWindowObject(WindowObject); - - return Result; + } + } + else + { + RtlInitUnicodeString(&SafeText, NULL); + } + + /* FIXME - do this thread-safe! otherwise one could crash here! */ + if(WindowObject->WindowName.Buffer) + { + ExFreePool(WindowObject->WindowName.Buffer); + } + + WindowObject->WindowName = SafeText; + + IntReleaseWindowObject(WindowObject); + return TRUE; } /* * NtUserInternalGetWindowText * - * FIXME: Call this from user32.dll! - * * Status * @implemented */ -DWORD STDCALL -NtUserInternalGetWindowText(HWND WindowHandle, LPWSTR Text, INT MaxCount) +INT STDCALL +NtUserInternalGetWindowText(HWND hWnd, LPWSTR lpString, INT nMaxCount) { - PWINDOW_OBJECT WindowObject; - DWORD Result; - - WindowObject = IntGetWindowObject(WindowHandle); - if (!WindowObject) - { - SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); - return 0; - } - - Result = WindowObject->WindowName.Length / sizeof(WCHAR); - if (Text) - { - /* FIXME: Shouldn't it be always NULL terminated? */ - wcsncpy(Text, WindowObject->WindowName.Buffer, MaxCount); - if (MaxCount < Result) + PWINDOW_OBJECT WindowObject; + NTSTATUS Status; + INT Result; + + if(lpString && (nMaxCount <= 1)) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return 0; + } + + WindowObject = IntGetWindowObject(hWnd); + if(!WindowObject) + { + SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); + return 0; + } + + /* FIXME - do this thread-safe! otherwise one could crash here! */ + Result = WindowObject->WindowName.Length / sizeof(WCHAR); + if(lpString) + { + const WCHAR Terminator = L'\0'; + INT Copy; + WCHAR *Buffer = (WCHAR*)lpString; + + Copy = min(nMaxCount - 1, Result); + if(Copy > 0) + { + Status = MmCopyToCaller(Buffer, WindowObject->WindowName.Buffer, Copy * sizeof(WCHAR)); + if(!NT_SUCCESS(Status)) { - Result = MaxCount; + SetLastNtError(Status); + IntReleaseWindowObject(WindowObject); + return 0; } - } - - IntReleaseWindowObject(WindowObject); - - return Result; + Buffer += Copy; + } + + Status = MmCopyToCaller(Buffer, &Terminator, sizeof(WCHAR)); + if(!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + IntReleaseWindowObject(WindowObject); + return 0; + } + + Result = Copy; + } + + IntReleaseWindowObject(WindowObject); + return Result; } DWORD STDCALL