コード例 #1
0
ファイル: input.c プロジェクト: RPG-7/reactos
/*
 * DoTheScreenSaver
 *
 * Check if scrensaver should be started and sends message to SAS window
 */
VOID FASTCALL
DoTheScreenSaver(VOID)
{
    LARGE_INTEGER TickCount;
    DWORD Test, TO;

    if (gspv.iScrSaverTimeout > 0) // Zero means Off.
    {
        KeQueryTickCount(&TickCount);
        Test = MsqCalculateMessageTime(&TickCount);
        Test = Test - LastInputTick;
        TO = 1000 * gspv.iScrSaverTimeout;
        if (Test > TO)
        {
            TRACE("Screensaver Message Start! Tick %lu Timeout %d \n", Test, gspv.iScrSaverTimeout);

            if (ppiScrnSaver) // We are or we are not the screensaver, prevent reentry...
            {
                if (!(ppiScrnSaver->W32PF_flags & W32PF_IDLESCREENSAVER))
                {
                    ppiScrnSaver->W32PF_flags |= W32PF_IDLESCREENSAVER;
                    ERR("Screensaver is Idle\n");
                }
            }
            else
            {
                PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
                if (ForegroundQueue && ForegroundQueue->spwndActive)
                    UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_START_SCREENSAVE, 1); // lParam 1 == Secure
                else
                    UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_START_SCREENSAVE, 0);
            }
        }
    }
}
コード例 #2
0
LRESULT FASTCALL
DefWndHandleSysCommand(PWND pWnd, WPARAM wParam, LPARAM lParam)
{
   LRESULT lResult = 0;
   BOOL Hook = FALSE;

   if (ISITHOOKED(WH_CBT) || (pWnd->head.rpdesk->pDeskInfo->fsHooks & HOOKID_TO_FLAG(WH_CBT)))
   {
      Hook = TRUE;
      lResult = co_HOOK_CallHooks(WH_CBT, HCBT_SYSCOMMAND, wParam, lParam);

      if (lResult) return lResult;
   }

   switch (wParam & 0xfff0)
   {
      case SC_SCREENSAVE:
        ERR("Screensaver Called!\n");
        UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_START_SCREENSAVE, 0); // always lParam 0 == not Secure
        break;

      default:
   // We do not support anything else here so we should return normal even when sending a hook.
        return 0;
   }

   return(Hook ? 1 : 0); // Don't call us again from user space.
}
コード例 #3
0
ファイル: winsta.c プロジェクト: reactos/reactos
BOOL
APIENTRY
NtUserLockWorkStation(VOID)
{
    BOOL ret;
    PTHREADINFO pti = PsGetCurrentThreadWin32Thread();

    UserEnterExclusive();

    if (pti->rpdesk == IntGetActiveDesktop())
    {
        ret = UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_LOCK_WORKSTATION, 0);
    }
    else
    {
        ret = FALSE;
    }

    UserLeave();

    return ret;
}
コード例 #4
0
ファイル: simplecall.c プロジェクト: HBelusca/NasuTek-Odyssey
/*
 * @implemented
 */
