From fe14b6603d0f6b5760c232db392c9b19dc9e2d3a Mon Sep 17 00:00:00 2001
From: Ulrich Weigand <weigand@informatik.uni-erlangen.de>
Date: Sun, 28 Feb 1999 11:17:03 +0000
Subject: [PATCH] NE modules adapted to CreateProcess changes.
 LoadModule16/LoadLibrary16 reorganization.

---
 loader/ne/module.c | 293 +++++++++++++++++++++++++++++++++++----------
 1 file changed, 229 insertions(+), 64 deletions(-)

diff --git a/loader/ne/module.c b/loader/ne/module.c
index f8c53c2a674..25d6d5fcec7 100644
--- a/loader/ne/module.c
+++ b/loader/ne/module.c
@@ -10,6 +10,7 @@
 #include <string.h>
 #include <unistd.h>
 #include "wine/winbase16.h"
+#include "winerror.h"
 #include "module.h"
 #include "neexe.h"
 #include "peexe.h"
@@ -708,7 +709,7 @@ static BOOL NE_LoadDLLs( NE_MODULE *pModule )
             /* its handle in the list of DLLs to initialize.   */
             HMODULE16 hDLL;
 
-            if ((hDLL = NE_LoadModule( buffer, NULL, TRUE, TRUE )) == 2)
+            if ((hDLL = NE_LoadModule( buffer, TRUE )) == 2)
             {
                 /* file not found */
                 char *p;
@@ -718,7 +719,7 @@ static BOOL NE_LoadDLLs( NE_MODULE *pModule )
                 if (!(p = strrchr( buffer, '\\' ))) p = buffer;
                 memcpy( p + 1, pstr + 1, *pstr );
                 strcpy( p + 1 + *pstr, ".dll" );
-                hDLL = NE_LoadModule( buffer, NULL, TRUE, TRUE );
+                hDLL = NE_LoadModule( buffer, TRUE );
             }
             if (hDLL < 32)
             {
@@ -743,63 +744,29 @@ static BOOL NE_LoadDLLs( NE_MODULE *pModule )
 
 
 /**********************************************************************
- *	    NE_LoadModule
+ *	    NE_LoadFileModule
  *
- * Implementation of LoadModule16().
+ * Load first instance of NE module from file.
+ * (Note: caller is responsible for ensuring the module isn't
+ *        already loaded!)
  */
-HINSTANCE16 NE_LoadModule( LPCSTR name, HINSTANCE16 *hPrevInstance,
-                           BOOL implicit, BOOL lib_only )
+static HINSTANCE16 NE_LoadFileModule( HFILE16 hFile, OFSTRUCT *ofs, 
+                                      BOOL implicit )
 {
-    HMODULE16 hModule;
     HINSTANCE16 hInstance;
+    HMODULE16 hModule;
     NE_MODULE *pModule;
-    HFILE16 hFile;
-    OFSTRUCT ofs;
-
-    /* Check if the module is already loaded */
-
-    if ((hModule = GetModuleHandle16( name )) != 0)
-    {
-        HINSTANCE16 prev;
-        pModule = NE_GetPtr( hModule );
-        if ( pModule->module32 ) return (HINSTANCE16)21;
-
-        hInstance = NE_CreateInstance( pModule, &prev, lib_only );
-        if (hInstance != prev)  /* not a library */
-            NE_LoadSegment( pModule, pModule->dgroup );
-        pModule->count++;
-        if (hPrevInstance) *hPrevInstance = prev;
-        return hInstance;
-    }
-    if (hPrevInstance) *hPrevInstance = 0;
-
-    /* Try to load the built-in first if not disabled */
-
-    if ((hModule = fnBUILTIN_LoadModule( name, FALSE ))) return hModule;
-
-    if ((hFile = OpenFile16( name, &ofs, OF_READ )) == HFILE_ERROR16)
-    {
-        /* Now try the built-in even if disabled */
-        if ((hModule = fnBUILTIN_LoadModule( name, TRUE )))
-        {
-            MSG( "Could not load Windows DLL '%s', using built-in module.\n",
-                 name );
-            return hModule;
-        }
-        return 2;  /* File not found */
-    }
 
     /* Create the module structure */
 
-    hModule = NE_LoadExeHeader( hFile, &ofs );
-    _lclose16( hFile );
+    hModule = NE_LoadExeHeader( hFile, ofs );
     if (hModule < 32) return hModule;
     pModule = NE_GetPtr( hModule );
 
     /* Allocate the segments for this module */
 
     if (!NE_CreateSegments( pModule ) ||
-        !(hInstance = NE_CreateInstance( pModule, NULL, lib_only )))
+        !(hInstance = NE_CreateInstance( pModule, NULL, FALSE )))
     {
         GlobalFreeAll16( hModule );
         return 8;  /* Insufficient memory */
@@ -833,35 +800,233 @@ HINSTANCE16 NE_LoadModule( LPCSTR name, HINSTANCE16 *hPrevInstance,
     return hInstance;
 }
 
+/**********************************************************************
+ *	    NE_LoadModule
+ *
+ * Load first instance of NE module, deciding whether to use
+ * built-in module or load module from file.
+ * (Note: caller is responsible for ensuring the module isn't
+ *        already loaded!)
+ */
+HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL implicit )
+{
+    HINSTANCE16 hInstance;
+    HMODULE16 hModule;
+    HFILE16 hFile;
+    OFSTRUCT ofs;
+
+    /* Try to load the built-in first if not disabled */
+
+    if ((hModule = fnBUILTIN_LoadModule( name, FALSE ))) return hModule;
 
-/***********************************************************************
- *           LoadLibrary   (KERNEL.95)
+    if ((hFile = OpenFile16( name, &ofs, OF_READ )) == HFILE_ERROR16)
+    {
+        /* Now try the built-in even if disabled */
+        if ((hModule = fnBUILTIN_LoadModule( name, TRUE )))
+        {
+            MSG( "Could not load Windows DLL '%s', using built-in module.\n",
+                 name );
+            return hModule;
+        }
+        return 2;  /* File not found */
+    }
+
+    hInstance = NE_LoadFileModule( hFile, &ofs, implicit );
+    _lclose16( hFile );
+
+    return hInstance;
+}
+
+/**********************************************************************
+ *          LoadModule16    (KERNEL.45)
  */
