Пример #1
0
BOOL NotifyLogon(
    PWINDOWSTATION pwinsta,
    PLUID pluidCaller,
    DWORD dwFlags)
{
    BOOL fNotified = FALSE;
    PWND pwndWinlogon;

    if (dwFlags & EWX_SHUTDOWN) {
        for (pwinsta = grpwinstaList; pwinsta != NULL;
                pwinsta = pwinsta->rpwinstaNext) {
            pwndWinlogon = pwinsta->spwndLogonNotify;
            if (pwndWinlogon != NULL) {
                _PostMessage(pwndWinlogon, WM_LOGONNOTIFY, LOGON_LOGOFF,
                        (LONG)dwFlags);
                fNotified = TRUE;
            }
        }
    } else {
        LUID  luidSystem = SYSTEM_LUID;

        pwndWinlogon = pwinsta->spwndLogonNotify;
        if (pwndWinlogon != NULL &&
                (RtlEqualLuid(&pwinsta->luidUser, pluidCaller) ||
                 RtlEqualLuid(&luidSystem, pluidCaller))) {
            _PostMessage(pwndWinlogon, WM_LOGONNOTIFY, LOGON_LOGOFF,
                    (LONG)dwFlags);
            fNotified = TRUE;
        }
    }
    return fNotified;
}
Пример #2
0
/***************************************************************************\
* xxxCancelMouseMoveTracking
*
* History
* 12/07/96 GerardoB  Created
\***************************************************************************/
void xxxCancelMouseMoveTracking (DWORD dwDTFlags, PWND pwndTrack, int htEx, DWORD dwDTCancel)
{

    CheckLock(pwndTrack);
    /*
     * Hottracking
     */
    if ((dwDTFlags & DF_HOTTRACKING) && (dwDTCancel & DF_HOTTRACKING)) {
        /*
         * The current state must be owned by the current queue.
         * Otherwise, we're about to do an inter-queue cancelation.
         */
        UserAssert(PtiCurrent()->pq == GETPTI(pwndTrack)->pq);

        xxxHotTrack(pwndTrack, htEx, FALSE);
    }

    /*
     * Tooltips
     */
    if ((dwDTFlags & DF_TOOLTIPSHOWING) && (dwDTCancel & DF_TOOLTIP)) {
        PTOOLTIPWND pttwnd = (PTOOLTIPWND)PWNDTOOLTIP(pwndTrack);
        TL tlpwnd;

        ThreadLockAlways(pttwnd, &tlpwnd);
        xxxResetTooltip(pttwnd);
        ThreadUnlock(&tlpwnd);
    }

    /*
     * Mouse Leave
     */
    if ((dwDTFlags & DF_TRACKMOUSELEAVE) && (dwDTCancel & DF_TRACKMOUSELEAVE)) {
        _PostMessage(pwndTrack,
                     ((htEx == HTCLIENT) ? WM_MOUSELEAVE : WM_NCMOUSELEAVE),
                     0, 0);
    }

    /*
     * Mouse Hover
     */
    if ((dwDTFlags & DF_TRACKMOUSEHOVER) && (dwDTCancel & DF_TRACKMOUSEHOVER)) {
        _KillSystemTimer(pwndTrack, IDSYS_MOUSEHOVER);
    }
}
Пример #3
0
BOOL _TranslateMessage(
    LPMSG pmsg,
    UINT flags)
{
    PTHREADINFO pti;
    UINT wMsgType;
    WORD *pwParam;
    int cChar;
    BOOL fSysKey = FALSE;
    BOOL bBreak;
    LPARAM lParam;

    switch (pmsg->message) {

    default:
        return FALSE;

    case WM_SYSKEYDOWN:
        /*
         * HACK carried over from Win3 code: system messages
         * only get posted during KEYDOWN processing - so
         * set fSysKey only for WM_SYSKEYDOWN.
         */
        fSysKey = TRUE;
        /*
         * Fall thru...
         */

    case WM_SYSKEYUP:
    case WM_KEYDOWN:
    case WM_KEYUP:
        pti = PtiCurrent();

        if ((pti->pMenuState != NULL) &&
                (HW(pti->pMenuState->pGlobalPopupMenu->spwndPopupMenu) ==
                pmsg->hwnd)) {
            flags |= 1;
        } else {
            flags &= ~1;
        }

        /*
         * Don't change the contents of the passed in structure.
         */
        lParam = pmsg->lParam;

        cChar = InternalToUnicode(LOWORD(pmsg->wParam),  // virtual key code
                         HIWORD(lParam),  // scan code, make/break bit
                         pti->pq->afKeyState,
                         pState, 16,  // see init.c
                         flags, &bBreak);

/*
 * LATER 12/7/90 - GregoryW
 * Note: Win3.x TranslateMessage returns TRUE if ToAscii is called.
 *       Proper behavior is to return TRUE if any translation is
 *       performed by ToAscii.  If we have to remain compatible
 *       (even though apps clearly don't currently care about the
 *       return value) then the following return should be changed
 *       to TRUE.  If we want the new 32-bit apps to have a meaningful
 *       return value we should leave this as FALSE.
 *
 *      If console is calling us with the TM_POSTCHARBREAKS flag then we
 *      return FALSE if no char was actually posted
 *
 *      !!! LATER get console to change so it does not need private API
 *      TranslateMessageEx
 */

        if (!cChar) {
            if (flags & TM_POSTCHARBREAKS)
                return FALSE;
            else
                return TRUE;
        }

        /*
         * Some translation performed.  Figure out what type of
         * message to post.
         *
         */
        if (cChar > 0)
            wMsgType = (fSysKey) ? (UINT)WM_SYSCHAR : (UINT)WM_CHAR;
        else {
            wMsgType = (fSysKey) ? (UINT)WM_SYSDEADCHAR : (UINT)WM_DEADCHAR;
            cChar = -cChar;                // want positive value
        }

        if (bBreak) {
            lParam |=  0x80000000;
        } else {
            lParam &= ~0x80000000;
        }

        pwParam = (WORD *)pState;

        for ( ; cChar > 0; cChar--) {

            /*
             * If this is a multi-character posting, all but the last one
             * should be marked as fake keystrokes for Console/VDM.
             */

            _PostMessage(PW(pmsg->hwnd), wMsgType, (DWORD)*pwParam,
                    lParam | (cChar > 1 ? FAKE_KEYSTROKE : 0));

            *pwParam = 0;        // zero out old character
            pwParam += 1;
        }

        return TRUE;
    }
}
Пример #4
0
BOOL xxxDoHotKeyStuff(
    UINT vk,
    BOOL fBreak,
    DWORD fsReserveKeys)
{
#ifdef WINDOWS_NOT_HOT
    static BOOL fOnlyWinKey = FALSE;
#endif
    static UINT fsModifiers = 0;
    static UINT fsModOnlyCandidate = 0;
    UINT fsModOnlyHotkey;
    UINT fs;
    PHOTKEY phk;
    PWND pwnd;
    BOOL fCancel;
    BOOL fEatDebugKeyBreak = FALSE;

    CheckCritIn();

    /*
     * Update fsModifiers.
     */
    fs = 0;
    fsModOnlyHotkey = 0;

    switch (vk) {
    case VK_RSHIFT:
        fs = MOD_RSHIFT;
    case VK_LSHIFT:
    case VK_SHIFT:
        vk = VK_SHIFT;
        fs |= MOD_SHIFT;
        break;

    case VK_RCONTROL:
        fs = MOD_RCONTROL;
    case VK_LCONTROL:
        vk = VK_CONTROL;
    case VK_CONTROL:
        fs |= MOD_CONTROL;
        break;

    case VK_RMENU:
        fs = MOD_RALT;
    case VK_LMENU:
        vk = VK_MENU;
    case VK_MENU:
        fs |= MOD_ALT;
        break;

    case VK_LWIN:
    case VK_RWIN:
        fs = MOD_WIN;
        break;

    default:
        /*
         * A non-modifier key rules out Modifier-Only hotkeys
         */
        fsModOnlyCandidate = 0;
        break;
    }

    if (fBreak) {
        fsModifiers &= ~fs;
        /*
         * If a modifier key is coming up, the current modifier only hotkey
         * candidate must be tested to see if it is a hotkey.  Store this
         * in fsModOnlyHotkey, and prevent the next key release from
         * being a candidate by clearing fsModOnlyCandidate.
         */
        if (fs != 0) {
            fsModOnlyHotkey = fsModOnlyCandidate;
            fsModOnlyCandidate = 0;
        }
    } else {
        fsModifiers |= fs;
        /*
         * If a modifier key is going down, we have a modifier-only hotkey
         * candidate.  Save current modifier state until the following break.
         */
        if (fs != 0) {
            fsModOnlyCandidate = fsModifiers;
        }
    }

    if (vk == VK_DELETE) {
        /*
         * Special case for SAS (Ctrl+Alt+Del) - examine physical key state!
         *
         * An evil daemon process can fool convincingly pretend to be winlogon
         * by registering Alt+Del as a hotkey, and spinning another thread that
         * continually calls keybd_event() to send the Ctrl key up: when the
         * user types Ctrl+Alt+Del, only Alt+Del will be seen by the system,
         * the evil daemon will get woken by WM_HOTKEY and can pretend to be
         * winlogon.  So look at gafPhysKeyState in this case, to see what keys
         * were physically pressed.
         * NOTE: If hotkeys are ever made to work under journal playback, make
         * sure they don't affect the gafPhysKeyState!  - IanJa.
         */
        UINT fPhysMods =
                (TestKeyDownBit(gafPhysKeyState, VK_MENU) ? MOD_ALT : 0) |
                (TestKeyDownBit(gafPhysKeyState, VK_SHIFT) ? MOD_SHIFT : 0) |
                (TestKeyDownBit(gafPhysKeyState, VK_CONTROL) ? MOD_CONTROL : 0);
        if ((fPhysMods & (MOD_CONTROL|MOD_ALT)) == MOD_CONTROL|MOD_ALT) {
            /*
             * Use physical modifiers keys
             */
            fsModifiers = fPhysMods;
        }
    }

#ifdef WINDOWS_NOT_HOT
    /*
     * track whether any key has been pressed since a Windows key went down
     */
    if (vk == VK_LWIN || vk == VK_RWIN) {
        if (!fBreak) {
            fOnlyWinKey = TRUE;
        } else if (fOnlyWinKey) {
            fOnlyWinKey = FALSE;
            CancelJournalling();

            pwnd = GETDESKINFO(PtiCurrent())->spwndShell;
            if (pwnd != NULL) {
                _PostMessage(pwnd, WM_SYSCOMMAND, SC_TASKLIST, 0);
                return TRUE;
            }
        }

    } else {
        fOnlyWinKey = FALSE;
    }
#endif

    /*
     * If the key is not a hotkey then we're done but first check if the
     * key is an Alt-Escape if so we need to cancel journalling.
     *
     * NOTE: Support for Alt+Esc to cancel journalling dropped in NT 4.0
     */
    if (fsModOnlyHotkey && fBreak) {
        /*
         * A hotkey involving only VK_SHIFT, VK_CONTROL, VK_MENU or VK_WINDOWS
         * must only operate on a key release.
         */
        if ((phk = IsHotKey(LOWORD(fsModOnlyHotkey), VK_NONE)) == NULL) {
            return FALSE;
        }
    } else if ((phk = IsHotKey(LOWORD(fsModifiers), vk)) == NULL) {
        return FALSE;
    }

    if (phk->id == IDHOT_WINDOWS) {
        pwnd = GETDESKINFO(PtiCurrent())->spwndShell;
        if (pwnd != NULL) {
            _PostMessage(pwnd, WM_SYSCOMMAND, SC_TASKLIST, 0);
            return TRUE;
        }
    }

    if ((phk->id == IDHOT_DEBUG) || (phk->id == IDHOT_DEBUGSERVER)) {

        if (!fBreak) {
            /*
             * The DEBUG key has been pressed.  Break the appropriate
             * thread into the debugger.
             */
            fEatDebugKeyBreak = xxxActivateDebugger(phk->fsModifiers);
        }

        /*
         * This'll eat the debug key down and break if we broke into
         * the debugger on the server only on the down.
         */
        return fEatDebugKeyBreak;
    }

    /*
     * don't allow hotkeys(except for ones owned by the logon process)
     * if the window station is locked.
     */

    if (((grpdeskRitInput->rpwinstaParent->dwFlags & WSF_SWITCHLOCK) != 0) &&
            (phk->pti->Thread->Cid.UniqueProcess != gpidLogon)) {
        return FALSE;
    }

    if ((fsModOnlyHotkey == 0) && fBreak) {
        /*
         * Do Modifier-Only hotkeys on break events, else return here.
         */
        return FALSE;
    }

    /*
     * Unhook hooks if a control-escape, alt-escape, or control-alt-del
     * comes through, so the user can cancel if the system seems hung.
     *
     * Note the hook may be locked so even if the unhook succeeds it
     * won't remove the hook from the global asphkStart array.  So
     * we have to walk the list manually.  This code works because
     * we are in the critical section and we know other hooks won't
     * be deleted.
     *
     * Once we've unhooked, post a WM_CANCELJOURNAL message to the app
     * that set the hook so it knows we did this.
     *
     * NOTE: Support for Alt+Esc to cancel journalling dropped in NT 4.0
     */
    fCancel = FALSE;
    if (vk == VK_ESCAPE && LOWORD(fsModifiers) == MOD_CONTROL) {
        fCancel = TRUE;
    }

    if (vk == VK_DELETE && (fsModifiers & (MOD_CONTROL | MOD_ALT)) ==
            (MOD_CONTROL | MOD_ALT)) {
        fCancel = TRUE;
    }

    if (fCancel)
        CancelJournalling();

    /*
     * See if the key is reserved by a console window.  If it is,
     * return FALSE so the key will be passed to the console.
     */
    if (fsReserveKeys != 0) {
        switch (vk) {
        case VK_TAB:
            if ((fsReserveKeys & CONSOLE_ALTTAB) &&
                    ((fsModifiers & (MOD_CONTROL | MOD_ALT)) == MOD_ALT)) {
                return FALSE;
            }
            break;
        case VK_ESCAPE:
            if ((fsReserveKeys & CONSOLE_ALTESC) &&
                    ((fsModifiers & (MOD_CONTROL | MOD_ALT)) == MOD_ALT)) {
                return FALSE;
            }
            if ((fsReserveKeys & CONSOLE_CTRLESC) &&
                    ((fsModifiers & (MOD_CONTROL | MOD_ALT)) == MOD_CONTROL)) {
                return FALSE;
            }
            break;
        case VK_RETURN:
            if ((fsReserveKeys & CONSOLE_ALTENTER) &&
                    ((fsModifiers & (MOD_CONTROL | MOD_ALT)) == MOD_ALT)) {
                return FALSE;
            }
            break;
        case VK_SNAPSHOT:
            if ((fsReserveKeys & CONSOLE_PRTSC) &&
                    ((fsModifiers & (MOD_CONTROL | MOD_ALT)) == 0)) {
                return FALSE;
            }
            if ((fsReserveKeys & CONSOLE_ALTPRTSC) &&
                    ((fsModifiers & (MOD_CONTROL | MOD_ALT)) == MOD_ALT)) {
                return FALSE;
            }
            break;
        case VK_SPACE:
            if ((fsReserveKeys & CONSOLE_ALTSPACE) &&
                    ((fsModifiers & (MOD_CONTROL | MOD_ALT)) == MOD_ALT)) {
                return FALSE;
            }
            break;
        }
    }

    /*
     * If this is the task-list hotkey, go ahead and set foreground
     * status to the task-list queue right now.  This prevents problems
     * where the user hits ctrl-esc and types-ahead before the task-list
     * processes the hotkey and brings up the task-list window.
     */
    if ((LOWORD(fsModifiers) == MOD_CONTROL) && (vk == VK_ESCAPE) && !fBreak) {
        PWND pwndSwitch;
        TL tlpwndSwitch;

        if (ghwndSwitch != NULL) {
            pwndSwitch = PW(ghwndSwitch);
            ThreadLock(pwndSwitch, &tlpwndSwitch);
            xxxSetForegroundWindow2(pwndSwitch, NULL, 0);
            ThreadUnlock(&tlpwndSwitch);
        }
    }

    /*
     * Get the hot key contents.
     */
    if (phk->spwnd == NULL) {
        _PostThreadMessage(
                phk->pti, WM_HOTKEY, phk->id,
                MAKELONG(LOWORD(fsModifiers), vk));
    } else {
        if (phk->spwnd == PWND_INPUTOWNER) {
            if (gpqForeground != NULL) {
                pwnd = gpqForeground->spwndFocus;
            } else {
                return FALSE;
            }

        } else {
            pwnd = phk->spwnd;
        }

        if (pwnd) {
            if (pwnd == pwnd->head.rpdesk->pDeskInfo->spwndShell && phk->id == SC_TASKLIST) {
                _PostMessage(pwnd, WM_SYSCOMMAND, SC_TASKLIST, 0);
            } else {
                _PostMessage(pwnd, WM_HOTKEY, phk->id, MAKELONG(LOWORD(fsModifiers), vk));
            }
        }
    }

    /*
     * If this is a Modifier-Only hotkey, let the modifier break through
     * by returning FALSE, otherwise we will have modifier keys stuck down.
     */
    return (fsModOnlyHotkey == 0);
}
Пример #5
0
void PostMessageWait(dword dwProcID, dword dwEvent, byte *pBuff, int nLength)
{
	while (!_PostMessage(dwProcID, dwEvent, pBuff, nLength))
		::Sleep(110);
}