diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index dd8507e978f981120eac4f20a9f4cf420ab7c186..1168e1c6bb6c2060055c61186d4c5f9244719552 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -496,7 +496,6 @@ static WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename )
     WCHAR *p;
     IMAGE_NT_HEADERS *nt = RtlImageNtHeader(hModule);
     PLIST_ENTRY entry, mark;
-    BOOLEAN linked = FALSE;
     DWORD len;
 
     RtlUnicodeToMultiByteSize( &len, filename, (strlenW(filename) + 1) * sizeof(WCHAR) );
@@ -507,8 +506,7 @@ static WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename )
     wm->deps     = NULL;
 
     wm->ldr.BaseAddress   = hModule;
-    wm->ldr.EntryPoint    = (nt->OptionalHeader.AddressOfEntryPoint) ?
-                            ((char *)hModule + nt->OptionalHeader.AddressOfEntryPoint) : 0;
+    wm->ldr.EntryPoint    = NULL;
     wm->ldr.SizeOfImage   = nt->OptionalHeader.SizeOfImage;
     wm->ldr.Flags         = 0;
     wm->ldr.LoadCount     = 0;
@@ -522,27 +520,15 @@ static WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename )
     else p = wm->ldr.FullDllName.Buffer;
     RtlInitUnicodeString( &wm->ldr.BaseDllName, p );
 
-    /* this is a bit ugly, but we need to have app module first in LoadOrder
-     * list, But in wine, ntdll is loaded first, so by inserting DLLs at the tail
-     * and app module at the head we insure that order
-     */
-    if (!(nt->FileHeader.Characteristics & IMAGE_FILE_DLL))
+    if (nt->FileHeader.Characteristics & IMAGE_FILE_DLL)
     {
-        /* is first loaded module a DLL or an exec ? */
-        mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
-        if (mark->Flink == mark ||
-            (CONTAINING_RECORD(mark->Flink, LDR_MODULE, InLoadOrderModuleList)->Flags & LDR_IMAGE_IS_DLL))
-        {
-            InsertHeadList(&NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList,
-                           &wm->ldr.InLoadOrderModuleList);
-            linked = TRUE;
-        }
+        wm->ldr.Flags |= LDR_IMAGE_IS_DLL;
+        if (nt->OptionalHeader.AddressOfEntryPoint)
+            wm->ldr.EntryPoint = (char *)hModule + nt->OptionalHeader.AddressOfEntryPoint;
     }
-    else wm->ldr.Flags |= LDR_IMAGE_IS_DLL;
 
-    if (!linked)
-        InsertTailList(&NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList,
-                       &wm->ldr.InLoadOrderModuleList);
+    InsertTailList(&NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList,
+                   &wm->ldr.InLoadOrderModuleList);
 
     /* insert module in MemoryList, sorted in increasing base addresses */
     mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
@@ -692,7 +678,7 @@ static BOOL MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved )
 
     if (wm->ldr.Flags & LDR_DONT_RESOLVE_REFS) return TRUE;
     if (wm->ldr.TlsIndex != -1) call_tls_callbacks( wm->ldr.BaseAddress, reason );
-    if (!entry || !(wm->ldr.Flags & LDR_IMAGE_IS_DLL)) return TRUE;
+    if (!entry) return TRUE;
 
     if (TRACE_ON(relay))
     {
@@ -1078,8 +1064,10 @@ static void load_builtin_callback( void *module, const char *filename )
     {
         /* if we already have an executable, ignore this one */
         if (!NtCurrentTeb()->Peb->ImageBaseAddress)
+        {
             NtCurrentTeb()->Peb->ImageBaseAddress = module;
-        return; /* don't create the modref here, will be done later on */
+            return; /* don't create the modref here, will be done later on */
+        }
     }
 
     /* create the MODREF */
@@ -1771,6 +1759,43 @@ PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule)
 }
 
 
+/******************************************************************
+ *		init_system_dir
+ *
+ * System dir initialization once kernel32 has been loaded.
+ */
+static inline void init_system_dir(void)
+{
+    PLIST_ENTRY mark, entry;
+    LPWSTR buffer, p;
+
+    if (!MODULE_GetSystemDirectory( &system_dir ))
+    {
+        ERR( "Couldn't get system dir\n");
+        exit(1);
+    }
+
+    /* prepend the system dir to the name of the already created modules */
+    mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
+    for (entry = mark->Flink; entry != mark; entry = entry->Flink)
+    {
+        LDR_MODULE *mod = CONTAINING_RECORD( entry, LDR_MODULE, InLoadOrderModuleList );
+
+        assert( mod->Flags & LDR_WINE_INTERNAL );
+
+        buffer = RtlAllocateHeap( GetProcessHeap(), 0,
+                                  system_dir.Length + mod->FullDllName.Length + 2*sizeof(WCHAR) );
+        if (!buffer) continue;
+        strcpyW( buffer, system_dir.Buffer );
+        p = buffer + strlenW( buffer );
+        if (p > buffer && p[-1] != '\\') *p++ = '\\';
+        strcpyW( p, mod->FullDllName.Buffer );
+        RtlInitUnicodeString( &mod->FullDllName, buffer );
+        RtlInitUnicodeString( &mod->BaseDllName, p );
+    }
+}
+
+
 /******************************************************************
  *		LdrInitializeThunk (NTDLL.@)
  *
@@ -1786,11 +1811,7 @@ void WINAPI LdrInitializeThunk( HANDLE main_file, void *CreateFileW_ptr, ULONG u
     IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
 
     pCreateFileW = CreateFileW_ptr;
-    if (!MODULE_GetSystemDirectory( &system_dir ))
-    {
-        ERR( "Couldn't get system dir\n");
-        exit(1);
-    }
+    init_system_dir();
 
     /* allocate the modref for the main exe */
     if (!(wm = alloc_module( peb->ImageBaseAddress, main_exe_name->Buffer )))
@@ -1800,6 +1821,10 @@ void WINAPI LdrInitializeThunk( HANDLE main_file, void *CreateFileW_ptr, ULONG u
     }
     wm->ldr.LoadCount = -1;  /* can't unload main exe */
 
+    /* the main exe needs to be the first in the load order list */
+    RemoveEntryList( &wm->ldr.InLoadOrderModuleList );
+    InsertHeadList( &peb->LdrData->InLoadOrderModuleList, &wm->ldr.InLoadOrderModuleList );
+
     /* Install signal handlers; this cannot be done before, since we cannot
      * send exceptions to the debugger before the create process event that
      * is sent by REQ_INIT_PROCESS_DONE.
@@ -1813,7 +1838,7 @@ void WINAPI LdrInitializeThunk( HANDLE main_file, void *CreateFileW_ptr, ULONG u
     {
         req->module      = peb->ImageBaseAddress;
         req->module_size = wm->ldr.SizeOfImage;
-        req->entry       = wm->ldr.EntryPoint;
+        req->entry       = (char *)peb->ImageBaseAddress + nt->OptionalHeader.AddressOfEntryPoint;
         /* API requires a double indirection */
         req->name        = &main_exe_name->Buffer;
         req->exe_file    = main_file;