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

439 lines
12 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
STDCALL
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
STDCALL
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
STDCALL
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
STDCALL
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
STDCALL
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
STDCALL
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;
}
}