1 /*
2 * PROJECT: ReactOS API Tests
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Precompiled header for isapnp_unittest
5 * COPYRIGHT: Copyright 2024 Dmitry Borisov <di.sean@protonmail.com>
6 */
7
8 #pragma once
9
10 #include <apitest.h>
11
12 #define WIN32_NO_STATUS
13 #include <ndk/rtlfuncs.h>
14
15 typedef PVOID PDEVICE_OBJECT;
16
17 #define UNIT_TEST
18 #include <isapnphw.h>
19 #include <isapnpres.h>
20
21 /* KERNEL DEFINITIONS (MOCK) **************************************************/
22
23 #define PAGED_CODE()
24 #define CODE_SEG(segment)
25 #define DPRINT(...) do { if (0) { trace(__VA_ARGS__); } } while (0)
26 #define DPRINT1(...) do { if (0) { trace(__VA_ARGS__); } } while (0)
27 #define KeStallExecutionProcessor(MicroSeconds)
28
29 FORCEINLINE
30 PVOID
ExAllocatePoolWithTag(ULONG PoolType,SIZE_T NumberOfBytes,ULONG Tag)31 ExAllocatePoolWithTag(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
32 {
33 PULONG_PTR Mem = HeapAlloc(GetProcessHeap(), 0, NumberOfBytes + 2 * sizeof(PVOID));
34 if (Mem == NULL)
35 return NULL;
36
37 Mem[0] = NumberOfBytes;
38 Mem[1] = Tag;
39
40 return (PVOID)(Mem + 2);
41 }
42
43 FORCEINLINE
44 PVOID
ExAllocatePoolZero(ULONG PoolType,SIZE_T NumberOfBytes,ULONG Tag)45 ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
46 {
47 PVOID Result = ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag);
48
49 if (Result != NULL)
50 RtlZeroMemory(Result, NumberOfBytes);
51
52 return Result;
53 }
54
55 FORCEINLINE
56 VOID
ExFreePoolWithTag(PVOID MemPtr,ULONG Tag)57 ExFreePoolWithTag(PVOID MemPtr, ULONG Tag)
58 {
59 PULONG_PTR Mem = MemPtr;
60
61 Mem -= 2;
62 ok(Mem[1] == Tag, "Tag is %lx, expected %lx\n", Tag, Mem[1]);
63 HeapFree(GetProcessHeap(), 0, Mem);
64 }
65
66 FORCEINLINE
67 SIZE_T
GetPoolAllocSize(PVOID MemPtr)68 GetPoolAllocSize(PVOID MemPtr)
69 {
70 PVOID* Mem = MemPtr;
71
72 Mem -= 2;
73 return (SIZE_T)Mem[0];
74 }
75
76 /* ISAPNP DRIVER DEFINITIONS (MOCK) *******************************************/
77
78 #define TAG_ISAPNP 'pasI'
79
80 typedef struct _ISAPNP_FDO_EXTENSION
81 {
82 LIST_ENTRY DeviceListHead;
83 ULONG DeviceCount;
84 ULONG Cards;
85 PUCHAR ReadDataPort;
86 } ISAPNP_FDO_EXTENSION, *PISAPNP_FDO_EXTENSION;
87
88 typedef struct _ISAPNP_PDO_EXTENSION
89 {
90 PISAPNP_LOGICAL_DEVICE IsaPnpDevice;
91
92 PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
93
94 PCM_RESOURCE_LIST ResourceList;
95 ULONG ResourceListSize;
96 } ISAPNP_PDO_EXTENSION, *PISAPNP_PDO_EXTENSION;
97
98 /* TEST DEFINITIONS ***********************************************************/
99
100 typedef enum _ISAPNP_STATE
101 {
102 IsaWaitForKey = 0,
103 IsaSleep = 1,
104 IsaIsolation = 2,
105 IsaConfgure = 3
106 } ISAPNP_STATE;
107
108 typedef struct _ISAPNP_CARD_LOGICAL_DEVICE
109 {
110 UCHAR Registers[0xFF];
111 } ISAPNP_CARD_LOGICAL_DEVICE, *PISAPNP_CARD_LOGICAL_DEVICE;
112
113 #define TEST_MAX_SUPPORTED_DEVICES 7
114
115 typedef struct _ISAPNP_CARD
116 {
117 ISAPNP_STATE State;
118 UCHAR LfsrCount;
119 UCHAR Lfsr;
120 UCHAR SelectNumberReg;
121 UCHAR DeviceNumberReg;
122 UCHAR SerialIsolationIdx;
123 UCHAR SerialIdResponse;
124 UCHAR IsolationRead;
125 PUCHAR PnpRom;
126 PUCHAR ReadDataPort;
127 ULONG RomIdx;
128 ULONG RomSize;
129 ULONG LogicalDevices;
130 ISAPNP_CARD_LOGICAL_DEVICE LogDev[TEST_MAX_SUPPORTED_DEVICES];
131 } ISAPNP_CARD, *PISAPNP_CARD;
132
133 UCHAR
134 NTAPI
135 READ_PORT_UCHAR(
136 _In_ PUCHAR Port);
137
138 VOID
139 NTAPI
140 WRITE_PORT_UCHAR(
141 _In_ PUCHAR Port,
142 _In_ UCHAR Value);
143
144 VOID
145 IsaBusCreateCard(
146 _Inout_ PISAPNP_CARD Card,
147 _In_ PVOID PnpRom,
148 _In_ ULONG RomSize,
149 _In_ ULONG LogicalDevices);
150
151 VOID
152 DrvCreateCard1(
153 _In_ PISAPNP_CARD Card);
154
155 VOID
156 DrvTestCard1Dev1Resources(
157 _In_ PCM_RESOURCE_LIST ResourceList,
158 _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList);
159
160 VOID
161 DrvTestCard1Dev2Resources(
162 _In_ PCM_RESOURCE_LIST ResourceList,
163 _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList);
164
165 VOID
166 DrvTestCard1Dev3Resources(
167 _In_ PCM_RESOURCE_LIST ResourceList,
168 _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList);
169
170 VOID
171 DrvTestCard1Dev4Resources(
172 _In_ PCM_RESOURCE_LIST ResourceList,
173 _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList);
174
175 VOID
176 DrvTestCard1Dev5Resources(
177 _In_ PCM_RESOURCE_LIST ResourceList,
178 _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList);
179
180 VOID
181 DrvTestCard1Dev6Resources(
182 _In_ PCM_RESOURCE_LIST ResourceList,
183 _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList);
184
185 VOID
186 DrvTestCard1Dev7Resources(
187 _In_ PCM_RESOURCE_LIST ResourceList,
188 _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList);
189
190 PCM_RESOURCE_LIST
191 DrvTestCard1Dev6CreateConfigurationResources(VOID);
192
193 VOID
194 DrvTestCard1Dev6ConfigurationResult(
195 _In_ PISAPNP_CARD_LOGICAL_DEVICE LogDev);
196
197 VOID
198 DrvCreateCard2(
199 _In_ PISAPNP_CARD Card);
200
201 #define expect_resource_list_header(ResourceList, ExpectedIface, ExpectedCount) \
202 do { \
203 ok_eq_int((ResourceList)->List[0].InterfaceType, (ExpectedIface)); \
204 ok_eq_ulong((ResourceList)->List[0].BusNumber, 0UL); \
205 ok_eq_int((ResourceList)->List[0].PartialResourceList.Version, 1); /* 0 */ \
206 ok_eq_int((ResourceList)->List[0].PartialResourceList.Revision, 1); /* 0x3000 */ \
207 ok_eq_ulong((ResourceList)->List[0].PartialResourceList.Count, (ExpectedCount)); \
208 } while (0)
209
210 #define expect_requirements_list_header(ReqList, ExpectedIface, ExpectedCount) \
211 do { \
212 ok_eq_int((ReqList)->InterfaceType, (ExpectedIface)); \
213 ok_eq_ulong((ReqList)->BusNumber, 0UL); \
214 ok_eq_ulong((ReqList)->SlotNumber, 0UL); \
215 ok_eq_ulong((ReqList)->AlternativeLists, (ExpectedCount)); \
216 } while (0)
217
218 #define expect_alt_list_header(AltList, ExpectedCount) \
219 do { \
220 ok_eq_int((AltList)->Version, 1); \
221 ok_eq_int((AltList)->Revision, 1); \
222 ok_eq_ulong((AltList)->Count, (ExpectedCount)); \
223 } while (0)
224
225 #define expect_port_req(Desc, ExpectedOption, ExpectedFlags, ExpectedShare, \
226 ExpectedLength, ExpectedAlign, ExpectedMin, ExpectedMax) \
227 do { \
228 ok((Desc)->Type == CmResourceTypePort, \
229 "Desc->Type = %u, expected %u\n", (Desc)->Type, CmResourceTypePort); \
230 ok((Desc)->Option == (ExpectedOption), \
231 "Desc->Option = %u, expected %u\n", (Desc)->Option, (ExpectedOption)); \
232 ok((Desc)->Flags == (ExpectedFlags), \
233 "Desc->Flags = %x, expected %x\n", (Desc)->Flags, (ExpectedFlags)); \
234 ok((Desc)->ShareDisposition == (ExpectedShare), \
235 "Desc->ShareDisposition = %u, expected %u\n", \
236 (Desc)->ShareDisposition, (ExpectedShare)); \
237 ok((Desc)->u.Port.Length == (ExpectedLength), \
238 "Desc->u.Port.Length = %lx, expected %lx\n", \
239 (Desc)->u.Port.Length, (ExpectedLength)); \
240 ok((Desc)->u.Port.Alignment == (ExpectedAlign), \
241 "Desc->u.Port.Alignment = %lu, expected %lu\n", \
242 (Desc)->u.Port.Alignment, (ExpectedAlign)); \
243 ok((Desc)->u.Port.MinimumAddress.QuadPart == (ExpectedMin), \
244 "Desc->u.Port.MinimumAddress = 0x%I64x, expected 0x%I64x\n", \
245 (Desc)->u.Port.MinimumAddress.QuadPart, (ExpectedMin)); \
246 ok((Desc)->u.Port.MaximumAddress.QuadPart == (ExpectedMax), \
247 "Desc->u.Port.MaximumAddress = 0x%I64x, expected 0x%I64x\n", \
248 (Desc)->u.Port.MaximumAddress.QuadPart, (ExpectedMax)); \
249 } while (0)
250
251 #define expect_irq_req(Desc, ExpectedOption, ExpectedFlags, ExpectedShare, \
252 ExpectedMin, ExpectedMax) \
253 do { \
254 ok((Desc)->Type == CmResourceTypeInterrupt, \
255 "Desc->Type = %u, expected %u\n", (Desc)->Type, CmResourceTypeInterrupt); \
256 ok((Desc)->Option == (ExpectedOption), \
257 "Desc->Option = %u, expected %u\n", (Desc)->Option, (ExpectedOption)); \
258 ok((Desc)->Flags == (ExpectedFlags), \
259 "Desc->Flags = %x, expected %x\n", (Desc)->Flags, (ExpectedFlags)); \
260 ok((Desc)->ShareDisposition == (ExpectedShare), \
261 "Desc->ShareDisposition = %u, expected %u\n", \
262 (Desc)->ShareDisposition, (ExpectedShare)); \
263 ok((Desc)->u.Interrupt.MinimumVector == (ExpectedMin), \
264 "Desc->u.Interrupt.MinimumVector = %lu, expected %lu\n", \
265 (Desc)->u.Interrupt.MinimumVector, (ExpectedMin)); \
266 ok((Desc)->u.Interrupt.MaximumVector == (ExpectedMax), \
267 "Desc->u.Interrupt.MaximumVector = %lu, expected %lu\n", \
268 (Desc)->u.Interrupt.MaximumVector, (ExpectedMax)); \
269 } while (0)
270
271 #define expect_dma_req(Desc, ExpectedOption, ExpectedFlags, ExpectedShare, \
272 ExpectedMin, ExpectedMax) \
273 do { \
274 ok((Desc)->Type == CmResourceTypeDma, \
275 "Desc->Type = %u, expected %u\n", (Desc)->Type, CmResourceTypeDma); \
276 ok((Desc)->Option == (ExpectedOption), \
277 "Desc->Option = %u, expected %u\n", (Desc)->Option, (ExpectedOption)); \
278 ok((Desc)->Flags == (ExpectedFlags), \
279 "Desc->Flags = %x, expected %x\n", (Desc)->Flags, (ExpectedFlags)); \
280 ok((Desc)->ShareDisposition == (ExpectedShare), \
281 "Desc->ShareDisposition = %u, expected %u\n", \
282 (Desc)->ShareDisposition, (ExpectedShare)); \
283 ok((Desc)->u.Dma.MinimumChannel == (ExpectedMin), \
284 "Desc->u.Dma.MinimumChannel = %lu, expected %lu\n", \
285 (Desc)->u.Dma.MinimumChannel, (ExpectedMin)); \
286 ok((Desc)->u.Dma.MaximumChannel == (ExpectedMax), \
287 "Desc->u.Dma.MaximumChannel = %lu, expected %lu\n", \
288 (Desc)->u.Dma.MaximumChannel, (ExpectedMax)); \
289 } while (0)
290
291 #define expect_mem_req(Desc, ExpectedOption, ExpectedFlags, ExpectedShare, \
292 ExpectedLength, ExpectedAlign, ExpectedMin, ExpectedMax) \
293 do { \
294 ok((Desc)->Type == CmResourceTypeMemory, \
295 "Desc->Type = %u, expected %u\n", (Desc)->Type, CmResourceTypeMemory); \
296 ok((Desc)->Option == (ExpectedOption), \
297 "Desc->Option = %u, expected %u\n", (Desc)->Option, (ExpectedOption)); \
298 ok((Desc)->Flags == (ExpectedFlags), \
299 "Desc->Flags = %x, expected %x\n", (Desc)->Flags, (ExpectedFlags)); \
300 ok((Desc)->ShareDisposition == (ExpectedShare), \
301 "Desc->ShareDisposition = %u, expected %u\n", \
302 (Desc)->ShareDisposition, (ExpectedShare)); \
303 ok((Desc)->u.Memory.Length == (ExpectedLength), \
304 "Desc->u.Memory.Length = %lx, expected %lx\n", \
305 (Desc)->u.Memory.Length, (ExpectedLength)); \
306 ok((Desc)->u.Memory.Alignment == (ExpectedAlign), \
307 "Desc->u.Memory.Alignment = %lx, expected %lx\n", \
308 (Desc)->u.Memory.Alignment, (ExpectedAlign)); \
309 ok((Desc)->u.Memory.MinimumAddress.QuadPart == (ExpectedMin), \
310 "Desc->u.Memory.MinimumAddress = 0x%I64x, expected 0x%I64x\n", \
311 (Desc)->u.Memory.MinimumAddress.QuadPart, (ExpectedMin)); \
312 ok((Desc)->u.Memory.MaximumAddress.QuadPart == (ExpectedMax), \
313 "Desc->u.Memory.MaximumAddress = 0x%I64x, expected 0x%I64x\n", \
314 (Desc)->u.Memory.MaximumAddress.QuadPart, (ExpectedMax)); \
315 } while (0)
316
317 #define expect_cfg_req(Desc, ExpectedOption, ExpectedFlags, ExpectedShare, \
318 ExpectedPriority, ExpectedRes1, ExpectedRes2) \
319 do { \
320 ok((Desc)->Type == CmResourceTypeConfigData, \
321 "Desc->Type = %u, expected %u\n", (Desc)->Type, CmResourceTypeConfigData); \
322 ok((Desc)->Option == (ExpectedOption), \
323 "Desc->Option = %u, expected %u\n", (Desc)->Option, (ExpectedOption)); \
324 ok((Desc)->Flags == (ExpectedFlags), \
325 "Desc->Flags = %x, expected %x\n", (Desc)->Flags, (ExpectedFlags)); \
326 ok((Desc)->ShareDisposition == (ExpectedShare), \
327 "Desc->ShareDisposition = %u, expected %u\n", \
328 (Desc)->ShareDisposition, (ExpectedShare)); \
329 ok((Desc)->u.ConfigData.Priority == (ExpectedPriority), \
330 "Desc->u.ConfigData.Priority = %lx, expected %lx\n", \
331 (Desc)->u.ConfigData.Priority, (ExpectedPriority)); \
332 ok((Desc)->u.ConfigData.Reserved1 == (ExpectedRes1), \
333 "Desc->u.ConfigData.Reserved1 = %lx, expected %lx\n", \
334 (Desc)->u.ConfigData.Reserved2, (ExpectedRes1)); \
335 ok((Desc)->u.ConfigData.Reserved2 == (ExpectedRes2), \
336 "Desc->u.ConfigData.Reserved2 = %lx, expected %lx\n", \
337 (Desc)->u.ConfigData.Reserved2, (ExpectedRes2)); \
338 } while (0)
339
340 #define expect_port_res(Desc, ExpectedFlags, ExpectedShare, ExpectedLength, ExpectedStart) \
341 do { \
342 ok((Desc)->Type == CmResourceTypePort, \
343 "Desc->Type = %u, expected %u\n", (Desc)->Type, CmResourceTypePort); \
344 ok((Desc)->Flags == (ExpectedFlags), \
345 "Desc->Flags = %x, expected %x\n", (Desc)->Flags, (ExpectedFlags)); \
346 ok((Desc)->ShareDisposition == (ExpectedShare), \
347 "Desc->ShareDisposition = %u, expected %u\n", \
348 (Desc)->ShareDisposition, (ExpectedShare)); \
349 ok((Desc)->u.Port.Length == (ExpectedLength), \
350 "Desc->u.Port.Length = %lx, expected %lx\n", \
351 (Desc)->u.Port.Length, (ExpectedLength)); \
352 ok((Desc)->u.Port.Start.QuadPart == (ExpectedStart), \
353 "Desc->u.Port.Start = 0x%I64x, expected 0x%I64x\n", \
354 (Desc)->u.Port.Start.QuadPart, (ExpectedStart)); \
355 } while (0)
356
357 #define expect_irq_res(Desc, ExpectedFlags, ExpectedShare, \
358 ExpectedLevel, ExpectedVector, ExpectedAffinity) \
359 do { \
360 ok((Desc)->Type == CmResourceTypeInterrupt, \
361 "Desc->Type = %u, expected %u\n", (Desc)->Type, CmResourceTypeInterrupt); \
362 ok((Desc)->Flags == (ExpectedFlags), \
363 "Desc->Flags = %x, expected %x\n", (Desc)->Flags, (ExpectedFlags)); \
364 ok((Desc)->ShareDisposition == (ExpectedShare), \
365 "Desc->ShareDisposition = %u, expected %u\n", \
366 (Desc)->ShareDisposition, (ExpectedShare)); \
367 ok((Desc)->u.Interrupt.Level == (ExpectedLevel), \
368 "Desc->u.Interrupt.Level = %lu\n", (Desc)->u.Interrupt.Level); \
369 ok((Desc)->u.Interrupt.Vector == (ExpectedVector), \
370 "Desc->u.Interrupt.Vector = %lu\n", (Desc)->u.Interrupt.Vector); \
371 ok((Desc)->u.Interrupt.Affinity == (ExpectedAffinity), \
372 "Desc->u.Interrupt.Affinity = %Ix\n", (Desc)->u.Interrupt.Affinity); \
373 } while (0)
374
375 #define expect_dma_res(Desc, ExpectedFlags, ExpectedShare, ExpectedChannel) \
376 do { \
377 ok((Desc)->Type == CmResourceTypeDma, \
378 "Desc->Type = %u, expected %u\n", (Desc)->Type, CmResourceTypeDma); \
379 ok((Desc)->Flags == (ExpectedFlags), \
380 "Desc->Flags = %x, expected %x\n", (Desc)->Flags, (ExpectedFlags)); \
381 ok((Desc)->ShareDisposition == (ExpectedShare), \
382 "Desc->ShareDisposition = %u, expected %u\n", \
383 (Desc)->ShareDisposition, (ExpectedShare)); \
384 ok((Desc)->u.Dma.Channel == (ExpectedChannel), \
385 "Desc->u.Dma.Channel = %lu, expected %lu\n", \
386 (Desc)->u.Dma.Channel, (ExpectedChannel)); \
387 ok((Desc)->u.Dma.Port == 0ul, \
388 "Desc->u.Dma.Port = %lu, expected %lu\n", \
389 (Desc)->u.Dma.Port, 0ul); \
390 ok((Desc)->u.Dma.Reserved1 == 0ul, \
391 "Desc->u.Dma.Reserved1 = %lx, expected 0\n", (Desc)->u.Dma.Reserved1); \
392 } while (0)
393
394 #define expect_mem_res(Desc, ExpectedFlags, ExpectedShare, ExpectedLength, ExpectedStart) \
395 do { \
396 ok((Desc)->Type == CmResourceTypeMemory, \
397 "Desc->Type = %u, expected %u\n", (Desc)->Type, CmResourceTypeMemory); \
398 ok((Desc)->Flags == (ExpectedFlags), \
399 "Desc->Flags = %x, expected %x\n", (Desc)->Flags, (ExpectedFlags)); \
400 ok((Desc)->ShareDisposition == (ExpectedShare), \
401 "Desc->ShareDisposition = %u, expected %u\n", \
402 (Desc)->ShareDisposition, (ExpectedShare)); \
403 ok((Desc)->u.Memory.Length == (ExpectedLength), \
404 "Desc->u.Memory.Length = %lx, expected %lx\n", \
405 (Desc)->u.Memory.Length, (ExpectedLength)); \
406 ok((Desc)->u.Memory.Start.QuadPart == (ExpectedStart), \
407 "Desc->u.Memory.Start = 0x%I64x, expected 0x%I64x\n", \
408 (Desc)->u.Memory.Start.QuadPart, (ExpectedStart)); \
409 } while (0)
410