diff --git a/reactos/dll/win32/user32/misc/desktop.c b/reactos/dll/win32/user32/misc/desktop.c index c02e2a87405..837da4b8fb7 100644 --- a/reactos/dll/win32/user32/misc/desktop.c +++ b/reactos/dll/win32/user32/misc/desktop.c @@ -356,19 +356,35 @@ CreateDesktopW(LPCWSTR lpszDesktop, ACCESS_MASK dwDesiredAccess, LPSECURITY_ATTRIBUTES lpsa) { - UNICODE_STRING DesktopName; + OBJECT_ATTRIBUTES oas; + UNICODE_STRING DesktopName, DesktopDevice; HWINSTA hWinSta; HDESK hDesktop; + ULONG Attributes = (OBJ_OPENIF|OBJ_CASE_INSENSITIVE); + /* Retrive WinStation handle. */ hWinSta = NtUserGetProcessWindowStation(); + /* Initialize the strings. */ RtlInitUnicodeString(&DesktopName, lpszDesktop); + RtlInitUnicodeString(&DesktopDevice, lpszDevice); - hDesktop = NtUserCreateDesktop(&DesktopName, - dwFlags, - dwDesiredAccess, - lpsa, - hWinSta); + /* Check for process is inherited, set flag if set. */ + if (lpsa && lpsa->bInheritHandle) Attributes |= OBJ_INHERIT; + + /* Initialize the attributes for the desktop. */ + InitializeObjectAttributes( &oas, + &DesktopName, + Attributes, + hWinSta, + lpsa ? lpsa->lpSecurityDescriptor : NULL); + + /* Send the request and call to win32k. */ + hDesktop = NtUserCreateDesktop( &oas, + &DesktopDevice, + pDevmode, + dwFlags, + dwDesiredAccess); return(hDesktop); } diff --git a/reactos/dll/win32/user32/windows/defwnd.c b/reactos/dll/win32/user32/windows/defwnd.c index 8c41edfee22..8520c5284a1 100644 --- a/reactos/dll/win32/user32/windows/defwnd.c +++ b/reactos/dll/win32/user32/windows/defwnd.c @@ -670,8 +670,9 @@ DefWndDoSizeMove(HWND hwnd, WORD wParam) //#if 0 // if (ISITHOOKED(WH_CBT)) { - if (NtUserMessageCall( hwnd, WM_CBT, HCBT_MOVESIZE, (LPARAM)&sizingRect, 0, FNID_DEFWINDOWPROC, FALSE)) - moved = FALSE; + LRESULT lResult; + NtUserMessageCall( hwnd, WM_CBT, HCBT_MOVESIZE, (LPARAM)&sizingRect, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE); + if (lResult) moved = FALSE; } //#endif (void)NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE, NULL); @@ -758,8 +759,9 @@ DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) //#if 0 // if (ISITHOOKED(WH_CBT)) { - if (NtUserMessageCall( hWnd, WM_SYSCOMMAND, wParam, lParam, 0, FNID_DEFWINDOWPROC, FALSE)) - return 0; + LRESULT lResult; + NtUserMessageCall( hWnd, WM_SYSCOMMAND, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE); + if (lResult) return 0; } //#endif switch (wParam & 0xfff0) diff --git a/reactos/dll/win32/user32/windows/hook.c b/reactos/dll/win32/user32/windows/hook.c index aae11431709..d4ca13e28c7 100644 --- a/reactos/dll/win32/user32/windows/hook.c +++ b/reactos/dll/win32/user32/windows/hook.c @@ -219,13 +219,13 @@ CallNextHookEx( { PCWPSTRUCT pCWP = (PCWPSTRUCT)lParam; - lResult = NtUserMessageCall( pCWP->hwnd, - pCWP->message, - pCWP->wParam, - pCWP->lParam, - 0, - FNID_CALLWNDPROC, - pHook->Ansi); + NtUserMessageCall( pCWP->hwnd, + pCWP->message, + pCWP->wParam, + pCWP->lParam, + (ULONG_PTR)&lResult, + FNID_CALLWNDPROC, + pHook->Ansi); } else { @@ -233,13 +233,13 @@ CallNextHookEx( ClientInfo->dwHookData = pCWPR->lResult; - lResult = NtUserMessageCall( pCWPR->hwnd, - pCWPR->message, - pCWPR->wParam, - pCWPR->lParam, - 0, - FNID_CALLWNDPROCRET, - pHook->Ansi); + NtUserMessageCall( pCWPR->hwnd, + pCWPR->message, + pCWPR->wParam, + pCWPR->lParam, + (ULONG_PTR)&lResult, + FNID_CALLWNDPROCRET, + pHook->Ansi); } ClientInfo->CI_flags ^= ((ClientInfo->CI_flags ^ Flags) & CI_CURTHPRHOOK); ClientInfo->dwHookData = Save; @@ -429,8 +429,9 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength) Common = (PHOOKPROC_CALLBACK_ARGUMENTS) Arguments; switch(Common->HookId) - { + { case WH_CBT: + { switch(Common->Code) { case HCBT_CREATEWND: @@ -494,7 +495,6 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength) { ERR("Common = 0x%x, Proc = 0x%x\n",Common,Common->Proc); } - switch(Common->Code) { case HCBT_CREATEWND: @@ -502,6 +502,7 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength) break; } break; + } case WH_KEYBOARD_LL: KeyboardLlData = (PKBDLLHOOKSTRUCT)((PCHAR) Common + Common->lParam); Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) KeyboardLlData); @@ -536,7 +537,7 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength) break; default: return ZwCallbackReturn(NULL, 0, STATUS_NOT_SUPPORTED); - } + } return ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS); } @@ -547,15 +548,15 @@ User32CallEventProcFromKernel(PVOID Arguments, ULONG ArgumentLength) PEVENTPROC_CALLBACK_ARGUMENTS Common; Common = (PEVENTPROC_CALLBACK_ARGUMENTS) Arguments; - + Common->Proc(Common->hook, - Common->event, + Common->event, Common->hwnd, - Common->idObject, - Common->idChild, - Common->dwEventThread, - Common->dwmsEventTime); - + Common->idObject, + Common->idChild, + Common->dwEventThread, + Common->dwmsEventTime); + return ZwCallbackReturn(NULL, 0, STATUS_SUCCESS); } diff --git a/reactos/dll/win32/user32/windows/message.c b/reactos/dll/win32/user32/windows/message.c index 22dbb133df0..3f9db51bb1e 100644 --- a/reactos/dll/win32/user32/windows/message.c +++ b/reactos/dll/win32/user32/windows/message.c @@ -1700,6 +1700,74 @@ PostMessageW( return Result; } +BOOL +WINAPI +PostMessageWX( + HWND hWnd, + UINT Msg, + WPARAM wParam, + LPARAM lParam) +{ + LRESULT Ret; + + /* Check for combo box or a list box to send names. */ + if (Msg == CB_DIR || Msg == LB_DIR) + { + /* + Set DDL_POSTMSGS, so use the PostMessage function to send messages to the + combo/list box. Forces a call like DlgDirListComboBox. + */ + wParam |= DDL_POSTMSGS; + return NtUserPostMessage(hWnd, Msg, wParam, lParam); + } + + /* No drop files or current Process, just post message. */ + if ( (Msg != WM_DROPFILES) || + ( NtUserQueryWindow( hWnd, QUERY_WINDOW_UNIQUE_PROCESS_ID) == + PtrToUint(NtCurrentTeb()->ClientId.UniqueProcess) ) ) + { + return NtUserPostMessage(hWnd, Msg, wParam, lParam); + } + + /* We have drop files or this is not the same process for this window. */ + + /* Just incase, check wParam for Global memory handle and send size. */ + Ret = SendMessageW( hWnd, + WM_COPYGLOBALDATA, + (WPARAM)GlobalSize((HGLOBAL)wParam), // Zero if not a handle. + (LPARAM)wParam); // Send wParam as lParam. + + if ( Ret ) return NtUserPostMessage(hWnd, Msg, (WPARAM)Ret, lParam); + + return FALSE; +} +BOOL +WINAPI +PostMessageAX( + HWND hWnd, + UINT Msg, + WPARAM wParam, + LPARAM lParam) +{ + MSG AnsiMsg, UcMsg; + BOOL Ret; + + AnsiMsg.hwnd = hWnd; + AnsiMsg.message = Msg; + AnsiMsg.wParam = wParam; + AnsiMsg.lParam = lParam; + + if (!MsgiAnsiToUnicodeMessage(&UcMsg, &AnsiMsg)) + { + return FALSE; + } + + Ret = PostMessageWX( hWnd, UcMsg.message, UcMsg.wParam, UcMsg.lParam); + + MsgiAnsiToUnicodeCleanup(&UcMsg, &AnsiMsg); + + return Ret; +} /* * @implemented @@ -2113,6 +2181,43 @@ SendNotifyMessageW( return Result; } +BOOL +WINAPI +SendNotifyMessageAX( + HWND hWnd, + UINT Msg, + WPARAM wParam, + LPARAM lParam) +{ + BOOL Ret; + MSG AnsiMsg, UcMsg; + + AnsiMsg.hwnd = hWnd; + AnsiMsg.message = Msg; + AnsiMsg.wParam = wParam; + AnsiMsg.lParam = lParam; + if (! MsgiAnsiToUnicodeMessage(&UcMsg, &AnsiMsg)) + { + return FALSE; + } + /* ATM, ReactOS does not support Ansi in win32k. */ + Ret = NtUserMessageCall(hWnd, UcMsg.message, UcMsg.wParam, UcMsg.lParam, 0, FNID_SENDNOTIFYMESSAGE, FALSE); + + MsgiAnsiToUnicodeCleanup(&UcMsg, &AnsiMsg); + + return Ret; +} + +BOOL +WINAPI +SendNotifyMessageWX( + HWND hWnd, + UINT Msg, + WPARAM wParam, + LPARAM lParam) +{ + return NtUserMessageCall(hWnd, Msg, wParam, lParam, 0, FNID_SENDNOTIFYMESSAGE, FALSE); +} /* * @implemented diff --git a/reactos/include/reactos/win32k/callback.h b/reactos/include/reactos/win32k/callback.h index d0f12a36821..b28d7355716 100644 --- a/reactos/include/reactos/win32k/callback.h +++ b/reactos/include/reactos/win32k/callback.h @@ -61,9 +61,6 @@ typedef struct _EVENTPROC_CALLBACK_ARGUMENTS DWORD dwEventThread; DWORD dwmsEventTime; WINEVENTPROC Proc; - BOOLEAN Ansi; - UINT ModuleNameLength; - WCHAR ModuleName[1]; } EVENTPROC_CALLBACK_ARGUMENTS, *PEVENTPROC_CALLBACK_ARGUMENTS; NTSTATUS WINAPI diff --git a/reactos/include/reactos/win32k/ntuser.h b/reactos/include/reactos/win32k/ntuser.h index 0ec3e16e361..d177d165a7f 100644 --- a/reactos/include/reactos/win32k/ntuser.h +++ b/reactos/include/reactos/win32k/ntuser.h @@ -268,6 +268,8 @@ typedef LONG_PTR (NTAPI *PFN_FNID)(struct _WND*, UINT, WPARAM, LPARAM, ULONG_PTR #define FNID_IME 0x02A9 #define FNID_CALLWNDPROC 0x02AA #define FNID_CALLWNDPROCRET 0x02AB +#define FNID_HKINLPCWPEXSTRUCT 0x02AC +#define FNID_HKINLPCWPRETEXSTRUCT 0x02AD #define FNID_SENDMESSAGE 0x02B0 // Kernel has option to use TimeOut or normal msg send, based on type of msg. #define FNID_SENDMESSAGEWTOOPTION 0x02B1 @@ -308,8 +310,15 @@ typedef LONG_PTR (NTAPI *PFN_FNID)(struct _WND*, UINT, WPARAM, LPARAM, ULONG_PTR #define ICLS_SWITCH 19 #define ICLS_ICONTITLE 20 #define ICLS_TOOLTIPS 21 +#if (_WIN32_WINNT <= 0x0501) #define ICLS_UNKNOWN 22 #define ICLS_NOTUSED 23 +#else +#define ICLS_SYSSHADOW 22 +#define ICLS_HWNDMESSAGE 23 +#define ICLS_UNKNOWN 24 +#define ICLS_NOTUSED 25 +#endif #define ICLS_END 31 #define COLOR_LAST COLOR_MENUBAR @@ -327,7 +336,7 @@ typedef struct tagOEMBITMAPINFO typedef struct tagMBSTRING { - WCHAR szName[15]; + WCHAR szName[16]; UINT uID; UINT uStr; } MBSTRING, *PMBSTRING; @@ -389,8 +398,8 @@ typedef struct tagSERVERINFO DWORD dwSRVIFlags; ULONG_PTR cHandleEntries; PFN_FNID mpFnidPfn[FNID_NUM]; -// WNDPROC aStoCidPfn[7]; -// USHORT mpFnid_serverCBWndProc[31]; + WNDPROC aStoCidPfn[7]; + USHORT mpFnid_serverCBWndProc[FNID_NUM]; PFNCLIENT apfnClientA; PFNCLIENT apfnClientW; PFNCLIENTWORKER apfnClientWorker; @@ -553,6 +562,7 @@ typedef struct _USERCONNECT // // Non SDK Window Message types. // +#define WM_COPYGLOBALDATA 73 #define WM_SYSTIMER 280 #define WM_POPUPSYSTEMMENU 787 #define WM_CBT 1023 // ReactOS only. @@ -1072,6 +1082,18 @@ NtUserChangeDisplaySettings( DWORD dwflags, LPVOID lParam); +BOOL +NTAPI +NtUserCheckDesktopByThreadId( + DWORD dwThreadId); + +BOOL +NTAPI +NtUserCheckWindowThreadDesktop( + HWND hwnd, + DWORD dwThreadId, + ULONG ReturnValue); + DWORD NTAPI NtUserCheckImeHotKey( @@ -1145,11 +1167,11 @@ NtUserCreateCaret( HDESK NTAPI NtUserCreateDesktop( - PUNICODE_STRING lpszDesktopName, + POBJECT_ATTRIBUTES poa, + PUNICODE_STRING lpszDesktopDevice, + LPDEVMODEW lpdmw, DWORD dwFlags, - ACCESS_MASK dwDesiredAccess, - LPSECURITY_ATTRIBUTES lpSecurity, - HWINSTA hWindowStation); + ACCESS_MASK dwDesiredAccess); DWORD NTAPI @@ -1936,7 +1958,7 @@ NtUserMapVirtualKeyEx( UINT keyCode, UINT transType, DWORD keyboardId, HKL dwhkl ); -LRESULT +BOOL NTAPI NtUserMessageCall( HWND hWnd, diff --git a/reactos/subsystems/win32/win32k/include/desktop.h b/reactos/subsystems/win32/win32k/include/desktop.h index a5b6962dbf0..8b7d15a3a95 100644 --- a/reactos/subsystems/win32/win32k/include/desktop.h +++ b/reactos/subsystems/win32/win32k/include/desktop.h @@ -28,6 +28,7 @@ typedef struct _DESKTOP PWIN32HEAP pheapDesktop; PSECTION_OBJECT DesktopHeapSection; PDESKTOPINFO DesktopInfo; + HWND spwndMessage; } DESKTOP, *PDESKTOP; extern PDESKTOP InputDesktop; @@ -134,6 +135,7 @@ VOID co_IntShellHookNotify(WPARAM Message, LPARAM lParam); &(OBJECT_HEADER_TO_NAME_INFO(OBJECT_TO_OBJECT_HEADER(d))->Name) : \ NULL +HWND FASTCALL IntGetMessageWindow(VOID); static __inline PVOID DesktopHeapAlloc(IN PDESKTOP Desktop, diff --git a/reactos/subsystems/win32/win32k/include/hook.h b/reactos/subsystems/win32/win32k/include/hook.h index 21ef8803444..9f71f25505d 100644 --- a/reactos/subsystems/win32/win32k/include/hook.h +++ b/reactos/subsystems/win32/win32k/include/hook.h @@ -36,8 +36,9 @@ typedef struct tagEVENTHOOK DWORD idProcess; DWORD idThread; WINEVENTPROC Proc; /* Event function */ - BOOLEAN Ansi; /* Is it an Ansi event? */ ULONG Flags; /* Some internal flags */ + ULONG_PTR offPfn; + INT ihmod; UNICODE_STRING ModuleName; /* Module name for global events */ } EVENTHOOK, *PEVENTHOOK; diff --git a/reactos/subsystems/win32/win32k/include/window.h b/reactos/subsystems/win32/win32k/include/window.h index 223d0c4972f..5745825150c 100644 --- a/reactos/subsystems/win32/win32k/include/window.h +++ b/reactos/subsystems/win32/win32k/include/window.h @@ -13,6 +13,8 @@ typedef struct _WINDOW_OBJECT *PWINDOW_OBJECT; #include #include +extern ATOM AtomMessage; + BOOL FASTCALL UserUpdateUiState(PWINDOW Wnd, WPARAM wParam); typedef struct _WINDOW_OBJECT @@ -167,8 +169,9 @@ IntShowOwnedPopups( PWINDOW_OBJECT owner, BOOL fShow ); LRESULT FASTCALL IntDefWindowProc( PWINDOW_OBJECT Window, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL Ansi); -VOID FASTCALL IntNotifyWinEvent(DWORD, PWINDOW_OBJECT, LONG, LONG); +VOID FASTCALL IntNotifyWinEvent(DWORD, HWND, LONG, LONG); +HWND APIENTRY co_IntCreateWindowEx(DWORD,PUNICODE_STRING,PUNICODE_STRING,DWORD,LONG,LONG,LONG,LONG,HWND,HMENU,HINSTANCE,LPVOID,DWORD,BOOL); #endif /* _WIN32K_WINDOW_H */ /* EOF */ diff --git a/reactos/subsystems/win32/win32k/ntuser/callback.c b/reactos/subsystems/win32/win32k/ntuser/callback.c index cb522d0f01c..d32a047ed1f 100644 --- a/reactos/subsystems/win32/win32k/ntuser/callback.c +++ b/reactos/subsystems/win32/win32k/ntuser/callback.c @@ -605,6 +605,9 @@ co_IntCallHookProc(INT HookId, return Result; } +// +// Events are notifications w/o results. +// LRESULT APIENTRY co_IntCallEventProc(HWINEVENTHOOK hook, @@ -616,11 +619,11 @@ co_IntCallEventProc(HWINEVENTHOOK hook, DWORD dwmsEventTime, WINEVENTPROC Proc) { - LRESULT Result; + LRESULT Result = 0; NTSTATUS Status; PEVENTPROC_CALLBACK_ARGUMENTS Common; ULONG ArgumentLength, ResultLength; - PVOID Argument, ResultPointer, pWnd; + PVOID Argument, ResultPointer; ArgumentLength = sizeof(EVENTPROC_CALLBACK_ARGUMENTS); @@ -643,8 +646,6 @@ co_IntCallEventProc(HWINEVENTHOOK hook, ResultPointer = NULL; ResultLength = sizeof(LRESULT); - IntSetTebWndCallback (&hWnd, &pWnd); - UserLeaveCo(); Status = KeUserModeCallback(USER32_CALLBACK_EVENTPROC, @@ -653,13 +654,8 @@ co_IntCallEventProc(HWINEVENTHOOK hook, &ResultPointer, &ResultLength); - /* Simulate old behaviour: copy into our local buffer */ - Result = *(LRESULT*)ResultPointer; - UserEnterCo(); - IntRestoreTebWndCallback (hWnd, pWnd); - IntCbFreeMemory(Argument); if (!NT_SUCCESS(Status)) diff --git a/reactos/subsystems/win32/win32k/ntuser/desktop.c b/reactos/subsystems/win32/win32k/ntuser/desktop.c index 312f42a838b..bdaadf71feb 100644 --- a/reactos/subsystems/win32/win32k/ntuser/desktop.c +++ b/reactos/subsystems/win32/win32k/ntuser/desktop.c @@ -556,6 +556,17 @@ PWINDOW_OBJECT FASTCALL UserGetDesktopWindow(VOID) return UserGetWindowObject(pdo->DesktopWindow); } +HWND FASTCALL IntGetMessageWindow(VOID) +{ + PDESKTOP pdo = IntGetActiveDesktop(); + + if (!pdo) + { + DPRINT("No active desktop\n"); + return NULL; + } + return pdo->spwndMessage; +} HWND FASTCALL IntGetCurrentThreadDesktopWindow(VOID) { @@ -829,8 +840,14 @@ IntFreeDesktopHeap(IN OUT PDESKTOP Desktop) * Creates a new desktop. * * Parameters - * lpszDesktopName - * Name of the new desktop. + * poaAttribs + * Object Attributes. + * + * lpszDesktopDevice + * Name of the device. + * + * pDeviceMode + * Device Mode. * * dwFlags * Interaction flags. @@ -838,11 +855,6 @@ IntFreeDesktopHeap(IN OUT PDESKTOP Desktop) * dwDesiredAccess * Requested type of access. * - * lpSecurity - * Security descriptor. - * - * hWindowStation - * Handle to window station on which to create the desktop. * * Return Value * If the function succeeds, the return value is a handle to the newly @@ -857,17 +869,19 @@ IntFreeDesktopHeap(IN OUT PDESKTOP Desktop) HDESK APIENTRY NtUserCreateDesktop( - PUNICODE_STRING lpszDesktopName, + POBJECT_ATTRIBUTES poa, + PUNICODE_STRING lpszDesktopDevice, + LPDEVMODEW lpdmw, DWORD dwFlags, - ACCESS_MASK dwDesiredAccess, - LPSECURITY_ATTRIBUTES lpSecurity, - HWINSTA hWindowStation) + ACCESS_MASK dwDesiredAccess) { OBJECT_ATTRIBUTES ObjectAttributes; + PTHREADINFO W32Thread; +// HWND hwndMessage; PWINSTATION_OBJECT WinStaObject; PDESKTOP DesktopObject; UNICODE_STRING DesktopName; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; HDESK Desktop; CSR_API_MESSAGE Request; PVOID DesktopHeapSystemBase = NULL; @@ -875,12 +889,36 @@ NtUserCreateDesktop( UNICODE_STRING SafeDesktopName; ULONG DummyContext; ULONG_PTR HeapSize = 4 * 1024 * 1024; /* FIXME */ + HWINSTA hWindowStation = NULL ; + PUNICODE_STRING lpszDesktopName = NULL; +// UNICODE_STRING AtomName; DECLARE_RETURN(HDESK); - DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName); UserEnterExclusive(); + _SEH2_TRY + { + ProbeForRead( poa, + sizeof(OBJECT_ATTRIBUTES), + 1); + + hWindowStation = poa->RootDirectory; + lpszDesktopName = poa->ObjectName; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status =_SEH2_GetExceptionCode(); + } + _SEH2_END + + if (! NT_SUCCESS(Status)) + { + DPRINT1("Failed reading Object Attributes from user space.\n"); + SetLastNtError(Status); + RETURN( NULL); + } + Status = IntValidateWindowStationHandle( hWindowStation, KernelMode, @@ -1037,6 +1075,52 @@ NtUserCreateDesktop( RETURN( NULL); } + W32Thread = PsGetCurrentThreadWin32Thread(); + + if (!W32Thread->Desktop) IntSetThreadDesktop(DesktopObject,FALSE); + +#if 0 + /* + Based on wine/server/window.c line 1804 in get_desktop_window. + We create an atom to be used for create desktop to create + the message window. + */ + // FIXME! + // ReactOS CreateWindow does not know how to correctly use Atom Classes. + // So we have this HAX! + { // Warning! HACK! Yes it is very wrong! + + // Normally, this would have been performed during the win32k init phase. + // AtomMessage = IntAddGlobalAtom(L"Message", TRUE); // <- correct, but should be in ntuser.c + + AtomMessage = + } + AtomName.Buffer = ((PWSTR)((ULONG_PTR)(WORD)(AtomMessage))); + AtomName.Length = 0; + + hwndMessage = co_IntCreateWindowEx( 0, + &AtomName, + NULL, + (WS_POPUP|WS_CLIPCHILDREN), + 0, + 0, + 100, + 100, + NULL, + NULL, + NULL,//hModuleWin, // pi->hModUser; ? no! + NULL, + 0, + TRUE); + if (!hwndMessage) + { + DPRINT1("Failed to create Message window handle\n"); + } + else + { + DesktopObject->spwndMessage = hwndMessage; + } +#endif RETURN( Desktop); CLEANUP: diff --git a/reactos/subsystems/win32/win32k/ntuser/event.c b/reactos/subsystems/win32/win32k/ntuser/event.c index eb1c01a16e3..0b85dded343 100644 --- a/reactos/subsystems/win32/win32k/ntuser/event.c +++ b/reactos/subsystems/win32/win32k/ntuser/event.c @@ -165,14 +165,14 @@ VOID FASTCALL IntNotifyWinEvent( DWORD Event, - PWINDOW_OBJECT Window, + HWND hWnd, LONG idObject, LONG idChild) { PEVENTHOOK pEH; LRESULT Result; - if (!GlobalEvents->Counts) return; + if (!GlobalEvents || !GlobalEvents->Counts) return; pEH = (PEVENTHOOK)GlobalEvents->Events.Flink; @@ -187,7 +187,7 @@ IntNotifyWinEvent( if (!(pEH->idProcess) || !(pEH->idThread) || (NtCurrentTeb()->ClientId.UniqueProcess == (PVOID)pEH->idProcess)) { - Result = IntCallLowLevelEvent(pEH, Event, Window->hSelf, idObject, idChild); + Result = IntCallLowLevelEvent(pEH, Event, hWnd, idObject, idChild); } }// if ^skip own thread && ((Pid && CPid == Pid && ^skip own process) || all process) else if ( !(pEH->Flags & WINEVENT_SKIPOWNTHREAD) && @@ -198,7 +198,7 @@ IntNotifyWinEvent( { Result = co_IntCallEventProc( pEH->Self, Event, - Window->hSelf, + hWnd, idObject, idChild, PtrToUint(NtCurrentTeb()->ClientId.UniqueThread), @@ -234,7 +234,7 @@ NtUserNotifyWinEvent( if (gpsi->dwInstalledEventHooks & GetMaskFromEvent(Event)) { UserRefObjectCo(Window, &Ref); - IntNotifyWinEvent( Event, Window, idObject, idChild); + IntNotifyWinEvent( Event, Window->hSelf, idObject, idChild); UserDerefObjectCo(Window); } UserLeave(); @@ -259,6 +259,8 @@ NtUserSetWinEventHook( HANDLE Handle; PETHREAD Thread = NULL; + DPRINT("NtUserSetWinEventHook hmod 0x%x, pfn 0x%x\n",hmodWinEventProc, lpfnWinEventProc); + UserEnterExclusive(); if ( !GlobalEvents ) @@ -316,7 +318,6 @@ NtUserSetWinEventHook( pEH->eventMax = eventMax; pEH->idProcess = idProcess; pEH->idThread = idThread; - pEH->Ansi = FALSE; pEH->Flags = dwflags; @@ -363,7 +364,9 @@ NtUserSetWinEventHook( pEH->ModuleName.Length = ModuleName.Length; - pEH->Proc = (void *)((char *)lpfnWinEventProc - (char *)hmodWinEventProc); + pEH->offPfn = (ULONG_PTR)((char *)lpfnWinEventProc - (char *)hmodWinEventProc); + pEH->ihmod = (INT)hmodWinEventProc; + pEH->Proc = lpfnWinEventProc; } else pEH->Proc = lpfnWinEventProc; diff --git a/reactos/subsystems/win32/win32k/ntuser/message.c b/reactos/subsystems/win32/win32k/ntuser/message.c index 147a250f82f..e888f34f853 100644 --- a/reactos/subsystems/win32/win32k/ntuser/message.c +++ b/reactos/subsystems/win32/win32k/ntuser/message.c @@ -156,6 +156,10 @@ MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam) Size = sizeof(COPYDATASTRUCT) + ((PCOPYDATASTRUCT)lParam)->cbData; break; + case WM_COPYGLOBALDATA: + Size = wParam; + break; + default: assert(FALSE); Size = 0; @@ -2023,7 +2027,7 @@ IntUninitMessagePumpHook() } -LRESULT APIENTRY +BOOL APIENTRY NtUserMessageCall( HWND hWnd, UINT Msg, @@ -2034,6 +2038,8 @@ NtUserMessageCall( BOOL Ansi) { LRESULT lResult = 0; + BOOL Ret = FALSE; + BOOL BadChk = FALSE; PWINDOW_OBJECT Window = NULL; USER_REFERENCE_ENTRY Ref; @@ -2043,21 +2049,23 @@ NtUserMessageCall( if (hWnd && (hWnd != INVALID_HANDLE_VALUE) && !(Window = UserGetWindowObject(hWnd))) { UserLeave(); - return 0; + return FALSE; } switch(dwType) { case FNID_DEFWINDOWPROC: UserRefObjectCo(Window, &Ref); lResult = IntDefWindowProc(Window, Msg, wParam, lParam, Ansi); + Ret = TRUE; UserDerefObjectCo(Window); break; + case FNID_SENDNOTIFYMESSAGE: + Ret = UserSendNotifyMessage(hWnd, Msg, wParam, lParam); + break; case FNID_BROADCASTSYSTEMMESSAGE: { PBROADCASTPARM parm; - BOOL BadChk = FALSE; DWORD_PTR RetVal = 0; - lResult = -1; if (ResultInfo) { @@ -2119,11 +2127,11 @@ NtUserMessageCall( } else if (parm->flags & BSF_POSTMESSAGE) { - lResult = UserPostMessage(HWND_BROADCAST, Msg, wParam, lParam); + Ret = UserPostMessage(HWND_BROADCAST, Msg, wParam, lParam); } else if ( parm->flags & BSF_SENDNOTIFYMESSAGE) { - lResult = UserSendNotifyMessage(HWND_BROADCAST, Msg, wParam, lParam); + Ret = UserSendNotifyMessage(HWND_BROADCAST, Msg, wParam, lParam); } } } @@ -2189,8 +2197,33 @@ NtUserMessageCall( } break; } + + switch(dwType) + { + case FNID_DEFWINDOWPROC: + case FNID_CALLWNDPROC: + case FNID_CALLWNDPROCRET: + if (ResultInfo) + { + _SEH2_TRY + { + ProbeForWrite((PVOID)ResultInfo, sizeof(LRESULT), 1); + RtlCopyMemory((PVOID)ResultInfo, &lResult, sizeof(LRESULT)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + BadChk = TRUE; + } + _SEH2_END; + } + break; + default: + break; + } + UserLeave(); - return lResult; + + return BadChk ? FALSE : Ret; } #define INFINITE 0xFFFFFFFF diff --git a/reactos/subsystems/win32/win32k/ntuser/ntuser.c b/reactos/subsystems/win32/win32k/ntuser/ntuser.c index 56f88d8be45..d32db11e07e 100644 --- a/reactos/subsystems/win32/win32k/ntuser/ntuser.c +++ b/reactos/subsystems/win32/win32k/ntuser/ntuser.c @@ -34,6 +34,7 @@ #include ERESOURCE UserLock; +ATOM AtomMessage; // Window Message atom. BOOL gbInitialized; BOOL diff --git a/reactos/subsystems/win32/win32k/ntuser/window.c b/reactos/subsystems/win32/win32k/ntuser/window.c index a08f33ef318..cd859f818c1 100644 --- a/reactos/subsystems/win32/win32k/ntuser/window.c +++ b/reactos/subsystems/win32/win32k/ntuser/window.c @@ -393,6 +393,8 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window, IntDeRegisterShellHookWindow(Window->hSelf); + IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Window->hSelf, OBJID_WINDOW, 0); + if(SendMessages) { /* Send destroy messages */ @@ -1552,7 +1554,7 @@ co_IntCreateWindowEx(DWORD dwExStyle, RTL_ATOM ClassAtom; PWINDOW_OBJECT Window = NULL; PWINDOW_OBJECT ParentWindow = NULL, OwnerWindow; - HWND ParentWindowHandle; + HWND ParentWindowHandle = NULL; HWND OwnerWindowHandle; PMENU_OBJECT SystemMenu; HWND hWnd; @@ -1576,7 +1578,12 @@ co_IntCreateWindowEx(DWORD dwExStyle, PTHREADINFO pti; pti = PsGetCurrentThreadWin32Thread(); - ParentWindowHandle = pti->Desktop->DesktopWindow; + + if (pti->Desktop) + { + ParentWindowHandle = pti->Desktop->DesktopWindow; + } + OwnerWindowHandle = NULL; if (hWndParent == HWND_MESSAGE) @@ -1585,8 +1592,8 @@ co_IntCreateWindowEx(DWORD dwExStyle, * native ole32.OleInitialize uses HWND_MESSAGE to create the * message window (style: WS_POPUP|WS_DISABLED) */ - DPRINT("FIXME - Parent is HWND_MESSAGE\n"); - // ParentWindowHandle set already. + DPRINT1("FIXME - Parent is HWND_MESSAGE\n"); + // ParentWindowHandle = IntGetMessageWindow(); } else if (hWndParent) { @@ -1605,16 +1612,16 @@ co_IntCreateWindowEx(DWORD dwExStyle, RETURN( (HWND)0); /* WS_CHILD needs a parent, but WS_POPUP doesn't */ } -// if (NULL != ParentWindowHandle) -// { - ParentWindow = UserGetWindowObject(ParentWindowHandle); + if (ParentWindowHandle) + { + ParentWindow = UserGetWindowObject(ParentWindowHandle); - if (ParentWindow) UserRefObjectCo(ParentWindow, &ParentRef); -// } -// else -// { -// ParentWindow = NULL; -// } + if (ParentWindow) UserRefObjectCo(ParentWindow, &ParentRef); + } + else + { + ParentWindow = NULL; + } /* FIXME: parent must belong to the current process */ @@ -2123,17 +2130,9 @@ AllocErr: IntUnlinkWindow(Window); RETURN((HWND)0); } -#if 0 - Result = IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_WINDOW, 0); - if (Result == (LRESULT)-1) - { - /* FIXME: Cleanup. */ - DPRINT1("IntCreateWindowEx(): event CREATE hook failed. No cleanup performed!\n"); - IntUnlinkWindow(Window); - RETURN((HWND)0); - } -#endif + IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window->hSelf, OBJID_WINDOW, 0); + /* Send move and size messages. */ if (!(Window->Flags & WINDOWOBJECT_NEED_SIZE)) { @@ -2417,6 +2416,12 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window) return FALSE; } + /* Call hooks */ + if (ISITHOOKED(WH_CBT)) + { + if (co_HOOK_CallHooks(WH_CBT, HCBT_DESTROYWND, (WPARAM) hWnd, 0)) return FALSE; + } + /* Look whether the focus is within the tree of windows we will * be destroying. */ @@ -2436,11 +2441,6 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window) Window->MessageQueue->CaptureWindow = NULL; IntDereferenceMessageQueue(Window->MessageQueue); - /* Call hooks */ - if (ISITHOOKED(WH_CBT)) - { - if (co_HOOK_CallHooks(WH_CBT, HCBT_DESTROYWND, (WPARAM) hWnd, 0)) return FALSE; - } IntEngWindowChanged(Window, WOC_DELETE); isChild = (0 != (Wnd->Style & WS_CHILD)); @@ -3225,6 +3225,18 @@ NtUserSetParent(HWND hWndChild, HWND hWndNewParent) DPRINT("Enter NtUserSetParent\n"); UserEnterExclusive(); + /* + Check Parent first from user space, set it here. + */ + if (!hWndNewParent) + { + hWndNewParent = IntGetDesktopWindow(); + } + else if (hWndNewParent == HWND_MESSAGE) + { + // hWndNewParent = IntGetMessageWindow(); + } + RETURN( co_UserSetParent(hWndChild, hWndNewParent)); CLEANUP: