阅读:1607回复:9
how to post message to application (wdm)
有人知道在WDM中怎样发送信息给用户程序吗?
我想先用"DeviceIoControl" 传递一个类似 "HWND" 的参数给 DRIVER,在DRIVER收到某个信息后(中断),给那个“HWND”窗口发送一个用户自定义信息。 在VxD中我用 "_Shell_PostMessage" 实现的。现在要开发NT/2K的DRIVER, 该怎样实现,请指点。 谢谢 |
|
沙发#
发布于:2001-10-18 12:49
我使用的方法是用deviceiocrl 发送一个event 的handle过去,当然,先在应用程序里面create 这个event.
然后在wdm里面就可以set 这个event了,而application 当然有个东西一直在wait 这个event.试验证明该方法可行。 使用hwind ,我没事过。 |
|
|
板凳#
发布于:2002-05-15 11:10
在您的恢复文章中提到 “ 而application 当然有个东西一直在wait 这个event.试验证明该方法可行。”
请问,如何实现建立一个东西,让他一直等某个event呢? |
|
地板#
发布于:2002-05-15 12:38
WaitForSingleObject和WaitforMultiObject,可能名字不太对。
|
|
地下室#
发布于:2002-05-15 12:40
在MSDN找。
|
|
5楼#
发布于:2002-05-15 15:39
我使用的方法是用deviceiocrl 发送一个event 的handle过去,当然,先在应用程序里面create 这个event. 方法不对!两个对象同名就可以了!都在\\BASENAMEDOBJECTS上下CREATE同名对象就可以共享了!给你看段文章! Despite the mechanism used, the driver and application will need a common method of synchronizing access to the shared buffer. This can be done in a variety of ways. Probably the simplest mechanism is sharing one or more named events. When an application calls CreateEvent(), the named event is automatically created in the Object Manager’s BaseNamedObjects directory. A driver can open, and share, these event objects by calling IoCreateNotificationEvent(), and specifying the same name as was specified in user mode (except, of course, specifying “\\BaseNamedObjects” as the directory). 明白了?什么都不用说了!KeWaitForSingleObject是正确的等待方法~~ |
|
|
6楼#
发布于:2002-05-16 08:05
其实两种方法都可以
在driverstudio中给出了三种方法 robin给出的是第二种 top 用的是第三种 还有一个第一种, 用ntstatus来确认任务的完成与否 |
|
7楼#
发布于:2002-05-16 13:14
其实两种方法都可以 你的理解错了!我和ROBIN说的是一种!叫事件同步,还有另一种就是IRP 队列来轮询! |
|
|
8楼#
发布于:2002-05-16 13:16
还有你说的第一种根本就不是方法~~不要误导初学者!
|
|
|
9楼#
发布于:2002-05-16 14:57
下面是driverstudio里面的原文,top请看:
Signaling an Application from a Kernel Mode Driver Sometimes a driver needs to signal an application. There are at least three ways to do this: Method 1 The application makes a DeviceIoControl to the driver. The driver returns STATUS_PENDING. When the event occurs, the driver completes the IRP. The thread returns from the DeviceIoControl call and handles the event. // sample class declaration class MyDevice : public KDevice { public: MyDevice(); VOID EventHandler(void); DEVMEMBER_DISPATCHERS DEVMEMBER_CANCELIRP (MyDevice, CancelSignalIrp); KIrp m_IrpToCompleteToSignalEvent; }; // Handler for Device Control requests NTSTATUS MyDevice::DeviceControl(KIrp I) { switch (I.IoctlCode()) { case MYDEVICE_IOCTL_SETUP_SIGNAL: CancelSpinLock::Acquire(); I.SetCancelRoutine(LinkTo(CancelSignalIrp)); m_IrpToCompleteToSignalEvent = I; CancelSpinLock::Release(); return STATUS_PENDING; break; . . . } } // cancel routine for the signal IRP VOID MyDevice::CancelSignalIrp(KIrp I) { m_IrpToCompleteToSignalEvent = KIrp(NULL); I.Information() = 0; CancelSpinLock::Release(I->CancelIrql); I.Complete(STATUS_CANCELLED); } // Routine that completes the IRP to signal the event // to the application. Not callable at IRQL > DISPATCH_LEVEL. VOID MyDevice::EventHandler(void) { KIrp I = m_IrpToCompleteToSignalEvent; m_IrpToCompleteToSignalEvent = KIrp(NULL); I.Information() = 0; I.Complete(STATUS_SUCCESS); } Method 2 The application creates an event object, and passes the handle to the driver via DeviceIoControl. The driver obtains an object pointer for the event, which it can then set or reset. Note that the thread handle is specific to the calling process. Therefore, this method can only be used for monolithic or highest level drivers. // sample class declaration class MyDevice : public KDevice { public: MyDevice(); VOID EventHandler(void); KEvent * m_pEventToSignal; }; // Handler for Device Control requests NTSTATUS MyDevice::DeviceControl(KIrp I) { switch (I.IoctlCode()) { case MYDEVICE_IOCTL_SETUP_SIGNAL: // app passes event handle in input buffer HANDLE hEvent = *(HANDLE*)I.IoctlBuffer(); m_pEventToSignal = new(NonPagedPool) KEvent(hEvent); NTSTATUS status = (m_pEventToSignal != NULL) : STATUS_SUCCESS ? STATUS_INSUFFICIENT_RESOURCES; return I.Complete(status); break; . . . } } // Routine signals the event to the application. // Not callable at IRQL > DISPATCH_LEVEL. VOID MyDevice::EventHandler(void) { m_pEventToSignal->Set(); // or Pulse } Method 3 Note: This method is not available in versions of Windows NT earlier than 4.0. Create a named event. #define APP_EVENT_NAME \"SynchEvent\" #define DRIVER_EVENT_NAME L\"\\\\BaseNamedObjects\\\\SynchEvent\" // Application code hEvent = OpenEvent(SYNCHRONIZE, FALSE, EVENT_NAME); // The driver must have already created the event in // order for this to succeed. If you want the app to // create the event, use CreateEvent instead of OpenEvent. // If the user is not privileged, it is required to // create the event in the application. // Driver Initialization Code KEvent* m_pSynchEvent = new (NonPagedPool) KEvent( KUstring(DRIVER_EVENT_NAME),SynchronizationEvent); m_pSynchEvent->Clear(); // initially signaled // The following code signals the event m_pSynchEvent->Set(); |
|