mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +00:00
5070e8960a
CORE-17256 - Implement support for complex input buffers. This will enable the IDE driver with some hack to execute the _STM (channel timing settings) control method. - Fix a memory leak. - Fix returned status code. - Correctly calculate the output buffer size. - Improve buffer validation. - Implement support for async control requests. - Implement local reference conversion. - Implement support for subpackage argument conversion. - Place some code into INIT section.
1349 lines
46 KiB
C
1349 lines
46 KiB
C
/*
|
|
* PROJECT: ReactOS API Tests
|
|
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
|
* PURPOSE: Unit Tests for acpi!Bus_PDO_EvalMethod (IOCTL_ACPI_EVAL_METHOD handler)
|
|
* COPYRIGHT: Copyright 2024 Dmitry Borisov (di.sean@protonmail.com)
|
|
*/
|
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
#include <apitest.h>
|
|
|
|
#define WIN32_NO_STATUS
|
|
#include <ndk/rtlfuncs.h>
|
|
|
|
#define UNIT_TEST
|
|
#include <acpi.h>
|
|
|
|
#include <acpiioct.h>
|
|
#include <ntintsafe.h>
|
|
#include <initguid.h>
|
|
|
|
/* TEST DEFINITIONS ***********************************************************/
|
|
|
|
#define ok_eq_str_ex(entry, value, expected) \
|
|
ok(!strcmp(value, expected), \
|
|
"Line %lu: " #value " = \"%s\", expected \"%s\"\n", (entry)->Line, value, expected)
|
|
|
|
#define ok_eq_print_ex(entry, value, expected, spec) \
|
|
ok((value) == (expected), \
|
|
"Line %lu: " #value " = " spec ", expected " spec "\n", (entry)->Line, value, expected)
|
|
|
|
#define ok_not_print_ex(entry, value, expected, spec) \
|
|
ok((value) != (expected), \
|
|
"Line %lu: " #value " = " spec ", expected " spec "\n", (entry)->Line, value, expected)
|
|
|
|
#define ok_eq_hex_ex(entry, value, expected) ok_eq_print_ex(entry, value, expected, "0x%08lx")
|
|
#define ok_eq_pointer_ex(entry, value, expected) ok_eq_print_ex(entry, value, expected, "%p")
|
|
#define ok_eq_int_ex(entry, value, expected) ok_eq_print_ex(entry, value, expected, "%d")
|
|
#define ok_eq_uint_ex(entry, value, expected) ok_eq_print_ex(entry, value, expected, "%u")
|
|
#define ok_eq_ulong_ex(entry, value, expected) ok_eq_print_ex(entry, value, expected, "%lu")
|
|
#define ok_eq_ulonglong_ex(entry, value, expected) ok_eq_print_ex(entry, value, expected, "%I64u")
|
|
|
|
#define ok_not_pointer_ex(entry, value, expected) ok_not_print_ex(entry, value, expected, "%p")
|
|
|
|
typedef struct _EVAL_TEST_ENTRY
|
|
{
|
|
ULONG Line;
|
|
|
|
ULONG Flags;
|
|
#define STM_TEST_FLAG_INVALID_ARG_3_1 (1 << 0 )
|
|
#define STM_TEST_FLAG_INVALID_ARG_3_2 (1 << 1 )
|
|
#define STM_TEST_FLAG_INVALID_ARG_3_4 (1 << 2 )
|
|
#define STM_TEST_FLAG_INVALID_ARG_3_5 (1 << 3 )
|
|
#define STM_TEST_FLAG_INVALID_SIZE_1 (1 << 4 )
|
|
#define STM_TEST_FLAG_LARGE_ARG_BUFFER (1 << 5 )
|
|
#define STM_TEST_FLAG_CHANGE_ARG_COUNT (1 << 6 )
|
|
#define STM_TEST_FLAG_SUB_IN_BUFFER (1 << 7 )
|
|
#define STM_TEST_FLAG_SUB_IRP_BUFFER (1 << 8 )
|
|
#define STM_TEST_FLAG_SET_IN_BUFFER (1 << 9 )
|
|
#define STM_TEST_FLAG_SET_IRP_BUFFER (1 << 10)
|
|
#define STM_TEST_FLAG_BAD_ARG_TYPE (1 << 11)
|
|
|
|
#define GTM_TEST_FLAG_BAD_SIGNARUTE (1 << 0)
|
|
#define GTM_TEST_FLAG_BUFFER_HAS_SIGNARUTE (1 << 1)
|
|
#define GTM_TEST_FLAG_BUFFER_HAS_COUNT (1 << 2)
|
|
#define GTM_TEST_FLAG_BUFFER_HAS_LENGTH (1 << 3)
|
|
#define GTM_TEST_FLAG_ARG_HAS_BUFFER_TYPE (1 << 4)
|
|
#define GTM_TEST_FLAG_ARG_HAS_DATA_LENGTH (1 << 5)
|
|
#define GTM_TEST_FLAG_INC_OUT_BUFFER (1 << 6)
|
|
#define GTM_TEST_FLAG_DEC_OUT_BUFFER (1 << 7)
|
|
#define GTM_TEST_FLAG_SET_OUT_BUFFER (1 << 8)
|
|
|
|
#define GTM_TEST_FLAG_METHOD_SUCCESS \
|
|
(GTM_TEST_FLAG_BUFFER_HAS_SIGNARUTE | \
|
|
GTM_TEST_FLAG_BUFFER_HAS_COUNT | GTM_TEST_FLAG_BUFFER_HAS_LENGTH | \
|
|
GTM_TEST_FLAG_ARG_HAS_BUFFER_TYPE | GTM_TEST_FLAG_ARG_HAS_DATA_LENGTH)
|
|
|
|
#define DSM_TEST_FLAG_EMPTY_PACKAGE (1 << 0)
|
|
#define DSM_TEST_FLAG_LARGE_SUB_PACKAGE_BUFFER (1 << 1)
|
|
|
|
NTSTATUS Status;
|
|
ULONG Value;
|
|
} EVAL_TEST_ENTRY;
|
|
|
|
/* KERNEL DEFINITIONS (MOCK) **************************************************/
|
|
|
|
#define PAGED_CODE()
|
|
#define CODE_SEG(...)
|
|
#define DPRINT(...) do { if (0) DbgPrint(__VA_ARGS__); } while (0)
|
|
#define DPRINT1(...) do { if (0) DbgPrint(__VA_ARGS__); } while (0)
|
|
|
|
typedef struct _IO_STACK_LOCATION
|
|
{
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
ULONG OutputBufferLength;
|
|
ULONG InputBufferLength;
|
|
} DeviceIoControl;
|
|
} Parameters;
|
|
} IO_STACK_LOCATION, *PIO_STACK_LOCATION;
|
|
|
|
typedef struct _IRP
|
|
{
|
|
union
|
|
{
|
|
PVOID SystemBuffer;
|
|
} AssociatedIrp;
|
|
IO_STATUS_BLOCK IoStatus;
|
|
|
|
PVOID OutputBuffer;
|
|
IO_STACK_LOCATION MyStack;
|
|
} IRP, *PIRP;
|
|
|
|
static LONG DrvpBlocksAllocated = 0;
|
|
|
|
#define ExAllocatePoolUninitialized ExAllocatePoolWithTag
|
|
#define NonPagedPool 1
|
|
static
|
|
PVOID
|
|
ExAllocatePoolWithTag(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
|
|
{
|
|
PULONG_PTR Mem;
|
|
|
|
Mem = HeapAlloc(GetProcessHeap(), 0, NumberOfBytes + 2 * sizeof(PVOID));
|
|
Mem[0] = NumberOfBytes;
|
|
Mem[1] = Tag;
|
|
|
|
++DrvpBlocksAllocated;
|
|
|
|
return (PVOID)(Mem + 2);
|
|
}
|
|
|
|
static
|
|
VOID
|
|
ExFreePoolWithTag(PVOID MemPtr, ULONG Tag)
|
|
{
|
|
PULONG_PTR Mem = MemPtr;
|
|
|
|
Mem -= 2;
|
|
ok(Mem[1] == Tag, "Tag is %lx, expected %lx\n", Tag, Mem[1]);
|
|
HeapFree(GetProcessHeap(), 0, Mem);
|
|
|
|
--DrvpBlocksAllocated;
|
|
}
|
|
|
|
static
|
|
PIO_STACK_LOCATION
|
|
IoGetCurrentIrpStackLocation(PIRP Irp)
|
|
{
|
|
return &Irp->MyStack;
|
|
}
|
|
|
|
/* ACPI DEFINITIONS ***********************************************************/
|
|
|
|
#include <pshpack1.h>
|
|
typedef struct _IDE_ACPI_TIMING_MODE_BLOCK
|
|
{
|
|
struct
|
|
{
|
|
ULONG PioSpeed;
|
|
ULONG DmaSpeed;
|
|
} Drive[2];
|
|
|
|
ULONG ModeFlags;
|
|
} IDE_ACPI_TIMING_MODE_BLOCK, *PIDE_ACPI_TIMING_MODE_BLOCK;
|
|
#include <poppack.h>
|
|
|
|
#define STM_ID_BLOCK_SIZE 512
|
|
|
|
/* ACPI DEFINITIONS (MOCK) ****************************************************/
|
|
|
|
#define FAKE_SB_NAMESPACE_ACPI_HANDLE 0xFF0F0001
|
|
#define FAKE_INTB_ACPI_HANDLE 0xFF0F0002
|
|
#define FAKE_INTC_ACPI_HANDLE 0xFF0F0003
|
|
|
|
typedef struct _PDO_DEVICE_DATA
|
|
{
|
|
HANDLE AcpiHandle;
|
|
} PDO_DEVICE_DATA, *PPDO_DEVICE_DATA;
|
|
|
|
typedef struct _GTM_OBJECT_BUFFER
|
|
{
|
|
ACPI_OBJECT Obj;
|
|
IDE_ACPI_TIMING_MODE_BLOCK TimingMode;
|
|
} GTM_OBJECT_BUFFER, *PGTM_OBJECT_BUFFER;
|
|
|
|
typedef struct _BIF_OBJECT_BUFFER
|
|
{
|
|
ACPI_OBJECT Obj;
|
|
ACPI_OBJECT BatteryInformation[13];
|
|
CHAR Buffer1[1 + 1];
|
|
CHAR Buffer2[1 + 1];
|
|
CHAR Buffer3[4 + 1];
|
|
CHAR Buffer4[7 + 1];
|
|
} BIF_OBJECT_BUFFER, *PBIF_OBJECT_BUFFER;
|
|
|
|
typedef struct _PCL_OBJECT_BUFFER
|
|
{
|
|
ACPI_OBJECT Obj;
|
|
} PCL_OBJECT_BUFFER, *PPCL_OBJECT_BUFFER;
|
|
|
|
typedef struct _PRT_OBJECT_BUFFER
|
|
{
|
|
ACPI_OBJECT Obj;
|
|
ACPI_OBJECT PackageContainer[2];
|
|
ACPI_OBJECT Package1[4];
|
|
ACPI_OBJECT Package2[4];
|
|
} PRT_OBJECT_BUFFER, *PPRT_OBJECT_BUFFER;
|
|
|
|
DEFINE_GUID(MY_DSM_GUID,
|
|
0xB76E0B40, 0x3EC6, 0x4DBD, 0x8A, 0xCB, 0x8B, 0xCA, 0x65, 0xB8, 0xBC, 0x70);
|
|
|
|
static const ULONG DrvpBifIntegerFields[9] =
|
|
{
|
|
0, 50000, 50000, 1, 10000, 100, 50, 1, 1
|
|
};
|
|
|
|
static const ULONG DrvpMyDsmIntegerFields[3] =
|
|
{
|
|
0xAAAAAAAA, 0xBBBBBBBB, 0xDDDDDDDD
|
|
};
|
|
|
|
static const EVAL_TEST_ENTRY* DrvpEvalTestEntry;
|
|
|
|
void *
|
|
AcpiOsAllocate (
|
|
ACPI_SIZE Size)
|
|
{
|
|
return ExAllocatePoolWithTag(NonPagedPool, Size, 'FFUB');
|
|
}
|
|
|
|
void
|
|
AcpiOsFree (
|
|
void * Memory)
|
|
{
|
|
ExFreePoolWithTag(Memory, 'FFUB');
|
|
}
|
|
|
|
ACPI_STATUS
|
|
AcpiGetName (
|
|
ACPI_HANDLE Handle,
|
|
UINT32 NameType,
|
|
ACPI_BUFFER *Buffer)
|
|
{
|
|
/* We don't support anything else */
|
|
ok(NameType == ACPI_SINGLE_NAME, "Unexpected call to %s\n", __FUNCTION__);
|
|
|
|
/* Return a NULL-terminated string */
|
|
if (Buffer->Length < (4 + 1))
|
|
return AE_BUFFER_OVERFLOW;
|
|
|
|
switch ((ULONG_PTR)Handle)
|
|
{
|
|
case FAKE_SB_NAMESPACE_ACPI_HANDLE:
|
|
RtlCopyMemory(Buffer->Pointer, "_SB_", sizeof("_SB_"));
|
|
break;
|
|
|
|
case FAKE_INTB_ACPI_HANDLE:
|
|
RtlCopyMemory(Buffer->Pointer, "LNKB", sizeof("LNKB"));
|
|
break;
|
|
|
|
case FAKE_INTC_ACPI_HANDLE:
|
|
RtlCopyMemory(Buffer->Pointer, "LNKC", sizeof("LNKC"));
|
|
break;
|
|
|
|
default:
|
|
return AE_BAD_PARAMETER;
|
|
}
|
|
|
|
return AE_OK;
|
|
}
|
|
|
|
ACPI_STATUS
|
|
AcpiEvaluateObject (
|
|
ACPI_HANDLE Object,
|
|
ACPI_STRING Pathname,
|
|
ACPI_OBJECT_LIST *ParameterObjects,
|
|
ACPI_BUFFER *ReturnObjectBuffer)
|
|
{
|
|
UNREFERENCED_PARAMETER(Object);
|
|
|
|
/* We don't support anything else */
|
|
ok(ReturnObjectBuffer->Length == ACPI_ALLOCATE_BUFFER,
|
|
"Unexpected call to %s\n", __FUNCTION__);
|
|
|
|
if (strcmp(Pathname, "_STM") == 0)
|
|
{
|
|
ACPI_OBJECT* Arg;
|
|
PIDE_ACPI_TIMING_MODE_BLOCK TimingMode;
|
|
|
|
if (ParameterObjects->Count > 3)
|
|
return AE_AML_UNINITIALIZED_ARG;
|
|
|
|
if (ParameterObjects->Count != 3)
|
|
return AE_OK;
|
|
|
|
/* Argument 1 */
|
|
{
|
|
Arg = ParameterObjects->Pointer;
|
|
|
|
ok_eq_uint_ex(DrvpEvalTestEntry, Arg->Type, ACPI_TYPE_BUFFER);
|
|
ok_eq_uint_ex(DrvpEvalTestEntry, Arg->Buffer.Length, sizeof(*TimingMode));
|
|
|
|
TimingMode = (PIDE_ACPI_TIMING_MODE_BLOCK)Arg->Buffer.Pointer;
|
|
|
|
ok_eq_ulong_ex(DrvpEvalTestEntry, TimingMode->Drive[0].PioSpeed, 508LU);
|
|
ok_eq_ulong_ex(DrvpEvalTestEntry, TimingMode->Drive[0].DmaSpeed, 120LU);
|
|
ok_eq_ulong_ex(DrvpEvalTestEntry, TimingMode->Drive[1].PioSpeed, 240LU);
|
|
ok_eq_ulong_ex(DrvpEvalTestEntry, TimingMode->Drive[1].DmaSpeed, 180LU);
|
|
ok_eq_hex_ex(DrvpEvalTestEntry, TimingMode->ModeFlags, 0x10LU);
|
|
}
|
|
/* Argument 2 */
|
|
{
|
|
++Arg;
|
|
|
|
ok_eq_uint_ex(DrvpEvalTestEntry, Arg->Type, ACPI_TYPE_BUFFER);
|
|
ok_eq_uint_ex(DrvpEvalTestEntry, Arg->Buffer.Length, STM_ID_BLOCK_SIZE);
|
|
}
|
|
/* Argument 3 */
|
|
{
|
|
++Arg;
|
|
|
|
ok_eq_uint_ex(DrvpEvalTestEntry, Arg->Type, ACPI_TYPE_BUFFER);
|
|
ok_eq_uint_ex(DrvpEvalTestEntry, Arg->Buffer.Length, STM_ID_BLOCK_SIZE);
|
|
}
|
|
|
|
return AE_OK;
|
|
}
|
|
else if (strcmp(Pathname, "_GTM") == 0)
|
|
{
|
|
PGTM_OBJECT_BUFFER ReturnObject;
|
|
PIDE_ACPI_TIMING_MODE_BLOCK TimingMode;
|
|
|
|
ReturnObject = AcpiOsAllocate(sizeof(*ReturnObject));
|
|
if (!ReturnObject)
|
|
return AE_NO_MEMORY;
|
|
|
|
/*
|
|
* VPC 2007 output
|
|
* AcpiGetHandle(NULL, "\\_SB.PCI0.IDE0.CHN1", &ObjHandle);
|
|
* AcpiEvaluateObject(ObjHandle, "_GTM", NULL, &ReturnObj);
|
|
*/
|
|
TimingMode = &ReturnObject->TimingMode;
|
|
TimingMode->Drive[0].PioSpeed = 900;
|
|
TimingMode->Drive[0].DmaSpeed = 900;
|
|
TimingMode->Drive[1].PioSpeed = 120;
|
|
TimingMode->Drive[1].DmaSpeed = 120;
|
|
TimingMode->ModeFlags = 0x12;
|
|
|
|
ReturnObject->Obj.Type = ACPI_TYPE_BUFFER;
|
|
ReturnObject->Obj.Buffer.Length = sizeof(*TimingMode);
|
|
ReturnObject->Obj.Buffer.Pointer = (PUCHAR)TimingMode;
|
|
|
|
ReturnObjectBuffer->Pointer = ReturnObject;
|
|
ReturnObjectBuffer->Length = sizeof(*ReturnObject);
|
|
return AE_OK;
|
|
}
|
|
else if (strcmp(Pathname, "_BIF") == 0)
|
|
{
|
|
PBIF_OBJECT_BUFFER ReturnObject;
|
|
ACPI_OBJECT* BatteryInformation;
|
|
ULONG i;
|
|
|
|
ReturnObject = AcpiOsAllocate(sizeof(*ReturnObject));
|
|
if (!ReturnObject)
|
|
return AE_NO_MEMORY;
|
|
|
|
/*
|
|
* Vbox 7.0 output
|
|
* AcpiGetHandle(NULL, "\\_SB.PCI0.BAT0", &ObjHandle);
|
|
* AcpiEvaluateObject(ObjHandle, "_BIF", NULL, &ReturnObj);
|
|
*/
|
|
BatteryInformation = &ReturnObject->BatteryInformation[0];
|
|
for (i = 0; i < RTL_NUMBER_OF(DrvpBifIntegerFields); ++i)
|
|
{
|
|
BatteryInformation[i].Integer.Type = ACPI_TYPE_INTEGER;
|
|
BatteryInformation[i].Integer.Value = DrvpBifIntegerFields[i];
|
|
}
|
|
BatteryInformation[i].String.Type = ACPI_TYPE_STRING;
|
|
BatteryInformation[i].String.Length = 1; /* Excluding the trailing null */
|
|
BatteryInformation[i].String.Pointer = &ReturnObject->Buffer1[0];
|
|
RtlCopyMemory(BatteryInformation[i].String.Pointer, "1", sizeof("1"));
|
|
++i;
|
|
BatteryInformation[i].String.Type = ACPI_TYPE_STRING;
|
|
BatteryInformation[i].String.Length = 1;
|
|
BatteryInformation[i].String.Pointer = &ReturnObject->Buffer2[0];
|
|
RtlCopyMemory(BatteryInformation[i].String.Pointer, "0", sizeof("0"));
|
|
++i;
|
|
BatteryInformation[i].String.Type = ACPI_TYPE_STRING;
|
|
BatteryInformation[i].String.Length = 4;
|
|
BatteryInformation[i].String.Pointer = &ReturnObject->Buffer3[0];
|
|
RtlCopyMemory(BatteryInformation[i].String.Pointer, "VBOX", sizeof("VBOX"));
|
|
++i;
|
|
BatteryInformation[i].String.Type = ACPI_TYPE_STRING;
|
|
BatteryInformation[i].String.Length = 7;
|
|
BatteryInformation[i].String.Pointer = &ReturnObject->Buffer4[0];
|
|
RtlCopyMemory(BatteryInformation[i].String.Pointer, "innotek", sizeof("innotek"));
|
|
|
|
ReturnObject->Obj.Type = ACPI_TYPE_PACKAGE;
|
|
ReturnObject->Obj.Package.Count = 13;
|
|
ReturnObject->Obj.Package.Elements = BatteryInformation;
|
|
|
|
ReturnObjectBuffer->Pointer = ReturnObject;
|
|
ReturnObjectBuffer->Length = sizeof(*ReturnObject);
|
|
return AE_OK;
|
|
}
|
|
else if (strcmp(Pathname, "_PCL") == 0)
|
|
{
|
|
PPCL_OBJECT_BUFFER ReturnObject;
|
|
|
|
ReturnObject = AcpiOsAllocate(sizeof(*ReturnObject));
|
|
if (!ReturnObject)
|
|
return AE_NO_MEMORY;
|
|
|
|
/*
|
|
* Vbox 7.0 output
|
|
* AcpiGetHandle(NULL, "\\_SB.PCI0.AC", &ObjHandle);
|
|
* AcpiEvaluateObject(ObjHandle, "_PCL", NULL, &ReturnObj);
|
|
*/
|
|
ReturnObject->Obj.Reference.Type = ACPI_TYPE_LOCAL_REFERENCE;
|
|
ReturnObject->Obj.Reference.ActualType = ACPI_TYPE_DEVICE;
|
|
ReturnObject->Obj.Reference.Handle = (ACPI_HANDLE)(ULONG_PTR)FAKE_SB_NAMESPACE_ACPI_HANDLE;
|
|
|
|
ReturnObjectBuffer->Pointer = ReturnObject;
|
|
ReturnObjectBuffer->Length = sizeof(*ReturnObject);
|
|
return AE_OK;
|
|
}
|
|
else if (strcmp(Pathname, "_PRT") == 0)
|
|
{
|
|
PPRT_OBJECT_BUFFER ReturnObject;
|
|
ULONG i;
|
|
|
|
ReturnObject = AcpiOsAllocate(sizeof(*ReturnObject));
|
|
if (!ReturnObject)
|
|
return AE_NO_MEMORY;
|
|
|
|
/*
|
|
* Vbox 7.0 output
|
|
* AcpiGetHandle(NULL, "\\_SB.PCI0", &ObjHandle);
|
|
* AcpiEvaluateObject(ObjHandle, "_PRT", NULL, &ReturnObj);
|
|
*
|
|
* NOTE: To avoid similar copies of code executed and tested over and over again
|
|
* we return 2 packages. The original method returns 120 packages.
|
|
*/
|
|
ReturnObject->Obj.Type = ACPI_TYPE_PACKAGE;
|
|
ReturnObject->Obj.Package.Count = 2;
|
|
ReturnObject->Obj.Package.Elements = &ReturnObject->PackageContainer[0];
|
|
|
|
i = 0;
|
|
ReturnObject->PackageContainer[i].Type = ACPI_TYPE_PACKAGE;
|
|
ReturnObject->PackageContainer[i].Package.Count = 4;
|
|
ReturnObject->PackageContainer[i].Package.Elements = &ReturnObject->Package1[0];
|
|
++i;
|
|
ReturnObject->PackageContainer[i].Type = ACPI_TYPE_PACKAGE;
|
|
ReturnObject->PackageContainer[i].Package.Count = 4;
|
|
ReturnObject->PackageContainer[i].Package.Elements = &ReturnObject->Package2[0];
|
|
|
|
/* Package 1 */
|
|
i = 0;
|
|
ReturnObject->Package1[i].Integer.Type = ACPI_TYPE_INTEGER;
|
|
ReturnObject->Package1[i].Integer.Value = 0x0002FFFF;
|
|
++i;
|
|
ReturnObject->Package1[i].Integer.Type = ACPI_TYPE_INTEGER;
|
|
ReturnObject->Package1[i].Integer.Value = 0x00000000;
|
|
++i;
|
|
ReturnObject->Package1[i].Reference.Type = ACPI_TYPE_LOCAL_REFERENCE;
|
|
ReturnObject->Package1[i].Reference.ActualType = ACPI_TYPE_DEVICE;
|
|
ReturnObject->Package1[i].Reference.Handle = (ACPI_HANDLE)(ULONG_PTR)FAKE_INTB_ACPI_HANDLE;
|
|
++i;
|
|
ReturnObject->Package1[i].Integer.Type = ACPI_TYPE_INTEGER;
|
|
ReturnObject->Package1[i].Integer.Value = 0x00000000;
|
|
|
|
/* Package 2 */
|
|
i = 0;
|
|
ReturnObject->Package2[i].Integer.Type = ACPI_TYPE_INTEGER;
|
|
ReturnObject->Package2[i].Integer.Value = 0x0002FFFF;
|
|
++i;
|
|
ReturnObject->Package2[i].Integer.Type = ACPI_TYPE_INTEGER;
|
|
ReturnObject->Package2[i].Integer.Value = 0x00000001;
|
|
++i;
|
|
ReturnObject->Package2[i].Reference.Type = ACPI_TYPE_LOCAL_REFERENCE;
|
|
ReturnObject->Package2[i].Reference.ActualType = ACPI_TYPE_DEVICE;
|
|
ReturnObject->Package2[i].Reference.Handle = (ACPI_HANDLE)(ULONG_PTR)FAKE_INTC_ACPI_HANDLE;
|
|
++i;
|
|
ReturnObject->Package2[i].Integer.Type = ACPI_TYPE_INTEGER;
|
|
ReturnObject->Package2[i].Integer.Value = 0x00000000;
|
|
|
|
ReturnObjectBuffer->Pointer = ReturnObject;
|
|
ReturnObjectBuffer->Length = sizeof(*ReturnObject);
|
|
return AE_OK;
|
|
}
|
|
else if (strcmp(Pathname, "_DSM") == 0)
|
|
{
|
|
ACPI_OBJECT* Arg;
|
|
|
|
/* Assumed object count per the spec */
|
|
ok_eq_uint(ParameterObjects->Count, 4);
|
|
|
|
if (ParameterObjects->Count != 4)
|
|
return AE_AML_UNINITIALIZED_ARG;
|
|
|
|
/* Argument 1 */
|
|
{
|
|
Arg = ParameterObjects->Pointer;
|
|
|
|
ok_eq_uint_ex(DrvpEvalTestEntry, Arg->Type, ACPI_TYPE_BUFFER);
|
|
ok_eq_uint_ex(DrvpEvalTestEntry, Arg->Buffer.Length, sizeof(GUID));
|
|
}
|
|
|
|
/* NOTE: This UUID doesn't exist, for testing purposes only */
|
|
if (IsEqualGUID(Arg->Buffer.Pointer, &MY_DSM_GUID))
|
|
{
|
|
/* Argument 2 */
|
|
{
|
|
++Arg;
|
|
|
|
ok_eq_uint_ex(DrvpEvalTestEntry, Arg->Type, ACPI_TYPE_INTEGER);
|
|
ok_eq_ulonglong_ex(DrvpEvalTestEntry, Arg->Integer.Value, 1ULL);
|
|
}
|
|
/* Argument 3 */
|
|
{
|
|
++Arg;
|
|
|
|
ok_eq_uint_ex(DrvpEvalTestEntry, Arg->Type, ACPI_TYPE_INTEGER);
|
|
ok_eq_ulonglong_ex(DrvpEvalTestEntry, Arg->Integer.Value, 2ULL);
|
|
}
|
|
/* Argument 4 */
|
|
{
|
|
++Arg;
|
|
|
|
ok_eq_uint_ex(DrvpEvalTestEntry, Arg->Type, ACPI_TYPE_PACKAGE);
|
|
|
|
if (DrvpEvalTestEntry->Flags & DSM_TEST_FLAG_EMPTY_PACKAGE)
|
|
{
|
|
ok_eq_uint_ex(DrvpEvalTestEntry, Arg->Package.Count, 0);
|
|
ok_eq_pointer_ex(DrvpEvalTestEntry, Arg->Package.Elements, NULL);
|
|
}
|
|
else
|
|
{
|
|
ACPI_OBJECT* PackageArg;
|
|
ACPI_OBJECT* PackageArg2;
|
|
ULONG i;
|
|
|
|
ok_eq_uint_ex(DrvpEvalTestEntry, Arg->Package.Count, 4);
|
|
ok_not_pointer_ex(DrvpEvalTestEntry, Arg->Package.Elements, NULL);
|
|
|
|
if (!Arg->Package.Elements)
|
|
return AE_AML_UNINITIALIZED_ARG;
|
|
|
|
/* Package 1 Arguments 1-2 */
|
|
PackageArg = Arg->Package.Elements;
|
|
for (i = 0; i < RTL_NUMBER_OF(DrvpMyDsmIntegerFields) - 1; i++)
|
|
{
|
|
ok_eq_uint_ex(DrvpEvalTestEntry, PackageArg->Type, ACPI_TYPE_INTEGER);
|
|
ok_eq_ulonglong_ex(DrvpEvalTestEntry,
|
|
PackageArg->Integer.Value,
|
|
(ULONG64)DrvpMyDsmIntegerFields[i]);
|
|
|
|
++PackageArg;
|
|
}
|
|
|
|
/* Package 1 Argument 3 */
|
|
{
|
|
Arg = PackageArg;
|
|
|
|
ok_eq_uint_ex(DrvpEvalTestEntry, Arg->Type, ACPI_TYPE_PACKAGE);
|
|
ok_eq_uint_ex(DrvpEvalTestEntry, Arg->Package.Count, 1);
|
|
|
|
/* Package 2 Argument 1 */
|
|
PackageArg2 = Arg->Package.Elements;
|
|
|
|
ok_eq_uint_ex(DrvpEvalTestEntry, PackageArg2->Type, ACPI_TYPE_STRING);
|
|
|
|
/* Excluding the trailing null */
|
|
ok_eq_uint_ex(DrvpEvalTestEntry,
|
|
PackageArg2->String.Length,
|
|
(sizeof("1_TESTDATATESTDATA_2") - 1));
|
|
ok_eq_int_ex(DrvpEvalTestEntry,
|
|
memcmp(PackageArg2->String.Pointer,
|
|
"1_TESTDATATESTDATA_2",
|
|
sizeof("1_TESTDATATESTDATA_2") - 1),
|
|
0);
|
|
}
|
|
/* Package 1 Argument 4 */
|
|
{
|
|
++PackageArg;
|
|
|
|
ok_eq_uint_ex(DrvpEvalTestEntry, PackageArg->Type, ACPI_TYPE_INTEGER);
|
|
ok_eq_ulonglong_ex(DrvpEvalTestEntry,
|
|
PackageArg->Integer.Value,
|
|
(ULONG64)DrvpMyDsmIntegerFields[2]);
|
|
}
|
|
}
|
|
}
|
|
|
|
return AE_OK;
|
|
}
|
|
}
|
|
|
|
return AE_NOT_FOUND;
|
|
}
|
|
|
|
#include "../../../../drivers/bus/acpi/eval.c"
|
|
|
|
/* GLOBALS ********************************************************************/
|
|
|
|
/* 2 ID blocks + timings + room for the test data */
|
|
#define STM_MAX_BUFFER_SIZE \
|
|
(FIELD_OFFSET(ACPI_EVAL_INPUT_BUFFER_COMPLEX, Argument) + \
|
|
2 * STM_ID_BLOCK_SIZE + sizeof(IDE_ACPI_TIMING_MODE_BLOCK) + 0x100)
|
|
|
|
#define GTM_MAX_BUFFER_SIZE \
|
|
(FIELD_OFFSET(ACPI_EVAL_OUTPUT_BUFFER, Argument) + \
|
|
ACPI_METHOD_ARGUMENT_LENGTH(sizeof(IDE_ACPI_TIMING_MODE_BLOCK)) + 0x50)
|
|
|
|
static const EVAL_TEST_ENTRY DrvpSmtTests[] =
|
|
{
|
|
{ __LINE__, 0, STATUS_SUCCESS },
|
|
{ __LINE__, STM_TEST_FLAG_INVALID_SIZE_1, STATUS_ACPI_INVALID_ARGTYPE },
|
|
{ __LINE__, STM_TEST_FLAG_LARGE_ARG_BUFFER, STATUS_ACPI_INVALID_ARGTYPE },
|
|
{ __LINE__, STM_TEST_FLAG_SUB_IN_BUFFER, STATUS_SUCCESS, 1 },
|
|
{ __LINE__, STM_TEST_FLAG_SUB_IN_BUFFER, STATUS_SUCCESS, 9 },
|
|
{ __LINE__, STM_TEST_FLAG_SUB_IRP_BUFFER, STATUS_SUCCESS, 1 },
|
|
{ __LINE__, STM_TEST_FLAG_SUB_IRP_BUFFER, STATUS_SUCCESS, 9 },
|
|
{ __LINE__, STM_TEST_FLAG_SET_IN_BUFFER, STATUS_SUCCESS, 0 },
|
|
{ __LINE__, STM_TEST_FLAG_SET_IRP_BUFFER, STATUS_INFO_LENGTH_MISMATCH, 0 },
|
|
{ __LINE__, STM_TEST_FLAG_SET_IRP_BUFFER, STATUS_INFO_LENGTH_MISMATCH,
|
|
RTL_SIZEOF_THROUGH_FIELD(ACPI_EVAL_INPUT_BUFFER, Signature) - 2 },
|
|
{ __LINE__, STM_TEST_FLAG_SET_IRP_BUFFER, STATUS_INFO_LENGTH_MISMATCH,
|
|
RTL_SIZEOF_THROUGH_FIELD(ACPI_EVAL_INPUT_BUFFER, Signature) - 1 },
|
|
{ __LINE__, STM_TEST_FLAG_SET_IRP_BUFFER, STATUS_INFO_LENGTH_MISMATCH,
|
|
RTL_SIZEOF_THROUGH_FIELD(ACPI_EVAL_INPUT_BUFFER, Signature) },
|
|
{ __LINE__, STM_TEST_FLAG_SET_IRP_BUFFER, STATUS_INFO_LENGTH_MISMATCH,
|
|
sizeof(ACPI_EVAL_INPUT_BUFFER) - 2 },
|
|
{ __LINE__, STM_TEST_FLAG_SET_IRP_BUFFER, STATUS_INFO_LENGTH_MISMATCH,
|
|
sizeof(ACPI_EVAL_INPUT_BUFFER) - 1 },
|
|
{ __LINE__, STM_TEST_FLAG_SET_IRP_BUFFER, STATUS_INSUFFICIENT_RESOURCES,
|
|
sizeof(ACPI_EVAL_INPUT_BUFFER) },
|
|
{ __LINE__, STM_TEST_FLAG_SET_IRP_BUFFER, STATUS_INSUFFICIENT_RESOURCES,
|
|
sizeof(ACPI_EVAL_INPUT_BUFFER) + 1 },
|
|
{ __LINE__, STM_TEST_FLAG_SET_IRP_BUFFER, STATUS_INSUFFICIENT_RESOURCES,
|
|
sizeof(ACPI_EVAL_INPUT_BUFFER) + 2 },
|
|
{ __LINE__, STM_TEST_FLAG_BAD_ARG_TYPE, STATUS_SUCCESS, 0 },
|
|
{ __LINE__, STM_TEST_FLAG_CHANGE_ARG_COUNT, STATUS_ACPI_INCORRECT_ARGUMENT_COUNT, 0 },
|
|
|
|
#if 0
|
|
/*
|
|
* The return status depends on AML interpreter implementation
|
|
* and testing it is not practical, keeping this for reference only.
|
|
*/
|
|
{ __LINE__, STM_TEST_FLAG_INVALID_ARG_3_1, STATUS_SUCCESS },
|
|
{ __LINE__, STM_TEST_FLAG_INVALID_ARG_3_2, STATUS_ACPI_INVALID_ARGTYPE },
|
|
{ __LINE__, STM_TEST_FLAG_INVALID_ARG_3_4, STATUS_SUCCESS },
|
|
{ __LINE__, STM_TEST_FLAG_INVALID_ARG_3_5, STATUS_SUCCESS },
|
|
{ __LINE__, STM_TEST_FLAG_CHANGE_ARG_COUNT, STATUS_ACPI_INCORRECT_ARGUMENT_COUNT, 30 },
|
|
{ __LINE__, STM_TEST_FLAG_CHANGE_ARG_COUNT, STATUS_ACPI_INCORRECT_ARGUMENT_COUNT, 2 },
|
|
#endif
|
|
};
|
|
|
|
static const EVAL_TEST_ENTRY DrvpGtmTests[] =
|
|
{
|
|
{ __LINE__, GTM_TEST_FLAG_METHOD_SUCCESS, STATUS_SUCCESS },
|
|
{ __LINE__, GTM_TEST_FLAG_METHOD_SUCCESS |
|
|
GTM_TEST_FLAG_INC_OUT_BUFFER, STATUS_SUCCESS, 1 },
|
|
{ __LINE__, GTM_TEST_FLAG_METHOD_SUCCESS |
|
|
GTM_TEST_FLAG_DEC_OUT_BUFFER, STATUS_BUFFER_OVERFLOW, 1 },
|
|
{ __LINE__, GTM_TEST_FLAG_SET_OUT_BUFFER, STATUS_SUCCESS, 0 },
|
|
{ __LINE__, GTM_TEST_FLAG_SET_OUT_BUFFER, STATUS_BUFFER_TOO_SMALL, 1 },
|
|
{ __LINE__, GTM_TEST_FLAG_SET_OUT_BUFFER, STATUS_BUFFER_TOO_SMALL,
|
|
FIELD_OFFSET(ACPI_EVAL_OUTPUT_BUFFER, Argument) - 1 },
|
|
{ __LINE__, GTM_TEST_FLAG_SET_OUT_BUFFER, STATUS_BUFFER_TOO_SMALL,
|
|
FIELD_OFFSET(ACPI_EVAL_OUTPUT_BUFFER, Argument) },
|
|
{ __LINE__, GTM_TEST_FLAG_SET_OUT_BUFFER, STATUS_BUFFER_TOO_SMALL,
|
|
FIELD_OFFSET(ACPI_EVAL_OUTPUT_BUFFER, Argument) + 1 },
|
|
{ __LINE__, GTM_TEST_FLAG_SET_OUT_BUFFER, STATUS_BUFFER_TOO_SMALL,
|
|
sizeof(ACPI_EVAL_OUTPUT_BUFFER) - 1 },
|
|
{ __LINE__, GTM_TEST_FLAG_BUFFER_HAS_SIGNARUTE |
|
|
GTM_TEST_FLAG_BUFFER_HAS_COUNT |
|
|
GTM_TEST_FLAG_BUFFER_HAS_LENGTH |
|
|
GTM_TEST_FLAG_SET_OUT_BUFFER,
|
|
STATUS_BUFFER_OVERFLOW,
|
|
sizeof(ACPI_EVAL_OUTPUT_BUFFER) },
|
|
{ __LINE__, GTM_TEST_FLAG_BUFFER_HAS_SIGNARUTE |
|
|
GTM_TEST_FLAG_BUFFER_HAS_COUNT |
|
|
GTM_TEST_FLAG_BUFFER_HAS_LENGTH |
|
|
GTM_TEST_FLAG_SET_OUT_BUFFER,
|
|
STATUS_BUFFER_OVERFLOW,
|
|
sizeof(ACPI_EVAL_OUTPUT_BUFFER) + 1 },
|
|
|
|
/* Pass an invalid signature */
|
|
{ __LINE__, GTM_TEST_FLAG_BAD_SIGNARUTE, STATUS_INVALID_PARAMETER_1 },
|
|
{ __LINE__, GTM_TEST_FLAG_BAD_SIGNARUTE | GTM_TEST_FLAG_SET_OUT_BUFFER,
|
|
STATUS_INVALID_PARAMETER_1, 0 },
|
|
{ __LINE__, GTM_TEST_FLAG_BAD_SIGNARUTE | GTM_TEST_FLAG_SET_OUT_BUFFER,
|
|
STATUS_BUFFER_TOO_SMALL,
|
|
sizeof(ACPI_EVAL_OUTPUT_BUFFER) - 1 },
|
|
{ __LINE__, GTM_TEST_FLAG_BAD_SIGNARUTE | GTM_TEST_FLAG_SET_OUT_BUFFER,
|
|
STATUS_INVALID_PARAMETER_1,
|
|
sizeof(ACPI_EVAL_OUTPUT_BUFFER) },
|
|
};
|
|
|
|
static const EVAL_TEST_ENTRY DrvpBifTests[] =
|
|
{
|
|
{ __LINE__, 0, STATUS_SUCCESS },
|
|
};
|
|
|
|
static const EVAL_TEST_ENTRY DrvpPclTests[] =
|
|
{
|
|
{ __LINE__, 0, STATUS_SUCCESS },
|
|
};
|
|
|
|
static const EVAL_TEST_ENTRY DrvpPrtTests[] =
|
|
{
|
|
{ __LINE__, 0, STATUS_SUCCESS },
|
|
};
|
|
|
|
static const EVAL_TEST_ENTRY DrvpDsmTests[] =
|
|
{
|
|
{ __LINE__, 0, STATUS_SUCCESS },
|
|
{ __LINE__, DSM_TEST_FLAG_EMPTY_PACKAGE, STATUS_SUCCESS },
|
|
{ __LINE__, DSM_TEST_FLAG_LARGE_SUB_PACKAGE_BUFFER, STATUS_ACPI_INVALID_ARGTYPE },
|
|
};
|
|
|
|
/* FUNCTIONS ******************************************************************/
|
|
|
|
static
|
|
NTSTATUS
|
|
DrvCallAcpiDriver(
|
|
_In_ PVOID InputBuffer,
|
|
_In_ ULONG InputBufferLength,
|
|
_Out_opt_ PACPI_EVAL_OUTPUT_BUFFER OutputBuffer,
|
|
_In_ ULONG OutputBufferLength)
|
|
{
|
|
PDO_DEVICE_DATA DeviceData;
|
|
IRP Irp;
|
|
|
|
DeviceData.AcpiHandle = NULL;
|
|
|
|
Irp.AssociatedIrp.SystemBuffer = InputBuffer;
|
|
Irp.OutputBuffer = OutputBuffer;
|
|
|
|
Irp.MyStack.Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
|
|
Irp.MyStack.Parameters.DeviceIoControl.OutputBufferLength = OutputBufferLength;
|
|
|
|
return Bus_PDO_EvalMethod(&DeviceData, &Irp);
|
|
}
|
|
|
|
static
|
|
VOID
|
|
DrvEvaluateStmObject(
|
|
_In_ const EVAL_TEST_ENTRY* TestEntry,
|
|
_In_ PIDE_ACPI_TIMING_MODE_BLOCK TimingMode,
|
|
_In_ PUCHAR IdBlock,
|
|
_In_ PACPI_EVAL_INPUT_BUFFER_COMPLEX InputBuffer)
|
|
{
|
|
PACPI_METHOD_ARGUMENT Argument, Argument2, Argument3;
|
|
NTSTATUS Status;
|
|
ULONG InputBufferSize, IrpBufferSize;
|
|
|
|
InputBufferSize = FIELD_OFFSET(ACPI_EVAL_INPUT_BUFFER_COMPLEX, Argument) +
|
|
ACPI_METHOD_ARGUMENT_LENGTH(sizeof(*TimingMode)) +
|
|
ACPI_METHOD_ARGUMENT_LENGTH(STM_ID_BLOCK_SIZE) +
|
|
ACPI_METHOD_ARGUMENT_LENGTH(STM_ID_BLOCK_SIZE);
|
|
|
|
if (TestEntry->Flags & STM_TEST_FLAG_INVALID_SIZE_1)
|
|
{
|
|
InputBufferSize -= ACPI_METHOD_ARGUMENT_LENGTH(STM_ID_BLOCK_SIZE) +
|
|
ACPI_METHOD_ARGUMENT_LENGTH(STM_ID_BLOCK_SIZE);
|
|
}
|
|
|
|
InputBuffer->MethodNameAsUlong = 'MTS_'; // _STM
|
|
InputBuffer->Signature = ACPI_EVAL_INPUT_BUFFER_COMPLEX_SIGNATURE;
|
|
if (TestEntry->Flags & STM_TEST_FLAG_SUB_IN_BUFFER)
|
|
{
|
|
InputBuffer->Size = InputBufferSize - TestEntry->Value;
|
|
}
|
|
else if (TestEntry->Flags & STM_TEST_FLAG_SET_IN_BUFFER)
|
|
{
|
|
InputBuffer->Size = TestEntry->Value;
|
|
}
|
|
else
|
|
{
|
|
InputBuffer->Size = InputBufferSize;
|
|
}
|
|
|
|
if (TestEntry->Flags & STM_TEST_FLAG_CHANGE_ARG_COUNT)
|
|
{
|
|
InputBuffer->ArgumentCount = TestEntry->Value;
|
|
}
|
|
else
|
|
{
|
|
InputBuffer->ArgumentCount = 3;
|
|
}
|
|
|
|
/* Argument 1: The channel timing information block */
|
|
Argument = InputBuffer->Argument;
|
|
ACPI_METHOD_SET_ARGUMENT_BUFFER(Argument, TimingMode, sizeof(*TimingMode));
|
|
|
|
/* Argument 2: The ATA drive ID block */
|
|
Argument2 = ACPI_METHOD_NEXT_ARGUMENT(Argument);
|
|
ACPI_METHOD_SET_ARGUMENT_BUFFER(Argument2, IdBlock, STM_ID_BLOCK_SIZE);
|
|
|
|
/* Argument 3: The ATA drive ID block */
|
|
Argument3 = ACPI_METHOD_NEXT_ARGUMENT(Argument2);
|
|
ACPI_METHOD_SET_ARGUMENT_BUFFER(Argument3, IdBlock, STM_ID_BLOCK_SIZE);
|
|
|
|
if (TestEntry->Flags & STM_TEST_FLAG_BAD_ARG_TYPE)
|
|
{
|
|
Argument3->Type = 0xFFFF;
|
|
}
|
|
|
|
if (TestEntry->Flags & STM_TEST_FLAG_LARGE_ARG_BUFFER)
|
|
{
|
|
Argument2->DataLength = STM_ID_BLOCK_SIZE * 2;
|
|
Argument3->DataLength = STM_ID_BLOCK_SIZE * 2;
|
|
}
|
|
|
|
if (TestEntry->Flags & STM_TEST_FLAG_INVALID_ARG_3_1)
|
|
{
|
|
ACPI_METHOD_SET_ARGUMENT_STRING(Argument3, IdBlock);
|
|
}
|
|
else if (TestEntry->Flags & STM_TEST_FLAG_INVALID_ARG_3_2)
|
|
{
|
|
ACPI_METHOD_SET_ARGUMENT_INTEGER(Argument3, 0xDEADBEEF);
|
|
}
|
|
else if (TestEntry->Flags & STM_TEST_FLAG_INVALID_ARG_3_4)
|
|
{
|
|
Argument3->DataLength += 5;
|
|
}
|
|
else if (TestEntry->Flags & STM_TEST_FLAG_INVALID_ARG_3_5)
|
|
{
|
|
Argument3->DataLength -= 5;
|
|
}
|
|
|
|
if (TestEntry->Flags & STM_TEST_FLAG_SUB_IRP_BUFFER)
|
|
{
|
|
IrpBufferSize = InputBufferSize - TestEntry->Value;
|
|
}
|
|
else if (TestEntry->Flags & STM_TEST_FLAG_SET_IRP_BUFFER)
|
|
{
|
|
IrpBufferSize = TestEntry->Value;
|
|
}
|
|
else
|
|
{
|
|
IrpBufferSize = InputBufferSize;
|
|
}
|
|
|
|
/* Evaluate the _STM method */
|
|
DrvpEvalTestEntry = TestEntry;
|
|
Status = DrvCallAcpiDriver(InputBuffer, IrpBufferSize, NULL, 0);
|
|
|
|
ok_eq_hex_ex(TestEntry, Status, TestEntry->Status);
|
|
}
|
|
|
|
static
|
|
VOID
|
|
DrvTestComplexBuffer(VOID)
|
|
{
|
|
IDE_ACPI_TIMING_MODE_BLOCK TimingMode;
|
|
UCHAR IdBlock[STM_ID_BLOCK_SIZE];
|
|
ULONG i;
|
|
UCHAR Buffer[STM_MAX_BUFFER_SIZE];
|
|
PACPI_EVAL_INPUT_BUFFER_COMPLEX InputBuffer = (PACPI_EVAL_INPUT_BUFFER_COMPLEX)Buffer;
|
|
|
|
/* Initialize method arguments */
|
|
RtlZeroMemory(IdBlock, sizeof(IdBlock));
|
|
TimingMode.Drive[0].PioSpeed = 508;
|
|
TimingMode.Drive[0].DmaSpeed = 120;
|
|
TimingMode.Drive[1].PioSpeed = 240;
|
|
TimingMode.Drive[1].DmaSpeed = 180;
|
|
TimingMode.ModeFlags = 0x10;
|
|
|
|
for (i = 0; i < RTL_NUMBER_OF(DrvpSmtTests); ++i)
|
|
{
|
|
DrvEvaluateStmObject(&DrvpSmtTests[i], &TimingMode, IdBlock, InputBuffer);
|
|
}
|
|
}
|
|
|
|
static
|
|
VOID
|
|
DrvEvaluateGtmObject(
|
|
_In_ const EVAL_TEST_ENTRY* TestEntry,
|
|
_In_ PACPI_EVAL_OUTPUT_BUFFER OutputBuffer)
|
|
{
|
|
ACPI_EVAL_INPUT_BUFFER InputBuffer;
|
|
ULONG OutputBufferSize;
|
|
NTSTATUS Status;
|
|
PACPI_METHOD_ARGUMENT Argument;
|
|
ULONG Signature, Count, Length;
|
|
USHORT Type, DataLength;
|
|
PIDE_ACPI_TIMING_MODE_BLOCK TimingMode;
|
|
|
|
InputBuffer.MethodNameAsUlong = 'MTG_'; // _GTM
|
|
if (TestEntry->Flags & GTM_TEST_FLAG_BAD_SIGNARUTE)
|
|
InputBuffer.Signature = 'BAD0';
|
|
else
|
|
InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
|
|
|
|
OutputBufferSize = FIELD_OFFSET(ACPI_EVAL_OUTPUT_BUFFER, Argument) +
|
|
ACPI_METHOD_ARGUMENT_LENGTH(sizeof(*TimingMode));
|
|
|
|
if (TestEntry->Flags & GTM_TEST_FLAG_INC_OUT_BUFFER)
|
|
{
|
|
OutputBufferSize += TestEntry->Value;
|
|
}
|
|
else if (TestEntry->Flags & GTM_TEST_FLAG_DEC_OUT_BUFFER)
|
|
{
|
|
OutputBufferSize -= TestEntry->Value;
|
|
}
|
|
else if (TestEntry->Flags & GTM_TEST_FLAG_SET_OUT_BUFFER)
|
|
{
|
|
OutputBufferSize = TestEntry->Value;
|
|
}
|
|
|
|
/* Evaluate the _GTM method */
|
|
Status = DrvCallAcpiDriver(&InputBuffer, sizeof(InputBuffer), OutputBuffer, OutputBufferSize);
|
|
|
|
ok_eq_hex_ex(TestEntry, Status, TestEntry->Status);
|
|
|
|
if (TestEntry->Flags & GTM_TEST_FLAG_BUFFER_HAS_SIGNARUTE)
|
|
Signature = ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE;
|
|
else
|
|
Signature = 0;
|
|
ok_eq_hex_ex(TestEntry, OutputBuffer->Signature, Signature);
|
|
|
|
if (TestEntry->Flags & GTM_TEST_FLAG_BUFFER_HAS_COUNT)
|
|
Count = 1;
|
|
else
|
|
Count = 0;
|
|
ok_eq_ulong_ex(TestEntry, OutputBuffer->Count, Count);
|
|
|
|
if (TestEntry->Flags & GTM_TEST_FLAG_BUFFER_HAS_LENGTH)
|
|
{
|
|
Length = FIELD_OFFSET(ACPI_EVAL_OUTPUT_BUFFER, Argument) +
|
|
ACPI_METHOD_ARGUMENT_LENGTH(sizeof(*TimingMode));
|
|
}
|
|
else
|
|
{
|
|
Length = 0;
|
|
}
|
|
ok_eq_ulong_ex(TestEntry, OutputBuffer->Length, Length);
|
|
|
|
Argument = OutputBuffer->Argument;
|
|
if (TestEntry->Flags & GTM_TEST_FLAG_ARG_HAS_BUFFER_TYPE)
|
|
Type = ACPI_METHOD_ARGUMENT_BUFFER;
|
|
else
|
|
Type = ACPI_METHOD_ARGUMENT_INTEGER;
|
|
ok_eq_uint_ex(TestEntry, Argument->Type, Type);
|
|
|
|
if (TestEntry->Flags & GTM_TEST_FLAG_ARG_HAS_DATA_LENGTH)
|
|
DataLength = sizeof(ACPI_EVAL_OUTPUT_BUFFER);
|
|
else
|
|
DataLength = 0;
|
|
ok_eq_uint_ex(TestEntry, Argument->DataLength, DataLength);
|
|
|
|
if ((TestEntry->Flags & GTM_TEST_FLAG_ARG_HAS_BUFFER_TYPE) && NT_SUCCESS(TestEntry->Status))
|
|
{
|
|
TimingMode = (PIDE_ACPI_TIMING_MODE_BLOCK)Argument->Data;
|
|
|
|
ok_eq_ulong_ex(TestEntry, TimingMode->Drive[0].PioSpeed, 900LU);
|
|
ok_eq_ulong_ex(TestEntry, TimingMode->Drive[0].DmaSpeed, 900LU);
|
|
ok_eq_ulong_ex(TestEntry, TimingMode->Drive[1].PioSpeed, 120LU);
|
|
ok_eq_ulong_ex(TestEntry, TimingMode->Drive[1].DmaSpeed, 120LU);
|
|
ok_eq_hex_ex(TestEntry, TimingMode->ModeFlags, 0x12LU);
|
|
}
|
|
}
|
|
|
|
static
|
|
VOID
|
|
DrvTestInputBuffer(VOID)
|
|
{
|
|
UCHAR Buffer[GTM_MAX_BUFFER_SIZE];
|
|
ULONG i;
|
|
PACPI_EVAL_OUTPUT_BUFFER OutputBuffer = (PACPI_EVAL_OUTPUT_BUFFER)Buffer;
|
|
|
|
for (i = 0; i < RTL_NUMBER_OF(DrvpGtmTests); ++i)
|
|
{
|
|
RtlZeroMemory(Buffer, sizeof(Buffer));
|
|
|
|
DrvEvaluateGtmObject(&DrvpGtmTests[i], OutputBuffer);
|
|
}
|
|
}
|
|
|
|
static
|
|
VOID
|
|
DrvEvaluateBifObject(
|
|
_In_ const EVAL_TEST_ENTRY* TestEntry,
|
|
_In_ PACPI_EVAL_OUTPUT_BUFFER OutputBuffer)
|
|
{
|
|
ACPI_EVAL_INPUT_BUFFER InputBuffer;
|
|
ULONG i, OutputBufferSize;
|
|
NTSTATUS Status;
|
|
PACPI_METHOD_ARGUMENT Argument;
|
|
|
|
InputBuffer.MethodNameAsUlong = 'FIB_'; // _BIF
|
|
InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
|
|
|
|
OutputBufferSize = FIELD_OFFSET(ACPI_EVAL_OUTPUT_BUFFER, Argument) +
|
|
ACPI_METHOD_ARGUMENT_LENGTH(sizeof(ULONG)) * 9 +
|
|
ACPI_METHOD_ARGUMENT_LENGTH(sizeof("1")) +
|
|
ACPI_METHOD_ARGUMENT_LENGTH(sizeof("0")) +
|
|
ACPI_METHOD_ARGUMENT_LENGTH(sizeof("VBOX")) +
|
|
ACPI_METHOD_ARGUMENT_LENGTH(sizeof("innotek"));
|
|
|
|
/* Evaluate the _BIF method */
|
|
Status = DrvCallAcpiDriver(&InputBuffer, sizeof(InputBuffer), OutputBuffer, OutputBufferSize);
|
|
|
|
ok_eq_hex_ex(TestEntry, Status, TestEntry->Status);
|
|
ok_eq_hex_ex(TestEntry, OutputBuffer->Signature, (ULONG)ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE);
|
|
ok_eq_ulong_ex(TestEntry, OutputBuffer->Count, 13LU);
|
|
ok_eq_ulong_ex(TestEntry, OutputBuffer->Length, OutputBufferSize);
|
|
|
|
/* Arguments 1-9 */
|
|
Argument = OutputBuffer->Argument;
|
|
for (i = 0; i < RTL_NUMBER_OF(DrvpBifIntegerFields); ++i)
|
|
{
|
|
ok_eq_uint_ex(TestEntry, Argument->Type, ACPI_METHOD_ARGUMENT_INTEGER);
|
|
ok_eq_uint_ex(TestEntry, Argument->DataLength, sizeof(ULONG));
|
|
ok_eq_ulong_ex(TestEntry, Argument->Argument, DrvpBifIntegerFields[i]);
|
|
|
|
Argument = ACPI_METHOD_NEXT_ARGUMENT(Argument);
|
|
}
|
|
/* Argument 10 */
|
|
{
|
|
ok_eq_uint_ex(TestEntry, Argument->Type, ACPI_METHOD_ARGUMENT_STRING);
|
|
ok_eq_uint_ex(TestEntry, Argument->DataLength, sizeof("1")); // Including the trailing null
|
|
ok_eq_str_ex(TestEntry, (PCSTR)Argument->Data, "1");
|
|
}
|
|
/* Argument 11 */
|
|
{
|
|
Argument = ACPI_METHOD_NEXT_ARGUMENT(Argument);
|
|
|
|
ok_eq_uint_ex(TestEntry, Argument->Type, ACPI_METHOD_ARGUMENT_STRING);
|
|
ok_eq_uint_ex(TestEntry, Argument->DataLength, sizeof("0"));
|
|
ok_eq_str_ex(TestEntry, (PCSTR)Argument->Data, "0");
|
|
}
|
|
/* Argument 12 */
|
|
{
|
|
Argument = ACPI_METHOD_NEXT_ARGUMENT(Argument);
|
|
|
|
ok_eq_uint_ex(TestEntry, Argument->Type, ACPI_METHOD_ARGUMENT_STRING);
|
|
ok_eq_uint_ex(TestEntry, Argument->DataLength, sizeof("VBOX"));
|
|
ok_eq_str_ex(TestEntry, (PCSTR)Argument->Data, "VBOX");
|
|
}
|
|
/* Argument 13 */
|
|
{
|
|
Argument = ACPI_METHOD_NEXT_ARGUMENT(Argument);
|
|
|
|
ok_eq_uint_ex(TestEntry, Argument->Type, ACPI_METHOD_ARGUMENT_STRING);
|
|
ok_eq_uint_ex(TestEntry, Argument->DataLength, sizeof("innotek"));
|
|
ok_eq_str_ex(TestEntry, (PCSTR)Argument->Data, "innotek");
|
|
}
|
|
}
|
|
|
|
static
|
|
VOID
|
|
DrvTestPackageReturnValueAndStringData(VOID)
|
|
{
|
|
UCHAR Buffer[0x100];
|
|
ULONG i;
|
|
PACPI_EVAL_OUTPUT_BUFFER OutputBuffer = (PACPI_EVAL_OUTPUT_BUFFER)Buffer;
|
|
|
|
for (i = 0; i < RTL_NUMBER_OF(DrvpBifTests); ++i)
|
|
{
|
|
RtlZeroMemory(Buffer, sizeof(Buffer));
|
|
|
|
DrvEvaluateBifObject(&DrvpBifTests[i], OutputBuffer);
|
|
}
|
|
}
|
|
|
|
static
|
|
VOID
|
|
DrvEvaluatePclObject(
|
|
_In_ const EVAL_TEST_ENTRY* TestEntry,
|
|
_In_ PACPI_EVAL_OUTPUT_BUFFER OutputBuffer)
|
|
{
|
|
ACPI_EVAL_INPUT_BUFFER InputBuffer;
|
|
ULONG OutputBufferSize;
|
|
NTSTATUS Status;
|
|
PACPI_METHOD_ARGUMENT Argument;
|
|
|
|
InputBuffer.MethodNameAsUlong = 'LCP_'; // _PCL
|
|
InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
|
|
|
|
OutputBufferSize = FIELD_OFFSET(ACPI_EVAL_OUTPUT_BUFFER, Argument) +
|
|
ACPI_METHOD_ARGUMENT_LENGTH(sizeof("ABCD")); // ACPI name for the object
|
|
|
|
/* Evaluate the _PCL method */
|
|
Status = DrvCallAcpiDriver(&InputBuffer, sizeof(InputBuffer), OutputBuffer, OutputBufferSize);
|
|
|
|
ok_eq_hex_ex(TestEntry, Status, TestEntry->Status);
|
|
ok_eq_hex_ex(TestEntry, OutputBuffer->Signature, (ULONG)ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE);
|
|
ok_eq_ulong_ex(TestEntry, OutputBuffer->Count, 1LU);
|
|
ok_eq_ulong_ex(TestEntry, OutputBuffer->Length, OutputBufferSize);
|
|
|
|
Argument = OutputBuffer->Argument;
|
|
|
|
ok_eq_uint_ex(TestEntry, Argument->Type, ACPI_METHOD_ARGUMENT_STRING);
|
|
ok_eq_uint_ex(TestEntry, Argument->DataLength, sizeof("ABCD"));
|
|
ok_eq_str_ex(TestEntry, (PCSTR)Argument->Data, "_SB_");
|
|
}
|
|
|
|
static
|
|
VOID
|
|
DrvTestReferenceReturnValue(VOID)
|
|
{
|
|
UCHAR Buffer[0x100];
|
|
ULONG i;
|
|
PACPI_EVAL_OUTPUT_BUFFER OutputBuffer = (PACPI_EVAL_OUTPUT_BUFFER)Buffer;
|
|
|
|
for (i = 0; i < RTL_NUMBER_OF(DrvpPclTests); ++i)
|
|
{
|
|
RtlZeroMemory(Buffer, sizeof(Buffer));
|
|
|
|
DrvEvaluatePclObject(&DrvpPclTests[i], OutputBuffer);
|
|
}
|
|
}
|
|
|
|
static
|
|
VOID
|
|
DrvEvaluatePrtObject(
|
|
_In_ const EVAL_TEST_ENTRY* TestEntry,
|
|
_In_ PACPI_EVAL_OUTPUT_BUFFER OutputBuffer)
|
|
{
|
|
ACPI_EVAL_INPUT_BUFFER InputBuffer;
|
|
ULONG PackageNum, ArgNum, OutputBufferSize;
|
|
NTSTATUS Status;
|
|
PACPI_METHOD_ARGUMENT Argument, PackageArgument;
|
|
|
|
InputBuffer.MethodNameAsUlong = 'TRP_'; // _PRT
|
|
InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
|
|
|
|
#define PRT_PACKAGE_ENTRY_SIZE \
|
|
(ACPI_METHOD_ARGUMENT_LENGTH(sizeof(ULONG)) * 3 + \
|
|
ACPI_METHOD_ARGUMENT_LENGTH(sizeof("LNKB")))
|
|
|
|
OutputBufferSize = FIELD_OFFSET(ACPI_EVAL_OUTPUT_BUFFER, Argument) +
|
|
ACPI_METHOD_ARGUMENT_LENGTH(PRT_PACKAGE_ENTRY_SIZE) * 2;
|
|
|
|
/* Evaluate the _PRT method */
|
|
Status = DrvCallAcpiDriver(&InputBuffer, sizeof(InputBuffer), OutputBuffer, OutputBufferSize);
|
|
|
|
ok_eq_hex_ex(TestEntry, Status, TestEntry->Status);
|
|
ok_eq_hex_ex(TestEntry, OutputBuffer->Signature, (ULONG)ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE);
|
|
ok_eq_ulong_ex(TestEntry, OutputBuffer->Count, 2LU);
|
|
ok_eq_ulong_ex(TestEntry, OutputBuffer->Length, OutputBufferSize);
|
|
|
|
Argument = OutputBuffer->Argument;
|
|
for (PackageNum = 0; PackageNum < 2; PackageNum++)
|
|
{
|
|
ok_eq_uint_ex(TestEntry, Argument->Type, ACPI_METHOD_ARGUMENT_PACKAGE);
|
|
ok_eq_uint_ex(TestEntry, Argument->DataLength, (USHORT)PRT_PACKAGE_ENTRY_SIZE);
|
|
|
|
PackageArgument = (PACPI_METHOD_ARGUMENT)Argument->Data;
|
|
for (ArgNum = 0; ArgNum < 4; ArgNum++)
|
|
{
|
|
if (ArgNum != 2)
|
|
{
|
|
ULONG ExpectedValue;
|
|
|
|
ok_eq_uint_ex(TestEntry, PackageArgument->Type, ACPI_METHOD_ARGUMENT_INTEGER);
|
|
ok_eq_uint_ex(TestEntry, PackageArgument->DataLength, sizeof(ULONG));
|
|
|
|
if (ArgNum == 0)
|
|
{
|
|
ExpectedValue = 0x0002FFFF;
|
|
}
|
|
else
|
|
{
|
|
if ((PackageNum == 1) && (ArgNum == 1))
|
|
ExpectedValue = 0x00000001;
|
|
else
|
|
ExpectedValue = 0x00000000;
|
|
}
|
|
ok_eq_ulong_ex(TestEntry, PackageArgument->Argument, ExpectedValue);
|
|
}
|
|
else
|
|
{
|
|
ok_eq_uint_ex(TestEntry, PackageArgument->Type, ACPI_METHOD_ARGUMENT_STRING);
|
|
ok_eq_uint_ex(TestEntry, PackageArgument->DataLength, sizeof("ABCD"));
|
|
ok_eq_str_ex(TestEntry, (PCSTR)PackageArgument->Data,
|
|
(PackageNum == 0) ? "LNKB" : "LNKC");
|
|
}
|
|
|
|
PackageArgument = ACPI_METHOD_NEXT_ARGUMENT(PackageArgument);
|
|
}
|
|
|
|
Argument = ACPI_METHOD_NEXT_ARGUMENT(Argument);
|
|
}
|
|
}
|
|
|
|
static
|
|
VOID
|
|
DrvTestNestedPackageReturnValue(VOID)
|
|
{
|
|
UCHAR Buffer[0x100];
|
|
ULONG i;
|
|
PACPI_EVAL_OUTPUT_BUFFER OutputBuffer = (PACPI_EVAL_OUTPUT_BUFFER)Buffer;
|
|
|
|
for (i = 0; i < RTL_NUMBER_OF(DrvpPclTests); ++i)
|
|
{
|
|
RtlZeroMemory(Buffer, sizeof(Buffer));
|
|
|
|
DrvEvaluatePrtObject(&DrvpPrtTests[i], OutputBuffer);
|
|
}
|
|
}
|
|
|
|
static
|
|
VOID
|
|
DrvEvaluateDsmObject(
|
|
_In_ const EVAL_TEST_ENTRY* TestEntry)
|
|
{
|
|
#define MY_DSM_SUB_PACKAGE_ENTRY_SIZE \
|
|
(ACPI_METHOD_ARGUMENT_LENGTH(sizeof("1_TESTDATATESTDATA_2")))
|
|
|
|
#define MY_DSM_PACKAGE_ENTRY_SIZE \
|
|
(ACPI_METHOD_ARGUMENT_LENGTH(sizeof(ULONG)) * 3 + \
|
|
ACPI_METHOD_ARGUMENT_LENGTH(MY_DSM_SUB_PACKAGE_ENTRY_SIZE))
|
|
|
|
#define MY_DSM_BUFFER_SIZE \
|
|
(FIELD_OFFSET(ACPI_EVAL_INPUT_BUFFER_COMPLEX, Argument) + \
|
|
ACPI_METHOD_ARGUMENT_LENGTH(sizeof(GUID)) + \
|
|
ACPI_METHOD_ARGUMENT_LENGTH(sizeof(ULONG)) + \
|
|
ACPI_METHOD_ARGUMENT_LENGTH(sizeof(ULONG)) + \
|
|
ACPI_METHOD_ARGUMENT_LENGTH(MY_DSM_PACKAGE_ENTRY_SIZE))
|
|
|
|
UCHAR Buffer[MY_DSM_BUFFER_SIZE];
|
|
ULONG InputSize;
|
|
NTSTATUS Status;
|
|
PACPI_METHOD_ARGUMENT Argument, PackageArgument, PackageArgument2;
|
|
PACPI_EVAL_INPUT_BUFFER_COMPLEX InputBuffer = (PACPI_EVAL_INPUT_BUFFER_COMPLEX)Buffer;
|
|
|
|
RtlZeroMemory(Buffer, sizeof(Buffer));
|
|
|
|
InputSize = MY_DSM_BUFFER_SIZE;
|
|
if (TestEntry->Flags & DSM_TEST_FLAG_EMPTY_PACKAGE)
|
|
{
|
|
InputSize -= ACPI_METHOD_ARGUMENT_LENGTH(MY_DSM_PACKAGE_ENTRY_SIZE);
|
|
InputSize += ACPI_METHOD_ARGUMENT_LENGTH(ACPI_METHOD_ARGUMENT_LENGTH(0));
|
|
}
|
|
|
|
InputBuffer->MethodNameAsUlong = 'MSD_'; // _DSM
|
|
InputBuffer->Signature = ACPI_EVAL_INPUT_BUFFER_COMPLEX_SIGNATURE;
|
|
InputBuffer->ArgumentCount = 4;
|
|
InputBuffer->Size = InputSize;
|
|
|
|
/* Argument 1: The UUID */
|
|
Argument = InputBuffer->Argument;
|
|
ACPI_METHOD_SET_ARGUMENT_BUFFER(Argument, &MY_DSM_GUID, sizeof(GUID));
|
|
|
|
/* Argument 2: The Revision ID */
|
|
Argument = ACPI_METHOD_NEXT_ARGUMENT(Argument);
|
|
ACPI_METHOD_SET_ARGUMENT_INTEGER(Argument, 1);
|
|
|
|
/* Argument 3: The Function Index */
|
|
Argument = ACPI_METHOD_NEXT_ARGUMENT(Argument);
|
|
ACPI_METHOD_SET_ARGUMENT_INTEGER(Argument, 2);
|
|
|
|
/* Argument 4: The device-specific package */
|
|
Argument = ACPI_METHOD_NEXT_ARGUMENT(Argument);
|
|
Argument->Type = ACPI_METHOD_ARGUMENT_PACKAGE;
|
|
if (TestEntry->Flags & DSM_TEST_FLAG_EMPTY_PACKAGE)
|
|
{
|
|
/* Empty package */
|
|
Argument->DataLength = ACPI_METHOD_ARGUMENT_LENGTH(0);
|
|
Argument->Argument = 0;
|
|
}
|
|
else
|
|
{
|
|
Argument->DataLength = MY_DSM_PACKAGE_ENTRY_SIZE;
|
|
|
|
/* Package 1 Argument 1: Some test data */
|
|
PackageArgument = (PACPI_METHOD_ARGUMENT)Argument->Data;
|
|
ACPI_METHOD_SET_ARGUMENT_INTEGER(PackageArgument, DrvpMyDsmIntegerFields[0]);
|
|
|
|
/* Package 1 Argument 2: Some test data */
|
|
PackageArgument = ACPI_METHOD_NEXT_ARGUMENT(PackageArgument);
|
|
ACPI_METHOD_SET_ARGUMENT_INTEGER(PackageArgument, DrvpMyDsmIntegerFields[1]);
|
|
|
|
/* Package 1 Argument 3: Start a new subpackage */
|
|
PackageArgument = ACPI_METHOD_NEXT_ARGUMENT(PackageArgument);
|
|
PackageArgument->Type = ACPI_METHOD_ARGUMENT_PACKAGE;
|
|
PackageArgument->DataLength = MY_DSM_SUB_PACKAGE_ENTRY_SIZE;
|
|
|
|
/* Package 2 Argument 1: Some test data */
|
|
PackageArgument2 = (PACPI_METHOD_ARGUMENT)PackageArgument->Data;
|
|
ACPI_METHOD_SET_ARGUMENT_STRING(PackageArgument2, "1_TESTDATATESTDATA_2");
|
|
|
|
if (TestEntry->Flags & DSM_TEST_FLAG_LARGE_SUB_PACKAGE_BUFFER)
|
|
{
|
|
PackageArgument2->DataLength = 32768;
|
|
}
|
|
else
|
|
{
|
|
/* Package 1 Argument 4: Some test data */
|
|
PackageArgument = ACPI_METHOD_NEXT_ARGUMENT(PackageArgument);
|
|
ACPI_METHOD_SET_ARGUMENT_INTEGER(PackageArgument, DrvpMyDsmIntegerFields[2]);
|
|
}
|
|
}
|
|
|
|
/* Evaluate the _DSM method */
|
|
DrvpEvalTestEntry = TestEntry;
|
|
Status = DrvCallAcpiDriver(InputBuffer, InputSize, NULL, 0);
|
|
|
|
ok_eq_hex_ex(TestEntry, Status, TestEntry->Status);
|
|
}
|
|
|
|
static
|
|
VOID
|
|
DrvTestPackageInputValue(VOID)
|
|
{
|
|
ULONG i;
|
|
|
|
for (i = 0; i < RTL_NUMBER_OF(DrvpDsmTests); ++i)
|
|
{
|
|
DrvEvaluateDsmObject(&DrvpDsmTests[i]);
|
|
}
|
|
}
|
|
|
|
static
|
|
VOID
|
|
DrvTestUnknownMethod(VOID)
|
|
{
|
|
NTSTATUS Status;
|
|
ACPI_EVAL_INPUT_BUFFER InputBuffer;
|
|
|
|
InputBuffer.MethodNameAsUlong = 'FFF_'; // _FFF
|
|
InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
|
|
|
|
/* Try to evaluate some unsupported control method */
|
|
Status = DrvCallAcpiDriver(&InputBuffer, sizeof(InputBuffer), NULL, 0);
|
|
|
|
ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND);
|
|
}
|
|
|
|
START_TEST(Bus_PDO_EvalMethod)
|
|
{
|
|
DrvTestComplexBuffer();
|
|
DrvTestInputBuffer();
|
|
DrvTestPackageReturnValueAndStringData();
|
|
DrvTestReferenceReturnValue();
|
|
DrvTestNestedPackageReturnValue();
|
|
DrvTestPackageInputValue();
|
|
DrvTestUnknownMethod();
|
|
|
|
ok(DrvpBlocksAllocated == 0, "Leaking memory %ld blocks\n", DrvpBlocksAllocated);
|
|
}
|