阅读:1222回复:6
再问wdm与app用event通讯(25分)
wdm主要程序段
NTSTATUS WDMDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION IrpStack; ULONG dwInputBufferLength; ULONG dwOutputBufferLength; ULONG dwIoControlCode; PVOID pvIOBuffer; NTSTATUS ntStatus; UNICODE_STRING EventName; NTSTATUS evt_res; OBJECT_HANDLE_INFORMATION obj_info; KEVENT event; KdPrint( ("Enter\n") ); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IrpStack = IoGetCurrentIrpStackLocation(Irp); pvIOBuffer = Irp->AssociatedIrp.SystemBuffer; dwInputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength; dwOutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength; switch (IrpStack->MajorFunction) { case IRP_MJ_DEVICE_CONTROL: KdPrint( ("IRP_MJ_DEVICE_CONTROL\n") ); dwIoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode; switch (dwIoControlCode) { case IOCTL_WDMTEST: KdPrint( ("IOCTL_WDMTEST\n") ); KdPrint( ("%x\n", pvIOBuffer ) ); evt_res = ObReferenceObjectByHandle( *((HANDLE*)pvIOBuffer), GENERIC_ALL, NULL, KernelMode, &event, &obj_info ); if( NT_SUCCESS(evt_res) ){ KdPrint( ("ObReferenceObjectByHandle OK!\n") ); KeSetEvent( &event, IO_NO_INCREMENT, FALSE ); <------ 1 KdPrint( ("KeSetEvent OK!\n") ); ObDereferenceObject(&event); KdPrint( ("ObDereferenceObject OK!\n") ); }else{ KdPrint( ("ObReferenceObjectByHandle Fail!\n") ); } break; default: KdPrint( ("ERROR\n") ); Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; break; } break; } ntStatus = Irp->IoStatus.Status; IoCompleteRequest (Irp, IO_NO_INCREMENT); KdPrint( ("Leaving\n") ); return ntStatus; } app调用程序段: 全局中定义 HANDLE evt; 函数中 DWORD dwBytesReturned; evt = CreateEvent( 0, FALSE, FALSE, 0 ); InstallDrive(); OpenDrive(); if (!DeviceIoControl(hDriver, IOCTL_WDMTEST, &evt, sizeof(evt), 0, 0, &dwBytesReturned, NULL)) AfxMessageBox("err"); 当把那句“1”屏蔽掉后,不会兰屏,并且kdprint出的东西是我希望的东西,把“1”加上后,运行deviceiocontrol就兰屏 哪里错了(小弟学驱动刚一个星期,如果可以,请说明的详细一些,谢谢) |
|
沙发#
发布于:2004-04-02 09:31
不要在ObReferenceObjectByHandle( *((HANDLE*)pvIOBuffer), GENERIC_ALL, NULL,
KernelMode, &event, &obj_info ); 后直接KESETEVENT 而应该专门用一个SETEVENT的IOCONTROL来SETEVENT |
|
|
板凳#
发布于:2004-04-02 09:50
那么KEVENT event这句话我应该申明在哪里?可不可以直接放在程序最前面的全局变量中??
|
|
地板#
发布于:2004-04-02 11:19
可以用全局变量,不过最好放在设备扩展里。
|
|
|
地下室#
发布于:2004-04-02 12:13
我用IoCreateNotificationEvent成功通讯了,但是我用ObReferenceObjectByHandle转换后,发现,原来在app中reset的event,被他这么一转换后,怎么event自动就变成了set了呢?我在ObReferenceObjectByHandle后直接用KeClearEvent也没用(我没有用ObDereferenceObject)
|
|
5楼#
发布于:2004-04-02 13:16
前面的问题解决了,最后一个问题,哪里调用ObDereferenceObject比较合适?
|
|
6楼#
发布于:2004-04-07 16:29
evt_res = ObReferenceObjectByHandle( *((HANDLE*)pvIOBuffer), GENERIC_ALL, NULL,KernelMode, &event, &obj_info );
编不过 dispatch.c(52) : error C4047: 'function' : 'void ** ' differs in levels of indir ection from 'struct _KEVENT *' 我也是初学者根你学习 |
|