- Update NDK with proper (when possible) RTL structure names that were previously...
[reactos.git] / reactos / lib / ntdll / ldr / utils.c
index d9ed9eb..1c9240d 100644 (file)
@@ -1,5 +1,5 @@
-/* $Id: utils.c,v 1.81 2004/01/25 09:57:14 jfilby Exp $
- * 
+/* $Id$
+ *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            lib/ntdll/ldr/utils.c
 
 /* INCLUDES *****************************************************************/
 
-#include <reactos/config.h>
-#include <ddk/ntddk.h>
-#include <windows.h>
-#include <string.h>
-#include <wchar.h>
-#include <ntdll/ldr.h>
-#include <ntos/minmax.h>
+#include <ntdll.h>
+#define NDEBUG
+#include <debug.h>
 
 #define LDRP_PROCESS_CREATION_TIME 0x8000000
 
-#ifdef DBG_NTDLL_LDR_UTILS
-#define NDEBUG
-#endif
-#include <ntdll/ntdll.h>
-
 /* GLOBALS *******************************************************************/
 
+#ifdef NDEBUG
+#if defined(__GNUC__)
+#define TRACE_LDR(args...) if (RtlGetNtGlobalFlags() & FLG_SHOW_LDR_SNAPS) { DbgPrint("(LDR:%s:%d) ",__FILE__,__LINE__); DbgPrint(args); }
+#else
+#endif /* __GNUC__ */
+#else
+#define TRACE_LDR(args...) do { DbgPrint("(LDR:%s:%d) ",__FILE__,__LINE__); DbgPrint(args); } while(0)
+#endif
+
 typedef struct _TLS_DATA
 {
    PVOID StartAddressOfRawData;
    DWORD TlsDataSize;
    DWORD TlsZeroSize;
    PIMAGE_TLS_CALLBACK TlsAddressOfCallBacks;
-   PLDR_MODULE Module;
+   PLDR_DATA_TABLE_ENTRY Module;
 } TLS_DATA, *PTLS_DATA;
 
 static PTLS_DATA LdrpTlsArray = NULL;
@@ -50,28 +50,28 @@ static ULONG LdrpTlsCount = 0;
 static ULONG LdrpTlsSize = 0;
 static HANDLE LdrpKnownDllsDirHandle = NULL;
 static UNICODE_STRING LdrpKnownDllPath = {0, 0, NULL};
-static PLDR_MODULE LdrpLastModule = NULL;
-extern ULONG NtGlobalFlag;
-extern PLDR_MODULE ExeModule;
+static PLDR_DATA_TABLE_ENTRY LdrpLastModule = NULL;
+extern PLDR_DATA_TABLE_ENTRY ExeModule;
 
 /* PROTOTYPES ****************************************************************/
 
-static NTSTATUS LdrFindEntryForName(PUNICODE_STRING Name, PLDR_MODULE *Module, BOOL Ref);
+static NTSTATUS LdrFindEntryForName(PUNICODE_STRING Name, PLDR_DATA_TABLE_ENTRY *Module, BOOLEAN Ref);
 static PVOID LdrFixupForward(PCHAR ForwardName);
 static PVOID LdrGetExportByName(PVOID BaseAddress, PUCHAR SymbolName, USHORT Hint);
-static NTSTATUS LdrpLoadModule(IN PWSTR SearchPath OPTIONAL, 
-                              IN ULONG LoadFlags,  
-                              IN PUNICODE_STRING Name,
-                              OUT PLDR_MODULE *Module);
+static NTSTATUS LdrpLoadModule(IN PWSTR SearchPath OPTIONAL,
+                               IN ULONG LoadFlags,
+                               IN PUNICODE_STRING Name,
+                               OUT PLDR_DATA_TABLE_ENTRY *Module,
+                               OUT PVOID *BaseAddress OPTIONAL);
 static NTSTATUS LdrpAttachProcess(VOID);
-static VOID LdrpDetachProcess(BOOL UnloadAll);
+static VOID LdrpDetachProcess(BOOLEAN UnloadAll);
 
 /* FUNCTIONS *****************************************************************/
 
-#ifdef KDBG
+#if defined(DBG) || defined(KDBG)
 
 VOID
-LdrpLoadUserModuleSymbols(PLDR_MODULE LdrModule)
+LdrpLoadUserModuleSymbols(PLDR_DATA_TABLE_ENTRY LdrModule)
 {
   NtSystemDebugControl(
     DebugDbgLoadSymbols,
@@ -82,9 +82,21 @@ LdrpLoadUserModuleSymbols(PLDR_MODULE LdrModule)
     NULL);
 }
 
-#endif /* DBG */
+#endif /* DBG || KDBG */
+
+BOOLEAN
+LdrMappedAsDataFile(PVOID *BaseAddress)
+{
+  if (0 != ((DWORD_PTR) *BaseAddress & (PAGE_SIZE - 1)))
+    {
+      *BaseAddress = (PVOID) ((DWORD_PTR) *BaseAddress & ~ ((DWORD_PTR) PAGE_SIZE - 1));
+      return TRUE;
+    }
+
+   return FALSE;
+}
 
-static inline LONG LdrpDecrementLoadCount(PLDR_MODULE Module, BOOL Locked)
+static __inline LONG LdrpDecrementLoadCount(PLDR_DATA_TABLE_ENTRY Module, BOOLEAN Locked)
 {
    LONG LoadCount;
    if (!Locked)
@@ -92,7 +104,7 @@ static inline LONG LdrpDecrementLoadCount(PLDR_MODULE Module, BOOL Locked)
        RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
      }
    LoadCount = Module->LoadCount;
-   if (Module->LoadCount > 0)
+   if (Module->LoadCount > 0 && Module->LoadCount != 0xFFFF)
      {
        Module->LoadCount--;
      }
@@ -103,7 +115,7 @@ static inline LONG LdrpDecrementLoadCount(PLDR_MODULE Module, BOOL Locked)
    return LoadCount;
 }
 
-static inline LONG LdrpIncrementLoadCount(PLDR_MODULE Module, BOOL Locked)
+static __inline LONG LdrpIncrementLoadCount(PLDR_DATA_TABLE_ENTRY Module, BOOLEAN Locked)
 {
    LONG LoadCount;
    if (!Locked)
@@ -111,7 +123,7 @@ static inline LONG LdrpIncrementLoadCount(PLDR_MODULE Module, BOOL Locked)
        RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
      }
    LoadCount = Module->LoadCount;
-   if (Module->LoadCount >= 0)
+   if (Module->LoadCount != 0xFFFF)
      {
        Module->LoadCount++;
      }
@@ -122,7 +134,7 @@ static inline LONG LdrpIncrementLoadCount(PLDR_MODULE Module, BOOL Locked)
    return LoadCount;
 }
 
-static inline VOID LdrpAcquireTlsSlot(PLDR_MODULE Module, ULONG Size, BOOL Locked)
+static __inline VOID LdrpAcquireTlsSlot(PLDR_DATA_TABLE_ENTRY Module, ULONG Size, BOOLEAN Locked)
 {
    if (!Locked)
      {
@@ -137,34 +149,34 @@ static inline VOID LdrpAcquireTlsSlot(PLDR_MODULE Module, ULONG Size, BOOL Locke
      }
 }
 
-static inline VOID LdrpTlsCallback(PLDR_MODULE Module, ULONG dwReason)
+static __inline VOID LdrpTlsCallback(PLDR_DATA_TABLE_ENTRY Module, ULONG dwReason)
 {
    PIMAGE_TLS_CALLBACK TlsCallback;
-   if (Module->TlsIndex >= 0 && Module->LoadCount == -1)
+   if (Module->TlsIndex != 0xFFFF && Module->LoadCount == 0xFFFF)
      {
        TlsCallback = LdrpTlsArray[Module->TlsIndex].TlsAddressOfCallBacks;
        if (TlsCallback)
          {
            while (*TlsCallback)
              {
-              TRACE_LDR("%wZ - Calling tls callback at %x\n",
-                        &Module->BaseDllName, TlsCallback);
-              TlsCallback(Module->BaseAddress, dwReason, NULL);
-              TlsCallback++;
-            }
-        }
+               TRACE_LDR("%wZ - Calling tls callback at %x\n",
+                         &Module->BaseDllName, TlsCallback);
+               TlsCallback(Module->DllBase, dwReason, NULL);
+               TlsCallback = (PIMAGE_TLS_CALLBACK)((ULONG_PTR)TlsCallback + sizeof(PVOID));
+             }
+         }
      }
 }
 
-static BOOL LdrpCallDllEntry(PLDR_MODULE Module, DWORD dwReason, PVOID lpReserved)
+static BOOLEAN LdrpCallDllEntry(PLDR_DATA_TABLE_ENTRY Module, DWORD dwReason, PVOID lpReserved)
 {
-   if (!(Module->Flags & IMAGE_DLL) ||
+   if (!(Module->Flags & LDRP_IMAGE_DLL) ||
        Module->EntryPoint == 0)
      {
        return TRUE;
      }
    LdrpTlsCallback(Module, dwReason);
-   return  ((PDLLMAIN_FUNC)Module->EntryPoint)(Module->BaseAddress, dwReason, lpReserved);
+   return  ((PDLLMAIN_FUNC)Module->EntryPoint)(Module->DllBase, dwReason, lpReserved);
 }
 
 static NTSTATUS
@@ -174,39 +186,44 @@ LdrpInitializeTlsForThread(VOID)
    PTLS_DATA TlsInfo;
    PVOID TlsData;
    ULONG i;
+   PTEB Teb = NtCurrentTeb();
 
    DPRINT("LdrpInitializeTlsForThread() called for %wZ\n", &ExeModule->BaseDllName);
 
+   Teb->StaticUnicodeString.Length = 0;
+   Teb->StaticUnicodeString.MaximumLength = sizeof(Teb->StaticUnicodeBuffer);
+   Teb->StaticUnicodeString.Buffer = Teb->StaticUnicodeBuffer;
+
    if (LdrpTlsCount > 0)
      {
        TlsPointers = RtlAllocateHeap(RtlGetProcessHeap(),
                                      0,
-                                     LdrpTlsCount * sizeof(PVOID) + LdrpTlsSize); 
+                                     LdrpTlsCount * sizeof(PVOID) + LdrpTlsSize);
        if (TlsPointers == NULL)
          {
-          DPRINT1("failed to allocate thread tls data\n");
-          return STATUS_NO_MEMORY;
-        }
-       
-       TlsData = (PVOID)TlsPointers + LdrpTlsCount * sizeof(PVOID);
-       NtCurrentTeb()->ThreadLocalStoragePointer = TlsPointers;
+           DPRINT1("failed to allocate thread tls data\n");
+           return STATUS_NO_MEMORY;
+         }
+
+       TlsData = (PVOID)((ULONG_PTR)TlsPointers + LdrpTlsCount * sizeof(PVOID));
+       Teb->ThreadLocalStoragePointer = TlsPointers;
 
        TlsInfo = LdrpTlsArray;
        for (i = 0; i < LdrpTlsCount; i++, TlsInfo++)
          {
-          TRACE_LDR("Initialize tls data for %wZ\n", &TlsInfo->Module->BaseDllName);
-          TlsPointers[i] = TlsData;
-          if (TlsInfo->TlsDataSize)
-            {
-              memcpy(TlsData, TlsInfo->StartAddressOfRawData, TlsInfo->TlsDataSize);
-              TlsData += TlsInfo->TlsDataSize;
-            }
-          if (TlsInfo->TlsZeroSize)
-            {
-              memset(TlsData, 0, TlsInfo->TlsZeroSize);
-              TlsData += TlsInfo->TlsZeroSize;
-            }
-        }
+           TRACE_LDR("Initialize tls data for %wZ\n", &TlsInfo->Module->BaseDllName);
+           TlsPointers[i] = TlsData;
+           if (TlsInfo->TlsDataSize)
+             {
+               memcpy(TlsData, TlsInfo->StartAddressOfRawData, TlsInfo->TlsDataSize);
+               TlsData = (PVOID)((ULONG_PTR)TlsData + TlsInfo->TlsDataSize);
+             }
+           if (TlsInfo->TlsZeroSize)
+             {
+               memset(TlsData, 0, TlsInfo->TlsZeroSize);
+               TlsData = (PVOID)((ULONG_PTR)TlsData + TlsInfo->TlsZeroSize);
+             }
+         }
      }
    DPRINT("LdrpInitializeTlsForThread() done\n");
    return STATUS_SUCCESS;
@@ -217,62 +234,65 @@ LdrpInitializeTlsForProccess(VOID)
 {
    PLIST_ENTRY ModuleListHead;
    PLIST_ENTRY Entry;
-   PLDR_MODULE Module;
+   PLDR_DATA_TABLE_ENTRY Module;
    PIMAGE_TLS_DIRECTORY TlsDirectory;
    PTLS_DATA TlsData;
+   ULONG Size;
 
    DPRINT("LdrpInitializeTlsForProccess() called for %wZ\n", &ExeModule->BaseDllName);
-   
+
    if (LdrpTlsCount > 0)
      {
        LdrpTlsArray = RtlAllocateHeap(RtlGetProcessHeap(),
                                       0,
-                                      LdrpTlsCount * sizeof(TLS_DATA)); 
+                                      LdrpTlsCount * sizeof(TLS_DATA));
        if (LdrpTlsArray == NULL)
          {
-          DPRINT1("Failed to allocate global tls data\n");
+           DPRINT1("Failed to allocate global tls data\n");
            return STATUS_NO_MEMORY;
          }
-      
+
        ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
        Entry = ModuleListHead->Flink;
        while (Entry != ModuleListHead)
          {
-           Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
-          if (Module->LoadCount == -1 &&
-              Module->TlsIndex >= 0)
+           Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList);
+           if (Module->LoadCount == 0xFFFF &&
+               Module->TlsIndex != 0xFFFF)
              {
                TlsDirectory = (PIMAGE_TLS_DIRECTORY)
-                                RtlImageDirectoryEntryToData(Module->BaseAddress,
+                                 RtlImageDirectoryEntryToData(Module->DllBase,
                                                               TRUE,
                                                               IMAGE_DIRECTORY_ENTRY_TLS,
-                                                              NULL);
-               assert(Module->TlsIndex < LdrpTlsCount);
-              TlsData = &LdrpTlsArray[Module->TlsIndex];
-              TlsData->StartAddressOfRawData = (PVOID)TlsDirectory->StartAddressOfRawData;
-              TlsData->TlsDataSize = TlsDirectory->EndAddressOfRawData - TlsDirectory->StartAddressOfRawData;
-              TlsData->TlsZeroSize = TlsDirectory->SizeOfZeroFill;
-              TlsData->TlsAddressOfCallBacks = *TlsDirectory->AddressOfCallBacks;
-              TlsData->Module = Module;
+                                                              &Size);
+               ASSERT(Module->TlsIndex < LdrpTlsCount);
+               TlsData = &LdrpTlsArray[Module->TlsIndex];
+               TlsData->StartAddressOfRawData = (PVOID)TlsDirectory->StartAddressOfRawData;
+               TlsData->TlsDataSize = TlsDirectory->EndAddressOfRawData - TlsDirectory->StartAddressOfRawData;
+               TlsData->TlsZeroSize = TlsDirectory->SizeOfZeroFill;
+               if (TlsDirectory->AddressOfCallBacks)
+                 TlsData->TlsAddressOfCallBacks = *(PIMAGE_TLS_CALLBACK*)TlsDirectory->AddressOfCallBacks;
+               else
+                 TlsData->TlsAddressOfCallBacks = NULL;
+               TlsData->Module = Module;
 #if 0
                DbgPrint("TLS directory for %wZ\n", &Module->BaseDllName);
-              DbgPrint("StartAddressOfRawData: %x\n", TlsDirectory->StartAddressOfRawData);
-              DbgPrint("EndAddressOfRawData:   %x\n", TlsDirectory->EndAddressOfRawData);
-              DbgPrint("SizeOfRawData:         %d\n", TlsDirectory->EndAddressOfRawData - TlsDirectory->StartAddressOfRawData);
-              DbgPrint("AddressOfIndex:        %x\n", TlsDirectory->AddressOfIndex);
-              DbgPrint("AddressOfCallBacks:    %x (%x)\n", TlsDirectory->AddressOfCallBacks, *TlsDirectory->AddressOfCallBacks);
-              DbgPrint("SizeOfZeroFill:        %d\n", TlsDirectory->SizeOfZeroFill);
-              DbgPrint("Characteristics:       %x\n", TlsDirectory->Characteristics);
+               DbgPrint("StartAddressOfRawData: %x\n", TlsDirectory->StartAddressOfRawData);
+               DbgPrint("EndAddressOfRawData:   %x\n", TlsDirectory->EndAddressOfRawData);
+               DbgPrint("SizeOfRawData:         %d\n", TlsDirectory->EndAddressOfRawData - TlsDirectory->StartAddressOfRawData);
+               DbgPrint("AddressOfIndex:        %x\n", TlsDirectory->AddressOfIndex);
+               DbgPrint("AddressOfCallBacks:    %x (%x)\n", TlsDirectory->AddressOfCallBacks, *TlsDirectory->AddressOfCallBacks);
+               DbgPrint("SizeOfZeroFill:        %d\n", TlsDirectory->SizeOfZeroFill);
+               DbgPrint("Characteristics:       %x\n", TlsDirectory->Characteristics);
 #endif
-              /* 
-               * FIXME:
-               *   Is this region allways writable ?
-               */
+               /*
+                * FIXME:
+                *   Is this region allways writable ?
+                */
                *(PULONG)TlsDirectory->AddressOfIndex = Module->TlsIndex;
-              CHECKPOINT1;
-            }
-          Entry = Entry->Flink;
-       }
+             }
+           Entry = Entry->Flink;
+        }
     }
   DPRINT("LdrpInitializeTlsForProccess() done\n");
   return STATUS_SUCCESS;
