Release 970509

Tue May  6 19:12:20 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [loader/task.c] [loader/module.c]
	Fixed command line in LoadModule to already include the length
	indicator (thanks to Andreas Mohr).

	* [windows/dialog.c]
	DlgDirList: fixed behavior with DDL_DRIVES | DDL_EXCLUSIVE (thanks
	to Bruce Milner for this one); correctly update file spec on exit.

	* [windows/winproc.c] [if1632/thunk.c] [include/callback.h]
	Moved emulator-specific code for calling window procedure to
	thunk.c.

Mon Apr 28 10:21:59 1997  Huw D M Davies <h.davies1@physics.oxford.ac.uk>

	* [memory/local.c]
	Better implementation of moveable blocks (first word in block is
	the handle itself) and discarded blocks. Local(Re)Alloc is much
	more like the real thing.

Thu Apr 24 19:50:19 1997  Albrecht Kleine <kleine@ak.sax.de>

	* [objects/metafile.c]
	Added handling of meta record META_DIBCREATEPATTERNBRUSH.

Mon Apr 21 14:03:32 1997  Alex Korobka <alex@trantor.pharm.sunysb.edu>

	* [multimedia/mmsystem.c] [multimedia/audio.c]
	Fixed leftover problems with masked device IDs.

	* [msdos/int21.c]
	Removed code duplications, fixed Write.

	* [windows/event.c] [windows/dce.c] [windows/nonclient.c]
	  [windows/winpos.c]
	Yet another attempt to make -managed work better.

	* [controls/combo.c]
	UI fix.

