Release 970928

Sat Sep 27 12:36:56 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [if1632/relay.c]
	Made Catch and Throw also save %si and %di (untested).

	* [memory/selector.c]
	Added check for %fs and %gs in SELECTOR_FreeBlock.

	* [rc/winerc.c]
	Generated files no longer depend on Wine includes.
	Made .h generation optional.

	* [tools/build.c] [loader/task.c]
	Added CALL32_Init function.
	Added possibility to pass arguments when using CALLTO16_regs_.
	32-bit stack pointer is now saved on the 16-bit stack, instead of
	using IF1632_Saved32_esp.
	Removed CallTo32 callbacks.

	* [tools/makedep.c] [*/Makefile.in]
	Added support for directly generating dependencies for .y, .l and
	.rc files. Modified the makefiles to use this feature.

	* [windows/winproc.c] [if1632/thunk.c]
	Use CALLTO16_regs to call window procedures.

Thu Sep 25 12:18:57 1997  Kristian Nielsen <kristian.nielsen@risoe.dk>

	* [if1632/kernel.spec]
	Changed entry for SwitchStackBack to remove arguments from stack
	upon return (arguments left over from previous SwitchStackTo()).
	Borland C++ 4.0 now compiles "Hello World" (but crashes after
	outputting the .exe).

Wed Sep 24 13:54:44 1997  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [files/directory.c]
	SearchPath might get NULL buffer (empty LRU list in wordpad).

	* [memory/selector.c]
	Added SUnMapLS*.

	* [loader/pe_image.c]
	Be able to run executeables from non mmap()ble filesystems.
	PE_LoadLibrary adds librarys loaded by another process to
	its own modref list too.

	* [windows/keyboard.c][include/accel.h][loader/resource.c]
	Fixed accelerator leakage, use SDK defines/names.

	* [graphics/env.c][misc/main.c]
	Set/GetEnvironemnt have nothing to do with environment vars,
	but with Printer Environment.

	* [graphics/escape.c]
	Escape32: map args back to segmented pointers.

	* [windows/win.c]
	WS_POPUP|WS_CHILD windows don't need a parent window (SDK).

Tue Sep 16 14:40:16 1997  Robert Wilhelm  <robert@physiol.med.tu-muenchen.de>

	* [if1632/crtdll.spec] [misc/crtdll.c]
	Added signal().
diff --git a/ANNOUNCE b/ANNOUNCE
index e22d153..0e140d5 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,15 +1,12 @@
-This is release 970914 of Wine, the MS Windows emulator.  This is still a
+This is release 970928 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-970914: (see ChangeLog for details)
-	- Better resource handling.
-	- New Progress control.
-	- Improved PE module support.
-	- Many relay code changes.
+WHAT'S NEW with Wine-970928: (see ChangeLog for details)
+	- More relay code changes.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -18,10 +15,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-970914.tar.gz
-  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-970914.tar.gz
-  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-970914.tar.gz
-  ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-970914.tar.gz
+  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
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/BUGS b/BUGS
index 13a5ffd..0b3f2c6 100644
--- a/BUGS
+++ b/BUGS
@@ -9,9 +9,6 @@
 
 General:
 
- * LoadAccelerators() must not create any objects apart
-   from loading the resource.
-
  * Catch/Throw() do not save SI and DI registers (quite fatal).
 
  * We need to do InsertMenuItem32[AW] and then code most of the other
diff --git a/ChangeLog b/ChangeLog
index b9e775e..5c7855e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,70 @@
 ----------------------------------------------------------------------
+Sat Sep 27 12:36:56 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>
+
+	* [if1632/relay.c]
+	Made Catch and Throw also save %si and %di (untested).
+
+	* [memory/selector.c]
+	Added check for %fs and %gs in SELECTOR_FreeBlock.
+
+	* [rc/winerc.c]
+	Generated files no longer depend on Wine includes.
+	Made .h generation optional.
+
+	* [tools/build.c] [loader/task.c]
+	Added CALL32_Init function.
+	Added possibility to pass arguments when using CALLTO16_regs_.
+	32-bit stack pointer is now saved on the 16-bit stack, instead of
+	using IF1632_Saved32_esp.
+	Removed CallTo32 callbacks.
+
+	* [tools/makedep.c] [*/Makefile.in]
+	Added support for directly generating dependencies for .y, .l and
+	.rc files. Modified the makefiles to use this feature.
+
+	* [windows/winproc.c] [if1632/thunk.c]
+	Use CALLTO16_regs to call window procedures.
+
+Thu Sep 25 12:18:57 1997  Kristian Nielsen <kristian.nielsen@risoe.dk>
+
+	* [if1632/kernel.spec]
+	Changed entry for SwitchStackBack to remove arguments from stack
+	upon return (arguments left over from previous SwitchStackTo()).
+	Borland C++ 4.0 now compiles "Hello World" (but crashes after
+	outputting the .exe).
+
+Wed Sep 24 13:54:44 1997  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
+
+	* [files/directory.c]
+	SearchPath might get NULL buffer (empty LRU list in wordpad).
+
+	* [memory/selector.c]
+	Added SUnMapLS*.
+
+	* [loader/pe_image.c]
+	Be able to run executeables from non mmap()ble filesystems.
+	PE_LoadLibrary adds librarys loaded by another process to
+	its own modref list too.
+
+	* [windows/keyboard.c][include/accel.h][loader/resource.c]
+	Fixed accelerator leakage, use SDK defines/names.
+
+	* [graphics/env.c][misc/main.c]
+	Set/GetEnvironemnt have nothing to do with environment vars,
+	but with Printer Environment.
+
+	* [graphics/escape.c]
+	Escape32: map args back to segmented pointers.
+
+	* [windows/win.c]
+	WS_POPUP|WS_CHILD windows don't need a parent window (SDK).
+
+Tue Sep 16 14:40:16 1997  Robert Wilhelm  <robert@physiol.med.tu-muenchen.de>
+
+	* [if1632/crtdll.spec] [misc/crtdll.c]
+	Added signal().
+
+----------------------------------------------------------------------
 Thu Sep 11 18:24:56 1997  Philippe De Muyter  <phdm@info.ucl.ac.be>
 
 	* [objects/dc.c]
diff --git a/Make.rules.in b/Make.rules.in
index f637307..d31d7df 100644
--- a/Make.rules.in
+++ b/Make.rules.in
@@ -6,9 +6,10 @@
 # SRCDIR       : source directory for this module
 # MODULE       : name of the module being built
 # C_SRCS       : C sources for the module (optional)
-# GEN_C_SRCS   : generated C sources (optional)
 # ASM_SRCS     : assembly sources (optional)
 # GEN_ASM_SRCS : generated assembly sources (optional)
+# RC_SRCS      : resource source files (optional)
+# EXTRA_SRCS   : extra source files for make depend (optional)
 # EXTRA_OBJS   : extra object files (optional)
 
 # First some useful definitions
@@ -56,8 +57,8 @@
 manext          = .1
 includedir      = @includedir@/wine
 
-OBJS = $(GEN_C_SRCS:.c=.o) $(C_SRCS:.c=.o) \
-       $(GEN_ASM_SRCS:.s=.o) $(ASM_SRCS:.S=.o) $(EXTRA_OBJS)
+OBJS = $(C_SRCS:.c=.o) $(GEN_ASM_SRCS:.s=.o) $(ASM_SRCS:.S=.o) \
+       $(RC_SRCS:.rc=.o) $(EXTRA_OBJS)
 
 # Implicit rules
 
@@ -110,11 +111,11 @@
 
 # Misc. rules
 
-depend:: $(MAKEDEP) $(C_SRCS) $(GEN_C_SRCS)
-	$(MAKEDEP) $(DIVINCL) -C. $(GEN_C_SRCS) -C$(SRCDIR) $(C_SRCS)
+depend:: $(MAKEDEP) $(C_SRCS) $(RC_SRCS) $(EXTRA_SRCS)
+	$(MAKEDEP) $(DIVINCL) -C$(SRCDIR) $(C_SRCS) $(RC_SRCS) $(EXTRA_SRCS)
 
 clean::
-	$(RM) *.o \#*\# *~ *.bak *.orig *.rej *.flc winerctmp.c core $(GEN_C_SRCS) $(GEN_C_SRCS:.c=.h) $(GEN_ASM_SRCS) $(PROGRAMS)
+	$(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)
 
 dummy:
 
diff --git a/controls/combo.c b/controls/combo.c
index 3c3590f..26903fa 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -902,6 +902,7 @@
 	   case LBN_KILLFOCUS:
 		/* nothing to do here since ComboLBox always resets the focus to its
 		 * combo/edit counterpart */
+		 break;
        }
    }
    return 0;
diff --git a/controls/desktop.c b/controls/desktop.c
index b1651f2..fd2963c 100644
--- a/controls/desktop.c
+++ b/controls/desktop.c
@@ -32,17 +32,18 @@
     if ((file = _lopen32( filename, OF_READ )) == HFILE_ERROR32)
     {
         UINT32 len = GetWindowsDirectory32A( NULL, 0 );
-        if (!(buffer = HeapAlloc( SystemHeap, 0, len + strlen(filename) + 2 )))
+        if (!(buffer = HeapAlloc( GetProcessHeap(), 0,
+                                  len + strlen(filename) + 2 )))
             return 0;
         GetWindowsDirectory32A( buffer, len + 1 );
         strcat( buffer, "\\" );
         strcat( buffer, filename );
         file = _lopen32( buffer, OF_READ );
-        HeapFree( SystemHeap, 0, buffer );
+        HeapFree( GetProcessHeap(), 0, buffer );
     }
     if (file == HFILE_ERROR32) return 0;
     size = _llseek32( file, 0, 2 );
-    if (!(buffer = HeapAlloc( SystemHeap, 0, size )))
+    if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size )))
     {
 	_lclose32( file );
 	return 0;
@@ -56,13 +57,13 @@
       /* Check header content */
     if ((fileHeader->bfType != 0x4d42) || (size < fileHeader->bfSize))
     {
-	HeapFree( SystemHeap, 0, buffer );
+	HeapFree( GetProcessHeap(), 0, buffer );
 	return 0;
     }
     hbitmap = CreateDIBitmap32( hdc, &bitmapInfo->bmiHeader, CBM_INIT,
                                 buffer + fileHeader->bfOffBits,
                                 bitmapInfo, DIB_RGB_COLORS );
-    HeapFree( SystemHeap, 0, buffer );
+    HeapFree( GetProcessHeap(), 0, buffer );
     return hbitmap;
 }
 
diff --git a/controls/listbox.c b/controls/listbox.c
index 1308e81..165f483 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -484,14 +484,17 @@
                          "rect=%d,%d-%d,%d\n",
                          wnd->hwndSelf, index, item ? item->str : "", action,
                          rect->left, rect->top, rect->right, rect->bottom );
-        /* FIXME: check LBS_USETABSTOPS style */
-        if (item)
-            ExtTextOut32A( hdc, rect->left + 1, rect->top + 1,
-                           ETO_OPAQUE | ETO_CLIPPED, rect, item->str,
-                           strlen(item->str), NULL );
-        else
+        if (!item)
             ExtTextOut32A( hdc, rect->left + 1, rect->top + 1,
                            ETO_OPAQUE | ETO_CLIPPED, rect, NULL, 0, NULL );
+        else if (!(descr->style & LBS_USETABSTOPS)) 
+	    ExtTextOut32A( hdc, rect->left + 1, rect->top + 1,
+			   ETO_OPAQUE | ETO_CLIPPED, rect, item->str,
+			   strlen(item->str), NULL );
+        else
+	    TabbedTextOut32A( hdc, rect->left + 1 , rect->top + 1,
+			      item->str, strlen(item->str), 
+			      descr->nb_tabs, descr->tabs, 0);
         if (item && item->selected)
         {
             SetBkColor32( hdc, oldBk );
@@ -595,7 +598,12 @@
     {
         INT32 i;
         LPINT16 p = (LPINT16)tabs;
-        for (i = 0; i < descr->nb_tabs; i++) descr->tabs[i] = *p++;
+        dprintf_listbox( stddeb, "Listbox %04x: settabstops ", wnd->hwndSelf);
+        for (i = 0; i < descr->nb_tabs; i++) {
+            descr->tabs[i] = *p++<<1; /* FIXME */
+            dprintf_listbox( stddeb, "%hd ", descr->tabs[i]);
+	}
+	dprintf_listbox( stddeb, "\n");
     }
     else memcpy( descr->tabs, tabs, descr->nb_tabs * sizeof(INT32) );
     /* FIXME: repaint the window? */
diff --git a/controls/menu.c b/controls/menu.c
index 9e08d31..682423f 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -3533,9 +3533,9 @@
     if (!name) return 0;
     
     /* check for Win32 module */
-    instance = MODULE_HANDLEtoHMODULE16( instance );
-    if (MODULE_GetPtr(instance)->flags & NE_FFLAGS_WIN32)
+    if (HIWORD(instance))
         return LoadMenu32A(instance,PTR_SEG_TO_LIN(name));
+    instance = GetExePtr( instance );
 
     if (!(hRsrc = FindResource16( instance, name, RT_MENU ))) return 0;
     if (!(handle = LoadResource16( instance, hRsrc ))) return 0;
diff --git a/debugger/Makefile.in b/debugger/Makefile.in
index 2ab72d1..9b01414 100644
--- a/debugger/Makefile.in
+++ b/debugger/Makefile.in
@@ -21,12 +21,13 @@
 	stack.c \
 	types.c
 
-GEN_C_SRCS = \
-	y.tab.c \
-	lex.yy.c
+EXTRA_SRCS = dbg.y debug.l
+EXTRA_OBJS = y.tab.o lex.yy.o
 
 all: $(MODULE).o
 
+depend:: y.tab.h
+
 #
 # This is a special test program that helps debug the internal debugger.
 #
@@ -41,4 +42,7 @@
 lex.yy.c: debug.l
 	$(LEX) -8 -I $(SRCDIR)/debug.l
 
+clean::
+	$(RM) y.tab.c y.tab.h lex.yy.c
+
 ### Dependencies:
diff --git a/debugger/stabs.c b/debugger/stabs.c
index 0fe8e41..98bcc38 100644
--- a/debugger/stabs.c
+++ b/debugger/stabs.c
@@ -1098,11 +1098,15 @@
 	strcat(fn,"/");
 	strcat(fn,filename);
 	if ((rtn = DEBUG_ProcessElfObject(fn,load_offset))) {
+		free(fn);
       		free(paths);
 		goto leave;
 	}
-	s = t+1;
+	free(fn);
+	if (t) s = t+1;
       }
+      if (!s || !*s)
+      	fprintf(stderr," %s not found",filename);
       free(paths);
       goto leave;
     }
diff --git a/files/directory.c b/files/directory.c
index ba6a2aa..0f45fa9 100644
--- a/files/directory.c
+++ b/files/directory.c
@@ -596,9 +596,12 @@
     res = full_name.long_name +
               strlen(DRIVE_GetRoot( full_name.short_name[0] - 'A' ));
     while (*res == '/') res++;
-    if (buflen > 3) lstrcpyn32A( buffer + 3, res, buflen - 3 );
-    for (p = buffer; *p; p++) if (*p == '/') *p = '\\';
-    if (lastpart) *lastpart = strrchr( buffer, '\\' ) + 1;
+    if (buflen)
+    {
+        if (buflen > 3) lstrcpyn32A( buffer + 3, res, buflen - 3 );
+        for (p = buffer; *p; p++) if (*p == '/') *p = '\\';
+        if (lastpart) *lastpart = strrchr( buffer, '\\' ) + 1;
+    }
     return *res ? strlen(res) + 2 : 3;
 }
 
@@ -626,12 +629,15 @@
     res = full_name.long_name +
               strlen(DRIVE_GetRoot( full_name.short_name[0] - 'A' ));
     while (*res == '/') res++;
-    if (buflen > 3) lstrcpynAtoW( buffer + 3, res + 1, buflen - 3 );
-    for (p = buffer; *p; p++) if (*p == '/') *p = '\\';
-    if (lastpart)
+    if (buflen)
     {
-        for (p = *lastpart = buffer; *p; p++)
-            if (*p == '\\') *lastpart = p + 1;
+        if (buflen > 3) lstrcpynAtoW( buffer + 3, res + 1, buflen - 3 );
+        for (p = buffer; *p; p++) if (*p == '/') *p = '\\';
+        if (lastpart)
+        {
+            for (p = *lastpart = buffer; *p; p++)
+                if (*p == '\\') *lastpart = p + 1;
+        }
     }
     return *res ? strlen(res) + 2 : 3;
 }
diff --git a/graphics/Makefile.in b/graphics/Makefile.in
index 98f9338..9cab411 100644
--- a/graphics/Makefile.in
+++ b/graphics/Makefile.in
@@ -8,6 +8,7 @@
 C_SRCS = \
 	bitblt.c \
 	driver.c \
+	env.c \
 	escape.c \
 	fontengine.c \
 	mapping.c \
diff --git a/graphics/env.c b/graphics/env.c
new file mode 100644
index 0000000..9e284d7
--- /dev/null
+++ b/graphics/env.c
@@ -0,0 +1,84 @@
+/* 
+ * Driver Environment functions
+ *
+ * Note: This has NOTHING to do with the task/process environment!
+ *
+ * Copyright 1997 Marcus Meissner
+ */
+#include <stdio.h>
+#include "windows.h"
+#include "gdi.h"
+#include "debug.h"
+#include "stddebug.h"
+
+/***********************************************************************
+ *           GetEnvironment   (GDI.134)
+ */
+INT16 WINAPI GetEnvironment(LPCSTR lpPortName, LPDEVMODE16 lpdev, UINT16 nMaxSiz)
+{
+    fprintf(stddeb, "GetEnvironment('%s','%p',%d),\n",
+		lpPortName, lpdev, nMaxSiz);
+    return 0;
+}
+
+/***********************************************************************
+ *          SetEnvironment   (GDI.132)
+ */
+INT16 WINAPI SetEnvironment(LPCSTR lpPortName, LPDEVMODE16 lpdev, UINT16 nCount)
+{
+    fprintf(stddeb, "SetEnvironment('%s', '%p', %d) !\n", 
+		lpPortName, lpdev, nCount);
+    fprintf(stderr,
+    	"\tdevmode:\n"
+    	"\tname = %s\n"
+	"\tdmSpecVersion = %d\n"
+	"\tdmDriverVersion = %d\n"
+	"\tdmSize = %d\n"
+	"\tdmDriverExtra = %d\n"
+	"\tdmFields = %ld\n"
+	"\tdmOrientation = %d\n"
+	"\tdmPaperSize = %d\n"
+	"\tdmPaperLength = %d\n"
+	"\tdmPaperWidth = %d\n"
+	"\tdmScale = %d\n"
+	"\tdmCopies = %d\n"
+	"\tdmDefaultSource = %d\n"
+	"\tdmPrintQuality = %d\n"
+	"\tdmColor = %d\n"
+	"\tdmDuplex = %d\n"
+	"\tdmYResolution = %d\n"
+	"\tdmTTOption = %d\n"
+	"\tdmCollate = %d\n"
+	"\tdmFBitsPerPel = %d\n"
+	"\tdmPelsWidth = %ld\n"
+	"\tdmPelsHeight = %ld\n"
+	"\tdmDisplayFlags = %ld\n"
+	"\tdmDisplayFrequency = %ld\n",
+	
+    	lpdev->dmDeviceName,
+    	lpdev->dmSpecVersion,
+    	lpdev->dmDriverVersion,
+    	lpdev->dmSize,
+    	lpdev->dmDriverExtra,
+    	lpdev->dmFields,
+    	lpdev->dmOrientation,
+    	lpdev->dmPaperSize,
+    	lpdev->dmPaperLength,
+    	lpdev->dmPaperWidth,
+    	lpdev->dmScale,
+    	lpdev->dmCopies,
+    	lpdev->dmDefaultSource,
+    	lpdev->dmPrintQuality,
+    	lpdev->dmColor,
+    	lpdev->dmDuplex,
+    	lpdev->dmYResolution,
+    	lpdev->dmTTOption,
+    	lpdev->dmCollate,
+    	lpdev->dmBitsPerPel,
+    	lpdev->dmPelsWidth,
+    	lpdev->dmPelsHeight,
+    	lpdev->dmDisplayFlags,
+    	lpdev->dmDisplayFrequency
+   );
+    return 0;
+}
diff --git a/graphics/escape.c b/graphics/escape.c
index b60b9a8..124f7e7 100644
--- a/graphics/escape.c
+++ b/graphics/escape.c
@@ -7,6 +7,8 @@
 #include <stdio.h>
 #include "windows.h"
 #include "gdi.h"
+#include "heap.h"
+#include "ldt.h"
 #include "dc.h"
 
 INT16 WINAPI Escape16( HDC16 hdc, INT16 nEscape, INT16 cbInput,
@@ -20,13 +22,56 @@
 INT32 WINAPI Escape32( HDC32 hdc, INT32 nEscape, INT32 cbInput,
                        LPVOID lpszInData, LPVOID lpvOutData )
 {
-    DC * dc = DC_GetDCPtr( hdc );
+    DC		*dc = DC_GetDCPtr( hdc );
+    SEGPTR	segin,segout;
+    INT32	ret;
+
     if (!dc || !dc->funcs->pEscape) return 0;
+    segin	= (SEGPTR)lpszInData;
+    segout	= (SEGPTR)lpvOutData;
     switch (nEscape) {
-    case GETSCALINGFACTOR:
-         return 1;
-    	
+    	/* Escape(hdc,QUERYESCSUPPORT,LPINT32,NULL) */
+    case QUERYESCSUPPORT: {
+    	LPINT16 x = (LPINT16)SEGPTR_NEW(INT16);
+	*x = *(INT32*)lpszInData;
+	segin = SEGPTR_GET(x);
+	break;
     }
-    return dc->funcs->pEscape( dc, nEscape, cbInput,
-                               (SEGPTR)lpszInData, (SEGPTR)lpvOutData );
+
+    	/* Escape(hdc,GETSCALINGFACTOR,NULL,LPPOINT32) */
+    	/* Escape(hdc,GETPHYSPAGESIZE,NULL,LPPOINT32) */
+    	/* Escape(hdc,GETPRINTINGOFFSET,NULL,LPPOINT32) */
+
+    case GETSCALINGFACTOR:
+    case GETPHYSPAGESIZE:
+    case GETPRINTINGOFFSET:
+	segout = SEGPTR_GET(SEGPTR_NEW(POINT16));
+	break;
+    }
+    ret = dc->funcs->pEscape( dc, nEscape, cbInput, segin, segout );
+    switch(nEscape) {
+    case QUERYESCSUPPORT:
+    	if (ret)
+		fprintf(stderr,"target DC implements Escape %d\n",nEscape);
+    	SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
+	break;
+    case GETSCALINGFACTOR:
+    case GETPRINTINGOFFSET:
+    case GETPHYSPAGESIZE: {
+    	LPPOINT16 x = (LPPOINT16)PTR_SEG_TO_LIN(segout);
+	CONV_POINT16TO32(x,(LPPOINT32)lpvOutData);
+	SEGPTR_FREE(x);
+	break;
+    }
+    default:
+    	break;
+    }
+    return ret;
+}
+
+INT32 WINAPI ExtEscape32(HDC32 hdc,INT32 nEscape,INT32 cbInput,LPCSTR x,INT32 cbOutput,LPSTR out) {
+	fprintf(stderr,"ExtEscape32(0x%04x,0x%x,%d,%s,%d,%p),stub!\n",
+		hdc,nEscape,cbInput,x,cbOutput,out
+	);
+	return 1;
 }
diff --git a/graphics/fontengine.c b/graphics/fontengine.c
index 1676836..5a118ac 100644
--- a/graphics/fontengine.c
+++ b/graphics/fontengine.c
@@ -10,7 +10,7 @@
 /* GDI 300 */
 WORD WINAPI EngineEnumerateFont(LPSTR fontname, FARPROC16 proc, DWORD data )
 {
-    fprintf(stderr,"EngineEnumerateFont(%s,%p,%d),stub\n",fontname,proc,data);
+    fprintf(stderr,"EngineEnumerateFont(%s,%p,%lx),stub\n",fontname,proc,data);
     return 0;
 }
 #ifdef NOTDEF
diff --git a/graphics/x11drv/text.c b/graphics/x11drv/text.c
index 0b90d62..d7c28cf 100644
--- a/graphics/x11drv/text.c
+++ b/graphics/x11drv/text.c
@@ -279,6 +279,10 @@
 		   dc->w.DCOrgX + x + info.width, dc->w.DCOrgY + y - lineAscent );
     }
 
-    if (flags & ETO_CLIPPED) SelectClipRgn32( dc->hSelf, hRgnClip );
+    if (flags & ETO_CLIPPED) 
+    {
+      SelectClipRgn32( dc->hSelf, hRgnClip );
+      DeleteObject32( hRgnClip );
+    }
     return TRUE;
 }
diff --git a/if1632/Makefile.in b/if1632/Makefile.in
index 20df647..e9bb416 100644
--- a/if1632/Makefile.in
+++ b/if1632/Makefile.in
@@ -65,8 +65,7 @@
 	$(SPEC_FILES) \
 	callfrom16.s \
 	callfrom32.s \
-	callto16.s \
-	callto32.s \
+	callto16.s
 
 .SUFFIXES: .spec
 
@@ -88,7 +87,4 @@
 callto16.s: $(TOPSRCDIR)/include/callback.h $(BUILD)
 	$(BUILD) -o $@ -callto16 `cat $(TOPSRCDIR)/include/callback.h | grep "extern.*CallTo16_" | sed 's/.*CallTo16_\(.*\)(.*/\1/' | sort | uniq`
 
-callto32.s: $(TOPSRCDIR)/include/callback.h $(BUILD)
-	$(BUILD) -o $@ -callto32 `cat $(TOPSRCDIR)/include/callback.h | grep "extern.*CallTo32_" | sed 's/.*CallTo32_\(.*\)(.*/\1/' | sort | uniq`
-
 ### Dependencies:
diff --git a/if1632/crtdll.spec b/if1632/crtdll.spec
index 993bb1d..da626f5 100644
--- a/if1632/crtdll.spec
+++ b/if1632/crtdll.spec
@@ -456,7 +456,7 @@
 452 cdecl setbuf(ptr ptr) CRTDLL_setbuf
 453 cdecl setlocale(long ptr) CRTDLL_setlocale
 454 stub setvbuf
-455 stub signal
+455 cdecl signal(long ptr) CRTDLL_signal
 456 cdecl sin(double) sin
 457 cdecl sinh(double) sinh
 458 varargs sprintf() wsprintf32A
diff --git a/if1632/gdi32.spec b/if1632/gdi32.spec
index 2baeae2..1380cdb 100644
--- a/if1632/gdi32.spec
+++ b/if1632/gdi32.spec
@@ -99,7 +99,7 @@
  92 stdcall ExcludeClipRect(long long long long long) ExcludeClipRect32
  93 stub ExtCreatePen
  94 stub ExtCreateRegion
- 95 stub ExtEscape
+ 95 stdcall ExtEscape(long long long ptr long ptr) ExtEscape32
  96 stdcall ExtFloodFill(long long long long long) ExtFloodFill32
  97 stub ExtSelectClipRgn
  98 stdcall ExtTextOutA(long long long long ptr ptr long ptr) ExtTextOut32A
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index df6f2e7..646e52a 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -52,8 +52,8 @@
 52  pascal16 FreeProcInstance(segptr) FreeProcInstance16
 53  stub CallProcInstance
 54  pascal16 GetInstanceData(word word word) GetInstanceData
