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 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 151 START_TEST(HalSystemInfo) 152 { 153 TestAMLIllegalIOPortAddresses(); 154 } 155