- Silence TCPIP.
[reactos.git] / reactos / ntoskrnl / po / power.c
index c0c549e..d3f8322 100644 (file)
@@ -1,42 +1,36 @@
-/*
- *  ReactOS kernel
- *  Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+/* $Id$
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/* $Id: power.c,v 1.3 2001/05/01 23:08:20 chorns Exp $
+ * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/po/power.c
  * PURPOSE:         Power Manager
- * PROGRAMMER:      Casper S. Hornstrup (chorns@users.sourceforge.net)
- * UPDATE HISTORY:
- *   20/08/1999 EA  Created
- *   16/04/2001 CSH Stubs added
+ *
+ * PROGRAMMERS:     Casper S. Hornstrup (chorns@users.sourceforge.net)
+ *                  HervĂ© Poussineau (hpoussin@reactos.com)
  */
-#include <ddk/ntddk.h>
-#include <internal/config.h>
-#include <internal/io.h>
-#include <internal/po.h>
 
+#include <ntoskrnl.h>
 #define NDEBUG
 #include <internal/debug.h>
 
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, PoInit)
+#endif
 
-PDEVICE_NODE PopSystemPowerDeviceNode = NULL;
 
+typedef struct _REQUEST_POWER_ITEM
+{
+  PREQUEST_POWER_COMPLETE CompletionRoutine;
+  POWER_STATE PowerState;
+  PVOID Context;
+} REQUEST_POWER_ITEM, *PREQUEST_POWER_ITEM;
+
+PDEVICE_NODE PopSystemPowerDeviceNode = NULL;
+BOOLEAN PopAcpiPresent = FALSE;
 
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
 PoCallDriver(
@@ -50,6 +44,9 @@ PoCallDriver(
   return Status;
 }
 
+/*
+ * @unimplemented
+ */
 PULONG
 STDCALL
 PoRegisterDeviceForIdleDetection(
@@ -61,6 +58,9 @@ PoRegisterDeviceForIdleDetection(
   return NULL;
 }
 
+/*
+ * @unimplemented
+ */
 PVOID
 STDCALL
 PoRegisterSystemState(
@@ -70,17 +70,110 @@ PoRegisterSystemState(
   return NULL;
 }
 
+static
+NTSTATUS STDCALL
+PopRequestPowerIrpCompletion(
+  IN PDEVICE_OBJECT DeviceObject,
+  IN PIRP Irp,
+  IN PVOID Context)
+{
+  PIO_STACK_LOCATION Stack;
+  PREQUEST_POWER_ITEM RequestPowerItem;
+  
+  Stack = IoGetNextIrpStackLocation(Irp);
+  RequestPowerItem = (PREQUEST_POWER_ITEM)Context;
+  
+  RequestPowerItem->CompletionRoutine(
+    DeviceObject,
+    Stack->MinorFunction,
+    RequestPowerItem->PowerState,
+    RequestPowerItem->Context,
+    &Irp->IoStatus);
+  
+  ExFreePool(&Irp->IoStatus);
+  ExFreePool(Context);
+  return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
 PoRequestPowerIrp(
   IN PDEVICE_OBJECT DeviceObject,
-  IN UCHAR MinorFunction,  
+  IN UCHAR MinorFunction,
   IN POWER_STATE PowerState,
   IN PREQUEST_POWER_COMPLETE CompletionFunction,
   IN PVOID Context,
-  OUT PIRP *Irp   OPTIONAL)
+  OUT PIRP *pIrp OPTIONAL)
 {
-  return STATUS_NOT_IMPLEMENTED;
+  PDEVICE_OBJECT TopDeviceObject;
+  PIO_STACK_LOCATION Stack;
+  PIRP Irp;
+  PIO_STATUS_BLOCK IoStatusBlock;
+  PREQUEST_POWER_ITEM RequestPowerItem;
+  NTSTATUS Status;
+  
+  if (MinorFunction != IRP_MN_QUERY_POWER
+    && MinorFunction != IRP_MN_SET_POWER
+    && MinorFunction != IRP_MN_WAIT_WAKE)
+    return STATUS_INVALID_PARAMETER_2;
+  
+  RequestPowerItem = ExAllocatePool(NonPagedPool, sizeof(REQUEST_POWER_ITEM));
+  if (!RequestPowerItem)
+    return STATUS_INSUFFICIENT_RESOURCES;
+  IoStatusBlock = ExAllocatePool(NonPagedPool, sizeof(IO_STATUS_BLOCK));
+  if (!IoStatusBlock)
+  {
+    ExFreePool(RequestPowerItem);
+    return STATUS_INSUFFICIENT_RESOURCES;
+  }
+  
+  /* Always call the top of the device stack */
+  TopDeviceObject = IoGetAttachedDeviceReference(DeviceObject);
+  
+  Irp = IoBuildSynchronousFsdRequest(
+    IRP_MJ_PNP,
+    TopDeviceObject,
+    NULL,
+    0,
+    NULL,
+    NULL,
+    IoStatusBlock);
+  if (!Irp)
+  {
+    ExFreePool(RequestPowerItem);
+    ExFreePool(IoStatusBlock);
+    return STATUS_INSUFFICIENT_RESOURCES;
+  }
+  
+  /* POWER IRPs are always initialized with a status code of
+     STATUS_NOT_IMPLEMENTED */
+  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+  Irp->IoStatus.Information = 0;
+  
+  Stack = IoGetNextIrpStackLocation(Irp);
+  Stack->MinorFunction = MinorFunction;
+  if (MinorFunction == IRP_MN_WAIT_WAKE)
+    Stack->Parameters.WaitWake.PowerState = PowerState.SystemState;
+  else
+    Stack->Parameters.WaitWake.PowerState = PowerState.DeviceState;
+  
+  RequestPowerItem->CompletionRoutine = CompletionFunction;
+  RequestPowerItem->PowerState = PowerState;
+  RequestPowerItem->Context = Context;
+  
+  if (pIrp != NULL)
+    *pIrp = Irp;
+  
+  IoSetCompletionRoutine(Irp, PopRequestPowerIrpCompletion, RequestPowerItem, TRUE, TRUE, TRUE);
+  Status = IoCallDriver(TopDeviceObject, Irp);
+  
+  /* Always return STATUS_PENDING. The completion routine
+   * will call CompletionFunction and complete the Irp.
+   */
+  return STATUS_PENDING;
 }
 
 VOID
@@ -90,6 +183,9 @@ PoSetDeviceBusy(
 {
 }
 
+/*
+ * @unimplemented
+ */
 POWER_STATE
 STDCALL
 PoSetPowerState(
@@ -99,12 +195,17 @@ PoSetPowerState(
 {
   POWER_STATE ps;
 
+  ASSERT_IRQL(DISPATCH_LEVEL);
+
   ps.SystemState = PowerSystemWorking;  // Fully on
   ps.DeviceState = PowerDeviceD0;       // Fully on
 
   return ps;
 }
 
+/*
+ * @unimplemented
+ */
 VOID
 STDCALL
 PoSetSystemState(
@@ -112,6 +213,9 @@ PoSetSystemState(
 {
 }
 
+/*
+ * @unimplemented
+ */
 VOID
 STDCALL
 PoStartNextPowerIrp(
@@ -119,6 +223,9 @@ PoStartNextPowerIrp(
 {
 }
 
+/*
+ * @unimplemented
+ */
 VOID
 STDCALL
 PoUnregisterSystemState(
@@ -127,12 +234,10 @@ PoUnregisterSystemState(
 }
 
 NTSTATUS
+NTAPI
 PopSetSystemPowerState(
   SYSTEM_POWER_STATE PowerState)
 {
-
-#ifdef ACPI
-
   IO_STATUS_BLOCK IoStatusBlock;
   PDEVICE_OBJECT DeviceObject;
   PIO_STACK_LOCATION IrpSp;
@@ -141,6 +246,8 @@ PopSetSystemPowerState(
   KEVENT Event;
   PIRP Irp;
 
+  if (!PopAcpiPresent) return STATUS_NOT_IMPLEMENTED;
+
   Status = IopGetSystemPowerDeviceObject(&DeviceObject);
   if (!NT_SUCCESS(Status)) {
     CPRINT("No system power driver available\n");
@@ -186,15 +293,106 @@ PopSetSystemPowerState(
   ObDereferenceObject(Fdo);
 
   return Status;
+}
 
-#endif /* ACPI */
+VOID
+INIT_FUNCTION
+NTAPI
+PoInit(PLOADER_PARAMETER_BLOCK LoaderBlock,
+       BOOLEAN ForceAcpiDisable)
+{
+  if (ForceAcpiDisable)
+    {
+      /* Set the ACPI State to False if it's been forced that way */
+      PopAcpiPresent = FALSE;
+    }
+  else
+    {
+      /* Otherwise check the LoaderBlock's Flag */
+      PopAcpiPresent = (LoaderBlock->Flags & MB_FLAGS_ACPI_TABLE) ? TRUE : FALSE;
+    }
+}
 
-  return STATUS_NOT_IMPLEMENTED;
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+NtInitiatePowerAction (
+       IN POWER_ACTION SystemAction,
+       IN SYSTEM_POWER_STATE MinSystemState,
+       IN ULONG Flags,
+       IN BOOLEAN Asynchronous)
+{
+       UNIMPLEMENTED;
+       return STATUS_NOT_IMPLEMENTED;
 }
 
-VOID
-PoInit(VOID)
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+NtPowerInformation(
+       IN POWER_INFORMATION_LEVEL PowerInformationLevel,
+       IN PVOID InputBuffer  OPTIONAL,
+       IN ULONG InputBufferLength,
+       OUT PVOID OutputBuffer  OPTIONAL,
+       IN ULONG OutputBufferLength
+       )
+{
+   NTSTATUS Status;
+
+   PAGED_CODE();
+
+   DPRINT("NtPowerInformation(PowerInformationLevel 0x%x, InputBuffer 0x%x, "
+          "InputBufferLength 0x%x, OutputBuffer 0x%x, OutputBufferLength 0x%x)\n",
+          PowerInformationLevel,
+          InputBuffer, InputBufferLength,
+          OutputBuffer, OutputBufferLength);
+   switch (PowerInformationLevel)
+   {
+   case SystemBatteryState:
+      {
+      PSYSTEM_BATTERY_STATE BatteryState = (PSYSTEM_BATTERY_STATE)OutputBuffer;
+
+      if (InputBuffer != NULL)
+         return STATUS_INVALID_PARAMETER;
+      if (OutputBufferLength < sizeof(SYSTEM_BATTERY_STATE))
+         return STATUS_BUFFER_TOO_SMALL;
+
+      /* Just zero the struct (and thus set BatteryState->BatteryPresent = FALSE) */
+      RtlZeroMemory(BatteryState, sizeof(SYSTEM_BATTERY_STATE));
+      BatteryState->EstimatedTime = (ULONG)-1;
+
+      Status = STATUS_SUCCESS;
+      break;
+      }
+
+   default:
+      Status = STATUS_NOT_IMPLEMENTED;
+      DPRINT1("PowerInformationLevel 0x%x is UNIMPLEMENTED! Have a nice day.\n",
+              PowerInformationLevel);
+      for (;;);
+      break;
+   }
+
+   return Status;
+}
+
+
+NTSTATUS
+STDCALL
+PoQueueShutdownWorkItem(
+       IN PWORK_QUEUE_ITEM WorkItem
+       )
 {
+  PAGED_CODE();
+
+  DPRINT1("PoQueueShutdownWorkItem(%p)\n", WorkItem);
+
+  return STATUS_NOT_IMPLEMENTED;
 }
 
+
 /* EOF */