当前位置: 首页 > news >正文

win32k!xxxKeyEvent函数里面的win32k!xxxDoHotKeyStuff如何确定是CAD键的到来的

win32k!xxxKeyEvent函数里面的win32k!xxxDoHotKeyStuff如何确定是CAD键的到来的

chenghao@chenghaodeiMac core % grep "StartDeviceRead" -nr|grep -v "inary"
./ntuser/kernel/pnp.c:1687:* StartDeviceRead
./ntuser/kernel/pnp.c:1702:PDEVICEINFO StartDeviceRead(
./ntuser/kernel/pnp.c:1762:            TAGMSG1(DBGTAG_PNP, "StartDeviceRead: pDevInfo=%p has been closed on demand.", pDeviceInfo);
./ntuser/kernel/pnp.c:1767:                    TAGMSG1(DBGTAG_PNP, "StartDeviceRead: pDevInfo=%p, bFlags has been reset.", pDeviceInfo);
./ntuser/kernel/pnp.c:1876:        RIPMSG2(RIP_WARNING, "StartDeviceRead %#p failed Status %#x",
./ntuser/kernel/pnp.c:2108:                    pDeviceInfoNext = StartDeviceRead(pDeviceInfo);
./ntuser/kernel/pnp.c:2122:                    pDeviceInfoNext = StartDeviceRead(pDeviceInfo);
./ntuser/kernel/pnp.c:2214:            pDeviceInfoNext = StartDeviceRead(pDeviceInfo);
./ntuser/kernel/pnp.c:2248:                pDeviceInfoNext = StartDeviceRead(pDeviceInfo);
./ntuser/kernel/userk.h:4520:PDEVICEINFO StartDeviceRead(PDEVICEINFO pDeviceInfo);
./ntuser/kernel/ntinput.c:651:     * (see StartDeviceRead).
./ntuser/kernel/ntinput.c:2084:    StartDeviceRead(pDeviceInfo);
./ntuser/kernel/ntinput.c:2091:* has been processed by USER, StartDeviceRead() is called again to request
./ntuser/kernel/ntinput.c:4347:* have been consumed, calls StartDeviceRead() to request more keyboard events.

VOID NTAPI InputApc(
IN PVOID ApcContext,
IN PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG Reserved
)
{
PDEVICEINFO pDeviceInfo = (PDEVICEINFO)ApcContext;
UNREFERENCED_PARAMETER(Reserved);

    /*
* Check if the RIT is being terminated.
* If we hit this assertion, the RIT was killed by someone inadvertently.
* Not much can be done if it once happens.
*/
UserAssert(gptiRit);
UserAssert((gptiRit->TIF_flags & TIF_INCLEANUP) == 0);


#ifdef DIAGNOSE_IO
pDeviceInfo->nReadsOutstanding--;
#endif

    /*
* If this device needs freeing, abandon reading now and request the free.
* (Don't even process the input that we received in this APC)
*/
if (pDeviceInfo->usActions & GDIAF_FREEME) {
#ifdef GENERIC_INPUT
CheckCritOut();
EnterCrit();
#endif
EnterDeviceInfoListCrit();
pDeviceInfo->bFlags &= ~GDIF_READING;
FreeDeviceInfo(pDeviceInfo);
LeaveDeviceInfoListCrit();
#ifdef GENERIC_INPUT
LeaveCrit();
#endif
return;
}

    if (NT_SUCCESS(IoStatusBlock->Status) && pDeviceInfo->handle) {
PDEVICE_TEMPLATE pDevTpl = &aDeviceTemplate[pDeviceInfo->type];
pDevTpl->DeviceRead(pDeviceInfo);
}

    if (IsRemoteConnection()) {

        PoSetSystemState(ES_SYSTEM_REQUIRED);

    }

    StartDeviceRead(pDeviceInfo);
}


DEVICE_TEMPLATE aDeviceTemplate[DEVICE_TYPE_MAX + 1] = {
// DEVICE_TYPE_MOUSE
{
sizeof(GENERIC_DEVICE_INFO)+sizeof(MOUSE_DEVICE_INFO),    // cbDeviceInfo
&GUID_CLASS_MOUSE,                                        // pClassGUID
PMAP_MOUCLASS_PARAMS,                                     // uiRegistrySection
L"mouclass",                                              // pwszClassName
DD_MOUSE_DEVICE_NAME_U L"0",                              // pwszDefDevName
DD_MOUSE_DEVICE_NAME_U L"Legacy0",                        // pwszLegacyDevName
IOCTL_MOUSE_QUERY_ATTRIBUTES,                             // IOCTL_Attr
FIELD_OFFSET(DEVICEINFO, mouse.Attr),                     // offAttr
sizeof((PDEVICEINFO)NULL)->mouse.Attr,                    // cbAttr
FIELD_OFFSET(DEVICEINFO, mouse.Data),                     // offData
sizeof((PDEVICEINFO)NULL)->mouse.Data,                    // cbData
ProcessMouseInput,                                        // Reader routine
NULL                                                      // pkeHidChange
},
// DEVICE_TYPE_KEYBOARD
{
sizeof(GENERIC_DEVICE_INFO)+sizeof(KEYBOARD_DEVICE_INFO), // cbDeviceInfo
&GUID_CLASS_KEYBOARD,                                     // pClassGUID
PMAP_KBDCLASS_PARAMS,                                     // uiRegistrySection
L"kbdclass",                                              // pwszClassName
DD_KEYBOARD_DEVICE_NAME_U L"0",                           // pwszDefDevName
DD_KEYBOARD_DEVICE_NAME_U L"Legacy0",                     // pwszLegacyDevName
IOCTL_KEYBOARD_QUERY_ATTRIBUTES,                          // IOCTL_Attr
FIELD_OFFSET(DEVICEINFO, keyboard.Attr),                  // offAttr
sizeof((PDEVICEINFO)NULL)->keyboard.Attr,                 // cbAttr
FIELD_OFFSET(DEVICEINFO, keyboard.Data),                  // offData
sizeof((PDEVICEINFO)NULL)->keyboard.Data,                 // cbData
ProcessKeyboardInput,                                     // Reader routine
NULL                                                      // pkeHidChange
},
#ifdef GENERIC_INPUT
// DEVICE_TYPE_HID
{
sizeof(GENERIC_DEVICE_INFO)+sizeof(HID_DEVICE_INFO),        // cbDeviceInfo
&GUID_CLASS_INPUT,                                          // pClassGUID
0,                                                          // uiRegistrySection. LATER: add real one
L"hid",                                                     // pwszClassName
L"",                                                        // pwszDefDevName
L"",                                                        // pwszLegacyDevName
0,                                                          // IOCTL_ATTR
0,                                                          // offAttr
0,                                                          // cbAttr
0,                                                          // offData
0,                                                          // cbData
ProcessHidInput,                                            // Reader routine
NULL,                                                       // pkeHidChange,
DT_HID,                                                     // dwFlags
},
#endif
// Add new input device type template here
};


PDEVICEINFO StartDeviceRead(
PDEVICEINFO pDeviceInfo)
{

    /*
* Avoid to start reading NULL device handle.
* This happen when the DeviceNotify receives QUERY_REMOVE
* and the RIT finishes processing it, but RequestDeviceChange
* has not finished its wait.
*/
#ifdef GENERIC_INPUT
pDeviceInfo->ReadStatus = ZwReadFile(
pDeviceInfo->handle,
NULL,                // hReadEvent
InputApc,            // InputApc()
pDeviceInfo,         // ApcContext
&pDeviceInfo->iosb,
pBuffer,
ulLengthToRead,
PZERO(LARGE_INTEGER), NULL);
#else

        pDeviceInfo->ReadStatus = ZwReadFile(
pDeviceInfo->handle,
NULL,                // hReadEvent
InputApc,            // InputApc()
pDeviceInfo,         // ApcContext
&pDeviceInfo->iosb,
(PVOID)((PBYTE)pDeviceInfo + pDevTpl->offData),
pDevTpl->cbData,
PZERO(LARGE_INTEGER), NULL);
#endif


VOID ProcessKeyboardInput(PDEVICEINFO pDeviceInfo)
{
PKEYBOARD_INPUT_DATA pkei;
PKEYBOARD_INPUT_DATA pkeiStart, pkeiEnd;

    EnterCrit();
UserAssert(pDeviceInfo->type == DEVICE_TYPE_KEYBOARD);
UserAssert(pDeviceInfo->iosb.Information);
UserAssert(NT_SUCCESS(pDeviceInfo->iosb.Status));

    /*
* Switch the keyboard layout table, if the current KL has multiple
* tables.
*/
if (gpKL && gpKL->uNumTbl > 0 &&
(gpKL->dwLastKbdType != GET_KEYBOARD_DEVINFO_TYPE(pDeviceInfo) ||
gpKL->dwLastKbdSubType != GET_KEYBOARD_DEVINFO_SUBTYPE(pDeviceInfo))) {
SearchAndSetKbdTbl(pDeviceInfo,
GET_KEYBOARD_DEVINFO_TYPE(pDeviceInfo),
GET_KEYBOARD_DEVINFO_SUBTYPE(pDeviceInfo));
/*
* Whether or not we found the match, cache the type/subtype so that
* we will not try to find the same type/subtype for a while.
*/
gpKL->dwLastKbdType = GET_KEYBOARD_DEVINFO_TYPE(pDeviceInfo);
gpKL->dwLastKbdSubType = GET_KEYBOARD_DEVINFO_SUBTYPE(pDeviceInfo);
}

    pkeiStart = pDeviceInfo->keyboard.Data;
pkeiEnd   = (PKEYBOARD_INPUT_DATA)((PBYTE)pkeiStart + pDeviceInfo->iosb.Information);
for (pkei = pkeiStart; pkei < pkeiEnd; pkei++) {
ProcessKeyboardInputWorker(pkei,
#ifdef GENERIC_INPUT
pDeviceInfo,
#endif
TRUE);
}

    LeaveCrit();
}


VOID ProcessKeyboardInputWorker(
PKEYBOARD_INPUT_DATA pkei,
#ifdef GENERIC_INPUT
PDEVICEINFO pDeviceInfo,
#endif
BOOL fProcessRemap)
{

        //
// Keep track of real modifier key state.  Conveniently, the values for
// VK_LSHIFT, VK_RSHIFT, VK_LCONTROL, VK_RCONTROL, VK_LMENU and
// VK_RMENU are contiguous.  We'll construct a bit field to keep track
// of the current modifier key state.  If a bit is set, the corresponding
// modifier key is down.  The bit field has the following format:
//
//     +---------------------------------------------------+
//     | Right | Left  |  Right  |  Left   | Right | Left  |
//     |  Alt  |  Alt  | Control | Control | Shift | Shift |
//     +---------------------------------------------------+
//         5       4        3         2        1       0     Bit
//
// Add bit 7 -- VK_RWIN
//     bit 6 -- VK_LWIN

        switch (Vk) {
case VK_LSHIFT:
case VK_RSHIFT:
case VK_LCONTROL:
case VK_RCONTROL:
case VK_LMENU:
case VK_RMENU:
gCurrentModifierBit = 1 << (Vk & 0xf);
break;
case VK_LWIN:
gCurrentModifierBit = 0x40;
break;
case VK_RWIN:
gCurrentModifierBit = 0x80;
break;
default:
gCurrentModifierBit = 0;
}
if (gCurrentModifierBit) {
/*
* If this is a break of a modifier key then clear the bit value.
* Otherwise, set it.
*/
if (pkei->Flags & KEY_BREAK) {
gPhysModifierState &= ~gCurrentModifierBit;
} else {
gPhysModifierState |= gCurrentModifierBit;
}
}

        if (!TEST_ACCF(ACCF_ACCESSENABLED)) {
xxxProcessKeyEvent(&ke, (ULONG_PTR)pkei->ExtraInformation,
pkei->Flags & KEY_TERMSRV_SHADOW ? TRUE : FALSE);
} else {
if ((gtmridAccessTimeOut != 0) && TEST_ACCESSFLAG(AccessTimeOut, ATF_TIMEOUTON)) {
gtmridAccessTimeOut = InternalSetTimer(
NULL,
gtmridAccessTimeOut,
(UINT)gAccessTimeOut.iTimeOutMSec,
xxxAccessTimeOutTimer,
TMRF_RIT | TMRF_ONESHOT
);
}
if (AccessProceduresStream(&ke, pkei->ExtraInformation, 0)) {
xxxProcessKeyEvent(&ke, (ULONG_PTR)pkei->ExtraInformation,
pkei->Flags & KEY_TERMSRV_SHADOW ? TRUE : FALSE);
}
}
} else {


VOID xxxProcessKeyEvent(
PKE pke,
ULONG_PTR ExtraInformation,
BOOL bInjected)
{


} else {
if (KEOEMProcs(pke) && xxxKELocaleProcs(pke) && xxxKENLSProcs(pke,ExtraInformation)) {
xxxKeyEvent(pke->usFlaggedVk, pke->bScanCode,
pke->dwTime, ExtraInformation,
#ifdef GENERIC_INPUT
pke->hDevice,
&pke->data,
#endif
bInjected);
}

BOOL xxxDoHotKeyStuff(
UINT vk,
BOOL fBreak,
DWORD fsReserveKeys)
{
UINT fsModOnlyHotkey;
UINT fs;
PHOTKEY phk;
BOOL fCancel;
BOOL fEatDebugKeyBreak;
PWND pwnd;
BOOL bSAS;

    CheckCritIn();


chenghao@chenghaodeiMac core % grep "xxxDoHotKeyStuff" -nr|grep -v "inary"
./kmode/win32k.prf:2615:xxxDoHotKeyStuff@12
./ntuser/kernel/userk.h:5164:BOOL    xxxDoHotKeyStuff(UINT vk, BOOL fBreak, DWORD fsReserveKeys);
./ntuser/kernel/ntinput.c:2810:    if (xxxDoHotKeyStuff(Vk, fBreak, fsReserveKeys)) {
./ntuser/kernel/hotkeys.c:462: * The below two states are used by xxxDoHotKeyStuff().
./ntuser/kernel/hotkeys.c:488:* xxxDoHotKeyStuff
./ntuser/kernel/hotkeys.c:514:BOOL xxxDoHotKeyStuff(

VOID xxxKeyEvent(
USHORT    usFlaggedVk,
WORD      wScanCode,
DWORD     time,
ULONG_PTR ExtraInfo,
#ifdef GENERIC_INPUT
HANDLE    hDevice,
PKEYBOARD_INPUT_DATA pkei,
#endif
BOOL      bInjected)
{


/*
* Check for hotkeys.
*/
if (xxxDoHotKeyStuff(Vk, fBreak, fsReserveKeys)) {

/***************************************************************************\
* IsSAS
*
* Checks the physical state of keyboard modifiers that would effect SAS.
\***************************************************************************/
BOOL IsSAS(
BYTE vk,
UINT *pfsModifiers)
{
CheckCritIn();

    if (gvkSAS != vk) {
return FALSE;
}

    /*
* Special case for SAS - examine real physical modifier-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 gfsSASModifiersDown 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 gfsSASModifiersDown!  - IanJa.
*/
    if (gfsSASModifiersDown == gfsSASModifiers) {
*pfsModifiers = gfsSASModifiersDown;
return TRUE;

}

    return FALSE;
}


chenghao@chenghaodeiMac core % grep "gfsSASModifiersDown" -nr|grep -v "inary"
./ntuser/kdexts/userexts.c:11868:        moveExpValue(&PhysModifiers, VAR(gfsSASModifiersDown));
./ntuser/kernel/globals.h:531:extern UINT      gfsSASModifiersDown; // SAS modifiers really physically down
./ntuser/kernel/ntinput.c:2659:     * Maintain gfsSASModifiersDown to indicate which of Ctrl/Shift/Alt
./ntuser/kernel/ntinput.c:2664:            gfsSASModifiersDown &= ~VKTOMODIFIERS(Vk);
./ntuser/kernel/ntinput.c:2666:            gfsSASModifiersDown |= VKTOMODIFIERS(Vk);
./ntuser/kernel/hotkeys.c:448:     * winlogon.  So look at gfsSASModifiersDown in this case, to see what keys
./ntuser/kernel/hotkeys.c:451:     * sure they don't affect the gfsSASModifiersDown!  - IanJa.
./ntuser/kernel/hotkeys.c:453:    if (gfsSASModifiersDown == gfsSASModifiers) {
./ntuser/kernel/hotkeys.c:454:        *pfsModifiers = gfsSASModifiersDown;
./ntuser/kernel/hotkeys.c:483:    gfsSASModifiersDown = 0;
./ntuser/kernel/globals.c:648: * real physically pressed modifier keys (gfsSASModifiersDown).
./ntuser/kernel/globals.c:664:UINT  gfsSASModifiersDown; // SAS modifiers really physically down


参考:

0: kd> kc
#
00 win32k!PostInputMessage
01 win32k!xxxKeyEvent
02 win32k!xxxProcessKeyEvent
03 win32k!ProcessKeyboardInputWorker
04 win32k!ProcessKeyboardInput
05 win32k!InputApc
06 nt!KiDeliverApc
07 nt!KiSwapThread
08 nt!KeWaitForMultipleObjects
09 win32k!RawInputThread
0a win32k!xxxCreateSystemThreads
0b win32k!NtUserCallOneParam
0c nt!_KiSystemService
0d SharedUserData!SystemCallStub

0: kd> kc
#
00 win32k!StoreQMessage
01 win32k!_PostMessage
02 win32k!xxxDoHotKeyStuff
03 win32k!xxxKeyEvent
04 win32k!xxxProcessKeyEvent
05 win32k!ProcessKeyboardInputWorker
06 win32k!ProcessKeyboardInput
07 win32k!InputApc
08 nt!KiDeliverApc
09 nt!KiSwapThread
0a nt!KeWaitForMultipleObjects
0b win32k!RawInputThread
0c win32k!xxxCreateSystemThreads
0d win32k!NtUserCallOneParam
0e nt!_KiSystemService
0f SharedUserData!SystemCallStub
10 winsrv!NtUserCallOneParam

参考:

VOID xxxKeyEvent(
USHORT    usFlaggedVk,
WORD      wScanCode,
DWORD     time,
ULONG_PTR ExtraInfo,
#ifdef GENERIC_INPUT
HANDLE    hDevice,
PKEYBOARD_INPUT_DATA pkei,
#endif
BOOL      bInjected)
{


/*
* Maintain gfsSASModifiersDown to indicate which of Ctrl/Shift/Alt
* are really truly physically down
*/
if (!bInjected && ((wScanCode & SCANCODE_SIMULATED) == 0)) {
if (fBreak) {
gfsSASModifiersDown &= ~VKTOMODIFIERS(Vk);
        } else {
gfsSASModifiersDown |= VKTOMODIFIERS(Vk);
}

}


#define VKTOMODIFIERS(Vk) ((((Vk) >= VK_SHIFT) && ((Vk) <= VK_MENU)) ? \
(MOD_SHIFT >> ((Vk) - VK_SHIFT)) :           \
0)


../../public/sdk/inc/winuser.h:2975:#define MOD_SHIFT       0x0004


100

10    100
11    10
12    1

VK_SHIFT             10            16                     Shift键
VK_CONTROL      11             17                      Ctrl键
VK_MENU             12            18                     Alt键


CTRL+ALT=0x3

gfsSASModifiersDown=0x3

http://www.dtcms.com/a/590102.html

相关文章:

  • 网站建设课我要表白网站在线制作
  • 烟台网站建设 烟台网亿网络公司python培训学校
  • 计算机网络自顶向下方法41——网络层 自治系统内部的路由选择:开放最短路优先(OSPF)设置OSPF链路权值
  • HDFS分布式存储“入门教程“:从“文件上传“到“副本管理“,3步理解核心原理
  • 做网站的人是什么职位个人备案网站建设方案书
  • 网站后台补丁如何做珠海做网站公司有哪些
  • 黑龙江省农业网站建设情况win7怎么建设网站
  • 海南网站开发公司汝阳建设局网站
  • 人工智能备考2.2.1-2.2.5总结
  • 网络安全形势下怎么建设学校网站wordpress diy主题
  • 已经有域名如何做网站万网域名注册步骤
  • 有域名怎么建立网站建设网站需要什么技术
  • Altium Designer 6.0 初学教程(一)
  • 碳化硅为啥能成“功率芯片新贵”?
  • 蒙古网站群建设海口百度seo公司
  • 深圳网络做网站基于oa系统的网站建设
  • iis做的网站提示500学校的网站管理系统
  • 13.POSIX信号量
  • 网站开发实习深圳外贸公司名单
  • Node.js后端框架Express.js
  • 网站建设不用备案的淘宝网网页版入口
  • 创意互动网站jsp做网站视频教程
  • 普中51单片机学习笔记-流水灯
  • 先备案先建网站运城市住房和城乡建设厅网站
  • 制作网站要什么软件app运营成本估算
  • MBSE与数字孪生:五大行业案例
  • 火狐安装uBlock广告拦截工具
  • AActor前面为什么要加A? UObject前面为什么要加U?
  • C++ 变量作用域 存储期 链接性:const / static / extern 全面解析
  • 五星酒店网站建设方案公司换网站换域名 备案