Release 971012

Sun Oct 12 15:03:01 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [if1632/builtin.c] [if1632/relay.c]
	Relay debugging entry points are now generated on the fly for
	Win32 DLLs.

	* [include/stackframe.h]
	Added VA_LIST16 type and macros to access arguments on the 16-bit
	stack.

	* [memory/global.c]
	Fixed GlobalHandle32 to work with fixed blocks.

	* [misc/ddeml.c] (New file)
	Added a lot of stubs for DDEML functions.

	* [objects/dc.c]
	Added Get/SetGraphicsMode().

	* [objects/gdiobj.c] [windows/winpos.c]
	Added a few stubs.

	* [tools/build.c]
	Removed 'byte', 'word', 'long' and 'return' entry points for Win32.
	'register' functions can no longer take arguments in Win32.
 	The Win32 NE module is now generated by MODULE_CreateDummyModule.
	CallFrom32 callbacks removed except for register functions.

Fri Oct 10 18:22:18 1997  John Harvey <john@division.co.uk>

	* [graphics/win16drv/Makefile.in] [graphics/win16drv/brush.c]
	  [graphics/win16drv/graphics.c] [graphics/win16drv/init.c]
	  [graphics/win16drv/objects.c] [graphics/win16drv/pen.c]
	  [graphics/win16drv/prtdrv.c] [graphics/win16drv/text.c]
	  [include/callback.h] [include/win16drv.h]
	Added support for pens and brushes in SelectObject. Added support
	for LineTo, MoveToEx, PatBlt (very preliminary), Polygon and
	Rectangle. Text is drawn in the correct place more often. These
	changes may only work with the Windows Postscript driver since
	many other drivers now need more GDI support.

Tue Oct  7 21:06:23 1997  Kristian Nielsen  <kristian.nielsen@risoe.dk>

	* [debugger/expr.c]
	Fixed typo for the >> operator.

	* [loader/task.c]
	Fixed SwitchStackTo(); it used to return with the new stack placed
	four bytes too high in memory.

	* [loader/ne_resource.c]
	Removed problematic nametable code introduced in Wine 970914.

Tue Oct  7 02:24:12 1997  Dimitrie O. Paun  <dimi@cs.toronto.edu>

	* [controls/commctrl.c]
	Added this files to hold functions from the comctl32.dll
	Added to this files some functions scattered in different places
	(such as InitCommonControls) and added some new ones as well.

	* [include/syscolor.h] [windows/syscolor.c]
	Added proper entries for all possible COLOR_* values.

	* [objects/brush.c]
	Modified GetSysColorBrush to return the correct brush for 
	all possible COLOR_* constants.

Sat Oct  4 23:35:20 1997  U.Bonnes <bon@elektron.ikp.physik.th-darmstadt.de>

	* [loader/module.c] [scheduler/process.c] [win32/environment.c]
	Another approach to get access to an unrestricted commandline.

	* [misc/crtdll.c]
	Make fclose work again.

	* [if1632/crtdll.spec]
	Use sprintf for crtdll-sprintf again as e.g. %g is not available
	for wsprintf.

	* [misc/wsprintf.c]
	Make WPR_STRING work in more situations.
	Added debug output for the wsprintf functions.

	* [misc/crtdll.c] [misc/main.c]
	Use argv[0] as comand with CRTDLL_system.

Fri Oct  3 14:00:29 MET DST 1997  Jan Willamowius  <jan@janhh.shnet.org>

	* [*/*]
        Removed some compiler warnings.

	* [msdos/int15.c]
        New INT 15 handler.
diff --git a/ANNOUNCE b/ANNOUNCE
index 0e140d5..5ad867a 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,12 +1,14 @@
-This is release 970928 of Wine, the MS Windows emulator.  This is still a
+This is release 971012 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-970928: (see ChangeLog for details)
-	- More relay code changes.
+WHAT'S NEW with Wine-971012: (see ChangeLog for details)
+	- Improvements to printer driver support.
+	- More common controls functions.
+	- Win32 relay code changes.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -15,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-970928.tar.gz
-  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-970928.tar.gz
-  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-970928.tar.gz
-  ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-970928.tar.gz
+  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
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/ChangeLog b/ChangeLog
index 5c7855e..f668af6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,99 @@
 ----------------------------------------------------------------------
+Sun Oct 12 15:03:01 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>
+
+	* [if1632/builtin.c] [if1632/relay.c]
+	Relay debugging entry points are now generated on the fly for
+	Win32 DLLs.
+
+	* [include/stackframe.h]
+	Added VA_LIST16 type and macros to access arguments on the 16-bit
+	stack.
+
+	* [memory/global.c]
+	Fixed GlobalHandle32 to work with fixed blocks.
+
+	* [misc/ddeml.c] (New file)
+	Added a lot of stubs for DDEML functions.
+
+	* [objects/dc.c]
+	Added Get/SetGraphicsMode().
+
+	* [objects/gdiobj.c] [windows/winpos.c]
+	Added a few stubs.
+
+	* [tools/build.c]
+	Removed 'byte', 'word', 'long' and 'return' entry points for Win32.
+	'register' functions can no longer take arguments in Win32.
+ 	The Win32 NE module is now generated by MODULE_CreateDummyModule.
+	CallFrom32 callbacks removed except for register functions.
+
+Fri Oct 10 18:22:18 1997  John Harvey <john@division.co.uk>
+
+	* [graphics/win16drv/Makefile.in] [graphics/win16drv/brush.c]
+	  [graphics/win16drv/graphics.c] [graphics/win16drv/init.c]
+	  [graphics/win16drv/objects.c] [graphics/win16drv/pen.c]
+	  [graphics/win16drv/prtdrv.c] [graphics/win16drv/text.c]
+	  [include/callback.h] [include/win16drv.h]
+	Added support for pens and brushes in SelectObject. Added support
+	for LineTo, MoveToEx, PatBlt (very preliminary), Polygon and
+	Rectangle. Text is drawn in the correct place more often. These
+	changes may only work with the Windows Postscript driver since
+	many other drivers now need more GDI support.
+
+Tue Oct  7 21:06:23 1997  Kristian Nielsen  <kristian.nielsen@risoe.dk>
+
+	* [debugger/expr.c]
+	Fixed typo for the >> operator.
+
+	* [loader/task.c]
+	Fixed SwitchStackTo(); it used to return with the new stack placed
+	four bytes too high in memory.
+
+	* [loader/ne_resource.c]
+	Removed problematic nametable code introduced in Wine 970914.
+
+Tue Oct  7 02:24:12 1997  Dimitrie O. Paun  <dimi@cs.toronto.edu>
+
+	* [controls/commctrl.c]
+	Added this files to hold functions from the comctl32.dll
+	Added to this files some functions scattered in different places
+	(such as InitCommonControls) and added some new ones as well.
+
+	* [include/syscolor.h] [windows/syscolor.c]
+	Added proper entries for all possible COLOR_* values.
+
+	* [objects/brush.c]
+	Modified GetSysColorBrush to return the correct brush for 
+	all possible COLOR_* constants.
+
+Sat Oct  4 23:35:20 1997  U.Bonnes <bon@elektron.ikp.physik.th-darmstadt.de>
+
+	* [loader/module.c] [scheduler/process.c] [win32/environment.c]
+	Another approach to get access to an unrestricted commandline.
+
+	* [misc/crtdll.c]
+	Make fclose work again.
+
+	* [if1632/crtdll.spec]
+	Use sprintf for crtdll-sprintf again as e.g. %g is not available
+	for wsprintf.
+
+	* [misc/wsprintf.c]
+	Make WPR_STRING work in more situations.
+	Added debug output for the wsprintf functions.
+
+	* [misc/crtdll.c] [misc/main.c]
+	Use argv[0] as comand with CRTDLL_system.
+
+Fri Oct  3 14:00:29 MET DST 1997  Jan Willamowius  <jan@janhh.shnet.org>
+
+	* [*/*]
+        Removed some compiler warnings.
+
+	* [msdos/int15.c]
+        New INT 15 handler.
+
+----------------------------------------------------------------------
 Sat Sep 27 12:36:56 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>
 
 	* [if1632/relay.c]
diff --git a/Make.rules.in b/Make.rules.in
index d31d7df..6a94c60 100644
--- a/Make.rules.in
+++ b/Make.rules.in
@@ -74,18 +74,18 @@
 	$(CC) -c -o $*.o $<  
 
 .rc.c:
-	echo "#include \"windows.h\"" >winerctmp.c
-	echo WINDOWS_H_ENDS_HERE >>winerctmp.c
-	cat $< >>winerctmp.c
-	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P winerctmp.c | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | $(WINERC) $(RCFLAGS) -c -o $* -p $*
-	$(RM) winerctmp.c
+	echo "#include \"windows.h\"" >$*-tmp.c
+	echo WINDOWS_H_ENDS_HERE >>$*-tmp.c
+	cat $< >>$*-tmp.c
+	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P $*-tmp.c | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | $(WINERC) $(RCFLAGS) -c -o $* -p $*
+	$(RM) $*-tmp.c
 
 .rc.h:
-	echo "#include \"windows.h\"" >winerctmp.c
-	echo WINDOWS_H_ENDS_HERE >>winerctmp.c
-	cat $< >>winerctmp.c
-	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P winerctmp.c | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | $(WINERC) $(RCFLAGS) -c -o $* -p $*
-	$(RM) winerctmp.c
+	echo "#include \"windows.h\"" >$*-tmp.c
+	echo WINDOWS_H_ENDS_HERE >>$*-tmp.c
+	cat $< >>$*-tmp.c
+	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P $*-tmp.c | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | $(WINERC) $(RCFLAGS) -c -o $* -p $*
+	$(RM) $*-tmp.c
 
 
 # Rule to rebuild resource compiler
@@ -115,7 +115,7 @@
 	$(MAKEDEP) $(DIVINCL) -C$(SRCDIR) $(C_SRCS) $(RC_SRCS) $(EXTRA_SRCS)
 
 clean::
-	$(RM) *.o \#*\# *~ *.bak *.orig *.rej *.flc winerctmp.c y.tab.c y.tab.h lex.yy.c core $(GEN_ASM_SRCS) $(RC_SRCS:.rc=.c) $(RC_SRCS:.rc=.h) $(PROGRAMS)
+	$(RM) *.o \#*\# *~ *.bak *.orig *.rej *.flc *-tmp.c y.tab.c y.tab.h lex.yy.c core $(GEN_ASM_SRCS) $(RC_SRCS:.rc=.c) $(RC_SRCS:.rc=.h) $(PROGRAMS)
 
 dummy:
 
diff --git a/controls/Makefile.in b/controls/Makefile.in
index 9be0848..2974ba5 100644
--- a/controls/Makefile.in
+++ b/controls/Makefile.in
@@ -8,6 +8,7 @@
 C_SRCS = \
 	button.c \
 	combo.c \
+	commctrl.c \
 	desktop.c \
 	edit.c \
 	icontitle.c \
diff --git a/controls/commctrl.c b/controls/commctrl.c
new file mode 100644
index 0000000..0ce4e00
--- /dev/null
+++ b/controls/commctrl.c
@@ -0,0 +1,164 @@
+/*		
+ * Common controls functions
+ *
+ * Copyright 1997 Dimitrie O. Paun
+ *
+ */
+
+#include "win.h"
+#include "heap.h"
+#include "commctrl.h"
+#include "progress.h"
+#include "status.h"
+#include "updown.h"
+
+/* Win32 common controls */
+
+static WNDCLASS32A WIDGETS_CommonControls32[] =
+{
+    { CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW, StatusWindowProc, 0,
+      sizeof(STATUSWINDOWINFO), 0, 0, 0, 0, 0, STATUSCLASSNAME32A },
+    { CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW, UpDownWindowProc, 0,
+      sizeof(UPDOWN_INFO), 0, 0, 0, 0, 0, UPDOWN_CLASS32A },
+    { CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW, ProgressWindowProc, 0,
+      sizeof(PROGRESS_INFO), 0, 0, 0, 0, 0, PROGRESS_CLASS32A }
+};
+
+#define NB_COMMON_CONTROLS32 \
+         (sizeof(WIDGETS_CommonControls32)/sizeof(WIDGETS_CommonControls32[0]))
+
+
+/***********************************************************************
+ *           DrawStatusText32A   (COMCTL32.5)
+ */
+void WINAPI DrawStatusText32A( HDC32 hdc, LPRECT32 lprc, LPCSTR text,
+                               UINT32 style )
+{
+    RECT32 r = *lprc;
+    UINT32 border = BDR_SUNKENOUTER;
+
+    DrawEdge32(hdc, &r, BDR_RAISEDINNER, BF_RECT|BF_ADJUST|BF_FLAT);
+
+    if(style==SBT_POPOUT)
+      border = BDR_RAISEDOUTER;
+    else if(style==SBT_NOBORDERS)
+      border = 0;
+
+    DrawEdge32(hdc, &r, border, BF_RECT|BF_ADJUST|BF_MIDDLE);
+
+    /* now draw text */
+    if (text) {
+      int oldbkmode = SetBkMode32(hdc, TRANSPARENT);
+      r.left += 3;
+      DrawText32A(hdc, text, lstrlen32A(text),
+		  &r, DT_LEFT|DT_VCENTER|DT_SINGLELINE);  
+      if (oldbkmode != TRANSPARENT)
+	SetBkMode32(hdc, oldbkmode);
+    }
+    
+}
+
+/***********************************************************************
+ *           DrawStatusText32W   (COMCTL32.24)
+ */
+void WINAPI DrawStatusText32W( HDC32 hdc, LPRECT32 lprc, LPCWSTR text,
+                               UINT32 style )
+{
+  LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, text );
+  DrawStatusText32A(hdc, lprc, p, style);
+  HeapFree( GetProcessHeap(), 0, p );         
+}
+
+/***********************************************************************
+ *           DrawStatusText16   (COMCTL32.23)
+ */
+void WINAPI DrawStatusText16( HDC16 hdc, LPRECT16 lprc, LPCSTR text,
+			      UINT16 style )
+{
+  if(!lprc)
+    DrawStatusText32A((HDC32)hdc, 0, text, (UINT32)style);
+  else{    
+    RECT32 rect32;
+    CONV_RECT16TO32( lprc, &rect32 );
+    DrawStatusText32A((HDC32)hdc, &rect32, text, (UINT32)style);
+  }
+}
+
+/***********************************************************************
+ *           CreateStatusWindow32A   (COMCTL32.6)
+ */
+HWND32 WINAPI CreateStatusWindow32A( INT32 style, LPCSTR text, HWND32 parent,
+                                     UINT32 wid )
+{
+    return CreateWindow32A(STATUSCLASSNAME32A, text, style, 
+			   CW_USEDEFAULT32, CW_USEDEFAULT32,
+			   CW_USEDEFAULT32, CW_USEDEFAULT32, 
+			   parent, wid, 0, 0);
+}
+
+/***********************************************************************
+ *           CreateStatusWindow16   (COMCTL32.18)
+ */
+HWND16 WINAPI CreateStatusWindow16( INT16 style, LPCSTR text, HWND16 parent,
+				    UINT16 wid )
+{
+    return CreateWindow16(STATUSCLASSNAME16, text, style, 
+			   CW_USEDEFAULT16, CW_USEDEFAULT16,
+			   CW_USEDEFAULT16, CW_USEDEFAULT16, 
+			   parent, wid, 0, 0);
+}
+
+/***********************************************************************
+ *           CreateStatusWindow32W   (COMCTL32.19)
+ */
+HWND32 WINAPI CreateStatusWindow32W( INT32 style, LPCWSTR text, HWND32 parent,
+                                     UINT32 wid )
+{
+    return CreateWindow32W(STATUSCLASSNAME32W, text, style, 
+			   CW_USEDEFAULT32, CW_USEDEFAULT32,
+			   CW_USEDEFAULT32, CW_USEDEFAULT32, 
+			   parent, wid, 0, 0);
+}
+
+/***********************************************************************
+ *           CreateUpDownControl  (COMCTL32.16)
+ */
+HWND32 WINAPI CreateUpDownControl( DWORD style, INT32 x, INT32 y,
+                                   INT32 cx, INT32 cy, HWND32 parent,
+                                   INT32 id, HINSTANCE32 inst, HWND32 buddy,
+                                   INT32 maxVal, INT32 minVal, INT32 curVal )
+{
+  HWND32 hUD = CreateWindow32A(UPDOWN_CLASS32A, 0, style, x, y, cx, cy,
+			       parent, id, inst, 0);
+  if(hUD){
+    SendMessage32A(hUD, UDM_SETBUDDY, buddy, 0);
+    SendMessage32A(hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
+    SendMessage32A(hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));     
+  }
+
+  return hUD;
+}
+
+
+/***********************************************************************
+ *           InitCommonControls   (COMCTL32.17)
+ */
+void WINAPI InitCommonControls(void)
+{
+    int i;
+    char name[30];
+    const char *old_name;
+    WNDCLASS32A *class32 = WIDGETS_CommonControls32;
+
+    for (i = 0; i < NB_COMMON_CONTROLS32; i++, class32++)
+    {
+        /* Just to make sure the string is > 0x10000 */
+        old_name = class32->lpszClassName;
+        strcpy( name, (char *)class32->lpszClassName );
+        class32->lpszClassName = name;
+        class32->hCursor = LoadCursor16( 0, IDC_ARROW );
+        RegisterClass32A( class32 );
+        class32->lpszClassName = old_name;	
+    }
+}
+
diff --git a/controls/status.c b/controls/status.c
index df14c53..3fae2d9 100644
--- a/controls/status.c
+++ b/controls/status.c
@@ -10,7 +10,6 @@
 #include "status.h"
 #include "commctrl.h"
 #include "heap.h"
-#include "syscolor.h"
 #include "win.h"
 
 /*
@@ -35,49 +34,6 @@
     return ((STATUSWINDOWINFO *) &wndPtr->wExtra[0]);
 }
 
-/***********************************************************************
- *           DrawStatusText32A   (COMCTL32.3)
- */
-void WINAPI DrawStatusText32A( HDC32 hdc, LPRECT32 lprc, LPCSTR text,
-                               UINT32 style )
-{
-    RECT32 r, rt;
-    int	oldbkmode;
-    UINT32 border;
-
-    r = *lprc;
-
-    if(style == SBT_OWNERDRAW){
-      /* FIXME for SBT_OWNERDRAW, SBT_RTLREADING */
-    }
-    else{
-      DrawEdge32(hdc, &r, BDR_RAISEDINNER, BF_RECT|BF_ADJUST|BF_FLAT);
-
-      if(style==SBT_POPOUT)
-	border = BDR_RAISEDOUTER;
-      else if(style==SBT_NOBORDERS)
-	border = 0;
-      else
-	border = BDR_SUNKENOUTER;
-
-      DrawEdge32(hdc, &r, border, BF_RECT | BF_ADJUST | BF_MIDDLE);
-
-      /* now draw text */
-      if (text) {
-	SelectObject32(hdc, sysColorObjects.hpenWindowText);
-	oldbkmode = SetBkMode32(hdc, TRANSPARENT);
-	rt = r;
-	rt.left += 3;
-	DrawText32A(hdc, text, lstrlen32A(text),
-		    &rt, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
-
-	if (oldbkmode != TRANSPARENT)
-	  SetBkMode32(hdc, oldbkmode);
-      }
-    }
-
-}
-
 static BOOL32 SW_Refresh( HWND32 hwnd, HDC32 hdc, STATUSWINDOWINFO *self )
 {
 	int	i;
@@ -475,23 +431,4 @@
 }
 
 
-/***********************************************************************
- *           CreateStatusWindow32A   (COMCTL32.4)
- */
-HWND32 WINAPI CreateStatusWindow32A( INT32 style, LPCSTR text, HWND32 parent,
-                                     UINT32 wid )
-{
-    HWND32 ret;
-    ATOM atom;
 
-    atom = GlobalFindAtom32A(STATUSCLASSNAME32A);
-    if (!atom) {
-	/* Some apps don't call InitCommonControls */
-	InitCommonControls();
-    }
-
-    ret = CreateWindowEx32A(0, STATUSCLASSNAME32A, "Status Window",
-			    style, CW_USEDEFAULT32, CW_USEDEFAULT32,
-			    CW_USEDEFAULT32, CW_USEDEFAULT32, parent, 0, 0, 0);
-    return (ret);
-}
diff --git a/controls/updown.c b/controls/updown.c
index 4282300..bf81fdb 100644
--- a/controls/updown.c
+++ b/controls/updown.c
@@ -847,21 +847,3 @@
     return 0;
 }
 
-/***********************************************************************
- *           CreateUpDownControl  (COMCTL32.14)
- */
-HWND32 WINAPI CreateUpDownControl( DWORD style, INT32 x, INT32 y,
-                                   INT32 cx, INT32 cy, HWND32 parent,
-                                   INT32 id, HINSTANCE32 inst, HWND32 buddy,
-                                   INT32 maxVal, INT32 minVal, INT32 curVal )
-{
-  HWND32 hUD = CreateWindow32A(UPDOWN_CLASS32A, 0, style, x, y, cx, cy,
-			       parent, id, inst, 0);
-  if(hUD){
-    SendMessage32A(hUD, UDM_SETBUDDY, buddy, 0);
-    SendMessage32A(hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
-    SendMessage32A(hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));     
-  }
-
-  return hUD;
-}
diff --git a/controls/widgets.c b/controls/widgets.c
index 9c1d4a3..81af00a 100644
--- a/controls/widgets.c
+++ b/controls/widgets.c
@@ -9,12 +9,8 @@
 #include "win.h"
 #include "commctrl.h"
 #include "button.h"
-#include "progress.h"
 #include "static.h"
-#include "status.h"
-#include "updown.h"
 #include "scroll.h"
-#include "updown.h"
 #include "desktop.h"
 #include "mdi.h"
 #include "gdi.h"
@@ -99,22 +95,6 @@
 
 static ATOM bicAtomTable[BIC32_NB_CLASSES];
 
-/* Win32 common controls */
-
-static WNDCLASS32A WIDGETS_CommonControls32[] =
-{
-    { CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW, StatusWindowProc, 0,
-      sizeof(STATUSWINDOWINFO), 0, 0, 0, 0, 0, STATUSCLASSNAME32A },
-    { CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW, UpDownWindowProc, 0,
-      sizeof(UPDOWN_INFO), 0, 0, 0, 0, 0, UPDOWN_CLASS32A },
-    { CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW, ProgressWindowProc, 0,
-      sizeof(PROGRESS_INFO), 0, 0, 0, 0, 0, PROGRESS_CLASS32A }
-};
-
-#define NB_COMMON_CONTROLS32 \
-         (sizeof(WIDGETS_CommonControls32)/sizeof(WIDGETS_CommonControls32[0]))
-
-
 /***********************************************************************
  *           WIDGETS_Init
  * 
@@ -167,29 +147,6 @@
 
 
 /***********************************************************************
- *           InitCommonControls   (COMCTL32.15)
- */
-void WINAPI InitCommonControls(void)
-{
-    int i;
-    char name[30];
-    const char *old_name;
-    WNDCLASS32A *class32 = WIDGETS_CommonControls32;
-
-    for (i = 0; i < NB_COMMON_CONTROLS32; i++, class32++)
-    {
-        /* Just to make sure the string is > 0x10000 */
-        old_name = class32->lpszClassName;
-        strcpy( name, (char *)class32->lpszClassName );
-        class32->lpszClassName = name;
-        class32->hCursor = LoadCursor16( 0, IDC_ARROW );
-        RegisterClass32A( class32 );
-        class32->lpszClassName = old_name;	
-    }
-}
-
-
-/***********************************************************************
  *           WIDGETS_IsControl32
  *
  * Check whether pWnd is a built-in control or not.
diff --git a/debugger/expr.c b/debugger/expr.c
index 1735eda..e8a7d6d 100644
--- a/debugger/expr.c
+++ b/debugger/expr.c
@@ -548,7 +548,7 @@
 	  break;
 	case EXP_OP_SHR:
 	  rtn.seg = 0;
-	  exp->un.binop.result = ((unsigned) VAL(exp1) << VAL(exp2));
+	  exp->un.binop.result = ((unsigned) VAL(exp1) >> VAL(exp2));
 	  break;
 	case EXP_OP_MUL:
 	  rtn.seg = 0;
diff --git a/files/profile.c b/files/profile.c
index a034d86..875a590 100644
--- a/files/profile.c
+++ b/files/profile.c
@@ -975,14 +975,13 @@
  *           GetPrivateProfileSection32A   (KERNEL32.255)
  */
 INT32 WINAPI GetPrivateProfileSection32A( LPCSTR section, LPSTR buffer,
-                                         INT32 len, LPCSTR filename )
+                                          INT32 len, LPCSTR filename )
 {
     if (PROFILE_Open( filename ))
         return PROFILE_GetString( section, NULL, NULL, buffer, len );
     return 0;
 }
 
-
 /***********************************************************************
  *           WritePrivateProfileString16   (KERNEL.129)
  */
diff --git a/graphics/win16drv/Makefile.in b/graphics/win16drv/Makefile.in
index 895b2bb..1f9cf22 100644
--- a/graphics/win16drv/Makefile.in
+++ b/graphics/win16drv/Makefile.in
@@ -6,9 +6,12 @@
 MODULE    = win16drv
 
 C_SRCS = \
+	brush.c \
 	font.c \
+	graphics.c \
 	init.c \
 	objects.c \
+	pen.c \
 	prtdrv.c \
 	text.c
 
diff --git a/graphics/win16drv/brush.c b/graphics/win16drv/brush.c
new file mode 100644
index 0000000..d64b14e
--- /dev/null
+++ b/graphics/win16drv/brush.c
@@ -0,0 +1,35 @@
+/*
+ * GDI brush objects - win16drv
+ *
+ * Copyright 1997  John Harvey
+ */
+
+#include <stdlib.h>
+#include "brush.h"
+#include "win16drv.h"
+#include "stddebug.h"
+#include "debug.h"
+
+HBRUSH32 WIN16DRV_BRUSH_SelectObject( DC * dc, HBRUSH32 hbrush,
+                                      BRUSHOBJ * brush )
+{
+    WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
+    HBRUSH16	 prevHandle = dc->w.hBrush;
+    int		 nSize;
+    LOGBRUSH16 	 lBrush16;
+    dc->w.hBrush = hbrush;
+    lBrush16.lbStyle = brush->logbrush.lbStyle;
+    lBrush16.lbColor = brush->logbrush.lbColor;
+    lBrush16.lbHatch = brush->logbrush.lbHatch;
+    nSize = PRTDRV_RealizeObject (physDev->segptrPDEVICE, OBJ_BRUSH,
+                                  &lBrush16, NULL, 
+                                  0); 
+    /*  may need to realloc segptrFOntInfo*/
+    physDev->segptrBrushInfo = WIN16_GlobalLock16(GlobalAlloc16(GHND, nSize));
+    nSize = PRTDRV_RealizeObject(physDev->segptrPDEVICE, OBJ_BRUSH,
+                                 &lBrush16, 
+                                 (LPVOID)physDev->segptrBrushInfo, 
+                                 win16drv_SegPtr_TextXForm); 
+                         
+    return prevHandle;
+}
diff --git a/graphics/win16drv/graphics.c b/graphics/win16drv/graphics.c
new file mode 100644
index 0000000..1a72994
--- /dev/null
+++ b/graphics/win16drv/graphics.c
@@ -0,0 +1,105 @@
+/*
+ * Windows 16 bit device driver graphics functions
+ *
+ * Copyright 1997 John Harvey
+ */
+
+#include "win16drv.h"
+
+/**********************************************************************
+ *	     WIN16DRV_MoveToEx
+ */
+BOOL32
+WIN16DRV_MoveToEx(DC *dc,INT32 x,INT32 y,LPPOINT32 pt) 
+{
+    if (pt)
+    {
+	pt->x = dc->w.CursPosX;
+	pt->y = dc->w.CursPosY;
+    }
+    dc->w.CursPosX = x;
+    dc->w.CursPosY = y;
+    return TRUE;
+}
+
+/***********************************************************************
+ *           WIN16DRV_LineTo
+ */
+BOOL32
+WIN16DRV_LineTo( DC *dc, INT32 x, INT32 y )
+{
+    BOOL32 bRet ;
+    WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
+    POINT16 points[2];
+    points[0].x = dc->w.DCOrgX + XLPTODP( dc, dc->w.CursPosX );
+    points[0].y = dc->w.DCOrgY + YLPTODP( dc, dc->w.CursPosY );
+    points[1].x = dc->w.DCOrgX + XLPTODP( dc, x );
+    points[1].y = dc->w.DCOrgY + YLPTODP( dc, y );
+    bRet = PRTDRV_Output(physDev->segptrPDEVICE,
+                         OS_POLYLINE, 2, points, 
+                         physDev->segptrPenInfo,
+                         NULL,
+                         win16drv_SegPtr_DrawMode, NULL);
+
+    dc->w.CursPosX = x;
+    dc->w.CursPosY = y;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           WIN16DRV_Rectangle
+ */
+BOOL32
+WIN16DRV_Rectangle(DC *dc, INT32 left, INT32 top, INT32 right, INT32 bottom)
+{
+    WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
+    BOOL32 bRet = 0;
+    POINT16 points[2];
+    printf("In WIN16drv_Rectangle, x %d y %d DCOrgX %d y %d\n",
+           left, top, dc->w.DCOrgX, dc->w.DCOrgY);
+    printf("In WIN16drv_Rectangle, VPortOrgX %d y %d\n",
+           dc->vportOrgX, dc->vportOrgY);
+    points[0].x = XLPTODP(dc, left);
+    points[0].y = YLPTODP(dc, top);
+
+    points[1].x = XLPTODP(dc, right);
+    points[1].y = XLPTODP(dc, bottom);
+    bRet = PRTDRV_Output(physDev->segptrPDEVICE,
+                         OS_RECTANGLE, 2, points, 
+                         physDev->segptrPenInfo,
+                         physDev->segptrBrushInfo,
+                         win16drv_SegPtr_DrawMode, NULL);
+    return bRet;
+}
+
+
+
+
+/***********************************************************************
+ *           WIN16DRV_Polygon
+ */
+BOOL32
+WIN16DRV_Polygon(DC *dc, LPPOINT32 pt, INT32 count )
+{
+    WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
+    BOOL32 bRet = 0;
+    LPPOINT16 points;
+    int i;
+    points = malloc(count * sizeof(POINT16));
+    for (i = 0; i<count ; i++)
+    {
+      points[i].x = ((pt[i].x - dc->wndOrgX) * dc->vportExtX/ dc->wndExtX) + dc->vportOrgX;
+      points[i].y = ((pt[i].y - dc->wndOrgY) * dc->vportExtY/ dc->wndExtY) + dc->vportOrgY;
+    }
+    bRet = PRTDRV_Output(physDev->segptrPDEVICE,
+                         OS_WINDPOLYGON, 2, points, 
+                         physDev->segptrPenInfo,
+                         physDev->segptrBrushInfo,
+                         win16drv_SegPtr_DrawMode, NULL);
+    return bRet;
+}
+
+
+
+
diff --git a/graphics/win16drv/init.c b/graphics/win16drv/init.c
index 4611105..2254bf4 100644
--- a/graphics/win16drv/init.c
+++ b/graphics/win16drv/init.c
@@ -67,8 +67,8 @@
     WIN16DRV_GetTextMetrics,         /* pGetTextMetrics */
     NULL,                            /* pIntersectClipRect */
     NULL,                            /* pIntersectVisRect */
-    NULL,                            /* pLineTo */
-    NULL,                            /* pMoveToEx */
+    WIN16DRV_LineTo,                 /* pLineTo */
+    WIN16DRV_MoveToEx,               /* pMoveToEx */
     NULL,                            /* pOffsetClipRgn */
     NULL,                            /* pOffsetViewportOrgEx */
     NULL,                            /* pOffsetWindowOrgEx */
@@ -76,10 +76,10 @@
     WIN16DRV_PatBlt,                 /* pPatBlt */
     NULL,                            /* pPie */
     NULL,                            /* pPolyPolygon */
-    NULL,                            /* pPolygon */
+    WIN16DRV_Polygon,                /* pPolygon */
     NULL,                            /* pPolyline */
     NULL,                            /* pRealizePalette */
-    NULL,                            /* pRectangle */
+    WIN16DRV_Rectangle,                            /* pRectangle */
     NULL,                            /* pRestoreDC */
     NULL,                            /* pRoundRect */
     NULL,                            /* pSaveDC */
@@ -278,11 +278,11 @@
 
     /* TTD Shouldn't really do pointer arithmetic on segment points */
     physDev->segptrPDEVICE = WIN16_GlobalLock16(GlobalAlloc16(GHND, nPDEVICEsize))+sizeof(PDEVICE_HEADER);
-    *(BYTE *)(PTR_SEG_TO_LIN(physDev->segptrPDEVICE)+0) = 'N'; 
-    *(BYTE *)(PTR_SEG_TO_LIN(physDev->segptrPDEVICE)+1) = 'B'; 
+    *((BYTE *)PTR_SEG_TO_LIN(physDev->segptrPDEVICE)+0) = 'N'; 
+    *((BYTE *)PTR_SEG_TO_LIN(physDev->segptrPDEVICE)+1) = 'B'; 
 
     /* Set up the header */
-    pPDH = (PDEVICE_HEADER *)(PTR_SEG_TO_LIN(physDev->segptrPDEVICE) - sizeof(PDEVICE_HEADER)); 
+    pPDH = (PDEVICE_HEADER *)((BYTE*)PTR_SEG_TO_LIN(physDev->segptrPDEVICE) - sizeof(PDEVICE_HEADER)); 
     pPDH->pLPD = pLPD;
     
     dprintf_win16drv(stddeb, "PRTDRV_Enable: PDEVICE allocated %08lx\n",(DWORD)(physDev->segptrPDEVICE));
@@ -389,8 +389,14 @@
 extern BOOL32 WIN16DRV_PatBlt( struct tagDC *dc, INT32 left, INT32 top,
                              INT32 width, INT32 height, DWORD rop )
 {
-  printf("In WIN16DRV_PatBlt\n");
-  return FALSE;
+  
+    WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
+    BOOL32 bRet = 0;
+
+    bRet = PRTDRV_StretchBlt( physDev->segptrPDEVICE, left, top, width, height, NULL, 0, 0, width, height,
+                       PATCOPY, physDev->segptrBrushInfo, win16drv_SegPtr_DrawMode, NULL);
+
+    return bRet;
 }
 /* 
  * Escape (GDI.38)
@@ -415,17 +421,17 @@
 
           case NEXTBAND:
             {
-              SEGPTR newInData =  WIN16_GlobalLock16(GlobalAlloc16(GHND, sizeof(POINT16)));
+              LPPOINT16 newInData =  SEGPTR_NEW(POINT16);
+
               nRet = PRTDRV_Control(physDev->segptrPDEVICE, nEscape,
-                                    newInData, lpOutData);
-              GlobalFree16(newInData);
+                                    SEGPTR_GET(newInData), lpOutData);
+              SEGPTR_FREE(newInData);
               break;
             }
 
 	  case GETEXTENDEDTEXTMETRICS:
             {
-              SEGPTR newInData =  WIN16_GlobalLock16(GlobalAlloc16(GHND, sizeof(EXTTEXTDATA)));
-              EXTTEXTDATA *textData = (EXTTEXTDATA *)(PTR_SEG_TO_LIN(newInData));
+	      EXTTEXTDATA *textData = SEGPTR_NEW(EXTTEXTDATA);
 
               textData->nSize = cbInput;
               textData->lpindata = lpInData;
@@ -433,9 +439,8 @@
               textData->lpXForm = win16drv_SegPtr_TextXForm;
               textData->lpDrawMode = win16drv_SegPtr_DrawMode;
               nRet = PRTDRV_Control(physDev->segptrPDEVICE, nEscape,
-                                    newInData, lpOutData);
-              GlobalFree16(newInData);
-              
+                                    SEGPTR_GET(textData), lpOutData);
+              SEGPTR_FREE(textData);
             }
           break;
           case STARTDOC:
@@ -443,13 +448,14 @@
 				  lpInData, lpOutData);
             if (nRet != -1)
             {
-              SEGPTR newInData =  WIN16_GlobalLock16(GlobalAlloc16(GHND, sizeof(HDC32)));
+              HDC32 *tmpHdc = SEGPTR_NEW(HDC32);
+
 #define SETPRINTERDC SETABORTPROC
-              HDC32 *tmpHdc = (HDC32 *)(PTR_SEG_TO_LIN(newInData));
+
               *tmpHdc = dc->hSelf;
               PRTDRV_Control(physDev->segptrPDEVICE, SETPRINTERDC,
-                             newInData, (SEGPTR)NULL);
-              GlobalFree16(newInData);
+                             SEGPTR_GET(tmpHdc), (SEGPTR)NULL);
+              SEGPTR_FREE(tmpHdc);
             }
             break;
 	  default:
@@ -659,7 +665,7 @@
 
 HANDLE16 WINAPI OpenJob(LPSTR lpOutput, LPSTR lpTitle, HDC16 hDC)
 {
-    HANDLE16 hHandle = SP_ERROR;
+    HANDLE16 hHandle = (HANDLE16)SP_ERROR;
     PPRINTJOB pPrintJob;
 
     dprintf_win16drv(stddeb, "OpenJob: \"%s\" \"%s\" %04x\n", lpOutput, lpTitle, hDC);
diff --git a/graphics/win16drv/objects.c b/graphics/win16drv/objects.c
index ee54724..c2e1f82 100644
--- a/graphics/win16drv/objects.c
+++ b/graphics/win16drv/objects.c
@@ -37,11 +37,15 @@
     switch(ptr->wMagic)
     {
     case PEN_MAGIC:
-        fprintf(stderr, "WIN16DRV_SelectObject for PEN not implemented\n");
+        ret = WIN16DRV_PEN_SelectObject( dc, handle, (PENOBJ *)ptr );	  
+        break;
     case BRUSH_MAGIC:
-        fprintf(stderr, "WIN16DRV_SelectObject for BRUSH not implemented\n");
+        ret = WIN16DRV_BRUSH_SelectObject( dc, handle, (BRUSHOBJ *)ptr );	  
+        break;
     case BITMAP_MAGIC:
         fprintf(stderr, "WIN16DRV_SelectObject for BITMAP not implemented\n");
+        ret = 1;
+        break;
     case FONT_MAGIC:
         ret = WIN16DRV_FONT_SelectObject( dc, handle, (FONTOBJ *)ptr );	  
 	break;
diff --git a/graphics/win16drv/pen.c b/graphics/win16drv/pen.c
new file mode 100644
index 0000000..d4b5933
--- /dev/null
+++ b/graphics/win16drv/pen.c
@@ -0,0 +1,41 @@
+/*
+ * GDI pen objects
+ *
+ * Copyright 1997 John Harvey
+ */
+
+#include "pen.h"
+#include "color.h"
+#include "win16drv.h"
+#include "stddebug.h"
+#include "debug.h"
+
+/***********************************************************************
+ *           PEN_SelectObject
+ */
+HPEN32 WIN16DRV_PEN_SelectObject( DC * dc, HPEN32 hpen, PENOBJ * pen )
+{
+    WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
+    HPEN32 prevHandle = dc->w.hPen;
+    int		 nSize;
+    LOGPEN16 	 lPen16;
+    dc->w.hPen = hpen;
+    printf("In WIN16DRV_PEN_SelectObject\n");
+    lPen16.lopnStyle   = pen->logpen.lopnStyle;
+    lPen16.lopnWidth.x = pen->logpen.lopnWidth.x;
+    lPen16.lopnWidth.y = pen->logpen.lopnWidth.y;
+    lPen16.lopnColor   = pen->logpen.lopnColor;
+    nSize = PRTDRV_RealizeObject (physDev->segptrPDEVICE, OBJ_PEN,
+                                  &lPen16, NULL, 
+                                  0); 
+    /*  may need to realloc segptrFOntInfo*/
+    physDev->segptrPenInfo = WIN16_GlobalLock16(GlobalAlloc16(GHND, nSize));
+    nSize = PRTDRV_RealizeObject(physDev->segptrPDEVICE, OBJ_PEN,
+                                 &lPen16, 
+                                 (LPVOID)physDev->segptrPenInfo, 
+                                 0); 
+                         
+
+    return prevHandle;
+}
+
diff --git a/graphics/win16drv/prtdrv.c b/graphics/win16drv/prtdrv.c
index 086c41b..6a533ba 100644
--- a/graphics/win16drv/prtdrv.c
+++ b/graphics/win16drv/prtdrv.c
@@ -1,7 +1,7 @@
 /*
  * Windows Device Context initialisation functions
  *
- * Copyright 1996 John Harvey
+ * Copyright 1996,1997 John Harvey
  */
 
 #include <stdlib.h>
@@ -12,7 +12,8 @@
 #include <errno.h>
 #include "windows.h"
 #include "win16drv.h"
-
+#include "heap.h"
+#include "brush.h"
 #include "callback.h"
 #include "stddebug.h"
 #include "debug.h"
@@ -82,7 +83,6 @@
 	      pLPD = ptmpLPD;
 	}
     }