-55  pascal16 Catch(ptr) Catch 
-56  pascal16 Throw(ptr word) Throw
+55  register Catch(segptr) Catch 
+56  register Throw(segptr word) Throw
 57  pascal16 GetProfileInt(str str s_word) GetProfileInt16
 58  pascal16 GetProfileString(str str str ptr word) GetProfileString16
 59  pascal16 WriteProfileString(str str str) WriteProfileString16
@@ -106,7 +106,7 @@
 106 pascal SetSwapAreaSize(word) SetSwapAreaSize
 107 pascal16 SetErrorMode(word) SetErrorMode16
 108 pascal16 SwitchStackTo(word word word) SwitchStackTo
-109 register SwitchStackBack() SwitchStackBack
+109 register SwitchStackBack(word word word) SwitchStackBack
 110 pascal16 PatchCodeHandle(word) PatchCodeHandle
 111 pascal   GlobalWire(word) GlobalWire16
 112 pascal16 GlobalUnWire(word) GlobalUnWire16
@@ -276,8 +276,8 @@
 355 pascal16 GetWinDebugInfo(ptr word) GetWinDebugInfo
 356 pascal16 SetWinDebugInfo(ptr) SetWinDebugInfo
 357 stub KERNEL_357
-358 stub KERNEL_358
-359 stub KERNEL_359
+358 pascal KERNEL_358(long) _KERNEL_358
+359 pascal KERNEL_359(long) _KERNEL_359
 360 stub OpenFileEx
 #361 PIGLET_361
 403 pascal16 FarSetOwner(word word) FarSetOwner
@@ -310,7 +310,7 @@
 454 stub KERNEL_454
 455 stub KERNEL_455
 471 stub KERNEL_471
-472 stub KERNEL_472
+472 register KERNEL_472() _KERNEL_472
 473 stub KERNEL_473
 482 stub KERNEL_482
 485 stub KERNEL_485
@@ -339,6 +339,6 @@
 621 stub KERNEL_621
 627 stub IsBadFlatReadWritePtr
 630 stub KERNEL_630
-631 stub FUNC004	# shell hook
+631 pascal FUNC004(word word long) FUNC004	# shell hook
 651 stub KERNEL_651
 700 pascal KERNEL_700() stub_KERNEL_700
diff --git a/if1632/kernel32.spec b/if1632/kernel32.spec
index 3b6243a..84a265c 100644
--- a/if1632/kernel32.spec
+++ b/if1632/kernel32.spec
@@ -40,7 +40,7 @@
  
  50 stdcall AddAtomA(ptr) AddAtom32A
 
- 52 register _KERNEL32_52(long) _KERNEL32_52
+ 52 stdcall _KERNEL32_52() _KERNEL32_52
 
 # WOW calls
  54 stdcall WOWCallback16(long long) WOWCallback16
@@ -85,15 +85,15 @@
  93 stdcall GETPWIN16LOCK(ptr) GetPWinLock
  97 stub ENTERSYSLEVEL
  98 stub LEAVESYSLEVEL
- 99 stub _KERNEL32_98
-100 stub _KERNEL32_99
+ 99 stdcall _KERNEL32_98(long) _KERNEL32_98
+100 stdcall _KERNEL32_99(long long long) _KERNEL32_99
 101 stub _KERNEL32_100
 
 
 102 stdcall AddAtomW(ptr) AddAtom32W
 103 stub AllocConsole
 104 stub AllocLSCallback
-105 stub AllocSLCallback
+105 stdcall AllocSLCallback(ptr ptr) AllocSLCallback
 106 stdcall AreFileApisANSI() AreFileApisANSI
 107 stub BackupRead
 108 stub BackupSeek
@@ -262,7 +262,7 @@
 272 stub FreeLibraryAndExitThread
 271 stdcall FreeLibrary(long) FreeLibrary32
 273 stdcall FreeResource(long) FreeResource32
-274 stub FreeSLCallback
+274 stdcall FreeSLCallback(long) FreeSLCallback
 275 stub GenerateConsoleCtrlEvent
 276 stdcall GetACP() GetACP
 277 stdcall GetAtomNameA(long ptr long) GetAtomName32A
@@ -591,15 +591,15 @@
 600 register SMapLS_IP_EBP_40() SMapLS_IP_EBP_40
 601 register SMapLS_IP_EBP_8() SMapLS_IP_EBP_8
 602 stub SUnMapLS
-603 stub SUnMapLS_IP_EBP_12
-604 stub SUnMapLS_IP_EBP_16
-605 stub SUnMapLS_IP_EBP_20
-606 stub SUnMapLS_IP_EBP_24
-607 stub SUnMapLS_IP_EBP_28
-608 stub SUnMapLS_IP_EBP_32
-609 stub SUnMapLS_IP_EBP_36
-610 stub SUnMapLS_IP_EBP_40
-611 stub SUnMapLS_IP_EBP_8
+603 register SUnMapLS_IP_EBP_12() SUnMapLS_IP_EBP_12
+604 register SUnMapLS_IP_EBP_16() SUnMapLS_IP_EBP_16
+605 register SUnMapLS_IP_EBP_20() SUnMapLS_IP_EBP_20
+606 register SUnMapLS_IP_EBP_24() SUnMapLS_IP_EBP_24
+607 register SUnMapLS_IP_EBP_28() SUnMapLS_IP_EBP_28
+608 register SUnMapLS_IP_EBP_32() SUnMapLS_IP_EBP_32
+609 register SUnMapLS_IP_EBP_36() SUnMapLS_IP_EBP_36
+610 register SUnMapLS_IP_EBP_40() SUnMapLS_IP_EBP_40
+611 register SUnMapLS_IP_EBP_8() SUnMapLS_IP_EBP_8
 612 stub ScrollConsoleScreenBufferA
 613 stub ScrollConsoleScreenBufferW
 614 stdcall SearchPathA(ptr ptr ptr long ptr ptr) SearchPath32A
@@ -669,7 +669,7 @@
 678 stdcall SizeofResource(long long) SizeofResource32
 679 stdcall Sleep(long) Sleep
 680 stub SleepEx
-681 stub SuspendThread
+681 stdcall SuspendThread(long) SuspendThread
 682 stdcall SystemTimeToFileTime(ptr ptr) SystemTimeToFileTime
 683 stub SystemTimeToTzSpecificLocalTime
 684 stub TerminateProcess
@@ -709,7 +709,7 @@
 718 stdcall VirtualUnlock(ptr long) VirtualUnlock
 719 stub WaitCommEvent
 720 stub WaitForDebugEvent
-721 stub WaitForMultipleObjects
+721 stdcall WaitForMultipleObjects(long ptr long long) WaitForMultipleObjects
 722 stub WaitForMultipleObjectsEx
 723 stdcall WaitForSingleObject(long long) WaitForSingleObject
 724 stdcall WaitForSingleObjectEx(long long long) WaitForSingleObjectEx
diff --git a/if1632/mmsystem.spec b/if1632/mmsystem.spec
index 68b3a60..f23df57 100644
--- a/if1632/mmsystem.spec
+++ b/if1632/mmsystem.spec
@@ -22,7 +22,7 @@
 201    pascal  MIDIOUTGETNUMDEVS() midiOutGetNumDevs
 202    pascal  MIDIOUTGETDEVCAPS(word segptr word) midiOutGetDevCaps
 203    pascal  MIDIOUTGETERRORTEXT(word ptr word) midiOutGetErrorText
-204    pascal  MIDIOUTOPEN(ptr word ptr long long long) midiOutOpen
+204    pascal  MIDIOUTOPEN(ptr word ptr long long) midiOutOpen
 205    pascal  MIDIOUTCLOSE(word) midiOutClose
 206    pascal  MIDIOUTPREPAREHEADER(word segptr word) midiOutPrepareHeader
 207    pascal  MIDIOUTUNPREPAREHEADER(word segptr word) midiOutUnprepareHeader
@@ -120,7 +120,7 @@
 1218   pascal  MMIOFLUSH(word word) mmioFlush
 1219   pascal  MMIOADVANCE(word ptr word) mmioAdvance
 1220   pascal  MMIOSTRINGTOFOURCC(ptr word) mmioStringToFOURCC
-1221   pascal  MMIOINSTALLIOPROC(long ptr long) mmioInstallIOProc
+1221   pascal  MMIOINSTALLIOPROC(long ptr long) mmioInstallIOProc16
 1222   pascal  MMIOSENDMESSAGE(word word long long) mmioSendMessage
 1223   pascal  MMIODESCEND(word ptr ptr word) mmioDescend
 1224   pascal  MMIOASCEND(word ptr word) mmioAscend
diff --git a/if1632/relay.c b/if1632/relay.c
index 6ad7c32..09a83c2 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -11,7 +11,6 @@
 #include "module.h"
 #include "stackframe.h"
 #include "task.h"
-#include "callback.h"
 #include "xmalloc.h"
 #include "stddebug.h"
 /* #define DEBUG_RELAY */
@@ -35,7 +34,6 @@
 
     extern void CALLTO16_Start(), CALLTO16_End();
     extern void CALLTO16_Ret_word(), CALLTO16_Ret_long();
-    extern int CALLTO32_LargeStack();
     extern DWORD CALLTO16_RetAddr_word, CALLTO16_RetAddr_long;
 
     codesel = GLOBAL_CreateBlock( GMEM_FIXED, (void *)CALLTO16_Start,
@@ -50,10 +48,6 @@
     CALLTO16_RetAddr_long=MAKELONG( (int)CALLTO16_Ret_long-(int)CALLTO16_Start,
                                     codesel );
 
-    /* Set the CallLargeStack function pointer */
-
-    IF1632_CallLargeStack = CALLTO32_LargeStack;
-
     /* Initialize thunking */
 
     return THUNK_Init();
@@ -163,7 +157,7 @@
         break;
     case 2: /* regs */
         printf( "retval=none ret=%04x:%04x ds=%04x\n",
-                frame->cs, frame->ip, frame->ds );
+                (WORD)CS_reg(context), IP_reg(context), (WORD)DS_reg(context));
         printf( "     AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n",
                 AX_reg(context), BX_reg(context), CX_reg(context),
                 DX_reg(context), SI_reg(context), DI_reg(context),
@@ -197,8 +191,8 @@
  * as 'stub' in the spec file).
  * (The args are the same than for RELAY_DebugCallFrom32).
  */
