Release 960705

Fri Jul  5 16:27:43 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [controls/desktop.c]
	Use Windows file I/O routines to load the desktop bitmap.

	* [files/file.c]
	Implemented RemoveDirectory* and DeleteFile*.

	* [include/wine.h]
	Added SIGCONTEXT typedef to replace #define sigcontext_struct.

	* [loader/task.c]
	Fixed initial breakpoint setting for Win32 tasks.

	* [misc/wsprintf.c]
	Ignore Unicode formats for wsprintf16().

	* [objects/font.c]
	Implemented Win32 version of GetTextMetrics.

	* [windows/winproc.c] [windows/win.c] [windows/class.c]
	  [windows/dialog.c]
	Modified windows procedures to use thunks, to ensure that the
	procedure can be called directly from the Windows program.

	* [windows/win.c]
	Added function WIN_BuildWinArray() to make it easier to enumerate
	windows. Implemented Win32 version of EnumWindows() and friends.

Fri Jul  5 11:56:22 1996  Andreas Kirschbaum <ank@rbg.informatik.th-darmstadt.de>

	* [controls/button.c] [windows/win.c]
	Operator precedence fixes.

	* [controls/edit.c]
	Implemented ES_PASSWORD, ES_LOWERCASE and ES_UPPERCASE styles.
	Fixed word wrap with long words.

	* [debugger/debug.l]
	New alias "where" for command "backtrace".

	* [if1632/gdi.spec]
	Corrected parameter of ExtTextOut.

	* [loader/module.c]
	Corrected printing of table of modules.

	* [misc/spy.c]
	Removed superfluous \n in message name.

	* [windows/message.c]
	Declared MSG_SendMessage as static.
	Changed parameter of DirectedYield() from queue handle to task handle.
	Removed warning mesages for argument of printf.

	* [windows/nonclient.c]
	Added the flag DT_NOPREFIX when drawing window titles.

	* [windows/win.c]
	WIN_WalkWindows now prints the invalid window handle.
	Added a warning if Get-/SetWindowWord/-Long gets an invalid offset.

	* [windows/winproc.c]
	Allows creating dialog windows with NULL as dialog function.

Wed Jul  3 09:26:41 1996  Andrew Lewycky <plewycky@oise.utoronto.ca>

	* [windows/event.c]
	EVENT_key: Fixes to VK_ code generation for space bar and
	punctuation.

	* [files/file.c]
	GetTempFileName: first character in temporary name is "~".

	* [memory/heap.c]
	HEAP_MakeInUseBlockFree now frees the whole subheap if possible.

	* [objects/text.c]
	ExtTextOut16(): handle NULL lpRect and ETO_OPAQUE.

	* [misc/driver.c]
	Removed some bugs and reformatted. Actually loads drivers now.

	* [include/callback.h]
	Added CallDriverProc() and CallWindowsExitProc().

	* [loader/module.c]
	MODULE_CallWEP(): new function.

	* [misc/lzexpand.c]
	LZSeek(): return new pointer, not old one.

	* [misc/ver.c]
	find_ne_resource(): fixed dependence on LZSeek() bug.
	GetFileResource(): initialize reslen before using it.

	* [windows/class.c]
	SetClassWord(): add missing else.

	* [objects/font.c]
	lpFontList is now MAX_FONTS+1. It used to overwrite the array.
	InitFontList: allocate one huge array of structures.
	FONT_MatchFont: uppercase the face name.

Thu Jun 27 12:41:40 1996  Bruce Milner <bruce@genetics.utah.edu>

	* [memory/heap.c]
	Fixed a typo in HeapReAlloc().

Tue Jun 25 22:22:03 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [files/directory.c] [files/drive.c] [if1632/kernel.spec]
	  [if1632/kernel32.spec] [if1632/shell.spec] [include/windows.h]
	GetTempPath* added
	GetDriveType* fixed, updated to NewNameStandard.
	GetCurrentDirectory* fixed (needs to prepend X:\).

	* [controls/listbox.c]
	Missing NULL check added.

	* [if1632/winmm.spec] [loader/builtin.c]
	winmm.dll (32bit mmsystem equivalent) specs added.

	* [memory/string.c] [if1632/kernel32.spec] [include/windows.h]
	Rtl{Move,Zero,Fill}Memory added.

	* [misc/registry.c]
	Some NULL ptr dereference bugs fixed.

	* [multimedia/mcicda.c][multimedia/mcistring.c][multimedia/mmsystem.c]
	Check for NULL ptr.
	Fill mciOpenDrv when mixing mciOpen and mciSendString("open ..").
	Aliasing should work for all MCI devices.

	* [windows/win.c]
	Allow passing invalid window handles to CloseWindow().

Tue Jun 25 20:02:15 1996  Jukka Iivonen <iivonen@cc.helsinki.fi>

	* [files/directory.c] [if1632/kernel32.spec]
	GetSystemDirectory32A and GetSystemDirectory32W added.

	* [misc/main.c] [if1632/kernel32.spec]
	Beep and SetEnvironmentVariable32W added.
diff --git a/loader/module.c b/loader/module.c
index d394aa3..c643c7d 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -30,8 +30,8 @@
 
 extern HINSTANCE PE_LoadModule( int fd, OFSTRUCT *ofs, LOADPARAMS* params );
 
-static HMODULE hFirstModule = 0;
-static HMODULE hCachedModule = 0;  /* Module cached by MODULE_OpenFile */
+static HMODULE16 hFirstModule = 0;
+static HMODULE16 hCachedModule = 0;  /* Module cached by MODULE_OpenFile */
 
 #ifndef WINELIB
 static HANDLE hInitialStack32 = 0;
@@ -41,7 +41,7 @@
 /***********************************************************************
  *           MODULE_GetPtr
  */
