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 ****************************************************************/
23 LdrAccessResource(IN PVOID BaseAddress,
24 IN PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry,
25 OUT PVOID *Resource OPTIONAL,
26 OUT PULONG Size OPTIONAL)
28 PIMAGE_SECTION_HEADER Section;
29 PIMAGE_NT_HEADERS NtHeader;
36 if(!ResourceDataEntry)
37 return STATUS_RESOURCE_DATA_NOT_FOUND;
39 Data = (ULONG)RtlImageDirectoryEntryToData (BaseAddress,
41 IMAGE_DIRECTORY_ENTRY_RESOURCE,
44 return STATUS_RESOURCE_DATA_NOT_FOUND;
46 if ((ULONG)BaseAddress & 1)
48 /* loaded as ordinary file */
49 NtHeader = RtlImageNtHeader((PVOID)((ULONG)BaseAddress & ~1UL));
50 Offset = (ULONG)BaseAddress - Data + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
51 Section = RtlImageRvaToSection (NtHeader, BaseAddress, NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);
54 return STATUS_RESOURCE_DATA_NOT_FOUND;
57 if (Section->Misc.VirtualSize < ResourceDataEntry->OffsetToData)
59 SectionRva = RtlImageRvaToSection (NtHeader, BaseAddress, ResourceDataEntry->OffsetToData)->VirtualAddress;
60 SectionVa = RtlImageRvaToVa(NtHeader, BaseAddress, SectionRva, NULL);
61 Offset = SectionRva - SectionVa + Data - Section->VirtualAddress;
67 *Resource = (PVOID)(ResourceDataEntry->OffsetToData - Offset + (ULONG)BaseAddress);
72 *Size = ResourceDataEntry->Size;
75 return STATUS_SUCCESS;
83 LdrFindResource_U(PVOID BaseAddress,
84 PLDR_RESOURCE_INFO ResourceInfo,
86 PIMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry)
88 PIMAGE_RESOURCE_DIRECTORY ResDir;
89 PIMAGE_RESOURCE_DIRECTORY ResBase;
90 PIMAGE_RESOURCE_DIRECTORY_ENTRY ResEntry;
91 NTSTATUS Status = STATUS_SUCCESS;
97 DPRINT ("LdrFindResource_U()\n");
99 /* Get the pointer to the resource directory */
100 ResDir = (PIMAGE_RESOURCE_DIRECTORY)
101 RtlImageDirectoryEntryToData (BaseAddress,
103 IMAGE_DIRECTORY_ENTRY_RESOURCE,
107 return STATUS_RESOURCE_DATA_NOT_FOUND;
110 DPRINT("ResourceDirectory: %x\n", (ULONG)ResDir);
114 /* Let's go into resource tree */
115 for (i = 0; i < Level; i++)
117 DPRINT("ResDir: %x\n", (ULONG)ResDir);
118 Id = ((PULONG)ResourceInfo)[i];
119 EntryCount = ResDir->NumberOfNamedEntries;
120 ResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(ResDir + 1);
121 DPRINT("ResEntry %x\n", (ULONG)ResEntry);
124 /* Resource name is a unicode string */
125 for (; EntryCount--; ResEntry++)
127 /* Scan entries for equal name */
128 if (ResEntry->Name & 0x80000000)
130 ws = (PWCHAR)((ULONG)ResDir + (ResEntry->Name & 0x7FFFFFFF));
131 if (!wcsncmp((PWCHAR)Id, ws + 1, *ws ) &&
132 wcslen((PWCHAR)Id) == (ULONG)*ws )
141 /* We use ID number instead of string */
142 ResEntry += EntryCount;
143 EntryCount = ResDir->NumberOfIdEntries;
144 for (; EntryCount--; ResEntry++)
146 /* Scan entries for equal name */
147 if (ResEntry->Name == Id)
149 DPRINT("ID entry found %x\n", Id);
154 DPRINT("Error %lu\n", i);
159 return STATUS_RESOURCE_TYPE_NOT_FOUND;
162 return STATUS_RESOURCE_NAME_NOT_FOUND;
165 if (ResDir->NumberOfNamedEntries || ResDir->NumberOfIdEntries)
167 /* Use the first available language */
168 ResEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(ResDir + 1);
171 return STATUS_RESOURCE_LANG_NOT_FOUND;
174 return STATUS_RESOURCE_DATA_NOT_FOUND;
177 return STATUS_INVALID_PARAMETER;
180 ResDir = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)ResBase +
181 (ResEntry->OffsetToData & 0x7FFFFFFF));
183 DPRINT("ResourceDataEntry: %x\n", (ULONG)ResDir);
185 if (ResourceDataEntry)
187 *ResourceDataEntry = (PVOID)ResDir;