-HINSTANCE16 WINAPI LoadLibrary16( LPCSTR libname )
+HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
 {
-    HINSTANCE16 handle;
-    LPCSTR p;
-    char *new_name;
+    BOOL lib_only = !paramBlock || (paramBlock == (LPVOID)-1);
+    LOADPARAMS16 *params;
+    LPSTR cmd_line, new_cmd_line;
+    LPCVOID env = NULL;
+    STARTUPINFOA startup;
+    PROCESS_INFORMATION info;
+    HINSTANCE16 hInstance, hPrevInstance = 0;
+    HMODULE16 hModule;
+    NE_MODULE *pModule;
+    PDB *pdb;
+
 
-    TRACE(module, "(%08x) %s\n", (int)libname, libname);
+    /* Load module */
 
-    /* Check for an extension */
+    if ( ( hModule = GetModuleHandle16( name ) ) != 0 )
+    {
+        /* Special case: second instance of an already loaded NE module */
+
+        if ( !( pModule = NE_GetPtr( hModule ) ) ) return (HINSTANCE16)11;
+        if ( pModule->module32 ) return (HINSTANCE16)21;
 
-    if ((p = strrchr( libname, '.')) && !strchr( p, '/' ) && !strchr( p, '\\'))
+        hInstance = NE_CreateInstance( pModule, &hPrevInstance, lib_only );
+        if ( hInstance != hPrevInstance )  /* not a library */
+            NE_LoadSegment( pModule, pModule->dgroup );
+
+        pModule->count++;
+    }
+    else
     {
-        /* An extension is present -> use the name as is */
-        return NE_LoadModule( libname, NULL, FALSE, TRUE );
+        /* Main case: load first instance of NE module */
+
+        if ( (hInstance = NE_LoadModule( name, FALSE )) < 32 );
+            return hInstance;
+
+        if ( !(pModule = NE_GetPtr( hInstance )) )
+            return (HINSTANCE16)11;
     }
 
-    /* Now append .dll before loading */
+    /* If library module, we're finished */
+
+    if ( ( pModule->flags & NE_FFLAGS_LIBMODULE ) || lib_only )
+        return hInstance;
+
+    /* Create a task for this instance */
+
+    pModule->flags |= NE_FFLAGS_GUI;  /* FIXME: is this necessary? */
+
+    params = (LOADPARAMS16 *)paramBlock;
+    cmd_line = (LPSTR)PTR_SEG_TO_LIN( params->cmdLine );
+    if (!cmd_line) cmd_line = "";
+    else if (*cmd_line) cmd_line++;  /* skip the length byte */
 
-    if (!(new_name = HeapAlloc( GetProcessHeap(), 0, strlen(libname) + 4 )))
+    if (!(new_cmd_line = HeapAlloc( GetProcessHeap(), 0,
+                                    strlen(cmd_line)+strlen(name)+2 )))
         return 0;
-    strcpy( new_name, libname );
-    strcat( new_name, ".dll" );
-    handle = NE_LoadModule( new_name, NULL, FALSE, TRUE );
-    HeapFree( GetProcessHeap(), 0, new_name );
-    return handle;
+    strcpy( new_cmd_line, name );
+    strcat( new_cmd_line, " " );
+    strcat( new_cmd_line, cmd_line );
+
+    if (params->hEnvironment) env = GlobalLock16( params->hEnvironment );
+
+    memset( &info, '\0', sizeof(info) );
+    memset( &startup, '\0', sizeof(startup) );
+    startup.cb = sizeof(startup);
+    if (params->showCmd)
+    {
+        startup.dwFlags = STARTF_USESHOWWINDOW;
+        startup.wShowWindow = ((UINT16 *)PTR_SEG_TO_LIN(params->showCmd))[1];
+    }
+
+    pdb = PROCESS_Create( pModule, new_cmd_line, env,
+                          hInstance, hPrevInstance, TRUE, &startup, &info );
+
+    CloseHandle( info.hThread );
+    CloseHandle( info.hProcess );
+
+    if (params->hEnvironment) GlobalUnlock16( params->hEnvironment );
+    HeapFree( GetProcessHeap(), 0, new_cmd_line );
+
+    /* Start task */
+
+    if (pdb) TASK_StartTask( pdb->task );
+
+    return hInstance;
+}
+
+/**********************************************************************
+ *          NE_CreateProcess
+ */
+BOOL NE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line,
+                       LPCSTR env, BOOL inherit, LPSTARTUPINFOA startup,
+                       LPPROCESS_INFORMATION info )
+{
+    HINSTANCE16 hInstance, hPrevInstance = 0;
+    HMODULE16 hModule;
+    NE_MODULE *pModule;
+    HFILE16 hFile16;
+
+    /* Special case: second instance of an already loaded NE module */
+
+    if ( ( hModule = GetModuleHandle16( ofs->szPathName ) ) != 0 )
+    {
+        if (   !( pModule = NE_GetPtr( hModule) )
+            ||  ( pModule->flags & NE_FFLAGS_LIBMODULE )
+            ||  pModule->module32 )
+        {
+            SetLastError( ERROR_BAD_FORMAT );
+            return FALSE;
+        }
+
+        hInstance = NE_CreateInstance( pModule, &hPrevInstance, FALSE );
+        if ( hInstance != hPrevInstance )  /* not a library */
+            NE_LoadSegment( pModule, pModule->dgroup );
+
+        pModule->count++;
+    }
+
+    /* Main case: load first instance of NE module */
+    else
+    {
+        /* If we didn't get a file handle, return */
+
+        if ( hFile == HFILE_ERROR )
+            return FALSE;
+
+        /* Allocate temporary HFILE16 for NE_LoadFileModule */
+
+        if (!DuplicateHandle( GetCurrentProcess(), hFile,
+                              GetCurrentProcess(), &hFile,
+                              0, FALSE, DUPLICATE_SAME_ACCESS ))
+        {
+            SetLastError( ERROR_INVALID_HANDLE );
+            return FALSE;
+        }
+        hFile16 = FILE_AllocDosHandle( hFile );
+
+        /* Load module */
+
+        hInstance = NE_LoadFileModule( hFile16, ofs, TRUE );
+        _lclose16( hFile16 );
+
+        if ( hInstance < 32 )
+        {
+            SetLastError( hInstance );
+            return FALSE;
+        }
+
+        if (   !( pModule = NE_GetPtr( hInstance ) )
+            ||  ( pModule->flags & NE_FFLAGS_LIBMODULE) )
+        {
+            /* FIXME: cleanup */
+            SetLastError( ERROR_BAD_FORMAT );
+            return FALSE;
+        }
+    }
+
+    /* Create a task for this instance */
+
+    pModule->flags |= NE_FFLAGS_GUI;  /* FIXME: is this necessary? */
+
+    if ( !PROCESS_Create( pModule, cmd_line, env,
+                          hInstance, hPrevInstance, inherit, startup, info ) )
+        return FALSE;
+
+    return TRUE;
+}
+
+/***********************************************************************
+ *           LoadLibrary16   (KERNEL.95)
+ */
+HINSTANCE16 WINAPI LoadLibrary16( LPCSTR libname )
+{
+    char dllname[256], *p;
+
+    TRACE( module, "(%08x) %s\n", (int)libname, libname );
+
+    /* Append .DLL to name if no extension present */
+
+    strcpy( dllname, libname );
+    if (!(p = strrchr( dllname, '.')) || strchr( p, '/' ) || strchr( p, '\\'))
+        strcat( dllname, ".DLL" );
+
+    /* Load library module */
+
+    return LoadModule16( dllname, (LPVOID)-1 );
 }
 
 
@@ -1163,7 +1328,7 @@ HMODULE WINAPI MapHModuleSL(HMODULE16 hmod) {
 	if (!hmod) {
 		TDB *pTask = (TDB*)GlobalLock16(GetCurrentTask());
 
-		hmod = pTask->hInstance;
+		hmod = pTask->hModule;
 	}
 	pModule = (NE_MODULE*)GlobalLock16(hmod);
 	if (	(pModule->magic!=IMAGE_OS2_SIGNATURE)	||
-- 
GitLab