reactos/sdk/lib/drivers/wdf/shared/inc/private/common/fxpkgio.hpp
Victor Perevertkin 8a978a179f
[WDF] Add Windows Driver Framework files
Takern from Microsoft GitHub repo:
d9c6040fe9

Licensed under MIT
2020-11-03 00:06:26 +03:00

446 lines
9.5 KiB
C++

/*++
Copyright (c) Microsoft Corporation
Module Name:
FxPkgIo.hpp
Abstract:
This module implements the I/O package for the driver frameworks.
Author:
Environment:
Both kernel and user mode
Revision History:
--*/
#ifndef _FXPKGIO_H_
#define _FXPKGIO_H_
#include "FxPkgIoShared.hpp"
#include "FxIrpDynamicDispatchInfo.hpp"
#include "FxDeviceCallbacks.hpp"
#include "FxCxDeviceInfo.hpp"
//
// This flag is or-ed with a pointer value that is ptr aligned, only lower 2 bits are available.
//
#define FX_IN_DISPATCH_CALLBACK 0x00000001
enum FxIoIteratorList {
FxIoQueueIteratorListInvalid = 0,
FxIoQueueIteratorListPowerOn,
FxIoQueueIteratorListPowerOff,
};
#define IO_ITERATOR_FLUSH_TAG (PVOID) 'sulf'
#define IO_ITERATOR_POWER_TAG (PVOID) 'ewop'
//
// This class is allocated by the driver frameworks manager
// PER DEVICE, and is not package global, but per device global,
// data.
//
// This is similar to the NT DeviceExtension.
//
class FxPkgIo : public FxPackage
{
private:
FxIoQueue* m_DefaultQueue;
//
// This is the list of IoQueue objects allocated by the driver
// and associated with this device. The IoPackage instance
// will release these references automatically when the device
// is removed.
//
LIST_ENTRY m_IoQueueListHead;
//
// This is the forwarding table
//
FxIoQueue* m_DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1];
//
// This is the seed value used to pass to the
// FxRandom for testing forward progress
//
ULONG m_RandomSeed;
// TRUE if behave as a filter (forward default requests)
BOOLEAN m_Filter;
BOOLEAN m_PowerStateOn;
//
// TRUE if queues are shutting down (surprise_remove/remove in progress).
//
BOOLEAN m_QueuesAreShuttingDown;
//
// We'll maintain the dynamic dispatch table "per device" so that it is possible
// to have different callbacks for each device.
// Note that each device may be associted with multiple class extension in the future.
//
LIST_ENTRY m_DynamicDispatchInfoListHead;
//
// If !=NULL, a pre-process callback was registered
//
FxIoInCallerContext m_InCallerContextCallback;
public:
FxPkgIo(
__in PFX_DRIVER_GLOBALS FxDriverGlobals,
__in CfxDevice *Device
);
~FxPkgIo();
//
// Package manager dispatch entries
//
_Must_inspect_result_
virtual
NTSTATUS
Dispatch(
__inout MdIrp Irp
);
//
// Returns the Top level queue for the Io based on the Irp MajorFunction
//
FxIoQueue*
GetDispatchQueue(
_In_ UCHAR MajorFunction
)
{
return m_DispatchTable[MajorFunction];
}
// Do not specify argument names
FX_DECLARE_VF_FUNCTION_P1(
NTSTATUS,
VerifyDispatchContext,
_In_ WDFCONTEXT
);
//
// Api's supplied by this package
//
_Must_inspect_result_
NTSTATUS
__fastcall
DispatchStep1(
__inout MdIrp Irp,
__in WDFCONTEXT DispatchContext
);
_Must_inspect_result_
NTSTATUS
__fastcall
DispatchStep2(
__inout MdIrp Irp,
__in_opt FxIoInCallerContext* IoInCallerCtx,
__in_opt FxIoQueue* Queue
);
/*++
Routine Description:
Initializes the default queue, and allows the driver to
pass configuration information.
The driver callbacks registered in this call are used
to supply the callbacks for the driver default I/O queue.
Arguments:
hDevice - Pointer Device Object
Return Value:
NTSTATUS
--*/
_Must_inspect_result_
NTSTATUS
InitializeDefaultQueue(
__in CfxDevice * Device,
__inout FxIoQueue * Queue
);
//
// Register the I/O in-caller context callback
//
__inline
VOID
SetIoInCallerContextCallback(
__inout PFN_WDF_IO_IN_CALLER_CONTEXT EvtIoInCallerContext
)
{
m_InCallerContextCallback.m_Method = EvtIoInCallerContext;
}
// Do not specify argument names
FX_DECLARE_VF_FUNCTION_P2(
NTSTATUS,
VerifyEnqueueRequestUpdateFlags,
_In_ FxRequest*,
_Inout_ SHORT*
);
// Do not specify argument names
FX_DECLARE_VF_FUNCTION_P2(
VOID,
VerifyEnqueueRequestRestoreFlags,
_In_ FxRequest*,
_In_ SHORT
);
//
// Enqueue a request to the I/O processing pipeline
// from the device driver
//
_Must_inspect_result_
NTSTATUS
EnqueueRequest(
__in CfxDevice* Device,
__inout FxRequest* pRequest
);
FxDriver*
GetDriver(
VOID
);
__inline
CfxDevice*
GetDevice(
VOID
)
{
return m_Device;
}
__inline
FxIoQueue*
GetDefaultQueue(
VOID
)
{
return m_DefaultQueue;
}
__inline
BOOLEAN
IsFilter(
VOID
)
{
return m_Filter;
}
//
// This is called as a result of a power management state
// that requests that all I/O in progress stop.
//
//
// FxIoStopProcessingForPowerHold:
// the function returns when the driver has acknowledged that it has
// stopped all I/O processing, but may have outstanding "in-flight" requests
// that have not been completed.
//
// FxIoStopProcessingForPowerPurge:
// the function returns when all requests have been completed and/or
// cancelled., and there are no more in-flight requests.
//
// Any queues not marked as PowerManaged will be left alone.
//
// This is called on a PASSIVE_LEVEL thread that can block until
// I/O has been stopped, or completed/cancelled.
//
_Must_inspect_result_
NTSTATUS
StopProcessingForPower(
__in FxIoStopProcessingForPowerAction Action
);
//
// This is called to start, or resume processing when PNP/Power
// resources have been supplied to the device driver.
//
// The driver is notified of resumption for any in-flight I/O.
//
_Must_inspect_result_
NTSTATUS
ResumeProcessingForPower();
//
// This is called on a device which has been restarted from the removed
// state. It will reset purged queues so that they can accept new requests
// when ResumeProcessingForPower is called afterwards.
//
VOID
ResetStateForRestart(
VOID
);
//
// Called by CfxDevice when WdfDeviceSetFilter is called.
//
_Must_inspect_result_
NTSTATUS
SetFilter(
__in BOOLEAN Value
);
//
// Create an IoQueue and associate it with the FxIoPkg per device
// instance.
//
_Must_inspect_result_
NTSTATUS
CreateQueue(
__in PWDF_IO_QUEUE_CONFIG Config,
__in PWDF_OBJECT_ATTRIBUTES QueueAttributes,
__in_opt FxDriver* Caller,
__deref_out FxIoQueue** ppQueue
);
VOID
RemoveQueueReferences(
__inout FxIoQueue* pQueue
);
_Must_inspect_result_
NTSTATUS
ConfigureDynamicDispatching(
__in UCHAR MajorFunction,
__in_opt FxCxDeviceInfo* CxDeviceInfo,
__in PFN_WDFDEVICE_WDM_IRP_DISPATCH EvtDeviceWdmIrpDispatch,
__in_opt WDFCONTEXT DriverContext
);
_Must_inspect_result_
NTSTATUS
ConfigureForwarding(
__inout FxIoQueue* TargetQueue,
__in WDF_REQUEST_TYPE RequestType
);
_Must_inspect_result_
NTSTATUS
FlushAllQueuesByFileObject(
__in MdFileObject FileObject
);
__inline
VOID
RequestCompletedCallback(
__in FxRequest* Request
)
{
UNREFERENCED_PARAMETER(Request);
//
// If this is called, the driver called WDFREQUEST.Complete
// from the PreProcess callback handler.
//
// Since we have a handler, the FXREQUEST object will
// dereference itself upon return from this callback, which
// will destroy the final reference count.
//
}
__inline
BOOLEAN
IsTopLevelQueue(
__in FxIoQueue* Queue
)
{
UCHAR index;
for (index = 0; index <= IRP_MJ_MAXIMUM_FUNCTION; index++) {
if (m_DispatchTable[index] == Queue) {
return TRUE;
}
}
return FALSE;
}
NTSTATUS
DispathToInCallerContextCallback(
__in FxIoInCallerContext *InCallerContextInfo,
__in FxRequest *Request,
__inout MdIrp Irp
);
__inline
FxIoInCallerContext*
GetIoInCallerContextCallback(
__in_opt FxCxDeviceInfo* CxDeviceInfo
)
{
if (CxDeviceInfo != NULL) {
return &CxDeviceInfo->IoInCallerContextCallback;
}
else {
return &m_InCallerContextCallback;
}
}
private:
VOID
AddIoQueue(
__inout FxIoQueue* IoQueue
);
VOID
RemoveIoQueue(
__inout FxIoQueue* IoQueue
);
FxIoQueue*
GetFirstIoQueueLocked(
__in FxIoQueueNode* QueueBookmark,
__in PVOID Tag
);
FxIoQueue*
GetNextIoQueueLocked(
__in FxIoQueueNode* QueueBookmark,
__in PVOID Tag
);
VOID
GetIoQueueListLocked(
__in PSINGLE_LIST_ENTRY SListHead,
__inout FxIoIteratorList ListType
);
_Must_inspect_result_
NTSTATUS
VerifierFreeRequestToTestForwardProgess(
__in FxRequest* Request
);
};
#endif // _FXPKGIO_H