@@ -292,15 +312,15 @@ LdrpInitLoader(VOID)
 
   /* Get handle to the 'KnownDlls' directory */
   RtlInitUnicodeString(&Name,
-                      L"\\KnownDlls");
+                       L"\\KnownDlls");
   InitializeObjectAttributes(&ObjectAttributes,
-                            &Name,
-                            OBJ_CASE_INSENSITIVE,
-                            NULL,
-                            NULL);
+                             &Name,
+                             OBJ_CASE_INSENSITIVE,
+                             NULL,
+                             NULL);
   Status = NtOpenDirectoryObject(&LdrpKnownDllsDirHandle,
-                                DIRECTORY_QUERY | DIRECTORY_TRAVERSE,
-                                &ObjectAttributes);
+                                 DIRECTORY_QUERY | DIRECTORY_TRAVERSE,
+                                 &ObjectAttributes);
   if (!NT_SUCCESS(Status))
     {
       DPRINT("NtOpenDirectoryObject() failed (Status %lx)\n", Status);
@@ -312,8 +332,8 @@ LdrpInitLoader(VOID)
   LinkTarget.Length = 0;
   LinkTarget.MaximumLength = MAX_PATH * sizeof(WCHAR);
   LinkTarget.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
-                                     0,
-                                     MAX_PATH * sizeof(WCHAR));
+                                      0,
+                                      MAX_PATH * sizeof(WCHAR));
   if (LinkTarget.Buffer == NULL)
     {
       NtClose(LdrpKnownDllsDirHandle);
@@ -322,15 +342,15 @@ LdrpInitLoader(VOID)
     }
 
   RtlInitUnicodeString(&Name,
-                      L"KnownDllPath");
+                       L"KnownDllPath");
   InitializeObjectAttributes(&ObjectAttributes,
-                            &Name,
-                            OBJ_CASE_INSENSITIVE | OBJ_OPENLINK,
-                            LdrpKnownDllsDirHandle,
-                            NULL);
+                             &Name,
+                             OBJ_CASE_INSENSITIVE | OBJ_OPENLINK,
+                             LdrpKnownDllsDirHandle,
+                             NULL);
   Status = NtOpenSymbolicLinkObject(&LinkHandle,
-                                   SYMBOLIC_LINK_ALL_ACCESS,
-                                   &ObjectAttributes);
+                                    SYMBOLIC_LINK_ALL_ACCESS,
+                                    &ObjectAttributes);
   if (!NT_SUCCESS(Status))
     {
       RtlFreeUnicodeString(&LinkTarget);
@@ -340,8 +360,8 @@ LdrpInitLoader(VOID)
     }
 
   Status = NtQuerySymbolicLinkObject(LinkHandle,
-                                    &LinkTarget,
-                                    &Length);
+                                     &LinkTarget,
+                                     &Length);
   NtClose(LinkHandle);
   if (!NT_SUCCESS(Status))
     {
@@ -351,7 +371,7 @@ LdrpInitLoader(VOID)
     }
 
   RtlCreateUnicodeString(&LdrpKnownDllPath,
-                        LinkTarget.Buffer);
+                         LinkTarget.Buffer);
 
   RtlFreeUnicodeString(&LinkTarget);
 
@@ -439,21 +459,21 @@ LdrAdjustDllName (PUNICODE_STRING FullDllName,
    RtlCreateUnicodeString(FullDllName, Buffer);
 }
 
-PLDR_MODULE
+PLDR_DATA_TABLE_ENTRY
 LdrAddModuleEntry(PVOID ImageBase,
-                 PIMAGE_NT_HEADERS NTHeaders,
-                 PWSTR FullDosName)
+                  PIMAGE_NT_HEADERS NTHeaders,
+                  PWSTR FullDosName)
 {
-  PLDR_MODULE Module;
+  PLDR_DATA_TABLE_ENTRY Module;
 
-  Module = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof (LDR_MODULE));
-  assert(Module);
-  memset(Module, 0, sizeof(LDR_MODULE));
-  Module->BaseAddress = (PVOID)ImageBase;
-  Module->EntryPoint = NTHeaders->OptionalHeader.AddressOfEntryPoint;
+  Module = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof (LDR_DATA_TABLE_ENTRY));
+  ASSERT(Module);
+  memset(Module, 0, sizeof(LDR_DATA_TABLE_ENTRY));
+  Module->DllBase = (PVOID)ImageBase;
+  Module->EntryPoint = (PVOID)NTHeaders->OptionalHeader.AddressOfEntryPoint;
   if (Module->EntryPoint != 0)
