Implemented new PE DLL initalization code, trying to call the
DllEntryPoint routines always in correct order :-)
Bypass snooping when getting data buffer addresses (thunk buffers,
__GP handlers) and for 32-bit routines directly called from 16-bit
(due to stack address size problems).

diff --git a/loader/module.c b/loader/module.c
index c26df0d..93aadfe 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -52,6 +52,71 @@
     return NULL;
 }
 
+/*************************************************************************
+ *		MODULE_InitializeDLLs
+ * 
+ * Call the initialization routines of all DLLs belonging to the
+ * current process. This is somewhat complicated due to the fact that
+ *
+ * - we have to respect the module dependencies, i.e. modules implicitly
+ *   referenced by another module have to be initialized before the module
+ *   itself can be initialized
+ * 
+ * - the initialization routine of a DLL can itself call LoadLibrary,
+ *   thereby introducing a whole new set of dependencies (even involving
+ *   the 'old' modules) at any time during the whole process
+ *
+ * (Note that this routine can be recursively entered not only directly
+ *  from itself, but also via LoadLibrary from one of the called initialization
+ *  routines.)
+ */
+void MODULE_InitializeDLLs( PDB32 *process, HMODULE32 root,
+                            DWORD type, LPVOID lpReserved )
+{
+    WINE_MODREF *wm = MODULE32_LookupHMODULE( process, root );
+    int i;
+
+    if (!wm) return;
+
+    /* If called for main EXE, check for invalid recursion */
+    if ( !root && wm->initDone )
+    {
+        FIXME(module, "Invalid recursion!\n");
+        return;
+    }
+
+    /* Tag current MODREF to prevent recursive loop */
+    wm->initDone = TRUE;
+
+    /* Recursively initialize all child DLLs */
+    for ( i = 0; i < wm->nDeps; i++ )
+        if ( wm->deps[i] && !wm->deps[i]->initDone )
+            MODULE_InitializeDLLs( process, 
+                                   wm->deps[i]->module, type, lpReserved );
+
+    /* Now we can call the initialization routine */
+    switch ( wm->type )
+    {
+    case MODULE32_PE:
+        PE_InitDLL( wm, type, lpReserved );
+        break;
+
+    default:
+    	ERR(module, "wine_modref type %d not handled.\n", wm->type);
+        break;
+    }
+
+    /* If called for main EXE, reset recursion flags */
+    if ( !root )
+        for ( wm = process->modref_list; wm; wm = wm->next )
+        {
+            if (!wm->initDone)
+                FIXME(module, "Orphaned module in modref_list?\n");
+
+            wm->initDone = FALSE;
+        }
+}
+
 
 /***********************************************************************
  *           MODULE_CreateDummyModule
@@ -305,7 +370,7 @@
     }
     else
     {
-        hInstance = NE_LoadModule( name, &hPrevInstance, FALSE, FALSE );
+        hInstance = NE_LoadModule( name, &hPrevInstance, TRUE, FALSE );
         if (hInstance < 32) return hInstance;
 
         if (   !(pModule = NE_GetPtr(hInstance)) 
@@ -699,9 +764,9 @@
 	strcat( buffer, ".dll" );
 	hmod = PE_LoadLibraryEx32A(buffer,process,hfile,flags);
     }
-    /* initialize all DLLs, which haven't been initialized yet. */
+    /* initialize DLL just loaded */
     if (hmod >= 32)
-        PE_InitializeDLLs( process, DLL_PROCESS_ATTACH, NULL);
+        MODULE_InitializeDLLs( PROCESS_Current(), hmod, DLL_PROCESS_ATTACH, NULL);
     return hmod;
 }
 
@@ -996,9 +1061,16 @@
  */
 FARPROC32 WINAPI GetProcAddress32( HMODULE32 hModule, LPCSTR function )
 {
-    return MODULE_GetProcAddress32( PROCESS_Current(), hModule, function );
+    return MODULE_GetProcAddress32( PROCESS_Current(), hModule, function, TRUE );
 }
 
+/***********************************************************************
+ *           WIN16_GetProcAddress32   		(KERNEL.453)
+ */
+FARPROC32 WINAPI WIN16_GetProcAddress32( HMODULE32 hModule, LPCSTR function )
+{
+    return MODULE_GetProcAddress32( PROCESS_Current(), hModule, function, FALSE );
+}
 
 /***********************************************************************
  *           MODULE_GetProcAddress32   		(internal)
@@ -1006,7 +1078,8 @@
 FARPROC32 MODULE_GetProcAddress32( 
 	PDB32 *process,		/* [in] process context */
 	HMODULE32 hModule, 	/* [in] current module handle */
-	LPCSTR function )	/* [in] function to be looked up */
+	LPCSTR function,	/* [in] function to be looked up */
+	BOOL32 snoop )
 {
     WINE_MODREF	*wm = MODULE32_LookupHMODULE(process,hModule);
 
@@ -1019,7 +1092,7 @@
     switch (wm->type)
     {
     case MODULE32_PE:
-    	return PE_FindExportedFunction( process, wm, function);
+     	return PE_FindExportedFunction( process, wm, function, snoop );
     case MODULE32_ELF:
     	return ELF_FindExportedFunction( process, wm, function);
     default:
@@ -1062,11 +1135,13 @@
 SEGPTR WINAPI HasGPHandler( SEGPTR address )
 {
     HMODULE16 hModule;
+    int gpOrdinal;
     SEGPTR gpPtr;
     GPHANDLERDEF *gpHandler;
    
     if (    (hModule = FarGetOwner( SELECTOROF(address) )) != 0
-         && (gpPtr = (SEGPTR)WIN32_GetProcAddress16( hModule, "__GP" )) != 0
+         && (gpOrdinal = NE_GetOrdinal( hModule, "__GP" )) != 0
+         && (gpPtr = (SEGPTR)NE_GetEntryPointEx( hModule, gpOrdinal, FALSE )) != 0
          && !IsBadReadPtr16( gpPtr, sizeof(GPHANDLERDEF) )
          && (gpHandler = PTR_SEG_TO_LIN( gpPtr )) != NULL )
     {