ReactOS 0.4.15-dev-7788-g1ad9096
fxpkgpnp.cpp
Go to the documentation of this file.
1/*++
2
3
4Copyright (c) Microsoft. All rights reserved.
5
6Module Name:
7
8 FxPkgPnp.cpp
9
10Abstract:
11
12 This module implements the pnp IRP handlers for the driver framework.
13
14Author:
15
16
17
18Environment:
19
20 Both kernel and user mode
21
22Revision History:
23
24
25
26
27
28--*/
29
30#include "pnppriv.hpp"
31
32#include <initguid.h>
33#include <wdmguid.h>
34
35extern "C" {
36
37#if defined(EVENT_TRACING)
38#include "FxPkgPnp.tmh"
39#endif
40
41}
42
43/* dc7a8e51-49b3-4a3a-9e81-625205e7d729 */
45 0xdc7a8e51, 0x49b3, 0x4a3a, { 0x9e, 0x81, 0x62, 0x52, 0x05, 0xe7, 0xd7, 0x29 }
46};
47
49 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
52 ) :
53 FxPackage(FxDriverGlobals, Device, Type)
54{
55 ULONG i;
56
60
61 //
62 // Initialize the structures to the default state and then override the
63 // non WDF std default values to the unsupported / off values.
64 //
72
82 ;
83
86
95 ;
96
99
103
105 for (i = 0; i < PowerSystemMaximum; i++) {
107 }
108
112
123
128
129 //
130 // We only set the pending child count to 1 once we know we have successfully
131 // created an FxDevice and initialized it fully. If we delete an FxDevice
132 // which is half baked, it cannot have any FxChildLists which have any
133 // pending children on them.
134 //
136
138
141
142 m_Failed = FALSE;
144
148
153
157
159
161
164
172
176
178
179#if (FX_CORE_MODE==FX_CORE_KERNEL_MODE)
180 //
181 // Interrupt APIs for Vista and forward
182 //
185
186 //
187 // Interrupt APIs for Windows 8 and forward
188 //
191
192#endif
193
195
197}
198
200{
202
204
205 //
206 // We should either have zero pending children or we never made it out of
207 // the init state during a failed WDFDEVICE create or failed EvtDriverDeviceAdd
208 //
211
212
214 while (ple != NULL) {
216
218
219 //
220 // Advance to the next before deleting the current
221 //
222 ple = ple->Next;
223
224 //
225 // No longer in the list
226 //
227 pDI->m_Entry.Next = NULL;
228
229 delete pDI;
230 }
232
233 if (m_DmaEnablerList != NULL) {
234 delete m_DmaEnablerList;
236 }
237
238 if (m_RemovalDeviceList != NULL) {
239 delete m_RemovalDeviceList;
241 }
242
246 }
247
248 if (m_PnpStateCallbacks != NULL) {
249 delete m_PnpStateCallbacks;
250 }
251
254 }
255
258 }
259
263 }
264
265 if (m_EnumInfo != NULL) {
266 delete m_EnumInfo;
268 }
269
270 if (m_Resources != NULL) {
271 m_Resources->RELEASE(this);
273 }
274
275 if (m_ResourcesRaw != NULL) {
276 m_ResourcesRaw->RELEASE(this);
278 }
279
281}
282
285 VOID
286 )
287{
289
290 //
291 // All of the interrupts were freed during this object's dispose path. This
292 // is because all of the interrupts were attached as children to this object.
293 //
294 // It is safe to just reinitialize the list head.
295 //
297
299
300 //
301 // A derived class can insert an embedded FxQueryInterface into the QI list,
302 // so clear out the list before the destructor chain runs. (The derived
303 // class will be destructed first, as such, the embedded FxQueryInterface
304 // will also destruct first and complain it is still in a list.
305 //
307
308 //
309 // Clear out the head while holding the lock so that we synchronize against
310 // processing a QI while deleting the list.
311 //
313
315
316 while (ple != NULL) {
317 FxQueryInterface* pQI;
318
320
321 //
322 // Advance before we potentiall free the structure
323 //
324 ple = ple->Next;
325
326 //
327 // FxQueryInterface's destructor requires Next be NULL
328 //
329 pQI->m_Entry.Next = NULL;
330
331 if (pQI->m_EmbeddedInterface == FALSE) {
332 delete pQI;
333 }
334 }
335
336#if (FX_CORE_MODE==FX_CORE_KERNEL_MODE)
338#endif
339
340 //
341 // Call up the hierarchy
342 //
343 return FxPackage::Dispose(); // __super call
344}
345
346
351 )
352
353/*++
354
355Routine Description:
356
357 This function initializes state associated with an instance of FxPkgPnp.
358 This differs from the constructor because it can do operations which
359 will fail, and can return failure. (Constructors can't fail, they can
360 only throw exceptions, which we can't deal with in this kernel mode
361 environment.)
362
363Arguments:
364
365 DeviceInit - Struct that the driver initialized that contains defaults.
366
367Returns:
368
369 NTSTATUS
370
371--*/
372
373{
376
378
379 m_ReleaseHardwareAfterDescendantsOnFailure = (DeviceInit->ReleaseHardwareOrderOnFailure ==
381
383 if (!NT_SUCCESS(status)) {
386 "Could not initialize QueryInterfaceLock for "
387 "WDFDEVICE %p, %!STATUS!",
389 return status;
390 }
391
393 if (!NT_SUCCESS(status)) {
396 "Could not initialize DeviceInterfaceLock for "
397 "WDFDEVICE %p, %!STATUS!",
399 return status;
400 }
401
402 //
403 // Initialize preallocated events for UM
404 // (For KM, events allocated on stack are used since event initialization
405 // doesn't fail in KM)
406 //
407#if (FX_CORE_MODE==FX_CORE_USER_MODE)
408
410 if (!NT_SUCCESS(status)) {
413 "Could not initialize cleanup event for "
414 "WDFDEVICE %p, %!STATUS!",
416 return status;
417 }
418
420 if (!NT_SUCCESS(status)) {
423 "Could not initialize remove event for "
424 "WDFDEVICE %p, %!STATUS!",
426 return status;
427 }
428#endif
429
430 if (DeviceInit->IsPwrPolOwner()) {
433
436 }
437
439 if (!NT_SUCCESS(status)) {
440 return status;
441 }
442
443#if (FX_CORE_MODE==FX_CORE_KERNEL_MODE)
445#endif
446 }
447
448 //
449 // we will change the access flags on the object later on when we build up
450 // the list from the wdm resources
451 //
454 m_Device,
457 if (!NT_SUCCESS(status)) {
458 return status;
459 }
460
463 m_Device);
464
465 //
466 // This should never fail
467 //
469 if (!NT_SUCCESS(status)) {
472 return status;
473 }
474
475 m_Resources->ADDREF(this);
476
477 //
478 // we will change the access flags on the object later on when we build up
479 // the list from the wdm resources
480 //
483 m_Device,
486 if (!NT_SUCCESS(status)) {
487 return status;
488 }
489
492 m_Device);
493
494 //
495 // This should never fail
496 //
498 if (!NT_SUCCESS(status)) {
501 return status;
502 }
503
504 m_ResourcesRaw->ADDREF(this);
505
506 status = RegisterCallbacks(&DeviceInit->PnpPower.PnpPowerEventCallbacks);
507 if (!NT_SUCCESS(status)) {
508 return status;
509 }
510
511 if (IsPowerPolicyOwner()) {
512 RegisterPowerPolicyCallbacks(&DeviceInit->PnpPower.PolicyEventCallbacks);
513 }
514
515 return status;
516}
517
522 )
523
524/*++
525
526Routine Description:
527
528 This is the main dispatch handler for the pnp package. This method is
529 called by the framework manager when a PNP or Power IRP enters the driver.
530 This function will dispatch the IRP to a function designed to handle the
531 specific IRP.
532
533Arguments:
534
535 Device - a pointer to the FxDevice
536
537 Irp - a pointer to the FxIrp
538
539Returns:
540
541 NTSTATUS
542
543--*/
544
545{
547 FxIrp irp(Irp);
548
549#if (FX_CORE_MODE==FX_CORE_KERNEL_MODE)
551#endif
552
554
555 switch (irp.GetMinorFunction()) {
564 case IRP_MN_EJECT:
568 "WDFDEVICE 0x%p !devobj 0x%p, IRP_MJ_PNP, %!pnpmn! IRP 0x%p",
572 break;
573
577 "WDFDEVICE 0x%p !devobj 0x%p, IRP_MJ_PNP, %!pnpmn! "
578 "type %!DEVICE_RELATION_TYPE! IRP 0x%p",
583 break;
584
585 default:
588 "WDFDEVICE 0x%p !devobj 0x%p, IRP_MJ_PNP, %!pnpmn! IRP 0x%p",
592 break;
593 }
594
596 status = (*GetDispatchPnp()[irp.GetMinorFunction()])(this, &irp);
597 }
598 else {
599 //
600 // For Pnp IRPs we don't understand, just forget about them
601 //
603 }
604 }
605 else {
606 //
607 // If this isn't a PnP Irp, it must be a power irp.
608 //
609 switch (irp.GetMinorFunction()) {
610 case IRP_MN_WAIT_WAKE:
611 case IRP_MN_SET_POWER:
615 "WDFDEVICE 0x%p !devobj 0x%p IRP_MJ_POWER, %!pwrmn! "
616 "IRP 0x%p for %!SYSTEM_POWER_STATE! (S%d)",
622 }
623 else {
626 "WDFDEVICE 0x%p !devobj 0x%p IRP_MJ_POWER, %!pwrmn! "
627 "IRP 0x%p for %!DEVICE_POWER_STATE!",
632 }
633 break;
634
635 default:
638 "WDFDEVICE 0x%p !devobj 0x%p IRP_MJ_POWER, %!pwrmn! IRP 0x%p",
642 break;
643 }
644
646
649 }
650 else {
651 //
652 // For Power IRPs we don't understand, just forget about them
653 //
655 }
656 }
657
658 return status;
659}
660
663 __in PNP_DEVICE_STATE PnpDeviceState
664 )
665
666/*++
667
668Routine Description:
669
670 This function handled IRP_MN_QUERY_DEVICE_STATE. Most of the bits are
671 just copied from internal Framework state.
672
673Arguments:
674
675 PnpDeviceState - Bitfield that will be returned to the sender of the IRP.
676
677Returns:
678
679 NTSTATUS
680
681--*/
682
683{
684 LONG state;
685
687
688 //
689 // Return device state set by driver.
690 //
691 SET_PNP_DEVICE_STATE_BIT(&PnpDeviceState,
693 state,
694 Disabled);
695 SET_PNP_DEVICE_STATE_BIT(&PnpDeviceState,
697 state,
698 DontDisplayInUI);
699 SET_PNP_DEVICE_STATE_BIT(&PnpDeviceState,
701 state,
702 Failed);
703 SET_PNP_DEVICE_STATE_BIT(&PnpDeviceState,
705 state,
706 NotDisableable);
707 SET_PNP_DEVICE_STATE_BIT(&PnpDeviceState,
709 state,
710 Removed);
711 SET_PNP_DEVICE_STATE_BIT(&PnpDeviceState,
713 state,
714 ResourcesChanged);
715
717 LONG caps;
718
719 //
720 // Mask off all caps except for NoDispalyInUI
721 //
723
724 //
725 // If the driver didn't specify pnp state, see if they specified no
726 // display as a capability. For raw PDOs and just usability, it is not
727 // always clear to the driver writer that they must set both the pnp cap
728 // and the pnp state for the no display in UI property to stick after
729 // the device has been started.
730 //
731 if (caps == FxPnpCapNoDisplayInUITrue) {
732 PnpDeviceState |= PNP_DEVICE_DONT_DISPLAY_IN_UI;
733 }
734 else if (caps == FxPnpCapNoDisplayInUIFalse) {
735 PnpDeviceState &= ~PNP_DEVICE_DONT_DISPLAY_IN_UI;
736 }
737 }
738
739 //
740 // Return device state maintained by frameworks.
741 //
742 if (IsInSpecialUse()) {
743 PnpDeviceState |= PNP_DEVICE_NOT_DISABLEABLE;
744 }
745
746 //
747 // If there is an internal failure, then indicate that up to pnp.
748 //
750 PnpDeviceState |= PNP_DEVICE_FAILED;
751 }
752
753 return PnpDeviceState;
754}
755
760 )
761/*++
762
763Routine Description:
764 Handles a query device relations for the bus relations type (all other types
765 are handled by HandleQueryDeviceRelations). This function will call into
766 each of the device's FxChildList objects to process the request.
767
768Arguments:
769 Irp - the request contain the query device relations
770
771Return Value:
772 NTSTATUS
773
774 --*/
775{
777 PDEVICE_RELATIONS pRelations;
779 NTSTATUS status, listStatus;
780 BOOLEAN changed;
781
782 //
783 // Before we do anything, callback into the driver
784 //
786
787 //
788 // Default to success unless list processing fails
789 //
791
792 //
793 // Keep track of changes made by any list object. If anything changes,
794 // remember it for post-processing.
795 //
796 changed = FALSE;
797
798 pRelations = (PDEVICE_RELATIONS) Irp->GetInformation();
799
800 if (m_EnumInfo != NULL) {
802
803 pList->LockForEnum(GetDriverGlobals());
804 }
805 else {
806 pList = NULL;
807 }
808
809 ple = NULL;
810 while (pList != NULL && (ple = pList->GetNextEntry(ple)) != NULL) {
811 FxChildList* pChildList;
812
813 pChildList = FxChildList::_FromEntry(ple);
814
815 //
816 // ProcessBusRelations will free and reallocate pRelations if necessary
817 //
818 listStatus = pChildList->ProcessBusRelations(&pRelations);
819
820 //
821 // STATUS_NOT_SUPPORTED is a special value. It indicates that the call
822 // to ProcessBusRelations did not modify pRelations in any way.
823 //
824 if (listStatus == STATUS_NOT_SUPPORTED) {
825 continue;
826 }
827
828
829 if (!NT_SUCCESS(listStatus)) {
832 "WDFDEVICE %p, WDFCHILDLIST %p returned %!STATUS! from "
833 "processing bus relations",
834 m_Device->GetHandle(), pChildList->GetHandle(), listStatus);
835 status = listStatus;
836 break;
837 }
838
839 //
840 // We updated pRelations, change the status later
841 //
842 changed = TRUE;
843 }
844
845 //
846 // By checking for NT_SUCCESS(status) below we account for
847 // both the cases - list changed, as well as list unchanged but possibly
848 // children being reported missing (that doesn't involve list change).
849 //
850 if (NT_SUCCESS(status)) {
851
852 ple = NULL;
853 while (pList != NULL && (ple = pList->GetNextEntry(ple)) != NULL) {
854 FxChildList* pChildList;
855
856 pChildList = FxChildList::_FromEntry(ple);
857
858 //
859 // invoke the ReportedMissing callback for for children that are
860 // being reporte missing
861 //
862 pChildList->InvokeReportedMissingCallback();
863 }
864 }
865
866 if (pList != NULL) {
867 pList->UnlockFromEnum(GetDriverGlobals());
868 }
869
870 if (NT_SUCCESS(status) && changed == FALSE) {
871 //
872 // Went through the entire list of FxChildList objects, but no object
873 // modified the pRelations, so restore the caller's NTSTATUS.
874 //
875 status = Irp->GetStatus();
876 }
877
878 //
879 // Re-set the relations into the structure so that any changes that any call
880 // to FxChildList::ProcessBusRelations takes effect and is reported.
881 //
882 Irp->SetInformation((ULONG_PTR) pRelations);
883 Irp->SetStatus(status);
884
887 "WDFDEVICE %p, returning %!STATUS! from processing bus relations",
889 );
890
891 if (NT_SUCCESS(status) && pRelations != NULL) {
892 ULONG i;
893
896 "WDFDEVICE %p returning %d devices in relations %p",
897 m_Device->GetHandle(), pRelations->Count, pRelations
898 );
899
900 //
901 // Try to not consume an IFR entry per DO reported. Instead, report up
902 // to 4 at a time.
903 //
904 for (i = 0; i < pRelations->Count && GetDriverGlobals()->FxVerboseOn; i += 4) {
905 if (i + 3 < pRelations->Count) {
908 "PDO %p PDO %p PDO %p PDO %p",
909 pRelations->Objects[i],
910 pRelations->Objects[i+1],
911 pRelations->Objects[i+2],
912 pRelations->Objects[i+3]
913 );
914 }
915 else if (i + 2 < pRelations->Count) {
918 "PDO %p PDO %p PDO %p",
919 pRelations->Objects[i],
920 pRelations->Objects[i+1],
921 pRelations->Objects[i+2]
922 );
923 }
924 else if (i + 1 < pRelations->Count) {
927 "PDO %p PDO %p",
928 pRelations->Objects[i],
929 pRelations->Objects[i+1]
930 );
931 }
932 else {
935 "PDO %p",
936 pRelations->Objects[i]
937 );
938 }
939 }
940 }
941
942 return status;
943}
944
949 )
950{
952
953 //
954 // Probably is a better check then this to see if the driver set the bus
955 // information
956 //
957 if (m_BusInformation.BusTypeGuid.Data1 != 0x0) {
958 PPNP_BUS_INFORMATION pBusInformation;
960
964
965 if (pBusInformation != NULL) {
966 //
967 // Initialize the PNP_BUS_INFORMATION structure with the data
968 // from PDO properties.
969 //
970 RtlCopyMemory(pBusInformation,
972 sizeof(PNP_BUS_INFORMATION));
973
974 Irp->SetInformation((ULONG_PTR) pBusInformation);
976 }
977 else {
978 Irp->SetInformation(NULL);
980
983 "WDFDEVICE %p could not allocate PNP_BUS_INFORMATION string, "
984 " %!STATUS!", m_Device->GetHandle(), status);
985 }
986 }
987 else {
988 status = Irp->GetStatus();
989 }
990
991 return status;
992}
993
999 )
1000/*++
1001
1002Routine Description:
1003 Handles the query device relations request for all relation types *except*
1004 for bus relations (HandleQueryBusRelations handles that type exclusively).
1005
1006 This function will allocate a PDEVICE_RELATIONS structure if the passed in
1007 FxRelatedDeviceList contains any devices to add to the relations list.
1008
1009Arguments:
1010 Irp - the request
1011
1012 List - list containing devices to report in the relations
1013
1014Return Value:
1015 NTSTATUS
1016
1017 --*/
1018{
1019 PDEVICE_RELATIONS pPriorRelations, pNewRelations;
1022 ULONG count;
1023 size_t size;
1025 BOOLEAN retry;
1027
1028 if (List == NULL) {
1029 //
1030 // Indicate that we didn't modify the irp at all since we have no list
1031 //
1032 return STATUS_NOT_SUPPORTED;
1033 }
1034
1036 type = Irp->GetParameterQDRType();
1038
1039 //
1040 // Notify driver that he should re-scan for device relations.
1041 //
1043
1044 pPriorRelations = (PDEVICE_RELATIONS) Irp->GetInformation();
1045 retry = FALSE;
1046
1047 count = 0;
1048
1049 List->LockForEnum(pFxDriverGlobals);
1050
1051 //
1052 // Count how many entries there are in the list
1053 //
1054 for (entry = NULL; (entry = List->GetNextEntry(entry)) != NULL; count++) {
1055 DO_NOTHING();
1056 }
1057
1058 //
1059 // If we have
1060 // 1) no devices in the list AND
1061 // a) we have nothing to report OR
1062 // b) we have something to report and there are previous relations (which
1063 // if left unchanged will be used to report our missing devices)
1064 //
1065 // THEN we have nothing else to do, just return
1066 //
1067 if (count == 0 &&
1068 (List->m_NeedReportMissing == 0 || pPriorRelations != NULL)) {
1069 List->UnlockFromEnum(pFxDriverGlobals);
1070 return STATUS_NOT_SUPPORTED;
1071 }
1072
1073 if (pPriorRelations != NULL) {
1074 //
1075 // Looks like another driver in the stack has already added some
1076 // entries. Make sure we allocate space for these additional entries.
1077 //
1078 count += pPriorRelations->Count;
1079 }
1080
1081 //
1082 // Allocate space for the device relations structure (which includes
1083 // space for one PDEVICE_OBJECT, and then allocate enough additional
1084 // space for the extra PDEVICE_OBJECTS we need.
1085 //
1086 // (While no FxChildList objects are used in this function, this static
1087 // function from the class computes what we need.)
1088 //
1090
1093
1094 if (pNewRelations == NULL) {
1095 //
1096 // Dereference any previously reported relations before exiting. They
1097 // are dereferenced here because the PNP manager will see error and not
1098 // do anything while the driver which added these objects expects the
1099 // pnp manager to do the dereference. Since this device is changing the
1100 // status, it must act like the pnp manager.
1101 //
1102 if (pPriorRelations != NULL) {
1103 ULONG i;
1104
1105 for (i = 0; i < pPriorRelations->Count; i++) {
1106 Mx::MxDereferenceObject(pPriorRelations->Objects[i]);
1107 }
1108 }
1109
1110 if (List->IncrementRetries() < 3) {
1111 retry = TRUE;
1112 }
1113
1115
1118 "WDFDEVICE %p could not allocate device relations for type %d string, "
1119 " %!STATUS!", m_Device->GetHandle(), type, status);
1120
1121 goto Done;
1122 }
1123
1124 RtlZeroMemory(pNewRelations, size);
1125
1126 //
1127 // If there was an existing device relations structure, copy
1128 // the entries to the new structure.
1129 //
1130 if (pPriorRelations != NULL && pPriorRelations->Count > 0) {
1132 pNewRelations,
1133 pPriorRelations,
1135 );
1136 }
1137
1138 //
1139 // Walk the list and return the relations here
1140 //
1141 for (entry = NULL;
1142 (entry = List->GetNextEntry(entry)) != NULL;
1143 pNewRelations->Count++) {
1144 MdDeviceObject pdo;
1145
1146 pdo = entry->GetDevice();
1147
1150 }
1151
1152 //
1153 // Add it to the DEVICE_RELATIONS structure. Pnp dictates that each
1154 // PDO in the list be referenced.
1155 //
1156 pNewRelations->Objects[pNewRelations->Count] = reinterpret_cast<PDEVICE_OBJECT>(pdo);
1158 }
1159
1160Done:
1161 if (NT_SUCCESS(status)) {
1162 List->ZeroRetries();
1163 }
1164
1165 List->UnlockFromEnum(GetDriverGlobals());
1166
1167 if (pPriorRelations != NULL) {
1168 MxMemory::MxFreePool(pPriorRelations);
1169 }
1170
1171 if (retry) {
1172 MxDeviceObject physicalDeviceObject(
1174 );
1175
1176 physicalDeviceObject.InvalidateDeviceRelations(type);
1177 }
1178
1179 Irp->SetStatus(status);
1180 Irp->SetInformation((ULONG_PTR) pNewRelations);
1181
1182 return status;
1183}
1184
1188 VOID
1189 )
1190
1191/*++
1192
1193Routine Description:
1194
1195 This function does any initialization to this object which must be done
1196 after the underlying device object has been attached to the device stack,
1197 i.e. you can send IRPs down this stack now.
1198
1199Arguments:
1200
1201 none
1202
1203Returns:
1204
1205 NTSTATUS
1206
1207--*/
1208
1209{
1211
1213 if (!NT_SUCCESS(status)) {
1215 "PnP State Machine init failed, %!STATUS!",
1216 status);
1217 return status;
1218 }
1219
1221 if (!NT_SUCCESS(status)) {
1223 "Power State Machine init failed, %!STATUS!",
1224 status);
1225 return status;
1226 }
1227
1229 if (!NT_SUCCESS(status)) {
1231 "Power Policy State Machine init failed, %!STATUS!",
1232 status);
1233 return status;
1234 }
1235
1236 return status;
1237}
1238
1239VOID
1242 )
1243/*++
1244
1245Routine Description:
1246 Finish initializing the object. All initialization up until this point
1247 could fail. This function cannot fail, so all it can do is assign field
1248 values and take allocations from DeviceInit.
1249
1250Arguments:
1251 DeviceInit - device initialization structure that the driver writer has
1252 initialized
1253
1254Return Value:
1255 None
1256
1257 --*/
1258
1259{
1260 //
1261 // Reassign the state callback arrays away from the init struct.
1262 // Set the init field to NULL so that it does not attempt to free the array
1263 // when it is destroyed.
1264 //
1265 m_PnpStateCallbacks = DeviceInit->PnpPower.PnpStateCallbacks;
1266 DeviceInit->PnpPower.PnpStateCallbacks = NULL;
1267
1268 m_PowerStateCallbacks = DeviceInit->PnpPower.PowerStateCallbacks;
1269 DeviceInit->PnpPower.PowerStateCallbacks = NULL;
1270
1271 m_PowerPolicyStateCallbacks = DeviceInit->PnpPower.PowerPolicyStateCallbacks;
1272 DeviceInit->PnpPower.PowerPolicyStateCallbacks = NULL;
1273
1274 //
1275 // Bias the count towards one so that we can optimize the synchronous
1276 // cleanup case when the device is being destroyed.
1277 //
1279
1280 //
1281 // Now "Add" this device in the terms that the PnP state machine uses. This
1282 // will be in the context of an actual AddDevice function for FDOs, and
1283 // something very much like it for PDOs.
1284 //
1285 // Important that the posting of the event is after setting of the state
1286 // callback arrays so that we can guarantee that any state transition
1287 // callback will be made.
1288 //
1290}
1291
1292VOID
1294 VOID
1295 )
1296{
1299 "WDFDEVICE %p, !devobj %p processing delayed deletion from pnp state "
1300 "machine", m_Device->GetHandle(), m_Device->GetDeviceObject());
1301
1303 DeleteDevice();
1304}
1305
1306VOID
1310 )
1311
1312/*++
1313
1314Routine Description:
1315
1316 This function marks the device as capable of handling the paging path,
1317 hibernation or crashdumps. Any device that is necessary for one of these
1318 three things will get notification. It is then responsible for forwarding
1319 the notification to its parent. The Framework handles that. This
1320 function just allows a driver to tell the Framework how to respond.
1321
1322
1323Arguments:
1324
1325 FileType - identifies which of the special paths the device is in
1326 Supported - Yes or No
1327
1328Returns:
1329
1330 void
1331
1332--*/
1333
1334{
1335 switch (FileType) {
1338 case WdfSpecialFileDump:
1339 case WdfSpecialFileBoot:
1341 break;
1342
1343 default:
1345 "Invalid special file type %x", FileType);
1346 }
1347}
1348
1354 )
1355
1356/*++
1357
1358Routine Description:
1359
1360 This driver may be sent IRP_MN_QUERY_INTERFACE, which is a way of getting
1361 a direct-call table from some driver in a device stack. In some cases, the
1362 right response is to turn around and send a similar query to the device's
1363 parent. This function does that.
1364
1365
1366Arguments:
1367
1368 Device - This WDFDEVICE.
1369 Irp - The IRP that was sent to us.
1370
1371Returns:
1372
1373 NTSTATUS
1374
1375--*/
1376
1377{
1378 MdIrp pFwdIrp;
1380 NTSTATUS prevStatus;
1382
1383 prevStatus = Irp->GetStatus();
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396 pTopOfStack.SetObject(Device->m_ParentDevice->GetAttachedDeviceReference());
1397
1398 pFwdIrp = FxIrp::AllocateIrp(pTopOfStack.GetStackSize());
1399
1400 if (pFwdIrp != NULL) {
1401 FxAutoIrp fxFwdIrp(pFwdIrp);
1402
1403 //
1404 // The worker routine copies stack parameters to forward-Irp, sends it
1405 // down the stack synchronously, then copies back the stack parameters
1406 // from forward-irp to original-irp
1407 //
1409
1410 if (fxFwdIrp.GetStatus() != STATUS_NOT_SUPPORTED) {
1411 status = fxFwdIrp.GetStatus();
1412 }
1413 else {
1414 status = prevStatus;
1415 }
1416
1417 Irp->SetStatus(status);
1418 Irp->SetInformation(fxFwdIrp.GetInformation());
1419 }
1420 else {
1422
1424 Device->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
1425 "WDFDEVICE %p could not allocate IRP to send QI to parent !devobj "
1426 "%p, %!STATUS!", Device->GetHandle(), pTopOfStack.GetObject(),
1427 status);
1428 }
1429
1430 pTopOfStack.DereferenceObject();
1431
1432 return status;
1433}
1434
1438 __inout FxIrp* Irp,
1440 )
1441{
1443
1445
1446 //
1447 // Send the request down the stack first. If someone lower handles it
1448 // or failed trying to, just return their status
1449 //
1451
1453 //
1454 // Success or failure trying to handle it
1455 //
1456 return status;
1457 }
1458
1459 //
1460 // The semantic of this QI is that it sent down while processing start or
1461 // a device usage notification on the way *up* the stack. That means that
1462 // by the time the QI gets to the lower part of the stack, the power thread
1463 // will have already been allocated and exported.
1464 //
1466
1467 if (Irp->GetParameterQueryInterfaceVersion() == 1 &&
1468 Irp->GetParameterQueryInterfaceSize() >=
1470 //
1471 // Expose the interface to the requesting driver.
1472 //
1474
1476
1477 //
1478 // Caller assumes a reference has been taken.
1479 //
1482 );
1483 }
1484 else {
1486 }
1487
1488 return status;
1489}
1490
1494 __inout FxIrp* Irp,
1496 )
1497
1498/*++
1499
1500Routine Description:
1501
1502 This driver may be sent IRP_MN_QUERY_INTERFACE, which is a way of getting
1503 a direct-call table from some driver in a device stack. This function
1504 looks into a list of interfaces that the driver has registered and, if
1505 the interface that is being sought is present, it answers the IRP.
1506
1507Arguments:
1508
1509 Irp - The IRP that was sent to us.
1510 CompleteRequest - tells the caller whether the IRP should be completed
1511
1512Returns:
1513
1514 NTSTATUS
1515
1516--*/
1517
1518{
1520 const GUID* pInterfaceType;
1522 FxQueryInterface *pQI;
1523 PVOID pFound;
1524 PINTERFACE pExposedInterface;
1525 PVOID pExposedInterfaceSpecificData;
1526 BOOLEAN sendToParent;
1527
1529
1531
1532 pFound = NULL;
1533 pQI = NULL;
1534 pExposedInterface = NULL;
1535 pExposedInterfaceSpecificData = NULL;
1536 sendToParent = FALSE;
1537
1538 pInterfaceType = Irp->GetParameterQueryInterfaceType();
1539 //
1540 // The power thread is special cased because it has a different semantic
1541 // then the usual QI irp that we expose to the driver writer. In this case,
1542 // we want to fill in the interface if the lower stack does not support it.
1543 //
1544 if (FxIsEqualGuid(pInterfaceType, &GUID_POWER_THREAD_INTERFACE)) {
1546 }
1547 else if (FxIsEqualGuid(pInterfaceType, &GUID_REENUMERATE_SELF_INTERFACE_STANDARD)) {
1548 if (m_Device->IsPdo()) {
1549 return ((FxPkgPdo*) this)->HandleQueryInterfaceForReenumerate(
1551 }
1552 }
1553
1554 status = Irp->GetStatus();
1555
1556 //
1557 // Walk the interface collection and return the appropriate interface.
1558 //
1560
1561 for (ple = m_QueryInterfaceHead.Next; ple != NULL; ple = ple->Next) {
1563
1564 if (FxIsEqualGuid(Irp->GetParameterQueryInterfaceType(),
1565 &pQI->m_InterfaceType)) {
1566
1567 pExposedInterface = Irp->GetParameterQueryInterfaceInterface();
1568 pExposedInterfaceSpecificData =
1569 Irp->GetParameterQueryInterfaceInterfaceSpecificData();
1570
1571 if (pQI->m_Interface != NULL) {
1572 //
1573 // NOTE: If a driver has exposed the same interface GUID with
1574 // different sizes as a ways of versioning, then the driver
1575 // writer can specify the minimum size and version number
1576 // and then fill in the remaining fields in the callback
1577 // below.
1578 //
1579 if (pQI->m_Interface->Size <= Irp->GetParameterQueryInterfaceSize() &&
1580 pQI->m_Interface->Version <= Irp->GetParameterQueryInterfaceVersion()) {
1581
1582 if (pQI->m_ImportInterface == FALSE) {
1583 //
1584 // Expose the interface to the requesting driver.
1585 //
1586 RtlCopyMemory(pExposedInterface,
1587 pQI->m_Interface,
1588 pQI->m_Interface->Size);
1589 }
1590 else {
1591 //
1592 // The interface contains data which the driver wants
1593 // before copying over its information, so don't do a
1594 // copy and let the event callback do the copy
1595 //
1596 DO_NOTHING();
1597 }
1598 }
1599 else {
1601 break;
1602 }
1603 }
1604
1605 callback.m_Method = pQI->m_ProcessRequest.m_Method;
1606 sendToParent = pQI->m_SendQueryToParentStack;
1607 pFound = pQI;
1608
1610 break;
1611 }
1612 }
1613
1615
1616 if (!NT_SUCCESS(status) || pFound == NULL) {
1617 goto Done;
1618 }
1619
1620 //
1621 // Let the driver see the interface before it is handed out.
1622 //
1623 status = callback.Invoke(m_Device->GetHandle(),
1624 (LPGUID) Irp->GetParameterQueryInterfaceType(),
1625 pExposedInterface,
1626 pExposedInterfaceSpecificData);
1627
1628 //
1629 // STATUS_NOT_SUPPORTED is a special cased error code which indicates that
1630 // the QI should travel down the rest of the stack.
1631 //
1633 goto Done;
1634 }
1635
1636 //
1637 // If it is meant for the parent, send it down the parent stack
1638 //
1639 if (sendToParent) {
1641 goto Done;
1642 }
1643
1644 //
1645 // Reference the interface before returning it to the requesting driver.
1646 // If this is an import interface, the event callback is free to not fill
1647 // in the InterfaceReference function pointer.
1648 //
1649 if (pExposedInterface->InterfaceReference != NULL) {
1650 pExposedInterface->InterfaceReference(pExposedInterface->Context);
1651 }
1652
1653 //
1654 // If we are not a PDO in the stack, then send the fully formatted QI request
1655 // down the stack to allow others to filter the interface.
1656 //
1657 if (m_Device->IsPdo() == FALSE) {
1659
1660 Irp->SetStatus(status);
1661 Irp->CopyCurrentIrpStackLocationToNext();
1662 status = Irp->SendIrpSynchronously(m_Device->GetAttachedDevice());
1663 }
1664
1665Done:
1666 if (pFound != NULL) {
1668 }
1669
1670 return status;
1671}
1672
1676 VOID
1677 )
1678{
1681
1683
1685
1687 &deviceObject,
1689 &caps);
1690
1691 if (NT_SUCCESS(status)) {
1692 ULONG states, i;
1693
1694 ASSERT(caps.DeviceCaps.DeviceWake <= 0xFF && caps.DeviceCaps.SystemWake <= 0xFF);
1695
1696 m_SystemWake = (BYTE) caps.DeviceCaps.SystemWake;
1697
1698 //
1699 // Initialize the array of wakeable D-states to say that all system
1700 // states down to the one identified in the caps can generate wake.
1701 // This will be overridden below if the BIOS supplied more information.
1702 //
1703 // Compatibility Note: Non-ACPI bus drivers (root-enumerated drivers)
1704 // or other bus drivers that haven't set the power settings correctly
1705 // for their PDO may end up with a valid value for DeviceWake in the
1706 // device capabilities but a value of PowerSystemUnspecified for
1707 // SystemWake, in which case a call to WdfDeviceAssignS0IdleSettings or
1708 // WdfDeviceAssignSxWakeSettings DDIs will fail on 1.11+ resulting in
1709 // device compat issues. The failure is expected and right thing to do
1710 // but has compatibility implications - drivers that worked earlier now
1711 // fail on 1.11. Note that earlier versions of WDF did not have
1712 // m_DeviceWake as an array and stored just the capabilities->DeviceWake
1713 // value without regard to the SystemWake but the current implementation
1714 // introduces dependency on systemWake value). So for compat reasons,
1715 // for pre-1.11 compiled drivers we initilaize the array with DeviceWake
1716 // value ignoring SystemWake, removing any dependency of DeviceWake
1717 // on SystemWake value and thus preserving previous behavior for
1718 // pre-1.11 compiled drivers.
1719 //
1721
1723
1724 for (i = PowerSystemWorking; i <= m_SystemWake; i++) {
1725
1726 //
1727 // Note that this cast is hiding a conversion between two slightly
1728 // incompatible types. DeviceWake is in terms of DEVICE_POWER_STATE
1729 // which is defined this way:
1730 //
1731 // typedef enum _DEVICE_POWER_STATE {
1732 // PowerDeviceUnspecified = 0,
1733 // PowerDeviceD0,
1734 // PowerDeviceD1,
1735 // PowerDeviceD2,
1736 // PowerDeviceD3,
1737 // PowerDeviceMaximum
1738 // } DEVICE_POWER_STATE, *PDEVICE_POWER_STATE;
1739 //
1740 // m_DeviceWake is defined in terms of DEVICE_WAKE_DEPTH which is
1741 // defined this way:
1742 //
1743 // typedef enum _DEVICE_WAKE_DEPTH {
1744 // DeviceWakeDepthNotWakeable = 0,
1745 // DeviceWakeDepthD0,
1746 // DeviceWakeDepthD1,
1747 // DeviceWakeDepthD2,
1748 // DeviceWakeDepthD3hot,
1749 // DeviceWakeDepthD3cold,
1750 // DeviceWakeDepthMaximum
1751 // } DEVICE_WAKE_DEPTH, *PDEVICE_WAKE_DEPTH;
1752 //
1753 // The result is that the conversion below will map D3 onto D3hot,
1754 // which is a safe assumption to start with, one which may be
1755 // overridden later.
1756 //
1758 m_DeviceWake[i - PowerSystemWorking] = (BYTE) caps.DeviceCaps.DeviceWake;
1759 }
1760 }
1761 else {
1762 //
1763 // See comments above for information on mapping of device power
1764 // state to device wake depth.
1765 //
1768 (BYTE) caps.DeviceCaps.DeviceWake);
1769 }
1770
1771 //
1772 // Capture the S -> D state mapping table as a ULONG for use in the
1773 // power policy owner state machine when the machine moves into Sx and
1774 // the device is not armed for wake and has set an IdealDxStateForSx
1775 // value
1776 //
1777 states = 0x0;
1778
1779 for (i = 0; i < ARRAY_SIZE(caps.DeviceCaps.DeviceState); i++) {
1780 _SetPowerCapState(i, caps.DeviceCaps.DeviceState[i], &states);
1781 }
1782
1784
1785 //
1786 // Query for the D3cold support interface. If present, it will tell
1787 // us specifically which D-states will work for generating wake signals
1788 // from specific S-states.
1789 //
1790 // Earlier versions of WDF didn't make this query, so for compatibility,
1791 // we only make it now if the driver was built against WDF 1.11 or
1792 // later. In truth, this just shifts the failure from initialization
1793 // time to run time, because the information that we're presumably
1794 // getting from the BIOS with this interrogation is saying that the
1795 // code in earlier verisions of WDF would have blindly enabled a device
1796 // for wake which simply wasn't capable of generating its wake signal
1797 // from the chosen D-state. Thus the device would have been put into
1798 // a low power state and then failed to resume in response to its wake
1799 // signal.
1800 //
1801
1802 if (GetDriverGlobals()->IsVersionGreaterThanOrEqualTo(1,11)) {
1803
1804 //
1805 // Cycle through all the system states that this device can wake
1806 // from. There's no need to look at deeper sleep states than
1807 // m_SystemWake because the driver will not arm for wake in
1808 // those states.
1809 //
1810 for (i = PowerSystemWorking; i <= m_SystemWake; i++) {
1813 }
1814 }
1815 }
1816 }
1817
1818 return status;
1819}
1820
1826 )
1827/*++
1828
1829Routine Description:
1830 This method is called in response to a PnP StartDevice IRP coming down the
1831 stack.
1832
1833Arguments:
1834 This - device instance
1835 Irp - a pointer to the FxIrp
1836
1837Returns:
1838 STATUS_PENDING
1839
1840--*/
1841{
1842 This->SetPendingPnpIrp(Irp);
1843 This->PnpProcessEvent(PnpEventStartDevice);
1844
1845 return STATUS_PENDING;
1846}
1847
1853 )
1854
1855/*++
1856
1857Routine Description:
1858
1859 Pnp callback querying to see if the device can be stopped.
1860
1861 The Framework philosophy surrounding Query Stop (and Query Remove) is that
1862 it's impossible to really know if you can stop unless you've tried to stop.
1863 This may not always be true, but it's hard to find a general strategy that
1864 works that is less conservative. Furthermore, I couldn't find good examples
1865 of drivers that would really benefit from continuing to handle requests
1866 until the actual Stop IRP arrived, particularly when you consider that
1867 most QueryStops are followed immediately by Stops.
1868
1869 So this function sends an event to the PnP State machine that begins the
1870 stopping process. If it is successful, then ultimately the QueryStop IRP
1871 will be successfully completed.
1872
1873Arguments:
1874
1875 This - a pointer to the PnP package
1876
1877 Irp - a pointer to the FxIrp
1878
1879Return Value:
1880
1881 STATUS_PENDING
1882
1883 --*/
1884
1885{
1886 //
1887 // Keep this IRP around, since we're going to deal with it later.
1888 //
1889 This->SetPendingPnpIrp(Irp);
1890
1891 //
1892 // Now run the state machine on this thread.
1893 //
1894 This->PnpProcessEvent(PnpEventQueryStop);
1895
1896 return STATUS_PENDING;
1897}
1898
1904 )
1905/*++
1906
1907Routine Description:
1908
1909 This routine is invoked in response to a query stop failing, somewhere in
1910 the stack. Note that we can receive a cancel stop without being in the
1911 query stop state if a driver above us in the stack failed the query stop.
1912
1913 Again, this function just exists to bridge the gap between the WDM IRPs
1914 and the PnP state machine. This function does little more than send an
1915 event to the machine.
1916
1917Arguments:
1918
1919 This - the package
1920
1921 Irp - a pointer to the FxIrp
1922
1923Returns:
1924
1925 STATUS_PENDING
1926
1927--*/
1928{
1929 //
1930 // Seed the irp with success
1931 //
1932 Irp->SetStatus(STATUS_SUCCESS);
1933
1934 //
1935 // Pend it and transition the state machine
1936 //
1937 This->SetPendingPnpIrp(Irp);
1938 This->PnpProcessEvent(PnpEventCancelStop);
1939
1940 return STATUS_PENDING;
1941}
1942
1948 )
1949/*++
1950
1951Routine Description:
1952
1953 This method is invoked in response to a Pnp StopDevice IRP.
1954
1955Arguments:
1956
1957 Irp - a pointer to the FxIrp
1958
1959Returns:
1960
1961 STATUS_PENDING
1962
1963--*/
1964{
1965 //
1966 // Seed the irp with success
1967 //
1968 Irp->SetStatus(STATUS_SUCCESS);
1969
1970 //
1971 // Pend and transition the state machine
1972 //
1973 This->SetPendingPnpIrp(Irp);
1974 This->PnpProcessEvent(PnpEventStop);
1975
1976 return STATUS_PENDING;
1977}
1978
1984 )
1985/*++
1986
1987Routine Description:
1988
1989 Again, the Framework handles QueryRemove by stopping everything going on
1990 related to the device and then asking the driver whether it can be
1991 removed. This function just kicks the state machine. Final completion
1992 of the IRP will come (much) later.
1993
1994Arguments:
1995
1996 This - the package
1997
1998 Irp - a pointer to the FxIrp
1999
2000Returns:
2001
2002 STATUS_PENDING
2003
2004--*/
2005{
2006 //
2007 // By default we handle this state.
2008 //
2009 Irp->SetStatus(STATUS_SUCCESS);
2010
2011 //
2012 // Keep this IRP around, since we're going to deal with it later.
2013 //
2014 This->SetPendingPnpIrp(Irp);
2015
2016 //
2017 // Now run the state machine on this thread.
2018 //
2019 This->PnpProcessEvent(PnpEventQueryRemove);
2020
2021 return STATUS_PENDING;
2022}
2023
2029 )
2030
2031/*++
2032
2033Routine Description:
2034
2035 Notification of a previous remove being canceled. Kick the state machine.
2036
2037Arguments:
2038
2039 This - the package
2040
2041 Irp - FxIrp representing the notification
2042
2043Return Value:
2044
2045 STATUS_PENDING
2046
2047 --*/
2048
2049{
2050 //
2051 // Seed the irp with success
2052 //
2053 Irp->SetStatus(STATUS_SUCCESS);
2054
2055 //
2056 // Pend it and transition the state machine
2057 //
2058
2059 This->SetPendingPnpIrp(Irp);
2060 This->PnpProcessEvent(PnpEventCancelRemove);
2061
2062 return STATUS_PENDING;
2063}
2064
2065VOID
2067 __in BOOLEAN CleanupPnp
2068 )
2069{
2070#if (FX_CORE_MODE==FX_CORE_USER_MODE)
2072#else
2073 FxCREvent eventOnStack;
2074 eventOnStack.Initialize();
2075 FxCREvent * event = eventOnStack.GetSelfPointer();
2076#endif
2077
2078 //
2079 // Order of shutdown is important here.
2080 // o Pnp initiates events to power policy.
2081 // o Power policy initiates events to power and device-power-requirement
2082 // o Power does not initiate any events
2083 // o Device-power-requirement does not initiate any events
2084 //
2085 // By shutting them down in the order in which they send events, we can
2086 // guarantee that no new events will be posted into the subsidiary state
2087 // machines.
2088 //
2089
2090 //
2091 // This will shut off the pnp state machine and synchronize any outstanding
2092 // threads of execution.
2093 //
2094 if (CleanupPnp && m_PnpMachine.SetFinished(
2095 event
2096 ) == FALSE) {
2099 "WDFDEVICE %p, !devobj %p waiting for pnp state machine to finish",
2101
2102 //
2103 // Process the event *before* completing the irp so that this event is in
2104 // the queue before the device remove event which will be processed
2105 // right after the start irp has been completed.
2106 //
2107 event->EnterCRAndWaitAndLeave();
2108 }
2109
2110 //
2111 // Even though event is a SynchronizationEvent, so we need to reset it for
2112 // the next wait because SetFinished will set it if even if the transition
2113 // to the finished state is immediate
2114 //
2115 event->Clear();
2116
2120 "WDFDEVICE %p, !devobj %p waiting for pwr pol state machine to finish",
2122
2123 event->EnterCRAndWaitAndLeave();
2124 }
2125
2126 //
2127 // See previous comment about why we Clear()
2128 //
2129 event->Clear();
2130
2134 "WDFDEVICE %p, !devobj %p waiting for pwr state machine to finish",
2136
2137 event->EnterCRAndWaitAndLeave();
2138 }
2139
2140 if (IsPowerPolicyOwner()) {
2141 //
2142 // See previous comment about why we Clear()
2143 //
2144 event->Clear();
2145
2147 m_DevicePowerRequirementMachine) {
2148
2150 m_DevicePowerRequirementMachine->SetFinished(event)) {
2151
2154 "WDFDEVICE %p, !devobj %p waiting for device power "
2155 "requirement state machine to finish",
2158
2159 event->EnterCRAndWaitAndLeave();
2160 }
2161 }
2162
2164 }
2165
2166 //
2167 // Release the power thread if we have one either through creation or query.
2168 // Since the power policy state machine is off, we should no longer need
2169 // a dedicated thread.
2170 //
2171 // *** NOTE ***
2172 // The power thread must be released *BEFORE* sending the irp down the stack
2173 // because this can happen
2174 // 1) this driver is not the power thread owner, but the last client
2175 // 2) we send the pnp irp first
2176 // 3) the power thread owner waits on this thread for all the clients to go
2177 // away, but this device still has a reference on it
2178 // 4) this device will not release the reference b/c the owner is waiting
2179 // in the same thread.
2180 //
2182
2183 //
2184 // Deref the reenumeration interface
2185 //
2187}
2188
2189VOID
2191 __in MxEvent * WaitEvent
2192 )
2193/*++
2194
2195Routine Description:
2196 The device failed creation in some stage. It is assumed that the device has
2197 enough state that it can survive a transition through the pnp state machine
2198 (which means that pointers like m_PkgIo are valid and != NULL). When this
2199 function returns, it will have deleted the owning FxDevice.
2200
2201Arguments:
2202 WaitEvent - Event on which RemoveProcessed wait will be performed
2203
2204 We can't initialize this event on stack as the initialization
2205 can fail in user-mode. We can't have Initialize method
2206 preinitailize this event either as this function may get called
2207 before initialize (or in case of initialization failure).
2208
2209 Hence the caller preallocates the event and passes to this
2210 function.
2211
2212 Caller must initialize this event as SynchronizationEvent
2213 and it must be unsignalled.
2214Return Value:
2215 None
2216
2217 --*/
2218{
2220
2221 //
2222 // Caller must initialize the event as Synchronization event and it should
2223 // be passed as non-signalled. But we Clear it just to be sure.
2224 //
2225 WaitEvent->Clear();
2226
2227 ADDREF(WaitEvent);
2228
2230 m_DeviceRemoveProcessed = WaitEvent;
2231
2232 //
2233 // Simulate a remove event coming to the device. After this call returns
2234 // m_Device is still valid and must be deleted.
2235 //
2237
2238 //
2239 // No need to wait in a critical region because we are in the context of a
2240 // pnp request which is in the system context.
2241 //
2242 WaitEvent->WaitFor(Executive, KernelMode, FALSE, NULL);
2244
2245 RELEASE(WaitEvent);
2246}
2247
2248VOID
2250 VOID
2251 )
2252/*++
2253
2254Routine Description:
2255 This routine will detach and delete the device object and free the memory
2256 for the device if there are no other references to it. Before calling this
2257 routine, the state machines should have been cleaned up and the power thread
2258 released.
2259
2260--*/
2261{
2262 //
2263 // This will detach and delete the device object
2264 //
2265 m_Device->Destroy();
2266
2267 //
2268 // If this is the last reference, this will free the memory for the device
2269 //
2271}
2272
2278 )
2279
2280/*++
2281
2282Routine Description:
2283
2284 Notification of a remove. Kick the state machine.
2285
2286Arguments:
2287
2288 This - the package
2289
2290 Irp - FxIrp representing the notification
2291
2292Return Value:
2293
2294 status
2295
2296 --*/
2297
2298{
2299#if (FX_CORE_MODE==FX_CORE_USER_MODE)
2300 MxEvent * event = This->m_RemoveEventUm.GetSelfPointer();
2301#else
2302 MxEvent eventOnStack;
2303 eventOnStack.Initialize(SynchronizationEvent, FALSE);
2304 MxEvent * event = eventOnStack.GetSelfPointer();
2305#endif
2306
2308
2310 This->m_Device->GetRemoveLock(),
2311 Irp->GetIrp());
2312
2313#if DBG
2315#else
2317#endif
2318
2319 //
2320 // Keep this object around after m_Device has RELEASE'ed its reference to
2321 // this package.
2322 //
2323 This->ADDREF(Irp);
2324
2325 //
2326 // Removes are always success
2327 //
2328 Irp->SetStatus(STATUS_SUCCESS);
2329
2330 ASSERT(This->m_DeviceRemoveProcessed == NULL);
2331 This->m_DeviceRemoveProcessed = event;
2332
2333 //
2334 // Post the event and wait for the FxDevice to destroy itself or determine
2335 // it has not been reported missing yet (for PDOs and bus filters).
2336 //
2337 This->PnpProcessEvent(PnpEventRemove);
2338
2340 This->GetDriverGlobals(), TRACE_LEVEL_INFORMATION, TRACINGPNP,
2341 "WDFDEVICE %p, !devobj %p waiting for remove event to finish processing",
2342 This->m_Device->GetHandle(), This->m_Device->GetDeviceObject());
2343
2344 //
2345 // No need to wait in a critical region because we are in the context of a
2346 // pnp request which is in the system context.
2347 //
2348 event->WaitFor(Executive, KernelMode, FALSE, NULL);
2349
2350 This->m_DeviceRemoveProcessed = NULL;
2351
2352 status = This->ProcessRemoveDeviceOverload(Irp);
2353
2354 //
2355 // Release the reference added at the top. This is most likely going to be
2356 // the last reference on the package for KMDF. For UMDF, host manages the
2357 // lifetime of FxDevice so this may not be the last release for UMDF.
2358 //
2359 This->RELEASE(Irp);
2360
2361 return status;
2362}
2363
2368 )
2369
2370/*++
2371
2372Routine Description:
2373
2374 Notification that the device has been surprise removed. Kick the state
2375 machine.
2376
2377Arguments:
2378
2379 Irp - pointer to FxIrp representing this notification
2380
2381Return Value:
2382
2383 STATUS_PENDING
2384
2385--*/
2386
2387{
2388 //
2389 // Package specific handling
2390 //
2391 Irp->SetStatus(STATUS_SUCCESS);
2394
2395 return STATUS_PENDING;
2396}
2397
2403 )
2404
2405/*++
2406
2407Routine Description:
2408
2409 This the first-level dispatch routine for IRP_MN_WAIT_WAKE. What one
2410 does with a WaitWake IRP depends very much on whether one is an FDO, a PDO
2411 or a filter. So dispatch immediately to a subclassable function.
2412
2413Arguments:
2414
2415 This - the package
2416
2417 Irp - pointer to FxIrp representing this notification
2418
2419Return Value:
2420
2421 status
2422
2423--*/
2424
2425{
2426 return This->DispatchWaitWake(Irp);
2427}
2428
2433 )
2434/*++
2435
2436Routine Description:
2437
2438 Handles wait wake requests in a generic fashion
2439
2440Arguments:
2441
2442
2443Return Value:
2444
2445 --*/
2446{
2447 PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();
2449 PIRP oldIrp;
2450 KIRQL irql;
2451
2452 if (IsPowerPolicyOwner()) {
2454 //
2455 // A power irp arrived, but we did not request it. log and bugcheck
2456 //
2459 "Received wait wake power irp %p on device %p, but the irp was "
2460 "not requested by the device (the power policy owner)",
2461 Irp->GetIrp(), m_Device->GetDeviceObject());
2462
2464 WDF_POWER_MULTIPLE_PPO, // specific type
2465 (ULONG_PTR)m_Device->GetDeviceObject(), //parm 2
2466 (ULONG_PTR)Irp->GetIrp()); // parm 3
2467
2468 /* NOTREACHED */
2469 }
2470
2471 //
2472 // We are no longer requesting a power irp because we received the one
2473 // we requested.
2474 //
2476 }
2477
2478 //
2479 // The Framework has the concept of a "Wait/Wake Owner." This is the layer
2480 // in the stack that is enabling and disabling wake at the bus level. This
2481 // is probably the PDO or a bus filter like ACPI.sys. This is distinct
2482 // from being the "Power Policy Owner," which would mean that this driver
2483 // is deciding what D-state is appropriate for the device, and also
2484 // sending Wait/Wake IRPs.
2485 //
2486
2489
2491 //
2492 // We only allow one pended wait wake irp in the stack at a time.
2493 // Fail this secondary wait wake request.
2494 //
2496
2499 "Failing wait wake irp %p with %!STATUS! because wait wake irp "
2500 "%p already pended",
2502 }
2503 else {
2504 MdCancelRoutine pRoutine;
2505
2506 //
2507 // No wait wake irp is currently in the stack, so attempt to set
2508 // a cancel routine and transition the power state machine into a
2509 // a state where it can arm the device at the bus level for this
2510 // child.
2511 //
2512 // The power state machine expects the wait wake irp to have a cancel
2513 // routine set in all states. For those states which require a
2514 // non cancelable irp, those states clear the cancel routine as
2515 // appropriate.
2516 //
2517 pRoutine = Irp->SetCancelRoutine(_PowerWaitWakeCancelRoutine);
2518#if DBG
2519 ASSERT(pRoutine == NULL);
2520#else
2521 UNREFERENCED_PARAMETER(pRoutine);
2522#endif
2524
2525 if (Irp->IsCanceled()) {
2528 "wait wake irp %p already canceled", Irp->GetIrp());
2529
2530 //
2531 // This IRP has already been cancelled, we must clear the cancel
2532 // routine before completing the IRP.
2533 //
2534 pRoutine = Irp->SetCancelRoutine(NULL);
2535
2536 if (pRoutine != NULL) {
2537 //
2538 // Our cancel routine will not be called
2539 //
2540#if DBG
2542#else
2543 UNREFERENCED_PARAMETER(pRoutine);
2544#endif
2545 Irp->SetStatus(STATUS_CANCELLED);
2547 }
2548 }
2549
2550 if (status == STATUS_PENDING) {
2551 //
2552 // Either we successfully set the cancel routine or the irp
2553 // was canceled and the cancel routine is about to run when
2554 // we drop the lock. If the routine is about to run, we still
2555 // need to setup m_SharedPower to values that it expects.
2556 //
2557 Irp->MarkIrpPending();
2558 m_SharedPower.m_WaitWakeIrp = Irp->GetIrp();
2559 }
2560 }
2562
2563 if (NT_SUCCESS(status)) {
2564 //
2565 // Post to the appropriate matchines
2566 //
2568
2569 if (IsPowerPolicyOwner()) {
2571 }
2572 }
2573 else {
2575 }
2576
2577 return status;
2578 }
2579 else if (IsPowerPolicyOwner()) {
2580 //
2581 // Try to set m_WaitWakeIrp to the new IRP value only if the current
2582 // value of m_WaitWakeIrp is NULL because there can only be one
2583 // active wait wake irp in the stack at a time. Since the power policy
2584 // state machine never sends more then one, this is really a guard
2585 // against some other device in the stack sending a wait wake irp to
2586 // this device in the wrong state.
2587 //
2590 Irp->GetIrp(),
2591 NULL
2592 );
2593
2594 //
2595 // If oldIrp is NULL then there was no previous irp and we successfully
2596 // exchanged the new PIRP value into m_WaitWakeIrp
2597 //
2598 if (oldIrp == NULL) {
2600
2601 //
2602 // NOTE: There is a built in race condition here that WDF cannot
2603 // solve with the given WDM primitives. After arming the
2604 // device for wake, there is a window where the wait wake irp
2605 // has not yet been processed by the wait wake owner. Until
2606 // the wake request is processed, wake events could be generated
2607 // and lost. There is nothing we can do about this until we
2608 // have synchronous "goto Dx and arm" command available.
2609 //
2610 Irp->CopyCurrentIrpStackLocationToNext();
2611 Irp->SetCompletionRoutineEx(m_Device->GetDeviceObject(),
2613 this);
2614
2615 //
2616 // Technically, there should be a PDO vs FDO overload here which
2617 // does the right thing w/regard to this request and if it is at the
2618 // bottom of the stack or not. But, by design, we check for
2619 // m_WaitWakeOwner first which has the direct side affect of making
2620 // it impossible for a PDO to get to this point.
2621 //
2622 ASSERT(m_Device->IsFdo());
2623
2624 status = Irp->PoCallDriver(m_Device->GetAttachedDevice());
2625
2626 //
2627 // Send the wake arrived after sending the request as commented above.
2628 // This window between sending the request and sending the event to
2629 // the state machine allows the wait owner to complete the request
2630 // immediately. When completed synchronously, it has an effect on
2631 // both wake scenarios:
2632 //
2633 // 1) wake from S0: the device never transitions to Dx and the idle
2634 // timer is resumed if no i/o is present
2635 //
2636 // 2) wake from sx: the device is disarmed for wake from Sx and
2637 // put into Dx with being armed for wake.
2638 //
2640 }
2641 else {
2643
2645 FxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP,
2646 "already have a ww irp %p, failing new ww irp %p with %!STATUS!",
2647 oldIrp, Irp->GetIrp(), status);
2648
2650 }
2651 }
2652 else {
2653 //
2654 // Not the power policy owner, not the wait wake irp owner, ignore the
2655 // irp
2656 //
2657 // This will release the remove lock.
2658 //
2660 }
2661
2662 return status;
2663}
2664
2669 )
2670{
2672
2673 //
2674 // Update the callback table.
2675 //
2676 m_DeviceD0Entry.m_Method = DispatchTable->EvtDeviceD0Entry;
2678 DispatchTable->EvtDeviceD0EntryPostInterruptsEnabled;
2680 DispatchTable->EvtDeviceD0ExitPreInterruptsDisabled;
2681 m_DeviceD0Exit.m_Method = DispatchTable->EvtDeviceD0Exit;
2682
2683 m_DevicePrepareHardware.m_Method = DispatchTable->EvtDevicePrepareHardware;
2684 m_DeviceReleaseHardware.m_Method = DispatchTable->EvtDeviceReleaseHardware;
2685
2686 m_DeviceQueryStop.m_Method = DispatchTable->EvtDeviceQueryStop;
2687 m_DeviceQueryRemove.m_Method = DispatchTable->EvtDeviceQueryRemove;
2688
2689 m_DeviceSurpriseRemoval.m_Method = DispatchTable->EvtDeviceSurpriseRemoval;
2690
2691 m_DeviceUsageNotification.m_Method = DispatchTable->EvtDeviceUsageNotification;
2692 m_DeviceUsageNotificationEx.m_Method = DispatchTable->EvtDeviceUsageNotificationEx;
2693 m_DeviceRelationsQuery.m_Method = DispatchTable->EvtDeviceRelationsQuery;
2694
2695 if (DispatchTable->EvtDeviceSelfManagedIoCleanup != NULL ||
2696 DispatchTable->EvtDeviceSelfManagedIoFlush != NULL ||
2697 DispatchTable->EvtDeviceSelfManagedIoInit != NULL ||
2698 DispatchTable->EvtDeviceSelfManagedIoSuspend != NULL ||
2699 DispatchTable->EvtDeviceSelfManagedIoRestart != NULL) {
2700
2702 this);
2703
2704 if (!NT_SUCCESS(status)) {
2705 return status;
2706 }
2707
2709 }
2710
2711 return STATUS_SUCCESS;
2712}
2713
2714VOID
2717 )
2718{
2720 Callbacks->EvtDeviceArmWakeFromS0;
2722 Callbacks->EvtDeviceArmWakeFromSx;
2724 Callbacks->EvtDeviceArmWakeFromSxWithReason;
2725
2727 Callbacks->EvtDeviceDisarmWakeFromS0;
2729 Callbacks->EvtDeviceDisarmWakeFromSx;
2730
2732 Callbacks->EvtDeviceWakeFromS0Triggered;
2734 Callbacks->EvtDeviceWakeFromSxTriggered;
2735}
2736
2739 __in const GUID* Guid,
2742 )
2743{
2744 // WDF_WMI_PROVIDER_CONFIG config;
2745 // NTSTATUS status;
2746
2747 // WDF_WMI_PROVIDER_CONFIG_INIT(&config, Guid);
2748
2749 // //
2750 // // We are assuming we are registering either for the wait wake or device
2751 // // timeout GUIDs which both operate on BOOLEANs. If we expand this API in
2752 // // the future, have the caller pass in a config structure for the provider
2753 // // GUID.
2754 // //
2755 // config.MinInstanceBufferSize = sizeof(BOOLEAN);
2756
2757 // status = m_Device->m_PkgWmi->AddPowerPolicyProviderAndInstance(
2758 // &config,
2759 // Callbacks,
2760 // Instance);
2761
2762 // if (status == STATUS_OBJECT_NAME_COLLISION) {
2763 // status = STATUS_SUCCESS;
2764 // }
2765
2766 // if (!NT_SUCCESS(status)) {
2767 // DoTraceLevelMessage(
2768 // GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
2769 // "Failed to register WMI power GUID %!STATUS!", status);
2770 // }
2771 //
2772 // return status;
2774 return STATUS_SUCCESS;
2775}
2776
2780 )
2781/*++
2782
2783Routine Description:
2784
2785 Updates the S0 Idle settings for the device and then posts an update event
2786 to the power policy state machine. The first this function is called, the
2787 ability to allow the user to control this setting is set.
2788
2789Arguments:
2790
2791 Settings - The settings to apply.
2792
2793Return Value:
2794
2795 NTSTATUS
2796
2797 --*/
2798{
2799 DEVICE_POWER_STATE dxState;
2800 ULONG idleTimeout;
2802 BOOLEAN enabled, s0Capable, overridable, firstTime;
2803 WDF_TRI_STATE powerUpOnSystemWake;
2804 const LONGLONG negliblySmallIdleTimeout = -1; // 100 nanoseconds
2805
2806 s0Capable = FALSE;
2807 dxState = PowerDeviceD3;
2808 overridable = FALSE;
2809 firstTime = TRUE;
2810
2811 if (Settings->Enabled == WdfTrue) {
2812 enabled = TRUE;
2813
2814 } else if (Settings->Enabled == WdfUseDefault) {
2815 enabled = TRUE;
2816
2819
2820 //
2821 // Read registry. If registry value is not found, the value of "enabled"
2822 // remains unchanged
2823 //
2824 ReadRegistryS0Idle(&valueName, &enabled);
2825 }
2826 else {
2829 "If registry value WdfDefaultIdleInWorkingState was present, "
2830 "it was not read because DDI WdfDeviceAssignS0IdleSettings "
2831 "was not called at PASSIVE_LEVEL");
2832 }
2833 }
2834 else {
2835 enabled = FALSE;
2836 }
2837
2839 firstTime = FALSE;
2840 }
2841
2844 if (!NT_SUCCESS(status)) {
2845 return status;
2846 }
2847
2848 //
2849 // Do not set m_CapsQueried to TRUE yet because we will do that once we
2850 // know the entire stack has been built we will do the query again.
2851 //
2852 }
2853
2854 switch (Settings->IdleCaps) {
2856 case IdleCanWakeFromS0:
2857 s0Capable = TRUE;
2858
2859 if (Settings->DxState == PowerDeviceMaximum) {
2861
2862 //
2863 // Some bus drivers
2864
2865 // incorrectly report DeviceWake=D0 to
2866 // indicate that it does not support wake instead of specifying
2867 // PowerDeviceUnspecified and KMDF ends up requesting
2868 // a D0 irp when going to Dx. The check prevents this bug.
2869 //
2870 if (dxState < PowerDeviceD1 ||
2871 dxState > PowerDeviceD3 ||
2872 (dxState > PowerDeviceD2 && Settings->IdleCaps == IdleUsbSelectiveSuspend)
2873 ) {
2875
2878 "DeviceWake power state reported in device capabilities "
2879 "%!DEVICE_POWER_STATE! indicates that device can not signal"
2880 " a wake event, %!STATUS!",
2881 dxState, status);
2882 return status;
2883 }
2884 }
2885 else {
2886 DEVICE_POWER_STATE dxDeepest;
2887
2888 dxState = Settings->DxState;
2890
2891 if (dxState > dxDeepest) {
2893
2896 "DxState specified by driver %!DEVICE_POWER_STATE! cannot "
2897 "be lighter than lightest available device wake state"
2898 " %!DEVICE_POWER_STATE!, %!STATUS!", dxState,
2899 dxDeepest, status);
2900 return status;
2901 }
2902
2903 //
2904 // Can only perform wait wake from D2 on a USB device
2905 //
2906 if (dxState > PowerDeviceD2 &&
2907 Settings->IdleCaps == IdleUsbSelectiveSuspend) {
2909
2912 "DxState specified by driver %!DEVICE_POWER_STATE! cannot "
2913 "be lighter than PowerDeviceD2 for USB selective suspend "
2914 "%!STATUS!",
2915 dxState, status);
2916 return status;
2917 }
2918 }
2919
2920 if (Settings->IdleCaps == IdleUsbSelectiveSuspend) {
2922
2923 if (!NT_SUCCESS(status)) {
2926 "Failed to initialize USB selective suspend %!STATUS!",
2927 status);
2928 return status;
2929 }
2930 }
2931
2932 break;
2933
2935 s0Capable = FALSE;
2936
2937 if (Settings->DxState == PowerDeviceMaximum) {
2938 dxState = PowerDeviceD3;
2939 }
2940 else {
2941 dxState = Settings->DxState;
2942 }
2943
2944 break;
2945
2946 default:
2947 ASSERT(FALSE);
2948 break;
2949 }
2950
2951 if (Settings->IdleTimeout == IdleTimeoutDefaultValue) {
2952 idleTimeout = FxPowerPolicyDefaultTimeout;
2953 }
2954 else {
2955 idleTimeout = Settings->IdleTimeout;
2956 }
2957
2958 if (Settings->UserControlOfIdleSettings == IdleAllowUserControl) {
2959
2960 // status = UpdateWmiInstanceForS0Idle(AddInstance);
2961 // if (!NT_SUCCESS(status)) {
2962 // return status;
2963 // } __REACTOS__
2964
2965 if (Settings->Enabled == WdfUseDefault) {
2966 //
2967 // Read the registry entry for idle enabled if it's the first time.
2968 //
2969 if (firstTime && Mx::MxGetCurrentIrql() == PASSIVE_LEVEL) {
2971
2972 //
2973 // Read registry. If registry value is not found, the value of
2974 // "enabled" remains unchanged
2975 //
2976 ReadRegistryS0Idle(&valueName, &enabled);
2977 }
2978 else {
2979 //
2980 // Use the saved value for idle enabled.
2981 //
2983 }
2984 }
2985
2986 overridable = TRUE;
2987 }
2988 else if (Settings->UserControlOfIdleSettings == IdleDoNotAllowUserControl) {
2989 //
2990 // No user control
2991 //
2992 overridable = FALSE;
2993
2994 // (void) UpdateWmiInstanceForS0Idle(RemoveInstance); __REACTOS__
2995 }
2996
2997 //
2998 // !!!! DO NOT INTRODUCE FAILURES BEYOND THIS POINT !!!!
2999 //
3000 // We should not introduce any failures that are not due to driver errors
3001 // beyond this point. This is because we are going to commit the driver's
3002 // S0-idle settings now and any failure in the midst of that could leave us
3003 // in a bad state. Therefore, all failable code where the failure is beyond
3004 // the driver's control should be placed above this point.
3005 //
3006 // For example, a driver may want wake-from-S0 support, but the device may
3007 // not support it. We already checked for that failure above, before we
3008 // started committing any of the driver's S0-idle settings.
3009 //
3010 // Any failures below this point should only be due to driver errors, i.e.
3011 // the driver incorrectly calling the AssignS0IdleSettings DDI.
3012 //
3013
3014 if (firstTime) {
3017 }
3018
3019 //
3020 // IdleTimeoutType is available only on > 1.9
3021 //
3022#ifndef __REACTOS__
3024 if (firstTime) {
3025 if ((SystemManagedIdleTimeout == Settings->IdleTimeoutType) ||
3027 Settings->IdleTimeoutType)) {
3028 //
3029 // This is the first time S0-idle policy is being specified and
3030 // the caller has asked for the idle timeout to be determined
3031 // by the power manager.
3032 //
3034 m_TimeoutMgmt.UseSystemManagedIdleTimeout(
3036 );
3037 if (!NT_SUCCESS(status)) {
3038 return status;
3039 }
3040 }
3041 } else {
3042 //
3043 // This is not the first time S0-idle policy is being specified.
3044 // Verify that the caller is not trying to change their mind about
3045 // whether the idle timeout is determined by the power manager.
3046 //
3047 BOOLEAN currentlyUsingSystemManagedIdleTimeout;
3048 BOOLEAN callerWantsSystemManagedIdleTimeout;
3049
3050 currentlyUsingSystemManagedIdleTimeout =
3052 UsingSystemManagedIdleTimeout();
3053 callerWantsSystemManagedIdleTimeout =
3054 ((SystemManagedIdleTimeout == Settings->IdleTimeoutType) ||
3055 (SystemManagedIdleTimeoutWithHint == Settings->IdleTimeoutType));
3056
3057 //
3058 // UMDF currently does not implement
3059 // IdleTimeoutManagement::_SystemManagedIdleTimeoutAvailable. So
3060 // that method must be called only as part of the second check in
3061 // the "if" statement below. Since UMDF currently does not support
3062 // system managed idle timeout, the first check will always evaluate
3063 // to 'FALSE', so the second check never gets executed for UMDF.
3064 //
3065 if ((callerWantsSystemManagedIdleTimeout !=
3066 currentlyUsingSystemManagedIdleTimeout)
3067 &&
3069 ) {
3070
3074 "A previous call to assign S0-idle policy specified that "
3075 "the idle timeout %s be determined by the power manager. "
3076 "This decision cannot be changed. %!STATUS!",
3077 currentlyUsingSystemManagedIdleTimeout ?
3078 "should" :
3079 "should not",
3080 status);
3082 return status;
3083 }
3084 }
3085 }
3086#endif
3087
3088 if (Settings->IdleCaps == IdleCannotWakeFromS0) {
3089 //
3090 // PowerUpIdleDeviceOnSystemWake field added after v1.7.
3091 // By default KMDF uses an optimization where the device is not powered
3092 // up when resuming from Sx if it is idle. The field
3093 // PowerUpIdleDeviceOnSystemWake is used to turn off this optimization and allow
3094 // device to power up when resuming from Sx. Note that this optimization
3095 // is applicable only for IdleCannotWakeFromS0. In other cases the
3096 // device is always powered up in order to arm for wake.
3097 //
3098 powerUpOnSystemWake =
3100 Settings->PowerUpIdleDeviceOnSystemWake :
3102
3103 switch(powerUpOnSystemWake) {
3104 case WdfTrue:
3108 "Driver turned off S0Idle optimization. Device will be "
3109 "powered up on resume from Sx even when it is idle");
3110 break;
3111 case WdfFalse:
3115 "Driver turned on S0Idle optimization. Device will remain "
3116 "powered off if idle when resuming from Sx");
3117 break;
3118 case WdfUseDefault:
3119 DO_NOTHING();
3120 break;
3121 default:
3122 break;
3123 }
3124 }
3125
3126 if (FALSE ==
3128 {
3129 if (Settings->IdleCaps == IdleUsbSelectiveSuspend) {
3132 m_IdleSettings.UsbSSCapabilityKnown = TRUE;
3133
3134 } else if (Settings->IdleCaps == IdleCanWakeFromS0) {
3135
3137 m_IdleSettings.UsbSSCapabilityKnown = TRUE;
3138 }
3139 }
3140
3141 //
3142 // Wake FromS0Capable is set every time because we want to allow the driver
3143 // to swap between idle wake capable and idle not wake capable. This should
3144 // be allowed so that a scenario similar to the following can be implemented:
3145 //
3146 // a) when the device has an outstanding open, the device should arm itself
3147 // for wake when idle
3148 //
3149 // b) when the device does not have an outstanding open, the device should
3150 // be off and not armed.
3151 //
3152 // The only way to be off is to assign S0 wake settings, so the
3153 // WakeFromS0Capable field must change on each DDI call. This is not a
3154 // problem for the power policy state machine because it evaluates
3155 // WakeFromS0Capable state before enabling of idle. If we are not
3156 // WakeFromS0Capable and USB SS capable (ie a have a torn/unsynchronized
3157 // state) in m_IdleSettings, we will recover from it when processing
3158 // PwrPolS0IdlePolicyChanged in the state machine (b/c this event causes
3159 // both fields to be reevaluated).
3160 //
3162
3164
3166 m_IdleSettings.m_TimeoutMgmt.UsingSystemManagedIdleTimeout()) {
3167 //
3168 // With system managed idle timeout, we don't want to apply an idle
3169 // timeout of our own on top of that. Effectively, our idle timeout is
3170 // 0.
3171 // But we apply a negligibly small timeout value as this allows us to
3172 // keep the same logic in the idle state machine, regardless of whether
3173 // we're using system-managed idle timeout or driver-managed idle
3174 // timeout.
3175 //
3176 if (firstTime) {
3178 m_PowerIdleMachine.m_PowerTimeout.QuadPart =
3179 negliblySmallIdleTimeout;
3180 }
3181
3182 if (SystemManagedIdleTimeoutWithHint == Settings->IdleTimeoutType) {
3183 //
3184 // We save the idle timeout hint, but we don't provide the hint to
3185 // the power framework immediately. This is because currently we may
3186 // or may not be registered with the power framework. Note that
3187 // WdfDeviceAssignS0IdleSettings might get called even when we are
3188 // not registered with the power framework.
3189 //
3190 // Therefore, we provide the hint to the power framework only when
3191 // we get to the WdfDevStatePwrPolStartingDecideS0Wake state. This
3192 // state is a good choice for providing the hint because:
3193 // 1. We know we would be registered with the power framework when
3194 // we are in this state.
3195 // 2. Any change in S0-idle settings causes us to go through this
3196 // state.
3197 //
3199 idleTimeout;
3200 }
3201
3202 } else {
3204 = WDF_REL_TIMEOUT_IN_MS(idleTimeout);
3205 }
3206
3207 //
3208 // If the driver is 1.11 or later, update the bus drivers with the client's
3209 // choice on the topic of D3hot or D3cold.
3210 //
3212 (Settings->ExcludeD3Cold != WdfUseDefault)) {
3214 BOOLEAN enableD3Cold;
3215
3217
3218 switch (Settings->ExcludeD3Cold) {
3219 case WdfFalse:
3220 enableD3Cold = TRUE;
3221 break;
3222 default:
3225 "Invalid tri-state value for ExcludeD3Cold %d",
3226 Settings->ExcludeD3Cold);
3228 case WdfTrue:
3229 enableD3Cold = FALSE;
3230 break;
3231 }
3232
3234 &deviceObject,
3236 enableD3Cold);
3237 }
3238
3240
3241 return STATUS_SUCCESS;
3242}
3243
3247 __in BOOLEAN ArmForWakeIfChildrenAreArmedForWake,
3248 __in BOOLEAN IndicateChildWakeOnParentWake
3249 )
3250/*++
3251
3252Routine Description:
3253
3254 Updates the Sx wake settings for the device. No event is posted to the
3255 state machine because this setting is statically checked when the machine
3256 is entering an Sx state (unlike S0 idle which can be checked at any time).
3257
3258 The first this function is called, the ability to allow the user to control
3259 this setting is set.
3260
3261Arguments:
3262
3263 Settings - the new settings to apply
3264
3265 ArmForWakeIfChildrenAreArmedForWake - Inidicates whether the device
3266 should arm for wake when one or more children are armed for wake
3267
3268 IndicateChildWakeOnParentWake - Indicates whether the device should
3269 propagate the wake status to its children
3270
3271Return Value:
3272
3273 NTSTATUS
3274
3275 --*/
3276{
3277 DEVICE_POWER_STATE dxState;
3279 BOOLEAN overridable, firstTime, enabled;
3280
3281 dxState = PowerDeviceD3;
3282 overridable = FALSE;
3283 firstTime = TRUE;
3284
3285 if (Settings->Enabled == WdfTrue) {
3286 enabled = TRUE;
3287
3288 }
3289 else if (Settings->Enabled == WdfUseDefault) {
3290 enabled = TRUE;
3291
3294
3295 //
3296 // Read registry. If registry value is not found, the value of "enabled"
3297 // remains unchanged
3298 //
3299 ReadRegistrySxWake(&valueName, &enabled);
3300 }
3301 else {
3304 "If registry value WdfDefaultWakeFromSleepState was present, "
3305 "it was not read because DDI WdfDeviceAssignSxWakeSettings "
3306 "was not called at PASSIVE_LEVEL");
3307 }
3308 }
3309 else {
3310 enabled = FALSE;
3311 }
3312
3314 firstTime = FALSE;
3315 }
3316
3319 if (!NT_SUCCESS(status)) {
3320 return status;
3321 }
3322
3323 //
3324 // Do not set m_CapsQueried to TRUE yet because we will do that once we
3325 // know the entire stack has been built we will do the query again.
3326 //
3327 }
3328
3329 if (Settings->DxState == PowerDeviceMaximum) {
3331
3332 //
3333 // Some bus drivers
3334
3335 // incorrectly report DeviceWake=D0 to
3336 // indicate that it does not support wake instead of specifying
3337 // PowerDeviceUnspecified and KMDF ends up requesting
3338 // a D0 irp when going to Dx. The check prevents this bug.
3339 //
3340 if (dxState < PowerDeviceD1 || dxState > PowerDeviceD3) {
3342
3345 "DeviceWake power state reported in device capabilities "
3346 "%!DEVICE_POWER_STATE! indicates that device can not signal a "
3347 "wake event, %!STATUS!",
3348 dxState, status);
3349 return status;
3350 }
3351 }
3352 else {
3353 DEVICE_POWER_STATE dxDeepest;
3354
3355 dxState = Settings->DxState;
3357
3358 if (dxState > dxDeepest) {
3362 "DxState specified by driver %!DEVICE_POWER_STATE! cannot be"
3363 " lighter than lightest available device wake state "
3364 "%!DEVICE_POWER_STATE!, %!STATUS!", dxState,
3365 dxDeepest, status);
3366 return status;
3367 }
3368 }
3369
3370 if (Settings->UserControlOfWakeSettings == WakeAllowUserControl) {
3371
3372 // status = UpdateWmiInstanceForSxWake(AddInstance); __REACTOS__
3373
3374 // if (!NT_SUCCESS(status)) {
3375 // return status;
3376 // }
3377
3378 if (Settings->Enabled == WdfUseDefault) {
3379 //
3380 // Read the registry entry for wake enabled if it's the first time.
3381 //
3382 if (firstTime && Mx::MxGetCurrentIrql() == PASSIVE_LEVEL) {
3384
3385 //
3386 // Read registry. If registry value is not found, the value of
3387 // "enabled" remains unchanged
3388 //
3389 ReadRegistrySxWake(&valueName, &enabled);
3390 }
3391 else {
3392 //
3393 // Use the saved value for wake enabled.
3394 //
3396 }
3397 }
3398
3399 overridable = TRUE;
3400 }
3401 else if (Settings->UserControlOfWakeSettings == WakeDoNotAllowUserControl) {
3402 //
3403 // No user control, just set to enabled
3404 //
3405 overridable = FALSE;
3406
3407 // (void) UpdateWmiInstanceForSxWake(RemoveInstance); __REACTOS__
3408 }
3409
3410 if (firstTime) {
3413
3414 //
3415 // If ArmForWakeIfChildrenAreArmedForWake setting is set to FALSE,
3416 // then we use the legacy framework behavior which did not depend
3417 // on the child device being capable of arming for wake or not.
3418 //
3420 ArmForWakeIfChildrenAreArmedForWake;
3421
3422 //
3423 // If IndicateChildWakeOnParentWake setting is set to FALSE, then
3424 // we use the legacy framework behavior wherein the wake status
3425 // is not propagated from the parent device to the child device.
3426 //
3428 IndicateChildWakeOnParentWake;
3429 }
3430
3432
3434
3435 return STATUS_SUCCESS;
3436}
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3457 __in FxWmiInstanceInternal* /* Instance */,
3458 __in ULONG /* OutBufferSize */,
3461 )
3462{
3463 *((BOOLEAN*) OutBuffer) =
3465 *BufferUsed = sizeof(BOOLEAN);
3466
3467 return STATUS_SUCCESS;
3468}
3469
3473 __in FxWmiInstanceInternal* /* Instance */,
3474 __in ULONG /* InBufferSize */,
3475 __in PVOID InBuffer
3476 )
3477{
3478 BOOLEAN value;
3479
3480
3481 //
3482 // FxWmiIrpHandler makes sure the buffer is at least one byte big, so we
3483 // don't check the buffer size.
3484 //
3485
3486 value = *(PBOOLEAN) InBuffer;
3487
3489
3490 return STATUS_SUCCESS;
3491}
3492
3496 __in FxWmiInstanceInternal* /* Instance */,
3499 __in PVOID InBuffer
3500 )
3501{
3502 BOOLEAN value;
3503
3504 if (DataItemId != 0) {
3506 }
3507
3508 if (InBufferSize < sizeof(BOOLEAN)) {
3510 }
3511
3512 value = *(BOOLEAN*) InBuffer;
3514
3515 return STATUS_SUCCESS;
3516}
3517
3521 __in FxWmiInstanceInternal* /* Instance */,
3522 __in ULONG /* OutBufferSize */,
3525 )
3526{
3527 *((BOOLEAN*) OutBuffer) =
3529 *BufferUsed = sizeof(BOOLEAN);
3530
3531 return STATUS_SUCCESS;
3532}
3533
3537 __in FxWmiInstanceInternal* /* Instance */,
3538 __in ULONG /* InBufferSize */,
3539 __in PVOID InBuffer
3540 )
3541{
3542 BOOLEAN value;
3543
3544 //
3545 // FxWmiIrpHandler makes sure that the buffer is at least one byte big, so
3546 // we don't check the buffer size
3547 //
3548 value = *(PBOOLEAN) InBuffer;
3549
3551
3552 return STATUS_SUCCESS;
3553}
3554
3558 __in FxWmiInstanceInternal* /* Instance */,
3561 __in PVOID InBuffer
3562 )
3563{
3564 BOOLEAN value;
3565
3566 if (DataItemId != 0) {
3568 }
3569
3570 if (InBufferSize < sizeof(BOOLEAN)) {
3572 }
3573
3574 value = *(BOOLEAN*) InBuffer;
3576
3577 return STATUS_SUCCESS;
3578}
3579
3583 __in SYSTEM_POWER_STATE QueryState
3584 )
3585/*++
3586
3587Framework Philosophy Discussion:
3588
3589 WDM sends IRP_MN_QUERY_POWER for system power states (where system power
3590 states are S0-working, S1-light-sleep, S2-deeper-sleep, S3-deepest-sleep,
3591 S4-hibernation, S5-soft-off.) The idea is that, if a driver can't support
3592 a particular state, it fails the query. The problem is that this idea is
3593 horribly broken.
3594
3595 The first problem is that WDM doesn't always send these IRPs. In some
3596 situations, (very low battery, system getting critically hot) WDM will
3597 attempt to preserve user data by sleeping or hibernating, rather than just
3598 crashing. This is good, but it makes a driver writer's life very difficult,
3599 since it means that you have to deal with being told to go to a particular
3600 state even if you think that your device won't be able to deal well with
3601 that state.
3602
3603 The second problem is that, by the time the system is going to sleep, the
3604 user probably isn't still looking at the screen. This is especially true
3605 for laptop computers, as the system is very likely sleeping because the
3606 user closed the clamshell lid. So any attempt to ask the user how to
3607 resolve a situation where a driver doesn't want to go to a low power state
3608 is futile. Furthermore, even when the screen is still available, users
3609 dislike it when they push the sleep button or the power button on their
3610 machines and the machines don't do what they were told to do.
3611
3612 The third problem is related to the second. While there may be completely
3613 legitimate reasons for the driver to want to delay or even to veto a
3614 transition into a sleep state, (an example of a valid scenario would be one
3615 in which the driver was involved in burning a CD, an operation which can't
3616 be interrupted,) there isn't any good way for a driver to interact with a
3617 user anyhow. (Which desktop is the right one to send messages to? What
3618 should the UI for problem resolution look like? How does a driver put up
3619 UI anyhow?)
3620
3621 All the driver really knows is that it will or won't be able to maintain
3622 device state, and it will or won't be able to get enough power to arm
3623 any wake events that it might want to deliver (like PME#.)
3624
3625 Consequently, the designers of the PnP/Power model in the Framework have
3626 decided that all QueryPower-Sx IRPs will be completed successfully
3627 except if the device cannot maintain enough power to trigger its wake
3628 signal *AND* if the system supports lighter sleep states than the
3629 one that is currently being queried. (If it does, then the kernel's power
3630 manager will turn right around and query for those, next.)
3631
3632 This story usually brings up a few objections:
3633
3634 1) My device is important! When it's operating, I don't want
3635 the machine to just fall asleep. I need to fail QueryPower-Sx to
3636 prevent that.
3637
3638 This objection is an unfortunate consequence of the existing DDK. There
3639 is a perfectly good API that allows a driver to say that the machine
3640 shouldn't just fall asleep. (See PoSetSystemState.) If a user presses
3641 a button telling the machine to go to sleep, then the driver has a
3642 responsibility to do that.
3643
3644 2) There are certain operations that just can't be interrupted!
3645
3646 While that's true, those operations started somewhere, probably in user-
3647 mode. Those same user-mode components would be much, much better suited
3648 toward negotiating with the user or with other components to figure out
3649 what to do when the uninterruptable must be interrupted. User-mode
3650 components get notification that the system is going to sleep and they
3651 can delay or veto the transition. Get over the idea that your driver
3652 needs to be involved, too.
3653
3654Routine Description:
3655
3656 Determines if for the passed in System state, if we can wake the machine
3657 from it. If the query state is the machine's minimum system state, then
3658 we always succeed it because we want the machine to go to at least some
3659 sleeping state. We always succeed hibernate and system off requests as well.
3660
3661Arguments:
3662
3663 QueryState - The proposed system state
3664
3665Return Value:
3666
3667 NT_SUCCESS if the queried state should be allowed, !NT_SUCCESS otherwise
3668
3669 --*/
3670{
3671 PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();
3673
3674 if (QueryState >= PowerSystemHibernate ||
3676 //
3677 // If the query is for the machine's minimum S state or we going into
3678 // hibernate or off, always succeed it.
3679 //
3681 }
3682 else {
3683
3684 //
3685 // On Windows Vista and above, its OK to return a failure status code
3686 // if the system is going into an S state at which the device cannot
3687 // wake the system.
3688 //
3690
3691 //
3692 // The S state the machine is going into is one where we can't
3693 // wake it up because our D state is too low for this S state.
3694 // Since this isn't the minimum S state the machine is capable
3695 // of, reject the current query.
3696 //
3698 FxDriverGlobals, TRACE_LEVEL_WARNING, TRACINGPNP,
3699 "failing system query power because the device cannot wake the "
3700 "machine from S%d",
3701 QueryState - 1);
3702
3704 }
3705
3706 return status;
3707}
3708
3709VOID
3712 )
3713{
3717}
3718
3719VOID
3722 )
3723/*++
3724
3725Routine Description:
3726 Sets the wake from Sx state
3727
3728 No need to post an event to the power policy state machine because we
3729 will not change any active due to a change in this setting. We only
3730 evaluate this state when going into Sx and once in this state we will not
3731 change our behavior until the next Sx, which will then evaluate this state.
3732
3733Arguments:
3734 State - New state
3735
3736Return Value:
3737 VOID
3738
3739 --*/
3740{
3743
3744 //
3745 // Since we are not posting an event to the power policy state machine, try
3746 // to write out the value now, otherwise it will be written when we
3747 // transition
3748 //
3752
3753 timeout = 0;
3754
3755 //
3756 // If the lock is already acquired on this thread, this will fail, which
3757 // is OK.
3758 //
3761 &timeout
3762 );
3763
3764 if (FxWaitLockInternal::IsLockAcquired(status)) {
3765 SaveState(TRUE);
3766
3769 );
3770 }
3771 }
3772}
3773
3774VOID
3777 )
3778/*++
3779
3780Routine Description:
3781 Marks the device as a victim of catastrophic failure, either in software
3782 or in hardware.
3783
3784 If AttemptToRestart is TRUE, then we should try to get the stack re-built
3785 after it has been torn down. This would typically be the case the failure
3786 was in the software, and possibly not be the case if the failure was in
3787 the hardware.
3788
3789Arguments:
3790 FailedAction - action to take once the stack has been removed
3791
3792Return Value:
3793 None
3794
3795 --*/
3796{
3798 MdDeviceObject pdo;
3799
3800#if (FX_CORE_MODE == FX_CORE_USER_MODE)
3801 if (GetDriverGlobals()->IsVersionGreaterThanOrEqualTo(2, 15) == FALSE &&
3803
3807 "WdfDeviceFailedAttemptRestart is only available for UMDF 2.15 "
3808 "and later drivers. Reverting to WdfDeviceFailedNoRestart.");
3809 }
3810#endif
3811
3813
3814 //
3815 // This will cause the PnP manager to tear down this stack, even if
3816 // the PDO can't be surprise-removed.
3817 //
3818 m_Failed = TRUE;
3819
3821 //
3822 // Attempt to get the PDO surprise-removed.
3823 //
3825
3826 if (NT_SUCCESS(status)) {
3827 return;
3828 }
3829 }
3830
3831#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
3832 //
3833 // In between creating a PDO WDFDEVICE and it starting, if this DDI is called,
3834 // we will not have a valid PDO. Make sure it is valid before we proceed.
3835 //
3837
3838 if (pdo != NULL) {
3839 //
3840 // Now tell the PnP manager to re-query us for our state.
3841 //
3842 MxDeviceObject physicalDeviceObject(pdo);
3843
3844 physicalDeviceObject.InvalidateDeviceState(
3846 );
3847 }
3848#else // USER_MODE
3852#endif
3853}
3854
3860 )
3861{
3862 return This->PnpDeviceUsageNotification(Irp);
3863}
3864
3869 )
3870{
3872 FxRelatedDevice *pDependent;
3873 FxAutoIrp relatedIrp(NULL), parentIrp(NULL);
3874 MxDeviceObject topOfParentStack;
3877 MxDeviceObject pAttached;
3878 MdIrp pNewIrp;
3880 BOOLEAN inPath, supported;
3881 ULONG oldFlags;
3882 MxAutoWorkItem workItem;
3883
3885 "Entering DeviceUsageNotification handler");
3886
3888
3889 type = Irp->GetParameterUsageNotificationType();
3890 inPath = Irp->GetParameterUsageNotificationInPath();
3891 supported = FALSE;
3892
3895 "type %x, in path %x, can support paging %x, dump file %x, "
3896 "hiber file %x, boot file %x",
3897 type, inPath,
3902
3903
3906 if (inPath) {
3907 if (m_Device->IsFilter()) {
3908 //
3909 // Filters always support usage notifications
3910 //
3911 supported = TRUE;
3912 }
3913 else {
3914 supported = IsUsageSupported(type);
3915 }
3916 }
3917 else {
3918 //
3919 // We always handle notifications where we are out of the path
3920 //
3921 supported = TRUE;
3922 }
3923 }
3924
3925 if (supported == FALSE) {
3927
3930 "Usage type %x not supported, %!STATUS!", type, status);
3931
3932 return CompletePnpRequest(Irp, status);
3933 }
3934
3935 //
3936 // Usage notification IRP gets forwarded to parent stack or to
3937 // dependent stack. Since in such cases (with deep device tree) the stack
3938 // may run out quickly, ensure there is enough stack, otherwise use a
3939 // workitem.
3940 //
3942 (m_Device->IsPdo() ||
3944
3945 status = workItem.Allocate(m_Device->GetDeviceObject());
3946 if (!NT_SUCCESS(status)) {
3949 "WDFDEVICE %p !devobj %p could not allocate workitem "
3950 "to send usage notification type %d, inpath %d, %!STATUS!",
3953 type, inPath, status);
3954
3955 return CompletePnpRequest(Irp, status);
3956 }
3957 }
3958
3959 //
3960 // Usage notification is supported. Set the flags on the device object
3961 // before processing this any further and save the current flags on the
3962 // device object.
3963 //
3964 oldFlags = SetUsageNotificationFlags(type, inPath);
3965
3966 if (m_Device->IsPdo()) {
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979 topOfParentStack.SetObject(
3981
3982 pNewIrp = FxIrp::AllocateIrp(topOfParentStack.GetStackSize());
3983 if (pNewIrp != NULL) {
3984 parentIrp.SetIrp(pNewIrp);
3985
3986 //
3987 // parentIrp now owns the irp
3988 //
3989 pNewIrp = NULL;
3990
3991 status = SendDeviceUsageNotification(&topOfParentStack,
3992 &parentIrp,
3993 &workItem,
3994 Irp,
3995 FALSE);
3996 }
3997 else {
3999
4002 "WDFDEVICE %p could not allocate PIRP for parent !devobj %p to "
4003 "send usage notification type %d, inpath %d, %!STATUS!",
4004 m_Device->GetHandle(), topOfParentStack.GetObject(),
4005 type, inPath, status);
4006 }
4007 topOfParentStack.DereferenceObject();
4008 topOfParentStack.SetObject(NULL);
4009
4010 if (!NT_SUCCESS(status)) {
4012 "Exit %!STATUS!", status);
4013
4014 RevertUsageNotificationFlags(type, inPath, oldFlags);
4015 return CompletePnpRequest(Irp, status);
4016 }
4017 }
4018
4019 maxStack = 0;
4020 pDependent = NULL;
4021
4022 //
4023 // If the driver supports the given special file, lets notify dependent
4024 // stacks.
4025 //
4026
4027 //
4028 // LockForEnum will lock out new changes to the list until we unlock the list.
4029 // We remain at passive level once we are locked.
4030 //
4032 //
4033 // We capture the m_UsageDependentDeviceList pointer value so that we
4034 // always use the same pointer value and that we have matched actions
4035 // (lock for enum / unlock from enum). What we are trying to avoid is
4036 // this:
4037 // 1) we do not lock for enum because m_UsageDependentDeviceList == NULL
4038 // 2) in the middle of this function, m_UsageDependentDeviceList is
4039 // assigned a pointer value
4040 // 3) we try to unlock from enum later (or iterate, thinking the enum
4041 // lock is held) by checking m_UsageDependentDeviceList for NULL, and
4042 // now that is != NULL, use it.
4043 //
4044 // By capturing the pointer now, we either have a list or not and we don't
4045 // hit situations 2 or 3. So, the rule is every subseqeunt time we need
4046 // to check if there is valid m_UsageDependentDeviceList pointer, we
4047 // use pList, but when we use the list, we can use m_UsageDependentDeviceList
4048 // directly.
4049 //
4051
4053
4054 while ((pDependent = m_UsageDependentDeviceList->GetNextEntry(pDependent)) != NULL) {
4055
4056 MxDeviceObject deviceObject(pDependent->GetDevice());
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4071
4072 if (pAttached.GetStackSize() > maxStack) {
4073 maxStack = pAttached.GetStackSize();
4074 }
4075
4076 pAttached.DereferenceObject();
4077 }
4078 }
4079 else {
4080 pList = NULL;
4081 }
4082
4083 if (maxStack > 0) {
4084 //
4085 // If we have a maxStack size, we have a list as well
4086 //
4088
4089 //
4090 // Allocate one irp for all the stacks so that we don't have an
4091 // allocation later. This way, once we have the irp, we can send the
4092 // usage notification to all stacks reliably, as well as the reverting
4093 // of the notification if we encounter failure.
4094 //
4095 pNewIrp = FxIrp::AllocateIrp(maxStack);
4096 if (pNewIrp == NULL) {
4098
4101 "WDFDEVICE %p could not allocate IRP to send usage notifications"
4102 " to related stacks, type %d, inpath %d, status %!STATUS!",
4103 m_Device->GetHandle(), type, inPath, status);
4104 }
4105 else {
4106 MxDeviceObject dependentDevice;
4107
4108 //
4109 // relatedIrp will free the irp when it goes out of scope
4110 //
4111 relatedIrp.SetIrp(pNewIrp);
4112
4113 //
4114 // Walk our collection of dependent device stacks, and notify
4115 // each stack of the device notification. If any fail, notify
4116 // the stacks who already were told of the reverted behavior.
4117 //
4118 pDependent = NULL;
4119 while ((pDependent = m_UsageDependentDeviceList->GetNextEntry(pDependent)) != NULL) {
4120 dependentDevice.SetObject(pDependent->GetDevice());
4121 status = SendDeviceUsageNotification(&dependentDevice,
4122 &relatedIrp,
4123 &workItem,
4124 Irp,
4125 FALSE);
4126
4127 if (!NT_SUCCESS(status)) {
4128 FxRelatedDevice* pDependent2;
4129
4130 pDependent2 = NULL;
4131
4132 //
4133 // A device failed the device usage notification request.
4134 // Notify the stacks that didn't fail, so they can unwind
4135 // the operation.
4136 //
4137 while ((pDependent2 = m_UsageDependentDeviceList->GetNextEntry(pDependent2)) != NULL &&
4138 pDependent2 != pDependent) {
4139 dependentDevice.SetObject(pDependent2->GetDevice());
4140
4141 //
4142 // We're already in a failure path. We can't do anything
4143 // about yet another failure. So we ignore the return
4144 // value.
4145 //
4146 (void) SendDeviceUsageNotification(&dependentDevice,
4147 &relatedIrp,
4148 &workItem,
4149 Irp,
4150 TRUE);
4151 }
4152
4153 //
4154 // Now break out of our outter loop.
4155 //
4156 break;
4157 }
4158 }
4159 }
4160 }
4161
4162 //
4163 // If we are successful to this point, then send the IRP down the
4164 // stack.
4165 //
4166 if (NT_SUCCESS(status)) {
4167 BOOLEAN referenceSucceeded, sendDown;
4168
4169 referenceSucceeded = FALSE;
4170 sendDown = TRUE;
4171
4172 //
4173 // Make sure the stack is in D0 before sending down the request. This
4174 // will at least guarantee that all devices below this one are in D0
4175 // when the make the transition from power pageable to non or vice versa.
4176 //
4177 if (IsPowerPolicyOwner()) {
4179
4180 if (NT_SUCCESS(status)) {
4181 referenceSucceeded = TRUE;
4182 }
4183 else {
4184 Irp->SetStatus(status);
4185 sendDown = FALSE;
4186 }
4187 }
4188
4189 if (sendDown) {
4190 //
4191 // If we supported the usage, set the status to success, otherwise we
4192 // keep the status in the irp as it arrived to this device
4193 //
4194 if (supported) {
4195 Irp->SetStatus(status);
4196 }
4198 }
4199
4200 //
4201 // Transitioning from a thread which was power pagable to non power
4202 // pagable. We now need a power thread for the stack, ask for it.
4203 // Note that there is no need for power thread in case of "boot"
4204 // notification since boot notification doesn't require clearing device's
4205 // DO_POWER_PAGABLE flag (power thread is required when handling power
4206 // irp at dispatch level which can happen if the DO_POWER_PAGABLE flag
4207 // is cleared).
4208 //
4209 // NOTE: Once we have a power thread, we never go back to using work
4210 // items even though the stack may revert to power pagable.
4211 // This is an acceptable tradeoff between resource usage and
4212 // WDF complexity.
4213 //
4214 //
4215 if (NT_SUCCESS(status) &&
4216 inPath &&
4217 (HasPowerThread() == FALSE) &&
4219 ) {
4221
4222 if (!NT_SUCCESS(status)) {
4223 //
4224 // Keep status the same through out so we can set it back in
4225 // the irp when we are done.
4226 //
4227 if (m_Device->IsPdo()) {
4228 //
4229 // need to revert our parent's stack
4230 //
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243 topOfParentStack.SetObject(
4245
4246 //
4247 // Ignore the status because we can't do anything on failure
4248 //
4249 (void) SendDeviceUsageNotification(&topOfParentStack,
4250 &parentIrp,
4251 &workItem,
4252 Irp,
4253 TRUE);
4254
4255 topOfParentStack.DereferenceObject();
4256 }
4257 else {
4258 //
4259 // Notify the stack below us
4260 //
4261 Irp->CopyCurrentIrpStackLocationToNext();
4262 Irp->SetParameterUsageNotificationInPath(FALSE);
4263
4264 //
4265 // Required for pnp irps
4266 //
4267 Irp->SetStatus(STATUS_NOT_SUPPORTED);
4268
4269 //
4270 // Ignore the status because we can't do anything on failure
4271 //
4272 (void) Irp->SendIrpSynchronously(m_Device->GetAttachedDevice());
4273 }
4274
4275 Irp->SetStatus(status);
4276 }
4277 }
4278
4279 //
4280 // Now check whether the lower devices succeeded or failed. If they
4281 // failed, back out our changes and propogate the failure.
4282 //
4283 if (!NT_SUCCESS(status)) {
4284 //
4285 // Revert the flags set on the device object.
4286 //
4287 RevertUsageNotificationFlags(type, inPath, oldFlags);
4288
4289 //
4290 // Notify dependent stacks of the failure.
4291 //
4292 pDependent = NULL;
4293
4294 //
4295 // See pList initiatilazation as to why we compare pList for != NULL
4296 // and not m_UsageDependentDeviceList.
4297 //
4298 if (pList != NULL) {
4299 MxDeviceObject dependentDevice;
4300
4301 while ((pDependent = m_UsageDependentDeviceList->GetNextEntry(pDependent)) != NULL) {
4302 dependentDevice.SetObject(pDependent->GetDevice());
4303
4304 //
4305 // We're already in a failure path. We can't do anything
4306 // about yet another failure. So we ignore the return value.
4307 //
4308 (void) SendDeviceUsageNotification(&dependentDevice,
4309 &relatedIrp,
4310 &workItem,
4311 Irp,
4312 TRUE);
4313 }
4314 }
4315 }
4316
4317 //
4318 // By this point, we have propagated the notification to dependent devices
4319 // and lower stack, and if anyone failed during that time, we also
4320 // propagated failure to dependent stacks and lower stack.
4321 // If status is success at this point, invoke the driver's callback.
4322 //
4323 if (NT_SUCCESS(status)) {
4324 //
4325 // Invoke callback. Note that only one of the callbacks
4326 // DeviceUsageNotification or DeviceUsgeNotificationEx will get
4327 // invoked since only one of the callbacks at a time is supported.
4328 // We ensured that during registration of the callback.
4329 // Note that Ex callback will return success if driver did not
4330 // supply any callback.
4331 //
4334 inPath);
4335
4339 inPath
4340 );
4341
4342 if (!NT_SUCCESS(status)) {
4343 //
4344 // Driver's callback returned failure. We need to propagate
4345 // failure to lower stack and dependent stacks.
4346 //
4347 //
4348 // Keep status the same through out so we can set it back in
4349 // the irp when we are done.
4350 //
4351 if (m_Device->IsPdo()) {
4352 //
4353 // need to revert our parent's stack
4354 //
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367 topOfParentStack.SetObject(
4369
4370 //
4371 // Ignore the status because we can't do anything on failure
4372 //
4373 (void) SendDeviceUsageNotification(&topOfParentStack,
4374 &parentIrp,
4375 &workItem,
4376 Irp,
4377 TRUE);
4378
4379 topOfParentStack.DereferenceObject();
4380 }
4381 else {
4382 //
4383 // Notify the stack below us
4384 //
4385 Irp->CopyCurrentIrpStackLocationToNext();
4386 Irp->SetParameterUsageNotificationInPath(FALSE);
4387
4388 //
4389 // Required for pnp irps
4390 //
4391 Irp->SetStatus(STATUS_NOT_SUPPORTED);
4392
4393 //
4394 // Ignore the status because we can't do anything on failure
4395 //
4396 (void) Irp->SendIrpSynchronously(m_Device->GetAttachedDevice());
4397 }
4398
4399 Irp->SetStatus(status);
4400
4401 //
4402 // Revert the flags set on the device object.
4403 //
4404 RevertUsageNotificationFlags(type, inPath, oldFlags);
4405
4406 //
4407 // Notify dependent stacks of the failure.
4408 //
4409 pDependent = NULL;
4410
4411 //
4412 // See pList initiatilazation as to why we compare pList for != NULL
4413 // and not m_UsageDependentDeviceList.
4414 //
4415 if (pList != NULL) {
4416 MxDeviceObject dependentDevice;
4417
4418 while ((pDependent = m_UsageDependentDeviceList->GetNextEntry(pDependent)) != NULL) {
4419 dependentDevice.SetObject(pDependent->GetDevice());
4420
4421 //
4422 // We're already in a failure path. We can't do anything
4423 // about yet another failure. So we ignore the return value.
4424 //
4425 (void) SendDeviceUsageNotification(&dependentDevice,
4426 &relatedIrp,
4427 &workItem,
4428 Irp,
4429 TRUE);
4430 }
4431 }
4432 }
4433
4434 if (NT_SUCCESS(status)) {
4435
4436 CommitUsageNotification(type, oldFlags);
4437
4438 //
4439 // If we are in the dump file path, we cannot idle out because we
4440 // can experience a crash dump at any time.
4441 //
4443 //
4444 // Add a reference everytime we are notified of being in the
4445 // path, no need to match the first inPath notification and the
4446 // last !inPath notification.
4447 //
4448 if (inPath) {
4449 NTSTATUS refStatus;
4450
4452
4453 //
4454 // Since our previous synchronous power reference succeeded,
4455 // an addtional reference while we are powered up should
4456 // never fail.
4457 //
4458 refStatus = PowerReference(FALSE);
4459#if DBG
4460 ASSERT(NT_SUCCESS(refStatus));
4461#else
4462 UNREFERENCED_PARAMETER(refStatus);
4463#endif
4464 }
4465 else {
4466 ASSERT(GetUsageCount(type) >= 0);
4468 }
4469 }
4470 }
4471 }
4472
4473 //
4474 // We no longer need to be in D0 if we don't have to be.
4475 //
4476 if (referenceSucceeded) {
4479 }
4480 }
4481
4482 //
4483 // See pList initiatilazation as to why we compare pList for != NULL
4484 // and not m_UsageDependentDeviceList.
4485 //
4486 if (pList != NULL) {
4488 }
4489
4491 "Exit %!STATUS!", status);
4492
4493 return CompletePnpRequest(Irp, status);
4494}
4495
4496ULONG
4499 __in BOOLEAN InPath
4500 )
4501/*++
4502
4503Routine Description:
4504
4505 This routine sets the usage notification flags on the device object (for
4506 non-boot usages) and updates the special file usage count .
4507
4508Arguments:
4509
4510 Type - the special file type - paging, hibernate, dump or boot file.
4511
4512 InPath - indicates whether the system is creating or removing the special
4513 file on the device.
4514
4515Return Value:
4516
4517 Returns the old flags on the device object.
4518
4519--*/
4520{
4521 PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();
4522 ULONG oldFlags, newFlags;
4523
4524 oldFlags = m_Device->GetDeviceObjectFlags();
4525
4526 //
4527
4528 //
4530 FxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP,
4531 "Before: type %d, in path %d, special count %d, flags 0x%x, "
4532 "device %p (WDFDEVICE %p), is pageable capable %d",
4533 Type, InPath, GetUsageCount(Type), oldFlags,
4536
4537 //
4538 // Adjust our "special file count".
4539 //
4540 AdjustUsageCount(Type, InPath);
4541
4542 //
4543 // Boot notification doesn't require updating device flags.
4544 //
4546 return oldFlags;
4547 }
4548
4549 if (m_Device->IsFilter()) {
4550 //
4551 // Clear the previous flags and reset them to the attached
4552 // device's flags
4553 //
4554 newFlags = oldFlags & ~(DO_POWER_PAGABLE | DO_POWER_INRUSH);
4555 newFlags |= m_Device->GetAttachedDeviceObjectFlags() &
4557 m_Device->SetDeviceObjectFlags(newFlags);
4558 }
4559 else {
4560 if (InPath) {
4562 m_Device->GetDeviceObjectFlags() & ~DO_POWER_PAGABLE
4563 );
4564 }
4565 else {
4569 );
4570 }
4571 }
4572 }
4573
4574 return oldFlags;
4575}
4576
4577VOID
4580 __in BOOLEAN InPath,
4582 )
4583/*++
4584
4585Routine Description:
4586
4587 This routine reverts the usage notification flags to the old flags on
4588 the device object and updates the special file usage count.
4589
4590Arguments:
4591
4592 Type - the special file type - paging, hibernate or dump file.
4593
4594 InPath - indicates whether the system is creating or removing the special
4595 file on the device.
4596
4597 OldFlags - the previous flags on the device object.
4598
4599--*/
4600{
4601 //
4602 // Re-adjust our "special file count".
4603 //
4604 InPath = !InPath;
4605 AdjustUsageCount(Type, InPath);
4606
4607 //
4608 // Restore the flags on the device object.
4609 //
4611}
4612
4613VOID
4617 )
4618/*++
4619
4620Routine Description:
4621
4622 This routine commits the usage notification flags on the device object
4623 and invokes the usage notification callbacks. If the current flags on
4624 the device object indicates that there was a transition from power-pagable
4625 to non power-pagable, or vice-versa, then an event is posted to the power
4626 state machine to notify it of the change. After this routine is called
4627 the PNP manager will no longer be able to disable the device.
4628
4629Arguments:
4630
4631 Type - the special file type - paging, hibernation or crash dump file.
4632
4633 InPath - indicates whether the system is creating or removing the special
4634 file on the device.
4635
4636 OldFlags - the previous flags on the device object.
4637
4638--*/
4639{
4640 PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();
4641 ULONG newFlags;
4642
4643 newFlags = m_Device->GetDeviceObjectFlags();
4644
4646 (newFlags & DO_POWER_PAGABLE) == 0) {
4647 //
4648 // We transitioned from a power pageable to a non power pageable
4649 // device. Move the power state machine to the appropriate
4650 // state.
4651 //
4653 }
4654
4655 if ((OldFlags & DO_POWER_PAGABLE) == 0 &&
4656 (newFlags & DO_POWER_PAGABLE) == DO_POWER_PAGABLE) {
4657 //
4658 // We transitioned from a non power pageable to a power pageable
4659 // device. Move the power state machine to the appropriate
4660 // state.
4661 //
4663 }
4664
4665 //
4666 // Notify PNP that it should no longer be able
4667 // to disable this device.
4668 //
4669 MxDeviceObject physicalDeviceObject(
4671 );
4672 physicalDeviceObject.InvalidateDeviceState(
4674 );
4675
4677 FxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP,
4678 "After: special count %d, flags 0x%x, device %p (WDFDEVICE %p)",
4679 GetUsageCount(Type), newFlags,
4681}
4682
4687 )
4688{
4689 FxRelatedDevice* pRelated;
4691
4693 KIRQL irql;
4694
4695 Lock(&irql);
4698
4701 }
4702 else {
4704
4707 "Could not allocate usage device list for WDFDEVICE %p, "
4708 "%!STATUS!", m_Device->GetHandle(), status);
4709 }
4710
4711 }
4712 else {
4713 //
4714 // another thread allocated the list already
4715 //
4717 }
4718 Unlock(irql);
4719
4720 if (!NT_SUCCESS(status)) {
4721 return status;
4722 }
4723 }
4724
4725 pRelated = new(GetDriverGlobals())
4727
4728 if (pRelated == NULL) {
4730 }
4731
4733
4734 if (!NT_SUCCESS(status)) {
4735 pRelated->DeleteFromFailedCreate();
4736 }
4737
4738 return status;
4739}
4740
4741VOID
4744 )
4745{
4748 }
4749}
4750
4755 )
4756{
4757 FxRelatedDevice* pRelated;
4759
4760 if (m_RemovalDeviceList == NULL) {
4761 KIRQL irql;
4762
4763 Lock(&irql);
4764 if (m_RemovalDeviceList == NULL) {
4766
4767 if (m_RemovalDeviceList != NULL) {
4769 }
4770 else {
4772
4775 "Could not allocate removal device list for WDFDEVICE %p, "
4776 "%!STATUS!", m_Device->GetHandle(), status);
4777 }
4778 }
4779 else {
4780 //
4781 // another thread allocated the list already
4782 //
4784 }
4785 Unlock(irql);
4786
4787 if (!NT_SUCCESS(status)) {
4788 return status;
4789 }
4790 }
4791
4792 pRelated = new(GetDriverGlobals())
4794 if (pRelated == NULL) {
4796 }
4797
4799
4800 if (NT_SUCCESS(status)) {
4801 //
4802 // RemovalRelations are queried automatically by PnP when the device is
4803 // going to be query removed. No need to tell pnp that the list changed
4804 // until it needs to query for it.
4805 //
4806 DO_NOTHING();
4807 }
4808 else {
4809 pRelated->DeleteFromFailedCreate();
4810 }
4811
4812 return status;
4813}
4814
4815VOID
4818 )
4819{
4820 if (m_RemovalDeviceList != NULL) {
4822 }
4823
4824 //
4825 // RemovalRelations are queried automatically by PnP when the device is
4826 // going to be query removed. No need to tell pnp that the list changed
4827 // until it needs to query for it.
4828 //
4829}
4830
4831VOID
4833 VOID
4834 )
4835{
4837
4838 if (m_RemovalDeviceList == NULL) {
4839 return;
4840 }
4841
4845 }
4847
4848 //
4849 // RemovalRelations are queried automatically by PnP when the device is
4850 // going to be query removed. No need to tell pnp that the list changed
4851 // until it needs to query for it.
4852 //
4853}
4854
4855VOID
4857 VOID
4858 )
4859/*++
4860
4861Routine Description:
4862 Sets the failure field and then optionally invalidates the device state.
4863
4864Arguments:
4865 InvalidateState - If TRUE, the state is invalidated
4866
4867Return Value:
4868 None
4869
4870 --*/
4871{
4873
4874 MxDeviceObject physicalDeviceObject(
4876 );
4877 physicalDeviceObject.InvalidateDeviceState(
4879 );
4880}
4881
4882VOID
4884 __inout FxIrp* Irp,
4885 __in BOOLEAN MarkIrpPending
4886 )
4887{
4888 if (m_PendingPnPIrp != NULL ) {
4889 FxIrp pendingIrp(m_PendingPnPIrp);
4890
4891 //
4892 // A state changing pnp irp is already pended. If we don't bugcheck
4893 // the pended pnp irp will be overwritten with new pnp irp and the old
4894 // one may never get completed, which may have drastic implications (
4895 // unresponsive system, power manager not sending Sx Irp etc.)
4896 //
4898 "A new state changing pnp irp %!pnpmn! IRP %p arrived while another "
4899 "pnp irp %!pnpmn! IRP %p is still pending WDFDEVICE %p\n",
4900 Irp->GetMinorFunction(), Irp->GetIrp(),
4901 pendingIrp.GetMinorFunction(),pendingIrp.GetIrp(),
4902 m_Device->GetHandle());
4903
4905 WDF_PNP_FATAL_ERROR, // specific type
4906 (ULONG_PTR)m_Device->GetHandle(), //parm 2
4907 (ULONG_PTR)Irp->GetIrp()); // parm 3
4908
4909 /* NOTREACHED */
4910 return;
4911 }
4912 if (MarkIrpPending) {
4913 Irp->MarkIrpPending();
4914 }
4915 m_PendingPnPIrp = Irp->GetIrp();
4916}
4917
4921 VOID
4922 )
4923{
4924 KIRQL irql;
4926
4927 if (m_EnumInfo != NULL) {
4928 return STATUS_SUCCESS;
4929 }
4930
4931 Lock(&irql);
4932 if (m_EnumInfo == NULL) {
4934
4935 if (m_EnumInfo != NULL) {
4937
4938 if (!NT_SUCCESS(status)) {
4939 delete m_EnumInfo;
4940 m_EnumInfo = NULL;
4941
4943 TRACINGPNP,
4944 "Could not initialize enum info for "
4945 "WDFDEVICE %p, %!STATUS!",
4947 }
4948
4949 }
4950 else {
4952
4954 "Could not allocate enum info for WDFDEVICE %p, "
4955 "%!STATUS!", m_Device->GetHandle(), status);
4956 }
4957 }
4958 else {
4959 //
4960 // another thread allocated the list already
4961 //
4963 }
4964 Unlock(irql);
4965
4966 return status;
4967}
4968
4969VOID
4972 )
4973{
4975 "Adding FxChildList %p, WDFCHILDLIST %p", List,
4976 List->GetHandle());
4977
4979 &List->m_TransactionLink);
4980}
4981
4982VOID
4985 )
4986{
4988 "Removing FxChildList %p, WDFCHILDLIST %p", List,
4989 List->GetHandle());
4990
4991 m_EnumInfo->m_ChildListList.Remove(GetDriverGlobals(), &List->m_TransactionLink);
4992
4993 //
4994
4995 //
4996}
4997
4998VOID
5000 __inout PLONG PendingCount
5001 )
5002{
5004
5005 ple = NULL;
5006
5007 if (m_EnumInfo != NULL) {
5011 }
5013 }
5014}
5015
5016VOID
5020 )
5021/*++
5022
5023Routine Description:
5024 Add a query interface structure to the list of interfaces supported
5025
5026Arguments:
5027 QI - the interface to add
5028
5029 Lock - indication of the list lock should be acquired or not
5030
5031Return Value:
5032 None
5033
5034 --*/
5035{
5037
5038 if (Lock) {
5040 }
5041
5042 ASSERT(QI->m_Entry.Next == NULL);
5043
5044 //
5045 // Iterate until we find the end of the list and then append the new
5046 // structure. ppPrev is the pointer to the Next pointer value. When we
5047 // get to the end, ppPrev will be equal to the Next field which points to NULL.
5048 //
5051
5052 while (pCur != NULL) {
5053 ppPrev = &pCur->Next;
5054 pCur = pCur->Next;
5055 }
5056
5057 *ppPrev = &QI->m_Entry;
5058
5059 if (Lock) {
5061 }
5062}
5063
5068VOID
5070 __in PKDPC Dpc,
5074 )
5075/*++
5076
5077Routine Description:
5078
5079 This routine's job is to crash the machine, attempting to get some data
5080 into the crashdump file (or minidump) about why the machine stopped
5081 responding during an attempt to put the machine to sleep.
5082
5083Arguments:
5084
5085 This - the instance of FxPkgPnp
5086
5087Return Value:
5088
5089 this routine never returns
5090
5091--*/
5092{
5094 FxWatchdog* pThis;
5096
5100
5101 pThis = (FxWatchdog*) Context;
5102 pDevice = pThis->m_PkgPnp->GetDevice();
5103
5106 "The driver failed to return from a callback routine "
5107 "in a reasonable period of time. This prevented the "
5108 "machine from going to sleep or from hibernating. The "
5109 "machine crashed because that was the best way to get "
5110 "data about the cause of the crash into a minidump file.");
5111
5112 data.PowerState = pDevice->GetDevicePowerState();
5113 data.PowerPolicyState = pDevice->GetDevicePowerPolicyState();
5114 data.DeviceObject = reinterpret_cast<PDEVICE_OBJECT>(pDevice->GetDeviceObject());
5115 data.Device = pDevice->GetHandle();
5116 data.TimedOutThread = reinterpret_cast<PKTHREAD>(pThis->m_CallingThread);
5117
5120 (ULONG_PTR) &data);
5121}
5122
5126 VOID
5127 )
5128/*++
5129
5130Routine Description:
5131 Creates a power thread for the device node. This thread is share among all
5132 the devices in the stack through the POWER_THREAD_INTERFACE structure and
5133 PnP query interface.
5134
5135Arguments:
5136 None
5137
5138Return Value:
5139 NTSTATUS
5140
5141 --*/
5142{
5143 FxSystemThread *pThread, *pOld;
5145
5147 &pThread,
5151
5152 if (!NT_SUCCESS(status)) {
5153 return status;
5154 }
5155
5156 //
5157 // Simple locking logic in case N requests are conncurrent. (The requests
5158 // never should be concurrent, but in the case that there are 2 usage
5159 // notifications coming in from two different sources, it could
5160 // theoritically happen.)
5161 //
5163 (PVOID*) &m_PowerThread, pThread, NULL);
5164
5165 if (pOld != NULL) {
5166 //
5167 // Someone also set the thread pointer value at the same time, free
5168 // our new one here.
5169 //
5170 pThread->ExitThread();
5171 pThread->DeleteObject();
5172 }
5173
5175
5176 return STATUS_SUCCESS;
5177}
5178
5179VOID
5181 VOID
5182 )
5183/*++
5184
5185Routine Description:
5186 If this device is the owner of the power thread, it kills the thread.
5187 Otherwise, if this device has acquired the thread from a lower device,
5188 release the reference now.
5189
5190Arguments:
5191 None
5192
5193Return Value:
5194 None
5195
5196 --*/
5197{
5198 BOOLEAN hadThread;
5199
5200 hadThread = m_HasPowerThread;
5201
5202 //
5203 // Set to FALSE before cleaning up the reference or thread itself in case
5204 // there is some other context trying to enqueue. The only way that could
5205 // be happening is if the power policy owner is not WDF and sends power irps
5206 // after query remove or surprise remove.
5207 //
5209
5210 //
5211 // Check for ownership
5212 //
5213 if (m_PowerThread != NULL) {
5214
5216
5217 //
5218 // Event on stack is used, which is fine since this code is invoked
5219 // only in KM. Verify this assumption.
5220 //
5221 // If this code is ever needed for UM, m_PowerThreadEvent should be
5222 // pre-initialized (simlar to the way m_RemoveEventUm is used)
5223 //
5225
5228
5230 //
5231 // Wait for all references to go away before exitting the thread.
5232 // A reference will be taken for every device in the stack above this
5233 // one which queried for the interface.
5234 //
5235 event.EnterCRAndWaitAndLeave();
5236 }
5237
5239
5240 //
5241 // Wait for the thread to exit and then delete it. Since we have
5242 // turned off the power policy state machine, we can safely do this here.
5243 // Any upper level clients will have also turned off their power policy
5244 // state machines.
5245 //
5248
5250 }
5251 else if (hadThread) {
5252 //
5253 // Release our reference
5254 //
5257 );
5258 }
5259}
5260
5261VOID
5264 )
5265/*++
5266
5267Routine Description:
5268 Increments the ref count on the thread interface.
5269
5270Arguments:
5271 Context - FxPkgPnp*
5272
5273Return Value:
5274 None
5275
5276 --*/
5277{
5278 LONG count;
5279
5282 );
5283
5284#if DBG
5285 ASSERT(count >= 2);
5286#else
5288#endif
5289}
5290
5291VOID
5294 )
5295/*++
5296
5297Routine Description:
5298 Interface deref for the thread interface. If this is the last reference
5299 released, an event is set so that the thread which waiting for the last ref
5300 to go away can unblock.
5301
5302Arguments:
5303 Context - FxPkgPnp*
5304
5305Return Value:
5306 None
5307
5308 --*/
5309
5310{
5311 FxPkgPnp* pThis;
5312
5313 pThis = (FxPkgPnp*) Context;
5314
5316 pThis->m_PowerThreadEvent->Set();
5317 }
5318}
5319
5323 VOID
5324 )
5325/*++
5326
5327Routine Description:
5328 Take a power reference during a query pnp transition.
5329
5330Arguments:
5331 None
5332
5333Return Value:
5334 None
5335
5336 --*/
5337{
5338 if (IsPowerPolicyOwner()) {
5339 //
5340 // We want to synchronously wait to move into D0
5341 //
5342 return PowerReference(TRUE);
5343 }
5344 else {
5345 return STATUS_SUCCESS;
5346 }
5347}
5348
5352 VOID
5353 )
5354/*++
5355
5356Routine Description:
5357 Take a power reference during a query pnp transition.
5358
5359Arguments:
5360 None
5361
5362Return Value:
5363 None
5364
5365 --*/
5366{
5367 if (IsPowerPolicyOwner()) {
5368 //
5369 // We want to synchronously wait to move into D0
5370 //
5372 m_PowerIdleMachine.PowerReferenceWithFlags(
5374 );
5375 }
5376 else {
5377 return STATUS_SUCCESS;
5378 }
5379}
5380
5381VOID
5383 VOID
5384 )
5385/*++
5386
5387Routine Description:
5388 Release the power reference taken during a query pnp transition
5389
5390Arguments:
5391 None
5392
5393Return Value:
5394 None
5395
5396 --*/
5397{
5398 if (IsPowerPolicyOwner()) {
5400 }
5401}
5402
5405 __inout FxIrp* Irp,
5407 )
5408{
5409 MdIrp irp;
5410
5411 //
5412 // Once we call CompleteRequest, 2 things happen
5413 // 1) this object may go away
5414 // 2) Irp->m_Irp will be cleared
5415 //
5416 // As such, we capture the underlying WDM objects so that we can use them
5417 // to release the remove lock and use the PIRP *value* as a tag to release
5418 // the remlock.
5419 //
5420 irp = Irp->GetIrp();
5421
5422 Irp->SetStatus(Status);
5423 Irp->StartNextPowerIrp();
5424 Irp->CompleteRequest(IO_NO_INCREMENT);
5425
5427 irp);
5428
5429 return Status;
5430}
5431
5432LONG
5434 VOID
5435 )
5436/*++
5437
5438Routine Description:
5439 Returns the pnp device state encoded into a ULONG. This state is the state
5440 that is reported to PNp via IRP_MN_QUERY_PNP_DEVICE_STATE after it has been
5441 decoded into the bits pnp expects
5442
5443Arguments:
5444 None
5445
5446Return Value:
5447 the current state bits
5448
5449 --*/
5450{
5451 LONG state;
5452 KIRQL irql;
5453
5454 //
5455 // State is shared with the caps bits. Use a lock to guard against
5456 // corruption of the value between these 2 values
5457 //
5458 Lock(&irql);
5460 Unlock(irql);
5461
5462 return state;
5463}
5464
5465LONG
5467 VOID
5468 )
5469/*++
5470
5471Routine Description:
5472 Returns the pnp device capabilities encoded into a LONG. This state is used
5473 in reporting device capabilities via IRP_MN_QUERY_CAPABILITIES and filling
5474 in the PDEVICE_CAPABILITIES structure.
5475
5476Arguments:
5477 None
5478
5479Return Value:
5480 the current pnp cap bits
5481
5482 --*/
5483{
5484 LONG caps;
5485 KIRQL irql;
5486
5487 Lock(&irql);
5489 Unlock(irql);
5490
5491 return caps;
5492}
5493
5494
5495VOID
5498 )
5499/*++
5500
5501Routine Description:
5502 Encode the driver provided pnp capabilities into our internal capabilities
5503 bit field and store the result.
5504
5505Arguments:
5506 PnpCapabilities - capabilities as reported by the driver writer
5507
5508Return Value:
5509 None
5510
5511 --*/
5512{
5513 LONG pnpCaps;
5514 KIRQL irql;
5515
5516 pnpCaps = 0;
5517 pnpCaps |= GET_PNP_CAP_BITS_FROM_STRUCT(PnpCapabilities, LockSupported);
5518 pnpCaps |= GET_PNP_CAP_BITS_FROM_STRUCT(PnpCapabilities, EjectSupported);
5520 pnpCaps |= GET_PNP_CAP_BITS_FROM_STRUCT(PnpCapabilities, DockDevice);
5521 pnpCaps |= GET_PNP_CAP_BITS_FROM_STRUCT(PnpCapabilities, UniqueID);
5522 pnpCaps |= GET_PNP_CAP_BITS_FROM_STRUCT(PnpCapabilities, SilentInstall);
5523 pnpCaps |= GET_PNP_CAP_BITS_FROM_STRUCT(PnpCapabilities, SurpriseRemovalOK);
5524 pnpCaps |= GET_PNP_CAP_BITS_FROM_STRUCT(PnpCapabilities, HardwareDisabled);
5525 pnpCaps |= GET_PNP_CAP_BITS_FROM_STRUCT(PnpCapabilities, NoDisplayInUI);
5526
5527 //
5528 // Since the caller of IRP_MN_QUERY_CAPABILITIES sets these 2 values to -1,
5529 // we can reuse the -1 as the default/no override value since the associated
5530 // PDEVICE_CAPAPBILITIES structure will have been predisposed to these values
5531 //
5532 if (PnpCapabilities->Address != (ULONG) -1) {
5534 }
5535 if (PnpCapabilities->UINumber != (ULONG) -1) {
5537 }
5538
5539 //
5540 // Use the FxPnpStateMask to keep the state mask while applying the new
5541 // pnp capabilities.
5542 //
5543 Lock(&irql);
5545 Unlock(irql);
5546}
5547
5548VOID
5551 )
5552/*++
5553
5554Routine Description:
5555 Decodes our internal pnp state bitfield into the external WDF_DEVICE_STATE
5556 structure
5557
5558Arguments:
5559 State - the structure to decode into
5560
5561Return Value:
5562 None
5563
5564 --*/
5565{
5566 LONG state;
5567
5569
5571 SET_TRI_STATE_FROM_STATE_BITS(state, State, DontDisplayInUI);
5573 SET_TRI_STATE_FROM_STATE_BITS(state, State, NotDisableable);
5575 SET_TRI_STATE_FROM_STATE_BITS(state, State, ResourcesChanged);
5576}
5577
5578VOID
5581 )
5582/*++
5583
5584Routine Description:
5585 Encodes the driver writer provided state into our internal bit field.
5586
5587Arguments:
5588 State - the states to encode
5589
5590Return Value:
5591 None
5592
5593 --*/
5594{
5595 LONG pnpState;
5596 KIRQL irql;
5597
5598 pnpState = 0x0;
5600 pnpState |= GET_PNP_STATE_BITS_FROM_STRUCT(State, DontDisplayInUI);
5602 pnpState |= GET_PNP_STATE_BITS_FROM_STRUCT(State, NotDisableable);
5604 pnpState |= GET_PNP_STATE_BITS_FROM_STRUCT(State, ResourcesChanged);
5605
5606 //
5607 // Mask off FxPnpCapMask to keep the capabilities part of the bitfield
5608 // the same while change the pnp state.
5609 //
5610 Lock(&irql);
5612 Unlock(irql);
5613}
5614
5615VOID
5620 )
5621/*++
5622
5623Routine Description:
5624 Encodes the given device power state (State) into Result at the given Index.
5625 States are encoded in nibbles (4 bit chunks), starting at the bottom of the
5626 result and moving upward
5627
5628Arguments:
5629 Index - zero based index into the number of nibbles to encode the value
5630
5631 State - State to encode
5632
5633 Result - pointer to where the encoding will take place
5634
5635Return Value:
5636 None
5637
5638 --*/
5639{
5640 //
5641 // We store off state in 4 bits, starting at the lowest byte
5642 //
5643 ASSERT(Index < 8);
5644
5645 //
5646 // Erase the old value
5647 //
5648 *Result &= ~(0xF << (Index * 4));
5649
5650 //
5651 // Write in the new one
5652 //
5653 *Result |= (0xF & State) << (Index * 4);
5654}
5655
5660 )
5661/*++
5662
5663Routine Description:
5664 Decodes our internal device state encoding and returns a normalized device
5665 power state for the given index.
5666
5667Arguments:
5668 Index - nibble (4 bit chunk) index into the State
5669
5670 State - value which has the device states encoded into it
5671
5672Return Value:
5673 device power state for the given Index
5674
5675 --*/
5676{
5677 ASSERT(Index < 8);
5678 // isolate the value and normalize it
5679 return (DEVICE_POWER_STATE) ((State & (0xF << (Index * 4))) >> (Index * 4));
5680}
5681
5682VOID
5685 )
5686/*++
5687
5688Routine Description:
5689 Encodes the driver provided power capabilities into the object. The device
5690 power states are encoded into one ULONG while the other power caps are
5691 encoded into their own distinct fields.
5692
5693Arguments:
5694 PowerCapabilities - the power caps reported by the driver writer
5695
5696Return Value:
5697 None
5698
5699 --*/
5700{
5701 ULONG states, i;
5702 USHORT powerCaps;
5703
5704 states = 0x0;
5705
5706 //
5707 // Build up the device power state encoding into a temp var so that if we are
5708 // retrieving the encoding in another thread, we don't get a partial view
5709 //
5710 for (i = 0; i < ARRAY_SIZE(PowerCapabilities->DeviceState); i++) {
5711 _SetPowerCapState(i, PowerCapabilities->DeviceState[i], &states);
5712 }
5713
5714 m_PowerCaps.States = states;
5715
5716 //
5717 // Same idea. Build up the caps locally first so that when we assign them
5718 // into the object, it is assigned as a whole.
5719 //
5720 powerCaps = 0x0;
5721 powerCaps |= GET_POWER_CAP_BITS_FROM_STRUCT(PowerCapabilities, DeviceD1);
5722 powerCaps |= GET_POWER_CAP_BITS_FROM_STRUCT(PowerCapabilities, DeviceD2);
5723 powerCaps |= GET_POWER_CAP_BITS_FROM_STRUCT(PowerCapabilities, WakeFromD0);
5724 powerCaps |= GET_POWER_CAP_BITS_FROM_STRUCT(PowerCapabilities, WakeFromD1);
5725 powerCaps |= GET_POWER_CAP_BITS_FROM_STRUCT(PowerCapabilities, WakeFromD2);
5726 powerCaps |= GET_POWER_CAP_BITS_FROM_STRUCT(PowerCapabilities, WakeFromD3);
5727
5728 m_PowerCaps.Caps = powerCaps;
5729
5730 if (PowerCapabilities->DeviceWake != PowerDeviceMaximum) {
5732 }
5733 if (PowerCapabilities->SystemWake != PowerSystemMaximum) {
5735 }
5736
5740
5741 if (PowerCapabilities->IdealDxStateForSx != PowerDeviceMaximum) {
5742 //
5743 // Caller has already validated that IdealDxStateForSx is only set if
5744 // they device is the power policy owner.
5745 //
5747 PowerCapabilities->IdealDxStateForSx;
5748 }
5749}
5750
5753 __inout FxIrp* Irp,
5755 )
5756{
5757 MdIrp pIrp = Irp->GetIrp();
5758
5759 Irp->SetStatus(Status);
5760 Irp->CompleteRequest(IO_NO_INCREMENT);
5761
5763 pIrp);
5764
5765 return Status;
5766}
5767
5768BOOLEAN
5770 VOID
5771 )
5772{
5774 return TRUE;
5775 }
5776 else {
5777 return FALSE;
5778 }
5779}
5780
5781ULONG
5783 VOID
5784 )
5785/*++
5786
5787Routine Description:
5788 This routine determines the reasons for whether wake should be enabled or
5789 not. Wake could be enabled because it is explicitly enabled for the device
5790 in the wake policy settings or, because the device opted to depend on its
5791 children being armed for wake.
5792
5793Arguments:
5794 None
5795
5796Return Value:
5797 Returns a combination of FxPowerPolicySxWakeChildrenArmedFlag, to indicate
5798 that wake can be enabled because of more than one children being armed for
5799 wake, and FxPowerPolicySxWakeDeviceEnabledFlag, to indicate that wake can
5800 be enabled because the device was explicitly enabled in the wake policy
5801 settings.
5802
5803 Returns Zero to indicate that wake is currently disabled for the device.
5804
5805--*/
5806{
5807 ULONG wakeReason;
5808
5809 wakeReason = 0x0;
5810
5813 //
5814 // Wake settings depends on children and one or more children are
5815 // armed for wake.
5816 //
5818 }
5819
5821 //
5822 // Wake settings is explicitly enabled.
5823 //
5825 }
5826
5827 return wakeReason;
5828}
5829
5830VOID
5832 __in BOOLEAN UseCanSaveState
5833 )
5834/*++
5835
5836Routine Description:
5837 Saves any permanent state of the device out to the registry
5838
5839Arguments:
5840 None
5841
5842Return Value:
5843 None
5844
5845 --*/
5846
5847{
5851 ULONG value;
5852
5853 //
5854 // We only have settings to save if we are the power policy owner
5855 //
5856 if (IsPowerPolicyOwner() == FALSE) {
5857 return;
5858 }
5859
5860 if (UseCanSaveState &&
5864 "Not saving wake settings for WDFDEVICE %p due to system power "
5865 "transition", m_Device->GetHandle());
5866 return;
5867 }
5868
5869 //
5870 // Check to see if there is anything to write out
5871 //
5874 return;
5875 }
5876
5877 //
5878 // No need to write out if user control is not enabled
5879 //
5882 return;
5883 }
5884
5885 //
5886 // If the device is in paging path we should not be touching registry during
5887 // power up because it may incur page fault which won't be satisfied if the
5888 // device is still not powered up, blocking power Irp. User control state
5889 // change will not get written if any at this time but will be flushed out
5890 // to registry during device disable/remove in the remove path.
5891 //
5893 return;
5894 }
5895
5896#if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
5897
5899 if (!NT_SUCCESS(status)) {
5900 return;
5901 }
5902#else
5904#endif
5905
5910
5912
5914 }
5915
5920
5922
5924 }
5925}
5926
5927VOID
5930 )
5931/*++
5932
5933Routine Description:
5934
5935 This routine adds a WDFINTERRUPT object onto the list of interrupts
5936 which are attached to this device. This list is used in response to
5937 several IRPs.
5938
5939Note:
5940
5941 It shouldn't be necessary to lock this list, since the driver will add or
5942 remove interrupt objects only in callbacks that are effectively serialized
5943 by the PnP manager.
5944
5945Further note:
5946
5947 This list must remain sorted by order of interrupt object creation. E.g.
5948 the first interrupt object created must be first in this list.
5949
5950Arguments:
5951
5952 Interrupt - a Framework interrupt object
5953
5954Return Value:
5955
5956 VOID
5957
5958--*/
5959{
5962}
5963
5964VOID
5967 )
5968/*++
5969
5970Routine Description:
5971 This routine removes a WDFINTERRUPT object onto the list of interrupts
5972 which are attached to this device. This list is used in response to
5973 several IRPs.
5974
5975Arguments:
5976
5977 Interrupt - a Framework interrupt object
5978
5979Return Value:
5980
5981 VOID
5982
5983--*/
5984{
5986 RemoveEntryList(&Interrupt->m_PnpList);
5987}
5988
5989VOID
5991 VOID
5992 )
5993/*++
5994
5995Routine Description:
5996
5997 This routine traverses all resource objects and tells them that their
5998 resources are no longer valid.
5999
6000Arguments:
6001
6002 none
6003
6004Return Value:
6005
6006 VOID
6007
6008--*/
6009{
6010 FxInterrupt* interruptInstance;
6011 PLIST_ENTRY intListEntry;
6012
6013 //
6014 // Revoke each of the interrupts.
6015 //
6016
6017 intListEntry = m_InterruptListHead.Flink;
6018
6019 while (intListEntry != &m_InterruptListHead) {
6020
6021 //
6022 // Disconnect interrupts and then tell them that they no longer
6023 // own their resources.
6024 //
6025
6026 interruptInstance = CONTAINING_RECORD(intListEntry, FxInterrupt, m_PnpList);
6027 interruptInstance->RevokeResources();
6028 intListEntry = intListEntry->Flink;
6029 }
6030
6031 //
6032 // Now revoke each of the DMA enablers (only system-mode enablers
6033 // will be affected by this)
6034 //
6035
6036 if (m_DmaEnablerList != NULL) {
6037 FxTransactionedEntry* listEntry;
6038
6040
6041 for (listEntry = m_DmaEnablerList->GetNextEntry(NULL);
6042 listEntry != NULL;
6043 listEntry = m_DmaEnablerList->GetNextEntry(listEntry)) {
6045 (FxDmaEnabler *) listEntry->GetTransactionedObject()
6046 );
6047 }
6048
6050 }
6051}
6052
6056 __in ULONG NotifyFlags
6057 )
6058/*++
6059
6060Routine Description:
6061
6062 This routine traverses all resource objects and tells them that the device
6063 is entering D0. If an error is encountered, the walking of the list is
6064 halted.
6065
6066Arguments:
6067
6068 none
6069
6070Return Value:
6071
6072 VOID
6073
6074--*/
6075{
6076 FxInterrupt* pInterrupt;
6079
6082 ple = ple->Flink) {
6083
6084 //
6085 // Connect the interrupts
6086 //
6087 pInterrupt = CONTAINING_RECORD(ple, FxInterrupt, m_PnpList);
6088
6089 status = pInterrupt->Connect(NotifyFlags);
6090
6091 if (!NT_SUCCESS(status)) {
6093 "WDFINTERRUPT %p failed to connect, %!STATUS!",
6094 pInterrupt->GetHandle(), status);
6095
6096 return status;
6097 }
6098 }
6099
6100 return STATUS_SUCCESS;
6101}
6102
6105 __in ULONG NotifyFlags
6106 )
6107/*++
6108
6109Routine Description:
6110 This routine traverses all resource objects and tells them that the device
6111 is leaving D0. If there is an error, the remaining resources in the list
6112 are still notified of exitting D0.
6113
6114Arguments:
6115 NotifyFlags - combination of values from the enum NotifyResourcesFlags
6116
6117Return Value:
6118 None
6119
6120--*/
6121{
6122 FxInterrupt* pInterrupt;
6124 NTSTATUS status, finalStatus;
6125
6126 finalStatus = STATUS_SUCCESS;
6127
6128 //
6129 // Disconect in the reverse order in which we connected the interrupts
6130 //
6133 ple = ple->Blink) {
6134
6135 //
6136 // Disconnect interrupts and then tell them that they no longer
6137 // own their resources.
6138 //
6139 pInterrupt = CONTAINING_RECORD(ple, FxInterrupt, m_PnpList);
6140
6141 status = pInterrupt->Disconnect(NotifyFlags);
6142
6143 if (!NT_SUCCESS(status)) {
6144 //
6145 // When we encounter an error we still disconnect the remaining
6146 // interrupts b/c we would just do it later during device tear down
6147 // (might as well do it now).
6148 //
6150 "WDFINTERRUPT %p failed to disconnect, %!STATUS!",
6151 pInterrupt->GetHandle(), status);
6152 //
6153 // Overwriting a previous finalStatus is OK, we'll just report the
6154 // last one
6155 //
6156 finalStatus = status;
6157 }
6158 }
6159
6160 return finalStatus;
6161}
6162
6163VOID
6165 __in FxWakeInterruptEvents WakeInterruptEvent
6166 )
6167/*++
6168
6169Routine Description:
6170 This routine traverses all interrupt objects and queues the
6171 given event into those interrupts that are marked as wake
6172 capable and have a state machine
6173
6174Arguments:
6175 WakeInterruptEvent - Event to be queued in the wake interrupt
6176 state machines
6177
6178Return Value:
6179 None
6180
6181--*/
6182{
6183 FxInterrupt* pInterrupt;
6185
6186 if (m_WakeInterruptCount == 0) {
6187 return;
6188 }
6189
6190 //
6191 // Initialize the pending count to the wake interrupt count
6192 // If the event needs an acknowledgement, this variable will
6193 // be decremented as the interrupt machines ack.
6194 //
6196
6199 ple = ple->Flink) {
6200
6201 pInterrupt = CONTAINING_RECORD(ple, FxInterrupt, m_PnpList);
6202
6203 if (pInterrupt->IsWakeCapable()) {
6204 pInterrupt->ProcessWakeInterruptEvent(WakeInterruptEvent);
6205 }
6206
6207 }
6208}
6209
6210VOID
6212 __in BOOLEAN ProcessPowerEventOnDifferentThread
6213 )
6214/*++
6215
6216Routine Description:
6217 This routine is invoked by the interrupt wake machine to acknowledge
6218 back an event that was queued into it. When the last interrupt machine
6219 acknowledges, an event is queued back into the Pnp/power state machine
6220
6221Arguments:
6222
6223 ProcessPowerEventOnDifferentThread - Once all wake interrupts for the device
6224 have acknowledged the operation, if this is TRUE, the power state
6225 machine will process the PowerWakeInterruptCompleteTransition event on a
6226 seperate thread.
6227
6228Return Value:
6229 None
6230
6231--*/
6232{
6236 ProcessPowerEventOnDifferentThread
6237 );
6238 }
6239}
6240
6241
6245 )
6246{
6247// NTSTATUS status;
6248// PPO_FX_COMPONENT_IDLE_STATE idleStates = NULL;
6249// ULONG idleStatesSize = 0;
6250// PPO_FX_COMPONENT component = NULL;
6251// ULONG componentSize = 0;
6252// PPOX_SETTINGS poxSettings = NULL;
6253// ULONG poxSettingsSize = 0;
6254// BYTE * buffer = NULL;
6255
6256// if (FALSE==(IdleTimeoutManagement::_SystemManagedIdleTimeoutAvailable())) {
6257// //
6258// // If system-managed idle timeout is not available on this OS, then
6259// // there is nothing to do.
6260// //
6261// DoTraceLevelMessage(
6262// GetDriverGlobals(), TRACE_LEVEL_INFORMATION, TRACINGPNP,
6263// "WDFDEVICE %p !devobj %p Power framework is not supported on the "
6264// "current OS. Therefore, the power framework settings will not take "
6265// "effect.",
6266// m_Device->GetHandle(),
6267// m_Device->GetDeviceObject()
6268// );
6269// return STATUS_SUCCESS;
6270// }
6271
6272// if (NULL != PowerFrameworkSettings->Component) {
6273// //
6274// // Caller should ensure that IdleStateCount is not zero
6275// //
6276// ASSERT(0 != PowerFrameworkSettings->Component->IdleStateCount);
6277
6278// //
6279// // Compute buffer size needed for storing F-states
6280// //
6281// status = RtlULongMult(
6282// PowerFrameworkSettings->Component->IdleStateCount,
6283// sizeof(*(PowerFrameworkSettings->Component->IdleStates)),
6284// &idleStatesSize
6285// );
6286// if (FALSE == NT_SUCCESS(status)) {
6287// DoTraceLevelMessage(
6288// GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
6289// "WDFDEVICE %p !devobj %p Unable to compute length of buffer "
6290// "required to store F-states. RtlULongMult failed with "
6291// "%!STATUS!",
6292// m_Device->GetHandle(),
6293// m_Device->GetDeviceObject(),
6294// status
6295// );
6296// goto exit;
6297// }
6298
6299// //
6300// // Compute buffer size needed for storing component information
6301// // (including F-states)
6302// //
6303// status = RtlULongAdd(idleStatesSize,
6304// sizeof(*component),
6305// &componentSize);
6306// if (FALSE == NT_SUCCESS(status)) {
6307// DoTraceLevelMessage(
6308// GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
6309// "WDFDEVICE %p !devobj %p Unable to compute length of buffer "
6310// "required to store driver's component information. RtlULongAdd "
6311// "failed with %!STATUS!",
6312// m_Device->GetHandle(),
6313// m_Device->GetDeviceObject(),
6314// status
6315// );
6316// goto exit;
6317// }
6318// }
6319
6320// //
6321// // Compute total buffer size needed for power framework settings
6322// //
6323// status = RtlULongAdd(componentSize,
6324// sizeof(*poxSettings),
6325// &poxSettingsSize);
6326// if (FALSE == NT_SUCCESS(status)) {
6327// DoTraceLevelMessage(
6328// GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
6329// "WDFDEVICE %p !devobj %p Unable to compute length of buffer "
6330// "required to store driver's power framework settings. RtlULongAdd "
6331// "failed with %!STATUS!",
6332// m_Device->GetHandle(),
6333// m_Device->GetDeviceObject(),
6334// status
6335// );
6336// goto exit;
6337// }
6338
6339// //
6340// // Allocate memory to copy the settings
6341// //
6342// buffer = (BYTE *) MxMemory::MxAllocatePoolWithTag(NonPagedPool,
6343// poxSettingsSize,
6344// GetDriverGlobals()->Tag);
6345// if (NULL == buffer) {
6346// status = STATUS_INSUFFICIENT_RESOURCES;
6347// DoTraceLevelMessage(
6348// GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
6349// "WDFDEVICE %p !devobj %p Unable to allocate buffer required to "
6350// "store F-states. %!STATUS!",
6351// m_Device->GetHandle(),
6352// m_Device->GetDeviceObject(),
6353// status
6354// );
6355// goto exit;
6356// }
6357
6358// //
6359// // Set our pointers to point to appropriate locations in the buffer.
6360// //
6361// // NOTES:
6362// // - The array of F-states comes first because it has ULONGLONG members
6363// // because of which it has the biggest alignment requirement.
6364// // - The logic below works even if the client driver did not specify any
6365// // component information. In that case idleStatesSize and componentSize
6366// // are both 0 and 'poxSettings' points to the beginning of the allocated
6367// // buffer
6368// //
6369// idleStates = (PPO_FX_COMPONENT_IDLE_STATE) buffer;
6370// component = (PPO_FX_COMPONENT) (buffer + idleStatesSize);
6371// poxSettings = (PPOX_SETTINGS) (buffer + componentSize);
6372
6373// //
6374// // Copy the relevant parts of the settings buffer
6375// //
6376// poxSettings->EvtDeviceWdmPostPoFxRegisterDevice =
6377// PowerFrameworkSettings->EvtDeviceWdmPostPoFxRegisterDevice;
6378// poxSettings->EvtDeviceWdmPrePoFxUnregisterDevice =
6379// PowerFrameworkSettings->EvtDeviceWdmPrePoFxUnregisterDevice;
6380// poxSettings->Component = PowerFrameworkSettings->Component;
6381// poxSettings->ComponentActiveConditionCallback =
6382// PowerFrameworkSettings->ComponentActiveConditionCallback;
6383// poxSettings->ComponentIdleConditionCallback =
6384// PowerFrameworkSettings->ComponentIdleConditionCallback;
6385// poxSettings->ComponentIdleStateCallback =
6386// PowerFrameworkSettings->ComponentIdleStateCallback;
6387// poxSettings->PowerControlCallback =
6388// PowerFrameworkSettings->PowerControlCallback;
6389// poxSettings->PoFxDeviceContext = PowerFrameworkSettings->PoFxDeviceContext;
6390
6391// if (NULL != PowerFrameworkSettings->Component) {
6392// //
6393// // Copy the component information
6394// //
6395// poxSettings->Component = component;
6396// RtlCopyMemory(poxSettings->Component,
6397// PowerFrameworkSettings->Component,
6398// sizeof(*component));
6399
6400// //
6401// // Caller should ensure that IdleStates is not NULL
6402// //
6403// ASSERT(NULL != PowerFrameworkSettings->Component->IdleStates);
6404
6405// //
6406// // Copy the F-states
6407// //
6408// poxSettings->Component->IdleStates = idleStates;
6409// RtlCopyMemory(poxSettings->Component->IdleStates,
6410// PowerFrameworkSettings->Component->IdleStates,
6411// idleStatesSize);
6412// }
6413
6414// //
6415// // Commit these settings
6416// //
6417// status = m_PowerPolicyMachine.m_Owner->
6418// m_IdleSettings.m_TimeoutMgmt.CommitPowerFrameworkSettings(
6419// GetDriverGlobals(),
6420// poxSettings
6421// );
6422// if (FALSE == NT_SUCCESS(status)) {
6423// goto exit;
6424// }
6425
6426// status = STATUS_SUCCESS;
6427
6428// exit:
6429// if (FALSE == NT_SUCCESS(status)) {
6430// if (NULL != buffer) {
6431// MxMemory::MxFreePool(buffer);
6432// }
6433// }
6434// return status;
6436 return STATUS_SUCCESS;
6437}
6438
6441 __in SYSTEM_POWER_STATE SystemState
6442 )
6443{
6444 DEVICE_POWER_STATE dxState;
6445
6446 //
6447 // Earlier versions of WDF (pre-1.11) did not take into account SystemState
6448 // in figuring out the deepest wake state. So for compatibility we restrict
6449 // this to drivers compiled for 1.11 or newer. See comments in the
6450 // FxPkgPnp::QueryForCapabilities function for more information on
6451 // compatibility risk.
6452 //
6453 if (GetDriverGlobals()->IsVersionGreaterThanOrEqualTo(1,11)) {
6454 if ((SystemState < PowerSystemWorking) ||
6455 (SystemState > PowerSystemHibernate)) {
6456 dxState = PowerDeviceD0;
6457 } else {
6458 dxState = MapWakeDepthToDstate(
6460 );
6461 }
6462 }
6463 else {
6464 //
6465 // For pre-1.11 drivers, all of m_DeviceWake array is populated with
6466 // the same DeviceWake value obtained from device capabilities so we
6467 // just use the first one (index 0).
6468 //
6470 }
6471
6472 //
6473 // Per WDM docs DeviceWake and SystemWake must be non-zero to support
6474 // wake. We warn about the violation. Ideally, a verifier check would have
6475 // been better but we want to avoid that because some drivers may
6476 // intentionally call this DDI and do not treat the DDI failure as fatal (
6477 // because they are aware that DDI may succeed in some cases), and a verifier
6478 // breakpoint would force them to avoid the verifier failure by not enabling
6479 // verifier.
6480 //
6481 if (dxState == PowerDeviceUnspecified ||
6485 "SystemWake %!SYSTEM_POWER_STATE! and DeviceWake "
6486 "%!DEVICE_POWER_STATE! power state reported in device "
6487 "capabilities do not support wake. Both the SystemWake and "
6488 "DeviceWake members should be nonzero to support wake-up on "
6489 "this system.", m_SystemWake, dxState);
6490 }
6491
6492 return dxState;
6493}
6494
struct _IRP * PIRP
#define SaveState(State)
unsigned char BOOLEAN
Type
Definition: Type.h:7
static int state
Definition: maze.c:121
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define ARRAY_SIZE(A)
Definition: main.h:33
const struct winhelp_callbacks Callbacks
Definition: callback.c:161
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
VOID NotifyDeviceRemove(__inout PLONG ChildCount)
static FxChildList * _FromEntry(__in FxTransactionedEntry *Entry)
WDFCHILDLIST GetHandle(VOID)
VOID InvokeReportedMissingCallback(VOID)
static size_t _ComputeRelationsSize(__in ULONG Count)
_Must_inspect_result_ NTSTATUS ProcessBusRelations(__inout PDEVICE_RELATIONS *DeviceRelations)
static _Must_inspect_result_ NTSTATUS _CreateAndInit(__in FxCmResList **ResourceList, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in CfxDevice *Device, __in_opt PWDF_OBJECT_ATTRIBUTES ListAttributes, __in UCHAR AccessFlags)
Definition: fxresource.hpp:400
__inline MxDeviceObject * GetMxDeviceObject(VOID)
Definition: fxdevice.hpp:183
ULONG __inline GetDeviceObjectFlags(VOID)
Definition: fxdevice.hpp:192
VOID __inline SetDeviceObjectFlags(_In_ ULONG Flags)
Definition: fxdevice.hpp:201
MdDeviceObject __inline GetPhysicalDevice(VOID)
Definition: fxdevice.hpp:228
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
MdDeviceObject __inline GetAttachedDevice(VOID)
Definition: fxdevice.hpp:210
__inline MdDeviceObject GetAttachedDeviceReference(VOID)
Definition: fxdevice.hpp:429
ULONG __inline GetAttachedDeviceObjectFlags(VOID)
Definition: fxdevice.hpp:219
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
static FxDeviceInterface * _FromEntry(__in PSINGLE_LIST_ENTRY Entry)
SINGLE_LIST_ENTRY m_Entry
PFN_WDF_DEVICE_PROCESS_QUERY_INTERFACE_REQUEST m_Method
CfxDevice * m_ParentDevice
Definition: fxdevice.hpp:569
virtual VOID DeleteObject(VOID)
Definition: fxdevice.cpp:1135
__inline WDF_DEVICE_POWER_POLICY_STATE GetDevicePowerPolicyState()
Definition: fxdevice.hpp:1165
VOID Destroy(VOID)
Definition: fxdevicekm.cpp:329
MdDeviceObject __inline GetSafePhysicalDevice(VOID)
Definition: fxdevice.hpp:1005
__inline BOOLEAN IsPdo(VOID)
Definition: fxdevice.hpp:1245
_Must_inspect_result_ NTSTATUS OpenSettingsKey(__out HANDLE *Key, __in ACCESS_MASK DesiredAccess=STANDARD_RIGHTS_ALL)
Definition: fxdevicekm.cpp:818
MdRemoveLock GetRemoveLock(VOID)
Definition: fxdevicekm.hpp:47
__inline WDF_DEVICE_POWER_STATE GetDevicePowerState()
Definition: fxdevice.hpp:1157
__inline BOOLEAN IsFilter()
Definition: fxdevice.hpp:1408
__inline WDF_DEVICE_PNP_STATE GetDevicePnpState()
Definition: fxdevice.hpp:1149
__inline BOOLEAN IsPowerPageableCapable(VOID)
Definition: fxdevice.hpp:1421
__inline BOOLEAN IsFdo(VOID)
Definition: fxdevice.hpp:1227
_Must_inspect_result_ NTSTATUS Connect(__in ULONG NotifyFlags)
__inline BOOLEAN IsWakeCapable(VOID)
VOID ProcessWakeInterruptEvent(__in FxWakeInterruptEvents Event)
_Must_inspect_result_ NTSTATUS Disconnect(__in ULONG NotifyFlags)
VOID RevokeResources(VOID)
WDFINTERRUPT GetHandle(VOID)
Definition: fxirp.hpp:28
UCHAR GetMajorFunction(VOID)
Definition: fxirpum.cpp:217
DEVICE_RELATION_TYPE GetParameterQDRType()
Definition: fxirpum.cpp:731
static _Must_inspect_result_ MdIrp AllocateIrp(_In_ CCHAR StackSize, _In_opt_ FxDevice *Device=NULL)
Definition: fxirpum.cpp:1089
POWER_STATE_TYPE GetParameterPowerType()
Definition: fxirpum.cpp:683
SYSTEM_POWER_STATE GetParameterPowerStateSystemState()
Definition: fxirpum.cpp:707
NTSTATUS GetStatus()
Definition: fxirpum.cpp:466
MdIrp GetIrp(VOID)
Definition: fxirpum.cpp:15
DEVICE_POWER_STATE GetParameterPowerStateDeviceState()
Definition: fxirpum.cpp:695
MdIrp SetIrp(MdIrp irp)
Definition: fxirpkm.hpp:71
UCHAR GetMinorFunction(VOID)
Definition: fxirpum.cpp:297
ULONG_PTR GetInformation()
Definition: fxirpum.cpp:513
virtual VOID DeleteObject(VOID)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
CfxDevice * m_Device
Definition: fxobject.hpp:329
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
virtual BOOLEAN Dispose(VOID)
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
VOID MarkDisposeOverride(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1101
_Must_inspect_result_ NTSTATUS Commit(__in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __out_opt WDFOBJECT *ObjectHandle, __in_opt FxObject *Parent=NULL, __in BOOLEAN AssignDriverAsDefaultParent=TRUE)
Definition: fxobject.cpp:904
__inline CfxDevice * GetDevice(VOID)
Definition: fxpackage.hpp:46
MdIrp m_PendingPnPIrp
Definition: fxpkgpnp.hpp:4360
static WDF_SPECIAL_FILE_TYPE _UsageToSpecialType(__in DEVICE_USAGE_NOTIFICATION_TYPE Type)
Definition: fxpkgpnp.hpp:3202
VOID SetInternalFailure(VOID)
Definition: fxpkgpnp.cpp:4856
VOID AddInterruptObject(__in FxInterrupt *Interrupt)
Definition: fxpkgpnp.cpp:5928
static MdCancelRoutineType _PowerWaitWakeCancelRoutine
Definition: fxpkgpnp.hpp:2736
VOID RemoveUsageDevice(__in MdDeviceObject DependentDevice)
Definition: fxpkgpnp.cpp:4742
FxPnpStateCallback * m_PnpStateCallbacks
Definition: fxpkgpnp.hpp:4374
ULONG m_PnpCapsUINumber
Definition: fxpkgpnp.hpp:4091
FxCmResList * m_Resources
Definition: fxpkgpnp.hpp:4220
VOID ProcessDelayedDeletion(VOID)
Definition: fxpkgpnp.cpp:1293
_Must_inspect_result_ NTSTATUS AllocateEnumInfo(VOID)
Definition: fxpkgpnp.cpp:4920
FxPnpDeviceUsageNotificationEx m_DeviceUsageNotificationEx
Definition: fxpkgpnp.hpp:4548
static _Must_inspect_result_ NTSTATUS _PnpCancelRemoveDevice(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:2026
VOID ChildListNotifyRemove(__inout PLONG PendingCount)
Definition: fxpkgpnp.cpp:4999
VOID AddQueryInterface(__in FxQueryInterface *QI, __in BOOLEAN Lock)
Definition: fxpkgpnp.cpp:5017
VOID RegisterPowerPolicyCallbacks(__in PWDF_POWER_POLICY_EVENT_CALLBACKS Callbacks)
Definition: fxpkgpnp.cpp:2715
PFN_IO_REPORT_INTERRUPT_INACTIVE m_IoReportInterruptInactive
Definition: fxpkgpnp.hpp:4294
_Must_inspect_result_ NTSTATUS QueryForCapabilities(VOID)
Definition: fxpkgpnp.cpp:1675
static _Must_inspect_result_ NTSTATUS _PnpRemoveDevice(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:2275
FxSystemThread * m_PowerThread
Definition: fxpkgpnp.hpp:4350
_Must_inspect_result_ NTSTATUS HandleQueryBusInformation(__inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:947
static VOID STDCALL _PowerThreadInterfaceDereference(__inout PVOID Context)
Definition: fxpkgpnp.cpp:5292
virtual VOID ReleaseReenumerationInterface(VOID)=0
ULONG m_InterruptObjectCount
Definition: fxpkgpnp.hpp:4308
_Must_inspect_result_ NTSTATUS CreatePowerThread(VOID)
Definition: fxpkgpnp.cpp:5125
SINGLE_LIST_ENTRY m_DeviceInterfaceHead
Definition: fxpkgpnp.hpp:4126
FxWaitLockInternal m_QueryInterfaceLock
Definition: fxpkgpnp.hpp:4120
FxSelfManagedIoMachine * m_SelfManagedIoMachine
Definition: fxpkgpnp.hpp:4155
_Must_inspect_result_ NTSTATUS PnpPowerReferenceDuringQueryPnp(VOID)
Definition: fxpkgpnp.cpp:5351
LONG m_SpecialFileCount[WdfSpecialFileMax-1]
Definition: fxpkgpnp.hpp:4139
_Must_inspect_result_ NTSTATUS PnpDeviceUsageNotification(__inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:3867
FxCmResList * m_ResourcesRaw
Definition: fxpkgpnp.hpp:4225
PNP_BUS_INFORMATION m_BusInformation
Definition: fxpkgpnp.hpp:4232
FxRelatedDeviceList * m_UsageDependentDeviceList
Definition: fxpkgpnp.hpp:4113
PFN_IO_DISCONNECT_INTERRUPT_EX m_IoDisconnectInterruptEx
Definition: fxpkgpnp.hpp:4289
static NTSTATUS _SxWakeSetItem(__in CfxDevice *Device, __in FxWmiInstanceInternal *Instance, __in ULONG DataItemId, __in ULONG InBufferSize, __in PVOID InBuffer)
Definition: fxpkgpnp.cpp:3556
FxPowerStateCallback * m_PowerStateCallbacks
Definition: fxpkgpnp.hpp:4376
BOOLEAN m_ReleaseHardwareAfterDescendantsOnFailure
Definition: fxpkgpnp.hpp:4277
static VOID STDCALL _PowerThreadInterfaceReference(__inout PVOID Context)
Definition: fxpkgpnp.cpp:5262
LONG m_PendingChildCount
Definition: fxpkgpnp.hpp:4178
FxPowerMachine m_PowerMachine
Definition: fxpkgpnp.hpp:4152
LONG m_PowerThreadInterfaceReferenceCount
Definition: fxpkgpnp.hpp:4352
FxPnpDeviceD0Exit m_DeviceD0Exit
Definition: fxpkgpnp.hpp:4554
UCHAR m_SystemPowerAction
Definition: fxpkgpnp.hpp:4242
_Must_inspect_result_ NTSTATUS __inline PowerReference(__in BOOLEAN WaitForD0, __in_opt PVOID Tag=NULL, __in_opt LONG Line=0, __in_opt PSTR File=NULL)
Definition: fxpkgpnp.hpp:3486
VOID PowerProcessEvent(__in FxPowerEvent Event, __in BOOLEAN ProcessEventOnDifferentThread=FALSE)
FxWaitLockInternal m_DeviceInterfaceLock
Definition: fxpkgpnp.hpp:4124
FxPnpDeviceQueryRemove m_DeviceQueryRemove
Definition: fxpkgpnp.hpp:4560
ULONG SetUsageNotificationFlags(__in DEVICE_USAGE_NOTIFICATION_TYPE Type, __in BOOLEAN InPath)
Definition: fxpkgpnp.cpp:4497
BYTE m_SetDeviceRemoveProcessed
Definition: fxpkgpnp.hpp:4198
BYTE m_FailedAction
Definition: fxpkgpnp.hpp:4191
static _Must_inspect_result_ NTSTATUS _PnpQueryRemoveDevice(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:1981
FxEnumerationInfo * m_EnumInfo
Definition: fxpkgpnp.hpp:4215
VOID ReleasePowerThread(VOID)
Definition: fxpkgpnp.cpp:5180
ULONG PowerPolicyGetCurrentWakeReason(VOID)
Definition: fxpkgpnp.cpp:5782
virtual _Must_inspect_result_ NTSTATUS Initialize(__in PWDFDEVICE_INIT DeviceInit)
Definition: fxpkgpnp.cpp:349
_Must_inspect_result_ NTSTATUS AddUsageDevice(__in MdDeviceObject DependentDevice)
Definition: fxpkgpnp.cpp:4685
_Must_inspect_result_ NTSTATUS HandleQueryInterfaceForPowerThread(__inout FxIrp *Irp, __out PBOOLEAN CompleteRequest)
Definition: fxpkgpnp.cpp:1437
VOID SetPowerCaps(__in PWDF_DEVICE_POWER_CAPABILITIES PowerCapabilities)
Definition: fxpkgpnp.cpp:5683
BOOLEAN m_InternalFailure
Definition: fxpkgpnp.hpp:4249
static VOID _SetPowerCapState(__in ULONG Index, __in DEVICE_POWER_STATE State, __out PULONG Result)
Definition: fxpkgpnp.cpp:5616
static VOID _PowerProcessEventInner(__in FxPkgPnp *This, __in FxPostProcessInfo *Info, __in PVOID WorkerContext)
VOID SetUsageSupport(__in DEVICE_USAGE_NOTIFICATION_TYPE Usage, __in BOOLEAN Supported)
Definition: fxpkgpnp.hpp:3138
BOOLEAN IsDevicePowerUpIrpPending(VOID)
Definition: fxpkgpnp.hpp:3113
BOOLEAN m_Failed
Definition: fxpkgpnp.hpp:4095
MxEvent * m_DeviceRemoveProcessed
Definition: fxpkgpnp.hpp:4172
virtual _Must_inspect_result_ NTSTATUS Dispatch(__in MdIrp Irp)
Definition: fxpkgpnp.cpp:520
virtual const PFN_PNP_POWER_CALLBACK * GetDispatchPower(VOID)=0
static NTSTATUS _S0IdleQueryInstance(__in CfxDevice *Device, __in FxWmiInstanceInternal *Instance, __in ULONG OutBufferSize, __out PVOID OutBuffer, __out PULONG BufferUsed)
Definition: fxpkgpnp.cpp:3455
_Must_inspect_result_ NTSTATUS HandleQueryDeviceRelations(__inout FxIrp *Irp, __inout FxRelatedDeviceList *List)
Definition: fxpkgpnp.cpp:996
BOOLEAN PowerPolicyCanWakeFromSystemState(__in SYSTEM_POWER_STATE SystemState)
Definition: fxpkgpnp.hpp:2831
virtual const PFN_PNP_POWER_CALLBACK * GetDispatchPnp(VOID)=0
BOOLEAN IsUsageSupported(__in DEVICE_USAGE_NOTIFICATION_TYPE Usage)
Definition: fxpkgpnp.hpp:3130
NTSTATUS NotifyResourceObjectsDx(__in ULONG NotifyFlags)
Definition: fxpkgpnp.cpp:6104
POWER_THREAD_INTERFACE m_PowerThreadInterface
Definition: fxpkgpnp.hpp:4213
VOID RevokeDmaEnablerResources(__in FxDmaEnabler *Enabler)
Definition: fxpkgpnpkm.cpp:529
BYTE m_DevicePowerStateOld
Definition: fxpkgpnp.hpp:4108
LONG AdjustUsageCount(__in DEVICE_USAGE_NOTIFICATION_TYPE Usage, __in BOOLEAN Add)
Definition: fxpkgpnp.hpp:3147
PFN_IO_REPORT_INTERRUPT_ACTIVE m_IoReportInterruptActive
Definition: fxpkgpnp.hpp:4293
static NTSTATUS _SxWakeQueryInstance(__in CfxDevice *Device, __in FxWmiInstanceInternal *Instaace, __in ULONG OutBufferSize, __out PVOID OutBuffer, __out PULONG BufferUsed)
Definition: fxpkgpnp.cpp:3519
FxCREvent * m_PowerThreadEvent
Definition: fxpkgpnp.hpp:4354
FxPowerPolicyStateCallback * m_PowerPolicyStateCallbacks
Definition: fxpkgpnp.hpp:4378
_Must_inspect_result_ NTSTATUS PostCreateDeviceInitialize(VOID)
Definition: fxpkgpnp.cpp:1187
virtual NTSTATUS QueryForPowerThread(VOID)=0
FxPnpMachine m_PnpMachine
Definition: fxpkgpnp.hpp:4151
SINGLE_LIST_ENTRY m_QueryInterfaceHead
Definition: fxpkgpnp.hpp:4122
static _Must_inspect_result_ NTSTATUS _PnpCancelStopDevice(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:1901
static DEVICE_USAGE_NOTIFICATION_TYPE _SpecialTypeToUsage(__in WDF_SPECIAL_FILE_TYPE Type)
Definition: fxpkgpnp.hpp:3187
_Must_inspect_result_ NTSTATUS PowerPolicyHandleSystemQueryPower(__in SYSTEM_POWER_STATE QueryState)
Definition: fxpkgpnp.cpp:3582
VOID ReadRegistrySxWake(__in PCUNICODE_STRING ValueName, __out BOOLEAN *Enabled)
Definition: fxpkgpnpkm.cpp:469
FxPnpDeviceD0Entry m_DeviceD0Entry
Definition: fxpkgpnp.hpp:4551
FxSpinLockTransactionedList * m_DmaEnablerList
Definition: fxpkgpnp.hpp:4227
DEVICE_POWER_STATE PowerPolicyGetDeviceDeepestDeviceWakeState(__in SYSTEM_POWER_STATE SystemState)
Definition: fxpkgpnp.cpp:6440
MxEvent m_RemoveEventUm
Definition: fxpkgpnp.hpp:4305
BOOLEAN m_AchievedStart
Definition: fxpkgpnp.hpp:4344
VOID NotifyResourceobjectsToReleaseResources(VOID)
Definition: fxpkgpnp.cpp:5990
VOID SetPnpCaps(__in PWDF_DEVICE_PNP_CAPABILITIES PnpCapabilities)
Definition: fxpkgpnp.cpp:5496
VOID SaveState(__in BOOLEAN UseCanSaveState)
Definition: fxpkgpnp.cpp:5831
VOID CommitUsageNotification(__in DEVICE_USAGE_NOTIFICATION_TYPE Type, __in ULONG OldFlags)
Definition: fxpkgpnp.cpp:4614
virtual NTSTATUS AskParentToRemoveAndReenumerate(VOID)=0
VOID AddChildList(__in FxChildList *List)
Definition: fxpkgpnp.cpp:4970
MdIrp m_PendingSystemPowerIrp
Definition: fxpkgpnp.hpp:4366
LONG GetPnpCapsInternal(VOID)
Definition: fxpkgpnp.cpp:5466
static _Must_inspect_result_ NTSTATUS _PnpStopDevice(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:1945
BOOLEAN m_SpecialSupport[WdfSpecialFileMax-1]
Definition: fxpkgpnp.hpp:4133
BOOLEAN PowerPolicyIsWakeEnabled(VOID)
Definition: fxpkgpnp.cpp:5769
VOID RemoveInterruptObject(__in FxInterrupt *Interrupt)
Definition: fxpkgpnp.cpp:5965
static _Must_inspect_result_ NTSTATUS _PnpQueryStopDevice(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:1850
BOOLEAN m_CapsQueried
Definition: fxpkgpnp.hpp:4247
BYTE m_DevicePowerState
Definition: fxpkgpnp.hpp:4105
LONG GetPnpStateInternal(VOID)
Definition: fxpkgpnp.cpp:5433
VOID CleanupStateMachines(__in BOOLEAN ClenaupPnp)
Definition: fxpkgpnp.cpp:2066
FxPkgPnp(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in CfxDevice *Device, __in WDFTYPE Type)
Definition: fxpkgpnp.cpp:48
FxPowerCaps m_PowerCaps
Definition: fxpkgpnp.hpp:4093
VOID __inline PowerDereference(__in_opt PVOID Tag=NULL, __in_opt LONG Line=0, __in_opt PSTR File=NULL)
Definition: fxpkgpnp.hpp:3498
VOID SetSpecialFileSupport(__in WDF_SPECIAL_FILE_TYPE FileType, __in BOOLEAN Supported)
Definition: fxpkgpnp.cpp:1307
VOID GetPnpState(__out PWDF_DEVICE_STATE State)
Definition: fxpkgpnp.cpp:5549
VOID PnpPowerDereferenceSelf(VOID)
Definition: fxpkgpnp.cpp:5382
_Must_inspect_result_ NTSTATUS AddRemovalDevice(__in MdDeviceObject DependentDevice)
Definition: fxpkgpnp.cpp:4753
static NTSTATUS _S0IdleSetItem(__in CfxDevice *Device, __in FxWmiInstanceInternal *Instance, __in ULONG DataItemId, __in ULONG InBufferSize, __in PVOID InBuffer)
Definition: fxpkgpnp.cpp:3494
_Must_inspect_result_ NTSTATUS HandleQueryBusRelations(__inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:758
ULONG m_PnpCapsAddress
Definition: fxpkgpnp.hpp:4090
LONG GetUsageCount(__in __range(1, 4) ULONG Usage)
Definition: fxpkgpnp.hpp:3161
VOID DeleteDevice(VOID)
Definition: fxpkgpnp.cpp:2249
FxPnpDeviceQueryStop m_DeviceQueryStop
Definition: fxpkgpnp.hpp:4559
VOID RemoveChildList(__in FxChildList *List)
Definition: fxpkgpnp.cpp:4983
static VOID _PnpProcessEventInner(__inout FxPkgPnp *This, __inout FxPostProcessInfo *Info, __in PVOID WorkerContext)
static VOID _PowerThreadEnqueue(__in PVOID Context, __in PWORK_QUEUE_ITEM WorkItem)
Definition: fxpkgpnp.hpp:3944
BOOLEAN m_WakeInterruptsKeepConnected
Definition: fxpkgpnp.hpp:4339
static NTSTATUS _S0IdleSetInstance(__in CfxDevice *Device, __in FxWmiInstanceInternal *Instance, __in ULONG InBufferSize, __in PVOID InBuffer)
Definition: fxpkgpnp.cpp:3471
VOID PowerPolicySetSxWakeState(__in BOOLEAN State)
Definition: fxpkgpnp.cpp:3720
NTSTATUS PowerPolicySetS0IdleSettings(__in PWDF_DEVICE_POWER_POLICY_IDLE_SETTINGS Settings)
Definition: fxpkgpnp.cpp:2778
static NTSTATUS _SxWakeSetInstance(__in CfxDevice *Device, __in FxWmiInstanceInternal *Instance, __in ULONG InBufferSize, __in PVOID InBuffer)
Definition: fxpkgpnp.cpp:3535
VOID AckPendingWakeInterruptOperation(__in BOOLEAN ProcessPowerEventOnDifferentThread)
Definition: fxpkgpnp.cpp:6211
static const GUID GUID_POWER_THREAD_INTERFACE
Definition: fxpkgpnp.hpp:4282
FxPnpDeviceReleaseHardware m_DeviceReleaseHardware
Definition: fxpkgpnp.hpp:4557
SharedPowerData m_SharedPower
Definition: fxpkgpnp.hpp:4161
VOID RemoveRemovalDevice(__in MdDeviceObject DependentDevice)
Definition: fxpkgpnp.cpp:4816
FxPnpDeviceUsageNotification m_DeviceUsageNotification
Definition: fxpkgpnp.hpp:4547
_Must_inspect_result_ NTSTATUS NotifyResourceObjectsD0(__in ULONG NotifyFlags)
Definition: fxpkgpnp.cpp:6055
NTSTATUS RegisterPowerPolicyWmiInstance(__in const GUID *Guid, __in FxWmiInstanceInternalCallbacks *Callbacks, __out FxWmiInstanceInternal **Instance)
Definition: fxpkgpnp.cpp:2738
VOID SetPnpState(__in PWDF_DEVICE_STATE State)
Definition: fxpkgpnp.cpp:5579
FxPnpDevicePrepareHardware m_DevicePrepareHardware
Definition: fxpkgpnp.hpp:4556
ULONG m_WakeInterruptCount
Definition: fxpkgpnp.hpp:4316
_Must_inspect_result_ NTSTATUS DispatchWaitWake(__inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:2431
virtual BOOLEAN Dispose(VOID)
Definition: fxpkgpnp.cpp:284
VOID ReadRegistryS0Idle(__in PCUNICODE_STRING ValueName, __out BOOLEAN *Enabled)
Definition: fxpkgpnpkm.cpp:376
VOID PnpProcessEvent(__in FxPnpEvent Event, __in BOOLEAN ProcessEventOnDifferentThread=FALSE)
BYTE m_SystemPowerState
Definition: fxpkgpnp.hpp:4102
LIST_ENTRY m_InterruptListHead
Definition: fxpkgpnp.hpp:4310
FxPnpDeviceD0ExitPreInterruptsDisabled m_DeviceD0ExitPreInterruptsDisabled
Definition: fxpkgpnp.hpp:4553
_Must_inspect_result_ NTSTATUS PnpPowerReferenceSelf(VOID)
Definition: fxpkgpnp.cpp:5322
ULONG m_DeviceStopCount
Definition: fxpkgpnp.hpp:4146
FxPnpDeviceSurpriseRemoval m_DeviceSurpriseRemoval
Definition: fxpkgpnp.hpp:4561
static VOID _PowerPolicyProcessEventInner(__inout FxPkgPnp *This, __inout FxPostProcessInfo *Info, __in PVOID WorkerContext)
BOOLEAN HasPowerThread(VOID)
Definition: fxpkgpnp.hpp:3508
VOID CleanupDeviceFromFailedCreate(__in MxEvent *WaitEvent)
Definition: fxpkgpnp.cpp:2190
FxPnpStateAndCaps m_PnpStateAndCaps
Definition: fxpkgpnp.hpp:4088
NTSTATUS AssignPowerFrameworkSettings(__in PWDF_POWER_FRAMEWORK_SETTINGS PowerFrameworkSettings)
Definition: fxpkgpnp.cpp:6243
NTSTATUS CompletePowerRequest(__inout FxIrp *Irp, __in NTSTATUS Status)
Definition: fxpkgpnp.cpp:5404
VOID RevertUsageNotificationFlags(__in DEVICE_USAGE_NOTIFICATION_TYPE Type, __in BOOLEAN InPath, __in ULONG OldFlags)
Definition: fxpkgpnp.cpp:4578
friend FxPowerPolicyOwnerSettings
Definition: fxpkgpnp.hpp:493
FxRelatedDeviceList * m_RemovalDeviceList
Definition: fxpkgpnp.hpp:4115
VOID SetPendingPnpIrp(__inout FxIrp *Irp, __in BOOLEAN MarkIrpPending=TRUE)
Definition: fxpkgpnp.cpp:4883
BOOLEAN m_DeviceInterfacesCanBeEnabled
Definition: fxpkgpnp.hpp:4128
static _Must_inspect_result_ NTSTATUS _PnpStartDevice(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:1823
VOID QueryForD3ColdInterface(VOID)
Definition: fxpkgpnpkm.cpp:538
BYTE m_SystemWake
Definition: fxpkgpnp.hpp:4188
FxPowerPolicyMachine m_PowerPolicyMachine
Definition: fxpkgpnp.hpp:4153
BOOLEAN IsInSpecialUse(VOID)
Definition: fxpkgpnp.hpp:3170
NTSTATUS CompletePnpRequest(__inout FxIrp *Irp, __in NTSTATUS Status)
Definition: fxpkgpnp.cpp:5752
BYTE m_DeviceWake[DeviceWakeStates]
Definition: fxpkgpnp.hpp:4185
VOID SetDeviceFailed(__in WDF_DEVICE_FAILED_ACTION FailedAction)
Definition: fxpkgpnp.cpp:3775
static DEVICE_POWER_STATE _GetPowerCapState(__in ULONG Index, __in ULONG State)
Definition: fxpkgpnp.cpp:5657
VOID PowerPolicySetS0IdleState(__in BOOLEAN State)
Definition: fxpkgpnp.cpp:3710
FxPnpDeviceD0EntryPostInterruptsEnabled m_DeviceD0EntryPostInterruptsEnabled
Definition: fxpkgpnp.hpp:4552
VOID SendEventToAllWakeInterrupts(__in enum FxWakeInterruptEvents WakeInterruptEvent)
Definition: fxpkgpnp.cpp:6164
virtual VOID FinishInitialize(__inout PWDFDEVICE_INIT DeviceInit)
Definition: fxpkgpnp.cpp:1240
ULONG m_WakeInterruptPendingAckCount
Definition: fxpkgpnp.hpp:4323
virtual NTSTATUS SendIrpSynchronously(FxIrp *Irp)=0
FxCREvent m_CleanupEventUm
Definition: fxpkgpnp.hpp:4304
VOID ClearRemovalDevicesList(VOID)
Definition: fxpkgpnp.cpp:4832
BOOLEAN m_HasPowerThread
Definition: fxpkgpnp.hpp:4256
NTSTATUS PowerPolicySetSxWakeSettings(__in PWDF_DEVICE_POWER_POLICY_WAKE_SETTINGS Settings, __in BOOLEAN ArmForWakeIfChildrenAreArmedForWake, __in BOOLEAN IndicateChildWakeOnParentWake)
Definition: fxpkgpnp.cpp:3245
PNP_DEVICE_STATE HandleQueryPnpDeviceState(__in PNP_DEVICE_STATE PnpDeviceState)
Definition: fxpkgpnp.cpp:662
_Must_inspect_result_ NTSTATUS HandleQueryInterface(__inout FxIrp *Irp, __out PBOOLEAN CompleteRequest)
Definition: fxpkgpnp.cpp:1493
static _Must_inspect_result_ NTSTATUS _DispatchWaitWake(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:2400
static _Must_inspect_result_ NTSTATUS _PnpDeviceUsageNotification(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:3857
PFN_IO_CONNECT_INTERRUPT_EX m_IoConnectInterruptEx
Definition: fxpkgpnp.hpp:4288
MdIrp m_PendingDevicePowerIrp
Definition: fxpkgpnp.hpp:4372
virtual NTSTATUS FireAndForgetIrp(FxIrp *Irp)=0
_Must_inspect_result_ NTSTATUS PnpSurpriseRemoval(__inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:2366
_Must_inspect_result_ NTSTATUS RegisterCallbacks(__in PWDF_PNPPOWER_EVENT_CALLBACKS DispatchTable)
Definition: fxpkgpnp.cpp:2667
D3COLD_SUPPORT_INTERFACE m_D3ColdInterface
Definition: fxpkgpnp.hpp:4166
VOID WriteStateToRegistry(__in HANDLE RegKey, __in PUNICODE_STRING ValueName, __in ULONG Value)
Definition: fxpkgpnpkm.cpp:301
VOID DropD3ColdInterface(VOID)
Definition: fxpkgpnpkm.cpp:615
FxPnpDeviceRelationsQuery m_DeviceRelationsQuery
Definition: fxpkgpnp.hpp:4549
static MdCompletionRoutineType _PowerPolicyWaitWakeCompletionRoutine
Definition: fxpkgpnp.hpp:2801
BOOLEAN m_SystemWokenByWakeInterrupt
Definition: fxpkgpnp.hpp:4330
VOID PowerPolicyProcessEvent(__in FxPowerPolicyEvent Event, __in BOOLEAN ProcessEventOnDifferentThread=FALSE)
PFN_WDF_DEVICE_D0_ENTRY_POST_INTERRUPTS_ENABLED m_Method
PFN_WDF_DEVICE_D0_ENTRY m_Method
PFN_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED m_Method
PFN_WDF_DEVICE_D0_EXIT m_Method
PFN_WDF_DEVICE_PREPARE_HARDWARE m_Method
PFN_WDF_DEVICE_QUERY_REMOVE m_Method
PFN_WDF_DEVICE_QUERY_STOP m_Method
PFN_WDF_DEVICE_RELATIONS_QUERY m_Method
VOID Invoke(__in WDFDEVICE Device, __in DEVICE_RELATION_TYPE RelationType)
PFN_WDF_DEVICE_RELEASE_HARDWARE m_Method
PFN_WDF_DEVICE_SURPRISE_REMOVAL m_Method
PFN_WDF_DEVICE_USAGE_NOTIFICATION_EX m_Method
_Must_inspect_result_ NTSTATUS Invoke(__in WDFDEVICE Device, __in WDF_SPECIAL_FILE_TYPE NotificationType, __in BOOLEAN InPath)
VOID Invoke(__in WDFDEVICE Device, __in WDF_SPECIAL_FILE_TYPE NotificationType, __in BOOLEAN InPath)
PFN_WDF_DEVICE_USAGE_NOTIFICATION m_Method
PFN_WDF_DEVICE_ARM_WAKE_FROM_S0 m_Method
PFN_WDF_DEVICE_ARM_WAKE_FROM_SX m_Method
PFN_WDF_DEVICE_ARM_WAKE_FROM_SX_WITH_REASON m_MethodWithReason
PFN_WDF_DEVICE_DISARM_WAKE_FROM_S0 m_Method
PFN_WDF_DEVICE_DISARM_WAKE_FROM_SX m_Method
PFN_WDF_DEVICE_WAKE_FROM_S0_TRIGGERED m_Method
PFN_WDF_DEVICE_WAKE_FROM_SX_TRIGGERED m_Method
VOID UnlockFromEnum(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
_Must_inspect_result_ NTSTATUS Add(__in PFX_DRIVER_GLOBALS Globals, __inout FxRelatedDevice *Entry)
VOID Remove(__in PFX_DRIVER_GLOBALS Globals, __in MdDeviceObject Device)
VOID LockForEnum(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
_Must_inspect_result_ FxRelatedDevice * GetNextEntry(__in_opt FxRelatedDevice *Entry)
MdDeviceObject GetDevice(VOID)
VOID InitializeMachine(__in PWDF_PNPPOWER_EVENT_CALLBACKS Callbacks)
static NTSTATUS _CreateAndInit(__deref_out FxSelfManagedIoMachine **SelfManagedIoMachine, __in FxPkgPnp *PkgPnp)
static _Must_inspect_result_ NTSTATUS _CreateAndInit(__deref_out FxSystemThread **SystemThread, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in WDFDEVICE Device, __in MdDeviceObject DeviceObject)
BOOLEAN ExitThread(VOID)
_Must_inspect_result_ FxTransactionedEntry * GetNextEntry(__in_opt FxTransactionedEntry *Entry)
VOID UnlockFromEnum(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
NTSTATUS Add(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxTransactionedEntry *Entry)
VOID LockForEnum(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
VOID Remove(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxTransactionedEntry *Entry)
CHECK_RETURN_IF_USER_MODE NTSTATUS Initialize()
Definition: fxwaitlock.hpp:235
static BOOLEAN _SystemManagedIdleTimeoutAvailable(VOID)
Definition: supportkm.cpp:211
__inline VOID SetObject(__in_opt MdDeviceObject DeviceObject)
VOID InvalidateDeviceState(__in MdDeviceObject Fdo)
VOID InvalidateDeviceRelations(__in DEVICE_RELATION_TYPE Type)
CCHAR GetStackSize(VOID)
VOID DereferenceObject()
__inline MdDeviceObject GetObject(VOID)
MdDeviceObject GetAttachedDeviceReference(VOID)
CHECK_RETURN_IF_USER_MODE __inline NTSTATUS Initialize(__in EVENT_TYPE Type, __in BOOLEAN InitialState)
Definition: mxeventkm.h:55
MxEvent * GetSelfPointer(VOID)
Definition: mxevent.h:110
static __inline VOID MxFreePool(__in PVOID Ptr)
Definition: mxmemorykm.h:41
static __inline PVOID MxAllocatePoolWithTag(__in POOL_TYPE PoolType, __in SIZE_T NumberOfBytes, __in ULONG Tag)
Definition: mxmemorykm.h:30
_Must_inspect_result_ __inline NTSTATUS Allocate(__in MdDeviceObject DeviceObject, __in_opt PVOID ThreadPoolEnv=NULL)
Definition: mxworkitemkm.h:41
static __inline NTSTATUS MxAcquireRemoveLock(__in MdRemoveLock RemoveLock, __in_opt PVOID Tag)
Definition: mxgeneralkm.h:268
static __inline BOOLEAN MxHasEnoughRemainingThreadStack(VOID)
Definition: mxgeneralkm.h:298
static __inline VOID MxAssert(__in BOOLEAN Condition)
Definition: mxgeneralkm.h:165
static __inline VOID MxReleaseRemoveLock(__in MdRemoveLock RemoveLock, __in PVOID Tag)
Definition: mxgeneralkm.h:278
static __inline VOID MxDereferenceObject(__in PVOID Object)
Definition: mxgeneralkm.h:247
static __inline VOID MxReferenceObject(__in PVOID Object)
Definition: mxgeneralkm.h:238
static __inline KIRQL MxGetCurrentIrql()
Definition: mxgeneralkm.h:86
@ Supported
Definition: classpnp.h:733
_In_ PIRP Irp
Definition: csq.h:116
#define __in
Definition: dbghelp.h:35
#define __inout
Definition: dbghelp.h:50
#define __in_opt
Definition: dbghelp.h:38
#define __out
Definition: dbghelp.h:62
#define TRACINGPNP
Definition: dbgtrace.h:67
#define TRACINGDEVICE
Definition: dbgtrace.h:58
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI CompleteRequest(IN PIRP Irp, IN NTSTATUS Status, IN ULONG_PTR Information)
Definition: dispatch.c:19
KIRQL irql
Definition: wave.h:1
#define __drv_requiresIRQL(irql)
Definition: driverspecs.h:321
#define __drv_maxIRQL(irql)
Definition: driverspecs.h:291
#define __drv_sameIRQL
Definition: driverspecs.h:325
#define __drv_minIRQL(irql)
Definition: driverspecs.h:293
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define PagedPool
Definition: env_spec_w32.h:308
@ Removed
Definition: fbtusb.h:86
FxChildList * pList
FxDevice * pDevice
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
PFX_DRIVER_GLOBALS pFxDriverGlobals
MxDeviceObject deviceObject
FX_TRACK_DRIVER(fxDriverGlobals)
SINGLE_LIST_ENTRY * pCur
PSINGLE_LIST_ENTRY ple
SINGLE_LIST_ENTRY ** ppPrev
FxVerifierDbgBreakPoint(pFxDriverGlobals)
FxAutoRegKey hKey
#define ROSWDFNOTIMPLEMENTED
Definition: fxglobals.h:52
_Must_inspect_result_ BOOLEAN __inline FxIsEqualGuid(__in CONST GUID *Lhs, __in CONST GUID *Rhs)
Definition: fxglobals.h:977
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
SHORT OldFlags
Definition: fxioqueue.cpp:1325
PDEVICE_OBJECT pTopOfStack
#define WDF_VERIFY_KM_ONLY_CODE()
Definition: fxmacros.hpp:298
@ ObjectDoNotLock
Definition: fxobject.hpp:128
#define ADDREF(_tag)
Definition: fxobject.hpp:49
#define RELEASE(_tag)
Definition: fxobject.hpp:50
_Must_inspect_result_ NTSTATUS PnpPassThroughQI(__in CfxDevice *Device, __inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:1351
const UCHAR DeviceWakeStates
Definition: fxpkgpnp.hpp:199
@ FxPnpCapSilentInstallUseDefault
Definition: fxpkgpnp.hpp:309
@ FxPnpStateResourcesChangedUseDefault
Definition: fxpkgpnp.hpp:277
@ FxPnpStateMask
Definition: fxpkgpnp.hpp:280
@ FxPnpStateDisabledUseDefault
Definition: fxpkgpnp.hpp:252
@ FxPnpCapHardwareDisabledUseDefault
Definition: fxpkgpnp.hpp:319
@ FxPnpCapSurpriseRemovalOKUseDefault
Definition: fxpkgpnp.hpp:314
@ FxPnpCapUniqueIDUseDefault
Definition: fxpkgpnp.hpp:304
@ FxPnpCapEjectSupportedUseDefault
Definition: fxpkgpnp.hpp:289
@ FxPnpStateNotDisableableUseDefault
Definition: fxpkgpnp.hpp:267
@ FxPnpStateDontDisplayInUIMask
Definition: fxpkgpnp.hpp:258
@ FxPnpCapLockSupportedUseDefault
Definition: fxpkgpnp.hpp:284
@ FxPnpStateRemovedUseDefault
Definition: fxpkgpnp.hpp:272
@ FxPnpCapNoDisplayInUIMask
Definition: fxpkgpnp.hpp:325
@ FxPnpCapNoDisplayInUITrue
Definition: fxpkgpnp.hpp:323
@ FxPnpStateDontDisplayInUIUseDefault
Definition: fxpkgpnp.hpp:257
@ FxPnpStateFailedUseDefault
Definition: fxpkgpnp.hpp:262
@ FxPnpCapMask
Definition: fxpkgpnp.hpp:327
@ FxPnpCapDockDeviceUseDefault
Definition: fxpkgpnp.hpp:299
@ FxPnpCapRemovableUseDefault
Definition: fxpkgpnp.hpp:294
@ FxPnpCapNoDisplayInUIFalse
Definition: fxpkgpnp.hpp:322
@ FxPnpCapNoDisplayInUIUseDefault
Definition: fxpkgpnp.hpp:324
@ FxPowerCapWakeFromD0UseDefault
Definition: fxpkgpnp.hpp:383
@ FxPowerCapDeviceD2UseDefault
Definition: fxpkgpnp.hpp:378
@ FxPowerCapWakeFromD2UseDefault
Definition: fxpkgpnp.hpp:393
@ FxPowerCapDeviceD1UseDefault
Definition: fxpkgpnp.hpp:373
@ FxPowerCapWakeFromD1UseDefault
Definition: fxpkgpnp.hpp:388
@ FxPowerCapWakeFromD3UseDefault
Definition: fxpkgpnp.hpp:398
VOID PnpPassThroughQIWorker(__in MxDeviceObject *Device, __inout FxIrp *Irp, __inout FxIrp *ForwardIrp)
Definition: fxpkgpnpkm.cpp:498
@ PnpEventRemove
@ PnpEventSurpriseRemove
@ PnpEventStop
@ PnpEventQueryRemove
@ PnpEventStartDevice
@ PnpEventCancelStop
@ PnpEventQueryStop
@ PnpEventCancelRemove
@ PnpEventAddDevice
@ FxPowerReferenceSendPnpPowerUpEvent
@ FxPowerPolicySxWakeDeviceEnabledFlag
@ FxPowerPolicySxWakeChildrenArmedFlag
@ PwrPolS0IdlePolicyChanged
@ FxPowerPolicyDefaultTimeout
@ PowerMarkPageable
@ PowerMarkNonpageable
@ PowerWakeInterruptCompleteTransition
@ PowerWakeArrival
@ RelatedDeviceStateNeedsReportPresent
@ RelatedDeviceStateReportedPresent
FxIrp * pIrp
FxIrp * irp
@ FxResourceNoAccess
Definition: fxresource.hpp:274
USHORT WDFTYPE
Definition: fxtypes.h:29
#define FxVerifierBugCheck(FxDriverGlobals, Error,...)
Definition: fxverifier.h:58
Status
Definition: gdiplustypes.h:25
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
struct _cl_event * event
Definition: glext.h:7739
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: glext.h:7750
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:599
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
#define C_ASSERT(e)
Definition: intsafe.h:73
uint32_t entry
Definition: isohybrid.c:63
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
static IPrintDialogCallback callback
Definition: printdlg.c:326
@ Disabled
Definition: mountmgr.h:158
#define _Must_inspect_result_
Definition: ms_sal.h:558
#define __fallthrough
Definition: ms_sal.h:2886
#define DO_NOTHING()
Definition: mxgeneral.h:32
IWudfIrp * MdIrp
Definition: mxum.h:103
WUDF_DRIVER_CANCEL * MdCancelRoutine
Definition: mxum.h:143
#define KernelMode
Definition: asm.h:34
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define STANDARD_RIGHTS_WRITE
Definition: nt_native.h:66
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
@ SynchronizationEvent
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
@ PowerSystemMaximum
Definition: ntpoapi.h:42
@ PowerSystemUnspecified
Definition: ntpoapi.h:35
@ PowerSystemWorking
Definition: ntpoapi.h:36
@ PowerSystemHibernate
Definition: ntpoapi.h:40
@ PowerActionNone
Definition: ntpoapi.h:123
@ PowerDeviceD1
Definition: ntpoapi.h:50
@ PowerDeviceUnspecified
Definition: ntpoapi.h:48
@ PowerDeviceD0
Definition: ntpoapi.h:49
@ PowerDeviceD2
Definition: ntpoapi.h:51
@ PowerDeviceD3
Definition: ntpoapi.h:52
@ PowerDeviceMaximum
Definition: ntpoapi.h:53
enum _DEVICE_POWER_STATE DEVICE_POWER_STATE
enum _SYSTEM_POWER_STATE SYSTEM_POWER_STATE
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:650
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_POWER_STATE_INVALID
Definition: ntstatus.h:831
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define SET_TRI_STATE_FROM_STATE_BITS(state, S, FieldName)
Definition: pnppriv.hpp:189
#define GET_PNP_STATE_BITS_FROM_STRUCT(S, FieldName)
Definition: pnppriv.hpp:221
#define GET_POWER_CAP_BITS_FROM_STRUCT(S, FieldName)
Definition: pnppriv.hpp:231
#define SET_PNP_DEVICE_STATE_BIT(State, ExternalState, value, Name)
Definition: pnppriv.hpp:258
#define GET_PNP_CAP_BITS_FROM_STRUCT(S, FieldName)
Definition: pnppriv.hpp:226
#define QI(I)
FxLibraryGlobalsType FxLibraryGlobals
Definition: globals.cpp:95
#define maxStack
Definition: rtf.h:1090
_In_ UCHAR _In_ ULONG _Out_ PUCHAR _Outptr_result_bytebuffer_ OutBufferLength PVOID * OutBuffer
Definition: scsi.h:4071
@ Failed
Definition: arc.h:79
@ Removable
Definition: arc.h:81
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
NTSTATUS EnterCRAndWaitAndLeave(VOID)
Definition: fxwaitlock.hpp:87
FxCREvent * GetSelfPointer(VOID)
Definition: fxwaitlock.hpp:180
VOID Set(VOID)
Definition: fxwaitlock.hpp:144
CHECK_RETURN_IF_USER_MODE NTSTATUS Initialize(__in BOOLEAN InitialState=FALSE)
Definition: fxwaitlock.hpp:51
NTSTATUS Initialize(VOID)
Definition: fxpkgpnp.hpp:442
FxWaitLockTransactionedList m_ChildListList
Definition: fxpkgpnp.hpp:485
FxWaitLockInternal m_StateMachineLock
BOOLEAN SetFinished(__in FxCREvent *Event)
Definition: eventqueue.cpp:91
PFN_IO_REPORT_INTERRUPT_INACTIVE IoReportInterruptInactive
Definition: fxglobals.h:764
PFN_IO_DISCONNECT_INTERRUPT_EX IoDisconnectInterruptEx
Definition: fxglobals.h:732
RTL_OSVERSIONINFOEXW OsVersionInfo
Definition: fxglobals.h:770
PFN_IO_CONNECT_INTERRUPT_EX IoConnectInterruptEx
Definition: fxglobals.h:730
PFN_IO_REPORT_INTERRUPT_ACTIVE IoReportInterruptActive
Definition: fxglobals.h:762
ULONG D3Latency
Definition: fxpkgpnp.hpp:425
BYTE SystemWake
Definition: fxpkgpnp.hpp:413
ULONG D2Latency
Definition: fxpkgpnp.hpp:424
ULONG D1Latency
Definition: fxpkgpnp.hpp:423
USHORT Caps
Definition: fxpkgpnp.hpp:406
BYTE DeviceWake
Definition: fxpkgpnp.hpp:412
ULONG States
Definition: fxpkgpnp.hpp:418
_Must_inspect_result_ NTSTATUS Init(__inout FxPkgPnp *Pnp, __in PFN_PNP_EVENT_WORKER WorkerRoutine)
_Must_inspect_result_ NTSTATUS InitUsbSS(VOID)
FxPowerPolicyOwnerSettings * m_Owner
FxPowerDeviceArmWakeFromSx m_DeviceArmWakeFromSx
FxPowerDeviceWakeFromSxTriggered m_DeviceWakeFromSxTriggered
FxPowerDeviceArmWakeFromS0 m_DeviceArmWakeFromS0
FxPowerDeviceDisarmWakeFromSx m_DeviceDisarmWakeFromSx
_Must_inspect_result_ NTSTATUS Init(VOID)
FxPowerDeviceDisarmWakeFromS0 m_DeviceDisarmWakeFromS0
FxPowerDeviceWakeFromS0Triggered m_DeviceWakeFromS0Triggered
BOOLEAN m_SendQueryToParentStack
FxDeviceProcessQueryInterfaceRequest m_ProcessRequest
static FxQueryInterface * _FromEntry(__in PSINGLE_LIST_ENTRY Entry)
SINGLE_LIST_ENTRY m_Entry
_Must_inspect_result_ NTSTATUS Init(__inout FxPkgPnp *Pnp, __in PFN_PNP_EVENT_WORKER WorkerRoutine, __in PVOID WorkerContext=NULL)
Definition: eventqueue.cpp:370
FxObject * GetTransactionedObject(VOID)
FxPkgPnp * m_PkgPnp
Definition: fxwatchdog.hpp:110
static MdDeferredRoutineType _WatchdogDpc
Definition: fxwatchdog.hpp:106
MxThread m_CallingThread
Definition: fxwatchdog.hpp:112
_Must_inspect_result_ NTSTATUS Init(__inout FxPkgPnp *Pnp, __in PFN_PNP_EVENT_WORKER WorkerRoutine, __in PVOID WorkerContext=NULL)
Definition: eventqueue.cpp:321
IdleTimeoutManagement m_TimeoutMgmt
DEVICE_POWER_STATE DxState
BOOLEAN m_ExtendWatchDogTimer
Definition: fxpkgpnp.hpp:196
BOOLEAN m_WaitWakeOwner
Definition: fxpkgpnp.hpp:186
MdIrp m_WaitWakeIrp
Definition: fxpkgpnp.hpp:180
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
_Must_inspect_result_ BOOLEAN IsVersionGreaterThanOrEqualTo(__in ULONG Major, __in ULONG Minor)
Definition: globalskm.cpp:92
BOOLEAN FxVerboseOn
Definition: fxglobals.h:462
PVOID Context
Definition: miniport.h:123
USHORT Version
Definition: miniport.h:122
USHORT Size
Definition: miniport.h:121
PINTERFACE_REFERENCE InterfaceReference
Definition: miniport.h:124
PINTERFACE_DEREFERENCE InterfaceDereference
Definition: miniport.h:125
Definition: ketypes.h:699
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
ULONG dwMajorVersion
Definition: rtltypes.h:270
PFN_POWER_THREAD_ENQUEUE PowerThreadEnqueue
Definition: fxpkgpnp.hpp:110
Definition: ntbasedef.h:628
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
DEVICE_CAPABILITIES DeviceCaps
Definition: device_common.h:30
DEVICE_WAKE_DEPTH DeepestWakeableDstate[PowerSystemHibernate+1]
Definition: device_common.h:37
Definition: name.c:39
Definition: ps.c:97
Definition: dhcpd.h:245
_Must_inspect_result_ NTSTATUS GetStackCapabilities(__in PFX_DRIVER_GLOBALS DriverGlobals, __in MxDeviceObject *DeviceInStack, __in_opt PD3COLD_SUPPORT_INTERFACE D3ColdInterface, __out PSTACK_DEVICE_CAPABILITIES Capabilities)
Definition: supportkm.cpp:48
VOID CopyQueryInterfaceToIrpStack(__in PPOWER_THREAD_INTERFACE PowerThreadInterface, __in FxIrp *Irp)
Definition: supportkm.cpp:32
VOID SetD3ColdSupport(__in PFX_DRIVER_GLOBALS DriverGlobals, __in MxDeviceObject *DeviceInStack, __in PD3COLD_SUPPORT_INTERFACE D3ColdInterface, __in BOOLEAN UseD3Cold)
Definition: supportkm.cpp:172
_Must_inspect_result_ NTSTATUS SendDeviceUsageNotification(__in MxDeviceObject *RelatedDevice, __inout FxIrp *RelatedIrp, __in MxWorkItem *Workitem, __in FxIrp *OriginalIrp, __in BOOLEAN Revert)
Definition: supportkm.cpp:220
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char * PBOOLEAN
Definition: typedefs.h:53
int64_t LONGLONG
Definition: typedefs.h:68
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
int32_t * PLONG
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
char CCHAR
Definition: typedefs.h:51
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
LONGLONG QuadPart
Definition: typedefs.h:114
Definition: pdh_main.c:94
struct _WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_V1_7 WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_V1_7
@ WDF_PNP_FATAL_ERROR
Definition: wdfbugcodes.h:69
@ WDF_POWER_MULTIPLE_PPO
Definition: wdfbugcodes.h:70
@ WDF_POWER_ROUTINE_TIMED_OUT
Definition: wdfbugcodes.h:58
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ PWDFDEVICE_INIT DeviceInit
Definition: wdfcontrol.h:113
#define DECLARE_CONST_UNICODE_STRING(_variablename, _string)
Definition: wdfcore.h:161
FORCEINLINE LONGLONG WDF_REL_TIMEOUT_IN_MS(_In_ ULONGLONG Time)
Definition: wdfcore.h:80
@ WakeAllowUserControl
Definition: wdfdevice.h:418
@ WakeDoNotAllowUserControl
Definition: wdfdevice.h:417
@ WdfDevStatePnpInit
Definition: wdfdevice.h:69
_In_ PWDFDEVICE_INIT _In_ BOOLEAN IsPowerPolicyOwner
Definition: wdfdevice.h:2966
@ WdfPowerDeviceD3Final
Definition: wdfdevice.h:427
enum _WDF_SPECIAL_FILE_TYPE WDF_SPECIAL_FILE_TYPE
@ WdfReleaseHardwareOrderOnFailureAfterDescendants
Definition: wdfdevice.h:476
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_POWER_POLICY_IDLE_SETTINGS Settings
Definition: wdfdevice.h:2595
@ WdfDeviceFailedNoRestart
Definition: wdfdevice.h:470
@ WdfDeviceFailedAttemptRestart
Definition: wdfdevice.h:469
@ WdfDeviceFailedUndefined
Definition: wdfdevice.h:468
#define WDF_SX_WAKE_ENABLED_VALUE_NAME
Definition: wdfdevice.h:491
@ WdfSpecialFileBoot
Definition: wdfdevice.h:445
@ WdfSpecialFileMax
Definition: wdfdevice.h:446
@ WdfSpecialFileHibernation
Definition: wdfdevice.h:443
@ WdfSpecialFileDump
Definition: wdfdevice.h:444
@ WdfSpecialFilePaging
Definition: wdfdevice.h:442
#define WDF_SX_WAKE_DEFAULT_VALUE_NAME
Definition: wdfdevice.h:493
_In_ WDFDEVICE _In_ WDF_SPECIAL_FILE_TYPE FileType
Definition: wdfdevice.h:2741
#define IdleTimeoutDefaultValue
Definition: wdfdevice.h:816
_In_ WDFDEVICE _In_ WDF_DEVICE_FAILED_ACTION FailedAction
Definition: wdfdevice.h:3975
_Must_inspect_result_ _In_ WDFDEVICE _In_ PDEVICE_OBJECT DependentDevice
Definition: wdfdevice.h:2263
@ IdleDoNotAllowUserControl
Definition: wdfdevice.h:407
@ IdleAllowUserControl
Definition: wdfdevice.h:408
_In_ WDFDEVICE _In_ PWDF_DEVICE_PNP_CAPABILITIES PnpCapabilities
Definition: wdfdevice.h:3857
_In_ WDFDEVICE _In_ PWDF_DEVICE_POWER_CAPABILITIES PowerCapabilities
Definition: wdfdevice.h:3886
@ SystemManagedIdleTimeout
Definition: wdfdevice.h:1244
@ SystemManagedIdleTimeoutWithHint
Definition: wdfdevice.h:1245
#define WDF_S0_IDLE_ENABLED_VALUE_NAME
Definition: wdfdevice.h:490
enum _WDF_DEVICE_FAILED_ACTION WDF_DEVICE_FAILED_ACTION
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_POWER_FRAMEWORK_SETTINGS PowerFrameworkSettings
Definition: wdfdevice.h:4335
@ IdleUsbSelectiveSuspend
Definition: wdfdevice.h:402
@ IdleCanWakeFromS0
Definition: wdfdevice.h:401
@ IdleCannotWakeFromS0
Definition: wdfdevice.h:400
#define WDF_S0_IDLE_DEFAULT_VALUE_NAME
Definition: wdfdevice.h:492
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
Definition: wdfdpc.h:112
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFINTERRUPT * Interrupt
Definition: wdfinterrupt.h:379
_Must_inspect_result_ _In_ WDFOBJECT _In_ CONST GUID * Guid
Definition: wdfobject.h:762
_In_ PWDFDEVICE_INIT _In_ PWDF_PDO_EVENT_CALLBACKS DispatchTable
Definition: wdfpdo.h:248
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127
@ WdfTrue
Definition: wdftypes.h:88
@ WdfUseDefault
Definition: wdftypes.h:89
@ WdfFalse
Definition: wdftypes.h:87
enum _WDF_TRI_STATE WDF_TRI_STATE
#define WDF_NO_HANDLE
Definition: wdftypes.h:107
#define WDF_NO_OBJECT_ATTRIBUTES
Definition: wdftypes.h:105
_In_ ULONG _Out_ PULONG BufferUsed
Definition: wdfwmi.h:92
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_WMI_INSTANCE_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_opt_ WDFWMIINSTANCE * Instance
Definition: wdfwmi.h:481
_In_ ULONG InBufferSize
Definition: wdfwmi.h:106
_In_ ULONG DataItemId
Definition: wdfwmi.h:123
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
struct _PNP_BUS_INFORMATION * PPNP_BUS_INFORMATION
enum _DEVICE_WAKE_DEPTH DEVICE_WAKE_DEPTH
#define IRP_MN_CANCEL_STOP_DEVICE
@ BusRelations
Definition: iotypes.h:2152
#define IRP_MN_WAIT_WAKE
#define IRP_MN_QUERY_PNP_DEVICE_STATE
#define IRP_MN_EJECT
#define PNP_DEVICE_NOT_DISABLEABLE
Definition: iotypes.h:1006
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED
Definition: iotypes.h:1005
#define IRP_MN_START_DEVICE
#define PNP_DEVICE_FAILED
Definition: iotypes.h:1003
ULONG PNP_DEVICE_STATE
Definition: iotypes.h:997
#define PNP_DEVICE_DONT_DISPLAY_IN_UI
Definition: iotypes.h:1002
#define IRP_MN_REMOVE_DEVICE
#define PNP_DEVICE_DISABLED
Definition: iotypes.h:1001
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define DO_POWER_PAGABLE
#define IRP_MN_QUERY_STOP_DEVICE
#define IRP_MN_SET_POWER
#define DO_POWER_INRUSH
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define IRP_MN_STOP_DEVICE
@ DeviceWakeDepthMaximum
Definition: iotypes.h:7485
@ DeviceWakeDepthD0
Definition: iotypes.h:7480
@ DeviceWakeDepthNotWakeable
Definition: iotypes.h:7479
#define IRP_MJ_POWER
_In_ SYSTEM_POWER_STATE SystemPowerState
Definition: iotypes.h:7519
enum _DEVICE_RELATION_TYPE DEVICE_RELATION_TYPE
#define PNP_DEVICE_REMOVED
Definition: iotypes.h:1004
FORCEINLINE DEVICE_POWER_STATE MapWakeDepthToDstate(_In_ DEVICE_WAKE_DEPTH WakeDepth)
Definition: iotypes.h:7490
#define IRP_MN_QUERY_POWER
enum _DEVICE_USAGE_NOTIFICATION_TYPE DEVICE_USAGE_NOTIFICATION_TYPE
@ DeviceUsageTypeDumpFile
Definition: iotypes.h:1172
@ DeviceUsageTypePaging
Definition: iotypes.h:1170
#define IRP_MN_QUERY_REMOVE_DEVICE
@ Executive
Definition: ketypes.h:415
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:688
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:689
unsigned char UCHAR
Definition: xmlstorage.h:181
unsigned char BYTE
Definition: xxhash.c:193