reactos/sdk/lib/drivers/wdf/shared/inc/private/common/fxpkgio.hpp
Victor Perevertkin 1f377076d7
[WDF] Fix KMDF so it can compile with ReactOS SDK
Not all files are included, but these are necessary to compile cdrom driver.
So far it can only be statically linked with drivers, a proper
implementation requires wdfldr helper driver
2020-11-03 00:06:27 +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