阅读:2895回复:11
关于针对Ctrl2cap源码,键盘的访问只能写不能读的问题?各位大虾帮忙!!
从网上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 也就是说只能写而不能读, 请问给位这是什么问题? 如果说是驱动程序的权限设置问题,那么如何在更改驱动程序,才能让它可写呢? 谢谢大家有空看我的问题!! |
|
最新喜欢:![]() |
沙发#
发布于:2004-03-08 17:55
你需要加载驱动才行,要么通过SCM,要么通过注册表。
还有CTRL2CAP属于过滤驱动,所以一般的IRP他都往下传,包括IRP―CREATE和CLOSE,但你如果要对其进行操作,则必须生成2个设备对象,一个是你自己本身,另一个代表过滤设备对象,在CREATE。CLOSE的IRP里进行判断,如果是你自己的就返回IOCOMPLETEQUEST,如果是发往过滤对象的就往下传。详细的参考SFILTER的方法。 [编辑 - 3/8/04 by wowocock] |
|
|
板凳#
发布于:2004-03-09 11:13
驱动我已经加载了呀,你可以见附件呀!
但是为什么还是只能写而不能读呢?难道这与windows 2000独享键盘有关呢?我想应该不会吧, 还有一点我始终不明白,书上有这么一句: 如果过滤器驱动程序使一个特别的MajorFunction表项处于默认状态,则该类型的IRP将会以STATUS_INVALID_DEVICE_REQUEST结果失败。(I/O管理器含有一个默认的派遣函数,该函数就以这个结果简单地完成一个IRP。系统最初送给驱动程序对象中的所有MajorFunction表项都指向这个默认例程) 会不会不能读的与原因与这一句话有关? 我很困惑,始终解决不了这个不能读的问题,那我以后怎么在应用程序中如何知道键盘按键信息呀? |
|
地板#
发布于:2004-03-09 12:50
你的驱动DISPATCH里没有IRP-CREATE,CLOSE,那么当然是不能CREATEFILE成功了,添加该例程,直接设置成功返回即可。
|
|
|
地下室#
发布于: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信息里面可以看到驱动已经加载,你能回答我是出了什么原因吗? |
|
5楼#
发布于:2004-03-09 20:59
我不是说了需要2个设备对象,自身的和过滤的,你只能对自身的返回成功,对过滤的必须把IRP往下传,不然的话,当然完蛋拉。
|
|
|
6楼#
发布于:2004-03-10 18:54
谢谢你的指点,按照你的方法我的createfile已经可以成功啦!:)
另外,我的分已经送出去了,希望你可以检查一下,如果没有收到,请通知我! :) |
|
7楼#
发布于:2004-06-10 10:58
楼主啊,我现在也在研究ctrl2cap,我也想和应用程序通信,但是尝试了却失败了,能否把你实现的代码贴出来啊?或把例子发邮件给我好吗? zkfm@vip.163.com
非常感谢了啊! |
|
8楼#
发布于:2004-06-10 14:09
上来就是要原代码?
Ctrl2cap在网上不是有的下载吗? |
|
|
9楼#
发布于:2004-06-10 17:02
呵呵,ctrl2cap的代码我有了,我想要的是 能 和应用程序通信的代码,我自己也想了好多办法和应用程序通信,好象不行啊
我看上面的高手说要建立两个设备,但是我不知道到底该怎么搞,我是新手,见凉哦 还有,我没有建立两个设备对象建立的符号连接就可以既写也可读了,到底什么原因哦? 楼主,可以把你的代码发给我吗,真的非常感谢了,我才学,不知道到底怎么做 |
|
10楼#
发布于:2007-06-21 16:59
楼主,还是指点以下我们这些新手吧。
你是如何把驱动和应用程序通信的? |
|
11楼#
发布于:2007-06-21 17:05
我仔细看了你给出的代码片段,按照我的理解。是不是建立一个符号链接指向设备对象,
然后在应用程序中读写这个符号链接就可以和这个设备对象通信了??只是最后不明白 如何区别两个设备对象,一个是自己的,一个是要过滤的。 用设备扩展来标识吗?? |
|