summaryrefslogtreecommitdiffstats
path: root/private/ntos/po/misc.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/po/misc.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/po/misc.c')
-rw-r--r--private/ntos/po/misc.c278
1 files changed, 278 insertions, 0 deletions
diff --git a/private/ntos/po/misc.c b/private/ntos/po/misc.c
new file mode 100644
index 000000000..1f5d75283
--- /dev/null
+++ b/private/ntos/po/misc.c
@@ -0,0 +1,278 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ misc.c
+
+Abstract:
+
+ This module implements the power management
+
+Author:
+
+ Ken Reneris (kenr) 19-July-1994
+
+Revision History:
+
+--*/
+
+
+#include "pop.h"
+
+
+#ifdef ALLOC_PRAGMA
+
+#ifdef _PNP_POWER_
+#pragma alloc_text(PAGE,PoInitializeDeviceObject)
+#endif
+
+#pragma alloc_text(PAGE,PoSetPowerManagementEnable)
+#endif
+
+#ifdef _PNP_POWER_
+
+VOID
+PoInitializeDeviceObject (
+ IN PDEVICE_OBJECT DeviceObject
+ )
+{
+ PDEVOBJ_EXTENSION DeviceObjectExt;
+
+ DeviceObjectExt = DeviceObject->DeviceObjectExtension;
+ DeviceObjectExt->CurrentPowerState = PowerUp;
+ DeviceObjectExt->PendingPowerState = PowerUp;
+ DeviceObjectExt->PowerControlNeeded = TRUE;
+ DeviceObjectExt->UseAsyncPowerUp = TRUE;
+
+ KeInitializeDeviceQueue (&DeviceObjectExt->DeviceHoldingQueue);
+
+ PopLockDeviceList (FALSE);
+
+ //
+ // Add to global list of all device objects
+ //
+
+ InsertTailList (&PopDeviceList, &DeviceObjectExt->AllDeviceObjects);
+ PopUnlockDeviceList ();
+}
+
+
+
+VOID
+PoRunDownDeviceObject (
+ IN PDEVICE_OBJECT DeviceObject
+ )
+{
+ KIRQL OldIrql;
+ PDEVOBJ_EXTENSION DeviceObjectExt;
+
+ DeviceObjectExt = (PDEVOBJ_EXTENSION) DeviceObject->DeviceObjectExtension;
+
+ //
+ // Lock power management devicelist and state information
+ //
+
+ PopLockDeviceList (FALSE);
+ PopLockStateDatabase (&OldIrql);
+
+ //
+ // If in IdleScan list, remove it
+ //
+
+ if (DeviceObjectExt->IdleList.Flink) {
+ RemoveEntryList (&DeviceObjectExt->IdleList);
+ }
+
+ //
+ // Verify not busy
+ //
+
+ ASSERT (DeviceObjectExt->CurrentSetPowerIrp == NULL);
+ ASSERT (IsListEmpty (&DeviceObjectExt->DeviceHoldingQueue.DeviceListHead));
+
+ //
+ // If in PowerState change remove it
+ //
+
+ if (DeviceObjectExt->PowerStateChange.Flink) {
+
+ //
+ // Requent setting state to current state. That will
+ // remove it from the list.
+ //
+
+ PopRequestPowerChange (
+ DeviceObjectExt,
+ DeviceObjectExt->CurrentPowerState,
+ DeviceObjectExt->CurrentDevicePowerState
+ );
+
+ ASSERT (DeviceObjectExt->PowerStateChange.Flink);
+ }
+
+ //
+ // Remove from global list of all device objects
+ //
+
+ RemoveEntryList (&DeviceObjectExt->AllDeviceObjects);
+
+ //
+ // Unlock device list and state information
+ //
+
+ PopUnlockStateDatabase (OldIrql);
+ PopUnlockDeviceList ();
+}
+
+
+VOID
+PoSetPowerManagementEnable (
+ IN BOOLEAN Enable
+ )
+{
+ PoEnabled = Enable;
+
+ if (Enable) {
+ KeSetTimer (&PopIdleScanTimer, PopIdleScanTime, &PopIdleScanDpc);
+ }
+}
+
+
+POBJECT_NAME_INFORMATION
+PopGetDeviceName (
+ PDEVICE_OBJECT DeviceObject
+ )
+/*++
+
+Routine Description:
+
+ Utility function to lookup the device object's name. If the
+ device objects name can't be found, then the driver objects
+ name is looked up.
+
+--*/
+{
+ POBJECT_NAME_INFORMATION ObjectName;
+ NTSTATUS Status;
+ ULONG ObjectNameSize, NewSize;
+
+ if (KeGetCurrentIrql() >= DISPATCH_LEVEL) {
+ return NULL;
+ }
+
+ ObjectName = (POBJECT_NAME_INFORMATION)
+ ExAllocatePool (PagedPool, sizeof (OBJECT_NAME_INFORMATION) + 100);
+ ObjectNameSize = sizeof (OBJECT_NAME_INFORMATION);
+ if (!ObjectName) {
+ return NULL;
+ }
+
+ //
+ // Get the name of the device object
+ //
+
+ for (; ;) {
+ NewSize = 0;
+ Status = ObQueryNameString (
+ DeviceObject,
+ ObjectName,
+ ObjectNameSize,
+ &NewSize
+ );
+
+ if (NewSize <= ObjectNameSize) {
+ break;
+ }
+
+ ExFreePool (ObjectName);
+ ObjectName = (POBJECT_NAME_INFORMATION) ExAllocatePool (PagedPool, NewSize);
+ ObjectNameSize = NewSize;
+ if (!ObjectName) {
+ break;
+ }
+ }
+
+ //
+ // If no device object name, get the driver object name
+ //
+
+ if (NT_SUCCESS(Status) && !ObjectName->Name.Length) {
+ for (; ;) {
+ NewSize = 0;
+ Status = ObQueryNameString (
+ DeviceObject->DriverObject,
+ ObjectName,
+ ObjectNameSize,
+ &NewSize
+ );
+
+ if (NewSize <= ObjectNameSize) {
+ break;
+ }
+
+ ExFreePool (ObjectName);
+ ObjectName = (POBJECT_NAME_INFORMATION) ExAllocatePool (PagedPool, NewSize);
+ ObjectNameSize = NewSize;
+ if (!ObjectName) {
+ break;
+ }
+ }
+ }
+
+ if (!ObjectName) {
+ return NULL;
+ }
+
+ if (!NT_SUCCESS(Status) || !ObjectName->Name.Length) {
+ ExFreePool (ObjectName);
+ return NULL;
+ }
+
+ return ObjectName;
+}
+
+#if DBG
+PUCHAR
+PopPowerState (
+ POWER_STATE PowerState
+ )
+{
+ PUCHAR p;
+
+ switch (PowerState) {
+ case PowerUnspecified: p = "PowerUnspecified"; break;
+ case PowerUp: p = "PowerUp"; break;
+ case PowerQuery: p = "PowerQuery"; break;
+ case PowerStandby: p = "PowerStandby"; break;
+ case PowerSuspend: p = "PowerSuspend"; break;
+ case PowerHibernate: p = "PowerHibernate"; break;
+ case PowerDown: p = "PowerDown"; break;
+ case PowerDownRemove: p = "PowerDownRemove"; break;
+ default: p = "INVALID POWER STATE"; break;
+ }
+
+ return p;
+}
+#endif
+
+#endif // _PNP_POWER_
+
+ULONG
+PoQueryPowerSequence (
+ VOID
+ )
+{
+
+#ifndef _PNP_POWER_
+
+ return 1;
+
+#else
+
+ ASSERT (PoPowerSequence);
+ return PoPowerSequence;
+
+#endif
+}