1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxDeviceInterfaceUM.cpp 8 9 Abstract: 10 11 This module implements the device interface object. 12 13 Author: 14 15 16 17 Environment: 18 19 User mode only 20 21 Revision History: 22 23 --*/ 24 25 #include "FxSupportPch.hpp" 26 27 extern "C" { 28 #include "FxDeviceInterfaceUM.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 MxMemory::MxFreePool(m_SymbolicLinkName.Buffer); 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 HRESULT hr; 142 NTSTATUS status; 143 IWudfDeviceStack *pDeviceStack; 144 145 146 147 148 // 149 // Get the IWudfDeviceStack interface 150 // 151 pDeviceStack = m_Device->GetDeviceStackInterface(); 152 153 // 154 // Enable the interface 155 // 156 hr = pDeviceStack->SetDeviceInterfaceState(&this->m_InterfaceClassGUID, 157 this->m_ReferenceString.Buffer, 158 State); 159 160 if (SUCCEEDED(hr)) { 161 m_State = State; 162 } 163 else { 164 status = FxDevice::NtStatusFromHr(pDeviceStack, hr); 165 DoTraceLevelMessage( 166 FxDevice::GetFxDevice(m_Device)->GetDriverGlobals(), 167 TRACE_LEVEL_WARNING, TRACINGPNP, 168 "Failed to %s device interface %!STATUS!", 169 (State ? "enable" : "disable"), status); 170 171 172 173 174 175 } 176 } 177 178 _Must_inspect_result_ 179 NTSTATUS 180 FxDeviceInterface::Register( 181 __in MdDeviceObject DeviceObject 182 ) 183 /*++ 184 185 Routine Description: 186 Registers the device interface for a given PDO 187 188 Arguments: 189 DeviceObject - FDO for the device stack in case of UM, and PDO for 190 in case of KM. 191 192 Return Value: 193 returned by IWudfDeviceStack::CreateDeviceInterface 194 195 --*/ 196 { 197 HRESULT hr; 198 NTSTATUS status; 199 IWudfDeviceStack *pDeviceStack; 200 201 m_Device = DeviceObject; 202 203 // 204 // Get the IWudfDeviceStack interface 205 // 206 pDeviceStack = m_Device->GetDeviceStackInterface(); 207 208 hr = pDeviceStack->CreateDeviceInterface(&m_InterfaceClassGUID, 209 m_ReferenceString.Buffer); 210 211 if (SUCCEEDED(hr)) { 212 status = STATUS_SUCCESS; 213 } 214 else { 215 status = FxDevice::NtStatusFromHr(pDeviceStack, hr); 216 } 217 218 return status; 219 } 220 221 _Must_inspect_result_ 222 NTSTATUS 223 FxDeviceInterface::Register( 224 _In_ FxDevice* Device 225 ) 226 { 227 NTSTATUS status; 228 229 // 230 // For UMDF, PDO is already known so no reason to defer registration. 231 // Also, note that Register takes fdo as parameter for UMDF. 232 // 233 status = Register(Device->GetDeviceObject()); 234 235 return status; 236 } 237 238 NTSTATUS 239 FxDeviceInterface::GetSymbolicLinkName( 240 _In_ FxString* LinkString 241 ) 242 { 243 NTSTATUS status; 244 PCWSTR symLink = NULL; 245 246 if (m_SymbolicLinkName.Buffer == NULL) { 247 IWudfDeviceStack *pDeviceStack; 248 IWudfDeviceStack2 *pDeviceStack2; 249 250 // 251 // Get the IWudfDeviceStack interface 252 // 253 pDeviceStack = m_Device->GetDeviceStackInterface(); 254 HRESULT hrQI; 255 HRESULT hr; 256 257 hrQI = pDeviceStack->QueryInterface(IID_IWudfDeviceStack2, 258 (PVOID*)&pDeviceStack2); 259 FX_VERIFY(INTERNAL, CHECK_QI(hrQI, pDeviceStack2)); 260 pDeviceStack->Release(); 261 262 // 263 // Get the symbolic link 264 // 265 hr = pDeviceStack2->GetInterfaceSymbolicLink(&m_InterfaceClassGUID, 266 m_ReferenceString.Buffer, 267 &symLink); 268 if (FAILED(hr)) { 269 status = FxDevice::GetFxDevice(m_Device)->NtStatusFromHr(hr); 270 } 271 else { 272 RtlInitUnicodeString(&m_SymbolicLinkName, symLink); 273 status = STATUS_SUCCESS; 274 } 275 } 276 else { 277 status = STATUS_SUCCESS; 278 } 279 280 if (NT_SUCCESS(status)) { 281 // 282 // Attempt a copy 283 // 284 status = LinkString->Assign(&m_SymbolicLinkName); 285 } 286 287 return status; 288 } 289 290