summaryrefslogtreecommitdiff
path: root/pofx/WDF/Driver/MultiComp/inc/WdfPoFx.h
blob: bcecdc86670202d402b0bdefa6244db8db36df0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
/*++

Copyright (c) Microsoft Corporation.  All rights reserved.

    THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
    KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
    PURPOSE.

Module Name:

    WdfPoFx.h

Abstract:
    This header file describes the interface between the driver layer and the
    power framework helper library.

Environment:

    Kernel mode

--*/
#if !defined(_WDFPOFX_H_)
#define _WDFPOFX_H_
    
#include <ntddk.h>
#include <wdf.h>

//
// Routine description:
//      This routine is invoked by the power framework helper library to notify
//      the driver layer that it has registered with the power framework. The 
//      driver layer can provide this callback to the power framework helper 
//      library by calling PfhSetPoHandleAvailabilityCallbacks. The power 
//      framework helper library invokes this routine during the processing of 
//      the first start IRP for the device. (Note that the device might receive
//      more than one start IRP if a resource rebalance occurs while it is 
//      operational).
//
// Arguments:
//      Device - Handle to the KMDF device object
//
//      PoHandle - Handle that represents the device's registration with the
//          power framework.
//
// Return value:
//      An NTSTATUS value representing success or failure of the function. If 
//      the driver layer returns an NTSTATUS value representing failure, the 
//      power framework helper library immediately unregisters with the power
//      framework and fails the start IRP.
//
typedef
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
PFH_CALLBACK_POHANDLE_AVAILABLE(
    _In_ WDFDEVICE Device,
    _In_ POHANDLE PoHandle
    );

typedef PFH_CALLBACK_POHANDLE_AVAILABLE *PPFH_CALLBACK_POHANDLE_AVAILABLE;

//
// Routine description:
//      This routine is invoked by the power framework helper library to notify
//      the driver layer that it is about to unregister with the power 
//      framework. The driver layer can provide this callback to the power 
//      framework helper library by calling 
//      PfhSetPoHandleAvailabilityCallbacks. The POHANDLE representing the 
//      device's registration with the power framework is not guaranteed to be 
//      valid after the driver layer has returned from this routine. Therefore, 
//      the driver layer must stop using the POHANDLE before it returns from 
//      this routine. 
//
// Arguments:
//      Device - Handle to the KMDF device object
//
//      PoHandle - Handle that represents the device's registration with the
//          power framework.
//
// Return value:
//      None
//
typedef
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
PFH_CALLBACK_POHANDLE_UNAVAILABLE(
    _In_ WDFDEVICE Device,
    _In_ POHANDLE PoHandle
    );

typedef PFH_CALLBACK_POHANDLE_UNAVAILABLE *PPFH_CALLBACK_POHANDLE_UNAVAILABLE;

//
// PfhInitializerCreate
// ====================
// Routine description:
//      This routine is invoked by the driver layer to create a power framework
//      helper library initializer object. This initializer object helps the
//      power framework library to initialize its own settings for KMDF objects.
//      After creating the initializer object, the driver layer passes it in 
//      as an argument to several initialization methods in the power framework
//      helper library.
//
//      If the driver layer calls any of the following methods when creating a 
//      KMDF device object, the initializer object needs to be passed in as an
//      argument:
//          PfhAssignWdmPowerIrpPreProcessCallback
//          PfhInterceptWdfPnpPowerEventCallbacks
//          PfhSetPoHandleAvailabilityCallbacks
//          PfhInitializeDeviceSettings
//
//      If the driver layer calls any of the following methods when creating a 
//      KMDF queue object, the initializer object needs to be passed in as an
//      argument:
//          PfhInterceptComponentQueueConfig
//          PfhSetComponentForComponentQueue
//          PfhInitializeComponentQueueSettings
//
//      The same initializer object can be used to initialize more than one KMDF
//      object, but at any given time it must be used to initialize only one 
//      KMDF object. For example, the driver layer could use an initializer 
//      object to initialize a KMDF device object and when it is done 
//      initializing the device object, the same object can be used to 
//      initialize a different KMDF object (not necessarily a device object).
//
//      The initializer object is a child of the KMDF driver object and is 
//      deleted by KMDF when the driver object is deleted. This means that by 
//      default the initializer object remains in memory until the driver is 
//      unloaded. However, the driver layer can proactively delete the 
//      initializer object using the WdfObjectDelete method when it has finished
//      using it.
//
// Arguments:
//      Initializer - Pointer to a location that receives a handle to the new
//          initializer object.
//
// Return value:
//      An NTSTATUS value representing success or failure of the function.
//
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
PfhInitializerCreate(
    _Out_ WDFOBJECT * Initializer
    );