-    Module->EntryPoint += (ULONG)Module->BaseAddress;
-  Module->SizeOfImage = NTHeaders->OptionalHeader.SizeOfImage;
+    Module->EntryPoint = (PVOID)((ULONG_PTR)Module->EntryPoint + (ULONG_PTR)Module->DllBase);
+  Module->SizeOfImage = LdrpGetResidentSize(NTHeaders);
   if (NtCurrentPeb()->Ldr->Initialized == TRUE)
     {
       /* loading while app is running */
@@ -463,7 +483,7 @@ LdrAddModuleEntry(PVOID ImageBase,
        * loading while app is initializing
        * dll must not be unloaded
        */
-      Module->LoadCount = -1;
+      Module->LoadCount = 0xFFFF;
     }
 
   Module->Flags = 0;
@@ -476,7 +496,7 @@ LdrAddModuleEntry(PVOID ImageBase,
   RtlCreateUnicodeString (&Module->BaseDllName,
                           wcsrchr(FullDosName, L'\\') + 1);
   DPRINT ("BaseDllName %wZ\n", &Module->BaseDllName);
-  
+
   RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
   InsertTailList(&NtCurrentPeb()->Ldr->InLoadOrderModuleList,
                  &Module->InLoadOrderModuleList);
@@ -488,8 +508,8 @@ LdrAddModuleEntry(PVOID ImageBase,
 
 static NTSTATUS
 LdrpMapKnownDll(IN PUNICODE_STRING DllName,
-               OUT PUNICODE_STRING FullDosName,
-               OUT PHANDLE SectionHandle)
+                OUT PUNICODE_STRING FullDosName,
+                OUT PHANDLE SectionHandle)
 {
   OBJECT_ATTRIBUTES ObjectAttributes;
   NTSTATUS Status;
@@ -505,13 +525,13 @@ LdrpMapKnownDll(IN PUNICODE_STRING DllName,
   DPRINT("LdrpKnownDllPath '%wZ'\n", &LdrpKnownDllPath);
 
   InitializeObjectAttributes(&ObjectAttributes,
-                            DllName,
-                            OBJ_CASE_INSENSITIVE,
-                            LdrpKnownDllsDirHandle,
-                            NULL);
+                             DllName,
+                             OBJ_CASE_INSENSITIVE,
+                             LdrpKnownDllsDirHandle,
+                             NULL);
   Status = NtOpenSection(SectionHandle,
-                        SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE,
-                        &ObjectAttributes);
+                         SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE,
+                         &ObjectAttributes);
   if (!NT_SUCCESS(Status))
     {
       DPRINT("NtOpenSection() failed for '%wZ' (Status %lx)\n", DllName, Status);
@@ -521,8 +541,8 @@ LdrpMapKnownDll(IN PUNICODE_STRING DllName,
   FullDosName->Length = LdrpKnownDllPath.Length + DllName->Length + sizeof(WCHAR);
   FullDosName->MaximumLength = FullDosName->Length + sizeof(WCHAR);
   FullDosName->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
-                                       0,
-                                       FullDosName->MaximumLength);
+                                        0,
+                                        FullDosName->MaximumLength);
   if (FullDosName->Buffer == NULL)
     {
       FullDosName->Length = 0;
@@ -544,9 +564,10 @@ LdrpMapKnownDll(IN PUNICODE_STRING DllName,
 
 static NTSTATUS
 LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL,
-                   IN PUNICODE_STRING DllName,
-                   OUT PUNICODE_STRING FullDosName,
-                   OUT PHANDLE SectionHandle)
+                    IN PUNICODE_STRING DllName,
+                    OUT PUNICODE_STRING FullDosName,
+                    IN BOOLEAN MapAsDataFile,
+                    OUT PHANDLE SectionHandle)
 {
   WCHAR                 SearchPathBuffer[MAX_PATH];
   WCHAR                 DosName[MAX_PATH];
@@ -556,23 +577,34 @@ LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL,
   char                  BlockBuffer [1024];
   PIMAGE_DOS_HEADER     DosHeader;
   PIMAGE_NT_HEADERS     NTHeaders;
-  PVOID                 ImageBase;
-  ULONG                 ImageSize;
   IO_STATUS_BLOCK       IoStatusBlock;
-  NTSTATUS Status;
+  NTSTATUS              Status;
+  ULONG                 len;
 
   DPRINT("LdrpMapDllImageFile() called\n");
 
   if (SearchPath == NULL)
     {
-      SearchPath = SearchPathBuffer;
-      wcscpy (SearchPathBuffer, SharedUserData->NtSystemRoot);
+      /* get application running path */
+
+      wcscpy (SearchPathBuffer, NtCurrentPeb()->ProcessParameters->ImagePathName.Buffer);
+
+      len = wcslen (SearchPathBuffer);
+
+      while (len && SearchPathBuffer[len - 1] != L'\\')
+           len--;
+
+      if (len) SearchPathBuffer[len-1] = L'\0';
+
+      wcscat (SearchPathBuffer, L";");
+
+      wcscat (SearchPathBuffer, SharedUserData->NtSystemRoot);
       wcscat (SearchPathBuffer, L"\\system32;");
       wcscat (SearchPathBuffer, SharedUserData->NtSystemRoot);
       wcscat (SearchPathBuffer, L";.");
-    }
 
-  DPRINT("SearchPath %S\n", SearchPath);
+      SearchPath = SearchPathBuffer;
+    }
 
   if (RtlDosSearchPath_U (SearchPath,
                           DllName->Buffer,
@@ -582,7 +614,6 @@ LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL,
                           NULL) == 0)
     return STATUS_DLL_NOT_FOUND;
 
-  DPRINT("DosName %S\n", DosName);
 
   if (!RtlDosPathNameToNtPathName_U (DosName,
                                      &FullNtFileName,
@@ -604,11 +635,11 @@ LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL,
                       GENERIC_READ|SYNCHRONIZE,
                       &FileObjectAttributes,
                       &IoStatusBlock,
-                      0,
+                      FILE_SHARE_READ,
                       FILE_SYNCHRONOUS_IO_NONALERT);
   if (!NT_SUCCESS(Status))
     {
-      DbgPrint("Dll open of %wZ failed: Status = 0x%08x\n", 
+      DPRINT1("Dll open of %wZ failed: Status = 0x%08x\n",
                &FullNtFileName, Status);
       RtlFreeUnicodeString (&FullNtFileName);
       return Status;
@@ -631,7 +662,7 @@ LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL,
       return Status;
     }
   /*
-   * Overlay DOS and NT headers structures to the 
+   * Overlay DOS and NT headers structures to the
    * buffer with DLL's header raw data.
    */
   DosHeader = (PIMAGE_DOS_HEADER) BlockBuffer;
@@ -639,21 +670,16 @@ LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL,
   /*
    * Check it is a PE image file.
    */
-  if ((DosHeader->e_magic != IMAGE_DOS_MAGIC)
+  if ((DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
       || (DosHeader->e_lfanew == 0L)
-      || (*(PULONG)(NTHeaders) != IMAGE_PE_MAGIC))
+      || (*(PULONG)(NTHeaders) != IMAGE_NT_SIGNATURE))
     {
       DPRINT("NTDLL format invalid\n");
       NtClose(FileHandle);
-      
+
       return STATUS_UNSUCCESSFUL;
     }
-  
-  ImageBase = (PVOID) NTHeaders->OptionalHeader.ImageBase;
-  ImageSize = NTHeaders->OptionalHeader.SizeOfImage;
-  
-  DPRINT("ImageBase 0x%08x\n", ImageBase);
-  
+
   /*
    * Create a section for dll.
    */
@@ -661,8 +687,8 @@ LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL,
                            SECTION_ALL_ACCESS,
                            NULL,
                            NULL,
-                           PAGE_READWRITE,
-                           SEC_COMMIT | SEC_IMAGE,
+                           PAGE_READONLY,
+                           SEC_COMMIT | (MapAsDataFile ? 0 : SEC_IMAGE),
                            FileHandle);
   NtClose(FileHandle);
 
@@ -673,7 +699,7 @@ LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL,
     }
 
   RtlCreateUnicodeString(FullDosName,
-                        DosName);
+                         DosName);
 
   return Status;
 }
@@ -696,16 +722,19 @@ LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL,
  *
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
             IN ULONG LoadFlags,
             IN PUNICODE_STRING Name,
             OUT PVOID *BaseAddress OPTIONAL)
 {
   NTSTATUS              Status;
-  PLDR_MODULE           Module;
+  PLDR_DATA_TABLE_ENTRY           Module;
 
-  TRACE_LDR("LdrLoadDll, loading %wZ%s%S\n", Name, SearchPath ? " from " : "", SearchPath ? SearchPath : L"");
+  TRACE_LDR("LdrLoadDll, loading %wZ%s%S\n",
+            Name,
+            SearchPath ? " from " : "",
+            SearchPath ? SearchPath : L"");
 
   if (Name == NULL)
     {
@@ -715,15 +744,15 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
 
   *BaseAddress = NULL;
 
-  Status = LdrpLoadModule(SearchPath, LoadFlags, Name, &Module);
-  if (NT_SUCCESS(Status))
+  Status = LdrpLoadModule(SearchPath, LoadFlags, Name, &Module, BaseAddress);
+  if (NT_SUCCESS(Status) && 0 == (LoadFlags & LOAD_LIBRARY_AS_DATAFILE))
     {
       RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
       Status = LdrpAttachProcess();
       RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
       if (NT_SUCCESS(Status))
         {
-          *BaseAddress = Module->BaseAddress;
+          *BaseAddress = Module->DllBase;
         }
    }
   return Status;
@@ -746,13 +775,13 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
  *
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 LdrFindEntryForAddress(PVOID Address,
-                       PLDR_MODULE *Module)
+                       PLDR_DATA_TABLE_ENTRY *Module)
 {
   PLIST_ENTRY ModuleListHead;
   PLIST_ENTRY Entry;
-  PLDR_MODULE ModulePtr;
+  PLDR_DATA_TABLE_ENTRY ModulePtr;
 
   DPRINT("LdrFindEntryForAddress(Address %p)\n", Address);
 
@@ -770,15 +799,15 @@ LdrFindEntryForAddress(PVOID Address,
 
   while (Entry != ModuleListHead)
     {
-      ModulePtr = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
+      ModulePtr = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList);
 
-      DPRINT("Scanning %wZ at %p\n", &ModulePtr->BaseDllName, ModulePtr->BaseAddress);
+      DPRINT("Scanning %wZ at %p\n", &ModulePtr->BaseDllName, ModulePtr->DllBase);
 
-      if ((Address >= ModulePtr->BaseAddress) &&
-          (Address <= (ModulePtr->BaseAddress + ModulePtr->SizeOfImage)))
+      if ((Address >= ModulePtr->DllBase) &&
+          ((ULONG_PTR)Address <= ((ULONG_PTR)ModulePtr->DllBase + ModulePtr->SizeOfImage)))
         {
           *Module = ModulePtr;
-         RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
+          RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
           return(STATUS_SUCCESS);
         }
 
@@ -809,12 +838,12 @@ LdrFindEntryForAddress(PVOID Address,
  */
 static NTSTATUS
 LdrFindEntryForName(PUNICODE_STRING Name,
-                    PLDR_MODULE *Module,
-                   BOOL Ref)
+                    PLDR_DATA_TABLE_ENTRY *Module,
+                    BOOLEAN Ref)
 {
   PLIST_ENTRY ModuleListHead;
   PLIST_ENTRY Entry;
-  PLDR_MODULE ModulePtr;
+  PLDR_DATA_TABLE_ENTRY ModulePtr;
   BOOLEAN ContainsPath;
   UNICODE_STRING AdjustedName;
   unsigned i;
@@ -849,7 +878,7 @@ LdrFindEntryForName(PUNICODE_STRING Name,
       ContainsPath = L'\\' == AdjustedName.Buffer[i] ||
                      L'/' == AdjustedName.Buffer[i];
     }
-  
+
   if (LdrpLastModule)
     {
       if ((! ContainsPath &&
@@ -858,18 +887,18 @@ LdrFindEntryForName(PUNICODE_STRING Name,
            0 == RtlCompareUnicodeString(&LdrpLastModule->FullDllName, &AdjustedName, TRUE)))
         {
           *Module = LdrpLastModule;
-         if (Ref && (*Module)->LoadCount != -1)
-           {
+          if (Ref && (*Module)->LoadCount != 0xFFFF)
+            {
               (*Module)->LoadCount++;
-           }
+            }
           RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
-         RtlFreeUnicodeString(&AdjustedName);
+          RtlFreeUnicodeString(&AdjustedName);
           return(STATUS_SUCCESS);
         }
     }
   while (Entry != ModuleListHead)
     {
-      ModulePtr = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
+      ModulePtr = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList);
 
       DPRINT("Scanning %wZ %wZ\n", &ModulePtr->BaseDllName, &AdjustedName);
 
@@ -879,12 +908,12 @@ LdrFindEntryForName(PUNICODE_STRING Name,
            0 == RtlCompareUnicodeString(&ModulePtr->FullDllName, &AdjustedName, TRUE)))
         {
           *Module = LdrpLastModule = ModulePtr;
-         if (Ref && ModulePtr->LoadCount != -1)
-           {
+          if (Ref && ModulePtr->LoadCount != 0xFFFF)
+            {
               ModulePtr->LoadCount++;
             }
           RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
-         RtlFreeUnicodeString(&AdjustedName);
+          RtlFreeUnicodeString(&AdjustedName);
           return(STATUS_SUCCESS);
         }
 
@@ -919,7 +948,7 @@ LdrFixupForward(PCHAR ForwardName)
    UNICODE_STRING DllName;
    NTSTATUS Status;
    PCHAR p;
-   PLDR_MODULE Module;
+   PLDR_DATA_TABLE_ENTRY Module;
    PVOID BaseAddress;
 
    strcpy(NameBuffer, ForwardName);
@@ -933,8 +962,8 @@ LdrFixupForward(PCHAR ForwardName)
                                           NameBuffer);
 
         Status = LdrFindEntryForName (&DllName, &Module, FALSE);
-       /* FIXME:
-        *   The caller (or the image) is responsible for loading of the dll, where the function is forwarded.
+        /* FIXME:
+         *   The caller (or the image) is responsible for loading of the dll, where the function is forwarded.
          */
         if (!NT_SUCCESS(Status))
           {
@@ -942,11 +971,11 @@ LdrFixupForward(PCHAR ForwardName)
                                  LDRP_PROCESS_CREATION_TIME,
                                  &DllName,
                                  &BaseAddress);
-            if (NT_SUCCESS(Status))
-              {
-                Status = LdrFindEntryForName (&DllName, &Module, FALSE);
-              }
-         }
+             if (NT_SUCCESS(Status))
+               {
+                 Status = LdrFindEntryForName (&DllName, &Module, FALSE);
+               }
+          }
         RtlFreeUnicodeString (&DllName);
         if (!NT_SUCCESS(Status))
           {
@@ -954,9 +983,9 @@ LdrFixupForward(PCHAR ForwardName)
             return NULL;
           }
 
-        DPRINT("BaseAddress: %p\n", Module->BaseAddress);
-        
-        return LdrGetExportByName(Module->BaseAddress, p+1, -1);
+        DPRINT("BaseAddress: %p\n", Module->DllBase);
+
+        return LdrGetExportByName(Module->DllBase, (PUCHAR)(p+1), -1);
      }
 
    return NULL;
@@ -966,7 +995,7 @@ LdrFixupForward(PCHAR ForwardName)
 /**********************************************************************
  * NAME                                                         LOCAL
  *      LdrGetExportByOrdinal
- *      
+ *
  * DESCRIPTION
  *
  * ARGUMENTS
@@ -980,14 +1009,13 @@ LdrFixupForward(PCHAR ForwardName)
  */
 static PVOID
 LdrGetExportByOrdinal (
-        PVOID   BaseAddress,   
+        PVOID   BaseAddress,
         ULONG   Ordinal
         )
 {
         PIMAGE_EXPORT_DIRECTORY ExportDir;
         ULONG                   ExportDirSize;
         PDWORD                  * ExFunctions;
-        USHORT                  * ExOrdinals;
         PVOID                   Function;
 
         ExportDir = (PIMAGE_EXPORT_DIRECTORY)
@@ -997,23 +1025,20 @@ LdrGetExportByOrdinal (
                                               &ExportDirSize);
 
 
-        ExOrdinals = (USHORT *)
-                RVA(
-                        BaseAddress,
-                        ExportDir->AddressOfNameOrdinals
-                        );
         ExFunctions = (PDWORD *)
                 RVA(
                         BaseAddress,
                         ExportDir->AddressOfFunctions
                         );
-        DbgPrint(
-                "LdrGetExportByOrdinal(Ordinal %d) = %x\n",
+        DPRINT(
+                "LdrGetExportByOrdinal(Ordinal %d) = %p\n",
                 Ordinal,
                 RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] )
                 );
 
-        Function = RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] );
+        Function = (0 != ExFunctions[Ordinal - ExportDir->Base]
+                    ? RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] )
+                    : NULL);
 
         if (((ULONG)Function >= (ULONG)ExportDir) &&
             ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
@@ -1029,7 +1054,7 @@ LdrGetExportByOrdinal (
 /**********************************************************************
  * NAME                                                         LOCAL
  *      LdrGetExportByName
- *      
+ *
  * DESCRIPTION
  *
  * ARGUMENTS
@@ -1039,7 +1064,7 @@ LdrGetExportByOrdinal (
  * REVISIONS
  *
  * NOTE
- *  AddressOfNames and AddressOfNameOrdinals are paralell tables, 
+ *  AddressOfNames and AddressOfNameOrdinals are paralell tables,
  *  both with NumberOfNames entries.
  *
  */
@@ -1052,13 +1077,12 @@ LdrGetExportByName(PVOID BaseAddress,
    PDWORD                       * ExFunctions;
    PDWORD                       * ExNames;
    USHORT                       * ExOrdinals;
-   ULONG                        i;
    PVOID                        ExName;
    ULONG                        Ordinal;
    PVOID                        Function;
    LONG minn, maxn;
    ULONG ExportDirSize;
-   
+
    DPRINT("LdrGetExportByName %x %s %hu\n", BaseAddress, SymbolName, Hint);
 
    ExportDir = (PIMAGE_EXPORT_DIRECTORY)
@@ -1068,7 +1092,7 @@ LdrGetExportByName(PVOID BaseAddress,
                                   &ExportDirSize);
    if (ExportDir == NULL)
      {
-        DbgPrint("LdrGetExportByName(): no export directory!\n");
+        DPRINT1("LdrGetExportByName(): no export directory!\n");
         return NULL;
      }
 
@@ -1076,7 +1100,7 @@ LdrGetExportByName(PVOID BaseAddress,
    //The symbol names may be missing entirely
    if (ExportDir->AddressOfNames == 0)
    {
-      DPRINT("LdrGetExportByName(): symbol names missing entirely\n");  
+      DPRINT("LdrGetExportByName(): symbol names missing entirely\n");
       return NULL;
    }
 
@@ -1089,14 +1113,14 @@ LdrGetExportByName(PVOID BaseAddress,
                               ExportDir->AddressOfNameOrdinals);
    ExFunctions = (PDWORD *)RVA(BaseAddress,
                                ExportDir->AddressOfFunctions);
-   
+
    /*
     * Check the hint first
     */
    if (Hint < ExportDir->NumberOfNames)
      {
         ExName = RVA(BaseAddress, ExNames[Hint]);
-        if (strcmp(ExName, SymbolName) == 0)
+        if (strcmp(ExName, (PCHAR)SymbolName) == 0)
           {
              Ordinal = ExOrdinals[Hint];
              Function = RVA(BaseAddress, ExFunctions[Ordinal]);
@@ -1105,19 +1129,19 @@ LdrGetExportByName(PVOID BaseAddress,
                {
                   DPRINT("Forward: %s\n", (PCHAR)Function);
                   Function = LdrFixupForward((PCHAR)Function);
-                 if (Function == NULL)
-                   {
+                  if (Function == NULL)
+                    {
                       DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
-                   } 
-                 return Function;
+                    }
+                  return Function;
                }
              if (Function != NULL)
                return Function;
           }
      }
-   
+
    /*
-    * Try a binary search first
+    * Binary search
     */
    minn = 0;
    maxn = ExportDir->NumberOfNames - 1;
@@ -1129,7 +1153,7 @@ LdrGetExportByName(PVOID BaseAddress,
         mid = (minn + maxn) / 2;
 
         ExName = RVA(BaseAddress, ExNames[mid]);
-        res = strcmp(ExName, SymbolName);
+        res = strcmp(ExName, (PCHAR)SymbolName);
         if (res == 0)
           {
              Ordinal = ExOrdinals[mid];
@@ -1139,11 +1163,11 @@ LdrGetExportByName(PVOID BaseAddress,
                {
                   DPRINT("Forward: %s\n", (PCHAR)Function);
                   Function = LdrFixupForward((PCHAR)Function);
-                 if (Function == NULL)
-                   {
+                  if (Function == NULL)
+                    {
                       DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
-                   } 
-                 return Function;
+                    }
+                  return Function;
                }
              if (Function != NULL)
                return Function;
@@ -1162,32 +1186,7 @@ LdrGetExportByName(PVOID BaseAddress,
              minn = mid + 1;
           }
      }
-   
-   /*
-    * Fall back on a linear search
-    */
-   DPRINT("LdrGetExportByName(): Falling back on a linear search of export table\n");
-   for (i = 0; i < ExportDir->NumberOfNames; i++)
-     {
-        ExName = RVA(BaseAddress, ExNames[i]);
-        if (strcmp(ExName,SymbolName) == 0)
-          {
-             Ordinal = ExOrdinals[i];
-             Function = RVA(BaseAddress, ExFunctions[Ordinal]);
-             DPRINT("%x %x %x\n", Function, ExportDir, ExportDir + ExportDirSize);
-             if (((ULONG)Function >= (ULONG)ExportDir) &&
-                 ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
-               {
-                  DPRINT("Forward: %s\n", (PCHAR)Function);
-                  Function = LdrFixupForward((PCHAR)Function);
-              }
-            if (Function == NULL)
-              {
-                break;
-              }
-            return Function;
-          }
-     }
+
    DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
    return (PVOID)NULL;
 }
@@ -1196,10 +1195,10 @@ LdrGetExportByName(PVOID BaseAddress,
 /**********************************************************************
  * NAME                                                         LOCAL
  *      LdrPerformRelocations
- *      
+ *
  * DESCRIPTION
  *      Relocate a DLL's memory image.
- *      
+ *
  * ARGUMENTS
  *
  * RETURN VALUE
@@ -1209,184 +1208,116 @@ LdrGetExportByName(PVOID BaseAddress,
  * NOTE
  *
  */
-static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS        NTHeaders,
-                                       PVOID                    ImageBase)
+static NTSTATUS
+LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders,
+                      PVOID ImageBase)
 {
-  USHORT                        NumberOfEntries;
-  PUSHORT                       pValue16;
-  ULONG                 RelocationRVA;
-  ULONG                 Delta32;
-  ULONG                 Offset;
-  PULONG                        pValue32;
-  PRELOCATION_DIRECTORY RelocationDir;
-  PRELOCATION_ENTRY     RelocationBlock;
-  int                   i;
   PIMAGE_DATA_DIRECTORY RelocationDDir;
-  ULONG OldProtect;
-  ULONG OldProtect2;
+  PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
+  ULONG Count, ProtectSize, OldProtect, OldProtect2;
+  PVOID Page, ProtectPage, ProtectPage2;
+  PUSHORT TypeOffset;
+  ULONG_PTR Delta;
   NTSTATUS Status;
-  PIMAGE_SECTION_HEADER Sections;
-  ULONG MaxExtend;
 
   if (NTHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
     {
       return STATUS_UNSUCCESSFUL;
     }
 
-  Sections = 
-    (PIMAGE_SECTION_HEADER)((PVOID)NTHeaders + sizeof(IMAGE_NT_HEADERS));
-  MaxExtend = 0;
-  for (i = 0; i < NTHeaders->FileHeader.NumberOfSections; i++)
-    {
-      if (!(Sections[i].Characteristics & IMAGE_SECTION_NOLOAD))
-        {
-          ULONG Extend;
-          Extend = 
-            (ULONG)(Sections[i].VirtualAddress + Sections[i].Misc.VirtualSize);
-          MaxExtend = max(MaxExtend, Extend);
-        }
-    }
-  
-  RelocationDDir = 
+  RelocationDDir =
     &NTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
-  RelocationRVA = RelocationDDir->VirtualAddress;
 
-  if (RelocationRVA)
+  if (RelocationDDir->VirtualAddress == 0 || RelocationDDir->Size == 0)
     {
-      RelocationDir = 
-        (PRELOCATION_DIRECTORY)((PCHAR)ImageBase + RelocationRVA);
+      return STATUS_SUCCESS;
+    }
 
-      while (RelocationDir->SizeOfBlock)
-        {
-          if (RelocationDir->VirtualAddress > MaxExtend)
-            {
-              RelocationRVA += RelocationDir->SizeOfBlock;
-              RelocationDir = 
-                (PRELOCATION_DIRECTORY) (ImageBase + RelocationRVA);
-              continue;
-            }
+  ProtectSize = PAGE_SIZE;
+  Delta = (ULONG_PTR)ImageBase - NTHeaders->OptionalHeader.ImageBase;
+  RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)ImageBase +
+                  RelocationDDir->VirtualAddress);
+  RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)ImageBase +
+                  RelocationDDir->VirtualAddress + RelocationDDir->Size);
 
-          Delta32 = (ULONG)(ImageBase - NTHeaders->OptionalHeader.ImageBase);
-          RelocationBlock = 
-            (PRELOCATION_ENTRY) (RelocationRVA + ImageBase + 
-                                 sizeof (RELOCATION_DIRECTORY));          
-          NumberOfEntries = 
-            RelocationDir->SizeOfBlock - sizeof (RELOCATION_DIRECTORY);
-          NumberOfEntries = NumberOfEntries / sizeof (RELOCATION_ENTRY);
+  while (RelocationDir < RelocationEnd &&
+         RelocationDir->SizeOfBlock > 0)
+    {
+      Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) /
+              sizeof(USHORT);
+      Page = (PVOID)((ULONG_PTR)ImageBase + (ULONG_PTR)RelocationDir->VirtualAddress);
+      TypeOffset = (PUSHORT)(RelocationDir + 1);
+
+      /* Unprotect the page(s) we're about to relocate. */
+      ProtectPage = Page;
+      Status = NtProtectVirtualMemory(NtCurrentProcess(),
+                                      &ProtectPage,
+                                      &ProtectSize,
+                                      PAGE_READWRITE,
+                                      &OldProtect);
+      if (!NT_SUCCESS(Status))
+        {
+          DPRINT1("Failed to unprotect relocation target.\n");
+          return Status;
+        }
 
+      if (RelocationDir->VirtualAddress + PAGE_SIZE <
+          NTHeaders->OptionalHeader.SizeOfImage)
+        {
+          ProtectPage2 = (PVOID)((ULONG_PTR)ProtectPage + PAGE_SIZE);
           Status = NtProtectVirtualMemory(NtCurrentProcess(),
-                                          ImageBase + 
-                                          RelocationDir->VirtualAddress,
-                                          PAGE_SIZE,
+                                          &ProtectPage2,
+                                          &ProtectSize,
                                           PAGE_READWRITE,
-                                          &OldProtect);
-          if (!NT_SUCCESS(Status))
-            {
-              DPRINT1("Failed to unprotect relocation target.\n");
-              return(Status);
-            }
-
-          if (RelocationDir->VirtualAddress + PAGE_SIZE < MaxExtend)
-            {
-                 Status = NtProtectVirtualMemory(NtCurrentProcess(),
-                                                 ImageBase + 
-                                                 RelocationDir->VirtualAddress + PAGE_SIZE,
-                                                 PAGE_SIZE,
-                                                 PAGE_READWRITE,
-                                                 &OldProtect2);
-                 if (!NT_SUCCESS(Status))
-                   {
-                     DPRINT1("Failed to unprotect relocation target (2).\n");
-                  NtProtectVirtualMemory(NtCurrentProcess(),
-                                        ImageBase + 
-                                        RelocationDir->VirtualAddress,
-                                        PAGE_SIZE,
-                                        OldProtect,
-                                        &OldProtect);
-                     return(Status);
-                   }
-              }
-                
-          for (i = 0; i < NumberOfEntries; i++)
-            {
-              Offset = (RelocationBlock[i].TypeOffset & 0xfff);
-              Offset += (ULONG)(RelocationDir->VirtualAddress + ImageBase);
-
-              /*
-               * What kind of relocations should we perform
-               * for the current entry?
-               */
-              switch (RelocationBlock[i].TypeOffset >> 12)
-                {
-                case TYPE_RELOC_ABSOLUTE:
-                  break;
-                  
-                case TYPE_RELOC_HIGH:
-                  pValue16 = (PUSHORT)Offset;
-                  *pValue16 += Delta32 >> 16;
-                  break;
-                  
-                case TYPE_RELOC_LOW:
-                  pValue16 = (PUSHORT)Offset;
-                  *pValue16 += Delta32 & 0xffff;
-                  break;
-                  
-                case TYPE_RELOC_HIGHLOW:
-                  pValue32 = (PULONG)Offset;
-                  *pValue32 += Delta32;
-                  break;
-                          
-                case TYPE_RELOC_HIGHADJ:
-                  /* FIXME: do the highadjust fixup  */
-                  DPRINT("TYPE_RELOC_HIGHADJ fixup not implemented, sorry\n");
-                  return(STATUS_UNSUCCESSFUL);
-                  
-                default:
-                  DPRINT("unexpected fixup type\n");
-                  return STATUS_UNSUCCESSFUL;
-                }             
-            }
-
-          Status = NtProtectVirtualMemory(NtCurrentProcess(),
-                                          ImageBase + 
-                                          RelocationDir->VirtualAddress,
-                                          PAGE_SIZE,
-                                          OldProtect,
-                                          &OldProtect);
+                                          &OldProtect2);
           if (!NT_SUCCESS(Status))
             {
-              DPRINT1("Failed to protect relocation target.\n");
-              return(Status);
-            }
-
-          if (RelocationDir->VirtualAddress + PAGE_SIZE < MaxExtend)
-            {
-                 Status = NtProtectVirtualMemory(NtCurrentProcess(),
-                                                 ImageBase + 
-                                                 RelocationDir->VirtualAddress + PAGE_SIZE,
-                                                 PAGE_SIZE,
-                                                 OldProtect2,
-                                                 &OldProtect2);
-                 if (!NT_SUCCESS(Status))
-                   {
-                     DPRINT1("Failed to protect relocation target2.\n");
-                     return(Status);
-                   }
+              DPRINT1("Failed to unprotect relocation target (2).\n");
+              NtProtectVirtualMemory(NtCurrentProcess(),
+                                     &ProtectPage,
+                                     &ProtectSize,
+                                     OldProtect,
+                                     &OldProtect);
+              return Status;
             }
+        }
+      else
+        {
+          ProtectPage2 = NULL;
+        }
 
-          RelocationRVA += RelocationDir->SizeOfBlock;
-          RelocationDir = 
-            (PRELOCATION_DIRECTORY) (ImageBase + RelocationRVA);
+      RelocationDir = LdrProcessRelocationBlock(Page,
+                                                Count,
+                                                TypeOffset,
+                                                Delta);
+      if (RelocationDir == NULL)
+        return STATUS_UNSUCCESSFUL;
+
+      /* Restore old page protection. */
+      NtProtectVirtualMemory(NtCurrentProcess(),
+                             &ProtectPage,
+                             &ProtectSize,
+                             OldProtect,
+                             &OldProtect);
+
+      if (ProtectPage2 != NULL)
+        {
+          NtProtectVirtualMemory(NtCurrentProcess(),
+                                 &ProtectPage2,
+                                 &ProtectSize,
+                                 OldProtect2,
+                                 &OldProtect2);
         }
     }
+
   return STATUS_SUCCESS;
 }
-static NTSTATUS 
+
+static NTSTATUS
 LdrpGetOrLoadModule(PWCHAR SerachPath,
-                   PCHAR Name, 
-                   PLDR_MODULE* Module, 
-                   BOOL Load)
+                    PCHAR Name,
+                    PLDR_DATA_TABLE_ENTRY* Module,
+                    BOOLEAN Load)
 {
    UNICODE_STRING DllName;
    NTSTATUS Status;
@@ -1394,18 +1325,19 @@ LdrpGetOrLoadModule(PWCHAR SerachPath,
    DPRINT("LdrpGetOrLoadModule() called for %s\n", Name);
 
    RtlCreateUnicodeStringFromAsciiz (&DllName, Name);
-          
+
    Status = LdrFindEntryForName (&DllName, Module, Load);
    if (Load && !NT_SUCCESS(Status))
      {
-       Status = LdrpLoadModule(SerachPath, 
-                              NtCurrentPeb()->Ldr->Initialized ? 0 : LDRP_PROCESS_CREATION_TIME, 
-                              &DllName, 
-                              Module);
+       Status = LdrpLoadModule(SerachPath,
+                               NtCurrentPeb()->Ldr->Initialized ? 0 : LDRP_PROCESS_CREATION_TIME,
+                               &DllName,
+                               Module,
+                               NULL);
        if (NT_SUCCESS(Status))
          {
-          Status = LdrFindEntryForName (&DllName, Module, FALSE);
-        }
+           Status = LdrFindEntryForName (&DllName, Module, FALSE);
+         }
        if (!NT_SUCCESS(Status))
          {
            DPRINT1("failed to load %wZ\n", &DllName);
@@ -1416,123 +1348,152 @@ LdrpGetOrLoadModule(PWCHAR SerachPath,
 }
 
 static NTSTATUS
-LdrpProcessImportDirectory(PLDR_MODULE Module, 
-                          PLDR_MODULE ImportedModule,
-                          PCHAR ImportedName)
+LdrpProcessImportDirectoryEntry(PLDR_DATA_TABLE_ENTRY Module,
+                                PLDR_DATA_TABLE_ENTRY ImportedModule,
+                                PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory)
 {
-   PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory;
    NTSTATUS Status;
    PVOID* ImportAddressList;
    PULONG FunctionNameList;
-   DWORD pName;
-   WORD pHint;
    PVOID IATBase;
    ULONG OldProtect;
    ULONG Ordinal;
    ULONG IATSize;
-   PCHAR Name;
-
-   DPRINT("LdrpProcessImportDirectory(%x '%wZ', %x '%wZ', %x '%s')\n",
-          Module, &Module->BaseDllName, ImportedModule, 
-         &ImportedModule->BaseDllName, ImportedName, ImportedName);
 
-   ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)
-                              RtlImageDirectoryEntryToData(Module->BaseAddress, 
-                                                          TRUE, 
-                                                          IMAGE_DIRECTORY_ENTRY_IMPORT, 
-                                                          NULL);
-   if (ImportModuleDirectory == NULL)
+   if (ImportModuleDirectory == NULL || ImportModuleDirectory->Name == 0)
      {
        return STATUS_UNSUCCESSFUL;
      }
 
-   while (ImportModuleDirectory->dwRVAModuleName)
+   /* Get the import address list. */
+   ImportAddressList = (PVOID *)((ULONG_PTR)Module->DllBase + (ULONG_PTR)ImportModuleDirectory->FirstThunk);
+
+   /* Get the list of functions to import. */
+   if (ImportModuleDirectory->OriginalFirstThunk != 0)
      {
-       Name = (PCHAR)Module->BaseAddress + ImportModuleDirectory->dwRVAModuleName;
-       if (0 == _stricmp(Name, ImportedName))
-         {
+       FunctionNameList = (PULONG) ((ULONG_PTR)Module->DllBase + (ULONG_PTR)ImportModuleDirectory->OriginalFirstThunk);
+     }
+   else
+     {
+       FunctionNameList = (PULONG)((ULONG_PTR)Module->DllBase + (ULONG_PTR)ImportModuleDirectory->FirstThunk);
+     }
 
-           /* Get the import address list. */
-           ImportAddressList = (PVOID *)(Module->BaseAddress + ImportModuleDirectory->dwRVAFunctionAddressList);
+   /* Get the size of IAT. */
+   IATSize = 0;
+   while (FunctionNameList[IATSize] != 0L)
+     {
+       IATSize++;
+     }
 
-           /* Get the list of functions to import. */
-           if (ImportModuleDirectory->dwRVAFunctionNameList != 0)
+   /* Unprotect the region we are about to write into. */
+   IATBase = (PVOID)ImportAddressList;
+   IATSize *= sizeof(PVOID*);
+   Status = NtProtectVirtualMemory(NtCurrentProcess(),
+                                   &IATBase,
+                                   &IATSize,
+                                   PAGE_READWRITE,
+                                   &OldProtect);
+   if (!NT_SUCCESS(Status))
+     {
+       DPRINT1("Failed to unprotect IAT.\n");
+       return(Status);
+     }
+
+   /* Walk through function list and fixup addresses. */
+   while (*FunctionNameList != 0L)
+     {
+       if ((*FunctionNameList) & 0x80000000)
+         {
+           Ordinal = (*FunctionNameList) & 0x7fffffff;
+           *ImportAddressList = LdrGetExportByOrdinal(ImportedModule->DllBase, Ordinal);
+           if ((*ImportAddressList) == NULL)
              {
-               FunctionNameList = (PULONG) (Module->BaseAddress + ImportModuleDirectory->dwRVAFunctionNameList);
+               DPRINT1("Failed to import #%ld from %wZ\n", Ordinal, &ImportedModule->FullDllName);
+               return STATUS_UNSUCCESSFUL;
              }
-           else
+         }
+       else
+         {
+           IMAGE_IMPORT_BY_NAME *pe_name;
+           pe_name = RVA(Module->DllBase, *FunctionNameList);
+           *ImportAddressList = LdrGetExportByName(ImportedModule->DllBase, pe_name->Name, pe_name->Hint);
+           if ((*ImportAddressList) == NULL)
              {
-               FunctionNameList = (PULONG)(Module->BaseAddress + ImportModuleDirectory->dwRVAFunctionAddressList);
+               DPRINT1("Failed to import %s from %wZ\n", pe_name->Name, &ImportedModule->FullDllName);
+               return STATUS_UNSUCCESSFUL;
              }
+         }
+       ImportAddressList++;
+       FunctionNameList++;
+     }
 
-           /* Get the size of IAT. */
-           IATSize = 0;
-           while (FunctionNameList[IATSize] != 0L)
-             {
-               IATSize++;
-             }
+   /* Protect the region we are about to write into. */
+   Status = NtProtectVirtualMemory(NtCurrentProcess(),
+                                   &IATBase,
+                                   &IATSize,
+                                   OldProtect,
+                                   &OldProtect);
+   if (!NT_SUCCESS(Status))
+     {
+       DPRINT1("Failed to protect IAT.\n");
+       return(Status);
+     }
 
-          /* Unprotect the region we are about to write into. */
-          IATBase = (PVOID)ImportAddressList;
-          Status = NtProtectVirtualMemory(NtCurrentProcess(),
-                                          IATBase,
-                                          IATSize * sizeof(PVOID*),
-                                          PAGE_READWRITE,
-                                          &OldProtect);
-          if (!NT_SUCCESS(Status))
-            {
-              DPRINT1("Failed to unprotect IAT.\n");
-              return(Status);
-            }
-         
-          /* Walk through function list and fixup addresses. */
-         
-          while (*FunctionNameList != 0L)
-            {
-              if ((*FunctionNameList) & 0x80000000)
-                {
-                  Ordinal = (*FunctionNameList) & 0x7fffffff;
-                  *ImportAddressList = LdrGetExportByOrdinal(ImportedModule->BaseAddress, Ordinal);
-                }
-              else
-                {
-                  pName = (DWORD) (Module->BaseAddress + *FunctionNameList + 2);
-                  pHint = *(PWORD)(Module->BaseAddress + *FunctionNameList);
+   return STATUS_SUCCESS;
+}
 
-                  *ImportAddressList = LdrGetExportByName(ImportedModule->BaseAddress, (PUCHAR)pName, pHint);
-                  if ((*ImportAddressList) == NULL)
-                    {
-                      DPRINT1("Failed to import %s\n", pName);
-                      return STATUS_UNSUCCESSFUL;
-                    }
-                }
-              ImportAddressList++;
-              FunctionNameList++;
-           }
+static NTSTATUS
+LdrpProcessImportDirectory(
+   PLDR_DATA_TABLE_ENTRY Module,
+   PLDR_DATA_TABLE_ENTRY ImportedModule,
+   PCHAR ImportedName)
+{
+   NTSTATUS Status;
+   PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory;
+   PCHAR Name;
+   ULONG Size;
 
-           /* Protect the region we are about to write into. */
-           Status = NtProtectVirtualMemory(NtCurrentProcess(),
-                                           IATBase,
-                                           IATSize * sizeof(PVOID*),
-                                           OldProtect,
-                                           &OldProtect);
+   DPRINT("LdrpProcessImportDirectory(%x '%wZ', '%s')\n",
+          Module, &Module->BaseDllName, ImportedName);
+
+
+   ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR)
+                             RtlImageDirectoryEntryToData(Module->DllBase,
+                                                          TRUE,
+                                                          IMAGE_DIRECTORY_ENTRY_IMPORT,
+                                                          &Size);
+   if (ImportModuleDirectory == NULL)
+     {
+       return STATUS_UNSUCCESSFUL;
+     }
+
+   while (ImportModuleDirectory->Name)
+     {
+       Name = (PCHAR)Module->DllBase + ImportModuleDirectory->Name;
+       if (0 == _stricmp(Name, ImportedName))
+         {
+           Status = LdrpProcessImportDirectoryEntry(Module,
+                                                    ImportedModule,
+                                                    ImportModuleDirectory);
            if (!NT_SUCCESS(Status))
              {
-               DPRINT1("Failed to protect IAT.\n");
-               return(Status);
+               return Status;
              }
-        }
+         }
        ImportModuleDirectory++;
      }
 
+
    return STATUS_SUCCESS;
 }
 
-NTSTATUS LdrpAdjustImportDirectory(PLDR_MODULE Module, 
-                                  PLDR_MODULE ImportedModule,
-                                  PUCHAR ImportedName)
+
+static NTSTATUS
+LdrpAdjustImportDirectory(PLDR_DATA_TABLE_ENTRY Module,
+                          PLDR_DATA_TABLE_ENTRY ImportedModule,
+                          PCHAR ImportedName)
 {
-   PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory;
+   PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory;
    NTSTATUS Status;
    PVOID* ImportAddressList;
    PVOID Start;
@@ -1544,37 +1505,38 @@ NTSTATUS LdrpAdjustImportDirectory(PLDR_MODULE Module,
    ULONG IATSize;
    PIMAGE_NT_HEADERS NTHeaders;
    PCHAR Name;
+   ULONG Size;
 
    DPRINT("LdrpAdjustImportDirectory(Module %x '%wZ', %x '%wZ', %x '%s')\n",
           Module, &Module->BaseDllName, ImportedModule, &ImportedModule->BaseDllName, ImportedName);
 
-   ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)
-                              RtlImageDirectoryEntryToData(Module->BaseAddress, 
-                                                          TRUE, 
-                                                          IMAGE_DIRECTORY_ENTRY_IMPORT, 
-                                                          NULL);
+   ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR)
+                              RtlImageDirectoryEntryToData(Module->DllBase,
+                                                           TRUE,
+                                                           IMAGE_DIRECTORY_ENTRY_IMPORT,
+                                                           &Size);
    if (ImportModuleDirectory == NULL)
      {
        return STATUS_UNSUCCESSFUL;
      }
 
-   while (ImportModuleDirectory->dwRVAModuleName)
+   while (ImportModuleDirectory->Name)
      {
-       Name = (PCHAR)Module->BaseAddress + ImportModuleDirectory->dwRVAModuleName;
-       if (0 == _stricmp(Name, ImportedName))
+       Name = (PCHAR)Module->DllBase + ImportModuleDirectory->Name;
+       if (0 == _stricmp(Name, (PCHAR)ImportedName))
          {
 
            /* Get the import address list. */
-           ImportAddressList = (PVOID *)(Module->BaseAddress + ImportModuleDirectory->dwRVAFunctionAddressList);
+           ImportAddressList = (PVOID *)((ULONG_PTR)Module->DllBase + (ULONG_PTR)ImportModuleDirectory->FirstThunk);
 
            /* Get the list of functions to import. */
-           if (ImportModuleDirectory->dwRVAFunctionNameList != 0)
+           if (ImportModuleDirectory->OriginalFirstThunk != 0)
              {
-               FunctionNameList = (PULONG) (Module->BaseAddress + ImportModuleDirectory->dwRVAFunctionNameList);
+               FunctionNameList = (PULONG) ((ULONG_PTR)Module->DllBase + (ULONG_PTR)ImportModuleDirectory->OriginalFirstThunk);
              }
            else
              {
-               FunctionNameList = (PULONG)(Module->BaseAddress + ImportModuleDirectory->dwRVAFunctionAddressList);
+               FunctionNameList = (PULONG)((ULONG_PTR)Module->DllBase + (ULONG_PTR)ImportModuleDirectory->FirstThunk);
              }
 
            /* Get the size of IAT. */
@@ -1584,47 +1546,48 @@ NTSTATUS LdrpAdjustImportDirectory(PLDR_MODULE Module,
                IATSize++;
              }
 
-          /* Unprotect the region we are about to write into. */
-          IATBase = (PVOID)ImportAddressList;
-          Status = NtProtectVirtualMemory(NtCurrentProcess(),
-                                          IATBase,
-                                          IATSize * sizeof(PVOID*),
-                                          PAGE_READWRITE,
-                                          &OldProtect);
-          if (!NT_SUCCESS(Status))
-            {
-              DPRINT1("Failed to unprotect IAT.\n");
-              return(Status);
-            }
-         
-          NTHeaders = RtlImageNtHeader (ImportedModule->BaseAddress);
-          Start = (PVOID)NTHeaders->OptionalHeader.ImageBase;
-          End = Start + ImportedModule->SizeOfImage;
-          Offset = ImportedModule->BaseAddress - Start;
-
-          /* Walk through function list and fixup addresses. */
-          while (*FunctionNameList != 0L)
-            {
-              if (*ImportAddressList >= Start && *ImportAddressList < End)
+           /* Unprotect the region we are about to write into. */
+           IATBase = (PVOID)ImportAddressList;
+           IATSize *= sizeof(PVOID*);
+           Status = NtProtectVirtualMemory(NtCurrentProcess(),
+                                           &IATBase,
+                                           &IATSize,
+                                           PAGE_READWRITE,
+                                           &OldProtect);
+           if (!NT_SUCCESS(Status))
+             {
+               DPRINT1("Failed to unprotect IAT.\n");
+               return(Status);
+             }
+
+           NTHeaders = RtlImageNtHeader (ImportedModule->DllBase);
+           Start = (PVOID)NTHeaders->OptionalHeader.ImageBase;
+           End = (PVOID)((ULONG_PTR)Start + ImportedModule->SizeOfImage);
+           Offset = (ULONG)((ULONG_PTR)ImportedModule->DllBase - (ULONG_PTR)Start);
+
+           /* Walk through function list and fixup addresses. */
+           while (*FunctionNameList != 0L)
+             {
+               if (*ImportAddressList >= Start && *ImportAddressList < End)
                  {
-                  (*ImportAddressList) += Offset;
-                }
-              ImportAddressList++;
-              FunctionNameList++;
-            }
+                   (*ImportAddressList) = (PVOID)((ULONG_PTR)(*ImportAddressList) + Offset);
+                 }
+               ImportAddressList++;
+               FunctionNameList++;
+             }
 
-            /* Protect the region we are about to write into. */
-            Status = NtProtectVirtualMemory(NtCurrentProcess(),
-                                            IATBase,
-                                            IATSize * sizeof(PVOID*),
-                                            OldProtect,
-                                            &OldProtect);
-            if (!NT_SUCCESS(Status))
-              {
-                DPRINT1("Failed to protect IAT.\n");
-                return(Status);
-              }
-        }
+           /* Protect the region we are about to write into. */
+           Status = NtProtectVirtualMemory(NtCurrentProcess(),
+                                           &IATBase,
+                                           &IATSize,
+                                           OldProtect,
+                                           &OldProtect);
+           if (!NT_SUCCESS(Status))
+             {
+               DPRINT1("Failed to protect IAT.\n");
+               return(Status);
+             }
+         }
        ImportModuleDirectory++;
      }
    return STATUS_SUCCESS;
