Release 960414

Sun Apr 14 12:51:27 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [controls/menu.c] [include/dialog.h] [windows/dialog.c]
	Made the resource loading code always use the correct Windows
	layout for Winelib on other CPUs.

	* [include/module.h] [loader/module.c]
	Added self handle in NE_MODULE structure, so we can use a pointer
	instead of a handle.
	Added function MODULE_GetPtr() to validate a HMODULE.

	* [memory/heap.c]
	Implemented Win32 heap management.

	* [memory/selector.c]
	Fix selector limit for huge blocks.

Sat Apr 13 00:19:12 1996  Huw D. M. Davies <h.davies1@physics.oxford.ac.uk>

	* [objects/metafile.c]
	Fixed memcpy bug to allow memory based metafiles to work.

Fri Apr 12 19:25:41 1996  Frans van Dorsselaer  <dorssel@rulhm1.leidenuniv.nl>

	* [controls/edit.c] [controls/EDIT.TODO]
	Complete rewrite.  Everything changed: new features, new bugs.
	Main addition: WordWrap.

Fri Apr 12 20:29:55 1996  Tristan Tarrant <tst@dcs.ed.ac.uk>

	* [resources/sysres_It.rc]
	Fixed a few mistakes in the file and resized some of the controls.

Fri Apr 12 09:55:13 1996  John Harvey <john@division.co.uk>

	* [misc/winsocket.c]
	Fixed broken #if defined that stopped unixware compiling.

	* [win32/resource.c]
        Added missing return to end of FindResource32.

Thu Apr 11 18:00:00 1996  Alex Korobka <alex@phm30.pharm.sunysb.edu>

	* [windows/keyboard.c] [windows/event.c]
	Fixed GetKeyState for mouse buttons.

	* [windows/message.c]
	WM_MOUSEACTIVATE wasn't sent in some cases.

Wed Apr 10 18:59:53 1996  Niels de Carpentier  <niels@cindy.et.tudelft.nl>

	* [objects/font.c]
	Match slightly bigger font if height negative.

Mon Apr  8 13:46:15 1996  Deano Calver <deano@rattie.demon.co.uk>

	* [multimedia/mmsystem.c]
	Changed read's to FILE_read's in mmsystem to fix mmio bug.

Sun Apr  7 21:40:29 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [misc/commdlg.c] [resources/sysres_En.rc] [resources/sysres_De.rc]
	Introduced ColorDlgProc() for ChooseColor() and replaced fitting
	En-,De- resources. 
	As written in TODO: some national language support is needed here.
diff --git a/loader/module.c b/loader/module.c
index 060c286..128c05a 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -72,10 +72,11 @@
     dprintf_module( stddeb, "Built-in %s: hmodule=%04x\n",
                     table->name, hModule );
     pModule = (NE_MODULE *)GlobalLock( hModule );