//
// PfhAssignWdmPowerIrpPreProcessCallback
// ======================================
// Routine description:
//      This routine is invoked by the driver layer to enable the power 
//      framework helper library to register a WDM preprocess callback function
//      to handle power IRPs before KMDF has a chance to process them. The 
//      driver layer must invoke this routine before creating the KMDF device 
//      object. 
//
//      This routine must be invoked for any device whose power management is 
//      done using the power framework helper library, even if the driver layer
//      is not interested in preprocessing power IRPs for that device.
//
//      If the driver layer also wishes to pre-process power IRPs before KMDF
//      has a chance to preprocess them, it can specify this via the arguments
//      to this routine. The driver layer must *not* directly call the 
//      WdfDeviceInitAssignWdmIrpPreprocessCallback method to register a pre-
//      process callback routine for power IRPs, i.e. IRPs with a major function
//      code of IRP_MJ_POWER. Instead it must use 
//      PfhAssignWdmPowerIrpPreProcessCallback to accomplish this. However, for
//      preprocessing IRPs with other major function codes, the driver should 
//      use WdfDeviceInitAssignWdmIrpPreprocessCallback.
//
//      If the driver layer specifies a preprocess callback via 
//      PfhAssignWdmPowerIrpPreProcessCallback, it gets to preprocess the power
//      IRP before the power framework helper library preprocesses it. Once the
//      driver layer is done preprocessing the power IRP, it must call
//      PfhWdmDispatchPreprocessedPowerIrp to allow the power framework helper
//      library and eventually KMDF to process the IRP. The driver layer must 
//      *not* directly call WdfDeviceWdmDispatchPreprocessedIrp to forward a
//      pre-processed power IRP, i.e. an IRP with major function code 
//      IRP_MJ_POWER, to KMDF. Preprocessed IRPs with other major function codes
//      should be forwarded to KMDF via WdfDeviceWdmDispatchPreprocessedIrp.
//
// Arguments:
//      Initializer - Handle to the initializer object that is being used to 
//          initialize the power framework helper library's device object 
//          settings.
//
//      DeviceInit - Pointer to a WDFDEVICE_INIT structure
//
//      EvtDeviceWdmPowerIrpPreprocess - Pointer to the driver layer's 
//          EVT_WDFDEVICE_WDM_IRP_PREPROCESS callback function for power IRPs. 
//          This argument is optional. If the driver layer does not want to 
//          preprocess power IRPs, it can specify NULL.
//
//      MinorFunctions - Pointer to an array of one or more minor function codes
//          for IRP_MJ_POWER that the driver layer wants to pre-process. This 
//          argument is optional. If the driver layer does not want to 
//          preprocess power IRPs, it can specify NULL.
//
//      NumMinorFunctions - Number of minor function codes that are contained in
//          the MinorFunctions array.
//
// Return value:
//      An NTSTATUS value representing success or failure of the function.
//
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
PfhAssignWdmPowerIrpPreProcessCallback(
    _In_ WDFOBJECT Initializer,
    _In_ PWDFDEVICE_INIT DeviceInit,
    _In_opt_ PFN_WDFDEVICE_WDM_IRP_PREPROCESS EvtDeviceWdmPowerIrpPreprocess,
    _In_reads_opt_(NumMinorFunctions) PUCHAR MinorFunctions,
    _In_ ULONG NumMinorFunctions
    );

