Release 971101

Thu Oct 30 21:52:23 1997  Martin Boehme <boehme@informatik.mu-luebeck.de>

	* [windows/nonclient.c]
	Changed NC_TrackSysMenu to give the same behaviour as MS-Windows,
	i.e. system menu already appears when mouse button is depressed.
	Changed NC_HandleNCLButtonDblClk so that double clicks on scroll
	bar arrows are handled the same way as single clicks.

	* [windows/winpos.c]
	Fixed SetWindowPos32 to clear WIN_NO_REDRAW when SWP_SHOWWINDOW is
	set; this is the way MS-Windows behaves.

Thu Oct 30 21:08:57 1997  Morten Welinder  <terra@diku.dk>

	* [controls/status.c]
	In SW_SetText, fix condition, I hope.

	* [controls/menu.c]
 	(GetMenuState32): Don't mask return value. Print more debug info.
	(MENU_MenuBarCalcSize): Be more careful when printing debug
	information.
	(MENU_SetItemData): Empty strings are separators.

	* [graphics/x11drv/text.c]
	Don't prototype CLIPPING_IntersectClipRect.

	* [include/dc.h]
	Prototype CLIPPING_IntersectClipRect.

	* [objects/font.c]
	Remove non-portable (and faulty) smartness in FONT_TextMetric*to*.
	In CreateFont32W and CreateFont16, handle null font name.

	* [objects/text.c]
 	(TEXT_NextLine): Fix end-of-line bug.

	* [if1632/shell32.spec]
	Activate existing implementation of ExtractIconA.

	* [misc/shell.c]
	For Control_RunDLL, add types for parameters.

Thu Oct 30 14:54:11 1997  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [controls/static.c] [include/windows.h] [misc/spy.c]
	Added some win32 defines to static controls, basic SS_BITMAP style
	handling implemented. [please add more, I am lacking knowledge and
	time]

	* [controls/status.c]
	part_num 255 seems to indicate whole statusline (win95 cdplayer.exe)

	* [if1632/thunk.c] [tools/build.c]
	Support lret and 0x66 lret calls for CallTo16_regs
	(needed for KERNEL32_45)
	Fixed KERNEL32_45, QT_Thunk (should work now).

	* [if1632/relay.c][if1632/builtin.c][tools/build.c][if1632/*32.spec]
	Added string dumping to relay debugging for win32 apifuncs.

	* [misc/ver.c]
	Fixed and cleaned up VerQueryValue*.

	* [multimedia/*.c][include/mmsystem.h][if1632/mmsystem.spec]
	  [if1632/winmm.spec]
	Win32 support for lowlevel multimedia functions.
	Added some mixer* lowlevel functions.
	Some small fixes in the audio lowlevel queue handling, code
	reformatting/cleanups.

	* [debugger/hash.c]
	Don't show difference between 16bit symbols if they are in
	different segments.

	* [objects/cursoricon.c]
	Added GetIconInfo (partial) and CreateIconIndirect.

	* [windows/mdi.c]
	Fixed some "bad class" problems and crashes in MDICreateChild,
	which happen in Win32 (jwp32.exe).

Wed Oct 29 00:57:27 1997  Bruce Milner  <Bruce.Milner@genetics.utah.edu>

	* [if1632/winaspi.spec] [misc/aspi.c] [include/aspi.c]
	  [documentation/aspi] [include/callback.h]
	Added support for 16 bit ASPI calls to linux generic SCSI.
	The support is not complete, but appears to run my Mustek
	scanner from within ipplus.exe.

Mon Oct 27 00:59:41 1997  Alex Korobka <alex@trantor.pharm.sunysb.edu>

	* [windows/dce.c]
	DC reuse framework.

Sun Oct 26 18:41:21 1997  Huw D M Davies <h.davies1@physics.oxford.ac.uk>

	* [graphics/x11drv/xfont.c]
	Substituted fonts are removed from the alias table. References to
	the old name are also updated.

	* [controls/combo.c]
	LB_SELECTSTRING32 not CB_SELECTSTRING32 should be sent to
	ComboLBox.

Sun Oct 26 14:25:00 1997  Nikita V. Youshchenko <yoush@cs.msu.su>

	* [include/drive.h] [files/drive.c] [msdos/int21.c]
	Partially implemented DOS drive mapping (int21 AX=440F).

Sat Oct 25 13:03:29 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [debugger/debug.l]
	Support '.' in identifiers. Use "x . y" to access structure
	fields.

	* [debugger/hash.c] [loader/pe_image.c]
	Load entry points of Win32 modules only when entering the
	debugger.

	* [debugger/break.c]
	New function DEBUG_AddModuleBreakpoint() to set a breakpoint at
	the start of every module.

	* [files/file.c]
	FILE_mmap() can now fake mmap() for unaligned offsets or broken
	filesystems.

	* [include/callback.h] [misc/callback.c] [if1632/thunk.c]
	Use a table of callbacks instead of macros to differentiate
	between emulator and Winelib.

	* [loader/task.c]
	Initialize current directory from cwd, not from module path.

	* [tools/build.c]
	Read CallTo16 prototypes directly from thunk.c source file.

	* [windows/winproc.c] [windows/mdi.c]
	Added translation for WM_MDIACTIVATE and WM_MDIGETACTIVE.

Fri Oct 24 21:41:25 1997  Uwe Bonnes  <bon@elektron.ikp.tu-darmstadt.de>

	* [files/drive.c]
	Allow arguments like "a" for the drive related apis.

	* [memory/global.c]
	Keep the calculation for dwMemoryLoad in range.

	* [misc/crtdll.c]
	Make CRTDLL_getcwd use GetCurrentDirectory32A and alloc
	its memory if requested.
	Implemented CRTDLL_rename and CRTDLL_stat needed for
	lcc-win32:wedit.exe.
	Implemented CRTDLL__fullpath.

	* [misc/comm.c]
	High speed modes for the 16-bit mode Comm functions.

	* [misc/cpu.c]
	As applications may treat lpMaximumApplicationAddress as long,
	use a valid long number.

	* [misc/main.c]
	In SystemParametersInfo16 ignore SPI_GETHIGHCONTRAST too.

	* [misc/ole2nls.c]
	Implement LCMAP_UPPERCASE for LCMapString32.

	* [misc/wsprintf]
	Made WPRINTF_ParseFormatA understand %ws.

	* [win32/file.c]
	Ignore FILE_ATTRIBUTE_NORMAL.
	Stub for ReadFileEx.

Fri Oct 24 15:36:02 1997  Doug Ridgway <ridgway@routh.ucsd.edu>

	* [memory/local.c]
	Local heap exhaustion message now prints which builtin heap filled.

Fri Oct 24 00:46:34 1997  Huw D M Davies <h.davies1@physics.oxford.ac.uk>

	* [windows/dialog.c]
	Reversed CreateFont16/32W typo.

Thu Oct 23 23:44:20 1997  Kristian Nielsen  <kristian.nielsen@risoe.dk>

	* [if1632/user.spec]
	Fixed argument list for ChangeClipboardChain.

	* [windows/mdi.c]
	Pass correct hInstance to CreateWindow16() in MDICreateChild().

Mon Oct 20 11:51:24 1997  Carsten Fallesen <cf@it.dtu.dk>

	* [objects/metafile.c]
	Added support for META_SETTEXTCHAREXTRA.

	* [objects/region.c]
	Fixed crash in XPolygonRegion if there is only one point in 
	in the region.

	* [if1632/gdi32.spec][include/gdi.h][include/windows.h]
	  [objects/gdiobj.c]
	Completed OBJ_XXX defines in gdi.h, removed OBJ_XXX in gdiobj.c 
	and included gdi.h instead. Implemented GetObjectType32().

Thu Oct 16 17:21:32 1997  Philippe De Muyter  <phdm@info.ucl.ac.be>

	* [documentation/wine.texinfo]
	Fixed WIN32 and Makefiles entries of Reference manual node, that
	made makeinfo dump core.

Mon Oct 13 17:15:57 1997  Robert Wilhelm  <robert@physiol.med.tu-muenchen.de>

	* [if1632/crtdll.spec]
	Added missing math functions y0(), y1(), y2(), floor(), frexp(),
	ldexp(), modf().
diff --git a/ANNOUNCE b/ANNOUNCE
index 5ad867a..d0eb735 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,14 +1,14 @@
-This is release 971012 of Wine, the MS Windows emulator.  This is still a
+This is release 971101 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-971012: (see ChangeLog for details)
-	- Improvements to printer driver support.
-	- More common controls functions.
-	- Win32 relay code changes.
+WHAT'S NEW with Wine-971101: (see ChangeLog for details)
+	- Win32 version of multimedia functions.
+	- ASPI support.
+	- Better DCE handling (in progress).
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -17,10 +17,10 @@
 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-971012.tar.gz
-  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-971012.tar.gz
-  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-971012.tar.gz
-  ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-971012.tar.gz
+  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-971101.tar.gz
+  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-971101.tar.gz
+  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-971101.tar.gz
+  ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-971101.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/BUGS b/BUGS
index 0b3f2c6..8b769fe 100644
--- a/BUGS
+++ b/BUGS
@@ -5,12 +5,10 @@
 add new entries and, more importantly, remove those for the 
 bugs you fixed ;-)
 ------------------------------------------------------------
-As of Sept 1997 -
+As of Oct 1997 -
 
 General:
 
- * Catch/Throw() do not save SI and DI registers (quite fatal).
-
  * We need to do InsertMenuItem32[AW] and then code most of the other
    inserting function in terms of this.  Without this, we cannot support
    all the new extended menus.  Not hard, but slightly big.
@@ -38,6 +36,14 @@
 
 Miscellaneous:
 
+ * Missing menu separators in BCW, other programs.
+
+ * BCW fails with "bad class 'MessageWindow'" message.
+
+ * MIRC is unable to show 'Options' dialog.
+
+ * Tab switching in MIRC 'Setup' dialog leaks memory.
+
  * nBytesWidth in CURSORICONINFO is bogus for some bpp
    (doesn't reflect the fact that bits are packed and 16-bit aligned).
 
@@ -47,16 +53,12 @@
  * Netscape displays partially downloaded inline graphics with
    wrong offsets. Bitmap is missing in the splash-window.
 
- * BCW 4.5 crashes after SwitchStackBack().
-
  * Text alignment problems in Word and Write (variable pitch fonts).
 
- * Font mapper weights
+ * Font mapper weights are rather crude.
 
  * "Cursor XXXX has more than 1 bpp!"
 
- * Margins in edit controls are too wide.
-
  * SGI window manager treats Wine windows as topmost.
 
  * Write shows blank space instead of Paintbrush OLE1 object ( GetDIBits()? ).
diff --git a/ChangeLog b/ChangeLog
index f668af6..aa26de6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,224 @@
 ----------------------------------------------------------------------
+Thu Oct 30 21:52:23 1997  Martin Boehme <boehme@informatik.mu-luebeck.de>
+
+	* [windows/nonclient.c]
+	Changed NC_TrackSysMenu to give the same behaviour as MS-Windows,
+	i.e. system menu already appears when mouse button is depressed.
+	Changed NC_HandleNCLButtonDblClk so that double clicks on scroll
+	bar arrows are handled the same way as single clicks.
+
+	* [windows/winpos.c]
+	Fixed SetWindowPos32 to clear WIN_NO_REDRAW when SWP_SHOWWINDOW is
+	set; this is the way MS-Windows behaves.
+
+Thu Oct 30 21:08:57 1997  Morten Welinder  <terra@diku.dk>
+
+	* [controls/status.c]
+	In SW_SetText, fix condition, I hope.
+
+	* [controls/menu.c]
+ 	(GetMenuState32): Don't mask return value. Print more debug info.
+	(MENU_MenuBarCalcSize): Be more careful when printing debug
+	information.
+	(MENU_SetItemData): Empty strings are separators.
+
+	* [graphics/x11drv/text.c]
+	Don't prototype CLIPPING_IntersectClipRect.
+
+	* [include/dc.h]
+	Prototype CLIPPING_IntersectClipRect.
+
+	* [objects/font.c]
+	Remove non-portable (and faulty) smartness in FONT_TextMetric*to*.
+	In CreateFont32W and CreateFont16, handle null font name.
+
+	* [objects/text.c]
+ 	(TEXT_NextLine): Fix end-of-line bug.
+
+	* [if1632/shell32.spec]
+	Activate existing implementation of ExtractIconA.
+
+	* [misc/shell.c]
+	For Control_RunDLL, add types for parameters.
+
+Thu Oct 30 14:54:11 1997  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
+
+	* [controls/static.c] [include/windows.h] [misc/spy.c]
+	Added some win32 defines to static controls, basic SS_BITMAP style
+	handling implemented. [please add more, I am lacking knowledge and
+	time]
+
+	* [controls/status.c]
+	part_num 255 seems to indicate whole statusline (win95 cdplayer.exe)
+
+	* [if1632/thunk.c] [tools/build.c]
+	Support lret and 0x66 lret calls for CallTo16_regs
+	(needed for KERNEL32_45)
+	Fixed KERNEL32_45, QT_Thunk (should work now).
+
+	* [if1632/relay.c][if1632/builtin.c][tools/build.c][if1632/*32.spec]
+	Added string dumping to relay debugging for win32 apifuncs.
+
+	* [misc/ver.c]
+	Fixed and cleaned up VerQueryValue*.
+
+	* [multimedia/*.c][include/mmsystem.h][if1632/mmsystem.spec]
+	  [if1632/winmm.spec]
+	Win32 support for lowlevel multimedia functions.
+	Added some mixer* lowlevel functions.
+	Some small fixes in the audio lowlevel queue handling, code
+	reformatting/cleanups.
+
+	* [debugger/hash.c]
+	Don't show difference between 16bit symbols if they are in
+	different segments.
+
+	* [objects/cursoricon.c]
+	Added GetIconInfo (partial) and CreateIconIndirect.
+
+	* [windows/mdi.c]
+	Fixed some "bad class" problems and crashes in MDICreateChild,
+	which happen in Win32 (jwp32.exe).
+
+Wed Oct 29 00:57:27 1997  Bruce Milner  <Bruce.Milner@genetics.utah.edu>
+
+	* [if1632/winaspi.spec] [misc/aspi.c] [include/aspi.c]
+	  [documentation/aspi] [include/callback.h]
+	Added support for 16 bit ASPI calls to linux generic SCSI.
+	The support is not complete, but appears to run my Mustek
+	scanner from within ipplus.exe.
+
+Mon Oct 27 00:59:41 1997  Alex Korobka <alex@trantor.pharm.sunysb.edu>
+
+	* [windows/dce.c]
+	DC reuse framework.
+
+Sun Oct 26 18:41:21 1997  Huw D M Davies <h.davies1@physics.oxford.ac.uk>
+
+	* [graphics/x11drv/xfont.c]
+	Substituted fonts are removed from the alias table. References to
+	the old name are also updated.
+
+	* [controls/combo.c]
+	LB_SELECTSTRING32 not CB_SELECTSTRING32 should be sent to
+	ComboLBox.
+
+Sun Oct 26 14:25:00 1997  Nikita V. Youshchenko <yoush@cs.msu.su>
+
+	* [include/drive.h] [files/drive.c] [msdos/int21.c]
+	Partially implemented DOS drive mapping (int21 AX=440F).
+
+Sat Oct 25 13:03:29 1997  Alexandre Julliard  <Alexandre.Julliard@urbanet.ch>
+
+	* [debugger/debug.l]
+	Support '.' in identifiers. Use "x . y" to access structure
+	fields.
+
+	* [debugger/hash.c] [loader/pe_image.c]
+	Load entry points of Win32 modules only when entering the
+	debugger.
+
+	* [debugger/break.c]
+	New function DEBUG_AddModuleBreakpoint() to set a breakpoint at
+	the start of every module.
+
+	* [files/file.c]
+	FILE_mmap() can now fake mmap() for unaligned offsets or broken
+	filesystems.
+
+	* [include/callback.h] [misc/callback.c] [if1632/thunk.c]
+	Use a table of callbacks instead of macros to differentiate
+	between emulator and Winelib.
+
+	* [loader/task.c]
+	Initialize current directory from cwd, not from module path.
+
+	* [tools/build.c]
+	Read CallTo16 prototypes directly from thunk.c source file.
+
+	* [windows/winproc.c] [windows/mdi.c]
+	Added translation for WM_MDIACTIVATE and WM_MDIGETACTIVE.
+
+Fri Oct 24 21:41:25 1997  Uwe Bonnes  <bon@elektron.ikp.tu-darmstadt.de>
+
+	* [files/drive.c]
+	Allow arguments like "a" for the drive related apis.
+
+	* [memory/global.c]
+	Keep the calculation for dwMemoryLoad in range.
+
+	* [misc/crtdll.c]
+	Make CRTDLL_getcwd use GetCurrentDirectory32A and alloc
+	its memory if requested.
+	Implemented CRTDLL_rename and CRTDLL_stat needed for
+	lcc-win32:wedit.exe.
+	Implemented CRTDLL__fullpath.
+
+	* [misc/comm.c]
+	High speed modes for the 16-bit mode Comm functions.
+
+	* [misc/cpu.c]
+	As applications may treat lpMaximumApplicationAddress as long,
+	use a valid long number.
+
+	* [misc/main.c]
+	In SystemParametersInfo16 ignore SPI_GETHIGHCONTRAST too.
+
+	* [misc/ole2nls.c]
+	Implement LCMAP_UPPERCASE for LCMapString32.
+
+	* [misc/wsprintf]
+	Made WPRINTF_ParseFormatA understand %ws.
+
+	* [win32/file.c]
+	Ignore FILE_ATTRIBUTE_NORMAL.
+	Stub for ReadFileEx.
+
+Fri Oct 24 15:36:02 1997  Doug Ridgway <ridgway@routh.ucsd.edu>
+
+	* [memory/local.c]
+	Local heap exhaustion message now prints which builtin heap filled.
+
+Fri Oct 24 00:46:34 1997  Huw D M Davies <h.davies1@physics.oxford.ac.uk>
+
+	* [windows/dialog.c]
+	Reversed CreateFont16/32W typo.
+
+Thu Oct 23 23:44:20 1997  Kristian Nielsen  <kristian.nielsen@risoe.dk>
+
+	* [if1632/user.spec]
+	Fixed argument list for ChangeClipboardChain.
+
+	* [windows/mdi.c]
+	Pass correct hInstance to CreateWindow16() in MDICreateChild().
+
+Mon Oct 20 11:51:24 1997  Carsten Fallesen <cf@it.dtu.dk>
+
+	* [objects/metafile.c]
+	Added support for META_SETTEXTCHAREXTRA.
+
+	* [objects/region.c]
+	Fixed crash in XPolygonRegion if there is only one point in 
+	in the region.
+
+	* [if1632/gdi32.spec][include/gdi.h][include/windows.h]
+	  [objects/gdiobj.c]
+	Completed OBJ_XXX defines in gdi.h, removed OBJ_XXX in gdiobj.c 
+	and included gdi.h instead. Implemented GetObjectType32().
+
+Thu Oct 16 17:21:32 1997  Philippe De Muyter  <phdm@info.ucl.ac.be>
+
+	* [documentation/wine.texinfo]
+	Fixed WIN32 and Makefiles entries of Reference manual node, that
+	made makeinfo dump core.
+
+Mon Oct 13 17:15:57 1997  Robert Wilhelm  <robert@physiol.med.tu-muenchen.de>
+
+	* [if1632/crtdll.spec]
+	Added missing math functions y0(), y1(), y2(), floor(), frexp(),
+	ldexp(), modf().
+
+----------------------------------------------------------------------
 Sun Oct 12 15:03:01 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>
 
 	* [if1632/builtin.c] [if1632/relay.c]
diff --git a/controls/button.c b/controls/button.c
index 312282d..27e73c4 100644
--- a/controls/button.c
+++ b/controls/button.c
@@ -170,12 +170,14 @@
 
     case WM_SETTEXT:
         DEFWND_SetText( wndPtr, (LPSTR)lParam );
-        PAINT_BUTTON( wndPtr, style, ODA_DRAWENTIRE );
+	if( wndPtr->dwStyle & WS_VISIBLE )
+            PAINT_BUTTON( wndPtr, style, ODA_DRAWENTIRE );
         return 0;
 
     case WM_SETFONT:
         infoPtr->hFont = (HFONT16)wParam;
-        if (lParam) PAINT_BUTTON( wndPtr, style, ODA_DRAWENTIRE );
+        if (lParam && (wndPtr->dwStyle & WS_VISIBLE)) 
+	    PAINT_BUTTON( wndPtr, style, ODA_DRAWENTIRE );
         break;
 
     case WM_GETFONT:
diff --git a/controls/combo.c b/controls/combo.c
index 26903fa..b66173c 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -1128,7 +1128,7 @@
  */
 static LRESULT COMBO_SelectString( LPHEADCOMBO lphc, INT32 start, LPCSTR pText )
 {
-   INT32 index = SendMessage32A( lphc->hWndLBox, CB_SELECTSTRING32, 
+   INT32 index = SendMessage32A( lphc->hWndLBox, LB_SELECTSTRING32, 
 				 (WPARAM32)start, (LPARAM)pText );
    if( index >= 0 )
         if( lphc->wState & CBF_EDIT )
diff --git a/controls/edit.c b/controls/edit.c
index 7e32b57..c6bcafe 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -978,7 +978,7 @@
 	if (es->word_break_proc16) {
 		HLOCAL16 hloc16 = EDIT_EM_GetHandle16(wnd, es);
 		SEGPTR segptr = LocalLock16(hloc16);
-		INT32 ret = (INT32)CallWordBreakProc16((FARPROC16)es->word_break_proc16,
+		INT32 ret = (INT32)Callbacks->CallWordBreakProc(es->word_break_proc16,
 						segptr + start, index, count, action);
 		LocalUnlock16(hloc16);
 		return ret;
diff --git a/controls/menu.c b/controls/menu.c
index 682423f..a31b2f1 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -754,10 +754,10 @@
 	    if ((i != start) &&
 		(lpitem->fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
 
-
-	    dprintf_menu( stddeb, "MENU_MenuBarCalcSize: calling "
-			  "MENU_CalcItemSize on item '%s', org=(%d, %d)\n",
-			  lpitem->text, orgX, orgY );
+	    dprintf_menu( stddeb,
+			  "MENU_MenuBarCalcSize: calling MENU_CalcItemSize"
+			  " org=(%d, %d)\n", orgX, orgY );
+	    debug_print_menuitem ("  item: ", lpitem, "\n");
 	    MENU_CalcItemSize( hdc, lpitem, hwndOwner, orgX, orgY, TRUE );
 	    if (lpitem->rect.right > lprect->right)
 	    {
@@ -1396,7 +1396,7 @@
 
     if (IS_STRING_ITEM(flags))
     {
-        if (!str)
+        if (!str || !*str)
         {
             flags |= MF_SEPARATOR;
             item->text = NULL;
@@ -1904,7 +1904,7 @@
         else
             item = MENU_FindItemByCoords( ptmenu, pmt->pt, &id );
 
-	if( ptmenu->FocusedItem == id )
+	if( item && (ptmenu->FocusedItem == id ))
 	{
 	    if( !(item->fType & MF_POPUP) )
 		return MENU_ExecFocusedItem( pmt, hPtMenu );
@@ -2861,6 +2861,7 @@
     dprintf_menu(stddeb,"GetMenuState(%04x, %04x, %04x);\n", 
 		 hMenu, wItemID, wFlags);
     if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return -1;
+    debug_print_menuitem ("  item: ", item, "\n");
     if (item->fType & MF_POPUP)
     {
 	POPUPMENU *menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( item->hSubMenu );
@@ -2868,9 +2869,12 @@
 	else return (menu->nItems << 8) | (menu->wFlags & 0xff);
     }
     else
-        /* Non POPUP Menus only return flags in the lower byte */
-        /* XXX ??? */
-	return ((item->fType | item->fState) & 0x00ff);
+    {
+	 /* We used to (from way back then) mask the result to 0xff.  */
+	 /* I don't know why and it seems wrong as the documented */
+	 /* return flag MF_SEPARATOR is outside that mask.  */
+	 return (item->fType | item->fState);
+    }
 }
 
 
diff --git a/controls/scroll.c b/controls/scroll.c
index b8a3d4e..4b7867e 100644
--- a/controls/scroll.c
+++ b/controls/scroll.c
@@ -410,18 +410,20 @@
     r = *rect;
     if (vertical)
     {
-        r.top    += arrowSize;
+        r.top    += arrowSize - 1;
         r.bottom -= arrowSize;
+	r.right--;
     }
     else
     {
-        r.left  += arrowSize;
+        r.left  += arrowSize - 1;
         r.right -= arrowSize;
+	r.bottom--;
     }
 
       /* Draw the scroll bar frame */
 
-    GRAPH_DrawRectangle( hdc, r.left, r.top, r.right - 1, r.bottom - 1, 0);
+    GRAPH_DrawRectangle( hdc, r.left, r.top, r.right - r.left, r.bottom - r.top, 0);
 
       /* Draw the scroll rectangles and thumb */
 
@@ -443,7 +445,7 @@
                   r.right - r.left - 2,
                   r.bottom - r.top - thumbSize - 2,
                   bottom_selected ? 0x0f0000 : PATCOPY );
-        r.bottom = r.top + thumbSize + 1;
+        r.bottom = r.top + thumbSize + 2;
     }
     else  /* horizontal */
     {
@@ -456,7 +458,7 @@
                   r.right - r.left - thumbSize - 2,
                   r.bottom - r.top - 2,
                   bottom_selected ? 0x0f0000 : PATCOPY );
-        r.right = r.left + thumbSize + 1;
+        r.right = r.left + thumbSize + 2;
     }
 
       /* Draw the thumb */
diff --git a/controls/static.c b/controls/static.c
index ecd4a02..0e565f2 100644
--- a/controls/static.c
+++ b/controls/static.c
@@ -8,12 +8,15 @@
 #include <stdio.h>
 #include "windows.h"
 #include "win.h"
+#include "bitmap.h"
+#include "cursoricon.h"
 #include "static.h"
 #include "heap.h"
 
 static void STATIC_PaintTextfn( WND *wndPtr, HDC32 hdc );
 static void STATIC_PaintRectfn( WND *wndPtr, HDC32 hdc );
 static void STATIC_PaintIconfn( WND *wndPtr, HDC32 hdc );
+static void STATIC_PaintBitmapfn( WND *wndPtr, HDC32 hdc );
 
 
 static COLORREF color_windowframe, color_background, color_window;
@@ -21,9 +24,7 @@
 
 typedef void (*pfPaint)( WND *, HDC32 );
 
-#define LAST_STATIC_TYPE  SS_LEFTNOWORDWRAP
-
-static pfPaint staticPaintFunc[LAST_STATIC_TYPE+1] =
+static pfPaint staticPaintFunc[SS_TYPEMASK+1] =
 {
     STATIC_PaintTextfn,      /* SS_LEFT */
     STATIC_PaintTextfn,      /* SS_CENTER */
@@ -37,7 +38,13 @@
     STATIC_PaintRectfn,      /* SS_WHITEFRAME */
     NULL,                    /* Not defined */
     STATIC_PaintTextfn,      /* SS_SIMPLE */
-    STATIC_PaintTextfn       /* SS_LEFTNOWORDWRAP */
+    STATIC_PaintTextfn,      /* SS_LEFTNOWORDWRAP */
+    NULL,                    /* SS_OWNERDRAW */
+    STATIC_PaintBitmapfn,    /* SS_BITMAP */
+    NULL,                    /* SS_ENHMETAFILE */
+    NULL,                    /* SS_ETCHEDHORIZ */
+    NULL,                    /* SS_ETCHEDVERT */
+    NULL,                    /* SS_ETCHEDFRAME */
 };
 
 
@@ -52,7 +59,7 @@
     STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
     CURSORICONINFO *info = hicon?(CURSORICONINFO *) GlobalLock16( hicon ):NULL;
 
-    if ((wndPtr->dwStyle & 0x0f) != SS_ICON) return 0;
+    if ((wndPtr->dwStyle & SS_TYPEMASK) != SS_ICON) return 0;
     if (hicon && !info) {
 	fprintf(stderr,"STATIC_SetIcon: huh? hicon!=0, but info=0???\n");
     	return 0;
@@ -68,6 +75,33 @@
     return prevIcon;
 }
 
+/***********************************************************************
+ *           STATIC_SetBitmap
+ *
+ * Set the bitmap for an SS_BITMAP control.
+ */
+static HICON16 STATIC_SetBitmap( WND *wndPtr, HICON16 hicon )
+{
+    HICON16 prevIcon;
+    STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
+    BITMAPOBJ *info = GDI_HEAP_LOCK(hicon);
+
+    if ((wndPtr->dwStyle & SS_TYPEMASK) != SS_BITMAP) return 0;
+    if (hicon && !info) {
+	fprintf(stderr,"STATIC_SetBitmap: huh? hicon!=0, but info=0???\n");
+    	return 0;
+    }
+    prevIcon = infoPtr->hIcon;
+    infoPtr->hIcon = hicon;
+    if (hicon)
+    {
+        SetWindowPos32( wndPtr->hwndSelf, 0, 0, 0, info->bitmap.bmWidth, info->bitmap.bmHeight,
+                        SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER );
+    }
+    GDI_HEAP_UNLOCK( hicon );
+    return prevIcon;
+}
+
 
 /***********************************************************************
  *           STATIC_LoadIcon
@@ -95,6 +129,32 @@
     return hicon;
 }
 
+/***********************************************************************
+ *           STATIC_LoadBitmap
+ *
+ * Load the bitmap for an SS_BITMAP control.
+ */
+static HBITMAP16 STATIC_LoadBitmap( WND *wndPtr, LPCSTR name )
+{
+    HBITMAP16 hbitmap;
+
+    if (wndPtr->flags & WIN_ISWIN32)
+    {
+        hbitmap = LoadBitmap32A( wndPtr->hInstance, name );
+        if (!hbitmap)  /* Try OEM icon (FIXME: is this right?) */
+            hbitmap = LoadBitmap32A( 0, name );
+    }
+    else
+    {
+        LPSTR segname = SEGPTR_STRDUP(name);
+        hbitmap = LoadBitmap16( wndPtr->hInstance, SEGPTR_GET(segname) );
+        if (!hbitmap)  /* Try OEM icon (FIXME: is this right?) */
+            hbitmap = LoadBitmap32A( 0, segname );
+        SEGPTR_FREE(segname);
+    }
+    return hbitmap;
+}
+
 
 /***********************************************************************
  *           StaticWndProc
@@ -104,7 +164,7 @@
 {
     LRESULT lResult = 0;
     WND *wndPtr = WIN_FindWndPtr(hWnd);
-    LONG style = wndPtr->dwStyle & 0x0000000F;
+    LONG style = wndPtr->dwStyle & SS_TYPEMASK;
     STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
 
     switch (uMsg)
@@ -118,10 +178,19 @@
                                 STATIC_LoadIcon( wndPtr, cs->lpszName ));
             return 1;
         }
+	if (style == SS_BITMAP)
+	{
+            CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
+            if (cs->lpszName)
+                STATIC_SetBitmap( wndPtr,
+                                STATIC_LoadBitmap( wndPtr, cs->lpszName ));
+	    fprintf(stderr,"STATIC:style SS_BITMAP, dwStyle is 0x%08lx\n",wndPtr->dwStyle);
+            return 1;
+	}
         return DefWindowProc32A( hWnd, uMsg, wParam, lParam );
 
     case WM_CREATE:
-        if (style < 0L || style > LAST_STATIC_TYPE)
+        if (style < 0L || style > SS_TYPEMASK)
         {
             fprintf( stderr, "STATIC: Unknown style 0x%02lx\n", style );
             lResult = -1L;
@@ -136,7 +205,7 @@
     case WM_NCDESTROY:
         if (style == SS_ICON)
             DestroyIcon32( STATIC_SetIcon( wndPtr, 0 ) );
-        else 
+        else
             lResult = DefWindowProc32A( hWnd, uMsg, wParam, lParam );
         break;
 
@@ -165,7 +234,9 @@
         if (style == SS_ICON)
             /* FIXME : should we also return the previous hIcon here ??? */
             STATIC_SetIcon( wndPtr, STATIC_LoadIcon( wndPtr, (LPCSTR)lParam ));
-        else
+        else if (style == SS_BITMAP) 
+            STATIC_SetBitmap(wndPtr,STATIC_LoadBitmap(wndPtr,(LPCSTR)lParam ));
+	else
             DEFWND_SetText( wndPtr, (LPCSTR)lParam );
         InvalidateRect32( hWnd, NULL, FALSE );
         UpdateWindow32( hWnd );
@@ -173,6 +244,7 @@
 
     case WM_SETFONT:
         if (style == SS_ICON) return 0;
+        if (style == SS_BITMAP) return 0;
         infoPtr->hFont = (HFONT16)wParam;
         if (LOWORD(lParam))
         {
@@ -190,10 +262,20 @@
     case WM_GETDLGCODE:
         return DLGC_STATIC;
 
-    case STM_GETICON:
+    	return infoPtr->hIcon;
+    case STM_GETIMAGE:
+    case STM_GETICON16:
+    case STM_GETICON32:
         return infoPtr->hIcon;
 
-    case STM_SETICON:
+    case STM_SETIMAGE:
+    	/* FIXME: handle wParam */
+        lResult = STATIC_SetBitmap( wndPtr, (HBITMAP32)lParam );
+        InvalidateRect32( hWnd, NULL, FALSE );
+        UpdateWindow32( hWnd );
+	break;
+    case STM_SETICON16:
+    case STM_SETICON32:
         lResult = STATIC_SetIcon( wndPtr, (HICON16)wParam );
         InvalidateRect32( hWnd, NULL, FALSE );
         UpdateWindow32( hWnd );
@@ -219,7 +301,7 @@
 
     GetClientRect32( wndPtr->hwndSelf, &rc);
 
-    switch (style & 0x0000000F)
+    switch (style & SS_TYPEMASK)
     {
     case SS_LEFT:
 	wFormat = DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK | DT_NOCLIP;
@@ -263,7 +345,7 @@
 
     GetClientRect32( wndPtr->hwndSelf, &rc);
     
-    switch (wndPtr->dwStyle & 0x0f)
+    switch (wndPtr->dwStyle & SS_TYPEMASK)
     {
     case SS_BLACKRECT:
 	hBrush = CreateSolidBrush32(color_windowframe);
@@ -308,3 +390,28 @@
     FillRect32( hdc, &rc, hbrush );
     if (infoPtr->hIcon) DrawIcon32( hdc, rc.left, rc.top, infoPtr->hIcon );
 }
+
+static void STATIC_PaintBitmapfn(WND *wndPtr, HDC32 hdc ) 
+{
+    RECT32 rc;
+    HBRUSH32 hbrush;
+    STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
+    HDC32 hMemDC;
+    HBITMAP32 oldbitmap;
+
+    GetClientRect32( wndPtr->hwndSelf, &rc );
+    hbrush = SendMessage32A( GetParent32(wndPtr->hwndSelf), WM_CTLCOLORSTATIC,
+                             hdc, wndPtr->hwndSelf );
+    FillRect32( hdc, &rc, hbrush );
+    if (infoPtr->hIcon) {
+        BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_HEAP_LOCK( infoPtr->hIcon );
+
+	if (!bmp) return;
+        if (!(hMemDC = CreateCompatibleDC32( hdc ))) return;
+
+	oldbitmap = SelectObject32(hMemDC,infoPtr->hIcon);
+	BitBlt32(hdc,bmp->size.cx,bmp->size.cy,bmp->bitmap.bmWidth,bmp->bitmap.bmHeight,hMemDC,0,0,SRCCOPY);
+	DeleteDC32(hMemDC);
+        GDI_HEAP_UNLOCK(infoPtr->hIcon);
+    }
+}
diff --git a/controls/status.c b/controls/status.c
index 3fae2d9..d05aa6d 100644
--- a/controls/status.c
+++ b/controls/status.c
@@ -118,10 +118,10 @@
     part_num = ((INT32) wParam) & 0x00ff;
     style = ((INT32) wParam) & 0xff00;
 
-    if (part_num > 255)
+    if (part_num >= 255)
 	return FALSE;
 
-    if (self->simple)
+    if ((self->simple) || (part_num==255))
 	part = &self->part0;
     else
 	part = &self->parts[part_num];
diff --git a/debugger/break.c b/debugger/break.c
index e2265f9..f26f7be 100644
--- a/debugger/break.c
+++ b/debugger/break.c
@@ -9,6 +9,9 @@
 #include <stdlib.h>
 #include <sys/types.h>
 #include <sys/mman.h>
+#include "module.h"
+#include "process.h"
+#include "toolhelp.h"
 #include "windows.h"
 #include "debugger.h"
 
@@ -225,6 +228,7 @@
 	addr.off = DEBUG_GetExprValue(&addr, NULL);
 	addr.seg = seg2;
       }
+    if (!DBG_CHECK_READ_PTR( &addr, 1 )) return;
 
     if (next_bp < MAX_BREAKPOINTS)
         num = next_bp++;
@@ -238,7 +242,6 @@
             return;
         }
     }
-    if (!DBG_CHECK_READ_PTR( &addr, 1 )) return;
     p = DBG_ADDR_TO_LIN( &addr );
     breakpoints[num].addr    = addr;
     breakpoints[num].addrlen = !addr.seg ? 32 :
@@ -326,6 +329,54 @@
 
 
 /***********************************************************************
+ *           DEBUG_AddModuleBreakpoints
+ *
+ * Add a breakpoint at the start of every loaded module.
+ */
+void DEBUG_AddModuleBreakpoints(void)
+{
+    MODULEENTRY entry;
+    NE_MODULE *pModule;
+    BOOL32 ok;
+    DBG_ADDR addr = { NULL, 0, 0 };
+
+    for (ok = ModuleFirst(&entry); ok; ok = ModuleNext(&entry))
+    {
+        if (!(pModule = MODULE_GetPtr( entry.hModule ))) continue;
+        if (pModule->flags & NE_FFLAGS_LIBMODULE) continue;  /* Library */
+
+        if (pModule->flags & NE_FFLAGS_WIN32)  /* PE module */
+        {
+            PE_MODULE *pe = pModule->pe_module;
+            PE_MODREF *pem;
+            if (!pCurrentProcess) continue;
+            pem = pCurrentProcess->modref_list;
+            while (pem)
+            {
+		if (pem->pe_module == pe) break;
+		pem = pem->next;
+            }
+            if (!pem) continue;
+            addr.seg = 0;
+            addr.off = pem->load_addr +
+                      (DWORD)pe->pe_header->OptionalHeader.AddressOfEntryPoint;
+            fprintf( stderr, "Win32 task '%s': ", entry.szModule );
+            DEBUG_AddBreakpoint( &addr );
+        }
+        else  /* NE module */
+        {
+            addr.seg = NE_SEG_TABLE(pModule)[pModule->cs-1].selector;
+            addr.off = pModule->ip;
+            fprintf( stderr, "Win16 task '%s': ", entry.szModule );
+            DEBUG_AddBreakpoint( &addr );
+        }
+    }
+
+    DEBUG_SetBreakpoints( TRUE );  /* Setup breakpoints */
+}
+
+
+/***********************************************************************
  *           DEBUG_ShouldContinue
  *
  * Determine if we should continue execution after a SIGTRAP signal when
diff --git a/debugger/debug.l b/debugger/debug.l
index abbaf69..0c4bc8a 100644
--- a/debugger/debug.l
+++ b/debugger/debug.l
@@ -34,7 +34,7 @@
 DIGIT	   [0-9]
 HEXDIGIT   [0-9a-fA-F]
 FORMAT     [bcdiswx]
-IDENTIFIER [_a-zA-Z~][_a-zA-Z0-9~@]*
+IDENTIFIER [_a-zA-Z\.~][_a-zA-Z0-9\.~@]*
 PATHNAME   [/_a-zA-Z\.~][/_a-zA-Z0-9\.~@]*
 STRING     \"[^\n"]+\"
 
diff --git a/debugger/hash.c b/debugger/hash.c
index 610785f..dc81bd6 100644
--- a/debugger/hash.c
+++ b/debugger/hash.c
@@ -12,6 +12,7 @@
 #include <sys/types.h>
 #include <neexe.h>
 #include "module.h"
+#include "process.h"
 #include "selectors.h"
 #include "debugger.h"
 #include "toolhelp.h"
@@ -264,8 +265,7 @@
 		c++;
 		if(    (strcmp(c, "callfrom16.s") == 0)
 		    || (strcmp(c, "callto16.s") == 0)
-		    || (strcmp(c, "callfrom32.s") == 0)
-		    || (strcmp(c, "callto32.s") == 0) )
+		    || (strcmp(c, "call32.s") == 0) )
 		  {
 		    new->flags |= SYM_TRAMPOLINE;
 		  }
@@ -676,9 +676,13 @@
       {
 	if (addr->off == nearest->addr.off)
 	  sprintf( name_buffer, "%s%s", nearest->name, arglist);
-	else
-	  sprintf( name_buffer, "%s+0x%lx%s", nearest->name,
-		   addr->off - nearest->addr.off, arglist);
+	else {
+	  if (addr->seg && (nearest->addr.seg!=addr->seg))
+	      return NULL;
+	  else
+	      sprintf( name_buffer, "%s+0x%lx%s", nearest->name,
+		       addr->off - nearest->addr.off, arglist);
+ 	}
       }
     return name_buffer;
 }
@@ -734,6 +738,132 @@
 
 
 /***********************************************************************
+ *           DEBUG_LoadEntryPoints16
+ *
+ * Load the entry points of a Win16 module into the hash table.
+ */
+static void DEBUG_LoadEntryPoints16( HMODULE16 hModule, NE_MODULE *pModule,
+                                     const char *name )
+{
+    DBG_ADDR addr;
+    char buffer[256];
+    FARPROC16 address;
+
+    /* First search the resident names */
+
+    unsigned char *cpnt = (unsigned char *)pModule + pModule->name_table;
+    while (*cpnt)
+    {
+        cpnt += *cpnt + 1 + sizeof(WORD);
+        sprintf( buffer, "%s.%.*s", name, *cpnt, cpnt + 1 );
+        if ((address = MODULE_GetEntryPoint( hModule,
+                                             *(WORD *)(cpnt + *cpnt + 1) )))
+        {
+            addr.seg = HIWORD(address);
+            addr.off = LOWORD(address);
+            addr.type = NULL;
+            DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32 | SYM_FUNC );
+        }
+    }
+
+    /* Now search the non-resident names table */
+
+    if (!pModule->nrname_handle) return;  /* No non-resident table */
+    cpnt = (char *)GlobalLock16( pModule->nrname_handle );
+    while (*cpnt)
+    {
+        cpnt += *cpnt + 1 + sizeof(WORD);
+        sprintf( buffer, "%s.%.*s", name, *cpnt, cpnt + 1 );
+        if ((address = MODULE_GetEntryPoint( hModule,
+                                             *(WORD *)(cpnt + *cpnt + 1) )))
+        {
+            addr.seg = HIWORD(address);
+            addr.off = LOWORD(address);
+            addr.type = NULL;
+            DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32 | SYM_FUNC );
+        }
+    }
+}
+
+
+/***********************************************************************
+ *           DEBUG_LoadEntryPoints32
+ *
+ * Load the entry points of a Win32 module into the hash table.
+ */
+static void DEBUG_LoadEntryPoints32( PE_MODULE *pe, const char *name )
+{
+#define RVA(x) (load_addr+(DWORD)(x))
+
+    DBG_ADDR addr;
+    char buffer[256];
+    int i, j;
+    IMAGE_EXPORT_DIRECTORY *exports;
+    DWORD load_addr;
+    WORD *ordinals;
+    void **functions;
+    const char **names;
+
+    PE_MODREF *pem = pCurrentProcess->modref_list;
+    while (pem && (pem->pe_module != pe)) pem = pem->next;
+    if (!pem) return;
+    load_addr = pem->load_addr;
+    exports = pem->pe_export;
+
+    addr.seg = 0;
+    addr.type = NULL;
+
+    /* Add start of DLL */
+
+    addr.off = load_addr;
+    DEBUG_AddSymbol( name, &addr, NULL, SYM_WIN32 | SYM_FUNC );
+
+    /* Add entry point */
+
+    sprintf( buffer, "%s.EntryPoint", name );
+    addr.off = RVA( pe->pe_header->OptionalHeader.AddressOfEntryPoint );
+    DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32 | SYM_FUNC );
+
+    /* Add start of sections */
+
+    for (i = 0; i < pe->pe_header->FileHeader.NumberOfSections; i++)
+    {
+        sprintf( buffer, "%s.%s", name, pe->pe_seg[i].Name );
+        addr.off = RVA( pe->pe_seg[i].VirtualAddress );
+        DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32 | SYM_FUNC );
+    }
+
+    /* Add exported functions */
+
+    if (!exports) return;
+    ordinals  = (WORD *)RVA( exports->AddressOfNameOrdinals );
+    names     = (const char **)RVA( exports->AddressOfNames );
+    functions = (void **)RVA( exports->AddressOfFunctions );
+
+    for (i = 0; i < exports->NumberOfNames; i++)
+    {
+        if (!names[i]) continue;
+        sprintf( buffer, "%s.%s", name, (char *)RVA(names[i]) );
+        addr.off = RVA( functions[ordinals[i]] );
+        DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32 | SYM_FUNC );
+    }
+
+    for (i = 0; i < exports->NumberOfFunctions; i++)
+    {
+        if (!functions[i]) continue;
+        /* Check if we already added it with a name */
+        for (j = 0; j < exports->NumberOfNames; j++)
+            if ((ordinals[j] == i) && names[j]) break;
+        if (j < exports->NumberOfNames) continue;
+        sprintf( buffer, "%s.%ld", name, i + exports->Base );
+        addr.off = (DWORD)RVA( functions[i] );
+        DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32 | SYM_FUNC );
+    }
+#undef RVA
+}
+
+
+/***********************************************************************
  *           DEBUG_LoadEntryPoints
  *
  * Load the entry points of all the modules into the hash table.
@@ -742,58 +872,24 @@
 {
     MODULEENTRY entry;
     NE_MODULE *pModule;
-    DBG_ADDR addr;
-    char buffer[256];
-    unsigned char *cpnt, *name;
-    FARPROC16 address;
     BOOL32 ok;
 
     for (ok = ModuleFirst(&entry); ok; ok = ModuleNext(&entry))
     {
         if (!(pModule = MODULE_GetPtr( entry.hModule ))) continue;
-        if (pModule->flags & NE_FFLAGS_WIN32) continue;
+        fprintf( stderr, " %s", entry.szModule );
 
-        name = (unsigned char *)pModule + pModule->name_table;
-
-        fprintf( stderr, " %.*s",*name, name + 1 );
-
-        /* First search the resident names */
-
-        cpnt = (unsigned char *)pModule + pModule->name_table;
-        while (*cpnt)
+        if (pModule->flags & NE_FFLAGS_WIN32)  /* PE module */
         {
-            cpnt += *cpnt + 1 + sizeof(WORD);
-            sprintf( buffer, "%.*s_%.*s", *name, name + 1, *cpnt, cpnt + 1 );
-            if ((address = MODULE_GetEntryPoint( entry.hModule,
-                                            *(WORD *)(cpnt + *cpnt + 1) )))
-            {
-                addr.seg = HIWORD(address);
-                addr.off = LOWORD(address);
-		addr.type = NULL;
-                DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32 | SYM_FUNC );
-            }
+            if (pModule->flags & NE_FFLAGS_BUILTIN) continue;
+            DEBUG_LoadEntryPoints32( pModule->pe_module, entry.szModule );
         }
-
-        /* Now search the non-resident names table */
-
-        if (!pModule->nrname_handle) continue;  /* No non-resident table */
-        cpnt = (char *)GlobalLock16( pModule->nrname_handle );
-        while (*cpnt)
-        {
-            cpnt += *cpnt + 1 + sizeof(WORD);
-            sprintf( buffer, "%.*s_%.*s", *name, name + 1, *cpnt, cpnt + 1 );
-            if ((address = MODULE_GetEntryPoint( entry.hModule,
-                                                *(WORD *)(cpnt + *cpnt + 1) )))
-            {
-                addr.seg = HIWORD(address);
-                addr.off = LOWORD(address);
-		addr.type = NULL;
-                DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32);
-            }
-        }
+        else  /* NE module */
+            DEBUG_LoadEntryPoints16( entry.hModule, pModule, entry.szModule );
     }
 }
 
+
 void
 DEBUG_AddLineNumber( struct name_hash * func, int line_num, 
 		     unsigned long offset )
diff --git a/debugger/types.c b/debugger/types.c
index 137b662..567799c 100644
--- a/debugger/types.c
+++ b/debugger/types.c
@@ -751,10 +751,13 @@
     }
   
   if( addr->type == NULL )
-    {
-      fprintf(stderr, "Unable to evaluate expression\n");
+  {
+      /* No type, just print the addr value */
+      if (addr->seg && (addr->seg != 0xffffffff))
+          DEBUG_nchar += fprintf( stderr, "0x%04lx: ", addr->seg );
+      DEBUG_nchar += fprintf( stderr, "0x%08lx", addr->off );
       goto leave;
-    }
+  }
   
   if( level == 0 )
     {
diff --git a/documentation/aspi b/documentation/aspi
new file mode 100644
index 0000000..942357e
--- /dev/null
+++ b/documentation/aspi
@@ -0,0 +1,78 @@
+This file describes setting up the Windows ASPI interface.
+
+Warning/Warning/Warning!!!!!!
+=============================
+THIS MAY TRASH YOUR SYSTEM IF USED INCORRECTLY
+THIS MAY TRASH YOUR SYSTEM IF USED CORRECTLY
+
+Now that I have said that. ASPI is a direct link to SCSI devices from
+windows programs. ASPI just forwards the SCSI commands that programs send
+to it to the SCSI bus.
+
+If you use the wrong scsi device in your setup file, you can send
+completely bogus commands to the wrong device - An example would be
+formatting your hard drives (assuming the device gave you permission -
+if you're running as root, all bets are off).
+
+Cookbook for setting up scanner: (At least how mine is to work)
+================================
+
+Windows requirements:
+=====================
+0) The scanner software needs to use the "Adaptec" compatible drivers
+(ASPI). At least with Mustek, they allow you the choice of using
+the builtin card or the "Adaptec (AHA)" compatible drivers. This will not
+work any other way.
+
+1) You probably need a real windows install of the software to set the
+LUN's/SCSI id's up correctly. I'm not exactly sure.
+
+LINUX requirements:
+============================================================
+0) Your scsi card must be supported under linux. This will not work with
+an unknown scsi card.
+
+1) Compile generic scsi drivers into your kernel.
+
+2) Linux by default uses smaller scsi buffers than Windows. There is a
+kernel build define SG_BIG_BUFF (in sg.h) that is by default set too low.
+The SANE project recommends 130560 and this seems to work just fine. This
+does require a kernel rebuild.
+
+3) Make the devices for the scanner (generic scsi devices) - look at the scsi
+programming how-to for device numbering.
+
+4) I would recommend making the scanner device writable by a group.
+I made a group called "scanner" and added myself to it. Running as root
+increases your risk of sending bad scsi commands to the wrong device. With
+a regular user, you are better protected.
+
+5) Add a scsi device entry for your particular scanner to wine.conf.
+The format is [scsi cCtTdD] where C=controller, T=target, D=LUN
+
+ex. I set mine up as  controller 0, Target 6, LUN 0.
+[scsi c0t6d0]
+Device=/dev/sgi
+
+Yours will vary with your particular SCSI setup.
+
+
+General Information:
+====================
+The mustek scanner I have was shipped with a package "ipplus". This
+program uses the TWAIN driver specification to access scanners.
+
+                            (TWAIN MANAGER)
+ipplus.exe <---> (TWAIN INTERFACE) <---> (TWAIN DATA SOURCE . ASPI) -> WINASPI
+
+NOTES/BUGS:
+===========
+The biggest is that it only works under linux at the moment.
+The ASPI code was only tested using a Mustek 800SP with a Buslogic
+controller under Linux.
+
+I make no warranty to the aspi code. It makes my scanner work. Your scanner
+may explode. I have no way of determining this. I take zero responsibility!
+
+
+Bruce Milner
diff --git a/documentation/internals b/documentation/internals
index 9308036..10bc578 100644
--- a/documentation/internals
+++ b/documentation/internals
@@ -18,6 +18,9 @@
 
 1. Windowing subsystem
 
+   windows/win.c
+   windows/winpos.c
+
    Windows are arranged into parent/child hierarchy with one
    common ancestor for all windows (desktop window). Each window
    structure contains a pointer to the immediate ancestor (parent 
@@ -63,7 +66,89 @@
    fake stub. In desktop mode, however, only desktop window has an X
    window associated with it.
 
-2. Messaging subsystem
+2. Visible region, clipping region and update region
+
+   windows/dce.c
+   windows/winpos.c
+   windows/painting.c
+
+    ________________________
+   |_________               |  A and B are child windows of C
+   |    A    |______        | 
+   |         |      |       |
+   |---------'      |       |
+   |   |      B     |       |
+   |   |            |       |
+   |   `------------'       |
+   |                   C    |
+   `------------------------'
+
+   Visible region determines which part of the window is not obscured
+   by other windows. If a window has the WS_CLIPCHILDREN style then all
+   areas below its children are considered invisible. Similarily, if
+   the WS_CLIPSIBLINGS bit is in effect then all areas obscured by its
+   siblings are invisible. Child windows are always clipped by the 
+   boundaries of their parent windows.
+
+   B has a WS_CLIPSIBLINGS style:
+   .          ______ 
+   :         |      |
+   |   ,-----'      |
+   |   |      B     | - visible region of B
+   |   |            |
+   :   `------------'
+    
+   When the program requests a display context (DC) for a window it 
+   can specify an optional clipping region that further restricts the 
+   area where the graphics output can appear. This area is calculated 
+   as an intersection of the visible region and a clipping region. 
+
+   Program asked for a DC with a clipping region:
+          ______
+      ,--|--.   |     .    ,--. 
+   ,--+--'  |   |     :   _:  |
+   |  |   B |   |  => |  |    | - DC region where the painting will
+   |  |     |   |     |  |    |   be visible
+   `--|-----|---'     :  `----'
+      `-----'
+
+   When the window manager detects that some part of the window 
+   became visible it adds this area to the update region of this
+   window and then generates WM_ERASEBKGND and WM_PAINT messages. 
+   In addition, WM_NCPAINT message is sent when the uncovered area 
+   intersects a nonclient part of the window. Application must reply 
+   to the WM_PAINT message by calling BeginPaint()/EndPaint() pair of
+   functions. BeginPaint() returns a DC that uses accumulated update 
+   region as a clipping region. This operation cleans up invalidated
+   area and the window will not receive another WM_PAINT until the
+   window manager creates a new update region.
+
+   A was moved to the left:
+    ________________________       ...          / C update region
+   |______                  |     :      .___ /
+   | A    |_________        |  => |   ...|___|..
+   |      |         |       |     |   :  |   |
+   |------'         |       |     |   :  '---' 
+   |   |      B     |       |     |   :      \
+   |   |            |       |     :            \
+   |   `------------'       |                    B update region
+   |                   C    |
+   `------------------------'
+
+
+   Windows maintains a display context cache consisting of entries that 
+   include DC itself, window to which it belongs, and an optional clipping 
+   region (visible region is stored in the DC itself). When an API call 
+   changes the state of the window tree, window manager has to go through 
+   the DC cache to recalculate visible regions for entries whose windows 
+   were involved in the operation. DC entries (DCE) can be either private
+   to the window, or private to the window class, or shared between all 
+   windows. Windows 3.1 limits the number of shared DCEs to 5. 
+
+3. Messaging subsystem
+
+   windows/queue.c
+   windows/message.c
 
    Each Windows task/thread has its own message queue - this is where
    it gets messages from. Messages can be generated on the fly
diff --git a/documentation/wine.texinfo b/documentation/wine.texinfo
index 1395c61..02f88a6 100644
--- a/documentation/wine.texinfo
+++ b/documentation/wine.texinfo
@@ -440,10 +440,10 @@
 @node Reference Manual, Installation, Introduction, Top
 
 @menu
-* @WIN32{} Reference Manual::      The @WIN32{} function calls and data types.
+* WIN32 Reference Manual::      The @WIN32{} function calls and data types.
 * Resources and INI files::     How to determine the appearance and
                                 behaviour of Wine programs.
-* Metafiles--Icons--Bitmaps::     FIXME missing.
+* Metafiles-Icons-Bitmaps::     FIXME missing.
 * Debugging::                   Debugging Wine.
 * Programs::                    Programs written to run in/with Wine.
 * Tools::                       Programs to support Wine.
diff --git a/files/drive.c b/files/drive.c
index cee484a..fc592c6 100644
--- a/files/drive.c
+++ b/files/drive.c
@@ -5,6 +5,7 @@
  * Copyright 1996 Alexandre Julliard
  */
 
+#include <assert.h>
 #include <ctype.h>
 #include <string.h>
 #include <stdlib.h>
@@ -502,6 +503,54 @@
 
 
 /***********************************************************************
+ *           DRIVE_SetLogicalMapping
+ */
+int DRIVE_SetLogicalMapping ( int existing_drive, int new_drive )
+{
+ /* If new_drive is already valid, do nothing and return 0
+    otherwise, copy DOSDrives[existing_drive] to DOSDrives[new_drive] */
+  
+    DOSDRIVE *old, *new;
+    
+    old = DOSDrives + existing_drive;
+    new = DOSDrives + new_drive;
+
+    if ((existing_drive < 0) || (existing_drive >= MAX_DOS_DRIVES) ||
+        !old->root ||
+	(new_drive < 0) || (new_drive >= MAX_DOS_DRIVES))
+    {
+        DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk );
+        return 0;
+    }
+
+    if ( new->root )
+    {
+        dprintf_dosfs ( stddeb, "Can\'t map drive %c to drive %c - "
+	                        "drive %c already exists\n",
+			'A' + existing_drive, 'A' + new_drive,
+			'A' + new_drive );
+	return 0;
+    }
+
+    new->root = HEAP_strdupA( SystemHeap, 0, old->root );
+    new->dos_cwd = HEAP_strdupA( SystemHeap, 0, old->dos_cwd );
+    new->unix_cwd = HEAP_strdupA( SystemHeap, 0, old->unix_cwd );
+    memcpy ( new->label, old->label, 12 );
+    new->serial = old->serial;
+    new->type = old->type;
+    new->flags = old->flags;
+    new->dev = old->dev;
+    new->ino = old->ino;
+
+    dprintf_dosfs ( stddeb, "Drive %c is now equal to drive %c\n",
+                    'A' + new_drive, 'A' + existing_drive );
+
+    return 1;
+}
+
+
+
+/***********************************************************************
  *           DRIVE_GetFreeSpace
  */
 static int DRIVE_GetFreeSpace( int drive, DWORD *size, DWORD *available )
@@ -560,7 +609,7 @@
     if (!root) drive = DRIVE_GetCurrentDrive();
     else
     {
-        if ((root[1] != ':') || (root[2] != '\\'))
+        if ((root[1]) && ((root[1] != ':') || (root[2] != '\\')))
         {
             fprintf( stderr, "GetDiskFreeSpaceA: invalid root '%s'\n", root );
             return FALSE;
@@ -622,7 +671,7 @@
 UINT32 WINAPI GetDriveType32A( LPCSTR root )
 {
     dprintf_dosfs( stddeb, "GetDriveType32A(%s)\n", root );
-    if (root[1] != ':')
+    if ((root[1]) && (root[1] != ':'))
     {
         fprintf( stderr, "GetDriveType32A: invalid root '%s'\n", root );
         return DRIVE_DOESNOTEXIST;
@@ -669,11 +718,7 @@
 {
     char *pref = "A:\\";
     const char *s = DRIVE_GetDosCwd( DRIVE_GetCurrentDrive() );
-    if (!s)
-    {
-        *buf = '\0';
-        return 0;
-    }
+    assert(s);
     lstrcpyn32A( buf, pref, MIN( 4, buflen ) );
     if (buflen) buf[0] += DRIVE_GetCurrentDrive();
     if (buflen > 3) lstrcpyn32A( buf + 3, s, buflen - 3 );
@@ -820,7 +865,7 @@
     if (!root) drive = DRIVE_GetCurrentDrive();
     else
     {
-        if ((root[1] != ':') || (root[2] != '\\'))
+        if ((root[1]) &&((root[1] != ':') || (root[2] != '\\')))
         {
             fprintf( stderr, "GetVolumeInformation: invalid root '%s'\n",root);
             return FALSE;
@@ -836,7 +881,7 @@
 
     if (filename_len) *filename_len = 12;
     if (flags) *flags = 0;
-    if (fsname) lstrcpyn32A( fsname, "FAT", fsname_len );
+    if (fsname) lstrcpyn32A( fsname, "FAT16", fsname_len );
     return TRUE;
 }
 
diff --git a/files/file.c b/files/file.c
index 540446a..51d443b 100644
--- a/files/file.c
+++ b/files/file.c
@@ -1207,12 +1207,32 @@
 /***********************************************************************
  *           FILE_mmap
  */
-LPVOID FILE_mmap( FILE_OBJECT *file, LPVOID start,
+LPVOID FILE_mmap( HFILE32 hFile, LPVOID start,
                   DWORD size_high, DWORD size_low,
                   DWORD offset_high, DWORD offset_low,
                   int prot, int flags )
 {
+    LPVOID ret;
+    FILE_OBJECT *file = FILE_GetFile( hFile );
+    if (!file) return (LPVOID)-1;
+    ret = FILE_dommap( file, start, size_high, size_low,
+                       offset_high, offset_low, prot, flags );
+    FILE_ReleaseFile( file );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           FILE_dommap
+ */
+LPVOID FILE_dommap( FILE_OBJECT *file, LPVOID start,
+                    DWORD size_high, DWORD size_low,
+                    DWORD offset_high, DWORD offset_low,
+                    int prot, int flags )
+{
     int fd = -1;
+    int pos;
+    LPVOID ret;
 
     if (size_high || offset_high)
         fprintf( stderr, "FILE_mmap: offsets larger than 4Gb not supported\n");
@@ -1244,7 +1264,52 @@
     }
     else fd = file->unix_handle;
 
-    return mmap( start, size_low, prot, flags, fd, offset_low );
+    if ((ret = mmap( start, size_low, prot,
+                     flags, fd, offset_low )) != (LPVOID)-1)
+        return ret;
+
+    /* mmap() failed; if this is because the file offset is not    */
+    /* page-aligned (EINVAL), or because the underlying filesystem */
+    /* does not support mmap() (ENOEXEC), we do it by hand.        */
+
+    if (!file) return ret;
+    if ((errno != ENOEXEC) && (errno != EINVAL)) return ret;
+    if (prot & PROT_WRITE)
+    {
+        /* We cannot fake shared write mappings */
+#ifdef MAP_SHARED
+	if (flags & MAP_SHARED) return ret;
+#endif
+#ifdef MAP_PRIVATE
+	if (!(flags & MAP_PRIVATE)) return ret;
+#endif
+    }
+/*    printf( "FILE_mmap: mmap failed (%d), faking it\n", errno );*/
+    /* Reserve the memory with an anonymous mmap */
+    ret = FILE_mmap( NULL, start, size_high, size_low, 0, 0,
+                     PROT_READ | PROT_WRITE, flags );
+    if (ret == (LPVOID)-1) return ret;
+    /* Now read in the file */
+    if ((pos = lseek( fd, offset_low, SEEK_SET )) == -1)
+    {
+        FILE_munmap( ret, size_high, size_low );
+        return (LPVOID)-1;
+    }
+    read( fd, ret, size_low );
+    lseek( fd, pos, SEEK_SET );  /* Restore the file pointer */
+    mprotect( ret, size_low, prot );  /* Set the right protection */
+    return ret;
+}
+
+
+/***********************************************************************
+ *           FILE_munmap
+ */
+int FILE_munmap( LPVOID start, DWORD size_high, DWORD size_low )
+{
+    if (size_high)
+      fprintf( stderr, "FILE_munmap: offsets larger than 4Gb not supported\n");
+    return munmap( start, size_low );
 }
 
 
@@ -1262,8 +1327,6 @@
 
 /**************************************************************************
  *           MoveFileEx32A   (KERNEL32.???)
- *
- * 
  */
 BOOL32 WINAPI MoveFileEx32A( LPCSTR fn1, LPCSTR fn2, DWORD flag )
 {
diff --git a/graphics/escape.c b/graphics/escape.c
index 124f7e7..83e006a 100644
--- a/graphics/escape.c
+++ b/graphics/escape.c
@@ -47,6 +47,31 @@
     case GETPRINTINGOFFSET:
 	segout = SEGPTR_GET(SEGPTR_NEW(POINT16));
 	break;
+
+      /* Escape(hdc,GETTECHNOLOGY,NULL,LPSTR); */
+
+    case GETTECHNOLOGY: {
+        segout = SEGPTR_GET(SEGPTR_ALLOC(200)); /* enough I hope */
+        break;
+
+    }
+
+      /* Escape(hdc,ENABLEPAIRKERNING,LPINT16,LPINT16); */
+
+    case ENABLEPAIRKERNING: {
+        LPINT16 enab = SEGPTR_NEW(INT16);
+        segout = SEGPTR_GET(SEGPTR_NEW(INT16));
+        segin = SEGPTR_GET(enab);
+        *enab = *(INT32*)lpszInData;
+        break;
+    }
+
+      /* Escape(hdc,GETFACENAME,NULL,LPSTR); */
+
+    case GETFACENAME: {
+        segout = SEGPTR_GET(SEGPTR_ALLOC(200));
+        break;
+    }
     }
     ret = dc->funcs->pEscape( dc, nEscape, cbInput, segin, segout );
     switch(nEscape) {
@@ -63,6 +88,24 @@
 	SEGPTR_FREE(x);
 	break;
     }
+    case GETTECHNOLOGY: {
+        LPSTR x=PTR_SEG_TO_LIN(segout);
+        lstrcpy32A(lpvOutData,x);
+        SEGPTR_FREE(x);
+    }
+    case ENABLEPAIRKERNING: {
+        LPINT16 enab = (LPINT16)PTR_SEG_TO_LIN(segout);
+
+        *(LPINT32)lpvOutData = *enab;
+        SEGPTR_FREE(enab);
+        SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
+    }
+    case GETFACENAME: {
+        LPSTR x = (LPSTR)PTR_SEG_TO_LIN(segout);
+        lstrcpy32A(lpvOutData,x);
+        SEGPTR_FREE(x);
+        break;
+    }
     default:
     	break;
     }
diff --git a/graphics/painting.c b/graphics/painting.c
index 5fef330..15cb841 100644
--- a/graphics/painting.c
+++ b/graphics/painting.c
@@ -16,6 +16,7 @@
 #include "dc.h"
 #include "bitmap.h"
 #include "callback.h"
+#include "heap.h"
 #include "metafile.h"
 #include "syscolor.h"
 #include "palette.h"
@@ -23,7 +24,6 @@
 #include "region.h"
 #include "stddebug.h"
 #include "debug.h"
-#include "xmalloc.h"
 
 BOOL32 DrawDiagEdge32(HDC32 hdc, RECT32 *rect, UINT32 edge, UINT32 flags);
 BOOL32 DrawRectEdge32(HDC32 hdc, RECT32 *rect, UINT32 edge, UINT32 flags);
@@ -360,6 +360,17 @@
     return dc->funcs->pSetPixel(dc,x,y,color);
 }
 
+/***********************************************************************
+ *           SetPixel32    (GDI32.329)
+ */
+BOOL32 WINAPI SetPixelV32( HDC32 hdc, INT32 x, INT32 y, COLORREF color )
+{
+    DC * dc = DC_GetDCPtr( hdc );
+  
+    if (!dc || !dc->funcs->pSetPixel) return FALSE;
+    dc->funcs->pSetPixel(dc,x,y,color);
+    return TRUE;
+}
 
 /***********************************************************************
  *           GetPixel16    (GDI.83)
@@ -534,12 +545,14 @@
 BOOL16 WINAPI Polyline16( HDC16 hdc, LPPOINT16 pt, INT16 count )
 {
     register int i;
-    LPPOINT32 pt32 = (LPPOINT32)xmalloc(count*sizeof(POINT32));
     BOOL16 ret;
+    LPPOINT32 pt32 = (LPPOINT32)HeapAlloc( GetProcessHeap(), 0,
+                                           count*sizeof(POINT32) );
 
+    if (!pt32) return FALSE;
     for (i=count;i--;) CONV_POINT16TO32(&(pt[i]),&(pt32[i]));
     ret = Polyline32(hdc,pt32,count);
-    free(pt32);
+    HeapFree( GetProcessHeap(), 0, pt32 );
     return ret;
 }
 
@@ -562,13 +575,14 @@
 BOOL16 WINAPI Polygon16( HDC16 hdc, LPPOINT16 pt, INT16 count )
 {
     register int i;
-    LPPOINT32 pt32 = (LPPOINT32)xmalloc(count*sizeof(POINT32));
     BOOL32 ret;
+    LPPOINT32 pt32 = (LPPOINT32)HeapAlloc( GetProcessHeap(), 0,
+                                           count*sizeof(POINT32) );
 
-
+    if (!pt32) return FALSE;
     for (i=count;i--;) CONV_POINT16TO32(&(pt[i]),&(pt32[i]));
     ret = Polygon32(hdc,pt32,count);
-    free(pt32);
+    HeapFree( GetProcessHeap(), 0, pt32 );
     return ret;
 }
 
@@ -599,15 +613,16 @@
     nrpts=0;
     for (i=polygons;i--;)
     	nrpts+=counts[i];
-    pt32 = (LPPOINT32)xmalloc(sizeof(POINT32)*nrpts);
+    pt32 = (LPPOINT32)HEAP_xalloc( GetProcessHeap(), 0, sizeof(POINT32)*nrpts);
     for (i=nrpts;i--;)
     	CONV_POINT16TO32(&(pt[i]),&(pt32[i]));
-    counts32 = (LPINT32)xmalloc(polygons*sizeof(INT32));
+    counts32 = (LPINT32)HEAP_xalloc( GetProcessHeap(), 0,
+                                     polygons*sizeof(INT32) );
     for (i=polygons;i--;) counts32[i]=counts[i];
    
     ret = PolyPolygon32(hdc,pt32,counts32,polygons);
-    free(counts32);
-    free(pt32);
+    HeapFree( GetProcessHeap(), 0, counts32 );
+    HeapFree( GetProcessHeap(), 0, pt32 );
     return ret;
 }
 
diff --git a/graphics/win16drv/graphics.c b/graphics/win16drv/graphics.c
index 1a72994..ec2a72e 100644
--- a/graphics/win16drv/graphics.c
+++ b/graphics/win16drv/graphics.c
@@ -4,6 +4,7 @@
  * Copyright 1997 John Harvey
  */
 
+#include "heap.h"
 #include "win16drv.h"
 
 /**********************************************************************
@@ -64,7 +65,7 @@
     points[0].y = YLPTODP(dc, top);
 
     points[1].x = XLPTODP(dc, right);
-    points[1].y = XLPTODP(dc, bottom);
+    points[1].y = YLPTODP(dc, bottom);
     bRet = PRTDRV_Output(physDev->segptrPDEVICE,
                          OS_RECTANGLE, 2, points, 
                          physDev->segptrPenInfo,
@@ -86,7 +87,7 @@
     BOOL32 bRet = 0;
     LPPOINT16 points;
     int i;
-    points = malloc(count * sizeof(POINT16));
+    points = HEAP_xalloc( GetProcessHeap(), 0, count * sizeof(POINT16) );
     for (i = 0; i<count ; i++)
     {
       points[i].x = ((pt[i].x - dc->wndOrgX) * dc->vportExtX/ dc->wndExtX) + dc->vportOrgX;
@@ -97,9 +98,6 @@
                          physDev->segptrPenInfo,
                          physDev->segptrBrushInfo,
                          win16drv_SegPtr_DrawMode, NULL);
+    HeapFree( GetProcessHeap(), 0, points );
     return bRet;
 }
-
-
-
-
diff --git a/graphics/win16drv/init.c b/graphics/win16drv/init.c
index 2254bf4..ba0a454 100644
--- a/graphics/win16drv/init.c
+++ b/graphics/win16drv/init.c
@@ -413,6 +413,10 @@
     {
 	switch(nEscape)
           {
+	  case ENABLEPAIRKERNING:
+	    fprintf(stderr,"Escape: ENABLEPAIRKERNING ignored.\n");
+            nRet = 1;
+	    break;
           case SETABORTPROC:
 	    printf("Escape: SetAbortProc ignored should be stored in dc somewhere\n");
             /* Make calling application believe this worked */
diff --git a/graphics/win16drv/prtdrv.c b/graphics/win16drv/prtdrv.c
index 6a533ba..4d22cff 100644
--- a/graphics/win16drv/prtdrv.c
+++ b/graphics/win16drv/prtdrv.c
@@ -191,27 +191,17 @@
 
     if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
     {
-	LONG lP1, lP3, lP4;
-	WORD wP2;
-
 	if (pLPD->fn[FUNC_CONTROL] == NULL)
 	{
 	    dprintf_win16drv(stddeb, "PRTDRV_Control: Not supported by driver\n");
 	    return 0;
 	}
-
-	lP1 = (SEGPTR)lpDestDev;
-	wP2 = wfunction;
-	lP3 = (SEGPTR)lpInData;
-	lP4 = (SEGPTR)lpOutData;
-
-	wRet = CallTo16_word_lwll(pLPD->fn[FUNC_CONTROL], 
-                                  lP1, wP2, lP3, lP4);
+	wRet = Callbacks->CallDrvControlProc( pLPD->fn[FUNC_CONTROL], 
+                                              (SEGPTR)lpDestDev, wfunction,
+                                              lpInData, lpOutData );
     }
     dprintf_win16drv(stddeb, "PRTDRV_Control: return %x\n", wRet);
     return wRet;
-
-    return 0;
 }
 
 /*
@@ -253,7 +243,7 @@
 	lP4 = SEGPTR_STRDUP(lpOutputFile);
 	lP5 = (LONG)lpData;
         
-	wRet = CallTo16_word_lwlll(pLPD->fn[FUNC_ENABLE], 
+	wRet = Callbacks->CallDrvEnableProc(pLPD->fn[FUNC_ENABLE], 
 				   (wStyle==INITPDEVICE)?lP1:SEGPTR_GET(lP1),
 				   wP2,
 				   SEGPTR_GET(lP3),
@@ -286,7 +276,7 @@
 
     if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
     {
-	LONG lP1, lP3, lP4;
+	LONG lP1, lP4;
 	LPBYTE lP2;
 
 	if (pLPD->fn[FUNC_ENUMDFONTS] == NULL) {
@@ -296,11 +286,10 @@
 
 	lP1 = (SEGPTR)lpDestDev;
 	lP2 = SEGPTR_STRDUP(lpFaceName);
-	lP3 = (LONG)lpCallbackFunc; 
 	lP4 = (LONG)lpClientData;
-        
-	wRet = CallTo16_word_llll(pLPD->fn[FUNC_ENUMDFONTS], 
-                                  lP1, SEGPTR_GET(lP2), lP3, lP4);
+        wRet = Callbacks->CallDrvEnumDFontsProc( pLPD->fn[FUNC_ENUMDFONTS], 
+                                                 lP1, SEGPTR_GET(lP2),
+                                                 lpCallbackFunc, lP4);
 	SEGPTR_FREE(lP2);
     } else 
         fprintf(stderr,"Failed to find device\n");
@@ -321,7 +310,8 @@
 
     if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
     {
-	LONG lP1, lP3, lP4;
+	LONG lP1, lP4;
+        FARPROC16 lP3;
 	WORD wP2;
 
 	if (pLPD->fn[FUNC_ENUMDFONTS] == NULL)
@@ -337,12 +327,12 @@
 	/* 
 	 * Need to pass addres of function conversion function that will switch back to 32 bit code if necessary
 	 */
-	lP3 = (LONG)lpCallbackFunc; 
+	lP3 = (FARPROC16)lpCallbackFunc; 
 
 	lP4 = (LONG)lpClientData;
         
-	wRet = CallTo16_word_lwll(pLPD->fn[FUNC_ENUMOBJ], 
-                                  lP1, wP2, lP3, lP4);
+        wRet = Callbacks->CallDrvEnumObjProc( pLPD->fn[FUNC_ENUMOBJ], 
+                                              lP1, wP2, lP3, lP4 );
     }
     else 
         fprintf(stderr,"Failed to find device\n");
@@ -399,9 +389,9 @@
 	}
 	else
 	  lP8 = 0L;
-	wRet = CallTo16_word_lwwlllll(pLPD->fn[FUNC_OUTPUT], 
-                                      lP1, wP2, wP3, SEGPTR_GET(lP4), lP5,
-                                      lP6, lP7, SEGPTR_GET(lP8));
+	wRet = Callbacks->CallDrvOutputProc(pLPD->fn[FUNC_OUTPUT], 
+                                            lP1, wP2, wP3, SEGPTR_GET(lP4),
+                                            lP5, lP6, lP7, SEGPTR_GET(lP8));
         SEGPTR_FREE(lP4);
         SEGPTR_FREE(lP8);
     }
@@ -460,8 +450,9 @@
 
         lP5 = lpTextXForm;
 
-	dwRet = CallTo16_long_lwlll(pLPD->fn[FUNC_REALIZEOBJECT], 
-                                    lP1, wP2, SEGPTR_GET(lP3), lP4, lP5);
+	dwRet = Callbacks->CallDrvRealizeProc(pLPD->fn[FUNC_REALIZEOBJECT], 
+                                              lP1, wP2, SEGPTR_GET(lP3),
+                                              lP4, lP5);
         SEGPTR_FREE(lP3);
 
     }
@@ -520,10 +511,11 @@
 	}
 	else
 	  lP14 = 0L;
-	wRet = CallTo16_word_lwwwwlwwwwllll(pLPD->fn[FUNC_STRETCHBLT], 
-                                           lP1, wP2, wP3, wP4, wP5,
-                                            lP6, wP7, wP8, wP9, wP10, 
-                                            lP11, lP12, lP13, SEGPTR_GET(lP14));
+	wRet = Callbacks->CallDrvStretchBltProc(pLPD->fn[FUNC_STRETCHBLT], 
+                                                lP1, wP2, wP3, wP4, wP5,
+                                                lP6, wP7, wP8, wP9, wP10, 
+                                                lP11, lP12, lP13,
+                                                SEGPTR_GET(lP14));
         SEGPTR_FREE(lP14);
         printf("Called StretchBlt ret %d\n",wRet);
     }
@@ -601,10 +593,12 @@
                "0x%lx 0x%lx %p 0x%x\n",lP1, wP2, wP3, lP4, 
 					   nSize,lP5, iP6, lP7, lP8, lP9, lP10,
 					   lP11, wP12);
-	dwRet = CallTo16_long_lwwllwlllllw(pLPD->fn[FUNC_EXTTEXTOUT], 
-                                           lP1, wP2, wP3, SEGPTR_GET(lP4), 
-					   SEGPTR_GET(lP5), iP6, lP7, lP8, lP9, lP10,
-					   SEGPTR_GET(lP11), wP12);
+	dwRet = Callbacks->CallDrvExtTextOutProc(pLPD->fn[FUNC_EXTTEXTOUT], 
+                                                 lP1, wP2, wP3,
+                                                 SEGPTR_GET(lP4),
+                                                 SEGPTR_GET(lP5), iP6, lP7,
+                                                 lP8, lP9, lP10,
+                                                 SEGPTR_GET(lP11), wP12);
     }
     dprintf_win16drv(stddeb, "PRTDRV_ExtTextOut: return %lx\n", dwRet);
     return dwRet;
diff --git a/graphics/win16drv/text.c b/graphics/win16drv/text.c
index cef68aa..e4b1cc4 100644
--- a/graphics/win16drv/text.c
+++ b/graphics/win16drv/text.c
@@ -97,7 +97,7 @@
     }
 #endif        
 
-	dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, XLPTODP(dc,x), XLPTODP(dc,y), 
+	dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, XLPTODP(dc,x), YLPTODP(dc,y), 
 				  &clipRect, str, 
 				  wCount,  physDev->segptrFontInfo, win16drv_SegPtr_DrawMode, 
 				  win16drv_SegPtr_TextXForm, NULL, lpOpaqueRect, wOptions);
diff --git a/graphics/x11drv/bitblt.c b/graphics/x11drv/bitblt.c
index a497ce2..4436913 100644
--- a/graphics/x11drv/bitblt.c
+++ b/graphics/x11drv/bitblt.c
@@ -655,7 +655,8 @@
     widthDst  = abs(widthDst);
     heightDst = abs(heightDst);
 
-    if (!(rowSrc = (int *)malloc( (widthSrc+widthDst)*sizeof(int) ))) return;
+    if (!(rowSrc = (int *)HeapAlloc( GetProcessHeap(), 0,
+                                    (widthSrc+widthDst)*sizeof(int) ))) return;
     rowDst = rowSrc + widthSrc;
 
       /* When stretching, all modes are the same, and DELETESCANS is faster */
@@ -799,7 +800,7 @@
                         widthDst*sizeof(int) );
         }
     }        
-    free( rowSrc );
+    HeapFree( GetProcessHeap(), 0, rowSrc );
 }
 
 
diff --git a/graphics/x11drv/text.c b/graphics/x11drv/text.c
index d7c28cf..984d295 100644
--- a/graphics/x11drv/text.c
+++ b/graphics/x11drv/text.c
@@ -16,14 +16,10 @@
 #include "stddebug.h"
 /* #define DEBUG_TEXT */
 #include "debug.h"
-#include "xmalloc.h"
 
 #define SWAP_INT(a,b)  { int t = a; a = b; b = t; }
 
 
-extern int CLIPPING_IntersectClipRect( DC * dc, short left, short top,
-                                       short right, short bottom, UINT16 flags);
-
 /***********************************************************************
  *           X11DRV_ExtTextOut
  */
@@ -195,7 +191,8 @@
 
 	/* allocate max items */
 
-        pitem = items = xmalloc( count * sizeof(XTextItem) );
+        pitem = items = HEAP_xalloc( GetProcessHeap(), 0,
+                                     count * sizeof(XTextItem) );
         delta = i = 0;
 	if( lpDx ) /* explicit character widths */
 	{
@@ -245,7 +242,7 @@
 
         XDrawText( display, dc->u.x.drawable, dc->u.x.gc,
                    dc->w.DCOrgX + x, dc->w.DCOrgY + y, items, pitem - items );
-        free( items );
+        HeapFree( GetProcessHeap(), 0, items );
     }
 
       /* Draw underline and strike-out if needed */
diff --git a/graphics/x11drv/xfont.c b/graphics/x11drv/xfont.c
index 7118cbe..b02b710 100644
--- a/graphics/x11drv/xfont.c
+++ b/graphics/x11drv/xfont.c
@@ -56,11 +56,13 @@
 
 /* Font alias table - these 2 aliases are always present */
 
-static fontAlias aliasTable[2] = { 
-			{ "Helvetica", "Helv", &aliasTable[1] },
+static fontAlias __aliasTable[2] = { 
+			{ "Helvetica", "Helv", &__aliasTable[1] },
 			{ "Times", "Tms Rmn", NULL } 
 			};
 
+static fontAlias *aliasTable = __aliasTable;
+
 /* Optional built-in aliases, they are installed only when X
  * cannot supply us with original MS fonts */
 
@@ -961,6 +963,27 @@
 		{
 		    if( bSubst )
 		    {
+			fontAlias *pfa, *prev = NULL;
+
+			for(pfa = aliasTable; pfa; pfa = pfa->next)
+			{
+	/* Remove lpAlias from aliasTable - we should free the old entry */
+			    if(!lstrcmp32A(lpAlias, pfa->faAlias))
+			    {
+				if(prev)
+				    prev->next = pfa->next;
+				else
+				    aliasTable = pfa->next;
+			     }
+
+	/* Update any references to the substituted font in aliasTable */
+			    if(!lstrcmp32A(frMatch->lfFaceName,
+							pfa->faTypeFace))
+				pfa->faTypeFace = HEAP_strdupA( SystemHeap, 0,
+							 lpAlias );
+			    prev = pfa;
+			}
+						
 #ifdef DEBUG_FONT_INIT
                         dprintf_font(stddeb, "\tsubstituted '%s' with %s\n",
 						frMatch->lfFaceName, lpAlias );
diff --git a/if1632/Makefile.in b/if1632/Makefile.in
index ddc8d34..2469274 100644
--- a/if1632/Makefile.in
+++ b/if1632/Makefile.in
@@ -45,6 +45,7 @@
 	version.spec \
 	w32sys.spec \
 	win87em.spec \
+	winaspi.spec \
 	wing.spec \
 	winmm.spec \
 	winsock.spec \
@@ -84,7 +85,7 @@
 call32.s: $(BUILD)
 	$(BUILD) -o $@ -call32
 
-callto16.s: $(TOPSRCDIR)/include/callback.h $(BUILD)
-	$(BUILD) -o $@ -callto16 `cat $(TOPSRCDIR)/include/callback.h | grep "extern.*CallTo16_" | sed 's/.*CallTo16_\(.*\)(.*/\1/' | sort | uniq`
+callto16.s: $(SRCDIR)/thunk.c $(BUILD)
+	$(BUILD) -o $@ -callto16 $(SRCDIR)/thunk.c
 
 ### Dependencies:
diff --git a/if1632/advapi32.spec b/if1632/advapi32.spec
index 237e01c..d72abaa 100644
--- a/if1632/advapi32.spec
+++ b/if1632/advapi32.spec
@@ -128,16 +128,16 @@
 0124 stub ReadEventLogA
 0125 stub ReadEventLogW
 0126 stdcall RegCloseKey(long) RegCloseKey
-0127 stdcall RegConnectRegistryA(ptr long ptr) RegConnectRegistry32A
+0127 stdcall RegConnectRegistryA(str long ptr) RegConnectRegistry32A
 0128 stub RegConnectRegistryW
-0129 stdcall RegCreateKeyA(long ptr ptr) RegCreateKey32A
-0130 stdcall RegCreateKeyExA(long ptr long ptr long long ptr ptr ptr) RegCreateKeyEx32A
-0131 stdcall RegCreateKeyExW(long ptr long ptr long long ptr ptr ptr) RegCreateKeyEx32W
-0132 stdcall RegCreateKeyW(long ptr ptr) RegCreateKey32W
-0133 stdcall RegDeleteKeyA(long ptr) RegDeleteKey32A
-0134 stdcall RegDeleteKeyW(long ptr) RegDeleteKey32W
-0135 stdcall RegDeleteValueA(long ptr) RegDeleteValue32A
-0136 stdcall RegDeleteValueW(long ptr) RegDeleteValue32W
+0129 stdcall RegCreateKeyA(long str ptr) RegCreateKey32A
+0130 stdcall RegCreateKeyExA(long str long ptr long long ptr ptr ptr) RegCreateKeyEx32A
+0131 stdcall RegCreateKeyExW(long wstr long ptr long long ptr ptr ptr) RegCreateKeyEx32W
+0132 stdcall RegCreateKeyW(long wstr ptr) RegCreateKey32W
+0133 stdcall RegDeleteKeyA(long str) RegDeleteKey32A
+0134 stdcall RegDeleteKeyW(long wstr) RegDeleteKey32W
+0135 stdcall RegDeleteValueA(long str) RegDeleteValue32A
+0136 stdcall RegDeleteValueW(long wstr) RegDeleteValue32W
 0137 stdcall RegEnumKeyA(long long ptr long) RegEnumKey32A
 0138 stdcall RegEnumKeyExA(long long ptr ptr ptr ptr ptr ptr) RegEnumKeyEx32A
 0139 stdcall RegEnumKeyExW(long long ptr ptr ptr ptr ptr ptr) RegEnumKeyEx32W
@@ -149,18 +149,18 @@
 0145 stub RegLoadKeyA
 0146 stub RegLoadKeyW
 0147 stub RegNotifyChangeKeyValue
-0148 stdcall RegOpenKeyA(long ptr ptr) RegOpenKey32A
-0149 stdcall RegOpenKeyExA(long ptr long long ptr) RegOpenKeyEx32A
-0150 stdcall RegOpenKeyExW(long ptr long long ptr) RegOpenKeyEx32W
-0151 stdcall RegOpenKeyW(long ptr ptr) RegOpenKey32W
+0148 stdcall RegOpenKeyA(long str ptr) RegOpenKey32A
+0149 stdcall RegOpenKeyExA(long str long long ptr) RegOpenKeyEx32A
+0150 stdcall RegOpenKeyExW(long wstr long long ptr) RegOpenKeyEx32W
+0151 stdcall RegOpenKeyW(long wstr ptr) RegOpenKey32W
 0152 stdcall RegQueryInfoKeyA(long ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) RegQueryInfoKey32A
 0153 stdcall RegQueryInfoKeyW(long ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) RegQueryInfoKey32W
 0154 stub RegQueryMultipleValuesA
 0155 stub RegQueryMultipleValuesW
-0156 stdcall RegQueryValueA(long ptr ptr ptr) RegQueryValue32A
-0157 stdcall RegQueryValueExA(long ptr ptr ptr ptr ptr) RegQueryValueEx32A
-0158 stdcall RegQueryValueExW(long ptr ptr ptr ptr ptr) RegQueryValueEx32W
-0159 stdcall RegQueryValueW(long ptr ptr ptr) RegQueryValue32W
+0156 stdcall RegQueryValueA(long str ptr ptr) RegQueryValue32A
+0157 stdcall RegQueryValueExA(long str ptr ptr ptr ptr) RegQueryValueEx32A
+0158 stdcall RegQueryValueExW(long wstr ptr ptr ptr ptr) RegQueryValueEx32W
+0159 stdcall RegQueryValueW(long wstr ptr ptr) RegQueryValue32W
 0160 stub RegRemapPreDefKey
 0161 stub RegReplaceKeyA
 0162 stub RegReplaceKeyW
@@ -169,10 +169,10 @@
 0165 stub RegSaveKeyA
 0166 stub RegSaveKeyW
 0167 stub RegSetKeySecurity
-0168 stdcall RegSetValueA(long ptr long ptr long) RegSetValue32A
-0169 stdcall RegSetValueExA(long ptr long long ptr long) RegSetValueEx32A
-0170 stdcall RegSetValueExW(long ptr long long ptr long) RegSetValueEx32W
-0171 stdcall RegSetValueW(long ptr long ptr long) RegSetValue32W
+0168 stdcall RegSetValueA(long str long ptr long) RegSetValue32A
+0169 stdcall RegSetValueExA(long str long long ptr long) RegSetValueEx32A
+0170 stdcall RegSetValueExW(long wstr long long ptr long) RegSetValueEx32W
+0171 stdcall RegSetValueW(long wstr long ptr long) RegSetValue32W
 0172 stub RegUnLoadKeyA
 0173 stub RegUnLoadKeyW
 0174 stub RegisterEventSourceA
diff --git a/if1632/builtin.c b/if1632/builtin.c
index 29ba5ac..95e29e3 100644
--- a/if1632/builtin.c
+++ b/if1632/builtin.c
@@ -41,6 +41,7 @@
     const char * const *names;      /* Pointer to names table */
     const WORD         *ordinals;   /* Pointer to ordinals table */
     const BYTE         *args;       /* Pointer to argument lengths */
+    const DWORD        *argtypes;   /* Pointer to argument types bitmask */
 } WIN32_DESCRIPTOR;
 
 typedef union
@@ -101,6 +102,7 @@
 extern const DLL_DESCRIPTOR VER_Descriptor;
 extern const DLL_DESCRIPTOR W32SYS_Descriptor;
 extern const DLL_DESCRIPTOR WING_Descriptor;
+extern const DLL_DESCRIPTOR WINASPI_Descriptor;
 
 /* 32-bit DLLs */
 
@@ -155,6 +157,7 @@
     { &VER_Descriptor,      NULL, 0 },
     { &W32SYS_Descriptor,   NULL, 0 },
     { &WING_Descriptor,     NULL, 0 },
+    { &WINASPI_Descriptor,  NULL, 0 },
     /* Win32 DLLs */
     { &ADVAPI32_Descriptor, NULL, DLL_FLAG_WIN32 },
     { &COMCTL32_Descriptor, NULL, DLL_FLAG_WIN32 | DLL_FLAG_NOT_USED },
@@ -462,7 +465,7 @@
  * This function _must_ return the real entry point to call
  * after the debug info is printed.
  */
-FARPROC32 BUILTIN_GetEntryPoint32( char *buffer, void *relay )
+FARPROC32 BUILTIN_GetEntryPoint32( char *buffer, void *relay, DWORD *typemask )
 {
     BUILTIN_DLL *dll;
     int ordinal, i;
@@ -487,6 +490,7 @@
     assert( i < descr->nb_names );
 
     sprintf( buffer, "%s.%d: %s", descr->name, ordinal, descr->names[i] );
+    *typemask = descr->argtypes[ordinal - descr->base];
     return (FARPROC32)descr->functions[ordinal - descr->base];
 }
 
diff --git a/if1632/crtdll.spec b/if1632/crtdll.spec
index 566e2df..c0b8f3c 100644
--- a/if1632/crtdll.spec
+++ b/if1632/crtdll.spec
@@ -114,8 +114,8 @@
 110 stub _fsopen
 111 stub _fstat
 112 stub _ftime
-113 stub _ftol
-114 stub _fullpath
+113 cdecl _ftol(double) CRTDLL__ftol
+114 cdecl _fullpath(ptr ptr long) CRTDLL__fullpath
 115 stub _futime
 116 stub _gcvt
 117 stub _get_osfhandle
@@ -281,7 +281,7 @@
 277 stub _spawnvp
 278 stub _spawnvpe
 279 stub _splitpath
-280 stub _stat
+280 cdecl _stat (ptr ptr) CRTDLL__stat
 281 stub _statusfp
 282 cdecl _strcmpi(ptr ptr) CRTDLL__strcmpi
 283 stub _strdate
@@ -336,9 +336,9 @@
 332 cdecl _write(long ptr long) CRTDLL__write
 333 stub _wtoi
 334 stub _wtol
-335 stub _y0
-336 stub _y1
-337 stub _yn
+335 cdecl _y0(double) y0
+336 cdecl _y1(double) y1
+337 cdecl _yn(long double) yn
 338 stub abort
 339 cdecl abs(long) abs
 340 cdecl acos(double) acos
@@ -371,7 +371,7 @@
 367 stub fgetpos
 368 cdecl fgets(ptr long ptr) CRTDLL_fgets
 369 stub fgetwc
-370 stub floor
+370 cdecl floor(double) floor
 371 cdecl fmod(double double) fmod
 372 cdecl fopen(ptr ptr) CRTDLL_fopen
 373 varargs fprintf() CRTDLL_fprintf
@@ -381,7 +381,7 @@
 377 cdecl fread(ptr long long ptr) CRTDLL_fread
 378 cdecl free(ptr) CRTDLL_free
 379 stub freopen
-380 stub frexp
+380 cdecl frexp(double ptr) frexp
 381 stub fscanf
 382 cdecl fseek(ptr long long) CRTDLL_fseek
 383 stub fsetpos
@@ -421,7 +421,7 @@
 417 stub iswxdigit
 418 cdecl isxdigit(long) isxdigit
 419 cdecl labs(long) labs
-420 stub ldexp
+420 cdecl ldexp(double long) ldexp
 421 cdecl ldiv(long long) ldiv
 422 stub localeconv
 423 cdecl localtime(ptr) localtime
@@ -438,7 +438,7 @@
 434 cdecl memmove(ptr ptr long) memmove
 435 cdecl memset(ptr long long) memset 
 436 cdecl mktime(ptr) mktime
-437 stub modf
+437 cdecl modf(double ptr) modf
 438 stub perror
 439 cdecl pow(double double) pow
 440 varargs printf() printf
@@ -450,7 +450,7 @@
 446 cdecl rand() CRTDLL_rand
 447 cdecl realloc(ptr long) CRTDLL_realloc
 448 stub remove
-449 stub rename
+449 cdecl rename(str str) CRTDLL_rename
 450 stub rewind
 451 stub scanf
 452 cdecl setbuf(ptr ptr) CRTDLL_setbuf
diff --git a/if1632/gdi32.spec b/if1632/gdi32.spec
index 7d7851a..3a3abe9 100644
--- a/if1632/gdi32.spec
+++ b/if1632/gdi32.spec
@@ -3,9 +3,9 @@
 
   0 stub AbortDoc
   1 stub AbortPath
-  2 stdcall AddFontResourceA(ptr) AddFontResource32A
+  2 stdcall AddFontResourceA(str) AddFontResource32A
   3 stub AddFontResourceTracking
-  4 stdcall AddFontResourceW(ptr) AddFontResource32W
+  4 stdcall AddFontResourceW(wstr) AddFontResource32W
   5 stub AngleArc
   6 stdcall AnimatePalette(long long long ptr) AnimatePalette32
   7 stdcall Arc(long long long long long long long long long) Arc32
@@ -24,8 +24,8 @@
  20 stub CombineTransform
  21 stub CopyEnhMetaFileA
  22 stub CopyEnhMetaFileW
- 23 stdcall CopyMetaFileA(long ptr) CopyMetaFile32A
- 24 stdcall CopyMetaFileW(long ptr) CopyMetaFile32W
+ 23 stdcall CopyMetaFileA(long str) CopyMetaFile32A
+ 24 stdcall CopyMetaFileW(long wstr) CopyMetaFile32W
  25 stdcall CreateBitmap(long long long long ptr) CreateBitmap32
  26 stdcall CreateBitmapIndirect(ptr) CreateBitmapIndirect32
  27 stdcall CreateBrushIndirect(ptr) CreateBrushIndirect32
@@ -33,8 +33,8 @@
  29 stub CreateColorSpaceW
  30 stdcall CreateCompatibleBitmap(long long long) CreateCompatibleBitmap32
  31 stdcall CreateCompatibleDC(long) CreateCompatibleDC32
- 32 stdcall CreateDCA(ptr ptr ptr ptr) CreateDC32A
- 33 stdcall CreateDCW(ptr ptr ptr ptr) CreateDC32W
+ 32 stdcall CreateDCA(str str str ptr) CreateDC32A
+ 33 stdcall CreateDCW(wstr wstr wstr ptr) CreateDC32W
  34 stdcall CreateDIBPatternBrush(long long) CreateDIBPatternBrush32
  35 stub CreateDIBPatternBrushPt
  36 stdcall CreateDIBSection(long ptr long ptr long long) CreateDIBSection
@@ -45,15 +45,15 @@
  41 stub CreateEnhMetaFileA
  42 stub CreateEnhMetaFileW
  43 stdcall CreateFontA(long long long long long long long long
-                        long long long long long ptr) CreateFont32A
+                        long long long long long str) CreateFont32A
  44 stdcall CreateFontIndirectA(ptr) CreateFontIndirect32A
  45 stdcall CreateFontIndirectW(ptr) CreateFontIndirect32W
  46 stdcall CreateFontW(long long long long long long long long
-                        long long long long long ptr) CreateFont32W
+                        long long long long long wstr) CreateFont32W
  47 stub CreateHalftonePalette
  48 stdcall CreateHatchBrush(long long) CreateHatchBrush32
- 49 stdcall CreateICA(ptr ptr ptr ptr) CreateIC32A
- 50 stdcall CreateICW(ptr ptr ptr ptr) CreateIC32W
+ 49 stdcall CreateICA(str str str ptr) CreateIC32A
+ 50 stdcall CreateICW(wstr wstr wstr ptr) CreateIC32W
  51 stub CreateMetaFileA
  52 stub CreateMetaFileW
  53 stdcall CreatePalette(ptr) CreatePalette32
@@ -66,8 +66,8 @@
  60 stdcall CreateRectRgnIndirect(ptr) CreateRectRgnIndirect32
  61 stdcall CreateRoundRectRgn(long long long long long long)
              CreateRoundRectRgn32
- 62 stdcall CreateScalableFontResourceA(long ptr ptr ptr) CreateScalableFontResource32A
- 63 stdcall CreateScalableFontResourceW(long ptr ptr ptr) CreateScalableFontResource32W
+ 62 stdcall CreateScalableFontResourceA(long str str str) CreateScalableFontResource32A
+ 63 stdcall CreateScalableFontResourceW(long wstr wstr wstr) CreateScalableFontResource32W
  64 stdcall CreateSolidBrush(long) CreateSolidBrush32
  65 stdcall DPtoLP(long ptr long) DPtoLP32
  66 stub DeleteColorSpace
@@ -84,12 +84,12 @@
  77 stub EndPage
  78 stub EndPath
  79 stub EnumEnhMetaFile
- 80 stdcall EnumFontFamiliesA(long ptr ptr long) EnumFontFamilies32A
- 81 stdcall EnumFontFamiliesExA(long ptr ptr long long) EnumFontFamiliesEx32A
- 82 stdcall EnumFontFamiliesExW(long ptr ptr long long) EnumFontFamiliesEx32W
- 83 stdcall EnumFontFamiliesW(long ptr ptr long) EnumFontFamilies32W
- 84 stdcall EnumFontsA(long ptr ptr long) EnumFonts32A
- 85 stdcall EnumFontsW(long ptr ptr long) EnumFonts32W
+ 80 stdcall EnumFontFamiliesA(long str ptr long) EnumFontFamilies32A
+ 81 stdcall EnumFontFamiliesExA(long str ptr long long) EnumFontFamiliesEx32A
+ 82 stdcall EnumFontFamiliesExW(long wstr ptr long long) EnumFontFamiliesEx32W
+ 83 stdcall EnumFontFamiliesW(long wstr ptr long) EnumFontFamilies32W
+ 84 stdcall EnumFontsA(long str ptr long) EnumFonts32A
+ 85 stdcall EnumFontsW(long wstr ptr long) EnumFonts32W
  86 stub EnumICMProfilesA
  87 stub EnumICMProfilesW
  88 stub EnumMetaFile
@@ -102,8 +102,8 @@
  95 stdcall ExtEscape(long long long ptr long ptr) ExtEscape32
  96 stdcall ExtFloodFill(long long long long long) ExtFloodFill32
  97 stub ExtSelectClipRgn
- 98 stdcall ExtTextOutA(long long long long ptr ptr long ptr) ExtTextOut32A
- 99 stdcall ExtTextOutW(long long long long ptr ptr long ptr) ExtTextOut32W
+ 98 stdcall ExtTextOutA(long long long long ptr str long ptr) ExtTextOut32A
+ 99 stdcall ExtTextOutW(long long long long ptr wstr long ptr) ExtTextOut32W
 100 stub FillPath
 101 stdcall FillRgn(long long long) FillRgn32
 102 stub FixBrushOrgEx
@@ -132,7 +132,7 @@
 125 stub GdiCreateLocalRegion
 126 stub GdiDeleteLocalDC
 127 stub GdiDeleteLocalObject
-128 stub GdiFlush
+128 stdcall GdiFlush() GdiFlush
 129 stdcall GdiGetBatchLimit() GdiGetBatchLimit
 130 stub GdiGetLocalBrush
 131 stub GdiGetLocalDC
@@ -201,15 +201,15 @@
 194 stub GetLogColorSpaceA
 195 stub GetLogColorSpaceW
 196 stdcall GetMapMode(long) GetMapMode32
-197 stdcall GetMetaFileA(ptr) GetMetaFile32A
+197 stdcall GetMetaFileA(str) GetMetaFile32A
 198 stub GetMetaFileBitsEx
-199 stdcall GetMetaFileW(ptr) GetMetaFile32W
+199 stdcall GetMetaFileW(wstr) GetMetaFile32W
 200 stub GetMetaRgn
 201 stub GetMiterLimit
 202 stdcall GetNearestColor(long long) GetNearestColor32
 203 stdcall GetNearestPaletteIndex(long long) GetNearestPaletteIndex32
 204 stdcall GetObjectA(long long ptr) GetObject32A
-205 stub GetObjectType
+205 stdcall GetObjectType(long) GetObjectType
 206 stdcall GetObjectW(long long ptr) GetObject32W
 207 stub GetOutlineTextMetricsA
 208 stub GetOutlineTextMetricsW
@@ -227,17 +227,17 @@
 220 stdcall GetStockObject(long) GetStockObject32
 221 stdcall GetStretchBltMode(long) GetStretchBltMode32
 222 stdcall GetSystemPaletteEntries(long long long ptr) GetSystemPaletteEntries32
-223 stdcall GetSystemPaletteUse() GetSystemPaletteUse32
+223 stdcall GetSystemPaletteUse(long) GetSystemPaletteUse32
 224 stdcall GetTextAlign(long) GetTextAlign32
 225 stdcall GetTextCharacterExtra(long) GetTextCharacterExtra32
 226 stdcall GetTextCharset(long) GetTextCharset32
 227 stdcall GetTextColor(long) GetTextColor32
-228 stdcall GetTextExtentExPointA(long ptr long long ptr ptr ptr) GetTextExtentExPoint32A
-229 stdcall GetTextExtentExPointW(long ptr long long ptr ptr ptr) GetTextExtentExPoint32W
-230 stdcall GetTextExtentPoint32A(long ptr long ptr) GetTextExtentPoint32A
-231 stdcall GetTextExtentPoint32W(long ptr long ptr) GetTextExtentPoint32W
-232 stdcall GetTextExtentPointA(long ptr long ptr) GetTextExtentPoint32ABuggy
-233 stdcall GetTextExtentPointW(long ptr long ptr) GetTextExtentPoint32WBuggy
+228 stdcall GetTextExtentExPointA(long str long long ptr ptr ptr) GetTextExtentExPoint32A
+229 stdcall GetTextExtentExPointW(long wstr long long ptr ptr ptr) GetTextExtentExPoint32W
+230 stdcall GetTextExtentPoint32A(long str long ptr) GetTextExtentPoint32A
+231 stdcall GetTextExtentPoint32W(long wstr long ptr) GetTextExtentPoint32W
+232 stdcall GetTextExtentPointA(long str long ptr) GetTextExtentPoint32ABuggy
+233 stdcall GetTextExtentPointW(long wstr long ptr) GetTextExtentPoint32WBuggy
 234 stdcall GetTextFaceA(long long ptr) GetTextFace32A
 235 stdcall GetTextFaceW(long long ptr) GetTextFace32W
 236 stdcall GetTextMetricsA(long ptr) GetTextMetrics32A
@@ -288,9 +288,9 @@
 281 stdcall RectInRegion(long ptr) RectInRegion32
 282 stdcall RectVisible(long ptr) RectVisible32
 283 stdcall Rectangle(long long long long long) Rectangle32
-284 stdcall RemoveFontResourceA(ptr) RemoveFontResource32A
+284 stdcall RemoveFontResourceA(str) RemoveFontResource32A
 285 stub RemoveFontResourceTracking
-286 stdcall RemoveFontResourceW(ptr) RemoveFontResource32W
+286 stdcall RemoveFontResourceW(wstr) RemoveFontResource32W
 287 stdcall ResetDCA(long ptr) ResetDC32A
 288 stdcall ResetDCW(long ptr) ResetDC32W
 289 stdcall ResizePalette(long long) ResizePalette32
@@ -334,7 +334,7 @@
 326 stdcall SetPaletteEntries(long long long ptr) SetPaletteEntries32
 327 stdcall SetPixel(long long long long) SetPixel32
 328 stub SetPixelFormat
-329 stub SetPixelV
+329 stdcall SetPixelV(long long long long) SetPixelV32
 330 stdcall SetPolyFillMode(long long) SetPolyFillMode32
 331 stdcall SetROP2(long long) SetROP232
 332 stdcall SetRectRgn(long long long long long) SetRectRgn32
@@ -362,8 +362,8 @@
 352 stub StrokeAndFillPath
 353 stub StrokePath
 354 stub SwapBuffers
-355 stdcall TextOutA(long long long ptr long) TextOut32A
-356 stdcall TextOutW(long long long ptr long) TextOut32W
+355 stdcall TextOutA(long long long str long) TextOut32A
+356 stdcall TextOutW(long long long wstr long) TextOut32W
 357 stub UnloadNetworkFonts
 358 stdcall UnrealizeObject(long) UnrealizeObject32
 359 stdcall UpdateColors(long) UpdateColors32
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index 646e52a..98f1934 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -321,7 +321,7 @@
 511 stub KERNEL_511
 513 pascal   LoadLibraryEx32W(ptr long long) LoadLibraryEx32W16
 514 pascal16 FreeLibrary32W(long) FreeLibrary32
-515 pascal   GetProcAddress32W(long ptr) GetProcAddress32
+515 pascal   GetProcAddress32W(long str) GetProcAddress32
 516 pascal GetVDMPointer32W(segptr long) GetVDMPointer32W
 517 pascal CallProc32W() WIN16_CallProc32W
 518 stub CallProcEx32W
diff --git a/if1632/kernel32.spec b/if1632/kernel32.spec
index 8652559..c0b0b1c 100644
--- a/if1632/kernel32.spec
+++ b/if1632/kernel32.spec
@@ -26,19 +26,19 @@
  31 stub _KERNEL32_31
  
  34 stdcall _KERNEL32_34() _KERNEL32_34
- 35 stdcall LoadLibrary16(ptr) LoadLibrary16
+ 35 stdcall LoadLibrary16(str) LoadLibrary16
  36 stdcall FreeLibrary16(long) FreeLibrary16
- 37 stdcall GetProcAddress16(long ptr) WIN32_GetProcAddress16
+ 37 stdcall GetProcAddress16(long str) WIN32_GetProcAddress16
  
- 40 stub _KERNEL32_40
- 41 stdcall _KERNEL32_41(long long long long long) _KERNEL32_41
+ 40 register _KERNEL32_40() _KERNEL32_40
+ 41 stdcall _KERNEL32_41(long str long str str) _KERNEL32_41
  42 stub _KERNEL32_42
- 43 stdcall _KERNEL32_43(long ptr long ptr ptr) _KERNEL32_43
+ 43 stdcall _KERNEL32_43(long str long str str) _KERNEL32_43
  45 register _KERNEL32_45() _KERNEL32_45 
- 46 stdcall _KERNEL32_46(long long long long long) _KERNEL32_46
+ 46 stdcall _KERNEL32_46(long str long str str) _KERNEL32_46
  47 stub _KERNEL32_47
  
- 50 stdcall AddAtomA(ptr) AddAtom32A
+ 50 stdcall AddAtomA(str) AddAtom32A
 
  52 stdcall _KERNEL32_52() _KERNEL32_52
 
@@ -48,10 +48,10 @@
  56 stdcall WOWGetVDMPointer(long long long) WOWGetVDMPointer
  57 stub WOWHandle32
  58 stub WOWHandle16
- 59 stub WOWGlobalAlloc16
- 60 stub WOWGlobalLock16
- 61 stub WOWGlobalUnlock16
- 62 stub WOWGlobalFree16
+ 59 stdcall WOWGlobalAlloc16(long long) GlobalAlloc16
+ 60 stdcall WOWGlobalLock16(long) WIN16_GlobalLock16
+ 61 stdcall WOWGlobalUnlock16(long) GlobalUnlock16
+ 62 stdcall WOWGlobalFree16(long) GlobalFree16
  63 stdcall WOWGlobalAllocLock16(long long ptr) WOWGlobalAllocLock16
  64 stub WOWGlobalUnlockFree16
  65 stub WOWGlobalLockSize16
@@ -78,7 +78,7 @@
 
  87 stdcall _KERNEL32_87() _KERNEL32_87
  88 varargs _KERNEL32_88() _KERNEL32_88
- 89 stub _KERNEL32_89
+ 89 stdcall FT_PrologPrime(ptr ptr) FT_PrologPrime
  90 register _KERNEL32_90() _KERNEL32_90
  91 stub _KERNEL32_91
  92 stub _KERNEL32_92
@@ -90,7 +90,7 @@
 101 stub _KERNEL32_100
 
 
-102 stdcall AddAtomW(ptr) AddAtom32W
+102 stdcall AddAtomW(wstr) AddAtom32W
 103 stub AllocConsole
 104 stub AllocLSCallback
 105 stdcall AllocSLCallback(ptr ptr) AllocSLCallback
@@ -101,10 +101,10 @@
 110 stdcall Beep(long long) Beep
 111 stub BeginUpdateResourceA
 112 stub BeginUpdateResourceW
-113 stdcall BuildCommDCBA(ptr ptr) BuildCommDCB32A
-114 stdcall BuildCommDCBAndTimeoutsA(ptr ptr ptr) BuildCommDCBAndTimeouts32A
-115 stdcall BuildCommDCBAndTimeoutsW(ptr ptr ptr) BuildCommDCBAndTimeouts32W
-116 stdcall BuildCommDCBW(ptr ptr) BuildCommDCB32W
+113 stdcall BuildCommDCBA(str ptr) BuildCommDCB32A
+114 stdcall BuildCommDCBAndTimeoutsA(str ptr ptr) BuildCommDCBAndTimeouts32A
+115 stdcall BuildCommDCBAndTimeoutsW(wstr ptr ptr) BuildCommDCBAndTimeouts32W
+116 stdcall BuildCommDCBW(wstr ptr) BuildCommDCB32W
 117 stub CallNamedPipeA
 118 stub CallNamedPipeW
 119 stub Callback12
@@ -131,39 +131,39 @@
 140 stub CommConfigDialogA
 141 stub CommConfigDialogW
 142 stdcall CompareFileTime(ptr ptr) CompareFileTime
-143 stdcall CompareStringA(long long ptr long ptr long) CompareString32A
-144 stdcall CompareStringW(long long ptr long ptr long) CompareString32W
+143 stdcall CompareStringA(long long str long str long) CompareString32A
+144 stdcall CompareStringW(long long wstr long wstr long) CompareString32W
 145 stub ConnectNamedPipe
 146 stdcall ContinueDebugEvent(long long long) ContinueDebugEvent
 147 stub ConvertDefaultLocale
 148 stdcall ConvertToGlobalHandle(long) ConvertToGlobalHandle
-149 stdcall CopyFileA(ptr ptr long) CopyFile32A
-150 stdcall CopyFileW(ptr ptr long) CopyFile32W
+149 stdcall CopyFileA(str str long) CopyFile32A
+150 stdcall CopyFileW(wstr wstr long) CopyFile32W
 151 stub CreateConsoleScreenBuffer
-152 stdcall CreateDirectoryA(ptr ptr) CreateDirectory32A
-153 stdcall CreateDirectoryExA(ptr ptr ptr) CreateDirectoryEx32A
-154 stdcall CreateDirectoryExW(ptr ptr ptr) CreateDirectoryEx32W
-155 stdcall CreateDirectoryW(ptr ptr) CreateDirectory32W
-156 stdcall CreateEventA(ptr long long ptr) CreateEvent32A
-157 stdcall CreateEventW(ptr long long ptr) CreateEvent32W
-158 stdcall CreateFileA(ptr long long ptr long long long) CreateFile32A
-159 stdcall CreateFileMappingA(long ptr long long long ptr) CreateFileMapping32A
-160 stdcall CreateFileMappingW(long ptr long long long ptr) CreateFileMapping32W
-161 stdcall CreateFileW(ptr long long ptr long long long) CreateFile32W
+152 stdcall CreateDirectoryA(str ptr) CreateDirectory32A
+153 stdcall CreateDirectoryExA(str str ptr) CreateDirectoryEx32A
+154 stdcall CreateDirectoryExW(wstr wstr ptr) CreateDirectoryEx32W
+155 stdcall CreateDirectoryW(wstr ptr) CreateDirectory32W
+156 stdcall CreateEventA(ptr long long str) CreateEvent32A
+157 stdcall CreateEventW(ptr long long wstr) CreateEvent32W
+158 stdcall CreateFileA(str long long ptr long long long) CreateFile32A
+159 stdcall CreateFileMappingA(long ptr long long long str) CreateFileMapping32A
+160 stdcall CreateFileMappingW(long ptr long long long wstr) CreateFileMapping32W
+161 stdcall CreateFileW(wstr long long ptr long long long) CreateFile32W
 162 stub CreateIoCompletionPort
 163 stub CreateKernelThread
 164 stub CreateMailslotA
 165 stub CreateMailslotW
-166 stdcall CreateMutexA(ptr long ptr) CreateMutex32A
-167 stdcall CreateMutexW(ptr long ptr) CreateMutex32W
+166 stdcall CreateMutexA(ptr long str) CreateMutex32A
+167 stdcall CreateMutexW(ptr long wstr) CreateMutex32W
 168 stub CreateNamedPipeA
 169 stub CreateNamedPipeW
 170 stub CreatePipe
-171 stdcall CreateProcessA(ptr ptr ptr ptr long long ptr ptr ptr ptr) CreateProcess32A
+171 stdcall CreateProcessA(str str ptr ptr long long ptr str ptr ptr) CreateProcess32A
 172 stub CreateProcessW
 173 stub CreateRemoteThread
-174 stdcall CreateSemaphoreA(ptr long long ptr) CreateSemaphore32A
-175 stdcall CreateSemaphoreW(ptr long long ptr) CreateSemaphore32W
+174 stdcall CreateSemaphoreA(ptr long long str) CreateSemaphore32A
+175 stdcall CreateSemaphoreW(ptr long long wstr) CreateSemaphore32W
 176 stub CreateSocketHandle
 177 stub CreateTapePartition
 178 stdcall CreateThread(ptr long ptr long long ptr) CreateThread
@@ -174,8 +174,8 @@
 183 stub DefineDosDeviceW
 184 stdcall DeleteAtom(long) DeleteAtom32
 185 stdcall DeleteCriticalSection(ptr)	DeleteCriticalSection
-186 stdcall DeleteFileA(ptr) DeleteFile32A
-187 stdcall DeleteFileW(ptr) DeleteFile32W
+186 stdcall DeleteFileA(str) DeleteFile32A
+187 stdcall DeleteFileW(wstr) DeleteFile32W
 188 stub DeviceIoControl
 189 stdcall DisableThreadLibraryCalls(long) DisableThreadLibraryCalls
 190 stub DisconnectNamedPipe
@@ -188,10 +188,10 @@
 197 stub EnumCalendarInfoW
 198 stub EnumDateFormatsA
 199 stub EnumDateFormatsW
-200 stdcall EnumResourceLanguagesA(long ptr ptr ptr long) EnumResourceLanguages32A
-201 stdcall EnumResourceLanguagesW(long ptr ptr ptr long) EnumResourceLanguages32W
-202 stdcall EnumResourceNamesA(long ptr ptr long) EnumResourceNames32A
-203 stdcall EnumResourceNamesW(long ptr ptr long) EnumResourceNames32W
+200 stdcall EnumResourceLanguagesA(long str str ptr long) EnumResourceLanguages32A
+201 stdcall EnumResourceLanguagesW(long wstr wstr ptr long) EnumResourceLanguages32W
+202 stdcall EnumResourceNamesA(long str ptr long) EnumResourceNames32A
+203 stdcall EnumResourceNamesW(long wstr ptr long) EnumResourceNames32W
 204 stdcall EnumResourceTypesA(long ptr long) EnumResourceTypes32A
 205 stdcall EnumResourceTypesW(long ptr long) EnumResourceTypes32W
 206 stdcall EnumSystemCodePagesA(ptr long) EnumSystemCodePages32A
@@ -204,8 +204,8 @@
 213 stdcall EscapeCommFunction(long long) EscapeCommFunction32
 214 stdcall ExitProcess(long) ExitProcess
 215 stub ExitThread
-216 stdcall ExpandEnvironmentStringsA(ptr ptr long) ExpandEnvironmentStrings32A
-217 stdcall ExpandEnvironmentStringsW(ptr ptr long) ExpandEnvironmentStrings32W
+216 stdcall ExpandEnvironmentStringsA(str ptr long) ExpandEnvironmentStrings32A
+217 stdcall ExpandEnvironmentStringsW(wstr ptr long) ExpandEnvironmentStrings32W
 218 stub FT_Exit0
 219 stub FT_Exit12
 220 stub FT_Exit16
@@ -223,8 +223,8 @@
 232 stub FT_Exit8
 233 stub FT_Prolog
 234 stub FT_Thunk
-235 stdcall FatalAppExitA(long ptr) FatalAppExit32A
-236 stdcall FatalAppExitW(long ptr) FatalAppExit32W
+235 stdcall FatalAppExitA(long str) FatalAppExit32A
+236 stdcall FatalAppExitW(long wstr) FatalAppExit32W
 237 stub FatalExit
 238 stdcall FileTimeToDosDateTime(ptr ptr ptr) FileTimeToDosDateTime
 239 stdcall FileTimeToLocalFileTime(ptr ptr) FileTimeToLocalFileTime
@@ -232,21 +232,21 @@
 241 stub FillConsoleOutputAttribute
 242 stub FillConsoleOutputCharacterA
 243 stub FillConsoleOutputCharacterW
-244 stdcall FindAtomA(ptr) FindAtom32A
-245 stdcall FindAtomW(ptr) FindAtom32W
+244 stdcall FindAtomA(str) FindAtom32A
+245 stdcall FindAtomW(wstr) FindAtom32W
 247 stub FindCloseChangeNotification
 246 stdcall FindClose(long) FindClose32
 248 stub FindFirstChangeNotificationA
 249 stub FindFirstChangeNotificationW
-250 stdcall FindFirstFileA(ptr ptr) FindFirstFile32A
-251 stdcall FindFirstFileW(ptr ptr) FindFirstFile32W
+250 stdcall FindFirstFileA(str ptr) FindFirstFile32A
+251 stdcall FindFirstFileW(wstr ptr) FindFirstFile32W
 252 stub FindNextChangeNotification
 253 stdcall FindNextFileA(long ptr) FindNextFile32A
 254 stdcall FindNextFileW(long ptr) FindNextFile32W
-255 stdcall FindResourceA(long ptr ptr) FindResource32A
-256 stdcall FindResourceExA(long ptr ptr long) FindResourceEx32A
-257 stdcall FindResourceExW(long ptr ptr long) FindResourceEx32W
-258 stdcall FindResourceW(long ptr ptr) FindResource32W
+255 stdcall FindResourceA(long str str) FindResource32A
+256 stdcall FindResourceExA(long str str long) FindResourceEx32A
+257 stdcall FindResourceExW(long wstr wstr long) FindResourceEx32W
+258 stdcall FindResourceW(long wstr wstr) FindResource32W
 259 stdcall FlushConsoleInputBuffer(long) FlushConsoleInputBuffer
 260 stdcall FlushFileBuffers(long) FlushFileBuffers
 261 stub FlushInstructionCache
@@ -298,31 +298,31 @@
 307 stdcall GetCurrentProcessId() GetCurrentProcessId
 308 stdcall GetCurrentThread() GetCurrentThread
 309 stdcall GetCurrentThreadId() GetCurrentThreadId
-310 stub GetDateFormatA
+310 stdcall GetDateFormatA(long long ptr ptr ptr long) GetDateFormat32A
 311 stub GetDateFormatW
 312 stub GetDaylightFlag
 313 stub GetDefaultCommConfigA
 314 stub GetDefaultCommConfigW
-315 stdcall GetDiskFreeSpaceA(ptr ptr ptr ptr ptr) GetDiskFreeSpace32A
-316 stdcall GetDiskFreeSpaceW(ptr ptr ptr ptr ptr) GetDiskFreeSpace32W
-317 stdcall GetDriveTypeA(ptr) GetDriveType32A
-318 stdcall GetDriveTypeW(ptr) GetDriveType32W
+315 stdcall GetDiskFreeSpaceA(str ptr ptr ptr ptr) GetDiskFreeSpace32A
+316 stdcall GetDiskFreeSpaceW(wstr ptr ptr ptr ptr) GetDiskFreeSpace32W
+317 stdcall GetDriveTypeA(str) GetDriveType32A
+318 stdcall GetDriveTypeW(wstr) GetDriveType32W
 320 stdcall GetEnvironmentStringsA() GetEnvironmentStrings32A
 321 stdcall GetEnvironmentStringsW() GetEnvironmentStrings32W
 319 stdcall GetEnvironmentStrings() GetEnvironmentStrings32A
-322 stdcall GetEnvironmentVariableA(ptr ptr long) GetEnvironmentVariable32A
-323 stdcall GetEnvironmentVariableW(ptr ptr long) GetEnvironmentVariable32W
+322 stdcall GetEnvironmentVariableA(str ptr long) GetEnvironmentVariable32A
+323 stdcall GetEnvironmentVariableW(wstr ptr long) GetEnvironmentVariable32W
 324 stub GetErrorMode
 325 stub GetExitCodeProcess
 326 stdcall GetExitCodeThread(long ptr) GetExitCodeThread
-327 stdcall GetFileAttributesA(ptr) GetFileAttributes32A
-328 stdcall GetFileAttributesW(ptr) GetFileAttributes32W
+327 stdcall GetFileAttributesA(str) GetFileAttributes32A
+328 stdcall GetFileAttributesW(wstr) GetFileAttributes32W
 329 stdcall GetFileInformationByHandle(long ptr) GetFileInformationByHandle
 330 stdcall GetFileSize(long ptr) GetFileSize
 331 stdcall GetFileTime(long ptr ptr ptr) GetFileTime
 332 stdcall GetFileType(long) GetFileType
-333 stdcall GetFullPathNameA(ptr long ptr ptr) GetFullPathName32A
-334 stdcall GetFullPathNameW(ptr long ptr ptr) GetFullPathName32W
+333 stdcall GetFullPathNameA(str long ptr ptr) GetFullPathName32A
+334 stdcall GetFullPathNameW(wstr long ptr ptr) GetFullPathName32W
 335 stub GetHandleContext
 336 stub GetHandleInformation
 337 stub GetLSCallbackTarget
@@ -338,8 +338,8 @@
 347 stub GetMailslotInfo
 348 stdcall GetModuleFileNameA(long ptr long) GetModuleFileName32A
 349 stdcall GetModuleFileNameW(long ptr long) GetModuleFileName32W
-350 stdcall GetModuleHandleA(ptr) GetModuleHandle32A
-351 stdcall GetModuleHandleW(ptr) GetModuleHandle32W
+350 stdcall GetModuleHandleA(str) GetModuleHandle32A
+351 stdcall GetModuleHandleW(wstr) GetModuleHandle32W
 352 stub GetNamedPipeHandleStateA
 353 stub GetNamedPipeHandleStateW
 354 stub GetNamedPipeInfo
@@ -350,18 +350,18 @@
 359 stdcall GetOEMCP() GetOEMCP
 360 stub GetOverlappedResult
 361 stdcall GetPriorityClass(long) GetPriorityClass
-362 stdcall GetPrivateProfileIntA(ptr ptr long ptr) GetPrivateProfileInt32A
-363 stdcall GetPrivateProfileIntW(ptr ptr long ptr) GetPrivateProfileInt32W
-364 stdcall GetPrivateProfileSectionA(ptr ptr long ptr) GetPrivateProfileSection32A
+362 stdcall GetPrivateProfileIntA(str str long str) GetPrivateProfileInt32A
+363 stdcall GetPrivateProfileIntW(wstr wstr long wstr) GetPrivateProfileInt32W
+364 stdcall GetPrivateProfileSectionA(str str long str) GetPrivateProfileSection32A
 365 stub GetPrivateProfileSectionNamesA
 366 stub GetPrivateProfileSectionNamesW
 367 stub GetPrivateProfileSectionW
-368 stdcall GetPrivateProfileStringA(ptr ptr ptr ptr long ptr) GetPrivateProfileString32A
-369 stdcall GetPrivateProfileStringW(ptr ptr ptr ptr long ptr) GetPrivateProfileString32W
+368 stdcall GetPrivateProfileStringA(str str str ptr long str) GetPrivateProfileString32A
+369 stdcall GetPrivateProfileStringW(wstr wstr wstr ptr long wstr) GetPrivateProfileString32W
 370 stub GetPrivateProfileStructA
 371 stub GetPrivateProfileStructW
-372 stdcall GetProcAddress(long ptr) GetProcAddress32
-373 stdcall GetProcessAffinityMask(long ptr ptr)	GetProcessAffinityMask
+372 stdcall GetProcAddress(long str) GetProcAddress32
+373 stdcall GetProcessAffinityMask(long ptr ptr) GetProcessAffinityMask
 374 stub GetProcessFlags
 375 stdcall GetProcessHeap() GetProcessHeap
 376 stub GetProcessHeaps
@@ -370,24 +370,24 @@
 379 stdcall GetProcessVersion(long) GetProcessVersion
 380 stdcall GetProcessWorkingSetSize(long ptr ptr) GetProcessWorkingSetSize
 381 stub GetProductName
-382 stdcall GetProfileIntA(ptr ptr long) GetProfileInt32A
-383 stdcall GetProfileIntW(ptr ptr long) GetProfileInt32W
-384 stdcall GetProfileSectionA(ptr ptr long) GetProfileSection32A
+382 stdcall GetProfileIntA(str str long) GetProfileInt32A
+383 stdcall GetProfileIntW(wstr wstr long) GetProfileInt32W
+384 stdcall GetProfileSectionA(str str long) GetProfileSection32A
 385 stub GetProfileSectionW
-386 stdcall GetProfileStringA(ptr ptr ptr ptr long) GetProfileString32A
-387 stdcall GetProfileStringW(ptr ptr ptr ptr long) GetProfileString32W
+386 stdcall GetProfileStringA(str str str ptr long) GetProfileString32A
+387 stdcall GetProfileStringW(wstr wstr wstr ptr long) GetProfileString32W
 388 stub GetQueuedCompletionStatus
 389 stub GetSLCallbackTarget
 390 stub GetSLCallbackTemplate
-391 stdcall GetShortPathNameA(ptr ptr long) GetShortPathName32A
-392 stdcall GetShortPathNameW(ptr ptr long) GetShortPathName32W
+391 stdcall GetShortPathNameA(str ptr long) GetShortPathName32A
+392 stdcall GetShortPathNameW(wstr ptr long) GetShortPathName32W
 393 stdcall GetStartupInfoA(ptr) GetStartupInfo32A
 394 stdcall GetStartupInfoW(ptr) GetStartupInfo32W
 395 stdcall GetStdHandle(long)	GetStdHandle
-396 stdcall GetStringTypeA(long long ptr long ptr) GetStringType32A
-397 stdcall GetStringTypeExA(long long ptr long ptr) GetStringTypeEx32A
-398 stdcall GetStringTypeExW(long long ptr long ptr) GetStringTypeEx32W
-399 stdcall GetStringTypeW(long ptr long ptr) GetStringType32W
+396 stdcall GetStringTypeA(long long str long ptr) GetStringType32A
+397 stdcall GetStringTypeExA(long long str long ptr) GetStringTypeEx32A
+398 stdcall GetStringTypeExW(long long wstr long ptr) GetStringTypeEx32W
+399 stdcall GetStringTypeW(long wstr long ptr) GetStringType32W
 400 stdcall GetSystemDefaultLCID() GetSystemDefaultLCID
 401 stdcall GetSystemDefaultLangID() GetSystemDefaultLangID
 402 stdcall GetSystemDirectoryA(ptr long) GetSystemDirectory32A
@@ -400,8 +400,8 @@
 409 stub GetTapeParameters
 410 stub GetTapePosition
 411 stub GetTapeStatus
-412 stdcall GetTempFileNameA(ptr ptr long ptr) GetTempFileName32A
-413 stdcall GetTempFileNameW(ptr ptr long ptr) GetTempFileName32W
+412 stdcall GetTempFileNameA(str str long ptr) GetTempFileName32A
+413 stdcall GetTempFileNameW(wstr wstr long ptr) GetTempFileName32W
 414 stdcall GetTempPathA(long ptr) GetTempPath32A
 415 stdcall GetTempPathW(long ptr) GetTempPath32W
 416 stdcall GetThreadContext(long ptr) GetThreadContext
@@ -410,7 +410,7 @@
 419 stdcall GetThreadSelectorEntry(long long ptr) GetThreadSelectorEntry
 420 stub GetThreadTimes
 421 stdcall GetTickCount() GetTickCount
-422 stub GetTimeFormatA
+422 stdcall GetTimeFormatA(long long ptr str ptr long) GetTimeFormat32A
 423 stub GetTimeFormatW
 424 stdcall GetTimeZoneInformation(ptr) GetTimeZoneInformation
 425 stdcall GetUserDefaultLCID() GetUserDefaultLCID
@@ -418,17 +418,17 @@
 427 stdcall GetVersion() GetVersion32
 428 stdcall GetVersionExA(ptr) GetVersionEx32A
 429 stdcall GetVersionExW(ptr) GetVersionEx32W
-430 stdcall GetVolumeInformationA(ptr ptr long ptr ptr ptr ptr long) GetVolumeInformation32A
-431 stdcall GetVolumeInformationW(ptr ptr long ptr ptr ptr ptr long) GetVolumeInformation32W
+430 stdcall GetVolumeInformationA(str ptr long ptr ptr ptr ptr long) GetVolumeInformation32A
+431 stdcall GetVolumeInformationW(wstr ptr long ptr ptr ptr ptr long) GetVolumeInformation32W
 432 stdcall GetWindowsDirectoryA(ptr long) GetWindowsDirectory32A
 433 stdcall GetWindowsDirectoryW(ptr long) GetWindowsDirectory32W
-434 stdcall GlobalAddAtomA(ptr) GlobalAddAtom32A
-435 stdcall GlobalAddAtomW(ptr) GlobalAddAtom32W
+434 stdcall GlobalAddAtomA(str) GlobalAddAtom32A
+435 stdcall GlobalAddAtomW(wstr) GlobalAddAtom32W
 436 stdcall GlobalAlloc(long long) GlobalAlloc32
 437 stdcall GlobalCompact(long) GlobalCompact32
 438 stdcall GlobalDeleteAtom(long) GlobalDeleteAtom
-439 stdcall GlobalFindAtomA(ptr) GlobalFindAtom32A
-440 stdcall GlobalFindAtomW(ptr) GlobalFindAtom32W
+439 stdcall GlobalFindAtomA(str) GlobalFindAtom32A
+440 stdcall GlobalFindAtomW(wstr) GlobalFindAtom32W
 441 stdcall GlobalFix(long) GlobalFix32
 442 stdcall GlobalFlags(long) GlobalFlags32
 443 stdcall GlobalFree(long) GlobalFree32
@@ -480,14 +480,14 @@
 489 stdcall IsValidLocale(long long) IsValidLocale
 490 stub K32Thk1632Epilog
 491 stub K32Thk1632Prolog
-492 stdcall LCMapStringA(long long ptr long ptr long) LCMapString32A
-493 stdcall LCMapStringW(long long ptr long ptr long) LCMapString32W
+492 stdcall LCMapStringA(long long str long ptr long) LCMapString32A
+493 stdcall LCMapStringW(long long wstr long ptr long) LCMapString32W
 494 stdcall LeaveCriticalSection(ptr)	LeaveCriticalSection
-495 stdcall LoadLibraryA(ptr) LoadLibrary32A
-496 stdcall LoadLibraryExA(ptr long long) LoadLibraryEx32A
+495 stdcall LoadLibraryA(str) LoadLibrary32A
+496 stdcall LoadLibraryExA(str long long) LoadLibraryEx32A
 497 stub LoadLibraryExW
-498 stdcall LoadLibraryW(ptr) LoadLibrary32W
-499 stub LoadModule
+498 stdcall LoadLibraryW(wstr) LoadLibrary32W
+499 stdcall LoadModule(str ptr) LoadModule32
 500 stdcall LoadResource(long long) LoadResource32
 501 stdcall LocalAlloc(long long) LocalAlloc32
 502 stdcall LocalCompact(long) LocalCompact32
@@ -517,27 +517,27 @@
 526 stdcall MapViewOfFileEx(long long long long long ptr) MapViewOfFileEx
 527 stub Module32First
 528 stub Module32Next
-529 stdcall MoveFileA(ptr ptr) MoveFile32A
-530 stdcall MoveFileExA(ptr ptr long) MoveFileEx32A
-531 stdcall MoveFileExW(ptr ptr long) MoveFileEx32W
-532 stdcall MoveFileW(ptr ptr) MoveFile32W
+529 stdcall MoveFileA(str str) MoveFile32A
+530 stdcall MoveFileExA(str str long) MoveFileEx32A
+531 stdcall MoveFileExW(wstr wstr long) MoveFileEx32W
+532 stdcall MoveFileW(wstr wstr) MoveFile32W
 533 stdcall MulDiv(long long long) MulDiv32
-534 stdcall MultiByteToWideChar(long long ptr long ptr long) MultiByteToWideChar
+534 stdcall MultiByteToWideChar(long long str long ptr long) MultiByteToWideChar
 535 stub NotifyNLSUserCache
-536 stdcall OpenEventA(long long ptr) OpenEvent32A
-537 stdcall OpenEventW(long long ptr) OpenEvent32W
-538 stdcall OpenFile(ptr ptr long) OpenFile32
-539 stdcall OpenFileMappingA(long long ptr) OpenFileMapping32A
-540 stdcall OpenFileMappingW(long long ptr) OpenFileMapping32W
-541 stdcall OpenMutexA(long long ptr) OpenMutex32A
-542 stdcall OpenMutexW(long long ptr) OpenMutex32W
+536 stdcall OpenEventA(long long str) OpenEvent32A
+537 stdcall OpenEventW(long long wstr) OpenEvent32W
+538 stdcall OpenFile(str ptr long) OpenFile32
+539 stdcall OpenFileMappingA(long long str) OpenFileMapping32A
+540 stdcall OpenFileMappingW(long long wstr) OpenFileMapping32W
+541 stdcall OpenMutexA(long long str) OpenMutex32A
+542 stdcall OpenMutexW(long long wstr) OpenMutex32W
 543 stub OpenProcess
 544 stub OpenProfileUserMapping
-545 stdcall OpenSemaphoreA(long long ptr) OpenSemaphore32A
-546 stdcall OpenSemaphoreW(long long ptr) OpenSemaphore32W
+545 stdcall OpenSemaphoreA(long long str) OpenSemaphore32A
+546 stdcall OpenSemaphoreW(long long wstr) OpenSemaphore32W
 547 stub OpenVxDHandle
-548 stdcall OutputDebugStringA(ptr) OutputDebugString32A
-549 stdcall OutputDebugStringW(ptr) OutputDebugString32W
+548 stdcall OutputDebugStringA(str) OutputDebugString32A
+549 stdcall OutputDebugStringW(wstr) OutputDebugString32W
 550 stub PeekConsoleInputA
 551 stub PeekConsoleInputW
 552 stub PeekNamedPipe
@@ -548,8 +548,8 @@
 557 stub PulseEvent
 558 stdcall PurgeComm(long long) PurgeComm
 559 register QT_Thunk() QT_Thunk
-560 stdcall QueryDosDeviceA(ptr ptr long) QueryDosDevice32A
-561 stdcall QueryDosDeviceW(ptr ptr long) QueryDosDevice32W
+560 stdcall QueryDosDeviceA(str ptr long) QueryDosDevice32A
+561 stdcall QueryDosDeviceW(wstr ptr long) QueryDosDevice32W
 562 stub QueryNumberOfEventLogRecords
 563 stub QueryOldestEventLogRecord
 564 stdcall QueryPerformanceCounter(ptr) QueryPerformanceCounter
@@ -566,14 +566,14 @@
 575 stub ReadConsoleOutputW
 576 stdcall ReadConsoleW(long ptr long ptr ptr) ReadConsole32W
 577 stdcall ReadFile(long ptr long ptr ptr) ReadFile
-578 stub ReadFileEx
+578 stdcall ReadFileEx(long ptr long ptr ptr) ReadFileEx
 579 stdcall ReadProcessMemory(long ptr ptr long ptr) ReadProcessMemory
 580 stub RegisterServiceProcess
 581 stdcall ReinitializeCriticalSection(ptr) ReinitializeCriticalSection
 582 stdcall ReleaseMutex(long) ReleaseMutex
 583 stdcall ReleaseSemaphore(long long ptr) ReleaseSemaphore
-584 stdcall RemoveDirectoryA(ptr) RemoveDirectory32A
-585 stdcall RemoveDirectoryW(ptr) RemoveDirectory32W
+584 stdcall RemoveDirectoryA(str) RemoveDirectory32A
+585 stdcall RemoveDirectoryW(wstr) RemoveDirectory32W
 586 stdcall ResetEvent(long) ResetEvent
 587 stdcall ResumeThread(long) ResumeThread
 588 stdcall RtlFillMemory(ptr long long) RtlFillMemory
@@ -602,8 +602,8 @@
 611 register SUnMapLS_IP_EBP_8() SUnMapLS_IP_EBP_8
 612 stub ScrollConsoleScreenBufferA
 613 stub ScrollConsoleScreenBufferW
-614 stdcall SearchPathA(ptr ptr ptr long ptr ptr) SearchPath32A
-615 stdcall SearchPathW(ptr ptr ptr long ptr ptr) SearchPath32W
+614 stdcall SearchPathA(str str str long ptr ptr) SearchPath32A
+615 stdcall SearchPathW(wstr wstr wstr long ptr ptr) SearchPath32W
 616 stdcall SetCommBreak(long) SetCommBreak32
 617 stub SetCommConfig
 618 stdcall SetCommMask(long ptr) SetCommMask
@@ -620,23 +620,23 @@
 629 stub SetConsoleOutputCP
 630 stub SetConsoleScreenBufferSize
 631 stub SetConsoleTextAttribute
-632 stdcall SetConsoleTitleA(ptr) SetConsoleTitle32A
-633 stdcall SetConsoleTitleW(ptr) SetConsoleTitle32W
+632 stdcall SetConsoleTitleA(str) SetConsoleTitle32A
+633 stdcall SetConsoleTitleW(wstr) SetConsoleTitle32W
 634 stub SetConsoleWindowInfo
-635 stdcall SetCurrentDirectoryA(ptr) SetCurrentDirectory32A
-636 stdcall SetCurrentDirectoryW(ptr) SetCurrentDirectory32W
+635 stdcall SetCurrentDirectoryA(str) SetCurrentDirectory32A
+636 stdcall SetCurrentDirectoryW(wstr) SetCurrentDirectory32W
 637 stub SetDaylightFlag
 638 stub SetDefaultCommConfigA
 639 stub SetDefaultCommConfigW
 640 stdcall SetEndOfFile(long) SetEndOfFile
-641 stdcall SetEnvironmentVariableA(ptr ptr) SetEnvironmentVariable32A
-642 stdcall SetEnvironmentVariableW(ptr ptr) SetEnvironmentVariable32W
+641 stdcall SetEnvironmentVariableA(str str) SetEnvironmentVariable32A
+642 stdcall SetEnvironmentVariableW(wstr wstr) SetEnvironmentVariable32W
 643 stdcall SetErrorMode(long) SetErrorMode32
-644 stdcall	SetEvent(long) SetEvent
+644 stdcall SetEvent(long) SetEvent
 645 stdcall SetFileApisToANSI() SetFileApisToANSI
 646 stdcall SetFileApisToOEM() SetFileApisToOEM
-647 stdcall SetFileAttributesA(ptr long) SetFileAttributes32A
-648 stdcall SetFileAttributesW(ptr long) SetFileAttributes32W
+647 stdcall SetFileAttributesA(str long) SetFileAttributes32A
+648 stdcall SetFileAttributesW(wstr long) SetFileAttributes32W
 649 stdcall SetFilePointer(long long ptr long) SetFilePointer
 650 stdcall SetFileTime(long ptr ptr ptr) SetFileTime
 651 stub SetHandleContext
@@ -644,7 +644,7 @@
 653 stub SetHandleInformation
 654 stdcall SetLastError(long) SetLastError
 655 stub SetLocalTime
-656 stdcall SetLocaleInfoA(long long ptr) SetLocaleInfoA
+656 stdcall SetLocaleInfoA(long long str) SetLocaleInfoA
 657 stub SetLocaleInfoW
 658 stub SetMailslotInfo
 659 stub SetNamedPipeHandleState
@@ -676,7 +676,7 @@
 685 stdcall TerminateThread(long long) TerminateThread
 686 stub Thread32First
 687 stub Thread32Next
-688 stdcall ThunkConnect32(ptr ptr ptr ptr ptr ptr) ThunkConnect32
+688 stdcall ThunkConnect32(ptr str str str ptr ptr) ThunkConnect32
 689 stdcall TlsAlloc()	TlsAlloc
 690 stub TlsAllocInternal
 691 stdcall TlsFree(long) TlsFree
@@ -686,7 +686,7 @@
 695 stub Toolhelp32ReadProcessMemory
 696 stub TransactNamedPipe
 697 stdcall TransmitCommChar(long long) TransmitCommChar32
-698 stdcall UTRegister(long ptr ptr ptr ptr ptr ptr) UTRegister
+698 stdcall UTRegister(long str str str ptr ptr ptr) UTRegister
 699 stdcall UTUnRegister(long) UTUnRegister
 700 stdcall UnMapLS(long) UnMapLS
 701 stub UnMapSLFixArray
@@ -715,8 +715,8 @@
 724 stdcall WaitForSingleObjectEx(long long long) WaitForSingleObjectEx
 725 stub WaitNamedPipeA
 726 stub WaitNamedPipeW
-727 stdcall WideCharToMultiByte(long long ptr long ptr long ptr ptr)	WideCharToMultiByte
-728 stdcall WinExec(ptr long) WinExec32
+727 stdcall WideCharToMultiByte(long long wstr long ptr long ptr ptr)	WideCharToMultiByte
+728 stdcall WinExec(str long) WinExec32
 729 stdcall WriteConsoleA(long ptr long ptr ptr) WriteConsole32A
 730 stub WriteConsoleInputA
 731 stub WriteConsoleInputW
@@ -730,15 +730,15 @@
 739 stub WriteFileEx
 740 stub WritePrivateProfileSectionA
 741 stub WritePrivateProfileSectionW
-742 stdcall WritePrivateProfileStringA(ptr ptr ptr ptr) WritePrivateProfileString32A
-743 stdcall WritePrivateProfileStringW(ptr ptr ptr ptr) WritePrivateProfileString32W
+742 stdcall WritePrivateProfileStringA(str str str str) WritePrivateProfileString32A
+743 stdcall WritePrivateProfileStringW(wstr wstr wstr wstr) WritePrivateProfileString32W
 744 stub WritePrivateProfileStructA
 745 stub WritePrivateProfileStructW
 746 stub WriteProcessMemory
 747 stub WriteProfileSectionA
 748 stub WriteProfileSectionW
-749 stdcall WriteProfileStringA(ptr ptr ptr) WriteProfileString32A
-750 stdcall WriteProfileStringW(ptr ptr ptr) WriteProfileString32W
+749 stdcall WriteProfileStringA(str str str) WriteProfileString32A
+750 stdcall WriteProfileStringW(wstr wstr wstr) WriteProfileString32W
 751 stub WriteTapemark
 752 stub _DebugOut
 753 stub _DebugPrintf
@@ -751,24 +751,24 @@
 760 stdcall _lread(long ptr long) _lread32
 761 stdcall _lwrite(long ptr long) _lwrite32
 762 stub dprintf
-763 stdcall lstrcat(ptr ptr) lstrcat32A
-764 stdcall lstrcatA(ptr ptr) lstrcat32A
-765 stdcall lstrcatW(ptr ptr) lstrcat32W
-766 stdcall lstrcmp(ptr ptr) lstrcmp32A
-767 stdcall lstrcmpA(ptr ptr) lstrcmp32A
-768 stdcall lstrcmpW(ptr ptr) lstrcmp32W
-769 stdcall lstrcmpi(ptr ptr) lstrcmpi32A
-770 stdcall lstrcmpiA(ptr ptr) lstrcmpi32A
-771 stdcall lstrcmpiW(ptr ptr) lstrcmpi32W
-772 stdcall lstrcpy(ptr ptr) lstrcpy32A
-773 stdcall lstrcpyA(ptr ptr) lstrcpy32A
-774 stdcall lstrcpyW(ptr ptr) lstrcpy32W
-775 stdcall lstrcpyn(ptr ptr long) lstrcpyn32A
-776 stdcall lstrcpynA(ptr ptr long) lstrcpyn32A
-777 stdcall lstrcpynW(ptr ptr long) lstrcpyn32W
-778 stdcall lstrlen(ptr) lstrlen32A
-779 stdcall lstrlenA(ptr) lstrlen32A
-780 stdcall lstrlenW(ptr) lstrlen32W
+763 stdcall lstrcat(str str) lstrcat32A
+764 stdcall lstrcatA(str str) lstrcat32A
+765 stdcall lstrcatW(wstr wstr) lstrcat32W
+766 stdcall lstrcmp(str str) lstrcmp32A
+767 stdcall lstrcmpA(str str) lstrcmp32A
+768 stdcall lstrcmpW(wstr wstr) lstrcmp32W
+769 stdcall lstrcmpi(str str) lstrcmpi32A
+770 stdcall lstrcmpiA(str str) lstrcmpi32A
+771 stdcall lstrcmpiW(wstr wstr) lstrcmpi32W
+772 stdcall lstrcpy(ptr str) lstrcpy32A
+773 stdcall lstrcpyA(ptr str) lstrcpy32A
+774 stdcall lstrcpyW(ptr wstr) lstrcpy32W
+775 stdcall lstrcpyn(ptr str long) lstrcpyn32A
+776 stdcall lstrcpynA(ptr str long) lstrcpyn32A
+777 stdcall lstrcpynW(ptr wstr long) lstrcpyn32W
+778 stdcall lstrlen(str) lstrlen32A
+779 stdcall lstrlenA(str) lstrlen32A
+780 stdcall lstrlenW(wstr) lstrlen32W
 # 
 # Functions exported by kernel32.dll in NT 3.51
 # 
diff --git a/if1632/mmsystem.spec b/if1632/mmsystem.spec
index f23df57..c0178e1 100644
--- a/if1632/mmsystem.spec
+++ b/if1632/mmsystem.spec
@@ -3,14 +3,15 @@
 
 #1      pascal  MMSYSTEM_WEP(word word word ptr) MMSYSTEM_WEP
 2      pascal  SNDPLAYSOUND(ptr word) sndPlaySound
-5      pascal  MMSYSTEMGETVERSION() mmsystemGetVersion
+3      stub    PLAYSOUND
+5      pascal  mmsystemGetVersion() mmsystemGetVersion16
 6      pascal  DriverProc(long word word long long) DriverProc
+8      stub    WMMMIDIRUNONCE
 30     pascal16 OutputDebugStr(ptr) OutputDebugString16
-31     pascal  DriverCallback(long word word word long long long)
-               DriverCallback
-#32    pascal  STACKENTER
-#33    pascal  STACKLEAVE
-#34    pascal  MMDRVINSTALL
+31     pascal  DriverCallback(long word word word long long long) DriverCallback
+32     stub    STACKENTER
+33     stub    STACKLEAVE
+34     stub    MMDRVINSTALL
 101    pascal  JOYGETNUMDEVS() JoyGetNumDevs
 102    pascal  JOYGETDEVCAPS(word ptr word) JoyGetDevCaps
 103    pascal  JOYGETPOS(word ptr) JoyGetPos
@@ -19,75 +20,85 @@
 106    pascal  JOYSETCAPTURE(word word word word) JoySetCapture
 107    pascal  JOYSETTHRESHOLD(word word) JoySetThreshold
 109    pascal  JOYSETCALIBRATION(word) JoySetCalibration
-201    pascal  MIDIOUTGETNUMDEVS() midiOutGetNumDevs
-202    pascal  MIDIOUTGETDEVCAPS(word segptr word) midiOutGetDevCaps
-203    pascal  MIDIOUTGETERRORTEXT(word ptr word) midiOutGetErrorText
-204    pascal  MIDIOUTOPEN(ptr word ptr long long) midiOutOpen
-205    pascal  MIDIOUTCLOSE(word) midiOutClose
-206    pascal  MIDIOUTPREPAREHEADER(word segptr word) midiOutPrepareHeader
-207    pascal  MIDIOUTUNPREPAREHEADER(word segptr word) midiOutUnprepareHeader
-208    pascal  MIDIOUTSHORTMSG(word long) midiOutShortMsg
-209    pascal  MIDIOUTLONGMSG(word ptr word) midiOutLongMsg
-210    pascal  MIDIOUTRESET(word) midiOutReset
-211    pascal  MIDIOUTGETVOLUME(word segptr) midiOutGetVolume
-212    pascal  MIDIOUTSETVOLUME(word long) midiOutSetVolume
-213    pascal  MIDIOUTCACHEPATCHES(word word segptr word) midiOutCachePatches
-214    pascal  MIDIOUTCACHEDRUMPATCHES(word word segptr word) midiOutCacheDrumPatches
-215    pascal  MIDIOUTGETID(word ptr) midiOutGetID
-216    pascal  MIDIOUTMESSAGE(word word long long) midiOutMessage
-301    pascal  MIDIINGETNUMDEVS() midiInGetNumDevs
-302    pascal  MIDIINGETDEVCAPS(word segptr word) midiInGetDevCaps
-303    pascal  MIDIINGETERRORTEXT(word ptr word) midiInGetErrorText
-304    pascal  MIDIINOPEN(ptr word ptr long long long) midiInOpen
-305    pascal  MIDIINCLOSE(word) midiInClose
-306    pascal  MIDIINPREPAREHEADER(word segptr word) midiInPrepareHeader
-307    pascal  MIDIINUNPREPAREHEADER(word segptr word) midiInUnprepareHeader
-308    pascal  MIDIINADDBUFFER(word segptr word) midiInAddBuffer
-309    pascal  MIDIINSTART(word) midiInStart
-310    pascal  MIDIINSTOP(word) midiInStop
-311    pascal  MIDIINRESET(word) midiInReset
-312    pascal  MIDIINGETID(word ptr) midiInGetID
-313    pascal  MIDIINMESSAGE(word word long long) midiInMessage
-350    pascal  AUXGETNUMDEVS() auxGetNumDevs
-351    pascal  AUXGETDEVCAPS(word segptr word) auxGetDevCaps
-352    pascal  AUXGETVOLUME(word segptr) auxGetVolume
-353    pascal  AUXSETVOLUME(word long) auxSetVolume
-354    pascal  AUXOUTMESSAGE(word word long long) auxOutMessage
-401    pascal  WAVEOUTGETNUMDEVS() waveOutGetNumDevs
-402    pascal  WAVEOUTGETDEVCAPS(word segptr word) waveOutGetDevCaps
-403    pascal  WAVEOUTGETERRORTEXT(word ptr word) waveOutGetErrorText
-404    pascal  WAVEOUTOPEN(ptr word segptr long long long) waveOutOpen
-405    pascal  WAVEOUTCLOSE(word) waveOutClose
-406    pascal  WAVEOUTPREPAREHEADER(word segptr word) waveOutPrepareHeader
-407    pascal  WAVEOUTUNPREPAREHEADER(word segptr word) waveOutUnprepareHeader
-408    pascal  WAVEOUTWRITE(word segptr word) waveOutWrite
-409    pascal  WAVEOUTPAUSE(word) waveOutPause
-410    pascal  WAVEOUTRESTART(word) waveOutRestart
-411    pascal  WAVEOUTRESET(word) waveOutReset
-412    pascal  WAVEOUTGETPOSITION(word segptr word) waveOutGetPosition
-413    pascal  WAVEOUTGETPITCH(word ptr) waveOutGetPitch
-414    pascal  WAVEOUTSETPITCH(word long) waveOutSetPitch
-415    pascal  WAVEOUTGETVOLUME(word segptr) waveOutGetVolume
-416    pascal  WAVEOUTSETVOLUME(word long) waveOutSetVolume
-417    pascal  WAVEOUTGETPLAYBACKRATE(word ptr) waveOutGetPlaybackRate
-418    pascal  WAVEOUTSETPLAYBACKRATE(word long) waveOutSetPlaybackRate
-419    pascal  WAVEOUTBREAKLOOP(word) waveOutBreakLoop
-420    pascal  WAVEOUTGETID(word ptr) waveOutGetID
-421    pascal  WAVEOUTMESSAGE(word word long long) waveOutMessage
-501    pascal  WAVEINGETNUMDEVS() waveInGetNumDevs
-502    pascal  WAVEINGETDEVCAPS(word segptr word) waveInGetDevCaps
-503    pascal  WAVEINGETERRORTEXT(word ptr word) waveInGetErrorText
-504    pascal  WAVEINOPEN(ptr word segptr long long long) waveInOpen
-505    pascal  WAVEINCLOSE(word) waveInClose
-506    pascal  WAVEINPREPAREHEADER(word segptr word) waveInPrepareHeader
-507    pascal  WAVEINUNPREPAREHEADER(word segptr word) waveInUnprepareHeader
-508    pascal  WAVEINADDBUFFER(word segptr word) waveInAddBuffer
-509    pascal  WAVEINSTART(word) waveInStart
-510    pascal  WAVEINSTOP(word) waveInStop
-511    pascal  WAVEINRESET(word) waveInReset
-512    pascal  WAVEINGETPOSITION(word segptr word) waveInGetPosition
-513    pascal  WAVEINGETID(word ptr) waveInGetID
-514    pascal  WAVEINMESSAGE(word word long long) waveInMessage
+110    stub    JOYGETPOSEX
+111    stub    JOYCONFIGCHANGED
+201    pascal  midiOutGetNumDevs() midiOutGetNumDevs16
+202    pascal  midiOutGetDevCaps(word str word) midiOutGetDevCaps16
+203    pascal  midiOutGetErrorText(word ptr word) midiOutGetErrorText16
+204    pascal  midiOutOpen(ptr word long long long) midiOutOpen16
+205    pascal  midiOutClose(word) midiOutClose16
+206    pascal  midiOutPrepareHeader(word ptr word) midiOutPrepareHeader16
+207    pascal  midiOutUnprepareHeader(word ptr word) midiOutUnprepareHeader16
+208    pascal  midiOutShortMsg(word long) midiOutShortMsg16
+209    pascal  midiOutLongMsg(word ptr word) midiOutLongMsg16
+210    pascal  midiOutReset(word) midiOutReset16
+211    pascal  midiOutGetVolume(word ptr) midiOutGetVolume16
+212    pascal  midiOutSetVolume(word long) midiOutSetVolume16
+213    pascal  midiOutCachePatches(word word ptr word) midiOutCachePatches16
+214    pascal  midiOutCacheDrumPatches(word word ptr word) midiOutCacheDrumPatches16
+215    pascal  midiOutGetID(word ptr) midiOutGetID16
+216    pascal  midiOutMessage(word word long long) midiOutMessage16
+250    stub    MIDISTREAMPROPERTY
+251    stub    MIDISTREAMOPEN
+252    stub    MIDISTREAMCLOSE
+253    stub    MIDISTREAMPOSITION
+254    stub    MIDISTREAMOUT
+255    stub    MIDISTREAMPAUSE
+256    stub    MIDISTREAMRESTART
+257    stub    MIDISTREAMSTOP
+301    pascal  midiInGetNumDevs() midiInGetNumDevs16
+302    pascal  midiInGetDevCaps(word ptr word) midiInGetDevCaps16
+303    pascal  midiInGetErrorText(word ptr word) midiInGetErrorText16
+304    pascal  midiInOpen(ptr word ptr long long long) midiInOpen16
+305    pascal  midiInClose(word) midiInClose16
+306    pascal  midiInPrepareHeader(word ptr word) midiInPrepareHeader16
+307    pascal  midiInUnprepareHeader(word ptr word) midiInUnprepareHeader16
+308    pascal  midiInAddBuffer(word ptr word) midiInAddBuffer16
+309    pascal  midiInStart(word) midiInStart16
+310    pascal  midiInStop(word) midiInStop16
+311    pascal  midiInReset(word) midiInReset16
+312    pascal  midiInGetID(word ptr) midiInGetID16
+313    pascal  midiInMessage(word word long long) midiInMessage16
+350    pascal  auxGetNumDevs() auxGetNumDevs16
+351    pascal  auxGetDevCaps(word ptr word) auxGetDevCaps16
+352    pascal  auxGetVolume(word ptr) auxGetVolume16
+353    pascal  auxSetVolume(word long) auxSetVolume16
+354    pascal  auxOutMessage(word word long long) auxOutMessage16
+401    pascal  waveOutGetNumDevs() waveOutGetNumDevs16
+402    pascal  waveOutGetDevCaps(word ptr word) waveOutGetDevCaps16
+403    pascal  waveOutGetErrorText(word ptr word) waveOutGetErrorText16
+404    pascal  waveOutOpen(ptr word ptr long long long) waveOutOpen16
+405    pascal  waveOutClose(word) waveOutClose16
+406    pascal  waveOutPrepareHeader(word ptr word) waveOutPrepareHeader16
+407    pascal  waveOutUnprepareHeader(word ptr word) waveOutUnprepareHeader16
+408    pascal  waveOutWrite(word ptr word) waveOutWrite16
+409    pascal  waveOutPause(word) waveOutPause16
+410    pascal  waveOutRestart(word) waveOutRestart16
+411    pascal  waveOutReset(word) waveOutReset16
+412    pascal  waveOutGetPosition(word ptr word) waveOutGetPosition16
+413    pascal  waveOutGetPitch(word ptr) waveOutGetPitch16
+414    pascal  waveOutSetPitch(word long) waveOutSetPitch16
+415    pascal  waveOutGetVolume(word ptr) waveOutGetVolume16
+416    pascal  waveOutSetVolume(word long) waveOutSetVolume16
+417    pascal  waveOutGetPlaybackRate(word ptr) waveOutGetPlaybackRate16
+418    pascal  waveOutSetPlaybackRate(word long) waveOutSetPlaybackRate16
+419    pascal  waveOutBreakLoop(word) waveOutBreakLoop16
+420    pascal  waveOutGetID(word ptr) waveOutGetID16
+421    pascal  waveOutMessage(word word long long) waveOutMessage16
+501    pascal  waveInGetNumDevs() waveInGetNumDevs16
+502    pascal  waveInGetDevCaps(word ptr word) waveInGetDevCaps16
+503    pascal  waveInGetErrorText(word ptr word) waveInGetErrorText16
+504    pascal  waveInOpen(ptr word ptr long long long) waveInOpen16
+505    pascal  waveInClose(word) waveInClose16
+506    pascal  waveInPrepareHeader(word ptr word) waveInPrepareHeader16
+507    pascal  waveInUnprepareHeader(word ptr word) waveInUnprepareHeader16
+508    pascal  waveInAddBuffer(word ptr word) waveInAddBuffer16
+509    pascal  waveInStart(word) waveInStart16
+510    pascal  waveInStop(word) waveInStop16
+511    pascal  waveInReset(word) waveInReset16
+512    pascal  waveInGetPosition(word ptr word) waveInGetPosition16
+513    pascal  waveInGetID(word ptr) waveInGetID16
+514    pascal  waveInMessage(word word long long) waveInMessage16
 601    pascal  timeGetSystemTime(ptr word) timeGetSystemTime
 602    pascal  timeSetEvent(word word segptr long word) timeSetEvent
 603    pascal  timeKillEvent(word) timeKillEvent
@@ -98,18 +109,46 @@
 701    pascal  MCISENDCOMMAND(word word long long) mciSendCommand
 702    pascal  MCISENDSTRING(str ptr word word) mciSendString
 703    pascal  MCIGETDEVICEID(ptr) mciGetDeviceID
-706    pascal  MCIGETERRORSTRING(long ptr word) mciGetErrorString
-#900   pascal  MMTASKCREATE
-#902   pascal  MMTASKBLOCK
-#903   pascal  MMTASKSIGNAL
-#904   pascal  MMGETCURRENTTASK
-#905   pascal  MMTASKYIELD
+705    stub    MCILOADCOMMANDRESOURCE
+706    pascal  mciGetErrorString(long ptr word) mciGetErrorString16
+707    stub    MCISETDRIVERDATA
+708    stub    MCIGETDRIVERDATA
+710    stub    MCIDRIVERYIELD
+711    stub    MCIDRIVERNOTIFY
+712    stub    MCIEXECUTE
+713    stub    MCIFREECOMMANDRESOURCE
+714    stub    MCISETYIELDPROC
+715    stub    MCIGETDEVICEIDFROMELEMENTID
+716    stub    MCIGETYIELDPROC
+717    stub    MCIGETCREATORTASK
+800    pascal  mixerGetNumDevs() mixerGetNumDevs16
+801    pascal  mixerGetDevCaps(word ptr long) mixerGetDevCaps16
+802    pascal  mixerOpen(ptr word long long) mixerOpen16
+803    pascal  mixerClose(word) mixerClose16
+804    pascal  mixerMessage(word word long long) mixerMessage16
+805    pascal  mixerGetLineInfo(word ptr long) mixerGetLineInfo16
+806    pascal  mixerGetID(word) mixerGetID16
+807    pascal  mixerGetLineControls(word ptr long) mixerGetLineControls16
+808    pascal  mixerGetControlDetails(word ptr long) mixerGetControlDetails16
+809    pascal  mixerSetControlDetails(word ptr long) mixerSetControlDetails16
+900    stub    MMTASKCREATE
+902    stub    MMTASKBLOCK
+903    stub    MMTASKSIGNAL
+904    stub    MMGETCURRENTTASK
+905    stub    MMTASKYIELD
 1100   pascal  DRVOPEN(str str long) DrvOpen
 1101   pascal  DRVCLOSE(word long long) DrvClose
 1102   pascal  DRVSENDMESSAGE(word word long long) DrvSendMessage
 1103   pascal  DRVGETMODULEHANDLE(word) DrvGetModuleHandle
 1104   pascal  DRVDEFDRIVERPROC(long word word long long) DrvDefDriverProc
-1210   pascal  MMIOOPEN(ptr ptr long) mmioOpen
+1120   stub    MMTHREADCREATE
+1121   stub    MMTHREADSIGNAL
+1122   stub    MMTHREADBLOCK
+1123   stub    MMTHREADISCURRENT
+1124   stub    MMTHREADISVALID
+1125   stub    MMTHREADGETTASK
+1150   stub    MMSHOWMMCPLPROPERTYSHEET
+1210   pascal  mmioOpen(str ptr long) mmioOpen16
 1211   pascal  MMIOCLOSE(word word) mmioClose
 1212   pascal  MMIOREAD(word ptr long) mmioRead
 1213   pascal  MMIOWRITE(word ptr long) mmioWrite
@@ -119,12 +158,16 @@
 1217   pascal  MMIOSETBUFFER(word ptr long word) mmioSetBuffer
 1218   pascal  MMIOFLUSH(word word) mmioFlush
 1219   pascal  MMIOADVANCE(word ptr word) mmioAdvance
-1220   pascal  MMIOSTRINGTOFOURCC(ptr word) mmioStringToFOURCC
+1220   pascal  mmioStringToFOURCC(str word) mmioStringToFOURCC16
 1221   pascal  MMIOINSTALLIOPROC(long ptr long) mmioInstallIOProc16
 1222   pascal  MMIOSENDMESSAGE(word word long long) mmioSendMessage
 1223   pascal  MMIODESCEND(word ptr ptr word) mmioDescend
 1224   pascal  MMIOASCEND(word ptr word) mmioAscend
 1225   pascal  MMIOCREATECHUNK(word ptr word) mmioCreateChunk
 1226   pascal  MMIORENAME(ptr ptr ptr long) mmioRename
-
-
+#2000   stub    WINMMF_THUNKDATA16
+#2001   stub    RING3_DEVLOADER
+#2002   stub    WINMMTILEBUFFER
+#2003   stub    WINMMUNTILEBUFFER
+#2005   stub    MCIGETTHUNKTABLE
+#2006   stub    WINMMSL_THUNKDATA16
diff --git a/if1632/ntdll.spec b/if1632/ntdll.spec
index 3d71013..b8fd7f5 100644
--- a/if1632/ntdll.spec
+++ b/if1632/ntdll.spec
@@ -864,7 +864,7 @@
 861 stub _alloca_probe
 862 cdecl _chkstk() NTDLL_chkstk
 863 stub _fltused
-864 stub _ftol
+864 cdecl _ftol(double) CRTDLL__ftol
 865 stub _itoa
 866 stub _ltoa
 867 stub _memccpy
diff --git a/if1632/relay.c b/if1632/relay.c
index 2018c73..a49114d 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -9,10 +9,10 @@
 #include "windows.h"
 #include "winnt.h"
 #include "global.h"
+#include "heap.h"
 #include "module.h"
 #include "stackframe.h"
 #include "task.h"
-#include "xmalloc.h"
 #include "stddebug.h"
 /* #define DEBUG_RELAY */
 #include "debug.h"
@@ -53,8 +53,10 @@
     CALLTO16_RetAddr_regs=MAKELONG( (int)CALLTO16_Ret_regs-(int)CALLTO16_Start,
                                     codesel );
 
-    /* Initialize thunking */
+    /* Create built-in modules */
+    if (!BUILTIN_Init()) return FALSE;
 
+    /* Initialize thunking */
     return THUNK_Init();
 }
 
@@ -245,6 +247,7 @@
     int i, ret;
     char buffer[80];
     FARPROC32 func;
+    DWORD mask, typemask;
 
     int *args = &ret_addr;
     /* Relay addr is the return address for this function */
@@ -252,13 +255,23 @@
     WORD nb_args = *(WORD *)(relay_addr + 1) / sizeof(int);
 
     assert(debugging_relay);
-    func = BUILTIN_GetEntryPoint32( buffer, relay_addr - 5 );
+    func = BUILTIN_GetEntryPoint32( buffer, relay_addr - 5, &typemask );
     printf( "Call %s(", buffer );
     args++;
-    for (i = 0; i < nb_args; i++)
+    for (i = 0, mask = 3; i < nb_args; i++, mask <<= 2)
     {
         if (i) printf( "," );
-        printf( "%08x", args[i] );
+	if ((typemask & mask) && HIWORD(args[i]))
+        {
+	    if (typemask & (2<<(2*i)))
+            {
+                char buff[80];
+                lstrcpynWtoA( buff, (LPWSTR)args[i], sizeof(buff) );
+	    	printf( "%08x L\"%s\"", args[i], buff );
+	    }
+            else printf( "%08x \"%s\"", args[i], (char *)args[i] );
+	}
+        else printf( "%08x", args[i] );
     }
     printf( ") ret=%08x\n", ret_addr );
     if (*relay_addr == 0xc3) /* cdecl */
@@ -371,14 +384,16 @@
     else
     {
         char buffer[80];
+        DWORD typemask;
 
+    	__RESTORE_ES;
         /* Fixup the context structure because of the extra parameter */
         /* pushed by the relay debugging code */
 
         EIP_reg(&context) = ret_addr;
         ESP_reg(&context) += sizeof(int);
 
-        BUILTIN_GetEntryPoint32( buffer, relay_addr - 5 );
+        BUILTIN_GetEntryPoint32( buffer, relay_addr - 5, &typemask );
         printf("Call %s(regs) ret=%08x\n", buffer, ret_addr );
         printf(" EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx ESI=%08lx EDI=%08lx\n",
                 EAX_reg(&context), EBX_reg(&context), ECX_reg(&context),
@@ -524,8 +539,9 @@
         argconvmask = VA_ARG16( valist, DWORD );
         proc32      = VA_ARG16( valist, FARPROC32 );
 	fprintf(stderr,"CallProc32W(%ld,%ld,%p,args[",nrofargs,argconvmask,proc32);
-	args = (DWORD*)xmalloc(sizeof(DWORD)*nrofargs);
-	for (i=nrofargs;i--;) {
+	args = (DWORD*)HEAP_xalloc( GetProcessHeap(), 0,
+                                    sizeof(DWORD)*nrofargs );
+	for (i=0;i<nrofargs;i++) {
 		if (argconvmask & (1<<i))
                 {
                     SEGPTR ptr = VA_ARG16( valist, SEGPTR );
@@ -568,6 +584,6 @@
         STACK16_POP( (3 + nrofargs) * sizeof(DWORD) );
 
 	fprintf(stderr,"returns %08lx\n",ret);
-	free(args);
+	HeapFree( GetProcessHeap(), 0, args );
 	return ret;
 }
diff --git a/if1632/shell32.spec b/if1632/shell32.spec
index d538fbf..a064b46 100644
--- a/if1632/shell32.spec
+++ b/if1632/shell32.spec
@@ -39,7 +39,7 @@
  101 stub ExtractAssociatedIconExA
  124 stub ExtractAssociatedIconExW
  125 stub ExtractAssociatedIconW
- 133 stub ExtractIconA
+ 133 stdcall ExtractIconA(long ptr long) ExtractIcon32A
  135 stub ExtractIconEx
  138 stub ExtractIconExA
  148 stub ExtractIconResInfoA
diff --git a/if1632/system.spec b/if1632/system.spec
index 311643b..62ba8e6 100644
--- a/if1632/system.spec
+++ b/if1632/system.spec
@@ -2,8 +2,8 @@
 type	win16
 
 1 pascal   InquireSystem(word word) InquireSystem
-2 pascal16 CreateSystemTimer(word segptr) THUNK_CreateSystemTimer
-3 pascal16 KillSystemTimer(word) THUNK_KillSystemTimer
+2 pascal16 CreateSystemTimer(word segptr) CreateSystemTimer
+3 pascal16 KillSystemTimer(word) SYSTEM_KillSystemTimer
 4 pascal16 EnableSystemTimers() EnableSystemTimers
 5 pascal16 DisableSystemTimers() DisableSystemTimers
 6 pascal   GetSystemMSecCount() GetTickCount
diff --git a/if1632/thunk.c b/if1632/thunk.c
index 088ecbc..0502f28 100644
--- a/if1632/thunk.c
+++ b/if1632/thunk.c
@@ -1,7 +1,7 @@
 /*
  * Emulator and Win95 thunks
  *
- * Copyright 1996 Alexandre Julliard
+ * Copyright 1996, 1997 Alexandre Julliard
  * Copyright 1997 Marcus Meissner
  */
 
@@ -13,7 +13,6 @@
 #include "heap.h"
 #include "hook.h"
 #include "module.h"
-#include "winproc.h"
 #include "stackframe.h"
 #include "selectors.h"
 #include "task.h"
@@ -22,6 +21,46 @@
 #include "stddebug.h"
 #include "debug.h"
 
+
+/* List of the 16-bit callback functions. This list is used  */
+/* by the build program to generate the file if1632/callto16.S */
+
+/* ### start build ### */
+extern LONG CALLBACK CallTo16_regs_short(const CONTEXT *context, INT32 offset);
+extern LONG CALLBACK CallTo16_regs_long (const CONTEXT *context, INT32 offset);
+extern WORD CALLBACK CallTo16_word_     (FARPROC16);
+extern WORD CALLBACK CallTo16_word_w    (FARPROC16,WORD);
+extern LONG CALLBACK CallTo16_long_l    (FARPROC16,LONG);
+extern WORD CALLBACK CallTo16_word_ww   (FARPROC16,WORD,WORD);
+extern WORD CALLBACK CallTo16_word_wl   (FARPROC16,WORD,LONG);
+extern WORD CALLBACK CallTo16_word_ll   (FARPROC16,LONG,LONG);
+extern WORD CALLBACK CallTo16_word_www  (FARPROC16,WORD,WORD,WORD);
+extern WORD CALLBACK CallTo16_word_wwl  (FARPROC16,WORD,WORD,LONG);
+extern WORD CALLBACK CallTo16_word_wlw  (FARPROC16,WORD,LONG,WORD);
+extern LONG CALLBACK CallTo16_long_wwl  (FARPROC16,WORD,WORD,LONG);
+extern WORD CALLBACK CallTo16_word_llwl (FARPROC16,LONG,LONG,WORD,LONG);
+extern WORD CALLBACK CallTo16_word_lwll (FARPROC16,LONG,WORD,LONG,LONG);
+extern WORD CALLBACK CallTo16_word_lwww (FARPROC16,LONG,WORD,WORD,WORD);
+extern WORD CALLBACK CallTo16_word_wwll (FARPROC16,WORD,WORD,LONG,LONG);
+extern WORD CALLBACK CallTo16_word_wllwl(FARPROC16,WORD,LONG,LONG,WORD,LONG);
+extern LONG CALLBACK CallTo16_long_lwwll(FARPROC16,LONG,WORD,WORD,LONG,LONG);
+extern WORD CALLBACK CallTo16_word_wwlll(FARPROC16,WORD,WORD,LONG,LONG,LONG);
+extern WORD CALLBACK CallTo16_word_wwwww(FARPROC16,WORD,WORD,WORD,WORD,WORD);
+extern WORD CALLBACK CallTo16_word_lwlll(FARPROC16,LONG,WORD,LONG,LONG,LONG);
+extern WORD CALLBACK CallTo16_word_llll (FARPROC16,LONG,LONG,LONG,LONG);
+extern LONG CALLBACK CallTo16_long_lwlll(FARPROC16,LONG,WORD,LONG,LONG,LONG);
+extern LONG CALLBACK CallTo16_word_lwwlllll(FARPROC16,LONG,WORD,WORD,LONG,LONG,
+                                            LONG,LONG,WORD);
+extern LONG CALLBACK CallTo16_long_lwwllwlllllw(FARPROC16,LONG,WORD,WORD,LONG,
+                                                LONG,WORD,LONG,LONG,LONG,LONG,
+                                                LONG,WORD);
+extern LONG CALLBACK CallTo16_word_lwwwwlwwwwllll(FARPROC16,LONG,WORD,WORD,
+                                                  WORD,WORD,LONG,WORD,WORD,
+                                                  WORD,WORD,LONG,LONG,LONG,
+                                                  LONG);
+/* ### stop build ### */
+
+
 typedef void (*RELAY)();
 
 #pragma pack(1)
@@ -46,8 +85,39 @@
 
 static THUNK *firstThunk = NULL;
 
-static LRESULT THUNK_CallWndProc16( WNDPROC16 proc, HWND16 hwnd, UINT16 msg,
-                                    WPARAM16 wParam, LPARAM lParam );
+static LRESULT WINAPI THUNK_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
+                                           UINT16 msg, WPARAM16 wParam,
+                                           LPARAM lParam );
+static void WINAPI THUNK_CallTaskReschedule(void);
+
+/* TASK_Reschedule() 16-bit entry point */
+static FARPROC16 TASK_RescheduleProc;
+
+/* Callbacks function table for the emulator */
+static const CALLBACKS_TABLE CALLBACK_EmulatorTable =
+{
+    (void *)CallTo16_regs_short,           /* CallRegisterProc */
+    THUNK_CallTaskReschedule,              /* CallTaskRescheduleProc */
+    THUNK_CallWndProc16,                   /* CallWndProc */
+    (void *)CallTo16_long_lwwll,           /* CallDriverProc */
+    (void *)CallTo16_word_wwlll,           /* CallDriverCallback */
+    (void *)CallTo16_word_wwlll,           /* CallTimeFuncProc */
+    (void *)CallTo16_word_w,               /* CallWindowsExitProc */
+    (void *)CallTo16_word_lwww,            /* CallWordBreakProc */
+    (void *)CallTo16_word_ww,              /* CallBootAppProc */
+    (void *)CallTo16_word_www,             /* CallLoadAppSegProc */
+    (void *)CallTo16_word_,                /* CallSystemTimerProc */
+    (void *)CallTo16_long_l,               /* CallASPIPostProc */
+    (void *)CallTo16_word_lwll,            /* CallDrvControlProc */
+    (void *)CallTo16_word_lwlll,           /* CallDrvEnableProc */
+    (void *)CallTo16_word_llll,            /* CallDrvEnumDFontsProc */
+    (void *)CallTo16_word_lwll,            /* CallDrvEnumObjProc */
+    (void *)CallTo16_word_lwwlllll,        /* CallDrvOutputProc */
+    (void *)CallTo16_long_lwlll,           /* CallDrvRealizeProc */
+    (void *)CallTo16_word_lwwwwlwwwwllll,  /* CallDrvStretchBltProc */
+    (void *)CallTo16_long_lwwllwlllllw     /* CallDrvExtTextOutProc */
+};
+
 
 /***********************************************************************
  *           THUNK_Init
@@ -55,7 +125,9 @@
 BOOL32 THUNK_Init(void)
 {
     /* Set the window proc calling functions */
-    WINPROC_SetCallWndProc16( THUNK_CallWndProc16 );
+    Callbacks = &CALLBACK_EmulatorTable;
+    /* Get the 16-bit reschedule function pointer */
+    TASK_RescheduleProc = MODULE_GetWndProcEntry16( "TASK_Reschedule" );
     return TRUE;
 }
 
@@ -117,8 +189,9 @@
  *
  * Call a 16-bit window procedure
  */
-static LRESULT THUNK_CallWndProc16( WNDPROC16 proc, HWND16 hwnd, UINT16 msg,
-                                    WPARAM16 wParam, LPARAM lParam )
+static LRESULT WINAPI THUNK_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
+                                           UINT16 msg, WPARAM16 wParam,
+                                           LPARAM lParam )
 {
     CONTEXT context;
     LRESULT ret;
@@ -154,13 +227,22 @@
     args[4] = hwnd;
     /* args[5] and args[6] are used by relay code to store the stack pointer */
 
-    ret = CallTo16_regs_( &context, -(5 * sizeof(WORD)) );
+    ret = CallTo16_regs_short( &context, -(5 * sizeof(WORD)) );
     if (offset) STACK16_POP(offset);
     return ret;
 }
 
 
 /***********************************************************************
+ *           THUNK_CallTaskReschedule
+ */
+static void WINAPI THUNK_CallTaskReschedule(void)
+{
+    CallTo16_word_(TASK_RescheduleProc);
+}
+
+
+/***********************************************************************
  *           THUNK_EnumObjects16   (GDI.71)
  */
 INT16 WINAPI THUNK_EnumObjects16( HDC16 hdc, INT16 nObjType,
@@ -337,31 +419,6 @@
 }
 
 
-/***********************************************************************
- *           THUNK_CreateSystemTimer   (SYSTEM.2)
- */
-WORD WINAPI THUNK_CreateSystemTimer( WORD rate, FARPROC16 callback )
-{
-    THUNK *thunk = THUNK_Alloc( callback, (RELAY)CallTo16_word_ );
-    if (!thunk) return 0;
-    return CreateSystemTimer( rate, (FARPROC16)thunk );
-}
-
-
-/***********************************************************************
- *           THUNK_KillSystemTimer   (SYSTEM.3)
- */
-WORD WINAPI THUNK_KillSystemTimer( WORD timer )
-{
-    extern WORD SYSTEM_KillSystemTimer( WORD timer );  /* misc/system.c */
-    extern FARPROC16 SYSTEM_GetTimerProc( WORD timer );  /* misc/system.c */
-
-    THUNK *thunk = (THUNK *)SYSTEM_GetTimerProc( timer );
-    WORD ret = SYSTEM_KillSystemTimer( timer );
-    if (thunk) THUNK_Free( thunk );
-    return ret;
-}
-
 
 static FARPROC16 defDCHookProc = NULL;
 
@@ -512,10 +569,10 @@
  *  68xxxxxxxx		    push FT_Prolog
  *  C3			    lret
  */
-static void _write_ftprolog(LPBYTE start,DWORD thunkstart) {
+static void _write_ftprolog(LPBYTE thunk,DWORD thunkstart) {
 	LPBYTE	x;
 
-	x	= start;
+	x	= thunk;
 	*x++	= 0x0f;*x++=0xb6;*x++=0xd1; /* movzbl edx,cl */
 	*x++	= 0x8B;*x++=0x14;*x++=0x95;*(DWORD*)x= thunkstart;
 	x+=4;	/* mov edx, [4*edx + thunkstart] */
@@ -526,6 +583,13 @@
 }
 
 /***********************************************************************
+ *			FT_PrologPrime			(KERNEL32.89)
+ */
+void WINAPI FT_PrologPrime(DWORD startind,LPBYTE thunk) {
+	_write_ftprolog(thunk,*(DWORD*)(startind+thunk));
+}
+
+/***********************************************************************
  * Generates a QT_Thunk style call.
  *	
  *  33C9                    xor ecx, ecx
@@ -623,39 +687,31 @@
 
 
 /**********************************************************************
- * The infamous and undocumented QT_Thunk procedure.
+ * 		QT_Thunk			(KERNEL32)
  *
- * We get arguments in [EBP+8] up to [EBP+38].
- * We have to set up a frame in the 16 bit stackframe.
- *	saved_ss_sp:	bp+0x40
- *			bp+0x3c
- *			...
- *		bp:	bp+0x00
- *		sp:	
- *		
+ * The target address is in EDX.
+ * The 16 bit arguments start at ESP+4.
+ * The number of 16bit argumentbytes is EBP-ESP-0x44 (68 Byte thunksetup).
+ * [ok]
  */
 VOID WINAPI QT_Thunk(CONTEXT *context)
 {
 	CONTEXT	context16;
-	LPBYTE	curstack;
-	DWORD	ret;
+	DWORD	argsize;
 
-	fprintf(stderr,"QT_Thunk(%08lx) ..",EDX_reg(context));
-	fprintf(stderr,"	argsize probably ebp-esp=%ld\n",
-		EBP_reg(context)-ESP_reg(context)
-	);
 	memcpy(&context16,context,sizeof(context16));
 
-	curstack = (LPBYTE)CURRENT_STACK16;
-	memcpy(curstack-0x44,(LPBYTE)EBP_reg(context),0x40);
-	EBP_reg(&context16)	 = LOWORD(IF1632_Saved16_ss_sp)-0x40;
 	CS_reg(&context16)	 = HIWORD(EDX_reg(context));
 	IP_reg(&context16)	 = LOWORD(EDX_reg(context));
-#ifndef WINELIB
-	ret = CallTo16_regs_(&context16,-0x40);
-#endif
-	fprintf(stderr,". returned %08lx\n",ret);
-	EAX_reg(context) 	 = ret;
+
+	argsize = EBP_reg(context)-ESP_reg(context)-0x44;
+
+	/* additional 4 bytes used by the relaycode for storing the stackptr */
+	memcpy(	((LPBYTE)CURRENT_STACK16)-argsize-4,
+		(LPBYTE)ESP_reg(context)+4,
+		argsize
+	);
+	EAX_reg(context) = CallTo16_regs_short(&context16,-argsize);
 }
 
 
@@ -674,22 +730,15 @@
 /***********************************************************************
  *           _KERNEL32_52    (KERNEL32.52)
  * Returns a pointer to ThkBuf in the 16bit library SYSTHUNK.DLL.
+ * [ok probably]
  */
 LPVOID WINAPI _KERNEL32_52()
 {
 	HMODULE32	hmod = LoadLibrary16("systhunk.dll");
-	DWORD		ret;
 
-	fprintf(stderr,"_KERNE32_52()\n");
 	if (hmod<=32)
 		return 0;
-
-	ret = (DWORD)WIN32_GetProcAddress16(hmod,"ThkBuf");
-
-	fprintf(stderr,"	GetProcAddress16(0x%04x,\"ThkBuf\") returns %08lx\n",
-			hmod,ret
-	);
-	return PTR_SEG_TO_LIN(ret);
+	return PTR_SEG_TO_LIN(WIN32_GetProcAddress16(hmod,"ThkBuf"));
 }
 
 /***********************************************************************
@@ -701,6 +750,7 @@
  *	04: SEGPTR	ptr		? where does it point to?
  * The pointer ptr is written into the first DWORD of 'thunk'.
  * (probably correct implemented)
+ * [ok probably]
  */
 DWORD WINAPI _KERNEL32_43(LPDWORD thunk,LPCSTR thkbuf,DWORD len,
                            LPCSTR dll16,LPCSTR dll32)
@@ -709,36 +759,34 @@
 	LPDWORD		addr;
 	SEGPTR		segaddr;
 
-	fprintf(stderr,"_KERNEL32_43(%p,%s,0x%08lx,%s,%s)\n",thunk,thkbuf,len,dll16,dll32);
-
 	hmod = LoadLibrary16(dll16);
 	if (hmod<32) {
-		fprintf(stderr,"->failed to load 16bit DLL %s, error %d\n",dll16,hmod);
+		fprintf(stderr,"KERNEL32_43->failed to load 16bit DLL %s, error %d\n",dll16,hmod);
 		return 0;
 	}
 	segaddr = (DWORD)WIN32_GetProcAddress16(hmod,(LPSTR)thkbuf);
 	if (!segaddr) {
-		fprintf(stderr,"->no %s exported from %s!\n",thkbuf,dll16);
+		fprintf(stderr,"KERNEL32_43->no %s exported from %s!\n",thkbuf,dll16);
 		return 0;
 	}
 	addr = (LPDWORD)PTR_SEG_TO_LIN(segaddr);
 	if (addr[0] != len) {
-		fprintf(stderr,"->thkbuf length mismatch? %ld vs %ld\n",len,addr[0]);
+		fprintf(stderr,"KERNEL32_43->thkbuf length mismatch? %ld vs %ld\n",len,addr[0]);
 		return 0;
 	}
 	if (!addr[1])
 		return 0;
-	fprintf(stderr,"	addr[1] is %08lx\n",addr[1]);
 	*(DWORD*)thunk = addr[1];
 	return addr[1];
 }
 
 /***********************************************************************
  * 		_KERNEL32_45 	(KERNEL32.44)
- * Looks like another 32->16 thunk. Dunno why they need two of them.
- * calls the win16 address in EAX with the current stack.
+ * Another 32->16 thunk, the difference to QT_Thunk is, that the called routine
+ * uses 0x66 lret, and that we have to pass CX in DI.
+ * (there seems to be some kind of BL/BX return magic too...)
  *
- * FIXME: doesn't seem to work correctly yet...
+ * [doesn't crash anymore]
  */
 VOID WINAPI _KERNEL32_45(CONTEXT *context)
 {
@@ -754,25 +802,55 @@
 
 	memcpy(&context16,context,sizeof(context16));
 
-	curstack = (LPBYTE)CURRENT_STACK16;
-	memcpy(curstack-stacksize-4,(LPBYTE)EBP_reg(context),stacksize);
-	fprintf(stderr,"IF1632_Saved16_ss_sp is 0x%08lx\n",IF1632_Saved16_ss_sp);
-	EBP_reg(&context16)	 = LOWORD(IF1632_Saved16_ss_sp)-stacksize;
 	DI_reg(&context16)	 = CX_reg(context);
 	CS_reg(&context16)	 = HIWORD(EAX_reg(context));
 	IP_reg(&context16)	 = LOWORD(EAX_reg(context));
-	/* some more registers spronged locally, but I don't think they are
-	 * needed
-	 */
-#ifndef WINELIB
-	ret = CallTo16_regs_(&context16,-stacksize);
-#endif
+
+	curstack = PTR_SEG_TO_LIN(STACK16_PUSH(stacksize));
+	memcpy(curstack-stacksize,(LPBYTE)ESP_reg(context),stacksize);
+	ret = CallTo16_regs_long(&context16,0);
+	STACK16_POP(stacksize);
+
 	fprintf(stderr,". returned %08lx\n",ret);
 	EAX_reg(context) 	 = ret;
 }
 
 /***********************************************************************
- *		(KERNEL32.40)
+ * 		_KERNEL32_40 	(KERNEL32.40)
+ * YET Another 32->16 thunk, the difference to the others is still mysterious
+ * target address is EDX
+ *
+ * [crashes]
+ */
+VOID WINAPI _KERNEL32_40(CONTEXT *context)
+{
+	CONTEXT	context16;
+	LPBYTE	curstack;
+	DWORD	ret,stacksize;
+
+	fprintf(stderr,"_KERNEL32_40(EDX=0x%08lx)\n",
+		EDX_reg(context)
+	);
+	stacksize = EBP_reg(context)-ESP_reg(context);
+	fprintf(stderr,"	stacksize = %ld\n",stacksize);
+	fprintf(stderr,"on top of stack: 0x%04x\n",*(WORD*)ESP_reg(context));
+
+	memcpy(&context16,context,sizeof(context16));
+
+	CS_reg(&context16)	 = HIWORD(EDX_reg(context));
+	IP_reg(&context16)	 = LOWORD(EDX_reg(context));
+
+	curstack = PTR_SEG_TO_LIN(STACK16_PUSH(stacksize));
+	memcpy(curstack-stacksize,(LPBYTE)ESP_reg(context),stacksize);
+	ret = CallTo16_regs_short(&context16,0);
+	STACK16_POP(stacksize);
+
+	fprintf(stderr,". returned %08lx\n",ret);
+	EAX_reg(context) 	 = ret;
+}
+
+/***********************************************************************
+ *		(KERNEL32.41)
  * A thunk setup routine.
  * Expects a pointer to a preinitialized thunkbuffer in the first argument
  * looking like:
@@ -805,7 +883,7 @@
  *	00: DWORD	length		? don't know exactly
  *	04: SEGPTR	ptr		? where does it point to?
  * The segpointer ptr is written into the first DWORD of 'thunk'.
- * (probably correct implemented)
+ * [ok probably]
  */
 
 LPVOID WINAPI _KERNEL32_41(LPBYTE thunk,LPCSTR thkbuf,DWORD len,LPCSTR dll16,
@@ -816,10 +894,6 @@
 	LPDWORD		addr,addr2;
 	DWORD		segaddr;
 
-	fprintf(stderr,"KERNEL32_41(%p,%s,%ld,%s,%s)\n",
-		thunk,thkbuf,len,dll16,dll32
-	);
-
 	/* FIXME: add checks for valid code ... */
 	/* write pointers to kernel32.89 and kernel32.90 (+ordinal base of 1) */
 	*(DWORD*)(thunk+0x35) = (DWORD)GetProcAddress32(hkrnl32,(LPSTR)90);
@@ -828,39 +902,34 @@
 	
 	hmod = LoadLibrary16(dll16);
 	if (hmod<32) {
-		fprintf(stderr,"->failed to load 16bit DLL %s, error %d\n",dll16,hmod);
+		fprintf(stderr,"KERNEL32_41->failed to load 16bit DLL %s, error %d\n",dll16,hmod);
 		return NULL;
 	}
 	segaddr = (DWORD)WIN32_GetProcAddress16(hmod,(LPSTR)thkbuf);
 	if (!segaddr) {
-		fprintf(stderr,"->no %s exported from %s!\n",thkbuf,dll16);
+		fprintf(stderr,"KERNEL32_41->no %s exported from %s!\n",thkbuf,dll16);
 		return NULL;
 	}
 	addr = (LPDWORD)PTR_SEG_TO_LIN(segaddr);
 	if (addr[0] != len) {
-		fprintf(stderr,"->thkbuf length mismatch? %ld vs %ld\n",len,addr[0]);
+		fprintf(stderr,"KERNEL32_41->thkbuf length mismatch? %ld vs %ld\n",len,addr[0]);
 		return NULL;
 	}
 	addr2 = PTR_SEG_TO_LIN(addr[1]);
-	fprintf(stderr,"	addr2 is %08lx:%p\n",addr[1],addr2);
 	if (HIWORD(addr2))
 		*(DWORD*)thunk = (DWORD)addr2;
 	return addr2;
 }
 
 /***********************************************************************
- *							(KERNEL32.91)
- * Thunk priming? function
+ *							(KERNEL32.90)
+ * QT Thunk priming function
  * Rewrites the first part of the thunk to use the QT_Thunk interface
  * and jumps to the start of that code.
+ * [ok]
  */
 VOID WINAPI _KERNEL32_90(CONTEXT *context)
 {
-	fprintf(stderr,"_KERNEL32_90(eax=0x%08lx,edx=0x%08lx,ebp[-4]=0x%02x,target = %08lx, *target =%08lx)\n",
-		EAX_reg(context),EDX_reg(context),((BYTE*)EBP_reg(context))[-4],
-		(*(DWORD*)(EAX_reg(context)+EDX_reg(context)))+4*(((BYTE*)EBP_reg(context))[-4]),
-		*(DWORD*)((*(DWORD*)(EAX_reg(context)+EDX_reg(context)))+4*(((BYTE*)EBP_reg(context))[-4]))
-	);
 	_write_qtthunk((LPBYTE)EAX_reg(context),*(DWORD*)(EAX_reg(context)+EDX_reg(context)));
 	/* we just call the real QT_Thunk right now 
 	 * we can bypass the relaycode, for we already have the registercontext
@@ -875,6 +944,7 @@
  * The start of the thunkbuf looks like this:
  * 	00: DWORD	length
  *	04: SEGPTR	address for thunkbuffer pointer
+ * [ok probably]
  */
 VOID WINAPI _KERNEL32_46(LPBYTE thunk,LPSTR thkbuf,DWORD len,LPSTR dll16,
                          LPSTR dll32)
@@ -883,22 +953,19 @@
 	HMODULE16	hmod;
 	SEGPTR		segaddr;
 
-	fprintf(stderr,"KERNEL32_46(%p,%s,%lx,%s,%s)\n",
-		thunk,thkbuf,len,dll16,dll32
-	);
 	hmod = LoadLibrary16(dll16);
 	if (hmod < 32) {
-		fprintf(stderr,"->couldn't load %s, error %d\n",dll16,hmod);
+		fprintf(stderr,"KERNEL32_46->couldn't load %s, error %d\n",dll16,hmod);
 		return;
 	}
 	segaddr = (SEGPTR)WIN32_GetProcAddress16(hmod,thkbuf);
 	if (!segaddr) {
-		fprintf(stderr,"-> haven't found %s in %s!\n",thkbuf,dll16);
+		fprintf(stderr,"KERNEL32_46-> haven't found %s in %s!\n",thkbuf,dll16);
 		return;
 	}
 	addr = (LPDWORD)PTR_SEG_TO_LIN(segaddr);
 	if (addr[0] != len) {
-		fprintf(stderr,"-> length of thkbuf differs from expected length! (%ld vs %ld)\n",addr[0],len);
+		fprintf(stderr,"KERNEL32_46-> length of thkbuf differs from expected length! (%ld vs %ld)\n",addr[0],len);
 		return;
 	}
 	*(DWORD*)PTR_SEG_TO_LIN(addr[1]) = (DWORD)thunk;
@@ -907,10 +974,11 @@
 /**********************************************************************
  *           _KERNEL32_87
  * Check if thunking is initialized (ss selector set up etc.)
+ * We do that differently, so just return TRUE.
+ * [ok]
  */
 BOOL32 WINAPI _KERNEL32_87()
 {
-    fprintf(stderr,"KERNEL32_87 stub, returning TRUE\n");
     return TRUE;
 }
 
@@ -920,6 +988,7 @@
  * thunks. It should probably be capable of crossing processboundaries.
  *
  * And YES, I've seen nr=48 (somewhere in the Win95 32<->16 OLE coupling)
+ * [ok]
  */
 DWORD WINAPIV _KERNEL32_88( DWORD nr, DWORD flags, FARPROC32 fun, ... )
 {
diff --git a/if1632/user.spec b/if1632/user.spec
index 69d5bc7..dd58ec9 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -149,7 +149,7 @@
 146 pascal16 GetClipboardFormatName(word ptr s_word) GetClipboardFormatName16
 147 pascal16 SetClipboardViewer(word) SetClipboardViewer16
 148 pascal16 GetClipboardViewer() GetClipboardViewer16
-149 pascal16 ChangeClipboardChain(word ptr) ChangeClipboardChain16
+149 pascal16 ChangeClipboardChain(word word) ChangeClipboardChain16
 150 pascal16 LoadMenu(word segstr) LoadMenu16
 151 pascal16 CreateMenu() CreateMenu16
 152 pascal16 DestroyMenu(word) DestroyMenu16
diff --git a/if1632/user32.spec b/if1632/user32.spec
index 5bc484e..b6f321b 100644
--- a/if1632/user32.spec
+++ b/if1632/user32.spec
@@ -25,26 +25,26 @@
  22 stdcall ChangeClipboardChain(long long) ChangeClipboardChain32
  23 stdcall ChangeMenuA(long long ptr long long) ChangeMenu32A
  24 stdcall ChangeMenuW(long long ptr long long) ChangeMenu32W
- 25 stdcall CharLowerA(ptr) CharLower32A
- 26 stdcall CharLowerBuffA(ptr long) CharLowerBuff32A
- 27 stdcall CharLowerBuffW(ptr long) CharLowerBuff32W
- 28 stdcall CharLowerW(ptr) CharLower32W
- 29 stdcall CharNextA(ptr) CharNext32A
- 30 stdcall CharNextExA(long ptr long) CharNextEx32A
- 31 stdcall CharNextExW(long ptr long) CharNextEx32W
- 32 stdcall CharNextW(ptr) CharNext32W
- 33 stdcall CharPrevA(ptr ptr) CharPrev32A
- 34 stdcall CharPrevExA(long ptr ptr long) CharPrevEx32A
- 35 stdcall CharPrevExW(long ptr ptr long) CharPrevEx32W
- 36 stdcall CharPrevW(ptr ptr) CharPrev32W
- 37 stdcall CharToOemA(ptr ptr) CharToOem32A
- 38 stdcall CharToOemBuffA(ptr ptr long) CharToOemBuff32A
- 39 stdcall CharToOemBuffW(ptr ptr long) CharToOemBuff32W
- 40 stdcall CharToOemW(ptr ptr) CharToOem32W
- 41 stdcall CharUpperA(ptr) CharUpper32A
- 42 stdcall CharUpperBuffA(ptr long) CharUpperBuff32A
- 43 stdcall CharUpperBuffW(ptr long) CharUpperBuff32W
- 44 stdcall CharUpperW(ptr) CharUpper32W
+ 25 stdcall CharLowerA(str) CharLower32A
+ 26 stdcall CharLowerBuffA(str long) CharLowerBuff32A
+ 27 stdcall CharLowerBuffW(wstr long) CharLowerBuff32W
+ 28 stdcall CharLowerW(wstr) CharLower32W
+ 29 stdcall CharNextA(str) CharNext32A
+ 30 stdcall CharNextExA(long str long) CharNextEx32A
+ 31 stdcall CharNextExW(long wstr long) CharNextEx32W
+ 32 stdcall CharNextW(wstr) CharNext32W
+ 33 stdcall CharPrevA(str str) CharPrev32A
+ 34 stdcall CharPrevExA(long str str long) CharPrevEx32A
+ 35 stdcall CharPrevExW(long wstr wstr long) CharPrevEx32W
+ 36 stdcall CharPrevW(wstr wstr) CharPrev32W
+ 37 stdcall CharToOemA(str str) CharToOem32A
+ 38 stdcall CharToOemBuffA(str str long) CharToOemBuff32A
+ 39 stdcall CharToOemBuffW(wstr wstr long) CharToOemBuff32W
+ 40 stdcall CharToOemW(wstr wstr) CharToOem32W
+ 41 stdcall CharUpperA(str) CharUpper32A
+ 42 stdcall CharUpperBuffA(str long) CharUpperBuff32A
+ 43 stdcall CharUpperBuffW(wstr long) CharUpperBuff32W
+ 44 stdcall CharUpperW(wstr) CharUpper32W
  45 stdcall CheckDlgButton(long long long) CheckDlgButton32
  46 stdcall CheckMenuItem(long long long) CheckMenuItem32
  47 stub CheckMenuRadioItem
@@ -78,14 +78,14 @@
  75 stdcall CreateIcon(long long long long long ptr ptr) CreateIcon32
  76 stub CreateIconFromResource
  77 stdcall CreateIconFromResourceEx(ptr long long long long long long) CreateIconFromResourceEx32
- 78 stub CreateIconIndirect
+ 78 stdcall CreateIconIndirect(ptr) CreateIconIndirect
  79 stub CreateMDIWindowA
  80 stub CreateMDIWindowW
  81 stdcall CreateMenu() CreateMenu32
  82 stdcall CreatePopupMenu() CreatePopupMenu32
- 83 stdcall CreateWindowExA(long ptr ptr long long long long long 
+ 83 stdcall CreateWindowExA(long str str long long long long long 
                             long long long ptr) CreateWindowEx32A
- 84 stdcall CreateWindowExW(long ptr ptr long long long long long 
+ 84 stdcall CreateWindowExW(long wstr wstr long long long long long 
                             long long long ptr) CreateWindowEx32W
  85 stub CreateWindowStationA
  86 stub CreateWindowStationW
@@ -141,8 +141,8 @@
 136 stdcall DialogBoxIndirectParamA(long ptr long ptr long) DialogBoxIndirectParam32A
 137 stdcall DialogBoxIndirectParamAorW(long ptr long ptr long) DialogBoxIndirectParam32A
 138 stdcall DialogBoxIndirectParamW(long ptr long ptr long) DialogBoxIndirectParam32W
-139 stdcall DialogBoxParamA(long ptr long ptr long) DialogBoxParam32A
-140 stdcall DialogBoxParamW(long ptr long ptr long) DialogBoxParam32W
+139 stdcall DialogBoxParamA(long str long ptr long) DialogBoxParam32A
+140 stdcall DialogBoxParamW(long wstr long ptr long) DialogBoxParam32W
 141 stdcall DispatchMessageA(ptr) DispatchMessage32A
 142 stdcall DispatchMessageW(ptr) DispatchMessage32W
 143 stdcall DlgDirListA(long ptr long long long) DlgDirList32A
@@ -166,10 +166,10 @@
 161 stdcall DrawMenuBar(long) DrawMenuBar32
 162 stdcall DrawStateA(long long ptr long long long long long long long) DrawState32A
 163 stub DrawStateW
-164 stdcall DrawTextA(long ptr long ptr long) DrawText32A
-165 stdcall DrawTextExA(long ptr long ptr long ptr) DrawTextEx32A
-166 stdcall DrawTextExW(long ptr long ptr long ptr) DrawTextEx32W
-167 stdcall DrawTextW(long ptr long ptr long) DrawText32W
+164 stdcall DrawTextA(long str long ptr long) DrawText32A
+165 stdcall DrawTextExA(long str long ptr long ptr) DrawTextEx32A
+166 stdcall DrawTextExW(long wstr long ptr long ptr) DrawTextEx32W
+167 stdcall DrawTextW(long wstr long ptr long) DrawText32W
 168 stub EditWndProc
 169 stdcall EmptyClipboard() EmptyClipboard32
 170 stdcall EnableMenuItem(long long long) EnableMenuItem32
@@ -200,10 +200,10 @@
 195 stdcall ExcludeUpdateRgn(long long) ExcludeUpdateRgn32
 196 stdcall ExitWindowsEx(long long) ExitWindowsEx
 197 stdcall FillRect(long ptr long) FillRect32
-198 stdcall FindWindowA(ptr ptr) FindWindow32A
-199 stdcall FindWindowExA(long long ptr ptr) FindWindowEx32A
-200 stdcall FindWindowExW(long long ptr ptr) FindWindowEx32W
-201 stdcall FindWindowW(ptr ptr) FindWindow32W
+198 stdcall FindWindowA(str str) FindWindow32A
+199 stdcall FindWindowExA(long long str str) FindWindowEx32A
+200 stdcall FindWindowExW(long long wstr wstr) FindWindowEx32W
+201 stdcall FindWindowW(wstr wstr) FindWindow32W
 202 stdcall FlashWindow(long long) FlashWindow32
 203 stdcall FrameRect(long ptr long) FrameRect32
 204 stub FreeDDElParam
@@ -213,10 +213,10 @@
 208 stdcall GetCapture() GetCapture32
 209 stdcall GetCaretBlinkTime() GetCaretBlinkTime32
 210 stdcall GetCaretPos(ptr) GetCaretPos32
-211 stdcall GetClassInfoA(long ptr ptr) GetClassInfo32A
-212 stdcall GetClassInfoExA(long ptr ptr) GetClassInfoEx32A
-213 stdcall GetClassInfoExW(long ptr ptr) GetClassInfoEx32W
-214 stdcall GetClassInfoW(long ptr ptr) GetClassInfo32W
+211 stdcall GetClassInfoA(long str ptr) GetClassInfo32A
+212 stdcall GetClassInfoExA(long str ptr) GetClassInfoEx32A
+213 stdcall GetClassInfoExW(long wstr ptr) GetClassInfoEx32W
+214 stdcall GetClassInfoW(long wstr ptr) GetClassInfo32W
 215 stdcall GetClassLongA(long long) GetClassLong32A
 216 stdcall GetClassLongW(long long) GetClassLong32W
 217 stdcall GetClassNameA(long ptr long) GetClassName32A
@@ -244,7 +244,7 @@
 239 stdcall GetDoubleClickTime() GetDoubleClickTime32
 240 stdcall GetFocus() GetFocus32
 241 stdcall GetForegroundWindow() GetForegroundWindow32
-242 stub GetIconInfo
+242 stdcall GetIconInfo(long ptr) GetIconInfo
 243 stub GetInputDesktop
 244 stdcall GetInputState() GetInputState32
 245 stdcall GetInternalWindowPos(long ptr ptr) GetInternalWindowPos32
@@ -295,8 +295,8 @@
 290 stdcall GetSysColorBrush(long) GetSysColorBrush32
 291 stdcall GetSystemMenu(long long) GetSystemMenu32
 292 stdcall GetSystemMetrics(long) GetSystemMetrics32
-293 stdcall GetTabbedTextExtentA(long ptr long long ptr) GetTabbedTextExtent32A
-294 stdcall GetTabbedTextExtentW(long ptr long long ptr) GetTabbedTextExtent32W
+293 stdcall GetTabbedTextExtentA(long str long long ptr) GetTabbedTextExtent32A
+294 stdcall GetTabbedTextExtentW(long wstr long long ptr) GetTabbedTextExtent32W
 295 stub GetThreadDesktop
 296 stdcall GetTopWindow(long) GetTopWindow32
 297 stdcall GetUpdateRect(long ptr long) GetUpdateRect32
@@ -357,32 +357,32 @@
 352 stdcall IsZoomed(long) IsZoomed32
 353 stdcall KillSystemTimer(long long) KillSystemTimer32
 354 stdcall KillTimer(long long) KillTimer32
-355 stdcall LoadAcceleratorsA(long ptr) LoadAccelerators32A
-356 stdcall LoadAcceleratorsW(long ptr) LoadAccelerators32W
-357 stdcall LoadBitmapA(long ptr) LoadBitmap32A
-358 stdcall LoadBitmapW(long ptr) LoadBitmap32W
-359 stdcall LoadCursorA(long ptr) LoadCursor32A
+355 stdcall LoadAcceleratorsA(long str) LoadAccelerators32A
+356 stdcall LoadAcceleratorsW(long wstr) LoadAccelerators32W
+357 stdcall LoadBitmapA(long str) LoadBitmap32A
+358 stdcall LoadBitmapW(long wstr) LoadBitmap32W
+359 stdcall LoadCursorA(long str) LoadCursor32A
 360 stub LoadCursorFromFileA
 361 stub LoadCursorFromFileW
-362 stdcall LoadCursorW(long ptr) LoadCursor32W
-363 stdcall LoadIconA(long ptr) LoadIcon32A
-364 stdcall LoadIconW(long ptr) LoadIcon32W
-365 stdcall LoadImageA(long ptr long long long long) LoadImage32A
-366 stdcall LoadImageW(long ptr long long long long) LoadImage32W
+362 stdcall LoadCursorW(long wstr) LoadCursor32W
+363 stdcall LoadIconA(long str) LoadIcon32A
+364 stdcall LoadIconW(long wstr) LoadIcon32W
+365 stdcall LoadImageA(long str long long long long) LoadImage32A
+366 stdcall LoadImageW(long wstr long long long long) LoadImage32W
 367 stub LoadKeyboardLayoutA
 368 stub LoadKeyboardLayoutW
 369 stub LoadLocalFonts
-370 stdcall LoadMenuA(long ptr) LoadMenu32A
+370 stdcall LoadMenuA(long str) LoadMenu32A
 371 stdcall LoadMenuIndirectA(ptr) LoadMenuIndirect32A
 372 stdcall LoadMenuIndirectW(ptr) LoadMenuIndirect32W
-373 stdcall LoadMenuW(long ptr) LoadMenu32W
+373 stdcall LoadMenuW(long wstr) LoadMenu32W
 374 stub LoadRemoteFonts
 375 stdcall LoadStringA(long long ptr long) LoadString32A
 376 stdcall LoadStringW(long long ptr long) LoadString32W
 377 stub LockWindowStation
 378 stdcall LockWindowUpdate(long) LockWindowUpdate32
-378 stdcall LookupIconIdFromDirectory(ptr long) LookupIconIdFromDirectory
-379 stdcall LookupIconIdFromDirectoryEx(ptr long long long long) LookupIconIdFromDirectoryEx32
+379 stdcall LookupIconIdFromDirectory(ptr long) LookupIconIdFromDirectory
+380 stdcall LookupIconIdFromDirectoryEx(ptr long long long long) LookupIconIdFromDirectoryEx32
 381 stub MBToWCSEx
 382 stdcall MapDialogRect(long ptr) MapDialogRect32
 383 stdcall MapVirtualKeyA(long long) MapVirtualKey32A
@@ -393,12 +393,12 @@
 388 stub MenuWindowProcA
 389 stub MenuWindowProcW
 390 stdcall MessageBeep(long) MessageBeep32
-391 stdcall MessageBoxA(long ptr ptr long) MessageBox32A
-392 stdcall MessageBoxExA(long ptr ptr long long) MessageBoxEx32A
-393 stdcall MessageBoxExW(long ptr ptr long long) MessageBoxEx32W
+391 stdcall MessageBoxA(long str str long) MessageBox32A
+392 stdcall MessageBoxExA(long str str long long) MessageBoxEx32A
+393 stdcall MessageBoxExW(long wstr wstr long long) MessageBoxEx32W
 394 stub MessageBoxIndirectA
 395 stub MessageBoxIndirectW
-396 stdcall MessageBoxW(long ptr ptr long) MessageBox32W
+396 stdcall MessageBoxW(long wstr wstr long) MessageBox32W
 397 stdcall ModifyMenuA(long long long long ptr) ModifyMenu32A
 398 stdcall ModifyMenuW(long long long long ptr) ModifyMenu32W
 399 stdcall MoveWindow(long long long long long long) MoveWindow32
@@ -433,8 +433,8 @@
 428 stdcall RegisterClassExA(ptr) RegisterClassEx32A
 429 stdcall RegisterClassExW(ptr) RegisterClassEx32W
 430 stdcall RegisterClassW(ptr) RegisterClass32W
-431 stdcall RegisterClipboardFormatA(ptr) RegisterClipboardFormat32A
-432 stdcall RegisterClipboardFormatW(ptr) RegisterClipboardFormat32W
+431 stdcall RegisterClipboardFormatA(str) RegisterClipboardFormat32A
+432 stdcall RegisterClipboardFormatW(wstr) RegisterClipboardFormat32W
 433 stub RegisterHotKey
 434 stub RegisterLogonProcess
 435 stub RegisterSystemThread
@@ -444,8 +444,8 @@
 439 stdcall ReleaseCapture() ReleaseCapture
 440 stdcall ReleaseDC(long long) ReleaseDC32
 441 stdcall RemoveMenu(long long long) RemoveMenu32
-442 stdcall RemovePropA(long ptr) RemoveProp32A
-443 stdcall RemovePropW(long ptr) RemoveProp32W
+442 stdcall RemovePropA(long str) RemoveProp32A
+443 stdcall RemovePropW(long wstr) RemoveProp32W
 444 stub ReplyMessage
 445 stub ResetDisplay
 446 stub ReuseDDElParam
@@ -478,10 +478,10 @@
 473 stub SetCursorContents
 474 stdcall SetCursorPos(long long) SetCursorPos32
 475 stub SetDebugErrorLevel
-476 stdcall SetDeskWallPaper(ptr) SetDeskWallPaper32
+476 stdcall SetDeskWallPaper(str) SetDeskWallPaper32
 477 stdcall SetDlgItemInt(long long long long) SetDlgItemInt32
-478 stdcall SetDlgItemTextA(long long ptr) SetDlgItemText32A
-479 stdcall SetDlgItemTextW(long long ptr) SetDlgItemText32W
+478 stdcall SetDlgItemTextA(long long str) SetDlgItemText32A
+479 stdcall SetDlgItemTextW(long long wstr) SetDlgItemText32W
 480 stdcall SetDoubleClickTime(long) SetDoubleClickTime32
 481 stdcall SetFocus(long) SetFocus32
 482 stdcall SetForegroundWindow(long) SetForegroundWindow32
@@ -499,8 +499,8 @@
 494 stdcall SetMessageQueue(long) SetMessageQueue32
 495 stdcall SetParent(long long) SetParent32
 496 stub SetProcessWindowStation
-497 stdcall SetPropA(long ptr long) SetProp32A
-498 stdcall SetPropW(long ptr long) SetProp32W
+497 stdcall SetPropA(long str long) SetProp32A
+498 stdcall SetPropW(long wstr long) SetProp32W
 499 stdcall SetRect(ptr long long long long) SetRect32
 500 stdcall SetRectEmpty(ptr) SetRectEmpty32
 501 stdcall SetScrollInfo(long long ptr long) SetScrollInfo32
@@ -524,8 +524,8 @@
 519 stdcall SetWindowPlacement(long ptr) SetWindowPlacement32
 520 stdcall SetWindowPos(long long long long long long long) SetWindowPos32
 521 stub SetWindowStationUser
-522 stdcall SetWindowTextA(long ptr) SetWindowText32A
-523 stdcall SetWindowTextW(long ptr) SetWindowText32W
+522 stdcall SetWindowTextA(long str) SetWindowText32A
+523 stdcall SetWindowTextW(long wstr) SetWindowText32W
 524 stdcall SetWindowWord(long long long) SetWindowWord32
 525 stdcall SetWindowsHookA(long ptr) SetWindowsHook32A
 526 stdcall SetWindowsHookExA(long long long long) SetWindowsHookEx32A
@@ -544,8 +544,8 @@
 539 stdcall SwitchToThisWindow(long long) SwitchToThisWindow32
 540 stdcall SystemParametersInfoA(long long ptr long) SystemParametersInfo32A
 541 stdcall SystemParametersInfoW(long long ptr long) SystemParametersInfo32W
-542 stdcall TabbedTextOutA(long long long ptr long long ptr long) TabbedTextOut32A
-543 stdcall TabbedTextOutW(long long long ptr long long ptr long) TabbedTextOut32W
+542 stdcall TabbedTextOutA(long long long str long long ptr long) TabbedTextOut32A
+543 stdcall TabbedTextOutW(long long long wstr long long ptr long) TabbedTextOut32W
 544 stub TileChildWindows
 545 stub TileWindows
 546 stdcall ToAscii(long long ptr ptr long) ToAscii32
@@ -565,8 +565,8 @@
 560 stub UnloadKeyboardLayout
 561 stub UnlockWindowStation
 562 stub UnpackDDElParam
-563 stdcall UnregisterClassA(ptr long) UnregisterClass32A
-564 stdcall UnregisterClassW(ptr long) UnregisterClass32W
+563 stdcall UnregisterClassA(str long) UnregisterClass32A
+564 stdcall UnregisterClassW(wstr long) UnregisterClass32W
 565 stub UnregisterHotKey
 566 stub UpdatePerUserSystemParameters
 567 stdcall UpdateWindow(long) UpdateWindow32
@@ -581,16 +581,16 @@
 576 stdcall VkKeyScanW(long) VkKeyScan32W
 577 stub WaitForInputIdle
 578 stdcall WaitMessage() WaitMessage
-579 stdcall WinHelpA(long ptr long long) WinHelp32A
-580 stdcall WinHelpW(long ptr long long) WinHelp32W
+579 stdcall WinHelpA(long str long long) WinHelp32A
+580 stdcall WinHelpW(long wstr long long) WinHelp32W
 581 stdcall WindowFromDC(long) WindowFromDC32
 582 stdcall WindowFromPoint(long long) WindowFromPoint32
 583 stub keybd_event
 584 stub mouse_event
 585 varargs wsprintfA() wsprintf32A
 586 varargs wsprintfW() wsprintf32W
-587 stdcall wvsprintfA(ptr ptr ptr) wvsprintf32A
-588 stdcall wvsprintfW(ptr ptr ptr) wvsprintf32W
+587 stdcall wvsprintfA(str str ptr) wvsprintf32A
+588 stdcall wvsprintfW(wstr wstr ptr) wvsprintf32W
 #late additions
 589 stub ChangeDisplaySettingsA
 590 stub ChangeDisplaySettingsW
diff --git a/if1632/version.spec b/if1632/version.spec
index bd3dc79..f1644b2 100644
--- a/if1632/version.spec
+++ b/if1632/version.spec
@@ -1,17 +1,17 @@
 name version
 type win32
 
-0 stdcall GetFileVersionInfoA(ptr long long ptr) GetFileVersionInfo32A
-1 stdcall GetFileVersionInfoSizeA(ptr ptr) GetFileVersionInfoSize32A
-2 stdcall GetFileVersionInfoSizeW(ptr ptr) GetFileVersionInfoSize32W
-3 stdcall GetFileVersionInfoW(ptr long long ptr) GetFileVersionInfo32W
+0 stdcall GetFileVersionInfoA(str long long ptr) GetFileVersionInfo32A
+1 stdcall GetFileVersionInfoSizeA(str ptr) GetFileVersionInfoSize32A
+2 stdcall GetFileVersionInfoSizeW(wstr ptr) GetFileVersionInfoSize32W
+3 stdcall GetFileVersionInfoW(wstr long long ptr) GetFileVersionInfo32W
 #4 stub VerFThk_ThunkData32
-5 stdcall VerFindFileA(long ptr ptr ptr ptr ptr ptr ptr) VerFindFile32A
-6 stdcall VerFindFileW(long ptr ptr ptr ptr ptr ptr ptr) VerFindFile32W
-7 stdcall VerInstallFileA(long ptr ptr ptr ptr ptr ptr ptr) VerInstallFile32A
-8 stdcall VerInstallFileW(long ptr ptr ptr ptr ptr ptr ptr) VerInstallFile32W
+5 stdcall VerFindFileA(long str str str ptr ptr ptr ptr) VerFindFile32A
+6 stdcall VerFindFileW(long wstr wstr wstr ptr ptr ptr ptr) VerFindFile32W
+7 stdcall VerInstallFileA(long str str str str str ptr ptr) VerInstallFile32A
+8 stdcall VerInstallFileW(long wstr wstr wstr wstr wstr ptr ptr) VerInstallFile32W
 9 stdcall VerLanguageNameA(long ptr long) VerLanguageName32A
 10 stdcall VerLanguageNameW(long ptr long) VerLanguageName32W
-11 stdcall VerQueryValueA(ptr ptr ptr ptr) VerQueryValue32A
-12 stdcall VerQueryValueW(ptr ptr ptr ptr) VerQueryValue32W
+11 stdcall VerQueryValueA(ptr str ptr ptr) VerQueryValue32A
+12 stdcall VerQueryValueW(ptr wstr ptr ptr) VerQueryValue32W
 #13 stub VerThkSL_ThunkData32
diff --git a/if1632/winaspi.spec b/if1632/winaspi.spec
new file mode 100644
index 0000000..9474b71
--- /dev/null
+++ b/if1632/winaspi.spec
@@ -0,0 +1,7 @@
+name	winaspi
+type	win16
+
+1	pascal16 GetASPISupportInfo() GetASPISupportInfo16
+2	pascal16 SendASPICommand(segptr) SendASPICommand16
+#3	stub GETASPIDLLVERSION
+#3	stub INSERTINASPICHAIN
diff --git a/if1632/winmm.spec b/if1632/winmm.spec
index ba38635..3c70167 100644
--- a/if1632/winmm.spec
+++ b/if1632/winmm.spec
@@ -1,185 +1,185 @@
 name winmm
 type win32
 
-0001 stdcall PlaySoundA(ptr long long) PlaySound32A
-0004 stub CloseDriver
-0005 stub DefDriverProc
-0006 stub DriverCallback
-0007 stub DrvClose
-0008 stub DrvDefDriverProc
-0009 stub DrvGetModuleHandle
-0010 stub DrvOpen
-0011 stub DrvOpenA
-0012 stub DrvSendMessage
-0013 stub GetDriverFlags
-0014 stub GetDriverModuleHandle
-0015 stub OpenDriver
-0016 stub OpenDriverA
-0017 stub PlaySound
-0018 stdcall PlaySoundW(ptr long long) PlaySound32W
-0019 stub SendDriverMessage
-0020 stub auxGetDevCapsA
-0021 stub auxGetDevCapsW
-0022 stub auxGetNumDevs
-0023 stub auxGetVolume
-0024 stub auxOutMessage
-0025 stub auxSetVolume
-0026 stub joyConfigChanged
-0027 stub joyGetDevCapsA
-0028 stub joyGetDevCapsW
-0029 stub joyGetNumDevs
-0030 stub joyGetPos
-0031 stub joyGetPosEx
-0032 stub joyGetThreshold
-0033 stub joyReleaseCapture
-0034 stub joySetCapture
-0035 stub joySetThreshold
-0036 stub mciDriverNotify
-0037 stub mciDriverYield
-0038 stub mciExecute
-0039 stub mciFreeCommandResource
-0040 stub mciGetCreatorTask
-0041 stub mciGetDeviceIDA
-0042 stub mciGetDeviceIDFromElementIDW
-0043 stub mciGetDeviceIDW
-0044 stub mciGetDriverData
-0045 stub mciGetErrorStringA
-0046 stub mciGetErrorStringW
-0047 stub mciGetYieldProc
-0048 stub mciLoadCommandResource
-0049 stub mciSendCommandA
-0050 stub mciSendCommandW
-0051 stdcall mciSendStringA(ptr ptr long long) mciSendString
-0052 stub mciSendStringW
-0053 stub mciSetDriverData
-0054 stub mciSetYieldProc
-0055 stub midiConnect
-0056 stub midiDisconnect
-0057 stub midiInAddBuffer
-0058 stub midiInClose
-0059 stub midiInGetDevCapsA
-0060 stub midiInGetDevCapsW
-0061 stub midiInGetErrorTextA
-0062 stub midiInGetErrorTextW
-0063 stub midiInGetID
-0064 stub midiInGetNumDevs
-0065 stub midiInMessage
-0066 stub midiInOpen
-0067 stub midiInPrepareHeader
-0068 stub midiInReset
-0069 stub midiInStart
-0070 stub midiInStop
-0071 stub midiInUnprepareHeader
-0072 stub midiOutCacheDrumPatches
-0073 stub midiOutCachePatches
-0074 stub midiOutClose
-0075 stub midiOutGetDevCapsA
-0076 stub midiOutGetDevCapsW
-0077 stub midiOutGetErrorTextA
-0078 stub midiOutGetErrorTextW
-0079 stub midiOutGetID
-0080 stub midiOutGetNumDevs
-0081 stub midiOutGetVolume
-0082 stub midiOutLongMsg
-0083 stub midiOutMessage
-0084 stub midiOutOpen
-0085 stub midiOutPrepareHeader
-0086 stub midiOutReset
-0087 stub midiOutSetVolume
-0088 stub midiOutShortMsg
-0089 stub midiOutUnprepareHeader
-0090 stub midiStreamClose
-0091 stub midiStreamOpen
-0092 stub midiStreamOut
-0093 stub midiStreamPause
-0094 stub midiStreamPosition
-0095 stub midiStreamProperty
-0096 stub midiStreamRestart
-0097 stub midiStreamStop
-0098 stub mixerClose
-0099 stub mixerGetControlDetailsA
-0100 stub mixerGetControlDetailsW
-0101 stub mixerGetDevCapsA
-0102 stub mixerGetDevCapsW
-0103 stub mixerGetID
-0104 stub mixerGetLineControlsA
-0105 stub mixerGetLineControlsW
-0106 stub mixerGetLineInfoA
-0107 stub mixerGetLineInfoW
-0108 stub mixerGetNumDevs
-0109 stub mixerMessage
-0110 stub mixerOpen
-0111 stub mixerSetControlDetails
-0112 stub mmioAdvance
-0113 stub mmioAscend
-0114 stub mmioClose
-0115 stub mmioCreateChunk
-0116 stub mmioDescend
-0117 stub mmioFlush
-0118 stub mmioGetInfo
-0119 stub mmioInstallIOProc16
-0120 stdcall mmioInstallIOProcA(long ptr long) mmioInstallIOProc32A
-0121 stub mmioInstallIOProcW
-0122 stub mmioOpenA
-0123 stub mmioOpenW
-0124 stub mmioRead
-0125 stub mmioRenameA
-0126 stub mmioRenameW
-0127 stub mmioSeek
-0128 stub mmioSendMessage
-0129 stub mmioSetBuffer
-0130 stub mmioSetInfo
-0131 stub mmioStringToFOURCCA
-0132 stub mmioStringToFOURCCW
-0133 stub mmioWrite
-0134 stub mmsystemGetVersion
-0135 stdcall sndPlaySoundA(ptr long) sndPlaySound
-0136 stub sndPlaySoundW
-0137 stub timeBeginPeriod
-0138 stub timeEndPeriod
-0139 stub timeGetDevCaps
-0140 stub timeGetSystemTime
-0141 stdcall timeGetTime() timeGetTime
-0142 stub timeKillEvent
-0143 stub timeSetEvent
-0144 stub waveInAddBuffer
-0145 stub waveInClose
-0146 stub waveInGetDevCapsA
-0147 stub waveInGetDevCapsW
-0148 stub waveInGetErrorTextA
-0149 stub waveInGetErrorTextW
-0150 stub waveInGetID
-0151 stub waveInGetNumDevs
-0152 stub waveInGetPosition
-0153 stub waveInMessage
-0154 stub waveInOpen
-0155 stub waveInPrepareHeader
-0156 stub waveInReset
-0157 stub waveInStart
-0158 stub waveInStop
-0159 stub waveInUnprepareHeader
-0160 stub waveOutBreakLoop
-0161 stub waveOutClose
-0162 stub waveOutGetDevCapsA
-0163 stub waveOutGetDevCapsW
-0164 stub waveOutGetErrorTextA
-0165 stub waveOutGetErrorTextW
-0166 stub waveOutGetID
-0167 	stdcall waveOutGetNumDevs() waveOutGetNumDevs
-0168 stub waveOutGetPitch
-0169 stub waveOutGetPlaybackRate
-0170 stub waveOutGetPosition
-0171 stub waveOutGetVolume
-0172 stub waveOutMessage
-0173 stub waveOutOpen
-0174 stub waveOutPause
-0175 stub waveOutPrepareHeader
-0176 stub waveOutReset
-0177 stub waveOutRestart
-0178 stub waveOutSetPitch
-0179 stub waveOutSetPlaybackRate
-0180 stub waveOutSetVolume
-0181 stub waveOutUnprepareHeader
-0182 stub waveOutWrite
-0183 stub winmmf_ThunkData32
-0184 stub winmmsl_ThunkData32
+  1 stdcall PlaySoundA(ptr long long) PlaySound32A
+  4 stub CloseDriver
+  5 stub DefDriverProc
+  6 stub DriverCallback
+  7 stub DrvClose
+  8 stub DrvDefDriverProc
+  9 stub DrvGetModuleHandle
+ 10 stub DrvOpen
+ 11 stub DrvOpenA
+ 12 stub DrvSendMessage
+ 13 stub GetDriverFlags
+ 14 stub GetDriverModuleHandle
+ 15 stdcall OpenDriver(ptr ptr long) OpenDriver
+ 16 stub OpenDriverA
+ 17 stub PlaySound
+ 18 stdcall PlaySoundW(ptr long long) PlaySound32W
+ 19 stub SendDriverMessage
+ 20 stdcall auxGetDevCapsA(long ptr long) auxGetDevCaps32A
+ 21 stdcall auxGetDevCapsW(long ptr long) auxGetDevCaps32W
+ 22 stdcall auxGetNumDevs() auxGetNumDevs32
+ 23 stdcall auxGetVolume(long ptr) auxGetVolume32
+ 24 stdcall auxOutMessage(long long long long) auxOutMessage32
+ 25 stdcall auxSetVolume(long long) auxSetVolume32
+ 26 stub joyConfigChanged
+ 27 stub joyGetDevCapsA
+ 28 stub joyGetDevCapsW
+ 29 stub joyGetNumDevs
+ 30 stub joyGetPos
+ 31 stub joyGetPosEx
+ 32 stub joyGetThreshold
+ 33 stub joyReleaseCapture
+ 34 stub joySetCapture
+ 35 stub joySetThreshold
+ 36 stub mciDriverNotify
+ 37 stub mciDriverYield
+ 38 stub mciExecute
+ 39 stub mciFreeCommandResource
+ 40 stub mciGetCreatorTask
+ 41 stub mciGetDeviceIDA
+ 42 stub mciGetDeviceIDFromElementIDW
+ 43 stub mciGetDeviceIDW
+ 44 stub mciGetDriverData
+ 45 stdcall mciGetErrorStringA(long ptr long) mciGetErrorString32A
+ 46 stdcall mciGetErrorStringW(long ptr long) mciGetErrorString32W
+ 47 stub mciGetYieldProc
+ 48 stub mciLoadCommandResource
+ 49 stub mciSendCommandA
+ 50 stub mciSendCommandW
+ 51 stdcall mciSendStringA(ptr ptr long long) mciSendString
+ 52 stub mciSendStringW
+ 53 stub mciSetDriverData
+ 54 stub mciSetYieldProc
+ 55 stub midiConnect
+ 56 stub midiDisconnect
+ 57 stdcall midiInAddBuffer(long ptr long) midiInAddBuffer32
+ 58 stdcall midiInClose(long) midiInClose32
+ 59 stdcall midiInGetDevCapsA(long ptr long) midiInGetDevCaps32A
+ 60 stdcall midiInGetDevCapsW(long ptr long) midiInGetDevCaps32W
+ 61 stdcall midiInGetErrorTextA(long ptr long) midiInGetErrorText32A
+ 62 stdcall midiInGetErrorTextW(long ptr long) midiInGetErrorText32W
+ 63 stdcall midiInGetID(long) midiInGetID32
+ 64 stdcall midiInGetNumDevs() midiInGetNumDevs32
+ 65 stdcall midiInMessage(long long long long) midiInMessage32
+ 66 stdcall midiInOpen(ptr long long long long) midiInOpen32
+ 67 stdcall midiInPrepareHeader(long ptr long) midiInPrepareHeader32
+ 68 stdcall midiInReset(long) midiInReset32
+ 69 stdcall midiInStart(long) midiInStart32
+ 70 stdcall midiInStop(long) midiInStop32
+ 71 stdcall midiInUnprepareHeader(long ptr long) midiInUnprepareHeader32
+ 72 stdcall midiOutCacheDrumPatches(long long ptr long) midiOutCacheDrumPatches32
+ 73 stdcall midiOutCachePatches(long long ptr long) midiOutCachePatches32
+ 74 stdcall midiOutClose(long) midiOutClose32
+ 75 stdcall midiOutGetDevCapsA(long ptr long) midiOutGetDevCaps32A
+ 76 stdcall midiOutGetDevCapsW(long ptr long) midiOutGetDevCaps32W
+ 77 stdcall midiOutGetErrorTextA(long ptr long) midiOutGetErrorText32A
+ 78 stdcall midiOutGetErrorTextW(long ptr long) midiOutGetErrorText32W
+ 79 stdcall midiOutGetID(long) midiOutGetID32
+ 80 stdcall midiOutGetNumDevs() midiOutGetNumDevs32
+ 81 stdcall midiOutGetVolume(long ptr) midiOutGetVolume32
+ 82 stdcall midiOutLongMsg(long ptr long) midiOutLongMsg32
+ 83 stdcall midiOutMessage(long long long long) midiOutMessage32
+ 84 stdcall midiOutOpen(ptr long long long long) midiOutOpen32
+ 85 stdcall midiOutPrepareHeader(long ptr long) midiOutPrepareHeader32
+ 86 stdcall midiOutReset(long) midiOutReset32
+ 87 stdcall midiOutSetVolume(long ptr) midiOutSetVolume32
+ 88 stdcall midiOutShortMsg(long long) midiOutShortMsg32
+ 89 stdcall midiOutUnprepareHeader(long ptr long) midiOutUnprepareHeader32
+ 90 stub midiStreamClose
+ 91 stub midiStreamOpen
+ 92 stub midiStreamOut
+ 93 stub midiStreamPause
+ 94 stub midiStreamPosition
+ 95 stub midiStreamProperty
+ 96 stub midiStreamRestart
+ 97 stub midiStreamStop
+ 98 stdcall mixerClose(long) mixerClose32
+ 99 stdcall mixerGetControlDetailsA(long ptr long) mixerGetControlDetails32A
+100 stdcall mixerGetControlDetailsW(long ptr long) mixerGetControlDetails32W
+101 stdcall mixerGetDevCapsA(long ptr long) mixerGetDevCaps32A
+102 stdcall mixerGetDevCapsW(long ptr long) mixerGetDevCaps32W
+103 stdcall mixerGetID(long ptr long) mixerGetID32
+104 stdcall mixerGetLineControlsA(long ptr long) mixerGetLineControls32A
+105 stdcall mixerGetLineControlsW(long ptr long) mixerGetLineControls32W
+106 stdcall mixerGetLineInfoA(long ptr long) mixerGetLineInfo32A
+107 stdcall mixerGetLineInfoW(long ptr long) mixerGetLineInfo32W
+108 stdcall mixerGetNumDevs() mixerGetNumDevs32
+109 stdcall mixerMessage(long long long long) mixerMessage32
+110 stdcall mixerOpen(ptr long long long long) mixerOpen32
+111 stdcall mixerSetControlDetails(long ptr long) mixerSetControlDetails32
+112 stub mmioAdvance
+113 stub mmioAscend
+114 stub mmioClose
+115 stub mmioCreateChunk
+116 stub mmioDescend
+117 stub mmioFlush
+118 stub mmioGetInfo
+119 stub mmioInstallIOProc16
+120 stdcall mmioInstallIOProcA(long ptr long) mmioInstallIOProc32A
+121 stub mmioInstallIOProcW
+122 stdcall mmioOpenA(str ptr long) mmioOpen32A
+123 stdcall mmioOpenW(wstr ptr long) mmioOpen32W
+124 stub mmioRead
+125 stub mmioRenameA
+126 stub mmioRenameW
+127 stub mmioSeek
+128 stub mmioSendMessage
+129 stub mmioSetBuffer
+130 stub mmioSetInfo
+131 stdcall mmioStringToFOURCCA(str long) mmioStringToFOURCC32A
+132 stdcall mmioStringToFOURCCW(wstr long) mmioStringToFOURCC32W
+133 stub mmioWrite
+134 stdcall mmsystemGetVersion() mmsystemGetVersion32
+135 stdcall sndPlaySoundA(ptr long) sndPlaySound
+136 stub sndPlaySoundW
+137 stub timeBeginPeriod
+138 stub timeEndPeriod
+139 stub timeGetDevCaps
+140 stub timeGetSystemTime
+141 stdcall timeGetTime() timeGetTime
+142 stub timeKillEvent
+143 stub timeSetEvent
+144 stdcall waveInAddBuffer(long ptr long) waveInAddBuffer32
+145 stdcall waveInClose(long) waveInClose32
+146 stdcall waveInGetDevCapsA(long ptr long) waveInGetDevCaps32A
+147 stdcall waveInGetDevCapsW(long ptr long) waveInGetDevCaps32W
+148 stdcall waveInGetErrorTextA(long ptr long) waveInGetErrorText32A
+149 stdcall waveInGetErrorTextW(long ptr long) waveInGetErrorText32W
+150 stdcall waveInGetID(long ptr) waveInGetID32
+151 stdcall waveInGetNumDevs() waveInGetNumDevs32
+152 stdcall waveInGetPosition(long ptr long) waveInGetPosition32
+153 stdcall waveInMessage(long long long long) waveInMessage32
+154 stdcall waveInOpen(ptr long ptr long long long) waveInOpen32
+155 stdcall waveInPrepareHeader(long ptr long) waveInPrepareHeader32
+156 stdcall waveInReset(long) waveInReset32
+157 stdcall waveInStart(long) waveInStart32
+158 stdcall waveInStop(long) waveInStop32
+159 stdcall waveInUnprepareHeader(long ptr long) waveInUnprepareHeader32
+160 stdcall waveOutBreakLoop(long) waveOutBreakLoop32
+161 stdcall waveOutClose(long) waveOutClose32
+162 stdcall waveOutGetDevCapsA(long ptr long) waveOutGetDevCaps32A
+163 stdcall waveOutGetDevCapsW(long ptr long) waveOutGetDevCaps32W
+164 stdcall waveOutGetErrorTextA(long ptr long) waveOutGetErrorText32A
+165 stdcall waveOutGetErrorTextW(long ptr long) waveOutGetErrorText32W
+166 stdcall waveOutGetID(long ptr) waveOutGetID32
+167 stdcall waveOutGetNumDevs() waveOutGetNumDevs32
+168 stdcall waveOutGetPitch(long ptr) waveOutGetPitch32
+169 stdcall waveOutGetPlaybackRate(long ptr) waveOutGetPlaybackRate32
+170 stdcall waveOutGetPosition(long ptr long) waveOutGetPosition32
+171 stdcall waveOutGetVolume(long ptr) waveOutGetVolume32
+172 stdcall waveOutMessage(long long long long) waveOutMessage32
+173 stdcall waveOutOpen(ptr long ptr long long long) waveOutOpen32
+174 stdcall waveOutPause(long) waveOutPause32
+175 stdcall waveOutPrepareHeader(long ptr long) waveOutPrepareHeader32
+176 stdcall waveOutReset(long) waveOutReset32
+177 stdcall waveOutRestart(long) waveOutRestart32
+178 stdcall waveOutSetPitch(long long) waveOutSetPitch32
+179 stdcall waveOutSetPlaybackRate(long long) waveOutSetPlaybackRate32
+180 stdcall waveOutSetVolume(long long) waveOutSetVolume32
+181 stdcall waveOutUnprepareHeader(long ptr long) waveOutPrepareHeader32
+182 stdcall waveOutWrite(long ptr long) waveOutWrite32
+183 stub winmmf_ThunkData32
+184 stub winmmsl_ThunkData32
diff --git a/if1632/winspool.spec b/if1632/winspool.spec
index 41c15cd..cafda74 100644
--- a/if1632/winspool.spec
+++ b/if1632/winspool.spec
@@ -51,7 +51,7 @@
 148 stub DeletePrinterIC
 149 stub DevQueryPrint
 150 stub DeviceCapabilities
-151 stdcall DeviceCapabilitiesA(ptr ptr long ptr ptr) DeviceCapabilities32A
+151 stdcall DeviceCapabilitiesA(str str long ptr ptr) DeviceCapabilities32A
 152 stub DeviceCapabilitiesW
 153 stub DeviceMode
 154 stub DocumentEvent
diff --git a/if1632/wsock32.spec b/if1632/wsock32.spec
index 6269b17..829fe95 100644
--- a/if1632/wsock32.spec
+++ b/if1632/wsock32.spec
@@ -25,15 +25,15 @@
 022 stdcall shutdown(long long) WINSOCK_shutdown32
 023 stdcall socket(long long long) WINSOCK_socket32
 051 stdcall gethostbyaddr(ptr long long) WINSOCK_gethostbyaddr32
-052 stdcall gethostbyname(ptr) WINSOCK_gethostbyname32
-053 stdcall getprotobyname(ptr) WINSOCK_getprotobyname32
+052 stdcall gethostbyname(str) WINSOCK_gethostbyname32
+053 stdcall getprotobyname(str) WINSOCK_getprotobyname32
 054 stdcall getprotobynumber(long) WINSOCK_getprotobynumber32
-055 stdcall getservbyname(ptr ptr) WINSOCK_getservbyname32
-056 stdcall getservbyport(long ptr) WINSOCK_getservbyport32
+055 stdcall getservbyname(str str) WINSOCK_getservbyname32
+056 stdcall getservbyport(long str) WINSOCK_getservbyport32
 057 stdcall gethostname(ptr long) WINSOCK_gethostname32
-101 stub WSAAsyncSelect
+101 stdcall WSAAsyncSelect(long long long long) WSAAsyncSelect
 102 stub WSAAsyncGetHostByAddr
-103 stub WSAAsyncGetHostByName
+103 stdcall WSAAsyncGetHostByName(long long ptr ptr long) WSAAsyncGetHostByName32
 104 stub WSAAsyncGetProtoByNumber
 105 stub WSAAsyncGetProtoByName
 106 stub WSAAsyncGetServByPort
diff --git a/include/aspi.h b/include/aspi.h
new file mode 100644
index 0000000..901aa9e
--- /dev/null
+++ b/include/aspi.h
@@ -0,0 +1,173 @@
+#if !defined(ASPI_H)
+#define ASPI_H
+
+#pragma pack(1)
+
+#define SS_PENDING	0x00
+#define SS_COMP		0x01
+#define SS_ABORTED	0x02
+#define SS_ERR		0x04
+#define SS_OLD_MANAGE	0xe1
+#define SS_ILLEGAL_MODE	0xe2
+#define SS_NO_ASPI	0xe3
+#define SS_FAILED_INIT	0xe4
+#define SS_INVALID_HA	0x81
+#define SS_INVALID_SRB	0xe0
+#define SS_ASPI_IS_BUSY	0xe5
+#define SS_BUFFER_TO_BIG	0xe6
+
+#define SC_HA_INQUIRY		0x00
+#define SC_GET_DEV_TYPE 	0x01
+#define SC_EXEC_SCSI_CMD	0x02
+#define SC_ABORT_SRB		0x03
+#define SC_RESET_DEV		0x04
+
+/* Host adapter status codes */
+#define HASTAT_OK		0x00
+#define HASTAT_SEL_TO		0x11
+#define HASTAT_DO_DU		0x12
+#define HASTAT_BUS_FREE		0x13
+#define HASTAT_PHASE_ERR	0x14
+
+/* Target status codes */
+#define STATUS_GOOD		0x00
+#define STATUS_CHKCOND		0x02
+#define STATUS_BUSY		0x08
+#define STATUS_RESCONF		0x18
+
+
+typedef union SRB16 * LPSRB16;
+
+struct SRB_HaInquiry16 {
+  BYTE	SRB_cmd;
+  BYTE	SRB_Status;
+  BYTE	SRB_HaId;
+  BYTE	SRB_Flags;
+  WORD	SRB_55AASignature;
+  WORD	SRB_ExtBufferSize;
+  BYTE	HA_Count;
+  BYTE	HA_SCSI_ID;
+  BYTE	HA_ManagerId[16];
+  BYTE	HA_Identifier[16];
+  BYTE	HA_Unique[16];
+  BYTE	HA_ExtBuffer[4];
+} WINE_PACKED;
+
+typedef struct SRB_HaInquiry16 SRB_HaInquiry16;
+
+struct SRB_ExecSCSICmd16 {
+  BYTE        SRB_Cmd;                // ASPI command code		(W)
+  BYTE        SRB_Status;             // ASPI command status byte	(R)
+  BYTE        SRB_HaId;               // ASPI host adapter number	(W)
+  BYTE        SRB_Flags;              // ASPI request flags		(W)
+  DWORD       SRB_Hdr_Rsvd;           // Reserved, MUST = 0		(-)
+  BYTE        SRB_Target;             // Target's SCSI ID		(W)
+  BYTE        SRB_Lun;                // Target's LUN number		(W)
+  DWORD       SRB_BufLen;             // Data Allocation LengthPG	(W/R)
+  BYTE        SRB_SenseLen;           // Sense Allocation Length	(W)
+  SEGPTR      SRB_BufPointer;         // Data Buffer Pointer		(W)
+  DWORD       SRB_Rsvd1;              // Reserved, MUST = 0		(-/W)
+  BYTE        SRB_CDBLen;             // CDB Length = 6			(W)
+  BYTE        SRB_HaStat;             // Host Adapter Status		(R)
+  BYTE        SRB_TargStat;           // Target Status			(R)
+  FARPROC16   SRB_PostProc;	      // Post routine			(W)
+  BYTE        SRB_Rsvd2[34];          // Reserved, MUST = 0
+  BYTE		CDBByte[0];	      // SCSI CBD - variable length	(W)
+  /* variable example for 6 byte cbd
+   * BYTE        CDBByte[6];             // SCSI CDB			(W)
+   * BYTE        SenseArea6[SENSE_LEN];  // Request Sense buffer 	(R)
+   */
+} WINE_PACKED ;
+
+typedef struct SRB_ExecSCSICmd16 SRB_ExecSCSICmd16;
+
+struct SRB_ExecSCSICmd32 {
+  BYTE        SRB_Cmd;            // ASPI command code = SC_EXEC_SCSI_CMD
+  BYTE        SRB_Status;         // ASPI command status byte
+  BYTE        SRB_HaId;           // ASPI host adapter number
+  BYTE        SRB_Flags;          // ASPI request flags
+  DWORD       SRB_Hdr_Rsvd;       // Reserved
+  BYTE        SRB_Target;         // Target's SCSI ID
+  BYTE        SRB_Lun;            // Target's LUN number
+  WORD        SRB_Rsvd1;          // Reserved for Alignment
+  DWORD       SRB_BufLen;         // Data Allocation Length
+  BYTE        *SRB_BufPointer;    // Data Buffer Point
+  BYTE        SRB_SenseLen;       // Sense Allocation Length
+  BYTE        SRB_CDBLen;         // CDB Length
+  BYTE        SRB_HaStat;         // Host Adapter Status
+  BYTE        SRB_TargStat;       // Target Status
+  void        (*SRB_PostProc)();  // Post routine
+  void        *SRB_Rsvd2;         // Reserved
+  BYTE        SRB_Rsvd3[16];      // Reserved for expansion
+  BYTE        CDBByte[16];        // SCSI CDB
+  BYTE        SenseArea[0];       // Request sense buffer - var length
+};
+
+typedef struct SRB_ExecSCSICmd32 SRB_ExecSCSICmd32;
+
+struct SRB_Abort16 {
+  BYTE        SRB_Cmd;            // ASPI command code = SC_ABORT_SRB
+  BYTE        SRB_Status;         // ASPI command status byte
+  BYTE        SRB_HaId;           // ASPI host adapter number
+  BYTE        SRB_Flags;          // ASPI request flags
+  DWORD       SRB_Hdr_Rsvd;       // Reserved, MUST = 0
+  LPSRB16     SRB_ToAbort;        // Pointer to SRB to abort
+} WINE_PACKED;
+
+typedef struct SRB_Abort16 SRB_Abort16;
+
+struct SRB_BusDeviceReset16 {
+  BYTE        SRB_Cmd;            // ASPI command code = SC_RESET_DEV
+  BYTE        SRB_Status;         // ASPI command status byte
+  BYTE        SRB_HaId;           // ASPI host adapter number
+  BYTE        SRB_Flags;          // ASPI request flags
+  DWORD       SRB_Hdr_Rsvd;       // Reserved, MUST = 0
+  BYTE        SRB_Target;         // Target's SCSI ID
+  BYTE        SRB_Lun;            // Target's LUN number
+  BYTE        SRB_ResetRsvd1[14]; // Reserved, MUST = 0
+  BYTE        SRB_HaStat;         // Host Adapter Status
+  BYTE        SRB_TargStat;       // Target Status
+  SEGPTR      SRB_PostProc;           // Post routine
+  BYTE        SRB_ResetRsvd2[34]; // Reserved, MUST = 0
+} WINE_PACKED;
+
+typedef struct SRB_BusDeviceReset16 SRB_BusDeviceReset16;
+
+struct SRB_GDEVBlock16 {
+  BYTE        SRB_Cmd;            // ASPI command code = SC_GET_DEV_TYPE
+  BYTE        SRB_Status;         // ASPI command status byte
+  BYTE        SRB_HaId;           // ASPI host adapter number
+  BYTE        SRB_Flags;          // ASPI request flags
+  DWORD       SRB_Hdr_Rsvd;       // Reserved, MUST = 0
+  BYTE        SRB_Target;         // Target's SCSI ID
+  BYTE        SRB_Lun;            // Target's LUN number
+  BYTE        SRB_DeviceType;     // Target's peripheral device type
+} WINE_PACKED;
+
+typedef struct SRB_GDEVBlock16 SRB_GDEVBlock16;
+
+
+
+struct SRB_Common16 {
+  BYTE	SRB_cmd;
+};
+
+
+typedef struct SRB_Common16 SRB_Common16;
+
+
+union SRB16 {
+  SRB_Common16		common;
+  SRB_HaInquiry16	inquiry;
+  SRB_ExecSCSICmd16	cmd;
+  SRB_Abort16		abort;
+  SRB_BusDeviceReset16	reset;
+  SRB_GDEVBlock16	devtype;
+};
+
+typedef union SRB16 SRB16;
+
+
+
+
+#endif
diff --git a/include/callback.h b/include/callback.h
index e2e230e..cbb235e 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -17,69 +17,48 @@
      IF1632_CallLargeStack( (int(*)())(func), (void *)(arg) ) : \
      ((int(*)())(func))((void *)arg))
 
-/* List of the 16-bit callback functions. This list is used  */
-/* by the build program to generate the file if1632/callto16.S */
+typedef struct
+{
+    VOID (CALLBACK *CallRegisterProc)( CONTEXT *, INT32 );
+    VOID (CALLBACK *CallTaskRescheduleProc)(void);
+    LRESULT (CALLBACK *CallWndProc)( WNDPROC16, HWND16, UINT16,
+                                     WPARAM16, LPARAM );
+    LRESULT (CALLBACK *CallDriverProc)( DRIVERPROC16, DWORD, HDRVR16,
+                                        UINT16, LPARAM, LPARAM );
+    LRESULT (CALLBACK *CallDriverCallback)( FARPROC16, HANDLE16, UINT16,
+                                            DWORD, LPARAM, LPARAM );
+    LRESULT (CALLBACK *CallTimeFuncProc)( FARPROC16, WORD, UINT16,
+                                          DWORD, LPARAM, LPARAM );
+    INT16 (CALLBACK *CallWindowsExitProc)( FARPROC16, INT16 );
+    INT16 (CALLBACK *CallWordBreakProc)( EDITWORDBREAKPROC16, SEGPTR, INT16,
+                                         INT16, INT16 );
+    VOID (CALLBACK *CallBootAppProc)( FARPROC16, HANDLE16, HFILE16 );
+    WORD (CALLBACK *CallLoadAppSegProc)( FARPROC16, HANDLE16, HFILE16, WORD );
+    VOID (CALLBACK *CallSystemTimerProc)( FARPROC16 );
+    LRESULT (CALLBACK *CallASPIPostProc)( FARPROC16, SEGPTR );
+    /* Following are the graphics driver callbacks */
+    WORD (CALLBACK *CallDrvControlProc)( FARPROC16, SEGPTR, WORD,
+                                         SEGPTR, SEGPTR );
+    WORD (CALLBACK *CallDrvEnableProc)( FARPROC16, SEGPTR, WORD, SEGPTR,
+                                        SEGPTR, SEGPTR );
+    WORD (CALLBACK *CallDrvEnumDFontsProc)( FARPROC16, SEGPTR, SEGPTR,
+                                            FARPROC16, SEGPTR );
+    WORD (CALLBACK *CallDrvEnumObjProc)( FARPROC16, SEGPTR, WORD, FARPROC16,
+                                         SEGPTR );
+    WORD (CALLBACK *CallDrvOutputProc)( FARPROC16, SEGPTR, WORD, WORD, SEGPTR,
+                                        SEGPTR, SEGPTR, SEGPTR, SEGPTR );
+    DWORD (CALLBACK *CallDrvRealizeProc)( FARPROC16, SEGPTR, WORD, SEGPTR,
+                                          SEGPTR, SEGPTR );
+    WORD (CALLBACK *CallDrvStretchBltProc)( FARPROC16, SEGPTR, WORD, WORD,
+                                            WORD, WORD, SEGPTR, WORD, WORD,
+                                            WORD, WORD, DWORD, SEGPTR, SEGPTR,
+                                            SEGPTR );
+    DWORD (CALLBACK *CallDrvExtTextOutProc)( FARPROC16, SEGPTR, WORD, WORD,
+                                             SEGPTR, SEGPTR, INT16, SEGPTR,
+                                             SEGPTR, SEGPTR, SEGPTR, SEGPTR,
+                                             WORD );
+} CALLBACKS_TABLE;
 
-#ifndef WINELIB
-
-extern LONG CALLBACK CallTo16_regs_     (const CONTEXT *context, INT32 offset);
-extern WORD CALLBACK CallTo16_word_     (FARPROC16);
-extern WORD CALLBACK CallTo16_word_w    (FARPROC16,WORD);
-extern LONG CALLBACK CallTo16_long_l    (FARPROC16,LONG);
-extern WORD CALLBACK CallTo16_word_ww   (FARPROC16,WORD,WORD);
-extern WORD CALLBACK CallTo16_word_wl   (FARPROC16,WORD,LONG);
-extern WORD CALLBACK CallTo16_word_ll   (FARPROC16,LONG,LONG);
-extern WORD CALLBACK CallTo16_word_www  (FARPROC16,WORD,WORD,WORD);
-extern WORD CALLBACK CallTo16_word_wwl  (FARPROC16,WORD,WORD,LONG);
-extern WORD CALLBACK CallTo16_word_wlw  (FARPROC16,WORD,LONG,WORD);
-extern LONG CALLBACK CallTo16_long_wwl  (FARPROC16,WORD,WORD,LONG);
-extern WORD CALLBACK CallTo16_word_llwl (FARPROC16,LONG,LONG,WORD,LONG);
-extern WORD CALLBACK CallTo16_word_lwll (FARPROC16,LONG,WORD,LONG,LONG);
-extern LONG CALLBACK CallTo16_long_wwwl (FARPROC16,WORD,WORD,WORD,LONG);
-extern WORD CALLBACK CallTo16_word_lwww (FARPROC16,LONG,WORD,WORD,WORD);
-extern WORD CALLBACK CallTo16_word_wwll (FARPROC16,WORD,WORD,LONG,LONG);
-extern WORD CALLBACK CallTo16_word_wllwl(FARPROC16,WORD,LONG,LONG,WORD,LONG);
-extern LONG CALLBACK CallTo16_long_lwwll(FARPROC16,LONG,WORD,WORD,LONG,LONG);
-extern WORD CALLBACK CallTo16_word_wwlll(FARPROC16,WORD,WORD,LONG,LONG,LONG);
-extern WORD CALLBACK CallTo16_word_wwwww(FARPROC16,WORD,WORD,WORD,WORD,WORD);
-extern WORD CALLBACK CallTo16_word_lwlll(FARPROC16,LONG,WORD,LONG,LONG,LONG);
-extern WORD CALLBACK CallTo16_word_llll (FARPROC16,LONG,LONG,LONG,LONG);
-extern LONG CALLBACK CallTo16_long_lwlll(FARPROC16,LONG,WORD,LONG,LONG,LONG);
-extern LONG CALLBACK CallTo16_word_lwwlllll(FARPROC16,LONG,WORD,WORD,LONG,LONG,
-                                            LONG,LONG,WORD);
-extern LONG CALLBACK CallTo16_long_lwwllwlllllw(FARPROC16,LONG,WORD,WORD,LONG,
-                                                LONG,WORD,LONG,LONG,LONG,LONG,
-                                                LONG,WORD);
-extern LONG CALLBACK CallTo16_word_lwwwwlwwwwllll(FARPROC16,LONG,WORD,WORD,
-                                                  WORD,WORD,LONG,WORD,WORD,
-                                                  WORD,WORD,LONG,LONG,LONG,
-                                                  LONG);
-
-#define CallDriverProc( func, dwId, msg, hdrvr, lparam1, lparam2 ) \
-    CallTo16_long_lwwll( func, dwId, msg, hdrvr, lparam1, lparam2 )
-#define CallDriverCallback( func, hdev, msg, user, lparam1, lparam2 ) \
-    CallTo16_word_wwlll( func, hdev, msg, user, lparam1, lparam2 )
-#define CallTimeFuncProc( func, id, msg, dwUser, dw1, dw2 ) \
-    CallTo16_word_wwlll( func, id, msg, dwUser, dw1, dw2 )
-#define CallWindowsExitProc( func, nExitType ) \
-    CallTo16_word_w( func, nExitType )
-#define CallWordBreakProc16( func, lpch, ichCurrent, cch, code ) \
-    CallTo16_word_lwww( func, lpch, ichCurrent, cch, code )
-
-#else  /* WINELIB */
-
-#define CallDriverProc( func, dwId, msg, hdrvr, lparam1, lparam2 ) \
-    (*func)( dwId, msg, hdrvr, lparam1, lparam2 )
-#define CallDriverCallback( func, hdev, msg, user, lparam1, lparam2 ) \
-    (*func)( hdev, msg, user, lparam1, lparam2 )
-#define CallTimeFuncProc( func, id, msg, dwUser, dw1, dw2 ) \
-    (*func)( id, msg, dwUser, dw1, dw2 )
-#define CallWindowsExitProc( func, nExitType ) \
-    (*func)( nExitType )
-#define CallWordBreakProc16( func, lpch, ichCurrent, cch, code ) \
-    (*func)( lpch, ichCurrent, cch, code )
-
-#endif  /* WINELIB */
-
+extern const CALLBACKS_TABLE *Callbacks;
 
 #endif /* __WINE_CALLBACK_H */
diff --git a/include/dc.h b/include/dc.h
index 192c2a3..f04a318 100644
--- a/include/dc.h
+++ b/include/dc.h
@@ -24,4 +24,7 @@
 
 extern const int DC_XROPfunction[];
 
+INT32 CLIPPING_IntersectClipRect( DC * dc, INT32 left, INT32 top,
+                                  INT32 right, INT32 bottom, UINT32 flags );
+
 #endif /* __WINE_DC_H */
diff --git a/include/dce.h b/include/dce.h
index 4fd109a..9718df6 100644
--- a/include/dce.h
+++ b/include/dce.h
@@ -20,6 +20,7 @@
 #define DCX_NORECOMPUTE      	0x00100000
 #define DCX_VALIDATE         	0x00200000
 
+#define DCX_DCEEMPTY		0x00000800
 #define DCX_DCEBUSY		0x00001000
 #define DCX_WINDOWPAINT		0x00020000
 #define DCX_KEEPCLIPRGN		0x00040000
@@ -47,7 +48,8 @@
 
 extern void  DCE_Init(void);
 extern DCE*  DCE_AllocDCE( HWND32 hWnd, DCE_TYPE type );
-extern void  DCE_FreeDCE( DCE *dce );
+extern DCE*  DCE_FreeDCE( DCE *dce );
+extern void  DCE_FreeWindowDCE( WND* );
 extern INT16 DCE_ExcludeRgn( HDC32, WND*, HRGN32 );
 extern HRGN32 DCE_GetVisRgn( HWND32, WORD );
 extern BOOL32 DCE_InvalidateDCE( WND*, RECT32* );
diff --git a/include/debug.h b/include/debug.h
index fc4dae8..365c0ea 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -7,6 +7,7 @@
 
 #ifdef DEBUG_NONE_EXT
 #undef DEBUG_ACCEL
+#undef DEBUG_ASPI
 #undef DEBUG_ATOM
 #undef DEBUG_BITBLT
 #undef DEBUG_BITMAP
@@ -27,7 +28,6 @@
 #undef DEBUG_DOSFS
 #undef DEBUG_DRIVER
 #undef DEBUG_EDIT
-#undef DEBUG_ENV
 #undef DEBUG_EVENT
 #undef DEBUG_EXEC
 #undef DEBUG_FILE
@@ -93,6 +93,7 @@
 
 #ifdef DEBUG_ALL_EXT
 #define DEBUG_ACCEL
+#define DEBUG_ASPI
 #define DEBUG_ATOM
 #define DEBUG_BITBLT
 #define DEBUG_BITMAP
@@ -113,7 +114,6 @@
 #define DEBUG_DOSFS
 #define DEBUG_DRIVER
 #define DEBUG_EDIT
-#define DEBUG_ENV
 #define DEBUG_EVENT
 #define DEBUG_EXEC
 #define DEBUG_FILE
@@ -185,6 +185,11 @@
 #else
     0,
 #endif
+#ifdef DEBUG_ASPI
+    1,
+#else
+    0,
+#endif
 #ifdef DEBUG_ATOM
     1,
 #else
@@ -285,11 +290,6 @@
 #else
     0,
 #endif
-#ifdef DEBUG_ENV
-    1,
-#else
-    0,
-#endif
 #ifdef DEBUG_EVENT
     1,
 #else
@@ -616,8 +616,21 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_atom if(!debug_msg_enabled[1]) ; else fprintf
-#define debugging_atom debug_msg_enabled[1]
+#define dprintf_aspi if(!debug_msg_enabled[1]) ; else fprintf
+#define debugging_aspi debug_msg_enabled[1]
+#else
+#ifdef DEBUG_ASPI
+#define dprintf_aspi fprintf
+#define debugging_aspi 1
+#else
+#define dprintf_aspi while(0) fprintf
+#define debugging_aspi 0
+#endif
+#endif
+
+#ifdef DEBUG_RUNTIME
+#define dprintf_atom if(!debug_msg_enabled[2]) ; else fprintf
+#define debugging_atom debug_msg_enabled[2]
 #else
 #ifdef DEBUG_ATOM
 #define dprintf_atom fprintf
@@ -629,8 +642,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_bitblt if(!debug_msg_enabled[2]) ; else fprintf
-#define debugging_bitblt debug_msg_enabled[2]
+#define dprintf_bitblt if(!debug_msg_enabled[3]) ; else fprintf
+#define debugging_bitblt debug_msg_enabled[3]
 #else
 #ifdef DEBUG_BITBLT
 #define dprintf_bitblt fprintf
@@ -642,8 +655,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_bitmap if(!debug_msg_enabled[3]) ; else fprintf
-#define debugging_bitmap debug_msg_enabled[3]
+#define dprintf_bitmap if(!debug_msg_enabled[4]) ; else fprintf
+#define debugging_bitmap debug_msg_enabled[4]
 #else
 #ifdef DEBUG_BITMAP
 #define dprintf_bitmap fprintf
@@ -655,8 +668,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_caret if(!debug_msg_enabled[4]) ; else fprintf
-#define debugging_caret debug_msg_enabled[4]
+#define dprintf_caret if(!debug_msg_enabled[5]) ; else fprintf
+#define debugging_caret debug_msg_enabled[5]
 #else
 #ifdef DEBUG_CARET
 #define dprintf_caret fprintf
@@ -668,8 +681,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_cdaudio if(!debug_msg_enabled[5]) ; else fprintf
-#define debugging_cdaudio debug_msg_enabled[5]
+#define dprintf_cdaudio if(!debug_msg_enabled[6]) ; else fprintf
+#define debugging_cdaudio debug_msg_enabled[6]
 #else
 #ifdef DEBUG_CDAUDIO
 #define dprintf_cdaudio fprintf
@@ -681,8 +694,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_class if(!debug_msg_enabled[6]) ; else fprintf
-#define debugging_class debug_msg_enabled[6]
+#define dprintf_class if(!debug_msg_enabled[7]) ; else fprintf
+#define debugging_class debug_msg_enabled[7]
 #else
 #ifdef DEBUG_CLASS
 #define dprintf_class fprintf
@@ -694,8 +707,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_clipboard if(!debug_msg_enabled[7]) ; else fprintf
-#define debugging_clipboard debug_msg_enabled[7]
+#define dprintf_clipboard if(!debug_msg_enabled[8]) ; else fprintf
+#define debugging_clipboard debug_msg_enabled[8]
 #else
 #ifdef DEBUG_CLIPBOARD
 #define dprintf_clipboard fprintf
@@ -707,8 +720,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_clipping if(!debug_msg_enabled[8]) ; else fprintf
-#define debugging_clipping debug_msg_enabled[8]
+#define dprintf_clipping if(!debug_msg_enabled[9]) ; else fprintf
+#define debugging_clipping debug_msg_enabled[9]
 #else
 #ifdef DEBUG_CLIPPING
 #define dprintf_clipping fprintf
@@ -720,8 +733,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_combo if(!debug_msg_enabled[9]) ; else fprintf
-#define debugging_combo debug_msg_enabled[9]
+#define dprintf_combo if(!debug_msg_enabled[10]) ; else fprintf
+#define debugging_combo debug_msg_enabled[10]
 #else
 #ifdef DEBUG_COMBO
 #define dprintf_combo fprintf
@@ -733,8 +746,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_comm if(!debug_msg_enabled[10]) ; else fprintf
-#define debugging_comm debug_msg_enabled[10]
+#define dprintf_comm if(!debug_msg_enabled[11]) ; else fprintf
+#define debugging_comm debug_msg_enabled[11]
 #else
 #ifdef DEBUG_COMM
 #define dprintf_comm fprintf
@@ -746,8 +759,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_commdlg if(!debug_msg_enabled[11]) ; else fprintf
-#define debugging_commdlg debug_msg_enabled[11]
+#define dprintf_commdlg if(!debug_msg_enabled[12]) ; else fprintf
+#define debugging_commdlg debug_msg_enabled[12]
 #else
 #ifdef DEBUG_COMMDLG
 #define dprintf_commdlg fprintf
@@ -759,8 +772,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_crtdll if(!debug_msg_enabled[12]) ; else fprintf
-#define debugging_crtdll debug_msg_enabled[12]
+#define dprintf_crtdll if(!debug_msg_enabled[13]) ; else fprintf
+#define debugging_crtdll debug_msg_enabled[13]
 #else
 #ifdef DEBUG_CRTDLL
 #define dprintf_crtdll fprintf
@@ -772,8 +785,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_cursor if(!debug_msg_enabled[13]) ; else fprintf
-#define debugging_cursor debug_msg_enabled[13]
+#define dprintf_cursor if(!debug_msg_enabled[14]) ; else fprintf
+#define debugging_cursor debug_msg_enabled[14]
 #else
 #ifdef DEBUG_CURSOR
 #define dprintf_cursor fprintf
@@ -785,8 +798,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_dc if(!debug_msg_enabled[14]) ; else fprintf
-#define debugging_dc debug_msg_enabled[14]
+#define dprintf_dc if(!debug_msg_enabled[15]) ; else fprintf
+#define debugging_dc debug_msg_enabled[15]
 #else
 #ifdef DEBUG_DC
 #define dprintf_dc fprintf
@@ -798,8 +811,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_dde if(!debug_msg_enabled[15]) ; else fprintf
-#define debugging_dde debug_msg_enabled[15]
+#define dprintf_dde if(!debug_msg_enabled[16]) ; else fprintf
+#define debugging_dde debug_msg_enabled[16]
 #else
 #ifdef DEBUG_DDE
 #define dprintf_dde fprintf
@@ -811,8 +824,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_dialog if(!debug_msg_enabled[16]) ; else fprintf
-#define debugging_dialog debug_msg_enabled[16]
+#define dprintf_dialog if(!debug_msg_enabled[17]) ; else fprintf
+#define debugging_dialog debug_msg_enabled[17]
 #else
 #ifdef DEBUG_DIALOG
 #define dprintf_dialog fprintf
@@ -824,8 +837,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_dll if(!debug_msg_enabled[17]) ; else fprintf
-#define debugging_dll debug_msg_enabled[17]
+#define dprintf_dll if(!debug_msg_enabled[18]) ; else fprintf
+#define debugging_dll debug_msg_enabled[18]
 #else
 #ifdef DEBUG_DLL
 #define dprintf_dll fprintf
@@ -837,8 +850,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_dosfs if(!debug_msg_enabled[18]) ; else fprintf
-#define debugging_dosfs debug_msg_enabled[18]
+#define dprintf_dosfs if(!debug_msg_enabled[19]) ; else fprintf
+#define debugging_dosfs debug_msg_enabled[19]
 #else
 #ifdef DEBUG_DOSFS
 #define dprintf_dosfs fprintf
@@ -850,8 +863,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_driver if(!debug_msg_enabled[19]) ; else fprintf
-#define debugging_driver debug_msg_enabled[19]
+#define dprintf_driver if(!debug_msg_enabled[20]) ; else fprintf
+#define debugging_driver debug_msg_enabled[20]
 #else
 #ifdef DEBUG_DRIVER
 #define dprintf_driver fprintf
@@ -863,8 +876,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_edit if(!debug_msg_enabled[20]) ; else fprintf
-#define debugging_edit debug_msg_enabled[20]
+#define dprintf_edit if(!debug_msg_enabled[21]) ; else fprintf
+#define debugging_edit debug_msg_enabled[21]
 #else
 #ifdef DEBUG_EDIT
 #define dprintf_edit fprintf
@@ -876,19 +889,6 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_env if(!debug_msg_enabled[21]) ; else fprintf
-#define debugging_env debug_msg_enabled[21]
-#else
-#ifdef DEBUG_ENV
-#define dprintf_env fprintf
-#define debugging_env 1
-#else
-#define dprintf_env while(0) fprintf
-#define debugging_env 0
-#endif
-#endif
-
-#ifdef DEBUG_RUNTIME
 #define dprintf_event if(!debug_msg_enabled[22]) ; else fprintf
 #define debugging_event debug_msg_enabled[22]
 #else
@@ -1686,6 +1686,7 @@
 #ifdef DEBUG_DEFINE_VARIABLES
 static char *debug_msg_name[] = {
     "accel",
+    "aspi",
     "atom",
     "bitblt",
     "bitmap",
@@ -1706,7 +1707,6 @@
     "dosfs",
     "driver",
     "edit",
-    "env",
     "event",
     "exec",
     "file",
diff --git a/include/debugger.h b/include/debugger.h
index 9117373..2d7d025 100644
--- a/include/debugger.h
+++ b/include/debugger.h
@@ -145,6 +145,7 @@
 extern void DEBUG_DelBreakpoint( int num );
 extern void DEBUG_EnableBreakpoint( int num, BOOL32 enable );
 extern void DEBUG_InfoBreakpoints(void);
+extern void DEBUG_AddModuleBreakpoints(void);
 extern BOOL32 DEBUG_HandleTrap(void);
 extern BOOL32 DEBUG_ShouldContinue( enum exec_mode mode, int * count );
 extern enum exec_mode DEBUG_RestartExecution( enum exec_mode mode, int count );
diff --git a/include/drive.h b/include/drive.h
index f129bed..3520a1b 100644
--- a/include/drive.h
+++ b/include/drive.h
@@ -43,5 +43,6 @@
 extern int DRIVE_Chdir( int drive, const char *path );
 extern int DRIVE_Disable( int drive  );
 extern int DRIVE_Enable( int drive  );
+extern int DRIVE_SetLogicalMapping ( int existing_drive, int new_drive );
 
 #endif  /* __WINE_DRIVE_H */
diff --git a/include/file.h b/include/file.h
index bb33157..badc67a 100644
--- a/include/file.h
+++ b/include/file.h
@@ -43,10 +43,15 @@
 extern HFILE32 FILE_Dup2( HFILE32 hFile1, HFILE32 hFile2 );
 extern HFILE32 FILE_Open( LPCSTR path, INT32 mode );
 extern BOOL32 FILE_SetFileType( HFILE32 hFile, DWORD type );
-extern LPVOID FILE_mmap( FILE_OBJECT *file, LPVOID start,
+extern LPVOID FILE_mmap( HFILE32 hFile, LPVOID start,
                          DWORD size_high, DWORD size_low,
                          DWORD offset_high, DWORD offset_low,
                          int prot, int flags );
+extern LPVOID FILE_dommap( FILE_OBJECT *file, LPVOID start,
+                           DWORD size_high, DWORD size_low,
+                           DWORD offset_high, DWORD offset_low,
+                         int prot, int flags );
+extern int FILE_munmap( LPVOID start, DWORD size_high, DWORD size_low );
 extern HFILE32 _lcreat_uniq( LPCSTR path, INT32 attr );
 
 /* files/directory.c */
diff --git a/include/gdi.h b/include/gdi.h
index 17e2741..4f2c4e1 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -34,6 +34,21 @@
 } GDIOBJHDR;
 
 
+#define OBJ_PEN             1 
+#define OBJ_BRUSH           2 
+#define OBJ_DC              3 
+#define OBJ_METADC          4 
+#define OBJ_PAL             5 
+#define OBJ_FONT            6 
+#define OBJ_BITMAP          7 
+#define OBJ_REGION          8 
+#define OBJ_METAFILE        9 
+#define OBJ_MEMDC           10 
+#define OBJ_EXTPEN          11 
+#define OBJ_ENHMETADC       12 
+#define OBJ_ENHMETAFILE     13 
+
+
 typedef struct tagDeviceCaps
 {
     WORD   version;       /*   0: driver version */
diff --git a/include/mmsystem.h b/include/mmsystem.h
index 73b46d4..dce9cb0 100644
--- a/include/mmsystem.h
+++ b/include/mmsystem.h
@@ -8,35 +8,68 @@
 typedef LPSTR		    HPSTR;          /* a huge version of LPSTR */
 typedef LPCSTR			HPCSTR;         /* a huge version of LPCSTR */
 
-#define MAXWAVEDRIVERS 10
-#define MAXMIDIDRIVERS 10
-#define MAXAUXDRIVERS 10
-#define MAXMCIDRIVERS 32
+#pragma pack(1)
+
+#define MAXWAVEDRIVERS	10
+#define MAXMIDIDRIVERS	10
+#define MAXAUXDRIVERS	10
+#define MAXMCIDRIVERS	32
+#define MAXMIXERDRIVERS	10
 
 #define MAXPNAMELEN      32     /* max product name length (including NULL) */
 #define MAXERRORLENGTH   128    /* max error text length (including NULL) */
 
 typedef WORD    VERSION;        /* major (high byte), minor (low byte) */
 
+typedef UINT16	MMVERSION16;
+typedef UINT32	MMVERSION32;
+DECL_WINELIB_TYPE(MMVERSION);
+typedef UINT16	MCIDEVICEID16;
+typedef UINT32	MCIDEVICEID32;
+DECL_WINELIB_TYPE(MCIDEVICE);
+
 typedef struct {
-    UINT16    wType;              /* indicates the contents of the union */
+    UINT16    wType;		/* indicates the contents of the union */
     union {
-        DWORD ms;               /* milliseconds */
-        DWORD sample;           /* samples */
-        DWORD cb;               /* byte count */
-        struct {                /* SMPTE */
-            BYTE hour;          /* hours */
-            BYTE min;           /* minutes */
-            BYTE sec;           /* seconds */
-            BYTE frame;         /* frames  */
-            BYTE fps;           /* frames per second */
-            BYTE dummy;         /* pad */
-            } smpte;
-        struct {                /* MIDI */
-            DWORD songptrpos;   /* song pointer position */
-            } midi;
-        } u;
-} MMTIME,  *LPMMTIME;
+	DWORD ms;		/* milliseconds */
+	DWORD sample;		/* samples */
+	DWORD cb;		/* byte count */
+	struct {		/* SMPTE */
+	    BYTE hour;		/* hours */
+	    BYTE min;		/* minutes */
+	    BYTE sec;		/* seconds */
+	    BYTE frame;		/* frames  */
+	    BYTE fps;		/* frames per second */
+	    BYTE dummy;		/* pad */
+	} smpte;
+	struct {		/* MIDI */
+	    DWORD songptrpos;	/* song pointer position */
+	} midi;
+    } u;
+} MMTIME16,  *LPMMTIME16;
+
+typedef struct {
+    UINT32    wType;
+    union {
+	DWORD ms;
+	DWORD sample;
+	DWORD cb;
+	struct {
+	    BYTE hour;
+	    BYTE min;
+	    BYTE sec;
+	    BYTE frame;
+	    BYTE fps;
+	    BYTE dummy;
+	    BYTE pad[2];
+	} smpte;
+	struct {
+	    DWORD songptrpos;
+	} midi;
+    } u;
+} MMTIME32,  *LPMMTIME32;
+DECL_WINELIB_TYPE(MMTIME);
+DECL_WINELIB_TYPE(LPMMTIME);
 
 #define TIME_MS         0x0001  /* time in milliseconds */
 #define TIME_SAMPLES    0x0002  /* number of wave samples */
@@ -129,7 +162,9 @@
 #define MM_PC_JOYSTICK          12      /* Joystick adapter */
 
 
-WORD WINAPI mmsystemGetVersion(void);
+UINT16 WINAPI mmsystemGetVersion16(void);
+UINT32 WINAPI mmsystemGetVersion32(void);
+#define mmsystemGetVersion WINELIB_NAME(mmsystemGetVersion)
 BOOL16 WINAPI sndPlaySound(LPCSTR lpszSoundName, UINT16 uFlags);
 BOOL32 WINAPI PlaySound32A(LPCSTR pszSound, HMODULE32 hmod, DWORD fdwSound);
 BOOL32 WINAPI PlaySound32W(LPCWSTR pszSound, HMODULE32 hmod, DWORD fdwSound);
@@ -158,6 +193,8 @@
 typedef HWAVEIN16 *LPHWAVEIN16;
 typedef HWAVEOUT16 *LPHWAVEOUT16;
 typedef LPDRVCALLBACK LPWAVECALLBACK;
+typedef HMIXER16 *LPHMIXER16;
+typedef HMIXER32 *LPHMIXER32;
 
 #define WOM_OPEN        MM_WOM_OPEN
 #define WOM_CLOSE       MM_WOM_CLOSE
@@ -172,15 +209,15 @@
 #define  WAVE_ALLOWSYNC        0x0002
 
 typedef struct wavehdr_tag {
-    LPSTR       lpData;                 /* pointer to locked data buffer */
-    DWORD       dwBufferLength;         /* length of data buffer */
-    DWORD       dwBytesRecorded;        /* used for input only */
-    DWORD       dwUser;                 /* for client's use */
-    DWORD       dwFlags;                /* assorted flags (see defines) */
-    DWORD       dwLoops;                /* loop control counter */
-/*    struct wavehdr_tag *lpNext;*/         
-    SEGPTR      lp16Next;               /* reserved for driver */
-    DWORD       reserved;               /* reserved for driver */
+    LPSTR       lpData;		/* pointer to locked data buffer */
+    DWORD       dwBufferLength;	/* length of data buffer */
+    DWORD       dwBytesRecorded;/* used for input only */
+    DWORD       dwUser;		/* for client's use */
+    DWORD       dwFlags;	/* assorted flags (see defines) */
+    DWORD       dwLoops;	/* loop control counter */
+
+    struct wavehdr_tag *lpNext;	/* reserved for driver */
+    DWORD       reserved;	/* reserved for driver */
 } WAVEHDR, *LPWAVEHDR;
 
 #define WHDR_DONE       0x00000001  /* done bit */
@@ -190,14 +227,38 @@
 #define WHDR_INQUEUE    0x00000010  /* reserved for driver */
 
 typedef struct {
-    UINT16    wMid;                  /* manufacturer ID */
-    UINT16    wPid;                  /* product ID */
-    VERSION vDriverVersion;        /* version of the driver */
-    char    szPname[MAXPNAMELEN];  /* product name (NULL terminated string) */
-    DWORD   dwFormats WINE_PACKED;             /* formats supported */
-    UINT16    wChannels;             /* number of sources supported */
-    DWORD   dwSupport WINE_PACKED;             /* functionality supported by driver */
-} WAVEOUTCAPS, *LPWAVEOUTCAPS;
+    WORD	wMid;			/* manufacturer ID */
+    WORD	wPid;			/* product ID */
+    MMVERSION16	vDriverVersion;		/* version of the driver */
+    CHAR	szPname[MAXPNAMELEN];	/* product name (0 terminated string) */
+    DWORD	dwFormats;		/* formats supported */
+    WORD	wChannels;		/* number of sources supported */
+    DWORD	dwSupport;		/* functionality supported by driver */
+} WAVEOUTCAPS16, *LPWAVEOUTCAPS16;
+
+typedef struct {
+    WORD	wMid;			/* manufacturer ID */
+    WORD	wPid;			/* product ID */
+    MMVERSION32	vDriverVersion;		/* version of the driver */
+    CHAR	szPname[MAXPNAMELEN];	/* product name (0 terminated string) */
+    DWORD	dwFormats;		/* formats supported */
+    WORD	wChannels;		/* number of sources supported */
+    WORD	wReserved1;		/* padding */
+    DWORD	dwSupport;		/* functionality supported by driver */
+} WAVEOUTCAPS32A, *LPWAVEOUTCAPS32A;
+
+typedef struct {
+    WORD	wMid;			/* manufacturer ID */
+    WORD	wPid;			/* product ID */
+    MMVERSION32	vDriverVersion;		/* version of the driver */
+    WCHAR	szPname[MAXPNAMELEN];	/* product name (0 terminated string) */
+    DWORD	dwFormats;		/* formats supported */
+    WORD	wChannels;		/* number of sources supported */
+    WORD	wReserved1;		/* padding */
+    DWORD	dwSupport;		/* functionality supported by driver */
+} WAVEOUTCAPS32W, *LPWAVEOUTCAPS32W;
+DECL_WINELIB_TYPE(WAVEOUTCAPS);
+DECL_WINELIB_TYPE(LPWAVEOUTCAPS);
 
 #define WAVECAPS_PITCH          0x0001   /* supports pitch control */
 #define WAVECAPS_PLAYBACKRATE   0x0002   /* supports playback rate control */
@@ -206,13 +267,34 @@
 #define WAVECAPS_SYNC           0x0010
 
 typedef struct {
-    UINT16    wMid;                    /* manufacturer ID */
-    UINT16    wPid;                    /* product ID */
-    VERSION vDriverVersion;          /* version of the driver */
-    char    szPname[MAXPNAMELEN];    /* product name (NULL terminated string) */
-    DWORD   dwFormats WINE_PACKED;               /* formats supported */
-    UINT16    wChannels;               /* number of channels supported */
-} WAVEINCAPS, *LPWAVEINCAPS;
+    WORD	wMid;			/* manufacturer ID */
+    WORD	wPid;			/* product ID */
+    MMVERSION16	vDriverVersion;		/* version of the driver */
+    CHAR	szPname[MAXPNAMELEN];	/* product name (0 terminated string) */
+    DWORD	dwFormats;		/* formats supported */
+    WORD	wChannels;		/* number of channels supported */
+} WAVEINCAPS16, *LPWAVEINCAPS16;
+
+typedef struct {
+    WORD	wMid;			/* manufacturer ID */
+    WORD	wPid;			/* product ID */
+    MMVERSION32	vDriverVersion;		/* version of the driver */
+    CHAR	szPname[MAXPNAMELEN];	/* product name (0 terminated string) */
+    DWORD	dwFormats;		/* formats supported */
+    WORD	wChannels;		/* number of channels supported */
+    WORD	wReserved1;
+} WAVEINCAPS32A, *LPWAVEINCAPS32A;
+typedef struct {
+    WORD	wMid;			/* manufacturer ID */
+    WORD	wPid;			/* product ID */
+    MMVERSION32	vDriverVersion;		/* version of the driver */
+    WCHAR	szPname[MAXPNAMELEN];	/* product name (0 terminated string) */
+    DWORD	dwFormats;		/* formats supported */
+    WORD	wChannels;		/* number of channels supported */
+    WORD	wReserved1;
+} WAVEINCAPS32W, *LPWAVEINCAPS32W;
+DECL_WINELIB_TYPE(WAVEINCAPS);
+DECL_WINELIB_TYPE(LPWAVEINCAPS);
 
 #define WAVE_INVALIDFORMAT     0x00000000       /* invalid format */
 #define WAVE_FORMAT_1M08       0x00000001       /* 11.025 kHz, Mono,   8-bit  */
@@ -228,76 +310,145 @@
 #define WAVE_FORMAT_4M16       0x00000400       /* 44.1   kHz, Mono,   16-bit */
 #define WAVE_FORMAT_4S16       0x00000800       /* 44.1   kHz, Stereo, 16-bit */
 
-/* general format structure common to all formats */
+/* General format structure common to all formats, same for Win16 and Win32 */
 typedef struct {
-    WORD    wFormatTag;						/* format type */
-    WORD    nChannels; 						/* number of channels */
-    DWORD   nSamplesPerSec WINE_PACKED;		/* sample rate */
-    DWORD   nAvgBytesPerSec WINE_PACKED;	/* for buffer estimation */
-    WORD    nBlockAlign; 					/* block size of data */
+    WORD	wFormatTag;	/* format type */
+    WORD	nChannels;	/* number of channels */
+    DWORD	nSamplesPerSec;	/* sample rate */
+    DWORD	nAvgBytesPerSec;/* for buffer estimation */
+    WORD	nBlockAlign; 	/* block size of data */
 } WAVEFORMAT, *LPWAVEFORMAT;
 
 #define WAVE_FORMAT_PCM     1
 
 typedef struct {
-    WAVEFORMAT  wf;
-    WORD        wBitsPerSample;
+    WAVEFORMAT	wf;
+    WORD	wBitsPerSample;
 } PCMWAVEFORMAT, *LPPCMWAVEFORMAT;
 
-UINT16 WINAPI waveOutGetNumDevs(void);
-UINT16 WINAPI waveOutGetDevCaps(UINT16 uDeviceID, WAVEOUTCAPS * lpCaps,
-                                UINT16 uSize);
-UINT16 WINAPI waveOutGetVolume(UINT16 uDeviceID, DWORD * lpdwVolume);
-UINT16 WINAPI waveOutSetVolume(UINT16 uDeviceID, DWORD dwVolume);
-UINT16 WINAPI waveOutGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize);
-UINT16 WINAPI waveGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize);
-UINT16 WINAPI waveOutOpen(HWAVEOUT16 * lphWaveOut, UINT16 uDeviceID,
-    const LPWAVEFORMAT lpFormat, DWORD dwCallback, DWORD dwInstance, DWORD dwFlags);
-UINT16 WINAPI waveOutClose(HWAVEOUT16 hWaveOut);
-UINT16 WINAPI waveOutPrepareHeader(HWAVEOUT16 hWaveOut,
-                                   WAVEHDR *lpWaveOutHdr, UINT16 uSize);
-UINT16 WINAPI waveOutUnprepareHeader(HWAVEOUT16 hWaveOut,
-                                     WAVEHDR *lpWaveOutHdr, UINT16 uSize);
-UINT16 WINAPI waveOutWrite(HWAVEOUT16 hWaveOut, WAVEHDR * lpWaveOutHdr,
-                           UINT16 uSize);
-UINT16 WINAPI waveOutPause(HWAVEOUT16 hWaveOut);
-UINT16 WINAPI waveOutRestart(HWAVEOUT16 hWaveOut);
-UINT16 WINAPI waveOutReset(HWAVEOUT16 hWaveOut);
-UINT16 WINAPI waveOutBreakLoop(HWAVEOUT16 hWaveOut);
-UINT16 WINAPI waveOutGetPosition(HWAVEOUT16 hWaveOut, MMTIME * lpInfo,
-                                 UINT16 uSize);
-UINT16 WINAPI waveOutGetPitch(HWAVEOUT16 hWaveOut, DWORD * lpdwPitch);
-UINT16 WINAPI waveOutSetPitch(HWAVEOUT16 hWaveOut, DWORD dwPitch);
-UINT16 WINAPI waveOutGetPlaybackRate(HWAVEOUT16 hWaveOut, DWORD * lpdwRate);
-UINT16 WINAPI waveOutSetPlaybackRate(HWAVEOUT16 hWaveOut, DWORD dwRate);
-UINT16 WINAPI waveOutGetID(HWAVEOUT16 hWaveOut, UINT16 * lpuDeviceID);
+/* dito same for Win16 / Win32 */
+typedef struct {
+    WORD	wFormatTag;	/* format type */
+    WORD	nChannels;	/* number of channels (i.e. mono, stereo...) */
+    DWORD	nSamplesPerSec;	/* sample rate */
+    DWORD	nAvgBytesPerSec;/* for buffer estimation */
+    WORD	nBlockAlign;	/* block size of data */
+    WORD	wBitsPerSample;	/* number of bits per sample of mono data */
+    WORD	cbSize;		/* the count in bytes of the size of */
+				/* extra information (after cbSize) */
+} WAVEFORMATEX,*LPWAVEFORMATEX;
 
-DWORD WINAPI waveOutMessage(HWAVEOUT16 hWaveOut, UINT16 uMessage, DWORD dw1,
-                            DWORD dw2);
+UINT16 WINAPI waveOutGetNumDevs16();
+UINT32 WINAPI waveOutGetNumDevs32();
+#define waveOutGetNumDevs WINELIB_NAME(waveOutGetNumDevs)
+UINT16 WINAPI waveOutGetDevCaps16(UINT16,LPWAVEOUTCAPS16,UINT16);
+UINT32 WINAPI waveOutGetDevCaps32A(UINT32,LPWAVEOUTCAPS32A,UINT32);
+UINT32 WINAPI waveOutGetDevCaps32W(UINT32,LPWAVEOUTCAPS32W,UINT32);
+#define waveOutGetDevCaps WINELIB_NAME_AW(waveOutGetDevCaps)
+UINT16 WINAPI waveOutGetVolume16(UINT16,DWORD*);
+UINT32 WINAPI waveOutGetVolume32(UINT32,DWORD*);
+#define waveOutGetVolume WINELIB_NAME(waveOutGetVolume)
+UINT16 WINAPI waveOutSetVolume16(UINT16,DWORD);
+UINT32 WINAPI waveOutSetVolume32(UINT32,DWORD);
+#define waveOutSetVolume WINELIB_NAME(waveOutSetVolume)
+UINT16 WINAPI waveOutGetErrorText16(UINT16,LPSTR,UINT16);
+UINT32 WINAPI waveOutGetErrorText32A(UINT32,LPSTR,UINT32);
+UINT32 WINAPI waveOutGetErrorText32W(UINT32,LPWSTR,UINT32);
+#define waveOutGetErrorText WINELIB_NAME_AW(waveOutGetErrorText)
+UINT16 WINAPI waveOutOpen16(HWAVEOUT16*,UINT16,const LPWAVEFORMATEX,DWORD,DWORD,DWORD);
+UINT32 WINAPI waveOutOpen32(HWAVEOUT32*,UINT32,const LPWAVEFORMATEX,DWORD,DWORD,DWORD);
+#define waveOutOpen WINELIB_NAME(waveOutOpen)
+UINT16 WINAPI waveOutClose16(HWAVEOUT16);
+UINT32 WINAPI waveOutClose32(HWAVEOUT32);
+#define waveOutClose WINELIB_NAME(waveOutClose)
+UINT16 WINAPI waveOutPrepareHeader16(HWAVEOUT16,WAVEHDR*,UINT16);
+UINT32 WINAPI waveOutPrepareHeader32(HWAVEOUT32,WAVEHDR*,UINT32);
+#define waveOutPrepareHeader WINELIB_NAME(waveOutPrepareHeader)
+UINT16 WINAPI waveOutUnprepareHeader16(HWAVEOUT16,WAVEHDR*,UINT16);
+UINT32 WINAPI waveOutUnprepareHeader32(HWAVEOUT32,WAVEHDR*,UINT32);
+#define waveOutUnprepareHeader WINELIB_NAME(waveOutUnprepareHeader)
+UINT16 WINAPI waveOutWrite16(HWAVEOUT16,WAVEHDR*,UINT16);
+UINT32 WINAPI waveOutWrite32(HWAVEOUT32,WAVEHDR*,UINT32);
+#define waveOutWrite WINELIB_NAME(waveOutWrite)
+UINT16 WINAPI waveOutPause16(HWAVEOUT16);
+UINT32 WINAPI waveOutPause32(HWAVEOUT32);
+#define waveOutPause WINELIB_NAME(waveOutPause)
+UINT16 WINAPI waveOutRestart16(HWAVEOUT16);
+UINT32 WINAPI waveOutRestart32(HWAVEOUT32);
+#define waveOutRestart WINELIB_NAME(waveOutRestart)
+UINT16 WINAPI waveOutReset16(HWAVEOUT16);
+UINT32 WINAPI waveOutReset32(HWAVEOUT32);
+#define waveOutReset WINELIB_NAME(waveOutReset)
+UINT16 WINAPI waveOutBreakLoop16(HWAVEOUT16);
+UINT32 WINAPI waveOutBreakLoop32(HWAVEOUT32);
+#define waveOutBreakLoop WINELIB_NAME(waveOutBreakLoop)
+UINT16 WINAPI waveOutGetPosition16(HWAVEOUT16,LPMMTIME16,UINT16);
+UINT32 WINAPI waveOutGetPosition32(HWAVEOUT32,LPMMTIME32,UINT32);
+#define waveOutGetPosition WINELIB_NAME(waveOutGetPosition)
+UINT16 WINAPI waveOutGetPitch16(HWAVEOUT16,DWORD*);
+UINT32 WINAPI waveOutGetPitch32(HWAVEOUT32,DWORD*);
+#define waveOutGetPitch WINELIB_NAME(waveOutGetPitch)
+UINT16 WINAPI waveOutSetPitch16(HWAVEOUT16,DWORD);
+UINT32 WINAPI waveOutSetPitch32(HWAVEOUT32,DWORD);
+#define waveOutSetPitch WINELIB_NAME(waveOutSetPitch)
+UINT16 WINAPI waveOutGetPlaybackRate16(HWAVEOUT16,DWORD*);
+UINT32 WINAPI waveOutGetPlaybackRate32(HWAVEOUT32,DWORD*);
+#define waveOutGetPlaybackRate WINELIB_NAME(waveOutGetPlaybackRate)
+UINT16 WINAPI waveOutSetPlaybackRate16(HWAVEOUT16,DWORD);
+UINT32 WINAPI waveOutSetPlaybackRate32(HWAVEOUT32,DWORD);
+#define waveOutSetPlaybackRate WINELIB_NAME(waveOutSetPlaybackRate)
+UINT16 WINAPI waveOutGetID16(HWAVEOUT16,UINT16*);
+UINT32 WINAPI waveOutGetID32(HWAVEOUT32,UINT32*);
+#define waveOutGetID WINELIB_NAME(waveOutGetID)
+DWORD WINAPI waveOutMessage16(HWAVEOUT16,UINT16,DWORD,DWORD);
+DWORD WINAPI waveOutMessage32(HWAVEOUT32,UINT32,DWORD,DWORD);
+#define waveOutMessage WINELIB_NAME(waveOutMessage)
 
-UINT16 WINAPI waveInGetNumDevs(void);
-UINT16 WINAPI waveInGetDevCaps(UINT16 uDeviceID, WAVEINCAPS * lpCaps,
-                               UINT16 uSize);
-UINT16 WINAPI waveInGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize);
-UINT16 WINAPI waveInOpen(HWAVEIN16 * lphWaveIn, UINT16 uDeviceID,
-                         const LPWAVEFORMAT lpFormat, DWORD dwCallback,
-                         DWORD dwInstance, DWORD dwFlags);
-UINT16 WINAPI waveInClose(HWAVEIN16 hWaveIn);
-UINT16 WINAPI waveInPrepareHeader(HWAVEIN16 hWaveIn, WAVEHDR * lpWaveInHdr,
-                                  UINT16 uSize);
-UINT16 WINAPI waveInUnprepareHeader(HWAVEIN16 hWaveIn, WAVEHDR * lpWaveInHdr,
-                                    UINT16 uSize);
-UINT16 WINAPI waveInAddBuffer(HWAVEIN16 hWaveIn, WAVEHDR * lpWaveInHdr,
-                              UINT16 uSize);
-UINT16 WINAPI waveInStart(HWAVEIN16 hWaveIn);
-UINT16 WINAPI waveInStop(HWAVEIN16 hWaveIn);
-UINT16 WINAPI waveInReset(HWAVEIN16 hWaveIn);
-UINT16 WINAPI waveInGetPosition(HWAVEIN16 hWaveIn, MMTIME * lpInfo,
-                                UINT16 uSize);
-UINT16 WINAPI waveInGetID(HWAVEIN16 hWaveIn, UINT16 * lpuDeviceID);
+UINT16 WINAPI waveInGetNumDevs16();
+UINT32 WINAPI waveInGetNumDevs32();
+#define waveInGetNumDevs WINELIB_NAME(waveInGetNumDevs)
+UINT16 WINAPI waveInGetDevCaps16(UINT16,LPWAVEINCAPS16,UINT16);
+UINT32 WINAPI waveInGetDevCaps32A(UINT32,LPWAVEINCAPS32A,UINT32);
+UINT32 WINAPI waveInGetDevCaps32W(UINT32,LPWAVEINCAPS32W,UINT32);
+#define waveInGetDevCaps WINELIB_NAME_AW(waveInGetDevCaps)
+UINT16 WINAPI waveInGetErrorText16(UINT16,LPSTR,UINT16);
+UINT32 WINAPI waveInGetErrorText32A(UINT32,LPSTR,UINT32);
+UINT32 WINAPI waveInGetErrorText32W(UINT32,LPWSTR,UINT32);
+#define waveInGetErrorText WINELIB_NAME_AW(waveInGetErrorText)
+UINT16 WINAPI waveInOpen16(HWAVEIN16*,UINT16,const LPWAVEFORMAT,DWORD,DWORD,DWORD);
+UINT32 WINAPI waveInOpen32(HWAVEIN32*,UINT32,const LPWAVEFORMAT,DWORD,DWORD,DWORD);
+#define waveInOpen WINELIB_NAME(waveInOpen)
+UINT16 WINAPI waveInClose16(HWAVEIN16);
+UINT32 WINAPI waveInClose32(HWAVEIN32);
+#define waveInClose WINELIB_TYPE(waveInClose)
+UINT16 WINAPI waveInPrepareHeader16(HWAVEIN16,WAVEHDR*,UINT16);
+UINT32 WINAPI waveInPrepareHeader32(HWAVEIN32,WAVEHDR*,UINT32);
+#define waveInPrepareHeader WINELIB_NAME(waveInPrepareHeader)
+UINT16 WINAPI waveInUnprepareHeader16(HWAVEIN16,WAVEHDR*,UINT16);
+UINT32 WINAPI waveInUnprepareHeader32(HWAVEIN32,WAVEHDR*,UINT32);
+#define waveInUnprepareHeader WINELIB_NAME(waveInUnprepareHeader)
+UINT16 WINAPI waveInAddBuffer16(HWAVEIN16,WAVEHDR*,UINT16);
+UINT32 WINAPI waveInAddBuffer32(HWAVEIN32,WAVEHDR*,UINT32);
+#define waveInAddBuffer WINELIB_NAME(waveInAddBuffer)
+UINT16 WINAPI waveInStart16(HWAVEIN16);
+UINT32 WINAPI waveInStart32(HWAVEIN32);
+#define waveInStart WINELIB_NAME(waveInStart)
+UINT16 WINAPI waveInStop16(HWAVEIN16);
+UINT32 WINAPI waveInStop32(HWAVEIN32);
+#define waveInStop WINELIB_NAME(waveInStop)
+UINT16 WINAPI waveInReset16(HWAVEIN16);
+UINT32 WINAPI waveInReset32(HWAVEIN32);
+#define waveInReset WINELIB_NAME(waveInReset)
+UINT16 WINAPI waveInGetPosition16(HWAVEIN16,LPMMTIME16,UINT16);
+UINT32 WINAPI waveInGetPosition32(HWAVEIN32,LPMMTIME32,UINT32);
+#define waveInGetPosition WINELIB_NAME(waveInGetPosition)
+UINT16 WINAPI waveInGetID16(HWAVEIN16,UINT16*);
+UINT32 WINAPI waveInGetID32(HWAVEIN32,UINT32*);
+#define waveInGetID WINELIB_NAME(waveInGetID)
 
-DWORD WINAPI waveInMessage(HWAVEIN16 hWaveIn, UINT16 uMessage, DWORD dw1,
-                           DWORD dw2);
+DWORD WINAPI waveInMessage16(HWAVEIN16,UINT16,DWORD,DWORD);
+DWORD WINAPI waveInMessage32(HWAVEIN32,UINT32,DWORD,DWORD);
+#define waveInMessage WINELIB_NAME(waveInMessage)
 
 #define MIDIERR_UNPREPARED    (MIDIERR_BASE + 0)   /* header not prepared */
 #define MIDIERR_STILLPLAYING  (MIDIERR_BASE + 1)   /* still something playing */
@@ -338,16 +489,43 @@
 #define MIDI_UNCACHE        4
 
 typedef struct {
-    UINT16    wMid;                  /* manufacturer ID */
-    UINT16    wPid;                  /* product ID */
-    VERSION vDriverVersion;        /* version of the driver */
-    char    szPname[MAXPNAMELEN];  /* product name (NULL terminated string) */
-    UINT16    wTechnology;           /* type of device */
-    UINT16    wVoices;               /* # of voices (internal synth only) */
-    UINT16    wNotes;                /* max # of notes (internal synth only) */
-    UINT16    wChannelMask;          /* channels used (internal synth only) */
-    DWORD   dwSupport WINE_PACKED;             /* functionality supported by driver */
-} MIDIOUTCAPS, *LPMIDIOUTCAPS;
+    WORD	wMid;		/* manufacturer ID */
+    WORD	wPid;		/* product ID */
+    MMVERSION16	vDriverVersion;	/* version of the driver */
+    CHAR	szPname[MAXPNAMELEN];/* product name (NULL terminated string) */
+    WORD	wTechnology;	/* type of device */
+    WORD	wVoices;	/* # of voices (internal synth only) */
+    WORD	wNotes;		/* max # of notes (internal synth only) */
+    WORD	wChannelMask;	/* channels used (internal synth only) */
+    DWORD	dwSupport;	/* functionality supported by driver */
+} MIDIOUTCAPS16, *LPMIDIOUTCAPS16;
+
+typedef struct {
+    WORD	wMid;		/* manufacturer ID */
+    WORD	wPid;		/* product ID */
+    MMVERSION32	vDriverVersion;	/* version of the driver */
+    CHAR	szPname[MAXPNAMELEN];/* product name (NULL terminated string) */
+    WORD	wTechnology;	/* type of device */
+    WORD	wVoices;	/* # of voices (internal synth only) */
+    WORD	wNotes;		/* max # of notes (internal synth only) */
+    WORD	wChannelMask;	/* channels used (internal synth only) */
+    DWORD	dwSupport;	/* functionality supported by driver */
+} MIDIOUTCAPS32A, *LPMIDIOUTCAPS32A;
+
+typedef struct {
+    WORD	wMid;		/* manufacturer ID */
+    WORD	wPid;		/* product ID */
+    MMVERSION32	vDriverVersion;	/* version of the driver */
+    WCHAR	szPname[MAXPNAMELEN];/* product name (NULL terminated string) */
+    WORD	wTechnology;	/* type of device */
+    WORD	wVoices;	/* # of voices (internal synth only) */
+    WORD	wNotes;		/* max # of notes (internal synth only) */
+    WORD	wChannelMask;	/* channels used (internal synth only) */
+    DWORD	dwSupport;	/* functionality supported by driver */
+} MIDIOUTCAPS32W, *LPMIDIOUTCAPS32W;
+
+DECL_WINELIB_TYPE_AW(MIDIOUTCAPS);
+DECL_WINELIB_TYPE_AW(LPMIDIOUTCAPS);
 
 #define MOD_MIDIPORT    1  /* output port */
 #define MOD_SYNTH       2  /* generic internal synth */
@@ -355,87 +533,176 @@
 #define MOD_FMSYNTH     4  /* FM internal synth */
 #define MOD_MAPPER      5  /* MIDI mapper */
 
-#define MIDICAPS_VOLUME          0x0001  /* supports volume control */
-#define MIDICAPS_LRVOLUME        0x0002  /* separate left-right volume control */
-#define MIDICAPS_CACHE           0x0004
+#define MIDICAPS_VOLUME		0x0001  /* supports volume control */
+#define MIDICAPS_LRVOLUME	0x0002  /* separate left-right volume control */
+#define MIDICAPS_CACHE		0x0004
 
 typedef struct {
-    UINT16    wMid;                  /* manufacturer ID */
-    UINT16    wPid;                  /* product ID */
-    VERSION vDriverVersion;        /* version of the driver */
-    char    szPname[MAXPNAMELEN];  /* product name (NULL terminated string) */
-} MIDIINCAPS, *LPMIDIINCAPS;
+    WORD	wMid;		/* manufacturer ID */
+    WORD	wPid;		/* product ID */
+    MMVERSION16	vDriverVersion;	/* version of the driver */
+    CHAR	szPname[MAXPNAMELEN];/* product name (NULL terminated string) */
+    DWORD	dwSupport;	/* included in win95 and higher */
+} MIDIINCAPS16, *LPMIDIINCAPS16;
 
 typedef struct {
-    LPSTR       lpData;               /* pointer to locked data block */
-    DWORD       dwBufferLength;       /* length of data in data block */
-    DWORD       dwBytesRecorded;      /* used for input only */
-    DWORD       dwUser;               /* for client's use */
-    DWORD       dwFlags;              /* assorted flags (see defines) */
-    struct midihdr_tag *lpNext;       /* reserved for driver */
-    DWORD       reserved;             /* reserved for driver */
+    WORD	wMid;		/* manufacturer ID */
+    WORD	wPid;		/* product ID */
+    MMVERSION32	vDriverVersion;	/* version of the driver */
+    CHAR	szPname[MAXPNAMELEN];/* product name (NULL terminated string) */
+    DWORD	dwSupport;	/* included in win95 and higher */
+} MIDIINCAPS32A, *LPMIDIINCAPS32A;
+
+typedef struct {
+    WORD	wMid;		/* manufacturer ID */
+    WORD	wPid;		/* product ID */
+    MMVERSION32	vDriverVersion;	/* version of the driver */
+    WCHAR	szPname[MAXPNAMELEN];/* product name (NULL terminated string) */
+    DWORD	dwSupport;	/* included in win95 and higher */
+} MIDIINCAPS32W, *LPMIDIINCAPS32W;
+
+DECL_WINELIB_TYPE_AW(MIDIINCAPS);
+DECL_WINELIB_TYPE_AW(LPMIDIINCAPS);
+
+typedef struct {
+    LPSTR	lpData;		/* pointer to locked data block */
+    DWORD	dwBufferLength;	/* length of data in data block */
+    DWORD	dwBytesRecorded;/* used for input only */
+    DWORD	dwUser;		/* for client's use */
+    DWORD	dwFlags;	/* assorted flags (see defines) */
+    struct midihdr_tag *lpNext;	/* reserved for driver */
+    DWORD	reserved;	/* reserved for driver */
 } MIDIHDR, *LPMIDIHDR;
 
 #define MHDR_DONE       0x00000001       /* done bit */
 #define MHDR_PREPARED   0x00000002       /* set if header prepared */
 #define MHDR_INQUEUE    0x00000004       /* reserved for driver */
 
-UINT16 WINAPI midiOutGetNumDevs(void);
-UINT16 WINAPI midiOutGetDevCaps(UINT16 uDeviceID,
-    MIDIOUTCAPS * lpCaps, UINT16 uSize);
-UINT16 WINAPI midiOutGetVolume(UINT16 uDeviceID, DWORD * lpdwVolume);
-UINT16 WINAPI midiOutSetVolume(UINT16 uDeviceID, DWORD dwVolume);
-UINT16 WINAPI midiOutGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize);
-UINT16 WINAPI midiGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize);
-UINT16 WINAPI midiOutOpen(HMIDIOUT16 * lphMidiOut, UINT16 uDeviceID,
-    DWORD dwCallback, DWORD dwInstance, DWORD dwFlags);
-UINT16 WINAPI midiOutClose(HMIDIOUT16 hMidiOut);
-UINT16 WINAPI midiOutPrepareHeader(HMIDIOUT16 hMidiOut,
-    MIDIHDR * lpMidiOutHdr, UINT16 uSize);
-UINT16 WINAPI midiOutUnprepareHeader(HMIDIOUT16 hMidiOut,
-    MIDIHDR * lpMidiOutHdr, UINT16 uSize);
-UINT16 WINAPI midiOutShortMsg(HMIDIOUT16 hMidiOut, DWORD dwMsg);
-UINT16 WINAPI midiOutLongMsg(HMIDIOUT16 hMidiOut,
-    MIDIHDR * lpMidiOutHdr, UINT16 uSize);
-UINT16 WINAPI midiOutReset(HMIDIOUT16 hMidiOut);
-UINT16 WINAPI midiOutCachePatches(HMIDIOUT16 hMidiOut,
-    UINT16 uBank, WORD * lpwPatchArray, UINT16 uFlags);
-UINT16 WINAPI midiOutCacheDrumPatches(HMIDIOUT16 hMidiOut,
-    UINT16 uPatch, WORD * lpwKeyArray, UINT16 uFlags);
-UINT16 WINAPI midiOutGetID(HMIDIOUT16 hMidiOut, UINT16 * lpuDeviceID);
+UINT16 WINAPI midiOutGetNumDevs16();
+UINT32 WINAPI midiOutGetNumDevs32();
+#define midiOutGetNumDevs WINELIB_NAME(midiOutGetNumDevs)
+UINT16 WINAPI midiOutGetDevCaps16(UINT16,LPMIDIOUTCAPS16,UINT16);
+UINT32 WINAPI midiOutGetDevCaps32A(UINT32,LPMIDIOUTCAPS32A,UINT32);
+UINT32 WINAPI midiOutGetDevCaps32W(UINT32,LPMIDIOUTCAPS32W,UINT32);
+#define midiOutGetDevCaps WINELIB_NAME_AW(midiOutGetDevCaps)
+UINT16 WINAPI midiOutGetVolume16(UINT16,DWORD*);
+UINT32 WINAPI midiOutGetVolume32(UINT32,DWORD*);
+#define midiOutGetVolume WINELIB_NAME(midiOutGetVolume)
+UINT16 WINAPI midiOutSetVolume16(UINT16,DWORD);
+UINT32 WINAPI midiOutSetVolume32(UINT32,DWORD);
+#define midiOutSetVolume WINELIB_NAME(midiOutSetVolume)
+UINT16 WINAPI midiOutGetErrorText16(UINT16,LPSTR,UINT16);
+UINT32 WINAPI midiOutGetErrorText32A(UINT32,LPSTR,UINT32);
+UINT32 WINAPI midiOutGetErrorText32W(UINT32,LPWSTR,UINT32);
+#define midiOutGetErrorText WINELIB_NAME_AW(midiOutGetErrorText)
+UINT16 WINAPI midiGetErrorText(UINT16,LPSTR,UINT16);
+UINT16 WINAPI midiOutOpen16(HMIDIOUT16*,UINT16,DWORD,DWORD,DWORD);
+UINT32 WINAPI midiOutOpen32(HMIDIOUT32*,UINT32,DWORD,DWORD,DWORD);
+#define midiOutOpen WINELIB_NAME(midiOutOpen)
+UINT16 WINAPI midiOutClose16(HMIDIOUT16);
+UINT32 WINAPI midiOutClose32(HMIDIOUT32);
+#define midiOutClose WINELIB_NAME(midiOutClose)
+UINT16 WINAPI midiOutPrepareHeader16(HMIDIOUT16,MIDIHDR*,UINT16);
+UINT32 WINAPI midiOutPrepareHeader32(HMIDIOUT32,MIDIHDR*,UINT32);
+#define midiOutPrepareHeader WINELIB_NAME(midiOutPrepareHeader)
+UINT16 WINAPI midiOutUnprepareHeader16(HMIDIOUT16,MIDIHDR*,UINT16);
+UINT32 WINAPI midiOutUnprepareHeader32(HMIDIOUT32,MIDIHDR*,UINT32);
+#define midiOutUnprepareHeader WINELIB_NAME(midiOutUnprepareHeader)
+UINT16 WINAPI midiOutShortMsg16(HMIDIOUT16,DWORD);
+UINT32 WINAPI midiOutShortMsg32(HMIDIOUT32,DWORD);
+#define midiOutShortMsg WINELIB_NAME(midiOutShortMsg)
+UINT16 WINAPI midiOutLongMsg16(HMIDIOUT16,MIDIHDR*,UINT16);
+UINT32 WINAPI midiOutLongMsg32(HMIDIOUT32,MIDIHDR*,UINT32);
+#define midiOutLongMsg WINELIB_NAME(midiOutLongMsg)
+UINT16 WINAPI midiOutReset16(HMIDIOUT16);
+UINT32 WINAPI midiOutReset32(HMIDIOUT32);
+#define midiOutReset WINELIB_NAME(midiOutReset)
+UINT16 WINAPI midiOutCachePatches16(HMIDIOUT16,UINT16,WORD*,UINT16);
+UINT32 WINAPI midiOutCachePatches32(HMIDIOUT32,UINT32,WORD*,UINT32);
+#define midiOutCachePatches WINELIB_NAME(midiOutCachePatches)
+UINT16 WINAPI midiOutCacheDrumPatches16(HMIDIOUT16,UINT16,WORD*,UINT16);
+UINT32 WINAPI midiOutCacheDrumPatches32(HMIDIOUT32,UINT32,WORD*,UINT32);
+#define midiOutCacheDrumPatches WINELIB_NAME(midiOutCacheDrumPatches)
+UINT16 WINAPI midiOutGetID16(HMIDIOUT16,UINT16*);
+UINT32 WINAPI midiOutGetID32(HMIDIOUT32,UINT32*);
+#define midiOutGetID WINELIB_NAME(midiOutGetID)
 
-DWORD WINAPI midiOutMessage(HMIDIOUT16 hMidiOut, UINT16 uMessage, DWORD dw1, DWORD dw2);
+DWORD WINAPI midiOutMessage16(HMIDIOUT16,UINT16,DWORD,DWORD);
+DWORD WINAPI midiOutMessage32(HMIDIOUT32,UINT32,DWORD,DWORD);
+#define midiOutMessage WINELIB_NAME(midiOutMessage)
 
-UINT16 WINAPI midiInGetNumDevs(void);
-UINT16 WINAPI midiInGetDevCaps(UINT16 uDeviceID,
-    LPMIDIINCAPS lpCaps, UINT16 uSize);
-UINT16 WINAPI midiInGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize);
-UINT16 WINAPI midiInOpen(HMIDIIN16 * lphMidiIn, UINT16 uDeviceID,
-    DWORD dwCallback, DWORD dwInstance, DWORD dwFlags);
-UINT16 WINAPI midiInClose(HMIDIIN16 hMidiIn);
-UINT16 WINAPI midiInPrepareHeader(HMIDIIN16 hMidiIn,
-    MIDIHDR * lpMidiInHdr, UINT16 uSize);
-UINT16 WINAPI midiInUnprepareHeader(HMIDIIN16 hMidiIn,
-    MIDIHDR * lpMidiInHdr, UINT16 uSize);
-UINT16 WINAPI midiInAddBuffer(HMIDIIN16 hMidiIn,
-    MIDIHDR * lpMidiInHdr, UINT16 uSize);
-UINT16 WINAPI midiInStart(HMIDIIN16 hMidiIn);
-UINT16 WINAPI midiInStop(HMIDIIN16 hMidiIn);
-UINT16 WINAPI midiInReset(HMIDIIN16 hMidiIn);
-UINT16 WINAPI midiInGetID(HMIDIIN16 hMidiIn, UINT16 * lpuDeviceID);
-
-DWORD WINAPI midiInMessage(HMIDIIN16 hMidiIn, UINT16 uMessage, DWORD dw1, DWORD dw2);
+UINT16 WINAPI midiInGetNumDevs16(void);
+UINT32 WINAPI midiInGetNumDevs32(void);
+#define midiInGetNumDevs WINELIB_NAME(midiInGetNumDevs)
+UINT16 WINAPI midiInGetDevCaps16(UINT16,LPMIDIINCAPS16,UINT16);
+UINT32 WINAPI midiInGetDevCaps32A(UINT32,LPMIDIINCAPS32A,UINT32);
+UINT32 WINAPI midiInGetDevCaps32W(UINT32,LPMIDIINCAPS32W,UINT32);
+#define midiInGetDevCaps WINELIB_NAME_AW(midiInGetDevCaps)
+UINT16 WINAPI midiInGetErrorText16(UINT16,LPSTR,UINT16);
+UINT32 WINAPI midiInGetErrorText32A(UINT32,LPSTR,UINT32);
+UINT32 WINAPI midiInGetErrorText32W(UINT32,LPWSTR,UINT32);
+#define midiInGetErrorText WINELIB_NAME_AW(midiInGetErrorText)
+UINT16 WINAPI midiInOpen16(HMIDIIN16*,UINT16,DWORD,DWORD,DWORD);
+UINT32 WINAPI midiInOpen32(HMIDIIN32*,UINT32,DWORD,DWORD,DWORD);
+#define midiInOpen WINELIB_NAME(midiInOpen)
+UINT16 WINAPI midiInClose16(HMIDIIN16);
+UINT32 WINAPI midiInClose32(HMIDIIN32);
+#define midiInClose WINELIB_NAME(midiInClose)
+UINT16 WINAPI midiInPrepareHeader16(HMIDIIN16,MIDIHDR*,UINT16);
+UINT32 WINAPI midiInPrepareHeader32(HMIDIIN32,MIDIHDR*,UINT32);
+#define midiInPrepareHeader WINELIB_NAME(midiInPrepareHeader)
+UINT16 WINAPI midiInUnprepareHeader16(HMIDIIN16,MIDIHDR*,UINT16);
+UINT32 WINAPI midiInUnprepareHeader32(HMIDIIN32,MIDIHDR*,UINT32);
+#define midiInUnprepareHeader WINELIB_NAME(midiInUnprepareHeader)
+UINT16 WINAPI midiInAddBuffer16(HMIDIIN16,MIDIHDR*,UINT16);
+UINT32 WINAPI midiInAddBuffer32(HMIDIIN32,MIDIHDR*,UINT32);
+#define midiInAddBuffer WINELIB_NAME(midiInAddBuffer)
+UINT16 WINAPI midiInStart16(HMIDIIN16);
+UINT32 WINAPI midiInStart32(HMIDIIN32);
+#define midiInStart WINELIB_NAME(midiInStart)
+UINT16 WINAPI midiInStop16(HMIDIIN16);
+UINT32 WINAPI midiInStop32(HMIDIIN32);
+#define midiInStop WINELIB_NAME(midiInStop)
+UINT16 WINAPI midiInReset16(HMIDIIN16);
+UINT32 WINAPI midiInReset32(HMIDIIN32);
+#define midiInReset WINELIB_NAME(midiInReset)
+UINT16 WINAPI midiInGetID16(HMIDIIN16,UINT16*);
+UINT32 WINAPI midiInGetID32(HMIDIIN32,UINT32*);
+#define midiInGetID WINELIB_NAME(midiInGetID)
+DWORD WINAPI midiInMessage16(HMIDIIN16,UINT16,DWORD,DWORD);
+DWORD WINAPI midiInMessage32(HMIDIIN32,UINT32,DWORD,DWORD);
+#define midiInMessage WINELIB_NAME(midiInMessage)
 
 #define AUX_MAPPER     (-1)
 
 typedef struct {
-    UINT16    wMid;                  /* manufacturer ID */
-    UINT16    wPid;                  /* product ID */
-    VERSION vDriverVersion;        /* version of the driver */
-    char    szPname[MAXPNAMELEN];  /* product name (NULL terminated string) */
-    UINT16    wTechnology;           /* type of device */
-    DWORD   dwSupport WINE_PACKED;             /* functionality supported by driver */
-} AUXCAPS, *LPAUXCAPS;
+    WORD	wMid;			/* manufacturer ID */
+    WORD	wPid;			/* product ID */
+    MMVERSION16	vDriverVersion;		/* version of the driver */
+    CHAR	szPname[MAXPNAMELEN];	/* product name (NULL terminated string) */
+    WORD	wTechnology;		/* type of device */
+    DWORD	dwSupport;		/* functionality supported by driver */
+} AUXCAPS16, *LPAUXCAPS16;
+
+typedef struct {
+    WORD	wMid;			/* manufacturer ID */
+    WORD	wPid;			/* product ID */
+    MMVERSION32	vDriverVersion;		/* version of the driver */
+    CHAR	szPname[MAXPNAMELEN];	/* product name (NULL terminated string) */
+    WORD	wTechnology;		/* type of device */
+    WORD	wReserved1;		/* padding */
+    DWORD	dwSupport;		/* functionality supported by driver */
+} AUXCAPS32A, *LPAUXCAPS32A;
+
+typedef struct {
+    WORD	wMid;			/* manufacturer ID */
+    WORD	wPid;			/* product ID */
+    MMVERSION32	vDriverVersion;		/* version of the driver */
+    WCHAR	szPname[MAXPNAMELEN];	/* product name (NULL terminated string) */
+    WORD	wTechnology;		/* type of device */
+    WORD	wReserved1;		/* padding */
+    DWORD	dwSupport;		/* functionality supported by driver */
+} AUXCAPS32W, *LPAUXCAPS32W;
 
 #define AUXCAPS_CDAUDIO    1       /* audio from internal CD-ROM drive */
 #define AUXCAPS_AUXIN      2       /* audio from auxiliary input jacks */
@@ -443,12 +710,24 @@
 #define AUXCAPS_VOLUME          0x0001  /* supports volume control */
 #define AUXCAPS_LRVOLUME        0x0002  /* separate left-right volume control */
 
-UINT16 WINAPI auxGetNumDevs(void);
-UINT16 WINAPI auxGetDevCaps(UINT16 uDeviceID, AUXCAPS * lpCaps, UINT16 uSize);
-UINT16 WINAPI auxSetVolume(UINT16 uDeviceID, DWORD dwVolume);
-UINT16 WINAPI auxGetVolume(UINT16 uDeviceID, DWORD * lpdwVolume);
+UINT16 WINAPI auxGetNumDevs16();
+UINT32 WINAPI auxGetNumDevs32();
+#define auxGetNumDevs WINELIB_NAME(auxGetNumDevs)
+UINT16 WINAPI auxGetDevCaps16 (UINT16,LPAUXCAPS16,UINT16);
+UINT32 WINAPI auxGetDevCaps32A(UINT32,LPAUXCAPS32A,UINT32);
+UINT32 WINAPI auxGetDevCaps32W(UINT32,LPAUXCAPS32W,UINT32);
+#define auxGetDevCaps WINELIB_NAME_AW(auxGetDevCaps)
+UINT16 WINAPI auxSetVolume16(UINT16,DWORD);
+UINT32 WINAPI auxSetVolume32(UINT32,DWORD);
+#define auxSetVolume WINELIB_NAME(auxSetVolume)
 
-DWORD WINAPI auxOutMessage(UINT16 uDeviceID, UINT16 uMessage, DWORD dw1, DWORD dw2);
+UINT16 WINAPI auxGetVolume16(UINT16,LPDWORD);
+UINT32 WINAPI auxGetVolume32(UINT32,LPDWORD);
+#define auxGetVolume WINELIB_NAME(auxGetVolume)
+
+DWORD WINAPI auxOutMessage16(UINT16,UINT16,DWORD,DWORD);
+DWORD WINAPI auxOutMessage32(UINT32,UINT32,DWORD,DWORD);
+#define auxOutMessage WINELIB_NAME(auxOutMessage)
 
 #define TIMERR_NOERROR        (0)                  /* no error */
 #define TIMERR_NOCANDO        (TIMERR_BASE+1)      /* request not completed */
@@ -464,7 +743,7 @@
     UINT16    wPeriodMax;     /* maximum period supported  */
 } TIMECAPS, *LPTIMECAPS;
 
-UINT16 WINAPI timeGetSystemTime(MMTIME * lpTime, UINT16 uSize);
+UINT16 WINAPI timeGetSystemTime(LPMMTIME16 lpTime, UINT16 uSize);
 DWORD WINAPI timeGetTime(void);
 UINT16 WINAPI timeSetEvent(UINT16 uDelay, UINT16 uResolution,
     LPTIMECALLBACK lpFunction, DWORD dwUser, UINT16 uFlags);
@@ -521,6 +800,463 @@
     BOOL16 bChanged);
 UINT16 WINAPI joySetThreshold(UINT16 uJoyID, UINT16 uThreshold);
 
+typedef struct {
+	WORD		wMid;		/* manufacturer id */
+	WORD		wPid;		/* product id */
+	MMVERSION16	vDriverVersion;		/* version of the driver */
+	CHAR		szPname[MAXPNAMELEN];	/* product name */
+	DWORD		fdwSupport;	/* misc. support bits */
+	DWORD		cDestinations;	/* count of destinations */
+} MIXERCAPS16,*LPMIXERCAPS16;
+
+typedef struct {
+	WORD		wMid;
+	WORD		wPid;
+	MMVERSION32	vDriverVersion;
+	CHAR		szPname[MAXPNAMELEN];
+	DWORD		fdwSupport;
+	DWORD		cDestinations;
+} MIXERCAPS32A,*LPMIXERCAPS32A;
+
+typedef struct {
+	WORD		wMid;
+	WORD		wPid;
+	MMVERSION32	vDriverVersion;
+	WCHAR		szPname[MAXPNAMELEN];
+	DWORD		fdwSupport;
+	DWORD		cDestinations;
+} MIXERCAPS32W,*LPMIXERCAPS32W;
+
+DECL_WINELIB_TYPE_AW(MIXERCAPS);
+DECL_WINELIB_TYPE_AW(LPMIXERCAPS);
+
+#define MIXER_SHORT_NAME_CHARS	16
+#define MIXER_LONG_NAME_CHARS	64
+
+/*  MIXERLINE.fdwLine */
+#define	MIXERLINE_LINEF_ACTIVE		0x00000001
+#define	MIXERLINE_LINEF_DISCONNECTED	0x00008000
+#define	MIXERLINE_LINEF_SOURCE		0x80000000
+
+/*  MIXERLINE.dwComponentType */
+/*  component types for destinations and sources */
+#define	MIXERLINE_COMPONENTTYPE_DST_FIRST	0x00000000L
+#define	MIXERLINE_COMPONENTTYPE_DST_UNDEFINED	(MIXERLINE_COMPONENTTYPE_DST_FIRST + 0)
+#define	MIXERLINE_COMPONENTTYPE_DST_DIGITAL	(MIXERLINE_COMPONENTTYPE_DST_FIRST + 1)
+#define	MIXERLINE_COMPONENTTYPE_DST_LINE	(MIXERLINE_COMPONENTTYPE_DST_FIRST + 2)
+#define	MIXERLINE_COMPONENTTYPE_DST_MONITOR	(MIXERLINE_COMPONENTTYPE_DST_FIRST + 3)
+#define	MIXERLINE_COMPONENTTYPE_DST_SPEAKERS	(MIXERLINE_COMPONENTTYPE_DST_FIRST + 4)
+#define	MIXERLINE_COMPONENTTYPE_DST_HEADPHONES	(MIXERLINE_COMPONENTTYPE_DST_FIRST + 5)
+#define	MIXERLINE_COMPONENTTYPE_DST_TELEPHONE	(MIXERLINE_COMPONENTTYPE_DST_FIRST + 6)
+#define	MIXERLINE_COMPONENTTYPE_DST_WAVEIN	(MIXERLINE_COMPONENTTYPE_DST_FIRST + 7)
+#define	MIXERLINE_COMPONENTTYPE_DST_VOICEIN	(MIXERLINE_COMPONENTTYPE_DST_FIRST + 8)
+#define	MIXERLINE_COMPONENTTYPE_DST_LAST	(MIXERLINE_COMPONENTTYPE_DST_FIRST + 8)
+
+#define	MIXERLINE_COMPONENTTYPE_SRC_FIRST	0x00001000L
+#define	MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED	(MIXERLINE_COMPONENTTYPE_SRC_FIRST + 0)
+#define	MIXERLINE_COMPONENTTYPE_SRC_DIGITAL	(MIXERLINE_COMPONENTTYPE_SRC_FIRST + 1)
+#define	MIXERLINE_COMPONENTTYPE_SRC_LINE	(MIXERLINE_COMPONENTTYPE_SRC_FIRST + 2)
+#define	MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE	(MIXERLINE_COMPONENTTYPE_SRC_FIRST + 3)
+#define	MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER	(MIXERLINE_COMPONENTTYPE_SRC_FIRST + 4)
+#define	MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC	(MIXERLINE_COMPONENTTYPE_SRC_FIRST + 5)
+#define	MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE	(MIXERLINE_COMPONENTTYPE_SRC_FIRST + 6)
+#define	MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER	(MIXERLINE_COMPONENTTYPE_SRC_FIRST + 7)
+#define	MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT	(MIXERLINE_COMPONENTTYPE_SRC_FIRST + 8)
+#define	MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY	(MIXERLINE_COMPONENTTYPE_SRC_FIRST + 9)
+#define	MIXERLINE_COMPONENTTYPE_SRC_ANALOG	(MIXERLINE_COMPONENTTYPE_SRC_FIRST + 10)
+#define	MIXERLINE_COMPONENTTYPE_SRC_LAST	(MIXERLINE_COMPONENTTYPE_SRC_FIRST + 10)
+
+/*  MIXERLINE.Target.dwType */
+#define	MIXERLINE_TARGETTYPE_UNDEFINED	0
+#define	MIXERLINE_TARGETTYPE_WAVEOUT	1
+#define	MIXERLINE_TARGETTYPE_WAVEIN	2
+#define	MIXERLINE_TARGETTYPE_MIDIOUT	3
+#define	MIXERLINE_TARGETTYPE_MIDIIN	4
+#define MIXERLINE_TARGETTYPE_AUX	5
+
+typedef struct {
+    DWORD	cbStruct;		/* size of MIXERLINE structure */
+    DWORD	dwDestination;		/* zero based destination index */
+    DWORD	dwSource;		/* zero based source index (if source) */
+    DWORD	dwLineID;		/* unique line id for mixer device */
+    DWORD	fdwLine;		/* state/information about line */
+    DWORD	dwUser;			/* driver specific information */
+    DWORD	dwComponentType;	/* component type line connects to */
+    DWORD	cChannels;		/* number of channels line supports */
+    DWORD	cConnections;		/* number of connections [possible] */
+    DWORD	cControls;		/* number of controls at this line */
+    CHAR	szShortName[MIXER_SHORT_NAME_CHARS];
+    CHAR	szName[MIXER_LONG_NAME_CHARS];
+    struct {
+	DWORD	dwType;			/* MIXERLINE_TARGETTYPE_xxxx */
+	DWORD	dwDeviceID;		/* target device ID of device type */
+	WORD	wMid;			/* of target device */
+	WORD	wPid;			/*      " */
+	MMVERSION16	vDriverVersion;	/*      " */
+	CHAR	szPname[MAXPNAMELEN];	/*      " */
+    } Target;
+} MIXERLINE16, *LPMIXERLINE16;
+
+typedef struct {
+    DWORD	cbStruct;
+    DWORD	dwDestination;
+    DWORD	dwSource;
+    DWORD	dwLineID;
+    DWORD	fdwLine;
+    DWORD	dwUser;
+    DWORD	dwComponentType;
+    DWORD	cChannels;
+    DWORD	cConnections;
+    DWORD	cControls;
+    CHAR	szShortName[MIXER_SHORT_NAME_CHARS];
+    CHAR	szName[MIXER_LONG_NAME_CHARS];
+    struct {
+	DWORD	dwType;
+	DWORD	dwDeviceID;
+	WORD	wMid;
+	WORD	wPid;
+	MMVERSION32	vDriverVersion;
+	CHAR	szPname[MAXPNAMELEN];
+    } Target;
+} MIXERLINE32A, *LPMIXERLINE32A;
+
+typedef struct {
+    DWORD	cbStruct;
+    DWORD	dwDestination;
+    DWORD	dwSource;
+    DWORD	dwLineID;
+    DWORD	fdwLine;
+    DWORD	dwUser;
+    DWORD	dwComponentType;
+    DWORD	cChannels;
+    DWORD	cConnections;
+    DWORD	cControls;
+    WCHAR	szShortName[MIXER_SHORT_NAME_CHARS];
+    WCHAR	szName[MIXER_LONG_NAME_CHARS];
+    struct {
+	DWORD	dwType;
+	DWORD	dwDeviceID;
+	WORD	wMid;
+	WORD	wPid;
+	MMVERSION32	vDriverVersion;
+	WCHAR	szPname[MAXPNAMELEN];
+    } Target;
+} MIXERLINE32W, *LPMIXERLINE32W;
+
+DECL_WINELIB_TYPE_AW(MIXERLINE);
+DECL_WINELIB_TYPE_AW(LPMIXERLINE);
+
+/*  MIXERCONTROL.fdwControl */
+#define	MIXERCONTROL_CONTROLF_UNIFORM	0x00000001L
+#define	MIXERCONTROL_CONTROLF_MULTIPLE	0x00000002L
+#define	MIXERCONTROL_CONTROLF_DISABLED	0x80000000L
+
+/*  MIXERCONTROL_CONTROLTYPE_xxx building block defines */
+#define	MIXERCONTROL_CT_CLASS_MASK		0xF0000000L
+#define	MIXERCONTROL_CT_CLASS_CUSTOM		0x00000000L
+#define	MIXERCONTROL_CT_CLASS_METER		0x10000000L
+#define	MIXERCONTROL_CT_CLASS_SWITCH		0x20000000L
+#define	MIXERCONTROL_CT_CLASS_NUMBER		0x30000000L
+#define	MIXERCONTROL_CT_CLASS_SLIDER		0x40000000L
+#define	MIXERCONTROL_CT_CLASS_FADER		0x50000000L
+#define	MIXERCONTROL_CT_CLASS_TIME		0x60000000L
+#define	MIXERCONTROL_CT_CLASS_LIST		0x70000000L
+
+#define	MIXERCONTROL_CT_SUBCLASS_MASK		0x0F000000L
+
+#define	MIXERCONTROL_CT_SC_SWITCH_BOOLEAN	0x00000000L
+#define	MIXERCONTROL_CT_SC_SWITCH_BUTTON	0x01000000L
+
+#define	MIXERCONTROL_CT_SC_METER_POLLED		0x00000000L
+
+#define	MIXERCONTROL_CT_SC_TIME_MICROSECS	0x00000000L
+#define	MIXERCONTROL_CT_SC_TIME_MILLISECS	0x01000000L
+
+#define	MIXERCONTROL_CT_SC_LIST_SINGLE		0x00000000L
+#define	MIXERCONTROL_CT_SC_LIST_MULTIPLE	0x01000000L
+
+#define	MIXERCONTROL_CT_UNITS_MASK		0x00FF0000L
+#define	MIXERCONTROL_CT_UNITS_CUSTOM		0x00000000L
+#define	MIXERCONTROL_CT_UNITS_BOOLEAN		0x00010000L
+#define	MIXERCONTROL_CT_UNITS_SIGNED		0x00020000L
+#define	MIXERCONTROL_CT_UNITS_UNSIGNED		0x00030000L
+#define	MIXERCONTROL_CT_UNITS_DECIBELS		0x00040000L /* in 10ths */
+#define	MIXERCONTROL_CT_UNITS_PERCENT		0x00050000L /* in 10ths */
+
+/*  Commonly used control types for specifying MIXERCONTROL.dwControlType */
+#define MIXERCONTROL_CONTROLTYPE_CUSTOM		(MIXERCONTROL_CT_CLASS_CUSTOM | MIXERCONTROL_CT_UNITS_CUSTOM)
+#define MIXERCONTROL_CONTROLTYPE_BOOLEANMETER	(MIXERCONTROL_CT_CLASS_METER | MIXERCONTROL_CT_SC_METER_POLLED | MIXERCONTROL_CT_UNITS_BOOLEAN)
+#define MIXERCONTROL_CONTROLTYPE_SIGNEDMETER	(MIXERCONTROL_CT_CLASS_METER | MIXERCONTROL_CT_SC_METER_POLLED | MIXERCONTROL_CT_UNITS_SIGNED)
+#define MIXERCONTROL_CONTROLTYPE_PEAKMETER	(MIXERCONTROL_CONTROLTYPE_SIGNEDMETER + 1)
+#define MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER	(MIXERCONTROL_CT_CLASS_METER | MIXERCONTROL_CT_SC_METER_POLLED | MIXERCONTROL_CT_UNITS_UNSIGNED)
+#define MIXERCONTROL_CONTROLTYPE_BOOLEAN	(MIXERCONTROL_CT_CLASS_SWITCH | MIXERCONTROL_CT_SC_SWITCH_BOOLEAN | MIXERCONTROL_CT_UNITS_BOOLEAN)
+#define MIXERCONTROL_CONTROLTYPE_ONOFF		(MIXERCONTROL_CONTROLTYPE_BOOLEAN + 1)
+#define MIXERCONTROL_CONTROLTYPE_MUTE		(MIXERCONTROL_CONTROLTYPE_BOOLEAN + 2)
+#define MIXERCONTROL_CONTROLTYPE_MONO		(MIXERCONTROL_CONTROLTYPE_BOOLEAN + 3)
+#define MIXERCONTROL_CONTROLTYPE_LOUDNESS	(MIXERCONTROL_CONTROLTYPE_BOOLEAN + 4)
+#define MIXERCONTROL_CONTROLTYPE_STEREOENH	(MIXERCONTROL_CONTROLTYPE_BOOLEAN + 5)
+#define MIXERCONTROL_CONTROLTYPE_BUTTON		(MIXERCONTROL_CT_CLASS_SWITCH | MIXERCONTROL_CT_SC_SWITCH_BUTTON | MIXERCONTROL_CT_UNITS_BOOLEAN)
+#define MIXERCONTROL_CONTROLTYPE_DECIBELS	(MIXERCONTROL_CT_CLASS_NUMBER | MIXERCONTROL_CT_UNITS_DECIBELS)
+#define MIXERCONTROL_CONTROLTYPE_SIGNED		(MIXERCONTROL_CT_CLASS_NUMBER | MIXERCONTROL_CT_UNITS_SIGNED)
+#define MIXERCONTROL_CONTROLTYPE_UNSIGNED	(MIXERCONTROL_CT_CLASS_NUMBER | MIXERCONTROL_CT_UNITS_UNSIGNED)
+#define MIXERCONTROL_CONTROLTYPE_PERCENT	(MIXERCONTROL_CT_CLASS_NUMBER | MIXERCONTROL_CT_UNITS_PERCENT)
+#define MIXERCONTROL_CONTROLTYPE_SLIDER		(MIXERCONTROL_CT_CLASS_SLIDER | MIXERCONTROL_CT_UNITS_SIGNED)
+#define MIXERCONTROL_CONTROLTYPE_PAN		(MIXERCONTROL_CONTROLTYPE_SLIDER + 1)
+#define MIXERCONTROL_CONTROLTYPE_QSOUNDPAN	(MIXERCONTROL_CONTROLTYPE_SLIDER + 2)
+#define MIXERCONTROL_CONTROLTYPE_FADER		(MIXERCONTROL_CT_CLASS_FADER | MIXERCONTROL_CT_UNITS_UNSIGNED)
+#define MIXERCONTROL_CONTROLTYPE_VOLUME		(MIXERCONTROL_CONTROLTYPE_FADER + 1)
+#define MIXERCONTROL_CONTROLTYPE_BASS		(MIXERCONTROL_CONTROLTYPE_FADER + 2)
+#define MIXERCONTROL_CONTROLTYPE_TREBLE		(MIXERCONTROL_CONTROLTYPE_FADER + 3)
+#define MIXERCONTROL_CONTROLTYPE_EQUALIZER	(MIXERCONTROL_CONTROLTYPE_FADER + 4)
+#define MIXERCONTROL_CONTROLTYPE_SINGLESELECT	(MIXERCONTROL_CT_CLASS_LIST | MIXERCONTROL_CT_SC_LIST_SINGLE | MIXERCONTROL_CT_UNITS_BOOLEAN)
+#define MIXERCONTROL_CONTROLTYPE_MUX		(MIXERCONTROL_CONTROLTYPE_SINGLESELECT + 1)
+#define MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT	(MIXERCONTROL_CT_CLASS_LIST | MIXERCONTROL_CT_SC_LIST_MULTIPLE | MIXERCONTROL_CT_UNITS_BOOLEAN)
+#define MIXERCONTROL_CONTROLTYPE_MIXER		(MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT + 1)
+#define MIXERCONTROL_CONTROLTYPE_MICROTIME	(MIXERCONTROL_CT_CLASS_TIME | MIXERCONTROL_CT_SC_TIME_MICROSECS | MIXERCONTROL_CT_UNITS_UNSIGNED)
+#define MIXERCONTROL_CONTROLTYPE_MILLITIME	(MIXERCONTROL_CT_CLASS_TIME | MIXERCONTROL_CT_SC_TIME_MILLISECS | MIXERCONTROL_CT_UNITS_UNSIGNED)
+
+
+typedef struct {
+    DWORD		cbStruct;           /* size in bytes of MIXERCONTROL */
+    DWORD		dwControlID;        /* unique control id for mixer device */
+    DWORD		dwControlType;      /* MIXERCONTROL_CONTROLTYPE_xxx */
+    DWORD		fdwControl;         /* MIXERCONTROL_CONTROLF_xxx */
+    DWORD		cMultipleItems;     /* if MIXERCONTROL_CONTROLF_MULTIPLE set */
+    CHAR		szShortName[MIXER_SHORT_NAME_CHARS];
+    CHAR		szName[MIXER_LONG_NAME_CHARS];
+    union {
+	struct {
+	    LONG	lMinimum;	/* signed minimum for this control */
+	    LONG	lMaximum;	/* signed maximum for this control */
+	} l;
+	struct {
+	    DWORD	dwMinimum;	/* unsigned minimum for this control */
+	    DWORD	dwMaximum;	/* unsigned maximum for this control */
+	} dw;
+	DWORD       	dwReserved[6];
+    } Bounds;
+    union {
+	DWORD		cSteps;		/* # of steps between min & max */
+	DWORD		cbCustomData;	/* size in bytes of custom data */
+	DWORD		dwReserved[6];	/* !!! needed? we have cbStruct.... */
+    } Metrics;
+} MIXERCONTROL16, *LPMIXERCONTROL16;
+
+typedef struct {
+    DWORD		cbStruct;
+    DWORD		dwControlID;
+    DWORD		dwControlType;
+    DWORD		fdwControl;
+    DWORD		cMultipleItems;
+    CHAR		szShortName[MIXER_SHORT_NAME_CHARS];
+    CHAR		szName[MIXER_LONG_NAME_CHARS];
+    union {
+	struct {
+	    LONG	lMinimum;
+	    LONG	lMaximum;
+	} l;
+	struct {
+	    DWORD	dwMinimum;
+	    DWORD	dwMaximum;
+	} dw;
+	DWORD       	dwReserved[6];
+    } Bounds;
+    union {
+	DWORD		cSteps;
+	DWORD		cbCustomData;
+	DWORD		dwReserved[6];
+    } Metrics;
+} MIXERCONTROL32A, *LPMIXERCONTROL32A;
+
+typedef struct {
+    DWORD		cbStruct;
+    DWORD		dwControlID;
+    DWORD		dwControlType;
+    DWORD		fdwControl;
+    DWORD		cMultipleItems;
+    WCHAR		szShortName[MIXER_SHORT_NAME_CHARS];
+    WCHAR		szName[MIXER_LONG_NAME_CHARS];
+    union {
+	struct {
+	    LONG	lMinimum;
+	    LONG	lMaximum;
+	} l;
+	struct {
+	    DWORD	dwMinimum;
+	    DWORD	dwMaximum;
+	} dw;
+	DWORD       	dwReserved[6];
+    } Bounds;
+    union {
+	DWORD		cSteps;
+	DWORD		cbCustomData;
+	DWORD		dwReserved[6];
+    } Metrics;
+} MIXERCONTROL32W, *LPMIXERCONTROL32W;
+
+DECL_WINELIB_TYPE_AW(MIXERCONTROL);
+DECL_WINELIB_TYPE_AW(LPMIXERCONTROL);
+
+typedef struct {
+    DWORD	cbStruct;	/* size in bytes of MIXERLINECONTROLS */
+    DWORD	dwLineID;	/* line id (from MIXERLINE.dwLineID) */
+    union {
+	DWORD	dwControlID;	/* MIXER_GETLINECONTROLSF_ONEBYID */
+	DWORD	dwControlType;	/* MIXER_GETLINECONTROLSF_ONEBYTYPE */
+    } u;
+    DWORD	cControls;	/* count of controls pmxctrl points to */
+    DWORD	cbmxctrl;	/* size in bytes of _one_ MIXERCONTROL */
+    LPMIXERCONTROL16	pamxctrl;/* pointer to first MIXERCONTROL array */
+} MIXERLINECONTROLS16, *LPMIXERLINECONTROLS16;
+
+typedef struct {
+    DWORD	cbStruct;
+    DWORD	dwLineID;
+    union {
+	DWORD	dwControlID;
+	DWORD	dwControlType;
+    } u;
+    DWORD	cControls;
+    DWORD	cbmxctrl;
+    LPMIXERCONTROL32A	pamxctrl;
+} MIXERLINECONTROLS32A, *LPMIXERLINECONTROLS32A;
+
+typedef struct {
+    DWORD	cbStruct;
+    DWORD	dwLineID;
+    union {
+	DWORD	dwControlID;
+	DWORD	dwControlType;
+    } u;
+    DWORD	cControls;
+    DWORD	cbmxctrl;
+    LPMIXERCONTROL32W	pamxctrl;
+} MIXERLINECONTROLS32W, *LPMIXERLINECONTROLS32W;
+
+DECL_WINELIB_TYPE_AW(MIXERLINECONTROLS);
+DECL_WINELIB_TYPE_AW(LPMIXERLINECONTROLS);
+
+typedef struct {
+    DWORD	cbStruct;	/* size in bytes of MIXERCONTROLDETAILS */
+    DWORD	dwControlID;	/* control id to get/set details on */
+    DWORD	cChannels;	/* number of channels in paDetails array */
+    union {
+        HWND16	hwndOwner;	/* for MIXER_SETCONTROLDETAILSF_CUSTOM */
+        DWORD	cMultipleItems;	/* if _MULTIPLE, the number of items per channel */
+    } u;
+    DWORD	cbDetails;	/* size of _one_ details_XX struct */
+    LPVOID	paDetails;	/* pointer to array of details_XX structs */
+} MIXERCONTROLDETAILS16,*LPMIXERCONTROLDETAILS16;
+
+typedef struct {
+    DWORD	cbStruct;
+    DWORD	dwControlID;
+    DWORD	cChannels;
+    union {
+        HWND32	hwndOwner;
+        DWORD	cMultipleItems;
+    } u;
+    DWORD	cbDetails;
+    LPVOID	paDetails;
+} MIXERCONTROLDETAILS32,*LPMIXERCONTROLDETAILS32;
+
+DECL_WINELIB_TYPE(MIXERCONTROLDETAILS);
+DECL_WINELIB_TYPE(LPMIXERCONTROLDETAILS);
+
+typedef struct {
+    DWORD	dwParam1;
+    DWORD	dwParam2;
+    CHAR	szName[MIXER_LONG_NAME_CHARS];
+} MIXERCONTROLDETAILS_LISTTEXT16,*LPMIXERCONTROLDETAILS_LISTTEXT16;
+
+typedef struct {
+    DWORD	dwParam1;
+    DWORD	dwParam2;
+    CHAR	szName[MIXER_LONG_NAME_CHARS];
+} MIXERCONTROLDETAILS_LISTTEXT32A,*LPMIXERCONTROLDETAILS_LISTTEXT32A;
+
+typedef struct {
+    DWORD	dwParam1;
+    DWORD	dwParam2;
+    WCHAR	szName[MIXER_LONG_NAME_CHARS];
+} MIXERCONTROLDETAILS_LISTTEXT32W,*LPMIXERCONTROLDETAILS_LISTTEXT32W;
+
+DECL_WINELIB_TYPE_AW(MIXERCONTROLDETAILS);
+DECL_WINELIB_TYPE_AW(LPMIXERCONTROLDETAILS);
+
+/*  MIXER_GETCONTROLDETAILSF_VALUE */
+typedef struct {
+	LONG	fValue;
+} MIXERCONTROLDETAILS_BOOLEAN,*LPMIXERCONTROLDETAILS_BOOLEAN;
+
+typedef struct {
+	LONG	lValue;
+} MIXERCONTROLDETAILS_SIGNED,*LPMIXERCONTROLDETAILS_SIGNED;
+
+typedef struct {
+	DWORD	dwValue;
+} MIXERCONTROLDETAILS_UNSIGNED,*LPMIXERCONTROLDETAILS_UNSIGNED;
+
+/* bits passed to mixerGetLineInfo.fdwInfo */
+#define MIXER_GETLINEINFOF_DESTINATION		0x00000000L
+#define MIXER_GETLINEINFOF_SOURCE		0x00000001L
+#define MIXER_GETLINEINFOF_LINEID		0x00000002L
+#define MIXER_GETLINEINFOF_COMPONENTTYPE	0x00000003L
+#define MIXER_GETLINEINFOF_TARGETTYPE		0x00000004L
+#define MIXER_GETLINEINFOF_QUERYMASK		0x0000000FL
+
+/* bitmask passed to mixerGetLineControl */
+#define MIXER_GETLINECONTROLSF_ALL		0x00000000L
+#define MIXER_GETLINECONTROLSF_ONEBYID		0x00000001L
+#define MIXER_GETLINECONTROLSF_ONEBYTYPE	0x00000002L
+#define MIXER_GETLINECONTROLSF_QUERYMASK	0x0000000FL
+
+/* bitmask passed to mixerGetControlDetails */
+#define MIXER_GETCONTROLDETAILSF_VALUE		0x00000000L
+#define MIXER_GETCONTROLDETAILSF_LISTTEXT	0x00000001L
+#define MIXER_GETCONTROLDETAILSF_QUERYMASK	0x0000000FL
+
+/* bitmask passed to mixerSetControlDetails */
+#define	MIXER_SETCONTROLDETAILSF_VALUE		0x00000000L
+#define	MIXER_SETCONTROLDETAILSF_CUSTOM		0x00000001L
+#define	MIXER_SETCONTROLDETAILSF_QUERYMASK	0x0000000FL
+
+UINT16 WINAPI mixerGetNumDevs16();
+UINT32 WINAPI mixerGetNumDevs32();
+#define mixerGetNumDevs WINELIB_NAME(mixerGetNumDevs)
+UINT16 WINAPI mixerOpen16(LPHMIXER16,UINT16,DWORD,DWORD,DWORD);
+UINT32 WINAPI mixerOpen32(LPHMIXER32,UINT32,DWORD,DWORD,DWORD);
+#define mixerOpen WINELIB_NAME(mixerOpen)
+UINT16 WINAPI mixerClose16(HMIXER16);
+UINT32 WINAPI mixerClose32(HMIXER32);
+#define mixerClose WINELIB_NAME(mixerClose)
+UINT16 WINAPI mixerMessage16(HMIXER16,UINT16,DWORD,DWORD);
+UINT32 WINAPI mixerMessage32(HMIXER32,UINT32,DWORD,DWORD);
+#define mixerMessage WINELIB_NAME(mixerMessage)
+UINT16 WINAPI mixerGetDevCaps16(UINT16,LPMIXERCAPS16,UINT16);
+UINT32 WINAPI mixerGetDevCaps32A(UINT32,LPMIXERCAPS32A,UINT32);
+UINT32 WINAPI mixerGetDevCaps32W(UINT32,LPMIXERCAPS32W,UINT32);
+#define mixerGetDevCaps WINELIB_NAME_AW(mixerGetDevCaps)
+UINT16 WINAPI mixerGetLineInfo16(HMIXEROBJ16,LPMIXERLINE16,DWORD);
+UINT32 WINAPI mixerGetLineInfo32A(HMIXEROBJ32,LPMIXERLINE32A,DWORD);
+UINT32 WINAPI mixerGetLineInfo32W(HMIXEROBJ32,LPMIXERLINE32W,DWORD);
+#define mixerGetLineInfo WINELIB_NAME_AW(mixerGetLineInfo)
+UINT16 WINAPI mixerGetID16(HMIXEROBJ16,LPUINT16,DWORD);
+UINT32 WINAPI mixerGetID32(HMIXEROBJ32,LPUINT32,DWORD);
+#define mixerGetID WINELIB_NAME(mixerGetID)
+UINT16 WINAPI mixerGetLineControls16(HMIXEROBJ16,LPMIXERLINECONTROLS16,DWORD);
+UINT32 WINAPI mixerGetLineControls32A(HMIXEROBJ32,LPMIXERLINECONTROLS32A,DWORD);
+UINT32 WINAPI mixerGetLineControls32W(HMIXEROBJ32,LPMIXERLINECONTROLS32W,DWORD);
+#define mixerGetLineControl WINELIB_NAME_AW(mixerGetLineControl)
+UINT16 WINAPI mixerGetControlDetails16(HMIXEROBJ16,LPMIXERCONTROLDETAILS16,DWORD);
+UINT32 WINAPI mixerGetControlDetails32A(HMIXEROBJ32,LPMIXERCONTROLDETAILS32,DWORD);
+UINT32 WINAPI mixerGetControlDetails32W(HMIXEROBJ32,LPMIXERCONTROLDETAILS32,DWORD);
+#define mixerGetControlDetails WINELIB_NAME_AW(mixerGetControlDetails)
+UINT16 WINAPI mixerSetControlDetails16(HMIXEROBJ16,LPMIXERCONTROLDETAILS16,DWORD);
+UINT32 WINAPI mixerSetControlDetails32A(HMIXEROBJ16,LPMIXERCONTROLDETAILS32,DWORD);
+UINT32 WINAPI mixerSetControlDetails32W(HMIXEROBJ16,LPMIXERCONTROLDETAILS32,DWORD);
+#define mixerSetControlDetails WINELIB_NAME_AW(mixerSetControlDetails)
+
 #define MMIOERR_BASE            256
 #define MMIOERR_FILENOTFOUND    (MMIOERR_BASE + 1)  /* file not found */
 #define MMIOERR_OUTOFMEMORY     (MMIOERR_BASE + 2)  /* out of memory */
@@ -543,26 +1279,48 @@
 DECL_WINELIB_TYPE(LPMMIOPROC);
 
 typedef struct {
-        DWORD           dwFlags;        /* general status flags */
-        FOURCC          fccIOProc;      /* pointer to I/O procedure */
-        LPMMIOPROC16    pIOProc;        /* pointer to I/O procedure */
-        UINT16            wErrorRet;      /* place for error to be returned */
-        HTASK16         htask;          /* alternate local task */
+        DWORD		dwFlags;	/* general status flags */
+        FOURCC		fccIOProc;	/* pointer to I/O procedure */
+        LPMMIOPROC16	pIOProc;	/* pointer to I/O procedure */
+        UINT16		wErrorRet;	/* place for error to be returned */
+        HTASK16		htask;		/* alternate local task */
         /* fields maintained by MMIO functions during buffered I/O */
-        LONG            cchBuffer;      /* size of I/O buffer (or 0L) */
-        HPSTR           pchBuffer;      /* start of I/O buffer (or NULL) */
-        HPSTR           pchNext;        /* pointer to next byte to read/write */
-        HPSTR           pchEndRead;     /* pointer to last valid byte to read */
-        HPSTR           pchEndWrite;    /* pointer to last byte to write */
-        LONG            lBufOffset;     /* disk offset of start of buffer */
+        LONG		cchBuffer;	/* size of I/O buffer (or 0L) */
+        HPSTR		pchBuffer;	/* start of I/O buffer (or NULL) */
+        HPSTR		pchNext;	/* pointer to next byte to read/write */
+        HPSTR		pchEndRead;	/* pointer to last valid byte to read */
+        HPSTR		pchEndWrite;	/* pointer to last byte to write */
+        LONG		lBufOffset;	/* disk offset of start of buffer */
         /* fields maintained by I/O procedure */
-        LONG            lDiskOffset;    /* disk offset of next read or write */
-        DWORD           adwInfo[3];     /* data specific to type of MMIOPROC */
+        LONG		lDiskOffset;	/* disk offset of next read or write */
+        DWORD		adwInfo[3];	/* data specific to type of MMIOPROC */
         /* other fields maintained by MMIO */
-        DWORD           dwReserved1;    /* reserved for MMIO use */
-        DWORD           dwReserved2;    /* reserved for MMIO use */
-        HMMIO16         hmmio;          /* handle to open file */
-} MMIOINFO, *LPMMIOINFO;
+        DWORD		dwReserved1;	/* reserved for MMIO use */
+        DWORD		dwReserved2;	/* reserved for MMIO use */
+        HMMIO16		hmmio;		/* handle to open file */
+} MMIOINFO16, *LPMMIOINFO16;
+
+typedef struct {
+        DWORD		dwFlags;
+        FOURCC		fccIOProc;
+        LPMMIOPROC32	pIOProc;
+        UINT32		wErrorRet;
+        HTASK32		htask;
+        /* fields maintained by MMIO functions during buffered I/O */
+        LONG		cchBuffer;
+        HPSTR		pchBuffer;
+        HPSTR		pchNext;
+        HPSTR		pchEndRead;
+        HPSTR		pchEndWrite;
+        LONG		lBufOffset;
+        /* fields maintained by I/O procedure */
+        LONG		lDiskOffset;
+        DWORD		adwInfo[3];
+        /* other fields maintained by MMIO */
+        DWORD		dwReserved1;
+        DWORD		dwReserved2;
+        HMMIO32		hmmio;
+} MMIOINFO32, *LPMMIOINFO32;
 
 typedef struct _MMCKINFO
 {
@@ -640,23 +1398,28 @@
 LPMMIOPROC32 WINAPI mmioInstallIOProc32W(FOURCC,LPMMIOPROC32,DWORD);
 #define      mmioInstallIOPro WINELIB_NAME_AW(mmioInstallIOProc)
 
-FOURCC WINAPI mmioStringToFOURCC(LPCSTR sz, UINT16 uFlags);
-HMMIO16 WINAPI mmioOpen(LPSTR szFileName, MMIOINFO * lpmmioinfo,
-    DWORD dwOpenFlags);
+FOURCC WINAPI mmioStringToFOURCC16(LPCSTR sz, UINT16 uFlags);
+FOURCC WINAPI mmioStringToFOURCC32A(LPCSTR sz, UINT32 uFlags);
+FOURCC WINAPI mmioStringToFOURCC32W(LPCWSTR sz, UINT32 uFlags);
+#define mmioStringToFOURCC WINELIB_NAME_AW(mmioStringToFOURCC)
+HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16 * lpmmioinfo, DWORD dwOpenFlags);
+HMMIO32 WINAPI mmioOpen32A(LPSTR szFileName, MMIOINFO32 * lpmmioinfo, DWORD dwOpenFlags);
+HMMIO32 WINAPI mmioOpen32W(LPWSTR szFileName, MMIOINFO32 * lpmmioinfo, DWORD dwOpenFlags);
+#define mmioOpen WINELIB_NAME_AW(mmioOpen)
 
 UINT16 WINAPI mmioRename(LPCSTR szFileName, LPCSTR szNewFileName,
-     MMIOINFO * lpmmioinfo, DWORD dwRenameFlags);
+     MMIOINFO16 * lpmmioinfo, DWORD dwRenameFlags);
 
 UINT16 WINAPI mmioClose(HMMIO16 hmmio, UINT16 uFlags);
 LONG WINAPI mmioRead(HMMIO16 hmmio, HPSTR pch, LONG cch);
 LONG WINAPI mmioWrite(HMMIO16 hmmio, HPCSTR pch, LONG cch);
 LONG WINAPI mmioSeek(HMMIO16 hmmio, LONG lOffset, int iOrigin);
-UINT16 WINAPI mmioGetInfo(HMMIO16 hmmio, MMIOINFO * lpmmioinfo, UINT16 uFlags);
-UINT16 WINAPI mmioSetInfo(HMMIO16 hmmio, const MMIOINFO * lpmmioinfo, UINT16 uFlags);
+UINT16 WINAPI mmioGetInfo(HMMIO16 hmmio, MMIOINFO16 * lpmmioinfo, UINT16 uFlags);
+UINT16 WINAPI mmioSetInfo(HMMIO16 hmmio, const MMIOINFO16 * lpmmioinfo, UINT16 uFlags);
 UINT16 WINAPI mmioSetBuffer(HMMIO16 hmmio, LPSTR pchBuffer, LONG cchBuffer,
     UINT16 uFlags);
 UINT16 WINAPI mmioFlush(HMMIO16 hmmio, UINT16 uFlags);
-UINT16 WINAPI mmioAdvance(HMMIO16 hmmio, MMIOINFO * lpmmioinfo, UINT16 uFlags);
+UINT16 WINAPI mmioAdvance(HMMIO16 hmmio, MMIOINFO16 * lpmmioinfo, UINT16 uFlags);
 LONG WINAPI mmioSendMessage(HMMIO16 hmmio, UINT16 uMessage,
     LPARAM lParam1, LPARAM lParam2);
 UINT16 WINAPI mmioDescend(HMMIO16 hmmio, MMCKINFO * lpck,
@@ -674,8 +1437,10 @@
 UINT16 WINAPI mciGetDeviceID (LPCSTR lpstrName);
 UINT16 WINAPI mciGetDeviceIDFromElementID (DWORD dwElementID,
                                            LPCSTR lpstrType);
-BOOL16 WINAPI mciGetErrorString (DWORD wError, LPSTR lpstrBuffer,
-                                 UINT16 uLength);
+BOOL16 WINAPI mciGetErrorString16 (DWORD,LPSTR,UINT16);
+BOOL32 WINAPI mciGetErrorString32A(DWORD,LPSTR,UINT32);
+BOOL32 WINAPI mciGetErrorString32W(DWORD,LPWSTR,UINT32);
+#define mciGetErrorString WINELIB_NAME_AW(mciGetErrorString)
 BOOL16 WINAPI mciSetYieldProc (UINT16 uDeviceID, YIELDPROC fpYieldProc,
                                DWORD dwYieldData);
 
@@ -945,13 +1710,32 @@
 } MCI_GENERIC_PARMS, *LPMCI_GENERIC_PARMS;
 
 typedef struct {
-	DWORD   dwCallback;
-	UINT16  wDeviceID;
-	UINT16  wReserved0;
-	SEGPTR  lpstrDeviceType;
-	SEGPTR  lpstrElementName;
-	SEGPTR  lpstrAlias;
-} MCI_OPEN_PARMS, *LPMCI_OPEN_PARMS;
+	DWORD	dwCallback;
+	WORD	wDeviceID;
+	WORD	wReserved0;
+	LPSTR	lpstrDeviceType;
+	LPSTR	lpstrElementName;
+	LPSTR	lpstrAlias;
+} MCI_OPEN_PARMS16, *LPMCI_OPEN_PARMS16;
+
+typedef struct {
+	DWORD		dwCallback;
+	MCIDEVICEID32	wDeviceID;
+	LPSTR		lpstrDeviceType;
+	LPSTR		lpstrElementName;
+	LPSTR		lpstrAlias;
+} MCI_OPEN_PARMS32A, *LPMCI_OPEN_PARMS32A;
+
+typedef struct {
+	DWORD		dwCallback;
+	MCIDEVICEID32	wDeviceID;
+	LPWSTR		lpstrDeviceType;
+	LPWSTR		lpstrElementName;
+	LPWSTR		lpstrAlias;
+} MCI_OPEN_PARMS32W, *LPMCI_OPEN_PARMS32W;
+
+DECL_WINELIB_TYPE_AW(MCI_OPEN_PARMS);
+DECL_WINELIB_TYPE_AW(LPMCI_OPEN_PARMS);
 
 typedef struct {
 	DWORD   dwCallback;
@@ -975,7 +1759,22 @@
 	DWORD   dwCallback;
 	LPSTR   lpstrReturn;
 	DWORD   dwRetSize;
-} MCI_INFO_PARMS, *LPMCI_INFO_PARMS;
+} MCI_INFO_PARMS16, *LPMCI_INFO_PARMS16;
+
+typedef struct {
+	DWORD   dwCallback;
+	LPSTR   lpstrReturn;
+	DWORD   dwRetSize;
+} MCI_INFO_PARMS32A, *LPMCI_INFO_PARMS32A;
+
+typedef struct {
+	DWORD   dwCallback;
+	LPSTR   lpstrReturn;
+	DWORD   dwRetSize;
+} MCI_INFO_PARMS32W, *LPMCI_INFO_PARMS32W;
+
+DECL_WINELIB_TYPE(MCI_INFO_PARMS);
+DECL_WINELIB_TYPE(LPMCI_INFO_PARMS);
 
 typedef struct {
 	DWORD   dwCallback;
@@ -984,13 +1783,32 @@
 } MCI_GETDEVCAPS_PARMS, *LPMCI_GETDEVCAPS_PARMS;
 
 typedef struct {
-	DWORD   dwCallback;
-	LPSTR   lpstrReturn;
-	DWORD   dwRetSize;
-	DWORD   dwNumber;
-	UINT16    wDeviceType;
-	UINT16    wReserved0;
-} MCI_SYSINFO_PARMS, *LPMCI_SYSINFO_PARMS;
+	DWORD	dwCallback;
+	LPSTR	lpstrReturn;
+	DWORD	dwRetSize;
+	DWORD	dwNumber;
+	WORD	wDeviceType;
+	WORD	wReserved0;
+} MCI_SYSINFO_PARMS16, *LPMCI_SYSINFO_PARMS16;
+
+typedef struct {
+	DWORD	dwCallback;
+	LPSTR	lpstrReturn;
+	DWORD	dwRetSize;
+	DWORD	dwNumber;
+	UINT32	wDeviceType;
+} MCI_SYSINFO_PARMS32A, *LPMCI_SYSINFO_PARMS32A;
+
+typedef struct {
+	DWORD	dwCallback;
+	LPWSTR	lpstrReturn;
+	DWORD	dwRetSize;
+	DWORD	dwNumber;
+	UINT32	wDeviceType;
+} MCI_SYSINFO_PARMS32W, *LPMCI_SYSINFO_PARMS32W;
+
+DECL_WINELIB_TYPE_AW(MCI_SYSINFO_PARMS);
+DECL_WINELIB_TYPE_AW(LPMCI_SYSINFO_PARMS);
 
 typedef struct {
 	DWORD   dwCallback;
@@ -999,12 +1817,21 @@
 } MCI_SET_PARMS, *LPMCI_SET_PARMS;
 
 typedef struct {
-	DWORD   dwCallback;
-	int     nVirtKey;
-	UINT16    wReserved0;
-	HWND16  hwndBreak;
-	UINT16    wReserved1;
-} MCI_BREAK_PARMS, *LPMCI_BREAK_PARMS;
+	DWORD	dwCallback;
+	UINT16	nVirtKey;
+	WORD	wReserved0;
+	HWND16	hwndBreak;
+	WORD	wReserved1;
+} MCI_BREAK_PARMS16, *LPMCI_BREAK_PARMS16;
+
+typedef struct {
+	DWORD	dwCallback;
+	INT32	nVirtKey;
+	HWND32	hwndBreak;
+} MCI_BREAK_PARMS32, *LPMCI_BREAK_PARMS32;
+
+DECL_WINELIB_TYPE(MCI_BREAK_PARMS);
+DECL_WINELIB_TYPE(LPMCI_BREAK_PARMS);
 
 typedef struct {
 	DWORD   dwCallback;
@@ -1017,9 +1844,22 @@
 } MCI_SAVE_PARMS, *LPMCI_SAVE_PARMS;
 
 typedef struct {
-	DWORD   dwCallback;
-	LPCSTR  lpfilename;
-} MCI_LOAD_PARMS, *LPMCI_LOAD_PARMS;
+	DWORD	dwCallback;
+	LPCSTR	lpfilename;
+} MCI_LOAD_PARMS16, *LPMCI_LOAD_PARMS16;
+
+typedef struct {
+	DWORD	dwCallback;
+	LPCSTR	lpfilename;
+} MCI_LOAD_PARMS32A, *LPMCI_LOAD_PARMS32A;
+
+typedef struct {
+	DWORD	dwCallback;
+	LPCWSTR	lpfilename;
+} MCI_LOAD_PARMS32W, *LPMCI_LOAD_PARMS32W;
+
+DECL_WINELIB_TYPE(MCI_LOAD_PARMS);
+DECL_WINELIB_TYPE(LPMCI_LOAD_PARMS);
 
 typedef struct {
 	DWORD   dwCallback;
@@ -1078,9 +1918,22 @@
 } MCI_VD_STEP_PARMS, *LPMCI_VD_STEP_PARMS;
 
 typedef struct {
-	DWORD   dwCallback;
-	LPCSTR  lpstrCommand;
-} MCI_VD_ESCAPE_PARMS, *LPMCI_VD_ESCAPE_PARMS;
+	DWORD	dwCallback;
+	LPCSTR	lpstrCommand;
+} MCI_VD_ESCAPE_PARMS16, *LPMCI_VD_ESCAPE_PARMS16;
+
+typedef struct {
+	DWORD	dwCallback;
+	LPCSTR	lpstrCommand;
+} MCI_VD_ESCAPE_PARMS32A, *LPMCI_VD_ESCAPE_PARMS32A;
+
+typedef struct {
+	DWORD	dwCallback;
+	LPCWSTR	lpstrCommand;
+} MCI_VD_ESCAPE_PARMS32W, *LPMCI_VD_ESCAPE_PARMS32W;
+
+DECL_WINELIB_TYPE(MCI_VD_ESCAPE_PARMS);
+DECL_WINELIB_TYPE(LPMCI_VD_ESCAPE_PARMS);
 
 #define MCI_WAVE_OPEN_BUFFER            0x00010000L
 
@@ -1109,14 +1962,35 @@
 #define MCI_WAVE_GETDEVCAPS_OUTPUTS     0x00004002L
 
 typedef struct {
-	DWORD   dwCallback;
-	UINT16  wDeviceID;
-	UINT16  wReserved0;
-	SEGPTR  lpstrDeviceType;
-	SEGPTR  lpstrElementName;
-	SEGPTR  lpstrAlias;
-	DWORD   dwBufferSeconds;
-} MCI_WAVE_OPEN_PARMS, *LPMCI_WAVE_OPEN_PARMS;
+	DWORD		dwCallback;
+	MCIDEVICEID16	wDeviceID;
+	WORD		wReserved0;
+	SEGPTR		lpstrDeviceType;
+	SEGPTR		lpstrElementName;
+	SEGPTR		lpstrAlias;
+	DWORD		dwBufferSeconds;
+} MCI_WAVE_OPEN_PARMS16, *LPMCI_WAVE_OPEN_PARMS16;
+
+typedef struct {
+	DWORD		dwCallback;
+	MCIDEVICEID32	wDeviceID;
+	LPCSTR		lpstrDeviceType;
+	LPCSTR		lpstrElementName;
+	LPCSTR		lpstrAlias;
+	DWORD   	dwBufferSeconds;
+} MCI_WAVE_OPEN_PARMS32A, *LPMCI_WAVE_OPEN_PARMS32A;
+
+typedef struct {
+	DWORD		dwCallback;
+	MCIDEVICEID32	wDeviceID;
+	LPCWSTR		lpstrDeviceType;
+	LPCWSTR		lpstrElementName;
+	LPCWSTR		lpstrAlias;
+	DWORD   	dwBufferSeconds;
+} MCI_WAVE_OPEN_PARMS32W, *LPMCI_WAVE_OPEN_PARMS32W;
+
+DECL_WINELIB_TYPE_AW(MCI_WAVE_OPEN_PARMS);
+DECL_WINELIB_TYPE_AW(LPMCI_WAVE_OPEN_PARMS);
 
 typedef struct {
 	DWORD   dwCallback;
@@ -1125,24 +1999,41 @@
 } MCI_WAVE_DELETE_PARMS, *LPMCI_WAVE_DELETE_PARMS;
 
 typedef struct {
-	DWORD   dwCallback;
-	DWORD   dwTimeFormat;
-	DWORD   dwAudio;
-	UINT16    wInput;
-	UINT16    wReserved0;
-	UINT16    wOutput;
-	UINT16    wReserved1;
-	UINT16    wFormatTag;
-	UINT16    wReserved2;
-	UINT16    nChannels;
-	UINT16    wReserved3;
-	DWORD   nSamplesPerSec;
-	DWORD   nAvgBytesPerSec;
-	UINT16    nBlockAlign;
-	UINT16    wReserved4;
-	UINT16    wBitsPerSample;
-	UINT16    wReserved5;
-} MCI_WAVE_SET_PARMS, * LPMCI_WAVE_SET_PARMS;
+	DWORD	dwCallback;
+	DWORD	dwTimeFormat;
+	DWORD	dwAudio;
+	UINT16	wInput;
+	UINT16	wReserved0;
+	UINT16	wOutput;
+	UINT16	wReserved1;
+	UINT16	wFormatTag;
+	UINT16	wReserved2;
+	UINT16	nChannels;
+	UINT16	wReserved3;
+	DWORD	nSamplesPerSec;
+	DWORD	nAvgBytesPerSec;
+	UINT16	nBlockAlign;
+	UINT16	wReserved4;
+	UINT16	wBitsPerSample;
+	UINT16	wReserved5;
+} MCI_WAVE_SET_PARMS16, * LPMCI_WAVE_SET_PARMS16;
+
+typedef struct {
+	DWORD	dwCallback;
+	DWORD	dwTimeFormat;
+	DWORD	dwAudio;
+	UINT32	wInput;
+	UINT32	wOutput;
+	UINT32	wFormatTag;
+	UINT32	nChannels;
+	DWORD	nSamplesPerSec;
+	DWORD	nAvgBytesPerSec;
+	UINT32	nBlockAlign;
+	UINT32	wBitsPerSample;
+} MCI_WAVE_SET_PARMS32, * LPMCI_WAVE_SET_PARMS32;
+
+DECL_WINELIB_TYPE(MCI_WAVE_SET_PARMS);
+DECL_WINELIB_TYPE(LPMCI_WAVE_SET_PARMS);
 
 #define     MCI_SEQ_DIV_PPQN            (0 + MCI_SEQ_OFFSET)
 #define     MCI_SEQ_DIV_SMPTE_24        (1 + MCI_SEQ_OFFSET)
@@ -1239,7 +2130,30 @@
 	DWORD   dwStyle;
 	HWND16  hWndParent;
 	UINT16  wReserved1;
-} MCI_ANIM_OPEN_PARMS, *LPMCI_ANIM_OPEN_PARMS;
+} MCI_ANIM_OPEN_PARMS16, *LPMCI_ANIM_OPEN_PARMS16;
+
+typedef struct {
+	DWORD		dwCallback;
+	MCIDEVICEID32	wDeviceID;
+	LPCSTR		lpstrDeviceType;
+	LPCSTR		lpstrElementName;
+	LPCSTR		lpstrAlias;
+	DWORD		dwStyle;
+	HWND32		hWndParent;
+} MCI_ANIM_OPEN_PARMS32A, *LPMCI_ANIM_OPEN_PARMS32A;
+
+typedef struct {
+	DWORD		dwCallback;
+	MCIDEVICEID32	wDeviceID;
+	LPCSTR		lpstrDeviceType;
+	LPCSTR		lpstrElementName;
+	LPCSTR		lpstrAlias;
+	DWORD		dwStyle;
+	HWND32		hWndParent;
+} MCI_ANIM_OPEN_PARMS32W, *LPMCI_ANIM_OPEN_PARMS32W;
+
+DECL_WINELIB_TYPE_AW(MCI_ANIM_OPEN_PARMS);
+DECL_WINELIB_TYPE_AW(LPMCI_ANIM_OPEN_PARMS);
 
 typedef struct {
 	DWORD   dwCallback;
@@ -1254,13 +2168,30 @@
 } MCI_ANIM_STEP_PARMS, *LPMCI_ANIM_STEP_PARMS;
 
 typedef struct {
-	DWORD   dwCallback;
-	HWND16  hWnd;
-	UINT16    wReserved1;
-	UINT16    nCmdShow;
-	UINT16    wReserved2;
-	LPCSTR  lpstrText;
-} MCI_ANIM_WINDOW_PARMS, *LPMCI_ANIM_WINDOW_PARMS;
+	DWORD	dwCallback;
+	HWND16	hWnd;
+	WORD	wReserved1;
+	WORD	nCmdShow;
+	WORD	wReserved2;
+	LPCSTR	lpstrText;
+} MCI_ANIM_WINDOW_PARMS16, *LPMCI_ANIM_WINDOW_PARMS16;
+
+typedef struct {
+	DWORD	dwCallback;
+	HWND32	hWnd;
+	UINT32	nCmdShow;
+	LPCSTR	lpstrText;
+} MCI_ANIM_WINDOW_PARMS32A, *LPMCI_ANIM_WINDOW_PARMS32A;
+
+typedef struct {
+	DWORD	dwCallback;
+	HWND32	hWnd;
+	UINT32	nCmdShow;
+	LPCWSTR	lpstrText;
+} MCI_ANIM_WINDOW_PARMS32W, *LPMCI_ANIM_WINDOW_PARMS32W;
+
+DECL_WINELIB_TYPE(MCI_ANIM_WINDOW_PARMS);
+DECL_WINELIB_TYPE(LPMCI_ANIM_WINDOW_PARMS);
 
 typedef struct {
 	DWORD   dwCallback;
@@ -1270,13 +2201,35 @@
 #else   /* ifdef MCI_USE_OFFEXT */
 	RECT16  rc;
 #endif  /* ifdef MCI_USE_OFFEXT */
-} MCI_ANIM_RECT_PARMS, *LPMCI_ANIM_RECT_PARMS;
+} MCI_ANIM_RECT_PARMS16, *LPMCI_ANIM_RECT_PARMS16;
+
+typedef struct {
+	DWORD	dwCallback;
+#ifdef MCI_USE_OFFEXT
+	POINT32	ptOffset;
+	POINT32	ptExtent;
+#else   /* ifdef MCI_USE_OFFEXT */
+	RECT32	rc;
+#endif  /* ifdef MCI_USE_OFFEXT */
+} MCI_ANIM_RECT_PARMS32, *LPMCI_ANIM_RECT_PARMS32;
+
+DECL_WINELIB_TYPE(MCI_ANIM_RECT_PARMS);
+DECL_WINELIB_TYPE(LPMCI_ANIM_RECT_PARMS);
 
 typedef struct {
 	DWORD   dwCallback;
 	RECT16  rc;
 	HDC16   hDC;
-} MCI_ANIM_UPDATE_PARMS, *LPMCI_ANIM_UPDATE_PARMS;
+} MCI_ANIM_UPDATE_PARMS16, *LPMCI_ANIM_UPDATE_PARMS16;
+
+typedef struct {
+	DWORD   dwCallback;
+	RECT32  rc;
+	HDC32   hDC;
+} MCI_ANIM_UPDATE_PARMS32, *LPMCI_ANIM_UPDATE_PARMS32;
+
+DECL_WINELIB_TYPE(MCI_ANIM_UPDATE_PARMS);
+DECL_WINELIB_TYPE(LPMCI_ANIM_UPDATE_PARMS);
 
 #define MCI_OVLY_OPEN_WS                0x00010000L
 #define MCI_OVLY_OPEN_PARENT            0x00020000L
@@ -1310,25 +2263,65 @@
 #define MCI_OVLY_WHERE_VIDEO            0x00100000L
 
 typedef struct {
-	DWORD   dwCallback;
-	UINT16    wDeviceID;
-	UINT16    wReserved0;
-	LPCSTR  lpstrDeviceType;
-	LPCSTR  lpstrElementName;
-	LPCSTR  lpstrAlias;
-	DWORD   dwStyle;
-	HWND16  hWndParent;
-	UINT16    wReserved1;
-} MCI_OVLY_OPEN_PARMS, *LPMCI_OVLY_OPEN_PARMS;
+	DWORD		dwCallback;
+	MCIDEVICEID16	wDeviceID;
+	WORD		wReserved0;
+	LPCSTR		lpstrDeviceType;
+	LPCSTR		lpstrElementName;
+	LPCSTR		lpstrAlias;
+	DWORD		dwStyle;
+	HWND16		hWndParent;
+	WORD		wReserved1;
+} MCI_OVLY_OPEN_PARMS16, *LPMCI_OVLY_OPEN_PARMS16;
 
 typedef struct {
-	DWORD   dwCallback;
-	HWND16  hWnd;
-	UINT16    wReserved1;
-	UINT16    nCmdShow;
-	UINT16    wReserved2;
-	LPCSTR  lpstrText;
-} MCI_OVLY_WINDOW_PARMS, *LPMCI_OVLY_WINDOW_PARMS;
+	DWORD		dwCallback;
+	MCIDEVICEID32	wDeviceID;
+	LPCSTR		lpstrDeviceType;
+	LPCSTR		lpstrElementName;
+	LPCSTR		lpstrAlias;
+	DWORD		dwStyle;
+	HWND32		hWndParent;
+} MCI_OVLY_OPEN_PARMS32A, *LPMCI_OVLY_OPEN_PARMS32A;
+
+typedef struct {
+	DWORD		dwCallback;
+	MCIDEVICEID32	wDeviceID;
+	LPCWSTR		lpstrDeviceType;
+	LPCWSTR		lpstrElementName;
+	LPCWSTR		lpstrAlias;
+	DWORD		dwStyle;
+	HWND32		hWndParent;
+} MCI_OVLY_OPEN_PARMS32W, *LPMCI_OVLY_OPEN_PARMS32W;
+
+DECL_WINELIB_TYPE_AW(MCI_OVLY_OPEN_PARMS);
+DECL_WINELIB_TYPE_AW(LPMCI_OVLY_OPEN_PARMS);
+
+typedef struct {
+	DWORD	dwCallback;
+	HWND16	hWnd;
+	WORD	wReserved1;
+	UINT16	nCmdShow;
+	WORD	wReserved2;
+	LPCSTR	lpstrText;
+} MCI_OVLY_WINDOW_PARMS16, *LPMCI_OVLY_WINDOW_PARMS16;
+
+typedef struct {
+	DWORD	dwCallback;
+	HWND32	hWnd;
+	UINT32	nCmdShow;
+	LPCSTR	lpstrText;
+} MCI_OVLY_WINDOW_PARMS32A, *LPMCI_OVLY_WINDOW_PARMS32A;
+
+typedef struct {
+	DWORD	dwCallback;
+	HWND32	hWnd;
+	UINT32	nCmdShow;
+	LPCWSTR	lpstrText;
+} MCI_OVLY_WINDOW_PARMS32W, *LPMCI_OVLY_WINDOW_PARMS32W;
+
+DECL_WINELIB_TYPE_AW(MCI_OVLY_OPEN_WINDOW_PARMS);
+DECL_WINELIB_TYPE_AW(LPMCI_OVLY_OPEN_WINDOW_PARMS);
 
 typedef struct {
 	DWORD   dwCallback;
@@ -1338,20 +2331,62 @@
 #else   /* ifdef MCI_USE_OFFEXT */
 	RECT16  rc;
 #endif  /* ifdef MCI_USE_OFFEXT */
-} MCI_OVLY_RECT_PARMS, *LPMCI_OVLY_RECT_PARMS;
+} MCI_OVLY_RECT_PARMS16, *LPMCI_OVLY_RECT_PARMS16;
+
+typedef struct {
+	DWORD   dwCallback;
+#ifdef MCI_USE_OFFEXT
+	POINT32 ptOffset;
+	POINT32 ptExtent;
+#else   /* ifdef MCI_USE_OFFEXT */
+	RECT32  rc;
+#endif  /* ifdef MCI_USE_OFFEXT */
+} MCI_OVLY_RECT_PARMS32, *LPMCI_OVLY_RECT_PARMS32;
+
+DECL_WINELIB_TYPE(MCI_OVLY_RECT_PARMS);
+DECL_WINELIB_TYPE(LPMCI_OVLY_RECT_PARMS);
 
 typedef struct {
 	DWORD   dwCallback;
 	LPCSTR  lpfilename;
 	RECT16  rc;
-} MCI_OVLY_SAVE_PARMS, *LPMCI_OVLY_SAVE_PARMS;
+} MCI_OVLY_SAVE_PARMS16, *LPMCI_OVLY_SAVE_PARMS16;
 
 typedef struct {
 	DWORD   dwCallback;
 	LPCSTR  lpfilename;
-	RECT16  rc;
-} MCI_OVLY_LOAD_PARMS, *LPMCI_OVLY_LOAD_PARMS;
+	RECT32  rc;
+} MCI_OVLY_SAVE_PARMS32A, *LPMCI_OVLY_SAVE_PARMS32A;
 
+typedef struct {
+	DWORD   dwCallback;
+	LPCWSTR  lpfilename;
+	RECT32  rc;
+} MCI_OVLY_SAVE_PARMS32W, *LPMCI_OVLY_SAVE_PARMS32W;
+
+DECL_WINELIB_TYPE_AW(MCI_OVLY_SAVE_PARMS);
+DECL_WINELIB_TYPE_AW(LPMCI_OVLY_SAVE_PARMS);
+
+typedef struct {
+	DWORD	dwCallback;
+	LPCSTR	lpfilename;
+	RECT16	rc;
+} MCI_OVLY_LOAD_PARMS16, *LPMCI_OVLY_LOAD_PARMS16;
+
+typedef struct {
+	DWORD	dwCallback;
+	LPCSTR	lpfilename;
+	RECT32	rc;
+} MCI_OVLY_LOAD_PARMS32A, *LPMCI_OVLY_LOAD_PARMS32A;
+
+typedef struct {
+	DWORD	dwCallback;
+	LPCWSTR	lpfilename;
+	RECT32	rc;
+} MCI_OVLY_LOAD_PARMS32W, *LPMCI_OVLY_LOAD_PARMS32W;
+
+DECL_WINELIB_TYPE_AW(MCI_OVLY_LOAD_PARMS);
+DECL_WINELIB_TYPE_AW(LPMCI_OVLY_LOAD_PARMS);
 
 /**************************************************************
  * 		Linux MMSYSTEM Internals & Sample Audio Drivers
@@ -1427,6 +2462,15 @@
 #define AUXDM_GETVOLUME     5
 #define AUXDM_SETVOLUME     6
 
+#define	MXDM_GETNUMDEVS		1
+#define	MXDM_GETDEVCAPS		2
+#define	MXDM_OPEN		3
+#define	MXDM_CLOSE		4
+#define	MXDM_GETLINEINFO	5
+#define	MXDM_GETLINECONTROLS	6
+#define	MXDM_GETCONTROLDETAILS	7
+#define	MXDM_SETCONTROLDETAILS	8
+
 #define MCI_MAX_DEVICE_TYPE_LENGTH 80
 
 #define MCI_FALSE                       (MCI_STRING_OFFSET + 19)
@@ -1493,6 +2537,7 @@
 
 #define MAKEMCIRESOURCE(wRet, wRes) MAKELRESULT((wRet), (wRes))
 
+/* the 95 DDK defines those slightly different, but they are internal anyway */
 typedef struct {
 	DWORD   	dwCallback;
 	DWORD   	dwInstance;
@@ -1501,35 +2546,42 @@
 } PORTALLOC, *LPPORTALLOC;
 
 typedef struct {
-	HWAVE16			hWave;
+	HWAVE16		hWave;
 	LPWAVEFORMAT	lpFormat;
-	DWORD			dwCallBack;
-	DWORD			dwInstance;
-	UINT16                  uDeviceID;
+	DWORD		dwCallBack;
+	DWORD		dwInstance;
+	UINT16		uDeviceID;
 } WAVEOPENDESC, *LPWAVEOPENDESC;
 
 typedef struct {
-	HMIDI16			hMidi;
-	DWORD			dwCallback;
-	DWORD			dwInstance;
+	HMIDI16		hMidi;
+	DWORD		dwCallback;
+	DWORD		dwInstance;
 } MIDIOPENDESC, *LPMIDIOPENDESC;
 
 typedef struct {
-	UINT16			wDelay;
-	UINT16			wResolution;
+	UINT16		wDelay;
+	UINT16		wResolution;
 	LPTIMECALLBACK	lpFunction;
-	DWORD			dwUser;
-	UINT16			wFlags;
+	DWORD		dwUser;
+	UINT16		wFlags;
 } TIMEREVENT, *LPTIMEREVENT;
 
+typedef struct tMIXEROPENDESC
+{
+	HMIXEROBJ16	hmx;
+	DWORD		dwCallback;
+	DWORD		dwInstance;
+	UINT16		uDeviceID;
+} MIXEROPENDESC,*LPMIXEROPENDESC;
+
 typedef struct {
-	UINT16    wDeviceID;				/* device ID */
-	LPSTR 	lpstrParams;			/* parameter string for entry in SYSTEM.INI */
-	UINT16    wCustomCommandTable;	/* custom command table (0xFFFF if none) */
-									/* filled in by the driver */
-	UINT16    wType;					/* driver type */
-									/* filled in by the driver */
-} MCI_OPEN_DRIVER_PARMS, * LPMCI_OPEN_DRIVER_PARMS;
+	UINT16	wDeviceID;	/* device ID */
+	LPSTR	lpstrParams;	/* parameter string for entry in SYSTEM.INI */
+	UINT16	wCustomCommandTable;	/* custom command table (0xFFFF if none)
+					 * filled in by the driver */
+	UINT16	wType;		/* driver type (filled in by the driver) */
+} MCI_OPEN_DRIVER_PARMS, *LPMCI_OPEN_DRIVER_PARMS;
 
 DWORD  WINAPI mciGetDriverData(UINT16 uDeviceID);
 BOOL16 WINAPI mciSetDriverData(UINT16 uDeviceID, DWORD dwData);
@@ -1551,6 +2603,8 @@
                              WORD wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2);
 DWORD WINAPI auxMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
 					DWORD dwParam1, DWORD dwParam2);
+DWORD WINAPI mixMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
+					DWORD dwParam1, DWORD dwParam2);
 DWORD WINAPI midMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
 					DWORD dwParam1, DWORD dwParam2);
 DWORD WINAPI modMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
@@ -1559,5 +2613,6 @@
 					DWORD dwParam1, DWORD dwParam2);
 DWORD WINAPI wodMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
 					DWORD dwParam1, DWORD dwParam2);
+#pragma pack(4)
 
 #endif /* __WINE_MMSYSTEM_H */
diff --git a/include/module.h b/include/module.h
index b411b97..5b7cb2b 100644
--- a/include/module.h
+++ b/include/module.h
@@ -135,7 +135,8 @@
 extern BOOL32 BUILTIN_Init(void);
 extern HMODULE16 BUILTIN_LoadModule( LPCSTR name, BOOL32 force );
 extern LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, WORD *pOrd );
-extern FARPROC32 BUILTIN_GetEntryPoint32( char *buffer, void *relay );
+extern FARPROC32 BUILTIN_GetEntryPoint32( char *buffer, void *relay,
+                                          DWORD *typemask );
 extern FARPROC32 BUILTIN_GetProcAddress32(NE_MODULE *pModule, LPCSTR function);
 extern BOOL32 BUILTIN_ParseDLLOptions( const char *str );
 extern void BUILTIN_PrintDLLs(void);
diff --git a/include/region.h b/include/region.h
index c5818f1..d53546a 100644
--- a/include/region.h
+++ b/include/region.h
@@ -20,5 +20,6 @@
 extern BOOL32 REGION_DeleteObject( HRGN32 hrgn, RGNOBJ * obj );
 extern BOOL32 REGION_UnionRectWithRgn( HRGN32 hrgn, const RECT32 *lpRect );
 extern BOOL32 REGION_FrameRgn( HRGN32 dest, HRGN32 src, INT32 x, INT32 y );
+extern BOOL32 REGION_IsEmpty( HRGN32 rgn );
 
 #endif  /* __WINE_REGION_H */
diff --git a/include/stddebug.h b/include/stddebug.h
index c5ac25b..8f73efc 100644
--- a/include/stddebug.h
+++ b/include/stddebug.h
@@ -77,6 +77,7 @@
 
 #ifdef DEBUG_NONE
 #undef DEBUG_ACCEL
+#undef DEBUG_ASPI
 #undef DEBUG_ATOM
 #undef DEBUG_BITBLT
 #undef DEBUG_BITMAP
@@ -97,7 +98,6 @@
 #undef DEBUG_DOSFS
 #undef DEBUG_DRIVER
 #undef DEBUG_EDIT
-#undef DEBUG_ENV
 #undef DEBUG_EVENT
 #undef DEBUG_EXEC
 #undef DEBUG_FILE
@@ -163,6 +163,7 @@
 
 #ifdef DEBUG_ALL
 #define DEBUG_ACCEL
+#define DEBUG_ASPI
 #define DEBUG_ATOM
 #define DEBUG_BITBLT
 #define DEBUG_BITMAP
@@ -183,7 +184,6 @@
 #define DEBUG_DOSFS
 #define DEBUG_DRIVER
 #define DEBUG_EDIT
-#define DEBUG_ENV
 #define DEBUG_EVENT
 #define DEBUG_EXEC
 #define DEBUG_FILE
diff --git a/include/windows.h b/include/windows.h
index 83d4603..a37a669 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -768,12 +768,21 @@
 #define DLGWINDOWEXTRA      30
 
   /* Dialog styles */
-#define DS_ABSALIGN         0x001
-#define DS_SYSMODAL         0x002
-#define DS_LOCALEDIT        0x020
-#define DS_SETFONT          0x040
-#define DS_MODALFRAME       0x080
-#define DS_NOIDLEMSG        0x100
+#define DS_ABSALIGN		0x0001
+#define DS_SYSMODAL		0x0002
+#define DS_3DLOOK		0x0004	/* win95 */
+#define DS_FIXEDSYS		0x0008	/* win95 */
+#define DS_NOFAILCREATE		0x0010	/* win95 */
+#define DS_LOCALEDIT		0x0020
+#define DS_SETFONT		0x0040
+#define DS_MODALFRAME		0x0080
+#define DS_NOIDLEMSG		0x0100
+#define DS_SETFOREGROUND	0x0200	/* win95 */
+#define DS_CONTROL		0x0400	/* win95 */
+#define DS_CENTER		0x0800	/* win95 */
+#define DS_CENTERMOUSE		0x1000	/* win95 */
+#define DS_CONTEXTHELP		0x2000	/* win95 */
+
 
   /* Dialog messages */
 #define DM_GETDEFID         (WM_USER+0)
@@ -1917,7 +1926,7 @@
 } DIBSECTION,*LPDIBSECTION;
 
 
-  /* Cursors / Icons */
+/* Cursors / Icons */
 
 typedef struct
 {
@@ -1929,7 +1938,14 @@
     BYTE    bBitsPerPixel;
 } CURSORICONINFO;
 
-
+/* only used by Win32 functions */
+typedef struct {
+	BOOL32		fIcon;
+	DWORD		xHotspot;
+	DWORD		yHotspot;
+	HBITMAP32	hbmMask;
+	HBITMAP32	hbmColor;
+} ICONINFO,*LPICONINFO;
 
 typedef struct {
 	BYTE i;  /* much more .... */
@@ -3227,13 +3243,34 @@
 #define SS_BLACKFRAME       0x00000007L
 #define SS_GRAYFRAME        0x00000008L
 #define SS_WHITEFRAME       0x00000009L
+
 #define SS_SIMPLE           0x0000000BL
 #define SS_LEFTNOWORDWRAP   0x0000000CL
+
+#define SS_OWNERDRAW        0x0000000DL
+#define SS_BITMAP           0x0000000EL
+#define SS_ENHMETAFILE      0x0000000FL
+
+#define SS_ETCHEDHORZ       0x00000010L
+#define SS_ETCHEDVERT       0x00000011L
+#define SS_ETCHEDFRAME      0x00000012L
+#define SS_TYPEMASK         0x0000001FL
+
 #define SS_NOPREFIX         0x00000080L
+#define SS_CENTERIMAGE      0x00000200L
+#define SS_RIGHTJUST        0x00000400L
+#define SS_REALSIZEIMAGE    0x00000800L
+#define SS_SUNKEN           0x00001000L
 
 /* Static Control Messages */
-#define STM_SETICON         (WM_USER+0)
-#define STM_GETICON         (WM_USER+1)
+#define STM_SETICON16       (WM_USER+0)
+#define STM_SETICON32       0x0170
+#define STM_SETICON	    WINELIB_NAME(STM_SETICON)
+#define STM_GETICON16       (WM_USER+1)
+#define STM_GETICON32       0x0171
+#define STM_GETICON	    WINELIB_NAME(STM_GETICON)
+#define STM_SETIMAGE        0x0172
+#define STM_GETIMAGE        0x0173
 
 /* WM_H/VSCROLL commands */
 #define SB_LINEUP           0
@@ -5430,6 +5467,7 @@
 HANDLE32    WINAPI CreateFileMapping32W(HANDLE32,LPSECURITY_ATTRIBUTES,DWORD,
                                         DWORD,DWORD,LPCWSTR);
 #define     CreateFileMapping WINELIB_NAME_AW(CreateFileMapping)
+HICON32     WINAPI CreateIconIndirect(LPICONINFO);
 HANDLE32    WINAPI CreateMutex32A(LPSECURITY_ATTRIBUTES,BOOL32,LPCSTR);
 HANDLE32    WINAPI CreateMutex32W(LPSECURITY_ATTRIBUTES,BOOL32,LPCWSTR);
 #define     CreateMutex WINELIB_NAME_AW(CreateMutex)
@@ -5508,6 +5546,7 @@
 BOOL32      WINAPI GetMenuItemInfo32A(HMENU32,UINT32,BOOL32,MENUITEMINFO32A*);
 BOOL32      WINAPI GetMenuItemInfo32W(HMENU32,UINT32,BOOL32,MENUITEMINFO32W*);
 #define     GetMenuItemInfo WINELIB_NAME_AW(GetMenuItemInfo)
+DWORD       WINAPI GetObjectType(HANDLE32);
 UINT32      WINAPI GetOEMCP(void);
 DWORD       WINAPI GetPriorityClass(HANDLE32);
 INT32       WINAPI GetPrivateProfileSection32A(LPCSTR,LPSTR,INT32,LPCSTR);
@@ -5562,6 +5601,9 @@
 BOOL32      WINAPI MoveFile32A(LPCSTR,LPCSTR);
 BOOL32      WINAPI MoveFile32W(LPCWSTR,LPCWSTR);
 #define     MoveFile WINELIB_NAME_AW(MoveFile)
+BOOL32      WINAPI MoveFileEx32A(LPCSTR,LPCSTR,DWORD);
+BOOL32      WINAPI MoveFileEx32W(LPCWSTR,LPCWSTR,DWORD);
+#define     MoveFileEx WINELIB_NAME_AW(MoveFileEx)
 HANDLE32    WINAPI OpenEvent32A(DWORD,BOOL32,LPCSTR);
 HANDLE32    WINAPI OpenEvent32W(DWORD,BOOL32,LPCWSTR);
 #define     OpenEvent WINELIB_NAME_AW(OpenEvent)
diff --git a/include/winproc.h b/include/winproc.h
index 592b357..83018a6 100644
--- a/include/winproc.h
+++ b/include/winproc.h
@@ -57,26 +57,22 @@
 extern INT32 WINPROC_MapMsg16To32W( UINT16 msg16, WPARAM16 wParam16,
                                     UINT32 *pmsg32, WPARAM32 *pwparam32,
                                     LPARAM *plparam );
-extern INT32 WINPROC_MapMsg32ATo16( UINT32 msg32, WPARAM32 wParam32,
-                                    UINT16 *pmsg16, WPARAM16 *pwparam16,
-                                    LPARAM *plparam );
-extern INT32 WINPROC_MapMsg32WTo16( UINT32 msg32, WPARAM32 wParam32,
-                                    UINT16 *pmsg16, WPARAM16 *pwparam16,
-                                    LPARAM *plparam );
+extern INT32 WINPROC_MapMsg32ATo16( HWND32 hwnd, UINT32 msg32,
+                                    WPARAM32 wParam32, UINT16 *pmsg16,
+                                    WPARAM16 *pwparam16, LPARAM *plparam );
+extern INT32 WINPROC_MapMsg32WTo16( HWND32 hwnd, UINT32 msg32,
+                                    WPARAM32 wParam32, UINT16 *pmsg16,
+                                    WPARAM16 *pwparam16, LPARAM *plparam );
 extern void WINPROC_UnmapMsg32ATo32W( UINT32 msg, WPARAM32 wParam,
                                       LPARAM lParam );
 extern void WINPROC_UnmapMsg32WTo32A( UINT32 msg, WPARAM32 wParam,
                                       LPARAM lParam );
-extern void WINPROC_UnmapMsg16To32A( UINT32 msg, WPARAM32 wParam,
-                                     LPARAM lParam );
-extern void WINPROC_UnmapMsg16To32W( UINT32 msg, WPARAM32 wParam,
-                                     LPARAM lParam );
+extern LRESULT WINPROC_UnmapMsg16To32A( UINT32 msg, WPARAM32 wParam,
+                                        LPARAM lParam, LRESULT result );
+extern LRESULT WINPROC_UnmapMsg16To32W( UINT32 msg, WPARAM32 wParam,
+                                        LPARAM lParam, LRESULT result );
 extern void WINPROC_UnmapMsg32ATo16( UINT32 msg, WPARAM32 wParam,
                                      LPARAM lParam, MSGPARAM16* pm16 );
 extern void WINPROC_UnmapMsg32WTo16( UINT32 msg, WPARAM32 wParam,
                                      LPARAM lParam, MSGPARAM16* pm16 );
-
-typedef LRESULT (*WINPROC_CALLWNDPROC16)(WNDPROC16,HWND16,UINT16,WPARAM16,LPARAM);
-extern void WINPROC_SetCallWndProc16( WINPROC_CALLWNDPROC16 proc );
-
 #endif  /* __WINE_WINPROC_H */
diff --git a/include/winsock.h b/include/winsock.h
index 84187ef..d202655 100644
--- a/include/winsock.h
+++ b/include/winsock.h
@@ -435,6 +435,7 @@
 
 /* ws_... struct conversion flags */
 
+#define WS_DUP_LINEAR		0x0000
 #define WS_DUP_NATIVE           0x0001		/* native structure format (not ws_..) */
 #define WS_DUP_OFFSET           0x0002		/* internal pointers are offsets */
 #define WS_DUP_SEGPTR           0x0004		/* internal pointers are SEGPTRs */
diff --git a/include/wintypes.h b/include/wintypes.h
index afbf781..7cf79d5 100644
--- a/include/wintypes.h
+++ b/include/wintypes.h
@@ -122,7 +122,6 @@
 typedef ACCESS_MASK     REGSAM;
 typedef HANDLE32        HHOOK;
 typedef HANDLE32        HKEY;
-typedef HANDLE32        HMIXEROBJ;
 typedef DWORD           LCID;
 typedef WORD            LANGID;
 typedef DWORD           LCTYPE;
@@ -145,7 +144,6 @@
 typedef INT32          *LPINT32;
 typedef UINT32         *LPUINT32;
 typedef HKEY           *LPHKEY;
-typedef HMIXEROBJ      *LPHMIXEROBJ;
 typedef FLOAT          *LPFLOAT;
 
 /* Special case: a segmented pointer is just a pointer in the user's code. */
@@ -179,6 +177,8 @@
 DECLARE_HANDLE(HMIDI);
 DECLARE_HANDLE(HMIDIIN);
 DECLARE_HANDLE(HMIDIOUT);
+DECLARE_HANDLE(HMIXER);
+DECLARE_HANDLE(HMIXEROBJ);
 DECLARE_HANDLE(HMMIO);
 DECLARE_HANDLE(HMODULE);
 DECLARE_HANDLE(HPALETTE);
diff --git a/library/miscstubs.c b/library/miscstubs.c
index aaafc88..7e61917 100644
--- a/library/miscstubs.c
+++ b/library/miscstubs.c
@@ -3,7 +3,7 @@
  *      libwine.a.
  */
 
-#include <stdarg.h>
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -21,7 +21,6 @@
 extern LRESULT PrintDlgProc(HWND16,UINT16,WPARAM16,LPARAM);
 extern LRESULT PrintSetupDlgProc(HWND16,UINT16,WPARAM16,LPARAM);
 extern LRESULT ReplaceTextDlgProc(HWND16,UINT16,WPARAM16,LPARAM);
-extern LRESULT TASK_Reschedule(void);
 
 /***********************************************************************
  *           MODULE_GetWndProcEntry16 (not a Windows API function)
@@ -39,8 +38,7 @@
   MAP_STR_TO_PROC("PrintDlgProc",PrintDlgProc);
   MAP_STR_TO_PROC("PrintSetupDlgProc",PrintSetupDlgProc);
   MAP_STR_TO_PROC("ReplaceTextDlgProc",ReplaceTextDlgProc);
-  MAP_STR_TO_PROC("TASK_Reschedule",TASK_Reschedule);
   fprintf(stderr,"warning: No mapping for %s(), add one in library/miscstubs.c\n",name);
+  assert( FALSE );
   return NULL;
 }
-
diff --git a/loader/main.c b/loader/main.c
index 944ffb7..d5bd59e 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -92,9 +92,6 @@
     /* Initialize relay code */
     if (!RELAY_Init()) return 0;
 
-    /* Create built-in modules */
-    if (!BUILTIN_Init()) return 0;
-
       /* Initialize signal handling */
     if (!SIGNAL_InitEmulator()) return 0;
 
@@ -232,7 +229,7 @@
         return 0;
     }
 
-    if (Options.debug) DEBUG_SetBreakpoints( TRUE );  /* Setup breakpoints */
+    if (Options.debug) DEBUG_AddModuleBreakpoints();
 
     Yield();  /* Start the first task */
     fprintf( stderr, "WinMain: Should never happen: returned from Yield()\n" );
diff --git a/loader/module.c b/loader/module.c
index 65b655c..c1d3047 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -636,9 +636,7 @@
                   ne_header.rname_tab_offset - ne_header.resource_tab_offset,
                   pData )) return (HMODULE32)11;  /* invalid exe */
         pData += ne_header.rname_tab_offset - ne_header.resource_tab_offset;
-#ifndef WINELIB
 	NE_InitResourceHandler( hModule );
-#endif
     }
     else pModule->res_table = 0;  /* No resource table */
 
@@ -1017,7 +1015,7 @@
 	dprintf_module( stddeb, "module %04x doesn't have a WEP\n", hModule );
 	return FALSE;
     }
-    return CallWindowsExitProc( WEP, WEP_FREE_DLL );
+    return Callbacks->CallWindowsExitProc( WEP, WEP_FREE_DLL );
 }
 
 
@@ -1258,7 +1256,8 @@
                 stack16Top->cs = 0;
 
                 hf = FILE_DupUnixHandle( MODULE_OpenFile( hModule ) );
-		CallTo16_word_ww( selfloadheader->BootApp, hModule, hf );
+                Callbacks->CallBootAppProc( selfloadheader->BootApp,
+                                            hModule, hf );
                 _lclose32(hf);
 		/* some BootApp procs overwrite the selector of dgroup */
 		pSegTable[pModule->dgroup - 1].selector = saved_dgroup;
@@ -1341,6 +1340,15 @@
     return MODULE_Load( name, paramBlock, 0 );
 }
 
+/**********************************************************************
+ *	    LoadModule32    (KERNEL32)
+ * FIXME: check this function
+ */
+DWORD LoadModule32( LPCSTR name, LPVOID paramBlock ) 
+{
+    return MODULE_Load( name, paramBlock, 0 );
+}
+
 
 /**********************************************************************
  *	    FreeModule16    (KERNEL.46)
@@ -1865,7 +1873,6 @@
      * but we could get HMODULE16 or the like (think builtin modules)
      */
 
-#ifndef WINELIB
     NE_MODULE *pModule;
 
     if (!(pModule = MODULE_GetPtr( hModule )))
@@ -1875,9 +1882,6 @@
     if (pModule->flags & NE_FFLAGS_BUILTIN)
         return (LPIMAGE_NT_HEADERS)0;
     return pModule->pe_module->pe_header;
-#else
-    return NULL;
-#endif
 }
 
 
@@ -1919,12 +1923,13 @@
 BOOL16 WINAPI ModuleNext( MODULEENTRY *lpme )
 {
     NE_MODULE *pModule;
+    char *name;
 
     if (!lpme->wNext) return FALSE;
     if (!(pModule = MODULE_GetPtr( lpme->wNext ))) return FALSE;
-    strncpy( lpme->szModule, (char *)pModule + pModule->name_table,
-             MAX_MODULE_NAME );
-    lpme->szModule[MAX_MODULE_NAME] = '\0';
+    name = (char *)pModule + pModule->name_table;
+    memcpy( lpme->szModule, name + 1, *name );
+    lpme->szModule[(BYTE)*name] = '\0';
     lpme->hModule = lpme->wNext;
     lpme->wcUsage = pModule->count;
     strncpy( lpme->szExePath, NE_MODULE_NAME(pModule), MAX_PATH );
diff --git a/loader/ne_image.c b/loader/ne_image.c
index 09334ba..5fadcef 100644
--- a/loader/ne_image.c
+++ b/loader/ne_image.c
@@ -1,4 +1,3 @@
-#ifndef WINELIB
 /*
  * NE modules
  *
@@ -88,8 +87,8 @@
         stack16Top->bp = 0;
         stack16Top->ip = 0;
         stack16Top->cs = 0;
- 	newselector =  CallTo16_word_www( selfloadheader->LoadAppSeg,
-                                          hModule, hf, segnum );
+ 	newselector = Callbacks->CallLoadAppSegProc(selfloadheader->LoadAppSeg,
+                                                    hModule, hf, segnum );
         _lclose32( hf );
  	if (newselector != oldselector) {
  	  /* Self loaders like creating their own selectors; 
@@ -519,7 +518,7 @@
     dprintf_dll( stddeb, "Calling LibMain, cs:ip=%04lx:%04x ds=%04lx di=%04x cx=%04x\n", 
                  CS_reg(&context), IP_reg(&context), DS_reg(&context),
                  DI_reg(&context), CX_reg(&context) );
-    CallTo16_regs_( &context, 0 );
+    Callbacks->CallRegisterProc( &context, 0 );
     return TRUE;
 }
 
@@ -537,11 +536,7 @@
     HMODULE16 *pDLL;
 
     if (!(pModule = MODULE_GetPtr( hModule ))) return;
-    if (pModule->flags & NE_FFLAGS_WIN32)
-    {
-/*        PE_InitializeDLLs(hModule); */
-        return;
-    }
+    if (pModule->flags & NE_FFLAGS_WIN32) return;
 
     if (pModule->dlls_to_init)
     {
@@ -558,7 +553,7 @@
 
 
 /***********************************************************************
- *           NE_PatchCodeHandle
+ *           PatchCodeHandle
  *
  * Needed for self-loading modules.
  */
@@ -567,4 +562,3 @@
 void WINAPI PatchCodeHandle(HANDLE16 hSel)
 {
 }
-#endif /* WINELIB */
diff --git a/loader/ne_resource.c b/loader/ne_resource.c
index 37ec64f..0e340bd 100644
--- a/loader/ne_resource.c
+++ b/loader/ne_resource.c
@@ -1,4 +1,3 @@
-#ifndef WINELIB
 /*
  *
  * Copyright 1993 Robert J. Amstadt
@@ -305,9 +304,7 @@
     NE_MODULE *pModule = MODULE_GetPtr( hModule );
     if (!pModule || !pModule->res_table) return 0;
     sizeShift = *(WORD *)((char *)pModule + pModule->res_table);
-#ifndef WINELIB
     pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc);
-#endif
     if (size < (DWORD)pNameInfo->length << sizeShift)
         size = (DWORD)pNameInfo->length << sizeShift;
     return GLOBAL_Alloc( GMEM_FIXED, size, hModule, FALSE, FALSE, FALSE );
@@ -324,9 +321,7 @@
 
     NE_MODULE *pModule = MODULE_GetPtr( hModule );
     if (!pModule || !pModule->res_table) return -1;
-#ifndef WINELIB
     pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc);
-#endif
 
     if ((fd = _lopen32( NE_MODULE_NAME(pModule), OF_READ )) != -1)
     {
@@ -348,9 +343,7 @@
     NE_MODULE *pModule = MODULE_GetPtr( hModule );
     if (!pModule || !pModule->res_table) return 0;
     sizeShift = *(WORD *)((char *)pModule + pModule->res_table);
-#ifndef WINELIB
     pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc);
-#endif
     return (DWORD)pNameInfo->length << sizeShift;
 }
 
@@ -371,7 +364,6 @@
 
     d = pModule->res_table + 2;
     pTypeInfo = (NE_TYPEINFO *)((char *)pModule + d);
-#ifndef WINELIB
     while( hRsrc > d )
     {
 	if (pTypeInfo->type_id == 0)
@@ -389,7 +381,7 @@
 	}
 	pTypeInfo = (NE_TYPEINFO *)(((char *)pModule) + d);
     }
-#endif
+
     if (pNameInfo)
     {
 	RESOURCEHANDLER16 __r16loader;
@@ -459,6 +451,7 @@
                 {
                     GlobalFree16( pNameInfo->handle );
                     pNameInfo->handle = 0;
+		    pNameInfo->flags &= ~NE_SEGFLAGS_LOADED;
                 }
                 return 0;
             }
@@ -472,4 +465,3 @@
     GlobalFree16( handle ); /* it could have been DirectResAlloc()'ed */
     return handle;
 }
-#endif /* WINELIB */
diff --git a/loader/pe_image.c b/loader/pe_image.c
index f53575b..07b147c 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -22,6 +22,7 @@
 #include "windows.h"
 #include "winbase.h"
 #include "callback.h"
+#include "file.h"
 #include "neexe.h"
 #include "peexe.h"
 #include "process.h"
@@ -30,7 +31,6 @@
 #include "global.h"
 #include "task.h"
 #include "ldt.h"
-#include "options.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "xmalloc.h"
@@ -45,17 +45,12 @@
 
 void dump_exports(IMAGE_EXPORT_DIRECTORY * pe_exports, unsigned int load_addr)
 { 
-#ifndef WINELIB
   char		*Module;
-  int		i;
+  int		i, j;
   u_short	*ordinal;
   u_long	*function,*functions;
   u_char	**name,*ename;
-  char		buffer[1000];
-  DBG_ADDR	daddr;
 
-  daddr.seg = 0;
-  daddr.type = NULL;
   Module = (char*)RVA(pe_exports->Name);
   dprintf_win32(stddeb,"\n*******EXPORT DATA*******\nModule name is %s, %ld functions, %ld names\n", 
 	 Module,
@@ -66,25 +61,17 @@
   functions=function=(u_long*) RVA(pe_exports->AddressOfFunctions);
   name=(u_char**) RVA(pe_exports->AddressOfNames);
 
-  dprintf_win32(stddeb,"%-32s Ordinal Virt Addr\n", "Function Name");
-  for (i=0;i<pe_exports->NumberOfFunctions;i++) {
-      if (i<pe_exports->NumberOfNames) {
-	  ename=(char*)RVA(*name++);
-	  dprintf_win32(stddeb,"%-32s %4d    %8.8lx (%8.8lx)\n",ename,*ordinal,functions[*ordinal],*function);
-	  sprintf(buffer,"%s_%s",Module,ename);
-	  daddr.off=RVA(functions[*ordinal]);
-	  ordinal++;
-	  function++;
-      } else {
-      	  /* ordinals/names no longer valid, but we still got functions */
-	  dprintf_win32(stddeb,"%-32s %4s    %8s %8.8lx\n","","","",*function);
-	  sprintf(buffer,"%s_%d",Module,i);
-	  daddr.off=RVA(*functions);
-	  function++;
-      }
-      DEBUG_AddSymbol(buffer,&daddr, NULL, SYM_WIN32 | SYM_FUNC);
+  dprintf_win32(stddeb," Ord  Virt Addr  Name\n" );
+  for (i=0;i<pe_exports->NumberOfFunctions;i++, function++)
+  {
+      if (!*function) continue;  /* No such function */
+      dprintf_win32( stddeb,"%4d  %08lx", i + pe_exports->Base, *function );
+      /* Check if we have a name for it */
+      for (j = 0; j < pe_exports->NumberOfNames; j++)
+          if (ordinal[j] == i)
+              dprintf_win32( stddeb, "  %s", (char*)RVA(name[j]) );
+      dprintf_win32( stddeb,"\n" );
   }
-#endif
 }
 
 /* Look up the specified function or ordinal in the exportlist:
@@ -241,9 +228,7 @@
 	char			*Module;
 	IMAGE_IMPORT_BY_NAME	*pe_name;
 	LPIMAGE_THUNK_DATA	import_list,thunk_list;
-	int			ordimportwarned;
 
-        ordimportwarned = 0;
 	Module = (char *) RVA(pe_imp->Name);
 	dprintf_win32 (stddeb, "%s\n", Module);
 
@@ -258,10 +243,6 @@
 		if (IMAGE_SNAP_BY_ORDINAL(import_list->u1.Ordinal)) {
 		    int ordinal = IMAGE_ORDINAL(import_list->u1.Ordinal);
 
-		    if(!lstrncmpi32A(Module,"kernel32",8) && !ordimportwarned){
-		       fprintf(stderr,"%s imports kernel32.dll by ordinal. May crash.\n",modname);
-		       ordimportwarned = 1;
-		    }
 		    dprintf_win32 (stddeb, "--- Ordinal %s,%d\n", Module, ordinal);
 		    thunk_list->u1.Function=(LPDWORD)GetProcAddress32(MODULE_FindModule(Module),(LPCSTR)ordinal);
 		    if (!thunk_list->u1.Function) {
@@ -292,13 +273,6 @@
 		    /* not sure about this branch, but it seems to work */
 		    int ordinal = IMAGE_ORDINAL(thunk_list->u1.Ordinal);
 
-
-		    if (!lstrncmpi32A(Module,"kernel32",8) && 
-		    	!ordimportwarned
-		    ) {
-		       fprintf(stderr,"%s imports kernel32.dll by ordinal. May crash.\n",modname);
-		       ordimportwarned = 1;
-		    }
 		    dprintf_win32(stddeb,"--- Ordinal %s.%d\n",Module,ordinal);
 		    thunk_list->u1.Function=(LPDWORD)GetProcAddress32(MODULE_FindModule(Module),
 						     (LPCSTR) ordinal);
@@ -422,65 +396,46 @@
  * Load one PE format DLL/EXE into memory
  * 
  * Unluckily we can't just mmap the sections where we want them, for 
- * (at least) Linux does only support offset with are multiples of the
- * underlying filesystemblocksize, but PE DLLs usually have alignments of 512
- * byte. This fails for instance when you try to map from CDROM (bsize 2048).
+ * (at least) Linux does only support offsets which are page-aligned.
  *
  * BUT we have to map the whole image anyway, for Win32 programs sometimes
  * want to access them. (HMODULE32 point to the start of it)
  */
-static PE_MODULE *PE_LoadImage( int fd )
+static PE_MODULE *PE_LoadImage( HFILE32 hFile )
 {
-	struct pe_data		*pe;
-	struct stat		stbuf;
+    struct pe_data *pe;
+    HMODULE32 hModule;
+    HANDLE32 mapping;
 
-	if (-1==fstat(fd,&stbuf)) {
-		perror("PE_LoadImage:fstat");
-		return NULL;
-	}
-	pe = xmalloc(sizeof(struct pe_data));
-	memset(pe,0,sizeof(struct pe_data));
+    /* map the PE file somewhere */
+    mapping = CreateFileMapping32A( hFile, NULL, PAGE_READONLY | SEC_COMMIT,
+                                    0, 0, NULL );
+    if (!mapping)
+    {
+        fprintf( stderr, "PE_LoadImage: CreateFileMapping error %ld\n",
+                 GetLastError() );
+        return NULL;
+    }
+    hModule = (HMODULE32)MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
+    CloseHandle( mapping );
+    if (!hModule)
+    {
+        fprintf( stderr, "PE_LoadImage: MapViewOfFile error %ld\n",
+                 GetLastError() );
+        return NULL;
+    }
 
-	/* map the PE image somewhere */
-	pe->mappeddll = (HMODULE32)mmap(NULL,stbuf.st_size,PROT_READ,MAP_SHARED,fd,0);
-	if (!pe->mappeddll || pe->mappeddll==-1) {
-		if (errno==ENOEXEC) {
-			int	res=0,curread = 0;
-
-			lseek(fd,0,SEEK_SET);
-			/* linux: some filesystems don't support mmap (samba,
-			 * ntfs apparently) so we have to read the image the
-			 * hard way
-			 */
-			pe->mappeddll = xmalloc(stbuf.st_size);
-			while (curread < stbuf.st_size) {
-				res = read(fd,pe->mappeddll+curread,stbuf.st_size-curread);
-				if (res<=0) 
-					break;
-				curread+=res;
-			}
-			if (res == -1) {
-				perror("PE_LoadImage:mmap compat read");
-				free(pe->mappeddll);
-				free(pe);
-				return NULL;
-			}
-
-		} else {
-			perror("PE_LoadImage:mmap");
-			free(pe);
-			return NULL;
-		}
-	}
-	/* link PE header */
-	pe->pe_header = (IMAGE_NT_HEADERS*)(pe->mappeddll+(((IMAGE_DOS_HEADER*)pe->mappeddll)->e_lfanew));
-	if (pe->pe_header->Signature!=IMAGE_NT_SIGNATURE) {
-		fprintf(stderr,"image doesn't have PE signature, but 0x%08lx\n",
-			pe->pe_header->Signature
-		);
-		free(pe);
-		return NULL;
-	}
+    /* build PE header */
+    pe = xmalloc(sizeof(struct pe_data));
+    pe->mappeddll = hModule;
+    pe->pe_header = (IMAGE_NT_HEADERS*)(pe->mappeddll+(((IMAGE_DOS_HEADER*)pe->mappeddll)->e_lfanew));
+    if (pe->pe_header->Signature!=IMAGE_NT_SIGNATURE)
+    {
+        fprintf(stderr,"image doesn't have PE signature, but 0x%08lx\n",
+                pe->pe_header->Signature );
+        free(pe);
+        return NULL;
+    }
 
 	if (pe->pe_header->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) {
 		fprintf(stderr,"trying to load PE image for unsupported architecture (");
@@ -523,7 +478,6 @@
 	int			i, result;
 	int			load_addr;
 	IMAGE_DATA_DIRECTORY	dir;
-	char			buffer[200];
 	char			*modname;
 	int			vma_size;
 	
@@ -553,8 +507,8 @@
 	{
 		/* memcpy only non-BSS segments */
 		/* FIXME: this should be done by mmap(..MAP_PRIVATE|MAP_FIXED..)
-		 * but it is not possible for (at least) Linux needs an offset
-		 * aligned to a block on the filesystem.
+		 * but it is not possible for (at least) Linux needs
+		 * a page-aligned offset.
 		 */
 		if(!(pe->pe_seg[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA))
 		    memcpy((char*)RVA(pe->pe_seg[i].VirtualAddress),
@@ -599,8 +553,10 @@
 	dir=pe->pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
 	if(dir.Size)
 	{
+		/* 
 		if(pem->pe_import && (int)pem->pe_import!=RVA(dir.VirtualAddress))
 			fprintf(stderr,"wrong import directory??\n");
+		 */
 		pem->pe_import = (LPIMAGE_IMPORT_DESCRIPTOR) RVA(dir.VirtualAddress);
 	}
 
@@ -682,25 +638,6 @@
 		if ((s=strchr(modname,'.')))
 			*s='\0';
 	}
-
-#ifndef WINELIB
-        {
-            DBG_ADDR daddr = { NULL, 0, 0 };
-            /* add start of sections as debugsymbols */
-            for(i=0;i<pe->pe_header->FileHeader.NumberOfSections;i++) {
-		sprintf(buffer,"%s_%s",modname,pe->pe_seg[i].Name);
-		daddr.off= RVA(pe->pe_seg[i].VirtualAddress);
-		DEBUG_AddSymbol(buffer,&daddr, NULL, SYM_WIN32 | SYM_FUNC);
-            }
-            /* add entry point */
-            sprintf(buffer,"%s_EntryPoint",modname);
-            daddr.off=RVA(pe->pe_header->OptionalHeader.AddressOfEntryPoint);
-            DEBUG_AddSymbol(buffer,&daddr, NULL, SYM_WIN32 | SYM_FUNC);
-            /* add start of DLL */
-            daddr.off=load_addr;
-            DEBUG_AddSymbol(modname,&daddr, NULL, SYM_WIN32 | SYM_FUNC);
-        }
-#endif
 }
 
 HINSTANCE16 MODULE_CreateInstance(HMODULE16 hModule,LOADPARAMS *params);
@@ -730,17 +667,20 @@
 		pModule = MODULE_GetPtr(hModule);
 	} else {
 
+#ifndef WINELIB
 		/* try to load builtin, enabled modules first */
 		if ((hModule = BUILTIN_LoadModule( name, FALSE )))
 			return hModule;
-
+#endif
 		/* try to open the specified file */
 		if (HFILE_ERROR32==(hFile=OpenFile32(name,&ofs,OF_READ))) {
+#ifndef WINELIB
 			/* Now try the built-in even if disabled */
 			if ((hModule = BUILTIN_LoadModule( name, TRUE ))) {
 				fprintf( stderr, "Warning: could not load Windows DLL '%s', using built-in module.\n", name );
 				return hModule;
 			}
+#endif
 			return 1;
 		}
 		if ((hModule = MODULE_CreateDummyModule( &ofs )) < 32) {
@@ -749,8 +689,8 @@
 		}
 		pModule		= (NE_MODULE *)GlobalLock16( hModule );
 		pModule->flags	= NE_FFLAGS_WIN32;
-		pModule->pe_module = PE_LoadImage( FILE_GetUnixHandle(hFile) );
-		_lclose32(hFile);
+		pModule->pe_module = PE_LoadImage( hFile );
+		CloseHandle( hFile );
 		if (!pModule->pe_module)
 			return 21;
 	}
@@ -774,8 +714,8 @@
     pModule = (NE_MODULE *)GlobalLock16( hModule );
     pModule->flags = NE_FFLAGS_WIN32;
 
-    pModule->pe_module = PE_LoadImage( FILE_GetUnixHandle(hFile) );
-    _lclose32(hFile);
+    pModule->pe_module = PE_LoadImage( hFile );
+    CloseHandle( hFile );
     if (!pModule->pe_module)
     	return 21;
 
@@ -810,13 +750,6 @@
 
     if (type==DLL_PROCESS_ATTACH)
 	pem->flags |= PE_MODREF_PROCESS_ATTACHED;
-#ifndef WINELIB
-    if (Options.debug) {
-            DBG_ADDR addr = { NULL, 0, RVA(pe->pe_header->OptionalHeader.AddressOfEntryPoint) };
-            DEBUG_AddBreakpoint( &addr );
-	    DEBUG_SetBreakpoints(TRUE);
-    }
-#endif
 
     /*  DLL_ATTACH_PROCESS:
      *		lpreserved is NULL for dynamic loads, not-NULL for static loads
diff --git a/loader/resource.c b/loader/resource.c
index 69cefc2..fee5cfa 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -698,7 +698,7 @@
     return retval;
 }
 
-#ifndef WINELIB
+
 /**********************************************************************
  *	SetResourceHandler	(KERNEL.43)
  */
@@ -723,6 +723,7 @@
     return NULL;
 }
 
+
 /**********************************************************************
  *	EnumResourceTypesA	(KERNEL32.90)
  */
@@ -776,4 +777,3 @@
 {
     return PE_EnumResourceLanguages32W(hmodule,type,name,lpfun,lParam);
 }
-#endif  /* WINELIB */
diff --git a/loader/task.c b/loader/task.c
index 0b749d4..b0c44ca 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -11,6 +11,7 @@
 #include "windows.h"
 #include "user.h"
 #include "callback.h"
+#include "drive.h"
 #include "file.h"
 #include "global.h"
 #include "instance.h"
@@ -18,7 +19,6 @@
 #include "miscemu.h"
 #include "module.h"
 #include "neexe.h"
-#include "options.h"
 #include "peexe.h"
 #include "pe_image.h"
 #include "process.h"
@@ -33,10 +33,6 @@
 #include "debug.h"
 #include "dde_proc.h"
 
-#ifndef WINELIB
-#include "debugger.h"
-#endif
-
   /* Min. number of thunks allocated when creating a new segment */
 #define MIN_THUNKS  32
 
@@ -57,15 +53,6 @@
 static UINT16 nTaskCount = 0;
 static HGLOBAL16 hDOSEnvironment = 0;
 
-  /* TASK_Reschedule() 16-bit entry point */
-static FARPROC16 TASK_RescheduleProc;
-
-#ifdef WINELIB
-#define TASK_SCHEDULE()  TASK_Reschedule()
-#else
-#define TASK_SCHEDULE()  CallTo16_word_(TASK_RescheduleProc)
-#endif
-
 static HGLOBAL16 TASK_CreateDOSEnvironment(void);
 static void	 TASK_YieldToSystem(TDB*);
 
@@ -75,12 +62,10 @@
  */
 BOOL32 TASK_Init(void)
 {
-
-    TASK_RescheduleProc = MODULE_GetWndProcEntry16( "TASK_Reschedule" );
     if (!(hDOSEnvironment = TASK_CreateDOSEnvironment()))
         fprintf( stderr, "Not enough memory for DOS Environment\n" );
     TASK_SystemTHDB.teb_sel = SELECTOR_AllocBlock( &TASK_SystemTHDB, 0x1000, SEGMENT_DATA, TRUE, FALSE );
-#ifndef WINELIB
+#ifdef __i386__
     __asm__ __volatile__("movw %w0,%%fs"::"r"(TASK_SystemTHDB.teb_sel));
 #endif
     return (hDOSEnvironment != 0);
@@ -369,8 +354,9 @@
 
         InitTask( NULL );
         InitApp( pTask->hModule );
+#ifdef __i386__
         __asm__ __volatile__("movw %w0,%%fs"::"r" (pCurrentThread->teb_sel));
-
+#endif
         PE_InitializeDLLs( pCurrentProcess, DLL_PROCESS_ATTACH, (LPVOID)-1 );
         dprintf_relay( stddeb, "CallTo32(entryproc=%p)\n", entry );
         exit_code = entry();
@@ -406,7 +392,7 @@
                       SELECTOROF(IF1632_Saved16_ss_sp),
                       OFFSETOF(IF1632_Saved16_ss_sp) );
 
-        CallTo16_regs_( &context, 0 );
+        Callbacks->CallRegisterProc( &context, 0 );
         /* This should never return */
         fprintf( stderr, "TASK_CallToStart: Main program returned!\n" );
         TASK_KillCurrentTask( 1 );
@@ -429,11 +415,10 @@
     NE_MODULE *pModule;
     SEGTABLEENTRY *pSegTable;
     LPSTR name;
-    char filename[256];
     char *stack32Top;
     STACK16FRAME *frame16;
     STACK32FRAME *frame32;
-#ifndef WINELIB32
+#ifndef WINELIB
     extern DWORD CALLTO16_RetAddr_regs;
     extern void CALLTO16_Restore();
 #endif
@@ -465,13 +450,7 @@
     memcpy( GlobalLock16( hEnvironment ), GlobalLock16( hParentEnv ),
             GlobalSize16( hParentEnv ) );
 
-      /* Get current directory */
-    
-    GetModuleFileName16( hModule, filename, sizeof(filename) );
-    name = strrchr(filename, '\\');
-    if (name) *(name+1) = 0;
-
-      /* Fill the task structure */
+    /* Fill the task structure */
 
     pTask->nEvents       = 1;  /* So the task can be started */
     pTask->hSelf         = hTask;
@@ -485,10 +464,12 @@
     pTask->hPrevInstance = hPrevInstance;
     pTask->hModule       = hModule;
     pTask->hParent       = hCurrentTask;
-    pTask->curdrive      = filename[0] - 'A' + 0x80;
-    strcpy( pTask->curdir, filename+2 );
     pTask->magic         = TDB_MAGIC;
     pTask->nCmdShow      = cmdShow;
+    pTask->curdrive      = DRIVE_GetCurrentDrive() | 0x80;
+    strcpy( pTask->curdir, "\\" );
+    lstrcpyn32A( pTask->curdir + 1, DRIVE_GetDosCwd( DRIVE_GetCurrentDrive() ),
+                 sizeof(pTask->curdir) - 1 );
 
       /* Create the thunks block */
 
@@ -546,6 +527,7 @@
     /* Create the Win32 part of the task */
 
     pCurrentProcess = pdb32 = PROCESS_Create( pTask, cmdLine );
+    /* FIXME: check for pdb32 == NULL.  */
     pdb32->task = hTask;
     if (pModule->flags & NE_FFLAGS_WIN32)
     {
@@ -565,6 +547,8 @@
     else
         pTask->thdb = THREAD_Create( pdb32, 0, NULL );
 
+    /* FIXME: check for pTask->thdb == NULL.  */
+
     /* Create the 32-bit stack frame */
 
     stack32Top = (char*)pTask->thdb->teb.stack_top;
@@ -592,10 +576,10 @@
     frame16->ebp = 0;
     frame16->ds = frame16->es = pTask->hInstance;
     frame16->entry_point = 0;
-    frame16->entry_ip = OFFSETOF(TASK_RescheduleProc) + 14;
-    frame16->entry_cs = SELECTOROF(TASK_RescheduleProc);
+    frame16->entry_ip = 0;
+    frame16->entry_cs = 0;
     frame16->bp = 0;
-    *(DWORD *)(frame16 + 1) = frame32; /* Store the 32-bit stack pointer */
+    *(STACK32FRAME **)(frame16 + 1) = frame32; /* Store the 32-bit %esp */
 #ifndef WINELIB
     frame16->ip = LOWORD( CALLTO16_RetAddr_regs );
     frame16->cs = HIWORD( CALLTO16_RetAddr_regs );
@@ -607,30 +591,6 @@
 
     if (!IF1632_Saved16_ss_sp) IF1632_Saved16_ss_sp = pTask->ss_sp;
 
-      /* Add a breakpoint at the start of the task */
-
-#ifndef WINELIB
-    if (Options.debug)
-    {
-        if (pModule->flags & NE_FFLAGS_WIN32)
-        {
-	/*
-            DBG_ADDR addr = { NULL, 0, pCurrentProcess->exe_modref->load_addr + 
-                              pCurrentProcess->exe_modref->pe_module->pe_header->OptionalHeader.AddressOfEntryPoint };
-            fprintf( stderr, "Win32 task '%s': ", name );
-            DEBUG_AddBreakpoint( &addr );
-	 */
-        }
-        else
-        {
-            DBG_ADDR addr = { NULL, pSegTable[pModule->cs-1].selector,
-                              pModule->ip };
-            fprintf( stderr, "Win16 task '%s': ", name );
-            DEBUG_AddBreakpoint( &addr );
-        }
-    }
-#endif  /* WINELIB */
-
       /* Add the task to the linked list */
 
     TASK_LinkTask( hTask );
@@ -847,7 +807,7 @@
 {
   MESSAGEQUEUE*		pQ;
 
-  TASK_SCHEDULE();
+  Callbacks->CallTaskRescheduleProc();
 
   if( pTask )
   {
@@ -884,10 +844,8 @@
 
     pTask->userhandler = (USERSIGNALPROC)&USER_SignalProc;
 
-#ifndef WINELIB
     /* Initialize implicitly loaded DLLs */
     NE_InitializeDLLs( pTask->hModule );
-#endif
 
     if (context)
     {
@@ -922,9 +880,7 @@
     pinstance = (INSTANCEDATA *)PTR_SEG_OFF_TO_LIN(CURRENT_DS, 0);
     pinstance->stackbottom = stackhi; /* yup, that's right. Confused me too. */
     pinstance->stacktop    = stacklow; 
-#ifndef WINELIB
     pinstance->stackmin    = OFFSETOF(IF1632_Saved16_ss_sp);
-#endif
 }
 
 
diff --git a/memory/global.c b/memory/global.c
index 8e9bc5c..b4b53cd 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -1259,7 +1259,7 @@
             lpmem->dwTotalVirtual = lpmem->dwTotalPhys+lpmem->dwTotalPageFile;
             lpmem->dwAvailVirtual = lpmem->dwAvailPhys+lpmem->dwAvailPageFile;
             lpmem->dwMemoryLoad = (lpmem->dwTotalVirtual-lpmem->dwAvailVirtual)
-                                      * 100 / lpmem->dwTotalVirtual;
+                                      / (lpmem->dwTotalVirtual / 100);
             return;
         }
     }
diff --git a/memory/ldt.c b/memory/ldt.c
index 36da4e1..62fd1b0 100644
--- a/memory/ldt.c
+++ b/memory/ldt.c
@@ -161,7 +161,6 @@
 #ifdef __i386__
 
 #ifdef linux
-    if (!__winelib)
     {
         struct modify_ldt_s ldt_info;
 
@@ -205,7 +204,6 @@
 #endif  /* linux */
 
 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
-    if (!__winelib)
     {
         long d[2];
 
@@ -222,7 +220,6 @@
 #endif  /* __NetBSD__ || __FreeBSD__ || __OpenBSD__ */
 
 #if defined(__svr4__) || defined(_SCO_DS)
-    if (!__winelib)
     {
         struct ssd ldt_mod;
         int i;
diff --git a/memory/local.c b/memory/local.c
index 5a75d1e..780dc17 100644
--- a/memory/local.c
+++ b/memory/local.c
@@ -27,6 +27,10 @@
 #include "stddebug.h"
 #include "debug.h"
 
+/* needed only  for GDI_HeapSel and USER_HeapSel */
+#include "gdi.h"
+#include "user.h"
+
 typedef struct
 {
 /* Arena header */
@@ -327,7 +331,7 @@
         if (LOCAL_GetHeap(selector))
         {
             fprintf( stderr, "LocalInit: Heap %04x initialized twice.\n", selector);
-            if (debugging_local) LOCAL_PrintHeap(selector);
+            LOCAL_PrintHeap(selector);
         }
     }
 
@@ -781,7 +785,7 @@
         if (pArena->size >= size) return arena;
     }
     dprintf_local( stddeb, "Local_FindFreeBlock: not enough space\n" );
-    if (debugging_local) LOCAL_PrintHeap(ds);
+    LOCAL_PrintHeap(ds);
     return 0;
 }
 
@@ -822,8 +826,19 @@
 	arena = LOCAL_FindFreeBlock( ds, size );
     }
     if (arena == 0) {
-	fprintf( stderr, "Local_GetBlock: not enough space in heap %04x for %d bytes\n",
-                 ds, size );
+        if (ds == GDI_HeapSel) { 
+	    fprintf( stderr, 
+	       "Local_GetBlock: not enough space in GDI local heap (%04x) for %d bytes\n",
+		     ds, size );
+	} else if (ds == USER_HeapSel) {
+	    fprintf( stderr, 
+	       "Local_GetBlock: not enough space in USER local heap (%04x) for %d bytes\n",
+		     ds, size );
+	} else {
+	    dprintf_local( stddeb, 
+	       "Local_GetBlock: not enough space in local heap %04x for %d bytes\n",
+		     ds, size );
+	}
 	return 0;
     }
 
diff --git a/memory/selector.c b/memory/selector.c
index bf4f829..2966095 100644
--- a/memory/selector.c
+++ b/memory/selector.c
@@ -568,7 +568,6 @@
     	ptr = MapLS((LPVOID)val);
 	*(DWORD*)(EBP_reg(context)+argoff) = ptr;
     }
-    fprintf(stderr,"[EBP+%d] %08lx => %08lx\n",argoff,val,ptr);
     EAX_reg(context) = ptr;
 }
 
@@ -655,4 +654,3 @@
     fprintf(stdnimp,"WOWGetVDMPointerUnfix(%08lx), STUB\n",vp);
     /* FIXME: unfix heapsegment */
 }
-
diff --git a/memory/virtual.c b/memory/virtual.c
index 0788836..8bc92ce 100644
--- a/memory/virtual.c
+++ b/memory/virtual.c
@@ -230,7 +230,7 @@
  */
 static void VIRTUAL_DeleteView( FILE_VIEW *view )
 {
-    munmap( (void *)view->base, view->size );
+    FILE_munmap( (void *)view->base, 0, view->size );
     if (view->next) view->next->prev = view->prev;
     if (view->prev) view->prev->next = view->next;
     else VIRTUAL_FirstView = view->next;
@@ -468,8 +468,8 @@
     if ((type & MEM_RESERVE) || !base)
     {
         view_size = size + (base ? 0 : granularity_mask + 1);
-        ptr = (UINT32)FILE_mmap( NULL, (LPVOID)base, 0, view_size, 0, 0,
-                                 VIRTUAL_GetUnixProt( vprot ), MAP_PRIVATE );
+        ptr = (UINT32)FILE_dommap( NULL, (LPVOID)base, 0, view_size, 0, 0,
+                                   VIRTUAL_GetUnixProt( vprot ), MAP_PRIVATE );
         if (ptr == (UINT32)-1)
         {
             SetLastError( ERROR_OUTOFMEMORY );
@@ -483,16 +483,16 @@
             if (ptr & granularity_mask)
             {
                 UINT32 extra = granularity_mask + 1 - (ptr & granularity_mask);
-                munmap( (void *)ptr, extra );
+                FILE_munmap( (void *)ptr, 0, extra );
                 ptr += extra;
                 view_size -= extra;
             }
             if (view_size > size)
-                munmap( (void *)(ptr + size), view_size - size );
+                FILE_munmap( (void *)(ptr + size), 0, view_size - size );
         }
         if (!(view = VIRTUAL_CreateView( ptr, size, 0, 0, vprot, NULL )))
         {
-            munmap( (void *)ptr, size );
+            FILE_munmap( (void *)ptr, 0, size );
             SetLastError( ERROR_OUTOFMEMORY );
             return NULL;
         }
@@ -1056,9 +1056,9 @@
     dprintf_virtual( stddeb, "MapViewOfFile: handle=%x size=%x offset=%lx\n",
                      handle, size, offset_low );
 
-    ptr = (UINT32)FILE_mmap( mapping->file, addr, 0, size, 0, offset_low,
-                             VIRTUAL_GetUnixProt( mapping->protect ),
-                             flags );
+    ptr = (UINT32)FILE_dommap( mapping->file, addr, 0, size, 0, offset_low,
+                               VIRTUAL_GetUnixProt( mapping->protect ),
+                               flags );
     if (ptr == (UINT32)-1)
     {
         SetLastError( ERROR_OUTOFMEMORY );
@@ -1074,7 +1074,7 @@
     return (LPVOID)ptr;
 
 error:
-    if (ptr != (UINT32)-1) munmap( (void *)ptr, size );
+    if (ptr != (UINT32)-1) FILE_munmap( (void *)ptr, 0, size );
     K32OBJ_DecCount( &mapping->header );
     return NULL;
 }
diff --git a/misc/Makefile.in b/misc/Makefile.in
index 49f090b..1038b93 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -6,6 +6,8 @@
 MODULE    = misc
 
 C_SRCS = \
+	aspi.c \
+	callback.c \
 	comm.c \
 	commdlg.c \
 	compobj.c \
diff --git a/misc/aspi.c b/misc/aspi.c
new file mode 100644
index 0000000..fe453a9
--- /dev/null
+++ b/misc/aspi.c
@@ -0,0 +1,432 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <ldt.h>
+#include <memory.h>
+#include <unistd.h>
+#include <callback.h>
+#include "windows.h"
+#include "aspi.h"
+#include "options.h"
+#include "heap.h"
+#include "debug.h"
+#include "stddebug.h"
+
+/* FIXME!
+ * 1) Residual byte length reporting not handled
+ * 2) Make this code re-entrant for multithreading
+ * 3) Only linux supported so far
+ */
+
+#ifdef linux
+
+/* This is a duplicate of the sg_header from /usr/src/linux/include/scsi/sg.h
+ * kernel 2.0.30
+ * This will probably break at some point, but for those who don't have
+ * kernels installed, I think this should still work.
+ *
+ */
+
+struct sg_header
+ {
+  int pack_len;    /* length of incoming packet <4096 (including header) */
+  int reply_len;   /* maximum length <4096 of expected reply */
+  int pack_id;     /* id number of packet */
+  int result;      /* 0==ok, otherwise refer to errno codes */
+  unsigned int twelve_byte:1; /* Force 12 byte command length for group 6 & 7 commands  */
+  unsigned int other_flags:31;			/* for future use */
+  unsigned char sense_buffer[16]; /* used only by reads */
+  /* command follows then data for command */
+ };
+
+#define SCSI_OFF sizeof(struct sg_header)
+#endif
+
+#define ASPI_POSTING(prb) (prb->SRB_Flags & 0x1)
+
+#define HOST_TO_TARGET(prb) (((prb->SRB_Flags>>3) & 0x3) == 0x2)
+#define TARGET_TO_HOST(prb) (((prb->SRB_Flags>>3) & 0x3) == 0x1)
+#define NO_DATA_TRANSFERED(prb) (((prb->SRB_Flags>>3) & 0x3) == 0x3)
+
+#define SRB_ENABLE_RESIDUAL_COUNT 0x4
+
+#define INQUIRY_VENDOR		8
+
+#define MUSTEK_SCSI_AREA_AND_WINDOWS 0x04
+#define MUSTEK_SCSI_READ_SCANNED_DATA 0x08
+#define MUSTEK_SCSI_GET_IMAGE_STATUS 0x0f
+#define MUSTEK_SCSI_ADF_AND_BACKTRACE 0x10
+#define MUSTEK_SCSI_CCD_DISTANCE 0x11
+#define MUSTEK_SCSI_START_STOP 0x1b
+
+#define CMD_TEST_UNIT_READY 0x00
+#define CMD_REQUEST_SENSE 0x03
+#define CMD_INQUIRY 0x12
+
+/* scanner commands - just for debug */
+#define CMD_SCAN_GET_DATA_BUFFER_STATUS 0x34
+#define CMD_SCAN_GET_WINDOW 0x25
+#define CMD_SCAN_OBJECT_POSITION 0x31
+#define CMD_SCAN_READ 0x28
+#define CMD_SCAN_RELEASE_UNIT 0x17
+#define CMD_SCAN_RESERVE_UNIT 0x16
+#define CMD_SCAN_SCAN 0x1b
+#define CMD_SCAN_SEND 0x2a
+#define CMD_SCAN_CHANGE_DEFINITION 0x40
+
+#define INQURIY_CMDLEN 6
+#define INQURIY_REPLY_LEN 96
+#define INQUIRY_VENDOR 8
+
+#define SENSE_BUFFER(prb) (&prb->CDBByte[prb->SRB_CDBLen])
+
+
+/* Just a container for seeing what devices are open */
+struct ASPI_DEVICE_INFO {
+    struct ASPI_DEVICE_INFO *	next;
+    int				fd;
+    int				hostId;
+    int				target;
+    int				lun;
+};
+
+typedef struct ASPI_DEVICE_INFO ASPI_DEVICE_INFO;
+static ASPI_DEVICE_INFO *ASPI_open_devices = NULL;
+
+#ifdef linux
+static int
+ASPI_OpenDevice16(SRB_ExecSCSICmd16 *prb)
+{
+    int	fd;
+    char	idstr[20];
+    char	device_str[50];
+    ASPI_DEVICE_INFO *curr;
+
+    /* search list of devices to see if we've opened it already.
+     * There is not an explicit open/close in ASPI land, so hopefully
+     * keeping a device open won't be a problem.
+     */
+
+    for (curr = ASPI_open_devices; curr; curr = curr->next) {
+	if (curr->hostId == prb->SRB_HaId &&
+	    curr->target == prb->SRB_Target &&
+	    curr->lun == prb->SRB_Lun) {
+	    return curr->fd;
+	}
+    }
+
+    /* device wasn't cached, go ahead and open it */
+    sprintf(idstr, "scsi c%1dt%1dd%1d", prb->SRB_HaId, prb->SRB_Target, prb->SRB_Lun);
+
+    if (!PROFILE_GetWineIniString(idstr, "Device", "", device_str, sizeof(device_str))) {
+	dprintf_aspi(stddeb, "Trying to open unlisted scsi device %s\n", idstr);
+	return -1;
+    }
+
+    dprintf_aspi(stddeb, "Opening device %s=%s\n", idstr, device_str);
+
+    fd = open(device_str, O_RDWR);
+    if (fd == -1) {
+	int save_error = errno;
+	dprintf_aspi(stddeb, "Error opening device errno=%d\n", save_error);
+	return -1;
+    }
+
+    /* device is now open */
+    curr = HeapAlloc( SystemHeap, 0, sizeof(ASPI_DEVICE_INFO) );
+    curr->fd = fd;
+    curr->hostId = prb->SRB_HaId;
+    curr->target = prb->SRB_Target;
+    curr->lun = prb->SRB_Lun;
+
+    /* insert new record at beginning of open device list */
+    curr->next = ASPI_open_devices;
+    ASPI_open_devices = curr;
+    return fd;
+}
+
+
+static void
+ASPI_DebugPrintCmd16(SRB_ExecSCSICmd16 *prb)
+{
+  BYTE	cmd;
+  int	i;
+  BYTE *cdb;
+  BYTE *lpBuf;
+
+  lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
+
+  switch (prb->CDBByte[0]) {
+  case CMD_INQUIRY:
+    dprintf_aspi(stddeb, "{\n");
+    dprintf_aspi(stddeb, "\tEVPD: %d\n", prb->CDBByte[1] & 1);
+    dprintf_aspi(stddeb, "\tLUN: %d\n", (prb->CDBByte[1] & 0xc) >> 1);
+    dprintf_aspi(stddeb, "\tPAGE CODE: %d\n", prb->CDBByte[2]);
+    dprintf_aspi(stddeb, "\tALLOCATION LENGTH: %d\n", prb->CDBByte[4]);
+    dprintf_aspi(stddeb, "\tCONTROL: %d\n", prb->CDBByte[5]);
+    dprintf_aspi(stddeb, "}\n");
+    break;
+  case CMD_SCAN_SCAN:
+    dprintf_aspi(stddeb, "Transfer Length: %d\n", prb->CDBByte[4]);
+    break;
+  }
+
+  dprintf_aspi(stddeb, "Host Adapter: %d\n", prb->SRB_HaId);
+  dprintf_aspi(stddeb, "Flags: %d\n", prb->SRB_Flags);
+  if (TARGET_TO_HOST(prb)) {
+    dprintf_aspi(stddeb, "\tData transfer: Target to host. Length checked.\n");
+  }
+  else if (HOST_TO_TARGET(prb)) {
+    dprintf_aspi(stddeb, "\tData transfer: Host to target. Length checked.\n");
+  }
+  else if (NO_DATA_TRANSFERED(prb)) {
+    dprintf_aspi(stddeb, "\tData transfer: none\n");
+  }
+  else {
+    dprintf_aspi(stddeb, "\tTransfer by scsi cmd. Length not checked\n");
+  }
+
+  dprintf_aspi(stddeb, "\tResidual byte length reporting %s\n", prb->SRB_Flags & 0x4 ? "enabled" : "disabled");
+  dprintf_aspi(stddeb, "\tLinking %s\n", prb->SRB_Flags & 0x2 ? "enabled" : "disabled");
+  dprintf_aspi(stddeb, "\tPosting %s\n", prb->SRB_Flags & 0x1 ? "enabled" : "disabled");
+  dprintf_aspi(stddeb, "Target: %d\n", prb->SRB_Target);
+  dprintf_aspi(stddeb, "Lun: %d\n", prb->SRB_Lun);
+  dprintf_aspi(stddeb, "BufLen: %ld\n", prb->SRB_BufLen);
+  dprintf_aspi(stddeb, "SenseLen: %d\n", prb->SRB_SenseLen);
+  dprintf_aspi(stddeb, "BufPtr: %lx (%p)\n", prb->SRB_BufPointer, lpBuf);
+  dprintf_aspi(stddeb, "LinkPointer %lx\n", prb->SRB_Rsvd1);
+  dprintf_aspi(stddeb, "CDB Length: %d\n", prb->SRB_CDBLen);
+  dprintf_aspi(stddeb, "POST Proc: %lx\n", (DWORD) prb->SRB_PostProc);
+  cdb = &prb->CDBByte[0];
+  dprintf_aspi(stddeb, "CDB buffer[");
+  cmd = prb->CDBByte[0];
+  for (i = 0; i < prb->SRB_CDBLen; i++) {
+    if (i != 0)
+      dprintf_aspi(stddeb, ",");
+    dprintf_aspi(stddeb, "%02x", *cdb++);
+  }
+  dprintf_aspi(stddeb, "]\n");
+}
+
+static void
+PrintSenseArea16(SRB_ExecSCSICmd16 *prb)
+{
+  int	i;
+  BYTE *cdb;
+
+  cdb = &prb->CDBByte[0];
+  dprintf_aspi(stddeb, "SenseArea[");
+  for (i = 0; i < prb->SRB_SenseLen; i++) {
+    if (i)
+      dprintf_aspi(stddeb, ",");
+    dprintf_aspi(stddeb, "%02x", *cdb++);
+  }
+  dprintf_aspi(stddeb, "]\n");
+}
+
+static void
+ASPI_DebugPrintResult16(SRB_ExecSCSICmd16 *prb)
+{
+  BYTE *lpBuf;
+
+  lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
+
+  switch (prb->CDBByte[0]) {
+  case CMD_INQUIRY:
+    dprintf_aspi(stddeb, "Vendor: %s\n", lpBuf + INQUIRY_VENDOR);
+    break;
+  case CMD_TEST_UNIT_READY:
+    PrintSenseArea16(prb);
+    break;
+  }
+}
+
+static WORD
+ASPI_ExecScsiCmd16(SRB_ExecSCSICmd16 *prb, SEGPTR segptr_prb)
+{
+  struct sg_header *sg_hd, *sg_reply_hdr;
+  int	status;
+  BYTE *lpBuf;
+  int	in_len, out_len;
+  int	error_code = 0;
+  int	fd;
+
+  ASPI_DebugPrintCmd16(prb);
+
+  fd = ASPI_OpenDevice16(prb);
+  if (fd == -1) {
+      prb->SRB_Status = SS_ERR;
+      return SS_ERR;
+  }
+
+  sg_hd = NULL;
+  sg_reply_hdr = NULL;
+
+  prb->SRB_Status = SS_PENDING;
+  lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
+
+  if (!prb->SRB_CDBLen) {
+      prb->SRB_Status = SS_ERR;
+      return SS_ERR;
+  }
+
+  /* build up sg_header + scsi cmd */
+  if (HOST_TO_TARGET(prb)) {
+    /* send header, command, and then data */
+    in_len = SCSI_OFF + prb->SRB_CDBLen + prb->SRB_BufLen;
+    sg_hd = (struct sg_header *) malloc(in_len);
+    memset(sg_hd, 0, SCSI_OFF);
+    memcpy(sg_hd + 1, &prb->CDBByte[0], prb->SRB_CDBLen);
+    if (prb->SRB_BufLen) {
+      memcpy(((BYTE *) sg_hd) + SCSI_OFF + prb->SRB_CDBLen, lpBuf, prb->SRB_BufLen);
+    }
+  }
+  else {
+    /* send header and command - no data */
+    in_len = SCSI_OFF + prb->SRB_CDBLen;
+    sg_hd = (struct sg_header *) malloc(in_len);
+    memset(sg_hd, 0, SCSI_OFF);
+    memcpy(sg_hd + 1, &prb->CDBByte[0], prb->SRB_CDBLen);
+  }
+
+  if (TARGET_TO_HOST(prb)) {
+    out_len = SCSI_OFF + prb->SRB_BufLen;
+    sg_reply_hdr = (struct sg_header *) malloc(out_len);
+    memset(sg_reply_hdr, 0, SCSI_OFF);
+    sg_hd->reply_len = out_len;
+  }
+  else {
+    out_len = SCSI_OFF;
+    sg_reply_hdr = (struct sg_header *) malloc(out_len);
+    memset(sg_reply_hdr, 0, SCSI_OFF);
+    sg_hd->reply_len = out_len;
+  }
+
+  status = write(fd, sg_hd, in_len);
+  if (status < 0 || status != in_len) {
+      int myerror = errno;
+
+    fprintf(stderr, "not enough bytes written to scsi device bytes=%d .. %d\n", in_len, status);
+    if (status < 0) {
+	if (myerror == ENOMEM) {
+	    fprintf(stderr, "ASPI: Linux generic scsi driver\n  You probably need to re-compile your kernel with a larger SG_BIG_BUFF value (sg.h)\n  Suggest 130560\n");
+	}
+	dprintf_aspi(stddeb, "errno: = %d\n", myerror);
+    }
+    goto error_exit;
+  }
+
+  status = read(fd, sg_reply_hdr, out_len);
+  if (status < 0 || status != out_len) {
+    dprintf_aspi(stddeb, "not enough bytes read from scsi device%d\n", status);
+    goto error_exit;
+  }
+
+  if (sg_reply_hdr->result != 0) {
+    error_code = sg_reply_hdr->result;
+    dprintf_aspi(stddeb, "reply header error (%d)\n", sg_reply_hdr->result);
+    goto error_exit;
+  }
+
+  if (TARGET_TO_HOST(prb) && prb->SRB_BufLen) {
+    memcpy(lpBuf, sg_reply_hdr + 1, prb->SRB_BufLen);
+  }
+
+  /* copy in sense buffer to amount that is available in client */
+  if (prb->SRB_SenseLen) {
+    int sense_len = prb->SRB_SenseLen;
+    if (prb->SRB_SenseLen > 16)
+      sense_len = 16;
+    memcpy(SENSE_BUFFER(prb), &sg_reply_hdr->sense_buffer[0], sense_len);
+  }
+
+
+  prb->SRB_Status = SS_COMP;
+  prb->SRB_HaStat = HASTAT_OK;
+  prb->SRB_TargStat = STATUS_GOOD;
+
+  /* now do  posting */
+
+  if (ASPI_POSTING(prb) && prb->SRB_PostProc) {
+    dprintf_aspi(stddeb, "ASPI: Post Routine (%lx) called\n", (DWORD) prb->SRB_PostProc);
+    Callbacks->CallASPIPostProc(prb->SRB_PostProc, segptr_prb);
+  }
+
+  free(sg_reply_hdr);
+  free(sg_hd);
+  ASPI_DebugPrintResult16(prb);
+  return SS_COMP;
+  
+error_exit:
+  if (error_code == EBUSY) {
+      prb->SRB_Status = SS_ASPI_IS_BUSY;
+      dprintf_aspi(stddeb, "ASPI: Device busy\n");
+  }
+  else {
+      dprintf_aspi(stddeb, "ASPI_GenericHandleScsiCmd failed\n");
+      prb->SRB_Status = SS_ERR;
+  }
+
+  /* I'm not sure exactly error codes work here
+   * We probably should set prb->SRB_TargStat, SRB_HaStat ?
+   */
+  dprintf_aspi(stddeb, "ASPI_GenericHandleScsiCmd: error_exit\n");
+  free(sg_reply_hdr);
+  free(sg_hd);
+  return prb->SRB_Status;
+}
+#endif
+
+/***********************************************************************
+ *             GetASPISupportInfo16   (WINASPI.1)
+ */
+
+WORD
+GetASPISupportInfo16()
+{
+#ifdef linux
+    dprintf_aspi(stddeb, "GETASPISupportInfo\n");
+    /* high byte SS_COMP - low byte number of host adapters.
+     * FIXME!!! The number of host adapters is incorrect.
+     * I'm not sure how to determine this under linux etc.
+     */
+    return ((SS_COMP << 8) | 0x1);
+#else
+    return ((SS_COMP << 8) | 0x0);
+#endif
+}
+
+/***********************************************************************
+ *             SendASPICommand16   (WINASPI.2)
+ */
+
+WORD
+SendASPICommand16(SEGPTR segptr_srb)
+{
+#ifdef linux
+  LPSRB16 lpSRB = PTR_SEG_TO_LIN(segptr_srb);
+
+  switch (lpSRB->common.SRB_cmd) {
+  case SC_HA_INQUIRY:
+    dprintf_aspi(stddeb, "ASPI: Not implemented SC_HA_INQUIRY\n");
+    break;
+  case SC_GET_DEV_TYPE:
+    dprintf_aspi(stddeb, "ASPI: Not implemented SC_GET_DEV_TYPE\n");
+    break;
+  case SC_EXEC_SCSI_CMD:
+    return ASPI_ExecScsiCmd16(&lpSRB->cmd, segptr_srb);
+    break;
+  case SC_RESET_DEV:
+    dprintf_aspi(stddeb, "ASPI: Not implemented SC_RESET_DEV\n");
+    break;
+  default:
+    dprintf_aspi(stddeb, "ASPI: Unknown command %d\n", lpSRB->common.SRB_cmd);
+  }
+  return SS_INVALID_SRB;
+#else
+  return SS_INVALID_SRB;
+#endif
+}
diff --git a/misc/callback.c b/misc/callback.c
new file mode 100644
index 0000000..d8e9081
--- /dev/null
+++ b/misc/callback.c
@@ -0,0 +1,156 @@
+/*
+ * Function callbacks for the library
+ *
+ * Copyright 1997 Alexandre Julliard
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include "callback.h"
+
+extern void TASK_Reschedule(void);  /* loader/task.c */
+
+/**********************************************************************
+ *	     CALLBACK_CallWndProc
+ */
+static LRESULT WINAPI CALLBACK_CallWndProc( WNDPROC16 proc, HWND16 hwnd,
+                                            UINT16 msg, WPARAM16 wParam,
+                                            LPARAM lParam )
+{
+    return proc( hwnd, msg, wParam, lParam );
+}
+
+
+/**********************************************************************
+ *	     CALLBACK_CallRegisterProc
+ */
+static VOID WINAPI CALLBACK_CallRegisterProc( CONTEXT *context, INT32 offset)
+{
+    fprintf( stderr, "Cannot call a register proc in Winelib\n" );
+    assert( FALSE );
+}
+
+
+/**********************************************************************
+ *	     CALLBACK_CallDriverProc
+ */
+static LRESULT WINAPI CALLBACK_CallDriverProc( DRIVERPROC16 proc, DWORD dwId,
+                                               HDRVR16 hdrvr, UINT16 msg,
+                                               LPARAM lp1, LPARAM lp2 )
+{
+    return proc( dwId, hdrvr, msg, lp1, lp2 );
+}
+
+
+/**********************************************************************
+ *	     CALLBACK_CallDriverCallback
+ */
+static LRESULT WINAPI CALLBACK_CallDriverCallback( FARPROC16 proc,
+                                                   HANDLE16 hDev, UINT16 msg,
+                                                   DWORD dwUser, LPARAM lp1,
+                                                   LPARAM lp2 )
+{
+    return proc( hDev, msg, dwUser, lp1, lp2 );
+}
+
+
+/**********************************************************************
+ *	     CALLBACK_CallTimeFuncProc
+ */
+static LRESULT WINAPI CALLBACK_CallTimeFuncProc( FARPROC16 proc, WORD id,
+                                                 UINT16 msg, DWORD dwUser,
+                                                 LPARAM lp1, LPARAM lp2 )
+{
+    return proc( id, msg, dwUser, lp1, lp2 );
+}
+
+
+/**********************************************************************
+ *	     CALLBACK_CallWindowsExitProc
+ */
+static INT16 WINAPI CALLBACK_CallWindowsExitProc( FARPROC16 proc, INT16 type)
+{
+    return proc( type );
+}
+
+
+/**********************************************************************
+ *	     CALLBACK_CallWordBreakProc
+ */
+static INT16 WINAPI CALLBACK_CallWordBreakProc( EDITWORDBREAKPROC16 proc,
+                                                SEGPTR text, INT16 word,
+                                                INT16 len, INT16 action )
+{
+    return proc( (LPSTR)text, word, len, action );
+}
+
+
+/**********************************************************************
+ *	     CALLBACK_CallBootAppProc
+ */
+static void WINAPI CALLBACK_CallBootAppProc( FARPROC16 proc, HANDLE16 module,
+                                             HFILE16 file )
+{
+    proc( module, file );
+}
+
+
+/**********************************************************************
+ *	     CALLBACK_CallLoadAppSegProc
+ */
+static WORD WINAPI CALLBACK_CallLoadAppSegProc( FARPROC16 proc,
+                                                HANDLE16 module, HFILE16 file,
+                                                WORD seg )
+{
+    return proc( module, file, seg );
+}
+
+
+/**********************************************************************
+ *	     CALLBACK_CallSystemTimerProc
+ */
+static void WINAPI CALLBACK_CallSystemTimerProc( FARPROC16 proc )
+{
+    proc();
+}
+
+
+/**********************************************************************
+ *	     CALLBACK_CallASPIPostProc
+ */
+static LRESULT WINAPI CALLBACK_CallASPIPostProc( FARPROC16 proc, SEGPTR ptr )
+{
+    return proc( ptr );
+}
+
+/**********************************************************************
+ *	     CALLBACK_WinelibTable
+ *
+ * The callbacks function table for Winelib
+ */
+static const CALLBACKS_TABLE CALLBACK_WinelibTable =
+{
+    CALLBACK_CallRegisterProc,     /* CallRegisterProc */
+    TASK_Reschedule,               /* CallTaskRescheduleProc */
+    CALLBACK_CallWndProc,          /* CallWndProc */
+    CALLBACK_CallDriverProc,       /* CallDriverProc */
+    CALLBACK_CallDriverCallback,   /* CallDriverCallback */
+    CALLBACK_CallTimeFuncProc,     /* CallTimeFuncProc */
+    CALLBACK_CallWindowsExitProc,  /* CallWindowsExitProc */
+    CALLBACK_CallWordBreakProc,    /* CallWordBreakProc */
+    CALLBACK_CallBootAppProc,      /* CallBootAppProc */
+    CALLBACK_CallLoadAppSegProc,   /* CallLoadAppSegProc */
+    CALLBACK_CallSystemTimerProc,  /* CallSystemTimerProc */
+    CALLBACK_CallASPIPostProc,     /* CallASPIPostProc */
+    /* The graphics driver callbacks are never used in Winelib */
+    NULL,                          /* CallDrvControlProc */
+    NULL,                          /* CallDrvEnableProc */
+    NULL,                          /* CallDrvEnumDFontsProc */
+    NULL,                          /* CallDrvEnumObjProc */
+    NULL,                          /* CallDrvOutputProc */
+    NULL,                          /* CallDrvRealizeProc */
+    NULL,                          /* CallDrvStretchBltProc */
+    NULL                           /* CallDrvExtTextOutProc */
+};
+
+const CALLBACKS_TABLE *Callbacks = &CALLBACK_WinelibTable;
diff --git a/misc/comm.c b/misc/comm.c
index 5dc0621..08f9675 100644
--- a/misc/comm.c
+++ b/misc/comm.c
@@ -928,7 +928,7 @@
 	struct DosDeviceStruct *ptr;
 
     	dprintf_comm(stddeb,
-		"SetCommState: fd %d, ptr %p\n", lpdcb->Id, lpdcb);
+		"SetCommState16: fd %d, ptr %p\n", lpdcb->Id, lpdcb);
 	if (tcgetattr(lpdcb->Id, &port) == -1) {
 		commerror = WinError();	
 		return -1;
@@ -998,6 +998,12 @@
 		case CBR_38400:
 			port.c_cflag |= B38400;
 			break;		
+		case 57600:
+			port.c_cflag |= B57600;
+			break;		
+		case 57601:
+			port.c_cflag |= B115200;
+			break;		
 		default:
 			commerror = IE_BAUDRATE;
 			return -1;
@@ -1088,6 +1094,7 @@
 	
 
     	dprintf_comm(stddeb,"SetCommState: stopbits %d\n",lpdcb->StopBits);
+
 	switch (lpdcb->StopBits) {
 		case ONESTOPBIT:
 				port.c_cflag &= ~CSTOPB;
@@ -1118,7 +1125,7 @@
 
 	if (tcsetattr(lpdcb->Id, TCSADRAIN, &port) == -1) {
 		commerror = WinError();	
-		return -1;
+		return FALSE;
 	} else {
 		commerror = 0;
 		return 0;
@@ -1133,7 +1140,7 @@
 	struct termios port;
 	struct DosDeviceStruct *ptr;
 
-    	dprintf_comm(stddeb,"SetCommState: fd %d, ptr %p\n",fd,lpdcb);
+    	dprintf_comm(stddeb,"SetCommState32: fd %d, ptr %p\n",fd,lpdcb);
 	if (tcgetattr(fd,&port) == -1) {
 		commerror = WinError();	
 		return FALSE;
@@ -1340,7 +1347,7 @@
 {
 	struct termios port;
 
-    	dprintf_comm(stddeb,"GetCommState: fd %d, ptr %p\n", fd, lpdcb);
+    	dprintf_comm(stddeb,"GetCommState16: fd %d, ptr %p\n", fd, lpdcb);
 	if (tcgetattr(fd, &port) == -1) {
 		commerror = WinError();	
 		return -1;
@@ -1379,6 +1386,12 @@
 		case B38400:
 			lpdcb->BaudRate = 38400;
 			break;
+		case B57600:
+			lpdcb->BaudRate = 57600;
+			break;
+		case B115200:
+			lpdcb->BaudRate = 57601;
+			break;
 	}
 #endif
 	switch (port.c_cflag & CSIZE) {
@@ -1459,8 +1472,8 @@
 {
 	struct termios	port;
 
-
     	dprintf_comm(stddeb,"GetCommState32: fd %d, ptr %p\n", fd, lpdcb);
+        if (GetDeviceStruct(fd) == NULL) return FALSE;
 	if (tcgetattr(fd, &port) == -1) {
 		commerror = WinError();	
 		return FALSE;
diff --git a/misc/cpu.c b/misc/cpu.c
index 9fd96cb..014c546 100644
--- a/misc/cpu.c
+++ b/misc/cpu.c
@@ -28,7 +28,7 @@
 
 	/* FIXME: better values for the two entries below... */
 	cachedsi.lpMinimumApplicationAddress	= (void *)0x40000000;
-	cachedsi.lpMaximumApplicationAddress	= (void *)0x80000000;
+	cachedsi.lpMaximumApplicationAddress	= (void *)0x7FFFFFFF;
 	cachedsi.dwActiveProcessorMask		= 1;
 	cachedsi.dwNumberOfProcessors		= 1;
 	cachedsi.dwProcessorType		= PROCESSOR_INTEL_386;
diff --git a/misc/crtdll.c b/misc/crtdll.c
index 91a8732..d5be371 100644
--- a/misc/crtdll.c
+++ b/misc/crtdll.c
@@ -24,6 +24,7 @@
 #include <stdlib.h>
 #include <stdarg.h>
 #include <string.h>
+#include <sys/stat.h>
 #include <unistd.h>
 #include <time.h>
 #include <ctype.h>
@@ -34,7 +35,6 @@
 #include "stddebug.h"
 #include "debug.h"
 #include "module.h"
-#include "xmalloc.h"
 #include "heap.h"
 #include "crtdll.h"
 #include "drive.h"
@@ -84,7 +84,8 @@
 	dprintf_crtdll(stddeb,"CRTDLL__GetMainArgs(%p,%p,%p,%ld).\n",
 		argc,argv,environ,flag
 	);
-	CRTDLL_acmdln_dll = cmdline = xstrdup( GetCommandLine32A() );
+	CRTDLL_acmdln_dll = cmdline = HEAP_strdupA( GetProcessHeap(), 0,
+                                                    GetCommandLine32A() );
  	dprintf_crtdll(stddeb,"CRTDLL__GetMainArgs got \"%s\"\n",
 		cmdline);
 
@@ -105,9 +106,11 @@
 	i=0;xargv=NULL;xargc=0;afterlastspace=0;
 	while (cmdline[i]) {
 		if (cmdline[i]==' ') {
-			xargv=(char**)xrealloc(xargv,sizeof(char*)*(++xargc));
+			xargv=(char**)HeapReAlloc( GetProcessHeap(), 0, xargv,
+                                                   sizeof(char*)*(++xargc));
 			cmdline[i]='\0';
-			xargv[xargc-1] = xstrdup(cmdline+afterlastspace);
+			xargv[xargc-1] = HEAP_strdupA( GetProcessHeap(), 0,
+                                                       cmdline+afterlastspace);
 			i++;
 			while (cmdline[i]==' ')
 				i++;
@@ -116,9 +119,11 @@
 		} else
 			i++;
 	}
-	xargv=(char**)xrealloc(xargv,sizeof(char*)*(++xargc));
+	xargv=(char**)HeapReAlloc( GetProcessHeap(), 0, xargv,
+                                   sizeof(char*)*(++xargc));
 	cmdline[i]='\0';
-	xargv[xargc-1] = xstrdup(cmdline+afterlastspace);
+	xargv[xargc-1] = HEAP_strdupA( GetProcessHeap(), 0,
+                                       cmdline+afterlastspace);
 	CRTDLL_argc_dll	= xargc;
 	*argc		= xargc;
 	CRTDLL_argv_dll	= xargv;
@@ -126,10 +131,7 @@
 
 	dprintf_crtdll(stddeb,"CRTDLL__GetMainArgs found %d arguments\n",
 		CRTDLL_argc_dll);
-	/* FIXME ... use real environment */
-	*environ	= xmalloc(sizeof(LPSTR));
-	CRTDLL_environ_dll = *environ;
-	(*environ)[0] = NULL;
+	CRTDLL_environ_dll = *environ = GetEnvironmentStrings32A();
 	return 0;
 }
 
@@ -920,6 +922,66 @@
 }
 
 /*********************************************************************
+ *                  rename           (CRTDLL.449)
+ */
+INT32 __cdecl CRTDLL_rename(LPCSTR oldpath,LPCSTR newpath)
+{
+    BOOL32 ok = MoveFileEx32A( oldpath, newpath, MOVEFILE_REPLACE_EXISTING );
+    return ok ? 0 : -1;
+}
+
+
+/*********************************************************************
+ *                  _stat          (CRTDLL.280)
+ */
+
+struct win_stat
+{
+    UINT16 win_st_dev;
+    UINT16 win_st_ino;
+    UINT16 win_st_mode;
+    INT16  win_st_nlink;
+    INT16  win_st_uid;
+    INT16  win_st_gid;
+    UINT32 win_st_rdev;
+    INT32  win_st_size;
+    INT32  win_st_atime;
+    INT32  win_st_mtime;
+    INT32  win_st_ctime;
+};
+
+int __cdecl CRTDLL__stat(const char * filename, struct win_stat * buf)
+{
+    int ret=0;
+    DOS_FULL_NAME full_name;
+    struct stat mystat;
+
+    if (!DOSFS_GetFullName( filename, TRUE, &full_name ))
+    {
+      dprintf_crtdll(stddeb,"CRTDLL__stat filename %s bad name\n",filename);
+      return -1;
+    }
+    ret=stat(full_name.long_name,&mystat);
+    dprintf_crtdll(stddeb,"CRTDLL__stat %s%s\n",
+		   filename, (ret)?" failed":"");
+
+    /* FIXME: should check what Windows returns */
+
+    buf->win_st_dev   = mystat.st_dev;
+    buf->win_st_ino   = mystat.st_ino;
+    buf->win_st_mode  = mystat.st_mode;
+    buf->win_st_nlink = mystat.st_nlink;
+    buf->win_st_uid   = mystat.st_uid;
+    buf->win_st_gid   = mystat.st_gid;
+    buf->win_st_rdev  = mystat.st_rdev;
+    buf->win_st_size  = mystat.st_size;
+    buf->win_st_atime = mystat.st_atime;
+    buf->win_st_mtime = mystat.st_mtime;
+    buf->win_st_ctime = mystat.st_ctime;
+    return ret;
+}
+
+/*********************************************************************
  *                  _open           (CRTDLL.239)
  */
 HFILE32 __cdecl CRTDLL__open(LPCSTR path,INT32 flags)
@@ -1350,36 +1412,55 @@
 }
 
 /*********************************************************************
+ *                  _fullpath           (CRTDLL.114)
+ */
+LPSTR __cdecl CRTDLL__fullpath(LPSTR buf, LPCSTR name, INT32 size)
+{
+  DOS_FULL_NAME full_name;
+
+  if (!buf)
+  {
+      size = 256;
+      if(!(buf = CRTDLL_malloc(size))) return NULL;
+  }
+  if (!DOSFS_GetFullName( name, FALSE, &full_name )) return NULL;
+  lstrcpyn32A(buf,full_name.short_name,size);
+  dprintf_crtdll(stderr,"CRTDLL_fullpath got %s\n",buf);
+  return buf;
+}
+
+/*********************************************************************
  *                  _getcwd           (CRTDLL.120)
  */
 CHAR* __cdecl CRTDLL__getcwd(LPSTR buf, INT32 size)
 {
-  DOS_FULL_NAME full_name;
-  char *ret;
+  char test[1];
+  int len;
 
-  dprintf_crtdll(stddeb,"CRTDLL_getcwd for buf %p size %d\n",
-		 buf,size);
-  if (buf == NULL)
+  len = size;
+  if (!buf) {
+    len = size;
+    if (size < 0) /* allocate as big as nescessary */
+      len =GetCurrentDirectory32A(1,test);
+    if(!(buf = CRTDLL_malloc(len)))
     {
-      dprintf_crtdll(stderr,"CRTDLL_getcwd malloc unsupported\n");
-      printf("CRTDLL_getcwd malloc unsupported\n");
-      return 0;
+	/* set error to OutOfRange */
+	return( NULL );
     }
-  ret = getcwd(buf,size);
-  if (!DOSFS_GetFullName( buf, FALSE, &full_name )) 
+  }
+  size = len;
+  if(!(len =GetCurrentDirectory32A(len,buf)))
     {
-      dprintf_crtdll(stddeb,"CRTDLL_getcwd failed\n");
-      return 0;
+      return NULL;
     }
-  if (strlen(full_name.short_name)>size) 
+  if (len > size)
     {
-      dprintf_crtdll(stddeb,"CRTDLL_getcwd string too long\n");
-      return 0;
+      /* set error to ERANGE */
+      dprintf_crtdll(stddeb,"CRTDLL_getcwd buffer to small\n");
+      return NULL;
     }
-  ret=strcpy(buf,full_name.short_name);
-  if (ret) 
-    dprintf_crtdll(stddeb,"CRTDLL_getcwd returned:%s\n",ret);
-  return ret;
+  return buf;
+
 }
 
 /*********************************************************************
@@ -1495,3 +1576,10 @@
 {
     dprintf_crtdll(stddeb,"CRTDLL_signal %d %p: STUB!\n",sig,ptr);
 }
+
+/*********************************************************************
+ *                  _ftol           (CRTDLL.113)
+ */
+LONG __cdecl CRTDLL__ftol(double fl) {
+	return (LONG)fl;
+}
diff --git a/misc/lzexpand.c b/misc/lzexpand.c
index 1754d62..9f37072 100644
--- a/misc/lzexpand.c
+++ b/misc/lzexpand.c
@@ -21,7 +21,6 @@
 #include "lzexpand.h"
 #include "stddebug.h"
 #include "debug.h"
-#include "xmalloc.h"
 
 
 /* The readahead length of the decompressor. Reading single bytes
@@ -169,7 +168,8 @@
 		_llseek32(hfSrc,0,SEEK_SET);
 		return ret?ret:hfSrc;
 	}
-	lzstates=xrealloc(lzstates,(++nroflzstates)*sizeof(struct lzstate));
+	lzstates = HeapReAlloc( GetProcessHeap(), 0, lzstates,
+                                (++nroflzstates)*sizeof(struct lzstate) );
 	lzs		= lzstates+(nroflzstates-1);
 
 	memset(lzs,'\0',sizeof(*lzs));
@@ -178,7 +178,7 @@
 	lzs->lastchar	= head.lastchar;
 	lzs->reallength = head.reallength;
 
-	lzs->get	= xmalloc(GETLEN);
+	lzs->get	= HEAP_xalloc( GetProcessHeap(), 0, GETLEN );
 	lzs->getlen	= 0;
 	lzs->getcur	= 0;
 
@@ -513,7 +513,8 @@
 static LPSTR LZEXPAND_MangleName( LPCSTR fn )
 {
     char *p;
-    char *mfn = (char *)xmalloc( strlen(fn) + 3 ); /* "._" and \0 */
+    char *mfn = (char *)HEAP_xalloc( GetProcessHeap(), 0,
+                                     strlen(fn) + 3 ); /* "._" and \0 */
     strcpy( mfn, fn );
     if (!(p = strrchr( mfn, '\\' ))) p = mfn;
     if ((p = strchr( p, '.' )))
@@ -552,7 +553,7 @@
         {
             LPSTR mfn = LZEXPAND_MangleName(fn);
             fd = OpenFile32(mfn,ofs,mode);
-            free( mfn );
+            HeapFree( GetProcessHeap(), 0, mfn );
 	}
 	if ((mode&~0x70)!=OF_READ)
 		return fd;
@@ -612,11 +613,13 @@
 		return;
 	}
 	if (lzstates[i].get)
-		free(lzstates[i].get);
+		HeapFree( GetProcessHeap(), 0, lzstates[i].get );
 	_lclose32(lzstates[i].realfd);
-	memcpy(lzstates+i,lzstates+i+1,sizeof(struct lzstate)*(nroflzstates-i-1));
+	memmove(lzstates+i,lzstates+i+1,
+                sizeof(struct lzstate)*(nroflzstates-i-1));
 	nroflzstates--;
-	lzstates=xrealloc(lzstates,sizeof(struct lzstate)*nroflzstates);
+	lzstates = HeapReAlloc( GetProcessHeap(), 0, lzstates,
+                                sizeof(struct lzstate)*nroflzstates );
 }
 
 /***********************************************************************
diff --git a/misc/main.c b/misc/main.c
index 3e574de..67c037c 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -178,16 +178,6 @@
 
 #define WINE_APP_DEFAULTS "/usr/lib/X11/app-defaults/Wine"
 
-typedef struct tagENVENTRY {
-  LPSTR	       	        Name;
-  LPSTR	       	        Value;
-  WORD	       	        wSize;
-  struct tagENVENTRY    *Prev;
-  struct tagENVENTRY    *Next;
-} ENVENTRY, *LPENVENTRY;
-
-LPENVENTRY	lpEnvList = NULL;
-
 Display *display;
 Screen *screen;
 Window rootWindow;
@@ -1221,6 +1211,7 @@
 		case SPI_SETFASTTASKSWITCH:
 		case SPI_SETKEYBOARDDELAY:
 		case SPI_SETKEYBOARDSPEED:
+	        case SPI_GETHIGHCONTRAST:
 			fprintf(stderr, "SystemParametersInfo: option %d ignored.\n", uAction);
 			break;
 
diff --git a/misc/ole2nls.c b/misc/ole2nls.c
index e89c0c6..5264c46 100644
--- a/misc/ole2nls.c
+++ b/misc/ole2nls.c
@@ -2039,11 +2039,10 @@
 ) {
 	int	i,len;
 
-	fprintf(stderr,"LCMapStringA(0x%04lx,0x%08lx,%s,%d,%p,%d)\n",
-		lcid,mapflags,srcstr,srclen,dststr,dstlen
-	);
+	dprintf_string(stderr,"LCMapStringA(0x%04lx,0x%08lx,%s,%d,%p,%d)\n",
+		lcid,mapflags,srcstr,srclen,dststr,dstlen);
 	if (!dstlen || !dststr) {
-		dststr = srcstr;
+		dststr = (LPSTR)srcstr;
 	}
 	if (!srclen) srclen = strlen(srcstr);
 	if (!dstlen) dstlen = strlen(dststr);
@@ -2055,8 +2054,18 @@
 			dststr[i]=tolower(srcstr[i]);
 		mapflags &= ~LCMAP_LOWERCASE;
 	}
+	if (mapflags & LCMAP_UPPERCASE) {
+		for (i=0;i<len;i++)
+			dststr[i]=toupper(srcstr[i]);
+		mapflags &= ~LCMAP_UPPERCASE;
+	}
 	if (mapflags)
+	  {
+	    fprintf(stderr,
+		    "LCMapStringA(0x%04lx,0x%08lx,%p,%d,%p,%d)\n",
+		    lcid,mapflags,srcstr,srclen,dststr,dstlen);
 		fprintf(stderr,"	unimplemented flags: 0x%08lx\n",mapflags);
+	  }
 	return len;
 }
 
@@ -2068,11 +2077,11 @@
 ) {
 	int	i,len;
 
-	fprintf(stderr,"LCMapStringW(0x%04lx,0x%08lx,%p,%d,%p,%d)\n",
+	dprintf_string(stderr,"LCMapStringW(0x%04lx,0x%08lx,%p,%d,%p,%d)\n",
 		lcid,mapflags,srcstr,srclen,dststr,dstlen
 	);
 	if (!dstlen || !dststr) {
-		dststr = srcstr;
+		dststr = (LPWSTR)srcstr;
 	}
 	if (!srclen) srclen = lstrlen32W(srcstr);
 	if (!dstlen) dstlen = lstrlen32W(dststr);
@@ -2084,7 +2093,38 @@
 			dststr[i]=tolower(srcstr[i]);
 		mapflags &= ~LCMAP_LOWERCASE;
 	}
+	if (mapflags & LCMAP_UPPERCASE) {
+		for (i=0;i<len;i++)
+			dststr[i]=toupper(srcstr[i]);
+		mapflags &= ~LCMAP_UPPERCASE;
+	}
 	if (mapflags)
+	  {
+	    fprintf(stderr,
+		    "LCMapStringW(0x%04lx,0x%08lx,%p,%d,%p,%d)\n",
+		    lcid,mapflags,srcstr,srclen,dststr,dstlen);
 		fprintf(stderr,"	unimplemented flags: 0x%08lx\n",mapflags);
+	  }
 	return len;
 }
+
+
+INT32 WINAPI GetDateFormat32A(LCID locale,DWORD flags,LPSYSTEMTIME xtime,
+			      LPCSTR format, LPSTR date,INT32 datelen
+) {
+	fprintf(stderr,"GetDateFormat(0x%04x,0x%08lx,%p,%s,%p,%d), stub\n",
+		locale,flags,xtime,format,date,datelen
+	);
+	lstrcpyn32A(date,"1.4.1997",datelen);
+	return strlen("1.4.1997");
+}
+
+INT32 WINAPI GetTimeFormat32A(LCID locale,DWORD flags,LPSYSTEMTIME xtime,
+			      LPCSTR format, LPSTR timestr,INT32 timelen
+) {
+	fprintf(stderr,"GetDateFormat(0x%04x,0x%08lx,%p,%s,%p,%d), stub\n",
+		locale,flags,xtime,format,timestr,timelen
+	);
+	lstrcpyn32A(timestr,"00:00:42",timelen);
+	return strlen("00:00:42");
+}
diff --git a/misc/registry.c b/misc/registry.c
index e14b342..a2c47b0 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -2640,7 +2640,8 @@
 		*lpszValue	= 0;
 		*lpcchValue	= 2;
 	}
-	*lpdwType=val->type;
+	if (lpdwType)
+		*lpdwType=val->type;
 	if (lpbData) {
 		if (val->len>*lpcbData)
 			return ERROR_MORE_DATA;
diff --git a/misc/shell.c b/misc/shell.c
index 22e5f7b..0de6093 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -333,7 +333,7 @@
 
 
 /*************************************************************************
- *             ShellExecute32A   (SHELL32.84)
+ *             ShellExecute32A   (SHELL32.245)
  */
 HINSTANCE32 WINAPI ShellExecute32A( HWND32 hWnd, LPCSTR lpOperation,
                                     LPCSTR lpFile, LPCSTR lpParameters,
@@ -411,7 +411,7 @@
             ABOUT_INFO *info = (ABOUT_INFO *)lParam;
             if (info)
             {
-                SendDlgItemMessage32A(hWnd, stc1, STM_SETICON, info->hIcon, 0);
+                SendDlgItemMessage32A(hWnd, stc1, STM_SETICON32,info->hIcon, 0);
                 GetWindowText32A( hWnd, Template, sizeof(Template) );
                 sprintf( AppTitle, Template, info->szApp );
                 SetWindowText32A( hWnd, AppTitle );
@@ -452,7 +452,7 @@
 }
 
 /*************************************************************************
- *             ShellAbout32A   (SHELL32.82)
+ *             ShellAbout32A   (SHELL32.243)
  */
 BOOL32 WINAPI ShellAbout32A( HWND32 hWnd, LPCSTR szApp, LPCSTR szOtherStuff,
                              HICON32 hIcon )
@@ -469,7 +469,7 @@
 
 
 /*************************************************************************
- *             ShellAbout32W   (SHELL32.83)
+ *             ShellAbout32W   (SHELL32.244)
  */
 BOOL32 WINAPI ShellAbout32W( HWND32 hWnd, LPCWSTR szApp, LPCWSTR szOtherStuff,
                              HICON32 hIcon )
@@ -754,7 +754,7 @@
 
 
 /*************************************************************************
- *             ExtractIcon32A   (SHELL32.20)
+ *             ExtractIcon32A   (SHELL32.133)
  */
 HICON32 WINAPI ExtractIcon32A( HINSTANCE32 hInstance, LPCSTR lpszExeFileName,
                                UINT32 nIconIndex )
@@ -983,7 +983,7 @@
 
 
 /*************************************************************************
- *				SHGetFileInfoA		[SHELL32.54]
+ *				SHGetFileInfoA		[SHELL32.218]
  */
 DWORD WINAPI SHGetFileInfo32A(LPCSTR path,DWORD dwFileAttributes,
                               SHFILEINFO32A *psfi, UINT32 sizeofpsfi,
@@ -996,7 +996,7 @@
 }
 
 /*************************************************************************
- *				CommandLineToArgvW	[SHELL32.2]
+ *				CommandLineToArgvW	[SHELL32.7]
  */
 LPWSTR* WINAPI CommandLineToArgvW(LPWSTR cmdline,LPDWORD numargs)
 {
@@ -1043,12 +1043,26 @@
 	return argv;
 }
 
-void WINAPI Control_RunDLL(DWORD a1,DWORD a2,LPSTR a3,DWORD a4) {
-	fprintf(stderr,"Control_RunDLL(0x%08lx,0x%08lx,%s,0x%08lx)\n",
-		a1,a2,a3,a4
-	);
+/*************************************************************************
+ *				Control_RunDLL		[SHELL32.12]
+ *
+ * Wild speculation in the following!
+ *
+ * http://premium.microsoft.com/msdn/library/techart/msdn193.htm
+ */
+
+void WINAPI Control_RunDLL (HWND32 hwnd, LPCVOID code, LPCSTR cmd, DWORD arg4)
+{
+  dprintf_exec (stddeb, "Control_RunDLL (%08x, %p, \"%s\", %08lx)\n",
+		hwnd,
+		code ? code : "(null)",
+		cmd ? cmd : "(null)",
+		arg4);
 }
 
+/*************************************************************************
+ */
+
 void WINAPI FreeIconList( DWORD dw )
 {
     fprintf( stdnimp, "FreeIconList: empty stub\n" );
diff --git a/misc/spy.c b/misc/spy.c
index 4524f3e..45f368b 100644
--- a/misc/spy.c
+++ b/misc/spy.c
@@ -299,7 +299,11 @@
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
     /* 0x0170 - Win32 Static controls */
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    "STM_SETICON32",		/* 0x0170 */
+    "STM_GETICON32",		/* 0x0171 */
+    "STM_SETIMAGE32",		/* 0x0172 */
+    "STM_GETIMAGE32",		/* 0x0173 */
+    NULL, NULL, NULL, NULL, 
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
     /* 0x0180 - Win32 Listboxes */
diff --git a/misc/system.c b/misc/system.c
index 1c34729..65646bc 100644
--- a/misc/system.c
+++ b/misc/system.c
@@ -13,6 +13,7 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 
+#include "callback.h"
 #include "windows.h"
 #include "miscemu.h"
 
@@ -43,7 +44,7 @@
         if ((SYS_Timers[i].ticks -= SYS_TIMER_RATE) <= 0)
         {
             SYS_Timers[i].ticks += SYS_Timers[i].rate;
-            SYS_Timers[i].callback();
+            Callbacks->CallSystemTimerProc( SYS_Timers[i].callback );
         }
     }
 }
@@ -177,15 +178,3 @@
     SYS_TimersDisabled = TRUE;
     if (SYS_NbTimers) SYSTEM_StopTicks();
 }
-
-
-/***********************************************************************
- *           SYSTEM_GetTimerProc
- *
- * Return the timer proc of a system timer. Used by thunking code.
- */
-FARPROC16 SYSTEM_GetTimerProc( WORD timer )
-{
-    if (!timer || (timer > NB_SYS_TIMERS)) return NULL;
-    return SYS_Timers[timer-1].callback;
-}
diff --git a/misc/toolhelp.c b/misc/toolhelp.c
index cba7996..c9ceabb 100644
--- a/misc/toolhelp.c
+++ b/misc/toolhelp.c
@@ -14,7 +14,6 @@
 #include "toolhelp.h"
 #include "stddebug.h"
 #include "debug.h"
-#include "xmalloc.h"
 
 /* FIXME: to make this working, we have to callback all these registered 
  * functions from all over the WINE code. Someone with more knowledge than
@@ -41,9 +40,12 @@
             break;
     if (i==nrofnotifys) {
         if (notifys==NULL)
-            notifys=(struct notify*)xmalloc(sizeof(struct notify));
+            notifys=(struct notify*)HeapAlloc( GetProcessHeap(), 0,
+                                               sizeof(struct notify) );
         else
-            notifys=(struct notify*)xrealloc(notifys,sizeof(struct notify)*(nrofnotifys+1));
+            notifys=(struct notify*)HeapReAlloc( GetProcessHeap(), 0, notifys,
+                                        sizeof(struct notify)*(nrofnotifys+1));
+        if (!notifys) return FALSE;
         nrofnotifys++;
     }
     notifys[i].htask=htask;
@@ -63,7 +65,8 @@
     if (i==-1)
         return FALSE;
     memcpy(notifys+i,notifys+(i+1),sizeof(struct notify)*(nrofnotifys-i-1));
-    notifys=(struct notify*)xrealloc(notifys,(nrofnotifys-1)*sizeof(struct notify));
+    notifys=(struct notify*)HeapReAlloc( GetProcessHeap(), 0, notifys,
+                                        (nrofnotifys-1)*sizeof(struct notify));
     nrofnotifys--;
     return TRUE;
 }
diff --git a/misc/ver.c b/misc/ver.c
index f48ea77..e81a539 100644
--- a/misc/ver.c
+++ b/misc/ver.c
@@ -1126,7 +1126,6 @@
 }
 
 
-/* FIXME: UNICODE? */
 struct dbA {
 	WORD	nextoff;
 	WORD	datalen;
@@ -1138,7 +1137,8 @@
  */
 };
 
-/* FIXME: UNICODE? */
+#define DATA_OFFSET_A(db) ((4+(strlen((db)->name)+4))&~3)
+
 struct dbW {
 	WORD	nextoff;
 	WORD	datalen;
@@ -1151,9 +1151,17 @@
  */
 };
 
+/* WORD nextoffset;
+ * WORD datalength;
+ * WORD btype;
+ * WCHAR szKey[]; (zero terminated)
+ * PADDING (round up to nearest 32bit boundary)
+ */
+#define DATA_OFFSET_W(db) ((2+2+2+((lstrlen32W((db)->name)+1)*2+3))&~3)
+
 /* this one used for Win16 resources, which are always in ASCII format */
 static BYTE*
-_find_dataA(BYTE *block,LPCSTR str, WORD buff_remain) {
+_find_dataA(BYTE *block,LPCSTR str, int buff_remain) {
 	char	*nextslash;
 	int	substrlen, inc_size;
 	struct	dbA	*db;
@@ -1174,37 +1182,36 @@
 
 	while (1) {
 		db=(struct dbA*)block;
-		dprintf_ver(stddeb,"db=%p,db->nextoff=%d,db->datalen=%d,db->name=%s,db->data=%s\n",
-			db,db->nextoff,db->datalen,db->name,(char*)((char*)db+4+((strlen(db->name)+4)&~3))
+		dprintf_ver(stddeb,"db=%p,db->nextoff=%d,db->datalen=%d,db->name=%s\n",
+			db,db->nextoff,db->datalen,db->name
 		);
-		if ((!db->nextoff) || (!buff_remain)) /* no more entries ? */
+		if ((!db->nextoff) || (buff_remain<=0)) /* no more entries ? */
 			return NULL;
 
 		dprintf_ver(stddeb,"comparing with %s\n",db->name);
-		if (!strncmp(db->name,str,substrlen)) {
+		if (!lstrncmpi32A(db->name,str,substrlen)) {
 			if (nextslash) {
-				inc_size = 4+((strlen(db->name)+4)&~3)+((db->datalen+3)&~3);
-
-				return _find_dataA( block+inc_size ,nextslash,
-							buff_remain - inc_size);
-			}
-			else
+				inc_size=DATA_OFFSET_A(db)+((db->datalen+3)&~3);
+				return _find_dataA(block+inc_size,nextslash,
+							db->nextoff-inc_size);
+			} else
 				return block;
 		}
-		inc_size=((db->nextoff+3)&~3);
-		block=block+inc_size;
-		buff_remain=buff_remain-inc_size;
+		inc_size	 = ((db->nextoff+3)&~3);
+		block		+= inc_size;
+		buff_remain	-= inc_size;
 	}
 }
 
 /* this one used for Win32 resources, which are always in UNICODE format */
 extern LPWSTR CRTDLL_wcschr(LPCWSTR str,WCHAR xchar);
 static BYTE*
-_find_dataW(BYTE *block,LPCWSTR str, WORD buff_remain) {
+_find_dataW(BYTE *block,LPCWSTR str, int buff_remain) {
 	LPWSTR	nextslash;
 	int	substrlen, inc_size;
 	struct	dbW	*db;
 
+
 	while (*str && *str=='\\')
 		str++;
 	if (NULL!=(nextslash=CRTDLL_wcschr(str,'\\')))
@@ -1220,22 +1227,42 @@
 
 
 	while (1) {
+		char	*xs,*vs;
 		db=(struct dbW*)block;
-		if ((!db->nextoff) || (!buff_remain)) /* no more entries ? */
+		xs= HEAP_strdupWtoA(GetProcessHeap(),0,db->name);
+		if (db->datalen) {
+			if (db->btext)
+				vs = HEAP_strdupWtoA(GetProcessHeap(),0,(WCHAR*)((block+DATA_OFFSET_W(db))));
+			else
+				vs = HEAP_strdupA(GetProcessHeap(),0,"not a string");
+		} else
+			vs = HEAP_strdupA(GetProcessHeap(),0,"no data");
+
+		dprintf_ver(stddeb,"db->nextoff=%d,db->name=%s,db->data=\"%s\"\n",
+			db->nextoff,xs,vs
+		);
+		HeapFree(GetProcessHeap(),0,vs);
+		HeapFree(GetProcessHeap(),0,xs);
+		if ((!db->nextoff) || (buff_remain<=0)) /* no more entries ? */
 			return NULL;
 
-		if (!lstrncmp32W(db->name,str,substrlen)) {
+		if (!lstrncmpi32W(db->name,str,substrlen)) {
 			if (nextslash) {
-				inc_size = 8+((lstrlen32W(db->name)*sizeof(WCHAR)+4)&~3)+((db->datalen+3)&~3);
-
+				/* DATA_OFFSET_W(db) (padded to 32bit already)
+				 * DATA[datalength]
+				 * PADDING (round up to nearest 32bit boundary)
+				 * -->	next level structs
+				 */
+				inc_size=DATA_OFFSET_W(db)+((db->datalen+3)&~3);
 				return _find_dataW( block+inc_size ,nextslash,
-							buff_remain - inc_size);
+							db->nextoff-inc_size);
 			} else
 				return block;
 		}
-		inc_size=((db->nextoff+3)&~3);
-		block=block+inc_size;
-		buff_remain=buff_remain-inc_size;
+		/* skip over this block, round up to nearest 32bit boundary */
+		inc_size	=  ((db->nextoff+3)&~3);
+		block		+= inc_size;
+		buff_remain	-= inc_size;
 	}
 }
 
@@ -1244,46 +1271,59 @@
 DWORD WINAPI VerQueryValue16(SEGPTR segblock,LPCSTR subblock,SEGPTR *buffer,
                              UINT16 *buflen)
 {
+	LPSTR	s;
 	BYTE	*block=PTR_SEG_TO_LIN(segblock),*b;
-	char	*s;
 
 	dprintf_ver(stddeb,"VerQueryValue16(%p,%s,%p,%d)\n",
 		block,subblock,buffer,*buflen
 	);
+
 	s=(char*)xmalloc(strlen("VS_VERSION_INFO\\")+strlen(subblock)+1);
 	strcpy(s,"VS_VERSION_INFO\\");strcat(s,subblock);
-
 	/* check for UNICODE version */
 	if (	(*(DWORD*)(block+0x14) != VS_FFI_SIGNATURE) && 
 		(*(DWORD*)(block+0x28) == VS_FFI_SIGNATURE)
 	) {
 		struct	dbW	*db;
 		LPWSTR	wstr;
+		LPSTR	xs;
+
 		wstr = HEAP_strdupAtoW(GetProcessHeap(),0,s);
-		b=_find_dataW(block, wstr, *(WORD *)block);
+		b=_find_dataW(block,wstr,*(WORD*)block);
 		HeapFree(GetProcessHeap(),0,wstr);
 		if (!b) {
-			fprintf(stderr,"key %s not found in versionresource.\n",subblock);
+			fprintf(stderr,"key %s not found in versionresource.\n",s);
 			*buflen=0;
 			return 0;
 		}
 		db=(struct dbW*)b;
-		b	= b+8+((lstrlen32W(db->name)*sizeof(WCHAR)+4)&~3);
+		b	= b+DATA_OFFSET_W(db);
 		*buflen	= db->datalen;
+		if (db->btext) {
+		    xs = HEAP_strdupWtoA(GetProcessHeap(),0,(WCHAR*)b);
+		    dprintf_ver(stderr,"->%s\n",xs);
+		    HeapFree(GetProcessHeap(),0,xs);
+		} else
+		    dprintf_ver(stderr,"->%p\n",b);
 	} else {
 		struct	dbA	*db;
-		b=_find_dataA(block, s, *(WORD *)block);
+		b=_find_dataA(block,s,*(WORD*)block);
 		if (!b) {
-			fprintf(stderr,"key %s not found in versionresource.\n",subblock);
+			fprintf(stderr,"key %s not found in versionresource.\n",s);
 			*buflen=0;
 			return 0;
 		}
 		db=(struct dbA*)b;
-		b	= b+4+((lstrlen32A(db->name)+4)&~3);
+		b	= b+DATA_OFFSET_A(db);
 		*buflen	= db->datalen;
+		/* the string is only printable, if it is below \\StringFileInfo*/
+		if (!lstrncmpi32A("VS_VERSION_INFO\\StringFileInfo\\",s,strlen("VS_VERSION_INFO\\StringFileInfo\\")))
+		    dprintf_ver(stddeb,"	-> %s=%s\n",subblock,b);
+		else
+		    dprintf_ver(stddeb,"	-> %s=%p\n",subblock,b);
 	}
 	*buffer	= (b-block)+segblock;
-	dprintf_ver(stddeb,"	-> %s=%s\n",subblock,b);
+	free(s);
 	return 1;
 }
 
@@ -1296,28 +1336,38 @@
 	dprintf_ver(stddeb,"VerQueryValue32A(%p,%s,%p,%d)\n",
 		block,subblock,buffer,*buflen
 	);
+
 	s=(char*)xmalloc(strlen("VS_VERSION_INFO\\")+strlen(subblock)+1);
 	strcpy(s,"VS_VERSION_INFO\\");strcat(s,subblock);
+
 	/* check for UNICODE version */
 	if (	(*(DWORD*)(block+0x14) != VS_FFI_SIGNATURE) && 
 		(*(DWORD*)(block+0x28) == VS_FFI_SIGNATURE)
 	) {
 		LPWSTR	wstr;
+		LPSTR	xs;
 		struct	dbW	*db;
+
 		wstr = HEAP_strdupAtoW(GetProcessHeap(),0,s);
-		b=_find_dataW(block, wstr, *(WORD *)block);
+		b=_find_dataW(block,wstr,*(WORD*)block);
 		HeapFree(GetProcessHeap(),0,wstr);
 		if (!b) {
-			fprintf(stderr,"key %s not found in versionresource.\n",subblock);
+			fprintf(stderr,"key %s not found in versionresource.\n",s);
 			*buflen=0;
 			return 0;
 		}
-		db=(struct dbW*)b;
+		db	= (struct dbW*)b;
 		*buflen	= db->datalen;
-		b	= b+8+((lstrlen32W(db->name)*sizeof(WCHAR)+4)&~3);
+		b	= b+DATA_OFFSET_W(db);
+		if (db->btext) {
+		    xs = HEAP_strdupWtoA(GetProcessHeap(),0,(WCHAR*)b);
+		    dprintf_ver(stderr,"->%s\n",xs);
+		    HeapFree(GetProcessHeap(),0,xs);
+		} else
+		    dprintf_ver(stderr,"->%p\n",b);
 	} else {
 		struct	dbA	*db;
-		b=_find_dataA(block, s, *(WORD *)block);
+		b=_find_dataA(block,s,*(WORD*)block);
 		if (!b) {
 			fprintf(stderr,"key %s not found in versionresource.\n",subblock);
 			*buflen=0;
@@ -1325,10 +1375,16 @@
 		}
 		db=(struct dbA*)b;
 		*buflen	= db->datalen;
-		b	= b+4+((lstrlen32A(db->name)+4)&~3);
+		b	= b+DATA_OFFSET_A(db);
+
+		/* the string is only printable, if it is below \\StringFileInfo*/
+		if (!lstrncmpi32A("VS_VERSION_INFO\\StringFileInfo\\",s,strlen("VS_VERSION_INFO\\StringFileInfo\\")))
+		    dprintf_ver(stddeb,"	-> %s=%s\n",subblock,b);
+		else
+		    dprintf_ver(stddeb,"	-> %s=%p\n",subblock,b);
 	}
 	*buffer	= b;
-	dprintf_ver(stddeb,"	-> %s=%s\n",subblock,b);
+	free(s);
 	return 1;
 }
 
diff --git a/misc/winsock.c b/misc/winsock.c
index 5aa8477..a5d4dc9 100644
--- a/misc/winsock.c
+++ b/misc/winsock.c
@@ -1332,115 +1332,233 @@
 /* ----------------------------------- DNS services
  *
  * IMPORTANT: 16-bit API structures have SEGPTR pointers inside them.
- * Also, we have to use wsock32 stubs to convert error codes from Unix
- * to WSA, hence no direct mapping in if1632/wsock32.spec.
- *
- * FIXME: Win32 may need "short" h_addrtype and h_length in
- * ...ent structures. If so, use WS_dup_...(pwsi, ..., 0) to
- * convert.
+ * Also, we have to use wsock32 stubs to convert structures and
+ * error codes from Unix to WSA, hence no direct mapping in if1632/wsock32.spec.
  */
 
 static char*	NULL_STRING = "NULL";
 
-
 /***********************************************************************
- *		gethostbyaddr()		(WINSOCK.51)
- *
- *
-struct WIN_hostent *
+ *		gethostbyaddr()		(WINSOCK.51)(WSOCK32.51)
  */
-SEGPTR WINAPI WINSOCK_gethostbyaddr16(const char *addr, INT16 len, INT16 type)
+static struct WIN_hostent* __ws_gethostbyaddr(const char *addr, int len, int type, int dup_flag)
 {
     LPWSINFO      	pwsi = wsi_find(GetCurrentTask());
 
-    dprintf_winsock(stddeb, "WS_GetHostByAddr16(%08x): ptr %8x, len %d, type %d\n", 
-			  (unsigned)pwsi, (unsigned) addr, len, type);
     if( pwsi )
     {
-	struct hostent*	host = gethostbyaddr(addr, len, type);
-	if( host )
-	    if( WS_dup_he(pwsi, host, WS_DUP_SEGPTR) )
-		return SEGPTR_GET(pwsi->buffer);
+	struct hostent*	host;
+	if( (host = gethostbyaddr(addr, len, type)) != NULL )
+	    if( WS_dup_he(pwsi, host, dup_flag) )
+		return (struct WIN_hostent*)(pwsi->buffer);
 	    else 
 		pwsi->err = WSAENOBUFS;
 	else 
 	    pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
     }
-    return (SEGPTR)NULL;
-}
-
-/***********************************************************************
- *              gethostbyaddr()		(WSOCK32.51)
- */
-struct hostent*  WINAPI WINSOCK_gethostbyaddr32(const char *addr, INT32 len,
-                                                INT32 type)
-{
-    LPWSINFO		pwsi = wsi_find(GetCurrentTask());
-
-    dprintf_winsock(stddeb, "WS_GetHostByAddr32(%08x): ptr %8x, len %d, type %d\n",
-                            (unsigned)pwsi, (unsigned) addr, len, type);
-    if( pwsi )
-    {
-	struct hostent* host = gethostbyaddr( addr, len, type );
-	if( host ) 
-	    return host;
-	pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
-    }
     return NULL;
 }
 
+SEGPTR WINAPI WINSOCK_gethostbyaddr16(const char *addr, INT16 len, INT16 type)
+{
+    struct WIN_hostent* retval;
+    dprintf_winsock(stddeb, "WS_GetHostByAddr16: ptr %08x, len %d, type %d\n",
+                            (unsigned) addr, len, type);
+    retval = __ws_gethostbyaddr( addr, len, type, WS_DUP_SEGPTR );
+    return retval ? SEGPTR_GET(retval) : ((SEGPTR)NULL);
+}
+
+struct WIN_hostent* WINAPI WINSOCK_gethostbyaddr32(const char *addr, INT32 len,
+                                                INT32 type)
+{
+    dprintf_winsock(stddeb, "WS_GetHostByAddr32: ptr %08x, len %d, type %d\n",
+                             (unsigned) addr, len, type);
+    return __ws_gethostbyaddr(addr, len, type, WS_DUP_LINEAR);
+}
+
 /***********************************************************************
- *		gethostbyname()		(WINSOCK.52) 
- *
- *
-struct WIN_hostent *
+ *		gethostbyname()		(WINSOCK.52)(WSOCK32.52)
  */
-SEGPTR WINAPI WINSOCK_gethostbyname16(const char *name)
+static struct WIN_hostent * __ws_gethostbyname(const char *name, int dup_flag)
 {
     LPWSINFO              pwsi = wsi_find(GetCurrentTask());
 
-    dprintf_winsock(stddeb, "WS_GetHostByName16(%08x): %s\n",
-                          (unsigned)pwsi, (name)?name:"NULL");
     if( pwsi )
     {
 	struct hostent*     host;
 	if( (host = gethostbyname(name)) != NULL )
-	    if( WS_dup_he(pwsi, host, WS_DUP_SEGPTR) )
-		return SEGPTR_GET(pwsi->buffer);
-	    else pwsi->err = WSAENOBUFS;
+	     if( WS_dup_he(pwsi, host, dup_flag) )
+		 return (struct WIN_hostent*)(pwsi->buffer);
+	     else pwsi->err = WSAENOBUFS;
 	else pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
-  }
-  return (SEGPTR)NULL;
-}
-
-/***********************************************************************
- *              gethostbyname()		(WSOCK32,52)
- */
-struct hostent*  WINAPI WINSOCK_gethostbyname32(const char* name)
-{
-    LPWSINFO            pwsi = wsi_find(GetCurrentTask());
-
-    dprintf_winsock(stddeb, "WS_GetHostByName32(%08x): %s\n",
-                            (unsigned)pwsi, (name)?name:"NULL");
-    if( pwsi )
-    {
-	struct hostent* host = gethostbyname( name );
-	if( host )
-	    return host;
-	pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
     }
     return NULL;
 }
 
+SEGPTR WINAPI WINSOCK_gethostbyname16(const char *name)
+{
+    struct WIN_hostent* retval;
+    dprintf_winsock(stddeb, "WS_GetHostByName16: %s\n", (name)?name:NULL_STRING);
+    retval = __ws_gethostbyname( name, WS_DUP_SEGPTR );
+    return (retval)? SEGPTR_GET(retval) : ((SEGPTR)NULL) ;
+}
+
+struct WIN_hostent* WINAPI WINSOCK_gethostbyname32(const char* name)
+{
+    dprintf_winsock(stddeb, "WS_GetHostByName32: %s\n", (name)?name:NULL_STRING);
+    return __ws_gethostbyname( name, WS_DUP_LINEAR );
+}
+
+
 /***********************************************************************
- *		gethostname()		(WSOCK32.57)
+ *		getprotobyname()	(WINSOCK.53)(WSOCK32.53)
+ */
+static struct WIN_protoent* __ws_getprotobyname(const char *name, int dup_flag)
+{
+    LPWSINFO              pwsi = wsi_find(GetCurrentTask());
+
+    if( pwsi )
+    {
+	struct protoent*     proto;
+	if( (proto = getprotobyname(name)) != NULL )
+	    if( WS_dup_pe(pwsi, proto, dup_flag) )
+		return (struct WIN_protoent*)(pwsi->buffer);
+	    else pwsi->err = WSAENOBUFS;
+	else pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
+    }
+    return NULL;
+}
+
+SEGPTR WINAPI WINSOCK_getprotobyname16(const char *name)
+{
+    struct WIN_protoent* retval;
+    dprintf_winsock(stddeb, "WS_GetProtoByName16: %s\n", (name)?name:NULL_STRING);
+    retval = __ws_getprotobyname(name, WS_DUP_SEGPTR);
+    return retval ? SEGPTR_GET(retval) : ((SEGPTR)NULL);
+}
+
+struct WIN_protoent* WINAPI WINSOCK_getprotobyname32(const char* name)
+{
+    dprintf_winsock(stddeb, "WS_GetProtoByName32: %s\n", (name)?name:NULL_STRING);
+    return __ws_getprotobyname(name, WS_DUP_LINEAR);
+}
+
+
+/***********************************************************************
+ *		getprotobynumber()	(WINSOCK.54)(WSOCK32.54)
+ */
+static struct WIN_protoent* __ws_getprotobynumber(int number, int dup_flag)
+{
+    LPWSINFO              pwsi = wsi_find(GetCurrentTask());
+
+    if( pwsi )
+    {
+	struct protoent*     proto;
+	if( (proto = getprotobynumber(number)) != NULL )
+	    if( WS_dup_pe(pwsi, proto, dup_flag) )
+		return (struct WIN_protoent*)(pwsi->buffer);
+	    else pwsi->err = WSAENOBUFS;
+	else pwsi->err = WSANO_DATA;
+    }
+    return NULL;
+}
+
+SEGPTR WINAPI WINSOCK_getprotobynumber16(INT16 number)
+{
+    struct WIN_protoent* retval;
+    dprintf_winsock(stddeb, "WS_GetProtoByNumber16: %i\n", number);
+    retval = __ws_getprotobynumber(number, WS_DUP_SEGPTR);
+    return retval ? SEGPTR_GET(retval) : ((SEGPTR)NULL);
+}
+
+struct WIN_protoent* WINAPI WINSOCK_getprotobynumber32(INT32 number)
+{
+    dprintf_winsock(stddeb, "WS_GetProtoByNumber32: %i\n", number);
+    return __ws_getprotobynumber(number, WS_DUP_LINEAR);
+}
+
+
+/***********************************************************************
+ *		getservbyname()		(WINSOCK.55)(WSOCK32.55)
+ */
+struct WIN_servent* __ws_getservbyname(const char *name, const char *proto, int dup_flag)
+{
+    LPWSINFO              pwsi = wsi_find(GetCurrentTask());
+
+    if( pwsi )
+    {
+	struct servent*     serv;
+	if( (serv = getservbyname(name, proto)) != NULL )
+	    if( WS_dup_se(pwsi, serv, dup_flag) )
+		return (struct WIN_servent*)(pwsi->buffer);
+	    else pwsi->err = WSAENOBUFS;
+	else pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
+    }
+    return NULL;
+}
+
+SEGPTR WINAPI WINSOCK_getservbyname16(const char *name, const char *proto)
+{
+    struct WIN_servent* retval;
+    dprintf_winsock(stddeb, "WS_GetServByName16: '%s', '%s'\n",
+                            (name)?name:NULL_STRING, (proto)?proto:NULL_STRING);
+    retval = __ws_getservbyname(name, proto, WS_DUP_SEGPTR);
+    return retval ? SEGPTR_GET(retval) : ((SEGPTR)NULL);
+}
+
+struct WIN_servent* WINAPI WINSOCK_getservbyname32(const char *name, const char *proto)
+{
+    dprintf_winsock(stddeb, "WS_GetServByName32: '%s', '%s'\n",
+                            (name)?name:NULL_STRING, (proto)?proto:NULL_STRING);
+    return __ws_getservbyname(name, proto, WS_DUP_LINEAR);
+}
+
+
+/***********************************************************************
+ *		getservbyport()		(WINSOCK.56)(WSOCK32.56)
+ */
+static struct WIN_servent* __ws_getservbyport(int port, const char* proto, int dup_flag)
+{
+    LPWSINFO              pwsi = wsi_find(GetCurrentTask());
+
+    if( pwsi )
+    {
+	struct servent*     serv;
+	if( (serv = getservbyport(port, proto)) != NULL )
+	    if( WS_dup_se(pwsi, serv, dup_flag) )
+		return (struct WIN_servent*)(pwsi->buffer);
+	    else pwsi->err = WSAENOBUFS;
+	else pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
+    }
+    return NULL;
+}
+
+SEGPTR WINAPI WINSOCK_getservbyport16(INT16 port, const char *proto)
+{
+    struct WIN_servent* retval;
+    dprintf_winsock(stddeb, "WS_GetServByPort16: %i, '%s'\n",
+                            (int)port, (proto)?proto:NULL_STRING);
+    retval = __ws_getservbyport(port, proto, WS_DUP_SEGPTR);
+    return retval ? SEGPTR_GET(retval) : ((SEGPTR)NULL);
+}
+
+struct WIN_servent* WINAPI WINSOCK_getservbyport32(INT32 port, const char *proto)
+{
+    dprintf_winsock(stddeb, "WS_GetServByPort32: %i, '%s'\n",
+                            (int)port, (proto)?proto:NULL_STRING);
+    return __ws_getservbyport(port, proto, WS_DUP_LINEAR);
+}
+
+
+/***********************************************************************
+ *              gethostname()           (WSOCK32.57)
  */
 INT32 WINAPI WINSOCK_gethostname32(char *name, INT32 namelen)
 {
     LPWSINFO              pwsi = wsi_find(GetCurrentTask());
 
-    dprintf_winsock(stddeb, "WS_GetHostName(%08x): name %s, len %d\n", 
-			  (unsigned)pwsi, (name)?name:NULL_STRING, namelen);
+    dprintf_winsock(stddeb, "WS_GetHostName(%08x): name %s, len %d\n",
+                          (unsigned)pwsi, (name)?name:NULL_STRING, namelen);
     if( pwsi )
     {
 	if (gethostname(name, namelen) == 0) return 0;
@@ -1450,186 +1568,13 @@
 }
 
 /***********************************************************************
- *              gethostname()		(WINSOCK.57)
+ *              gethostname()           (WINSOCK.57)
  */
 INT16 WINAPI WINSOCK_gethostname16(char *name, INT16 namelen)
 {
     return (INT16)WINSOCK_gethostname32(name, namelen);
 }
 
-/***********************************************************************
- *		getprotobyname()	(WINSOCK.53)
- *
- *
-struct WIN_protoent *
- */
-SEGPTR WINAPI WINSOCK_getprotobyname16(char *name)
-{
-    LPWSINFO              pwsi = wsi_find(GetCurrentTask());
-
-    dprintf_winsock(stddeb, "WS_GetProtoByName16(%08x): %s\n",
-                          (unsigned)pwsi, (name)?name:NULL_STRING);
-    if( pwsi )
-    {
-	struct protoent*     proto;
-	if( (proto = getprotobyname(name)) != NULL )
-	    if( WS_dup_pe(pwsi, proto, WS_DUP_SEGPTR) )
-		return SEGPTR_GET(pwsi->buffer);
-	    else pwsi->err = WSAENOBUFS;
-	else pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
-    }
-    return (SEGPTR)NULL;
-}
-
-/***********************************************************************
- *              getprotobyname()	(WSOCK32.53)
- */
-struct protoent* WINAPI WINSOCK_getprotobyname32(char* name)
-{
-    LPWSINFO              pwsi = wsi_find(GetCurrentTask());
-
-    dprintf_winsock(stddeb, "WS_GetProtoByName32(%08x): %s\n",
-                          (unsigned)pwsi, (name)?name:NULL_STRING);
-    if( pwsi )
-    {
-	struct protoent* proto;
-	if( (proto = getprotobyname(name)) != NULL )
-                return proto;
-        pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
-    }
-    return NULL;
-}
-
-
-/***********************************************************************
- *		getprotobynumber()	(WINSOCK.54)
- *
- *
-struct WIN_protoent *
- */
-SEGPTR WINAPI WINSOCK_getprotobynumber16(INT16 number)
-{
-    LPWSINFO              pwsi = wsi_find(GetCurrentTask());
-
-    dprintf_winsock(stddeb, "WS_GetProtoByNumber16(%08x): %i\n", (unsigned)pwsi, number);
-
-    if( pwsi )
-    {
-	struct protoent*     proto;
-	if( (proto = getprotobynumber(number)) != NULL )
-	    if( WS_dup_pe(pwsi, proto, WS_DUP_SEGPTR) )
-		return SEGPTR_GET(pwsi->buffer);
-	    else pwsi->err = WSAENOBUFS;
-	else pwsi->err = WSANO_DATA;
-    }
-    return (SEGPTR)NULL;
-}
-
-/***********************************************************************
- *              getprotobynumber()	(WSOCK32.54)
- */
-struct protoent* WINAPI WINSOCK_getprotobynumber32(INT32 number)
-{
-    LPWSINFO              pwsi = wsi_find(GetCurrentTask());
-
-    dprintf_winsock(stddeb, "WS_GetProtoByNumber32(%08x): %i\n", (unsigned)pwsi, number);
-
-    if( pwsi )
-    {
-	struct protoent* proto;
-	if( (proto = getprotobynumber(number)) != NULL )
-	    return proto;
-	pwsi->err = WSANO_DATA;
-    }
-    return NULL;
-}
-
-/***********************************************************************
- *		getservbyname()		(WINSOCK.55)
- *
- *
-struct WIN_servent *
- */
-SEGPTR WINAPI WINSOCK_getservbyname16(const char *name, const char *proto)
-{
-    LPWSINFO              pwsi = wsi_find(GetCurrentTask());
-
-    dprintf_winsock(stddeb, "WS_GetServByName16(%08x): '%s', '%s'\n", 
-			  (unsigned)pwsi, (name)?name:NULL_STRING, (proto)?proto:NULL_STRING);
-    if( pwsi )
-    {
-	struct servent*     serv;
-	if( (serv = getservbyname(name, proto)) != NULL )
-	    if( WS_dup_se(pwsi, serv, WS_DUP_SEGPTR) )
-		return SEGPTR_GET(pwsi->buffer);
-	    else pwsi->err = WSAENOBUFS;
-	else pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
-    }
-    return (SEGPTR)NULL;
-}
-
-/***********************************************************************
- *              getservbyname()		(WSOCK32.55)
- */
-struct servent* WINAPI WINSOCK_getservbyname32(const char *name, const char *proto)
-{
-    LPWSINFO              pwsi = wsi_find(GetCurrentTask());
-
-    dprintf_winsock(stddeb, "WS_GetServByName32(%08x): '%s', '%s'\n",
-                          (unsigned)pwsi, (name)?name:NULL_STRING, (proto)?proto:NULL_STRING);
-    if( pwsi )
-    {
-	struct servent* serv;
-	if( (serv = getservbyname(name, proto)) != NULL )
-	    return serv;
-	pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
-    }
-    return NULL;
-}
-
-/***********************************************************************
- *		getservbyport()		(WINSOCK.56)
- *
- *
-struct WIN_servent *
- */
-SEGPTR WINAPI WINSOCK_getservbyport16(INT16 port, const char *proto)
-{
-    LPWSINFO              pwsi = wsi_find(GetCurrentTask());
-
-    dprintf_winsock(stddeb, "WS_GetServByPort16(%08x): %i, '%s'\n",
-                          (unsigned)pwsi, (int)port, (proto)?proto:NULL_STRING);
-    if( pwsi )
-    {
-	struct servent*     serv;
-	if( (serv = getservbyport(port, proto)) != NULL )
-	    if( WS_dup_se(pwsi, serv, WS_DUP_SEGPTR) )
-		return SEGPTR_GET(pwsi->buffer);
-	    else pwsi->err = WSAENOBUFS;
-	else pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
-    }
-    return (SEGPTR)NULL;
-}
-
-/***********************************************************************
- *              getservbyport()		(WSOCK32.56)
- */
-struct servent* WINAPI WINSOCK_getservbyport32(INT32 port, const char *proto)
-{
-    LPWSINFO              pwsi = wsi_find(GetCurrentTask());
-
-    dprintf_winsock(stddeb, "WS_GetServByPort32(%08x): %i, '%s'\n",
-                          (unsigned)pwsi, (int)port, (proto)?proto:NULL_STRING);
-    if( pwsi )
-    {
-	struct servent* serv;
-	if( (serv = getservbyport(port, proto)) != NULL )
-	    return serv;
-	pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
-    }
-    return NULL;
-}
-
 
 /* ------------------------------------- Windows sockets extensions -- *
  *								       *
@@ -1679,6 +1624,19 @@
   return 0;
 }                     
 
+/***********************************************************************
+ *       WSAAsyncGetHostByName32()	(WSOCK32.103)
+ */
+HANDLE32 WINAPI WSAAsyncGetHostByName32(HWND32 hWnd, UINT32 uMsg, LPCSTR name, 
+                                      LPSTR sbuf, INT32 buflen)
+{
+  LPWSINFO              pwsi = wsi_find(GetCurrentTask());
+  dprintf_winsock(stddeb, "WS_AsyncGetHostByName(%08x): hwnd %04x, msg %04x, host %s, buffer %i\n",
+                          (unsigned)pwsi, hWnd, uMsg, (name)?name:NULL_STRING, (int)buflen );
+
+  return 0;
+}                     
+
 
 /***********************************************************************
  *       WSAAsyncGetProtoByName()	(WINSOCK.105)
diff --git a/misc/wsprintf.c b/misc/wsprintf.c
index 87a8477..da2d15f 100644
--- a/misc/wsprintf.c
+++ b/misc/wsprintf.c
@@ -19,6 +19,7 @@
 #define WPRINTF_LONG        0x0008  /* Long arg ('l' prefix) */
 #define WPRINTF_SHORT       0x0010  /* Short arg ('h' prefix) */
 #define WPRINTF_UPPER_HEX   0x0020  /* Upper-case hex ('X' specifier) */
+#define WPRINTF_WIDE        0x0040  /* Wide arg ('w' prefix) */
 
 typedef enum
 {
@@ -75,6 +76,7 @@
     }
     if (*p == 'l') { res->flags |= WPRINTF_LONG; p++; }
     else if (*p == 'h') { res->flags |= WPRINTF_SHORT; p++; }
+    else if (*p == 'w') { res->flags |= WPRINTF_WIDE; p++; }
     switch(*p)
     {
     case 'c':
@@ -88,10 +90,12 @@
         res->type = WPR_SIGNED;
         break;
     case 's':
-        res->type = (res->flags & WPRINTF_LONG) ? WPR_WSTRING : WPR_STRING;
+        res->type = (res->flags & (WPRINTF_LONG |WPRINTF_WIDE)) 
+	            ? WPR_WSTRING : WPR_STRING;
         break;
     case 'S':
-        res->type = (res->flags & WPRINTF_SHORT) ? WPR_STRING : WPR_WSTRING;
+        res->type = (res->flags & (WPRINTF_SHORT|WPRINTF_WIDE))
+	            ? WPR_STRING : WPR_WSTRING;
         break;
     case 'u':
         res->type = WPR_UNSIGNED;
diff --git a/msdos/int21.c b/msdos/int21.c
index 94ab5ed..b654e5f 100644
--- a/msdos/int21.c
+++ b/msdos/int21.c
@@ -24,7 +24,6 @@
 #include "task.h"
 #include "options.h"
 #include "miscemu.h"
-#include "xmalloc.h"
 #include "stddebug.h"
 #include "debug.h"
 #if defined(__svr4__) || defined(_SCO_DS)
@@ -535,7 +534,7 @@
         SET_CFLAG(context);
         return 0;
     }
-    dta->unixPath = xstrdup( full_name.long_name );
+    dta->unixPath = HEAP_strdupA( GetProcessHeap(), 0, full_name.long_name );
     p = strrchr( dta->unixPath, '/' );
     *p = '\0';
 
@@ -544,7 +543,7 @@
      */
     if (!DOSFS_ToDosFCBFormat( p + 1, dta->mask ))
     {
-        free( dta->unixPath );
+        HeapFree( GetProcessHeap(), 0, dta->unixPath );
         dta->unixPath = NULL;
         DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk );
         AX_reg(context) = ER_FileNotFound;
@@ -569,14 +568,14 @@
     if (!(count = DOSFS_FindNext( dta->unixPath, dta->mask, NULL, dta->drive,
                                   dta->search_attr, dta->count, &entry )))
     {
-        free( dta->unixPath );
+        HeapFree( GetProcessHeap(), 0, dta->unixPath );
         dta->unixPath = NULL;
         return 0;
     }
     if ((int)dta->count + count > 0xffff)
     {
         fprintf( stderr, "Too many directory entries in %s\n", dta->unixPath );
-        free( dta->unixPath );
+        HeapFree( GetProcessHeap(), 0, dta->unixPath );
         dta->unixPath = NULL;
         return 0;
     }
@@ -850,13 +849,15 @@
     case 0x27: /* RANDOM BLOCK READ FROM FCB FILE */
     case 0x28: /* RANDOM BLOCK WRITE TO FCB FILE */
     case 0x29: /* PARSE FILENAME INTO FCB */
-    case 0x2e: /* SET VERIFY FLAG */
     case 0x37: /* "SWITCHAR" - GET SWITCH CHARACTER
                   "SWITCHAR" - SET SWITCH CHARACTER
                   "AVAILDEV" - SPECIFY \DEV\ PREFIX USE */
     case 0x54: /* GET VERIFY FLAG */
         INT_BARF( context, 0x21 );
         break;
+    case 0x2e: /* SET VERIFY FLAG */
+    	/* we cannot change the behaviour anyway, so just ignore it */
+    	break;
 
     case 0x18: /* NULL FUNCTIONS FOR CP/M COMPATIBILITY */
     case 0x1d:
@@ -1197,16 +1198,20 @@
             break;
 
 	case 0x0e: /* get logical drive mapping */
-	    AL_reg(context) = 0; /* drive has no mapping */
+	    AL_reg(context) = 0; /* drive has no mapping - FIXME: may be wrong*/
 	    break;
 
         case 0x0F:   /* Set logical drive mapping */
-            /* FIXME: Not implemented at the moment, always returns error
-             */
-            INT_BARF( context, 0x21 );
-            AX_reg(context) = 0x0001; /* invalid function */
-            SET_CFLAG(context);
+	    {
+	    int drive;
+	    drive = DOS_GET_DRIVE ( BL_reg(context) );
+	    if ( ! DRIVE_SetLogicalMapping ( drive, drive+1 ) )
+	    {
+		SET_CFLAG(context);
+		AX_reg(context) = 0x000F;  /* invalid drive */
+	    }
             break;
+	    }
                 
         default:
             INT_BARF( context, 0x21 );
diff --git a/multimedia/Makefile.in b/multimedia/Makefile.in
index 717bec4..8f20e17 100644
--- a/multimedia/Makefile.in
+++ b/multimedia/Makefile.in
@@ -12,6 +12,7 @@
 	mcicda.c \
 	mcistring.c \
 	midi.c \
+	mixer.c \
 	mmaux.c \
 	mmsystem.c \
 	time.c
diff --git a/multimedia/audio.c b/multimedia/audio.c
index 039521e..0d5e14c 100644
--- a/multimedia/audio.c
+++ b/multimedia/audio.c
@@ -3,9 +3,16 @@
  *
  * Copyright 1994 Martin Ayotte
  */
+/*
+ * FIXME:
+ *	- record/play should and must be done asynchronous
+ *	- segmented/linear pointer problems (lpData in waveheaders,W*_DONE cbs)
+ */
 
 #define EMULATE_SB16
 
+#define DEBUG_MCIWAVE
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -15,6 +22,7 @@
 #include "user.h"
 #include "driver.h"
 #include "mmsystem.h"
+#include "heap.h"
 #include "ldt.h"
 
 #ifdef linux
@@ -41,37 +49,37 @@
 #define MAX_MCIWAVDRV 	(1)
 
 typedef struct {
-	int		    unixdev;
-	int		    state;
-	DWORD		    bufsize;
-	WAVEOPENDESC        waveDesc;
-	WORD                wFlags;
-	PCMWAVEFORMAT	    Format;
-	SEGPTR  	    lp16QueueHdr;  /* Segmented LPWAVEHDR */
-	DWORD		    dwTotalPlayed;
-	} LINUX_WAVEOUT;
+	int		unixdev;
+	int		state;
+	DWORD		bufsize;
+	WAVEOPENDESC	waveDesc;
+	WORD		wFlags;
+	PCMWAVEFORMAT	Format;
+	LPWAVEHDR	lpQueueHdr;
+	DWORD		dwTotalPlayed;
+} LINUX_WAVEOUT;
 
 typedef struct {
-	int	            unixdev;
-	int	            state;
-	DWORD               bufsize;            /* Linux '/dev/dsp' give us that size */
-	WAVEOPENDESC        waveDesc;
-	WORD                wFlags;
-	PCMWAVEFORMAT       Format;
-	SEGPTR              lp16QueueHdr;  /* Segmented LPWAVEHDR */
-	DWORD               dwTotalRecorded;
-	} LINUX_WAVEIN;
+	int		unixdev;
+	int		state;
+	DWORD		bufsize;	/* Linux '/dev/dsp' give us that size */
+	WAVEOPENDESC	waveDesc;
+	WORD		wFlags;
+	PCMWAVEFORMAT	Format;
+	LPWAVEHDR	lpQueueHdr;
+	DWORD		dwTotalRecorded;
+} LINUX_WAVEIN;
 
 typedef struct {
-        int                 nUseCount;          /* Incremented for each shared open */
-	BOOL16              fShareable;         /* TRUE if first open was shareable */
-	WORD                wNotifyDeviceID;    /* MCI device ID with a pending notification */
-	HANDLE16            hCallback;          /* Callback handle for pending notification */
-	HMMIO16	            hFile;		/* mmio file handle open as Element */
-	MCI_WAVE_OPEN_PARMS openParms;
-	PCMWAVEFORMAT       WaveFormat;
-	WAVEHDR             WaveHdr;
-	BOOL16              fInput;             /* FALSE = Output, TRUE = Input */
+        int		nUseCount;	/* Incremented for each shared open */
+	BOOL16		fShareable;	/* TRUE if first open was shareable */
+	WORD		wNotifyDeviceID;/* MCI device ID with a pending notification */
+	HANDLE16	hCallback;	/* Callback handle for pending notification */
+	HMMIO16		hFile;		/* mmio file handle open as Element */
+	MCI_WAVE_OPEN_PARMS16 openParms;
+	PCMWAVEFORMAT	WaveFormat;
+	WAVEHDR		WaveHdr;
+	BOOL16		fInput;		/* FALSE = Output, TRUE = Input */
 } LINUX_MCIWAVE;
 
 static LINUX_WAVEOUT	WOutDev[MAX_WAVOUTDRV];
@@ -80,8 +88,8 @@
 
 
 /**************************************************************************
-* 				WAVE_NotifyClient			[internal]
-*/
+ * 			WAVE_NotifyClient			[internal]
+ */
 static DWORD WAVE_NotifyClient(UINT16 wDevID, WORD wMsg, 
 				DWORD dwParam1, DWORD dwParam2)
 {
@@ -125,14 +133,12 @@
 
 
 /**************************************************************************
- * 				WAVE_mciOpen	                        [internal]*/
-static DWORD WAVE_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_PARMS lpParms)
+ * 			WAVE_mciOpen	                        [internal]
+ */
+static DWORD WAVE_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_PARMS16 lpParms)
 {
-	HLOCAL16        hFormat;
-	LPWAVEFORMAT    lpFormat;
 	LPPCMWAVEFORMAT	lpWaveFormat;
-	HLOCAL16	hDesc;
-	LPWAVEOPENDESC 	lpDesc;
+	WAVEOPENDESC 	waveDesc;
 	LPSTR		lpstrElementName;
 	DWORD		dwRet;
 	char		str[128];
@@ -149,11 +155,10 @@
 			++MCIWavDev[wDevID].nUseCount;
 		else
 			return MCIERR_MUST_USE_SHAREABLE;
-		}
-	else {
+	} else {
 		MCIWavDev[wDevID].nUseCount = 1;
 		MCIWavDev[wDevID].fShareable = dwFlags & MCI_OPEN_SHAREABLE;
-		}
+	}
 
 	MCIWavDev[wDevID].fInput = FALSE;
 
@@ -166,25 +171,22 @@
 		if ( lpstrElementName && (strlen(lpstrElementName) > 0)) {
 			strcpy(str, lpstrElementName);
 			CharUpper32A(str);
-			MCIWavDev[wDevID].hFile = mmioOpen(str, NULL, 
+			MCIWavDev[wDevID].hFile = mmioOpen16(str, NULL, 
 				MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_EXCLUSIVE);
 			if (MCIWavDev[wDevID].hFile == 0) {
 				dprintf_mciwave(stddeb,"WAVE_mciOpen // can't find file='%s' !\n", str);
 				return MCIERR_FILE_NOT_FOUND;
-				}
 			}
+		}
 		else 
 			MCIWavDev[wDevID].hFile = 0;
-		}
+	}
 	dprintf_mciwave(stddeb,"WAVE_mciOpen // hFile=%u\n", MCIWavDev[wDevID].hFile);
-	memcpy(&MCIWavDev[wDevID].openParms, lpParms, sizeof(MCI_WAVE_OPEN_PARMS));
+	memcpy(&MCIWavDev[wDevID].openParms, lpParms, sizeof(MCI_WAVE_OPEN_PARMS16));
 	MCIWavDev[wDevID].wNotifyDeviceID = lpParms->wDeviceID;
 	lpWaveFormat = &MCIWavDev[wDevID].WaveFormat;
 
-	hDesc = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
-	if (hDesc == 0) return MCIERR_INTERNAL;   /* is this right ? */
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hDesc);
-	lpDesc->hWave = 0;
+	waveDesc.hWave = 0;
 /*
 	lpWaveFormat->wf.wFormatTag = WAVE_FORMAT_PCM;
 	lpWaveFormat->wBitsPerSample = 8;
@@ -196,33 +198,28 @@
 	if (MCIWavDev[wDevID].hFile != 0) {
 		MMCKINFO	mmckInfo;
 		MMCKINFO	ckMainRIFF;
-		if (mmioDescend(MCIWavDev[wDevID].hFile, &ckMainRIFF, NULL, 0) != 0) {
+		if (mmioDescend(MCIWavDev[wDevID].hFile, &ckMainRIFF, NULL, 0) != 0)
 			return MCIERR_INTERNAL;
-			}
 		dprintf_mciwave(stddeb,
 				"WAVE_mciOpen // 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'))) {
+		    (ckMainRIFF.fccType != mmioFOURCC('W', 'A', 'V', 'E')))
 			return MCIERR_INTERNAL;
-			}
 		mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
-		if (mmioDescend(MCIWavDev[wDevID].hFile, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) != 0) {
+		if (mmioDescend(MCIWavDev[wDevID].hFile, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) != 0)
 			return MCIERR_INTERNAL;
-			}
 		dprintf_mciwave(stddeb,
 				"WAVE_mciOpen // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
 				(LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType,
 				mmckInfo.cksize);
 		if (mmioRead(MCIWavDev[wDevID].hFile, (HPSTR) lpWaveFormat,
-		    (long) sizeof(PCMWAVEFORMAT)) != (long) sizeof(PCMWAVEFORMAT)) {
+		    (long) sizeof(PCMWAVEFORMAT)) != (long) sizeof(PCMWAVEFORMAT))
 			return MCIERR_INTERNAL;
-			}
 		mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
-		if (mmioDescend(MCIWavDev[wDevID].hFile, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) != 0) {
+		if (mmioDescend(MCIWavDev[wDevID].hFile, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) != 0)
 			return MCIERR_INTERNAL;
-			}
 		dprintf_mciwave(stddeb,
 				"WAVE_mciOpen // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
 				(LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType,
@@ -231,31 +228,23 @@
 			"WAVE_mciOpen // nChannels=%d nSamplesPerSec=%ld\n",
 			lpWaveFormat->wf.nChannels, lpWaveFormat->wf.nSamplesPerSec);
 		lpWaveFormat->wBitsPerSample = 0;
-		}
-
+	}
 	lpWaveFormat->wf.nAvgBytesPerSec = 
 		lpWaveFormat->wf.nSamplesPerSec * lpWaveFormat->wf.nBlockAlign;
-	hFormat = USER_HEAP_ALLOC(sizeof(PCMWAVEFORMAT));
-	lpFormat =  (LPWAVEFORMAT) USER_HEAP_LIN_ADDR(hFormat);
-	memcpy(lpFormat, lpWaveFormat, sizeof(PCMWAVEFORMAT));
-	lpDesc->lpFormat = (LPWAVEFORMAT)USER_HEAP_SEG_ADDR(hFormat);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_SEG_ADDR(hDesc);
+	waveDesc.lpFormat = (LPWAVEFORMAT)lpWaveFormat;
 
 /*
    By default the device will be opened for output, the MCI_CUE function is there to
    change from output to input and back
 */
 
-	dwRet = wodMessage(wDevID, WODM_OPEN, 0, (DWORD)lpDesc, CALLBACK_NULL);
-
-	USER_HEAP_FREE(hFormat);
-	USER_HEAP_FREE(hDesc);
+	dwRet=wodMessage(wDevID,WODM_OPEN,0,(DWORD)&waveDesc,CALLBACK_NULL);
 	return 0;
 }
 
 /**************************************************************************
-*                               WAVE_mciCue             [internal]
-*/
+ *                               WAVE_mciCue             [internal]
+ */
 
 static DWORD WAVE_mciCue(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
 {
@@ -270,9 +259,8 @@
    are ignored
 */
 
-        DWORD          dwRet;
-        HLOCAL16       hDesc;
-        LPWAVEOPENDESC lpDesc;
+        DWORD		dwRet;
+        WAVEOPENDESC	waveDesc;
 
 	dprintf_mciwave(stddeb,"WAVE_mciCue(%u, %08lX, %p);\n", wDevID, dwParam, lpParms);
 
@@ -283,39 +271,31 @@
 	  MCIWavDev[wDevID].hFile = 0;
 	}
 
-	hDesc = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hDesc);
-
 	dwRet = MMSYSERR_NOERROR;  /* assume success */
-
 	if ((dwParam & MCI_WAVE_INPUT) && !MCIWavDev[wDevID].fInput) {
-
 /* FIXME this is just a hack WOutDev should be hidden here */
-	        memcpy(lpDesc,&WOutDev[wDevID].waveDesc,sizeof(WAVEOPENDESC));
+	        memcpy(&waveDesc,&WOutDev[wDevID].waveDesc,sizeof(WAVEOPENDESC));
 
 	        dwRet = wodMessage(wDevID, WODM_CLOSE, 0, 0L, 0L);
 	        if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
-	        dwRet = widMessage(wDevID, WIDM_OPEN, 0, (DWORD)lpDesc, CALLBACK_NULL);
+	        dwRet = widMessage(wDevID, WIDM_OPEN, 0, (DWORD)&waveDesc, CALLBACK_NULL);
 		MCIWavDev[wDevID].fInput = TRUE;
 	}
 	else if (MCIWavDev[wDevID].fInput) {
 /* FIXME this is just a hack WInDev should be hidden here */
-	        memcpy(lpDesc,&WInDev[wDevID].waveDesc,sizeof(WAVEOPENDESC));
+	        memcpy(&waveDesc,&WInDev[wDevID].waveDesc,sizeof(WAVEOPENDESC));
 
 	        dwRet = widMessage(wDevID, WIDM_CLOSE, 0, 0L, 0L);
 	        if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
-	        dwRet = wodMessage(wDevID, WODM_OPEN, 0, (DWORD)lpDesc, CALLBACK_NULL);
+	        dwRet = wodMessage(wDevID, WODM_OPEN, 0, (DWORD)&waveDesc, CALLBACK_NULL);
 		MCIWavDev[wDevID].fInput = FALSE;
 	}
-
-	USER_HEAP_FREE(hDesc);
-
         return dwRet;
 }
 
 /**************************************************************************
-* 				WAVE_mciClose		[internal]
-*/
+ *				WAVE_mciClose		[internal]
+ */
 static DWORD WAVE_mciClose(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
 {
 	DWORD		dwRet;
@@ -340,17 +320,15 @@
 
 
 /**************************************************************************
-* 				WAVE_mciPlay		[internal]
-*/
+ * 				WAVE_mciPlay		[internal]
+ */
 static DWORD WAVE_mciPlay(UINT16 wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
 {
-	int				start, end;
-	LONG			bufsize, count;
-	HGLOBAL16		hData;
-	HLOCAL16		hWaveHdr;
-	LPWAVEHDR		lpWaveHdr;
-	SEGPTR  		lp16WaveHdr;
-	DWORD			dwRet;
+	int		start, end;
+	LONG		bufsize, count;
+	HGLOBAL16	hData;
+	LPWAVEHDR	lpWaveHdr;
+	DWORD		dwRet;
 
 	dprintf_mciwave(stddeb,
 		 "WAVE_mciPlay(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
@@ -370,11 +348,11 @@
 		start = lpParms->dwFrom; 
 		dprintf_mciwave(stddeb,
 				"WAVE_mciPlay // MCI_FROM=%d \n", start);
-		}
+	}
 	if (dwFlags & MCI_TO) {
 		end = lpParms->dwTo;
 		dprintf_mciwave(stddeb,"WAVE_mciPlay // MCI_TO=%d \n", end);
-		}
+	}
 #if 0
 	if (dwFlags & MCI_NOTIFY) {
         dprintf_mciwave(stddeb,
@@ -395,53 +373,45 @@
 	bufsize = 64000;
 	lpWaveHdr = &MCIWavDev[wDevID].WaveHdr;
 	hData = GlobalAlloc16(GMEM_MOVEABLE, bufsize);
-	lpWaveHdr->lpData = (LPSTR) WIN16_GlobalLock16(hData);
+	lpWaveHdr->lpData = (LPSTR) GlobalLock16(hData);
 	lpWaveHdr->dwUser = 0L;
 	lpWaveHdr->dwFlags = 0L;
 	lpWaveHdr->dwLoops = 0L;
-	hWaveHdr = USER_HEAP_ALLOC(sizeof(WAVEHDR));
-	lp16WaveHdr = 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, lp16WaveHdr, sizeof(WAVEHDR));
+	dwRet=wodMessage(wDevID,WODM_PREPARE,0,(DWORD)lpWaveHdr,sizeof(WAVEHDR));
 	while(TRUE) {
-		count = mmioRead(MCIWavDev[wDevID].hFile, 
-			PTR_SEG_TO_LIN(lpWaveHdr->lpData), bufsize);
+		count = mmioRead(MCIWavDev[wDevID].hFile, lpWaveHdr->lpData, bufsize);
 		dprintf_mciwave(stddeb,"WAVE_mciPlay // mmioRead bufsize=%ld count=%ld\n", bufsize, count);
 		if (count < 1) break;
 		lpWaveHdr->dwBufferLength = count;
 /*		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, lp16WaveHdr, sizeof(WAVEHDR));
-		}
-	dwRet = wodMessage(wDevID, WODM_UNPREPARE, 0, lp16WaveHdr, sizeof(WAVEHDR));
+		dwRet=wodMessage(wDevID,WODM_WRITE,0,(DWORD)lpWaveHdr,sizeof(WAVEHDR));
+	}
+	dwRet = wodMessage(wDevID,WODM_UNPREPARE,0,(DWORD)lpWaveHdr,sizeof(WAVEHDR));
 	if (lpWaveHdr->lpData != NULL) {
 		GlobalUnlock16(hData);
 		GlobalFree16(hData);
 		lpWaveHdr->lpData = NULL;
-		}
-	USER_HEAP_FREE(hWaveHdr);
+	}
 	if (dwFlags & MCI_NOTIFY) {
 		dprintf_mciwave(stddeb,"WAVE_mciPlay // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
 		mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback), 
 			MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
-		}
+	}
 	return 0;
 }
 
 
 /**************************************************************************
-* 				WAVE_mciRecord			[internal]
-*/
+ * 				WAVE_mciRecord			[internal]
+ */
 static DWORD WAVE_mciRecord(UINT16 wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms)
 {
 	int		       	start, end;
 	LONG			bufsize;
 	HGLOBAL16		hData;
-	HLOCAL16		hWaveHdr;
 	LPWAVEHDR		lpWaveHdr;
-	SEGPTR   		lp16WaveHdr;
 	DWORD			dwRet;
 
 	dprintf_mciwave(stddeb,
@@ -457,30 +427,26 @@
 				MCIWavDev[wDevID].openParms.lpstrElementName);
 		return MCIERR_FILE_NOT_FOUND;
 	}
-	start = 1; 		end = 99999;
+	start = 1; 	end = 99999;
 	if (dwFlags & MCI_FROM) {
 		start = lpParms->dwFrom; 
 		dprintf_mciwave(stddeb,
 				"WAVE_mciRecord // MCI_FROM=%d \n", start);
-		}
+	}
 	if (dwFlags & MCI_TO) {
 		end = lpParms->dwTo;
 		dprintf_mciwave(stddeb,"WAVE_mciRecord // MCI_TO=%d \n", end);
-		}
+	}
 	bufsize = 64000;
 	lpWaveHdr = &MCIWavDev[wDevID].WaveHdr;
 	hData = GlobalAlloc16(GMEM_MOVEABLE, bufsize);
-	lpWaveHdr->lpData = (LPSTR) WIN16_GlobalLock16(hData);
+	lpWaveHdr->lpData = (LPSTR)GlobalLock16(hData);
 	lpWaveHdr->dwBufferLength = bufsize;
 	lpWaveHdr->dwUser = 0L;
 	lpWaveHdr->dwFlags = 0L;
 	lpWaveHdr->dwLoops = 0L;
-	hWaveHdr = USER_HEAP_ALLOC(sizeof(WAVEHDR));
-	lp16WaveHdr = 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));
-    dprintf_mciwave(stddeb,"WAVE_mciRecord // after WIDM_PREPARE \n");
+	dwRet=widMessage(wDevID,WIDM_PREPARE,0,(DWORD)lpWaveHdr,sizeof(WAVEHDR));
+	dprintf_mciwave(stddeb,"WAVE_mciRecord // after WIDM_PREPARE \n");
 	while(TRUE) {
 		lpWaveHdr->dwBytesRecorded = 0;
 		dwRet = widMessage(wDevID, WIDM_START, 0, 0L, 0L);
@@ -488,28 +454,27 @@
                     "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(wDevID,WIDM_UNPREPARE,0,(DWORD)lpWaveHdr,sizeof(WAVEHDR));
 	dprintf_mciwave(stddeb,"WAVE_mciRecord // after WIDM_UNPREPARE \n");
 	if (lpWaveHdr->lpData != NULL) {
 		GlobalUnlock16(hData);
 		GlobalFree16(hData);
 		lpWaveHdr->lpData = NULL;
-		}
-	USER_HEAP_FREE(hWaveHdr);
+	}
 	if (dwFlags & MCI_NOTIFY) {
 	  dprintf_mciwave(stddeb,"WAVE_mciRecord // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
 		mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback), 
 			MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
-		}
+	}
 	return 0;
 }
 
 
 /**************************************************************************
-* 				WAVE_mciStop			[internal]
-*/
+ * 				WAVE_mciStop			[internal]
+ */
 static DWORD WAVE_mciStop(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
         DWORD dwRet;
@@ -527,8 +492,8 @@
 
 
 /**************************************************************************
-* 				WAVE_mciPause			[internal]
-*/
+ * 				WAVE_mciPause			[internal]
+ */
 static DWORD WAVE_mciPause(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
         DWORD dwRet;
@@ -546,8 +511,8 @@
 
 
 /**************************************************************************
-* 				WAVE_mciResume			[internal]
-*/
+ * 				WAVE_mciResume			[internal]
+ */
 static DWORD WAVE_mciResume(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
 	dprintf_mciwave(stddeb,
@@ -558,8 +523,8 @@
 
 
 /**************************************************************************
-* 				WAVE_mciSet			[internal]
-*/
+ * 				WAVE_mciSet			[internal]
+ */
 static DWORD WAVE_mciSet(UINT16 wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
 {
 	dprintf_mciwave(stddeb,
@@ -571,20 +536,20 @@
 		 "WAVE_mciSet // dwAudio=%08lX\n", lpParms->dwAudio);
 	if (dwFlags & MCI_SET_TIME_FORMAT) {
 		switch (lpParms->dwTimeFormat) {
-			case MCI_FORMAT_MILLISECONDS:
-				dprintf_mciwave(stddeb,	"WAVE_mciSet // MCI_FORMAT_MILLISECONDS !\n");
-				break;
-			case MCI_FORMAT_BYTES:
-				dprintf_mciwave(stddeb, "WAVE_mciSet // MCI_FORMAT_BYTES !\n");
-				break;
-			case MCI_FORMAT_SAMPLES:
-				dprintf_mciwave(stddeb,	"WAVE_mciSet // MCI_FORMAT_SAMPLES !\n");
-				break;
-			default:
-				dprintf_mciwave(stddeb,	"WAVE_mciSet // bad time format !\n");
-				return MCIERR_BAD_TIME_FORMAT;
-			}
+		case MCI_FORMAT_MILLISECONDS:
+			dprintf_mciwave(stddeb,	"WAVE_mciSet // MCI_FORMAT_MILLISECONDS !\n");
+			break;
+		case MCI_FORMAT_BYTES:
+			dprintf_mciwave(stddeb, "WAVE_mciSet // MCI_FORMAT_BYTES !\n");
+			break;
+		case MCI_FORMAT_SAMPLES:
+			dprintf_mciwave(stddeb,	"WAVE_mciSet // MCI_FORMAT_SAMPLES !\n");
+			break;
+		default:
+			dprintf_mciwave(stddeb,	"WAVE_mciSet // bad time format !\n");
+			return MCIERR_BAD_TIME_FORMAT;
 		}
+	}
 	if (dwFlags & MCI_SET_VIDEO) return MCIERR_UNSUPPORTED_FUNCTION;
 	if (dwFlags & MCI_SET_DOOR_OPEN) return MCIERR_UNSUPPORTED_FUNCTION;
 	if (dwFlags & MCI_SET_DOOR_CLOSED) return MCIERR_UNSUPPORTED_FUNCTION;
@@ -627,8 +592,8 @@
 
 
 /**************************************************************************
-* 				WAVE_mciStatus		[internal]
-*/
+ * 				WAVE_mciStatus		[internal]
+ */
 static DWORD WAVE_mciStatus(UINT16 wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
 {
 	dprintf_mciwave(stddeb,
@@ -636,96 +601,95 @@
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	if (dwFlags & MCI_STATUS_ITEM) {
 		switch(lpParms->dwItem) {
-			case MCI_STATUS_CURRENT_TRACK:
-				lpParms->dwReturn = 1;
-				break;
-			case MCI_STATUS_LENGTH:
-				lpParms->dwReturn = 5555;
-				if (dwFlags & MCI_TRACK) {
-					lpParms->dwTrack = 1;
-					lpParms->dwReturn = 2222;
-					}
-				break;
-			case MCI_STATUS_MODE:
-				lpParms->dwReturn = MCI_MODE_STOP;
-				break;
-			case MCI_STATUS_MEDIA_PRESENT:
-				dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_STATUS_MEDIA_PRESENT !\n");
-				lpParms->dwReturn = TRUE;
-				break;
-			case MCI_STATUS_NUMBER_OF_TRACKS:
-				lpParms->dwReturn = 1;
-				break;
-			case MCI_STATUS_POSITION:
-				lpParms->dwReturn = 3333;
-				if (dwFlags & MCI_STATUS_START) {
-					lpParms->dwItem = 1;
-					}
-				if (dwFlags & MCI_TRACK) {
-					lpParms->dwTrack = 1;
-					lpParms->dwReturn = 777;
-					}
-				break;
-			case MCI_STATUS_READY:
-				dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_STATUS_READY !\n");
-				lpParms->dwReturn = TRUE;
-				break;
-			case MCI_STATUS_TIME_FORMAT:
-				dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_STATUS_TIME_FORMAT !\n");
-				lpParms->dwReturn = MCI_FORMAT_MILLISECONDS;
-				break;
-			case MCI_WAVE_INPUT:
-				dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_INPUT !\n");
-				lpParms->dwReturn = 0;
-				break;
-			case MCI_WAVE_OUTPUT:
-				dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_OUTPUT !\n");
-				lpParms->dwReturn = 0;
-				break;
-			case MCI_WAVE_STATUS_AVGBYTESPERSEC:
-				dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_AVGBYTESPERSEC !\n");
-				lpParms->dwReturn = 22050;
-				break;
-			case MCI_WAVE_STATUS_BITSPERSAMPLE:
-				dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_BITSPERSAMPLE !\n");
-				lpParms->dwReturn = 8;
-				break;
-			case MCI_WAVE_STATUS_BLOCKALIGN:
-				dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_BLOCKALIGN !\n");
-				lpParms->dwReturn = 1;
-				break;
-			case MCI_WAVE_STATUS_CHANNELS:
-				dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_CHANNELS !\n");
-				lpParms->dwReturn = 1;
-				break;
-			case MCI_WAVE_STATUS_FORMATTAG:
-				dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_FORMATTAG !\n");
-				lpParms->dwReturn = WAVE_FORMAT_PCM;
-				break;
-			case MCI_WAVE_STATUS_LEVEL:
-				dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_LEVEL !\n");
-				lpParms->dwReturn = 0xAAAA5555;
-				break;
-			case MCI_WAVE_STATUS_SAMPLESPERSEC:
-				dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_SAMPLESPERSEC !\n");
-				lpParms->dwReturn = 22050;
-				break;
-			default:
-				dprintf_mciwave(stddeb,"WAVE_mciStatus // unknown command %08lX !\n", lpParms->dwItem);
-				return MCIERR_UNRECOGNIZED_COMMAND;
+		case MCI_STATUS_CURRENT_TRACK:
+			lpParms->dwReturn = 1;
+			break;
+		case MCI_STATUS_LENGTH:
+			lpParms->dwReturn = 5555;
+			if (dwFlags & MCI_TRACK) {
+				lpParms->dwTrack = 1;
+				lpParms->dwReturn = 2222;
+				}
+			break;
+		case MCI_STATUS_MODE:
+			lpParms->dwReturn = MCI_MODE_STOP;
+			break;
+		case MCI_STATUS_MEDIA_PRESENT:
+			dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_STATUS_MEDIA_PRESENT !\n");
+			lpParms->dwReturn = TRUE;
+			break;
+		case MCI_STATUS_NUMBER_OF_TRACKS:
+			lpParms->dwReturn = 1;
+			break;
+		case MCI_STATUS_POSITION:
+			lpParms->dwReturn = 3333;
+			if (dwFlags & MCI_STATUS_START)
+				lpParms->dwItem = 1;
+			if (dwFlags & MCI_TRACK) {
+				lpParms->dwTrack = 1;
+				lpParms->dwReturn = 777;
 			}
+			break;
+		case MCI_STATUS_READY:
+			dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_STATUS_READY !\n");
+			lpParms->dwReturn = TRUE;
+			break;
+		case MCI_STATUS_TIME_FORMAT:
+			dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_STATUS_TIME_FORMAT !\n");
+			lpParms->dwReturn = MCI_FORMAT_MILLISECONDS;
+			break;
+		case MCI_WAVE_INPUT:
+			dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_INPUT !\n");
+			lpParms->dwReturn = 0;
+			break;
+		case MCI_WAVE_OUTPUT:
+			dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_OUTPUT !\n");
+			lpParms->dwReturn = 0;
+			break;
+		case MCI_WAVE_STATUS_AVGBYTESPERSEC:
+			dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_AVGBYTESPERSEC !\n");
+			lpParms->dwReturn = 22050;
+			break;
+		case MCI_WAVE_STATUS_BITSPERSAMPLE:
+			dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_BITSPERSAMPLE !\n");
+			lpParms->dwReturn = 8;
+			break;
+		case MCI_WAVE_STATUS_BLOCKALIGN:
+			dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_BLOCKALIGN !\n");
+			lpParms->dwReturn = 1;
+			break;
+		case MCI_WAVE_STATUS_CHANNELS:
+			dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_CHANNELS !\n");
+			lpParms->dwReturn = 1;
+			break;
+		case MCI_WAVE_STATUS_FORMATTAG:
+			dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_FORMATTAG !\n");
+			lpParms->dwReturn = WAVE_FORMAT_PCM;
+			break;
+		case MCI_WAVE_STATUS_LEVEL:
+			dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_LEVEL !\n");
+			lpParms->dwReturn = 0xAAAA5555;
+			break;
+		case MCI_WAVE_STATUS_SAMPLESPERSEC:
+			dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_SAMPLESPERSEC !\n");
+			lpParms->dwReturn = 22050;
+			break;
+		default:
+			dprintf_mciwave(stddeb,"WAVE_mciStatus // unknown command %08lX !\n", lpParms->dwItem);
+			return MCIERR_UNRECOGNIZED_COMMAND;
 		}
+	}
 	if (dwFlags & MCI_NOTIFY) {
 		dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
 		mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback), 
 			MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
-		}
+	}
  	return 0;
 }
 
 /**************************************************************************
-* 				WAVE_mciGetDevCaps		[internal]
-*/
+ * 				WAVE_mciGetDevCaps		[internal]
+ */
 static DWORD WAVE_mciGetDevCaps(UINT16 wDevID, DWORD dwFlags, 
 					LPMCI_GETDEVCAPS_PARMS lpParms)
 {
@@ -734,72 +698,72 @@
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	if (dwFlags & MCI_GETDEVCAPS_ITEM) {
 		switch(lpParms->dwItem) {
-			case MCI_GETDEVCAPS_CAN_RECORD:
-				lpParms->dwReturn = TRUE;
-				break;
-			case MCI_GETDEVCAPS_HAS_AUDIO:
-				lpParms->dwReturn = TRUE;
-				break;
-			case MCI_GETDEVCAPS_HAS_VIDEO:
-				lpParms->dwReturn = FALSE;
-				break;
-			case MCI_GETDEVCAPS_DEVICE_TYPE:
-				lpParms->dwReturn = MCI_DEVTYPE_WAVEFORM_AUDIO;
-				break;
-			case MCI_GETDEVCAPS_USES_FILES:
-				lpParms->dwReturn = TRUE;
-				break;
-			case MCI_GETDEVCAPS_COMPOUND_DEVICE:
-				lpParms->dwReturn = TRUE;
-				break;
-			case MCI_GETDEVCAPS_CAN_EJECT:
-				lpParms->dwReturn = FALSE;
-				break;
-			case MCI_GETDEVCAPS_CAN_PLAY:
-				lpParms->dwReturn = TRUE;
-				break;
-			case MCI_GETDEVCAPS_CAN_SAVE:
-				lpParms->dwReturn = TRUE;
-				break;
-			case MCI_WAVE_GETDEVCAPS_INPUTS:
-				lpParms->dwReturn = 1;
-				break;
-			case MCI_WAVE_GETDEVCAPS_OUTPUTS:
-				lpParms->dwReturn = 1;
-				break;
-			default:
-				return MCIERR_UNRECOGNIZED_COMMAND;
-			}
+		case MCI_GETDEVCAPS_CAN_RECORD:
+			lpParms->dwReturn = TRUE;
+			break;
+		case MCI_GETDEVCAPS_HAS_AUDIO:
+			lpParms->dwReturn = TRUE;
+			break;
+		case MCI_GETDEVCAPS_HAS_VIDEO:
+			lpParms->dwReturn = FALSE;
+			break;
+		case MCI_GETDEVCAPS_DEVICE_TYPE:
+			lpParms->dwReturn = MCI_DEVTYPE_WAVEFORM_AUDIO;
+			break;
+		case MCI_GETDEVCAPS_USES_FILES:
+			lpParms->dwReturn = TRUE;
+			break;
+		case MCI_GETDEVCAPS_COMPOUND_DEVICE:
+			lpParms->dwReturn = TRUE;
+			break;
+		case MCI_GETDEVCAPS_CAN_EJECT:
+			lpParms->dwReturn = FALSE;
+			break;
+		case MCI_GETDEVCAPS_CAN_PLAY:
+			lpParms->dwReturn = TRUE;
+			break;
+		case MCI_GETDEVCAPS_CAN_SAVE:
+			lpParms->dwReturn = TRUE;
+			break;
+		case MCI_WAVE_GETDEVCAPS_INPUTS:
+			lpParms->dwReturn = 1;
+			break;
+		case MCI_WAVE_GETDEVCAPS_OUTPUTS:
+			lpParms->dwReturn = 1;
+			break;
+		default:
+			return MCIERR_UNRECOGNIZED_COMMAND;
 		}
+	}
  	return 0;
 }
 
 /**************************************************************************
-* 				WAVE_mciInfo			[internal]
-*/
-static DWORD WAVE_mciInfo(UINT16 wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms)
+ * 				WAVE_mciInfo			[internal]
+ */
+static DWORD WAVE_mciInfo(UINT16 wDevID, DWORD dwFlags, LPMCI_INFO_PARMS16 lpParms)
 {
 	dprintf_mciwave(stddeb,
 		"WAVE_mciInfo(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	lpParms->lpstrReturn = NULL;
 	switch(dwFlags) {
-		case MCI_INFO_PRODUCT:
-			lpParms->lpstrReturn = "Linux Sound System 0.5";
-			break;
-		case MCI_INFO_FILE:
-			lpParms->lpstrReturn = 
-				(LPSTR)MCIWavDev[wDevID].openParms.lpstrElementName;
-			break;
-		case MCI_WAVE_INPUT:
-			lpParms->lpstrReturn = "Linux Sound System 0.5";
-			break;
-		case MCI_WAVE_OUTPUT:
-			lpParms->lpstrReturn = "Linux Sound System 0.5";
-			break;
-		default:
-			return MCIERR_UNRECOGNIZED_COMMAND;
-		}
+	case MCI_INFO_PRODUCT:
+		lpParms->lpstrReturn = "Linux Sound System 0.5";
+		break;
+	case MCI_INFO_FILE:
+		lpParms->lpstrReturn = 
+			(LPSTR)MCIWavDev[wDevID].openParms.lpstrElementName;
+		break;
+	case MCI_WAVE_INPUT:
+		lpParms->lpstrReturn = "Linux Sound System 0.5";
+		break;
+	case MCI_WAVE_OUTPUT:
+		lpParms->lpstrReturn = "Linux Sound System 0.5";
+		break;
+	default:
+		return MCIERR_UNRECOGNIZED_COMMAND;
+	}
 	if (lpParms->lpstrReturn != NULL)
 		lpParms->dwRetSize = strlen(lpParms->lpstrReturn);
 	else
@@ -812,15 +776,16 @@
 
 
 /**************************************************************************
-* 				wodGetDevCaps				[internal]
-*/
-static DWORD wodGetDevCaps(WORD wDevID, LPWAVEOUTCAPS lpCaps, DWORD dwSize)
+ * 			wodGetDevCaps				[internal]
+ */
+static DWORD wodGetDevCaps(WORD wDevID, LPWAVEOUTCAPS16 lpCaps, DWORD dwSize)
 {
 	int 	audio;
-	int		smplrate;
-	int		samplesize = 16;
-	int		dsp_stereo = 1;
-	int		bytespersmpl;
+	int	smplrate;
+	int	samplesize = 16;
+	int	dsp_stereo = 1;
+	int	bytespersmpl;
+
 	dprintf_mciwave(stddeb,
 		   "wodGetDevCaps(%u, %p, %lu);\n", wDevID, lpCaps, dwSize);
 	if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
@@ -845,30 +810,36 @@
 	smplrate = 44100;
 	if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
 		lpCaps->dwFormats |= WAVE_FORMAT_4M08;
-		if (lpCaps->wChannels > 1)	lpCaps->dwFormats |= WAVE_FORMAT_4S08;
+		if (lpCaps->wChannels > 1)
+			lpCaps->dwFormats |= WAVE_FORMAT_4S08;
 		if (bytespersmpl > 1) {
 			lpCaps->dwFormats |= WAVE_FORMAT_4M16;
-			if (lpCaps->wChannels > 1)	lpCaps->dwFormats |= WAVE_FORMAT_4S16;
-			}
+			if (lpCaps->wChannels > 1)
+				lpCaps->dwFormats |= WAVE_FORMAT_4S16;
 		}
+	}
 	smplrate = 22050;
 	if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
 		lpCaps->dwFormats |= WAVE_FORMAT_2M08;
-		if (lpCaps->wChannels > 1)	lpCaps->dwFormats |= WAVE_FORMAT_2S08;
+		if (lpCaps->wChannels > 1)
+			lpCaps->dwFormats |= WAVE_FORMAT_2S08;
 		if (bytespersmpl > 1) {
 			lpCaps->dwFormats |= WAVE_FORMAT_2M16;
-			if (lpCaps->wChannels > 1)	lpCaps->dwFormats |= WAVE_FORMAT_2S16;
-			}
+			if (lpCaps->wChannels > 1)
+				lpCaps->dwFormats |= WAVE_FORMAT_2S16;
 		}
+	}
 	smplrate = 11025;
 	if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
 		lpCaps->dwFormats |= WAVE_FORMAT_1M08;
-		if (lpCaps->wChannels > 1)	lpCaps->dwFormats |= WAVE_FORMAT_1S08;
+		if (lpCaps->wChannels > 1)
+			lpCaps->dwFormats |= WAVE_FORMAT_1S08;
 		if (bytespersmpl > 1) {
 			lpCaps->dwFormats |= WAVE_FORMAT_1M16;
-			if (lpCaps->wChannels > 1)	lpCaps->dwFormats |= WAVE_FORMAT_1S16;
-			}
+			if (lpCaps->wChannels > 1)
+				lpCaps->dwFormats |= WAVE_FORMAT_1S16;
 		}
+	}
 	close(audio);
 	dprintf_mciwave(stddeb,
 		"wodGetDevCaps // dwFormats = %08lX\n", lpCaps->dwFormats);
@@ -877,34 +848,30 @@
 
 
 /**************************************************************************
-* 				wodOpen				[internal]
-*/
+ * 				wodOpen				[internal]
+ */
 static DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
 {
-	int 		audio;
-	int			abuf_size;
-	int			smplrate;
-	int			samplesize;
-	int			dsp_stereo;
-	LPWAVEFORMAT lpFormat;
+	int 	 audio,abuf_size,smplrate,samplesize,dsp_stereo;
+	LPWAVEFORMAT	lpFormat;
 
 	dprintf_mciwave(stddeb,
 		"wodOpen(%u, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
 	if (lpDesc == NULL) {
 		dprintf_mciwave(stddeb,"Linux 'wodOpen' // Invalid Parameter !\n");
 		return MMSYSERR_INVALPARAM;
-		}
+	}
 	if (wDevID >= MAX_WAVOUTDRV) {
 		dprintf_mciwave(stddeb,"Linux 'wodOpen' // MAX_WAVOUTDRV reached !\n");
 		return MMSYSERR_ALLOCATED;
-		}
+	}
 	WOutDev[wDevID].unixdev = 0;
 	if (access(SOUND_DEV,0) != 0) return MMSYSERR_NOTENABLED;
 	audio = open (SOUND_DEV, O_WRONLY, 0);
 	if (audio == -1) {
 		dprintf_mciwave(stddeb,"Linux 'wodOpen' // can't open !\n");
 		return MMSYSERR_ALLOCATED ;
-		}
+	}
 	IOCTL(audio, SNDCTL_DSP_GETBLKSIZE, abuf_size);
 	if (abuf_size < 1024 || abuf_size > 65536) {
 		if (abuf_size == -1)
@@ -912,29 +879,30 @@
 		else
 			dprintf_mciwave(stddeb,"Linux 'wodOpen' // SNDCTL_DSP_GETBLKSIZE Invalid bufsize !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
 	WOutDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
 	switch(WOutDev[wDevID].wFlags) {
-		case DCB_NULL:
-			dprintf_mciwave(stddeb,	"Linux 'wodOpen' // CALLBACK_NULL !\n");
-			break;
-		case DCB_WINDOW:
-			dprintf_mciwave(stddeb,	"Linux 'wodOpen' // CALLBACK_WINDOW !\n");
-			break;
-		case DCB_TASK:
-			dprintf_mciwave(stddeb,	"Linux 'wodOpen' // CALLBACK_TASK !\n");
-			break;
-		case DCB_FUNCTION:
-			dprintf_mciwave(stddeb,	"Linux 'wodOpen' // CALLBACK_FUNCTION !\n");
-			break;
-		}
-	WOutDev[wDevID].lp16QueueHdr = NULL;
+	case DCB_NULL:
+		dprintf_mciwave(stddeb,	"Linux 'wodOpen' // CALLBACK_NULL !\n");
+		break;
+	case DCB_WINDOW:
+		dprintf_mciwave(stddeb,	"Linux 'wodOpen' // CALLBACK_WINDOW !\n");
+		break;
+	case DCB_TASK:
+		dprintf_mciwave(stddeb,	"Linux 'wodOpen' // CALLBACK_TASK !\n");
+		break;
+	case DCB_FUNCTION:
+		dprintf_mciwave(stddeb,	"Linux 'wodOpen' // CALLBACK_FUNCTION !\n");
+		break;
+	}
+	WOutDev[wDevID].lpQueueHdr = NULL;
 	WOutDev[wDevID].unixdev = audio;
 	WOutDev[wDevID].dwTotalPlayed = 0;
 	WOutDev[wDevID].bufsize = abuf_size;
+	/* FIXME: copy lpFormat too? */
 	memcpy(&WOutDev[wDevID].waveDesc, lpDesc, sizeof(WAVEOPENDESC));
 	dprintf_mciwave(stddeb,"Linux 'wodOpen' // lpDesc->lpFormat = %p\n",lpDesc->lpFormat);
-        lpFormat = (LPWAVEFORMAT) PTR_SEG_TO_LIN(lpDesc->lpFormat); 
+        lpFormat = lpDesc->lpFormat; 
 	dprintf_mciwave(stddeb,"Linux 'wodOpen' // lpFormat = %p\n",lpFormat);
 	if (lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
 		dprintf_mciwave(stddeb,"Linux 'wodOpen' // Bad format %04X !\n",
@@ -944,7 +912,7 @@
 		dprintf_mciwave(stddeb,"Linux 'wodOpen' // Bad nSamplesPerSec %ld !\n",
 				lpFormat->nSamplesPerSec);
 		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;
@@ -955,7 +923,7 @@
 		(WOutDev[wDevID].Format.wf.nAvgBytesPerSec /
 		WOutDev[wDevID].Format.wf.nSamplesPerSec) /
 		WOutDev[wDevID].Format.wf.nChannels;
-		}
+	}
 	samplesize = WOutDev[wDevID].Format.wBitsPerSample;
 	smplrate = WOutDev[wDevID].Format.wf.nSamplesPerSec;
 	dsp_stereo = (WOutDev[wDevID].Format.wf.nChannels > 1) ? TRUE : FALSE;
@@ -973,13 +941,13 @@
 	if (WAVE_NotifyClient(wDevID, WOM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
 		dprintf_mciwave(stddeb,"Linux 'wodOpen' // can't notify client !\n");
 		return MMSYSERR_INVALPARAM;
-		}
+	}
 	return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
-* 				wodClose			[internal]
-*/
+ * 				wodClose			[internal]
+ */
 static DWORD wodClose(WORD wDevID)
 {
 	dprintf_mciwave(stddeb,"wodClose(%u);\n", wDevID);
@@ -987,15 +955,16 @@
 	if (WOutDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'wodClose' // can't close !\n");
 		return MMSYSERR_NOTENABLED;
-		}
-	if (WOutDev[wDevID].lp16QueueHdr != NULL) {
+	}
+	if (WOutDev[wDevID].lpQueueHdr != NULL) {
 	        dprintf_mciwave(stddeb,"linux 'wodclose' // still buffers open !\n");
-		return WAVERR_STILLPLAYING;
+		/* Don't care. Who needs those buffers anyway */
+		/*return WAVERR_STILLPLAYING; */
 	}
 	close(WOutDev[wDevID].unixdev);
 	WOutDev[wDevID].unixdev = 0;
 	WOutDev[wDevID].bufsize = 0;
-	WOutDev[wDevID].lp16QueueHdr = NULL;
+	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;
@@ -1004,19 +973,21 @@
 }
 
 /**************************************************************************
-* 				wodWrite			[internal]
-*/
-static DWORD wodWrite(WORD wDevID, SEGPTR lp16WaveHdr, DWORD dwSize)
+ * 				wodWrite			[internal]
+ * FIXME: this should _APPEND_ the lpWaveHdr to the output queue of the
+ * device, and initiate async playing.
+ */
+static DWORD wodWrite(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
 	int		count;
 	LPSTR	        lpData;
-	LPWAVEHDR       lpWaveHdr = (LPWAVEHDR)PTR_SEG_TO_LIN(lp16WaveHdr);
+	LPWAVEHDR	xwavehdr;
 
 	dprintf_mciwave(stddeb,"wodWrite(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
 	if (WOutDev[wDevID].unixdev == 0) {
         dprintf_mciwave(stddeb,"Linux 'wodWrite' // can't play !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
 	if (lpWaveHdr->lpData == NULL) return WAVERR_UNPREPARED;
 	if (!(lpWaveHdr->dwFlags & WHDR_PREPARED)) return WAVERR_UNPREPARED;
 	if (lpWaveHdr->dwFlags & WHDR_INQUEUE) return WAVERR_STILLPLAYING;
@@ -1026,58 +997,59 @@
 		"wodWrite() // dwBufferLength %lu !\n", lpWaveHdr->dwBufferLength);
 	dprintf_mciwave(stddeb,
 		"wodWrite() // WOutDev[%u].unixdev %u !\n", wDevID, WOutDev[wDevID].unixdev);
-	lpData = PTR_SEG_TO_LIN(lpWaveHdr->lpData);
+	lpData = lpWaveHdr->lpData;
 	count = write (WOutDev[wDevID].unixdev, lpData, lpWaveHdr->dwBufferLength);
-	dprintf_mciwave(stddeb,
-		"wodWrite() // write returned count %u !\n", count);
+	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[wDevID].dwTotalPlayed += count;
 	lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
 	lpWaveHdr->dwFlags |= WHDR_DONE;
-	if (WAVE_NotifyClient(wDevID, WOM_DONE, lp16WaveHdr, count) != MMSYSERR_NOERROR) {
-		dprintf_mciwave(stddeb,"Linux 'wodWrite' // can't notify client !\n");
-		return MMSYSERR_INVALPARAM;
+	if ((DWORD)lpWaveHdr->lpData!=lpWaveHdr->reserved) {
+		/* FIXME: what if it expects it's OWN lpwavehdr back? */
+		xwavehdr = SEGPTR_NEW(WAVEHDR);
+		memcpy(xwavehdr,lpWaveHdr,sizeof(WAVEHDR));
+		xwavehdr->lpData = (LPBYTE)xwavehdr->reserved;
+		if (WAVE_NotifyClient(wDevID, WOM_DONE, (DWORD)SEGPTR_GET(xwavehdr), count) != MMSYSERR_NOERROR) {
+			dprintf_mciwave(stddeb,"Linux 'wodWrite' // can't notify client !\n");
+			SEGPTR_FREE(xwavehdr);
+			return MMSYSERR_INVALPARAM;
 		}
+		SEGPTR_FREE(xwavehdr);
+	} else {
+		if (WAVE_NotifyClient(wDevID, WOM_DONE, (DWORD)lpWaveHdr, count) != MMSYSERR_NOERROR) {
+			dprintf_mciwave(stddeb,"Linux 'wodWrite' // can't notify client !\n");
+			return MMSYSERR_INVALPARAM;
+		}
+	}
 	return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
-* 				wodPrepare			[internal]
-*/
-static DWORD wodPrepare(WORD wDevID, SEGPTR lp16WaveHdr, DWORD dwSize)
+ * 				wodPrepare			[internal]
+ */
+static DWORD wodPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
-        LPWAVEHDR lpWaveHdr;
-
 	dprintf_mciwave(stddeb,
-		"wodPrepare(%u, %p, %08lX);\n", wDevID, (void *)lp16WaveHdr, dwSize);
+		"wodPrepare(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
 	if (WOutDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'wodPrepare' // can't prepare !\n");
 		return MMSYSERR_NOTENABLED;
-		}
-
-	lpWaveHdr = PTR_SEG_TO_LIN(lp16WaveHdr);
-
-	/* the COOL waveeditor feels much better without this check... 
-	 * someone please have a look at available documentation
-	if (WOutDev[wDevID].lpQueueHdr != NULL) {
-		dprintf_mciwave(stddeb,"Linux 'wodPrepare' // already prepare !\n");
-		return MMSYSERR_NOTENABLED;
 	}
-	*/
+	/* don't append to queue, wodWrite does that */
 	WOutDev[wDevID].dwTotalPlayed = 0;
-	WOutDev[wDevID].lp16QueueHdr = lp16WaveHdr;
-	if (lpWaveHdr->dwFlags & WHDR_INQUEUE) return WAVERR_STILLPLAYING;
+	if (lpWaveHdr->dwFlags & WHDR_INQUEUE)
+		return WAVERR_STILLPLAYING;
 	lpWaveHdr->dwFlags |= WHDR_PREPARED;
 	lpWaveHdr->dwFlags &= ~WHDR_DONE;
 	return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
-* 				wodUnprepare			[internal]
-*/
+ * 				wodUnprepare			[internal]
+ */
 static DWORD wodUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
 	dprintf_mciwave(stddeb,
@@ -1085,20 +1057,20 @@
 	if (WOutDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'wodUnprepare' // can't unprepare !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
+	if (lpWaveHdr->dwFlags & WHDR_INQUEUE)
+		return WAVERR_STILLPLAYING;
 	
 	lpWaveHdr->dwFlags &= ~WHDR_PREPARED;
-	lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
 	lpWaveHdr->dwFlags |= WHDR_DONE;
-	WOutDev[wDevID].lp16QueueHdr = NULL;
 	dprintf_mciwave(stddeb,
 		"Linux 'wodUnprepare' // all headers unprepared !\n");
 	return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
-* 				wodRestart				[internal]
-*/
+ * 			wodRestart				[internal]
+ */
 static DWORD wodRestart(WORD wDevID)
 {
 	dprintf_mciwave(stddeb,"wodRestart(%u);\n", wDevID);
@@ -1116,8 +1088,8 @@
 }
 
 /**************************************************************************
-* 				wodReset				[internal]
-*/
+ * 			wodReset				[internal]
+ */
 static DWORD wodReset(WORD wDevID)
 {
 	dprintf_mciwave(stddeb,"wodReset(%u);\n", wDevID);
@@ -1130,16 +1102,16 @@
 
 
 /**************************************************************************
-* 				wodGetPosition			[internal]
-*/
-static DWORD wodGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
+ * 				wodGetPosition			[internal]
+ */
+static DWORD wodGetPosition(WORD wDevID, LPMMTIME16 lpTime, DWORD uSize)
 {
 	int		time;
 	dprintf_mciwave(stddeb,"wodGetPosition(%u, %p, %lu);\n", wDevID, lpTime, uSize);
 	if (WOutDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'wodGetPosition' // can't get pos !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
 	if (lpTime == NULL)	return MMSYSERR_INVALPARAM;
 	dprintf_mciwave(stddeb,"wodGetPosition // wType=%04X !\n", 
 			lpTime->wType);
@@ -1152,50 +1124,50 @@
 	dprintf_mciwave(stddeb,"wodGetPosition // nAvgBytesPerSec=%lu\n",
 			WOutDev[wDevID].Format.wf.nAvgBytesPerSec); 
 	switch(lpTime->wType) {
-		case TIME_BYTES:
-			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[wDevID].dwTotalPlayed);
-			dprintf_mciwave(stddeb,"wodGetPosition // wBitsPerSample=%u\n", 
-					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[wDevID].dwTotalPlayed /
+	case TIME_BYTES:
+		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[wDevID].dwTotalPlayed);
+		dprintf_mciwave(stddeb,"wodGetPosition // wBitsPerSample=%u\n", 
+				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[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;
+		time -= lpTime->u.smpte.min * 1800;
+		lpTime->u.smpte.sec = time / 30;
+		time -= lpTime->u.smpte.sec * 30;
+		lpTime->u.smpte.frame = time;
+		lpTime->u.smpte.fps = 30;
+		dprintf_mciwave(stddeb,
+		  "wodGetPosition // TIME_SMPTE=%02u:%02u:%02u:%02u\n",
+		  lpTime->u.smpte.hour, lpTime->u.smpte.min,
+		  lpTime->u.smpte.sec, lpTime->u.smpte.frame);
+		break;
+	default:
+		dprintf_mciwave(stddeb,"wodGetPosition() format not supported ! use TIME_MS !\n");
+		lpTime->wType = TIME_MS;
+	case TIME_MS:
+		lpTime->u.ms = 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;
-			time -= lpTime->u.smpte.min * 1800;
-			lpTime->u.smpte.sec = time / 30;
-			time -= lpTime->u.smpte.sec * 30;
-			lpTime->u.smpte.frame = time;
-			lpTime->u.smpte.fps = 30;
-			dprintf_mciwave(stddeb,
-			  "wodGetPosition // TIME_SMPTE=%02u:%02u:%02u:%02u\n",
-			  lpTime->u.smpte.hour, lpTime->u.smpte.min,
-			  lpTime->u.smpte.sec, lpTime->u.smpte.frame);
-			break;
-		default:
-			dprintf_mciwave(stddeb,"wodGetPosition() format not supported ! use TIME_MS !\n");
-			lpTime->wType = TIME_MS;
-		case TIME_MS:
-			lpTime->u.ms = WOutDev[wDevID].dwTotalPlayed /
-					(WOutDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
-			dprintf_mciwave(stddeb,"wodGetPosition // TIME_MS=%lu\n", lpTime->u.ms);
-			break;
-		}
+		dprintf_mciwave(stddeb,"wodGetPosition // TIME_MS=%lu\n", lpTime->u.ms);
+		break;
+	}
 	return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
-* 				wodGetVolume			[internal]
-*/
+ * 				wodGetVolume			[internal]
+ */
 static DWORD wodGetVolume(WORD wDevID, LPDWORD lpdwVol)
 {
 	int 	mixer;
@@ -1205,11 +1177,11 @@
 	if ((mixer = open(MIXER_DEV, O_RDONLY)) < 0) {
 		dprintf_mciwave(stddeb, "Linux 'wodGetVolume' // mixer device not available !\n");
 		return MMSYSERR_NOTENABLED;
-		}
-    if (ioctl(mixer, SOUND_MIXER_READ_PCM, &volume) == -1) {
+	}
+	if (ioctl(mixer, SOUND_MIXER_READ_PCM, &volume) == -1) {
 		dprintf_mciwave(stddeb,"Linux 'wodGetVolume' // unable read mixer !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
 	close(mixer);
 	left = volume & 0x7F;
 	right = (volume >> 8) & 0x7F;
@@ -1220,8 +1192,8 @@
 
 
 /**************************************************************************
-* 				wodSetVolume			[internal]
-*/
+ * 				wodSetVolume			[internal]
+ */
 static DWORD wodSetVolume(WORD wDevID, DWORD dwParam)
 {
 	int 	mixer;
@@ -1244,8 +1216,8 @@
 #endif /* linux || __FreeBSD__*/
 
 /**************************************************************************
-* 				wodMessage			[sample driver]
-*/
+ * 				wodMessage			[sample driver]
+ */
 DWORD wodMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
 					DWORD dwParam1, DWORD dwParam2)
 {
@@ -1253,47 +1225,47 @@
 			wDevID, wMsg, dwUser, dwParam1, dwParam2);
 #if defined(linux) || defined(__FreeBSD__)
         switch(wMsg) {
-		case WODM_OPEN:
-			return wodOpen(wDevID, (LPWAVEOPENDESC)PTR_SEG_TO_LIN(dwParam1), dwParam2);
-		case WODM_CLOSE:
-			return wodClose(wDevID);
-		case WODM_WRITE:
-			return wodWrite(wDevID, dwParam1, dwParam2);
-		case WODM_PAUSE:
-			return MMSYSERR_NOTSUPPORTED;
-	        case WODM_STOP:
-			return MMSYSERR_NOTSUPPORTED;
-		case WODM_GETPOS:
-			return wodGetPosition(wDevID, (LPMMTIME)PTR_SEG_TO_LIN(dwParam1), dwParam2);
-		case WODM_BREAKLOOP:
-			return MMSYSERR_NOTSUPPORTED;
-		case WODM_PREPARE:
-			return wodPrepare(wDevID, dwParam1, dwParam2);
-		case WODM_UNPREPARE:
-			return wodUnprepare(wDevID, (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
-		case WODM_GETDEVCAPS:
-			return wodGetDevCaps(wDevID, (LPWAVEOUTCAPS)PTR_SEG_TO_LIN(dwParam1), dwParam2);
-		case WODM_GETNUMDEVS:
-			return 1L;
-		case WODM_GETPITCH:
-			return MMSYSERR_NOTSUPPORTED;
-		case WODM_SETPITCH:
-			return MMSYSERR_NOTSUPPORTED;
-		case WODM_GETPLAYBACKRATE:
-			return MMSYSERR_NOTSUPPORTED;
-		case WODM_SETPLAYBACKRATE:
-			return MMSYSERR_NOTSUPPORTED;
-		case WODM_GETVOLUME:
-			return wodGetVolume(wDevID, (LPDWORD)PTR_SEG_TO_LIN(dwParam1));
-		case WODM_SETVOLUME:
-			return wodSetVolume(wDevID, dwParam1);
-		case WODM_RESTART:
-			return wodRestart(wDevID);
-		case WODM_RESET:
-			return wodReset(wDevID);
-		default:
-			dprintf_mciwave(stddeb,"wodMessage // unknown message !\n");
-		}
+	case WODM_OPEN:
+		return wodOpen(wDevID, (LPWAVEOPENDESC)dwParam1, dwParam2);
+	case WODM_CLOSE:
+		return wodClose(wDevID);
+	case WODM_WRITE:
+		return wodWrite(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
+	case WODM_PAUSE:
+		return MMSYSERR_NOTSUPPORTED;
+	case WODM_STOP:
+		return MMSYSERR_NOTSUPPORTED;
+	case WODM_GETPOS:
+		return wodGetPosition(wDevID, (LPMMTIME16)dwParam1, dwParam2);
+	case WODM_BREAKLOOP:
+		return MMSYSERR_NOTSUPPORTED;
+	case WODM_PREPARE:
+		return wodPrepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
+	case WODM_UNPREPARE:
+		return wodUnprepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
+	case WODM_GETDEVCAPS:
+		return wodGetDevCaps(wDevID,(LPWAVEOUTCAPS16)dwParam1,dwParam2);
+	case WODM_GETNUMDEVS:
+		return 1L;
+	case WODM_GETPITCH:
+		return MMSYSERR_NOTSUPPORTED;
+	case WODM_SETPITCH:
+		return MMSYSERR_NOTSUPPORTED;
+	case WODM_GETPLAYBACKRATE:
+		return MMSYSERR_NOTSUPPORTED;
+	case WODM_SETPLAYBACKRATE:
+		return MMSYSERR_NOTSUPPORTED;
+	case WODM_GETVOLUME:
+		return wodGetVolume(wDevID, (LPDWORD)dwParam1);
+	case WODM_SETVOLUME:
+		return wodSetVolume(wDevID, dwParam1);
+	case WODM_RESTART:
+		return wodRestart(wDevID);
+	case WODM_RESET:
+		return wodReset(wDevID);
+	default:
+		dprintf_mciwave(stddeb,"wodMessage // unknown message !\n");
+	}
 	return MMSYSERR_NOTSUPPORTED;
 #else
 	return MMSYSERR_NOTENABLED;
@@ -1306,15 +1278,12 @@
 #if defined(linux) || defined(__FreeBSD__)
 
 /**************************************************************************
-* 				widGetDevCaps				[internal]
-*/
-static DWORD widGetDevCaps(WORD wDevID, LPWAVEINCAPS lpCaps, DWORD dwSize)
+ * 			widGetDevCaps				[internal]
+ */
+static DWORD widGetDevCaps(WORD wDevID, LPWAVEINCAPS16 lpCaps, DWORD dwSize)
 {
-	int 	audio;
-	int		smplrate;
-	int		samplesize = 16;
-	int		dsp_stereo = 1;
-	int		bytespersmpl;
+	int 	audio,smplrate,samplesize=16,dsp_stereo=1,bytespersmpl;
+
 	dprintf_mciwave(stddeb,
 		"widGetDevCaps(%u, %p, %lu);\n", wDevID, lpCaps, dwSize);
 	if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
@@ -1336,30 +1305,36 @@
 	smplrate = 44100;
 	if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
 		lpCaps->dwFormats |= WAVE_FORMAT_4M08;
-		if (lpCaps->wChannels > 1)	lpCaps->dwFormats |= WAVE_FORMAT_4S08;
+		if (lpCaps->wChannels > 1)
+			lpCaps->dwFormats |= WAVE_FORMAT_4S08;
 		if (bytespersmpl > 1) {
 			lpCaps->dwFormats |= WAVE_FORMAT_4M16;
-			if (lpCaps->wChannels > 1)	lpCaps->dwFormats |= WAVE_FORMAT_4S16;
-			}
+			if (lpCaps->wChannels > 1)
+				lpCaps->dwFormats |= WAVE_FORMAT_4S16;
 		}
+	}
 	smplrate = 22050;
 	if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
 		lpCaps->dwFormats |= WAVE_FORMAT_2M08;
-		if (lpCaps->wChannels > 1)	lpCaps->dwFormats |= WAVE_FORMAT_2S08;
+		if (lpCaps->wChannels > 1)
+			lpCaps->dwFormats |= WAVE_FORMAT_2S08;
 		if (bytespersmpl > 1) {
 			lpCaps->dwFormats |= WAVE_FORMAT_2M16;
-			if (lpCaps->wChannels > 1)	lpCaps->dwFormats |= WAVE_FORMAT_2S16;
-			}
+			if (lpCaps->wChannels > 1)
+				lpCaps->dwFormats |= WAVE_FORMAT_2S16;
 		}
+	}
 	smplrate = 11025;
 	if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
 		lpCaps->dwFormats |= WAVE_FORMAT_1M08;
-		if (lpCaps->wChannels > 1)	lpCaps->dwFormats |= WAVE_FORMAT_1S08;
+		if (lpCaps->wChannels > 1)
+			lpCaps->dwFormats |= WAVE_FORMAT_1S08;
 		if (bytespersmpl > 1) {
 			lpCaps->dwFormats |= WAVE_FORMAT_1M16;
-			if (lpCaps->wChannels > 1)	lpCaps->dwFormats |= WAVE_FORMAT_1S16;
-			}
+			if (lpCaps->wChannels > 1)
+				lpCaps->dwFormats |= WAVE_FORMAT_1S16;
 		}
+	}
 	close(audio);
 	dprintf_mciwave(stddeb,
 		"widGetDevCaps // dwFormats = %08lX\n", lpCaps->dwFormats);
@@ -1368,32 +1343,29 @@
 
 
 /**************************************************************************
-* 				widOpen				[internal]
-*/
+ * 				widOpen				[internal]
+ */
 static DWORD widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
 {
-	int 		audio;
-	int			abuf_size;
-	int			smplrate;
-	int			samplesize;
-	int			dsp_stereo;
-	LPWAVEFORMAT  lpFormat;
+	int 		audio,abuf_size,smplrate,samplesize,dsp_stereo;
+	LPWAVEFORMAT	lpFormat;
+
 	dprintf_mciwave(stddeb, "widOpen(%u, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
 	if (lpDesc == NULL) {
 		dprintf_mciwave(stddeb,"Linux 'widOpen' // Invalid Parameter !\n");
 		return MMSYSERR_INVALPARAM;
-		}
+	}
 	if (wDevID >= MAX_WAVINDRV) {
 		dprintf_mciwave(stddeb,"Linux 'widOpen' // MAX_WAVINDRV reached !\n");
 		return MMSYSERR_ALLOCATED;
-		}
+	}
 	WInDev[wDevID].unixdev = 0;
 	if (access(SOUND_DEV,0) != 0) return MMSYSERR_NOTENABLED;
 	audio = open (SOUND_DEV, O_RDONLY, 0);
 	if (audio == -1) {
 		dprintf_mciwave(stddeb,"Linux 'widOpen' // can't open !\n");
 		return MMSYSERR_ALLOCATED;
-		}
+	}
 	IOCTL(audio, SNDCTL_DSP_GETBLKSIZE, abuf_size);
 	if (abuf_size < 1024 || abuf_size > 65536) {
 		if (abuf_size == -1)
@@ -1401,33 +1373,36 @@
 		else
 			dprintf_mciwave(stddeb,"Linux 'widOpen' // SNDCTL_DSP_GETBLKSIZE Invalid bufsize !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
 	WInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
 	switch(WInDev[wDevID].wFlags) {
-		case DCB_NULL:
-			dprintf_mciwave(stddeb,	"Linux 'widOpen' // CALLBACK_NULL !\n");
-			break;
-		case DCB_WINDOW:
-			dprintf_mciwave(stddeb, "Linux 'widOpen' // CALLBACK_WINDOW !\n");
-			break;
-		case DCB_TASK:
-			dprintf_mciwave(stddeb,	"Linux 'widOpen' // CALLBACK_TASK !\n");
-			break;
-		case DCB_FUNCTION:
-			dprintf_mciwave(stddeb,	"Linux 'widOpen' // CALLBACK_FUNCTION !\n");
-			break;
-		}
-	WInDev[wDevID].lp16QueueHdr = NULL;
+	case DCB_NULL:
+		dprintf_mciwave(stddeb,"Linux 'widOpen' // CALLBACK_NULL!\n");
+		break;
+	case DCB_WINDOW:
+		dprintf_mciwave(stddeb,"Linux 'widOpen' // CALLBACK_WINDOW!\n");
+		break;
+	case DCB_TASK:
+		dprintf_mciwave(stddeb,"Linux 'widOpen' // CALLBACK_TASK!\n");
+		break;
+	case DCB_FUNCTION:
+		dprintf_mciwave(stddeb,"Linux 'widOpen' // CALLBACK_FUNCTION!\n");
+		break;
+	}
+	if (WInDev[wDevID].lpQueueHdr) {
+		HeapFree(GetProcessHeap(),0,WInDev[wDevID].lpQueueHdr);
+		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 = (LPWAVEFORMAT) PTR_SEG_TO_LIN(lpDesc->lpFormat); 
+        lpFormat = (LPWAVEFORMAT) lpDesc->lpFormat; 
 	if (lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
 		dprintf_mciwave(stddeb,"Linux 'widOpen' // Bad format %04X !\n",
 					lpFormat->wFormatTag);
 		return WAVERR_BADFORMAT;
-		}
+	}
 	memcpy(&WInDev[wDevID].Format, lpFormat, sizeof(PCMWAVEFORMAT));
 	WInDev[wDevID].Format.wBitsPerSample = 8; /* <-------------- */
 	if (WInDev[wDevID].Format.wf.nChannels == 0) return WAVERR_BADFORMAT;
@@ -1437,7 +1412,7 @@
 		(WInDev[wDevID].Format.wf.nAvgBytesPerSec /
 		WInDev[wDevID].Format.wf.nSamplesPerSec) /
 		WInDev[wDevID].Format.wf.nChannels;
-		}
+	}
 	samplesize = WInDev[wDevID].Format.wBitsPerSample;
 	smplrate = WInDev[wDevID].Format.wf.nSamplesPerSec;
 	dsp_stereo = (WInDev[wDevID].Format.wf.nChannels > 1) ? TRUE : FALSE;
@@ -1455,13 +1430,13 @@
 	if (WAVE_NotifyClient(wDevID, WIM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
 		dprintf_mciwave(stddeb,"Linux 'widOpen' // can't notify client !\n");
 		return MMSYSERR_INVALPARAM;
-		}
+	}
 	return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
-* 				widClose			[internal]
-*/
+ * 				widClose			[internal]
+ */
 static DWORD widClose(WORD wDevID)
 {
 	dprintf_mciwave(stddeb,"widClose(%u);\n", wDevID);
@@ -1469,8 +1444,8 @@
 	if (WInDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'widClose' // can't close !\n");
 		return MMSYSERR_NOTENABLED;
-		}
-	if (WInDev[wDevID].lp16QueueHdr != NULL) {
+	}
+	if (WInDev[wDevID].lpQueueHdr != NULL) {
 	        dprintf_mciwave(stddeb,"linux 'widclose' // still buffers open !\n");
 		return WAVERR_STILLPLAYING;
 	}
@@ -1480,60 +1455,56 @@
 	if (WAVE_NotifyClient(wDevID, WIM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
 		dprintf_mciwave(stddeb,"Linux 'widClose' // can't notify client !\n");
 		return MMSYSERR_INVALPARAM;
-		}
+	}
 	return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
-* 				widAddBuffer		[internal]
-*/
-static DWORD widAddBuffer(WORD wDevID, SEGPTR lp16WaveHdr, DWORD dwSize)
+ * 				widAddBuffer		[internal]
+ */
+static DWORD widAddBuffer(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
-	int			count	= 1;
+	int		count	= 1;
 	LPWAVEHDR 	lpWIHdr;
-	LPWAVEHDR       lpWaveHdr = (LPWAVEHDR)PTR_SEG_TO_LIN(lp16WaveHdr);
 
 	dprintf_mciwave(stddeb,
 		"widAddBuffer(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
 	if (WInDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'widAddBuffer' // can't do it !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
 	if (!(lpWaveHdr->dwFlags & WHDR_PREPARED)) {
 		dprintf_mciwave(stddeb,	"Linux 'widAddBuffer' // never been prepared !\n");
 		return WAVERR_UNPREPARED;
-		}
+	}
 	if (lpWaveHdr->dwFlags & WHDR_INQUEUE) {
 		dprintf_mciwave(stddeb,	"Linux 'widAddBuffer' // header already in use !\n");
 		return WAVERR_STILLPLAYING;
-		}
+	}
 	lpWaveHdr->dwFlags |= WHDR_PREPARED;
 	lpWaveHdr->dwFlags |= WHDR_INQUEUE;
 	lpWaveHdr->dwFlags &= ~WHDR_DONE;
 	lpWaveHdr->dwBytesRecorded = 0;
-	if (WInDev[wDevID].lp16QueueHdr == NULL) {
-		/* begin the queue with a first header ... */
-		WInDev[wDevID].lp16QueueHdr = lp16WaveHdr;
-		WInDev[wDevID].dwTotalRecorded = 0;
-		}
-	else {
-		/* added to the queue, except if it's the one just prepared ... */
-		lpWIHdr = (LPWAVEHDR)PTR_SEG_TO_LIN(WInDev[wDevID].lp16QueueHdr);
-		while (lpWIHdr->lp16Next != NULL) {
-			lpWIHdr = (LPWAVEHDR)PTR_SEG_TO_LIN(lpWIHdr->lp16Next);
+	if (WInDev[wDevID].lpQueueHdr == NULL) {
+		WInDev[wDevID].lpQueueHdr = lpWaveHdr;
+	} else {
+		lpWIHdr = WInDev[wDevID].lpQueueHdr;
+		while (lpWIHdr->lpNext != NULL) {
+			lpWIHdr = lpWIHdr->lpNext;
 			count++;
-			}
-		lpWIHdr->lp16Next = lp16WaveHdr;
-		count++;
 		}
+		lpWIHdr->lpNext = lpWaveHdr;
+		lpWaveHdr->lpNext = NULL;
+		count++;
+	}
 	dprintf_mciwave(stddeb,
 		"widAddBuffer // buffer added ! (now %u in queue)\n", count);
 	return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
-* 				widPrepare			[internal]
-*/
+ * 				widPrepare			[internal]
+ */
 static DWORD widPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
 	dprintf_mciwave(stddeb,
@@ -1541,12 +1512,9 @@
 	if (WInDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'widPrepare' // can't prepare !\n");
 		return MMSYSERR_NOTENABLED;
-		}
-	if (WInDev[wDevID].lp16QueueHdr != NULL) {
-		dprintf_mciwave(stddeb,"Linux 'widPrepare' // already prepare !\n");
-		return WAVERR_BADFORMAT;
-		}
-	if (lpWaveHdr->dwFlags & WHDR_INQUEUE) return WAVERR_STILLPLAYING;
+	}
+	if (lpWaveHdr->dwFlags & WHDR_INQUEUE)
+		return WAVERR_STILLPLAYING;
 	lpWaveHdr->dwFlags |= WHDR_PREPARED;
 	lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
 	lpWaveHdr->dwFlags &= ~WHDR_DONE;
@@ -1556,8 +1524,8 @@
 }
 
 /**************************************************************************
-* 				widUnprepare			[internal]
-*/
+ * 				widUnprepare			[internal]
+ */
 static DWORD widUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
 	dprintf_mciwave(stddeb,
@@ -1565,98 +1533,99 @@
 	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[wDevID].lp16QueueHdr = NULL;
-	dprintf_mciwave(stddeb,
-		"Linux 'widUnprepare' // all headers unprepared !\n");
+
+	dprintf_mciwave(stddeb, "Linux 'widUnprepare' // all headers unprepared !\n");
 	return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
-* 				widStart				[internal]
-*/
+ * 			widStart				[internal]
+ */
 static DWORD widStart(WORD wDevID)
 {
-	int			count	= 1;
+	int		count	= 1;
 	int             bytesRead;
 	LPWAVEHDR 	lpWIHdr;
-	SEGPTR          lp16WaveHdr;
+	LPWAVEHDR	*lpWaveHdr;
 
 	dprintf_mciwave(stddeb,"widStart(%u);\n", wDevID);
 	if (WInDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,	"Linux 'widStart' // can't start recording !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
 
-	lp16WaveHdr = WInDev[wDevID].lp16QueueHdr;
-	dprintf_mciwave(stddeb,"Linux 'widstart'// lp16WaveHdr = %08lx\n",(DWORD)lp16WaveHdr);
-	if (lp16WaveHdr == NULL || 
-		((LPWAVEHDR)PTR_SEG_TO_LIN(lp16WaveHdr))->lpData == NULL) {
+	lpWaveHdr = &(WInDev[wDevID].lpQueueHdr);
+	dprintf_mciwave(stddeb,"Linux 'widstart'// lpWaveHdr = %08lx\n",(DWORD)lpWaveHdr);
+	if (!*lpWaveHdr || !(*lpWaveHdr)->lpData) {
 		dprintf_mciwave(stddeb,"Linux 'widStart' // never been prepared !\n");
 		return WAVERR_UNPREPARED;
-		}
+	}
 
-	while(lp16WaveHdr != NULL) {
-	        lpWIHdr = (LPWAVEHDR)PTR_SEG_TO_LIN(lp16WaveHdr);
-		lpWIHdr->dwBufferLength &= 0xFFFF;
+	while(*lpWaveHdr != NULL) {
+	        lpWIHdr = *lpWaveHdr;
 		dprintf_mciwave(stddeb,
 			"widStart // recording buf#%u=%p size=%lu \n",
 			count, lpWIHdr->lpData, lpWIHdr->dwBufferLength);
 		fflush(stddeb);
 		bytesRead = read (WInDev[wDevID].unixdev, 
-			PTR_SEG_TO_LIN(lpWIHdr->lpData),
+			lpWIHdr->lpData,
 			lpWIHdr->dwBufferLength);
+		if (bytesRead==-1)
+			perror("read from audio device");
+		fprintf(stderr,"bytesread = %d (%ld)\n",bytesRead,lpWIHdr->dwBufferLength);
 		lpWIHdr->dwBytesRecorded = bytesRead;
 		WInDev[wDevID].dwTotalRecorded += lpWIHdr->dwBytesRecorded;
 		lpWIHdr->dwFlags &= ~WHDR_INQUEUE;
 		lpWIHdr->dwFlags |= WHDR_DONE;
 
-		if (WAVE_NotifyClient(wDevID, WIM_DATA, (DWORD)lp16WaveHdr, lpWIHdr->dwBytesRecorded) != 
-			MMSYSERR_NOERROR) {
+		/* FIXME: should pass segmented pointer here, do we need that?*/
+		if (WAVE_NotifyClient(wDevID, WIM_DATA, (DWORD)lpWaveHdr, lpWIHdr->dwBytesRecorded) != MMSYSERR_NOERROR) {
 			dprintf_mciwave(stddeb,	"Linux 'widStart' // can't notify client !\n");
 			return MMSYSERR_INVALPARAM;
-			}
-		lp16WaveHdr = lpWIHdr->lp16Next ;
-		count++;
 		}
+		/* removes the current block from the queue */
+		*lpWaveHdr = lpWIHdr->lpNext;
+		count++;
+	}
 	dprintf_mciwave(stddeb,"widStart // end of recording !\n");
 	fflush(stddeb);
 	return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
-* 				widStop					[internal]
-*/
+ * 			widStop					[internal]
+ */
 static DWORD widStop(WORD wDevID)
 {
 	dprintf_mciwave(stddeb,"widStop(%u);\n", wDevID);
 	if (WInDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'widStop' // can't stop !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
 	return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
-* 				widReset				[internal]
-*/
+ * 			widReset				[internal]
+ */
 static DWORD widReset(WORD wDevID)
 {
 	dprintf_mciwave(stddeb,"widReset(%u);\n", wDevID);
 	if (WInDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'widReset' // can't reset !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
 	return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
-* 				widGetPosition			[internal]
-*/
-static DWORD widGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
+ * 				widGetPosition			[internal]
+ */
+static DWORD widGetPosition(WORD wDevID, LPMMTIME16 lpTime, DWORD uSize)
 {
 	int		time;
     
@@ -1665,7 +1634,7 @@
 	if (WInDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'widGetPosition' // can't get pos !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
 	if (lpTime == NULL)	return MMSYSERR_INVALPARAM;
 	dprintf_mciwave(stddeb,"widGetPosition // wType=%04X !\n", 
 			lpTime->wType);
@@ -1679,51 +1648,51 @@
 			WInDev[wDevID].Format.wf.nAvgBytesPerSec); 
 	fflush(stddeb);
 	switch(lpTime->wType) {
-		case TIME_BYTES:
-			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[wDevID].dwTotalRecorded * 8 /
-					  WInDev[wDevID].Format.wBitsPerSample;
-			dprintf_mciwave(stddeb,
-					"widGetPosition // TIME_SAMPLES=%lu\n", 
-					lpTime->u.sample);
-			break;
-		case TIME_SMPTE:
-			time = WInDev[wDevID].dwTotalRecorded /
+	case TIME_BYTES:
+		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[wDevID].dwTotalRecorded * 8 /
+				  WInDev[wDevID].Format.wBitsPerSample;
+		dprintf_mciwave(stddeb,
+				"widGetPosition // TIME_SAMPLES=%lu\n", 
+				lpTime->u.sample);
+		break;
+	case TIME_SMPTE:
+		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;
+		time -= lpTime->u.smpte.min * 1800;
+		lpTime->u.smpte.sec = time / 30;
+		time -= lpTime->u.smpte.sec * 30;
+		lpTime->u.smpte.frame = time;
+		lpTime->u.smpte.fps = 30;
+dprintf_mciwave(stddeb,"widGetPosition // TIME_SMPTE=%02u:%02u:%02u:%02u\n",
+				lpTime->u.smpte.hour, lpTime->u.smpte.min,
+				lpTime->u.smpte.sec, lpTime->u.smpte.frame);
+		break;
+	default:
+		dprintf_mciwave(stddeb,"widGetPosition() format not supported ! use TIME_MS !\n");
+		lpTime->wType = TIME_MS;
+	case TIME_MS:
+		lpTime->u.ms = 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;
-			time -= lpTime->u.smpte.min * 1800;
-			lpTime->u.smpte.sec = time / 30;
-			time -= lpTime->u.smpte.sec * 30;
-			lpTime->u.smpte.frame = time;
-			lpTime->u.smpte.fps = 30;
-            dprintf_mciwave(stddeb,"widGetPosition // TIME_SMPTE=%02u:%02u:%02u:%02u\n",
-					lpTime->u.smpte.hour, lpTime->u.smpte.min,
-					lpTime->u.smpte.sec, lpTime->u.smpte.frame);
-			break;
-		default:
-			dprintf_mciwave(stddeb,"widGetPosition() format not supported ! use TIME_MS !\n");
-			lpTime->wType = TIME_MS;
-		case TIME_MS:
-			lpTime->u.ms = WInDev[wDevID].dwTotalRecorded /
-					(WInDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
-			dprintf_mciwave(stddeb,
-			      "widGetPosition // TIME_MS=%lu\n", lpTime->u.ms);
-			break;
-		}
+		dprintf_mciwave(stddeb,
+		      "widGetPosition // TIME_MS=%lu\n", lpTime->u.ms);
+		break;
+	}
 	return MMSYSERR_NOERROR;
 }
 
 #endif /* linux || __FreeBSD__ */
 
 /**************************************************************************
-* 				widMessage			[sample driver]
-*/
+ * 				widMessage			[sample driver]
+ */
 DWORD widMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
 					DWORD dwParam1, DWORD dwParam2)
 {
@@ -1731,33 +1700,33 @@
 			wDevID, wMsg, dwUser, dwParam1, dwParam2);
 #if defined(linux) || defined(__FreeBSD__)
 	switch(wMsg) {
-		case WIDM_OPEN:
-			return widOpen(wDevID, (LPWAVEOPENDESC)PTR_SEG_TO_LIN(dwParam1), dwParam2);
-		case WIDM_CLOSE:
-			return widClose(wDevID);
-		case WIDM_ADDBUFFER:
-			return widAddBuffer(wDevID, dwParam1, dwParam2);
-		case WIDM_PREPARE:
-			return widPrepare(wDevID, (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
-		case WIDM_UNPREPARE:
-			return widUnprepare(wDevID, (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
-		case WIDM_GETDEVCAPS:
-			return widGetDevCaps(wDevID, (LPWAVEINCAPS)PTR_SEG_TO_LIN(dwParam1), dwParam2);
-		case WIDM_GETNUMDEVS:
-			return 1;
-		case WIDM_GETPOS:
-			return widGetPosition(wDevID, (LPMMTIME)PTR_SEG_TO_LIN(dwParam1), dwParam2);
-		case WIDM_RESET:
-			return widReset(wDevID);
-		case WIDM_START:
-			return widStart(wDevID);
-		case WIDM_PAUSE:
-			return widStop(wDevID);
-		case WIDM_STOP:
-			return widStop(wDevID);
-		default:
-			dprintf_mciwave(stddeb,"widMessage // unknown message !\n");
-		}
+	case WIDM_OPEN:
+		return widOpen(wDevID, (LPWAVEOPENDESC)dwParam1, dwParam2);
+	case WIDM_CLOSE:
+		return widClose(wDevID);
+	case WIDM_ADDBUFFER:
+		return widAddBuffer(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
+	case WIDM_PREPARE:
+		return widPrepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
+	case WIDM_UNPREPARE:
+		return widUnprepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
+	case WIDM_GETDEVCAPS:
+		return widGetDevCaps(wDevID, (LPWAVEINCAPS16)dwParam1,dwParam2);
+	case WIDM_GETNUMDEVS:
+		return 1;
+	case WIDM_GETPOS:
+		return widGetPosition(wDevID, (LPMMTIME16)dwParam1, dwParam2);
+	case WIDM_RESET:
+		return widReset(wDevID);
+	case WIDM_START:
+		return widStart(wDevID);
+	case WIDM_PAUSE:
+		return widStop(wDevID);
+	case WIDM_STOP:
+		return widStop(wDevID);
+	default:
+		dprintf_mciwave(stddeb,"widMessage // unknown message !\n");
+	}
 	return MMSYSERR_NOTSUPPORTED;
 #else
 	return MMSYSERR_NOTENABLED;
@@ -1766,8 +1735,8 @@
 
 
 /**************************************************************************
-* 				AUDIO_DriverProc		[sample driver]
-*/
+ * 				AUDIO_DriverProc		[sample driver]
+ */
 LONG WAVE_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
 						DWORD dwParam1, DWORD dwParam2)
 {
@@ -1775,93 +1744,93 @@
 	dprintf_mciwave(stddeb,"WAVE_DriverProc(%08lX, %04X, %04X, %08lX, %08lX)\n", 
 		dwDevID, hDriv, wMsg, dwParam1, dwParam2);
 	switch(wMsg) {
-		case DRV_LOAD:
-			return 1;
-		case DRV_FREE:
-			return 1;
-		case DRV_OPEN:
-			return 1;
-		case DRV_CLOSE:
-			return 1;
-		case DRV_ENABLE:
-			return 1;
-		case DRV_DISABLE:
-			return 1;
-		case DRV_QUERYCONFIGURE:
-			return 1;
-		case DRV_CONFIGURE:
-			MessageBox16(0, "Sample MultiMedia Linux Driver !", 
-								"MMLinux Driver", MB_OK);
-			return 1;
-		case DRV_INSTALL:
-			return DRVCNF_RESTART;
-		case DRV_REMOVE:
-			return DRVCNF_RESTART;
-		case MCI_OPEN_DRIVER:
-		case MCI_OPEN:
-			return WAVE_mciOpen(dwDevID, dwParam1, (LPMCI_WAVE_OPEN_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		case MCI_CUE:
-			return WAVE_mciCue(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		case MCI_CLOSE_DRIVER:
-		case MCI_CLOSE:
-			return WAVE_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		case MCI_PLAY:
-			return WAVE_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		case MCI_RECORD:
-			return WAVE_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		case MCI_STOP:
-			return WAVE_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		case MCI_SET:
-			return WAVE_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		case MCI_PAUSE:
-			return WAVE_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		case MCI_RESUME:
-			return WAVE_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		case MCI_STATUS:
-			return WAVE_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		case MCI_GETDEVCAPS:
-			return WAVE_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		case MCI_INFO:
-			return WAVE_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS)PTR_SEG_TO_LIN(dwParam2));
+	case DRV_LOAD:
+		return 1;
+	case DRV_FREE:
+		return 1;
+	case DRV_OPEN:
+		return 1;
+	case DRV_CLOSE:
+		return 1;
+	case DRV_ENABLE:
+		return 1;
+	case DRV_DISABLE:
+		return 1;
+	case DRV_QUERYCONFIGURE:
+		return 1;
+	case DRV_CONFIGURE:
+		MessageBox16(0, "Sample MultiMedia Linux Driver !", 
+							"MMLinux Driver", MB_OK);
+		return 1;
+	case DRV_INSTALL:
+		return DRVCNF_RESTART;
+	case DRV_REMOVE:
+		return DRVCNF_RESTART;
+	case MCI_OPEN_DRIVER:
+	case MCI_OPEN:
+		return WAVE_mciOpen(dwDevID, dwParam1, (LPMCI_WAVE_OPEN_PARMS16)PTR_SEG_TO_LIN(dwParam2));
+	case MCI_CUE:
+		return WAVE_mciCue(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
+	case MCI_CLOSE_DRIVER:
+	case MCI_CLOSE:
+		return WAVE_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
+	case MCI_PLAY:
+		return WAVE_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)PTR_SEG_TO_LIN(dwParam2));
+	case MCI_RECORD:
+		return WAVE_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)PTR_SEG_TO_LIN(dwParam2));
+	case MCI_STOP:
+		return WAVE_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
+	case MCI_SET:
+		return WAVE_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)PTR_SEG_TO_LIN(dwParam2));
+	case MCI_PAUSE:
+		return WAVE_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
+	case MCI_RESUME:
+		return WAVE_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
+	case MCI_STATUS:
+		return WAVE_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)PTR_SEG_TO_LIN(dwParam2));
+	case MCI_GETDEVCAPS:
+		return WAVE_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)PTR_SEG_TO_LIN(dwParam2));
+	case MCI_INFO:
+		return WAVE_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS16)PTR_SEG_TO_LIN(dwParam2));
 
-                case MCI_LOAD:
-			return MMSYSERR_NOTSUPPORTED;
-		case MCI_SAVE:
-			return MMSYSERR_NOTSUPPORTED;
-		case MCI_SEEK:
-			return MMSYSERR_NOTSUPPORTED;
-		case MCI_FREEZE:
-			return MMSYSERR_NOTSUPPORTED;
-		case MCI_PUT:
-			return MMSYSERR_NOTSUPPORTED;
-		case MCI_REALIZE:
-			return MMSYSERR_NOTSUPPORTED;
-		case MCI_UNFREEZE:
-			return MMSYSERR_NOTSUPPORTED;
-		case MCI_UPDATE:
-			return MMSYSERR_NOTSUPPORTED;
-		case MCI_WHERE:
-			return MMSYSERR_NOTSUPPORTED;
-		case MCI_WINDOW:
-			return MMSYSERR_NOTSUPPORTED;
-		case MCI_STEP:
-			return MMSYSERR_NOTSUPPORTED;
-		case MCI_SPIN:
-			return MMSYSERR_NOTSUPPORTED;
-		case MCI_ESCAPE:
-			return MMSYSERR_NOTSUPPORTED;
-		case MCI_COPY:
-			return MMSYSERR_NOTSUPPORTED;
-		case MCI_CUT:
-			return MMSYSERR_NOTSUPPORTED;
-		case MCI_DELETE:
-			return MMSYSERR_NOTSUPPORTED;
-		case MCI_PASTE:
-			return MMSYSERR_NOTSUPPORTED;
+	case MCI_LOAD:
+		return MMSYSERR_NOTSUPPORTED;
+	case MCI_SAVE:
+		return MMSYSERR_NOTSUPPORTED;
+	case MCI_SEEK:
+		return MMSYSERR_NOTSUPPORTED;
+	case MCI_FREEZE:
+		return MMSYSERR_NOTSUPPORTED;
+	case MCI_PUT:
+		return MMSYSERR_NOTSUPPORTED;
+	case MCI_REALIZE:
+		return MMSYSERR_NOTSUPPORTED;
+	case MCI_UNFREEZE:
+		return MMSYSERR_NOTSUPPORTED;
+	case MCI_UPDATE:
+		return MMSYSERR_NOTSUPPORTED;
+	case MCI_WHERE:
+		return MMSYSERR_NOTSUPPORTED;
+	case MCI_WINDOW:
+		return MMSYSERR_NOTSUPPORTED;
+	case MCI_STEP:
+		return MMSYSERR_NOTSUPPORTED;
+	case MCI_SPIN:
+		return MMSYSERR_NOTSUPPORTED;
+	case MCI_ESCAPE:
+		return MMSYSERR_NOTSUPPORTED;
+	case MCI_COPY:
+		return MMSYSERR_NOTSUPPORTED;
+	case MCI_CUT:
+		return MMSYSERR_NOTSUPPORTED;
+	case MCI_DELETE:
+		return MMSYSERR_NOTSUPPORTED;
+	case MCI_PASTE:
+		return MMSYSERR_NOTSUPPORTED;
 
-		default:
-			return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
-		}
+	default:
+		return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
+	}
 #else
 	return MMSYSERR_NOTENABLED;
 #endif
diff --git a/multimedia/mcianim.c b/multimedia/mcianim.c
index 59a9f46..7b44e39 100644
--- a/multimedia/mcianim.c
+++ b/multimedia/mcianim.c
@@ -29,7 +29,7 @@
     BOOL16  fShareable;         /* TRUE if first open was shareable */
     WORD    wNotifyDeviceID;    /* MCI device ID with a pending notification */
     HANDLE16 hCallback;          /* Callback handle for pending notification */
-	MCI_OPEN_PARMS openParms;
+	MCI_OPEN_PARMS16 openParms;
 	DWORD	dwTimeFormat;
 	int		mode;
 	UINT16	nCurTrack;
@@ -38,7 +38,7 @@
 	DWORD	dwTotalLen;
 	LPDWORD	lpdwTrackLen;
 	LPDWORD	lpdwTrackPos;
-	} LINUX_ANIM;
+} LINUX_ANIM;
 
 static LINUX_ANIM	AnimDev[MAX_ANIMDRV];
 #endif
@@ -49,7 +49,7 @@
 /**************************************************************************
 * 				ANIM_mciOpen			[internal]
 */
-static DWORD ANIM_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS lpParms)
+static DWORD ANIM_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS16 lpParms)
 {
 #if defined(linux) || defined(__FreeBSD__)
 	LPSTR		lpstrElementName;
@@ -83,7 +83,7 @@
 			CharUpper32A(str);
 			}
 		}
-	memcpy(&AnimDev[wDevID].openParms, lpParms, sizeof(MCI_OPEN_PARMS));
+	memcpy(&AnimDev[wDevID].openParms, lpParms, sizeof(MCI_OPEN_PARMS16));
 	AnimDev[wDevID].wNotifyDeviceID = lpParms->wDeviceID;
 	AnimDev[wDevID].mode = 0;
 	AnimDev[wDevID].dwTimeFormat = MCI_FORMAT_TMSF;
@@ -285,7 +285,7 @@
 /**************************************************************************
 * 				ANIM_mciInfo			[internal]
 */
-static DWORD ANIM_mciInfo(UINT16 wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms)
+static DWORD ANIM_mciInfo(UINT16 wDevID, DWORD dwFlags, LPMCI_INFO_PARMS16 lpParms)
 {
 #if defined(linux) || defined(__FreeBSD__)
 	dprintf_mcianim(stddeb,"ANIM_mciInfo(%u, %08lX, %p);\n", 
@@ -617,7 +617,7 @@
 		case MCI_OPEN_DRIVER:
 		case MCI_OPEN:
 			return ANIM_mciOpen(dwDevID, dwParam1, 
-					(LPMCI_OPEN_PARMS)PTR_SEG_TO_LIN(dwParam2)); 
+					(LPMCI_OPEN_PARMS16)PTR_SEG_TO_LIN(dwParam2)); 
 		case DRV_CLOSE:
 		case MCI_CLOSE_DRIVER:
 		case MCI_CLOSE:
@@ -642,7 +642,7 @@
 					(LPMCI_GETDEVCAPS_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_INFO:
 			return ANIM_mciInfo(dwDevID, dwParam1, 
-						(LPMCI_INFO_PARMS)PTR_SEG_TO_LIN(dwParam2));
+						(LPMCI_INFO_PARMS16)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_STATUS:
 			return ANIM_mciStatus(dwDevID, dwParam1, 
 						(LPMCI_STATUS_PARMS)PTR_SEG_TO_LIN(dwParam2));
diff --git a/multimedia/mcicda.c b/multimedia/mcicda.c
index bfde0cc..d92d840 100644
--- a/multimedia/mcicda.c
+++ b/multimedia/mcicda.c
@@ -51,7 +51,7 @@
     BOOL16  fShareable;         /* TRUE if first open was shareable */
     WORD    wNotifyDeviceID;    /* MCI device ID with a pending notification */
     HANDLE16 hCallback;          /* Callback handle for pending notification */
-	MCI_OPEN_PARMS openParms;
+	MCI_OPEN_PARMS16 openParms;
 	DWORD	dwTimeFormat;
 	int		unixdev;
 #ifdef linux
@@ -227,7 +227,7 @@
 /**************************************************************************
 * 				CDAUDIO_mciOpen			[internal]
 */
-static DWORD CDAUDIO_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS lpParms)
+static DWORD CDAUDIO_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS16 lpParms)
 {
 #if defined(linux) || defined(__FreeBSD__)
     	dprintf_cdaudio(stddeb,"CDAUDIO_mciOpen(%04X, %08lX, %p);\n", 
@@ -251,7 +251,7 @@
 		dprintf_cdaudio(stddeb,"CDAUDIO_mciOpen // MCI_OPEN_ELEMENT !\n");
 /*		return MCIERR_NO_ELEMENT_ALLOWED; */
 		}
-	memcpy(&CDADev[wDevID].openParms, lpParms, sizeof(MCI_OPEN_PARMS));
+	memcpy(&CDADev[wDevID].openParms, lpParms, sizeof(MCI_OPEN_PARMS16));
 	CDADev[wDevID].wNotifyDeviceID = lpParms->wDeviceID;
 	CDADev[wDevID].unixdev = open (CDAUDIO_DEV, O_RDONLY, 0);
 	if (CDADev[wDevID].unixdev == -1) {
@@ -361,7 +361,7 @@
 /**************************************************************************
 * 				CDAUDIO_mciInfo			[internal]
 */
-static DWORD CDAUDIO_mciInfo(UINT16 wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms)
+static DWORD CDAUDIO_mciInfo(UINT16 wDevID, DWORD dwFlags, LPMCI_INFO_PARMS16 lpParms)
 {
 #if defined(linux) || defined(__FreeBSD__)
     	dprintf_cdaudio(stddeb,"CDAUDIO_mciInfo(%04X, %08lX, %p);\n", 
@@ -1037,7 +1037,7 @@
 		case DRV_OPEN:
 		case MCI_OPEN_DRIVER:
 		case MCI_OPEN:
-			return CDAUDIO_mciOpen(dwDevID, dwParam1, (LPMCI_OPEN_PARMS)PTR_SEG_TO_LIN(dwParam2)); 
+			return CDAUDIO_mciOpen(dwDevID, dwParam1, (LPMCI_OPEN_PARMS16)PTR_SEG_TO_LIN(dwParam2)); 
 		case DRV_CLOSE:
 		case MCI_CLOSE_DRIVER:
 		case MCI_CLOSE:
@@ -1061,7 +1061,7 @@
 				(LPMCI_GETDEVCAPS_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_INFO:
 			return CDAUDIO_mciInfo(dwDevID, dwParam1, 
-				(LPMCI_INFO_PARMS)PTR_SEG_TO_LIN(dwParam2));
+				(LPMCI_INFO_PARMS16)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_STATUS:
 			return CDAUDIO_mciStatus(dwDevID, dwParam1, 
 				(LPMCI_STATUS_PARMS)PTR_SEG_TO_LIN(dwParam2));
diff --git a/multimedia/mcistring.c b/multimedia/mcistring.c
index f97ca49..298bd5c 100644
--- a/multimedia/mcistring.c
+++ b/multimedia/mcistring.c
@@ -33,7 +33,7 @@
 /* FIXME: I need to remember the aliasname of a spec. driver. 
  *        and this is the easiest way. *sigh*
  */
-extern MCI_OPEN_PARMS		mciOpenDrv[MAXMCIDRIVERS];
+extern MCI_OPEN_PARMS16		mciOpenDrv[MAXMCIDRIVERS];
 
 #define GetDrv(wDevID) (&mciDrv[MMSYSTEM_DevIDToIndex(wDevID)])
 #define GetOpenDrv(wDevID) (&mciOpenDrv[MMSYSTEM_DevIDToIndex(wDevID)])
@@ -305,10 +305,10 @@
 	int		res,i;
 	char		*s;
 	union U {
-		MCI_OPEN_PARMS	openParams;
-		MCI_WAVE_OPEN_PARMS	waveopenParams;
-		MCI_ANIM_OPEN_PARMS	animopenParams;
-		MCI_OVLY_OPEN_PARMS	ovlyopenParams;
+		MCI_OPEN_PARMS16	openParams;
+		MCI_WAVE_OPEN_PARMS16	waveopenParams;
+		MCI_ANIM_OPEN_PARMS16	animopenParams;
+		MCI_OVLY_OPEN_PARMS16	ovlyopenParams;
 	};
         union U *pU = SEGPTR_NEW(union U);
 
@@ -316,7 +316,7 @@
 	s=strchr(dev,'!');
 	if (s!=NULL) {
 		*s++='\0';
-		pU->openParams.lpstrElementName=SEGPTR_GET(SEGPTR_STRDUP(s));
+		pU->openParams.lpstrElementName=(LPSTR)SEGPTR_GET(SEGPTR_STRDUP(s));
 		dwFlags |= MCI_OPEN_ELEMENT;
 	}
 	if (!STRCMP(dev,"cdaudio")) {
@@ -350,7 +350,7 @@
 	pU->openParams.wDeviceID	= wDevID;
 	pU->ovlyopenParams.dwStyle	= 0; 
 	pU->animopenParams.dwStyle	= 0; 
-	pU->openParams.lpstrDeviceType	= SEGPTR_GET(SEGPTR_STRDUP(dev));
+	pU->openParams.lpstrDeviceType	= (LPSTR)SEGPTR_GET(SEGPTR_STRDUP(dev));
 	pU->openParams.lpstrAlias	= NULL;
 	dwFlags |= MCI_OPEN_TYPE;
 	i=0;
@@ -358,13 +358,13 @@
 		FLAG1("shareable",MCI_OPEN_SHAREABLE);
 		if (!STRCMP(keywords[i],"alias") && (i+1<nrofkeywords)) {
 			dwFlags |= MCI_OPEN_ALIAS;
-			pU->openParams.lpstrAlias=SEGPTR_GET(SEGPTR_STRDUP(keywords[i+1]));
+			pU->openParams.lpstrAlias=(LPSTR)SEGPTR_GET(SEGPTR_STRDUP(keywords[i+1]));
 			i+=2;
 			continue;
 		}
 		if (!STRCMP(keywords[i],"element") && (i+1<nrofkeywords)) {
 			dwFlags |= MCI_OPEN_ELEMENT;
-			pU->openParams.lpstrElementName=SEGPTR_GET(SEGPTR_STRDUP(keywords[i+1]));
+			pU->openParams.lpstrElementName=(LPSTR)SEGPTR_GET(SEGPTR_STRDUP(keywords[i+1]));
 			i+=2;
 			continue;
 		}
@@ -434,7 +434,7 @@
 	}
 	_MCI_CALL_DRIVER( MCI_OPEN, SEGPTR_GET(pU) );
 	if (res==0)
-		memcpy(GetOpenDrv(wDevID),&pU->openParams,sizeof(MCI_OPEN_PARMS));
+		memcpy(GetOpenDrv(wDevID),&pU->openParams,sizeof(MCI_OPEN_PARMS16));
 	else {
 		SEGPTR_FREE(PTR_SEG_TO_LIN(pU->openParams.lpstrElementName));
 		SEGPTR_FREE(PTR_SEG_TO_LIN(pU->openParams.lpstrDeviceType));
@@ -672,7 +672,7 @@
 MCISTR_Set(_MCISTR_PROTO_) {
 	union U {
 		MCI_SET_PARMS		setParams;
-		MCI_WAVE_SET_PARMS	wavesetParams;
+		MCI_WAVE_SET_PARMS16	wavesetParams;
 		MCI_SEQ_SET_PARMS	seqsetParams;
 	};
         union U *pU = SEGPTR_NEW(union U);
@@ -848,7 +848,7 @@
 static DWORD
 MCISTR_Break(_MCISTR_PROTO_)
 {
-    MCI_BREAK_PARMS *breakParams = SEGPTR_NEW(MCI_BREAK_PARMS);
+    MCI_BREAK_PARMS16 *breakParams = SEGPTR_NEW(MCI_BREAK_PARMS16);
     int res,i;
 
     if (!breakParams) return 0;
@@ -859,7 +859,7 @@
 		if (!strcmp(keywords[i],"on") && (nrofkeywords>i+1)) {
 			dwFlags&=~MCI_BREAK_OFF;
 			dwFlags|=MCI_BREAK_KEY;
-			sscanf(keywords[i+1],"%d",&(breakParams->nVirtKey));
+			sscanf(keywords[i+1],"%hd",&(breakParams->nVirtKey));
 			i+=2;
 			continue;
 		}
@@ -1312,7 +1312,7 @@
 static DWORD
 MCISTR_Info(_MCISTR_PROTO_)
 {
-	MCI_INFO_PARMS	*infoParams = SEGPTR_NEW(MCI_INFO_PARMS);
+	MCI_INFO_PARMS16 *infoParams = SEGPTR_NEW(MCI_INFO_PARMS16);
 	DWORD		sflags;
 	int		i,res;
 
@@ -1342,7 +1342,7 @@
 	return res;
 }
 
-DWORD mciSysInfo(DWORD dwFlags,LPMCI_SYSINFO_PARMS lpParms);
+DWORD mciSysInfo(DWORD dwFlags,LPMCI_SYSINFO_PARMS16 lpParms);
 
 /* query MCI driver itself for information
  * Arguments:
@@ -1356,7 +1356,7 @@
  */
 static DWORD
 MCISTR_Sysinfo(_MCISTR_PROTO_) {
-	MCI_SYSINFO_PARMS	sysinfoParams;
+	MCI_SYSINFO_PARMS16	sysinfoParams;
 	int			i,res;
 
 	sysinfoParams.lpstrReturn	= lpstrReturnString;
@@ -1393,8 +1393,8 @@
 static DWORD
 MCISTR_Load(_MCISTR_PROTO_) {
 	union U {
-		MCI_LOAD_PARMS	loadParams;
-		MCI_OVLY_LOAD_PARMS	ovlyloadParams;
+		MCI_LOAD_PARMS16	loadParams;
+		MCI_OVLY_LOAD_PARMS16	ovlyloadParams;
 	};
         union U *pU = SEGPTR_NEW(union U);
 	int		i,len,res;
@@ -1441,7 +1441,7 @@
 MCISTR_Save(_MCISTR_PROTO_) {
 	union U {
 		MCI_SAVE_PARMS	saveParams;
-		MCI_OVLY_SAVE_PARMS	ovlysaveParams;
+		MCI_OVLY_SAVE_PARMS16	ovlysaveParams;
 	};
         union U *pU = SEGPTR_NEW(union U);
 	int		i,len,res;
@@ -1575,7 +1575,7 @@
 static DWORD
 MCISTR_Escape(_MCISTR_PROTO_)
 {
-	MCI_VD_ESCAPE_PARMS *escapeParams = SEGPTR_NEW(MCI_VD_ESCAPE_PARMS);
+	MCI_VD_ESCAPE_PARMS16 *escapeParams = SEGPTR_NEW(MCI_VD_ESCAPE_PARMS16);
 	int			i,len,res;
 	char		*s;
 
@@ -1607,7 +1607,7 @@
 static DWORD
 MCISTR_Unfreeze(_MCISTR_PROTO_)
 {
-	MCI_OVLY_RECT_PARMS *unfreezeParams = SEGPTR_NEW(MCI_OVLY_RECT_PARMS);
+	MCI_OVLY_RECT_PARMS16 *unfreezeParams = SEGPTR_NEW(MCI_OVLY_RECT_PARMS16);
 	int			i,res;
 
 	if (uDevTyp != MCI_DEVTYPE_OVERLAY)
@@ -1634,7 +1634,7 @@
 static DWORD
 MCISTR_Freeze(_MCISTR_PROTO_)
 {
-	MCI_OVLY_RECT_PARMS *freezeParams = SEGPTR_NEW(MCI_OVLY_RECT_PARMS);
+	MCI_OVLY_RECT_PARMS16 *freezeParams = SEGPTR_NEW(MCI_OVLY_RECT_PARMS16);
 	int			i,res;
 
 	if (uDevTyp != MCI_DEVTYPE_OVERLAY)
@@ -1673,8 +1673,8 @@
 static DWORD
 MCISTR_Put(_MCISTR_PROTO_) {
 	union U {
-		MCI_OVLY_RECT_PARMS	ovlyputParams;
-		MCI_ANIM_RECT_PARMS	animputParams;
+		MCI_OVLY_RECT_PARMS16	ovlyputParams;
+		MCI_ANIM_RECT_PARMS16	animputParams;
 	};
         union U *pU = SEGPTR_NEW(union U);
 	int	i,res;
@@ -1813,7 +1813,7 @@
 static DWORD
 MCISTR_Update(_MCISTR_PROTO_) {
 	int		i,res;
-	MCI_ANIM_UPDATE_PARMS *updateParams = SEGPTR_NEW(MCI_ANIM_UPDATE_PARMS);
+	MCI_ANIM_UPDATE_PARMS16 *updateParams = SEGPTR_NEW(MCI_ANIM_UPDATE_PARMS16);
 
 	i=0;
 	while (i<nrofkeywords) {
@@ -1851,8 +1851,8 @@
 static DWORD
 MCISTR_Where(_MCISTR_PROTO_) {
 	union U {
-		MCI_ANIM_RECT_PARMS	animwhereParams;
-		MCI_OVLY_RECT_PARMS	ovlywhereParams;
+		MCI_ANIM_RECT_PARMS16	animwhereParams;
+		MCI_OVLY_RECT_PARMS16	ovlywhereParams;
 	};
         union U *pU = SEGPTR_NEW(union U);
 	int	i,res;
@@ -1906,8 +1906,8 @@
 	int	i,res;
 	char	*s;
 	union U {
-		MCI_ANIM_WINDOW_PARMS	animwindowParams;
-		MCI_OVLY_WINDOW_PARMS	ovlywindowParams;
+		MCI_ANIM_WINDOW_PARMS16	animwindowParams;
+		MCI_OVLY_WINDOW_PARMS16	ovlywindowParams;
 	};
         union U *pU = SEGPTR_NEW(union U);
 
diff --git a/multimedia/midi.c b/multimedia/midi.c
index 9392819..471a4d1 100644
--- a/multimedia/midi.c
+++ b/multimedia/midi.c
@@ -43,29 +43,29 @@
 #define MAX_MCIMIDIDRV 	(1)
 
 typedef struct {
-	int				unixdev;
-	int				state;
-	DWORD			bufsize;
+	int		unixdev;
+	int		state;
+	DWORD		bufsize;
 	MIDIOPENDESC	midiDesc;
-	WORD			wFlags;
-	LPMIDIHDR 		lpQueueHdr;
-	DWORD			dwTotalPlayed;
-	} LINUX_MIDIIN;
+	WORD		wFlags;
+	LPMIDIHDR 	lpQueueHdr;
+	DWORD		dwTotalPlayed;
+} LINUX_MIDIIN;
 
 typedef struct {
-	int				unixdev;
-	int				state;
-	DWORD			bufsize;
+	int		unixdev;
+	int		state;
+	DWORD		bufsize;
 	MIDIOPENDESC	midiDesc;
-	WORD			wFlags;
-	LPMIDIHDR 		lpQueueHdr;
-	DWORD			dwTotalPlayed;
-	} LINUX_MIDIOUT;
+	WORD		wFlags;
+	LPMIDIHDR 	lpQueueHdr;
+	DWORD		dwTotalPlayed;
+} LINUX_MIDIOUT;
 
 typedef struct {
-	int     nUseCount;          /* Incremented for each shared open */
-	BOOL16  fShareable;         /* TRUE if first open was shareable */
-	WORD    wNotifyDeviceID;    /* MCI device ID with a pending notification */
+	int	nUseCount;          /* Incremented for each shared open */
+	BOOL16	fShareable;         /* TRUE if first open was shareable */
+	WORD	wNotifyDeviceID;    /* MCI device ID with a pending notification */
 	HANDLE16 hCallback;         /* Callback handle for pending notification */
 	HMMIO16	hFile;				/* mmio file handle open as Element		*/
 	DWORD	dwBeginData;
@@ -73,21 +73,21 @@
 	WORD	wFormat;
 	WORD	nTracks;
 	WORD	nTempo;
-	MCI_OPEN_PARMS openParms;
-/* 	MIDIHDR		MidiHdr; */
-	HLOCAL16        hMidiHdr;
-	WORD		dwStatus;
-	} LINUX_MCIMIDI;
+	MCI_OPEN_PARMS16 openParms;
+/* 	MIDIHDR	MidiHdr; */
+	HLOCAL16	hMidiHdr;
+	WORD	dwStatus;
+} LINUX_MCIMIDI;
 
-static LINUX_MIDIIN		MidiInDev[MAX_MIDIINDRV];
+static LINUX_MIDIIN	MidiInDev[MAX_MIDIINDRV];
 static LINUX_MIDIOUT	MidiOutDev[MAX_MIDIOUTDRV];
 static LINUX_MCIMIDI	MCIMidiDev[MAX_MCIMIDIDRV];
 #endif
 
 
 /**************************************************************************
-* 				MIDI_NotifyClient			[internal]
-*/
+ * 			MIDI_NotifyClient			[internal]
+ */
 static DWORD MIDI_NotifyClient(UINT16 wDevID, WORD wMsg, 
 				DWORD dwParam1, DWORD dwParam2)
 {
@@ -135,8 +135,8 @@
 
 
 /**************************************************************************
-* 				MIDI_ReadByte			[internal]	
-*/
+ * 				MIDI_ReadByte			[internal]	
+ */
 static DWORD MIDI_ReadByte(UINT16 wDevID, BYTE *lpbyt)
 {
 #if defined(linux) || defined(__FreeBSD__)
@@ -144,8 +144,8 @@
 		if (mmioRead(MCIMidiDev[wDevID].hFile, (HPSTR)lpbyt,
 			(long) sizeof(BYTE)) == (long) sizeof(BYTE)) {
 			return 0;
-			}
 		}
+	}
 	dprintf_midi(stddeb, "MIDI_ReadByte // error reading wDevID=%04X\n", wDevID);
 	return MCIERR_INTERNAL;
 
@@ -156,8 +156,8 @@
 
 
 /**************************************************************************
-* 				MIDI_ReadWord			[internal]	
-*/
+ * 				MIDI_ReadWord			[internal]	
+ */
 static DWORD MIDI_ReadWord(UINT16 wDevID, LPWORD lpw)
 {
 	BYTE	hibyte, lobyte;
@@ -166,17 +166,17 @@
 			if (MIDI_ReadByte(wDevID, &lobyte) == 0) {
 				*lpw = ((WORD)hibyte << 8) + lobyte;
 				return 0;
-				}
 			}
 		}
+	}
 	dprintf_midi(stddeb, "MIDI_ReadWord // error reading wDevID=%04X\n", wDevID);
 	return MCIERR_INTERNAL;
 }
 
 
 /**************************************************************************
-* 				MIDI_ReadLong			[internal]	
-*/
+ * 				MIDI_ReadLong			[internal]	
+ */
 static DWORD MIDI_ReadLong(UINT16 wDevID, LPDWORD lpdw)
 {
 	WORD	hiword, loword;
@@ -185,17 +185,17 @@
 			if (MIDI_ReadWord(wDevID, &loword) == 0) {
 				*lpdw = MAKELONG(loword, hiword);
 				return 0;
-				}
 			}
 		}
+	}
 	dprintf_midi(stddeb, "MIDI_ReadLong // error reading wDevID=%04X\n", wDevID);
 	return MCIERR_INTERNAL;
 }
 
 
 /**************************************************************************
-* 				MIDI_ReadVaryLen		[internal]	
-*/
+ *  				MIDI_ReadVaryLen		[internal]	
+ */
 static DWORD MIDI_ReadVaryLen(UINT16 wDevID, LPDWORD lpdw)
 {
 	BYTE	byte;
@@ -204,15 +204,15 @@
 	if (MIDI_ReadByte(wDevID, &byte) != 0) {
 		dprintf_midi(stddeb, "MIDI_ReadVaryLen // error reading wDevID=%04X\n", wDevID);
 		return MCIERR_INTERNAL;
-		}
+	}
 	value = (DWORD)(byte & 0x7F);
 	while (byte & 0x80) {
 		if (MIDI_ReadByte(wDevID, &byte) != 0) {
 			dprintf_midi(stddeb, "MIDI_ReadVaryLen // error reading wDevID=%04X\n", wDevID);
 			return MCIERR_INTERNAL;
-			}
-		value = (value << 7) + (byte & 0x7F);
 		}
+		value = (value << 7) + (byte & 0x7F);
+	}
 	*lpdw = value;
 /*
 	dprintf_midi(stddeb, "MIDI_ReadVaryLen // val=%08lX \n", value);
@@ -222,8 +222,8 @@
 
 
 /**************************************************************************
-* 				MIDI_ReadMThd			[internal]	
-*/
+ * 				MIDI_ReadMThd			[internal]	
+ */
 static DWORD MIDI_ReadMThd(UINT16 wDevID, DWORD dwOffset)
 {
 #if defined(linux) || defined(__FreeBSD__)
@@ -233,23 +233,18 @@
 	if (mmioSeek(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
 		dprintf_midi(stddeb, "MIDI_ReadMThd // can't seek at %08lX begin of 'MThd' \n", dwOffset);
 		return MCIERR_INTERNAL;
-		}
+	}
 	if (mmioRead(MCIMidiDev[wDevID].hFile, (HPSTR)&fourcc,
-		(long) sizeof(FOURCC)) != (long) sizeof(FOURCC)) {
+		(long) sizeof(FOURCC)) != (long) sizeof(FOURCC))
 		return MCIERR_INTERNAL;
-		}
-	if (MIDI_ReadLong(wDevID, &toberead) != 0) {
+	if (MIDI_ReadLong(wDevID, &toberead) != 0)
 		return MCIERR_INTERNAL;
-		}
-	if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].wFormat) != 0) {
+	if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].wFormat) != 0)
 		return MCIERR_INTERNAL;
-		}
-	if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].nTracks) != 0) {
+	if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].nTracks) != 0)
 		return MCIERR_INTERNAL;
-		}
-	if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].nTempo) != 0) {
+	if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].nTempo) != 0)
 		return MCIERR_INTERNAL;
-		}
 	dprintf_midi(stddeb, "MIDI_ReadMThd // toberead=%08lX, wFormat=%04X nTracks=%04X nTempo=%04X\n",
 		toberead, MCIMidiDev[wDevID].wFormat,
 		MCIMidiDev[wDevID].nTracks,
@@ -260,9 +255,8 @@
 		Mf_division = division = read16bit ();
 */
 	return 0;
-
 #else
-         return MMSYSERR_NOTENABLED;
+	return MMSYSERR_NOTENABLED;
 #endif
 }
 
@@ -293,9 +287,9 @@
 
 
 /**************************************************************************
-* 				MIDI_mciOpen			[internal]	
-*/
-static DWORD MIDI_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS lpParms)
+ * 				MIDI_mciOpen			[internal]	
+ */
+static DWORD MIDI_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS16 lpParms)
 {
 #if defined(linux) || defined(__FreeBSD__)
 	MIDIOPENDESC 	MidiDesc;
@@ -315,12 +309,11 @@
 			++MCIMidiDev[wDevID].nUseCount;
 		else
 			return MCIERR_MUST_USE_SHAREABLE;
-		}
-	else {
+	} else {
 		MCIMidiDev[wDevID].nUseCount = 1;
 		MCIMidiDev[wDevID].fShareable = dwFlags & MCI_OPEN_SHAREABLE;
 		MCIMidiDev[wDevID].hMidiHdr = USER_HEAP_ALLOC(sizeof(MIDIHDR));
-		}
+	}
 
 	dprintf_midi(stddeb, "MIDI_mciOpen // wDevID=%04X\n", wDevID);
 /*	lpParms->wDeviceID = wDevID;*/
@@ -332,18 +325,17 @@
 		if (strlen(lpstrElementName) > 0) {
 			strcpy(str, lpstrElementName);
 			CharUpper32A(str);
-			MCIMidiDev[wDevID].hFile = mmioOpen(str, NULL, 
+			MCIMidiDev[wDevID].hFile = mmioOpen16(str, NULL, 
 				MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_EXCLUSIVE);
 			if (MCIMidiDev[wDevID].hFile == 0) {
 				dprintf_midi(stddeb, "MIDI_mciOpen // can't find file='%s' !\n", str);
 				return MCIERR_FILE_NOT_FOUND;
-				}
 			}
-		else 
+		} else 
 			MCIMidiDev[wDevID].hFile = 0;
-		}
+	}
 	dprintf_midi(stddeb, "MIDI_mciOpen // hFile=%u\n", MCIMidiDev[wDevID].hFile);
-	memcpy(&MCIMidiDev[wDevID].openParms, lpParms, sizeof(MCI_OPEN_PARMS));
+	memcpy(&MCIMidiDev[wDevID].openParms, lpParms, sizeof(MCI_OPEN_PARMS16));
 	MCIMidiDev[wDevID].wNotifyDeviceID = lpParms->wDeviceID;
 	MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
 	MCIMidiDev[wDevID].dwBeginData = 0;
@@ -353,7 +345,7 @@
 		MMCKINFO	ckMainRIFF;
 		if (mmioDescend(MCIMidiDev[wDevID].hFile, &ckMainRIFF, NULL, 0) != 0) {
 			return MCIERR_INTERNAL;
-			}
+		}
 		dprintf_midi(stddeb,"MIDI_mciOpen // ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
 				(LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
 				ckMainRIFF.cksize);
@@ -361,26 +353,26 @@
 		if (ckMainRIFF.ckid == mmioFOURCC('R', 'M', 'I', 'D')) {
 			dprintf_midi(stddeb, "MIDI_mciOpen // is a 'RMID' file \n");
 			dwOffset = ckMainRIFF.dwDataOffset;
-			}
+		}
 		if (ckMainRIFF.ckid != mmioFOURCC('M', 'T', 'h', 'd')) {
 			dprintf_midi(stddeb, "MIDI_mciOpen // unknown format !\n");
 			return MCIERR_INTERNAL;
-			}
+		}
 		if (MIDI_ReadMThd(wDevID, dwOffset) != 0) {
 			dprintf_midi(stddeb, "MIDI_mciOpen // can't read 'MThd' header \n");
 			return MCIERR_INTERNAL;
-			}
+		}
 		dwOffset = mmioSeek(MCIMidiDev[wDevID].hFile, 0, SEEK_CUR);
 		if (MIDI_ReadMTrk(wDevID, dwOffset) != 0) {
 			dprintf_midi(stddeb, "MIDI_mciOpen // can't read 'MTrk' header \n");
 			return MCIERR_INTERNAL;
-			}
+		}
 		dwOffset = mmioSeek(MCIMidiDev[wDevID].hFile, 0, SEEK_CUR);
 		MCIMidiDev[wDevID].dwBeginData = dwOffset;
 		dprintf_midi(stddeb, "MIDI_mciOpen // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
 				(LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
 				ckMainRIFF.cksize);
-		}
+	}
 
 	dwRet = modMessage(wDevID, MODM_OPEN, 0, (DWORD)&MidiDesc, CALLBACK_NULL);
 /*	dwRet = midMessage(wDevID, MIDM_OPEN, 0, (DWORD)&MidiDesc, CALLBACK_NULL);*/
@@ -392,8 +384,8 @@
 }
 
 /**************************************************************************
-* 				MIDI_mciStop			[internal]
-*/
+ * 				MIDI_mciStop			[internal]
+ */
 static DWORD MIDI_mciStop(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
 #if defined(linux) || defined(__FreeBSD__)
@@ -410,8 +402,8 @@
 
 
 /**************************************************************************
-* 				MIDI_mciClose		[internal]
-*/
+ * 				MIDI_mciClose		[internal]
+ */
 static DWORD MIDI_mciClose(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
 {
 #if defined(linux) || defined(__FreeBSD__)
@@ -445,60 +437,56 @@
 
 
 /**************************************************************************
-* 				MIDI_mciPlay		[internal]
-*/
+ * 				MIDI_mciPlay		[internal]
+ */
 static DWORD MIDI_mciPlay(UINT16 wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
 {
 #if defined(linux) || defined(__FreeBSD__)
-	int			count;
-	int			start, end;
+	int		count,start,end;
 	LPMIDIHDR	lpMidiHdr;
-	DWORD           lp16MidiHdr;
-	DWORD		dwData;
+	DWORD		dwData,dwRet;
 	LPWORD		ptr;
-	DWORD		dwRet;
 
 	dprintf_midi(stddeb, "MIDI_mciPlay(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (MCIMidiDev[wDevID].hFile == 0) {
 		dprintf_midi(stddeb, "MIDI_mciPlay // can't find file='%08lx' !\n", 
-				MCIMidiDev[wDevID].openParms.lpstrElementName);
+				(DWORD)MCIMidiDev[wDevID].openParms.lpstrElementName);
 		return MCIERR_FILE_NOT_FOUND;
-		}
+	}
 	start = 1; 		end = 99999;
 	if (dwFlags & MCI_FROM) {
 		start = lpParms->dwFrom; 
 		dprintf_midi(stddeb, "MIDI_mciPlay // MCI_FROM=%d \n", start);
-		}
+	}
 	if (dwFlags & MCI_TO) {
 		end = lpParms->dwTo;
 		dprintf_midi(stddeb, "MIDI_mciPlay // MCI_TO=%d \n", end);
-		}
+	}
 #if 0
 	if (dwFlags & MCI_NOTIFY) {
 		dprintf_midi(stddeb, "MIDI_mciPlay // MCI_NOTIFY %08lX !\n", lpParms->dwCallback);
 		switch(fork()) {
-			case -1:
-				dprintf_midi(stddeb, "MIDI_mciPlay // Can't 'fork' process !\n");
-				break;
-			case 0:
-				dprintf_midi(stddeb, "MIDI_mciPlay // process started ! play in background ...\n");
-				break;
-			default:
-				dprintf_midi(stddeb, "MIDI_mciPlay // process started ! return to caller...\n");
-				return 0;
-			}
+		case -1:
+			dprintf_midi(stddeb, "MIDI_mciPlay // Can't 'fork' process !\n");
+			break;
+		case 0:
+			dprintf_midi(stddeb, "MIDI_mciPlay // process started ! play in background ...\n");
+			break;
+		default:
+			dprintf_midi(stddeb, "MIDI_mciPlay // process started ! return to caller...\n");
+			return 0;
 		}
+	}
 #endif
 
 	lpMidiHdr = USER_HEAP_LIN_ADDR(MCIMidiDev[wDevID].hMidiHdr);
-	lp16MidiHdr = USER_HEAP_SEG_ADDR(MCIMidiDev[wDevID].hMidiHdr);
 
-	lpMidiHdr->lpData = (LPSTR) malloc(1200);
+	lpMidiHdr->lpData = (LPSTR)xmalloc(1200);
 	if (lpMidiHdr->lpData == NULL) return MCIERR_INTERNAL;
 	lpMidiHdr->dwBufferLength = 1024;
 	lpMidiHdr->dwUser = 0L;
 	lpMidiHdr->dwFlags = 0L;
-	dwRet = modMessage(wDevID, MODM_PREPARE, 0, (DWORD)lp16MidiHdr, sizeof(MIDIHDR));
+	dwRet = modMessage(wDevID, MODM_PREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
 
 /*	dprintf_midi(stddeb, "MIDI_mciPlay // after MODM_PREPARE \n"); */
 
@@ -511,7 +499,7 @@
 		for (count = 0; count < lpMidiHdr->dwBufferLength; count++) {
 			if (MIDI_ReadVaryLen(wDevID, &dwData) != 0) break;
 			*ptr = LOWORD(dwData);
-			}
+		}
 /*
 		count = mmioRead(MCIMidiDev[wDevID].hFile, lpMidiHdr->lpData, lpMidiHdr->dwBufferLength);
 */
@@ -521,7 +509,7 @@
 		lpMidiHdr->dwBytesRecorded = count;
 		dprintf_midi(stddeb, "MIDI_mciPlay // before MODM_LONGDATA lpMidiHdr=%p dwBytesRecorded=%lu\n",
 					lpMidiHdr, lpMidiHdr->dwBytesRecorded);
-		dwRet = modMessage(wDevID, MODM_LONGDATA, 0, (DWORD)lp16MidiHdr, sizeof(MIDIHDR));
+		dwRet = modMessage(wDevID, MODM_LONGDATA, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
 		if (dwRet != MMSYSERR_NOERROR) {
 		  switch (dwRet) {
 		  case MMSYSERR_NOTENABLED:
@@ -544,11 +532,11 @@
 		  }	
 		}
 	      }
-	dwRet = modMessage(wDevID, MODM_UNPREPARE, 0, (DWORD)lp16MidiHdr, sizeof(MIDIHDR));
+	dwRet = modMessage(wDevID, MODM_UNPREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
 	if (lpMidiHdr->lpData != NULL) {
 		free(lpMidiHdr->lpData);
 		lpMidiHdr->lpData = NULL;
-	      }
+	}
 	MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
 	if (dwFlags & MCI_NOTIFY) {
 		dprintf_midi(stddeb, "MIDI_mciPlay // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
@@ -557,7 +545,7 @@
 #if 0
 		exit(1);
 #endif
-	      }
+	}
 	return 0;
 #else
 	return MMSYSERR_NOTENABLED;
@@ -566,8 +554,8 @@
 
 
 /**************************************************************************
-* 				MIDI_mciRecord			[internal]
-*/
+ * 				MIDI_mciRecord			[internal]
+ */
 static DWORD MIDI_mciRecord(UINT16 wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms)
 {
 #if defined(linux) || defined(__FreeBSD__)
@@ -578,18 +566,18 @@
 	dprintf_midi(stddeb, "MIDI_mciRecord(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (MCIMidiDev[wDevID].hFile == 0) {
 		dprintf_midi(stddeb, "MIDI_mciRecord // can't find file='%08lx' !\n", 
-				MCIMidiDev[wDevID].openParms.lpstrElementName);
+			(DWORD)MCIMidiDev[wDevID].openParms.lpstrElementName);
 		return MCIERR_FILE_NOT_FOUND;
-		}
+	}
 	start = 1; 		end = 99999;
 	if (dwFlags & MCI_FROM) {
 		start = lpParms->dwFrom; 
 		dprintf_midi(stddeb, "MIDI_mciRecord // MCI_FROM=%d \n", start);
-		}
+	}
 	if (dwFlags & MCI_TO) {
 		end = lpParms->dwTo;
 		dprintf_midi(stddeb, "MIDI_mciRecord // MCI_TO=%d \n", end);
-		}
+	}
 	lpMidiHdr = USER_HEAP_LIN_ADDR(MCIMidiDev[wDevID].hMidiHdr);
 	lpMidiHdr->lpData = (LPSTR) xmalloc(1200);
 	lpMidiHdr->dwBufferLength = 1024;
@@ -606,20 +594,20 @@
 		dprintf_midi(stddeb, "MIDI_mciRecord // after MIDM_START lpMidiHdr=%p dwBytesRecorded=%lu\n",
 					lpMidiHdr, lpMidiHdr->dwBytesRecorded);
 		if (lpMidiHdr->dwBytesRecorded == 0) break;
-		}
+	}
 	dprintf_midi(stddeb, "MIDI_mciRecord // before MIDM_UNPREPARE \n");
 	dwRet = midMessage(wDevID, MIDM_UNPREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
 	dprintf_midi(stddeb, "MIDI_mciRecord // after MIDM_UNPREPARE \n");
 	if (lpMidiHdr->lpData != NULL) {
 		free(lpMidiHdr->lpData);
 		lpMidiHdr->lpData = NULL;
-		}
+	}
 	MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
 	if (dwFlags & MCI_NOTIFY) {
 		dprintf_midi(stddeb, "MIDI_mciRecord // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
 		mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback), 
 			MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
-		}
+	}
 	return 0;
 #else
 	return MMSYSERR_NOTENABLED;
@@ -628,8 +616,8 @@
 
 
 /**************************************************************************
-* 				MIDI_mciPause			[internal]
-*/
+ * 				MIDI_mciPause			[internal]
+ */
 static DWORD MIDI_mciPause(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
 #if defined(linux) || defined(__FreeBSD__)
@@ -643,8 +631,8 @@
 
 
 /**************************************************************************
-* 				MIDI_mciResume			[internal]
-*/
+ * 				MIDI_mciResume			[internal]
+ */
 static DWORD MIDI_mciResume(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
 #if defined(linux) || defined(__FreeBSD__)
@@ -658,8 +646,8 @@
 
 
 /**************************************************************************
-* 				MIDI_mciSet			[internal]
-*/
+ * 				MIDI_mciSet			[internal]
+ */
 static DWORD MIDI_mciSet(UINT16 wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
 {
 #if defined(linux) || defined(__FreeBSD__)
@@ -669,53 +657,44 @@
 	dprintf_midi(stddeb, "MIDI_mciSet // dwAudio=%08lX\n", lpParms->dwAudio);
 	if (dwFlags & MCI_SET_TIME_FORMAT) {
 		switch (lpParms->dwTimeFormat) {
-			case MCI_FORMAT_MILLISECONDS:
-				dprintf_midi(stddeb, "MIDI_mciSet // MCI_FORMAT_MILLISECONDS !\n");
-				break;
-			case MCI_FORMAT_BYTES:
-				dprintf_midi(stddeb, "MIDI_mciSet // MCI_FORMAT_BYTES !\n");
-				break;
-			case MCI_FORMAT_SAMPLES:
-				dprintf_midi(stddeb, "MIDI_mciSet // MCI_FORMAT_SAMPLES !\n");
-				break;
-			default:
-				dprintf_midi(stddeb, "MIDI_mciSet // bad time format !\n");
-				return MCIERR_BAD_TIME_FORMAT;
-			}
+		case MCI_FORMAT_MILLISECONDS:
+			dprintf_midi(stddeb, "MIDI_mciSet // MCI_FORMAT_MILLISECONDS !\n");
+			break;
+		case MCI_FORMAT_BYTES:
+			dprintf_midi(stddeb, "MIDI_mciSet // MCI_FORMAT_BYTES !\n");
+			break;
+		case MCI_FORMAT_SAMPLES:
+			dprintf_midi(stddeb, "MIDI_mciSet // MCI_FORMAT_SAMPLES !\n");
+			break;
+		default:
+			dprintf_midi(stddeb, "MIDI_mciSet // bad time format !\n");
+			return MCIERR_BAD_TIME_FORMAT;
 		}
+	}
 	if (dwFlags & MCI_SET_VIDEO) return MCIERR_UNSUPPORTED_FUNCTION;
 	if (dwFlags & MCI_SET_DOOR_OPEN) return MCIERR_UNSUPPORTED_FUNCTION;
 	if (dwFlags & MCI_SET_DOOR_CLOSED) return MCIERR_UNSUPPORTED_FUNCTION;
-	if (dwFlags & MCI_SET_AUDIO) {
+	if (dwFlags & MCI_SET_AUDIO)
 		dprintf_midi(stddeb, "MIDI_mciSet // MCI_SET_AUDIO !\n");
-		}
 	if (dwFlags && MCI_SET_ON) {
 		dprintf_midi(stddeb, "MIDI_mciSet // MCI_SET_ON !\n");
-		if (dwFlags && MCI_SET_AUDIO_LEFT) {
+		if (dwFlags && MCI_SET_AUDIO_LEFT)
 			dprintf_midi(stddeb, "MIDI_mciSet // MCI_SET_AUDIO_LEFT !\n");
-			}
-		if (dwFlags && MCI_SET_AUDIO_RIGHT) {
+		if (dwFlags && MCI_SET_AUDIO_RIGHT)
 			dprintf_midi(stddeb, "MIDI_mciSet // MCI_SET_AUDIO_RIGHT !\n");
-			}
-		}
-	if (dwFlags & MCI_SET_OFF) {
+	}
+	if (dwFlags & MCI_SET_OFF)
 		dprintf_midi(stddeb, "MIDI_mciSet // MCI_SET_OFF !\n");
-		}
-	if (dwFlags & MCI_SEQ_SET_MASTER) {
+	if (dwFlags & MCI_SEQ_SET_MASTER)
 		dprintf_midi(stddeb, "MIDI_mciSet // MCI_SEQ_SET_MASTER !\n");
-		}
-	if (dwFlags & MCI_SEQ_SET_SLAVE) {
+	if (dwFlags & MCI_SEQ_SET_SLAVE)
 		dprintf_midi(stddeb, "MIDI_mciSet // MCI_SEQ_SET_SLAVE !\n");
-		}
-	if (dwFlags & MCI_SEQ_SET_OFFSET) {
+	if (dwFlags & MCI_SEQ_SET_OFFSET)
 		dprintf_midi(stddeb, "MIDI_mciSet // MCI_SEQ_SET_OFFSET !\n");
-		}
-	if (dwFlags & MCI_SEQ_SET_PORT) {
+	if (dwFlags & MCI_SEQ_SET_PORT)
 		dprintf_midi(stddeb, "MIDI_mciSet // MCI_SEQ_SET_PORT !\n");
-		}
-	if (dwFlags & MCI_SEQ_SET_TEMPO) {
+	if (dwFlags & MCI_SEQ_SET_TEMPO)
 		dprintf_midi(stddeb, "MIDI_mciSet // MCI_SEQ_SET_TEMPO !\n");
-		}
  	return 0;
 #else
 	return MCIERR_INTERNAL;
@@ -724,8 +703,8 @@
 
 
 /**************************************************************************
-* 				MIDI_mciStatus		[internal]
-*/
+ * 				MIDI_mciStatus		[internal]
+ */
 static DWORD MIDI_mciStatus(UINT16 wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
 {
 #if defined(linux) || defined(__FreeBSD__)
@@ -733,78 +712,77 @@
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	if (dwFlags & MCI_STATUS_ITEM) {
 		switch(lpParms->dwItem) {
-			case MCI_STATUS_CURRENT_TRACK:
-				lpParms->dwReturn = 1;
-				break;
-			case MCI_STATUS_LENGTH:
-				lpParms->dwReturn = 5555;
-				if (dwFlags & MCI_TRACK) {
-					lpParms->dwTrack = 1;
-					lpParms->dwReturn = 2222;
-					}
-				break;
-			case MCI_STATUS_MODE:
-				lpParms->dwReturn = MCI_MODE_STOP;
-				break;
-			case MCI_STATUS_MEDIA_PRESENT:
-				dprintf_midi(stddeb, "MIDI_mciStatus // MCI_STATUS_MEDIA_PRESENT !\n");
-				lpParms->dwReturn = TRUE;
-				break;
-			case MCI_STATUS_NUMBER_OF_TRACKS:
-				lpParms->dwReturn = 1;
-				break;
-			case MCI_STATUS_POSITION:
-				lpParms->dwReturn = 3333;
-				if (dwFlags & MCI_STATUS_START) {
-					lpParms->dwItem = 1;
-					}
-				if (dwFlags & MCI_TRACK) {
-					lpParms->dwTrack = 1;
-					lpParms->dwReturn = 777;
-					}
-				break;
-			case MCI_STATUS_READY:
-				dprintf_midi(stddeb, "MIDI_mciStatus // MCI_STATUS_READY !\n");
-				lpParms->dwReturn = TRUE;
-				break;
-			case MCI_STATUS_TIME_FORMAT:
-				dprintf_midi(stddeb, "MIDI_mciStatus // MCI_STATUS_TIME_FORMAT !\n");
-				lpParms->dwReturn = MCI_FORMAT_MILLISECONDS;
-				break;
-			case MCI_SEQ_STATUS_DIVTYPE:
-				dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_DIVTYPE !\n");
-				lpParms->dwReturn = 0;
-				break;
-			case MCI_SEQ_STATUS_MASTER:
-				dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_MASTER !\n");
-				lpParms->dwReturn = 0;
-				break;
-			case MCI_SEQ_STATUS_SLAVE:
-				dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_SLAVE !\n");
-				lpParms->dwReturn = 0;
-				break;
-			case MCI_SEQ_STATUS_OFFSET:
-				dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_OFFSET !\n");
-				lpParms->dwReturn = 0;
-				break;
-			case MCI_SEQ_STATUS_PORT:
-				dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_PORT !\n");
-				lpParms->dwReturn = 0;
-				break;
-			case MCI_SEQ_STATUS_TEMPO:
-				dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_TEMPO !\n");
-				lpParms->dwReturn = 0;
-				break;
-			default:
-				dprintf_midi(stddeb, "MIDI_mciStatus // unknowm command %08lX !\n", lpParms->dwItem);
-				return MCIERR_UNRECOGNIZED_COMMAND;
+		case MCI_STATUS_CURRENT_TRACK:
+			lpParms->dwReturn = 1;
+			break;
+		case MCI_STATUS_LENGTH:
+			lpParms->dwReturn = 5555;
+			if (dwFlags & MCI_TRACK) {
+				lpParms->dwTrack = 1;
+				lpParms->dwReturn = 2222;
 			}
+			break;
+		case MCI_STATUS_MODE:
+			lpParms->dwReturn = MCI_MODE_STOP;
+			break;
+		case MCI_STATUS_MEDIA_PRESENT:
+			dprintf_midi(stddeb, "MIDI_mciStatus // MCI_STATUS_MEDIA_PRESENT !\n");
+			lpParms->dwReturn = TRUE;
+			break;
+		case MCI_STATUS_NUMBER_OF_TRACKS:
+			lpParms->dwReturn = 1;
+			break;
+		case MCI_STATUS_POSITION:
+			lpParms->dwReturn = 3333;
+			if (dwFlags & MCI_STATUS_START)
+				lpParms->dwItem = 1;
+			if (dwFlags & MCI_TRACK) {
+				lpParms->dwTrack = 1;
+				lpParms->dwReturn = 777;
+			}
+			break;
+		case MCI_STATUS_READY:
+			dprintf_midi(stddeb, "MIDI_mciStatus // MCI_STATUS_READY !\n");
+			lpParms->dwReturn = TRUE;
+			break;
+		case MCI_STATUS_TIME_FORMAT:
+			dprintf_midi(stddeb, "MIDI_mciStatus // MCI_STATUS_TIME_FORMAT !\n");
+			lpParms->dwReturn = MCI_FORMAT_MILLISECONDS;
+			break;
+		case MCI_SEQ_STATUS_DIVTYPE:
+			dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_DIVTYPE !\n");
+			lpParms->dwReturn = 0;
+			break;
+		case MCI_SEQ_STATUS_MASTER:
+			dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_MASTER !\n");
+			lpParms->dwReturn = 0;
+			break;
+		case MCI_SEQ_STATUS_SLAVE:
+			dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_SLAVE !\n");
+			lpParms->dwReturn = 0;
+			break;
+		case MCI_SEQ_STATUS_OFFSET:
+			dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_OFFSET !\n");
+			lpParms->dwReturn = 0;
+			break;
+		case MCI_SEQ_STATUS_PORT:
+			dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_PORT !\n");
+			lpParms->dwReturn = 0;
+			break;
+		case MCI_SEQ_STATUS_TEMPO:
+			dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_TEMPO !\n");
+			lpParms->dwReturn = 0;
+			break;
+		default:
+			dprintf_midi(stddeb, "MIDI_mciStatus // unknowm command %08lX !\n", lpParms->dwItem);
+			return MCIERR_UNRECOGNIZED_COMMAND;
 		}
+	}
 	if (dwFlags & MCI_NOTIFY) {
 		dprintf_midi(stddeb, "MIDI_mciStatus // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
 		mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback), 
 			MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
-		}
+	}
  	return 0;
 #else
 	return MCIERR_INTERNAL;
@@ -812,8 +790,8 @@
 }
 
 /**************************************************************************
-* 				MIDI_mciGetDevCaps		[internal]
-*/
+ * 				MIDI_mciGetDevCaps		[internal]
+ */
 static DWORD MIDI_mciGetDevCaps(UINT16 wDevID, DWORD dwFlags, 
 					LPMCI_GETDEVCAPS_PARMS lpParms)
 {
@@ -822,37 +800,37 @@
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	if (dwFlags & MCI_GETDEVCAPS_ITEM) {
 		switch(lpParms->dwItem) {
-			case MCI_GETDEVCAPS_CAN_RECORD:
-				lpParms->dwReturn = TRUE;
-				break;
-			case MCI_GETDEVCAPS_HAS_AUDIO:
-				lpParms->dwReturn = TRUE;
-				break;
-			case MCI_GETDEVCAPS_HAS_VIDEO:
-				lpParms->dwReturn = FALSE;
-				break;
-			case MCI_GETDEVCAPS_DEVICE_TYPE:
-				lpParms->dwReturn = MCI_DEVTYPE_SEQUENCER;
-				break;
-			case MCI_GETDEVCAPS_USES_FILES:
-				lpParms->dwReturn = TRUE;
-				break;
-			case MCI_GETDEVCAPS_COMPOUND_DEVICE:
-				lpParms->dwReturn = TRUE;
-				break;
-			case MCI_GETDEVCAPS_CAN_EJECT:
-				lpParms->dwReturn = FALSE;
-				break;
-			case MCI_GETDEVCAPS_CAN_PLAY:
-				lpParms->dwReturn = TRUE;
-				break;
-			case MCI_GETDEVCAPS_CAN_SAVE:
-				lpParms->dwReturn = FALSE;
-				break;
-			default:
-				return MCIERR_UNRECOGNIZED_COMMAND;
-			}
+		case MCI_GETDEVCAPS_CAN_RECORD:
+			lpParms->dwReturn = TRUE;
+			break;
+		case MCI_GETDEVCAPS_HAS_AUDIO:
+			lpParms->dwReturn = TRUE;
+			break;
+		case MCI_GETDEVCAPS_HAS_VIDEO:
+			lpParms->dwReturn = FALSE;
+			break;
+		case MCI_GETDEVCAPS_DEVICE_TYPE:
+			lpParms->dwReturn = MCI_DEVTYPE_SEQUENCER;
+			break;
+		case MCI_GETDEVCAPS_USES_FILES:
+			lpParms->dwReturn = TRUE;
+			break;
+		case MCI_GETDEVCAPS_COMPOUND_DEVICE:
+			lpParms->dwReturn = TRUE;
+			break;
+		case MCI_GETDEVCAPS_CAN_EJECT:
+			lpParms->dwReturn = FALSE;
+			break;
+		case MCI_GETDEVCAPS_CAN_PLAY:
+			lpParms->dwReturn = TRUE;
+			break;
+		case MCI_GETDEVCAPS_CAN_SAVE:
+			lpParms->dwReturn = FALSE;
+			break;
+		default:
+			return MCIERR_UNRECOGNIZED_COMMAND;
 		}
+	}
  	return 0;
 #else
 	return MCIERR_INTERNAL;
@@ -860,24 +838,24 @@
 }
 
 /**************************************************************************
-* 				MIDI_mciInfo			[internal]
-*/
-static DWORD MIDI_mciInfo(UINT16 wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms)
+ * 				MIDI_mciInfo			[internal]
+ */
+static DWORD MIDI_mciInfo(UINT16 wDevID, DWORD dwFlags, LPMCI_INFO_PARMS16 lpParms)
 {
 #if defined(linux) || defined(__FreeBSD__)
 	dprintf_midi(stddeb, "MIDI_mciInfo(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	lpParms->lpstrReturn = NULL;
 	switch(dwFlags) {
-		case MCI_INFO_PRODUCT:
-			lpParms->lpstrReturn = "Linux Sound System 0.5";
-			break;
-		case MCI_INFO_FILE:
-			lpParms->lpstrReturn = "FileName";
-			break;
-		default:
-			return MCIERR_UNRECOGNIZED_COMMAND;
-		}
+	case MCI_INFO_PRODUCT:
+		lpParms->lpstrReturn = "Linux Sound System 0.5";
+		break;
+	case MCI_INFO_FILE:
+		lpParms->lpstrReturn = "FileName";
+		break;
+	default:
+		return MCIERR_UNRECOGNIZED_COMMAND;
+	}
 	if (lpParms->lpstrReturn != NULL)
 		lpParms->dwRetSize = strlen(lpParms->lpstrReturn);
 	else
@@ -893,9 +871,9 @@
 
 
 /**************************************************************************
-* 				midGetDevCaps			[internal]
-*/
-static DWORD midGetDevCaps(WORD wDevID, LPMIDIINCAPS lpCaps, DWORD dwSize)
+ * 				midGetDevCaps			[internal]
+ */
+static DWORD midGetDevCaps(WORD wDevID, LPMIDIINCAPS16 lpCaps, DWORD dwSize)
 {
 	dprintf_midi(stddeb, "midGetDevCaps(%04X, %p, %08lX);\n", wDevID, lpCaps, dwSize);
 	lpCaps->wMid = 0x00FF; 	        /* Manufac ID */
@@ -907,8 +885,8 @@
 }
 
 /**************************************************************************
-* 				midOpen					[internal]
-*/
+ * 			midOpen					[internal]
+ */
 static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
 {
 #if defined(linux) || defined(__FreeBSD__)
@@ -918,17 +896,17 @@
 	if (lpDesc == NULL) {
 		dprintf_midi(stddeb,"Linux 'midOpen' // Invalid Parameter !\n");
 		return MMSYSERR_INVALPARAM;
-		}
+	}
 	if (wDevID >= MAX_MIDIINDRV) {
 		dprintf_midi(stddeb,"Linux 'midOpen' // MAX_MIDIINDRV reached !\n");
 		return MMSYSERR_ALLOCATED;
-		}
+	}
 	MidiInDev[wDevID].unixdev = 0;
 	midi = open (MIDI_DEV, O_RDONLY, 0);
 	if (midi == -1) {
 		dprintf_midi(stddeb,"Linux 'midOpen' // can't open !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
 	MidiInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
 	switch(MidiInDev[wDevID].wFlags) {
 		case DCB_NULL:
@@ -946,7 +924,7 @@
 			dprintf_midi(stddeb,
 				   "Linux 'midOpen' // CALLBACK_FUNCTION !\n");
 			break;
-		}
+	}
 	MidiInDev[wDevID].lpQueueHdr = NULL;
 	MidiInDev[wDevID].unixdev = midi;
 	MidiInDev[wDevID].dwTotalPlayed = 0;
@@ -954,7 +932,7 @@
 	if (MIDI_NotifyClient(wDevID, MIM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
 		dprintf_midi(stddeb,"Linux 'midOpen' // can't notify client !\n");
 		return MMSYSERR_INVALPARAM;
-		}
+	}
 	return MMSYSERR_NOERROR;
 #else
 	return MMSYSERR_NOTENABLED;
@@ -962,8 +940,8 @@
 }
 
 /**************************************************************************
-* 				midClose				[internal]
-*/
+ * 			midClose				[internal]
+ */
 static DWORD midClose(WORD wDevID)
 {
 #if defined(linux) || defined(__FreeBSD__)
@@ -971,14 +949,14 @@
 	if (MidiInDev[wDevID].unixdev == 0) {
 		dprintf_midi(stddeb,"Linux 'midClose' // can't close !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
 	close(MidiInDev[wDevID].unixdev);
 	MidiInDev[wDevID].unixdev = 0;
 	MidiInDev[wDevID].bufsize = 0;
 	if (MIDI_NotifyClient(wDevID, MIM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
 		dprintf_midi(stddeb,"Linux 'midClose' // can't notify client !\n");
 		return MMSYSERR_INVALPARAM;
-		}
+	}
 	return MMSYSERR_NOERROR;
 #else
 	return MMSYSERR_NOTENABLED;
@@ -986,8 +964,8 @@
 }
 
 /**************************************************************************
-* 				midAddBuffer		[internal]
-*/
+ * 				midAddBuffer		[internal]
+ */
 static DWORD midAddBuffer(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
 {
 	dprintf_midi(stddeb, "midAddBuffer(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
@@ -995,8 +973,8 @@
 }
 
 /**************************************************************************
-* 				midPrepare			[internal]
-*/
+ * 				midPrepare			[internal]
+ */
 static DWORD midPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
 {
 	dprintf_midi(stddeb, "midPrepare(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
@@ -1004,8 +982,8 @@
 }
 
 /**************************************************************************
-* 				midUnprepare			[internal]
-*/
+ * 				midUnprepare			[internal]
+ */
 static DWORD midUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
 {
 	dprintf_midi(stddeb, "midUnprepare(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
@@ -1013,8 +991,8 @@
 }
 
 /**************************************************************************
-* 				midReset				[internal]
-*/
+ * 			midReset				[internal]
+ */
 static DWORD midReset(WORD wDevID)
 {
 	dprintf_midi(stddeb, "midReset(%04X);\n", wDevID);
@@ -1023,8 +1001,8 @@
 
 
 /**************************************************************************
-* 				midStart				[internal]
-*/
+ * 			midStart				[internal]
+ */
 static DWORD midStart(WORD wDevID)
 {
 	dprintf_midi(stddeb, "midStart(%04X);\n", wDevID);
@@ -1033,8 +1011,8 @@
 
 
 /**************************************************************************
-* 				midStop					[internal]
-*/
+ *			midStop					[internal]
+ */
 static DWORD midStop(WORD wDevID)
 {
 	dprintf_midi(stddeb, "midStop(%04X);\n", wDevID);
@@ -1043,35 +1021,35 @@
 
 
 /**************************************************************************
-* 				midMessage				[sample driver]
-*/
+ * 			midMessage				[sample driver]
+ */
 DWORD midMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
 					DWORD dwParam1, DWORD dwParam2)
 {
 	dprintf_midi(stddeb, "midMessage(%04X, %04X, %08lX, %08lX, %08lX);\n", 
 			wDevID, wMsg, dwUser, dwParam1, dwParam2);
 	switch(wMsg) {
-		case MIDM_OPEN:
-			return midOpen(wDevID, (LPMIDIOPENDESC)PTR_SEG_TO_LIN(dwParam1), dwParam2);
-		case MIDM_CLOSE:
-			return midClose(wDevID);
-		case MIDM_ADDBUFFER:
-			return midAddBuffer(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
-		case MIDM_PREPARE:
-			return midPrepare(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
-		case MIDM_UNPREPARE:
-			return midUnprepare(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
-		case MIDM_GETDEVCAPS:
-			return midGetDevCaps(wDevID, (LPMIDIINCAPS)PTR_SEG_TO_LIN(dwParam1), dwParam2);
-		case MIDM_GETNUMDEVS:
-			return 0;
-		case MIDM_RESET:
-			return midReset(wDevID);
-		case MIDM_START:
-			return midStart(wDevID);
-		case MIDM_STOP:
-			return midStop(wDevID);
-		}
+	case MIDM_OPEN:
+		return midOpen(wDevID,(LPMIDIOPENDESC)dwParam1, dwParam2);
+	case MIDM_CLOSE:
+		return midClose(wDevID);
+	case MIDM_ADDBUFFER:
+		return midAddBuffer(wDevID,(LPMIDIHDR)dwParam1, dwParam2);
+	case MIDM_PREPARE:
+		return midPrepare(wDevID,(LPMIDIHDR)dwParam1, dwParam2);
+	case MIDM_UNPREPARE:
+		return midUnprepare(wDevID,(LPMIDIHDR)dwParam1, dwParam2);
+	case MIDM_GETDEVCAPS:
+		return midGetDevCaps(wDevID,(LPMIDIINCAPS16)dwParam1,dwParam2);
+	case MIDM_GETNUMDEVS:
+		return 0;
+	case MIDM_RESET:
+		return midReset(wDevID);
+	case MIDM_START:
+		return midStart(wDevID);
+	case MIDM_STOP:
+		return midStop(wDevID);
+	}
 	return MMSYSERR_NOTSUPPORTED;
 }
 
@@ -1081,9 +1059,9 @@
 
 
 /**************************************************************************
-* 				modGetDevCaps			[internal]
-*/
-static DWORD modGetDevCaps(WORD wDevID, LPMIDIOUTCAPS lpCaps, DWORD dwSize)
+ * 				modGetDevCaps			[internal]
+ */
+static DWORD modGetDevCaps(WORD wDevID, LPMIDIOUTCAPS16 lpCaps, DWORD dwSize)
 {
 	dprintf_midi(stddeb, "modGetDevCaps(%04X, %p, %08lX);\n", wDevID, lpCaps, dwSize);
 	lpCaps->wMid = 0x00FF; 	/* Manufac ID */
@@ -1105,8 +1083,8 @@
 
 
 /**************************************************************************
-* 				modOpen					[internal]
-*/
+ * 			modOpen					[internal]
+ */
 static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
 {
 #if defined(linux) || defined(__FreeBSD__)
@@ -1117,35 +1095,35 @@
 	if (lpDesc == NULL) {
 		dprintf_midi(stddeb,"Linux 'modOpen' // Invalid Parameter !\n");
 		return MMSYSERR_INVALPARAM;
-		}
+	}
 	if (wDevID>= MAX_MIDIOUTDRV) {
 		dprintf_midi(stddeb,"Linux 'modOpen' // MAX_MIDIOUTDRV reached !\n");
 		return MMSYSERR_ALLOCATED;
-		}
+	}
 	MidiOutDev[wDevID].unixdev = 0;
 	midi = open (MIDI_DEV, O_WRONLY, 0);
 	if (midi == -1) {
 		dprintf_midi(stddeb,"Linux 'modOpen' // can't open !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
 	MidiOutDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
 	switch(MidiOutDev[wDevID].wFlags) {
-		case DCB_NULL:
-			dprintf_midi(stddeb,"Linux 'modOpen' // CALLBACK_NULL !\n");
-			break;
-		case DCB_WINDOW:
-			dprintf_midi(stddeb,
-				"Linux 'modOpen' // CALLBACK_WINDOW !\n");
-			break;
-		case DCB_TASK:
-			dprintf_midi(stddeb,
-				"Linux 'modOpen' // CALLBACK_TASK !\n");
-			break;
-		case DCB_FUNCTION:
-			dprintf_midi(stddeb,
-				"Linux 'modOpen' // CALLBACK_FUNCTION !\n");
-			break;
-		}
+	case DCB_NULL:
+		dprintf_midi(stddeb,"Linux 'modOpen' // CALLBACK_NULL !\n");
+		break;
+	case DCB_WINDOW:
+		dprintf_midi(stddeb,
+			"Linux 'modOpen' // CALLBACK_WINDOW !\n");
+		break;
+	case DCB_TASK:
+		dprintf_midi(stddeb,
+			"Linux 'modOpen' // CALLBACK_TASK !\n");
+		break;
+	case DCB_FUNCTION:
+		dprintf_midi(stddeb,
+			"Linux 'modOpen' // CALLBACK_FUNCTION !\n");
+		break;
+	}
 	MidiOutDev[wDevID].lpQueueHdr = NULL;
 	MidiOutDev[wDevID].unixdev = midi;
 	MidiOutDev[wDevID].dwTotalPlayed = 0;
@@ -1153,7 +1131,7 @@
 	if (MIDI_NotifyClient(wDevID, MOM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
 		dprintf_midi(stddeb,"Linux 'modOpen' // can't notify client !\n");
 		return MMSYSERR_INVALPARAM;
-		}
+	}
 	dprintf_midi(stddeb,
 		"Linux 'modOpen' // Succesful unixdev=%d !\n", midi);
 	return MMSYSERR_NOERROR;
@@ -1164,8 +1142,8 @@
 
 
 /**************************************************************************
-* 				modClose				[internal]
-*/
+ * 			modClose				[internal]
+ */
 static DWORD modClose(WORD wDevID)
 {
 #if defined(linux) || defined(__FreeBSD__)
@@ -1173,14 +1151,14 @@
 	if (MidiOutDev[wDevID].unixdev == 0) {
 		dprintf_midi(stddeb,"Linux 'modClose' // can't close !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
 	close(MidiOutDev[wDevID].unixdev);
 	MidiOutDev[wDevID].unixdev = 0;
 	MidiOutDev[wDevID].bufsize = 0;
 	if (MIDI_NotifyClient(wDevID, MOM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
 		dprintf_midi(stddeb,"Linux 'modClose' // can't notify client !\n");
 		return MMSYSERR_INVALPARAM;
-		}
+	}
 	return MMSYSERR_NOERROR;
 #else
 	return MMSYSERR_NOTENABLED;
@@ -1188,8 +1166,8 @@
 }
 
 /**************************************************************************
-* 				modData					[internal]
-*/
+ * 			modData					[internal]
+ */
 static DWORD modData(WORD wDevID, DWORD dwParam)
 {
 #if defined(linux) || defined(__FreeBSD__)
@@ -1198,15 +1176,15 @@
 	dprintf_midi(stddeb,	
 		"modData(%04X, %08lX);\n", wDevID, dwParam);
 	if (MidiOutDev[wDevID].unixdev == 0) {
-        dprintf_midi(stddeb,"Linux 'modData' // can't play !\n");
+        	dprintf_midi(stddeb,"Linux 'modData' // can't play !\n");
 		return MIDIERR_NODEVICE;
-		}
+	}
 	event = LOWORD(dwParam);
 	if (write (MidiOutDev[wDevID].unixdev, 
 		&event, sizeof(WORD)) != sizeof(WORD)) {
 		dprintf_midi(stddeb,
 			"modData() // error writting unixdev !\n");
-		}
+	}
 	return MMSYSERR_NOTENABLED;
 #else
         return MMSYSERR_NOTENABLED;
@@ -1214,8 +1192,8 @@
 }
 
 /**************************************************************************
-* 				modLongData					[internal]
-*/
+ *		modLongData					[internal]
+ */
 static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
 {
 #if defined(linux) || defined(__FreeBSD__)
@@ -1250,7 +1228,7 @@
 		if (write (MidiOutDev[wDevID].unixdev, ptr, 
 			sizeof(WORD)) != sizeof(WORD)) break;
 		ptr++;
-		}
+	}
 
 	en = errno;
 	dprintf_midi(stddeb, "Linux 'modLongData' // after write count = %d\n",count);
@@ -1261,13 +1239,13 @@
 		dprintf_midi(stddeb,
 			"                 errno = %d error = %s\n",en,strerror(en));
 		return MMSYSERR_NOTENABLED;
-		}
+	}
 	lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
 	lpMidiHdr->dwFlags |= MHDR_DONE;
 	if (MIDI_NotifyClient(wDevID, MOM_DONE, 0L, 0L) != MMSYSERR_NOERROR) {
 		dprintf_midi(stddeb,"Linux 'modLongData' // can't notify client !\n");
 		return MMSYSERR_INVALPARAM;
-		}
+	}
 	return MMSYSERR_NOERROR;
 #else
 	return MMSYSERR_NOTENABLED;
@@ -1275,8 +1253,8 @@
 }
 
 /**************************************************************************
-* 				modPrepare				[internal]
-*/
+ * 			modPrepare				[internal]
+ */
 static DWORD modPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
 {
 #if defined(linux) || defined(__FreeBSD__)
@@ -1285,11 +1263,11 @@
 	if (MidiOutDev[wDevID].unixdev == 0) {
 		dprintf_midi(stddeb,"Linux 'modPrepare' // can't prepare !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
 	if (MidiOutDev[wDevID].lpQueueHdr != NULL) {
 		dprintf_midi(stddeb,"Linux 'modPrepare' // already prepare !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
 	MidiOutDev[wDevID].dwTotalPlayed = 0;
 	MidiOutDev[wDevID].lpQueueHdr = PTR_SEG_TO_LIN(lpMidiHdr);
 	if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING;
@@ -1302,8 +1280,8 @@
 }
 
 /**************************************************************************
-* 				modUnprepare			[internal]
-*/
+ * 				modUnprepare			[internal]
+ */
 static DWORD modUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
 {
 #if defined(linux) || defined(__FreeBSD__)
@@ -1312,7 +1290,7 @@
 	if (MidiOutDev[wDevID].unixdev == 0) {
 		dprintf_midi(stddeb,"Linux 'modUnprepare' // can't unprepare !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
 	return MMSYSERR_NOERROR;
 #else
 	return MMSYSERR_NOTENABLED;
@@ -1320,8 +1298,8 @@
 }
 
 /**************************************************************************
-* 				modReset				[internal]
-*/
+ * 			modReset				[internal]
+ */
 static DWORD modReset(WORD wDevID)
 {
 	dprintf_midi(stddeb, "modReset(%04X);\n", wDevID);
@@ -1330,98 +1308,98 @@
 
 
 /**************************************************************************
-* 				modMessage			[sample driver]
-*/
+ * 				modMessage			[sample driver]
+ */
 DWORD modMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
 					DWORD dwParam1, DWORD dwParam2)
 {
 	dprintf_midi(stddeb, "modMessage(%04X, %04X, %08lX, %08lX, %08lX);\n", 
 			wDevID, wMsg, dwUser, dwParam1, dwParam2);
 	switch(wMsg) {
-		case MODM_OPEN:
-			return modOpen(wDevID, (LPMIDIOPENDESC)PTR_SEG_TO_LIN(dwParam1), dwParam2);
-		case MODM_CLOSE:
-			return modClose(wDevID);
-		case MODM_DATA:
-			return modData(wDevID, dwParam1);
-		case MODM_LONGDATA:
-			return modLongData(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
-		case MODM_PREPARE:
-			return modPrepare(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
-		case MODM_UNPREPARE:
-			return modUnprepare(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
-		case MODM_GETDEVCAPS:
-			return modGetDevCaps(wDevID, (LPMIDIOUTCAPS)PTR_SEG_TO_LIN(dwParam1), dwParam2);
-		case MODM_GETNUMDEVS:
-			return 1;
-		case MODM_GETVOLUME:
-			return 0;
-		case MODM_SETVOLUME:
-			return 0;
-		case MODM_RESET:
-			return modReset(wDevID);
-		}
+	case MODM_OPEN:
+		return modOpen(wDevID, (LPMIDIOPENDESC)dwParam1, dwParam2);
+	case MODM_CLOSE:
+		return modClose(wDevID);
+	case MODM_DATA:
+		return modData(wDevID, dwParam1);
+	case MODM_LONGDATA:
+		return modLongData(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
+	case MODM_PREPARE:
+		return modPrepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
+	case MODM_UNPREPARE:
+		return modUnprepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
+	case MODM_GETDEVCAPS:
+		return modGetDevCaps(wDevID,(LPMIDIOUTCAPS16)dwParam1,dwParam2);
+	case MODM_GETNUMDEVS:
+		return 1;
+	case MODM_GETVOLUME:
+		return 0;
+	case MODM_SETVOLUME:
+		return 0;
+	case MODM_RESET:
+		return modReset(wDevID);
+	}
 	return MMSYSERR_NOTSUPPORTED;
 }
 
 
 /**************************************************************************
-* 				MIDI_DriverProc		[sample driver]
-*/
+ * 				MIDI_DriverProc		[sample driver]
+ */
 LONG MIDI_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
 						DWORD dwParam1, DWORD dwParam2)
 {
 #if defined(linux) || defined(__FreeBSD__)
 	switch(wMsg) {
-		case DRV_LOAD:
-			return 1;
-		case DRV_FREE:
-			return 1;
-		case DRV_OPEN:
-			return 1;
-		case DRV_CLOSE:
-			return 1;
-		case DRV_ENABLE:
-			return 1;
-		case DRV_DISABLE:
-			return 1;
-		case DRV_QUERYCONFIGURE:
-			return 1;
-		case DRV_CONFIGURE:
-			MessageBox16(0, "Sample Midi Linux Driver !", 
-                                     "MMLinux Driver", MB_OK);
-			return 1;
-		case DRV_INSTALL:
-			return DRVCNF_RESTART;
-		case DRV_REMOVE:
-			return DRVCNF_RESTART;
-		case MCI_OPEN_DRIVER:
-		case MCI_OPEN:
-			return MIDI_mciOpen(dwDevID, dwParam1, (LPMCI_OPEN_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		case MCI_CLOSE_DRIVER:
-		case MCI_CLOSE:
-			return MIDI_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		case MCI_PLAY:
-			return MIDI_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		case MCI_RECORD:
-			return MIDI_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		case MCI_STOP:
-			return MIDI_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		case MCI_SET:
-			return MIDI_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		case MCI_PAUSE:
-			return MIDI_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		case MCI_RESUME:
-			return MIDI_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		case MCI_STATUS:
-			return MIDI_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		case MCI_GETDEVCAPS:
-			return MIDI_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		case MCI_INFO:
-			return MIDI_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS)PTR_SEG_TO_LIN(dwParam2));
-		default:
-			return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
-		}
+	case DRV_LOAD:
+		return 1;
+	case DRV_FREE:
+		return 1;
+	case DRV_OPEN:
+		return 1;
+	case DRV_CLOSE:
+		return 1;
+	case DRV_ENABLE:
+		return 1;
+	case DRV_DISABLE:
+		return 1;
+	case DRV_QUERYCONFIGURE:
+		return 1;
+	case DRV_CONFIGURE:
+		MessageBox16(0, "Sample Midi Linux Driver !", 
+			     "MMLinux Driver", MB_OK);
+		return 1;
+	case DRV_INSTALL:
+		return DRVCNF_RESTART;
+	case DRV_REMOVE:
+		return DRVCNF_RESTART;
+	case MCI_OPEN_DRIVER:
+	case MCI_OPEN:
+		return MIDI_mciOpen(dwDevID, dwParam1, (LPMCI_OPEN_PARMS16)PTR_SEG_TO_LIN(dwParam2));
+	case MCI_CLOSE_DRIVER:
+	case MCI_CLOSE:
+		return MIDI_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
+	case MCI_PLAY:
+		return MIDI_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)PTR_SEG_TO_LIN(dwParam2));
+	case MCI_RECORD:
+		return MIDI_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)PTR_SEG_TO_LIN(dwParam2));
+	case MCI_STOP:
+		return MIDI_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
+	case MCI_SET:
+		return MIDI_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)PTR_SEG_TO_LIN(dwParam2));
+	case MCI_PAUSE:
+		return MIDI_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
+	case MCI_RESUME:
+		return MIDI_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
+	case MCI_STATUS:
+		return MIDI_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)PTR_SEG_TO_LIN(dwParam2));
+	case MCI_GETDEVCAPS:
+		return MIDI_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)PTR_SEG_TO_LIN(dwParam2));
+	case MCI_INFO:
+		return MIDI_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS16)PTR_SEG_TO_LIN(dwParam2));
+	default:
+		return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
+	}
 #else
 	return MMSYSERR_NOTENABLED;
 #endif
diff --git a/multimedia/mixer.c b/multimedia/mixer.c
new file mode 100644
index 0000000..14ec17a
--- /dev/null
+++ b/multimedia/mixer.c
@@ -0,0 +1,221 @@
+/*
+ * Sample MIXER Wine Driver for Linux
+ *
+ * Copyright 1997 Marcus Meissner
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include "windows.h"
+#include "user.h"
+#include "driver.h"
+#include "mmsystem.h"
+
+#ifdef linux
+#include <linux/soundcard.h>
+#elif __FreeBSD__
+#include <machine/soundcard.h>
+#endif
+
+#include "stddebug.h"
+#include "debug.h"
+
+#define MIXER_DEV "/dev/mixer"
+
+#ifdef SOUND_VERSION
+#define IOCTL(a,b,c)		ioctl(a,b,&c)
+#else
+#define IOCTL(a,b,c)		(c = ioctl(a,b,c) )
+#endif
+
+
+/**************************************************************************
+ * 				MIX_GetDevCaps			[internal]
+ */
+static DWORD MIX_GetDevCaps(WORD wDevID, LPMIXERCAPS16 lpCaps, DWORD dwSize)
+{
+#ifdef linux
+	int 		mixer,mask;
+	struct	mixer_info	mi;
+
+	dprintf_mmaux(stddeb,"MIX_GetDevCaps(%04X, %p, %lu);\n", wDevID, lpCaps, dwSize);
+	if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
+	if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
+		dprintf_mmaux(stddeb,"MIX_GetDevCaps // mixer device not available !\n");
+		return MMSYSERR_NOTENABLED;
+	}
+	if (ioctl(mixer, SOUND_MIXER_INFO, &mi) == -1) {
+		close(mixer);
+		perror("ioctl mixer SOUND_MIXER_INFO");
+		return MMSYSERR_NOTENABLED;
+	}
+	fprintf(stderr,"SOUND_MIXER_INFO returns { \"%s\",\"%s\" }\n",mi.id,mi.name);
+	lpCaps->wMid = 0xAA;
+	lpCaps->wPid = 0x55;
+	lpCaps->vDriverVersion = 0x0100;
+	strcpy(lpCaps->szPname,mi.name);
+	if (ioctl(mixer, SOUND_MIXER_READ_DEVMASK, &mask) == -1) {
+		close(mixer);
+		perror("ioctl mixer SOUND_MIXER_DEVMASK");
+		return MMSYSERR_NOTENABLED;
+	}
+	/* FIXME: can the Linux Mixer differ between multiple mixertargets? */
+	lpCaps->cDestinations = 1;
+	lpCaps->fdwSupport = 0; /* No bits defined yet */
+
+	close(mixer);
+	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
+}
+
+#ifdef linux
+static char *sdlabels[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_LABELS;
+static char *sdnames[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
+#endif
+
+/**************************************************************************
+ * 				MIX_GetLineInfo			[internal]
+ */
+static DWORD MIX_GetLineInfo(WORD wDevID, LPMIXERLINE16 lpml, DWORD fdwInfo)
+{
+#ifdef linux
+	int 		mixer,i,j,devmask,recsrc,recmask;
+
+	dprintf_mmaux(stddeb,"MIX_GetDevLineInfo(%04X, %p, %lu);\n", wDevID, lpml, fdwInfo);
+	if (lpml == NULL) return MMSYSERR_NOTENABLED;
+	if ((mixer = open(MIXER_DEV, O_RDWR)) < 0)
+		return MMSYSERR_NOTENABLED;
+
+	if (ioctl(mixer, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
+		close(mixer);
+		perror("ioctl mixer SOUND_MIXER_DEVMASK");
+		return MMSYSERR_NOTENABLED;
+	}
+	if (ioctl(mixer, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) {
+		close(mixer);
+		perror("ioctl mixer SOUND_MIXER_RECSRC");
+		return MMSYSERR_NOTENABLED;
+	}
+	if (ioctl(mixer, SOUND_MIXER_READ_RECMASK, &recmask) == -1) {
+		close(mixer);
+		perror("ioctl mixer SOUND_MIXER_RECMASK");
+		return MMSYSERR_NOTENABLED;
+	}
+	lpml->cbStruct = sizeof(MIXERLINE16);
+	/* FIXME: set all the variables correctly... the lines below
+	 * are very wrong...
+	 */
+	lpml->fdwLine	= MIXERLINE_LINEF_ACTIVE;
+	lpml->cChannels	= 2;
+
+	switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK) {
+	case MIXER_GETLINEINFOF_DESTINATION:
+		/* FIXME: Linux doesn't seem to support multiple outputs? 
+		 * So we have only one outputtype, Speaker.
+		 */
+		lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
+		/* we have all connections found in the devmask */
+		lpml->cConnections = 0;
+		for (j=0;j<31;j++)
+			if (devmask & (1<<j))
+				lpml->cConnections++;
+		break;
+	case MIXER_GETLINEINFOF_SOURCE:
+		for (i=j=0;j<31;j++) {
+			if (devmask & (1<<j)) {
+				if (lpml->dwSource == i)
+					break;
+				i++;
+			}
+		}
+		strcpy(lpml->szShortName,sdlabels[i]);
+		strcpy(lpml->szName,sdnames[i]);
+		lpml->dwLineID = i;
+		switch (i) {
+		case SOUND_MIXER_SYNTH:
+			lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER;
+			lpml->fdwLine	|= MIXERLINE_LINEF_SOURCE;
+			break;
+		case SOUND_MIXER_CD:
+			lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC;
+			lpml->fdwLine	|= MIXERLINE_LINEF_SOURCE;
+			break;
+		case SOUND_MIXER_LINE:
+			lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_LINE;
+			lpml->fdwLine	|= MIXERLINE_LINEF_SOURCE;
+			break;
+		case SOUND_MIXER_MIC:
+			lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
+			lpml->fdwLine	|= MIXERLINE_LINEF_SOURCE;
+			break;
+		case SOUND_MIXER_PCM:
+			lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
+			lpml->fdwLine	|= MIXERLINE_LINEF_SOURCE;
+			break;
+		default:
+			fprintf(stderr,"MIX_GetLineInfo:mixertype %d not handle.\n",i);
+			break;
+		}
+		break;
+	case MIXER_GETLINEINFOF_LINEID:
+		fprintf(stderr,"MIX_GetLineInfo: _LINEID (%ld) not implemented yet.\n",lpml->dwLineID);
+		break;
+	case MIXER_GETLINEINFOF_COMPONENTTYPE:
+		fprintf(stderr,"MIX_GetLineInfo: _COMPONENTTYPE not implemented yet.\n");
+		break;
+	case MIXER_GETLINEINFOF_TARGETTYPE:
+		fprintf(stderr,"MIX_GetLineInfo: _TARGETTYPE not implemented yet.\n");
+		break;
+	}
+	lpml->Target.dwType = MIXERLINE_TARGETTYPE_AUX;
+	close(mixer);
+	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
+}
+
+/**************************************************************************
+ * 				MIX_GetLineInfo			[internal]
+ */
+static DWORD MIX_Open(WORD wDevID, LPMIXEROPENDESC lpmod, DWORD flags)
+{
+#ifdef linux
+
+	dprintf_mmaux(stddeb,"MIX_Open(%04X, %p, %lu);\n",wDevID,lpmod,flags);
+	if (lpmod == NULL) return MMSYSERR_NOTENABLED;
+	/* hmm. We don't keep the mixer device open. So just pretend it works */
+	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
+}
+
+/**************************************************************************
+ * 				mixMessage			[sample driver]
+ */
+DWORD mixMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
+					DWORD dwParam1, DWORD dwParam2)
+{
+	dprintf_mmaux(stddeb,"mixMessage(%04X, %04X, %08lX, %08lX, %08lX);\n", 
+			wDevID, wMsg, dwUser, dwParam1, dwParam2);
+	switch(wMsg) {
+	case MXDM_GETDEVCAPS:
+		return MIX_GetDevCaps(wDevID,(LPMIXERCAPS16)dwParam1,dwParam2);
+	case MXDM_GETLINEINFO:
+		return MIX_GetLineInfo(wDevID,(LPMIXERLINE16)dwParam1,dwParam2);
+	case MXDM_GETNUMDEVS:
+		dprintf_mmsys(stddeb,"MIX_GetNumDevs() return 1;\n");
+		return 1;
+	case MXDM_OPEN:
+		return MIX_Open(wDevID,(LPMIXEROPENDESC)dwParam1,dwParam2);
+	default:
+		dprintf_mmaux(stddeb,"mixMessage // unknown message %d!\n",wMsg);
+	}
+	return MMSYSERR_NOTSUPPORTED;
+}
diff --git a/multimedia/mmaux.c b/multimedia/mmaux.c
index 5b261d0..de34c4f 100644
--- a/multimedia/mmaux.c
+++ b/multimedia/mmaux.c
@@ -41,24 +41,24 @@
 
 
 /**************************************************************************
-* 				AUX_GetDevCaps			[internal]
-*/
-static DWORD AUX_GetDevCaps(WORD wDevID, LPAUXCAPS lpCaps, DWORD dwSize)
+ * 				AUX_GetDevCaps			[internal]
+ */
+static DWORD AUX_GetDevCaps(WORD wDevID, LPAUXCAPS16 lpCaps, DWORD dwSize)
 {
 #ifdef linux
-	int 	mixer;
-	int		volume;
+	int 	mixer,volume;
+
 	dprintf_mmaux(stddeb,"AUX_GetDevCaps(%04X, %p, %lu);\n", wDevID, lpCaps, dwSize);
 	if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
 	if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
 		dprintf_mmaux(stddeb,"AUX_GetDevCaps // mixer device not available !\n");
 		return MMSYSERR_NOTENABLED;
-		}
-    if (ioctl(mixer, SOUND_MIXER_READ_LINE, &volume) == -1) {
+	}
+	if (ioctl(mixer, SOUND_MIXER_READ_LINE, &volume) == -1) {
 		close(mixer);
 		dprintf_mmaux(stddeb,"AUX_GetDevCaps // unable read mixer !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
 	close(mixer);
 #ifdef EMULATE_SB16
 	lpCaps->wMid = 0x0002;
@@ -112,21 +112,19 @@
 
 
 /**************************************************************************
-* 				AUX_GetVolume			[internal]
-*/
+ * 				AUX_GetVolume			[internal]
+ */
 static DWORD AUX_GetVolume(WORD wDevID, LPDWORD lpdwVol)
 {
 #ifdef linux
-	int 	mixer;
-	int		volume, left, right;
-	int		cmd;
+	int 	mixer,volume,left,right,cmd;
 
 	dprintf_mmaux(stddeb,"AUX_GetVolume(%04X, %p);\n", wDevID, lpdwVol);
 	if (lpdwVol == NULL) return MMSYSERR_NOTENABLED;
 	if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
 		dprintf_mmaux(stddeb,"Linux 'AUX_GetVolume' // mixer device not available !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
 	switch(wDevID) {
 		case 0:
 			dprintf_mmaux(stddeb,"Linux 'AUX_GetVolume' // SOUND_MIXER_READ_PCM !\n");
@@ -159,7 +157,7 @@
 	if (ioctl(mixer, cmd, &volume) == -1) {
 		dprintf_mmaux(stddeb,"Linux 'AUX_GetVolume' // unable read mixer !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
 	close(mixer);
 	left = volume & 0x7F;
 	right = (volume >> 8) & 0x7F;
@@ -172,8 +170,8 @@
 }
 
 /**************************************************************************
-* 				AUX_SetVolume			[internal]
-*/
+ * 				AUX_SetVolume			[internal]
+ */
 static DWORD AUX_SetVolume(WORD wDevID, DWORD dwParam)
 {
 #ifdef linux
@@ -229,26 +227,25 @@
 
 
 /**************************************************************************
-* 				auxMessage			[sample driver]
-*/
+ * 				auxMessage			[sample driver]
+ */
 DWORD auxMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
 					DWORD dwParam1, DWORD dwParam2)
 {
 	dprintf_mmaux(stddeb,"auxMessage(%04X, %04X, %08lX, %08lX, %08lX);\n", 
 			wDevID, wMsg, dwUser, dwParam1, dwParam2);
 	switch(wMsg) {
-		case AUXDM_GETDEVCAPS:
-			return AUX_GetDevCaps(wDevID, 
-				(LPAUXCAPS)PTR_SEG_TO_LIN(dwParam1), dwParam2);
-		case AUXDM_GETNUMDEVS:
-			dprintf_mmaux(stddeb,"AUX_GetNumDevs() return %d;\n", NumDev);
-			return NumDev;
-		case AUXDM_GETVOLUME:
-			return AUX_GetVolume(wDevID, (LPDWORD)PTR_SEG_TO_LIN(dwParam1));
-		case AUXDM_SETVOLUME:
-			return AUX_SetVolume(wDevID, dwParam1);
-		default:
-			dprintf_mmaux(stddeb,"auxMessage // unknown message !\n");
-		}
+	case AUXDM_GETDEVCAPS:
+		return AUX_GetDevCaps(wDevID,(LPAUXCAPS16)dwParam1,dwParam2);
+	case AUXDM_GETNUMDEVS:
+		dprintf_mmaux(stddeb,"AUX_GetNumDevs() return %d;\n", NumDev);
+		return NumDev;
+	case AUXDM_GETVOLUME:
+		return AUX_GetVolume(wDevID,(LPDWORD)dwParam1);
+	case AUXDM_SETVOLUME:
+		return AUX_SetVolume(wDevID,dwParam1);
+	default:
+		dprintf_mmaux(stddeb,"auxMessage // unknown message !\n");
+	}
 	return MMSYSERR_NOTSUPPORTED;
 }
diff --git a/multimedia/mmsystem.c b/multimedia/mmsystem.c
index 0b56fb3..159e78f 100644
--- a/multimedia/mmsystem.c
+++ b/multimedia/mmsystem.c
@@ -35,10 +35,10 @@
 /* struct below is to remember alias/devicenames for mcistring.c 
  * FIXME: should use some internal struct ... 
  */
-MCI_OPEN_PARMS		mciOpenDrv[MAXMCIDRIVERS];
+MCI_OPEN_PARMS16 mciOpenDrv[MAXMCIDRIVERS];
 
 UINT16 midiGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize);
-UINT16 waveGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize);
+static UINT16 waveGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize);
 LONG WINAPI DrvDefDriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
                              DWORD dwParam1, DWORD dwParam2);
 
@@ -67,37 +67,37 @@
 #define MMSYSTEM_MAGIC 0x0F00
 
 /**************************************************************************
-* 				MMSYSTEM_DevIDToIndex	[internal]
-*/
+ * 				MMSYSTEM_DevIDToIndex	[internal]
+ */
 int MMSYSTEM_DevIDToIndex(UINT16 wDevID) {
 	return wDevID - MMSYSTEM_MAGIC;
 }
 
 /**************************************************************************
-* 				MMSYSTEM_FirstDevId	[internal]
-*/
+ * 				MMSYSTEM_FirstDevId	[internal]
+ */
 UINT16 MMSYSTEM_FirstDevID(void)
 {
 	return MMSYSTEM_MAGIC;
 }
 
 /**************************************************************************
-* 				MMSYSTEM_NextDevId	[internal]
-*/
+ * 				MMSYSTEM_NextDevId	[internal]
+ */
 UINT16 MMSYSTEM_NextDevID(UINT16 wDevID) {
 	return wDevID + 1;
 }
 
 /**************************************************************************
-* 				MMSYSTEM_DevIdValid	[internal]
-*/
+ * 				MMSYSTEM_DevIdValid	[internal]
+ */
 BOOL32 MMSYSTEM_DevIDValid(UINT16 wDevID) {
 	return wDevID >= 0x0F00 && wDevID < (0x0F00 + MAXMCIDRIVERS);
 }
 
 /**************************************************************************
-* 				MMSYSTEM_WEP		[MMSYSTEM.1]
-*/
+ * 				MMSYSTEM_WEP		[MMSYSTEM.1]
+ */
 int WINAPI MMSYSTEM_WEP(HINSTANCE16 hInstance, WORD wDataSeg,
                         WORD cbHeapSize, LPSTR lpCmdLine)
 {
@@ -105,6 +105,22 @@
 	return(TRUE);
 }
 
+void
+MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16,LPMMTIME32 mmt32) {
+	mmt16->wType = mmt32->wType;
+	/* layout of rest is the same for 32/16 */
+	memcpy(&(mmt32->u),&(mmt16->u),sizeof(mmt16->u));
+}
+
+void
+MMSYSTEM_MMTIME16to32(LPMMTIME32 mmt32,LPMMTIME16 mmt16) {
+	mmt32->wType = mmt16->wType;
+	/* layout of rest is the same for 32/16,
+	 * Note: mmt16->u is 2 bytes smaller than mmt32->u
+	 */
+	memcpy(&(mmt16->u),&(mmt32->u),sizeof(mmt16->u));
+}
+
 /**************************************************************************
 * 				PlaySoundA		[WINMM.1]
 */
@@ -127,11 +143,11 @@
 */
 BOOL32 WINAPI PlaySound32W(LPCWSTR pszSound, HMODULE32 hmod, DWORD fdwSound)
 {
-  LPSTR pszSoundA = xmalloc((lstrlen32W(pszSound)+1)*sizeof(WCHAR));
+  LPSTR pszSoundA = HEAP_strdupWtoA(GetProcessHeap(),0,pszSound);
   BOOL32 bSound;
-  lstrcpyWtoA(pszSoundA, pszSound);
+
   bSound = PlaySound32A(pszSoundA, hmod, fdwSound);
-  free(pszSoundA);
+  HeapFree(GetProcessHeap(),0,pszSoundA);
   return bSound;
 }
 
@@ -152,7 +168,7 @@
 		dprintf_mmsys(stddeb, "sndPlaySound // Stop !\n");
 		return FALSE;
 		}
-	hmmio = mmioOpen((LPSTR)lpszSoundName, NULL, 
+	hmmio = mmioOpen16((LPSTR)lpszSoundName, NULL, 
 		MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
 
 	if (uFlags & SND_MEMORY) {
@@ -166,7 +182,7 @@
 		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);
+		hmmio = mmioOpen16(str, NULL, MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
 		if (hmmio == 0) 
 		{
 			dprintf_mmsys(stddeb, "sndPlaySound // can't find SystemSound='%s' !\n", str);
@@ -207,57 +223,46 @@
 			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;
+			    WAVEOPENDESC	waveDesc;
+			    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));
+			    waveDesc.hWave    = 0;
+			    waveDesc.lpFormat = (LPWAVEFORMAT)&pcmWaveFormat;
 
-			    lpWaveDesc->hWave    = 0;
-			    lpWaveDesc->lpFormat = (LPWAVEFORMAT) SEGPTR_GET(lpFormat);
-
-			    dwRet = wodMessage( 0, 
-						WODM_OPEN, 0, (DWORD)SEGPTR_GET(lpWaveDesc), CALLBACK_NULL);
-			    SEGPTR_FREE(lpFormat);
-			    SEGPTR_FREE(lpWaveDesc);
-
+			    dwRet = wodMessage( 0, WODM_OPEN, 0, (DWORD)&waveDesc, CALLBACK_NULL);
 			    if (dwRet == MMSYSERR_NOERROR) 
 			    {
-				LPWAVEHDR    lpWaveHdr = (LPWAVEHDR) SEGPTR_ALLOC(sizeof(WAVEHDR));
-				SEGPTR       spWaveHdr = SEGPTR_GET(lpWaveHdr);
-				HGLOBAL16    hData;
-				INT32        count, bufsize;
+				WAVEHDR		waveHdr;
+				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;
+				waveHdr.lpData = (LPSTR)GlobalLock16(hData);
+				waveHdr.dwBufferLength = bufsize;
+				waveHdr.dwUser = 0L;
+				waveHdr.dwFlags = 0L;
+				waveHdr.dwLoops = 0L;
 
-				dwRet = wodMessage( 0,
-						    WODM_PREPARE, 0, (DWORD)spWaveHdr, sizeof(WAVEHDR));
+				dwRet = wodMessage(0,WODM_PREPARE,0,(DWORD)&waveHdr,sizeof(WAVEHDR));
 				if (dwRet == MMSYSERR_NOERROR) 
 				{
 				    while( TRUE )
 				    {
-					count = mmioRead(hmmio, PTR_SEG_TO_LIN(lpWaveHdr->lpData), bufsize);
+					count = mmioRead(hmmio, waveHdr.lpData, bufsize);
 					if (count < 1) break;
-					lpWaveHdr->dwBufferLength = count;
-				/*	lpWaveHdr->dwBytesRecorded = count; */
-					wodMessage( 0, WODM_WRITE, 
-						    0, (DWORD)spWaveHdr, sizeof(WAVEHDR));
+					waveHdr.dwBufferLength = count;
+				/*	waveHdr.dwBytesRecorded = count; */
+					/* FIXME: doesn't expect async ops */ 
+					wodMessage( 0, WODM_WRITE, 0, (DWORD)&waveHdr, sizeof(WAVEHDR));
 				    }
-				    wodMessage( 0, 
-					        WODM_UNPREPARE, 0, (DWORD)spWaveHdr, sizeof(WAVEHDR));
-				    wodMessage( 0,
-						WODM_CLOSE, 0, 0L, 0L);
+				    wodMessage( 0, WODM_UNPREPARE, 0, (DWORD)&waveHdr, sizeof(WAVEHDR));
+				    wodMessage( 0, WODM_CLOSE, 0, 0L, 0L);
 
 				    bRet = TRUE;
 				}
@@ -265,8 +270,6 @@
 
 				GlobalUnlock16(hData);
 				GlobalFree16(hData);
-
-				SEGPTR_FREE(lpWaveHdr);
 			    }
 			}
 		    }
@@ -279,12 +282,21 @@
 }
 
 /**************************************************************************
-* 				mmsystemGetVersion	[MMSYSTEM.5]
-*/
-WORD WINAPI mmsystemGetVersion()
+ * 				mmsystemGetVersion	[WINMM.134]
+ */
+UINT32 WINAPI mmsystemGetVersion32()
 {
-	dprintf_mmsys(stddeb, "mmsystemGetVersion // 0.4.0 ...?... :-) !\n");
-	return 0x0040;
+	return mmsystemGetVersion16();
+}
+
+/**************************************************************************
+ * 				mmsystemGetVersion	[MMSYSTEM.5]
+ * return value borrowed from Win95 winmm.dll ;)
+ */
+UINT16 WINAPI mmsystemGetVersion16()
+{
+	dprintf_mmsys(stddeb, "mmsystemGetVersion // 3.10 (Win95?)\n");
+	return 0x030a;
 }
 
 /**************************************************************************
@@ -323,17 +335,375 @@
 			return FALSE;
 		case DCB_FUNCTION:
 			dprintf_mmsys(stddeb, "DriverCallback() // CALLBACK_FUNCTION !\n");
-			CallDriverCallback( (FARPROC16)dwCallBack, hDev, wMsg,
-                                            dwUser, dwParam1, dwParam2 );
+			Callbacks->CallDriverCallback( (FARPROC16)dwCallBack,
+                                                       hDev, wMsg, dwUser,
+                                                       dwParam1, dwParam2 );
 			break;
 		}
 	return TRUE;
 }
 
 /**************************************************************************
-* 				auxGetNumDevs		[MMSYSTEM.350]
-*/
-UINT16 WINAPI auxGetNumDevs()
+ * 	Mixer devices. New to Win95
+ */
+/**************************************************************************
+ * find out the real mixer ID depending on hmix (depends on dwFlags)
+ * FIXME: also fix dwInstance passing to mixMessage 
+ */
+static UINT32 _get_mixerID_from_handle(HMIXEROBJ32 hmix,DWORD dwFlags) {
+	/* FIXME: Check dwFlags for MIXER_OBJECTF_xxxx entries and modify hmix 
+	 * accordingly. For now we always use mixerdevice 0. 
+	 */
+	return 0;
+}
+/**************************************************************************
+ * 				mixerGetNumDevs		[WINMM.108]
+ */
+UINT32 WINAPI mixerGetNumDevs32() 
+{
+	return mixerGetNumDevs16();
+}
+
+/**************************************************************************
+ * 				mixerGetNumDevs	
+ */
+UINT16 WINAPI mixerGetNumDevs16() 
+{
+	UINT16	count;
+
+	count = mixMessage(0,MXDM_GETNUMDEVS,0L,0L,0L);
+	dprintf_mmaux(stddeb,"mixerGetNumDevs returns %d\n",count);
+	return count;
+}
+
+/**************************************************************************
+ * 				mixerGetDevCapsW		[WINMM.102]
+ */
+UINT32 WINAPI mixerGetDevCaps32W(UINT32 devid,LPMIXERCAPS32W mixcaps,UINT32 size) 
+{
+	MIXERCAPS16	mic16;
+	UINT32	ret = mixerGetDevCaps16(devid,&mic16,sizeof(mic16));
+
+	mixcaps->wMid = mic16.wMid;
+	mixcaps->wPid = mic16.wPid;
+	mixcaps->vDriverVersion = mic16.vDriverVersion;
+	lstrcpyAtoW(mixcaps->szPname,mic16.szPname);
+	mixcaps->fdwSupport = mic16.fdwSupport;
+	mixcaps->cDestinations = mic16.cDestinations;
+	return ret;
+}
+/**************************************************************************
+ * 				mixerGetDevCaps		[WINMM.101]
+ */
+UINT32 WINAPI mixerGetDevCaps32A(UINT32 devid,LPMIXERCAPS32A mixcaps,UINT32 size) 
+{
+	MIXERCAPS16	mic16;
+	UINT32	ret = mixerGetDevCaps16(devid,&mic16,sizeof(mic16));
+
+	mixcaps->wMid = mic16.wMid;
+	mixcaps->wPid = mic16.wPid;
+	mixcaps->vDriverVersion = mic16.vDriverVersion;
+	strcpy(mixcaps->szPname,mic16.szPname);
+	mixcaps->fdwSupport = mic16.fdwSupport;
+	mixcaps->cDestinations = mic16.cDestinations;
+	return ret;
+}
+
+/**************************************************************************
+ * 				mixerGetDevCaps	
+ */
+UINT16 WINAPI mixerGetDevCaps16(UINT16 devid,LPMIXERCAPS16 mixcaps,UINT16 size) 
+{
+	fprintf(stderr,"mixerGetDevCaps!\n");
+	return mixMessage(devid,MXDM_GETDEVCAPS,0L,(DWORD)mixcaps,(DWORD)size);
+}
+
+/**************************************************************************
+ * 				mixerOpen		[WINMM.110]
+ */
+UINT32 WINAPI mixerOpen32(LPHMIXER32 lphmix,UINT32 uDeviceID,DWORD dwCallback,
+DWORD dwInstance,DWORD fdwOpen) 
+{
+	HMIXER16	hmix16;
+	UINT32		ret;
+
+	fprintf(stderr,"mixerOpen32(%p,%d,%08lx,%08lx,%08lx)\n",
+		lphmix,uDeviceID,dwCallback,dwInstance,fdwOpen
+	);
+	ret = mixerOpen16(&hmix16,uDeviceID,dwCallback,dwInstance,fdwOpen);
+	if (lphmix) *lphmix = hmix16;
+	return ret;
+}
+
+/**************************************************************************
+ * 				mixerOpen
+ */
+UINT16 WINAPI mixerOpen16(LPHMIXER16 lphmix,UINT16 uDeviceID,DWORD dwCallback,
+DWORD dwInstance,DWORD fdwOpen) 
+{
+	HMIXER16	hmix;
+	LPMIXEROPENDESC	lpmod;
+	BOOL32		mapperflag = (uDeviceID==0);
+	DWORD		dwRet;
+
+	fprintf(stderr,"mixerOpen(%p,%d,%08lx,%08lx,%08lx)\n",
+		lphmix,uDeviceID,dwCallback,dwInstance,fdwOpen
+	);
+	hmix = USER_HEAP_ALLOC(sizeof(MIXEROPENDESC));
+	if (lphmix) *lphmix = hmix;
+	lpmod = (LPMIXEROPENDESC)USER_HEAP_LIN_ADDR(hmix);
+	lpmod->hmx = hmix;
+	lpmod->dwCallback = dwCallback;
+	lpmod->dwInstance = dwInstance;
+	if (uDeviceID >= MAXMIXERDRIVERS)
+		uDeviceID = 0;
+	while(uDeviceID < MAXMIXERDRIVERS) {
+		dwRet=mixMessage(uDeviceID,MXDM_OPEN,dwInstance,(DWORD)lpmod,fdwOpen);
+		if (dwRet == MMSYSERR_NOERROR) break;
+		if (!mapperflag) break;
+		uDeviceID++;
+	}
+	lpmod->uDeviceID = uDeviceID;
+	return dwRet;
+}
+
+/**************************************************************************
+ * 				mixerClose		[WINMM.98]
+ */
+UINT32 WINAPI mixerClose32(HMIXER32 hmix) {
+	return mixerClose16(hmix);
+}
+
+/**************************************************************************
+ * 				mixerClose
+ */
+UINT16 WINAPI mixerClose16(HMIXER16 hmix) {
+	LPMIXEROPENDESC	lpmod;
+
+	fprintf(stderr,"mixerClose(%04x)\n",hmix);
+	lpmod = (LPMIXEROPENDESC)USER_HEAP_LIN_ADDR(hmix);
+	return mixMessage(lpmod->uDeviceID,MXDM_CLOSE,lpmod->dwInstance,0L,0L);
+}
+
+/**************************************************************************
+ * 				mixerGetID		[WINMM.103]
+ */
+UINT32 WINAPI mixerGetID32(HMIXEROBJ32 hmix,LPUINT32 lpid,DWORD fdwID) {
+	UINT16	xid;
+
+	UINT32	ret = mixerGetID16(hmix,&xid,fdwID);
+	if (*lpid) *lpid = xid;
+	return ret;
+}
+
+/**************************************************************************
+ * 				mixerGetID
+ */
+UINT16 WINAPI mixerGetID16(HMIXEROBJ16 hmix,LPUINT16 lpid,DWORD fdwID) {
+	fprintf(stderr,"mixerGetID(%04x)\n",hmix);
+	return _get_mixerID_from_handle(hmix,fdwID);
+}
+
+/**************************************************************************
+ * 				mixerGetControlDetailsA	[WINMM.99]
+ */
+UINT32 mixerGetControlDetails32A(HMIXEROBJ32 hmix,LPMIXERCONTROLDETAILS32 lpmcd,DWORD fdwDetails) {
+	fprintf(stderr,"mixerGetControlDetails(%04x,%p,%08lx),stub!\n",
+		hmix,lpmcd,fdwDetails
+	);
+	return MMSYSERR_NOTENABLED;
+}
+
+/**************************************************************************
+ * 				mixerGetControlDetailsW	[WINMM.100]
+ */
+UINT32 mixerGetControlDetails32W(HMIXEROBJ32 hmix,LPMIXERCONTROLDETAILS32 lpmcd,DWORD fdwDetails) {
+	fprintf(stderr,"mixerGetControlDetails(%04x,%p,%08lx),stub!\n",
+		hmix,lpmcd,fdwDetails
+	);
+	return MMSYSERR_NOTENABLED;
+}
+
+/**************************************************************************
+ * 				mixerGetControlDetails	[MMSYSTEM.808]
+ */
+UINT16 mixerGetControlDetails16(HMIXEROBJ16 hmix,LPMIXERCONTROLDETAILS16 lpmcd,DWORD fdwDetails) {
+	fprintf(stderr,"mixerGetControlDetails(%04x,%p,%08lx),stub!\n",
+		hmix,lpmcd,fdwDetails
+	);
+	return MMSYSERR_NOTENABLED;
+}
+
+/**************************************************************************
+ * 				mixerGetLineControlsA	[WINMM.104]
+ */
+UINT32 mixerGetLineControls32A(HMIXEROBJ32 hmix,LPMIXERLINECONTROLS32A lpmlc,DWORD fdwControls) {
+	fprintf(stderr,"mixerGetLineControlsA(%04x,%p,%08lx),stub!\n",
+		hmix,lpmlc,fdwControls
+	);
+	return MMSYSERR_NOTENABLED;
+}
+
+/**************************************************************************
+ * 				mixerGetLineControlsW	[WINMM.105]
+ */
+UINT32 mixerGetLineControls32W(HMIXEROBJ32 hmix,LPMIXERLINECONTROLS32W lpmlc,DWORD fdwControls) {
+	fprintf(stderr,"mixerGetLineControlsA(%04x,%p,%08lx),stub!\n",
+		hmix,lpmlc,fdwControls
+	);
+	return MMSYSERR_NOTENABLED;
+}
+
+/**************************************************************************
+ * 				mixerGetLineControls	[MMSYSTEM.807]
+ */
+UINT16 mixerGetLineControls16(HMIXEROBJ16 hmix,LPMIXERLINECONTROLS16 lpmlc,DWORD fdwControls) {
+	fprintf(stderr,"mixerGetLineControls(%04x,%p,%08lx),stub!\n",
+		hmix,lpmlc,fdwControls
+	);
+	return MMSYSERR_NOTENABLED;
+}
+
+/**************************************************************************
+ * 				mixerGetLineInfoA	[WINMM.106]
+ */
+UINT32 mixerGetLineInfo32A(HMIXEROBJ32 hmix,LPMIXERLINE32A lpml,DWORD fdwInfo) {
+	MIXERLINE16	ml16;
+	UINT32		ret;
+
+	ml16.dwDestination = lpml->dwDestination;
+	fprintf(stderr,"mixerGetLineInfoA(%04x,%p,%08lx),stub!\n",
+		hmix,lpml,fdwInfo
+	);
+	ret = mixerGetLineInfo16(hmix,&ml16,fdwInfo);
+	lpml->cbStruct = sizeof(*lpml);
+	lpml->dwSource = ml16.dwSource;
+	lpml->dwLineID = ml16.dwLineID;
+	lpml->fdwLine = ml16.fdwLine;
+	lpml->dwUser = ml16.dwUser;
+	lpml->dwComponentType = ml16.dwComponentType;
+	lpml->cChannels = ml16.cChannels;
+	lpml->cConnections = ml16.cConnections;
+	lpml->cControls = ml16.cControls;
+	strcpy(lpml->szShortName,ml16.szShortName);
+	strcpy(lpml->szName,ml16.szName);
+	lpml->Target.dwType = ml16.Target.dwType;
+	lpml->Target.dwDeviceID = ml16.Target.dwDeviceID;
+	lpml->Target.wMid = ml16.Target.wMid;
+	lpml->Target.wPid = ml16.Target.wPid;
+	lpml->Target.vDriverVersion = ml16.Target.vDriverVersion;
+	strcpy(lpml->Target.szPname,ml16.Target.szPname);
+	return ret;
+}
+
+/**************************************************************************
+ * 				mixerGetLineInfoW	[WINMM.107]
+ */
+UINT32 mixerGetLineInfo32W(HMIXEROBJ32 hmix,LPMIXERLINE32W lpml,DWORD fdwInfo) {
+	MIXERLINE16	ml16;
+	UINT32		ret;
+
+	ml16.dwDestination = lpml->dwDestination;
+	fprintf(stderr,"mixerGetLineInfoW(%04x,%p,%08lx),stub!\n",
+		hmix,lpml,fdwInfo
+	);
+	ret = mixerGetLineInfo16(hmix,&ml16,fdwInfo);
+	lpml->cbStruct = sizeof(*lpml);
+	lpml->dwSource = ml16.dwSource;
+	lpml->dwLineID = ml16.dwLineID;
+	lpml->fdwLine = ml16.fdwLine;
+	lpml->dwUser = ml16.dwUser;
+	lpml->dwComponentType = ml16.dwComponentType;
+	lpml->cChannels = ml16.cChannels;
+	lpml->cConnections = ml16.cConnections;
+	lpml->cControls = ml16.cControls;
+	lstrcpyAtoW(lpml->szShortName,ml16.szShortName);
+	lstrcpyAtoW(lpml->szName,ml16.szName);
+	lpml->Target.dwType = ml16.Target.dwType;
+	lpml->Target.dwDeviceID = ml16.Target.dwDeviceID;
+	lpml->Target.wMid = ml16.Target.wMid;
+	lpml->Target.wPid = ml16.Target.wPid;
+	lpml->Target.vDriverVersion = ml16.Target.vDriverVersion;
+	/*lstrcpyAtoW(lpml->Target.szPname,ml16.Target.szPname);*/
+	return ret;
+}
+
+/**************************************************************************
+ * 				mixerGetLineInfo	[MMSYSTEM.805]
+ */
+UINT16 mixerGetLineInfo16(HMIXEROBJ16 hmix,LPMIXERLINE16 lpml,DWORD fdwInfo) {
+	UINT16 devid =  _get_mixerID_from_handle(hmix,fdwInfo);
+
+	fprintf(stderr,"mixerGetLineInfo16(%04x,%p[line %08lx],%08lx)\n",
+		hmix,lpml,lpml->dwDestination,fdwInfo
+	);
+	return mixMessage(devid,MXDM_GETLINEINFO,0,(DWORD)lpml,fdwInfo);
+}
+
+/**************************************************************************
+ * 				mixerSetControlDetails	[WINMM.111]
+ */
+UINT32 mixerSetControlDetails32(HMIXEROBJ32 hmix,LPMIXERCONTROLDETAILS32 lpmcd,DWORD fdwDetails) {
+	fprintf(stderr,"mixerSetControlDetails32(%04x,%p,%08lx),stub!\n",
+		hmix,lpmcd,fdwDetails
+	);
+	return MMSYSERR_NOTENABLED;
+}
+
+/**************************************************************************
+ * 				mixerSetControlDetails	[MMSYSTEM.809]
+ */
+UINT16 mixerSetControlDetails16(HMIXEROBJ16 hmix,LPMIXERCONTROLDETAILS16 lpmcd,DWORD fdwDetails) {
+	fprintf(stderr,"mixerSetControlDetails16(%04x,%p,%08lx),stub!\n",
+		hmix,lpmcd,fdwDetails
+	);
+	return MMSYSERR_NOTENABLED;
+}
+
+/**************************************************************************
+ * 				mixerMessage		[WINMM.109]
+ */
+UINT32 mixerMessage32(HMIXER32 hmix,UINT32 uMsg,DWORD dwParam1,DWORD dwParam2) {
+	LPMIXEROPENDESC	lpmod;
+	UINT16	uDeviceID;
+
+	lpmod = (LPMIXEROPENDESC)USER_HEAP_LIN_ADDR(hmix);
+	if (lpmod)
+		uDeviceID = lpmod->uDeviceID;
+	else
+		uDeviceID = 0;
+	fprintf(stderr,"mixerMessage(%04lx,%d,%08lx,%08lx)\n",(DWORD)hmix,uMsg,dwParam1,dwParam2);
+	return mixMessage(uDeviceID,uMsg,0L,dwParam1,dwParam2);
+}
+
+/**************************************************************************
+ * 				mixerMessage		[MMSYSTEM.804]
+ */
+UINT16 mixerMessage16(HMIXER16 hmix,UINT16 uMsg,DWORD dwParam1,DWORD dwParam2) {
+	LPMIXEROPENDESC	lpmod;
+	UINT16	uDeviceID;
+
+	lpmod = (LPMIXEROPENDESC)USER_HEAP_LIN_ADDR(hmix);
+	if (lpmod)
+		uDeviceID = lpmod->uDeviceID;
+	else
+		uDeviceID = 0;
+	fprintf(stderr,"mixerMessage(%04x,%d,%08lx,%08lx)\n",hmix,uMsg,dwParam1,dwParam2);
+	return mixMessage(uDeviceID,uMsg,0L,dwParam1,dwParam2);
+}
+
+/**************************************************************************
+ * 				auxGetNumDevs		[WINMM.22]
+ */
+UINT32 WINAPI auxGetNumDevs32()
+{
+	return auxGetNumDevs16();
+}
+
+/**************************************************************************
+ * 				auxGetNumDevs		[MMSYSTEM.350]
+ */
+UINT16 WINAPI auxGetNumDevs16()
 {
 	UINT16	count = 0;
 	dprintf_mmsys(stddeb, "auxGetNumDevs !\n");
@@ -343,48 +713,156 @@
 }
 
 /**************************************************************************
-* 				auxGetDevCaps		[MMSYSTEM.351]
-*/
-UINT16 WINAPI auxGetDevCaps(UINT16 uDeviceID, AUXCAPS * lpCaps, UINT16 uSize)
+ * 				auxGetDevCaps		[WINMM.20]
+ */
+UINT32 WINAPI auxGetDevCaps32W(UINT32 uDeviceID,LPAUXCAPS32W lpCaps,UINT32 uSize)
+{
+	AUXCAPS16	ac16;
+	UINT32	ret = auxGetDevCaps16(uDeviceID,&ac16,sizeof(ac16));
+
+	lpCaps->wMid = ac16.wMid;
+	lpCaps->wPid = ac16.wPid;
+	lpCaps->vDriverVersion = ac16.vDriverVersion;
+	lstrcpyAtoW(lpCaps->szPname,ac16.szPname);
+	lpCaps->wTechnology = ac16.wTechnology;
+	lpCaps->dwSupport = ac16.dwSupport;
+	return ret;
+}
+
+/**************************************************************************
+ * 				auxGetDevCaps		[WINMM.21]
+ */
+UINT32 WINAPI auxGetDevCaps32A(UINT32 uDeviceID,LPAUXCAPS32A lpCaps,UINT32 uSize)
+{
+	AUXCAPS16	ac16;
+	UINT32	ret = auxGetDevCaps16(uDeviceID,&ac16,sizeof(ac16));
+
+	lpCaps->wMid = ac16.wMid;
+	lpCaps->wPid = ac16.wPid;
+	lpCaps->vDriverVersion = ac16.vDriverVersion;
+	strcpy(lpCaps->szPname,ac16.szPname);
+	lpCaps->wTechnology = ac16.wTechnology;
+	lpCaps->dwSupport = ac16.dwSupport;
+	return ret;
+}
+
+/**************************************************************************
+ * 				auxGetDevCaps		[MMSYSTEM.351]
+ */
+UINT16 WINAPI auxGetDevCaps16(UINT16 uDeviceID,LPAUXCAPS16 lpCaps, UINT16 uSize)
 {
 	dprintf_mmsys(stddeb, "auxGetDevCaps(%04X, %p, %d) !\n", 
 					uDeviceID, lpCaps, uSize);
-	return auxMessage(uDeviceID, AUXDM_GETDEVCAPS, 
+	return auxMessage(uDeviceID, AUXDM_GETDEVCAPS,
 				0L, (DWORD)lpCaps, (DWORD)uSize);
 }
 
 /**************************************************************************
-* 				auxGetVolume		[MMSYSTEM.352]
-*/
-UINT16 WINAPI auxGetVolume(UINT16 uDeviceID, DWORD * lpdwVolume)
+ * 				auxGetVolume		[WINM.23]
+ */
+UINT32 WINAPI auxGetVolume32(UINT32 uDeviceID, DWORD * lpdwVolume)
+{
+	return auxGetVolume16(uDeviceID,lpdwVolume);
+}
+
+/**************************************************************************
+ * 				auxGetVolume		[MMSYSTEM.352]
+ */
+UINT16 WINAPI auxGetVolume16(UINT16 uDeviceID, DWORD * lpdwVolume)
 {
 	dprintf_mmsys(stddeb, "auxGetVolume(%04X, %p) !\n", uDeviceID, lpdwVolume);
 	return auxMessage(uDeviceID, AUXDM_GETVOLUME, 0L, (DWORD)lpdwVolume, 0L);
 }
 
 /**************************************************************************
-* 				auxSetVolume		[MMSYSTEM.353]
-*/
-UINT16 WINAPI auxSetVolume(UINT16 uDeviceID, DWORD dwVolume)
+ * 				auxSetVolume		[WINMM.25]
+ */
+UINT32 WINAPI auxSetVolume32(UINT32 uDeviceID, DWORD dwVolume)
+{
+	return auxSetVolume16(uDeviceID,dwVolume);
+}
+
+/**************************************************************************
+ * 				auxSetVolume		[MMSYSTEM.353]
+ */
+UINT16 WINAPI auxSetVolume16(UINT16 uDeviceID, DWORD dwVolume)
 {
 	dprintf_mmsys(stddeb, "auxSetVolume(%04X, %08lX) !\n", uDeviceID, dwVolume);
 	return auxMessage(uDeviceID, AUXDM_SETVOLUME, 0L, dwVolume, 0L);
 }
 
 /**************************************************************************
-* 				auxOutMessage		[MMSYSTEM.354]
-*/
-DWORD WINAPI auxOutMessage(UINT16 uDeviceID, UINT16 uMessage, DWORD dw1, DWORD dw2)
+ * 				auxOutMessage		[MMSYSTEM.354]
+ */
+DWORD WINAPI auxOutMessage32(UINT32 uDeviceID,UINT32 uMessage,DWORD dw1,DWORD dw2)
+{
+	switch (uMessage) {
+	case AUXDM_GETNUMDEVS:
+	case AUXDM_GETVOLUME:
+	case AUXDM_SETVOLUME:
+		/* no argument conversion needed */
+		break;
+	case AUXDM_GETDEVCAPS:
+		return auxGetDevCaps32A(uDeviceID,(LPAUXCAPS32A)dw1,dw2);
+	default:
+		fprintf(stderr,"unhandled auxMessage32(%04x,%04x,%08lx,%08lx)\n",
+			uDeviceID,uMessage,dw1,dw2
+		);
+		break;
+	}
+	return auxMessage(uDeviceID,uMessage,0L,dw1,dw2);
+}
+
+/**************************************************************************
+ * 				auxOutMessage		[MMSYSTEM.354]
+ */
+DWORD WINAPI auxOutMessage16(UINT16 uDeviceID, UINT16 uMessage, DWORD dw1, DWORD dw2)
 {
 	dprintf_mmsys(stddeb, "auxOutMessage(%04X, %04X, %08lX, %08lX)\n", 
 				uDeviceID, uMessage, dw1, dw2);
+	switch (uMessage) {
+	case AUXDM_GETNUMDEVS:
+	case AUXDM_SETVOLUME:
+		/* no argument conversion needed */
+		break;
+	case AUXDM_GETVOLUME:
+		return auxGetVolume16(uDeviceID,(LPDWORD)PTR_SEG_TO_LIN(dw1));
+	case AUXDM_GETDEVCAPS:
+		return auxGetDevCaps16(uDeviceID,(LPAUXCAPS16)PTR_SEG_TO_LIN(dw1),dw2);
+	default:
+		fprintf(stderr,"unhandled auxMessage32(%04x,%04x,%08lx,%08lx)\n",
+			uDeviceID,uMessage,dw1,dw2
+		);
+		break;
+	}
 	return auxMessage(uDeviceID, uMessage, 0L, dw1, dw2);
 }
 
 /**************************************************************************
-* 				mciGetErrorString		[MMSYSTEM.706]
-*/
-BOOL16 WINAPI mciGetErrorString (DWORD wError, LPSTR lpstrBuffer, UINT16 uLength)
+ * 				mciGetErrorStringW		[WINMM.46]
+ */
+BOOL32 WINAPI mciGetErrorString32W(DWORD wError,LPWSTR lpstrBuffer,UINT32 uLength)
+{
+	LPSTR	bufstr = HeapAlloc(GetProcessHeap(),0,uLength);
+	BOOL32	ret = mciGetErrorString32A(wError,bufstr,uLength);
+
+	lstrcpyAtoW(lpstrBuffer,bufstr);
+	HeapFree(GetProcessHeap(),0,bufstr);
+	return ret;
+}
+
+/**************************************************************************
+ * 				mciGetErrorStringA		[WINMM.45]
+ */
+BOOL32 WINAPI mciGetErrorString32A(DWORD wError,LPSTR lpstrBuffer,UINT32 uLength)
+{
+	return mciGetErrorString16(wError,lpstrBuffer,uLength);
+}
+
+/**************************************************************************
+ * 				mciGetErrorString		[MMSYSTEM.706]
+ */
+BOOL16 WINAPI mciGetErrorString16(DWORD wError,LPSTR lpstrBuffer,UINT16 uLength)
 {
 	LPSTR	msgptr;
 	dprintf_mmsys(stddeb, "mciGetErrorString(%08lX, %p, %d);\n", wError, lpstrBuffer, uLength);
@@ -650,7 +1128,7 @@
 		default:
 			msgptr = "Unknown MCI Error !\n";
 			break;
-		}
+	}
         lstrcpyn32A(lpstrBuffer, msgptr, uLength);
 	dprintf_mmsys(stddeb, "mciGetErrorString // msg = %s;\n", msgptr);
 	return TRUE;
@@ -658,8 +1136,8 @@
 
 
 /**************************************************************************
-* 				mciDriverNotify			[MMSYSTEM.711]
-*/
+ * 				mciDriverNotify			[MMSYSTEM.711]
+ */
 BOOL16 WINAPI mciDriverNotify(HWND16 hWndCallBack, UINT16 wDevID, UINT16 wStatus)
 {
 	dprintf_mmsys(stddeb, "mciDriverNotify(%04X, %u, %04X)\n", hWndCallBack, wDevID, wStatus);
@@ -671,13 +1149,13 @@
 }
 
 /**************************************************************************
-* 				mciOpen					[internal]
-*/
+ * 			mciOpen					[internal]
+ */
 
-DWORD mciOpen(DWORD dwParam, LPMCI_OPEN_PARMS lp16Parms)
+DWORD mciOpen(DWORD dwParam, LPMCI_OPEN_PARMS16 lp16Parms)
 {
 	char	str[128];
-	LPMCI_OPEN_PARMS lpParms;
+	LPMCI_OPEN_PARMS16 lpParms;
 	UINT16	uDevTyp = 0;
 	UINT16	wDevID = MMSYSTEM_FirstDevID();
 	DWORD dwret;
@@ -736,20 +1214,20 @@
 	if (dwParam & MCI_OPEN_ALIAS) {
 		dprintf_mmsys(stddeb, "MCI_OPEN // Alias='%s' !\n",
 			(char*)PTR_SEG_TO_LIN(lpParms->lpstrAlias));
-                GetOpenDrv(wDevID)->lpstrAlias = SEGPTR_GET(
+                GetOpenDrv(wDevID)->lpstrAlias = (LPSTR)SEGPTR_GET(
                     SEGPTR_STRDUP((char*)PTR_SEG_TO_LIN(lpParms->lpstrAlias)));
 		/* mplayer does allocate alias to CDAUDIO */
 	}
 	if (dwParam & MCI_OPEN_TYPE) {
 		if (dwParam & MCI_OPEN_TYPE_ID) {
-			dprintf_mmsys(stddeb, "MCI_OPEN // Dev=%08lx !\n", lpParms->lpstrDeviceType);
+			dprintf_mmsys(stddeb, "MCI_OPEN // Dev=%08lx!\n", (DWORD)lpParms->lpstrDeviceType);
 			uDevTyp = LOWORD((DWORD)lpParms->lpstrDeviceType);
- 			GetOpenDrv(wDevID)->lpstrDeviceType=lpParms->lpstrDeviceType;
+ 			GetOpenDrv(wDevID)->lpstrDeviceType=(LPSTR)lpParms->lpstrDeviceType;
 		} else {
-			if (lpParms->lpstrDeviceType == (SEGPTR)NULL) return MCIERR_INTERNAL;
+			if (lpParms->lpstrDeviceType == NULL) return MCIERR_INTERNAL;
 			dprintf_mmsys(stddeb, "MCI_OPEN // Dev='%s' !\n",
                               (char*)PTR_SEG_TO_LIN(lpParms->lpstrDeviceType));
-                        GetOpenDrv(wDevID)->lpstrDeviceType = SEGPTR_GET(
+                        GetOpenDrv(wDevID)->lpstrDeviceType=(LPSTR)SEGPTR_GET(
               SEGPTR_STRDUP((char*)PTR_SEG_TO_LIN(lpParms->lpstrDeviceType)));
 			strcpy(str, PTR_SEG_TO_LIN(lpParms->lpstrDeviceType));
 			CharUpper32A(str);
@@ -797,7 +1275,7 @@
 	  dprintf_mmsys(stddeb, "MCI_OPEN // No DIGITAL_VIDEO yet !\n");
 	  return MCIERR_DEVICE_NOT_INSTALLED;
         default:
-	  dprintf_mmsys(stddeb, "MCI_OPEN // Invalid Device Name '%08lx' !\n", lpParms->lpstrDeviceType);
+	  dprintf_mmsys(stddeb, "MCI_OPEN // Invalid Device Name '%08lx' !\n", (DWORD)lpParms->lpstrDeviceType);
 	  return MCIERR_INVALID_DEVICE_NAME;
         }
 
@@ -856,9 +1334,9 @@
 
 
 /**************************************************************************
-* 				mciSysinfo				[internal]
+* 			mciSysinfo				[internal]
 */
-DWORD mciSysInfo(DWORD dwFlags, LPMCI_SYSINFO_PARMS lpParms)
+DWORD mciSysInfo(DWORD dwFlags, LPMCI_SYSINFO_PARMS16 lpParms)
 {
 	int	len;
 	LPSTR	ptr;
@@ -868,44 +1346,44 @@
 	dprintf_mci(stddeb, "mciSysInfo(%08lX, %08lX)\n", dwFlags, (DWORD)lpParms);
 	lpstrReturn = PTR_SEG_TO_LIN(lpParms->lpstrReturn);
 	switch(dwFlags) {
-		case MCI_SYSINFO_QUANTITY:
-			dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_QUANTITY \n");
-			lpdwRet = (DWORD *)lpstrReturn;
-			*(lpdwRet) = InstalledCount;		
-			return 0;
-		case MCI_SYSINFO_INSTALLNAME:
-			dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_INSTALLNAME \n");
-			if (lpInstallNames == NULL) {
-				InstalledCount = 0;
-				InstalledListLen = 0;
-				ptr = lpInstallNames = xmalloc(2048);
-				GetPrivateProfileString32A("mci", NULL, "", lpInstallNames, 2000, SysFile);
-				while(strlen(ptr) > 0) {
-					dprintf_mci(stddeb, "---> '%s' \n", ptr);
-					len = strlen(ptr) + 1;
-					ptr += len;
-					InstalledListLen += len;
-					InstalledCount++;
-				}
+	case MCI_SYSINFO_QUANTITY:
+		dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_QUANTITY \n");
+		lpdwRet = (DWORD *)lpstrReturn;
+		*(lpdwRet) = InstalledCount;
+		return 0;
+	case MCI_SYSINFO_INSTALLNAME:
+		dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_INSTALLNAME \n");
+		if (lpInstallNames == NULL) {
+			InstalledCount = 0;
+			InstalledListLen = 0;
+			ptr = lpInstallNames = xmalloc(2048);
+			GetPrivateProfileString32A("mci", NULL, "", lpInstallNames, 2000, SysFile);
+			while(strlen(ptr) > 0) {
+				dprintf_mci(stddeb, "---> '%s' \n", ptr);
+				len = strlen(ptr) + 1;
+				ptr += len;
+				InstalledListLen += len;
+				InstalledCount++;
 			}
-			if (lpParms->dwRetSize < InstalledListLen)
-				lstrcpyn32A(lpstrReturn, lpInstallNames, lpParms->dwRetSize - 1);
-			else
-				strcpy(lpstrReturn, lpInstallNames);
-			return 0;
-		case MCI_SYSINFO_NAME:
-			dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_NAME \n");
-			return 0;
-		case MCI_SYSINFO_OPEN:
-			dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_OPEN \n");
-			return 0;
 		}
+		if (lpParms->dwRetSize < InstalledListLen)
+			lstrcpyn32A(lpstrReturn, lpInstallNames, lpParms->dwRetSize - 1);
+		else
+			strcpy(lpstrReturn, lpInstallNames);
+		return 0;
+	case MCI_SYSINFO_NAME:
+		dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_NAME \n");
+		return 0;
+	case MCI_SYSINFO_OPEN:
+		dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_OPEN \n");
+		return 0;
+	}
 	return MMSYSERR_INVALPARAM;
 }
 
 /**************************************************************************
-* 				mciSound				[internal]
-*  not used anymore ??
+ * 			mciSound				[internal]
+ *  not used anymore ??
 
 DWORD mciSound(UINT16 wDevID, DWORD dwParam, LPMCI_SOUND_PARMS lpParms)
 {
@@ -914,8 +1392,8 @@
 		dprintf_mci(stddeb, "MCI_SOUND // file='%s' !\n", lpParms->lpstrSoundName);
 	return MCIERR_INVALID_DEVICE_ID;
 }
-*
-*/
+ *
+ */
 
 static const char *_mciCommandToString(UINT16 wMsg)
 {
@@ -974,13 +1452,13 @@
     switch(wMsg)
     {
     case MCI_OPEN:
-        return mciOpen(dwParam1, (LPMCI_OPEN_PARMS)dwParam2);
+        return mciOpen(dwParam1, (LPMCI_OPEN_PARMS16)dwParam2);
     case MCI_CLOSE:
         return mciClose( wDevID, dwParam1,
                          (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
     case MCI_SYSINFO:
         return mciSysInfo( dwParam1,
-                           (LPMCI_SYSINFO_PARMS)PTR_SEG_TO_LIN(dwParam2));
+                           (LPMCI_SYSINFO_PARMS16)PTR_SEG_TO_LIN(dwParam2));
     default:
         switch(GetDrv(wDevID)->wType)
         {
@@ -1069,9 +1547,16 @@
 }
 
 /**************************************************************************
-* 				midiOutGetNumDevs	[MMSYSTEM.201]
-*/
-UINT16 WINAPI midiOutGetNumDevs(void)
+ * 				midiOutGetNumDevs	[WINMM.80]
+ */
+UINT32 WINAPI midiOutGetNumDevs32(void)
+{
+	return midiOutGetNumDevs16();
+}
+/**************************************************************************
+ * 				midiOutGetNumDevs	[MMSYSTEM.201]
+ */
+UINT16 WINAPI midiOutGetNumDevs16(void)
 {
 	UINT16	count = 0;
 	dprintf_mmsys(stddeb, "midiOutGetNumDevs\n");
@@ -1081,27 +1566,89 @@
 }
 
 /**************************************************************************
-* 				midiOutGetDevCaps	[MMSYSTEM.202]
-*/
-UINT16 WINAPI midiOutGetDevCaps(UINT16 uDeviceID, MIDIOUTCAPS * lpCaps, UINT16 uSize)
+ * 				midiOutGetDevCapsW	[WINMM.76]
+ */
+UINT32 WINAPI midiOutGetDevCaps32W(UINT32 uDeviceID,LPMIDIOUTCAPS32W lpCaps, UINT32 uSize)
+{
+	MIDIOUTCAPS16	moc16;
+	UINT32		ret;
+
+	ret = midiOutGetDevCaps16(uDeviceID,&moc16,sizeof(moc16));
+	lpCaps->wMid		= moc16.wMid;
+	lpCaps->wPid		= moc16.wPid;
+	lpCaps->vDriverVersion	= moc16.vDriverVersion;
+	lstrcpyAtoW(lpCaps->szPname,moc16.szPname);
+	lpCaps->wTechnology	= moc16.wTechnology;
+	lpCaps->wVoices		= moc16.wVoices;
+	lpCaps->wNotes		= moc16.wNotes;
+	lpCaps->wChannelMask	= moc16.wChannelMask;
+	lpCaps->dwSupport	= moc16.dwSupport;
+	return ret;
+}
+/**************************************************************************
+ * 				midiOutGetDevCapsA	[WINMM.75]
+ */
+UINT32 WINAPI midiOutGetDevCaps32A(UINT32 uDeviceID,LPMIDIOUTCAPS32A lpCaps, UINT32 uSize)
+{
+	MIDIOUTCAPS16	moc16;
+	UINT32		ret;
+
+	ret = midiOutGetDevCaps16(uDeviceID,&moc16,sizeof(moc16));
+	lpCaps->wMid		= moc16.wMid;
+	lpCaps->wPid		= moc16.wPid;
+	lpCaps->vDriverVersion	= moc16.vDriverVersion;
+	strcpy(lpCaps->szPname,moc16.szPname);
+	lpCaps->wTechnology	= moc16.wTechnology;
+	lpCaps->wVoices		= moc16.wVoices;
+	lpCaps->wNotes		= moc16.wNotes;
+	lpCaps->wChannelMask	= moc16.wChannelMask;
+	lpCaps->dwSupport	= moc16.dwSupport;
+	return ret;
+}
+
+/**************************************************************************
+ * 				midiOutGetDevCaps	[MMSYSTEM.202]
+ */
+UINT16 WINAPI midiOutGetDevCaps16(UINT16 uDeviceID,LPMIDIOUTCAPS16 lpCaps, UINT16 uSize)
 {
 	dprintf_mmsys(stddeb, "midiOutGetDevCaps\n");
 	return modMessage(uDeviceID,MODM_GETDEVCAPS,0,(DWORD)lpCaps,uSize);
 }
 
 /**************************************************************************
-* 				midiOutGetErrorText 	[MMSYSTEM.203]
-*/
-UINT16 WINAPI midiOutGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize)
+ * 				midiOutGetErrorTextA 	[WINMM.77]
+ */
+UINT32 WINAPI midiOutGetErrorText32A(UINT32 uError, LPSTR lpText, UINT32 uSize)
 {
 	dprintf_mmsys(stddeb, "midiOutGetErrorText\n");
 	return midiGetErrorText(uError, lpText, uSize);
 }
 
+/**************************************************************************
+ * 				midiOutGetErrorTextW 	[WINMM.78]
+ */
+UINT32 WINAPI midiOutGetErrorText32W(UINT32 uError, LPWSTR lpText, UINT32 uSize)
+{
+	LPSTR	xstr = HeapAlloc(GetProcessHeap(),0,uSize);
+	UINT32	ret;
+	dprintf_mmsys(stddeb, "midiOutGetErrorText\n");
+	ret = midiGetErrorText(uError, xstr, uSize);
+	lstrcpyAtoW(lpText,xstr);
+	HeapFree(GetProcessHeap(),0,xstr);
+	return ret;
+}
+/**************************************************************************
+ * 				midiOutGetErrorText 	[MMSYSTEM.203]
+ */
+UINT16 WINAPI midiOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
+{
+	dprintf_mmsys(stddeb, "midiOutGetErrorText\n");
+	return midiGetErrorText(uError, lpText, uSize);
+}
 
 /**************************************************************************
-* 				midiGetErrorText       	[internal]
-*/
+ * 				midiGetErrorText       	[internal]
+ */
 UINT16 WINAPI midiGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize)
 {
 	LPSTR	msgptr;
@@ -1145,14 +1692,26 @@
 }
 
 /**************************************************************************
-* 				midiOutOpen    		[MMSYSTEM.204]
-*/
-UINT16 WINAPI midiOutOpen(HMIDIOUT16 * lphMidiOut, UINT16 uDeviceID,
-                          DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
+ * 				midiOutOpen    		[WINM.84]
+ */
+UINT32 WINAPI midiOutOpen32(HMIDIOUT32 * lphMidiOut, UINT32 uDeviceID,
+                            DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
+{
+	HMIDIOUT16	hmo16;
+	UINT32		ret;
+
+	ret = midiOutOpen16(&hmo16,uDeviceID,dwCallback,dwInstance,dwFlags);
+	if (lphMidiOut) *lphMidiOut = hmo16;
+	return ret;
+}
+/**************************************************************************
+ * 				midiOutOpen    		[MMSYSTEM.204]
+ */
+UINT16 WINAPI midiOutOpen16(HMIDIOUT16 * lphMidiOut, UINT16 uDeviceID,
+                            DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
 {
 	HMIDI16	hMidiOut;
 	LPMIDIOPENDESC	lpDesc;
-	LPMIDIOPENDESC	lp16Desc;
 	DWORD	dwRet = 0;
 	BOOL32	bMapperFlg = FALSE;
 	if (lphMidiOut != NULL) *lphMidiOut = 0;
@@ -1165,27 +1724,35 @@
 	}
 	hMidiOut = USER_HEAP_ALLOC(sizeof(MIDIOPENDESC));
 	if (lphMidiOut != NULL) *lphMidiOut = hMidiOut;
-	lp16Desc = (LPMIDIOPENDESC) USER_HEAP_SEG_ADDR(hMidiOut);
-	lpDesc = (LPMIDIOPENDESC) PTR_SEG_TO_LIN(lp16Desc);
-	if (lpDesc == NULL) return MMSYSERR_NOMEM;
+	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
+	if (lpDesc == NULL)
+		return MMSYSERR_NOMEM;
 	lpDesc->hMidi = hMidiOut;
 	lpDesc->dwCallback = dwCallback;
 	lpDesc->dwInstance = dwInstance;
 	while(uDeviceID < MAXMIDIDRIVERS) {
 		dwRet = modMessage(uDeviceID, MODM_OPEN, 
-			lpDesc->dwInstance, (DWORD)lp16Desc, 0L);
+			lpDesc->dwInstance, (DWORD)lpDesc, 0L);
 		if (dwRet == MMSYSERR_NOERROR) break;
 		if (!bMapperFlg) break;
 		uDeviceID++;
 		dprintf_mmsys(stddeb, "midiOutOpen	// MIDI_MAPPER mode ! try next driver...\n");
-		}
+	}
 	return dwRet;
 }
 
 /**************************************************************************
-* 				midiOutClose		[MMSYSTEM.205]
-*/
-UINT16 WINAPI midiOutClose(HMIDIOUT16 hMidiOut)
+ * 				midiOutClose		[WINMM.74]
+ */
+UINT32 WINAPI midiOutClose32(HMIDIOUT32 hMidiOut)
+{
+	return midiOutClose16(hMidiOut);
+}
+
+/**************************************************************************
+ * 				midiOutClose		[MMSYSTEM.205]
+ */
+UINT16 WINAPI midiOutClose16(HMIDIOUT16 hMidiOut)
 {
 	LPMIDIOPENDESC	lpDesc;
 	dprintf_mmsys(stddeb, "midiOutClose(%04X)\n", hMidiOut);
@@ -1195,10 +1762,19 @@
 }
 
 /**************************************************************************
-* 				midiOutPrepareHeader	[MMSYSTEM.206]
-*/
-UINT16 WINAPI midiOutPrepareHeader(HMIDIOUT16 hMidiOut,
-                                   MIDIHDR * lpMidiOutHdr, UINT16 uSize)
+ * 				midiOutPrepareHeader	[WINMM.85]
+ */
+UINT32 WINAPI midiOutPrepareHeader32(HMIDIOUT32 hMidiOut,
+                                     MIDIHDR * lpMidiOutHdr, UINT32 uSize)
+{
+	return midiOutPrepareHeader16(hMidiOut,lpMidiOutHdr,uSize);
+}
+
+/**************************************************************************
+ * 				midiOutPrepareHeader	[MMSYSTEM.206]
+ */
+UINT16 WINAPI midiOutPrepareHeader16(HMIDIOUT16 hMidiOut,
+                                     MIDIHDR * lpMidiOutHdr, UINT16 uSize)
 {
 	LPMIDIOPENDESC	lpDesc;
 	dprintf_mmsys(stddeb, "midiOutPrepareHeader(%04X, %p, %d)\n", 
@@ -1206,13 +1782,21 @@
 	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return modMessage(0, MODM_PREPARE, lpDesc->dwInstance, 
-						(DWORD)lpMidiOutHdr, (DWORD)uSize);
+			  (DWORD)lpMidiOutHdr, (DWORD)uSize);
 }
 
 /**************************************************************************
-* 				midiOutUnprepareHeader	[MMSYSTEM.207]
-*/
-UINT16 WINAPI midiOutUnprepareHeader(HMIDIOUT16 hMidiOut,
+ * 				midiOutUnprepareHeader	[WINMM.89]
+ */
+UINT32 WINAPI midiOutUnprepareHeader32(HMIDIOUT32 hMidiOut,
+                                       MIDIHDR * lpMidiOutHdr, UINT32 uSize)
+{
+	return midiOutUnprepareHeader16(hMidiOut,lpMidiOutHdr,uSize);
+}
+/**************************************************************************
+ * 				midiOutUnprepareHeader	[MMSYSTEM.207]
+ */
+UINT16 WINAPI midiOutUnprepareHeader16(HMIDIOUT16 hMidiOut,
                                      MIDIHDR * lpMidiOutHdr, UINT16 uSize)
 {
 	LPMIDIOPENDESC	lpDesc;
@@ -1225,9 +1809,16 @@
 }
 
 /**************************************************************************
-* 				midiOutShortMsg		[MMSYSTEM.208]
-*/
-UINT16 WINAPI midiOutShortMsg(HMIDIOUT16 hMidiOut, DWORD dwMsg)
+ * 				midiOutShortMsg		[WINMM.88]
+ */
+UINT32 WINAPI midiOutShortMsg32(HMIDIOUT32 hMidiOut, DWORD dwMsg)
+{
+	return midiOutShortMsg16(hMidiOut,dwMsg);
+}
+/**************************************************************************
+ * 				midiOutShortMsg		[MMSYSTEM.208]
+ */
+UINT16 WINAPI midiOutShortMsg16(HMIDIOUT16 hMidiOut, DWORD dwMsg)
 {
 	LPMIDIOPENDESC	lpDesc;
 	dprintf_mmsys(stddeb, "midiOutShortMsg(%04X, %08lX)\n", hMidiOut, dwMsg);
@@ -1237,10 +1828,19 @@
 }
 
 /**************************************************************************
-* 				midiOutLongMsg		[MMSYSTEM.209]
-*/
-UINT16 WINAPI midiOutLongMsg(HMIDIOUT16 hMidiOut,
-                             MIDIHDR * lpMidiOutHdr, UINT16 uSize)
+ * 				midiOutLongMsg		[WINMM.82]
+ */
+UINT32 WINAPI midiOutLongMsg32(HMIDIOUT32 hMidiOut,
+                               MIDIHDR * lpMidiOutHdr, UINT32 uSize)
+{
+	return midiOutLongMsg16(hMidiOut,lpMidiOutHdr,uSize);
+}
+
+/**************************************************************************
+ * 				midiOutLongMsg		[MMSYSTEM.209]
+ */
+UINT16 WINAPI midiOutLongMsg16(HMIDIOUT16 hMidiOut,
+                               MIDIHDR * lpMidiOutHdr, UINT16 uSize)
 {
 	LPMIDIOPENDESC	lpDesc;
 	dprintf_mmsys(stddeb, "midiOutLongMsg(%04X, %p, %d)\n", 
@@ -1252,9 +1852,17 @@
 }
 
 /**************************************************************************
-* 				midiOutReset		[MMSYSTEM.210]
-*/
-UINT16 WINAPI midiOutReset(HMIDIOUT16 hMidiOut)
+ * 				midiOutReset		[WINMM.86]
+ */
+UINT32 WINAPI midiOutReset32(HMIDIOUT32 hMidiOut)
+{
+	return midiOutReset16(hMidiOut);
+}
+
+/**************************************************************************
+ * 				midiOutReset		[MMSYSTEM.210]
+ */
+UINT16 WINAPI midiOutReset16(HMIDIOUT16 hMidiOut)
 {
 	LPMIDIOPENDESC	lpDesc;
 	dprintf_mmsys(stddeb, "midiOutReset(%04X)\n", hMidiOut);
@@ -1264,30 +1872,52 @@
 }
 
 /**************************************************************************
-* 				midiOutGetVolume	[MMSYSTEM.211]
-*/
-UINT16 WINAPI midiOutGetVolume(UINT16 uDeviceID, DWORD * lpdwVolume)
+ * 				midiOutGetVolume	[WINM.81]
+ */
+UINT32 WINAPI midiOutGetVolume32(UINT32 uDeviceID, DWORD * lpdwVolume)
+{
+	return midiOutGetVolume16(uDeviceID,lpdwVolume);
+}
+/**************************************************************************
+ * 				midiOutGetVolume	[MMSYSTEM.211]
+ */
+UINT16 WINAPI midiOutGetVolume16(UINT16 uDeviceID, DWORD * lpdwVolume)
 {
 	dprintf_mmsys(stddeb, "midiOutGetVolume(%04X, %p);\n", uDeviceID, lpdwVolume);
 	return modMessage(uDeviceID, MODM_GETVOLUME, 0L, (DWORD)lpdwVolume, 0L);
-	return 0;
 }
 
 /**************************************************************************
-* 				midiOutSetVolume	[MMSYSTEM.212]
-*/
-UINT16 WINAPI midiOutSetVolume(UINT16 uDeviceID, DWORD dwVolume)
+ * 				midiOutSetVolume	[WINMM.87]
+ */
+UINT32 WINAPI midiOutSetVolume32(UINT32 uDeviceID, DWORD dwVolume)
+{
+	return midiOutSetVolume16(uDeviceID,dwVolume);
+}
+
+/**************************************************************************
+ * 				midiOutSetVolume	[MMSYSTEM.212]
+ */
+UINT16 WINAPI midiOutSetVolume16(UINT16 uDeviceID, DWORD dwVolume)
 {
 	dprintf_mmsys(stddeb, "midiOutSetVolume(%04X, %08lX);\n", uDeviceID, dwVolume);
 	return modMessage(uDeviceID, MODM_SETVOLUME, 0L, dwVolume, 0L);
-	return 0;
 }
 
 /**************************************************************************
-* 				midiOutCachePatches		[MMSYSTEM.213]
-*/
-UINT16 WINAPI midiOutCachePatches(HMIDIOUT16 hMidiOut, UINT16 uBank,
-                                  WORD * lpwPatchArray, UINT16 uFlags)
+ * 				midiOutCachePatches		[WINMM.73]
+ */
+UINT32 WINAPI midiOutCachePatches32(HMIDIOUT32 hMidiOut, UINT32 uBank,
+                                    WORD * lpwPatchArray, UINT32 uFlags)
+{
+	return midiOutCachePatches16(hMidiOut,uBank,lpwPatchArray,uFlags);
+}
+
+/**************************************************************************
+ * 				midiOutCachePatches		[MMSYSTEM.213]
+ */
+UINT16 WINAPI midiOutCachePatches16(HMIDIOUT16 hMidiOut, UINT16 uBank,
+                                    WORD * lpwPatchArray, UINT16 uFlags)
 {
         /* not really necessary to support this */
 	fprintf(stdnimp, "midiOutCachePatches: not supported yet\n");
@@ -1295,43 +1925,134 @@
 }
 
 /**************************************************************************
-* 				midiOutCacheDrumPatches	[MMSYSTEM.214]
-*/
-UINT16 WINAPI midiOutCacheDrumPatches(HMIDIOUT16 hMidiOut, UINT16 uPatch,
-                                      WORD * lpwKeyArray, UINT16 uFlags)
+ * 				midiOutCacheDrumPatches	[WINMM.72]
+ */
+UINT32 WINAPI midiOutCacheDrumPatches32(HMIDIOUT32 hMidiOut, UINT32 uPatch,
+                                        WORD * lpwKeyArray, UINT32 uFlags)
+{
+	return midiOutCacheDrumPatches16(hMidiOut,uPatch,lpwKeyArray,uFlags);
+}
+
+/**************************************************************************
+ * 				midiOutCacheDrumPatches	[MMSYSTEM.214]
+ */
+UINT16 WINAPI midiOutCacheDrumPatches16(HMIDIOUT16 hMidiOut, UINT16 uPatch,
+                                        WORD * lpwKeyArray, UINT16 uFlags)
 {
 	fprintf(stdnimp, "midiOutCacheDrumPatchesi: not supported yet\n");
 	return MMSYSERR_NOTSUPPORTED;
 }
 
 /**************************************************************************
-* 				midiOutGetID		[MMSYSTEM.215]
-*/
-UINT16 WINAPI midiOutGetID(HMIDIOUT16 hMidiOut, UINT16 * lpuDeviceID)
+ * 				midiOutGetID		[WINMM.79]
+ */
+UINT32 WINAPI midiOutGetID32(HMIDIOUT32 hMidiOut, UINT32 * lpuDeviceID)
+{
+	UINT16	xid;
+	UINT32	ret;
+
+	ret = midiOutGetID16(hMidiOut,&xid);
+	*lpuDeviceID = xid;
+	return ret;
+}
+
+/**************************************************************************
+ * 				midiOutGetID		[MMSYSTEM.215]
+ */
+UINT16 WINAPI midiOutGetID16(HMIDIOUT16 hMidiOut, UINT16 * lpuDeviceID)
 {
 	dprintf_mmsys(stddeb, "midiOutGetID\n");
 	return 0;
 }
 
 /**************************************************************************
-* 				midiOutMessage		[MMSYSTEM.216]
-*/
-DWORD WINAPI midiOutMessage(HMIDIOUT16 hMidiOut, UINT16 uMessage, 
-                            DWORD dwParam1, DWORD dwParam2)
+ * 				midiOutMessage		[WINMM.83]
+ */
+DWORD WINAPI midiOutMessage32(HMIDIOUT32 hMidiOut, UINT32 uMessage, 
+                              DWORD dwParam1, DWORD dwParam2)
 {
 	LPMIDIOPENDESC	lpDesc;
+
 	dprintf_mmsys(stddeb, "midiOutMessage(%04X, %04X, %08lX, %08lX)\n", 
 			hMidiOut, uMessage, dwParam1, dwParam2);
 	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	switch (uMessage) {
+	case MODM_OPEN:
+		fprintf(stderr,"midiOutMessage32: can't handle MODM_OPEN!\n");
+		return 0;
+	case MODM_GETDEVCAPS:
+		return midiOutGetDevCaps32A(hMidiOut,(LPMIDIOUTCAPS32A)dwParam1,dwParam2);
+	case MODM_GETNUMDEVS:
+	case MODM_RESET:
+	case MODM_CLOSE:
+	case MODM_GETVOLUME:
+	case MODM_SETVOLUME:
+	case MODM_LONGDATA:
+	case MODM_PREPARE:
+	case MODM_UNPREPARE:
+		/* no argument conversion needed */
+		break;
+	default:
+		fprintf(stderr,"unhandled midiOutMessage32(%04x,%04x,%08lx,%08lx)\n",
+			hMidiOut,uMessage,dwParam1,dwParam2
+		);
+		break;
+	}
 	return modMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
-	return 0;
 }
 
 /**************************************************************************
-* 				midiInGetNumDevs	[MMSYSTEM.301]
-*/
-UINT16 WINAPI midiInGetNumDevs(void)
+ * 				midiOutMessage		[MMSYSTEM.216]
+ */
+DWORD WINAPI midiOutMessage16(HMIDIOUT16 hMidiOut, UINT16 uMessage, 
+                              DWORD dwParam1, DWORD dwParam2)
+{
+	LPMIDIOPENDESC	lpDesc;
+
+	dprintf_mmsys(stddeb, "midiOutMessage(%04X, %04X, %08lX, %08lX)\n", 
+			hMidiOut, uMessage, dwParam1, dwParam2);
+	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
+	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	switch (uMessage) {
+	case MODM_OPEN:
+		fprintf(stderr,"midiOutMessage16: can't handle MODM_OPEN!\n");
+		return 0;
+	case MODM_GETNUMDEVS:
+	case MODM_RESET:
+	case MODM_CLOSE:
+	case MODM_SETVOLUME:
+		/* no argument conversion needed */
+		break;
+	case MODM_GETVOLUME:
+		return midiOutGetVolume16(hMidiOut,(LPDWORD)PTR_SEG_TO_LIN(dwParam1));
+	case MODM_LONGDATA:
+		return midiOutLongMsg16(hMidiOut,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+	case MODM_PREPARE:
+		return midiOutPrepareHeader16(hMidiOut,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+	case MODM_UNPREPARE:
+		return midiOutUnprepareHeader16(hMidiOut,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+	default:
+		fprintf(stderr,"unhandled midiOutMessage16(%04x,%04x,%08lx,%08lx)\n",
+			hMidiOut,uMessage,dwParam1,dwParam2
+		);
+		break;
+	}
+	return modMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
+}
+
+/**************************************************************************
+ * 				midiInGetNumDevs	[WINMM.64]
+ */
+UINT32 WINAPI midiInGetNumDevs32(void)
+{
+	return midiInGetNumDevs16();
+}
+
+/**************************************************************************
+ * 				midiInGetNumDevs	[MMSYSTEM.301]
+ */
+UINT16 WINAPI midiInGetNumDevs16(void)
 {
 	UINT16	count = 0;
 	dprintf_mmsys(stddeb, "midiInGetNumDevs\n");
@@ -1341,35 +2062,100 @@
 }
 
 /**************************************************************************
-* 				midiInGetDevCaps	[MMSYSTEM.302]
-*/
-UINT16 WINAPI midiInGetDevCaps(UINT16 uDeviceID,
-                               LPMIDIINCAPS lpCaps, UINT16 uSize)
+ * 				midiInGetDevCaps	[WINMM.60]
+ */
+UINT32 WINAPI midiInGetDevCaps32W(UINT32 uDeviceID,
+                                  LPMIDIINCAPS32W lpCaps, UINT32 uSize)
+{
+	MIDIINCAPS16	mic16;
+	UINT32		ret = midiInGetDevCaps16(uDeviceID,&mic16,uSize);
+
+	lpCaps->wMid = mic16.wMid;
+	lpCaps->wPid = mic16.wPid;
+	lpCaps->vDriverVersion = mic16.vDriverVersion;
+	lstrcpyAtoW(lpCaps->szPname,mic16.szPname);
+	lpCaps->dwSupport = mic16.dwSupport;
+	return ret;
+}
+
+/**************************************************************************
+ * 				midiInGetDevCaps	[WINMM.59]
+ */
+UINT32 WINAPI midiInGetDevCaps32A(UINT32 uDeviceID,
+                                  LPMIDIINCAPS32A lpCaps, UINT32 uSize)
+{
+	MIDIINCAPS16	mic16;
+	UINT32		ret = midiInGetDevCaps16(uDeviceID,&mic16,uSize);
+
+	lpCaps->wMid = mic16.wMid;
+	lpCaps->wPid = mic16.wPid;
+	lpCaps->vDriverVersion = mic16.vDriverVersion;
+	strcpy(lpCaps->szPname,mic16.szPname);
+	lpCaps->dwSupport = mic16.dwSupport;
+	return ret;
+}
+
+/**************************************************************************
+ * 				midiInGetDevCaps	[MMSYSTEM.302]
+ */
+UINT16 WINAPI midiInGetDevCaps16(UINT16 uDeviceID,
+                               LPMIDIINCAPS16 lpCaps, UINT16 uSize)
 {
 	dprintf_mmsys(stddeb, "midiInGetDevCaps\n");
 	return midMessage(uDeviceID,MIDM_GETDEVCAPS,0,(DWORD)lpCaps,uSize);;
 }
 
 /**************************************************************************
-* 				midiInGetErrorText 		[MMSYSTEM.303]
-*/
-UINT16 WINAPI midiInGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize)
+ * 				midiInGetErrorText 		[WINMM.62]
+ */
+UINT32 WINAPI midiInGetErrorText32W(UINT32 uError, LPWSTR lpText, UINT32 uSize)
+{
+	LPSTR	xstr = HeapAlloc(GetProcessHeap(),0,uSize);
+	UINT32	ret = midiInGetErrorText16(uError,xstr,uSize);
+	lstrcpyAtoW(lpText,xstr);
+	HeapFree(GetProcessHeap(),0,xstr);
+	return ret;
+}
+/**************************************************************************
+ * 				midiInGetErrorText 		[WINMM.61]
+ */
+UINT32 WINAPI midiInGetErrorText32A(UINT32 uError, LPSTR lpText, UINT32 uSize)
+{
+	return midiInGetErrorText16(uError,lpText,uSize);
+}
+
+/**************************************************************************
+ * 				midiInGetErrorText 		[MMSYSTEM.303]
+ */
+UINT16 WINAPI midiInGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
 {
 	dprintf_mmsys(stddeb, "midiInGetErrorText\n");
 	return (midiGetErrorText(uError, lpText, uSize));
 }
 
 /**************************************************************************
-* 				midiInOpen		[MMSYSTEM.304]
-*/
-UINT16 WINAPI midiInOpen(HMIDIIN16 * lphMidiIn, UINT16 uDeviceID,
-                         DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
+ * 				midiInOpen		[WINMM.66]
+ */
+UINT32 WINAPI midiInOpen32(HMIDIIN32 * lphMidiIn, UINT32 uDeviceID,
+                           DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
+{
+	HMIDIIN16	xhmid16;
+	UINT32 ret = midiInOpen16(&xhmid16,uDeviceID,dwCallback,dwInstance,dwFlags);
+	if (lphMidiIn) *lphMidiIn = xhmid16;
+	return ret;
+}
+
+/**************************************************************************
+ * 				midiInOpen		[MMSYSTEM.304]
+ */
+UINT16 WINAPI midiInOpen16(HMIDIIN16 * lphMidiIn, UINT16 uDeviceID,
+                           DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
 {
 	HMIDI16	hMidiIn;
 	LPMIDIOPENDESC	lpDesc;
-	LPMIDIOPENDESC	lp16Desc;
 	DWORD	dwRet = 0;
 	BOOL32	bMapperFlg = FALSE;
+
 	if (lphMidiIn != NULL) *lphMidiIn = 0;
 	dprintf_mmsys(stddeb, "midiInOpen(%p, %d, %08lX, %08lX, %08lX);\n", 
 		lphMidiIn, uDeviceID, dwCallback, dwInstance, dwFlags);
@@ -1377,11 +2163,10 @@
 		dprintf_mmsys(stddeb, "midiInOpen	// MIDI_MAPPER mode requested !\n");
 		bMapperFlg = TRUE;
 		uDeviceID = 0;
-		}
+	}
 	hMidiIn = USER_HEAP_ALLOC(sizeof(MIDIOPENDESC));
 	if (lphMidiIn != NULL) *lphMidiIn = hMidiIn;
-	lp16Desc = (LPMIDIOPENDESC) USER_HEAP_SEG_ADDR(hMidiIn);
-	lpDesc = (LPMIDIOPENDESC) PTR_SEG_TO_LIN(lp16Desc);
+	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
 	if (lpDesc == NULL) return MMSYSERR_NOMEM;
 	lpDesc->hMidi = hMidiIn;
 	lpDesc->dwCallback = dwCallback;
@@ -1393,14 +2178,22 @@
 		if (!bMapperFlg) break;
 		uDeviceID++;
 		dprintf_mmsys(stddeb, "midiInOpen	// MIDI_MAPPER mode ! try next driver...\n");
-		}
+	}
 	return dwRet;
 }
 
 /**************************************************************************
-* 				midiInClose		[MMSYSTEM.305]
-*/
-UINT16 WINAPI midiInClose(HMIDIIN16 hMidiIn)
+ * 				midiInClose		[WINMM.58]
+ */
+UINT32 WINAPI midiInClose32(HMIDIIN32 hMidiIn)
+{
+	return midiInClose16(hMidiIn);
+}
+
+/**************************************************************************
+ * 				midiInClose		[MMSYSTEM.305]
+ */
+UINT16 WINAPI midiInClose16(HMIDIIN16 hMidiIn)
 {
 	LPMIDIOPENDESC	lpDesc;
 	dprintf_mmsys(stddeb, "midiInClose(%04X)\n", hMidiIn);
@@ -1410,10 +2203,19 @@
 }
 
 /**************************************************************************
-* 				midiInPrepareHeader	[MMSYSTEM.306]
-*/
-UINT16 WINAPI midiInPrepareHeader(HMIDIIN16 hMidiIn,
-                                  MIDIHDR * lpMidiInHdr, UINT16 uSize)
+ * 				midiInPrepareHeader	[WINMM.67]
+ */
+UINT32 WINAPI midiInPrepareHeader32(HMIDIIN32 hMidiIn,
+                                    MIDIHDR * lpMidiInHdr, UINT32 uSize)
+{
+	return midiInPrepareHeader16(hMidiIn,lpMidiInHdr,uSize);
+}
+
+/**************************************************************************
+ * 				midiInPrepareHeader	[MMSYSTEM.306]
+ */
+UINT16 WINAPI midiInPrepareHeader16(HMIDIIN16 hMidiIn,
+                                    MIDIHDR * lpMidiInHdr, UINT16 uSize)
 {
 	LPMIDIOPENDESC	lpDesc;
 	dprintf_mmsys(stddeb, "midiInPrepareHeader(%04X, %p, %d)\n", 
@@ -1425,10 +2227,19 @@
 }
 
 /**************************************************************************
-* 				midiInUnprepareHeader	[MMSYSTEM.307]
-*/
-UINT16 WINAPI midiInUnprepareHeader(HMIDIIN16 hMidiIn,
-                                    MIDIHDR * lpMidiInHdr, UINT16 uSize)
+ * 				midiInUnprepareHeader	[WINMM.71]
+ */
+UINT32 WINAPI midiInUnprepareHeader32(HMIDIIN32 hMidiIn,
+                                      MIDIHDR * lpMidiInHdr, UINT32 uSize)
+{
+	return midiInUnprepareHeader16(hMidiIn,lpMidiInHdr,uSize);
+}
+
+/**************************************************************************
+ * 				midiInUnprepareHeader	[MMSYSTEM.307]
+ */
+UINT16 WINAPI midiInUnprepareHeader16(HMIDIIN16 hMidiIn,
+                                      MIDIHDR * lpMidiInHdr, UINT16 uSize)
 {
 	LPMIDIOPENDESC	lpDesc;
 	dprintf_mmsys(stddeb, "midiInUnprepareHeader(%04X, %p, %d)\n", 
@@ -1440,70 +2251,183 @@
 }
 
 /**************************************************************************
-* 				midiInAddBuffer		[MMSYSTEM.308]
-*/
-UINT16 WINAPI midiInAddBuffer(HMIDIIN16 hMidiIn,
-                              MIDIHDR * lpMidiInHdr, UINT16 uSize)
+ * 				midiInAddBuffer		[WINMM.57]
+ */
+UINT32 WINAPI midiInAddBuffer32(HMIDIIN32 hMidiIn,
+                                MIDIHDR * lpMidiInHdr, UINT32 uSize)
+{
+	return midiInAddBuffer16(hMidiIn,lpMidiInHdr,uSize);
+}
+
+/**************************************************************************
+ * 				midiInAddBuffer		[MMSYSTEM.308]
+ */
+UINT16 WINAPI midiInAddBuffer16(HMIDIIN16 hMidiIn,
+                                MIDIHDR * lpMidiInHdr, UINT16 uSize)
 {
 	dprintf_mmsys(stddeb, "midiInAddBuffer\n");
 	return 0;
 }
 
 /**************************************************************************
-* 				midiInStart			[MMSYSTEM.309]
-*/
-UINT16 WINAPI midiInStart(HMIDIIN16 hMidiIn)
+ * 				midiInStart			[WINMM.69]
+ */
+UINT32 WINAPI midiInStart32(HMIDIIN32 hMidiIn)
+{
+	return midiInStart16(hMidiIn);
+}
+
+/**************************************************************************
+ * 				midiInStart			[MMSYSTEM.309]
+ */
+UINT16 WINAPI midiInStart16(HMIDIIN16 hMidiIn)
 {
 	dprintf_mmsys(stddeb, "midiInStart\n");
 	return 0;
 }
 
 /**************************************************************************
-* 				midiInStop			[MMSYSTEM.310]
-*/
-UINT16 WINAPI midiInStop(HMIDIIN16 hMidiIn)
+ * 				midiInStop			[WINMM.70]
+ */
+UINT32 WINAPI midiInStop32(HMIDIIN32 hMidiIn)
+{
+	return midiInStop16(hMidiIn);
+}
+
+/**************************************************************************
+ * 				midiInStop			[MMSYSTEM.310]
+ */
+UINT16 WINAPI midiInStop16(HMIDIIN16 hMidiIn)
 {
 	dprintf_mmsys(stddeb, "midiInStop\n");
 	return 0;
 }
 
 /**************************************************************************
-* 				midiInReset			[MMSYSTEM.311]
-*/
-UINT16 WINAPI midiInReset(HMIDIIN16 hMidiIn)
+ * 				midiInReset			[WINMM.68]
+ */
+UINT32 WINAPI midiInReset32(HMIDIIN32 hMidiIn)
+{
+	return midiInReset16(hMidiIn);
+}
+
+/**************************************************************************
+ * 				midiInReset			[MMSYSTEM.311]
+ */
+UINT16 WINAPI midiInReset16(HMIDIIN16 hMidiIn)
 {
 	dprintf_mmsys(stddeb, "midiInReset\n");
 	return 0;
 }
 
 /**************************************************************************
-* 				midiInGetID			[MMSYSTEM.312]
-*/
-UINT16 WINAPI midiInGetID(HMIDIIN16 hMidiIn, UINT16 * lpuDeviceID)
+ * 				midiInGetID			[WINMM.63]
+ */
+UINT32 WINAPI midiInGetID32(HMIDIIN32 hMidiIn, UINT32 * lpuDeviceID)
 {
 	dprintf_mmsys(stddeb, "midiInGetID\n");
 	return 0;
 }
 
 /**************************************************************************
-* 				midiInMessage		[MMSYSTEM.313]
-*/
-DWORD WINAPI midiInMessage(HMIDIIN16 hMidiIn, UINT16 uMessage, 
-                           DWORD dwParam1, DWORD dwParam2)
+ * 				midiInGetID			[MMSYSTEM.312]
+ */
+UINT16 WINAPI midiInGetID16(HMIDIIN16 hMidiIn, UINT16 * lpuDeviceID)
+{
+	dprintf_mmsys(stddeb, "midiInGetID\n");
+	return 0;
+}
+
+/**************************************************************************
+ * 				midiInMessage		[WINMM.65]
+ */
+DWORD WINAPI midiInMessage32(HMIDIIN32 hMidiIn, UINT32 uMessage, 
+                             DWORD dwParam1, DWORD dwParam2)
 {
 	LPMIDIOPENDESC	lpDesc;
 	dprintf_mmsys(stddeb, "midiInMessage(%04X, %04X, %08lX, %08lX)\n", 
 			hMidiIn, uMessage, dwParam1, dwParam2);
 	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	switch (uMessage) {
+	case MIDM_OPEN:
+		fprintf(stderr,"midiInMessage32: can't handle MIDM_OPEN!\n");
+		return 0;
+	case MIDM_GETDEVCAPS:
+		return midiInGetDevCaps32A(hMidiIn,(LPMIDIINCAPS32A)dwParam1,dwParam2);
+	case MIDM_GETNUMDEVS:
+	case MIDM_RESET:
+	case MIDM_STOP:
+	case MIDM_START:
+	case MIDM_CLOSE:
+		/* no argument conversion needed */
+		break;
+	case MIDM_PREPARE:
+		return midiInPrepareHeader32(hMidiIn,(LPMIDIHDR)dwParam1,dwParam2);
+	case MIDM_UNPREPARE:
+		return midiInUnprepareHeader32(hMidiIn,(LPMIDIHDR)dwParam1,dwParam2);
+	case MIDM_ADDBUFFER:
+		return midiInAddBuffer32(hMidiIn,(LPMIDIHDR)dwParam1,dwParam2);
+	default:
+		fprintf(stderr,"unhandled midiInMessage32(%04x,%04x,%08lx,%08lx)\n",
+			hMidiIn,uMessage,dwParam1,dwParam2
+		);
+		break;
+	}
+	return midMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
+}
+
+/**************************************************************************
+ * 				midiInMessage		[MMSYSTEM.313]
+ */
+DWORD WINAPI midiInMessage16(HMIDIIN16 hMidiIn, UINT16 uMessage, 
+                             DWORD dwParam1, DWORD dwParam2)
+{
+	LPMIDIOPENDESC	lpDesc;
+	dprintf_mmsys(stddeb, "midiInMessage(%04X, %04X, %08lX, %08lX)\n", 
+			hMidiIn, uMessage, dwParam1, dwParam2);
+	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
+	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	switch (uMessage) {
+	case MIDM_OPEN:
+		fprintf(stderr,"midiInMessage16: can't handle MIDM_OPEN!\n");
+		return 0;
+	case MIDM_GETDEVCAPS:
+		return midiInGetDevCaps16(hMidiIn,(LPMIDIINCAPS16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+	case MIDM_GETNUMDEVS:
+	case MIDM_RESET:
+	case MIDM_STOP:
+	case MIDM_START:
+	case MIDM_CLOSE:
+		/* no argument conversion needed */
+		break;
+	case MIDM_PREPARE:
+		return midiInPrepareHeader16(hMidiIn,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+	case MIDM_UNPREPARE:
+		return midiInUnprepareHeader16(hMidiIn,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+	case MIDM_ADDBUFFER:
+		return midiInAddBuffer16(hMidiIn,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+	default:
+		fprintf(stderr,"unhandled midiInMessage16(%04x,%04x,%08lx,%08lx)\n",
+			hMidiIn,uMessage,dwParam1,dwParam2
+		);
+		break;
+	}
 	return midMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
 }
 
 
 /**************************************************************************
-* 				waveOutGetNumDevs		[MMSYSTEM.401]
-*/
-UINT16 WINAPI waveOutGetNumDevs()
+ * 				waveOutGetNumDevs		[MMSYSTEM.401]
+ */
+UINT32 WINAPI waveOutGetNumDevs32() {
+	return waveOutGetNumDevs16();
+}
+
+/**************************************************************************
+ * 				waveOutGetNumDevs		[WINMM.167]
+ */
+UINT16 WINAPI waveOutGetNumDevs16()
 {
 	UINT16	count = 0;
 	dprintf_mmsys(stddeb, "waveOutGetNumDevs\n");
@@ -1513,31 +2437,90 @@
 }
 
 /**************************************************************************
-* 				waveOutGetDevCaps		[MMSYSTEM.402]
-*/
-UINT16 WINAPI waveOutGetDevCaps(UINT16 uDeviceID, WAVEOUTCAPS * lpCaps,
+ * 				waveOutGetDevCaps		[MMSYSTEM.402]
+ */
+UINT16 WINAPI waveOutGetDevCaps16(UINT16 uDeviceID, WAVEOUTCAPS16 * lpCaps,
                                 UINT16 uSize)
 {
-	if (uDeviceID > waveOutGetNumDevs() - 1) return MMSYSERR_BADDEVICEID;
+	if (uDeviceID > waveOutGetNumDevs16() - 1) return MMSYSERR_BADDEVICEID;
 	if (uDeviceID == (UINT16)WAVE_MAPPER) return MMSYSERR_BADDEVICEID; /* FIXME: do we have a wave mapper ? */
 	dprintf_mmsys(stddeb, "waveOutGetDevCaps\n");
 	return wodMessage(uDeviceID, WODM_GETDEVCAPS, 0L, (DWORD)lpCaps, uSize);
 }
 
 /**************************************************************************
-* 				waveOutGetErrorText 	[MMSYSTEM.403]
-*/
-UINT16 WINAPI waveOutGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize)
+ * 				waveOutGetDevCapsA		[WINMM.162]
+ */
+UINT32 WINAPI waveOutGetDevCaps32A(UINT32 uDeviceID, LPWAVEOUTCAPS32A lpCaps,
+                                UINT32 uSize)
 {
-   dprintf_mmsys(stddeb, "waveOutGetErrorText\n");
-   return(waveGetErrorText(uError, lpText, uSize));
+	WAVEOUTCAPS16	woc16;
+	UINT16 ret = waveOutGetDevCaps16(uDeviceID,&woc16,sizeof(woc16));
+	
+	lpCaps->wMid = woc16.wMid;
+	lpCaps->wPid = woc16.wPid;
+	lpCaps->vDriverVersion = woc16.vDriverVersion;
+	strcpy(lpCaps->szPname,woc16.szPname);
+	lpCaps->dwFormats = woc16.dwFormats;
+	lpCaps->wChannels = woc16.wChannels;
+	lpCaps->dwSupport = woc16.dwSupport;
+	return ret;
+}
+
+/**************************************************************************
+ * 				waveOutGetDevCapsW		[WINMM.163]
+ */
+UINT32 WINAPI waveOutGetDevCaps32W(UINT32 uDeviceID, LPWAVEOUTCAPS32W lpCaps,
+                                UINT32 uSize)
+{
+	WAVEOUTCAPS16	woc16;
+	UINT32 ret = waveOutGetDevCaps16(uDeviceID,&woc16,sizeof(woc16));
+
+	lpCaps->wMid = woc16.wMid;
+	lpCaps->wPid = woc16.wPid;
+	lpCaps->vDriverVersion = woc16.vDriverVersion;
+	lstrcpyAtoW(lpCaps->szPname,woc16.szPname);
+	lpCaps->dwFormats = woc16.dwFormats;
+	lpCaps->wChannels = woc16.wChannels;
+	lpCaps->dwSupport = woc16.dwSupport;
+	return ret;
+}
+
+/**************************************************************************
+ * 				waveOutGetErrorText 	[MMSYSTEM.403]
+ */
+UINT16 WINAPI waveOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
+{
+	dprintf_mmsys(stddeb, "waveOutGetErrorText\n");
+	return(waveGetErrorText(uError, lpText, uSize));
+}
+
+/**************************************************************************
+ * 				waveOutGetErrorTextA 	[WINMM.164]
+ */
+UINT32 WINAPI waveOutGetErrorText32A(UINT32 uError, LPSTR lpText, UINT32 uSize)
+{
+	return(waveOutGetErrorText16(uError, lpText, uSize));
+}
+
+/**************************************************************************
+ * 				waveOutGetErrorTextW 	[WINMM.165]
+ */
+UINT32 WINAPI waveOutGetErrorText32W(UINT32 uError, LPWSTR lpText, UINT32 uSize)
+{
+	LPSTR	xstr = HeapAlloc(GetProcessHeap(),0,uSize);
+	UINT32	ret = waveOutGetErrorText32A(uError, xstr, uSize);
+	
+	lstrcpyAtoW(lpText,xstr);
+	HeapFree(GetProcessHeap(),0,xstr);
+	return ret;
 }
 
 
 /**************************************************************************
-* 				waveGetErrorText 		[internal]
-*/
-UINT16 waveGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize)
+ * 				waveGetErrorText 		[internal]
+ */
+static UINT16 waveGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize)
 {
 	LPSTR	msgptr;
 	dprintf_mmsys(stddeb, "waveGetErrorText(%04X, %p, %d);\n", uError, lpText, uSize);
@@ -1601,60 +2584,78 @@
 }
 
 /**************************************************************************
-* 				waveOutOpen			[MMSYSTEM.404]
-*/
-UINT16 WINAPI waveOutOpen(HWAVEOUT16 * lphWaveOut, UINT16 uDeviceID,
-                          const LPWAVEFORMAT lpFormat, DWORD dwCallback,
-                          DWORD dwInstance, DWORD dwFlags)
+ *			waveOutOpen			[WINMM.173]
+ * All the args/structs have the same layout as the win16 equivalents
+ */
+UINT32 WINAPI waveOutOpen32(HWAVEOUT32 * lphWaveOut, UINT32 uDeviceID,
+                            const LPWAVEFORMATEX lpFormat, DWORD dwCallback,
+                            DWORD dwInstance, DWORD dwFlags)
 {
-	HWAVEOUT16 hWaveOut;
+	HWAVEOUT16	hwo16;
+	UINT32	ret=waveOutOpen16(&hwo16,uDeviceID,lpFormat,dwCallback,dwInstance,dwFlags);
+	if (lphWaveOut) *lphWaveOut=hwo16;
+	return ret;
+}
+/**************************************************************************
+ *			waveOutOpen			[MMSYSTEM.404]
+ */
+UINT16 WINAPI waveOutOpen16(HWAVEOUT16 * lphWaveOut, UINT16 uDeviceID,
+                            const LPWAVEFORMATEX lpFormat, DWORD dwCallback,
+                            DWORD dwInstance, DWORD dwFlags)
+{
+	HWAVEOUT16	hWaveOut;
 	LPWAVEOPENDESC	lpDesc;
-	LPWAVEOPENDESC	lp16Desc;
-	DWORD	dwRet = 0;
-	BOOL32	bMapperFlg = FALSE;
+	DWORD		dwRet = 0;
+	BOOL32		bMapperFlg = FALSE;
 
 	dprintf_mmsys(stddeb, "waveOutOpen(%p, %d, %p, %08lX, %08lX, %08lX);\n", 
 		lphWaveOut, uDeviceID, lpFormat, dwCallback, dwInstance, dwFlags);
-	if (dwFlags & WAVE_FORMAT_QUERY) {
+	if (dwFlags & WAVE_FORMAT_QUERY)
 		dprintf_mmsys(stddeb, "waveOutOpen	// WAVE_FORMAT_QUERY requested !\n");
-		}
 	if (uDeviceID == (UINT16)WAVE_MAPPER) {
 		dprintf_mmsys(stddeb, "waveOutOpen	// WAVE_MAPPER mode requested !\n");
 		bMapperFlg = TRUE;
 		uDeviceID = 0;
-		}
+	}
 	if (lpFormat == NULL) return WAVERR_BADFORMAT;
 
 	hWaveOut = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
 	if (lphWaveOut != NULL) *lphWaveOut = hWaveOut;
-	lp16Desc = (LPWAVEOPENDESC) USER_HEAP_SEG_ADDR(hWaveOut);
-	lpDesc = (LPWAVEOPENDESC) PTR_SEG_TO_LIN(lp16Desc);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_NOMEM;
 	lpDesc->hWave = hWaveOut;
-	lpDesc->lpFormat = lpFormat;  /* should the struct be copied iso pointer? */
+	lpDesc->lpFormat = (LPWAVEFORMAT)lpFormat;  /* should the struct be copied iso pointer? */
 	lpDesc->dwCallBack = dwCallback;
 	lpDesc->dwInstance = dwInstance;
-	if (uDeviceID >= MAXWAVEDRIVERS) uDeviceID = 0;
+	if (uDeviceID >= MAXWAVEDRIVERS)
+		uDeviceID = 0;
 	while(uDeviceID < MAXWAVEDRIVERS) {
 		dwRet = wodMessage(uDeviceID, WODM_OPEN, 
-			lpDesc->dwInstance, (DWORD)lp16Desc, dwFlags);
+			lpDesc->dwInstance, (DWORD)lpDesc, dwFlags);
 		if (dwRet == MMSYSERR_NOERROR) break;
 		if (!bMapperFlg) break;
 		uDeviceID++;
 		dprintf_mmsys(stddeb, "waveOutOpen	// WAVE_MAPPER mode ! try next driver...\n");
-		}
+	}
 	lpDesc->uDeviceID = uDeviceID;  /* save physical Device ID */
 	if (dwFlags & WAVE_FORMAT_QUERY) {
 		dprintf_mmsys(stddeb, "waveOutOpen	// End of WAVE_FORMAT_QUERY !\n");
-		dwRet = waveOutClose(hWaveOut);
-		}
+		dwRet = waveOutClose32(hWaveOut);
+	}
 	return dwRet;
 }
 
 /**************************************************************************
-* 				waveOutClose		[MMSYSTEM.405]
-*/
-UINT16 WINAPI waveOutClose(HWAVEOUT16 hWaveOut)
+ * 				waveOutClose		[WINMM.161]
+ */
+UINT32 WINAPI waveOutClose32(HWAVEOUT32 hWaveOut)
+{
+	return waveOutClose16(hWaveOut);
+}
+/**************************************************************************
+ * 				waveOutClose		[MMSYSTEM.405]
+ */
+UINT16 WINAPI waveOutClose16(HWAVEOUT16 hWaveOut)
 {
 	LPWAVEOPENDESC	lpDesc;
 
@@ -1665,10 +2666,10 @@
 }
 
 /**************************************************************************
-* 				waveOutPrepareHeader	[MMSYSTEM.406]
-*/
-UINT16 WINAPI waveOutPrepareHeader(HWAVEOUT16 hWaveOut,
-                                   WAVEHDR * lpWaveOutHdr, UINT16 uSize)
+ * 				waveOutPrepareHeader	[WINMM.175]
+ */
+UINT32 WINAPI waveOutPrepareHeader32(HWAVEOUT32 hWaveOut,
+                                   WAVEHDR * lpWaveOutHdr, UINT32 uSize)
 {
 	LPWAVEOPENDESC	lpDesc;
 
@@ -1677,14 +2678,34 @@
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return wodMessage( lpDesc->uDeviceID, WODM_PREPARE, lpDesc->dwInstance, 
-							(DWORD)lpWaveOutHdr, uSize);
+			   (DWORD)lpWaveOutHdr,uSize);
+}
+/**************************************************************************
+ * 				waveOutPrepareHeader	[MMSYSTEM.406]
+ */
+UINT16 WINAPI waveOutPrepareHeader16(HWAVEOUT16 hWaveOut,
+                                     WAVEHDR * lpWaveOutHdr, UINT16 uSize)
+{
+	LPWAVEOPENDESC	lpDesc;
+	LPBYTE		saveddata = lpWaveOutHdr->lpData;
+	UINT16		ret;
+
+	dprintf_mmsys(stddeb, "waveOutPrepareHeader(%04X, %p, %u);\n", 
+					hWaveOut, lpWaveOutHdr, uSize);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	lpWaveOutHdr->lpData = PTR_SEG_TO_LIN(lpWaveOutHdr->lpData);
+	ret = wodMessage( lpDesc->uDeviceID, WODM_PREPARE, lpDesc->dwInstance, 
+			   (DWORD)lpWaveOutHdr,uSize);
+	lpWaveOutHdr->lpData = saveddata;
+	return ret;
 }
 
 /**************************************************************************
-* 				waveOutUnprepareHeader	[MMSYSTEM.407]
-*/
-UINT16 WINAPI waveOutUnprepareHeader(HWAVEOUT16 hWaveOut,
-                                     WAVEHDR * lpWaveOutHdr, UINT16 uSize)
+ * 				waveOutUnprepareHeader	[WINMM.181]
+ */
+UINT32 WINAPI waveOutUnprepareHeader32(HWAVEOUT32 hWaveOut,
+                                       WAVEHDR * lpWaveOutHdr, UINT32 uSize)
 {
 	LPWAVEOPENDESC	lpDesc;
 
@@ -1692,29 +2713,74 @@
 						hWaveOut, lpWaveOutHdr, uSize);
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage( lpDesc->uDeviceID, WODM_UNPREPARE, lpDesc->dwInstance, 
-							(DWORD)lpWaveOutHdr, uSize);
+	return wodMessage(lpDesc->uDeviceID,WODM_UNPREPARE,lpDesc->dwInstance, 
+					(DWORD)lpWaveOutHdr, uSize);
+}
+/**************************************************************************
+ * 				waveOutUnprepareHeader	[MMSYSTEM.407]
+ */
+UINT16 WINAPI waveOutUnprepareHeader16(HWAVEOUT16 hWaveOut,
+                                     WAVEHDR * lpWaveOutHdr, UINT16 uSize)
+{
+	LPWAVEOPENDESC	lpDesc;
+	LPBYTE		saveddata = lpWaveOutHdr->lpData;
+	UINT16		ret;
+
+	dprintf_mmsys(stddeb, "waveOutUnprepareHeader(%04X, %p, %u);\n", 
+						hWaveOut, lpWaveOutHdr, uSize);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	lpWaveOutHdr->lpData = PTR_SEG_TO_LIN(lpWaveOutHdr->lpData);
+	ret = wodMessage(lpDesc->uDeviceID,WODM_UNPREPARE,lpDesc->dwInstance, 
+			  (DWORD)lpWaveOutHdr, uSize);
+	lpWaveOutHdr->lpData = saveddata;
+	return ret;
 }
 
 /**************************************************************************
-* 				waveOutWrite		[MMSYSTEM.408]
-*/
-UINT16 WINAPI waveOutWrite(HWAVEOUT16 hWaveOut, WAVEHDR * lpWaveOutHdr,
+ * 				waveOutWrite		[MMSYSTEM.408]
+ */
+UINT32 WINAPI waveOutWrite32(HWAVEOUT32 hWaveOut, WAVEHDR * lpWaveOutHdr,
+                             UINT32 uSize)
+{
+	LPWAVEOPENDESC	lpDesc;
+	dprintf_mmsys(stddeb, "waveOutWrite(%04X, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	lpWaveOutHdr->reserved = (DWORD)lpWaveOutHdr->lpData;
+	return wodMessage( lpDesc->uDeviceID, WODM_WRITE, lpDesc->dwInstance, (DWORD)lpWaveOutHdr, uSize);
+}
+/**************************************************************************
+ * 				waveOutWrite		[MMSYSTEM.408]
+ */
+UINT16 WINAPI waveOutWrite16(HWAVEOUT16 hWaveOut, WAVEHDR * lpWaveOutHdr,
                            UINT16 uSize)
 {
 	LPWAVEOPENDESC	lpDesc;
+	UINT16		ret;
 
 	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( lpDesc->uDeviceID, WODM_WRITE, lpDesc->dwInstance, 
-							(DWORD)lpWaveOutHdr, uSize);
+	lpWaveOutHdr->reserved=(DWORD)lpWaveOutHdr->lpData;/*save original ptr*/
+	lpWaveOutHdr->lpData = PTR_SEG_TO_LIN(lpWaveOutHdr->lpData);
+	ret = wodMessage( lpDesc->uDeviceID, WODM_WRITE, lpDesc->dwInstance, (DWORD)lpWaveOutHdr, uSize);
+	lpWaveOutHdr->lpData = (LPBYTE)lpWaveOutHdr->reserved;
+	return ret;
 }
 
 /**************************************************************************
-* 				waveOutPause		[MMSYSTEM.409]
-*/
-UINT16 WINAPI waveOutPause(HWAVEOUT16 hWaveOut)
+ * 				waveOutPause		[WINMM.174]
+ */
+UINT32 WINAPI waveOutPause32(HWAVEOUT32 hWaveOut)
+{
+	return waveOutPause16(hWaveOut);
+}
+
+/**************************************************************************
+ * 				waveOutPause		[MMSYSTEM.409]
+ */
+UINT16 WINAPI waveOutPause16(HWAVEOUT16 hWaveOut)
 {
 	LPWAVEOPENDESC	lpDesc;
 
@@ -1725,9 +2791,16 @@
 }
 
 /**************************************************************************
-* 				waveOutRestart		[MMSYSTEM.410]
-*/
-UINT16 WINAPI waveOutRestart(HWAVEOUT16 hWaveOut)
+ * 				waveOutRestart		[WINMM.177]
+ */
+UINT32 WINAPI waveOutRestart32(HWAVEOUT32 hWaveOut)
+{
+	return waveOutRestart16(hWaveOut);
+}
+/**************************************************************************
+ * 				waveOutRestart		[MMSYSTEM.410]
+ */
+UINT16 WINAPI waveOutRestart16(HWAVEOUT16 hWaveOut)
 {
 	LPWAVEOPENDESC	lpDesc;
 
@@ -1738,9 +2811,17 @@
 }
 
 /**************************************************************************
-* 				waveOutReset		[MMSYSTEM.411]
-*/
-UINT16 WINAPI waveOutReset(HWAVEOUT16 hWaveOut)
+ * 				waveOutReset		[WINMM.176]
+ */
+UINT32 WINAPI waveOutReset32(HWAVEOUT32 hWaveOut)
+{
+	return waveOutReset16(hWaveOut);
+}
+
+/**************************************************************************
+ * 				waveOutReset		[MMSYSTEM.411]
+ */
+UINT16 WINAPI waveOutReset16(HWAVEOUT16 hWaveOut)
 {
 	LPWAVEOPENDESC	lpDesc;
 	dprintf_mmsys(stddeb, "waveOutReset(%04X)\n", hWaveOut);
@@ -1750,10 +2831,21 @@
 }
 
 /**************************************************************************
-* 				waveOutGetPosition	[MMSYSTEM.412]
-*/
-UINT16 WINAPI waveOutGetPosition(HWAVEOUT16 hWaveOut, MMTIME * lpTime,
-                                 UINT16 uSize)
+ * 				waveOutGetPosition	[WINMM.170]
+ */
+UINT32 WINAPI waveOutGetPosition32(HWAVEOUT32 hWaveOut, LPMMTIME32 lpTime,
+                                   UINT32 uSize)
+{
+	MMTIME16	mmt16;
+	UINT32 ret = waveOutGetPosition16(hWaveOut,&mmt16,sizeof(mmt16));
+	MMSYSTEM_MMTIME16to32(lpTime,&mmt16);
+	return ret;
+}
+/**************************************************************************
+ * 				waveOutGetPosition	[MMSYSTEM.412]
+ */
+UINT16 WINAPI waveOutGetPosition16(HWAVEOUT16 hWaveOut,LPMMTIME16 lpTime,
+                                   UINT16 uSize)
 {
 	LPWAVEOPENDESC	lpDesc;
 	dprintf_mmsys(stddeb, "waveOutGetPosition(%04X, %p, %u);\n", hWaveOut, lpTime, uSize);
@@ -1763,88 +2855,75 @@
 							(DWORD)lpTime, (DWORD)uSize);
 }
 
-/**************************************************************************
-* 				waveOutGetPitch		[MMSYSTEM.413]
-*/
-UINT16 WINAPI waveOutGetPitch(HWAVEOUT16 hWaveOut, DWORD * lpdwPitch)
-{
-	LPWAVEOPENDESC	lpDesc;
-	dprintf_mmsys(stddeb, "waveOutGetPitch(%04X, %p);\n", hWaveOut, lpdwPitch);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage( lpDesc->uDeviceID, WODM_GETPITCH, lpDesc->dwInstance, 
-								(DWORD)lpdwPitch, 0L);
+#define WAVEOUT_SHORTCUT_1(xx,XX,atype) \
+	UINT32 WINAPI waveOut##xx##32(HWAVEOUT32 hWaveOut, atype x)	\
+{									\
+	return waveOut##xx##16(hWaveOut,x);				\
+}									\
+UINT16 WINAPI waveOut##xx##16(HWAVEOUT16 hWaveOut, atype x)		\
+{									\
+	LPWAVEOPENDESC	lpDesc;						\
+	dprintf_mmsys(stddeb, "waveOut"#xx"(%04X, %08lx);\n", hWaveOut,(DWORD)x);\
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);		\
+	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;		\
+	return wodMessage(lpDesc->uDeviceID, WODM_##XX, lpDesc->dwInstance,\
+			  (DWORD)x, 0L);				\
 }
 
-/**************************************************************************
-* 				waveOutSetPitch		[MMSYSTEM.414]
-*/
-UINT16 WINAPI waveOutSetPitch(HWAVEOUT16 hWaveOut, DWORD dwPitch)
-{
-	LPWAVEOPENDESC	lpDesc;
-	dprintf_mmsys(stddeb, "waveOutSetPitch(%04X, %08lX);\n", hWaveOut, dwPitch);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage( lpDesc->uDeviceID, WODM_SETPITCH, lpDesc->dwInstance, (DWORD)dwPitch, 0L);
+WAVEOUT_SHORTCUT_1(GetPitch,GETPITCH,DWORD*)
+WAVEOUT_SHORTCUT_1(SetPitch,SETPITCH,DWORD)
+WAVEOUT_SHORTCUT_1(GetPlaybackRate,GETPLAYBACKRATE,DWORD*)
+WAVEOUT_SHORTCUT_1(SetPlaybackRate,SETPLAYBACKRATE,DWORD)
+
+#define WAVEOUT_SHORTCUT_2(xx,XX,atype) \
+	UINT32 WINAPI waveOut##xx##32(UINT32 devid, atype x)		\
+{									\
+	return waveOut##xx##16(devid,x);				\
+}									\
+UINT16 WINAPI waveOut##xx##16(UINT16 devid, atype x)			\
+{									\
+	dprintf_mmsys(stddeb, "waveOut"#xx"(%04X, %08lx);\n", devid,(DWORD)x);	\
+	return wodMessage(devid, WODM_##XX, 0L,	(DWORD)x, 0L);		\
 }
+	
+
+WAVEOUT_SHORTCUT_2(GetVolume,GETVOLUME,DWORD*)
+WAVEOUT_SHORTCUT_2(SetVolume,SETVOLUME,DWORD)
+
 
 /**************************************************************************
-* 				waveOutGetVolume	[MMSYSTEM.415]
-*/
-UINT16 WINAPI waveOutGetVolume(UINT16 uDeviceID, DWORD * lpdwVolume)
+ * 				waveOutBreakLoop 	[MMSYSTEM.419]
+ */
+UINT32 WINAPI waveOutBreakLoop32(HWAVEOUT32 hWaveOut)
 {
-	dprintf_mmsys(stddeb, "waveOutGetVolume(%04X, %p);\n", uDeviceID, lpdwVolume);
-	return wodMessage(uDeviceID, WODM_GETVOLUME, 0L, (DWORD)lpdwVolume, 0L);
+	return waveOutBreakLoop16(hWaveOut);
 }
-
 /**************************************************************************
-* 				waveOutSetVolume	[MMSYSTEM.416]
-*/
-UINT16 WINAPI waveOutSetVolume(UINT16 uDeviceID, DWORD dwVolume)
-{
-	dprintf_mmsys(stddeb, "waveOutSetVolume(%04X, %08lX);\n", uDeviceID, dwVolume);
-	return wodMessage(uDeviceID, WODM_SETVOLUME, 0L, dwVolume, 0L);
-}
-
-/**************************************************************************
-* 				waveOutGetPlaybackRate	[MMSYSTEM.417]
-*/
-UINT16 WINAPI waveOutGetPlaybackRate(HWAVEOUT16 hWaveOut, DWORD * lpdwRate)
-{
-	LPWAVEOPENDESC	lpDesc;
-	dprintf_mmsys(stddeb, "waveOutGetPlaybackRate(%04X, %p);\n", hWaveOut, lpdwRate);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage( lpDesc->uDeviceID, WODM_GETPLAYBACKRATE, lpDesc->dwInstance, 
-								(DWORD)lpdwRate, 0L);
-}
-
-/**************************************************************************
-* 				waveOutSetPlaybackRate	[MMSYSTEM.418]
-*/
-UINT16 WINAPI waveOutSetPlaybackRate(HWAVEOUT16 hWaveOut, DWORD dwRate)
-{
-	LPWAVEOPENDESC	lpDesc;
-	dprintf_mmsys(stddeb, "waveOutSetPlaybackRate(%04X, %08lX);\n", hWaveOut, dwRate);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage( lpDesc->uDeviceID, WODM_SETPLAYBACKRATE, 
-		lpDesc->dwInstance, (DWORD)dwRate, 0L);
-}
-
-/**************************************************************************
-* 				waveOutBreakLoop 	[MMSYSTEM.419]
-*/
-UINT16 WINAPI waveOutBreakLoop(HWAVEOUT16 hWaveOut)
+ * 				waveOutBreakLoop 	[MMSYSTEM.419]
+ */
+UINT16 WINAPI waveOutBreakLoop16(HWAVEOUT16 hWaveOut)
 {
 	dprintf_mmsys(stddeb, "waveOutBreakLoop(%04X)\n", hWaveOut);
 	return MMSYSERR_INVALHANDLE;
 }
 
 /**************************************************************************
-* 				waveOutGetID	 	[MMSYSTEM.420]
-*/
-UINT16 WINAPI waveOutGetID(HWAVEOUT16 hWaveOut, UINT16 * lpuDeviceID)
+ * 				waveOutGetID	 	[MMSYSTEM.420]
+ */
+UINT32 WINAPI waveOutGetID32(HWAVEOUT32 hWaveOut, UINT32 * lpuDeviceID)
+{
+	LPWAVEOPENDESC	lpDesc;
+	dprintf_mmsys(stddeb, "waveOutGetID(%04X, %p);\n", hWaveOut, lpuDeviceID);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
+	*lpuDeviceID = lpDesc->uDeviceID;
+        return 0;
+}
+/**************************************************************************
+ * 				waveOutGetID	 	[MMSYSTEM.420]
+ */
+UINT16 WINAPI waveOutGetID16(HWAVEOUT16 hWaveOut, UINT16 * lpuDeviceID)
 {
 	LPWAVEOPENDESC	lpDesc;
 	dprintf_mmsys(stddeb, "waveOutGetID(%04X, %p);\n", hWaveOut, lpuDeviceID);
@@ -1856,23 +2935,109 @@
 }
 
 /**************************************************************************
-* 				waveOutMessage 		[MMSYSTEM.421]
-*/
-DWORD WINAPI waveOutMessage(HWAVEOUT16 hWaveOut, UINT16 uMessage, 
-                            DWORD dwParam1, DWORD dwParam2)
+ * 				waveOutMessage 		[MMSYSTEM.421]
+ */
+DWORD WINAPI waveOutMessage32(HWAVEOUT32 hWaveOut, UINT32 uMessage, 
+                              DWORD dwParam1, DWORD dwParam2)
 {
 	LPWAVEOPENDESC	lpDesc;
-	dprintf_mmsys(stddeb, "waveOutMessage(%04X, %04X, %08lX, %08lX)\n", 
-			hWaveOut, uMessage, dwParam1, dwParam2);
+
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	switch (uMessage) {
+	case WODM_GETNUMDEVS:
+	case WODM_GETPOS:
+	case WODM_GETVOLUME:
+	case WODM_GETPITCH:
+	case WODM_GETPLAYBACKRATE:
+	case WODM_SETVOLUME:
+	case WODM_SETPITCH:
+	case WODM_SETPLAYBACKRATE:
+	case WODM_RESET:
+	case WODM_PAUSE:
+	case WODM_PREPARE:
+	case WODM_UNPREPARE:
+	case WODM_STOP:
+	case WODM_CLOSE:
+		/* no argument conversion needed */
+		break;
+	case WODM_WRITE:
+		return waveOutWrite32(hWaveOut,(LPWAVEHDR)dwParam1,dwParam2);
+	case WODM_GETDEVCAPS:
+		/* FIXME: UNICODE/ANSI? */
+		return waveOutGetDevCaps32A(hWaveOut,(LPWAVEOUTCAPS32A)dwParam1,dwParam2);
+	case WODM_OPEN:
+		fprintf(stderr,"waveOutMessage32 can't handle WODM_OPEN, please report.\n");
+		break;
+	default:
+		fprintf(stderr,"unhandled waveOutMessage32(0x%04x,0x%04x,%08lx,%08lx)\n",
+			hWaveOut,uMessage,dwParam1,dwParam2
+		);
+		break;
+	}
 	return wodMessage( lpDesc->uDeviceID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
 }
 
 /**************************************************************************
-* 				waveInGetNumDevs 		[MMSYSTEM.501]
-*/
-UINT16 WINAPI waveInGetNumDevs()
+ * 				waveOutMessage 		[MMSYSTEM.421]
+ */
+DWORD WINAPI waveOutMessage16(HWAVEOUT16 hWaveOut, UINT16 uMessage, 
+                              DWORD dwParam1, DWORD dwParam2)
+{
+	LPWAVEOPENDESC	lpDesc;
+
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	switch (uMessage) {
+	case WODM_GETNUMDEVS:
+	case WODM_SETVOLUME:
+	case WODM_SETPITCH:
+	case WODM_SETPLAYBACKRATE:
+	case WODM_RESET:
+	case WODM_PAUSE:
+	case WODM_STOP:
+	case WODM_CLOSE:
+		/* no argument conversion needed */
+		break;
+	case WODM_GETPOS:
+		return waveOutGetPosition16(hWaveOut,(LPMMTIME16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+	case WODM_GETVOLUME:
+		return waveOutGetVolume16(hWaveOut,(LPDWORD)PTR_SEG_TO_LIN(dwParam1));
+	case WODM_GETPITCH:
+		return waveOutGetPitch16(hWaveOut,(LPDWORD)PTR_SEG_TO_LIN(dwParam1));
+	case WODM_GETPLAYBACKRATE:
+		return waveOutGetPlaybackRate16(hWaveOut,(LPDWORD)PTR_SEG_TO_LIN(dwParam1));
+	case WODM_GETDEVCAPS:
+		return waveOutGetDevCaps16(hWaveOut,(LPWAVEOUTCAPS16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+	case WODM_PREPARE:
+		return waveOutPrepareHeader16(hWaveOut,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+	case WODM_UNPREPARE:
+		return waveOutUnprepareHeader16(hWaveOut,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+	case WODM_WRITE:
+		return waveOutWrite16(hWaveOut,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+	case WODM_OPEN:
+		fprintf(stderr,"waveOutMessage16 can't handle WODM_OPEN, please report.\n");
+		break;
+	default:
+		fprintf(stderr,"unhandled waveOutMessage16(0x%04x,0x%04x,%08lx,%08lx)\n",
+			hWaveOut,uMessage,dwParam1,dwParam2
+		);
+	}
+	return wodMessage( lpDesc->uDeviceID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
+}
+
+/**************************************************************************
+ * 				waveInGetNumDevs 		[WINMM.151]
+ */
+UINT32 WINAPI waveInGetNumDevs32()
+{
+	return waveInGetNumDevs16();
+}
+
+/**************************************************************************
+ * 				waveInGetNumDevs 		[MMSYSTEM.501]
+ */
+UINT16 WINAPI waveInGetNumDevs16()
 {
 	UINT16	count = 0;
 	dprintf_mmsys(stddeb, "waveInGetNumDevs\n");
@@ -1881,21 +3046,74 @@
 	return count;
 }
 
-
 /**************************************************************************
-* 				waveInGetDevCaps 		[MMSYSTEM.502]
-*/
-UINT16 WINAPI waveInGetDevCaps(UINT16 uDeviceID, WAVEINCAPS * lpCaps, UINT16 uSize)
+ * 				waveInGetDevCapsA 		[WINMM.147]
+ */
+UINT32 WINAPI waveInGetDevCaps32W(UINT32 uDeviceID, LPWAVEINCAPS32W lpCaps, UINT32 uSize)
+{
+	WAVEINCAPS16	wic16;
+	UINT32	ret = waveInGetDevCaps16(uDeviceID,&wic16,uSize);
+
+	lpCaps->wMid = wic16.wMid;
+	lpCaps->wPid = wic16.wPid;
+	lpCaps->vDriverVersion = wic16.vDriverVersion;
+	lstrcpyAtoW(lpCaps->szPname,wic16.szPname);
+	lpCaps->dwFormats = wic16.dwFormats;
+	lpCaps->wChannels = wic16.wChannels;
+
+	return ret;
+}
+/**************************************************************************
+ * 				waveInGetDevCapsA 		[WINMM.146]
+ */
+UINT32 WINAPI waveInGetDevCaps32A(UINT32 uDeviceID, LPWAVEINCAPS32A lpCaps, UINT32 uSize)
+{
+	WAVEINCAPS16	wic16;
+	UINT32	ret = waveInGetDevCaps16(uDeviceID,&wic16,uSize);
+	
+	lpCaps->wMid = wic16.wMid;
+	lpCaps->wPid = wic16.wPid;
+	lpCaps->vDriverVersion = wic16.vDriverVersion;
+	strcpy(lpCaps->szPname,wic16.szPname);
+	lpCaps->dwFormats = wic16.dwFormats;
+	lpCaps->wChannels = wic16.wChannels;
+	return ret;
+}
+/**************************************************************************
+ * 				waveInGetDevCaps 		[MMSYSTEM.502]
+ */
+UINT16 WINAPI waveInGetDevCaps16(UINT16 uDeviceID, LPWAVEINCAPS16 lpCaps, UINT16 uSize)
 {
 	dprintf_mmsys(stddeb, "waveInGetDevCaps\n");
 	return widMessage(uDeviceID, WIDM_GETDEVCAPS, 0L, (DWORD)lpCaps, uSize);
 }
 
+/**************************************************************************
+ * 				waveInGetErrorTextA 	[WINMM.148]
+ */
+UINT32 WINAPI waveInGetErrorText32A(UINT32 uError, LPSTR lpText, UINT32 uSize)
+{
+   dprintf_mmsys(stddeb, "waveInGetErrorText\n");
+   return(waveGetErrorText(uError, lpText, uSize));
+}
 
 /**************************************************************************
-* 				waveInGetErrorText 	[MMSYSTEM.503]
-*/
-UINT16 WINAPI waveInGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize)
+ * 				waveInGetErrorTextW 	[WINMM.149]
+ */
+UINT32 WINAPI waveInGetErrorText32W(UINT32 uError, LPWSTR lpText, UINT32 uSize)
+{
+	LPSTR txt = HeapAlloc(GetProcessHeap(),0,uSize);
+	UINT32	ret = waveGetErrorText(uError, txt, uSize);
+
+	lstrcpyAtoW(lpText,txt);
+	HeapFree(GetProcessHeap(),0,txt);
+	return ret;
+}
+
+/**************************************************************************
+ * 				waveInGetErrorText 	[MMSYSTEM.503]
+ */
+UINT16 WINAPI waveInGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
 {
    dprintf_mmsys(stddeb, "waveInGetErrorText\n");
    return(waveGetErrorText(uError, lpText, uSize));
@@ -1903,32 +3121,42 @@
 
 
 /**************************************************************************
-* 				waveInOpen			[MMSYSTEM.504]
-*/
-UINT16 WINAPI waveInOpen(HWAVEIN16 * lphWaveIn, UINT16 uDeviceID,
-                         const LPWAVEFORMAT lpFormat, DWORD dwCallback,
-                         DWORD dwInstance, DWORD dwFlags)
+ * 				waveInOpen			[WINMM.154]
+ */
+UINT32 WINAPI waveInOpen32(HWAVEIN32 * lphWaveIn, UINT32 uDeviceID,
+                           const LPWAVEFORMAT lpFormat, DWORD dwCallback,
+                           DWORD dwInstance, DWORD dwFlags)
+{
+	HWAVEIN16	hwin16;
+	UINT32	ret=waveInOpen16(&hwin16,uDeviceID,lpFormat,dwCallback,dwInstance,dwFlags);
+	if (lphWaveIn) *lphWaveIn = hwin16;
+	return ret;
+}
+
+/**************************************************************************
+ * 				waveInOpen			[MMSYSTEM.504]
+ */
+UINT16 WINAPI waveInOpen16(HWAVEIN16 * lphWaveIn, UINT16 uDeviceID,
+                           const LPWAVEFORMAT lpFormat, DWORD dwCallback,
+                           DWORD dwInstance, DWORD dwFlags)
 {
 	HWAVEIN16 hWaveIn;
 	LPWAVEOPENDESC	lpDesc;
-	LPWAVEOPENDESC	lp16Desc;
 	DWORD	dwRet = 0;
 	BOOL32	bMapperFlg = FALSE;
 	dprintf_mmsys(stddeb, "waveInOpen(%p, %d, %p, %08lX, %08lX, %08lX);\n", 
 		lphWaveIn, uDeviceID, lpFormat, dwCallback, dwInstance, dwFlags);
-	if (dwFlags & WAVE_FORMAT_QUERY) {
+	if (dwFlags & WAVE_FORMAT_QUERY)
 		dprintf_mmsys(stddeb, "waveInOpen // WAVE_FORMAT_QUERY requested !\n");
-		}
 	if (uDeviceID == (UINT16)WAVE_MAPPER) {
 		dprintf_mmsys(stddeb, "waveInOpen	// WAVE_MAPPER mode requested !\n");
 		bMapperFlg = TRUE;
 		uDeviceID = 0;
-		}
+	}
 	if (lpFormat == NULL) return WAVERR_BADFORMAT;
 	hWaveIn = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
 	if (lphWaveIn != NULL) *lphWaveIn = hWaveIn;
-	lp16Desc = (LPWAVEOPENDESC) USER_HEAP_SEG_ADDR(hWaveIn);
-	lpDesc = (LPWAVEOPENDESC) PTR_SEG_TO_LIN(lp16Desc);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
 	if (lpDesc == NULL) return MMSYSERR_NOMEM;
 	lpDesc->hWave = hWaveIn;
 	lpDesc->lpFormat = lpFormat;
@@ -1936,25 +3164,31 @@
 	lpDesc->dwInstance = dwInstance;
 	while(uDeviceID < MAXWAVEDRIVERS) {
 		dwRet = widMessage(uDeviceID, WIDM_OPEN, 
-			lpDesc->dwInstance, (DWORD)lp16Desc, 0L);
+			lpDesc->dwInstance, (DWORD)lpDesc, 0L);
 		if (dwRet == MMSYSERR_NOERROR) break;
 		if (!bMapperFlg) break;
 		uDeviceID++;
 		dprintf_mmsys(stddeb, "waveInOpen	// WAVE_MAPPER mode ! try next driver...\n");
-		}
+	}
 	lpDesc->uDeviceID = uDeviceID;
 	if (dwFlags & WAVE_FORMAT_QUERY) {
 		dprintf_mmsys(stddeb, "waveInOpen	// End of WAVE_FORMAT_QUERY !\n");
-		dwRet = waveInClose(hWaveIn);
-		}
+		dwRet = waveInClose16(hWaveIn);
+	}
 	return dwRet;
 }
 
-
 /**************************************************************************
-* 				waveInClose			[MMSYSTEM.505]
-*/
-UINT16 WINAPI waveInClose(HWAVEIN16 hWaveIn)
+ * 				waveInClose			[WINMM.145]
+ */
+UINT32 WINAPI waveInClose32(HWAVEIN32 hWaveIn)
+{
+	return waveInClose16(hWaveIn);
+}
+/**************************************************************************
+ * 				waveInClose			[MMSYSTEM.505]
+ */
+UINT16 WINAPI waveInClose16(HWAVEIN16 hWaveIn)
 {
 	LPWAVEOPENDESC	lpDesc;
 
@@ -1964,95 +3198,173 @@
 	return widMessage(lpDesc->uDeviceID, WIDM_CLOSE, lpDesc->dwInstance, 0L, 0L);
 }
 
-
 /**************************************************************************
-* 				waveInPrepareHeader		[MMSYSTEM.506]
-*/
-UINT16 WINAPI waveInPrepareHeader(HWAVEIN16 hWaveIn,
-                                  WAVEHDR * lpWaveInHdr, UINT16 uSize)
+ * 				waveInPrepareHeader		[WINMM.155]
+ */
+UINT32 WINAPI waveInPrepareHeader32(HWAVEIN32 hWaveIn,
+                                  WAVEHDR * lpWaveInHdr, UINT32 uSize)
 {
 	LPWAVEOPENDESC	lpDesc;
-	LPWAVEHDR 		lp32WaveInHdr;
 
 	dprintf_mmsys(stddeb, "waveInPrepareHeader(%04X, %p, %u);\n", 
 					hWaveIn, lpWaveInHdr, uSize);
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
-	lp32WaveInHdr = PTR_SEG_TO_LIN(lpWaveInHdr);
-	lp32WaveInHdr->lp16Next = (SEGPTR)NULL;
-    lp32WaveInHdr->dwBytesRecorded = 0;
+	lpWaveInHdr = lpWaveInHdr;
+	lpWaveInHdr->lpNext = NULL;
+    	lpWaveInHdr->dwBytesRecorded = 0;
 	dprintf_mmsys(stddeb, "waveInPrepareHeader // lpData=%p size=%lu \n", 
-		lp32WaveInHdr->lpData, lp32WaveInHdr->dwBufferLength);
-	return widMessage(lpDesc->uDeviceID, WIDM_PREPARE, lpDesc->dwInstance, 
-							(DWORD)lpWaveInHdr, uSize);
+		lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
+	return widMessage(lpDesc->uDeviceID,WIDM_PREPARE,lpDesc->dwInstance, 
+			  (DWORD)lpWaveInHdr, uSize);
+}
+/**************************************************************************
+ * 				waveInPrepareHeader		[MMSYSTEM.506]
+ */
+UINT16 WINAPI waveInPrepareHeader16(HWAVEIN16 hWaveIn,
+                                  WAVEHDR * lpWaveInHdr, UINT16 uSize)
+{
+	LPWAVEOPENDESC	lpDesc;
+	LPBYTE		saveddata = lpWaveInHdr->lpData;
+	UINT16		ret;
+
+	dprintf_mmsys(stddeb, "waveInPrepareHeader(%04X, %p, %u);\n", 
+					hWaveIn, lpWaveInHdr, uSize);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
+	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
+	lpWaveInHdr = lpWaveInHdr;
+	lpWaveInHdr->lpNext = NULL;
+    	lpWaveInHdr->dwBytesRecorded = 0;
+
+	dprintf_mmsys(stddeb, "waveInPrepareHeader // lpData=%p size=%lu \n", 
+		lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
+	lpWaveInHdr->lpData = PTR_SEG_TO_LIN(lpWaveInHdr->lpData);
+	ret = widMessage(lpDesc->uDeviceID,WIDM_PREPARE,lpDesc->dwInstance, 
+			  (DWORD)lpWaveInHdr,uSize);
+	lpWaveInHdr->lpData = saveddata;
+	return ret;
 }
 
 
 /**************************************************************************
-* 				waveInUnprepareHeader	[MMSYSTEM.507]
-*/
-UINT16 WINAPI waveInUnprepareHeader(HWAVEIN16 hWaveIn,
-                                    WAVEHDR * lpWaveInHdr, UINT16 uSize)
+ * 				waveInUnprepareHeader	[WINMM.159]
+ */
+UINT32 WINAPI waveInUnprepareHeader32(HWAVEIN32 hWaveIn,
+                                      WAVEHDR * lpWaveInHdr, UINT32 uSize)
 {
 	LPWAVEOPENDESC	lpDesc;
-	LPWAVEHDR 		lp32WaveInHdr;
 
 	dprintf_mmsys(stddeb, "waveInUnprepareHeader(%04X, %p, %u);\n", 
 						hWaveIn, lpWaveInHdr, uSize);
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
-	lp32WaveInHdr = PTR_SEG_TO_LIN(lpWaveInHdr);
-	USER_HEAP_FREE(HIWORD((DWORD)lp32WaveInHdr->lpData));
-	lp32WaveInHdr->lpData = NULL;
-	lp32WaveInHdr->lp16Next = (SEGPTR)NULL;
-	return widMessage(lpDesc->uDeviceID, WIDM_UNPREPARE, lpDesc->dwInstance, 
-							(DWORD)lpWaveInHdr, uSize);
+	/*USER_HEAP_FREE(HIWORD((DWORD)lpWaveInHdr->lpData)); FIXME */
+	lpWaveInHdr->lpData = NULL;
+	lpWaveInHdr->lpNext = NULL;
+	return widMessage(lpDesc->uDeviceID,WIDM_UNPREPARE,lpDesc->dwInstance, 
+			  (DWORD)lpWaveInHdr, uSize);
 }
-
-
 /**************************************************************************
-* 				waveInAddBuffer		[MMSYSTEM.508]
-*/
-UINT16 WINAPI waveInAddBuffer(HWAVEIN16 hWaveIn,
-                              WAVEHDR * lpWaveInHdr, UINT16 uSize)
+ * 				waveInUnprepareHeader	[MMSYSTEM.507]
+ */
+UINT16 WINAPI waveInUnprepareHeader16(HWAVEIN16 hWaveIn,
+                                      WAVEHDR * lpWaveInHdr, UINT16 uSize)
 {
 	LPWAVEOPENDESC	lpDesc;
-	LPWAVEHDR 		lp32WaveInHdr;
+
+	dprintf_mmsys(stddeb, "waveInUnprepareHeader(%04X, %p, %u);\n", 
+						hWaveIn, lpWaveInHdr, uSize);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
+	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
+	/*USER_HEAP_FREE(HIWORD((DWORD)lpWaveInHdr->lpData)); FIXME */
+	lpWaveInHdr->lpData = NULL;
+	lpWaveInHdr->lpNext = NULL;
+	return widMessage(lpDesc->uDeviceID,WIDM_UNPREPARE,lpDesc->dwInstance, 
+			  (DWORD)lpWaveInHdr, uSize);
+}
+
+/**************************************************************************
+ * 				waveInAddBuffer		[WINMM.144]
+ */
+UINT32 WINAPI waveInAddBuffer32(HWAVEIN32 hWaveIn,
+                                WAVEHDR * lpWaveInHdr, UINT32 uSize)
+{
+	LPWAVEOPENDESC	lpDesc;
 
 	dprintf_mmsys(stddeb, "waveInAddBuffer(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
-	lp32WaveInHdr = PTR_SEG_TO_LIN(lpWaveInHdr);
-	lp32WaveInHdr->lp16Next = (SEGPTR)NULL;
-    lp32WaveInHdr->dwBytesRecorded = 0;
+	lpWaveInHdr->lpNext = NULL;
+	lpWaveInHdr->dwBytesRecorded = 0;
 	dprintf_mmsys(stddeb, "waveInAddBuffer // lpData=%p size=%lu \n", 
-		lp32WaveInHdr->lpData, lp32WaveInHdr->dwBufferLength);
+		lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
 	return widMessage(lpDesc->uDeviceID, WIDM_ADDBUFFER, lpDesc->dwInstance,
 								(DWORD)lpWaveInHdr, uSize);
+	
 }
 
+/**************************************************************************
+ * 				waveInAddBuffer		[MMSYSTEM.508]
+ */
+UINT16 WINAPI waveInAddBuffer16(HWAVEIN16 hWaveIn,
+                                WAVEHDR * lpWaveInHdr, UINT16 uSize)
+{
+	LPWAVEOPENDESC	lpDesc;
+	UINT16		ret;
+
+	dprintf_mmsys(stddeb, "waveInAddBuffer(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
+	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
+	lpWaveInHdr->lpNext = NULL;
+	lpWaveInHdr->dwBytesRecorded = 0;
+	lpWaveInHdr->lpData = PTR_SEG_TO_LIN(lpWaveInHdr->lpData);
+	dprintf_mmsys(stddeb, "waveInAddBuffer // lpData=%p size=%lu \n", 
+		lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
+	ret = widMessage(lpDesc->uDeviceID, WIDM_ADDBUFFER, lpDesc->dwInstance,
+			  (DWORD)lpWaveInHdr, uSize);
+	/*lpWaveInHdr->lpData = saveddata;*/
+	return ret;
+}
 
 /**************************************************************************
-* 				waveInStart			[MMSYSTEM.509]
-*/
-UINT16 WINAPI waveInStart(HWAVEIN16 hWaveIn)
+ * 				waveInStart			[WINMM.157]
+ */
+UINT32 WINAPI waveInStart32(HWAVEIN32 hWaveIn)
+{
+	return waveInStart16(hWaveIn);
+}
+
+/**************************************************************************
+ * 				waveInStart			[MMSYSTEM.509]
+ */
+UINT16 WINAPI waveInStart16(HWAVEIN16 hWaveIn)
 {
 	LPWAVEOPENDESC	lpDesc;
 
 	dprintf_mmsys(stddeb, "waveInStart(%04X)\n", hWaveIn);
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return widMessage(lpDesc->uDeviceID, WIDM_START, lpDesc->dwInstance, 0L, 0L);
+	return widMessage(lpDesc->uDeviceID,WIDM_START,lpDesc->dwInstance,0,0);
 }
 
+/**************************************************************************
+ * 				waveInStop			[WINMM.158]
+ */
+UINT32 WINAPI waveInStop32(HWAVEIN32 hWaveIn)
+{
+	return waveInStop16(hWaveIn);
+}
 
 /**************************************************************************
-* 				waveInStop			[MMSYSTEM.510]
-*/
-UINT16 WINAPI waveInStop(HWAVEIN16 hWaveIn)
+ * 				waveInStop			[MMSYSTEM.510]
+ */
+UINT16 WINAPI waveInStop16(HWAVEIN16 hWaveIn)
 {
 	LPWAVEOPENDESC	lpDesc;
 
@@ -2062,26 +3374,45 @@
 	return widMessage(lpDesc->uDeviceID, WIDM_STOP, lpDesc->dwInstance, 0L, 0L);
 }
 
+/**************************************************************************
+ * 				waveInReset			[WINMM.156]
+ */
+UINT32 WINAPI waveInReset32(HWAVEIN32 hWaveIn)
+{
+	return waveInReset16(hWaveIn);
+}
 
 /**************************************************************************
-* 				waveInReset			[MMSYSTEM.511]
-*/
-UINT16 WINAPI waveInReset(HWAVEIN16 hWaveIn)
+ * 				waveInReset			[MMSYSTEM.511]
+ */
+UINT16 WINAPI waveInReset16(HWAVEIN16 hWaveIn)
 {
 	LPWAVEOPENDESC	lpDesc;
 
 	dprintf_mmsys(stddeb, "waveInReset(%04X)\n", hWaveIn);
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return widMessage(lpDesc->uDeviceID, WIDM_RESET, lpDesc->dwInstance, 0L, 0L);
+	return widMessage(lpDesc->uDeviceID,WIDM_RESET,lpDesc->dwInstance,0,0);
 }
 
+/**************************************************************************
+ * 				waveInGetPosition	[WINMM.152]
+ */
+UINT32 WINAPI waveInGetPosition32(HWAVEIN32 hWaveIn, LPMMTIME32 lpTime,
+                                  UINT32 uSize)
+{
+	MMTIME16 mmt16;
+	UINT32	ret = waveInGetPosition16(hWaveIn,&mmt16,uSize);
+
+	MMSYSTEM_MMTIME16to32(lpTime,&mmt16);
+	return ret;
+}
 
 /**************************************************************************
-* 				waveInGetPosition	[MMSYSTEM.512]
-*/
-UINT16 WINAPI waveInGetPosition(HWAVEIN16 hWaveIn, MMTIME * lpTime,
-                                UINT16 uSize)
+ * 				waveInGetPosition	[MMSYSTEM.512]
+ */
+UINT16 WINAPI waveInGetPosition16(HWAVEIN16 hWaveIn,LPMMTIME16 lpTime,
+                                  UINT16 uSize)
 {
 	LPWAVEOPENDESC	lpDesc;
 
@@ -2092,11 +3423,10 @@
 			  (DWORD)lpTime, (DWORD)uSize);
 }
 
-
 /**************************************************************************
-* 				waveInGetID			[MMSYSTEM.513]
-*/
-UINT16 WINAPI waveInGetID(HWAVEIN16 hWaveIn, UINT16 * lpuDeviceID)
+ * 				waveInGetID			[WINMM.150]
+ */
+UINT32 WINAPI waveInGetID32(HWAVEIN32 hWaveIn, UINT32 * lpuDeviceID)
 {
 	LPWAVEOPENDESC	lpDesc;
 
@@ -2110,31 +3440,131 @@
 
 
 /**************************************************************************
-* 				waveInMessage 		[MMSYSTEM.514]
-*/
-DWORD WINAPI waveInMessage(HWAVEIN16 hWaveIn, UINT16 uMessage,
-                           DWORD dwParam1, DWORD dwParam2)
+ * 				waveInGetID			[MMSYSTEM.513]
+ */
+UINT16 WINAPI waveInGetID16(HWAVEIN16 hWaveIn, UINT16 * lpuDeviceID)
 {
 	LPWAVEOPENDESC	lpDesc;
 
-	dprintf_mmsys(stddeb, "waveInMessage(%04X, %04X, %08lX, %08lX)\n", 
+	dprintf_mmsys(stddeb, "waveInGetID\n");
+	if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
+	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	*lpuDeviceID = lpDesc->uDeviceID;
+	return 0;
+}
+
+/**************************************************************************
+ * 				waveInMessage 		[WINMM.153]
+ */
+DWORD WINAPI waveInMessage32(HWAVEIN32 hWaveIn, UINT32 uMessage,
+                             DWORD dwParam1, DWORD dwParam2)
+{
+	LPWAVEOPENDESC	lpDesc;
+
+	fprintf(stderr, "waveInMessage32(%04X, %04X, %08lX, %08lX),FIXME!\n", 
 			hWaveIn, uMessage, dwParam1, dwParam2);
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	switch (uMessage) {
+	case WIDM_OPEN:
+		fprintf(stderr,"waveInMessage32: cannot handle WIDM_OPEN, please report.\n");
+		break;
+	case WIDM_GETNUMDEVS:
+	case WIDM_GETPOS:
+	case WIDM_CLOSE:
+	case WIDM_STOP :
+	case WIDM_RESET:
+	case WIDM_START:
+	case WIDM_PREPARE:
+	case WIDM_UNPREPARE:
+	case WIDM_ADDBUFFER:
+	case WIDM_PAUSE:
+		/* no argument conversion needed */
+		break;
+	case WIDM_GETDEVCAPS:
+		/*FIXME: ANSI/UNICODE */
+		return waveInGetDevCaps32A(hWaveIn,(LPWAVEINCAPS32A)dwParam1,dwParam2);
+	default:
+		fprintf(stderr,"unhandled waveInMessage32(%04x,%04x,%08lx,%08lx)\n",hWaveIn,uMessage,dwParam1,dwParam2);
+		break;
+	}
 	return widMessage(lpDesc->uDeviceID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
 }
 
+/**************************************************************************
+ * 				waveInMessage 		[MMSYSTEM.514]
+ */
+DWORD WINAPI waveInMessage16(HWAVEIN16 hWaveIn, UINT16 uMessage,
+                             DWORD dwParam1, DWORD dwParam2)
+{
+	LPWAVEOPENDESC	lpDesc;
+
+	fprintf(stderr, "waveInMessage(%04X, %04X, %08lX, %08lX),FIXME!\n", 
+			hWaveIn, uMessage, dwParam1, dwParam2);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
+	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	switch (uMessage) {
+	case WIDM_OPEN:
+		fprintf(stderr,"waveInMessage16: cannot handle WIDM_OPEN, please report.\n");
+		break;
+	case WIDM_GETNUMDEVS:
+	case WIDM_CLOSE:
+	case WIDM_STOP :
+	case WIDM_RESET:
+	case WIDM_START:
+	case WIDM_PAUSE:
+		/* no argument conversion needed */
+		break;
+	case WIDM_GETDEVCAPS:
+		return waveInGetDevCaps16(hWaveIn,(LPWAVEINCAPS16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+	case WIDM_GETPOS:
+		return waveInGetPosition16(hWaveIn,(LPMMTIME16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+	case WIDM_PREPARE:
+		return waveInPrepareHeader16(hWaveIn,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+	case WIDM_UNPREPARE:
+		return waveInUnprepareHeader16(hWaveIn,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+	case WIDM_ADDBUFFER:
+		return waveInAddBuffer16(hWaveIn,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+	default:
+		fprintf(stderr,"unhandled waveInMessage16(%04x,%04x,%08lx,%08lx)\n",hWaveIn,uMessage,dwParam1,dwParam2);
+		break;
+	}
+	return widMessage(lpDesc->uDeviceID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
+}
 
 /**************************************************************************
-* 				mmioOpen       		[MMSYSTEM.1210]
-*/
-HMMIO16 WINAPI mmioOpen(LPSTR szFileName, MMIOINFO * lpmmioinfo,
-                        DWORD dwOpenFlags)
+ * 				mmioOpenW       		[WINMM.123]
+ */
+HMMIO32 WINAPI mmioOpen32W(LPWSTR szFileName, MMIOINFO32 * lpmmioinfo,
+                          DWORD dwOpenFlags)
+{
+	LPSTR	szFn = HEAP_strdupWtoA(GetProcessHeap(),0,szFileName);
+	HMMIO32 ret = mmioOpen16(szFn,(LPMMIOINFO16)lpmmioinfo,dwOpenFlags);
+
+	HeapFree(GetProcessHeap(),0,szFn);
+	return ret;
+}
+
+/**************************************************************************
+ * 				mmioOpenA       		[WINMM.122]
+ */
+HMMIO32 WINAPI mmioOpen32A(LPSTR szFileName, MMIOINFO32 * lpmmioinfo,
+                          DWORD dwOpenFlags)
+{
+	return mmioOpen16(szFileName,(LPMMIOINFO16)lpmmioinfo,dwOpenFlags);
+}
+
+/**************************************************************************
+ * 				mmioOpen       		[MMSYSTEM.1210]
+ */
+HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16 * lpmmioinfo,
+                          DWORD dwOpenFlags)
 {
         HFILE32 hFile;
 	HMMIO16		hmmio;
 	OFSTRUCT	ofs;
-	LPMMIOINFO	lpmminfo;
+	LPMMIOINFO16	lpmminfo;
 	dprintf_mmio(stddeb, "mmioOpen('%s', %p, %08lX);\n", szFileName, lpmmioinfo, dwOpenFlags);
         if (!szFileName)
         {
@@ -2144,10 +3574,10 @@
  	}
 	hFile = OpenFile32(szFileName, &ofs, dwOpenFlags);
 	if (hFile == -1) return 0;
-	hmmio = GlobalAlloc16(GMEM_MOVEABLE, sizeof(MMIOINFO));
-	lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
+	hmmio = GlobalAlloc16(GMEM_MOVEABLE, sizeof(MMIOINFO16));
+	lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) return 0;
-	memset(lpmminfo, 0, sizeof(MMIOINFO));
+	memset(lpmminfo, 0, sizeof(MMIOINFO16));
 	lpmminfo->hmmio = hmmio;
 	lpmminfo->dwReserved2 = hFile;
 	GlobalUnlock16(hmmio);
@@ -2161,9 +3591,9 @@
 */
 UINT16 WINAPI mmioClose(HMMIO16 hmmio, UINT16 uFlags)
 {
-	LPMMIOINFO	lpmminfo;
+	LPMMIOINFO16	lpmminfo;
 	dprintf_mmio(stddeb, "mmioClose(%04X, %04X);\n", hmmio, uFlags);
-	lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
+	lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) return 0;
 	_lclose32((HFILE32)lpmminfo->dwReserved2);
 	GlobalUnlock16(hmmio);
@@ -2179,9 +3609,9 @@
 LONG WINAPI mmioRead(HMMIO16 hmmio, HPSTR pch, LONG cch)
 {
 	LONG		count;
-	LPMMIOINFO	lpmminfo;
+	LPMMIOINFO16	lpmminfo;
 	dprintf_mmio(stddeb, "mmioRead(%04X, %p, %ld);\n", hmmio, pch, cch);
-	lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
+	lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) return 0;
 	count = _lread32(LOWORD(lpmminfo->dwReserved2), pch, cch);
 	GlobalUnlock16(hmmio);
@@ -2197,9 +3627,9 @@
 LONG WINAPI mmioWrite(HMMIO16 hmmio, HPCSTR pch, LONG cch)
 {
 	LONG		count;
-	LPMMIOINFO	lpmminfo;
+	LPMMIOINFO16	lpmminfo;
 	dprintf_mmio(stddeb, "mmioWrite(%04X, %p, %ld);\n", hmmio, pch, cch);
-	lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
+	lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) return 0;
 	count = _lwrite32(LOWORD(lpmminfo->dwReserved2), (LPSTR)pch, cch);
 	GlobalUnlock16(hmmio);
@@ -2212,9 +3642,9 @@
 LONG WINAPI mmioSeek(HMMIO16 hmmio, LONG lOffset, int iOrigin)
 {
 	int		count;
-	LPMMIOINFO	lpmminfo;
+	LPMMIOINFO16	lpmminfo;
 	dprintf_mmio(stddeb, "mmioSeek(%04X, %08lX, %d);\n", hmmio, lOffset, iOrigin);
-	lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
+	lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) {
 		dprintf_mmio(stddeb, "mmioSeek // can't lock hmmio=%04X !\n", hmmio);
 		return 0;
@@ -2227,13 +3657,13 @@
 /**************************************************************************
 * 				mmioGetInfo	       	[MMSYSTEM.1215]
 */
-UINT16 WINAPI mmioGetInfo(HMMIO16 hmmio, MMIOINFO * lpmmioinfo, UINT16 uFlags)
+UINT16 WINAPI mmioGetInfo(HMMIO16 hmmio, MMIOINFO16 * lpmmioinfo, UINT16 uFlags)
 {
-	LPMMIOINFO	lpmminfo;
+	LPMMIOINFO16	lpmminfo;
 	dprintf_mmio(stddeb, "mmioGetInfo\n");
-	lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
+	lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) return 0;
-	memcpy(lpmmioinfo, lpmminfo, sizeof(MMIOINFO));
+	memcpy(lpmmioinfo, lpmminfo, sizeof(MMIOINFO16));
 	GlobalUnlock16(hmmio);
 	return 0;
 }
@@ -2241,11 +3671,11 @@
 /**************************************************************************
 * 				mmioSetInfo    		[MMSYSTEM.1216]
 */
-UINT16 WINAPI mmioSetInfo(HMMIO16 hmmio, const MMIOINFO * lpmmioinfo, UINT16 uFlags)
+UINT16 WINAPI mmioSetInfo(HMMIO16 hmmio, const MMIOINFO16 * lpmmioinfo, UINT16 uFlags)
 {
-	LPMMIOINFO	lpmminfo;
+	LPMMIOINFO16	lpmminfo;
 	dprintf_mmio(stddeb, "mmioSetInfo\n");
-	lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
+	lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) return 0;
 	GlobalUnlock16(hmmio);
 	return 0;
@@ -2266,9 +3696,9 @@
 */
 UINT16 WINAPI mmioFlush(HMMIO16 hmmio, UINT16 uFlags)
 {
-	LPMMIOINFO	lpmminfo;
+	LPMMIOINFO16	lpmminfo;
 	dprintf_mmio(stddeb, "mmioFlush(%04X, %04X)\n", hmmio, uFlags);
-	lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
+	lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) return 0;
 	GlobalUnlock16(hmmio);
 	return 0;
@@ -2277,12 +3707,12 @@
 /**************************************************************************
 * 				mmioAdvance    		[MMSYSTEM.1219]
 */
-UINT16 WINAPI mmioAdvance(HMMIO16 hmmio, MMIOINFO * lpmmioinfo, UINT16 uFlags)
+UINT16 WINAPI mmioAdvance(HMMIO16 hmmio, MMIOINFO16 * lpmmioinfo, UINT16 uFlags)
 {
 	int		count = 0;
-	LPMMIOINFO	lpmminfo;
+	LPMMIOINFO16	lpmminfo;
 	dprintf_mmio(stddeb, "mmioAdvance\n");
-	lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
+	lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) return 0;
 	if (uFlags == MMIO_READ) {
 		count = _lread32(LOWORD(lpmminfo->dwReserved2), 
@@ -2299,9 +3729,29 @@
 }
 
 /**************************************************************************
-* 				mmioStringToFOURCC	[MMSYSTEM.1220]
-*/
-FOURCC WINAPI mmioStringToFOURCC(LPCSTR sz, UINT16 uFlags)
+ * 				mmioStringToFOURCCW	[WINMM.131]
+ */
+FOURCC WINAPI mmioStringToFOURCC32A(LPCSTR sz, UINT32 uFlags)
+{
+	return mmioStringToFOURCC16(sz,uFlags);
+}
+
+/**************************************************************************
+ * 				mmioStringToFOURCCW	[WINMM.132]
+ */
+FOURCC WINAPI mmioStringToFOURCC32W(LPCWSTR sz, UINT32 uFlags)
+{
+	LPSTR	szA = HEAP_strdupWtoA(GetProcessHeap(),0,sz);
+	FOURCC	ret = mmioStringToFOURCC32A(szA,uFlags);
+
+	HeapFree(GetProcessHeap(),0,szA);
+	return ret;
+}
+
+/**************************************************************************
+ * 				mmioStringToFOURCC	[MMSYSTEM.1220]
+ */
+FOURCC WINAPI mmioStringToFOURCC16(LPCSTR sz, UINT16 uFlags)
 {
 	dprintf_mmio(stddeb, "mmioStringToFOURCC // empty stub \n");
 	return 0;
@@ -2440,7 +3890,7 @@
 * 				mmioRename     		[MMSYSTEM.1226]
 */
 UINT16 WINAPI mmioRename(LPCSTR szFileName, LPCSTR szNewFileName,
-                         MMIOINFO * lpmmioinfo, DWORD dwRenameFlags)
+                         MMIOINFO16 * lpmmioinfo, DWORD dwRenameFlags)
 {
 	dprintf_mmio(stddeb, "mmioRename('%s', '%s', %p, %08lX); // empty stub \n",
 			szFileName, szNewFileName, lpmmioinfo, dwRenameFlags);
diff --git a/multimedia/time.c b/multimedia/time.c
index a9c7976..c631ce0 100644
--- a/multimedia/time.c
+++ b/multimedia/time.c
@@ -20,8 +20,8 @@
 #include "xmalloc.h"
 
 static BOOL32 mmTimeStarted = FALSE;
-static MMTIME mmSysTimeMS;
-static MMTIME mmSysTimeSMPTE;
+static MMTIME16 mmSysTimeMS;
+static MMTIME16 mmSysTimeSMPTE;
 
 typedef struct tagTIMERENTRY {
     WORD wDelay;
@@ -78,8 +78,8 @@
  *          guess current implementation via SetTimer has to be improved upon.		
  */
 
-		CallTimeFuncProc(lpTimer->lpFunc, lpTimer->wTimerID, 
-                                    0, lpTimer->dwUser, 0, 0);
+		Callbacks->CallTimeFuncProc(lpTimer->lpFunc, lpTimer->wTimerID,
+                                            0, lpTimer->dwUser, 0, 0 );
 
 		dprintf_mmtime(stddeb, "MMSysTimeCallback // after CallBack16 !\n");
 		fflush(stdout);
@@ -114,7 +114,7 @@
 /**************************************************************************
  * 				timeGetSystemTime	[MMSYSTEM.601]
  */
-WORD WINAPI timeGetSystemTime(LPMMTIME lpTime, WORD wSize)
+WORD WINAPI timeGetSystemTime(LPMMTIME16 lpTime, WORD wSize)
 {
     dprintf_mmsys(stddeb, "timeGetSystemTime(%p, %u);\n", lpTime, wSize);
     if (!mmTimeStarted)
diff --git a/objects/cursoricon.c b/objects/cursoricon.c
index fb02109..2a7cc6d 100644
--- a/objects/cursoricon.c
+++ b/objects/cursoricon.c
@@ -1447,4 +1447,53 @@
 /**********************************************************************
  *          GetIconInfo		(USER32.241)
  */
+BOOL32 WINAPI GetIconInfo(HICON32 hIcon,LPICONINFO iconinfo) {
+    CURSORICONINFO	*ciconinfo;
 
+    ciconinfo = GlobalLock16(hIcon);
+    if (!ciconinfo)
+	return FALSE;
+    iconinfo->xHotspot = ciconinfo->ptHotSpot.x;
+    iconinfo->yHotspot = ciconinfo->ptHotSpot.y;
+    iconinfo->fIcon    = TRUE; /* hmm */
+    /* FIXME ... add both bitmaps */
+    return TRUE;
+}
+
+/**********************************************************************
+ *          CreateIconIndirect		(USER32.78)
+ */
+HICON32 WINAPI CreateIconIndirect(LPICONINFO iconinfo) {
+    BITMAPOBJ *bmpXor,*bmpAnd;
+    HICON32 hObj;
+    int	sizeXor,sizeAnd;
+
+    bmpXor = (BITMAPOBJ *) GDI_GetObjPtr( iconinfo->hbmColor, BITMAP_MAGIC );
+    bmpAnd = (BITMAPOBJ *) GDI_GetObjPtr( iconinfo->hbmMask, BITMAP_MAGIC );
+
+    sizeXor = bmpXor->bitmap.bmHeight * bmpXor->bitmap.bmWidthBytes;
+    sizeAnd = bmpAnd->bitmap.bmHeight * bmpAnd->bitmap.bmWidthBytes;
+
+    hObj = GlobalAlloc16( GMEM_MOVEABLE, 
+		     sizeof(CURSORICONINFO) + sizeXor + sizeAnd );
+    if (hObj)
+    {
+	CURSORICONINFO *info;
+
+	info = (CURSORICONINFO *)GlobalLock16( hObj );
+	info->ptHotSpot.x   = iconinfo->xHotspot;
+	info->ptHotSpot.y   = iconinfo->yHotspot;
+	info->nWidth        = bmpXor->bitmap.bmWidth;
+	info->nHeight       = bmpXor->bitmap.bmHeight;
+	info->nWidthBytes   = bmpXor->bitmap.bmWidthBytes;
+	info->bPlanes       = bmpXor->bitmap.bmPlanes;
+	info->bBitsPerPixel = bmpXor->bitmap.bmBitsPixel;
+
+	/* Transfer the bitmap bits to the CURSORICONINFO structure */
+
+	GetBitmapBits32( iconinfo->hbmMask ,sizeAnd,(char*)(info + 1) );
+	GetBitmapBits32( iconinfo->hbmColor,sizeXor,(char*)(info + 1) +sizeAnd);
+	GlobalUnlock16( hObj );
+    }
+    return hObj;
+}
diff --git a/objects/dc.c b/objects/dc.c
index 762459d..2e0e1c1 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -453,9 +453,9 @@
     newdc->hSelf = (HDC32)handle;
     newdc->saveLevel = 0;
 
-    newdc->w.hGCClipRgn = 0;
-    newdc->w.hVisRgn = CreateRectRgn32( 0, 0, 0, 0 );
-    CombineRgn32( newdc->w.hVisRgn, dc->w.hVisRgn, 0, RGN_COPY );	
+    /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
+
+    newdc->w.hGCClipRgn = newdc->w.hVisRgn = 0;
     if (dc->w.hClipRgn)
     {
 	newdc->w.hClipRgn = CreateRectRgn32( 0, 0, 0, 0 );
@@ -527,8 +527,8 @@
     dc->vportExtY         = dcs->vportExtY;
 
     if (!(dc->w.flags & DC_MEMORY)) dc->w.bitsPerPixel = dcs->w.bitsPerPixel;
-    CombineRgn32( dc->w.hVisRgn, dcs->w.hVisRgn, 0, RGN_COPY );
     SelectClipRgn32( hdc, dcs->w.hClipRgn );
+
     SelectObject32( hdc, dcs->w.hBitmap );
     SelectObject32( hdc, dcs->w.hBrush );
     SelectObject32( hdc, dcs->w.hFont );
@@ -1110,14 +1110,13 @@
  */
 WORD WINAPI SetHookFlags(HDC16 hDC, WORD flags)
 {
-  DC* dc = (DC*)GDI_GetObjPtr( hDC, DC_MAGIC );
+    DC* dc = (DC*)GDI_GetObjPtr( hDC, DC_MAGIC );
 
-  if( dc )
+    if( dc )
     {
         WORD wRet = dc->w.flags & DC_DIRTY;
 
-        /* "Undocumented Windows" info is slightly
-         *  confusing
+        /* "Undocumented Windows" info is slightly confusing.
          */
 
         dprintf_dc(stddeb,"SetHookFlags: hDC %04x, flags %04x\n",hDC,flags);
@@ -1129,6 +1128,6 @@
 	GDI_HEAP_UNLOCK( hDC );
         return wRet;
     }
-  return 0;
+    return 0;
 }
 
diff --git a/objects/dib.c b/objects/dib.c
index 5035ec34..1f93183 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -193,7 +193,8 @@
         colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
         colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
     }
-    if (!(colorMapping = (int *)malloc( colors * sizeof(int) ))) return NULL;
+    if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
+                                          colors * sizeof(int) ))) return NULL;
 
     if (coloruse == DIB_RGB_COLORS)
     {
@@ -664,7 +665,7 @@
         fprintf( stderr, "Invalid depth %d for SetDIBits!\n", descr->infoBpp );
         break;
     }
-    if (colorMapping) free(colorMapping);
+    if (colorMapping) HeapFree( GetProcessHeap(), 0, colorMapping );
     XPutImage( display, descr->drawable, descr->gc, bmpImage,
                descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
                descr->width, descr->height );
diff --git a/objects/font.c b/objects/font.c
index 5404d2a..93173f9 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -43,7 +43,7 @@
 /***********************************************************************
  *              LOGFONT conversion functions.
  */
-static void __logfont32to16( INT16* plf16, INT32* plf32 )
+static void __logfont32to16( INT16* plf16, const INT32* plf32 )
 {
     int  i;
     for( i = 0; i < 5; i++ ) *plf16++ = *plf32++;
@@ -51,7 +51,7 @@
    *((INT32*)plf16)   = *plf32;
 }
 
-static void __logfont16to32( INT32* plf32, INT16* plf16 )
+static void __logfont16to32( INT32* plf32, const INT16* plf16 )
 {
     int i;
     for( i = 0; i < 5; i++ ) *plf32++ = *plf16++;
@@ -61,117 +61,149 @@
 
 void FONT_LogFont32ATo16( const LOGFONT32A* font32, LPLOGFONT16 font16 )
 {
-  __logfont32to16( (INT16*)font16, (INT32*)font32 );
+  __logfont32to16( (INT16*)font16, (const INT32*)font32 );
     lstrcpyn32A( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
 }
 
 void FONT_LogFont32WTo16( const LOGFONT32W* font32, LPLOGFONT16 font16 )
 {
-  __logfont32to16( (INT16*)font16, (INT32*)font32 );
+  __logfont32to16( (INT16*)font16, (const INT32*)font32 );
     lstrcpynWtoA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
 }
 
-void FONT_LogFont16To32A( LPLOGFONT16 font16, LPLOGFONT32A font32 )
+void FONT_LogFont16To32A( const LPLOGFONT16 font16, LPLOGFONT32A font32 )
 {
-  __logfont16to32( (INT32*)font32, (INT16*)font16 );
+  __logfont16to32( (INT32*)font32, (const INT16*)font16 );
     lstrcpyn32A( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
 }
 
-void FONT_LogFont16To32W( LPLOGFONT16 font16, LPLOGFONT32W font32 )
+void FONT_LogFont16To32W( const LPLOGFONT16 font16, LPLOGFONT32W font32 )
 {
-  __logfont16to32( (INT32*)font32, (INT16*)font16 );
+  __logfont16to32( (INT32*)font32, (const INT16*)font16 );
     lstrcpynAtoW( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
 }
 
 /***********************************************************************
  *              TEXTMETRIC conversion functions.
  */
-void FONT_TextMetric32Ato16( LPTEXTMETRIC32A ptm32, LPTEXTMETRIC16 ptm16 )
+void FONT_TextMetric32Ato16(const LPTEXTMETRIC32A ptm32, LPTEXTMETRIC16 ptm16 )
 {
-    int         i;
-    INT16*      pi16 = (INT16*)ptm16;
-
-   *(INT32*)&ptm16->tmFirstChar = *(INT32*)&ptm32->tmFirstChar;
-   *(INT32*)&ptm16->tmItalic = *(INT32*)&ptm32->tmItalic;
-   *(INT16*)&ptm16->tmPitchAndFamily = *(INT16*)&ptm32->tmPitchAndFamily;
-#define pi32 ((INT32*)ptm32)
-    for( i = 0; i < 8; i++ ) *pi16++ = *pi32++;
-    ptm16->tmOverhang = pi32[0];
-    ptm16->tmDigitizedAspectX = pi32[1];
-    ptm16->tmDigitizedAspectY = pi32[2];
-#undef  pi32
-}
-
-void FONT_TextMetric32Wto16( LPTEXTMETRIC32W ptm32, LPTEXTMETRIC16 ptm16 )
-{
-    int         i;
-    INT16*      pi16 = (INT16*)ptm16;
-
+    ptm16->tmHeight = ptm32->tmHeight;
+    ptm16->tmAscent = ptm32->tmAscent;
+    ptm16->tmDescent = ptm32->tmDescent;
+    ptm16->tmInternalLeading = ptm32->tmInternalLeading;
+    ptm16->tmExternalLeading = ptm32->tmExternalLeading;
+    ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
+    ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
+    ptm16->tmWeight = ptm32->tmWeight;
+    ptm16->tmOverhang = ptm32->tmOverhang;
+    ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
+    ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
     ptm16->tmFirstChar = ptm32->tmFirstChar;
     ptm16->tmLastChar = ptm32->tmLastChar;
     ptm16->tmDefaultChar = ptm32->tmDefaultChar;
     ptm16->tmBreakChar = ptm32->tmBreakChar;
-   *(INT32*)&ptm16->tmItalic = *(INT32*)&ptm32->tmItalic;
-   *(INT16*)&ptm16->tmPitchAndFamily = *(INT16*)&ptm32->tmPitchAndFamily;
-#define pi32 ((INT32*)ptm32)
-    for( i = 0; i < 8; i++ ) *pi16++ = *pi32++;
-    ptm16->tmOverhang = pi32[0];
-    ptm16->tmDigitizedAspectX = pi32[1];
-    ptm16->tmDigitizedAspectY = pi32[2];
-#undef  pi32
+    ptm16->tmItalic = ptm32->tmItalic;
+    ptm16->tmUnderlined = ptm32->tmUnderlined;
+    ptm16->tmStruckOut = ptm32->tmStruckOut;
+    ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
+    ptm16->tmCharSet = ptm32->tmCharSet;
 }
 
-void FONT_TextMetric16to32A( LPTEXTMETRIC16 ptm16, LPTEXTMETRIC32A ptm32 )
+void FONT_TextMetric32Wto16(const LPTEXTMETRIC32W ptm32, LPTEXTMETRIC16 ptm16 )
 {
-    int         i;
-    INT16*      pi16 = (INT16*)ptm16;
-
-   *(INT32*)&ptm32->tmFirstChar = *(INT32*)&ptm16->tmFirstChar;
-   *(INT32*)&ptm32->tmItalic = *(INT32*)&ptm16->tmItalic;
-   *(INT16*)&ptm32->tmPitchAndFamily = *(INT16*)&ptm16->tmPitchAndFamily;
-#define pi32 ((INT32*)ptm32)
-    for( i = 0; i < 8; i++ ) *pi32++ = *pi16++;
-    pi32[0] = ptm16->tmOverhang;
-    pi32[1] = ptm16->tmDigitizedAspectX;
-    pi32[2] = ptm16->tmDigitizedAspectY;
-#undef  pi32
+    ptm16->tmHeight = ptm32->tmHeight;
+    ptm16->tmAscent = ptm32->tmAscent;
+    ptm16->tmDescent = ptm32->tmDescent;
+    ptm16->tmInternalLeading = ptm32->tmInternalLeading;
+    ptm16->tmExternalLeading = ptm32->tmExternalLeading;
+    ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
+    ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
+    ptm16->tmWeight = ptm32->tmWeight;
+    ptm16->tmOverhang = ptm32->tmOverhang;
+    ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
+    ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
+    ptm16->tmFirstChar = ptm32->tmFirstChar;
+    ptm16->tmLastChar = ptm32->tmLastChar;
+    ptm16->tmDefaultChar = ptm32->tmDefaultChar;
+    ptm16->tmBreakChar = ptm32->tmBreakChar;
+    ptm16->tmItalic = ptm32->tmItalic;
+    ptm16->tmUnderlined = ptm32->tmUnderlined;
+    ptm16->tmStruckOut = ptm32->tmStruckOut;
+    ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
+    ptm16->tmCharSet = ptm32->tmCharSet;
 }
 
-void FONT_TextMetric16to32W( LPTEXTMETRIC16 ptm16, LPTEXTMETRIC32W ptm32 )
+void FONT_TextMetric16to32A(const LPTEXTMETRIC16 ptm16, LPTEXTMETRIC32A ptm32 )
 {
-    int         i;
-    INT16*      pi16 = (INT16*)ptm16;
-
+    ptm32->tmHeight = ptm16->tmHeight;
+    ptm32->tmAscent = ptm16->tmAscent;
+    ptm32->tmDescent = ptm16->tmDescent;
+    ptm32->tmInternalLeading = ptm16->tmInternalLeading;
+    ptm32->tmExternalLeading = ptm16->tmExternalLeading;
+    ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
+    ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
+    ptm32->tmWeight = ptm16->tmWeight;
+    ptm32->tmOverhang = ptm16->tmOverhang;
+    ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
+    ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
     ptm32->tmFirstChar = ptm16->tmFirstChar;
     ptm32->tmLastChar = ptm16->tmLastChar;
     ptm32->tmDefaultChar = ptm16->tmDefaultChar;
     ptm32->tmBreakChar = ptm16->tmBreakChar;
-   *(INT32*)&ptm32->tmItalic = *(INT32*)&ptm16->tmItalic;
-   *(INT16*)&ptm32->tmPitchAndFamily = *(INT16*)&ptm16->tmPitchAndFamily;
-#define pi32 ((INT32*)ptm32)
-    for( i = 0; i < 8; i++ ) *pi32++ = *pi16++;
-    pi32[0] = ptm16->tmOverhang;
-    pi32[1] = ptm16->tmDigitizedAspectX;
-    pi32[2] = ptm16->tmDigitizedAspectY;
-#undef  pi32
+    ptm32->tmItalic = ptm16->tmItalic;
+    ptm32->tmUnderlined = ptm16->tmUnderlined;
+    ptm32->tmStruckOut = ptm16->tmStruckOut;
+    ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
+    ptm32->tmCharSet = ptm16->tmCharSet;
 }
 
-void FONT_TextMetric32Ato32W( LPTEXTMETRIC32A ptm32A, LPTEXTMETRIC32W ptm32W )
+void FONT_TextMetric16to32W(const LPTEXTMETRIC16 ptm16, LPTEXTMETRIC32W ptm32 )
 {
-    int         i;
-#define pi32A ((INT32*)ptm32A)
-#define pi32W ((INT32*)ptm32W)
-    for( i = 0; i < 8; i++ ) *pi32W++ = *pi32A++;
-#undef pi32W
-#undef pi32A
-#define pch32A ((BYTE*)ptm32A)
-#define pch32W ((WCHAR*)ptm32W)
-   for( i = 0; i < 4; i++ ) *pch32W++ = *pch32A++;
-#undef pch32W
-#define pch32W ((BYTE*)ptm32W)
-   for( i = 0; i < 5; i++ ) *pch32W++ = *pch32A++;
-#undef pch32W
-#undef pch32A
+    ptm32->tmHeight = ptm16->tmHeight;
+    ptm32->tmAscent = ptm16->tmAscent;
+    ptm32->tmDescent = ptm16->tmDescent;
+    ptm32->tmInternalLeading = ptm16->tmInternalLeading;
+    ptm32->tmExternalLeading = ptm16->tmExternalLeading;
+    ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
+    ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
+    ptm32->tmWeight = ptm16->tmWeight;
+    ptm32->tmOverhang = ptm16->tmOverhang;
+    ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
+    ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
+    ptm32->tmFirstChar = ptm16->tmFirstChar;
+    ptm32->tmLastChar = ptm16->tmLastChar;
+    ptm32->tmDefaultChar = ptm16->tmDefaultChar;
+    ptm32->tmBreakChar = ptm16->tmBreakChar;
+    ptm32->tmItalic = ptm16->tmItalic;
+    ptm32->tmUnderlined = ptm16->tmUnderlined;
+    ptm32->tmStruckOut = ptm16->tmStruckOut;
+    ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
+    ptm32->tmCharSet = ptm16->tmCharSet;
+}
+
+void FONT_TextMetric32Ato32W(const LPTEXTMETRIC32A ptm32A, LPTEXTMETRIC32W ptm32W )
+{
+    ptm32W->tmHeight = ptm32A->tmHeight;
+    ptm32W->tmAscent = ptm32A->tmAscent;
+    ptm32W->tmDescent = ptm32A->tmDescent;
+    ptm32W->tmInternalLeading = ptm32A->tmInternalLeading;
+    ptm32W->tmExternalLeading = ptm32A->tmExternalLeading;
+    ptm32W->tmAveCharWidth = ptm32A->tmAveCharWidth;
+    ptm32W->tmMaxCharWidth = ptm32A->tmMaxCharWidth;
+    ptm32W->tmWeight = ptm32A->tmWeight;
+    ptm32W->tmOverhang = ptm32A->tmOverhang;
+    ptm32W->tmDigitizedAspectX = ptm32A->tmDigitizedAspectX;
+    ptm32W->tmDigitizedAspectY = ptm32A->tmDigitizedAspectY;
+    ptm32W->tmFirstChar = ptm32A->tmFirstChar;
+    ptm32W->tmLastChar = ptm32A->tmLastChar;
+    ptm32W->tmDefaultChar = ptm32A->tmDefaultChar;
+    ptm32W->tmBreakChar = ptm32A->tmBreakChar;
+    ptm32W->tmItalic = ptm32A->tmItalic;
+    ptm32W->tmUnderlined = ptm32A->tmUnderlined;
+    ptm32W->tmStruckOut = ptm32A->tmStruckOut;
+    ptm32W->tmPitchAndFamily = ptm32A->tmPitchAndFamily;
+    ptm32W->tmCharSet = ptm32A->tmCharSet;
 }
 
 /***********************************************************************
@@ -238,7 +270,8 @@
     LOGFONT16 logfont = { height, width, esc, orient, weight, italic, underline,
                           strikeout, charset, outpres, clippres, quality, pitch, };
 
-    dprintf_font(stddeb,"CreateFont16('%s',%d,%d)\n", name, height, width);
+    dprintf_font(stddeb,"CreateFont16('%s',%d,%d)\n",
+		 (name ? name : "(null)") , height, width);
     if (name) 
 	lstrcpyn32A(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
     else 
@@ -274,7 +307,7 @@
                                          italic, underline, strikeout, charset,
                                          outpres, clippres, quality, pitch,
                                          namea );
-    HeapFree( GetProcessHeap(), 0, namea );
+    if (namea) HeapFree( GetProcessHeap(), 0, namea );
     return ret;
 }
 
@@ -953,7 +986,7 @@
  */
 DWORD WINAPI SetMapperFlags32( HDC32 hDC, DWORD dwFlag )
 {
-    dprintf_font(stdnimp,"SetmapperFlags(%04x, %08lX) // Empty Stub !\n",
+    dprintf_font(stdnimp,"SetMapperFlags(%04x, %08lX) // Empty Stub !\n",
                  hDC, dwFlag);
     return 0L;
 }
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index 3d577f9..6504676 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -18,13 +18,10 @@
 #include "region.h"
 #include "stddebug.h"
 #include "debug.h"
+#include "gdi.h"
 
 WORD GDI_HeapSel = 0;
 
-/* Object types for EnumObjects() */
-#define OBJ_PEN             1
-#define OBJ_BRUSH           2
-
 /***********************************************************************
  *          GDI stock objects 
  */
@@ -453,6 +450,62 @@
     return result;
 }
 
+/***********************************************************************
+ *           GetObjectType    (GDI32.205)
+ */
+DWORD WINAPI GetObjectType( HANDLE32 handle )
+{
+    GDIOBJHDR * ptr = NULL;
+    INT32 result = 0;
+    dprintf_gdi(stddeb, "GetObjectType: %08x\n", handle );
+
+    if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
+      ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
+    else
+      ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
+    if (!ptr) return 0;
+    
+    switch(ptr->wMagic)
+    {
+      case PEN_MAGIC:
+	  result = OBJ_PEN;
+	  break;
+      case BRUSH_MAGIC: 
+	  result = OBJ_BRUSH;
+	  break;
+      case BITMAP_MAGIC: 
+	  result = OBJ_BITMAP;
+	  break;
+      case FONT_MAGIC:
+	  result = OBJ_FONT;
+	  break;
+      case PALETTE_MAGIC:
+	  result = OBJ_PAL;
+	  break;
+      case REGION_MAGIC:
+	  result = OBJ_REGION;
+	  break;
+      case DC_MAGIC:
+	  result = OBJ_DC;
+	  break;
+      case META_DC_MAGIC:
+	  result = OBJ_METADC;
+	  break;
+      case METAFILE_MAGIC:
+	  result = OBJ_METAFILE;
+	  break;
+      case METAFILE_DC_MAGIC:
+	  result = OBJ_METADC;
+	  break;
+
+	  default:
+	  fprintf( stderr, "GetObjectType: magic %04x not implemented\n",
+			   ptr->wMagic );
+	  break;
+    }
+    GDI_HEAP_UNLOCK( handle );
+    return result;
+}
 
 /***********************************************************************
  *           GetObject32W    (GDI32.206)
@@ -714,6 +767,14 @@
     /* Nothing to do */
 }
 
+/***********************************************************************
+ *           GdiFlush    (GDI32.128)
+ */
+BOOL32 WINAPI GdiFlush(void)
+{
+    return TRUE;  /* FIXME */
+}
+
 
 /***********************************************************************
  *           GdiGetBatchLimit    (GDI32.129)
diff --git a/objects/metafile.c b/objects/metafile.c
index ba27f44..7785313 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -259,6 +259,7 @@
 
     dprintf_metafile(stddeb,"PlayMetaFile(%04x %04x)\n",hdc,hmf);
 
+    if (!mh) return FALSE;
     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
     hPen = dc->w.hPen;
     hBrush = dc->w.hBrush;
@@ -783,12 +784,15 @@
         }
         break;	
        
+     case META_SETTEXTCHAREXTRA:
+	    SetTextCharacterExtra16(hdc, (INT16)*(mr->rdParam));
+	    break;
+
      case META_SETTEXTJUSTIFICATION:
        	SetTextJustification32(hdc, *(mr->rdParam + 1), *(mr->rdParam));
 	break;
 
 #define META_UNIMP(x) case x: fprintf(stderr,"PlayMetaFileRecord:record type "#x" not implemented.\n");break;
-    META_UNIMP(META_SETTEXTCHAREXTRA)
     META_UNIMP(META_FRAMEREGION)
     META_UNIMP(META_DRAWTEXT)
     META_UNIMP(META_SETDIBTODEV)
diff --git a/objects/oembitmap.c b/objects/oembitmap.c
index 2a3cb2d..ba13b82 100644
--- a/objects/oembitmap.c
+++ b/objects/oembitmap.c
@@ -15,10 +15,10 @@
 #include "callback.h"
 #include "color.h"
 #include "cursoricon.h"
+#include "heap.h"
 #include "stddebug.h"
 #include "tweak.h"
 #include "debug.h"
-#include "xmalloc.h"
 
   /* Include OEM pixmaps */
 #include "bitmaps/obm_cdrom"
@@ -208,34 +208,36 @@
   /* palette indexes, but system colors that will be converted to    */
   /* indexes later on.                                               */
 
+#if 0
 static const struct
 {
     char *   name;
     COLORREF color;
 } OBM_SymbolicColors[] =
+#endif
+static XpmColorSymbol OBM_Colors[] =
 {
-    { "black",            RGB(0,0,0) },
-    { "white",            RGB(255,255,255) },
-    { "red",              RGB(255,0,0) },
-    { "green",            RGB(0,255,0) },
-    { "blue",             RGB(0,0,255) },
-    { "yellow",           RGB(255,255,0) },
-    { "cyan",             RGB(0,255,255) },    
-    { "dkyellow",         RGB(128,128,0) },
-    { "purple",           RGB(128,0,128) },
-    { "ltgray",           RGB(192,192,192) },
-    { "dkgray",           RGB(128,128,128) },
-    { "foldercol",        RGB(0,191,191) },
-    { "button_face",      PALETTEINDEX(COLOR_BTNFACE) },
-    { "button_shadow",    PALETTEINDEX(COLOR_BTNSHADOW) },
-    { "button_highlight", PALETTEINDEX(COLOR_BTNHIGHLIGHT) },
-    { "button_edge",      PALETTEINDEX(COLOR_BTNHIGHLIGHT) },
-    { "button_text",      PALETTEINDEX(COLOR_BTNTEXT) },
-    { "window_frame",     PALETTEINDEX(COLOR_WINDOWFRAME) }
+    { "black",            NULL, (Pixel)RGB(0,0,0) },
+    { "white",            NULL, (Pixel)RGB(255,255,255) },
+    { "red",              NULL, (Pixel)RGB(255,0,0) },
+    { "green",            NULL, (Pixel)RGB(0,255,0) },
+    { "blue",             NULL, (Pixel)RGB(0,0,255) },
+    { "yellow",           NULL, (Pixel)RGB(255,255,0) },
+    { "cyan",             NULL, (Pixel)RGB(0,255,255) },    
+    { "dkyellow",         NULL, (Pixel)RGB(128,128,0) },
+    { "purple",           NULL, (Pixel)RGB(128,0,128) },
+    { "ltgray",           NULL, (Pixel)RGB(192,192,192) },
+    { "dkgray",           NULL, (Pixel)RGB(128,128,128) },
+    { "foldercol",        NULL, (Pixel)RGB(0,191,191) },
+    { "button_face",      NULL, (Pixel)PALETTEINDEX(COLOR_BTNFACE) },
+    { "button_shadow",    NULL, (Pixel)PALETTEINDEX(COLOR_BTNSHADOW) },
+    { "button_highlight", NULL, (Pixel)PALETTEINDEX(COLOR_BTNHIGHLIGHT) },
+    { "button_edge",      NULL, (Pixel)PALETTEINDEX(COLOR_BTNHIGHLIGHT) },
+    { "button_text",      NULL, (Pixel)PALETTEINDEX(COLOR_BTNTEXT) },
+    { "window_frame",     NULL, (Pixel)PALETTEINDEX(COLOR_WINDOWFRAME) }
 };
 
-#define NB_COLOR_SYMBOLS \
-            (sizeof(OBM_SymbolicColors)/sizeof(OBM_SymbolicColors[0]))
+#define NB_COLOR_SYMBOLS (sizeof(OBM_Colors)/sizeof(OBM_Colors[0]))
 
   /* These are the symbolic colors for monochrome bitmaps   */
   /* This is needed to make sure that black is always 0 and */
@@ -247,8 +249,6 @@
     { "white", NULL, 0xffffffff }
 };
 
-static XpmColorSymbol *OBM_Colors = NULL;
-
 /* This structure holds the arguments for OBM_CreateBitmaps() */
 typedef struct
 {
@@ -266,23 +266,19 @@
  */
 static BOOL32 OBM_InitColorSymbols()
 {
+    static BOOL32 initialized = FALSE;
     int i;
 
-    if (OBM_Colors) return TRUE;  /* Already initialised */
+    if (initialized) return TRUE;  /* Already initialised */
+    initialized = TRUE;
 
-    OBM_Colors = (XpmColorSymbol *) malloc( sizeof(XpmColorSymbol) *
-                                            NB_COLOR_SYMBOLS );
-    if (!OBM_Colors) return FALSE;
     for (i = 0; i < NB_COLOR_SYMBOLS; i++)
     {
-        OBM_Colors[i].name  = OBM_SymbolicColors[i].name;
-        OBM_Colors[i].value = NULL;
-        if (OBM_SymbolicColors[i].color & 0xff000000)  /* PALETTEINDEX */
+        if (OBM_Colors[i].pixel & 0xff000000)  /* PALETTEINDEX */
             OBM_Colors[i].pixel = COLOR_ToPhysical( NULL,
-                            GetSysColor32(OBM_SymbolicColors[i].color & 0xff));
+                                    GetSysColor32(OBM_Colors[i].pixel & 0xff));
         else  /* RGB*/
-            OBM_Colors[i].pixel = COLOR_ToPhysical( NULL,
-                                                 OBM_SymbolicColors[i].color );
+            OBM_Colors[i].pixel = COLOR_ToPhysical( NULL, OBM_Colors[i].pixel);
     }
     return TRUE;
 }
@@ -331,7 +327,8 @@
     XpmAttributes *attrs;
     int err;
 
-    attrs = (XpmAttributes *)xmalloc( XpmAttributesSize() );
+    attrs = (XpmAttributes *)HEAP_xalloc( GetProcessHeap(), 0,
+                                          XpmAttributesSize() );
     attrs->valuemask    = XpmColormap | XpmDepth | XpmColorSymbols |XpmHotspot;
     attrs->colormap     = COLOR_GetColormap();
     attrs->depth        = descr->color ? screenDepth : 1;
@@ -343,7 +340,7 @@
 
     if (err != XpmSuccess)
     {
-        free( attrs );
+        HeapFree( GetProcessHeap(), 0, attrs );
         return FALSE;
     }
     descr->hotspot.x = attrs->x_hotspot;
@@ -353,7 +350,7 @@
     if (descr->need_mask)
         descr->mask = OBM_MakeBitmap( attrs->width, attrs->height,
                                       1, pixmask );
-    free( attrs );
+    HeapFree( GetProcessHeap(), 0, attrs );
     if (!descr->bitmap)
     {
         if (pixmap) XFreePixmap( display, pixmap );
diff --git a/objects/palette.c b/objects/palette.c
index 0049425..c8adcaa 100644
--- a/objects/palette.c
+++ b/objects/palette.c
@@ -46,7 +46,8 @@
 
     /* create default palette (20 system colors) */
 
-    palPtr = xmalloc( sizeof(LOGPALETTE) + (NB_RESERVED_COLORS-1)*sizeof(PALETTEENTRY) );
+    palPtr = HeapAlloc( GetProcessHeap(), 0,
+             sizeof(LOGPALETTE) + (NB_RESERVED_COLORS-1)*sizeof(PALETTEENTRY));
     if (!palPtr) return FALSE;
 
     palPtr->palVersion = 0x300;
@@ -66,7 +67,7 @@
 
     GDI_HEAP_UNLOCK( hpalette );
 
-    free( palPtr );
+    HeapFree( GetProcessHeap(), 0, palPtr );
     return hpalette;
 }
 
diff --git a/objects/region.c b/objects/region.c
index a8e86e8..fd0bbb5 100644
--- a/objects/region.c
+++ b/objects/region.c
@@ -422,6 +422,7 @@
 
     for (i = 0; i < nbpolygons; i++, count++)
     {
+        if (*count <= 1) continue;
 	for (j = *count, pt = xpoints; j > 0; j--, points++, pt++)
 	{
 	    pt->x = points->x;
@@ -436,7 +437,7 @@
             GDI_FreeObject( hrgn );
             return 0;
         }
-	if (i > 0)
+	if (obj->xrgn)
 	{
 	    Region tmprgn = XCreateRegion();
 	    if (mode == WINDING) XUnionRegion( xrgn, obj->xrgn, tmprgn );
@@ -570,34 +571,51 @@
     }
 }
 
+
+/***********************************************************************
+ *           REGION_IsEmpty
+ */
+BOOL32 REGION_IsEmpty( HRGN32 hRgn )
+{
+    RGNOBJ*     rgnObj = (RGNOBJ*) GDI_GetObjPtr( hRgn, REGION_MAGIC );
+    BOOL32	ret = TRUE;
+
+    if( rgnObj )
+    {
+	if( rgnObj->xrgn && !XEmptyRegion(rgnObj->xrgn) ) ret = FALSE;
+	GDI_HEAP_UNLOCK( hRgn );
+    }
+    return ret;
+}
+
+
 /***********************************************************************
  *           REGION_UnionRectWithRgn
  *
- * Add rectangle to region
+ * Add rc rectangle to the region.
  */
 BOOL32 REGION_UnionRectWithRgn( HRGN32 hRgn, const RECT32 *rc )
 {
-  RGNOBJ 	*rgnObj = (RGNOBJ*) GDI_GetObjPtr( hRgn, REGION_MAGIC );
-  XRectangle     rect = { rc->left, rc->top, rc->right - rc->left, rc->bottom - rc->top };
-  BOOL32 ret = FALSE;
+    RGNOBJ*	rgnObj = (RGNOBJ*) GDI_GetObjPtr( hRgn, REGION_MAGIC );
+    XRectangle  rect = { rc->left, rc->top, rc->right - rc->left, rc->bottom - rc->top };
+    BOOL32 	ret = ERROR;
 
-  if( rgnObj )
-  {
-    if( !rgnObj->xrgn )
+    if( rgnObj )
     {
-      if (!(rgnObj->xrgn = XCreateRegion()))
-      {
-         GDI_FreeObject( hRgn );
-         return 0;
-      }
-      ret = SIMPLEREGION; 
+	if( !rgnObj->xrgn )
+	{
+	    if ((rgnObj->xrgn = XCreateRegion()))
+		ret = SIMPLEREGION;
+	    else
+		goto done;
+	}
+	else
+	    ret = COMPLEXREGION;
+	XUnionRectWithRegion( &rect, rgnObj->xrgn, rgnObj->xrgn );
+done:
+	GDI_HEAP_UNLOCK( hRgn );
     }
-    else
-      ret = COMPLEXREGION;
-    XUnionRectWithRegion( &rect, rgnObj->xrgn, rgnObj->xrgn );
-    GDI_HEAP_UNLOCK( hRgn );
-  }
-  return ret;
+    return ret;
 }
 
 
@@ -608,26 +626,27 @@
  */
 BOOL32 REGION_FrameRgn( HRGN32 hDest, HRGN32 hSrc, INT32 x, INT32 y )
 {
-    RGNOBJ *destObj,*srcObj;
-    Region result;
+    BOOL32 bRet;
+    RGNOBJ *srcObj = (RGNOBJ*) GDI_GetObjPtr( hSrc, REGION_MAGIC );
 
-    destObj = (RGNOBJ*) GDI_GetObjPtr( hDest, REGION_MAGIC );
-    srcObj  = (RGNOBJ*) GDI_GetObjPtr( hSrc, REGION_MAGIC );
-    if (!srcObj->xrgn) 
+    if (srcObj->xrgn) 
     {
-      GDI_HEAP_UNLOCK( hDest );
-      GDI_HEAP_UNLOCK( hSrc );
-      return FALSE;
+	RGNOBJ* destObj = (RGNOBJ*) GDI_GetObjPtr( hDest, REGION_MAGIC );
+	Region  resRgn;
+
+	REGION_CopyRegion( srcObj, destObj );
+	XShrinkRegion( destObj->xrgn, -x, -y );
+	resRgn = XCreateRegion();
+	XSubtractRegion( destObj->xrgn, srcObj->xrgn, resRgn );
+	XDestroyRegion( destObj->xrgn );
+	destObj->xrgn = resRgn;
+	GDI_HEAP_UNLOCK( hDest );
+	bRet = TRUE;
     }
-    REGION_CopyRegion( srcObj, destObj );
-    XShrinkRegion( destObj->xrgn, -x, -y );
-    result = XCreateRegion();
-    XSubtractRegion( destObj->xrgn, srcObj->xrgn, result );
-    XDestroyRegion( destObj->xrgn );
-    destObj->xrgn = result;
-    GDI_HEAP_UNLOCK( hDest );
+    else
+	bRet = FALSE;
     GDI_HEAP_UNLOCK( hSrc );
-    return TRUE;
+    return bRet;
 }
 
 
@@ -647,118 +666,108 @@
  */
 INT32 WINAPI CombineRgn32(HRGN32 hDest, HRGN32 hSrc1, HRGN32 hSrc2, INT32 mode)
 {
-    RGNOBJ *destObj, *src1Obj, *src2Obj;
-    Region destrgn;
-    INT32 result;
+    RGNOBJ *destObj = (RGNOBJ *) GDI_GetObjPtr( hDest, REGION_MAGIC);
+    INT32 result = ERROR;
 
     dprintf_region(stddeb, "CombineRgn: %04x,%04x -> %04x mode=%x\n", 
 		   hSrc1, hSrc2, hDest, mode );
-    
-    if (!(destObj = (RGNOBJ *) GDI_GetObjPtr( hDest, REGION_MAGIC )))
-	return ERROR;
-    if (!(src1Obj = (RGNOBJ *) GDI_GetObjPtr( hSrc1, REGION_MAGIC )))
+    if (destObj)
     {
-        GDI_HEAP_UNLOCK( hDest );
-	return ERROR;
-    }
-    if (mode == RGN_COPY) 
-    {
-       result = REGION_CopyRegion( src1Obj, destObj );
-       GDI_HEAP_UNLOCK( hDest );
-       GDI_HEAP_UNLOCK( hSrc1 );
-       return result;
-    }
+	RGNOBJ *src1Obj = (RGNOBJ *) GDI_GetObjPtr( hSrc1, REGION_MAGIC);
 
-    if (!(src2Obj = (RGNOBJ *) GDI_GetObjPtr( hSrc2, REGION_MAGIC )))
-    {
-       GDI_HEAP_UNLOCK( hDest );
-       GDI_HEAP_UNLOCK( hSrc1 );
-       return ERROR;
-    }
-      /* Some optimizations for null regions */
-
-    if (!src1Obj->xrgn || !src2Obj->xrgn)
-    {
-        switch(mode)
-        {
-        case RGN_DIFF:
-            if (src1Obj->xrgn)
+	if (src1Obj)
+	{
+	    if (mode == RGN_COPY)
+		result = REGION_CopyRegion( src1Obj, destObj );
+	    else
 	    {
-                result = REGION_CopyRegion( src1Obj, destObj );
-		GDI_HEAP_UNLOCK( hDest );
-		GDI_HEAP_UNLOCK( hSrc1 );
-		GDI_HEAP_UNLOCK( hSrc2 );
-		return result;
+		RGNOBJ *src2Obj = (RGNOBJ *) GDI_GetObjPtr( hSrc2, REGION_MAGIC);
+
+		if (src2Obj)
+		{
+		    if (!src1Obj->xrgn || !src2Obj->xrgn)
+		    {
+			/* Some optimizations for null regions */
+			switch( mode )
+			{
+			    case RGN_DIFF:
+				 if (src1Obj->xrgn)
+				 {
+				     result = REGION_CopyRegion( src1Obj, destObj );
+				     break;
+				 }
+				 /* else fall through */
+			    case RGN_AND:
+				 if (destObj->xrgn) 
+				 {
+				     XDestroyRegion( destObj->xrgn );
+				     destObj->xrgn = 0;
+				 }
+				 result = NULLREGION;
+				 break;
+
+			    case RGN_OR:
+			    case RGN_XOR:
+#define __SRC_RGN ((src1Obj->xrgn) ? src1Obj : src2Obj)
+				 result = REGION_CopyRegion( __SRC_RGN, destObj );
+#undef  __SRC_RGN
+				 break;
+
+			    case 0:
+			    default:
+				 /* makes gcc generate more efficient code */
+			}
+		    }
+		    else /* both regions are present */
+		    {
+			Region  destRgn = XCreateRegion();
+
+			if (destRgn)
+			{
+			    switch (mode)
+			    {
+				case RGN_AND:
+				     XIntersectRegion( src1Obj->xrgn, src2Obj->xrgn, destRgn );
+				     break;
+				case RGN_OR:
+				     XUnionRegion( src1Obj->xrgn, src2Obj->xrgn, destRgn );
+				     break;
+				case RGN_XOR:
+				     XXorRegion( src1Obj->xrgn, src2Obj->xrgn, destRgn );
+				     break;
+				case RGN_DIFF:
+			             XSubtractRegion( src1Obj->xrgn, src2Obj->xrgn, destRgn );
+				     break;
+
+				case 0: /* makes gcc generate more efficient code */
+				default:
+				     XDestroyRegion( destRgn );
+				     goto done;
+			    }
+
+			    if ( destObj->xrgn ) 
+				 XDestroyRegion( destObj->xrgn );
+			    if ( XEmptyRegion( destRgn ) )
+			    {
+				 XDestroyRegion( destRgn );
+				 destObj->xrgn = 0;
+				 result = NULLREGION;
+			    }
+			    else 
+			    {
+				 destObj->xrgn = destRgn;
+				 result = COMPLEXREGION;
+			    }
+			}
+		    }
+done:
+		    GDI_HEAP_UNLOCK( hSrc2 );
+		}
 	    }
-            /* else fall through */
-        case RGN_AND:
-            if (destObj->xrgn) XDestroyRegion( destObj->xrgn );
-	    destObj->xrgn = 0;
-	    GDI_HEAP_UNLOCK( hDest );
 	    GDI_HEAP_UNLOCK( hSrc1 );
-	    GDI_HEAP_UNLOCK( hSrc2 );
-	    return NULLREGION;
-        case RGN_OR:
-        case RGN_XOR:
-            if (src1Obj->xrgn)
-                result = REGION_CopyRegion( src1Obj, destObj );
-            else
-                result = REGION_CopyRegion( src2Obj, destObj );
-	    GDI_HEAP_UNLOCK( hDest );
-	    GDI_HEAP_UNLOCK( hSrc1 );
-	    GDI_HEAP_UNLOCK( hSrc2 );
-	    return result;
-	default:
-	    GDI_HEAP_UNLOCK( hDest );
-	    GDI_HEAP_UNLOCK( hSrc1 );
-	    GDI_HEAP_UNLOCK( hSrc2 );
-	    return ERROR;
-        }
-    }
-
-      /* Perform the operation with the two X regions */
-
-    if (!(destrgn = XCreateRegion()))
-    {
-      GDI_HEAP_UNLOCK( hDest );
-      GDI_HEAP_UNLOCK( hSrc1 );
-      GDI_HEAP_UNLOCK( hSrc2 );
-      return ERROR;
-    }
-    switch(mode)
-    {
-    case RGN_AND:
-        XIntersectRegion( src1Obj->xrgn, src2Obj->xrgn, destrgn );
-        break;
-    case RGN_OR:
-        XUnionRegion( src1Obj->xrgn, src2Obj->xrgn, destrgn );
-        break;
-    case RGN_XOR:
-        XXorRegion( src1Obj->xrgn, src2Obj->xrgn, destrgn );
-        break;
-    case RGN_DIFF:
-        XSubtractRegion( src1Obj->xrgn, src2Obj->xrgn, destrgn );
-        break;
-    default:
-        XDestroyRegion( destrgn );
+	}
 	GDI_HEAP_UNLOCK( hDest );
-	GDI_HEAP_UNLOCK( hSrc1 );
-	GDI_HEAP_UNLOCK( hSrc2 );
-        return ERROR;
     }
-    if (destObj->xrgn) XDestroyRegion( destObj->xrgn );
-    destObj->xrgn = destrgn;
-    if (XEmptyRegion(destObj->xrgn))
-    {
-        XDestroyRegion( destObj->xrgn );
-        destObj->xrgn = 0;
-	GDI_HEAP_UNLOCK( hDest );
-	GDI_HEAP_UNLOCK( hSrc1 );
-	GDI_HEAP_UNLOCK( hSrc2 );
-        return NULLREGION;
-    }
-    GDI_HEAP_UNLOCK( hDest );
-    GDI_HEAP_UNLOCK( hSrc1 );
-    GDI_HEAP_UNLOCK( hSrc2 );
-    return COMPLEXREGION;
+    return result;
 }
+
diff --git a/objects/text.c b/objects/text.c
index 7e66e56..aab82fa 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -13,7 +13,6 @@
 #include "stddebug.h"
 /* #define DEBUG_TEXT */
 #include "debug.h"
-#include "xmalloc.h"
 
 #define TAB     9
 #define LF     10
@@ -60,8 +59,11 @@
 	case LF:
 	    if (!(format & DT_SINGLELINE))
 	    {
-		if (str[i] == CR && str[i+1] == LF)
-		    i++;
+		if ((*count > 1) && (str[i] == CR) && (str[i+1] == LF))
+                {
+		    (*count)--;
+                    i++;
+                }
 		i++;
 		*len = j;
 		(*count)--;
@@ -348,12 +350,14 @@
     BOOL32	ret;
     int		i;
     RECT32	rect32;
-    LPINT32	lpdx32 = lpDx?(LPINT32)xmalloc(sizeof(INT32)*count):NULL;
+    LPINT32	lpdx32 = NULL;
 
+    if (lpDx) lpdx32 = (LPINT32)HEAP_xalloc( GetProcessHeap(), 0,
+                                             sizeof(INT32)*count );
     if (lprect)	CONV_RECT16TO32(lprect,&rect32);
     if (lpdx32)	for (i=count;i--;) lpdx32[i]=lpDx[i];
     ret = ExtTextOut32A(hdc,x,y,flags,lprect?&rect32:NULL,str,count,lpdx32);
-    if (lpdx32) free(lpdx32);
+    if (lpdx32) HeapFree( GetProcessHeap(), 0, lpdx32 );
     return ret;
 
 
diff --git a/scheduler/thread.c b/scheduler/thread.c
index 990eb76..91131b5 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -131,6 +131,14 @@
 
     /* Free the associated memory */
 
+#ifdef __i386__
+    {
+        /* Check if we are deleting the current thread */
+        WORD fs;
+        __asm__("movw %%fs,%w0":"=r" (fs));
+        if (fs == thdb->teb_sel) __asm__ __volatile__("pushw %ds\n\tpopw %fs");
+    }
+#endif
     SELECTOR_FreeBlock( thdb->teb_sel, 1 );
     HeapFree( SystemHeap, 0, thdb );
 
@@ -330,7 +338,7 @@
  */
 BOOL32 WINAPI GetThreadContext( HANDLE32 handle, CONTEXT *context )
 {
-    THDB *thread = (THDB*)PROCESS_GetObjPtr( handle, K32OBJ_THREAD );
+    THDB *thread = THREAD_GetPtr( handle );
     if (!thread) return FALSE;
     *context = thread->context;
     K32OBJ_DecCount( &thread->header );
diff --git a/tools/build.c b/tools/build.c
index 06f6af2..253bb45 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -1,7 +1,7 @@
 /*
  * Copyright 1993 Robert J. Amstadt
  * Copyright 1995 Martin von Loewis
- * Copyright 1995, 1996 Alexandre Julliard
+ * Copyright 1995, 1996, 1997 Alexandre Julliard
  * Copyright 1997 Eric Youngdale
  */
 
@@ -393,6 +393,8 @@
             odp->u.func.arg_types[i] = 'p';
 	else if (!strcmp(token, "str"))
 	    odp->u.func.arg_types[i] = 't';
+	else if (!strcmp(token, "wstr"))
+	    odp->u.func.arg_types[i] = 'W';
 	else if (!strcmp(token, "segstr"))
 	    odp->u.func.arg_types[i] = 'T';
         else if (!strcmp(token, "double"))
@@ -410,6 +412,8 @@
         {
             if (strcmp(token, "long") &&
                 strcmp(token, "ptr") &&
+                strcmp(token, "str") &&
+                strcmp(token, "wstr") &&
                 strcmp(token, "double"))
             {
                 fprintf( stderr, "%s:%d: Type '%s' not supported for Win32\n",
@@ -1068,6 +1072,21 @@
             fprintf( outfile, "\t.long Name_%d\n", i );
     }
 
+    /* Output the DLL argument types */
+
+    fprintf( outfile, "ArgTypes:\n" );
+    for (i = Base, odp = OrdinalDefinitions + Base; i <= Limit; i++, odp++)
+    {
+    	unsigned int j, mask = 0;
+	if ((odp->type == TYPE_STDCALL) || (odp->type == TYPE_CDECL))
+	    for (j = 0; odp->u.func.arg_types[j]; j++)
+            {
+                if (odp->u.func.arg_types[j] == 't') mask |= 1<< (j*2);
+                if (odp->u.func.arg_types[j] == 'W') mask |= 2<< (j*2);
+	    }
+	fprintf( outfile, "\t.long %ld\n",mask);
+    }
+
     /* Output the DLL ordinals table */
 
     fprintf( outfile, "FuncOrdinals:\n" );
@@ -1125,6 +1144,7 @@
     fprintf( outfile, "\t.long FuncNames\n" );        /* Function names */
     fprintf( outfile, "\t.long FuncOrdinals\n" );     /* Function ordinals */
     fprintf( outfile, "\t.long FuncArgs\n" );         /* Function arguments */
+    fprintf( outfile, "\t.long ArgTypes\n" );         /* Function argtypes */
 #ifdef USE_STABS
     fprintf( outfile, "\t.text\n");
     fprintf( outfile, "\t.stabs \"\",100,0,0,.Letext\n");
@@ -1620,7 +1640,7 @@
             /* Push again the address of the context struct in case */
             /* it has been removed by an stdcall function */
             fprintf( outfile, "\tleal -%d(%%ebp),%%esp\n",
-                     sizeof(CONTEXT) + 32 );
+                     sizeof(CONTEXT) + STRUCTOFFSET(STACK32FRAME,ebp) );
             fprintf( outfile, "\tpushl %%esp\n" );
         }
         fprintf( outfile, "\tpushl %%eax\n" );
@@ -1728,7 +1748,7 @@
  * Prototypes for the CallTo16 functions:
  *   extern WINAPI WORD CallTo16_word_xxx( FARPROC16 func, args... );
  *   extern WINAPI LONG CallTo16_long_xxx( FARPROC16 func, args... );
- *   extern WINAPI void CallTo16_regs_( const CONTEXT *context );
+ *   extern WINAPI void CallTo16_regs_{short,long}( const CONTEXT *context );
  */
 static void BuildCallTo16Func( FILE *outfile, char *profile )
 {
@@ -1740,8 +1760,8 @@
     else if (!strncmp( "regs_", profile, 5 )) reg_func = 1;
     else if (strncmp( "long_", profile, 5 ))
     {
-        fprintf( stderr, "Invalid function name '%s', ignored\n", profile );
-        return;
+        fprintf( stderr, "Invalid function name '%s'.\n", profile );
+        exit(1);
     }
 
     /* Function header */
@@ -1833,9 +1853,19 @@
         fprintf( outfile, "\tmovl %d(%%ebx),%%esi\n", CONTEXTOFFSET(Esi) );
         fprintf( outfile, "\tmovl %d(%%ebx),%%edi\n", CONTEXTOFFSET(Edi) );
 
-        /* Push the return address */
-
-        fprintf( outfile, "\tpushl " PREFIX "CALLTO16_RetAddr_regs\n" );
+        /* Push the return address 
+	 * With _short suffix, we push 16:16 address (normal lret)
+	 * With _long suffix, we push 16:32 address (0x66 lret, for KERNEL32_45)
+	 */
+	if (!strncmp(profile,"regs_short",10))
+	    fprintf( outfile, "\tpushl " PREFIX "CALLTO16_RetAddr_regs\n" );
+	else 
+	{
+	    fprintf( outfile, "\tpushw $0\n" );
+	    fprintf( outfile, "\tpushw " PREFIX "CALLTO16_RetAddr_regs+2\n" );
+	    fprintf( outfile, "\tpushw $0\n" );
+	    fprintf( outfile, "\tpushw " PREFIX "CALLTO16_RetAddr_regs\n" );
+	}
 
         /* Push the called routine address */
 
@@ -2233,7 +2263,18 @@
 static int BuildCallTo16( FILE *outfile, char * outname, int argc, char *argv[] )
 {
     char buffer[1024];
-    int i;
+    FILE *infile;
+
+    if (argc > 2)
+    {
+        infile = fopen( argv[2], "r" );
+        if (!infile)
+        {
+            perror( argv[2] );
+            exit( 1 );
+        }
+    }
+    else infile = stdin;
 
     /* File header */
 
@@ -2260,7 +2301,23 @@
 
     /* Build the callback functions */
 
-    for (i = 2; i < argc; i++) BuildCallTo16Func( outfile, argv[i] );
+    while (fgets( buffer, sizeof(buffer), infile ))
+    {
+        if (strstr( buffer, "### start build ###" )) break;
+    }
+    while (fgets( buffer, sizeof(buffer), infile ))
+    {
+        char *p = strstr( buffer, "CallTo16_" );
+        if (p)
+        {
+            char *profile = p + strlen( "CallTo16_" );
+            p = profile;
+            while ((*p == '_') || isalpha(*p)) p++;
+            *p = '\0';
+            BuildCallTo16Func( outfile, profile );
+        }
+        if (strstr( buffer, "### stop build ###" )) break;
+    }
 
     /* Output the 16-bit return code */
 
@@ -2275,6 +2332,7 @@
     fprintf( outfile, ".Letext:\n");
 #endif
 
+    fclose( infile );
     return 0;
 }
 
diff --git a/win32/console.c b/win32/console.c
index 872ac73..d10a1ca 100644
--- a/win32/console.c
+++ b/win32/console.c
@@ -10,7 +10,6 @@
 #include "winerror.h"
 #include "wincon.h"
 #include "heap.h"
-#include "xmalloc.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -124,14 +123,10 @@
                                LPDWORD lpNumberOfCharsWritten,
                                LPVOID lpReserved )
 {
-	LPSTR	buf = (LPSTR)xmalloc(nNumberOfCharsToWrite+1);
-
-	lstrcpyn32A(buf,lpBuffer,nNumberOfCharsToWrite);
-	buf[nNumberOfCharsToWrite]=0;
-	fprintf(stderr,"%s",buf);
-	free(buf);
-	*lpNumberOfCharsWritten=nNumberOfCharsToWrite;
-	return TRUE;
+    *lpNumberOfCharsWritten = fprintf( stderr, "%.*s",
+                                       (int)nNumberOfCharsToWrite,
+                                       (LPSTR)lpBuffer );
+    return TRUE;
 }
 
 /***********************************************************************
@@ -143,14 +138,11 @@
                                LPDWORD lpNumberOfCharsWritten,
                                LPVOID lpReserved )
 {
-	LPSTR	buf = (LPSTR)xmalloc(2*nNumberOfCharsToWrite+1);
-
-	lstrcpynWtoA(buf,lpBuffer,nNumberOfCharsToWrite);
-	buf[nNumberOfCharsToWrite]=0;
-	fprintf(stderr,"%s",buf);
-	free(buf);
-	*lpNumberOfCharsWritten=nNumberOfCharsToWrite;
-	return TRUE;
+    LPSTR buf =  HEAP_strdupWtoA( GetProcessHeap(), 0, lpBuffer );
+    *lpNumberOfCharsWritten = fprintf( stderr, "%.*s",
+                                       (int)nNumberOfCharsToWrite, buf );
+    HeapFree( GetProcessHeap(), 0, buf );
+    return TRUE;
 }
 
 /***********************************************************************
@@ -176,12 +168,12 @@
                               LPDWORD lpNumberOfCharsRead,
                               LPVOID lpReserved )
 {
-	LPSTR	buf = (LPSTR)xmalloc(nNumberOfCharsToRead);
-
-	fgets(buf,nNumberOfCharsToRead,stdin);
-	lstrcpynAtoW(lpBuffer,buf,nNumberOfCharsToRead);
-	*lpNumberOfCharsRead = strlen(buf);
-	return TRUE;
+    LPSTR buf = (LPSTR)HEAP_xalloc( GetProcessHeap(), 0, nNumberOfCharsToRead);
+    fgets(buf,nNumberOfCharsToRead,stdin);
+    lstrcpynAtoW(lpBuffer,buf,nNumberOfCharsToRead);
+    *lpNumberOfCharsRead = strlen(buf);
+    HeapFree( GetProcessHeap(), 0, buf );
+    return TRUE;
 }
 
 /***********************************************************************
diff --git a/win32/file.c b/win32/file.c
index 23cfecc..a0d9ab9 100644
--- a/win32/file.c
+++ b/win32/file.c
@@ -20,7 +20,6 @@
 #include "file.h"
 #include "heap.h"
 #include "handle32.h"
-#include "xmalloc.h"
 #include "stddebug.h"
 #define DEBUG_WIN32
 #include "debug.h"
@@ -68,6 +67,29 @@
 }
 
 
+/***********************************************************************
+ *              ReadFileEx                (KERNEL32.)
+ */
+typedef /* from winbase.h */
+VOID
+(WINAPI *LPOVERLAPPED_COMPLETION_ROUTINE)(
+    DWORD dwErrorCode,
+    DWORD dwNumberOfBytesTransfered,
+    LPOVERLAPPED lpOverlapped
+    );
+
+BOOL32 WINAPI ReadFileEx(HFILE32 hFile, LPVOID lpBuffer, DWORD numtoread,
+			 LPOVERLAPPED lpOverlapped, 
+			 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
+{
+
+    fprintf(stdnimp,"ReadFileEx file %d to buf %p num %ld %p func %p stub\n",
+	    hFile, lpBuffer, numtoread, lpOverlapped, lpCompletionRoutine);
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return 0;
+}
+
+
 /*************************************************************************
  *              CreateFile32A              (KERNEL32.45)
  *
@@ -200,6 +222,12 @@
         return FALSE;
 
     dprintf_file(stddeb,"SetFileAttributes(%s,%lx)\n",lpFileName,attributes);
+    if (attributes & FILE_ATTRIBUTE_NORMAL) {
+      attributes &= ~FILE_ATTRIBUTE_NORMAL;
+      if (attributes)
+        fprintf(stdnimp,"SetFileAttributesA(%s):%lx illegal combination with FILE_ATTRIBUTE_NORMAL.\n",
+		lpFileName,attributes);
+    }
     if(stat(full_name.long_name,&buf)==-1)
     {
         SetLastError(ErrnoToLastError(errno));
diff --git a/win32/init.c b/win32/init.c
index ed836ed..0e19a1e 100644
--- a/win32/init.c
+++ b/win32/init.c
@@ -16,7 +16,6 @@
 #include "task.h"
 #include "stddebug.h"
 #include "debug.h"
-#include "xmalloc.h"
   
 /***********************************************************************
  *              GetStartupInfoA         (KERNEL32.273)
@@ -68,16 +67,12 @@
  */
 BOOL32 WINAPI GetComputerName32W(LPWSTR name,LPDWORD size)
 {
-	LPSTR	nameA = (LPSTR)xmalloc(*size);
-
-	if (!GetComputerName32A(nameA,size)) {
-		free(nameA);
-		return FALSE;
-	}
-	lstrcpynAtoW(name,nameA,*size);
-	free(nameA);
-	/* FIXME : size correct? */
-	return TRUE;
+    LPSTR nameA = (LPSTR)HeapAlloc( GetProcessHeap(), 0, *size);
+    BOOL32 ret = GetComputerName32A(nameA,size);
+    if (ret) lstrcpynAtoW(name,nameA,*size);
+    HeapFree( GetProcessHeap(), 0, nameA );
+    /* FIXME : size correct? */
+    return ret;
 }
 
 /***********************************************************************
@@ -104,10 +99,11 @@
  */
 BOOL32 WINAPI GetUserName32W(LPWSTR lpszName, LPDWORD lpSize)
 {
-	LPSTR name = (LPSTR)xmalloc(*lpSize);
+	LPSTR name = (LPSTR)HeapAlloc( GetProcessHeap(), 0, *lpSize );
 	DWORD	size = *lpSize;
 	BOOL32 res = GetUserName32A(name,lpSize);
 
 	lstrcpynAtoW(lpszName,name,size);
+        HeapFree( GetProcessHeap(), 0, name );
 	return res;
 }
diff --git a/win32/security.c b/win32/security.c
index 62c6bd2..d808cd7 100644
--- a/win32/security.c
+++ b/win32/security.c
@@ -4,7 +4,6 @@
 
 #include "windows.h"
 #include "ntdll.h"
-#include "xmalloc.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -82,7 +81,9 @@
     DWORD nSubAuthority6, DWORD nSubAuthority7,
     LPSID *pSid) {
 
-    *pSid = xmalloc(GetSidLengthRequired(nSubAuthorityCount));
+    if (!(*pSid = HeapAlloc( GetProcessHeap(), 0,
+                             GetSidLengthRequired(nSubAuthorityCount))))
+        return FALSE;
     (*pSid)->Revision = SID_REVISION;
     if (pIdentifierAuthority)
         memcpy(&(*pSid)->IdentifierAuthority, pIdentifierAuthority,
@@ -112,8 +113,9 @@
 /***********************************************************************
  *           FreeSid  (ADVAPI.42)
  */
-VOID* WINAPI FreeSid(LPSID pSid) {
-    free(pSid);
+VOID* WINAPI FreeSid(LPSID pSid)
+{
+    HeapFree( GetProcessHeap(), 0, pSid );
     return NULL;
 }
 
diff --git a/win32/thread.c b/win32/thread.c
index 4d4da74..e33755a 100644
--- a/win32/thread.c
+++ b/win32/thread.c
@@ -15,7 +15,6 @@
 #include "winerror.h"
 #include "stddebug.h"
 #include "debug.h"
-#include "xmalloc.h"
 
 
 /*
diff --git a/windows/dce.c b/windows/dce.c
index d54654c..8576190 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -2,7 +2,7 @@
  * USER DCE functions
  *
  * Copyright 1993 Alexandre Julliard
- *	     1996 Alex Korobka
+ *	     1996,1997 Alex Korobka
  *
  *
  * Note: Visible regions of CS_OWNDC/CS_CLASSDC window DCs 
@@ -10,15 +10,18 @@
  * 
  * Internal DCX flags:
  *
- * DCX_DCEBUSY     - dce structure is in use
- * DCX_KEEPCLIPRGN - do not delete clipping region in ReleaseDC
+ * DCX_DCEEMPTY    - dce is uninitialized
+ * DCX_DCEBUSY     - dce is in use
+ * DCX_KEEPCLIPRGN - ReleaseDC should preserve the clipping region
  * DCX_WINDOWPAINT - BeginPaint specific flag
  */
 
+#include "options.h"
 #include "dce.h"
 #include "class.h"
 #include "win.h"
 #include "gdi.h"
+#include "region.h"
 #include "heap.h"
 #include "sysmetrics.h"
 #include "stddebug.h"
@@ -30,9 +33,30 @@
 static DCE *firstDCE = 0;
 static HDC32 defaultDCstate = 0;
 
+static void DCE_DeleteClipRgn( DCE* );
+static INT32 DCE_ReleaseDC( DCE* );
+
+
+/***********************************************************************
+ *           DCE_DumpCache
+ */
+static void DCE_DumpCache()
+{
+    DCE* dce = firstDCE;
+    
+    printf("DCE:\n");
+    while( dce )
+    {
+	printf("\t[0x%08x] hWnd 0x%04x, dcx %08x, %s %s\n",
+	(unsigned)dce, dce->hwndCurrent, (unsigned)dce->DCXflags, (dce->DCXflags & DCX_CACHE) ?
+	"Cache" : "Owned", (dce->DCXflags & DCX_DCEBUSY) ? "InUse" : "" );
+	dce = dce->next;
+    }
+}
+
 /***********************************************************************
  *           DCE_AllocDCE
-*
+ *
  * Allocate a new DCE.
  */
 DCE *DCE_AllocDCE( HWND32 hWnd, DCE_TYPE type )
@@ -54,19 +78,19 @@
     dce->next        = firstDCE;
     firstDCE = dce;
 
-    if( type != DCE_CACHE_DC )
-      {
+    if( type != DCE_CACHE_DC ) /* owned or class DC */
+    {
 	dce->DCXflags = DCX_DCEBUSY;
 	if( hWnd )
-	  {
+	{
 	    WND* wnd = WIN_FindWndPtr(hWnd);
 	
 	    if( wnd->dwStyle & WS_CLIPCHILDREN ) dce->DCXflags |= DCX_CLIPCHILDREN;
 	    if( wnd->dwStyle & WS_CLIPSIBLINGS ) dce->DCXflags |= DCX_CLIPSIBLINGS;
-	  }
+	}
 	SetHookFlags(dce->hDC,DCHF_INVALIDATEVISRGN);
-      }
-    else dce->DCXflags = DCX_CACHE;
+    }
+    else dce->DCXflags = DCX_CACHE | DCX_DCEEMPTY;
 
     return dce;
 }
@@ -75,11 +99,11 @@
 /***********************************************************************
  *           DCE_FreeDCE
  */
-void DCE_FreeDCE( DCE *dce )
+DCE* DCE_FreeDCE( DCE *dce )
 {
     DCE **ppDCE = &firstDCE;
 
-    if (!dce) return;
+    if (!dce) return NULL;
     while (*ppDCE && (*ppDCE != dce)) ppDCE = &(*ppDCE)->next;
     if (*ppDCE == dce) *ppDCE = dce->next;
 
@@ -89,81 +113,176 @@
     if( dce->hClipRgn && !(dce->DCXflags & DCX_KEEPCLIPRGN) )
 	DeleteObject32(dce->hClipRgn);
     HeapFree( SystemHeap, 0, dce );
+    return *ppDCE;
+}
+
+/***********************************************************************
+ *           DCE_FreeWindowDCE
+ *
+ * Remove owned DCE and reset unreleased cache DCEs.
+ */
+void DCE_FreeWindowDCE( WND* pWnd )
+{
+    DCE *pDCE = firstDCE;
+
+    while( pDCE )
+    {
+	if( pDCE->hwndCurrent == pWnd->hwndSelf )
+	{
+	    if( pDCE == pWnd->dce ) /* owned DCE */
+	    {
+		pDCE = DCE_FreeDCE( pDCE );
+		pWnd->dce = NULL;
+		continue;
+	    }
+	    else
+	    {
+		if(!(pDCE->DCXflags & DCX_CACHE) ) /* class DCE */
+		{
+		    if( pDCE->DCXflags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN) )
+			DCE_DeleteClipRgn( pDCE );
+		}
+		else if( pDCE->DCXflags & DCX_DCEBUSY ) /* shared cache DCE */
+		{
+		    fprintf(stderr,"[%04x] GetDC() without ReleaseDC()!\n", pWnd->hwndSelf);
+		    DCE_ReleaseDC( pDCE );
+		}
+
+		pDCE->DCXflags &= DCX_CACHE;
+		pDCE->DCXflags |= DCX_DCEEMPTY;
+		pDCE->hwndCurrent = 0;
+	    }
+	}
+	pDCE = pDCE->next;
+    }
 }
 
 
-/**********************************************************************
- *          WindowFromDC16   (USER32.580)
+/***********************************************************************
+ *   DCE_DeleteClipRgn
  */
-HWND16 WINAPI WindowFromDC16( HDC16 hDC )
+static void DCE_DeleteClipRgn( DCE* dce )
 {
-    return (HWND16)WindowFromDC32( hDC );
+    dce->DCXflags &= ~(DCX_EXCLUDERGN | DCX_INTERSECTRGN | DCX_WINDOWPAINT);
+
+    if( dce->DCXflags & DCX_KEEPCLIPRGN )
+	dce->DCXflags &= ~DCX_KEEPCLIPRGN;
+    else
+	if( dce->hClipRgn > 1 )
+	    DeleteObject32( dce->hClipRgn );
+
+    dce->hClipRgn = 0;
+    RestoreVisRgn(dce->hDC);
 }
 
 
-/**********************************************************************
- *          WindowFromDC32   (USER32.580)
+/***********************************************************************
+ *   DCE_ReleaseDC
  */
-HWND32 WINAPI WindowFromDC32( HDC32 hDC )
+static INT32 DCE_ReleaseDC( DCE* dce )
 {
-    DCE *dce = firstDCE;
-    while (dce && (dce->hDC != hDC)) dce = dce->next;
-    return dce ? dce->hwndCurrent : 0;
+    if ((dce->DCXflags & (DCX_DCEEMPTY | DCX_DCEBUSY)) != DCX_DCEBUSY) return 0;
+
+    /* restore previous visible region */
+
+    if ((dce->DCXflags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) &&
+        (dce->DCXflags & (DCX_CACHE | DCX_WINDOWPAINT)) )
+        DCE_DeleteClipRgn( dce );
+
+    if (dce->DCXflags & DCX_CACHE)
+    {
+        SetDCState( dce->hDC, defaultDCstate );
+        dce->DCXflags &= ~DCX_DCEBUSY;	/* but without DCX_DCEEMPTY */
+    }
+    return 1;
 }
 
 
 /***********************************************************************
  *   DCE_InvalidateDCE
  *
- * It is called from SetWindowPos - we have to invalidate all busy
- * DCE's for windows whose client rect intersects with update rectangle 
+ * It is called from SetWindowPos() - we have to mark as dirty all busy
+ * DCE's for windows whose client rect intersects with specified update 
+ * rectangle. wndScope is the immediate parent of the window(s) that 
+ * was(were) moved and(or) resized.
  */
 BOOL32 DCE_InvalidateDCE(WND* wndScope, RECT32* pRectUpdate)
 {
     BOOL32 bRet = FALSE;
-    DCE *dce;
 
- if( !wndScope ) return 0;
+    if( wndScope )
+    {
+	DCE *dce;
 
- dprintf_dc(stddeb,"InvalidateDCE: scope hwnd = %04x, (%i,%i - %i,%i)\n",
-                    wndScope->hwndSelf, pRectUpdate->left,pRectUpdate->top,
+	dprintf_dc(stddeb,"InvalidateDCE: scope hwnd = %04x, (%i,%i - %i,%i)\n",
+                         wndScope->hwndSelf, pRectUpdate->left,pRectUpdate->top,
 				        pRectUpdate->right,pRectUpdate->bottom);
- /* walk all DCE's */
+	if( debugging_dc ) DCE_DumpCache();
 
- for (dce = firstDCE; (dce); dce = dce->next)
-  { 
-    if( dce->DCXflags & DCX_DCEBUSY )
-      {
-        WND * wndCurrent, * wnd; 
+	if( !Options.desktopGeometry && wndScope == WIN_GetDesktop() ) return TRUE;
 
-	wnd = wndCurrent = WIN_FindWndPtr(dce->hwndCurrent);
+ 	/* walk all DCEs and fixup non-empty entries */
 
-	/* desktop is not critical (DC is not owned anyway) */
+	for (dce = firstDCE; (dce); dce = dce->next)
+	{
+	    if( !(dce->DCXflags & DCX_DCEEMPTY) )
+	    {
+		WND* wndCurrent = WIN_FindWndPtr(dce->hwndCurrent);
 
-	if( wnd == WIN_GetDesktop() ) continue; 
+		if( wndCurrent && wndCurrent != WIN_GetDesktop() )
+		{
+		    WND* wnd = wndCurrent;
+		    INT32 xoffset = 0, yoffset = 0;
 
-	/* check if DCE window is within z-order scope */
+		    if( (wndCurrent == wndScope) && !(dce->DCXflags & DCX_CLIPCHILDREN) )
+			continue;
 
-	for( ; wnd ; wnd = wnd->parent )
-	    if( wnd == wndScope )
-	      { 
-	        RECT32 wndRect = wndCurrent->rectWindow;
+		    /* check if DCE window is within the z-order scope */
 
-	        dprintf_dc(stddeb,"\tgot hwnd %04x\n", wndCurrent->hwndSelf);
-  
-	        MapWindowPoints32( wndCurrent->parent->hwndSelf,
-                                   wndScope->hwndSelf,
-                                   (LPPOINT32)&wndRect, 2 );
-	        if (IntersectRect32( &wndRect, &wndRect, pRectUpdate ))
-	        {    
-		   SetHookFlags(dce->hDC, DCHF_INVALIDATEVISRGN);
-		   bRet = TRUE;
+		    for( wnd = wndCurrent; wnd; wnd = wnd->parent )
+		    {
+			if( wnd == wndScope )
+		 	{
+			    RECT32 wndRect;
+
+			    wndRect = wndCurrent->rectWindow;
+
+			    OffsetRect32( &wndRect, xoffset - wndCurrent->rectClient.left, 
+						    yoffset - wndCurrent->rectClient.top);
+			    if (IntersectRect32( &wndRect, &wndRect, pRectUpdate ))
+			    { 
+				if( !(dce->DCXflags & DCX_DCEBUSY) )
+				{
+				    /* Don't bother with visible regions of unused DCEs */
+
+				    dprintf_dc(stddeb,"\tpurged %08x dce [%04x]\n", 
+						(unsigned)dce, wndCurrent->hwndSelf);
+
+				    dce->hwndCurrent = 0;
+				    dce->DCXflags &= DCX_CACHE;
+				    dce->DCXflags |= DCX_DCEEMPTY;
+				}
+				else
+				{
+				    /* Set dirty bit in the hDC */
+
+				    dprintf_dc(stddeb,"\tfixed up %08x dce [%04x]\n", 
+						(unsigned)dce, wndCurrent->hwndSelf);
+
+				    SetHookFlags(dce->hDC, DCHF_INVALIDATEVISRGN);
+				    bRet = TRUE;
+				}
+			    }
+			    break;
+			}
+			xoffset += wnd->rectClient.left;
+			yoffset += wnd->rectClient.top;
+		    }
 		}
-	        break;
-	      }
-      }
-  }
- return bRet;
+	    }
+	} /* dce list */
+    }
+    return bRet;
 }
 
 /***********************************************************************
@@ -185,87 +304,83 @@
 /***********************************************************************
  *           DCE_GetVisRect
  *
- * Calc the visible rectangle of a window, i.e. the client or
- * window area clipped by the client area of all ancestors.
- * Return FALSE if the visible region is empty.
+ * Calculate the visible rectangle of a window (i.e. the client or
+ * window area clipped by the client area of all ancestors) in the
+ * corresponding coordinates. Return FALSE if the visible region is empty.
  */
 static BOOL32 DCE_GetVisRect( WND *wndPtr, BOOL32 clientArea, RECT32 *lprect )
 {
-    int xoffset, yoffset;
-
     *lprect = clientArea ? wndPtr->rectClient : wndPtr->rectWindow;
-    xoffset = lprect->left;
-    yoffset = lprect->top;
 
-    if (!(wndPtr->dwStyle & WS_VISIBLE) || (wndPtr->flags & WIN_NO_REDRAW))
+    if ((wndPtr->dwStyle & WS_VISIBLE) && !(wndPtr->flags & WIN_NO_REDRAW))
     {
-        SetRectEmpty32( lprect );  /* Clip everything */
-        return FALSE;
+	INT32 xoffset = lprect->left;
+	INT32 yoffset = lprect->top;
+
+	while (wndPtr->parent)
+	{
+	    wndPtr = wndPtr->parent;
+
+	    if ((wndPtr->flags & WIN_NO_REDRAW) ||
+		(wndPtr->dwStyle & (WS_ICONIC | WS_VISIBLE)) != WS_VISIBLE )
+		goto fail;
+
+	    xoffset += wndPtr->rectClient.left;
+	    yoffset += wndPtr->rectClient.top;
+	    OffsetRect32( lprect, wndPtr->rectClient.left,
+				  wndPtr->rectClient.top );
+
+	    if( (wndPtr->rectClient.left >= wndPtr->rectClient.right) ||
+		(wndPtr->rectClient.top >= wndPtr->rectClient.bottom) ||
+		(lprect->left >= wndPtr->rectClient.right) ||
+		(lprect->right <= wndPtr->rectClient.left) ||
+		(lprect->top >= wndPtr->rectClient.bottom) ||
+		(lprect->bottom <= wndPtr->rectClient.top) )
+		goto fail;
+
+	    lprect->left = MAX( lprect->left, wndPtr->rectClient.left );
+	    lprect->right = MIN( lprect->right, wndPtr->rectClient.right );
+	    lprect->top = MAX( lprect->top, wndPtr->rectClient.top );
+	    lprect->bottom = MIN( lprect->bottom, wndPtr->rectClient.bottom );
+	}
+	OffsetRect32( lprect, -xoffset, -yoffset );
+	return TRUE;
     }
 
-    while (wndPtr->parent)
-    {
-        wndPtr = wndPtr->parent;
-        if (!(wndPtr->dwStyle & WS_VISIBLE) ||
-            (wndPtr->flags & WIN_NO_REDRAW) ||
-            (wndPtr->dwStyle & WS_ICONIC))
-        {
-            SetRectEmpty32( lprect );  /* Clip everything */
-            return FALSE;
-        }
-	xoffset += wndPtr->rectClient.left;
-	yoffset += wndPtr->rectClient.top;
-	OffsetRect32( lprect, wndPtr->rectClient.left,
-                      wndPtr->rectClient.top );
-
-	  /* Warning!! we assume that IntersectRect() handles the case */
-	  /* where the destination is the same as one of the sources.  */
-	if (!IntersectRect32( lprect, lprect, &wndPtr->rectClient ))
-            return FALSE;  /* Visible rectangle is empty */
-    }
-    OffsetRect32( lprect, -xoffset, -yoffset );
-    return TRUE;
+fail:
+    SetRectEmpty32( lprect );
+    return FALSE;
 }
 
 
 /***********************************************************************
- *           DCE_ClipWindows
+ *           DCE_AddClipRects
  *
- * Go through the linked list of windows from hwndStart to hwndEnd,
- * 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. Now it skips managed windows 
- * because we have no idea about decoration size anyway.
+ * Go through the linked list of windows from pWndStart to pWndEnd,
+ * adding to the clip region the intersection of the target rectangle
+ * with an offset window rectangle.
  */
-static HRGN32 DCE_ClipWindows( WND *pWndStart, WND *pWndEnd,
-                               HRGN32 hrgn, int xoffset, int yoffset )
+static BOOL32 DCE_AddClipRects( WND *pWndStart, WND *pWndEnd, 
+			        HRGN32 hrgnClip, LPRECT32 lpRect, int x, int y )
 {
-    HRGN32 hrgnNew;
+    RECT32 rect;
 
-    if ( pWndStart == NULL ) return hrgn;
-    if ( (hrgnNew = CreateRectRgn32( 0, 0, 0, 0 )) )
+    if (pWndStart->window) return TRUE; /* X itself will do the clipping */
+
+    for (; pWndStart != pWndEnd; pWndStart = pWndStart->next)
     {
-	for (; pWndStart != pWndEnd; pWndStart = pWndStart->next)
-	{
-	    if ( !(pWndStart->dwStyle & WS_VISIBLE) ||
-		 (pWndStart->flags & WIN_MANAGED) ) continue;
+	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 );
-    } else pWndEnd = NULL;
+	rect.left = pWndStart->rectWindow.left + x;
+	rect.top = pWndStart->rectWindow.top + y;
+	rect.right = pWndStart->rectWindow.right + x;
+	rect.bottom = pWndStart->rectWindow.bottom + y;
 
-    if (pWndStart != pWndEnd)  /* something went wrong */
-    {
-        DeleteObject32( hrgn );
-        return 0;
+	if( IntersectRect32( &rect, &rect, lpRect ))
+	    if(!REGION_UnionRectWithRgn( hrgnClip, &rect ))
+		break;
     }
-    return hrgn;
+    return (pWndStart == pWndEnd);
 }
 
 
@@ -278,65 +393,87 @@
  */
 HRGN32 DCE_GetVisRgn( HWND32 hwnd, WORD flags )
 {
+    HRGN32 hrgnVis = 0;
     RECT32 rect;
-    HRGN32 hrgn;
-    int xoffset, yoffset;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
-      /* Get visible rectangle and create a region with it. 
-       */
+    /* Get visible rectangle and create a region with it. */
 
-    if (!wndPtr || !DCE_GetVisRect( wndPtr, !(flags & DCX_WINDOW), &rect ))
+    if (wndPtr && DCE_GetVisRect(wndPtr, !(flags & DCX_WINDOW), &rect))
     {
-        return CreateRectRgn32( 0, 0, 0, 0 );  /* Visible region is empty */
-    }
-    if (!(hrgn = CreateRectRgnIndirect32( &rect ))) return 0;
-
-      /* Clip all children from the visible region */
-
-    if (flags & DCX_CLIPCHILDREN)
-    {
-        if (flags & DCX_WINDOW)
+	if((hrgnVis = CreateRectRgnIndirect32( &rect )))
         {
-            xoffset = wndPtr->rectClient.left - wndPtr->rectWindow.left;
-            yoffset = wndPtr->rectClient.top - wndPtr->rectWindow.top;
-        }
-        else xoffset = yoffset = 0;
-        hrgn = DCE_ClipWindows( wndPtr->child, NULL, hrgn, xoffset, yoffset );
-        if (!hrgn) return 0;
-    }
+	    HRGN32 hrgnClip = CreateRectRgn32( 0, 0, 0, 0 );
+	    INT32 xoffset, yoffset;
 
-      /* Clip siblings placed above this window */
+	    if( hrgnClip )
+	    {
+		/* Compute obscured region for the visible rectangle by 
+		 * clipping children, siblings, and ancestors. Note that
+		 * DCE_GetVisRect() returns a rectangle either in client
+		 * or in window coordinates (for DCX_WINDOW request). */
 
-    if (flags & DCX_WINDOW)
-    {
-        xoffset = -wndPtr->rectWindow.left;
-        yoffset = -wndPtr->rectWindow.top;
+		if( (flags & DCX_CLIPCHILDREN) && wndPtr->child )
+		{
+		    if( flags & DCX_WINDOW )
+		    {
+			/* adjust offsets since child window rectangles are 
+			 * in client coordinates */
+
+			xoffset = wndPtr->rectClient.left - wndPtr->rectWindow.left;
+			yoffset = wndPtr->rectClient.top - wndPtr->rectWindow.top;
+		    }
+		    else 
+			xoffset = yoffset = 0;
+
+		    DCE_AddClipRects( wndPtr->child, NULL, hrgnClip, 
+				      &rect, xoffset, yoffset );
+		}
+
+		/* sibling window rectangles are in client 
+		 * coordinates of the parent window */
+
+		if (flags & DCX_WINDOW)
+		{
+		    xoffset = -wndPtr->rectWindow.left;
+		    yoffset = -wndPtr->rectWindow.top;
+		}
+		else
+		{
+		    xoffset = -wndPtr->rectClient.left;
+		    yoffset = -wndPtr->rectClient.top;
+		}
+
+		if (flags & DCX_CLIPSIBLINGS && wndPtr->parent )
+		    DCE_AddClipRects( wndPtr->parent->child,
+				      wndPtr, hrgnClip, &rect, xoffset, yoffset );
+
+		while (wndPtr->dwStyle & WS_CHILD)
+		{
+		    wndPtr = wndPtr->parent;
+		    xoffset -= wndPtr->rectClient.left;
+		    yoffset -= wndPtr->rectClient.top;
+		    DCE_AddClipRects( wndPtr->parent->child, wndPtr,
+					hrgnClip, &rect, xoffset, yoffset );
+		}
+
+		/* Now once we've got a jumbo clip region we have
+		 * to substract it from the visible rectangle.
+	         */
+
+		CombineRgn32( hrgnVis, hrgnVis, hrgnClip, RGN_DIFF );
+		DeleteObject32( hrgnClip );
+	    }
+	    else
+	    {
+		DeleteObject32( hrgnVis );
+		hrgnVis = 0;
+	    }
+	}
     }
     else
-    {
-        xoffset = -wndPtr->rectClient.left;
-        yoffset = -wndPtr->rectClient.top;
-    }
-    if (flags & DCX_CLIPSIBLINGS)
-    {
-        hrgn = DCE_ClipWindows( wndPtr->parent ? wndPtr->parent->child : NULL,
-                                wndPtr, hrgn, xoffset, yoffset );
-        if (!hrgn) return 0;
-    }
-
-      /* Clip siblings of all ancestors that have the WS_CLIPSIBLINGS style */
-
-    while (wndPtr->dwStyle & WS_CHILD)
-    {
-        wndPtr = wndPtr->parent;
-        xoffset -= wndPtr->rectClient.left;
-        yoffset -= wndPtr->rectClient.top;
-        hrgn = DCE_ClipWindows( wndPtr->parent ? wndPtr->parent->child : NULL,
-                                wndPtr, hrgn, xoffset, yoffset );
-        if (!hrgn) return 0;
-    }
-    return hrgn;
+	hrgnVis = CreateRectRgn32(0, 0, 0, 0); /* empty */
+    return hrgnVis;
 }
 
 
@@ -346,7 +483,7 @@
  * Set the drawable, origin and dimensions for the DC associated to
  * a given window.
  */
-static void DCE_SetDrawable( WND *wndPtr, DC *dc, WORD flags )
+static void DCE_SetDrawable( WND *wndPtr, DC *dc, WORD flags, BOOL32 bSetClipOrigin )
 {
     if (!wndPtr)  /* Get a DC for the whole screen */
     {
@@ -376,6 +513,14 @@
         dc->w.DCOrgX -= wndPtr->rectWindow.left;
         dc->w.DCOrgY -= wndPtr->rectWindow.top;
         dc->u.x.drawable = wndPtr->window;
+
+	/* This is needed when we reuse a cached DC because
+	 * SetDCState() called by ReleaseDC() screws up DC
+	 * origins for child windows.
+	 */
+
+	if( bSetClipOrigin )
+	    XSetClipOrigin( display, dc->u.x.gc, dc->w.DCOrgX, dc->w.DCOrgY );
     }
 }
 /***********************************************************************
@@ -427,21 +572,27 @@
  *           GetDCEx32    (USER32.230)
  *
  * Unimplemented flags: DCX_LOCKWINDOWUPDATE
+ *
+ * FIXME: Full support for hrgnClip == 1 (alias for entire window).
  */
 HDC32 WINAPI GetDCEx32( HWND32 hwnd, HRGN32 hrgnClip, DWORD flags )
 {
-    HRGN32 	hrgnVisible;
+    HRGN32 	hrgnVisible = 0;
     HDC32 	hdc = 0;
     DCE * 	dce;
     DC * 	dc;
     WND * 	wndPtr;
-    DWORD 	dcx_flags = 0;
-    BOOL32	need_update = TRUE;
+    DWORD 	dcxFlags = 0;
+    BOOL32	bUpdateVisRgn = TRUE;
+    BOOL32	bUpdateClipOrigin = FALSE;
 
-    dprintf_dc(stddeb,"GetDCEx: hwnd %04x, hrgnClip %04x, flags %08x\n", hwnd, hrgnClip, (unsigned)flags);
+    dprintf_dc(stddeb,"GetDCEx: hwnd %04x, hrgnClip %04x, flags %08x\n", 
+				hwnd, hrgnClip, (unsigned)flags);
     
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
 
+    /* fixup flags */
+
     if (!(wndPtr->class->style & (CS_OWNDC | CS_CLASSDC))) flags |= DCX_CACHE;
 
     if (flags & DCX_USESTYLE)
@@ -467,101 +618,167 @@
         flags &= ~(DCX_PARENTCLIP | DCX_CLIPCHILDREN);
     }
 
-    if (flags & DCX_WINDOW) flags = (flags & ~DCX_CLIPCHILDREN) | DCX_CACHE;
+    if (flags & DCX_WINDOW) 
+	flags = (flags & ~DCX_CLIPCHILDREN) | DCX_CACHE;
 
-    if (!(wndPtr->dwStyle & WS_CHILD) || !wndPtr->parent ) flags &= ~DCX_PARENTCLIP;
+    if (!(wndPtr->dwStyle & WS_CHILD) || !wndPtr->parent ) 
+	flags &= ~DCX_PARENTCLIP;
     else if( flags & DCX_PARENTCLIP )
     {
-        flags |= DCX_CACHE;
-        if( !(flags & (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN)) )
-          if( (wndPtr->dwStyle & WS_VISIBLE) && (wndPtr->parent->dwStyle & WS_VISIBLE) )
-          {
-              flags &= ~DCX_CLIPCHILDREN;
-              if( wndPtr->parent->dwStyle & WS_CLIPSIBLINGS )
-                  flags |= DCX_CLIPSIBLINGS;
-          }
+	flags |= DCX_CACHE;
+	if( !(flags & (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN)) )
+	    if( (wndPtr->dwStyle & WS_VISIBLE) && (wndPtr->parent->dwStyle & WS_VISIBLE) )
+	    {
+		flags &= ~DCX_CLIPCHILDREN;
+		if( wndPtr->parent->dwStyle & WS_CLIPSIBLINGS )
+		    flags |= DCX_CLIPSIBLINGS;
+	    }
     }
 
+    /* find a suitable DCE */
+
+    dcxFlags = flags & (DCX_PARENTCLIP | DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | 
+		        DCX_CACHE | DCX_WINDOW);
+
     if (flags & DCX_CACHE)
     {
+	DCE*	dceEmpty;
+	DCE*	dceUnused;
+
+	dceEmpty = dceUnused = NULL;
+
+	/* Strategy: First, we attempt to find a non-empty but unused DCE with
+	 * compatible flags. Next, we look for an empty entry. If the cache is
+	 * full we have to purge one of the unused entries.
+	 */
+
 	for (dce = firstDCE; (dce); dce = dce->next)
 	{
-	    if ((dce->DCXflags & DCX_CACHE) && !(dce->DCXflags & DCX_DCEBUSY)) break;
+	    if ((dce->DCXflags & (DCX_CACHE | DCX_DCEBUSY)) == DCX_CACHE )
+	    {
+		dceUnused = dce;
+
+		if (dce->DCXflags & DCX_DCEEMPTY)
+		    dceEmpty = dce;
+		else
+		if ((dce->hwndCurrent == hwnd) &&
+		   ((dce->DCXflags & (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN |
+				      DCX_CACHE | DCX_WINDOW | DCX_PARENTCLIP)) == dcxFlags))
+		{
+		    dprintf_dc(stddeb,"\tfound valid %08x dce [%04x]\n", (unsigned)dce, hwnd );
+
+/* Eventually, this won't be commented out but at this time
+ * there are still some problems with DC reuse.
+ * 
+		    bUpdateVisRgn = TRUE; 
+ */
+		    bUpdateClipOrigin = TRUE;
+		    break;
+		}
+	    }
 	}
+	if (!dce) dce = (dceEmpty) ? dceEmpty : dceUnused;
     }
     else 
     {
-        dce = (wndPtr->class->style & CS_OWNDC)?wndPtr->dce:wndPtr->class->dce;
+        dce = (wndPtr->class->style & CS_OWNDC) ? wndPtr->dce : wndPtr->class->dce;
 	if( dce->hwndCurrent == hwnd )
 	{
 	    dprintf_dc(stddeb,"\tskipping hVisRgn update\n");
-	    need_update = FALSE;
-	}
+	    bUpdateVisRgn = FALSE; /* updated automatically, via DCHook() */
 
-	if( hrgnClip && dce->hClipRgn && !(dce->DCXflags & DCX_KEEPCLIPRGN))
-	{
-	    fprintf(stdnimp,"GetDCEx: hClipRgn collision!\n");
-            DeleteObject32( dce->hClipRgn ); 
-	    need_update = TRUE;
+	    if( (dce->DCXflags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN)) &&
+		(flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN)) )
+	    {
+		/* This is likely to be a nested BeginPaint(). */
+
+		if( dce->hClipRgn != hrgnClip )
+		{
+		    fprintf(stdnimp,"GetDCEx: new hrgnClip [%04x] smashes the previous [%04x]!\n",
+				     hrgnClip, dce->hClipRgn );
+		    DCE_DeleteClipRgn( dce );
+		}
+		else 
+		    RestoreVisRgn(dce->hDC);
+	    }
 	}
     }
-
-    dcx_flags = flags & ( DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_CACHE | DCX_WINDOW | DCX_WINDOWPAINT);
-
     if (!dce) return 0;
+
     dce->hwndCurrent = hwnd;
     dce->hClipRgn = 0;
-    dce->DCXflags = dcx_flags | DCX_DCEBUSY;
+    dce->DCXflags = dcxFlags | (flags & DCX_WINDOWPAINT) | DCX_DCEBUSY;
     hdc = dce->hDC;
     
     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
+    bUpdateVisRgn = bUpdateVisRgn || (dc->w.flags & DC_DIRTY);
 
-    DCE_SetDrawable( wndPtr, dc, flags );
-    if( need_update || dc->w.flags & DC_DIRTY )
+    /* recompute visible region */
+
+    DCE_SetDrawable( wndPtr, dc, flags, bUpdateClipOrigin );
+    if( bUpdateVisRgn )
     {
-      dprintf_dc(stddeb,"updating hDC anyway\n");
+	dprintf_dc(stddeb,"updating %08x dce, visrgn [%04x]\n", (unsigned)dce, hwnd);
 
-      if (flags & DCX_PARENTCLIP)
+	if (flags & DCX_PARENTCLIP)
         {
             WND *parentPtr = wndPtr->parent;
-            dcx_flags = flags & ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN |
-                                       DCX_WINDOW);
-            if (parentPtr->dwStyle & WS_CLIPSIBLINGS)
-                dcx_flags |= DCX_CLIPSIBLINGS;
-            hrgnVisible = DCE_GetVisRgn( parentPtr->hwndSelf, dcx_flags );
-            if (flags & DCX_WINDOW)
-                OffsetRgn32( hrgnVisible, -wndPtr->rectWindow.left,
-                                          -wndPtr->rectWindow.top );
-            else OffsetRgn32( hrgnVisible, -wndPtr->rectClient.left,
-                                           -wndPtr->rectClient.top );
+
+	    if( wndPtr->dwStyle & WS_VISIBLE && !(parentPtr->dwStyle & WS_MINIMIZE) )
+	    {
+		if( parentPtr->dwStyle & WS_CLIPSIBLINGS ) 
+		    dcxFlags = DCX_CLIPSIBLINGS | (flags & ~(DCX_CLIPCHILDREN | DCX_WINDOW));
+		else
+		    dcxFlags = flags & ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_WINDOW);
+
+                hrgnVisible = DCE_GetVisRgn( parentPtr->hwndSelf, dcxFlags );
+		if( flags & DCX_WINDOW )
+		    OffsetRgn32( hrgnVisible, -wndPtr->rectWindow.left,
+					      -wndPtr->rectWindow.top );
+		else
+		    OffsetRgn32( hrgnVisible, -wndPtr->rectClient.left,
+					      -wndPtr->rectClient.top );
+	    }
+	    else
+		hrgnVisible = CreateRectRgn32( 0, 0, 0, 0 );
         }
-           /* optimize away GetVisRgn for desktop if it isn't there */
+        else 
+	    if ((hwnd == GetDesktopWindow32()) &&
+                (rootWindow == DefaultRootWindow(display)))
+                 hrgnVisible = CreateRectRgn32( 0, 0, SYSMETRICS_CXSCREEN,
+						      SYSMETRICS_CYSCREEN );
+	    else hrgnVisible = DCE_GetVisRgn( hwnd, flags );
 
-      else if ((hwnd == GetDesktopWindow32()) &&
-               (rootWindow == DefaultRootWindow(display)))
-	       hrgnVisible = CreateRectRgn32( 0, 0, SYSMETRICS_CXSCREEN,
-                                                    SYSMETRICS_CYSCREEN );
-      else hrgnVisible = DCE_GetVisRgn( hwnd, flags );
 
-      if( wndPtr->parent && wndPtr->window )
-      {
-        WND* 	wnd = wndPtr->parent->child;
-	RECT32  rect;
+	if( wndPtr->parent && wndPtr->window )
+	{
+	    /* Problem - X doesn't discard save under buffers when
+	     * the old data is invalidated by the new graphics output.
+	     *
+	     * FIXME: Instead of overriding we should try to discard
+	     *        save_unders by calling XSetWindowAttributes().
+	     *        And we should do it for the child window GetDCEx() 
+	     *	      calls as well. */
+
+            WND*    wnd = wndPtr->parent->child;
+	    RECT32  rect;
 	
-        for( ; wnd != wndPtr; wnd = wnd->next )
-           if( wnd->class->style & CS_SAVEBITS &&
-               wnd->dwStyle & WS_VISIBLE &&
-	       IntersectRect32(&rect, &wndPtr->rectClient, &wnd->rectClient) )
-               wnd->flags |= WIN_SAVEUNDER_OVERRIDE;
-      }
-
-      dc->w.flags &= ~DC_DIRTY;
-      SelectVisRgn( hdc, hrgnVisible );
+	    for( ; wnd != wndPtr; wnd = wnd->next )
+		if( wnd->class->style & CS_SAVEBITS && 
+		    wnd->dwStyle & WS_VISIBLE &&
+		    IntersectRect32(&rect, &wndPtr->rectClient, &wnd->rectClient) )
+                    wnd->flags |= WIN_SAVEUNDER_OVERRIDE;
+	}
+	dc->w.flags &= ~DC_DIRTY;
+	SelectVisRgn( hdc, hrgnVisible );
     }
-    else hrgnVisible = CreateRectRgn32( 0, 0, 0, 0 );
+
+    /* apply additional region operation (if any) */
 
     if( flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN) )
     {
+	if( !hrgnVisible ) hrgnVisible = CreateRectRgn32( 0, 0, 0, 0 );
+
 	dce->DCXflags |= flags & (DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_EXCLUDERGN);
 	dce->hClipRgn = hrgnClip;
 
@@ -572,7 +789,8 @@
                       (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF );
 	SelectVisRgn( hdc, hrgnVisible );
     }
-    DeleteObject32( hrgnVisible );
+
+    if( hrgnVisible ) DeleteObject32( hrgnVisible );
 
     dprintf_dc(stddeb, "GetDCEx(%04x,%04x,0x%lx): returning %04x\n", 
 	       hwnd, hrgnClip, flags, hdc);
@@ -639,34 +857,11 @@
     dprintf_dc(stddeb, "ReleaseDC: %04x %04x\n", hwnd, hdc );
         
     while (dce && (dce->hDC != hdc)) dce = dce->next;
-    if (!dce) return 0;
-    if (!(dce->DCXflags & DCX_DCEBUSY) ) return 0;
 
-    /* restore previous visible region */
-
-    if ( dce->DCXflags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN) &&
-	(dce->DCXflags & DCX_CACHE || dce->DCXflags & DCX_WINDOWPAINT) )
-    {
-	dprintf_dc(stddeb,"\tcleaning up visrgn...\n");
-	dce->DCXflags &= ~(DCX_EXCLUDERGN | DCX_INTERSECTRGN | DCX_WINDOWPAINT);
-
-	if( dce->DCXflags & DCX_KEEPCLIPRGN )
-	    dce->DCXflags &= ~DCX_KEEPCLIPRGN;
-	else
-	    if( dce->hClipRgn > 1 )
-	        DeleteObject32( dce->hClipRgn );
-
-        dce->hClipRgn = 0;
-	RestoreVisRgn(dce->hDC);
-    }
-
-    if (dce->DCXflags & DCX_CACHE)
-    {
-	SetDCState( dce->hDC, defaultDCstate );
-	dce->DCXflags = DCX_CACHE;
-	dce->hwndCurrent = 0;
-    }
-    return 1;
+    if ( dce ) 
+	if ( dce->DCXflags & DCX_DCEBUSY )
+	     return DCE_ReleaseDC( dce );
+    return 0;
 }
 
 /***********************************************************************
@@ -684,12 +879,17 @@
     while (dce && (dce->hDC != hDC)) dce = dce->next;
     if (!dce) return 0;
 
-  switch( code )
+    switch( code )
     {
       case DCHC_INVALIDVISRGN:
-         {
+
+	   /* GDI code calls this when it detects that the
+	    * DC is dirty (usually after SetHookFlags()). This
+	    * means that we have to recompute the visible region.
+	    */
+
            if( dce->DCXflags & DCX_DCEBUSY )
- 	     {
+ 	   {
 	       SetHookFlags(hDC, DCHF_VALIDATEVISRGN);
 	       hVisRgn = DCE_GetVisRgn(dce->hwndCurrent, dce->DCXflags);
 
@@ -699,7 +899,7 @@
 
                if ( (dce->DCXflags & DCX_INTERSECTRGN && dce->hClipRgn != 1) ||
                   (  dce->DCXflags & DCX_EXCLUDERGN && dce->hClipRgn) )
-                  {
+               {
 
                     if( (!dce->hClipRgn && dce->DCXflags & DCX_INTERSECTRGN) ||
                          (dce->hClipRgn == 1 && dce->DCXflags & DCX_EXCLUDERGN) )            
@@ -707,25 +907,44 @@
                     else
                          CombineRgn32(hVisRgn, hVisRgn, dce->hClipRgn, 
                                       (dce->DCXflags & DCX_EXCLUDERGN)? RGN_DIFF:RGN_AND);
-	          }  
+	       }  
 	       SelectVisRgn(hDC, hVisRgn);
 	       DeleteObject32( hVisRgn );
-	     }
-           else
+	   }
+           else /* non-fatal but shouldn't happen */
 	     dprintf_dc(stddeb,"DCHook: DC is not in use!\n");
-         }
-	 break;
+	   break;
 
       case DCHC_DELETEDC: /* FIXME: ?? */
-	 break;
+	   break;
 
       default:
-	 fprintf(stdnimp,"DCHook: unknown code\n");
+	   fprintf(stdnimp,"DCHook: unknown code\n");
     }
   return 0;
 }
 
 
+/**********************************************************************
+ *          WindowFromDC16   (USER32.580)
+ */
+HWND16 WINAPI WindowFromDC16( HDC16 hDC )
+{
+    return (HWND16)WindowFromDC32( hDC );
+}
+
+
+/**********************************************************************
+ *          WindowFromDC32   (USER32.580)
+ */
+HWND32 WINAPI WindowFromDC32( HDC32 hDC )
+{
+    DCE *dce = firstDCE;
+    while (dce && (dce->hDC != hDC)) dce = dce->next;
+    return dce ? dce->hwndCurrent : 0;
+}
+
+
 /***********************************************************************
  *           LockWindowUpdate16   (USER.294)
  */
diff --git a/windows/dialog.c b/windows/dialog.c
index b56f684..b68151e 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -486,14 +486,15 @@
 
       /* Load menu */
 
-    if (template.menuName) {
-	if (!HIWORD(hInst)) /* win32 modules always have hiword set */
+    if (template.menuName)
+    {
+        if (!win32Template)
         {
             LPSTR str = SEGPTR_STRDUP( template.menuName );
 	    hMenu = LoadMenu16( hInst, SEGPTR_GET(str) );
             SEGPTR_FREE( str );
-	} else /* win32 modules always have hiword set */
-	    hMenu = LoadMenu32A( hInst, template.menuName );
+	}
+        else hMenu = LoadMenu32W( hInst, (LPCWSTR)template.menuName );
     }
 
       /* Create custom font if needed */
@@ -503,12 +504,12 @@
           /* The font height must be negative as it is a point size */
           /* (see CreateFont() documentation in the Windows SDK).   */
 	if (win32Template)
-	    hFont = CreateFont16( -template.pointSize, 0, 0, 0, FW_DONTCARE,
+	    hFont = CreateFont32W( -template.pointSize, 0, 0, 0, FW_DONTCARE,
 			    FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
 			    PROOF_QUALITY, FF_DONTCARE,
-                            template.faceName );
+                            (LPCWSTR)template.faceName );
 	else
-	    hFont = CreateFont32W( -template.pointSize, 0, 0, 0, FW_DONTCARE,
+	    hFont = CreateFont16( -template.pointSize, 0, 0, 0, FW_DONTCARE,
 			    FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
 			    PROOF_QUALITY, FF_DONTCARE,
                             template.faceName );
diff --git a/windows/driver.c b/windows/driver.c
index 2b8df27..dbc8531 100644
--- a/windows/driver.c
+++ b/windows/driver.c
@@ -61,8 +61,8 @@
 	return 0;
     }
 
-    retval = CallDriverProc( (FARPROC16)lpdrv->lpDrvProc, 0L /* FIXME */, 
-                             hDriver, msg, lParam1, lParam2 );
+    retval = Callbacks->CallDriverProc( lpdrv->lpDrvProc, 0L /* FIXME */,
+                                        hDriver, msg, lParam1, lParam2 );
 
     dprintf_driver( stddeb, "SendDriverMessage // retval = %ld\n", retval );
 
diff --git a/windows/event.c b/windows/event.c
index cb6dcb8..b54769a 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -34,7 +34,6 @@
 #include "winpos.h"
 #include "drive.h"
 #include "shell.h"
-#include "xmalloc.h"
 #include "keyboard.h"
 #include "stddebug.h"
 #include "debug.h"
@@ -859,7 +858,7 @@
 
 	    /* remove carriage returns */
 
-	    lpstr = (char*)xmalloc(size--);
+	    lpstr = (char*)HEAP_xalloc( GetProcessHeap(), 0, size-- );
 	    for(i=0,j=0; i < size && text[i]; i++ )
 	    {
 	       if( text[i] == '\r' && 
@@ -871,7 +870,7 @@
 	    XChangeProperty(display, request, rprop, 
 			    XA_STRING, 8, PropModeReplace, 
 			    lpstr, j);
-	    free(lpstr);
+	    HeapFree( GetProcessHeap(), 0, lpstr );
 
 	    /* close only if we opened before */
 
diff --git a/windows/hook.c b/windows/hook.c
index 594dd1a..0fa854d 100644
--- a/windows/hook.c
+++ b/windows/hook.c
@@ -267,9 +267,9 @@
 	{
             LPCWPSTRUCT32   lpcwp32 = (LPCWPSTRUCT32)lParam;
             if (bA) WINPROC_UnmapMsg16To32A( lpcwp32->message, lpcwp32->wParam,
-                                             lpcwp32->lParam );
+                                             lpcwp32->lParam, 0 );
             else WINPROC_UnmapMsg16To32W( lpcwp32->message, lpcwp32->wParam,
-                                          lpcwp32->lParam );
+                                          lpcwp32->lParam, 0 );
 	    HeapFree( SystemHeap, 0, lpcwp32 );
             break;
 	}
@@ -399,12 +399,12 @@
           lpcwp16->hwnd = lpcwp32->hwnd;
           lpcwp16->lParam = lpcwp32->lParam;
 
-          if (bA) WINPROC_MapMsg32ATo16( lpcwp32->message, lpcwp32->wParam,
-                                         &lpcwp16->message, &lpcwp16->wParam,
-                                         &lpcwp16->lParam );
-          else WINPROC_MapMsg32WTo16( lpcwp32->message, lpcwp32->wParam,
-                                      &lpcwp16->message, &lpcwp16->wParam,
-                                      &lpcwp16->lParam );
+          if (bA) WINPROC_MapMsg32ATo16( lpcwp32->hwnd, lpcwp32->message,
+                                         lpcwp32->wParam, &lpcwp16->message,
+                                         &lpcwp16->wParam, &lpcwp16->lParam );
+          else WINPROC_MapMsg32WTo16( lpcwp32->hwnd, lpcwp32->message,
+                                      lpcwp32->wParam, &lpcwp16->message,
+                                      &lpcwp16->wParam, &lpcwp16->lParam );
 	  *plParam = (LPARAM)SEGPTR_GET( lpcwp16 );
           break;
       }
diff --git a/windows/keyboard.c b/windows/keyboard.c
index 229ef59..60c8cd6 100644
--- a/windows/keyboard.c
+++ b/windows/keyboard.c
@@ -20,12 +20,12 @@
 #include "windows.h"
 #include "win.h"
 #include "gdi.h"
+#include "heap.h"
 #include "keyboard.h"
 #include "message.h"
 #include "stddebug.h"
 /* #define DEBUG_KEYBOARD */
 #include "debug.h"
-#include "xmalloc.h"
 #include "accel.h"
 #include "struct32.h"
 
@@ -974,11 +974,11 @@
  */
 INT32 WINAPI GetKeyNameText32W(LONG lParam, LPWSTR lpBuffer, INT32 nSize)
 {
-	LPSTR buf = xmalloc(nSize);
-	int	res = GetKeyNameText32A(lParam,buf,nSize);
+	LPSTR buf = HEAP_xalloc( GetProcessHeap(), 0, nSize );
+	int res = GetKeyNameText32A(lParam,buf,nSize);
 
 	lstrcpynAtoW(lpBuffer,buf,nSize);
-	free(buf);
+	HeapFree( GetProcessHeap(), 0, buf );
 	return res;
 }
 
diff --git a/windows/mdi.c b/windows/mdi.c
index 3fd4b95..ccc4bcf 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -16,7 +16,6 @@
 #include <string.h>
 #include <stdio.h>
 #include <math.h>
-#include "xmalloc.h"
 #include "windows.h"
 #include "win.h"
 #include "heap.h"
@@ -341,11 +340,26 @@
         style |= (WS_VISIBLE | WS_OVERLAPPEDWINDOW);
     }
 
-    hwnd = CreateWindow16( (LPCSTR)PTR_SEG_TO_LIN(cs->szClass),
-                           (LPCSTR)PTR_SEG_TO_LIN(cs->szTitle), style, 
-                           cs->x, cs->y, cs->cx, cs->cy, parent, 
-                           (HMENU16)wIDmenu, w->hInstance, 
-                           (LPVOID)lParam);
+    if( w->flags & WIN_ISWIN32 )
+    {
+    	MDICREATESTRUCT32A cs32a;
+
+	STRUCT32_MDICREATESTRUCT16to32A(cs,&cs32a);
+	cs32a.szTitle = (LPCSTR)PTR_SEG_TO_LIN(cs->szTitle);
+	cs32a.szClass = (LPCSTR)PTR_SEG_TO_LIN(cs->szClass);
+
+	hwnd = CreateWindow32A(cs32a.szClass,cs32a.szTitle, style, 
+			       cs->x, cs->y, cs->cx, cs->cy, parent, 
+			       (HMENU16)wIDmenu, cs->hOwner,
+			       (LPVOID)&cs32a);
+	STRUCT32_MDICREATESTRUCT32Ato16(&cs32a,cs);
+    }
+    else
+	hwnd = CreateWindow16( (LPCSTR)PTR_SEG_TO_LIN(cs->szClass),
+			       (LPCSTR)PTR_SEG_TO_LIN(cs->szTitle), style, 
+			       cs->x, cs->y, cs->cx, cs->cy, parent, 
+			       (HMENU32)wIDmenu, cs->hOwner,
+			       (LPVOID)lParam);
 
     /* MDI windows are WS_CHILD so they won't be activated by CreateWindow */
 
@@ -527,16 +541,9 @@
     if( wndPrev )
     {
 	wndPrev->dwStyle |= WS_SYSMENU;
-	SendMessage16( prevActiveWnd, WM_NCACTIVATE, FALSE, 0L );
-
-#ifdef WINELIB32
+	SendMessage32A( prevActiveWnd, WM_NCACTIVATE, FALSE, 0L );
         SendMessage32A( prevActiveWnd, WM_MDIACTIVATE, (WPARAM32)prevActiveWnd, 
                         (LPARAM)hWndChild);
-#else 
-
-        SendMessage16( prevActiveWnd, WM_MDIACTIVATE, FALSE,
-                       MAKELONG(hWndChild,prevActiveWnd));
-#endif 
         /* uncheck menu item */
        	if( clientInfo->hWindowMenu )
        	        CheckMenuItem32( clientInfo->hWindowMenu,
@@ -582,15 +589,8 @@
 	    else
 		SetFocus32( clientInfo->self );
     }
-
-#ifdef WINELIB32
-    SendMessage32A( hWndChild, WM_MDIACTIVATE, (WPARAM32)hWndChild,
-                    (LPARAM)prevActiveWnd );
-#else
-    SendMessage16( hWndChild, WM_MDIACTIVATE, TRUE,
-                   MAKELONG(hWndChild,prevActiveWnd));
-#endif
-
+    SendMessage32A( hWndChild, WM_MDIACTIVATE, (WPARAM32)prevActiveWnd,
+                    (LPARAM)hWndChild );
     return 1;
 }
 
@@ -1008,11 +1008,10 @@
 	return 0;
 
       case WM_MDISETMENU:
-#ifdef WINELIB32
-	return (LRESULT)MDISetMenu(hwnd, FALSE, (HMENU16)wParam, (HMENU16)lParam);
-#else
-	return (LRESULT)MDISetMenu(hwnd, wParam, LOWORD(lParam), HIWORD(lParam));
-#endif
+          /* if Winelib32:
+           * return (LRESULT)MDISetMenu(hwnd, FALSE, (HMENU16)wParam, (HMENU16)lParam);
+           */
+          return (LRESULT)MDISetMenu(hwnd, wParam, LOWORD(lParam), HIWORD(lParam));
 	
       case WM_MDITILE:
 	ci->mdiFlags |= MDIF_NEEDUPDATE;
diff --git a/windows/msgbox.c b/windows/msgbox.c
index a2cb5be..627e0cf 100644
--- a/windows/msgbox.c
+++ b/windows/msgbox.c
@@ -73,20 +73,20 @@
     /* Set the icon */
     switch(lpmb->type & MB_ICONMASK) {
      case MB_ICONEXCLAMATION:
-      SendDlgItemMessage16(hwnd, stc1, STM_SETICON, 
+      SendDlgItemMessage16(hwnd, stc1, STM_SETICON16,
                            (WPARAM16)LoadIcon16(0, IDI_EXCLAMATION), 0);
       break;
      case MB_ICONQUESTION:
-      SendDlgItemMessage16(hwnd, stc1, STM_SETICON, 
+      SendDlgItemMessage16(hwnd, stc1, STM_SETICON16,
                            (WPARAM16)LoadIcon16(0, IDI_QUESTION), 0);
       break;
      case MB_ICONASTERISK:
-      SendDlgItemMessage16(hwnd, stc1, STM_SETICON, 
+      SendDlgItemMessage16(hwnd, stc1, STM_SETICON16,
                            (WPARAM16)LoadIcon16(0, IDI_ASTERISK), 0);
       break;
      case MB_ICONHAND:
      default:
-      SendDlgItemMessage16(hwnd, stc1, STM_SETICON, 
+      SendDlgItemMessage16(hwnd, stc1, STM_SETICON16,
                            (WPARAM16)LoadIcon16(0, IDI_HAND), 0);
       break;
     }
diff --git a/windows/nonclient.c b/windows/nonclient.c
index fa30a1e..3638ebc 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -102,8 +102,8 @@
     }
     if (menu) rect->top -= SYSMETRICS_CYMENU + SYSMETRICS_CYBORDER;
 
-    if (style & WS_VSCROLL) rect->right  += SYSMETRICS_CXVSCROLL;
-    if (style & WS_HSCROLL) rect->bottom += SYSMETRICS_CYHSCROLL;
+    if (style & WS_VSCROLL) rect->right  += SYSMETRICS_CXVSCROLL - 1;
+    if (style & WS_HSCROLL) rect->bottom += SYSMETRICS_CYHSCROLL - 1;
 }
 
 
@@ -1342,56 +1342,8 @@
     WND*	wndPtr = WIN_FindWndPtr( hwnd );
     
     if (wndPtr->dwStyle & WS_SYSMENU)
-    {
-	int	iconic, on = 1;
-
-	iconic = wndPtr->dwStyle & WS_MINIMIZE;
-
-	if( !iconic ) 
-	{
-	     HDC16	hdc = GetWindowDC32(hwnd);
-	     RECT32	rect;
-             RECT16     rTrack;
-	     BOOL32 	bNew, bTrack = TRUE;
-	     MSG16	msg;
-	    
-	     NC_GetSysPopupPos( wndPtr, &rect );
-             CONV_RECT32TO16( &rect, &rTrack );
-	     MapWindowPoints16( 0, hwnd, (LPPOINT16)&rTrack, 2 );
-
-	     /* track mouse while waiting for WM_LBUTTONUP */
-	     if(TWEAK_Win95Look)
-		 NC_DrawSysButton95( hwnd, hdc, bTrack );
-	     else
-		 NC_DrawSysButton( hwnd, hdc, bTrack );
-	     SetCapture32(hwnd);
-	     do
-	     {
-		msg.message = WM_NULL;
-		PeekMessage16( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE);
-		if( msg.message == WM_MOUSEMOVE )
-		{
-		    if( (bNew = PtInRect16(&rTrack, MAKEPOINT16(msg.lParam))) )
-		    {   if( bTrack ) continue; }
-		    else 
-		    {   if(!bTrack ) continue; }
-
-		    if(TWEAK_Win95Look)
-			NC_DrawSysButton95( hwnd, hdc, bTrack = bNew);
-		    else
-			NC_DrawSysButton( hwnd, hdc, bTrack = bNew);
-		}
-	     } while( msg.message != WM_LBUTTONUP );
-
-	     ReleaseCapture();
-	     ReleaseDC32(hwnd, hdc);
-	     on = PtInRect16(&rTrack, MAKEPOINT16(msg.lParam));
-	} 
-
-	if( on ) 
-	    SendMessage16( hwnd, WM_SYSCOMMAND, 
-			   SC_MOUSEMENU + HTSYSMENU, *((LPARAM*)&pt));
-    }
+	SendMessage16( hwnd, WM_SYSCOMMAND, 
+		SC_MOUSEMENU + HTSYSMENU, *((LPARAM*)&pt));
 }
 
 
@@ -1694,7 +1646,9 @@
     if( wndPtr->dwStyle & WS_MINIMIZE )
     {
 	WINPOS_ShowIconTitle( wndPtr, TRUE );
-	if( !moved ) NC_TrackSysMenu( hwnd, pt );
+	if (!moved && (wndPtr->dwStyle & WS_SYSMENU))
+            SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU,
+                           MAKELPARAM( pt.x, pt.y ) );
     }
 }
 
@@ -1839,7 +1793,7 @@
 	break;
 
     case HTSYSMENU:
-        NC_TrackSysMenu( hwnd, MAKEPOINT16(lParam) );
+	SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
 	break;
 
     case HTMENU:
@@ -1909,6 +1863,16 @@
         if (!(pWnd->class->style & CS_NOCLOSE))
             SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, lParam );
 	break;
+
+    case HTHSCROLL:
+	SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL,
+            lParam );
+	break;
+
+    case HTVSCROLL:
+	SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL,
+            lParam );
+	break;
     }
     return 0;
 }
diff --git a/windows/win.c b/windows/win.c
index 32c9f2f..5856606 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -308,7 +308,7 @@
 
     if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
     {
-        if (wndPtr->hrgnUpdate) DeleteObject32( wndPtr->hrgnUpdate );
+        if (wndPtr->hrgnUpdate > 1) DeleteObject32( wndPtr->hrgnUpdate );
         QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
     }
 
@@ -316,19 +316,29 @@
 
     if( wndPtr->hmemTaskQ )
     {
-      int           pos;
-      MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) GlobalLock16(wndPtr->hmemTaskQ);
+        int           pos;
+	BOOL32	      bPostQuit = FALSE;
+	WPARAM32      wQuitParam = 0;
+        MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) GlobalLock16(wndPtr->hmemTaskQ);
 
-      while( (pos = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != -1 ) 
-	      QUEUE_RemoveMsg(msgQ, pos);
-      wndPtr->hmemTaskQ = 0;
+	while( (pos = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != -1 )
+	{
+	    if( msgQ->messages[pos].msg.message == WM_QUIT ) 
+	    {
+		bPostQuit = TRUE;
+		wQuitParam = msgQ->messages[pos].msg.wParam;
+	    }
+	    QUEUE_RemoveMsg(msgQ, pos);
+	}
+	if( bPostQuit ) PostQuitMessage32(wQuitParam);
+	wndPtr->hmemTaskQ = 0;
     }
 
     if (!(wndPtr->dwStyle & WS_CHILD))
        if (wndPtr->wIDmenu) DestroyMenu32( (HMENU32)wndPtr->wIDmenu );
     if (wndPtr->hSysMenu) DestroyMenu32( wndPtr->hSysMenu );
     if (wndPtr->window) EVENT_DestroyWindow( wndPtr );
-    if (wndPtr->class->style & CS_OWNDC) DCE_FreeDCE( wndPtr->dce );
+    if (wndPtr->class->style & CS_OWNDC) DCE_FreeWindowDCE( wndPtr );
 
     WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW );
 
diff --git a/windows/winpos.c b/windows/winpos.c
index 9454080..b916d90 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -2053,7 +2053,11 @@
     if (hwnd == GetDesktopWindow32()) return FALSE;
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
 
-    if (wndPtr->dwStyle & WS_VISIBLE) flags &= ~SWP_SHOWWINDOW;
+    if(wndPtr->dwStyle & WS_VISIBLE)
+    {
+        if(!(wndPtr->flags & WIN_NO_REDRAW))
+            flags &= ~SWP_SHOWWINDOW;
+    }
     else
     {
 	uFlags |= SMC_NOPARENTERASE; 
@@ -2061,6 +2065,9 @@
 	if (!(flags & SWP_SHOWWINDOW)) flags |= SWP_NOREDRAW;
     }
 
+    if(flags & SWP_SHOWWINDOW)
+       wndPtr->flags&=~WIN_NO_REDRAW;
+
 /*     Check for windows that may not be resized 
        FIXME: this should be done only for Windows 3.0 programs 
        if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW ) )
@@ -2120,7 +2127,7 @@
     
       /* Send WM_WINDOWPOSCHANGING message */
 
-    if (!(flags & SWP_NOSENDCHANGING))
+    if (!(winpos.flags & SWP_NOSENDCHANGING))
 	SendMessage32A( hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)&winpos );
 
       /* Calculate new position and size */
@@ -2155,7 +2162,7 @@
          */
 	if( wndPtr->parent == WIN_GetDesktop() )
 	    hwndInsertAfter = WINPOS_ReorderOwnedPopups( hwndInsertAfter,
-							 wndPtr, flags );
+							 wndPtr, winpos.flags );
 
         if (wndPtr->window)
         {
@@ -2165,14 +2172,15 @@
         else WINPOS_MoveWindowZOrder( winpos.hwnd, hwndInsertAfter );
     }
 
-    if ( !wndPtr->window && !(flags & SWP_NOREDRAW) && 
-        (!(flags & SWP_NOMOVE) || !(flags & SWP_NOSIZE) || (flags & SWP_FRAMECHANGED)) )
+    if ( !wndPtr->window && !(winpos.flags & SWP_NOREDRAW) && 
+	((winpos.flags & (SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED)) 
+		      != (SWP_NOMOVE | SWP_NOSIZE)) )
           visRgn = DCE_GetVisRgn(hwnd, DCX_WINDOW | DCX_CLIPSIBLINGS);
 
 
       /* Send WM_NCCALCSIZE message to get new client area */
-    if( (flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE )
-      {
+    if( (winpos.flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE )
+    {
          result = WINPOS_SendNCCalcSize( winpos.hwnd, TRUE, &newWindowRect,
 				    &wndPtr->rectWindow, &wndPtr->rectClient,
 				    &winpos, &newClientRect );
@@ -2184,11 +2192,11 @@
              winpos.flags &= ~SWP_NOCLIENTMOVE;
 
          if( (newClientRect.right - newClientRect.left !=
-             wndPtr->rectClient.right - wndPtr->rectClient.left) ||
-  	    (newClientRect.bottom - newClientRect.top !=
-	     wndPtr->rectClient.bottom - wndPtr->rectClient.top) )
+              wndPtr->rectClient.right - wndPtr->rectClient.left) ||
+	     (newClientRect.bottom - newClientRect.top !=
+	      wndPtr->rectClient.bottom - wndPtr->rectClient.top) )
 	     winpos.flags &= ~SWP_NOCLIENTSIZE;
-      }
+    }
     else
       if( !(flags & SWP_NOMOVE) && (newClientRect.left != wndPtr->rectClient.left ||
 				    newClientRect.top != wndPtr->rectClient.top) )
@@ -2196,15 +2204,15 @@
 
     /* Update active DCEs */
 
-    if( !(flags & SWP_NOZORDER) || (flags & SWP_HIDEWINDOW) || (flags & SWP_SHOWWINDOW)
-                                || (memcmp(&newWindowRect,&wndPtr->rectWindow,sizeof(newWindowRect))
-                                    && wndPtr->dwStyle & WS_VISIBLE ) )
-      {
+    if( (((winpos.flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE) && 
+					 wndPtr->dwStyle & WS_VISIBLE) || 
+	(flags & (SWP_HIDEWINDOW | SWP_SHOWWINDOW)) ) 
+    {
         RECT32 rect;
 
-        UnionRect32(&rect,&newWindowRect,&wndPtr->rectWindow);
+        UnionRect32(&rect, &newWindowRect, &wndPtr->rectWindow);
         DCE_InvalidateDCE(wndPtr->parent, &rect);
-      }
+    }
 
     /* change geometry */
 
diff --git a/windows/winproc.c b/windows/winproc.c
index ddb5be1..e5960bb 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -7,6 +7,7 @@
 
 #include <stdio.h>
 #include "windows.h"
+#include "callback.h"
 #include "heap.h"
 #include "selectors.h"
 #include "struct32.h"
@@ -92,13 +93,6 @@
 
 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;
-
 
 /**********************************************************************
  *	     WINPROC_Init
@@ -116,18 +110,6 @@
 
 
 /**********************************************************************
- *	     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.
@@ -142,15 +124,6 @@
 
 
 /**********************************************************************
- *	     WINPROC_SetCallWndProc16
- */
-void WINPROC_SetCallWndProc16( WINPROC_CALLWNDPROC16 proc )
-{
-    WINPROC_CallWndProc16Ptr = proc;
-}
-
-
-/**********************************************************************
  *	     WINPROC_GetPtr
  *
  * Return a pointer to the win proc.
@@ -464,7 +437,6 @@
         return 1;
     case WM_ASKCBFORMATNAME:
     case WM_DEVMODECHANGE:
-    case WM_MDIACTIVATE:
     case WM_PAINTCLIPBOARD:
     case WM_SIZECLIPBOARD:
     case WM_WININICHANGE:
@@ -576,7 +548,6 @@
         return 1;
     case WM_ASKCBFORMATNAME:
     case WM_DEVMODECHANGE:
-    case WM_MDIACTIVATE:
     case WM_PAINTCLIPBOARD:
     case WM_SIZECLIPBOARD:
     case WM_WININICHANGE:
@@ -757,6 +728,9 @@
             *plparam = (LPARAM)cs;
         }
         return 1;
+    case WM_MDIGETACTIVE:
+        *plparam = (LPARAM)HeapAlloc( SystemHeap, 0, sizeof(BOOL32) );
+        return 1;
     case WM_MDISETMENU:
         *pwparam32 = (WPARAM32)(HMENU32)LOWORD(*plparam);
         *plparam   = (LPARAM)(HMENU32)HIWORD(*plparam);
@@ -766,6 +740,10 @@
         *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
         *plparam   = (LPARAM)(HMENU32)HIWORD(*plparam);
         return 0;
+    case WM_MDIACTIVATE:
+        *pwparam32 = (WPARAM32)(HWND32)HIWORD(*plparam);
+        *plparam   = (LPARAM)(HWND32)LOWORD(*plparam);
+        return 0;
     case WM_NCCALCSIZE:
         {
             NCCALCSIZE_PARAMS16 *nc16;
@@ -826,7 +804,6 @@
         return 1;
     case WM_ASKCBFORMATNAME:
     case WM_DEVMODECHANGE:
-    case WM_MDIACTIVATE:
     case WM_PAINTCLIPBOARD:
     case WM_SIZECLIPBOARD:
     case WM_WININICHANGE:
@@ -845,7 +822,8 @@
  *
  * Unmap a message that was mapped from 16- to 32-bit Ansi.
  */
-void WINPROC_UnmapMsg16To32A( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
+LRESULT WINPROC_UnmapMsg16To32A( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
+                                 LRESULT result )
 {
     switch(msg)
     {
@@ -883,6 +861,10 @@
             HeapFree( SystemHeap, 0, cs );
         }
         break;
+    case WM_MDIGETACTIVE:
+        result = MAKELONG( LOWORD(result), (BOOL16)(*(BOOL32 *)lParam) );
+        HeapFree( SystemHeap, 0, (BOOL32 *)lParam );
+        break;
     case WM_NCCALCSIZE:
         {
             NCCALCSIZE_PARAMS16 *nc16;
@@ -924,6 +906,7 @@
         }
         break;
     }
+    return result;
 }
 
 
@@ -995,7 +978,8 @@
  *
  * Unmap a message that was mapped from 16- to 32-bit Unicode.
  */
-void WINPROC_UnmapMsg16To32W( UINT32 msg, WPARAM32 wParam, LPARAM lParam )
+LRESULT WINPROC_UnmapMsg16To32W( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
+                                 LRESULT result )
 {
     switch(msg)
     {
@@ -1031,9 +1015,9 @@
         }
         break;
     default:
-        WINPROC_UnmapMsg16To32A( msg, wParam, lParam );
-        break;
+        return WINPROC_UnmapMsg16To32A( msg, wParam, lParam, result );
     }
+    return result;
 }
 
 
@@ -1043,8 +1027,9 @@
  * Map a message from 32-bit Ansi to 16-bit.
  * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
  */
-INT32 WINPROC_MapMsg32ATo16( UINT32 msg32, WPARAM32 wParam32, UINT16 *pmsg16,
-                             WPARAM16 *pwparam16, LPARAM *plparam )
+INT32 WINPROC_MapMsg32ATo16( HWND32 hwnd, UINT32 msg32, WPARAM32 wParam32,
+                             UINT16 *pmsg16, WPARAM16 *pwparam16,
+                             LPARAM *plparam )
 {
     *pmsg16 = (UINT16)msg32;
     *pwparam16 = (WPARAM16)LOWORD(wParam32);
@@ -1348,15 +1333,22 @@
             *plparam = (LPARAM)SEGPTR_GET(cs);
         }
         return 1;
+    case WM_MDIGETACTIVE:
+        return 1;
     case WM_MDISETMENU:
-        *pwparam16 = TRUE;  /* FIXME? */
         *plparam   = MAKELPARAM( (HMENU16)LOWORD(wParam32),
                                  (HMENU16)LOWORD(*plparam) );
+        *pwparam16 = (*plparam == 0);
         return 0;
     case WM_MENUCHAR:
     case WM_MENUSELECT:
         *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
         return 0;
+    case WM_MDIACTIVATE:
+        *pwparam16 = ((HWND32)*plparam == hwnd);
+        *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
+                               (HWND16)LOWORD(wParam32) );
+        return 0;
     case WM_NCCALCSIZE:
         {
             NCCALCSIZE_PARAMS32 *nc32 = (NCCALCSIZE_PARAMS32 *)*plparam;
@@ -1422,7 +1414,6 @@
         return 1;
     case WM_ASKCBFORMATNAME:
     case WM_DEVMODECHANGE:
-    case WM_MDIACTIVATE:
     case WM_PAINTCLIPBOARD:
     case WM_SIZECLIPBOARD:
     case WM_WININICHANGE:
@@ -1441,8 +1432,8 @@
  *
  * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
  */
-void WINPROC_UnmapMsg32ATo16( UINT32 msg, WPARAM32 wParam, 
-					  LPARAM lParam, MSGPARAM16* p16 ) 
+void WINPROC_UnmapMsg32ATo16( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
+                              MSGPARAM16* p16 ) 
 {
     switch(msg)
     {
@@ -1531,6 +1522,10 @@
             SEGPTR_FREE( cs );
         }
         break;
+    case WM_MDIGETACTIVE:
+        if (lParam) *(BOOL32 *)lParam = (BOOL16)HIWORD(p16->lResult);
+        p16->lResult = (HWND32)LOWORD(p16->lResult);
+        break;
     case WM_NCCALCSIZE:
         {
             NCCALCSIZE_PARAMS32 *nc32;
@@ -1577,8 +1572,9 @@
  * Map a message from 32-bit Unicode to 16-bit.
  * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
  */
-INT32 WINPROC_MapMsg32WTo16( UINT32 msg32, WPARAM32 wParam32, UINT16 *pmsg16,
-                             WPARAM16 *pwparam16, LPARAM *plparam )
+INT32 WINPROC_MapMsg32WTo16( HWND32 hwnd, UINT32 msg32, WPARAM32 wParam32,
+                             UINT16 *pmsg16, WPARAM16 *pwparam16,
+                             LPARAM *plparam )
 {
     switch(msg32)
     {
@@ -1658,7 +1654,7 @@
         }
         return 1;
     default:  /* No Unicode translation needed */
-        return WINPROC_MapMsg32ATo16( msg32, wParam32, pmsg16,
+        return WINPROC_MapMsg32ATo16( hwnd, msg32, wParam32, pmsg16,
                                       pwparam16, plparam );
     }
 }
@@ -1669,8 +1665,8 @@
  *
  * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
  */
-void WINPROC_UnmapMsg32WTo16( UINT32 msg, WPARAM32 wParam, 
-					  LPARAM lParam, MSGPARAM16* p16 )
+void WINPROC_UnmapMsg32WTo16( UINT32 msg, WPARAM32 wParam, LPARAM lParam,
+                              MSGPARAM16* p16 )
 {
     switch(msg)
     {
@@ -1741,8 +1737,7 @@
     if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
         return 0;
     result = WINPROC_CallWndProc32( func, hwnd, msg32, wParam32, lParam );
-    WINPROC_UnmapMsg16To32A( msg32, wParam32, lParam );
-    return result;
+    return WINPROC_UnmapMsg16To32A( msg32, wParam32, lParam, result );
 }
 
 
@@ -1762,8 +1757,7 @@
     if (WINPROC_MapMsg16To32W( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
         return 0;
     result = WINPROC_CallWndProc32( func, hwnd, msg32, wParam32, lParam );
-    WINPROC_UnmapMsg16To32W( msg32, wParam32, lParam );
-    return result;
+    return WINPROC_UnmapMsg16To32W( msg32, wParam32, lParam, result );
 }
 
 
@@ -1780,11 +1774,11 @@
     MSGPARAM16 mp16;
 
     mp16.lParam = lParam;
-    if (WINPROC_MapMsg32ATo16( msg, wParam, 
-			      &msg16, &mp16.wParam, &mp16.lParam ) == -1)
+    if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam, 
+                               &msg16, &mp16.wParam, &mp16.lParam ) == -1)
         return 0;
-    mp16.lResult = WINPROC_CallWndProc16Ptr( func, hwnd, msg16,
-                                             mp16.wParam, mp16.lParam );
+    mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16,
+                                           mp16.wParam, mp16.lParam );
     WINPROC_UnmapMsg32ATo16( msg, wParam, lParam, &mp16 );
     return mp16.lResult;
 }
@@ -1803,10 +1797,11 @@
     MSGPARAM16 mp16;
 
     mp16.lParam = lParam;
-    if (WINPROC_MapMsg32WTo16( msg, wParam, &msg16, &mp16.wParam, &mp16.lParam ) == -1)
+    if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam,
+                               &mp16.lParam ) == -1)
         return 0;
-    mp16.lResult = WINPROC_CallWndProc16Ptr( func, hwnd, msg16,
-                                             mp16.wParam, mp16.lParam );
+    mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16,
+                                           mp16.wParam, mp16.lParam );
     WINPROC_UnmapMsg32WTo16( msg, wParam, lParam, &mp16 );
     return mp16.lResult;
 }
@@ -1821,19 +1816,19 @@
     WINDOWPROC *proc = WINPROC_GetPtr( func );
 
     if (!proc)
-        return WINPROC_CallWndProc16Ptr( func, hwnd, msg, wParam, lParam );
+        return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam );
 
 #if testing
     func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 );
-    return WINPROC_CallWndProc16Ptr( func, hwnd, msg, wParam, lParam );
+    return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam );
 #endif
     
     switch(proc->type)
     {
     case WIN_PROC_16:
         if (!proc->thunk.t_from32.proc) return 0;
-        return WINPROC_CallWndProc16Ptr( proc->thunk.t_from32.proc,
-                                         hwnd, msg, wParam, lParam );
+        return Callbacks->CallWndProc( proc->thunk.t_from32.proc,
+                                       hwnd, msg, wParam, lParam );
     case WIN_PROC_32A:
         if (!proc->thunk.t_from16.proc) return 0;
         return WINPROC_CallProc16To32A( hwnd, msg, wParam, lParam,