ReactOS 0.4.16-dev-1104-ge0ef51b
eval.c File Reference
#include "precomp.h"
#include <debug.h>
Include dependency graph for eval.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define AcpiVerifyInBuffer(Stack, Length)    ((Stack)->Parameters.DeviceIoControl.InputBufferLength >= (Length))
 
#define AcpiVerifyOutBuffer(Stack, Length)    ((Stack)->Parameters.DeviceIoControl.OutputBufferLength >= (Length))
 
#define TAG_ACPI_PARAMETERS_LIST   'OpcA'
 
#define TAG_ACPI_PACKAGE_LIST   'PpcA'
 
#define ACPI_OBJECT_NAME_LENGTH   (4 + 1)
 
#define ACPI_MAX_PACKAGE_DEPTH   5
 

Functions

static NTSTATUS EvalConvertObjectReference (_Out_ PACPI_METHOD_ARGUMENT Argument, _In_ ACPI_OBJECT *Reference)
 Performs translation from the supplied object reference into a string method argument.
 
static NTSTATUS EvalGetElementSize (_In_ ACPI_OBJECT *Obj, _In_ ULONG Depth, _Out_opt_ PULONG Count, _Out_ PULONG Size)
 Calculates the number of bytes needed for returned method argument based on the type of an ACPI_OBJECT structure.
 
static NTSTATUS EvalConvertEvaluationResults (_Out_ ACPI_METHOD_ARGUMENT *Argument, _In_ ULONG Depth, _In_ ACPI_OBJECT *Obj)
 Performs translation from the supplied ACPI_OBJECT structure into a method argument.
 
static ULONG EvalGetPackageCount (_In_ PACPI_METHOD_ARGUMENT Package, _In_ PACPI_METHOD_ARGUMENT PackageArgument, _In_ ULONG DataLength)
 Returns the number of sub-objects (elements) in a package.
 
static NTSTATUS EvalConvertParameterObjects (_Out_ ACPI_OBJECT *Arg, _In_ ULONG Depth, _In_ PACPI_METHOD_ARGUMENT Argument, _In_ PIO_STACK_LOCATION IoStack, _In_ ULONG Offset)
 Performs translation from the supplied method argument into an ACPI_OBJECT structure.
 
static NTSTATUS EvalCreateParametersList (_In_ PIRP Irp, _In_ PIO_STACK_LOCATION IoStack, _In_ PACPI_EVAL_INPUT_BUFFER EvalInputBuffer, _Out_ ACPI_OBJECT_LIST *ParamList)
 Creates a counted array of ACPI_OBJECTs from the given input buffer.
 
static VOID EvalFreeParameterArgument (_In_ ACPI_OBJECT *Arg, _In_ ULONG Depth)
 Deallocates the memory for all sub-objects (elements) in a package.
 
static VOID EvalFreeParametersList (_In_ ACPI_OBJECT_LIST *ParamList)
 Deallocates the given array of ACPI_OBJECTs.
 
static NTSTATUS EvalAcpiStatusToNtStatus (_In_ ACPI_STATUS AcpiStatus)
 Converts the provided value of ACPI_STATUS to NTSTATUS return value.
 
static ACPI_STATUS EvalEvaluateObject (_In_ PPDO_DEVICE_DATA DeviceData, _In_ PACPI_EVAL_INPUT_BUFFER EvalInputBuffer, _In_ ACPI_OBJECT_LIST *ParamList, _In_ ACPI_BUFFER *ReturnBuffer)
 Evaluates an ACPI namespace object.
 
static NTSTATUS EvalCreateOutputArguments (_In_ PIRP Irp, _In_ PIO_STACK_LOCATION IoStack, _In_ ACPI_BUFFER *ReturnBuffer)
 Writes the results from the evaluation into the output IRP buffer.
 
NTSTATUS NTAPI Bus_PDO_EvalMethod (_In_ PPDO_DEVICE_DATA DeviceData, _Inout_ PIRP Irp)
 

Macro Definition Documentation

◆ ACPI_MAX_PACKAGE_DEPTH

#define ACPI_MAX_PACKAGE_DEPTH   5

Maximum number of nested package structures supported by the driver. This should be enough to cover all the existing ACPI methods.

Definition at line 27 of file eval.c.

◆ ACPI_OBJECT_NAME_LENGTH

#define ACPI_OBJECT_NAME_LENGTH   (4 + 1)

Null terminated ACPI name for the object. For example, _DSM, LNKB, etc.

Definition at line 21 of file eval.c.

◆ AcpiVerifyInBuffer

#define AcpiVerifyInBuffer (   Stack,
  Length 
)     ((Stack)->Parameters.DeviceIoControl.InputBufferLength >= (Length))

