reactos/sdk/lib/drivers/wdf/shared/targets/general/km/fxiotargetapikm.cpp
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

433 lines
11 KiB
C++

/*++
Copyright (c) Microsoft Corporation
Module Name:
FxIoTargetAPIKm.cpp
Abstract:
This module implements the IO Target APIs
Author:
Environment:
kernel mode only
Revision History:
--*/
#include "..\..\FxTargetsShared.hpp"
extern "C" {
#include "FxIoTargetAPIKm.tmh"
}
//
// Extern the entire file
//
extern "C" {
__drv_maxIRQL(DISPATCH_LEVEL)
PDEVICE_OBJECT
WDFEXPORT(WdfIoTargetWdmGetTargetDeviceObject)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIOTARGET IoTarget
)
/*++
Routine Description:
Returns the PDEVICE_OBJECT. This is the device which PIRPs are sent to.
This is not necessarily the PDEVICE_OBJECT that WDFDEVICE is attached to.
Arguments:
IoTarget - target whose WDM device object is being returned
Return Value:
valid PDEVICE_OBJECT or NULL on failure
--*/
{
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxIoTarget* pTarget;
PDEVICE_OBJECT pDevice;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
IoTarget,
FX_TYPE_IO_TARGET,
(PVOID*) &pTarget,
&pFxDriverGlobals);
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"enter WDFIOTARGET 0x%p", IoTarget);
pDevice = pTarget->GetTargetDevice();
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"exit WDFIOTARGET 0x%p, WDM DevObj 0x%p", IoTarget, pDevice);
return pDevice;
}
__drv_maxIRQL(DISPATCH_LEVEL)
PDEVICE_OBJECT
WDFEXPORT(WdfIoTargetWdmGetTargetPhysicalDevice)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIOTARGET IoTarget
)
/*++
Routine Description:
Returns the PDO for the target itself. This is not necessarily the same
PDO as the WDFDEVICE that owns the target. Not all targets have a PDO since
you can open a legacy non pnp PDEVICE_OBJECT which does not have one.
Arguments:
IoTarget - target whose PDO is being returned
Return Value:
A valid PDEVICE_OBJECT or NULL upon success
--*/
{
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxIoTarget* pTarget;
PDEVICE_OBJECT pPdo;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
IoTarget,
FX_TYPE_IO_TARGET,
(PVOID*) &pTarget,
&pFxDriverGlobals);
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"enter WDFIOTARGET 0x%p", IoTarget);
pPdo = pTarget->GetTargetPDO();
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"exit WDFIOTARGET 0x%p, WDM PDO 0x%p", IoTarget, pPdo);
return pPdo;
}
__drv_maxIRQL(DISPATCH_LEVEL)
PFILE_OBJECT
WDFEXPORT(WdfIoTargetWdmGetTargetFileObject)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIOTARGET IoTarget
)
/*++
Routine Description:
Returns the PFILE_OBJECT associated with the target. Not all targets have
an underlying file object so NULL is a valid and successful return value.
Arguments:
IoTarget - the target whose fileobject is being returned
Return Value:
a valid PFILE_OBJECT or NULL upon success
--*/
{
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxIoTarget* pTarget;
MdFileObject pFile;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
IoTarget,
FX_TYPE_IO_TARGET,
(PVOID*) &pTarget,
&pFxDriverGlobals);
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"enter WDFIOTARGET 0x%p", IoTarget);
pFile = pTarget->GetTargetFileObject();
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"exit WDFIOTARGET 0x%p, WDM FileObj 0x%p", IoTarget, pFile);
return pFile;
}
__drv_maxIRQL(PASSIVE_LEVEL)
_Must_inspect_result_
NTSTATUS
WDFEXPORT(WdfIoTargetQueryForInterface)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIOTARGET IoTarget,
__in
LPCGUID InterfaceType,
__out
PINTERFACE Interface,
__in
USHORT Size,
__in
USHORT Version,
__in_opt
PVOID InterfaceSpecificData
)
/*++
Routine Description:
Sends a query interface pnp request to the top of the target's stack.
Arguments:
IoTarget - the target which is being queried
InterfaceType - interface type specifier
Interface - Interface block which will be filled in by the component which
responds to the query interface
Size - size in bytes of Interface
Version - version of InterfaceType being requested
InterfaceSpecificData - Additional data associated with Interface
Return Value:
NTSTATUS
--*/
{
FxIoTarget* pTarget;
PFX_DRIVER_GLOBALS pFxDriverGlobals;
PDEVICE_OBJECT pTopOfStack;
NTSTATUS status;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
IoTarget,
FX_TYPE_IO_TARGET,
(PVOID*) &pTarget,
&pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, InterfaceType);
FxPointerNotNull(pFxDriverGlobals, Interface);
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
if (!NT_SUCCESS(status)) {
return status;
}
pTopOfStack = IoGetAttachedDeviceReference(pTarget->GetTargetDevice());
ASSERT(pTopOfStack != NULL);
status = FxQueryInterface::_QueryForInterface(pTopOfStack,
InterfaceType,
Interface,
Size,
Version,
InterfaceSpecificData);
ObDereferenceObject(pTopOfStack);
return status;
}
_Must_inspect_result_
__drv_maxIRQL(PASSIVE_LEVEL)
NTSTATUS
WDFEXPORT(WdfIoTargetQueryTargetProperty)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIOTARGET IoTarget,
__in
DEVICE_REGISTRY_PROPERTY DeviceProperty,
__in
ULONG BufferLength,
__drv_when(BufferLength != 0, __out_bcount_part_opt(BufferLength, *ResultLength))
__drv_when(BufferLength == 0, __out_opt)
PVOID PropertyBuffer,
__deref_out_range(<=,BufferLength)
PULONG ResultLength
)
/*++
Routine Description:
Retrieves the requested device property for the given target
Arguments:
IoTarget - the target whose PDO whose will be queried
DeviceProperty - the property being queried
BufferLength - length of PropertyBuffer in bytes
PropertyBuffer - Buffer which will receive the property being queried
ResultLength - if STATUS_BUFFER_TOO_SMALL is returned, then this will contain
the required length
Return Value:
NTSTATUS
--*/
{
DDI_ENTRY();
PFX_DRIVER_GLOBALS pGlobals;
NTSTATUS status;
FxIoTarget* pTarget;
MdDeviceObject pPdo;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
IoTarget,
FX_TYPE_IO_TARGET,
(PVOID*) &pTarget,
&pGlobals);
FxPointerNotNull(pGlobals, ResultLength);
if (BufferLength > 0) {
FxPointerNotNull(pGlobals, PropertyBuffer);
}
status = FxVerifierCheckIrqlLevel(pGlobals, PASSIVE_LEVEL);
if (!NT_SUCCESS(status)) {
return status;
}
pPdo = pTarget->GetTargetPDO();
if (pPdo == NULL) {
status = STATUS_INVALID_DEVICE_REQUEST;
DoTraceLevelMessage(pGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
"WDFIOTARGET 0x%p has no PDO (not opened yet?), %!STATUS!",
IoTarget, status);
return status;
}
status = FxDevice::_GetDeviceProperty(pPdo,
DeviceProperty,
BufferLength,
PropertyBuffer,
ResultLength);
DoTraceLevelMessage(pGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"exit WDFIOTARGET 0x%p, Property %d, %!STATUS!",
IoTarget, DeviceProperty, status);
return status;
}
_Must_inspect_result_
__drv_maxIRQL(PASSIVE_LEVEL)
WDFAPI
NTSTATUS
WDFEXPORT(WdfIoTargetAllocAndQueryTargetProperty)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIOTARGET IoTarget,
__in
DEVICE_REGISTRY_PROPERTY DeviceProperty,
__in
__drv_strictTypeMatch(1)
POOL_TYPE PoolType,
__in_opt
PWDF_OBJECT_ATTRIBUTES PropertyMemoryAttributes,
__out
WDFMEMORY* PropertyMemory
)
/*++
Routine Description:
Allocates and retrieves the requested device property for the given target
Arguments:
IoTarget - the target whose PDO whose will be queried
DeviceProperty - the property being queried
PoolType - what type of pool to allocate
PropertyMemoryAttributes - attributes to associate with PropertyMemory
PropertyMemory - handle which will receive the property buffer
Return Value:
NTSTATUS
--*/
{
DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals;
NTSTATUS status;
FxIoTarget* pTarget;
MdDeviceObject pPdo;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
IoTarget,
FX_TYPE_IO_TARGET,
(PVOID*) &pTarget,
&pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, PropertyMemory);
*PropertyMemory = NULL;
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
if (!NT_SUCCESS(status)) {
return status;
}
FxVerifierCheckNxPoolType(pFxDriverGlobals, PoolType, pFxDriverGlobals->Tag);
status = FxValidateObjectAttributes(pFxDriverGlobals, PropertyMemoryAttributes);
if (!NT_SUCCESS(status)) {
return status;
}
pPdo = pTarget->GetTargetPDO();
if (pPdo == NULL) {
status = STATUS_INVALID_DEVICE_REQUEST;
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
"WDFIOTARGET %p has no PDO (not opened yet?), %!STATUS!",
IoTarget, status);
return status;
}
//
// Worker function which does the 2 passes. First pass to query the size,
// the second pass w/the correctly sized buffer.
//
status = FxDevice::_AllocAndQueryProperty(pFxDriverGlobals,
NULL,
NULL,
pPdo,
DeviceProperty,
PoolType,
PropertyMemoryAttributes,
PropertyMemory);
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"exit WDFIOTARGET 0x%p, Property %d, %!STATUS!",
IoTarget, DeviceProperty, status);
return status;
}
}