@@ -1634,7 +1597,7 @@ NTSTATUS LdrpAdjustImportDirectory(PLDR_MODULE Module,
 /**********************************************************************
  * NAME                                                         LOCAL
  *      LdrFixupImports
- *      
+ *
  * DESCRIPTION
  *      Compute the entry point for every symbol the DLL imports
  *      from other modules.
@@ -1648,55 +1611,56 @@ NTSTATUS LdrpAdjustImportDirectory(PLDR_MODULE Module,
  * NOTE
  *
  */
-static NTSTATUS 
+static NTSTATUS
 LdrFixupImports(IN PWSTR SearchPath OPTIONAL,
-               IN PLDR_MODULE Module)
+                IN PLDR_DATA_TABLE_ENTRY Module)
 {
-   PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory;
-   PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectoryCurrent;
+   PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory;
+   PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectoryCurrent;
    PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportDescriptor;
    PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportDescriptorCurrent;
    PIMAGE_TLS_DIRECTORY TlsDirectory;
-   ULONG TlsSize;
+   ULONG TlsSize = 0;
    NTSTATUS Status;
-   PLDR_MODULE ImportedModule;
+   PLDR_DATA_TABLE_ENTRY ImportedModule;
    PCHAR ImportedName;
-   
+   ULONG Size;
+
    DPRINT("LdrFixupImports(SearchPath %x, Module %x)\n", SearchPath, Module);
-   
+
    /* Check for tls data */
    TlsDirectory = (PIMAGE_TLS_DIRECTORY)
-                     RtlImageDirectoryEntryToData(Module->BaseAddress, 
-                                                 TRUE, 
-                                                 IMAGE_DIRECTORY_ENTRY_TLS, 
-                                                 NULL);
+                     RtlImageDirectoryEntryToData(Module->DllBase,
+                                                  TRUE,
+                                                  IMAGE_DIRECTORY_ENTRY_TLS,
+                                                  &Size);
    if (TlsDirectory)
      {
-       TlsSize = TlsDirectory->EndAddressOfRawData 
-                  - TlsDirectory->StartAddressOfRawData
-                  + TlsDirectory->SizeOfZeroFill;
+       TlsSize = TlsDirectory->EndAddressOfRawData
+                   - TlsDirectory->StartAddressOfRawData
+                   + TlsDirectory->SizeOfZeroFill;
        if (TlsSize > 0 &&
-          NtCurrentPeb()->Ldr->Initialized)
+           NtCurrentPeb()->Ldr->Initialized)
          {
            TRACE_LDR("Trying to load dynamicly %wZ which contains a tls directory\n",
-                    &Module->BaseDllName);
-          return STATUS_UNSUCCESSFUL;
-        }
+                     &Module->BaseDllName);
+           return STATUS_UNSUCCESSFUL;
+         }
      }
    /*
     * Process each import module.
     */