//
// PfhWdmDispatchPreprocessedPowerIrp
// ==================================
// Routine description:
//      This routine is invoked by the driver layer to forward a pre-processed
//      power IRP to the power framework helper library. It is similar to KMDF's
//      WdfDeviceWdmDispatchPreprocessedIrp method. For power IRPs, the driver 
//      layer must use PfhWdmDispatchPreprocessedPowerIrp instead of 
//      WdfDeviceWdmDispatchPreprocessedIrp. The power framework helper library 
//      eventually forwards it to KMDF after pre-processing it.
//
// Arguments:
//      Device - Handle to a KMDF device object
//
//      Irp - Pointer to the pre-processed IRP
//
// Return value:
//      An NTSTATUS value that the power framework helper library provides as a
//      result of processing the IRP. The driver *must* use this return value as
//      return value for its EvtDeviceWdmPowerIrpPreprocess callback function.
//
_IRQL_requires_max_(DISPATCH_LEVEL)
NTSTATUS
PfhWdmDispatchPreprocessedPowerIrp(
    _In_ WDFDEVICE Device,
    _Inout_ PIRP Irp
    );

//
// PfhInterceptWdfPnpPowerEventCallbacks
// =====================================
// Routine description:
//      This routine is invoked by the driver layer to enable the power 
//      framework helper library to register its PNP and power event callbacks
//      with KMDF. If the driver layer has specified a callback for a PNP or 
//      power event that the power framework helper library is also interested 
//      in, then the power framework helper library saves the driver layer's 
//      callback and invokes it from when KMDF invokes its own callback. The
//      driver layer must call PfhInterceptWdfPnpPowerEventCallbacks after it 
//      has initialized the WDF_PNPPOWER_EVENT_CALLBACKS structure but before it
//      has called WdfDeviceInitSetPnpPowerEventCallbacks.
//
//      This routine must be invoked for any device whose power management is 
//      done using the power framework helper library, even if the driver layer
//      does not want to specify any PNP or power event callbacks for that 
//      device. After invoking this routine, the driver layer must invoke 
//      WdfDeviceInitSetPnpPowerEventCallbacks so that the power framework 
//      helper library's callbacks are registered with KMDF.
//
// Arguments:
//      Initializer - Handle to the initializer object that is being used to 
//          initialize the power framework helper library's device object 
//          settings.
//
//      DriverLayerPnpPowerCallbacks - Pointer to a caller-initialized 
//          WDF_PNPPOWER_EVENT_CALLBACKS structure.
//
// Return value:
//      None
//
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
PfhInterceptWdfPnpPowerEventCallbacks(
    _In_ WDFOBJECT Initializer,
    _Inout_ PWDF_PNPPOWER_EVENT_CALLBACKS DriverLayerPnpPowerCallbacks
    );
    
//
// PfhSetPoHandleAvailabilityCallbacks
// ===================================
// Routine description:
//      This routine is invoked by the driver layer to receive the POHANDLE that
//      represents the device's registration with the power framework and to be
//      notified when the handle is about to become invalid because of an 
//      impending unregistration. The POHANDLE received in this manner can be 
//      used to directly invoke power framework routines. However, the driver 
//      layer must *not* invoke the following power framework routines because 
//      they can interfere with the operation of the power framework helper 
//      library:
//          PoFxStartDevicePowerManagement
//          PoFxUnregisterDevice 
//
//      PfhSetPoHandleAvailabilityCallbacks must be invoked before the driver
//      layer has created the KMDF device object. The driver layer need not 
//      invoke this routine if it is not interested in using the POHANDLE 
//      directly.
//
// Arguments:
//      Initializer - Handle to the initializer object that is being used to 
//          initialize the power framework helper library's device object 
//          settings.
//
//      EvtPfhPoHandleAvailable - Pointer to the driver layer's 
//          PFH_CALLBACK_POHANDLE_AVAILABLE callback function.
//
//      EvtPfhPoHandleUnavailable - Pointer to the driver layer's 
//          PFH_CALLBACK_POHANDLE_UNAVAILABLE callback function.
//
// Return value:
//      None
//
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
PfhSetPoHandleAvailabilityCallbacks(
    _In_ WDFOBJECT Initializer,
    _In_ PPFH_CALLBACK_POHANDLE_AVAILABLE PfhCallbackPoHandleAvailable,
    _In_ PPFH_CALLBACK_POHANDLE_UNAVAILABLE PfhCallbackPoHandleUnavailable
    );

