Need extra proto.
[reactos.git] / reactos / subsys / win32k / ntuser / menu.c
index 765a7aa..b6dbb75 100644 (file)
@@ -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.38 2003/12/28 01:13:02 weiden Exp $
+/* $Id$
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  */
 /* INCLUDES ******************************************************************/
 
-#include <ddk/ntddk.h>
-#include <win32k/win32k.h>
-#include <napi/win32.h>
-#include <include/menu.h>
-#include <include/error.h>
-#include <include/winsta.h>
-#include <include/object.h>
-#include <include/guicheck.h>
-#include <include/window.h>
-#include <include/color.h>
-#include <internal/safe.h>
+#include <w32k.h>
 
 #define NDEBUG
 #include <debug.h>
 
+PMENU_OBJECT FASTCALL
+IntGetSystemMenu(PWINDOW_OBJECT Window, BOOL bRevert, BOOL RetMenu);
+
+
+
+/* STATIC FUNCTION ***********************************************************/
+
+static
+BOOL FASTCALL
+UserMenuItemInfo(
+   PMENU_OBJECT Menu,
+   UINT Item,
+   BOOL ByPosition,
+   PROSMENUITEMINFO UnsafeItemInfo,
+   BOOL SetOrGet);
+
+static
+BOOL FASTCALL
+UserMenuInfo(
+   PMENU_OBJECT Menu,
+   PROSMENUINFO UnsafeMenuInfo,
+   BOOL SetOrGet);
+
 /* INTERNAL ******************************************************************/
 
 /* maximum number of menu items a menu can contain */
   } else { \
     (state) &= ~MFS_DEFAULT; \
   } \
+  if((change) & MF_MOUSESELECT) { \
+    (state) |= MF_MOUSESELECT; \
+  } else { \
+    (state) &= ~MF_MOUSESELECT; \
+  } \
 }
 
 #define FreeMenuText(MenuItem) \
   } \
 }
 
+#define InRect(r, x, y) \
+      ( ( ((r).right >=  x)) && \
+        ( ((r).left <= x)) && \
+        ( ((r).bottom >=  y)) && \
+        ( ((r).top <= y)) )
+
 NTSTATUS FASTCALL
 InitMenuImpl(VOID)
 {
-  return(STATUS_SUCCESS);
+   return(STATUS_SUCCESS);
 }
 
 NTSTATUS FASTCALL
 CleanupMenuImpl(VOID)
 {
-  return(STATUS_SUCCESS);
+   return(STATUS_SUCCESS);
 }
 
+PMENU_OBJECT FASTCALL UserGetMenuObject(HMENU hMenu)
+{
+   PMENU_OBJECT Menu;
+   
+   if (!hMenu)
+   {
+      SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
+      return NULL;
+   }
+   
+   Menu = (PMENU_OBJECT)UserGetObject(&gHandleTable, hMenu, otMenu);
+   if (!Menu)
+   {
+      SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
+      return NULL;
+   }
+
+   ASSERT(USER_BODY_TO_HEADER(Menu)->RefCount >= 0);
+   return Menu;
+}
+
+
 #if 0
 void FASTCALL
 DumpMenuItemList(PMENU_ITEM MenuItem)
 {
-  UINT cnt = 0;
-  while(MenuItem)
-  {
-    if(MenuItem->Text.Length)
-      DbgPrint(" %d. %wZ\n", ++cnt, &MenuItem->Text);
-    else
-      DbgPrint(" %d. NO TEXT dwTypeData==%d\n", ++cnt, (DWORD)MenuItem->Text.Buffer);
-    DbgPrint("   fType=");
-    if(MFT_BITMAP & MenuItem->fType) DbgPrint("MFT_BITMAP ");
-    if(MFT_MENUBARBREAK & MenuItem->fType) DbgPrint("MFT_MENUBARBREAK ");
-    if(MFT_MENUBREAK & MenuItem->fType) DbgPrint("MFT_MENUBREAK ");
-    if(MFT_OWNERDRAW & MenuItem->fType) DbgPrint("MFT_OWNERDRAW ");
-    if(MFT_RADIOCHECK & MenuItem->fType) DbgPrint("MFT_RADIOCHECK ");
-    if(MFT_RIGHTJUSTIFY & MenuItem->fType) DbgPrint("MFT_RIGHTJUSTIFY ");
-    if(MFT_SEPARATOR & MenuItem->fType) DbgPrint("MFT_SEPARATOR ");
-    if(MFT_STRING & MenuItem->fType) DbgPrint("MFT_STRING ");
-    DbgPrint("\n   fState=");
-    if(MFS_DISABLED & MenuItem->fState) DbgPrint("MFS_DISABLED ");
-    else DbgPrint("MFS_ENABLED ");
-    if(MFS_CHECKED & MenuItem->fState) DbgPrint("MFS_CHECKED ");
-    else DbgPrint("MFS_UNCHECKED ");
-    if(MFS_HILITE & MenuItem->fState) DbgPrint("MFS_HILITE ");
-    else DbgPrint("MFS_UNHILITE ");
-    if(MFS_DEFAULT & MenuItem->fState) DbgPrint("MFS_DEFAULT ");
-    if(MFS_GRAYED & MenuItem->fState) DbgPrint("MFS_GRAYED ");
-    DbgPrint("\n   wId=%d\n", MenuItem->wID);
-    MenuItem = MenuItem->Next;
-  }
-  DbgPrint("Entries: %d\n", cnt);
-  return;
+   UINT cnt = 0;
+   while(MenuItem)
+   {
+      if(MenuItem->Text.Length)
+         DbgPrint(" %d. %wZ\n", ++cnt, &MenuItem->Text);
+      else
+         DbgPrint(" %d. NO TEXT dwTypeData==%d\n", ++cnt, (DWORD)MenuItem->Text.Buffer);
+      DbgPrint("   fType=");
+      if(MFT_BITMAP & MenuItem->fType)
+         DbgPrint("MFT_BITMAP ");
+      if(MFT_MENUBARBREAK & MenuItem->fType)
+         DbgPrint("MFT_MENUBARBREAK ");
+      if(MFT_MENUBREAK & MenuItem->fType)
+         DbgPrint("MFT_MENUBREAK ");
+      if(MFT_OWNERDRAW & MenuItem->fType)
+         DbgPrint("MFT_OWNERDRAW ");
+      if(MFT_RADIOCHECK & MenuItem->fType)
+         DbgPrint("MFT_RADIOCHECK ");
+      if(MFT_RIGHTJUSTIFY & MenuItem->fType)
+         DbgPrint("MFT_RIGHTJUSTIFY ");
+      if(MFT_SEPARATOR & MenuItem->fType)
+         DbgPrint("MFT_SEPARATOR ");
+      if(MFT_STRING & MenuItem->fType)
+         DbgPrint("MFT_STRING ");
+      DbgPrint("\n   fState=");
+      if(MFS_DISABLED & MenuItem->fState)
+         DbgPrint("MFS_DISABLED ");
+      else
+         DbgPrint("MFS_ENABLED ");
+      if(MFS_CHECKED & MenuItem->fState)
+         DbgPrint("MFS_CHECKED ");
+      else
+         DbgPrint("MFS_UNCHECKED ");
+      if(MFS_HILITE & MenuItem->fState)
+         DbgPrint("MFS_HILITE ");
+      else
+         DbgPrint("MFS_UNHILITE ");
+      if(MFS_DEFAULT & MenuItem->fState)
+         DbgPrint("MFS_DEFAULT ");
+      if(MFS_GRAYED & MenuItem->fState)
+         DbgPrint("MFS_GRAYED ");
+      DbgPrint("\n   wId=%d\n", MenuItem->wID);
+      MenuItem = MenuItem->Next;
+   }
+   DbgPrint("Entries: %d\n", cnt);
+   return;
 }
 #endif
 
 PMENU_OBJECT FASTCALL
 IntGetMenuObject(HMENU hMenu)
 {
-  PMENU_OBJECT MenuObject;
-  PW32PROCESS W32Process = PsGetWin32Process();
-  
-  if(!W32Process)
-  {
-    return NULL;
-  }
-  
-  NTSTATUS Status = ObmReferenceObjectByHandle(W32Process->
-                      WindowStation->HandleTable, hMenu, otMenu, 
-                      (PVOID*)&MenuObject);
-  if (!NT_SUCCESS(Status))
-  {
-    return NULL;
-  }
-  return MenuObject;
-}
-
-VOID FASTCALL
-IntReleaseMenuObject(PMENU_OBJECT MenuObject)
-{
-  ObmDereferenceObject(MenuObject);
+   PMENU_OBJECT Menu = UserGetMenuObject(hMenu);
+   if (Menu)
+   {
+      ASSERT(USER_BODY_TO_HEADER(Menu)->RefCount >= 0);
+
+      USER_BODY_TO_HEADER(Menu)->RefCount++;
+   }
+   return Menu;
 }
 
 BOOL FASTCALL
-IntFreeMenuItem(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem,
-    BOOL RemoveFromList, BOOL bRecurse)
+IntFreeMenuItem(PMENU_OBJECT Menu, PMENU_ITEM MenuItem,
+                BOOL RemoveFromList, BOOL bRecurse)
 {
-  FreeMenuText(MenuItem);
-  if(RemoveFromList)
-  {
-    /* FIXME - Remove from List */
-    MenuObject->MenuItemCount--;
-  }
-  if(bRecurse && MenuItem->hSubMenu)
-  {
-    PMENU_OBJECT SubMenuObject;
-    SubMenuObject = IntGetMenuObject(MenuItem->hSubMenu );
-    if(SubMenuObject)
-    {
-      IntDestroyMenuObject(SubMenuObject, bRecurse, TRUE);
-      IntReleaseMenuObject(SubMenuObject);
-    }
-  }
-  
-  /* Free memory */
-  ExFreePool(MenuItem);
-  
-  return TRUE;
+   FreeMenuText(MenuItem);
+   if(RemoveFromList)
+   {
+      /* FIXME - Remove from List */
+      Menu->MenuInfo.MenuItemCount--;
+   }
+   if(bRecurse && MenuItem->hSubMenu)
+   {
+      PMENU_OBJECT SubMenu;
+      SubMenu = UserGetMenuObject(MenuItem->hSubMenu );
+      if(SubMenu)
+      {
+         IntDestroyMenuObject(SubMenu, bRecurse, TRUE);
+      }
+   }
+
+   /* Free memory */
+   ExFreePool(MenuItem);
+
+   return TRUE;
 }
 
 BOOL FASTCALL
