From fbfd3a482042938eb4298add090ba2fc4361896e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9=20van=20Geldorp?= Date: Wed, 16 Jun 2004 06:09:40 +0000 Subject: [PATCH] Marshall WM_CREATE/WM_NCCREATE messages svn path=/trunk/; revision=9675 --- reactos/lib/user32/windows/message.c | 32 +++- reactos/subsys/win32k/include/cleanup.h | 6 + reactos/subsys/win32k/ntuser/callback.c | 36 ++-- reactos/subsys/win32k/ntuser/message.c | 114 ++++++++++-- reactos/subsys/win32k/ntuser/misc.c | 34 +++- reactos/subsys/win32k/ntuser/window.c | 224 ++++++++++++++++-------- 6 files changed, 332 insertions(+), 114 deletions(-) diff --git a/reactos/lib/user32/windows/message.c b/reactos/lib/user32/windows/message.c index b46f5af9604..e2f074b2d5a 100644 --- a/reactos/lib/user32/windows/message.c +++ b/reactos/lib/user32/windows/message.c @@ -1,4 +1,4 @@ -/* $Id: message.c,v 1.39 2004/04/29 21:13:16 gvg Exp $ +/* $Id: message.c,v 1.40 2004/06/16 06:09:40 gvg Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -17,6 +17,11 @@ #define NTOS_MODE_USER #include +#ifndef TODO +#define NDEBUG +#include +#endif + /* DDE message exchange * * - Session initialization @@ -257,6 +262,27 @@ MsgiKMToUMMessage(PMSG KMMsg, PMSG UMMsg) switch (UMMsg->message) { + case WM_CREATE: + case WM_NCCREATE: + { + CREATESTRUCTW *Cs = (CREATESTRUCTW *) KMMsg->lParam; + PCHAR Class; + Cs->lpszName = (LPCWSTR) ((PCHAR) Cs + (DWORD_PTR) Cs->lpszName); + Class = (PCHAR) Cs + (DWORD_PTR) Cs->lpszClass; + if (L'A' == *((WCHAR *) Class)) + { + Class += sizeof(WCHAR); + Cs->lpszClass = (LPCWSTR)(DWORD_PTR) (*((ATOM *) Class)); + } + else + { + ASSERT(L'S' == *((WCHAR *) Class)); + Class += sizeof(WCHAR); + Cs->lpszClass = (LPCWSTR) Class; + } + } + break; + case WM_DDE_ACK: { PKMDDELPARAM DdeLparam = (PKMDDELPARAM) KMMsg->lParam; @@ -270,8 +296,9 @@ MsgiKMToUMMessage(PMSG KMMsg, PMSG UMMsg) { UMMsg->lParam = DdeLparam->Value.Unpacked; } - break; } + break; + case WM_DDE_EXECUTE: { PKMDDEEXECUTEDATA KMDdeExecuteData; @@ -301,6 +328,7 @@ MsgiKMToUMMessage(PMSG KMMsg, PMSG UMMsg) UMMsg->lParam = (LPARAM) GlobalData; } break; + default: break; } diff --git a/reactos/subsys/win32k/include/cleanup.h b/reactos/subsys/win32k/include/cleanup.h index 6ceb9166f8b..46d6496e2ea 100644 --- a/reactos/subsys/win32k/include/cleanup.h +++ b/reactos/subsys/win32k/include/cleanup.h @@ -11,4 +11,10 @@ NTSTATUS FASTCALL IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest, PUNICODE_STRING Source); +NTSTATUS FASTCALL +IntUnicodeStringToNULLTerminated(PWSTR *Dest, PUNICODE_STRING Src); + +void FASTCALL +IntFreeNULLTerminatedFromUnicodeString(PWSTR NullTerminated, PUNICODE_STRING UnicodeString); + #endif /* ndef _SUBSYS_WIN32K_INCLUDE_CLEANUP_H */ diff --git a/reactos/subsys/win32k/ntuser/callback.c b/reactos/subsys/win32k/ntuser/callback.c index 3b254fc87c5..143690fad4c 100644 --- a/reactos/subsys/win32k/ntuser/callback.c +++ b/reactos/subsys/win32k/ntuser/callback.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: callback.c,v 1.23 2004/05/22 21:12:15 weiden Exp $ +/* $Id: callback.c,v 1.24 2004/06/16 06:09:40 gvg Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -250,6 +250,8 @@ IntCallHookProc(INT HookId, CBT_CREATEWNDW *CbtCreateWnd; PCHAR Extra; PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra; + PUNICODE_STRING WindowName; + PUNICODE_STRING ClassName; ArgumentLength = sizeof(HOOKPROC_CALLBACK_ARGUMENTS) - sizeof(WCHAR) + ModuleName->Length; @@ -261,15 +263,12 @@ IntCallHookProc(INT HookId, case HCBT_CREATEWND: CbtCreateWnd = (CBT_CREATEWNDW *) lParam; ArgumentLength += sizeof(HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS); - if (NULL != CbtCreateWnd->lpcs->lpszName) + WindowName = (PUNICODE_STRING) (CbtCreateWnd->lpcs->lpszName); + ArgumentLength += WindowName->Length + sizeof(WCHAR); + ClassName = (PUNICODE_STRING) (CbtCreateWnd->lpcs->lpszClass); + if (! IS_ATOM(ClassName->Buffer)) { - ArgumentLength += (wcslen(CbtCreateWnd->lpcs->lpszName) - + 1) * sizeof(WCHAR); - } - if (0 != HIWORD(CbtCreateWnd->lpcs->lpszClass)) - { - ArgumentLength += (wcslen(CbtCreateWnd->lpcs->lpszClass) - + 1) * sizeof(WCHAR); + ArgumentLength += ClassName->Length + sizeof(WCHAR); } break; default: @@ -310,19 +309,18 @@ IntCallHookProc(INT HookId, CbtCreatewndExtra->Cs = *(CbtCreateWnd->lpcs); CbtCreatewndExtra->WndInsertAfter = CbtCreateWnd->hwndInsertAfter; Extra = (PCHAR) (CbtCreatewndExtra + 1); - if (NULL != CbtCreateWnd->lpcs->lpszName) + RtlCopyMemory(Extra, WindowName->Buffer, WindowName->Length); + CbtCreatewndExtra->Cs.lpszName = (LPCWSTR) (Extra - (PCHAR) CbtCreatewndExtra); + Extra += WindowName->Length; + *((WCHAR *) Extra) = L'\0'; + Extra += sizeof(WCHAR); + if (! IS_ATOM(ClassName->Buffer)) { - memcpy(Extra, CbtCreateWnd->lpcs->lpszName, - (wcslen(CbtCreateWnd->lpcs->lpszName) + 1) * sizeof(WCHAR)); - CbtCreatewndExtra->Cs.lpszName = (LPCWSTR) (Extra - (PCHAR) CbtCreatewndExtra); - Extra += (wcslen(CbtCreateWnd->lpcs->lpszName) + 1) * sizeof(WCHAR); - } - if (0 != HIWORD(CbtCreateWnd->lpcs->lpszClass)) - { - memcpy(Extra, CbtCreateWnd->lpcs->lpszClass, - (wcslen(CbtCreateWnd->lpcs->lpszClass) + 1) * sizeof(WCHAR)); + RtlCopyMemory(Extra, ClassName->Buffer, ClassName->Length); CbtCreatewndExtra->Cs.lpszClass = (LPCWSTR) MAKELONG(Extra - (PCHAR) CbtCreatewndExtra, 1); + Extra += ClassName->Length; + *((WCHAR *) Extra) = L'\0'; } break; } diff --git a/reactos/subsys/win32k/ntuser/message.c b/reactos/subsys/win32k/ntuser/message.c index 42cc2eec8b5..8d9ebf17a75 100644 --- a/reactos/subsys/win32k/ntuser/message.c +++ b/reactos/subsys/win32k/ntuser/message.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: message.c,v 1.69 2004/05/22 21:12:15 weiden Exp $ +/* $Id: message.c,v 1.70 2004/06/16 06:09:40 gvg Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -71,13 +71,13 @@ typedef struct tagMSGMEMORY static MSGMEMORY MsgMemory[] = { - { WM_CREATE, sizeof(CREATESTRUCTW), MMS_FLAG_READWRITE }, + { WM_CREATE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE }, { WM_DDE_ACK, sizeof(KMDDELPARAM), MMS_FLAG_READ }, { WM_DDE_EXECUTE, MMS_SIZE_WPARAM, MMS_FLAG_READ }, { WM_GETMINMAXINFO, sizeof(MINMAXINFO), MMS_FLAG_READWRITE }, { WM_GETTEXT, MMS_SIZE_WPARAMWCHAR, MMS_FLAG_WRITE }, { WM_NCCALCSIZE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE }, - { WM_NCCREATE, sizeof(CREATESTRUCTW), MMS_FLAG_READWRITE }, + { WM_NCCREATE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE }, { WM_SETTEXT, MMS_SIZE_LPARAMSZ, MMS_FLAG_READ }, { WM_STYLECHANGED, sizeof(STYLESTRUCT), MMS_FLAG_READ }, { WM_STYLECHANGING, sizeof(STYLESTRUCT), MMS_FLAG_READWRITE }, @@ -107,6 +107,11 @@ FindMsgMemory(UINT Msg) static UINT FASTCALL MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam) { + CREATESTRUCTW *Cs; + PUNICODE_STRING WindowName; + PUNICODE_STRING ClassName; + UINT Size; + if (MMS_SIZE_WPARAM == MsgMemoryEntry->Size) { return (UINT) wParam; @@ -123,9 +128,27 @@ MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam) { switch(MsgMemoryEntry->Message) { + case WM_CREATE: + case WM_NCCREATE: + Cs = (CREATESTRUCTW *) lParam; + WindowName = (PUNICODE_STRING) Cs->lpszName; + ClassName = (PUNICODE_STRING) Cs->lpszClass; + Size = sizeof(CREATESTRUCTW) + WindowName->Length + sizeof(WCHAR); + if (IS_ATOM(ClassName->Buffer)) + { + Size += sizeof(WCHAR) + sizeof(ATOM); + } + else + { + Size += sizeof(WCHAR) + ClassName->Length + sizeof(WCHAR); + } + return Size; + break; + case WM_NCCALCSIZE: return wParam ? sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS) : sizeof(RECT); break; + default: assert(FALSE); return 0; @@ -141,29 +164,82 @@ MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam) static FASTCALL NTSTATUS PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam) { - NCCALCSIZE_PARAMS *UnpackedParams; - NCCALCSIZE_PARAMS *PackedParams; + NCCALCSIZE_PARAMS *UnpackedNcCalcsize; + NCCALCSIZE_PARAMS *PackedNcCalcsize; + CREATESTRUCTW *UnpackedCs; + CREATESTRUCTW *PackedCs; + PUNICODE_STRING WindowName; + PUNICODE_STRING ClassName; + UINT Size; + PCHAR CsData; *lParamPacked = lParam; if (WM_NCCALCSIZE == Msg && wParam) { - UnpackedParams = (NCCALCSIZE_PARAMS *) lParam; - if (UnpackedParams->lppos != (PWINDOWPOS) (UnpackedParams + 1)) + UnpackedNcCalcsize = (NCCALCSIZE_PARAMS *) lParam; + if (UnpackedNcCalcsize->lppos != (PWINDOWPOS) (UnpackedNcCalcsize + 1)) { - PackedParams = ExAllocatePoolWithTag(PagedPool, - sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS), - TAG_MSG); - if (NULL == PackedParams) + PackedNcCalcsize = ExAllocatePoolWithTag(PagedPool, + sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS), + TAG_MSG); + if (NULL == PackedNcCalcsize) { DPRINT1("Not enough memory to pack lParam\n"); return STATUS_NO_MEMORY; } - RtlCopyMemory(PackedParams, UnpackedParams, sizeof(NCCALCSIZE_PARAMS)); - PackedParams->lppos = (PWINDOWPOS) (PackedParams + 1); - RtlCopyMemory(PackedParams->lppos, UnpackedParams->lppos, sizeof(WINDOWPOS)); - *lParamPacked = (LPARAM) PackedParams; + RtlCopyMemory(PackedNcCalcsize, UnpackedNcCalcsize, sizeof(NCCALCSIZE_PARAMS)); + PackedNcCalcsize->lppos = (PWINDOWPOS) (PackedNcCalcsize + 1); + RtlCopyMemory(PackedNcCalcsize->lppos, UnpackedNcCalcsize->lppos, sizeof(WINDOWPOS)); + *lParamPacked = (LPARAM) PackedNcCalcsize; } } + else if (WM_CREATE == Msg || WM_NCCREATE == Msg) + { + UnpackedCs = (CREATESTRUCTW *) lParam; + WindowName = (PUNICODE_STRING) UnpackedCs->lpszName; + ClassName = (PUNICODE_STRING) UnpackedCs->lpszClass; + Size = sizeof(CREATESTRUCTW) + WindowName->Length + sizeof(WCHAR); + if (IS_ATOM(ClassName->Buffer)) + { + Size += sizeof(WCHAR) + sizeof(ATOM); + } + else + { + Size += sizeof(WCHAR) + ClassName->Length + sizeof(WCHAR); + } + PackedCs = ExAllocatePoolWithTag(PagedPool, Size, TAG_MSG); + if (NULL == PackedCs) + { + DPRINT1("Not enough memory to pack lParam\n"); + return STATUS_NO_MEMORY; + } + RtlCopyMemory(PackedCs, UnpackedCs, sizeof(CREATESTRUCTW)); + CsData = (PCHAR) (PackedCs + 1); + PackedCs->lpszName = (LPCWSTR) (CsData - (PCHAR) PackedCs); + RtlCopyMemory(CsData, WindowName->Buffer, WindowName->Length); + CsData += WindowName->Length; + *((WCHAR *) CsData) = L'\0'; + CsData += sizeof(WCHAR); + PackedCs->lpszClass = (LPCWSTR) (CsData - (PCHAR) PackedCs); + if (IS_ATOM(ClassName->Buffer)) + { + *((WCHAR *) CsData) = L'A'; + CsData += sizeof(WCHAR); + *((ATOM *) CsData) = (ATOM)(DWORD_PTR) ClassName->Buffer; + CsData += sizeof(ATOM); + } + else + { + *((WCHAR *) CsData) = L'S'; + CsData += sizeof(WCHAR); + RtlCopyMemory(CsData, ClassName->Buffer, ClassName->Length); + CsData += ClassName->Length; + *((WCHAR *) CsData) = L'\0'; + CsData += sizeof(WCHAR); + } + ASSERT(CsData == (PCHAR) PackedCs + Size); + *lParamPacked = (LPARAM) PackedCs; + } return STATUS_SUCCESS; } @@ -192,8 +268,14 @@ UnpackParam(LPARAM lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam) return STATUS_SUCCESS; } + else if (WM_CREATE == Msg || WM_NCCREATE == Msg) + { + ExFreePool((PVOID) lParamPacked); - assert(FALSE); + return STATUS_SUCCESS; + } + + ASSERT(FALSE); return STATUS_INVALID_PARAMETER; } diff --git a/reactos/subsys/win32k/ntuser/misc.c b/reactos/subsys/win32k/ntuser/misc.c index 68cfe18e24b..0e06f30da1a 100644 --- a/reactos/subsys/win32k/ntuser/misc.c +++ b/reactos/subsys/win32k/ntuser/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.77 2004/06/11 20:15:07 gvg Exp $ +/* $Id: misc.c,v 1.78 2004/06/16 06:09:40 gvg Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -1210,3 +1210,35 @@ IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest, return STATUS_SUCCESS; } +NTSTATUS FASTCALL +IntUnicodeStringToNULLTerminated(PWSTR *Dest, PUNICODE_STRING Src) +{ + if (Src->Length + sizeof(WCHAR) <= Src->MaximumLength + && L'\0' == Src->Buffer[Src->Length / sizeof(WCHAR)]) + { + /* The unicode_string is already nul terminated. Just reuse it. */ + *Dest = Src->Buffer; + return STATUS_SUCCESS; + } + + *Dest = ExAllocatePoolWithTag(PagedPool, Src->Length + sizeof(WCHAR), TAG_STRING); + if (NULL == *Dest) + { + return STATUS_NO_MEMORY; + } + RtlCopyMemory(*Dest, Src->Buffer, Src->Length); + (*Dest)[Src->Length / 2] = L'\0'; + + return STATUS_SUCCESS; +} + +void FASTCALL +IntFreeNULLTerminatedFromUnicodeString(PWSTR NullTerminated, PUNICODE_STRING UnicodeString) +{ + if (NullTerminated != UnicodeString->Buffer) + { + ExFreePool(NullTerminated); + } +} + +/* EOF */ diff --git a/reactos/subsys/win32k/ntuser/window.c b/reactos/subsys/win32k/ntuser/window.c index 5af359c5efd..ffdd0fc880b 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.236 2004/05/27 11:47:42 weiden Exp $ +/* $Id: window.c,v 1.237 2004/06/16 06:09:40 gvg Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -1383,20 +1383,20 @@ IntCalcDefPosSize(PWINDOW_OBJECT Parent, PWINDOW_OBJECT WindowObject, RECT *rc, * @implemented */ HWND STDCALL -NtUserCreateWindowEx(DWORD dwExStyle, - PUNICODE_STRING lpClassName, - PUNICODE_STRING lpWindowName, - DWORD dwStyle, - LONG x, - LONG y, - LONG nWidth, - LONG nHeight, - HWND hWndParent, - HMENU hMenu, - HINSTANCE hInstance, - LPVOID lpParam, - DWORD dwShowMode, - BOOL bUnicodeWindow) +IntCreateWindowEx(DWORD dwExStyle, + PUNICODE_STRING ClassName, + PUNICODE_STRING WindowName, + DWORD dwStyle, + LONG x, + LONG y, + LONG nWidth, + LONG nHeight, + HWND hWndParent, + HMENU hMenu, + HINSTANCE hInstance, + LPVOID lpParam, + DWORD dwShowMode, + BOOL bUnicodeWindow) { PWINSTATION_OBJECT WinStaObject; PWNDCLASS_OBJECT ClassObject; @@ -1405,7 +1405,6 @@ NtUserCreateWindowEx(DWORD dwExStyle, HWND ParentWindowHandle; HWND OwnerWindowHandle; PMENU_OBJECT SystemMenu; - UNICODE_STRING WindowName; NTSTATUS Status; HANDLE Handle; POINT Pos; @@ -1420,44 +1419,7 @@ NtUserCreateWindowEx(DWORD dwExStyle, LRESULT Result; BOOL MenuChanged; BOOL ClassFound; - LPWSTR OrigWindowName = NULL; - - DPRINT("NtUserCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight); - - /* safely copy the window name */ - if(lpWindowName) - { - Status = MmCopyFromCaller(&WindowName, lpWindowName, sizeof(UNICODE_STRING)); - if (!NT_SUCCESS(Status)) - { - SetLastNtError(Status); - return((HWND)0); - } - if(WindowName.Buffer) - { - /* safe the original pointer to the window name */ - OrigWindowName = WindowName.Buffer; - - if(!(WindowName.Buffer = ExAllocatePoolWithTag(NonPagedPool, WindowName.MaximumLength, TAG_STRING))) - { - SetLastNtError(STATUS_NO_MEMORY); - return((HWND)0); - } - - Status = MmCopyFromCaller(WindowName.Buffer, OrigWindowName, WindowName.MaximumLength); - if(!NT_SUCCESS(Status)) - { - ExFreePool(WindowName.Buffer); - SetLastNtError(Status); - return((HWND)0); - } - } - - if(!WindowName.Buffer) - RtlInitUnicodeString(&WindowName, NULL); - } - else - RtlInitUnicodeString(&WindowName, NULL); + PWSTR ClassNameString; ParentWindowHandle = PsGetWin32Thread()->Desktop->DesktopWindow; OwnerWindowHandle = NULL; @@ -1479,7 +1441,6 @@ NtUserCreateWindowEx(DWORD dwExStyle, } else if ((dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD) { - RtlFreeUnicodeString(&WindowName); return (HWND)0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */ } @@ -1495,10 +1456,34 @@ NtUserCreateWindowEx(DWORD dwExStyle, /* FIXME: parent must belong to the current process */ /* Check the class. */ - ClassFound = ClassReferenceClassByNameOrAtom(&ClassObject, lpClassName->Buffer, hInstance); + if (IS_ATOM(ClassName->Buffer)) + { + ClassFound = ClassReferenceClassByNameOrAtom(&ClassObject, ClassName->Buffer, hInstance); + } + else + { + Status = IntUnicodeStringToNULLTerminated(&ClassNameString, ClassName); + if (! NT_SUCCESS(Status)) + { + if (NULL != ParentWindow) + { + IntReleaseWindowObject(ParentWindow); + } + return NULL; + } + ClassFound = ClassReferenceClassByNameOrAtom(&ClassObject, ClassNameString, hInstance); + IntFreeNULLTerminatedFromUnicodeString(ClassNameString, ClassName); + } if (!ClassFound) { - RtlFreeUnicodeString(&WindowName); + if (IS_ATOM(ClassName->Buffer)) + { + DPRINT1("Class 0x%x not found\n", (DWORD_PTR) ClassName->Buffer); + } + else + { + DPRINT1("Class %wZ not found\n", ClassName); + } if (NULL != ParentWindow) { IntReleaseWindowObject(ParentWindow); @@ -1516,7 +1501,6 @@ NtUserCreateWindowEx(DWORD dwExStyle, if (!NT_SUCCESS(Status)) { ClassDereferenceObject(ClassObject); - RtlFreeUnicodeString(&WindowName); if (NULL != ParentWindow) { IntReleaseWindowObject(ParentWindow); @@ -1537,7 +1521,6 @@ NtUserCreateWindowEx(DWORD dwExStyle, { ObDereferenceObject(WinStaObject); ClassDereferenceObject(ClassObject); - RtlFreeUnicodeString(&WindowName); if (NULL != ParentWindow) { IntReleaseWindowObject(ParentWindow); @@ -1622,8 +1605,27 @@ NtUserCreateWindowEx(DWORD dwExStyle, ExInitializeFastMutex(&WindowObject->PropListLock); ExInitializeFastMutex(&WindowObject->RelativesLock); ExInitializeFastMutex(&WindowObject->UpdateLock); - - WindowObject->WindowName = WindowName; + + if (NULL != WindowName->Buffer) + { + WindowObject->WindowName.MaximumLength = WindowName->MaximumLength; + WindowObject->WindowName.Length = WindowName->Length; + WindowObject->WindowName.Buffer = ExAllocatePoolWithTag(PagedPool, WindowName->MaximumLength, + TAG_STRING); + if (NULL == WindowObject->WindowName.Buffer) + { + ClassDereferenceObject(ClassObject); + DPRINT1("Failed to allocate mem for window name\n"); + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + RtlCopyMemory(WindowObject->WindowName.Buffer, WindowName->Buffer, WindowName->MaximumLength); + } + else + { + RtlInitUnicodeString(&WindowObject->WindowName, NULL); + } + /* Correct the window style. */ if (!(dwStyle & WS_CHILD)) @@ -1685,8 +1687,8 @@ NtUserCreateWindowEx(DWORD dwExStyle, Cs.x = Pos.x; Cs.y = Pos.y; Cs.style = dwStyle; - Cs.lpszName = OrigWindowName; /* pass the original pointer to usermode! */ - Cs.lpszClass = lpClassName->Buffer; + Cs.lpszName = (LPCWSTR) WindowName; + Cs.lpszClass = (LPCWSTR) ClassName; Cs.dwExStyle = dwExStyle; CbtCreate.lpcs = &Cs; CbtCreate.hwndInsertAfter = HWND_TOP; @@ -1834,9 +1836,9 @@ NtUserCreateWindowEx(DWORD dwExStyle, Cs.x = Pos.x; Cs.y = Pos.y; - DPRINT("[win32k.window] NtUserCreateWindowEx style %d, exstyle %d, parent %d\n", Cs.style, Cs.dwExStyle, Cs.hwndParent); - DPRINT("NtUserCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight); - DPRINT("NtUserCreateWindowEx(): About to send NCCREATE message.\n"); + DPRINT("[win32k.window] IntCreateWindowEx style %d, exstyle %d, parent %d\n", Cs.style, Cs.dwExStyle, Cs.hwndParent); + DPRINT("IntCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight); + DPRINT("IntCreateWindowEx(): About to send NCCREATE message.\n"); Result = IntSendMessage(WindowObject->Self, WM_NCCREATE, 0, (LPARAM) &Cs); if (!Result) { @@ -1845,14 +1847,14 @@ NtUserCreateWindowEx(DWORD dwExStyle, { IntReleaseWindowObject(ParentWindow); } - DPRINT("NtUserCreateWindowEx(): NCCREATE message failed.\n"); + DPRINT("IntCreateWindowEx(): NCCREATE message failed.\n"); return((HWND)0); } /* Calculate the non-client size. */ MaxPos.x = WindowObject->WindowRect.left; MaxPos.y = WindowObject->WindowRect.top; - DPRINT("NtUserCreateWindowEx(): About to get non-client size.\n"); + DPRINT("IntCreateWindowEx(): About to get non-client size.\n"); /* WinPosGetNonClientSize SENDS THE WM_NCCALCSIZE message */ Result = WinPosGetNonClientSize(WindowObject->Self, &WindowObject->WindowRect, @@ -1909,7 +1911,7 @@ NtUserCreateWindowEx(DWORD dwExStyle, } /* Send the WM_CREATE message. */ - DPRINT("NtUserCreateWindowEx(): about to send CREATE message.\n"); + DPRINT("IntCreateWindowEx(): about to send CREATE message.\n"); Result = IntSendMessage(WindowObject->Self, WM_CREATE, 0, (LPARAM) &Cs); if (Result == (LRESULT)-1) { @@ -1919,7 +1921,7 @@ NtUserCreateWindowEx(DWORD dwExStyle, IntReleaseWindowObject(ParentWindow); } ClassDereferenceObject(ClassObject); - DPRINT("NtUserCreateWindowEx(): send CREATE message failed.\n"); + DPRINT("IntCreateWindowEx(): send CREATE message failed.\n"); return((HWND)0); } @@ -1928,7 +1930,7 @@ NtUserCreateWindowEx(DWORD dwExStyle, { LONG lParam; - DPRINT("NtUserCreateWindow(): About to send WM_SIZE\n"); + DPRINT("IntCreateWindow(): About to send WM_SIZE\n"); if ((WindowObject->ClientRect.right - WindowObject->ClientRect.left) < 0 || (WindowObject->ClientRect.bottom - WindowObject->ClientRect.top) < 0) @@ -1941,7 +1943,7 @@ NtUserCreateWindowEx(DWORD dwExStyle, IntSendMessage(WindowObject->Self, WM_SIZE, SIZE_RESTORED, lParam); - DPRINT("NtUserCreateWindow(): About to send WM_MOVE\n"); + DPRINT("IntCreateWindow(): About to send WM_MOVE\n"); if (0 != (WindowObject->Style & WS_CHILD) && ParentWindow) { @@ -1969,7 +1971,7 @@ NtUserCreateWindowEx(DWORD dwExStyle, ((WindowObject->Style & WS_CHILD) || NtUserGetActiveWindow()) ? SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED : SWP_NOZORDER | SWP_FRAMECHANGED; - DPRINT("NtUserCreateWindow(): About to minimize/maximize\n"); + DPRINT("IntCreateWindow(): About to minimize/maximize\n"); DPRINT("%d,%d %dx%d\n", NewPos.left, NewPos.top, NewPos.right, NewPos.bottom); WinPosSetWindowPos(WindowObject->Self, 0, NewPos.left, NewPos.top, NewPos.right, NewPos.bottom, SwFlag); @@ -1979,7 +1981,7 @@ NtUserCreateWindowEx(DWORD dwExStyle, if ((WindowObject->Style & WS_CHILD) && (!(WindowObject->ExStyle & WS_EX_NOPARENTNOTIFY)) && ParentWindow) { - DPRINT("NtUserCreateWindow(): About to notify parent\n"); + DPRINT("IntCreateWindow(): About to notify parent\n"); IntSendMessage(ParentWindow->Self, WM_PARENTNOTIFY, MAKEWPARAM(WM_CREATE, WindowObject->IDMenu), @@ -2003,15 +2005,85 @@ NtUserCreateWindowEx(DWORD dwExStyle, if (dwStyle & WS_VISIBLE) { - DPRINT("NtUserCreateWindow(): About to show window\n"); + DPRINT("IntCreateWindow(): About to show window\n"); WinPosShowWindow(WindowObject->Self, dwShowMode); } - DPRINT("NtUserCreateWindow(): = %X\n", Handle); + DPRINT("IntCreateWindow(): = %X\n", Handle); DPRINT("WindowObject->SystemMenu = 0x%x\n", WindowObject->SystemMenu); return((HWND)Handle); } +HWND STDCALL +NtUserCreateWindowEx(DWORD dwExStyle, + PUNICODE_STRING UnsafeClassName, + PUNICODE_STRING UnsafeWindowName, + DWORD dwStyle, + LONG x, + LONG y, + LONG nWidth, + LONG nHeight, + HWND hWndParent, + HMENU hMenu, + HINSTANCE hInstance, + LPVOID lpParam, + DWORD dwShowMode, + BOOL bUnicodeWindow) +{ + NTSTATUS Status; + UNICODE_STRING WindowName; + UNICODE_STRING ClassName; + HWND NewWindow; + + DPRINT("NtUserCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight); + + /* Get the class name (string or atom) */ + Status = MmCopyFromCaller(&ClassName, UnsafeClassName, sizeof(UNICODE_STRING)); + if (! NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return NULL; + } + if (! IS_ATOM(ClassName.Buffer)) + { + Status = IntSafeCopyUnicodeString(&ClassName, UnsafeClassName); + if (! NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return NULL; + } + } + + /* safely copy the window name */ + if (NULL != UnsafeWindowName) + { + Status = IntSafeCopyUnicodeString(&WindowName, UnsafeWindowName); + if (! NT_SUCCESS(Status)) + { + if (! IS_ATOM(ClassName.Buffer)) + { + RtlFreeUnicodeString(&ClassName); + } + SetLastNtError(Status); + return NULL; + } + } + else + { + RtlInitUnicodeString(&WindowName, NULL); + } + + NewWindow = IntCreateWindowEx(dwExStyle, &ClassName, &WindowName, dwStyle, x, y, nWidth, nHeight, + hWndParent, hMenu, hInstance, lpParam, dwShowMode, bUnicodeWindow); + + RtlFreeUnicodeString(&WindowName); + if (! IS_ATOM(ClassName.Buffer)) + { + RtlFreeUnicodeString(&ClassName); + } + + return NewWindow; +} /* * @unimplemented