-    if (pLPD == NULL) fprintf(stderr,"Couldn't find driver %s\n", pszDriver);
     return pLPD;
 }
 
@@ -142,27 +142,23 @@
         strcat(drvName, ".DRV");
         hInst = LoadLibrary16(drvName);
     }
-    dprintf_win16drv(stddeb, "Loaded the library\n");
 
     
     if (hInst <= 32)
     {
 	/* Failed to load driver */
 	fprintf(stderr, "Failed to load printer driver %s\n", pszDriver);
-    }
-    else
-    {
-	HANDLE16 hHandle;
-
+    } else {
+        dprintf_win16drv(stddeb, "Loaded the library\n");
 	/* Allocate some memory for printer driver info */
 	pLPD = malloc(sizeof(LOADED_PRINTER_DRIVER));
 	memset(pLPD, 0 , sizeof(LOADED_PRINTER_DRIVER));
 	
-	pLPD->hInst = hInst;
-	strcpy(pLPD->szDriver,pszDriver);
+	pLPD->hInst	= hInst;
+	pLPD->szDriver	= HEAP_strdupA(SystemHeap,0,pszDriver);
 
 	/* Get DS for the printer module */
-	pLPD->ds_reg = hInst;
+	pLPD->ds_reg	= hInst;
 
 	dprintf_win16drv(stddeb, "DS for %s is %x\n", pszDriver, pLPD->ds_reg);
 
@@ -172,12 +168,6 @@
 	/* Set initial usage count */
 	pLPD->nUsageCount = 1;
 
-	/* Create a thunking buffer */
-	hHandle = GlobalAlloc16(GHND, (1024 * 8));
-	pLPD->hThunk = hHandle;
-	pLPD->ThunkBufSegPtr = WIN16_GlobalLock16(hHandle);
-	pLPD->ThunkBufLimit = pLPD->ThunkBufSegPtr + (1024*8);
-
 	/* Update table of loaded printer drivers */
 	pLPD->nIndex = nDriverSlot;
 	gapLoadedPrinterDrivers[nDriverSlot] = pLPD;
@@ -186,42 +176,6 @@
     return pLPD;
 }
 
-/* 
- * Thunking utility functions
- */
-
-static BOOL32 AddData(SEGPTR *pSegPtr, const void *pData, int nSize, SEGPTR Limit)
-{
-    BOOL32 bRet = FALSE;
-    char *pBuffer = PTR_SEG_TO_LIN((*pSegPtr));
-    char *pLimit = PTR_SEG_TO_LIN(Limit);
-
-
-    if ((pBuffer + nSize) < pLimit)
-    {
-	DWORD *pdw = (DWORD *)pSegPtr;
-	SEGPTR SegPtrOld = *pSegPtr;
-	SEGPTR SegPtrNew;
-
-	dprintf_win16drv(stddeb, "AddData: Copying %d from %p to %p(0x%x)\n", nSize, pData, pBuffer, (UINT32)*pSegPtr);
-	memcpy(pBuffer, pData, nSize); 
-	SegPtrNew = (SegPtrOld + nSize + 1);
-	*pdw = (DWORD)SegPtrNew;
-    }
-    return bRet;
-}
-
-
-static BOOL32 GetParamData(SEGPTR SegPtrSrc,void *pDataDest, int nSize)
-{
-    char *pSrc =  PTR_SEG_TO_LIN(SegPtrSrc);
-    char *pDest = pDataDest;
-
-    dprintf_win16drv(stddeb, "GetParamData: Copying %d from %lx(%lx) to %lx\n", nSize, (DWORD)pSrc, (DWORD)SegPtrSrc, (DWORD)pDataDest);
-    memcpy(pDest, pSrc, nSize);
-    return TRUE;
-}
-
 /*
  *  Control (ordinal 3)
  */
@@ -273,61 +227,45 @@
 
     /* Get the printer driver info */
     if (wStyle == INITPDEVICE)
-    {
 	pLPD = FindPrinterDriverFromPDEVICE((SEGPTR)lpDevInfo);
-    }
     else
-    {
 	pLPD = FindPrinterDriverFromName((char *)lpDeviceName);
-    }
-    if (pLPD != NULL)
-    {
-	LONG lP1, lP3, lP4, lP5;
-	WORD wP2;
-	SEGPTR SegPtr = pLPD->ThunkBufSegPtr;
-	SEGPTR Limit = pLPD->ThunkBufLimit;
-	int   nSize;
+    if (pLPD != NULL) {
+	LONG		lP5;
+	DeviceCaps	*lP1;
+	LPSTR		lP3,lP4;
+	WORD		wP2;
 
-	if (pLPD->fn[FUNC_ENABLE] == NULL)
-	{
+	if (!pLPD->fn[FUNC_ENABLE]) {
 	    dprintf_win16drv(stddeb, "PRTDRV_Enable: Not supported by driver\n");
 	    return 0;
 	}
 
 	if (wStyle == INITPDEVICE)
-	{
-	    /* All ready a 16 address */
-	    lP1 = (SEGPTR)lpDevInfo;
-	}
+	    lP1 = (DeviceCaps*)lpDevInfo;/* 16 bit segmented ptr already */
 	else
-	{
-	    /* 32 bit data */
-	    lP1 = SegPtr;
-	    nSize = sizeof(DeviceCaps);
-	    AddData(&SegPtr, lpDevInfo, nSize, Limit);	
-	}
+	    lP1 = SEGPTR_NEW(DeviceCaps);
 	
 	wP2 = wStyle;
 	
-	lP3 = SegPtr;
-	nSize = strlen(lpDestDevType) + 1;
-	AddData(&SegPtr, lpDestDevType, nSize, Limit);	
-
-	lP4 = SegPtr; 
-	nSize = strlen(lpOutputFile) + 1;
-	AddData(&SegPtr, lpOutputFile, nSize, Limit);	
-
+	/* SEGPTR_STRDUP handles NULL like a charm ... */
+	lP3 = SEGPTR_STRDUP(lpDestDevType);
+	lP4 = SEGPTR_STRDUP(lpOutputFile);
 	lP5 = (LONG)lpData;
         
-
 	wRet = CallTo16_word_lwlll(pLPD->fn[FUNC_ENABLE], 
-				   lP1, wP2, lP3, lP4, lP5);
+				   (wStyle==INITPDEVICE)?lP1:SEGPTR_GET(lP1),
+				   wP2,
+				   SEGPTR_GET(lP3),
+				   SEGPTR_GET(lP4),
+				   lP5);
+	SEGPTR_FREE(lP3);
+	SEGPTR_FREE(lP4);
 
 	/* Get the data back */
-	if (lP1 != 0 && wStyle != INITPDEVICE)
-	{
-	    nSize = sizeof(DeviceCaps);
-	    GetParamData(lP1, lpDevInfo, nSize);
+	if (lP1 != 0 && wStyle != INITPDEVICE) {
+	    memcpy(lpDevInfo,lP1,sizeof(DeviceCaps));
+	    SEGPTR_FREE(lP1);
 	}
     }
     dprintf_win16drv(stddeb, "PRTDRV_Enable: return %x\n", wRet);
@@ -348,39 +286,23 @@
 
     if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
     {
-	LONG lP1, lP2, lP3, lP4;
+	LONG lP1, lP3, lP4;
+	LPBYTE lP2;
 
-	SEGPTR SegPtr = pLPD->ThunkBufSegPtr;
-	SEGPTR Limit = pLPD->ThunkBufLimit;
-	int   nSize;
-
-	if (pLPD->fn[FUNC_ENUMDFONTS] == NULL)
-	{
+	if (pLPD->fn[FUNC_ENUMDFONTS] == NULL) {
 	    dprintf_win16drv(stddeb, "PRTDRV_EnumDFonts: Not supported by driver\n");
 	    return 0;
 	}
 
 	lP1 = (SEGPTR)lpDestDev;
-	
-	if (lpFaceName == NULL)
-	{
-	    lP2 = 0;
-	}
-	else
-	{
-	    lP2 = SegPtr;
-	    nSize = strlen(lpFaceName) + 1;
-	    AddData(&SegPtr, lpFaceName, nSize, Limit);	
-	}
-
+	lP2 = SEGPTR_STRDUP(lpFaceName);
 	lP3 = (LONG)lpCallbackFunc; 
-
 	lP4 = (LONG)lpClientData;
         
 	wRet = CallTo16_word_llll(pLPD->fn[FUNC_ENUMDFONTS], 
-                                  lP1, lP2, lP3, lP4);
-    }
-    else 
+                                  lP1, SEGPTR_GET(lP2), lP3, lP4);
+	SEGPTR_FREE(lP2);
+    } else 
         fprintf(stderr,"Failed to find device\n");
     
     dprintf_win16drv(stddeb, "PRTDRV_EnumDFonts: return %x\n", wRet);
@@ -429,6 +351,63 @@
     return wRet;
 }
 
+/*
+ *	Output (ordinal 8)
+ */
+WORD PRTDRV_Output(LPPDEVICE 	 lpDestDev,
+                   WORD 	 wStyle, 
+                   WORD 	 wCount,
+                   POINT16     **points, 
+                   SEGPTR 	 lpPPen,
+                   SEGPTR	 lpPBrush,
+                   SEGPTR	 lpDrawMode,
+                   RECT16 	*lpClipRect)
+{
+    WORD wRet = 0;
+    LOADED_PRINTER_DRIVER *pLPD = NULL;
+    
+    dprintf_win16drv(stddeb, "PRTDRV_OUTPUT\n");
+    
+    if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
+    {
+        LONG lP1, lP5, lP6, lP7;
+        LPPOINT16 lP4;
+        LPRECT16 lP8;
+        WORD wP2, wP3;
+	int   nSize;
+	if (pLPD->fn[FUNC_OUTPUT] == NULL)
+	{
+	    dprintf_win16drv(stddeb, "PRTDRV_Output: Not supported by driver\n");
+	    return 0;
+	}
+
+        lP1 = lpDestDev;
+        wP2 = wStyle;
+        wP3 = wCount;
+        nSize = sizeof(POINT16) * wCount;
+ 	lP4 = (LPPOINT16 )SEGPTR_ALLOC(nSize);
+ 	memcpy(lP4,points,nSize);
+        lP5 = lpPPen;
+        lP6 = lpPBrush;
+        lP7 = lpDrawMode;
+        
+	if (lpClipRect != NULL)
+	{
+	    lP8 = SEGPTR_NEW(RECT16);
+	    memcpy(lP8,lpClipRect,sizeof(RECT16));
+
+	}
+	else
+	  lP8 = 0L;
+	wRet = CallTo16_word_lwwlllll(pLPD->fn[FUNC_OUTPUT], 
+                                      lP1, wP2, wP3, SEGPTR_GET(lP4), lP5,
+                                      lP6, lP7, SEGPTR_GET(lP8));
+        SEGPTR_FREE(lP4);
+        SEGPTR_FREE(lP8);
+    }
+    return wRet;
+}
+
 /* 
  * RealizeObject (ordinal 10)
  */
@@ -443,11 +422,10 @@
     
     if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
     {
-	LONG lP1, lP3, lP4, lP5;  
-	WORD wP2;
-	SEGPTR SegPtr = pLPD->ThunkBufSegPtr;
-	SEGPTR Limit = pLPD->ThunkBufLimit;
-	int   nSize;
+	LONG	lP1, lP4, lP5;  
+	LPBYTE	lP3;
+	WORD	wP2;
+	unsigned int	nSize;
 
 	if (pLPD->fn[FUNC_REALIZEOBJECT] == NULL)
 	{
@@ -458,31 +436,99 @@
 	lP1 = lpDestDev;
 	wP2 = wStyle;
 	
-	lP3 = SegPtr;
 	switch (wStyle)
 	{
-        case 3: 
+        case OBJ_BRUSH:
+            nSize = sizeof (LOGBRUSH16);
+            break;
+        case OBJ_FONT: 
             nSize = sizeof(LOGFONT16); 
             break;
+        case OBJ_PEN:
+            nSize = sizeof(LOGPEN16); 
+            break;
+        case OBJ_PBITMAP:
         default:
-	    fprintf(stderr,"PRTDRV_RealizeObject: Object type %d not supported\n", wStyle);
+	    fprintf(stderr, "PRTDRV_RealizeObject: Object type %d not supported\n", wStyle);
             nSize = 0;
             
 	}
-	AddData(&SegPtr, lpInObj, nSize, Limit);	
+ 	lP3 = SEGPTR_ALLOC(nSize);
+ 	memcpy(lP3,lpInObj,nSize);
 	
 	lP4 = (LONG)lpOutObj;
 
         lP5 = lpTextXForm;
 
 	dwRet = CallTo16_long_lwlll(pLPD->fn[FUNC_REALIZEOBJECT], 
-                                    lP1, wP2, lP3, lP4, lP5);
+                                    lP1, wP2, SEGPTR_GET(lP3), lP4, lP5);
+        SEGPTR_FREE(lP3);
 
     }
     dprintf_win16drv(stddeb, "PRTDRV_RealizeObject: return %x\n", dwRet);
     return dwRet;
 }
 
