webstartlove
驱动牛犊
驱动牛犊
  • 注册日期2002-07-01
  • 最后登录2004-04-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2764回复:11

关于针对Ctrl2cap源码,键盘的访问只能写不能读的问题?各位大虾帮忙!!

楼主#
更多 发布于:2004-03-08 17:35
从网上http://www.sysinternals.com 下载键盘驱动源码Ctrl2cap Keyboard Filter ,相信有人看过,我想写一个应用程序与这个驱动进行沟通,所以我修改了一下这个源码,
我只修改了AddDevice部分,其他的地方我没有该!
以下是原代码(没有经过修改的)
typedef struct _DEVICE_EXTENSION
{
      PDEVICE_OBJECT  TopOfStack;

} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

NTSTATUS
Ctrl2capAddDevice(
    IN PDRIVER_OBJECT   Driver,
    IN PDEVICE_OBJECT   PDO
    )
{
    PDEVICE_EXTENSION        devExt;
    IO_ERROR_LOG_PACKET      errorLogEntry;
    PDEVICE_OBJECT           device;
    NTSTATUS                 status = STATUS_SUCCESS;

    status = IoCreateDevice(Driver,                  
                            sizeof(DEVICE_EXTENSION),
                            NULL,                    
                            FILE_DEVICE_KEYBOARD,  
                            0,                    
                            FALSE,                
                            &device              
                            );

    if (!NT_SUCCESS(status)) {

        return (status);
    }

    RtlZeroMemory(device->DeviceExtension, sizeof(DEVICE_EXTENSION));

    devExt = (PDEVICE_EXTENSION) device->DeviceExtension;
    devExt->TopOfStack = IoAttachDeviceToDeviceStack(device, PDO);

    ASSERT(devExt->TopOfStack);

    device->Flags |= (DO_BUFFERED_IO | DO_POWER_PAGABLE);
    device->Flags &= ~DO_DEVICE_INITIALIZING;
    return status;
}


我修改的代码如下:

typedef struct _DEVICE_EXTENSION
{
    UNICODE_STRING  ifSymLinkName;
    PDEVICE_OBJECT  TopOfStack;

} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

NTSTATUS
Ctrl2capAddDevice(
    IN PDRIVER_OBJECT   Driver,
    IN PDEVICE_OBJECT   PDO
    )
{
    PDEVICE_EXTENSION        devExt;
    IO_ERROR_LOG_PACKET      errorLogEntry;
    PDEVICE_OBJECT           device;
    NTSTATUS                 status = STATUS_SUCCESS;
    static WCHAR i=0;
    UNICODE_STRING devname,linkname;
    RtlInitUnicodeString(&devname, L"\\Device\\KEYFILTER0");
    RtlInitUnicodeString(&linkname, L"\\DosDevices\\SYSKEYFILTER0");
    devname.Buffer[(devname.Length/sizeof(WCHAR))-1]=L'0'+i;
    linkname.Buffer[(linkname.Length/sizeof(WCHAR))-1]=L'0'+i;
    i++;
    status = IoCreateDevice(Driver,                  
                            sizeof(DEVICE_EXTENSION),
                            &devname,                    
                            FILE_DEVICE_UNKNOWN,  
                            0,                    
                            FALSE,                
                            &device              
                            );

    if (!NT_SUCCESS(status)) {

        return (status);
    }

    RtlZeroMemory(device->DeviceExtension, sizeof(DEVICE_EXTENSION));

    devExt = (PDEVICE_EXTENSION) device->DeviceExtension;
    
    status=IoCreateSymbolicLink(&linkname,&devname);
    if (!NT_SUCCESS(status)) {
DbgPrint(" - IoCreateSymbolicLink failed\n");
        return (status);
    }
    IoInitializeRemoveLock(&devExt->RemoveLock, 0, 0, 0);
    devExt->DeviceObject = device;
    devExt->Pdo = PDO;
    
    devExt->TopOfStack = IoAttachDeviceToDeviceStack(device, PDO);

    ASSERT(devExt->TopOfStack);

    device->Flags |= (DO_DIRECT_IO | DO_BUFFERED_IO | DO_POWER_PAGABLE | DO_POWER_INRUSH);
    device->Flags &= ~DO_DEVICE_INITIALIZING;
    return status;
}

