- fixed definition of RtlImageRvaToVa - imported the Ldr resource functions from wine and share them in lib/rtl 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 _____
Modified: trunk/reactos/include/ndk/rtlfuncs.h --- 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, _____
Modified: trunk/reactos/lib/ntdll/def/ntdll.def --- 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 _____
Deleted: trunk/reactos/lib/ntdll/ldr/res.c --- 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].V irtualAddress; - Section = RtlImageRvaToSection(NtHeader, BaseAddress, NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].V irtualAddress); - 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 */ _____
Modified: trunk/reactos/lib/ntdll/ntdll.xml --- 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> _____
Modified: trunk/reactos/lib/ntdll/rtl/libsupp.c --- 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; +} _____
Added: trunk/reactos/lib/rtl/i386/res_asm.s --- 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 _____
Modified: trunk/reactos/lib/rtl/image.c --- 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); _____
Added: trunk/reactos/lib/rtl/res.c --- 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 _____
Modified: trunk/reactos/lib/rtl/rtl.h --- 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 */ _____
Modified: trunk/reactos/lib/rtl/rtl.xml --- 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> _____
Deleted: trunk/reactos/ntoskrnl/ldr/resource.c --- 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]