zoukankan      html  css  js  c++  java
  • [内核编程] 4.4 从请求中打印出按键信息

    4.4 从请求中打印出按键信息

    4.4.1 从缓冲区中获得KEYBOARD_INPUT_DATA

    请求完成后,读到的信息在Irp_AssociatedIrp.SystemBuffer中。这里需要介绍一下这个缓冲区中的数据格式。这个缓冲区中可能含有n个KEYBOARD_INPUT_DATA 结构(这个结构在WDK的头文件中有定义)。

    typedef struct _KEYBOARD_INPUT_DATA{
        //头文件里的解释是这样的:对设备DeviceKeyboardPort0,这个
        //值是0;对DeviceKeyboardPort1,这个值是 1,依次类推
        USHORT  UnitId;
        //扫描码
        USHORT  MakeCode;
        //一个标记。标记这是一个键释放还是其他的扫描码
        USHORT  Flags;
        //保留
        USHORT  Reserved;
        //扩展信息
        ULOG  ExtraInformation;
    }KEYBOARD_INPUT_DATA,*PKEYBOARD_INPUT_DATA;

    下面是Flags可能的取值。并不是完全明白。

    #define KEY_MAKE 0
    #define KEY_BREAK 1
    #define KEY_E0 2
    #define KEY_E1 4
    #define KEY_TERMSRV_SET_LED 8
    #define KEY_TERMSRV_SHADOW 0x10
    #define KEY_TERMSRV_VKPACKET 0x20

    至少有多少个这样的结构,取决于输入缓冲区到底有多长。实际上,这种结构的个数应该为:
                                    size = buf_len / sizeof(KEYBOARD_INPUT_DATA);

    4.4.2 从KEBOARD_INPUT_DATA中得到键

    KEYBOARD_INPUT_DATA下面的MakeCode就是扫描码。对于Flags,这里只需考虑KEY_BREAK(0)——按下,和KEY_BREAK(非0)——弹起,两种可能。

    相关处理代码在c2pReadComplete函数中:

             KeyData = (PKEYBOARD_INPUT_DATA)buf;
            // 获得这个缓冲区的长度。一般的说返回值有多长都保存在
            // Information中。
            buf_len = Irp->IoStatus.Information;
            numKeys = buf_len / sizeof(KEYBOARD_INPUT_DATA);
            //… 这里可以做进一步的处理。我这里很简单的打印出所有的扫
            // 描码。
            //for(i=0;i<buf_len;++i)
            for(i=0;i<numKeys;++i)
            {
                //DbgPrint("ctrl2cap: %2x
    ", buf[i]);
                DbgPrint("
    ");
                DbgPrint("numKeys : %d",numKeys);
                DbgPrint("ScanCode: %x ", KeyData->MakeCode ); 
                DbgPrint("%s
    ", KeyData->Flags ?"Up" : "Down" );
                print_keystroke((UCHAR)KeyData->MakeCode);
    
                if( KeyData->MakeCode == CAPS_LOCK) 
                { 
                    KeyData->MakeCode = LCONTROL; 
                } 
            }    

    4.4.3 从MakeCode到实际字符

    // flags for keyboard status
    #define    S_SHIFT                1
    #define    S_CAPS                2
    #define    S_NUM                4
    
    //这是一个标记,用来保存当前键盘的状态。其中有3个位,分别表示
    //Caps Lock 键、Num Lock 键 和 Shift 键是否按下了
    static int kb_status = S_NUM;
    void __stdcall print_keystroke(UCHAR sch)
    {
        UCHAR    ch = 0;
        int        off = 0;
    
        if ((sch & 0x80) == 0)    //make
        {
            //如果按下了字母或者数字等可见字符
            if ((sch < 0x47) || 
                ((sch >= 0x47 && sch < 0x54) && (kb_status & S_NUM))) // Num Lock
            {
                //最终得到哪个字符必须由Caps Lock 和 Num Lock 及 Shift这几个键
                //的状态来决定,所以写在一张表中
                ch = asciiTbl[off+sch];
            }
    
            switch (sch)
            {
            //Caps Lock 键和 Num Lock键类似,都是“按下两次”等于没按过一样的“反复键”
            //所以这里用异或来设置标志。也就是说,按一次起作用,再按一次就不起作用了
            case 0x3A:
                kb_status ^= S_CAPS;
                break;
            
            //注意 Shift键的特点
            //(1)Shift键有两个,左右各一个,扫描码互不相同
            //(2)Shift键是按下起作用,弹起则作用消失,所以这里用或来设置标记
            case 0x2A:
            case 0x36:
                kb_status |= S_SHIFT;
                break;
            
            //Num Lock 键
            case 0x45:
                kb_status ^= S_NUM;
            }
        }
        else        //break
        {
            if (sch == 0xAA || sch == 0xB6)
                kb_status &= ~S_SHIFT;
        }
    
        if (ch >= 0x20 && ch < 0x7F)
        {
            DbgPrint("%C 
    ",ch);
        }
    
    }
  • 相关阅读:
    高程图 GridMap
    VINS-Mono代码分析与总结(二) 系统初始化
    IMU误差模型与校准
    VINS-Mono代码分析与总结(一) IMU预积分
    XJTU 大一上
    iOS路由最佳选择是什么
    正向代理、反向代理、透明代理
    centos7国内镜像glbc版安装
    IntelliJ idea 中使用Git
    Mongo DB 2.6 需要知道的一些自身限定
  • 原文地址:https://www.cnblogs.com/fanling999/p/4068930.html
Copyright © 2011-2022 走看看