Release 950606

Tue Jun  6 12:11:41 1995  Alexandre Julliard  (julliard@sunsite.unc.edu)

	* [controls/menu.c]
	Fixed bug with drawing multi-column menus with vertical separator.

	* [debugger/debug.l]
	Fixed NULL-pointer reference after readline().

	* [if1632/winprocs.spec] [miscemu/int21.c] [miscemu/interrupts.c]
	Added interrupt vector emulation. Allows to retrieve an interrupt
	vector and jump to it without crashing.

	* [loader/ldt.c]
	Moved ldt.c to memory directory.

	* [loader/task.c]
	Implemented LockCurrentTask() and GetInstanceData().

	* [objects/bitblt.c]
	Fixed a bug that caused StretchBlt() to use wrong colors when
	stretching a monochrome bitmap to a color display.

	* [objects/bitmap.c]
	Fixed a segmented pointer bug in CreateBitmapIndirect().

	* [tools/build.c]
	Added possibility to have arguments for register functions; used
	by interrupt vectors to remove the flags from the stack.
	Generate a new function CallTo32_LargeStack(), that allows calling
	a 32-bit function using the original 32-bit stack, for functions
	that need more that 64k of stack.

Tue May 30 10:29:56 1995  Martin von Loewis  <martin@informatik.hu-berlin.de>

	* [if1632/shell.spec] [misc/shell.c]
	DoEnvironmentSubst: fixed prototype

	* [if1632/gdi.spec] [objects/palette.c]
	SetSystemPaletteUse: new function

	* [if1632/kernel.spec] [loader/resource.c]
	DirectResAlloc: new function

	* [if1632/user.spec] [windows/keyboard.c]
	SetKeyboardState: new function

Mon May 29 12:58:28 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
        
	* [tools/build.c]
        Prevent interrupts from destroying the args for a 32 bit function
        by loading the correct value into %esp directly after %ss.

	* [loader/ne_image.c] [loader/module.c]
	The new instance must be created earlier in LoadModule(), so that
	fixups referencing it will be handled correctly.
        Initialize the local heap for a DGROUP in NE_LoadSegment().
	
	* [objects/dib.c]
	Like RLE8 bitmaps, RLE4 bitmaps don't always end with a proper code.
	This used to crash Wine. Fixed.

        * [objects/text.c]
	Fix possible null pointer dereference in debugging output.
	
	* [misc/commdlg.c]
	Handle user input in the edit control better. Some bugs fixed.
	
	* [memory/local.c]
	Started implementing moveable blocks. This is unfinished (!), but
	at least it does not seem to break things.

Wed May 24 13:26:36 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
        
	* [loader/module.c]
	LoadModule(): DLLs occasionally have a data segment, and they work
	much better if it is loaded :-)
	LoadLibrary(): pass HMODULE instead of HINSTANCE to NE_InitializeDLLs.
	FindModule(): also strip off the last backslash of the pathnames
	(Winhelp tried to load C:\WINDOWS\SYSTEM\COMMDLG.DLL).
	GetModuleHandle(): just call MODULE_FindModule, it does the same job,
	only better.
	
	* [loader/ne_image.c]
	LocalInit() the heap of a DLL in NE_InitDLL. (This is probably
	not really correct, it seems that all programs and DLLs try to do
	this themselves. But they pass weird parameters.)
	NE_InitializeDLLs should also call NE_InitDLL for the passed hModule.
	
	* [loader/task.c] [misc/user.c]
	Finish global initializations in InitTask instead of InitApp, or
	all the DLLs will be initialized in InitTask without any available
	window classes!
diff --git a/loader/module.c b/loader/module.c
index c4af5bf..aa397d8 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -292,7 +292,7 @@
 /***********************************************************************
  *           MODULE_CreateSegments
  */
