1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7     FxPkgFdoUm.cpp
8 
9 Abstract:
10 
11     This module implements the pnp/power package for the driver
12     framework.
13 
14 Author:
15 
16 
17 
18 
19 Environment:
20 
21     User mode only
22 
23 Revision History:
24 
25 
26 
27 --*/
28 
29 #include "../pnppriv.hpp"
30 
31 #include <initguid.h>
32 #include <wdmguid.h>
33 
34 
35 #if defined(EVENT_TRACING)
36 // Tracing support
37 extern "C" {
38 #include "FxPkgFdoUm.tmh"
39 }
40 #endif
41 
42 _Must_inspect_result_
43 NTSTATUS
44 FxPkgFdo::PnpFilterResourceRequirements(
45     __inout FxIrp *Irp
46     )
47 
48 /*++
49 
50 Routine Description:
51 
52     This method is invoked in response to a Pnp FilterResourceRequirements IRP.
53 
54 Arguments:
55 
56     Device - a pointer to the FxDevice
57 
58     Irp - a pointer to the FxIrp
59 
60 Returns:
61 
62     NTSTATUS
63 
64 --*/
65 
66 {
67     UNREFERENCED_PARAMETER(Irp);
68     ASSERTMSG("Not implemented for UMDF\n", FALSE);
69 
70     return STATUS_NOT_IMPLEMENTED;
71 }
72 
73 _Must_inspect_result_
74 NTSTATUS
75 FxPkgFdo::PnpQueryCapabilities(
76     __inout FxIrp *Irp
77     )
78 
79 /*++
80 
81 Routine Description:
82 
83     This method is invoked in response to a Pnp QueryCapabilities IRP.
84 
85 Arguments:
86 
87     Device - a pointer to the FxDevice
88 
89     Irp - a pointer to the FxIrp
90 
91 Returns:
92 
93     NTSTATUS
94 
95 --*/
96 
97 {
98     HandleQueryCapabilities(Irp);
99 
100     //
101     // Set a completion routine on the IRP
102     //
103     Irp->CopyCurrentIrpStackLocationToNext();
104     Irp->SetCompletionRoutine(
105         _PnpQueryCapabilitiesCompletionRoutine,
106         this
107         );
108 
109     //
110     // Send the IRP down the stack
111     //
112     Irp->CallDriver(m_Device->GetAttachedDevice());
113 
114     return STATUS_SUCCESS;
115 }
116 
117 _Must_inspect_result_
118 NTSTATUS
119 FxPkgFdo::_PnpQueryCapabilitiesCompletionRoutine(
120     __in    MdDeviceObject DeviceObject,
121     __inout MdIrp Irp,
122     __inout PVOID Context
123     )
124 {
125     NTSTATUS status;
126     FxPkgFdo* pThis;
127     FxIrp irp(Irp);
128 
129     UNREFERENCED_PARAMETER(DeviceObject);
130 
131     pThis = (FxPkgFdo*) Context;
132     status = irp.GetStatus();
133 
134     //
135     // Now that the IRP has returned to us, we modify what the bus driver
136     // set up.
137     //
138     if (NT_SUCCESS(status)) {
139         pThis->HandleQueryCapabilitiesCompletion(&irp);
140     }
141 
142     pThis->CompletePnpRequest(&irp, status);
143 
144     return STATUS_MORE_PROCESSING_REQUIRED;
145 }
146 
147 _Must_inspect_result_
148 NTSTATUS
149 FxPkgFdo::_PnpQueryPnpDeviceState(
150     __inout FxPkgPnp* This,
151     __inout FxIrp *Irp
152     )
153 
154 /*++
155 
156 Routine Description:
157 
158     This method is invoked in response to a Pnp QueryPnpDeviceState IRP.
159 
160 Arguments:
161 
162     Irp - a pointer to the FxIrp
163 
164 Returns:
165 
166     NTSTATUS
167 
168 --*/
169 
170 {
171     FxPkgFdo* pThis;
172 
173     pThis = (FxPkgFdo*) This;
174 
175     //
176     // Set a completion routine on the IRP
177     //
178     Irp->CopyCurrentIrpStackLocationToNext();
179     Irp->SetCompletionRoutine(
180         FxPkgFdo::_PnpQueryPnpDeviceStateCompletionRoutine,
181         pThis
182         );
183 
184     //
185     // Send the IRP down the stack
186     //
187     Irp->CallDriver(pThis->m_Device->GetAttachedDevice());
188 
189     return STATUS_SUCCESS;
190 }
191 
192 _Must_inspect_result_
193 NTSTATUS
194 FxPkgFdo::_PnpQueryPnpDeviceStateCompletionRoutine(
195     __in    MdDeviceObject DeviceObject,
196     __inout MdIrp Irp,
197     __inout PVOID Context
198     )
199 {
200     NTSTATUS status;
201     FxPkgFdo* pThis;
202     FxIrp irp(Irp);
203 
204     UNREFERENCED_PARAMETER(DeviceObject);
205 
206     pThis = (FxPkgFdo*) Context;
207     status = irp.GetStatus();
208 
209     if (status == STATUS_NOT_SUPPORTED) {
210         //
211         // Morph into a successful code so that we process the request
212         //
213         status = STATUS_SUCCESS;
214         irp.SetStatus(status);
215     }
216 
217     if (NT_SUCCESS(status)) {
218         pThis->HandleQueryPnpDeviceStateCompletion(&irp);
219     }
220     else {
221         DoTraceLevelMessage(
222             pThis->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
223             "Lower stack returned error for query pnp device state, %!STATUS!",
224             status);
225     }
226 
227     //
228     // Since we already sent the request down the stack, we must complete it
229     // now.
230     //
231     pThis->CompletePnpRequest(&irp, status);
232 
233     return STATUS_MORE_PROCESSING_REQUIRED;
234 }
235 
236 _Must_inspect_result_
237 NTSTATUS
238 FxPkgFdo::Initialize(
239     __in PWDFDEVICE_INIT DeviceInit
240     )
241 /*++
242 
243 
244 
245 
246 
247 
248 
249 
250 
251 
252 
253 Routine Description:
254 
255     After creating a FxPkgFdo, the driver writer will initialize it by passing
256     a set of driver callbacks that allow the driver writer to customize the
257     behavior when handling certain IRPs.
258 
259     This is the place to do any initialization that might fail.
260 
261 Arguments:
262 
263     Device - a pointer to the FxDevice
264 
265     DispatchTable - a driver supplied table of callbacks
266 
267 Returns:
268 
269     NTSTATUS
270 
271 --*/
272 {
273     PFX_DRIVER_GLOBALS pGlobals;
274     NTSTATUS status;
275 
276     pGlobals = GetDriverGlobals();
277 
278     status = FxPkgPnp::Initialize(DeviceInit);
279     if (!NT_SUCCESS(status)) {
280         return status;
281     }
282 
283     status = AllocateEnumInfo();
284     if (!NT_SUCCESS(status)) {
285         return status;
286     }
287 
288     return status;
289 }
290 
291 _Must_inspect_result_
292 NTSTATUS
293 FxPkgFdo::AskParentToRemoveAndReenumerate(
294     VOID
295     )
296 /*++
297 
298 Routine Description:
299     This routine asks the PDO to ask its parent bus driver to Surprise-Remove
300     and re-enumerate the PDO.  This will be done only at the point of
301     catastrophic software failure, and occasionally after catastrophic hardware
302     failure.
303 
304 Arguments:
305     None
306 
307 Return Value:
308     status
309 
310   --*/
311 {
312     HRESULT hr;
313     IWudfDeviceStack2* pDevStack = m_Device->GetDeviceStack2();
314 
315     hr = pDevStack->ReenumerateSelf();
316     if (SUCCEEDED(hr)) {
317         return STATUS_SUCCESS;
318     }
319 
320     return STATUS_NOT_SUPPORTED;
321 }
322 
323