3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ldr/resource.c
6 * PURPOSE: Resource loader
8 * PROGRAMMERS: Eric Kohl (ekohl@rz-online.de)
11 /* INCLUDES *****************************************************************/
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
;
200 LdrFindResourceDirectory_U(
201 IN PVOID BaseAddress
,
202 IN PLDR_RESOURCE_INFO ResourceInfo
,
204 OUT PIMAGE_RESOURCE_DIRECTORY
*ResourceDirectory
208 return STATUS_NOT_IMPLEMENTED
;
217 IN PVOID BaseAddress
,
218 IN PLDR_RESOURCE_INFO ResourceInfo
,
220 IN OUT PULONG ResourceCount
,
221 OUT PVOID Resources OPTIONAL
225 return STATUS_NOT_IMPLEMENTED
;