-NE_MODULE *MODULE_GetPtr( HMODULE hModule )
+NE_MODULE *MODULE_GetPtr( HMODULE16 hModule )
 {
     NE_MODULE *pModule = (NE_MODULE *)GlobalLock16( hModule );
     if (!pModule || (pModule->magic != NE_SIGNATURE) ||
@@ -53,7 +53,7 @@
 /***********************************************************************
  *           MODULE_DumpModule
  */
-void MODULE_DumpModule( HMODULE hmodule )
+void MODULE_DumpModule( HMODULE16 hmodule )
 {
     int i, ordinal;
     SEGTABLEENTRY *pSeg;
@@ -134,9 +134,8 @@
         pword = (WORD *)((BYTE *)pModule + pModule->modref_table);
         for (i = 0; i < pModule->modref_count; i++, pword++)
         {
-            char *name = (char *)pModule + pModule->import_table + *pword;
-            printf( "%d: %04x -> '%*.*s'\n",
-                    i, *pword, *name, *name, name + 1 );
+	    printf( "%d: %04x -> '%s'\n", i, *pword,
+		    MODULE_GetModuleName(*pword));
         }
     }
     else printf( "None\n" );
@@ -217,7 +216,7 @@
 /***********************************************************************
  *           MODULE_OpenFile
  */
-int MODULE_OpenFile( HMODULE hModule )
+int MODULE_OpenFile( HMODULE16 hModule )
 {
     NE_MODULE *pModule;
     char *name;
@@ -288,7 +287,7 @@
  *           MODULE_CreateSegments
  */
 #ifndef WINELIB32
-static BOOL MODULE_CreateSegments( HMODULE hModule )
+static BOOL MODULE_CreateSegments( HMODULE16 hModule )
 {
     SEGTABLEENTRY *pSegment;
     NE_MODULE *pModule;
@@ -321,7 +320,7 @@
  *           MODULE_GetInstance
  */
 #ifndef WINELIB32
-HINSTANCE MODULE_GetInstance( HMODULE hModule )
+HINSTANCE16 MODULE_GetInstance( HMODULE16 hModule )
 {
     SEGTABLEENTRY *pSegment;
     NE_MODULE *pModule;
@@ -339,7 +338,7 @@
 /***********************************************************************
  *           MODULE_CreateInstance
  */
-HINSTANCE MODULE_CreateInstance( HMODULE hModule, LOADPARAMS *params )
+HINSTANCE16 MODULE_CreateInstance( HMODULE16 hModule, LOADPARAMS *params )
 {
     SEGTABLEENTRY *pSegment;
     NE_MODULE *pModule;
@@ -373,12 +372,12 @@
 /***********************************************************************
  *           MODULE_LoadExeHeader
  */
-static HMODULE MODULE_LoadExeHeader( HFILE hFile, OFSTRUCT *ofs )
+static HMODULE16 MODULE_LoadExeHeader( HFILE hFile, OFSTRUCT *ofs )
 {
     struct mz_header_s mz_header;
     struct ne_header_s ne_header;
     int size;
-    HMODULE hModule;
+    HMODULE16 hModule;
     NE_MODULE *pModule;
     BYTE *pData;
     char *buffer, *fastload = NULL;
@@ -394,14 +393,15 @@
 
     _llseek( hFile, 0, SEEK_SET );
     if ((FILE_Read(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
-        (mz_header.mz_magic != MZ_SIGNATURE)) return (HMODULE)11;  /* invalid exe */
+        (mz_header.mz_magic != MZ_SIGNATURE))
+        return (HMODULE16)11;  /* invalid exe */
 
     _llseek( hFile, mz_header.ne_offset, SEEK_SET );
     if (FILE_Read( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
-        return (HMODULE)11;  /* invalid exe */
+        return (HMODULE16)11;  /* invalid exe */
 
-    if (ne_header.ne_magic == PE_SIGNATURE) return (HMODULE)21;  /* win32 exe */
-    if (ne_header.ne_magic != NE_SIGNATURE) return (HMODULE)11;  /* invalid exe */
+    if (ne_header.ne_magic == PE_SIGNATURE) return (HMODULE16)21;  /* win32 exe */
+    if (ne_header.ne_magic != NE_SIGNATURE) return (HMODULE16)11;  /* invalid exe */
 
     /* We now have a valid NE header */
 
@@ -422,7 +422,7 @@
            ne_header.entry_tab_length;
 
     hModule = GlobalAlloc16( GMEM_MOVEABLE | GMEM_ZEROINIT, size );
-    if (!hModule) return (HMODULE)11;  /* invalid exe */
+    if (!hModule) return (HMODULE16)11;  /* invalid exe */
     FarSetOwner( hModule, hModule );
     pModule = (NE_MODULE *)GlobalLock16( hModule );
     memcpy( pModule, &ne_header, sizeof(ne_header) );
@@ -474,7 +474,7 @@
 
         if (!READ( ne_header.segment_tab_offset,
              ne_header.n_segment_tab * sizeof(struct ne_segment_table_entry_s),
-             buffer )) return (HMODULE)11;  /* invalid exe */
+             buffer )) return (HMODULE16)11;  /* invalid exe */
         pSeg = (struct ne_segment_table_entry_s *)buffer;
         for (i = ne_header.n_segment_tab; i > 0; i--, pSeg++)
         {
@@ -486,7 +486,7 @@
     else
     {
         GlobalFree16( hModule );
-        return (HMODULE)11;  /* invalid exe */
+        return (HMODULE16)11;  /* invalid exe */
     }
 
     /* Get the resource table */
@@ -496,7 +496,7 @@
         pModule->res_table = (int)pData - (int)pModule;
         if (!READ(ne_header.resource_tab_offset,
                   ne_header.rname_tab_offset - ne_header.resource_tab_offset,
-                  pData )) return (HMODULE)11;  /* invalid exe */
+                  pData )) return (HMODULE16)11;  /* invalid exe */
         pData += ne_header.rname_tab_offset - ne_header.resource_tab_offset;
     }
     else pModule->res_table = 0;  /* No resource table */
@@ -509,7 +509,7 @@
                pData ))
     {
         GlobalFree16( hModule );
-        return (HMODULE)11;  /* invalid exe */
+        return (HMODULE16)11;  /* invalid exe */
     }
     pData += ne_header.moduleref_tab_offset - ne_header.rname_tab_offset;
 
@@ -520,7 +520,7 @@
         pModule->modref_table = (int)pData - (int)pModule;
         if (!READ( ne_header.moduleref_tab_offset,
                   ne_header.n_mod_ref_tab * sizeof(WORD),
-                  pData )) return (HMODULE)11;  /* invalid exe */
+                  pData )) return (HMODULE16)11;  /* invalid exe */
         pData += ne_header.n_mod_ref_tab * sizeof(WORD);
     }
     else pModule->modref_table = 0;  /* No module references */
@@ -533,7 +533,7 @@
                pData ))
     {
         GlobalFree16( hModule );
-        return (HMODULE)11;  /* invalid exe */
+        return (HMODULE16)11;  /* invalid exe */
     }
     pData += ne_header.entry_tab_offset - ne_header.iname_tab_offset;
 