-   ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)
-                              RtlImageDirectoryEntryToData(Module->BaseAddress, 
-                                                          TRUE, 
-                                                          IMAGE_DIRECTORY_ENTRY_IMPORT, 
-                                                          NULL);
+   ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR)
+                              RtlImageDirectoryEntryToData(Module->DllBase,
+                                                           TRUE,
+                                                           IMAGE_DIRECTORY_ENTRY_IMPORT,
+                                                           &Size);
 
    BoundImportDescriptor = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)
-                              RtlImageDirectoryEntryToData(Module->BaseAddress, 
-                                                          TRUE, 
-                                                          IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT, 
-                                                          NULL);
+                              RtlImageDirectoryEntryToData(Module->DllBase,
+                                                           TRUE,
+                                                           IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
+                                                           &Size);
 
    if (BoundImportDescriptor != NULL && ImportModuleDirectory == NULL)
      {
@@ -1710,133 +1674,133 @@ LdrFixupImports(IN PWSTR SearchPath OPTIONAL,
        BoundImportDescriptorCurrent = BoundImportDescriptor;
        while (BoundImportDescriptorCurrent->OffsetModuleName)
          {
-          ImportedName = (PCHAR)BoundImportDescriptor + BoundImportDescriptorCurrent->OffsetModuleName;
-          TRACE_LDR("%wZ bound to %s\n", &Module->BaseDllName, ImportedName);
-          Status = LdrpGetOrLoadModule(SearchPath, ImportedName, &ImportedModule, TRUE);
-          if (!NT_SUCCESS(Status))
-            {
-              DPRINT1("failed to load %s\n", ImportedName);
-              return Status;
-            }
-          if (Module == ImportedModule)
-            {
-              LdrpDecrementLoadCount(Module, FALSE);
-            }
-          if (ImportedModule->TimeDateStamp != BoundImportDescriptorCurrent->TimeDateStamp)
-            {
-              TRACE_LDR("%wZ has stale binding to %wZ\n", 
-                        &Module->BaseDllName, &ImportedModule->BaseDllName);
-              Status = LdrpProcessImportDirectory(Module, ImportedModule, ImportedName);
-              if (!NT_SUCCESS(Status))
-                {
-                  DPRINT1("failed to import %s\n", ImportedName);
-                  return Status;
-                }
-            }
-          else
-            {
-              BOOL WrongForwarder;
-              WrongForwarder = FALSE;
-              if (ImportedModule->Flags & IMAGE_NOT_AT_BASE)
-                {
-                  TRACE_LDR("%wZ has stale binding to %s\n", 
-                            &Module->BaseDllName, ImportedName);
-                }
-              else
-                {
-                  TRACE_LDR("%wZ has correct binding to %wZ\n", 
-                          &Module->BaseDllName, &ImportedModule->BaseDllName);
-                }
-              if (BoundImportDescriptorCurrent->NumberOfModuleForwarderRefs)
-                {
-                  PIMAGE_BOUND_FORWARDER_REF BoundForwarderRef;
-                  ULONG i;
-                  PLDR_MODULE ForwarderModule;
-                  PUCHAR ForwarderName;
+           ImportedName = (PCHAR)BoundImportDescriptor + BoundImportDescriptorCurrent->OffsetModuleName;
+           TRACE_LDR("%wZ bound to %s\n", &Module->BaseDllName, ImportedName);
+           Status = LdrpGetOrLoadModule(SearchPath, ImportedName, &ImportedModule, TRUE);
+           if (!NT_SUCCESS(Status))
+             {
+               DPRINT1("failed to load %s\n", ImportedName);
+               return Status;
+             }
+           if (Module == ImportedModule)
+             {
+               LdrpDecrementLoadCount(Module, FALSE);
+             }
+           if (ImportedModule->TimeDateStamp != BoundImportDescriptorCurrent->TimeDateStamp)
+             {
+               TRACE_LDR("%wZ has stale binding to %wZ\n",
+                         &Module->BaseDllName, &ImportedModule->BaseDllName);
+               Status = LdrpProcessImportDirectory(Module, ImportedModule, ImportedName);
+               if (!NT_SUCCESS(Status))
+                 {
+                   DPRINT1("failed to import %s\n", ImportedName);
+                   return Status;
+                 }
+             }
+           else
+             {
+               BOOLEAN WrongForwarder;
+               WrongForwarder = FALSE;
+               if (ImportedModule->Flags & LDRP_IMAGE_NOT_AT_BASE)
+                 {
+                   TRACE_LDR("%wZ has stale binding to %s\n",
+                             &Module->BaseDllName, ImportedName);
+                 }
+               else
+                 {
+                   TRACE_LDR("%wZ has correct binding to %wZ\n",
+                           &Module->BaseDllName, &ImportedModule->BaseDllName);
+                 }
+               if (BoundImportDescriptorCurrent->NumberOfModuleForwarderRefs)
+                 {
+                   PIMAGE_BOUND_FORWARDER_REF BoundForwarderRef;
+                   ULONG i;
+                   PLDR_DATA_TABLE_ENTRY ForwarderModule;
+                   PCHAR ForwarderName;
 
                    BoundForwarderRef = (PIMAGE_BOUND_FORWARDER_REF)(BoundImportDescriptorCurrent + 1);
-                  for (i = 0; i < BoundImportDescriptorCurrent->NumberOfModuleForwarderRefs; i++, BoundForwarderRef++)
-                    {
-                      ForwarderName = (PCHAR)BoundImportDescriptor + BoundForwarderRef->OffsetModuleName;
-                      TRACE_LDR("%wZ bound to %s via forwardes from %s\n",
-                                &Module->BaseDllName, ForwarderName, ImportedName);
-                      Status = LdrpGetOrLoadModule(SearchPath, ForwarderName, &ForwarderModule, TRUE);
-                      if (!NT_SUCCESS(Status))
-                        {
-                          DPRINT1("failed to load %s\n", ForwarderName);
-                          return Status;
-                        }
-                      if (Module == ImportedModule)
-                        {
-                          LdrpDecrementLoadCount(Module, FALSE);
-                        }
-                      if (ForwarderModule->TimeDateStamp != BoundForwarderRef->TimeDateStamp ||
-                          ForwarderModule->Flags & IMAGE_NOT_AT_BASE)
-                        {
-                          TRACE_LDR("%wZ has stale binding to %s\n",
-                                    &Module->BaseDllName, ForwarderName);
-                          WrongForwarder = TRUE;
-                        }
-                      else
-                        {
-                          TRACE_LDR("%wZ has correct binding to %s\n",
-                                    &Module->BaseDllName, ForwarderName);
-                        }
-                    }
-                }
-              if (WrongForwarder ||
-                  ImportedModule->Flags & IMAGE_NOT_AT_BASE)
-                {
+                   for (i = 0; i < BoundImportDescriptorCurrent->NumberOfModuleForwarderRefs; i++, BoundForwarderRef++)
+                     {
+                       ForwarderName = (PCHAR)BoundImportDescriptor + BoundForwarderRef->OffsetModuleName;
+                       TRACE_LDR("%wZ bound to %s via forwardes from %s\n",
+                                 &Module->BaseDllName, ForwarderName, ImportedName);
+                       Status = LdrpGetOrLoadModule(SearchPath, ForwarderName, &ForwarderModule, TRUE);
+                       if (!NT_SUCCESS(Status))
+                         {
+                           DPRINT1("failed to load %s\n", ForwarderName);
+                           return Status;
+                         }
+                       if (Module == ImportedModule)
+                         {
+                           LdrpDecrementLoadCount(Module, FALSE);
+                         }
+                       if (ForwarderModule->TimeDateStamp != BoundForwarderRef->TimeDateStamp ||
+                           ForwarderModule->Flags & LDRP_IMAGE_NOT_AT_BASE)
+                         {
+                           TRACE_LDR("%wZ has stale binding to %s\n",
+                                     &Module->BaseDllName, ForwarderName);
+                           WrongForwarder = TRUE;
+                         }
+                       else
+                         {
+                           TRACE_LDR("%wZ has correct binding to %s\n",
+                                     &Module->BaseDllName, ForwarderName);
+                         }
+                     }
+                 }
+               if (WrongForwarder ||
+                   ImportedModule->Flags & LDRP_IMAGE_NOT_AT_BASE)
+                 {
                    Status = LdrpProcessImportDirectory(Module, ImportedModule, ImportedName);
-                  if (!NT_SUCCESS(Status))
-                    {
-                      DPRINT1("failed to import %s\n", ImportedName);
-                      return Status;
-                    }
-                }
-              else if (ImportedModule->Flags & IMAGE_NOT_AT_BASE)
-                {
-                  TRACE_LDR("Adjust imports for %s from %wZ\n",
-                            ImportedName, &Module->BaseDllName);
+                   if (!NT_SUCCESS(Status))
+                     {
+                       DPRINT1("failed to import %s\n", ImportedName);
+                       return Status;
+                     }
+                 }
+               else if (ImportedModule->Flags & LDRP_IMAGE_NOT_AT_BASE)
+                 {
+                   TRACE_LDR("Adjust imports for %s from %wZ\n",
+                             ImportedName, &Module->BaseDllName);
                    Status = LdrpAdjustImportDirectory(Module, ImportedModule, ImportedName);
-                  if (!NT_SUCCESS(Status))
-                  {
-                    DPRINT1("failed to adjust import entries for %s\n", ImportedName);
-                    return Status;
-                  }
-                }
-              else if (WrongForwarder)
-                {
-                  /*
-                   * FIXME:
-                   *   Update only forwarders
-                   */
-                  TRACE_LDR("Stale BIND %s from %wZ\n", 
-                            ImportedName, &Module->BaseDllName);
+                   if (!NT_SUCCESS(Status))
+                   {
+                     DPRINT1("failed to adjust import entries for %s\n", ImportedName);
+                     return Status;
+                   }
+                 }
+               else if (WrongForwarder)
+                 {
+                   /*
+                    * FIXME:
+                    *   Update only forwarders
+                    */
+                   TRACE_LDR("Stale BIND %s from %wZ\n",
+                             ImportedName, &Module->BaseDllName);
                    Status = LdrpProcessImportDirectory(Module, ImportedModule, ImportedName);
-                  if (!NT_SUCCESS(Status))
-                    {
-                      DPRINT1("faild to import %s\n", ImportedName);
-                      return Status;
-                    }
-                }
-              else
-                {
-                  /* nothing to do */
-                }
-            }
+                   if (!NT_SUCCESS(Status))
+                     {
+                       DPRINT1("faild to import %s\n", ImportedName);
+                       return Status;
+                     }
+                 }
+               else
+                 {
+                   /* nothing to do */
+                 }
+             }
            BoundImportDescriptorCurrent += BoundImportDescriptorCurrent->NumberOfModuleForwarderRefs + 1;
-        }
+         }
      }
    else if (ImportModuleDirectory)
      {
        DPRINT("ImportModuleDirectory %x\n", ImportModuleDirectory);
 
        ImportModuleDirectoryCurrent = ImportModuleDirectory;
-       while (ImportModuleDirectoryCurrent->dwRVAModuleName)
+       while (ImportModuleDirectoryCurrent->Name)
          {
-          ImportedName = (PCHAR)Module->BaseAddress + ImportModuleDirectoryCurrent->dwRVAModuleName;
-          TRACE_LDR("%wZ imports functions from %s\n", &Module->BaseDllName, ImportedName);
+           ImportedName = (PCHAR)Module->DllBase + ImportModuleDirectoryCurrent->Name;
+           TRACE_LDR("%wZ imports functions from %s\n", &Module->BaseDllName, ImportedName);
 
            Status = LdrpGetOrLoadModule(SearchPath, ImportedName, &ImportedModule, TRUE);
            if (!NT_SUCCESS(Status))
@@ -1844,21 +1808,23 @@ LdrFixupImports(IN PWSTR SearchPath OPTIONAL,
                DPRINT1("failed to load %s\n", ImportedName);
                return Status;
              }
-          if (Module == ImportedModule)
-            {
-              LdrpDecrementLoadCount(Module, FALSE);
-            }
-          TRACE_LDR("Initializing imports for %wZ from %s\n",
-                    &Module->BaseDllName, ImportedName);
-           Status = LdrpProcessImportDirectory(Module, ImportedModule, ImportedName);
-          if (!NT_SUCCESS(Status))
-            {
-              DPRINT1("failed to import %s\n", ImportedName);
-              return Status;
-            }
-          ImportModuleDirectoryCurrent++;
-        }
+           if (Module == ImportedModule)
+             {
+               LdrpDecrementLoadCount(Module, FALSE);
+             }
+
+           TRACE_LDR("Initializing imports for %wZ from %s\n",
+                     &Module->BaseDllName, ImportedName);
+           Status = LdrpProcessImportDirectoryEntry(Module, ImportedModule, ImportModuleDirectoryCurrent);
+           if (!NT_SUCCESS(Status))
+             {
+               DPRINT1("failed to import %s\n", ImportedName);
+               return Status;
+             }
+           ImportModuleDirectoryCurrent++;
+         }
      }