-void RELAY_Unimplemented32( int nb_args, void *relay_addr,
-                            void *entry_point, int ebp, int ret_addr )
+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 );
@@ -222,9 +216,13 @@
 
     if (nb_args == -1)  /* Register function */
     {
-        CONTEXT *context = *(CONTEXT **)stack;
-        printf( "CallTo16(func=%04lx:%04x,ds=%04lx)\n",
+        CONTEXT *context = (CONTEXT *)stack[0];
+        WORD *stack16 = (WORD *)CURRENT_STACK16 - 2 /* for saved %%esp */;
+        printf( "CallTo16(func=%04lx:%04x,ds=%04lx",
                 CS_reg(context), IP_reg(context), DS_reg(context) );
+        nb_args = -stack[1] / sizeof(WORD);
+        while (nb_args--) printf( ",0x%04x", *(--stack16) );
+        printf( ")\n" );
         printf( "     AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x BP=%04x ES=%04x\n",
                 AX_reg(context), BX_reg(context), CX_reg(context),
                 DX_reg(context), SI_reg(context), DI_reg(context),
@@ -233,7 +231,8 @@
     else
     {
         printf( "CallTo16(func=%04x:%04x,ds=%04x",
-                HIWORD(stack[0]), LOWORD(stack[0]), CURRENT_DS );
+                HIWORD(stack[0]), LOWORD(stack[0]),
+                SELECTOROF(IF1632_Saved16_ss_sp) );
         stack++;
         while (nb_args--) printf( ",0x%04x", *stack++ );
         printf( ")\n" );
@@ -312,28 +311,16 @@
 }
 
 
-/***********************************************************************
- *           RELAY_DebugCallTo32
- */
-void RELAY_DebugCallTo32( unsigned int func, int nbargs, unsigned int arg1  )
-{
-    unsigned int *argptr;
-
-    if (!debugging_relay) return;
-
-    printf( "CallTo32(func=%08x", func );
-    for (argptr = &arg1; nbargs; nbargs--, argptr++)
-        printf( ",%08x", *argptr );
-    printf( ")\n" );
-}
-
-
 /**********************************************************************
  *	     Catch    (KERNEL.55)
+ *
+ * Real prototype is:
+ *   INT16 WINAPI Catch( LPCATCHBUF lpbuf );
  */
-INT16 WINAPI Catch( LPCATCHBUF lpbuf )
+void WINAPI Catch( CONTEXT *context )
 {
     STACK16FRAME *pFrame = CURRENT_STACK16;
+    LPCATCHBUF lpbuf = (LPCATCHBUF)PTR_SEG_TO_LIN(*(SEGPTR *)pFrame->args);
 
     /* Note: we don't save the current ss, as the catch buffer is */
     /* only 9 words long. Hopefully no one will have the silly    */
@@ -350,39 +337,44 @@
      * lpbuf[7] = unused
      * lpbuf[8] = ss
      */
-    /* FIXME: we need to save %si and %di */
 
-    lpbuf[0] = pFrame->ip;
-    lpbuf[1] = pFrame->cs;
+    lpbuf[0] = IP_reg(context);
+    lpbuf[1] = CS_reg(context);
     lpbuf[2] = LOWORD(pFrame->saved_ss_sp);
-    lpbuf[3] = pFrame->bp;
-    lpbuf[4] = LOWORD(IF1632_Saved32_esp);
-    lpbuf[5] = HIWORD(IF1632_Saved32_esp);
-    lpbuf[6] = pFrame->ds;
+    lpbuf[3] = BP_reg(context);
+    lpbuf[4] = SI_reg(context);
+    lpbuf[5] = DI_reg(context);
+    lpbuf[6] = DS_reg(context);
     lpbuf[7] = OFFSETOF(IF1632_Saved16_ss_sp);
     lpbuf[8] = HIWORD(pFrame->saved_ss_sp);
-    return 0;
+    AX_reg(context) = 0;  /* Return 0 */
 }
 
 
 /**********************************************************************
  *	     Throw    (KERNEL.56)
+ *
+ * Real prototype is:
+ *   INT16 WINAPI Throw( LPCATCHBUF lpbuf, INT16 retval );
  */
-INT16 WINAPI Throw( LPCATCHBUF lpbuf, INT16 retval )
+void WINAPI Throw( CONTEXT *context )
 {
-    STACK16FRAME *pFrame;
-    WORD es = CURRENT_STACK16->es;
+    STACK16FRAME *pFrame = CURRENT_STACK16;
+    LPCATCHBUF lpbuf = (LPCATCHBUF)PTR_SEG_TO_LIN(*(SEGPTR *)&pFrame->args[1]);
+    WORD retval = pFrame->args[0];
 
     IF1632_Saved16_ss_sp = MAKELONG( lpbuf[7] - sizeof(WORD),
                                      HIWORD(IF1632_Saved16_ss_sp) );
-    IF1632_Saved32_esp = MAKELONG( lpbuf[4], lpbuf[5] );
     pFrame = CURRENT_STACK16;
     pFrame->saved_ss_sp = MAKELONG( lpbuf[2], lpbuf[8] );
-    pFrame->ds          = lpbuf[6];
-    pFrame->bp          = lpbuf[3];
-    pFrame->ip          = lpbuf[0];
-    pFrame->cs          = lpbuf[1];
-    pFrame->es          = es;
+    IP_reg(context) = lpbuf[0];
+    CS_reg(context) = lpbuf[1];
+    BP_reg(context) = lpbuf[3];
+    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 */
     {
         static FARPROC16 entryPoint = NULL;
@@ -393,13 +385,12 @@
         pFrame->entry_cs = SELECTOROF(entryPoint);
         pFrame->entry_ip = OFFSETOF(entryPoint);
     }
-    return retval;
 }
 
 /**********************************************************************
- *	     CallProc32W    (KERNEL.56)
+ *	     CallProc32W    (KERNEL.517)
  */
-DWORD /*WINAPI*/ WIN16_CallProc32W()
+DWORD WINAPI WIN16_CallProc32W()
 {
 	DWORD *win_stack = (DWORD *)CURRENT_STACK16->args;
 	DWORD	nrofargs = win_stack[0];
@@ -422,21 +413,21 @@
 	}
 	fprintf(stderr,"]) - ");
 	switch (nrofargs) {
-	case 0: ret = CallTo32_0(proc32);
+	case 0: ret = proc32();
 		break;
-	case 1:	ret = CallTo32_1(proc32,args[0]);
+	case 1:	ret = proc32(args[0]);
 		break;
-	case 2:	ret = CallTo32_2(proc32,args[0],args[1]);
+	case 2:	ret = proc32(args[0],args[1]);
 		break;
-	case 3:	ret = CallTo32_3(proc32,args[0],args[1],args[2]);
+	case 3:	ret = proc32(args[0],args[1],args[2]);
 		break;
-	case 4:	ret = CallTo32_4(proc32,args[0],args[1],args[2],args[3]);
+	case 4:	ret = proc32(args[0],args[1],args[2],args[3]);
 		break;
-	case 5:	ret = CallTo32_5(proc32,args[0],args[1],args[2],args[3],args[4]);
+	case 5:	ret = proc32(args[0],args[1],args[2],args[3],args[4]);
 		break;
-	case 6:	ret = CallTo32_6(proc32,args[0],args[1],args[2],args[3],args[4],args[5]);
+	case 6:	ret = proc32(args[0],args[1],args[2],args[3],args[4],args[5]);
 		break;
-	case 7:	ret = CallTo32_7(proc32,args[0],args[1],args[2],args[3],args[4],args[5],args[6]);
+	case 7:	ret = proc32(args[0],args[1],args[2],args[3],args[4],args[5],args[6]);
 		break;
 	default:
 		/* FIXME: should go up to 32  arguments */
diff --git a/if1632/signal.c b/if1632/signal.c
index 06890db..d5810d1 100644
--- a/if1632/signal.c
+++ b/if1632/signal.c
@@ -35,17 +35,14 @@
 /* Signal handler declaration */
 
 #ifdef linux
-#define HANDLER_DEF(name) void name (int signal, SIGCONTEXT context_struct)
-#define HANDLER_PROLOG SIGCONTEXT *context = &context_struct; {
-#define HANDLER_EPILOG }
+# define HANDLER_DEF(name) void name (int signal, SIGCONTEXT context)
+# define HANDLER_CONTEXT (&context)
 #elif defined(__svr4__) || defined(_SCO_DS)
-#define HANDLER_DEF(name) void name (int signal, void *siginfo, SIGCONTEXT *context)
-#define HANDLER_PROLOG  /* nothing */
-#define HANDLER_EPILOG  /* nothing */
+# define HANDLER_DEF(name) void name(int signal, void *siginfo, SIGCONTEXT *context)
+# define HANDLER_CONTEXT context
 #else
-#define HANDLER_DEF(name) void name (int signal, int code, SIGCONTEXT *context)
-#define HANDLER_PROLOG  /* nothing */
-#define HANDLER_EPILOG  /* nothing */
+# define HANDLER_DEF(name) void name(int signal, int code, SIGCONTEXT *context)
+# define HANDLER_CONTEXT context
 #endif
 
 extern void SIGNAL_SetHandler( int sig, void (*func)(), int flags );
@@ -59,10 +56,9 @@
  */
 static HANDLER_DEF(SIGNAL_break)
 {
-    HANDLER_PROLOG;
-    if (Options.debug) wine_debug( signal, context );  /* Enter our debugger */
+    if (Options.debug)
+        wine_debug( signal, HANDLER_CONTEXT );  /* Enter our debugger */
     else exit(0);
-    HANDLER_EPILOG;
 }
 
 
@@ -73,9 +69,7 @@
  */
 static HANDLER_DEF(SIGNAL_trap)
 {
-  HANDLER_PROLOG;
-  wine_debug( signal, context );  /* Enter our debugger */
-  HANDLER_EPILOG;
+    wine_debug( signal, HANDLER_CONTEXT );  /* Enter our debugger */
 }
 
 
@@ -86,21 +80,18 @@
  */
 static HANDLER_DEF(SIGNAL_fault)
 {
-    HANDLER_PROLOG;
-    if (CS_sig(context) == WINE_CODE_SELECTOR)
+    if (CS_sig(HANDLER_CONTEXT) == WINE_CODE_SELECTOR)
     {
-        fprintf( stderr, "Segmentation fault in Wine program (%04x:%08lx)."
-                         "  Please debug.\n",
-                 (unsigned short) CS_sig(context), EIP_sig(context));
+        fprintf( stderr, "Segmentation fault in 32-bit code (0x%08lx).\n",
+                 EIP_sig(HANDLER_CONTEXT) );
     }
     else
     {
-        if (INSTR_EmulateInstruction( context )) return;
-        fprintf( stderr, "Segmentation fault in Windows program %04x:%08lx.\n",
-                 (unsigned short) CS_sig(context), EIP_sig(context) );
+        if (INSTR_EmulateInstruction( HANDLER_CONTEXT )) return;
+        fprintf( stderr, "Segmentation fault in 16-bit code (%04x:%04lx).\n",
+                 (WORD)CS_sig(HANDLER_CONTEXT), EIP_sig(HANDLER_CONTEXT) );
     }
-    wine_debug( signal, context );
-    HANDLER_EPILOG;
+    wine_debug( signal, HANDLER_CONTEXT );
 }
 
 
@@ -205,12 +196,10 @@
  */
 static HANDLER_DEF(SIGNAL_tick)
 {
-    HANDLER_PROLOG
     CONTEXT nt_context;
-    SIGNAL_SetSigContext( context, &nt_context );
+    SIGNAL_SetSigContext( HANDLER_CONTEXT, &nt_context );
     if (THREAD_SwitchThread( &nt_context ))
-        SIGNAL_GetSigContext( context, &nt_context );
-    HANDLER_EPILOG
+        SIGNAL_GetSigContext( HANDLER_CONTEXT, &nt_context );
 }
 
 /**********************************************************************
diff --git a/if1632/thunk.c b/if1632/thunk.c
index 901a9bb..2da1a3d 100644
--- a/if1632/thunk.c
+++ b/if1632/thunk.c
@@ -15,7 +15,10 @@
 #include "module.h"
 #include "winproc.h"
 #include "stackframe.h"
+#include "selectors.h"
+#include "task.h"
 #include "except.h"
+#include "win.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -117,20 +120,44 @@
 static LRESULT THUNK_CallWndProc16( WNDPROC16 proc, HWND16 hwnd, UINT16 msg,
                                     WPARAM16 wParam, LPARAM lParam )
 {
+    CONTEXT context;
+    LRESULT ret;
+    WORD *args;
+    WND *wndPtr = WIN_FindWndPtr( hwnd );
+    DWORD offset = 0;
+
+    /* Window procedures want ax = hInstance, ds = es = ss */
+
+    DS_reg(&context)  = SELECTOROF(IF1632_Saved16_ss_sp);
+    ES_reg(&context)  = DS_reg(&context);
+    EAX_reg(&context) = wndPtr ? wndPtr->hInstance : DS_reg(&context);
+    CS_reg(&context)  = SELECTOROF(proc);
+    EIP_reg(&context) = OFFSETOF(proc);
+    EBP_reg(&context) = OFFSETOF(IF1632_Saved16_ss_sp)
+                        + (WORD)&((STACK16FRAME*)0)->bp;
+
     if (((msg == WM_CREATE) || (msg == WM_NCCREATE)) && lParam)
     {
-        CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
         /* Build the CREATESTRUCT on the 16-bit stack. */
         /* This is really ugly, but some programs (notably the */
         /* "Undocumented Windows" examples) want it that way.  */
-        return CallTo16_wndp_lllllllwlwwwl( (FARPROC16)proc,
-                         cs->dwExStyle, cs->lpszClass, cs->lpszName, cs->style,
-                         MAKELONG( cs->y, cs->x ), MAKELONG( cs->cy, cs->cx ),
-                         MAKELONG( cs->hMenu, cs->hwndParent ), cs->hInstance,
-                         (LONG)cs->lpCreateParams, hwnd, msg, wParam,
-                         IF1632_Saved16_ss_sp - sizeof(CREATESTRUCT16) );
+        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;
     }
-    return CallTo16_wndp_wwwl( (FARPROC16)proc, hwnd, msg, wParam, lParam );
+    args = (WORD *)CURRENT_STACK16 - 7;
+    args[0] = LOWORD(lParam);
+    args[1] = HIWORD(lParam);
+    args[2] = wParam;
+    args[3] = msg;
+    args[4] = hwnd;
+    /* args[5] and args[6] are used by relay code to store the stack pointer */
+
+    ret = CallTo16_regs_( &context, -(5 * sizeof(WORD)) );
+    IF1632_Saved16_ss_sp += offset;
+    return ret;
 }
 
 
@@ -608,7 +635,6 @@
  *		sp:	
  *		
  */
-extern DWORD IF1632_Saved16_ss_sp;
 VOID WINAPI QT_Thunk(CONTEXT *context)
 {
 	CONTEXT	context16;
@@ -621,19 +647,16 @@
 	);
 	memcpy(&context16,context,sizeof(context16));
 
-	curstack = PTR_SEG_TO_LIN(IF1632_Saved16_ss_sp);
-	memcpy(curstack-0x40,(LPBYTE)EBP_reg(context),0x40);
+	curstack = (LPBYTE)CURRENT_STACK16;
+	memcpy(curstack-0x44,(LPBYTE)EBP_reg(context),0x40);
 	EBP_reg(&context16)	 = LOWORD(IF1632_Saved16_ss_sp)-0x40;
-	IF1632_Saved16_ss_sp	-= 0x3c;
-
 	CS_reg(&context16)	 = HIWORD(EDX_reg(context));
 	IP_reg(&context16)	 = LOWORD(EDX_reg(context));
 #ifndef WINELIB
-	ret = CallTo16_regs_(&context16);
+	ret = CallTo16_regs_(&context16,-0x40);
 #endif
 	fprintf(stderr,". returned %08lx\n",ret);
 	EAX_reg(context) 	 = ret;
-	IF1632_Saved16_ss_sp	+= 0x3c;
 }
 
 
@@ -651,17 +674,23 @@
 
 /***********************************************************************
  *           _KERNEL32_52    (KERNEL32.52)
- * FIXME: what does it really do?
+ * Returns a pointer to ThkBuf in the 16bit library SYSTHUNK.DLL.
  */
-VOID WINAPI _KERNEL32_52(DWORD arg1,CONTEXT *regs)
+LPVOID WINAPI _KERNEL32_52()
 {
-	fprintf(stderr,"_KERNE32_52(arg1=%08lx,%08lx)\n",arg1,EDI_reg(regs));
+	HMODULE32	hmod = LoadLibrary16("systhunk.dll");
+	DWORD		ret;
 
-	EAX_reg(regs) = (DWORD)WIN32_GetProcAddress16(EDI_reg(regs),"ThkBuf");
+	fprintf(stderr,"_KERNE32_52()\n");
+	if (hmod<=32)
+		return 0;
 
-	fprintf(stderr,"	GetProcAddress16(\"ThkBuf\") returns %08lx\n",
-			EAX_reg(regs)
+	ret = (DWORD)WIN32_GetProcAddress16(hmod,"ThkBuf");
+
+	fprintf(stderr,"	GetProcAddress16(0x%04x,\"ThkBuf\") returns %08lx\n",
+			hmod,ret
 	);
+	return PTR_SEG_TO_LIN(ret);
 }
 
 /***********************************************************************
@@ -674,7 +703,7 @@
  * The pointer ptr is written into the first DWORD of 'thunk'.
  * (probably correct implemented)
  */
-BOOL32 WINAPI _KERNEL32_43(LPDWORD thunk,LPCSTR thkbuf,DWORD len,
+DWORD WINAPI _KERNEL32_43(LPDWORD thunk,LPCSTR thkbuf,DWORD len,
                            LPCSTR dll16,LPCSTR dll32)
 {
 	HINSTANCE16	hmod;
@@ -686,17 +715,17 @@
 	hmod = LoadLibrary16(dll16);
 	if (hmod<32) {
 		fprintf(stderr,"->failed to load 16bit DLL %s, error %d\n",dll16,hmod);
-		return NULL;
+		return 0;
 	}
 	segaddr = (DWORD)WIN32_GetProcAddress16(hmod,(LPSTR)thkbuf);
 	if (!segaddr) {
 		fprintf(stderr,"->no %s exported from %s!\n",thkbuf,dll16);
-		return NULL;
+		return 0;
 	}
 	addr = (LPDWORD)PTR_SEG_TO_LIN(segaddr);
 	if (addr[0] != len) {
 		fprintf(stderr,"->thkbuf length mismatch? %ld vs %ld\n",len,addr[0]);
-		return NULL;
+		return 0;
 	}
 	if (!addr[1])
 		return 0;
@@ -726,12 +755,10 @@
 
 	memcpy(&context16,context,sizeof(context16));
 
-	curstack = PTR_SEG_TO_LIN(IF1632_Saved16_ss_sp);
-	memcpy(curstack-stacksize,(LPBYTE)EBP_reg(context),stacksize);
+	curstack = (LPBYTE)CURRENT_STACK16;
+	memcpy(curstack-stacksize-4,(LPBYTE)EBP_reg(context),stacksize);
 	fprintf(stderr,"IF1632_Saved16_ss_sp is 0x%08lx\n",IF1632_Saved16_ss_sp);
 	EBP_reg(&context16)	 = LOWORD(IF1632_Saved16_ss_sp)-stacksize;
-	IF1632_Saved16_ss_sp	-= stacksize;
-
 	DI_reg(&context16)	 = CX_reg(context);
 	CS_reg(&context16)	 = HIWORD(EAX_reg(context));
 	IP_reg(&context16)	 = LOWORD(EAX_reg(context));
@@ -739,12 +766,10 @@
 	 * needed
 	 */
 #ifndef WINELIB
-	ret = CallTo16_regs_(&context16);
+	ret = CallTo16_regs_(&context16,-stacksize);
 #endif
 	fprintf(stderr,". returned %08lx\n",ret);
 	EAX_reg(context) 	 = ret;
-	IF1632_Saved16_ss_sp	+= stacksize;
-
 }
 
 /***********************************************************************
@@ -905,33 +930,32 @@
     fprintf(stderr,"KERNEL32_88(%ld,0x%08lx,%p,[ ",nr,flags,fun);
     for (i=0;i<nr/4;i++) fprintf(stderr,"0x%08lx,",args[i]);
     fprintf(stderr,"])");
-#ifndef WINELIB
     switch (nr) {
-    case 0:	ret = CallTo32_0(fun);
+    case 0:	ret = fun();
 		break;
-    case 4:	ret = CallTo32_1(fun,args[0]);
+    case 4:	ret = fun(args[0]);
 		break;
-    case 8:	ret = CallTo32_2(fun,args[0],args[1]);
+    case 8:	ret = fun(args[0],args[1]);
 		break;
-    case 12:	ret = CallTo32_3(fun,args[0],args[1],args[2]);
+    case 12:	ret = fun(args[0],args[1],args[2]);
 		break;
-    case 16:	ret = CallTo32_4(fun,args[0],args[1],args[2],args[3]);
+    case 16:	ret = fun(args[0],args[1],args[2],args[3]);
 		break;
-    case 20:	ret = CallTo32_5(fun,args[0],args[1],args[2],args[3],args[4]);
+    case 20:	ret = fun(args[0],args[1],args[2],args[3],args[4]);
 		break;
-    case 24:	ret = CallTo32_6(fun,args[0],args[1],args[2],args[3],args[4],args[5]);
+    case 24:	ret = fun(args[0],args[1],args[2],args[3],args[4],args[5]);
 		break;
-    case 28:	ret = CallTo32_7(fun,args[0],args[1],args[2],args[3],args[4],args[5],args[6]);
+    case 28:	ret = fun(args[0],args[1],args[2],args[3],args[4],args[5],args[6]);
 		break;
-    case 32:	ret = CallTo32_8(fun,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7]);
+    case 32:	ret = fun(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7]);
 		break;
-    case 36:	ret = CallTo32_9(fun,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]);
+    case 36:	ret = fun(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]);
 		break;
-    case 40:	ret = CallTo32_10(fun,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9]);
+    case 40:	ret = fun(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9]);
 		break;
-    case 44:	ret = CallTo32_11(fun,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10]);
+    case 44:	ret = fun(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10]);
 		break;
-    case 48:	ret = CallTo32_12(fun,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11]);
+    case 48:	ret = fun(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;
     default:
 	fprintf(stderr,"    unsupported nr of arguments, %ld\n",nr);
@@ -939,7 +963,6 @@
 	break;
 
     }
-#endif
     fprintf(stderr," returning %ld ...\n",ret);
     return ret;
 }
@@ -953,3 +976,107 @@
     fprintf(stderr,"KERNEL_619(0x%04x,0x%08lx,0x%08lx)\n",x,y,z);
     return x;
 }
+
+/**********************************************************************
+ *			AllocSLCallback		(KERNEL32)
+ *
+ * Win95 uses some structchains for callbacks. It allocates them
+ * in blocks of 100 entries, size 32 bytes each, layout:
+ * blockstart:
+ * 	0:	PTR	nextblockstart
+ *	4:	entry	*first;
+ *	8:	WORD	sel ( start points to blockstart)
+ *	A:	WORD	unknown
+ * 100xentry:
+ *	00..17:		Code
+ *	18:	PDB	*owning_process;
+ *	1C:	PTR	blockstart
+ *
+ * We ignore this for now. (Just a note for further developers)
+ * FIXME: use this method, so we don't waste selectors...
+ *
+ * Following code is then generated by AllocSLCallback. The code is 16 bit, so
+ * the 0x66 prefix switches from word->long registers.
+ *
+ *	665A		pop	edx 
+ *	6668x arg2 x 	pushl	<arg2>
+ *	6652		push	edx
+ *	EAx arg1 x	jmpf	<arg1>
+ *
+ * returns the startaddress of this thunk.
+ *
+ * Note, that they look very similair to the ones allocates by THUNK_Alloc.
+ */
+DWORD WINAPI
+AllocSLCallback(DWORD finalizer,DWORD callback) {
+	LPBYTE	x,thunk = HeapAlloc( GetProcessHeap(), 0, 32 );
+	WORD	sel;
+
+	x=thunk;
+	*x++=0x66;*x++=0x5a;				/* popl edx */
+	*x++=0x66;*x++=0x68;*(DWORD*)x=finalizer;x+=4;	/* pushl finalizer */
+	*x++=0x66;*x++=0x52;				/* pushl edx */
+	*x++=0xea;*(DWORD*)x=callback;x+=4;		/* jmpf callback */
+
+	*(DWORD*)(thunk+18) = GetCurrentProcessId();
+
+	sel = SELECTOR_AllocBlock( thunk , 32, SEGMENT_CODE, FALSE, FALSE );
+	return (sel<<16)|0;
+}
+
+void WINAPI
+FreeSLCallback(DWORD x) {
+	fprintf(stderr,"FreeSLCallback(0x%08lx)\n",x);
+}
+
+/**********************************************************************
+ * 		KERNEL_358		(KERNEL)
+ * Allocates a code segment which starts at the address passed in x. limit
+ * 0xfffff, and returns the pointer to the start.
+ */
+DWORD WINAPI
+_KERNEL_358(DWORD x) {
+	WORD	sel;
+
+	fprintf(stderr,"_KERNEL_358(0x%08lx),stub\n",x);
+	if (!HIWORD(x))
+		return x;
+
+	sel = SELECTOR_AllocBlock( PTR_SEG_TO_LIN(x) , 0xffff, SEGMENT_CODE, FALSE, FALSE );
+	return (sel<<16)|(0x0000);
+}
+
+/**********************************************************************
+ * 		KERNEL_359		(KERNEL)
+ * Frees the code segment of the passed linear pointer (This has usually
+ * been allocated by _KERNEL_358).
+ */
+VOID WINAPI
+_KERNEL_359(DWORD x) {
+	DWORD	savedsssp;
+
+	fprintf(stderr,"_KERNEL_359(0x%08lx),stub\n",x);
+	if ((HIWORD(x) & 7)!=7)
+		return;
+	savedsssp = IF1632_Saved16_ss_sp;IF1632_Saved16_ss_sp = 0;
+	SELECTOR_FreeBlock(x>>16,1);
+	IF1632_Saved16_ss_sp = savedsssp;
+	return;
+}
+
+/**********************************************************************
+ * 		KERNEL_472		(KERNEL)
+ * something like GetCurrenthInstance.
+ */
+VOID WINAPI
+_KERNEL_472(CONTEXT *context) {
+	fprintf(stderr,"_KERNEL_472(0x%08lx),stub\n",EAX_reg(context));
+	if (!EAX_reg(context)) {
+		TDB *pTask = (TDB*)GlobalLock16(GetCurrentTask());
+		AX_reg(context)=pTask->hInstance;
+		return;
+	}
+	if (!HIWORD(EAX_reg(context)))
+		return; /* returns the passed value */
+	/* hmm ... fixme */
+}
diff --git a/if1632/winmm.spec b/if1632/winmm.spec
index 3ee913f..ba38635 100644
--- a/if1632/winmm.spec
+++ b/if1632/winmm.spec
@@ -1,7 +1,7 @@
 name winmm
 type win32
 
-0001 stub PlaySoundA
+0001 stdcall PlaySoundA(ptr long long) PlaySound32A
 0004 stub CloseDriver
 0005 stub DefDriverProc
 0006 stub DriverCallback
@@ -16,7 +16,7 @@
 0015 stub OpenDriver
 0016 stub OpenDriverA
 0017 stub PlaySound
-0018 stub PlaySoundW
+0018 stdcall PlaySoundW(ptr long long) PlaySound32W
 0019 stub SendDriverMessage
 0020 stub auxGetDevCapsA
 0021 stub auxGetDevCapsW
@@ -118,7 +118,7 @@
 0117 stub mmioFlush
 0118 stub mmioGetInfo
 0119 stub mmioInstallIOProc16
-0120 stub mmioInstallIOProcA
+0120 stdcall mmioInstallIOProcA(long ptr long) mmioInstallIOProc32A
 0121 stub mmioInstallIOProcW
 0122 stub mmioOpenA
 0123 stub mmioOpenW
diff --git a/include/accel.h b/include/accel.h
index 7c3ad95..e9b3be8 100644
--- a/include/accel.h
+++ b/include/accel.h
@@ -1,8 +1,7 @@
 /*
  * structure definitions for ACCELERATORS
  *
- * Copyright  Martin Ayotte, 1994
- *
+ * taken straight from Win32 SDK includes
  */
 
 #ifndef __WINE_ACCEL_H
@@ -10,21 +9,28 @@
 
 #include "windows.h"
 
-typedef struct {
-	WORD		wEvent;
-	WORD		wIDval;
-	BYTE		type;
-	} ACCELENTRY, *LPACCELENTRY;
+#pragma pack(1)
 
-typedef struct {
-	WORD		wCount;
-	ACCELENTRY 	tbl[1];
-	} ACCELHEADER, *LPACCELHEADER;
+#define	FVIRTKEY	TRUE          /* Assumed to be == TRUE */
+#define	FNOINVERT	0x02
+#define	FSHIFT		0x04
+#define	FCONTROL	0x08
+#define	FALT		0x10
 
-#define VIRTKEY_ACCEL	0x01
-#define SHIFT_ACCEL	0x04
-#define CONTROL_ACCEL	0x08
-#define ALT_ACCEL       0x10
-#define SYSTEM_ACCEL	0x80
+typedef struct tagACCEL16 {
+	BYTE	fVirt;		/* Also called the flags field */
+	WORD	key;
+	WORD	cmd;
+} ACCEL16, *LPACCEL16;
+
+typedef struct tagACCEL32 {
+	BYTE	fVirt;		/* Also called the flags field */
+	BYTE	pad0;
+	WORD	key;
+	WORD	cmd;
+	WORD	pad1;
+} ACCEL32, *LPACCEL32;
+
+#pragma pack(4)
 
 #endif  /* __WINE_ACCEL_H */
diff --git a/include/callback.h b/include/callback.h
index 9bd9049..40bf782 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -22,7 +22,7 @@
 
 #ifndef WINELIB
 
-extern LONG CALLBACK CallTo16_regs_     (const CONTEXT *context);
+extern LONG CALLBACK CallTo16_regs_     (const CONTEXT *context, INT32 offset);
 extern WORD CALLBACK CallTo16_word_     (FARPROC16);
 extern WORD CALLBACK CallTo16_word_w    (FARPROC16,WORD);
 extern LONG CALLBACK CallTo16_long_l    (FARPROC16,LONG);
@@ -36,16 +36,12 @@
 extern WORD CALLBACK CallTo16_word_llwl (FARPROC16,LONG,LONG,WORD,LONG);
 extern WORD CALLBACK CallTo16_word_lwll (FARPROC16,LONG,WORD,LONG,LONG);
 extern LONG CALLBACK CallTo16_long_wwwl (FARPROC16,WORD,WORD,WORD,LONG);
-extern LONG CALLBACK CallTo16_wndp_wwwl (FARPROC16,WORD,WORD,WORD,LONG);
 extern WORD CALLBACK CallTo16_word_lwww (FARPROC16,LONG,WORD,WORD,WORD);
 extern WORD CALLBACK CallTo16_word_wwll (FARPROC16,WORD,WORD,LONG,LONG);
 extern WORD CALLBACK CallTo16_word_wllwl(FARPROC16,WORD,LONG,LONG,WORD,LONG);
 extern LONG CALLBACK CallTo16_long_lwwll(FARPROC16,LONG,WORD,WORD,LONG,LONG);
 extern WORD CALLBACK CallTo16_word_wwlll(FARPROC16,WORD,WORD,LONG,LONG,LONG);
 extern WORD CALLBACK CallTo16_word_wwwww(FARPROC16,WORD,WORD,WORD,WORD,WORD);
-extern LONG CALLBACK CallTo16_wndp_lllllllwlwwwl(FARPROC16,LONG,LONG,LONG,LONG,
-                                                 LONG,LONG,LONG,WORD,LONG,WORD,
-                                                 WORD,WORD,LONG);
 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);
@@ -64,25 +60,6 @@
 #define CallWordBreakProc16( func, lpch, ichCurrent, cch, code ) \
     CallTo16_word_lwww( func, lpch, ichCurrent, cch, code )
 
-
-/* List of the 32-bit callback functions. This list is used  */
-/* by the build program to generate the file if1632/callto32.S */
-
-extern LONG CALLBACK CallTo32_0( FARPROC32 );
-extern LONG CALLBACK CallTo32_1( FARPROC32, DWORD );
-extern LONG CALLBACK CallTo32_2( FARPROC32, DWORD, DWORD );
-extern LONG CALLBACK CallTo32_3( FARPROC32, DWORD, DWORD, DWORD );
-extern LONG CALLBACK CallTo32_4( FARPROC32, DWORD, DWORD, DWORD, DWORD );
-extern LONG CALLBACK CallTo32_5( FARPROC32, DWORD, DWORD, DWORD, DWORD, DWORD );
-extern LONG CALLBACK CallTo32_6( FARPROC32, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD );
-extern LONG CALLBACK CallTo32_7( FARPROC32, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD );
-extern LONG CALLBACK CallTo32_8( FARPROC32, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD );
-extern LONG CALLBACK CallTo32_9( FARPROC32, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD );
-extern LONG CALLBACK CallTo32_10( FARPROC32, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD );
-extern LONG CALLBACK CallTo32_11( FARPROC32, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD );
-extern LONG CALLBACK CallTo32_12( FARPROC32, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD );
-extern LONG CALLBACK CallTo32_13( FARPROC32, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD );
-
 #else  /* WINELIB */
 
 #define CallDriverProc( func, dwId, msg, hdrvr, lparam1, lparam2 ) \
diff --git a/include/mmsystem.h b/include/mmsystem.h
index 4735202..d2f5c16 100644
--- a/include/mmsystem.h
+++ b/include/mmsystem.h
@@ -131,6 +131,9 @@
 
 WORD WINAPI mmsystemGetVersion(void);
 BOOL16 WINAPI sndPlaySound(LPCSTR lpszSoundName, UINT16 uFlags);
+BOOL32 WINAPI PlaySound32A(LPCSTR pszSound, HMODULE32 hmod, DWORD fdwSound);
+BOOL32 WINAPI PlaySound32W(LPCWSTR pszSound, HMODULE32 hmod, DWORD fdwSound);
+#define PlaySound WINELIB_NAME_AW(PlaySound)
 
 #define SND_SYNC            0x0000  /* play synchronously (default) */
 #define SND_ASYNC           0x0001  /* play asynchronously */
@@ -139,6 +142,12 @@
 #define SND_LOOP            0x0008  /* loop the sound until next sndPlaySound */
 #define SND_NOSTOP          0x0010  /* don't stop any currently playing sound */
 
+#define SND_NOWAIT	0x00002000L /* don't wait if the driver is busy */
+#define SND_ALIAS       0x00010000L /* name is a registry alias */
+#define SND_ALIAS_ID	0x00110000L /* alias is a predefined ID */
+#define SND_FILENAME    0x00020000L /* name is file name */
+#define SND_RESOURCE    0x00040004L /* name is resource name or atom */
+
 /* waveform audio error return values */
 #define WAVERR_BADFORMAT      (WAVERR_BASE + 0)    /* unsupported wave format */
 #define WAVERR_STILLPLAYING   (WAVERR_BASE + 1)    /* still something playing */
@@ -527,13 +536,16 @@
 #define CFSEPCHAR       '+'             /* compound file name separator char. */
 
 typedef DWORD           FOURCC;         /* a four character code */
-typedef LONG (CALLBACK *LPMMIOPROC)(LPSTR lpmmioinfo, UINT16 uMessage,
-                                    LPARAM lParam1, LPARAM lParam2);
+typedef LONG (CALLBACK *LPMMIOPROC16)(LPSTR lpmmioinfo, UINT16 uMessage,
+                                      LPARAM lParam1, LPARAM lParam2);
+typedef LONG (CALLBACK *LPMMIOPROC32)(LPSTR lpmmioinfo, UINT32 uMessage,
+                                      LPARAM lParam1, LPARAM lParam2);
+DECL_WINELIB_TYPE(LPMMIOPROC);
 
 typedef struct {
         DWORD           dwFlags;        /* general status flags */
         FOURCC          fccIOProc;      /* pointer to I/O procedure */
-        LPMMIOPROC      pIOProc;        /* pointer to I/O procedure */
+        LPMMIOPROC16    pIOProc;        /* pointer to I/O procedure */
         UINT16            wErrorRet;      /* place for error to be returned */
         HTASK16         htask;          /* alternate local task */
         /* fields maintained by MMIO functions during buffered I/O */
@@ -623,9 +635,12 @@
                 ( (DWORD)(BYTE)(ch0) | ( (DWORD)(BYTE)(ch1) << 8 ) |    \
                 ( (DWORD)(BYTE)(ch2) << 16 ) | ( (DWORD)(BYTE)(ch3) << 24 ) )
 
+LPMMIOPROC16 WINAPI mmioInstallIOProc16(FOURCC,LPMMIOPROC16,DWORD);
+LPMMIOPROC32 WINAPI mmioInstallIOProc32A(FOURCC,LPMMIOPROC32,DWORD);
+LPMMIOPROC32 WINAPI mmioInstallIOProc32W(FOURCC,LPMMIOPROC32,DWORD);
+#define      mmioInstallIOPro WINELIB_NAME_AW(mmioInstallIOProc)
+
 FOURCC WINAPI mmioStringToFOURCC(LPCSTR sz, UINT16 uFlags);
-LPMMIOPROC WINAPI mmioInstallIOProc(FOURCC fccIOProc, LPMMIOPROC pIOProc,
-    DWORD dwFlags);
 HMMIO16 WINAPI mmioOpen(LPSTR szFileName, MMIOINFO * lpmmioinfo,
     DWORD dwOpenFlags);
 
diff --git a/include/resource.h b/include/resource.h
index 50bd60a..4f1cd26 100644
--- a/include/resource.h
+++ b/include/resource.h
@@ -42,6 +42,7 @@
 #define HAVE_WINE_CONSTRUCTOR
 #else
 #define WINE_CONSTRUCTOR
+#undef HAVE_WINE_CONSTRUCTOR
 #endif
 
 typedef HGLOBAL16 (CALLBACK *RESOURCEHANDLER16)(HGLOBAL16, HMODULE16, HRSRC16 );
diff --git a/include/stackframe.h b/include/stackframe.h
index 09cdb85..f1b513a 100644
--- a/include/stackframe.h
+++ b/include/stackframe.h
@@ -15,33 +15,32 @@
   /* 16-bit stack layout after CallFrom16() */
 typedef struct
 {
-    DWORD   saved_ss_sp;             /* saved previous 16-bit stack */
-    DWORD   ebp;                     /* full 32-bit content of ebp */
-    WORD    entry_ip;                /* ip of entry point */
-    WORD    ds;                      /* ds */
-    WORD    entry_cs;                /* cs of entry point */
-    WORD    es;                      /* es */
-    DWORD   entry_point WINE_PACKED; /* 32-bit entry point to call */
-    WORD    bp;                      /* 16-bit bp */
-    WORD    ip;                      /* return address */
-    WORD    cs;
-    WORD    args[1];                 /* arguments to API function */
+    DWORD   saved_ss_sp;    /* 00 saved previous 16-bit stack */
+    DWORD   ebp;            /* 04 full 32-bit content of ebp */
+    WORD    entry_ip;       /* 08 ip of entry point */
+    WORD    ds;             /* 0a ds */
+    WORD    entry_cs;       /* 0c cs of entry point */
+    WORD    es;             /* 0e es */
+    DWORD   entry_point;    /* 10 32-bit entry point to call */
+    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() */
 typedef struct
 {
-    DWORD   saved_esp;      /* saved previous 32-bit stack */
-    DWORD   edi;            /* saved registers */
-    DWORD   esi;
-    DWORD   edx;
-    DWORD   ecx;
-    DWORD   ebx;
-    DWORD   restore_addr;   /* return address for restoring code selector */
-    DWORD   codeselector;   /* code selector to restore */
-    DWORD   ebp;            /* saved 32-bit frame pointer */
-    DWORD   retaddr;        /* actual return address */
-    DWORD   args[1];        /* arguments to 16-bit function */
+    DWORD   edi;            /* 00 saved registers */
+    DWORD   esi;            /* 04 */
+    DWORD   edx;            /* 08 */
+    DWORD   ecx;            /* 0c */
+    DWORD   ebx;            /* 10 */
+    DWORD   restore_addr;   /* 14 return address for restoring code selector */
+    DWORD   codeselector;   /* 18 code selector to restore */
+    DWORD   ebp;            /* 1c saved 32-bit frame pointer */
+    DWORD   retaddr;        /* 20 actual return address */
+    DWORD   args[1];        /* 24 arguments to 16-bit function */
 } STACK32FRAME;
 
 #pragma pack(4)
diff --git a/include/task.h b/include/task.h
index 1fe0a2c..ef54135 100644
--- a/include/task.h
+++ b/include/task.h
@@ -68,7 +68,7 @@
     WORD      unused1;                    /* 0a */
     HTASK16   hSelf;                      /* 0c Selector of this TDB */
     HANDLE16  hPrevInstance;              /* 0e Previous instance of module */
-    DWORD     esp;                        /* 10 32-bit stack pointer */
+    DWORD     unused2;                    /* 10 */
     WORD      ctrlword8087;               /* 14 80x87 control word */
     WORD      flags;                      /* 16 Task flags */
     UINT16    error_mode;                 /* 18 Error mode (see SetErrorMode)*/
diff --git a/include/windows.h b/include/windows.h
index e2afd45..5cd9e11 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -5210,6 +5210,32 @@
 	UINT32	uiLengthDrawn;
 } DRAWTEXTPARAMS,*LPDRAWTEXTPARAMS;
 
+/* ifdef _x86_ ... */
+typedef struct _LDT_ENTRY {
+    WORD	LimitLow;
+    WORD	BaseLow;
+    union {
+	struct {
+	    BYTE	BaseMid;
+	    BYTE	Flags1;/*Declare as bytes to avoid alignment problems */
+	    BYTE	Flags2; 
+	    BYTE	BaseHi;
+	} Bytes;
+	struct {
+	    DWORD	BaseMid		: 8;
+	    DWORD	Type		: 5;
+	    DWORD	Dpl		: 2;
+	    DWORD	Pres		: 1;
+	    DWORD	LimitHi		: 4;
+	    DWORD	Sys		: 1;
+	    DWORD	Reserved_0	: 1;
+	    DWORD	Default_Big	: 1;
+	    DWORD	Granularity	: 1;
+	    DWORD	BaseHi		: 8;
+	} Bits;
+    } HighWord;
+} LDT_ENTRY, *LPLDT_ENTRY;
+
 #pragma pack(4)
 
 /* Declarations for functions that exist only in Win16 */
@@ -5219,7 +5245,6 @@
 WORD        WINAPI AllocSelector(WORD);
 WORD        WINAPI AllocSelectorArray(WORD);
 VOID        WINAPI CalcChildScroll(HWND16,WORD);
-INT16       WINAPI Catch(LPCATCHBUF);
 VOID        WINAPI CascadeChildWindows(HWND16,WORD);
 INT16       WINAPI CloseComm(INT16);
 HGLOBAL16   WINAPI CreateCursorIconIndirect(HINSTANCE16,CURSORICONINFO*,
@@ -5261,7 +5286,7 @@
 HDC16       WINAPI GetDCState(HDC16);
 HWND16      WINAPI GetDesktopHwnd(void);
 SEGPTR      WINAPI GetDOSEnvironment(void);
-INT16       WINAPI GetEnvironment(LPCSTR,LPSTR,UINT16);
+INT16       WINAPI GetEnvironment(LPCSTR,LPDEVMODE16,UINT16);
 HMODULE16   WINAPI GetExePtr(HANDLE16);
 WORD        WINAPI GetExeVersion(void);
 WORD        WINAPI GetExpWinVer(HMODULE16);
@@ -5341,7 +5366,7 @@
 DWORD       WINAPI SetDCOrg(HDC16,INT16,INT16);
 VOID        WINAPI SetDCState(HDC16,HDC16);
 BOOL16      WINAPI SetDeskPattern(void);
-INT16       WINAPI SetEnvironment(LPCSTR,LPCSTR,UINT16);
+INT16       WINAPI SetEnvironment(LPCSTR,LPDEVMODE16,UINT16);
 WORD        WINAPI SetHookFlags(HDC16,WORD);
 HMETAFILE16 WINAPI SetMetaFileBits(HGLOBAL16);
 VOID        WINAPI SetPriority(HTASK16,INT16);
@@ -5359,7 +5384,6 @@
 VOID        WINAPI SwitchStackBack(void);
 VOID        WINAPI SwitchStackTo(WORD,WORD,WORD);
 VOID        WINAPI TileChildWindows(HWND16,WORD);
-INT16       WINAPI Throw(LPCATCHBUF,INT16);
 INT16       WINAPI UngetCommChar(INT16,CHAR);
 VOID        WINAPI UserYield(void);
 BOOL16      WINAPI WaitEvent(HTASK16);
@@ -5490,6 +5514,7 @@
 #define     GetTextExtentExPoint WINELIB_NAME_AW(GetTextExtentExPoint)
 LCID        WINAPI GetThreadLocale();
 INT32       WINAPI GetThreadPriority(HANDLE32);
+BOOL32      WINAPI GetThreadSelectorEntry(HANDLE32,DWORD,LPLDT_ENTRY);
 BOOL32      WINAPI GetUserName32A(LPSTR,LPDWORD);
 BOOL32      WINAPI GetUserName32W(LPWSTR,LPDWORD);
 #define     GetUserName WINELIB_NAME_AW(GetUserName)
diff --git a/include/winnt.h b/include/winnt.h
index 6664527..a23df14 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -139,32 +139,6 @@
 
 #endif  /* __WINE__ */
 
-/* ifdef _x86_ ... */
-typedef struct _LDT_ENTRY {
-    WORD	LimitLow;
-    WORD	BaseLow;
-    union {
-	struct {
-	    BYTE	BaseMid;
-	    BYTE	Flags1;/*Declare as bytes to avoid alignment problems */
-	    BYTE	Flags2; 
-	    BYTE	BaseHi;
-	} Bytes;
-	struct {
-	    DWORD	BaseMid		: 8;
-	    DWORD	Type		: 5;
-	    DWORD	Dpl		: 2;
-	    DWORD	Pres		: 1;
-	    DWORD	LimitHi		: 4;
-	    DWORD	Sys		: 1;
-	    DWORD	Reserved_0	: 1;
-	    DWORD	Default_Big	: 1;
-	    DWORD	Granularity	: 1;
-	    DWORD	BaseHi		: 8;
-	} Bits;
-    } HighWord;
-} LDT_ENTRY, *LPLDT_ENTRY;
-
 /*
  * Exception codes
  */
diff --git a/include/winsock.h b/include/winsock.h
index cfd1ce5..84187ef 100644
--- a/include/winsock.h
+++ b/include/winsock.h
@@ -176,7 +176,7 @@
 #define WS_SO_LINGER       0x0080          /* linger on close if data present */
 #define WS_SO_OOBINLINE    0x0100          /* leave received OOB data in line */
 
-#define WS_SO_DONTLINGER   (UINT16)(~WS_SO_LINGER)
+#define WS_SO_DONTLINGER   (UINT32)(~WS_SO_LINGER)
 
 /*
  * Additional options.
@@ -235,7 +235,7 @@
 #define WS_FD_CONNECT      0x0010
 #define WS_FD_CLOSE        0x0020
 
-#define WS_FD_NONBLOCK	   0x10000000	/* internal per-socket flags */
+#define WS_FD_LISTENING	   0x10000000	/* internal per-socket flags */
 #define WS_FD_INACTIVE	   0x20000000
 #define WS_FD_CONNECTED	   0x40000000
 #define WS_FD_RAW	   0x80000000
diff --git a/libtest/Makefile.in b/libtest/Makefile.in
index e9f772a..3a85109 100644
--- a/libtest/Makefile.in
+++ b/libtest/Makefile.in
@@ -3,6 +3,7 @@
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = none
+RCFLAGS   = -w16 -h
 PROGRAMS  = expand hello hello2 hello3 hello4 new rolex
 ALL_LIBS  = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LDLIBS)
 
@@ -15,13 +16,17 @@
 	new.c \
 	rolex.c
 
-GEN_C_SRCS = \
-	hello3res.c
+RC_SRCS = \
+	hello3res.rc
 
 all: check_winerc $(PROGRAMS)
 
+depend:: $(RC_SRCS:.rc=.h)
+
 @MAKE_RULES@
 
+$(RC_SRCS:.rc=.c) $(RC_SRCS:.rc=.h): $(WINERC)
+
 expand: expand.o
 	$(CC) -o expand expand.o $(LDOPTIONS) $(ALL_LIBS)
 
@@ -43,6 +48,4 @@
 rolex: rolex.o
 	$(CC) -o rolex rolex.o $(LDOPTIONS) $(ALL_LIBS)
 
-hello3res.c hello3res.h: $(WINERC)
-
 ### Dependencies:
diff --git a/libtest/hello3res.rc b/libtest/hello3res.rc
index 5f5408c..c0dfe0a 100644
--- a/libtest/hello3res.rc
+++ b/libtest/hello3res.rc
@@ -24,7 +24,3 @@
 	CONTROL "", 106, "LISTBOX", LBS_STANDARD | LBS_DISABLENOSCROLL | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 86, 23, 86, 85
 #endif
 END
-
-
-BITDEMO BITMAP "../rc/winelogo.bmp"
-
diff --git a/loader/main.c b/loader/main.c
index b3e4f8b..944ffb7 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -23,6 +23,7 @@
 #include "queue.h"
 #include "syscolor.h"
 #include "sysmetrics.h"
+#include "callback.h"
 #include "file.h"
 #include "gdi.h"
 #include "heap.h"
@@ -180,10 +181,11 @@
 int main(int argc, char *argv[] )
 {
     extern BOOL32 MAIN_WineInit( int *argc, char *argv[] );
+    extern void *CALL32_Init(void);
     extern char * DEBUG_argv0;
 
     int i,loaded;
-    HINSTANCE16 handle;
+    HINSTANCE32 handle;
 
     __winelib = 0;  /* First of all, clear the Winelib flag */
 
@@ -196,6 +198,10 @@
     if (!MAIN_WineInit( &argc, argv )) return 1;
     if (!MAIN_Init()) return 1;
 
+    /* Initialize CALL32 routines */
+    /* This needs to be done just before task-switching starts */
+    IF1632_CallLargeStack = (int (*)(int (*func)(), void *arg))CALL32_Init();
+
     loaded=0;
     for (i = 1; i < argc; i++)
     {
diff --git a/loader/module.c b/loader/module.c
index c40d240..d1cc2b5 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -639,7 +639,9 @@
                   ne_header.rname_tab_offset - ne_header.resource_tab_offset,
                   pData )) return (HMODULE32)11;  /* invalid exe */
         pData += ne_header.rname_tab_offset - ne_header.resource_tab_offset;
+#ifndef WINELIB
 	NE_InitResourceHandler( hModule );
+#endif
     }
     else pModule->res_table = 0;  /* No resource table */
 
@@ -1219,7 +1221,6 @@
 	if (pModule->flags & NE_FFLAGS_SELFLOAD)
 	{
                 HFILE32 hf;
-                HGLOBAL16 hInitialStack32 = 0;
 		/* Handle self loading modules */
 		SEGTABLEENTRY * pSegTable = (SEGTABLEENTRY *) NE_SEG_TABLE(pModule);
 		SELFLOADHEADER *selfloadheader;
@@ -1259,44 +1260,14 @@
                 stack16Top->ip = 0;
                 stack16Top->cs = 0;
 
-		if (!IF1632_Saved32_esp)
-                {
-		  STACK32FRAME* frame32;
-		  char *stack32Top;
-		  /* Setup an initial 32 bit stack frame */
-		  hInitialStack32 = GLOBAL_Alloc( GMEM_FIXED, 0x10000,
-						  hModule, FALSE, FALSE, 
-						  FALSE );
-
-		  /* Create the 32-bit stack frame */
-		  
-		  stack32Top = (char*)GlobalLock16(hInitialStack32) + 
-		    0x10000;
-		  frame32 = (STACK32FRAME *)stack32Top - 1;
-		  frame32->saved_esp = (DWORD)stack32Top;
-		  frame32->edi = 0;
-		  frame32->esi = 0;
-		  frame32->edx = 0;
-		  frame32->ecx = 0;
-		  frame32->ebx = 0;
-		  frame32->ebp = 0;
-		  frame32->restore_addr = 0;
-		  frame32->retaddr      = 0;
-		  frame32->codeselector = WINE_CODE_SELECTOR;
-		  /* pTask->esp = (DWORD)frame32; */
-		}
                 hf = FILE_DupUnixHandle( MODULE_OpenFile( hModule ) );
 		CallTo16_word_ww( selfloadheader->BootApp, hModule, hf );
                 _lclose32(hf);
 		/* some BootApp procs overwrite the selector of dgroup */
 		pSegTable[pModule->dgroup - 1].selector = saved_dgroup;
 		IF1632_Saved16_ss_sp = oldstack;
-		for (i = 2; i <= pModule->seg_count; i++) NE_LoadSegment( hModule, i );
-		if (hInitialStack32)
-                {
-		  GlobalFree16(hInitialStack32);
-		  hInitialStack32 = 0;
-		}
+		for (i = 2; i <= pModule->seg_count; i++)
+                    NE_LoadSegment( hModule, i );
 	} 
 	else
         {
@@ -1638,7 +1609,7 @@
         return 2;  /* File not found */
     if (!(cmdShowHandle = GlobalAlloc16( 0, 2 * sizeof(WORD) )))
         return 8;  /* Out of memory */
-    if (!(cmdLineHandle = GlobalAlloc16( 0, 1024 )))
+    if (!(cmdLineHandle = GlobalAlloc16( 0, 256 )))
     {
         GlobalFree16( cmdShowHandle );
         return 8;  /* Out of memory */
@@ -1683,11 +1654,11 @@
 	}
 
 	if (*p)
-	    lstrcpyn32A( cmdline + 1, p + 1, 1023 );
+	    lstrcpyn32A( cmdline + 1, p + 1, 255 );
 	else
 	    cmdline[1] = '\0';
 
-	cmdline[0] = strlen( cmdline + 1 ) + 1;
+	cmdline[0] = strlen( cmdline + 1 );
 	*p = '\0';
 
 	/* Now load the executable file */
diff --git a/loader/ne_image.c b/loader/ne_image.c
index e1631e9..48df65f 100644
--- a/loader/ne_image.c
+++ b/loader/ne_image.c
@@ -520,7 +520,7 @@
     dprintf_dll( stddeb, "Calling LibMain, cs:ip=%04lx:%04x ds=%04lx di=%04x cx=%04x\n", 
                  CS_reg(&context), IP_reg(&context), DS_reg(&context),
                  DI_reg(&context), CX_reg(&context) );
-    CallTo16_regs_( &context );
+    CallTo16_regs_( &context, 0 );
     return TRUE;
 }
 
diff --git a/loader/pe_image.c b/loader/pe_image.c
index 415094f..f53575b 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -1,4 +1,3 @@
-#ifndef WINELIB
 /* 
  *  Copyright	1994	Eric Youndale & Erik Bos
  *  Copyright	1995	Martin von Löwis
@@ -12,6 +11,7 @@
  */
 
 #include <ctype.h>
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -33,8 +33,10 @@
 #include "options.h"
 #include "stddebug.h"
 #include "debug.h"
-#include "debugger.h"
 #include "xmalloc.h"
+#ifndef WINELIB
+#include "debugger.h"
+#endif
 
 static void PE_InitDLL(PE_MODREF* modref, DWORD type, LPVOID lpReserved);
 
@@ -43,6 +45,7 @@
 
 void dump_exports(IMAGE_EXPORT_DIRECTORY * pe_exports, unsigned int load_addr)
 { 
+#ifndef WINELIB
   char		*Module;
   int		i;
   u_short	*ordinal;
@@ -81,6 +84,7 @@
       }
       DEBUG_AddSymbol(buffer,&daddr, NULL, SYM_WIN32 | SYM_FUNC);
   }
+#endif
 }
 
 /* Look up the specified function or ordinal in the exportlist:
@@ -428,11 +432,8 @@
 static PE_MODULE *PE_LoadImage( int fd )
 {
 	struct pe_data		*pe;
-	DBG_ADDR		daddr;
 	struct stat		stbuf;
 
-	daddr.seg=0;
-	daddr.type = NULL;
 	if (-1==fstat(fd,&stbuf)) {
 		perror("PE_LoadImage:fstat");
 		return NULL;
@@ -443,9 +444,33 @@
 	/* map the PE image somewhere */
 	pe->mappeddll = (HMODULE32)mmap(NULL,stbuf.st_size,PROT_READ,MAP_SHARED,fd,0);
 	if (!pe->mappeddll || pe->mappeddll==-1) {
-		perror("PE_LoadImage:mmap");
-		free(pe);
-		return NULL;
+		if (errno==ENOEXEC) {
+			int	res=0,curread = 0;
+
+			lseek(fd,0,SEEK_SET);
+			/* linux: some filesystems don't support mmap (samba,
+			 * ntfs apparently) so we have to read the image the
+			 * hard way
+			 */
+			pe->mappeddll = xmalloc(stbuf.st_size);
+			while (curread < stbuf.st_size) {
+				res = read(fd,pe->mappeddll+curread,stbuf.st_size-curread);
+				if (res<=0) 
+					break;
+				curread+=res;
+			}
+			if (res == -1) {
+				perror("PE_LoadImage:mmap compat read");
+				free(pe->mappeddll);
+				free(pe);
+				return NULL;
+			}
+
+		} else {
+			perror("PE_LoadImage:mmap");
+			free(pe);
+			return NULL;
+		}
 	}
 	/* link PE header */
 	pe->pe_header = (IMAGE_NT_HEADERS*)(pe->mappeddll+(((IMAGE_DOS_HEADER*)pe->mappeddll)->e_lfanew));