+    pModule->self = hModule;
 
     if (pModule->flags & NE_FFLAGS_WIN32)
     {
-        ((NE_WIN32_EXTRAINFO*)(pModule+1))->pe_module = (DWORD)table;
+        pModule->pe_module = (PE_MODULE *)table;
     }
     else  /* Win16 module */
     {
@@ -127,6 +128,18 @@
 
 
 /***********************************************************************
+ *           MODULE_GetPtr
+ */
+NE_MODULE *MODULE_GetPtr( HMODULE hModule )
+{
+    NE_MODULE *pModule = (NE_MODULE *)GlobalLock( hModule );
+    if (!pModule || (pModule->magic != NE_SIGNATURE) ||
+        (pModule->self != hModule)) return NULL;
+    return pModule;
+}
+
+
+/***********************************************************************
  *           MODULE_DumpModule
  */
 void MODULE_DumpModule( HMODULE hmodule )
@@ -135,9 +148,9 @@
     SEGTABLEENTRY *pSeg;
     BYTE *pstr;
     WORD *pword;
-    NE_MODULE *pModule = (NE_MODULE *)GlobalLock( hmodule );
+    NE_MODULE *pModule;
 
-    if (!pModule || (pModule->magic != NE_SIGNATURE))
+    if (!(pModule = MODULE_GetPtr( hmodule )))
     {
         fprintf( stderr, "**** %04x is not a module handle\n", hmodule );
         return;
@@ -156,7 +169,7 @@
             pModule->os_flags, pModule->min_swap_area,
             pModule->expected_version );
     if (pModule->flags & NE_FFLAGS_WIN32)
-        printf( "PE module=%08x\n", (unsigned int)NE_WIN32_MODULE(pModule) );
+        printf( "PE module=%08x\n", (unsigned int)pModule->pe_module );
 
       /* Dump the file info */
 
@@ -276,8 +289,8 @@
     fprintf( stderr, "Module Flags Name\n" );
     while (hModule)
     {
-        NE_MODULE *pModule = (NE_MODULE *)GlobalLock( hModule );
-        if (!pModule || (pModule->magic != NE_SIGNATURE))
+        NE_MODULE *pModule = MODULE_GetPtr( hModule );
+        if (!pModule)
         {
             fprintf( stderr, "**** Bad module %04x in list\n", hModule );
             return;
@@ -304,7 +317,7 @@
     hModule = GetExePtr( hModule );  /* In case we were passed an hInstance */
     dprintf_module( stddeb, "MODULE_OpenFile(%04x) cache: mod=%04x fd=%d\n",
                     hModule, hCachedModule, cachedfd );
-    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return -1;
+    if (!(pModule = MODULE_GetPtr( hModule ))) return -1;
     if (hCachedModule == hModule) return cachedfd;
     close( cachedfd );
     hCachedModule = hModule;
@@ -370,7 +383,7 @@
     NE_MODULE *pModule;
     int i, minsize;
 
-    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return FALSE;
+    if (!(pModule = MODULE_GetPtr( hModule ))) return FALSE;
     pSegment = NE_SEG_TABLE( pModule );
     for (i = 1; i <= pModule->seg_count; i++, pSegment++)
     {
@@ -402,7 +415,7 @@
     SEGTABLEENTRY *pSegment;
     NE_MODULE *pModule;
     
-    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
+    if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
     if (pModule->dgroup == 0) return hModule;
 
     pSegment = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
@@ -422,7 +435,7 @@
     int minsize;
     HINSTANCE hNewInstance, hPrevInstance;
 
-    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
+    if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
     if (pModule->dgroup == 0) return hModule;
 
     pSegment = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
@@ -501,10 +514,17 @@
     if (!hModule) return (HMODULE)11;  /* invalid exe */
     FarSetOwner( hModule, hModule );
     pModule = (NE_MODULE *)GlobalLock( hModule );
-    memcpy( pModule, &ne_header, sizeof(NE_MODULE) );
+    memcpy( pModule, &ne_header, sizeof(ne_header) );
     pModule->count = 0;
+    pModule->pe_module = NULL;
+    pModule->self = hModule;
+    pModule->self_loading_sel = 0;
     pData = (BYTE *)(pModule + 1);
 
+    /* Clear internal Wine flags in case they are set in the EXE file */
+
+    pModule->flags &= ~(NE_FFLAGS_BUILTIN | NE_FFLAGS_WIN32);
+
     /* Read the fast-load area */
 
     if (ne_header.additional_flags & NE_AFLAGS_FASTLOAD)
@@ -524,10 +544,6 @@
         }
     }
 
-    /* Clear internal Wine flags in case they are set in the EXE file */
-
-    pModule->flags &= ~(NE_FFLAGS_BUILTIN | NE_FFLAGS_WIN32);
-
     /* Store the filename information */
 
     pModule->fileinfo = (int)pData - (int)pModule;
@@ -556,7 +572,11 @@
         }
         free( buffer );
     }
-    else return (HMODULE)11;  /* invalid exe */
+    else
+    {
+        GlobalFree( hModule );
+        return (HMODULE)11;  /* invalid exe */
+    }
 
     /* Get the resource table */
 
@@ -575,7 +595,11 @@
     pModule->name_table = (int)pData - (int)pModule;
     if (!READ( ne_header.rname_tab_offset,
                ne_header.moduleref_tab_offset - ne_header.rname_tab_offset,
-               pData )) return (HMODULE)11;  /* invalid exe */
+               pData ))
+    {
+        GlobalFree( hModule );
+        return (HMODULE)11;  /* invalid exe */
+    }
     pData += ne_header.moduleref_tab_offset - ne_header.rname_tab_offset;
 
     /* Get the module references table */
@@ -595,7 +619,11 @@
     pModule->import_table = (int)pData - (int)pModule;
     if (!READ( ne_header.iname_tab_offset, 
                ne_header.entry_tab_offset - ne_header.iname_tab_offset,
-               pData )) return (HMODULE)11;  /* invalid exe */
+               pData ))
+    {
+        GlobalFree( hModule );
+        return (HMODULE)11;  /* invalid exe */
+    }
     pData += ne_header.entry_tab_offset - ne_header.iname_tab_offset;
 
     /* Get the entry table */
