Серж
Гость
|
|
« Ответ #3 : 04-07-2005 07:32 » |
|
Detsel, конечно, откроется. Еще один способ - просто передать handle открытого в приложении события через DeviceIOControl.
Вот тебе текст из DriverStudio: 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();
|