Implemented the RtlImage* functions, and use them to replace the
PE_HEADER macro.
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index f572b33..c9ec684 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -68,3 +68,83 @@
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 81b01ab..1f97e81 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 74e844e..b07b25d 100644
--- a/dlls/ntdll/rtl.c
+++ b/dlls/ntdll/rtl.c
@@ -346,23 +346,6 @@
}
-/***********************************************************************
- * 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 ef91450..748fbe6 100644
--- a/include/module.h
+++ b/include/module.h
@@ -170,13 +170,6 @@
#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 90e6ca1..0bf93db 100644
--- a/include/ntddk.h
+++ b/include/ntddk.h
@@ -1073,6 +1073,9 @@
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 e833cd0..f302f06 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 @@
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 6a41cb5..19a7a8e 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -121,7 +121,7 @@
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 @@
/* 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 84a999c..029665c 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -55,27 +55,6 @@
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 @@
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 @@
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 @@
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);
- return NULL;
- }
+ 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 @@
}
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 @@
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 @@
*/
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 @@
/* 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 @@
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 @@
/* 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 @@
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 @@
{
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 0f06b62..ed830de 100644
--- a/loader/pe_resource.c
+++ b/loader/pe_resource.c
@@ -32,35 +32,14 @@
#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
*
* Check if a module handle is for a LOAD_LIBRARY_AS_DATAFILE module.
@@ -72,48 +51,22 @@
/**********************************************************************
- * 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
*
* Get the resource directory of a PE module
*/
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 @@
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 a7c7656..0db7996 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 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 @@
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 @@
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 @@
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 384fea3..5b6dc13 100644
--- a/msdos/vxd.c
+++ b/msdos/vxd.c
@@ -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 @@
(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 9f26d99..5e9879b 100644
--- a/relay32/builtin32.c
+++ b/relay32/builtin32.c
@@ -86,6 +86,7 @@
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 @@
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 d9a4e9f..7da6c1a 100644
--- a/relay32/relay386.c
+++ b/relay32/relay386.c
@@ -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 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 @@
/* 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 @@
*/
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 7fea6f8..c43e44a 100644
--- a/relay32/snoop.c
+++ b/relay32/snoop.c
@@ -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 @@
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)
diff --git a/scheduler/process.c b/scheduler/process.c
index a170e7f..3d35141 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -450,6 +450,7 @@
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 @@
}
/* 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 @@
/* 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;