3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ldr/resource.c
6 * PURPOSE: Resource loader
7 * PROGRAMMERS: Eric Kohl (ekohl@rz-online.de)
10 /* INCLUDES *****************************************************************/
12 #include <ddk/ntddk.h>
15 #include <internal/debug.h>
17 /* FUNCTIONS ****************************************************************/
20 LdrAccessResource(IN PVOID BaseAddress,
21 IN PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry,
22 OUT PVOID *Resource OPTIONAL,
23 OUT PULONG Size OPTIONAL)
25 PIMAGE_SECTION_HEADER Section;
26 PIMAGE_NT_HEADERS NtHeader;
33 Data = (ULONG)RtlImageDirectoryEntryToData (BaseAddress,
35 IMAGE_DIRECTORY_ENTRY_RESOURCE,
38 return STATUS_RESOURCE_DATA_NOT_FOUND;
40 if ((ULONG)BaseAddress & 1)
42 /* loaded as ordinary file */
43 NtHeader = RtlImageNtHeader((PVOID)((ULONG)BaseAddress & ~1UL));
44 Offset = (ULONG)BaseAddress - Data + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
45 Section = RtlImageRvaToSection (NtHeader, BaseAddress, NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);
48 return STATUS_RESOURCE_DATA_NOT_FOUND;
51 if (Section->Misc.VirtualSize < ResourceDataEntry->OffsetToData)
53 SectionRva = RtlImageRvaToSection (NtHeader, BaseAddress, ResourceDataEntry->OffsetToData)->VirtualAddress;
54 SectionVa = RtlImageRvaToVa(NtHeader, BaseAddress, SectionRva, NULL);
55 Offset = SectionRva - SectionVa + Data - Section->VirtualAddress;
61 *Resource = (PVOID)(ResourceDataEntry->OffsetToData - Offset + (ULONG)BaseAddress);
66 *Size = ResourceDataEntry->Size;
69 return STATUS_SUCCESS;
74 LdrFindResource_U(PVOID BaseAddress,
75 PLDR_RESOURCE_INFO ResourceInfo,
77 PIMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry)
79 PIMAGE_RESOURCE_DIRECTORY ResDir;
80 PIMAGE_RESOURCE_DIRECTORY ResBase;
81 PIMAGE_RESOURCE_DIRECTORY_ENTRY ResEntry;
82 NTSTATUS Status = STATUS_SUCCESS;
88 DPRINT ("LdrFindResource_U()\n");
90 /* Get the pointer to the resource directory */
91 ResDir = (PIMAGE_RESOURCE_DIRECTORY)
92 RtlImageDirectoryEntryToData (BaseAddress,
94 IMAGE_DIRECTORY_ENTRY_RESOURCE,
98 return STATUS_RESOURCE_DATA_NOT_FOUND;
101 DPRINT("ResourceDirectory: %x\n", (ULONG)ResDir);
105 /* Let's go into resource tree */
106 for (i = 0; i < Level; i++)
108 DPRINT("ResDir: %x\n", (ULONG)ResDir);
109 Id = ((PULONG)ResourceInfo)[i];
110 EntryCount = ResDir->NumberOfNamedEntries;
111 ResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(ResDir + 1);
112 DPRINT("ResEntry %x\n", (ULONG)ResEntry);
115 /* Resource name is a unicode string */
116 for (; EntryCount--; ResEntry++)
118 /* Scan entries for equal name */
119 if (ResEntry->Name & 0x80000000)
121 ws = (PWCHAR)((ULONG)ResDir + (ResEntry->Name & 0x7FFFFFFF));
122 if (!wcsncmp((PWCHAR)Id, ws + 1, *ws ) &&
123 wcslen((PWCHAR)Id) == (int)*ws )
132 /* We use ID number instead of string */
133 ResEntry += EntryCount;
134 EntryCount = ResDir->NumberOfIdEntries;
135 for (; EntryCount--; ResEntry++)
137 /* Scan entries for equal name */
138 if (ResEntry->Name == Id)
140 DPRINT("ID entry found %x\n", Id);
145 DPRINT("Error %lu\n", i);
150 return STATUS_RESOURCE_TYPE_NOT_FOUND;
153 return STATUS_RESOURCE_NAME_NOT_FOUND;
156 if (ResDir->NumberOfNamedEntries || ResDir->NumberOfIdEntries)
158 /* Use the first available language */
159 ResEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(ResDir + 1);
162 return STATUS_RESOURCE_LANG_NOT_FOUND;
165 return STATUS_RESOURCE_DATA_NOT_FOUND;
168 return STATUS_INVALID_PARAMETER;
171 ResDir = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)ResBase +
172 (ResEntry->OffsetToData & 0x7FFFFFFF));
174 DPRINT("ResourceDataEntry: %x\n", (ULONG)ResDir);
176 if (ResourceDataEntry)
178 *ResourceDataEntry = (PVOID)ResDir;