Mon Apr 21 13:10:24 1997  Marcus Meissner <msmeissn@immd4.informatik.uni-erlangen.de>

	* [debugger/*]
	All "Loading from ..." lines merged into one so important
	information before the crash doesn't scroll out.

	* [if1632/kernel.spec]
	Added some ordinal stubs used by win95 OLE and friends.

	* [win32/process.c] [if1632/kernel.spec] [loader/module.c]
	MsgWaitForMultipleObjects,GetProcessTimes,RtlImageNtHeaders,
 	LoadLibraryEx32W and GetProcAddress32W added.

	* [objects/bitmap.c]
	XImages use another memory layout for depth 4 (and poss. other
 	depths) then Windows bitmaps. Replaced speedup hack by generic
 	(and better working) code.

	* [objects/dib.c]
	Another ximage!=bitmap memory layout bug. 
	All _XinitImageFuncPtrs except one removed.

Sun Apr 20 17:12:30 1997  Andrew Taylor <andrew@riscan.com>

	* [multimedia/audio.c]
	Fixed some regression bugs.

Sun Apr 20 12:15:09 1997  Andreas Mohr <100.30936@germany.net>

	* [loader/module.c]
	Fixed MODULE_LoadExeHeader() to use the correct offset for
	fast-load area.

Sat Apr 19 16:40:00 1997  Chad Fraleigh <chadf@bookcase.com>

	* [controls/*] [debugger/*] [graphics/win16drv/*] [loader/*] [misc/*]
	  [win32/*]
	Removed <malloc.h> and added <stdlib.h> where needed.
	Changed printf formaters to match argument types (%lx instead of %x).
	Casted some types to make the compiler happy. Mostly pointer<->ulong.

	* [graphics/win16drv/init.c]
	Fixed uninitialized variable.

	* [include/msdos.h]
	Added <sys/types.h> needed for <dirent.h>.

	* [include/sigcontext.h]
	Combined a common NetBSD & FreeBSD #ifdef, and added in OpenBSD.
	Casted EIP_sig/ESP_sig to be unsigned long (declared as 'int' in *BSD).

	* [misc/crtdll.c] [misc/lstr.c]
	Casted last argument in v*printf() to be va_list. This code seems to
	make BIG assumptions about the implementation of va_list.

	* [misc/ver.c]
	Fixed impossible if() expression (unsigned < 0).

	* [misc/winsock.c]
	Removed semicolon on the end of an if() statement.

	* [windows/mdi.c]
	Changed a counter/index to unsigned since it was complaining about
	signed/unsigned comparison and didn't need to be negative.

Wed Apr 16 17:43:19 1997 Georg Beyerle <gbeyerle@awi-potsdam.de>

	* [scheduler/thread.c]
	Minor fix in thread database initialization.

Wed Apr 16 17:28:05 1997  Andreas Mohr <100.30936@germany.net>

	* [files/file.c]
	Fixed FILE_FillInfo() to omit the archive flag when handling a DOS
	directory entry.
diff --git a/ANNOUNCE b/ANNOUNCE
index 0642a55..2b89c81 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,13 +1,13 @@
-This is release 970415 of Wine, the MS Windows emulator.  This is still a
+This is release 970509 of Wine, the MS Windows emulator.  This is still a
 developer's only release.  There are many bugs and many unimplemented API
 features.  Most applications still do not work correctly.
 
 Patches should be submitted to "julliard@lrc.epfl.ch".  Please don't
 forget to include a ChangeLog entry.
 
-WHAT'S NEW with Wine-970415: (see ChangeLog for details)
-	- Edit control improvements.
-	- Some files moved around.
+WHAT'S NEW with Wine-970509: (see ChangeLog for details)
+	- Better local heap implementation.
+	- Improvements to -managed mode.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -16,11 +16,11 @@
 the release is available at the ftp sites.  The sources will be available
 from the following locations:
 
-  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-970415.tar.gz
-  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-970415.tar.gz
-  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-970415.tar.gz
-  ftp://aris.com/pub/linux/ALPHA/Wine/development/Wine-970415.tar.gz
-  ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-970415.tar.gz
+  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-970509.tar.gz
+  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-970509.tar.gz
+  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-970509.tar.gz
+  ftp://aris.com/pub/linux/ALPHA/Wine/development/Wine-970509.tar.gz
+  ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-970509.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/ChangeLog b/ChangeLog
index dde65a7..45d2aef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,122 @@
 ----------------------------------------------------------------------
+Tue May  6 19:12:20 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>
+
+	* [loader/task.c] [loader/module.c]
+	Fixed command line in LoadModule to already include the length
+	indicator (thanks to Andreas Mohr).
+
+	* [windows/dialog.c]
+	DlgDirList: fixed behavior with DDL_DRIVES | DDL_EXCLUSIVE (thanks
+	to Bruce Milner for this one); correctly update file spec on exit.
+
+	* [windows/winproc.c] [if1632/thunk.c] [include/callback.h]
+	Moved emulator-specific code for calling window procedure to
+	thunk.c.
+
+Mon Apr 28 10:21:59 1997  Huw D M Davies <h.davies1@physics.oxford.ac.uk>
+
+	* [memory/local.c]
+	Better implementation of moveable blocks (first word in block is
+	the handle itself) and discarded blocks. Local(Re)Alloc is much
+	more like the real thing.
+
+Thu Apr 24 19:50:19 1997  Albrecht Kleine <kleine@ak.sax.de>
+
+	* [objects/metafile.c]
+	Added handling of meta record META_DIBCREATEPATTERNBRUSH.
+
+Mon Apr 21 14:03:32 1997  Alex Korobka <alex@trantor.pharm.sunysb.edu>
+
+	* [multimedia/mmsystem.c] [multimedia/audio.c]
+	Fixed leftover problems with masked device IDs.
+
+	* [msdos/int21.c]
+	Removed code duplications, fixed Write.
+
+	* [windows/event.c] [windows/dce.c] [windows/nonclient.c]
+	  [windows/winpos.c]
+	Yet another attempt to make -managed work better.
+
+	* [controls/combo.c]
+	UI fix.
+
+Mon Apr 21 13:10:24 1997  Marcus Meissner <msmeissn@immd4.informatik.uni-erlangen.de>
+
+	* [debugger/*]
+	All "Loading from ..." lines merged into one so important
+	information before the crash doesn't scroll out.
+
+	* [if1632/kernel.spec]
+	Added some ordinal stubs used by win95 OLE and friends.
+
+	* [win32/process.c] [if1632/kernel.spec] [loader/module.c]
+	MsgWaitForMultipleObjects,GetProcessTimes,RtlImageNtHeaders,
+ 	LoadLibraryEx32W and GetProcAddress32W added.
+
+	* [objects/bitmap.c]
+	XImages use another memory layout for depth 4 (and poss. other
+ 	depths) then Windows bitmaps. Replaced speedup hack by generic
+ 	(and better working) code.
+
+	* [objects/dib.c]
+	Another ximage!=bitmap memory layout bug. 
+	All _XinitImageFuncPtrs except one removed.
+
+Sun Apr 20 17:12:30 1997  Andrew Taylor <andrew@riscan.com>
+
+	* [multimedia/audio.c]
+	Fixed some regression bugs.
+
+Sun Apr 20 12:15:09 1997  Andreas Mohr <100.30936@germany.net>
+
+	* [loader/module.c]
+	Fixed MODULE_LoadExeHeader() to use the correct offset for
+	fast-load area.
+
+Sat Apr 19 16:40:00 1997  Chad Fraleigh <chadf@bookcase.com>
+
+	* [controls/*] [debugger/*] [graphics/win16drv/*] [loader/*] [misc/*]
+	  [win32/*]
+	Removed <malloc.h> and added <stdlib.h> where needed.
+	Changed printf formaters to match argument types (%lx instead of %x).
+	Casted some types to make the compiler happy. Mostly pointer<->ulong.
+
+	* [graphics/win16drv/init.c]
+	Fixed uninitialized variable.
+
+	* [include/msdos.h]
+	Added <sys/types.h> needed for <dirent.h>.
+
+	* [include/sigcontext.h]
+	Combined a common NetBSD & FreeBSD #ifdef, and added in OpenBSD.
+	Casted EIP_sig/ESP_sig to be unsigned long (declared as 'int' in *BSD).
+
+	* [misc/crtdll.c] [misc/lstr.c]
+	Casted last argument in v*printf() to be va_list. This code seems to
+	make BIG assumptions about the implementation of va_list.
+
+	* [misc/ver.c]
+	Fixed impossible if() expression (unsigned < 0).
+
+	* [misc/winsock.c]
+	Removed semicolon on the end of an if() statement.
+
+	* [windows/mdi.c]
+	Changed a counter/index to unsigned since it was complaining about
+	signed/unsigned comparison and didn't need to be negative.
+
+Wed Apr 16 17:43:19 1997 Georg Beyerle <gbeyerle@awi-potsdam.de>
+
+	* [scheduler/thread.c]
+	Minor fix in thread database initialization.
+
+Wed Apr 16 17:28:05 1997  Andreas Mohr <100.30936@germany.net>
+
+	* [files/file.c]
+	Fixed FILE_FillInfo() to omit the archive flag when handling a DOS
+	directory entry.
+
+----------------------------------------------------------------------
 Mon Apr 14 11:22:54 1997  John Harvey <john@division.co.uk>
 
 	* [graphics/win16drv/init.c]
diff --git a/Makefile.in b/Makefile.in
index f861a0a..afb9edd 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -111,7 +111,7 @@
 
 install_wine: dummy
 	$(INSTALL_PROGRAM) wine $(bindir)/wine
-	$(INSTALL_DATA) wine.man $(mandir)/wine$(manext)
+	$(INSTALL_DATA) $(TOPSRC)/wine.man $(mandir)/wine$(manext)
 
 libwine.a: $(COMMONSUBDIRS) $(LIBSUBDIRS) dummy
 	$(RM) $@
@@ -139,7 +139,7 @@
 	done
 
 etags:
-	etags `find . -name '*.[chS]' -print`
+	etags `find . -name '*.[chS]' -print | grep -v dbgmain`
 
 clean:
 	for i in $(ALLSUBDIRS); do (cd $$i; $(MAKE) clean) || exit 1; done
diff --git a/controls/combo.c b/controls/combo.c
index 7bfb68d..cd1a6b5 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -395,26 +395,26 @@
  */
 static void CBPaintText(LPHEADCOMBO lphc, HDC16 hdc)
 {
-   INT32	id, size;
+   INT32	id, size = 0;
    LPSTR	pText = NULL;
 
    /* follow Windows combobox that sends a bunch of text 
-    * inquiries to its listbox while processing WM_PAINT.
-    */
+    * inquiries to its listbox while processing WM_PAINT. */
 
-   size = SendMessage32A( lphc->hWndLBox, LB_GETTEXTLEN32,
-	 	(id = SendMessage32A(lphc->hWndLBox, LB_GETCURSEL32, 0, 0)), 0);
-
-   if( !(pText = HeapAlloc( GetProcessHeap(), 0, size + 1)) ) return;
-
-   SendMessage32A( lphc->hWndLBox, LB_GETTEXT32, (WPARAM32)id, (LPARAM)pText );
-   pText[size] = '\0';	/* just in case */
+   if( (id = SendMessage32A(lphc->hWndLBox, LB_GETCURSEL32, 0, 0) ) != LB_ERR )
+   {
+        size = SendMessage32A( lphc->hWndLBox, LB_GETTEXTLEN32, id, 0);
+        if( (pText = HeapAlloc( GetProcessHeap(), 0, size + 1)) )
+	{
+	    SendMessage32A( lphc->hWndLBox, LB_GETTEXT32, (WPARAM32)id, (LPARAM)pText );
+	    pText[size] = '\0';	/* just in case */
+	} else return;
+   }
 
    if( lphc->wState & CBF_EDIT )
    {
-	if( CB_HASSTRINGS(lphc) )
-	    SetWindowText32A( lphc->hWndEdit, (pText) ? pText : "" );
-	if( lphc->wState & CBF_FOCUSED )
+	if( CB_HASSTRINGS(lphc) ) SetWindowText32A( lphc->hWndEdit, pText );
+	if( lphc->wState & CBF_FOCUSED ) 
 	    SendMessage32A( lphc->hWndEdit, EM_SETSEL32, 0, (LPARAM)(-1));
    }
    else /* paint text field ourselves */
@@ -478,8 +478,9 @@
 	    else
 	    {
 		ExtTextOut32A( hDC, rect.left + 1, rect.top + 1,
-			       ETO_OPAQUE | ETO_CLIPPED, &rect, pText, size, NULL );
-		if( lphc->wState & CBF_FOCUSED && !(lphc->wState & CBF_DROPPED) )
+                               ETO_OPAQUE | ETO_CLIPPED, &rect,
+                               (pText) ? pText : "" , size, NULL );
+		if(lphc->wState & CBF_FOCUSED && !(lphc->wState & CBF_DROPPED))
 		    DrawFocusRect32( hDC, &rect );
 	    }
 
@@ -957,7 +958,7 @@
    /* get it from the listbox */
 
    idx = SendMessage32A( lphc->hWndLBox, LB_GETCURSEL32, 0, 0 );
-   if( idx >= 0 )
+   if( idx != LB_ERR )
    {
        LPSTR        lpBuffer;
        INT32	    length = SendMessage32A( lphc->hWndLBox, LB_GETTEXTLEN32,
diff --git a/controls/menu.c b/controls/menu.c
index 6dda2f3..f266e8f 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -2365,7 +2365,7 @@
     LPPOPUPMENU	menu;
 
     if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) return -1;
-    if ((nPos < 0) || (nPos >= menu->nItems)) return -1;
+    if ((nPos < 0) || ((UINT16) nPos >= menu->nItems)) return -1;
     if (menu->items[nPos].item_flags & MF_POPUP) return -1;
     return menu->items[nPos].item_id;
 }
diff --git a/debugger/dbg.y b/debugger/dbg.y
index a4ca4f3..b913c70 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -433,6 +433,7 @@
 	 * don't grok that yet, and in this case we fall back to using
 	 * the wine.sym file.
 	 */
+	fprintf(stderr,"Loading symbols: ");
 	if( DEBUG_ReadExecutableDbgInfo() == FALSE )
         {
 	    PROFILE_GetWineIniString( "wine", "SymbolTableFile", "wine.sym",
@@ -447,6 +448,7 @@
 	DEBUG_ProcessDeferredDebug();
 
         DEBUG_LoadEntryPoints();
+	fprintf(stderr,"\n");
     }
 
 #if 0
diff --git a/debugger/hash.c b/debugger/hash.c
index ab63c4a..610785f 100644
--- a/debugger/hash.c
+++ b/debugger/hash.c
@@ -755,8 +755,7 @@
 
         name = (unsigned char *)pModule + pModule->name_table;
 
-        fprintf( stderr, "Loading symbols from Win16 module %.*s...\n",
-                 *name, name + 1 );
+        fprintf( stderr, " %.*s",*name, name + 1 );
 
         /* First search the resident names */
 
diff --git a/debugger/msc.c b/debugger/msc.c
index 844e642..3668877 100644
--- a/debugger/msc.c
+++ b/debugger/msc.c
@@ -24,7 +24,6 @@
 #include <limits.h>
 #include <string.h>
 #include <unistd.h>
-#include <malloc.h>
 #ifndef PATH_MAX
 #define PATH_MAX _MAX_PATH
 #endif
@@ -2324,8 +2323,7 @@
 
       if( last_proc != deefer->dbg_index )
 	{
-	  fprintf(stderr, "Loading symbols from Win32 file %s...\n", 
-		  deefer->module_name);
+	  fprintf(stderr, " %s",deefer->module_name);
 	  last_proc = deefer->dbg_index;
 	}
 
diff --git a/debugger/source.c b/debugger/source.c
index 2e3f073..56b686a 100644
--- a/debugger/source.c
+++ b/debugger/source.c
@@ -15,7 +15,6 @@
 #include <limits.h>
 #include <string.h>
 #include <unistd.h>
-#include <malloc.h>
 #ifndef PATH_MAX
 #define PATH_MAX _MAX_PATH
 #endif
diff --git a/debugger/stabs.c b/debugger/stabs.c
index 83e99bf..dcdeaeb 100644
--- a/debugger/stabs.c
+++ b/debugger/stabs.c
@@ -1110,8 +1110,9 @@
 
   /*
    * Give a nice status message here...
+   * Well not, just print the name.
    */
-  fprintf(stderr, "Loading symbols from ELF file %s...\n", filename);
+  fprintf(stderr, " %s", filename);
 
   /*
    * Next, we need to find a few of the internal ELF headers within
@@ -1359,7 +1360,7 @@
   /*
    * Give a nice status message here...
    */
-  fprintf(stderr, "Loading symbols from a.out file %s...\n", exe_name);
+  fprintf(stderr, " %s", exe_name);
 
   rtn = TRUE;
 
diff --git a/debugger/stack.c b/debugger/stack.c
index 8c668ad..ca2bcc7 100644
--- a/debugger/stack.c
+++ b/debugger/stack.c
@@ -6,7 +6,7 @@
  */
 
 #include <stdio.h>
-#include <malloc.h>
+#include <stdlib.h>
 #include "xmalloc.h"
 #include "windows.h"
 #include "debugger.h"
diff --git a/debugger/types.c b/debugger/types.c
index 1bbc6ed..137b662 100644
--- a/debugger/types.c
+++ b/debugger/types.c
@@ -17,7 +17,6 @@
 #include <limits.h>
 #include <string.h>
 #include <unistd.h>
-#include <malloc.h>
 
 #include "win.h"
 #include "pe_image.h"
diff --git a/files/file.c b/files/file.c
index 47e02e8..641957f 100644
--- a/files/file.c
+++ b/files/file.c
@@ -309,9 +309,10 @@
  */
 static void FILE_FillInfo( struct stat *st, BY_HANDLE_FILE_INFORMATION *info )
 {
-    info->dwFileAttributes = FILE_ATTRIBUTE_ARCHIVE;
     if (S_ISDIR(st->st_mode))
-        info->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
+        info->dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
+    else
+        info->dwFileAttributes = FILE_ATTRIBUTE_ARCHIVE;
     if (!(st->st_mode & S_IWUSR))
         info->dwFileAttributes |= FILE_ATTRIBUTE_READONLY;
 
@@ -1168,6 +1169,9 @@
 
     if (!file)
     {
+	/* Linux EINVAL's on us if we don't pass MAP_PRIVATE to an anon mmap */
+	flags &= ~MAP_SHARED;
+	flags |= MAP_PRIVATE;
 #ifdef MAP_ANON
         flags |= MAP_ANON;
 #else
diff --git a/graphics/win16drv/font.c b/graphics/win16drv/font.c
index 09bc7aa..db761f1 100644
--- a/graphics/win16drv/font.c
+++ b/graphics/win16drv/font.c
@@ -39,7 +39,7 @@
 			      NULL, str, 
 			      -count,  physDev->segptrFontInfo, lpDrawMode, 
 			      lpTextXForm, NULL, NULL, 0);
-    printf("LPGDI_GetTextExtPoint: cx=0x%x, cy=0x%x Ret 0x%x\n", size->cx,size->cy,dwRet);
+    printf("LPGDI_GetTextExtPoint: cx=0x%x, cy=0x%x Ret 0x%lx\n", size->cx, size->cy, dwRet);
 
     return TRUE;
 }
diff --git a/graphics/win16drv/init.c b/graphics/win16drv/init.c
index f67c2a2..da9e60b 100644
--- a/graphics/win16drv/init.c
+++ b/graphics/win16drv/init.c
@@ -395,8 +395,8 @@
 	case 0x100:
 	  {
 	    LPEXTTEXTDATA textData =  PTR_SEG_TO_LIN(lpInData);
-	    printf("Got in data 0x%x textData 0x%x\n",lpInData, textData);
-	    printf("size %d in 0x%x:0x%x font 0x%x:0x%x xform 0x%x:0x%x drawm 0x%x:0x%x\n",
+	    printf("Got in data 0x%lx textData 0x%p\n",lpInData, textData);
+	    printf("size %d in 0x%p:0x%p font 0x%p:0x%p xform 0x%p:0x%p drawm 0x%p:0x%p\n",
 		   textData->nSize,
 		   textData->lpindata,PTR_SEG_TO_LIN(textData->lpindata),
 		   textData->lpFont,PTR_SEG_TO_LIN(textData->lpFont),
@@ -450,7 +450,7 @@
 ExtractPQ(HPQ hPQ) 
 { 
     struct hpq *queue, *prev, *current, *currentPrev;
-    int key, tag = -1;
+    int key = 0, tag = -1;
     currentPrev = prev = NULL;
     queue = current = hpqueue;
     if (current)
@@ -651,7 +651,7 @@
 
     dprintf_win16drv(stddeb, "WriteDialog: %04x %04x \"%s\"\n", hJob,  cchMsg, lpMsg);
 
-    nRet = MessageBox16(NULL, lpMsg, "Printing Error", MB_OKCANCEL);
+    nRet = MessageBox16(0, lpMsg, "Printing Error", MB_OKCANCEL);
     return nRet;
 }
 
diff --git a/if1632/comdlg32.spec b/if1632/comdlg32.spec
index 8ca5480..b6fa002 100644
--- a/if1632/comdlg32.spec
+++ b/if1632/comdlg32.spec
@@ -19,8 +19,8 @@
 0014 stub LoadAlterBitmap
 0015 stub PageSetupDlgA
 0016 stub PageSetupDlgW
-0017 stub PrintDlgA
-0018 stub PrintDlgW
+0017 return PrintDlgA 4 0
+0018 return PrintDlgW 4 0
 0019 stub ReplaceTextA
 0020 stub ReplaceTextW
 0021 stub WantArrows
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index 422e68e..3721737 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -73,8 +73,8 @@
 74  pascal16 OpenFile(ptr ptr word) OpenFile16
 75  stub OpenPathName
 76  stub DeletePathName
-#77 RESERVED1
-#78 RESERVED2
+77 stub KERNEL_77		#RESERVED1
+78 stub KERNEL_78 		#RESERVED2
 #79 RESERVED3
 #80 RESERVED4
 81  pascal16 _lclose(word) _lclose16
@@ -205,6 +205,12 @@
 205 stub CVWBreak
 206 pascal16 AllocSelectorArray(word) AllocSelectorArray
 207 pascal16 IsDBCSLeadByte(word) IsDBCSLeadByte16
+208 stub KERNEL_208
+209 stub KERNEL_209
+210 stub KERNEL_210
+211 stub KERNEL_211
+213 stub KERNEL_213
+214 stub KERNEL_214
 216 pascal   RegEnumKey(long long ptr long) RegEnumKey16
 217 pascal   RegOpenKey(long ptr ptr) RegOpenKey16
 218 pascal   RegCreateKey(long ptr ptr) RegCreateKey16
@@ -217,14 +223,17 @@
 225 pascal   RegQueryValueEx(long ptr ptr ptr ptr ptr) RegQueryValueEx16
 226 pascal   RegSetValueEx(long ptr long long ptr long) RegSetValueEx16
 227 pascal   RegFlushKey(long) RegFlushKey
-#228 K228
-#229 K229
+228 stub K228
+229 stub K229
 230 stub GlobalSmartPageLock
 231 stub GlobalSmartPageUnlock
 232 stub RegLoadKey
 233 stub RegUnloadKey
 234 stub RegSaveKey
 235 stub InvalidateNlsCache
+237 stub KERNEL_237
+262 stub KERNEL_262
+263 stub KERNEL_263
 310 pascal16 LocalHandleDelta(word) LocalHandleDelta
 311 stub GetSetKernelDosProc
 314 stub DebugDefineSegment
@@ -237,7 +246,7 @@
 324 stub LogError
 325 stub LogParamError
 326 return IsRomFile 2 0
-#327 K327
+327 stub KERNEL_327
 328 stub _DebugOutput
 #329 K329
 #332 stub THHOOK
@@ -264,6 +273,9 @@
 354 pascal   GetAppCompatFlags(word) GetAppCompatFlags16
 355 pascal16 GetWinDebugInfo(ptr word) GetWinDebugInfo
 356 pascal16 SetWinDebugInfo(ptr) SetWinDebugInfo
+357 stub KERNEL_357
+358 stub KERNEL_358
+359 stub KERNEL_359
 360 stub OpenFileEx
 #361 PIGLET_361
 403 pascal16 FarSetOwner(word word) FarSetOwner
@@ -282,14 +294,48 @@
 420 pascal   GetFileAttributes(ptr) GetFileAttributes16
 421 pascal16 SetFileAttributes(ptr long) SetFileAttributes16
 422 pascal16 GetDiskFreeSpace(ptr ptr ptr ptr ptr) GetDiskFreeSpace16 
+431 stub KERNEL_431
 432 stub FileTimeToLocalFileTime
+435 stub KERNEL_435
+439 stub KERNEL_439
+440 stub KERNEL_440
+444 stub KERNEL_444
+445 stub KERNEL_445
+446 stub KERNEL_446
+447 stub KERNEL_447
+449 stub KERNEL_449
 450 pascal16 KERNEL_450() stub_KERNEL_450
+454 stub KERNEL_454
+455 stub KERNEL_455
+471 stub KERNEL_471
+472 stub KERNEL_472
+473 stub KERNEL_473
+482 stub KERNEL_482
 491 stub RegisterServiceProcess
-513 stub LoadLibraryEx32W
+500 stub KERNEL_500
+502 stub KERNEL_502
+503 stub KERNEL_503
+511 stub KERNEL_511
+513 pascal LoadLibraryEx32W(ptr long long) LoadLibraryEx32W16
 514 stub FreeLibrary32W
-515 stub GetProcAddress32W
+515 pascal GetProcAddress32W(long ptr) GetProcAddress32
 516 stub GetVDMPointer32W
 517 stub CallProc32W
 518 stub CallProcEx32W
+519 stub KERNEL_519
+522 stub KERNEL_522
+525 stub KERNEL_525
+600 stub KERNEL_600
+601 stub KERNEL_601
+604 stub KERNEL_604
+605 stub KERNEL_605
+612 stub KERNEL_612
+613 stub KERNEL_613
+614 stub KERNEL_614
+619 stub KERNEL_619
+621 stub KERNEL_621
 627 stub IsBadFlatReadWritePtr
+630 stub KERNEL_630
 631 stub FUNC004	# shell hook
+651 stub KERNEL_651
+700 return KERNEL_700 0 1
diff --git a/if1632/kernel32.spec b/if1632/kernel32.spec
index 29ca260..23d4f31 100644
--- a/if1632/kernel32.spec
+++ b/if1632/kernel32.spec
@@ -264,7 +264,7 @@
 0259 stdcall GetProcessHeap() GetProcessHeap
 0260 stub GetProcessHeaps
 0261 stub GetProcessShutdownParameters
-0262 stub GetProcessTimes
+0262 stdcall GetProcessTimes(long ptr ptr ptr ptr) GetProcessTimes
 0263 stub GetProcessWorkingSetSize
 0264 stdcall GetProfileIntA(ptr ptr long) GetProfileInt32A
 0265 stdcall GetProfileIntW(ptr ptr long) GetProfileInt32W
@@ -685,3 +685,4 @@
 0679 stdcall MapLS(ptr) MapLS
 0680 stdcall UnMapLS(long) UnMapLS
 0681 stub OpenVxDHandle
+0682 stub FT_Exit12
diff --git a/if1632/ntdll.spec b/if1632/ntdll.spec
index 0ccee24..42d9ef2 100644
--- a/if1632/ntdll.spec
+++ b/if1632/ntdll.spec
@@ -398,7 +398,7 @@
 394 stub RtlGetUserInfoHeap
 395 stub RtlIdentifierAuthoritySid
 396 stub RtlImageDirectoryEntryToData
-397 stub RtlImageNtHeader
+397 stdcall RtlImageNtHeader(long) RtlImageNtHeader
 398 stub RtlImpersonateSelf
 399 stdcall RtlInitAnsiString(ptr ptr) RtlInitAnsiString
 400 stub RtlInitCodePageTable
@@ -877,7 +877,7 @@
 873 stub _stricmp
 874 stub _strlwr
 875 stub _strnicmp
-876 stub _strupr
+876 stdcall _strupr(ptr) CRTDLL__strupr
 877 stub _ultoa
 878 stub _vsnprintf
 879 stdcall _wcsicmp(ptr ptr) lstrcmpi32W
diff --git a/if1632/relay.c b/if1632/relay.c
index 045bb16..8e8a15f 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -26,6 +26,7 @@
 BOOL32 RELAY_Init(void)
 {
     WORD codesel;
+    extern BOOL32 THUNK_Init(void);
 
       /* Allocate the code selector for CallTo16 routines */
 
@@ -44,7 +45,10 @@
                                     codesel );
     CALLTO16_RetAddr_long=MAKELONG( (int)CALLTO16_Ret_long-(int)CALLTO16_Start,
                                     codesel );
-    return TRUE;
+
+    /* Initialize thunking */
+
+    return THUNK_Init();
 }
 
 
diff --git a/if1632/thunk.c b/if1632/thunk.c
index f566103..20f05cd 100644
--- a/if1632/thunk.c
+++ b/if1632/thunk.c
@@ -9,9 +9,11 @@
 #include "heap.h"
 #include "hook.h"
 #include "module.h"
+#include "winproc.h"
+#include "stackframe.h"
+#include "except.h"
 #include "stddebug.h"
 #include "debug.h"
-#include "except.h"
 
 typedef void (*RELAY)();
 
@@ -37,6 +39,21 @@
 
 static THUNK *firstThunk = NULL;
 
+static LRESULT THUNK_CallWndProc16( WNDPROC16 proc, HWND16 hwnd, UINT16 msg,
+                                    WPARAM16 wParam, LPARAM lParam );
+
+/***********************************************************************
+ *           THUNK_Init
+ */
+BOOL32 THUNK_Init(void)
+{
+    /* Set the window proc calling functions */
+    WINPROC_SetCallWndProc16( THUNK_CallWndProc16 );
+    WINPROC_SetCallWndProc32( (WINPROC_CALLWNDPROC32)CallTo32_4 );
+    return TRUE;
+}
+
+
 /***********************************************************************
  *           THUNK_Alloc
  */
@@ -72,7 +89,7 @@
 /***********************************************************************
  *           THUNK_Free
  */
-void THUNK_Free( THUNK *thunk )
+static void THUNK_Free( THUNK *thunk )
 {
     if (HEAP_IsInsideHeap( GetProcessHeap(), 0, thunk ))
     {
@@ -90,6 +107,32 @@
 
 
 /***********************************************************************
+ *           THUNK_CallWndProc16
+ *
+ * Call a 16-bit window procedure
+ */
+static LRESULT THUNK_CallWndProc16( WNDPROC16 proc, HWND16 hwnd, UINT16 msg,
+                                    WPARAM16 wParam, LPARAM lParam )
+{
+    if ((msg == WM_CREATE) || (msg == WM_NCCREATE))
+    {
+        CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
+        /* Build the CREATESTRUCT on the 16-bit stack. */
+        /* This is really ugly, but some programs (notably the */
+        /* "Undocumented Windows" examples) want it that way.  */
+        return CallTo16_long_lllllllwlwwwl( (FARPROC16)proc,
+                         cs->dwExStyle, cs->lpszClass, cs->lpszName, cs->style,
+                         MAKELONG( cs->y, cs->x ), MAKELONG( cs->cy, cs->cx ),
+                         MAKELONG( cs->hMenu, cs->hwndParent ), cs->hInstance,
+                         (LONG)cs->lpCreateParams, hwnd, msg, wParam,
+                         MAKELONG( IF1632_Saved16_sp-sizeof(CREATESTRUCT16),
+                                   IF1632_Saved16_ss ) );
+    }
+    return CallTo16_long_wwwl( (FARPROC16)proc, hwnd, msg, wParam, lParam );
+}
+
+
+/***********************************************************************
  *           THUNK_EnumObjects16   (GDI.71)
  */
 INT16 THUNK_EnumObjects16( HDC16 hdc, INT16 nObjType,
diff --git a/if1632/user32.spec b/if1632/user32.spec
index f6c3ea4..ff7dd1a 100644
--- a/if1632/user32.spec
+++ b/if1632/user32.spec
@@ -403,7 +403,7 @@
 0396 stdcall ModifyMenuA(long long long long ptr) ModifyMenu32A
 0397 stdcall ModifyMenuW(long long long long ptr) ModifyMenu32W
 0398 stdcall MoveWindow(long long long long long long) MoveWindow32
-0399 stub MsgWaitForMultipleObjects
+0399 stdcall MsgWaitForMultipleObjects(long ptr long long long) MsgWaitForMultipleObjects
 0400 stdcall OemKeyScan(long) OemKeyScan
 0401 stdcall OemToCharA(ptr ptr) OemToChar32A
 0402 stdcall OemToCharBuffA(ptr ptr long) OemToCharBuff32A
diff --git a/include/callback.h b/include/callback.h
index 4c2ed26..d1cb792 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -16,12 +16,10 @@
 /* List of the 16-bit callback functions. This list is used  */
 /* by the build program to generate the file if1632/callto16.S */
 
-                               /* func     parameters */
-extern WORD CallTo16_word_     ( FARPROC16 );
-
 #ifndef WINELIB
 
 extern void CallTo16_regs_     ( const CONTEXT *context );
+extern WORD CallTo16_word_     ( FARPROC16 );
 extern WORD CallTo16_word_w    ( FARPROC16, WORD );
 extern WORD CallTo16_word_ww   ( FARPROC16, WORD, WORD );
 extern WORD CallTo16_word_wl   ( FARPROC16, WORD, LONG );
@@ -54,17 +52,8 @@
     CallTo16_word_wwlll( func, id, msg, dwUser, dw1, dw2 )
 #define CallWindowsExitProc( func, nExitType ) \
     CallTo16_word_w( func, nExitType )
-#define CallWndProc16( func, hwnd, msg, wParam, lParam ) \
-    CallTo16_long_wwwl( (FARPROC16)(func), hwnd, msg, wParam, lParam )
 #define CallWordBreakProc16( func, lpch, ichCurrent, cch, code ) \
     CallTo16_word_lwww( func, lpch, ichCurrent, cch, code )
-#define CallWndProcNCCREATE16( func, exStyle, clsName, winName, style, \
-                               x, y, cx, cy, hparent, hmenu, instance, \
-                               params, hwnd, msg, wParam, lParam ) \
-    CallTo16_long_lllllllwlwwwl( (FARPROC16)(func), exStyle, clsName, winName,\
-                                 style, MAKELONG(y,x), MAKELONG(cy,cx), \
-                                 MAKELONG(hmenu,hparent), instance, params, \
-                                 hwnd, msg, wParam, lParam )
 
 
 /* List of the 32-bit callback functions. This list is used  */
@@ -81,8 +70,6 @@
     CallTo32_0( func )
 #define CallDLLEntryProc32( func, hmodule, a, b ) \
     CallTo32_3( func, hmodule, a, b )
-#define CallWndProc32( func, hwnd, msg, wParam, lParam ) \
-    CallTo32_4( func, hwnd, msg, wParam, lParam )
 #define CallWordBreakProc32A( func, lpch, ichCurrent, cch, code ) \
     CallTo32_4( func, (DWORD)lpch, ichCurrent, cch, code )
 
@@ -95,10 +82,6 @@
     (*func)( id, msg, dwUser, dw1, dw2 )
 #define CallWindowsExitProc( func, nExitType ) \
     (*func)( nExitType )
-#define CallWndProc16( func, hwnd, msg, wParam, lParam ) \
-    (*func)( hwnd, msg, wParam, lParam )
-#define CallWndProc32( func, hwnd, msg, wParam, lParam ) \
-    (*func)( hwnd, msg, wParam, lParam )
 #define CallWordBreakProc16( func, lpch, ichCurrent, cch, code ) \
     (*func)( lpch, ichCurrent, cch, code )
 #define CallWordBreakProc32A( func, lpch, ichCurrent, cch, code ) \
diff --git a/include/msdos.h b/include/msdos.h
index 111fbc7..3eb18a6 100644
--- a/include/msdos.h
+++ b/include/msdos.h
@@ -1,6 +1,7 @@
 #ifndef __WINE_MSDOS_H
 #define __WINE_MSDOS_H
 
+#include <sys/types.h>
 #include <dirent.h>
 #include "windows.h"
 #include "comm.h"
diff --git a/include/sigcontext.h b/include/sigcontext.h
index 55c60c2..2b4c33e 100644
--- a/include/sigcontext.h
+++ b/include/sigcontext.h
@@ -39,12 +39,7 @@
 } SIGCONTEXT;
 #endif  /* linux */
 
-#ifdef __NetBSD__
-#include <signal.h>
-typedef struct sigcontext SIGCONTEXT;
-#endif  /* NetBSD */
-
-#ifdef __FreeBSD__
+#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
 #include <signal.h>
 typedef struct sigcontext SIGCONTEXT;
 #endif  /* FreeBSD */
@@ -123,8 +118,8 @@
 #define EFL_sig(context)     ((context)->sc_efl)
 #endif                      
                             
-#define EIP_sig(context)     ((context)->sc_eip)
-#define ESP_sig(context)     ((context)->sc_esp)
+#define EIP_sig(context)     (*((unsigned long*)&(context)->sc_eip))
+#define ESP_sig(context)     (*((unsigned long*)&(context)->sc_esp))
 
 #endif  /* linux || __NetBSD__ || __FreeBSD__ */
 
diff --git a/include/windows.h b/include/windows.h
index c9fe841..dbfb29e 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -5611,13 +5611,13 @@
 LONG       DispatchMessage32A(const MSG32*);
 LONG       DispatchMessage32W(const MSG32*);
 #define    DispatchMessage WINELIB_NAME_AW(DispatchMessage)
-INT16      DlgDirList16(HWND16,LPCSTR,INT16,INT16,UINT16);
-INT32      DlgDirList32A(HWND32,LPCSTR,INT32,INT32,UINT32);
-INT32      DlgDirList32W(HWND32,LPCWSTR,INT32,INT32,UINT32);
+INT16      DlgDirList16(HWND16,LPSTR,INT16,INT16,UINT16);
+INT32      DlgDirList32A(HWND32,LPSTR,INT32,INT32,UINT32);
+INT32      DlgDirList32W(HWND32,LPWSTR,INT32,INT32,UINT32);
 #define    DlgDirList WINELIB_NAME_AW(DlgDirList)
-INT16      DlgDirListComboBox16(HWND16,LPCSTR,INT16,INT16,UINT16);
-INT32      DlgDirListComboBox32A(HWND32,LPCSTR,INT32,INT32,UINT32);
-INT32      DlgDirListComboBox32W(HWND32,LPCWSTR,INT32,INT32,UINT32);
+INT16      DlgDirListComboBox16(HWND16,LPSTR,INT16,INT16,UINT16);
+INT32      DlgDirListComboBox32A(HWND32,LPSTR,INT32,INT32,UINT32);
+INT32      DlgDirListComboBox32W(HWND32,LPWSTR,INT32,INT32,UINT32);
 #define    DlgDirListComboBox WINELIB_NAME_AW(DlgDirListComboBox)
 BOOL16     DlgDirSelectComboBoxEx16(HWND16,LPSTR,INT16,INT16);
 BOOL32     DlgDirSelectComboBoxEx32A(HWND32,LPSTR,INT32,INT32);
diff --git a/include/winproc.h b/include/winproc.h
index d239dfd..c601898 100644
--- a/include/winproc.h
+++ b/include/winproc.h
@@ -76,4 +76,9 @@
 extern void WINPROC_UnmapMsg32WTo16( UINT32 msg, WPARAM32 wParam,
                                      LPARAM lParam, MSGPARAM16* pm16 );
 
+typedef LRESULT (*WINPROC_CALLWNDPROC16)(WNDPROC16,HWND16,UINT16,WPARAM16,LPARAM);
+typedef LRESULT (*WINPROC_CALLWNDPROC32)(WNDPROC32,HWND32,UINT32,WPARAM32,LPARAM);
+extern void WINPROC_SetCallWndProc16( WINPROC_CALLWNDPROC16 proc );
+extern void WINPROC_SetCallWndProc32( WINPROC_CALLWNDPROC32 proc );
+
 #endif  /* __WINE_WINPROC_H */
diff --git a/library/miscstubs.c b/library/miscstubs.c
index 693fbcc..38094c1 100644
--- a/library/miscstubs.c
+++ b/library/miscstubs.c
@@ -17,6 +17,10 @@
     /* FIXME: signals don't work in the library */
 }
 
+/* for windows/winproc.c */
+void CallFrom16_long_wwwll(void) {}
+void CallFrom32_stdcall_5(void) {}
+
 int CallTo32_LargeStack( int (*func)(), int nbargs, ...)
 {
   va_list arglist;
diff --git a/loader/module.c b/loader/module.c
index d7df2fe..19bb6d0 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -451,7 +451,7 @@
        ((fastload && ((offset) >= fastload_offset) && \
          ((offset)+(size) <= fastload_offset+fastload_length)) ? \
         (memcpy( buffer, fastload+(offset)-fastload_offset, (size) ), TRUE) : \
-        (_llseek32( hFile, mz_header.ne_offset+(offset), SEEK_SET), \
+        (_llseek32( hFile, (offset), SEEK_SET), \
          _lread32( hFile, (buffer), (size) ) == (size)))
 
     _llseek32( hFile, 0, SEEK_SET );
@@ -509,10 +509,11 @@
                         fastload_offset, fastload_length );
         if ((fastload = HeapAlloc( SystemHeap, 0, fastload_length )) != NULL)
         {
-            _llseek32( hFile, mz_header.ne_offset + fastload_offset, SEEK_SET);
+            _llseek32( hFile, fastload_offset, SEEK_SET);
             if (_lread32(hFile, fastload, fastload_length) != fastload_length)
             {
                 HeapFree( SystemHeap, 0, fastload );
+                fprintf(stderr, "Error reading fast-load area !\n");
                 fastload = NULL;
             }
         }
@@ -536,12 +537,12 @@
         int i;
         struct ne_segment_table_entry_s *pSeg;
 
-        if (!READ( ne_header.segment_tab_offset,
+        if (!READ( mz_header.ne_offset + ne_header.segment_tab_offset,
              ne_header.n_segment_tab * sizeof(struct ne_segment_table_entry_s),
              buffer ))
         {
             HeapFree( SystemHeap, 0, buffer );
-            HeapFree( SystemHeap, 0, fastload );
+            if (fastload) HeapFree( SystemHeap, 0, fastload );
             GlobalFree16( hModule );
             return (HMODULE16)11;  /* invalid exe */
         }
@@ -555,7 +556,7 @@
     }
     else
     {
-        HeapFree( SystemHeap, 0, fastload );
+        if (fastload) HeapFree( SystemHeap, 0, fastload );
         GlobalFree16( hModule );
         return (HMODULE16)11;  /* invalid exe */
     }
@@ -565,7 +566,7 @@
     if (ne_header.resource_tab_offset < ne_header.rname_tab_offset)
     {
         pModule->res_table = (int)pData - (int)pModule;
-        if (!READ(ne_header.resource_tab_offset,
+        if (!READ(mz_header.ne_offset + ne_header.resource_tab_offset,
                   ne_header.rname_tab_offset - ne_header.resource_tab_offset,
                   pData )) return (HMODULE16)11;  /* invalid exe */
         pData += ne_header.rname_tab_offset - ne_header.resource_tab_offset;
@@ -575,11 +576,11 @@
     /* Get the resident names table */
 
     pModule->name_table = (int)pData - (int)pModule;
-    if (!READ( ne_header.rname_tab_offset,
+    if (!READ( mz_header.ne_offset + ne_header.rname_tab_offset,
                ne_header.moduleref_tab_offset - ne_header.rname_tab_offset,
                pData ))
     {
-        HeapFree( SystemHeap, 0, fastload );
+        if (fastload) HeapFree( SystemHeap, 0, fastload );
         GlobalFree16( hModule );
         return (HMODULE16)11;  /* invalid exe */
     }
@@ -590,11 +591,11 @@
     if (ne_header.n_mod_ref_tab > 0)
     {
         pModule->modref_table = (int)pData - (int)pModule;
-        if (!READ( ne_header.moduleref_tab_offset,
+        if (!READ( mz_header.ne_offset + ne_header.moduleref_tab_offset,
                   ne_header.n_mod_ref_tab * sizeof(WORD),
                   pData ))
         {
-            HeapFree( SystemHeap, 0, fastload );
+            if (fastload) HeapFree( SystemHeap, 0, fastload );
             GlobalFree16( hModule );
             return (HMODULE16)11;  /* invalid exe */
         }
@@ -605,11 +606,11 @@
     /* Get the imported names table */
 
     pModule->import_table = (int)pData - (int)pModule;
-    if (!READ( ne_header.iname_tab_offset, 
+    if (!READ( mz_header.ne_offset + ne_header.iname_tab_offset, 
                ne_header.entry_tab_offset - ne_header.iname_tab_offset,
                pData ))
     {
-        HeapFree( SystemHeap, 0, fastload );
+        if (fastload) HeapFree( SystemHeap, 0, fastload );
         GlobalFree16( hModule );
         return (HMODULE16)11;  /* invalid exe */
     }
@@ -618,11 +619,11 @@
     /* Get the entry table */
 
     pModule->entry_table = (int)pData - (int)pModule;
-    if (!READ( ne_header.entry_tab_offset,
+    if (!READ( mz_header.ne_offset + ne_header.entry_tab_offset,
                ne_header.entry_tab_length,
                pData ))
     {
-        HeapFree( SystemHeap, 0, fastload );
+        if (fastload) HeapFree( SystemHeap, 0, fastload );
         GlobalFree16( hModule );
         return (HMODULE16)11;  /* invalid exe */
     }
@@ -631,7 +632,7 @@
     /* Free the fast-load area */
 
 #undef READ
-    HeapFree( SystemHeap, 0, fastload );
+    if (fastload) HeapFree( SystemHeap, 0, fastload );
 
     /* Get the non-resident names table */
 
@@ -1380,6 +1381,17 @@
 
 
 /***********************************************************************
+ *           LoadLibraryEx32W   (KERNEL.513)
+ */
+HINSTANCE16 LoadLibraryEx32W16( LPCSTR libname, HANDLE16 hf, DWORD flags )
+{
+    fprintf(stderr,"LoadLibraryEx32W(%s,%d,%08lx)\n",libname,hf,flags);
+    if (!flags && !hf)
+    	return LoadLibrary32A(libname);
+    return 0;
+}
+
+/***********************************************************************
  *           LoadLibrary   (KERNEL.95)
  */
 HINSTANCE16 LoadLibrary16( LPCSTR libname )
@@ -1459,8 +1471,9 @@
     cmdline = (char *)GlobalLock16( cmdLineHandle );
     lstrcpyn32A(filename, lpCmdLine, sizeof(filename) - 4 /* for extension */);
     for (p = filename; *p && (*p != ' ') && (*p != '\t'); p++);
-    if (*p) lstrcpyn32A( cmdline, p + 1, 128 );
-    else cmdline[0] = '\0';
+    if (*p) lstrcpyn32A( cmdline + 1, p + 1, 127 );
+    else cmdline[1] = '\0';
+    cmdline[0] = strlen( cmdline + 1 ) + 1;
     *p = '\0';
 
       /* Now load the executable file */
@@ -1603,6 +1616,10 @@
 #ifndef WINELIB
     NE_MODULE *pModule;
 
+    if (HIWORD(function))
+	dprintf_win32(stddeb,"GetProcAddress32(%08lx,%s)\n",(DWORD)hModule,function);
+    else
+	dprintf_win32(stddeb,"GetProcAddress32(%08lx,%p)\n",(DWORD)hModule,function);
     hModule = GetExePtr( hModule );
     if (!(pModule = MODULE_GetPtr( hModule )))
         return (FARPROC32)0;
@@ -1616,6 +1633,26 @@
 #endif
 }
 
+/***********************************************************************
+ *           RtlImageNtHeaders   (NTDLL)
+ */
+LPIMAGE_NT_HEADERS
+RtlImageNtHeader(HMODULE32 hModule)
+{
+#ifndef WINELIB
+    NE_MODULE *pModule;
+
+    hModule = GetExePtr( hModule );
+    if (!(pModule = MODULE_GetPtr( hModule )))
+        return (LPIMAGE_NT_HEADERS)0;
+    if (!(pModule->flags & NE_FFLAGS_WIN32) || !pModule->pe_module)
+        return (LPIMAGE_NT_HEADERS)0;
+    return pModule->pe_module->pe_header;
+#else
+    return NULL;
+#endif
+}
+
 
 /**********************************************************************
  *	    GetExpWinVer    (KERNEL.167)
diff --git a/loader/signal.c b/loader/signal.c
index 96281bf..5290f7c7 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -151,15 +151,15 @@
   HANDLER_PROLOG;
   if (CS_sig(context) == WINE_CODE_SELECTOR)
     {
-        fprintf( stderr, "Segmentation fault in Wine program (%x:%lx)."
+        fprintf( stderr, "Segmentation fault in Wine program (%04x:%08lx)."
                          "  Please debug.\n",
-                 CS_sig(context), EIP_sig(context) );
+		(unsigned short) CS_sig(context), EIP_sig(context));
     }
   else
     {
         if (INSTR_EmulateInstruction( context )) return;
-        fprintf( stderr, "Segmentation fault in Windows program %x:%lx.\n",
-                 CS_sig(context), EIP_sig(context) );
+        fprintf( stderr, "Segmentation fault in Windows program %04x:%08lx.\n",
+		(unsigned short) CS_sig(context), EIP_sig(context) );
     }
   wine_debug( signal, context );
   HANDLER_EPILOG;
diff --git a/loader/task.c b/loader/task.c
index 97cf296..8ada240 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -514,8 +514,7 @@
     memset( pTask->pdb.fileHandles, 0xff, sizeof(pTask->pdb.fileHandles) );
     pTask->pdb.environment    = hEnvironment;
     pTask->pdb.nbFiles        = 20;
-    lstrcpyn32A( pTask->pdb.cmdLine + 1, cmdLine, 127 );
-    pTask->pdb.cmdLine[0] = strlen( pTask->pdb.cmdLine + 1 );
+    lstrcpyn32A( pTask->pdb.cmdLine, cmdLine, 127 );
 
       /* Get the compatibility flags */
 
@@ -539,6 +538,7 @@
     /* Create the Win32 part of the task */
 
     pdb32 = PROCESS_Create( pTask );
+    pdb32->task = hTask;
     if (pModule->flags & NE_FFLAGS_WIN32)
     {
         LPTHREAD_START_ROUTINE start =
diff --git a/memory/local.c b/memory/local.c
index c04fe2d..3baea5d 100644
--- a/memory/local.c
+++ b/memory/local.c
@@ -57,6 +57,18 @@
     BYTE lock;                /* Lock count */
 } LOCALHANDLEENTRY;
 
+/*
+ * We make addr = 4n + 2 and set *((WORD *)addr - 1) = &addr like Windows does
+ * in case something actually relies on this.
+ * Note the ARENA_HEADER(addr) still produces the desired result ie. 4n - 4
+ *
+ * An unused handle has lock = flags = 0xff. In windows addr is that of next
+ * free handle, at the moment in wine we set it to 0.
+ *
+ * A discarded block's handle has lock = addr = 0 and flags = 0x40
+ * (LMEM_DISCARDED >> 8)
+ */
+
 #pragma pack(1)
 
 typedef struct
@@ -564,6 +576,27 @@
 }
 
 
+
+/***********************************************************************
+ *           LOCAL_GrowArenaUpward
+ *
+ * Grow an arena upward by using the next arena (must be free and big
+ * enough). Newsize includes the arena header and must be aligned.
+ */
+static void LOCAL_GrowArenaUpward( WORD ds, WORD arena, WORD newsize )
+{
+    char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
+    LOCALHEAPINFO *pInfo;
+    LOCALARENA *pArena = ARENA_PTR( ptr, arena );
+    WORD nextArena = pArena->next;
+
+    if (!(pInfo = LOCAL_GetHeap( ds ))) return;
+    LOCAL_RemoveBlock( ptr, nextArena );
+    pInfo->items--;
+    LOCAL_ShrinkArena( ds, arena, newsize );
+}
+
+
 /***********************************************************************
  *           LOCAL_GetFreeSpace
  */
@@ -632,8 +665,7 @@
         pEntry = (LOCALHANDLEENTRY *)(ptr + table + sizeof(WORD));
         for(count = *(WORD *)(ptr + table); count > 0; count--, pEntry++)
         {
-            if((pEntry->lock == 0) && !(pEntry->flags &
-                                        (LMEM_DISCARDED >> 8)))
+            if((pEntry->lock == 0) && (pEntry->flags != (LMEM_DISCARDED >> 8)))
             {
                 /* OK we can move this one if we want */
                 dprintf_local(stddeb,
@@ -705,14 +737,14 @@
         pEntry = (LOCALHANDLEENTRY *)(ptr + table + sizeof(WORD));
         for(count = *(WORD *)(ptr + table); count > 0; count--, pEntry++)
         {
-            if((pEntry->flags & (LMEM_DISCARDABLE >> 8)) &&
-               pEntry->lock == 0 && !(pEntry->flags & (LMEM_DISCARDED >> 8)))
-            {
+            if(pEntry->addr && pEntry->lock == 0 &&
+	     (pEntry->flags & (LMEM_DISCARDABLE >> 8)))
+	    {
                 dprintf_local(stddeb, "Discarding handle %04x (block %04x).\n",
                               (char *)pEntry - ptr, pEntry->addr);
-                LOCAL_FreeArena(ds, pEntry->addr);
+                LOCAL_FreeArena(ds, ARENA_HEADER(pEntry->addr));
                 pEntry->addr = 0;
-                pEntry->flags |= (LMEM_DISCARDED >> 8);
+                pEntry->flags = (LMEM_DISCARDED >> 8);
                 /* Call localnotify proc */
             }
         }
@@ -770,7 +802,7 @@
 	LOCAL_PrintHeap(ds);
 	return 0;
     }
-    
+
     size += ARENA_HEADER_SIZE;
     size = LALIGN( MAX( size, sizeof(LOCALARENA) ) );
 
@@ -801,8 +833,8 @@
     LOCAL_RemoveFreeBlock( ptr, arena );
     LOCAL_ShrinkArena( ds, arena, size );
 
-    if (flags & LMEM_ZEROINIT) memset( (char *)pArena + ARENA_HEADER_SIZE, 0,
-                                       size - ARENA_HEADER_SIZE );
+    if (flags & LMEM_ZEROINIT)
+	memset((char *)pArena + ARENA_HEADER_SIZE, 0, size-ARENA_HEADER_SIZE);
     return arena + ARENA_HEADER_SIZE;
 }
 
@@ -838,7 +870,10 @@
 
     *(WORD *)(ptr + handle) = pInfo->hdelta;
     pEntry = (LOCALHANDLEENTRY *)(ptr + handle + sizeof(WORD));
-    for (i = pInfo->hdelta; i > 0; i--) (pEntry++)->lock = 0xff;
+    for (i = pInfo->hdelta; i > 0; i--, pEntry++) {
+	pEntry->lock = pEntry->flags = 0xff;
+	pEntry->addr = 0;
+    }
     *(WORD *)pEntry = pInfo->htable;
     pInfo->htable = handle;
     return TRUE;
@@ -886,6 +921,7 @@
     /* Now allocate this entry */
 
     pEntry->lock = 0;
+    pEntry->flags = 0;
     dprintf_local( stddeb, "LOCAL_GetNewHandleEntry(%04x): %04x\n",
                    ds, ((char *)pEntry - ptr) );
     return (HLOCAL16)((char *)pEntry - ptr);
@@ -928,7 +964,7 @@
 
     pEntry->addr = 0;  /* just in case */
     pEntry->lock = 0xff;
-
+    pEntry->flags = 0xff; 
     /* Now check if all entries in this table are free */
 
     table = *pTable;
@@ -965,7 +1001,7 @@
     else
     {
         LOCALHANDLEENTRY *pEntry = (LOCALHANDLEENTRY *)(ptr + handle);
-        if (!(pEntry->flags & (LMEM_DISCARDED >> 8)))
+        if (pEntry->flags != (LMEM_DISCARDED >> 8))
         {
             dprintf_local( stddeb, "LocalFree: real block at %04x\n",
 			   pEntry->addr );
@@ -982,6 +1018,7 @@
  *           LOCAL_Alloc
  *
  * Implementation of LocalAlloc().
+ *
  */
 HLOCAL16 LOCAL_Alloc( HANDLE16 ds, WORD flags, WORD size )
 {
@@ -990,26 +1027,47 @@
     
     dprintf_local( stddeb, "LocalAlloc: %04x %d ds=%04x\n", flags, size, ds );
 
+    if(size > 0 && size <= 4) size = 5;
     if (flags & LMEM_MOVEABLE)
     {
 	LOCALHANDLEENTRY *plhe;
 	HLOCAL16 hmem;
-	
-	if (!(hmem = LOCAL_GetBlock( ds, size, flags ))) return 0;
+
+	if(size)
+	{
+	    if (!(hmem = LOCAL_GetBlock( ds, size + sizeof(HLOCAL16), flags )))
+		return 0;
+        }
+	else /* We just need to allocate a discarded handle */
+	    hmem = 0;
 	if (!(handle = LOCAL_GetNewHandleEntry( ds )))
         {
 	    fprintf( stderr, "LocalAlloc: couldn't get handle\n");
-	    LOCAL_FreeArena( ds, ARENA_HEADER(hmem) );
+	    if(hmem)
+		LOCAL_FreeArena( ds, ARENA_HEADER(hmem) );
 	    return 0;
 	}
 	ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
 	plhe = (LOCALHANDLEENTRY *)(ptr + handle);
-	plhe->addr = hmem;
-        plhe->flags = (BYTE)(flags >> 8);
 	plhe->lock = 0;
+	if(hmem)
+	{
+	    plhe->addr = hmem + sizeof(HLOCAL16);
+	    plhe->flags = (BYTE)((flags & 0x0f00) >> 8);
+	    *(HLOCAL16 *)(ptr + hmem) = handle;
+	}
+	else
+	{
+	    plhe->addr = 0;
+	    plhe->flags = LMEM_DISCARDED >> 8;
+        }
     }
-    else handle = LOCAL_GetBlock( ds, size, flags );
-
+    else /* FIXED */
+    {
+	if(!size)
+	    return 0;
+	handle = LOCAL_GetBlock( ds, size, flags );
+    }
     return handle;
 }
 
@@ -1025,88 +1083,106 @@
     LOCALHEAPINFO *pInfo;
     LOCALARENA *pArena, *pNext;
     LOCALHANDLEENTRY *pEntry;
-    WORD arena, newhandle, blockhandle, oldsize;
+    WORD arena, oldsize;
+    HLOCAL16 hmem, blockhandle;
     LONG nextarena;
 
-    if (!handle) return LOCAL_Alloc( ds, size, flags );
+    if (!handle) return 0;
+    if(HANDLE_MOVEABLE(handle) &&
+     ((LOCALHANDLEENTRY *)(ptr + handle))->lock == 0xff) /* An unused handle */
+	return 0;
 
     dprintf_local( stddeb, "LocalReAlloc: %04x %d %04x ds=%04x\n",
                    handle, size, flags, ds );
     if (!(pInfo = LOCAL_GetHeap( ds ))) return 0;
     
-    if (HANDLE_FIXED( handle )) blockhandle = handle;
+    if (HANDLE_FIXED( handle ))
+	blockhandle = handle;
     else
     {
 	pEntry = (LOCALHANDLEENTRY *) (ptr + handle);
-	if(pEntry->flags & (LMEM_DISCARDED >> 8))
+	if(pEntry->flags == (LMEM_DISCARDED >> 8))
         {
+	    HLOCAL16 hl;
+	    if(pEntry->addr)
+		fprintf(stderr,
+			"LOCAL_ReAlloc: Dicarded block has non-zero addr.\n");
 	    dprintf_local(stddeb, "ReAllocating discarded block\n");
-	    if (!(pEntry->addr = LOCAL_GetBlock( ds, size, flags))) return 0;
+	    if(size <= 4) size = 5;
+	    if (!(hl = LOCAL_GetBlock( ds, size + sizeof(HLOCAL16), flags)))
+		return 0;
             ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );  /* Reload ptr */
             pEntry = (LOCALHANDLEENTRY *) (ptr + handle);
-            pEntry->flags = (BYTE) (flags >> 8);
+	    pEntry->addr = hl + sizeof(HLOCAL16);
+            pEntry->flags = 0;
             pEntry->lock = 0;
+	    *(HLOCAL16 *)(ptr + hl) = handle;
             return handle;
-	}    
-	if (!(blockhandle = pEntry->addr))
+	}
+	if (((blockhandle = pEntry->addr) & 3) != 2)
 	{
 	    fprintf( stderr, "Local_ReAlloc(%04x,%04x): invalid handle\n",
                      ds, handle );
 	    return 0;
         }
+	if(*((HLOCAL16 *)(ptr + blockhandle) - 1) != handle) {
+	    fprintf(stderr, "Local_ReAlloc: Back ptr to handle is invalid\n");
+	    return 0;
+        }
+    }
+
+    if (flags & LMEM_MODIFY)
+    {
+        if (HANDLE_MOVEABLE(handle))
+	{
+	    pEntry = (LOCALHANDLEENTRY *)(ptr + handle);
+	    pEntry->flags = (flags & 0x0f00) >> 8;
+	    dprintf_local(stddeb, "Changing flags to %x.\n", pEntry->flags);
+	}
+	return handle;
+    }
+
+    if (!size)
+    {
+        if (flags & LMEM_MOVEABLE)
+        {
+	    if (HANDLE_FIXED(handle))
+	    {
+                dprintf_local(stddeb, "Freeing fixed block.\n");
+                return LOCAL_Free( ds, handle );
+            }
+	    else /* Moveable block */
+	    {
+		pEntry = (LOCALHANDLEENTRY *)(ptr + handle);
+		if (pEntry->lock == 0)
+		{
+		    /* discards moveable blocks */
+                    dprintf_local(stddeb,"Discarding block\n");
+                    LOCAL_FreeArena(ds, ARENA_HEADER(pEntry->addr));
+                    pEntry->addr = 0;
+                    pEntry->flags = (LMEM_DISCARDED >> 8);
+                    return handle;
+	        }
+	    }
+	    return 0;
+        }
+        else if(flags == 0)
+        {
+            pEntry = (LOCALHANDLEENTRY *)(ptr + handle);
+            if (pEntry->lock == 0)
+            {
+		/* Frees block */
+		return LOCAL_Free( ds, handle );
+	    }
+        }
+        return 0;
     }
 
     arena = ARENA_HEADER( blockhandle );
     dprintf_local( stddeb, "LocalReAlloc: arena is %04x\n", arena );
     pArena = ARENA_PTR( ptr, arena );
-    
-    if ((flags & LMEM_MODIFY) && (flags & LMEM_DISCARDABLE))
-    {
-        if (HANDLE_FIXED(handle))
-        {
-            fprintf(stderr,"LocalReAlloc: LMEM_MODIFY & LMEM_DISCARDABLE on a fixed handle.\n");
-            return handle;
-        }
-        dprintf_local( stddeb, "Making block discardable.\n" );
-        pEntry = (LOCALHANDLEENTRY *)(ptr + handle);
-        pEntry->flags |= (LMEM_DISCARDABLE >> 8);
-        return handle;
-    }
 
-    if ((flags & LMEM_MODIFY) || (flags & LMEM_DISCARDABLE))
-    {
-        fprintf(stderr,"LocalReAlloc: flags %04x. MODIFY & DISCARDABLE should both be set\n", flags);
-        return handle;
-    }
-
-    if (!size)
-    {
-        if (HANDLE_FIXED(handle))
-        {
-            if (flags & LMEM_MOVEABLE)
-            {
-                dprintf_local(stddeb, "Freeing fixed block.\n");
-                return LOCAL_Free( ds, handle );
-            }
-            else size = 1;
-        }
-        else
-        {
-            pEntry = (LOCALHANDLEENTRY *)(ptr + handle);
-            if (pEntry->lock == 0)
-            {
-                /* discards moveable blocks is this right? */
-                dprintf_local(stddeb,"Discarding block\n");
-                LOCAL_FreeArena(ds, ARENA_HEADER(pEntry->addr));
-                pEntry->addr = 0;
-                pEntry->flags = (LMEM_DISCARDED >> 8);
-                return 0;
-            }
-            return handle;
-        }
-    }
-
-    size = LALIGN( size );
+    if(size <= 4) size = 5;
     oldsize = pArena->next - arena - ARENA_HEADER_SIZE;
     nextarena = LALIGN(blockhandle + size);
 
@@ -1114,58 +1190,58 @@
 
     if (nextarena <= pArena->next)
     {
-        if (nextarena < pArena->next - LALIGN(sizeof(LOCALARENA)))
-        {
-	    dprintf_local( stddeb, "size reduction, making new free block\n");
-              /* It is worth making a new free block */
-            LOCAL_AddBlock( ptr, arena, nextarena );
-            pInfo->items++;
-            LOCAL_FreeArena( ds, nextarena );
-        }
+	dprintf_local( stddeb, "size reduction, making new free block\n");
+	LOCAL_ShrinkArena(ds, arena, nextarena - arena);
         dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", handle );
         return handle;
     }
 
-      /* Check if the next block is free */
+      /* Check if the next block is free and large enough */
 
     pNext = ARENA_PTR( ptr, pArena->next );
     if (((pNext->prev & 3) == LOCAL_ARENA_FREE) &&
         (nextarena <= pNext->next))
     {
-        LOCAL_RemoveBlock( ptr, pArena->next );
-        if (nextarena < pArena->next - LALIGN(sizeof(LOCALARENA)))
-        {
-	    dprintf_local( stddeb, "size increase, making new free block\n");
-              /* It is worth making a new free block */
-            LOCAL_AddBlock( ptr, arena, nextarena );
-            pInfo->items++;
-            LOCAL_FreeArena( ds, nextarena );
-        }
+	dprintf_local( stddeb, "size increase, making new free block\n");
+        LOCAL_GrowArenaUpward(ds, arena, nextarena - arena);
         dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", handle );
         return handle;
     }
 
-    /* Now we have to allocate a new block, but not if fixed block and no
-       LMEM_MOVEABLE */
+    /* Now we have to allocate a new block, but not if (fixed block or locked
+       block) and no LMEM_MOVEABLE */
 
-    if (HANDLE_FIXED(handle) && !(flags & LMEM_MOVEABLE))
+    if (!(flags & LMEM_MOVEABLE))
     {
-        dprintf_local(stddeb, "Needed to move fixed block, but LMEM_MOVEABLE not specified.\n");
-        return 0;  /* FIXME: should we free it here? */
+	if (HANDLE_FIXED(handle))
+        {
+            dprintf_local(stddeb,
+	     "Needed to move fixed block, but LMEM_MOVEABLE not specified.\n");
+            return 0;
+        }
+	else
+	{
+	    if(((LOCALHANDLEENTRY *)(ptr + handle))->lock != 0)
+	    {
+		dprintf_local(stddeb,
+	"Needed to move locked block, but LMEM_MOVEABLE not specified.\n");
+		return 0;
+	    }
+        }
     }
-
-    newhandle = LOCAL_GetBlock( ds, size, flags );
+    if(HANDLE_MOVEABLE(handle)) size += sizeof(HLOCAL16);
+    hmem = LOCAL_GetBlock( ds, size, flags );
     ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );  /* Reload ptr */
-    if (!newhandle)
+    if (!hmem)
     {
         /* Remove the block from the heap and try again */
         LPSTR buffer = HeapAlloc( SystemHeap, 0, oldsize );
         if (!buffer) return 0;
-        memcpy( buffer, ptr + (arena + ARENA_HEADER_SIZE), oldsize );
+        memcpy( buffer, ptr + arena + ARENA_HEADER_SIZE, oldsize );
         LOCAL_FreeArena( ds, arena );
-        if (!(newhandle = LOCAL_GetBlock( ds, size, flags )))
+        if (!(hmem = LOCAL_GetBlock( ds, size, flags )))
         {
-            if (!(newhandle = LOCAL_GetBlock( ds, oldsize, flags )))
+            if (!(hmem = LOCAL_GetBlock( ds, oldsize, flags )))
             {
                 fprintf( stderr, "LocalRealloc: can't restore saved block\n" );
                 HeapFree( SystemHeap, 0, buffer );
@@ -1174,25 +1250,27 @@
             size = oldsize;
         }
         ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );  /* Reload ptr */
-        memcpy( ptr + newhandle, buffer, oldsize );
+        memcpy( ptr + hmem, buffer, oldsize );
         HeapFree( SystemHeap, 0, buffer );
     }
     else
     {
-        memcpy( ptr + newhandle, ptr + (arena + ARENA_HEADER_SIZE), oldsize );
+        memcpy( ptr + hmem, ptr + (arena + ARENA_HEADER_SIZE), oldsize );
         LOCAL_FreeArena( ds, arena );
     }
     if (HANDLE_MOVEABLE( handle ))
     {
 	dprintf_local( stddeb, "LocalReAlloc: fixing handle\n");
         pEntry = (LOCALHANDLEENTRY *)(ptr + handle);
-        pEntry->addr = newhandle;
-        pEntry->lock = 0;
-	newhandle = handle;
+        pEntry->addr = hmem + sizeof(HLOCAL16);
+	/* Back ptr should still be correct */
+	if(*(HLOCAL16 *)(ptr + hmem) != handle)
+	    fprintf(stderr, "Local_ReAlloc: back ptr is invalid.\n");
+	hmem = handle;
     }
-    if (size == oldsize) newhandle = 0;  /* Realloc failed */
-    dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", newhandle );
-    return newhandle;
+    if (size == oldsize) hmem = 0;  /* Realloc failed */
+    dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", hmem );
+    return hmem;
 }
 
 
@@ -1205,6 +1283,7 @@
     if (HANDLE_MOVEABLE(handle))
     {
         LOCALHANDLEENTRY *pEntry = (LOCALHANDLEENTRY *)(heap + handle);
+	if (pEntry->flags == LMEM_DISCARDED) return 0;
         if (pEntry->lock < 0xfe) pEntry->lock++;
         handle = pEntry->addr;
     }
@@ -1266,6 +1345,7 @@
     dprintf_local( stddeb, "LocalSize: %04x ds=%04x\n", handle, ds );
 
     if (HANDLE_MOVEABLE( handle )) handle = *(WORD *)(ptr + handle);
+    if (!handle) return 0;
     pArena = ARENA_PTR( ptr, ARENA_HEADER(handle) );
     return pArena->next - handle;
 }
@@ -1477,6 +1557,7 @@
 	return 0;
     }
     dprintf_local( stddeb, "LocalNotify(%04x): %08lx\n", ds, (DWORD)func );
+    fprintf(stdnimp, "LocalNotify(): Half implemented\n");
     oldNotify = pInfo->notify;
     pInfo->notify = func;
     return oldNotify;
diff --git a/memory/virtual.c b/memory/virtual.c
index 920ceeb..2e3a6c0 100644
--- a/memory/virtual.c
+++ b/memory/virtual.c
@@ -1019,6 +1019,7 @@
     {
     case FILE_MAP_ALL_ACCESS:
     case FILE_MAP_WRITE:
+    case FILE_MAP_WRITE | FILE_MAP_READ:
         if (!(mapping->protect & VPROT_WRITE))
         {
             SetLastError( ERROR_INVALID_PARAMETER );
@@ -1028,6 +1029,7 @@
         /* fall through */
     case FILE_MAP_READ:
     case FILE_MAP_COPY:
+    case FILE_MAP_COPY | FILE_MAP_READ:
         if (mapping->protect & VPROT_READ) break;
         /* fall through */
     default:
diff --git a/misc/crtdll.c b/misc/crtdll.c
index 563bd39..f9ab8c0 100644
--- a/misc/crtdll.c
+++ b/misc/crtdll.c
@@ -9,6 +9,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <string.h>
 #include <unistd.h>
 #include <time.h>
@@ -135,7 +136,8 @@
 int CRTDLL_fprintf(DWORD *args)
 {
 	/* FIXME: use args[0] */
-	return vfprintf(stderr,(LPSTR)(args[1]),args+2);
+	/* CMF - This makes a BIG assumption about va_list */
+	return vfprintf(stderr, (LPSTR) args[1], (va_list) &args[2]);
 }
 
 /*********************************************************************
@@ -143,7 +145,8 @@
  */
 int CRTDLL_printf(DWORD *args)
 {
-	return vfprintf(stdout,(LPSTR)(args[0]),args+1);
+	/* CMF - This makes a BIG assumption about va_list */
+	return vfprintf(stdout, (LPSTR) args[0], (va_list) &args[1]);
 }
 
 /*********************************************************************
@@ -151,7 +154,8 @@
  */
 int CRTDLL_sprintf(DWORD *args)
 {
-	return vsprintf((LPSTR)(args[0]),(LPSTR)(args[1]),args+2);
+	/* CMF - This makes a BIG assumption about va_list */
+	return vsprintf((LPSTR) args[0], (LPSTR) args[1], (va_list) &args[2]);
 }
 
 /*********************************************************************
@@ -577,7 +581,8 @@
  */
 int CRTDLL_vsprintf(DWORD *args)
 {
-    return vsprintf((char *)args[0],(char *)args[1],args+2);
+	/* CMF - This makes a BIG assumption about va_list */
+	return vsprintf((char *) args[0], (char *) args[1], (va_list) &args[2]);
 }
 
 /*********************************************************************
@@ -585,7 +590,8 @@
  */
 int CRTDLL_sscanf(DWORD *args)
 {
-    return vsscanf((char *)args[0],(char *)args[1],args+2);
+	/* CMF - This makes a BIG assumption about va_list */
+	return vsscanf((char *) args[0], (char *) args[1], (va_list) &args[2]);
 }
 
 
diff --git a/misc/lstr.c b/misc/lstr.c
index 29c60ee..7f565ca 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -504,8 +504,8 @@
 	if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
 		from = HEAP_strdupA( GetProcessHeap(), 0, (LPSTR)lpSource);
 	if (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM) {
-		/* gather information from system message tables ... */
-		fprintf(stdnimp,"	- FORMAT_MESSAGE_FROM_SYSTEM not implemented.\n");
+		from = HeapAlloc( GetProcessHeap(),0,200 );
+		sprintf(from,"Systemmessage, messageid = 0x%08lx\n",dwMessageId);
 	}
 	if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE) {
 		INT32	bufsize;
@@ -585,7 +585,9 @@
 						sprintfbuf=HeapAlloc(GetProcessHeap(),0,strlen((LPSTR)argliststart[0])+1);
 					else
 						sprintfbuf=HeapAlloc(GetProcessHeap(),0,100);
-					vsprintf(sprintfbuf,fmtstr,argliststart);
+
+					/* CMF - This makes a BIG assumption about va_list */
+					vsprintf(sprintfbuf, fmtstr, (va_list) argliststart);
 					x=sprintfbuf;
 					while (*x) {
 						ADD_TO_T(*x++);
@@ -697,7 +699,8 @@
 		from = HEAP_strdupWtoA(GetProcessHeap(),0,(LPWSTR)lpSource);
 	if (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM) {
 		/* gather information from system message tables ... */
-		fprintf(stdnimp,"	- FORMAT_MESSAGE_FROM_SYSTEM not implemented.\n");
+		from = HeapAlloc( GetProcessHeap(),0,200 );
+		sprintf(from,"Systemmessage, messageid = 0x%08lx\n",dwMessageId);
 	}
 	if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE) {
 		INT32	bufsize;
@@ -783,10 +786,14 @@
 						xarr[1]=*(argliststart+1);
 						xarr[2]=*(argliststart+2);
 						sprintfbuf=HeapAlloc(GetProcessHeap(),0,lstrlen32W((LPWSTR)argliststart[0])*2+1);
-						vsprintf(sprintfbuf,fmtstr,xarr);
+
+						/* CMF - This makes a BIG assumption about va_list */
+						vsprintf(sprintfbuf, fmtstr, (va_list) xarr);
 					} else {
 						sprintfbuf=HeapAlloc(GetProcessHeap(),0,100);
-						vsprintf(sprintfbuf,fmtstr,argliststart);
+
+						/* CMF - This makes a BIG assumption about va_list */
+						vsprintf(sprintfbuf, fmtstr, (va_list) argliststart);
 					}
 					x=sprintfbuf;
 					while (*x) {
diff --git a/misc/ole2nls.c b/misc/ole2nls.c
index 66e2f36..ea6975d 100644
--- a/misc/ole2nls.c
+++ b/misc/ole2nls.c
@@ -6,7 +6,7 @@
 
 #include <string.h>
 #include <ctype.h>
-#include <malloc.h>
+#include <stdlib.h>
 #include "windows.h"
 #include "heap.h"
 #include "ole.h"
diff --git a/misc/registry.c b/misc/registry.c
index 668ebf8..2719bd3 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -7,7 +7,6 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#include <malloc.h>
 #include <unistd.h>
 #include <ctype.h>
 #include <errno.h>
@@ -669,7 +668,7 @@
 		else {
 			s++;
 			if (*s=='\\') {
-				*ws+='\\';
+				*ws++='\\';
 				s++;
 				continue;
 			}
diff --git a/misc/ver.c b/misc/ver.c
index b381f35..bd3d0b2 100644
--- a/misc/ver.c
+++ b/misc/ver.c
@@ -545,7 +545,7 @@
 	}
 	ret = LZCopy32(hfsrc,hfdst);
 	_lclose32(hfdst);
-	if (ret<0) {
+	if (((long) ret) < 0) {
 	    /* translate LZ errors into VIF_xxx */
 	    switch (ret) {
 	    case LZERROR_BADINHANDLE:
diff --git a/misc/winsock.c b/misc/winsock.c
index 6652b8a..b250184 100644
--- a/misc/winsock.c
+++ b/misc/winsock.c
@@ -186,7 +186,7 @@
  * sockets set in it that the program never asked for.
  */
 
-static int inline sock_error_p(int s)
+__inline__ static int sock_error_p(int s)
 {
     unsigned int optval, optlen;
 
@@ -704,7 +704,7 @@
   {
     int length, fromlen32 = *fromlen16;
 
-    if ((length = recvfrom(pws->fd, buf, len, flags, from, &fromlen32)) >= 0 );
+    if ((length = recvfrom(pws->fd, buf, len, flags, from, &fromlen32)) >= 0)
     {   
       *fromlen16 = fromlen32; 
        notify_client(pws, WS_FD_READ);
diff --git a/msdos/dpmi.c b/msdos/dpmi.c
index 4ad248e..408e6dc 100644
--- a/msdos/dpmi.c
+++ b/msdos/dpmi.c
@@ -296,6 +296,7 @@
             		SET_CFLAG(context);
 			break;
 		    }
+		    break;
 		default:
             	    SET_CFLAG(context);
 		    break;
diff --git a/msdos/int21.c b/msdos/int21.c
index 08ee577..4af3a53 100644
--- a/msdos/int21.c
+++ b/msdos/int21.c
@@ -227,7 +227,7 @@
     RESET_CFLAG(context);
 }
 
-static void ioctlGenericBlkDevReq( CONTEXT *context )
+static BOOL32 ioctlGenericBlkDevReq( CONTEXT *context )
 {
 	BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS_reg(context), DX_reg(context));
 	int drive = DOS_GET_DRIVE( BL_reg(context) );
@@ -235,20 +235,21 @@
 	if (!DRIVE_IsValid(drive))
         {
             DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk );
-            AX_reg(context) = DOS_ExtendedError;
-            SET_CFLAG(context);
-            return;
+            return TRUE;
 	}
 
 	if (CH_reg(context) != 0x08)
         {
             INT_BARF( context, 0x21 );
-            return;
+            return FALSE;
 	}
-	switch (CL_reg(context)) {
+
+	switch (CL_reg(context)) 
+	{
 		case 0x4a: /* lock logical volume */
 			dprintf_int(stddeb,"int21: lock logical volume (%d) level %d mode %d\n",drive,BH_reg(context),DX_reg(context));
-			return;
+			break;
+
 		case 0x60: /* get device parameters */
 			   /* used by w4wgrp's winfile */
 			memset(dataptr, 0, 0x26);
@@ -268,9 +269,11 @@
 			}
 			CreateBPB(drive, &dataptr[7]);			
 			RESET_CFLAG(context);
-			return;
+			break;
+
 		case 0x66:/*  get disk serial number */
-			{	char	label[12],fsname[9],path[4];
+			{	
+				char	label[12],fsname[9],path[4];
 				DWORD	serial;
 
 				strcpy(path,"x:\\");path[0]=drive+'A';
@@ -281,14 +284,17 @@
 				memcpy(dataptr+2,&serial,4);
 				memcpy(dataptr+6,label	,11);
 				memcpy(dataptr+17,fsname,8);
-				return;
 			}
+			break;
+
 		case 0x6a:
 			dprintf_int(stddeb,"int21: logical volume %d unlocked.\n",drive);
-			return;
+			break;
+
 		default:
                         INT_BARF( context, 0x21 );
 	}
+	return FALSE;
 }
 
 static void INT21_GetSystemDate( CONTEXT *context )
@@ -308,15 +314,11 @@
     DX_reg(context) = (systime.wSecond << 8) | (systime.wMilliseconds / 10);
 }
 
-static void INT21_CreateFile( CONTEXT *context )
+static BOOL32 INT21_CreateFile( CONTEXT *context )
 {
     AX_reg(context) = _lcreat16( PTR_SEG_OFF_TO_LIN( DS_reg(context),
                                           DX_reg(context) ), CX_reg(context) );
-    if (AX_reg(context) == (WORD)HFILE_ERROR16)
-    {
-	AX_reg(context) = DOS_ExtendedError;
-	SET_CFLAG(context);
-    }
+    return (AX_reg(context) == (WORD)HFILE_ERROR16);
 }
 
 
@@ -406,92 +408,108 @@
     }
 }
 
-void ExtendedOpenCreateFile(CONTEXT *context )
+static BOOL32 INT21_ExtendedOpenCreateFile(CONTEXT *context )
 {
-  BYTE action=DL_reg(context);
+  BOOL32 bExtendedError = FALSE;
+  BYTE action = DL_reg(context);
+
   /* Shuffle arguments to call OpenExistingFile */
   AL_reg(context) = BL_reg(context);
   DX_reg(context) = SI_reg(context);
   /* BX,CX and DX should be preserved */
   OpenExistingFile(context);
-  if ((EFL_reg(context) & 0x0001)==0) 
-    { /* It exists */
+
+  if ((EFL_reg(context) & 0x0001) == 0) /* File exists */
+  {
+      UINT16	uReturnCX = 0;
+
       /* Now decide what do do */
-      if ((action & 0x07)== 0)
-	{
+
+      if ((action & 0x07) == 0)
+      {
 	  BX_reg(context) = AX_reg(context);
 	  CloseFile(context);
-	  AX_reg(context) = 0x0050;/*File exists*/
-	  CX_reg(context) = 0;
+	  AX_reg(context) = 0x0050;	/*File exists*/
 	  SET_CFLAG(context);
-	  dprintf_int(stddeb, "int21: extended open/create: failed because file exixts \n");
-	  return;
-	}
-      if ((action & 0x07)== 2) {
-	/* Truncate it, but first check if opened for write */
-	if ((BL_reg(context) & 0x0007)== 0) {
-	  BX_reg(context) = AX_reg(context);
-	  CloseFile(context);
-	  dprintf_int(stddeb, "int21: extended open/create: failed, trunc on ro file");
-	  AX_reg(context) = 0x000C;/*Access code invalid*/
-	  CX_reg(context) = 0;
-	  SET_CFLAG(context);
-	  return;
-	}
-	/* Shuffle arguments to call CloseFile */
-	dprintf_int(stddeb, "int21: extended open/create: Closing before truncate\n");
-	BX_reg(context) = AX_reg(context);
-	/* BX and DX should be preserved */
-	CloseFile(context);
-	if (EFL_reg(context) & 0x0001) {
-	  dprintf_int(stddeb, "int21: extended open/create: close before trunc failed");
-	  AX_reg(context) = 0x0019;/*Seek Error*/
-	  CX_reg(context) = 0;
-	  SET_CFLAG(context);
-	}
-	/* Shuffle arguments to call CreateFile */
-	dprintf_int(stddeb, "int21: extended open/create: Truncating\n");
-	AL_reg(context) = BL_reg(context);
-	/* CX is still the same */
-	DX_reg(context) = SI_reg(context);
-	INT21_CreateFile(context);
-	if (EFL_reg(context) & 0x0001) { /*no file open, flags set */
-	  dprintf_int(stddeb, "int21: extended open/create: trunc failed");
-	  return;
-	}
-	CX_reg(context) = 3;
-	return;
+	  dprintf_int(stddeb, "int21: extended open/create: failed because file exists \n");
       }
-      CX_reg(context) = 1;
-      return;
-    }
+      else if ((action & 0x07) == 2) 
+      {
+	/* Truncate it, but first check if opened for write */
+	if ((BL_reg(context) & 0x0007)== 0) 
+	{
+		  BX_reg(context) = AX_reg(context);
+		  CloseFile(context);
+		  dprintf_int(stddeb, "int21: extended open/create: failed, trunc on ro file");
+		  AX_reg(context) = 0x000C;	/*Access code invalid*/
+		  SET_CFLAG(context);
+	}
+	else
+	{
+		/* Shuffle arguments to call CloseFile while
+		 * preserving BX and DX */
+
+		dprintf_int(stddeb, "int21: extended open/create: Closing before truncate\n");
+		BX_reg(context) = AX_reg(context);
+		CloseFile(context);
+		if (EFL_reg(context) & 0x0001) 
+		{
+		   dprintf_int(stddeb, "int21: extended open/create: close before trunc failed");
+		   AX_reg(context) = 0x0019;	/*Seek Error*/
+		   CX_reg(context) = 0;
+		   SET_CFLAG(context);
+		}
+		/* Shuffle arguments to call CreateFile */
+
+		dprintf_int(stddeb, "int21: extended open/create: Truncating\n");
+		AL_reg(context) = BL_reg(context);
+		/* CX is still the same */
+		DX_reg(context) = SI_reg(context);
+		bExtendedError = INT21_CreateFile(context);
+
+		if (EFL_reg(context) & 0x0001) 	/*no file open, flags set */
+		{
+		    dprintf_int(stddeb, "int21: extended open/create: trunc failed");
+		    return bExtendedError;
+		}
+		uReturnCX = 0x3;
+	}
+      } 
+      else uReturnCX = 0x1;
+
+      CX_reg(context) = uReturnCX;
+  }
   else /* file does not exist */
-    {
+  {
       RESET_CFLAG(context); /* was set by OpenExistingFile(context) */
       if ((action & 0xF0)== 0)
       {
 	CX_reg(context) = 0;
 	SET_CFLAG(context);
 	dprintf_int(stddeb, "int21: extended open/create: failed, file dosen't exist\n");
-	return;
       }
-      /* Shuffle arguments to call CreateFile */
-      dprintf_int(stddeb, "int21: extended open/create: Creating\n");
-      AL_reg(context) = BL_reg(context);
-      /* CX should still be the same */
-      DX_reg(context) = SI_reg(context);
-      INT21_CreateFile(context);
-      if (EFL_reg(context) & 0x0001) { /*no file open, flags set */
-	dprintf_int(stddeb, "int21: extended open/create: create failed\n");
-	return;
+      else
+      {
+        /* Shuffle arguments to call CreateFile */
+        dprintf_int(stddeb, "int21: extended open/create: Creating\n");
+        AL_reg(context) = BL_reg(context);
+        /* CX should still be the same */
+        DX_reg(context) = SI_reg(context);
+        bExtendedError = INT21_CreateFile(context);
+        if (EFL_reg(context) & 0x0001)  /*no file open, flags set */
+	{
+  	    dprintf_int(stddeb, "int21: extended open/create: create failed\n");
+	    return bExtendedError;
+        }
+        CX_reg(context) = 2;
       }
-      CX_reg(context) = 2;
-      return;
-    }
+  }
+
+  return bExtendedError;
 }
 
 
-static void INT21_ChangeDir( CONTEXT *context )
+static BOOL32 INT21_ChangeDir( CONTEXT *context )
 {
     int drive;
     char *dirname = PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context));
@@ -503,11 +521,7 @@
         dirname += 2;
     }
     else drive = DRIVE_GetCurrentDrive();
-    if (!DRIVE_Chdir( drive, dirname ))
-    {
-        AX_reg(context) = DOS_ExtendedError;
-        SET_CFLAG(context);
-    }
+    return DRIVE_Chdir( drive, dirname );
 }
 
 
@@ -581,7 +595,7 @@
 }
 
 
-static int INT21_CreateTempFile( CONTEXT *context )
+static BOOL32 INT21_CreateTempFile( CONTEXT *context )
 {
     static int counter = 0;
     char *name = PTR_SEG_OFF_TO_LIN( DS_reg(context), DX_reg(context) );
@@ -595,14 +609,14 @@
         if ((AX_reg(context) = _lcreat_uniq( name, 0 )) != (WORD)HFILE_ERROR16)
         {
             dprintf_int( stddeb, "INT21_CreateTempFile: created %s\n", name );
-            return 1;
+            return TRUE;
         }
-        if (DOS_ExtendedError != ER_FileExists) return 0;
+        if (DOS_ExtendedError != ER_FileExists) return FALSE;
     }
 }
 
 
-static int INT21_GetCurrentDirectory( CONTEXT *context ) 
+static BOOL32 INT21_GetCurrentDirectory( CONTEXT *context ) 
 {
     int drive = DOS_GET_DRIVE( DL_reg(context) );
     char *ptr = (char *)PTR_SEG_OFF_TO_LIN( DS_reg(context), SI_reg(context) );
@@ -610,11 +624,11 @@
     if (!DRIVE_IsValid(drive))
     {
         DOS_ERROR( ER_InvalidDrive, EC_NotFound, SA_Abort, EL_Disk );
-        return 0;
+        return FALSE;
     }
-
     lstrcpyn32A( ptr, DRIVE_GetDosCwd(drive), 64 );
-    return 1;
+    AX_reg(context) = 0x0100;			     /* success return code */
+    return TRUE;
 }
 
 
@@ -885,6 +899,8 @@
  */
 void DOS3Call( CONTEXT *context )
 {
+    BOOL32	bSetDOSExtendedError = FALSE;
+
     dprintf_int( stddeb, "int21: AX=%04x BX=%04x CX=%04x DX=%04x "
                  "SI=%04x DI=%04x DS=%04x ES=%04x EFL=%08lx\n",
                  AX_reg(context), BX_reg(context), CX_reg(context),
@@ -1112,35 +1128,23 @@
         break;
 
     case 0x39: /* "MKDIR" - CREATE SUBDIRECTORY */
-        if (!CreateDirectory16( PTR_SEG_OFF_TO_LIN( DS_reg(context),
-                                                    DX_reg(context) ), NULL))
-        {
-            AX_reg(context) = DOS_ExtendedError;
-            SET_CFLAG(context);
-        }
+        bSetDOSExtendedError = (!CreateDirectory16( PTR_SEG_OFF_TO_LIN( DS_reg(context),
+                                                           DX_reg(context) ), NULL));
         break;
 	
     case 0x3a: /* "RMDIR" - REMOVE SUBDIRECTORY */
-        if (!RemoveDirectory16( PTR_SEG_OFF_TO_LIN( DS_reg(context),
-                                                    DX_reg(context) )))
-        {
-            AX_reg(context) = DOS_ExtendedError;
-            SET_CFLAG(context);
-        }
+        bSetDOSExtendedError = (!RemoveDirectory16( PTR_SEG_OFF_TO_LIN( DS_reg(context),
+                                                                 DX_reg(context) )));
         break;
 
     case 0x3b: /* "CHDIR" - SET CURRENT DIRECTORY */
-        INT21_ChangeDir(context);
+        bSetDOSExtendedError = !INT21_ChangeDir(context);
         break;
 	
     case 0x3c: /* "CREAT" - CREATE OR TRUNCATE FILE */
         AX_reg(context) = _lcreat16( PTR_SEG_OFF_TO_LIN( DS_reg(context),
                                     DX_reg(context) ), CX_reg(context) );
-        if (AX_reg(context) == (WORD)HFILE_ERROR16)
-        {
-            AX_reg(context) = DOS_ExtendedError;
-            SET_CFLAG(context);
-        }
+        bSetDOSExtendedError = (AX_reg(context) == (WORD)HFILE_ERROR16);
         break;
 
     case 0x3d: /* "OPEN" - OPEN EXISTING FILE */
@@ -1148,11 +1152,7 @@
         break;
 
     case 0x3e: /* "CLOSE" - CLOSE FILE */
-        if ((AX_reg(context) = _lclose16( BX_reg(context) )) != 0)
-        {
-            AX_reg(context) = DOS_ExtendedError;
-            SET_CFLAG(context);
-        }
+        bSetDOSExtendedError = ((AX_reg(context) = _lclose16( BX_reg(context) )) != 0);
         break;
 
     case 0x3f: /* "READ" - READ FROM FILE OR DEVICE */
@@ -1161,11 +1161,7 @@
                                        PTR_SEG_OFF_TO_SEGPTR( DS_reg(context),
                                                               DX_reg(context) ),
                                        CX_reg(context) );
-            if (result == -1)
-            {
-                AX_reg(context) = DOS_ExtendedError;
-                SET_CFLAG(context);
-            }
+            if (result == -1) bSetDOSExtendedError = TRUE;
             else AX_reg(context) = (WORD)result;
         }
         break;
@@ -1176,22 +1172,14 @@
                                      PTR_SEG_OFF_TO_LIN( DS_reg(context),
                                                          DX_reg(context) ),
                                      CX_reg(context) );
-            if (result == -1)
-            {
-                AX_reg(context) = DOS_ExtendedError;
-                SET_CFLAG(context);
-            }
+            if (result == -1) bSetDOSExtendedError = TRUE;
             else AX_reg(context) = (WORD)result;
         }
         break;
 
     case 0x41: /* "UNLINK" - DELETE FILE */
-        if (!DeleteFile32A( PTR_SEG_OFF_TO_LIN( DS_reg(context),
-                                                DX_reg(context) )))
-        {
-            AX_reg(context) = DOS_ExtendedError;
-            SET_CFLAG(context);
-        }		
+        bSetDOSExtendedError = (!DeleteFile32A( PTR_SEG_OFF_TO_LIN( DS_reg(context),
+                                                             DX_reg(context) )));
         break;
 
     case 0x42: /* "LSEEK" - SET CURRENT FILE POSITION */
@@ -1199,14 +1187,12 @@
             LONG status = _llseek16( BX_reg(context),
                                      MAKELONG(DX_reg(context),CX_reg(context)),
                                      AL_reg(context) );
-            if (status == -1)
-            {
-                AX_reg(context) = DOS_ExtendedError;
-                SET_CFLAG(context);
-                break;
-            }
-            AX_reg(context) = LOWORD(status);
-            DX_reg(context) = HIWORD(status);
+            if (status == -1) bSetDOSExtendedError = TRUE;
+	    else
+	    {
+            	AX_reg(context) = LOWORD(status);
+           	DX_reg(context) = HIWORD(status);
+	    }
         }
         break;
 
@@ -1217,21 +1203,15 @@
             AX_reg(context) = (WORD)GetFileAttributes32A(
                                           PTR_SEG_OFF_TO_LIN(DS_reg(context),
                                                              DX_reg(context)));
-            if (AX_reg(context) == 0xffff)
-            {
-                AX_reg(context) = DOS_ExtendedError;
-                SET_CFLAG(context);
-            }
+            if (AX_reg(context) == 0xffff) bSetDOSExtendedError = TRUE;
             else CX_reg(context) = AX_reg(context);
             break;
+
         case 0x01:
-            if (!SetFileAttributes32A( PTR_SEG_OFF_TO_LIN(DS_reg(context),
-                                                          DX_reg(context)),
-                                       CX_reg(context) ))
-            {
-                AX_reg(context) = DOS_ExtendedError;
-                SET_CFLAG(context);
-            }
+            bSetDOSExtendedError = 
+		(!SetFileAttributes32A( PTR_SEG_OFF_TO_LIN(DS_reg(context), 
+							   DX_reg(context)),
+                                       			   CX_reg(context) ));
             break;
         }
         break;
@@ -1312,8 +1292,9 @@
             break;
 
         case 0x0d:
-            ioctlGenericBlkDevReq(context);
+            bSetDOSExtendedError = ioctlGenericBlkDevReq(context);
             break;
+
 	case 0x0e: /* get logical drive mapping */
 	    AL_reg(context) = 0; /* drive has no mapping */
 	    break;
@@ -1333,31 +1314,17 @@
         break;
 
     case 0x45: /* "DUP" - DUPLICATE FILE HANDLE */
-        if ((AX_reg(context) = FILE_Dup(BX_reg(context))) == (WORD)HFILE_ERROR16)
-        {
-            AX_reg(context) = DOS_ExtendedError;
-            SET_CFLAG(context);
-        }
+        bSetDOSExtendedError = ((AX_reg(context) = FILE_Dup(BX_reg(context))) == (WORD)HFILE_ERROR16);
         break;
 
     case 0x46: /* "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE */
-        if (FILE_Dup2( BX_reg(context), CX_reg(context) ) == HFILE_ERROR32)
-        {
-            AX_reg(context) = DOS_ExtendedError;
-            SET_CFLAG(context);
-        }
-       else AX_reg(context) = 0x0100; 
-        /* intlist: many Microsoft products for Windows rely on this */
+        bSetDOSExtendedError = (FILE_Dup2( BX_reg(context), CX_reg(context) ) == HFILE_ERROR32);
         break;
 
     case 0x47: /* "CWD" - GET CURRENT DIRECTORY */
-        if (!INT21_GetCurrentDirectory(context))
-        {
-            AX_reg(context) = DOS_ExtendedError;
-            SET_CFLAG(context);
-        }
+        bSetDOSExtendedError = !INT21_GetCurrentDirectory(context);
         break;
-	
+
     case 0x48: /* ALLOCATE MEMORY */
     case 0x49: /* FREE MEMORY */
     case 0x4a: /* RESIZE MEMORY BLOCK */
@@ -1406,12 +1373,9 @@
         break;
 
     case 0x56: /* "RENAME" - RENAME FILE */
-        if (!MoveFile32A( PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context)),
-                          PTR_SEG_OFF_TO_LIN(ES_reg(context),DI_reg(context))))
-        {
-            AX_reg(context) = DOS_ExtendedError;
-            SET_CFLAG(context);
-        }
+        bSetDOSExtendedError = 
+		(!MoveFile32A( PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context)),
+			       PTR_SEG_OFF_TO_LIN(ES_reg(context),DI_reg(context))));
         break;
 
     case 0x57: /* FILE DATE AND TIME */
@@ -1421,10 +1385,7 @@
             {
                 FILETIME filetime;
                 if (!GetFileTime( BX_reg(context), NULL, NULL, &filetime ))
-                {
-                    AX_reg(context) = DOS_ExtendedError;
-                    SET_CFLAG(context);
-                }
+		     bSetDOSExtendedError = TRUE;
                 else FileTimeToDosDateTime( &filetime, &DX_reg(context),
                                             &CX_reg(context) );
             }
@@ -1435,11 +1396,8 @@
                 FILETIME filetime;
                 DosDateTimeToFileTime( DX_reg(context), CX_reg(context),
                                        &filetime );
-                if (!SetFileTime( BX_reg(context), NULL, NULL, &filetime ))
-                {
-                    AX_reg(context) = DOS_ExtendedError;
-                    SET_CFLAG(context);
-                }
+                bSetDOSExtendedError = 
+			(!SetFileTime( BX_reg(context), NULL, NULL, &filetime ));
             }
             break;
         }
@@ -1462,27 +1420,20 @@
         break;
 
     case 0x5a: /* CREATE TEMPORARY FILE */
-        if (!INT21_CreateTempFile(context))
-        {
-            AX_reg(context) = DOS_ExtendedError;
-            SET_CFLAG(context);
-        }
+        bSetDOSExtendedError = !INT21_CreateTempFile(context);
         break;
 
     case 0x5b: /* CREATE NEW FILE */
-        if ((AX_reg(context) = _lcreat_uniq( PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context)), 0 )) == (WORD)HFILE_ERROR16)
-        {
-            AX_reg(context) = DOS_ExtendedError;
-            SET_CFLAG(context);
-        }
+        bSetDOSExtendedError = ((AX_reg(context) = 
+		_lcreat_uniq( PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context)), 0 )) 
+								== (WORD)HFILE_ERROR16);
         break;
 
     case 0x5d: /* NETWORK */
     case 0x5e:
         /* network software not installed */
         DOS_ERROR( ER_NoNetwork, EC_NotFound, SA_Abort, EL_Network );