Definition at line 8 of file eval.c.

◆ AcpiVerifyOutBuffer

#define AcpiVerifyOutBuffer (   Stack,
  Length 
)     ((Stack)->Parameters.DeviceIoControl.OutputBufferLength >= (Length))

Definition at line 11 of file eval.c.

◆ NDEBUG

#define NDEBUG

Definition at line 4 of file eval.c.

◆ TAG_ACPI_PACKAGE_LIST

#define TAG_ACPI_PACKAGE_LIST   'PpcA'

Definition at line 15 of file eval.c.

◆ TAG_ACPI_PARAMETERS_LIST

#define TAG_ACPI_PARAMETERS_LIST   'OpcA'

Definition at line 14 of file eval.c.

Function Documentation

◆ Bus_PDO_EvalMethod()

NTSTATUS NTAPI Bus_PDO_EvalMethod ( _In_ PPDO_DEVICE_DATA  DeviceData,
_Inout_ PIRP  Irp 
)

Definition at line 765 of file eval.c.

768{
769 PIO_STACK_LOCATION IoStack;
770 PACPI_EVAL_INPUT_BUFFER EvalInputBuffer;
771 ACPI_OBJECT_LIST ParamList;
772 ACPI_STATUS AcpiStatus;
774 ACPI_BUFFER ReturnBuffer = { ACPI_ALLOCATE_BUFFER, NULL };
775
777 EvalInputBuffer = Irp->AssociatedIrp.SystemBuffer;
778
779 Status = EvalCreateParametersList(Irp, IoStack, EvalInputBuffer, &ParamList);
780 if (!NT_SUCCESS(Status))
781 return Status;
782
783 AcpiStatus = EvalEvaluateObject(DeviceData, EvalInputBuffer, &ParamList, &ReturnBuffer);
784
785 if (ParamList.Count != 0)
786 EvalFreeParametersList(&ParamList);
787
788 if (!ACPI_SUCCESS(AcpiStatus))
789 {
790 DPRINT("Query method '%.4s' failed on %p with status 0x%04x\n",
791 EvalInputBuffer->MethodName,
792 DeviceData->AcpiHandle,
793 AcpiStatus);
794
795 return EvalAcpiStatusToNtStatus(AcpiStatus);
796 }
797
798 Status = EvalCreateOutputArguments(Irp, IoStack, &ReturnBuffer);
799
800 if (ReturnBuffer.Pointer)
801 AcpiOsFree(ReturnBuffer.Pointer);
802
803 return Status;
804}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define ACPI_SUCCESS(a)
Definition: acexcep.h:94
void AcpiOsFree(void *Memory)
Definition: osl.c:167
#define ACPI_ALLOCATE_BUFFER
Definition: actypes.h:1046
UINT32 ACPI_STATUS
Definition: actypes.h:460
LONG NTSTATUS
Definition: precomp.h:26
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
static NTSTATUS EvalCreateOutputArguments(_In_ PIRP Irp, _In_ PIO_STACK_LOCATION IoStack, _In_ ACPI_BUFFER *ReturnBuffer)
Writes the results from the evaluation into the output IRP buffer.
Definition: eval.c:701
static NTSTATUS EvalCreateParametersList(_In_ PIRP Irp, _In_ PIO_STACK_LOCATION IoStack, _In_ PACPI_EVAL_INPUT_BUFFER EvalInputBuffer, _Out_ ACPI_OBJECT_LIST *ParamList)
Creates a counted array of ACPI_OBJECTs from the given input buffer.
Definition: eval.c:421
static ACPI_STATUS EvalEvaluateObject(_In_ PPDO_DEVICE_DATA DeviceData, _In_ PACPI_EVAL_INPUT_BUFFER EvalInputBuffer, _In_ ACPI_OBJECT_LIST *ParamList, _In_ ACPI_BUFFER *ReturnBuffer)
Evaluates an ACPI namespace object.
Definition: eval.c:682
static VOID EvalFreeParametersList(_In_ ACPI_OBJECT_LIST *ParamList)
Deallocates the given array of ACPI_OBJECTs.
Definition: eval.c:610
static NTSTATUS EvalAcpiStatusToNtStatus(_In_ ACPI_STATUS AcpiStatus)
Converts the provided value of ACPI_STATUS to NTSTATUS return value.
Definition: eval.c:630
Status
Definition: gdiplustypes.h:25
#define DPRINT
Definition: sndvol32.h:73
void * Pointer
Definition: actypes.h:1054

Referenced by ACPIDispatchDeviceControl(), and DrvCallAcpiDriver().

◆ EvalAcpiStatusToNtStatus()

static NTSTATUS EvalAcpiStatusToNtStatus ( _In_ ACPI_STATUS  AcpiStatus)
static

