* Sync up to trunk head (r65270).
authorAmine Khaldi <amine.khaldi@reactos.org>
Wed, 5 Nov 2014 19:33:30 +0000 (19:33 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Wed, 5 Nov 2014 19:33:30 +0000 (19:33 +0000)
svn path=/branches/shell-experiments/; revision=65271

59 files changed:
1  2 
base/applications/regedit/childwnd.c
dll/win32/iphlpapi/CMakeLists.txt
dll/win32/iphlpapi/address.c
dll/win32/iphlpapi/iphlpapi_main.c
dll/win32/syssetup/classinst.c
drivers/bus/pci/pdo.c
drivers/filesystems/fastfat/cleanup.c
drivers/filesystems/fastfat/fcb.c
drivers/filesystems/ntfs/attrib.c
drivers/filesystems/ntfs/blockdev.c
drivers/filesystems/ntfs/create.c
drivers/filesystems/ntfs/dirctl.c
drivers/filesystems/ntfs/fcb.c
drivers/filesystems/ntfs/finfo.c
drivers/filesystems/ntfs/mft.c
drivers/filesystems/ntfs/misc.c
drivers/filesystems/ntfs/ntfs.h
drivers/filesystems/ntfs/rw.c
drivers/filesystems/ntfs/volinfo.c
drivers/network/afd/afd/tdi.c
drivers/network/afd/include/afd.h
drivers/network/tcpip/include/info.h
drivers/network/tcpip/tcpip/iinfo.c
drivers/network/tcpip/tcpip/ninfo.c
drivers/storage/class/disk/disk.c
drivers/storage/fdc/fdc/fdc.c
drivers/storage/fdc/fdc/fdo.c
drivers/storage/fdc/fdc/pdo.c
include/psdk/iptypes.h
include/reactos/libs/fast486/fast486.h
lib/fast486/common.c
lib/fast486/common.h
lib/fast486/common.inl
lib/fast486/extraops.c
lib/fast486/opcodes.c
lib/fast486/opgroups.c
ntoskrnl/config/cmlazy.c
ntoskrnl/config/ntapi.c
ntoskrnl/ex/init.c
ntoskrnl/ex/pushlock.c
ntoskrnl/ex/sysinfo.c
ntoskrnl/include/internal/ps.h
ntoskrnl/include/internal/se.h
ntoskrnl/io/iomgr/file.c
ntoskrnl/ke/i386/traphdlr.c
ntoskrnl/ke/thrdschd.c
ntoskrnl/lpc/connect.c
ntoskrnl/lpc/send.c
ntoskrnl/ob/obsecure.c
ntoskrnl/ps/query.c
ntoskrnl/ps/quota.c
ntoskrnl/se/acl.c
ntoskrnl/se/sd.c
subsystems/ntvdm/bios/bios32/bios32.c
subsystems/ntvdm/dos/mouse32.c
subsystems/ntvdm/hardware/keyboard.c
subsystems/ntvdm/hardware/mouse.c
win32ss/gdi/ntgdi/region.c
win32ss/user/ntuser/focus.c

Simple merge
Simple merge
index 0000000,2571536..2571536
mode 000000,100644..100644
--- /dev/null
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index ace2852,0000000..85fee5e
mode 100644,000000..100644
--- /dev/null
@@@ -1,1279 -1,0 +1,1280 @@@
-       ERR("SetActiveWindow: Summery ERROR, active state changed!\n");
 +/*
 + * COPYRIGHT:        See COPYING in the top level directory
 + * PROJECT:          ReactOS Win32k subsystem
 + * PURPOSE:          Focus functions
 + * FILE:             subsystems/win32/win32k/ntuser/focus.c
 + * PROGRAMER:        ReactOS Team
 + */
 +
 +#include <win32k.h>
 +DBG_DEFAULT_CHANNEL(UserFocus);
 +
 +PUSER_MESSAGE_QUEUE gpqForeground = NULL;
 +PUSER_MESSAGE_QUEUE gpqForegroundPrev = NULL;
 +PTHREADINFO gptiForeground = NULL;
 +PPROCESSINFO gppiLockSFW = NULL;
 +ULONG guSFWLockCount = 0; // Rule #8, No menus are active. So should be zero.
 +PTHREADINFO ptiLastInput = NULL;
 +
 +/*
 +  Check locking of a process or one or more menus are active.
 +*/
 +BOOL FASTCALL
 +IsFGLocked(VOID)
 +{
 +   return (gppiLockSFW || guSFWLockCount);
 +}
 +
++/*
++  Get capture window via foreground Queue.
++*/
 +HWND FASTCALL
 +IntGetCaptureWindow(VOID)
 +{
 +   PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
 +   return ( ForegroundQueue ? (ForegroundQueue->spwndCapture ? UserHMGetHandle(ForegroundQueue->spwndCapture) : 0) : 0);
 +}
 +
 +HWND FASTCALL
 +IntGetThreadFocusWindow(VOID)
 +{
 +   PTHREADINFO pti;
 +   PUSER_MESSAGE_QUEUE ThreadQueue;
 +
 +   pti = PsGetCurrentThreadWin32Thread();
 +   ThreadQueue = pti->MessageQueue;
 +   if (!ThreadQueue)
 +     return NULL;
 +   return ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
 +}
 +
 +BOOL FASTCALL
 +co_IntSendDeactivateMessages(HWND hWndPrev, HWND hWnd)
 +{
 +   USER_REFERENCE_ENTRY RefPrev;
 +   PWND WndPrev;
 +   BOOL Ret = TRUE;
 +
 +   if (hWndPrev && (WndPrev = ValidateHwndNoErr(hWndPrev)))
 +   {
 +      UserRefObjectCo(WndPrev, &RefPrev);
 +
 +      if (co_IntSendMessageNoWait(hWndPrev, WM_NCACTIVATE, FALSE, 0)) //(LPARAM)hWnd))
 +      {
 +         co_IntSendMessageNoWait(hWndPrev, WM_ACTIVATE,
 +                    MAKEWPARAM(WA_INACTIVE, WndPrev->style & WS_MINIMIZE),
 +                    (LPARAM)hWnd);
 +
 +         if (WndPrev)
 +            WndPrev->state &= ~WNDS_ACTIVEFRAME;
 +      }
 +      else
 +      {
 +         ERR("Application is keeping itself Active to prevent the change!\n");
 +         Ret = FALSE;
 +      }
 +
 +      UserDerefObjectCo(WndPrev);
 +   }
 +   return Ret;
 +}
 +
 +BOOL FASTCALL
 +co_IntMakeWindowActive(PWND Window)
 +{
 +  PWND spwndOwner;
 +  if (VerifyWnd(Window))
 +  {  // Set last active for window and it's owner.
 +     spwndOwner = Window;
 +     while (spwndOwner->spwndOwner)
 +     {
 +       spwndOwner = spwndOwner->spwndOwner;
 +     }
 +     spwndOwner->spwndLastActive = Window;
 +     return TRUE;
 +   }
 +   ERR("MakeWindowActive Failed!\n");
 +   return FALSE;
 +}
 +
 +BOOL FASTCALL
 +co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOOL Async)
 +{
 +   USER_REFERENCE_ENTRY Ref, RefPrev;
 +   HANDLE OldTID, NewTID;
 +   PTHREADINFO pti, ptiOld, ptiNew;
 +   BOOL InAAPM = FALSE;
 +
 +   //ERR("SendActivateMessages\n");
 +
 +   pti = PsGetCurrentThreadWin32Thread();
 +
 +   if (Window)
 +   {
 +      UserRefObjectCo(Window, &Ref);
 +
 +      if (WindowPrev) UserRefObjectCo(WindowPrev, &RefPrev);
 +
 +      /* Send palette messages */
 +      if (gpsi->PUSIFlags & PUSIF_PALETTEDISPLAY &&
 +          //co_IntPostOrSendMessage(UserHMGetHandle(Window), WM_QUERYNEWPALETTE, 0, 0))
 +          co_IntSendMessage(UserHMGetHandle(Window), WM_QUERYNEWPALETTE, 0, 0))
 +      {
 +         UserSendNotifyMessage( HWND_BROADCAST,
 +                                WM_PALETTEISCHANGING,
 +                               (WPARAM)UserHMGetHandle(Window),
 +                                0);
 +      }
 +      //// Fixes CORE-6434.
 +      if (!(Window->style & WS_CHILD))
 +      {
 +         PWND pwndTemp = co_GetDesktopWindow(Window)->spwndChild;
 +
 +         while (pwndTemp && !(pwndTemp->style & WS_VISIBLE)) pwndTemp = pwndTemp->spwndNext;
 +
 +         if (Window != pwndTemp || (WindowPrev && !IntIsWindowVisible(WindowPrev)))
 +         {
 +            if (!Async || pti->MessageQueue == gpqForeground)
 +            {
 +               UINT flags = SWP_NOSIZE | SWP_NOMOVE;
 +               if (Window == pwndTemp) flags |= SWP_NOACTIVATE;
 +               //ERR("co_IntSendActivateMessages SetWindowPos! Async %d pti Q == FGQ %d\n",Async,pti->MessageQueue == gpqForeground);
 +               co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, flags);
 +            }
 +         }
 +      }
 +      ////
 +      //// CORE-1161 and CORE-6651
 +      if (Window->spwndPrev)
 +      {
 +         HWND *phwndTopLevel, *phwndCurrent;
 +         PWND pwndCurrent, pwndDesktop;
 +
 +         pwndDesktop = UserGetDesktopWindow();
 +         if (Window->spwndParent == pwndDesktop )
 +         {
 +            phwndTopLevel = IntWinListChildren(pwndDesktop);
 +            phwndCurrent = phwndTopLevel;
 +            while(*phwndCurrent)
 +            {
 +                pwndCurrent = UserGetWindowObject(*phwndCurrent);
 +
 +                if (pwndCurrent && pwndCurrent->spwndOwner == Window )
 +                {
 +                    co_WinPosSetWindowPos(pwndCurrent, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
 +                }
 +                phwndCurrent++;
 +            }
 +            ExFreePool(phwndTopLevel);
 +          }
 +      }
 +   }
 +   ////
 +   OldTID = WindowPrev ? IntGetWndThreadId(WindowPrev) : NULL;
 +   NewTID = Window ? IntGetWndThreadId(Window) : NULL;
 +   ptiOld = WindowPrev ? WindowPrev->head.pti : NULL;
 +   ptiNew = Window ? Window->head.pti : NULL;
 +
 +   //ERR("SendActivateMessage Old -> %x, New -> %x\n", OldTID, NewTID);
 +
 +   if (!(pti->TIF_flags & TIF_INACTIVATEAPPMSG) &&
 +        (!WindowPrev || OldTID != NewTID) )
 +   {
 +      PWND cWindow;
 +      HWND *List, *phWnd;
 +
 +      List = IntWinListChildren(UserGetDesktopWindow());
 +      if ( List )
 +      {
 +         if ( OldTID )
 +         {
 +            ptiOld->TIF_flags |= TIF_INACTIVATEAPPMSG;
 +            // Note: Do not set pci flags, this does crash!
 +            for (phWnd = List; *phWnd; ++phWnd)
 +            {
 +               cWindow = ValidateHwndNoErr(*phWnd);
 +               if (cWindow && cWindow->head.pti == ptiOld)
 +               { // FALSE if the window is being deactivated,
 +                 // ThreadId that owns the window being activated.
 +                 //ERR("SendActivateMessage Old\n");
 +                 co_IntSendMessageNoWait(*phWnd, WM_ACTIVATEAPP, FALSE, (LPARAM)NewTID);
 +               }
 +            }
 +            ptiOld->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
 +         }
 +         if ( NewTID )
 +         {  //// Prevents a resource crash due to reentrance!
 +            InAAPM = TRUE;
 +            pti->TIF_flags |= TIF_INACTIVATEAPPMSG;
 +            ////
 +            for (phWnd = List; *phWnd; ++phWnd)
 +            {
 +               cWindow = ValidateHwndNoErr(*phWnd);
 +               if (cWindow && cWindow->head.pti == ptiNew)
 +               { // TRUE if the window is being activated,
 +                 // ThreadId that owns the window being deactivated.
 +                 //ERR("SendActivateMessage New\n");
 +                 co_IntSendMessageNoWait(*phWnd, WM_ACTIVATEAPP, TRUE, (LPARAM)OldTID);
 +               }
 +            }
 +         }
 +         ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
 +      }
 +   }
 +
 +   if (Window)
 +   {
 +      if (WindowPrev)
 +         UserDerefObjectCo(WindowPrev); // Now allow the previous window to die.
 +
 +      if (Window->state & WNDS_ACTIVEFRAME)
 +      {  // If already active frame do not allow NCPaint.
 +         //ERR("SendActivateMessage Is Active Frame!\n");
 +         Window->state |= WNDS_NONCPAINT;
 +      }
 +
 +      if (Window->style & WS_MINIMIZE)
 +      {
 +         TRACE("Widow was minimized\n");
 +      }
 +
 +      co_IntMakeWindowActive(Window);
 +
 +      co_IntSendMessageNoWait( UserHMGetHandle(Window),
 +                               WM_NCACTIVATE,
 +                              (WPARAM)(Window == (gpqForeground ? gpqForeground->spwndActive : NULL)),
 +                               0); //(LPARAM)hWndPrev);
 +
 +      co_IntSendMessageNoWait( UserHMGetHandle(Window),
 +                               WM_ACTIVATE,
 +                               MAKEWPARAM(MouseActivate ? WA_CLICKACTIVE : WA_ACTIVE, Window->style & WS_MINIMIZE),
 +                              (LPARAM)(WindowPrev ? UserHMGetHandle(WindowPrev) : 0));
 +
 +      if (Window->spwndParent == UserGetDesktopWindow() &&
 +          Window->spwndOwner == NULL &&
 +          (!(Window->ExStyle & WS_EX_TOOLWINDOW) ||
 +           (Window->ExStyle & WS_EX_APPWINDOW)))
 +      {
 +         // FIXME lParam; The value is TRUE if the window is in full-screen mode, or FALSE otherwise.
 +         co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, (WPARAM) UserHMGetHandle(Window), FALSE);
 +      }
 +      else
 +      {
 +          co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, 0, FALSE);
 +      }
 +
 +      Window->state &= ~WNDS_NONCPAINT;
 +
 +      UserDerefObjectCo(Window);
 +   }
 +
 +   OldTID = WindowPrev ? IntGetWndThreadId(WindowPrev) : NULL;
 +   NewTID = Window ? IntGetWndThreadId(Window) : NULL;
 +   ptiOld = WindowPrev ? WindowPrev->head.pti : NULL;
 +   ptiNew = Window ? Window->head.pti : NULL;
 +
 +   //ERR("SendActivateMessage WindowPrev -> %x, Old -> %x, New -> %x\n", WindowPrev, OldTID, NewTID);
 +
 +   if (!(pti->TIF_flags & TIF_INACTIVATEAPPMSG) &&
 +        (OldTID != NewTID) )
 +   {
 +      PWND cWindow;
 +      HWND *List, *phWnd;
 +
 +      List = IntWinListChildren(UserGetDesktopWindow());
 +      if ( List )
 +      {
 +         if ( OldTID )
 +         {
 +            ptiOld->TIF_flags |= TIF_INACTIVATEAPPMSG;
 +            // Note: Do not set pci flags, this does crash!
 +            for (phWnd = List; *phWnd; ++phWnd)
 +            {
 +               cWindow = ValidateHwndNoErr(*phWnd);
 +               if (cWindow && cWindow->head.pti == ptiOld)
 +               {  // FALSE if the window is being deactivated,
 +                  // ThreadId that owns the window being activated.
 +                 co_IntSendMessageNoWait(*phWnd, WM_ACTIVATEAPP, FALSE, (LPARAM)NewTID);
 +               }
 +            }
 +            ptiOld->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
 +         }
 +         if ( NewTID )
 +         {  //// Prevents a resource crash due to reentrance!
 +            InAAPM = TRUE;
 +            pti->TIF_flags |= TIF_INACTIVATEAPPMSG;
 +            ////
 +            for (phWnd = List; *phWnd; ++phWnd)
 +            {
 +               cWindow = ValidateHwndNoErr(*phWnd);
 +               if (cWindow && cWindow->head.pti == ptiNew)
 +               { // TRUE if the window is being activated,
 +                 // ThreadId that owns the window being deactivated.
 +                 co_IntSendMessageNoWait(*phWnd, WM_ACTIVATEAPP, TRUE, (LPARAM)OldTID);
 +               }
 +            }
 +         }
 +         ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
 +      }
 +   }
 +   return InAAPM;
 +}
 +
 +VOID FASTCALL
 +IntSendFocusMessages( PTHREADINFO pti, PWND pWnd)
 +{
 +   PWND pWndPrev;
 +   PUSER_MESSAGE_QUEUE ThreadQueue = pti->MessageQueue; // Queue can change...
 +
 +   ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE;
 +   if (!pWnd && ThreadQueue->spwndActive)
 +   {
 +      ThreadQueue->QF_flags |= QF_FOCUSNULLSINCEACTIVE;
 +   }
 +
 +   pWndPrev = ThreadQueue->spwndFocus;
 +
 +   /* check if the specified window can be set in the input data of a given queue */
 +   if (!pWnd || ThreadQueue == pWnd->head.pti->MessageQueue)
 +      /* set the current thread focus window */
 +      ThreadQueue->spwndFocus = pWnd;
 +
 +   if (pWnd)
 +   {
 +      if (pWndPrev)
 +      {
 +         //co_IntPostOrSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, (WPARAM)UserHMGetHandle(pWnd), 0);
 +         co_IntSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, (WPARAM)UserHMGetHandle(pWnd), 0);
 +      }
 +      if (ThreadQueue->spwndFocus == pWnd)
 +      {
 +         IntNotifyWinEvent(EVENT_OBJECT_FOCUS, pWnd, OBJID_CLIENT, CHILDID_SELF, 0);
 +         //co_IntPostOrSendMessage(UserHMGetHandle(pWnd), WM_SETFOCUS, (WPARAM)(pWndPrev ? UserHMGetHandle(pWndPrev) : NULL), 0);
 +         co_IntSendMessage(UserHMGetHandle(pWnd), WM_SETFOCUS, (WPARAM)(pWndPrev ? UserHMGetHandle(pWndPrev) : NULL), 0);
 +      }
 +   }
 +   else
 +   {
 +      if (pWndPrev)
 +      {
 +         IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
 +         //co_IntPostOrSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, 0, 0);
 +         co_IntSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, 0, 0);
 +      }
 +   }
 +}
 +
 +VOID FASTCALL
 +FindRemoveAsyncMsg(PWND Wnd, WPARAM wParam)
 +{
 +   PTHREADINFO pti;
 +   PUSER_SENT_MESSAGE Message;
 +   PLIST_ENTRY Entry;
 +
 +   if (!Wnd) return;
 +
 +   pti = Wnd->head.pti;
 +
 +   Entry = pti->SentMessagesListHead.Flink;
 +   while (Entry != &pti->SentMessagesListHead)
 +   {
 +      // Scan sent queue messages to see if we received async messages.
 +      Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
 +      Entry = Entry->Flink;
 +
 +      if (Message->Msg.message == WM_ASYNC_SETACTIVEWINDOW &&
 +          Message->Msg.hwnd == UserHMGetHandle(Wnd) &&
 +          Message->Msg.wParam == wParam)
 +      {
 +         ERR("ASYNC SAW: Found one in the Sent Msg Queue! %p Activate/Deactivate %d\n", Message->Msg.hwnd, !!wParam);
 +         RemoveEntryList(&Message->ListEntry); // Purge the entry.
 +         ClearMsgBitsMask(pti, Message->QS_Flags);
 +         ExFreePoolWithTag(Message, TAG_USRMSG);
 +      }
 +   }
 +}
 +
 +BOOL FASTCALL
 +ToggleFGActivate(PTHREADINFO pti)
 +{
 +   BOOL Ret;
 +   PPROCESSINFO ppi = pti->ppi;
 +
 +   Ret = !!(pti->TIF_flags & TIF_ALLOWFOREGROUNDACTIVATE);
 +   if (Ret)
 +   {
 +      pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE;
 +   }
 +   else
 +      Ret = !!(ppi->W32PF_flags & W32PF_ALLOWFOREGROUNDACTIVATE);
 +
 +   if (Ret)
 +      ppi->W32PF_flags &= ~W32PF_ALLOWFOREGROUNDACTIVATE;
 +   //ERR("ToggleFGActivate is %d\n",Ret);
 +   return Ret;
 +}
 +
 +BOOL FASTCALL
 +IsAllowedFGActive(PTHREADINFO pti, PWND Wnd)
 +{
 +   // Not allowed if one or more,,
 +   if (!ToggleFGActivate(pti) ||              // bits not set,
 +        pti->rpdesk != gpdeskInputDesktop ||  // not current Desktop,
 +        pti->MessageQueue == gpqForeground || // if already the queue foreground,
 +        IsFGLocked() ||                       // foreground is locked,
 +        Wnd->ExStyle & WS_EX_NOACTIVATE )     // or,,, does not become the foreground window when the user clicks it.
 +   {
 +      return FALSE;
 +   }
 +   //ERR("IsAllowedFGActive is TRUE\n");
 +   return TRUE;
 +}
 +
 +/*
 +   Can the system force foreground from one or more conditions.
 + */
 +BOOL FASTCALL
 +CanForceFG(PPROCESSINFO ppi)
 +{
 +   if (!ptiLastInput ||
 +        ptiLastInput->ppi == ppi ||
 +       !gptiForeground ||
 +        gptiForeground->ppi == ppi ||
 +        ppi->W32PF_flags & (W32PF_ALLOWFOREGROUNDACTIVATE | W32PF_SETFOREGROUNDALLOWED) ||
 +        gppiInputProvider == ppi ||
 +       !gpqForeground
 +      ) return TRUE;
 +   //ERR("CanForceFG is FALSE\n");
 +   return FALSE;
 +}
 +
 +/*
 +   MSDN:
 +   The system restricts which processes can set the foreground window. A process
 +   can set the foreground window only if one of the following conditions is true:
 +
 +    * The process is the foreground process.
 +    * The process was started by the foreground process.
 +    * The process received the last input event.
 +    * There is no foreground process.
 +    * The foreground process is being debugged.
 +    * The foreground is not locked (see LockSetForegroundWindow).
 +    * The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
 +    * No menus are active.
 +*/
 +static
 +BOOL FASTCALL
 +co_IntSetForegroundAndFocusWindow(
 +    _In_ PWND Wnd,
 +    _In_ BOOL MouseActivate)
 +{
 +   HWND hWnd = Wnd ? UserHMGetHandle(Wnd) : NULL;
 +   HWND hWndPrev = NULL;
 +   PWND pWndPrev = NULL;
 +   PUSER_MESSAGE_QUEUE PrevForegroundQueue;
 +   PTHREADINFO pti;
 +   BOOL fgRet = FALSE, Ret = FALSE;
 +
 +   if (Wnd) ASSERT_REFS_CO(Wnd);
 +
 +   //ERR("SetForegroundAndFocusWindow(%x, %s)\n", hWnd, (MouseActivate ? "TRUE" : "FALSE"));
 +
 +   PrevForegroundQueue = IntGetFocusMessageQueue(); // Use this active desktop.
 +   pti = PsGetCurrentThreadWin32Thread();
 +
 +   if (PrevForegroundQueue)
 +   {  // Same Window Q as foreground just do active.
 +      if (Wnd && Wnd->head.pti->MessageQueue == PrevForegroundQueue)
 +      {
 +         //ERR("Same Window Q as foreground just do active.\n");
 +         if (pti->MessageQueue == PrevForegroundQueue)
 +         { // Same WQ and TQ go active.
 +            //ERR("Same WQ and TQ go active.\n");
 +            Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE);
 +         }
 +         else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd)
 +         { // Same WQ and it is active.
 +            //ERR("Same WQ and it is active.\n");
 +            Ret = TRUE;
 +         }
 +         else
 +         { // Same WQ as FG but not the same TQ send active.
 +            //ERR("Same WQ as FG but not the same TQ send active.\n");
 +            co_IntSendMessage(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate );
 +            Ret = TRUE;
 +         }
 +         return Ret;
 +      }
 +
 +      hWndPrev = PrevForegroundQueue->spwndActive ? UserHMGetHandle(PrevForegroundQueue->spwndActive) : 0;
 +      pWndPrev = PrevForegroundQueue->spwndActive;
 +   }
 +
 +   if ( (( !IsFGLocked() || pti->ppi == gppiInputProvider ) &&
 +         ( CanForceFG(pti->ppi) || pti->TIF_flags & (TIF_SYSTEMTHREAD|TIF_CSRSSTHREAD|TIF_ALLOWFOREGROUNDACTIVATE) )) ||
 +        pti->ppi == ppiScrnSaver
 +      )
 +   {
 +
 +      //ToggleFGActivate(pti); // win.c line 2662 fail
 +      if (Wnd)
 +      {
 +         IntSetFocusMessageQueue(Wnd->head.pti->MessageQueue);
 +         gptiForeground = Wnd->head.pti;
 +         //ERR("Set Foreground pti 0x%p Q 0x%p hWnd 0x%p\n",Wnd->head.pti, Wnd->head.pti->MessageQueue,Wnd->head.h);
 +      }
 +      else
 +      {
 +         IntSetFocusMessageQueue(NULL);
 +         gptiForeground = NULL;
 +         //ERR("Set Foreground pti 0x0 Q 0x0 hWnd 0x0\n");
 +      }
 +/*
 +     Henri Verbeet,
 +     What happens is that we get the WM_WINE_SETACTIVEWINDOW message sent by the
 +     other thread after we already changed the foreground window back to our own
 +     window.
 + */
 +      //ERR("SFAFW: 1\n");
 +      FindRemoveAsyncMsg(Wnd, 0); // Do this to fix test_SFW todos!
 +
 +      fgRet = TRUE;
 +   }
 +
 +   //  Fix FG Bounce with regedit.
 +   if (hWndPrev != hWnd )
 +   {
 +      if (PrevForegroundQueue &&
 +          fgRet &&
 +          PrevForegroundQueue->spwndActive)
 +      {
 +         //ERR("SFGW: Send NULL to 0x%x\n",hWndPrev);
 +         if (pti->MessageQueue == PrevForegroundQueue)
 +         {
 +            //ERR("SFGW: TI same as Prev TI\n");
 +            co_IntSetActiveWindow(NULL, FALSE, TRUE, FALSE);
 +         }
 +         else if (pWndPrev)
 +         {
 +            //ERR("SFGW Deactivate: TI not same as Prev TI\n");
 +            // No real reason to wait here.
 +            co_IntSendMessageNoWait(hWndPrev, WM_ASYNC_SETACTIVEWINDOW, 0, 0 );
 +         }
 +      }
 +   }
 +
 +   if (!Wnd) return FALSE; // Always return false.
 +
 +   if (pti->MessageQueue == Wnd->head.pti->MessageQueue)
 +   {
 +       //ERR("Same PQ and WQ go active.\n");
 +       Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE);
 +   }
 +   else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd)
 +   {
 +       //ERR("Same Active and Wnd.\n");
 +       Ret = TRUE;
 +   }
 +   else
 +   {
 +       //ERR("Activate Not same PQ and WQ and Wnd.\n");
 +       co_IntSendMessageNoWait(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate );
 +       Ret = TRUE;
 +   }
 +   return Ret && fgRet;
 +}
 +
 +/*
 +  Revision 7888, activate modal dialog when clicking on a disabled window.
 +*/
 +HWND FASTCALL
 +IntFindChildWindowToOwner(PWND Root, PWND Owner)
 +{
 +   HWND Ret;
 +   PWND Child, OwnerWnd;
 +
 +   for(Child = Root->spwndChild; Child; Child = Child->spwndNext)
 +   {
 +      OwnerWnd = Child->spwndOwner;
 +      if(!OwnerWnd)
 +         continue;
 +
 +      if(OwnerWnd == Owner)
 +      {
 +         Ret = Child->head.h;
 +         return Ret;
 +      }
 +   }
 +   return NULL;
 +}
 +
 +BOOL FASTCALL
 +co_IntMouseActivateWindow(PWND Wnd)
 +{
 +   HWND Top;
 +   USER_REFERENCE_ENTRY Ref;
 +   ASSERT_REFS_CO(Wnd);
 +
 +   if (Wnd->style & WS_DISABLED)
 +   {
 +      BOOL Ret;
 +      PWND TopWnd;
 +      PWND DesktopWindow = UserGetDesktopWindow();
 +      if (DesktopWindow)
 +      {
 +         ERR("Window Diabled\n");
 +         Top = IntFindChildWindowToOwner(DesktopWindow, Wnd);
 +         if ((TopWnd = ValidateHwndNoErr(Top)))
 +         {
 +            UserRefObjectCo(TopWnd, &Ref);
 +            Ret = co_IntMouseActivateWindow(TopWnd);
 +            UserDerefObjectCo(TopWnd);
 +
 +            return Ret;
 +         }
 +      }
 +      return FALSE;
 +   }
 +   TRACE("Mouse Active\n");
 +   co_IntSetForegroundAndFocusWindow(Wnd, TRUE);
 +   return TRUE;
 +}
 +
 +BOOL FASTCALL
 +co_IntSetActiveWindow(PWND Wnd OPTIONAL, BOOL bMouse, BOOL bFocus, BOOL Async)
 +{
 +   PTHREADINFO pti;
 +   PUSER_MESSAGE_QUEUE ThreadQueue;
 +   PWND pWndChg, WndPrev; // State changes.
 +   HWND hWndPrev;
 +   HWND hWnd = 0;
 +   BOOL InAAPM;
 +   CBTACTIVATESTRUCT cbt;
 +   //ERR("co_IntSetActiveWindow 1\n");
 +   if (Wnd)
 +   {
 +      ASSERT_REFS_CO(Wnd);
 +      hWnd = UserHMGetHandle(Wnd);
 +      if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
 +      if (Wnd == UserGetDesktopWindow()) return FALSE;
 +      //ERR("co_IntSetActiveWindow 1a hWnd 0x%p\n",hWnd);
 +   }
 +
 +   //ERR("co_IntSetActiveWindow 2\n");
 +   pti = PsGetCurrentThreadWin32Thread();
 +   ThreadQueue = pti->MessageQueue;
 +   ASSERT(ThreadQueue != 0);
 +
 +   hWndPrev = ThreadQueue->spwndActive ? UserHMGetHandle(ThreadQueue->spwndActive) : NULL;
 +
 +   pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch.
 +
 +   while (Wnd)
 +   {
 +      BOOL Ret, DoFG, AllowFG;
 +
 +      if (Wnd->state & WNDS_BEINGACTIVATED) return TRUE;
 +
 +      if (ThreadQueue == Wnd->head.pti->MessageQueue)
 +      {
 +         if (IsAllowedFGActive(pti, Wnd))
 +         {
 +             DoFG = TRUE;
 +         }
 +         else
 +         {
 +             //ERR("co_IntSetActiveWindow 3 Go Out!\n");
 +             break;
 +         }
 +         AllowFG = !pti->cVisWindows; // Nothing is visable.
 +         //ERR("co_IntSetActiveWindow 3a DoFG = %d AllowFG = %d\n",DoFG,AllowFG);
 +      }
 +      else //if (ThreadQueue != Wnd->head.pti->MessageQueue)
 +      {
 +         //PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
 +         // Rule 1 & 4, We are foreground so set this FG window or NULL foreground....
 +         //if (!ForegroundQueue || ForegroundQueue == ThreadQueue)
 +         if (!gpqForeground || gpqForeground == ThreadQueue)
 +         {
 +            DoFG = TRUE;
 +         }
 +         else
 +            DoFG = FALSE;
 +         if (DoFG)
 +         {
 +            if (pti->TIF_flags & TIF_ALLOWFOREGROUNDACTIVATE || pti->cVisWindows)
 +               AllowFG = TRUE;
 +            else
 +               AllowFG = FALSE;
 +         }
 +         else
 +            AllowFG = FALSE;
 +         //ERR("co_IntSetActiveWindow 3b DoFG = %d AllowFG = %d\n",DoFG,AllowFG);
 +      }
 +      Ret = FALSE;
 +      if (DoFG)
 +      {
 +         pti->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE;
 +         //ERR("co_IntSetActiveWindow 3c FG set\n");
 +         Ret = co_IntSetForegroundAndFocusWindow(Wnd, bMouse);
 +         if (AllowFG)
 +         {
 +            pti->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE;
 +         }
 +         else
 +         {
 +            pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE;
 +         }
 +      }
 +      return Ret;
 +   }
 +
 +   /* Call CBT hook chain */
 +   cbt.fMouse     = bMouse;
 +   cbt.hWndActive = hWndPrev;
 +   if (co_HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hWnd, (LPARAM)&cbt))
 +   {
 +      ERR("SetActiveWindow: WH_CBT Call Hook return!\n");
 +      return FALSE;
 +   }
 +
 +   if ( ThreadQueue->spwndActive && ThreadQueue->spwndActive->state & WNDS_DESTROYED )
 +      ThreadQueue->spwndActive = NULL;
 +   else
 +      ThreadQueue->spwndActivePrev = ThreadQueue->spwndActive;
 +
 +   WndPrev = ThreadQueue->spwndActive; // Keep to save changing active.
 +
 +   if (WndPrev)
 +   {
 +      if (ThreadQueue == gpqForeground) gpqForegroundPrev = ThreadQueue;
 +      if (!co_IntSendDeactivateMessages(UserHMGetHandle(WndPrev), hWnd)) return FALSE;
 +   }
 +
 +   WndPrev = ThreadQueue->spwndActive; // Again keep to save changing active.
 +
 +   // While in calling message proc or hook:
 +   // Fail if a preemptive switch was made, current active not made previous,
 +   // focus window is dead or no longer the same thread queue.
 +   if ( ThreadQueue->spwndActivePrev != ThreadQueue->spwndActive ||
 +        pWndChg != WndPrev ||
 +        (Wnd && !VerifyWnd(Wnd)) ||
 +        ThreadQueue != pti->MessageQueue )
 +   {
-       //co_IntPostOrSendMessage(hWndPrev, WM_CAPTURECHANGED, 0, (LPARAM)hWnd);
++      ERR("SetActiveWindow: Summary ERROR, active state changed!\n");
 +      return FALSE;
 +   }
 +
 +   if (!WndPrev) ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE;
 +
 +   if (Wnd) Wnd->state |= WNDS_BEINGACTIVATED;
 +
 +   IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
 +   //// Breaks Atl-Esc/Tab via User32.
 +   ////FindRemoveAsyncMsg(Wnd,(WPARAM)Wnd); // Clear out activate ASYNC messages.
 +
 +   /* check if the specified window can be set in the input data of a given queue */
 +   if ( !Wnd || ThreadQueue == Wnd->head.pti->MessageQueue)
 +   {
 +      /* set the current thread active window */
 +      ThreadQueue->spwndActive = Wnd;
 +   }
 +
 +   WndPrev = VerifyWnd(ThreadQueue->spwndActivePrev); // Now should be set but verify it again.
 +
 +   InAAPM = co_IntSendActivateMessages(WndPrev, Wnd, bMouse, Async);
 +
 +   /* now change focus if necessary */
 +   //// Fixes CORE-6452 allows setting focus on window.
 +   if (bFocus && !(ThreadQueue->QF_flags & QF_FOCUSNULLSINCEACTIVE))
 +   {
 +      /* Do not change focus if the window is no longer active */
 +      if (pti->MessageQueue->spwndActive != IntGetNonChildAncestor(pti->MessageQueue->spwndFocus))
 +      {
 +         PWND pWndSend = pti->MessageQueue->spwndActive;
 +         // Clear focus if the active window is minimized.
 +         if (pWndSend && pti->MessageQueue->spwndActive->style & WS_MINIMIZE) pWndSend = NULL;
 +         // Send focus messages and if so, set the focus.
 +         IntSendFocusMessages( pti, pWndSend);
 +      }
 +   }
 +   ////
 +   if (InAAPM)
 +   {
 +      pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
 +   }
 +
 +   // FIXME: Used in the menu loop!!!
 +   //ThreadQueue->QF_flags |= QF_ACTIVATIONCHANGE;
 +
 +   //ERR("co_IntSetActiveWindow Exit\n");
 +   if (Wnd) Wnd->state &= ~WNDS_BEINGACTIVATED;
 +   return (ThreadQueue->spwndActive == Wnd);
 +}
 +
 +BOOL FASTCALL
 +UserSetActiveWindow(PWND Wnd)
 +{
 +  if (Wnd) // Must have a window!
 +  {
 +     if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
 +
 +     return co_IntSetActiveWindow(Wnd, FALSE, TRUE, FALSE);
 +  }
 +  /*
 +     Yes your eye are not deceiving you~!
 +
 +     First part of wines Win.c test_SetActiveWindow:
 +
 +     flush_events( TRUE );
 +     ShowWindow(hwnd, SW_HIDE);
 +     SetFocus(0);
 +     SetActiveWindow(0);
 +     check_wnd_state(0, 0, 0, 0); <-- This should pass if ShowWindow does it's job!!! As of 10/28/2012 it does!
 +
 +  */
 +  return FALSE;
 +}
 +
 +HWND FASTCALL
 +co_UserSetFocus(PWND Window)
 +{
 +   HWND hWndPrev = 0;
 +   PWND pwndTop;
 +   PTHREADINFO pti;
 +   PUSER_MESSAGE_QUEUE ThreadQueue;
 +
 +   if (Window)
 +      ASSERT_REFS_CO(Window);
 +
 +   pti = PsGetCurrentThreadWin32Thread();
 +   ThreadQueue = pti->MessageQueue;
 +   ASSERT(ThreadQueue != 0);
 +
 +   TRACE("Enter SetFocus hWnd 0x%p pti 0x%p\n",Window ? UserHMGetHandle(Window) : 0, pti );
 +
 +   hWndPrev = ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
 +
 +   if (Window != 0)
 +   {
 +      if (hWndPrev == UserHMGetHandle(Window))
 +      {
 +         return hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0; /* Nothing to do */
 +      }
 +
 +      if (Window->head.pti->MessageQueue != ThreadQueue)
 +      {
 +         ERR("SetFocus Must have the same Q!\n");
 +         return 0;
 +      }
 +
 +      /* Check if we can set the focus to this window */
 +      //// Fixes wine win test_SetParent both "todo" line 3710 and 3720...
 +      for (pwndTop = Window; pwndTop; pwndTop = pwndTop->spwndParent)
 +      {
 +         if (pwndTop->style & (WS_MINIMIZED|WS_DISABLED)) return 0;
 +         if ((pwndTop->style & (WS_POPUP|WS_CHILD)) != WS_CHILD) break;
 +      }
 +      ////
 +      if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)Window->head.h, (LPARAM)hWndPrev))
 +      {
 +         ERR("SetFocus 1 WH_CBT Call Hook return!\n");
 +         return 0;
 +      }
 +
 +      /* Activate pwndTop if needed. */
 +      if (pwndTop != ThreadQueue->spwndActive)
 +      {
 +         PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue(); // Keep it based on desktop.
 +         if (ThreadQueue != ForegroundQueue && IsAllowedFGActive(pti, pwndTop)) // Rule 2 & 3.
 +         {
 +            //ERR("SetFocus: Set Foreground!\n");
 +            if (!(pwndTop->style & WS_VISIBLE))
 +            {
 +                pti->ppi->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE;
 +            }
 +            if (!co_IntSetForegroundAndFocusWindow(pwndTop, FALSE))
 +            {
 +               ERR("SetFocus: Set Foreground and Focus Failed!\n");
 +               return 0;
 +            }
 +         }
 +
 +         /* Set Active when it is needed. */
 +         if (pwndTop != ThreadQueue->spwndActive)
 +         {
 +            //ERR("SetFocus: Set Active!\n");
 +            if (!co_IntSetActiveWindow(pwndTop, FALSE, FALSE, FALSE))
 +            {
 +               ERR("SetFocus: Set Active Failed!\n");
 +               return 0;
 +            }
 +         }
 +
 +         /* Abort if window destroyed */
 +         if (Window->state2 & WNDS2_INDESTROY) return 0;
 +         /* Do not change focus if the window is no longer active */
 +         if (pwndTop != ThreadQueue->spwndActive)
 +         {
 +            ERR("SetFocus: Top window did not go active!\n");
 +            return 0;
 +         }
 +      }
 +
 +      // Check again! SetActiveWindow could have set the focus via WM_ACTIVATE.
 +      hWndPrev = ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
 +
 +      IntSendFocusMessages( pti, Window);
 +
 +      TRACE("Focus: %p -> %p\n", hWndPrev, Window->head.h);
 +   }
 +   else /* NULL hwnd passed in */
 +   {
 +      if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)0, (LPARAM)hWndPrev))
 +      {
 +         ERR("SetFocus: 2 WH_CBT Call Hook return!\n");
 +         return 0;
 +      }
 +
 +      /* set the current thread focus window null */
 +      IntSendFocusMessages( pti, NULL);
 +   }
 +   return hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0;
 +}
 +
 +HWND FASTCALL
 +UserGetForegroundWindow(VOID)
 +{
 +   PUSER_MESSAGE_QUEUE ForegroundQueue;
 +
 +   ForegroundQueue = IntGetFocusMessageQueue();
 +   return( ForegroundQueue ? (ForegroundQueue->spwndActive ? UserHMGetHandle(ForegroundQueue->spwndActive) : 0) : 0);
 +}
 +
 +HWND FASTCALL UserGetActiveWindow(VOID)
 +{
 +   PTHREADINFO pti;
 +   PUSER_MESSAGE_QUEUE ThreadQueue;
 +
 +   pti = PsGetCurrentThreadWin32Thread();
 +   ThreadQueue = pti->MessageQueue;
 +   return( ThreadQueue ? (ThreadQueue->spwndActive ? UserHMGetHandle(ThreadQueue->spwndActive) : 0) : 0);
 +}
 +
 +HWND APIENTRY
 +IntGetCapture(VOID)
 +{
 +   PTHREADINFO pti;
 +   PUSER_MESSAGE_QUEUE ThreadQueue;
 +   DECLARE_RETURN(HWND);
 +
 +   TRACE("Enter IntGetCapture\n");
 +
 +   pti = PsGetCurrentThreadWin32Thread();
 +   ThreadQueue = pti->MessageQueue;
 +   RETURN( ThreadQueue ? (ThreadQueue->spwndCapture ? UserHMGetHandle(ThreadQueue->spwndCapture) : 0) : 0);
 +
 +CLEANUP:
 +   TRACE("Leave IntGetCapture, ret=%p\n", _ret_);
 +   END_CLEANUP;
 +}
 +
 +HWND FASTCALL
 +co_UserSetCapture(HWND hWnd)
 +{
 +   PTHREADINFO pti;
 +   PUSER_MESSAGE_QUEUE ThreadQueue;
 +   PWND pWnd, Window = NULL;
 +   HWND hWndPrev;
 +
 +   pti = PsGetCurrentThreadWin32Thread();
 +   ThreadQueue = pti->MessageQueue;
 +
 +   if (ThreadQueue->QF_flags & QF_CAPTURELOCKED)
 +      return NULL;
 +
 +   if (hWnd && (Window = UserGetWindowObject(hWnd)))
 +   {
 +      if (Window->head.pti->MessageQueue != ThreadQueue)
 +      {
++         ERR("Window Thread dos not match Current!\n");
 +         return NULL;
 +      }
 +   }
 +
 +   hWndPrev = MsqSetStateWindow(pti, MSQ_STATE_CAPTURE, hWnd);
 +
 +   if (hWndPrev)
 +   {
 +      pWnd = UserGetWindowObject(hWndPrev);
 +      if (pWnd)
 +         IntNotifyWinEvent(EVENT_SYSTEM_CAPTUREEND, pWnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
 +   }
 +
 +   if (Window)
 +      IntNotifyWinEvent(EVENT_SYSTEM_CAPTURESTART, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
 +
 +   if (hWndPrev && hWndPrev != hWnd)
 +   {
 +      if (ThreadQueue->MenuOwner && Window) ThreadQueue->QF_flags |= QF_CAPTURELOCKED;
 +
-    ThreadQueue->spwndCapture = Window;
 +      co_IntSendMessage(hWndPrev, WM_CAPTURECHANGED, 0, (LPARAM)hWnd);
 +
 +      ThreadQueue->QF_flags &= ~QF_CAPTURELOCKED;
 +   }
 +
 +   if (hWnd == NULL) // Release mode.
 +   {
 +      MOUSEINPUT mi;
 +   /// These are HACKS!
 +      /* Also remove other windows if not capturing anymore */
 +      MsqSetStateWindow(pti, MSQ_STATE_MENUOWNER, NULL);
 +      MsqSetStateWindow(pti, MSQ_STATE_MOVESIZE, NULL);
 +   ///
 +      /* Somebody may have missed some mouse movements */
 +      mi.dx = 0;
 +      mi.dy = 0;
 +      mi.mouseData = 0;
 +      mi.dwFlags = MOUSEEVENTF_MOVE;
 +      mi.time = 0;
 +      mi.dwExtraInfo = 0;
 +      UserSendMouseInput(&mi, FALSE);
 +   }
 +   return hWndPrev;
 +}
 +
 +/*
 +  API Call
 +*/
 +BOOL
 +FASTCALL
 +IntReleaseCapture(VOID)
 +{
 +   PTHREADINFO pti;
 +   PUSER_MESSAGE_QUEUE ThreadQueue;
 +
 +   pti = PsGetCurrentThreadWin32Thread();
 +   ThreadQueue = pti->MessageQueue;
 +
 +   // Can not release inside WM_CAPTURECHANGED!!
 +   if (ThreadQueue->QF_flags & QF_CAPTURELOCKED) return FALSE;
 +
 +   co_UserSetCapture(NULL);
 +
 +   return TRUE;
 +}
 +
 +/*
 +  API Call
 +*/
 +BOOL FASTCALL
 +co_IntSetForegroundWindow(PWND Window)
 +{
 +   if (Window) ASSERT_REFS_CO(Window);
 +
 +   return co_IntSetForegroundAndFocusWindow(Window, FALSE);
 +}
 +
 +/*
 +  API Call
 +*/
 +BOOL FASTCALL
 +co_IntSetForegroundWindowMouse(PWND Window)
 +{
 +   if (Window) ASSERT_REFS_CO(Window);
 +
 +   return co_IntSetForegroundAndFocusWindow(Window, TRUE);
 +}
 +
 +/*
 +  API Call
 +*/
 +BOOL FASTCALL
 +IntLockSetForegroundWindow(UINT uLockCode)
 +{
 +   ULONG Err = ERROR_ACCESS_DENIED;
 +   PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
 +   switch (uLockCode)
 +   {
 +      case LSFW_LOCK:
 +         if ( CanForceFG(ppi) && !gppiLockSFW )
 +         {
 +            gppiLockSFW = ppi;
 +            return TRUE;
 +         }
 +         break;
 +      case LSFW_UNLOCK:
 +         if ( gppiLockSFW == ppi)
 +         {
 +            gppiLockSFW = NULL;
 +            return TRUE;
 +         }
 +         break;
 +      default:
 +         Err = ERROR_INVALID_PARAMETER;
 +   }
 +   EngSetLastError(Err);
 +   return FALSE;
 +}
 +
 +/*
 +  API Call
 +*/
 +BOOL FASTCALL
 +IntAllowSetForegroundWindow(DWORD dwProcessId)
 +{
 +   PPROCESSINFO ppi, ppiCur;
 +   PEPROCESS Process = NULL;
 +
 +   ppi = NULL;
 +   if (dwProcessId != ASFW_ANY)
 +   {
 +      if (!NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)dwProcessId, &Process)))
 +      {
 +         EngSetLastError(ERROR_INVALID_PARAMETER);
 +         return FALSE;
 +      }
 +      ppi = PsGetProcessWin32Process(Process);
 +      if (!ppi)
 +      {
 +         ObDereferenceObject(Process);
 +         return FALSE;
 +      }
 +   }
 +   ppiCur = PsGetCurrentProcessWin32Process();
 +   if (!CanForceFG(ppiCur))
 +   {
 +      if (Process) ObDereferenceObject(Process);
 +      EngSetLastError(ERROR_ACCESS_DENIED);
 +      return FALSE;
 +   }
 +   if (dwProcessId == ASFW_ANY)
 +   {  // All processes will be enabled to set the foreground window.
 +      //ERR("ptiLastInput is CLEARED!!\n");
 +      ptiLastInput = NULL;
 +   }
 +   else
 +   {  // Rule #3, last input event in force.
 +      ERR("ptiLastInput is SET!!\n");
 +      //ptiLastInput = ppi->ptiList; // See CORE-6384 & CORE-7030.
 +      ObDereferenceObject(Process);
 +   }
 +   return TRUE;
 +}
 +
 +/*
 + * @implemented
 + */
 +HWND APIENTRY
 +NtUserGetForegroundWindow(VOID)
 +{
 +   DECLARE_RETURN(HWND);
 +
 +   TRACE("Enter NtUserGetForegroundWindow\n");
 +   UserEnterExclusive();
 +
 +   RETURN( UserGetForegroundWindow());
 +
 +CLEANUP:
 +   TRACE("Leave NtUserGetForegroundWindow, ret=%p\n",_ret_);
 +   UserLeave();
 +   END_CLEANUP;
 +}
 +
 +HWND APIENTRY
 +NtUserSetActiveWindow(HWND hWnd)
 +{
 +   USER_REFERENCE_ENTRY Ref;
 +   HWND hWndPrev;
 +   PWND Window;
 +   DECLARE_RETURN(HWND);
 +
 +   TRACE("Enter NtUserSetActiveWindow(%p)\n", hWnd);
 +   UserEnterExclusive();
 +
 +   Window = NULL;
 +   if (hWnd)
 +   {
 +      if (!(Window = UserGetWindowObject(hWnd)))
 +      {
 +         ERR("NtUserSetActiveWindow: Invalid handle 0x%p!\n",hWnd);
 +         RETURN( NULL);
 +      }
 +   }
 +
 +   if (!Window ||
 +        Window->head.pti->MessageQueue == gptiCurrent->MessageQueue)
 +   {
 +      hWndPrev = gptiCurrent->MessageQueue->spwndActive ? UserHMGetHandle(gptiCurrent->MessageQueue->spwndActive) : NULL;
 +      if (Window) UserRefObjectCo(Window, &Ref);
 +      UserSetActiveWindow(Window);
 +      if (Window) UserDerefObjectCo(Window);
 +      RETURN( hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0 );
 +   }
 +   RETURN( NULL);
 +
 +CLEANUP:
 +   TRACE("Leave NtUserSetActiveWindow, ret=%p\n",_ret_);
 +   UserLeave();
 +   END_CLEANUP;
 +}
 +
 +/*
 + * @implemented
 + */
 +HWND APIENTRY
 +NtUserSetCapture(HWND hWnd)
 +{
 +   DECLARE_RETURN(HWND);
 +
 +   TRACE("Enter NtUserSetCapture(%p)\n", hWnd);
 +   UserEnterExclusive();
 +
 +   RETURN( co_UserSetCapture(hWnd));
 +
 +CLEANUP:
 +   TRACE("Leave NtUserSetCapture, ret=%p\n", _ret_);
 +   UserLeave();
 +   END_CLEANUP;
 +}
 +
 +/*
 + * @implemented
 + */
 +HWND APIENTRY
 +NtUserSetFocus(HWND hWnd)
 +{
 +   PWND Window;
 +   USER_REFERENCE_ENTRY Ref;
 +   DECLARE_RETURN(HWND);
 +   HWND ret;
 +
 +   TRACE("Enter NtUserSetFocus(%p)\n", hWnd);
 +   UserEnterExclusive();
 +
 +   if (hWnd)
 +   {
 +      if (!(Window = UserGetWindowObject(hWnd)))
 +      {
 +         ERR("NtUserSetFocus: Invalid handle 0x%p!\n",hWnd);
 +         RETURN(NULL);
 +      }
 +
 +      UserRefObjectCo(Window, &Ref);
 +      ret = co_UserSetFocus(Window);
 +      UserDerefObjectCo(Window);
 +
 +      RETURN(ret);
 +   }
 +   else
 +   {
 +      RETURN( co_UserSetFocus(0));
 +   }
 +
 +CLEANUP:
 +   TRACE("Leave NtUserSetFocus, ret=%p\n",_ret_);
 +   UserLeave();
 +   END_CLEANUP;
 +}
 +
 +/* EOF */