1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxDeviceInterfaceKM.cpp 8 9 Abstract: 10 11 This module implements the device interface object. 12 13 Author: 14 15 16 17 Environment: 18 19 Kernel mode only 20 21 Revision History: 22 23 --*/ 24 25 #include "fxsupportpch.hpp" 26 27 extern "C" { 28 // #include "FxDeviceInterfaceKM.tmh" 29 } 30 31 FxDeviceInterface::FxDeviceInterface( 32 ) 33 /*++ 34 35 Routine Description: 36 Constructor for the object. Initializes all fields 37 38 Arguments: 39 None 40 41 Return Value: 42 None 43 44 --*/ 45 { 46 RtlZeroMemory(&m_InterfaceClassGUID, sizeof(m_InterfaceClassGUID)); 47 48 RtlZeroMemory(&m_SymbolicLinkName, sizeof(m_SymbolicLinkName)); 49 RtlZeroMemory(&m_ReferenceString, sizeof(m_ReferenceString)); 50 51 m_Entry.Next = NULL; 52 53 m_State = FALSE; 54 } 55 56 FxDeviceInterface::~FxDeviceInterface() 57 /*++ 58 59 Routine Description: 60 Destructor for FxDeviceInterface. Cleans up any allocations previously 61 allocated. 62 63 Arguments: 64 None 65 66 Return Value: 67 None 68 69 --*/ 70 { 71 // the device interface should be off now 72 ASSERT(m_State == FALSE); 73 74 // should no longer be in any list 75 ASSERT(m_Entry.Next == NULL); 76 77 if (m_ReferenceString.Buffer != NULL) { 78 FxPoolFree(m_ReferenceString.Buffer); 79 RtlZeroMemory(&m_ReferenceString, sizeof(m_ReferenceString)); 80 } 81 82 if (m_SymbolicLinkName.Buffer != NULL) { 83 RtlFreeUnicodeString(&m_SymbolicLinkName); 84 } 85 } 86 87 _Must_inspect_result_ 88 NTSTATUS 89 FxDeviceInterface::Initialize( 90 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 91 __in CONST GUID* InterfaceGUID, 92 __in_opt PCUNICODE_STRING ReferenceString 93 ) 94 /*++ 95 96 Routine Description: 97 Initializes the object with the interface GUID and optional reference string 98 99 Arguments: 100 InterfaceGUID - GUID describing the interface 101 102 ReferenceString - string used to differentiate between 2 interfaces on the 103 same PDO 104 105 Return Value: 106 STATUS_SUCCESS or STATUS_INSUFFICIENT_RESOURCES 107 108 --*/ 109 { 110 RtlCopyMemory(&m_InterfaceClassGUID, InterfaceGUID, sizeof(GUID)); 111 112 if (ReferenceString != NULL) { 113 return FxDuplicateUnicodeString(FxDriverGlobals, 114 ReferenceString, 115 &m_ReferenceString); 116 } 117 else { 118 return STATUS_SUCCESS; 119 } 120 } 121 122 123 VOID 124 FxDeviceInterface::SetState( 125 __in BOOLEAN State 126 ) 127 /*++ 128 129 Routine Description: 130 Sets the state of the device interface 131 132 Arguments: 133 State - the state to set 134 135 136 Return Value: 137 None. 138 139 --*/ 140 { 141 m_State = State; 142 143 // 144 // Only set the state if the interface has been registered 145 // 146 if (m_SymbolicLinkName.Buffer != NULL) { 147 Mx::MxSetDeviceInterfaceState(&m_SymbolicLinkName, m_State); 148 } 149 } 150 151 _Must_inspect_result_ 152 NTSTATUS 153 FxDeviceInterface::Register( 154 __in PDEVICE_OBJECT Pdo 155 ) 156 /*++ 157 158 Routine Description: 159 Registers the device interface for a given PDO 160 161 Arguments: 162 Pdo - PDO for the device stack 163 164 165 Return Value: 166 returned by IoRegisterDeviceInterface 167 168 --*/ 169 { 170 PUNICODE_STRING pString; 171 172 if (m_ReferenceString.Length > 0) { 173 pString = &m_ReferenceString; 174 } 175 else { 176 pString = NULL; 177 } 178 179 return Mx::MxRegisterDeviceInterface( 180 Pdo, &m_InterfaceClassGUID, pString, &m_SymbolicLinkName); 181 } 182 183 _Must_inspect_result_ 184 NTSTATUS 185 FxDeviceInterface::Register( 186 _In_ FxDevice* Device 187 ) 188 { 189 NTSTATUS status; 190 MdDeviceObject pdo; 191 192 pdo = Device->GetSafePhysicalDevice(); 193 194 if (pdo != NULL) { 195 status = Register(pdo); 196 } 197 else { 198 // 199 // Leave the device interface unregistered. When we are in hardware 200 // available, we will register there once we know for sure we have a 201 // real live PDO that the system has acknowledged. 202 // 203 DO_NOTHING(); 204 205 status = STATUS_SUCCESS; 206 } 207 208 return status; 209 } 210 211 NTSTATUS 212 FxDeviceInterface::GetSymbolicLinkName( 213 _In_ FxString* LinkString 214 ) 215 { 216 NTSTATUS status; 217 218 if (m_SymbolicLinkName.Buffer == NULL) { 219 // 220 // The device interface has not yet been registered b/c it 221 // belongs to a PDO and the PDO has not been recognized by 222 // pnp yet. 223 // 224 status = STATUS_INVALID_DEVICE_STATE; 225 UNREFERENCED_PARAMETER(LinkString); 226 } 227 else { 228 // 229 // Attempt a copy 230 // 231 status = LinkString->Assign(&m_SymbolicLinkName); 232 } 233 234 return status; 235 } 236 237