mirror of
https://github.com/reactos/reactos.git
synced 2025-05-19 00:54:18 +00:00
290 lines
5.8 KiB
C++
290 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;
|
||
|
}
|
||
|
|