1 /*
2 * PROJECT: ReactOS Kernel-Mode Tests
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Test for HalQuerySystemInformation
5 * COPYRIGHT: Copyright 2020 Thomas Faber (thomas.faber@reactos.org)
6 */
7
8 #include <kmt_test.h>
9
10 #define NDEBUG
11 #include <debug.h>
12
13 static HAL_AMLI_BAD_IO_ADDRESS_LIST ExpectedList[] =
14 {
15 { 0x0000, 0x10, 1, NULL },
16 { 0x0020, 0x02, 0, NULL },
17 { 0x0040, 0x04, 1, NULL },
18 { 0x0048, 0x04, 1, NULL },
19 { 0x0070, 0x02, 1, NULL },
20 { 0x0074, 0x03, 1, NULL },
21 { 0x0081, 0x03, 1, NULL },
22 { 0x0087, 0x01, 1, NULL },
23 { 0x0089, 0x01, 1, NULL },
24 { 0x008A, 0x02, 1, NULL },
25 { 0x008F, 0x01, 1, NULL },
26 { 0x0090, 0x02, 1, NULL },
27 { 0x0093, 0x02, 1, NULL },
28 { 0x0096, 0x02, 1, NULL },
29 { 0x00A0, 0x02, 0, NULL },
30 { 0x00C0, 0x20, 1, NULL },
31 { 0x04D0, 0x02, 0, NULL },
32 /* We obviously don't have the expected pointer. Just use a non-null value */
33 { 0x0CF8, 0x08, 1, (PVOID)1 },
34 { 0x0000, 0x00, 0, NULL },
35 };
36
37 static
38 void
TestAMLIllegalIOPortAddresses(void)39 TestAMLIllegalIOPortAddresses(void)
40 {
41 NTSTATUS Status;
42 PHAL_AMLI_BAD_IO_ADDRESS_LIST AddressList;
43 ULONG AddressListLength;
44 ULONG ReturnedLength;
45
46 /* Query required size and check that it's valid */
47 ReturnedLength = 0x55555555;
48 Status = HalQuerySystemInformation(HalQueryAMLIIllegalIOPortAddresses,
49 0,
50 NULL,
51 &ReturnedLength);
52 ok_eq_hex(Status, STATUS_INFO_LENGTH_MISMATCH);
53 ok(ReturnedLength % sizeof(*AddressList) == 0, "List size %lu is not a multiple of %Iu\n", ReturnedLength, sizeof(*AddressList));
54 if (skip(ReturnedLength > 0 && ReturnedLength < 0x10000000, "Invalid length\n"))
55 {
56 return;
57 }
58 AddressListLength = ReturnedLength;
59 AddressList = ExAllocatePoolWithTag(NonPagedPool,
60 AddressListLength,
61 'OImK');
62 if (skip(AddressList != NULL, "Failed to alloc %lu bytes\n", AddressListLength))
63 {
64 return;
65 }
66
67 if (ReturnedLength != sizeof(*AddressList))
68 {
69 /* Try with space for exactly one entry and make sure we get
70 * the same return code
71 */
72 RtlFillMemory(AddressList, AddressListLength, 0x55);
73 ReturnedLength = 0x55555555;
74 Status = HalQuerySystemInformation(HalQueryAMLIIllegalIOPortAddresses,
75 sizeof(*AddressList),
76 AddressList,
77 &ReturnedLength);
78 ok_eq_hex(Status, STATUS_INFO_LENGTH_MISMATCH);
79 ok_eq_ulong(ReturnedLength, AddressListLength);
80 ok_eq_hex(AddressList[0].BadAddrBegin, 0x55555555UL);
81 }
82
83 /* One byte less than required should still return no data */
84 RtlFillMemory(AddressList, AddressListLength, 0x55);
85 ReturnedLength = 0x55555555;
86 Status = HalQuerySystemInformation(HalQueryAMLIIllegalIOPortAddresses,
87 AddressListLength - 1,
88 AddressList,
89 &ReturnedLength);
90 ok_eq_hex(Status, STATUS_INFO_LENGTH_MISMATCH);
91 ok_eq_ulong(ReturnedLength, AddressListLength);
92 ok_eq_hex(AddressList[0].BadAddrBegin, 0x55555555UL);
93
94 /* Specify required size */
95 RtlFillMemory(AddressList, AddressListLength, 0x55);
96 ReturnedLength = 0x55555555;
97 Status = HalQuerySystemInformation(HalQueryAMLIIllegalIOPortAddresses,
98 AddressListLength,
99 AddressList,
100 &ReturnedLength);
101 ok_eq_hex(Status, STATUS_SUCCESS);
102 ok_eq_ulong(ReturnedLength, AddressListLength);
103
104 /* Validate the table against our expectations */
105 ok_eq_ulong(ReturnedLength, sizeof(ExpectedList));
106 for (ULONG i = 0;
107 i < min(ReturnedLength, sizeof(ExpectedList)) / sizeof(*AddressList);
108 i++)
109 {
110 ok(AddressList[i].BadAddrBegin == ExpectedList[i].BadAddrBegin,
111 "[%lu] BadAddrBegin 0x%lx, expected 0x%lx\n",
112 i, AddressList[i].BadAddrBegin, ExpectedList[i].BadAddrBegin);
113 ok(AddressList[i].BadAddrSize == ExpectedList[i].BadAddrSize,
114 "[%lu] BadAddrSize 0x%lx, expected 0x%lx\n",
115 i, AddressList[i].BadAddrSize, ExpectedList[i].BadAddrSize);
116 ok(AddressList[i].OSVersionTrigger == ExpectedList[i].OSVersionTrigger,
117 "[%lu] OSVersionTrigger 0x%lx, expected 0x%lx\n",
118 i, AddressList[i].OSVersionTrigger, ExpectedList[i].OSVersionTrigger);
119 if (ExpectedList[i].IOHandler != NULL)
120 {
121 ok(AddressList[i].IOHandler != NULL,
122 "[%lu] IOHandler = %p\n", i, AddressList[i].IOHandler);
123 }
124 else
125 {
126 ok(AddressList[i].IOHandler == NULL,
127 "[%lu] IOHandler = %p\n", i, AddressList[i].IOHandler);
128 }
129
130 /* If we got an I/O handler, try to call it */
131 if (AddressList[i].IOHandler != NULL)
132 {
133 ULONG Data = 0x55555555;
134
135 /* We don't want to break devices, so call it with an address
136 * outside of its range, and it should return failure
137 */
138 Status = AddressList[i].IOHandler(TRUE,
139 AddressList[i].BadAddrBegin - 1,
140 1,
141 &Data);
142 ok(Status == STATUS_UNSUCCESSFUL,
143 "[%lu] IOHandler returned 0x%lx\n", i, Status);
144 ok(Data == 0x55555555,
145 "[%lu] IOHandler returned Data 0x%lx\n", i, Data);
146 }
147 }
148 ExFreePoolWithTag(AddressList, 'OImK');
149 }
150
START_TEST(HalSystemInfo)151 START_TEST(HalSystemInfo)
152 {
153 TestAMLIllegalIOPortAddresses();
154 }
155