Modified: trunk/reactos/include/ndk/rtlfuncs.h
Modified: trunk/reactos/lib/ntdll/def/ntdll.def
Deleted: trunk/reactos/lib/ntdll/ldr/res.c
Modified: trunk/reactos/lib/ntdll/ntdll.xml
Modified: trunk/reactos/lib/ntdll/rtl/libsupp.c
Added: trunk/reactos/lib/rtl/i386/res_asm.s
Modified: trunk/reactos/lib/rtl/image.c
Added: trunk/reactos/lib/rtl/res.c
Modified: trunk/reactos/lib/rtl/rtl.h
Modified: trunk/reactos/lib/rtl/rtl.xml
Deleted: trunk/reactos/ntoskrnl/ldr/resource.c
Modified: trunk/reactos/ntoskrnl/ntoskrnl.xml
Modified: trunk/reactos/ntoskrnl/rtl/libsupp.c
--- trunk/reactos/include/ndk/rtlfuncs.h 2005-12-08 23:48:53 UTC (rev 19986)
+++ trunk/reactos/include/ndk/rtlfuncs.h 2005-12-08 23:55:34 UTC (rev 19987)
@@ -2092,7 +2092,7 @@
);
NTSYSAPI
-ULONG
+PVOID
NTAPI
RtlImageRvaToVa(
PIMAGE_NT_HEADERS NtHeader,
--- trunk/reactos/lib/ntdll/def/ntdll.def 2005-12-08 23:48:53 UTC (rev 19986)
+++ trunk/reactos/lib/ntdll/def/ntdll.def 2005-12-08 23:55:34 UTC (rev 19987)
@@ -36,7 +36,7 @@
KiUserExceptionDispatcher@8
LdrAccessResource@16
LdrDisableThreadCalloutsForDll@4
-;LdrEnumResources@20
+LdrEnumResources@20
LdrFindEntryForAddress@8
LdrFindResourceDirectory_U@16
LdrFindResource_U@16
--- trunk/reactos/lib/ntdll/ldr/res.c 2005-12-08 23:48:53 UTC (rev 19986)
+++ trunk/reactos/lib/ntdll/ldr/res.c 2005-12-08 23:55:34 UTC (rev 19987)
@@ -1,387 +0,0 @@
-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: lib/ntdll/ldr/res.c
- * PURPOSE: Resource access for PE executables
- * PROGRAMMERS: Jean Michault
- * Rex Jolliff (rex@lvcablemodem.com)
- * Robert Dickenson (robd@mok.lvcm.com)
- * NOTES: Parts based on Wine code
- * Copyright 1995 Thomas Sandford
- * Copyright 1996 Martin von Loewis
- * Copyright 2003 Alexandre Julliard
- * Copyright 1993 Robert J. Amstadt
- * Copyright 1995 Alexandre Julliard
- * Copyright 1997 Marcus Meissner
- */
-
-/*
- * TODO:
- * - any comments ??
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntdll.h>
-#define NDEBUG
-#include <debug.h>
-
-/* PROTOTYPES ****************************************************************/
-
-
-
-/* FUNCTIONS *****************************************************************/
-
-static PIMAGE_RESOURCE_DIRECTORY_ENTRY FASTCALL
-FindEntryById(PIMAGE_RESOURCE_DIRECTORY ResDir,
- ULONG Id)
-{
- PIMAGE_RESOURCE_DIRECTORY_ENTRY ResEntry;
- LONG low, high, mid, result;
-
- /* We use ID number instead of string */
- ResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(ResDir + 1) + ResDir->NumberOfNamedEntries;
- DPRINT("ResEntry %x - Resource ID number instead of string\n", (ULONG)ResEntry);
- DPRINT("EntryCount %d\n", (ULONG)ResDir->NumberOfIdEntries);
-
- low = 0;
- high = ResDir->NumberOfIdEntries - 1;
- mid = high/2;
- while( low <= high ) {
- result = Id - ResEntry[mid].Name;
- if(result == 0)
- return ResEntry + mid;
- if(result < 0)
- high = mid - 1;
- else
- low = mid + 1;
-
- mid = (low + high)/2;
- }
-
- return NULL;
-}
-
-static int FASTCALL
-PushLanguage(WORD *list, int pos, WORD lang)
-{
- int i;
-
- for (i = 0; i < pos; i++) {
- if (list[i] == lang) {
- return pos;
- }
- }
-
- list[pos++] = lang;
-
- return pos;
-}
-
-/*
- Status = LdrFindResource_U (hModule,
- &ResourceInfo,
- RESOURCE_DATA_LEVEL,
- &ResourceDataEntry);
- */
-NTSTATUS NTAPI
-LdrFindResource_U(PVOID BaseAddress,
- PLDR_RESOURCE_INFO ResourceInfo,
- ULONG Level,
- PIMAGE_RESOURCE_DATA_ENTRY* ResourceDataEntry)
-{
- PIMAGE_RESOURCE_DIRECTORY ResDir;
- PIMAGE_RESOURCE_DIRECTORY ResBase;
- PIMAGE_RESOURCE_DIRECTORY_ENTRY ResEntry;
- NTSTATUS Status = STATUS_SUCCESS;
- PWCHAR ws;
- ULONG i;
- ULONG Id;
- LONG low, high, mid, result;
- WORD list[9]; /* list of languages to try */
- int j, pos = 0;
- LCID UserLCID, SystemLCID;
- LANGID UserLangID, SystemLangID;
- BOOLEAN MappedAsDataFile;
-
- MappedAsDataFile = LdrMappedAsDataFile(&BaseAddress);
- DPRINT("LdrFindResource_U(%08x, %08x, %d, %08x)\n", BaseAddress, ResourceInfo, Level, ResourceDataEntry);
-
- /* Get the pointer to the resource directory */
- ResDir = (PIMAGE_RESOURCE_DIRECTORY)RtlImageDirectoryEntryToData(BaseAddress,
- ! MappedAsDataFile, IMAGE_DIRECTORY_ENTRY_RESOURCE, &i);
- if (ResDir == NULL) {
- return STATUS_RESOURCE_DATA_NOT_FOUND;
- }
-
- DPRINT("ResourceDirectory: %x Size: %d\n", (ULONG)ResDir, (int)i);
-
- ResBase = ResDir;
-
- /* Let's go into resource tree */
- for (i = 0; i < (2 < Level ? 2 : Level); i++) {
- DPRINT("ResDir: %x Level: %d\n", (ULONG)ResDir, i);
-
- Id = ((PULONG)ResourceInfo)[i];
-
- if (Id & 0xFFFF0000) {
- /* Resource name is a unicode string */
- ResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(ResDir + 1);
- DPRINT("ResEntry %x - Resource name is a unicode string\n", (ULONG)ResEntry);
- DPRINT("EntryCount %d\n", (ULONG)ResDir->NumberOfNamedEntries);
-
- low = 0;
- high = ResDir->NumberOfNamedEntries - 1;
- mid = high/2;
- while( low <= high ) {
- /* Does we need check if it's named entry, think not */
- ws = (PWCHAR)((ULONG)ResBase + (ResEntry[mid].Name & 0x7FFFFFFF));
- result = _wcsnicmp((PWCHAR)Id, ws + 1, *ws);
- /* Need double check for lexical & length */
- if(result == 0) {
- result = (wcslen((PWCHAR)Id) - (int)*ws);
- if(result == 0) {
- ResEntry += mid;
- goto found;
- }
- }
- if(result < 0)
- high = mid - 1;
- else
- low = mid + 1;
-
- mid = (low + high)/2;
- }
- } else {
- /* We use ID number instead of string */
- ResEntry = FindEntryById(ResDir, Id);
- if (NULL != ResEntry) goto found;
- }
-
- switch (i) {
- case 0:
- DPRINT("Error %lu - STATUS_RESOURCE_TYPE_NOT_FOUND\n", i);
- return STATUS_RESOURCE_TYPE_NOT_FOUND;
- case 1:
- DPRINT("Error %lu - STATUS_RESOURCE_NAME_NOT_FOUND\n", i);
- return STATUS_RESOURCE_NAME_NOT_FOUND;
- case 2:
- if (ResDir->NumberOfNamedEntries || ResDir->NumberOfIdEntries) {
- /* Use the first available language */
- ResEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(ResDir + 1);
- break;
- }
- DPRINT("Error %lu - STATUS_RESOURCE_LANG_NOT_FOUND\n", i);
- return STATUS_RESOURCE_LANG_NOT_FOUND;
- case 3:
- DPRINT("Error %lu - STATUS_RESOURCE_DATA_NOT_FOUND\n", i);
- return STATUS_RESOURCE_DATA_NOT_FOUND;
- default:
- DPRINT("Error %lu - STATUS_INVALID_PARAMETER\n", i);
- return STATUS_INVALID_PARAMETER;
- }
-found:;
- ResDir = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)ResBase +
- (ResEntry->OffsetToData & 0x7FFFFFFF));
- }
-
- if (3 <= Level) {
- /* 1. specified language */
- pos = PushLanguage(list, pos, ResourceInfo->Language );
-
- /* 2. specified language with neutral sublanguage */
- pos = PushLanguage(list, pos, MAKELANGID(PRIMARYLANGID(ResourceInfo->Language), SUBLANG_NEUTRAL));
-
- /* 3. neutral language with neutral sublanguage */
- pos = PushLanguage(list, pos, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
-
- /* if no explicitly specified language, try some defaults */
- if (LANG_NEUTRAL == PRIMARYLANGID(ResourceInfo->Language)) {
- /* user defaults, unless SYS_DEFAULT sublanguage specified */
- if (SUBLANG_SYS_DEFAULT != SUBLANGID(ResourceInfo->Language)) {
- NtQueryDefaultLocale(TRUE, &UserLCID);
- UserLangID = LANGIDFROMLCID(UserLCID);
-
- /* 4. current thread locale language */
- pos = PushLanguage(list, pos, LANGIDFROMLCID(NtCurrentTeb()->CurrentLocale));
-
- /* 5. user locale language */
- pos = PushLanguage(list, pos, UserLangID);
-
- /* 6. user locale language with neutral sublanguage */
- pos = PushLanguage(list, pos, MAKELANGID(PRIMARYLANGID(UserLangID),
- SUBLANG_NEUTRAL));
- }
-
- /* now system defaults */
- NtQueryDefaultLocale(FALSE, &SystemLCID);
- SystemLangID = LANGIDFROMLCID(SystemLCID);
-
- /* 7. system locale language */
- pos = PushLanguage(list, pos, SystemLangID);
-
- /* 8. system locale language with neutral sublanguage */
- pos = PushLanguage(list, pos, MAKELANGID(PRIMARYLANGID(SystemLangID),
- SUBLANG_NEUTRAL));
-
- /* 9. English */
- pos = PushLanguage(list, pos, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT));
- }
-
- ResEntry = NULL;
- for (j = 0; NULL == ResEntry && j < pos; j++)
- ResEntry = FindEntryById(ResDir, list[j]);
- if (NULL == ResEntry) {
- if (ResDir->NumberOfNamedEntries || ResDir->NumberOfIdEntries) {
- /* Use the first available language */
- ResEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(ResDir + 1);
- } else {
- DPRINT("Error - STATUS_RESOURCE_LANG_NOT_FOUND\n", i);
- return STATUS_RESOURCE_LANG_NOT_FOUND;
- }
- }
- ResDir = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)ResBase +
- (ResEntry->OffsetToData & 0x7FFFFFFF));
- if (3 < Level) {
- DPRINT("Error - STATUS_INVALID_PARAMETER\n", i);
- return STATUS_INVALID_PARAMETER;
- }
- }
- DPRINT("ResourceDataEntry: %x\n", (ULONG)ResDir);
-
- if (ResourceDataEntry) {
- *ResourceDataEntry = (PVOID)ResDir;
- }
- return Status;
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS NTAPI
-LdrAccessResource(IN PVOID BaseAddress,
- IN PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry,
- OUT PVOID* Resource OPTIONAL,
- OUT PULONG Size OPTIONAL)
-{
- PIMAGE_SECTION_HEADER Section;
- PIMAGE_NT_HEADERS NtHeader;
- ULONG SectionRva;
- ULONG SectionVa;
- ULONG DataSize;
- ULONG Offset = 0;
- ULONG Data;
- BOOLEAN MappedAsDataFile;
-
- if(!ResourceDataEntry)
- return STATUS_RESOURCE_DATA_NOT_FOUND;
-
- MappedAsDataFile = LdrMappedAsDataFile(&BaseAddress);
- Data = (ULONG)RtlImageDirectoryEntryToData(BaseAddress,
- TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &DataSize);
- if (Data == 0) {
- return STATUS_RESOURCE_DATA_NOT_FOUND;
- }
- if (MappedAsDataFile) {
- /* loaded as ordinary file */
- NtHeader = RtlImageNtHeader(BaseAddress);
- Offset = (ULONG)BaseAddress - Data + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
- Section = RtlImageRvaToSection(NtHeader, BaseAddress, NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);
- if (Section == NULL) {
- return STATUS_RESOURCE_DATA_NOT_FOUND;
- }
- if (Section->Misc.VirtualSize < ResourceDataEntry->OffsetToData) {
- SectionRva = RtlImageRvaToSection (NtHeader, BaseAddress, ResourceDataEntry->OffsetToData)->VirtualAddress;
- SectionVa = RtlImageRvaToVa(NtHeader, BaseAddress, SectionRva, NULL);
- Offset = SectionRva - SectionVa + Data - Section->VirtualAddress;
- }
- }
- if (Resource) {
- *Resource = (PVOID)(ResourceDataEntry->OffsetToData - Offset + (ULONG)BaseAddress);
- }
- if (Size) {
- *Size = ResourceDataEntry->Size;
- }
- return STATUS_SUCCESS;
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS NTAPI
-LdrFindResourceDirectory_U(IN PVOID BaseAddress,
- IN PLDR_RESOURCE_INFO info,
- IN ULONG level,
- OUT PIMAGE_RESOURCE_DIRECTORY* addr)
-{
- PIMAGE_RESOURCE_DIRECTORY ResDir;
- PIMAGE_RESOURCE_DIRECTORY_ENTRY ResEntry;
- ULONG EntryCount;
- ULONG i;
- NTSTATUS Status = STATUS_SUCCESS;
- WCHAR* ws;
- PWCHAR* name = (PWCHAR*) info;
-
- /* Get the pointer to the resource directory */
- ResDir = (PIMAGE_RESOURCE_DIRECTORY)
- RtlImageDirectoryEntryToData(BaseAddress, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &i);
- if (ResDir == NULL) {
- return STATUS_RESOURCE_DATA_NOT_FOUND;
- }
-
- /* Let's go into resource tree */
- for (i = 0; i < level; i++, name++) {
- EntryCount = ResDir->NumberOfNamedEntries;
- ResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(ResDir + 1);
- if ((ULONG)(*name) & 0xFFFF0000) {
- /* Resource name is a unicode string */
- for (; EntryCount--; ResEntry++) {
- /* Scan entries for equal name */
- if (ResEntry->Name & 0x80000000) {
- ws = (WCHAR*)((ULONG)ResDir + (ResEntry->Name & 0x7FFFFFFF));
- if (!wcsncmp(*name, ws + 1, *ws) && wcslen(*name) == (int)*ws) {
- goto found;
- }
- }
- }
- } else {
- /* We use ID number instead of string */
- ResEntry += EntryCount;
- EntryCount = ResDir->NumberOfIdEntries;
- for (; EntryCount--; ResEntry++) {
- /* Scan entries for equal name */
- if (ResEntry->Name == (ULONG)(*name))
- goto found;
- }
- }
- switch (i) {
- case 0:
- return STATUS_RESOURCE_TYPE_NOT_FOUND;
- case 1:
- return STATUS_RESOURCE_NAME_NOT_FOUND;
- case 2:
- Status = STATUS_RESOURCE_LANG_NOT_FOUND;
- /* Just use first language entry */
- if (ResDir->NumberOfNamedEntries || ResDir->NumberOfIdEntries) {
- ResEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(ResDir + 1);
- break;
- }
- return Status;
- case 3:
- return STATUS_RESOURCE_DATA_NOT_FOUND;
- default:
- return STATUS_INVALID_PARAMETER;
- }
-found:;
- ResDir = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)ResDir + ResEntry->OffsetToData);
- }
- if (addr) {
- *addr = (PVOID)ResDir;
- }
- return Status;
-}
-
-/* EOF */
--- trunk/reactos/lib/ntdll/ntdll.xml 2005-12-08 23:48:53 UTC (rev 19986)
+++ trunk/reactos/lib/ntdll/ntdll.xml 2005-12-08 23:55:34 UTC (rev 19987)
@@ -11,6 +11,7 @@
<library>rtl</library>
<library>intrlck</library>
<library>string</library>
+ <library>pseh</library>
<linkerflag>-lgcc</linkerflag>
<linkerflag>-nostdlib</linkerflag>
<linkerflag>-nostartfiles</linkerflag>
@@ -23,7 +24,6 @@
<file>dbgui.c</file>
</directory>
<directory name="ldr">
- <file>res.c</file>
<file>startup.c</file>
<file>utils.c</file>
</directory>
--- trunk/reactos/lib/ntdll/rtl/libsupp.c 2005-12-08 23:48:53 UTC (rev 19986)
+++ trunk/reactos/lib/ntdll/rtl/libsupp.c 2005-12-08 23:55:34 UTC (rev 19987)
@@ -328,3 +328,105 @@
return NULL;
}
+
+/*
+ * Ldr Resource support code
+ */
+
+IMAGE_RESOURCE_DIRECTORY *find_entry_by_name( IMAGE_RESOURCE_DIRECTORY *dir,
+ LPCWSTR name, void *root,
+ int want_dir );
+IMAGE_RESOURCE_DIRECTORY *find_entry_by_id( IMAGE_RESOURCE_DIRECTORY *dir,
+ WORD id, void *root, int want_dir );
+IMAGE_RESOURCE_DIRECTORY *find_first_entry( IMAGE_RESOURCE_DIRECTORY *dir,
+ void *root, int want_dir );
+int push_language( USHORT *list, ULONG pos, WORD lang );
+
+/**********************************************************************
+ * find_entry
+ *
+ * Find a resource entry
+ */
+NTSTATUS find_entry( PVOID BaseAddress, LDR_RESOURCE_INFO *info,
+ ULONG level, void **ret, int want_dir )
+{
+ ULONG size;
+ void *root;
+ IMAGE_RESOURCE_DIRECTORY *resdirptr;
+ USHORT list[9]; /* list of languages to try */
+ int i, pos = 0;
+ LCID user_lcid, system_lcid;
+
+ root = RtlImageDirectoryEntryToData( BaseAddress, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &size );
+ if (!root) return STATUS_RESOURCE_DATA_NOT_FOUND;
+ resdirptr = root;
+
+ if (!level--) goto done;
+ if (!(*ret = find_entry_by_name( resdirptr, (LPCWSTR)info->Type, root, want_dir || level )))
+ return STATUS_RESOURCE_TYPE_NOT_FOUND;
+ if (!level--) return STATUS_SUCCESS;
+
+ resdirptr = *ret;
+ if (!(*ret = find_entry_by_name( resdirptr, (LPCWSTR)info->Name, root, want_dir || level )))
+ return STATUS_RESOURCE_NAME_NOT_FOUND;
+ if (!level--) return STATUS_SUCCESS;
+ if (level) return STATUS_INVALID_PARAMETER; /* level > 3 */
+
+ /* 1. specified language */
+ pos = push_language( list, pos, info->Language );
+
+ /* 2. specified language with neutral sublanguage */
+ pos = push_language( list, pos, MAKELANGID( PRIMARYLANGID(info->Language), SUBLANG_NEUTRAL ) );
+
+ /* 3. neutral language with neutral sublanguage */
+ pos = push_language( list, pos, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ) );
+
+ /* if no explicitly specified language, try some defaults */
+ if (PRIMARYLANGID(info->Language) == LANG_NEUTRAL)
+ {
+ /* user defaults, unless SYS_DEFAULT sublanguage specified */
+ if (SUBLANGID(info->Language) != SUBLANG_SYS_DEFAULT)
+ {
+ /* 4. current thread locale language */
+ pos = push_language( list, pos, LANGIDFROMLCID(NtCurrentTeb()->CurrentLocale) );
+
+ if (NT_SUCCESS(NtQueryDefaultLocale(TRUE, &user_lcid)))
+ {
+ /* 5. user locale language */
+ pos = push_language( list, pos, LANGIDFROMLCID(user_lcid) );
+
+ /* 6. user locale language with neutral sublanguage */
+ pos = push_language( list, pos, MAKELANGID( PRIMARYLANGID(user_lcid), SUBLANG_NEUTRAL ) );
+ }
+ }
+
+ /* now system defaults */
+
+ if (NT_SUCCESS(NtQueryDefaultLocale(FALSE, &system_lcid)))
+ {
+ /* 7. system locale language */
+ pos = push_language( list, pos, LANGIDFROMLCID( system_lcid ) );
+
+ /* 8. system locale language with neutral sublanguage */
+ pos = push_language( list, pos, MAKELANGID( PRIMARYLANGID(system_lcid), SUBLANG_NEUTRAL ) );
+ }
+
+ /* 9. English */
+ pos = push_language( list, pos, MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT ) );
+ }
+
+ resdirptr = *ret;
+ for (i = 0; i < pos; i++)
+ if ((*ret = find_entry_by_id( resdirptr, list[i], root, want_dir ))) return STATUS_SUCCESS;
+
+ /* if no explicitly specified language, return the first entry */
+ if (PRIMARYLANGID(info->Language) == LANG_NEUTRAL)
+ {
+ if ((*ret = find_first_entry( resdirptr, root, want_dir ))) return STATUS_SUCCESS;
+ }
+ return STATUS_RESOURCE_LANG_NOT_FOUND;
+
+done:
+ *ret = resdirptr;
+ return STATUS_SUCCESS;
+}
--- trunk/reactos/lib/rtl/i386/res_asm.s 2005-12-08 23:48:53 UTC (rev 19986)
+++ trunk/reactos/lib/rtl/i386/res_asm.s 2005-12-08 23:55:34 UTC (rev 19987)
@@ -0,0 +1,20 @@
+#include <ndk/asm.h>
+.intel_syntax noprefix
+
+/*
+ * On x86, Shrinker, an executable compressor, depends on the
+ * "call access_resource" instruction being there.
+ */
+.globl _LdrAccessResource@16
+_LdrAccessResource@16:
+ push ebp
+ mov ebp, esp
+ sub esp, 4
+ push [ebp + 24]
+ push [ebp + 20]
+ push [ebp + 16]
+ push [ebp + 12]
+ push [ebp + 8]
+ call _LdrpAccessResource@16
+ leave
+ ret 16
Property changes on: trunk/reactos/lib/rtl/i386/res_asm.s
___________________________________________________________________
Name: svn:eol-style
+ native
--- trunk/reactos/lib/rtl/image.c 2005-12-08 23:48:53 UTC (rev 19986)
+++ trunk/reactos/lib/rtl/image.c 2005-12-08 23:55:34 UTC (rev 19987)
@@ -80,7 +80,7 @@
return (PVOID)((ULONG_PTR)BaseAddress + Va);
/* image mapped as ordinary file, we must find raw pointer */
- return (PVOID)RtlImageRvaToVa (NtHeader, BaseAddress, Va, NULL);
+ return RtlImageRvaToVa (NtHeader, BaseAddress, Va, NULL);
}
@@ -117,7 +117,7 @@
/*
* @implemented
*/
-ULONG
+PVOID
NTAPI
RtlImageRvaToVa (
PIMAGE_NT_HEADERS NtHeader,
@@ -143,7 +143,7 @@
*SectionHeader = Section;
}
- return (ULONG)((ULONG_PTR)BaseAddress +
+ return (PVOID)((ULONG_PTR)BaseAddress +
Rva +
Section->PointerToRawData -
(ULONG_PTR)Section->VirtualAddress);
--- trunk/reactos/lib/rtl/res.c 2005-12-08 23:48:53 UTC (rev 19986)
+++ trunk/reactos/lib/rtl/res.c 2005-12-08 23:55:34 UTC (rev 19987)
@@ -0,0 +1,297 @@
+/*
+ * PE file resources
+ *
+ * Copyright 1995 Thomas Sandford
+ * Copyright 1996 Martin von Loewis
+ * Copyright 2003 Alexandre Julliard
+ * Copyright 1993 Robert J. Amstadt
+ * Copyright 1997 Marcus Meissner
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <rtl.h>
+
+#define NDEBUG
+#include <debug.h>
+
+NTSTATUS find_entry( PVOID BaseAddress, LDR_RESOURCE_INFO *info,
+ ULONG level, void **ret, int want_dir );
+
+/* FUNCTIONS ****************************************************************/
+
+_SEH_FILTER(page_fault)
+{
+ if (_SEH_GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ||
+ _SEH_GetExceptionCode() == EXCEPTION_PRIV_INSTRUCTION)
+ return EXCEPTION_EXECUTE_HANDLER;
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
+/**********************************************************************
+ * is_data_file_module
+ *
+ * Check if a module handle is for a LOAD_LIBRARY_AS_DATAFILE module.
+ */
+static int is_data_file_module( PVOID BaseAddress )
+{
+ return (ULONG_PTR)BaseAddress & 1;
+}
+
+
+/**********************************************************************
+ * push_language
+ *
+ * push a language in the list of languages to try
+ */
+int push_language( USHORT *list, ULONG pos, WORD lang )
+{
+ int i;
+ for (i = 0; i < pos; i++) if (list[i] == lang) return pos;
+ list[pos++] = lang;
+ return pos;
+}
+
+
+/**********************************************************************
+ * find_first_entry
+ *
+ * Find the first suitable entry in a resource directory
+ */
+IMAGE_RESOURCE_DIRECTORY *find_first_entry( IMAGE_RESOURCE_DIRECTORY *dir,
+ void *root, int want_dir )
+{
+ const IMAGE_RESOURCE_DIRECTORY_ENTRY *entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1);
+ int pos;
+
+ for (pos = 0; pos < dir->NumberOfNamedEntries + dir->NumberOfIdEntries; pos++)
+ {
+ if (!entry[pos].DataIsDirectory == !want_dir)
+ return (IMAGE_RESOURCE_DIRECTORY *)((char *)root + entry[pos].OffsetToDirectory);
+ }
+ return NULL;
+}
+
+
+/**********************************************************************
+ * find_entry_by_id
+ *
+ * Find an entry by id in a resource directory
+ */
+IMAGE_RESOURCE_DIRECTORY *find_entry_by_id( IMAGE_RESOURCE_DIRECTORY *dir,
+ WORD id, void *root, int want_dir )
+{
+ const IMAGE_RESOURCE_DIRECTORY_ENTRY *entry;
+ int min, max, pos;
+
+ entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1);
+ min = dir->NumberOfNamedEntries;
+ max = min + dir->NumberOfIdEntries - 1;
+ while (min <= max)
+ {
+ pos = (min + max) / 2;
+ if (entry[pos].Id == id)
+ {
+ if (!entry[pos].DataIsDirectory == !want_dir)
+ {
+ DPRINT("root %p dir %p id %04x ret %p\n",
+ root, dir, id, (const char*)root + entry[pos].OffsetToDirectory);
+ return (IMAGE_RESOURCE_DIRECTORY *)((char *)root + entry[pos].OffsetToDirectory);
+ }
+ break;
+ }
+ if (entry[pos].Id > id) max = pos - 1;
+ else min = pos + 1;
+ }
+ DPRINT("root %p dir %p id %04x not found\n", root, dir, id );
+ return NULL;
+}
+
+
+/**********************************************************************
+ * find_entry_by_name
+ *
+ * Find an entry by name in a resource directory
+ */
+IMAGE_RESOURCE_DIRECTORY *find_entry_by_name( IMAGE_RESOURCE_DIRECTORY *dir,
+ LPCWSTR name, void *root,
+ int want_dir )
+{
+ const IMAGE_RESOURCE_DIRECTORY_ENTRY *entry;
+ const IMAGE_RESOURCE_DIR_STRING_U *str;
+ int min, max, res, pos, namelen;
+
+ if (!((ULONG_PTR)name & 0xFFFF0000)) return find_entry_by_id( dir, (ULONG_PTR)name & 0xFFFF, root, want_dir );
+ entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1);
+ namelen = wcslen(name);
+ min = 0;
+ max = dir->NumberOfNamedEntries - 1;
+ while (min <= max)
+ {
+ pos = (min + max) / 2;
+ str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const char *)root + entry[pos].NameOffset);
+ res = wcsncmp( name, str->NameString, str->Length );
+ if (!res && namelen == str->Length)
+ {
+ if (!entry[pos].DataIsDirectory == !want_dir)
+ {
+ DPRINT("root %p dir %p name %ws ret %p\n",
+ root, dir, name, (const char*)root + entry[pos].OffsetToDirectory);
+ return (IMAGE_RESOURCE_DIRECTORY *)((char *)root + entry[pos].OffsetToDirectory);
+ }
+ break;
+ }
+ if (res < 0) max = pos - 1;
+ else min = pos + 1;
+ }
+ DPRINT("root %p dir %p name %ws not found\n", root, dir, name);
+ return NULL;
+}
+
+#ifdef __i386__
+NTSTATUS NTAPI LdrpAccessResource( PVOID BaseAddress, IMAGE_RESOURCE_DATA_ENTRY *entry,
+ void **ptr, ULONG *size )
+#else
+static NTSTATUS LdrpAccessResource( PVOID BaseAddress, IMAGE_RESOURCE_DATA_ENTRY *entry,
+ void **ptr, ULONG *size )
+#endif
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ _SEH_TRY
+ {
+ ULONG dirsize;
+
+ if (!RtlImageDirectoryEntryToData( BaseAddress, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &dirsize ))
+ status = STATUS_RESOURCE_DATA_NOT_FOUND;
+ else
+ {
+ if (ptr)
+ {
+ if (is_data_file_module(BaseAddress))
+ {
+ PVOID mod = (PVOID)((ULONG_PTR)BaseAddress & ~1);
+ *ptr = RtlImageRvaToVa( RtlImageNtHeader(mod), mod, entry->OffsetToData, NULL );
+ }
+ else *ptr = (char *)BaseAddress + entry->OffsetToData;
+ }
+ if (size) *size = entry->Size;
+ }
+ }
+ _SEH_EXCEPT(page_fault)
+ {
+ status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ return status;
+}
+
+
+/*
+ * @implemented
+ */
+NTSTATUS NTAPI
+LdrFindResource_U(PVOID BaseAddress,
+ PLDR_RESOURCE_INFO ResourceInfo,
+ ULONG Level,
+ PIMAGE_RESOURCE_DATA_ENTRY* ResourceDataEntry)
+{
+ void *res;
+ NTSTATUS status = STATUS_SUCCESS;
+
+ _SEH_TRY
+ {
+ if (ResourceInfo)
+ {
+ DPRINT( "module %p type %ws name %ws lang %04lx level %ld\n",
+ BaseAddress, (LPCWSTR)ResourceInfo->Type,
+ Level > 1 ? (LPCWSTR)ResourceInfo->Name : L"",
+ Level > 2 ? ResourceInfo->Language : 0, Level );
+ }
+
+ status = find_entry( BaseAddress, ResourceInfo, Level, &res, FALSE );
+ if (status == STATUS_SUCCESS) *ResourceDataEntry = res;
+ }
+ _SEH_EXCEPT(page_fault)
+ {
+ status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ return status;
+}
+
+#ifndef __i386__
+/*
+ * @implemented
+ */
+NTSTATUS NTAPI
+LdrAccessResource(IN PVOID BaseAddress,
+ IN PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry,
+ OUT PVOID* Resource OPTIONAL,
+ OUT PULONG Size OPTIONAL)
+{
+ return LdrpAccessResource( BaseAddress, ResourceDataEntry, Resource, Size );
+}
+#endif
+
+/*
+ * @implemented
+ */
+NTSTATUS NTAPI
+LdrFindResourceDirectory_U(IN PVOID BaseAddress,
+ IN PLDR_RESOURCE_INFO info,
+ IN ULONG level,
+ OUT PIMAGE_RESOURCE_DIRECTORY* addr)
+{
+ void *res;
+ NTSTATUS status = STATUS_SUCCESS;
+
+ _SEH_TRY
+ {
+ if (info)
+ {
+ DPRINT( "module %p type %ws name %ws lang %04lx level %ld\n",
+ BaseAddress, (LPCWSTR)info->Type,
+ level > 1 ? (LPCWSTR)info->Name : L"",
+ level > 2 ? info->Language : 0, level );
+ }
+
+ status = find_entry( BaseAddress, info, level, &res, TRUE );
+ if (status == STATUS_SUCCESS) *addr = res;
+ }
+ _SEH_EXCEPT(page_fault)
+ {
+ status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ return status;
+}
+
+
+/*
+ * @unimplemented
+ */
+NTSTATUS NTAPI
+LdrEnumResources(IN PVOID BaseAddress,
+ IN PLDR_RESOURCE_INFO ResourceInfo,
+ IN ULONG Level,
+ IN OUT PULONG ResourceCount,
+ OUT PVOID Resources OPTIONAL)
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
Property changes on: trunk/reactos/lib/rtl/res.c
___________________________________________________________________
Name: svn:keywords
+ author date revision
Name: svn:eol-style
+ native
--- trunk/reactos/lib/rtl/rtl.h 2005-12-08 23:48:53 UTC (rev 19986)
+++ trunk/reactos/lib/rtl/rtl.h 2005-12-08 23:55:34 UTC (rev 19987)
@@ -23,4 +23,6 @@
#include <reactos/helper.h>
#include "rtlp.h"
+#include <pseh/pseh.h>
+
/* EOF */
--- trunk/reactos/lib/rtl/rtl.xml 2005-12-08 23:48:53 UTC (rev 19986)
+++ trunk/reactos/lib/rtl/rtl.xml 2005-12-08 23:55:34 UTC (rev 19987)
@@ -5,6 +5,7 @@
<define name="NO_RTL_INLINES" />
<define name="_NTSYSTEM_" />
<define name="_NTDLLBUILD_" />
+ <define name="_SEH_NO_NATIVE_NLG" />
<include base="rtl">.</include>
<if property="ARCH" value="i386">
<directory name="i386">
@@ -36,6 +37,7 @@
<file>random_asm.S</file>
<file>pow_asm.s</file>
<file>prefetchmemory_asm.s</file>
+ <file>res_asm.s</file>
<file>sin_asm.s</file>
<file>sqrt_asm.s</file>
<file>tan_asm.s</file>
@@ -76,6 +78,7 @@
<file>random.c</file>
<file>rangelist.c</file>
<file>registry.c</file>
+ <file>res.c</file>
<file>resource.c</file>
<file>sd.c</file>
<file>security.c</file>
--- trunk/reactos/ntoskrnl/ldr/resource.c 2005-12-08 23:48:53 UTC (rev 19986)
+++ trunk/reactos/ntoskrnl/ldr/resource.c 2005-12-08 23:55:34 UTC (rev 19987)
@@ -1,228 +0,0 @@
-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/ldr/resource.c
- * PURPOSE: Resource loader
- *
- * PROGRAMMERS: Eric Kohl (ekohl@rz-online.de)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* FUNCTIONS ****************************************************************/
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-LdrAccessResource(IN PVOID BaseAddress,
- IN PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry,
- OUT PVOID *Resource OPTIONAL,
- OUT PULONG Size OPTIONAL)
-{
- PIMAGE_SECTION_HEADER Section;
- PIMAGE_NT_HEADERS NtHeader;
- ULONG SectionRva;
- ULONG SectionVa;
- ULONG DataSize;
- ULONG Offset = 0;
- ULONG Data;
-
- if(!ResourceDataEntry)
- return STATUS_RESOURCE_DATA_NOT_FOUND;
-
- Data = (ULONG)RtlImageDirectoryEntryToData (BaseAddress,
- TRUE,
[truncated at 1000 lines; 260 more skipped]