-        AX_reg(context) = DOS_ExtendedError;
-        SET_CFLAG(context);
+	bSetDOSExtendedError = TRUE;
         break;
 
     case 0x5f: /* NETWORK */
@@ -1492,8 +1443,7 @@
             if (!DRIVE_Enable( DL_reg(context) ))
             {
                 DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk );
-                AX_reg(context) = DOS_ExtendedError;
-                SET_CFLAG(context);
+		bSetDOSExtendedError = TRUE;
             }
             break;
 
@@ -1501,16 +1451,14 @@
             if (!DRIVE_Disable( DL_reg(context) ))
             {
                 DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk );
-                AX_reg(context) = DOS_ExtendedError;
-                SET_CFLAG(context);
+		bSetDOSExtendedError = TRUE;
             } 
             break;
 
         default:
             /* network software not installed */
             DOS_ERROR( ER_NoNetwork, EC_NotFound, SA_Abort, EL_Network );
-            AX_reg(context) = DOS_ExtendedError;
-            SET_CFLAG(context);
+	    bSetDOSExtendedError = TRUE;
             break;
         }
         break;
@@ -1521,10 +1469,7 @@
                                                         SI_reg(context)), 128,
                                      PTR_SEG_OFF_TO_LIN(ES_reg(context),
                                                         DI_reg(context)),NULL))