@@ -499,7 +524,6 @@
 	int			load_addr;
 	IMAGE_DATA_DIRECTORY	dir;
 	char			buffer[200];
-	DBG_ADDR		daddr;
 	char			*modname;
 	int			vma_size;
 	
@@ -604,6 +628,7 @@
 		pem->pe_reloc = (void *) RVA(dir.VirtualAddress);
 	}
 
+#ifndef WINELIB
 	if(pe->pe_header->OptionalHeader.DataDirectory
 		[IMAGE_DIRECTORY_ENTRY_DEBUG].Size)
 	  {
@@ -611,6 +636,7 @@
 			pe->pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress,
 			pe->pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size);
 	  }
+#endif
 
 	if(pe->pe_header->OptionalHeader.DataDirectory
 		[IMAGE_DIRECTORY_ENTRY_COPYRIGHT].Size)
@@ -657,19 +683,24 @@
 			*s='\0';
 	}
 
-	/* add start of sections as debugsymbols */
-	for(i=0;i<pe->pe_header->FileHeader.NumberOfSections;i++) {
+#ifndef WINELIB
+        {
+            DBG_ADDR daddr = { NULL, 0, 0 };
+            /* add start of sections as debugsymbols */
+            for(i=0;i<pe->pe_header->FileHeader.NumberOfSections;i++) {
 		sprintf(buffer,"%s_%s",modname,pe->pe_seg[i].Name);
 		daddr.off= RVA(pe->pe_seg[i].VirtualAddress);
 		DEBUG_AddSymbol(buffer,&daddr, NULL, SYM_WIN32 | SYM_FUNC);
-	}
-	/* add entry point */
-	sprintf(buffer,"%s_EntryPoint",modname);
-	daddr.off=RVA(pe->pe_header->OptionalHeader.AddressOfEntryPoint);
-	DEBUG_AddSymbol(buffer,&daddr, NULL, SYM_WIN32 | SYM_FUNC);
-	/* add start of DLL */
-	daddr.off=load_addr;
-	DEBUG_AddSymbol(modname,&daddr, NULL, SYM_WIN32 | SYM_FUNC);
+            }
+            /* add entry point */
+            sprintf(buffer,"%s_EntryPoint",modname);
+            daddr.off=RVA(pe->pe_header->OptionalHeader.AddressOfEntryPoint);
+            DEBUG_AddSymbol(buffer,&daddr, NULL, SYM_WIN32 | SYM_FUNC);
+            /* add start of DLL */
+            daddr.off=load_addr;
+            DEBUG_AddSymbol(modname,&daddr, NULL, SYM_WIN32 | SYM_FUNC);
+        }
+#endif
 }
 
 HINSTANCE16 MODULE_CreateInstance(HMODULE16 hModule,LOADPARAMS *params);
@@ -682,36 +713,47 @@
 	OFSTRUCT	ofs;
 	HMODULE32	hModule;
 	NE_MODULE	*pModule;
+	PE_MODREF	*pem;
 
-	if ((hModule = MODULE_FindModule( name )))
-		return hModule;
+	if ((hModule = MODULE_FindModule( name ))) {
+		/* the .DLL is either loaded or internal */
+		hModule = MODULE_HANDLEtoHMODULE32(hModule);
+		if (!HIWORD(hModule)) /* internal (or bad) */
+			return hModule;
+		/* check if this module is already mapped */
+		pem 	= ((PDB32*)GetCurrentProcessId())->modref_list;
+		while (pem) {
+			if (pem->pe_module->mappeddll == hModule)
+				return hModule;
+			pem = pem->next;
+		}
+		pModule = MODULE_GetPtr(hModule);
+	} else {
 
-	/* try to load builtin, enabled modules first */
-	if ((hModule = BUILTIN_LoadModule( name, FALSE )))
-		return hModule;
+		/* try to load builtin, enabled modules first */
+		if ((hModule = BUILTIN_LoadModule( name, FALSE )))
+			return hModule;
 
-	/* try to open the specified file */
-	if (HFILE_ERROR32==(hFile=OpenFile32(name,&ofs,OF_READ))) {
-		/* Now try the built-in even if disabled */
-		if ((hModule = BUILTIN_LoadModule( name, TRUE ))) {
-			fprintf( stderr, "Warning: could not load Windows DLL '%s', using built-in module.\n", name );
+		/* try to open the specified file */
+		if (HFILE_ERROR32==(hFile=OpenFile32(name,&ofs,OF_READ))) {
+			/* Now try the built-in even if disabled */
+			if ((hModule = BUILTIN_LoadModule( name, TRUE ))) {
+				fprintf( stderr, "Warning: could not load Windows DLL '%s', using built-in module.\n", name );
+				return hModule;
+			}
+			return 1;
+		}
+		if ((hModule = MODULE_CreateDummyModule( &ofs )) < 32) {
+			_lclose32(hFile);
 			return hModule;
 		}
-		return 1;
-	}
-	if ((hModule = MODULE_CreateDummyModule( &ofs )) < 32) {
+		pModule		= (NE_MODULE *)GlobalLock16( hModule );
+		pModule->flags	= NE_FFLAGS_WIN32;
+		pModule->pe_module = PE_LoadImage( FILE_GetUnixHandle(hFile) );
 		_lclose32(hFile);
-		return hModule;
+		if (!pModule->pe_module)
+			return 21;
 	}
-
-	pModule		= (NE_MODULE *)GlobalLock16( hModule );
-	pModule->flags	= NE_FFLAGS_WIN32;
-
-	/* FIXME: check if pe image loaded already ... */
-	pModule->pe_module = PE_LoadImage( FILE_GetUnixHandle(hFile) );
-	_lclose32(hFile);
-	if (!pModule->pe_module)
-		return 21;
 	/* recurse */
 	PE_MapImage(pModule->pe_module,(PDB32*)GetCurrentProcessId(),&ofs,flags);
 	return pModule->pe_module->mappeddll;
@@ -864,4 +906,3 @@
 	return TRUE;
 }
 
-#endif /* WINELIB */
diff --git a/loader/pe_resource.c b/loader/pe_resource.c
index 9b8ae7e..11ee003 100644
--- a/loader/pe_resource.c
+++ b/loader/pe_resource.c
@@ -1,4 +1,3 @@
-#ifndef WINELIB
 /*
  * PE (Portable Execute) File Resources
  *
@@ -149,48 +148,12 @@
 /**********************************************************************
  *	    PE_SizeofResource32
  */
-void
-_check_ptr(DWORD x,DWORD start,LPDWORD lastmax) {
-	if ((x>start) && (x<*lastmax))
-		*lastmax=x;
-}
-
-static void
-walk_resdir(DWORD loadaddr,DWORD rootresdir,DWORD xres,DWORD data,DWORD lvl,LPDWORD max){
-    LPIMAGE_RESOURCE_DIRECTORY		resdir;
-    LPIMAGE_RESOURCE_DATA_ENTRY		dataent;
-    LPIMAGE_RESOURCE_DIRECTORY_ENTRY	et;
-    int	i;
-
-    if (lvl==3) {
-    	dataent = (LPIMAGE_RESOURCE_DATA_ENTRY)(rootresdir+xres);
-	_check_ptr(loadaddr+dataent->OffsetToData,data,max);
-	return;
-    }
-    resdir = (LPIMAGE_RESOURCE_DIRECTORY)(rootresdir+xres);
-    et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
-    for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++)
-	walk_resdir(loadaddr,rootresdir,(lvl==2)?et[i].u2.OffsetToData:et[i].u2.s.OffsetToDirectory,data,lvl+1,max);
-}
-
 DWORD PE_SizeofResource32( HINSTANCE32 hModule, HANDLE32 hRsrc )
 {
-    PE_MODREF	*pem = HMODULE32toPE_MODREF(hModule);
-    DWORD	max,data;
-    IMAGE_DATA_DIRECTORY	dir;
-
-    if (!pem || !pem->pe_resource)
-    	return 0;
-    if (!hRsrc) return 0;
-
-    max=(DWORD)-1;
-    dir=pem->pe_module->pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
-    if(dir.Size)
-    	max=(DWORD)pem->pe_resource+dir.Size;
-
-    data=((DWORD)pem->load_addr+((LPIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
-    walk_resdir(pem->load_addr,(DWORD)pem->pe_resource,0,data,0,&max);
-    return max-data;
+    /* we don't need hModule */
+    if (!hRsrc)
+   	 return 0;
+    return ((LPIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size;
 }
 
 /**********************************************************************
@@ -419,4 +382,3 @@
     }
     return ret;
 }
-#endif
diff --git a/loader/resource.c b/loader/resource.c
index 2654396..23ba6b6 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -416,18 +416,10 @@
 
 /**********************************************************************
  *			LoadAccelerators16	[USER.177]
- *
- * FIXME: this code leaks memory because HACCEL must be a result of LoadResource()
- *        (see TWIN for hints).
  */
 HACCEL16 WINAPI LoadAccelerators16(HINSTANCE16 instance, SEGPTR lpTableName)
 {
-    HACCEL16 	hAccel;
-    HGLOBAL16 	rsc_mem;
-    HRSRC16 hRsrc;
-    BYTE 	*lp;
-    ACCELHEADER	*lpAccelTbl;
-    int 	i, n;
+    HRSRC16	hRsrc;
 
     if (HIWORD(lpTableName))
         dprintf_accel( stddeb, "LoadAccelerators: %04x '%s'\n",
@@ -438,30 +430,7 @@
 
     if (!(hRsrc = FindResource16( instance, lpTableName, RT_ACCELERATOR )))
       return 0;
-    if (!(rsc_mem = LoadResource16( instance, hRsrc ))) return 0;
-
-    lp = (BYTE *)LockResource16(rsc_mem);
-    n = SizeofResource16(instance,hRsrc)/sizeof(ACCELENTRY);
-    hAccel = GlobalAlloc16(GMEM_MOVEABLE, 
-    	sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY));
-    lpAccelTbl = (LPACCELHEADER)GlobalLock16(hAccel);
-    lpAccelTbl->wCount = 0;
-    for (i = 0; i < n; i++) {
-	lpAccelTbl->tbl[i].type = *(lp++);
-	lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
-	lp += 2;
-	lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
-	lp += 2;
-    	if (lpAccelTbl->tbl[i].wEvent == 0) break;
-	dprintf_accel(stddeb,
-		"Accelerator #%u / event=%04X id=%04X type=%02X \n", 
-		i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval, 
-		lpAccelTbl->tbl[i].type);
-	lpAccelTbl->wCount++;
- 	}
-    GlobalUnlock16(hAccel);
-    FreeResource16( rsc_mem );
-    return hAccel;
+    return LoadResource16(instance,hRsrc);
 }
 
 /**********************************************************************
@@ -475,12 +444,7 @@
  */
 HACCEL32 WINAPI LoadAccelerators32W(HINSTANCE32 instance,LPCWSTR lpTableName)
 {
-    HACCEL32 	hAccel;
-    HGLOBAL32 	rsc_mem;
     HRSRC32 hRsrc;
-    BYTE 	*lp;
-    ACCELHEADER	*lpAccelTbl;
-    int 	i, n;
 
     if (HIWORD(lpTableName))
         dprintf_accel( stddeb, "LoadAccelerators: %04x '%s'\n",
@@ -492,31 +456,7 @@
     if (!(hRsrc = FindResource32W( instance, lpTableName, 
 		(LPCWSTR)RT_ACCELERATOR )))
       return 0;
-    if (!(rsc_mem = LoadResource32( instance, hRsrc ))) return 0;
-
-    lp = (BYTE *)LockResource32(rsc_mem);
-    n = SizeofResource32(instance,hRsrc)/sizeof(ACCELENTRY);
-    hAccel = GlobalAlloc16(GMEM_MOVEABLE, 
-    	sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY));
-    lpAccelTbl = (LPACCELHEADER)GlobalLock16(hAccel);
-    lpAccelTbl->wCount = 0;
-    for (i = 0; i < n; i++) {
-	lpAccelTbl->tbl[i].type = *lp;
-	lp += 2;
-	lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
-	lp += 2;
-	lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
-	lp += 4;
-    	if (lpAccelTbl->tbl[i].wEvent == 0) break;
-	dprintf_accel(stddeb,
-		"Accelerator #%u / event=%04X id=%04X type=%02X \n", 
-		i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval, 
-		lpAccelTbl->tbl[i].type);
-	lpAccelTbl->wCount++;
- 	}
-    GlobalUnlock16(hAccel);
-    FreeResource32(rsc_mem);
-    return hAccel;
+    return LoadResource32( instance, hRsrc );
 }
 
 HACCEL32 WINAPI LoadAccelerators32A(HINSTANCE32 instance,LPCSTR lpTableName)
@@ -759,7 +699,7 @@
     return retval;
 }
 
-
+#ifndef WINELIB
 /**********************************************************************
  *	SetResourceHandler	(KERNEL.43)
  */
@@ -784,7 +724,6 @@
     return NULL;
 }
 
-#ifndef WINELIB
 /**********************************************************************
  *	EnumResourceTypesA	(KERNEL32.90)
  */
diff --git a/loader/task.c b/loader/task.c
index 3266976..0dcf6a6 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -47,12 +47,6 @@
   /* Saved 16-bit stack for current process (Win16 only) */
 DWORD IF1632_Saved16_ss_sp = 0;
 
-  /* Saved 32-bit stack for current process (Win16 only) */
-DWORD IF1632_Saved32_esp = 0;
-
-  /* Original Unix stack */
-DWORD IF1632_Original32_esp = 0;
-
   /* Pointer to function to switch to a larger stack */
 int (*IF1632_CallLargeStack)( int (*func)(), void *arg ) = NULL;
 
@@ -412,7 +406,7 @@
                       SELECTOROF(IF1632_Saved16_ss_sp),
                       OFFSETOF(IF1632_Saved16_ss_sp) );
 
-        CallTo16_regs_( &context );
+        CallTo16_regs_( &context, 0 );
         /* This should never return */
         fprintf( stderr, "TASK_CallToStart: Main program returned!\n" );
         TASK_KillCurrentTask( 1 );
@@ -436,7 +430,7 @@
     SEGTABLEENTRY *pSegTable;
     LPSTR name;
     char filename[256];
-    char *stack16Top, *stack32Top;
+    char *stack32Top;
     STACK16FRAME *frame16;
     STACK32FRAME *frame32;
 #ifndef WINELIB32
@@ -575,7 +569,6 @@
 
     stack32Top = (char*)pTask->thdb->teb.stack_top;
     frame32 = (STACK32FRAME *)stack32Top - 1;
-    frame32->saved_esp = (DWORD)stack32Top;
     frame32->edi = 0;
     frame32->esi = 0;
     frame32->edx = 0;
@@ -587,15 +580,14 @@
     frame32->retaddr = (DWORD)TASK_CallToStart;
     frame32->codeselector = WINE_CODE_SELECTOR;
 #endif
-    pTask->esp = (DWORD)frame32;
 
-      /* Create the 16-bit stack frame */
+    /* Create the 16-bit stack frame */
 
     pTask->ss_sp = PTR_SEG_OFF_TO_SEGPTR( hInstance,
                         ((pModule->sp != 0) ? pModule->sp :
                 pSegTable[pModule->ss-1].minsize + pModule->stack_size) & ~1 );
-    stack16Top = (char *)PTR_SEG_TO_LIN( pTask->ss_sp );
-    frame16 = (STACK16FRAME *)stack16Top - 1;
+    pTask->ss_sp -= sizeof(DWORD);  /* To store saved %%esp */
+    frame16 = (STACK16FRAME *)PTR_SEG_TO_LIN( pTask->ss_sp ) - 1;
     frame16->saved_ss_sp = 0;
     frame16->ebp = 0;
     frame16->ds = frame16->es = pTask->hInstance;
@@ -603,6 +595,8 @@
     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);
 #ifndef WINELIB
     frame16->ip = LOWORD( CALLTO16_RetAddr_word );
     frame16->cs = HIWORD( CALLTO16_RetAddr_word );
@@ -631,7 +625,8 @@
         }
         else
         {
-            DBG_ADDR addr = { NULL, pSegTable[pModule->cs-1].selector, pModule->ip };
+            DBG_ADDR addr = { NULL, pSegTable[pModule->cs-1].selector,
+                              pModule->ip };
             fprintf( stderr, "Win16 task '%s': ", name );
             DEBUG_AddBreakpoint( &addr );
         }