-IntRemoveMenuItem(PMENU_OBJECT MenuObject, UINT uPosition, UINT uFlags, 
-                   BOOL bRecurse)
+IntRemoveMenuItem(PMENU_OBJECT Menu, UINT uPosition, UINT uFlags,
+                  BOOL bRecurse)
 {
-  PMENU_ITEM PrevMenuItem, MenuItem;
-  if(IntGetMenuItemByFlag(MenuObject, uPosition, uFlags, &MenuItem, 
+   PMENU_ITEM PrevMenuItem, MenuItem;
+   if(IntGetMenuItemByFlag(Menu, uPosition, uFlags, &MenuItem,
                            &PrevMenuItem) > -1)
-  {
-    if(MenuItem)
-    {
-      if(PrevMenuItem)
-        PrevMenuItem->Next = MenuItem->Next;
-      else
+   {
+      if(MenuItem)
       {
-        MenuObject->MenuItemList = MenuItem->Next;
+         if(PrevMenuItem)
+            PrevMenuItem->Next = MenuItem->Next;
+         else
+         {
+            Menu->MenuItemList = MenuItem->Next;
+         }
+         return IntFreeMenuItem(Menu, MenuItem, TRUE, bRecurse);
       }
-      return IntFreeMenuItem(MenuObject, MenuItem, TRUE, bRecurse);
-    }
-  }
-  return FALSE;
+   }
+   return FALSE;
 }
 
 UINT FASTCALL
-IntDeleteMenuItems(PMENU_OBJECT MenuObject, BOOL bRecurse)
+IntDeleteMenuItems(PMENU_OBJECT Menu, BOOL bRecurse)
 {
-  UINT res = 0;
-  PMENU_ITEM NextItem;
-  PMENU_ITEM CurItem = MenuObject->MenuItemList;
-  while(CurItem)
-  {
-    NextItem = CurItem->Next;
-    IntFreeMenuItem(MenuObject, CurItem, FALSE, bRecurse);
-    CurItem = NextItem;
-    res++;
-  }
-  MenuObject->MenuItemCount = 0;
-  MenuObject->MenuItemList = NULL;
-  return res;
+   UINT res = 0;
+   PMENU_ITEM NextItem;
+   PMENU_ITEM CurItem = Menu->MenuItemList;
+   while(CurItem)
+   {
+      NextItem = CurItem->Next;
+      IntFreeMenuItem(Menu, CurItem, FALSE, bRecurse);
+      CurItem = NextItem;
+      res++;
+   }
+   Menu->MenuInfo.MenuItemCount = 0;
+   Menu->MenuItemList = NULL;
+   return res;
 }
 
 BOOL FASTCALL
-IntDestroyMenuObject(PMENU_OBJECT MenuObject, 
+IntDestroyMenuObject(PMENU_OBJECT Menu,
                      BOOL bRecurse, BOOL RemoveFromProcess)
 {
-  if(MenuObject)
-  {
-    /* remove all menu items */
-    ExAcquireFastMutexUnsafe (&MenuObject->MenuItemsLock);
-    IntDeleteMenuItems(MenuObject, bRecurse); /* do not destroy submenus */
-    ExReleaseFastMutexUnsafe (&MenuObject->MenuItemsLock);
-    
-    if(RemoveFromProcess)
-    {
-      ExAcquireFastMutexUnsafe(&MenuObject->W32Process->MenuListLock);
-      RemoveEntryList(&MenuObject->ListEntry);
-      ExReleaseFastMutexUnsafe(&MenuObject->W32Process->MenuListLock);
-    }
-    
-    ObmCloseHandle(MenuObject->W32Process->WindowStation->HandleTable, MenuObject->Self);
-  
-    return TRUE;
-  }
-  return FALSE;
+   if(Menu)
+   {
+      PWINSTATION_OBJECT WindowStation;
+      NTSTATUS Status;
+
+      /* remove all menu items */
+      IntDeleteMenuItems(Menu, bRecurse); /* do not destroy submenus */
+
+      if(RemoveFromProcess)
+      {
+         RemoveEntryList(&Menu->ListEntry);
+      }
+
+      Status = ObReferenceObjectByHandle(Menu->Process->Win32WindowStation,
+                                         0,
+                                         ExWindowStationObjectType,
+                                         KernelMode,
+                                         (PVOID*)&WindowStation,
+                                         NULL);
+      if(NT_SUCCESS(Status))
+      {
+         ObmDeleteObject(Menu->MenuInfo.Self, otMenu);
+         ObDereferenceObject(WindowStation);
+         return TRUE;
+      }
+   }
+   return FALSE;
 }
 
 PMENU_OBJECT FASTCALL
-IntCreateMenu(PHANDLE Handle)
+IntCreateMenu(PHANDLE Handle, BOOL IsMenuBar)
 {
-  PMENU_OBJECT MenuObject;
-  PW32PROCESS Win32Process = PsGetWin32Process();
-
-  MenuObject = (PMENU_OBJECT)ObmCreateObject(
-      Win32Process->WindowStation->HandleTable, Handle, 
-      otMenu, sizeof(MENU_OBJECT));
-
-  if(!MenuObject)
-  {
-    *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 */
-  MenuObject->MenuInfo.dwStyle = 0; /* FIXME */
-  MenuObject->MenuInfo.cyMax = 0; /* default */
-  MenuObject->MenuInfo.hbrBack =
-     NtGdiCreateSolidBrush(RGB(192, 192, 192)); /* FIXME: default background color */
-  MenuObject->MenuInfo.dwContextHelpID = 0; /* default */  
-  MenuObject->MenuInfo.dwMenuData = 0; /* default */
-  
-  MenuObject->MenuItemCount = 0;
-  MenuObject->MenuItemList = NULL;
-  ExInitializeFastMutex(&MenuObject->MenuItemsLock);
-
-  /* Insert menu item into process menu handle list */
-  ExAcquireFastMutexUnsafe(&Win32Process->MenuListLock);
-  InsertTailList(&Win32Process->MenuListHead, &MenuObject->ListEntry);
-  ExReleaseFastMutexUnsafe(&Win32Process->MenuListLock);
-
-  return MenuObject;
+   PMENU_OBJECT Menu;
+
+   Menu = (PMENU_OBJECT)ObmCreateObject(
+             &gHandleTable, Handle,
+             otMenu, sizeof(MENU_OBJECT));
+
+   if(!Menu)
+   {
+      *Handle = 0;
+      return NULL;
+   }
+
+   Menu->Process = PsGetCurrentProcess();
+   Menu->RtoL = FALSE; /* default */
+   Menu->MenuInfo.cbSize = sizeof(MENUINFO); /* not used */
+   Menu->MenuInfo.fMask = 0; /* not used */
+   Menu->MenuInfo.dwStyle = 0; /* FIXME */
+   Menu->MenuInfo.cyMax = 0; /* default */
+   Menu->MenuInfo.hbrBack =
+      NtGdiCreateSolidBrush(RGB(192, 192, 192), 0); /* FIXME: default background color */
+   Menu->MenuInfo.dwContextHelpID = 0; /* default */
+   Menu->MenuInfo.dwMenuData = 0; /* default */
+   Menu->MenuInfo.Self = *Handle;
+   Menu->MenuInfo.FocusedItem = NO_SELECTED_ITEM;
+   Menu->MenuInfo.Flags = (IsMenuBar ? 0 : MF_POPUP);
+   Menu->MenuInfo.Wnd = NULL;
+   Menu->MenuInfo.WndOwner = NULL;
+   Menu->MenuInfo.Height = 0;
+   Menu->MenuInfo.Width = 0;
+   Menu->MenuInfo.TimeToHide = FALSE;
+
+   Menu->MenuInfo.MenuItemCount = 0;
+   Menu->MenuItemList = NULL;
+
+   /* Insert menu item into process menu handle list */
+   InsertTailList(&PsGetWin32Process()->MenuListHead, &Menu->ListEntry);
+
+   return Menu;
 }
 
 BOOL FASTCALL
 IntCloneMenuItems(PMENU_OBJECT Destination, PMENU_OBJECT Source)
 {
-  PMENU_ITEM MenuItem, NewMenuItem = NULL;
-  PMENU_ITEM Old = NULL;
-
-  if(!Source->MenuItemCount)
-    return FALSE;
-
-  ExAcquireFastMutexUnsafe(&Destination->MenuItemsLock);
-  ExAcquireFastMutexUnsafe(&Source->MenuItemsLock);
-
-  MenuItem = Source->MenuItemList;
-  while(MenuItem)
-  {
-    Old = NewMenuItem;
-    if(NewMenuItem)
-      NewMenuItem->Next = MenuItem;
-    NewMenuItem = ExAllocatePool(PagedPool, sizeof(MENU_ITEM));
-    if(!NewMenuItem)
-      break;
-    NewMenuItem->fType = MenuItem->fType;
-    NewMenuItem->fState = MenuItem->fState;
-    NewMenuItem->wID = MenuItem->wID;
-    NewMenuItem->hSubMenu = MenuItem->hSubMenu;
-    NewMenuItem->hbmpChecked = MenuItem->hbmpChecked;
-    NewMenuItem->hbmpUnchecked = MenuItem->hbmpUnchecked;
-    NewMenuItem->dwItemData = MenuItem->dwItemData;
-    if((MENU_ITEM_TYPE(NewMenuItem->fType) == MF_STRING))
-    {
-      if(MenuItem->Text.Length)
+   PMENU_ITEM MenuItem, NewMenuItem = NULL;
+   PMENU_ITEM Old = NULL;
+
+   if(!Source->MenuInfo.MenuItemCount)
+      return FALSE;
+
+   MenuItem = Source->MenuItemList;
+   while(MenuItem)
+   {
+      Old = NewMenuItem;
+      if(NewMenuItem)
+         NewMenuItem->Next = MenuItem;
+      NewMenuItem = ExAllocatePoolWithTag(PagedPool, sizeof(MENU_ITEM), TAG_MENUITEM);
+      if(!NewMenuItem)
+         break;
+      NewMenuItem->fType = MenuItem->fType;
+      NewMenuItem->fState = MenuItem->fState;
+      NewMenuItem->wID = MenuItem->wID;
+      NewMenuItem->hSubMenu = MenuItem->hSubMenu;
+      NewMenuItem->hbmpChecked = MenuItem->hbmpChecked;
+      NewMenuItem->hbmpUnchecked = MenuItem->hbmpUnchecked;
+      NewMenuItem->dwItemData = MenuItem->dwItemData;
+      if((MENU_ITEM_TYPE(NewMenuItem->fType) == MF_STRING))
       {
-        NewMenuItem->Text.Length = 0;
-        NewMenuItem->Text.MaximumLength = MenuItem->Text.MaximumLength;
-        NewMenuItem->Text.Buffer = (PWSTR)ExAllocatePool(PagedPool, MenuItem->Text.MaximumLength);
-        if(!NewMenuItem->Text.Buffer)
-        {
-          ExFreePool(NewMenuItem);
-          break;
-        }
-        RtlCopyUnicodeString(&NewMenuItem->Text, &MenuItem->Text);
+         if(MenuItem->Text.Length)
+         {
+            NewMenuItem->Text.Length = 0;
+            NewMenuItem->Text.MaximumLength = MenuItem->Text.MaximumLength;
+            NewMenuItem->Text.Buffer = (PWSTR)ExAllocatePoolWithTag(PagedPool, MenuItem->Text.MaximumLength, TAG_STRING);
+            if(!NewMenuItem->Text.Buffer)
+            {
+               ExFreePool(NewMenuItem);
+               break;
+            }
+            RtlCopyUnicodeString(&NewMenuItem->Text, &MenuItem->Text);
+         }
+         else
+         {
+            NewMenuItem->Text.Buffer = MenuItem->Text.Buffer;
+         }
       }
       else
       {
-        NewMenuItem->Text.Buffer = MenuItem->Text.Buffer;
+         NewMenuItem->Text.Buffer = MenuItem->Text.Buffer;
       }
-    }
-    else
-    {
-      NewMenuItem->Text.Buffer = MenuItem->Text.Buffer;
-    }
-    NewMenuItem->hbmpItem = MenuItem->hbmpItem;
-
-    NewMenuItem->Next = NULL;
-    if(Old)
-      Old->Next = NewMenuItem;
-    else
-      Destination->MenuItemList = NewMenuItem;
-    Destination->MenuItemCount++;
-    MenuItem = MenuItem->Next;
-  }
-
-  ExReleaseFastMutexUnsafe(&Source->MenuItemsLock);
-  ExReleaseFastMutexUnsafe(&Destination->MenuItemsLock);
-  return TRUE;
+      NewMenuItem->hbmpItem = MenuItem->hbmpItem;
+
+      NewMenuItem->Next = NULL;
+      if(Old)
+         Old->Next = NewMenuItem;
+      else
+         Destination->MenuItemList = NewMenuItem;
+      Destination->MenuInfo.MenuItemCount++;
+      MenuItem = MenuItem->Next;
+   }
+
+   return TRUE;
 }
 
 PMENU_OBJECT FASTCALL
 IntCloneMenu(PMENU_OBJECT Source)
 {
-  HANDLE Handle;
-  PMENU_OBJECT MenuObject;
-  PW32PROCESS Process = PsGetWin32Process();
-  
-  if(!Source)
-    return NULL;
-    
-  MenuObject = (PMENU_OBJECT)ObmCreateObject(
-    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;
-  MenuObject->MenuInfo.dwStyle = Source->MenuInfo.dwStyle;
-  MenuObject->MenuInfo.cyMax = Source->MenuInfo.cyMax;
-  MenuObject->MenuInfo.hbrBack = Source->MenuInfo.hbrBack;
-  MenuObject->MenuInfo.dwContextHelpID = Source->MenuInfo.dwContextHelpID; 
-  MenuObject->MenuInfo.dwMenuData = Source->MenuInfo.dwMenuData;
-  
-  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);
-
-  return MenuObject;
+   HANDLE hMenu;
+   PMENU_OBJECT Menu;
+
+   if(!Source)
+      return NULL;
+
+   Menu = (PMENU_OBJECT)ObmCreateObject(
+             &gHandleTable, &hMenu,
+             otMenu, sizeof(MENU_OBJECT));
+
+   if(!Menu)
+      return NULL;
+
+   Menu->Process = PsGetCurrentProcess();
+   Menu->RtoL = Source->RtoL;
+   Menu->MenuInfo.cbSize = sizeof(MENUINFO); /* not used */
+   Menu->MenuInfo.fMask = Source->MenuInfo.fMask;
+   Menu->MenuInfo.dwStyle = Source->MenuInfo.dwStyle;
+   Menu->MenuInfo.cyMax = Source->MenuInfo.cyMax;
+   Menu->MenuInfo.hbrBack = Source->MenuInfo.hbrBack;
+   Menu->MenuInfo.dwContextHelpID = Source->MenuInfo.dwContextHelpID;
+   Menu->MenuInfo.dwMenuData = Source->MenuInfo.dwMenuData;
+   Menu->MenuInfo.Self = hMenu;
+   Menu->MenuInfo.FocusedItem = NO_SELECTED_ITEM;
+   Menu->MenuInfo.Wnd = NULL;
+   Menu->MenuInfo.WndOwner = NULL;
+   Menu->MenuInfo.Height = 0;
+   Menu->MenuInfo.Width = 0;
+   Menu->MenuInfo.TimeToHide = FALSE;
+
+   Menu->MenuInfo.MenuItemCount = 0;
+   Menu->MenuItemList = NULL;
+
+   /* Insert menu item into process menu handle list */
+   InsertTailList(&PsGetWin32Process()->MenuListHead, &Menu->ListEntry);
+
+   IntCloneMenuItems(Menu, Source);
+
+   return Menu;
 }
 
 BOOL FASTCALL
-IntSetMenuFlagRtoL(PMENU_OBJECT MenuObject)
+IntSetMenuFlagRtoL(PMENU_OBJECT Menu)
 {
-  MenuObject->RtoL = TRUE;
-  return TRUE;
+   Menu->RtoL = TRUE;
+   return TRUE;
 }
 
 BOOL FASTCALL
-IntSetMenuContextHelpId(PMENU_OBJECT MenuObject, DWORD dwContextHelpId)
+IntSetMenuContextHelpId(PMENU_OBJECT Menu, DWORD dwContextHelpId)
 {
-  MenuObject->MenuInfo.dwContextHelpID = dwContextHelpId;
-  return TRUE;
+   Menu->MenuInfo.dwContextHelpID = dwContextHelpId;
+   return TRUE;
 }
 
 BOOL FASTCALL
-IntGetMenuInfo(PMENU_OBJECT MenuObject, LPMENUINFO lpmi)
+IntGetMenuInfo(PMENU_OBJECT Menu, PROSMENUINFO lpmi)
 {
-  if(MenuObject)
-  {
-    if(lpmi->fMask & MIM_BACKGROUND)
-      lpmi->hbrBack = MenuObject->MenuInfo.hbrBack;
-    if(lpmi->fMask & MIM_HELPID)
-      lpmi->dwContextHelpID = MenuObject->MenuInfo.dwContextHelpID;
-    if(lpmi->fMask & MIM_MAXHEIGHT)
-      lpmi->cyMax = MenuObject->MenuInfo.cyMax;
-    if(lpmi->fMask & MIM_MENUDATA)
-      lpmi->dwMenuData = MenuObject->MenuInfo.dwMenuData;
-    if(lpmi->fMask & MIM_STYLE)
-      lpmi->dwStyle = MenuObject->MenuInfo.dwStyle;
-    return TRUE;
-  }
-  return FALSE;
+   if(lpmi->fMask & MIM_BACKGROUND)
+      lpmi->hbrBack = Menu->MenuInfo.hbrBack;
+   if(lpmi->fMask & MIM_HELPID)
+      lpmi->dwContextHelpID = Menu->MenuInfo.dwContextHelpID;
+   if(lpmi->fMask & MIM_MAXHEIGHT)
+      lpmi->cyMax = Menu->MenuInfo.cyMax;
+   if(lpmi->fMask & MIM_MENUDATA)
+      lpmi->dwMenuData = Menu->MenuInfo.dwMenuData;
+   if(lpmi->fMask & MIM_STYLE)
+      lpmi->dwStyle = Menu->MenuInfo.dwStyle;
+   if (sizeof(MENUINFO) < lpmi->cbSize)
+   {
+      RtlCopyMemory((char *) lpmi + sizeof(MENUINFO),
+                    (char *) &Menu->MenuInfo + sizeof(MENUINFO),
+                    lpmi->cbSize - sizeof(MENUINFO));
+   }
+
+   return TRUE;
 }
 
 
 BOOL FASTCALL
 IntIsMenu(HMENU hMenu)
 {
-  PMENU_OBJECT Menu;
-  
-  if((Menu = IntGetMenuObject(hMenu)))
-  {
-    IntReleaseMenuObject(Menu);
-    return TRUE;
-  }
-  return FALSE;
+   PMENU_OBJECT Menu;
+
+   if((Menu = UserGetMenuObject(hMenu)))
+   {
+      return TRUE;
+   }
+   return FALSE;
 }
 
 
 BOOL FASTCALL
-IntSetMenuInfo(PMENU_OBJECT MenuObject, LPMENUINFO lpmi)
+IntSetMenuInfo(PMENU_OBJECT Menu, PROSMENUINFO lpmi)
 {
-  if(lpmi->fMask & MIM_BACKGROUND)
-    MenuObject->MenuInfo.hbrBack = lpmi->hbrBack;
-  if(lpmi->fMask & MIM_HELPID)
-    MenuObject->MenuInfo.dwContextHelpID = lpmi->dwContextHelpID;
-  if(lpmi->fMask & MIM_MAXHEIGHT)
-    MenuObject->MenuInfo.cyMax = lpmi->cyMax;
-  if(lpmi->fMask & MIM_MENUDATA)
-    MenuObject->MenuInfo.dwMenuData = lpmi->dwMenuData;
-  if(lpmi->fMask & MIM_STYLE)
-    MenuObject->MenuInfo.dwStyle = lpmi->dwStyle;
-  if(lpmi->fMask & MIM_APPLYTOSUBMENUS)
-  {
-    /* FIXME */
-  }
-  return TRUE;
+   if(lpmi->fMask & MIM_BACKGROUND)
+      Menu->MenuInfo.hbrBack = lpmi->hbrBack;
+   if(lpmi->fMask & MIM_HELPID)
+      Menu->MenuInfo.dwContextHelpID = lpmi->dwContextHelpID;
+   if(lpmi->fMask & MIM_MAXHEIGHT)
+      Menu->MenuInfo.cyMax = lpmi->cyMax;
+   if(lpmi->fMask & MIM_MENUDATA)
+      Menu->MenuInfo.dwMenuData = lpmi->dwMenuData;
+   if(lpmi->fMask & MIM_STYLE)
+      Menu->MenuInfo.dwStyle = lpmi->dwStyle;
+   if(lpmi->fMask & MIM_APPLYTOSUBMENUS)
+   {
+      /* FIXME */
+   }
+   if (sizeof(MENUINFO) < lpmi->cbSize)
+   {
+      Menu->MenuInfo.FocusedItem = lpmi->FocusedItem;
+      Menu->MenuInfo.Height = lpmi->Height;
+      Menu->MenuInfo.Width = lpmi->Width;
+      Menu->MenuInfo.Wnd = lpmi->Wnd;
+      Menu->MenuInfo.WndOwner = lpmi->WndOwner;
+      Menu->MenuInfo.TimeToHide = lpmi->TimeToHide;
+   }
+
+   return TRUE;
 }
 
 
 int FASTCALL
-IntGetMenuItemByFlag(PMENU_OBJECT MenuObject, UINT uSearchBy, UINT fFlag, 
-                      PMENU_ITEM *MenuItem, PMENU_ITEM *PrevMenuItem)
+IntGetMenuItemByFlag(PMENU_OBJECT Menu, UINT uSearchBy, UINT fFlag,
+                     PMENU_ITEM *MenuItem, PMENU_ITEM *PrevMenuItem)
 {
-  PMENU_ITEM PrevItem = NULL;
-  PMENU_ITEM CurItem = MenuObject->MenuItemList;
-  int p;
-  if(MF_BYPOSITION & fFlag)
-  {
-    p = uSearchBy;
-    while(CurItem && (p > 0))
-    {
-      PrevItem = CurItem;
-      CurItem = CurItem->Next;
-      p--;
-    }
-    if(CurItem)
-    {
-      if(MenuItem) *MenuItem = CurItem;
-      if(PrevMenuItem) *PrevMenuItem = PrevItem;
-    }
-    else
-    {
-      if(MenuItem) *MenuItem = NULL;
-      if(PrevMenuItem) *PrevMenuItem = NULL; /* ? */
-      return -1;
-    }
-
-    return uSearchBy - p;
-  }
-  else
-  {
-    p = 0;
-    while(CurItem)
-    {
-      if(CurItem->wID == uSearchBy)
+   PMENU_ITEM PrevItem = NULL;
+   PMENU_ITEM CurItem = Menu->MenuItemList;
+   int p;
+   int ret;
+
+   if(MF_BYPOSITION & fFlag)
+   {
+      p = uSearchBy;
+      while(CurItem && (p > 0))
       {
-        if(MenuItem) *MenuItem = CurItem;
-        if(PrevMenuItem) *PrevMenuItem = PrevItem;
-        return p;
+         PrevItem = CurItem;
+         CurItem = CurItem->Next;
+         p--;
       }
-      PrevItem = CurItem;
-      CurItem = CurItem->Next;
-      p++;
-    }
-  }
-  return -1;
+      if(CurItem)
+      {
+         if(MenuItem)
+            *MenuItem = CurItem;
+         if(PrevMenuItem)
+            *PrevMenuItem = PrevItem;
+      }
+      else
+      {
+         if(MenuItem)
+            *MenuItem = NULL;
+         if(PrevMenuItem)
+            *PrevMenuItem = NULL; /* ? */
+         return -1;
+      }
+
+      return uSearchBy - p;
+   }
+   else
+   {
+      p = 0;
+      while(CurItem)
+      {
+         if(CurItem->wID == uSearchBy)
+         {
+            if(MenuItem)
+               *MenuItem = CurItem;
+            if(PrevMenuItem)
+               *PrevMenuItem = PrevItem;
+            return p;
+         }
+         else if (0 != (CurItem->fType & MF_POPUP))
+         {
+            Menu = UserGetMenuObject(CurItem->hSubMenu);
+            if (NULL != Menu)
+            {
+               ret = IntGetMenuItemByFlag(Menu, uSearchBy, fFlag,
+                                          MenuItem, PrevMenuItem);
+               if (-1 != ret)
+               {
+                  return ret;
+               }
+            }
+         }
+         PrevItem = CurItem;
+         CurItem = CurItem->Next;
+         p++;
+      }
+   }
+   return -1;
 }
 
 
 int FASTCALL
-IntInsertMenuItemToList(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, int pos)
+IntInsertMenuItemToList(PMENU_OBJECT Menu, PMENU_ITEM MenuItem, int pos)
 {
-  PMENU_ITEM CurItem;
-  PMENU_ITEM LastItem = NULL;
-  UINT npos = 0;
-
-  CurItem = MenuObject->MenuItemList;
-  if(pos <= -1)
-  {
-    while(CurItem)
-    {
-      LastItem = CurItem;
-      CurItem = CurItem->Next;
-      npos++;
-    }
-  }
-  else
-  {
-    while(CurItem && (pos > 0))
-    {
-      LastItem = CurItem;
-      CurItem = CurItem->Next;
-      pos--;
-      npos++;
-    }
-  }
-
-  if(CurItem)
-  {
-    if(LastItem)
-    {
-      /* insert the item before CurItem */
-      MenuItem->Next = LastItem->Next;
-      LastItem->Next = MenuItem;
-    }
-    else
-    {
-      /* insert at the beginning */
-      MenuObject->MenuItemList = MenuItem;
-      MenuItem->Next = CurItem;
-    }
-  }
-  else
-  {
-    if(LastItem)
-    {
-      /* append item */
-      LastItem->Next = MenuItem;
-      MenuItem->Next = NULL;
-    }
-    else
-    {
-      /* insert first item */
-      MenuObject->MenuItemList = MenuItem;
-      MenuItem->Next = NULL;
-    }
-  }
-  MenuObject->MenuItemCount++;
-
-  return npos;
+   PMENU_ITEM CurItem;
+   PMENU_ITEM LastItem = NULL;
+   UINT npos = 0;
+
+   CurItem = Menu->MenuItemList;
+   if(pos <= -1)
+   {
+      while(CurItem)
+      {
+         LastItem = CurItem;
+         CurItem = CurItem->Next;
+         npos++;
+      }
+   }
+   else
+   {
+      while(CurItem && (pos > 0))
+      {
+         LastItem = CurItem;
+         CurItem = CurItem->Next;
+         pos--;
+         npos++;
+      }
+   }
+
+   if(CurItem)
+   {
+      if(LastItem)
+      {
+         /* insert the item before CurItem */
+         MenuItem->Next = LastItem->Next;
+         LastItem->Next = MenuItem;
+      }
+      else
+      {
+         /* insert at the beginning */
+         Menu->MenuItemList = MenuItem;
+         MenuItem->Next = CurItem;
+      }
+   }
+   else
+   {
+      if(LastItem)
+      {
+         /* append item */
+         LastItem->Next = MenuItem;
+         MenuItem->Next = NULL;
+      }
+      else
+      {
+         /* insert first item */
+         Menu->MenuItemList = MenuItem;
+         MenuItem->Next = NULL;
+      }
+   }
+   Menu->MenuInfo.MenuItemCount++;
+
+   return npos;
 }
 
 BOOL FASTCALL
-IntGetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, LPMENUITEMINFOW lpmii)
+IntGetMenuItemInfo(PMENU_OBJECT Menu, /* UNUSED PARAM!! */
+                   PMENU_ITEM MenuItem, PROSMENUITEMINFO lpmii)
 {
-  if(!MenuItem || !MenuObject || !lpmii)
-  {
-    return FALSE;
-  }
-  
-  lpmii->cch = MenuItem->Text.Length;
-  
-  if(lpmii->fMask & MIIM_BITMAP)
-  {
-    lpmii->hbmpItem = MenuItem->hbmpItem;
-  }
-  if(lpmii->fMask & MIIM_CHECKMARKS)
-  {
-    lpmii->hbmpChecked = MenuItem->hbmpChecked;
-    lpmii->hbmpUnchecked = MenuItem->hbmpUnchecked;
-  }
-  if(lpmii->fMask & MIIM_DATA)
-  {
-    lpmii->dwItemData = MenuItem->dwItemData;
-  }
-  if(lpmii->fMask & (MIIM_FTYPE | MIIM_TYPE))
-  {
-    lpmii->fType = MenuItem->fType;
-  }
-  if(lpmii->fMask & MIIM_ID)
-  {
-    lpmii->wID = MenuItem->wID;
-  }
-  if(lpmii->fMask & MIIM_STATE)
-  {
-    lpmii->fState = MenuItem->fState;
-  }
-  if(lpmii->fMask & MIIM_SUBMENU)
-  {
-    lpmii->hSubMenu = MenuItem->hSubMenu;
-  }
-  
-  return TRUE;
+   NTSTATUS Status;
+
+   if(lpmii->fMask & MIIM_BITMAP)
+   {
+      lpmii->hbmpItem = MenuItem->hbmpItem;
+   }
+   if(lpmii->fMask & MIIM_CHECKMARKS)
+   {
+      lpmii->hbmpChecked = MenuItem->hbmpChecked;
+      lpmii->hbmpUnchecked = MenuItem->hbmpUnchecked;
+   }
+   if(lpmii->fMask & MIIM_DATA)
+   {
+      lpmii->dwItemData = MenuItem->dwItemData;
+   }
+   if(lpmii->fMask & (MIIM_FTYPE | MIIM_TYPE))
+   {
+      lpmii->fType = MenuItem->fType;
+   }
+   if(lpmii->fMask & MIIM_ID)
+   {
+      lpmii->wID = MenuItem->wID;
+   }
+   if(lpmii->fMask & MIIM_STATE)
+   {
+      lpmii->fState = MenuItem->fState;
+   }
+   if(lpmii->fMask & MIIM_SUBMENU)
+   {
+      lpmii->hSubMenu = MenuItem->hSubMenu;
+   }
+   if (lpmii->fMask & (MIIM_STRING | MIIM_TYPE))
+   {
+      if (lpmii->dwTypeData == NULL)
+      {
+         lpmii->cch = MenuItem->Text.Length / sizeof(WCHAR);
+      }
+      else
+      {
+         Status = MmCopyToCaller(lpmii->dwTypeData, MenuItem->Text.Buffer,
+                                 min(lpmii->cch * sizeof(WCHAR),
+                                     MenuItem->Text.MaximumLength));
+         if (! NT_SUCCESS(Status))
+         {
+            SetLastNtError(Status);
+            return FALSE;
+         }
+      }
+   }
+
+   if (sizeof(ROSMENUITEMINFO) == lpmii->cbSize)
+   {
+      lpmii->Rect = MenuItem->Rect;
+      lpmii->XTab = MenuItem->XTab;
+   }
+
+   return TRUE;
 }
 
 BOOL FASTCALL
-IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, LPCMENUITEMINFOW lpmii)
+IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, PROSMENUITEMINFO lpmii)
 {
-  PUNICODE_STRING Source;
-  UINT copylen = 0;
-  
-  if(!MenuItem || !MenuObject || !lpmii)
-  {
-    return FALSE;
-  }
+   PMENU_OBJECT SubMenuObject;
 
-  MenuItem->fType = lpmii->fType;
-  
-  if(lpmii->fMask & MIIM_BITMAP)
-  {
-    MenuItem->hbmpItem = lpmii->hbmpItem;
-  }
-  if(lpmii->fMask & MIIM_CHECKMARKS)
-  {
-    MenuItem->hbmpChecked = lpmii->hbmpChecked;
-    MenuItem->hbmpUnchecked = lpmii->hbmpUnchecked;
-  }
-  if(lpmii->fMask & MIIM_DATA)
-  {
-    MenuItem->dwItemData = lpmii->dwItemData;
-  }
-  if(lpmii->fMask & (MIIM_FTYPE | MIIM_TYPE))
-  {
-    MenuItem->fType = lpmii->fType;
-  }
-  if(lpmii->fMask & MIIM_ID)
-  {
-    MenuItem->wID = lpmii->wID;
-  }
-  if(lpmii->fMask & MIIM_STATE)
-  {
-    /* remove MFS_DEFAULT flag from all other menu items if this item
-       has the MFS_DEFAULT state */
-    if(lpmii->fState & MFS_DEFAULT)
-      IntSetMenuDefaultItem(MenuObject, -1, 0);
-    /* update the menu item state flags */
-    UpdateMenuItemState(MenuItem->fState, lpmii->fState);
-  }
-  
-  if(lpmii->fMask & MIIM_SUBMENU)
-  {
-    MenuItem->hSubMenu = lpmii->hSubMenu;
-  }
-  if((lpmii->fMask & (MIIM_TYPE | MIIM_STRING)) && 
-           (MENU_ITEM_TYPE(lpmii->fType) == MF_STRING))
-  {
-    if(lpmii->dwTypeData && lpmii->cch)
-    {
-      Source = (PUNICODE_STRING)lpmii->dwTypeData;
-      FreeMenuText(MenuItem);
-      copylen = min((UINT)Source->MaximumLength, (lpmii->cch + 1) * sizeof(WCHAR));
-      MenuItem->Text.Buffer = (PWSTR)ExAllocatePool(PagedPool, copylen);
-      if(MenuItem->Text.Buffer)
+   if(!MenuItem || !MenuObject || !lpmii)
+   {
+      return FALSE;
+   }
+
+   MenuItem->fType = lpmii->fType;
+
+   if(lpmii->fMask & MIIM_BITMAP)
+   {
+      MenuItem->hbmpItem = lpmii->hbmpItem;
+   }
+   if(lpmii->fMask & MIIM_CHECKMARKS)
+   {
+      MenuItem->hbmpChecked = lpmii->hbmpChecked;
+      MenuItem->hbmpUnchecked = lpmii->hbmpUnchecked;
+   }
+   if(lpmii->fMask & MIIM_DATA)
+   {
+      MenuItem->dwItemData = lpmii->dwItemData;
+   }
+   if(lpmii->fMask & (MIIM_FTYPE | MIIM_TYPE))
+   {
+      /*
+       * Delete the menu item type when changing type from
+       * MF_STRING.
+       */
+      if (MenuItem->fType != lpmii->fType &&
+            MENU_ITEM_TYPE(MenuItem->fType) == MF_STRING)
+      {
+         FreeMenuText(MenuItem);
+         RtlInitUnicodeString(&MenuItem->Text, NULL);
+      }
+      MenuItem->fType = lpmii->fType;
+   }
+   if(lpmii->fMask & MIIM_ID)
+   {
+      MenuItem->wID = lpmii->wID;
+   }
+   if(lpmii->fMask & MIIM_STATE)
+   {
+      /* remove MFS_DEFAULT flag from all other menu items if this item
+         has the MFS_DEFAULT state */
+      if(lpmii->fState & MFS_DEFAULT)
+         UserSetMenuDefaultItem(MenuObject, -1, 0);
+      /* update the menu item state flags */
+      UpdateMenuItemState(MenuItem->fState, lpmii->fState);
+   }
+
+   if(lpmii->fMask & MIIM_SUBMENU)
+   {
+      MenuItem->hSubMenu = lpmii->hSubMenu;
+      /* Make sure the submenu is marked as a popup menu */
+      if (MenuItem->hSubMenu)
       {
-        MenuItem->Text.Length = 0;
-        MenuItem->Text.MaximumLength = copylen;
-        RtlCopyUnicodeString(&MenuItem->Text, Source);
+         SubMenuObject = UserGetMenuObject(MenuItem->hSubMenu);
+         if (SubMenuObject != NULL)
+         {
+            SubMenuObject->MenuInfo.Flags |= MF_POPUP;
+            MenuItem->fType |= MF_POPUP;
+         }
+         else
+         {
+            MenuItem->fType &= ~MF_POPUP;
+         }
       }
       else
       {
-        MenuItem->Text.Length = 0;
-        MenuItem->Text.MaximumLength = 0;
-        MenuItem->Text.Buffer = NULL;
+         MenuItem->fType &= ~MF_POPUP;
       }
-    }
-    else
-    {
+   }
+   if ((lpmii->fMask & (MIIM_TYPE | MIIM_STRING)) &&
+         (MENU_ITEM_TYPE(lpmii->fType) == MF_STRING))
+   {
       FreeMenuText(MenuItem);
-      MenuItem->fType = MF_SEPARATOR;
-    }
-  }
-  else
-  {
-    RtlInitUnicodeString(&MenuItem->Text, NULL);
-  }
-  
-  return TRUE;
+
+      if(lpmii->dwTypeData && lpmii->cch)
+      {
+         UNICODE_STRING Source;
+
+         Source.Length =
+            Source.MaximumLength = lpmii->cch * sizeof(WCHAR);
+         Source.Buffer = lpmii->dwTypeData;
+
+         MenuItem->Text.Buffer = (PWSTR)ExAllocatePoolWithTag(
+                                    PagedPool, Source.Length + sizeof(WCHAR), TAG_STRING);
+         if(MenuItem->Text.Buffer != NULL)
+         {
+            MenuItem->Text.Length = 0;
+            MenuItem->Text.MaximumLength = Source.Length + sizeof(WCHAR);
+            RtlCopyUnicodeString(&MenuItem->Text, &Source);
+            MenuItem->Text.Buffer[MenuItem->Text.Length / sizeof(WCHAR)] = 0;
+         }
+         else
+         {
+            RtlInitUnicodeString(&MenuItem->Text, NULL);
+         }
+      }
+      else
+      {
+         if (0 == (MenuObject->MenuInfo.Flags & MF_SYSMENU))
+         {
+            MenuItem->fType |= MF_SEPARATOR;
+         }
+         RtlInitUnicodeString(&MenuItem->Text, NULL);
+      }
+   }
+
+   if (sizeof(ROSMENUITEMINFO) == lpmii->cbSize)
+   {
+      MenuItem->Rect = lpmii->Rect;
+      MenuItem->XTab = lpmii->XTab;
+   }
+
+   return TRUE;
 }
 
 BOOL FASTCALL
-IntInsertMenuItem(PMENU_OBJECT MenuObject, UINT uItem, WINBOOL fByPosition,
-                   LPCMENUITEMINFOW lpmii)
+IntInsertMenuItem(PMENU_OBJECT MenuObject, UINT uItem, BOOL fByPosition,
+                  PROSMENUITEMINFO ItemInfo)
 {
-  int pos = (int)uItem;
-  PMENU_ITEM MenuItem;
-  
-  if(MenuObject->MenuItemCount >= MAX_MENU_ITEMS)
-  {
-    /* FIXME Set last error code? */
-    SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
-    return FALSE;
-  }
-  
-  if(fByPosition)
-  {
-    /* calculate position */
-    if(pos > MenuObject->MenuItemCount)
-      pos = MenuObject->MenuItemCount;
-  }
-  else
-  {
-    pos = IntGetMenuItemByFlag(MenuObject, uItem, MF_BYCOMMAND, NULL, NULL);
-  }
-  if(pos < -1) pos = -1;
-  
-  MenuItem = ExAllocatePool(PagedPool, sizeof(MENU_ITEM));
-  if(!MenuItem)
-  {
-    /* FIXME Set last error code? */
-    SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
-    return FALSE;
-  }
-  
-  MenuItem->fType = MFT_STRING;
-  MenuItem->fState = MFS_ENABLED | MFS_UNCHECKED;
-  MenuItem->wID = 0;
-  MenuItem->hSubMenu = (HMENU)0;
-  MenuItem->hbmpChecked = (HBITMAP)0;
-  MenuItem->hbmpUnchecked = (HBITMAP)0;
-  MenuItem->dwItemData = 0;
-  RtlInitUnicodeString(&MenuItem->Text, NULL);
-  MenuItem->hbmpItem = (HBITMAP)0;  
-
-  if(!IntSetMenuItemInfo(MenuObject, MenuItem, lpmii))
-  {
-    ExFreePool(MenuItem);
-    return FALSE;
-  }
-  
-  pos = IntInsertMenuItemToList(MenuObject, MenuItem, pos);
+   int pos = (int)uItem;
+   PMENU_ITEM MenuItem;
+
+   if (MAX_MENU_ITEMS <= MenuObject->MenuInfo.MenuItemCount)
+   {
+      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+      return FALSE;
+   }
+
+   if (fByPosition)
+   {
+      /* calculate position */
+      if(MenuObject->MenuInfo.MenuItemCount < pos)
+      {
+         pos = MenuObject->MenuInfo.MenuItemCount;
+      }
+   }
+   else
+   {
+      pos = IntGetMenuItemByFlag(MenuObject, uItem, MF_BYCOMMAND, NULL, NULL);
+   }
+   if (pos < -1)
+   {
+      pos = -1;
+   }
+
+   MenuItem = ExAllocatePoolWithTag(PagedPool, sizeof(MENU_ITEM), TAG_MENUITEM);
+   if (NULL == MenuItem)
+   {
+      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+      return FALSE;
+   }
+
+   MenuItem->fType = MFT_STRING;
+   MenuItem->fState = MFS_ENABLED | MFS_UNCHECKED;
+   MenuItem->wID = 0;
+   MenuItem->hSubMenu = (HMENU)0;
+   MenuItem->hbmpChecked = (HBITMAP)0;
+   MenuItem->hbmpUnchecked = (HBITMAP)0;
+   MenuItem->dwItemData = 0;
+   RtlInitUnicodeString(&MenuItem->Text, NULL);
+   MenuItem->hbmpItem = (HBITMAP)0;
+
+   if (! IntSetMenuItemInfo(MenuObject, MenuItem, ItemInfo))
+   {
+      ExFreePool(MenuItem);
+      return FALSE;
+   }
+
+   /* Force size recalculation! */
+   MenuObject->MenuInfo.Height = 0;
+
+   pos = IntInsertMenuItemToList(MenuObject, MenuItem, pos);
+
+   DPRINT("IntInsertMenuItemToList = %i\n", pos);
 
-  return pos >= 0;
+   return (pos >= 0);
 }
 
 UINT FASTCALL
 IntEnableMenuItem(PMENU_OBJECT MenuObject, UINT uIDEnableItem, UINT uEnable)
 {
-  PMENU_ITEM MenuItem;
-  UINT res = IntGetMenuItemByFlag(MenuObject, uIDEnableItem, uEnable, &MenuItem, NULL);
-  if(!MenuItem || (res == (UINT)-1))
-  {
-    return (UINT)-1;
-  }
-  
-  res = MenuItem->fState & (MF_GRAYED | MF_DISABLED);
-  
-  if(uEnable & MF_DISABLED)
-  {
-    if(!(MenuItem->fState & MF_DISABLED))
-        MenuItem->fState |= MF_DISABLED;
-    if(uEnable & MF_GRAYED)
-    {
-      if(!(MenuItem->fState & MF_GRAYED))
-          MenuItem->fState |= MF_GRAYED;
-    }
-  }
-  else
-  {
-    if(uEnable & MF_GRAYED)
-    {
-      if(!(MenuItem->fState & MF_GRAYED))
-          MenuItem->fState |= MF_GRAYED;
+   PMENU_ITEM MenuItem;
+   UINT res = IntGetMenuItemByFlag(MenuObject, uIDEnableItem, uEnable, &MenuItem, NULL);
+   if(!MenuItem || (res == (UINT)-1))
+   {
+      return (UINT)-1;
+   }
+
+   res = MenuItem->fState & (MF_GRAYED | MF_DISABLED);
+
+   if(uEnable & MF_DISABLED)
+   {
       if(!(MenuItem->fState & MF_DISABLED))
-          MenuItem->fState |= MF_DISABLED;
-    }
-    else
-    {
-      if(MenuItem->fState & MF_DISABLED)
-          MenuItem->fState ^= MF_DISABLED;
-      if(MenuItem->fState & MF_GRAYED)
-          MenuItem->fState ^= MF_GRAYED;
-    }
-  }
-  
-  return res;
+         MenuItem->fState |= MF_DISABLED;
+      if(uEnable & MF_GRAYED)
+      {
+         if(!(MenuItem->fState & MF_GRAYED))
+            MenuItem->fState |= MF_GRAYED;
+      }
+   }
+   else
+   {
+      if(uEnable & MF_GRAYED)
+      {
+         if(!(MenuItem->fState & MF_GRAYED))
+            MenuItem->fState |= MF_GRAYED;
+         if(!(MenuItem->fState & MF_DISABLED))
+            MenuItem->fState |= MF_DISABLED;
+      }
+      else
+      {
+         if(MenuItem->fState & MF_DISABLED)
+            MenuItem->fState ^= MF_DISABLED;
+         if(MenuItem->fState & MF_GRAYED)
+            MenuItem->fState ^= MF_GRAYED;
+      }
+   }
+
+   return res;
 }
 
 
 DWORD FASTCALL
 IntBuildMenuItemList(PMENU_OBJECT MenuObject, PVOID Buffer, ULONG nMax)
 {
-  DWORD res = 0;
-  UINT sz;
-  MENUITEMINFOW mii;
-  PVOID Buf;
-  PMENU_ITEM CurItem = MenuObject->MenuItemList;
-  if(nMax)
-  {
-    sz = sizeof(MENUITEMINFOW) + sizeof(RECT);
-    Buf = Buffer;
-    mii.cbSize = sz;
-    mii.fMask = 0;
-    while(CurItem && (nMax >= sz))
-    {
-      mii.cch = CurItem->Text.Length / sizeof(WCHAR);
-      mii.dwItemData = CurItem->dwItemData;
-      if(CurItem->Text.Length)
-        mii.dwTypeData = NULL;
-      else
-        mii.dwTypeData = (LPWSTR)CurItem->Text.Buffer;
-      mii.fState = CurItem->fState;
-      mii.fType = CurItem->fType;
-      mii.hbmpChecked = CurItem->hbmpChecked;
-      mii.hbmpItem = CurItem->hbmpItem;
-      mii.hbmpUnchecked = CurItem->hbmpUnchecked;
-      mii.hSubMenu = CurItem->hSubMenu;
-      RtlCopyMemory(Buf, &mii, sizeof(MENUITEMINFOW));
-      Buf += sizeof(MENUITEMINFOW);
-      RtlCopyMemory(Buf, &CurItem->Rect, sizeof(RECT));
-      Buf += sizeof(RECT);      
-      nMax -= sz;
-      
-      if(CurItem->Text.Length && (nMax >= CurItem->Text.Length + sizeof(WCHAR)))
+   DWORD res = 0;
+   UINT sz;
+   ROSMENUITEMINFO mii;
+   PVOID Buf;
+   PMENU_ITEM CurItem = MenuObject->MenuItemList;
+   PWCHAR StrOut;
+   NTSTATUS Status;
+   WCHAR NulByte;
+
+   if (0 != nMax)
+   {
+      if (nMax < MenuObject->MenuInfo.MenuItemCount * sizeof(ROSMENUITEMINFO))
       {
-        /* copy string */
-        RtlCopyMemory(Buf, (LPWSTR)CurItem->Text.Buffer, CurItem->Text.Length);
-        Buf += CurItem->Text.Length + sizeof(WCHAR);
-        nMax -= CurItem->Text.Length + sizeof(WCHAR);
+         return 0;
       }
-      else
-        break;
+      StrOut = (PWCHAR)((char *) Buffer + MenuObject->MenuInfo.MenuItemCount
+                        * sizeof(ROSMENUITEMINFO));
+      nMax -= MenuObject->MenuInfo.MenuItemCount * sizeof(ROSMENUITEMINFO);
+      sz = sizeof(ROSMENUITEMINFO);
+      Buf = Buffer;
+      mii.cbSize = sizeof(ROSMENUITEMINFO);
+      mii.fMask = 0;
+      NulByte = L'\0';
+
+      while (NULL != CurItem)
+      {
+         mii.cch = CurItem->Text.Length / sizeof(WCHAR);
+         mii.dwItemData = CurItem->dwItemData;
+         if (0 != CurItem->Text.Length)
+         {
+            mii.dwTypeData = StrOut;
+         }
+         else
+         {
+            mii.dwTypeData = NULL;
+         }
+         mii.fState = CurItem->fState;
+         mii.fType = CurItem->fType;
+         mii.hbmpChecked = CurItem->hbmpChecked;
+         mii.hbmpItem = CurItem->hbmpItem;
+         mii.hbmpUnchecked = CurItem->hbmpUnchecked;
+         mii.hSubMenu = CurItem->hSubMenu;
+         mii.Rect = CurItem->Rect;
+         mii.XTab = CurItem->XTab;
+
+         Status = MmCopyToCaller(Buf, &mii, sizeof(ROSMENUITEMINFO));
+         if (! NT_SUCCESS(Status))
+         {
+            SetLastNtError(Status);
+            return 0;
+         }
+         Buf = (PVOID)((ULONG_PTR)Buf + sizeof(ROSMENUITEMINFO));
+
+         if (0 != CurItem->Text.Length
+               && (nMax >= CurItem->Text.Length + sizeof(WCHAR)))
+         {
+            /* copy string */
+            Status = MmCopyToCaller(StrOut, CurItem->Text.Buffer,
+                                    CurItem->Text.Length);
+            if (! NT_SUCCESS(Status))
+            {
+               SetLastNtError(Status);
+               return 0;
+            }
+            StrOut += CurItem->Text.Length / sizeof(WCHAR);
+            Status = MmCopyToCaller(StrOut, &NulByte, sizeof(WCHAR));
+            if (! NT_SUCCESS(Status))
+            {
+               SetLastNtError(Status);
+               return 0;
+            }
+            StrOut++;
+            nMax -= CurItem->Text.Length + sizeof(WCHAR);
+         }
+         else if (0 != CurItem->Text.Length)
+         {
+            break;
+         }
+
+         CurItem = CurItem->Next;
+         res++;
+      }
+   }
+   else
+   {
+      while (NULL != CurItem)
+      {
+         res += sizeof(ROSMENUITEMINFO) + CurItem->Text.Length + sizeof(WCHAR);
+         CurItem = CurItem->Next;
+      }
+   }
 
-      CurItem = CurItem->Next;
-      res++;
-    }
-  }
-  else
-  {
-    while(CurItem)
-    {
-      res += sizeof(MENUITEMINFOW) + sizeof(RECT);
-      res += CurItem->Text.Length + sizeof(WCHAR);
-      CurItem = CurItem->Next;
-    }
-  }
-  return res;
+   return res;
 }
 
 
 DWORD FASTCALL
 IntCheckMenuItem(PMENU_OBJECT MenuObject, UINT uIDCheckItem, UINT uCheck)
 {
-  PMENU_ITEM MenuItem;
-  int res = -1;
-
-  if((IntGetMenuItemByFlag(MenuObject, uIDCheckItem, uCheck, &MenuItem, NULL) < 0) || !MenuItem)
-  {
-    return -1;
-  }
-
-  res = (DWORD)(MenuItem->fState & MF_CHECKED);
-  if(uCheck & MF_CHECKED)
-  {
-    if(!(MenuItem->fState & MF_CHECKED))
-        MenuItem->fState |= MF_CHECKED;
-  }
-  else
-  {
-    if(MenuItem->fState & MF_CHECKED)
-        MenuItem->fState ^= MF_CHECKED;
-  }
-
-  return (DWORD)res;
+   PMENU_ITEM MenuItem;
+   int res = -1;
+
+   if((IntGetMenuItemByFlag(MenuObject, uIDCheckItem, uCheck, &MenuItem, NULL) < 0) || !MenuItem)
+   {
+      return -1;
+   }
+
+   res = (DWORD)(MenuItem->fState & MF_CHECKED);
+   if(uCheck & MF_CHECKED)
+   {
+      if(!(MenuItem->fState & MF_CHECKED))
+         MenuItem->fState |= MF_CHECKED;
+   }
+   else
+   {
+      if(MenuItem->fState & MF_CHECKED)
+         MenuItem->fState ^= MF_CHECKED;
+   }
+
+   return (DWORD)res;
 }
 
 BOOL FASTCALL
 IntHiliteMenuItem(PWINDOW_OBJECT WindowObject, PMENU_OBJECT MenuObject,
-  UINT uItemHilite, UINT uHilite)
+                  UINT uItemHilite, UINT uHilite)
 {
-  PMENU_ITEM MenuItem;
-  BOOL res = IntGetMenuItemByFlag(MenuObject, uItemHilite, uHilite, &MenuItem, NULL);
-  if(!MenuItem || !res)
-  {
-    return FALSE;
-  }
-  
-  if(uHilite & MF_HILITE)
-  {
-    if(!(MenuItem->fState & MF_HILITE))
-        MenuItem->fState |= MF_HILITE;
-  }
-  else
-  {
-    if(MenuItem->fState & MF_HILITE)
-        MenuItem->fState ^= MF_HILITE;
-  }
-  
-  /* FIXME - update the window's menu */
-  
-  return TRUE;
+   PMENU_ITEM MenuItem;
+   BOOL res = IntGetMenuItemByFlag(MenuObject, uItemHilite, uHilite, &MenuItem, NULL);
+   if(!MenuItem || !res)
+   {
+      return FALSE;
+   }
+
+   if(uHilite & MF_HILITE)
+   {
+      if(!(MenuItem->fState & MF_HILITE))
+         MenuItem->fState |= MF_HILITE;
+   }
+   else
+   {
+      if(MenuItem->fState & MF_HILITE)
+         MenuItem->fState ^= MF_HILITE;
+   }
+
+   /* FIXME - update the window's menu */
+
+   return TRUE;
 }
 
 BOOL FASTCALL