DWORD_PTR
APIENTRY
NtUserCallOneParam(
   DWORD_PTR Param,
   DWORD Routine)
{
   DECLARE_RETURN(DWORD_PTR);

   TRACE("Enter NtUserCallOneParam\n");

   UserEnterExclusive();

   switch(Routine)
   {
      case ONEPARAM_ROUTINE_POSTQUITMESSAGE:
          {
                PTHREADINFO pti;
                pti = PsGetCurrentThreadWin32Thread();
                MsqPostQuitMessage(pti->MessageQueue, Param);
                RETURN(TRUE);
          }

      case ONEPARAM_ROUTINE_BEGINDEFERWNDPOS:
         {
             PSMWP psmwp;
             HDWP hDwp = NULL;
             INT count = (INT)Param;

             if (count < 0)
             {
                EngSetLastError(ERROR_INVALID_PARAMETER);
                RETURN(0);
             }
             /* Windows allows zero count, in which case it allocates context for 8 moves */
             if (count == 0) count = 8;

             psmwp = (PSMWP) UserCreateObject( gHandleTable,
                                               NULL,
                                              (PHANDLE)&hDwp,
                                               otSMWP,
                                               sizeof(SMWP));
             if (!psmwp) RETURN(0);
             psmwp->acvr = ExAllocatePoolWithTag(PagedPool, count * sizeof(CVR), USERTAG_SWP);
             if (!psmwp->acvr)
             {
                UserDeleteObject(hDwp, otSMWP);
                RETURN(0);
             }
             RtlZeroMemory(psmwp->acvr, count * sizeof(CVR));
             psmwp->bHandle = TRUE;
             psmwp->ccvr = 0;          // actualCount
             psmwp->ccvrAlloc = count; // suggestedCount             
             RETURN((DWORD_PTR)hDwp);
         }

      case ONEPARAM_ROUTINE_SHOWCURSOR:
         RETURN( (DWORD_PTR)UserShowCursor((BOOL)Param) );

      case ONEPARAM_ROUTINE_GETDESKTOPMAPPING:
         {
             PTHREADINFO ti;
             ti = GetW32ThreadInfo();
             if (ti != NULL)
             {
                /* Try convert the pointer to a user mode pointer if the desktop is
                   mapped into the process */
                RETURN((DWORD_PTR)DesktopHeapAddressToUser((PVOID)Param));
             }
             else
             {
                RETURN(0);
             }
         }

      case ONEPARAM_ROUTINE_WINDOWFROMDC:
         RETURN( (DWORD_PTR)IntWindowFromDC((HDC)Param));

      case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON:
         {
            DWORD_PTR Result;

            Result = gspv.bMouseBtnSwap;
            gspv.bMouseBtnSwap = Param ? TRUE : FALSE;
            gpsi->aiSysMet[SM_SWAPBUTTON] = gspv.bMouseBtnSwap;
            RETURN(Result);
         }

      case ONEPARAM_ROUTINE_SWITCHCARETSHOWING:
         RETURN( (DWORD_PTR)IntSwitchCaretShowing((PVOID)Param));

      case ONEPARAM_ROUTINE_SETCARETBLINKTIME:
         RETURN( (DWORD_PTR)IntSetCaretBlinkTime((UINT)Param));

      case ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO:
         RETURN( (DWORD_PTR)MsqSetMessageExtraInfo((LPARAM)Param));

      case ONEPARAM_ROUTINE_CREATEEMPTYCUROBJECT:
         {
            PCURICON_OBJECT CurIcon;
			DWORD_PTR Result ;

            if (!(CurIcon = IntCreateCurIconHandle()))
            {
               EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
               RETURN(0);
            }

            Result = (DWORD_PTR)CurIcon->Self;
			UserDereferenceObject(CurIcon);
			RETURN(Result);
         }

      case ONEPARAM_ROUTINE_GETCURSORPOSITION:
         {
             BOOL ret = TRUE;

            _SEH2_TRY
            {
               ProbeForWrite((POINT*)Param,sizeof(POINT),1);
               RtlCopyMemory((POINT*)Param,&gpsi->ptCursor,sizeof(POINT));
            }
            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
            {
                SetLastNtError(_SEH2_GetExceptionCode());
                ret = FALSE;
            }
            _SEH2_END;

            RETURN (ret);
         }

      case ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING:
         {
            BOOL Enable;
            PPROCESSINFO Process = PsGetCurrentProcessWin32Process();

            if(Process != NULL)
            {
               Enable = (BOOL)(Param != 0);

               if(Enable)
               {
                  Process->W32PF_flags &= ~W32PF_NOWINDOWGHOSTING;
               }
               else
               {
                  Process->W32PF_flags |= W32PF_NOWINDOWGHOSTING;
               }

               RETURN( TRUE);
            }

            RETURN( FALSE);
         }

      case ONEPARAM_ROUTINE_GETINPUTEVENT:
         RETURN( (DWORD_PTR)IntMsqSetWakeMask(Param));

      case ONEPARAM_ROUTINE_GETKEYBOARDTYPE:
         RETURN( UserGetKeyboardType(Param));

      case ONEPARAM_ROUTINE_GETKEYBOARDLAYOUT:
         RETURN( (DWORD_PTR)UserGetKeyboardLayout(Param));

      case ONEPARAM_ROUTINE_RELEASEDC:
         RETURN (UserReleaseDC(NULL, (HDC) Param, FALSE));

      case ONEPARAM_ROUTINE_REALIZEPALETTE:
         RETURN (UserRealizePalette((HDC) Param));

      case ONEPARAM_ROUTINE_GETQUEUESTATUS:
      {
         RETURN (IntGetQueueStatus((DWORD)Param));
      }
      case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS:
         /* FIXME: Should use UserEnterShared */
         RETURN(IntEnumClipboardFormats(Param));

      case ONEPARAM_ROUTINE_CSRSS_GUICHECK:
          IntUserManualGuiCheck(Param);
          RETURN(TRUE);

      case ONEPARAM_ROUTINE_GETCURSORPOS:
      {
          BOOL Ret = TRUE;
          PPOINTL pptl;
          PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
          if (pti->hdesk != InputDesktopHandle) RETURN(FALSE);
          _SEH2_TRY
          {
             pptl = (PPOINTL)Param;
             *pptl = gpsi->ptCursor;
          }
          _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
          {
             Ret = FALSE;
          }
          _SEH2_END;
          RETURN(Ret);
      }
      case ONEPARAM_ROUTINE_SETPROCDEFLAYOUT:
      {
          PPROCESSINFO ppi;
          if (Param & LAYOUT_ORIENTATIONMASK)
          {
             ppi = PsGetCurrentProcessWin32Process();
             ppi->dwLayout = Param;
             RETURN(TRUE);
          }
          EngSetLastError(ERROR_INVALID_PARAMETER);
          RETURN(FALSE);
      }
      case ONEPARAM_ROUTINE_GETPROCDEFLAYOUT:
      {
          BOOL Ret = TRUE;
          PPROCESSINFO ppi;
          PDWORD pdwLayout;
          if ( PsGetCurrentProcess() == CsrProcess)
          {
             EngSetLastError(ERROR_INVALID_ACCESS);
             RETURN(FALSE);
          }
          ppi = PsGetCurrentProcessWin32Process();
          _SEH2_TRY
          {
             pdwLayout = (PDWORD)Param;
             *pdwLayout = ppi->dwLayout;
          }
          _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
          {
             SetLastNtError(_SEH2_GetExceptionCode());
             Ret = FALSE;
          }
          _SEH2_END;
          RETURN(Ret);
      }
      case ONEPARAM_ROUTINE_REPLYMESSAGE:
          RETURN (co_MsqReplyMessage((LRESULT) Param));
      case ONEPARAM_ROUTINE_MESSAGEBEEP:
          RETURN ( UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_MESSAGE_BEEP, Param) );
		  /* TODO: Implement sound sentry */
   }
   ERR("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
           Routine, Param);
   EngSetLastError(ERROR_INVALID_PARAMETER);
   RETURN( 0);

