mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 14:32:56 +00:00
[WDF] Add Windows Driver Framework files
Takern from Microsoft GitHub repo:
d9c6040fe9
Licensed under MIT
This commit is contained in:
parent
545df81502
commit
8a978a179f
475 changed files with 285099 additions and 0 deletions
381
sdk/lib/drivers/wdf/shared/inc/private/common/fxeventqueue.hpp
Normal file
381
sdk/lib/drivers/wdf/shared/inc/private/common/fxeventqueue.hpp
Normal file
|
@ -0,0 +1,381 @@
|
|||
//
|
||||
// Copyright (C) Microsoft. All rights reserved.
|
||||
//
|
||||
#ifndef _FXEVENTQUEUE_H_
|
||||
#define _FXEVENTQUEUE_H_
|
||||
|
||||
struct FxPostProcessInfo {
|
||||
FxPostProcessInfo(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
m_Event = NULL;
|
||||
m_DeleteObject = FALSE;
|
||||
m_SetRemovedEvent = FALSE;
|
||||
m_FireAndForgetIrp = NULL;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
SomethingToDo(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return ((m_Event != NULL) || m_DeleteObject) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
VOID
|
||||
Evaluate(
|
||||
__inout FxPkgPnp* PkgPnp
|
||||
);
|
||||
|
||||
FxCREvent* m_Event;
|
||||
BOOLEAN m_DeleteObject;
|
||||
BOOLEAN m_SetRemovedEvent;
|
||||
MdIrp m_FireAndForgetIrp;
|
||||
};
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(*PFN_PNP_EVENT_WORKER)(
|
||||
__in FxPkgPnp* PkgPnp,
|
||||
__in FxPostProcessInfo* Info,
|
||||
__in PVOID Context
|
||||
);
|
||||
|
||||
enum FxEventQueueFlags {
|
||||
FxEventQueueFlagWorkItemQueued = 0x01,
|
||||
FxEventQueueFlagClosed = 0x02,
|
||||
FxEventQueueFlagDelayDeletion = 0x04,
|
||||
};
|
||||
|
||||
struct FxEventQueue : public FxStump {
|
||||
FxEventQueue(
|
||||
__in UCHAR QueueDepth
|
||||
);
|
||||
|
||||
_Must_inspect_result_
|
||||
NTSTATUS
|
||||
Initialize(
|
||||
__in PFX_DRIVER_GLOBALS DriverGlobals
|
||||
);
|
||||
|
||||
_Acquires_lock_(this->m_QueueLock)
|
||||
__drv_maxIRQL(DISPATCH_LEVEL)
|
||||
__drv_setsIRQL(DISPATCH_LEVEL)
|
||||
VOID
|
||||
Lock(
|
||||
__out __drv_deref(__drv_savesIRQL)
|
||||
PKIRQL Irql
|
||||
)
|
||||
{
|
||||
m_QueueLock.Acquire(Irql);
|
||||
}
|
||||
|
||||
_Releases_lock_(this->m_QueueLock)
|
||||
__drv_requiresIRQL(DISPATCH_LEVEL)
|
||||
VOID
|
||||
Unlock(
|
||||
__in __drv_restoresIRQL
|
||||
KIRQL Irql
|
||||
)
|
||||
{
|
||||
m_QueueLock.Release(Irql);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
IsFull(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return ((m_QueueHead + m_QueueDepth - 1) % m_QueueDepth) == (m_QueueTail % m_QueueDepth);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
IsEmpty(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return m_QueueHead == m_QueueTail;
|
||||
}
|
||||
|
||||
VOID
|
||||
IncrementHead(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
m_QueueHead = (m_QueueHead + 1) % m_QueueDepth;
|
||||
}
|
||||
|
||||
UCHAR
|
||||
GetHead(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return m_QueueHead;
|
||||
}
|
||||
|
||||
UCHAR
|
||||
InsertAtHead(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
m_QueueHead = (m_QueueHead + m_QueueDepth - 1) % m_QueueDepth;
|
||||
return m_QueueHead;
|
||||
}
|
||||
|
||||
UCHAR
|
||||
InsertAtTail(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UCHAR index;
|
||||
|
||||
// Save the index which is the current tail
|
||||
index = m_QueueTail;
|
||||
|
||||
// goto next slot
|
||||
m_QueueTail = (m_QueueTail + 1) % m_QueueDepth;
|
||||
|
||||
// return the old tail as the slot to insert at
|
||||
return index;
|
||||
}
|
||||
|
||||
UCHAR
|
||||
IncrementHistoryIndex(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UCHAR cur;
|
||||
|
||||
cur = m_HistoryIndex;
|
||||
m_HistoryIndex = (m_HistoryIndex + 1) % m_QueueDepth;
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
IsClosedLocked(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return (m_QueueFlags & FxEventQueueFlagClosed) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
VOID
|
||||
GetFinishedState(
|
||||
__inout FxPostProcessInfo* Info
|
||||
)
|
||||
{
|
||||
if (IsIdleLocked()) {
|
||||
if (m_QueueFlags & FxEventQueueFlagDelayDeletion) {
|
||||
m_QueueFlags &= ~FxEventQueueFlagDelayDeletion;
|
||||
Info->m_DeleteObject = TRUE;
|
||||
}
|
||||
|
||||
if (IsClosedLocked()) {
|
||||
Info->m_Event = m_WorkItemFinished;
|
||||
m_WorkItemFinished = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
SetFinished(
|
||||
__in FxCREvent* Event
|
||||
);
|
||||
|
||||
VOID
|
||||
SetDelayedDeletion(
|
||||
VOID
|
||||
);
|
||||
|
||||
protected:
|
||||
VOID
|
||||
Configure(
|
||||
__in FxPkgPnp* Pnp,
|
||||
__in PFN_PNP_EVENT_WORKER WorkerRoutine,
|
||||
__in PVOID Context
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
QueueToThreadWorker(
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
EventQueueWorker(
|
||||
VOID
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
IsIdleLocked(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
//
|
||||
// We are idle if there is no work item queued, no work item running,
|
||||
// and there are no events in the queue. Since m_WorkItemQueued is
|
||||
// cleared before we enter the state machine, we must also track the
|
||||
// number of work items running.
|
||||
//
|
||||
if ((m_QueueFlags & FxEventQueueFlagWorkItemQueued) == 0x00 &&
|
||||
m_WorkItemRunningCount == 0x0 &&
|
||||
IsEmpty()) {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
// index into the beginning of the circular event ring buffer
|
||||
UCHAR m_QueueHead;
|
||||
|
||||
// index into the end of the circular event ring buffer
|
||||
UCHAR m_QueueTail;
|
||||
|
||||
// circular event ring buffer size
|
||||
UCHAR m_QueueDepth;
|
||||
|
||||
UCHAR m_HistoryIndex;
|
||||
|
||||
FxPkgPnp* m_PkgPnp;
|
||||
|
||||
//
|
||||
// Context that is passed back to the the state machine as
|
||||
// part of the event worker
|
||||
//
|
||||
PVOID m_EventWorkerContext;
|
||||
|
||||
//
|
||||
// Lock for the queue
|
||||
//
|
||||
MxLock m_QueueLock;
|
||||
|
||||
public:
|
||||
FxWaitLockInternal m_StateMachineLock;
|
||||
|
||||
protected:
|
||||
PFN_PNP_EVENT_WORKER m_EventWorker;
|
||||
|
||||
//
|
||||
// Guarded by m_QueueLock. Will be set to a valid pointer value when pnp
|
||||
// wants to remove the device and we want to synchronize against the work
|
||||
// item running.
|
||||
//
|
||||
FxCREvent* m_WorkItemFinished;
|
||||
|
||||
//
|
||||
//
|
||||
union {
|
||||
//
|
||||
// See FxEventQueueFlags for values
|
||||
//
|
||||
UCHAR m_QueueFlags;
|
||||
|
||||
struct {
|
||||
UCHAR WorkItemQueued : 1;
|
||||
UCHAR Closed : 1;
|
||||
UCHAR DelayDeletion : 1;
|
||||
} m_QueueFlagsByName;
|
||||
};
|
||||
|
||||
//
|
||||
// Count of times the work item is running. Since m_WorkItemQueued is
|
||||
// cleared before we enter the state machine, we must also track the
|
||||
// number of instances to make sure we know when we are idle or not.
|
||||
//
|
||||
UCHAR m_WorkItemRunningCount;
|
||||
};
|
||||
|
||||
struct FxWorkItemEventQueue : public FxEventQueue {
|
||||
FxWorkItemEventQueue(
|
||||
__in UCHAR QueueDepth
|
||||
);
|
||||
|
||||
~FxWorkItemEventQueue();
|
||||
|
||||
_Must_inspect_result_
|
||||
NTSTATUS
|
||||
Init(
|
||||
__inout FxPkgPnp* Pnp,
|
||||
__in PFN_PNP_EVENT_WORKER WorkerRoutine,
|
||||
__in PVOID WorkerContext = NULL
|
||||
);
|
||||
|
||||
VOID
|
||||
QueueToThread(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
if (QueueToThreadWorker()) {
|
||||
QueueWorkItem();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
VOID
|
||||
QueueWorkItem(
|
||||
VOID
|
||||
);
|
||||
|
||||
static
|
||||
MX_WORKITEM_ROUTINE
|
||||
_WorkItemCallback;
|
||||
|
||||
MxWorkItem m_WorkItem;
|
||||
};
|
||||
|
||||
//
|
||||
// struct that encapsulates posting a work item to the dedicated power thread
|
||||
// or work item depending on the power pagable status of the stack.
|
||||
//
|
||||
struct FxThreadedEventQueue : public FxEventQueue {
|
||||
FxThreadedEventQueue(
|
||||
__in UCHAR QueueDepth
|
||||
);
|
||||
|
||||
~FxThreadedEventQueue(
|
||||
VOID
|
||||
);
|
||||
|
||||
_Must_inspect_result_
|
||||
NTSTATUS
|
||||
Init(
|
||||
__inout FxPkgPnp* Pnp,
|
||||
__in PFN_PNP_EVENT_WORKER WorkerRoutine,
|
||||
__in PVOID WorkerContext = NULL
|
||||
);
|
||||
|
||||
VOID
|
||||
QueueToThread(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
if (QueueToThreadWorker()) {
|
||||
QueueWorkItem();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
static
|
||||
WORKER_THREAD_ROUTINE
|
||||
_WorkerThreadRoutine;
|
||||
|
||||
static
|
||||
MX_WORKITEM_ROUTINE
|
||||
_WorkItemCallback;
|
||||
|
||||
VOID
|
||||
QueueWorkItem(
|
||||
VOID
|
||||
);
|
||||
|
||||
MxWorkItem m_WorkItem;
|
||||
|
||||
// work item used to queue to the thread
|
||||
WORK_QUEUE_ITEM m_EventWorkQueueItem;
|
||||
};
|
||||
|
||||
#endif // _FXEVENTQUEUE_H_
|
Loading…
Add table
Add a link
Reference in a new issue