@@ -545,7 +545,7 @@
                pData ))
     {
         GlobalFree16( hModule );
-        return (HMODULE)11;  /* invalid exe */
+        return (HMODULE16)11;  /* invalid exe */
     }
     pData += ne_header.entry_tab_length;
 
@@ -558,7 +558,7 @@
         if (!pModule->nrname_handle)
         {
             GlobalFree16( hModule );
-            return (HMODULE)11;  /* invalid exe */
+            return (HMODULE16)11;  /* invalid exe */
         }
         buffer = GlobalLock16( pModule->nrname_handle );
         _llseek( hFile, ne_header.nrname_tab_offset, SEEK_SET );
@@ -567,7 +567,7 @@
         {
             GlobalFree16( pModule->nrname_handle );
             GlobalFree16( hModule );
-            return (HMODULE)11;  /* invalid exe */
+            return (HMODULE16)11;  /* invalid exe */
         }
     }
     else pModule->nrname_handle = 0;
@@ -577,13 +577,13 @@
     if (pModule->modref_count)
     {
         pModule->dlls_to_init = GLOBAL_Alloc(GMEM_ZEROINIT,
-                                    (pModule->modref_count+1)*sizeof(HMODULE),
+                                    (pModule->modref_count+1)*sizeof(HMODULE16),
                                     hModule, FALSE, FALSE, FALSE );
         if (!pModule->dlls_to_init)
         {
             if (pModule->nrname_handle) GlobalFree16( pModule->nrname_handle );
             GlobalFree16( hModule );
-            return (HMODULE)11;  /* invalid exe */
+            return (HMODULE16)11;  /* invalid exe */
         }
     }
     else pModule->dlls_to_init = 0;
@@ -599,7 +599,7 @@
  *
  * Lookup the ordinal for a given name.
  */
