1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7     pnppriv.hpp
8 
9 Abstract:
10 
11     This module implements the pnp package for the driver frameworks.
12 
13 Author:
14 
15 
16 
17 Environment:
18 
19     Both kernel and user mode
20 
21 Revision History:
22 
23 
24 
25 --*/
26 
27 #ifndef _PNPPRIV_H_
28 #define _PNPPRIV_H_
29 
30 #if ((FX_CORE_MODE)==(FX_CORE_USER_MODE))
31 #define FX_IS_USER_MODE (TRUE)
32 #define FX_IS_KERNEL_MODE (FALSE)
33 #elif ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
34 #define FX_IS_USER_MODE (FALSE)
35 #define FX_IS_KERNEL_MODE (TRUE)
36 #endif
37 
38 //
39 // common header file for all irphandler\* files
40 //
41 #include "shared/irphandlers/irphandlerspriv.hpp"
42 
43 //
44 // public headers
45 //
46 #include "wdfdevice.h"
47 #include "wdfchildlist.h"
48 #include "wdfpdo.h"
49 #include "wdffdo.h"
50 #include "wdfqueryinterface.h"
51 #include "wdfmemory.h"
52 #include "wdfwmi.h"
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 #ifndef _INTERRUPT_COMMON_H_
73 #include "wdfinterrupt.h"
74 #endif
75 #ifndef _WUDFDDI_TYPES_PRIVATE_H_
76 #include "wdfrequest.h"
77 #include "wdfio.h"
78 #endif
79 
80 //
81 // private headers
82 //
83 #include "fxwaitlock.hpp"
84 #include "fxtransactionedlist.hpp"
85 #include "fxrelateddevicelist.hpp"
86 #include "fxcollection.hpp"
87 
88 // support
89 #include "stringutil.hpp"
90 #include "fxstring.hpp"
91 #include "fxdevicetext.hpp"
92 #include "fxcallback.hpp"
93 #include "fxsystemthread.hpp"
94 #include "fxresource.hpp"
95 
96 // io
97 #include "fxpkgioshared.hpp"
98 
99 //
100 // FxDeviceInitShared.hpp is new header with definition of PdoInit split from
101 // FxDeviceInit.hpp
102 //
103 #include "fxdeviceinitshared.hpp"
104 
105 // bus
106 #include "fxchildlist.hpp"
107 
108 // FxDevice To Shared interface header
109 #include "fxdevicetomxinterface.hpp"
110 
111 // mode specific headers
112 #if FX_IS_KERNEL_MODE
113 #include "pnpprivkm.hpp"
114 #elif FX_IS_USER_MODE
115 #include "pnpprivum.hpp"
116 #endif
117 
118 #include "fxspinlock.hpp"
119 
120 #if FX_IS_KERNEL_MODE
121 #include "fxinterruptkm.hpp"
122 #elif FX_IS_USER_MODE
123 #include "fxinterruptum.hpp"
124 #endif
125 
126 #if FX_IS_KERNEL_MODE
127 #include "fxperftracekm.hpp"
128 #endif
129 
130 #include "fxtelemetry.hpp"
131 
132 // pnp
133 #include "fxrelateddevice.hpp"
134 #include "fxdeviceinterface.hpp"
135 #include "fxqueryinterface.hpp"
136 #include "fxpnpcallbacks.hpp"
137 #include "fxpackage.hpp"
138 #include "fxpkgpnp.hpp"
139 #include "fxwatchdog.hpp"
140 #include "fxpkgpdo.hpp"
141 #include "fxpkgfdo.hpp"
142 
143 // wmi
144 #include "fxwmiirphandler.hpp"
145 #include "fxwmiprovider.hpp"
146 #include "fxwmiinstance.hpp"
147 
148 
149 VOID
150 PnpPassThroughQIWorker(
151     __in    MxDeviceObject* Device,
152     __inout FxIrp* Irp,
153     __inout FxIrp* ForwardIrp
154     );
155 
156 VOID
157 CopyQueryInterfaceToIrpStack(
158     __in PPOWER_THREAD_INTERFACE PowerThreadInterface,
159     __in FxIrp* Irp
160     );
161 
162 _Must_inspect_result_
163 NTSTATUS
164 SendDeviceUsageNotification(
165     __in MxDeviceObject* RelatedDevice,
166     __in FxIrp* RelatedIrp,
167     __in MxWorkItem* Workitem,
168     __in FxIrp* OriginalIrp,
169     __in BOOLEAN Revert
170     );
171 
172 _Must_inspect_result_
173 NTSTATUS
174 GetStackCapabilities(
175     __in PFX_DRIVER_GLOBALS DriverGlobals,
176     __in MxDeviceObject* DeviceInStack,
177     __in_opt PD3COLD_SUPPORT_INTERFACE D3ColdInterface,
178     __out PSTACK_DEVICE_CAPABILITIES Capabilities
179     );
180 
181 VOID
182 SetD3ColdSupport(
183     __in PFX_DRIVER_GLOBALS DriverGlobals,
184     __in MxDeviceObject* DeviceInStack,
185     __in PD3COLD_SUPPORT_INTERFACE D3ColdInterface,
186     __in BOOLEAN UseD3Cold
187     );
188 
189 #define SET_TRI_STATE_FROM_STATE_BITS(state, S, FieldName)      \
190 {                                                               \
191     switch (state & (FxPnpState##FieldName##Mask)) {            \
192     case FxPnpState##FieldName##False :                         \
193         S->FieldName =  WdfFalse;                               \
194         break;                                                  \
195     case FxPnpState##FieldName##True:                           \
196         S->FieldName =  WdfTrue;                                \
197         break;                                                  \
198     case FxPnpState##FieldName##UseDefault :                    \
199     default:                                                    \
200         S->FieldName =  WdfUseDefault;                          \
201         break;                                                  \
202     }                                                           \
203 }
204 
205 LONG
206 __inline
207 FxGetValueBits(
208     __in WDF_TRI_STATE State,
209     __in LONG TrueValue,
210     __in LONG UseDefaultValue
211     )
212 {
213     switch (State) {
214     case WdfFalse:      return 0x0;
215     case WdfTrue:       return TrueValue;
216     case WdfUseDefault:
217     default:            return UseDefaultValue;
218     }
219 }
220 
221 #define GET_PNP_STATE_BITS_FROM_STRUCT(S, FieldName)\
222     FxGetValueBits(S->FieldName,                    \
223                  FxPnpState##FieldName##True,       \
224                  FxPnpState##FieldName##UseDefault)
225 
226 #define GET_PNP_CAP_BITS_FROM_STRUCT(S, FieldName)  \
227     FxGetValueBits(S->FieldName,                    \
228                  FxPnpCap##FieldName##True,         \
229                  FxPnpCap##FieldName##UseDefault)
230 
231 #define GET_POWER_CAP_BITS_FROM_STRUCT(S, FieldName)\
232     FxGetValueBits(S->FieldName,                    \
233                    FxPowerCap##FieldName##True,     \
234                    FxPowerCap##FieldName##UseDefault)
235 
236 __inline
237 VOID
238 FxSetPnpDeviceStateBit(
239     __in PNP_DEVICE_STATE* PnpDeviceState,
240     __in LONG ExternalState,
241     __in LONG InternalState,
242     __in LONG BitMask,
243     __in LONG TrueValue
244     )
245 {
246     LONG bits;
247 
248     bits = InternalState & BitMask;
249 
250     if (bits == TrueValue) {
251         *PnpDeviceState |= ExternalState;
252     }
253     else if (bits == 0) {  // 0 is the always false for every bit-set
254         *PnpDeviceState &= ~ExternalState;
255     }
256 }
257 
258 #define SET_PNP_DEVICE_STATE_BIT(State, ExternalState, value, Name) \
259     FxSetPnpDeviceStateBit(State,                                   \
260                            ExternalState,                           \
261                            state,                                   \
262                            FxPnpState##Name##Mask,                  \
263                            FxPnpState##Name##True)
264 
265 #define SET_PNP_CAP_IF_TRUE(caps, pCaps, FieldName)                         \
266 {                                                                           \
267     if ((caps & FxPnpCap##FieldName##Mask) == FxPnpCap##FieldName##True) {  \
268         pCaps->FieldName = TRUE;                                            \
269     }                                                                       \
270 }
271 
272 #define SET_PNP_CAP_IF_FALSE(caps, pCaps, FieldName)                        \
273 {                                                                           \
274     if ((caps & FxPnpCap##FieldName##Mask) == FxPnpCap##FieldName##False) { \
275         pCaps->FieldName = FALSE;                                           \
276     }                                                                       \
277 }
278 
279 #define SET_PNP_CAP(caps, pCaps, FieldName)                                 \
280 {                                                                           \
281     if ((caps & FxPnpCap##FieldName##Mask) == FxPnpCap##FieldName##False) { \
282         pCaps->FieldName = FALSE;                                           \
283     }                                                                       \
284     else if ((caps & FxPnpCap##FieldName##Mask) == FxPnpCap##FieldName##True) {  \
285         pCaps->FieldName = TRUE;                                            \
286     }                                                                       \
287 }
288 
289 #define SET_POWER_CAP(caps, pCaps, FieldName)                               \
290 {                                                                           \
291     if ((caps & FxPowerCap##FieldName##Mask) == FxPowerCap##FieldName##False) { \
292         pCaps->FieldName = FALSE;                                           \
293     }                                                                       \
294     else if ((caps & FxPowerCap##FieldName##Mask) == FxPowerCap##FieldName##True) {  \
295         pCaps->FieldName = TRUE;                                            \
296     }                                                                       \
297 }
298 
299 _Must_inspect_result_
300 PVOID
301 GetIoMgrObjectForWorkItemAllocation(
302     VOID
303     );
304 
305 
306 
307 
308 
309 
310 
311 typedef struct _WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_V1_7 {
312     //
313     // Size of this structure in bytes
314     //
315     ULONG Size;
316 
317     //
318     // Indicates whether the device can wake itself up while the machine is in
319     // S0.
320     //
321     WDF_POWER_POLICY_S0_IDLE_CAPABILITIES IdleCaps;
322 
323     //
324     // The low power state in which the device will be placed when it is idled
325     // out while the machine is in S0.
326     //
327     DEVICE_POWER_STATE DxState;
328 
329     //
330     // Amount of time the device must be idle before idling out.  Timeout is in
331     // milliseconds.
332     //
333     ULONG IdleTimeout;
334 
335     //
336     // Inidcates whether a user can control the idle policy of the device.
337     // By default, a user is allowed to change the policy.
338     //
339     WDF_POWER_POLICY_S0_IDLE_USER_CONTROL UserControlOfIdleSettings;
340 
341     //
342     // If WdfTrue, idling out while the machine is in S0 will be enabled.
343     //
344     // If WdfFalse, idling out will be disabled.
345     //
346     // If WdfUseDefault, the idling out will be enabled.  If
347     // UserControlOfIdleSettings is set to IdleAllowUserControl, the user's
348     // settings will override the default.
349     //
350     WDF_TRI_STATE Enabled;
351 
352 } WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_V1_7, *PWDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_V1_7;
353 
354 typedef struct _WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_V1_9 {
355     //
356     // Size of this structure in bytes
357     //
358     ULONG Size;
359 
360     //
361     // Indicates whether the device can wake itself up while the machine is in
362     // S0.
363     //
364     WDF_POWER_POLICY_S0_IDLE_CAPABILITIES IdleCaps;
365 
366     //
367     // The low power state in which the device will be placed when it is idled
368     // out while the machine is in S0.
369     //
370     DEVICE_POWER_STATE DxState;
371 
372     //
373     // Amount of time the device must be idle before idling out.  Timeout is in
374     // milliseconds.
375     //
376     ULONG IdleTimeout;
377 
378     //
379     // Inidcates whether a user can control the idle policy of the device.
380     // By default, a user is allowed to change the policy.
381     //
382     WDF_POWER_POLICY_S0_IDLE_USER_CONTROL UserControlOfIdleSettings;
383 
384     //
385     // If WdfTrue, idling out while the machine is in S0 will be enabled.
386     //
387     // If WdfFalse, idling out will be disabled.
388     //
389     // If WdfUseDefault, the idling out will be enabled.  If
390     // UserControlOfIdleSettings is set to IdleAllowUserControl, the user's
391     // settings will override the default.
392     //
393     WDF_TRI_STATE Enabled;
394 
395     //
396     // This field is applicable only when IdleCaps == IdleCannotWakeFromS0
397     // If WdfTrue,device is powered up on System Wake even if device is idle
398     // If WdfFalse, device is not powered up on system wake if it is idle
399     // If WdfUseDefault, the behavior is same as WdfFalse
400     //
401     WDF_TRI_STATE PowerUpIdleDeviceOnSystemWake;
402 
403 } WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_V1_9,
404     *PWDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_V1_9;
405 
406 typedef struct _WDF_PDO_EVENT_CALLBACKS_V1_9 {
407     //
408     // The size of this structure in bytes
409     //
410     ULONG Size;
411 
412     //
413     // Called in response to IRP_MN_QUERY_RESOURCES
414     //
415     PFN_WDF_DEVICE_RESOURCES_QUERY EvtDeviceResourcesQuery;
416 
417     //
418     // Called in response to IRP_MN_QUERY_RESOURCE_REQUIREMENTS
419     //
420     PFN_WDF_DEVICE_RESOURCE_REQUIREMENTS_QUERY EvtDeviceResourceRequirementsQuery;
421 
422     //
423     // Called in response to IRP_MN_EJECT
424     //
425     PFN_WDF_DEVICE_EJECT EvtDeviceEject;
426 
427     //
428     // Called in response to IRP_MN_SET_LOCK
429     //
430     PFN_WDF_DEVICE_SET_LOCK EvtDeviceSetLock;
431 
432     //
433     // Called in response to the power policy owner sending a wait wake to the
434     // PDO.  Bus generic arming shoulding occur here.
435     //
436     PFN_WDF_DEVICE_ENABLE_WAKE_AT_BUS       EvtDeviceEnableWakeAtBus;
437 
438     //
439     // Called in response to the power policy owner sending a wait wake to the
440     // PDO.  Bus generic disarming shoulding occur here.
441     //
442     PFN_WDF_DEVICE_DISABLE_WAKE_AT_BUS      EvtDeviceDisableWakeAtBus;
443 
444 } WDF_PDO_EVENT_CALLBACKS_V1_9, *PWDF_PDO_EVENT_CALLBACKS_V1_9;
445 
446 
447 
448 
449 
450 typedef struct _WDF_INTERRUPT_INFO_V1_7 {
451     //
452     // Size of this structure in bytes
453     //
454     ULONG                  Size;
455 
456     ULONG64                Reserved1;
457 
458     KAFFINITY              TargetProcessorSet;
459 
460     ULONG                  Reserved2;
461 
462     ULONG                  MessageNumber;
463 
464     ULONG                  Vector;
465 
466     KIRQL                  Irql;
467 
468     KINTERRUPT_MODE        Mode;
469 
470     WDF_INTERRUPT_POLARITY Polarity;
471 
472     BOOLEAN                MessageSignaled;
473 
474     // CM_SHARE_DISPOSITION
475     UCHAR                  ShareDisposition;
476 
477 } WDF_INTERRUPT_INFO_V1_7, *PWDF_INTERRUPT_INFO_V1_7;
478 
479 typedef struct _WDF_INTERRUPT_INFO_V1_7 *PWDF_INTERRUPT_INFO_V1_7;
480 typedef const struct _WDF_INTERRUPT_INFO_V1_7 *PCWDF_INTERRUPT_INFO_V1_7;
481 
482 #endif // _PNPPRIV_H_
483