ReactOS  0.4.15-dev-439-g292f67a
LdrEnumResources.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS api tests
3  * LICENSE: GPLv2+ - See COPYING in the top level directory
4  * PURPOSE: Test for LdrEnumResources
5  * PROGRAMMER: Timo Kreuzer
6  */
7 
8 #include "precomp.h"
9 
10 typedef struct _TEST_RESOURCES
11 {
31 
32 typedef struct _TEST_IMAGE
33 {
39 
40 static
41 VOID
43  PIMAGE_RESOURCE_DIRECTORY ResourceDirectory,
44  USHORT NumberOfNamedEntries,
45  USHORT NumberOfIdEntries)
46 {
47  ResourceDirectory->Characteristics = 0;
48  ResourceDirectory->TimeDateStamp = 0;
49  ResourceDirectory->MajorVersion = 0;
50  ResourceDirectory->MinorVersion = 0;
51  ResourceDirectory->NumberOfNamedEntries = NumberOfNamedEntries;
52  ResourceDirectory->NumberOfIdEntries = NumberOfIdEntries;
53 }
54 
55 static
56 VOID
60  PWCHAR Name,
61  PVOID Data)
62 {
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] = (USHORT)wcslen(Name);
69  wcscpy(&Resource->StringBuffer[Resource->StringIndex + 1], Name);
70  Resource->StringIndex += Resource->StringBuffer[Resource->StringIndex] * 2 + 1;
71 }
72 
73 static
74 VOID
78  USHORT Id,
79  PVOID Data)
80 {
81  DirEntry->Name = Id;
82  DirEntry->NameIsString = 0;
83  DirEntry->OffsetToData = (PUCHAR)Data - (PUCHAR)Resource;
84  if (DirEntry < Resource->Lang1Entries)
85  DirEntry->DataIsDirectory = 1;
86 }
87 
88 static
89 VOID
91  PVOID ImageBase,
93  PVOID Data,
94  ULONG Size)
95 {
96 
97  DataEntry->OffsetToData = (PUCHAR)Data - (PUCHAR)ImageBase;
98  DataEntry->Size = Size;
99  DataEntry->CodePage = 0;
100  DataEntry->Reserved = 0;
101 }
102 
103 static
104 VOID
106  PVOID ImageBase,
108 {
109 
110  memset(Resource->StringBuffer, 0, sizeof(Resource->StringBuffer));
111  Resource->StringIndex = 0;
112 
113  InitializeResourceDirectory(&Resource->TypeDirectory, 0, 2);
114  InitializeIdEntry(Resource, &Resource->TypeEntries[0], 1, &Resource->Name1Directory);
115  InitializeIdEntry(Resource, &Resource->TypeEntries[1], 2, &Resource->Name2Directory);
116 
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);
120 
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);
124 
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]);
128 
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]);
132 
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]);
136 
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]);
140 
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);
149 
150 }
151 
152 VOID
154  PTEST_IMAGE TestImage)
155 {
156  PIMAGE_DATA_DIRECTORY ResourceDirectory;
157 
159  TestImage->DosHeader.e_lfanew = sizeof(IMAGE_DOS_HEADER);
160 
162 
164  TestImage->NtHeaders.FileHeader.NumberOfSections = 1;
165  TestImage->NtHeaders.FileHeader.TimeDateStamp = 0;
167  TestImage->NtHeaders.FileHeader.NumberOfSymbols = 0;
169  TestImage->NtHeaders.FileHeader.Characteristics = 0;
170 
172  TestImage->NtHeaders.OptionalHeader.ImageBase = (DWORD_PTR)TestImage;
173  TestImage->NtHeaders.OptionalHeader.SizeOfImage = sizeof(TEST_IMAGE);
175 
176  ResourceDirectory = &TestImage->NtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
177  ResourceDirectory->VirtualAddress = FIELD_OFFSET(TEST_IMAGE, Resources);
178  ResourceDirectory->Size = sizeof(TEST_RESOURCES);
179 
180  strcpy((char*)TestImage->SectionHeaders[0].Name, ".rsrc");
181  TestImage->SectionHeaders[0].Misc.VirtualSize = sizeof(TEST_IMAGE);
183  TestImage->SectionHeaders[0].SizeOfRawData = sizeof(TEST_IMAGE);
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;
190 
191  InitializeTestResource(TestImage, &TestImage->Resources);
192 }
193 
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); \
197 
198 #define ok_enumres(_Res, _Type, _Name, _Lang, _Data, _Size) \
199  ok_dec((_Res)->Type, _Type); \
200  if ((ULONG_PTR)(_Name) > 0xFFFF) \
201  { \
202  ok_dec(*(WORD*)((_Res)->Name), wcslen((PWCHAR)(_Name))); \
203  ok_nwstr((PWCHAR)((_Res)->Name + 2), (PWCHAR)_Name, *(WORD*)((_Res)->Name)); \
204  } \
205  else \
206  { \
207  ok_dec((_Res)->Name, (ULONG_PTR)_Name); \
208  } \
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);
213 
214 static
215 void
217 {
218  LDR_RESOURCE_INFO ResourceInfo;
219  LDR_ENUM_RESOURCE_INFO EnumRes[8];
222 
223  InitializeTestImage(TestImage);
224 
225  memset(EnumRes, 0xcc, sizeof(EnumRes));
226 
227  ResourceInfo.Type = 1;
228  ResourceInfo.Name = 1;
229  ResourceInfo.Language = 0x408;
230  ResourceCount = 8;
231  Status = LdrEnumResources(TestImage, &ResourceInfo, 0, &ResourceCount, EnumRes);
233  ok_dec(ResourceCount, 8);
234 
235  ok_ptr((PVOID)EnumRes[0].Data, TestImage->Resources.StringBuffer);
236  ok_dec(EnumRes[0].Size, 2);
237 
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)
246 
247  Status = LdrEnumResources(TestImage, &ResourceInfo, 1, &ResourceCount, EnumRes);
249  ok_dec(ResourceCount, 4);
250 
251 }
252 
253 
254 static
255 void
257 {
258  LDR_RESOURCE_INFO ResourceInfo;
262 
263  InitializeTestImage(TestImage);
264 
265  ResourceInfo.Type = 6;
266  ResourceInfo.Name = 1;
267  ResourceInfo.Language = 0x409;
268 
269  ResourceCount = 8;
270  Status = LdrEnumResources(TestImage, &ResourceInfo, 3, &ResourceCount, Resources);
272  ok_dec(ResourceCount, 0);
273 
274  ResourceInfo.Type = 1;
275  ResourceInfo.Name = 7;
276  ResourceInfo.Language = 0x406;
277  ResourceCount = 8;
278  Status = LdrEnumResources(TestImage, &ResourceInfo, 0, &ResourceCount, Resources);
280  ok_dec(ResourceCount, 8);
281 
282  ResourceCount = 8;
283  Status = LdrEnumResources(TestImage, &ResourceInfo, 1, &ResourceCount, Resources);
285  ok_dec(ResourceCount, 4);
286 
287  ResourceCount = 8;
288  Status = LdrEnumResources(TestImage, &ResourceInfo, 2, &ResourceCount, Resources);
290  ok_dec(ResourceCount, 2);
291 
292  ResourceCount = 8;
293  Status = LdrEnumResources(TestImage, &ResourceInfo, 3, &ResourceCount, Resources);
295  ok_dec(ResourceCount, 1);
296 
297  ResourceCount = 8;
298  Status = LdrEnumResources(TestImage, &ResourceInfo, 99, &ResourceCount, Resources);
300  ok_dec(ResourceCount, 1);
301 
302  ResourceCount = 0;
303  Status = LdrEnumResources(TestImage, &ResourceInfo, 0, &ResourceCount, Resources);
305  ok_dec(ResourceCount, 8);
306 
307  ResourceCount = 7;
308  Status = LdrEnumResources(TestImage, &ResourceInfo, 0, &ResourceCount, Resources);
310  ok_dec(ResourceCount, 8);
311 
312  ResourceCount = 8;
313  Status = LdrEnumResources(NULL, &ResourceInfo, 1, &ResourceCount, Resources);
315  ok_dec(ResourceCount, 0);
316 
317  ResourceCount = 8;
318  Status = LdrEnumResources(TestImage, &ResourceInfo, 1, &ResourceCount, NULL);
320  ok_dec(ResourceCount, 4);
321 
322  ResourceCount = 8;
323  _SEH2_TRY
324  {
326  }
328  {
329  Status = 0xDeadC0de;
330  }
331  _SEH2_END
332  ok_hex(Status, 0xDeadC0de);
333 
334  ResourceCount = 42;
335  _SEH2_TRY
336  {
337  Status = LdrEnumResources(TestImage, &ResourceInfo, 1, NULL, Resources);
338  }
340  {
341  Status = 0xDeadC0de;
342  }
343  _SEH2_END
344  ok_hex(Status, 0xDeadC0de);
345  ok_dec(ResourceCount, 42);
346 
347  ResourceCount = 8;
348  Status = LdrEnumResources(TestImage + 2, &ResourceInfo, 1, &ResourceCount, NULL);
350  ok_dec(ResourceCount, 0);
351 
352  TestImage->Resources.TypeEntries[0].DataIsDirectory = 0;
353  Status = LdrEnumResources(TestImage, &ResourceInfo, 1, &ResourceCount, NULL);
355  ok_dec(ResourceCount, 0);
356 
357 }
358 
360 {
361  TEST_IMAGE TestImage;
362 
363  Test_Parameters(&TestImage);
364  Test_Data(&TestImage);
365 
366 }
NTSTATUS NTAPI LdrEnumResources(_In_ PVOID BaseAddress, _In_ PLDR_RESOURCE_INFO ResourceInfo, _In_ ULONG Level, _Inout_ ULONG *ResourceCount, _Out_writes_to_(*ResourceCount, *ResourceCount) LDR_ENUM_RESOURCE_INFO *Resources)
Definition: res.c:343
DWORD CodePage
Definition: pedump.c:461
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
static void Test_Parameters(PTEST_IMAGE TestImage)
#define DWORD_PTR
Definition: treelist.c:76
IMAGE_RESOURCE_DIRECTORY Name1Directory
WORD NumberOfRelocations
Definition: pedump.c:293
WCHAR StringBuffer[20]
IMAGE_RESOURCE_DIRECTORY_ENTRY Lang1Entries[2]
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
struct _TEST_IMAGE TEST_IMAGE
#define IMAGE_NT_OPTIONAL_HDR32_MAGIC
Definition: ntimage.h:376
IMAGE_RESOURCE_DIRECTORY Lang2Directory
#define ok_ptr(expression, result)
Definition: atltest.h:108
uint16_t * PWCHAR
Definition: typedefs.h:55
IMAGE_RESOURCE_DIRECTORY Name2Directory
DWORD PointerToRawData
Definition: pedump.c:290
#define ok_enumres(_Res, _Type, _Name, _Lang, _Data, _Size)
IMAGE_RESOURCE_DIRECTORY Lang4Directory
#define ok_hex(expression, result)
Definition: atltest.h:94
ULONG_PTR Type
Definition: ldrtypes.h:181
_SEH2_TRY
Definition: create.c:4226
DWORD Id
#define IMAGE_DOS_SIGNATURE
Definition: pedump.c:89
TEST_RESOURCES Resources
IMAGE_RESOURCE_DIRECTORY Lang3Directory
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:848
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
START_TEST(LdrEnumResources)
IMAGE_RESOURCE_DIRECTORY_STRING Name1String
ULONG_PTR Name
Definition: ldrtypes.h:182
smooth NULL
Definition: ftsmooth.c:416
Definition: pedump.c:457
WORD SizeOfOptionalHeader
Definition: ntddk_ex.h:127
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
struct _TEST_IMAGE * PTEST_IMAGE
#define IMAGE_NT_SIGNATURE
Definition: pedump.c:93
#define IMAGE_FILE_MACHINE_I386
Definition: pedump.c:174
DWORD OffsetToData
Definition: pedump.c:459
IMAGE_RESOURCE_DIRECTORY_ENTRY TypeEntries[2]
struct _IMAGE_OPTIONAL_HEADER IMAGE_OPTIONAL_HEADER
WORD NumberOfLinenumbers
Definition: pedump.c:294
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:345
DWORD NumberOfSymbols
Definition: ntddk_ex.h:126
IMAGE_NT_HEADERS NtHeaders
DWORD PointerToLinenumbers
Definition: pedump.c:292
__wchar_t WCHAR
Definition: xmlstorage.h:180
IMAGE_RESOURCE_DIRECTORY Lang1Directory
IMAGE_DOS_HEADER DosHeader
struct _TEST_RESOURCES TEST_RESOURCES
VOID InitializeTestImage(PTEST_IMAGE TestImage)
IMAGE_RESOURCE_DATA_ENTRY DataEntries[8]
static VOID InitializeIdEntry(PTEST_RESOURCES Resource, PIMAGE_RESOURCE_DIRECTORY_ENTRY DirEntry, USHORT Id, PVOID Data)
static ULONG ResourceCount
Definition: inbv.c:92
struct _TEST_RESOURCES * PTEST_RESOURCES
#define STATUS_RESOURCE_DATA_NOT_FOUND
Definition: ntstatus.h:359
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
static VOID InitializeResourceDirectory(PIMAGE_RESOURCE_DIRECTORY ResourceDirectory, USHORT NumberOfNamedEntries, USHORT NumberOfIdEntries)
IMAGE_RESOURCE_DIRECTORY_ENTRY Name1Entries[2]
static VOID InitializeDataEntry(PVOID ImageBase, PIMAGE_RESOURCE_DATA_ENTRY DataEntry, PVOID Data, ULONG Size)
static VOID InitializeTestResource(PVOID ImageBase, PTEST_RESOURCES Resource)
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
struct _IMAGE_DOS_HEADER IMAGE_DOS_HEADER
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
static VOID InitializeNamedEntry(PTEST_RESOURCES Resource, PIMAGE_RESOURCE_DIRECTORY_ENTRY DirEntry, PWCHAR Name, PVOID Data)
IMAGE_RESOURCE_DIRECTORY_ENTRY Lang3Entries[2]
IMAGE_RESOURCE_DIRECTORY TypeDirectory
Status
Definition: gdiplustypes.h:24
Definition: pedump.c:413
static void Test_Data(PTEST_IMAGE TestImage)
_SEH2_END
Definition: create.c:4400
ULONG DataIsDirectory
Definition: ntimage.h:195
unsigned short USHORT
Definition: pedump.c:61
DWORD PointerToSymbolTable
Definition: ntddk_ex.h:125
union _IMAGE_SECTION_HEADER::@1551 Misc
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
IMAGE_SECTION_HEADER SectionHeaders[1]
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
ULONG_PTR Language
Definition: ldrtypes.h:183
IMAGE_RESOURCE_DIRECTORY_ENTRY Name2Entries[2]
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
unsigned int ULONG
Definition: retypes.h:1
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define IMAGE_DIRECTORY_ENTRY_RESOURCE
Definition: pedump.c:261
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define memset(x, y, z)
Definition: compat.h:39
#define ok_dec(expression, result)
Definition: atltest.h:101
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
DWORD PointerToRelocations
Definition: pedump.c:291
IMAGE_RESOURCE_DIRECTORY_ENTRY Lang4Entries[2]
DWORD Reserved
Definition: pedump.c:462
IMAGE_RESOURCE_DIRECTORY_ENTRY Lang2Entries[2]
DWORD Size
Definition: pedump.c:460