A driver written in user mode uses WinDriver's API (WDC_xxx and/or WD_xxx [B.2]) to access devices. If a certain function that was implemented in the user mode requires kernel performance (the interrupt handler, for example), that function is moved to the WinDriver Kernel PlugIn. Generally it should be possible to move code that uses WDC_xxx / WD_xxx function calls from the user mode to the kernel without modification, since the same WinDriver API is supported both in the user mode and in the Kernel PlugIn.
There are two types of interaction between the WinDriver kernel and the WinDriver Kernel PlugIn:
At the end of your Kernel PlugIn development cycle, your driver will have the following components:
The following is a typical event sequence that covers all the functions that you can implement in your Kernel PlugIn:
| Event/Callback | Notes |
|---|---|
| Event: Windows loads your Kernel PlugIn driver. | This takes place at boot time, by dynamic loading, or as instructed by the registry. |
| Callback: Your KP_Init() Kernel PlugIn routine [B.6.2] is called | KP_Init() informs WinDriver of the name of your KP_Open() routine [B.6.2]. WinDriver will call this routine when the application wishes to open your driver - when it calls WDC_xxxDeviceOpen() (PCI: B.3.9], PCMCIA: [B.3.10], ISA: [B.3.11]]) with the name of a Kernel PlugIn driver to open, or when it calls the low-level WD_KernelPlugInOpen() function (see the WinDriver PCI Low-Level API Reference), which is called by the wrapper WDC_xxxDeviceOpen() functions. |
| Event: Your user-mode driver application calls WDC_xxxDeviceOpen() (PCI: [B.3.9], PCMCIA: [B.3.10], ISA: [B.3.11]]) with the name of a Kernel PlugIn driver to open, or it calls the low-level WD_KernelPlugInOpen() function (see the WinDriver PCI Low-Level API Reference), which is called by the wrapper WDC_xxxDeviceOpen() functions. | |
| Callback: Your KP_Open() Kernel PlugIn routine [B.6.2] is called. | The KP_Open() function [B.6.2] is used to inform WinDriver of the names of all the callback functions that you have implemented in your Kernel PlugIn driver and to initiate the Kernel PlugIn driver, if needed. |
| Event/Callback | Notes |
|---|---|
| Event: Your application calls WDC_CallKerPlug() [B.3.17], or the low-level WD_KernelPlugInCall() function (see the WinDriver PCI Low-Level API Reference). | Your application calls WDC_CallKerPlug() / WD_KernelPlugInCall() to execute code in the kernel mode (in the Kernel PlugIn driver). The application passes a message to the Kernel PlugIn driver. The Kernel PlugIn driver will select the code to execute according to the message sent. |
| Callback: Your KP_Call() Kernel PlugIn routine [B.6.4] is called. | KP_Call() [B.6.4] executes code according to the message passed to it from the user mode. |
| Event/Callback | Notes |
|---|---|
| Event: Your application calls WDC_IntEnable() [B.3.43] with the fUseKP parameter set to TRUE (after having opened the device with a Kernel PlugIn), or calls the low-level InterruptEnable() or WD_IntEnable() functions (see the WinDriver PCI Low-Level API Reference) with a handle to a Kernel PlugIn driver (set in the hKernelPlugIn field of the WD_INTERRUPT structure passed to the function). | |
| Callback: Your KP_IntEnable() Kernel PlugIn routine [B.6.6] is called | This function should contain any initialization required for your Kernel PlugIn interrupt handling. |
| Event: Your hardware creates an interrupt. | |
| Callback: Your KP_IntAtIrql() Kernel PlugIn routine [B.6.8] is called. | KP_IntAtIrql() runs at a high
priority, and therefore should
perform only the basic interrupt
handling (such as lowering the HW
interrupt signal of level sensitive
interrupts in order to acknowledge
the interrupt). If more interrupt processing is needed, KP_IntAtIrql() can return TRUE in order to defer additional processing to the KP_IntAtDpc() function [B.6.9]. |
| Event: Your application calls WDC_IntDisable() [B.3.44], or the low-level InterruptDisable() or WD_IntDisable() functions (see the WinDriver PCI Low-Level API Reference), when the interrupts were previously enabled in the Kernel PlugIn (see the description of the interrupt enable event above.) | |
| Callback: Your KP_IntDisable() Kernel PlugIn routine [B.6.7] is called. | This function should free any memory that was allocated by the KP_IntEnable() [B.6.6] callback. |
| Event/Callback | Notes |
|---|---|
| Event: The Kernel PlugIn KP_IntAtIrql() function [B.6.8] returns TRUE. | This informs WinDriver that additional interrupt processing as a deferred procedure call in the kernel. |
| Callback: Your KP_IntAtDpc() Kernel PlugIn routine [B.6.9] is called. | Processes the rest of the interrupt code, but at a lower priority than KP_IntAtIrql(). |
| Event: KP_IntAtDpc() [B.6.9] returns a value greater than 0. | This informs WinDriver that additional user-mode interrupt processing is also required. |
| Callback: WD_IntWait() (see the WinDriver PCI Low-Level API Reference) returns. | Your user-mode interrupt handler routine is executed. |
| Event/Callback | Notes |
|---|---|
| Event: Your application registers to receive Plug and Play and power management notifications using a Kernel PlugIn driver, by calling WDC_EventRegister() [B.3.46] with the with the fUseKP parameter set to TRUE (after having opened the device with a Kernel PlugIn), or calls the low-level EventRegister() (see the WinDriver PCI Low-Level API Reference) or WD_EventRegister() functions with a handle to a Kernel PlugIn driver (set in the hKernelPlugIn field of the WD_EVENT structure that is passed to the function). | |
| Event: A Plug and Play or power management event (to which the application registered to listen) occurs. | |
| Callback: Your KP_Event() Kernel PlugIn routine [B.6.5] is called. | KP_Event() receives information about the event that occurred and can proceed to handle it as needed. |
| Event: KP_Event() [B.6.5] returns TRUE. | This informs WinDriver that the event also requires user-mode handling. |
| Callback: WD_IntWait() (see the WinDriver PCI Low-Level API Reference) returns. | Your user-mode event handler routine is executed. |