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 #define WIN32_NO_STATUS
11 #include <ndk/ldrfuncs.h>
13 typedef struct _TEST_RESOURCES
15 IMAGE_RESOURCE_DIRECTORY TypeDirectory
;
16 IMAGE_RESOURCE_DIRECTORY_ENTRY TypeEntries
[2];
17 IMAGE_RESOURCE_DIRECTORY Name1Directory
;
18 IMAGE_RESOURCE_DIRECTORY_ENTRY Name1Entries
[2];
19 IMAGE_RESOURCE_DIRECTORY Name2Directory
;
20 IMAGE_RESOURCE_DIRECTORY_ENTRY Name2Entries
[2];
21 IMAGE_RESOURCE_DIRECTORY Lang1Directory
;
22 IMAGE_RESOURCE_DIRECTORY_ENTRY Lang1Entries
[2];
23 IMAGE_RESOURCE_DIRECTORY Lang2Directory
;
24 IMAGE_RESOURCE_DIRECTORY_ENTRY Lang2Entries
[2];
25 IMAGE_RESOURCE_DIRECTORY Lang3Directory
;
26 IMAGE_RESOURCE_DIRECTORY_ENTRY Lang3Entries
[2];
27 IMAGE_RESOURCE_DIRECTORY Lang4Directory
;
28 IMAGE_RESOURCE_DIRECTORY_ENTRY Lang4Entries
[2];
29 IMAGE_RESOURCE_DATA_ENTRY DataEntries
[8];
30 IMAGE_RESOURCE_DIRECTORY_STRING Name1String
;
32 WCHAR StringBuffer
[20];
33 } TEST_RESOURCES
, *PTEST_RESOURCES
;
35 typedef struct _TEST_IMAGE
37 IMAGE_DOS_HEADER DosHeader
;
38 IMAGE_NT_HEADERS NtHeaders
;
39 IMAGE_SECTION_HEADER SectionHeaders
[1];
40 TEST_RESOURCES Resources
;
41 } TEST_IMAGE
, *PTEST_IMAGE
;
45 InitializeResourceDirectory(
46 PIMAGE_RESOURCE_DIRECTORY ResourceDirectory
,
47 USHORT NumberOfNamedEntries
,
48 USHORT NumberOfIdEntries
)
50 ResourceDirectory
->Characteristics
= 0;
51 ResourceDirectory
->TimeDateStamp
= 0;
52 ResourceDirectory
->MajorVersion
= 0;
53 ResourceDirectory
->MinorVersion
= 0;
54 ResourceDirectory
->NumberOfNamedEntries
= NumberOfNamedEntries
;
55 ResourceDirectory
->NumberOfIdEntries
= NumberOfIdEntries
;
61 PTEST_RESOURCES Resource
,
62 PIMAGE_RESOURCE_DIRECTORY_ENTRY DirEntry
,
66 DirEntry
->Name
= Resource
->StringIndex
* 2 + FIELD_OFFSET(TEST_RESOURCES
, StringBuffer
);
67 DirEntry
->NameIsString
= 1;
68 DirEntry
->OffsetToData
= (PUCHAR
)Data
- (PUCHAR
)Resource
;
69 if (DirEntry
< Resource
->Lang1Entries
)
70 DirEntry
->DataIsDirectory
= 1;
71 Resource
->StringBuffer
[Resource
->StringIndex
] = wcslen(Name
);
72 wcscpy(&Resource
->StringBuffer
[Resource
->StringIndex
+ 1], Name
);
73 Resource
->StringIndex
+= Resource
->StringBuffer
[Resource
->StringIndex
] * 2 + 1;
79 PTEST_RESOURCES Resource
,
80 PIMAGE_RESOURCE_DIRECTORY_ENTRY DirEntry
,
85 DirEntry
->NameIsString
= 0;
86 DirEntry
->OffsetToData
= (PUCHAR
)Data
- (PUCHAR
)Resource
;
87 if (DirEntry
< Resource
->Lang1Entries
)
88 DirEntry
->DataIsDirectory
= 1;
95 PIMAGE_RESOURCE_DATA_ENTRY DataEntry
,
100 DataEntry
->OffsetToData
= (PUCHAR
)Data
- (PUCHAR
)ImageBase
;
101 DataEntry
->Size
= Size
;
102 DataEntry
->CodePage
= 0;
103 DataEntry
->Reserved
= 0;
108 InitializeTestResource(
110 PTEST_RESOURCES Resource
)
113 memset(Resource
->StringBuffer
, 0, sizeof(Resource
->StringBuffer
));
114 Resource
->StringIndex
= 0;
116 InitializeResourceDirectory(&Resource
->TypeDirectory
, 0, 2);
117 InitializeIdEntry(Resource
, &Resource
->TypeEntries
[0], 1, &Resource
->Name1Directory
);
118 InitializeIdEntry(Resource
, &Resource
->TypeEntries
[1], 2, &Resource
->Name2Directory
);
120 InitializeResourceDirectory(&Resource
->Name1Directory
, 1, 1);
121 InitializeNamedEntry(Resource
, &Resource
->Name1Entries
[0], L
"TEST", &Resource
->Lang1Directory
);
122 InitializeIdEntry(Resource
, &Resource
->Name1Entries
[1], 7, &Resource
->Lang2Directory
);
124 InitializeResourceDirectory(&Resource
->Name2Directory
, 2, 0);
125 InitializeNamedEntry(Resource
, &Resource
->Name2Entries
[0], L
"LOL", &Resource
->Lang3Directory
);
126 InitializeNamedEntry(Resource
, &Resource
->Name2Entries
[1], L
"xD", &Resource
->Lang4Directory
);
128 InitializeResourceDirectory(&Resource
->Lang1Directory
, 0, 2);
129 InitializeIdEntry(Resource
, &Resource
->Lang1Entries
[0], 0x409, &Resource
->DataEntries
[0]);
130 InitializeIdEntry(Resource
, &Resource
->Lang1Entries
[1], 0x407, &Resource
->DataEntries
[1]);
132 InitializeResourceDirectory(&Resource
->Lang2Directory
, 0, 2);
133 InitializeIdEntry(Resource
, &Resource
->Lang2Entries
[0], 0x408, &Resource
->DataEntries
[2]);
134 InitializeIdEntry(Resource
, &Resource
->Lang2Entries
[1], 0x406, &Resource
->DataEntries
[3]);
136 InitializeResourceDirectory(&Resource
->Lang3Directory
, 0, 2);
137 InitializeIdEntry(Resource
, &Resource
->Lang3Entries
[0], 0x405, &Resource
->DataEntries
[4]);
138 InitializeIdEntry(Resource
, &Resource
->Lang3Entries
[1], 0x403, &Resource
->DataEntries
[5]);
140 InitializeResourceDirectory(&Resource
->Lang4Directory
, 0, 2);
141 InitializeIdEntry(Resource
, &Resource
->Lang4Entries
[0], 0x402, &Resource
->DataEntries
[6]);
142 InitializeIdEntry(Resource
, &Resource
->Lang4Entries
[1], 0x404, &Resource
->DataEntries
[7]);
144 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[0], Resource
->StringBuffer
+ 0, 2);
145 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[1], Resource
->StringBuffer
+ 2, 4);
146 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[2], Resource
->StringBuffer
+ 4, 6);
147 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[3], Resource
->StringBuffer
+ 6, 8);
148 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[4], Resource
->StringBuffer
+ 8, 10);
149 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[5], Resource
->StringBuffer
+ 10, 12);
150 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[6], Resource
->StringBuffer
+ 12, 14);
151 InitializeDataEntry(ImageBase
, &Resource
->DataEntries
[7], Resource
->StringBuffer
+ 14, 16);
157 PTEST_IMAGE TestImage
)
159 PIMAGE_DATA_DIRECTORY ResourceDirectory
;
161 TestImage
->DosHeader
.e_magic
= IMAGE_DOS_SIGNATURE
;
162 TestImage
->DosHeader
.e_lfanew
= sizeof(IMAGE_DOS_HEADER
);
164 TestImage
->NtHeaders
.Signature
= IMAGE_NT_SIGNATURE
;
166 TestImage
->NtHeaders
.FileHeader
.Machine
= IMAGE_FILE_MACHINE_I386
;
167 TestImage
->NtHeaders
.FileHeader
.NumberOfSections
= 1;
168 TestImage
->NtHeaders
.FileHeader
.TimeDateStamp
= 0;
169 TestImage
->NtHeaders
.FileHeader
.PointerToSymbolTable
= 0;
170 TestImage
->NtHeaders
.FileHeader
.NumberOfSymbols
= 0;
171 TestImage
->NtHeaders
.FileHeader
.SizeOfOptionalHeader
= sizeof(IMAGE_OPTIONAL_HEADER
);
172 TestImage
->NtHeaders
.FileHeader
.Characteristics
= 0;
174 TestImage
->NtHeaders
.OptionalHeader
.Magic
= IMAGE_NT_OPTIONAL_HDR32_MAGIC
;
175 TestImage
->NtHeaders
.OptionalHeader
.ImageBase
= (DWORD
)TestImage
;
176 TestImage
->NtHeaders
.OptionalHeader
.SizeOfImage
= sizeof(TEST_IMAGE
);
177 TestImage
->NtHeaders
.OptionalHeader
.SizeOfHeaders
= sizeof(IMAGE_DOS_HEADER
) + sizeof(IMAGE_NT_HEADERS
);
179 ResourceDirectory
= &TestImage
->NtHeaders
.OptionalHeader
.DataDirectory
[IMAGE_DIRECTORY_ENTRY_RESOURCE
];
180 ResourceDirectory
->VirtualAddress
= FIELD_OFFSET(TEST_IMAGE
, Resources
);
181 ResourceDirectory
->Size
= sizeof(TEST_RESOURCES
);
183 strcpy((char*)TestImage
->SectionHeaders
[0].Name
, ".rsrc");
184 TestImage
->SectionHeaders
[0].Misc
.VirtualSize
= sizeof(TEST_IMAGE
);
185 TestImage
->SectionHeaders
[0].VirtualAddress
= FIELD_OFFSET(TEST_IMAGE
, Resources
);
186 TestImage
->SectionHeaders
[0].SizeOfRawData
= sizeof(TEST_IMAGE
);
187 TestImage
->SectionHeaders
[0].PointerToRawData
= FIELD_OFFSET(TEST_IMAGE
, Resources
);
188 TestImage
->SectionHeaders
[0].PointerToRelocations
= 0;
189 TestImage
->SectionHeaders
[0].PointerToLinenumbers
= 0;
190 TestImage
->SectionHeaders
[0].NumberOfRelocations
= 0;
191 TestImage
->SectionHeaders
[0].NumberOfLinenumbers
= 0;
192 TestImage
->SectionHeaders
[0].Characteristics
= 0;
194 InitializeTestResource(TestImage
, &TestImage
->Resources
);
197 #define ok_nwstr(str1, str2, count) \
198 ok(wcsncmp((PWCHAR)str1, (PWCHAR)str2, count) == 0, \
199 "string is wrong, expected: '%S', got '%S'\n", str1, str2); \
201 #define ok_enumres(_Res, _Type, _Name, _Lang, _Data, _Size) \
202 ok_dec((_Res)->Type, _Type); \
203 if ((ULONG_PTR)(_Name) > 0xFFFF) \
205 ok_dec(*(WORD*)((_Res)->Name), wcslen((PWCHAR)(_Name))); \
206 ok_nwstr((PWCHAR)((_Res)->Name + 2), (PWCHAR)_Name, *(WORD*)((_Res)->Name)); \
210 ok_dec((_Res)->Name, (ULONG_PTR)_Name); \
212 ok_hex((_Res)->Language, _Lang); \
213 ok_ptr((PVOID)(_Res)->Data, _Data); \
214 ok_dec((_Res)->Size, _Size); \
215 ok_dec((_Res)->Reserved, 0);
219 Test_Data(PTEST_IMAGE TestImage
)
221 LDR_RESOURCE_INFO ResourceInfo
;
222 LDR_ENUM_RESOURCE_INFO EnumRes
[8];
226 InitializeTestImage(TestImage
);
228 memset(EnumRes
, 0xcc, sizeof(EnumRes
));
230 ResourceInfo
.Type
= 1;
231 ResourceInfo
.Name
= 1;
232 ResourceInfo
.Language
= 0x408;
234 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 0, &ResourceCount
, EnumRes
);
235 ok_hex(Status
, STATUS_SUCCESS
);
236 ok_dec(ResourceCount
, 8);
238 ok_ptr((PVOID
)EnumRes
[0].Data
, TestImage
->Resources
.StringBuffer
);
239 ok_dec(EnumRes
[0].Size
, 2);
241 ok_enumres(&EnumRes
[0], 1, L
"TEST", 0x409, TestImage
->Resources
.StringBuffer
, 2)
242 ok_enumres(&EnumRes
[1], 1, L
"TEST", 0x407, TestImage
->Resources
.StringBuffer
+ 2, 4)
243 ok_enumres(&EnumRes
[2], 1, 7, 0x408, TestImage
->Resources
.StringBuffer
+ 4, 6)
244 ok_enumres(&EnumRes
[3], 1, 7, 0x406, TestImage
->Resources
.StringBuffer
+ 6, 8)
245 ok_enumres(&EnumRes
[4], 2, L
"LOL", 0x405, TestImage
->Resources
.StringBuffer
+ 8, 10)
246 ok_enumres(&EnumRes
[5], 2, L
"LOL", 0x403, TestImage
->Resources
.StringBuffer
+ 10, 12)
247 ok_enumres(&EnumRes
[6], 2, L
"xD", 0x402, TestImage
->Resources
.StringBuffer
+ 12, 14)
248 ok_enumres(&EnumRes
[7], 2, L
"xD", 0x404, TestImage
->Resources
.StringBuffer
+ 14, 16)
250 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 1, &ResourceCount
, EnumRes
);
251 ok_hex(Status
, STATUS_SUCCESS
);
252 ok_dec(ResourceCount
, 4);
259 Test_Parameters(PTEST_IMAGE TestImage
)
261 LDR_RESOURCE_INFO ResourceInfo
;
262 LDR_ENUM_RESOURCE_INFO Resources
[8];
266 InitializeTestImage(TestImage
);
268 ResourceInfo
.Type
= 6;
269 ResourceInfo
.Name
= 1;
270 ResourceInfo
.Language
= 0x409;
273 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 3, &ResourceCount
, Resources
);
274 ok_hex(Status
, STATUS_SUCCESS
);
275 ok_dec(ResourceCount
, 0);
277 ResourceInfo
.Type
= 1;
278 ResourceInfo
.Name
= 7;
279 ResourceInfo
.Language
= 0x406;
281 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 0, &ResourceCount
, Resources
);
282 ok_hex(Status
, STATUS_SUCCESS
);
283 ok_dec(ResourceCount
, 8);
286 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 1, &ResourceCount
, Resources
);
287 ok_hex(Status
, STATUS_SUCCESS
);
288 ok_dec(ResourceCount
, 4);
291 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 2, &ResourceCount
, Resources
);
292 ok_hex(Status
, STATUS_SUCCESS
);
293 ok_dec(ResourceCount
, 2);
296 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 3, &ResourceCount
, Resources
);
297 ok_hex(Status
, STATUS_SUCCESS
);
298 ok_dec(ResourceCount
, 1);
301 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 99, &ResourceCount
, Resources
);
302 ok_hex(Status
, STATUS_SUCCESS
);
303 ok_dec(ResourceCount
, 1);
306 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 0, &ResourceCount
, Resources
);
307 ok_hex(Status
, STATUS_INFO_LENGTH_MISMATCH
);
308 ok_dec(ResourceCount
, 8);
311 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 0, &ResourceCount
, Resources
);
312 ok_hex(Status
, STATUS_INFO_LENGTH_MISMATCH
);
313 ok_dec(ResourceCount
, 8);
316 Status
= LdrEnumResources(NULL
, &ResourceInfo
, 1, &ResourceCount
, Resources
);
317 ok_hex(Status
, STATUS_RESOURCE_DATA_NOT_FOUND
);
318 ok_dec(ResourceCount
, 0);
321 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 1, &ResourceCount
, NULL
);
322 ok_hex(Status
, STATUS_INFO_LENGTH_MISMATCH
);
323 ok_dec(ResourceCount
, 4);
328 Status
= LdrEnumResources(NULL
, NULL
, 0, NULL
, NULL
);
330 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
335 ok_hex(Status
, 0xDeadC0de);
340 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 1, NULL
, Resources
);
342 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
347 ok_hex(Status
, 0xDeadC0de);
348 ok_dec(ResourceCount
, 42);
351 Status
= LdrEnumResources(TestImage
+ 2, &ResourceInfo
, 1, &ResourceCount
, NULL
);
352 ok_hex(Status
, STATUS_RESOURCE_DATA_NOT_FOUND
);
353 ok_dec(ResourceCount
, 0);
355 TestImage
->Resources
.TypeEntries
[0].DataIsDirectory
= 0;
356 Status
= LdrEnumResources(TestImage
, &ResourceInfo
, 1, &ResourceCount
, NULL
);
357 ok_hex(Status
, STATUS_INVALID_IMAGE_FORMAT
);
358 ok_dec(ResourceCount
, 0);
362 START_TEST(LdrEnumResources
)
364 TEST_IMAGE TestImage
;
366 Test_Parameters(&TestImage
);
367 Test_Data(&TestImage
);