Converts the provided value of ACPI_STATUS to NTSTATUS return value.

Definition at line 630 of file eval.c.

632{
633 if (ACPI_ENV_EXCEPTION(AcpiStatus))
634 {
635 switch (AcpiStatus)
636 {
637 case AE_NOT_FOUND:
638 case AE_NOT_EXIST:
640
641 case AE_NO_MEMORY:
643
644 case AE_SUPPORT:
646
647 case AE_TIME:
648 return STATUS_IO_TIMEOUT;
649
652
655
656 default:
657 goto DefaultStatus;
658 }
659 }
660
661 if (ACPI_AML_EXCEPTION(AcpiStatus))
662 {
663 switch (AcpiStatus)
664 {
667
668 default:
669 goto DefaultStatus;
670 }
671 }
672
673DefaultStatus:
674 return STATUS_UNSUCCESSFUL;
675}
#define AE_SUPPORT
Definition: acexcep.h:123
#define AE_STACK_OVERFLOW
Definition: acexcep.h:120
#define ACPI_AML_EXCEPTION(Status)
Definition: acexcep.h:100
#define ACPI_ENV_EXCEPTION(Status)
Definition: acexcep.h:99
#define AE_NOT_FOUND
Definition: acexcep.h:113
#define AE_AML_UNINITIALIZED_ARG
Definition: acexcep.h:185
#define AE_NO_MEMORY
Definition: acexcep.h:112
#define AE_NOT_EXIST
Definition: acexcep.h:114
#define AE_NO_HARDWARE_RESPONSE
Definition: acexcep.h:130
#define AE_TIME
Definition: acexcep.h:125
#define STATUS_ACPI_STACK_OVERFLOW
Definition: ntstatus.h:1293
#define STATUS_ACPI_INCORRECT_ARGUMENT_COUNT
Definition: ntstatus.h:1302
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149

Referenced by Bus_PDO_EvalMethod().

◆ EvalConvertEvaluationResults()

static NTSTATUS EvalConvertEvaluationResults ( _Out_ ACPI_METHOD_ARGUMENT Argument,
_In_ ULONG  Depth,
_In_ ACPI_OBJECT Obj 
)
static

Performs translation from the supplied ACPI_OBJECT structure into a method argument.

Definition at line 165 of file eval.c.

169{
172
174 {
175 ASSERT(FALSE);
176 return STATUS_UNSUCCESSFUL;
177 }
178
179 Ptr = Argument;
180 switch (Obj->Type)
181 {
183 {
185 break;
186 }
187
188 case ACPI_TYPE_STRING:
189 {
190 ACPI_METHOD_SET_ARGUMENT_STRING(Ptr, Obj->String.Pointer);
191 break;
192 }
193
194 case ACPI_TYPE_BUFFER:
195 {
196 ACPI_METHOD_SET_ARGUMENT_BUFFER(Ptr, Obj->Buffer.Pointer, Obj->Buffer.Length);
197 break;
198 }
199
201 {
202 ULONG i;
203
204 /* Check if we need to wrap the list of elements into a package */
205 if (Depth > 0)
206 {
207 ULONG TotalPackageLength;
208
209 /* Get the size of the current packet */
210 TotalPackageLength = 0;
211 for (i = 0; i < Obj->Package.Count; i++)
212 {
213 ULONG ElementSize;
214
215 Status = EvalGetElementSize(&Obj->Package.Elements[i],
216 Depth + 1,
217 NULL,
218 &ElementSize);
219 if (!NT_SUCCESS(Status))
220 return Status;
221
222 TotalPackageLength += ElementSize;
223 }
224
225 /* Start a new package */
226 Argument->Type = ACPI_METHOD_ARGUMENT_PACKAGE;
227 Argument->DataLength = TotalPackageLength;
228
230 }
231
232 for (i = 0; i < Obj->Package.Count; i++)
233 {
234 Status = EvalConvertEvaluationResults(Ptr, Depth + 1, &Obj->Package.Elements[i]);
235 if (!NT_SUCCESS(Status))
236 return Status;
237
239 }
240 break;
241 }
242
244 {
246 if (!NT_SUCCESS(Status))
247 return Status;
248 break;
249 }
250
251 default:
252 {
253 DPRINT1("Unsupported element type %u\n", Obj->Type);
254 return STATUS_UNSUCCESSFUL;
255 }
256 }
257
258 return STATUS_SUCCESS;
259}
ACPI_METHOD_ARGUMENT UNALIGNED * PACPI_METHOD_ARGUMENT
Definition: acpiioct.h:71
#define ACPI_METHOD_NEXT_ARGUMENT(Argument)
Definition: acpiioct.h:150
#define ACPI_METHOD_SET_ARGUMENT_INTEGER(MethodArgument, IntData)
Definition: acpiioct.h:155
#define ACPI_METHOD_SET_ARGUMENT_STRING(Argument, StrData)
Definition: acpiioct.h:160
#define ACPI_METHOD_SET_ARGUMENT_BUFFER(Argument, BuffData, BuffLength)
Definition: acpiioct.h:165
#define ACPI_METHOD_ARGUMENT_PACKAGE
Definition: acpiioct.h:24
#define ACPI_TYPE_LOCAL_REFERENCE
Definition: actypes.h:719
#define ACPI_TYPE_STRING
Definition: actypes.h:689
#define ACPI_TYPE_BUFFER
Definition: actypes.h:690
#define ACPI_TYPE_INTEGER
Definition: actypes.h:688
#define ACPI_TYPE_PACKAGE
Definition: actypes.h:691
#define DPRINT1
Definition: precomp.h:8
#define FALSE
Definition: types.h:117
static NTSTATUS EvalConvertObjectReference(_Out_ PACPI_METHOD_ARGUMENT Argument, _In_ ACPI_OBJECT *Reference)
Performs translation from the supplied object reference into a string method argument.
Definition: eval.c:35
static NTSTATUS EvalConvertEvaluationResults(_Out_ ACPI_METHOD_ARGUMENT *Argument, _In_ ULONG Depth, _In_ ACPI_OBJECT *Obj)
Performs translation from the supplied ACPI_OBJECT structure into a method argument.
Definition: eval.c:165
static NTSTATUS EvalGetElementSize(_In_ ACPI_OBJECT *Obj, _In_ ULONG Depth, _Out_opt_ PULONG Count, _Out_ PULONG Size)
Calculates the number of bytes needed for returned method argument based on the type of an ACPI_OBJEC...
Definition: eval.c:69
#define ACPI_MAX_PACKAGE_DEPTH
Definition: eval.c:27
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ASSERT(a)
Definition: mode.c:44
#define STATUS_SUCCESS
Definition: shellext.h:65
uint32_t ULONG
Definition: typedefs.h:59
_In_opt_ PALLOCATE_FUNCTION _In_opt_ PFREE_FUNCTION _In_ ULONG _In_ SIZE_T _In_ ULONG _In_ USHORT Depth
Definition: exfuncs.h:819

Referenced by EvalConvertEvaluationResults(), and EvalCreateOutputArguments().

◆ EvalConvertObjectReference()

static NTSTATUS EvalConvertObjectReference ( _Out_ PACPI_METHOD_ARGUMENT  Argument,
_In_ ACPI_OBJECT Reference 
)
static

Performs translation from the supplied object reference into a string method argument.

Definition at line 35 of file eval.c.

38{
39 ACPI_BUFFER OutName;
40 ACPI_STATUS AcpiStatus;
41
42 Argument->Type = ACPI_METHOD_ARGUMENT_STRING;
43 Argument->DataLength = ACPI_OBJECT_NAME_LENGTH;
44
45 /* Convert the object handle to an ACPI name */
47 OutName.Pointer = &Argument->Data[0];
48
49 AcpiStatus = AcpiGetName(Reference->Reference.Handle, ACPI_SINGLE_NAME, &OutName);
50 if (!ACPI_SUCCESS(AcpiStatus))
51 {
52 DPRINT1("AcpiGetName() failed on %p with status 0x%04x\n",
53 Reference->Reference.Handle,
54 AcpiStatus);
55
58 }
59
60 return STATUS_SUCCESS;
61}
#define ACPI_METHOD_ARGUMENT_STRING
Definition: acpiioct.h:22
#define ACPI_SINGLE_NAME
Definition: actypes.h:1063
#define ACPI_OBJECT_NAME_LENGTH
Definition: eval.c:21
ACPI_STATUS AcpiGetName(ACPI_HANDLE Handle, UINT32 NameType, ACPI_BUFFER *Buffer)
Definition: nsxfname.c:173
ACPI_SIZE Length
Definition: actypes.h:1053

Referenced by EvalConvertEvaluationResults().

◆ EvalConvertParameterObjects()

static NTSTATUS EvalConvertParameterObjects ( _Out_ ACPI_OBJECT Arg,
_In_ ULONG  Depth,
_In_ PACPI_METHOD_ARGUMENT  Argument,
_In_ PIO_STACK_LOCATION  IoStack,
_In_ ULONG  Offset 
)
static

Performs translation from the supplied method argument into an ACPI_OBJECT structure.

Definition at line 295 of file eval.c.

301{
302
304 {
305 ASSERT(FALSE);
306 return STATUS_UNSUCCESSFUL;
307 }
308
309 /* Validate that the method argument fits into the buffer */
310 if (Depth > 0)
311 {
313
314 if (!AcpiVerifyInBuffer(IoStack, Offset))
315 {
316 DPRINT1("Argument buffer outside of argument bounds\n");
318 }
319 }
320
321 switch (Argument->Type)
322 {
324 {
325 Arg->Type = ACPI_TYPE_INTEGER;
326 Arg->Integer.Value = (ULONG64)Argument->Argument;
327 break;
328 }
329
331 {
332 /*
333 * FIXME: Add tests and remove this.
334 * We should either default to an empty string, or reject the IOCTL.
335 */
336 ASSERT(Argument->DataLength >= sizeof(UCHAR));
337 if (Argument->DataLength < sizeof(UCHAR))
338 {
340 }
341
342 Arg->Type = ACPI_TYPE_STRING;
343 Arg->String.Pointer = (PCHAR)&Argument->Data[0];
344 Arg->String.Length = Argument->DataLength - sizeof(UCHAR);
345 break;
346 }
347
349 {
350 Arg->Type = ACPI_TYPE_BUFFER;
351 Arg->Buffer.Pointer = &Argument->Data[0];
352 Arg->Buffer.Length = Argument->DataLength;
353 break;
354 }
355
357 {
358 ULONG i, PackageSize;
360 PACPI_METHOD_ARGUMENT PackageArgument;
361
362 Arg->Type = ACPI_TYPE_PACKAGE;
363
364 Arg->Package.Count = EvalGetPackageCount(Argument,
365 (PACPI_METHOD_ARGUMENT)Argument->Data,
366 Argument->DataLength);
367 /* Empty package, nothing more to convert */
368 if (Arg->Package.Count == 0)
369 {
370 Arg->Package.Elements = NULL;
371 break;
372 }
373
374 Status = RtlULongMult(Arg->Package.Count, sizeof(*Arg), &PackageSize);
375 if (!NT_SUCCESS(Status))
376 {
377 DPRINT1("Invalid package count 0x%x\n", Arg->Package.Count);
379 }
380
381 Arg->Package.Elements = ExAllocatePoolUninitialized(NonPagedPool,
382 PackageSize,
384 if (!Arg->Package.Elements)
386
387 PackageArgument = (PACPI_METHOD_ARGUMENT)Argument->Data;
388 for (i = 0; i < Arg->Package.Count; i++)
389 {
390 Status = EvalConvertParameterObjects(&Arg->Package.Elements[i],
391 Depth + 1,
392 PackageArgument,
393 IoStack,
394 Offset);
395 if (!NT_SUCCESS(Status))
396 {
397 ExFreePoolWithTag(Arg->Package.Elements, TAG_ACPI_PACKAGE_LIST);
398 return Status;
399 }
400
401 PackageArgument = ACPI_METHOD_NEXT_ARGUMENT(PackageArgument);
402 }
403 break;
404 }
405
406 default:
407 {
408 DPRINT1("Unknown argument type %u\n", Argument->Type);
409 return STATUS_UNSUCCESSFUL;
410 }
411 }
412
413 return STATUS_SUCCESS;
414}
#define ExAllocatePoolUninitialized
#define ACPI_METHOD_ARGUMENT_INTEGER
Definition: acpiioct.h:21
#define ACPI_METHOD_ARGUMENT_LENGTH_FROM_ARGUMENT(Argument)
Definition: acpiioct.h:147
#define ACPI_METHOD_ARGUMENT_BUFFER
Definition: acpiioct.h:23
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
static NTSTATUS EvalConvertParameterObjects(_Out_ ACPI_OBJECT *Arg, _In_ ULONG Depth, _In_ PACPI_METHOD_ARGUMENT Argument, _In_ PIO_STACK_LOCATION IoStack, _In_ ULONG Offset)
Performs translation from the supplied method argument into an ACPI_OBJECT structure.
Definition: eval.c:295
#define TAG_ACPI_PACKAGE_LIST
Definition: eval.c:15
static ULONG EvalGetPackageCount(_In_ PACPI_METHOD_ARGUMENT Package, _In_ PACPI_METHOD_ARGUMENT PackageArgument, _In_ ULONG DataLength)
Returns the number of sub-objects (elements) in a package.
Definition: eval.c:266
#define AcpiVerifyInBuffer(Stack, Length)
Definition: eval.c:8
#define NonPagedPool
Definition: env_spec_w32.h:307
#define PCHAR
Definition: match.c:90
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define for
Definition: utility.h:88
unsigned __int64 ULONG64
Definition: imports.h:198
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define STATUS_ACPI_INVALID_ARGTYPE
Definition: ntstatus.h:1299
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by EvalConvertParameterObjects(), and EvalCreateParametersList().

◆ EvalCreateOutputArguments()

static NTSTATUS EvalCreateOutputArguments ( _In_ PIRP  Irp,
_In_ PIO_STACK_LOCATION  IoStack,
_In_ ACPI_BUFFER ReturnBuffer 
)
static

Writes the results from the evaluation into the output IRP buffer.

Definition at line 701 of file eval.c.

705{
707 ULONG ExtraParamLength, OutputBufSize;
710 ULONG Count;
711
712 /* If we didn't get anything back then we're done */
713 if (!ReturnBuffer->Pointer || ReturnBuffer->Length == 0)
714 return STATUS_SUCCESS;
715
716 /* No output buffer is provided, we're done */
717 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == 0)
718 return STATUS_SUCCESS;
719
720 if (!AcpiVerifyOutBuffer(IoStack, sizeof(*OutputBuffer)))
721 {
722 DPRINT1("Buffer too small\n");
723
725 }
726
727 Obj = ReturnBuffer->Pointer;
728
729 Status = EvalGetElementSize(Obj, 0, &Count, &ExtraParamLength);
730 if (!NT_SUCCESS(Status))
731 return Status;
732
733 OutputBufSize = FIELD_OFFSET(ACPI_EVAL_OUTPUT_BUFFER, Argument) + ExtraParamLength;
734
735#ifdef UNIT_TEST
736 OutputBuffer = Irp->OutputBuffer;
737#else
738 OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
739#endif
741 OutputBuffer->Length = OutputBufSize;
742 OutputBuffer->Count = Count;
743
744 if (!AcpiVerifyOutBuffer(IoStack, OutputBufSize))
745 {
746 DPRINT("Buffer too small (%lu/%lu)\n",
747 IoStack->Parameters.DeviceIoControl.OutputBufferLength,
748 OutputBufSize);
749
750 Irp->IoStatus.Information = OutputBufSize;
752 }
753
755 if (!NT_SUCCESS(Status))
756 return Status;
757
758 Irp->IoStatus.Information = OutputBufSize;
759 return STATUS_SUCCESS;
760}
#define ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE
Definition: acpiioct.h:11
ACPI_EVAL_OUTPUT_BUFFER UNALIGNED * PACPI_EVAL_OUTPUT_BUFFER
Definition: acpiioct.h:90
#define AcpiVerifyOutBuffer(Stack, Length)
Definition: eval.c:11
int Count
Definition: noreturn.cpp:7
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863

Referenced by Bus_PDO_EvalMethod().

◆ EvalCreateParametersList()

static NTSTATUS EvalCreateParametersList ( _In_ PIRP  Irp,
_In_ PIO_STACK_LOCATION  IoStack,
_In_ PACPI_EVAL_INPUT_BUFFER  EvalInputBuffer,
_Out_ ACPI_OBJECT_LIST ParamList 
)
static

Creates a counted array of ACPI_OBJECTs from the given input buffer.

Definition at line 421 of file eval.c.

426{
427 ACPI_OBJECT* Arg;
428
430 {
431 DPRINT1("Buffer too small\n");
433 }
434
435 switch (EvalInputBuffer->Signature)
436 {
438 {
439 if (!AcpiVerifyInBuffer(IoStack, sizeof(*EvalInputBuffer)))
440 {
441 DPRINT1("Buffer too small\n");
443 }
444
445 ParamList->Count = 0;
446 break;
447 }
448
450 {
452
453 if (!AcpiVerifyInBuffer(IoStack, sizeof(*SimpleInt)))
454 {
455 DPRINT1("Buffer too small\n");
457 }
458
460 if (!Arg)
462
463 ParamList->Count = 1;
464 ParamList->Pointer = Arg;
465
466 SimpleInt = Irp->AssociatedIrp.SystemBuffer;
467
468 Arg->Type = ACPI_TYPE_INTEGER;
469 Arg->Integer.Value = (ULONG64)SimpleInt->IntegerArgument;
470 break;
471 }
472
474 {
476
477 if (!AcpiVerifyInBuffer(IoStack, sizeof(*SimpleStr)))
478 {
479 DPRINT1("Buffer too small\n");
481 }
482
484 if (!Arg)
486
487 ParamList->Count = 1;
488 ParamList->Pointer = Arg;
489
490 SimpleStr = Irp->AssociatedIrp.SystemBuffer;
491
492 Arg->Type = ACPI_TYPE_STRING;
493 Arg->String.Pointer = (PCHAR)SimpleStr->String;
494 Arg->String.Length = SimpleStr->StringLength;
495 break;
496 }
497
499 {
501 PACPI_METHOD_ARGUMENT Argument;
502 ULONG i, Length, Offset, ArgumentsSize;
504
505 if (!AcpiVerifyInBuffer(IoStack, sizeof(*ComplexBuffer)))
506 {
507 DPRINT1("Buffer too small\n");
509 }
510
511 ComplexBuffer = Irp->AssociatedIrp.SystemBuffer;
512
513 ParamList->Count = ComplexBuffer->ArgumentCount;
514 if (ParamList->Count == 0)
515 {
516 DPRINT1("No arguments\n");
518 }
519
520 Status = RtlULongMult(ParamList->Count, sizeof(*Arg), &ArgumentsSize);
521 if (!NT_SUCCESS(Status))
522 {
523 DPRINT1("Invalid argument count 0x%x\n", ParamList->Count);
525 }
526
528 ArgumentsSize,
530 if (!Arg)
532
533 ParamList->Pointer = Arg;
534
535 Argument = ComplexBuffer->Argument;
537
538 for (i = 0; i < ParamList->Count; i++)
539 {
540 Offset = Length;
542
543 if (!AcpiVerifyInBuffer(IoStack, Length))
544 {
545 DPRINT1("Argument buffer outside of argument bounds\n");
546
547 ExFreePoolWithTag(ParamList->Pointer, TAG_ACPI_PARAMETERS_LIST);
549 }
550
551 Status = EvalConvertParameterObjects(Arg, 0, Argument, IoStack, Offset);
552 if (!NT_SUCCESS(Status))
553 {
554 ExFreePoolWithTag(ParamList->Pointer, TAG_ACPI_PARAMETERS_LIST);
555 return Status;
556 }
557
558 Arg++;
559 Argument = ACPI_METHOD_NEXT_ARGUMENT(Argument);
560 }
561
562 break;
563 }
564
565 default:
566 {
567 DPRINT1("Unsupported input buffer signature: 0x%lx\n", EvalInputBuffer->Signature);
569 }
570 }
571
572 return STATUS_SUCCESS;
573}
#define ACPI_EVAL_INPUT_BUFFER_COMPLEX_SIGNATURE
Definition: acpiioct.h:10
#define ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER_SIGNATURE
Definition: acpiioct.h:8
#define ACPI_EVAL_INPUT_BUFFER_SIGNATURE
Definition: acpiioct.h:7
#define ACPI_EVAL_INPUT_BUFFER_SIMPLE_STRING_SIGNATURE
Definition: acpiioct.h:9
static const WCHAR Signature[]
Definition: parser.c:141
#define TAG_ACPI_PARAMETERS_LIST
Definition: eval.c:14
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:680
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:475
ACPI_METHOD_ARGUMENT Argument[ANYSIZE_ARRAY]
Definition: acpiioct.h:81
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
struct acpi_object::@656 Integer
struct acpi_object::@657 String
ACPI_OBJECT_TYPE Type
Definition: actypes.h:970

Referenced by Bus_PDO_EvalMethod().

◆ EvalEvaluateObject()

static ACPI_STATUS EvalEvaluateObject ( _In_ PPDO_DEVICE_DATA  DeviceData,
_In_ PACPI_EVAL_INPUT_BUFFER  EvalInputBuffer,
_In_ ACPI_OBJECT_LIST ParamList,
_In_ ACPI_BUFFER ReturnBuffer 
)
static

Evaluates an ACPI namespace object.

Definition at line 682 of file eval.c.

687{
688 CHAR MethodName[ACPI_OBJECT_NAME_LENGTH];
689
690 RtlCopyMemory(MethodName, EvalInputBuffer->MethodName, ACPI_OBJECT_NAME_LENGTH - 1);
691 MethodName[ACPI_OBJECT_NAME_LENGTH - 1] = ANSI_NULL;
692
693 return AcpiEvaluateObject(DeviceData->AcpiHandle, MethodName, ParamList, ReturnBuffer);
694}
ACPI_STATUS AcpiEvaluateObject(ACPI_HANDLE Handle, ACPI_STRING Pathname, ACPI_OBJECT_LIST *ExternalParams, ACPI_BUFFER *ReturnBuffer)
Definition: nsxfeval.c:217
#define ANSI_NULL
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
char CHAR
Definition: xmlstorage.h:175

Referenced by Bus_PDO_EvalMethod().

◆ EvalFreeParameterArgument()

static VOID EvalFreeParameterArgument ( _In_ ACPI_OBJECT Arg,
_In_ ULONG  Depth 
)
static

Deallocates the memory for all sub-objects (elements) in a package.

Definition at line 580 of file eval.c.

583{
584 ULONG i;
585
587 {
588 ASSERT(FALSE);
589 return;
590 }
591
592 if (Arg->Type == ACPI_TYPE_PACKAGE)
593 {
594 for (i = 0; i < Arg->Package.Count; i++)
595 {
596 EvalFreeParameterArgument(&Arg->Package.Elements[i], Depth + 1);
597 }
598
599 /* Check if the package isn't empty, and free it */
600 if (Arg->Package.Elements)
601 ExFreePoolWithTag(Arg->Package.Elements, TAG_ACPI_PACKAGE_LIST);
602 }
603}
static VOID EvalFreeParameterArgument(_In_ ACPI_OBJECT *Arg, _In_ ULONG Depth)
Deallocates the memory for all sub-objects (elements) in a package.
Definition: eval.c:580

Referenced by EvalFreeParameterArgument(), and EvalFreeParametersList().

◆ EvalFreeParametersList()

static VOID EvalFreeParametersList ( _In_ ACPI_OBJECT_LIST ParamList)
static

Deallocates the given array of ACPI_OBJECTs.

Definition at line 610 of file eval.c.

612{
613 ACPI_OBJECT* Arg;
614 ULONG i;
615
616 Arg = ParamList->Pointer;
617 for (i = 0; i < ParamList->Count; i++)
618 {
620 }
621
622 ExFreePoolWithTag(ParamList->Pointer, TAG_ACPI_PARAMETERS_LIST);
623}
char * Pointer
Definition: actypes.h:981

Referenced by Bus_PDO_EvalMethod().

◆ EvalGetElementSize()

static NTSTATUS EvalGetElementSize ( _In_ ACPI_OBJECT Obj,
_In_ ULONG  Depth,
_Out_opt_ PULONG  Count,
_Out_ PULONG  Size 
)
static

Calculates the number of bytes needed for returned method argument based on the type of an ACPI_OBJECT structure.

Definition at line 69 of file eval.c.

74{
75 ULONG TotalCount, TotalLength;
77
79 {
82 }
83
84 switch (Obj->Type)
85 {
87 {
89 TotalCount = 1;
90 break;
91 }
92
94 {
95 TotalLength = ACPI_METHOD_ARGUMENT_LENGTH(Obj->String.Length + sizeof(UCHAR));
96 TotalCount = 1;
97 break;
98 }
99
100 case ACPI_TYPE_BUFFER:
101 {
103 TotalCount = 1;
104 break;
105 }
106
108 {
109 ULONG i, TotalPackageLength;
110
111 /* Get the size of the current packet */
112 TotalPackageLength = 0;
113 for (i = 0; i < Obj->Package.Count; i++)
114 {
115 ULONG ElementSize;
116
117 Status = EvalGetElementSize(&Obj->Package.Elements[i],
118 Depth + 1,
119 NULL,
120 &ElementSize);
121 if (!NT_SUCCESS(Status))
122 return Status;
123
124 TotalPackageLength += ElementSize;
125 }
126
127 /* Check if we need to wrap the list of elements into a package */
128 if (Depth > 0)
129 {
130 TotalPackageLength = ACPI_METHOD_ARGUMENT_LENGTH(TotalPackageLength);
131 }
132
133 TotalLength = TotalPackageLength;
134 TotalCount = Obj->Package.Count;
135 break;
136 }
137
139 {
141 TotalCount = 1;
142 break;
143 }
144
145 default:
146 {
147 DPRINT1("Unsupported element type %u\n", Obj->Type);
148 return STATUS_UNSUCCESSFUL;
149 }
150 }
151
152 if (Count)
153 *Count = TotalCount;
154
155 *Size = TotalLength;
156
157 return STATUS_SUCCESS;
158}
#define ACPI_METHOD_ARGUMENT_LENGTH(DataLength)
Definition: acpiioct.h:144
_In_ ULONG TotalLength
Definition: usbdlib.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533

Referenced by EvalConvertEvaluationResults(), EvalCreateOutputArguments(), and EvalGetElementSize().

◆ EvalGetPackageCount()

static ULONG EvalGetPackageCount ( _In_ PACPI_METHOD_ARGUMENT  Package,
_In_ PACPI_METHOD_ARGUMENT  PackageArgument,
_In_ ULONG  DataLength 
)
static

Returns the number of sub-objects (elements) in a package.

Definition at line 266 of file eval.c.

270{
272 ULONG TotalLength = 0, TotalCount = 0;
273
274 /* Empty package */
275 if (DataLength < ACPI_METHOD_ARGUMENT_LENGTH(0) || Package->Argument == 0)
276 return 0;
277
278 Ptr = PackageArgument;
279 while (TotalLength < DataLength)
280 {
282 TotalCount++;
283
285 }
286
287 return TotalCount;
288}
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1444

Referenced by EvalConvertParameterObjects().