+
    if (TlsDirectory && TlsSize > 0)
      {
        LdrpAcquireTlsSlot(Module, TlsSize, FALSE);
@@ -1881,7 +1847,7 @@ LdrFixupImports(IN PWSTR SearchPath OPTIONAL,
  *      ImageBase
  *              Address at which the EXE's image
  *              is loaded.
- *              
+ *
  *      SectionHandle
  *              Handle of the section that contains
  *              the EXE's image.
@@ -1898,14 +1864,14 @@ LdrFixupImports(IN PWSTR SearchPath OPTIONAL,
  */
 PEPFUNC LdrPEStartup (PVOID  ImageBase,
                       HANDLE SectionHandle,
-                      PLDR_MODULE* Module,
+                      PLDR_DATA_TABLE_ENTRY* Module,
                       PWSTR FullDosName)
 {
    NTSTATUS             Status;
    PEPFUNC              EntryPoint = NULL;
    PIMAGE_DOS_HEADER    DosHeader;
    PIMAGE_NT_HEADERS    NTHeaders;
-   PLDR_MODULE tmpModule;
+   PLDR_DATA_TABLE_ENTRY tmpModule;
 
    DPRINT("LdrPEStartup(ImageBase %x SectionHandle %x)\n",
            ImageBase, (ULONG)SectionHandle);
@@ -1915,7 +1881,7 @@ PEPFUNC LdrPEStartup (PVOID  ImageBase,
     * to the DLL's image.
     */
    DosHeader = (PIMAGE_DOS_HEADER) ImageBase;
-   NTHeaders = (PIMAGE_NT_HEADERS) (ImageBase + DosHeader->e_lfanew);
+   NTHeaders = (PIMAGE_NT_HEADERS) ((ULONG_PTR)ImageBase + DosHeader->e_lfanew);
 
    /*
     * If the base address is different from the
@@ -1924,11 +1890,11 @@ PEPFUNC LdrPEStartup (PVOID  ImageBase,
     */
    if (ImageBase != (PVOID) NTHeaders->OptionalHeader.ImageBase)
      {
-       DbgPrint("LDR: Performing relocations\n");
+       DPRINT("LDR: Performing relocations\n");
        Status = LdrPerformRelocations(NTHeaders, ImageBase);
        if (!NT_SUCCESS(Status))
          {
-           DbgPrint("LdrPerformRelocations() failed\n");
+           DPRINT1("LdrPerformRelocations() failed\n");
            return NULL;
          }
      }
@@ -1936,7 +1902,7 @@ PEPFUNC LdrPEStartup (PVOID  ImageBase,
    if (Module != NULL)
      {
        *Module = LdrAddModuleEntry(ImageBase, NTHeaders, FullDosName);
-       (*Module)->SectionHandle = SectionHandle;
+       (*Module)->SectionPointer = SectionHandle;
      }
    else
      {
@@ -1944,13 +1910,13 @@ PEPFUNC LdrPEStartup (PVOID  ImageBase,
        Status = LdrFindEntryForAddress(ImageBase, Module);
        if (!NT_SUCCESS(Status))
          {
-          return NULL;
-        }
+           return NULL;
+         }
      }
-   
+
    if (ImageBase != (PVOID) NTHeaders->OptionalHeader.ImageBase)
      {
-       (*Module)->Flags |= IMAGE_NOT_AT_BASE;
+       (*Module)->Flags |= LDRP_IMAGE_NOT_AT_BASE;
      }
 
    /*
@@ -1980,7 +1946,6 @@ PEPFUNC LdrPEStartup (PVOID  ImageBase,
    RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
    if (!NT_SUCCESS(Status))
      {
-       CHECKPOINT1;
        return NULL;
      }
 
@@ -1991,27 +1956,29 @@ PEPFUNC LdrPEStartup (PVOID  ImageBase,
    DPRINT("AddressOfEntryPoint = %x\n",(ULONG)NTHeaders->OptionalHeader.AddressOfEntryPoint);
    if (NTHeaders->OptionalHeader.AddressOfEntryPoint != 0)
      {
-        EntryPoint = (PEPFUNC) (ImageBase
+        EntryPoint = (PEPFUNC) ((ULONG_PTR)ImageBase
                            + NTHeaders->OptionalHeader.AddressOfEntryPoint);
      }
    DPRINT("LdrPEStartup() = %x\n",EntryPoint);
    return EntryPoint;
 }
 
-static NTSTATUS 
+static NTSTATUS
 LdrpLoadModule(IN PWSTR SearchPath OPTIONAL,
-              IN ULONG LoadFlags,
-              IN PUNICODE_STRING Name,
-              PLDR_MODULE *Module)
+               IN ULONG LoadFlags,
+               IN PUNICODE_STRING Name,
+               PLDR_DATA_TABLE_ENTRY *Module,
+               PVOID *BaseAddress OPTIONAL)
 {
     UNICODE_STRING AdjustedName;
     UNICODE_STRING FullDosName;
     NTSTATUS Status;
-    PLDR_MODULE tmpModule;
+    PLDR_DATA_TABLE_ENTRY tmpModule;
     HANDLE SectionHandle;
     ULONG ViewSize;
     PVOID ImageBase;
     PIMAGE_NT_HEADERS NtHeaders;
+    BOOLEAN MappedAsDataFile;
 
     if (Module == NULL)
       {
@@ -2022,31 +1989,37 @@ LdrpLoadModule(IN PWSTR SearchPath OPTIONAL,
 
     DPRINT("%wZ\n", &AdjustedName);
 
+    MappedAsDataFile = FALSE;
     /* Test if dll is already loaded */
     Status = LdrFindEntryForName(&AdjustedName, Module, TRUE);
     if (NT_SUCCESS(Status))
       {
         RtlFreeUnicodeString(&AdjustedName);
+        if (NULL != BaseAddress)
+          {
+            *BaseAddress = (*Module)->DllBase;
+          }
       }
     else
       {
         /* Open or create dll image section */
         Status = LdrpMapKnownDll(&AdjustedName, &FullDosName, &SectionHandle);
-       if (!NT_SUCCESS(Status))
-         {
-            Status = LdrpMapDllImageFile(SearchPath, &AdjustedName, &FullDosName, &SectionHandle);
-         }
-       if (!NT_SUCCESS(Status))
-         {
+        if (!NT_SUCCESS(Status))
+          {
+            MappedAsDataFile = (0 != (LoadFlags & LOAD_LIBRARY_AS_DATAFILE));
+            Status = LdrpMapDllImageFile(SearchPath, &AdjustedName, &FullDosName,
+                                         MappedAsDataFile, &SectionHandle);
+          }
+        if (!NT_SUCCESS(Status))
+          {
             DPRINT1("Failed to create or open dll section of '%wZ' (Status %lx)\n", &AdjustedName, Status);
             RtlFreeUnicodeString(&AdjustedName);
-            RtlFreeUnicodeString(&FullDosName);
             return Status;
-         }
+          }
         RtlFreeUnicodeString(&AdjustedName);
-       /* Map the dll into the process */
-       ViewSize = 0;
-       ImageBase = 0;
+        /* Map the dll into the process */
+        ViewSize = 0;
+        ImageBase = 0;
         Status = NtMapViewOfSection(SectionHandle,
                                     NtCurrentProcess(),
                                     &ImageBase,
@@ -2056,7 +2029,7 @@ LdrpLoadModule(IN PWSTR SearchPath OPTIONAL,
                                     &ViewSize,
                                     0,
                                     MEM_COMMIT,
-                                    PAGE_READWRITE);
+                                    PAGE_READONLY);
         if (!NT_SUCCESS(Status))
           {
             DPRINT1("map view of section failed (Status %x)\n", Status);
@@ -2064,6 +2037,10 @@ LdrpLoadModule(IN PWSTR SearchPath OPTIONAL,
             NtClose(SectionHandle);
             return(Status);
           }
+        if (NULL != BaseAddress)
+          {
+            *BaseAddress = ImageBase;
+          }
         /* Get and check the NT headers */
         NtHeaders = RtlImageNtHeader(ImageBase);
         if (NtHeaders == NULL)
@@ -2074,63 +2051,76 @@ LdrpLoadModule(IN PWSTR SearchPath OPTIONAL,
             RtlFreeUnicodeString(&FullDosName);
             return STATUS_UNSUCCESSFUL;
           }
+        DPRINT("Mapped %wZ at %x\n", &FullDosName, ImageBase);
+        if (MappedAsDataFile)
+          {
+            ASSERT(NULL != BaseAddress);
+            if (NULL != BaseAddress)
+              {
+                *BaseAddress = (PVOID) ((char *) *BaseAddress + 1);
+              }
+            *Module = NULL;
+            RtlFreeUnicodeString(&FullDosName);
+            NtClose(SectionHandle);
+            return STATUS_SUCCESS;
+          }
         /* If the base address is different from the
          * one the DLL is actually loaded, perform any
          * relocation. */
         if (ImageBase != (PVOID) NtHeaders->OptionalHeader.ImageBase)
           {
-            DPRINT1("Performing relocations (%x -> %x)\n",
-              NtHeaders->OptionalHeader.ImageBase, ImageBase);
+            DPRINT1("Relocating (%x -> %x) %wZ\n",
+              NtHeaders->OptionalHeader.ImageBase, ImageBase, &FullDosName);
             Status = LdrPerformRelocations(NtHeaders, ImageBase);
             if (!NT_SUCCESS(Status))
               {
                 DPRINT1("LdrPerformRelocations() failed\n");
-               NtUnmapViewOfSection (NtCurrentProcess (), ImageBase);
+                NtUnmapViewOfSection (NtCurrentProcess (), ImageBase);
                 NtClose (SectionHandle);
                 RtlFreeUnicodeString(&FullDosName);
                 return STATUS_UNSUCCESSFUL;
-             }
+              }
           }
         *Module = LdrAddModuleEntry(ImageBase, NtHeaders, FullDosName.Buffer);
-        (*Module)->SectionHandle = SectionHandle;
+        (*Module)->SectionPointer = SectionHandle;
         if (ImageBase != (PVOID) NtHeaders->OptionalHeader.ImageBase)
           {
-           (*Module)->Flags |= IMAGE_NOT_AT_BASE;
-         }
+            (*Module)->Flags |= LDRP_IMAGE_NOT_AT_BASE;
+          }
         if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL)
           {
-           (*Module)->Flags |= IMAGE_DLL;
-         }
+            (*Module)->Flags |= LDRP_IMAGE_DLL;
+          }
         /* fixup the imported calls entry points */
         Status = LdrFixupImports(SearchPath, *Module);
         if (!NT_SUCCESS(Status))
           {
-           DPRINT1("LdrFixupImports failed for %wZ, status=%x\n", &(*Module)->BaseDllName, Status);
-           return Status;
-         }
-#ifdef KDBG
+            DPRINT1("LdrFixupImports failed for %wZ, status=%x\n", &(*Module)->BaseDllName, Status);
+            return Status;
+          }
+#if defined(DBG) || defined(KDBG)
         LdrpLoadUserModuleSymbols(*Module);
-#endif
+#endif /* DBG || KDBG */
         RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
-        InsertTailList(&NtCurrentPeb()->Ldr->InInitializationOrderModuleList, 
-                      &(*Module)->InInitializationOrderModuleList);
+        InsertTailList(&NtCurrentPeb()->Ldr->InInitializationOrderModuleList,
+                       &(*Module)->InInitializationOrderModuleList);
         RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
       }
     return STATUS_SUCCESS;
 }
 
-static NTSTATUS 
-LdrpUnloadModule(PLDR_MODULE Module, 
-                BOOL Unload)
+static NTSTATUS
+LdrpUnloadModule(PLDR_DATA_TABLE_ENTRY Module,
+                 BOOLEAN Unload)
 {
-   PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory;
+   PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory;
    PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportDescriptor;
    PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportDescriptorCurrent;
    PCHAR ImportedName;
-   PLDR_MODULE ImportedModule;
+   PLDR_DATA_TABLE_ENTRY ImportedModule;
    NTSTATUS Status;
    LONG LoadCount;
-
+   ULONG Size;
 
    if (Unload)
      {
@@ -2140,79 +2130,78 @@ LdrpUnloadModule(PLDR_MODULE Module,
    LoadCount = LdrpDecrementLoadCount(Module, Unload);
 
    TRACE_LDR("Unload %wZ, LoadCount %d\n", &Module->BaseDllName, LoadCount);
-   
+
    if (LoadCount == 0)
      {
        /* ?????????????????? */
-       CHECKPOINT1;
      }
    else if (LoadCount == 1)
      {
        BoundImportDescriptor = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)
-                                 RtlImageDirectoryEntryToData(Module->BaseAddress, 
-                                                             TRUE, 
-                                                             IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT, 
-                                                             NULL);
+                                 RtlImageDirectoryEntryToData(Module->DllBase,
+                                                              TRUE,
+                                                              IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
+                                                              &Size);
        if (BoundImportDescriptor)
         {
-         /* dereferencing all imported modules, use the bound import descriptor */
+          /* dereferencing all imported modules, use the bound import descriptor */
           BoundImportDescriptorCurrent = BoundImportDescriptor;
           while (BoundImportDescriptorCurrent->OffsetModuleName)
             {
-             ImportedName = (PCHAR)BoundImportDescriptor + BoundImportDescriptorCurrent->OffsetModuleName;
-             TRACE_LDR("%wZ trys to unload %s\n", &Module->BaseDllName, ImportedName);
+              ImportedName = (PCHAR)BoundImportDescriptor + BoundImportDescriptorCurrent->OffsetModuleName;
+              TRACE_LDR("%wZ trys to unload %s\n", &Module->BaseDllName, ImportedName);
               Status = LdrpGetOrLoadModule(NULL, ImportedName, &ImportedModule, FALSE);
-             if (!NT_SUCCESS(Status))
-               {
-                 DPRINT1("unable to found imported modul %s\n", ImportedName);
-               }
-             else
-               {
-                 if (Module != ImportedModule)
-                   {
+              if (!NT_SUCCESS(Status))
+                {
+                  DPRINT1("unable to found imported modul %s\n", ImportedName);
+                }
+              else
+                {
+                  if (Module != ImportedModule)
+                    {
                       Status = LdrpUnloadModule(ImportedModule, FALSE);
                       if (!NT_SUCCESS(Status))
-                       {
-                         DPRINT1("unable to unload %s\n", ImportedName);
-                       }
-                   }
-               }
-             BoundImportDescriptorCurrent++;
-           }
+                        {
+                          DPRINT1("unable to unload %s\n", ImportedName);
+                        }
+                    }
+                }
+              BoundImportDescriptorCurrent++;
+            }
          }
-       else 
+       else
          {
-           ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)
-                                      RtlImageDirectoryEntryToData(Module->BaseAddress, 
-                                                                  TRUE, 
-                                                                  IMAGE_DIRECTORY_ENTRY_IMPORT, 
-                                                                  NULL);
+           ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR)
+                                      RtlImageDirectoryEntryToData(Module->DllBase,
+                                                                   TRUE,
+                                                                   IMAGE_DIRECTORY_ENTRY_IMPORT,
+                                                                   &Size);
            if (ImportModuleDirectory)
-            {
-              /* dereferencing all imported modules, use the import descriptor */
-              while (ImportModuleDirectory->dwRVAModuleName)
-                {
-                  ImportedName = (PCHAR)Module->BaseAddress + ImportModuleDirectory->dwRVAModuleName;
-                  TRACE_LDR("%wZ trys to unload %s\n", &Module->BaseDllName, ImportedName);
+             {
+               /* dereferencing all imported modules, use the import descriptor */
+               while (ImportModuleDirectory->Name)
+                 {
+                   ImportedName = (PCHAR)Module->DllBase + ImportModuleDirectory->Name;
+                   TRACE_LDR("%wZ trys to unload %s\n", &Module->BaseDllName, ImportedName);
                    Status = LdrpGetOrLoadModule(NULL, ImportedName, &ImportedModule, FALSE);
-                  if (!NT_SUCCESS(Status))
-                    {
-                      DPRINT1("unable to found imported modul %s\n", ImportedName);
-                    }
-                  else
-                    {
-                      if (Module != ImportedModule)
-                        {
-                          Status = LdrpUnloadModule(ImportedModule, FALSE);
-                          if (!NT_SUCCESS(Status))
-                            {
-                              DPRINT1("unable to unload %s\n", ImportedName);
-                            }
-                        }
-                    }
-                  ImportModuleDirectory++;
-                }
-            }
+                   if (!NT_SUCCESS(Status))
+                     {
+                       DPRINT1("unable to found imported modul %s\n", ImportedName);
+                     }
+                   else
+                     {
+                       if (Module != ImportedModule)
+                         {
+                           Status = LdrpUnloadModule(ImportedModule, FALSE);
+                           if (!NT_SUCCESS(Status))
+                             {
+                               DPRINT1("unable to unload %s\n", ImportedName);
+                             }
+                         }
+                     }
+                   ImportModuleDirectory++;
+                 }
+             }
          }
      }
 