//
// The following enum defines the S0-idle power management configurations that 
// are supported by the power framework helper library
//
typedef enum _PFH_S0IDLE_CONFIG {
    //
    // S0-idle power management is not supported for the device
    //
    PfhS0IdleNotSupported,

    //
    // S0-idle power management is supported for the device and the driver can 
    // access pageable data during the device's power transitions. This implies
    // that the device can *never* be in the paging path.
    //
    PfhS0IdleSupportedPowerPageable,
    
    //
    // S0-idle power management is supported for the device and the driver 
    // *cannot* access pageable data during the device's power transitions. This
    // implies that the device can be in the paging path.
    //
    // If this configuration is chosen, the driver layer is responsible for 
    // supplying a PO_FX_DEVICE_POWER_REQUIRED_CALLBACK callback. This callback 
    // will be invoked when the power framework instructs the driver to power up
    // the device. In this callback, the driver layer must initiate device power
    // up. When the device has powered up, the driver layer must call 
    // PoFxReportDevicePoweredOn to inform the power framework about it. The 
    // driver layer should accomplish this in the following manner:
    //    - In the PO_FX_DEVICE_POWER_REQUIRED_CALLBACK callback it should queue
    //      work to its own worker thread (and not a system worker thread) to 
    //      make a blocking call to WdfDeviceStopIdle. Since this is a blocking
    //      call, the driver layer cannot make it directly from within 
    //      PO_FX_DEVICE_POWER_REQUIRED_CALLBACK for a couple of reasons. First,
    //      the PO_FX_DEVICE_POWER_REQUIRED_CALLBACK callback can be invoked at
    //      dispatch level. Second, the PO_FX_DEVICE_POWER_REQUIRED_CALLBACK
    //      callback might get invoked in the context of the I/O dispatch 
    //      routine of a power-managed queue and a blocking call to 
    //      WdfDeviceStopIdle in such a context can lead to a deadlock. Hence,
    //      the blocking call to WdfDeviceStopIdle must be made from a worker 
    //      thread. The driver cannot use a system worker thread because queuing
    //      a system work item to the system worker thread can cause pageable 
    //      data to be accessed. But by definition, pageable data cannot be 
    //      accessed in the PfhS0IdleSupportedNotPowerPageable configuration. 
    //      Hence the need for a driver-created worker thread.
    //    - Once the blocking call to WdfDeviceStopIdle has returned, the device
    //      is guaranteed to have returned to D0 and/or to remain in D0.
    //      Therefore the driver layer should call PoFxReportDevicePoweedOn at
    //      this point. If the call to WdfDeviceStopIdle failed, KMDF would have
    //      already declared the device to be in a failed state and initiated a
    //      PNP removal. However, even in the failure case, it is necessary to
    //      call PoFxReportDevicePoweredOn in order to unblock the power 
    //      framework and move it to a consistent state.
    //
    PfhS0IdleSupportedNotPowerPageable
    
} PFH_S0IDLE_CONFIG, *PPFH_S0IDLE_CONFIG;

