Implemented the RtlImage* functions, and use them to replace the

PE_HEADER macro.
This commit is contained in:
Alexandre Julliard 2002-08-09 19:57:38 +00:00
parent 3d8b123e5a
commit a5dea216cc
15 changed files with 191 additions and 210 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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.@]
*/

View File

@ -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
{

View File

@ -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,

View File

@ -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;

View File

@ -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;
}

View File

@ -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 (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);
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));
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;

View File

@ -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);
}

View File

@ -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,

View File

@ -24,6 +24,7 @@
#include <unistd.h>
#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);

View File

@ -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;

View File

@ -26,6 +26,7 @@
#include <stdio.h>
#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;

View File

@ -26,6 +26,7 @@
#include <string.h>
#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;j<PE_HEADER(hmod)->FileHeader.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 <pe_seg[j].VirtualAddress+
pe_seg[j].SizeOfRawData
))
)
break;
/* If we looked through all sections (and didn't find one)
* or if the sectionname contains "data", we return the
* original function since it is most likely a datareference.
*/
if ( (j==PE_HEADER(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)

View File

@ -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;