2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test for LdrEnumResources
5 * PROGRAMMER: Timo Kreuzer
8 #define WIN32_NO_STATUS
10 #include <wine/test.h>
11 #include <pseh/pseh2.h>
12 #include <ndk/ldrfuncs.h>
14 typedef struct _TEST_RESOURCES
16 IMAGE_RESOURCE_DIRECTORY TypeDirectory
;
17 IMAGE_RESOURCE_DIRECTORY_ENTRY TypeEntries
[2];
18 IMAGE_RESOURCE_DIRECTORY Name1Directory
;
19 IMAGE_RESOURCE_DIRECTORY_ENTRY Name1Entries
[2];
20 IMAGE_RESOURCE_DIRECTORY Name2Directory
;
21 IMAGE_RESOURCE_DIRECTORY_ENTRY Name2Entries
[2];
22 IMAGE_RESOURCE_DIRECTORY Lang1Directory
;
23 IMAGE_RESOURCE_DIRECTORY_ENTRY Lang1Entries
[2];
24 IMAGE_RESOURCE_DIRECTORY Lang2Directory
;
25 IMAGE_RESOURCE_DIRECTORY_ENTRY Lang2Entries
[2];
26 IMAGE_RESOURCE_DIRECTORY Lang3Directory
;
27 IMAGE_RESOURCE_DIRECTORY_ENTRY Lang3Entries
[2];
28 IMAGE_RESOURCE_DIRECTORY Lang4Directory
;
29 IMAGE_RESOURCE_DIRECTORY_ENTRY Lang4Entries
[2];
30 IMAGE_RESOURCE_DATA_ENTRY DataEntries
[8];
31 IMAGE_RESOURCE_DIRECTORY_STRING Name1String
;
33 WCHAR StringBuffer
[20];
34 } TEST_RESOURCES
, *PTEST_RESOURCES
;
36 typedef struct _TEST_IMAGE
38 IMAGE_DOS_HEADER DosHeader
;
39 IMAGE_NT_HEADERS NtHeaders
;
40 IMAGE_SECTION_HEADER SectionHeaders
[1];
41 TEST_RESOURCES Resources
;
42 } TEST_IMAGE
, *PTEST_IMAGE
;
46 InitializeResourceDirectory(
47 PIMAGE_RESOURCE_DIRECTORY ResourceDirectory
,
48 USHORT NumberOfNamedEntries
,
49 USHORT NumberOfIdEntries
)
51 ResourceDirectory
->Characteristics
= 0;
52 ResourceDirectory
->TimeDateStamp
= 0;
53 ResourceDirectory
->MajorVersion
= 0;
54 ResourceDirectory
->MinorVersion
= 0;
55 ResourceDirectory
->NumberOfNamedEntries
= NumberOfNamedEntries
;
56 ResourceDirectory
->NumberOfIdEntries
= NumberOfIdEntries
;
62 PTEST_RESOURCES Resource
,
63 PIMAGE_RESOURCE_DIRECTORY_ENTRY DirEntry
,
67 DirEntry
->Name
= Resource
->StringIndex
* 2 + FIELD_OFFSET(TEST_RESOURCES
, StringBuffer
);
68 DirEntry
->NameIsString
= 1;
69 DirEntry
->OffsetToData
= (PUCHAR
)Data
- (PUCHAR
)Resource
;
70 if (DirEntry
< Resource
->Lang1Entries
)
71 DirEntry
->DataIsDirectory
= 1;
72 Resource
->StringBuffer
[Resource
->StringIndex
] = wcslen(Name
);
73 wcscpy(&Resource
->StringBuffer
[Resource
->StringIndex
+ 1], Name
);
74 Resource
->StringIndex
+= Resource
->StringBuffer
[Resource
->StringIndex
] * 2 + 1;
80 PTEST_RESOURCES Resource
,
81 PIMAGE_RESOURCE_DIRECTORY_ENTRY DirEntry
,
86 DirEntry
->NameIsString
= 0;
87 DirEntry
->OffsetToData
= (PUCHAR
)Data
- (PUCHAR
)Resource
;
88 if (DirEntry
< Resource
->Lang1Entries
)
89 DirEntry
->DataIsDirectory
= 1;
96 PIMAGE_RESOURCE_DATA_ENTRY DataEntry
,
101 DataEntry
->OffsetToData
= (PUCHAR
)Data
- (PUCHAR
)ImageBase
;
102 DataEntry
->Size
= Size
;
103 DataEntry
->CodePage
= 0;
104 DataEntry
->Reserved
= 0;
109 InitializeTestResource(
111 PTEST_RESOURCES Resource
)
114 memset(Resource
->StringBuffer
, 0, sizeof(Resource
->StringBuffer
));
115 Resource
->StringIndex
= 0;
117 InitializeResourceDirectory(&Resource
->TypeDirectory
, 0, 2);
118 InitializeIdEntry(Resource
, &Resource
->TypeEntries
[0], 1, &Resource
->Name1Directory
);
119 InitializeIdEntry(Resource
, &Resource
->TypeEntries
[1], 2, &Resource
->Name2Directory
);
121 InitializeResourceDirectory(&Resource
->Name1Directory
, 1, 1);
122 InitializeNamedEntry(Resource
, &Resource
->Name1Entries
[0], L
"TEST", &Resource
->Lang1Directory
);
123 InitializeIdEntry(Resource
, &Resource
->Name1Entries
[1], 7, &Resource
->Lang2Directory
);
125 InitializeResourceDirectory(&Resource
->Name2Directory
, 2, 0);
126 InitializeNamedEntry(Resource
, &Resource
->Name2Entries
[0], L
"LOL", &Resource
->Lang3Directory
);
127 InitializeNamedEntry(Resource
, &Resource
->Name2Entries
[1], L
"xD", &Resource
->Lang4Directory
);
129 InitializeResourceDirectory(&Resource
->Lang1Directory
, 0, 2);
130 InitializeIdEntry(Resource
, &Resource
->Lang1Entries
[0], 0x409, &Resource
->DataEntries
[0]);
131 InitializeIdEntry(Resource
, &Resource
->Lang1Entries
[1], 0x407, &Resource
->DataEntries
[1]);
133 InitializeResourceDirectory(&Resource
->Lang2Directory
, 0, 2);
134 InitializeIdEntry(Resource
, &Resource
->Lang2Entries
[0], 0x408, &Resource
->DataEntries
[2]);
135 InitializeIdEntry(Resource
, &Resource
->Lang2Entries
[1], 0x406, &Resource
->DataEntries
[3]);
137 InitializeResourceDirectory(&Resource
->Lang3Directory
, 0, 2);
138 InitializeIdEntry(Resource
, &Resource
->Lang3Entries
[0], 0x405, &Resource
->DataEntries
[4]);
139 InitializeIdEntry(Resource
, &Resource
->Lang3Entries
[1], 0x403, &Resource
->DataEntries
[5]);
141 InitializeResourceDirectory(&Resource
->Lang4Directory
, 0, 2);
142 InitializeIdEntry(Resource
, &Resource
->Lang4Entries
[0], 0x402, &Resource
->DataEntries
[6]);
143 InitializeIdEntry(Resource
, &Resource
->Lang4Entries
[1], 0x404, &Resource
->DataEntries
[7]);
145 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[0], Resource
->StringBuffer
+ 0, 2);
146 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[1], Resource
->StringBuffer
+ 2, 4);
147 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[2], Resource
->StringBuffer
+ 4, 6);
148 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[3], Resource
->StringBuffer
+ 6, 8);
149 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[4], Resource
->StringBuffer
+ 8, 10);
150 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[5], Resource
->StringBuffer
+ 10, 12);
151 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[6], Resource
->StringBuffer
+ 12, 14);
152 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[7], Resource
->StringBuffer
+ 14, 16);
158 PTEST_IMAGE TestImage
)
160 PIMAGE_DATA_DIRECTORY ResourceDirectory
;
162 TestImage
->DosHeader
.e_magic
= IMAGE_DOS_SIGNATURE
;
163 TestImage
->DosHeader
.e_lfanew
= sizeof(IMAGE_DOS_HEADER
);
165 TestImage
->NtHeaders
.Signature
= IMAGE_NT_SIGNATURE
;
167 TestImage
->NtHeaders
.FileHeader
.Machine
= IMAGE_FILE_MACHINE_I386
;
168 TestImage
->NtHeaders
.FileHeader
.NumberOfSections
= 1;
169 TestImage
->NtHeaders
.FileHeader
.TimeDateStamp
= 0;
170 TestImage
->NtHeaders
.FileHeader
.PointerToSymbolTable
= 0;
171 TestImage
->NtHeaders
.FileHeader
.NumberOfSymbols
= 0;
172 TestImage
->NtHeaders
.FileHeader
.SizeOfOptionalHeader
= sizeof(IMAGE_OPTIONAL_HEADER
);
173 TestImage
->NtHeaders
.FileHeader
.Characteristics
= 0;
175 TestImage
->NtHeaders
.OptionalHeader
.Magic
= IMAGE_NT_OPTIONAL_HDR32_MAGIC
;
176 TestImage
->NtHeaders
.OptionalHeader
.ImageBase
= (DWORD
)TestImage
;
177 TestImage
->NtHeaders
.OptionalHeader
.SizeOfImage
= sizeof(TEST_IMAGE
);
178 TestImage
->NtHeaders
.OptionalHeader
.SizeOfHeaders
= sizeof(IMAGE_DOS_HEADER
) + sizeof(IMAGE_NT_HEADERS
);
180 ResourceDirectory
= &TestImage
->NtHeaders
.OptionalHeader
.DataDirectory
[IMAGE_DIRECTORY_ENTRY_RESOURCE
];
181 ResourceDirectory
->VirtualAddress
= FIELD_OFFSET(TEST_IMAGE
, Resources
);
182 ResourceDirectory
->Size
= sizeof(TEST_RESOURCES
);
184 strcpy((char*)TestImage
->SectionHeaders
[0].Name
, ".rsrc");
185 TestImage
->SectionHeaders
[0].Misc
.VirtualSize
= sizeof(TEST_IMAGE
);
186 TestImage
->SectionHeaders
[0].VirtualAddress
= FIELD_OFFSET(TEST_IMAGE
, Resources
);
187 TestImage
->SectionHeaders
[0].SizeOfRawData
= sizeof(TEST_IMAGE
);
188 TestImage
->SectionHeaders
[0].PointerToRawData
= FIELD_OFFSET(TEST_IMAGE
, Resources
);
189 TestImage
->SectionHeaders
[0].PointerToRelocations
= 0;
190 TestImage
->SectionHeaders
[0].PointerToLinenumbers
= 0;
191 TestImage
->SectionHeaders
[0].NumberOfRelocations
= 0;
192 TestImage
->SectionHeaders
[0].NumberOfLinenumbers
= 0;
193 TestImage
->SectionHeaders
[0].Characteristics
= 0;
195 InitializeTestResource(TestImage
, &TestImage
->Resources
);
198 #define ok_nwstr(str1, str2, count) \
199 ok(wcsncmp((PWCHAR)str1, (PWCHAR)str2, count) == 0, \
200 "string is wrong, expected: '%S', got '%S'\n", str1, str2); \
202 #define ok_enumres(_Res, _Type, _Name, _Lang, _Data, _Size) \
203 ok_dec((_Res)->Type, _Type); \
204 if ((ULONG_PTR)(_Name) > 0xFFFF) \
206 ok_dec(*(WORD*)((_Res)->Name), wcslen((PWCHAR)(_Name))); \
207 ok_nwstr((PWCHAR)((_Res)->Name + 2), (PWCHAR)_Name, *(WORD*)((_Res)->Name)); \
211 ok_dec((_Res)->Name, (ULONG_PTR)_Name); \
213 ok_hex((_Res)->Language, _Lang); \
214 ok_ptr((PVOID)(_Res)->Data, _Data); \
215 ok_dec((_Res)->Size, _Size); \
216 ok_dec((_Res)->Reserved, 0);
220 Test_Data(PTEST_IMAGE TestImage
)
222 LDR_RESOURCE_INFO ResourceInfo
;
223 LDR_ENUM_RESOURCE_INFO EnumRes
[8];
227 InitializeTestImage(TestImage
);
229 memset(EnumRes
, 0xcc, sizeof(EnumRes
));
231 ResourceInfo
.Type
= 1;
232 ResourceInfo
.Name
= 1;
233 ResourceInfo
.Language
= 0x408;
235 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 0, &ResourceCount
, EnumRes
);
236 ok_hex(Status
, STATUS_SUCCESS
);
237 ok_dec(ResourceCount
, 8);
239 ok_ptr((PVOID
)EnumRes
[0].Data
, TestImage
->Resources
.StringBuffer
);
240 ok_dec(EnumRes
[0].Size
, 2);
242 ok_enumres(&EnumRes
[0], 1, L
"TEST", 0x409, TestImage
->Resources
.StringBuffer
, 2)
243 ok_enumres(&EnumRes
[1], 1, L
"TEST", 0x407, TestImage
->Resources
.StringBuffer
+ 2, 4)
244 ok_enumres(&EnumRes
[2], 1, 7, 0x408, TestImage
->Resources
.StringBuffer
+ 4, 6)
245 ok_enumres(&EnumRes
[3], 1, 7, 0x406, TestImage
->Resources
.StringBuffer
+ 6, 8)
246 ok_enumres(&EnumRes
[4], 2, L
"LOL", 0x405, TestImage
->Resources
.StringBuffer
+ 8, 10)
247 ok_enumres(&EnumRes
[5], 2, L
"LOL", 0x403, TestImage
->Resources
.StringBuffer
+ 10, 12)
248 ok_enumres(&EnumRes
[6], 2, L
"xD", 0x402, TestImage
->Resources
.StringBuffer
+ 12, 14)
249 ok_enumres(&EnumRes
[7], 2, L
"xD", 0x404, TestImage
->Resources
.StringBuffer
+ 14, 16)
251 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 1, &ResourceCount
, EnumRes
);
252 ok_hex(Status
, STATUS_SUCCESS
);
253 ok_dec(ResourceCount
, 4);
260 Test_Parameters(PTEST_IMAGE TestImage
)
262 LDR_RESOURCE_INFO ResourceInfo
;
263 LDR_ENUM_RESOURCE_INFO Resources
[8];
267 InitializeTestImage(TestImage
);
269 ResourceInfo
.Type
= 6;
270 ResourceInfo
.Name
= 1;
271 ResourceInfo
.Language
= 0x409;
274 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 3, &ResourceCount
, Resources
);
275 ok_hex(Status
, STATUS_SUCCESS
);
276 ok_dec(ResourceCount
, 0);
278 ResourceInfo
.Type
= 1;
279 ResourceInfo
.Name
= 7;
280 ResourceInfo
.Language
= 0x406;
282 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 0, &ResourceCount
, Resources
);
283 ok_hex(Status
, STATUS_SUCCESS
);
284 ok_dec(ResourceCount
, 8);
287 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 1, &ResourceCount
, Resources
);
288 ok_hex(Status
, STATUS_SUCCESS
);
289 ok_dec(ResourceCount
, 4);
292 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 2, &ResourceCount
, Resources
);
293 ok_hex(Status
, STATUS_SUCCESS
);
294 ok_dec(ResourceCount
, 2);
297 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 3, &ResourceCount
, Resources
);
298 ok_hex(Status
, STATUS_SUCCESS
);
299 ok_dec(ResourceCount
, 1);
302 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 99, &ResourceCount
, Resources
);
303 ok_hex(Status
, STATUS_SUCCESS
);
304 ok_dec(ResourceCount
, 1);
307 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 0, &ResourceCount
, Resources
);
308 ok_hex(Status
, STATUS_INFO_LENGTH_MISMATCH
);
309 ok_dec(ResourceCount
, 8);
312 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 0, &ResourceCount
, Resources
);
313 ok_hex(Status
, STATUS_INFO_LENGTH_MISMATCH
);
314 ok_dec(ResourceCount
, 8);
317 Status
= LdrEnumResources(NULL
, &ResourceInfo
, 1, &ResourceCount
, Resources
);
318 ok_hex(Status
, STATUS_RESOURCE_DATA_NOT_FOUND
);
319 ok_dec(ResourceCount
, 0);
322 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 1, &ResourceCount
, NULL
);
323 ok_hex(Status
, STATUS_INFO_LENGTH_MISMATCH
);
324 ok_dec(ResourceCount
, 4);
329 Status
= LdrEnumResources(NULL
, NULL
, 0, NULL
, NULL
);
331 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
336 ok_hex(Status
, 0xDeadC0de);
341 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 1, NULL
, Resources
);
343 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
348 ok_hex(Status
, 0xDeadC0de);
349 ok_dec(ResourceCount
, 42);
352 Status
= LdrEnumResources(TestImage
+ 2, &ResourceInfo
, 1, &ResourceCount
, NULL
);
353 ok_hex(Status
, STATUS_RESOURCE_DATA_NOT_FOUND
);
354 ok_dec(ResourceCount
, 0);
356 TestImage
->Resources
.TypeEntries
[0].DataIsDirectory
= 0;
357 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 1, &ResourceCount
, NULL
);
358 ok_hex(Status
, STATUS_INVALID_IMAGE_FORMAT
);
359 ok_dec(ResourceCount
, 0);
363 START_TEST(LdrEnumResources
)
365 TEST_IMAGE TestImage
;
367 Test_Parameters(&TestImage
);
368 Test_Data(&TestImage
);