The following functions are callback functions which are implemented in your
Kernel PlugIn driver, and which will be called when their calling event occurs.
For example: KP_Init() [B.6.1] is the
callback function that is called when the driver is loaded. Any code that you
want to execute upon loading should be in this function.
KP_Init() sets the name of the driver and the
KP_Open() function.
KP_Open() sets the rest of the driver's callback functions.
For example:
kpOpenCall->funcClose = KP_Close;
kpOpenCall->funcCall = KP_Call;
kpOpenCall->funcIntEnable = KP_IntEnable;
kpOpenCall->funcIntDisable = KP_IntDisable;
kpOpenCall->funcIntAtIrql = KP_IntAtIrql;
kpOpenCall->funcIntAtDpc = KP_IntAtDpc;
kpOpenCall->funcIntAtIrqlMSI = KP_IntAtIrqlMSI;
kpOpenCall->funcIntAtDpcMSI = KP_IntAtDpcMSI;
kpOpenCall->funcEvent = KP_Event;
![]() | |
It is the convention of this reference guide to mark the Kernel PlugIn callback
functions as KP_XXX() – i.e., KP_Open(),
KP_Call(), etc. However, you are free to select any name that you
wish for your Kernel PlugIn callback functions, apart from
KP_Init(), provided you implement relevant callback functions in
your Kernel PlugIn. The generated DriverWizard Kernel PlugIn code, for example,
uses the selected driver name in the callback function names (e.g., for a
<MyKP> driver: KP_MyKP_Open(), KP_MyKP_Call(),
etc.).
|
• Called when the Kernel PlugIn driver is loaded.
Sets the name of the Kernel PlugIn driver and the
KP_Open() [B.6.2] callback function.
BOOL __cdecl KP_Init(KP_INIT *kpInit);
| Name | Type | Input/Output |
|---|---|---|
| kpInit | KP_INIT* | |
| • dwVerWD | DWORD | Output |
| • cDriverName | CHAR[12] | Output |
| • funcOpen | KP_FUNC_OPEN | Output |
| Name | Description |
|---|---|
| kpInit | Pointer to a Kernel PlugIn initialization information structure [B.7.4] |
| • dwVerWD | The version of the WinDriver Kernel PlugIn library |
| • cDriverName | The device driver name (up to 12 characters) |
| • funcOpen |
The KP_Open() callback function, which will be executed when
WD_KernelPlugInOpen() (see the WinDriver PCI Low-Level API Reference) is called.
WD_KernelPlugInOpen() is called from the
WDC_xxxDeviceOpen() functions (PCI [B.3.10] / PCMCIA [B.3.11] / ISA [B.3.12]) when these functions are called with a
valid Kernel PlugIn driver (set in the pcKPDriverName
parameter).
|
TRUE if successful. Otherwise FALSE.
KP_Init() function in your code in order
to link the Kernel PlugIn driver to WinDriver. KP_Init() is
called when the driver is loaded. Any code that you want to execute upon
loading should be in this function.
BOOL __cdecl KP_Init(KP_INIT *kpInit)
{
/* Check if the version of the WinDriver Kernel
PlugIn library is the same version
as windrvr.h and wd_kp.h */
if (kpInit->dwVerWD != WD_VER)
{
/* You need to re-compile your Kernel PlugIn
with the compatible version of the WinDriver
Kernel PlugIn library, windrvr.h and wd_kp.h */
return FALSE;
}
kpInit->funcOpen = KP_Open;
strcpy (kpInit->cDriverName, "KPDriver"); /* Up to 12 chars */
return TRUE;
}
• Called when WD_KernelPlugInOpen() (see the
WinDriver PCI Low-Level API Reference) is called from user mode.
WD_KernelPlugInOpen() is automatically called from the
WDC_xxxDeviceOpen() functions (PCI [B.3.10] / PCMCIA [B.3.11] / ISA [B.3.12]) when these functions are called with a
valid Kernel PlugIn driver (set in the pcKPDriverName
parameter).
This function sets the rest of the Kernel PlugIn callback functions
(KP_Call() [B.6.4],
KP_IntEnable() [B.6.6], etc.) and
performs any other desired initialization (such as allocating memory for the
driver context and filling it with data passed from the user mode, etc.).
The returned driver context (*ppDrvContext) will be passed to rest
of the Kernel PlugIn callback functions.
BOOL __cdecl KP_Open(
KP_OPEN_CALL *kpOpenCall,
HANDLE hWD,
PVOID pOpenData,
PVOID *ppDrvContext);
| Name | Type | Input/Output |
|---|---|---|
| kpOpenCall | KP_OPEN_CALL | Input |
| hWD | HANDLE | Input |
| pOpenData | PVOID | Input |
| ppDrvContext | PVOID* | Output |
| Name | Description |
|---|---|
| kpOpenCall | Structure to fill in the addresses of the KP_xxx()
callback functions [B.7.5]
|
| hWD | The WinDriver handle that WD_KernelPlugInOpen() was called
with
|
| pOpenData | Pointer to data passed from user mode |
| ppDrvContext | Pointer to driver context data with which the
KP_Close() [B.6.3],
KP_Call() [B.6.4],
KP_IntEnable() [B.6.6] and
KP_Event() [B.6.5] functions will be
called. Use this to keep driver specific information, which will be shared
among these callbacks.
|
TRUE if successful. If FALSE, the call to
WD_KernelPlugInOpen() from the user mode will fail.
BOOL __cdecl KP_Open(KP_OPEN_CALL *kpOpenCall, HANDLE hWD,
PVOID pOpenData, PVOID *ppDrvContext)
{
kpOpenCall->funcClose = KP_Close;
kpOpenCall->funcCall = KP_Call;
kpOpenCall->funcIntEnable = KP_IntEnable;
kpOpenCall->funcIntDisable = KP_IntDisable;
kpOpenCall->funcIntAtIrql = KP_IntAtIrql;
kpOpenCall->funcIntAtDpc = KP_IntAtDpc;
kpOpenCall->funcIntAtIrqlMSI = KP_IntAtIrqlMSI;
kpOpenCall->funcIntAtDpcMSI = KP_IntAtDpcMSI;
kpOpenCall->funcEvent = KP_Event;
/* You can allocate driver context memory here: */
*ppDrvContext = malloc(sizeof(MYDRV_STRUCT));
return *ppDrvContext!=NULL;
}
• Called when WD_KernelPlugInClose() (see the
WinDriver PCI Low-Level API Reference) is called from user mode.
For devices that have been opened with a Kernel PlugIn driver – i.e.,
WDC_xxxDeviceOpen() (PCI [B.3.10] / PCMCIA [B.3.11] / ISA [B.3.12]) was called with a valid Kernel PlugIn
driver (set in the pcKPDriverName parameter) – the
WDC_xxxDeviceClose() functions (PCI [B.3.13] / PCMCIA [B.3.14] / ISA [B.3.15]) automatically call
WD_KernelPlugInClose() in order to close the handle to the
Kernel PlugIn driver.
This functions can be used to perform any required clean-up for the Kernel PlugIn (such as freeing memory previously allocated for the driver context, etc.).
void __cdecl KP_Close(PVOID pDrvContext);
KP_FUNC_CLOSE Kernel PlugIn callback
function type.
| Name | Type | Input/Output |
|---|---|---|
| pDrvContext | PVOID | Input |
| Name | Description |
|---|---|
| pDrvContext |
Driver context data that was set by KP_Open() [B.6.2]
|
None
void __cdecl KP_Close(PVOID pDrvContext)
{
if (pDrvContext)
free(pDrvContext); /* Free allocated driver context memory */
}
• Called when the user-mode application calls
WDC_CallKerPlug() [B.3.18] (or
the low-level WD_KernelPlugInCall() function – see the
WinDriver PCI Low-Level API Reference).
This function is a message handler for your utility functions.
void __cdecl KP_Call(
PVOID pDrvContext,
WD_KERNEL_PLUGIN_CALL
*kpCall,
BOOL fIsKernelMode);
KP_FUNC_CALL Kernel PlugIn callback
function type.
| Name | Type | Input/Output |
|---|---|---|
| pDrvContext | PVOID | Input/Output |
| kpCall | WD_KERNEL_PLUGIN_CALL | |
| • dwMessage | DWORD | Input |
| • pData | PVOID | Input/Output |
| • dwResult | DWORD | Output |
| fIsKernelMode | BOOL | Input |
| Name | Description |
|---|---|
| pDrvContext |
Driver context data that was set by KP_Open() [B.6.2] and will also be passed to
KP_Close() [B.6.3],
KP_IntEnable() [B.6.6] and
KP_Event() [B.6.5]
|
| kpCall |
Structure with user-mode information received from the
WDC_CallKerPlug() [B.3.18] (or
from the low-level WD_KernelPlugInCall() function – see
the WinDriver PCI Low-Level API Reference) and/or with information to return back to the user
mode [B.7.3]
|
| fIsKernelMode | This parameter is passed by the WinDriver kernel – see remark 2, below. |
None
WDC_CallKerPlug() [B.3.18] (or the low-levelWD_KernelPlugInCall() function – see the
WinDriver PCI Low-Level API Reference) in the user mode will call your
KP_Call() [B.6.4] callback function
in the kernel mode. The KP_Call() function in the Kernel
PlugIn will determine which routine to execute according to the message
passed to it.
fIsKernelMode parameter is passed by the WinDriver kernel to
the KP_Call() routine. The user is not required to do anything
about this parameter. However, notice how this parameter is passed in the
sample code to the macro COPY_TO_USER_OR_KERNEL – This
is required for the macro to function correctly. Please refer to
section B.6.12 for more details
regarding the COPY_TO_USER_OR_KERNEL and
COPY_FROM_USER_OR_KERNEL macros.
void __cdecl KP_Call(PVOID pDrvContext,
WD_KERNEL_PLUGIN_CALL *kpCall, BOOL fIsKernelMode)
{
kpCall->dwResult = MY_DRV_OK;
switch (kpCall->dwMessage)
{
/* In this sample we implement a GetVersion message */
case MY_DRV_MSG_VERSION:
{
DWORD dwVer = 100;
MY_DRV_VERSION *ver = (MY_DRV_VERSION *)kpCall->pData;
COPY_TO_USER_OR_KERNEL(&ver->dwVer, &dwVer,
sizeof(DWORD), fIsKernelMode);
COPY_TO_USER_OR_KERNEL(ver->cVer, "My Driver V1.00",
sizeof("My Driver V1.00")+1, fIsKernelMode);
kpCall->dwResult = MY_DRV_OK;
}
break;
/* You can implement other messages here */
default:
kpCall->dwResult = MY_DRV_NO_IMPL_MESSAGE;
}
}
• Called when a Plug-and-Play or power management event for the
device is received, provided the user-mode application first called
WDC_EventRegister() [B.3.49]
with fUseKP = TRUE (or the low-level
EventRegister() function with a Kernel PlugIn handle – see
WinDriver PCI Low-Level API Reference) (see the Remarks below).
BOOL __cdecl KP_Event(
PVOID pDrvContext,
WD_EVENT *wd_event);
KP_FUNC_EVENT Kernel PlugIn callback
function type.
| Name | Type | Input/Output |
|---|---|---|
| pDrvContext | PVOID | Input/Output |
| wd_event | WD_EVENT* | Input |
| Name | Description |
|---|---|
| pDrvContext |
Driver context data that was set by KP_Open() [B.6.2] and will also be passed to
KP_Close() [B.6.3],
KP_IntEnable() [B.6.6] and
KP_Call() [B.6.4]
|
| wd_event | Pointer to the PnP/power management event information received from the user mode |
TRUE in order to notify the user about the event.
KP_Event() will be called if the user mode process called
WDC_EventRegister() [B.3.49]
with fUseKP= TRUE (or of the low-level
EventRegister() function was called with a Kernel PlugIn
handle – see the WinDriver PCI Low-Level API Reference)
BOOL __cdecl KP_Event(PVOID pDrvContext, WD_EVENT *wd_event)
{
/* Handle the event here */
return TRUE; /* Return TRUE to notify the user about the event */
}
• Called when WD_IntEnable() (see WinDriver PCI Low-Level API Reference) is
called from the user mode with a Kernel PlugIn handle.
WD_IntEnable() is called automatically from
WDC_IntEnable() [B.3.46] and
InterruptEnable() (see WinDriver PCI Low-Level API Reference).
The interrupt context that is set by this function (*ppIntContext)
will be passed to the rest of the Kernel PlugIn interrupt functions.
BOOL __cdecl KP_IntEnable (
PVOID pDrvContext,
WD_KERNEL_PLUGIN_CALL *kpCall,
PVOID *ppIntContext);
KP_FUNC_INT_ENABLE Kernel PlugIn callback
function type.
| Name | Type | Input/Output |
|---|---|---|
| pDrvContext | PVOID | Input/Output |
| kpCall | WD_KERNEL_PLUGIN_CALL | Input |
| • dwMessage | DWORD | Input |
| • pData | PVOID | Input/Output |
| • dwResult | DWORD | Output |
| ppIntContext | PVOID* | Input/Output |
| Name | Description |
|---|---|
| pDrvContext |
Driver context data that was set by KP_Open() [B.6.2] and will also be passed to
KP_Close() [B.6.3],
KP_Call() [B.6.4] and
KP_Event() [B.6.5]
|
| kpCall |
Structure with information from WD_IntEnable() [B.7.3]
|
| ppIntContext |
Pointer to interrupt context data that will be passed to
KP_IntDisable() [B.6.7] and to
the Kernel PlugIn interrupt handler functions. Use this context to keep
interrupt specific information.
|
Returns TRUE if enable is successful; otherwise returns
FALSE.
BOOL __cdecl KP_IntEnable(PVOID pDrvContext,
WD_KERNEL_PLUGIN_CALL *kpCall, PVOID *ppIntContext)
{
DWORD *pIntCount;
/* You can allocate specific memory for each interrupt
in *ppIntContext */
*ppIntContext = malloc(sizeof (DWORD));
if (!*ppIntContext)
return FALSE;
/* In this sample the information is a DWORD used to
count the incoming interrupts */
pIntCount = (DWORD *) *ppIntContext;
*pIntCount = 0; /* Reset the count to zero */
return TRUE;
}
• Called when WD_IntDisable() (see WinDriver PCI Low-Level API Reference)
is called from the user mode for interrupts that were enabled in the Kernel
PlugIn.
WD_IntDisable() is called automatically from
WDC_IntDisable() [B.3.47] and
InterruptDisable() (see WinDriver PCI Low-Level API Reference).
KP_IntEnable() [B.6.6].
void __cdecl KP_IntDisable(PVOID pIntContext);
KP_FUNC_INT_DISABLE Kernel PlugIn callback
function type.
| Name | Type | Input/Output |
|---|---|---|
| pIntContext | PVOID | Input |
| Name | Description |
|---|---|
| pIntContext |
Interrupt context data that was set by
KP_IntEnable() [B.6.6]
|
None
void __cdecl KP_IntDisable(PVOID pIntContext)
{
/* You can free the interrupt specific memory
allocated to pIntContext here */
free(pIntContext);
}
• High-priority legacy interrupt handler routine, which is run at
high interrupt request level. This function is called upon the arrival of a
legacy interrupt that has been enabled using a Kernel PlugIn driver –
see the description of WDC_IntEnable() [B.3.46] or the low-level InterruptEnable()
and WD_IntEnable() functions (see WinDriver PCI Low-Level API Reference).
BOOL __cdecl KP_IntAtIrql(
PVOID pIntContext,
BOOL *pfIsMyInterrupt);
KP_FUNC_INT_AT_IRQL Kernel PlugIn callback
function type.
| Name | Type | Input/Output |
|---|---|---|
| pIntContext | PVOID | Input/Output |
| pfIsMyInterrupt | BOOL* | Output |
| Name | Description |
|---|---|
| pIntContext |
Pointer to interrupt context data that was set by
KP_IntEnable() [B.6.6] and will
also be passed to KP_IntAtDpc() [B.6.9] (if executed) and
KP_IntDisable() [B.6.7]
|
| pfIsMyInterrupt |
Set *pfIsMyInterrupt to TRUE if the interrupt
belongs to this driver; otherwise set it to FALSE in order to
enable the interrupt service routines of other drivers for the same
interrupt to be called
|
TRUE if deferred interrupt processing (DPC) is required; otherwise
FALSE.
WDC_xxx() read/write address or configuration space
functions.
WDC_MultiTransfer() [B.3.25], or the low-level
WD_Transfer(), WD_MultiTransfer(), or
WD_DebugAdd() functions (see the WinDriver PCI Low-Level API Reference).
malloc(), free(), or any
WDC_xxx or WD_xxx API other than those listed
above.
KP_IntAtDpc() [B.6.9],
which runs at the deferred DISPATCH level and is not subject to the above
restrictions.
BOOL __cdecl KP_IntAtIrql(PVOID pIntContext,
BOOL *pfIsMyInterrupt)
{
DWORD *pdwIntCount = (DWORD *) pIntContext;
/* Check your hardware here to see if the interrupt belongs to you.
If it does, you must set *pfIsMyInterrupt to TRUE.
Otherwise, set *pfIsMyInterrupt to FALSE. */
*pfIsMyInterrupt = FALSE;
/* In this example we will schedule a DPC
once in every 5 interrupts */
(*pdwIntCount) ++;
if (*pdwIntCount==5)
{
*pdwIntCount = 0;
return TRUE;
}
return FALSE;
}
• Deferred processing legacy interrupt handler routine.
This function is called once the high-priority legacy interrupt handling is
completed, provided that KP_IntAtIrql() [B.6.8] returned TRUE.
DWORD __cdecl KP_IntAtDpc(
PVOID pIntContext,
DWORD dwCount);
KP_FUNC_INT_AT_DPC Kernel PlugIn callback
function type.
| Name | Type | Input/Output |
|---|---|---|
| pIntContext | PVOID | Input/Output |
| dwCount | DWORD | Input |
| Name | Description |
|---|---|
| pIntContext |
Interrupt context data that was set by
KP_IntEnable() [B.6.6], passed
to KP_IntAtIrql() [B.6.8], and
will be passed to KP_IntDisable() [B.6.7]
|
| dwCount |
The number of times KP_IntAtIrql() [B.6.8] returned TRUE since the last DPC
call. If dwCount is 1, KP_IntAtIrql() requested a
DPC only once since the last DPC call. If the value is greater than 1,
KP_IntAtIrql() has already requested a DPC a few times, but
the interval was too short, therefore KP_IntAtDpc() was not
called for each DPC request.
|
Returns the number of times to notify user mode (i.e., return from
WD_IntWait() – see the WinDriver PCI Low-Level API Reference).
KP_IntAtIrql() [B.6.8] interrupt
handler.
KP_IntAtDpc() returns with a value greater than zero,
WD_IntWait() returns and the user-mode interrupt handler will
be called in the amount of times set in the return value of
KP_IntAtDpc(). If you do not want the user-mode interrupt
handler to execute, KP_IntAtDpc() should return zero.
DWORD __cdecl KP_IntAtDpc(PVOID pIntContext, DWORD dwCount)
{
/* Return WD_IntWait as many times as KP_IntAtIrql
scheduled KP_IntAtDpc */
return dwCount;
}
• High-priority Message-Signaled Interrupts (MSI) / Extended Message-Signaled Interrupts (MSI-X) handler routine,
which is run at high interrupt request level. This function is called upon
the arrival of an MSI/MSI-X that has been enabled using a Kernel PlugIn
– see the description of WDC_IntEnable() [B.3.46] or the low-level InterruptEnable()
and WD_IntEnable() functions (see WinDriver PCI Low-Level API Reference).
BOOL __cdecl KP_PCI_IntAtIrqlMSI(
PVOID pIntContext,
ULONG dwLastMessage,
DWORD dwReserved);
KP_FUNC_INT_AT_IRQL_MSI Kernel PlugIn callback
function type.
| Name | Type | Input/Output |
|---|---|---|
| pIntContext | PVOID | Input/Output |
| dwLastMessage | DWORD | Input |
| dwReserved | DWORD | Input |
| Name | Description |
|---|---|
| pIntContext |
Pointer to interrupt context data that was set by
KP_IntEnable() [B.6.6] and will
also be passed to KP_IntAtDpcMSI() [B.6.11] (if executed) and
KP_IntDisable() [B.6.7]
|
| dwLastMessage | The message data for the last received interrupt (applicable only on Windows Vista and higher) |
| dwReserved | Reserved for future use. Do not use this parameter. |
TRUE if deferred MSI/MSI-X processing (DPC) is required; otherwise
FALSE.
WDC_xxx() read/write address or configuration space
functions.
WDC_MultiTransfer() [B.3.25], or the low-level
WD_Transfer(), WD_MultiTransfer(), or
WD_DebugAdd() functions (see the WinDriver PCI Low-Level API Reference).
malloc(), free(), or any
WDC_xxx or WD_xxx API other than those listed
above.
KP_IntAtDpcMSI() [B.6.11],
which runs at the deferred DISPATCH level and is not subject to the above
restrictions.
BOOL __cdecl KP_PCI_IntAtIrqlMSI(PVOID pIntContext,
ULONG dwLastMessage, DWORD dwReserved)
{
return TRUE;
}
• Deferred processing Message-Signaled Interrupts (MSI) / Extended Message-Signaled Interrupts (MSI-X) handler
routine.
This function is called once the high-priority MSI/MSI-X handling is
completed, provided that KP_IntAtIrqlMSI() [B.6.10] returned TRUE.
DWORD __cdecl KP_IntAtDpcMSI( PVOID pIntContext, DWORD dwCount, ULONG dwLastMessage, DWORD dwReserved);
KP_FUNC_INT_AT_DPC_MSI Kernel PlugIn callback
function type.
| Name | Type | Input/Output |
|---|---|---|
| pIntContext | PVOID | Input/Output |
| dwCount | DWORD | Input |
| dwLastMessage | DWORD | Input |
| dwReserved | DWORD | Input |
| Name | Description |
|---|---|
| pIntContext |
Interrupt context data that was set by
KP_IntEnable() [B.6.6], passed
to KP_IntAtIrqlMSI() [B.6.10],
and will be passed to KP_IntDisable() [B.6.7]
|
| dwCount |
The number of times KP_IntAtIrqlMSI() [B.6.10] returned TRUE since the last
DPC call. If dwCount is 1, KP_IntAtIrqlMSI()
requested a DPC only once since the last DPC call. If the value is greater
than 1, KP_IntAtIrqlMSI() has already requested a DPC a few
times, but the interval was too short, therefore
KP_IntAtDpcMSI() was not called for each DPC request.
|
| dwLastMessage | The message data for the last received interrupt (applicable only on Windows Vista and higher) |
| dwReserved | Reserved for future use. Do not use this parameter. |
Returns the number of times to notify user mode (i.e., return from
WD_IntWait() – see the WinDriver PCI Low-Level API Reference).
KP_IntAtIrqlMSI() [B.6.10]
interrupt handler.
KP_IntAtDpcMSI() returns with a value greater than zero,
WD_IntWait() returns and the user-mode interrupt handler will
be called in the amount of times set in the return value of
KP_IntAtDpcMSI(). If you do not want the user-mode interrupt
handler to execute, KP_IntAtDpcMSI() should return zero.
DWORD __cdecl KP_IntAtDpcMSI(PVOID pIntContext, DWORD dwCount,
ULONG dwLastMessage, DWORD dwReserved)
{
/* Return WD_IntWait as many times as KP_IntAtIrqlMSI
scheduled KP_IntAtDpcMSI */
return dwCount;
}
• Macros for copying data from the user mode to the Kernel PlugIn and vice versa.
COPY_TO_USER_OR_KERNEL and
COPY_FROM_USER_OR_KERNEL are macros used for copying data
(when necessary) to/from user-mode memory addresses (respectively), when
accessing such addresses from within the Kernel PlugIn. Copying the data
ensures that the user-mode address can be used correctly, even if the
context of the user-mode process changes in the midst of the I/O
operation. This is particularly relevant for long operations, during
which the context of the user-mode process may change. The use of macros
to perform the copy provides a generic solution for all supported
operating systems.
COPY_TO_USER_OR_KERNEL and
COPY_FROM_USER_OR_KERNEL macros are defined in the
WinDriver\include\kpstdlib.h header file.
COPY_TO_USER_OR_KERNEL macro,
see the KP_Call() [B.6.4]
implementation (KP_PCI_Call()) in the sample
WinDriver/samples/pci_diag/kp_pci/kp_pci.c Kernel PlugIn file.
KP_IntAtIrql() [B.6.8] and
KP_IntAtDpc() [B.6.9]), consider
using the technique outlined in the technical document titled "How do I
share a memory buffer between Kernel PlugIn and user-mode projects for DMA
or other purposes?" found under the "Kernel PlugIn" technical documents
section of the "Support" section.
![]() | |
The Kernel PlugIn spinlock functions can be called from any context
apart from high interrupt request level. Hence, they can be called from
any Kernel PlugIn function except for
KP_IntAtIrql() [B.6.8] and
KP_IntAtIrqlMSI() [B.6.10].
Note that the spinlock functions can be called from the deferred
processing interrupt handler functions –
KP_IntAtDpc() [B.6.9] and
KP_IntAtDpcMSI() [B.6.11].
|
![]() | |
| The Kernel PlugIn interlocked functions can be called from any context in the Kernel PlugIn, including from high interrupt request level. Hence, they can be called from any Kernel PlugIn function, including the Kernel PlugIn interrupt handler functions. |
The Kernel PlugIn synchronization APIs use the following types:
• Initializes a new Kernel PlugIn spinlock object.
KP_SPINLOCK * kp_spinlock_init(void);
If successful, returns a pointer to the new Kernel PlugIn
spinlock object [B.6.13.1], otherwise returns NULL.
• Waits on a Kernel PlugIn spinlock object.
void kp_spinlock_wait(KP_SPINLOCK *spinlock);
| Name | Type | Input/Output |
|---|---|---|
| spinlock | KP_SPINLOCK* | Input |
| Name | Description |
|---|---|
| spinlock | Pointer to the Kernel PlugIn spinlock object [B.6.13.1] on which to wait |
None
• Releases a Kernel PlugIn spinlock object.
void kp_spinlock_release(KP_SPINLOCK *spinlock);
| Name | Type | Input/Output |
|---|---|---|
| spinlock | KP_SPINLOCK* | Input |
| Name | Description |
|---|---|
| spinlock | Pointer to the Kernel PlugIn spinlock object [B.6.13.1] to release |
None
• Un-initializes a Kernel PlugIn spinlock object.
void kp_spinlock_uninit(KP_SPINLOCK *spinlock);
| Name | Type | Input/Output |
|---|---|---|
| spinlock | KP_SPINLOCK* | Input |
| Name | Description |
|---|---|
| spinlock | Pointer to the Kernel PlugIn spinlock object [B.6.13.1] to un-initialize |
None
• Initializes a Kernel PlugIn interlocked counter.
void kp_interlocked_init(KP_INTERLOCKED *target);
| Name | Type | Input/Output |
|---|---|---|
| target | KP_INTERLOCKED* | Input/Output |
| Name | Description |
|---|---|
| target | Pointer to the Kernel PlugIn interlocked counter [B.6.13.1] to initialize |
None
• Un-initializes a Kernel PlugIn interlocked counter.
void kp_interlocked_uninit(KP_INTERLOCKED *target);
| Name | Type | Input/Output |
|---|---|---|
| target | KP_INTERLOCKED* | Input/Output |
| Name | Description |
|---|---|
| target | Pointer to the Kernel PlugIn interlocked counter [B.6.13.1] to un-initialize |
None
• Increments the value of a Kernel PlugIn interlocked counter by one.
int kp_interlocked_increment(KP_INTERLOCKED *target);
| Name | Type | Input/Output |
|---|---|---|
| target | KP_INTERLOCKED* | Input/Output |
| Name | Description |
|---|---|
| target | Pointer to the Kernel PlugIn interlocked counter [B.6.13.1] to increment |
Returns the new value of the interlocked counter (target).
• Decrements the value of a Kernel PlugIn interlocked counter by one.
int kp_interlocked_decrement(KP_INTERLOCKED *target);
| Name | Type | Input/Output |
|---|---|---|
| target | KP_INTERLOCKED* | Input/Output |
| Name | Description |
|---|---|
| target | Pointer to the Kernel PlugIn interlocked counter [B.6.13.1] to decrement |
Returns the new value of the interlocked counter (target).
• Adds a specified value to the current value of a Kernel PlugIn interlocked counter.
int kp_interlocked_add(
KP_INTERLOCKED *target,
int val);
| Name | Type | Input/Output |
|---|---|---|
| target | KP_INTERLOCKED* | Input/Output |
| val | val | Input |
| Name | Description |
|---|---|
| target | Pointer to the Kernel PlugIn interlocked counter [B.6.13.1] to which to add |
| val |
The value to add to the interlocked counter (target)
|
Returns the new value of the interlocked counter (target).
• Reads to the value of a Kernel PlugIn interlocked counter.
int kp_interlocked_read(KP_INTERLOCKED *target);
| Name | Type | Input/Output |
|---|---|---|
| target | KP_INTERLOCKED* | Input |
| Name | Description |
|---|---|
| target | Pointer to the Kernel PlugIn interlocked counter [B.6.13.1] to read |
Returns the value of the interlocked counter (target).
• Sets the value of a Kernel PlugIn interlocked counter to the specified value.
void kp_interlocked_set(
KP_INTERLOCKED *target,
int val);
| Name | Type | Input/Output |
|---|---|---|
| target | KP_INTERLOCKED* | Input/Output |
| val | val | Input |
| Name | Description |
|---|---|
| target | Pointer to the Kernel PlugIn interlocked counter [B.6.13.1] to set |
| val |
The value to set for the interlocked counter (target)
|
None
• Sets the value of a Kernel PlugIn interlocked counter to the specified value and returns the previous value of the counter.
int kp_interlocked_exchange(
KP_INTERLOCKED *target,
int val);
| Name | Type | Input/Output |
|---|---|---|
| target | KP_INTERLOCKED* | Input/Output |
| val | val | Input |
| Name | Description |
|---|---|
| target | Pointer to the Kernel PlugIn interlocked counter [B.6.13.1] to exchange |
| val |
The new value to set for the interlocked counter (target)
|
Returns the previous value of the interlocked counter (target).