Author: sir_richard Date: Wed Mar 24 00:33:58 2010 New Revision: 46374
URL: http://svn.reactos.org/svn/reactos?rev=46374&view=rev Log: [CMBATT]: Implement ACPI package extraction routines, and CmBattSendDownStreamIrp to send ACPI IOCTLs.
Modified: trunk/reactos/drivers/bus/acpi/cmbatt/cmexec.c
Modified: trunk/reactos/drivers/bus/acpi/cmbatt/cmexec.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/acpi/cmbatt/cme... ============================================================================== --- trunk/reactos/drivers/bus/acpi/cmbatt/cmexec.c [iso-8859-1] (original) +++ trunk/reactos/drivers/bus/acpi/cmbatt/cmexec.c [iso-8859-1] Wed Mar 24 00:33:58 2010 @@ -9,25 +9,73 @@ /* INCLUDES *******************************************************************/
#include "cmbatt.h" +#include "ntstatus.h"
/* FUNCTIONS ******************************************************************/
NTSTATUS NTAPI -GetDwordElement(PACPI_METHOD_ARGUMENT Argument, - PULONG Value) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -NTAPI -GetStringElement(PACPI_METHOD_ARGUMENT Argument, - PCHAR Value) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; +GetDwordElement(IN PACPI_METHOD_ARGUMENT Argument, + OUT PULONG Value) +{ + NTSTATUS Status; + + /* Must have an integer */ + if (Argument->Type != ACPI_METHOD_ARGUMENT_INTEGER) + { + /* Not an integer, fail */ + Status = STATUS_ACPI_INVALID_DATA; + if (CmBattDebug & 0x4C) + DbgPrint("GetDwordElement: Object contained wrong data type - %d\n", + Argument->Type); + } + else + { + /* Read the integer value */ + *Value = Argument->Argument; + Status = STATUS_SUCCESS; + } + + /* Return status */ + return Status; +} + +NTSTATUS +NTAPI +GetStringElement(IN PACPI_METHOD_ARGUMENT Argument, + OUT PCHAR Value) +{ + NTSTATUS Status; + + /* Must have a string of buffer */ + if ((Argument->Type == ACPI_METHOD_ARGUMENT_STRING) || + (Argument->Type == ACPI_METHOD_ARGUMENT_BUFFER)) + { + /* String must be less than 256 characters */ + if (Argument->DataLength < 256) + { + /* Copy the buffer */ + RtlCopyMemory(Value, Argument->Data, Argument->DataLength); + Status = STATUS_SUCCESS; + } + else + { + /* The buffer is too small (the string is too large) */ + Status = STATUS_BUFFER_TOO_SMALL; + if (CmBattDebug & 0x4C) + DbgPrint("GetStringElement: return buffer not big enough - %d\n", Argument->DataLength); + } + } + else + { + /* Not valid string data */ + Status = STATUS_ACPI_INVALID_DATA; + if (CmBattDebug & 0x4C) + DbgPrint("GetStringElement: Object contained wrong data type - %d\n", Argument->Type); + } + + /* Return the status */ + return Status; }
NTSTATUS @@ -86,15 +134,72 @@
NTSTATUS NTAPI -CmBattSendDownStreamIrp(PDEVICE_OBJECT DeviceObject, - ULONG IoControlCode, - PVOID InputBuffer, - ULONG InputBufferLength, - PACPI_EVAL_OUTPUT_BUFFER OutputBuffer, - ULONG OutputBufferLength) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; +CmBattSendDownStreamIrp(IN PDEVICE_OBJECT DeviceObject, + IN ULONG IoControlCode, + IN PVOID InputBuffer, + IN ULONG InputBufferLength, + IN PACPI_EVAL_OUTPUT_BUFFER OutputBuffer, + IN ULONG OutputBufferLength) +{ + PIRP Irp; + NTSTATUS Status; + KEVENT Event; + IO_STATUS_BLOCK IoStatusBlock; + PAGED_CODE(); + + /* Initialize our wait event */ + KeInitializeEvent(&Event, SynchronizationEvent, 0); + + /* Allocate the IRP */ + Irp = IoBuildDeviceIoControlRequest(IoControlCode, + DeviceObject, + InputBuffer, + InputBufferLength, + OutputBuffer, + OutputBufferLength, + 0, + &Event, + &IoStatusBlock); + if (!Irp) + { + /* No IRP, fail */ + if (CmBattDebug & 0x4C) + DbgPrint("CmBattSendDownStreamIrp: Failed to allocate Irp\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Call ACPI */ + if (CmBattDebug & 0x40) + DbgPrint("CmBattSendDownStreamIrp: Irp %x [Tid] %x\n", Irp, KeGetCurrentThread()); + Status = IoCallDriver(DeviceObject, Irp); + if (Status == STATUS_PENDING) + { + /* Wait for completion */ + KeWaitForSingleObject(&Event, + Executive, + KernelMode, + FALSE, + NULL); + Status = Irp->IoStatus.Status; + } + + /* Check if caller wanted output */ + if (OutputBuffer) + { + /* Make sure it's valid ACPI output buffer */ + if ((OutputBuffer->Signature != ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE) || + !(OutputBuffer->Count)) + { + /* It isn't, so set failure code */ + Status = STATUS_ACPI_INVALID_DATA; + } + } + + /* Return status */ + if (CmBattDebug & 0x40) + DbgPrint("CmBattSendDownStreamIrp: Irp %x completed %x! [Tid] %x\n", + Irp, Status, KeGetCurrentThread()); + return Status; }
/* EOF */