@@ -824,14 +819,9 @@
     dprintf_task( stddeb, "Switching to task %04x (%.8s)\n",
                   hTask, pNewTask->module_name );
 
-      /* Save the stacks of the previous task (if any) */
+      /* Save the stack of the previous task (if any) */
 
-    if (pOldTask)
-    {
-        pOldTask->ss_sp = IF1632_Saved16_ss_sp;
-        pOldTask->esp   = IF1632_Saved32_esp;
-    }
-    else IF1632_Original32_esp = IF1632_Saved32_esp;
+    if (pOldTask) pOldTask->ss_sp = IF1632_Saved16_ss_sp;
 
      /* Make the task the last in the linked list (round-robin scheduling) */
 
@@ -840,13 +830,12 @@
     TASK_LinkTask( hTask );
     pNewTask->priority--;
 
-      /* Switch to the new stack */
+    /* Switch to the new stack */
 
     hCurrentTask = hTask;
     pCurrentThread = pNewTask->thdb;
     pCurrentProcess = pCurrentThread->process;
     IF1632_Saved16_ss_sp = pNewTask->ss_sp;
-    IF1632_Saved32_esp   = pNewTask->esp;
 }
 
 
@@ -1051,13 +1040,13 @@
     TDB *pCurTask = (TDB *)GlobalLock16( hCurrentTask );
     MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( pCurTask->hQueue );
     /* Handle sent messages */
-    if (queue && (queue->wakeBits & QS_SENDMESSAGE))
+    while (queue && (queue->wakeBits & QS_SENDMESSAGE))
         QUEUE_ReceiveMessage( queue );
 
     OldYield();
 
     queue = (MESSAGEQUEUE *)GlobalLock16( pCurTask->hQueue );
-    if (queue && (queue->wakeBits & QS_SENDMESSAGE))
+    while (queue && (queue->wakeBits & QS_SENDMESSAGE))
         QUEUE_ReceiveMessage( queue );
 }
 
@@ -1191,7 +1180,7 @@
 
     /* Switch to the new stack */
 
-    IF1632_Saved16_ss_sp = pTask->ss_sp = PTR_SEG_OFF_TO_SEGPTR( seg,
+    IF1632_Saved16_ss_sp = PTR_SEG_OFF_TO_SEGPTR( seg,
                                                   ptr - sizeof(STACK16FRAME) );
     newFrame = CURRENT_STACK16;
 
@@ -1230,18 +1219,18 @@
 
     /* Switch back to the old stack */
 
-    IF1632_Saved16_ss_sp = pTask->ss_sp = pData->old_ss_sp;
+    IF1632_Saved16_ss_sp = pData->old_ss_sp;
     pData->old_ss_sp = 0;
 
     /* Build a stack frame for the return */
 
     newFrame = CURRENT_STACK16;
     newFrame->saved_ss_sp = oldFrame->saved_ss_sp;
-    newFrame->entry_ip    = oldFrame->entry_ip;
-    newFrame->entry_cs    = oldFrame->entry_cs;
-    newFrame->bp          = oldFrame->bp;
-    newFrame->ip          = oldFrame->ip;
-    newFrame->cs          = oldFrame->cs;
+    if (debugging_relay)
+    {
+        newFrame->entry_ip = oldFrame->entry_ip;
+        newFrame->entry_cs = oldFrame->entry_cs;
+    }
 }
 
 
diff --git a/memory/global.c b/memory/global.c
index ce11ed2..6a2b86b 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -395,7 +395,7 @@
  */
 HGLOBAL16 WINAPI GlobalFree16( HGLOBAL16 handle )
 {
-    void *ptr = GlobalLock16( handle );
+    void *ptr = (void *)GET_ARENA_PTR(handle)->base;
 
     dprintf_global( stddeb, "GlobalFree16: %04x\n", handle );
     if (!GLOBAL_FreeBlock( handle )) return handle;  /* failed */
@@ -426,6 +426,7 @@
 #endif  /* CONFIG_IPC */
 
 	if (!GET_ARENA_PTR(handle)->base) return (SEGPTR)0;
+        GET_ARENA_PTR(handle)->lockCount++;
 	return PTR_SEG_OFF_TO_SEGPTR( GlobalHandleToSel(handle), 0 );
 	/* FIXME: put segment value in CX as well */
     }
@@ -441,6 +442,7 @@
 LPVOID WINAPI GlobalLock16( HGLOBAL16 handle )
 {
     if (!handle) return 0;
+    GET_ARENA_PTR(handle)->lockCount++;
 #ifdef CONFIG_IPC
     if (is_dde_handle(handle)) return DDE_AttachHandle(handle, NULL);
 #endif
@@ -453,8 +455,10 @@
  */
 BOOL16 WINAPI GlobalUnlock16( HGLOBAL16 handle )
 {
+    GLOBALARENA *pArena = GET_ARENA_PTR(handle);
     dprintf_global( stddeb, "GlobalUnlock16: %04x\n", handle );
-    return 0;
+    if (pArena->lockCount) pArena->lockCount--;
+    return pArena->lockCount;
 }
 
 
@@ -558,7 +562,7 @@
  */
 BOOL16 WINAPI GlobalUnWire16( HGLOBAL16 handle )
 {
-    return GlobalUnlock16( handle );
+    return !GlobalUnlock16( handle );
 }
 
 
diff --git a/memory/local.c b/memory/local.c
index c0062dc..5a75d1e 100644
--- a/memory/local.c
+++ b/memory/local.c
@@ -1236,7 +1236,7 @@
     if (!hmem)
     {
         /* Remove the block from the heap and try again */
-        LPSTR buffer = HeapAlloc( SystemHeap, 0, oldsize );
+        LPSTR buffer = HeapAlloc( GetProcessHeap(), 0, oldsize );
         if (!buffer) return 0;
         memcpy( buffer, ptr + arena + ARENA_HEADER_SIZE, oldsize );
         LOCAL_FreeArena( ds, arena );
@@ -1245,14 +1245,14 @@
             if (!(hmem = LOCAL_GetBlock( ds, oldsize, flags )))
             {
                 fprintf( stderr, "LocalRealloc: can't restore saved block\n" );
-                HeapFree( SystemHeap, 0, buffer );
+                HeapFree( GetProcessHeap(), 0, buffer );
                 return 0;
             }
             size = oldsize;
         }
         ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );  /* Reload ptr */
         memcpy( ptr + hmem, buffer, oldsize );
-        HeapFree( SystemHeap, 0, buffer );
+        HeapFree( GetProcessHeap(), 0, buffer );
     }
     else
     {
diff --git a/memory/selector.c b/memory/selector.c
index 421cd99..bf4f829 100644
--- a/memory/selector.c
+++ b/memory/selector.c
@@ -138,6 +138,25 @@
     dprintf_selector( stddeb, "SELECTOR_FreeBlock(%04x,%d)\n", sel, count );
     sel &= ~(__AHINCR - 1);  /* clear bottom bits of selector */
     nextsel = sel + (count << __AHSHIFT);
+
+#ifdef __i386__
+    {
+        /* Check if we are freeing current %fs or %gs selector */
+
+        WORD fs, gs;
+
+        __asm__("movw %%fs,%w0":"=r" (fs));
+        if ((fs >= sel) && (fs < nextsel))
+        {
+            fprintf( stderr, "SELECTOR_FreeBlock: freeing %%fs selector (%04x), not good.\n", fs );
+            __asm__("movw %w0,%%fs"::"r" (0));
+        }
+        __asm__("movw %%gs,%w0":"=r" (gs));
+        if ((gs >= sel) && (gs < nextsel))
+            __asm__("movw %w0,%%gs"::"r" (0));
+    }
+#endif  /* __i386__ */
+
     memset( &entry, 0, sizeof(entry) );  /* clear the LDT entries */
     for (i = SELECTOR_TO_ENTRY(sel); count; i++, count--)
     {
@@ -563,7 +582,7 @@
 void WINAPI SMapLS_IP_EBP_36(CONTEXT *context) {x_SMapLS_IP_EBP_x(context,36);}
 void WINAPI SMapLS_IP_EBP_40(CONTEXT *context) {x_SMapLS_IP_EBP_x(context,40);}
 
-void WINAPI SMapLS(CONTEXT *context,int argoff)
+void WINAPI SMapLS(CONTEXT *context)
 {
     if (EAX_reg(context)>=0x10000) {
 	EAX_reg(context) = MapLS((LPVOID)EAX_reg(context));
@@ -573,6 +592,28 @@
     }
 }
 
+void WINAPI SUnMapLS(CONTEXT *context)
+{
+    if (EAX_reg(context)>=0x10000)
+	UnMapLS((SEGPTR)EAX_reg(context));
+}
+
+static void
+x_SUnMapLS_IP_EBP_x(CONTEXT *context,int argoff) {
+	if (*(DWORD*)(EBP_reg(context)+argoff))
+		UnMapLS(*(DWORD*)(EBP_reg(context)+argoff));
+	*(DWORD*)(EBP_reg(context)+argoff)=0;
+}
+void WINAPI SUnMapLS_IP_EBP_8(CONTEXT *context) { x_SUnMapLS_IP_EBP_x(context,12); }
+void WINAPI SUnMapLS_IP_EBP_12(CONTEXT *context) { x_SUnMapLS_IP_EBP_x(context,12); }
+void WINAPI SUnMapLS_IP_EBP_16(CONTEXT *context) { x_SUnMapLS_IP_EBP_x(context,16); }
+void WINAPI SUnMapLS_IP_EBP_20(CONTEXT *context) { x_SUnMapLS_IP_EBP_x(context,20); }
+void WINAPI SUnMapLS_IP_EBP_24(CONTEXT *context) { x_SUnMapLS_IP_EBP_x(context,24); }
+void WINAPI SUnMapLS_IP_EBP_28(CONTEXT *context) { x_SUnMapLS_IP_EBP_x(context,28); }
+void WINAPI SUnMapLS_IP_EBP_32(CONTEXT *context) { x_SUnMapLS_IP_EBP_x(context,32); }
+void WINAPI SUnMapLS_IP_EBP_36(CONTEXT *context) { x_SUnMapLS_IP_EBP_x(context,36); }
+void WINAPI SUnMapLS_IP_EBP_40(CONTEXT *context) { x_SUnMapLS_IP_EBP_x(context,40); }
+
 /**********************************************************************
  *           WOWGetVDMPointer	(KERNEL32.55)
  * Get linear from segmented pointer. (MSDN lib)
diff --git a/memory/string.c b/memory/string.c
index 60194a3..88b72c4 100644
--- a/memory/string.c
+++ b/memory/string.c
@@ -281,7 +281,7 @@
     dprintf_string(stddeb,"strcpyn '%s' for %d chars\n",
 		 (src)?src:"NULL",n);
     while ((n-- > 1) && *src) *p++ = *src++;
-    *p = 0;
+    if (n >= 0) *p = 0;
     return dst;
 }
 
@@ -293,7 +293,7 @@
 {
     LPWSTR p = dst;
     while ((n-- > 1) && *src) *p++ = *src++;
-    *p = 0;
+    if (n >= 0) *p = 0;
     return dst;
 }
 
@@ -421,7 +421,7 @@
 {
     LPWSTR p = dst;
     while ((n-- > 1) && *src) *p++ = (WCHAR)(unsigned char)*src++;
-    *p = 0;
+    if (n >= 0) *p = 0;
     return dst;
 }
 
@@ -433,7 +433,7 @@
 {
     LPSTR p = dst;
     while ((n-- > 1) && *src) *p++ = (CHAR)*src++;
-    *p = 0;
+    if (n >= 0) *p = 0;
     return dst;
 }
 
@@ -560,9 +560,10 @@
  */
 BOOL32 WINAPI OemToChar32A( LPCSTR s, LPSTR d )
 {
+    LPSTR oldd = d;
     dprintf_string(stddeb,"OemToChar '%s'\n", (s)?s:"NULL");
     while ((*d++ = OEM_TO_ANSI(*s++)));
-    dprintf_string(stddeb," to '%s'\n", (d)?d:"NULL");
+    dprintf_string(stddeb," to '%s'\n", oldd);
     return TRUE;
 }
 
diff --git a/misc/comm.c b/misc/comm.c
index 22e16c9..5dc0621 100644
--- a/misc/comm.c
+++ b/misc/comm.c
@@ -837,7 +837,7 @@
         stol += msr;    
 	repid = ioctl(fd,TIOCMGET,&mstat);
 	dprintf_comm(stddeb,
-	" ioctl  %d, msr %x at %lx %lx\n",repid,mstat,stol,unknown[act]);
+	" ioctl  %d, msr %x at %p %p\n",repid,mstat,stol,unknown[act]);
 	if ((mstat&TIOCM_CAR)) {*stol |= 0x80;}
 	     else {*stol &=0x7f;}
 	dprintf_comm(stddeb," modem dcd construct %x\n",*stol);
diff --git a/misc/crtdll.c b/misc/crtdll.c
index 7ba7d07..e90db10 100644
--- a/misc/crtdll.c
+++ b/misc/crtdll.c
@@ -1453,3 +1453,13 @@
     wsnprintf32A(buf,buflen,"%d",x);
     return buf;
 }
+
+typedef VOID (*sig_handler_type)(VOID);
+
+/*********************************************************************
+ *                  signal           (CRTDLL.455)
+ */
+VOID __cdecl CRTDLL_signal(int sig, sig_handler_type ptr)
+{
+    dprintf_crtdll(stddeb,"CRTDLL_signal %d %p: STUB!\n",sig,ptr);
+}
diff --git a/misc/lzexpand.c b/misc/lzexpand.c
index ba2b02d..1754d62 100644
--- a/misc/lzexpand.c
+++ b/misc/lzexpand.c
@@ -478,7 +478,7 @@
 	LONG	len;
 #define BUFLEN	1000
 	BYTE	buf[BUFLEN];
-	INT32	(*xread)(HFILE32,LPVOID,UINT32);
+	INT32	WINAPI (*xread)(HFILE32,LPVOID,UINT32);
 
 	dprintf_file(stddeb,"LZCopy(%d,%d)\n",src,dest);
 	for (i=0;i<nroflzstates;i++)
diff --git a/misc/main.c b/misc/main.c
index c158941..d267e0a 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -197,7 +197,7 @@
 
 /* Default version is the same as -winver win31 */
 static LONG getVersion16 = MAKELONG( WINVERSION, 0x0616 ); /* DOS 6.22 */
-static LONG getVersion32 = MAKELONG( 4, 0x1606 ); /* DOS 6.22 */
+static LONG getVersion32 = MAKELONG( WINVERSION, 0x8000 );
 static OSVERSIONINFO32A getVersionEx = { sizeof(OSVERSIONINFO32A), 3, 10, 0,
                                          VER_PLATFORM_WIN32s, "Win32s 1.3" };
 
@@ -824,7 +824,7 @@
 
 
 /***********************************************************************
- *      GetVersion32
+ *      GetVersion32   (KERNEL32.427)
  */
 LONG WINAPI GetVersion32(void)
 {
@@ -908,100 +908,6 @@
 }
 
 /***********************************************************************
- *          SetEnvironment   (GDI.132)
- */
-INT16 WINAPI SetEnvironment(LPCSTR lpPortName, LPCSTR lpEnviron, UINT16 nCount)
-{
-    LPENVENTRY	lpNewEnv;
-    LPENVENTRY	lpEnv = lpEnvList;
-    dprintf_env(stddeb, "SetEnvironment('%s', '%s', %d) !\n", 
-		lpPortName, lpEnviron, nCount);
-    if (lpPortName == NULL) return -1;
-    while (lpEnv != NULL) {
-	if (lpEnv->Name != NULL && strcmp(lpEnv->Name, lpPortName) == 0) {
-	    if (nCount == 0 || lpEnviron == NULL) {
-		if (lpEnv->Prev != NULL) lpEnv->Prev->Next = lpEnv->Next;
-		if (lpEnv->Next != NULL) lpEnv->Next->Prev = lpEnv->Prev;
-		free(lpEnv->Value);
-		free(lpEnv->Name);
-		free(lpEnv);
-		dprintf_env(stddeb, "SetEnvironment() // entry deleted !\n");
-		return -1;
-	    }
-	    free(lpEnv->Value);
-	    lpEnv->Value = malloc(nCount);
-	    if (lpEnv->Value == NULL) {
-		dprintf_env(stddeb, "SetEnvironment() // Error allocating entry value !\n");
-		return 0;
-	    }
-	    memcpy(lpEnv->Value, lpEnviron, nCount);
-	    lpEnv->wSize = nCount;
-	    dprintf_env(stddeb, "SetEnvironment() // entry modified !\n");
-	    return nCount;
-	}
-	if (lpEnv->Next == NULL) break;
-	lpEnv = lpEnv->Next;
-    }
-    if (nCount == 0 || lpEnviron == NULL) return -1;
-    dprintf_env(stddeb, "SetEnvironment() // new entry !\n");
-    lpNewEnv = malloc(sizeof(ENVENTRY));
-    if (lpNewEnv == NULL) {
-	dprintf_env(stddeb, "SetEnvironment() // Error allocating new entry !\n");
-	return 0;
-    }
-    if (lpEnvList == NULL) {
-	lpEnvList = lpNewEnv;
-	lpNewEnv->Prev = NULL;
-    }
-    else 
-    {
-	lpEnv->Next = lpNewEnv;
-	lpNewEnv->Prev = lpEnv;
-    }
-    lpNewEnv->Next = NULL;
-    lpNewEnv->Name = malloc(strlen(lpPortName) + 1);
-    if (lpNewEnv->Name == NULL) {
-	dprintf_env(stddeb, "SetEnvironment() // Error allocating entry name !\n");
-	return 0;
-    }
-    strcpy(lpNewEnv->Name, lpPortName);
-    lpNewEnv->Value = malloc(nCount);
-    if (lpNewEnv->Value == NULL) {
-	dprintf_env(stddeb, "SetEnvironment() // Error allocating entry value !\n");
-	return 0;
-    }
-    memcpy(lpNewEnv->Value, lpEnviron, nCount);
-    lpNewEnv->wSize = nCount;
-    return nCount;
-}
-
-
-/***********************************************************************
- *           GetEnvironment   (GDI.134)
- */
-INT16 WINAPI GetEnvironment(LPCSTR lpPortName, LPSTR lpEnviron, UINT16 nMaxSiz)
-{
-    WORD       nCount;
-    LPENVENTRY lpEnv = lpEnvList;
-
-    dprintf_env(stddeb, "GetEnvironment('%s', '%s', %d) !\n",
-		lpPortName, lpEnviron, nMaxSiz);
-    while (lpEnv != NULL) {
-	if (lpEnv->Name != NULL && strcmp(lpEnv->Name, lpPortName) == 0) {
-	    if( lpEnviron == NULL ) return lpEnv->wSize;
-	    nCount = MIN(nMaxSiz, lpEnv->wSize);
-            memcpy(lpEnviron, lpEnv->Value, nCount);
-	    dprintf_env(stddeb, "GetEnvironment() // found '%s' !\n", lpEnv->Value);
-	    return nCount;
-	}
-	lpEnv = lpEnv->Next;
-    }
-    dprintf_env(stddeb, "GetEnvironment() // not found !\n");
-    return 0;
-}
-
-
-/***********************************************************************
  *	GetTimerResolution (USER.14)
  */
 LONG WINAPI GetTimerResolution(void)
diff --git a/misc/ole2nls.c b/misc/ole2nls.c
index 5fd924e..e89c0c6 100644
--- a/misc/ole2nls.c
+++ b/misc/ole2nls.c
@@ -2074,8 +2074,8 @@
 	if (!dstlen || !dststr) {
 		dststr = srcstr;
 	}
-	if (!srclen) srclen = strlen(srcstr);
-	if (!dstlen) dstlen = strlen(dststr);
+	if (!srclen) srclen = lstrlen32W(srcstr);
+	if (!dstlen) dstlen = lstrlen32W(dststr);
 	len = dstlen;
 	if (srclen < len)
 		len = srclen;
diff --git a/misc/shell.c b/misc/shell.c
index 63e618a..c701c72 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -46,8 +46,8 @@
 
 #pragma pack(4)
 
-extern HICON16   LoadIconHandler( HGLOBAL16 hResource, BOOL16 bNew );
-extern WORD 	 GetIconID( HGLOBAL16 hResource, DWORD resType );
+extern HICON16   WINAPI LoadIconHandler( HGLOBAL16 hResource, BOOL16 bNew );
+extern WORD 	 WINAPI GetIconID( HGLOBAL16 hResource, DWORD resType );
 
 static const char*	lpstrMsgWndCreated = "OTHERWINDOWCREATED";
 static const char*	lpstrMsgWndDestroyed = "OTHERWINDOWDESTROYED";
@@ -935,6 +935,12 @@
     return CallNextHookEx16( WH_SHELL, code, wParam, lParam );
 }
 
+LRESULT WINAPI FUNC004(INT16 code, WPARAM16 wParam, LPARAM lParam)
+{
+	fprintf(stderr,"FUNC004(%d,%d,%ld),STUB!\n",code,wParam,lParam);
+	return ShellHookProc(code,wParam,lParam);
+}
+
 /*************************************************************************
  *				RegisterShellHook	[SHELL.102]
  */
diff --git a/misc/spy.c b/misc/spy.c
index 56cebfe..4524f3e 100644
--- a/misc/spy.c
+++ b/misc/spy.c
@@ -765,6 +765,8 @@
     int i;
     char buffer[1024];
 
+    if (!debugging_message) return TRUE;
+
     PROFILE_GetWineIniString( "Spy", "Include", "", buffer, sizeof(buffer) );
     if (buffer[0] && strcmp( buffer, "INCLUDEALL" ))
     {
diff --git a/misc/winsock.c b/misc/winsock.c
index bec016c..c4d8d3d 100644
--- a/misc/winsock.c
+++ b/misc/winsock.c
@@ -43,6 +43,7 @@
 #include "stddebug.h"
 #include "debug.h"
 
+#define DEBUG_SOCKADDR 0
 #define dump_sockaddr(a) \
         fprintf(stderr, "sockaddr_in: family %d, address %s, port %d\n", \
                         ((struct sockaddr_in *)a)->sin_family, \
@@ -147,16 +148,16 @@
     return NULL;
 }
 
-static void fd_set_normalize(fd_set* fds, LPWSINFO pwsi, ws_fd_set* ws, int* highfd)
+static fd_set* fd_set_import( fd_set* fds, LPWSINFO pwsi, ws_fd_set* ws, int* highfd )
 {
-    /* translate Winsock fd set into the normal fd set */
+    /* translate Winsock fd set into local fd set */
 
-    FD_ZERO(fds);
     if( ws ) 
     { 
 	int 	i;
 	ws_socket*  pws;
 
+	FD_ZERO(fds);
 	for( i = 0; i < (ws->fd_count) ; i++ ) 
 	{
 	    pws = (ws_socket*)WS_HANDLE2PTR(ws->fd_array[i]);
@@ -166,29 +167,28 @@
 		FD_SET(pws->fd, fds); 
 	    }
 	}
+	return fds;
     }
+    return NULL;
 }
 
-/*
- * Note weirdness here: sockets with errors belong in exceptfds, but
- * are given to us in readfds or writefds, so move them to exceptfds if
- * there is an error. Note that this means that exceptfds may have mysterious
- * sockets set in it that the program never asked for.
- */
-
 __inline__ static int sock_error_p(int s)
 {
     unsigned int optval, optlen;
 
     optlen = sizeof(optval);
     getsockopt(s, SOL_SOCKET, SO_ERROR, &optval, &optlen);
-    if (optval) dprintf_winsock(stddeb, "error: %d\n", optval);
+    if (optval) dprintf_winsock(stddeb, "\t[%i] error: %d\n", s, optval);
     return optval != 0;
 }
 
-static void fd_set_update(LPWSINFO pwsi, fd_set* fds, ws_fd_set* ws,
-			  fd_set *errorfds)
+static int fd_set_export( LPWSINFO pwsi, fd_set* fds, fd_set* exceptfds, ws_fd_set* ws )
 {
+    int num_err = 0;
+
+    /* translate local fd set into Winsock fd set, adding
+     * errors to exceptfds (only if app requested it) */
+
     if( ws )
     {
 	int i, j, count = ws->fd_count;
@@ -200,9 +200,11 @@
 
 	    if( _check_ws(pwsi, pws) && FD_ISSET(fd, fds) )
 	    {
-		/* if error, move to errorfds */
-		if (errorfds && (FD_ISSET(fd, errorfds) || sock_error_p(fd)))
-		    FD_SET(fd, errorfds);
+		if ( exceptfds && sock_error_p(fd) )
+		{
+		    FD_SET(fd, exceptfds);
+		    num_err++;
+		}
 		else
 		    ws->fd_array[j++] = ws->fd_array[i];
 	    }
@@ -210,7 +212,7 @@
 	ws->fd_count = j;
 	dprintf_winsock(stddeb, "\n");
     }
-    return;
+    return num_err;
 }
 
 HANDLE16 __ws_gethandle( void* ptr )
@@ -520,9 +522,9 @@
 SOCKET16 WINAPI WINSOCK_accept16(SOCKET16 s, struct sockaddr* addr,
                                  INT16* addrlen16 )
 {
-    INT32 addrlen32 = *addrlen16;
+    INT32 addrlen32 = addrlen16 ? *addrlen16 : 0;
     SOCKET32 retSocket = WINSOCK_accept32( s, addr, &addrlen32 );
-   *addrlen16 = (INT16)addrlen32;
+    if( addrlen16 ) *addrlen16 = (INT16)addrlen32;
     return (SOCKET16)retSocket;
 }
 
@@ -536,7 +538,7 @@
 
     dprintf_winsock(stddeb, "WS_BIND(%08x): socket %04x, ptr %8x, length %d\n", 
 			   (unsigned)pwsi, s, (int) name, namelen);
-#if 0
+#if DEBUG_SOCKADDR
     dump_sockaddr(name);
 #endif
 
@@ -614,7 +616,7 @@
 
   dprintf_winsock(stddeb, "WS_CONNECT(%08x): socket %04x, ptr %8x, length %d\n", 
 			   (unsigned)pwsi, s, (int) name, namelen);
-#if 0
+#if DEBUG_SOCKADDR
   dump_sockaddr(name);
 #endif
 
