B.6 Kernel PlugIn Kernel-Mode Functions
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;
![[Note]](scripts/images/note.png) | |
|---|
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.).
|
PURPOSE
• 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.
PROTOTYPE
BOOL __cdecl KP_Init(KP_INIT *kpInit);
PARAMETERS
DESCRIPTION
RETURN VALUE
TRUE if successful. Otherwise
FALSE.
REMARKS
-
You must define the
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.
EXAMPLE
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;
}
PURPOSE
• 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.
PROTOTYPE
BOOL __cdecl KP_Open(
KP_OPEN_CALL *kpOpenCall,
HANDLE hWD,
PVOID pOpenData,
PVOID *ppDrvContext);
PARAMETERS
DESCRIPTION
RETURN VALUE
TRUE if successful. If
FALSE, the call to
WD_KernelPlugInOpen from the user mode will fail.
EXAMPLE
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;
}
PURPOSE
• 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.).
PROTOTYPE
void __cdecl KP_Close(PVOID pDrvContext);
KP_FUNC_CLOSE Kernel PlugIn callback
function type.
PARAMETERS
DESCRIPTION
RETURN VALUE
None
EXAMPLE
void __cdecl KP_Close(PVOID pDrvContext)
{
if (pDrvContext)
free(pDrvContext); /* Free allocated driver context memory */
}
PURPOSE
• 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.
PROTOTYPE
void __cdecl KP_Call(
PVOID pDrvContext,
WD_KERNEL_PLUGIN_CALL
*kpCall,
BOOL fIsKernelMode);
KP_FUNC_CALL Kernel PlugIn callback
function type.
PARAMETERS
DESCRIPTION
RETURN VALUE
None
REMARKS
-
Calling
WDC_CallKerPlug [B.3.18] (or the low-level
WD_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.
-
The
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.
EXAMPLE
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;
}
}
PURPOSE
• 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).
PROTOTYPE
BOOL __cdecl KP_Event(
PVOID pDrvContext,
WD_EVENT *wd_event);
KP_FUNC_EVENT Kernel PlugIn callback
function type.
PARAMETERS
DESCRIPTION
RETURN VALUE
TRUE in order to notify the user about the event.
REMARKS
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)
EXAMPLE
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 */
}
PURPOSE
• 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.
PROTOTYPE
BOOL __cdecl KP_IntEnable (
PVOID pDrvContext,
WD_KERNEL_PLUGIN_CALL *kpCall,
PVOID *ppIntContext);
KP_FUNC_INT_ENABLE Kernel PlugIn callback
function type.
PARAMETERS
DESCRIPTION
RETURN VALUE
Returns
TRUE if enable is successful; otherwise returns
FALSE.
REMARKS
-
This function should contain any initialization needed for your
Kernel PlugIn interrupt handling.
EXAMPLE
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;
}
PURPOSE
• 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).
• This function should free any memory that was allocated in
KP_IntEnable [
B.6.6].
PROTOTYPE
void __cdecl KP_IntDisable(PVOID pIntContext);
KP_FUNC_INT_DISABLE Kernel PlugIn callback
function type.
PARAMETERS
DESCRIPTION
RETURN VALUE
None
EXAMPLE
void __cdecl KP_IntDisable(PVOID pIntContext)
{
/* You can free the interrupt specific memory
allocated to pIntContext here */
free(pIntContext);
}
PURPOSE
• 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).
PROTOTYPE
BOOL __cdecl KP_IntAtIrql(
PVOID pIntContext,
BOOL *pfIsMyInterrupt);
KP_FUNC_INT_AT_IRQL Kernel PlugIn callback
function type.
PARAMETERS
DESCRIPTION
RETURN VALUE
TRUE if deferred interrupt processing (DPC) is required; otherwise
FALSE.
REMARKS
-
Code running at IRQL will only be interrupted by higher priority
interrupts.
-
Code running at high IRQL is limited in the following ways:
-
It may only access non-pageable memory.
-
It may only call the following functions (or wrapper functions that call
these functions):
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).
-
Specific kernel OS functions (such as WDK functions) that can be
called from high interrupt request level. Note that the use of such
functions may break the code's portability to other operating
systems.
-
It may not call
malloc,
free or any WDC_xxx or WD_xxx
API other than those listed above.
-
The code performed at high interrupt request level should be minimal
(e.g., only the code that acknowledges level-sensitive interrupts), since
it is operating at a high priority. The rest of your code should be
written in
KP_IntAtDpc [B.6.9], which runs at the
deferred DISPATCH level and is not subject to the above restrictions.
EXAMPLE
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;
}
PURPOSE
• 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.
PROTOTYPE
DWORD __cdecl KP_IntAtDpc(
PVOID pIntContext,
DWORD dwCount);
KP_FUNC_INT_AT_DPC Kernel PlugIn callback
function type.
PARAMETERS
DESCRIPTION
RETURN VALUE
Returns the number of times to notify user mode (i.e., return from
WD_IntWait – see the
WinDriver PCI Low-Level API Reference).
REMARKS
-
Most of the interrupt handling should be implemented within this
function, as opposed to the high-priority
KP_IntAtIrql [B.6.8] interrupt
handler.
-
If
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.
EXAMPLE
DWORD __cdecl KP_IntAtDpc(PVOID pIntContext, DWORD dwCount)
{
/* Return WD_IntWait as many times as KP_IntAtIrql
scheduled KP_IntAtDpc */
return dwCount;
}
PURPOSE
• 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).
PROTOTYPE
BOOL __cdecl KP_PCI_IntAtIrqlMSI(
PVOID pIntContext,
ULONG dwLastMessage,
DWORD dwReserved);
KP_FUNC_INT_AT_IRQL_MSI Kernel PlugIn callback
function type.
PARAMETERS
DESCRIPTION
RETURN VALUE
TRUE if deferred MSI/MSI-X processing (DPC) is required; otherwise
FALSE.
REMARKS
-
Code running at IRQL will only be interrupted by higher priority
interrupts.
-
Code running at high IRQL is limited in the following ways:
-
It may only access non-pageable memory.
-
It may only call the following functions (or wrapper functions that call
these functions):
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).
-
Specific kernel OS functions (such as WDK functions) that can be
called from high interrupt request level. Note that the use of such
functions may break the code's portability to other operating
systems.
-
It may not call
malloc,
free or any WDC_xxx or WD_xxx
API other than those listed above.
-
The code performed at high interrupt request level should be minimal,
since it is operating at a high priority. The rest of your code should be
written in
KP_IntAtDpcMSI [B.6.11],
which runs at the deferred DISPATCH level and is not subject to the above
restrictions.
EXAMPLE
BOOL __cdecl KP_PCI_IntAtIrqlMSI(PVOID pIntContext,
ULONG dwLastMessage, DWORD dwReserved)
{
return TRUE;
}
PURPOSE
• 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.
PROTOTYPE
DWORD __cdecl KP_IntAtDpcMSI(
PVOID pIntContext,
DWORD dwCount,
ULONG dwLastMessage,
DWORD dwReserved);
KP_FUNC_INT_AT_DPC_MSI Kernel PlugIn callback
function type.
PARAMETERS
DESCRIPTION
RETURN VALUE
Returns the number of times to notify user mode (i.e., return from
WD_IntWait – see the
WinDriver PCI Low-Level API Reference).
REMARKS
-
Most of the MSI/MSI-X handling should be implemented within this
function, as opposed to the high-priority
KP_IntAtIrqlMSI [B.6.10]
interrupt handler.
-
If
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.
EXAMPLE
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;
}
B.6.12 COPY_TO_USER_OR_KERNEL, COPY_FROM_USER_OR_KERNEL
PURPOSE
• Macros for copying data from the user mode to the Kernel PlugIn
and vice versa.
REMARKS
-
The
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.
-
Note that if you wish to access the user-mode data from within the
Kernel PlugIn interrupt handler functions, you should first copy the data
into some variable in the Kernel PlugIn before the execution of the
kernel-mode interrupt handler routines.
-
The
COPY_TO_USER_OR_KERNEL and
COPY_FROM_USER_OR_KERNEL macros are defined in the
WinDriver\include\kpstdlib.h header file.
-
For an example of using the
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.
-
To safely share a data buffer between the user-mode and Kernel PlugIn
routines (e.g.,
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.
B.6.13 Kernel PlugIn Synchronization APIs
This section describes the Kernel Plug-In synchronization APIs.
These APIs support the following synchronization mechanisms:
-
Spinlocks [B.6.13.2 – B.6.13.5], which are used to synchronize
between threads on a single or multiple CPU system.
![[Note]](scripts/images/note.png) | |
|---|
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].
|
-
Interlocked operations [B.6.13.6 – B.6.13.7], which are used for synchronizing access
to a variable that is shared by multiple threads by performing complex
operations on the variable in an atomic manner.
![[Note]](scripts/images/note.png) | |
|---|
|
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.
|
B.6.13.1 Kernel PlugIn Synchronization Types
The Kernel PlugIn synchronization APIs use the following types:
B.6.13.2 kp_spinlock_init()
PURPOSE
• Initializes a new Kernel PlugIn spinlock object.
PROTOTYPE
KP_SPINLOCK * kp_spinlock_init(void);
RETURN VALUE
If successful, returns a pointer to the new Kernel PlugIn spinlock
object [
B.6.13.1], otherwise returns
NULL.
B.6.13.3 kp_spinlock_wait()
PURPOSE
• Waits on a Kernel PlugIn spinlock object.
PROTOTYPE
void kp_spinlock_wait(KP_SPINLOCK *spinlock);
PARAMETERS
DESCRIPTION
RETURN VALUE
None
B.6.13.4 kp_spinlock_release()
PURPOSE
• Releases a Kernel PlugIn spinlock object.
PROTOTYPE
void kp_spinlock_release(KP_SPINLOCK *spinlock);
PARAMETERS
DESCRIPTION
RETURN VALUE
None
B.6.13.5 kp_spinlock_uninit()
PURPOSE
• Un-initializes a Kernel PlugIn spinlock object.
PROTOTYPE
void kp_spinlock_uninit(KP_SPINLOCK *spinlock);
PARAMETERS
DESCRIPTION
RETURN VALUE
None
B.6.13.6 kp_interlocked_init()
PURPOSE
• Initializes a Kernel PlugIn interlocked counter.
PROTOTYPE
void kp_interlocked_init(KP_INTERLOCKED *target);
PARAMETERS
DESCRIPTION
RETURN VALUE
None
B.6.13.7 kp_interlocked_uninit()
PURPOSE
• Un-initializes a Kernel PlugIn interlocked counter.
PROTOTYPE
void kp_interlocked_uninit(KP_INTERLOCKED *target);
PARAMETERS
DESCRIPTION
RETURN VALUE
None
B.6.13.8 kp_interlocked_increment()
PURPOSE
• Increments the value of a Kernel PlugIn interlocked counter by one.
PROTOTYPE
int kp_interlocked_increment(KP_INTERLOCKED *target);
PARAMETERS
DESCRIPTION
RETURN VALUE
Returns the new value of the interlocked counter (
target).
B.6.13.9 kp_interlocked_decrement()
PURPOSE
• Decrements the value of a Kernel PlugIn interlocked counter by one.
PROTOTYPE
int kp_interlocked_decrement(KP_INTERLOCKED *target);
PARAMETERS
DESCRIPTION
RETURN VALUE
Returns the new value of the interlocked counter (
target).
B.6.13.10 kp_interlocked_add()
PURPOSE
• Adds a specified value to the current value of a Kernel PlugIn
interlocked counter.
PROTOTYPE
int kp_interlocked_add(
KP_INTERLOCKED *target,
int val);
PARAMETERS
DESCRIPTION
RETURN VALUE
Returns the new value of the interlocked counter (
target).
B.6.13.11 kp_interlocked_read()
PURPOSE
• Reads to the value of a Kernel PlugIn interlocked counter.
PROTOTYPE
int kp_interlocked_read(KP_INTERLOCKED *target);
PARAMETERS
DESCRIPTION
RETURN VALUE
Returns the value of the interlocked counter (
target).
B.6.13.12 kp_interlocked_set()
PURPOSE
• Sets the value of a Kernel PlugIn interlocked counter to the
specified value.
PROTOTYPE
void kp_interlocked_set(
KP_INTERLOCKED *target,
int val);
PARAMETERS
DESCRIPTION
RETURN VALUE
None
B.6.13.13 kp_interlocked_exchange()
PURPOSE
• Sets the value of a Kernel PlugIn interlocked counter to the
specified value and returns the previous value of the counter.
PROTOTYPE
int kp_interlocked_exchange(
KP_INTERLOCKED *target,
int val);
PARAMETERS
DESCRIPTION
RETURN VALUE
Returns the previous value of the interlocked counter (
target).