* Sync up to trunk head (r60691).
[reactos.git] / ntoskrnl / po / power.c
index 85839a9..88df584 100644 (file)
@@ -21,6 +21,7 @@ typedef struct _REQUEST_POWER_ITEM
     PREQUEST_POWER_COMPLETE CompletionRoutine;
     POWER_STATE PowerState;
     PVOID Context;
+    PDEVICE_OBJECT TopDeviceObject;
 } REQUEST_POWER_ITEM, *PREQUEST_POWER_ITEM;
 
 typedef struct _POWER_STATE_TRAVERSE_CONTEXT
@@ -56,10 +57,11 @@ PopRequestPowerIrpCompletion(IN PDEVICE_OBJECT DeviceObject,
                                         RequestPowerItem->Context,
                                         &Irp->IoStatus);
 
-    ExFreePool(Context);
-
     IoFreeIrp(Irp);
 
+    ObDereferenceObject(RequestPowerItem->TopDeviceObject);
+    ExFreePool(Context);
+
     return STATUS_MORE_PROCESSING_REQUIRED;
 }
 
@@ -78,11 +80,11 @@ PopSendQuerySystemPowerState(PDEVICE_OBJECT DeviceObject, SYSTEM_POWER_STATE Sys
     PIO_STACK_LOCATION IrpSp;
     PIRP Irp;
     NTSTATUS Status;
-    
+
     KeInitializeEvent(&Event,
                       NotificationEvent,
                       FALSE);
-    
+
     Irp = IoBuildSynchronousFsdRequest(IRP_MJ_POWER,
                                        DeviceObject,
                                        NULL,
@@ -90,13 +92,14 @@ PopSendQuerySystemPowerState(PDEVICE_OBJECT DeviceObject, SYSTEM_POWER_STATE Sys
                                        NULL,
                                        &Event,
                                        &IoStatusBlock);
-    
+    if (!Irp) return STATUS_INSUFFICIENT_RESOURCES;
+
     IrpSp = IoGetNextIrpStackLocation(Irp);
     IrpSp->MinorFunction = IRP_MN_QUERY_POWER;
     IrpSp->Parameters.Power.Type = SystemPowerState;
     IrpSp->Parameters.Power.State.SystemState = SystemState;
     IrpSp->Parameters.Power.ShutdownType = PowerAction;
-    
+
     Status = PoCallDriver(DeviceObject, Irp);
     if (Status == STATUS_PENDING)
     {
@@ -107,7 +110,7 @@ PopSendQuerySystemPowerState(PDEVICE_OBJECT DeviceObject, SYSTEM_POWER_STATE Sys
                               NULL);
         Status = IoStatusBlock.Status;
     }
-    
+
     return Status;
 }
 
@@ -119,11 +122,11 @@ PopSendSetSystemPowerState(PDEVICE_OBJECT DeviceObject, SYSTEM_POWER_STATE Syste
     PIO_STACK_LOCATION IrpSp;
     PIRP Irp;
     NTSTATUS Status;
-    
+
     KeInitializeEvent(&Event,
                       NotificationEvent,
                       FALSE);
-    
+
     Irp = IoBuildSynchronousFsdRequest(IRP_MJ_POWER,
                                        DeviceObject,
                                        NULL,
@@ -131,13 +134,14 @@ PopSendSetSystemPowerState(PDEVICE_OBJECT DeviceObject, SYSTEM_POWER_STATE Syste
                                        NULL,
                                        &Event,
                                        &IoStatusBlock);
-    
+    if (!Irp) return STATUS_INSUFFICIENT_RESOURCES;
+
     IrpSp = IoGetNextIrpStackLocation(Irp);
     IrpSp->MinorFunction = IRP_MN_SET_POWER;
     IrpSp->Parameters.Power.Type = SystemPowerState;
     IrpSp->Parameters.Power.State.SystemState = SystemState;
     IrpSp->Parameters.Power.ShutdownType = PowerAction;
-    
+
     Status = PoCallDriver(DeviceObject, Irp);
     if (Status == STATUS_PENDING)
     {
@@ -148,7 +152,7 @@ PopSendSetSystemPowerState(PDEVICE_OBJECT DeviceObject, SYSTEM_POWER_STATE Syste
                               NULL);
         Status = IoStatusBlock.Status;
     }
-    
+
     return Status;
 }
 
@@ -226,7 +230,7 @@ PopSetSystemPowerState(SYSTEM_POWER_STATE PowerState, POWER_ACTION PowerAction)
     POWER_STATE_TRAVERSE_CONTEXT PowerContext;
     
     Status = IopGetSystemPowerDeviceObject(&DeviceObject);
-    if (!NT_SUCCESS(Status)) 
+    if (!NT_SUCCESS(Status))
     {
         DPRINT1("No system power driver available\n");
         Fdo = NULL;
@@ -547,6 +551,7 @@ PoRequestPowerIrp(IN PDEVICE_OBJECT DeviceObject,
                                         NULL);
     if (!Irp)
     {
+        ObDereferenceObject(TopDeviceObject);
         ExFreePool(RequestPowerItem);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
@@ -569,6 +574,7 @@ PoRequestPowerIrp(IN PDEVICE_OBJECT DeviceObject,
     RequestPowerItem->CompletionRoutine = CompletionFunction;
     RequestPowerItem->PowerState = PowerState;
     RequestPowerItem->Context = Context;
+    RequestPowerItem->TopDeviceObject = TopDeviceObject;
   
     if (pIrp != NULL)
         *pIrp = Irp;
@@ -673,8 +679,8 @@ NtPowerInformation(IN POWER_INFORMATION_LEVEL PowerInformationLevel,
 
     PAGED_CODE();
 
-    DPRINT("NtPowerInformation(PowerInformationLevel 0x%x, InputBuffer 0x%x, "
-           "InputBufferLength 0x%x, OutputBuffer 0x%x, OutputBufferLength 0x%x)\n",
+    DPRINT("NtPowerInformation(PowerInformationLevel 0x%x, InputBuffer 0x%p, "
+           "InputBufferLength 0x%x, OutputBuffer 0x%p, OutputBufferLength 0x%x)\n",
            PowerInformationLevel,
            InputBuffer, InputBufferLength,
            OutputBuffer, OutputBufferLength);
@@ -787,7 +793,7 @@ NtSetThreadExecutionState(IN EXECUTION_STATE esFlags,
     PreviousState = Thread->PowerState | ES_CONTINUOUS;
 
     /* Check if we need to update the power state */
-    if (esFlags & ES_CONTINUOUS) Thread->PowerState = esFlags;
+    if (esFlags & ES_CONTINUOUS) Thread->PowerState = (UCHAR)esFlags;
 
     /* Protect the write back to user mode */
     _SEH2_TRY
@@ -822,12 +828,12 @@ NtSetSystemPowerState(IN POWER_ACTION SystemAction,
         (MinSystemState <= PowerSystemUnspecified) ||
         (SystemAction > PowerActionWarmEject) ||
         (SystemAction < PowerActionReserved) ||
-        (Flags & ~(POWER_ACTION_QUERY_ALLOWED  |  
-                   POWER_ACTION_UI_ALLOWED     | 
-                   POWER_ACTION_OVERRIDE_APPS  | 
-                   POWER_ACTION_LIGHTEST_FIRST | 
-                   POWER_ACTION_LOCK_CONSOLE   | 
-                   POWER_ACTION_DISABLE_WAKES  | 
+        (Flags & ~(POWER_ACTION_QUERY_ALLOWED  |
+                   POWER_ACTION_UI_ALLOWED     |
+                   POWER_ACTION_OVERRIDE_APPS  |
+                   POWER_ACTION_LIGHTEST_FIRST |
+                   POWER_ACTION_LOCK_CONSOLE   |
+                   POWER_ACTION_DISABLE_WAKES  |
                    POWER_ACTION_CRITICAL)))
     {
         DPRINT1("NtSetSystemPowerState: Bad parameters!\n");
@@ -902,13 +908,13 @@ NtSetSystemPowerState(IN POWER_ACTION SystemAction,
         
 #ifndef NEWCC
         /* Flush dirty cache pages */
-        CcRosFlushDirtyPages(-1, &Dummy);
+        CcRosFlushDirtyPages(-1, &Dummy, FALSE); //HACK: We really should wait here!
 #else
         Dummy = 0;
 #endif
 
         /* Flush all volumes and the registry */
-        DPRINT1("Flushing volumes, cache flushed %d pages\n", Dummy);
+        DPRINT1("Flushing volumes, cache flushed %lu pages\n", Dummy);
         PopFlushVolumes(PopAction.Shutdown);
 
         /* Set IRP for drivers */