4.4.1从缓冲区中获得KEYBOARD_INPUT_DATA
请求完成之后,读到的信息在Irp->AssociatedIrp.SystemBuffer中,这个缓冲区可能含有n个KEYBOARD_INPUT_DATA结构
这个结构定义如下
typedef struct _KEYBOARD_INPUT_DATA{//对设备DeviceKeyboardPort0,这个值是0;对DeviceKeyboardPort1,这个值是1,依次类推USHORT UnitId;//扫描码USHORT MakeCode;//一个标记.是一个键按下(0)放还是弹起(非0)USHRT Flags;//保留USHORT Reserved;//扩展信息ULONG ExtraInformation;}KEYBOARD_INPUT_DATA,*PKEYBOARD_INPUT_DATA;
至于有多少个这样的结构,取决于输入缓冲区到底有多长
size = buf_len/sizeof(KEYBOARD_INPUT_DATA);
4.4.3从MakeCode到实际字符
所谓的实际字符就是ASII码,大写/小写字符的ASCII码并不相同,但是键是同一个(扫描码相同),具体是哪个取决于几个键的状态(Shift,Caps Lock,Num Lock键).Shift键和Caps Lock键不同:Shift键是按下生效,释放则无效;而Caps Lock键是按一次生效,再按一次无效.
下面代码把这些控制键的状态保存在kb_status这个变量,用3个位来保留.
#define S_SHIFT 1 //001#define S_CAPS 2 //010#define S_NUM 4 //100//这是一个标记,用来保存当前键盘的状态,其中3个位,分别表示CapsLock键,NumLock键和Shift键是否按下了static int kb_status = S_NUM;void __stdcall print_keystroke(UCHAR sch){UCHAR ch = 0;switch(sch){//Caps Lock键和Num Lock键类似,都是"按下两次"等于没按过一样,这里用异或设置标志case 0x3A:kb_status ^=S_CAPS;break;//Num Lock键case 0x45:kb_status ^=S_NUM;break;//注意Shift键的特点//(1)Shift键有两个,左右各一个,扫描码互不相同//(2)Shift键是按下起作用,弹起则作用消失,所以这里用或来设置标记case 0x2a:case 0x36:kb_status |= S_SHIFT;break;}//如果按下了字母或者是数字等可见字符if((sch <0x47) || ((sch >= 0x47 && sch < 0x54)&& (kb_status & S_NUM) )){//最终得到哪个字符必须由Caps Lock和NumLock及Shift这几个键的状态来决定,所以写在一张表中if (kb_status & S_CAPS){if (kb_status & S_SHIFT)ch = asciiTblCaps_Shift[sch];elsech = asciiTblCaps[sch];}else if(kb_status & S_SHIFT)ch = asciiTblShift[sch];elsech = asciiTblNormal[sch];if(ch >= 0x20 && ch < 0x7F) //打印出可见字符DbgPrint("%C n",ch);}}
完整的完成函数:
//PKEYBOARD_INPUT_DATA要引用下面的头文件 #include <ntddkbd.h>NTSTATUS c2pReadComplete(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context){size_t i;if(NT_SUCCESS(Irp->IoStatus.Status)){PKEYBOARD_INPUT_DATA KeyData = (PKEYBOARD_INPUT_DATA)(Irp->AssociatedIrp.SystemBuffer);//Flags == 0 表示按下if (KeyData->Flags == 0){ULONG numKeys = Irp->IoStatus.Information/sizeof(KEYBOARD_INPUT_DATA);for (i=0;i<numKeys;i++){//打印实际字符print_keystroke((UCHAR)KeyData->MakeCode);}}else{if(KeyData->MakeCode == 0xAA || KeyData->MakeCode == 0xB6) //+0x80为Shift弹起的扫描码kb_status &= ~S_SHIFT; //Shift键弹起,kb_status第1个位归为0}gC2pKeyCount--;if(Irp->PendingReturned){IoMarkIrpPending(Irp);}return Irp->IoStatus.Status;}}
Ascii字符表
unsigned char asciiTblNormal[]={0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x2D, 0x3D, 0x08, 0x09, //normal0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69, 0x6F, 0x70, 0x5B, 0x5D, 0x0D, 0x00, 0x61, 0x73,0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3B, 0x27, 0x60, 0x00, 0x5C, 0x7A, 0x78, 0x63, 0x76,0x62, 0x6E, 0x6D, 0x2C, 0x2E, 0x2F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,0x32, 0x33, 0x30, 0x2E,};unsigned char asciiTblCaps[]={0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x2D, 0x3D, 0x08, 0x09, //caps0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4F, 0x50, 0x5B, 0x5D, 0x0D, 0x00, 0x41, 0x53,0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3B, 0x27, 0x60, 0x00, 0x5C, 0x5A, 0x58, 0x43, 0x56,0x42, 0x4E, 0x4D, 0x2C, 0x2E, 0x2F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,0x32, 0x33, 0x30, 0x2E,};unsigned char asciiTblShift[]={0x00, 0x1B, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x08, 0x09, //shift0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4F, 0x50, 0x7B, 0x7D, 0x0D, 0x00, 0x41, 0x53,0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3A, 0x22, 0x7E, 0x00, 0x7C, 0x5A, 0x58, 0x43, 0x56,0x42, 0x4E, 0x4D, 0x3C, 0x3E, 0x3F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,0x32, 0x33, 0x30, 0x2E,};unsigned char asciiTblCaps_Shift[]={0x00, 0x1B, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x08, 0x09, //caps + shift0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69, 0x6F, 0x70, 0x7B, 0x7D, 0x0D, 0x00, 0x61, 0x73,0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3A, 0x22, 0x7E, 0x00, 0x7C, 0x7A, 0x78, 0x63, 0x76,0x62, 0x6E, 0x6D, 0x3C, 0x3E, 0x3F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,0x32, 0x33, 0x30, 0x2E,};
最后
以上就是欢呼跳跳糖最近收集整理的关于寒江独钓 第四章 按键信息 扫描码和Ascii码的全部内容,更多相关寒江独钓内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复