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;