@@ -622,9 +624,13 @@
   {
     if (connect(pws->fd, name, namelen) == 0) 
     { 
-	pws->flags &= ~(WS_FD_INACTIVE | WS_FD_CONNECT);
-	if( pws->psop && pws->flags & WS_FD_CONNECT )
+	if( pws->psop && (pws->flags & WS_FD_CONNECT) )
 	{
+	    /* application did AsyncSelect() but then went
+	     * ahead and called connect() without waiting for 
+	     * notification.
+	     */
+
 	    if( !(pws->flags & WS_FD_CONNECTED) )
 	    {
 		if( pws->flags & (WS_FD_READ | WS_FD_CLOSE) )
@@ -638,6 +644,7 @@
 		pws->flags |= WS_FD_CONNECTED;
 	    }
 	}
+	pws->flags &= ~(WS_FD_INACTIVE | WS_FD_CONNECT);
         return 0; 
     }
     pwsi->err = (errno == EINPROGRESS) ? WSAEWOULDBLOCK : wsaErrno();
@@ -682,7 +689,7 @@
     INT32 namelen32 = *namelen16;
     INT32 retVal = WINSOCK_getpeername32( s, name, &namelen32 );
 
-#if 0
+#if DEBUG_SOCKADDR
     dump_sockaddr(name);
 #endif
 
@@ -716,9 +723,20 @@
 INT16 WINAPI WINSOCK_getsockname16(SOCKET16 s, struct sockaddr *name,
                                    INT16 *namelen16)
 {
-    INT32 namelen32 = *namelen16;
-    INT32 retVal = WINSOCK_getsockname32( s, name, &namelen32 );
-   *namelen16 = namelen32;
+    INT32 retVal;
+
+    if( namelen16 )
+    {
+        INT32 namelen32 = *namelen16;
+        retVal = WINSOCK_getsockname32( s, name, &namelen32 );
+       *namelen16 = namelen32;
+
+#if DEBUG_SOCKADDR
+    dump_sockaddr(name);
+#endif
+
+    }
+    else retVal = SOCKET_ERROR;
     return (INT16)retVal;
 }
 
@@ -750,9 +768,12 @@
 INT16 WINAPI WINSOCK_getsockopt16(SOCKET16 s, INT16 level,
                                   INT16 optname, char *optval, INT16 *optlen)
 {
-    INT32 optlen32 = *optlen;
-    INT32 retVal = WINSOCK_getsockopt32( s, level, optname, optval, &optlen32 );
-   *optlen = optlen32;
+    INT32 optlen32;
+    INT32 *p = &optlen32;
+    INT32 retVal;
+    if( optlen ) optlen32 = *optlen; else p = NULL;
+    retVal = WINSOCK_getsockopt32( s, level, optname, optval, p );
+    if( optlen ) *optlen = optlen32;
     return (INT16)retVal;
 }
 
@@ -883,6 +904,7 @@
 	    int  fd_flags = fcntl(pws->fd, F_GETFL, 0);
 	    if( !(fd_flags & O_NONBLOCK) ) pws->flags |= WS_FD_ACCEPT;
 	}
+	else if( !(pws->flags & WS_FD_CONNECTED) ) pws->flags |= WS_FD_LISTENING;
 
 	if (listen(pws->fd, backlog) == 0) return 0;
 	pwsi->err = wsaErrno();
@@ -949,6 +971,11 @@
 
     dprintf_winsock(stddeb, "WS_RECVFROM(%08x): socket %04x, ptr %08x, len %d, flags %d",
                           (unsigned)pwsi, s, (unsigned)buf, len, flags);
+#if DEBUG_SOCKADDR
+    if( from ) dump_sockaddr(from);
+    else fprintf(stderr, "\tfrom = NULL\n");
+#endif
+
     if( _check_ws(pwsi, pws) )
     {
 	int length;
@@ -975,9 +1002,13 @@
 INT16 WINAPI WINSOCK_recvfrom16(SOCKET16 s, char *buf, INT16 len, INT16 flags,
                                 struct sockaddr *from, INT16 *fromlen16)
 {
-    INT32 fromlen32 = *fromlen16;
-    INT32 retVal = WINSOCK_recvfrom32( s, buf, len, flags, from, &fromlen32 );
-   *fromlen16 = fromlen32;
+    INT32 fromlen32;
+    INT32 *p = &fromlen32;
+    INT32 retVal;
+
+    if( fromlen16 ) fromlen32 = *fromlen16; else p = NULL;
+    retVal = WINSOCK_recvfrom32( s, buf, len, flags, from, p );
+    if( fromlen16 ) *fromlen16 = fromlen32;
     return (INT16)retVal;
 }
 
@@ -988,50 +1019,46 @@
                               ws_fd_set *ws_writefds, ws_fd_set *ws_exceptfds,
                               struct timeval *timeout)
 {
-  LPWSINFO      pwsi = wsi_find(GetCurrentTask());
+    LPWSINFO      pwsi = wsi_find(GetCurrentTask());
 	
-  dprintf_winsock(stddeb, "WS_SELECT(%08x): nfds %d (ignored), read %8x, write %8x, excp %8x\n", 
-  (unsigned) pwsi, nfds, (unsigned) ws_readfds, (unsigned) ws_writefds, (unsigned) ws_exceptfds);
+    dprintf_winsock(stddeb, "WS_SELECT(%08x): nfds %d (ignored), read %8x, write %8x, excp %8x\n", 
+    (unsigned) pwsi, nfds, (unsigned) ws_readfds, (unsigned) ws_writefds, (unsigned) ws_exceptfds);
 
-  if( pwsi )
-  {
-     int         highfd = 0;
-     fd_set      readfds, writefds, exceptfds, errorfds;
+    if( pwsi )
+    {
+	int         highfd = 0;
+	fd_set      readfds, writefds, exceptfds;
+	fd_set     *p_read, *p_write, *p_except;
 
-     fd_set_normalize(&readfds, pwsi, ws_readfds, &highfd);
-     fd_set_normalize(&writefds, pwsi, ws_writefds, &highfd);
-     fd_set_normalize(&exceptfds, pwsi, ws_exceptfds, &highfd);
-     FD_ZERO(&errorfds);
+	p_read = fd_set_import(&readfds, pwsi, ws_readfds, &highfd);
+	p_write = fd_set_import(&writefds, pwsi, ws_writefds, &highfd);
+	p_except = fd_set_import(&exceptfds, pwsi, ws_exceptfds, &highfd);
 
-     if( (highfd = select(highfd + 1, &readfds, &writefds, &exceptfds, timeout)) >= 0 )
-     {
-	  if( highfd )
-	  {
-	    fd_set_update(pwsi, &readfds, ws_readfds, &errorfds);
-	    fd_set_update(pwsi, &writefds, ws_writefds, &errorfds);
-
-	    /* update exception set (see "weirdness" comment in the
-	     * beginning of the file). */
-
-	    if (ws_exceptfds)
+	if( (highfd = select(highfd + 1, p_read, p_write, p_except, timeout)) >= 0 )
+	{
+	    if( highfd )
 	    {
-		int i, j, count = ws_exceptfds->fd_count;
+		fd_set_export(pwsi, &readfds, p_except, ws_readfds);
+		fd_set_export(pwsi, &writefds, p_except, ws_writefds);
 
-		for (i = j = 0; i < count; i++)
+		if (p_except && ws_exceptfds)
 		{
-		    ws_socket *pws = (ws_socket *)WS_HANDLE2PTR(ws_exceptfds->fd_array[i]);
-		    if( _check_ws(pwsi, pws) && 
-			(FD_ISSET(pws->fd, &exceptfds) || FD_ISSET(pws->fd, &errorfds)) )
-			ws_exceptfds->fd_array[j++] = ws_exceptfds->fd_array[i];
+		    int i, j, count = ws_exceptfds->fd_count;
+
+		    for (i = j = 0; i < count; i++)
+		    {
+			ws_socket *pws = (ws_socket *)WS_HANDLE2PTR(ws_exceptfds->fd_array[i]);
+			if( _check_ws(pwsi, pws) && FD_ISSET(pws->fd, &exceptfds) )
+			    ws_exceptfds->fd_array[j++] = ws_exceptfds->fd_array[i];
+		    }
+		    ws_exceptfds->fd_count = j;
 		}
-		ws_exceptfds->fd_count = j;
 	    }
-	  }
-	  return highfd; 
-     }
-     pwsi->err = wsaErrno();
-  } 
-  return SOCKET_ERROR;
+	    return highfd; 
+	}
+        pwsi->err = wsaErrno();
+    } 
+    return SOCKET_ERROR;
 }
 
 /***********************************************************************
@@ -1146,6 +1173,7 @@
                                   char *optval, INT16 optlen)
 {
     INT32 linger32[2];
+    if( !optval ) return SOCKET_ERROR;
     if( optname == SO_LINGER )
     {
 	INT16* ptr = (INT16*)optval;
@@ -1195,7 +1223,7 @@
 	{
 	    if( how > 1 ) 
 	    {
-		pws->flags &= ~WS_FD_CONNECTED;
+		pws->flags &= ~(WS_FD_CONNECTED | WS_FD_LISTENING);
 		pws->flags |= WS_FD_INACTIVE;
 	    }
 	    return 0;
@@ -1780,10 +1808,14 @@
 
 	    num_pending--;
 
-	    if( flags & WS_FD_ACCEPT )
-	    {
-		/* listening socket */
+	    /* Now figure out what kind of event we've got. The worst problem
+	     * we have to contend with is that some out of control applications 
+	     * really want to use mutually exclusive AsyncSelect() flags all at
+	     * the same time.
+	     */
 