+/* 
+ * StretchBlt (ordinal 27)
+ */
+DWORD PRTDRV_StretchBlt(LPPDEVICE lpDestDev,
+                        WORD wDestX, WORD wDestY,
+                        WORD wDestXext, WORD wDestYext, 
+                        LPPDEVICE lpSrcDev,
+                        WORD wSrcX, WORD wSrcY,
+                        WORD wSrcXext, WORD wSrcYext, 
+                        DWORD Rop3,
+                        SEGPTR lpPBrush,
+                        SEGPTR lpDrawMode,
+                        RECT16 *lpClipRect)
+{
+    WORD wRet = 0;
+    LOADED_PRINTER_DRIVER *pLPD = NULL;
+    
+    dprintf_win16drv(stddeb, "PRTDRV_StretchBlt:\n");
+    
+    if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
+    {
+        LONG lP1,lP6, lP11, lP12, lP13;
+        LPRECT16 lP14;
+        WORD wP2, wP3, wP4, wP5, wP7, wP8, wP9, wP10;
+
+	if (pLPD->fn[FUNC_STRETCHBLT] == NULL)
+	{
+	    dprintf_win16drv(stddeb, "PRTDRV_StretchBlt: Not supported by driver\n");
+	    return 0;
+	}
+	lP1  = lpDestDev;
+	wP2  = wDestX;
+	wP3  = wDestY;
+	wP4  = wDestXext;
+	wP5  = wDestYext;
+        lP6  = lpSrcDev;
+        wP7  = wSrcX;
+        wP8  = wSrcY;
+        wP9  = wSrcXext;
+        wP10 = wSrcYext;
+        lP11 = Rop3;
+        lP12 = lpPBrush;
+        lP13 = lpDrawMode;
+	if (lpClipRect != NULL)
+	{
+	    lP14 = SEGPTR_NEW(RECT16);
+	    memcpy(lP14,lpClipRect,sizeof(RECT16));
+
+	}
+	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));
+        SEGPTR_FREE(lP14);
+        printf("Called StretchBlt ret %d\n",wRet);
+    }
+    return wRet;
+}
 
 DWORD PRTDRV_ExtTextOut(LPPDEVICE lpDestDev, WORD wDestXOrg, WORD wDestYOrg,
                         RECT16 *lpClipRect, LPCSTR lpString, WORD wCount, 
@@ -497,13 +543,12 @@
     
     if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
     {
-	LONG lP1, lP4, lP5, lP7, lP8, lP9, lP10, lP11;  
-	WORD wP2, wP3, wP12;
-        INT16 iP6;
-
-	SEGPTR SegPtr = pLPD->ThunkBufSegPtr;
-	SEGPTR Limit = pLPD->ThunkBufLimit;
-	int   nSize;
+	LONG		lP1, lP7, lP8, lP9, lP10;  
+	LPSTR		lP5;
+	LPRECT16	lP4,lP11;
+	WORD		wP2, wP3, wP12;
+        INT16		iP6;
+	unsigned int	nSize = -1;
 
 	if (pLPD->fn[FUNC_EXTTEXTOUT] == NULL)
 	{
@@ -515,28 +560,22 @@
 	wP2 = wDestXOrg;
 	wP3 = wDestYOrg;
 	
-	if (lpClipRect != NULL)
-	{
-	    lP4 = SegPtr;
-	    nSize = sizeof(RECT16);
+	if (lpClipRect != NULL) {
+	    lP4 = SEGPTR_NEW(RECT16);
             dprintf_win16drv(stddeb, "Adding lpClipRect\n");
-            
-	    AddData(&SegPtr, lpClipRect, nSize, Limit);	
-	}
-	else
+	    memcpy(lP4,lpClipRect,sizeof(RECT16));
+	} else
 	  lP4 = 0L;
 
-	if (lpString != NULL)
-	{
+	if (lpString != NULL) {
 	    /* TTD WARNING THIS STRING ISNT NULL TERMINATED */
-	    lP5 = SegPtr;
 	    nSize = strlen(lpString);
-            nSize = abs(wCount);
-            dprintf_win16drv(stddeb, "Adding string size %d\n",nSize);
-            
-	    AddData(&SegPtr, lpString, nSize, Limit);	
-	}
-	else
+	    if (nSize>abs(wCount))
+	    	nSize = abs(wCount);
+	    lP5 = SEGPTR_ALLOC(nSize);
+            dprintf_win16drv(stddeb, "Adding lpString (nSize is %d)\n",nSize);
+	    memcpy(lP5,lpString,nSize);
+	} else
 	  lP5 = 0L;
 	
 	iP6 = wCount;
@@ -550,28 +589,23 @@
 	  dprintf_win16drv(stddeb, "PRTDRV_ExtTextOut: Char widths not supported\n");
 	lP10 = 0;
 	
-	if (lpOpaqueRect != NULL)
-	{
-	    lP11 = SegPtr;
-	    nSize = sizeof(RECT16);
-            dprintf_win16drv(stddeb, "Adding opaqueRect\n");
-	    AddData(&SegPtr, lpOpaqueRect, nSize, Limit);	
-	}
-	else
+	if (lpOpaqueRect != NULL) {
+	    lP11 = SEGPTR_NEW(RECT16);
+            dprintf_win16drv(stddeb, "Adding lpOpaqueRect\n");
+	    memcpy(lP11,lpOpaqueRect,sizeof(RECT16));	
+	} else
 	  lP11 = 0L;
 	
 	wP12 = wOptions;
-	dprintf_win16drv(stddeb, "Calling exttextout 0x%lx 0x%x 0x%x 0x%lx\n0x%lx 0x%x 0x%lx 0x%lx\n"
-               "0x%lx 0x%lx 0x%lx 0x%x\n",lP1, wP2, wP3, lP4, 
-					   lP5, iP6, lP7, lP8, lP9, lP10,
+	dprintf_win16drv(stddeb, "Calling ExtTextOut 0x%lx 0x%x 0x%x %p\n%*s 0x%x 0x%lx 0x%lx\n"
+               "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, lP4, 
-					   lP5, iP6, lP7, lP8, lP9, lP10,
-					   lP11, wP12);
+                                           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 6d1876e..cef68aa 100644
--- a/graphics/win16drv/text.c
+++ b/graphics/win16drv/text.c
@@ -97,7 +97,7 @@
     }
 #endif        
 
-	dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, x, y, 
+	dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, XLPTODP(dc,x), XLPTODP(dc,y), 
 				  &clipRect, str, 
 				  wCount,  physDev->segptrFontInfo, win16drv_SegPtr_DrawMode, 
 				  win16drv_SegPtr_TextXForm, NULL, lpOpaqueRect, wOptions);
diff --git a/if1632/Makefile.in b/if1632/Makefile.in
index e9bb416..ddc8d34 100644
--- a/if1632/Makefile.in
+++ b/if1632/Makefile.in
@@ -63,8 +63,8 @@
 
 GEN_ASM_SRCS = \
 	$(SPEC_FILES) \
+	call32.s \
 	callfrom16.s \
-	callfrom32.s \
 	callto16.s
 
 .SUFFIXES: .spec
@@ -81,8 +81,8 @@
 callfrom16.s: $(SPEC_FILES)
 	$(BUILD) -o $@ -callfrom16 `cat $(SPEC_FILES) | grep CallFrom16_ | sed 's/.*CallFrom16_\(.*\)/\1/' | sort | uniq`
 
-callfrom32.s: $(SPEC_FILES)
-	$(BUILD) -o $@ -callfrom32 `cat $(SPEC_FILES) | grep CallFrom32_ | sed 's/.*CallFrom32_\(.*\)/\1/' | sort | uniq`
+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`
diff --git a/if1632/advapi32.spec b/if1632/advapi32.spec
index c776a65..237e01c 100644
--- a/if1632/advapi32.spec
+++ b/if1632/advapi32.spec
@@ -74,7 +74,7 @@
 0070 stub ImpersonateNamedPipeClient
 0071 stub ImpersonateSelf
 0072 stub InitializeAcl
-0073 return InitializeSecurityDescriptor 8 1
+0073 stdcall InitializeSecurityDescriptor(ptr long) InitializeSecurityDescriptor
 0074 stdcall InitializeSid(ptr ptr long) InitializeSid
 0075 stub InitiateSystemShutdownA
 0076 stub InitiateSystemShutdownW
diff --git a/if1632/builtin.c b/if1632/builtin.c
index 0f2e4b9..29ba5ac 100644
--- a/if1632/builtin.c
+++ b/if1632/builtin.c
@@ -10,6 +10,7 @@
 #include "windows.h"
 #include "gdi.h"
 #include "global.h"
+#include "heap.h"
 #include "module.h"
 #include "miscemu.h"
 #include "neexe.h"
@@ -23,38 +24,46 @@
 
 typedef struct
 {
+    const char *name;              /* DLL name */
+    void       *module_start;      /* 32-bit address of the module data */
+    int         module_size;       /* Size of the module data */
     const BYTE *code_start;        /* 32-bit address of DLL code */
     const BYTE *data_start;        /* 32-bit address of DLL data */
 } WIN16_DESCRIPTOR;
 
 typedef struct
 {
+    const char         *name;       /* DLL name */
     int                 base;       /* Ordinal base */
-    int                 size;       /* Number of functions */
-    const void         *code_start; /* Start of DLL code */
-    const void        **functions;  /* Pointer to functions table */
-    const void        **nodbg_functions;  /* Pointer to funcs without debug */
+    int                 nb_funcs;   /* Number of functions */
+    int                 nb_names;   /* Number of function names */
+    const void        **functions;  /* Pointer to function table */
     const char * const *names;      /* Pointer to names table */
+    const WORD         *ordinals;   /* Pointer to ordinals table */
+    const BYTE         *args;       /* Pointer to argument lengths */
 } WIN32_DESCRIPTOR;
 
-typedef struct
+typedef union
 {
-    const char *name;              /* DLL name */
-    void       *module_start;      /* 32-bit address of the module data */
-    int         module_size;       /* Size of the module data */
-    union
-    {
-        WIN16_DESCRIPTOR win16;    /* Descriptor for Win16 DLL */
-        WIN32_DESCRIPTOR win32;    /* Descriptor for Win32 DLL */
-    } u;
+    const char *name;               /* DLL name */
+    WIN16_DESCRIPTOR win16;         /* Descriptor for Win16 DLL */
+    WIN32_DESCRIPTOR win32;         /* Descriptor for Win32 DLL */
 } DLL_DESCRIPTOR;
 
 typedef struct
 {
-    const DLL_DESCRIPTOR *descr;   /* DLL descriptor */
-    int                   flags;   /* flags (see below) */
-} BUILTIN_DLL;
+    BYTE  call;                    /* 0xe8 call callfrom32 (relative) */
+    DWORD callfrom32 WINE_PACKED;  /* RELAY_CallFrom32 relative addr */
+    BYTE  ret;                     /* 0xc2 ret $n  or  0xc3 ret */
+    WORD  args;                    /* nb of args to remove from the stack */
+} DEBUG_ENTRY_POINT;
 
+typedef struct
+{
+    const DLL_DESCRIPTOR *descr;     /* DLL descriptor */
+    DEBUG_ENTRY_POINT    *dbg_funcs; /* Relay debugging functions table */
+    int                   flags;     /* flags (see below) */
+} BUILTIN_DLL;
 
 /* DLL flags */
 #define DLL_FLAG_NOT_USED    0x01  /* Use original Windows DLL if possible */
@@ -117,65 +126,179 @@
 static BUILTIN_DLL BuiltinDLLs[] =
 {
     /* Win16 DLLs */
-    { &KERNEL_Descriptor,   DLL_FLAG_ALWAYS_USED },
-    { &USER_Descriptor,     DLL_FLAG_ALWAYS_USED },
-    { &GDI_Descriptor,      DLL_FLAG_ALWAYS_USED },
-    { &SYSTEM_Descriptor,   DLL_FLAG_ALWAYS_USED },
-    { &WIN87EM_Descriptor,  DLL_FLAG_NOT_USED },
-    { &SHELL_Descriptor,    0 },
-    { &SOUND_Descriptor,    0 },
-    { &KEYBOARD_Descriptor, 0 },
-    { &WINSOCK_Descriptor,  0 },
-    { &STRESS_Descriptor,   0 },
-    { &MMSYSTEM_Descriptor, 0 },
-    { &TOOLHELP_Descriptor, 0 },
-    { &MOUSE_Descriptor,    0 },
-    { &COMMDLG_Descriptor,  DLL_FLAG_NOT_USED },
-    { &OLE2_Descriptor,     DLL_FLAG_NOT_USED },
-    { &OLE2CONV_Descriptor, DLL_FLAG_NOT_USED },
-    { &OLE2DISP_Descriptor, DLL_FLAG_NOT_USED },
-    { &OLE2NLS_Descriptor,  DLL_FLAG_NOT_USED },
-    { &OLE2PROX_Descriptor, DLL_FLAG_NOT_USED },
-    { &OLECLI_Descriptor,   DLL_FLAG_NOT_USED },
-    { &OLESVR_Descriptor,   DLL_FLAG_NOT_USED },
-    { &COMPOBJ_Descriptor,  DLL_FLAG_NOT_USED },
-    { &STORAGE_Descriptor,  DLL_FLAG_NOT_USED },
-    { &WPROCS_Descriptor,   DLL_FLAG_ALWAYS_USED },
-    { &DDEML_Descriptor,    DLL_FLAG_NOT_USED },
-    { &LZEXPAND_Descriptor, 0 },
-    { &VER_Descriptor,      0 },
-    { &W32SYS_Descriptor,   0 },
-    { &WING_Descriptor,     0 },
+    { &KERNEL_Descriptor,   NULL, DLL_FLAG_ALWAYS_USED },
+    { &USER_Descriptor,     NULL, DLL_FLAG_ALWAYS_USED },
+    { &GDI_Descriptor,      NULL, DLL_FLAG_ALWAYS_USED },
+    { &SYSTEM_Descriptor,   NULL, DLL_FLAG_ALWAYS_USED },
+    { &WIN87EM_Descriptor,  NULL, DLL_FLAG_NOT_USED },
+    { &SHELL_Descriptor,    NULL, 0 },
+    { &SOUND_Descriptor,    NULL, 0 },
+    { &KEYBOARD_Descriptor, NULL, 0 },
+    { &WINSOCK_Descriptor,  NULL, 0 },
+    { &STRESS_Descriptor,   NULL, 0 },
+    { &MMSYSTEM_Descriptor, NULL, 0 },
+    { &TOOLHELP_Descriptor, NULL, 0 },
+    { &MOUSE_Descriptor,    NULL, 0 },
+    { &COMMDLG_Descriptor,  NULL, DLL_FLAG_NOT_USED },
+    { &OLE2_Descriptor,     NULL, DLL_FLAG_NOT_USED },
+    { &OLE2CONV_Descriptor, NULL, DLL_FLAG_NOT_USED },
+    { &OLE2DISP_Descriptor, NULL, DLL_FLAG_NOT_USED },
+    { &OLE2NLS_Descriptor,  NULL, DLL_FLAG_NOT_USED },
+    { &OLE2PROX_Descriptor, NULL, DLL_FLAG_NOT_USED },
+    { &OLECLI_Descriptor,   NULL, DLL_FLAG_NOT_USED },
+    { &OLESVR_Descriptor,   NULL, DLL_FLAG_NOT_USED },
+    { &COMPOBJ_Descriptor,  NULL, DLL_FLAG_NOT_USED },
+    { &STORAGE_Descriptor,  NULL, DLL_FLAG_NOT_USED },
+    { &WPROCS_Descriptor,   NULL, DLL_FLAG_ALWAYS_USED },
+    { &DDEML_Descriptor,    NULL, DLL_FLAG_NOT_USED },
+    { &LZEXPAND_Descriptor, NULL, 0 },
+    { &VER_Descriptor,      NULL, 0 },
+    { &W32SYS_Descriptor,   NULL, 0 },
+    { &WING_Descriptor,     NULL, 0 },
     /* Win32 DLLs */
-    { &ADVAPI32_Descriptor, 0 },
-    { &COMCTL32_Descriptor, DLL_FLAG_NOT_USED },
-    { &COMDLG32_Descriptor, 0 },
-    { &CRTDLL_Descriptor,   0 },
-    { &OLE32_Descriptor,    DLL_FLAG_NOT_USED },
-    { &GDI32_Descriptor,    0 },
-    { &KERNEL32_Descriptor, DLL_FLAG_ALWAYS_USED },
-    { &LZ32_Descriptor,     0 },
-    { &MPR_Descriptor,      DLL_FLAG_NOT_USED },
-    { &NTDLL_Descriptor,    0 },
-    { &SHELL32_Descriptor,  0 },
-    { &USER32_Descriptor,   0 },
-    { &VERSION_Descriptor,  0 },
-    { &WINMM_Descriptor,    0 },
-    { &WINSPOOL_Descriptor, 0 },
-    { &WSOCK32_Descriptor,  0 },
+    { &ADVAPI32_Descriptor, NULL, DLL_FLAG_WIN32 },
+    { &COMCTL32_Descriptor, NULL, DLL_FLAG_WIN32 | DLL_FLAG_NOT_USED },
+    { &COMDLG32_Descriptor, NULL, DLL_FLAG_WIN32 },
+    { &CRTDLL_Descriptor,   NULL, DLL_FLAG_WIN32 },
+    { &OLE32_Descriptor,    NULL, DLL_FLAG_WIN32 | DLL_FLAG_NOT_USED },
+    { &GDI32_Descriptor,    NULL, DLL_FLAG_WIN32 },
+    { &KERNEL32_Descriptor, NULL, DLL_FLAG_WIN32 | DLL_FLAG_ALWAYS_USED },
+    { &LZ32_Descriptor,     NULL, DLL_FLAG_WIN32 },
+    { &MPR_Descriptor,      NULL, DLL_FLAG_WIN32 | DLL_FLAG_NOT_USED },
+    { &NTDLL_Descriptor,    NULL, DLL_FLAG_WIN32 },
+    { &SHELL32_Descriptor,  NULL, DLL_FLAG_WIN32 },
+    { &USER32_Descriptor,   NULL, DLL_FLAG_WIN32 },
+    { &VERSION_Descriptor,  NULL, DLL_FLAG_WIN32 },
+    { &WINMM_Descriptor,    NULL, DLL_FLAG_WIN32 },
+    { &WINSPOOL_Descriptor, NULL, DLL_FLAG_WIN32 },
+    { &WSOCK32_Descriptor,  NULL, DLL_FLAG_WIN32 },
     /* Last entry */
-    { NULL, 0 }
+    { NULL, NULL, 0 }
 };
 
   /* Ordinal number for interrupt 0 handler in WPROCS.DLL */
 #define FIRST_INTERRUPT_ORDINAL 100
 
 /***********************************************************************
+ *           BUILTIN_BuildDebugEntryPoints
+ *
+ * Build the table of relay-debugging entry points for a Win32 DLL.
+ */
+static void BUILTIN_BuildDebugEntryPoints( BUILTIN_DLL *dll )
+{
+    int i;
+    DEBUG_ENTRY_POINT *entry;
+    extern void RELAY_CallFrom32();
+
+    assert( !dll->dbg_funcs );
+    assert( dll->flags & DLL_FLAG_WIN32 );
+    dll->dbg_funcs = HeapAlloc( SystemHeap, 0,
+                      dll->descr->win32.nb_funcs * sizeof(DEBUG_ENTRY_POINT) );
+    entry = dll->dbg_funcs;
+    for (i = 0; i < dll->descr->win32.nb_funcs; i++, entry++)
+    {
+        BYTE args = dll->descr->win32.args[i];
+        entry->call = 0xe8;  /* call */
+        switch(args)
+        {
+        case 0xfe:  /* register func */
+            entry->callfrom32 = (DWORD)dll->descr->win32.functions[i] -
+                                (DWORD)&entry->ret;
+            entry->ret        = 0x90;  /* nop */
+            entry->args       = 0;
+            break;
+        case 0xff:  /* stub */
+            entry->args = 0xffff;
+            break;
+        default:  /* normal function (stdcall or cdecl) */
+            entry->callfrom32 = (DWORD)RELAY_CallFrom32 - (DWORD)&entry->ret;
+            entry->ret        = (args & 0x80) ? 0xc3 : 0xc2; /* ret / ret $n */
+            entry->args       = (args & 0x7f) * sizeof(int);
+            break;
+        }
+    }
+}
+
+
+/***********************************************************************
+ *           BUILTIN_DoLoadModule16
+ *
+ * Load a built-in Win16 module. Helper function for BUILTIN_LoadModule
+ * and BUILTIN_Init.
+ */
+static HMODULE16 BUILTIN_DoLoadModule16( const WIN16_DESCRIPTOR *descr )
+{
+    NE_MODULE *pModule;
+    int minsize;
+    SEGTABLEENTRY *pSegTable;
+
+    HMODULE16 hModule = GLOBAL_CreateBlock( GMEM_MOVEABLE, descr->module_start,
+                                            descr->module_size, 0,
+                                            FALSE, FALSE, FALSE, NULL );
+    if (!hModule) return 0;
+    FarSetOwner( hModule, hModule );
+
+    dprintf_module( stddeb, "Built-in %s: hmodule=%04x\n",
+                    descr->name, hModule );
+    pModule = (NE_MODULE *)GlobalLock16( hModule );
+    pModule->self = hModule;
+
+    /* Allocate the code segment */
+
+    pSegTable = NE_SEG_TABLE( pModule );
+    pSegTable->selector = GLOBAL_CreateBlock( GMEM_FIXED, descr->code_start,
+                                              pSegTable->minsize, hModule,
+                                              TRUE, TRUE, FALSE, NULL );
+    if (!pSegTable->selector) return 0;
+    pSegTable++;
+
+    /* Allocate the data segment */
+
+    minsize = pSegTable->minsize ? pSegTable->minsize : 0x10000;
+    minsize += pModule->heap_size;
+    if (minsize > 0x10000) minsize = 0x10000;
+    pSegTable->selector = GLOBAL_Alloc( GMEM_FIXED, minsize,
+                                        hModule, FALSE, FALSE, FALSE );
+    if (!pSegTable->selector) return 0;
+    if (pSegTable->minsize) memcpy( GlobalLock16( pSegTable->selector ),
+                                    descr->data_start, pSegTable->minsize);
+    if (pModule->heap_size)
+        LocalInit( pSegTable->selector, pSegTable->minsize, minsize );
+
+    MODULE_RegisterModule( pModule );
+    return hModule;
+}
+
+
+/***********************************************************************
+ *           BUILTIN_DoLoadModule32
+ *
+ * Load a built-in Win32 module. Helper function for BUILTIN_LoadModule
+ * and BUILTIN_Init.
+ */
+static HMODULE16 BUILTIN_DoLoadModule32( BUILTIN_DLL *table )
+{
+    HMODULE16 hModule;
+    NE_MODULE *pModule;
+    OFSTRUCT ofs;
+
+    sprintf( ofs.szPathName, "%s.DLL", table->descr->name );
+    hModule = MODULE_CreateDummyModule( &ofs );
+    pModule = (NE_MODULE *)GlobalLock16( hModule );
+    pModule->pe_module = (PE_MODULE *)table;
+    pModule->flags = NE_FFLAGS_SINGLEDATA | NE_FFLAGS_BUILTIN |
+        NE_FFLAGS_LIBMODULE | NE_FFLAGS_WIN32;
+    if (debugging_relay) BUILTIN_BuildDebugEntryPoints( table );
+    return hModule;
+}
+
+
+/***********************************************************************
  *           BUILTIN_Init
  *
  * Load all built-in modules marked as 'always used'.
  */
-BOOL16 BUILTIN_Init(void)
+BOOL32 BUILTIN_Init(void)
 {
     BUILTIN_DLL *dll;
     NE_MODULE *pModule;
@@ -183,8 +306,17 @@
     HMODULE16 hModule;
 
     for (dll = BuiltinDLLs; dll->descr; dll++)
-        if (dll->flags & DLL_FLAG_ALWAYS_USED)
-            if (!BUILTIN_LoadModule(dll->descr->name, TRUE)) return FALSE;
+    {
+        if (!(dll->flags & DLL_FLAG_ALWAYS_USED)) continue;
+        if (dll->flags & DLL_FLAG_WIN32)
+        {
+            if (!BUILTIN_DoLoadModule32( dll )) return FALSE;
+        }
+        else
+        {
+            if (!BUILTIN_DoLoadModule16( &dll->descr->win16 )) return FALSE;
+        }
+    }
 
     /* Set the USER and GDI heap selectors */
 
@@ -223,10 +355,8 @@
  * Load a built-in module. If the 'force' parameter is FALSE, we only
  * load the module if it has not been disabled via the -dll option.
  */
-HMODULE16 BUILTIN_LoadModule( LPCSTR name, BOOL16 force )
+HMODULE16 BUILTIN_LoadModule( LPCSTR name, BOOL32 force )
 {
-    HMODULE16 hModule;
-    NE_MODULE *pModule;
     BUILTIN_DLL *table;
     char dllname[16], *p;
 
@@ -241,52 +371,10 @@
     if (!table->descr) return 0;
     if ((table->flags & DLL_FLAG_NOT_USED) && !force) return 0;
 
-    hModule = GLOBAL_CreateBlock( GMEM_MOVEABLE, table->descr->module_start,
-                                  table->descr->module_size, 0,
-                                  FALSE, FALSE, FALSE, NULL );
-    if (!hModule) return 0;
-    FarSetOwner( hModule, hModule );
-
-    dprintf_module( stddeb, "Built-in %s: hmodule=%04x\n",
-                    table->descr->name, hModule );
-    pModule = (NE_MODULE *)GlobalLock16( hModule );
-    pModule->self = hModule;
-
-    if (pModule->flags & NE_FFLAGS_WIN32)
-    {
-        pModule->pe_module = (PE_MODULE *)table;
-        table->flags |= DLL_FLAG_WIN32;
-    }
-    else  /* Win16 module */
-    {
-        const WIN16_DESCRIPTOR *descr = &table->descr->u.win16;
-        int minsize;
-
-        /* Allocate the code segment */
-
-        SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
-        pSegTable->selector = GLOBAL_CreateBlock(GMEM_FIXED, descr->code_start,
-                                                 pSegTable->minsize, hModule,
-                                                 TRUE, TRUE, FALSE, NULL );
-        if (!pSegTable->selector) return 0;
-        pSegTable++;
-
-        /* Allocate the data segment */
-
-        minsize = pSegTable->minsize ? pSegTable->minsize : 0x10000;
-        minsize += pModule->heap_size;
-        if (minsize > 0x10000) minsize = 0x10000;
-        pSegTable->selector = GLOBAL_Alloc( GMEM_FIXED, minsize,
-                                            hModule, FALSE, FALSE, FALSE );
-        if (!pSegTable->selector) return 0;
-        if (pSegTable->minsize) memcpy( GlobalLock16( pSegTable->selector ),
-                                        descr->data_start, pSegTable->minsize);
-        if (pModule->heap_size)
-            LocalInit( pSegTable->selector, pSegTable->minsize, minsize );
-    }
-
-    MODULE_RegisterModule( pModule );
-    return hModule;
+    if (table->flags & DLL_FLAG_WIN32)
+        return BUILTIN_DoLoadModule32( table );
+    else
+        return BUILTIN_DoLoadModule16( &table->descr->win16 );
 }
 
 
@@ -370,35 +458,36 @@
  *
  * Return the name of the DLL entry point corresponding
  * to a relay entry point address. This is used only by relay debugging.
+ *
+ * This function _must_ return the real entry point to call
+ * after the debug info is printed.
  */
-LPCSTR BUILTIN_GetEntryPoint32( void *relay )
+FARPROC32 BUILTIN_GetEntryPoint32( char *buffer, void *relay )
 {
-    static char buffer[80];
     BUILTIN_DLL *dll;
-    const void **funcs;
-    int i;
+    int ordinal, i;
+    const WIN32_DESCRIPTOR *descr;
 
     /* First find the module */
 
     for (dll = BuiltinDLLs; dll->descr; dll++)
         if ((dll->flags & DLL_FLAG_WIN32) &&
-            (dll->descr->u.win32.code_start <= relay) &&
-            ((void *)dll->descr->u.win32.functions > relay))
+            ((void *)dll->dbg_funcs <= relay) &&
+            ((void *)(dll->dbg_funcs + dll->descr->win32.nb_funcs) > relay))
             break;
-    if (!dll->descr)
-    {
-        sprintf( buffer, "???.???: %08x", (UINT32)relay );
-        return buffer;
-    }
+    assert(dll->descr);
+    descr = &dll->descr->win32;
 
     /* Now find the function */
 
-    relay = (BYTE *)relay - 11;  /* The relay entry point is 11 bytes long */
-    funcs = dll->descr->u.win32.functions;
-    for (i = 0; i < dll->descr->u.win32.size;i++) if (*funcs++ == relay) break;
-    sprintf( buffer, "%s.%d: %s", dll->descr->name,
-             dll->descr->u.win32.base + i, dll->descr->u.win32.names[i] );
-    return buffer;
+    ordinal = ((DWORD)relay-(DWORD)dll->dbg_funcs) / sizeof(DEBUG_ENTRY_POINT);
+    ordinal += descr->base;
+    for (i = 0; i < descr->nb_names; i++)
+        if (descr->ordinals[i] == ordinal) break;
+    assert( i < descr->nb_names );
+
+    sprintf( buffer, "%s.%d: %s", descr->name, ordinal, descr->names[i] );
+    return (FARPROC32)descr->functions[ordinal - descr->base];
 }
 
 
@@ -411,7 +500,7 @@
 FARPROC32 BUILTIN_GetProcAddress32( NE_MODULE *pModule, LPCSTR function )
 {
     BUILTIN_DLL *dll = (BUILTIN_DLL *)pModule->pe_module;
-    const WIN32_DESCRIPTOR *info = &dll->descr->u.win32;
+    const WIN32_DESCRIPTOR *info = &dll->descr->win32;
     WORD ordinal = 0;
 
     if (!dll) return NULL;
@@ -422,26 +511,24 @@
 
         dprintf_module( stddeb, "Looking for function %s in %s\n",
                         function, dll->descr->name );
-        for (i = 0; i < info->size; i++)
-            if (info->names[i] && !strcmp( function, info->names[i] ))
+        for (i = 0; i < info->nb_names; i++)
+            if (!strcmp( function, info->names[i] ))
             {
-                ordinal = info->base + i;
+                ordinal = info->ordinals[i];
                 break;
             }
-        if (i >= info->size) return NULL;  /* not found */
+        if (i >= info->nb_names) return NULL;  /* not found */
     }
     else  /* Find function by ordinal */
     {
         ordinal = LOWORD(function);
         dprintf_module( stddeb, "Looking for ordinal %d in %s\n",
                         ordinal, dll->descr->name );
-        if ((ordinal < info->base) || (ordinal >= info->base + info->size))
+        if ((ordinal < info->base) || (ordinal >= info->base + info->nb_funcs))
             return NULL;  /* not found */
     }
-#if testing
-    if (!debugging_relay)
-        return (FARPROC32)info->nodbg_functions[ordinal - info->base];
-#endif
+    if (dll->dbg_funcs && (dll->dbg_funcs[ordinal-info->base].args != 0xffff))
+        return (FARPROC32)&dll->dbg_funcs[ordinal - info->base];
     return (FARPROC32)info->functions[ordinal - info->base];
 }
 
@@ -465,7 +552,7 @@
  *
  * Set runtime DLL usage flags
  */
-BOOL16 BUILTIN_ParseDLLOptions( const char *str )
+BOOL32 BUILTIN_ParseDLLOptions( const char *str )
 {
     BUILTIN_DLL *dll;
     const char *p;
diff --git a/if1632/comctl32.spec b/if1632/comctl32.spec
index 197247f..058365d 100644
--- a/if1632/comctl32.spec
+++ b/if1632/comctl32.spec
@@ -21,13 +21,15 @@
  15 stub DrawInsert
  16 stdcall CreateUpDownControl(long long long long long long long long long long long long) CreateUpDownControl
  17 stdcall InitCommonControls() InitCommonControls
+# 18 pascal16 CreateStatusWindow(word ptr word word) CreateStatusWindow16
  18 stub CreateStatusWindow
- 19 stub CreateStatusWindowW
+ 19 stdcall CreateStatusWindowW(long ptr long long) CreateStatusWindow32W
  20 stub CreateToolbarEx
  21 stub DestroyPropertySheetPage
  22 stub DllGetVersion
+# 23 pascal16 DrawStatusText(word ptr ptr word) DrawStatusText16
  23 stub DrawStatusText
- 24 stub DrawStatusTextW
+ 24 stdcall DrawStatusTextW(long ptr ptr long) DrawStatusText32W
  25 stub ImageList_Add
  26 stub ImageList_AddIcon
  27 stub ImageList_AddMasked
diff --git a/if1632/comdlg32.spec b/if1632/comdlg32.spec
index e7136ab..bcb0a91 100644
--- a/if1632/comdlg32.spec
+++ b/if1632/comdlg32.spec
@@ -18,8 +18,8 @@
 14 stub LoadAlterBitmap
 15 stub PageSetupDlgA
 16 stub PageSetupDlgW
-17 return PrintDlgA 4 0
-18 return PrintDlgW 4 0
+17 stdcall PrintDlgA(ptr) PrintDlg32A
+18 stdcall PrintDlgW(ptr) PrintDlg32W
 19 stub ReplaceTextA
 20 stub ReplaceTextW
 21 stub WantArrows
diff --git a/if1632/commdlg.spec b/if1632/commdlg.spec
index 1a705ea..9f8be62 100644
--- a/if1632/commdlg.spec
+++ b/if1632/commdlg.spec
@@ -16,7 +16,7 @@
 16  pascal16 FormatCharDlgProc(word word word long) FormatCharDlgProc
 18  pascal16 FontStyleEnumProc(ptr ptr word long)   FontStyleEnumProc
 19  pascal16 FontFamilyEnumProc(ptr ptr word long)  FontFamilyEnumProc
-20  pascal16 PrintDlg(segptr) PrintDlg
+20  pascal16 PrintDlg(segptr) PrintDlg16
 21  pascal   PrintDlgProc(word word word long) PrintDlgProc
 22  pascal   PrintSetupDlgProc(word word word long) PrintSetupDlgProc
 #23  pascal  EDITINTEGERONLY exported, shared data
diff --git a/if1632/crtdll.spec b/if1632/crtdll.spec
index da626f5..566e2df 100644
--- a/if1632/crtdll.spec
+++ b/if1632/crtdll.spec
@@ -60,7 +60,7 @@
  56 stub _clearfp
  57 cdecl _close(long) CRTDLL__close
  58 stub _commit
- 59 long _commode_dll(0)
+ 59 extern _commode_dll CRTDLL_commode_dll
  60 stub _control87
  61 stub _controlfp
  62 stub _copysign
@@ -105,7 +105,7 @@
 101 stub _finite
 102 stub _flsbuf
 103 stub _flushall
-104 long _fmode_dll(0)
+104 extern _fmode_dll CRTDLL_fmode_dll
 105 stub _fpclass
 106 stub _fpieee_flt
 107 stub _fpreset
@@ -130,7 +130,7 @@
 126 stub _getpid
 127 stub _getsystime
 128 stub _getw
-129 register _global_unwind2(ptr) CRTDLL__global_unwind2
+129 register _global_unwind2() CRTDLL__global_unwind2
 130 stub _heapchk
 131 stub _heapmin
 132 stub _heapset
@@ -174,7 +174,7 @@
 170 stub _kbhit
 171 stub _lfind
 172 stub _loaddll
-173 register _local_unwind2(ptr long) CRTDLL__local_unwind2
+173 register _local_unwind2() CRTDLL__local_unwind2
 174 stub _locking
 175 stub _logb
 176 cdecl _lrotl (long long) CRTDLL__lrotl
@@ -244,7 +244,7 @@
 240 cdecl _open_osfhandle(long long) CRTDLL__open_osfhandle
 241 extern _osmajor_dll CRTDLL_osmajor_dll
 242 extern _osminor_dll CRTDLL_osminor_dll
-243 long _osmode_dll(0)
+243 extern _osmode_dll CRTDLL_osmode_dll
 244 extern _osver_dll CRTDLL_osver_dll
 245 extern _osversion_dll CRTDLL_osversion_dll
 246 stub _pclose
@@ -459,7 +459,7 @@
 455 cdecl signal(long ptr) CRTDLL_signal
 456 cdecl sin(double) sin
 457 cdecl sinh(double) sinh
-458 varargs sprintf() wsprintf32A
+458 varargs sprintf() sprintf
 459 cdecl sqrt(double) sqrt
 460 cdecl srand(long) CRTDLL_srand
 461 varargs sscanf() sscanf
diff --git a/if1632/ddeml.spec b/if1632/ddeml.spec
index 8da729c..46c2420 100644
--- a/if1632/ddeml.spec
+++ b/if1632/ddeml.spec
@@ -1,16 +1,17 @@
 name	ddeml
 type	win16
 
-2 stub DdeInitialize #(ptr segptr long long) DdeInitialize
-3 stub DdeUnInitialize #(long) DdeUnInitialize
+2 pascal16 DdeInitialize(ptr segptr long long) DdeInitialize16
+3 pascal16 DdeUninitialize(long) DdeUninitialize16
 4 stub DdeConnectList #(long word word word ptr) DdeConnectList
 5 stub DdeQueryNextServer #(word word) DdeQueryNextServer
 6 stub DdeDisconnectList #(word) DdeDisconnectList
-7 stub DdeConnect #(long word word ptr) DdeConnect
-8 stub DdeDisconnect #(word) DdeDisconnect
+7 pascal   DdeConnect(long long long ptr) DdeConnect16
+8 pascal16 DdeDisconnect(long) DdeDisconnect16
 9 stub DdeQueryConvInfo #(word long ptr) DdeQueryConvInfo
 10 stub DdeSetUserHandle #(word long long) DdeSetUserHandle
-11 stub DdeClientTransaction #(ptr long word word word word long ptr) DdeClientTransaction
+11 pascal   DdeClientTransaction(ptr long long long s_word s_word long ptr)
+            DdeClientTransaction16
 12 stub DdeAbandonTransaction #(long word long) DdeAbandonTransaction
 13 stub DdePostAdvise #(long word word) DdePostAdvise
 14 stub DdeCreateDataHandle #(long ptr long long word word word) DdeCreateDataHandle
@@ -18,15 +19,15 @@
 16 stub DdeGetData #(word ptr long long) DdeGetData
 17 stub DdeAccessData #(word ptr) DdeAccessData
 18 stub DdeUnaccessData #(word) DdeUnaccessData
-19 stub DdeFreeDataHandle #(word) DdeFreeDataHandle
-20 stub DdeGetLastError #(long) DdeGetLastError
-21 stub DdeCreateStringHandle #(long str word) DdeCreateStringHandle
-22 stub DdeFreeStringHandle #(long word) DdeFreeStringHandle
+19 pascal16 DdeFreeDataHandle(long) DdeFreeDataHandle16
+20 pascal16 DdeGetLastError(long) DdeGetLastError16
+21 pascal   DdeCreateStringHandle(long str s_word) DdeCreateStringHandle16
+22 pascal16 DdeFreeStringHandle(long long) DdeFreeStringHandle16
 23 stub DdeQueryString #(long word ptr long word) DdeQueryString
-24 stub DdeKeepStringHandle #(long word) DdeKeepStringHandle
+24 pascal16 DdeKeepStringHandle(long long) DdeKeepStringHandle16
 
 26 stub DdeEnableCallback #(long word word) DdeEnableCallback
-27 stub DdeNameService #(long word word word)
+27 pascal   DdeNameService(long long long s_word) DdeNameService16
 
 36 stub DdeCmpStringHandles #(word word) DdeCmpStringHandles
-37 stub DdeReconnect #(word) DdeReconnect
+37 pascal   DdeReconnect(long) DdeReconnect
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index eedf981..f365ed9 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -287,7 +287,7 @@
 451 pascal16 CreatePolyPolygonRgn(ptr ptr word word) CreatePolyPolygonRgn16
 452 stub GDISEEGDIDO
 460 stub GDITASKTERMINATION
-461 return SetObjectOwner 4 0
+461 pascal16 SetObjectOwner(word word) SetObjectOwner16
 462 pascal16 IsGDIObject(word) IsGDIObject
 463 stub MAKEOBJECTPRIVATE
 464 stub FIXUPBOGUSPUBLISHERMETAFILE
diff --git a/if1632/gdi32.spec b/if1632/gdi32.spec
index 1380cdb..7d7851a 100644
--- a/if1632/gdi32.spec
+++ b/if1632/gdi32.spec
@@ -133,7 +133,7 @@
 126 stub GdiDeleteLocalDC
 127 stub GdiDeleteLocalObject
 128 stub GdiFlush
-129 return GdiGetBatchLimit 0 1
+129 stdcall GdiGetBatchLimit() GdiGetBatchLimit
 130 stub GdiGetLocalBrush
 131 stub GdiGetLocalDC
 132 stub GdiGetLocalFont
@@ -143,7 +143,7 @@
 136 stub GdiPlayScript
 137 stub GdiReleaseLocalDC
 138 stub GdiSetAttrs
-139 return GdiSetBatchLimit 4 1
+139 stdcall GdiSetBatchLimit(long) GdiSetBatchLimit
 140 stub GdiSetServerAttr
 141 stub GetArcDirection
 142 stub GetAspectRatioFilterEx
@@ -192,7 +192,7 @@
 185 stub GetGlyphOutline
 186 stdcall GetGlyphOutlineA(long long long ptr long ptr ptr) GetGlyphOutline32A
 187 stdcall GetGlyphOutlineW(long long long ptr long ptr ptr) GetGlyphOutline32W
-188 return GetGraphicsMode 4 1 	# just return 1
+188 stdcall GetGraphicsMode(long) GetGraphicsMode
 189 stub GetICMProfileA
 190 stub GetICMProfileW
 191 stub GetKerningPairs
@@ -248,7 +248,7 @@
 241 stub GetWinMetaFileBits
 242 stdcall GetWindowExtEx(long ptr) GetWindowExtEx32
 243 stdcall GetWindowOrgEx(long ptr) GetWindowOrgEx32
-244 return GetWorldTransform 8 0
+244 stdcall GetWorldTransform(long ptr) GetWorldTransform
 245 stdcall IntersectClipRect(long long long long long) IntersectClipRect32
 246 stdcall InvertRgn(long long) InvertRgn32
 247 stdcall LPtoDP(long ptr long) LPtoDP32
@@ -322,7 +322,7 @@
 314 stub SetDeviceGammaRamp
 315 stub SetEnhMetaFileBits
 316 stub SetFontEnumeration
-317 return SetGraphicsMode 8 1
+317 stdcall SetGraphicsMode(long long) SetGraphicsMode
 318 stub SetICMMode
 319 stub SetICMProfileA
 320 stub SetICMProfileW
@@ -394,4 +394,4 @@
 383 stub UpdateICMRegKeyA
 384 stub UpdateICMRegKeyW
 385 stub gdiPlaySpoolStream
-386 return SetObjectOwner 8 0
+386 stdcall SetObjectOwner(long long) SetObjectOwner32
diff --git a/if1632/kernel32.spec b/if1632/kernel32.spec
index 84a265c..8652559 100644
--- a/if1632/kernel32.spec
+++ b/if1632/kernel32.spec
@@ -555,7 +555,7 @@
 564 stdcall QueryPerformanceCounter(ptr) QueryPerformanceCounter
 565 stub QueryPerformanceFrequency
 566 stub QueueUserAPC
-567 register RaiseException(long long long ptr) RaiseException
+567 register RaiseException() EXC_RaiseException
 568 stdcall ReadConsoleA(long ptr long ptr ptr) ReadConsole32A
 569 stub ReadConsoleInputA
 570 stub ReadConsoleInputW
@@ -578,7 +578,7 @@
 587 stdcall ResumeThread(long) ResumeThread
 588 stdcall RtlFillMemory(ptr long long) RtlFillMemory
 589 stdcall RtlMoveMemory(ptr ptr long) RtlMoveMemory
-590 register RtlUnwind(ptr long ptr long) RtlUnwind
+590 register RtlUnwind() EXC_RtlUnwind
 591 stdcall RtlZeroMemory(ptr long) RtlZeroMemory
 592 register SMapLS() SMapLS
 593 register SMapLS_IP_EBP_12() SMapLS_IP_EBP_12
diff --git a/if1632/ntdll.spec b/if1632/ntdll.spec
index ebe55e9..3d71013 100644
--- a/if1632/ntdll.spec
+++ b/if1632/ntdll.spec
@@ -862,7 +862,7 @@
 859 stub __eFYL2XP1
 860 stub __eGetStatusWord
 861 stub _alloca_probe
-862 return _chkstk 0 0
+862 cdecl _chkstk() NTDLL_chkstk
 863 stub _fltused
 864 stub _ftol
 865 stub _itoa
diff --git a/if1632/ole32.spec b/if1632/ole32.spec
index 4595e4f..300d3ee 100644
--- a/if1632/ole32.spec
+++ b/if1632/ole32.spec
@@ -108,7 +108,7 @@
 105 stub OleGetClipboard
 106 stub OleGetIconOfClass
 107 stub OleGetIconOfFile
-108 return OleInitialize 4 0
+108 stdcall OleInitialize(ptr) OleInitialize
 109 stub OleInitializeWOW
 110 stub OleIsCurrentClipboard
 111 stub OleIsRunning
@@ -131,7 +131,7 @@
 128 stub OleSetContainedObject
 129 stub OleSetMenuDescriptor
 130 stub OleTranslateAccelerator
-131 return OleUninitialize 0 0
+131 stdcall OleUninitialize() OleUninitialize
 132 stub OpenOrCreateStream
 133 stub ProgIDFromCLSID
 134 stub ReadClassStg
diff --git a/if1632/relay.c b/if1632/relay.c
index 09a83c2..2018c73 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -3,6 +3,7 @@
  * Copyright 1995 Alexandre Julliard
  */
 
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include "windows.h"
@@ -33,8 +34,10 @@
       /* Allocate the code selector for CallTo16 routines */
 
     extern void CALLTO16_Start(), CALLTO16_End();
-    extern void CALLTO16_Ret_word(), CALLTO16_Ret_long();
-    extern DWORD CALLTO16_RetAddr_word, CALLTO16_RetAddr_long;
+    extern void CALLTO16_Ret_word(), CALLTO16_Ret_long(), CALLTO16_Ret_regs();
+    extern DWORD CALLTO16_RetAddr_word;
+    extern DWORD CALLTO16_RetAddr_long;
+    extern DWORD CALLTO16_RetAddr_regs;
 
     codesel = GLOBAL_CreateBlock( GMEM_FIXED, (void *)CALLTO16_Start,
                                    (int)CALLTO16_End - (int)CALLTO16_Start,
@@ -47,6 +50,8 @@
                                     codesel );
     CALLTO16_RetAddr_long=MAKELONG( (int)CALLTO16_Ret_long-(int)CALLTO16_Start,
                                     codesel );
+    CALLTO16_RetAddr_regs=MAKELONG( (int)CALLTO16_Ret_regs-(int)CALLTO16_Start,
+                                    codesel );
 
     /* Initialize thunking */
 
@@ -71,7 +76,7 @@
     printf( "Call %s(", BUILTIN_GetEntryPoint16( frame->entry_cs,
                                                  frame->entry_ip,
                                                  &ordinal ));
-    args16 = (char *)frame->args;
+    VA_START16( args16 );
     for (i = 0; i < strlen(args); i++)
     {
         switch(args[i])
@@ -123,6 +128,7 @@
         if (*args) printf( "," );
     }
     printf( ") ret=%04x:%04x ds=%04x\n", frame->cs, frame->ip, frame->ds );
+    VA_END16( args16 );
 
     if (func_type == 2)  /* register function */
         printf( "     AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n",
@@ -185,22 +191,6 @@
 
 
 /***********************************************************************
- *           RELAY_Unimplemented32
- *
- * This function is called for unimplemented 32-bit entry points (declared
- * as 'stub' in the spec file).
- * (The args are the same than for RELAY_DebugCallFrom32).
- */
-void RELAY_Unimplemented32( void *relay_addr, void *entry_point,
-                            int ebp, int ret_addr )
-{
-    fprintf( stderr, "No handler for Win32 routine %s (called from %08x)\n",
-             BUILTIN_GetEntryPoint32( relay_addr ), ret_addr );
-    TASK_KillCurrentTask(1);
-}
-
-
-/***********************************************************************
  *           RELAY_DebugCallTo16
  *
  * 'stack' points to the called function address on the 32-bit stack.
@@ -241,73 +231,191 @@
 
 
 /***********************************************************************
- *           RELAY_DebugCallFrom32
+ *           RELAY_CallFrom32
  *
- * 'stack' points to the saved ebp on the stack.
- * Stack layout:
- *  ...        ...
- * (stack+12)  arg2
- * (stack+8)   arg1
- * (stack+4)   ret addr
- * (stack)     ebp
- * (stack-4)   entry point
- * (stack-8)   relay addr
+ * Stack layout on entry to this function:
+ *  ...      ...
+ * (esp+12)  arg2
+ * (esp+8)   arg1
+ * (esp+4)   ret_addr
+ * (esp)     return addr to relay code
  */
-void RELAY_DebugCallFrom32( int *stack, int nb_args )
+int RELAY_CallFrom32( int ret_addr, ... )
 {
-    int *parg, i;
+    int i, ret;
+    char buffer[80];
+    FARPROC32 func;
 
-    if (!debugging_relay) return;
-    printf( "Call %s(", BUILTIN_GetEntryPoint32( (void *)stack[-2] ));
-    for (i = nb_args & 0x7fffffff, parg = &stack[2]; i; parg++, i--)
+    int *args = &ret_addr;
+    /* Relay addr is the return address for this function */
+    BYTE *relay_addr = (BYTE *)args[-1];
+    WORD nb_args = *(WORD *)(relay_addr + 1) / sizeof(int);
+
+    assert(debugging_relay);
+    func = BUILTIN_GetEntryPoint32( buffer, relay_addr - 5 );
+    printf( "Call %s(", buffer );
+    args++;
+    for (i = 0; i < nb_args; i++)
     {
-        printf( "%08x", *parg );
-        if (i > 1) printf( "," );
+        if (i) printf( "," );
+        printf( "%08x", args[i] );
     }
-    printf( ") ret=%08x\n", stack[1] );
-    if (nb_args & 0x80000000)  /* Register function */
+    printf( ") ret=%08x\n", ret_addr );
+    if (*relay_addr == 0xc3) /* cdecl */
     {
-        CONTEXT *context = (CONTEXT *)((BYTE *)stack - sizeof(CONTEXT) - 8);
-        printf( " EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx ESI=%08lx EDI=%08lx\n",
-                context->Eax, context->Ebx, context->Ecx, context->Edx,
-                context->Esi, context->Edi );
-        printf( " EBP=%08lx ESP=%08lx EIP=%08lx DS=%04lx ES=%04lx FS=%04lx GS=%04lx EFL=%08lx\n",
-                context->Ebp, context->Esp, context->Eip, context->SegDs,
-                context->SegEs, context->SegFs, context->SegGs,
-                context->EFlags );
+        LRESULT (*cfunc)() = (LRESULT(*)())func;
+        switch(nb_args)
+        {
+        case 0: ret = cfunc(); break;
+        case 1: ret = cfunc(args[0]); break;
+        case 2: ret = cfunc(args[0],args[1]); break;
+        case 3: ret = cfunc(args[0],args[1],args[2]); break;
+        case 4: ret = cfunc(args[0],args[1],args[2],args[3]); break;
+        case 5: ret = cfunc(args[0],args[1],args[2],args[3],args[4]); break;
+        case 6: ret = cfunc(args[0],args[1],args[2],args[3],args[4],
+                            args[5]); break;
+        case 7: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
+                            args[6]); break;
+        case 8: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
+                            args[6],args[7]); break;
+        case 9: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
+                            args[6],args[7],args[8]); break;
+        case 10: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
+                             args[6],args[7],args[8],args[9]); break;
+        case 11: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
+                             args[6],args[7],args[8],args[9],args[10]); break;
+        case 12: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
+                             args[6],args[7],args[8],args[9],args[10],
+                             args[11]); break;
+        case 13: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
+                             args[6],args[7],args[8],args[9],args[10],args[11],
+                             args[12]); break;
+        case 14: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
+                             args[6],args[7],args[8],args[9],args[10],args[11],
+                             args[12],args[13]); break;
+        case 15: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
+                             args[6],args[7],args[8],args[9],args[10],args[11],
+                             args[12],args[13],args[14]); break;
+        default:
+            fprintf( stderr, "RELAY_CallFrom32: Unsupported nb args %d\n",
+                     nb_args );
+            assert(FALSE);
+        }
+    }
+    else  /* stdcall */
+    {
+        switch(nb_args)
+        {
+        case 0: ret = func(); break;
+        case 1: ret = func(args[0]); break;
+        case 2: ret = func(args[0],args[1]); break;
+        case 3: ret = func(args[0],args[1],args[2]); break;
+        case 4: ret = func(args[0],args[1],args[2],args[3]); break;
+        case 5: ret = func(args[0],args[1],args[2],args[3],args[4]); break;
+        case 6: ret = func(args[0],args[1],args[2],args[3],args[4],
+                           args[5]); break;
+        case 7: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
+                           args[6]); break;
+        case 8: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
+                           args[6],args[7]); break;
+        case 9: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
+                           args[6],args[7],args[8]); break;
+        case 10: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
+                            args[6],args[7],args[8],args[9]); break;
+        case 11: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
+                            args[6],args[7],args[8],args[9],args[10]); break;
+        case 12: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
+                            args[6],args[7],args[8],args[9],args[10],
+                            args[11]); break;
+        case 13: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
+                            args[6],args[7],args[8],args[9],args[10],args[11],
+                            args[12]); break;
+        case 14: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
+                            args[6],args[7],args[8],args[9],args[10],args[11],
+                            args[12],args[13]); break;
+        case 15: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
+                            args[6],args[7],args[8],args[9],args[10],args[11],
+                            args[12],args[13],args[14]); break;
+        default:
+            fprintf( stderr, "RELAY_CallFrom32: Unsupported nb args %d\n",
+                     nb_args );
+            assert(FALSE);
+        }
+    }
+    printf( "Ret  %s() retval=%08x ret=%08x\n", buffer, ret, ret_addr );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           RELAY_CallFrom32Regs
+ *
+ * 'stack' points to the relay addr on the stack.
+ * Stack layout:
+ *  ...      ...
+ * (esp+216) ret_addr
+ * (esp+212) return to relay debugging code (only when debugging_relay)
+ * (esp+208) entry point to call
+ * (esp+4)   CONTEXT
+ * (esp)     return addr to relay code
+ */
+void RELAY_CallFrom32Regs( CONTEXT context,
+                           void (CALLBACK *entry_point)(CONTEXT *),
+                           BYTE *relay_addr, int ret_addr )
+{
+    if (!debugging_relay)
+    {
+        /* Simply call the entry point */
+        entry_point( &context );
+    }
+    else
+    {
+        char buffer[80];
+
+        /* 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 );
+        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),
+                EDX_reg(&context), ESI_reg(&context), EDI_reg(&context) );
+        printf(" EBP=%08lx ESP=%08lx EIP=%08lx DS=%04lx ES=%04lx FS=%04lx GS=%04lx EFL=%08lx\n",
+                EBP_reg(&context), ESP_reg(&context), EIP_reg(&context),
+                DS_reg(&context), ES_reg(&context), FS_reg(&context),
+                GS_reg(&context), EFL_reg(&context) );
+
+        /* Now call the real function */
+        entry_point( &context );
+
+        printf("Ret  %s() retval=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),
+                EDX_reg(&context), ESI_reg(&context), EDI_reg(&context) );
+        printf(" EBP=%08lx ESP=%08lx EIP=%08lx DS=%04lx ES=%04lx FS=%04lx GS=%04lx EFL=%08lx\n",
+                EBP_reg(&context), ESP_reg(&context), EIP_reg(&context),
+                DS_reg(&context), ES_reg(&context), FS_reg(&context),
+                GS_reg(&context), EFL_reg(&context) );
     }
 }
 
 
 /***********************************************************************
- *           RELAY_DebugCallFrom32Ret
+ *           RELAY_Unimplemented32
  *
- * 'stack' points to the saved ebp on the stack.
- * Stack layout:
- *  ...        ...
- * (stack+12)  arg2
- * (stack+8)   arg1
- * (stack+4)   ret addr
- * (stack)     ebp
- * (stack-4)   entry point
- * (stack-8)   relay addr
+ * This function is called for unimplemented 32-bit entry points (declared
+ * as 'stub' in the spec file).
  */
-void RELAY_DebugCallFrom32Ret( int *stack, int nb_args, int ret_val )
+void RELAY_Unimplemented32( const char *dll_name, int ordinal,
+                            const char *func_name, int ret_addr )
 {
-    if (!debugging_relay) return;
-    printf( "Ret  %s() retval=%08x ret=%08x\n",
-            BUILTIN_GetEntryPoint32( (void *)stack[-2] ), ret_val, stack[1] );
-    if (nb_args & 0x80000000)  /* Register function */
-    {
-        CONTEXT *context = (CONTEXT *)((BYTE *)stack - sizeof(CONTEXT) - 8);
-        printf( " EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx ESI=%08lx EDI=%08lx\n",
-                context->Eax, context->Ebx, context->Ecx, context->Edx,
-                context->Esi, context->Edi );
-        printf( " EBP=%08lx ESP=%08lx EIP=%08lx DS=%04lx ES=%04lx FS=%04lx GS=%04lx EFL=%08lx\n",
-                context->Ebp, context->Esp, context->Eip, context->SegDs,
-                context->SegEs, context->SegFs, context->SegGs,
-                context->EFlags );
-    }
+    __RESTORE_ES;  /* Just in case */
+    fprintf( stderr, "No handler for Win32 routine %s.%d: %s (called from %08x)\n",
+             dll_name, ordinal, func_name, ret_addr );
+    TASK_KillCurrentTask(1);
 }
 
 
@@ -319,8 +427,15 @@
  */
 void WINAPI Catch( CONTEXT *context )
 {
+    VA_LIST16 valist;
+    SEGPTR buf;
+    LPCATCHBUF lpbuf;
     STACK16FRAME *pFrame = CURRENT_STACK16;
-    LPCATCHBUF lpbuf = (LPCATCHBUF)PTR_SEG_TO_LIN(*(SEGPTR *)pFrame->args);
+
+    VA_START16( valist );
+    buf   = VA_ARG16( valist, SEGPTR );
+    lpbuf = (LPCATCHBUF)PTR_SEG_TO_LIN( buf );
+    VA_END16( valist );
 
     /* Note: we don't save the current ss, as the catch buffer is */
     /* only 9 words long. Hopefully no one will have the silly    */
@@ -359,9 +474,16 @@
  */
 void WINAPI Throw( CONTEXT *context )
 {
-    STACK16FRAME *pFrame = CURRENT_STACK16;
-    LPCATCHBUF lpbuf = (LPCATCHBUF)PTR_SEG_TO_LIN(*(SEGPTR *)&pFrame->args[1]);
-    WORD retval = pFrame->args[0];
+    VA_LIST16 valist;
+    SEGPTR buf;
+    LPCATCHBUF lpbuf;
+    STACK16FRAME *pFrame;
+
+    VA_START16( valist );
+    AX_reg(context) = VA_ARG16( valist, WORD );  /* retval */
+    buf    = VA_ARG16( valist, SEGPTR );
+    lpbuf  = (LPCATCHBUF)PTR_SEG_TO_LIN( buf );
+    VA_END16( valist );
 
     IF1632_Saved16_ss_sp = MAKELONG( lpbuf[7] - sizeof(WORD),
                                      HIWORD(IF1632_Saved16_ss_sp) );
@@ -373,7 +495,6 @@
     SI_reg(context) = lpbuf[4];
     DI_reg(context) = lpbuf[5];
     DS_reg(context) = lpbuf[6];
-    AX_reg(context) = retval;
 
     if (debugging_relay)  /* Make sure we have a valid entry point address */
     {
@@ -392,26 +513,34 @@
  */
 DWORD WINAPI WIN16_CallProc32W()
 {
-	DWORD *win_stack = (DWORD *)CURRENT_STACK16->args;
-	DWORD	nrofargs = win_stack[0];
-	DWORD	argconvmask = win_stack[1];
-	FARPROC32	proc32 = (FARPROC32)win_stack[2];
-	DWORD	*args,ret;
-        STACK16FRAME stf16;
-	int	i;
+	DWORD nrofargs, argconvmask;
+	FARPROC32 proc32;
+	DWORD *args, ret;
+        VA_LIST16 valist;
+	int i;
 
+        VA_START16( valist );
+        nrofargs    = VA_ARG16( valist, DWORD );
+        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--;) {
-		if (argconvmask & (1<<i)) {
-			args[nrofargs-i-1] = (DWORD)PTR_SEG_TO_LIN(win_stack[3+i]);
-			fprintf(stderr,"%08lx(%p),",win_stack[3+i],PTR_SEG_TO_LIN(win_stack[3+i]));
-		} else {
-			args[nrofargs-i-1] = win_stack[3+i];
-			fprintf(stderr,"%ld,",win_stack[3+i]);
+		if (argconvmask & (1<<i))
+                {
+                    SEGPTR ptr = VA_ARG16( valist, SEGPTR );
+                    args[nrofargs-i-1] = (DWORD)PTR_SEG_TO_LIN(ptr);
+                    fprintf(stderr,"%08lx(%p),",ptr,PTR_SEG_TO_LIN(ptr));
+		}
+                else
+                {
+                    args[nrofargs-i-1] = VA_ARG16( valist, DWORD );
+                    fprintf(stderr,"%ld,",args[nrofargs-i-1]);
 		}
 	}
 	fprintf(stderr,"]) - ");
+        VA_END16( valist );
+
 	switch (nrofargs) {
 	case 0: ret = proc32();
 		break;
@@ -436,14 +565,7 @@
 		break;
 	}
 	/* POP nrofargs DWORD arguments and 3 DWORD parameters */
-	/* FIXME: this is a BAD hack, but I don't see any other way to
-	 * pop a variable number of arguments.  -MM
-	 * The -2 in the size is for not copying WORD args[0] (which would
-	 * overwrite the top WORD on the return stack)
-	 */
-	memcpy(&stf16,CURRENT_STACK16,sizeof(stf16)-2);
-	IF1632_Saved16_ss_sp += (3+nrofargs)*sizeof(DWORD);
-	memcpy(CURRENT_STACK16,&stf16,sizeof(stf16)-2);
+        STACK16_POP( (3 + nrofargs) * sizeof(DWORD) );
 
 	fprintf(stderr,"returns %08lx\n",ret);
 	free(args);
diff --git a/if1632/shell32.spec b/if1632/shell32.spec
index ed55b9b..d538fbf 100644
--- a/if1632/shell32.spec
+++ b/if1632/shell32.spec
@@ -55,7 +55,7 @@
  185 stub SHELL32_185
  186 stdcall FindExecutableA(ptr ptr ptr) FindExecutable32A
  187 stub FindExecutableW
- 188 return FreeIconList 4 0
+ 188 stdcall FreeIconList(long) FreeIconList
  189 stub InternalExtractIconListA
  190 stub InternalExtractIconListW
  191 stub OpenAs_RunDLL
diff --git a/if1632/thunk.c b/if1632/thunk.c
index 2da1a3d..088ecbc 100644
--- a/if1632/thunk.c
+++ b/if1632/thunk.c
@@ -143,9 +143,8 @@
         /* "Undocumented Windows" examples) want it that way.  */
         CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
         offset = sizeof(*cs);
-        memcpy( (char *)CURRENT_STACK16 - offset, cs, offset );
-        IF1632_Saved16_ss_sp -= offset;
-        lParam = IF1632_Saved16_ss_sp;
+        lParam = STACK16_PUSH( offset );
+        memcpy( PTR_SEG_TO_LIN(lParam), cs, offset );
     }
     args = (WORD *)CURRENT_STACK16 - 7;
     args[0] = LOWORD(lParam);
@@ -156,7 +155,7 @@
     /* args[5] and args[6] are used by relay code to store the stack pointer */
 
     ret = CallTo16_regs_( &context, -(5 * sizeof(WORD)) );
-    IF1632_Saved16_ss_sp += offset;
+    if (offset) STACK16_POP(offset);
     return ret;
 }
 
diff --git a/if1632/user.spec b/if1632/user.spec
index a354415..69d5bc7 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -232,7 +232,7 @@
 228 pascal16 GetNextDlgTabItem(word word word) GetNextDlgTabItem16
 229 pascal16 GetTopWindow(word) GetTopWindow16
 230 pascal16 GetNextWindow(word word) GetNextWindow16
-231 stub GetSystemDebugState
+231 return GetSystemDebugState 0 0  #FIXME
 232 pascal16 SetWindowPos(word word word word word word word) SetWindowPos16
 233 pascal16 SetParent(word word) SetParent16
 234 pascal16 UnhookWindowsHook(s_word segptr) THUNK_UnhookWindowsHook16
@@ -465,14 +465,14 @@
 532 pascal16 WNetGetPropertyText(word word word ptr word) WNetGetPropertyText
 533 stub WNetInitialize
 534 stub WNetLogon
-600 stub GetShellWindow
+600 pascal16 GetShellWindow() GetShellWindow16
 601 stub DoHotkeyStuff
 602 stub SetCheckCursorTimer
 604 stub BroadcastSystemMessage
 605 stub HackTaskMonitor
 606 stub FormatMessage
-608 stub GetForegroundWindow
-609 stub SetForegroundWindow
+608 pascal16 GetForegroundWindow() GetForegroundWindow16
+609 pascal16 SetForegroundWindow(word) SetForegroundWindow16
 610 stub DestroyIcon32
 620 stub ChangeDisplaySettings
 621 stub EnumDisplaySettings
diff --git a/if1632/user32.spec b/if1632/user32.spec
index b00e5d8..5bc484e 100644
--- a/if1632/user32.spec
+++ b/if1632/user32.spec
@@ -92,36 +92,36 @@
  87 stub DdeAbandonTransaction
  88 stub DdeAccessData
  89 stub DdeAddData
- 90 return DdeClientTransaction 32 0
+ 90 stdcall DdeClientTransaction(ptr long long long long long long ptr) DdeClientTransaction32
  91 stub DdeCmpStringHandles
- 92 return DdeConnect 16 0
+ 92 stdcall DdeConnect(long long long ptr) DdeConnect32
  93 stub DdeConnectList
  94 stub DdeCreateDataHandle
- 95 return DdeCreateStringHandleA 12 0
- 96 return DdeCreateStringHandleW 12 0
- 97 return DdeDisconnect 4 0
+ 95 stdcall DdeCreateStringHandleA(long ptr long) DdeCreateStringHandle32A
+ 96 stdcall DdeCreateStringHandleW(long ptr long) DdeCreateStringHandle32W
+ 97 stdcall DdeDisconnect(long) DdeDisconnect32
  98 stub DdeDisconnectList
  99 stub DdeEnableCallback
-100 return DdeFreeDataHandle 4 1
-101 return DdeFreeStringHandle 8 0
+100 stdcall DdeFreeDataHandle(long) DdeFreeDataHandle32
+101 stdcall DdeFreeStringHandle(long long) DdeFreeStringHandle32
 102 stub DdeGetData
-103 return DdeGetLastError 4 0
+103 stdcall DdeGetLastError(long) DdeGetLastError32
 104 stub DdeGetQualityOfService
 105 stub DdeImpersonateClient
-106 return DdeInitializeA 16 0
-107 return DdeInitializeW 16 0
-108 stub DdeKeepStringHandle
-109 return DdeNameService 16 0
+106 stdcall DdeInitializeA(ptr ptr long long) DdeInitialize32A
+107 stdcall DdeInitializeW(ptr ptr long long) DdeInitialize32W
+108 stdcall DdeKeepStringHandle(long long) DdeKeepStringHandle32
+109 stdcall DdeNameService(long long long long) DdeNameService32
 110 stub DdePostAdvise
 111 stub DdeQueryConvInfo
 112 stub DdeQueryNextServer
 113 stub DdeQueryStringA
 114 stub DdeQueryStringW
-115 stub DdeReconnect
+115 stdcall DdeReconnect(long) DdeReconnect
 116 stub DdeSetQualityOfService
 117 stub DdeSetUserHandle
 118 stub DdeUnaccessData
-119 return DdeUninitialize 4 0
+119 stdcall DdeUninitialize(long) DdeUninitialize32
 120 stdcall DefDlgProcA(long long long long) DefDlgProc32A
 121 stdcall DefDlgProcW(long long long long) DefDlgProc32W
 122 stdcall DefFrameProcA(long long long long long) DefFrameProc32A
@@ -243,7 +243,7 @@
 238 stdcall GetDlgItemTextW(long long ptr long) GetDlgItemText32W
 239 stdcall GetDoubleClickTime() GetDoubleClickTime32
 240 stdcall GetFocus() GetFocus32
-241 return GetForegroundWindow 0 0		#FIXME
+241 stdcall GetForegroundWindow() GetForegroundWindow32
 242 stub GetIconInfo
 243 stub GetInputDesktop
 244 stdcall GetInputState() GetInputState32
@@ -289,7 +289,7 @@
 284 stdcall GetScrollInfo(long long ptr) GetScrollInfo32
 285 stdcall GetScrollPos(long long) GetScrollPos32
 286 stdcall GetScrollRange(long long ptr ptr) GetScrollRange32
-287 return GetShellWindow 0 0
+287 stdcall GetShellWindow() GetShellWindow32
 288 stdcall GetSubMenu(long long) GetSubMenu32
 289 stdcall GetSysColor(long) GetSysColor32
 290 stdcall GetSysColorBrush(long) GetSysColorBrush32
@@ -484,7 +484,7 @@
 479 stdcall SetDlgItemTextW(long long ptr) SetDlgItemText32W
 480 stdcall SetDoubleClickTime(long) SetDoubleClickTime32
 481 stdcall SetFocus(long) SetFocus32
-482 return SetForegroundWindow 4 0
+482 stdcall SetForegroundWindow(long) SetForegroundWindow32
 483 stdcall SetInternalWindowPos(long long ptr ptr) SetInternalWindowPos32
 484 stdcall SetKeyboardState(ptr) SetKeyboardState
 485 stdcall SetLastErrorEx(long long) SetLastErrorEx
diff --git a/if1632/wprocs.spec b/if1632/wprocs.spec
index ea41aeb..351c974 100644
--- a/if1632/wprocs.spec
+++ b/if1632/wprocs.spec
@@ -38,7 +38,7 @@
 118 register INT_Int12Handler(word) INT_Int12Handler
 119 register INT_Int13Handler(word) INT_Int13Handler
 120 register INT_Int14Handler(word) BUILTIN_DefaultIntHandler
-121 register INT_Int15Handler(word) BUILTIN_DefaultIntHandler
+121 register INT_Int15Handler(word) INT_Int15Handler
 122 register INT_Int16Handler(word) BUILTIN_DefaultIntHandler
 123 register INT_Int17Handler(word) BUILTIN_DefaultIntHandler
 124 register INT_Int18Handler(word) BUILTIN_DefaultIntHandler
diff --git a/include/arch.h b/include/arch.h
deleted file mode 100644
index fc7c5cb..0000000
--- a/include/arch.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Machine dependent integer conversions
- *
- * Copyright Miguel de Icaza, 1994
-*/
-
-#if defined (mc68000) || defined (sparc)
-
-#define CONV_LONG(a) (((int)(a)&0xFF) << 24) | (((int)(a) & 0xFF00) << 8) | (((unsigned long)(a) & 0xFF0000) >> 8) | (((unsigned long)(a)&0xFF000000) >> 24) 
-#define CONV_SHORT(a) (((int)(a) & 0xFF) << 8) | (((unsigned long)(a) & 0xFF00) >> 8)
-#define CONV_CHAR_TO_LONG(x) ((unsigned long)(x) >> 24)
-#define CONV_SHORT_TO_LONG(x) ((unsigned long)(x) >> 16)
-
-#define CONV_BITMAPINFO(a) ARCH_ConvBitmapInfo(a)
-#define CONV_BITMAPCOREHEADER(a) ARCH_ConvCoreHeader(a)
-#else
-#define CONV_LONG(a) (a)
-#define CONV_SHORT(a) (a)
-#define CONV_CHAR_TO_LONG(a) (a)
-#define CONV_SHORT_TO_LONG(a) (a)
-
-#define CONV_BITMAPINFO(a)		/* */
-#define CONV_BITMAPCOREHEADER(a)	/* */
-#endif
diff --git a/include/callback.h b/include/callback.h
index 40bf782..e2e230e 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -45,9 +45,15 @@
 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 )
diff --git a/include/commctrl.h b/include/commctrl.h
index 80a3898..a8b0ae1 100644
--- a/include/commctrl.h
+++ b/include/commctrl.h
@@ -11,9 +11,9 @@
 
 /* StatusWindow */
 
-#define STATUSCLASSNAME16  "msctls_statusbar"
-#define STATUSCLASSNAME32A "msctls_statusbar32"
-#define STATUSCLASSNAME32W "msctls_statusbar32"
+#define STATUSCLASSNAME16     "msctls_statusbar"
+#define STATUSCLASSNAME32A    "msctls_statusbar32"
+#define STATUSCLASSNAME32W   L"msctls_statusbar32"       /*FIXME*/
 #define STATUSCLASSNAME WINELIB_NAME_AW(STATUSCLASSNAME)
 
 #define SB_SETTEXT32A         (WM_USER+1)
@@ -43,9 +43,9 @@
 
 /* UpDown */
 
-#define UPDOWN_CLASS32A       "msctls_updown32"
-#define UPDOWN_CLASS32W      L"msctls_updown32"
 #define UPDOWN_CLASS16        "msctls_updown"
+#define UPDOWN_CLASS32A       "msctls_updown32"
+#define UPDOWN_CLASS32W      L"msctls_updown32"   /*FIXME*/
 #define UPDOWN_CLASS          WINELIB_NAME_AW(UPDOWN_CLASS)
 
 typedef struct tagUDACCEL
@@ -96,12 +96,14 @@
  
 /* Functions prototypes */
 
+HWND16     WINAPI CreateStatusWindow16(INT16,LPCSTR,HWND16,UINT16);
 HWND32     WINAPI CreateStatusWindow32A(INT32,LPCSTR,HWND32,UINT32);
 HWND32     WINAPI CreateStatusWindow32W(INT32,LPCWSTR,HWND32,UINT32);
 #define    CreateStatusWindow WINELIB_NAME_AW(CreateStatusWindow)
 HWND32     WINAPI CreateUpDownControl(DWORD,INT32,INT32,INT32,INT32,
                                       HWND32,INT32,HINSTANCE32,HWND32,
                                       INT32,INT32,INT32);
+VOID       WINAPI DrawStatusText16(HDC16,LPRECT16,LPCSTR,UINT16);
 VOID       WINAPI DrawStatusText32A(HDC32,LPRECT32,LPCSTR,UINT32);
 VOID       WINAPI DrawStatusText32W(HDC32,LPRECT32,LPCWSTR,UINT32);
 #define    DrawStatusText WINELIB_NAME_AW(DrawStatusText)
diff --git a/include/commdlg.h b/include/commdlg.h
index 01d7bb7..2cac612 100644
--- a/include/commdlg.h
+++ b/include/commdlg.h
@@ -253,28 +253,80 @@
 #define CD_LBSELSUB      1
 #define CD_LBSELADD      2
 
-typedef struct {
-	DWORD 		lStructSize;
-	HWND16 		hwndOwner;
-	HGLOBAL16       hDevMode;
-	HGLOBAL16       hDevNames;
-	HDC16	       	hDC;
-	DWORD 		Flags;
-	UINT16		nFromPage;
-	UINT16		nToPage;
-	UINT16		nMinPage;
-	UINT16		nMaxPage;
-	UINT16		nCopies;
-	HINSTANCE16 	hInstance;
-	LPARAM 		lCustData;
-        WNDPROC16       lpfnPrintHook;
-        WNDPROC16       lpfnSetupHook;
-	SEGPTR 		lpPrintTemplateName;
-	SEGPTR 		lpSetupTemplateName;
-	HGLOBAL16       hPrintTemplate;
-	HGLOBAL16       hSetupTemplate;
-	} PRINTDLG;
-typedef PRINTDLG * LPPRINTDLG;
+typedef struct
+{
+    DWORD            lStructSize;
+    HWND16           hwndOwner;
+    HGLOBAL16        hDevMode;
+    HGLOBAL16        hDevNames;
+    HDC16            hDC;
+    DWORD            Flags;
+    WORD             nFromPage;
+    WORD             nToPage;
+    WORD             nMinPage;
+    WORD             nMaxPage;
+    WORD             nCopies;
+    HINSTANCE16      hInstance;
+    LPARAM           lCustData;
+    WNDPROC16        lpfnPrintHook;
+    WNDPROC16        lpfnSetupHook;
+    SEGPTR           lpPrintTemplateName;
+    SEGPTR           lpSetupTemplateName;
+    HGLOBAL16        hPrintTemplate;
+    HGLOBAL16        hSetupTemplate;
+} PRINTDLG16, *LPPRINTDLG16;
+
+typedef UINT32 (CALLBACK *LPPRINTHOOKPROC) (HWND32, UINT32, WPARAM32, LPARAM);
+typedef UINT32 (CALLBACK *LPSETUPHOOKPROC) (HWND32, UINT32, WPARAM32, LPARAM);
+
+typedef struct
+{
+    DWORD            lStructSize;
+    HWND32           hwndOwner;
+    HGLOBAL32        hDevMode;
+    HGLOBAL32        hDevNames;
+    HDC32            hDC;
+    DWORD            Flags;
+    WORD             nFromPage;
+    WORD             nToPage;
+    WORD             nMinPage;
+    WORD             nMaxPage;
+    WORD             nCopies;
+    HINSTANCE32      hInstance;
+    LPARAM           lCustData;
+    LPPRINTHOOKPROC  lpfnPrintHook;
+    LPSETUPHOOKPROC  lpfnSetupHook;
+    LPCSTR           lpPrintTemplateName;
+    LPCSTR           lpSetupTemplateName;
+    HGLOBAL32        hPrintTemplate;
+    HGLOBAL32        hSetupTemplate;
+} PRINTDLG32A, *LPPRINTDLG32A;
+
+typedef struct
+{
+    DWORD            lStructSize;
+    HWND32           hwndOwner;
+    HGLOBAL32        hDevMode;
+    HGLOBAL32        hDevNames;
+    HDC32            hDC;
+    DWORD            Flags;
+    WORD             nFromPage;
+    WORD             nToPage;
+    WORD             nMinPage;
+    WORD             nMaxPage;
+    WORD             nCopies;
+    HINSTANCE32      hInstance;
+    LPARAM           lCustData;
+    LPPRINTHOOKPROC  lpfnPrintHook;
+    LPSETUPHOOKPROC  lpfnSetupHook;
+    LPCWSTR          lpPrintTemplateName;
+    LPCWSTR          lpSetupTemplateName;
+    HGLOBAL32        hPrintTemplate;
+    HGLOBAL32        hSetupTemplate;
+} PRINTDLG32W, *LPPRINTDLG32W;
+
+DECL_WINELIB_TYPE_AW(PRINTDLG);
+DECL_WINELIB_TYPE_AW(LPPRINTDLG);
 
 #define PD_ALLPAGES                  0x00000000
 #define PD_SELECTION                 0x00000001
diff --git a/include/ddeml.h b/include/ddeml.h
new file mode 100644
index 0000000..d2d4d11
--- /dev/null
+++ b/include/ddeml.h
@@ -0,0 +1,85 @@
+/*
+ * DDEML library definitions
+ *
+ * Copyright 1997 Alexandre Julliard
+ */
+
+#ifndef __WINE__DDEML_H
+#define __WINE__DDEML_H
+
+#include "wintypes.h"
+
+typedef DWORD HCONVLIST;
+typedef DWORD HCONV;
+typedef DWORD HSZ;
+typedef DWORD HDDEDATA;
+
+typedef HDDEDATA (CALLBACK *PFNCALLBACK16)(UINT16,UINT16,HCONV,HSZ,HSZ,
+                                           HDDEDATA,DWORD,DWORD);
+typedef HDDEDATA (CALLBACK *PFNCALLBACK32)(UINT32,UINT32,HCONV,HSZ,HSZ,
+                                           HDDEDATA,DWORD,DWORD);
+DECL_WINELIB_TYPE(PFNCALLBACK);
+
+typedef struct
+{
+    UINT16  cb;
+    UINT16  wFlags;
+    UINT16  wCountryID;
+    INT16   iCodePage;
+    DWORD   dwLangID;
+    DWORD   dwSecurity;
+} CONVCONTEXT16, *LPCONVCONTEXT16;
+
+typedef struct
+{
+    UINT32  cb;
+    UINT32  wFlags;
+    UINT32  wCountryID;
+    INT32   iCodePage;
+    DWORD   dwLangID;
+    DWORD   dwSecurity;
+} CONVCONTEXT32, *LPCONVCONTEXT32;
+
+DECL_WINELIB_TYPE(CONVCONTEXT);
+DECL_WINELIB_TYPE(LPCONVCONTEXT);
+
+UINT16    WINAPI DdeInitialize16(LPDWORD,PFNCALLBACK16,DWORD,DWORD);
+UINT32    WINAPI DdeInitialize32A(LPDWORD,PFNCALLBACK32,DWORD,DWORD);
+UINT32    WINAPI DdeInitialize32W(LPDWORD,PFNCALLBACK32,DWORD,DWORD);
+#define   DdeInitialize WINELIB_NAME_AW(DdeInitialize)
+BOOL16    WINAPI DdeUninitialize16(DWORD);
+BOOL32    WINAPI DdeUninitialize32(DWORD);
+#define   DdeUninitialize WINELIB_NAME(DdeUninitialize)
+HCONV     WINAPI DdeConnect16(DWORD,HSZ,HSZ,LPCONVCONTEXT16);
+HCONV     WINAPI DdeConnect32(DWORD,HSZ,HSZ,LPCONVCONTEXT32);
+#define   DdeConnect WINELIB_NAME(DdeConnect)
+BOOL16    WINAPI DdeDisconnect16(HCONV);
+BOOL32    WINAPI DdeDisconnect32(HCONV);
+#define   DdeDisconnect WINELIB_NAME(DdeDisconnect)
+HCONV     WINAPI DdeReconnect(HCONV);
+HSZ       WINAPI DdeCreateStringHandle16(DWORD,LPCSTR,INT16);
+HSZ       WINAPI DdeCreateStringHandle32A(DWORD,LPCSTR,INT32);
+HSZ       WINAPI DdeCreateStringHandle32W(DWORD,LPCWSTR,INT32);
+#define   DdeCreateStringHandle WINELIB_NAME_AW(DdeCreateStringHandle)
+BOOL16    WINAPI DdeFreeStringHandle16(DWORD,HSZ);
+BOOL32    WINAPI DdeFreeStringHandle32(DWORD,HSZ);
+#define   DdeFreeStringHandle WINELIB_NAME(DdeFreeStringHandle)
+BOOL16    WINAPI DdeFreeDataHandle16(HDDEDATA);
+BOOL32    WINAPI DdeFreeDataHandle32(HDDEDATA);
+#define   DdeFreeDataHandle WINELIB_NAME(DdeFreeDataHandle)
+BOOL16    WINAPI DdeKeepStringHandle16(DWORD,HSZ);
+BOOL32    WINAPI DdeKeepStringHandle32(DWORD,HSZ);
+#define   DdeKeepStringHandle WINELIB_NAME(DdeKeepStringHandle)
+HDDEDATA  WINAPI DdeClientTransaction16(LPVOID,DWORD,HCONV,HSZ,UINT16,
+                                        UINT16,DWORD,LPDWORD);
+HDDEDATA  WINAPI DdeClientTransaction32(LPBYTE,DWORD,HCONV,HSZ,UINT32,
+                                        UINT32,DWORD,LPDWORD);
+#define   DdeClientTransaction WINELIB_NAME(DdeClientTransaction)
+HDDEDATA  WINAPI DdeNameService16(DWORD,HSZ,HSZ,UINT16);
+HDDEDATA  WINAPI DdeNameService32(DWORD,HSZ,HSZ,UINT32);
+#define   DdeNameService WINELIB_NAME(DdeNameService)
+UINT16    WINAPI DdeGetLastError16(DWORD);
+UINT32    WINAPI DdeGetLastError32(DWORD);
+#define   DdeGetLastError WINELIB_NAME(DdeGetLastError)
+
+#endif  /* __WINE__DDEML_H */
diff --git a/include/gdi.h b/include/gdi.h
index 817fdf7..17e2741 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -108,6 +108,7 @@
     BYTE          bitsPerPixel;
 
     INT32         MapMode;
+    INT32         GraphicsMode;      /* Graphics mode */
     INT32         DCOrgX;            /* DC origin */
     INT32         DCOrgY;
     INT32         CursPosX;          /* Current position */
diff --git a/include/mmsystem.h b/include/mmsystem.h
index d2f5c16..73b46d4 100644
--- a/include/mmsystem.h
+++ b/include/mmsystem.h
@@ -454,7 +454,7 @@
 #define TIMERR_NOCANDO        (TIMERR_BASE+1)      /* request not completed */
 #define TIMERR_STRUCT         (TIMERR_BASE+33)     /* time struct size */
 
-typedef void (*LPTIMECALLBACK) (UINT16 uTimerID, UINT16 uMessage, DWORD dwUser, DWORD dw1, DWORD dw2);
+typedef void (CALLBACK *LPTIMECALLBACK) (UINT16 uTimerID, UINT16 uMessage, DWORD dwUser, DWORD dw1, DWORD dw2);
 
 #define TIME_ONESHOT    0   /* program timer for single event */
 #define TIME_PERIODIC   1   /* program for continuous periodic event */
diff --git a/include/module.h b/include/module.h
index 1416362..b411b97 100644
--- a/include/module.h
+++ b/include/module.h
@@ -132,12 +132,12 @@
 extern FARPROC16 WIN32_GetProcAddress16( HMODULE32 hmodule, LPSTR name );
 
 /* builtin.c */
-extern BOOL16 BUILTIN_Init(void);
-extern HMODULE16 BUILTIN_LoadModule( LPCSTR name, BOOL16 force );
+extern BOOL32 BUILTIN_Init(void);
+extern HMODULE16 BUILTIN_LoadModule( LPCSTR name, BOOL32 force );
 extern LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, WORD *pOrd );
-extern LPCSTR BUILTIN_GetEntryPoint32( void *relay );
+extern FARPROC32 BUILTIN_GetEntryPoint32( char *buffer, void *relay );
 extern FARPROC32 BUILTIN_GetProcAddress32(NE_MODULE *pModule, LPCSTR function);
-extern BOOL16 BUILTIN_ParseDLLOptions( const char *str );
+extern BOOL32 BUILTIN_ParseDLLOptions( const char *str );
 extern void BUILTIN_PrintDLLs(void);
 
 /* ne_image.c */
diff --git a/include/options.h b/include/options.h
index 542613c..ba48841 100644
--- a/include/options.h
+++ b/include/options.h
@@ -47,6 +47,7 @@
 {
     char * desktopGeometry; /* NULL when no desktop */
     char * programName;     /* To use when loading resources */
+    char * argv0;           /* argv[0] of Wine process */
     int    usePrivateMap;
     int    useFixedMap;
     int    synchronous;     /* X synchronous mode */
diff --git a/include/peexe.h b/include/peexe.h
index 49d7cf9..364e44d 100644
--- a/include/peexe.h
+++ b/include/peexe.h
@@ -350,7 +350,7 @@
 	DWORD	Reserved[ 4 ];
 } IMAGE_LOAD_CONFIG_DIRECTORY,*LPIMAGE_LOAD_CONFIG_DIRECTORY;
 
-typedef VOID (*LPIMAGE_TLS_CALLBACK)(
+typedef VOID (CALLBACK *LPIMAGE_TLS_CALLBACK)(
 	LPVOID DllHandle,DWORD Reason,LPVOID Reserved
 );
 
diff --git a/include/stackframe.h b/include/stackframe.h
index f1b513a..e1cfa77 100644
--- a/include/stackframe.h
+++ b/include/stackframe.h
@@ -7,7 +7,8 @@
 #ifndef __WINE_STACKFRAME_H
 #define __WINE_STACKFRAME_H
 
-#include <windows.h>
+#include <string.h>
+#include "windows.h"
 #include "ldt.h"
 
 #pragma pack(1)
@@ -25,7 +26,6 @@
     WORD    bp;             /* 14 16-bit bp */
     WORD    ip;             /* 16 return address */
     WORD    cs;             /* 18 */
-    WORD    args[1];        /* 1a arguments to API function */
 } STACK16FRAME;
 
   /* 32-bit stack layout after CallTo16() */
@@ -48,14 +48,30 @@
   /* Saved 16-bit stack for current process (Win16 only) */
 extern DWORD IF1632_Saved16_ss_sp;
 
-  /* Saved 32-bit stack for current process (Win16 only) */
-extern DWORD IF1632_Saved32_esp;
+#define CURRENT_STACK16 ((STACK16FRAME *)PTR_SEG_TO_LIN(IF1632_Saved16_ss_sp))
+#define CURRENT_DS      (CURRENT_STACK16->ds)
 
-  /* Original Unix stack */
-extern DWORD IF1632_Original32_esp;
+/* varargs lists on the 16-bit stack */
 
-#define CURRENT_STACK16  ((STACK16FRAME *)PTR_SEG_TO_LIN(IF1632_Saved16_ss_sp))
+typedef void *VA_LIST16;
 
-#define CURRENT_DS   (CURRENT_STACK16->ds)
+#define __VA_ROUNDED16(type) \
+    ((sizeof(type) + sizeof(WORD) - 1) / sizeof(WORD) * sizeof(WORD))
+#define VA_START16(list) ((list) = (VA_LIST16)(CURRENT_STACK16 + 1))
+#define VA_ARG16(list,type) \
+    (((list) = (VA_LIST16)((char *)(list) + __VA_ROUNDED16(type))), \
+     *((type *)(void *)((char *)(list) - __VA_ROUNDED16(type))))
+#define VA_END16(list) ((void)0)
+
+/* Push bytes on the 16-bit stack; return a segptr to the first pushed byte */
+#define STACK16_PUSH(size) \
+ (memmove((char*)CURRENT_STACK16-(size),CURRENT_STACK16,sizeof(STACK16FRAME)),\
+  IF1632_Saved16_ss_sp -= (size), \
+  (SEGPTR)(IF1632_Saved16_ss_sp + sizeof(STACK16FRAME)))
+
+/* Pop bytes from the 16-bit stack */
+#define STACK16_POP(size) \
+ (memmove((char*)CURRENT_STACK16+(size),CURRENT_STACK16,sizeof(STACK16FRAME)),\
+  IF1632_Saved16_ss_sp += (size))
 
 #endif /* __WINE_STACKFRAME_H */
diff --git a/include/syscolor.h b/include/syscolor.h
index a212336..7845858 100644
--- a/include/syscolor.h
+++ b/include/syscolor.h
@@ -12,30 +12,33 @@
 struct SysColorObjects
 {
     HBRUSH32 hbrushScrollbar;        /* COLOR_SCROLLBAR           */
-                                     /* COLOR_BACKGROUND          */
+    HBRUSH32 hbrushBackground;       /* COLOR_BACKGROUND          */
     HBRUSH32 hbrushActiveCaption;    /* COLOR_ACTIVECAPTION       */
     HBRUSH32 hbrushInactiveCaption;  /* COLOR_INACTIVECAPTION     */
     HBRUSH32 hbrushMenu;             /* COLOR_MENU                */
     HBRUSH32 hbrushWindow;           /* COLOR_WINDOW              */
-    HPEN32   hpenWindowFrame;        /* COLOR_WINDOWFRAME         */
-                                     /* COLOR_MENUTEXT            */
-    HPEN32   hpenWindowText;         /* COLOR_WINDOWTEXT          */
-                                     /* COLOR_CAPTIONTEXT         */
+    HBRUSH32 hbrushWindowFrame;      /* COLOR_WINDOWFRAME         */
+    HBRUSH32 hbrushMenuText;         /* COLOR_MENUTEXT            */
+    HBRUSH32 hbrushWindowText;       /* COLOR_WINDOWTEXT          */
+    HBRUSH32 hbrushCaptionText;      /* COLOR_CAPTIONTEXT         */
     HBRUSH32 hbrushActiveBorder;     /* COLOR_ACTIVEBORDER        */
     HBRUSH32 hbrushInactiveBorder;   /* COLOR_INACTIVEBORDER      */
-                                     /* COLOR_APPWORKSPACE        */
+    HBRUSH32 hbrushAppWorkspace;     /* COLOR_APPWORKSPACE        */
     HBRUSH32 hbrushHighlight;        /* COLOR_HIGHLIGHT           */
-                                     /* COLOR_HIGHLIGHTTEXT       */
+    HBRUSH32 hbrushHighlightText;    /* COLOR_HIGHLIGHTTEXT       */
     HBRUSH32 hbrushBtnFace;          /* COLOR_BTNFACE             */
     HBRUSH32 hbrushBtnShadow;        /* COLOR_BTNSHADOW           */
-                                     /* COLOR_GRAYTEXT            */
-                                     /* COLOR_BTNTEXT             */
-                                     /* COLOR_INACTIVECAPTIONTEXT */
+    HBRUSH32 hbrushGrayText;         /* COLOR_GRAYTEXT            */
+    HBRUSH32 hbrushBtnText;          /* COLOR_BTNTEXT             */
+    HBRUSH32 hbrushInactiveCaptionText; /* COLOR_INACTIVECAPTIONTEXT */
     HBRUSH32 hbrushBtnHighlight;     /* COLOR_BTNHIGHLIGHT        */
-                                     /* COLOR_3DDKSHADOW          */
-                                     /* COLOR_3DLIGHT             */
-                                     /* COLOR_INFOTEXT            */
-                                     /* COLOR_INFOBK              */
+    HBRUSH32 hbrush3DDkShadow;       /* COLOR_3DDKSHADOW          */
+    HBRUSH32 hbrush3DLight;          /* COLOR_3DLIGHT             */
+    HBRUSH32 hbrushInfoText;         /* COLOR_INFOTEXT            */
+    HBRUSH32 hbrushInfoBk;           /* COLOR_INFOBK              */
+
+    HPEN32   hpenWindowFrame;        /* COLOR_WINDOWFRAME         */
+    HPEN32   hpenWindowText;         /* COLOR_WINDOWTEXT          */
 };
 
 extern void SYSCOLOR_Init(void);
diff --git a/include/win16drv.h b/include/win16drv.h
index 88acb12..62d9d7f 100644
--- a/include/win16drv.h
+++ b/include/win16drv.h
@@ -18,6 +18,20 @@
 #define INITPDEVICE 0x0000
 #endif
 
+#define     OS_ARC		3
+#define     OS_SCANLINES	4
+#define     OS_RECTANGLE	6
+#define     OS_ELLIPSE		7
+#define     OS_MARKER		8
+#define     OS_POLYLINE 	18
+#define     OS_ALTPOLYGON	22
+#define     OS_WINDPOLYGON	20
+#define     OS_PIE		23
+#define     OS_POLYMARKER	24
+#define     OS_CHORD		39
+#define     OS_CIRCLE		55
+#define     OS_ROUNDRECT	72
+
 /* Internal Data */
 #define ORD_BITBLT		1
 #define ORD_COLORINFO		2		
@@ -89,7 +103,7 @@
 
 typedef struct
 {
-    char 	szDriver[9];		/* Driver name eg EPSON */
+    LPSTR 	szDriver;		/* Driver name eg EPSON */
     HINSTANCE16	hInst;			/* Handle for driver */
     WORD	ds_reg;			/* DS of driver */
     FARPROC16 	fn[TOTAL_PRINTER_DRIVER_FUNCTIONS];	/* Printer functions */
@@ -97,9 +111,6 @@
     int		nPrinterFonts;		/* Number of printer fonts */
     PRINTER_FONTS_INFO *paPrinterFonts; /* array of printer fonts */
     int		nIndex;			/* Index in global driver array */
-    HGLOBAL16   hThunk;			/* Thunking buffer */
-    SEGPTR	ThunkBufSegPtr;
-    SEGPTR	ThunkBufLimit;
 } LOADED_PRINTER_DRIVER;
 
 typedef struct PDEVICE_HEADER
@@ -146,10 +157,12 @@
 /* Win16 printer driver physical DC */
 typedef struct
 {
-    SEGPTR	segptrPDEVICE;	/* PDEVICE used by 16 bit printer drivers */
-    LOGFONT16	lf;		/* Current font details */
+    SEGPTR		segptrPDEVICE;	/* PDEVICE used by 16 bit printer drivers */
+    LOGFONT16		lf;		/* Current font details */
     TEXTMETRIC16	tm;		/* Current font metrics */
-    SEGPTR	segptrFontInfo; /* Current font realized by printer driver */
+    SEGPTR		segptrFontInfo; /* Current font realized by printer driver */
+    SEGPTR		segptrBrushInfo; /* Current brush realized by printer driver */
+    SEGPTR		segptrPenInfo;   /* Current pen realized by printer driver */
 } WIN16DRV_PDEVICE;
 
 /*
@@ -187,6 +200,10 @@
 extern BOOL32 WIN16DRV_ExtTextOut( DC *dc, INT32 x, INT32 y, UINT32 flags,
                                   const RECT32 *lprect, LPCSTR str, UINT32 count,
                                   const INT32 *lpDx );
+extern BOOL32 WIN16DRV_LineTo( DC *dc, INT32 x, INT32 y );
+extern BOOL32 WIN16DRV_MoveToEx(DC *dc,INT32 x,INT32 y,LPPOINT32 pt);
+extern BOOL32 WIN16DRV_Polygon(DC *dc, LPPOINT32 pt, INT32 count );
+extern BOOL32 WIN16DRV_Rectangle(DC *dc, INT32 left, INT32 top, INT32 right, INT32 bottom);
 extern HGDIOBJ32 WIN16DRV_SelectObject( DC *dc, HGDIOBJ32 handle );
 extern BOOL32 WIN16DRV_PatBlt( struct tagDC *dc, INT32 left, INT32 top,
                                INT32 width, INT32 height, DWORD rop );
@@ -202,3 +219,4 @@
 extern LPDRAWMODE 	win16drv_DrawModeP;
 
 #endif  /* __WINE_WIN16DRV_H */
+
diff --git a/include/windows.h b/include/windows.h
index 5cd9e11..83d4603 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -1120,6 +1120,15 @@
   FONTSIGNATURE	fs;
 } CHARSETINFO,*LPCHARSETINFO;
 
+typedef struct
+{
+    FLOAT  eM11;
+    FLOAT  eM12;
+    FLOAT  eM21;
+    FLOAT  eM22;
+    FLOAT  eDx;
+    FLOAT  eDy;
+} XFORM, *LPXFORM;
 
 typedef struct 
 {
@@ -1432,14 +1441,16 @@
 DECL_WINELIB_TYPE_AW(LPNEWTEXTMETRICEX);
 
 
-typedef INT16 (*FONTENUMPROC16)(SEGPTR,SEGPTR,UINT16,LPARAM);
-typedef INT32 (*FONTENUMPROC32A)(LPENUMLOGFONT32A,LPNEWTEXTMETRIC32A,UINT32,LPARAM);
-typedef INT32 (*FONTENUMPROC32W)(LPENUMLOGFONT32W,LPNEWTEXTMETRIC32W,UINT32,LPARAM);
+typedef INT16 (CALLBACK *FONTENUMPROC16)(SEGPTR,SEGPTR,UINT16,LPARAM);
+typedef INT32 (CALLBACK *FONTENUMPROC32A)(LPENUMLOGFONT32A,LPNEWTEXTMETRIC32A,
+                                          UINT32,LPARAM);
+typedef INT32 (CALLBACK *FONTENUMPROC32W)(LPENUMLOGFONT32W,LPNEWTEXTMETRIC32W,
+                                          UINT32,LPARAM);
 DECL_WINELIB_TYPE_AW(FONTENUMPROC);
 
-typedef INT16 (*FONTENUMPROCEX16)(SEGPTR,SEGPTR,UINT16,LPARAM);
-typedef INT32 (*FONTENUMPROCEX32A)(LPENUMLOGFONTEX32A,LPNEWTEXTMETRICEX32A,UINT32,LPARAM);
-typedef INT32 (*FONTENUMPROCEX32W)(LPENUMLOGFONTEX32W,LPNEWTEXTMETRICEX32W,UINT32,LPARAM);
+typedef INT16 (CALLBACK *FONTENUMPROCEX16)(SEGPTR,SEGPTR,UINT16,LPARAM);
+typedef INT32 (CALLBACK *FONTENUMPROCEX32A)(LPENUMLOGFONTEX32A,LPNEWTEXTMETRICEX32A,UINT32,LPARAM);
+typedef INT32 (CALLBACK *FONTENUMPROCEX32W)(LPENUMLOGFONTEX32W,LPNEWTEXTMETRICEX32W,UINT32,LPARAM);
 DECL_WINELIB_TYPE_AW(FONTENUMPROCEX);
 
   /* tmPitchAndFamily bits */
@@ -1616,6 +1627,12 @@
 #define TRANSPARENT       1
 #define OPAQUE            2
 
+
+  /* Graphics Modes */
+#define GM_COMPATIBLE     1
+#define GM_ADVANCED       2
+#define GM_LAST           2
+
   /* Map modes */
 #define MM_TEXT		  1
 #define MM_LOMETRIC	  2
@@ -4274,8 +4291,10 @@
 #define META_CREATEBITMAP            0x06FE
 #define META_CREATEREGION            0x06FF
 
-typedef INT16 (*MFENUMPROC16)(HDC16,HANDLETABLE16*,METARECORD*,INT16,LPARAM);
-typedef INT32 (*MFENUMPROC32)(HDC32,HANDLETABLE32*,METARECORD*,INT32,LPARAM);
+typedef INT16 (CALLBACK *MFENUMPROC16)(HDC16,HANDLETABLE16*,METARECORD*,
+                                       INT16,LPARAM);
+typedef INT32 (CALLBACK *MFENUMPROC32)(HDC32,HANDLETABLE32*,METARECORD*,
+                                       INT32,LPARAM);
 DECL_WINELIB_TYPE(MFENUMPROC);
 
 #ifndef NOLOGERROR
@@ -4844,14 +4863,13 @@
     DWORD    Type;
 } MEMORY_BASIC_INFORMATION,*LPMEMORY_BASIC_INFORMATION;
 
-typedef DWORD (*LPTHREAD_START_ROUTINE)(LPVOID);
+typedef DWORD (CALLBACK *LPTHREAD_START_ROUTINE)(LPVOID);
 
-typedef BOOL32 (*CODEPAGE_ENUMPROC32A)(LPSTR);
-typedef BOOL32 (*CODEPAGE_ENUMPROC32W)(LPWSTR);
+typedef BOOL32 (CALLBACK *CODEPAGE_ENUMPROC32A)(LPSTR);
+typedef BOOL32 (CALLBACK *CODEPAGE_ENUMPROC32W)(LPWSTR);
 DECL_WINELIB_TYPE_AW(CODEPAGE_ENUMPROC);
-
-typedef BOOL32 (*LOCALE_ENUMPROC32A)(LPSTR);
-typedef BOOL32 (*LOCALE_ENUMPROC32W)(LPWSTR);
+typedef BOOL32 (CALLBACK *LOCALE_ENUMPROC32A)(LPSTR);
+typedef BOOL32 (CALLBACK *LOCALE_ENUMPROC32W)(LPWSTR);
 DECL_WINELIB_TYPE_AW(LOCALE_ENUMPROC);
 
 typedef struct tagSYSTEM_INFO
@@ -4889,8 +4907,8 @@
 #define	PROCESSOR_ALPHA_21064	21064
 
 /* service main function prototype */
-typedef VOID (*LPSERVICE_MAIN_FUNCTION32A)(DWORD,LPSTR);
-typedef VOID (*LPSERVICE_MAIN_FUNCTION32W)(DWORD,LPWSTR);
+typedef VOID (CALLBACK *LPSERVICE_MAIN_FUNCTION32A)(DWORD,LPSTR);
+typedef VOID (CALLBACK *LPSERVICE_MAIN_FUNCTION32W)(DWORD,LPWSTR);
 DECL_WINELIB_TYPE_AW(LPSERVICE_MAIN_FUNCTION);
 
 /* service start table */
@@ -5011,16 +5029,12 @@
 
 #define PR_JOBSTATUS	0x0000
 
-typedef BOOL32 (*ENUMRESTYPEPROC32A)(HMODULE32 hModule, LPSTR type,LONG lParam);
-typedef BOOL32 (*ENUMRESTYPEPROC32W)(HMODULE32 hModule, LPWSTR type,LONG lParam);
-typedef BOOL32 (*ENUMRESNAMEPROC32A)(HMODULE32 hModule, LPCSTR type,
-				LPSTR name,LONG lParam);
-typedef BOOL32 (*ENUMRESNAMEPROC32W)(HMODULE32 hModule, LPCWSTR type,
-				LPWSTR name,LONG lParam);
-typedef BOOL32 (*ENUMRESLANGPROC32A)(HMODULE32 hModule, LPCSTR type,
-				LPCSTR name,WORD lang,LONG lParam);
-typedef BOOL32 (*ENUMRESLANGPROC32W)(HMODULE32 hModule, LPCWSTR type,
-				LPCWSTR name,WORD lang,LONG lParam);
+typedef BOOL32 (CALLBACK *ENUMRESTYPEPROC32A)(HMODULE32,LPSTR,LONG);
+typedef BOOL32 (CALLBACK *ENUMRESTYPEPROC32W)(HMODULE32,LPWSTR,LONG);
+typedef BOOL32 (CALLBACK *ENUMRESNAMEPROC32A)(HMODULE32,LPCSTR,LPSTR,LONG);
+typedef BOOL32 (CALLBACK *ENUMRESNAMEPROC32W)(HMODULE32,LPCWSTR,LPWSTR,LONG);
+typedef BOOL32 (CALLBACK *ENUMRESLANGPROC32A)(HMODULE32,LPCSTR,LPCSTR,WORD,LONG);
+typedef BOOL32 (CALLBACK *ENUMRESLANGPROC32W)(HMODULE32,LPCWSTR,LPCWSTR,WORD,LONG);
 
 DECL_WINELIB_TYPE_AW(ENUMRESTYPEPROC);
 DECL_WINELIB_TYPE_AW(ENUMRESNAMEPROC);
@@ -5496,6 +5510,9 @@
 #define     GetMenuItemInfo WINELIB_NAME_AW(GetMenuItemInfo)
 UINT32      WINAPI GetOEMCP(void);
 DWORD       WINAPI GetPriorityClass(HANDLE32);
+INT32       WINAPI GetPrivateProfileSection32A(LPCSTR,LPSTR,INT32,LPCSTR);
+INT32       WINAPI GetPrivateProfileSection32W(LPCWSTR,LPWSTR,INT32,LPCWSTR);
+#define     GetPrivateProfileSection WINELIB_NAME_AW(GetPrivateProfileSection)
 HANDLE32    WINAPI GetProcessHeap(void);
 DWORD       WINAPI GetShortPathName32A(LPCSTR,LPSTR,DWORD);
 DWORD       WINAPI GetShortPathName32W(LPCWSTR,LPWSTR,DWORD);
@@ -5529,7 +5546,7 @@
 LPVOID      WINAPI HeapReAlloc(HANDLE32,DWORD,LPVOID,DWORD);
 DWORD       WINAPI HeapSize(HANDLE32,DWORD,LPVOID);
 BOOL32      WINAPI HeapUnlock(HANDLE32);
-BOOL32      WINAPI HeapValidate(HANDLE32,DWORD,LPVOID);
+BOOL32      WINAPI HeapValidate(HANDLE32,DWORD,LPCVOID);
 BOOL32      WINAPI IsDBCSLeadByteEx(UINT32,BYTE);
 BOOL32      WINAPI IsWindowUnicode(HWND32);
 BOOL32      WINAPI IsValidLocale(DWORD,DWORD);
@@ -6482,6 +6499,9 @@
 HWND16      WINAPI GetFocus16(void);
 HWND32      WINAPI GetFocus32(void);
 #define     GetFocus WINELIB_NAME(GetFocus)
+HWND16      WINAPI GetForegroundWindow16(void);
+HWND32      WINAPI GetForegroundWindow32(void);
+#define     GetForegroundWindow WINELIB_NAME(GetForegroundWindow)
 DWORD       WINAPI GetFreeSpace16(UINT16);
 #define     GetFreeSpace32(w) (0x100000L)
 #define     GetFreeSpace WINELIB_NAME(GetFreeSpace)
@@ -6641,6 +6661,9 @@
 BOOL16      WINAPI GetScrollRange16(HWND16,INT16,LPINT16,LPINT16);
 BOOL32      WINAPI GetScrollRange32(HWND32,INT32,LPINT32,LPINT32);
 #define     GetScrollRange WINELIB_NAME(GetScrollRange)
+HWND16      WINAPI GetShellWindow16(void);
+HWND32      WINAPI GetShellWindow32(void);
+#define     GetShellWindow WINELIB_NAME(GetShellWindow)
 HGDIOBJ16   WINAPI GetStockObject16(INT16);
 HGDIOBJ32   WINAPI GetStockObject32(INT32);
 #define     GetStockObject WINELIB_NAME(GetStockObject)
@@ -7428,6 +7451,9 @@
 HWND16      WINAPI SetFocus16(HWND16);
 HWND32      WINAPI SetFocus32(HWND32);
 #define     SetFocus WINELIB_NAME(SetFocus)
+BOOL16      WINAPI SetForegroundWindow16(HWND16);
+BOOL32      WINAPI SetForegroundWindow32(HWND32);
+#define     SetForegroundWindow WINELIB_NAME(SetForegroundWindow)
 UINT16      WINAPI SetHandleCount16(UINT16);
 UINT32      WINAPI SetHandleCount32(UINT32);
 #define     SetHandleCount WINELIB_NAME(SetHandleCount)
diff --git a/include/wintypes.h b/include/wintypes.h
index f420b39..afbf781 100644
--- a/include/wintypes.h
+++ b/include/wintypes.h
@@ -126,6 +126,7 @@
 typedef DWORD           LCID;
 typedef WORD            LANGID;
 typedef DWORD           LCTYPE;
+typedef float           FLOAT;
 
 /* Pointers types. These are the same for emulator and library. */
 
@@ -145,6 +146,7 @@
 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. */
 
diff --git a/library/Makefile.in b/library/Makefile.in
index c2bd7e8..4fd19a1 100644
--- a/library/Makefile.in
+++ b/library/Makefile.in
@@ -7,7 +7,6 @@
 LIBMODULE = library
 
 LIB_SRCS = \
-	arch.c \
 	libres.c \
 	miscstubs.c
 
diff --git a/library/arch.c b/library/arch.c
deleted file mode 100644
index 9f9c6c7..0000000
--- a/library/arch.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Big endian structure conversion routines
- *
- * Copyright Miguel de Icaza, 1994
- */
-
-#include "arch.h"
-#include "windows.h"
-
-void ARCH_ConvBitmapInfo (BITMAPINFOHEADER *image)
-{
-    image->biSize = CONV_LONG (image->biSize);
-    image->biWidth = CONV_LONG (image->biWidth);
-    image->biHeight = CONV_LONG (image->biHeight);
-    image->biPlanes = CONV_SHORT (image->biPlanes);
-    image->biBitCount = CONV_SHORT (image->biBitCount);
-    image->biCompression = CONV_LONG (image->biCompression);
-    image->biSizeImage = CONV_LONG (image->biSizeImage);
-    image->biXPelsPerMeter = CONV_LONG (image->biXPelsPerMeter);
-    image->biYPelsPerMeter = CONV_LONG (image->biYPelsPerMeter);
-    image->biClrUsed = CONV_LONG (image->biClrUsed);
-    image->biClrImportant = CONV_LONG (image->biClrImportant);
-}
-
-void ARCH_ConvCoreHeader (BITMAPCOREHEADER *image)
-{
-    image->bcSize = CONV_LONG (image->bcSize);
-    image->bcWidth = CONV_SHORT (image->bcWidth);
-    image->bcHeight = CONV_SHORT (image->bcHeight);
-    image->bcPlanes = CONV_SHORT (image->bcPlanes);
-    image->bcBitCount = CONV_SHORT (image->bcBitCount);
-}
diff --git a/library/miscstubs.c b/library/miscstubs.c
index 091a4b1..aaafc88 100644
--- a/library/miscstubs.c
+++ b/library/miscstubs.c
@@ -7,10 +7,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include "windows.h"
-#include "dde_mem.h"
-#include "global.h"
-#include "debug.h"
+#include "wintypes.h"
 
 
 /* for windows/winproc.c */
diff --git a/loader/module.c b/loader/module.c
index d1cc2b5..65b655c 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -417,6 +417,7 @@
     NE_MODULE *pModule;
     SEGTABLEENTRY *pSegment;
     char *pStr,*s;
+    int len;
     const char* basename;
 
     INT32 of_size = sizeof(OFSTRUCT) - sizeof(ofs->szPathName)
@@ -473,19 +474,15 @@
     /* Module name */
     pStr = (char *)pSegment;
     pModule->name_table = (int)pStr - (int)pModule;
-    /* strcpy( pStr, "\x08W32SXXXX" ); */
     basename = strrchr(ofs->szPathName,'\\');
-    if (!basename) 
-	    	basename=ofs->szPathName;
-    else
-	    	basename++;
-    basename=strdup(basename);
-    if ((s=strchr(basename,'.')))
-	    	*s='\0';
-    *pStr = strlen(basename);
-    if (*pStr>8) *pStr=8;
-    strncpy( pStr+1, basename, 8 );
-    free((void*)basename);
+    if (!basename) basename = ofs->szPathName;
+    else basename++;
+    len = strlen(basename);
+    if ((s = strchr(basename,'.'))) len = s - basename;
+    if (len > 8) len = 8;
+    *pStr = len;
+    strncpy( pStr+1, basename, len );
+    if (len < 8) pStr[len+1] = 0;
     pStr += 9;
 
     /* All tables zero terminated */
@@ -1609,7 +1606,7 @@
         return 2;  /* File not found */
     if (!(cmdShowHandle = GlobalAlloc16( 0, 2 * sizeof(WORD) )))
         return 8;  /* Out of memory */
-    if (!(cmdLineHandle = GlobalAlloc16( 0, 256 )))
+    if (!(cmdLineHandle = GlobalAlloc16( 0, 2048 )))
     {
         GlobalFree16( cmdShowHandle );
         return 8;  /* Out of memory */
@@ -1660,6 +1657,11 @@
 
 	cmdline[0] = strlen( cmdline + 1 );
 	*p = '\0';
+	/* this is a (hopefully acceptable hack to get the whole
+	   commandline for PROCESS_Create
+	   we put it after the processed one */
+	lstrcpyn32A(cmdline + (unsigned char)cmdline[0] +2,
+		    lpCmdLine, 2048 - 256);
 
 	/* Now load the executable file */
 
diff --git a/loader/ne_image.c b/loader/ne_image.c
index 48df65f..09334ba 100644
--- a/loader/ne_image.c
+++ b/loader/ne_image.c
@@ -18,7 +18,6 @@
 #include "neexe.h"
 #include "windows.h"
 #include "task.h"
-#include "arch.h"
 #include "selectors.h"
 #include "callback.h"
 #include "file.h"
diff --git a/loader/ne_resource.c b/loader/ne_resource.c
index 7121b18..37ec64f 100644
--- a/loader/ne_resource.c
+++ b/loader/ne_resource.c
@@ -14,7 +14,6 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include "windows.h"
-#include "arch.h"
 #include "global.h"
 #include "ldt.h"
 #include "module.h"
@@ -264,11 +263,8 @@
     if (!pModule || !pModule->res_table) return 0;
     pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2);
 
-    if ((pModule->expected_version < 0x030a) && (HIWORD(typeId) || HIWORD(resId)))
+    if (HIWORD(typeId) || HIWORD(resId))
     {
-        /* Search the names in the nametable (which is not present 
-         * since Windows 3.1).  */
-
         DWORD id = NE_FindNameTableId( pModule, typeId, resId );
         if (id)  /* found */
         {
diff --git a/loader/resource.c b/loader/resource.c
index 23ba6b6..69cefc2 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -12,7 +12,6 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include "arch.h"
 #include "windows.h"
 #include "gdi.h"
 #include "global.h"
diff --git a/loader/task.c b/loader/task.c
index 0dcf6a6..0b749d4 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -434,7 +434,7 @@
     STACK16FRAME *frame16;
     STACK32FRAME *frame32;
 #ifndef WINELIB32
-    extern DWORD CALLTO16_RetAddr_word;
+    extern DWORD CALLTO16_RetAddr_regs;
     extern void CALLTO16_Restore();
 #endif
     
@@ -586,8 +586,8 @@
     pTask->ss_sp = PTR_SEG_OFF_TO_SEGPTR( hInstance,
                         ((pModule->sp != 0) ? pModule->sp :
                 pSegTable[pModule->ss-1].minsize + pModule->stack_size) & ~1 );
-    pTask->ss_sp -= sizeof(DWORD);  /* To store saved %%esp */
-    frame16 = (STACK16FRAME *)PTR_SEG_TO_LIN( pTask->ss_sp ) - 1;
+    pTask->ss_sp -= sizeof(STACK16FRAME) - sizeof(DWORD) /* for saved %esp */;
+    frame16 = (STACK16FRAME *)PTR_SEG_TO_LIN( pTask->ss_sp );
     frame16->saved_ss_sp = 0;
     frame16->ebp = 0;
     frame16->ds = frame16->es = pTask->hInstance;
@@ -595,13 +595,11 @@
     frame16->entry_ip = OFFSETOF(TASK_RescheduleProc) + 14;
     frame16->entry_cs = SELECTOROF(TASK_RescheduleProc);
     frame16->bp = 0;
-    frame16->args[0] = LOWORD(frame32);
-    frame16->args[1] = HIWORD(frame32);
+    *(DWORD *)(frame16 + 1) = frame32; /* Store the 32-bit stack pointer */
 #ifndef WINELIB
-    frame16->ip = LOWORD( CALLTO16_RetAddr_word );
-    frame16->cs = HIWORD( CALLTO16_RetAddr_word );
+    frame16->ip = LOWORD( CALLTO16_RetAddr_regs );
+    frame16->cs = HIWORD( CALLTO16_RetAddr_regs );
 #endif  /* WINELIB */
-    pTask->ss_sp -= sizeof(STACK16FRAME);
 
       /* If there's no 16-bit stack yet, use a part of the new task stack */
       /* This is only needed to have a stack to switch from on the first  */
@@ -1180,14 +1178,17 @@
 
     /* Switch to the new stack */
 
+    /* Note: we need to take the 3 arguments into account; otherwise,
+     * the stack will underflow upon return from this function.
+     */
     IF1632_Saved16_ss_sp = PTR_SEG_OFF_TO_SEGPTR( seg,
-                                                  ptr - sizeof(STACK16FRAME) );
+                             ptr - sizeof(STACK16FRAME) - 3 * sizeof(WORD) );
     newFrame = CURRENT_STACK16;
 
     /* Copy the stack frame and the local variables to the new stack */
 
     copySize = oldFrame->bp - OFFSETOF(pData->old_ss_sp);
-    memcpy( newFrame, oldFrame, MAX( copySize, sizeof(STACK16FRAME) ));
+    memmove( newFrame, oldFrame, MAX( copySize, sizeof(STACK16FRAME) ));
 }
 
 
diff --git a/memory/global.c b/memory/global.c
index 6a2b86b..8e9bc5c 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -846,7 +846,7 @@
 
 #define MAGIC_GLOBAL_USED 0x5342
 #define GLOBAL_LOCK_MAX   0xFF
-#define HANDLE_TO_INTERN(h)  (PGLOBAL32_INTERN)(((char *)(h))-2)
+#define HANDLE_TO_INTERN(h)  ((PGLOBAL32_INTERN)(((char *)(h))-2))
 #define INTERN_TO_HANDLE(i)  ((HGLOBAL32) &((i)->Pointer))
 #define POINTER_TO_HANDLE(p) (*(((HGLOBAL32 *)(p))-1))
 #define ISHANDLE(h)          (((DWORD)(h)&2)!=0)
@@ -970,7 +970,18 @@
  */
 HGLOBAL32 WINAPI GlobalHandle32(LPCVOID pmem)
 {
-   return (HGLOBAL32) POINTER_TO_HANDLE(pmem);
+    HGLOBAL32 handle = POINTER_TO_HANDLE(pmem);
+    if (HEAP_IsInsideHeap( GetProcessHeap(), 0, (LPCVOID)handle ))
+    {
+        if (HANDLE_TO_INTERN(handle)->Magic == MAGIC_GLOBAL_USED)
+            return handle;  /* valid moveable block */
+    }
+    /* maybe FIXED block */
+    if (HeapValidate( GetProcessHeap(), 0, pmem ))
+        return (HGLOBAL32)pmem;  /* valid fixed block */
+
+    SetLastError( ERROR_INVALID_HANDLE );
+    return 0;
 }
 
 
diff --git a/memory/heap.c b/memory/heap.c
index 990ebb9..0cf20f5 100644
--- a/memory/heap.c
+++ b/memory/heap.c
@@ -1142,7 +1142,7 @@
 /***********************************************************************
  *           HeapValidate   (KERNEL32.343)
  */
-BOOL32 WINAPI HeapValidate( HANDLE32 heap, DWORD flags, LPVOID block )
+BOOL32 WINAPI HeapValidate( HANDLE32 heap, DWORD flags, LPCVOID block )
 {
     SUBHEAP *subheap;
     HEAP *heapPtr = (HEAP *)heap;
diff --git a/misc/Makefile.in b/misc/Makefile.in
index 92dc1c3..49f090b 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -11,6 +11,7 @@
 	compobj.c \
 	crtdll.c \
 	cpu.c \
+	ddeml.c \
 	error.c \
 	lstr.c \
 	lzexpand.c \
diff --git a/misc/commdlg.c b/misc/commdlg.c
index f21978e..4c3668d 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -1112,15 +1112,15 @@
 
 
 /***********************************************************************
- *           PrintDlg   (COMMDLG.20)
+ *           PrintDlg16   (COMMDLG.20)
  */
-BOOL16 WINAPI PrintDlg( SEGPTR printdlg )
+BOOL16 WINAPI PrintDlg16( SEGPTR printdlg )
 {
     HANDLE16 hInst;
     BOOL16 bRet = FALSE;
     LPCVOID template;
     HWND32 hwndDialog;
-    LPPRINTDLG lpPrint = (LPPRINTDLG)PTR_SEG_TO_LIN(printdlg);
+    LPPRINTDLG16 lpPrint = (LPPRINTDLG16)PTR_SEG_TO_LIN(printdlg);
 
     dprintf_commdlg(stddeb,"PrintDlg(%p) // Flags=%08lX\n", lpPrint, lpPrint->Flags );
 
@@ -1146,6 +1146,26 @@
 
 
 /***********************************************************************
+ *           PrintDlg32A   (COMDLG32.17)
+ */
+BOOL32 WINAPI PrintDlg32A( LPPRINTDLG32A printdlg )
+{
+    fprintf( stdnimp, "PrintDlg32A: empty stub\n" );
+    return FALSE;
+}
+
+
+/***********************************************************************
+ *           PrintDlg32W   (COMDLG32.18)
+ */
+BOOL32 WINAPI PrintDlg32W( LPPRINTDLG32W printdlg )
+{
+    fprintf( stdnimp, "PrintDlg32A: empty stub\n" );
+    return FALSE;
+}
+
+
+/***********************************************************************
  *           PrintDlgProc   (COMMDLG.21)
  */
 LRESULT WINAPI PrintDlgProc(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
diff --git a/misc/crtdll.c b/misc/crtdll.c
index e90db10..91a8732 100644
--- a/misc/crtdll.c
+++ b/misc/crtdll.c
@@ -39,6 +39,8 @@
 #include "crtdll.h"
 #include "drive.h"
 #include "file.h"
+#include "except.h"
+#include "options.h"
 
 extern int FILE_GetUnixHandle( HFILE32  );
 
@@ -52,9 +54,12 @@
 UINT32 CRTDLL_basemajor_dll;    /* CRTDLL.42 */
 UINT32 CRTDLL_baseminor_dll;    /* CRTDLL.43 */
 UINT32 CRTDLL_baseversion_dll;  /* CRTDLL.44 */
+UINT32 CRTDLL_commode_dll;      /* CRTDLL.59 */
 LPSTR  CRTDLL_environ_dll;      /* CRTDLL.75 */
+UINT32 CRTDLL_fmode_dll;        /* CRTDLL.104 */
 UINT32 CRTDLL_osmajor_dll;      /* CRTDLL.241 */
 UINT32 CRTDLL_osminor_dll;      /* CRTDLL.242 */
+UINT32 CRTDLL_osmode_dll;       /* CRTDLL.243 */
 UINT32 CRTDLL_osver_dll;        /* CRTDLL.244 */
 UINT32 CRTDLL_osversion_dll;    /* CRTDLL.245 */
 UINT32 CRTDLL_winmajor_dll;     /* CRTDLL.329 */
@@ -171,6 +176,29 @@
   return (DWORD)file;
 }
 
+/*******************************************************************
+ *         _global_unwind2  (CRTDLL.129)
+ */
+void __cdecl CRTDLL__global_unwind2( CONTEXT *context )
+{
+    /* Retrieve the arguments (args[0] is return addr, args[1] is first arg) */
+    DWORD *args = (DWORD *)ESP_reg(context);
+    RtlUnwind( (PEXCEPTION_FRAME)args[1], (LPVOID)EIP_reg(context),
+               NULL, 0, context );
+}
+
+/*******************************************************************
+ *         _local_unwind2  (CRTDLL.173)
+ */
+void __cdecl CRTDLL__local_unwind2( CONTEXT *context )
+{
+    /* Retrieve the arguments (args[0] is return addr, args[1] is first arg) */
+    DWORD *args = (DWORD *)ESP_reg(context);
+    PEXCEPTION_FRAME endframe = (PEXCEPTION_FRAME)args[1];
+    DWORD nr = args[2];
+    fprintf(stderr,"CRTDLL__local_unwind2(%p,%ld)\n",endframe,nr);
+}
+
 /*********************************************************************
  *                  fopen     (CRTDLL.372)
  */
@@ -700,10 +728,14 @@
 INT32 CRTDLL_system(LPSTR x)
 {
 #define SYSBUF_LENGTH 1500
-  char buffer[SYSBUF_LENGTH]="wine \"";
-  unsigned char *y =x;
-  unsigned char *bp =buffer+strlen(buffer);
-  int i =strlen(buffer) + strlen(x) +2;
+  char buffer[SYSBUF_LENGTH];
+  unsigned char *y = x;
+  unsigned char *bp;
+  int i;
+
+  sprintf( buffer, "%s \"", Options.argv0 );
+  bp = buffer + strlen(buffer);
+  i = strlen(buffer) + strlen(x) +2;
 
   /* Calculate needed buffer size tp prevent overflow*/
   while (*y) {
@@ -854,7 +886,7 @@
 INT32 __cdecl CRTDLL_fclose( FILE *stream )
 {
     int unix_handle=fileno(stream);
-    HFILE32 dos_handle=3;
+    HFILE32 dos_handle=1;
     HFILE32 ret=EOF;
 
     if (unix_handle<4) ret= fclose(stream);
diff --git a/misc/ddeml.c b/misc/ddeml.c
new file mode 100644
index 0000000..823265e
--- /dev/null
+++ b/misc/ddeml.c
@@ -0,0 +1,268 @@
+/*
+ * DDEML library
+ *
+ * Copyright 1997 Alexandre Julliard
+ */
+
+/* Only empty stubs for now */
+
+#include <stdio.h>
+#include "ddeml.h"
+#include "stddebug.h"
+#include "debug.h"
+
+
+/*****************************************************************
+ *            DdeInitialize16   (DDEML.2)
+ */
+UINT16 WINAPI DdeInitialize16( LPDWORD pidInst, PFNCALLBACK16 pfnCallback,
+                               DWORD afCmd, DWORD ulRes)
+{
+    fprintf( stdnimp, "DdeInitialize16: empty stub\n" );
+    return 0;
+}
+
+
+/*****************************************************************
+ *            DdeInitialize32A   (USER32.106)
+ */
+UINT32 WINAPI DdeInitialize32A( LPDWORD pidInst, PFNCALLBACK32 pfnCallback,
+                                DWORD afCmd, DWORD ulRes )
+{
+    fprintf( stdnimp, "DdeInitialize32A: empty stub\n" );
+    return 0;
+}
+
+
+/*****************************************************************
+ *            DdeInitialize32W   (USER32.107)
+ */
+UINT32 WINAPI DdeInitialize32W( LPDWORD pidInst, PFNCALLBACK32 pfnCallback,
+                                DWORD afCmd, DWORD ulRes )
+{
+    fprintf( stdnimp, "DdeInitialize32W: empty stub\n" );
+    return 0;
+}
+
+
+/*****************************************************************
+ *            DdeUninitialize16   (DDEML.3)
+ */
+BOOL16 WINAPI DdeUninitialize16( DWORD idInst )
+{
+    return (BOOL16)DdeUninitialize32( idInst );
+}
+
+
+/*****************************************************************
+ *            DdeUninitialize32   (USER32.119)
+ */
+BOOL32 WINAPI DdeUninitialize32( DWORD idInst )
+{
+    fprintf( stdnimp, "DdeUninitialize: empty stub\n" );
+    return TRUE;
+}
+
+
+/*****************************************************************
+ *            DdeConnect16   (DDEML.7)
+ */
+HCONV WINAPI DdeConnect16( DWORD idInst, HSZ hszService, HSZ hszTopic,
+                           LPCONVCONTEXT16 pCC )
+{
+    fprintf( stdnimp, "DdeConnect16: empty stub\n" );
+    return 0;
+}
+
+
+/*****************************************************************
+ *            DdeConnect32   (USER32.92)
+ */
+HCONV WINAPI DdeConnect32( DWORD idInst, HSZ hszService, HSZ hszTopic,
+                           LPCONVCONTEXT32 pCC )
+{
+    fprintf( stdnimp, "DdeConnect32: empty stub\n" );
+    return 0;
+}
+
+
+/*****************************************************************
+ *            DdeDisconnect16   (DDEML.8)
+ */
+BOOL16 WINAPI DdeDisconnect16( HCONV hConv )
+{
+    return (BOOL16)DdeDisconnect32( hConv );
+}
+
+
+/*****************************************************************
+ *            DdeDisconnect32   (USER32.97)
+ */
+BOOL32 WINAPI DdeDisconnect32( HCONV hConv )
+{
+    fprintf( stdnimp, "DdeDisconnect: empty stub\n" );
+    return 0;
+}
+
+
+/*****************************************************************
+ *            DdeReconnect   (DDEML.37) (USER32.115)
+ */
+HCONV WINAPI DdeReconnect( HCONV hConv )
+{
+    fprintf( stdnimp, "DdeReconnect: empty stub\n" );
+    return 0;
+}
+
+
+/*****************************************************************
+ *            DdeCreateStringHandle16   (DDEML.21)
+ */
+HSZ WINAPI DdeCreateStringHandle16( DWORD idInst, LPCSTR str, INT16 codepage )
+{
+    return DdeCreateStringHandle32A( idInst, str, codepage );
+}
+
+
+/*****************************************************************
+ *            DdeCreateStringHandle32A   (USER32.95)
+ */
+HSZ WINAPI DdeCreateStringHandle32A( DWORD idInst, LPCSTR psz, INT32 codepage )
+{
+    fprintf( stdnimp, "DdeCreateStringHandle32A: empty stub\n" );
+    return 0;
+}
+
+
+/*****************************************************************
+ *            DdeCreateStringHandle32W   (USER32.96)
+ */
+HSZ WINAPI DdeCreateStringHandle32W( DWORD idInst, LPCWSTR psz, INT32 codepage)
+{
+    fprintf( stdnimp, "DdeCreateStringHandle32W: empty stub\n" );
+    return 0;
+}
+
+
+/*****************************************************************
+ *            DdeFreeStringHandle16   (DDEML.22)
+ */
+BOOL16 WINAPI DdeFreeStringHandle16( DWORD idInst, HSZ hsz )
+{
+    return (BOOL32)DdeFreeStringHandle32( idInst, hsz );
+}
+
+
+/*****************************************************************
+ *            DdeFreeStringHandle32   (USER32.101)
+ */
+BOOL32 WINAPI DdeFreeStringHandle32( DWORD idInst, HSZ hsz )
+{
+    fprintf( stdnimp, "DdeFreeStringHandle: empty stub\n" );
+    return TRUE;
+}
+
+
+/*****************************************************************
+ *            DdeFreeDataHandle16   (DDEML.19)
+ */
+BOOL16 WINAPI DdeFreeDataHandle16( HDDEDATA hData )
+{
+    return (BOOL32)DdeFreeDataHandle32( hData );
+}
+
+
+/*****************************************************************
+ *            DdeFreeDataHandle32   (USER32.100)
+ */
+BOOL32 WINAPI DdeFreeDataHandle32( HDDEDATA hData )
+{
+    fprintf( stdnimp, "DdeFreeDataHandle: empty stub\n" );
+    return TRUE;
+}
+
+
+/*****************************************************************
+ *            DdeKeepStringHandle16   (DDEML.24)
+ */
+BOOL16 WINAPI DdeKeepStringHandle16( DWORD idInst, HSZ hsz )
+{
+    return (BOOL32)DdeKeepStringHandle32( idInst, hsz );
+}
+
+
+/*****************************************************************
+ *            DdeKeepStringHandle32  (USER32.108)
+ */
+BOOL32 WINAPI DdeKeepStringHandle32( DWORD idInst, HSZ hsz )
+{
+    fprintf( stdnimp, "DdeKeepStringHandle: empty stub\n" );
+    return TRUE;
+}
+
+
+/*****************************************************************
+ *            DdeClientTransaction16  (DDEML.11)
+ */
+HDDEDATA WINAPI DdeClientTransaction16( LPVOID pData, DWORD cbData,
+                                        HCONV hConv, HSZ hszItem, UINT16 wFmt,
+                                        UINT16 wType, DWORD dwTimeout,
+                                        LPDWORD pdwResult )
+{
+    return DdeClientTransaction32( (LPBYTE)pData, cbData, hConv, hszItem,
+                                   wFmt, wType, dwTimeout, pdwResult );
+}
+
+
+/*****************************************************************
+ *            DdeClientTransaction32  (USER32.90)
+ */
+HDDEDATA WINAPI DdeClientTransaction32( LPBYTE pData, DWORD cbData,
+                                        HCONV hConv, HSZ hszItem, UINT32 wFmt,
+                                        UINT32 wType, DWORD dwTimeout,
+                                        LPDWORD pdwResult )
+{
+    fprintf( stdnimp, "DdeClientTransaction: empty stub\n" );
+    return 0;
+}
+
+
+/*****************************************************************
+ *            DdeNameService16  (DDEML.27)
+ */
+HDDEDATA WINAPI DdeNameService16( DWORD idInst, HSZ hsz1, HSZ hsz2,
+                                  UINT16 afCmd )
+{
+    return DdeNameService32( idInst, hsz1, hsz2, afCmd );
+}
+
+
+/*****************************************************************
+ *            DdeNameService32  (USER32.109)
+ */
+HDDEDATA WINAPI DdeNameService32( DWORD idInst, HSZ hsz1, HSZ hsz2,
+                                  UINT32 afCmd )
+{
+    fprintf( stdnimp, "DdeNameService: empty stub\n" );
+    return 0;
+}
+
+
+/*****************************************************************
+ *            DdeGetLastError16  (DDEML.20)
+ */
+UINT16 WINAPI DdeGetLastError16( DWORD idInst )
+{
+    return (UINT16)DdeGetLastError32( idInst );
+}
+
+
+/*****************************************************************
+ *            DdeGetLastError32  (USER32.103)
+ */
+UINT32 WINAPI DdeGetLastError32( DWORD idInst )
+{
+    fprintf( stdnimp, "DdeGetLastError: empty stub\n" );
+    return 0;
+}
+
diff --git a/misc/lstr.c b/misc/lstr.c
index f2fd7c6..2d7db18 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -132,7 +132,7 @@
 void WINAPI OutputDebugString16( LPCSTR str )
 {
     char *module;
-    char *p, *buffer = HeapAlloc( GetProcessHeap(), 0, strlen(str)+1 );
+    char *p, *buffer = HeapAlloc( GetProcessHeap(), 0, strlen(str)+2 );
     /* Remove CRs */
     for (p = buffer; *str; str++) if (*str != '\r') *p++ = *str;
     *p = '\0';
diff --git a/misc/main.c b/misc/main.c
index d267e0a..3e574de 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -205,6 +205,7 @@
 {  /* default options */
     NULL,           /* desktopGeometry */
     NULL,           /* programName */
+    NULL,           /* argv0 */
     FALSE,          /* usePrivateMap */
     FALSE,          /* useFixedMap */
     FALSE,          /* synchronous */
@@ -484,6 +485,7 @@
     char *xrm_string;
 
     Options.programName = MAIN_GetProgramName( *argc, argv );
+    Options.argv0 = argv[0];
 
       /* Get display name from command line */
     for (i = 1; i < *argc - 1; i++)
diff --git a/misc/ntdll.c b/misc/ntdll.c
index aeef87a..933ae14 100644
--- a/misc/ntdll.c
+++ b/misc/ntdll.c
@@ -510,27 +510,12 @@
 	/* returns file io completion status */
 	return 0;
 }
-/*
-These functions were originally in CRTDLL. CRTFLL now call the C-Lib 
-function directly. So they were moved here
-*/
 
-/*********************************************************************
- *                  atoi          (NDLL.885)
+
+/**************************************************************************
+ *                 NTDLL_chkstk   (NTDLL.862)
  */
-INT32 NTDLL_atoi(LPCSTR x)
+void NTDLL_chkstk(void)
 {
-    if (!x) return 0;
-    return atoi(x);
+    /* FIXME: should subtract %eax bytes from stack pointer */
 }
-
-/*********************************************************************
- *                  atol          (NTDLL.886)
- */
-LONG NTDLL_atol(LPCSTR x)
-{
-    if (!x) return 0;
-    return atol(x);
-}
-
-
diff --git a/misc/ole2.c b/misc/ole2.c
index 8996ce9..d51e275 100644
--- a/misc/ole2.c
+++ b/misc/ole2.c
@@ -22,7 +22,7 @@
 }
 
 /***********************************************************************
- *           OleInitialize       [OLE2.2]
+ *           OleInitialize       (OLE2.2) (OLE32.108)
  */
 HRESULT WINAPI OleInitialize(LPVOID reserved)
 {
@@ -31,9 +31,9 @@
 }
 
 /***********************************************************************
- *           OleUnitialize       [OLE2.3]
+ *           OleUnitialize       (OLE2.3) (OLE32.131)
  */
-void WINAPI OleUninitialize()
+void WINAPI OleUninitialize(void)
 {
     dprintf_ole(stdnimp,"OleUninitialize()\n");
 }
diff --git a/misc/shell.c b/misc/shell.c
index c701c72..22e5f7b 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -1048,3 +1048,8 @@
 		a1,a2,a3,a4
 	);
 }
+
+void WINAPI FreeIconList( DWORD dw )
+{
+    fprintf( stdnimp, "FreeIconList: empty stub\n" );
+}
diff --git a/misc/ver.c b/misc/ver.c
index dc6836c..f48ea77 100644
--- a/misc/ver.c
+++ b/misc/ver.c
@@ -416,7 +416,8 @@
 	HFILE32			lzfd;
 	OFSTRUCT		ofs;
 	BYTE			*resdata = NULL;
-	int			reslen,res;
+	int			reslen=0;
+	int			res=0;
 
 	dprintf_ver(stddeb,"GetFileResourceSize(%s,%lx,%lx,%p)\n",
 		filename,(LONG)restype,(LONG)resid,off
@@ -452,7 +453,8 @@
 	HFILE32			lzfd;
 	OFSTRUCT		ofs;
 	BYTE			*resdata=NULL;
-	int			res,reslen=datalen;
+	int			res=0;
+	int			reslen=datalen;
 
 	dprintf_ver(stddeb,"GetFileResource(%s,%lx,%lx,%ld,%ld,%p)\n",
 		filename,(LONG)restype,(LONG)resid,off,datalen,data
@@ -1196,7 +1198,7 @@
 }
 
 /* this one used for Win32 resources, which are always in UNICODE format */
-extern LPWSTR CRTDLL_wcschr(LPWSTR str,WCHAR xchar);
+extern LPWSTR CRTDLL_wcschr(LPCWSTR str,WCHAR xchar);
 static BYTE*
 _find_dataW(BYTE *block,LPCWSTR str, WORD buff_remain) {
 	LPWSTR	nextslash;
diff --git a/misc/winsock.c b/misc/winsock.c
index c4d8d3d..5aa8477 100644
--- a/misc/winsock.c
+++ b/misc/winsock.c
@@ -629,6 +629,9 @@
 	    /* application did AsyncSelect() but then went
 	     * ahead and called connect() without waiting for 
 	     * notification.
+	     *
+	     * FIXME: Do we have to post a notification message 
+	     *        in this case?
 	     */
 
 	    if( !(pws->flags & WS_FD_CONNECTED) )
@@ -641,10 +644,10 @@
 		    EVENT_AddIO( pws->fd, EVENT_IO_WRITE );
 		else
 		    EVENT_DeleteIO( pws->fd, EVENT_IO_WRITE );
-		pws->flags |= WS_FD_CONNECTED;
 	    }
 	}
-	pws->flags &= ~(WS_FD_INACTIVE | WS_FD_CONNECT);
+	pws->flags |= WS_FD_CONNECTED;
+	pws->flags &= ~(WS_FD_INACTIVE | WS_FD_CONNECT | WS_FD_LISTENING);
         return 0; 
     }
     pwsi->err = (errno == EINPROGRESS) ? WSAEWOULDBLOCK : wsaErrno();
@@ -899,14 +902,17 @@
 			    (unsigned)pwsi, s, backlog);
     if( _check_ws(pwsi, pws) )
     {
-	if( !pws->psop )
+	if (listen(pws->fd, backlog) == 0)
 	{
-	    int  fd_flags = fcntl(pws->fd, F_GETFL, 0);
-	    if( !(fd_flags & O_NONBLOCK) ) pws->flags |= WS_FD_ACCEPT;
+	    if( !pws->psop )
+	    {
+		int  fd_flags = fcntl(pws->fd, F_GETFL, 0);
+		if( !(fd_flags & O_NONBLOCK) ) pws->flags |= WS_FD_ACCEPT;
+	    }
+	    pws->flags |= WS_FD_LISTENING;
+	    pws->flags &= ~(WS_FD_INACTIVE | WS_FD_CONNECTED); /* just in case */
+	    return 0;
 	}
-	else if( !(pws->flags & WS_FD_CONNECTED) ) pws->flags |= WS_FD_LISTENING;
-
-	if (listen(pws->fd, backlog) == 0) return 0;
 	pwsi->err = wsaErrno();
     }
     else if( pwsi ) pwsi->err = WSAENOTSOCK;
@@ -1816,6 +1822,9 @@
 
 	    if((flags & WS_FD_ACCEPT) && (flags & WS_FD_LISTENING))
 	    {
+		/* WS_FD_ACCEPT is valid only if the socket is in the
+		 * listening state */
+
 		FD_CLR( fd, &io_set[EVENT_IO_WRITE] );
 		if( r )
 		{
diff --git a/misc/wsprintf.c b/misc/wsprintf.c
index 9f11e07..87a8477 100644
--- a/misc/wsprintf.c
+++ b/misc/wsprintf.c
@@ -10,6 +10,8 @@
 #include "windows.h"
 #include "ldt.h"
 #include "stackframe.h"
+#include "debug.h"
+#include "stddebug.h"
 
 #define WPRINTF_LEFTALIGN   0x0001  /* Align output on the left ('-' prefix) */
 #define WPRINTF_PREFIX_HEX  0x0002  /* Prefix hex with 0x ('#' prefix) */
@@ -249,35 +251,27 @@
         {
         case WPR_WCHAR:  /* No Unicode in Win16 */
         case WPR_CHAR:
-            cur_arg = (DWORD)*(CHAR *)args;
-            args = (WORD *)args + 1;
+            cur_arg = (DWORD)VA_ARG16( args, CHAR );
             break;
         case WPR_WSTRING:  /* No Unicode in Win16 */
         case WPR_STRING:
-            if (IsBadReadPtr16( *(SEGPTR *)args, 1 )) cur_arg = (DWORD)"";
-            else cur_arg = (DWORD)PTR_SEG_TO_LIN( *(SEGPTR *)args );
-            args = (SEGPTR *)args + 1;
+            cur_arg = (DWORD)VA_ARG16( args, SEGPTR );
+            if (IsBadReadPtr16( (SEGPTR)cur_arg, 1 )) cur_arg = (DWORD)"";
+            else cur_arg = (DWORD)PTR_SEG_TO_LIN( (SEGPTR)cur_arg );
             break;
         case WPR_SIGNED:
             if (!(format.flags & WPRINTF_LONG))
             {
-                cur_arg = (DWORD)(INT32)*(INT16 *)args;
-                args = (INT16 *)args + 1;
+                cur_arg = (DWORD)(INT32)VA_ARG16( args, INT16 );
                 break;
             }
             /* fall through */
         case WPR_HEXA:
         case WPR_UNSIGNED:
             if (format.flags & WPRINTF_LONG)
-            {
-                cur_arg = (DWORD)*(UINT32 *)args;
-                args = (UINT32 *)args + 1;
-            }
+                cur_arg = (DWORD)VA_ARG16( args, UINT32 );
             else
-            {
-                cur_arg = (DWORD)*(UINT16 *)args;
-                args = (UINT16 *)args + 1;
-            }
+                cur_arg = (DWORD)VA_ARG16( args, UINT16 );
             break;
         }
         len = WPRINTF_GetLen( &format, &cur_arg, number, maxlen - 1 );
@@ -286,11 +280,13 @@
                 *p++ = ' ';
         switch(format.type)
         {
+        case WPR_WCHAR:
         case WPR_CHAR:
             if ((*p = (CHAR)cur_arg)) p++;
             else if (format.width > 1) *p++ = ' ';
             else len = 0;
             break;
+        case WPR_WSTRING:
         case WPR_STRING:
             if (len) memcpy( p, (LPCSTR)cur_arg, len );
             p += len;
@@ -312,10 +308,6 @@
             if (len) memcpy( p, number, len );
             p += len;
             break;
-        case WPR_WCHAR:
-        case WPR_WSTRING:
-            fprintf( stderr, "Unicode not supported in wsprintf16\n" );
-            break;
         }
         if (format.flags & WPRINTF_LEFTALIGN)
             for (i = format.precision; i < format.width; i++, maxlen--)
@@ -361,7 +353,7 @@
             else len = 0;
             break;
         case WPR_STRING:
-            if (len) memcpy( p, va_arg( args, LPCSTR ), len );
+            memcpy( p, va_arg( args, LPCSTR ), len );
             p += len;
             break;
         case WPR_WSTRING:
@@ -384,7 +376,7 @@
         case WPR_SIGNED:
         case WPR_UNSIGNED:
             for (i = len; i < format.precision; i++, maxlen--) *p++ = '0';
-            if (len) memcpy( p, number, len );
+            memcpy( p, number, len );
             p += len;
             (void)va_arg( args, INT32 ); /* Go to the next arg */
             break;
@@ -395,6 +387,7 @@
         maxlen -= len;
     }
     *p = 0;
+    dprintf_string(stddeb,"%s\n",buffer);
     return (maxlen > 1) ? (INT32)(p - buffer) : -1;
 }
 
@@ -475,6 +468,7 @@
  */
 INT16 WINAPI wvsprintf16( LPSTR buffer, LPCSTR spec, LPCVOID args )
 {
+    dprintf_string(stddeb,"wvsprintf16 for %p got ",buffer);
     return wvsnprintf16( buffer, 0xffff, spec, args );
 }
 
@@ -484,6 +478,7 @@
  */
 INT32 WINAPI wvsprintf32A( LPSTR buffer, LPCSTR spec, va_list args )
 {
+    dprintf_string(stddeb,"wvsprintf32A for %p got ",buffer);
     return wvsnprintf32A( buffer, 0xffffffff, spec, args );
 }
 
@@ -493,6 +488,7 @@
  */
 INT32 WINAPI wvsprintf32W( LPWSTR buffer, LPCWSTR spec, va_list args )
 {
+    dprintf_string(stddeb,"wvsprintf32W for %p got ",buffer);
     return wvsnprintf32W( buffer, 0xffffffff, spec, args );
 }
 
@@ -506,9 +502,10 @@
     va_list valist;
     INT16 res;
 
+    dprintf_string(stddeb,"wsprintf16 for %p got ",buffer);
     va_start( valist, spec );
     /* Note: we call the 32-bit version, because the args are 32-bit */
-    res = (INT16)wvsprintf32A( buffer, spec, valist );
+    res = (INT16)wvsnprintf32A( buffer, 0xffffffff, spec, valist );
     va_end( valist );
     return res;
 }
@@ -516,11 +513,18 @@
 /* Emulator version */
 INT16 WINAPIV WIN16_wsprintf16(void)
 {
-    SEGPTR *win_stack = (SEGPTR *)CURRENT_STACK16->args;
-    LPSTR buffer = (LPSTR)PTR_SEG_TO_LIN(win_stack[0]);
-    LPCSTR spec  = (LPCSTR)PTR_SEG_TO_LIN(win_stack[1]);
-    return wvsprintf16( buffer, spec, &win_stack[2] );
+    VA_LIST16 valist;
+    INT16 res;
+    SEGPTR buffer, spec;
 
+    VA_START16( valist );
+    buffer = VA_ARG16( valist, SEGPTR );
+    spec   = VA_ARG16( valist, SEGPTR );
+    dprintf_string(stddeb,"WIN16_wsprintf16 got ");
+    res = wvsnprintf16( (LPSTR)PTR_SEG_TO_LIN(buffer), 0xffff,
+                        (LPCSTR)PTR_SEG_TO_LIN(spec), valist );
+    VA_END16( valist );
+    return res;
 }
 
 
@@ -532,8 +536,9 @@
     va_list valist;
     INT32 res;
 
+    dprintf_string(stddeb,"wsprintf32A for %p got ",buffer);
     va_start( valist, spec );
-    res = wvsprintf32A( buffer, spec, valist );
+    res = wvsnprintf32A( buffer, 0xffffffff, spec, valist );
     va_end( valist );
     return res;
 }
@@ -547,8 +552,9 @@
     va_list valist;
     INT32 res;
 
+    dprintf_string(stddeb,"wsprintf32W for %p\n",buffer);
     va_start( valist, spec );
-    res = wvsprintf32W( buffer, spec, valist );
+    res = wvsnprintf32W( buffer, 0xffffffff, spec, valist );
     va_end( valist );
     return res;
 }
diff --git a/msdos/Makefile.in b/msdos/Makefile.in
index c380feb..a11285b 100644
--- a/msdos/Makefile.in
+++ b/msdos/Makefile.in
@@ -12,6 +12,7 @@
 	int11.c \
 	int12.c \
 	int13.c \
+	int15.c \
 	int1a.c \
 	int21.c \
 	int25.c \
diff --git a/msdos/int15.c b/msdos/int15.c
new file mode 100644
index 0000000..5d3ad57
--- /dev/null
+++ b/msdos/int15.c
@@ -0,0 +1,29 @@
+/*
+ * BIOS interrupt 15h handler
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "miscemu.h"
+#include "stddebug.h"
+#include "debug.h"
+
+
+/**********************************************************************
+ *	    INT_Int15Handler
+ *
+ * Handler for int 15h (old cassette interrupt).
+ */
+void WINAPI INT_Int15Handler( CONTEXT *context )
+{
+    switch(AH_reg(context))
+    {
+    case 0x88: /* get size of memory above 1 M */
+        AX_reg(context) = 64;  /* FIXME: are 64K ok? */
+        RESET_CFLAG(context);
+        break;
+
+    default:
+        INT_BARF( context, 0x15 );
+    }
+}
diff --git a/msdos/ioports.c b/msdos/ioports.c
index 1668963..c357c37 100644
--- a/msdos/ioports.c
+++ b/msdos/ioports.c
@@ -42,12 +42,16 @@
 #endif  /* linux && __i386__ */
 
 #ifdef DIRECT_IO_ACCESS
+
+extern int iopl(int level);
+
 static char do_direct_port_access = 0;
 static char port_permissions[0x10000];
 
 #define IO_READ  1
 #define IO_WRITE 2
-#endif
+
+#endif  /* DIRECT_IO_ACCESS */
 
 /**********************************************************************
  *	    IO_port_init
diff --git a/multimedia/time.c b/multimedia/time.c
index cf4905a..a9c7976 100644
--- a/multimedia/time.c
+++ b/multimedia/time.c
@@ -17,6 +17,7 @@
 #include "mmsystem.h"
 #include "stddebug.h"
 #include "debug.h"
+#include "xmalloc.h"
 
 static BOOL32 mmTimeStarted = FALSE;
 static MMTIME mmSysTimeMS;
diff --git a/objects/brush.c b/objects/brush.c
index b3fdb31..5ef84fb 100644
--- a/objects/brush.c
+++ b/objects/brush.c
@@ -254,8 +254,8 @@
   switch(index){
   case COLOR_SCROLLBAR:
     return sysColorObjects.hbrushScrollbar;
-  case COLOR_BACKGROUND: /* same as COLOR_DESKTOP */
-    return sysColorObjects.hbrushScrollbar; /*FIXME*/
+  case COLOR_BACKGROUND: 
+    return sysColorObjects.hbrushBackground; 
   case COLOR_ACTIVECAPTION:
     return sysColorObjects.hbrushActiveCaption;
   case COLOR_INACTIVECAPTION:
@@ -265,51 +265,43 @@
   case COLOR_WINDOW:
     return sysColorObjects.hbrushWindow;
   case COLOR_WINDOWFRAME:
-    fprintf( stderr, "GetSysColorBrush32: Unimplemented index(%d)\n", index );
-    break;
+    return sysColorObjects.hbrushWindowFrame;
   case COLOR_MENUTEXT:
-    fprintf( stderr, "GetSysColorBrush32: Unimplemented index(%d)\n", index );
-    break;
+    return sysColorObjects.hbrushMenuText;
   case COLOR_WINDOWTEXT:
-    fprintf( stderr, "GetSysColorBrush32: Unimplemented index(%d)\n", index );
-    break;
+    return sysColorObjects.hbrushWindowText;
   case COLOR_CAPTIONTEXT:
-    fprintf( stderr, "GetSysColorBrush32: Unimplemented index(%d)\n", index );
-    break;
+    return sysColorObjects.hbrushCaptionText;
   case COLOR_ACTIVEBORDER:
     return sysColorObjects.hbrushActiveBorder;
   case COLOR_INACTIVEBORDER:
     return sysColorObjects.hbrushInactiveBorder;
   case COLOR_APPWORKSPACE:
-    return sysColorObjects.hbrushActiveBorder; /*FIXME*/
+    return sysColorObjects.hbrushAppWorkspace; 
   case COLOR_HIGHLIGHT:
     return sysColorObjects.hbrushHighlight;
   case COLOR_HIGHLIGHTTEXT:
-    return sysColorObjects.hbrushHighlight; /*FIXME*/
+    return sysColorObjects.hbrushHighlightText;
   case COLOR_BTNFACE: /* same as COLOR_3DFACE */
     return sysColorObjects.hbrushBtnFace;
   case COLOR_BTNSHADOW: /* same as COLOR_3DSHADOW */
     return sysColorObjects.hbrushBtnShadow;
   case COLOR_GRAYTEXT:
-    return sysColorObjects.hbrushBtnShadow; /*FIXME*/
+    return sysColorObjects.hbrushGrayText;
   case COLOR_BTNTEXT:
-    return sysColorObjects.hbrushBtnShadow; /*FIXME*/
+    return sysColorObjects.hbrushBtnText;
   case COLOR_INACTIVECAPTIONTEXT:
-    return sysColorObjects.hbrushBtnShadow; /*FIXME*/
+    return sysColorObjects.hbrushInactiveCaptionText;
   case COLOR_BTNHIGHLIGHT: /* same as COLOR_(3DHIGH|3DHI|BTNHI)LIGHT */
     return sysColorObjects.hbrushBtnHighlight;
-    /*  case COLOR_3DDKSHADOW: FIXME
-    fprintf( stderr, "GetSysColorBrush32: Unimplemented index(%d)\n", index );
-    break;
+  case COLOR_3DDKSHADOW:
+    return sysColorObjects.hbrush3DDkShadow;
   case COLOR_3DLIGHT:
-    fprintf( stderr, "GetSysColorBrush32: Unimplemented index(%d)\n", index );
-    break;
+    return sysColorObjects.hbrush3DLight;
   case COLOR_INFOTEXT:
-    fprintf( stderr, "GetSysColorBrush32: Unimplemented index(%d)\n", index );
-    break;
+    return sysColorObjects.hbrushInfoText;
   case COLOR_INFOBK:
-    fprintf( stderr, "GetSysColorBrush32: Unimplemented index(%d)\n", index );
-    break;*/
+    return sysColorObjects.hbrushInfoBk;
   default:
     fprintf( stderr, "GetSysColorBrush32: Unknown index(%d)\n", index );
   }
diff --git a/objects/dc.c b/objects/dc.c
index ed3b3fd..762459d 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -52,6 +52,7 @@
     0,                      /* breakRem */
     1,                      /* bitsPerPixel */
     MM_TEXT,                /* MapMode */
+    GM_COMPATIBLE,          /* GraphicsMode */
     0,                      /* DCOrgX */
     0,                      /* DCOrgY */
     0,                      /* CursPosX */
@@ -1038,6 +1039,42 @@
 
 
 /***********************************************************************
+ *           GetGraphicsMode    (GDI32.188)
+ */
+INT32 WINAPI GetGraphicsMode( HDC32 hdc )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return 0;
+    return dc->w.GraphicsMode;
+}
+
+
+/***********************************************************************
+ *           SetGraphicsMode    (GDI32.317)
+ */
+INT32 WINAPI SetGraphicsMode( HDC32 hdc, INT32 mode )
+{
+    INT32 ret;
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return 0;
+    if ((mode <= 0) || (mode > GM_LAST)) return 0;
+    ret = dc->w.GraphicsMode;
+    dc->w.GraphicsMode = mode;
+    return ret;
+}
+
+
+/***********************************************************************
+ *           GetWorldTransform    (GDI32.244)
+ */
+BOOL32 WINAPI GetWorldTransform( HDC32 hdc, LPXFORM xform )
+{
+    fprintf( stdnimp, "GetWorldTransform: empty stub\n" );
+    return FALSE;
+}
+
+
+/***********************************************************************
  *           SetDCHook   (GDI.190)
  */
 BOOL16 WINAPI SetDCHook( HDC16 hdc, FARPROC16 hookProc, DWORD dwHookData )
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index 6c80245..3d577f9 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -698,6 +698,42 @@
 
 
 /***********************************************************************
+ *           SetObjectOwner16    (GDI.461)
+ */
+void WINAPI SetObjectOwner16( HGDIOBJ16 handle, HANDLE16 owner )
+{
+    /* Nothing to do */
+}
+
+
+/***********************************************************************
+ *           SetObjectOwner32    (GDI32.386)
+ */
+void WINAPI SetObjectOwner32( HGDIOBJ32 handle, HANDLE32 owner )
+{
+    /* Nothing to do */
+}
+
+
+/***********************************************************************
+ *           GdiGetBatchLimit    (GDI32.129)
+ */
+DWORD WINAPI GdiGetBatchLimit(void)
+{
+    return 1;  /* FIXME */
+}
+
+
+/***********************************************************************
+ *           GdiSetBatchLimit    (GDI32.139)
+ */
+DWORD WINAPI GdiSetBatchLimit( DWORD limit )
+{
+    return 1; /* FIXME */
+}
+
+
+/***********************************************************************
  *           MulDiv16   (GDI.128)
  */
 INT16 WINAPI MulDiv16( INT16 foo, INT16 bar, INT16 baz )
diff --git a/scheduler/process.c b/scheduler/process.c
index 25087fa..4600e4d 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -280,8 +280,14 @@
     array = NULL;
 
     /* Copy the command line */
-
-    if (!(pdb->env_db->cmd_line = HEAP_strdupA( pdb->heap, 0, cmd_line )))
+    /* Fixme: Here we rely on the hack that loader/module.c put's the unprocessed
+       commandline after the processed one in Pascal notation.
+       We may access Null data if we get called another way.
+       If we have a real CreateProcess sometimes, the problem to get an unrestricted
+       commandline will go away and we won't need that hack any longer
+       */
+    if (!(pdb->env_db->cmd_line =
+	  HEAP_strdupA( pdb->heap, 0, cmd_line + (unsigned char)cmd_line[0] + 2)))
         goto error;
 
     return TRUE;
diff --git a/tools/build.c b/tools/build.c
index 4dc7962..06f6af2 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -5,6 +5,7 @@
  * Copyright 1997 Eric Youngdale
  */
 
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -33,14 +34,14 @@
 typedef enum
 {
     TYPE_INVALID,
-    TYPE_BYTE,         /* byte variable */
-    TYPE_WORD,         /* word variable */
-    TYPE_LONG,         /* long variable */
+    TYPE_BYTE,         /* byte variable (Win16) */
+    TYPE_WORD,         /* word variable (Win16) */
+    TYPE_LONG,         /* long variable (Win16) */
     TYPE_PASCAL_16,    /* pascal function with 16-bit return (Win16) */
     TYPE_PASCAL,       /* pascal function with 32-bit return (Win16) */
+    TYPE_ABS,          /* absolute value (Win16) */
+    TYPE_RETURN,       /* simple return value function (Win16) */
     TYPE_REGISTER,     /* register function */
-    TYPE_ABS,          /* absolute value */
-    TYPE_RETURN,       /* simple return value function */
     TYPE_STUB,         /* unimplemented stub */
     TYPE_STDCALL,      /* stdcall function (Win32) */
     TYPE_CDECL,        /* cdecl function (Win32) */
@@ -57,9 +58,9 @@
     "long",         /* TYPE_LONG */
     "pascal16",     /* TYPE_PASCAL_16 */
     "pascal",       /* TYPE_PASCAL */
-    "register",     /* TYPE_REGISTER */
     "equate",       /* TYPE_ABS */
     "return",       /* TYPE_RETURN */
+    "register",     /* TYPE_REGISTER */
     "stub",         /* TYPE_STUB */
     "stdcall",      /* TYPE_STDCALL */
     "cdecl",        /* TYPE_CDECL */
@@ -425,6 +426,12 @@
     odp->u.func.arg_types[i] = '\0';
     if ((odp->type == TYPE_STDCALL) && !i)
         odp->type = TYPE_CDECL; /* stdcall is the same as cdecl for 0 args */
+    if ((odp->type == TYPE_REGISTER) && (SpecType == SPEC_WIN32) && i)
+    {
+        fprintf( stderr, "%s:%d: register functions cannot have arguments in Win32\n",
+                 SpecName, Line );
+        return -1;
+    }
     strcpy(odp->u.func.link_name, GetToken());
     return 0;
 }
@@ -448,6 +455,13 @@
 	return -1;
     }
 
+    if (SpecType == SPEC_WIN32)
+    {
+        fprintf( stderr, "%s:%d: 'equate' not supported for Win32\n",
+                 SpecName, Line );
+        return -1;
+    }
+
     odp->u.abs.value = value;
     return 0;
 }
@@ -481,6 +495,13 @@
 	return -1;
     }
 
+    if (SpecType == SPEC_WIN32)
+    {
+        fprintf( stderr, "%s:%d: 'return' not supported for Win32\n",
+                 SpecName, Line );
+        return -1;
+    }
+
     return 0;
 }
 
@@ -932,116 +953,6 @@
 
 
 /*******************************************************************
- *         BuildModule32
- *
- * Build the in-memory representation of a 32-bit pseudo-NE module, and dump it
- * as a byte stream into the assembly code.
- */
-static int BuildModule32( FILE *outfile )
-{
-    char *buffer;
-    NE_MODULE *pModule;
-    OFSTRUCT *pFileInfo;
-    BYTE *pstr;
-    WORD *pword;
-
-    /*   Module layout:
-     * NE_MODULE            Module
-     * OFSTRUCT             File information
-     * SEGTABLEENTRY        Segment table (empty)
-     * WORD[2]              Resource table (empty)
-     * BYTE[2]              Imported names (empty)
-     * BYTE[n]              Resident names table (1 entry)
-     * BYTE[n]              Entry table (empty)
-     */
-
-    buffer = xmalloc( 0x10000 );
-
-    pModule = (NE_MODULE *)buffer;
-    pModule->magic = IMAGE_OS2_SIGNATURE;
-    pModule->count = 1;
-    pModule->next = 0;
-    pModule->dgroup_entry = 0;
-    pModule->flags = NE_FFLAGS_SINGLEDATA | NE_FFLAGS_BUILTIN |
-                     NE_FFLAGS_LIBMODULE | NE_FFLAGS_WIN32;
-    pModule->dgroup = 0;
-    pModule->heap_size = DLLHeapSize;
-    pModule->stack_size = 0;
-    pModule->ip = 0;
-    pModule->cs = 0;
-    pModule->sp = 0;
-    pModule->ss = 0;
-    pModule->seg_count = 0;
-    pModule->modref_count = 0;
-    pModule->nrname_size = 0;
-    pModule->modref_table = 0;
-    pModule->nrname_fpos = 0;
-    pModule->moveable_entries = 0;
-    pModule->alignment = 0;
-    pModule->truetype = 0;
-    pModule->os_flags = NE_OSFLAGS_WINDOWS;
-    pModule->misc_flags = 0;
-    pModule->dlls_to_init  = 0;
-    pModule->nrname_handle = 0;
-    pModule->min_swap_area = 0;
-    pModule->expected_version = 0x030a;
-    pModule->pe_module = NULL;
-    pModule->self = 0;
-    pModule->self_loading_sel = 0;
-
-      /* File information */
-
-    pFileInfo = (OFSTRUCT *)(pModule + 1);
-    pModule->fileinfo = (int)pFileInfo - (int)pModule;
-    memset( pFileInfo, 0, sizeof(*pFileInfo) - sizeof(pFileInfo->szPathName) );
-    pFileInfo->cBytes = sizeof(*pFileInfo) - sizeof(pFileInfo->szPathName)
-                        + strlen(DLLFileName);
-    strcpy( pFileInfo->szPathName, DLLFileName );
-    pstr = (char *)pFileInfo + pFileInfo->cBytes + 1;
-        
-      /* Segment table */
-
-    pModule->seg_table = (int)pstr - (int)pModule;
-
-      /* Resource table */
-
-    pword = (WORD *)pstr;
-    pModule->res_table = (int)pword - (int)pModule;
-    *pword++ = 0;
-    *pword++ = 0;
-
-      /* Imported names table */
-
-    pstr = (char *)pword;
-    pModule->import_table = (int)pstr - (int)pModule;
-    *pstr++ = 0;
-    *pstr++ = 0;
-
-      /* Resident names table */
-
-    pModule->name_table = (int)pstr - (int)pModule;
-    /* First entry is module name */
-    *pstr = strlen(DLLName );
-    strcpy( pstr + 1, DLLName );
-    pstr += *pstr + 1;
-    *(WORD *)pstr = 0;
-    pstr += sizeof(WORD);
-    *pstr++ = 0;
-
-      /* Entry table */
-
-    pModule->entry_table = (int)pstr - (int)pModule;
-    *pstr++ = 0;
-
-      /* Dump the module content */
-
-    DumpBytes( outfile, (char *)pModule, (int)pstr - (int)pModule,
-               ".data", "Module_Start" );
-    return (int)pstr - (int)pModule;
-}
-
-
-/*******************************************************************
  *         BuildSpec32File
  *
  * Build a Win32 assembly file from a spec file.
@@ -1049,8 +960,9 @@
 static int BuildSpec32File( char * specfile, FILE *outfile )
 {
     ORDDEF *odp;
-    int i, module_size, len;
+    int i, nb_names, nb_stubs;
     char buffer[1024];
+    unsigned char *args, *p;
 
     fprintf( outfile, "/* File generated automatically; do not edit! */\n" );
     fprintf( outfile, "\t.file\t\"%s\"\n", specfile );
@@ -1067,131 +979,54 @@
 
     fprintf( outfile, "\t.text\n" );
     fprintf( outfile, "\t.align 4\n" );
-    fprintf( outfile, "Code_Start:\n\n" );
+    fprintf( outfile, "Code_Start:\n" );
+
+    /* Output code for all register functions */
 
     for (i = Base, odp = OrdinalDefinitions + Base; i <= Limit; i++, odp++)
     {
-        switch (odp->type)
-        {
-        case TYPE_INVALID:
-            break;
-
-        case TYPE_STDCALL:
-        case TYPE_CDECL:
-        case TYPE_STUB:
-        case TYPE_REGISTER:
-            fprintf( outfile, "/* %s.%d (%s) */\n", DLLName, i, odp->name);
+        if (odp->type != TYPE_REGISTER) continue;
+        fprintf( outfile, "\n/* %s.%d (%s) */\n", DLLName, i, odp->name);
+        fprintf( outfile, "\t.align 4\n" );
 #ifdef USE_STABS
-	    fprintf( outfile, ".stabs \"%s_%d:F1\",36,0,%d,%s_%d\n", 
-		     DLLName, i, odp->lineno, DLLName, i);
+        fprintf( outfile, ".stabs \"%s_%d:F1\",36,0,%d,%s_%d\n", 
+                 DLLName, i, odp->lineno, DLLName, i);
 #endif
-            fprintf( outfile, "%s_%d:\n", DLLName, i );
+        fprintf( outfile, "%s_%d:\n", DLLName, i );
 #ifdef USE_STABS
-	    fprintf( outfile, ".stabn 68,0,%d,0\n", odp->lineno);
+        fprintf( outfile, ".stabn 68,0,%d,0\n", odp->lineno);
 #endif
-            fprintf( outfile, "\tpushl %%ebp\n" );
-            fprintf( outfile, "\tpushl $" PREFIX "%s\n",odp->u.func.link_name);
-            fprintf( outfile, "\tcall " PREFIX "CallFrom32_%s_%d\n",
-                     (odp->type == TYPE_REGISTER) ? "regs" :
-                     ((odp->type == TYPE_STDCALL) ? "stdcall" : "cdecl"),
-                     strlen(odp->u.func.arg_types));
-            fprintf( outfile, "\tnop\n" );
-            break;
-
-        case TYPE_RETURN:
-            fprintf( outfile, "/* %s.%d (%s) */\n", DLLName, i, odp->name);
-#ifdef USE_STABS
-	    fprintf( outfile, ".stabs \"%s_%d:F1\",36,0,%d,%s_%d\n", 
-		     DLLName, i, odp->lineno, DLLName, i);
-#endif
-            fprintf( outfile, "%s_%d:\n", DLLName, i );
-#ifdef USE_STABS
-	    fprintf( outfile, ".stabn 68,0,%d,0\n", odp->lineno);
-#endif
-            fprintf( outfile, "\tmovl $%d,%%eax\n", odp->u.ret.ret_value );
-            if (odp->u.ret.arg_size)
-            {
-                fprintf( outfile, "\tret $%d\n", odp->u.ret.arg_size );
-            }
-            else
-            {
-                fprintf( outfile, "\tret\n" );
-                fprintf( outfile, "\tnop\n" );
-                fprintf( outfile, "\tnop\n" );
-            }
-            break;
-
-        case TYPE_BYTE:
-            fprintf( outfile, "/* %s.%d (%s) */\n", DLLName, i, odp->name);
-            fprintf( outfile, "\t.data\n" );
-            fprintf( outfile, "%s_%d:\n", DLLName, i );
-            len = StoreVariableCode( buffer, 1, odp );
-            DumpBytes( outfile, buffer, len, NULL, NULL );
-            fprintf( outfile, "\t.text\n" );
-            break;
-
-        case TYPE_WORD:
-            fprintf( outfile, "/* %s.%d (%s) */\n",
-                     DLLName, i, odp->name);
-            fprintf( outfile, "\t.data\n" );
-            fprintf( outfile, "%s_%d:\n", DLLName, i );
-            len = StoreVariableCode( buffer, 2, odp );
-            DumpBytes( outfile, buffer, len, NULL, NULL );
-            fprintf( outfile, "\t.text\n" );
-            break;
-
-        case TYPE_LONG:
-            fprintf( outfile, "/* %s.%d (%s) */\n",
-                     DLLName, i, odp->name);
-            fprintf( outfile, "\t.data\n" );
-            fprintf( outfile, "%s_%d:\n", DLLName, i );
-            len = StoreVariableCode( buffer, 4, odp );
-            DumpBytes( outfile, buffer, len, NULL, NULL );
-            fprintf( outfile, "\t.text\n" );
-            break;
-
-        case TYPE_VARARGS:
-        case TYPE_EXTERN:
-            break;
-
-        default:
-            fprintf(stderr,"build: function type %d not available for Win32\n",
-                    odp->type);
-            return -1;
-        }
+        fprintf( outfile, "\tpushl $" PREFIX "%s\n",odp->u.func.link_name);
+        fprintf( outfile, "\tjmp " PREFIX "CALL32_Regs\n" );
     }
 
-    module_size = BuildModule32( outfile );
+    /* Output code for all stubs functions */
 
-    /* Output the DLL functions table for no debugging code */
-
-    fprintf( outfile, "\t.text\n" );
-    fprintf( outfile, "\t.align 4\n" );
-    fprintf( outfile, "NoDbg_Functions:\n" );
+    nb_stubs = 0;
     for (i = Base, odp = OrdinalDefinitions + Base; i <= Limit; i++, odp++)
     {
-        switch(odp->type)
+        if (odp->type != TYPE_STUB) continue;
+        fprintf( outfile, "\n/* %s.%d (%s) */\n", DLLName, i, odp->name);
+#ifdef USE_STABS
+        fprintf( outfile, ".stabs \"%s_%d:F1\",36,0,%d,%s_%d\n", 
+                 DLLName, i, odp->lineno, DLLName, i);
+#endif
+        fprintf( outfile, "%s_%d:\n", DLLName, i );
+#ifdef USE_STABS
+        fprintf( outfile, ".stabn 68,0,%d,0\n", odp->lineno);
+#endif
+        fprintf( outfile, "\tpushl $Name_%d\n", i );
+        fprintf( outfile, "\tpushl $%d\n", i );
+        if (++nb_stubs == 1)
         {
-        case TYPE_INVALID:
-            fprintf( outfile, "\t.long 0\n" );
-            break;
-        case TYPE_VARARGS:
-            fprintf( outfile, "\t.long " PREFIX "%s\n",odp->u.vargs.link_name);
-            break;
-        case TYPE_EXTERN:
-            fprintf( outfile, "\t.long " PREFIX "%s\n", odp->u.ext.link_name );
-            break;
-        case TYPE_STDCALL:
-        case TYPE_CDECL:
-            fprintf( outfile, "\t.long " PREFIX "%s\n", odp->u.func.link_name);
-            break;
-        default:
-            fprintf( outfile, "\t.long %s_%d\n", DLLName, i );
-            break;
+            fprintf( outfile, "DoStub:\n" );
+            fprintf( outfile, "\tpushl $DLLName\n" );
+            fprintf( outfile, "\tcall " PREFIX "RELAY_Unimplemented32\n" );
         }
+        else fprintf( outfile, "\tjmp DoStub\n" );
     }
 
-    /* Output the DLL functions table for debugging code */
+    /* Output the DLL functions table */
 
     fprintf( outfile, "\t.text\n" );
     fprintf( outfile, "\t.align 4\n" );
@@ -1209,9 +1044,18 @@
         case TYPE_EXTERN:
             fprintf( outfile, "\t.long " PREFIX "%s\n", odp->u.ext.link_name );
             break;
-        default:
+        case TYPE_STDCALL:
+        case TYPE_CDECL:
+            fprintf( outfile, "\t.long " PREFIX "%s\n", odp->u.func.link_name);
+            break;
+        case TYPE_REGISTER:
+        case TYPE_STUB:
             fprintf( outfile, "\t.long %s_%d\n", DLLName, i );
             break;
+        default:
+            fprintf(stderr,"build: function type %d not available for Win32\n",
+                    odp->type);
+            return -1;
         }
     }
 
@@ -1220,8 +1064,20 @@
     fprintf( outfile, "FuncNames:\n" );
     for (i = Base, odp = OrdinalDefinitions + Base; i <= Limit; i++, odp++)
     {
-        if (odp->type == TYPE_INVALID) fprintf( outfile, "\t.long 0\n" );
-        else fprintf( outfile, "\t.long Name_%d\n", i );
+        if (odp->type != TYPE_INVALID)
+            fprintf( outfile, "\t.long Name_%d\n", i );
+    }
+
+    /* Output the DLL ordinals table */
+
+    fprintf( outfile, "FuncOrdinals:\n" );
+    nb_names = 0;
+    for (i = Base, odp = OrdinalDefinitions + Base; i <= Limit; i++, odp++)
+    {
+        if (odp->type == TYPE_INVALID) continue;
+        nb_names++;
+        /* Some assemblers do not have .word */
+        fprintf( outfile, "\t.byte %d,%d\n", LOBYTE(i), HIBYTE(i) );
     }
 
     /* Output the DLL names */
@@ -1232,6 +1088,29 @@
             fprintf( outfile, "Name_%d:\t.ascii \"%s\\0\"\n", i, odp->name );
     }
 
+    /* Output the DLL functions arguments */
+
+    args = p = (unsigned char *)xmalloc( Limit - Base + 1 );
+    for (i = Base, odp = OrdinalDefinitions + Base; i <= Limit; i++, odp++)
+    {
+        switch(odp->type)
+        {
+        case TYPE_STDCALL:
+            *p++ = (unsigned char)strlen(odp->u.func.arg_types);
+            break;
+        case TYPE_CDECL:
+            *p++ = 0x80 | (unsigned char)strlen(odp->u.func.arg_types);
+            break;
+        case TYPE_REGISTER:
+            *p++ = 0xfe;
+            break;
+        default:
+            *p++ = 0xff;
+            break;
+        }
+    }
+    DumpBytes( outfile, args, Limit - Base + 1, NULL, "FuncArgs" );
+
     /* Output the DLL descriptor */
 
     fprintf( outfile, "DLLName:\t.ascii \"%s\\0\"\n", DLLName );
@@ -1239,14 +1118,13 @@
     fprintf( outfile, "\t.globl " PREFIX "%s_Descriptor\n", DLLName );
     fprintf( outfile, PREFIX "%s_Descriptor:\n", DLLName );
     fprintf( outfile, "\t.long DLLName\n" );          /* Name */
-    fprintf( outfile, "\t.long Module_Start\n" );     /* Module start */
-    fprintf( outfile, "\t.long %d\n", module_size );  /* Module size */
     fprintf( outfile, "\t.long %d\n", Base );         /* Base */
-    fprintf( outfile, "\t.long %d\n", Limit+1-Base ); /* Size */
-    fprintf( outfile, "\t.long Code_Start\n" );       /* Code start */
+    fprintf( outfile, "\t.long %d\n", Limit+1-Base ); /* Number of functions */
+    fprintf( outfile, "\t.long %d\n", nb_names );     /* Number of names */
     fprintf( outfile, "\t.long Functions\n" );        /* Functions */
-    fprintf( outfile, "\t.long NoDbg_Functions\n" );  /* Funcs without debug*/
     fprintf( outfile, "\t.long FuncNames\n" );        /* Function names */
+    fprintf( outfile, "\t.long FuncOrdinals\n" );     /* Function ordinals */
+    fprintf( outfile, "\t.long FuncArgs\n" );         /* Function arguments */
 #ifdef USE_STABS
     fprintf( outfile, "\t.text\n");
     fprintf( outfile, "\t.stabs \"\",100,0,0,.Letext\n");
@@ -1411,77 +1289,6 @@
 
 
 /*******************************************************************
- *         BuildCall32LargeStack
- *
- * Build the function used to switch to the original 32-bit stack
- * before calling a 32-bit function from 32-bit code. This is used for
- * functions that need a large stack, like X bitmaps functions.
- *
- * The generated function has the following prototype:
- *   int xxx( int (*func)(), void *arg );
- *
- * The pointer to the function can be retrieved by calling CALL32_Init,
- * which also takes care of saving the current 32-bit stack pointer.
- *
- * Stack layout:
- *   ...     ...
- * (ebp+12)  arg
- * (ebp+8)   func
- * (ebp+4)   ret addr
- * (ebp)     ebp
- */
-static void BuildCall32LargeStack( FILE *outfile )
-{
-    /* Initialization function */
-
-    fprintf( outfile, "\n\t.align 4\n" );
-#ifdef USE_STABS
-    fprintf( outfile, ".stabs \"CALL32_Init:F1\",36,0,0," PREFIX "CALL32_Init\n");
-#endif
-    fprintf( outfile, "\t.globl " PREFIX "CALL32_Init\n" );
-    fprintf( outfile, PREFIX "CALL32_Init:\n" );
-    fprintf( outfile, "\tleal -256(%%esp),%%eax\n" );
-    fprintf( outfile, "\tmovl %%eax,CALL32_Original32_esp\n" );
-    fprintf( outfile, "\tmovl $CALL32_LargeStack,%%eax\n" );
-    fprintf( outfile, "\tret\n" );
-
-    /* Function header */
-
-    fprintf( outfile, "\n\t.align 4\n" );
-#ifdef USE_STABS
-    fprintf( outfile, ".stabs \"CALL32_LargeStack:F1\",36,0,0,CALL32_LargeStack\n");
-#endif
-    fprintf( outfile, "CALL32_LargeStack:\n" );
-    
-    /* Entry code */
-
-    fprintf( outfile, "\tpushl %%ebp\n" );
-    fprintf( outfile, "\tmovl %%esp,%%ebp\n" );
-
-    /* Switch to the original 32-bit stack pointer */
-
-    fprintf( outfile, "\tmovl CALL32_Original32_esp, %%esp\n" );
-
-    /* Transfer the argument and call the function */
-
-    fprintf( outfile, "\tpushl 12(%%ebp)\n" );
-    fprintf( outfile, "\tcall 8(%%ebp)\n" );
-
-    /* Restore registers and return */
-
-    fprintf( outfile, "\tmovl %%ebp,%%esp\n" );
-    fprintf( outfile, "\tpopl %%ebp\n" );
-    fprintf( outfile, "\tret\n" );
-
-    /* Data */
-
-    fprintf( outfile, "\t.data\n" );
-    fprintf( outfile, "CALL32_Original32_esp:\t.long 0\n" );
-    fprintf( outfile, "\t.text\n" );
-}
-
-
-/*******************************************************************
  *         TransferArgs16To32
  *
  * Get the arguments from the 16-bit stack and push them on the 32-bit stack.
@@ -2028,7 +1835,7 @@
 
         /* Push the return address */
 
-        fprintf( outfile, "\tpushl " PREFIX "CALLTO16_RetAddr_long\n" );
+        fprintf( outfile, "\tpushl " PREFIX "CALLTO16_RetAddr_regs\n" );
 
         /* Push the called routine address */
 
@@ -2111,16 +1918,25 @@
 {
     fprintf( outfile, "\t.globl " PREFIX "CALLTO16_Ret_word\n" );
     fprintf( outfile, "\t.globl " PREFIX "CALLTO16_Ret_long\n" );
+    fprintf( outfile, "\t.globl " PREFIX "CALLTO16_Ret_regs\n" );
 
-    /* Put return value into eax */
+    fprintf( outfile, PREFIX "CALLTO16_Ret_word:\n" );
+    fprintf( outfile, "\txorl %%edx,%%edx\n" );
+
+    /* Remove the arguments just in case */
 
     fprintf( outfile, PREFIX "CALLTO16_Ret_long:\n" );
+    fprintf( outfile, "\tleal -%d(%%ebp),%%esp\n",
+                 STRUCTOFFSET(STACK16FRAME,bp) + 4 /* for saved %%esp */ );
+
+    /* Put return value into %eax */
+
+    fprintf( outfile, PREFIX "CALLTO16_Ret_regs:\n" );
     fprintf( outfile, "\tshll $16,%%edx\n" );
     fprintf( outfile, "\tmovw %%ax,%%dx\n" );
     fprintf( outfile, "\tmovl %%edx,%%eax\n" );
-    fprintf( outfile, PREFIX "CALLTO16_Ret_word:\n" );
 
-    /* Restore 32-bit segment registers */
+    /* Restore 32-bit segment registers and stack*/
 
     fprintf( outfile, "\tpopl %%ecx\n" );  /* Get the saved %%esp */
     fprintf( outfile, "\tmovw $0x%04x,%%bx\n", WINE_DATA_SELECTOR );
@@ -2158,30 +1974,120 @@
     fprintf( outfile, "\t.data\n" );
     fprintf( outfile, "\t.globl " PREFIX "CALLTO16_RetAddr_word\n" );
     fprintf( outfile, "\t.globl " PREFIX "CALLTO16_RetAddr_long\n" );
+    fprintf( outfile, "\t.globl " PREFIX "CALLTO16_RetAddr_regs\n" );
     fprintf( outfile, "\t.globl " PREFIX "CALLTO16_Saved32_esp\n" );
     fprintf( outfile, PREFIX "CALLTO16_RetAddr_word:\t.long 0\n" );
     fprintf( outfile, PREFIX "CALLTO16_RetAddr_long:\t.long 0\n" );
+    fprintf( outfile, PREFIX "CALLTO16_RetAddr_regs:\t.long 0\n" );
     fprintf( outfile, PREFIX "CALLTO16_Saved32_esp:\t.long 0\n" );
     fprintf( outfile, "\t.text\n" );
 }
 
 
 /*******************************************************************
- *         BuildContext32
+ *         BuildCallTo32LargeStack
  *
- * Build the CONTEXT structure on the stack.
+ * Build the function used to switch to the original 32-bit stack
+ * before calling a 32-bit function from 32-bit code. This is used for
+ * functions that need a large stack, like X bitmaps functions.
+ *
+ * The generated function has the following prototype:
+ *   int xxx( int (*func)(), void *arg );
+ *
+ * The pointer to the function can be retrieved by calling CALL32_Init,
+ * which also takes care of saving the current 32-bit stack pointer.
+ *
+ * Stack layout:
+ *   ...     ...
+ * (ebp+12)  arg
+ * (ebp+8)   func
+ * (ebp+4)   ret addr
+ * (ebp)     ebp
  */
-static void BuildContext32( FILE *outfile )
+static void BuildCallTo32LargeStack( FILE *outfile )
 {
+    /* Initialization function */
+
+    fprintf( outfile, "\n\t.align 4\n" );
+#ifdef USE_STABS
+    fprintf( outfile, ".stabs \"CALL32_Init:F1\",36,0,0," PREFIX "CALL32_Init\n");
+#endif
+    fprintf( outfile, "\t.globl " PREFIX "CALL32_Init\n" );
+    fprintf( outfile, PREFIX "CALL32_Init:\n" );
+    fprintf( outfile, "\tleal -256(%%esp),%%eax\n" );
+    fprintf( outfile, "\tmovl %%eax,CALL32_Original32_esp\n" );
+    fprintf( outfile, "\tmovl $CALL32_LargeStack,%%eax\n" );
+    fprintf( outfile, "\tret\n" );
+
+    /* Function header */
+
+    fprintf( outfile, "\n\t.align 4\n" );
+#ifdef USE_STABS
+    fprintf( outfile, ".stabs \"CALL32_LargeStack:F1\",36,0,0,CALL32_LargeStack\n");
+#endif
+    fprintf( outfile, "CALL32_LargeStack:\n" );
+    
+    /* Entry code */
+
+    fprintf( outfile, "\tpushl %%ebp\n" );
+    fprintf( outfile, "\tmovl %%esp,%%ebp\n" );
+
+    /* Switch to the original 32-bit stack pointer */
+
+    fprintf( outfile, "\tmovl CALL32_Original32_esp, %%esp\n" );
+
+    /* Transfer the argument and call the function */
+
+    fprintf( outfile, "\tpushl 12(%%ebp)\n" );
+    fprintf( outfile, "\tcall 8(%%ebp)\n" );
+
+    /* Restore registers and return */
+
+    fprintf( outfile, "\tmovl %%ebp,%%esp\n" );
+    fprintf( outfile, "\tpopl %%ebp\n" );
+    fprintf( outfile, "\tret\n" );
+
+    /* Data */
+
+    fprintf( outfile, "\t.data\n" );
+    fprintf( outfile, "CALL32_Original32_esp:\t.long 0\n" );
+    fprintf( outfile, "\t.text\n" );
+}
+
+
+/*******************************************************************
+ *         BuildCallFrom32Regs
+ *
+ * Build a 32-bit-to-Wine call-back function for a 'register' function.
+ * 'args' is the number of dword arguments.
+ *
+ * Stack layout:
+ *   ...     ...
+ * (esp+208) ret addr (or relay addr when debugging_relay is on)
+ * (esp+204) entry point
+ * (esp+0)   CONTEXT struct
+ */
+static void BuildCallFrom32Regs( FILE *outfile )
+{
+    /* Function header */
+
+    fprintf( outfile, "\n\t.align 4\n" );
+#ifdef USE_STABS
+    fprintf( outfile, ".stabs \"CALL32_Regs:F1\",36,0,0," PREFIX "CALL32_Regs\n" );
+#endif
+    fprintf( outfile, "\t.globl " PREFIX "CALL32_Regs\n" );
+    fprintf( outfile, PREFIX "CALL32_Regs:\n" );
+
     /* Build the context structure */
 
     fprintf( outfile, "\tpushw $0\n" );
     fprintf( outfile, "\tpushw %%ss\n" );
-    fprintf( outfile, "\tpushl %%eax\n" );  /* %esp */
+    fprintf( outfile, "\tpushl %%eax\n" );  /* %esp place holder */
     fprintf( outfile, "\tpushfl\n" );
     fprintf( outfile, "\tpushw $0\n" );
     fprintf( outfile, "\tpushw %%cs\n" );
-    fprintf( outfile, "\tsubl $8,%%esp\n" );  /* %eip + %ebp */
+    fprintf( outfile, "\tpushl 20(%%esp)\n" );  /* %eip at time of call */
+    fprintf( outfile, "\tpushl %%ebp\n" );
 
     fprintf( outfile, "\tpushl %%eax\n" );
     fprintf( outfile, "\tpushl %%ecx\n" );
@@ -2200,56 +2106,31 @@
     fprintf( outfile, "\tmovw %%gs,%%ax\n" );
     fprintf( outfile, "\tpushl %%eax\n" );
 
-    fprintf( outfile, "\tsubl $%d,%%esp\n",
+    fprintf( outfile, "\tleal -%d(%%esp),%%esp\n",
              sizeof(FLOATING_SAVE_AREA) + 6 * sizeof(DWORD) /* DR regs */ );
     fprintf( outfile, "\tpushl $0x0001001f\n" );  /* ContextFlags */
 
     fprintf( outfile, "\tfsave %d(%%esp)\n", CONTEXTOFFSET(FloatSave) );
 
-    fprintf( outfile, "\tmovl 4(%%ebp),%%eax\n" ); /* %eip at time of call */
-    fprintf( outfile, "\tmovl %%eax,%d(%%esp)\n", CONTEXTOFFSET(Eip) );
-    fprintf( outfile, "\tmovl 0(%%ebp),%%eax\n" ); /* %ebp at time of call */
-    fprintf( outfile, "\tmovl %%eax,%d(%%esp)\n", CONTEXTOFFSET(Ebp) );
-    fprintf( outfile, "\tleal 8(%%ebp),%%eax\n" ); /* %esp at time of call */
+    fprintf( outfile, "\tleal %d(%%esp),%%eax\n",
+             sizeof(CONTEXT) + 4 ); /* %esp at time of call */
     fprintf( outfile, "\tmovl %%eax,%d(%%esp)\n", CONTEXTOFFSET(Esp) );
 
-    /* Push pointer to context */
+    fprintf( outfile, "\tcall " PREFIX "RELAY_CallFrom32Regs\n" );
 
-    fprintf( outfile, "\tpushl %%esp\n" );
-}
-
-
-/*******************************************************************
- *         RestoreContext32
- *
- * Restore the registers from the context structure.
- * All registers except %cs and %ss are restored.
- */
-static void RestoreContext32( FILE *outfile )
-{
     /* Restore the context structure */
 
-    fprintf( outfile, "\tleal %d(%%ebp),%%esp\n", -sizeof(CONTEXT)-8 );
     fprintf( outfile, "\tfrstor %d(%%esp)\n", CONTEXTOFFSET(FloatSave) );
 
-    /* Store flags over the relay addr */
-    fprintf( outfile, "\tmovl %d(%%esp),%%eax\n", CONTEXTOFFSET(EFlags) );
-    fprintf( outfile, "\tmovl %%eax,%d(%%esp)\n", sizeof(CONTEXT) );
+    /* Store %eip value onto the new stack */
 
-    /* Get the new stack addr */
-    fprintf( outfile, "\tmovl %d(%%esp),%%ebx\n", CONTEXTOFFSET(Esp) );
-
-    /* Set eip and ebp value onto the new stack */
     fprintf( outfile, "\tmovl %d(%%esp),%%eax\n", CONTEXTOFFSET(Eip) );
-    fprintf( outfile, "\tmovl %%eax,-4(%%ebx)\n" ); /* %eip at time of call */
-    fprintf( outfile, "\tmovl %d(%%esp),%%eax\n", CONTEXTOFFSET(Ebp) );
-    fprintf( outfile, "\tmovl %%eax,-8(%%ebx)\n" ); /* %ebp at time of call */
-
-    /* Set ebp to point to the new stack */
-    fprintf( outfile, "\tleal -8(%%ebx),%%ebp\n" );
+    fprintf( outfile, "\tmovl %d(%%esp),%%ebx\n", CONTEXTOFFSET(Esp) );
+    fprintf( outfile, "\tmovl %%eax,0(%%ebx)\n" );
 
     /* Restore all registers */
-    fprintf( outfile, "\taddl $%d,%%esp\n",
+
+    fprintf( outfile, "\tleal %d(%%esp),%%esp\n",
              sizeof(FLOATING_SAVE_AREA) + 7 * sizeof(DWORD) );
     fprintf( outfile, "\tpopl %%eax\n" );
     fprintf( outfile, "\tmovw %%ax,%%gs\n" );
@@ -2266,124 +2147,11 @@
     fprintf( outfile, "\tpopl %%edx\n" );
     fprintf( outfile, "\tpopl %%ecx\n" );
     fprintf( outfile, "\tpopl %%eax\n" );
-
-    fprintf( outfile, "\taddl $%d,%%esp\n",
-             6 * sizeof(DWORD) /* %ebp + %eip + %cs + %efl + %esp + %ss */ );
-    fprintf( outfile, "\tpopfl\n" );
-}
-
-
-/*******************************************************************
- *         BuildCallFrom32Func
- *
- * Build a 32-bit-to-Wine call-back function.
- * 'args' is the number of dword arguments.
- *
- * Stack layout:
- *   ...     ...
- * (ebp+12)  arg2
- * (ebp+8)   arg1
- * (ebp+4)   ret addr
- * (ebp)     ebp
- * (ebp-4)   entry point
- * (ebp-8)   relay addr
- */
-static void BuildCallFrom32Func( FILE *outfile, const char *profile )
-{
-    int args, stdcall, reg_func;
-
-    if (!strncmp( profile, "stdcall", 7 ))
-    {
-        stdcall = 1;
-        reg_func = 0;
-        args = atoi( profile + 8 );
-    }
-    else if (!strncmp( profile, "cdecl", 5 ))
-    {
-        stdcall = reg_func = 0;
-        args = atoi( profile + 6 );
-    }
-    else if (!strncmp( profile, "regs", 4 ))
-    {
-        stdcall = reg_func = 1;
-        args = atoi( profile + 5 );
-    }
-    else
-    {
-        fprintf( stderr, "Invalid function profile '%s', ignored\n", profile );
-        return;
-    }
-
-    /* Function header */
-
-    fprintf( outfile, "\n\t.align 4\n" );
-#ifdef USE_STABS
-    fprintf( outfile, ".stabs \"CallFrom32_%s:F1\",36,0,0," PREFIX "CallFrom32_%s\n", 
-	     profile, profile);
-#endif
-    fprintf( outfile, "\t.globl " PREFIX "CallFrom32_%s\n", profile );
-    fprintf( outfile, PREFIX "CallFrom32_%s:\n", profile );
-
-    /* Entry code */
-
-    fprintf( outfile, "\tleal 8(%%esp),%%ebp\n" );
-
-    /* Transfer the arguments */
-
-    if (reg_func) BuildContext32( outfile );
-
-    if (args)
-    {
-        int i;
-        for (i = args; i > 0; i--)
-            fprintf( outfile, "\tpushl %d(%%ebp)\n", 4 * i + 4 );
-    }
-
-#if 0
-    /* Set %es = %ds */
-
-    fprintf( outfile, "\tmovw %%ds,%%ax\n" );
-    fprintf( outfile, "\tmovw %%ax,%%es\n" );
-#endif
-
-    /* Print the debugging info */
-
-    if (debugging)
-    {
-        fprintf( outfile, "\tpushl $%d\n",  /* Nb args */
-                 reg_func ? args | 0x80000000 : args);
-        fprintf( outfile, "\tpushl %%ebp\n" );
-        fprintf( outfile, "\tcall " PREFIX "RELAY_DebugCallFrom32\n" );
-        fprintf( outfile, "\tadd $8, %%esp\n" );
-    }
-
-    /* Call the function */
-
-    fprintf( outfile, "\tcall -4(%%ebp)\n" );
-
-    /* Print the debugging info */
-
-    if (debugging)
-    {
-        fprintf( outfile, "\tpushl %%eax\n" );
-        fprintf( outfile, "\tpushl $%d\n",  /* Nb args */
-                 reg_func ? args | 0x80000000 : args);
-        fprintf( outfile, "\tpushl %%ebp\n" );
-        fprintf( outfile, "\tcall " PREFIX "RELAY_DebugCallFrom32Ret\n" );
-        fprintf( outfile, "\tpopl %%eax\n" );
-        fprintf( outfile, "\tpopl %%eax\n" );
-        fprintf( outfile, "\tpopl %%eax\n" );
-    }
-
-    if (reg_func) RestoreContext32( outfile );
-
-    fprintf( outfile, "\tmovl %%ebp,%%esp\n" );
     fprintf( outfile, "\tpopl %%ebp\n" );
-
-    /* Return, removing arguments */
-
-    if (args && stdcall) fprintf( outfile, "\tret $%d\n", args * 4 );
-    else fprintf( outfile, "\tret\n" );
+    fprintf( outfile, "\tleal 8(%%esp),%%esp\n" );  /* skip %eip and %cs */
+    fprintf( outfile, "\tpopfl\n" );
+    fprintf( outfile, "\tpopl %%esp\n" );
+    fprintf( outfile, "\tret\n" );
 }
 
 
@@ -2512,14 +2280,13 @@
 
 
 /*******************************************************************
- *         BuildCallFrom32
+ *         BuildCall32
  *
- * Build the 32-bit-to-Wine callbacks
+ * Build the 32-bit callbacks
  */
-static int BuildCallFrom32( FILE *outfile, char * outname, int argc, char *argv[] )
+static int BuildCall32( FILE *outfile, char * outname )
 {
     char buffer[1024];
-    int i;
 
     /* File header */
 
@@ -2538,16 +2305,16 @@
     fprintf( outfile, ".stabs \"%s\",100,0,0,Code_Start\n", outname);
     fprintf( outfile, "\t.text\n" );
     fprintf( outfile, "\t.align 4\n" );
-    fprintf( outfile, "Code_Start:\n\n" );
+    fprintf( outfile, "Code_Start:\n" );
 #endif
 
-    /* Build the callback functions */
-
-    for (i = 2; i < argc; i++) BuildCallFrom32Func( outfile, argv[i] );
-
     /* Build the 32-bit large stack callback */
 
-    BuildCall32LargeStack( outfile );
+    BuildCallTo32LargeStack( outfile );
+
+    /* Build the register callback function */
+
+    BuildCallFrom32Regs( outfile );
 
 #ifdef USE_STABS
     fprintf( outfile, "\t.text\n");
@@ -2568,7 +2335,7 @@
              "usage: build [-o outfile] -spec SPECNAMES\n"
              "       build [-o outfile] -callfrom16 FUNCTION_PROFILES\n"
              "       build [-o outfile] -callto16 FUNCTION_PROFILES\n"
-             "       build [-o outfile] -callfrom32 FUNCTION_PROFILES\n" );
+             "       build [-o outfile] -call32\n" );
     exit(1);
 }
 
@@ -2582,14 +2349,14 @@
     FILE *outfile = stdout;
     int res = -1;
 
-    if (argc <= 2) usage();
+    if (argc < 2) usage();
 
     if (!strcmp( argv[1], "-o" ))
     {
         outname = argv[2];
         argv += 2;
         argc -= 2;
-        if (argc <= 2) usage();
+        if (argc < 2) usage();
         if (!(outfile = fopen( outname, "w" )))
         {
             fprintf( stderr, "Unable to create output file '%s'\n", outname );
@@ -2603,8 +2370,8 @@
         res = BuildCallFrom16( outfile, outname, argc, argv );
     else if (!strcmp( argv[1], "-callto16" ))
         res = BuildCallTo16( outfile, outname, argc, argv );
-    else if (!strcmp( argv[1], "-callfrom32" ))
-        res = BuildCallFrom32( outfile, outname, argc, argv );
+    else if (!strcmp( argv[1], "-call32" ))
+        res = BuildCall32( outfile, outname );
     else
     {
         fclose( outfile );
diff --git a/tools/makedep.c b/tools/makedep.c
index 2bb6552..11f77d3 100644
--- a/tools/makedep.c
+++ b/tools/makedep.c
@@ -268,13 +268,13 @@
     {
         if (!strcmp( ext, ".y" ))  /* yacc file */
         {
-            fprintf( file, "y.tab.o: ./y.tab.c" );
-            *column += 18;
+            fprintf( file, "y.tab.o: y.tab.c" );
+            *column += 16;
         }
         else if (!strcmp( ext, ".l" ))  /* lex file */
         {
-            fprintf( file, "lex.yy.o: ./lex.yy.c" );
-            *column += 20;
+            fprintf( file, "lex.yy.o: lex.yy.c" );
+            *column += 18;
         }
         else if (!strcmp( ext, ".rc" ))  /* resource file */
         {
diff --git a/win32/advapi.c b/win32/advapi.c
index d6c25c0..33b4720 100644
--- a/win32/advapi.c
+++ b/win32/advapi.c
@@ -6,6 +6,7 @@
 
 #include <stdio.h>
 #include <unistd.h>
+#include <time.h>
 #include "windows.h"
 #include "winerror.h"
 #include "shell.h"
diff --git a/win32/environment.c b/win32/environment.c
index 1d676f8..90a0bf3 100644
--- a/win32/environment.c
+++ b/win32/environment.c
@@ -13,6 +13,7 @@
 #include "task.h"
 #include "stddebug.h"
 #include "debug.h"
+#include "process.h"  /* for pCurrentProcess */
 
 
 /***********************************************************************
@@ -20,21 +21,7 @@
  */
 LPCSTR WINAPI GetCommandLine32A(void)
 {
-    static char buffer[256];
-    char *cp;
-    PDB *pdb = (PDB *)GlobalLock16( GetCurrentPDB() );
-
-    /* FIXME: should use pCurrentProcess->env_db->cmd_line here */
-    lstrcpyn32A( buffer, MODULE_GetModuleName(GetCurrentTask()),
-                 sizeof(buffer) - 1 );
-    cp = buffer + strlen(buffer);
-    if (pdb->cmdLine[0])
-    {
-        *cp++ = ' ';
-        memcpy( cp, &pdb->cmdLine[1], pdb->cmdLine[0] );
-    }
-    dprintf_win32(stddeb,"CommandLine = %s\n", buffer );
-    return buffer;
+    return pCurrentProcess->env_db->cmd_line;
 }
 
 /***********************************************************************
diff --git a/win32/except.c b/win32/except.c
index 4fbcd9d..149d32f 100644
--- a/win32/except.c
+++ b/win32/except.c
@@ -46,25 +46,6 @@
     ((PEXCEPTION_FRAME)((TEB *)GET_SEL_BASE((pcontext)->SegFs))->except)
 
 /*******************************************************************
- *         _local_unwind2  (CRTDLL)
- */
-void WINAPI CRTDLL__local_unwind2(PEXCEPTION_FRAME endframe,DWORD nr,
-                                  PCONTEXT pcontext)
-{
-	fprintf(stderr,"CRTDLL__local_unwind2(%p,%ld)\n",endframe,nr);
-	return;
-}
-
-/*******************************************************************
- *         _global_unwind2  (CRTDLL)
- */
-void WINAPI CRTDLL__global_unwind2(PEXCEPTION_FRAME endframe,PCONTEXT pcontext)
-{
-	RtlUnwind(endframe,NULL/*should point to the return;*/,NULL,0,pcontext);
-	return;
-}
-
-/*******************************************************************
  *         RtlUnwind  (KERNEL32.443)
  *
  *  This function is undocumented. This is the general idea of 
@@ -78,7 +59,7 @@
    DWORD            dispatch;
    int              retval;
   
-   pcontext->Eax=returnEax;
+   EAX_reg(pcontext) = returnEax;
    
    /* build an exception record, if we do not have one */
    if(!pRecord)
@@ -86,7 +67,7 @@
      record.ExceptionCode    = STATUS_INVALID_DISPOSITION;
      record.ExceptionFlags   = 0;
      record.ExceptionRecord  = NULL;
-     record.ExceptionAddress = (LPVOID)pcontext->Eip; 
+     record.ExceptionAddress = (LPVOID)EIP_reg(pcontext); 
      record.NumberParameters = 0;
      pRecord = &record;
    }
@@ -125,6 +106,16 @@
    }
 }
 
+/* This is the real entry point called by relay debugging code */
+void EXC_RtlUnwind( CONTEXT *context )
+{
+    /* Retrieve the arguments (args[0] is return addr, args[1] is first arg) */
+    DWORD *args = (DWORD *)ESP_reg(context);
+    ESP_reg(context) += 4 * sizeof(DWORD);  /* Pop the arguments */
+    RtlUnwind( (PEXCEPTION_FRAME)args[1], (LPVOID)args[2],
+               (PEXCEPTION_RECORD)args[3], args[4], context );
+}
+
 
 /*******************************************************************
  *         RaiseException  (KERNEL32.418)
@@ -147,7 +138,7 @@
     record.ExceptionFlags      = dwExceptionFlags;
     record.ExceptionRecord     = NULL;
     record.NumberParameters    = cArguments;
-    record.ExceptionAddress    = (LPVOID) pcontext->Eip;
+    record.ExceptionAddress    = (LPVOID)EIP_reg(pcontext);
     
     if (lpArguments) for( i = 0; i < cArguments; i++)
         record.ExceptionInformation[i] = lpArguments[i];
@@ -162,6 +153,8 @@
        dprintf_win32(stddeb,"calling exception handler at 0x%x\n",
                                                 (int) pframe->Handler);
        dispatch=0;  
+       dprintf_relay(stddeb,"CallTo32(except=%p,record=%p,frame=%p,context=%p,dispatch=%p)\n",
+                     pframe->Handler, &record, pframe, pcontext, &dispatch );
        retval=pframe->Handler(&record,pframe,pcontext,&dispatch);
  
        dprintf_win32(stddeb,"exception handler returns 0x%x, dispatch=0x%x\n",
@@ -180,6 +173,14 @@
    }
 }
 
+/* This is the real entry point called by relay debugging code */
+void EXC_RaiseException( CONTEXT *context )
+{
+    /* Retrieve the arguments (args[0] is return addr, args[1] is first arg) */
+    DWORD *args = (DWORD *)ESP_reg(context);
+    ESP_reg(context) += 4 * sizeof(DWORD);  /* Pop the arguments */
+    RaiseException( args[1], args[2], args[3], (LPDWORD)args[4], context );
+}
 
 /*******************************************************************
  *         UnhandledExceptionFilter   (KERNEL32.537)
diff --git a/win32/security.c b/win32/security.c
index 4f7ef47..62c6bd2 100644
--- a/win32/security.c
+++ b/win32/security.c
@@ -118,6 +118,17 @@
 }
 
 /***********************************************************************
+ *           InitializeSecurityDescriptor  (ADVAPI.73)
+ */
+BOOL32 WINAPI InitializeSecurityDescriptor( SECURITY_DESCRIPTOR *pDescr,
+                                            DWORD revision )
+{
+    fprintf( stdnimp, "InitializeSecurityDescriptor: empty stub\n" );
+    return TRUE;
+}
+
+
+/***********************************************************************
  *           InitializeSid  (ADVAPI.74)
  */
 BOOL32 WINAPI InitializeSid (LPSID pSid, LPSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
diff --git a/windows/syscolor.c b/windows/syscolor.c
index fc1fb9d..45d2f73 100644
--- a/windows/syscolor.c
+++ b/windows/syscolor.c
@@ -23,7 +23,7 @@
     "Background", "192 192 192",     /* COLOR_BACKGROUND          */
     "ActiveTitle", "0 64 128",       /* COLOR_ACTIVECAPTION       */
     "InactiveTitle", "255 255 255",  /* COLOR_INACTIVECAPTION     */
-    "Menu", "255 255 255",             /* COLOR_MENU                */
+    "Menu", "255 255 255",           /* COLOR_MENU                */
     "Window", "255 255 255",         /* COLOR_WINDOW              */
     "WindowFrame", "0 0 0",          /* COLOR_WINDOWFRAME         */
     "MenuText", "0 0 0",             /* COLOR_MENUTEXT            */
@@ -97,6 +97,8 @@
 	sysColorObjects.hbrushScrollbar = CreateSolidBrush32( color );
 	break;
     case COLOR_BACKGROUND:
+	DeleteObject32( sysColorObjects.hbrushBackground );
+	sysColorObjects.hbrushBackground = CreateSolidBrush32( color );
 	break;
     case COLOR_ACTIVECAPTION:
 	DeleteObject32( sysColorObjects.hbrushActiveCaption );
@@ -115,16 +117,26 @@
 	sysColorObjects.hbrushWindow = CreateSolidBrush32( color );
 	break;
     case COLOR_WINDOWFRAME:
-	DeleteObject32( sysColorObjects.hpenWindowFrame );
+	DeleteObject32( sysColorObjects.hbrushWindowFrame );
+	sysColorObjects.hbrushWindowFrame = CreateSolidBrush32( color );
+	/* FIXME: we should not need this pen */
+	DeleteObject32( sysColorObjects.hpenWindowFrame ); 
 	sysColorObjects.hpenWindowFrame = CreatePen32( PS_SOLID, 1, color );
 	break;
     case COLOR_MENUTEXT:
+	DeleteObject32( sysColorObjects.hbrushMenuText );
+	sysColorObjects.hbrushMenuText = CreateSolidBrush32( color );
 	break;
     case COLOR_WINDOWTEXT:
+	DeleteObject32( sysColorObjects.hbrushWindowText );
+	sysColorObjects.hbrushWindowText = CreateSolidBrush32( color );
+	/* FIXME: we should not need this pen */
 	DeleteObject32( sysColorObjects.hpenWindowText );
 	sysColorObjects.hpenWindowText = CreatePen32( PS_DOT, 1, color );
 	break;
     case COLOR_CAPTIONTEXT:
+	DeleteObject32( sysColorObjects.hbrushCaptionText );
+	sysColorObjects.hbrushCaptionText = CreateSolidBrush32( color );
 	break;
     case COLOR_ACTIVEBORDER:
 	DeleteObject32( sysColorObjects.hbrushActiveBorder );
@@ -135,12 +147,16 @@
 	sysColorObjects.hbrushInactiveBorder = CreateSolidBrush32( color );
 	break;
     case COLOR_APPWORKSPACE:
+	DeleteObject32( sysColorObjects.hbrushAppWorkspace );
+	sysColorObjects.hbrushAppWorkspace = CreateSolidBrush32( color );
 	break;
     case COLOR_HIGHLIGHT:
 	DeleteObject32( sysColorObjects.hbrushHighlight );
-	sysColorObjects.hbrushHighlight = CreateSolidBrush32(MAKE_SOLID(color));
+	sysColorObjects.hbrushHighlight = CreateSolidBrush32( color );
 	break;
     case COLOR_HIGHLIGHTTEXT:
+	DeleteObject32( sysColorObjects.hbrushHighlightText );
+	sysColorObjects.hbrushHighlightText = CreateSolidBrush32( color );
 	break;
     case COLOR_BTNFACE:
 	DeleteObject32( sysColorObjects.hbrushBtnFace );
@@ -151,17 +167,35 @@
 	sysColorObjects.hbrushBtnShadow = CreateSolidBrush32( color );
 	break;
     case COLOR_GRAYTEXT:
+	DeleteObject32( sysColorObjects.hbrushGrayText );
+	sysColorObjects.hbrushGrayText = CreateSolidBrush32( color );
     case COLOR_BTNTEXT:
+	DeleteObject32( sysColorObjects.hbrushBtnText );
+	sysColorObjects.hbrushBtnText = CreateSolidBrush32( color );
+	break;
     case COLOR_INACTIVECAPTIONTEXT:
+	DeleteObject32( sysColorObjects.hbrushInactiveCaptionText );
+	sysColorObjects.hbrushInactiveCaptionText = CreateSolidBrush32(color);
 	break;
     case COLOR_BTNHIGHLIGHT:
 	DeleteObject32( sysColorObjects.hbrushBtnHighlight );
 	sysColorObjects.hbrushBtnHighlight = CreateSolidBrush32( color );
 	break;
     case COLOR_3DDKSHADOW:
+	DeleteObject32( sysColorObjects.hbrush3DDkShadow );
+	sysColorObjects.hbrush3DDkShadow = CreateSolidBrush32( color );
+	break;
     case COLOR_3DLIGHT:
+	DeleteObject32( sysColorObjects.hbrush3DLight );
+	sysColorObjects.hbrush3DLight = CreateSolidBrush32( color );
+	break;
     case COLOR_INFOTEXT:
+	DeleteObject32( sysColorObjects.hbrushInfoText );
+	sysColorObjects.hbrushInfoText = CreateSolidBrush32( color );
+	break;
     case COLOR_INFOBK:
+	DeleteObject32( sysColorObjects.hbrushInfoBk );
+	sysColorObjects.hbrushInfoBk = CreateSolidBrush32( color );
 	break;
     }
 }
diff --git a/windows/winpos.c b/windows/winpos.c
index b7cadcb..9454080 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -624,6 +624,62 @@
 }
 
 
+/*******************************************************************
+ *         GetForegroundWindow16    (USER.608)
+ */
+HWND16 WINAPI GetForegroundWindow16(void)
+{
+    return (HWND16)GetForegroundWindow32();
+}
+
+
+/*******************************************************************
+ *         SetForegroundWindow16    (USER.609)
+ */
+BOOL16 WINAPI SetForegroundWindow16( HWND16 hwnd )
+{
+    return SetForegroundWindow32( hwnd );
+}
+
+
+/*******************************************************************
+ *         GetForegroundWindow32    (USER32.241)
+ */
+HWND32 WINAPI GetForegroundWindow32(void)
+{
+    return GetActiveWindow32();
+}
+
+
+/*******************************************************************
+ *         SetForegroundWindow32    (USER32.482)
+ */
+BOOL32 WINAPI SetForegroundWindow32( HWND32 hwnd )
+{
+    SetActiveWindow32( hwnd );
+    return TRUE;
+}
+
+
+/*******************************************************************
+ *         GetShellWindow16    (USER.600)
+ */
+HWND16 WINAPI GetShellWindow16(void)
+{
+    return GetShellWindow32();
+}
+
+
+/*******************************************************************
+ *         GetShellWindow32    (USER32.287)
+ */
+HWND32 WINAPI GetShellWindow32(void)
+{
+    fprintf( stdnimp, "GetShellWindow: empty stub\n" );
+    return 0;
+}
+
+
 /***********************************************************************
  *           BringWindowToTop16   (USER.45)
  */
@@ -2423,10 +2479,10 @@
                 pDWP->winPos[i].cx = cx;
                 pDWP->winPos[i].cy = cy;
             }
-            pDWP->winPos[i].flags &= flags & (SWP_NOSIZE | SWP_NOMOVE |
-                                              SWP_NOZORDER | SWP_NOREDRAW |
-                                              SWP_NOACTIVATE | SWP_NOCOPYBITS |
-                                              SWP_NOOWNERZORDER);
+            pDWP->winPos[i].flags &= flags | ~(SWP_NOSIZE | SWP_NOMOVE |
+                                               SWP_NOZORDER | SWP_NOREDRAW |
+                                               SWP_NOACTIVATE | SWP_NOCOPYBITS|
+                                               SWP_NOOWNERZORDER);
             pDWP->winPos[i].flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW |
                                               SWP_FRAMECHANGED);
             return hdwp;