-WORD MODULE_GetOrdinal( HMODULE hModule, const char *name )
+WORD MODULE_GetOrdinal( HMODULE16 hModule, const char *name )
 {
     char buffer[256], *cpnt;
     BYTE len;
@@ -663,7 +663,7 @@
  *
  * Return the entry point for a given ordinal.
  */
-SEGPTR MODULE_GetEntryPoint( HMODULE hModule, WORD ordinal )
+SEGPTR MODULE_GetEntryPoint( HMODULE16 hModule, WORD ordinal )
 {
     NE_MODULE *pModule;
     WORD curOrdinal = 1;
@@ -714,7 +714,7 @@
  * Change the value of an entry point. Use with caution!
  * It can only change the offset value, not the selector.
  */
-BOOL MODULE_SetEntryPoint( HMODULE hModule, WORD ordinal, WORD offset )
+BOOL16 MODULE_SetEntryPoint( HMODULE16 hModule, WORD ordinal, WORD offset )
 {
     NE_MODULE *pModule;
     WORD curOrdinal = 1;
@@ -763,7 +763,7 @@
 {
     WORD ordinal;
     FARPROC16 ret;
-    static HMODULE hModule = 0;
+    static HMODULE16 hModule = 0;
 
     if (!hModule) hModule = GetModuleHandle( "WPROCS" );
     ordinal = MODULE_GetOrdinal( hModule, name );
@@ -777,7 +777,7 @@
 /***********************************************************************
  *           MODULE_GetModuleName
  */
-LPSTR MODULE_GetModuleName( HMODULE hModule )
+LPSTR MODULE_GetModuleName( HMODULE16 hModule )
 {
     NE_MODULE *pModule;
     BYTE *p, len;
@@ -807,9 +807,9 @@
  *
  * Find a module from a path name.
  */
-HMODULE MODULE_FindModule( LPCSTR path )
+HMODULE16 MODULE_FindModule( LPCSTR path )
 {
-    HMODULE hModule = hFirstModule;
+    HMODULE16 hModule = hFirstModule;
     LPCSTR filename, dotptr, modulepath, modulename;
     BYTE len, *name_table;
 
@@ -839,23 +839,44 @@
 
 
 /**********************************************************************
+ *	    MODULE_CallWEP
+ *
+ * Call a DLL's WEP, allowing it to shut down.
+ * FIXME: we always pass the WEP WEP_FREE_DLL, never WEP_SYSTEM_EXIT
+ */
+static BOOL16 MODULE_CallWEP( HMODULE16 hModule )
+{
+    FARPROC16 WEP = (FARPROC16)0;
+    WORD ordinal = MODULE_GetOrdinal( hModule, "WEP" );
+
+    if (ordinal) WEP = MODULE_GetEntryPoint( hModule, ordinal );
+    if (!WEP)
+    {
+	dprintf_module( stddeb, "module %04x doesn't have a WEP\n", hModule );
+	return FALSE;
+    }
+    return CallWindowsExitProc( WEP, WEP_FREE_DLL );
+}
+
+
+/**********************************************************************
  *	    MODULE_FreeModule
  *
  * Remove a module from memory.
  */
-static void MODULE_FreeModule( HMODULE hModule )
+static void MODULE_FreeModule( HMODULE16 hModule )
 {
-    HMODULE *hPrevModule;
+    HMODULE16 *hPrevModule;
     NE_MODULE *pModule;
     SEGTABLEENTRY *pSegment;
-    HMODULE *pModRef;
+    HMODULE16 *pModRef;
     int i;
 
     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 */
+    if (pModule->flags & NE_FFLAGS_LIBMODULE) MODULE_CallWEP( hModule );
 
     /* Free the objects owned by the module */
 
@@ -885,10 +906,10 @@
 
       /* Free the referenced modules */
 
-    pModRef = (HMODULE*)NE_MODULE_TABLE( pModule );
+    pModRef = (HMODULE16*)NE_MODULE_TABLE( pModule );
     for (i = 0; i < pModule->modref_count; i++, pModRef++)
     {
-        FreeModule( *pModRef );
+        FreeModule16( *pModRef );
     }
 
       /* Free the module storage */
@@ -908,7 +929,7 @@
  */
 HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock )
 {
-    HMODULE hModule;
+    HMODULE16 hModule;
     HANDLE hInstance, hPrevInstance;
     NE_MODULE *pModule;
     LOADPARAMS *params = (LOADPARAMS *)paramBlock;
@@ -977,7 +998,7 @@
             {
                 /* If the DLL is not loaded yet, load it and store */
                 /* its handle in the list of DLLs to initialize.   */
-                HMODULE hDLL;
+                HMODULE16 hDLL;
 
                 if ((hDLL = LoadModule( buffer, (LPVOID)-1 )) == 2)  /* file not found */
                 {
@@ -1015,7 +1036,7 @@
 		SEGTABLEENTRY * pSegTable = (SEGTABLEENTRY *) NE_SEG_TABLE(pModule);
 		SELFLOADHEADER *selfloadheader;
                 STACK16FRAME *stack16Top;
-		HMODULE hselfload = GetModuleHandle("WPROCS");
+		HMODULE16 hselfload = GetModuleHandle("WPROCS");
 		WORD oldss, oldsp, saved_dgroup = pSegTable[pModule->dgroup - 1].selector;
 		fprintf (stderr, "Warning:  %*.*s is a self-loading module\n"
                                 "Support for self-loading modules is very experimental\n",
@@ -1138,16 +1159,16 @@
 
 
 /**********************************************************************
- *	    FreeModule    (KERNEL.46)
+ *	    FreeModule16    (KERNEL.46)
  */
-BOOL FreeModule( HANDLE hModule )
+BOOL16 FreeModule16( HMODULE16 hModule )
 {
     NE_MODULE *pModule;
 
     hModule = GetExePtr( hModule );  /* In case we were passed an hInstance */
     if (!(pModule = MODULE_GetPtr( hModule ))) return FALSE;
 
-    dprintf_module( stddeb, "FreeModule: %s count %d\n", 
+    dprintf_module( stddeb, "FreeModule16: %s count %d\n", 
 		    MODULE_GetModuleName(hModule), pModule->count );
     if (--pModule->count == 0) MODULE_FreeModule( hModule );
     return TRUE;
@@ -1157,13 +1178,13 @@
 /**********************************************************************
  *	    GetModuleHandle    (KERNEL.47)
  */
-HMODULE WIN16_GetModuleHandle( SEGPTR name )
+HMODULE16 WIN16_GetModuleHandle( SEGPTR name )
 {
     if (HIWORD(name) == 0) return GetExePtr( (HANDLE)name );
     return MODULE_FindModule( PTR_SEG_TO_LIN(name) );
 }
 
-HMODULE GetModuleHandle( LPCSTR name )
+HMODULE16 GetModuleHandle( LPCSTR name )
 {
     return MODULE_FindModule( name );
 }
@@ -1237,7 +1258,7 @@
 void FreeLibrary( HANDLE handle )
 {
     dprintf_module( stddeb,"FreeLibrary: %04x\n", handle );
-    FreeModule( handle );
+    FreeModule16( handle );
 }
 
 
@@ -1416,7 +1437,7 @@
 /**********************************************************************
  *	    GetExpWinVer    (KERNEL.167)
  */
-WORD GetExpWinVer( HMODULE hModule )
+WORD GetExpWinVer( HMODULE16 hModule )
 {
     NE_MODULE *pModule = MODULE_GetPtr( hModule );
     return pModule ? pModule->expected_version : 0;
@@ -1426,7 +1447,7 @@
 /**********************************************************************
  *	    ModuleFirst    (TOOLHELP.59)
  */
-BOOL ModuleFirst( MODULEENTRY *lpme )
+BOOL16 ModuleFirst( MODULEENTRY *lpme )
 {
     lpme->wNext = hFirstModule;
     return ModuleNext( lpme );
@@ -1436,7 +1457,7 @@
 /**********************************************************************
  *	    ModuleNext    (TOOLHELP.60)
  */
-BOOL ModuleNext( MODULEENTRY *lpme )
+BOOL16 ModuleNext( MODULEENTRY *lpme )
 {
     NE_MODULE *pModule;
 
@@ -1457,7 +1478,7 @@
 /**********************************************************************
  *	    ModuleFindName    (TOOLHELP.61)
  */
-BOOL ModuleFindName( MODULEENTRY *lpme, LPCSTR name )
+BOOL16 ModuleFindName( MODULEENTRY *lpme, LPCSTR name )
 {
     lpme->wNext = GetModuleHandle( name );
     return ModuleNext( lpme );
@@ -1467,7 +1488,7 @@
 /**********************************************************************
  *	    ModuleFindHandle    (TOOLHELP.62)
  */
-BOOL ModuleFindHandle( MODULEENTRY *lpme, HMODULE hModule )
+BOOL16 ModuleFindHandle( MODULEENTRY *lpme, HMODULE16 hModule )
 {
     hModule = GetExePtr( hModule );  /* In case we were passed an hInstance */
     lpme->wNext = hModule;