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/cm…
==============================================================================
--- 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 */