reactos/sdk/lib/drivers/wdf/shared/support/um/fxdeviceinterfaceum.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

289 lines
5.8 KiB
C++

/*++
Copyright (c) Microsoft Corporation
Module Name:
FxDeviceInterfaceUM.cpp
Abstract:
This module implements the device interface object.
Author:
Environment:
User mode only
Revision History:
--*/
#include "FxSupportPch.hpp"
extern "C" {
#include "FxDeviceInterfaceUM.tmh"
}
FxDeviceInterface::FxDeviceInterface(
)
/*++
Routine Description:
Constructor for the object. Initializes all fields
Arguments:
None
Return Value:
None
--*/
{
RtlZeroMemory(&m_InterfaceClassGUID, sizeof(m_InterfaceClassGUID));
RtlZeroMemory(&m_SymbolicLinkName, sizeof(m_SymbolicLinkName));
RtlZeroMemory(&m_ReferenceString, sizeof(m_ReferenceString));
m_Entry.Next = NULL;
m_State = FALSE;
}
FxDeviceInterface::~FxDeviceInterface()
/*++
Routine Description:
Destructor for FxDeviceInterface. Cleans up any allocations previously
allocated.
Arguments:
None
Return Value:
None
--*/
{
// the device interface should be off now
ASSERT(m_State == FALSE);
// should no longer be in any list
ASSERT(m_Entry.Next == NULL);
if (m_ReferenceString.Buffer != NULL) {
FxPoolFree(m_ReferenceString.Buffer);
RtlZeroMemory(&m_ReferenceString, sizeof(m_ReferenceString));
}
if (m_SymbolicLinkName.Buffer != NULL) {
MxMemory::MxFreePool(m_SymbolicLinkName.Buffer);
}
}
_Must_inspect_result_
NTSTATUS
FxDeviceInterface::Initialize(
__in PFX_DRIVER_GLOBALS FxDriverGlobals,
__in CONST GUID* InterfaceGUID,
__in_opt PCUNICODE_STRING ReferenceString
)
/*++
Routine Description:
Initializes the object with the interface GUID and optional reference string
Arguments:
InterfaceGUID - GUID describing the interface
ReferenceString - string used to differentiate between 2 interfaces on the
same PDO
Return Value:
STATUS_SUCCESS or STATUS_INSUFFICIENT_RESOURCES
--*/
{
RtlCopyMemory(&m_InterfaceClassGUID, InterfaceGUID, sizeof(GUID));
if (ReferenceString != NULL) {
return FxDuplicateUnicodeString(FxDriverGlobals,
ReferenceString,
&m_ReferenceString);
}
else {
return STATUS_SUCCESS;
}
}
VOID
FxDeviceInterface::SetState(
__in BOOLEAN State
)
/*++
Routine Description:
Sets the state of the device interface
Arguments:
State - the state to set
Return Value:
None.
--*/
{
HRESULT hr;
NTSTATUS status;
IWudfDeviceStack *pDeviceStack;
//
// Get the IWudfDeviceStack interface
//
pDeviceStack = m_Device->GetDeviceStackInterface();
//
// Enable the interface
//
hr = pDeviceStack->SetDeviceInterfaceState(&this->m_InterfaceClassGUID,
this->m_ReferenceString.Buffer,
State);
if (SUCCEEDED(hr)) {
m_State = State;
}
else {
status = FxDevice::NtStatusFromHr(pDeviceStack, hr);
DoTraceLevelMessage(
FxDevice::GetFxDevice(m_Device)->GetDriverGlobals(),
TRACE_LEVEL_WARNING, TRACINGPNP,
"Failed to %s device interface %!STATUS!",
(State ? "enable" : "disable"), status);
}
}
_Must_inspect_result_
NTSTATUS
FxDeviceInterface::Register(
__in MdDeviceObject DeviceObject
)
/*++
Routine Description:
Registers the device interface for a given PDO
Arguments:
DeviceObject - FDO for the device stack in case of UM, and PDO for
in case of KM.
Return Value:
returned by IWudfDeviceStack::CreateDeviceInterface
--*/
{
HRESULT hr;
NTSTATUS status;
IWudfDeviceStack *pDeviceStack;
m_Device = DeviceObject;
//
// Get the IWudfDeviceStack interface
//
pDeviceStack = m_Device->GetDeviceStackInterface();
hr = pDeviceStack->CreateDeviceInterface(&m_InterfaceClassGUID,
m_ReferenceString.Buffer);
if (SUCCEEDED(hr)) {
status = STATUS_SUCCESS;
}
else {
status = FxDevice::NtStatusFromHr(pDeviceStack, hr);
}
return status;
}
_Must_inspect_result_
NTSTATUS
FxDeviceInterface::Register(
_In_ FxDevice* Device
)
{
NTSTATUS status;
//
// For UMDF, PDO is already known so no reason to defer registration.
// Also, note that Register takes fdo as parameter for UMDF.
//
status = Register(Device->GetDeviceObject());
return status;
}
NTSTATUS
FxDeviceInterface::GetSymbolicLinkName(
_In_ FxString* LinkString
)
{
NTSTATUS status;
PCWSTR symLink = NULL;
if (m_SymbolicLinkName.Buffer == NULL) {
IWudfDeviceStack *pDeviceStack;
IWudfDeviceStack2 *pDeviceStack2;
//
// Get the IWudfDeviceStack interface
//
pDeviceStack = m_Device->GetDeviceStackInterface();
HRESULT hrQI;
HRESULT hr;
hrQI = pDeviceStack->QueryInterface(IID_IWudfDeviceStack2,
(PVOID*)&pDeviceStack2);
FX_VERIFY(INTERNAL, CHECK_QI(hrQI, pDeviceStack2));
pDeviceStack->Release();
//
// Get the symbolic link
//
hr = pDeviceStack2->GetInterfaceSymbolicLink(&m_InterfaceClassGUID,
m_ReferenceString.Buffer,
&symLink);
if (FAILED(hr)) {
status = FxDevice::GetFxDevice(m_Device)->NtStatusFromHr(hr);
}
else {
RtlInitUnicodeString(&m_SymbolicLinkName, symLink);
status = STATUS_SUCCESS;
}
}
else {
status = STATUS_SUCCESS;
}
if (NT_SUCCESS(status)) {
//
// Attempt a copy
//
status = LinkString->Assign(&m_SymbolicLinkName);
}
return status;
}