zhangting00_200
驱动牛犊
驱动牛犊
  • 注册日期2005-05-15
  • 最后登录2005-11-29
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1279回复:1

我的USB鼠标过滤驱动程序如何与应用层程序通信?

楼主#
更多 发布于:2005-05-25 13:18
在此,我非常希望zhaock师兄能看到这个帖子。

问题是这样:
首先我用如下代码打开该设备:
HANDLE CMouseFliterOpen::GetDeviceViaInterface(GUID *pGuid,DWORD instance)
{

HDEVINFO info = SetupDiGetClassDevs(pGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
if(info==INVALID_HANDLE_VALUE)
{

return NULL;

}


SP_INTERFACE_DEVICE_DATA ifdata;
ifdata.cbSize = sizeof(ifdata);
if(!SetupDiEnumDeviceInterfaces(info, NULL, pGuid, instance, &ifdata))
{

SetupDiDestroyDeviceInfoList(info);
return NULL;

}


DWORD ReqLen;
SetupDiGetDeviceInterfaceDetail(info, &ifdata, NULL, 0, &ReqLen, NULL);
PSP_INTERFACE_DEVICE_DETAIL_DATA ifDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)(new char[ReqLen]);
if( ifDetail==NULL)
{
SetupDiDestroyDeviceInfoList(info);
return NULL;
}


ifDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
if( !SetupDiGetDeviceInterfaceDetail(info, &ifdata, ifDetail, ReqLen, NULL, NULL))
{
SetupDiDestroyDeviceInfoList(info);
delete ifDetail;
return NULL;
}
//
HANDLE rv=CreateFile(ifDetail->DevicePath,
                              0 ,
                              FILE_SHARE_READ | FILE_SHARE_WRITE,  
                              NULL,
                              OPEN_EXISTING,
                               0,
                              NULL);




if( rv==INVALID_HANDLE_VALUE)
{rv = NULL;
::MessageBox(NULL,\"句柄为空\",\"123\",NULL);
}
delete ifDetail;
SetupDiDestroyDeviceInfoList(info);
return rv;
}
此刻,ifDetail->DevicePath所得到的路径文件名是正确的,但是我在调用CreateFile函数的时候,第二个参数如果指定为“GENERIC_READ | GENERIC_WRITE”,那么CreateFile将创建失败;当指定为“0”的时候,能创建成功,从而获得该设备句柄。
我又使用该句柄进行下一步操作:调用DeviceIoControl设备IO控制函数,结果该函数调用失败!当然我没有忘记使用CTL_CODE宏,定义了IO控制码,也没有忘记使用使用GUIDGEN工具产生GUID,同时也在
MouFilter_AddDevice例程中进行了“设备接口”注册。在PNP例程中分离设备时也有禁止接口。同时我也写了如下代码处理IRP_MJ_DEVICE_CONTROL:
NTSTATUS RequestControl(IN PDEVICE_OBJECT
DeviceObject, IN PIRP Irp)
{

PIO_STACK_LOCATION IrpStack;
ULONG ControlCode;
ULONG InputLength,OutputLength;
NTSTATUS status;
DBGOUT((\"进入RequestControl处理例程\"));
IrpStack=IoGetCurrentIrpStackLocation(Irp);
//获取当前IRP所在的I/O堆栈
ControlCode=IrpStack->Parameters.DeviceIoControl.
IoControlCode; //取得控制码
InputLength=IrpStack->Parameters.DeviceIoControl.
InputBufferLength; //取输入缓冲区大小
OutputLength=IrpStack->Parameters.DeviceIoControl.
OutputBufferLength;//取输出缓冲区大小
switch(ControlCode)
{
DBGOUT((\"zhang_ting is a good man!\"));
case IOCTL_WDM1_ZERO_BUFFER: //HELLOWDM_IOCTL_HELLO
DBGOUT((\"Hello from WDM.\\n\"));//向调试器输出字符串
status=STATUS_SUCCESS; //置返回值
break;
default: status=STATUS_INVALID_DEVICE_REQUEST;
//输入的控制码不支持
}
return MouFilter_DispatchPassThrough(DeviceObject, Irp);
//调用CompleteRequest通知操作系统完成IRP操作
}
各位师兄:为什么我上的处理IRP_MJ_DEVICE_CONTROL的例程没有被执行呢?


最新喜欢:

xhzxlqtxhzxlq... yuzheyuzhe
圣经.雅歌
zhaock
驱动太牛
驱动太牛
  • 注册日期2002-01-26
  • 最后登录2018-06-02
  • 粉丝3
  • 关注2
  • 积分73328分
  • 威望362317点
  • 贡献值1点
  • 好评度226点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2005-05-26 10:17
我建议你用传统的方法,IoCreateDevice创建一个controlDevice,
IoCreateSymbolicName,应用程序和ControlDevice通讯。
驱动里,判断一下,如果是ControlDevice,就是处理应用程序的Irp,
直接处理了。如果不是,则是filte object,需要IoCallDriver往下传。
Interface的方法我当年就很少用,现在则全忘了
游客

返回顶部