@@ -603,7 +631,11 @@
     pModule->entry_table = (int)pData - (int)pModule;
     if (!READ( ne_header.entry_tab_offset,
                ne_header.entry_tab_length,
-               pData )) return (HMODULE)11;  /* invalid exe */
+               pData ))
+    {
+        GlobalFree( hModule );
+        return (HMODULE)11;  /* invalid exe */
+    }
     pData += ne_header.entry_tab_length;
 
     /* Get the non-resident names table */
@@ -612,11 +644,20 @@
     {
         pModule->nrname_handle = GLOBAL_Alloc( 0, ne_header.nrname_tab_length,
                                                hModule, FALSE, FALSE, FALSE );
-        if (!pModule->nrname_handle) return (HMODULE)11;  /* invalid exe */
+        if (!pModule->nrname_handle)
+        {
+            GlobalFree( hModule );
+            return (HMODULE)11;  /* invalid exe */
+        }
         buffer = GlobalLock( pModule->nrname_handle );
         _llseek( hFile, ne_header.nrname_tab_offset, SEEK_SET );
         if (FILE_Read( hFile, buffer, ne_header.nrname_tab_length )
-              != ne_header.nrname_tab_length) return (HMODULE)11;  /* invalid exe */
+              != ne_header.nrname_tab_length)
+        {
+            GlobalFree( pModule->nrname_handle );
+            GlobalFree( hModule );
+            return (HMODULE)11;  /* invalid exe */
+        }
     }
     else pModule->nrname_handle = 0;
 
@@ -627,14 +668,19 @@
         pModule->dlls_to_init = GLOBAL_Alloc(GMEM_ZEROINIT,
                                     (pModule->modref_count+1)*sizeof(HMODULE),
                                     hModule, FALSE, FALSE, FALSE );
-        if (!pModule->dlls_to_init) return (HMODULE)11;  /* invalid exe */
+        if (!pModule->dlls_to_init)
+        {
+            if (pModule->nrname_handle) GlobalFree( pModule->nrname_handle );
+            GlobalFree( hModule );
+            return (HMODULE)11;  /* invalid exe */
+        }
     }
     else pModule->dlls_to_init = 0;
 
-    if (debugging_module) MODULE_DumpModule( hModule );
     pModule->next = hFirstModule;
     hFirstModule = hModule;
     return hModule;
+#undef READ
 }
 
 
@@ -649,7 +695,7 @@
     BYTE len;
     NE_MODULE *pModule;
 
-    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
+    if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
 
     dprintf_module( stddeb, "MODULE_GetOrdinal(%04x,'%s')\n",
                     hModule, name );
@@ -714,7 +760,7 @@
     BYTE *p;
     WORD sel, offset;
 
-    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
+    if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
 
     p = (BYTE *)pModule + pModule->entry_table;
     while (*p && (curOrdinal + *p <= ordinal))
@@ -764,7 +810,7 @@
     WORD curOrdinal = 1;
     BYTE *p;
 
-    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return FALSE;
+    if (!(pModule = MODULE_GetPtr( hModule ))) return FALSE;
 
     p = (BYTE *)pModule + pModule->entry_table;
     while (*p && (curOrdinal + *p <= ordinal))
@@ -809,7 +855,7 @@
     register char *cpnt;
     NE_MODULE *pModule;
 
-    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
+    if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
 
       /* First search the resident names */
 
@@ -876,7 +922,7 @@
     BYTE *p, len;
     static char buffer[10];
 
-    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return NULL;
+    if (!(pModule = MODULE_GetPtr( hModule ))) return NULL;
     p = (BYTE *)pModule + pModule->name_table;
     len = MIN( *p, 8 );
     memcpy( buffer, p + 1, len );
@@ -890,10 +936,9 @@
  */
 void MODULE_RegisterModule( HMODULE hModule )
 {
-	NE_MODULE *pModule;
-	pModule = (NE_MODULE *)GlobalLock( hModule );
-	pModule->next = hFirstModule;
-	hFirstModule = hModule;
+    NE_MODULE *pModule = MODULE_GetPtr( hModule );
+    pModule->next = hFirstModule;
+    hFirstModule = hModule;
 }
 
 /**********************************************************************
@@ -915,7 +960,7 @@
 
     while(hModule)
     {
-        NE_MODULE *pModule = (NE_MODULE *)GlobalLock( hModule );
+        NE_MODULE *pModule = MODULE_GetPtr( hModule );
         if (!pModule) break;
         modulepath = NE_MODULE_NAME(pModule);
         if (!(modulename = strrchr( modulepath, '\\' )))
@@ -945,18 +990,22 @@
     HMODULE *pModRef;
     int i;
 
-    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return;
+    if (!(pModule = MODULE_GetPtr( hModule ))) return;
     if (pModule->flags & NE_FFLAGS_BUILTIN)
         return;  /* Can't free built-in module */
 
     /* FIXME: should call the exit code for the library here */
 
