diff --git a/reactos/subsys/win32k/include/menu.h b/reactos/subsys/win32k/include/menu.h index 99655387c55..7220cf74b7c 100644 --- a/reactos/subsys/win32k/include/menu.h +++ b/reactos/subsys/win32k/include/menu.h @@ -32,6 +32,7 @@ typedef struct _MENU_ITEM typedef struct _MENU_OBJECT { HANDLE Self; + PW32PROCESS W32Process; LIST_ENTRY ListEntry; int MenuItemCount; FAST_MUTEX MenuItemsLock; diff --git a/reactos/subsys/win32k/misc/object.c b/reactos/subsys/win32k/misc/object.c index cf67e37dc6b..95b36e9dcf7 100644 --- a/reactos/subsys/win32k/misc/object.c +++ b/reactos/subsys/win32k/misc/object.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: object.c,v 1.7 2003/12/12 14:22:37 gvg Exp $ +/* $Id: object.c,v 1.8 2003/12/17 19:56:13 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -113,7 +113,7 @@ ObmpGetObjectByHandle(PUSER_HANDLE_TABLE HandleTable, Current = Current->Flink; if (Current == &(HandleTable->ListHead)) { - DPRINT1("Invalid handle\n"); + DPRINT1("Invalid handle 0x%x\n", Handle); return NULL; } } @@ -479,7 +479,7 @@ ObmReferenceObjectByHandle(PUSER_HANDLE_TABLE HandleTable, if ((ObjectType != otUnknown) && (ObjectHeader->Type != ObjectType)) { - DPRINT1("Object type mismatch\n"); + DPRINT1("Object type mismatch 0x%x 0x%x\n", ObjectType, ObjectHeader->Type); return STATUS_UNSUCCESSFUL; } diff --git a/reactos/subsys/win32k/ntuser/menu.c b/reactos/subsys/win32k/ntuser/menu.c index bb877120416..3afd111f009 100644 --- a/reactos/subsys/win32k/ntuser/menu.c +++ b/reactos/subsys/win32k/ntuser/menu.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: menu.c,v 1.33 2003/11/23 12:31:53 weiden Exp $ +/* $Id: menu.c,v 1.34 2003/12/17 19:56:13 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -162,11 +162,11 @@ IntFreeMenuItem(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, if(bRecurse && MenuItem->hSubMenu) { PMENU_OBJECT SubMenuObject; - SubMenuObject = (PMENU_OBJECT)IntGetWindowObject( - MenuItem->hSubMenu ); + SubMenuObject = IntGetMenuObject(MenuItem->hSubMenu ); if(SubMenuObject) { IntDestroyMenuObject(SubMenuObject, bRecurse, TRUE); + IntReleaseMenuObject(SubMenuObject); } } @@ -217,14 +217,11 @@ IntDeleteMenuItems(PMENU_OBJECT MenuObject, BOOL bRecurse) } BOOL FASTCALL -IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse, BOOL RemoveFromProcess) +IntDestroyMenuObject(PMENU_OBJECT MenuObject, + BOOL bRecurse, BOOL RemoveFromProcess) { - PW32PROCESS W32Process; - if(MenuObject) { - W32Process = PsGetWin32Process(); - /* remove all menu items */ ExAcquireFastMutexUnsafe (&MenuObject->MenuItemsLock); IntDeleteMenuItems(MenuObject, bRecurse); /* do not destroy submenus */ @@ -232,14 +229,12 @@ IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse, BOOL RemoveFromProc if(RemoveFromProcess) { - ExAcquireFastMutexUnsafe(&W32Process->MenuListLock); + ExAcquireFastMutexUnsafe(&MenuObject->W32Process->MenuListLock); RemoveEntryList(&MenuObject->ListEntry); - ExReleaseFastMutexUnsafe(&W32Process->MenuListLock); + ExReleaseFastMutexUnsafe(&MenuObject->W32Process->MenuListLock); } - IntReleaseMenuObject(MenuObject); // needed? - - ObmCloseHandle(W32Process->WindowStation->HandleTable, MenuObject->Self); + ObmCloseHandle(MenuObject->W32Process->WindowStation->HandleTable, MenuObject->Self); return TRUE; } @@ -261,8 +256,9 @@ IntCreateMenu(PHANDLE Handle) *Handle = 0; return NULL; } - + MenuObject->Self = *Handle; + MenuObject->W32Process = Win32Process; MenuObject->RtoL = FALSE; /* default */ MenuObject->MenuInfo.cbSize = sizeof(MENUINFO); /* not used */ MenuObject->MenuInfo.fMask = 0; /* not used */ @@ -277,9 +273,9 @@ IntCreateMenu(PHANDLE Handle) ExInitializeFastMutex(&MenuObject->MenuItemsLock); /* Insert menu item into process menu handle list */ - ExAcquireFastMutexUnsafe (&Win32Process->MenuListLock); - InsertTailList (&Win32Process->MenuListHead, &MenuObject->ListEntry); - ExReleaseFastMutexUnsafe (&Win32Process->MenuListLock); + ExAcquireFastMutexUnsafe(&Win32Process->MenuListLock); + InsertTailList(&Win32Process->MenuListHead, &MenuObject->ListEntry); + ExReleaseFastMutexUnsafe(&Win32Process->MenuListLock); return MenuObject; } @@ -356,17 +352,19 @@ IntCloneMenu(PMENU_OBJECT Source) { HANDLE Handle; PMENU_OBJECT MenuObject; + PW32PROCESS Process = PsGetWin32Process(); if(!Source) return NULL; MenuObject = (PMENU_OBJECT)ObmCreateObject( - PsGetWin32Process()->WindowStation->HandleTable, Handle, + Process->WindowStation->HandleTable, &Handle, otMenu, sizeof(MENU_OBJECT)); if(!MenuObject) return NULL; MenuObject->Self = Handle; + MenuObject->W32Process = Process; MenuObject->RtoL = Source->RtoL; MenuObject->MenuInfo.cbSize = sizeof(MENUINFO); /* not used */ MenuObject->MenuInfo.fMask = Source->MenuInfo.fMask; @@ -379,6 +377,11 @@ IntCloneMenu(PMENU_OBJECT Source) MenuObject->MenuItemCount = 0; MenuObject->MenuItemList = NULL; ExInitializeFastMutex(&MenuObject->MenuItemsLock); + + /* Insert menu item into process menu handle list */ + ExAcquireFastMutexUnsafe(&Process->MenuListLock); + InsertTailList(&Process->MenuListHead, &MenuObject->ListEntry); + ExReleaseFastMutexUnsafe(&Process->MenuListLock); IntCloneMenuItems(MenuObject, Source); @@ -1033,7 +1036,7 @@ IntCleanupMenus(struct _EPROCESS *Process, PW32PROCESS Win32Process) PEPROCESS CurrentProcess; PLIST_ENTRY LastHead = NULL; PMENU_OBJECT MenuObject; - + CurrentProcess = PsGetCurrentProcess(); if (CurrentProcess != Process) { @@ -1183,7 +1186,7 @@ BOOL STDCALL NtUserDestroyMenu( HMENU hMenu) { - /* FIXME, check if menu belongs to the process */ + BOOL Ret; PMENU_OBJECT MenuObject = IntGetMenuObject(hMenu); if(!MenuObject) @@ -1191,8 +1194,17 @@ NtUserDestroyMenu( SetLastWin32Error(ERROR_INVALID_MENU_HANDLE); return FALSE; } + if(MenuObject->W32Process != PsGetWin32Process()) + { + IntReleaseMenuObject(MenuObject); + SetLastWin32Error(ERROR_ACCESS_DENIED); + return FALSE; + } - return IntDestroyMenuObject(MenuObject, FALSE, TRUE); + Ret = IntDestroyMenuObject(MenuObject, FALSE, TRUE); + + IntReleaseMenuObject(MenuObject); + return Ret; } diff --git a/reactos/subsys/win32k/ntuser/window.c b/reactos/subsys/win32k/ntuser/window.c index 821b8514200..baf838e3234 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.165 2003/12/17 13:11:55 weiden Exp $ +/* $Id: window.c,v 1.166 2003/12/17 19:56:13 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -245,6 +245,56 @@ IntWinListChildren(PWINDOW_OBJECT Window) return (NumChildren > 0) ? List : NULL; } +/*********************************************************************** + * IntSendDestroyMsg + */ +static void IntSendDestroyMsg(HWND Wnd) +{ +#if 0 /* FIXME */ + GUITHREADINFO info; + + if (GetGUIThreadInfo(GetCurrentThreadId(), &info)) + { + if (Wnd == info.hwndCaret) + { + DestroyCaret(); + } + } +#endif + + /* + * Send the WM_DESTROY to the window. + */ + IntSendMessage(Wnd, WM_DESTROY, 0, 0, TRUE); + + /* + * This WM_DESTROY message can trigger re-entrant calls to DestroyWindow + * make sure that the window still exists when we come back. + */ +#if 0 /* FIXME */ + if (IsWindow(Wnd)) + { + HWND* pWndArray; + int i; + + if (!(pWndArray = WIN_ListChildren( hwnd ))) return; + + /* start from the end (FIXME: is this needed?) */ + for (i = 0; pWndArray[i]; i++) ; + + while (--i >= 0) + { + if (IsWindow( pWndArray[i] )) WIN_SendDestroyMsg( pWndArray[i] ); + } + HeapFree(GetProcessHeap(), 0, pWndArray); + } + else + { + DPRINT("destroyed itself while in WM_DESTROY!\n"); + } +#endif +} + /*********************************************************************** * IntDestroyWindow * @@ -258,12 +308,18 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window, HWND *Children; HWND *ChildHandle; PWINDOW_OBJECT Child; - + PMENU_OBJECT Menu; + if (! IntWndBelongsToThread(Window, ThreadData)) { - DPRINT1("Window doesn't belong to current thread\n"); return 0; } + + if(SendMessages) + { + /* Send destroy messages */ + IntSendDestroyMsg(Window->Self); + } /* free child windows */ Children = IntWinListChildren(Window); @@ -274,10 +330,15 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window, Child = IntGetProcessWindowObject(ProcessData, *ChildHandle); if (NULL != Child) { - if (IntWndBelongsToThread(Child, ThreadData)) - IntDestroyWindow(Child, ProcessData, ThreadData, SendMessages); + if(IntWndBelongsToThread(Child, ThreadData)) + { + IntDestroyWindow(Child, ProcessData, ThreadData, SendMessages); + } else - IntSendMessage(Child->Self, WM_DESTROY, 0, 0, TRUE); + { + IntSendDestroyMsg(Child->Self); + IntDestroyWindow(Child, ProcessData, Child->OwnerThread->Win32Thread, FALSE); + } IntReleaseWindowObject(Child); } } @@ -285,7 +346,7 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window, } if (SendMessages) - { + { /* * Clear the update region to make sure no WM_PAINT messages will be * generated for this window while processing the WM_NCDESTROY. @@ -325,22 +386,23 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window, /* free resources associated with the window */ TIMER_RemoveWindowTimers(Window->Self); #endif - -#if 0 /* FIXME */ - if (0 == (Window->Style & WS_CHILD)) + + if (!(Window->Style & WS_CHILD) && Window->IDMenu + && (Menu = IntGetMenuObject((HMENU)Window->IDMenu))) { - HMENU Menu = (HMENU) NtUserSetWindowLongW(Window->Self, GWL_ID, 0); - if (NULL != Menu) - { - DestroyMenu(Menu); - } + IntDestroyMenuObject(Menu, TRUE, TRUE); + Window->IDMenu = 0; + IntReleaseMenuObject(Menu); } - if (Window->hSysMenu) - { - DestroyMenu(Window->hSysMenu); - Window->hSysMenu = 0; - } -#endif + + if(Window->SystemMenu + && (Menu = IntGetMenuObject(Window->SystemMenu))) + { + IntDestroyMenuObject(Menu, TRUE, TRUE); + Window->SystemMenu = (HMENU)0; + IntReleaseMenuObject(Menu); + } + DceFreeWindowDCE(Window); /* Always do this to catch orphaned DCs */ #if 0 /* FIXME */ WINPROC_FreeProc(Window->winproc, WIN_PROC_WINDOW); @@ -477,6 +539,8 @@ IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert, BOOL RetMenu) if(MenuObject) { IntDestroyMenuObject(MenuObject, FALSE, TRUE); + WindowObject->SystemMenu = (HMENU)0; + IntReleaseMenuObject(MenuObject); } } @@ -515,6 +579,7 @@ IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert, BOOL RetMenu) //IntReleaseMenuObject(NewMenuObject); } IntDestroyMenuObject(MenuObject, FALSE, TRUE); + IntReleaseMenuObject(MenuObject); } if(RetMenu) return ret; @@ -523,7 +588,10 @@ IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert, BOOL RetMenu) } else { - return IntGetMenuObject((HMENU)WindowObject->SystemMenu); + if(WindowObject->SystemMenu) + return IntGetMenuObject((HMENU)WindowObject->SystemMenu); + else + return NULL; } } @@ -714,58 +782,6 @@ IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent) return !IntIsWindow(hWndOldParent) ? NULL : WndOldParent; } - -/*********************************************************************** - * IntSendDestroyMsg - */ -static void IntSendDestroyMsg(HWND Wnd) -{ -#if 0 /* FIXME */ - GUITHREADINFO info; - - if (GetGUIThreadInfo(GetCurrentThreadId(), &info)) - { - if (Wnd == info.hwndCaret) - { - DestroyCaret(); - } - } -#endif - - /* - * Send the WM_DESTROY to the window. - */ - IntSendMessage(Wnd, WM_DESTROY, 0, 0, TRUE); - - /* - * This WM_DESTROY message can trigger re-entrant calls to DestroyWindow - * make sure that the window still exists when we come back. - */ -#if 0 /* FIXME */ - if (IsWindow(Wnd)) - { - HWND* pWndArray; - int i; - - if (!(pWndArray = WIN_ListChildren( hwnd ))) return; - - /* start from the end (FIXME: is this needed?) */ - for (i = 0; pWndArray[i]; i++) ; - - while (--i >= 0) - { - if (IsWindow( pWndArray[i] )) WIN_SendDestroyMsg( pWndArray[i] ); - } - HeapFree(GetProcessHeap(), 0, pWndArray); - } - else - { - DPRINT("destroyed itself while in WM_DESTROY!\n"); - } -#endif -} - - BOOL FASTCALL IntSetSystemMenu(PWINDOW_OBJECT WindowObject, PMENU_OBJECT MenuObject) { @@ -780,9 +796,14 @@ IntSetSystemMenu(PWINDOW_OBJECT WindowObject, PMENU_OBJECT MenuObject) } } - WindowObject->SystemMenu = MenuObject->Self; - if(MenuObject) /* FIXME check window style, propably return FALSE ? */ + if(MenuObject) + { + /* FIXME check window style, propably return FALSE ? */ + WindowObject->SystemMenu = MenuObject->Self; MenuObject->IsSystemMenu = TRUE; + } + else + WindowObject->SystemMenu = (HMENU)0; return TRUE; } @@ -1137,15 +1158,7 @@ NtUserCreateWindowEx(DWORD dwExStyle, WindowObject->Style = dwStyle & ~WS_VISIBLE; DPRINT("1: Style is now %d\n", WindowObject->Style); - SystemMenu = IntGetSystemMenu(WindowObject, TRUE, TRUE); - if(SystemMenu) - { - WindowObject->SystemMenu = SystemMenu->Self; - IntReleaseMenuObject(SystemMenu); - } - else - WindowObject->SystemMenu = (HANDLE)0; - + WindowObject->SystemMenu = (HMENU)0; WindowObject->ContextHelpId = 0; WindowObject->IDMenu = (UINT)hMenu; WindowObject->Instance = hInstance; @@ -1203,7 +1216,18 @@ NtUserCreateWindowEx(DWORD dwExStyle, /* FIXME: Note the window needs a size. */ } } - + + /* create system menu */ + if((WindowObject->Style & WS_SYSMENU) && (WindowObject->Style & WS_CAPTION)) + { + SystemMenu = IntGetSystemMenu(WindowObject, TRUE, TRUE); + if(SystemMenu) + { + WindowObject->SystemMenu = SystemMenu->Self; + IntReleaseMenuObject(SystemMenu); + } + } + /* Insert the window into the thread's window list. */ ExAcquireFastMutexUnsafe (&PsGetWin32Thread()->WindowListLock); InsertTailList (&PsGetWin32Thread()->WindowListHead, @@ -1581,9 +1605,6 @@ NtUserDestroyWindow(HWND Wnd) } #endif - /* Send destroy messages */ - IntSendDestroyMsg(Wnd); - if (!IntIsWindow(Wnd)) { return TRUE; @@ -1594,7 +1615,8 @@ NtUserDestroyWindow(HWND Wnd) /* Destroy the window storage */ IntDestroyWindow(Window, PsGetWin32Process(), PsGetWin32Thread(), TRUE); - + + IntReleaseWindowObject(Window); return TRUE; }