//
// PfhSetS0IdleConfiguration
// =========================
// Routine description:
//      This routine is invoked by the driver layer to specify whether or not
//      the device supports S0-idle power management. PfhSetS0IdleConfiguration
//      must be invoked before the driver layer has created the KMDF device 
//      object. If the driver layer does not invoke this routine, the power 
//      framework helper library assumes the device's S0-idle power management 
//      configuration to be PfhS0IdleNotSupported.
//
// Arguments:
//      Initializer - Handle to the initializer object that is being used to 
//          initialize the power framework helper library's device object 
//          settings.
//      S0IdleConfig - A PFH_S0IDLE_CONFIG value that specifies the device's
//          S0-idle power management configuration.
//
// Return value:
//      None
//
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
PfhSetS0IdleConfiguration(
    _In_ WDFOBJECT Initializer,
    _In_ PFH_S0IDLE_CONFIG S0IdleConfig
    );

//
// PfhInitializeDeviceSettings
// ===========================
// Routine description:
//      This routine is invoked by the driver layer to enable the power 
//      framework helper library to initialize the latter's settings for a KMDF
//      device object. The driver layer must invoke this routine for any KMDF
//      device object whose power management is done using the power framework
//      helper library. 
//
//      This routine must be invoked after the KMDF device object has been 
//      created and before the initializer object that is being used to 
//      initialize the device object is reused to initialize some other KMDF 
//      object. After calling this routine, the initializer object can be used 
//      for initializing other KMDF objects if needed.
//
// Arguments:
//      Device - Handle to the KMDF device object
//
//      Initializer - Handle to the initializer object that is being used to 
//          initialize the power framework helper library's device object 
//          settings.
//
// Return value:
//      An NTSTATUS value representing success or failure of the function.
//
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
PfhInitializeDeviceSettings(
    _In_ WDFDEVICE Device,
    _In_ WDFOBJECT Initializer
    );

//
// PfhInitializePowerFrameworkSettings
// ===================================
// Routine description:
//      This routine is invoked by the driver layer to specify its power 
//      framework settings. These settings are used by the power framework 
//      helper library when it registers with the power framework.
//      
//      This routine must be invoked before the driver layer's 
//      EvtDeviceSelfManagedIoInit callback is invoked or from within the driver
//      layer's EvtDeviceSelfManagedIoInit callback. Typically, the driver layer
//      would invoke this routine from with its EvtDriverDeviceAdd callback or
//      from one of the following callbacks that are invoked the first time a 
//      device is being started:
//          EvtDevicePrepareHardware
//          EvtDeviceD0Entry
//          EvtDeviceD0EntryPostInterruptsEnabled
//          EvtDeviceSelfManagedIoInit
//
//      The driver layer must not invoke PfhInitializePowerFrameworkSettings 
//      more than once for a given device. Note that a device might be started 
//      more than once if a resource rebalance occurs while the device is 
//      operational. In this case, the EvtDevicePrepareHardware, 
//      EvtDeviceD0Entry and EvtDeviceD0EntryPostInterruptsEnabled callbacks can
//      be invoked more than once. Therefore, if the driver layer chooses to 
//      call PfhInitializePowerFrameworkSettings from within one of these 
//      callbacks, it must take care to call it only when the callback is 
//      invoked for the first time.
//
// Arguments:
//      Device - Handle to the KMDF device object
//
//      PoFxDeviceInfo - Pointer to a caller-initialized 
//          PO_FX_DEVICE structure that contains the driver layer's power 
//          framework settings.
//
// Return value:
//      An NTSTATUS value representing success or failure of the function.
//
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
PfhInitializePowerFrameworkSettings(
    _In_ WDFDEVICE Device,
    _In_ PPO_FX_DEVICE PoFxDeviceInfo
    );

//
// PfhInterceptComponentQueueConfig
// ================================
// Routine description:
//      This routine is invoked by the driver layer to enable the power 
//      framework helper library to register its queue callbacks with KMDF. If
//      the driver layer has specified a queue callback that the power framework
//      helper library is also interested in, then the power framework helper 
//      library saves the driver layer's callback and invokes it from when KMDF
//      invokes its own callback. The driver layer must call 
//      PfhInterceptComponentQueueConfig after it has initialized the 
//      WDF_IO_QUEUE_CONFIG structure but before it has created the KMDF queue 
//      object. 
//
//      This routine must be invoked for each of the driver layer's component 
//      queues. Component queues are described in the routine description for 
//      PfhInitializeComponentQueueSettings. 
//
// Arguments:
//      Initializer - Handle to the initializer object that is being used to 
//          initialize the power framework helper library's queue object 
//          settings.
//
//      DriverLayerQueueConfig - Pointer to a caller-initialized 
//          WDF_IO_QUEUE_CONFIG structure.
//
// Return value:
//      None
//
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
PfhInterceptComponentQueueConfig(
    _In_ WDFOBJECT Initializer,
    _Inout_ PWDF_IO_QUEUE_CONFIG DriverLayerQueueConfig
    );

