2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test for LdrEnumResources
5 * PROGRAMMER: Timo Kreuzer
10 #include <pseh/pseh2.h>
12 typedef struct _TEST_RESOURCES
14 IMAGE_RESOURCE_DIRECTORY TypeDirectory
;
15 IMAGE_RESOURCE_DIRECTORY_ENTRY TypeEntries
[2];
16 IMAGE_RESOURCE_DIRECTORY Name1Directory
;
17 IMAGE_RESOURCE_DIRECTORY_ENTRY Name1Entries
[2];
18 IMAGE_RESOURCE_DIRECTORY Name2Directory
;
19 IMAGE_RESOURCE_DIRECTORY_ENTRY Name2Entries
[2];
20 IMAGE_RESOURCE_DIRECTORY Lang1Directory
;
21 IMAGE_RESOURCE_DIRECTORY_ENTRY Lang1Entries
[2];
22 IMAGE_RESOURCE_DIRECTORY Lang2Directory
;
23 IMAGE_RESOURCE_DIRECTORY_ENTRY Lang2Entries
[2];
24 IMAGE_RESOURCE_DIRECTORY Lang3Directory
;
25 IMAGE_RESOURCE_DIRECTORY_ENTRY Lang3Entries
[2];
26 IMAGE_RESOURCE_DIRECTORY Lang4Directory
;
27 IMAGE_RESOURCE_DIRECTORY_ENTRY Lang4Entries
[2];
28 IMAGE_RESOURCE_DATA_ENTRY DataEntries
[8];
29 IMAGE_RESOURCE_DIRECTORY_STRING Name1String
;
31 WCHAR StringBuffer
[20];
32 } TEST_RESOURCES
, *PTEST_RESOURCES
;
34 typedef struct _TEST_IMAGE
36 IMAGE_DOS_HEADER DosHeader
;
37 IMAGE_NT_HEADERS NtHeaders
;
38 IMAGE_SECTION_HEADER SectionHeaders
[1];
39 TEST_RESOURCES Resources
;
40 } TEST_IMAGE
, *PTEST_IMAGE
;
44 InitializeResourceDirectory(
45 PIMAGE_RESOURCE_DIRECTORY ResourceDirectory
,
46 USHORT NumberOfNamedEntries
,
47 USHORT NumberOfIdEntries
)
49 ResourceDirectory
->Characteristics
= 0;
50 ResourceDirectory
->TimeDateStamp
= 0;
51 ResourceDirectory
->MajorVersion
= 0;
52 ResourceDirectory
->MinorVersion
= 0;
53 ResourceDirectory
->NumberOfNamedEntries
= NumberOfNamedEntries
;
54 ResourceDirectory
->NumberOfIdEntries
= NumberOfIdEntries
;
60 PTEST_RESOURCES Resource
,
61 PIMAGE_RESOURCE_DIRECTORY_ENTRY DirEntry
,
65 DirEntry
->Name
= Resource
->StringIndex
* 2 + FIELD_OFFSET(TEST_RESOURCES
, StringBuffer
);
66 DirEntry
->NameIsString
= 1;
67 DirEntry
->OffsetToData
= (PUCHAR
)Data
- (PUCHAR
)Resource
;
68 if (DirEntry
< Resource
->Lang1Entries
)
69 DirEntry
->DataIsDirectory
= 1;
70 Resource
->StringBuffer
[Resource
->StringIndex
] = (USHORT
)wcslen(Name
);
71 wcscpy(&Resource
->StringBuffer
[Resource
->StringIndex
+ 1], Name
);
72 Resource
->StringIndex
+= Resource
->StringBuffer
[Resource
->StringIndex
] * 2 + 1;
78 PTEST_RESOURCES Resource
,
79 PIMAGE_RESOURCE_DIRECTORY_ENTRY DirEntry
,
84 DirEntry
->NameIsString
= 0;
85 DirEntry
->OffsetToData
= (PUCHAR
)Data
- (PUCHAR
)Resource
;
86 if (DirEntry
< Resource
->Lang1Entries
)
87 DirEntry
->DataIsDirectory
= 1;
94 PIMAGE_RESOURCE_DATA_ENTRY DataEntry
,
99 DataEntry
->OffsetToData
= (PUCHAR
)Data
- (PUCHAR
)ImageBase
;
100 DataEntry
->Size
= Size
;
101 DataEntry
->CodePage
= 0;
102 DataEntry
->Reserved
= 0;
107 InitializeTestResource(
109 PTEST_RESOURCES Resource
)
112 memset(Resource
->StringBuffer
, 0, sizeof(Resource
->StringBuffer
));
113 Resource
->StringIndex
= 0;
115 InitializeResourceDirectory(&Resource
->TypeDirectory
, 0, 2);
116 InitializeIdEntry(Resource
, &Resource
->TypeEntries
[0], 1, &Resource
->Name1Directory
);
117 InitializeIdEntry(Resource
, &Resource
->TypeEntries
[1], 2, &Resource
->Name2Directory
);
119 InitializeResourceDirectory(&Resource
->Name1Directory
, 1, 1);
120 InitializeNamedEntry(Resource
, &Resource
->Name1Entries
[0], L
"TEST", &Resource
->Lang1Directory
);
121 InitializeIdEntry(Resource
, &Resource
->Name1Entries
[1], 7, &Resource
->Lang2Directory
);
123 InitializeResourceDirectory(&Resource
->Name2Directory
, 2, 0);
124 InitializeNamedEntry(Resource
, &Resource
->Name2Entries
[0], L
"LOL", &Resource
->Lang3Directory
);
125 InitializeNamedEntry(Resource
, &Resource
->Name2Entries
[1], L
"xD", &Resource
->Lang4Directory
);
127 InitializeResourceDirectory(&Resource
->Lang1Directory
, 0, 2);
128 InitializeIdEntry(Resource
, &Resource
->Lang1Entries
[0], 0x409, &Resource
->DataEntries
[0]);
129 InitializeIdEntry(Resource
, &Resource
->Lang1Entries
[1], 0x407, &Resource
->DataEntries
[1]);
131 InitializeResourceDirectory(&Resource
->Lang2Directory
, 0, 2);
132 InitializeIdEntry(Resource
, &Resource
->Lang2Entries
[0], 0x408, &Resource
->DataEntries
[2]);
133 InitializeIdEntry(Resource
, &Resource
->Lang2Entries
[1], 0x406, &Resource
->DataEntries
[3]);
135 InitializeResourceDirectory(&Resource
->Lang3Directory
, 0, 2);
136 InitializeIdEntry(Resource
, &Resource
->Lang3Entries
[0], 0x405, &Resource
->DataEntries
[4]);
137 InitializeIdEntry(Resource
, &Resource
->Lang3Entries
[1], 0x403, &Resource
->DataEntries
[5]);
139 InitializeResourceDirectory(&Resource
->Lang4Directory
, 0, 2);
140 InitializeIdEntry(Resource
, &Resource
->Lang4Entries
[0], 0x402, &Resource
->DataEntries
[6]);
141 InitializeIdEntry(Resource
, &Resource
->Lang4Entries
[1], 0x404, &Resource
->DataEntries
[7]);
143 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[0], Resource
->StringBuffer
+ 0, 2);
144 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[1], Resource
->StringBuffer
+ 2, 4);
145 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[2], Resource
->StringBuffer
+ 4, 6);
146 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[3], Resource
->StringBuffer
+ 6, 8);
147 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[4], Resource
->StringBuffer
+ 8, 10);
148 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[5], Resource
->StringBuffer
+ 10, 12);
149 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[6], Resource
->StringBuffer
+ 12, 14);
150 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[7], Resource
->StringBuffer
+ 14, 16);
156 PTEST_IMAGE TestImage
)
158 PIMAGE_DATA_DIRECTORY ResourceDirectory
;
160 TestImage
->DosHeader
.e_magic
= IMAGE_DOS_SIGNATURE
;
161 TestImage
->DosHeader
.e_lfanew
= sizeof(IMAGE_DOS_HEADER
);
163 TestImage
->NtHeaders
.Signature
= IMAGE_NT_SIGNATURE
;
165 TestImage
->NtHeaders
.FileHeader
.Machine
= IMAGE_FILE_MACHINE_NATIVE
;
166 TestImage
->NtHeaders
.FileHeader
.NumberOfSections
= 1;
167 TestImage
->NtHeaders
.FileHeader
.TimeDateStamp
= 0;
168 TestImage
->NtHeaders
.FileHeader
.PointerToSymbolTable
= 0;
169 TestImage
->NtHeaders
.FileHeader
.NumberOfSymbols
= 0;
170 TestImage
->NtHeaders
.FileHeader
.SizeOfOptionalHeader
= sizeof(IMAGE_OPTIONAL_HEADER
);
171 TestImage
->NtHeaders
.FileHeader
.Characteristics
= 0;
174 TestImage
->NtHeaders
.OptionalHeader
.Magic
= IMAGE_NT_OPTIONAL_HDR64_MAGIC
;
176 TestImage
->NtHeaders
.OptionalHeader
.Magic
= IMAGE_NT_OPTIONAL_HDR32_MAGIC
;
178 TestImage
->NtHeaders
.OptionalHeader
.ImageBase
= (DWORD_PTR
)TestImage
;
179 TestImage
->NtHeaders
.OptionalHeader
.SizeOfImage
= sizeof(TEST_IMAGE
);
180 TestImage
->NtHeaders
.OptionalHeader
.SizeOfHeaders
= sizeof(IMAGE_DOS_HEADER
) + sizeof(IMAGE_NT_HEADERS
);
181 TestImage
->NtHeaders
.OptionalHeader
.NumberOfRvaAndSizes
= ARRAYSIZE(TestImage
->NtHeaders
.OptionalHeader
.DataDirectory
);
183 ResourceDirectory
= &TestImage
->NtHeaders
.OptionalHeader
.DataDirectory
[IMAGE_DIRECTORY_ENTRY_RESOURCE
];
184 ResourceDirectory
->VirtualAddress
= FIELD_OFFSET(TEST_IMAGE
, Resources
);
185 ResourceDirectory
->Size
= sizeof(TEST_RESOURCES
);
187 strcpy((char*)TestImage
->SectionHeaders
[0].Name
, ".rsrc");
188 TestImage
->SectionHeaders
[0].Misc
.VirtualSize
= sizeof(TEST_IMAGE
);
189 TestImage
->SectionHeaders
[0].VirtualAddress
= FIELD_OFFSET(TEST_IMAGE
, Resources
);
190 TestImage
->SectionHeaders
[0].SizeOfRawData
= sizeof(TEST_IMAGE
);
191 TestImage
->SectionHeaders
[0].PointerToRawData
= FIELD_OFFSET(TEST_IMAGE
, Resources
);
192 TestImage
->SectionHeaders
[0].PointerToRelocations
= 0;
193 TestImage
->SectionHeaders
[0].PointerToLinenumbers
= 0;
194 TestImage
->SectionHeaders
[0].NumberOfRelocations
= 0;
195 TestImage
->SectionHeaders
[0].NumberOfLinenumbers
= 0;
196 TestImage
->SectionHeaders
[0].Characteristics
= 0;
198 InitializeTestResource(TestImage
, &TestImage
->Resources
);
201 #define ok_nwstr(str1, str2, count) \
202 ok(wcsncmp((PWCHAR)str1, (PWCHAR)str2, count) == 0, \
203 "string is wrong, expected: '%S', got '%S'\n", str1, str2); \
205 #define ok_enumres(_Res, _Type, _Name, _Lang, _Data, _Size) \
206 ok_dec((_Res)->Type, _Type); \
207 if ((ULONG_PTR)(_Name) > 0xFFFF) \
209 ok_size_t(*(WORD*)((_Res)->Name), wcslen((PWCHAR)(_Name))); \
210 ok_nwstr((PWCHAR)((_Res)->Name + 2), (PWCHAR)_Name, *(WORD*)((_Res)->Name)); \
214 ok_dec((_Res)->Name, (ULONG_PTR)_Name); \
216 ok_hex((_Res)->Language, _Lang); \
217 ok_ptr((PVOID)(_Res)->Data, _Data); \
218 ok_dec((_Res)->Size, _Size); \
219 ok_dec((_Res)->Reserved, 0);
223 Test_Data(PTEST_IMAGE TestImage
)
225 LDR_RESOURCE_INFO ResourceInfo
;
226 LDR_ENUM_RESOURCE_INFO EnumRes
[8];
230 InitializeTestImage(TestImage
);
232 memset(EnumRes
, 0xcc, sizeof(EnumRes
));
234 ResourceInfo
.Type
= 1;
235 ResourceInfo
.Name
= 1;
236 ResourceInfo
.Language
= 0x408;
238 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 0, &ResourceCount
, EnumRes
);
239 ok_hex(Status
, STATUS_SUCCESS
);
240 ok_dec(ResourceCount
, 8);
242 ok_ptr((PVOID
)EnumRes
[0].Data
, TestImage
->Resources
.StringBuffer
);
243 ok_dec(EnumRes
[0].Size
, 2);
245 ok_enumres(&EnumRes
[0], 1, L
"TEST", 0x409, TestImage
->Resources
.StringBuffer
, 2)
246 ok_enumres(&EnumRes
[1], 1, L
"TEST", 0x407, TestImage
->Resources
.StringBuffer
+ 2, 4)
247 ok_enumres(&EnumRes
[2], 1, 7, 0x408, TestImage
->Resources
.StringBuffer
+ 4, 6)
248 ok_enumres(&EnumRes
[3], 1, 7, 0x406, TestImage
->Resources
.StringBuffer
+ 6, 8)
249 ok_enumres(&EnumRes
[4], 2, L
"LOL", 0x405, TestImage
->Resources
.StringBuffer
+ 8, 10)
250 ok_enumres(&EnumRes
[5], 2, L
"LOL", 0x403, TestImage
->Resources
.StringBuffer
+ 10, 12)
251 ok_enumres(&EnumRes
[6], 2, L
"xD", 0x402, TestImage
->Resources
.StringBuffer
+ 12, 14)
252 ok_enumres(&EnumRes
[7], 2, L
"xD", 0x404, TestImage
->Resources
.StringBuffer
+ 14, 16)
254 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 1, &ResourceCount
, EnumRes
);
255 ok_hex(Status
, STATUS_SUCCESS
);
256 ok_dec(ResourceCount
, 4);
263 Test_Parameters(PTEST_IMAGE TestImage
)
265 LDR_RESOURCE_INFO ResourceInfo
;
266 LDR_ENUM_RESOURCE_INFO Resources
[8];
270 InitializeTestImage(TestImage
);
272 ResourceInfo
.Type
= 6;
273 ResourceInfo
.Name
= 1;
274 ResourceInfo
.Language
= 0x409;
277 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 3, &ResourceCount
, Resources
);
278 ok_hex(Status
, STATUS_SUCCESS
);
279 ok_dec(ResourceCount
, 0);
281 ResourceInfo
.Type
= 1;
282 ResourceInfo
.Name
= 7;
283 ResourceInfo
.Language
= 0x406;
285 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 0, &ResourceCount
, Resources
);
286 ok_hex(Status
, STATUS_SUCCESS
);
287 ok_dec(ResourceCount
, 8);
290 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 1, &ResourceCount
, Resources
);
291 ok_hex(Status
, STATUS_SUCCESS
);
292 ok_dec(ResourceCount
, 4);
295 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 2, &ResourceCount
, Resources
);
296 ok_hex(Status
, STATUS_SUCCESS
);
297 ok_dec(ResourceCount
, 2);
300 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 3, &ResourceCount
, Resources
);
301 ok_hex(Status
, STATUS_SUCCESS
);
302 ok_dec(ResourceCount
, 1);
305 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 99, &ResourceCount
, Resources
);
306 ok_hex(Status
, STATUS_SUCCESS
);
307 ok_dec(ResourceCount
, 1);
310 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 0, &ResourceCount
, Resources
);
311 ok_hex(Status
, STATUS_INFO_LENGTH_MISMATCH
);
312 ok_dec(ResourceCount
, 8);
315 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 0, &ResourceCount
, Resources
);
316 ok_hex(Status
, STATUS_INFO_LENGTH_MISMATCH
);
317 ok_dec(ResourceCount
, 8);
320 Status
= LdrEnumResources(NULL
, &ResourceInfo
, 1, &ResourceCount
, Resources
);
321 ok_hex(Status
, STATUS_RESOURCE_DATA_NOT_FOUND
);
322 ok_dec(ResourceCount
, 0);
325 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 1, &ResourceCount
, NULL
);
326 ok_hex(Status
, STATUS_INFO_LENGTH_MISMATCH
);
327 ok_dec(ResourceCount
, 4);
332 Status
= LdrEnumResources(NULL
, NULL
, 0, NULL
, NULL
);
334 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
339 ok_hex(Status
, 0xDeadC0de);
344 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 1, NULL
, Resources
);
346 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
351 ok_hex(Status
, 0xDeadC0de);
352 ok_dec(ResourceCount
, 42);
355 Status
= LdrEnumResources(TestImage
+ 2, &ResourceInfo
, 1, &ResourceCount
, NULL
);
356 ok_hex(Status
, STATUS_RESOURCE_DATA_NOT_FOUND
);
357 ok_dec(ResourceCount
, 0);
359 TestImage
->Resources
.TypeEntries
[0].DataIsDirectory
= 0;
360 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 1, &ResourceCount
, NULL
);
361 ok_hex(Status
, STATUS_INVALID_IMAGE_FORMAT
);
362 ok_dec(ResourceCount
, 0);
366 START_TEST(LdrEnumResources
)
368 TEST_IMAGE TestImage
;
369 RtlZeroMemory(&TestImage
, sizeof(TestImage
));
371 Test_Parameters(&TestImage
);
372 Test_Data(&TestImage
);