-IntSetMenuDefaultItem(PMENU_OBJECT MenuObject, UINT uItem, UINT fByPos)
+UserSetMenuDefaultItem(PMENU_OBJECT MenuObject, UINT uItem, UINT fByPos)
 {
-  BOOL ret = FALSE;
-  PMENU_ITEM MenuItem = MenuObject->MenuItemList;
-    
-  if(uItem == (UINT)-1)
-  {
-    while(MenuItem)
-    {
-      if(MenuItem->fState & MFS_DEFAULT)
-        MenuItem->fState ^= MFS_DEFAULT;
-      MenuItem = MenuItem->Next;
-    }
-    return TRUE;
-  }
-  
-  if(fByPos)
-  {
-    UINT pos = 0;
-    while(MenuItem)
-    {
-      if(pos == uItem)
-      {
-        if(!(MenuItem->fState & MFS_DEFAULT))
-          MenuItem->fState |= MFS_DEFAULT;
-        ret = TRUE;
-      }
-      else
+   BOOL ret = FALSE;
+   PMENU_ITEM MenuItem = MenuObject->MenuItemList;
+
+   if(uItem == (UINT)-1)
+   {
+      while(MenuItem)
       {
-        if(MenuItem->fState & MFS_DEFAULT)
-          MenuItem->fState ^= MFS_DEFAULT;
+         if(MenuItem->fState & MFS_DEFAULT)
+            MenuItem->fState ^= MFS_DEFAULT;
+         MenuItem = MenuItem->Next;
       }
-      pos++;
-      MenuItem = MenuItem->Next;
-    }
-  }
-  else
-  {
-    while(MenuItem)
-    {
-      if(!ret && (MenuItem->wID == uItem))
+      return TRUE;
+   }
+
+   if(fByPos)
+   {
+      UINT pos = 0;
+      while(MenuItem)
       {
-        if(!(MenuItem->fState & MFS_DEFAULT))
-          MenuItem->fState |= MFS_DEFAULT;
-        ret = TRUE;
+         if(pos == uItem)
+         {
+            if(!(MenuItem->fState & MFS_DEFAULT))
+               MenuItem->fState |= MFS_DEFAULT;
+            ret = TRUE;
+         }
+         else
+         {
+            if(MenuItem->fState & MFS_DEFAULT)
+               MenuItem->fState ^= MFS_DEFAULT;
+         }
+         pos++;
+         MenuItem = MenuItem->Next;
       }
-      else
+   }
+   else
+   {
+      while(MenuItem)
       {
-        if(MenuItem->fState & MFS_DEFAULT)
-          MenuItem->fState ^= MFS_DEFAULT;
+         if(!ret && (MenuItem->wID == uItem))
+         {
+            if(!(MenuItem->fState & MFS_DEFAULT))
+               MenuItem->fState |= MFS_DEFAULT;
+            ret = TRUE;
+         }
+         else
+         {
+            if(MenuItem->fState & MFS_DEFAULT)
+               MenuItem->fState ^= MFS_DEFAULT;
+         }
+         MenuItem = MenuItem->Next;
       }
-      MenuItem = MenuItem->Next;
-    }
-  }
-  return ret;
+   }
+   return ret;
 }
 
 
 UINT FASTCALL
 IntGetMenuDefaultItem(PMENU_OBJECT MenuObject, UINT fByPos, UINT gmdiFlags,
-  DWORD *gismc)
+                      DWORD *gismc)
 {
-  UINT x = 0;
-  UINT res = -1;
-  UINT sres;
-  PMENU_OBJECT SubMenuObject;
-  PMENU_ITEM MenuItem = MenuObject->MenuItemList;
-  
-  while(MenuItem)
-  {
-    if(MenuItem->fState & MFS_DEFAULT)
-    {
-
-      if(!(gmdiFlags & GMDI_USEDISABLED) && (MenuItem->fState & MFS_DISABLED))
-        break;
-        
-      if(fByPos & MF_BYPOSITION)
-        res = x;
-      else
-        res = MenuItem->wID;
-        
-      if((*gismc < MAX_GOINTOSUBMENU) && (gmdiFlags & GMDI_GOINTOPOPUPS) && 
-         MenuItem->hSubMenu)
+   UINT x = 0;
+   UINT res = -1;
+   UINT sres;
+   PMENU_OBJECT SubMenuObject;
+   PMENU_ITEM MenuItem = MenuObject->MenuItemList;
+
+   while(MenuItem)
+   {
+      if(MenuItem->fState & MFS_DEFAULT)
       {
-      
-        SubMenuObject = IntGetMenuObject(MenuItem->hSubMenu);
-        if(!SubMenuObject || (SubMenuObject == MenuObject))
-          break;
-          
-        ExAcquireFastMutexUnsafe(&SubMenuObject->MenuItemsLock);
-        ExReleaseFastMutexUnsafe(&MenuObject->MenuItemsLock);
-        
-        (*gismc)++;
-        sres = IntGetMenuDefaultItem(SubMenuObject, fByPos, gmdiFlags, gismc);
-        (*gismc)--;
-        
-        ExReleaseFastMutexUnsafe(&SubMenuObject->MenuItemsLock);
-        ExAcquireFastMutexUnsafe(&MenuObject->MenuItemsLock);
-        IntReleaseMenuObject(SubMenuObject);
-        
-        if(sres > (UINT)-1)
-          res = sres;
+
+         if(!(gmdiFlags & GMDI_USEDISABLED) && (MenuItem->fState & MFS_DISABLED))
+            break;
+
+         if(fByPos & MF_BYPOSITION)
+            res = x;
+         else
+            res = MenuItem->wID;
+
+         if((*gismc < MAX_GOINTOSUBMENU) && (gmdiFlags & GMDI_GOINTOPOPUPS) &&
+               MenuItem->hSubMenu)
+         {
+
+            SubMenuObject = UserGetMenuObject(MenuItem->hSubMenu);
+            if(!SubMenuObject || (SubMenuObject == MenuObject))
+               break;
+
+            (*gismc)++;
+            sres = IntGetMenuDefaultItem(SubMenuObject, fByPos, gmdiFlags, gismc);
+            (*gismc)--;
+
+            if(sres > (UINT)-1)
+               res = sres;
+         }
+
+         break;
       }
-      
-      break;
-    }
-    
-    MenuItem = MenuItem->Next;
-    x++;
-  }
-  
-  return res;
+
+      MenuItem = MenuItem->Next;
+      x++;
+   }
+
+   return res;
+}
+
+VOID FASTCALL
+co_IntInitTracking(PWINDOW_OBJECT Window, PMENU_OBJECT Menu, BOOL Popup,
+                   UINT Flags)
+{
+   /* FIXME - hide caret */
+
+   if(!(Flags & TPM_NONOTIFY))
+      co_IntSendMessage(Window->hSelf, WM_SETCURSOR, (WPARAM)Window->hSelf, HTCAPTION);
+
+   /* FIXME - send WM_SETCURSOR message */
+
+   if(!(Flags & TPM_NONOTIFY))
+      co_IntSendMessage(Window->hSelf, WM_INITMENU, (WPARAM)Menu->MenuInfo.Self, 0);
 }
 