-            {
-                AX_reg(context) = DOS_ExtendedError;
-                SET_CFLAG(context);
-            }
+		bSetDOSExtendedError = TRUE;
             else AX_reg(context) = 0;
         }
         break;
@@ -1535,6 +1480,7 @@
         INT_BARF( context, 0x21 );
         SET_CFLAG(context);
     	break;
+
     case 0x65:{/* GET EXTENDED COUNTRY INFORMATION */
     	extern WORD WINE_LanguageId;
 	BYTE    *dataptr=PTR_SEG_OFF_TO_LIN(ES_reg(context),DI_reg(context));;
@@ -1573,66 +1519,45 @@
 
     case 0x67: /* SET HANDLE COUNT */
         SetHandleCount16( BX_reg(context) );
-        if (DOS_ExtendedError)
-        {
-            AX_reg(context) = DOS_ExtendedError;
-            SET_CFLAG(context);
-        }
+        if (DOS_ExtendedError) bSetDOSExtendedError = TRUE;
         break;
 
     case 0x68: /* "FFLUSH" - COMMIT FILE */
     case 0x6a: /* COMMIT FILE */
-        if (!FlushFileBuffers( BX_reg(context) ))
-        {
-            AX_reg(context) = DOS_ExtendedError;
-            SET_CFLAG(context);
-        }
+        bSetDOSExtendedError = (!FlushFileBuffers( BX_reg(context) ));
         break;		
 	
     case 0x69: /* DISK SERIAL NUMBER */
         switch (AL_reg(context))
         {
         case 0x00:
-            if (!INT21_GetDiskSerialNumber(context))
-            {
-                AX_reg(context) = DOS_ExtendedError;
-                SET_CFLAG(context);
-            }
+            if (!INT21_GetDiskSerialNumber(context)) bSetDOSExtendedError = TRUE;
             else AX_reg(context) = 0;
             break;
+
         case 0x01:
-            if (!INT21_SetDiskSerialNumber(context))
-            {
-                AX_reg(context) = DOS_ExtendedError;
-                SET_CFLAG(context);
-            }
+            if (!INT21_SetDiskSerialNumber(context)) bSetDOSExtendedError = TRUE;
             else AX_reg(context) = 1;
             break;
         }
         break;
     
     case 0x6C: /* Extended Open/Create*/
-        ExtendedOpenCreateFile(context);
+        bSetDOSExtendedError = INT21_ExtendedOpenCreateFile(context);
         break;
 	
     case 0x71: /* MS-DOS 7 (Windows95) - LONG FILENAME FUNCTIONS */
         switch(AL_reg(context))
         {
         case 0x39:  /* Create directory */
-            if (!CreateDirectory32A( PTR_SEG_OFF_TO_LIN( DS_reg(context),
-                                                     DX_reg(context) ), NULL))
-            {
-                AX_reg(context) = DOS_ExtendedError;
-                SET_CFLAG(context);
-            }
+            bSetDOSExtendedError = (!CreateDirectory32A( 
+					PTR_SEG_OFF_TO_LIN( DS_reg(context),
+                                                  DX_reg(context) ), NULL));
             break;
         case 0x3a:  /* Remove directory */
-            if (!RemoveDirectory32A( PTR_SEG_OFF_TO_LIN( DS_reg(context),
-                                                         DX_reg(context) )))
-            {
-                AX_reg(context) = DOS_ExtendedError;
-                SET_CFLAG(context);
-            }
+            bSetDOSExtendedError = (!RemoveDirectory32A( 
+					PTR_SEG_OFF_TO_LIN( DS_reg(context),
+                                                        DX_reg(context) )));
             break;
         case 0x43:  /* Get/Set file attributes */
         switch (BL_reg(context))
@@ -1641,20 +1566,13 @@
             CX_reg(context) = (WORD)GetFileAttributes32A(
                                           PTR_SEG_OFF_TO_LIN(DS_reg(context),
                                                              DX_reg(context)));
-            if (CX_reg(context) == 0xffff)
-            {
-                AX_reg(context) = DOS_ExtendedError;
-                SET_CFLAG(context);
-            }
+            if (CX_reg(context) == 0xffff) bSetDOSExtendedError = TRUE;
             break;
         case 0x01:
-            if (!SetFileAttributes32A( PTR_SEG_OFF_TO_LIN(DS_reg(context),
-                                                          DX_reg(context)),
-                                       CX_reg(context) ))
-            {
-                AX_reg(context) = DOS_ExtendedError;
-                SET_CFLAG(context);
-            }
+            bSetDOSExtendedError = (!SetFileAttributes32A( 
+				  	PTR_SEG_OFF_TO_LIN(DS_reg(context),
+                                                           DX_reg(context)),
+                                        CX_reg(context)  ) );
             break;
 	default:
 	  fprintf( stderr, 
@@ -1666,14 +1584,9 @@
 	}
 	break;
         case 0x47:  /* Get current directory */
-	  if (!INT21_GetCurrentDirectory(context))
-	    {
-	      AX_reg(context) = DOS_ExtendedError;
-	      SET_CFLAG(context);
-	    }
-	  else AX_reg(context) = 0x0100; 
-        /* intlist: many Microsoft products for Windows rely on this */
-        break;
+	    bSetDOSExtendedError = !INT21_GetCurrentDirectory(context);
+            break;
+
         case 0x4e:  /* Find first file */
             /* FIXME: use attributes in CX */
             if ((AX_reg(context) = FindFirstFile16(
@@ -1681,42 +1594,29 @@
                    (WIN32_FIND_DATA32A *)PTR_SEG_OFF_TO_LIN(ES_reg(context),
                                                             DI_reg(context))))
 		== INVALID_HANDLE_VALUE16)
-            {
-                AX_reg(context) = DOS_ExtendedError;
-                SET_CFLAG(context);
-            }
+		bSetDOSExtendedError = TRUE;
             break;
         case 0x4f:  /* Find next file */
             if (!FindNextFile16( BX_reg(context),
                     (WIN32_FIND_DATA32A *)PTR_SEG_OFF_TO_LIN(ES_reg(context),
                                                              DI_reg(context))))
-            {
-                AX_reg(context) = DOS_ExtendedError;
-                SET_CFLAG(context);
-            }
+		bSetDOSExtendedError = TRUE;
             break;
         case 0xa1:  /* Find close */
-            if (!FindClose16( BX_reg(context) ))
-            {
-                AX_reg(context) = DOS_ExtendedError;
-                SET_CFLAG(context);
-            }
+            bSetDOSExtendedError = (!FindClose16( BX_reg(context) ));
             break;
 	case 0xa0:
 	    break;
         case 0x60:  
 	  switch(CL_reg(context))
-	    {
+	  {
 	    case 0x02:  /*Get canonical long filename or path */
 	      if (!GetFullPathName32A
 		  ( PTR_SEG_OFF_TO_LIN(DS_reg(context),
 				       SI_reg(context)), 128,
 		    PTR_SEG_OFF_TO_LIN(ES_reg(context),
 				       DI_reg(context)),NULL))
-		{
-		  AX_reg(context) = DOS_ExtendedError;
-		  SET_CFLAG(context);
-		}
+		bSetDOSExtendedError = TRUE;
 	      else AX_reg(context) = 0;
 	      break;
 	    default:
@@ -1726,13 +1626,23 @@
 	      SET_CFLAG(context);
 	      AL_reg(context) = 0;
 	      break;
-	    }
+	  }
 	    break;
         case 0x6c:  /* Create or open file */
 	  /* translate Dos 7 action to Dos 6 action */
-	    ExtendedOpenCreateFile(context);
+	    bSetDOSExtendedError = INT21_ExtendedOpenCreateFile(context);
 	    break;
+
         case 0x3b:  /* Change directory */
+	    if (!SetCurrentDirectory32A(PTR_SEG_OFF_TO_LIN(
+	    					DS_reg(context),
+				        	DX_reg(context)
+					))
+	    ) {
+		SET_CFLAG(context);
+		AL_reg(context) = DOS_ExtendedError;
+	    }
+	    break;
         case 0x41:  /* Delete file */
         case 0x56:  /* Move (rename) file */
         default:
@@ -1761,7 +1671,15 @@
     default:
         INT_BARF( context, 0x21 );
         break;
+
+    } /* END OF SWITCH */
+
+    if( bSetDOSExtendedError )		/* set general error condition */
+    {   
+	AX_reg(context) = DOS_ExtendedError;
+	SET_CFLAG(context);
     }
+
     dprintf_int( stddeb, "ret21: AX=%04x BX=%04x CX=%04x DX=%04x "
                  "SI=%04x DI=%04x DS=%04x ES=%04x EFL=%08lx\n",
                  AX_reg(context), BX_reg(context), CX_reg(context),
@@ -1769,3 +1687,4 @@
                  (WORD)DS_reg(context), (WORD)ES_reg(context),
                  EFL_reg(context));
 }
+
diff --git a/multimedia/audio.c b/multimedia/audio.c
index 932d1f9..558466f 100644
--- a/multimedia/audio.c
+++ b/multimedia/audio.c
@@ -211,8 +211,8 @@
 	lpDesc->lpFormat = (LPWAVEFORMAT) USER_HEAP_LIN_ADDR(hFormat);
 	memcpy(lpDesc->lpFormat, lpWaveFormat, sizeof(PCMWAVEFORMAT));
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_SEG_ADDR(hDesc);
-	dwRet = wodMessage(wDevID, WODM_OPEN, 0, (DWORD)lpDesc, CALLBACK_NULL);
-	dwRet = widMessage(wDevID, WIDM_OPEN, 0, (DWORD)lpDesc, CALLBACK_NULL);
+	dwRet = wodMessage(index, WODM_OPEN, 0, (DWORD)lpDesc, CALLBACK_NULL);
+	dwRet = widMessage(index, WIDM_OPEN, 0, (DWORD)lpDesc, CALLBACK_NULL);
 	USER_HEAP_FREE(hFormat);
 	USER_HEAP_FREE(hDesc);
 	return 0;
@@ -233,9 +233,9 @@
 			mmioClose(MCIWavDev[index].hFile, 0);
 			MCIWavDev[index].hFile = 0;
 			}
-		dwRet = wodMessage(wDevID, WODM_CLOSE, 0, 0L, 0L);
+		dwRet = wodMessage(index, WODM_CLOSE, 0, 0L, 0L);
 		if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
-		dwRet = widMessage(wDevID, WIDM_CLOSE, 0, 0L, 0L);
+		dwRet = widMessage(index, WIDM_CLOSE, 0, 0L, 0L);
 		if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
 		}
 	return 0;
@@ -300,7 +300,7 @@
 	lp16WaveHdr = (LPWAVEHDR) USER_HEAP_SEG_ADDR(hWaveHdr);
 	memcpy(PTR_SEG_TO_LIN(lp16WaveHdr), lpWaveHdr, sizeof(WAVEHDR));
 	lpWaveHdr = PTR_SEG_TO_LIN(lp16WaveHdr);