经过上述修改,我编译后运行成功!
使用winogj察看,看到了符号链接 “ SYSKEYFILTER0“
然后,我写了一个测试程序,但是createfile没有成功,一下是代码:
HANDLE hdevice = CreateFile("\\\\.\\SYSKEYFILTER0",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

错误代码为 :5
查MSDN     : Access is denied.
我于是该createfile如下:
HANDLE hdevice = CreateFile("\\\\.\\SYSKEYFILTER0",GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
也就是说把 GENERIC_READ|GENERIC_WRITE 换为 GENERIC_WRITE
也就是说只能写而不能读,
请问给位这是什么问题?
如果说是驱动程序的权限设置问题,那么如何在更改驱动程序,才能让它可写呢?

谢谢大家有空看我的问题!!


最新喜欢:

hartonoharton...
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2004-03-08 17:55
你需要加载驱动才行,要么通过SCM,要么通过注册表。
还有CTRL2CAP属于过滤驱动,所以一般的IRP他都往下传,包括IRP―CREATE和CLOSE,但你如果要对其进行操作,则必须生成2个设备对象,一个是你自己本身,另一个代表过滤设备对象,在CREATE。CLOSE的IRP里进行判断,如果是你自己的就返回IOCOMPLETEQUEST,如果是发往过滤对象的就往下传。详细的参考SFILTER的方法。

[编辑 -  3/8/04 by  wowocock]
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
webstartlove
驱动牛犊
驱动牛犊
  • 注册日期2002-07-01
  • 最后登录2004-04-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-03-09 11:13
驱动我已经加载了呀,你可以见附件呀!
但是为什么还是只能写而不能读呢?难道这与windows 2000独享键盘有关呢?我想应该不会吧,
还有一点我始终不明白,书上有这么一句:

如果过滤器驱动程序使一个特别的MajorFunction表项处于默认状态,则该类型的IRP将会以STATUS_INVALID_DEVICE_REQUEST结果失败。(I/O管理器含有一个默认的派遣函数,该函数就以这个结果简单地完成一个IRP。系统最初送给驱动程序对象中的所有MajorFunction表项都指向这个默认例程)

会不会不能读的与原因与这一句话有关?
我很困惑,始终解决不了这个不能读的问题,那我以后怎么在应用程序中如何知道键盘按键信息呀?
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
地板#
发布于:2004-03-09 12:50
你的驱动DISPATCH里没有IRP-CREATE,CLOSE,那么当然是不能CREATEFILE成功了,添加该例程,直接设置成功返回即可。
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
webstartlove
驱动牛犊
驱动牛犊
  • 注册日期2002-07-01
  • 最后登录2004-04-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-03-09 19:13
首先谢谢你以前对我的回答!
应你的提示,我在ctrl2cap.c里面加了IRP_MJ_CREATE和IRP_MJ_CLOSE例程,代码见下面:

NTSTATUS Ctrl2capCreate(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp )
{
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
DbgPrint( "Create File is %ws\n", &(IrpStack->FileObject->FileName));

return STATUS_SUCCESS;

}


NTSTATUS Ctrl2capClose(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp )
{
DbgPrint("Close\n");

return STATUS_SUCCESS;

}

编译通过后,安装重新启动电脑,结果发现键盘不能响应按键信息,也就是说按键没有反应,在Dbgview信息里面可以看到驱动已经加载,你能回答我是出了什么原因吗?
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
5楼#
发布于:2004-03-09 20:59
我不是说了需要2个设备对象,自身的和过滤的,你只能对自身的返回成功,对过滤的必须把IRP往下传,不然的话,当然完蛋拉。
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
webstartlove
驱动牛犊
驱动牛犊
  • 注册日期2002-07-01
  • 最后登录2004-04-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-03-10 18:54
谢谢你的指点,按照你的方法我的createfile已经可以成功啦!:)
另外,我的分已经送出去了,希望你可以检查一下,如果没有收到,请通知我! :)
Deauty
驱动牛犊
驱动牛犊
  • 注册日期2002-11-27
  • 最后登录2008-10-12
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度13点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-06-10 10:58
楼主啊,我现在也在研究ctrl2cap,我也想和应用程序通信,但是尝试了却失败了,能否把你实现的代码贴出来啊?或把例子发邮件给我好吗? zkfm@vip.163.com

非常感谢了啊!
AllenZh
驱动老牛
驱动老牛
  • 注册日期2001-08-19
  • 最后登录2015-11-27
  • 粉丝19
  • 关注10
  • 积分1316分
  • 威望2387点
  • 贡献值7点
  • 好评度321点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-06-10 14:09
上来就是要原代码?
Ctrl2cap在网上不是有的下载吗?
1,承接Windows下驱动/应用开发 2,本人原创虚拟鼠标/键盘,触摸屏,虚拟显卡,Mirror驱动,XP无盘的SCSI虚拟磁盘驱动等 3,windows下有尝技术服务(包括BUG调试,员工培训等) 欢迎深圳和海外企业联系.msn:mfczmh@sina.com
Deauty
驱动牛犊
驱动牛犊
  • 注册日期2002-11-27
  • 最后登录2008-10-12
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度13点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-06-10 17:02
呵呵,ctrl2cap的代码我有了,我想要的是 能 和应用程序通信的代码,我自己也想了好多办法和应用程序通信,好象不行啊
    我看上面的高手说要建立两个设备,但是我不知道到底该怎么搞,我是新手,见凉哦
    还有,我没有建立两个设备对象建立的符号连接就可以既写也可读了,到底什么原因哦?


    楼主,可以把你的代码发给我吗,真的非常感谢了,我才学,不知道到底怎么做
guitar2002
驱动牛犊
驱动牛犊
  • 注册日期2006-10-26
  • 最后登录2007-06-22
  • 粉丝0
  • 关注0
  • 积分50分
  • 威望6点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2007-06-21 16:59
楼主,还是指点以下我们这些新手吧。
你是如何把驱动和应用程序通信的?
guitar2002
驱动牛犊
驱动牛犊
  • 注册日期2006-10-26
  • 最后登录2007-06-22
  • 粉丝0
  • 关注0
  • 积分50分
  • 威望6点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2007-06-21 17:05
我仔细看了你给出的代码片段,按照我的理解。是不是建立一个符号链接指向设备对象,
然后在应用程序中读写这个符号链接就可以和这个设备对象通信了??只是最后不明白
如何区别两个设备对象,一个是自己的,一个是要过滤的。
用设备扩展来标识吗??
游客

返回顶部