-BOOL MODULE_CreateSegments( HMODULE hModule )
+static BOOL MODULE_CreateSegments( HMODULE hModule )
 {
     SEGTABLEENTRY *pSegment;
     NE_MODULE *pModule;
@@ -308,9 +308,8 @@
         {
             /* FIXME: this is needed because heap growing is not implemented */
             pModule->heap_size = 0x10000 - minsize;
-            /* For tasks, the DGROUP is allocated by MODULE_MakeNewInstance */
-            minsize = 0x10000;
-            if (!(pModule->flags & NE_FFLAGS_LIBMODULE)) continue;
+            /* The DGROUP is allocated by MODULE_CreateInstance */
+            continue;
         }
         pSegment->selector = GLOBAL_Alloc( GMEM_ZEROINIT | GMEM_FIXED,
                                       minsize, hModule,
@@ -327,6 +326,57 @@
 
 
 /***********************************************************************
+ *           MODULE_GetInstance
+ */
+static HINSTANCE MODULE_GetInstance( HMODULE hModule )
+{
+    SEGTABLEENTRY *pSegment;
+    NE_MODULE *pModule;
+    
+    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
+    if (pModule->dgroup == 0) return hModule;
+
+    pSegment = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
+    
+    return pSegment->selector;
+}
+
+
+/***********************************************************************
+ *           MODULE_CreateInstance
+ */
+static HINSTANCE MODULE_CreateInstance( HMODULE hModule, LOADPARAMS *params )
+{
+    SEGTABLEENTRY *pSegment;
+    NE_MODULE *pModule;
+    int minsize;
+    HINSTANCE hNewInstance, hPrevInstance;
+
+    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
+    if (pModule->dgroup == 0) return hModule;
+
+    pSegment = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
+    hPrevInstance = pSegment->selector;
+
+      /* if it's a library, create a new instance only the first time */
+    if (hPrevInstance)
+    {
+        if (pModule->flags & NE_FFLAGS_LIBMODULE) return hPrevInstance;
+        if (params == (LOADPARAMS*)-1) return hPrevInstance;
+    }
+
+    minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
+    if (pModule->ss == pModule->dgroup) minsize += pModule->stack_size;
+    minsize += pModule->heap_size;
+    hNewInstance = GLOBAL_Alloc( GMEM_ZEROINIT | GMEM_FIXED,
+                                 minsize, hModule, FALSE, FALSE, FALSE );
+    if (!hNewInstance) return 0;
+    pSegment->selector = hNewInstance;
+    return hNewInstance;
+}
+
+
+/***********************************************************************
  *           MODULE_LoadExeHeader
  */
 HMODULE MODULE_LoadExeHeader( int fd, OFSTRUCT *ofs )
@@ -518,62 +568,6 @@
 
 
 /***********************************************************************
- *           MODULE_MakeNewInstance
- *
- * Create a new instance of the specified module.
- */
-HINSTANCE MODULE_MakeNewInstance( HMODULE hModule, LOADPARAMS *params )
-{
-    NE_MODULE *pModule;
-    SEGTABLEENTRY *pSegment;
-    HINSTANCE hNewInstance, hPrevInstance;
-    int minsize;
-
-    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
-    if (!pModule->dgroup) return hModule;  /* No DGROUP -> return the module */
-
-    pSegment = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
-    hPrevInstance = pSegment->selector;
-
-      /* Don't create a new instance if it's a library */
-
-    if (pModule->flags & NE_FFLAGS_LIBMODULE) return hPrevInstance;
-    if (params == (LOADPARAMS*)-1) return hPrevInstance;
-
-      /* Allocate the new data segment */
-
-    minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
-    if (pModule->ss == pModule->dgroup) minsize += pModule->stack_size;
-    minsize += pModule->heap_size;
-    hNewInstance = GLOBAL_Alloc( GMEM_ZEROINIT | GMEM_FIXED,
-                                 minsize, hModule, FALSE, FALSE, FALSE );
-    if (!hNewInstance) return 0;
-    pSegment->selector = hNewInstance;
-    NE_LoadSegment( hModule, pModule->dgroup );
-
-      /* Create a new task for this instance */
-    if (!TASK_CreateTask( hModule, hNewInstance, hPrevInstance,
-                          params->hEnvironment,
-                          (LPSTR)PTR_SEG_TO_LIN( params->cmdLine ),
-                          *((WORD *)PTR_SEG_TO_LIN(params->showCmd)+1) ))
-    {
-        GlobalFree( hNewInstance );
-        return 0;
-    }
-
-      /* Initialize the local heap */
-
-    if (pModule->heap_size)
-    {
-        WORD heapstart = pSegment->minsize;
-        if (pModule->ss == pModule->dgroup) heapstart += pModule->stack_size;
-        LocalInit( hNewInstance, heapstart, heapstart + pModule->heap_size );
-    }
-    return hNewInstance;
-}
-
-
-/***********************************************************************
  *           MODULE_GetOrdinal
  *
  * Lookup the ordinal for a given name.
@@ -800,6 +794,7 @@
     BYTE len, *name_table;
 
     if (!(filename = strrchr( path, '\\' ))) filename = path;
+    else filename++;
     if ((dotptr = strrchr( filename, '.' )) != NULL)
         len = (BYTE)(dotptr - filename);
     else len = strlen( filename );
@@ -811,6 +806,7 @@
         modulepath = ((LOADEDFILEINFO*)((char*)pModule + pModule->fileinfo))->filename;
         if (!(modulename = strrchr( modulepath, '\\' )))
             modulename = modulepath;
+        else modulename++;
         if (!strcasecmp( modulename, filename )) return hModule;
 
         name_table = (BYTE *)pModule + pModule->name_table;
@@ -878,8 +874,9 @@
 HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock )
 {
     HMODULE hModule;
-    HANDLE hInstance;
+    HANDLE hInstance, hPrevInstance;
     NE_MODULE *pModule;
+    LOADPARAMS *params = (LOADPARAMS *)paramBlock;
     WORD *pModRef, *pDLLs;
     int i, fd;
 
@@ -906,6 +903,9 @@
 
         MODULE_CreateSegments( hModule );
 
+        hPrevInstance = 0;
+        hInstance = MODULE_CreateInstance( hModule, (LOADPARAMS*)paramBlock );
+
           /* Load the referenced DLLs */
 
         pModRef = (WORD *)((char *)pModule + pModule->modref_table);
@@ -950,14 +950,9 @@
             }
         }
 
