[CMBATT]: Implement ACPI package extraction routines, and CmBattSendDownStreamIrp to send ACPI IOCTLs.

svn path=/trunk/; revision=46374
This commit is contained in:
Sir Richard 2010-03-23 23:33:58 +00:00
parent d94632570f
commit 5bf71f83d8

View file

@ -9,25 +9,73 @@
/* INCLUDES *******************************************************************/
#include "cmbatt.h"
#include "ntstatus.h"
/* FUNCTIONS ******************************************************************/
NTSTATUS
NTAPI
GetDwordElement(PACPI_METHOD_ARGUMENT Argument,
PULONG Value)
GetDwordElement(IN PACPI_METHOD_ARGUMENT Argument,
OUT PULONG Value)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
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(PACPI_METHOD_ARGUMENT Argument,
PCHAR Value)
GetStringElement(IN PACPI_METHOD_ARGUMENT Argument,
OUT PCHAR Value)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
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 @@ CmBattSetTripPpoint(PCMBATT_DEVICE_EXTENSION DeviceExtension,
NTSTATUS
NTAPI
CmBattSendDownStreamIrp(PDEVICE_OBJECT DeviceObject,
ULONG IoControlCode,
PVOID InputBuffer,
ULONG InputBufferLength,
PACPI_EVAL_OUTPUT_BUFFER OutputBuffer,
ULONG OutputBufferLength)
CmBattSendDownStreamIrp(IN PDEVICE_OBJECT DeviceObject,
IN ULONG IoControlCode,
IN PVOID InputBuffer,
IN ULONG InputBufferLength,
IN PACPI_EVAL_OUTPUT_BUFFER OutputBuffer,
IN ULONG OutputBufferLength)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
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 */