CLEANUP:
   TRACE("Leave NtUserCallOneParam, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}
コード例 #5
0
ファイル: timer.c プロジェクト: HBelusca/NasuTek-Odyssey
//
// Process win32k system timers.
//
VOID
CALLBACK
SystemTimerProc(HWND hwnd,
                UINT uMsg,
         UINT_PTR idEvent,
             DWORD dwTime)
{
  PDESKTOP pDesk;
  PWND pWnd = NULL;

  if (hwnd)
  {
     pWnd = UserGetWindowObject(hwnd);
     if (!pWnd)
     {
        ERR( "System Timer Proc has invalid window handle! 0x%x Id: %d\n", hwnd, idEvent);
        return;
     }
  }
  else
  {
     TRACE( "Windowless Timer Running!\n" );
     return;
  }

  switch (idEvent)
  {
/*
   Used in NtUserTrackMouseEvent.
 */
     case ID_EVENT_SYSTIMER_MOUSEHOVER:
       {
          POINT Point;
          UINT Msg;
          WPARAM wParam;

          pDesk = pWnd->head.rpdesk;
          if ( pDesk->dwDTFlags & DF_TME_HOVER &&
               pWnd == pDesk->spwndTrack )
          {
             Point = gpsi->ptCursor;
             if ( RECTL_bPointInRect(&pDesk->rcMouseHover, Point.x, Point.y) )
             {
                if (pDesk->htEx == HTCLIENT) // In a client area.
                {
                   wParam = get_key_state();
                   Msg = WM_MOUSEHOVER;

                   if (pWnd->ExStyle & WS_EX_LAYOUTRTL)
                   {
                      Point.x = pWnd->rcClient.right - Point.x - 1;
                   }
                   else
                      Point.x -= pWnd->rcClient.left;
                   Point.y -= pWnd->rcClient.top;
                }
                else
                {
                   wParam = pDesk->htEx; // Need to support all HTXYZ hits.
                   Msg = WM_NCMOUSEHOVER;
                }
                UserPostMessage(hwnd, Msg, wParam, MAKELPARAM(Point.x, Point.y));
                pDesk->dwDTFlags &= ~DF_TME_HOVER;
                break; // Kill this timer.
             }
          }
       }
       return; // Not this window so just return.

     default:
       ERR( "System Timer Proc invalid id %d!\n", idEvent );
       break;
  }
  IntKillTimer(pWnd, idEvent, TRUE);
}
コード例 #6
0
ファイル: hotkey.c プロジェクト: Moteesh/reactos
/*
 * co_UserProcessHotKeys
 *
 * Sends WM_HOTKEY message if given keys are hotkey
 */
BOOL NTAPI
co_UserProcessHotKeys(WORD wVk, BOOL bIsDown)
{
    UINT fModifiers;
    PHOT_KEY pHotKey;
    PWND pWnd;
    BOOL DoNotPostMsg = FALSE;
    BOOL IsModifier = FALSE;

    if (wVk == VK_SHIFT || wVk == VK_CONTROL || wVk == VK_MENU ||
        wVk == VK_LWIN || wVk == VK_RWIN)
    {
        /* Remember that this was a modifier */
        IsModifier = TRUE;
    }

    fModifiers = IntGetModifiers(gafAsyncKeyState);

    if (bIsDown)
    {
        if (IsModifier)
        {
            /* Modifier key down -- no hotkey trigger, but remember this */
            gfsModOnlyCandidate = fModifiers;
            return FALSE;
        }
        else
        {
            /* Regular key down -- check for hotkey, and reset mod candidates */
            pHotKey = IsHotKey(fModifiers, wVk);
            gfsModOnlyCandidate = 0;
        }
    }
    else
    {
        if (IsModifier)
        {
            /* Modifier key up -- modifier-only keys are triggered here */
            pHotKey = IsHotKey(gfsModOnlyCandidate, 0);
            gfsModOnlyCandidate = 0;
        }
        else
        {
            /* Regular key up -- no hotkey, but reset mod-only candidates */
            gfsModOnlyCandidate = 0;
            return FALSE;
        }
    }

    if (pHotKey)
    {
        TRACE("Hot key pressed (pWnd %p, id %d)\n", pHotKey->pWnd, pHotKey->id);

        /* FIXME: See comment about "UserDebuggerHotKey" on top of this file. */
        if (pHotKey->id == IDHK_SHIFTF12 || pHotKey->id == IDHK_F12)
        {
            if (bIsDown)
            {
                ERR("Hot key pressed for Debug Activation! ShiftF12 = %d or F12 = %d\n",pHotKey->id == IDHK_SHIFTF12 , pHotKey->id == IDHK_F12);
                //DoNotPostMsg = co_ActivateDebugger(); // FIXME
            }
            return DoNotPostMsg;
        }

        /* WIN and F12 keys are not hardcoded here. See comments on top of this file. */
        if (pHotKey->id == IDHK_WINKEY)
        {
            ASSERT(!bIsDown);
            pWnd = ValidateHwndNoErr(InputWindowStation->ShellWindow);
            if (pWnd)
            {
               TRACE("System Hot key Id %d Key %u\n", pHotKey->id, wVk );
               UserPostMessage(UserHMGetHandle(pWnd), WM_SYSCOMMAND, SC_TASKLIST, 0);
               co_IntShellHookNotify(HSHELL_TASKMAN, 0, 0);
               return FALSE;
            }
        }
        
        if (pHotKey->id == IDHK_SNAP_LEFT ||
            pHotKey->id == IDHK_SNAP_RIGHT ||
            pHotKey->id == IDHK_SNAP_UP ||
            pHotKey->id == IDHK_SNAP_DOWN)
        {
            HWND topWnd = UserGetForegroundWindow();
            if (topWnd)
            {
                UserPostMessage(topWnd, WM_KEYDOWN, wVk, 0);
            }
            return TRUE;
        }

        if (!pHotKey->pWnd)
        {
            TRACE("UPTM Hot key Id %d Key %u\n", pHotKey->id, wVk );
            UserPostThreadMessage(pHotKey->pti, WM_HOTKEY, pHotKey->id, MAKELONG(fModifiers, wVk));
            //ptiLastInput = pHotKey->pti;
            return TRUE; /* Don't send any message */
        }
        else
        {
            pWnd = pHotKey->pWnd;
            if (pWnd == PWND_BOTTOM)
            {
                if (gpqForeground == NULL)
                    return FALSE;

                pWnd = gpqForeground->spwndFocus;
            }

            if (pWnd)
            {
                //  pWnd->head.rpdesk->pDeskInfo->spwndShell needs testing.
                if (pWnd == ValidateHwndNoErr(InputWindowStation->ShellWindow) && pHotKey->id == SC_TASKLIST)
                {
                    UserPostMessage(UserHMGetHandle(pWnd), WM_SYSCOMMAND, SC_TASKLIST, 0);
                    co_IntShellHookNotify(HSHELL_TASKMAN, 0, 0);
                }
                else
                {
                    TRACE("UPM Hot key Id %d Key %u\n", pHotKey->id, wVk );
                    UserPostMessage(UserHMGetHandle(pWnd), WM_HOTKEY, pHotKey->id, MAKELONG(fModifiers, wVk));
                }
                //ptiLastInput = pWnd->head.pti;
                return TRUE; /* Don't send any message */
            }
        }
    }
    return FALSE;
}
コード例 #7
0
ファイル: main.c プロジェクト: hackbunny/reactos
NTSTATUS
NTAPI
UserDestroyThreadInfo(struct _ETHREAD *Thread)
{
    PTHREADINFO *ppti;
    PSINGLE_LIST_ENTRY psle;
    PPROCESSINFO ppiCurrent;
    struct _EPROCESS *Process;
    PTHREADINFO ptiCurrent;

    Process = Thread->ThreadsProcess;

    /* Get the Win32 Thread */
    ptiCurrent = PsGetThreadWin32Thread(Thread);

    ASSERT(ptiCurrent);

    TRACE_CH(UserThread,"Destroying pti 0x%p eThread 0x%p\n", ptiCurrent, Thread);

    ptiCurrent->TIF_flags |= TIF_INCLEANUP;
    ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;

    ppiCurrent = ptiCurrent->ppi;
    ASSERT(ppiCurrent);

    IsRemoveAttachThread(ptiCurrent);

    ptiCurrent->TIF_flags |= TIF_DONTATTACHQUEUE;
    ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;

    /* Decrement thread count and check if its 0 */
    ppiCurrent->cThreads--;

    if(ptiCurrent->TIF_flags & TIF_GUITHREADINITIALIZED)
    {
        /* Do now some process cleanup that requires a valid win32 thread */
        if(ptiCurrent->ppi->cThreads == 0)
        {
            /* Check if we have registered the user api hook */
            if(ptiCurrent->ppi == ppiUahServer)
            {
                /* Unregister the api hook */
                UserUnregisterUserApiHook();
            }

            /* Notify logon application to restart shell if needed */
            if(ptiCurrent->pDeskInfo)
            {
                if(ptiCurrent->pDeskInfo->ppiShellProcess == ppiCurrent)
                {
                    DWORD ExitCode = PsGetProcessExitStatus(Process);

                    TRACE_CH(UserProcess, "Shell process is exiting (%lu)\n", ExitCode);

                    UserPostMessage(hwndSAS,
                                    WM_LOGONNOTIFY,
                                    LN_SHELL_EXITED,
                                    ExitCode);

                    ptiCurrent->pDeskInfo->ppiShellProcess = NULL;
                }
            }
        }

        DceFreeThreadDCE(ptiCurrent);
        HOOK_DestroyThreadHooks(Thread);
        EVENT_DestroyThreadEvents(Thread);
        DestroyTimersForThread(ptiCurrent);
        KeSetEvent(ptiCurrent->pEventQueueServer, IO_NO_INCREMENT, FALSE);
        UnregisterThreadHotKeys(ptiCurrent);
        /*
                if (IsListEmpty(&ptiCurrent->WindowListHead))
                {
                   ERR_CH(UserThread,"Thread Window List is Empty!\n");
                }
        */
        co_DestroyThreadWindows(Thread);

        if (ppiCurrent && ppiCurrent->ptiList == ptiCurrent && !ptiCurrent->ptiSibling &&
                ppiCurrent->W32PF_flags & W32PF_CLASSESREGISTERED)
        {
            TRACE_CH(UserThread,"DestroyProcessClasses\n");
            /* no process windows should exist at this point, or the function will assert! */
            DestroyProcessClasses(ppiCurrent);
            ppiCurrent->W32PF_flags &= ~W32PF_CLASSESREGISTERED;
        }

        IntBlockInput(ptiCurrent, FALSE);
        IntCleanupThreadCallbacks(ptiCurrent);

        /* cleanup user object references stack */
        psle = PopEntryList(&ptiCurrent->ReferencesList);
        while (psle)
        {
            PUSER_REFERENCE_ENTRY ref = CONTAINING_RECORD(psle, USER_REFERENCE_ENTRY, Entry);
            TRACE_CH(UserThread,"thread clean: remove reference obj 0x%p\n",ref->obj);
            UserDereferenceObject(ref->obj);

            psle = PopEntryList(&ptiCurrent->ReferencesList);
        }
    }

    /* Find the THREADINFO in the PROCESSINFO's list */
    ppti = &ppiCurrent->ptiList;
    while (*ppti != NULL && *ppti != ptiCurrent)
    {
        ppti = &((*ppti)->ptiSibling);
    }

    /* we must have found it */
    ASSERT(*ppti == ptiCurrent);

    /* Remove it from the list */
    *ppti = ptiCurrent->ptiSibling;

    if (ptiCurrent->KeyboardLayout)
        UserDereferenceObject(ptiCurrent->KeyboardLayout);

    if (gptiForeground == ptiCurrent)
    {
//       IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
//       IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, NULL, OBJID_WINDOW, CHILDID_SELF, 0);

        gptiForeground = NULL;
    }

    // Fixes CORE-6384 & CORE-7030.
    /*    if (ptiLastInput == ptiCurrent)
        {
           if (!ppiCurrent->ptiList)
              ptiLastInput = gptiForeground;
           else
              ptiLastInput = ppiCurrent->ptiList;
           ERR_CH(UserThread,"DTI: ptiLastInput is Cleared!!\n");
        }
    */
    TRACE_CH(UserThread,"Freeing pti 0x%p\n", ptiCurrent);

    /* Free the THREADINFO */
    IntDereferenceThreadInfo(ptiCurrent);

    return STATUS_SUCCESS;
}
コード例 #8
0
ファイル: hotkey.c プロジェクト: hoangduit/reactos
/*
 * co_UserProcessHotKeys
 *
 * Sends WM_HOTKEY message if given keys are hotkey
 */
BOOL NTAPI
co_UserProcessHotKeys(WORD wVk, BOOL bIsDown)
{
    UINT fModifiers;
    PHOT_KEY pHotKey;
    PWND pWnd;
    BOOL DoNotPostMsg = FALSE;

    if (wVk == VK_SHIFT || wVk == VK_CONTROL || wVk == VK_MENU ||
        wVk == VK_LWIN || wVk == VK_RWIN)
    {
        /* Those keys are specified by modifiers */
        wVk = 0;
    }

    fModifiers = IntGetModifiers(gafAsyncKeyState);

    /* Check if it is a hotkey */
    pHotKey = IsHotKey(fModifiers, wVk);

    if (pHotKey)
    {
        TRACE("Hot key pressed (pWnd %p, id %d)\n", pHotKey->pWnd, pHotKey->id);

        /* FIXME: See comment about "UserDebuggerHotKey" on top of this file. */
        if (pHotKey->id == IDHK_SHIFTF12 || pHotKey->id == IDHK_F12)
        {
            if (bIsDown)
            {
                ERR("Hot key pressed for Debug Activation! ShiftF12 = %d or F12 = %d\n",pHotKey->id == IDHK_SHIFTF12 , pHotKey->id == IDHK_F12);
                //DoNotPostMsg = co_ActivateDebugger(); // FIXME
            }
            return DoNotPostMsg;
        }

        /* Process hotkey if it is key up event */
        if (!bIsDown)
        {
            /* WIN and F12 keys are not hardcoded here. See comments on top of this file. */
            if (pHotKey->id == IDHK_WINKEY && bWinHotkeyActive)
            {
                pWnd = ValidateHwndNoErr(InputWindowStation->ShellWindow);
                if (pWnd)
                {
                   TRACE("System Hot key Id %d Key %d\n",pHotKey->id, wVk );
                   UserPostMessage(UserHMGetHandle(pWnd), WM_SYSCOMMAND, SC_TASKLIST, 0);
                   co_IntShellHookNotify(HSHELL_TASKMAN, 0, 0);
                   bWinHotkeyActive = FALSE;
                   return FALSE;
                }
            }
        }
        else
        {    /* The user pressed the win key */
            if (pHotKey->id == IDHK_WINKEY)
            {
               bWinHotkeyActive = TRUE;
               return FALSE;
            }
        }

        if (bIsDown)
        {
            if (!pHotKey->pWnd)
            {
                TRACE("UPTM Hot key Id %d Key %d\n",pHotKey->id, wVk );
                UserPostThreadMessage(pHotKey->pti, WM_HOTKEY, pHotKey->id, MAKELONG(fModifiers, wVk));
                //ptiLastInput = pHotKey->pti;
                return TRUE; /* Don't send any message */
            }
            else
            {
               if (pHotKey->pWnd == PWND_BOTTOM)
               {
                   if (gpqForeground != NULL)
                   {
                      pWnd = gpqForeground->spwndFocus;
                   }
                   else
                      return FALSE;
                }
                else
                {
                   pWnd = pHotKey->pWnd;
                }
                if (pWnd)
                {          //  pWnd->head.rpdesk->pDeskInfo->spwndShell needs testing.
                   if (pWnd == ValidateHwndNoErr(InputWindowStation->ShellWindow) && pHotKey->id == SC_TASKLIST)
                   {
                      ERR("Sending to shell window w/o IDHK_WINKEY..\n");
                      UserPostMessage(UserHMGetHandle(pWnd), WM_SYSCOMMAND, SC_TASKLIST, 0);
                   }
                   else
                   {
                      TRACE("UPM Hot key Id %d Key %d\n",pHotKey->id, wVk );
                      UserPostMessage(UserHMGetHandle(pWnd), WM_HOTKEY, pHotKey->id, MAKELONG(fModifiers, wVk));
                   }
                   //ptiLastInput = pWnd->head.pti;
                   return TRUE; /* Don't send any message */
                }
            }
        }
    }
    return FALSE;
}