//
// PfhSetComponentForComponentQueue
// ================================
// Routine description:
//      This routine is invoked by the driver layer to specify the component
//      that is associated with a component queue. The current implementation of
//      the power framework helper library does not support associating a queue
//      with more than one component, so this routine must be called no more 
//      than once for a given queue.
//
//      This routine must be invoked for each queue that acts as a component 
//      queue. Component queues are described in the routine description for 
//      PfhInitializeComponentQueueSettings. 
//
// Arguments:
//      Initializer - Handle to the initializer object that is being used to 
//          initialize the power framework helper library's queue object 
//          settings.
//
//      Component - Component associated with the queue.
//
// Return value:
//      None
//
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
PfhSetComponentForComponentQueue(
    _In_ WDFOBJECT Initializer,
    _In_ ULONG Component
    );

//
// PfhInitializeComponentQueueSettings
// ===================================
// Routine description:
//      This routine is invoked by the driver layer to enable the power 
//      framework helper library to initialize the latter's settings for a KMDF
//      queue object. 
//
//      The driver layer must invoke this routine for any KMDF queue object that
//      acts as a component queue. A component queue is a queue whose state is 
//      tied to the active/idle state for a component. The queue can dispatch 
//      requests when the component is active and cannot dispatch requests when
//      the component is idle. A component queue must be power-managed. The 
//      driver layer must not explicitly change the state of any of its 
//      component queues.
//
//      This routine must be invoked after the KMDF queue object has been 
//      created and before the initializer object that is being used to 
//      initialize the queue object is reused to initialize some other KMDF 
//      object. After calling this routine, the initializer object can be used
//      for initializing other KMDF objects if needed.
//
// Arguments:
//      Queue - Handle to the KMDF queue object for the component queue
//
//      Initializer - Handle to the initializer object that is being used to 
//          initialize the power framework helper library's queue object 
//          settings.
//
// Return value:
//      An NTSTATUS value representing success or failure of the function.
//
_IRQL_requires_max_(DISPATCH_LEVEL)
NTSTATUS
PfhInitializeComponentQueueSettings(
    _In_ WDFQUEUE Queue,
    _In_ WDFOBJECT Initializer
    );

