From a5dea216ccad612784d4f0da3bdf60ad2c31f44c Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 9 Aug 2002 19:57:38 +0000 Subject: [PATCH] Implemented the RtlImage* functions, and use them to replace the PE_HEADER macro. --- dlls/ntdll/loader.c | 80 ++++++++++++++++++++++++++++++ dlls/ntdll/ntdll.spec | 4 +- dlls/ntdll/rtl.c | 17 ------- include/module.h | 7 --- include/ntddk.h | 3 ++ loader/elf.c | 3 +- loader/module.c | 10 ++-- loader/pe_image.c | 111 ++++++++++++++---------------------------- loader/pe_resource.c | 74 ++++++---------------------- misc/version.c | 18 ++++--- msdos/vxd.c | 7 ++- relay32/builtin32.c | 8 ++- relay32/relay386.c | 22 ++++----- relay32/snoop.c | 27 +++------- scheduler/process.c | 10 ++-- 15 files changed, 191 insertions(+), 210 deletions(-) diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index f572b339453..c9ec6844a66 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -68,3 +68,83 @@ NTSTATUS WINAPI LdrGetProcedureAddress(PVOID base, PANSI_STRING name, ULONG ord, return (*address) ? STATUS_SUCCESS : STATUS_DLL_NOT_FOUND; } + + +/*********************************************************************** + * RtlImageNtHeader (NTDLL.@) + */ +PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule) +{ + IMAGE_NT_HEADERS *ret = NULL; + IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)hModule; + + if (dos->e_magic == IMAGE_DOS_SIGNATURE) + { + ret = (IMAGE_NT_HEADERS *)((char *)dos + dos->e_lfanew); + if (ret->Signature != IMAGE_NT_SIGNATURE) ret = NULL; + } + return ret; +} + + +/*********************************************************************** + * RtlImageDirectoryEntryToData (NTDLL.@) + */ +PVOID WINAPI RtlImageDirectoryEntryToData( HMODULE module, BOOL image, WORD dir, ULONG *size ) +{ + const IMAGE_NT_HEADERS *nt; + DWORD addr; + + if ((ULONG_PTR)module & 1) /* mapped as data file */ + { + module = (HMODULE)((ULONG_PTR)module & ~1); + image = FALSE; + } + if (!(nt = RtlImageNtHeader( module ))) return NULL; + if (dir >= nt->OptionalHeader.NumberOfRvaAndSizes) return NULL; + if (!(addr = nt->OptionalHeader.DataDirectory[dir].VirtualAddress)) return NULL; + *size = nt->OptionalHeader.DataDirectory[dir].Size; + if (image || addr < nt->OptionalHeader.SizeOfHeaders) return (char *)module + addr; + + /* not mapped as image, need to find the section containing the virtual address */ + return RtlImageRvaToVa( nt, module, addr, NULL ); +} + + +/*********************************************************************** + * RtlImageRvaToSection (NTDLL.@) + */ +PIMAGE_SECTION_HEADER WINAPI RtlImageRvaToSection( const IMAGE_NT_HEADERS *nt, + HMODULE module, DWORD rva ) +{ + int i; + IMAGE_SECTION_HEADER *sec = (IMAGE_SECTION_HEADER*)((char*)&nt->OptionalHeader + + nt->FileHeader.SizeOfOptionalHeader); + for (i = 0; i < nt->FileHeader.NumberOfSections; i++, sec++) + { + if ((sec->VirtualAddress <= rva) && (sec->VirtualAddress + sec->SizeOfRawData > rva)) + return sec; + } + return NULL; +} + + +/*********************************************************************** + * RtlImageRvaToVa (NTDLL.@) + */ +PVOID WINAPI RtlImageRvaToVa( const IMAGE_NT_HEADERS *nt, HMODULE module, + DWORD rva, IMAGE_SECTION_HEADER **section ) +{ + IMAGE_SECTION_HEADER *sec; + + if (section && *section) /* try this section first */ + { + sec = *section; + if ((sec->VirtualAddress <= rva) && (sec->VirtualAddress + sec->SizeOfRawData > rva)) + goto found; + } + if (!(sec = RtlImageRvaToSection( nt, module, rva ))) return NULL; + found: + if (section) *section = sec; + return (char *)module + sec->PointerToRawData + (rva - sec->VirtualAddress); +} diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 81b01ab3b6c..1f97e81f5c2 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -403,8 +403,10 @@ @ stdcall RtlGetSaclSecurityDescriptor(ptr ptr ptr ptr)RtlGetSaclSecurityDescriptor @ stub RtlGetUserInfoHeap @ stdcall RtlIdentifierAuthoritySid(ptr) RtlIdentifierAuthoritySid -@ stub RtlImageDirectoryEntryToData +@ stdcall RtlImageDirectoryEntryToData(long long long ptr) RtlImageDirectoryEntryToData @ stdcall RtlImageNtHeader(long) RtlImageNtHeader +@ stdcall RtlImageRvaToSection(ptr long long) RtlImageRvaToSection +@ stdcall RtlImageRvaToVa(ptr long long ptr) RtlImageRvaToVa @ stdcall RtlImpersonateSelf(long) RtlImpersonateSelf @ stdcall RtlInitAnsiString(ptr str) RtlInitAnsiString @ stub RtlInitCodePageTable diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c index 74e844ea81e..b07b25d1658 100644 --- a/dlls/ntdll/rtl.c +++ b/dlls/ntdll/rtl.c @@ -346,23 +346,6 @@ BOOLEAN WINAPI RtlDosPathNameToNtPathName_U( } -/*********************************************************************** - * RtlImageNtHeader (NTDLL.@) - */ -PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule) -{ - IMAGE_NT_HEADERS *ret = NULL; - IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)hModule; - - if (dos->e_magic == IMAGE_DOS_SIGNATURE) - { - ret = (IMAGE_NT_HEADERS *)((char *)dos + dos->e_lfanew); - if (ret->Signature != IMAGE_NT_SIGNATURE) ret = NULL; - } - return ret; -} - - /****************************************************************************** * RtlCreateEnvironment [NTDLL.@] */ diff --git a/include/module.h b/include/module.h index ef9145003df..748fbe6fa79 100644 --- a/include/module.h +++ b/include/module.h @@ -170,13 +170,6 @@ extern WINE_MODREF *MODULE_modref_list; #define NE_MODULE_NAME(pModule) \ (((OFSTRUCT *)((char*)(pModule) + (pModule)->fileinfo))->szPathName) -#define PE_HEADER(module) \ - ((IMAGE_NT_HEADERS*)((LPBYTE)(module) + \ - (((IMAGE_DOS_HEADER*)(module))->e_lfanew))) - -#define PE_SECTIONS(module) \ - ((IMAGE_SECTION_HEADER*)((LPBYTE)&PE_HEADER(module)->OptionalHeader + \ - PE_HEADER(module)->FileHeader.SizeOfOptionalHeader)) enum loadorder_type { diff --git a/include/ntddk.h b/include/ntddk.h index 90e6ca13e91..0bf93db57f7 100644 --- a/include/ntddk.h +++ b/include/ntddk.h @@ -1073,6 +1073,9 @@ LPVOID WINAPI RtlNormalizeProcessParams(LPVOID x); DWORD WINAPI RtlNtStatusToDosError(DWORD error); BOOLEAN WINAPI RtlGetNtProductType(LPDWORD type); PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule); +PIMAGE_SECTION_HEADER WINAPI RtlImageRvaToSection( const IMAGE_NT_HEADERS *, HMODULE, DWORD ); +PVOID WINAPI RtlImageDirectoryEntryToData( HMODULE module, BOOL image, WORD dir, ULONG *size ); +PVOID WINAPI RtlImageRvaToVa( const IMAGE_NT_HEADERS *, HMODULE, DWORD, IMAGE_SECTION_HEADER **); DWORD WINAPI RtlOpenCurrentUser( IN ACCESS_MASK DesiredAccess, diff --git a/loader/elf.c b/loader/elf.c index e833cd0dddb..f302f06a918 100644 --- a/loader/elf.c +++ b/loader/elf.c @@ -33,7 +33,6 @@ #include "snoop.h" #include "file.h" -#include "module.h" #include "wine/debug.h" #include "winerror.h" @@ -77,7 +76,7 @@ static HMODULE ELF_CreateDummyModule( LPCSTR libname, LPCSTR modname ) dh = (PIMAGE_DOS_HEADER)hmod; dh->e_magic = IMAGE_DOS_SIGNATURE; dh->e_lfanew = sizeof(IMAGE_DOS_HEADER); - nth = PE_HEADER(hmod); + nth = (IMAGE_NT_HEADERS *)(dh + 1); nth->Signature = IMAGE_NT_SIGNATURE; nth->FileHeader.Machine = IMAGE_FILE_MACHINE_I386; nth->FileHeader.NumberOfSections = 1; diff --git a/loader/module.c b/loader/module.c index 6a41cb5f2d6..19a7a8e9236 100644 --- a/loader/module.c +++ b/loader/module.c @@ -121,7 +121,7 @@ WINE_MODREF *MODULE_AllocModRef( HMODULE hModule, LPCSTR filename ) if (wm->next) wm->next->prev = wm; MODULE_modref_list = wm; - if (!(PE_HEADER(hModule)->FileHeader.Characteristics & IMAGE_FILE_DLL)) + if (!(RtlImageNtHeader(hModule)->FileHeader.Characteristics & IMAGE_FILE_DLL)) { if (!exe_modref) exe_modref = wm; else FIXME( "Trying to load second .EXE file: %s\n", filename ); @@ -434,11 +434,11 @@ HMODULE16 MODULE_CreateDummyModule( LPCSTR filename, HMODULE module32 ) /* Set version and flags */ if (module32) { - pModule->expected_version = - ((PE_HEADER(module32)->OptionalHeader.MajorSubsystemVersion & 0xff) << 8 ) | - (PE_HEADER(module32)->OptionalHeader.MinorSubsystemVersion & 0xff); + IMAGE_NT_HEADERS *nt = RtlImageNtHeader( module32 ); + pModule->expected_version = ((nt->OptionalHeader.MajorSubsystemVersion & 0xff) << 8 ) | + (nt->OptionalHeader.MinorSubsystemVersion & 0xff); pModule->flags |= NE_FFLAGS_WIN32; - if (PE_HEADER(module32)->FileHeader.Characteristics & IMAGE_FILE_DLL) + if (nt->FileHeader.Characteristics & IMAGE_FILE_DLL) pModule->flags |= NE_FFLAGS_LIBMODULE | NE_FFLAGS_SINGLEDATA; } diff --git a/loader/pe_image.c b/loader/pe_image.c index 84a999c214e..029665c512f 100644 --- a/loader/pe_image.c +++ b/loader/pe_image.c @@ -55,27 +55,6 @@ WINE_DECLARE_DEBUG_CHANNEL(relay); WINE_DECLARE_DEBUG_CHANNEL(segment); -static IMAGE_EXPORT_DIRECTORY *get_exports( HMODULE hmod ) -{ - IMAGE_EXPORT_DIRECTORY *ret = NULL; - IMAGE_DATA_DIRECTORY *dir = PE_HEADER(hmod)->OptionalHeader.DataDirectory - + IMAGE_DIRECTORY_ENTRY_EXPORT; - if (dir->Size && dir->VirtualAddress) - ret = (IMAGE_EXPORT_DIRECTORY *)((char *)hmod + dir->VirtualAddress); - return ret; -} - -static IMAGE_IMPORT_DESCRIPTOR *get_imports( HMODULE hmod ) -{ - IMAGE_IMPORT_DESCRIPTOR *ret = NULL; - IMAGE_DATA_DIRECTORY *dir = PE_HEADER(hmod)->OptionalHeader.DataDirectory - + IMAGE_DIRECTORY_ENTRY_IMPORT; - if (dir->Size && dir->VirtualAddress) - ret = (IMAGE_IMPORT_DESCRIPTOR *)((char *)hmod + dir->VirtualAddress); - return ret; -} - - /* convert PE image VirtualAddress to Real Address */ #define RVA(x) ((void *)((char *)load_addr+(unsigned int)(x))) @@ -89,12 +68,11 @@ void dump_exports( HMODULE hModule ) DWORD *function,*functions; BYTE **name; unsigned int load_addr = hModule; + IMAGE_EXPORT_DIRECTORY *pe_exports; + DWORD rva_start, size; - DWORD rva_start = PE_HEADER(hModule)->OptionalHeader - .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; - DWORD rva_end = rva_start + PE_HEADER(hModule)->OptionalHeader - .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; - IMAGE_EXPORT_DIRECTORY *pe_exports = (IMAGE_EXPORT_DIRECTORY*)RVA(rva_start); + pe_exports = RtlImageDirectoryEntryToData( hModule, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size ); + rva_start = (char *)pe_exports - (char *)hModule; Module = (char*)RVA(pe_exports->Name); DPRINTF("*******EXPORT DATA*******\n"); @@ -117,7 +95,7 @@ void dump_exports( HMODULE hModule ) DPRINTF( " %s", (char*)RVA(name[j]) ); break; } - if ((*function >= rva_start) && (*function <= rva_end)) + if ((*function >= rva_start) && (*function <= rva_start + size)) DPRINTF(" (forwarded -> %s)", (char *)RVA(*function)); DPRINTF("\n"); } @@ -142,30 +120,24 @@ static FARPROC PE_FindExportedFunction( BYTE ** name, *ename = NULL; int i, ordinal; unsigned int load_addr = wm->module; - DWORD rva_start, rva_end, addr; + DWORD rva_start, addr; char * forward; - IMAGE_EXPORT_DIRECTORY *exports = get_exports(wm->module); + FARPROC proc; + IMAGE_EXPORT_DIRECTORY *exports; + DWORD exp_size; + + if (!(exports = RtlImageDirectoryEntryToData( wm->module, TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, &exp_size ))) + return NULL; + + if (HIWORD(funcName)) TRACE("(%s)\n",funcName); + else TRACE("(%d)\n",LOWORD(funcName)); - if (HIWORD(funcName)) - TRACE("(%s)\n",funcName); - else - TRACE("(%d)\n",(int)funcName); - if (!exports) { - /* Not a fatal problem, some apps do - * GetProcAddress(0,"RegisterPenApp") which triggers this - * case. - */ - WARN("Module %08x(%s)/MODREF %p doesn't have a exports table.\n",wm->module,wm->modname,wm); - return NULL; - } ordinals= RVA(exports->AddressOfNameOrdinals); function= RVA(exports->AddressOfFunctions); name = RVA(exports->AddressOfNames); forward = NULL; - rva_start = PE_HEADER(wm->module)->OptionalHeader - .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; - rva_end = rva_start + PE_HEADER(wm->module)->OptionalHeader - .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; + rva_start = (char *)exports - (char *)wm->module; if (HIWORD(funcName)) { @@ -219,9 +191,10 @@ static FARPROC PE_FindExportedFunction( } addr = function[ordinal]; if (!addr) return NULL; - if ((addr < rva_start) || (addr >= rva_end)) + + proc = RVA(addr); + if (((char *)proc < (char *)exports) || ((char *)proc >= (char *)exports + exp_size)) { - FARPROC proc = RVA(addr); if (snoop) { if (!ename) ename = "@"; @@ -232,8 +205,7 @@ static FARPROC PE_FindExportedFunction( else /* forward entry point */ { WINE_MODREF *wm_fw; - FARPROC proc; - char *forward = RVA(addr); + char *forward = (char *)proc; char module[256]; char *end = strchr(forward, '.'); @@ -257,10 +229,12 @@ static FARPROC PE_FindExportedFunction( */ DWORD PE_fixup_imports( WINE_MODREF *wm ) { - IMAGE_IMPORT_DESCRIPTOR *pe_imp; unsigned int load_addr = wm->module; int i,characteristics_detection=1; - IMAGE_IMPORT_DESCRIPTOR *imports = get_imports(wm->module); + IMAGE_IMPORT_DESCRIPTOR *imports, *pe_imp; + DWORD size; + + imports = RtlImageDirectoryEntryToData( wm->module, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size ); /* first, count the number of imported non-internal modules */ pe_imp = imports; @@ -406,21 +380,11 @@ HMODULE PE_LoadImage( HANDLE hFile, LPCSTR filename, DWORD flags ) /* virus check */ hModule = (HMODULE)base; - nt = PE_HEADER( hModule ); + nt = RtlImageNtHeader( hModule ); if (nt->OptionalHeader.AddressOfEntryPoint) { - int i; - IMAGE_SECTION_HEADER *sec = (IMAGE_SECTION_HEADER*)((char*)&nt->OptionalHeader + - nt->FileHeader.SizeOfOptionalHeader); - for (i = 0; i < nt->FileHeader.NumberOfSections; i++, sec++) - { - if (nt->OptionalHeader.AddressOfEntryPoint < sec->VirtualAddress) - continue; - if (nt->OptionalHeader.AddressOfEntryPoint < sec->VirtualAddress+sec->SizeOfRawData) - break; - } - if (i == nt->FileHeader.NumberOfSections) + if (!RtlImageRvaToSection( nt, hModule, nt->OptionalHeader.AddressOfEntryPoint )) MESSAGE("VIRUS WARNING: PE module has an invalid entrypoint (0x%08lx) " "outside all sections (possibly infected by Tchernobyl/SpaceFiller virus)!\n", nt->OptionalHeader.AddressOfEntryPoint ); @@ -448,7 +412,7 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule, LPCSTR filename, DWORD flags, HANDLE hFile, BOOL builtin ) { DWORD load_addr = (DWORD)hModule; /* for RVA */ - IMAGE_NT_HEADERS *nt = PE_HEADER(hModule); + IMAGE_NT_HEADERS *nt; IMAGE_DATA_DIRECTORY *dir; IMAGE_EXPORT_DIRECTORY *pe_export = NULL; WINE_MODREF *wm; @@ -456,6 +420,7 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule, LPCSTR filename, DWORD flags, /* Retrieve DataDirectory entries */ + nt = RtlImageNtHeader(hModule); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXPORT; if (dir->Size) pe_export = (PIMAGE_EXPORT_DIRECTORY)RVA(dir->VirtualAddress); @@ -651,10 +616,10 @@ typedef DWORD (CALLBACK *DLLENTRYPROC)(HMODULE,DWORD,LPVOID); BOOL PE_InitDLL( HMODULE module, DWORD type, LPVOID lpReserved ) { BOOL retv = TRUE; - IMAGE_NT_HEADERS *nt = PE_HEADER(module); + IMAGE_NT_HEADERS *nt = RtlImageNtHeader(module); /* Is this a library? And has it got an entrypoint? */ - if ((nt->FileHeader.Characteristics & IMAGE_FILE_DLL) && + if (nt && (nt->FileHeader.Characteristics & IMAGE_FILE_DLL) && (nt->OptionalHeader.AddressOfEntryPoint)) { DLLENTRYPROC entry = (void*)((char*)module + nt->OptionalHeader.AddressOfEntryPoint); @@ -692,19 +657,17 @@ void PE_InitTls( void ) { WINE_MODREF *wm; IMAGE_NT_HEADERS *peh; - DWORD size,datasize; + DWORD size,datasize,dirsize; LPVOID mem; PIMAGE_TLS_DIRECTORY pdir; int delta; for (wm = MODULE_modref_list;wm;wm=wm->next) { - peh = PE_HEADER(wm->module); - delta = wm->module - peh->OptionalHeader.ImageBase; - if (!peh->OptionalHeader.DataDirectory[IMAGE_FILE_THREAD_LOCAL_STORAGE].VirtualAddress) - continue; - pdir = (LPVOID)(wm->module + peh->OptionalHeader. - DataDirectory[IMAGE_FILE_THREAD_LOCAL_STORAGE].VirtualAddress); - + peh = RtlImageNtHeader(wm->module); + pdir = RtlImageDirectoryEntryToData( wm->module, TRUE, + IMAGE_DIRECTORY_ENTRY_TLS, &dirsize ); + if (!pdir) continue; + delta = (char *)wm->module - (char *)peh->OptionalHeader.ImageBase; if ( wm->tlsindex == -1 ) { LPDWORD xaddr; diff --git a/loader/pe_resource.c b/loader/pe_resource.c index 0f06b621371..ed830def2fe 100644 --- a/loader/pe_resource.c +++ b/loader/pe_resource.c @@ -32,34 +32,13 @@ #include "wine/unicode.h" #include "windef.h" #include "winnls.h" +#include "ntddk.h" #include "winerror.h" -#include "module.h" -#include "stackframe.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(resource); -/********************************************************************** - * get_module_base - * - * Get the base address of a module - */ -static const void *get_module_base( HMODULE hmod ) -{ - if (!hmod) hmod = GetModuleHandleA( NULL ); - else if (!HIWORD(hmod)) - { - FIXME("Enumeration of 16-bit resources is not supported\n"); - SetLastError(ERROR_INVALID_HANDLE); - return NULL; - } - - /* clear low order bit in case of LOAD_LIBRARY_AS_DATAFILE module */ - return (void *)((ULONG_PTR)hmod & ~1); -} - - /********************************************************************** * is_data_file_module * @@ -71,28 +50,6 @@ inline static int is_data_file_module( HMODULE hmod ) } -/********************************************************************** - * get_data_file_ptr - * - * Get a pointer to a given offset in a file mapped as data file. - */ -static const void *get_data_file_ptr( const void *base, DWORD offset ) -{ - const IMAGE_NT_HEADERS *nt = PE_HEADER(base); - const IMAGE_SECTION_HEADER *sec = (IMAGE_SECTION_HEADER *)((char *)&nt->OptionalHeader + - nt->FileHeader.SizeOfOptionalHeader); - int i; - - /* find the section containing the virtual address */ - for (i = 0; i < nt->FileHeader.NumberOfSections; i++, sec++) - { - if ((sec->VirtualAddress <= offset) && (sec->VirtualAddress + sec->SizeOfRawData > offset)) - return (char *)base + sec->PointerToRawData + (offset - sec->VirtualAddress); - } - return NULL; -} - - /********************************************************************** * get_resdir * @@ -100,20 +57,16 @@ static const void *get_data_file_ptr( const void *base, DWORD offset ) */ static const IMAGE_RESOURCE_DIRECTORY* get_resdir( HMODULE hmod ) { - const IMAGE_DATA_DIRECTORY *dir; - const IMAGE_RESOURCE_DIRECTORY *ret = NULL; - const void *base = get_module_base( hmod ); + DWORD size; - if (base) + if (!hmod) hmod = GetModuleHandleA( NULL ); + else if (!HIWORD(hmod)) { - dir = &PE_HEADER(base)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]; - if (dir->Size && dir->VirtualAddress) - { - if (is_data_file_module(hmod)) ret = get_data_file_ptr( base, dir->VirtualAddress ); - else ret = (IMAGE_RESOURCE_DIRECTORY *)((char *)base + dir->VirtualAddress); - } + FIXME("Enumeration of 16-bit resources is not supported\n"); + SetLastError(ERROR_INVALID_HANDLE); + return NULL; } - return ret; + return RtlImageDirectoryEntryToData( hmod, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &size ); } @@ -325,16 +278,19 @@ HRSRC PE_FindResourceW( HMODULE hmod, LPCWSTR name, LPCWSTR type ) HGLOBAL PE_LoadResource( HMODULE hmod, HRSRC hRsrc ) { DWORD offset; - const void *base = get_module_base( hmod ); - if (!hRsrc || !base) return 0; + if (!hRsrc) return 0; + if (!hmod) hmod = GetModuleHandleA( NULL ); offset = ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData; if (is_data_file_module(hmod)) - return (HANDLE)get_data_file_ptr( base, offset ); + { + hmod = (HMODULE)((ULONG_PTR)hmod & ~1); + return (HGLOBAL)RtlImageRvaToVa( RtlImageNtHeader(hmod), hmod, offset, NULL ); + } else - return (HANDLE)((char *)base + offset); + return (HGLOBAL)((char *)hmod + offset); } diff --git a/misc/version.c b/misc/version.c index a7c7656672a..0db79967c3d 100644 --- a/misc/version.c +++ b/misc/version.c @@ -29,6 +29,7 @@ #include "winreg.h" #include "wingdi.h" #include "winuser.h" +#include "ntddk.h" #include "wine/winbase16.h" #include "module.h" #include "wine/debug.h" @@ -352,11 +353,11 @@ static void VERSION_Init(void) */ static DWORD VERSION_GetSystemDLLVersion( HMODULE hmod ) { - IMAGE_DATA_DIRECTORY *dir = PE_HEADER(hmod)->OptionalHeader.DataDirectory - + IMAGE_DIRECTORY_ENTRY_IMPORT; - if (dir->Size && dir->VirtualAddress) + DWORD size; + IMAGE_IMPORT_DESCRIPTOR *pe_imp; + + if ((pe_imp = RtlImageDirectoryEntryToData( hmod, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size ))) { - IMAGE_IMPORT_DESCRIPTOR *pe_imp = (IMAGE_IMPORT_DESCRIPTOR *)((char *)hmod + dir->VirtualAddress); for ( ; pe_imp->Name; pe_imp++) { char * name = (char *)hmod + (unsigned int)pe_imp->Name; @@ -364,7 +365,7 @@ static DWORD VERSION_GetSystemDLLVersion( HMODULE hmod ) if (!strncasecmp(name, "ntdll", 5)) { - switch(PE_HEADER(hmod)->OptionalHeader.MajorOperatingSystemVersion) { + switch(RtlImageNtHeader(hmod)->OptionalHeader.MajorOperatingSystemVersion) { case 3: MESSAGE("WARNING: very old native DLL (NT 3.x) used, might cause instability.\n"); return NT351; @@ -405,12 +406,14 @@ DWORD VERSION_GetLinkedDllVersion(void) WINE_MODREF *wm; DWORD WinVersion = NB_WINDOWS_VERSIONS; PIMAGE_OPTIONAL_HEADER ophd; + IMAGE_NT_HEADERS *nt; /* First check the native dlls provided. These have to be from one windows version */ for ( wm = MODULE_modref_list; wm; wm=wm->next ) { - ophd = &(PE_HEADER(wm->module)->OptionalHeader); + nt = RtlImageNtHeader(wm->module); + ophd = &nt->OptionalHeader; TRACE("%s: %02x.%02x/%02x.%02x/%02x.%02x/%02x.%02x\n", wm->modname, @@ -449,7 +452,8 @@ DWORD VERSION_GetLinkedDllVersion(void) if(WinVersion != NB_WINDOWS_VERSIONS) return WinVersion; /* we are using no external system dlls, look at the exe */ - ophd = &(PE_HEADER(GetModuleHandleA(NULL))->OptionalHeader); + nt = RtlImageNtHeader(GetModuleHandleA(NULL)); + ophd = &nt->OptionalHeader; TRACE("%02x.%02x/%02x.%02x/%02x.%02x/%02x.%02x\n", ophd->MajorLinkerVersion, ophd->MinorLinkerVersion, diff --git a/msdos/vxd.c b/msdos/vxd.c index 384fea36323..5b6dc1376d3 100644 --- a/msdos/vxd.c +++ b/msdos/vxd.c @@ -24,6 +24,7 @@ #include #include "winbase.h" #include "windef.h" +#include "ntddk.h" #include "wingdi.h" #include "winuser.h" #include "wine/winbase16.h" @@ -758,8 +759,10 @@ void WINAPI VXD_Win32s( CONTEXT86 *context ) (struct Win32sModule *)W32S_APP2WINE(context->Edx); struct Win32sModule *module = moduleTable + context->Ecx; - IMAGE_NT_HEADERS *nt_header = PE_HEADER(module->baseAddr); - IMAGE_SECTION_HEADER *pe_seg = PE_SECTIONS(module->baseAddr); + IMAGE_NT_HEADERS *nt_header = RtlImageNtHeader( (HMODULE)module->baseAddr ); + IMAGE_SECTION_HEADER *pe_seg = (IMAGE_SECTION_HEADER*)((char *)&nt_header->OptionalHeader + + nt_header->FileHeader.SizeOfOptionalHeader); + HFILE image = _lopen(module->pathName, OF_READ); BOOL error = (image == HFILE_ERROR); diff --git a/relay32/builtin32.c b/relay32/builtin32.c index 9f26d99514c..5e9879b3c0d 100644 --- a/relay32/builtin32.c +++ b/relay32/builtin32.c @@ -86,6 +86,7 @@ int BUILTIN32_dlclose( void *handle ) static void load_library( void *base, const char *filename ) { HMODULE module = (HMODULE)base; + IMAGE_NT_HEADERS *nt; WINE_MODREF *wm; char *fullname; DWORD len; @@ -95,8 +96,13 @@ static void load_library( void *base, const char *filename ) ERR("could not map image for %s\n", filename ? filename : "main exe" ); return; } + if (!(nt = RtlImageNtHeader( module ))) + { + ERR( "bad module for %s\n", filename ? filename : "main exe" ); + return; + } - if (!(PE_HEADER(module)->FileHeader.Characteristics & IMAGE_FILE_DLL)) + if (!(nt->FileHeader.Characteristics & IMAGE_FILE_DLL)) { /* if we already have an executable, ignore this one */ if (!main_module) main_module = module; diff --git a/relay32/relay386.c b/relay32/relay386.c index d9a4e9f725f..7da6c1a2a03 100644 --- a/relay32/relay386.c +++ b/relay32/relay386.c @@ -26,6 +26,7 @@ #include #include "winnt.h" +#include "ntddk.h" #include "winreg.h" #include "stackframe.h" #include "module.h" @@ -199,24 +200,22 @@ static const char *find_exported_name( const char *module, */ static void get_entry_point( char *buffer, DEBUG_ENTRY_POINT *relay ) { - IMAGE_DATA_DIRECTORY *dir; IMAGE_EXPORT_DIRECTORY *exp = NULL; DEBUG_ENTRY_POINT *debug; char *p, *base = NULL; const char *name; int ordinal = 0; WINE_MODREF *wm; + DWORD size; /* First find the module */ for (wm = MODULE_modref_list; wm; wm = wm->next) { if (!(wm->flags & WINE_MODREF_INTERNAL)) continue; - base = (char *)wm->module; - dir = &PE_HEADER(base)->OptionalHeader.DataDirectory[IMAGE_FILE_EXPORT_DIRECTORY]; - if (!dir->Size) continue; - exp = (IMAGE_EXPORT_DIRECTORY *)(base + dir->VirtualAddress); - debug = (DEBUG_ENTRY_POINT *)((char *)exp + dir->Size); + exp = RtlImageDirectoryEntryToData( wm->module, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size ); + if (!exp) continue; + debug = (DEBUG_ENTRY_POINT *)((char *)exp + size); if (debug <= relay && relay < debug + exp->NumberOfFunctions) { ordinal = relay - debug; @@ -226,6 +225,7 @@ static void get_entry_point( char *buffer, DEBUG_ENTRY_POINT *relay ) /* Now find the function */ + base = (char *)wm->module; strcpy( buffer, base + exp->Name ); p = buffer + strlen(buffer); if (p > buffer + 4 && !strcasecmp( p - 4, ".dll" )) p -= 4; @@ -504,18 +504,18 @@ __ASM_GLOBAL_FUNC( RELAY_CallFrom32Regs, */ void RELAY_SetupDLL( const char *module ) { - IMAGE_DATA_DIRECTORY *dir; IMAGE_EXPORT_DIRECTORY *exports; DEBUG_ENTRY_POINT *debug; DWORD *funcs; int i; const char *name; char *p, dllname[80]; + DWORD size; - dir = &PE_HEADER(module)->OptionalHeader.DataDirectory[IMAGE_FILE_EXPORT_DIRECTORY]; - if (!dir->Size) return; - exports = (IMAGE_EXPORT_DIRECTORY *)(module + dir->VirtualAddress); - debug = (DEBUG_ENTRY_POINT *)((char *)exports + dir->Size); + exports = RtlImageDirectoryEntryToData( (HMODULE)module, TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, &size ); + if (!exports) return; + debug = (DEBUG_ENTRY_POINT *)((char *)exports + size); funcs = (DWORD *)(module + exports->AddressOfFunctions); strcpy( dllname, module + exports->Name ); p = dllname + strlen(dllname) - 4; diff --git a/relay32/snoop.c b/relay32/snoop.c index 7fea6f85e8b..c43e44a9953 100644 --- a/relay32/snoop.c +++ b/relay32/snoop.c @@ -26,6 +26,7 @@ #include #include "winbase.h" #include "winnt.h" +#include "ntddk.h" #include "snoop.h" #include "stackframe.h" #include "wine/debug.h" @@ -175,30 +176,16 @@ FARPROC SNOOP_GetProcAddress(HMODULE hmod,LPCSTR name,DWORD ordinal,FARPROC origfun) { SNOOP_DLL *dll = firstdll; SNOOP_FUN *fun; - int j; - IMAGE_SECTION_HEADER *pe_seg = PE_SECTIONS(hmod); + IMAGE_SECTION_HEADER *sec; if (!TRACE_ON(snoop)) return origfun; if (!*(LPBYTE)origfun) /* 0x00 is an imposs. opcode, poss. dataref. */ return origfun; - for (j=0;jFileHeader.NumberOfSections;j++) - /* 0x42 is special ELF loader tag */ - if ((pe_seg[j].VirtualAddress==0x42) || - (((char *)origfun - (char *)hmod>=pe_seg[j].VirtualAddress)&& - ((char *)origfun - (char *)hmod FileHeader.NumberOfSections) || - (strstr(pe_seg[j].Name,"data")) || - !(pe_seg[j].Characteristics & IMAGE_SCN_CNT_CODE) - ) - return origfun; + + sec = RtlImageRvaToSection( RtlImageNtHeader(hmod), hmod, (char *)origfun - (char *)hmod ); + + if (!sec || !(sec->Characteristics & IMAGE_SCN_CNT_CODE)) + return origfun; /* most likely a data reference */ while (dll) { if (hmod == dll->hmod) diff --git a/scheduler/process.c b/scheduler/process.c index a170e7f7846..3d351419807 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -450,6 +450,7 @@ static void start_process(void) LPTHREAD_START_ROUTINE entry; WINE_MODREF *wm; HANDLE main_file = main_exe_file; + IMAGE_NT_HEADERS *nt; /* use original argv[0] as name for the main module */ if (!main_exe_name[0]) @@ -466,16 +467,17 @@ static void start_process(void) } /* Retrieve entry point address */ + nt = RtlImageNtHeader( current_process.module ); entry = (LPTHREAD_START_ROUTINE)((char*)current_process.module + - PE_HEADER(current_process.module)->OptionalHeader.AddressOfEntryPoint); - console_app = (PE_HEADER(current_process.module)->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI); + nt->OptionalHeader.AddressOfEntryPoint); + console_app = (nt->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI); if (console_app) current_process.flags |= PDB32_CONSOLE_PROC; /* Signal the parent process to continue */ SERVER_START_REQ( init_process_done ) { req->module = (void *)current_process.module; - req->module_size = PE_HEADER(current_process.module)->OptionalHeader.SizeOfImage; + req->module_size = nt->OptionalHeader.SizeOfImage; req->entry = entry; /* API requires a double indirection */ req->name = &main_exe_name_ptr; @@ -633,7 +635,7 @@ void PROCESS_InitWine( int argc, char *argv[], LPSTR win16_exe_name, HANDLE *win /* create 32-bit module for main exe */ if (!(current_process.module = BUILTIN32_LoadExeModule( current_process.module ))) goto error; - stack_size = PE_HEADER(current_process.module)->OptionalHeader.SizeOfStackReserve; + stack_size = RtlImageNtHeader(current_process.module)->OptionalHeader.SizeOfStackReserve; /* allocate main thread stack */ if (!THREAD_InitStack( NtCurrentTeb(), stack_size )) goto error;