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
FxGetValueBits(__in WDF_TRI_STATE State,__in LONG TrueValue,__in LONG UseDefaultValue)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
FxSetPnpDeviceStateBit(__in PNP_DEVICE_STATE * PnpDeviceState,__in LONG ExternalState,__in LONG InternalState,__in LONG BitMask,__in LONG TrueValue)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