1 /*++ 2 3 Copyright (c) Microsoft. All rights reserved. 4 5 Module Name: 6 7 FxPkgPdo.hpp 8 9 Abstract: 10 11 This module implements the pnp package for Pdo objects. 12 13 Author: 14 15 16 17 Environment: 18 19 Both kernel and user mode 20 21 Revision History: 22 23 24 --*/ 25 26 #ifndef _FXPKGPDO_H_ 27 #define _FXPKGPDO_H_ 28 29 typedef NTSTATUS (FxPkgPdo::*PFN_PDO_HANDLER)(FxIrp *Irp); 30 31 class FxPkgPdo : public FxPkgPnp 32 { 33 public: 34 // 35 // Properties used in handling IRP_MN_QUERY_DEVICE_TEXT 36 // 37 SINGLE_LIST_ENTRY m_DeviceTextHead; 38 LCID m_DefaultLocale; 39 40 FxDeviceDescriptionEntry* m_Description; 41 42 FxChildList* m_OwningChildList; 43 44 // 45 // The following structure contains the function pointer table 46 // for the "events" this package can raise. 47 // 48 FxPnpDeviceResourcesQuery m_DeviceResourcesQuery; 49 FxPnpDeviceResourceRequirementsQuery m_DeviceResourceRequirementsQuery; 50 FxPnpDeviceEject m_DeviceEject; 51 FxPnpDeviceSetLock m_DeviceSetLock; 52 53 FxPowerDeviceEnableWakeAtBus m_DeviceEnableWakeAtBus; 54 FxPowerDeviceDisableWakeAtBus m_DeviceDisableWakeAtBus; 55 56 // added in 1.11 57 FxPnpDeviceReportedMissing m_DeviceReportedMissing; 58 59 BOOLEAN m_RawOK; 60 61 BOOLEAN m_Static; 62 63 BOOLEAN m_AddedToStaticList; 64 65 // 66 // This field is used to indicate that Requests on this PDO could be 67 // forwarded to the parent. 68 // 69 BOOLEAN m_AllowForwardRequestToParent; 70 71 protected: 72 // 73 // Pointer to a null terminated string which is the device ID. This is 74 // not a pointer that can be freed. m_IDsAllocation is the beginning of 75 // the allocation that can be freed. 76 // 77 PWSTR m_DeviceID; 78 79 // 80 // Pointer to a null terminated string which is the instance ID. This is 81 // not a pointer that can be freed. m_IDsAllocation is the beginning of 82 // the allocation that can be freed. 83 // 84 PWSTR m_InstanceID; 85 86 // 87 // Pointer to a multi sz which is the hardware IDs. This is 88 // not a pointer that can be freed. m_IDsAllocation is the beginning of 89 // the allocation that can be freed. 90 // 91 PWSTR m_HardwareIDs; 92 93 // 94 // Pointer to a multi sz which is the compatible IDs. This is 95 // not a pointer that can be freed. m_IDsAllocation is the beginning of 96 // the allocation that can be freed. 97 // 98 PWSTR m_CompatibleIDs; 99 100 // 101 // Pointer to a null terminated string which is the unique ID. This is 102 // not a pointer that can be freed. m_IDsAllocation is the beginning of 103 // the allocation that can be freed. 104 // 105 PWSTR m_ContainerID; 106 107 // 108 // Single allocation for all static ID strings (device, instance, hw, compat) 109 // for the device 110 // 111 PWSTR m_IDsAllocation; 112 113 FxRelatedDeviceList* m_EjectionDeviceList; 114 115 // 116 // IRP_MN_EJECT needs to be handled synchronously because PnP manager does 117 // not serialize it with other state changing PnP irps if not handled 118 // synchronously. This event is used to signal the completion of 119 // IRP_MN_EJECT processing. 120 // 121 MxEvent* m_DeviceEjectProcessed; 122 123 BOOLEAN m_CanBeDeleted; 124 125 // 126 // Parameter to track whether the EvtDeviceEnableWakeAtBus callback was 127 // invoked and to determine whether the EvtDeviceDisableWakeAtBus callback 128 // should be invoked or not. The EnableWakeAtBus callback may not get 129 // invoked if an upper driver in the stack completed the wait wake irp 130 // instead of passing it down the stack and the power policy owner is 131 // a PDO. 132 // 133 // This parameter can be referenced by either the power state machine or 134 // the power policy state machine when a PDO is the power policy owner 135 // but there is no locking mechanism necessary to synchronize access to 136 // the field. This is because the arrival of a Dx irp will move the power 137 // state machine to a state where it can no longer affect the value of 138 // this field and hence provides an implicit guard that allows the power 139 // policy state machine to use this field while processing the Dx irp. 140 // 141 BOOLEAN m_EnableWakeAtBusInvoked; 142 143 private: 144 // 145 // Table of internal methods to handle PnP minor function codes. 146 // 147 static const PFN_PNP_POWER_CALLBACK m_PdoPnpFunctionTable[IRP_MN_SURPRISE_REMOVAL + 1]; 148 149 // 150 // Table of internal methods to handle power minor function codes. 151 // 152 static const PFN_PNP_POWER_CALLBACK m_PdoPowerFunctionTable[IRP_MN_QUERY_POWER + 1]; 153 154 public: 155 156 FxPkgPdo( 157 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 158 __in CfxDevice *Device 159 ); 160 161 ~FxPkgPdo(); 162 163 _Must_inspect_result_ 164 virtual 165 NTSTATUS 166 Initialize( 167 __in PWDFDEVICE_INIT DeviceInit 168 ); 169 170 virtual 171 VOID 172 FinishInitialize( 173 __in PWDFDEVICE_INIT DeviceInit 174 ); 175 176 VOID 177 RegisterCallbacks( 178 __in PWDF_PDO_EVENT_CALLBACKS DispatchTable 179 ); 180 181 _Must_inspect_result_ 182 NTSTATUS 183 AddEjectionDevice( 184 __in MdDeviceObject DependentDevice 185 ); 186 187 VOID 188 RemoveEjectionDevice( 189 __in MdDeviceObject DependentDevice 190 ); 191 192 VOID 193 ClearEjectionDevicesList( 194 VOID 195 ); 196 197 _Must_inspect_result_ 198 NTSTATUS 199 HandleQueryInterfaceForReenumerate( 200 __in FxIrp* Irp, 201 __out PBOOLEAN CompleteRequest 202 ); 203 204 __inline 205 BOOLEAN IsForwardRequestToParentEnabled(VOID)206 IsForwardRequestToParentEnabled( 207 VOID 208 ) 209 { 210 return m_AllowForwardRequestToParent; 211 } 212 213 214 private: 215 _Must_inspect_result_ 216 virtual 217 NTSTATUS 218 SendIrpSynchronously( 219 __in FxIrp* Irp 220 ); 221 222 _Must_inspect_result_ 223 virtual 224 NTSTATUS 225 FireAndForgetIrp( 226 __inout FxIrp* Irp 227 ); 228 229 // 230 // The following are static member function. The only reason 231 // I've defined them as member functions at all is so they can see 232 // the private data in this class. 233 // 234 235 _Must_inspect_result_ 236 static 237 NTSTATUS 238 _PnpCompleteIrp( 239 __in FxPkgPnp* This, 240 __inout FxIrp *Irp 241 ); 242 243 _Must_inspect_result_ 244 static 245 NTSTATUS 246 _PnpQueryDeviceRelations( 247 __in FxPkgPnp* This, 248 __inout FxIrp *Irp 249 ); 250 251 _Must_inspect_result_ 252 NTSTATUS 253 PnpQueryDeviceRelations( 254 __inout FxIrp *Irp 255 ); 256 257 _Must_inspect_result_ 258 static 259 NTSTATUS 260 _PnpQueryInterface( 261 IN FxPkgPnp* This, 262 IN FxIrp *Irp 263 ); 264 265 _Must_inspect_result_ 266 static 267 NTSTATUS 268 _PnpQueryCapabilities( 269 __inout FxPkgPnp* This, 270 __inout FxIrp *Irp 271 ); 272 273 _Must_inspect_result_ 274 NTSTATUS 275 PnpQueryCapabilities( 276 __inout FxIrp *Irp 277 ); 278 279 VOID 280 HandleQueryCapabilities( 281 __inout PDEVICE_CAPABILITIES ReportedCaps, 282 __in PDEVICE_CAPABILITIES ParentCaps 283 ); 284 285 static 286 VOID 287 STDCALL 288 _QueryCapsWorkItem( 289 __in MdDeviceObject DeviceObject, 290 __in PVOID Context 291 ); 292 293 _Must_inspect_result_ 294 static 295 NTSTATUS 296 _PnpQueryResources( 297 __inout FxPkgPnp* This, 298 __inout FxIrp *Irp 299 ); 300 301 _Must_inspect_result_ 302 NTSTATUS 303 PnpQueryResources( 304 __inout FxIrp *Irp 305 ); 306 307 _Must_inspect_result_ 308 static 309 NTSTATUS 310 _PnpQueryResourceRequirements( 311 __inout FxPkgPnp* This, 312 __inout FxIrp *Irp 313 ); 314 315 _Must_inspect_result_ 316 NTSTATUS 317 PnpQueryResourceRequirements( 318 __inout FxIrp *Irp 319 ); 320 321 _Must_inspect_result_ 322 static 323 NTSTATUS 324 _PnpQueryDeviceText( 325 __inout FxPkgPnp* This, 326 __inout FxIrp *Irp 327 ); 328 329 _Must_inspect_result_ 330 static 331 NTSTATUS 332 _PnpFilterResourceRequirements( 333 __inout FxPkgPnp* This, 334 __inout FxIrp *Irp 335 ); 336 337 _Must_inspect_result_ 338 static 339 NTSTATUS 340 _PnpEject( 341 __inout FxPkgPnp* This, 342 __inout FxIrp *Irp 343 ); 344 345 virtual 346 BOOLEAN 347 PnpSendStartDeviceDownTheStackOverload( 348 VOID 349 ); 350 351 virtual 352 WDF_DEVICE_PNP_STATE 353 PnpEventEjectHardwareOverload( 354 VOID 355 ); 356 357 virtual 358 WDF_DEVICE_PNP_STATE 359 PnpEventCheckForDevicePresenceOverload( 360 VOID 361 ); 362 363 virtual 364 WDF_DEVICE_PNP_STATE 365 PnpEventPdoRemovedOverload( 366 VOID 367 ); 368 369 virtual 370 WDF_DEVICE_PNP_STATE 371 PnpEventFdoRemovedOverload( 372 VOID 373 ); 374 375 virtual 376 VOID 377 PnpEventSurpriseRemovePendingOverload( 378 VOID 379 ); 380 381 virtual 382 WDF_DEVICE_PNP_STATE 383 PnpGetPostRemoveState( 384 VOID 385 ); 386 387 _Must_inspect_result_ 388 static 389 NTSTATUS 390 _PnpSetLock( 391 __inout FxPkgPnp* This, 392 __inout FxIrp *Irp 393 ); 394 395 _Must_inspect_result_ 396 static 397 NTSTATUS 398 _PnpQueryId( 399 __inout FxPkgPnp* This, 400 __inout FxIrp *Irp 401 ); 402 403 _Must_inspect_result_ 404 static 405 NTSTATUS 406 _PnpQueryPnpDeviceState( 407 __inout FxPkgPnp* This, 408 __inout FxIrp *Irp 409 ); 410 411 _Must_inspect_result_ 412 static 413 NTSTATUS 414 _PnpQueryBusInformation( 415 __inout FxPkgPnp* This, 416 __inout FxIrp *Irp 417 ); 418 419 _Must_inspect_result_ 420 static 421 NTSTATUS 422 _PnpSurpriseRemoval( 423 __inout FxPkgPnp* This, 424 __inout FxIrp *Irp 425 ); 426 427 static 428 _Must_inspect_result_ 429 NTSTATUS 430 _DispatchPowerSequence( 431 __inout FxPkgPnp* This, 432 __in FxIrp *Irp 433 ); 434 435 static 436 _Must_inspect_result_ 437 NTSTATUS 438 _DispatchSetPower( 439 __inout FxPkgPnp* This, 440 __in FxIrp *Irp 441 ); 442 443 _Must_inspect_result_ 444 NTSTATUS 445 DispatchSystemSetPower( 446 __in FxIrp *Irp 447 ); 448 449 _Must_inspect_result_ 450 NTSTATUS 451 DispatchDeviceSetPower( 452 __in FxIrp *Irp 453 ); 454 455 static 456 _Must_inspect_result_ 457 NTSTATUS 458 _DispatchQueryPower( 459 __inout FxPkgPnp* This, 460 __in FxIrp *Irp 461 ); 462 463 virtual 464 _Must_inspect_result_ 465 NTSTATUS 466 PowerCheckParentOverload( 467 __in BOOLEAN* ParentOn 468 ); 469 470 virtual 471 WDF_DEVICE_POWER_STATE 472 PowerCheckDeviceTypeOverload( 473 VOID 474 ); 475 476 virtual 477 WDF_DEVICE_POWER_STATE 478 PowerCheckDeviceTypeNPOverload( 479 VOID 480 ); 481 482 virtual 483 _Must_inspect_result_ 484 NTSTATUS 485 PowerEnableWakeAtBusOverload( 486 VOID 487 ); 488 489 virtual 490 VOID 491 PowerDisableWakeAtBusOverload( 492 VOID 493 ); 494 495 virtual 496 VOID 497 PowerParentPowerDereference( 498 VOID 499 ); 500 501 virtual 502 VOID 503 PowerReleasePendingDeviceIrp( 504 __in BOOLEAN IrpMustBePresent = TRUE 505 ); 506 507 _Must_inspect_result_ 508 virtual 509 NTSTATUS 510 ProcessRemoveDeviceOverload( 511 __inout FxIrp* Irp 512 ); 513 514 virtual 515 VOID 516 DeleteSymbolicLinkOverload( 517 __in BOOLEAN GracefulRemove 518 ); 519 520 virtual 521 VOID QueryForReenumerationInterface(VOID)522 QueryForReenumerationInterface( 523 VOID 524 ) 525 { 526 // 527 // As the PDO, we already have the interface built in 528 // 529 DO_NOTHING(); 530 } 531 532 virtual 533 VOID ReleaseReenumerationInterface(VOID)534 ReleaseReenumerationInterface( 535 VOID 536 ) 537 { 538 // 539 // As the PDO, we already have the interface built in 540 // 541 DO_NOTHING(); 542 } 543 544 _Must_inspect_result_ 545 virtual 546 NTSTATUS 547 AskParentToRemoveAndReenumerate( 548 VOID 549 ); 550 551 _Must_inspect_result_ 552 virtual 553 NTSTATUS 554 QueryForPowerThread( 555 VOID 556 ); 557 558 virtual 559 const PFN_PNP_POWER_CALLBACK* GetDispatchPnp(VOID)560 GetDispatchPnp( 561 VOID 562 ) 563 { 564 return m_PdoPnpFunctionTable; 565 } 566 567 virtual 568 const PFN_PNP_POWER_CALLBACK* GetDispatchPower(VOID)569 GetDispatchPower( 570 VOID 571 ) 572 { 573 return m_PdoPowerFunctionTable; 574 } 575 576 static 577 VOID 578 STDCALL 579 _RemoveAndReenumerateSelf( 580 __in PVOID Context 581 ); 582 583 VOID 584 PowerNotifyParentChildWakeArmed( 585 VOID 586 ); 587 588 VOID 589 PowerNotifyParentChildWakeDisarmed( 590 VOID 591 ); 592 }; 593 594 #endif // _FXPKGPDO_H 595