@@ -2228,33 +2217,41 @@ LdrpUnloadModule(PLDR_MODULE Module,
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 LdrUnloadDll (IN PVOID BaseAddress)
 {
-   PLDR_MODULE Module;
+   PLDR_DATA_TABLE_ENTRY Module;
    NTSTATUS Status;
 
    if (BaseAddress == NULL)
      return STATUS_SUCCESS;
 
-   Status = LdrFindEntryForAddress(BaseAddress, &Module);
-   if (NT_SUCCESS(Status))
+   if (LdrMappedAsDataFile(&BaseAddress))
+     {
+       Status = NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
+     }
+   else
      {
-       TRACE_LDR("LdrUnloadDll, , unloading %wZ\n", &Module->BaseDllName);
-       Status = LdrpUnloadModule(Module, TRUE);
+       Status = LdrFindEntryForAddress(BaseAddress, &Module);
+       if (NT_SUCCESS(Status))
+         {
+           TRACE_LDR("LdrUnloadDll, , unloading %wZ\n", &Module->BaseDllName);
+           Status = LdrpUnloadModule(Module, TRUE);
+         }
      }
+
    return Status;
 }
 
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 LdrDisableThreadCalloutsForDll(IN PVOID BaseAddress)
 {
     PLIST_ENTRY ModuleListHead;
     PLIST_ENTRY Entry;
-    PLDR_MODULE Module;
+    PLDR_DATA_TABLE_ENTRY Module;
     NTSTATUS Status;
 
     DPRINT("LdrDisableThreadCalloutsForDll (BaseAddress %x)\n", BaseAddress);
@@ -2263,17 +2260,17 @@ LdrDisableThreadCalloutsForDll(IN PVOID BaseAddress)
     RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
     ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
     Entry = ModuleListHead->Flink;
-    while (Entry != ModuleListHead) 
+    while (Entry != ModuleListHead)
       {
-        Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
+        Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList);
 
-        DPRINT("BaseDllName %wZ BaseAddress %x\n", &Module->BaseDllName, Module->BaseAddress);
+        DPRINT("BaseDllName %wZ BaseAddress %x\n", &Module->BaseDllName, Module->DllBase);
 
-        if (Module->BaseAddress == BaseAddress) 
-         {
-            if (Module->TlsIndex == -1) 
-             {
-                Module->Flags |= DONT_CALL_FOR_THREAD;
+        if (Module->DllBase == BaseAddress)
+          {
+            if (Module->TlsIndex == 0xFFFF)
+              {
+                Module->Flags |= LDRP_DONT_CALL_FOR_THREADS;
                 Status = STATUS_SUCCESS;
               }
             break;
@@ -2287,34 +2284,35 @@ LdrDisableThreadCalloutsForDll(IN PVOID BaseAddress)
 /*
  * @implemented
  */
-NTSTATUS STDCALL
-LdrGetDllHandle(IN PWCHAR Path OPTIONAL,
-                IN ULONG Unknown2,
+NTSTATUS NTAPI
+LdrGetDllHandle(IN PWSTR DllPath OPTIONAL,
+                IN PULONG DllCharacteristics,
                 IN PUNICODE_STRING DllName,
-                OUT PVOID* BaseAddress)
+                OUT PVOID *DllHandle)
 {
-    PLDR_MODULE Module;
+    PLDR_DATA_TABLE_ENTRY Module;
     NTSTATUS Status;
 
-    TRACE_LDR("LdrGetDllHandle, searching for %wZ from %S\n", DllName, Path ? Path : L"");
+    TRACE_LDR("LdrGetDllHandle, searching for %wZ from %S\n",
+               DllName, DllPath ? DllPath : L"");
 
     /* NULL is the current executable */
-    if (DllName == NULL) 
+    if (DllName == NULL)
       {
-        *BaseAddress = ExeModule->BaseAddress;
-        DPRINT("BaseAddress %x\n", *BaseAddress);
+        *DllHandle = ExeModule->DllBase;
+        DPRINT("BaseAddress %x\n", *DllHandle);
         return STATUS_SUCCESS;
       }
 
     Status = LdrFindEntryForName(DllName, &Module, FALSE);
     if (NT_SUCCESS(Status))
       {
-        *BaseAddress = Module->BaseAddress;
+        *DllHandle = Module->DllBase;
         return STATUS_SUCCESS;
       }
 
     DPRINT("Failed to find dll %wZ\n", DllName);
-    *BaseAddress = NULL;
+    *DllHandle = NULL;
     return STATUS_DLL_NOT_FOUND;
 }
 
@@ -2322,7 +2320,7 @@ LdrGetDllHandle(IN PWCHAR Path OPTIONAL,
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 LdrGetProcedureAddress (IN PVOID BaseAddress,
                         IN PANSI_STRING Name,
                         IN ULONG Ordinal,
@@ -2343,9 +2341,9 @@ LdrGetProcedureAddress (IN PVOID BaseAddress,
    if (Name && Name->Length)
      {
        /* by name */
-       *ProcedureAddress = LdrGetExportByName(BaseAddress, Name->Buffer, 0xffff);
+       *ProcedureAddress = LdrGetExportByName(BaseAddress, (PUCHAR)Name->Buffer, 0xffff);
        if (*ProcedureAddress != NULL)
-        {
+         {
            return STATUS_SUCCESS;
          }
        DPRINT("LdrGetProcedureAddress: Can't resolve symbol '%Z'\n", Name);
@@ -2367,7 +2365,7 @@ LdrGetProcedureAddress (IN PVOID BaseAddress,
 /**********************************************************************
  * NAME                                                         LOCAL
  *      LdrpDetachProcess
- *      
+ *
  * DESCRIPTION
  *      Unload dll's which are no longer referenced from others dll's
  *
@@ -2380,14 +2378,14 @@ LdrGetProcedureAddress (IN PVOID BaseAddress,
  * REVISIONS
  *
  * NOTE
- *      The loader lock must be held on enty. 
+ *      The loader lock must be held on enty.
  */
-static VOID 
-LdrpDetachProcess(BOOL UnloadAll)
+static VOID
+LdrpDetachProcess(BOOLEAN UnloadAll)
 {
    PLIST_ENTRY ModuleListHead;
    PLIST_ENTRY Entry;
-   PLDR_MODULE Module;
+   PLDR_DATA_TABLE_ENTRY Module;
    static ULONG CallingCount = 0;
 
    DPRINT("LdrpDetachProcess() called for %wZ\n",
@@ -2399,58 +2397,58 @@ LdrpDetachProcess(BOOL UnloadAll)
    Entry = ModuleListHead->Blink;
    while (Entry != ModuleListHead)
      {
-       Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList);
-       if (((UnloadAll && Module->LoadCount <= 0) || Module->LoadCount == 0) &&
-          Module->Flags & ENTRY_PROCESSED &&
-          !(Module->Flags & UNLOAD_IN_PROGRESS))
+       Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
+       if (((UnloadAll && Module->LoadCount == 0xFFFF) || Module->LoadCount == 0) &&
+           Module->Flags & LDRP_ENTRY_PROCESSED &&
+           !(Module->Flags & LDRP_UNLOAD_IN_PROGRESS))
          {
-           Module->Flags |= UNLOAD_IN_PROGRESS;
-          if (Module == LdrpLastModule)
-            {
-              LdrpLastModule = NULL;
-            }
-           if (Module->Flags & PROCESS_ATTACH_CALLED)
-            {
-              TRACE_LDR("Unload %wZ - Calling entry point at %x\n",
-                        &Module->BaseDllName, Module->EntryPoint);
-              LdrpCallDllEntry(Module, DLL_PROCESS_DETACH, (PVOID)(Module->LoadCount == -1 ? 1 : 0));
-            }
-          else
-            {
+           Module->Flags |= LDRP_UNLOAD_IN_PROGRESS;
+           if (Module == LdrpLastModule)
+             {
+               LdrpLastModule = NULL;
+             }
+           if (Module->Flags & LDRP_PROCESS_ATTACH_CALLED)
+             {
+               TRACE_LDR("Unload %wZ - Calling entry point at %x\n",
+                         &Module->BaseDllName, Module->EntryPoint);
+               LdrpCallDllEntry(Module, DLL_PROCESS_DETACH, (PVOID)(Module->LoadCount == 0xFFFF ? 1 : 0));
+             }
+           else
+             {
                TRACE_LDR("Unload %wZ\n", &Module->BaseDllName);
-            }
-          Entry = ModuleListHead->Blink;
-        }
+             }
+           Entry = ModuleListHead->Blink;
+         }
        else
          {
-          Entry = Entry->Blink;
-        }
+           Entry = Entry->Blink;
+         }
      }
-      
+
    if (CallingCount == 1)
      {
        Entry = ModuleListHead->Blink;
        while (Entry != ModuleListHead)
          {
-           Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList);
-          Entry = Entry->Blink;
-          if (Module->Flags & UNLOAD_IN_PROGRESS &&
-              ((UnloadAll && Module->LoadCount >= 0) || Module->LoadCount == 0))
-            {
+           Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
+           Entry = Entry->Blink;
+           if (Module->Flags & LDRP_UNLOAD_IN_PROGRESS &&
+               ((UnloadAll && Module->LoadCount != 0xFFFF) || Module->LoadCount == 0))
+             {
                /* remove the module entry from the list */
-               RemoveEntryList (&Module->InLoadOrderModuleList)
+               RemoveEntryList (&Module->InLoadOrderModuleList);
                RemoveEntryList (&Module->InInitializationOrderModuleList);
 
-              NtUnmapViewOfSection (NtCurrentProcess (), Module->BaseAddress);
-               NtClose (Module->SectionHandle);
+               NtUnmapViewOfSection (NtCurrentProcess (), Module->DllBase);
+               NtClose (Module->SectionPointer);
 
-              TRACE_LDR("%wZ unloaded\n", &Module->BaseDllName);
+               TRACE_LDR("%wZ unloaded\n", &Module->BaseDllName);
 
                RtlFreeUnicodeString (&Module->FullDllName);
                RtlFreeUnicodeString (&Module->BaseDllName);
 
                RtlFreeHeap (RtlGetProcessHeap (), 0, Module);
-            }
+             }
          }
      }
    CallingCount--;
@@ -2460,7 +2458,7 @@ LdrpDetachProcess(BOOL UnloadAll)
 /**********************************************************************
  * NAME                                                         LOCAL
  *      LdrpAttachProcess
- *      
+ *
  * DESCRIPTION
  *      Initialize all dll's which are prepered for loading
  *
@@ -2481,9 +2479,9 @@ LdrpAttachProcess(VOID)
 {
    PLIST_ENTRY ModuleListHead;
    PLIST_ENTRY Entry;
-   PLDR_MODULE Module;
-   BOOL Result;
-   NTSTATUS Status;
+   PLDR_DATA_TABLE_ENTRY Module;
+   BOOLEAN Result;
+   NTSTATUS Status = STATUS_SUCCESS;
 
    DPRINT("LdrpAttachProcess() called for %wZ\n",
           &ExeModule->BaseDllName);
@@ -2492,28 +2490,28 @@ LdrpAttachProcess(VOID)
    Entry = ModuleListHead->Flink;
    while (Entry != ModuleListHead)
      {
-       Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList);
-       if (!(Module->Flags & (LOAD_IN_PROGRESS|UNLOAD_IN_PROGRESS|ENTRY_PROCESSED)))
-        {
-          Module->Flags |= LOAD_IN_PROGRESS;
+       Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
+       if (!(Module->Flags & (LDRP_LOAD_IN_PROGRESS|LDRP_UNLOAD_IN_PROGRESS|LDRP_ENTRY_PROCESSED)))
+         {
+           Module->Flags |= LDRP_LOAD_IN_PROGRESS;
            TRACE_LDR("%wZ loaded - Calling init routine at %x for process attaching\n",
-                    &Module->BaseDllName, Module->EntryPoint);
-          Result = LdrpCallDllEntry(Module, DLL_PROCESS_ATTACH, (PVOID)(Module->LoadCount == -1 ? 1 : 0));
+                     &Module->BaseDllName, Module->EntryPoint);
+           Result = LdrpCallDllEntry(Module, DLL_PROCESS_ATTACH, (PVOID)(Module->LoadCount == 0xFFFF ? 1 : 0));
            if (!Result)
              {
-              Status = STATUS_DLL_INIT_FAILED;
-              break;
-            }
-          if (Module->Flags & IMAGE_DLL && Module->EntryPoint != 0)
-            {
-              Module->Flags |= PROCESS_ATTACH_CALLED|ENTRY_PROCESSED;
-            }
-          else
-            {
-              Module->Flags |= ENTRY_PROCESSED;
-            }
-           Module->Flags &= ~LOAD_IN_PROGRESS;
-        }
+               Status = STATUS_DLL_INIT_FAILED;
+               break;
+             }
+           if (Module->Flags & LDRP_IMAGE_DLL && Module->EntryPoint != 0)
+             {
+               Module->Flags |= LDRP_PROCESS_ATTACH_CALLED|LDRP_ENTRY_PROCESSED;
+             }
+           else
+             {
+               Module->Flags |= LDRP_ENTRY_PROCESSED;
+             }
+           Module->Flags &= ~LDRP_LOAD_IN_PROGRESS;
+         }
        Entry = Entry->Flink;
      }
 
@@ -2525,74 +2523,73 @@ LdrpAttachProcess(VOID)
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 LdrShutdownProcess (VOID)
 {
-   LdrpDetachProcess(TRUE);
-   return STATUS_SUCCESS;
+  LdrpDetachProcess(TRUE);
+  return STATUS_SUCCESS;
 }
 
 /*
  * @implemented
  */
 
-NTSTATUS 
+NTSTATUS
 LdrpAttachThread (VOID)
 {
-   PLIST_ENTRY ModuleListHead;
-   PLIST_ENTRY Entry;
-   PLDR_MODULE Module;
-   NTSTATUS Status;
-
-   DPRINT("LdrpAttachThread() called for %wZ\n",
-          &ExeModule->BaseDllName);
+  PLIST_ENTRY ModuleListHead;
+  PLIST_ENTRY Entry;
+  PLDR_DATA_TABLE_ENTRY Module;
+  NTSTATUS Status;
 
-   RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
+  DPRINT("LdrpAttachThread() called for %wZ\n",
+         &ExeModule->BaseDllName);
 
-   Status = LdrpInitializeTlsForThread();
+  RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
 
-   if (NT_SUCCESS(Status))
-     {
+  Status = LdrpInitializeTlsForThread();
 
-       ModuleListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
-       Entry = ModuleListHead->Flink;
+  if (NT_SUCCESS(Status))
+    {
+      ModuleListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
+      Entry = ModuleListHead->Flink;
 
-       while (Entry != ModuleListHead)
-         {
-           Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList);
-          if (Module->Flags & PROCESS_ATTACH_CALLED &&
-              !(Module->Flags & DONT_CALL_FOR_THREAD) &&
-               !(Module->Flags & UNLOAD_IN_PROGRESS))
-            {
-               TRACE_LDR("%wZ - Calling entry point at %x for thread attaching\n", 
-                        &Module->BaseDllName, Module->EntryPoint);
-              LdrpCallDllEntry(Module, DLL_THREAD_ATTACH, NULL);
-             }
-           Entry = Entry->Flink;
-         }
+      while (Entry != ModuleListHead)
+        {
+          Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
+          if (Module->Flags & LDRP_PROCESS_ATTACH_CALLED &&
+              !(Module->Flags & LDRP_DONT_CALL_FOR_THREADS) &&
+              !(Module->Flags & LDRP_UNLOAD_IN_PROGRESS))
+            {
+              TRACE_LDR("%wZ - Calling entry point at %x for thread attaching\n",
+                        &Module->BaseDllName, Module->EntryPoint);
+              LdrpCallDllEntry(Module, DLL_THREAD_ATTACH, NULL);
+            }
+          Entry = Entry->Flink;
+        }
 
-       Entry = NtCurrentPeb()->Ldr->InLoadOrderModuleList.Flink;
-       Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
-       LdrpTlsCallback(Module, DLL_THREAD_ATTACH);
-     }
+      Entry = NtCurrentPeb()->Ldr->InLoadOrderModuleList.Flink;
+      Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList);
+      LdrpTlsCallback(Module, DLL_THREAD_ATTACH);
+    }
 
-   RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
+  RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
 
-   DPRINT("LdrpAttachThread() done\n");
+  DPRINT("LdrpAttachThread() done\n");
 
-   return Status;
+  return Status;
 }
 
 
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 LdrShutdownThread (VOID)
 {
    PLIST_ENTRY ModuleListHead;
    PLIST_ENTRY Entry;
-   PLDR_MODULE Module;
+   PLDR_DATA_TABLE_ENTRY Module;
 
    DPRINT("LdrShutdownThread() called for %wZ\n",
           &ExeModule->BaseDllName);
@@ -2603,14 +2600,14 @@ LdrShutdownThread (VOID)
    Entry = ModuleListHead->Blink;
    while (Entry != ModuleListHead)
      {
-       Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList);
+       Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
 
-       if (Module->Flags & PROCESS_ATTACH_CALLED &&
-          !(Module->Flags & DONT_CALL_FOR_THREAD) &&
-           !(Module->Flags & UNLOAD_IN_PROGRESS))
+       if (Module->Flags & LDRP_PROCESS_ATTACH_CALLED &&
+           !(Module->Flags & LDRP_DONT_CALL_FOR_THREADS) &&
+           !(Module->Flags & LDRP_UNLOAD_IN_PROGRESS))
          {
-           TRACE_LDR("%wZ - Calling entry point at %x for thread detaching\n", 
-                    &Module->BaseDllName, Module->EntryPoint);
+           TRACE_LDR("%wZ - Calling entry point at %x for thread detaching\n",
+                     &Module->BaseDllName, Module->EntryPoint);
            LdrpCallDllEntry(Module, DLL_THREAD_DETACH, NULL);
          }
        Entry = Entry->Blink;
@@ -2645,15 +2642,15 @@ LdrShutdownThread (VOID)
  *
  * @implemented
  */
-NTSTATUS STDCALL
-LdrQueryProcessModuleInformation(IN PMODULE_INFORMATION ModuleInformation OPTIONAL,
+NTSTATUS NTAPI
+LdrQueryProcessModuleInformation(IN PRTL_PROCESS_MODULES ModuleInformation OPTIONAL,
                                  IN ULONG Size OPTIONAL,
                                  OUT PULONG ReturnedSize)
 {
   PLIST_ENTRY ModuleListHead;
   PLIST_ENTRY Entry;
-  PLDR_MODULE Module;
-  PMODULE_ENTRY ModulePtr = NULL;
+  PLDR_DATA_TABLE_ENTRY Module;
+  PRTL_PROCESS_MODULE_INFORMATION ModulePtr = NULL;
   NTSTATUS Status = STATUS_SUCCESS;
   ULONG UsedSize = sizeof(ULONG);
   ANSI_STRING AnsiString;
@@ -2679,7 +2676,7 @@ LdrQueryProcessModuleInformation(IN PMODULE_INFORMATION ModuleInformation OPTION
 
   while (Entry != ModuleListHead)
     {
-      Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
+      Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList);
 
       DPRINT("  Module %wZ\n",
              &Module->FullDllName);
@@ -2690,31 +2687,30 @@ LdrQueryProcessModuleInformation(IN PMODULE_INFORMATION ModuleInformation OPTION
         }
       else if (ModuleInformation != NULL)
         {
-          ModulePtr->Unknown0 = 0;      // FIXME: ??
-          ModulePtr->Unknown1 = 0;      // FIXME: ??
-          ModulePtr->BaseAddress = Module->BaseAddress;
-          ModulePtr->SizeOfImage = Module->SizeOfImage;
+          ModulePtr->Reserved[0] = ModulePtr->Reserved[1] = 0;      // FIXME: ??
+          ModulePtr->Base = Module->DllBase;
+          ModulePtr->Size = Module->SizeOfImage;
           ModulePtr->Flags = Module->Flags;
-          ModulePtr->Unknown2 = 0;      // FIXME: load order index ??
-          ModulePtr->Unknown3 = 0;      // FIXME: ??
+          ModulePtr->Index = 0;      // FIXME: index ??
+          ModulePtr->Unknown = 0;      // FIXME: ??
           ModulePtr->LoadCount = Module->LoadCount;
 
           AnsiString.Length = 0;
           AnsiString.MaximumLength = 256;
-          AnsiString.Buffer = ModulePtr->ModuleName;
+          AnsiString.Buffer = ModulePtr->ImageName;
           RtlUnicodeStringToAnsiString(&AnsiString,
                                        &Module->FullDllName,
                                        FALSE);
-          p = strrchr(ModulePtr->ModuleName, '\\');
+          p = strrchr(ModulePtr->ImageName, '\\');
           if (p != NULL)
-            ModulePtr->PathLength = p - ModulePtr->ModuleName + 1;
+            ModulePtr->ModuleNameOffset = p - ModulePtr->ImageName + 1;
           else
-            ModulePtr->PathLength = 0;
+            ModulePtr->ModuleNameOffset = 0;
 
           ModulePtr++;
           ModuleInformation->ModuleCount++;
         }
-      UsedSize += sizeof(MODULE_ENTRY);
+      UsedSize += sizeof(RTL_PROCESS_MODULE_INFORMATION);
 
       Entry = Entry->Flink;
     }
@@ -2732,7 +2728,7 @@ LdrQueryProcessModuleInformation(IN PMODULE_INFORMATION ModuleInformation OPTION
 
 static BOOLEAN
 LdrpCheckImageChecksum (IN PVOID BaseAddress,
-                       IN ULONG ImageSize)
+                        IN ULONG ImageSize)
 {
   PIMAGE_NT_HEADERS Header;
   PUSHORT Ptr;
@@ -2755,9 +2751,9 @@ LdrpCheckImageChecksum (IN PVOID BaseAddress,
      {
       Sum += (ULONG)*Ptr;
       if (HIWORD(Sum) != 0)
-       {
-         Sum = LOWORD(Sum) + HIWORD(Sum);
-       }
+        {
+          Sum = LOWORD(Sum) + HIWORD(Sum);
+        }
       Ptr++;
      }
 
@@ -2765,9 +2761,9 @@ LdrpCheckImageChecksum (IN PVOID BaseAddress,
     {
       Sum += (ULONG)*((PUCHAR)Ptr);
       if (HIWORD(Sum) != 0)
-       {
-         Sum = LOWORD(Sum) + HIWORD(Sum);
-       }
+        {
+          Sum = LOWORD(Sum) + HIWORD(Sum);
+        }
     }
 
   CalcSum = (USHORT)(LOWORD(Sum) + HIWORD(Sum));
@@ -2799,6 +2795,33 @@ LdrpCheckImageChecksum (IN PVOID BaseAddress,
   return (BOOLEAN)(CalcSum == HeaderSum);
 }
 
+/*
+ * Compute size of an image as it is actually present in virt memory
+ * (i.e. excluding NEVER_LOAD sections)
+ */
+ULONG
+LdrpGetResidentSize(PIMAGE_NT_HEADERS NTHeaders)
+{
+  PIMAGE_SECTION_HEADER SectionHeader;
+  unsigned SectionIndex;
+  ULONG ResidentSize;
+
+  SectionHeader = (PIMAGE_SECTION_HEADER)((char *) &NTHeaders->OptionalHeader
+                                          + NTHeaders->FileHeader.SizeOfOptionalHeader);
+  ResidentSize = 0;
+  for (SectionIndex = 0; SectionIndex < NTHeaders->FileHeader.NumberOfSections; SectionIndex++)
+    {
+      if (0 == (SectionHeader->Characteristics & IMAGE_SCN_LNK_REMOVE)
+          && ResidentSize < SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize)
+        {
+          ResidentSize = SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize;
+        }
+      SectionHeader++;
+    }
+
+  return ResidentSize;
+}
+
 
 /***************************************************************************
  * NAME                                                         EXPORTED
@@ -2816,11 +2839,11 @@ LdrpCheckImageChecksum (IN PVOID BaseAddress,
  *
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 LdrVerifyImageMatchesChecksum (IN HANDLE FileHandle,
-                              ULONG Unknown1,
-                              ULONG Unknown2,
-                              ULONG Unknown3)
+                               ULONG Unknown1,
+                               ULONG Unknown2,
+                               ULONG Unknown3)
 {
   FILE_STANDARD_INFORMATION FileInfo;
   IO_STATUS_BLOCK IoStatusBlock;
@@ -2833,12 +2856,12 @@ LdrVerifyImageMatchesChecksum (IN HANDLE FileHandle,
   DPRINT ("LdrVerifyImageMatchesChecksum() called\n");
 
   Status = NtCreateSection (&SectionHandle,
-                           SECTION_MAP_EXECUTE,
-                           NULL,
-                           NULL,
-                           PAGE_EXECUTE,
-                           SEC_COMMIT,
-                           FileHandle);
+                            SECTION_MAP_READ,
+                            NULL,
+                            NULL,
+                            PAGE_READONLY,
+                            SEC_COMMIT,
+                            FileHandle);
   if (!NT_SUCCESS(Status))
     {
       DPRINT1 ("NtCreateSection() failed (Status %lx)\n", Status);
@@ -2848,15 +2871,15 @@ LdrVerifyImageMatchesChecksum (IN HANDLE FileHandle,
   ViewSize = 0;
   BaseAddress = NULL;
   Status = NtMapViewOfSection (SectionHandle,
-                              NtCurrentProcess (),
-                              &BaseAddress,
-                              0,
-                              0,
-                              NULL,
-                              &ViewSize,
-                              ViewShare,
-                              0,
-                              PAGE_EXECUTE);
+                               NtCurrentProcess (),
+                               &BaseAddress,
+                               0,
+                               0,
+                               NULL,
+                               &ViewSize,
+                               ViewShare,
+                               0,
+                               PAGE_READONLY);
   if (!NT_SUCCESS(Status))
     {
       DPRINT1 ("NtMapViewOfSection() failed (Status %lx)\n", Status);
@@ -2865,28 +2888,28 @@ LdrVerifyImageMatchesChecksum (IN HANDLE FileHandle,
     }
 
   Status = NtQueryInformationFile (FileHandle,
-                                  &IoStatusBlock,
-                                  &FileInfo,
-                                  sizeof (FILE_STANDARD_INFORMATION),
-                                  FileStandardInformation);
+                                   &IoStatusBlock,
+                                   &FileInfo,
+                                   sizeof (FILE_STANDARD_INFORMATION),
+                                   FileStandardInformation);
   if (!NT_SUCCESS(Status))
     {
       DPRINT1 ("NtMapViewOfSection() failed (Status %lx)\n", Status);
       NtUnmapViewOfSection (NtCurrentProcess (),
-                           BaseAddress);
+                            BaseAddress);
       NtClose (SectionHandle);
       return Status;
     }
 
   Result = LdrpCheckImageChecksum (BaseAddress,
-                                  FileInfo.EndOfFile.u.LowPart);
+                                   FileInfo.EndOfFile.u.LowPart);
   if (Result == FALSE)
     {
       Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
     }
 
   NtUnmapViewOfSection (NtCurrentProcess (),
-                       BaseAddress);
+                        BaseAddress);
 
   NtClose (SectionHandle);
 
@@ -2910,13 +2933,13 @@ LdrVerifyImageMatchesChecksum (IN HANDLE FileHandle,
  *
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING SubKey,
-                                  IN PCWSTR ValueName,
-                                  IN ULONG Type,
-                                  OUT PVOID Buffer,
-                                  IN ULONG BufferSize,
-                                  OUT PULONG ReturnedLength OPTIONAL)
+                                   IN PCWSTR ValueName,
+                                   IN ULONG Type,
+                                   OUT PVOID Buffer,
+                                   IN ULONG BufferSize,
+                                   OUT PULONG ReturnedLength OPTIONAL)
 {
   PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
   OBJECT_ATTRIBUTES ObjectAttributes;
@@ -2930,7 +2953,7 @@ LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING SubKey,
   NTSTATUS Status;
 
   wcscpy (NameBuffer,
-         L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\");
+          L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\");
   Ptr = wcsrchr (SubKey->Buffer, L'\\');
   if (Ptr == NULL)
     {
@@ -2942,17 +2965,17 @@ LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING SubKey,
     }
   wcscat (NameBuffer, Ptr);
   RtlInitUnicodeString (&KeyName,
-                       NameBuffer);
+                        NameBuffer);
 
   InitializeObjectAttributes (&ObjectAttributes,
-                             &KeyName,
-                             OBJ_CASE_INSENSITIVE,
-                             NULL,
-                             NULL);
+                              &KeyName,
+                              OBJ_CASE_INSENSITIVE,
+                              NULL,
+                              NULL);
 
   Status = NtOpenKey (&KeyHandle,
-                     KEY_READ,
-                     &ObjectAttributes);
+                      KEY_READ,
+                      &ObjectAttributes);
   if (!NT_SUCCESS(Status))
     {
       DPRINT ("NtOpenKey() failed (Status %lx)\n", Status);
@@ -2961,57 +2984,57 @@ LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING SubKey,
 
   KeyInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 32;
   KeyInfo = RtlAllocateHeap (RtlGetProcessHeap(),
-                            HEAP_ZERO_MEMORY,
-                            KeyInfoSize);
+                             HEAP_ZERO_MEMORY,
+                             KeyInfoSize);
 
   RtlInitUnicodeString (&ValueNameString,
-                       (PWSTR)ValueName);
+                        (PWSTR)ValueName);
   Status = NtQueryValueKey (KeyHandle,
-                           &ValueNameString,
-                           KeyValuePartialInformation,
-                           KeyInfo,
-                           KeyInfoSize,
-                           &ResultSize);
+                            &ValueNameString,
+                            KeyValuePartialInformation,
+                            KeyInfo,
+                            KeyInfoSize,
+                            &ResultSize);
   if (Status == STATUS_BUFFER_OVERFLOW)
     {
       KeyInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + KeyInfo->DataLength;
       RtlFreeHeap (RtlGetProcessHeap(),
-                  0,
-                  KeyInfo);
+                   0,
+                   KeyInfo);
       KeyInfo = RtlAllocateHeap (RtlGetProcessHeap(),
-                                HEAP_ZERO_MEMORY,
-                                KeyInfoSize);
+                                 HEAP_ZERO_MEMORY,
+                                 KeyInfoSize);
       if (KeyInfo == NULL)
-       {
-         NtClose (KeyHandle);
-         return Status;
-       }
+        {
+          NtClose (KeyHandle);
+          return Status;
+        }
 
       Status = NtQueryValueKey (KeyHandle,
-                               &ValueNameString,
-                               KeyValuePartialInformation,
-                               KeyInfo,
-                               KeyInfoSize,
-                               &ResultSize);
+                                &ValueNameString,
+                                KeyValuePartialInformation,
+                                KeyInfo,
+                                KeyInfoSize,
+                                &ResultSize);
     }
   NtClose (KeyHandle);
 
   if (!NT_SUCCESS(Status))
     {
       if (KeyInfo != NULL)
-       {
-         RtlFreeHeap (RtlGetProcessHeap(),
-                      0,
-                      KeyInfo);
-       }
+        {
+          RtlFreeHeap (RtlGetProcessHeap(),
+                       0,
+                       KeyInfo);
+        }
       return Status;
     }
 
   if (KeyInfo->Type != Type)
     {
       RtlFreeHeap (RtlGetProcessHeap(),
-                  0,
-                  KeyInfo);
+                   0,
+                   KeyInfo);
       return STATUS_OBJECT_TYPE_MISMATCH;
     }
 
@@ -3025,12 +3048,12 @@ LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING SubKey,
       ResultSize = KeyInfo->DataLength;
     }
   RtlCopyMemory (Buffer,
-                &KeyInfo->Data,
-                ResultSize);
+                 &KeyInfo->Data,
+                 ResultSize);
 
   RtlFreeHeap (RtlGetProcessHeap(),
-              0,
-              KeyInfo);
+               0,
+               KeyInfo);
 
   if (ReturnedLength != NULL)
     {
@@ -3040,4 +3063,55 @@ LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING SubKey,
   return Status;
 }
 
+
+PIMAGE_BASE_RELOCATION NTAPI
+LdrProcessRelocationBlock(IN PVOID Address,
+                         IN USHORT Count,
+                         IN PUSHORT TypeOffset,
+                         IN ULONG_PTR Delta)
+{
+  SHORT Offset;
+  USHORT Type;
+  USHORT i;
+  PUSHORT ShortPtr;
+  PULONG LongPtr;
+
+  for (i = 0; i < Count; i++)
+    {
+      Offset = *TypeOffset & 0xFFF;
+      Type = *TypeOffset >> 12;
+
+      switch (Type)
+        {
+          case IMAGE_REL_BASED_ABSOLUTE:
+            break;
+
+          case IMAGE_REL_BASED_HIGH:
+            ShortPtr = (PUSHORT)((ULONG_PTR)Address + Offset);
+            *ShortPtr += HIWORD(Delta);
+            break;
+
+          case IMAGE_REL_BASED_LOW:
+            ShortPtr = (PUSHORT)((ULONG_PTR)Address + Offset);
+            *ShortPtr += LOWORD(Delta);
+            break;
+
+          case IMAGE_REL_BASED_HIGHLOW:
+            LongPtr = (PULONG)((ULONG_PTR)Address + Offset);
+            *LongPtr += Delta;
+            break;
+
+          case IMAGE_REL_BASED_HIGHADJ:
+          case IMAGE_REL_BASED_MIPS_JMPADDR:
+          default:
+            DPRINT1("Unknown/unsupported fixup type %hu.\n", Type);
+            return NULL;
+        }
+
+      TypeOffset++;
+    }
+
+  return (PIMAGE_BASE_RELOCATION)TypeOffset;
+}
+
 /* EOF */