NTSTATUS PopSetSystemPowerStateTraverse(PDEVICE_NODE DeviceNode, PVOID Context) { PPOWER_STATE_TRAVERSE_CONTEXT PowerStateContext = Context; NTSTATUS Status; DPRINT("PopSetSystemPowerStateTraverse(%p, %p)\n", DeviceNode, Context); if (DeviceNode == IopRootDeviceNode) return STATUS_SUCCESS; if (DeviceNode->PhysicalDeviceObject == PowerStateContext->PowerDevice) return STATUS_SUCCESS; if (DeviceNode->Flags & DNF_LEGACY_DRIVER) return STATUS_SUCCESS; Status = PopSendSetSystemPowerState(DeviceNode->PhysicalDeviceObject, PowerStateContext->SystemPowerState, PowerStateContext->PowerAction); if (!NT_SUCCESS(Status)) { DPRINT1("Device '%wZ' failed IRP_MN_SET_POWER\n", &DeviceNode->InstancePath); } #if 0 return Status; #else return STATUS_SUCCESS; #endif }
NTSTATUS NTAPI PopSetSystemPowerState(SYSTEM_POWER_STATE PowerState, POWER_ACTION PowerAction) { PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT Fdo; NTSTATUS Status; DEVICETREE_TRAVERSE_CONTEXT Context; POWER_STATE_TRAVERSE_CONTEXT PowerContext; Status = IopGetSystemPowerDeviceObject(&DeviceObject); if (!NT_SUCCESS(Status)) { DPRINT1("No system power driver available\n"); Fdo = NULL; } else { Fdo = IoGetAttachedDeviceReference(DeviceObject); if (Fdo == DeviceObject) { DPRINT("An FDO was not attached\n"); return STATUS_UNSUCCESSFUL; } } /* Set up context */ PowerContext.PowerAction = PowerAction; PowerContext.SystemPowerState = PowerState; PowerContext.PowerDevice = Fdo; /* Query for system power change */ IopInitDeviceTreeTraverseContext(&Context, IopRootDeviceNode, PopQuerySystemPowerStateTraverse, &PowerContext); Status = IopTraverseDeviceTree(&Context); if (!NT_SUCCESS(Status)) { DPRINT1("Query system power state failed; changing state anyway\n"); } /* Set system power change */ IopInitDeviceTreeTraverseContext(&Context, IopRootDeviceNode, PopSetSystemPowerStateTraverse, &PowerContext); IopTraverseDeviceTree(&Context); if (!PopAcpiPresent) return STATUS_NOT_IMPLEMENTED; if (Fdo != NULL) { if (PowerAction != PowerActionShutdownReset) PopSendSetSystemPowerState(Fdo, PowerState, PowerAction); ObDereferenceObject(Fdo); } return Status; }