+	    if((flags & WS_FD_ACCEPT) && (flags & WS_FD_LISTENING))
+	    {
 		FD_CLR( fd, &io_set[EVENT_IO_WRITE] );
 		if( r )
 		{
@@ -1807,8 +1839,12 @@
 
 		    if( flags & (WS_FD_READ | WS_FD_CLOSE))
 			FD_SET( fd, &io_set[EVENT_IO_READ] );
-		    if( flags & WS_FD_WRITE ) FD_SET( fd, &io_set[EVENT_IO_WRITE] );
-		    else FD_CLR( fd, &io_set[EVENT_IO_WRITE] );
+		    else 
+			FD_CLR( fd, &io_set[EVENT_IO_READ] );
+		    if( flags & WS_FD_WRITE ) 
+			FD_SET( fd, &io_set[EVENT_IO_WRITE] );
+		    else 
+			FD_CLR( fd, &io_set[EVENT_IO_WRITE] );
 		    bPost = TRUE;
 		}
 		else if( r )
@@ -1838,6 +1874,8 @@
 		    if( PostMessage16( psop->hWnd, psop->uMsg, (WPARAM16)WS_PTR2HANDLE(psop->pws), 
 			              (LPARAM)WSAMAKESELECTREPLY( WS_FD_WRITE, 0 ) ) )
 		    {
+			dprintf_winsock(stddeb, "\t    hwnd %04x - %04x, %08x\n",
+                                psop->hWnd, psop->uMsg, (unsigned)MAKELONG(WS_FD_WRITE, 0) );
 			FD_CLR( fd, &io_set[EVENT_IO_WRITE] );
 			num_posted++;
 		    }
@@ -1898,6 +1936,8 @@
 
 	    if( bPost )
 	    {
+		dprintf_winsock(stddeb, "\t    hwnd %04x - %04x, %08x\n", 
+				psop->hWnd, psop->uMsg, (unsigned)dwEvent );
 		PostMessage16( psop->hWnd, psop->uMsg, 
 			      (WPARAM16)WS_PTR2HANDLE(psop->pws), (LPARAM)dwEvent );
 		bPost = FALSE;
@@ -2053,7 +2093,8 @@
 
   dprintf_winsock(stddeb, "WS_SetBlockingHook16(%08x): hook %08x\n", 
 			  (unsigned)pwsi, (unsigned) lpBlockFunc);
-  if( pwsi ) { 
+  if( pwsi ) 
+  { 
       prev = (FARPROC16)pwsi->blocking_hook; 
       pwsi->blocking_hook = (DWORD)lpBlockFunc; 
       pwsi->flags &= ~WSI_BLOCKINGHOOK32;
diff --git a/misc/winsock_dns.c b/misc/winsock_dns.c
index 8042489..173f6bb 100644
--- a/misc/winsock_dns.c
+++ b/misc/winsock_dns.c
@@ -167,7 +167,9 @@
       ws_async_op*	p = __async_op_list;
       __async_op_list->prev = p_aop;
 
-      /* traverse the list and reap dead ops */
+      /* traverse the list and retire dead ops created
+       * by the signal handler (see below). */
+
       while( p )
       {
 	  if( p->flags & WSMSG_DEAD_AOP )
@@ -213,7 +215,7 @@
  * link_async_op/unlink_async_op allow to install generic
  * async IO handlers (provided that aop_control function is defined).
  *
- * Note: AsyncGetXbyY expilicitly raise it.
+ * Note: pipe-based handlers must raise explicit SIGIO with kill(2).
  */
 
 void WINSOCK_sigio(int signal)
@@ -233,7 +235,11 @@
       if( FD_ISSET(p_aop->fd[0], &check_set) )
           if( p_aop->aop_control(p_aop, AOP_IO) == AOP_CONTROL_REMOVE )
 	  {
-	      p_aop->flags = WSMSG_DEAD_AOP;  /* can't free inside the signal */
+	     /* NOTE: memory management is signal-unsafe, therefore
+	      * we can only set a flag to remove this p_aop later on.
+	      */
+
+	      p_aop->flags = WSMSG_DEAD_AOP;
 	      close(p_aop->fd[0]);
 	      FD_CLR(p_aop->fd[0],&__async_io_fdset);
 	      if( p_aop->fd[0] == __async_io_max_fd )
diff --git a/msdos/dpmi.c b/msdos/dpmi.c
index ae7a852..189a99b 100644
--- a/msdos/dpmi.c
+++ b/msdos/dpmi.c
@@ -381,8 +381,9 @@
             break;
         }
     case 0x0501:  /* Allocate memory block */
-        if (!(ptr = (BYTE *)HeapAlloc( SystemHeap, 0,MAKELONG( CX_reg(context),
-                                                           BX_reg(context) ))))
+        if (!(ptr = (BYTE *)HeapAlloc( GetProcessHeap(), 0,
+                                       MAKELONG( CX_reg(context),
+                                                 BX_reg(context) ))))
         {
             AX_reg(context) = 0x8012;  /* linear memory not available */
             SET_CFLAG(context);
@@ -395,12 +396,12 @@
         break;
 
     case 0x0502:  /* Free memory block */
-        HeapFree( SystemHeap, 0,
+        HeapFree( GetProcessHeap(), 0,
                   (void *)MAKELONG( DI_reg(context), SI_reg(context) ) );
         break;
 
     case 0x0503:  /* Resize memory block */
-        if (!(ptr = (BYTE *)HeapReAlloc( SystemHeap, 0,
+        if (!(ptr = (BYTE *)HeapReAlloc( GetProcessHeap(), 0,
                            (void *)MAKELONG(DI_reg(context),SI_reg(context)),
                                    MAKELONG(CX_reg(context),BX_reg(context)))))
         {
diff --git a/msdos/int21.c b/msdos/int21.c
index 8bcb950..94ab5ed 100644
--- a/msdos/int21.c
+++ b/msdos/int21.c
@@ -677,7 +677,8 @@
     drive = DOS_GET_DRIVE( pFCB->drive );
     root = DRIVE_GetRoot( drive );
     cwd  = DRIVE_GetUnixCwd( drive );
-    pFCB->unixPath = HeapAlloc( SystemHeap, 0, strlen(root)+strlen(cwd)+2 );
+    pFCB->unixPath = HeapAlloc( GetProcessHeap(), 0,
+                                strlen(root)+strlen(cwd)+2 );
     if (!pFCB->unixPath) return 0;
     strcpy( pFCB->unixPath, root );
     strcat( pFCB->unixPath, "/" );
@@ -712,7 +713,7 @@
                                   DOS_GET_DRIVE( pFCB->drive ), attr,
                                   pFCB->count, &entry )))
     {
-        HeapFree( SystemHeap, 0, pFCB->unixPath );
+        HeapFree( GetProcessHeap(), 0, pFCB->unixPath );
         pFCB->unixPath = NULL;
         return 0;
     }
@@ -959,7 +960,8 @@
         break;
             
     case 0x30: /* GET DOS VERSION */
-        AX_reg(context) = HIWORD(GetVersion16());
+        AX_reg(context) = (HIWORD(GetVersion16()) >> 8) |
+                          (HIWORD(GetVersion16()) << 8);
         BX_reg(context) = 0x0012;     /* 0x123456 is Wine's serial # */
         CX_reg(context) = 0x3456;
         break;
@@ -992,7 +994,8 @@
 		break;
 				
 	      case 0x06: /* GET TRUE VERSION NUMBER */
-		BX_reg(context) = HIWORD(GetVersion16());
+		BX_reg(context) = (HIWORD(GetVersion16() >> 8)) |
+                                  (HIWORD(GetVersion16() << 8));
 		DX_reg(context) = 0x00;
 		break;
 
diff --git a/msdos/vxd.c b/msdos/vxd.c
index dc51e79..643967f 100644
--- a/msdos/vxd.c
+++ b/msdos/vxd.c
@@ -24,7 +24,7 @@
 
 static WORD VXD_WinVersion(void)
 {
-    WORD version = GetVersion16();
+    WORD version = LOWORD(GetVersion16());
     return (version >> 8) | (version << 8);
 }
 
diff --git a/multimedia/mmsystem.c b/multimedia/mmsystem.c
index 06b9743..0b56fb3 100644
--- a/multimedia/mmsystem.c
+++ b/multimedia/mmsystem.c
@@ -106,6 +106,36 @@
 }
 
 /**************************************************************************
+* 				PlaySoundA		[WINMM.1]
+*/
+BOOL32 WINAPI PlaySound32A(LPCSTR pszSound, HMODULE32 hmod, DWORD fdwSound)
+{
+  dprintf_mmsys(stddeb, "PlaySoundA: pszSound='%s' hmod=%04X fdwSound=%08lX\n",
+		pszSound, hmod, fdwSound);
+  if(hmod != 0 || !(fdwSound & SND_FILENAME)) {
+    fprintf(stderr, "PlaySoundA: only disk sound files are supported\n");
+    return FALSE;
+  } else {
+    BOOL16 bSound;
+    bSound = sndPlaySound(pszSound, (UINT16) fdwSound);
+    return (BOOL32) bSound;
+  }
+}
+
+/**************************************************************************
+* 				PlaySoundW		[WINMM.18]
+*/
+BOOL32 WINAPI PlaySound32W(LPCWSTR pszSound, HMODULE32 hmod, DWORD fdwSound)
+{
+  LPSTR pszSoundA = xmalloc((lstrlen32W(pszSound)+1)*sizeof(WCHAR));
+  BOOL32 bSound;
+  lstrcpyWtoA(pszSoundA, pszSound);
+  bSound = PlaySound32A(pszSoundA, hmod, fdwSound);
+  free(pszSoundA);
+  return bSound;
+}
+
+/**************************************************************************
 * 				sndPlaySound		[MMSYSTEM.2]
 */
 BOOL16 WINAPI sndPlaySound(LPCSTR lpszSoundName, UINT16 uFlags)
@@ -2278,16 +2308,31 @@
 }
 
 /**************************************************************************
-* 				mmioInstallIOProc	[MMSYSTEM.1221]
+* 				mmioInstallIOProc16	[MMSYSTEM.1221]
 */
-LPMMIOPROC WINAPI mmioInstallIOProc(FOURCC fccIOProc, 
-                                    LPMMIOPROC pIOProc, DWORD dwFlags)
+LPMMIOPROC16 WINAPI mmioInstallIOProc16(FOURCC fccIOProc, 
+                                        LPMMIOPROC16 pIOProc, DWORD dwFlags)
 {
 	dprintf_mmio(stddeb, "mmioInstallIOProc // empty stub \n");
 	return 0;
 }
 
 /**************************************************************************
+ * 				mmioInstallIOProc32A   [WINMM.120]
+ */
+LPMMIOPROC32 WINAPI mmioInstallIOProc32A(FOURCC fccIOProc, 
+                                         LPMMIOPROC32 pIOProc, DWORD dwFlags)
+{
+	dprintf_mmio(stddeb, "mmioInstallIOProcA (%c%c%c%c,%p,0x%08lx)// empty stub \n",
+                     (char)((fccIOProc&0xff000000)>>24),
+                     (char)((fccIOProc&0x00ff0000)>>16),
+                     (char)((fccIOProc&0x0000ff00)>> 8),
+                     (char)(fccIOProc&0x000000ff),
+                     pIOProc, dwFlags );
+	return 0;
+}
+
+/**************************************************************************
 * 				mmioSendMessage		[MMSYSTEM.1222]
 */
 LRESULT WINAPI mmioSendMessage(HMMIO16 hmmio, UINT16 uMessage,
diff --git a/objects/font.c b/objects/font.c
index 941881a..5404d2a 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -872,7 +872,7 @@
 
     if( firstChar != lastChar )
     {
-	LPINT32	buf32 = (LPINT32)HeapAlloc(SystemHeap, 0,
+	LPINT32	buf32 = (LPINT32)HeapAlloc(GetProcessHeap(), 0,
 				 sizeof(INT32)*(1 + (lastChar - firstChar)));
 	if( buf32 )
 	{
@@ -885,7 +885,7 @@
 		for (i = firstChar; i <= lastChar; i++)
 		    *buffer++ = *buf32++;
 	    }
-	    HeapFree(SystemHeap, 0, obuf32);
+	    HeapFree(GetProcessHeap(), 0, obuf32);
 	}
     }
     else /* happens quite often to warrant a special treatment */
diff --git a/programs/progman/Makefile.in b/programs/progman/Makefile.in
index a5d86f6..a09f86d 100644
--- a/programs/progman/Makefile.in
+++ b/programs/progman/Makefile.in
@@ -6,7 +6,7 @@
 PROGRAMS  = progman
 ALL_LIBS  = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LDLIBS)
 DEFS      = -I$(SRCDIR)
-RCFLAGS   = -w32
+RCFLAGS   = -w32 -h
 
 LANGUAGES   = En Da De Fr Fi Ko Hu It Va
 LICENSELANG = En
@@ -37,17 +37,19 @@
 	string.c \
 	$(LICENSELANG:%=License_%.c)
 
-GEN_C_SRCS = \
-	accel.c \
-	$(LANGUAGES:%=%.c) \
+RC_SRCS = \
+	accel.rc \
+	$(LANGUAGES:%=%.rc)
 
 C_SRCS = $(MOSTSRCS) $(STRINGSRCS)
 
 MOSTOBJS = $(MOSTSRCS:.c=.o)
-STRINGOBJS = $(STRINGSRCS:.c=.o) $(GEN_C_SRCS:.c=.o)
+STRINGOBJS = $(STRINGSRCS:.c=.o) $(RC_SRCS:.rc=.o)
 
 all: check_winerc $(PROGRAMS)
 
+depend:: $(RC_SRCS:.rc=.h)
+
 @MAKE_RULES@
 
 progman: $(MOSTOBJS) $(STRINGOBJS)
@@ -56,9 +58,7 @@
 install: dummy
 	$(INSTALL_PROGRAM) progman $(bindir)/progman
 
-accel.c accel.h: $(WINERC) Xx.rc
-
-$(LANGUAGES:%=%.c) $(LANGUAGES:%=%.h): $(WINERC) Xx.rc
+$(RC_SRCS:.rc=.c) $(RC_SRCS:.rc=.h): $(WINERC)
 
 dummy:
 
diff --git a/programs/winhelp/Makefile.in b/programs/winhelp/Makefile.in
index 717dfe1..22b605a 100644
--- a/programs/winhelp/Makefile.in
+++ b/programs/winhelp/Makefile.in
@@ -5,7 +5,7 @@
 MODULE    = none
 PROGRAMS  = winhelp hlp2sgml
 ALL_LIBS  = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LDLIBS)
-RCFLAGS   = -w32
+RCFLAGS   = -w32 -h
 
 LANGUAGES   = En Da De Fr Fi Ko Hu It Va
 
@@ -28,21 +28,22 @@
 	macro.c
 
 # Some strings need addresses >= 0x10000
-STRINGSRCS = \
-	string.c
+STRINGSRCS = string.c
 
-GEN_C_SRCS = \
-	y.tab.c \
-	lex.yy.c \
-	$(LANGUAGES:%=%.c)
+EXTRA_SRCS = macro.yacc.y macro.lex.l
+EXTRA_OBJS = y.tab.o lex.yy.o
+
+RC_SRCS = $(LANGUAGES:%=%.rc)
 
 C_SRCS = $(MOSTSRCS) $(STRINGSRCS)
 
 MOSTOBJS = $(MOSTSRCS:.c=.o)
-STRINGOBJS = $(STRINGSRCS:.c=.o) $(GEN_C_SRCS:.c=.o)
+STRINGOBJS = $(STRINGSRCS:.c=.o) $(RC_SRCS:.rc=.o)
 
 all: check_winerc $(PROGRAMS)
 
+depend:: $(RC_SRCS:.rc=.h) y.tab.h
+
 @MAKE_RULES@
 
 # Some strings need addresses >= 0x10000
@@ -62,7 +63,7 @@
 lex.yy.c: macro.lex.l
 	$(LEX) -8 -i $(SRCDIR)/macro.lex.l
 
-$(LANGUAGES:%=%.c) $(LANGUAGES:%=%.h): $(WINERC) Xx.rc
+$(RC_SRCS:.rc=.c) $(RC_SRCS:.rc=.h): $(WINERC)
 
 dummy:
 
diff --git a/rc/Makefile.in b/rc/Makefile.in
index 55c6b9e..13306f8 100644
--- a/rc/Makefile.in
+++ b/rc/Makefile.in
@@ -7,10 +7,13 @@
 MODULE    = none
 
 C_SRCS     = winerc.c
-GEN_C_SRCS = y.tab.c lex.yy.c
+EXTRA_SRCS = parser.y parser.l
+EXTRA_OBJS = y.tab.o lex.yy.o
 
 all: $(PROGRAMS)
 
+depend:: y.tab.h
+
 @MAKE_RULES@
 
 $(PROGRAMS): $(OBJS)
diff --git a/rc/winerc.c b/rc/winerc.c
index 66f7efe..ea8aa65 100644
--- a/rc/winerc.c
+++ b/rc/winerc.c
@@ -19,6 +19,7 @@
 	"   -b            Create a C array from a binary .res file\n"
         "   -c            Add 'const' prefix to C constants\n"
 	"   -d            Output debugging information\n"
+        "   -h            Also generate a .h file\n"
 	"   -p prefix     Give a prefix for the generated names\n"
 	"   -v            Show each resource as it is processed\n"
 	"   -o file       Output to file.c and file.h\n"
@@ -29,8 +30,7 @@
 int win32=1;
 int verbose,constant;
 gen_res* g_start;
-FILE *header,*code;
-char hname[256],sname[256];
+static FILE *header = NULL, *code = NULL;
 
 int transform_binary_file(void);
 int yyparse(void);
@@ -53,9 +53,10 @@
 {  
 	extern int yydebug;
 	extern char* optarg;
-	int optc,lose,ret,binary;
-	lose=binary=0;
-	while((optc=getopt(argc,argv,"bcdp:vo:w:"))!=EOF)
+	int optc,lose = 0, ret, binary = 0, output_header = 0;
+        char output_name[256];
+
+	while((optc=getopt(argc,argv,"bcdhp:vo:w:"))!=EOF)
 		switch(optc)
 		{
 			/* bison will print state transitions on stderr */
@@ -65,12 +66,13 @@
 					 setbuf(stdout,0);
 					 setbuf(stderr,0);
 					break;
+                        case 'h':output_header=1; break;
 			case 'p':prefix=strdup(optarg); break;
 			case 'c':constant=1;break;
 			case 'v':verbose=1;
 					 setbuf(stderr,0);
 					break;
-			case 'o':set_out_file(optarg);break;
+			case 'o':sprintf(output_name,"%s.c",optarg); break;
 			case 'w':if(!strcmp(optarg,"16"))win32=0;
 				 else if(!strcmp(optarg,"32"))win32=1;
 				 else lose++;
@@ -78,29 +80,30 @@
 			default: lose++;break;
 		}
 	if(lose)return fprintf(stderr,usage),1;
-	if(!header)header=stdout;
-	if(!code)code=stdout;
+
+        if (output_name[0])
+        {
+            code = fopen( output_name, "w" );
+            if (output_header)
+            {
+                output_name[strlen(output_name)-1] = 'h';
+                header = fopen( output_name, "w" );
+            }
+        }
+        if (!code) code = stdout;
 	if(binary)
 		ret=transform_binary_file();
 	else
 		ret=yyparse();
-	fclose(header);
+	if (header) fclose(header);
 	fclose(code);
 	return ret;
 }
 
-void set_out_file(char *prefix)
-{
-	sprintf(sname,"%s.c",prefix);
-	code=fopen(sname,"w");
-	sprintf(hname,"%s.h",prefix);
-	header=fopen(hname,"w");
-}
-
 int transform_binary_file()
 {
 	int i,c;
-	fprintf(header,"#define APPLICATION_HAS_RESOURCES 1\n");
+	if (header) fprintf(header,"#define APPLICATION_HAS_RESOURCES 1\n");
 	fprintf(code,"char _Application_resources[]={");
 	for(i=0;;i++)
 	{
@@ -767,25 +770,40 @@
 
     top=add_string_table(top);
 
-    fprintf( header, "/* %s\n"
-                     " * This file is automatically generated. Do not edit!\n"
-                     " */\n\n"
-                     "#include \"resource.h\"\n", hname );
+    /* Generate the header */
 
-    /* Declare the resources */
+    if (header)
+    {
+        fprintf( header,
+                 "/*\n"
+                 " * This file is automatically generated. Do not edit!\n"
+                 " */\n\n"
+                 "#ifndef __%s_H\n"
+                 "#define __%s_H\n\n"
+                 "struct resource;\n\n",
+                 prefix, prefix );
 
-    for (it=top;it;it=it->next)
-        fprintf( header,"extern %sstruct resource %s;\n",
-                 ISCONSTANT, get_resource_name(it) );
-    fprintf( header,"\nextern %sstruct resource * %s%s_Table[];\n",
-             ISCONSTANT, ISCONSTANT, prefix );
+        /* Declare the resources */
+        for (it=top;it;it=it->next)
+            fprintf( header,"extern %sstruct resource %s;\n",
+                     ISCONSTANT, get_resource_name(it) );
+        fprintf( header,"\nextern %sstruct resource * %s%s_Table[];\n\n",
+                 ISCONSTANT, ISCONSTANT, prefix );
+        fprintf( header, "#endif  /* __%s_H */\n", prefix );
+    }
 
     /* Print the resources bytes */
 
-    fprintf( code, "/* %s\n"
+    fprintf( code, "/*\n"
                    " * This file is automatically generated. Do not edit!\n"
                    " */\n\n"
-                   "#include \"%s\"\n", sname, hname );
+                   "struct resource {\n"
+                   "\tint id;\n"
+                   "\tint type;\n"
+                   "\tconst char *name;\n"
+                   "\tconst unsigned char* bytes;\n"
+                   "\tunsigned size;\n"
+                   "};\n\n" );
 
     for(it=top;it;it=it->next)
     {
@@ -867,23 +885,24 @@
 	    ISCONSTANT, ISCONSTANT, prefix);
     for (it=top;it;it=it->next)
         fprintf( code, "  &%s,\n", get_resource_name(it) );
-    fprintf( code, "  0\n};\n" );
+    fprintf( code, "  0\n};\n\n\n" );
 
-        /* Perform autoregistration */
-        fprintf( code, 
-                "#ifdef WINELIB\n"
-                "static void DoIt() WINE_CONSTRUCTOR;\n"
-                "static void DoIt()\n"
-                "{\n"
-                "\tLIBRES_RegisterResources(%s_Table);\n"
-                "}\n\n"
-                "#ifndef HAVE_WINE_CONSTRUCTOR\n"
-                "void LIBWINE_Register_%s(){\n"
-                "\tDoIt();\n"
-                "}\n"
-                "#endif\n"
-                "#endif /*WINELIB*/\n"
-                ,prefix,prefix);
+    /* Perform autoregistration */
+    fprintf( code, 
+             "#ifndef __WINE__\n"
+             "#if defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ >= 7)\n"
+             "static void DoIt(void) __attribute__((constructor));\n"
+             "#else\n"
+             "static void DoIt(void);\n"
+             "void LIBWINE_Register_%s(void) { DoIt(); }\n"
+             "#endif\n"
+             "static void DoIt(void)\n"
+             "{\n"
+             "\textern void LIBRES_RegisterResources(const struct resource* const * Res);\n"
+             "\tLIBRES_RegisterResources(%s_Table);\n"
+             "}\n\n"
+             "#endif /* __WINE__ */\n"
+             ,prefix,prefix);
 }
 
 gen_res* make_font(gen_res* res)
diff --git a/resources/Makefile.in b/resources/Makefile.in
index 1d3755c..43012e5 100644
--- a/resources/Makefile.in
+++ b/resources/Makefile.in
@@ -6,29 +6,28 @@
 MODULE    = resources
 RCFLAGS   = -w32
 
-SYSRES_SRCS = \
-	sysres_Cz.c \
-	sysres_Da.c \
-	sysres_De.c \
-	sysres_En.c \
-	sysres_Eo.c \
-	sysres_Es.c \
-	sysres_Fi.c \
-	sysres_Fr.c \
-	sysres_Hu.c \
-	sysres_It.c \
-	sysres_Ko.c \
-	sysres_No.c \
-	sysres_Pl.c \
-	sysres_Po.c
+RC_SRCS = \
+	sysres_Cz.rc \
+	sysres_Da.rc \
+	sysres_De.rc \
+	sysres_En.rc \
+	sysres_Eo.rc \
+	sysres_Es.rc \
+	sysres_Fi.rc \
+	sysres_Fr.rc \
+	sysres_Hu.rc \
+	sysres_It.rc \
+	sysres_Ko.rc \
+	sysres_No.rc \
+	sysres_Pl.rc \
+	sysres_Po.rc
 
 C_SRCS = sysres.c
-GEN_C_SRCS = $(SYSRES_SRCS)
 
 all: check_winerc $(MODULE).o
 
 @MAKE_RULES@
 
-$(SYSRES_SRCS): $(WINERC)
+$(RC_SRCS:.rc=.c): $(WINERC)
 
 ### Dependencies:
diff --git a/resources/sysres.c b/resources/sysres.c
index 36a0ad8..93e1057 100644
--- a/resources/sysres.c
+++ b/resources/sysres.c
@@ -9,20 +9,20 @@
 #include "options.h"
 #include "resource.h"
 
-#include "sysres_En.h"
-#include "sysres_Es.h"
-#include "sysres_De.h"
-#include "sysres_No.h"
-#include "sysres_Fr.h"
-#include "sysres_Fi.h"
-#include "sysres_Da.h"
-#include "sysres_Cz.h"
-#include "sysres_Eo.h"
-#include "sysres_It.h"
-#include "sysres_Ko.h"
-#include "sysres_Hu.h"
-#include "sysres_Pl.h"
-#include "sysres_Po.h"
+extern const struct resource * const sysres_En_Table[];
+extern const struct resource * const sysres_Es_Table[];
+extern const struct resource * const sysres_De_Table[];
+extern const struct resource * const sysres_No_Table[];
+extern const struct resource * const sysres_Fr_Table[];
+extern const struct resource * const sysres_Fi_Table[];
+extern const struct resource * const sysres_Da_Table[];
+extern const struct resource * const sysres_Cz_Table[];
+extern const struct resource * const sysres_Eo_Table[];
+extern const struct resource * const sysres_It_Table[];
+extern const struct resource * const sysres_Ko_Table[];
+extern const struct resource * const sysres_Hu_Table[];
+extern const struct resource * const sysres_Pl_Table[];
+extern const struct resource * const sysres_Po_Table[];
 
 static const struct resource * const * SYSRES_Resources[] =
 {
diff --git a/scheduler/thread.c b/scheduler/thread.c
index c350aee..990eb76 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -406,3 +406,11 @@
     return TRUE;
 }
 
+/**********************************************************************
+ *           SuspendThread   (KERNEL32)
+ */
+BOOL32 WINAPI SuspendThread(DWORD threadid)
+{
+    fprintf(stdnimp,"SuspendThread(0x%08lx), STUB!\n",threadid);
+    return TRUE;
+}
diff --git a/tools/build.c b/tools/build.c
index 1803272..4dc7962 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -16,6 +16,7 @@
 #include "module.h"
 #include "neexe.h"
 #include "selectors.h"
+#include "stackframe.h"
 
 #ifdef NEED_UNDERSCORE_PREFIX
 # define PREFIX "_"
@@ -148,8 +149,11 @@
 
 static int debugging = 1;
 
+  /* Offset of a structure field relative to the start of the struct */
+#define STRUCTOFFSET(type,field) ((int)&((type *)0)->field)
+
   /* Offset of register relative to the start of the CONTEXT struct */
-#define CONTEXTOFFSET(reg) ((int)&((CONTEXT *)0)->reg)
+#define CONTEXTOFFSET(reg)  STRUCTOFFSET(CONTEXT,reg)
 
 static void *xmalloc (size_t size)
 {
@@ -1414,7 +1418,10 @@
  * functions that need a large stack, like X bitmaps functions.
  *
  * The generated function has the following prototype:
- *   int CALLTO32_LargeStack( int (*func)(), void *arg );
+ *   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:
  *   ...     ...
@@ -1425,27 +1432,35 @@
  */
 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 \"CALLTO32_LargeStack:F1\",36,0,0," PREFIX "CALLTO32_LargeStack\n");
+    fprintf( outfile, ".stabs \"CALL32_LargeStack:F1\",36,0,0,CALL32_LargeStack\n");
 #endif
-    fprintf( outfile, "\t.globl " PREFIX "CALLTO32_LargeStack\n" );
-    fprintf( outfile, PREFIX "CALLTO32_LargeStack:\n" );
+    fprintf( outfile, "CALL32_LargeStack:\n" );
     
     /* Entry code */
 
     fprintf( outfile, "\tpushl %%ebp\n" );
     fprintf( outfile, "\tmovl %%esp,%%ebp\n" );
 
-    /* Retrieve the original 32-bit stack pointer and switch to it if any */
+    /* Switch to the original 32-bit stack pointer */
 
-    fprintf( outfile, "\tmovl " PREFIX "IF1632_Original32_esp, %%eax\n" );
-    fprintf( outfile, "\torl %%eax,%%eax\n" );
-    fprintf( outfile, "\tje no_orig_esp\n" );
-    fprintf( outfile, "\tmovl %%eax,%%esp\n" );
-    fprintf( outfile, "no_orig_esp:\n" );
+    fprintf( outfile, "\tmovl CALL32_Original32_esp, %%esp\n" );
 
     /* Transfer the argument and call the function */
 
@@ -1457,6 +1472,12 @@
     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" );
 }
 
 
@@ -1482,7 +1503,7 @@
 
     /* Get the 32-bit stack pointer */
 
-    fprintf( outfile, "\tmovl " PREFIX "IF1632_Saved32_esp,%%ebx\n" );
+    fprintf( outfile, "\tmovl " PREFIX "CALLTO16_Saved32_esp,%%ebx\n" );
 
     /* Copy the arguments */
 
@@ -1553,7 +1574,7 @@
 
     /* Get the 32-bit stack pointer */
 
-    fprintf( outfile, "\tmovl " PREFIX "IF1632_Saved32_esp,%%ebx\n" );
+    fprintf( outfile, "\tmovl " PREFIX "CALLTO16_Saved32_esp,%%ebx\n" );
 
     /* Store the registers */
 
@@ -1607,17 +1628,18 @@
 /*******************************************************************
  *         RestoreContext16
  *
- * Restore the registers from the context structure
+ * Restore the registers from the context structure.
+ * %edx must point to the 32-bit stack top.
  */
 static void RestoreContext16( FILE *outfile )
 {
     /* Get the 32-bit stack pointer */
 
-    fprintf( outfile, "\tmovl " PREFIX "IF1632_Saved32_esp,%%ebx\n" );
+    fprintf( outfile, "\tmovl %%edx,%%ebx\n" );
 
     /* Remove everything up to the return address from the 16-bit stack */
 
-    fprintf( outfile, "\taddl $18,%%esp\n" );
+    fprintf( outfile, "\taddl $22,%%esp\n" );
 
     /* Restore the registers */
 
@@ -1631,6 +1653,10 @@
              CONTEXTOFFSET(Edi) - sizeof(CONTEXT) );
     fprintf( outfile, "\tmovl %d(%%ebx),%%ebp\n",
              CONTEXTOFFSET(Ebp) - sizeof(CONTEXT) );
+    fprintf( outfile, "\tpushw %d(%%ebx)\n",  /* Push new cs */
+             CONTEXTOFFSET(SegCs) - sizeof(CONTEXT) );
+    fprintf( outfile, "\tpushw %d(%%ebx)\n",  /* Push new ip */
+             CONTEXTOFFSET(Eip) - sizeof(CONTEXT) );
     fprintf( outfile, "\tpushw %d(%%ebx)\n",  /* Push new ds */
              CONTEXTOFFSET(SegDs) - sizeof(CONTEXT) );
     fprintf( outfile, "\tpushw %d(%%ebx)\n",  /* Push new es */
@@ -1749,7 +1775,7 @@
 
     /* Switch to the 32-bit stack */
 
-    fprintf( outfile, "\tmovl " PREFIX "IF1632_Saved32_esp,%%ebp\n" );
+    fprintf( outfile, "\tmovl " PREFIX "CALLTO16_Saved32_esp,%%ebp\n" );
     fprintf( outfile, "\tpushw %%ds\n" );
     fprintf( outfile, "\tpopw %%ss\n" );
     fprintf( outfile, "\tleal -%d(%%ebp),%%esp\n",
@@ -1759,7 +1785,7 @@
 
     /* Setup %ebp to point to the previous stack frame (built by CallTo16) */
 
-    fprintf( outfile, "\taddl $32,%%ebp\n" );
+    fprintf( outfile, "\taddl $%d,%%ebp\n", STRUCTOFFSET(STACK32FRAME,ebp) );
 
     /* Print the debug information before the call */
 
@@ -1797,12 +1823,11 @@
         fprintf( outfile, "\tpopl %%eax\n" );
     }
 
-#if 0
     /* Restore the value of the saved 32-bit stack pointer */
 
-    fprintf( outfile, "\tleal -32(%%ebp),%%edx\n" );
-    fprintf( outfile, "movl %%edx," PREFIX "IF1632_Saved32_esp\n" );
-#endif
+    fprintf( outfile, "\tleal -%d(%%ebp),%%edx\n",
+             STRUCTOFFSET(STACK32FRAME,ebp) );
+    fprintf( outfile, "movl %%edx," PREFIX "CALLTO16_Saved32_esp\n" );
 
     /* Restore the 16-bit stack */
 
@@ -1896,19 +1921,16 @@
  * Prototypes for the CallTo16 functions:
  *   extern WINAPI WORD CallTo16_word_xxx( FARPROC16 func, args... );
  *   extern WINAPI LONG CallTo16_long_xxx( FARPROC16 func, args... );
- *   extern WINAPI LONG CallTo16_wndp_xxx( FARPROC16 func, args... );
  *   extern WINAPI void CallTo16_regs_( const CONTEXT *context );
  */
 static void BuildCallTo16Func( FILE *outfile, char *profile )
 {
-    int window_proc = 0;
     int short_ret = 0;
     int reg_func = 0;
     char *args = profile + 5;
 
     if (!strncmp( "word_", profile, 5 )) short_ret = 1;
-    else if (!strncmp( "regs_", profile, 5 )) reg_func = short_ret = 1;
-    else if (!strncmp( "wndp_", profile, 5 )) window_proc = 1;
+    else if (!strncmp( "regs_", profile, 5 )) reg_func = 1;
     else if (strncmp( "long_", profile, 5 ))
     {
         fprintf( stderr, "Invalid function name '%s', ignored\n", profile );
@@ -1960,8 +1982,7 @@
 
     /* Save the 32-bit stack */
 
-    fprintf( outfile, "\tpushl " PREFIX "IF1632_Saved32_esp\n" );
-    fprintf( outfile, "\tmovl %%esp," PREFIX "IF1632_Saved32_esp\n" );
+    fprintf( outfile, "\tmovl %%esp," PREFIX "CALLTO16_Saved32_esp\n" );
     fprintf( outfile, "\tmovl %%ebp,%%ebx\n" );
 
     /* Print debugging info */
@@ -1969,7 +1990,7 @@
     if (debugging)
     {
         /* Push the address of the first argument */
-        fprintf( outfile, "\tleal 8(%%ebx),%%eax\n" );
+        fprintf( outfile, "\tleal 8(%%ebp),%%eax\n" );
         fprintf( outfile, "\tpushl $%d\n", reg_func ? -1 : strlen(args) );
         fprintf( outfile, "\tpushl %%eax\n" );
         fprintf( outfile, "\tcall " PREFIX "RELAY_DebugCallTo16\n" );
@@ -1977,19 +1998,24 @@
         fprintf( outfile, "\tpopl %%eax\n" );
     }
 
-    /* Switch to the 16-bit stack */
-
-#ifdef __svr4__
-    fprintf( outfile,"\tdata16\n");
-#endif
-    fprintf( outfile, "\tmovw " PREFIX "IF1632_Saved16_ss_sp+2,%%ss\n" );
-    fprintf( outfile, "\tmovw " PREFIX "IF1632_Saved16_ss_sp,%%sp\n" );
-
-    /* Transfer the arguments */
-
     if (reg_func)
     {
+        /* Switch to the 16-bit stack, saving the current %%esp, */
+        /* and adding the specified offset to the new sp */
+        fprintf( outfile, "\tmovzwl " PREFIX "IF1632_Saved16_ss_sp,%%edx\n" );
+        fprintf( outfile, "\tleal -4(%%edx),%%edx\n" );
+        fprintf( outfile, "\tmovl 12(%%ebx),%%eax\n" ); /* Get the offset */
+        fprintf( outfile, "\taddl %%edx,%%eax\n" );
+#ifdef __svr4__
+        fprintf( outfile,"\tdata16\n");
+#endif
+        fprintf( outfile, "\tmovw " PREFIX "IF1632_Saved16_ss_sp+2,%%ss\n" );
+        fprintf( outfile, "\txchgl %%esp,%%eax\n" );
+        fprintf( outfile, "\t.byte 0x36\n" /* %ss: */ );
+        fprintf( outfile, "\tmovl %%eax,0(%%edx)\n" );
+
         /* Get the registers. ebx is handled later on. */
+
         fprintf( outfile, "\tmovl 8(%%ebx),%%ebx\n" );
         fprintf( outfile, "\tmovl %d(%%ebx),%%eax\n", CONTEXTOFFSET(SegEs) );
         fprintf( outfile, "\tmovw %%ax,%%es\n" );
@@ -1999,14 +2025,42 @@
         fprintf( outfile, "\tmovl %d(%%ebx),%%edx\n", CONTEXTOFFSET(Edx) );
         fprintf( outfile, "\tmovl %d(%%ebx),%%esi\n", CONTEXTOFFSET(Esi) );
         fprintf( outfile, "\tmovl %d(%%ebx),%%edi\n", CONTEXTOFFSET(Edi) );
+
+        /* Push the return address */
+
+        fprintf( outfile, "\tpushl " PREFIX "CALLTO16_RetAddr_long\n" );
+
+        /* Push the called routine address */
+
+        fprintf( outfile, "\tpushw %d(%%ebx)\n", CONTEXTOFFSET(SegCs) );
+        fprintf( outfile, "\tpushw %d(%%ebx)\n", CONTEXTOFFSET(Eip) );
+
+        /* Get the 16-bit ds */
+
+        fprintf( outfile, "\tpushw %d(%%ebx)\n", CONTEXTOFFSET(SegDs) );
+        /* Get ebx from the 32-bit stack */
+        fprintf( outfile, "\tmovl %d(%%ebx),%%ebx\n", CONTEXTOFFSET(Ebx) );
+        fprintf( outfile, "\tpopw %%ds\n" );
     }
     else  /* not a register function */
     {
         int pos = 12;  /* first argument position */
 
+        /* Switch to the 16-bit stack, saving the current %%esp */
+        fprintf( outfile, "\tmovl %%esp,%%eax\n" );
+#ifdef __svr4__
+        fprintf( outfile,"\tdata16\n");
+#endif
+        fprintf( outfile, "\tmovw " PREFIX "IF1632_Saved16_ss_sp+2,%%ss\n" );
+        fprintf( outfile, "\tmovw " PREFIX "IF1632_Saved16_ss_sp,%%sp\n" );
+        fprintf( outfile, "\tpushl %%eax\n" );
+
         /* Make %bp point to the previous stackframe (built by CallFrom16) */
         fprintf( outfile, "\tmovzwl %%sp,%%ebp\n" );
-        fprintf( outfile, "\taddw $20,%%bp\n" );
+        fprintf( outfile, "\tleal %d(%%ebp),%%ebp\n",
+                 STRUCTOFFSET(STACK16FRAME,bp) + 4 /* for saved %%esp */ );
+
+        /* Transfer the arguments */
 
         while (*args)
         {
@@ -2024,42 +2078,21 @@
             }
             pos += 4;
         }
-    }
 
-    /* Push the return address */
+        /* Push the return address */
 
-    fprintf( outfile, "\tpushl " PREFIX "CALLTO16_RetAddr_%s\n",
-             short_ret ? "word" : "long" );
+        fprintf( outfile, "\tpushl " PREFIX "CALLTO16_RetAddr_%s\n",
+                 short_ret ? "word" : "long" );
 
-    if (reg_func)
-    {
-        /* Push the called routine address */
-
-        fprintf( outfile, "\tpushw %d(%%ebx)\n", CONTEXTOFFSET(SegCs) );
-        fprintf( outfile, "\tpushw %d(%%ebx)\n", CONTEXTOFFSET(Eip) );
-
-        /* Get the 16-bit ds */
-
-        fprintf( outfile, "\tpushw %d(%%ebx)\n", CONTEXTOFFSET(SegDs) );
-        /* Get ebx from the 32-bit stack */
-        fprintf( outfile, "\tmovl %d(%%ebx),%%ebx\n", CONTEXTOFFSET(Ebx) );
-        fprintf( outfile, "\tpopw %%ds\n" );
-    }
-    else
-    {
         /* Push the called routine address */
 
         fprintf( outfile, "\tpushl 8(%%ebx)\n" );
 
-	if( window_proc )
-	{
-	    /* set ax to hInstance and initialize es and ds to ss */
+        /* Set %ds and %es (and %ax just in case) equal to %ss */
 
-	    fprintf( outfile, "\tmovw -10(%%ebp),%%ax\n" );
-	    fprintf( outfile, "\tmovw %%ss, %%cx\n" );
-	    fprintf( outfile, "\tmovw %%cx, %%ds\n" );
-	    fprintf( outfile, "\tmovw %%cx, %%es\n" );
-	}
+        fprintf( outfile, "\tmovw %%ss,%%ax\n" );
+        fprintf( outfile, "\tmovw %%ax,%%ds\n" );
+        fprintf( outfile, "\tmovw %%ax,%%es\n" );
     }
 
     /* Jump to the called routine */
@@ -2089,6 +2122,7 @@
 
     /* Restore 32-bit segment registers */
 
+    fprintf( outfile, "\tpopl %%ecx\n" );  /* Get the saved %%esp */
     fprintf( outfile, "\tmovw $0x%04x,%%bx\n", WINE_DATA_SELECTOR );
 #ifdef __svr4__
     fprintf( outfile, "\tdata16\n");
@@ -2098,15 +2132,14 @@
     fprintf( outfile, "\tdata16\n");
 #endif
     fprintf( outfile, "\tmovw %%bx,%%es\n" );
+
+    /* Restore the 32-bit stack */
+
 #ifdef __svr4__
     fprintf( outfile, "\tdata16\n");
 #endif
     fprintf( outfile, "\tmovw %%bx,%%ss\n" );
-
-    /* Restore the 32-bit stack */
-
-    fprintf( outfile, "\tmovl " PREFIX "IF1632_Saved32_esp,%%esp\n" );
-    fprintf( outfile, "\tpopl " PREFIX "IF1632_Saved32_esp\n" );
+    fprintf( outfile, "\tmovl %%ecx,%%esp\n" );
 
     /* Restore the 32-bit registers */
 
@@ -2118,7 +2151,6 @@
 
     /* Return to caller */
 
-/*    fprintf( outfile, "\tpopl %%ebp\n" );*/
     fprintf( outfile, "\tlret\n" );
 
     /* Declare the return address variables */
@@ -2126,8 +2158,10 @@
     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_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_Saved32_esp:\t.long 0\n" );
     fprintf( outfile, "\t.text\n" );
 }
 
@@ -2304,13 +2338,6 @@
         for (i = args; i > 0; i--)
             fprintf( outfile, "\tpushl %d(%%ebp)\n", 4 * i + 4 );
     }
-    else if (!reg_func)
-    {
-        /* Push the address of the arguments. The called function will */
-        /* ignore this if it really takes no arguments. */
-        fprintf( outfile, "\tleal 8(%%ebp),%%eax\n" );
-        fprintf( outfile, "\tpushl %%eax\n" );
-    }
 
 #if 0
     /* Set %es = %ds */
@@ -2361,71 +2388,6 @@
 
 
 /*******************************************************************
- *         BuildCallTo32Func
- *
- * Build a Wine-to-32-bit callback function.
- *
- * Stack frame of the callback function:
- *  ...      ...
- * (ebp+16) arg2
- * (ebp+12) arg1
- * (ebp+8)  func to call
- * (ebp+4)  return address
- * (ebp)    previous ebp
- *
- * Prototype for the CallTo32 functions:
- *   extern LONG CallTo32_nn( FARPROC32 func, args... );
- */
-static void BuildCallTo32Func( FILE *outfile, int args )
-{
-    /* Function header */
-
-    fprintf( outfile, "\n\t.align 4\n" );
-#ifdef USE_STABS
-    fprintf( outfile, ".stabs \"CallTo32_%d:F1\",36,0,0," PREFIX "CallTo32_%d\n", 
-	     args, args);
-#endif
-    fprintf( outfile, "\t.globl " PREFIX "CallTo32_%d\n", args );
-    fprintf( outfile, PREFIX "CallTo32_%d:\n", args );
-
-    /* Entry code */
-
-    fprintf( outfile, "\tpushl %%ebp\n" );
-    fprintf( outfile, "\tmovl %%esp,%%ebp\n" );
-
-    /* Transfer arguments */
-
-    if (args)
-    {
-        int i;
-        for (i = args; i > 0; i--)
-            fprintf( outfile, "\tpushl %d(%%ebp)\n", 4 * i + 8 );
-    }
-
-    /* Print the debugging output */
-
-    if (debugging)
-    {
-        fprintf( outfile, "\tpushl $%d\n", args );
-        fprintf( outfile, "\tpushl 8(%%ebp)\n" );
-        fprintf( outfile, "\tcall " PREFIX "RELAY_DebugCallTo32\n" );
-        fprintf( outfile, "\taddl $8,%%esp\n" );
-    }
-
-    /* Call the function */
-
-    fprintf( outfile, "\tcall 8(%%ebp)\n" );
-
-    /* Return to Wine */
-
-    fprintf( outfile, "\tmovl %%ebp,%%esp\n" );
-    fprintf( outfile, "\tpopl %%ebp\n" );
-    if (args) fprintf( outfile, "\tret $%d\n", args );
-    else fprintf( outfile, "\tret\n" );
-}
-
-
-/*******************************************************************
  *         BuildSpec
  *
  * Build the spec files
@@ -2583,61 +2545,10 @@
 
     for (i = 2; i < argc; i++) BuildCallFrom32Func( outfile, argv[i] );
 
-#ifdef USE_STABS
-    fprintf( outfile, "\t.text\n");
-    fprintf( outfile, "\t.stabs \"\",100,0,0,.Letext\n");
-    fprintf( outfile, ".Letext:\n");
-#endif
-
-    return 0;
-}
-
-
-/*******************************************************************
- *         BuildCallTo32
- *
- * Build the Wine-to-32-bit callbacks
- */
-static int BuildCallTo32( FILE *outfile, char * outname, 
-			  int argc, char *argv[] )
-{
-    char buffer[1024];
-    int i;
-
-    /* File header */
-
-    fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" );
-    fprintf( outfile, "\t.text\n" );
-
-    /*
-     * Throw in a couple of stabs.  The internal debugger doesn't really
-     * care about trying to step through this crap, but we use the file
-     * names as an indication that we should just step through it to whatever
-     * is on the other side.
-     */
-#ifdef USE_STABS
-    fprintf( outfile, "\t.file\t\"%s\"\n", outname );
-    getcwd(buffer, sizeof(buffer));
-
-    /*
-     * The stabs help the internal debugger as they are an indication that it
-     * is sensible to step into a thunk/trampoline.
-     */
-    fprintf( outfile, ".stabs \"%s/\",100,0,0,Code_Start\n", buffer);
-    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" );
-#endif
-
     /* Build the 32-bit large stack callback */
 
     BuildCall32LargeStack( outfile );
 
-    /* Build the callback functions */
-
-    for (i = 2; i < argc; i++) BuildCallTo32Func( outfile, atoi(argv[i]) );
-
 #ifdef USE_STABS
     fprintf( outfile, "\t.text\n");
     fprintf( outfile, "\t.stabs \"\",100,0,0,.Letext\n");
@@ -2653,11 +2564,11 @@
  */
 static void usage(void)
 {
-    fprintf(stderr, "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] -callto32 FUNCTION_PROFILES\n");
+    fprintf( stderr,
+             "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" );
     exit(1);
 }
 
@@ -2694,8 +2605,6 @@
         res = BuildCallTo16( outfile, outname, argc, argv );
     else if (!strcmp( argv[1], "-callfrom32" ))
         res = BuildCallFrom32( outfile, outname, argc, argv );
-    else if (!strcmp( argv[1], "-callto32" ))
-        res = BuildCallTo32( outfile, outname, argc, argv );
     else
     {
         fclose( outfile );
diff --git a/tools/makedep.c b/tools/makedep.c
index 9511f80..2bb6552 100644
--- a/tools/makedep.c
+++ b/tools/makedep.c
@@ -257,6 +257,43 @@
 
 
 /*******************************************************************
+ *         output_src
+ */
+static void output_src( FILE *file, INCL_FILE *pFile, int *column )
+{
+    char *name = strrchr( pFile->name, '/' );
+    char *obj = xstrdup( name ? name + 1 : pFile->name );
+    char *ext = strrchr( obj, '.' );
+    if (ext)
+    {
+        if (!strcmp( ext, ".y" ))  /* yacc file */
+        {
+            fprintf( file, "y.tab.o: ./y.tab.c" );
+            *column += 18;
+        }
+        else if (!strcmp( ext, ".l" ))  /* lex file */
+        {
+            fprintf( file, "lex.yy.o: ./lex.yy.c" );
+            *column += 20;
+        }
+        else if (!strcmp( ext, ".rc" ))  /* resource file */
+        {
+            *ext = '\0';
+            fprintf( file, "%s.c %s.h: %s", obj, obj, pFile->filename );
+            *column += 2 * strlen(obj) + strlen(pFile->filename) + 7;
+        }
+        else
+        {
+            strcpy( ext, ".o" );
+            fprintf( file, "%s: %s", obj, pFile->filename );
+            *column += strlen(obj) + strlen(pFile->filename) + 2;
+        }
+    }
+    free( obj );
+}
+
+
+/*******************************************************************
  *         output_dependencies
  */
 static void output_dependencies(void)
@@ -283,13 +320,8 @@
     }
     for( pFile = firstSrc; pFile; pFile = pFile->next)
     {
-        char *name = strrchr( pFile->name, '/' );
-        char *obj = xstrdup( name ? name + 1 : pFile->name );
-        char *ext = strrchr( obj, '.' );
-        if (ext) strcpy( ext, ".o" );
-        fprintf( file, "%s: %s", obj, pFile->filename );
-        column = strlen(obj) + strlen(pFile->filename) + 2;
-        free( obj );
+        column = 0;
+        output_src( file, pFile, &column );
         for (i = 0; i < MAX_INCLUDES; i++)
             if (pFile->files[i]) output_include( file, pFile->files[i],
                                                  pFile, &column );
diff --git a/win32/code_page.c b/win32/code_page.c
index 7a10618..82caf72 100644
--- a/win32/code_page.c
+++ b/win32/code_page.c
@@ -89,12 +89,12 @@
                                WCHAR *dst, int dstlen)
 {
     if (srclen == -1)
-   	 srclen = lstrlen32A(src);
+   	 srclen = lstrlen32A(src)+1;
     if (!dst)
          return srclen*2;
 
     lstrcpynAtoW(dst,src,srclen); /* FIXME */
-    return srclen*2;
+    return srclen*2-2;
 }
 
 int WINAPI WideCharToMultiByte(UINT32 page, DWORD flags, WCHAR *src, int srclen,
diff --git a/win32/ordinals.c b/win32/ordinals.c
index 28f098f..576d25b 100644
--- a/win32/ordinals.c
+++ b/win32/ordinals.c
@@ -34,10 +34,9 @@
 /**********************************************************************
  *           _KERNEL32_88
  */
-DWORD WINAPI WOW32_1(DWORD x,DWORD y)
+BOOL32 WINAPI WOW32_1(SEGPTR segptr,LPLDT_ENTRY ldtent)
 {
-    fprintf(stderr,"WOW32_1(0x%08lx,0x%08lx), stub!\n",x,y);
-    return 0;
+    return GetThreadSelectorEntry(GetCurrentThreadId(),segptr>>16,ldtent);
 }
 
 
@@ -129,3 +128,13 @@
 	fprintf(stderr,"KERNEL32_34(), STUB returning 0\n");
 	return 0;
 }
+
+BOOL32 WINAPI _KERNEL32_99(HANDLE32 threadid,DWORD exitcode,DWORD x) {
+	fprintf(stderr,"KERNEL32_99(%d,%ld,0x%08lx),stub\n",threadid,exitcode,x);
+	return TRUE;
+}
+
+DWORD WINAPI _KERNEL32_98(DWORD x) {
+	fprintf(stderr,"KERNEL32_98(0x%08lx),stub\n",x);
+	return 1;
+}
diff --git a/win32/process.c b/win32/process.c
index 6820269..5b26a52 100644
--- a/win32/process.c
+++ b/win32/process.c
@@ -339,9 +339,8 @@
 	return 0;
 }
 
-
 /***********************************************************************
- *           WaitForMultipleObjects    (USER32.399)
+ *           MsgWaitForMultipleObjects    (USER32.399)
  */
 DWORD WINAPI MsgWaitForMultipleObjects(
 	DWORD nCount,HANDLE32 *pHandles,BOOL32 fWaitAll,DWORD dwMilliseconds,
@@ -354,6 +353,16 @@
 	fprintf(stderr,"],%d,%ld,0x%08lx)\n",fWaitAll,dwMilliseconds,dwWakeMask);
 	return 0;
 }
+
+/***********************************************************************
+ *           WaitForMultipleObjects    (KERNEL32)
+ */
+DWORD WINAPI WaitForMultipleObjects(
+	DWORD nCount,HANDLE32 *pHandles,BOOL32 fWaitAll,DWORD dwMilliseconds
+) {
+	return MsgWaitForMultipleObjects(nCount,pHandles,fWaitAll,dwMilliseconds,0);
+}
+
 /***********************************************************************
  *           DuplicateHandle    (KERNEL32.78)
  */
diff --git a/windows/dialog.c b/windows/dialog.c
index 31cd880..b56f684 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -502,10 +502,16 @@
     {
           /* The font height must be negative as it is a point size */
           /* (see CreateFont() documentation in the Windows SDK).   */
-	hFont = CreateFont16( -template.pointSize, 0, 0, 0, FW_DONTCARE,
+	if (win32Template)
+	    hFont = CreateFont16( -template.pointSize, 0, 0, 0, FW_DONTCARE,
 			    FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
 			    PROOF_QUALITY, FF_DONTCARE,
-                            template.faceName );  /* FIXME: win32 */
+                            template.faceName );
+	else
+	    hFont = CreateFont32W( -template.pointSize, 0, 0, 0, FW_DONTCARE,
+			    FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
+			    PROOF_QUALITY, FF_DONTCARE,
+                            template.faceName );
 	if (hFont)
 	{
 	    TEXTMETRIC16 tm;
@@ -562,17 +568,18 @@
         }
     }
 
-    if (procType != WIN_PROC_16)
+    if (procType == WIN_PROC_16)
+        hwnd = CreateWindowEx16(template.exStyle, template.className,
+                                template.caption, template.style & ~WS_VISIBLE,
+                                rect.left, rect.top, rect.right, rect.bottom,
+                                owner, hMenu, hInst, NULL );
+    else
         hwnd = CreateWindowEx32W(template.exStyle, (LPCWSTR)template.className,
                                  (LPCWSTR)template.caption,
                                  template.style & ~WS_VISIBLE,
                                  rect.left, rect.top, rect.right, rect.bottom,
                                  owner, hMenu, hInst, NULL );
-    else
-        hwnd = CreateWindowEx32A(template.exStyle, template.className,
-                                template.caption, template.style & ~WS_VISIBLE,
-                                rect.left, rect.top, rect.right, rect.bottom,
-                                owner, hMenu, hInst, NULL );
+	
     if (!hwnd)
     {
 	if (hFont) DeleteObject32( hFont );
diff --git a/windows/event.c b/windows/event.c
index c843ec9..cb6dcb8 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -775,6 +775,7 @@
 	/* Fill WINDOWPOS struct */
 	winpos.flags = SWP_NOACTIVATE | SWP_NOZORDER;
 	winpos.hwnd = hwnd;
+        /* FIXME: position should be relative to root window */
 	winpos.x = event->x;
 	winpos.y = event->y;
 	winpos.cx = event->width;
diff --git a/windows/hook.c b/windows/hook.c
index 55e5785..594dd1a 100644
--- a/windows/hook.c
+++ b/windows/hook.c
@@ -17,7 +17,6 @@
 #include "windows.h"
 #include "hook.h"
 #include "queue.h"
-#include "stackframe.h"
 #include "user.h"
 #include "heap.h"
 #include "struct32.h"
@@ -696,7 +695,7 @@
 	}
 	else
 	  lpcbtcwW->lpcs->lpszClass = (LPCWSTR)lpcbtcwA->lpcs->lpszClass;
-	*plParam = lpcbtcwW;
+	*plParam = (LPARAM)lpcbtcwW;
     }
     return;
 }
@@ -750,7 +749,7 @@
                                                    lpcbtcwW->lpcs->lpszClass );
 	else
 	  lpcbtcwA->lpcs->lpszClass = (LPSTR)lpcbtcwW->lpcs->lpszClass;
-	*plParam = lpcbtcwA;
+	*plParam = (LPARAM)lpcbtcwA;
     }
     return;
 }
