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