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 typedef struct _TEST_RESOURCES
12 IMAGE_RESOURCE_DIRECTORY TypeDirectory
;
13 IMAGE_RESOURCE_DIRECTORY_ENTRY TypeEntries
[2];
14 IMAGE_RESOURCE_DIRECTORY Name1Directory
;
15 IMAGE_RESOURCE_DIRECTORY_ENTRY Name1Entries
[2];
16 IMAGE_RESOURCE_DIRECTORY Name2Directory
;
17 IMAGE_RESOURCE_DIRECTORY_ENTRY Name2Entries
[2];
18 IMAGE_RESOURCE_DIRECTORY Lang1Directory
;
19 IMAGE_RESOURCE_DIRECTORY_ENTRY Lang1Entries
[2];
20 IMAGE_RESOURCE_DIRECTORY Lang2Directory
;
21 IMAGE_RESOURCE_DIRECTORY_ENTRY Lang2Entries
[2];
22 IMAGE_RESOURCE_DIRECTORY Lang3Directory
;
23 IMAGE_RESOURCE_DIRECTORY_ENTRY Lang3Entries
[2];
24 IMAGE_RESOURCE_DIRECTORY Lang4Directory
;
25 IMAGE_RESOURCE_DIRECTORY_ENTRY Lang4Entries
[2];
26 IMAGE_RESOURCE_DATA_ENTRY DataEntries
[8];
27 IMAGE_RESOURCE_DIRECTORY_STRING Name1String
;
29 WCHAR StringBuffer
[20];
30 } TEST_RESOURCES
, *PTEST_RESOURCES
;
32 typedef struct _TEST_IMAGE
34 IMAGE_DOS_HEADER DosHeader
;
35 IMAGE_NT_HEADERS NtHeaders
;
36 IMAGE_SECTION_HEADER SectionHeaders
[1];
37 TEST_RESOURCES Resources
;
38 } TEST_IMAGE
, *PTEST_IMAGE
;
42 InitializeResourceDirectory(
43 PIMAGE_RESOURCE_DIRECTORY ResourceDirectory
,
44 USHORT NumberOfNamedEntries
,
45 USHORT NumberOfIdEntries
)
47 ResourceDirectory
->Characteristics
= 0;
48 ResourceDirectory
->TimeDateStamp
= 0;
49 ResourceDirectory
->MajorVersion
= 0;
50 ResourceDirectory
->MinorVersion
= 0;
51 ResourceDirectory
->NumberOfNamedEntries
= NumberOfNamedEntries
;
52 ResourceDirectory
->NumberOfIdEntries
= NumberOfIdEntries
;
58 PTEST_RESOURCES Resource
,
59 PIMAGE_RESOURCE_DIRECTORY_ENTRY DirEntry
,
63 DirEntry
->Name
= Resource
->StringIndex
* 2 + FIELD_OFFSET(TEST_RESOURCES
, StringBuffer
);
64 DirEntry
->NameIsString
= 1;
65 DirEntry
->OffsetToData
= (PUCHAR
)Data
- (PUCHAR
)Resource
;
66 if (DirEntry
< Resource
->Lang1Entries
)
67 DirEntry
->DataIsDirectory
= 1;
68 Resource
->StringBuffer
[Resource
->StringIndex
] = wcslen(Name
);
69 wcscpy(&Resource
->StringBuffer
[Resource
->StringIndex
+ 1], Name
);
70 Resource
->StringIndex
+= Resource
->StringBuffer
[Resource
->StringIndex
] * 2 + 1;
76 PTEST_RESOURCES Resource
,
77 PIMAGE_RESOURCE_DIRECTORY_ENTRY DirEntry
,
82 DirEntry
->NameIsString
= 0;
83 DirEntry
->OffsetToData
= (PUCHAR
)Data
- (PUCHAR
)Resource
;
84 if (DirEntry
< Resource
->Lang1Entries
)
85 DirEntry
->DataIsDirectory
= 1;
92 PIMAGE_RESOURCE_DATA_ENTRY DataEntry
,
97 DataEntry
->OffsetToData
= (PUCHAR
)Data
- (PUCHAR
)ImageBase
;
98 DataEntry
->Size
= Size
;
99 DataEntry
->CodePage
= 0;
100 DataEntry
->Reserved
= 0;
105 InitializeTestResource(
107 PTEST_RESOURCES Resource
)
110 memset(Resource
->StringBuffer
, 0, sizeof(Resource
->StringBuffer
));
111 Resource
->StringIndex
= 0;
113 InitializeResourceDirectory(&Resource
->TypeDirectory
, 0, 2);
114 InitializeIdEntry(Resource
, &Resource
->TypeEntries
[0], 1, &Resource
->Name1Directory
);
115 InitializeIdEntry(Resource
, &Resource
->TypeEntries
[1], 2, &Resource
->Name2Directory
);
117 InitializeResourceDirectory(&Resource
->Name1Directory
, 1, 1);
118 InitializeNamedEntry(Resource
, &Resource
->Name1Entries
[0], L
"TEST", &Resource
->Lang1Directory
);
119 InitializeIdEntry(Resource
, &Resource
->Name1Entries
[1], 7, &Resource
->Lang2Directory
);
121 InitializeResourceDirectory(&Resource
->Name2Directory
, 2, 0);
122 InitializeNamedEntry(Resource
, &Resource
->Name2Entries
[0], L
"LOL", &Resource
->Lang3Directory
);
123 InitializeNamedEntry(Resource
, &Resource
->Name2Entries
[1], L
"xD", &Resource
->Lang4Directory
);
125 InitializeResourceDirectory(&Resource
->Lang1Directory
, 0, 2);
126 InitializeIdEntry(Resource
, &Resource
->Lang1Entries
[0], 0x409, &Resource
->DataEntries
[0]);
127 InitializeIdEntry(Resource
, &Resource
->Lang1Entries
[1], 0x407, &Resource
->DataEntries
[1]);
129 InitializeResourceDirectory(&Resource
->Lang2Directory
, 0, 2);
130 InitializeIdEntry(Resource
, &Resource
->Lang2Entries
[0], 0x408, &Resource
->DataEntries
[2]);
131 InitializeIdEntry(Resource
, &Resource
->Lang2Entries
[1], 0x406, &Resource
->DataEntries
[3]);
133 InitializeResourceDirectory(&Resource
->Lang3Directory
, 0, 2);
134 InitializeIdEntry(Resource
, &Resource
->Lang3Entries
[0], 0x405, &Resource
->DataEntries
[4]);
135 InitializeIdEntry(Resource
, &Resource
->Lang3Entries
[1], 0x403, &Resource
->DataEntries
[5]);
137 InitializeResourceDirectory(&Resource
->Lang4Directory
, 0, 2);
138 InitializeIdEntry(Resource
, &Resource
->Lang4Entries
[0], 0x402, &Resource
->DataEntries
[6]);
139 InitializeIdEntry(Resource
, &Resource
->Lang4Entries
[1], 0x404, &Resource
->DataEntries
[7]);
141 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[0], Resource
->StringBuffer
+ 0, 2);
142 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[1], Resource
->StringBuffer
+ 2, 4);
143 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[2], Resource
->StringBuffer
+ 4, 6);
144 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[3], Resource
->StringBuffer
+ 6, 8);
145 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[4], Resource
->StringBuffer
+ 8, 10);
146 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[5], Resource
->StringBuffer
+ 10, 12);
147 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[6], Resource
->StringBuffer
+ 12, 14);
148 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[7], Resource
->StringBuffer
+ 14, 16);
154 PTEST_IMAGE TestImage
)
156 PIMAGE_DATA_DIRECTORY ResourceDirectory
;
158 TestImage
->DosHeader
.e_magic
= IMAGE_DOS_SIGNATURE
;
159 TestImage
->DosHeader
.e_lfanew
= sizeof(IMAGE_DOS_HEADER
);
161 TestImage
->NtHeaders
.Signature
= IMAGE_NT_SIGNATURE
;
163 TestImage
->NtHeaders
.FileHeader
.Machine
= IMAGE_FILE_MACHINE_I386
;
164 TestImage
->NtHeaders
.FileHeader
.NumberOfSections
= 1;
165 TestImage
->NtHeaders
.FileHeader
.TimeDateStamp
= 0;
166 TestImage
->NtHeaders
.FileHeader
.PointerToSymbolTable
= 0;
167 TestImage
->NtHeaders
.FileHeader
.NumberOfSymbols
= 0;
168 TestImage
->NtHeaders
.FileHeader
.SizeOfOptionalHeader
= sizeof(IMAGE_OPTIONAL_HEADER
);
169 TestImage
->NtHeaders
.FileHeader
.Characteristics
= 0;
171 TestImage
->NtHeaders
.OptionalHeader
.Magic
= IMAGE_NT_OPTIONAL_HDR32_MAGIC
;
172 TestImage
->NtHeaders
.OptionalHeader
.ImageBase
= (DWORD_PTR
)TestImage
;
173 TestImage
->NtHeaders
.OptionalHeader
.SizeOfImage
= sizeof(TEST_IMAGE
);
174 TestImage
->NtHeaders
.OptionalHeader
.SizeOfHeaders
= sizeof(IMAGE_DOS_HEADER
) + sizeof(IMAGE_NT_HEADERS
);
176 ResourceDirectory
= &TestImage
->NtHeaders
.OptionalHeader
.DataDirectory
[IMAGE_DIRECTORY_ENTRY_RESOURCE
];
177 ResourceDirectory
->VirtualAddress
= FIELD_OFFSET(TEST_IMAGE
, Resources
);
178 ResourceDirectory
->Size
= sizeof(TEST_RESOURCES
);
180 strcpy((char*)TestImage
->SectionHeaders
[0].Name
, ".rsrc");
181 TestImage
->SectionHeaders
[0].Misc
.VirtualSize
= sizeof(TEST_IMAGE
);
182 TestImage
->SectionHeaders
[0].VirtualAddress
= FIELD_OFFSET(TEST_IMAGE
, Resources
);
183 TestImage
->SectionHeaders
[0].SizeOfRawData
= sizeof(TEST_IMAGE
);
184 TestImage
->SectionHeaders
[0].PointerToRawData
= FIELD_OFFSET(TEST_IMAGE
, Resources
);
185 TestImage
->SectionHeaders
[0].PointerToRelocations
= 0;
186 TestImage
->SectionHeaders
[0].PointerToLinenumbers
= 0;
187 TestImage
->SectionHeaders
[0].NumberOfRelocations
= 0;
188 TestImage
->SectionHeaders
[0].NumberOfLinenumbers
= 0;
189 TestImage
->SectionHeaders
[0].Characteristics
= 0;
191 InitializeTestResource(TestImage
, &TestImage
->Resources
);
194 #define ok_nwstr(str1, str2, count) \
195 ok(wcsncmp((PWCHAR)str1, (PWCHAR)str2, count) == 0, \
196 "string is wrong, expected: '%S', got '%S'\n", str1, str2); \
198 #define ok_enumres(_Res, _Type, _Name, _Lang, _Data, _Size) \
199 ok_dec((_Res)->Type, _Type); \
200 if ((ULONG_PTR)(_Name) > 0xFFFF) \
202 ok_dec(*(WORD*)((_Res)->Name), wcslen((PWCHAR)(_Name))); \
203 ok_nwstr((PWCHAR)((_Res)->Name + 2), (PWCHAR)_Name, *(WORD*)((_Res)->Name)); \
207 ok_dec((_Res)->Name, (ULONG_PTR)_Name); \
209 ok_hex((_Res)->Language, _Lang); \
210 ok_ptr((PVOID)(_Res)->Data, _Data); \
211 ok_dec((_Res)->Size, _Size); \
212 ok_dec((_Res)->Reserved, 0);
216 Test_Data(PTEST_IMAGE TestImage
)
218 LDR_RESOURCE_INFO ResourceInfo
;
219 LDR_ENUM_RESOURCE_INFO EnumRes
[8];
223 InitializeTestImage(TestImage
);
225 memset(EnumRes
, 0xcc, sizeof(EnumRes
));
227 ResourceInfo
.Type
= 1;
228 ResourceInfo
.Name
= 1;
229 ResourceInfo
.Language
= 0x408;
231 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 0, &ResourceCount
, EnumRes
);
232 ok_hex(Status
, STATUS_SUCCESS
);
233 ok_dec(ResourceCount
, 8);
235 ok_ptr((PVOID
)EnumRes
[0].Data
, TestImage
->Resources
.StringBuffer
);
236 ok_dec(EnumRes
[0].Size
, 2);
238 ok_enumres(&EnumRes
[0], 1, L
"TEST", 0x409, TestImage
->Resources
.StringBuffer
, 2)
239 ok_enumres(&EnumRes
[1], 1, L
"TEST", 0x407, TestImage
->Resources
.StringBuffer
+ 2, 4)
240 ok_enumres(&EnumRes
[2], 1, 7, 0x408, TestImage
->Resources
.StringBuffer
+ 4, 6)
241 ok_enumres(&EnumRes
[3], 1, 7, 0x406, TestImage
->Resources
.StringBuffer
+ 6, 8)
242 ok_enumres(&EnumRes
[4], 2, L
"LOL", 0x405, TestImage
->Resources
.StringBuffer
+ 8, 10)
243 ok_enumres(&EnumRes
[5], 2, L
"LOL", 0x403, TestImage
->Resources
.StringBuffer
+ 10, 12)
244 ok_enumres(&EnumRes
[6], 2, L
"xD", 0x402, TestImage
->Resources
.StringBuffer
+ 12, 14)
245 ok_enumres(&EnumRes
[7], 2, L
"xD", 0x404, TestImage
->Resources
.StringBuffer
+ 14, 16)
247 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 1, &ResourceCount
, EnumRes
);
248 ok_hex(Status
, STATUS_SUCCESS
);
249 ok_dec(ResourceCount
, 4);
256 Test_Parameters(PTEST_IMAGE TestImage
)
258 LDR_RESOURCE_INFO ResourceInfo
;
259 LDR_ENUM_RESOURCE_INFO Resources
[8];
263 InitializeTestImage(TestImage
);
265 ResourceInfo
.Type
= 6;
266 ResourceInfo
.Name
= 1;
267 ResourceInfo
.Language
= 0x409;
270 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 3, &ResourceCount
, Resources
);
271 ok_hex(Status
, STATUS_SUCCESS
);
272 ok_dec(ResourceCount
, 0);
274 ResourceInfo
.Type
= 1;
275 ResourceInfo
.Name
= 7;
276 ResourceInfo
.Language
= 0x406;
278 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 0, &ResourceCount
, Resources
);
279 ok_hex(Status
, STATUS_SUCCESS
);
280 ok_dec(ResourceCount
, 8);
283 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 1, &ResourceCount
, Resources
);
284 ok_hex(Status
, STATUS_SUCCESS
);
285 ok_dec(ResourceCount
, 4);
288 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 2, &ResourceCount
, Resources
);
289 ok_hex(Status
, STATUS_SUCCESS
);
290 ok_dec(ResourceCount
, 2);
293 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 3, &ResourceCount
, Resources
);
294 ok_hex(Status
, STATUS_SUCCESS
);
295 ok_dec(ResourceCount
, 1);
298 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 99, &ResourceCount
, Resources
);
299 ok_hex(Status
, STATUS_SUCCESS
);
300 ok_dec(ResourceCount
, 1);
303 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 0, &ResourceCount
, Resources
);
304 ok_hex(Status
, STATUS_INFO_LENGTH_MISMATCH
);
305 ok_dec(ResourceCount
, 8);
308 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 0, &ResourceCount
, Resources
);
309 ok_hex(Status
, STATUS_INFO_LENGTH_MISMATCH
);
310 ok_dec(ResourceCount
, 8);
313 Status
= LdrEnumResources(NULL
, &ResourceInfo
, 1, &ResourceCount
, Resources
);
314 ok_hex(Status
, STATUS_RESOURCE_DATA_NOT_FOUND
);
315 ok_dec(ResourceCount
, 0);
318 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 1, &ResourceCount
, NULL
);
319 ok_hex(Status
, STATUS_INFO_LENGTH_MISMATCH
);
320 ok_dec(ResourceCount
, 4);
325 Status
= LdrEnumResources(NULL
, NULL
, 0, NULL
, NULL
);
327 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
332 ok_hex(Status
, 0xDeadC0de);
337 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 1, NULL
, Resources
);
339 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
344 ok_hex(Status
, 0xDeadC0de);
345 ok_dec(ResourceCount
, 42);
348 Status
= LdrEnumResources(TestImage
+ 2, &ResourceInfo
, 1, &ResourceCount
, NULL
);
349 ok_hex(Status
, STATUS_RESOURCE_DATA_NOT_FOUND
);
350 ok_dec(ResourceCount
, 0);
352 TestImage
->Resources
.TypeEntries
[0].DataIsDirectory
= 0;
353 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 1, &ResourceCount
, NULL
);
354 ok_hex(Status
, STATUS_INVALID_IMAGE_FORMAT
);
355 ok_dec(ResourceCount
, 0);
359 START_TEST(LdrEnumResources
)
361 TEST_IMAGE TestImage
;
363 Test_Parameters(&TestImage
);
364 Test_Data(&TestImage
);