mirror of
https://github.com/reactos/reactos.git
synced 2024-11-09 16:20:37 +00:00
1f377076d7
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
439 lines
12 KiB
C++
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;
|
|
}
|
|
|
|
}
|