+    /* Clear magic number just in case */
+
+    pModule->magic = pModule->self = 0;
+
       /* Remove it from the linked list */
 
     hPrevModule = &hFirstModule;
     while (*hPrevModule && (*hPrevModule != hModule))
     {
-        hPrevModule = &((NE_MODULE *)GlobalLock( *hPrevModule ))->next;
+        hPrevModule = &(MODULE_GetPtr( *hPrevModule ))->next;
     }
     if (*hPrevModule) *hPrevModule = pModule->next;
 
@@ -1038,7 +1087,7 @@
             return hModule;
         }
         _lclose( hFile );
-        pModule = (NE_MODULE *)GlobalLock( hModule );
+        pModule = MODULE_GetPtr( hModule );
 
           /* Allocate the segments for this module */
 
@@ -1086,7 +1135,7 @@
             }
             else  /* Increment the reference count of the DLL */
             {
-                NE_MODULE *pOldDLL = (NE_MODULE *)GlobalLock( *pModRef );
+                NE_MODULE *pOldDLL = MODULE_GetPtr( *pModRef );
                 if (pOldDLL) pOldDLL->count++;
             }
         }
@@ -1171,7 +1220,7 @@
 
           /* Fixup the functions prologs */
 
-        NE_FixupPrologs( hModule );
+        NE_FixupPrologs( pModule );
 
           /* Make sure the usage count is 1 on the first loading of  */
           /* the module, even if it contains circular DLL references */
@@ -1180,7 +1229,7 @@
     }
     else
     {
-        pModule = (NE_MODULE *)GlobalLock( hModule );
+        pModule = MODULE_GetPtr( hModule );
         hPrevInstance = MODULE_GetInstance( hModule );
         hInstance = MODULE_CreateInstance( hModule, params );
         if (hInstance != hPrevInstance)  /* not a library */
@@ -1191,7 +1240,8 @@
     hModule = GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(NE_MODULE) );
     pModule = (NE_MODULE *)GlobalLock( hModule );
     pModule->count = 1;
-    pModule->magic = 0x454e;
+    pModule->magic = NE_SIGNATURE;
+    pModule->self = hModule;
     hPrevInstance = 0;
     hInstance = MODULE_CreateInstance( hModule, (LOADPARAMS*)paramBlock );
 #endif /* WINELIB */
@@ -1218,7 +1268,7 @@
     NE_MODULE *pModule;
 
     hModule = GetExePtr( hModule );  /* In case we were passed an hInstance */
-    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return FALSE;
+    if (!(pModule = MODULE_GetPtr( hModule ))) return FALSE;
 
     dprintf_module( stddeb, "FreeModule: %s count %d\n", 
 		    MODULE_GetModuleName(hModule), pModule->count );
@@ -1250,7 +1300,7 @@
     NE_MODULE *pModule;
 
     hModule = GetExePtr( hModule );  /* In case we were passed an hInstance */
-    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
+    if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
     dprintf_module( stddeb, "GetModuleUsage(%04x): returning %d\n",
                     hModule, pModule->count );
     return pModule->count;
@@ -1265,7 +1315,7 @@
     NE_MODULE *pModule;
 
     hModule = GetExePtr( hModule );  /* In case we were passed an hInstance */
-    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
+    if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
     lstrcpyn( lpFileName, NE_MODULE_NAME(pModule), nSize );
     dprintf_module( stddeb, "GetModuleFilename: %s\n", lpFileName );
     return strlen(lpFileName);
@@ -1486,9 +1536,8 @@
  */
 WORD GetExpWinVer( HMODULE hModule )
 {
-    NE_MODULE *pModule = (NE_MODULE *)GlobalLock( hModule );
-
-    return pModule->expected_version;
+    NE_MODULE *pModule = MODULE_GetPtr( hModule );
+    return pModule ? pModule->expected_version : 0;
 }
 
 
@@ -1510,7 +1559,7 @@
     NE_MODULE *pModule;
 
     if (!lpme->wNext) return FALSE;
-    if (!(pModule = (NE_MODULE *)GlobalLock( lpme->wNext ))) return FALSE;
+    if (!(pModule = MODULE_GetPtr( lpme->wNext ))) return FALSE;
     strncpy( lpme->szModule, (char *)pModule + pModule->name_table,
              MAX_MODULE_NAME );
     lpme->szModule[MAX_MODULE_NAME] = '\0';