@@ -963,7 +962,6 @@
     HANDLE16 prevHook;
     HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
     LRESULT ret;
-    WORD old_ds;
 
     WPARAM32 wParamOrig = wParam;
     LPARAM lParamOrig = lParam;
@@ -986,11 +984,7 @@
     dprintf_hook( stddeb, "Calling hook %04x: %d %08x %08lx\n",
                   hook, code, wParam, lParam );
 
-    /* Set DS = SS to call hook procedure */
-    old_ds = CURRENT_DS;
-    CURRENT_DS = SELECTOROF(IF1632_Saved16_ss_sp);
     ret = data->proc(code, wParam, lParam);
-    CURRENT_DS = old_ds;
 
     dprintf_hook( stddeb, "Ret hook %04x = %08lx\n", hook, ret );
 
diff --git a/windows/keyboard.c b/windows/keyboard.c
index 9421737..229ef59 100644
--- a/windows/keyboard.c
+++ b/windows/keyboard.c
@@ -600,63 +600,33 @@
     return GetAsyncKeyState32(nKey);
 }
 
-
-
 /**********************************************************************
- *			TranslateAccelerator 	[USER.178]
+ *			TranslateAccelerator 	[USER.178][USER32.551..]
  *
  * FIXME: should send some WM_INITMENU or/and WM_INITMENUPOPUP  -messages
  */
-INT32 WINAPI TranslateAccelerator32(HWND32 hWnd, HACCEL32 hAccel, LPMSG32 msg)
+static BOOL32 KBD_translate_accelerator(HWND32 hWnd,LPMSG32 msg,
+                                        BYTE fVirt,WORD key,WORD cmd)
 {
-    MSG16	msg16;
+    BOOL32	sendmsg = FALSE;
 
-    STRUCT32_MSG32to16(msg,&msg16);
-    return TranslateAccelerator16(hWnd,hAccel,&msg16);
-}
-	
-INT16 WINAPI TranslateAccelerator16(HWND16 hWnd, HACCEL16 hAccel, LPMSG16 msg)
-{
-    ACCELHEADER	*lpAccelTbl;
-    int 	i;
-    BOOL32 sendmsg;
-    
-    if (hAccel == 0 || msg == NULL) return 0;
-    if (msg->message != WM_KEYDOWN &&
-    	msg->message != WM_KEYUP &&
-	msg->message != WM_SYSKEYDOWN &&
-	msg->message != WM_SYSKEYUP &&
-    	msg->message != WM_CHAR) return 0;
-
-    dprintf_accel(stddeb, "TranslateAccelerators hAccel=%04x, hWnd=%04x,\
-msg->hwnd=%04x, msg->message=%04x\n", hAccel,hWnd,msg->hwnd,msg->message);
-
-    lpAccelTbl = (LPACCELHEADER)GlobalLock16(hAccel);
-    for (sendmsg= i = 0; i < lpAccelTbl->wCount; i++) 
+    if(msg->wParam == key) 
     {
-     if(msg->wParam == lpAccelTbl->tbl[i].wEvent) 
-     {
-      if (msg->message == WM_CHAR) 
-      {
-        if ( !(lpAccelTbl->tbl[i].type & ALT_ACCEL) && 
-             !(lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) )
+    	if (msg->message == WM_CHAR) {
+        if ( !(fVirt & FALT) && !(fVirt & FVIRTKEY) )
         {
    	  dprintf_accel(stddeb,"found accel for WM_CHAR: ('%c')",msg->wParam&0xff);
    	  sendmsg=TRUE;
    	}  
-      }
-      else
-      {
-       if(lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) 
-       {
+      } else {
+       if(fVirt & FVIRTKEY) {
 	INT32 mask = 0;
         dprintf_accel(stddeb,"found accel for virt_key %04x (scan %04x)",
   	                       msg->wParam,0xff & HIWORD(msg->lParam));                
-	if(GetKeyState32(VK_SHIFT) & 0x8000) mask |= SHIFT_ACCEL;
-	if(GetKeyState32(VK_CONTROL) & 0x8000) mask |= CONTROL_ACCEL;
-	if(GetKeyState32(VK_MENU) & 0x8000) mask |= ALT_ACCEL;
-	if(mask == (lpAccelTbl->tbl[i].type &
-			    (SHIFT_ACCEL | CONTROL_ACCEL | ALT_ACCEL)))
+	if(GetKeyState32(VK_SHIFT) & 0x8000) mask |= FSHIFT;
+	if(GetKeyState32(VK_CONTROL) & 0x8000) mask |= FCONTROL;
+	if(GetKeyState32(VK_MENU) & 0x8000) mask |= FALT;
+	if(mask == (fVirt & (FSHIFT | FCONTROL | FALT)))
           sendmsg=TRUE;			    
         else
           dprintf_accel(stddeb,", but incorrect SHIFT/CTRL/ALT-state\n");
@@ -665,7 +635,7 @@
        {
          if (!(msg->lParam & 0x01000000))  /* no special_key */
          {
-           if ((lpAccelTbl->tbl[i].type & ALT_ACCEL) && (msg->lParam & 0x20000000))
+           if ((fVirt & FALT) && (msg->lParam & 0x20000000))
            {                                                   /* ^^ ALT pressed */
 	    dprintf_accel(stddeb,"found accel for Alt-%c", msg->wParam&0xff);
 	    sendmsg=TRUE;	    
@@ -682,10 +652,10 @@
         if (msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP)
           mesg=1;
         else 
-         if (GetCapture16())
+         if (GetCapture32())
            mesg=2;
          else
-          if (!IsWindowEnabled16(hWnd))
+          if (!IsWindowEnabled32(hWnd))
             mesg=3;
           else
           {
@@ -693,9 +663,9 @@
 
             hMenu = (wndPtr->dwStyle & WS_CHILD) ? 0 : (HMENU32)wndPtr->wIDmenu;
 	    iSysStat = (wndPtr->hSysMenu) ? GetMenuState32(GetSubMenu16(wndPtr->hSysMenu, 0),
-					    lpAccelTbl->tbl[i].wIDval, MF_BYCOMMAND) : -1 ;
+					    cmd, MF_BYCOMMAND) : -1 ;
 	    iStat = (hMenu) ? GetMenuState32(hMenu,
-					    lpAccelTbl->tbl[i].wIDval, MF_BYCOMMAND) : -1 ;
+					    cmd, MF_BYCOMMAND) : -1 ;
 
             if (iSysStat!=-1)
             {
@@ -726,8 +696,8 @@
           {
               dprintf_accel(stddeb,", sending %s, wParam=%0x\n",
                   mesg==WM_COMMAND ? "WM_COMMAND" : "WM_SYSCOMMAND",
-                  lpAccelTbl->tbl[i].wIDval);
-	      SendMessage16(hWnd, mesg, lpAccelTbl->tbl[i].wIDval,0x00010000L);
+                  cmd);
+	      SendMessage32A(hWnd, mesg, cmd, 0x00010000L);
 	  }
 	  else
 	  {
@@ -742,12 +712,56 @@
 	    */
 	    dprintf_accel(stddeb,", but won't send WM_{SYS}COMMAND, reason is #%d\n",mesg);
 	  }          
-          GlobalUnlock16(hAccel);
-          return 1;         
+          return TRUE;         
       }
-     }
     }
-    GlobalUnlock16(hAccel);
+    return FALSE;
+}
+
+INT32 WINAPI TranslateAccelerator32(HWND32 hWnd, HACCEL32 hAccel, LPMSG32 msg)
+{
+    LPACCEL32	lpAccelTbl = (LPACCEL32)LockResource32(hAccel);
+    int 	i;
+    
+    if (hAccel == 0 || msg == NULL) return 0;
+    if (msg->message != WM_KEYDOWN &&
+    	msg->message != WM_KEYUP &&
+	msg->message != WM_SYSKEYDOWN &&
+	msg->message != WM_SYSKEYUP &&
+    	msg->message != WM_CHAR) return 0;
+
+    dprintf_accel(stddeb, "TranslateAccelerators hAccel=%04x, hWnd=%04x,\
+msg->hwnd=%04x, msg->message=%04x\n", hAccel,hWnd,msg->hwnd,msg->message);
+
+    for (i = 0; lpAccelTbl[i].key ; i++)
+    	if (KBD_translate_accelerator(hWnd,msg,lpAccelTbl[i].fVirt,
+                                      lpAccelTbl[i].key,lpAccelTbl[i].cmd))
+		return 1;
+    return 0;
+}
+	
+INT16 WINAPI TranslateAccelerator16(HWND16 hWnd, HACCEL16 hAccel, LPMSG16 msg)
+{
+    LPACCEL16	lpAccelTbl = (LPACCEL16)LockResource16(hAccel);
+    int 	i;
+    MSG32	msg32;
+    
+    if (hAccel == 0 || msg == NULL) return 0;
+    if (msg->message != WM_KEYDOWN &&
+    	msg->message != WM_KEYUP &&
+	msg->message != WM_SYSKEYDOWN &&
+	msg->message != WM_SYSKEYUP &&
+    	msg->message != WM_CHAR) return 0;
+
+    dprintf_accel(stddeb, "TranslateAccelerators hAccel=%04x, hWnd=%04x,\
+msg->hwnd=%04x, msg->message=%04x\n", hAccel,hWnd,msg->hwnd,msg->message);
+    STRUCT32_MSG16to32(msg,&msg32);
+
+
+    for (i=0;lpAccelTbl[i].key;i++) 
+    	if (KBD_translate_accelerator(hWnd,&msg32,lpAccelTbl[i].fVirt,
+                                      lpAccelTbl[i].key,lpAccelTbl[i].cmd))
+		return 1;
     return 0;
 }
 
diff --git a/windows/syscolor.c b/windows/syscolor.c
index e722daa..fc1fb9d 100644
--- a/windows/syscolor.c
+++ b/windows/syscolor.c
@@ -210,7 +210,6 @@
 /*************************************************************************
  *             SetSysColors16   (USER.181)
  */
-/* FIXME -- check return type and insert comment if correct.  */
 VOID WINAPI SetSysColors16( INT16 nChanges, const INT16 *lpSysColor,
 			    const COLORREF *lpColorValues )
 {
diff --git a/windows/user.c b/windows/user.c
index 90e7567..dda1a28 100644
--- a/windows/user.c
+++ b/windows/user.c
@@ -23,8 +23,6 @@
 
 WORD USER_HeapSel = 0;
 
-extern HGLOBAL16 LoadDIBCursorHandler( HGLOBAL16, HINSTANCE16, HRSRC16 );
-extern HGLOBAL16 LoadDIBIconHandler( HGLOBAL16, HINSTANCE16, HRSRC16 );
 extern BOOL32 MENU_PatchResidentPopup( HQUEUE16, WND* );
 extern void QUEUE_FlushMessages(HQUEUE16);
 
diff --git a/windows/win.c b/windows/win.c
index 22d8eaf..32c9f2f 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -468,7 +468,7 @@
     if (HIWORD(cs->lpszClass)) dprintf_win( stddeb, "'%s' ", cs->lpszClass );
     else dprintf_win( stddeb, "#%04x ", LOWORD(cs->lpszClass) );
 
-    dprintf_win( stddeb, "%08lx %08lx %d,%d %dx%d %04x %04x %04x %p\n",
+    dprintf_win( stddeb, "%08lx %08lx %d,%d %dx%d %04x %04x %08x %p\n",
 		 cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy,
 		 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams);
 
@@ -482,11 +482,9 @@
             fprintf( stderr, "CreateWindowEx: bad parent %04x\n", cs->hwndParent );
 	    return 0;
 	}
-    }
-    else if (cs->style & WS_CHILD)
-    {
+    } else if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
         fprintf( stderr, "CreateWindowEx: no parent for child window\n" );
-        return 0;  /* WS_CHILD needs a parent */
+        return 0;  /* WS_CHILD needs a parent, but WS_POPUP doesn't */
     }
 
     /* Find the window class */
@@ -526,7 +524,7 @@
     wndPtr->next  = NULL;
     wndPtr->child = NULL;
 
-    if (cs->style & WS_CHILD)
+    if ((cs->style & WS_CHILD) && cs->hwndParent)
     {
         wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
         wndPtr->owner  = NULL;
diff --git a/windows/winproc.c b/windows/winproc.c
index 267029e..ddb5be1 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -9,7 +9,6 @@
 #include "windows.h"
 #include "heap.h"
 #include "selectors.h"
-#include "stackframe.h"
 #include "struct32.h"
 #include "win.h"
 #include "winproc.h"
@@ -1779,17 +1778,13 @@
 {
     UINT16 msg16;
     MSGPARAM16 mp16;
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-    WORD ds = CURRENT_DS;
 
     mp16.lParam = lParam;
     if (WINPROC_MapMsg32ATo16( msg, wParam, 
 			      &msg16, &mp16.wParam, &mp16.lParam ) == -1)
         return 0;
-    if (wndPtr) CURRENT_DS = wndPtr->hInstance;
     mp16.lResult = WINPROC_CallWndProc16Ptr( func, hwnd, msg16,
                                              mp16.wParam, mp16.lParam );
-    CURRENT_DS = ds;
     WINPROC_UnmapMsg32ATo16( msg, wParam, lParam, &mp16 );
     return mp16.lResult;
 }
@@ -1806,16 +1801,12 @@
 {
     UINT16 msg16;
     MSGPARAM16 mp16;
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-    WORD ds = CURRENT_DS;
 
     mp16.lParam = lParam;
     if (WINPROC_MapMsg32WTo16( msg, wParam, &msg16, &mp16.wParam, &mp16.lParam ) == -1)
         return 0;
-    if (wndPtr) CURRENT_DS = wndPtr->hInstance;
     mp16.lResult = WINPROC_CallWndProc16Ptr( func, hwnd, msg16,
                                              mp16.wParam, mp16.lParam );
-    CURRENT_DS = ds;
     WINPROC_UnmapMsg32WTo16( msg, wParam, lParam, &mp16 );
     return mp16.lResult;
 }
@@ -1827,41 +1818,22 @@
 LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
                                  WPARAM16 wParam, LPARAM lParam )
 {
-    LRESULT result;
-    WND *wndPtr;
-    WORD ds;
     WINDOWPROC *proc = WINPROC_GetPtr( func );
 
     if (!proc)
-    {
-        ds = CURRENT_DS;
-        wndPtr = WIN_FindWndPtr( hwnd );
-        if (wndPtr) CURRENT_DS = wndPtr->hInstance;
-        result = WINPROC_CallWndProc16Ptr( func, hwnd, msg, wParam, lParam );
-        CURRENT_DS = ds;
-        return result;
-    }
+        return WINPROC_CallWndProc16Ptr( func, hwnd, msg, wParam, lParam );
+
 #if testing
-    wndPtr = WIN_FindWndPtr( hwnd );
-    if (wndPtr) CURRENT_DS = wndPtr->hInstance;
-    result = WINPROC_CallWndProc16Ptr( WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16),
-                                       hwnd, msg, wParam, lParam );
-    CURRENT_DS = ds;
-    return result;
+    func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 );
+    return WINPROC_CallWndProc16Ptr( func, hwnd, msg, wParam, lParam );
 #endif
     
     switch(proc->type)
     {
     case WIN_PROC_16:
         if (!proc->thunk.t_from32.proc) return 0;
-        ds = CURRENT_DS;
-        wndPtr = WIN_FindWndPtr( hwnd );
-        if (wndPtr) CURRENT_DS = wndPtr->hInstance;
-        result = WINPROC_CallWndProc16Ptr( proc->thunk.t_from32.proc,
-                                           hwnd, msg, wParam, lParam );
-        CURRENT_DS = ds;
-        return result;
-
+        return WINPROC_CallWndProc16Ptr( proc->thunk.t_from32.proc,
+                                         hwnd, msg, wParam, lParam );
     case WIN_PROC_32A:
         if (!proc->thunk.t_from16.proc) return 0;
         return WINPROC_CallProc16To32A( hwnd, msg, wParam, lParam,