mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 13:21:39 +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
|
@ -0,0 +1,469 @@
|
|||
/*++
|
||||
Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
Module Name:
|
||||
|
||||
SelfManagedIoStateMachine.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
This module implements the self managed io state machine start / stop logic
|
||||
in the framework.
|
||||
|
||||
Author:
|
||||
|
||||
|
||||
|
||||
Environment:
|
||||
Both kernel and user mode
|
||||
|
||||
Revision History:
|
||||
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
#include "pnppriv.hpp"
|
||||
|
||||
extern "C" {
|
||||
#if defined(EVENT_TRACING)
|
||||
#include "SelfManagedIoStateMachine.tmh"
|
||||
#endif
|
||||
}
|
||||
|
||||
// * - We can get a restart from the created state if a PDO is newly enumerated
|
||||
// but was disabled on a previous enumeration. Treat restart as an init
|
||||
// in this case.
|
||||
const FxSelfManagedIoTargetState FxSelfManagedIoMachine::m_CreatedStates[] =
|
||||
{
|
||||
{ SelfManagedIoEventStart, FxSelfManagedIoInit DEBUGGED_EVENT },
|
||||
{ SelfManagedIoEventFlush, FxSelfManagedIoCreated DEBUGGED_EVENT },
|
||||
{ SelfManagedIoEventCleanup, FxSelfManagedIoFinal DEBUGGED_EVENT },
|
||||
};
|
||||
|
||||
const FxSelfManagedIoTargetState FxSelfManagedIoMachine::m_InitFailedStates[] =
|
||||
{
|
||||
{ SelfManagedIoEventSuspend, FxSelfManagedIoInitFailed DEBUGGED_EVENT },
|
||||
{ SelfManagedIoEventFlush, FxSelfManagedIoFlushing DEBUGGED_EVENT },
|
||||
};
|
||||
|
||||
const FxSelfManagedIoTargetState FxSelfManagedIoMachine::m_StartedStates[] =
|
||||
{
|
||||
{ SelfManagedIoEventSuspend, FxSelfManagedIoSuspending DEBUGGED_EVENT },
|
||||
};
|
||||
|
||||
const FxSelfManagedIoTargetState FxSelfManagedIoMachine::m_StoppedStates[] =
|
||||
{
|
||||
{ SelfManagedIoEventStart, FxSelfManagedIoRestarting DEBUGGED_EVENT },
|
||||
{ SelfManagedIoEventSuspend, FxSelfManagedIoStopped DEBUGGED_EVENT },
|
||||
{ SelfManagedIoEventFlush, FxSelfManagedIoFlushing DEBUGGED_EVENT },
|
||||
};
|
||||
|
||||
const FxSelfManagedIoTargetState FxSelfManagedIoMachine::m_FailedStates[] =
|
||||
{
|
||||
{ SelfManagedIoEventFlush, FxSelfManagedIoFlushing DEBUGGED_EVENT },
|
||||
{ SelfManagedIoEventSuspend, FxSelfManagedIoFailed DEBUGGED_EVENT },
|
||||
};
|
||||
|
||||
const FxSelfManagedIoTargetState FxSelfManagedIoMachine::m_FlushedStates[] =
|
||||
{
|
||||
{ SelfManagedIoEventStart, FxSelfManagedIoRestarting DEBUGGED_EVENT },
|
||||
{ SelfManagedIoEventCleanup, FxSelfManagedIoCleanup DEBUGGED_EVENT },
|
||||
{ SelfManagedIoEventFlush, FxSelfManagedIoFlushed TRAP_ON_EVENT },
|
||||
};
|
||||
|
||||
const FxSelfManagedIoStateTable FxSelfManagedIoMachine::m_StateTable[] =
|
||||
{
|
||||
// FxSelfManagedIoCreated
|
||||
{ NULL,
|
||||
FxSelfManagedIoMachine::m_CreatedStates,
|
||||
ARRAY_SIZE(FxSelfManagedIoMachine::m_CreatedStates),
|
||||
},
|
||||
|
||||
// FxSelfManagedIoInit
|
||||
{ FxSelfManagedIoMachine::Init,
|
||||
NULL,
|
||||
0,
|
||||
},
|
||||
|
||||
// FxSelfManagedIoInitFailed
|
||||
{ NULL,
|
||||
FxSelfManagedIoMachine::m_InitFailedStates,
|
||||
ARRAY_SIZE(FxSelfManagedIoMachine::m_InitFailedStates),
|
||||
},
|
||||
|
||||
// FxSelfManagedIoStarted
|
||||
{ NULL,
|
||||
FxSelfManagedIoMachine::m_StartedStates,
|
||||
ARRAY_SIZE(FxSelfManagedIoMachine::m_StartedStates),
|
||||
},
|
||||
|
||||
// FxSelfManagedIoSuspending
|
||||
{ FxSelfManagedIoMachine::Suspending,
|
||||
NULL,
|
||||
0,
|
||||
},
|
||||
|
||||
// FxSelfManagedIoStopped
|
||||
{ NULL,
|
||||
FxSelfManagedIoMachine::m_StoppedStates,
|
||||
ARRAY_SIZE(FxSelfManagedIoMachine::m_StoppedStates),
|
||||
},
|
||||
|
||||
// FxSelfManagedIoRestarting
|
||||
{ FxSelfManagedIoMachine::Restarting,
|
||||
NULL,
|
||||
0,
|
||||
},
|
||||
|
||||
// FxSelfManagedIoFailed
|
||||
{ NULL,
|
||||
FxSelfManagedIoMachine::m_FailedStates,
|
||||
ARRAY_SIZE(FxSelfManagedIoMachine::m_FailedStates),
|
||||
},
|
||||
|
||||
// FxSelfManagedIoFlushing
|
||||
{ FxSelfManagedIoMachine::Flushing,
|
||||
NULL,
|
||||
0,
|
||||
},
|
||||
|
||||
// FxSelfManagedIoFlushed
|
||||
{ NULL,
|
||||
FxSelfManagedIoMachine::m_FlushedStates,
|
||||
ARRAY_SIZE(FxSelfManagedIoMachine::m_FlushedStates),
|
||||
},
|
||||
|
||||
// FxSelfManagedIoCleanup
|
||||
{ FxSelfManagedIoMachine::Cleanup,
|
||||
NULL,
|
||||
0,
|
||||
},
|
||||
|
||||
// FxSelfManagedIoFinal
|
||||
{ NULL,
|
||||
NULL,
|
||||
0,
|
||||
},
|
||||
};
|
||||
|
||||
FxSelfManagedIoMachine::FxSelfManagedIoMachine(
|
||||
__in FxPkgPnp* PkgPnp
|
||||
)
|
||||
{
|
||||
m_PkgPnp = PkgPnp;
|
||||
|
||||
m_EventHistoryIndex = 0;
|
||||
m_StateHistoryIndex = 0;
|
||||
|
||||
m_CurrentState = FxSelfManagedIoCreated;
|
||||
|
||||
RtlZeroMemory(&m_Events, sizeof(m_Events));
|
||||
RtlZeroMemory(&m_States, sizeof(m_States));
|
||||
|
||||
//
|
||||
// Make sure we can fit the state into a byte
|
||||
//
|
||||
ASSERT(FxSelfManagedIoMax <= 0xFF);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
FxSelfManagedIoMachine::_CreateAndInit(
|
||||
__deref_out FxSelfManagedIoMachine** SelfManagedIoMachine,
|
||||
__in FxPkgPnp* PkgPnp
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
FxSelfManagedIoMachine * selfManagedIoMachine;
|
||||
|
||||
*SelfManagedIoMachine = NULL;
|
||||
|
||||
selfManagedIoMachine = new (PkgPnp->GetDriverGlobals()) FxSelfManagedIoMachine(
|
||||
PkgPnp
|
||||
);
|
||||
|
||||
if (selfManagedIoMachine == NULL) {
|
||||
DoTraceLevelMessage(
|
||||
PkgPnp->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
|
||||
"Self managed I/O state machine allocation failed for "
|
||||
"WDFDEVICE 0x%p",
|
||||
PkgPnp->GetDevice()->GetHandle());
|
||||
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
status = selfManagedIoMachine->m_StateMachineLock.Initialize();
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DoTraceLevelMessage(
|
||||
PkgPnp->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
|
||||
"Self managed I/O state machine lock initialization failed for "
|
||||
"WDFDEVICE 0x%p, %!STATUS!",
|
||||
PkgPnp->GetDevice()->GetHandle(),
|
||||
status);
|
||||
|
||||
delete selfManagedIoMachine;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
*SelfManagedIoMachine = selfManagedIoMachine;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
FxSelfManagedIoMachine::InitializeMachine(
|
||||
__in PWDF_PNPPOWER_EVENT_CALLBACKS Callbacks
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Sets all the function event callbacks.
|
||||
|
||||
Arguments:
|
||||
Callbacks - list of callbacks to set
|
||||
|
||||
Return Value:
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
m_DeviceSelfManagedIoCleanup.m_Method = Callbacks->EvtDeviceSelfManagedIoCleanup;
|
||||
m_DeviceSelfManagedIoFlush.m_Method = Callbacks->EvtDeviceSelfManagedIoFlush;
|
||||
m_DeviceSelfManagedIoInit.m_Method = Callbacks->EvtDeviceSelfManagedIoInit;
|
||||
m_DeviceSelfManagedIoSuspend.m_Method = Callbacks->EvtDeviceSelfManagedIoSuspend;
|
||||
m_DeviceSelfManagedIoRestart.m_Method = Callbacks->EvtDeviceSelfManagedIoRestart;
|
||||
}
|
||||
|
||||
WDFDEVICE
|
||||
FxSelfManagedIoMachine::GetDeviceHandle(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return m_PkgPnp->GetDevice()->GetHandle();
|
||||
}
|
||||
|
||||
_Must_inspect_result_
|
||||
NTSTATUS
|
||||
FxSelfManagedIoMachine::ProcessEvent(
|
||||
__in FxSelfManagedIoEvents Event
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Processes an event and runs it through the state machine. Unlike other
|
||||
state machines in the framework, this one acquires lock in the event
|
||||
processing function rather then relying on the caller to do so.
|
||||
|
||||
Arguments:
|
||||
Event - The event to feed into the state machine.
|
||||
|
||||
Return Value:
|
||||
result of the event
|
||||
|
||||
--*/
|
||||
{
|
||||
const FxSelfManagedIoStateTable* entry;
|
||||
FxSelfManagedIoStates newState;
|
||||
NTSTATUS status;
|
||||
|
||||
m_StateMachineLock.AcquireLock(m_PkgPnp->GetDriverGlobals());
|
||||
|
||||
m_Events.History[m_EventHistoryIndex] = (UCHAR) Event;
|
||||
m_EventHistoryIndex = (m_EventHistoryIndex + 1) %
|
||||
(sizeof(m_Events.History)/sizeof(m_Events.History[0]));
|
||||
|
||||
entry = &m_StateTable[m_CurrentState-FxSelfManagedIoCreated];
|
||||
newState = FxSelfManagedIoMax;
|
||||
|
||||
for (ULONG i = 0; i < entry->TargetStatesCount; i++) {
|
||||
if (entry->TargetStates[i].SelfManagedIoEvent == Event) {
|
||||
DO_EVENT_TRAP(&entry->TargetStates[i]);
|
||||
newState = entry->TargetStates[i].SelfManagedIoState;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (newState == FxSelfManagedIoMax) {
|
||||
//
|
||||
// We always can handle io increment/decrement from any state, but we
|
||||
// should not be dropping any other events from this state.
|
||||
//
|
||||
|
||||
COVERAGE_TRAP();
|
||||
}
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
|
||||
while (newState != FxSelfManagedIoMax) {
|
||||
DoTraceLevelMessage(
|
||||
m_PkgPnp->GetDriverGlobals(), TRACE_LEVEL_INFORMATION, TRACINGPNP,
|
||||
"WDFDEVICE 0x%p !devobj 0x%p entering self managed io state "
|
||||
"%!FxSelfManagedIoStates! from %!FxSelfManagedIoStates!",
|
||||
m_PkgPnp->GetDevice()->GetHandle(),
|
||||
m_PkgPnp->GetDevice()->GetDeviceObject(),
|
||||
newState, m_CurrentState);
|
||||
|
||||
m_States.History[m_StateHistoryIndex] = (UCHAR) newState;
|
||||
m_StateHistoryIndex = (m_StateHistoryIndex + 1) %
|
||||
(sizeof(m_States.History)/sizeof(m_States.History[0]));
|
||||
|
||||
m_CurrentState = (BYTE) newState;
|
||||
entry = &m_StateTable[m_CurrentState-FxSelfManagedIoCreated];
|
||||
|
||||
if (entry->StateFunc != NULL) {
|
||||
newState = entry->StateFunc(this, &status);
|
||||
}
|
||||
else {
|
||||
newState = FxSelfManagedIoMax;
|
||||
}
|
||||
}
|
||||
|
||||
m_StateMachineLock.ReleaseLock(m_PkgPnp->GetDriverGlobals());
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
FxSelfManagedIoStates
|
||||
FxSelfManagedIoMachine::Init(
|
||||
__in FxSelfManagedIoMachine* This,
|
||||
__out PNTSTATUS Status
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Calls the event callback for initializing self managed io.
|
||||
|
||||
Arguments:
|
||||
This - instance of the state machine
|
||||
|
||||
Status - result of the event callback into the driver
|
||||
|
||||
Return Value:
|
||||
new machine state
|
||||
|
||||
--*/
|
||||
{
|
||||
*Status = This->m_DeviceSelfManagedIoInit.Invoke(This->GetDeviceHandle());
|
||||
|
||||
if (NT_SUCCESS(*Status)) {
|
||||
return FxSelfManagedIoStarted;
|
||||
}
|
||||
else {
|
||||
return FxSelfManagedIoInitFailed;
|
||||
}
|
||||
}
|
||||
|
||||
FxSelfManagedIoStates
|
||||
FxSelfManagedIoMachine::Suspending(
|
||||
__in FxSelfManagedIoMachine* This,
|
||||
__out PNTSTATUS Status
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Invokes the self managed io suspend event callback. Upon failure goes to
|
||||
the failed state and awaits teardown of the stack.
|
||||
|
||||
Arguments:
|
||||
This - instance of the state machine
|
||||
|
||||
Status - result of the event callback into the driver
|
||||
|
||||
Return Value:
|
||||
new machine state
|
||||
|
||||
--*/
|
||||
{
|
||||
*Status = This->m_DeviceSelfManagedIoSuspend.Invoke(This->GetDeviceHandle());
|
||||
|
||||
if (NT_SUCCESS(*Status)) {
|
||||
return FxSelfManagedIoStopped;
|
||||
}
|
||||
else {
|
||||
return FxSelfManagedIoFailed;
|
||||
}
|
||||
}
|
||||
|
||||
FxSelfManagedIoStates
|
||||
FxSelfManagedIoMachine::Restarting(
|
||||
__in FxSelfManagedIoMachine* This,
|
||||
__out PNTSTATUS Status
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Invokes the self managed io event callback for restarting self managed io
|
||||
from the stopped state.
|
||||
|
||||
Arguments:
|
||||
This - instance of the state machine
|
||||
|
||||
Status - result of the event callback into the driver
|
||||
|
||||
Return Value:
|
||||
new machine state
|
||||
|
||||
--*/
|
||||
{
|
||||
*Status = This->m_DeviceSelfManagedIoRestart.Invoke(This->GetDeviceHandle());
|
||||
|
||||
if (NT_SUCCESS(*Status)) {
|
||||
return FxSelfManagedIoStarted;
|
||||
}
|
||||
else {
|
||||
return FxSelfManagedIoFailed;
|
||||
}
|
||||
}
|
||||
|
||||
FxSelfManagedIoStates
|
||||
FxSelfManagedIoMachine::Flushing(
|
||||
__in FxSelfManagedIoMachine* This,
|
||||
__out PNTSTATUS Status
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Calls the self managed io flush routine.
|
||||
|
||||
Arguments:
|
||||
This - instance of the state machine
|
||||
|
||||
Status - result of the event callback into the driver
|
||||
|
||||
Return Value:
|
||||
FxSelfManagedIoFlushed
|
||||
|
||||
--*/
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Status);
|
||||
This->m_DeviceSelfManagedIoFlush.Invoke(This->GetDeviceHandle());
|
||||
return FxSelfManagedIoFlushed;
|
||||
}
|
||||
|
||||
FxSelfManagedIoStates
|
||||
FxSelfManagedIoMachine::Cleanup(
|
||||
__in FxSelfManagedIoMachine* This,
|
||||
__out PNTSTATUS Status
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Calls the self managed io cleanup routine.
|
||||
|
||||
Arguments:
|
||||
This - instance of the state machine
|
||||
|
||||
Status - result of the event callback into the driver
|
||||
|
||||
Return Value:
|
||||
FxSelfManagedIoFinal
|
||||
|
||||
--*/
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Status);
|
||||
|
||||
This->m_DeviceSelfManagedIoCleanup.Invoke(This->GetDeviceHandle());
|
||||
return FxSelfManagedIoFinal;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue