ReactOS 0.4.15-dev-7924-g5949c20
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)
 
VOID NTAPI Bus_PDO_EvalMethodWorker (_In_ PVOID Parameter)
 

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 796 of file eval.c.

799{
800 PIO_STACK_LOCATION IoStack;
801 PACPI_EVAL_INPUT_BUFFER EvalInputBuffer;
802 ACPI_OBJECT_LIST ParamList;
803 ACPI_STATUS AcpiStatus;
805 ACPI_BUFFER ReturnBuffer = { ACPI_ALLOCATE_BUFFER, NULL };
806
807 PAGED_CODE();
808
810 EvalInputBuffer = Irp->AssociatedIrp.SystemBuffer;
811
812 Status = EvalCreateParametersList(Irp, IoStack, EvalInputBuffer, &ParamList);
813 if (!NT_SUCCESS(Status))
814 return Status;
815
816 AcpiStatus = EvalEvaluateObject(DeviceData, EvalInputBuffer, &ParamList, &ReturnBuffer);
817
818 if (ParamList.Count != 0)
819 EvalFreeParametersList(&ParamList);
820
821 if (!ACPI_SUCCESS(AcpiStatus))
822 {
823 DPRINT("Query method '%.4s' failed on %p with status 0x%04lx\n",
824 EvalInputBuffer->MethodName,
825 DeviceData->AcpiHandle,
826 AcpiStatus);
827
828 return EvalAcpiStatusToNtStatus(AcpiStatus);
829 }
830
831 Status = EvalCreateOutputArguments(Irp, IoStack, &ReturnBuffer);
832
833 if (ReturnBuffer.Pointer)
834 AcpiOsFree(ReturnBuffer.Pointer);
835
836 return Status;
837}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
#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:32
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:730
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:436
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:708
static VOID EvalFreeParametersList(_In_ ACPI_OBJECT_LIST *ParamList)
Deallocates the given array of ACPI_OBJECTs.
Definition: eval.c:631
static NTSTATUS EvalAcpiStatusToNtStatus(_In_ ACPI_STATUS AcpiStatus)
Converts the provided value of ACPI_STATUS to NTSTATUS return value.
Definition: eval.c:654
Status
Definition: gdiplustypes.h:25
#define DPRINT
Definition: sndvol32.h:71
void * Pointer
Definition: actypes.h:1054

Referenced by ACPIDispatchDeviceControl(), Bus_PDO_EvalMethodWorker(), and DrvCallAcpiDriver().

◆ Bus_PDO_EvalMethodWorker()

VOID NTAPI Bus_PDO_EvalMethodWorker ( _In_ PVOID  Parameter)

Definition at line 843 of file eval.c.

845{
846 PEVAL_WORKITEM_DATA WorkItemData = Parameter;
848 PIRP Irp;
849
850 PAGED_CODE();
851
852 Irp = WorkItemData->Irp;
853
854 Status = Bus_PDO_EvalMethod(WorkItemData->DeviceData, Irp);
855
856 ExFreePoolWithTag(WorkItemData, 'ipcA');
857
858 Irp->IoStatus.Status = Status;
860}
NTSTATUS NTAPI Bus_PDO_EvalMethod(_In_ PPDO_DEVICE_DATA DeviceData, _Inout_ PIRP Irp)
Definition: eval.c:796
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define IoCompleteRequest
Definition: irp.c:1240
PPDO_DEVICE_DATA DeviceData
Definition: acpisys.h:78
#define IO_NO_INCREMENT
Definition: iotypes.h:598
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323

◆ EvalAcpiStatusToNtStatus()

static NTSTATUS EvalAcpiStatusToNtStatus ( _In_ ACPI_STATUS  AcpiStatus)
static

Converts the provided value of ACPI_STATUS to NTSTATUS return value.

Definition at line 654 of file eval.c.

656{
657 PAGED_CODE();
658
659 if (ACPI_ENV_EXCEPTION(AcpiStatus))
660 {
661 switch (AcpiStatus)
662 {
663 case AE_NOT_FOUND:
664 case AE_NOT_EXIST:
666
667 case AE_NO_MEMORY:
669
670 case AE_SUPPORT:
672
673 case AE_TIME:
674 return STATUS_IO_TIMEOUT;
675
678
681
682 default:
683 break;
684 }
685 }
686
687 if (ACPI_AML_EXCEPTION(AcpiStatus))
688 {
689 switch (AcpiStatus)
690 {
693
694 default:
695 break;
696 }
697 }
698
699 return STATUS_UNSUCCESSFUL;
700}
#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 172 of file eval.c.

176{
179
180 PAGED_CODE();
181
183 {
184 ASSERT(FALSE);
185 return STATUS_UNSUCCESSFUL;
186 }
187
188 Ptr = Argument;
189 switch (Obj->Type)
190 {
192 {
194 break;
195 }
196
197 case ACPI_TYPE_STRING:
198 {
199 ACPI_METHOD_SET_ARGUMENT_STRING(Ptr, Obj->String.Pointer);
200 break;
201 }
202
203 case ACPI_TYPE_BUFFER:
204 {
205 ACPI_METHOD_SET_ARGUMENT_BUFFER(Ptr, Obj->Buffer.Pointer, Obj->Buffer.Length);
206 break;
207 }
208
210 {
211 ULONG i;
212
213 /* Check if we need to wrap the list of elements into a package */
214 if (Depth > 0)
215 {
216 ULONG TotalPackageLength;
217
218 /* Get the size of the current packet */
219 TotalPackageLength = 0;
220 for (i = 0; i < Obj->Package.Count; i++)
221 {
222 ULONG ElementSize;
223
224 Status = EvalGetElementSize(&Obj->Package.Elements[i],
225 Depth + 1,
226 NULL,
227 &ElementSize);
228 if (!NT_SUCCESS(Status))
229 return Status;
230
231 TotalPackageLength += ElementSize;
232 }
233
234 /* Start a new package */
235 Argument->Type = ACPI_METHOD_ARGUMENT_PACKAGE;
236 Argument->DataLength = TotalPackageLength;
237
239 }
240
241 for (i = 0; i < Obj->Package.Count; i++)
242 {
243 Status = EvalConvertEvaluationResults(Ptr, Depth + 1, &Obj->Package.Elements[i]);
244 if (!NT_SUCCESS(Status))
245 return Status;
246
248 }
249 break;
250 }
251
253 {
255 if (!NT_SUCCESS(Status))
256 return Status;
257 break;
258 }
259
260 default:
261 {
262 DPRINT1("Unsupported element type %lu\n", Obj->Type);
263 return STATUS_UNSUCCESSFUL;
264 }
265 }
266
267 return STATUS_SUCCESS;
268}
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:36
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:172
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:73
#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 36 of file eval.c.

39{
40 ACPI_BUFFER OutName;
41 ACPI_STATUS AcpiStatus;
42
43 PAGED_CODE();
44
45 Argument->Type = ACPI_METHOD_ARGUMENT_STRING;
46 Argument->DataLength = ACPI_OBJECT_NAME_LENGTH;
47
48 /* Convert the object handle to an ACPI name */
50 OutName.Pointer = &Argument->Data[0];
51
52 AcpiStatus = AcpiGetName(Reference->Reference.Handle, ACPI_SINGLE_NAME, &OutName);
53 if (!ACPI_SUCCESS(AcpiStatus))
54 {
55 DPRINT1("AcpiGetName() failed on %p with status 0x%04lx\n",
56 Reference->Reference.Handle,
57 AcpiStatus);
58
61 }
62
63 return STATUS_SUCCESS;
64}
#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 308 of file eval.c.

314{
315 PAGED_CODE();
316
318 {
319 ASSERT(FALSE);
320 return STATUS_UNSUCCESSFUL;
321 }
322
323 /* Validate that the method argument fits into the buffer */
324 if (Depth > 0)
325 {
327
328 if (!AcpiVerifyInBuffer(IoStack, Offset))
329 {
330 DPRINT1("Argument buffer outside of argument bounds\n");
332 }
333 }
334
335 switch (Argument->Type)
336 {
338 {
339 Arg->Type = ACPI_TYPE_INTEGER;
340 Arg->Integer.Value = (ULONG64)Argument->Argument;
341 break;
342 }
343
345 {
346 /*
347 * FIXME: Add tests and remove this.
348 * We should either default to an empty string, or reject the IOCTL.
349 */
350 ASSERT(Argument->DataLength >= sizeof(UCHAR));
351 if (Argument->DataLength < sizeof(UCHAR))
352 {
354 }
355
356 Arg->Type = ACPI_TYPE_STRING;
357 Arg->String.Pointer = (PCHAR)&Argument->Data[0];
358 Arg->String.Length = Argument->DataLength - sizeof(UCHAR);
359 break;
360 }
361
363 {
364 Arg->Type = ACPI_TYPE_BUFFER;
365 Arg->Buffer.Pointer = &Argument->Data[0];
366 Arg->Buffer.Length = Argument->DataLength;
367 break;
368 }
369
371 {
372 ULONG i, PackageSize;
374 PACPI_METHOD_ARGUMENT PackageArgument;
375
376 Arg->Type = ACPI_TYPE_PACKAGE;
377
378 Arg->Package.Count = EvalGetPackageCount(Argument,
379 (PACPI_METHOD_ARGUMENT)Argument->Data,
380 Argument->DataLength);
381 /* Empty package, nothing more to convert */
382 if (Arg->Package.Count == 0)
383 {
384 Arg->Package.Elements = NULL;
385 break;
386 }
387
388 Status = RtlULongMult(Arg->Package.Count, sizeof(*Arg), &PackageSize);
389 if (!NT_SUCCESS(Status))
390 {
391 DPRINT1("Invalid package count 0x%lx\n", Arg->Package.Count);
393 }
394
395 Arg->Package.Elements = ExAllocatePoolUninitialized(NonPagedPool,
396 PackageSize,
398 if (!Arg->Package.Elements)
400
401 PackageArgument = (PACPI_METHOD_ARGUMENT)Argument->Data;
402 for (i = 0; i < Arg->Package.Count; i++)
403 {
404 Status = EvalConvertParameterObjects(&Arg->Package.Elements[i],
405 Depth + 1,
406 PackageArgument,
407 IoStack,
408 Offset);
409 if (!NT_SUCCESS(Status))
410 {
411 ExFreePoolWithTag(Arg->Package.Elements, TAG_ACPI_PACKAGE_LIST);
412 return Status;
413 }
414
415 PackageArgument = ACPI_METHOD_NEXT_ARGUMENT(PackageArgument);
416 }
417 break;
418 }
419
420 default:
421 {
422 DPRINT1("Unknown argument type %u\n", Argument->Type);
423 return STATUS_UNSUCCESSFUL;
424 }
425 }
426
427 return STATUS_SUCCESS;
428}
#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
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:308
#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:276
#define AcpiVerifyInBuffer(Stack, Length)
Definition: eval.c:8
#define NonPagedPool
Definition: env_spec_w32.h:307
#define PCHAR
Definition: match.c:90
#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
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
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 730 of file eval.c.

734{
736 ULONG ExtraParamLength, OutputBufSize;
739 ULONG Count;
740
741 PAGED_CODE();
742
743 /* If we didn't get anything back then we're done */
744 if (!ReturnBuffer->Pointer || ReturnBuffer->Length == 0)
745 return STATUS_SUCCESS;
746
747 /* No output buffer is provided, we're done */
748 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == 0)
749 return STATUS_SUCCESS;
750
751 if (!AcpiVerifyOutBuffer(IoStack, sizeof(*OutputBuffer)))
752 {
753 DPRINT1("Buffer too small\n");
754
756 }
757
758 Obj = ReturnBuffer->Pointer;
759
760 Status = EvalGetElementSize(Obj, 0, &Count, &ExtraParamLength);
761 if (!NT_SUCCESS(Status))
762 return Status;
763
764 OutputBufSize = FIELD_OFFSET(ACPI_EVAL_OUTPUT_BUFFER, Argument) + ExtraParamLength;
765
766#ifdef UNIT_TEST
767 OutputBuffer = Irp->OutputBuffer;
768#else
769 OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
770#endif
772 OutputBuffer->Length = OutputBufSize;
773 OutputBuffer->Count = Count;
774
775 if (!AcpiVerifyOutBuffer(IoStack, OutputBufSize))
776 {
777 DPRINT("Buffer too small (%lu/%lu)\n",
778 IoStack->Parameters.DeviceIoControl.OutputBufferLength,
779 OutputBufSize);
780
781 Irp->IoStatus.Information = OutputBufSize;
783 }
784
786 if (!NT_SUCCESS(Status))
787 return Status;
788
789 Irp->IoStatus.Information = OutputBufSize;
790 return STATUS_SUCCESS;
791}
#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 436 of file eval.c.

441{
442 ACPI_OBJECT* Arg;
443
444 PAGED_CODE();
445
447 {
448 DPRINT1("Buffer too small\n");
450 }
451
452 switch (EvalInputBuffer->Signature)
453 {
455 {
456 if (!AcpiVerifyInBuffer(IoStack, sizeof(*EvalInputBuffer)))
457 {
458 DPRINT1("Buffer too small\n");
460 }
461
462 ParamList->Count = 0;
463 break;
464 }
465
467 {
469
470 if (!AcpiVerifyInBuffer(IoStack, sizeof(*SimpleInt)))
471 {
472 DPRINT1("Buffer too small\n");
474 }
475
477 if (!Arg)
479
480 ParamList->Count = 1;
481 ParamList->Pointer = Arg;
482
483 SimpleInt = Irp->AssociatedIrp.SystemBuffer;
484
485 Arg->Type = ACPI_TYPE_INTEGER;
486 Arg->Integer.Value = (ULONG64)SimpleInt->IntegerArgument;
487 break;
488 }
489
491 {
493
494 if (!AcpiVerifyInBuffer(IoStack, sizeof(*SimpleStr)))
495 {
496 DPRINT1("Buffer too small\n");
498 }
499
501 if (!Arg)
503
504 ParamList->Count = 1;
505 ParamList->Pointer = Arg;
506
507 SimpleStr = Irp->AssociatedIrp.SystemBuffer;
508
509 Arg->Type = ACPI_TYPE_STRING;
510 Arg->String.Pointer = (PCHAR)SimpleStr->String;
511 Arg->String.Length = SimpleStr->StringLength;
512 break;
513 }
514
516 {
518 PACPI_METHOD_ARGUMENT Argument;
519 ULONG i, Length, Offset, ArgumentsSize;
521
522 if (!AcpiVerifyInBuffer(IoStack, sizeof(*ComplexBuffer)))
523 {
524 DPRINT1("Buffer too small\n");
526 }
527
528 ComplexBuffer = Irp->AssociatedIrp.SystemBuffer;
529
530 ParamList->Count = ComplexBuffer->ArgumentCount;
531 if (ParamList->Count == 0)
532 {
533 DPRINT1("No arguments\n");
535 }
536
537 Status = RtlULongMult(ParamList->Count, sizeof(*Arg), &ArgumentsSize);
538 if (!NT_SUCCESS(Status))
539 {
540 DPRINT1("Invalid argument count 0x%lx\n", ParamList->Count);
542 }
543
545 ArgumentsSize,
547 if (!Arg)
549
550 ParamList->Pointer = Arg;
551
552 Argument = ComplexBuffer->Argument;
554
555 for (i = 0; i < ParamList->Count; i++)
556 {
557 Offset = Length;
559
560 if (!AcpiVerifyInBuffer(IoStack, Length))
561 {
562 DPRINT1("Argument buffer outside of argument bounds\n");
563
564 ExFreePoolWithTag(ParamList->Pointer, TAG_ACPI_PARAMETERS_LIST);
566 }
567
568 Status = EvalConvertParameterObjects(Arg, 0, Argument, IoStack, Offset);
569 if (!NT_SUCCESS(Status))
570 {
571 ExFreePoolWithTag(ParamList->Pointer, TAG_ACPI_PARAMETERS_LIST);
572 return Status;
573 }
574
575 Arg++;
576 Argument = ACPI_METHOD_NEXT_ARGUMENT(Argument);
577 }
578
579 break;
580 }
581
582 default:
583 {
584 DPRINT1("Unsupported input buffer signature: 0x%lx\n", EvalInputBuffer->Signature);
586 }
587 }
588
589 return STATUS_SUCCESS;
590}
#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:672
_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::@615 String
ACPI_OBJECT_TYPE Type
Definition: actypes.h:970
struct acpi_object::@614 Integer

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 708 of file eval.c.

713{
714 CHAR MethodName[ACPI_OBJECT_NAME_LENGTH];
715
716 PAGED_CODE();
717
718 RtlCopyMemory(MethodName, EvalInputBuffer->MethodName, ACPI_OBJECT_NAME_LENGTH);
719 MethodName[ACPI_OBJECT_NAME_LENGTH - 1] = ANSI_NULL;
720
721 return AcpiEvaluateObject(DeviceData->AcpiHandle, MethodName, ParamList, ReturnBuffer);
722}
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 598 of file eval.c.

601{
602 ULONG i;
603
604 PAGED_CODE();
605
607 {
608 ASSERT(FALSE);
609 return;
610 }
611
612 if (Arg->Type == ACPI_TYPE_PACKAGE)
613 {
614 for (i = 0; i < Arg->Package.Count; i++)
615 {
616 EvalFreeParameterArgument(&Arg->Package.Elements[i], Depth + 1);
617 }
618
619 /* Check if the package isn't empty, and free it */
620 if (Arg->Package.Elements)
621 ExFreePoolWithTag(Arg->Package.Elements, TAG_ACPI_PACKAGE_LIST);
622 }
623}
static VOID EvalFreeParameterArgument(_In_ ACPI_OBJECT *Arg, _In_ ULONG Depth)
Deallocates the memory for all sub-objects (elements) in a package.
Definition: eval.c:598

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 631 of file eval.c.

633{
634 ACPI_OBJECT* Arg;
635 ULONG i;
636
637 PAGED_CODE();
638
639 Arg = ParamList->Pointer;
640 for (i = 0; i < ParamList->Count; i++)
641 {
643 }
644
645 ExFreePoolWithTag(ParamList->Pointer, TAG_ACPI_PARAMETERS_LIST);
646}
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 73 of file eval.c.

78{
79 ULONG TotalCount, TotalLength;
81
82 PAGED_CODE();
83
85 {
88 }
89
90 switch (Obj->Type)
91 {
93 {
95 TotalCount = 1;
96 break;
97 }
98
100 {
101 TotalLength = ACPI_METHOD_ARGUMENT_LENGTH(Obj->String.Length + sizeof(UCHAR));
102 TotalCount = 1;
103 break;
104 }
105
106 case ACPI_TYPE_BUFFER:
107 {
109 TotalCount = 1;
110 break;
111 }
112
114 {
115 ULONG i, TotalPackageLength;
116
117 /* Get the size of the current packet */
118 TotalPackageLength = 0;
119 for (i = 0; i < Obj->Package.Count; i++)
120 {
121 ULONG ElementSize;
122
123 Status = EvalGetElementSize(&Obj->Package.Elements[i],
124 Depth + 1,
125 NULL,
126 &ElementSize);
127 if (!NT_SUCCESS(Status))
128 return Status;
129
130 TotalPackageLength += ElementSize;
131 }
132
133 /* Check if we need to wrap the list of elements into a package */
134 if (Depth > 0)
135 {
136 TotalPackageLength = ACPI_METHOD_ARGUMENT_LENGTH(TotalPackageLength);
137 }
138
139 TotalLength = TotalPackageLength;
140 TotalCount = Obj->Package.Count;
141 break;
142 }
143
145 {
147 TotalCount = 1;
148 break;
149 }
150
151 default:
152 {
153 DPRINT1("Unsupported element type %lu\n", Obj->Type);
154 return STATUS_UNSUCCESSFUL;
155 }
156 }
157
158 if (Count)
159 *Count = TotalCount;
160
161 *Size = TotalLength;
162
163 return STATUS_SUCCESS;
164}
#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 276 of file eval.c.

280{
282 ULONG TotalLength = 0, TotalCount = 0;
283
284 PAGED_CODE();
285
286 /* Empty package */
287 if (DataLength < ACPI_METHOD_ARGUMENT_LENGTH(0) || Package->Argument == 0)
288 return 0;
289
290 Ptr = PackageArgument;
291 while (TotalLength < DataLength)
292 {
294 TotalCount++;
295
297 }
298
299 return TotalCount;
300}
_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().