/* GLOBALS *******************************************************************/
-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
{
SYSTEM_POWER_STATE SystemPowerState;
IN PVOID Context)
{
PIO_STACK_LOCATION Stack;
- PREQUEST_POWER_ITEM RequestPowerItem;
+ PREQUEST_POWER_COMPLETE CompletionRoutine;
+ POWER_STATE PowerState;
- Stack = IoGetNextIrpStackLocation(Irp);
- RequestPowerItem = (PREQUEST_POWER_ITEM)Context;
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+ CompletionRoutine = Context;
- RequestPowerItem->CompletionRoutine(DeviceObject,
- Stack->MinorFunction,
- RequestPowerItem->PowerState,
- RequestPowerItem->Context,
- &Irp->IoStatus);
+ PowerState.DeviceState = (ULONG_PTR)Stack->Parameters.Others.Argument3;
+ CompletionRoutine(Stack->Parameters.Others.Argument1,
+ (UCHAR)(ULONG_PTR)Stack->Parameters.Others.Argument2,
+ PowerState,
+ Stack->Parameters.Others.Argument4,
+ &Irp->IoStatus);
+ IoSkipCurrentIrpStackLocation(Irp);
IoFreeIrp(Irp);
-
- ObDereferenceObject(RequestPowerItem->TopDeviceObject);
- ExFreePool(Context);
+ ObDereferenceObject(DeviceObject);
return STATUS_MORE_PROCESSING_REQUIRED;
}
PVOID Context)
{
PPOWER_STATE_TRAVERSE_CONTEXT PowerStateContext = Context;
+ PDEVICE_OBJECT TopDeviceObject;
NTSTATUS Status;
DPRINT("PopQuerySystemPowerStateTraverse(%p, %p)\n", DeviceNode, Context);
if (DeviceNode->Flags & DNF_LEGACY_DRIVER)
return STATUS_SUCCESS;
- Status = PopSendQuerySystemPowerState(DeviceNode->PhysicalDeviceObject,
+ TopDeviceObject = IoGetAttachedDeviceReference(DeviceNode->PhysicalDeviceObject);
+
+ Status = PopSendQuerySystemPowerState(TopDeviceObject,
PowerStateContext->SystemPowerState,
PowerStateContext->PowerAction);
if (!NT_SUCCESS(Status))
{
DPRINT1("Device '%wZ' failed IRP_MN_QUERY_POWER\n", &DeviceNode->InstancePath);
}
+ ObDereferenceObject(TopDeviceObject);
#if 0
return Status;
PVOID Context)
{
PPOWER_STATE_TRAVERSE_CONTEXT PowerStateContext = Context;
+ PDEVICE_OBJECT TopDeviceObject;
NTSTATUS Status;
DPRINT("PopSetSystemPowerStateTraverse(%p, %p)\n", DeviceNode, Context);
if (DeviceNode->Flags & DNF_LEGACY_DRIVER)
return STATUS_SUCCESS;
- Status = PopSendSetSystemPowerState(DeviceNode->PhysicalDeviceObject,
+ TopDeviceObject = IoGetAttachedDeviceReference(DeviceNode->PhysicalDeviceObject);
+ if (TopDeviceObject == PowerStateContext->PowerDevice)
+ {
+ ObDereferenceObject(TopDeviceObject);
+ return STATUS_SUCCESS;
+ }
+
+ Status = PopSendSetSystemPowerState(TopDeviceObject,
PowerStateContext->SystemPowerState,
PowerStateContext->PowerAction);
if (!NT_SUCCESS(Status))
DPRINT1("Device '%wZ' failed IRP_MN_SET_POWER\n", &DeviceNode->InstancePath);
}
+ ObDereferenceObject(TopDeviceObject);
+
#if 0
return Status;
#else
PDEVICE_OBJECT TopDeviceObject;
PIO_STACK_LOCATION Stack;
PIRP Irp;
- PREQUEST_POWER_ITEM RequestPowerItem;
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;
-
/* Always call the top of the device stack */
TopDeviceObject = IoGetAttachedDeviceReference(DeviceObject);
- Irp = IoBuildAsynchronousFsdRequest(IRP_MJ_POWER,
- TopDeviceObject,
- NULL,
- 0,
- NULL,
- NULL);
+ Irp = IoAllocateIrp(TopDeviceObject->StackSize + 2, FALSE);
if (!Irp)
{
ObDereferenceObject(TopDeviceObject);
- ExFreePool(RequestPowerItem);
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.Status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Information = 0;
+ IoSetNextIrpStackLocation(Irp);
+
Stack = IoGetNextIrpStackLocation(Irp);
+ Stack->Parameters.Others.Argument1 = DeviceObject;
+ Stack->Parameters.Others.Argument2 = (PVOID)(ULONG_PTR)MinorFunction;
+ Stack->Parameters.Others.Argument3 = (PVOID)(ULONG_PTR)PowerState.DeviceState;
+ Stack->Parameters.Others.Argument4 = Context;
+ Stack->DeviceObject = TopDeviceObject;
+ IoSetNextIrpStackLocation(Irp);
+
+ Stack = IoGetNextIrpStackLocation(Irp);
+ Stack->MajorFunction = IRP_MJ_POWER;
Stack->MinorFunction = MinorFunction;
if (MinorFunction == IRP_MN_WAIT_WAKE)
+ {
Stack->Parameters.WaitWake.PowerState = PowerState.SystemState;
+ }
else
{
Stack->Parameters.Power.Type = DevicePowerState;
Stack->Parameters.Power.State = PowerState;
}
- RequestPowerItem->CompletionRoutine = CompletionFunction;
- RequestPowerItem->PowerState = PowerState;
- RequestPowerItem->Context = Context;
- RequestPowerItem->TopDeviceObject = TopDeviceObject;
-
if (pIrp != NULL)
*pIrp = Irp;
- IoSetCompletionRoutine(Irp, PopRequestPowerIrpCompletion, RequestPowerItem, TRUE, TRUE, TRUE);
+ IoSetCompletionRoutine(Irp, PopRequestPowerIrpCompletion, CompletionFunction, TRUE, TRUE, TRUE);
PoCallDriver(TopDeviceObject, Irp);
/* Always return STATUS_PENDING. The completion routine
*/
NTSTATUS
NTAPI
-NtInitiatePowerAction (IN POWER_ACTION SystemAction,
- IN SYSTEM_POWER_STATE MinSystemState,
- IN ULONG Flags,
- IN BOOLEAN Asynchronous)
+NtInitiatePowerAction(IN POWER_ACTION SystemAction,
+ IN SYSTEM_POWER_STATE MinSystemState,
+ IN ULONG Flags,
+ IN BOOLEAN Asynchronous)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
IN ULONG OutputBufferLength)
{
NTSTATUS Status;
+ KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
PAGED_CODE();
InputBuffer, InputBufferLength,
OutputBuffer, OutputBufferLength);
+ if (PreviousMode != KernelMode)
+ {
+ _SEH2_TRY
+ {
+ ProbeForRead(InputBuffer, InputBufferLength, 1);
+ ProbeForWrite(OutputBuffer, OutputBufferLength, sizeof(ULONG));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+ }
+
switch (PowerInformationLevel)
{
case SystemBatteryState:
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 = MAXULONG;
+ _SEH2_TRY
+ {
+ /* Just zero the struct (and thus set BatteryState->BatteryPresent = FALSE) */
+ RtlZeroMemory(BatteryState, sizeof(SYSTEM_BATTERY_STATE));
+ BatteryState->EstimatedTime = MAXULONG;
+
+ Status = STATUS_SUCCESS;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
- Status = STATUS_SUCCESS;
break;
}
if (OutputBufferLength < sizeof(SYSTEM_POWER_CAPABILITIES))
return STATUS_BUFFER_TOO_SMALL;
- /* Just zero the struct (and thus set BatteryState->BatteryPresent = FALSE) */
- RtlZeroMemory(PowerCapabilities, sizeof(SYSTEM_POWER_CAPABILITIES));
- //PowerCapabilities->SystemBatteriesPresent = 0;
+ _SEH2_TRY
+ {
+ /* Just zero the struct (and thus set PowerCapabilities->SystemBatteriesPresent = FALSE) */
+ RtlZeroMemory(PowerCapabilities, sizeof(SYSTEM_POWER_CAPABILITIES));
+ //PowerCapabilities->SystemBatteriesPresent = 0;
+
+ Status = STATUS_SUCCESS;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ break;
+ }
+
+ case ProcessorInformation:
+ {
+ PPROCESSOR_POWER_INFORMATION PowerInformation = (PPROCESSOR_POWER_INFORMATION)OutputBuffer;
+
+ if (InputBuffer != NULL)
+ return STATUS_INVALID_PARAMETER;
+ if (OutputBufferLength < sizeof(PROCESSOR_POWER_INFORMATION))
+ return STATUS_BUFFER_TOO_SMALL;
+
+ _SEH2_TRY
+ {
+ PowerInformation->Number = 0;
+ PowerInformation->MaxMhz = 1000;
+ PowerInformation->CurrentMhz = 1000;
+ PowerInformation->MhzLimit = 1000;
+ PowerInformation->MaxIdleState = 0;
+ PowerInformation->CurrentIdleState = 0;
+
+ Status = STATUS_SUCCESS;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
- Status = STATUS_SUCCESS;
break;
}
}
/* You should not have made it this far */
- ASSERTMSG("System is still up and running?!", FALSE);
+ // ASSERTMSG("System is still up and running?!", FALSE);
+ DPRINT1("System is still up and running, you may not have chosen a yet supported power option: %u\n", PopAction.Action);
break;
}