-          /* Load the segments (except the DGROUP) */
+          /* Load the segments */
 
-        for (i = 1; i <= pModule->seg_count; i++)
-            if (i != pModule->dgroup) NE_LoadSegment( hModule, i );
-
-          /* Create an instance for this module */
-
-        hInstance = MODULE_MakeNewInstance( hModule, (LOADPARAMS*)paramBlock );
+        for (i = 1; i <= pModule->seg_count; i++) NE_LoadSegment( hModule, i );
 
           /* Fixup the functions prologs */
 
@@ -971,10 +966,23 @@
     else
     {
         pModule = (NE_MODULE *)GlobalLock( hModule );
-        hInstance = MODULE_MakeNewInstance( hModule, (LOADPARAMS*)paramBlock );
+        hPrevInstance = MODULE_GetInstance( hModule );
+        hInstance = MODULE_CreateInstance( hModule, params );
+        if (hInstance != hPrevInstance)  /* not a library */
+            NE_LoadSegment( hModule, pModule->dgroup );
         pModule->count++;
     }
 
+      /* Create a task for this instance */
+
+    if (!(pModule->flags & NE_FFLAGS_LIBMODULE) && (paramBlock != (LPVOID)-1))
+    {
+        TASK_CreateTask( hModule, hInstance, hPrevInstance,
+                         params->hEnvironment,
+                         (LPSTR)PTR_SEG_TO_LIN( params->cmdLine ),
+                         *((WORD *)PTR_SEG_TO_LIN(params->showCmd)+1) );
+    }
+
     return hInstance;
 }
 
@@ -999,20 +1007,7 @@
  */
 HMODULE GetModuleHandle( LPCSTR name )
 {
-    BYTE len = strlen(name);
-    HMODULE hModule = hFirstModule;
-
-    while( hModule )
-    {
-        NE_MODULE *pModule = (NE_MODULE *)GlobalLock( hModule );
-        char *pname = (char *)pModule + pModule->name_table;
-        if (((BYTE)*pname == len) && !strncasecmp( pname+1, name, len ))
-            break;
-        hModule = pModule->next;
-    }
-    dprintf_module( stddeb, "GetModuleHandle('%s'): returning %04x\n",
-                    name, hModule );
-    return hModule;
+    return MODULE_FindModule( name );
 }
 
 
@@ -1044,6 +1039,7 @@
     name = ((LOADEDFILEINFO*)((char*)pModule + pModule->fileinfo))->filename;
     strncpy( lpFileName, name, nSize );
     lpFileName[nSize-1] = '\0';
+    dprintf_module( stddeb, "GetModuleFilename: %s\n", lpFileName );
     return strlen(lpFileName);
 }
 
@@ -1056,6 +1052,8 @@
     HANDLE handle;
 
     dprintf_module( stddeb, "LoadLibrary: (%08x) %s\n", (int)libname, libname);
+    if ((handle = MODULE_FindModule( libname )) != 0) return handle;
+
     handle = LoadModule( libname, (LPVOID)-1 );
     if (handle == 2)  /* file not found */
     {
@@ -1064,7 +1062,7 @@
         strcat( buffer, ".dll" );
         handle = LoadModule( buffer, (LPVOID)-1 );
     }
-    if (handle >= 32) NE_InitializeDLLs( handle );
+    if (handle >= 32) NE_InitializeDLLs( GetExePtr(handle) );
     return handle;
 }