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