1*8a978a17SVictor Perevertkin /*++
2*8a978a17SVictor Perevertkin
3*8a978a17SVictor Perevertkin Copyright (c) Microsoft Corporation
4*8a978a17SVictor Perevertkin
5*8a978a17SVictor Perevertkin Module Name:
6*8a978a17SVictor Perevertkin
7*8a978a17SVictor Perevertkin FxDeviceInterfaceUM.cpp
8*8a978a17SVictor Perevertkin
9*8a978a17SVictor Perevertkin Abstract:
10*8a978a17SVictor Perevertkin
11*8a978a17SVictor Perevertkin This module implements the device interface object.
12*8a978a17SVictor Perevertkin
13*8a978a17SVictor Perevertkin Author:
14*8a978a17SVictor Perevertkin
15*8a978a17SVictor Perevertkin
16*8a978a17SVictor Perevertkin
17*8a978a17SVictor Perevertkin Environment:
18*8a978a17SVictor Perevertkin
19*8a978a17SVictor Perevertkin User mode only
20*8a978a17SVictor Perevertkin
21*8a978a17SVictor Perevertkin Revision History:
22*8a978a17SVictor Perevertkin
23*8a978a17SVictor Perevertkin --*/
24*8a978a17SVictor Perevertkin
25*8a978a17SVictor Perevertkin #include "FxSupportPch.hpp"
26*8a978a17SVictor Perevertkin
27*8a978a17SVictor Perevertkin extern "C" {
28*8a978a17SVictor Perevertkin #include "FxDeviceInterfaceUM.tmh"
29*8a978a17SVictor Perevertkin }
30*8a978a17SVictor Perevertkin
FxDeviceInterface()31*8a978a17SVictor Perevertkin FxDeviceInterface::FxDeviceInterface(
32*8a978a17SVictor Perevertkin )
33*8a978a17SVictor Perevertkin /*++
34*8a978a17SVictor Perevertkin
35*8a978a17SVictor Perevertkin Routine Description:
36*8a978a17SVictor Perevertkin Constructor for the object. Initializes all fields
37*8a978a17SVictor Perevertkin
38*8a978a17SVictor Perevertkin Arguments:
39*8a978a17SVictor Perevertkin None
40*8a978a17SVictor Perevertkin
41*8a978a17SVictor Perevertkin Return Value:
42*8a978a17SVictor Perevertkin None
43*8a978a17SVictor Perevertkin
44*8a978a17SVictor Perevertkin --*/
45*8a978a17SVictor Perevertkin {
46*8a978a17SVictor Perevertkin RtlZeroMemory(&m_InterfaceClassGUID, sizeof(m_InterfaceClassGUID));
47*8a978a17SVictor Perevertkin
48*8a978a17SVictor Perevertkin RtlZeroMemory(&m_SymbolicLinkName, sizeof(m_SymbolicLinkName));
49*8a978a17SVictor Perevertkin RtlZeroMemory(&m_ReferenceString, sizeof(m_ReferenceString));
50*8a978a17SVictor Perevertkin
51*8a978a17SVictor Perevertkin m_Entry.Next = NULL;
52*8a978a17SVictor Perevertkin
53*8a978a17SVictor Perevertkin m_State = FALSE;
54*8a978a17SVictor Perevertkin }
55*8a978a17SVictor Perevertkin
~FxDeviceInterface()56*8a978a17SVictor Perevertkin FxDeviceInterface::~FxDeviceInterface()
57*8a978a17SVictor Perevertkin /*++
58*8a978a17SVictor Perevertkin
59*8a978a17SVictor Perevertkin Routine Description:
60*8a978a17SVictor Perevertkin Destructor for FxDeviceInterface. Cleans up any allocations previously
61*8a978a17SVictor Perevertkin allocated.
62*8a978a17SVictor Perevertkin
63*8a978a17SVictor Perevertkin Arguments:
64*8a978a17SVictor Perevertkin None
65*8a978a17SVictor Perevertkin
66*8a978a17SVictor Perevertkin Return Value:
67*8a978a17SVictor Perevertkin None
68*8a978a17SVictor Perevertkin
69*8a978a17SVictor Perevertkin --*/
70*8a978a17SVictor Perevertkin {
71*8a978a17SVictor Perevertkin // the device interface should be off now
72*8a978a17SVictor Perevertkin ASSERT(m_State == FALSE);
73*8a978a17SVictor Perevertkin
74*8a978a17SVictor Perevertkin // should no longer be in any list
75*8a978a17SVictor Perevertkin ASSERT(m_Entry.Next == NULL);
76*8a978a17SVictor Perevertkin
77*8a978a17SVictor Perevertkin if (m_ReferenceString.Buffer != NULL) {
78*8a978a17SVictor Perevertkin FxPoolFree(m_ReferenceString.Buffer);
79*8a978a17SVictor Perevertkin RtlZeroMemory(&m_ReferenceString, sizeof(m_ReferenceString));
80*8a978a17SVictor Perevertkin }
81*8a978a17SVictor Perevertkin
82*8a978a17SVictor Perevertkin if (m_SymbolicLinkName.Buffer != NULL) {
83*8a978a17SVictor Perevertkin MxMemory::MxFreePool(m_SymbolicLinkName.Buffer);
84*8a978a17SVictor Perevertkin }
85*8a978a17SVictor Perevertkin }
86*8a978a17SVictor Perevertkin
87*8a978a17SVictor Perevertkin _Must_inspect_result_
88*8a978a17SVictor Perevertkin NTSTATUS
Initialize(__in PFX_DRIVER_GLOBALS FxDriverGlobals,__in CONST GUID * InterfaceGUID,__in_opt PCUNICODE_STRING ReferenceString)89*8a978a17SVictor Perevertkin FxDeviceInterface::Initialize(
90*8a978a17SVictor Perevertkin __in PFX_DRIVER_GLOBALS FxDriverGlobals,
91*8a978a17SVictor Perevertkin __in CONST GUID* InterfaceGUID,
92*8a978a17SVictor Perevertkin __in_opt PCUNICODE_STRING ReferenceString
93*8a978a17SVictor Perevertkin )
94*8a978a17SVictor Perevertkin /*++
95*8a978a17SVictor Perevertkin
96*8a978a17SVictor Perevertkin Routine Description:
97*8a978a17SVictor Perevertkin Initializes the object with the interface GUID and optional reference string
98*8a978a17SVictor Perevertkin
99*8a978a17SVictor Perevertkin Arguments:
100*8a978a17SVictor Perevertkin InterfaceGUID - GUID describing the interface
101*8a978a17SVictor Perevertkin
102*8a978a17SVictor Perevertkin ReferenceString - string used to differentiate between 2 interfaces on the
103*8a978a17SVictor Perevertkin same PDO
104*8a978a17SVictor Perevertkin
105*8a978a17SVictor Perevertkin Return Value:
106*8a978a17SVictor Perevertkin STATUS_SUCCESS or STATUS_INSUFFICIENT_RESOURCES
107*8a978a17SVictor Perevertkin
108*8a978a17SVictor Perevertkin --*/
109*8a978a17SVictor Perevertkin {
110*8a978a17SVictor Perevertkin RtlCopyMemory(&m_InterfaceClassGUID, InterfaceGUID, sizeof(GUID));
111*8a978a17SVictor Perevertkin
112*8a978a17SVictor Perevertkin if (ReferenceString != NULL) {
113*8a978a17SVictor Perevertkin return FxDuplicateUnicodeString(FxDriverGlobals,
114*8a978a17SVictor Perevertkin ReferenceString,
115*8a978a17SVictor Perevertkin &m_ReferenceString);
116*8a978a17SVictor Perevertkin }
117*8a978a17SVictor Perevertkin else {
118*8a978a17SVictor Perevertkin return STATUS_SUCCESS;
119*8a978a17SVictor Perevertkin }
120*8a978a17SVictor Perevertkin }
121*8a978a17SVictor Perevertkin
122*8a978a17SVictor Perevertkin
123*8a978a17SVictor Perevertkin VOID
SetState(__in BOOLEAN State)124*8a978a17SVictor Perevertkin FxDeviceInterface::SetState(
125*8a978a17SVictor Perevertkin __in BOOLEAN State
126*8a978a17SVictor Perevertkin )
127*8a978a17SVictor Perevertkin /*++
128*8a978a17SVictor Perevertkin
129*8a978a17SVictor Perevertkin Routine Description:
130*8a978a17SVictor Perevertkin Sets the state of the device interface
131*8a978a17SVictor Perevertkin
132*8a978a17SVictor Perevertkin Arguments:
133*8a978a17SVictor Perevertkin State - the state to set
134*8a978a17SVictor Perevertkin
135*8a978a17SVictor Perevertkin
136*8a978a17SVictor Perevertkin Return Value:
137*8a978a17SVictor Perevertkin None.
138*8a978a17SVictor Perevertkin
139*8a978a17SVictor Perevertkin --*/
140*8a978a17SVictor Perevertkin {
141*8a978a17SVictor Perevertkin HRESULT hr;
142*8a978a17SVictor Perevertkin NTSTATUS status;
143*8a978a17SVictor Perevertkin IWudfDeviceStack *pDeviceStack;
144*8a978a17SVictor Perevertkin
145*8a978a17SVictor Perevertkin
146*8a978a17SVictor Perevertkin
147*8a978a17SVictor Perevertkin
148*8a978a17SVictor Perevertkin //
149*8a978a17SVictor Perevertkin // Get the IWudfDeviceStack interface
150*8a978a17SVictor Perevertkin //
151*8a978a17SVictor Perevertkin pDeviceStack = m_Device->GetDeviceStackInterface();
152*8a978a17SVictor Perevertkin
153*8a978a17SVictor Perevertkin //
154*8a978a17SVictor Perevertkin // Enable the interface
155*8a978a17SVictor Perevertkin //
156*8a978a17SVictor Perevertkin hr = pDeviceStack->SetDeviceInterfaceState(&this->m_InterfaceClassGUID,
157*8a978a17SVictor Perevertkin this->m_ReferenceString.Buffer,
158*8a978a17SVictor Perevertkin State);
159*8a978a17SVictor Perevertkin
160*8a978a17SVictor Perevertkin if (SUCCEEDED(hr)) {
161*8a978a17SVictor Perevertkin m_State = State;
162*8a978a17SVictor Perevertkin }
163*8a978a17SVictor Perevertkin else {
164*8a978a17SVictor Perevertkin status = FxDevice::NtStatusFromHr(pDeviceStack, hr);
165*8a978a17SVictor Perevertkin DoTraceLevelMessage(
166*8a978a17SVictor Perevertkin FxDevice::GetFxDevice(m_Device)->GetDriverGlobals(),
167*8a978a17SVictor Perevertkin TRACE_LEVEL_WARNING, TRACINGPNP,
168*8a978a17SVictor Perevertkin "Failed to %s device interface %!STATUS!",
169*8a978a17SVictor Perevertkin (State ? "enable" : "disable"), status);
170*8a978a17SVictor Perevertkin
171*8a978a17SVictor Perevertkin
172*8a978a17SVictor Perevertkin
173*8a978a17SVictor Perevertkin
174*8a978a17SVictor Perevertkin
175*8a978a17SVictor Perevertkin }
176*8a978a17SVictor Perevertkin }
177*8a978a17SVictor Perevertkin
178*8a978a17SVictor Perevertkin _Must_inspect_result_
179*8a978a17SVictor Perevertkin NTSTATUS
Register(__in MdDeviceObject DeviceObject)180*8a978a17SVictor Perevertkin FxDeviceInterface::Register(
181*8a978a17SVictor Perevertkin __in MdDeviceObject DeviceObject
182*8a978a17SVictor Perevertkin )
183*8a978a17SVictor Perevertkin /*++
184*8a978a17SVictor Perevertkin
185*8a978a17SVictor Perevertkin Routine Description:
186*8a978a17SVictor Perevertkin Registers the device interface for a given PDO
187*8a978a17SVictor Perevertkin
188*8a978a17SVictor Perevertkin Arguments:
189*8a978a17SVictor Perevertkin DeviceObject - FDO for the device stack in case of UM, and PDO for
190*8a978a17SVictor Perevertkin in case of KM.
191*8a978a17SVictor Perevertkin
192*8a978a17SVictor Perevertkin Return Value:
193*8a978a17SVictor Perevertkin returned by IWudfDeviceStack::CreateDeviceInterface
194*8a978a17SVictor Perevertkin
195*8a978a17SVictor Perevertkin --*/
196*8a978a17SVictor Perevertkin {
197*8a978a17SVictor Perevertkin HRESULT hr;
198*8a978a17SVictor Perevertkin NTSTATUS status;
199*8a978a17SVictor Perevertkin IWudfDeviceStack *pDeviceStack;
200*8a978a17SVictor Perevertkin
201*8a978a17SVictor Perevertkin m_Device = DeviceObject;
202*8a978a17SVictor Perevertkin
203*8a978a17SVictor Perevertkin //
204*8a978a17SVictor Perevertkin // Get the IWudfDeviceStack interface
205*8a978a17SVictor Perevertkin //
206*8a978a17SVictor Perevertkin pDeviceStack = m_Device->GetDeviceStackInterface();
207*8a978a17SVictor Perevertkin
208*8a978a17SVictor Perevertkin hr = pDeviceStack->CreateDeviceInterface(&m_InterfaceClassGUID,
209*8a978a17SVictor Perevertkin m_ReferenceString.Buffer);
210*8a978a17SVictor Perevertkin
211*8a978a17SVictor Perevertkin if (SUCCEEDED(hr)) {
212*8a978a17SVictor Perevertkin status = STATUS_SUCCESS;
213*8a978a17SVictor Perevertkin }
214*8a978a17SVictor Perevertkin else {
215*8a978a17SVictor Perevertkin status = FxDevice::NtStatusFromHr(pDeviceStack, hr);
216*8a978a17SVictor Perevertkin }
217*8a978a17SVictor Perevertkin
218*8a978a17SVictor Perevertkin return status;
219*8a978a17SVictor Perevertkin }
220*8a978a17SVictor Perevertkin
221*8a978a17SVictor Perevertkin _Must_inspect_result_
222*8a978a17SVictor Perevertkin NTSTATUS
Register(_In_ FxDevice * Device)223*8a978a17SVictor Perevertkin FxDeviceInterface::Register(
224*8a978a17SVictor Perevertkin _In_ FxDevice* Device
225*8a978a17SVictor Perevertkin )
226*8a978a17SVictor Perevertkin {
227*8a978a17SVictor Perevertkin NTSTATUS status;
228*8a978a17SVictor Perevertkin
229*8a978a17SVictor Perevertkin //
230*8a978a17SVictor Perevertkin // For UMDF, PDO is already known so no reason to defer registration.
231*8a978a17SVictor Perevertkin // Also, note that Register takes fdo as parameter for UMDF.
232*8a978a17SVictor Perevertkin //
233*8a978a17SVictor Perevertkin status = Register(Device->GetDeviceObject());
234*8a978a17SVictor Perevertkin
235*8a978a17SVictor Perevertkin return status;
236*8a978a17SVictor Perevertkin }
237*8a978a17SVictor Perevertkin
238*8a978a17SVictor Perevertkin NTSTATUS
GetSymbolicLinkName(_In_ FxString * LinkString)239*8a978a17SVictor Perevertkin FxDeviceInterface::GetSymbolicLinkName(
240*8a978a17SVictor Perevertkin _In_ FxString* LinkString
241*8a978a17SVictor Perevertkin )
242*8a978a17SVictor Perevertkin {
243*8a978a17SVictor Perevertkin NTSTATUS status;
244*8a978a17SVictor Perevertkin PCWSTR symLink = NULL;
245*8a978a17SVictor Perevertkin
246*8a978a17SVictor Perevertkin if (m_SymbolicLinkName.Buffer == NULL) {
247*8a978a17SVictor Perevertkin IWudfDeviceStack *pDeviceStack;
248*8a978a17SVictor Perevertkin IWudfDeviceStack2 *pDeviceStack2;
249*8a978a17SVictor Perevertkin
250*8a978a17SVictor Perevertkin //
251*8a978a17SVictor Perevertkin // Get the IWudfDeviceStack interface
252*8a978a17SVictor Perevertkin //
253*8a978a17SVictor Perevertkin pDeviceStack = m_Device->GetDeviceStackInterface();
254*8a978a17SVictor Perevertkin HRESULT hrQI;
255*8a978a17SVictor Perevertkin HRESULT hr;
256*8a978a17SVictor Perevertkin
257*8a978a17SVictor Perevertkin hrQI = pDeviceStack->QueryInterface(IID_IWudfDeviceStack2,
258*8a978a17SVictor Perevertkin (PVOID*)&pDeviceStack2);
259*8a978a17SVictor Perevertkin FX_VERIFY(INTERNAL, CHECK_QI(hrQI, pDeviceStack2));
260*8a978a17SVictor Perevertkin pDeviceStack->Release();
261*8a978a17SVictor Perevertkin
262*8a978a17SVictor Perevertkin //
263*8a978a17SVictor Perevertkin // Get the symbolic link
264*8a978a17SVictor Perevertkin //
265*8a978a17SVictor Perevertkin hr = pDeviceStack2->GetInterfaceSymbolicLink(&m_InterfaceClassGUID,
266*8a978a17SVictor Perevertkin m_ReferenceString.Buffer,
267*8a978a17SVictor Perevertkin &symLink);
268*8a978a17SVictor Perevertkin if (FAILED(hr)) {
269*8a978a17SVictor Perevertkin status = FxDevice::GetFxDevice(m_Device)->NtStatusFromHr(hr);
270*8a978a17SVictor Perevertkin }
271*8a978a17SVictor Perevertkin else {
272*8a978a17SVictor Perevertkin RtlInitUnicodeString(&m_SymbolicLinkName, symLink);
273*8a978a17SVictor Perevertkin status = STATUS_SUCCESS;
274*8a978a17SVictor Perevertkin }
275*8a978a17SVictor Perevertkin }
276*8a978a17SVictor Perevertkin else {
277*8a978a17SVictor Perevertkin status = STATUS_SUCCESS;
278*8a978a17SVictor Perevertkin }
279*8a978a17SVictor Perevertkin
280*8a978a17SVictor Perevertkin if (NT_SUCCESS(status)) {
281*8a978a17SVictor Perevertkin //
282*8a978a17SVictor Perevertkin // Attempt a copy
283*8a978a17SVictor Perevertkin //
284*8a978a17SVictor Perevertkin status = LinkString->Assign(&m_SymbolicLinkName);
285*8a978a17SVictor Perevertkin }
286*8a978a17SVictor Perevertkin
287*8a978a17SVictor Perevertkin return status;
288*8a978a17SVictor Perevertkin }
289*8a978a17SVictor Perevertkin
290