+VOID FASTCALL
+co_IntExitTracking(PWINDOW_OBJECT Window, PMENU_OBJECT Menu, BOOL Popup,
+                   UINT Flags)
+{
+   if(!(Flags & TPM_NONOTIFY))
+      co_IntSendMessage(Window->hSelf, WM_EXITMENULOOP, 0 /* FIXME */, 0);
+
+   /* FIXME - Show caret again */
+}
+
+INT FASTCALL
+IntTrackMenu(PMENU_OBJECT Menu, PWINDOW_OBJECT Window, INT x, INT y,
+             RECT lprect)
+{
+   return 0;
+}
 
 BOOL FASTCALL
-IntTrackPopupMenu(PMENU_OBJECT MenuObject, PWINDOW_OBJECT WindowObject,
-                  UINT Flags, POINT *Pos, UINT MenuPos, RECT *ExcludeRect)
+co_IntTrackPopupMenu(PMENU_OBJECT Menu, PWINDOW_OBJECT Window,
+                     UINT Flags, POINT *Pos, UINT MenuPos, RECT *ExcludeRect)
 {
-  
-  return FALSE;
+   co_IntInitTracking(Window, Menu, TRUE, Flags);
+
+   co_IntExitTracking(Window, Menu, TRUE, Flags);
+   return FALSE;
+}
+
+BOOL FASTCALL
+IntSetMenuItemRect(PMENU_OBJECT Menu, UINT Item, BOOL fByPos, RECT *rcRect)
+{
+   PMENU_ITEM mi;
+   if(IntGetMenuItemByFlag(Menu, Item, (fByPos ? MF_BYPOSITION : MF_BYCOMMAND),
+                           &mi, NULL) > -1)
+   {
+      mi->Rect = *rcRect;
+      return TRUE;
+   }
+   return FALSE;
 }
 
 