//
// PfhRegisterDeviceProactive
// ==========================
// Routine description:
//      This routine is invoked by the driver layer to in order to proactively
//      register with the power framework. By default, the power framework 
//      helper library registers with the power framework in its 
//      EvtDeviceSelfManagedIoInit allback, after it has invoked the driver 
//      layer's EvtDeviceSelfManagedIoInit callback (if present). If the driver
//      layer is satisfied with this default behavior, it need not invoke 
//      PfhRegisterDeviceProactive at all. 
//
//      However, if the driver layer needs to interact with the power framework
//      before the point at which the power framework helper library registers 
//      by default, it can proactively register by calling 
//      PfhRegisterDeviceProactive. Before calling PfhRegisterDeviceProactive, 
//      the driver layer must ensure that it has already provided its power 
//      framework settings to the power framework helper library by calling 
//      PfhInitializePowerFrameworkSettings.
//
//      The power framework helper library unregisters with the power framework
//      helper library during device removal, in the EvtDeviceSelfManagedIoFlush
//      callback. 
//
//      The driver layer must ensure that it does not call 
//      PfhRegisterDeviceProactive if the device is already registered with 
//      the power framework. This means that if the driver layer calls 
//      PfhRegisterDeviceProactive in one of the following callbacks, it needs
//      to handle cases where the callback is called more than once. 
//          EvtDevicePrepareHardware
//          EvtDeviceD0Entry
//          EvtDeviceD0EntryPostInterruptsEnabled
//
//      If the device is being started for the first time or if the device is a 
//      PDO that is being restarted after being removed, the above callbacks 
//      would get invoked while the device is not yet registered with the power
//      framework.
//
//      If the device is being restarted after being stopped for resource 
//      rebalance, the above callbacks would get invoked while the device is 
//      already registered with the power framework.
//
//      If the device returns to the working state (D0) after being in a low-
//      power state (Dx), then EvtDeviceD0Entry and 
//      EvtDeviceD0EntryPostInterruptsEnabled would get invoked while the device
//      is already registered with the power framework (and 
//      EvtDevicePrepareHardware is not invoked at all).
//
//      Therefore, the driver layer must be careful to invoke 
//      PfhRegisterDeviceProactive only if the device is not already registered
//      with the power framework. It can determine whether or not the device is 
//      already registered by supplying the PFH_CALLBACK_POHANDLE_AVAILABLE and 
//      PFH_CALLBACK_POHANDLE_UNAVAILABLE callbacks via 
//      PfhSetPoHandleAvailabilityCallbacks.
//
//      Note that even if the driver layer invokes PfhRegisterDeviceProactive 
//      more than once, it must invoke PfhInitializePowerFrameworkSettings only 
//      once. The power framework settings that are supplied once get used for 
//      subsequent registrations as well.
//
// Arguments:
//      Device - Handle to the KMDF device object
//
// Return value:
//      An NTSTATUS value representing success or failure of the function.
//
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
PfhRegisterDeviceProactive(
    _In_ WDFDEVICE Device
    );

//
// PfhForwardRequestToQueue
// ========================
// Routine description:
//      This routine is invoked by the driver layer to forward a request to an
//      I/O queue. It is similar to the WdfRequestForwardToIoQueue method. At a
//      minimum, the driver layer must use PfhForwardRequestToQueue instead
//      of WdfRequestForwardToIoQueue when forwarding a request to or from a 
//      component queue. However, the driver layer can use 
//      PfhForwardRequestToQueue to forward requests between any two queues.
//      The driver layer might find it convenient to always use 
//      PfhForwardRequestToQueue instead of using it only in some places and 
//      using WdfRequestForwardToIoQueue in others.
//
// Arguments:
//      Request - Handle to the KMDF request object for the request that is to 
//          be forwarded.
//
//      Queue - Handle to the KMDF queue object for the destination queue
//
// Return value:
//      None
//
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
PfhForwardRequestToQueue(
    _In_ WDFREQUEST Request,
    _In_ WDFQUEUE Queue
    );

//
// PfhCompleteRequest
// ==================
// Routine description:
//      This routine is invoked by the driver layer to complete a request. It is
//      similar to the WdfRequestCompleteWithInformation method. At a minimum, 
//      the driver layer must use PfhCompleteRequest instead of 
//      WdfRequestComplete/WdfRequestCompleteWithInformation when it is 
//      completing a request that is associated with a component queue. However,
//      the driver layer can use PfhCompleteRequest to complete any request.
//      The driver layer might find it convenient to always use 
//      PfhCompleteRequest instead of using it only in some places and using
//      WdfRequestComplete/WdfRequestCompleteWithInformation in others.
//
// Arguments:
//      Request - Handle to the KMDF request object for the request that is to 
//          be completed.
//
//      Status - An NTSTATUS value that is used as the completion status of the 
//          request.
//
//      Information - Driver-defined completion status information for the 
//          request, such as the number of bytes that were transferred.
//
// Return value:
//      None
//
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
PfhCompleteRequest(
    _In_ WDFREQUEST Request,
    _In_ NTSTATUS Status,
    _In_ ULONG_PTR Information
    );

#endif // _WDFPOFX_H_