- Silence TCPIP.
[reactos.git] / reactos / ntoskrnl / po / power.c
index 2dc711b..d3f8322 100644 (file)
@@ -1,17 +1,30 @@
 /* $Id$
- * 
+ *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/po/power.c
  * PURPOSE:         Power Manager
- * 
+ *
  * PROGRAMMERS:     Casper S. Hornstrup (chorns@users.sourceforge.net)
+ *                  HervĂ© Poussineau (hpoussin@reactos.com)
  */
 
 #include <ntoskrnl.h>
 #define NDEBUG
 #include <internal/debug.h>
 
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, PoInit)
+#endif
+
+
+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;
 
@@ -57,20 +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;
+}
+
 /*
- * @unimplemented
+ * @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
@@ -91,7 +194,7 @@ PoSetPowerState(
   IN POWER_STATE State)
 {
   POWER_STATE ps;
-  
+
   ASSERT_IRQL(DISPATCH_LEVEL);
 
   ps.SystemState = PowerSystemWorking;  // Fully on
@@ -131,9 +234,10 @@ PoUnregisterSystemState(
 }
 
 NTSTATUS
+NTAPI
 PopSetSystemPowerState(
   SYSTEM_POWER_STATE PowerState)
-{    
+{
   IO_STATUS_BLOCK IoStatusBlock;
   PDEVICE_OBJECT DeviceObject;
   PIO_STACK_LOCATION IrpSp;
@@ -141,7 +245,7 @@ PopSetSystemPowerState(
   NTSTATUS Status;
   KEVENT Event;
   PIRP Irp;
-  
+
   if (!PopAcpiPresent) return STATUS_NOT_IMPLEMENTED;
 
   Status = IopGetSystemPowerDeviceObject(&DeviceObject);
@@ -191,9 +295,10 @@ PopSetSystemPowerState(
   return Status;
 }
 
-VOID 
+VOID
 INIT_FUNCTION
-PoInit(PLOADER_PARAMETER_BLOCK LoaderBlock, 
+NTAPI
+PoInit(PLOADER_PARAMETER_BLOCK LoaderBlock,
        BOOLEAN ForceAcpiDisable)
 {
   if (ForceAcpiDisable)
@@ -226,8 +331,8 @@ NtInitiatePowerAction (
 /*
  * @unimplemented
  */
-NTSTATUS 
-STDCALL 
+NTSTATUS
+STDCALL
 NtPowerInformation(
        IN POWER_INFORMATION_LEVEL PowerInformationLevel,
        IN PVOID InputBuffer  OPTIONAL,
@@ -237,7 +342,7 @@ NtPowerInformation(
        )
 {
    NTSTATUS Status;
-   
+
    PAGED_CODE();
 
    DPRINT("NtPowerInformation(PowerInformationLevel 0x%x, InputBuffer 0x%x, "
@@ -283,7 +388,7 @@ PoQueueShutdownWorkItem(
        )
 {
   PAGED_CODE();
-  
+
   DPRINT1("PoQueueShutdownWorkItem(%p)\n", WorkItem);
 
   return STATUS_NOT_IMPLEMENTED;