@@ -1051,34 +1282,30 @@ IntTrackPopupMenu(PMENU_OBJECT MenuObject, PWINDOW_OBJECT WindowObject,
 BOOL FASTCALL
 IntCleanupMenus(struct _EPROCESS *Process, PW32PROCESS Win32Process)
 {
-  PEPROCESS CurrentProcess;
-  PLIST_ENTRY LastHead = NULL;
-  PMENU_OBJECT MenuObject;
-  
-  CurrentProcess = PsGetCurrentProcess();
-  if (CurrentProcess != Process)
-  {
-    KeAttachProcess(Process);
-  }
-  
-  ExAcquireFastMutexUnsafe(&Win32Process->MenuListLock); 
-  while (Win32Process->MenuListHead.Flink != &(Win32Process->MenuListHead) &&
-         Win32Process->MenuListHead.Flink != LastHead)
-  {
-    LastHead = Win32Process->MenuListHead.Flink;
-    MenuObject = CONTAINING_RECORD(Win32Process->MenuListHead.Flink, MENU_OBJECT, ListEntry);
-    
-    ExReleaseFastMutexUnsafe(&Win32Process->MenuListLock);
-    IntDestroyMenuObject(MenuObject, FALSE, TRUE);
-    ExAcquireFastMutexUnsafe(&Win32Process->MenuListLock); 
-  }
-  ExReleaseFastMutexUnsafe(&Win32Process->MenuListLock);
-  
-  if (CurrentProcess != Process)
-  {
-    KeDetachProcess();
-  }
-  return TRUE;
+   PEPROCESS CurrentProcess;
+   PLIST_ENTRY LastHead = NULL;
+   PMENU_OBJECT MenuObject;
+
+   CurrentProcess = PsGetCurrentProcess();
+   if (CurrentProcess != Process)
+   {
+      KeAttachProcess(&Process->Pcb);
+   }
+
+   while (Win32Process->MenuListHead.Flink != &(Win32Process->MenuListHead) &&
+          Win32Process->MenuListHead.Flink != LastHead)
+   {
+      LastHead = Win32Process->MenuListHead.Flink;
+      MenuObject = CONTAINING_RECORD(Win32Process->MenuListHead.Flink, MENU_OBJECT, ListEntry);
+
+      IntDestroyMenuObject(MenuObject, FALSE, TRUE);
+   }
+
+   if (CurrentProcess != Process)
+   {
+      KeDetachProcess();
+   }
+   return TRUE;
 }
 
 /* FUNCTIONS *****************************************************************/
@@ -1090,33 +1317,38 @@ IntCleanupMenus(struct _EPROCESS *Process, PW32PROCESS Win32Process)
 DWORD
 STDCALL
 NtUserBuildMenuItemList(
- HMENU hMenu,
- VOID* Buffer,
- ULONG nBufSize,
- DWORD Reserved)
  HMENU hMenu,
  VOID* Buffer,
  ULONG nBufSize,
  DWORD Reserved)
 {
-  DWORD res = -1;
-  PMENU_OBJECT MenuObject = IntGetMenuObject(hMenu);
-  if(!MenuObject)
-  {
-    SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
-    return (DWORD)-1;
-  }
-  
-  if(Buffer)
-  {
-    ExAcquireFastMutexUnsafe(&MenuObject->MenuItemsLock);
-    res = IntBuildMenuItemList(MenuObject, Buffer, nBufSize);
-    ExReleaseFastMutexUnsafe(&MenuObject->MenuItemsLock);
-  }
-  else
-  {
-    res = MenuObject->MenuItemCount;
-  }
-  
-  IntReleaseMenuObject(MenuObject);
-
-  return res;
+   DWORD res = -1;
+   PMENU_OBJECT Menu;
+   DECLARE_RETURN(DWORD);
+
+   DPRINT("Enter NtUserBuildMenuItemList\n");
+   UserEnterExclusive();
+
+   if(!(Menu = UserGetMenuObject(hMenu)))
+   {
+      RETURN( (DWORD)-1);
+   }
+
+   if(Buffer)
+   {
+      res = IntBuildMenuItemList(Menu, Buffer, nBufSize);
+   }
+   else
+   {
+      res = Menu->MenuInfo.MenuItemCount;
+   }
+
+   RETURN( res);
+
+CLEANUP:
+   DPRINT("Leave NtUserBuildMenuItemList, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
@@ -1125,104 +1357,155 @@ NtUserBuildMenuItemList(
  */
 DWORD STDCALL
 NtUserCheckMenuItem(
-  HMENU hmenu,
-  UINT uIDCheckItem,
-  UINT uCheck)
+   HMENU hMenu,
+   UINT uIDCheckItem,
+   UINT uCheck)
+{
+   PMENU_OBJECT Menu;
+   DECLARE_RETURN(DWORD);
+
+   DPRINT("Enter NtUserCheckMenuItem\n");
+   UserEnterExclusive();
+
+   if(!(Menu = UserGetMenuObject(hMenu)))
+   {
+      RETURN( (DWORD)-1);
+   }
+
+   RETURN( IntCheckMenuItem(Menu, uIDCheckItem, uCheck));
+
+CLEANUP:
+   DPRINT("Leave NtUserCheckMenuItem, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
+}
+
+
+HMENU FASTCALL UserCreateMenu(BOOL PopupMenu)
 {
-  DWORD res = 0;
-  PMENU_OBJECT MenuObject = IntGetMenuObject(hmenu);
-  if(!MenuObject)
-  {
-    SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
-    return (DWORD)-1;
-  }
-  ExAcquireFastMutexUnsafe(&MenuObject->MenuItemsLock);
-  res = IntCheckMenuItem(MenuObject, uIDCheckItem, uCheck);
-  ExReleaseFastMutexUnsafe(&MenuObject->MenuItemsLock);
-  IntReleaseMenuObject(MenuObject);
-  return res;
+   PWINSTATION_OBJECT WinStaObject;
+   HANDLE Handle;
+
+   NTSTATUS Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
+                     KernelMode,
+                     0,
+                     &WinStaObject);
+
+   if (!NT_SUCCESS(Status))
+   {
+      DPRINT("Validation of window station handle (0x%X) failed\n",
+             PsGetCurrentProcess()->Win32WindowStation);
+      SetLastNtError(Status);
+      return (HMENU)0;
+   }
+
+   IntCreateMenu(&Handle, !PopupMenu);
+
+   ObDereferenceObject(WinStaObject);
+   return (HMENU)Handle;
 }
 
 
-/*
- * @unimplemented
- */
+
 HMENU STDCALL
-NtUserCreateMenu(VOID)
+NtUserCreateMenu(BOOL PopupMenu)
 {
-  PWINSTATION_OBJECT WinStaObject;
-  HANDLE Handle;
-
-  NTSTATUS Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
-                                      KernelMode,
-                                      0,
-                                      &WinStaObject);
-                              
-  if (!NT_SUCCESS(Status))
-  {
-    DPRINT("Validation of window station handle (0x%X) failed\n",
-      PROCESS_WINDOW_STATION());
-    SetLastNtError(Status);
-    return (HMENU)0;
-  }
-
-  IntCreateMenu(&Handle);
-
-  ObDereferenceObject(WinStaObject);
-  return (HMENU)Handle;
+   DECLARE_RETURN(HMENU);
+
+   DPRINT("Enter NtUserCreateMenu\n");
+   UserEnterExclusive();
+
+   RETURN(UserCreateMenu(PopupMenu));
+
+CLEANUP:
+   DPRINT("Leave NtUserCreateMenu, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
+
 /*
  * @implemented
  */
 BOOL STDCALL
 NtUserDeleteMenu(
-  HMENU hMenu,
-  UINT uPosition,
-  UINT uFlags)
+   HMENU hMenu,
+   UINT uPosition,
+   UINT uFlags)
 {
-  BOOL res;
-  PMENU_OBJECT MenuObject = IntGetMenuObject(hMenu);
-  if(!MenuObject)
-  {
-    SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
-    return FALSE;
-  }
-
-  res = IntRemoveMenuItem(MenuObject, uPosition, uFlags, TRUE);
-  IntReleaseMenuObject(MenuObject);
-  
-  return res;
+   PMENU_OBJECT Menu;
+   DECLARE_RETURN(BOOL);
+
+   DPRINT("Enter NtUserDeleteMenu\n");
+   UserEnterExclusive();
+
+   if(!(Menu = UserGetMenuObject(hMenu)))
+   {
+      RETURN( FALSE);
+   }
+
+   RETURN( IntRemoveMenuItem(Menu, uPosition, uFlags, TRUE));
+
+CLEANUP:
+   DPRINT("Leave NtUserDeleteMenu, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
+
+/*
+ * @implemented
+ */
+BOOL FASTCALL UserDestroyMenu(HMENU hMenu)
+{
+   PMENU_OBJECT Menu;
+   
+   if(!(Menu = UserGetMenuObject(hMenu)))
+   {
+      return FALSE;
+   }
+   
+   if(Menu->Process != PsGetCurrentProcess())
+   {
+      SetLastWin32Error(ERROR_ACCESS_DENIED);
+      return FALSE;
+   }
+
+   return IntDestroyMenuObject(Menu, FALSE, TRUE);
+}
+
 /*
  * @implemented
  */
 BOOL STDCALL
 NtUserDestroyMenu(
-  HMENU hMenu)
+   HMENU hMenu)
 {
-  BOOL Ret;
-  
-  PMENU_OBJECT MenuObject = IntGetMenuObject(hMenu);
-  if(!MenuObject)
-  {
-    SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
-    return FALSE;
-  }
-  if(MenuObject->W32Process != PsGetWin32Process())
-  {
-    IntReleaseMenuObject(MenuObject);
-    SetLastWin32Error(ERROR_ACCESS_DENIED);
-    return FALSE;
-  }
-
-  Ret = IntDestroyMenuObject(MenuObject, FALSE, TRUE);
-  
-  IntReleaseMenuObject(MenuObject);
-  return Ret;
+   PMENU_OBJECT Menu;
+   DECLARE_RETURN(BOOL);
+
+   DPRINT("Enter NtUserDestroyMenu\n");
+   UserEnterExclusive();
+
+   if(!(Menu = UserGetMenuObject(hMenu)))
+   {
+      RETURN( FALSE);
+   }
+   
+   if(Menu->Process != PsGetCurrentProcess())
+   {
+      SetLastWin32Error(ERROR_ACCESS_DENIED);
+      RETURN( FALSE);
+   }
+
+   RETURN( IntDestroyMenuObject(Menu, FALSE, TRUE));
+
+CLEANUP:
+   DPRINT("Leave NtUserDestroyMenu, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
@@ -1231,24 +1514,27 @@ NtUserDestroyMenu(
  */
 UINT STDCALL
 NtUserEnableMenuItem(
-  HMENU hMenu,
-  UINT uIDEnableItem,
-  UINT uEnable)
+   HMENU hMenu,
+   UINT uIDEnableItem,
+   UINT uEnable)
 {
-  UINT res = (UINT)-1;
-  PMENU_OBJECT MenuObject;
-  MenuObject = IntGetMenuObject(hMenu);
-  if(!MenuObject)
-  {
-    SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
-    return res;
-  }
-  ExAcquireFastMutexUnsafe(&MenuObject->MenuItemsLock);
-  res = IntEnableMenuItem(MenuObject, uIDEnableItem, uEnable);
-  ExReleaseFastMutexUnsafe(&MenuObject->MenuItemsLock);
-  IntReleaseMenuObject(MenuObject);
-
-  return res;
+   PMENU_OBJECT Menu;
+   DECLARE_RETURN(UINT);
+
+   DPRINT("Enter NtUserEnableMenuItem\n");
+   UserEnterExclusive();
+
+   if(!(Menu = UserGetMenuObject(hMenu)))
+   {
+      RETURN(-1);
+   }
+
+   RETURN( IntEnableMenuItem(Menu, uIDEnableItem, uEnable));
+
+CLEANUP:
+   DPRINT("Leave NtUserEnableMenuItem, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
@@ -1257,24 +1543,57 @@ NtUserEnableMenuItem(
  */
 DWORD STDCALL
 NtUserInsertMenuItem(
-  HMENU hMenu,
-  UINT uItem,
-  WINBOOL fByPosition,
-  LPCMENUITEMINFOW lpmii)
+   HMENU hMenu,
+   UINT uItem,
+   BOOL fByPosition,
+   LPCMENUITEMINFOW UnsafeItemInfo)
 {
-  DWORD res = 0;
-  PMENU_OBJECT MenuObject;
-  MenuObject = IntGetMenuObject(hMenu);
-  if(!MenuObject)
-  {
-    SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
-    return 0;
-  }
-  ExAcquireFastMutexUnsafe(&MenuObject->MenuItemsLock);
-  res = IntInsertMenuItem(MenuObject, uItem, fByPosition, lpmii);
-  ExReleaseFastMutexUnsafe(&MenuObject->MenuItemsLock);
-  IntReleaseMenuObject(MenuObject);
-  return res;
+   PMENU_OBJECT Menu;
+   NTSTATUS Status;
+   ROSMENUITEMINFO ItemInfo;
+   DECLARE_RETURN(DWORD);
+
+   DPRINT("Enter NtUserInsertMenuItem\n");
+   UserEnterExclusive();
+
+   if(!(Menu = UserGetMenuObject(hMenu)))
+   {
+      RETURN( FALSE);
+   }
+
+   /* Try to copy the whole MENUITEMINFOW structure */
+   Status = MmCopyFromCaller(&ItemInfo, UnsafeItemInfo, sizeof(MENUITEMINFOW));
+   if (NT_SUCCESS(Status))
+   {
+      if (sizeof(MENUITEMINFOW) != ItemInfo.cbSize
+         && FIELD_OFFSET(MENUITEMINFOW, hbmpItem) != ItemInfo.cbSize)
+      {
+         SetLastWin32Error(ERROR_INVALID_PARAMETER);
+         RETURN( FALSE);
+      }
+      RETURN( IntInsertMenuItem(Menu, uItem, fByPosition, &ItemInfo));
+   }
+
+   /* Try to copy without last field (not present in older versions) */
+   Status = MmCopyFromCaller(&ItemInfo, UnsafeItemInfo, FIELD_OFFSET(MENUITEMINFOW, hbmpItem));
+   if (NT_SUCCESS(Status))
+   {
+      if (FIELD_OFFSET(MENUITEMINFOW, hbmpItem) != ItemInfo.cbSize)
+      {
+         SetLastWin32Error(ERROR_INVALID_PARAMETER);
+         RETURN( FALSE);
+      }
+      ItemInfo.hbmpItem = (HBITMAP)0;
+      RETURN( IntInsertMenuItem(Menu, uItem, fByPosition, &ItemInfo));
+   }
+
+   SetLastNtError(Status);
+   RETURN( FALSE);
+
+CLEANUP:
+   DPRINT("Leave NtUserInsertMenuItem, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
@@ -1284,9 +1603,9 @@ NtUserInsertMenuItem(
 BOOL STDCALL
 NtUserEndMenu(VOID)
 {
-  UNIMPLEMENTED
-  
-  return 0;
+   UNIMPLEMENTED
+
+   return 0;
 }
 
 
@@ -1295,40 +1614,244 @@ NtUserEndMenu(VOID)
  */
 UINT STDCALL
 NtUserGetMenuDefaultItem(
-  HMENU hMenu,
-  UINT fByPos,
-  UINT gmdiFlags)
+   HMENU hMenu,
+   UINT fByPos,
+   UINT gmdiFlags)
 {
-  PMENU_OBJECT MenuObject;
-  UINT res = -1;
-  DWORD gismc = 0;
-  MenuObject = IntGetMenuObject(hMenu);
-  if(!MenuObject)
-  {
-    SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
-    return res;
-  }
-  ExAcquireFastMutexUnsafe(&MenuObject->MenuItemsLock);
-  res = IntGetMenuDefaultItem(MenuObject, fByPos, gmdiFlags, &gismc);
-  ExReleaseFastMutexUnsafe(&MenuObject->MenuItemsLock);
-  IntReleaseMenuObject(MenuObject);
-  return res;
+   PMENU_OBJECT Menu;
+   DWORD gismc = 0;
+   DECLARE_RETURN(UINT);
+
+   DPRINT("Enter NtUserGetMenuDefaultItem\n");
+   UserEnterExclusive();
+
+   if(!(Menu = UserGetMenuObject(hMenu)))
+   {
+      RETURN(-1);
+   }
+
+   RETURN( IntGetMenuDefaultItem(Menu, fByPos, gmdiFlags, &gismc));
+
+CLEANUP:
+   DPRINT("Leave NtUserGetMenuDefaultItem, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL STDCALL
 NtUserGetMenuBarInfo(
-  HWND hwnd,
-  LONG idObject,
-  LONG idItem,
-  PMENUBARINFO pmbi)
+   HWND hwnd,
+   LONG idObject,
+   LONG idItem,
+   PMENUBARINFO pmbi)
 {
-  UNIMPLEMENTED
-
-  return 0;
+   BOOL Res = TRUE;
+   PMENU_OBJECT MenuObject;
+   PMENU_ITEM mi;
+   PWINDOW_OBJECT WindowObject;
+   HMENU hMenu;
+   POINT Offset;
+   RECT Rect;
+   MENUBARINFO kmbi;
+   DECLARE_RETURN(BOOL);
+  
+   DPRINT("Enter NtUserGetMenuBarInfo\n");
+   UserEnterShared();
+  
+   if (!(WindowObject = UserGetWindowObject(hwnd)))
+     {
+        SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+        RETURN(FALSE);
+     }
+
+   hMenu = (HMENU)WindowObject->IDMenu;
+
+   if (!(MenuObject = UserGetMenuObject(hMenu)))
+     {
+       SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
+       RETURN(FALSE);
+     }
+
+   if (pmbi->cbSize != sizeof(MENUBARINFO))
+     {
+       SetLastWin32Error(ERROR_INVALID_PARAMETER);
+       RETURN(FALSE);
+     }
+
+   kmbi.cbSize = sizeof(MENUBARINFO);
+   kmbi.fBarFocused = FALSE;
+   kmbi.fFocused = FALSE;
+   kmbi.hwndMenu = NULL;
+   
+   switch (idObject)
+   {
+      case OBJID_MENU:
+      {
+         PMENU_OBJECT SubMenuObject;
+         kmbi.hMenu = hMenu;
+         if (idItem) /* Non-Zero-Based. */
+           {
+              if (IntGetMenuItemByFlag(MenuObject, idItem-1, MF_BYPOSITION, &mi, NULL) > -1)
+                   kmbi.rcBar = mi->Rect;
+              else
+                {
+                   Res = FALSE;
+                   break;
+                }
+           }
+         else
+           {  
+              /* If items is zero we assume info for the menu itself. */
+              if (!(IntGetClientOrigin(WindowObject, &Offset)))
+                {
+                   Res = FALSE;
+                   break;
+                }
+              Rect.left = Offset.x;
+              Rect.right = Offset.x + MenuObject->MenuInfo.Width;
+              Rect.top = Offset.y;
+              Rect.bottom = Offset.y + MenuObject->MenuInfo.Height;
+              kmbi.rcBar = Rect;
+              DPRINT("Rect top = %d bottom = %d left = %d right = %d \n",
+                       Rect.top, Rect.bottom, Rect.left, Rect.right);
+           }
+         if (idItem)
+           {
+              if (idItem-1 == MenuObject->MenuInfo.FocusedItem)
+                    kmbi.fFocused = TRUE;
+           }
+         if (MenuObject->MenuInfo.FocusedItem != NO_SELECTED_ITEM)
+               kmbi.fBarFocused = TRUE;
+         SubMenuObject = UserGetMenuObject(MenuObject->MenuItemList->hSubMenu);
+         if(SubMenuObject) kmbi.hwndMenu = SubMenuObject->MenuInfo.Wnd;
+         DPRINT("OBJID_MENU, idItem = %d\n",idItem);
+         break;
+      }
+      case OBJID_CLIENT:
+      {
+         PMENU_OBJECT SubMenuObject, XSubMenuObject;
+         SubMenuObject = UserGetMenuObject(MenuObject->MenuItemList->hSubMenu);
+         if(SubMenuObject) kmbi.hMenu = SubMenuObject->MenuInfo.Self;
+         else
+           {
+              Res = FALSE;
+              DPRINT1("OBJID_CLIENT, No SubMenu!\n");
+              break;
+           }
+         if (idItem)
+           {
+              if (IntGetMenuItemByFlag(SubMenuObject, idItem-1, MF_BYPOSITION, &mi, NULL) > -1)
+                   kmbi.rcBar = mi->Rect;
+              else
+                {
+                   Res = FALSE;
+                   break;
+                }
+           }
+         else
+           {
+              PWINDOW_OBJECT SubWinObj;
+              if (!(SubWinObj = UserGetWindowObject(SubMenuObject->MenuInfo.Wnd)))
+                {
+                   Res = FALSE;
+                   break;
+                }
+              if (!(IntGetClientOrigin(SubWinObj, &Offset)))
+                {
+                   Res = FALSE;
+                   break;
+                }
+              Rect.left = Offset.x;
+              Rect.right = Offset.x + SubMenuObject->MenuInfo.Width;
+              Rect.top = Offset.y;
+              Rect.bottom = Offset.y + SubMenuObject->MenuInfo.Height;
+              kmbi.rcBar = Rect;
+           }
+         if (idItem)
+           {
+              if (idItem-1 == SubMenuObject->MenuInfo.FocusedItem)
+                   kmbi.fFocused = TRUE;
+           }
+         if (SubMenuObject->MenuInfo.FocusedItem != NO_SELECTED_ITEM)
+               kmbi.fBarFocused = TRUE;
+         XSubMenuObject = UserGetMenuObject(SubMenuObject->MenuItemList->hSubMenu);
+         if (XSubMenuObject) kmbi.hwndMenu = XSubMenuObject->MenuInfo.Wnd;
+         DPRINT("OBJID_CLIENT, idItem = %d\n",idItem);
+         break;
+      }
+      case OBJID_SYSMENU:
+      {
+         PMENU_OBJECT SysMenuObject, SubMenuObject;
+         if(!(SysMenuObject = IntGetSystemMenu(WindowObject, FALSE, FALSE)))
+         {
+           Res = FALSE;
+           break;
+         }
+         kmbi.hMenu = SysMenuObject->MenuInfo.Self;
+         if (idItem)
+           {
+              if (IntGetMenuItemByFlag(SysMenuObject, idItem-1, MF_BYPOSITION, &mi, NULL) > -1)
+                   kmbi.rcBar = mi->Rect;
+              else
+                {
+                   Res = FALSE;
+                   break;
+                }
+           }
+         else
+           {
+              PWINDOW_OBJECT SysWinObj;
+              if (!(SysWinObj = UserGetWindowObject(SysMenuObject->MenuInfo.Wnd)))
+                {
+                   Res = FALSE;
+                   break;
+                }
+              if (!(IntGetClientOrigin(SysWinObj, &Offset)))
+                {
+                   Res = FALSE;
+                   break;
+                }
+              Rect.left = Offset.x;
+              Rect.right = Offset.x + SysMenuObject->MenuInfo.Width;
+              Rect.top = Offset.y;
+              Rect.bottom = Offset.y + SysMenuObject->MenuInfo.Height;
+              kmbi.rcBar = Rect;
+           }
+         if (idItem)
+           {
+              if (idItem-1 == SysMenuObject->MenuInfo.FocusedItem)
+                    kmbi.fFocused = TRUE;
+           }
+         if (SysMenuObject->MenuInfo.FocusedItem != NO_SELECTED_ITEM)
+               kmbi.fBarFocused = TRUE;
+         SubMenuObject = UserGetMenuObject(SysMenuObject->MenuItemList->hSubMenu);
+         if(SubMenuObject) kmbi.hwndMenu = SubMenuObject->MenuInfo.Wnd;
+         DPRINT("OBJID_SYSMENU, idItem = %d\n",idItem);
+         break;
+      }
+      default:
+         Res = FALSE;
+         DPRINT1("Unknown idObject = %d, idItem = %d\n",idObject,idItem);
+   }
+   if (Res)
+     {
+        NTSTATUS Status = MmCopyToCaller(pmbi, &kmbi, sizeof(MENUBARINFO));
+        if (! NT_SUCCESS(Status))
+          {
+            SetLastNtError(Status);
+            RETURN(FALSE);
+          }
+     }
+   RETURN(Res);
+
+CLEANUP:
+   DPRINT("Leave NtUserGetMenuBarInfo, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;  
 }
 
 
@@ -1337,28 +1860,72 @@ NtUserGetMenuBarInfo(
  */
 UINT STDCALL
 NtUserGetMenuIndex(
-  HMENU hMenu,
-  UINT wID)
+   HMENU hMenu,
+   UINT wID)
 {
-  UNIMPLEMENTED
+   UNIMPLEMENTED
 
-  return 0;
+   return 0;
 }
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL STDCALL
 NtUserGetMenuItemRect(
-  HWND hWnd,
-  HMENU hMenu,
-  UINT uItem,
-  LPRECT lprcItem)
+   HWND hWnd,
+   HMENU hMenu,
+   UINT uItem,
+   LPRECT lprcItem)
 {
-  UNIMPLEMENTED
-
-  return 0;
+   ROSMENUINFO mi;
+   HWND referenceHwnd;
+   RECT Rect;
+   NTSTATUS Status;
+   PMENU_OBJECT Menu;
+   PMENU_ITEM MenuItem;
+   DECLARE_RETURN(BOOL);
+
+   DPRINT("Enter NtUserGetMenuItemRect\n");
+   UserEnterShared();
+
+   if (!(Menu = UserGetMenuObject(hMenu)))
+   {
+      RETURN(FALSE);
+   }
+
+   if (IntGetMenuItemByFlag(Menu, uItem, MF_BYPOSITION, &MenuItem, NULL) > -1)
+        Rect = MenuItem->Rect;
+   else
+      RETURN(FALSE);
+   
+   referenceHwnd = hWnd;
+   
+   if(!hWnd)
+   {
+      if(!UserMenuInfo(Menu, &mi, FALSE))
+         RETURN( FALSE);
+      if(mi.Wnd == 0)
+         RETURN( FALSE);
+      referenceHwnd = mi.Wnd; /* Okay we found it, so now what do we do? */
+   }
+
+   if (lprcItem == NULL)
+      RETURN( FALSE);
+
+   Status = MmCopyToCaller(lprcItem, &Rect, sizeof(RECT));
+   if (! NT_SUCCESS(Status))
+   {
+      SetLastNtError(Status);
+      RETURN( FALSE);
+   }
+   RETURN( TRUE);
+
+CLEANUP:
+   DPRINT("Leave NtUserGetMenuItemRect, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
@@ -1367,142 +1934,286 @@ NtUserGetMenuItemRect(
  */
 BOOL STDCALL
 NtUserHiliteMenuItem(
-  HWND hwnd,
-  HMENU hmenu,
-  UINT uItemHilite,
-  UINT uHilite)
+   HWND hWnd,
+   HMENU hMenu,
+   UINT uItemHilite,
+   UINT uHilite)
 {
-  BOOL res = FALSE;
-  PMENU_OBJECT MenuObject;
-  PWINDOW_OBJECT WindowObject = IntGetWindowObject(hwnd);
-  if(!WindowObject)
-  {
-    SetLastWin32Error(ERROR_INVALID_HANDLE);
-    return res;
-  }
-  MenuObject = IntGetMenuObject(hmenu);
-  if(!MenuObject)
-  {
-    IntReleaseWindowObject(WindowObject);
-    SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
-    return res;
-  }
-  if(WindowObject->IDMenu == (UINT)hmenu)
-  {
-    ExAcquireFastMutexUnsafe(&MenuObject->MenuItemsLock);
-    res = IntHiliteMenuItem(WindowObject, MenuObject, uItemHilite, uHilite);
-    ExReleaseFastMutexUnsafe(&MenuObject->MenuItemsLock);
-  }
-  IntReleaseMenuObject(MenuObject);
-  IntReleaseWindowObject(WindowObject);
-  return res;
+   PMENU_OBJECT Menu;
+   PWINDOW_OBJECT Window;
+   DECLARE_RETURN(BOOLEAN);
+
+   DPRINT("Enter NtUserHiliteMenuItem\n");
+   UserEnterExclusive();
+
+   if(!(Window = UserGetWindowObject(hWnd)))
+   {
+      RETURN(FALSE);
+   }
+   
+   if(!(Menu = UserGetMenuObject(hMenu)))
+   {
+      RETURN(FALSE);
+   }
+   
+   if(Window->IDMenu == (UINT)hMenu)
+   {
+      RETURN( IntHiliteMenuItem(Window, Menu, uItemHilite, uHilite));
+   }
+
+   RETURN(FALSE);
+
+CLEANUP:
+   DPRINT("Leave NtUserHiliteMenuItem, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
+static
+BOOL FASTCALL
+UserMenuInfo(
+   PMENU_OBJECT Menu,
+   PROSMENUINFO UnsafeMenuInfo,
+   BOOL SetOrGet)
+{
+   BOOL Res;
+   DWORD Size;
+   NTSTATUS Status;
+   ROSMENUINFO MenuInfo;
+
+   Status = MmCopyFromCaller(&Size, &UnsafeMenuInfo->cbSize, sizeof(DWORD));
+   if (! NT_SUCCESS(Status))
+   {
+      SetLastNtError(Status);
+      return( FALSE);
+   }
+   if(Size < sizeof(MENUINFO) || sizeof(ROSMENUINFO) < Size)
+   {
+      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      return( FALSE);
+   }
+   Status = MmCopyFromCaller(&MenuInfo, UnsafeMenuInfo, Size);
+   if (! NT_SUCCESS(Status))
+   {
+      SetLastNtError(Status);
+      return( FALSE);
+   }
+
+   if(SetOrGet)
+   {
+      /* Set MenuInfo */
+      Res = IntSetMenuInfo(Menu, &MenuInfo);
+   }
+   else
+   {
+      /* Get MenuInfo */
+      Res = IntGetMenuInfo(Menu, &MenuInfo);
+      if (Res)
+      {
+         Status = MmCopyToCaller(UnsafeMenuInfo, &MenuInfo, Size);
+         if (! NT_SUCCESS(Status))
+         {
+            SetLastNtError(Status);
+            return( FALSE);
+         }
+      }
+   }
+
+   return( Res);
+}
+
+
+
+
+
 /*
  * @implemented
  */
 BOOL
 STDCALL
 NtUserMenuInfo(
HMENU hmenu,
LPMENUINFO lpmi,
BOOL fsog)
  HMENU hMenu,
  PROSMENUINFO UnsafeMenuInfo,
  BOOL SetOrGet)
 {
-  BOOL res = FALSE;
-  PMENU_OBJECT MenuObject;
-  
-  if(lpmi->cbSize != sizeof(MENUINFO))
-  {
-    /* FIXME - Set Last Error */
-    return FALSE;
-  }
-  MenuObject = IntGetMenuObject(hmenu);
-  if(!MenuObject)
-  {
-    SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
-    return FALSE;
-  }  
-  if(fsog)
-  {
-    /* Set MenuInfo */
-    res = IntSetMenuInfo(MenuObject, lpmi);  
-  }
-  else
-  {
-    /* Get MenuInfo */
-    res = IntGetMenuInfo(MenuObject, lpmi);
-  }  
-  IntReleaseMenuObject(MenuObject);
-  return res;
+   PMENU_OBJECT Menu;
+   DECLARE_RETURN(BOOL);
+
+   DPRINT("Enter NtUserMenuInfo\n");
+   UserEnterShared();
+
+   if (!(Menu = UserGetMenuObject(hMenu)))
+   {
+      RETURN(FALSE);
+   }
+
+   RETURN(UserMenuInfo(Menu, UnsafeMenuInfo, SetOrGet));
+
+CLEANUP:
+   DPRINT("Leave NtUserMenuInfo, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
+
 /*
- * @unimplemented
+ * @implemented
  */
 int STDCALL
 NtUserMenuItemFromPoint(
-  HWND hWnd,
-  HMENU hMenu,
-  DWORD X,
-  DWORD Y)
+   HWND hWnd,
+   HMENU hMenu,
+   DWORD X,
+   DWORD Y)
 {
-  UNIMPLEMENTED
+   PMENU_OBJECT Menu;
+   PWINDOW_OBJECT Window = NULL;
+   PMENU_ITEM mi;
+   int i;
+   DECLARE_RETURN(int);
+
+   DPRINT("Enter NtUserMenuItemFromPoint\n");
+   UserEnterExclusive();
+
+   if (!(Menu = UserGetMenuObject(hMenu)))
+   {
+      RETURN( -1);
+   }
+
+   if (!(Window = UserGetWindowObject(Menu->MenuInfo.Wnd)))
+   {
+      RETURN( -1);
+   }
+
+   X -= Window->WindowRect.left;
+   Y -= Window->WindowRect.top;
+
+   mi = Menu->MenuItemList;
+   for (i = 0; NULL != mi; i++)
+   {
+      if (InRect(mi->Rect, X, Y))
+      {
+         break;
+      }
+      mi = mi->Next;
+   }
+
+   RETURN( (mi ? i : NO_SELECTED_ITEM));
 
-  return 0;
+CLEANUP:
+   DPRINT("Leave NtUserMenuItemFromPoint, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
+
+static
+BOOL FASTCALL
+UserMenuItemInfo(
+   PMENU_OBJECT Menu,
+   UINT Item,
+   BOOL ByPosition,
+   PROSMENUITEMINFO UnsafeItemInfo,
+   BOOL SetOrGet)
+{
+   PMENU_ITEM MenuItem;
+   ROSMENUITEMINFO ItemInfo;
+   NTSTATUS Status;
+   UINT Size;
+   BOOL Ret;
+
+   Status = MmCopyFromCaller(&Size, &UnsafeItemInfo->cbSize, sizeof(UINT));
+   if (! NT_SUCCESS(Status))
+   {
+      SetLastNtError(Status);
+      return( FALSE);
+   }
+   if (sizeof(MENUITEMINFOW) != Size
+         && FIELD_OFFSET(MENUITEMINFOW, hbmpItem) != Size
+         && sizeof(ROSMENUITEMINFO) != Size)
+   {
+      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      return( FALSE);
+   }
+   Status = MmCopyFromCaller(&ItemInfo, UnsafeItemInfo, Size);
+   if (! NT_SUCCESS(Status))
+   {
+      SetLastNtError(Status);
+      return( FALSE);
+   }
+   /* If this is a pre-0x0500 _WIN32_WINNT MENUITEMINFOW, you can't
+      set/get hbmpItem */
+   if (FIELD_OFFSET(MENUITEMINFOW, hbmpItem) == Size
+         && 0 != (ItemInfo.fMask & MIIM_BITMAP))
+   {
+      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      return( FALSE);
+   }
+
+   if (IntGetMenuItemByFlag(Menu, Item,
+                            (ByPosition ? MF_BYPOSITION : MF_BYCOMMAND),
+                            &MenuItem, NULL) < 0)
+   {
+      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      return( FALSE);
+   }
+
+   if (SetOrGet)
+   {
+      Ret = IntSetMenuItemInfo(Menu, MenuItem, &ItemInfo);
+   }
+   else
+   {
+      Ret = IntGetMenuItemInfo(Menu, MenuItem, &ItemInfo);
+      if (Ret)
+      {
+         Status = MmCopyToCaller(UnsafeItemInfo, &ItemInfo, Size);
+         if (! NT_SUCCESS(Status))
+         {
+            SetLastNtError(Status);
+            return( FALSE);
+         }
+      }
+   }
+
+   return( Ret);
+}
+
+
+
 /*
  * @implemented
  */
 BOOL
 STDCALL
 NtUserMenuItemInfo(
- HMENU hMenu,
UINT uItem,
BOOL fByPosition,
LPMENUITEMINFOW lpmii,
BOOL fsog)
  HMENU hMenu,
  UINT Item,
  BOOL ByPosition,
  PROSMENUITEMINFO UnsafeItemInfo,
  BOOL SetOrGet)
 {
-  PMENU_OBJECT MenuObject;
-  PMENU_ITEM MenuItem;
-  MENUITEMINFOW Safemii;
-  NTSTATUS Status;
-  
-  MenuObject = IntGetMenuObject(hMenu);
-  if(!MenuObject)
-  {
-    SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
-    return FALSE;
-  }
-
-  if(fsog)
-  {
-    /* Set menu item info */
-  }
-  else
-  {
-    if((IntGetMenuItemByFlag(MenuObject, uItem, (fByPosition ? MF_BYPOSITION : MF_BYCOMMAND), 
-                            &MenuItem, NULL) > -1) &&
-       IntGetMenuItemInfo(MenuObject, MenuItem, &Safemii))
-    {
-      Status = MmCopyToCaller(lpmii, &Safemii, sizeof(MENUITEMINFOW));
-      if(!NT_SUCCESS(Status))
-      {
-        IntReleaseMenuObject(MenuObject);
-        SetLastNtError(Status);
-        return FALSE;
-      }
-      
-      IntReleaseMenuObject(MenuObject);
-      return TRUE;
-    }
-  }
-  
-  IntReleaseMenuObject(MenuObject);
-  return FALSE;
+   PMENU_OBJECT Menu;
+   DECLARE_RETURN(BOOL);
+
+   DPRINT("Enter NtUserMenuItemInfo\n");
+   UserEnterExclusive();
+
+   if (!(Menu = UserGetMenuObject(hMenu)))
+   {
+      RETURN(FALSE);
+   }
+
+   RETURN( UserMenuItemInfo(Menu, Item, ByPosition, UnsafeItemInfo, SetOrGet));
+
+CLEANUP:
+   DPRINT("Leave NtUserMenuItemInfo, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
+
 }
 
 
@@ -1511,22 +2222,28 @@ NtUserMenuItemInfo(
  */
 BOOL STDCALL
 NtUserRemoveMenu(
-  HMENU hMenu,
-  UINT uPosition,
-  UINT uFlags)
+   HMENU hMenu,
+   UINT uPosition,
+   UINT uFlags)
 {
-  BOOL res;
-  PMENU_OBJECT MenuObject = IntGetMenuObject(hMenu);
-  if(!MenuObject)
-  {
-    SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
-    return FALSE;
-  }
-
-  res = IntRemoveMenuItem(MenuObject, uPosition, uFlags, FALSE);
-  IntReleaseMenuObject(MenuObject);
-  
-  return res;
+   PMENU_OBJECT Menu;
+   DECLARE_RETURN(BOOL);
+
+   DPRINT("Enter NtUserRemoveMenu\n");
+   UserEnterExclusive();
+
+   if(!(Menu = UserGetMenuObject(hMenu)))
+   {
+      RETURN( FALSE);
+   }
+
+   RETURN(IntRemoveMenuItem(Menu, uPosition, uFlags, FALSE));
+
+CLEANUP:
+   DPRINT("Leave NtUserRemoveMenu, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
+
 }
 
 
@@ -1535,46 +2252,56 @@ NtUserRemoveMenu(
  */
 BOOL STDCALL
 NtUserSetMenuContextHelpId(
-  HMENU hmenu,
-  DWORD dwContextHelpId)
+   HMENU hMenu,
+   DWORD dwContextHelpId)
 {
-  BOOL res;
-  PMENU_OBJECT MenuObject = IntGetMenuObject(hmenu);
-  if(!MenuObject)
-  {
-    SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
-    return FALSE;
-  }
-
-  res = IntSetMenuContextHelpId(MenuObject, dwContextHelpId);
-  IntReleaseMenuObject(MenuObject);
-  return res;
+   PMENU_OBJECT Menu;
+   DECLARE_RETURN(BOOL);
+
+   DPRINT("Enter NtUserSetMenuContextHelpId\n");
+   UserEnterExclusive();
+
+   if(!(Menu = UserGetMenuObject(hMenu)))
+   {
+      RETURN( FALSE);
+   }
+
+   RETURN(IntSetMenuContextHelpId(Menu, dwContextHelpId));
+
+CLEANUP:
+   DPRINT("Leave NtUserSetMenuContextHelpId, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
+
 /*
  * @implemented
  */
 BOOL STDCALL
 NtUserSetMenuDefaultItem(
-  HMENU hMenu,
-  UINT uItem,
-  UINT fByPos)
+   HMENU hMenu,
+   UINT uItem,
+   UINT fByPos)
 {
-  BOOL res = FALSE;
-  PMENU_OBJECT MenuObject;
-  MenuObject = IntGetMenuObject(hMenu);
-  if(!MenuObject)
-  {
-    SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
-    return FALSE;
-  }
-  ExAcquireFastMutexUnsafe(&MenuObject->MenuItemsLock);
-  res = IntSetMenuDefaultItem(MenuObject, uItem, fByPos);
-  ExReleaseFastMutexUnsafe(&MenuObject->MenuItemsLock);
-  IntReleaseMenuObject(MenuObject);
-
-  return res;
+   PMENU_OBJECT Menu;
+   DECLARE_RETURN(BOOL);
+
+   DPRINT("Enter NtUserSetMenuDefaultItem\n");
+   UserEnterExclusive();
+
+   if(!(Menu = UserGetMenuObject(hMenu)))
+   {
+      RETURN( FALSE);
+   }
+
+   RETURN( UserSetMenuDefaultItem(Menu, uItem, fByPos));
+
+CLEANUP:
+   DPRINT("Leave NtUserSetMenuDefaultItem, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
@@ -1583,19 +2310,25 @@ NtUserSetMenuDefaultItem(
  */
 BOOL STDCALL
 NtUserSetMenuFlagRtoL(
-  HMENU hMenu)
+   HMENU hMenu)
 {
-  BOOL res;
-  PMENU_OBJECT MenuObject = IntGetMenuObject(hMenu);
-  if(!MenuObject)
-  {
-    SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
-    return FALSE;
-  }
-
-  res = IntSetMenuFlagRtoL(MenuObject);
-  IntReleaseMenuObject(MenuObject);
-  return res;
+   PMENU_OBJECT Menu;
+   DECLARE_RETURN(BOOL);
+
+   DPRINT("Enter NtUserSetMenuFlagRtoL\n");
+   UserEnterExclusive();
+
+   if(!(Menu = UserGetMenuObject(hMenu)))
+   {
+      RETURN( FALSE);
+   }
+
+   RETURN(IntSetMenuFlagRtoL(Menu));
+
+CLEANUP:
+   DPRINT("Leave NtUserSetMenuFlagRtoL, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
@@ -1604,12 +2337,12 @@ NtUserSetMenuFlagRtoL(
  */
 DWORD STDCALL
 NtUserThunkedMenuInfo(
-  HMENU hMenu,
-  LPCMENUINFO lpcmi)
+   HMENU hMenu,
+   LPCMENUINFO lpcmi)
 {
-  UNIMPLEMENTED
-  /* This function seems just to call SetMenuInfo() */
-  return 0;
+   UNIMPLEMENTED
+   /* This function seems just to call SetMenuInfo() */
+   return 0;
 }
 
 
@@ -1618,84 +2351,37 @@ NtUserThunkedMenuInfo(
  */
 DWORD STDCALL
 NtUserThunkedMenuItemInfo(
-  HMENU hMenu,
-  UINT uItem,
-  BOOL fByPosition,
-  BOOL bInsert,
-  LPMENUITEMINFOW lpmii,
-  PUNICODE_STRING lpszCaption)
+   HMENU hMenu,
+   UINT uItem,
+   BOOL fByPosition,
+   BOOL bInsert,
+   LPMENUITEMINFOW lpmii,
+   PUNICODE_STRING lpszCaption)
 {
-  UNIMPLEMENTED
-  /* lpszCaption may be NULL, check for it and call RtlInitUnicodeString()
-     if bInsert == TRUE call NtUserInsertMenuItem() else NtUserSetMenuItemInfo()
-  */
-  return 0;
+   UNIMPLEMENTED
+   /* lpszCaption may be NULL, check for it and call RtlInitUnicodeString()
+      if bInsert == TRUE call NtUserInsertMenuItem() else NtUserSetMenuItemInfo()
+   */
+   return 0;
 }
 
 
 /*
  * @implemented
  */
+/* NOTE: unused function */
 BOOL STDCALL
 NtUserTrackPopupMenuEx(
-  HMENU hmenu,
-  UINT fuFlags,
-  int x,
-  int y,
-  HWND hwnd,
-  LPTPMPARAMS lptpm)
+   HMENU hMenu,
+   UINT fuFlags,
+   int x,
+   int y,
+   HWND hWnd,
+   LPTPMPARAMS lptpm)
 {
-  PMENU_OBJECT MenuObject;
-  PWINDOW_OBJECT WindowObject;
-  TPMPARAMS Safetpm;
-  NTSTATUS Status;
-  POINT Pos;
-  BOOL Ret;
-  
-  MenuObject = IntGetMenuObject(hmenu);
-  if(!MenuObject)
-  {
-    SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
-    return FALSE;
-  }
-  
-  WindowObject = IntGetWindowObject(hwnd);
-  if(!WindowObject)
-  {
-    IntReleaseMenuObject(MenuObject);
-    SetLastWin32Error(ERROR_INVALID_HANDLE);
-    return FALSE;
-  }
-  
-  if(lptpm)
-  {
-    Status = MmCopyFromCaller(&Safetpm, lptpm, sizeof(TPMPARAMS));
-    if(!NT_SUCCESS(Status))
-    {
-      IntReleaseWindowObject(WindowObject);
-      IntReleaseMenuObject(MenuObject);
-      SetLastNtError(Status);
-      return FALSE;
-    }
-    if(Safetpm.cbSize != sizeof(TPMPARAMS))
-    {
-      IntReleaseWindowObject(WindowObject);
-      IntReleaseMenuObject(MenuObject);
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
-      return FALSE;
-    }
-  }
-  
-  Pos.x = x;
-  Pos.y = y;
-  
-  Ret = IntTrackPopupMenu(MenuObject, WindowObject, fuFlags, &Pos, 0, 
-                          (lptpm ? &Safetpm.rcExclude : NULL));
-  
-  IntReleaseWindowObject(WindowObject);
-  IntReleaseMenuObject(MenuObject);
-  
-  return Ret;
+   UNIMPLEMENTED
+
+   return FALSE;
 }