-	dwRet = wodMessage(wDevID, WODM_PREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
+	dwRet = wodMessage(index, WODM_PREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
 	while(TRUE) {
 		count = mmioRead(MCIWavDev[index].hFile, 
 			PTR_SEG_TO_LIN(lpWaveHdr->lpData), bufsize);
@@ -310,9 +310,9 @@
 /*		lpWaveHdr->dwBytesRecorded = count; */
 		dprintf_mciwave(stddeb,"WAVE_mciPlay // before WODM_WRITE lpWaveHdr=%p dwBufferLength=%lu dwBytesRecorded=%lu\n",
 				lpWaveHdr, lpWaveHdr->dwBufferLength, lpWaveHdr->dwBytesRecorded);
-		dwRet = wodMessage(wDevID, WODM_WRITE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
+		dwRet = wodMessage(index, WODM_WRITE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
 		}
-	dwRet = wodMessage(wDevID, WODM_UNPREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
+	dwRet = wodMessage(index, WODM_UNPREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
 	if (lpWaveHdr->lpData != NULL) {
 		GlobalUnlock16(hData);
 		GlobalFree16(hData);
@@ -371,18 +371,18 @@
 	lp16WaveHdr = (LPWAVEHDR) USER_HEAP_SEG_ADDR(hWaveHdr);
 	memcpy(PTR_SEG_TO_LIN(lp16WaveHdr), lpWaveHdr, sizeof(WAVEHDR));
 	lpWaveHdr = PTR_SEG_TO_LIN(lp16WaveHdr);
-	dwRet = widMessage(wDevID, WIDM_PREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
+	dwRet = widMessage(index, WIDM_PREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
     dprintf_mciwave(stddeb,"WAVE_mciRecord // after WIDM_PREPARE \n");
 	while(TRUE) {
 		lpWaveHdr->dwBytesRecorded = 0;
-		dwRet = widMessage(wDevID, WIDM_START, 0, 0L, 0L);
+		dwRet = widMessage(index, WIDM_START, 0, 0L, 0L);
 		dprintf_mciwave(stddeb,
                     "WAVE_mciRecord // after WIDM_START lpWaveHdr=%p dwBytesRecorded=%lu\n",
 					lpWaveHdr, lpWaveHdr->dwBytesRecorded);
 		if (lpWaveHdr->dwBytesRecorded == 0) break;
 		}
 	dprintf_mciwave(stddeb,"WAVE_mciRecord // before WIDM_UNPREPARE \n");
-	dwRet = widMessage(wDevID, WIDM_UNPREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
+	dwRet = widMessage(index, WIDM_UNPREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
 	dprintf_mciwave(stddeb,"WAVE_mciRecord // after WIDM_UNPREPARE \n");
 	if (lpWaveHdr->lpData != NULL) {
 		GlobalUnlock16(hData);
@@ -759,7 +759,6 @@
 */
 static DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
 {
-	int index = MMSYSTEM_DevIDToIndex(wDevID);
 	int 		audio;
 	int			abuf_size;
 	int			smplrate;
@@ -777,7 +776,7 @@
 		dprintf_mciwave(stddeb,"Linux 'wodOpen' // MAX_WAVOUTDRV reached !\n");
 		return MMSYSERR_ALLOCATED;
 		}
-	WOutDev[index].unixdev = 0;
+	WOutDev[wDevID].unixdev = 0;
 	audio = open (SOUND_DEV, O_WRONLY, 0);
 	if (audio == -1) {
 		dprintf_mciwave(stddeb,"Linux 'wodOpen' // can't open !\n");
@@ -791,8 +790,8 @@
 			dprintf_mciwave(stddeb,"Linux 'wodOpen' // SNDCTL_DSP_GETBLKSIZE Invalid bufsize !\n");
 		return MMSYSERR_NOTENABLED;
 		}
-	WOutDev[index].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
-	switch(WOutDev[index].wFlags) {
+	WOutDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
+	switch(WOutDev[wDevID].wFlags) {
 		case DCB_NULL:
 			dprintf_mciwave(stddeb,	"Linux 'wodOpen' // CALLBACK_NULL !\n");
 			break;
@@ -806,13 +805,12 @@
 			dprintf_mciwave(stddeb,	"Linux 'wodOpen' // CALLBACK_FUNCTION !\n");
 			break;
 		}
-	WOutDev[index].lpQueueHdr = NULL;
-	WOutDev[index].unixdev = audio;
-	WOutDev[index].dwTotalPlayed = 0;
-	WOutDev[index].bufsize = abuf_size;
-	memcpy(&WOutDev[index].waveDesc, lpDesc, sizeof(WAVEOPENDESC));
-/*	lpFormat = (LPWAVEFORMAT) PTR_SEG_TO_LIN(lpDesc->lpFormat); */
-	lpFormat = lpDesc->lpFormat;
+	WOutDev[wDevID].lpQueueHdr = NULL;
+	WOutDev[wDevID].unixdev = audio;
+	WOutDev[wDevID].dwTotalPlayed = 0;
+	WOutDev[wDevID].bufsize = abuf_size;
+	memcpy(&WOutDev[wDevID].waveDesc, lpDesc, sizeof(WAVEOPENDESC));
+        lpFormat = (LPWAVEFORMAT) PTR_SEG_TO_LIN(lpDesc->lpFormat); 
 	if (lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
 		dprintf_mciwave(stddeb,"Linux 'wodOpen' // Bad format %04X !\n",
 				lpFormat->wFormatTag);
@@ -822,31 +820,31 @@
 				lpFormat->nSamplesPerSec);
 		return WAVERR_BADFORMAT;
 		}
-	memcpy(&WOutDev[index].Format, lpFormat, sizeof(PCMWAVEFORMAT));
-	if (WOutDev[index].Format.wf.nChannels == 0) return WAVERR_BADFORMAT;
-	if (WOutDev[index].Format.wf.nSamplesPerSec == 0) return WAVERR_BADFORMAT;
+	memcpy(&WOutDev[wDevID].Format, lpFormat, sizeof(PCMWAVEFORMAT));
+	if (WOutDev[wDevID].Format.wf.nChannels == 0) return WAVERR_BADFORMAT;
+	if (WOutDev[wDevID].Format.wf.nSamplesPerSec == 0) return WAVERR_BADFORMAT;
 	dprintf_mciwave(stddeb,"Linux 'wodOpen' // wBitsPerSample=%u !\n",
-				WOutDev[index].Format.wBitsPerSample);
-	if (WOutDev[index].Format.wBitsPerSample == 0) {
-		WOutDev[index].Format.wBitsPerSample = 8 *
-		(WOutDev[index].Format.wf.nAvgBytesPerSec /
-		WOutDev[index].Format.wf.nSamplesPerSec) /
-		WOutDev[index].Format.wf.nChannels;
+				WOutDev[wDevID].Format.wBitsPerSample);
+	if (WOutDev[wDevID].Format.wBitsPerSample == 0) {
+		WOutDev[wDevID].Format.wBitsPerSample = 8 *
+		(WOutDev[wDevID].Format.wf.nAvgBytesPerSec /
+		WOutDev[wDevID].Format.wf.nSamplesPerSec) /
+		WOutDev[wDevID].Format.wf.nChannels;
 		}
-	samplesize = WOutDev[index].Format.wBitsPerSample;
-	smplrate = WOutDev[index].Format.wf.nSamplesPerSec;
-	dsp_stereo = (WOutDev[index].Format.wf.nChannels > 1) ? TRUE : FALSE;
+	samplesize = WOutDev[wDevID].Format.wBitsPerSample;
+	smplrate = WOutDev[wDevID].Format.wf.nSamplesPerSec;
+	dsp_stereo = (WOutDev[wDevID].Format.wf.nChannels > 1) ? TRUE : FALSE;
 	IOCTL(audio, SNDCTL_DSP_SPEED, smplrate);
 	IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize);
 	IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo);
 	dprintf_mciwave(stddeb,"Linux 'wodOpen' // wBitsPerSample=%u !\n",
-				WOutDev[index].Format.wBitsPerSample);
+				WOutDev[wDevID].Format.wBitsPerSample);
 	dprintf_mciwave(stddeb,"Linux 'wodOpen' // nAvgBytesPerSec=%lu !\n",
-				WOutDev[index].Format.wf.nAvgBytesPerSec);
+				WOutDev[wDevID].Format.wf.nAvgBytesPerSec);
 	dprintf_mciwave(stddeb,"Linux 'wodOpen' // nSamplesPerSec=%lu !\n",
-				WOutDev[index].Format.wf.nSamplesPerSec);
+				WOutDev[wDevID].Format.wf.nSamplesPerSec);
 	dprintf_mciwave(stddeb,"Linux 'wodOpen' // nChannels=%u !\n",
-				WOutDev[index].Format.wf.nChannels);
+				WOutDev[wDevID].Format.wf.nChannels);
 	if (WAVE_NotifyClient(wDevID, WOM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
 		dprintf_mciwave(stddeb,"Linux 'wodOpen' // can't notify client !\n");
 		return MMSYSERR_INVALPARAM;
@@ -859,16 +857,15 @@
 */
 static DWORD wodClose(WORD wDevID)
 {
-	int index = MMSYSTEM_DevIDToIndex(wDevID);
 	dprintf_mciwave(stddeb,"wodClose(%u);\n", wDevID);
-	if (WOutDev[index].unixdev == 0) {
+	if (WOutDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'wodClose' // can't close !\n");
 		return MMSYSERR_NOTENABLED;
 		}
-	close(WOutDev[index].unixdev);
-	WOutDev[index].unixdev = 0;
-	WOutDev[index].bufsize = 0;
-	WOutDev[index].lpQueueHdr = NULL;
+	close(WOutDev[wDevID].unixdev);
+	WOutDev[wDevID].unixdev = 0;
+	WOutDev[wDevID].bufsize = 0;
+	WOutDev[wDevID].lpQueueHdr = NULL;
 	if (WAVE_NotifyClient(wDevID, WOM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
 		dprintf_mciwave(stddeb,"Linux 'wodClose' // can't notify client !\n");
 		return MMSYSERR_INVALPARAM;
@@ -881,11 +878,10 @@
 */
 static DWORD wodWrite(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
-	int index = MMSYSTEM_DevIDToIndex(wDevID);
 	int		count;
 	LPSTR	lpData;
 	dprintf_mciwave(stddeb,"wodWrite(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
-	if (WOutDev[index].unixdev == 0) {
+	if (WOutDev[wDevID].unixdev == 0) {
         dprintf_mciwave(stddeb,"Linux 'wodWrite' // can't play !\n");
 		return MMSYSERR_NOTENABLED;
 		}
@@ -897,16 +893,16 @@
 	dprintf_mciwave(stddeb,
 		"wodWrite() // dwBufferLength %lu !\n", lpWaveHdr->dwBufferLength);
 	dprintf_mciwave(stddeb,
-		"wodWrite() // WOutDev[%u].unixdev %u !\n", wDevID, WOutDev[index].unixdev);
+		"wodWrite() // WOutDev[%u].unixdev %u !\n", wDevID, WOutDev[wDevID].unixdev);
 	lpData = PTR_SEG_TO_LIN(lpWaveHdr->lpData);
-	count = write (WOutDev[index].unixdev, lpData, lpWaveHdr->dwBufferLength);
+	count = write (WOutDev[wDevID].unixdev, lpData, lpWaveHdr->dwBufferLength);
 	dprintf_mciwave(stddeb,
 		"wodWrite() // write returned count %u !\n", count);
 	if (count != lpWaveHdr->dwBufferLength) {
 		dprintf_mciwave(stddeb,"Linux 'wodWrite' // error writting !\n");
 		return MMSYSERR_NOTENABLED;
 		}
-	WOutDev[index].dwTotalPlayed += count;
+	WOutDev[wDevID].dwTotalPlayed += count;
 	lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
 	lpWaveHdr->dwFlags |= WHDR_DONE;
 	if (WAVE_NotifyClient(wDevID, WOM_DONE, 0L, 0L) != MMSYSERR_NOERROR) {
@@ -921,22 +917,21 @@
 */
 static DWORD wodPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
-	int index = MMSYSTEM_DevIDToIndex(wDevID);
 	dprintf_mciwave(stddeb,
 		"wodPrepare(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
-	if (WOutDev[index].unixdev == 0) {
+	if (WOutDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'wodPrepare' // can't prepare !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	/* the COOL waveeditor feels much better without this check... 
 	 * someone please have a look at available documentation
-	if (WOutDev[index].lpQueueHdr != NULL) {
+	if (WOutDev[wDevID].lpQueueHdr != NULL) {
 		dprintf_mciwave(stddeb,"Linux 'wodPrepare' // already prepare !\n");
 		return MMSYSERR_NOTENABLED;
 	}
 	*/
-	WOutDev[index].dwTotalPlayed = 0;
-	WOutDev[index].lpQueueHdr = lpWaveHdr;
+	WOutDev[wDevID].dwTotalPlayed = 0;
+	WOutDev[wDevID].lpQueueHdr = lpWaveHdr;
 	if (lpWaveHdr->dwFlags & WHDR_INQUEUE) return WAVERR_STILLPLAYING;
 	lpWaveHdr->dwFlags |= WHDR_PREPARED;
 	lpWaveHdr->dwFlags &= ~WHDR_DONE;
@@ -948,10 +943,9 @@
 */
 static DWORD wodUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
-	int index = MMSYSTEM_DevIDToIndex(wDevID);
 	dprintf_mciwave(stddeb,
 		"wodUnprepare(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
-	if (WOutDev[index].unixdev == 0) {
+	if (WOutDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'wodUnprepare' // can't unprepare !\n");
 		return MMSYSERR_NOTENABLED;
 		}
@@ -963,9 +957,8 @@
 */
 static DWORD wodRestart(WORD wDevID)
 {
-	int index = MMSYSTEM_DevIDToIndex(wDevID);
 	dprintf_mciwave(stddeb,"wodRestart(%u);\n", wDevID);
-	if (WOutDev[index].unixdev == 0) {
+	if (WOutDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'wodRestart' // can't restart !\n");
 		return MMSYSERR_NOTENABLED;
 		}
@@ -977,9 +970,8 @@
 */
 static DWORD wodReset(WORD wDevID)
 {
-	int index = MMSYSTEM_DevIDToIndex(wDevID);
 	dprintf_mciwave(stddeb,"wodReset(%u);\n", wDevID);
-	if (WOutDev[index].unixdev == 0) {
+	if (WOutDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'wodReset' // can't reset !\n");
 		return MMSYSERR_NOTENABLED;
 		}
@@ -992,31 +984,30 @@
 */
 static DWORD wodGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
 {
-	int index = MMSYSTEM_DevIDToIndex(wDevID);
 	int		time;
 	dprintf_mciwave(stddeb,"wodGetPosition(%u, %p, %lu);\n", wDevID, lpTime, uSize);
-	if (WOutDev[index].unixdev == 0) {
+	if (WOutDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'wodGetPosition' // can't get pos !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	if (lpTime == NULL)	return MMSYSERR_INVALPARAM;
 	switch(lpTime->wType) {
 		case TIME_BYTES:
-			lpTime->u.cb = WOutDev[index].dwTotalPlayed;
+			lpTime->u.cb = WOutDev[wDevID].dwTotalPlayed;
 			dprintf_mciwave(stddeb,"wodGetPosition // TIME_BYTES=%lu\n", lpTime->u.cb);
 			break;
 		case TIME_SAMPLES:
 			dprintf_mciwave(stddeb,"wodGetPosition // dwTotalPlayed=%lu\n", 
-					WOutDev[index].dwTotalPlayed);
+					WOutDev[wDevID].dwTotalPlayed);
 			dprintf_mciwave(stddeb,"wodGetPosition // wBitsPerSample=%u\n", 
-					WOutDev[index].Format.wBitsPerSample);
-			lpTime->u.sample = WOutDev[index].dwTotalPlayed * 8 /
-						WOutDev[index].Format.wBitsPerSample;
+					WOutDev[wDevID].Format.wBitsPerSample);
+			lpTime->u.sample = WOutDev[wDevID].dwTotalPlayed * 8 /
+						WOutDev[wDevID].Format.wBitsPerSample;
 			dprintf_mciwave(stddeb,"wodGetPosition // TIME_SAMPLES=%lu\n", lpTime->u.sample);
 			break;
 		case TIME_SMPTE:
-			time = WOutDev[index].dwTotalPlayed /
-				(WOutDev[index].Format.wf.nAvgBytesPerSec / 1000);
+			time = WOutDev[wDevID].dwTotalPlayed /
+				(WOutDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
 			lpTime->u.smpte.hour = time / 108000;
 			time -= lpTime->u.smpte.hour * 108000;
 			lpTime->u.smpte.min = time / 1800;
@@ -1034,8 +1025,8 @@
 			dprintf_mciwave(stddeb,"wodGetPosition() format not supported ! use TIME_MS !\n");
 			lpTime->wType = TIME_MS;
 		case TIME_MS:
-			lpTime->u.ms = WOutDev[index].dwTotalPlayed /
-					(WOutDev[index].Format.wf.nAvgBytesPerSec / 1000);
+			lpTime->u.ms = WOutDev[wDevID].dwTotalPlayed /
+					(WOutDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
 			dprintf_mciwave(stddeb,"wodGetPosition // TIME_MS=%lu\n", lpTime->u.ms);
 			break;
 		}
@@ -1218,7 +1209,6 @@
 */
 static DWORD widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
 {
-	int index = MMSYSTEM_DevIDToIndex(wDevID);
 	int 		audio;
 	int			abuf_size;
 	int			smplrate;
@@ -1234,7 +1224,7 @@
 		dprintf_mciwave(stddeb,"Linux 'widOpen' // MAX_WAVINDRV reached !\n");
 		return MMSYSERR_ALLOCATED;
 		}
-	WInDev[index].unixdev = 0;
+	WInDev[wDevID].unixdev = 0;
 	audio = open (SOUND_DEV, O_RDONLY, 0);
 	if (audio == -1) {
 		dprintf_mciwave(stddeb,"Linux 'widOpen' // can't open !\n");
@@ -1248,8 +1238,8 @@
 			dprintf_mciwave(stddeb,"Linux 'widOpen' // SNDCTL_DSP_GETBLKSIZE Invalid bufsize !\n");
 		return MMSYSERR_NOTENABLED;
 		}
-	WInDev[index].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
-	switch(WInDev[index].wFlags) {
+	WInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
+	switch(WInDev[wDevID].wFlags) {
 		case DCB_NULL:
 			dprintf_mciwave(stddeb,	"Linux 'widOpen' // CALLBACK_NULL !\n");
 			break;
@@ -1263,41 +1253,41 @@
 			dprintf_mciwave(stddeb,	"Linux 'widOpen' // CALLBACK_FUNCTION !\n");
 			break;
 		}
-	WInDev[index].lpQueueHdr = NULL;
-	WInDev[index].unixdev = audio;
-	WInDev[index].bufsize = abuf_size;
-	WInDev[index].dwTotalRecorded = 0;
-	memcpy(&WInDev[index].waveDesc, lpDesc, sizeof(WAVEOPENDESC));
+	WInDev[wDevID].lpQueueHdr = NULL;
+	WInDev[wDevID].unixdev = audio;
+	WInDev[wDevID].bufsize = abuf_size;
+	WInDev[wDevID].dwTotalRecorded = 0;
+	memcpy(&WInDev[wDevID].waveDesc, lpDesc, sizeof(WAVEOPENDESC));
         lpFormat = lpDesc->lpFormat;
 	if (lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
 		dprintf_mciwave(stddeb,"Linux 'widOpen' // Bad format %04X !\n",
 					lpFormat->wFormatTag);
 		return WAVERR_BADFORMAT;
 		}
-	memcpy(&WInDev[index].Format, lpFormat, sizeof(PCMWAVEFORMAT));
-	WInDev[index].Format.wBitsPerSample = 8; /* <-------------- */
-	if (WInDev[index].Format.wf.nChannels == 0) return WAVERR_BADFORMAT;
-	if (WInDev[index].Format.wf.nSamplesPerSec == 0) return WAVERR_BADFORMAT;
-	if (WInDev[index].Format.wBitsPerSample == 0) {
-		WInDev[index].Format.wBitsPerSample = 8 *
-		(WInDev[index].Format.wf.nAvgBytesPerSec /
-		WInDev[index].Format.wf.nSamplesPerSec) /
-		WInDev[index].Format.wf.nChannels;
+	memcpy(&WInDev[wDevID].Format, lpFormat, sizeof(PCMWAVEFORMAT));
+	WInDev[wDevID].Format.wBitsPerSample = 8; /* <-------------- */
+	if (WInDev[wDevID].Format.wf.nChannels == 0) return WAVERR_BADFORMAT;
+	if (WInDev[wDevID].Format.wf.nSamplesPerSec == 0) return WAVERR_BADFORMAT;
+	if (WInDev[wDevID].Format.wBitsPerSample == 0) {
+		WInDev[wDevID].Format.wBitsPerSample = 8 *
+		(WInDev[wDevID].Format.wf.nAvgBytesPerSec /
+		WInDev[wDevID].Format.wf.nSamplesPerSec) /
+		WInDev[wDevID].Format.wf.nChannels;
 		}
-	samplesize = WInDev[index].Format.wBitsPerSample;
-	smplrate = WInDev[index].Format.wf.nSamplesPerSec;
-	dsp_stereo = (WInDev[index].Format.wf.nChannels > 1) ? TRUE : FALSE;
+	samplesize = WInDev[wDevID].Format.wBitsPerSample;
+	smplrate = WInDev[wDevID].Format.wf.nSamplesPerSec;
+	dsp_stereo = (WInDev[wDevID].Format.wf.nChannels > 1) ? TRUE : FALSE;
 	IOCTL(audio, SNDCTL_DSP_SPEED, smplrate);
 	IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize);
 	IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo);
 	dprintf_mciwave(stddeb,"Linux 'widOpen' // wBitsPerSample=%u !\n",
-				WInDev[index].Format.wBitsPerSample);
+				WInDev[wDevID].Format.wBitsPerSample);
 	dprintf_mciwave(stddeb,"Linux 'widOpen' // nSamplesPerSec=%lu !\n",
-				WInDev[index].Format.wf.nSamplesPerSec);
+				WInDev[wDevID].Format.wf.nSamplesPerSec);
 	dprintf_mciwave(stddeb,"Linux 'widOpen' // nChannels=%u !\n",
-				WInDev[index].Format.wf.nChannels);
+				WInDev[wDevID].Format.wf.nChannels);
 	dprintf_mciwave(stddeb,"Linux 'widOpen' // nAvgBytesPerSec=%lu\n",
-			WInDev[index].Format.wf.nAvgBytesPerSec); 
+			WInDev[wDevID].Format.wf.nAvgBytesPerSec); 
 	if (WAVE_NotifyClient(wDevID, WIM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
 		dprintf_mciwave(stddeb,"Linux 'widOpen' // can't notify client !\n");
 		return MMSYSERR_INVALPARAM;
@@ -1310,15 +1300,14 @@
 */
 static DWORD widClose(WORD wDevID)
 {
-	int index = MMSYSTEM_DevIDToIndex(wDevID);
 	dprintf_mciwave(stddeb,"widClose(%u);\n", wDevID);
-	if (WInDev[index].unixdev == 0) {
+	if (WInDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'widClose' // can't close !\n");
 		return MMSYSERR_NOTENABLED;
 		}
-	close(WInDev[index].unixdev);
-	WInDev[index].unixdev = 0;
-	WInDev[index].bufsize = 0;
+	close(WInDev[wDevID].unixdev);
+	WInDev[wDevID].unixdev = 0;
+	WInDev[wDevID].bufsize = 0;
 	if (WAVE_NotifyClient(wDevID, WIM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
 		dprintf_mciwave(stddeb,"Linux 'widClose' // can't notify client !\n");
 		return MMSYSERR_INVALPARAM;
@@ -1331,12 +1320,11 @@
 */
 static DWORD widAddBuffer(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
-	int index = MMSYSTEM_DevIDToIndex(wDevID);
 	int			count	= 1;
 	LPWAVEHDR 	lpWIHdr;
 	dprintf_mciwave(stddeb,
 		"widAddBuffer(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
-	if (WInDev[index].unixdev == 0) {
+	if (WInDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'widAddBuffer' // can't do it !\n");
 		return MMSYSERR_NOTENABLED;
 		}
@@ -1352,14 +1340,14 @@
 	lpWaveHdr->dwFlags |= WHDR_INQUEUE;
 	lpWaveHdr->dwFlags &= ~WHDR_DONE;
 	lpWaveHdr->dwBytesRecorded = 0;
-	if (WInDev[index].lpQueueHdr == NULL) {
+	if (WInDev[wDevID].lpQueueHdr == NULL) {
 		/* begin the queue with a first header ... */
-		WInDev[index].lpQueueHdr = lpWaveHdr;
-		WInDev[index].dwTotalRecorded = 0;
+		WInDev[wDevID].lpQueueHdr = lpWaveHdr;
+		WInDev[wDevID].dwTotalRecorded = 0;
 		}
 	else {
 		/* added to the queue, except if it's the one just prepared ... */
-		lpWIHdr = WInDev[index].lpQueueHdr;
+		lpWIHdr = WInDev[wDevID].lpQueueHdr;
 		while (lpWIHdr->lpNext != NULL) {
 			lpWIHdr = lpWIHdr->lpNext;
 			count++;
@@ -1377,14 +1365,13 @@
 */
 static DWORD widPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
-	int index = MMSYSTEM_DevIDToIndex(wDevID);
 	dprintf_mciwave(stddeb,
 		"widPrepare(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
-	if (WInDev[index].unixdev == 0) {
+	if (WInDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'widPrepare' // can't prepare !\n");
 		return MMSYSERR_NOTENABLED;
 		}
-	if (WInDev[index].lpQueueHdr != NULL) {
+	if (WInDev[wDevID].lpQueueHdr != NULL) {
 		dprintf_mciwave(stddeb,"Linux 'widPrepare' // already prepare !\n");
 		return WAVERR_BADFORMAT;
 		}
@@ -1402,17 +1389,16 @@
 */
 static DWORD widUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
-	int index = MMSYSTEM_DevIDToIndex(wDevID);
 	dprintf_mciwave(stddeb,
 		"widUnprepare(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
-	if (WInDev[index].unixdev == 0) {
+	if (WInDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'widUnprepare' // can't unprepare !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	lpWaveHdr->dwFlags &= ~WHDR_PREPARED;
 	lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
 	lpWaveHdr->dwFlags |= WHDR_DONE;
-	WInDev[index].lpQueueHdr = NULL;
+	WInDev[wDevID].lpQueueHdr = NULL;
 	dprintf_mciwave(stddeb,
 		"Linux 'widUnprepare' // all headers unprepared !\n");
 	return MMSYSERR_NOERROR;
@@ -1423,31 +1409,30 @@
 */
 static DWORD widStart(WORD wDevID)
 {
-	int index = MMSYSTEM_DevIDToIndex(wDevID);
 	int			count	= 1;
 	LPWAVEHDR 	lpWIHdr;
 	dprintf_mciwave(stddeb,"widStart(%u);\n", wDevID);
-	if (WInDev[index].unixdev == 0) {
+	if (WInDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,	"Linux 'widStart' // can't start recording !\n");
 		return MMSYSERR_NOTENABLED;
 		}
-	if (WInDev[index].lpQueueHdr == NULL || 
-		WInDev[index].lpQueueHdr->lpData == NULL) {
+	if (WInDev[wDevID].lpQueueHdr == NULL || 
+		WInDev[wDevID].lpQueueHdr->lpData == NULL) {
 		dprintf_mciwave(stddeb,"Linux 'widStart' // never been prepared !\n");
 		return WAVERR_UNPREPARED;
 		}
-	lpWIHdr = WInDev[index].lpQueueHdr;
+	lpWIHdr = WInDev[wDevID].lpQueueHdr;
 	while(lpWIHdr != NULL) {
 		lpWIHdr->dwBufferLength &= 0xFFFF;
 		dprintf_mciwave(stddeb,
 			"widStart // recording buf#%u=%p size=%lu \n",
 			count, lpWIHdr->lpData, lpWIHdr->dwBufferLength);
 		fflush(stddeb);
-		read (WInDev[index].unixdev, 
+		read (WInDev[wDevID].unixdev, 
 			PTR_SEG_TO_LIN(lpWIHdr->lpData),
 			lpWIHdr->dwBufferLength);
 		lpWIHdr->dwBytesRecorded = lpWIHdr->dwBufferLength;
-		WInDev[index].dwTotalRecorded += lpWIHdr->dwBytesRecorded;
+		WInDev[wDevID].dwTotalRecorded += lpWIHdr->dwBytesRecorded;
 		lpWIHdr->dwFlags &= ~WHDR_INQUEUE;
 		lpWIHdr->dwFlags |= WHDR_DONE;
 		if (WAVE_NotifyClient(wDevID, WIM_DATA, (DWORD)lpWIHdr, 0L) != 
@@ -1468,9 +1453,8 @@
 */
 static DWORD widStop(WORD wDevID)
 {
-	int index = MMSYSTEM_DevIDToIndex(wDevID);
 	dprintf_mciwave(stddeb,"widStop(%u);\n", wDevID);
-	if (WInDev[index].unixdev == 0) {
+	if (WInDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'widStop' // can't stop !\n");
 		return MMSYSERR_NOTENABLED;
 		}
@@ -1482,9 +1466,8 @@
 */
 static DWORD widReset(WORD wDevID)
 {
-	int index = MMSYSTEM_DevIDToIndex(wDevID);
 	dprintf_mciwave(stddeb,"widReset(%u);\n", wDevID);
-	if (WInDev[index].unixdev == 0) {
+	if (WInDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'widReset' // can't reset !\n");
 		return MMSYSERR_NOTENABLED;
 		}
@@ -1496,12 +1479,11 @@
 */
 static DWORD widGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
 {
-	int index = MMSYSTEM_DevIDToIndex(wDevID);
 	int		time;
     
 	dprintf_mciwave(stddeb,
 		"widGetPosition(%u, %p, %lu);\n", wDevID, lpTime, uSize);
-	if (WInDev[index].unixdev == 0) {
+	if (WInDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'widGetPosition' // can't get pos !\n");
 		return MMSYSERR_NOTENABLED;
 		}
@@ -1509,30 +1491,30 @@
 	dprintf_mciwave(stddeb,"widGetPosition // wType=%04X !\n", 
 			lpTime->wType);
 	dprintf_mciwave(stddeb,"widGetPosition // wBitsPerSample=%u\n",
-			WInDev[index].Format.wBitsPerSample); 
+			WInDev[wDevID].Format.wBitsPerSample); 
 	dprintf_mciwave(stddeb,"widGetPosition // nSamplesPerSec=%lu\n",
-			WInDev[index].Format.wf.nSamplesPerSec); 
+			WInDev[wDevID].Format.wf.nSamplesPerSec); 
 	dprintf_mciwave(stddeb,"widGetPosition // nChannels=%u\n",
-			WInDev[index].Format.wf.nChannels); 
+			WInDev[wDevID].Format.wf.nChannels); 
 	dprintf_mciwave(stddeb,"widGetPosition // nAvgBytesPerSec=%lu\n",
-			WInDev[index].Format.wf.nAvgBytesPerSec); 
+			WInDev[wDevID].Format.wf.nAvgBytesPerSec); 
 	fflush(stddeb);
 	switch(lpTime->wType) {
 		case TIME_BYTES:
-			lpTime->u.cb = WInDev[index].dwTotalRecorded;
+			lpTime->u.cb = WInDev[wDevID].dwTotalRecorded;
 			dprintf_mciwave(stddeb,
 			    "widGetPosition // TIME_BYTES=%lu\n", lpTime->u.cb);
 			break;
 		case TIME_SAMPLES:
-			lpTime->u.sample = WInDev[index].dwTotalRecorded * 8 /
-					  WInDev[index].Format.wBitsPerSample;
+			lpTime->u.sample = WInDev[wDevID].dwTotalRecorded * 8 /
+					  WInDev[wDevID].Format.wBitsPerSample;
 			dprintf_mciwave(stddeb,
 					"widGetPosition // TIME_SAMPLES=%lu\n", 
 					lpTime->u.sample);
 			break;
 		case TIME_SMPTE:
-			time = WInDev[index].dwTotalRecorded /
-				(WInDev[index].Format.wf.nAvgBytesPerSec / 1000);
+			time = WInDev[wDevID].dwTotalRecorded /
+				(WInDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
 			lpTime->u.smpte.hour = time / 108000;
 			time -= lpTime->u.smpte.hour * 108000;
 			lpTime->u.smpte.min = time / 1800;
@@ -1549,8 +1531,8 @@
 			dprintf_mciwave(stddeb,"widGetPosition() format not supported ! use TIME_MS !\n");
 			lpTime->wType = TIME_MS;
 		case TIME_MS:
-			lpTime->u.ms = WInDev[index].dwTotalRecorded /
-					(WInDev[index].Format.wf.nAvgBytesPerSec / 1000);
+			lpTime->u.ms = WInDev[wDevID].dwTotalRecorded /
+					(WInDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
 			dprintf_mciwave(stddeb,
 			      "widGetPosition // TIME_MS=%lu\n", lpTime->u.ms);
 			break;
diff --git a/multimedia/mmsystem.c b/multimedia/mmsystem.c
index 0c232a5..10da700 100644
--- a/multimedia/mmsystem.c
+++ b/multimedia/mmsystem.c
@@ -98,8 +98,7 @@
 int MMSYSTEM_WEP(HINSTANCE16 hInstance, WORD wDataSeg,
 		 WORD cbHeapSize, LPSTR lpCmdLine)
 {
-	/* isn't WEP the Windows Exit Procedure ? */
-	printf("MMSYSTEM DLL INIT ... hInst=%04X \n", hInstance);
+	fprintf(stderr, "STUB: Unloading MMSystem DLL ... hInst=%04X \n", hInstance);
 	return(TRUE);
 }
 
@@ -108,22 +107,12 @@
 */
 BOOL16 sndPlaySound(LPCSTR lpszSoundName, UINT16 uFlags)
 {
+	BOOL16			bRet = FALSE;
 	HMMIO16			hmmio;
-	MMCKINFO		mmckInfo;
-	MMCKINFO		ckMainRIFF;
-	HLOCAL16		hFormat;
-	PCMWAVEFORMAT 	pcmWaveFormat;
-	int				count;
-	int				bufsize;
-	HLOCAL16		hDesc;
-	LPWAVEOPENDESC 	lpWaveDesc;
-	HLOCAL16		hWaveHdr;
-	LPWAVEHDR		lpWaveHdr;
-	LPWAVEHDR		lp16WaveHdr;
-	HLOCAL16		hData;
-	DWORD			dwRet;
+	MMCKINFO                ckMainRIFF;
 	char			str[128];
 	LPSTR			ptr;
+
 	dprintf_mmsys(stddeb, "sndPlaySound // SoundName='%s' uFlags=%04X !\n", 
 									lpszSoundName, uFlags);
 	if (lpszSoundName == NULL) {
@@ -138,95 +127,122 @@
 		return FALSE;
 	}
 
-	if (hmmio == 0) {
+	if (hmmio == 0) 
+	{
 		dprintf_mmsys(stddeb, "sndPlaySound // searching in SystemSound List !\n");
 		GetProfileString32A("Sounds", (LPSTR)lpszSoundName, "", str, sizeof(str));
 		if (strlen(str) == 0) return FALSE;
 		if ( (ptr = (LPSTR)strchr(str, ',')) != NULL) *ptr = '\0';
 		hmmio = mmioOpen(str, NULL, MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
-		if (hmmio == 0) {
+		if (hmmio == 0) 
+		{
 			dprintf_mmsys(stddeb, "sndPlaySound // can't find SystemSound='%s' !\n", str);
 			return FALSE;
+		}
+	}
+
+	if (mmioDescend(hmmio, &ckMainRIFF, NULL, 0) == 0) 
+        {
+	    dprintf_mmsys(stddeb, "sndPlaySound // ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
+				(LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType, ckMainRIFF.cksize);
+
+	    if ((ckMainRIFF.ckid == FOURCC_RIFF) &&
+	    	(ckMainRIFF.fccType == mmioFOURCC('W', 'A', 'V', 'E')))
+	    {
+		MMCKINFO        mmckInfo;
+
+		mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
+
+		if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) == 0)
+		{
+		    PCMWAVEFORMAT           pcmWaveFormat;
+
+		    dprintf_mmsys(stddeb, "sndPlaySound // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
+				(LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize);
+
+		    if (mmioRead(hmmio, (HPSTR) &pcmWaveFormat,
+			        (long) sizeof(PCMWAVEFORMAT)) == (long) sizeof(PCMWAVEFORMAT))
+		    {
+
+			dprintf_mmsys(stddeb, "sndPlaySound // wFormatTag=%04X !\n", pcmWaveFormat.wf.wFormatTag);
+			dprintf_mmsys(stddeb, "sndPlaySound // nChannels=%d \n", pcmWaveFormat.wf.nChannels);
+			dprintf_mmsys(stddeb, "sndPlaySound // nSamplesPerSec=%ld\n", pcmWaveFormat.wf.nSamplesPerSec);
+			dprintf_mmsys(stddeb, "sndPlaySound // nAvgBytesPerSec=%ld\n", pcmWaveFormat.wf.nAvgBytesPerSec);
+			dprintf_mmsys(stddeb, "sndPlaySound // nBlockAlign=%d \n", pcmWaveFormat.wf.nBlockAlign);
+			dprintf_mmsys(stddeb, "sndPlaySound // wBitsPerSample=%u !\n", pcmWaveFormat.wBitsPerSample);
+
+			mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
+			if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) == 0)
+			{
+			    LPWAVEFORMAT     lpFormat	= (LPWAVEFORMAT) SEGPTR_ALLOC(sizeof(PCMWAVEFORMAT));
+			    LPWAVEOPENDESC   lpWaveDesc = (LPWAVEOPENDESC) SEGPTR_ALLOC(sizeof(WAVEOPENDESC));
+			    DWORD            dwRet;
+
+			    dprintf_mmsys(stddeb, "sndPlaySound // Chunk Found \
+ ckid=%.4s fccType=%.4s cksize=%08lX \n", (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize);
+
+			    pcmWaveFormat.wf.nAvgBytesPerSec = pcmWaveFormat.wf.nSamplesPerSec * 
+							   pcmWaveFormat.wf.nBlockAlign;
+			    memcpy(lpFormat, &pcmWaveFormat, sizeof(PCMWAVEFORMAT));
+
+			    lpWaveDesc->hWave    = 0;
+			    lpWaveDesc->lpFormat = (LPWAVEFORMAT) SEGPTR_GET(lpFormat);
+
+			    dwRet = wodMessage( MMSYSTEM_FirstDevID(), 
+						WODM_OPEN, 0, (DWORD)SEGPTR_GET(lpWaveDesc), CALLBACK_NULL);
+			    SEGPTR_FREE(lpFormat);
+			    SEGPTR_FREE(lpWaveDesc);
+
+			    if (dwRet == MMSYSERR_NOERROR) 
+			    {
+				LPWAVEHDR    lpWaveHdr = (LPWAVEHDR) SEGPTR_ALLOC(sizeof(WAVEHDR));
+				SEGPTR       spWaveHdr = SEGPTR_GET(lpWaveHdr);
+				HGLOBAL16    hData;
+				INT32        count, bufsize;
+
+				bufsize = 64000;
+				hData = GlobalAlloc16(GMEM_MOVEABLE, bufsize);
+				lpWaveHdr->lpData = (LPSTR) WIN16_GlobalLock16(hData);
+				lpWaveHdr->dwBufferLength = bufsize;
+				lpWaveHdr->dwUser = 0L;
+				lpWaveHdr->dwFlags = 0L;
+				lpWaveHdr->dwLoops = 0L;
+
+				dwRet = wodMessage( MMSYSTEM_FirstDevID(),
+						    WODM_PREPARE, 0, (DWORD)spWaveHdr, sizeof(WAVEHDR));
+				if (dwRet == MMSYSERR_NOERROR) 
+				{
+				    while( TRUE )
+				    {
+					count = mmioRead(hmmio, PTR_SEG_TO_LIN(lpWaveHdr->lpData), bufsize);
+					if (count < 1) break;
+					lpWaveHdr->dwBufferLength = count;
+				/*	lpWaveHdr->dwBytesRecorded = count; */
+					wodMessage( MMSYSTEM_FirstDevID(), WODM_WRITE, 
+						    0, (DWORD)spWaveHdr, sizeof(WAVEHDR));
+				    }
+				    wodMessage( MMSYSTEM_FirstDevID(), 
+						WODM_UNPREPARE, 0, (DWORD)spWaveHdr, sizeof(WAVEHDR));
+				    wodMessage( MMSYSTEM_FirstDevID(),
+						WODM_CLOSE, 0, 0L, 0L);
+
+				    bRet = TRUE;
+				}
+				else dprintf_mmsys(stddeb, "sndPlaySound // can't prepare WaveOut device !\n");
+
+				GlobalUnlock16(hData);
+				GlobalFree16(hData);
+
+				SEGPTR_FREE(lpWaveHdr);
+			    }
 			}
+		    }
 		}
-	if (mmioDescend(hmmio, &ckMainRIFF, NULL, 0) != 0) {
-ErrSND:	if (hmmio != 0)   mmioClose(hmmio, 0);
-		return FALSE;
-		}
-	dprintf_mmsys(stddeb, "sndPlaySound // ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
-				(LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
-				ckMainRIFF.cksize);
-	if ((ckMainRIFF.ckid != FOURCC_RIFF) ||
-	    (ckMainRIFF.fccType != mmioFOURCC('W', 'A', 'V', 'E'))) goto ErrSND;
-	mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
-	if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) != 0) goto ErrSND;
-	dprintf_mmsys(stddeb, "sndPlaySound // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
-			(LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType,
-			mmckInfo.cksize);
-	if (mmioRead(hmmio, (HPSTR) &pcmWaveFormat,
-		(long) sizeof(PCMWAVEFORMAT)) != (long) sizeof(PCMWAVEFORMAT)) goto ErrSND;
+	    }
+	}
 
-	dprintf_mmsys(stddeb, "sndPlaySound // wFormatTag=%04X !\n", pcmWaveFormat.wf.wFormatTag);
-	dprintf_mmsys(stddeb, "sndPlaySound // nChannels=%d \n", pcmWaveFormat.wf.nChannels);
-	dprintf_mmsys(stddeb, "sndPlaySound // nSamplesPerSec=%ld\n", pcmWaveFormat.wf.nSamplesPerSec);
-	dprintf_mmsys(stddeb, "sndPlaySound // nAvgBytesPerSec=%ld\n", pcmWaveFormat.wf.nAvgBytesPerSec);
-	dprintf_mmsys(stddeb, "sndPlaySound // nBlockAlign=%d \n", pcmWaveFormat.wf.nBlockAlign);
-	dprintf_mmsys(stddeb, "sndPlaySound // wBitsPerSample=%u !\n", pcmWaveFormat.wBitsPerSample);
-
-	mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
-	if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) != 0) goto ErrSND;
-	dprintf_mmsys(stddeb, "sndPlaySound // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
-			(LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType,
-			mmckInfo.cksize);
-	hDesc = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
-	lpWaveDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hDesc);
-	lpWaveDesc->hWave = 0;
-	pcmWaveFormat.wf.nAvgBytesPerSec = 
-		pcmWaveFormat.wf.nSamplesPerSec * pcmWaveFormat.wf.nBlockAlign;
-	hFormat = USER_HEAP_ALLOC(sizeof(PCMWAVEFORMAT));
-	lpWaveDesc->lpFormat = (LPWAVEFORMAT) USER_HEAP_LIN_ADDR(hFormat);
-	memcpy(lpWaveDesc->lpFormat, &pcmWaveFormat, sizeof(PCMWAVEFORMAT));
-	lpWaveDesc = (LPWAVEOPENDESC) USER_HEAP_SEG_ADDR(hDesc);
-	dwRet = wodMessage(0, WODM_OPEN, 0, (DWORD)lpWaveDesc, CALLBACK_NULL);
-	if (dwRet != MMSYSERR_NOERROR) {
-		dprintf_mmsys(stddeb, "sndPlaySound // can't open WaveOut device !\n");
-		goto ErrSND;
-		}
-	USER_HEAP_FREE(hFormat);
-	hWaveHdr = USER_HEAP_ALLOC(sizeof(WAVEHDR));
-	lpWaveHdr = (LPWAVEHDR) USER_HEAP_LIN_ADDR(hWaveHdr);
-	lp16WaveHdr = (LPWAVEHDR) USER_HEAP_SEG_ADDR(hWaveHdr);
-	bufsize = 64000;
-	hData = GlobalAlloc16(GMEM_MOVEABLE, bufsize);
-	lpWaveHdr->lpData = (LPSTR) WIN16_GlobalLock16(hData);
-	lpWaveHdr->dwBufferLength = bufsize;
-	lpWaveHdr->dwUser = 0L;
-	lpWaveHdr->dwFlags = 0L;
-	lpWaveHdr->dwLoops = 0L;
-	dwRet = wodMessage(0, WODM_PREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
-	if (dwRet != MMSYSERR_NOERROR) {
-		dprintf_mmsys(stddeb, "sndPlaySound // can't prepare WaveOut device !\n");
-		GlobalUnlock16(hData);
-		GlobalFree16(hData);
-		USER_HEAP_FREE(hDesc);
-		USER_HEAP_FREE(hWaveHdr);
-		goto ErrSND;
-		}
-	while(TRUE) {
-		count = mmioRead(hmmio, PTR_SEG_TO_LIN(lpWaveHdr->lpData), bufsize);
-		if (count < 1) break;
-		lpWaveHdr->dwBufferLength = count;
-/*		lpWaveHdr->dwBytesRecorded = count; */
-		wodMessage(0, WODM_WRITE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
-		}
-	wodMessage(0, WODM_UNPREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
-	wodMessage(0, WODM_CLOSE, 0, 0L, 0L);
-	GlobalUnlock16(hData);
-	GlobalFree16(hData);
-	USER_HEAP_FREE(hDesc);
-	USER_HEAP_FREE(hWaveHdr);
-	if (hmmio != 0)   mmioClose(hmmio, 0);
-	return TRUE;
+	if (hmmio != 0) mmioClose(hmmio, 0);
+	return bRet;
 }
 
 /**************************************************************************
@@ -1407,7 +1423,7 @@
 {
 	UINT16	count = 0;
 	dprintf_mmsys(stddeb, "waveOutGetNumDevs\n");
-	count += wodMessage(0, WODM_GETNUMDEVS, 0L, 0L, 0L);
+	count += wodMessage( MMSYSTEM_FirstDevID(), WODM_GETNUMDEVS, 0L, 0L, 0L);
 	dprintf_mmsys(stddeb, "waveOutGetNumDevs return %u \n", count);
 	return count;
 }
@@ -1552,7 +1568,7 @@
 	dprintf_mmsys(stddeb, "waveOutClose(%04X)\n", hWaveOut);
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage(0, WODM_CLOSE, lpDesc->dwInstance, 0L, 0L);
+	return wodMessage( MMSYSTEM_FirstDevID(), WODM_CLOSE, lpDesc->dwInstance, 0L, 0L);
 }
 
 /**************************************************************************
@@ -1566,7 +1582,7 @@
 					hWaveOut, lpWaveOutHdr, uSize);
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage(0, WODM_PREPARE, lpDesc->dwInstance, 
+	return wodMessage( MMSYSTEM_FirstDevID(), WODM_PREPARE, lpDesc->dwInstance, 
 							(DWORD)lpWaveOutHdr, uSize);
 }
 
@@ -1581,7 +1597,7 @@
 						hWaveOut, lpWaveOutHdr, uSize);
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage(0, WODM_UNPREPARE, lpDesc->dwInstance, 
+	return wodMessage( MMSYSTEM_FirstDevID(), WODM_UNPREPARE, lpDesc->dwInstance, 
 							(DWORD)lpWaveOutHdr, uSize);
 }
 
@@ -1594,7 +1610,7 @@
 	dprintf_mmsys(stddeb, "waveOutWrite(%04X, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage(0, WODM_WRITE, lpDesc->dwInstance, 
+	return wodMessage( MMSYSTEM_FirstDevID(), WODM_WRITE, lpDesc->dwInstance, 
 							(DWORD)lpWaveOutHdr, uSize);
 }
 
@@ -1607,7 +1623,7 @@
 	dprintf_mmsys(stddeb, "waveOutPause(%04X)\n", hWaveOut);
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage(0, WODM_PAUSE, lpDesc->dwInstance, 0L, 0L);
+	return wodMessage( MMSYSTEM_FirstDevID(), WODM_PAUSE, lpDesc->dwInstance, 0L, 0L);
 }
 
 /**************************************************************************
@@ -1619,7 +1635,7 @@
 	dprintf_mmsys(stddeb, "waveOutRestart(%04X)\n", hWaveOut);
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage(0, WODM_RESTART, lpDesc->dwInstance, 0L, 0L);
+	return wodMessage( MMSYSTEM_FirstDevID(), WODM_RESTART, lpDesc->dwInstance, 0L, 0L);
 }
 
 /**************************************************************************
@@ -1631,7 +1647,7 @@
 	dprintf_mmsys(stddeb, "waveOutReset(%04X)\n", hWaveOut);
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage(0, WODM_RESET, lpDesc->dwInstance, 0L, 0L);
+	return wodMessage( MMSYSTEM_FirstDevID(), WODM_RESET, lpDesc->dwInstance, 0L, 0L);
 }
 
 /**************************************************************************
@@ -1643,7 +1659,7 @@
 	dprintf_mmsys(stddeb, "waveOutGetPosition(%04X, %p, %u);\n", hWaveOut, lpTime, uSize);
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage(0, WODM_GETPOS, lpDesc->dwInstance, 
+	return wodMessage( MMSYSTEM_FirstDevID(), WODM_GETPOS, lpDesc->dwInstance, 
 							(DWORD)lpTime, (DWORD)uSize);
 }
 
@@ -1656,7 +1672,7 @@
 	dprintf_mmsys(stddeb, "waveOutGetPitch(%04X, %p);\n", hWaveOut, lpdwPitch);
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage(0, WODM_GETPITCH, lpDesc->dwInstance, 
+	return wodMessage( MMSYSTEM_FirstDevID(), WODM_GETPITCH, lpDesc->dwInstance, 
 								(DWORD)lpdwPitch, 0L);
 }
 
@@ -1669,7 +1685,7 @@
 	dprintf_mmsys(stddeb, "waveOutSetPitch(%04X, %08lX);\n", hWaveOut, dwPitch);
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage(0, WODM_SETPITCH, lpDesc->dwInstance, (DWORD)dwPitch, 0L);
+	return wodMessage( MMSYSTEM_FirstDevID(), WODM_SETPITCH, lpDesc->dwInstance, (DWORD)dwPitch, 0L);
 }
 
 /**************************************************************************
@@ -1699,7 +1715,7 @@
 	dprintf_mmsys(stddeb, "waveOutGetPlaybackRate(%04X, %p);\n", hWaveOut, lpdwRate);
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage(0, WODM_GETPLAYBACKRATE, lpDesc->dwInstance, 
+	return wodMessage( MMSYSTEM_FirstDevID(), WODM_GETPLAYBACKRATE, lpDesc->dwInstance, 
 								(DWORD)lpdwRate, 0L);
 }
 
@@ -1712,7 +1728,7 @@
 	dprintf_mmsys(stddeb, "waveOutSetPlaybackRate(%04X, %08lX);\n", hWaveOut, dwRate);
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage(0, WODM_SETPLAYBACKRATE, 
+	return wodMessage( MMSYSTEM_FirstDevID(), WODM_SETPLAYBACKRATE, 
 		lpDesc->dwInstance, (DWORD)dwRate, 0L);
 }
 
@@ -1752,7 +1768,7 @@
 			hWaveOut, uMessage, dwParam1, dwParam2);
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
+	return wodMessage( MMSYSTEM_FirstDevID(), uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
 }
 
 /**************************************************************************
diff --git a/objects/bitmap.c b/objects/bitmap.c
index 77147f7..52f3ef4 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -6,6 +6,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include "gdi.h"
@@ -28,29 +29,6 @@
 extern void CLIPPING_UpdateGCRegion( DC * dc );  /* objects/clipping.c */
 
 
-
-/***********************************************************************
- *           BITMAP_BmpToImage
- *
- * Create an XImage pointing to the bitmap data.
- */
-static XImage *BITMAP_BmpToImage( BITMAP16 * bmp, LPVOID bmpData )
-{
-    extern void _XInitImageFuncPtrs( XImage* );
-    XImage * image;
-
-    image = XCreateImage( display, DefaultVisualOfScreen(screen),
-			  bmp->bmBitsPixel, ZPixmap, 0, bmpData,
-			  bmp->bmWidth, bmp->bmHeight, 16, bmp->bmWidthBytes );
-    if (!image) return 0;
-    image->byte_order = MSBFirst;
-    image->bitmap_bit_order = MSBFirst;
-    image->bitmap_unit = 16;
-    _XInitImageFuncPtrs(image);
-    return image;
-}
-
-
 /***********************************************************************
  *           CreateBitmap16    (GDI.48)
  */
@@ -172,8 +150,10 @@
 LONG GetBitmapBits32( HBITMAP32 hbitmap, LONG count, LPVOID buffer )
 {
     BITMAPOBJ * bmp;
-    LONG height;
+    LONG height,widthbytes;
     XImage * image;
+    LPBYTE tmpbuffer,tbuf;
+    int	h,w,pad;
     
     /* KLUDGE! */
     if (count < 0) {
@@ -190,13 +170,112 @@
 	    bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
 	    1 << bmp->bitmap.bmBitsPixel, buffer, height );
     if (!height) return 0;
+
+    switch (bmp->bitmap.bmBitsPixel) {
+    case 1:
+	if (!(bmp->bitmap.bmWidth & 15))
+		pad = 0;
+	else
+		pad = ((16 - (bmp->bitmap.bmWidth & 15)) + 7) / 8;
+    	break;
+    case 4:
+	if (!(bmp->bitmap.bmWidth & 3))
+	    pad = 0;
+	else
+	    pad = ((4 - (bmp->bitmap.bmWidth & 3)) + 1) / 2;
+	break;
+    case 8:
+    	pad = (2 - (bmp->bitmap.bmWidth & 1)) & 1;
+    	break;
+    case 15:
+    case 16:
+    	pad = 0; /* we have 16bit alignment already */
+	break;
+    case 24:
+    	pad = (bmp->bitmap.bmWidth*3) & 1;
+    	break;
+    default:
+	fprintf(stderr,"GetBitMapBits32: unknown depth %d, please report.\n",
+		bmp->bitmap.bmBitsPixel
+	);
+	return 0;
+    }
+
+    widthbytes	= DIB_GetImageWidthBytesX11(bmp->bitmap.bmWidth,bmp->bitmap.bmBitsPixel);
+    tmpbuffer	= (LPBYTE)xmalloc(widthbytes*height);
+    image = XCreateImage( display, DefaultVisualOfScreen(screen),
+		  bmp->bitmap.bmBitsPixel, ZPixmap, 0, tmpbuffer,
+		  bmp->bitmap.bmWidth,height,32,widthbytes
+    );
     
-    if (!(image = BITMAP_BmpToImage( &bmp->bitmap, buffer ))) return 0;
     CallTo32_LargeStack( (int(*)())XGetSubImage, 11,
                          display, bmp->pixmap, 0, 0, bmp->bitmap.bmWidth,
                          height, AllPlanes, ZPixmap, image, 0, 0 );
-    image->data = NULL;
-    XDestroyImage( image );
+
+    /* copy XImage to 16 bit padded image buffer with real bitsperpixel */
+
+    tbuf = buffer;
+    switch (bmp->bitmap.bmBitsPixel)
+    {
+    case 1:
+        for (h=0;h<height;h++)
+        {
+            *tbuf = 0;
+            for (w=0;w<bmp->bitmap.bmWidth;w++)
+            {
+                *tbuf |= XGetPixel(image,w,h)<<(7-(w&7));
+                if ((w&7) == 7) *(++tbuf) = 0;
+            }
+            tbuf += pad;
+        }
+        break;
+    case 4:
+        for (h=0;h<height;h++)
+        {
+            for (w=0;w<bmp->bitmap.bmWidth;w++)
+            {
+                if (!(w & 1)) *tbuf = XGetPixel( image, w, h) << 4;
+	    	else *tbuf++ |= XGetPixel( image, w, h) & 0x0f;
+            }
+            tbuf += pad;
+        }
+        break;
+    case 8:
+        for (h=0;h<height;h++)
+        {
+            for (w=0;w<bmp->bitmap.bmWidth;w++)
+                *tbuf++ = XGetPixel(image,w,h);
+            tbuf += pad;
+        }
+        break;
+    case 15:
+    case 16:
+        for (h=0;h<height;h++)
+        {
+            for (w=0;w<bmp->bitmap.bmWidth;w++)
+            {
+	    	long pixel = XGetPixel(image,w,h);
+
+		*tbuf++ = pixel & 0xff;
+		*tbuf++ = (pixel>>8) & 0xff;
+            }
+        }
+        break;
+    case 24:
+        for (h=0;h<height;h++)
+        {
+            for (w=0;w<bmp->bitmap.bmWidth;w++)
+            {
+	    	long pixel = XGetPixel(image,w,h);
+
+		*tbuf++ = pixel & 0xff;
+		*tbuf++ = (pixel>> 8) & 0xff;
+		*tbuf++ = (pixel>>16) & 0xff;
+	    }
+            tbuf += pad;
+	}
+    }
+    XDestroyImage( image ); /* frees tbuffer too */
     return height * bmp->bitmap.bmWidthBytes;
 }
 
@@ -218,6 +297,8 @@
     BITMAPOBJ * bmp;
     LONG height;
     XImage * image;
+    LPBYTE sbuf,tmpbuffer;
+    int	w,h,pad,widthbytes;
     
     /* KLUDGE! */
     if (count < 0) {
@@ -236,12 +317,107 @@
     if (height > bmp->bitmap.bmHeight) height = bmp->bitmap.bmHeight;
     if (!height) return 0;
     	
-    if (!(image = BITMAP_BmpToImage( &bmp->bitmap, (LPVOID)buffer ))) return 0;
+    switch (bmp->bitmap.bmBitsPixel) {
+    case 1:
+	if (!(bmp->bitmap.bmWidth & 15))
+		pad = 0;
+	else
+		pad = ((16 - (bmp->bitmap.bmWidth & 15)) + 7) / 8;
+    	break;
+    case 4:
+	if (!(bmp->bitmap.bmWidth & 3))
+	    pad = 0;
+	else
+	    pad = ((4 - (bmp->bitmap.bmWidth & 3)) + 1) / 2;
+	break;
+    case 8:
+    	pad = (2 - (bmp->bitmap.bmWidth & 1)) & 1;
+    	break;
+    case 15:
+    case 16:
+    	pad = 0; /* we have 16bit alignment already */
+	break;
+    case 24:
+    	pad = (bmp->bitmap.bmWidth*3) & 1;
+    	break;
+    default:
+	fprintf(stderr,"SetBitMapBits32: unknown depth %d, please report.\n",
+		bmp->bitmap.bmBitsPixel
+	);
+	return 0;
+    }
+    sbuf = (LPBYTE)buffer;
+
+    widthbytes	= DIB_GetImageWidthBytesX11(bmp->bitmap.bmWidth,bmp->bitmap.bmBitsPixel);
+    tmpbuffer	= (LPBYTE)xmalloc(widthbytes*height);
+    image = XCreateImage( display, DefaultVisualOfScreen(screen),
+		  bmp->bitmap.bmBitsPixel, ZPixmap, 0, tmpbuffer,
+		  bmp->bitmap.bmWidth,height,32,widthbytes
+    );
+    
+    /* copy 16 bit padded image buffer with real bitsperpixel to XImage */
+    sbuf = (LPBYTE)buffer;
+    switch (bmp->bitmap.bmBitsPixel)
+    {
+    case 1:
+        for (h=0;h<height;h++)
+        {
+            for (w=0;w<bmp->bitmap.bmWidth;w++)
+            {
+                XPutPixel(image,w,h,(sbuf[0]>>(7-(w&7))) & 1);
+                if ((w&7) == 7)
+                    sbuf++;
+            }
+            sbuf += pad;
+        }
+        break;
+    case 4:
+        for (h=0;h<height;h++)
+        {
+            for (w=0;w<bmp->bitmap.bmWidth;w++)
+            {
+                if (!(w & 1)) XPutPixel( image, w, h, *sbuf >> 4 );
+                else XPutPixel( image, w, h, *sbuf++ & 0xf );
+            }
+            sbuf += pad;
+        }
+        break;
+    case 8:
+        for (h=0;h<height;h++)
+        {
+            for (w=0;w<bmp->bitmap.bmWidth;w++)
+                XPutPixel(image,w,h,*sbuf++);
+            sbuf += pad;
+        }
+        break;
+    case 15:
+    case 16:
+        for (h=0;h<height;h++)
+        {
+            for (w=0;w<bmp->bitmap.bmWidth;w++)
+            {
+                XPutPixel(image,w,h,sbuf[1]*256+sbuf[0]);
+                sbuf+=2;
+            }
+        }
+        break;
+    case 24: 
+        for (h=0;h<height;h++)
+        {
+            for (w=0;w<bmp->bitmap.bmWidth;w++)
+            {
+                XPutPixel(image,w,h,(sbuf[2]<<16)+(sbuf[1]<<8)+sbuf[0]);
+                sbuf += 3;
+            }
+            sbuf += pad;
+        }
+        break;
+    }
+
     CallTo32_LargeStack( XPutImage, 10,
                          display, bmp->pixmap, BITMAP_GC(bmp), image, 0, 0,
                          0, 0, bmp->bitmap.bmWidth, height );
-    image->data = NULL;
-    XDestroyImage( image );
+    XDestroyImage( image ); /* frees tmpbuffer too */
     return height * bmp->bitmap.bmWidthBytes;
 }
 
diff --git a/objects/cursoricon.c b/objects/cursoricon.c
index b4c140a..7212085 100644
--- a/objects/cursoricon.c
+++ b/objects/cursoricon.c
@@ -821,6 +821,11 @@
 
         /* Create a pixmap and transfer all the bits to it */
 
+	/* NOTE: Following hack works, but only because XFree depth
+	 * 	 1 images really use 1 bit/pixel (and so the same layout
+	 *	 as the Windows cursor data). Perhaps use a more generic
+	 *	 algorithm here.
+	 */
         pixmapAll = XCreatePixmap( display, rootWindow,
                                    ptr->nWidth, ptr->nHeight * 2, 1 );
         image = XCreateImage( display, DefaultVisualOfScreen(screen),
diff --git a/objects/dib.c b/objects/dib.c
index e294498..0eb78f0 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -800,7 +800,7 @@
     BITMAPOBJ * bmp;
     PALETTEENTRY * palEntry;
     PALETTEOBJ * palette;
-    XImage * bmpImage, * dibImage;
+    XImage * bmpImage;
     int i, x, y;
         
     if (!lines) return 0;
@@ -864,7 +864,7 @@
 	switch( info->bmiHeader.biBitCount )
 	{
 	   case 8:
-
+		/* pad up to 32 bit (FIXME: not 16? ) */
 		pad += (4 - (info->bmiHeader.biWidth & 3)) & 3;
 		for( y = yend - 1; (int)y >= (int)startscan; y-- )
 		{
@@ -873,32 +873,71 @@
 		   bbits += pad;
 		}
 		break;
-
-/* add more bpp-specific shortcuts here */
-
-	   default:
-
-		dibImage = XCreateImage(display, DefaultVisualOfScreen( screen ),
-			   info->bmiHeader.biBitCount, ZPixmap, 0, bits,
-			   info->bmiHeader.biWidth, info->bmiHeader.biHeight,
-			   32, DIB_GetImageWidthBytesX11(info->bmiHeader.biWidth,
-                                                info->bmiHeader.biBitCount ) );
-		if( dibImage )
+	   case 1:
+	   	pad += ((32 - (info->bmiHeader.biWidth & 31)) / 8) & 3;
+		for( y = yend - 1; (int)y >= (int)startscan; y-- )
 		{
-		    extern void _XInitImageFuncPtrs( XImage* );
-
-		    dibImage->byte_order = MSBFirst;
-		    dibImage->bitmap_bit_order = MSBFirst;
-		    dibImage->bitmap_unit = 16;
-		    _XInitImageFuncPtrs( dibImage );
-
-		    for (y = yend - 1; (int)y >= (int)startscan; y--)
-		        for (x = 0; x < xend; x++)
-			    XPutPixel( dibImage, x, yend - y + 1, 
-				       XGetPixel( bmpImage, x, y ));
-		    dibImage->data = NULL;
-		    XDestroyImage( dibImage );
+		   *bbits = 0;
+		   for( x = 0; x < xend; x++ ) {
+		   	
+			*bbits |= XGetPixel( bmpImage, x, y)<<(7-(x&7));
+			if ((x&7)==7) {
+			    bbits++;
+			    *bbits=0;
+			}
+		   }
+		   bbits += pad;
 		}
+		break;
+	   case 4:
+	   	pad += ((8 - (info->bmiHeader.biWidth & 7)) / 2) & 3;
+		for( y = yend - 1; (int)y >= (int)startscan; y-- )
+		{
+		   *bbits = 0;
+		   for( x = 0; x < xend; x++ ) {
+		   	
+			*bbits |= XGetPixel( bmpImage, x, y)<<(4*(1-(x&1)));
+			if ((x&1)==1) {
+			    bbits++;
+			    *bbits=0;
+			}
+		   }
+		   bbits += pad;
+		}
+		break;
+	   case 15:
+           case 16:
+	   	pad += (4 - ((info->bmiHeader.biWidth*2) & 3)) & 3;
+		for( y = yend - 1; (int)y >= (int)startscan; y-- )
+		{
+		   *bbits = 0;
+		   for( x = 0; x < xend; x++ ) {
+		   	unsigned long pixel=XGetPixel( bmpImage, x, y);
+			*bbits++ = pixel & 0xff;
+			*bbits++ = (pixel >> 8) & 0xff;
+		   }
+		   bbits += pad;
+		}
+		break;
+	   case 24:
+	   	pad += (4 - ((info->bmiHeader.biWidth*3) & 3)) & 3;
+		for( y = yend - 1; (int)y >= (int)startscan; y-- )
+		{
+		   *bbits = 0;
+		   for( x = 0; x < xend; x++ ) {
+		   	unsigned long pixel=XGetPixel( bmpImage, x, y);
+			*bbits++ = (pixel >>16) & 0xff;
+			*bbits++ = (pixel >> 8) & 0xff;
+			*bbits++ =  pixel       & 0xff;
+		   }
+		   bbits += pad;
+		}
+		break;
+	   default:
+	   	fprintf(stderr,"GetDIBits*: unsupported depth %d\n",
+			info->bmiHeader.biBitCount
+		);
+	   	break;
 	}
 
 	XDestroyImage( bmpImage );
diff --git a/objects/metafile.c b/objects/metafile.c
index e74209f..402e0aa 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -728,6 +728,18 @@
        	SelectClipRgn32(hdc, *(ht->objectHandle + *(mr->rdParam)));
 	break;
 
+     case META_DIBCREATEPATTERNBRUSH:
+	/*  *(mr->rdParam) may be BS_PATTERN or BS_DIBPATTERN: but there's no difference */
+        dprintf_metafile(stddeb,"META_DIBCREATEPATTERNBRUSH: %d\n",*(mr->rdParam));
+	s1 = mr->rdSize * 2 - sizeof(METARECORD) - 2;
+	hndl = GlobalAlloc16(GMEM_MOVEABLE, s1);
+	ptr = GlobalLock16(hndl);
+	memcpy(ptr, mr->rdParam + 2, s1);
+	GlobalUnlock16(hndl);
+	MF_AddHandle(ht, nHandles,CreateDIBPatternBrush16(hndl, *(mr->rdParam + 1)));
+	GlobalFree16(hndl);
+	break;
+
 #define META_UNIMP(x) case x: fprintf(stderr,"PlayMetaFileRecord:record type "#x" not implemented.\n");break;
     META_UNIMP(META_SETTEXTCHAREXTRA)
     META_UNIMP(META_SETTEXTJUSTIFICATION)
@@ -738,7 +750,6 @@
     META_UNIMP(META_SETPALENTRIES)
     META_UNIMP(META_RESIZEPALETTE)
     META_UNIMP(META_DIBBITBLT)
-    META_UNIMP(META_DIBCREATEPATTERNBRUSH)
     META_UNIMP(META_EXTFLOODFILL)
     META_UNIMP(META_RESETDC)
     META_UNIMP(META_STARTDOC)
diff --git a/scheduler/thread.c b/scheduler/thread.c
index 16f602c..33907ab 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -63,8 +63,8 @@
     /* Set a guard page at the bottom of the stack */
     VirtualProtect( thdb->stack_base, 1, PAGE_EXECUTE_READWRITE | PAGE_GUARD,
                     &old_prot );
-    thdb->teb.stack_top   = (char *)thdb->stack_base + stack_size;
-    thdb->teb.stack_low   = thdb->teb.stack_top;
+    thdb->teb.stack_top   = (char *)thdb->stack_base + stack_size - 1;
+    thdb->teb.stack_low   = thdb->stack_base;
     thdb->exit_stack      = thdb->teb.stack_top;
 
     /* Allocate the TEB selector (%fs register) */
diff --git a/win32/code_page.c b/win32/code_page.c
index c9b0f9f..508172b 100644
--- a/win32/code_page.c
+++ b/win32/code_page.c
@@ -5,7 +5,7 @@
  */
 
 #include <stdio.h>
-#include <malloc.h>
+#include <stdlib.h>
 #include "windows.h"
 #include "winerror.h"
 #include "winnls.h"
diff --git a/win32/console.c b/win32/console.c
index 6889b5f..d0b25ae 100644
--- a/win32/console.c
+++ b/win32/console.c
@@ -5,7 +5,7 @@
  */
 
 #include <stdio.h>
-#include <malloc.h>
+#include <stdlib.h>
 #include "windows.h"
 #include "winerror.h"
 #include "wincon.h"
diff --git a/win32/init.c b/win32/init.c
index 6372a41..ddd5799 100644
--- a/win32/init.c
+++ b/win32/init.c
@@ -7,7 +7,7 @@
 #include <string.h>
 #include <stdio.h>
 #include <unistd.h>
-#include <malloc.h>
+#include <stdlib.h>
 #include "windows.h"
 #include "winerror.h"
 #include "handle32.h"
diff --git a/win32/process.c b/win32/process.c
index 7178bf7..54baf23 100644
--- a/win32/process.c
+++ b/win32/process.c
@@ -7,12 +7,14 @@
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/times.h>
 #include "windows.h"
 #include "winerror.h"
 #include "heap.h"
 #include "thread.h"
 #include "handle32.h"
 #include "pe_image.h"
+#include "file.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -312,6 +314,7 @@
 	fprintf(stderr,"ResetEvent(%d) stub\n",h);
 	return 0;
 }
+
 /***********************************************************************
  *           WaitForSingleObject    (KERNEL32.561)
  */
@@ -320,6 +323,21 @@
 	fprintf(stderr,"WaitForSingleObject(%d,%ld) stub\n",h,timeout);
 	return 0;
 }
+
+/***********************************************************************
+ *           WaitForSingleObject    (USER32.399)
+ */
+DWORD MsgWaitForMultipleObjects(
+	DWORD nCount,HANDLE32 *pHandles,BOOL32 fWaitAll,DWORD dwMilliseconds,
+	DWORD dwWakeMask
+) {
+	int	i;
+	fprintf(stderr,"MsgWaitForMultipleObjects(%ld,[",nCount);
+	for (i=0;i<nCount;i++)
+		fprintf(stderr,"%ld,",(DWORD)pHandles[i]);
+	fprintf(stderr,"],%d,%ld,0x%08lx)\n",fWaitAll,dwMilliseconds,dwWakeMask);
+	return 0;
+}
 /***********************************************************************
  *           DuplicateHandle    (KERNEL32.78)
  */
@@ -425,3 +443,28 @@
 	);
 	return TRUE;
 }
+
+BOOL32
+ContinueDebugEvent(DWORD pid,DWORD tid,DWORD contstatus) {
+	fprintf(stderr,"ContinueDebugEvent(%ld,%ld,%ld), stub\n",pid,tid,contstatus);
+	return TRUE;
+}
+
+/*********************************************************************
+ *	GetProcessTimes				[KERNEL32.262]
+ *
+ * FIXME: implement this better ...
+ */
+BOOL32
+GetProcessTimes(
+	HANDLE32 hprocess,LPFILETIME lpCreationTime,LPFILETIME lpExitTime,
+	LPFILETIME lpKernelTime, LPFILETIME lpUserTime
+) {
+	struct tms tms;
+
+	times(&tms);
+	DOSFS_UnixTimeToFileTime(tms.tms_utime,lpUserTime,0);
+	DOSFS_UnixTimeToFileTime(tms.tms_stime,lpKernelTime,0);
+	return TRUE;
+}
+
diff --git a/windows/dce.c b/windows/dce.c
index 8452147..d259fe0 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -234,29 +234,31 @@
  * removing from the given region the rectangle of each window offset
  * by a given amount.  The new region is returned, and the original one
  * is destroyed.  Used to implement DCX_CLIPSIBLINGS and
- * DCX_CLIPCHILDREN styles.
+ * DCX_CLIPCHILDREN styles. Now it skips managed windows 
+ * because we have no idea about decoration size anyway.
  */
 static HRGN32 DCE_ClipWindows( WND *pWndStart, WND *pWndEnd,
                                HRGN32 hrgn, int xoffset, int yoffset )
 {
     HRGN32 hrgnNew;
 
-    if (!pWndStart) return hrgn;
-    if (!(hrgnNew = CreateRectRgn32( 0, 0, 0, 0 )))
+    if ( pWndStart == NULL ) return hrgn;
+    if ( (hrgnNew = CreateRectRgn32( 0, 0, 0, 0 )) )
     {
-        DeleteObject32( hrgn );
-        return 0;
-    }
-    for (; pWndStart != pWndEnd; pWndStart = pWndStart->next)
-    {
-        if (!(pWndStart->dwStyle & WS_VISIBLE)) continue;
-        SetRectRgn32( hrgnNew, pWndStart->rectWindow.left + xoffset,
-                      pWndStart->rectWindow.top + yoffset,
-                      pWndStart->rectWindow.right + xoffset,
-                      pWndStart->rectWindow.bottom + yoffset );
-        if (!CombineRgn32( hrgn, hrgn, hrgnNew, RGN_DIFF )) break;
-    }
-    DeleteObject32( hrgnNew );
+	for (; pWndStart != pWndEnd; pWndStart = pWndStart->next)
+	{
+	    if ( !(pWndStart->dwStyle & WS_VISIBLE) ||
+		 (pWndStart->flags & WIN_MANAGED) ) continue;
+	    
+            SetRectRgn32( hrgnNew, pWndStart->rectWindow.left + xoffset,
+				   pWndStart->rectWindow.top + yoffset,
+				   pWndStart->rectWindow.right + xoffset,
+				   pWndStart->rectWindow.bottom + yoffset );
+	    if (!CombineRgn32( hrgn, hrgn, hrgnNew, RGN_DIFF )) break;
+        }
+        DeleteObject32( hrgnNew );
+    } else pWndEnd = NULL;
+
     if (pWndStart != pWndEnd)  /* something went wrong */
     {
         DeleteObject32( hrgn );
@@ -281,9 +283,6 @@
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
       /* Get visible rectangle and create a region with it. 
-       * do we really need to calculate vis rgns for X windows? 
-       * - yes, to clip child windows but we should skip 
-       *   siblings in this case.
        */
 
     if (!wndPtr || !DCE_GetVisRect( wndPtr, !(flags & DCX_WINDOW), &rect ))
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 66b8aae..2083d51 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -412,7 +412,7 @@
 
     case WM_SETTEXT:
 	DEFWND_SetText( wndPtr, (LPSTR)PTR_SEG_TO_LIN(lParam) );
-	NC_HandleNCPaint( hwnd , (HRGN32)1 );  /* Repaint caption */
+	if( wndPtr->dwStyle & WS_CAPTION ) NC_HandleNCPaint( hwnd , (HRGN32)1 );
         break;
 
     default:
diff --git a/windows/dialog.c b/windows/dialog.c
index ca234ad..f59cbd9 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -1565,11 +1565,12 @@
  *
  * Helper function for DlgDirList*
  */
-static INT32 DIALOG_DlgDirList( HWND32 hDlg, LPCSTR spec, INT32 idLBox,
+static INT32 DIALOG_DlgDirList( HWND32 hDlg, LPSTR spec, INT32 idLBox,
                                 INT32 idStatic, UINT32 attrib, BOOL32 combo )
 {
     int drive;
     HWND32 hwnd;
+    LPSTR orig_spec = spec;
 
 #define SENDMSG(msg,wparam,lparam) \
     ((attrib & DDL_POSTMSGS) ? PostMessage32A( hwnd, msg, wparam, lparam ) \
@@ -1586,41 +1587,42 @@
     }
     else drive = DRIVE_GetCurrentDrive();
 
+    /* If the path exists and is a directory, chdir to it */
+    if (!spec || !spec[0] || DRIVE_Chdir( drive, spec )) spec = "*.*";
+    else
+    {
+        char *p, *p2;
+        p = spec;
+        if ((p2 = strrchr( p, '\\' ))) p = p2;
+        if ((p2 = strrchr( p, '/' ))) p = p2;
+        if (p != spec)
+        {
+            char sep = *p;
+            *p = 0;
+            if (!DRIVE_Chdir( drive, spec ))
+            {
+                *p = sep;  /* Restore the original spec */
+                return FALSE;
+            }
+            spec = p + 1;
+        }
+    }
+
+    dprintf_dialog( stddeb, "ListBoxDirectory: path=%c:\\%s mask=%s\n",
+                    'A' + drive, DRIVE_GetDosCwd(drive), spec );
+
     if (idLBox && ((hwnd = GetDlgItem32( hDlg, idLBox )) != 0))
     {
-        /* If the path exists and is a directory, chdir to it */
-        if (!spec || !spec[0] || DRIVE_Chdir( drive, spec )) spec = "*.*";
-        else
-        {
-            const char *p, *p2;
-            p = spec;
-            if ((p2 = strrchr( p, '\\' ))) p = p2 + 1;
-            if ((p2 = strrchr( p, '/' ))) p = p2 + 1;
-            if (p != spec)
-            {
-                BOOL32 ret = FALSE;
-                char *dir = HeapAlloc( SystemHeap, 0, p - spec );
-                if (dir)
-                {
-                    lstrcpyn32A( dir, spec, p - spec );
-                    ret = DRIVE_Chdir( drive, dir );
-                    HeapFree( SystemHeap, 0, dir );
-                }
-                if (!ret) return FALSE;
-                spec = p;
-            }
-        }
-        
-        dprintf_dialog( stddeb, "ListBoxDirectory: path=%c:\\%s mask=%s\n",
-                        'A' + drive, DRIVE_GetDosCwd(drive), spec );
-        
         SENDMSG( combo ? CB_RESETCONTENT32 : LB_RESETCONTENT32, 0, 0 );
-        if ((attrib & DDL_DIRECTORY) && !(attrib & DDL_EXCLUSIVE))
+        if (attrib & DDL_DIRECTORY)
         {
-            if (SENDMSG( combo ? CB_DIR32 : LB_DIR32,
-                         attrib & ~(DDL_DIRECTORY | DDL_DRIVES),
-                         (LPARAM)spec ) == LB_ERR)
-                return FALSE;
+            if (!(attrib & DDL_EXCLUSIVE))
+            {
+                if (SENDMSG( combo ? CB_DIR32 : LB_DIR32,
+                             attrib & ~(DDL_DIRECTORY | DDL_DRIVES),
+                             (LPARAM)spec ) == LB_ERR)
+                    return FALSE;
+            }
             if (SENDMSG( combo ? CB_DIR32 : LB_DIR32,
                        (attrib & (DDL_DIRECTORY | DDL_DRIVES)) | DDL_EXCLUSIVE,
                          (LPARAM)"*.*" ) == LB_ERR)
@@ -1645,12 +1647,41 @@
         /* Can't use PostMessage() here, because the string is on the stack */
         SetDlgItemText32A( hDlg, idStatic, temp );
     }
+
+    if (orig_spec && (spec != orig_spec))
+    {
+        /* Update the original file spec */
+        char *p = spec;
+        while ((*orig_spec++ = *p++));
+    }
+
     return TRUE;
 #undef SENDMSG
 }
 
 
 /**********************************************************************
+ *	    DIALOG_DlgDirListW
+ *
+ * Helper function for DlgDirList*32W
+ */
+static INT32 DIALOG_DlgDirListW( HWND32 hDlg, LPWSTR spec, INT32 idLBox,
+                                 INT32 idStatic, UINT32 attrib, BOOL32 combo )
+{
+    if (spec)
+    {
+        LPSTR specA = HEAP_strdupWtoA( GetProcessHeap(), 0, spec );
+        INT32 ret = DIALOG_DlgDirList( hDlg, specA, idLBox, idStatic,
+                                       attrib, combo );
+        lstrcpyAtoW( spec, specA );
+        HeapFree( GetProcessHeap(), 0, specA );
+        return ret;
+    }
+    return DIALOG_DlgDirList( hDlg, NULL, idLBox, idStatic, attrib, combo );
+}
+
+
+/**********************************************************************
  *	    DlgDirSelect    (USER.99)
  */
 BOOL16 DlgDirSelect( HWND16 hwnd, LPSTR str, INT16 id )
@@ -1725,7 +1756,7 @@
 /**********************************************************************
  *	    DlgDirList16    (USER.100)
  */
-INT16 DlgDirList16( HWND16 hDlg, LPCSTR spec, INT16 idLBox, INT16 idStatic,
+INT16 DlgDirList16( HWND16 hDlg, LPSTR spec, INT16 idLBox, INT16 idStatic,
                     UINT16 attrib )
 {
     return DIALOG_DlgDirList( hDlg, spec, idLBox, idStatic, attrib, FALSE );
@@ -1735,7 +1766,7 @@
 /**********************************************************************
  *	    DlgDirList32A    (USER32.142)
  */
-INT32 DlgDirList32A( HWND32 hDlg, LPCSTR spec, INT32 idLBox, INT32 idStatic,
+INT32 DlgDirList32A( HWND32 hDlg, LPSTR spec, INT32 idLBox, INT32 idStatic,
                      UINT32 attrib )
 {
     return DIALOG_DlgDirList( hDlg, spec, idLBox, idStatic, attrib, FALSE );
@@ -1745,21 +1776,17 @@
 /**********************************************************************
  *	    DlgDirList32W    (USER32.145)
  */
-INT32 DlgDirList32W( HWND32 hDlg, LPCWSTR spec, INT32 idLBox, INT32 idStatic,
+INT32 DlgDirList32W( HWND32 hDlg, LPWSTR spec, INT32 idLBox, INT32 idStatic,
                      UINT32 attrib )
 {
-    INT32 ret;
-    LPSTR specA = HEAP_strdupWtoA( GetProcessHeap(), 0, spec );
-    ret = DIALOG_DlgDirList( hDlg, specA, idLBox, idStatic, attrib, FALSE );
-    HeapFree( GetProcessHeap(), 0, specA );
-    return ret;
+    return DIALOG_DlgDirListW( hDlg, spec, idLBox, idStatic, attrib, FALSE );
 }
 
 
 /**********************************************************************
  *	    DlgDirListComboBox16    (USER.195)
  */
-INT16 DlgDirListComboBox16( HWND16 hDlg, LPCSTR spec, INT16 idCBox,
+INT16 DlgDirListComboBox16( HWND16 hDlg, LPSTR spec, INT16 idCBox,
                             INT16 idStatic, UINT16 attrib )
 {
     return DIALOG_DlgDirList( hDlg, spec, idCBox, idStatic, attrib, TRUE );
@@ -1769,7 +1796,7 @@
 /**********************************************************************
  *	    DlgDirListComboBox32A    (USER32.143)
  */
-INT32 DlgDirListComboBox32A( HWND32 hDlg, LPCSTR spec, INT32 idCBox,
+INT32 DlgDirListComboBox32A( HWND32 hDlg, LPSTR spec, INT32 idCBox,
                              INT32 idStatic, UINT32 attrib )
 {
     return DIALOG_DlgDirList( hDlg, spec, idCBox, idStatic, attrib, TRUE );
@@ -1779,12 +1806,8 @@
 /**********************************************************************
  *	    DlgDirListComboBox32W    (USER32.144)
  */
-INT32 DlgDirListComboBox32W( HWND32 hDlg, LPCWSTR spec, INT32 idCBox,
+INT32 DlgDirListComboBox32W( HWND32 hDlg, LPWSTR spec, INT32 idCBox,
                              INT32 idStatic, UINT32 attrib )
 {
-    INT32 ret;
-    LPSTR specA = HEAP_strdupWtoA( GetProcessHeap(), 0, spec );
-    ret = DIALOG_DlgDirList( hDlg, specA, idCBox, idStatic, attrib, FALSE );
-    HeapFree( GetProcessHeap(), 0, specA );
-    return ret;
+    return DIALOG_DlgDirListW( hDlg, spec, idCBox, idStatic, attrib, TRUE );
 }
diff --git a/windows/event.c b/windows/event.c
index 86c3129..fa01908 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -82,11 +82,11 @@
 
   /* Event handlers */
 static void EVENT_Key( XKeyEvent *event );
-static void EVENT_ButtonPress( XButtonEvent *event );
-static void EVENT_ButtonRelease( XButtonEvent *event );
-static void EVENT_MotionNotify( XMotionEvent *event );
-static void EVENT_FocusIn( HWND32 hwnd, XFocusChangeEvent *event );
-static void EVENT_FocusOut( HWND32 hwnd, XFocusChangeEvent *event );
+static void EVENT_ButtonPress( WND *pWnd, XButtonEvent *event );
+static void EVENT_ButtonRelease( WND *pWnd, XButtonEvent *event );
+static void EVENT_MotionNotify( WND *pWnd, XMotionEvent *event );
+static void EVENT_FocusIn( WND *pWnd, XFocusChangeEvent *event );
+static void EVENT_FocusOut( WND *pWnd, XFocusChangeEvent *event );
 static void EVENT_Expose( WND *pWnd, XExposeEvent *event );
 static void EVENT_GraphicsExpose( WND *pWnd, XGraphicsExposeEvent *event );
 static void EVENT_ConfigureNotify( HWND32 hwnd, XConfigureEvent *event );
@@ -129,12 +129,12 @@
 	
     case ButtonPress:
         if (InputEnabled)
-            EVENT_ButtonPress( (XButtonEvent*)event );
+            EVENT_ButtonPress( pWnd, (XButtonEvent*)event );
 	break;
 
     case ButtonRelease:
         if (InputEnabled)
-            EVENT_ButtonRelease( (XButtonEvent*)event );
+            EVENT_ButtonRelease( pWnd, (XButtonEvent*)event );
 	break;
 
     case MotionNotify:
@@ -150,16 +150,16 @@
 	{
             while (XCheckTypedWindowEvent(display,((XAnyEvent *)event)->window,
                                           MotionNotify, event));    
-            EVENT_MotionNotify( (XMotionEvent*)event );
+            EVENT_MotionNotify( pWnd, (XMotionEvent*)event );
 	}
 	break;
 
     case FocusIn:
-        EVENT_FocusIn( pWnd->hwndSelf, (XFocusChangeEvent*)event );
+        EVENT_FocusIn( pWnd, (XFocusChangeEvent*)event );
 	break;
 
     case FocusOut:
-	EVENT_FocusOut( pWnd->hwndSelf, (XFocusChangeEvent*)event );
+	EVENT_FocusOut( pWnd, (XFocusChangeEvent*)event );
 	break;
 
     case Expose:
@@ -380,6 +380,108 @@
     }    
 }
 
+/***********************************************************************
+ *           EVENT_QueryZOrder
+ *
+ * Try to synchronize internal z-order with the window manager's.
+ */
+static BOOL32 __check_query_condition( WND** pWndA, WND** pWndB )
+{
+    /* return TRUE if we have at least two managed windows */
+
+    for( *pWndB = NULL; *pWndA; *pWndA = (*pWndA)->next )
+        if( (*pWndA)->flags & WIN_MANAGED &&
+            (*pWndA)->dwStyle & WS_VISIBLE ) break;
+    if( *pWndA )
+        for( *pWndB = (*pWndA)->next; *pWndB; *pWndB = (*pWndB)->next )
+            if( (*pWndB)->flags & WIN_MANAGED &&
+                (*pWndB)->dwStyle & WS_VISIBLE ) break;
+     return ((*pWndB) != NULL);
+}
+
+static Window __get_common_ancestor( Window A, Window B,
+                                     Window** children, unsigned* total )
+{
+    /* find the real root window */
+
+    Window      root, *childrenB;
+    unsigned    totalB;
+
+    do
+    {
+        if( *children ) XFree( *children );
+        XQueryTree( display, A, &root, &A, children, total );
+        XQueryTree( display, B, &root, &B, &childrenB, &totalB );
+        if( childrenB ) XFree( childrenB );
+    } while( A != B && A && B );
+    return ( A && B ) ? A : 0 ;
+}
+
+static Window __get_top_decoration( Window w, Window ancestor )
+{
+    Window*     children, root, prev = w, parent = w;
+    unsigned    total;
+
+    do
+    {
+        w = parent;
+        XQueryTree( display, w, &root, &parent, &children, &total );
+        if( children ) XFree( children );
+    } while( parent && parent != ancestor );
+    dprintf_event( stddeb, "\t%08x -> %08x\n", (unsigned)prev, (unsigned)w );
+    return ( parent ) ? w : 0 ;
+}
+
+static unsigned __td_lookup( Window w, Window* list, unsigned max )
+{
+    unsigned    i;
+    for( i = 0; i < max; i++ ) if( list[i] == w ) break;
+    return i;
+}
+
+static BOOL32 EVENT_QueryZOrder( WND* pWndCheck )
+{
+    BOOL32      bRet = FALSE;
+    HWND32      hwndInsertAfter = HWND_TOP;
+    WND*        pWnd, *pWndZ = WIN_GetDesktop()->child;
+    Window      w, parent, *children = NULL;
+    unsigned    total, check, pos, best;
+
+    if( !__check_query_condition(&pWndZ, &pWnd) ) return TRUE;
+
+    parent = __get_common_ancestor( pWndZ->window, pWnd->window,
+                                      &children, &total );
+    if( parent )
+    {
+        w = __get_top_decoration( pWndCheck->window, parent );
+        if( w != children[total - 1] )
+        {
+            check = __td_lookup( w, children, total );
+            best = total;
+            for( pWnd = pWndZ; pWnd; pWnd = pWnd->next )
+            {
+                if( pWnd != pWndCheck )
+                {
+                    if( !(pWnd->flags & WIN_MANAGED) ||
+                        !(w = __get_top_decoration( pWnd->window, parent )) )
+                        continue;
+                    pos = __td_lookup( w, children, total );
+                    if( pos < best && pos > check )
+                    {
+                        best = pos;
+                        hwndInsertAfter = pWnd->hwndSelf;
+                    }
+                    if( check - best == 1 ) break;
+                }
+            }
+            WIN_UnlinkWindow( pWndCheck->hwndSelf );
+            WIN_LinkWindow( pWndCheck->hwndSelf, hwndInsertAfter);
+        }
+    }
+    if( children ) XFree( children );
+    return bRet;
+}
+
 
 /***********************************************************************
  *           EVENT_XStateToKeyState
@@ -455,11 +557,11 @@
 /***********************************************************************
  *           EVENT_MotionNotify
  */
-static void EVENT_MotionNotify( XMotionEvent *event )
+static void EVENT_MotionNotify( WND *pWnd, XMotionEvent *event )
 {
     hardware_event( WM_MOUSEMOVE, EVENT_XStateToKeyState( event->state ), 0L,
 		    event->x_root - desktopX, event->y_root - desktopY,
-		    event->time - MSG_WineStartTicks, 0 );
+		    event->time - MSG_WineStartTicks, (DWORD)pWnd->hwndSelf );
 }
 
 
@@ -486,7 +588,7 @@
 /***********************************************************************
  *           EVENT_ButtonPress
  */
-static void EVENT_ButtonPress( XButtonEvent *event )
+static void EVENT_ButtonPress( WND *pWnd, XButtonEvent *event )
 {
     static WORD messages[NB_BUTTONS] = 
         { WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN };
@@ -499,14 +601,14 @@
     hardware_event( messages[buttonNum],
 		    EVENT_XStateToKeyState( event->state ), 0L,
 		    event->x_root - desktopX, event->y_root - desktopY,
-		    event->time - MSG_WineStartTicks, 0 );
+		    event->time - MSG_WineStartTicks, (DWORD)pWnd->hwndSelf );
 }
 
 
 /***********************************************************************
  *           EVENT_ButtonRelease
  */
-static void EVENT_ButtonRelease( XButtonEvent *event )
+static void EVENT_ButtonRelease( WND *pWnd, XButtonEvent *event )
 {
     static const WORD messages[NB_BUTTONS] = 
         { WM_LBUTTONUP, WM_MBUTTONUP, WM_RBUTTONUP };
@@ -518,19 +620,26 @@
     hardware_event( messages[buttonNum],
 		    EVENT_XStateToKeyState( event->state ), 0L,
 		    event->x_root - desktopX, event->y_root - desktopY,
-		    event->time - MSG_WineStartTicks, 0 );
+		    event->time - MSG_WineStartTicks, (DWORD)pWnd->hwndSelf );
 }
 
 
 /**********************************************************************
  *              EVENT_FocusIn
  */
-static void EVENT_FocusIn( HWND32 hwnd, XFocusChangeEvent *event )
+static void EVENT_FocusIn( WND *pWnd, XFocusChangeEvent *event )
 {
-    if (event->detail == NotifyPointer) return;
-    if (hwnd != GetActiveWindow32()) WINPOS_ChangeActiveWindow( hwnd, FALSE );
-    if ((hwnd != GetFocus32()) && !IsChild32( hwnd, GetFocus32()))
-        SetFocus32( hwnd );
+    if (Options.managed) EVENT_QueryZOrder( pWnd );
+
+    if (event->detail != NotifyPointer)
+    { 
+	HWND32	hwnd = pWnd->hwndSelf;
+
+	if (hwnd != GetActiveWindow32()) 
+	    WINPOS_ChangeActiveWindow( hwnd, FALSE );
+	if ((hwnd != GetFocus32()) && !IsChild32( hwnd, GetFocus32()))
+            SetFocus32( hwnd );
+    }
 }
 
 
@@ -539,12 +648,17 @@
  *
  * Note: only top-level override-redirect windows get FocusOut events.
  */
-static void EVENT_FocusOut( HWND32 hwnd, XFocusChangeEvent *event )
+static void EVENT_FocusOut( WND *pWnd, XFocusChangeEvent *event )
 {
-    if (event->detail == NotifyPointer) return;
-    if (hwnd == GetActiveWindow32()) WINPOS_ChangeActiveWindow( 0, FALSE );
-    if ((hwnd == GetFocus32()) || IsChild32( hwnd, GetFocus32()))
-        SetFocus32( 0 );
+    if (event->detail != NotifyPointer)
+    {
+	HWND32	hwnd = pWnd->hwndSelf;
+
+	if (hwnd == GetActiveWindow32()) 
+	    WINPOS_ChangeActiveWindow( 0, FALSE );
+	if ((hwnd == GetFocus32()) || IsChild32( hwnd, GetFocus32()))
+	    SetFocus32( 0 );
+    }
 }
 
 /**********************************************************************
@@ -582,16 +696,14 @@
     }
     else
     {
-        WND *wndPtr;
+        WND *wndPtr = WIN_FindWndPtr( hwnd );
 	WINDOWPOS16 *winpos;
 	RECT16 newWindowRect, newClientRect;
 	HRGN32 hrgnOldPos, hrgnNewPos;
+	Window above = event->above;
 
-	if (!(wndPtr = WIN_FindWndPtr( hwnd )) ||
-	    !(wndPtr->flags & WIN_MANAGED) )
-	    return;
-	
-        if (!(winpos = SEGPTR_NEW(WINDOWPOS16))) return;
+	if (!wndPtr || !(wndPtr->flags & WIN_MANAGED) ||
+            !(winpos = SEGPTR_NEW(WINDOWPOS16))) return;
 
 	/* Fill WINDOWPOS struct */
 	winpos->flags = SWP_NOACTIVATE | SWP_NOZORDER;
@@ -630,12 +742,17 @@
 	wndPtr->rectWindow = newWindowRect;
 	wndPtr->rectClient = newClientRect;
 	SendMessage16( hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)SEGPTR_GET(winpos));
+
         SEGPTR_FREE(winpos);
 
-        /* full window drag leaves unrepainted garbage without this */
-        PAINT_RedrawWindow( 0, NULL, hrgnOldPos, RDW_INVALIDATE |
-                            RDW_ALLCHILDREN | RDW_ERASE | RDW_ERASENOW,
-                            RDW_C_USEHRGN );
+	if( IsWindow32( hwnd ) )
+	    if( above == None )			/* absolute bottom */
+	    {
+        	WIN_UnlinkWindow( hwnd );
+        	WIN_LinkWindow( hwnd, HWND_BOTTOM);
+	    }
+	    else EVENT_QueryZOrder( wndPtr );	/* try to outsmart window manager */
+
         DeleteObject32(hrgnOldPos);
         DeleteObject32(hrgnNewPos);
     }
diff --git a/windows/mdi.c b/windows/mdi.c
index d8bb5a3..e08e08d 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -609,7 +609,7 @@
  *
  *  iTotal returns number of children available for tiling or cascading
  */
-static MDIWCL* MDI_BuildWCL(WND* clientWnd, INT16* iTotal)
+static MDIWCL* MDI_BuildWCL(WND* clientWnd, UINT16* iTotal)
 {
     MDIWCL *listTop,*listNext;
     WND    *childWnd;
@@ -693,9 +693,10 @@
  */
 static LONG MDICascade(WND* clientWnd, MDICLIENTINFO *ci)
 {
-    MDIWCL	 *listTop,*listPrev;
-    INT16	  delta = 0,iToPosition = 0, n = 0;
-    POINT16       pos[2];
+	MDIWCL	*listTop,*listPrev;
+	INT16	delta = 0, n = 0;
+	UINT16	iToPosition = 0;
+	POINT16	pos[2];
   
     if (ci->hwndChildMaximized)
         ShowWindow16( ci->hwndChildMaximized, SW_NORMAL);
@@ -744,7 +745,7 @@
     int		  rows, columns;
     int           r, c;
     int           i;
-    INT16	  iToPosition = 0;
+    UINT16	  iToPosition = 0;
 
     if (ci->hwndChildMaximized)
 	ShowWindow16(ci->hwndChildMaximized, SW_NORMAL);
diff --git a/windows/message.c b/windows/message.c
index 38deb9e..751212c 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -23,6 +23,7 @@
 #include "dde.h"
 #include "queue.h"
 #include "winproc.h"
+#include "options.h"
 #include "stddebug.h"
 /* #define DEBUG_MSG */
 #include "debug.h"
@@ -59,8 +60,8 @@
  * to the user, left in the queue, or skipped entirely (in this case
  * HIWORD contains hit test code).
  */
-static DWORD MSG_TranslateMouseMsg( HWND16 hWndScope, DWORD filter, 
-				    MSG16 *msg, BOOL32 remove )
+static DWORD MSG_TranslateMouseMsg( HWND16 hTopWnd, DWORD filter, 
+				    MSG16 *msg, BOOL32 remove, WND* pWndScope )
 {
     static DWORD   dblclk_time_limit = 0;
     static UINT16     clk_message = 0;
@@ -86,10 +87,10 @@
     hWnd = GetCapture16();
     if( !hWnd )
     {
-	sendSC = 1;
-	ht = hittest = WINPOS_WindowFromPoint( WIN_GetDesktop(), msg->pt, &pWnd );
+	ht = hittest = WINPOS_WindowFromPoint( pWndScope, msg->pt, &pWnd );
 	if( !pWnd ) pWnd = WIN_GetDesktop();
 	hWnd = pWnd->hwndSelf;
+	sendSC = 1;
     } 
     else 
     {
@@ -111,8 +112,8 @@
 
 	/* check if hWnd is within hWndScope */
 
-    if( hWndScope && hWnd != hWndScope )
-	if( !IsChild16(hWndScope, hWnd) ) return SYSQ_MSG_CONTINUE;
+    if( hTopWnd && hWnd != hTopWnd )
+	if( !IsChild16(hTopWnd, hWnd) ) return SYSQ_MSG_CONTINUE;
 
     if( mouseClick )
     {
@@ -229,7 +230,7 @@
  *
  * Translate an keyboard hardware event into a real message.
  */
-static DWORD MSG_TranslateKbdMsg( HWND16 hWndScope, DWORD filter,
+static DWORD MSG_TranslateKbdMsg( HWND16 hTopWnd, DWORD filter,
 				  MSG16 *msg, BOOL32 remove )
 {
     WORD message = msg->message;
@@ -260,8 +261,8 @@
         return SYSQ_MSG_ABANDON;
     }
 
-    if (hWndScope && hWnd != hWndScope)
-	if (!IsChild16(hWndScope, hWnd)) return SYSQ_MSG_CONTINUE;
+    if (hTopWnd && hWnd != hTopWnd)
+	if (!IsChild16(hTopWnd, hWnd)) return SYSQ_MSG_CONTINUE;
     if (!MSG_CheckFilter(message, filter)) return SYSQ_MSG_CONTINUE;
 
     msg->hwnd = hWnd;
@@ -424,7 +425,11 @@
 
         if ((msg->message >= WM_MOUSEFIRST) && (msg->message <= WM_MOUSELAST))
         {
-            status = MSG_TranslateMouseMsg(hwnd, filter, msg, remove);
+	    HWND32 hWndScope = (HWND32)sysMsgQueue->messages[pos].extraInfo;
+
+	    status = MSG_TranslateMouseMsg(hwnd, filter, msg, remove, 
+					  (Options.managed && IsWindow32(hWndScope) ) 
+					   ? WIN_FindWndPtr(hWndScope) : WIN_GetDesktop() );
 	    kbd_msg = 0;
         }
         else if ((msg->message >= WM_KEYFIRST) && (msg->message <= WM_KEYLAST))
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 085b817..e0c6412 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -121,7 +121,7 @@
 
     if (!(style & (WS_POPUP | WS_CHILD)))  /* Overlapped window */
 	style |= WS_CAPTION;
-    style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME);
+    style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
     exStyle &= WS_EX_DLGMODALFRAME;
     if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
 
@@ -277,8 +277,7 @@
     rect->right  = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
     rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
 
-    if (wndPtr->dwStyle & WS_ICONIC) return;  /* No border to remove */
-    if (wndPtr->flags & WIN_MANAGED) return;
+    if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) return;
 
       /* Remove frame from rectangle */
     if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
diff --git a/windows/user.c b/windows/user.c
index a5c6ce8..b20670f 100644
--- a/windows/user.c
+++ b/windows/user.c
@@ -22,6 +22,7 @@
 WORD USER_HeapSel = 0;
 
 extern BOOL32 MENU_SwitchTPWndTo(HTASK16);
+extern void QUEUE_FlushMessages(HQUEUE16);
 
 /***********************************************************************
  *           GetFreeSystemResources   (USER.284)
diff --git a/windows/winpos.c b/windows/winpos.c
index 97bbb24..d588de4 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -281,12 +281,12 @@
 {
     WND *wndPtr;
     INT16 hittest = HTERROR;
-    INT16 x, y;
+    POINT16 xy = pt;
 
     *ppWnd = NULL;
-    x = pt.x;
-    y = pt.y;
     wndPtr = wndScope->child;
+    MapWindowPoints16( GetDesktopWindow16(), wndScope->hwndSelf, &xy, 1 );
+
     for (;;)
     {
         while (wndPtr)
@@ -298,10 +298,10 @@
             if ((wndPtr->dwStyle & WS_VISIBLE) &&
                 (!(wndPtr->dwStyle & WS_DISABLED) ||
                  ((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD)) &&
-                (x >= wndPtr->rectWindow.left) &&
-                (x < wndPtr->rectWindow.right) &&
-                (y >= wndPtr->rectWindow.top) &&
-                (y < wndPtr->rectWindow.bottom))
+                (xy.x >= wndPtr->rectWindow.left) &&
+                (xy.x < wndPtr->rectWindow.right) &&
+                (xy.y >= wndPtr->rectWindow.top) &&
+                (xy.y < wndPtr->rectWindow.bottom))
             {
                 *ppWnd = wndPtr;  /* Got a suitable window */
 
@@ -310,45 +310,35 @@
                 if (wndPtr->dwStyle & WS_DISABLED) return HTERROR;
 
                 /* If point is not in client area, ignore the children */
-                if ((x < wndPtr->rectClient.left) ||
-                    (x >= wndPtr->rectClient.right) ||
-                    (y < wndPtr->rectClient.top) ||
-                    (y >= wndPtr->rectClient.bottom)) break;
+                if ((xy.x < wndPtr->rectClient.left) ||
+                    (xy.x >= wndPtr->rectClient.right) ||
+                    (xy.y < wndPtr->rectClient.top) ||
+                    (xy.y >= wndPtr->rectClient.bottom)) break;
 
-                x -= wndPtr->rectClient.left;
-                y -= wndPtr->rectClient.top;
+                xy.x -= wndPtr->rectClient.left;
+                xy.y -= wndPtr->rectClient.top;
                 wndPtr = wndPtr->child;
             }
             else wndPtr = wndPtr->next;
         }
 
-        /* If nothing found, return the scope window */
-        if (!*ppWnd)
-        {
-            *ppWnd = wndScope;
-            if( pt.x >= (wndScope->rectClient.left - wndScope->rectWindow.left) &&
-                pt.x >= (wndScope->rectClient.top - wndScope->rectWindow.top ) &&
-                pt.x <= (wndScope->rectClient.right - wndScope->rectWindow.left) &&
-                pt.x <= (wndScope->rectClient.bottom - wndScope->rectWindow.top ) )
-                return HTCLIENT;
-	    if( pt.x < 0 || pt.y < 0 || 
-		pt.x > (wndScope->rectWindow.right - wndScope->rectWindow.left) ||
-		pt.y > (wndScope->rectWindow.bottom - wndScope->rectWindow.top ) )
-		return HTNOWHERE;
-	    return HTCAPTION;	/* doesn't matter in this case */
-        }
+        /* If nothing found, try the scope window */
+        if (!*ppWnd) *ppWnd = wndScope;
 
         /* Send the WM_NCHITTEST message (only if to the same task) */
-        if ((*ppWnd)->hmemTaskQ != GetTaskQueue(0)) return HTCLIENT;
-        hittest = (INT16)SendMessage16( (*ppWnd)->hwndSelf, WM_NCHITTEST, 0,
-                                    MAKELONG( pt.x, pt.y ) );
-        if (hittest != HTTRANSPARENT) return hittest;  /* Found the window */
+        if ((*ppWnd)->hmemTaskQ == GetTaskQueue(0))
+	{
+            hittest = (INT16)SendMessage16( (*ppWnd)->hwndSelf, WM_NCHITTEST, 
+						 0, MAKELONG( pt.x, pt.y ) );
+	    if (hittest != HTTRANSPARENT) return hittest;  /* Found the window */
+	}
+	else return HTCLIENT;
 
-        /* If no children found in last search, make point relative to parent*/
+        /* If no children found in last search, make point relative to parent */
         if (!wndPtr)
         {
-            x += (*ppWnd)->rectClient.left;
-            y += (*ppWnd)->rectClient.top;
+            xy.x += (*ppWnd)->rectClient.left;
+            xy.y += (*ppWnd)->rectClient.top;
         }
 
         /* Restart the search from the next sibling */
diff --git a/windows/winproc.c b/windows/winproc.c
index 4fbde92..9e7e3b3 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -7,7 +7,6 @@
 
 #include <stdio.h>
 #include "windows.h"
-#include "callback.h"
 #include "heap.h"
 #include "selectors.h"
 #include "stackframe.h"
@@ -95,16 +94,20 @@
                                         UINT32 msg, WPARAM32 wParam,
                                         LPARAM lParam );
 
-#ifndef WINELIB
 extern void CallFrom16_long_wwwll(void);
 extern void CallFrom32_stdcall_5(void);
-#else
-static void CallFrom16_long_wwwll(void) {}
-static void CallFrom32_stdcall_5(void) {}
-#endif  /* WINELIB */
 
 static HANDLE32 WinProcHeap;
 
+static LRESULT WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd, UINT16 msg,
+                                      WPARAM16 wParam, LPARAM lParam );
+static LRESULT WINPROC_CallWndProc32( WNDPROC32 proc, HWND32 hwnd, UINT32 msg,
+                                      WPARAM32 wParam, LPARAM lParam );
+
+static WINPROC_CALLWNDPROC16 WINPROC_CallWndProc16Ptr = WINPROC_CallWndProc16;
+static WINPROC_CALLWNDPROC32 WINPROC_CallWndProc32Ptr = WINPROC_CallWndProc32;
+
+
 /**********************************************************************
  *	     WINPROC_Init
  */
@@ -121,6 +124,48 @@
 
 
 /**********************************************************************
+ *	     WINPROC_CallWndProc16
+ *
+ * Call a 16-bit WndProc.
+ */
+static LRESULT WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd, UINT16 msg,
+                                      WPARAM16 wParam, LPARAM lParam )
+{
+    return proc( hwnd, msg, wParam, lParam );
+}
+
+
+/**********************************************************************
+ *	     WINPROC_CallWndProc32
+ *
+ * Call a 32-bit WndProc.
+ */
+static LRESULT WINPROC_CallWndProc32( WNDPROC32 proc, HWND32 hwnd, UINT32 msg,
+                                      WPARAM32 wParam, LPARAM lParam )
+{
+    return proc( hwnd, msg, wParam, lParam );
+}
+
+
+/**********************************************************************
+ *	     WINPROC_SetCallWndProc16
+ */
+void WINPROC_SetCallWndProc16( WINPROC_CALLWNDPROC16 proc )
+{
+    WINPROC_CallWndProc16Ptr = proc;
+}
+
+
+/**********************************************************************
+ *	     WINPROC_SetCallWndProc32
+ */
+void WINPROC_SetCallWndProc32( WINPROC_CALLWNDPROC32 proc )
+{
+    WINPROC_CallWndProc32Ptr = proc;
+}
+
+
+/**********************************************************************
  *	     WINPROC_GetPtr
  *
  * Return a pointer to the win proc.
@@ -1676,7 +1721,7 @@
     LRESULT result;
 
     if (WINPROC_MapMsg32ATo32W( msg, wParam, &lParam ) == -1) return 0;
-    result = CallWndProc32( func, hwnd, msg, wParam, lParam );
+    result = WINPROC_CallWndProc32Ptr( func, hwnd, msg, wParam, lParam );
     WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
     return result;
 }
@@ -1694,7 +1739,7 @@
     LRESULT result;
 
     if (WINPROC_MapMsg32WTo32A( msg, wParam, &lParam ) == -1) return 0;
-    result = CallWndProc32( func, hwnd, msg, wParam, lParam );
+    result = WINPROC_CallWndProc32Ptr( func, hwnd, msg, wParam, lParam );
     WINPROC_UnmapMsg32WTo32A( msg, wParam, lParam );
     return result;
 }
@@ -1715,7 +1760,7 @@
 
     if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
         return 0;
-    result = CallWndProc32( func, hwnd, msg32, wParam32, lParam );
+    result = WINPROC_CallWndProc32Ptr( func, hwnd, msg32, wParam32, lParam );
     WINPROC_UnmapMsg16To32A( msg32, wParam32, lParam );
     return result;
 }
@@ -1736,7 +1781,7 @@
 
     if (WINPROC_MapMsg16To32W( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
         return 0;
-    result = CallWndProc32( func, hwnd, msg32, wParam32, lParam );
+    result = WINPROC_CallWndProc32Ptr( func, hwnd, msg32, wParam32, lParam );
     WINPROC_UnmapMsg16To32W( msg32, wParam32, lParam );
     return result;
 }
@@ -1761,7 +1806,8 @@
 			      &msg16, &mp16.wParam, &mp16.lParam ) == -1)
         return 0;
     if (wndPtr) CURRENT_DS = wndPtr->hInstance;
-    mp16.lResult = CallWndProc16( func, hwnd, msg16, mp16.wParam, mp16.lParam );
+    mp16.lResult = WINPROC_CallWndProc16Ptr( func, hwnd, msg16,
+                                             mp16.wParam, mp16.lParam );
     CURRENT_DS = ds;
     WINPROC_UnmapMsg32ATo16( msg, wParam, lParam, &mp16 );
     return mp16.lResult;
@@ -1786,7 +1832,8 @@
     if (WINPROC_MapMsg32WTo16( msg, wParam, &msg16, &mp16.wParam, &mp16.lParam ) == -1)
         return 0;
     if (wndPtr) CURRENT_DS = wndPtr->hInstance;
-    mp16.lResult = CallWndProc16( func, hwnd, msg16, mp16.wParam, mp16.lParam );
+    mp16.lResult = WINPROC_CallWndProc16Ptr( func, hwnd, msg16,
+                                             mp16.wParam, mp16.lParam );
     CURRENT_DS = ds;
     WINPROC_UnmapMsg32WTo16( msg, wParam, lParam, &mp16 );
     return mp16.lResult;
@@ -1808,15 +1855,15 @@
     {
         wndPtr = WIN_FindWndPtr( hwnd );
         if (wndPtr) CURRENT_DS = wndPtr->hInstance;
-        result = CallWndProc16( (FARPROC16)func, hwnd, msg, wParam, lParam );
+        result = WINPROC_CallWndProc16Ptr( func, hwnd, msg, wParam, lParam );
         CURRENT_DS = ds;
         return result;
     }
 #if testing
     wndPtr = WIN_FindWndPtr( hwnd );
     if (wndPtr) CURRENT_DS = wndPtr->hInstance;
-    result = CallWndProc16( WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16),
-                            hwnd, msg, wParam, lParam );
+    result = WINPROC_CallWndProc16Ptr( WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16),
+                                       hwnd, msg, wParam, lParam );
     CURRENT_DS = ds;
     return result;
 #endif
@@ -1827,25 +1874,8 @@
         if (!proc->thunk.t_from32.proc) return 0;
         wndPtr = WIN_FindWndPtr( hwnd );
         if (wndPtr) CURRENT_DS = wndPtr->hInstance;
-#ifndef WINELIB
-        if ((msg == WM_CREATE) || (msg == WM_NCCREATE))
-        {
-            CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
-            /* Build the CREATESTRUCT on the 16-bit stack. */
-            /* This is really ugly, but some programs (notably the */
-            /* "Undocumented Windows" examples) want it that way.  */
-            result = CallWndProcNCCREATE16( proc->thunk.t_from32.proc,
-                    cs->dwExStyle, cs->lpszClass, cs->lpszName, cs->style,
-                    cs->x, cs->y, cs->cx, cs->cy, cs->hwndParent, cs->hMenu,
-                    cs->hInstance, (LONG)cs->lpCreateParams, hwnd, msg, wParam,
-                    MAKELONG( IF1632_Saved16_sp-sizeof(CREATESTRUCT16),
-                              IF1632_Saved16_ss ) );
-            CURRENT_DS = ds;
-            return result;
-        }
-#endif
-        result = CallWndProc16( proc->thunk.t_from32.proc,
-                                hwnd, msg, wParam, lParam );
+        result = WINPROC_CallWndProc16Ptr( proc->thunk.t_from32.proc,
+                                           hwnd, msg, wParam, lParam );
         CURRENT_DS = ds;
         return result;
 
@@ -1872,11 +1902,12 @@
 {
     WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
 
-    if (!proc) return CallWndProc32( func, hwnd, msg, wParam, lParam );
+    if (!proc) return WINPROC_CallWndProc32Ptr( func, hwnd, msg,
+                                                wParam, lParam );
 
 #if testing
     func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
-    return CallWndProc32( func, hwnd, msg, wParam, lParam );
+    return WINPROC_CallWndProc32Ptr( func, hwnd, msg, wParam, lParam );
 #endif
 
     switch(proc->type)
@@ -1887,8 +1918,8 @@
                                         hwnd, msg, wParam, lParam );
     case WIN_PROC_32A:
         if (!proc->thunk.t_from16.proc) return 0;
-        return CallWndProc32( proc->thunk.t_from16.proc,
-                              hwnd, msg, wParam, lParam );
+        return WINPROC_CallWndProc32Ptr( proc->thunk.t_from16.proc,
+                                         hwnd, msg, wParam, lParam );
     case WIN_PROC_32W:
         if (!proc->thunk.t_from16.proc) return 0;
         return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
@@ -1908,11 +1939,12 @@
 {
     WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
 
-    if (!proc) return CallWndProc32( func, hwnd, msg, wParam, lParam );
+    if (!proc) return WINPROC_CallWndProc32Ptr( func, hwnd, msg,
+                                                wParam, lParam );
 
 #if testing
     func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
-    return CallWndProc32( func, hwnd, msg, wParam, lParam );
+    return WINPROC_CallWndProc32Ptr( func, hwnd, msg, wParam, lParam );
 #endif
 
     switch(proc->type)
@@ -1927,8 +1959,8 @@
                                          hwnd, msg, wParam, lParam );
     case WIN_PROC_32W:
         if (!proc->thunk.t_from16.proc) return 0;
-        return CallWndProc32( proc->thunk.t_from16.proc,
-                              hwnd, msg, wParam, lParam );
+        return WINPROC_CallWndProc32Ptr( proc->thunk.t_from16.proc,
+                                         hwnd, msg, wParam, lParam );
     default:
         fprintf( stderr, "CallWindowProc32W: invalid proc %p\n", proc );
         return 0;