mirror of
https://github.com/reactos/reactos.git
synced 2025-01-05 22:12:46 +00:00
8a978a179f
Takern from Microsoft GitHub repo:
d9c6040fe9
Licensed under MIT
201 lines
4.2 KiB
C++
201 lines
4.2 KiB
C++
/*++
|
|
|
|
Copyright (c) Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
FxDpc.hpp
|
|
|
|
Abstract:
|
|
|
|
This module implements a frameworks managed DPC that
|
|
can synchrononize with driver frameworks object locks.
|
|
|
|
Author:
|
|
|
|
|
|
|
|
Environment:
|
|
|
|
kernel mode only
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
#ifndef _FXDPC_H_
|
|
#define _FXDPC_H_
|
|
|
|
//
|
|
// Driver Frameworks DPC Design:
|
|
//
|
|
// The driver frameworks provides an optional DPC wrapper object that allows
|
|
// the creation of a reference counted DPC object that can synchronize
|
|
// automatically with certain frameworks objects.
|
|
//
|
|
// This provides automatic synchronization between the DPC's execution, and the
|
|
// frameworks objects' event callbacks into the device driver.
|
|
//
|
|
// The WDFDPC object is designed to be re-useable, in which it can be re-linked
|
|
// into the DPC queue after firing.
|
|
//
|
|
// In many cases, the KDPC struct is embedded inside another structure that
|
|
// represents a device command block. These device command blocks are typically
|
|
// submitted to another device driver. So the calling driver, which is utilizing
|
|
// the driver frameworks would not likely have an opportunity to make
|
|
// changes to this. In order to support this, the caller can optionally supply
|
|
// a DPC object pointer to Initialize, and the WDFDPC object will use this
|
|
// embedded user supplied DPC object, and pass its address as the RawDpc
|
|
// parameter to the callback function.
|
|
//
|
|
// If the user does not supply a DPC pointer by passing NULL, then the
|
|
// internal DPC object is used, and RawDPC is NULL.
|
|
//
|
|
// Calling GetDpcPtr returns the DPC to be used, and could be
|
|
// the caller supplied DPC, or the embedded one depending on
|
|
// whether the caller supplied a user DPC pointer to Initialize.
|
|
//
|
|
// The GetDpcPtr allows linking of the WDFDPC object into various DPC
|
|
// lists by the driver.
|
|
//
|
|
|
|
class FxDpc : public FxNonPagedObject {
|
|
|
|
private:
|
|
|
|
KDPC m_Dpc;
|
|
|
|
//
|
|
// This is the Framework object who is associated with the DPC
|
|
// if supplied
|
|
//
|
|
FxObject* m_Object;
|
|
|
|
//
|
|
// This is the callback lock for the object this DPC will
|
|
// synchronize with
|
|
//
|
|
FxCallbackLock* m_CallbackLock;
|
|
|
|
//
|
|
// This is the object whose reference count actually controls
|
|
// the lifetime of the m_CallbackLock
|
|
//
|
|
FxObject* m_CallbackLockObject;
|
|
|
|
//
|
|
// This is the user supplied callback function
|
|
//
|
|
PFN_WDF_DPC m_Callback;
|
|
|
|
// Ensures only one of either Delete or Cleanup runs down the object
|
|
BOOLEAN m_RunningDown;
|
|
|
|
public:
|
|
static
|
|
_Must_inspect_result_
|
|
NTSTATUS
|
|
_Create(
|
|
__in PFX_DRIVER_GLOBALS FxDriverGlobals,
|
|
__in PWDF_DPC_CONFIG Config,
|
|
__in PWDF_OBJECT_ATTRIBUTES Attributes,
|
|
__in FxObject* ParentObject,
|
|
__out WDFDPC* Dpc
|
|
);
|
|
|
|
FxDpc(
|
|
__in PFX_DRIVER_GLOBALS FxDriverGlobals
|
|
);
|
|
|
|
virtual
|
|
~FxDpc(
|
|
VOID
|
|
);
|
|
|
|
KDPC*
|
|
GetDpcPtr(
|
|
VOID
|
|
)
|
|
{
|
|
return &m_Dpc;
|
|
}
|
|
|
|
WDFOBJECT
|
|
GetObject(
|
|
VOID
|
|
)
|
|
{
|
|
if (m_Object != NULL) {
|
|
return m_Object->GetObjectHandle();
|
|
}
|
|
else {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initialize the DPC using either the caller supplied DPC
|
|
struct, or if NULL, our own internal one.
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
NTSTATUS
|
|
|
|
--*/
|
|
_Must_inspect_result_
|
|
NTSTATUS
|
|
Initialize(
|
|
__in PWDF_OBJECT_ATTRIBUTES Attributes,
|
|
__in PWDF_DPC_CONFIG Config,
|
|
__in FxObject* ParentObject,
|
|
__out WDFDPC* Dpc
|
|
);
|
|
|
|
virtual
|
|
BOOLEAN
|
|
Dispose(
|
|
VOID
|
|
);
|
|
|
|
BOOLEAN
|
|
Cancel(
|
|
__in BOOLEAN Wait
|
|
);
|
|
|
|
VOID
|
|
DpcHandler(
|
|
__in PKDPC Dpc,
|
|
__in PVOID SystemArgument1,
|
|
__in PVOID SystemArgument2
|
|
);
|
|
|
|
private:
|
|
|
|
//
|
|
// Called from Dispose, or cleanup list to perform final flushing of any
|
|
// outstanding DPC's and dereferencing of objects.
|
|
//
|
|
VOID
|
|
FlushAndRundown(
|
|
);
|
|
|
|
static
|
|
KDEFERRED_ROUTINE
|
|
FxDpcThunk;
|
|
|
|
static
|
|
VOID
|
|
WorkItemThunk(
|
|
PDEVICE_OBJECT DeviceObject,
|
|
PVOID Context
|
|
);
|
|
};
|
|
|
|
#endif // _FXDPC_H_
|
|
|