Release 980413

Sun Apr 12 12:22:23 1997  Andreas Mohr <100.30936@germany.net>

	* [files/drive.c]
	Fixed "no free space" problem with partition sizes between 1 and 2 GB
	(cluster_sectors may not exceed 0x40).

	* [windows/msgbox.c] [if1632/user.spec] [include/windows.h]
	Implemented MessageBoxIndirect16, corrected MSGBOXPARAMS16.

	* [loader/task.c]
	DOS environment strings may never exceed 127 chars
	-> truncate Unix environment strings if necessary.

Sun Apr 12 02:51:44 1998  Dimitrie O. Paun  <dimi@mail.cs.toronto.edu>

	* [files/*.c]
	All fprintf statements were converted to appropriate debug
	messages.

	* [tools/find_debug_channels]
	Updated comments at the beginning of the file.

Sat Apr 11 15:27:21 1998  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [loader/module.c] [loader/task.c] [scheduler/process.c]
	Moved some code around to prepare the ground for CreateProcess().

	* [memory/environ.c] [loader/task.c]
	Moved Win32 environment strings functions to environ.c.
	Unified Win16 and Win32 environment management.

	* [scheduler/handle.c] [scheduler/k32obj.c] [scheduler/*.c]
	Implemented handle inheritance and DuplicateHandle().

	* [scheduler/thread.c]
	Create a 16-bit stack for all threads.

	* [windows/dialog.c]
	Implemented DIALOGEX resource format.

Fri Apr 10 20:21:51 1998  Marcus Meissner <marcus@mud.de>

	* [configure.in][include/acconfig.h][*/*][multimedia/*]
	Cleaned up the OSS detection stuff, added some more checks for
	headerfiles/functions.
	Removed a lot of OS specific #ifdefs.
	Lots of dependend multimedia cleanups.

	* [loader/pe_image.c]
	Enhanced comment, added missing reference count increase.

	* [ole/compobj.c]
	Replaced broken StringFromGUID2 by working one.

	* [misc/winsock.c]
	SO_LINGER uses unsigned 16 bit in Win16 and Win32, but unsigned
	int (32bit) for UNIX.

	* [memory/global.c]
	Allow realloc for lockcount 1 too.

Fri Apr 10 15:27:34 1998  Morten Welinder  <terra@diku.dk>

	* [graphics/x11drv/text.c]
	Handle control characters in trace.  Ignore terminating newline.

	* [multimedia/init.c]
	(MULTIMEDIA_Init): Correct allocations.

	* [tools/examine-relay]
 	Tidy up.

	* [windows/syscolor.c]
	Change highlight colour from lightblue to lightgray.  This
	looks correct for menus.

Fri Apr 10 01:49:58 1998  Douglas Ridgway  <ridgway@winehq.com>

	* [configure.in] [Make.rules.in]
	Add check for c2man before using it.

Fri Apr 10 02:59:21 1998  Douglas Ridgway  <ridgway@winehq.com>

	* [DEVELOPERS-HINTS]
	Simple description of adding API calls.

	* [include/wintypes.h] [include/windows.h]
	Get rid of Winelib16, avoid declaring some illegal functions in
	Winelib, add prototypes for some enhanced metafile functions, fix
	GetTextExtentPoint32 declarations.

	* [relay32/gdi32.spec] [objects/enhmetafile.c]
	Cosmetic and functional improvements.

	* [include/wincon.h] [programs/view/*]
	Fixes, improved compatibility with native compilers.

Thu Apr  9 15:48:49 1998  Ulrich Weigand <weigand@informatik.uni-erlangen.de>

	* [win32/kernel32.c]
	Implemented FT_Thunk / FT_Prolog / FT_Exit / FT_PrologPrime.
	Fixed Common32ThkLS thunk function.

	* [tools/build.c] [relay32/relay386.c] [if1632/relay.c]
	Changed relay code to allow register functions to modify stack layout.

	* [memory/selector.c]
	Implemented AllocMappedBuffer / FreeMappedBuffer.

	* [relay32/kernel32.spec] [if1632/kernel.spec] [win32/ordinals.c]
	Added names for undocumented functions.

	* [loader/module.c]
	Bugfix: LoadLibrary16 should *not* silently load 32-bit DLL.

Thu Apr  9 03:54:58 1998  Jim Peterson <jspeter@birch.ee.vt.edu>

	* [windows/keyboard.c]
	Fix an erroneous test in TranslateAccelerator{16,32} for the end
	of the accelerator table.

Thu Apr  8 20:36:28 1998  Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de> 

	* [misc/crtdll.c]
	Implement getenv.

	* [misc/commdlg.c]
	Make Get[Save/Open]FileName work in most situations.

	* [misc/lstr.c]
	Use wvsprintf32A instead of vsprintf in FormatMessage32X

	* [misc/version]
	Make NT3.50 a recognised version

	* [graphics/x11drv/graphics.c]
	Change the algorithme to draw arcs

	* [loader/resource.c]
	Return an empty buffer in LoadString32A if no resource found.

	* [win32/code_page.c]
	Try harder to get the right size in MultiByteToWideChar.

	* [win32/process.c]
	Call WinExec32 for CreateProcess32A.

	* [windows/user.c]
	Install default Int0 Handler in InitApp().

Thu Apr  8 19:29:48 1998  Eric Kohl <ekohl@abo.rhein-zeitung.de>

	* [misc/imagelist.c]
	Preliminary fix for drawing selected images.
	Various improvements.

	* [controls/progress.c][include/progress.c][include/commctrl.h]
	Added progress bar messages and styles for IE4.01 (dll version 4.72)
	compatibility.
	Fixed led size problem.

	* [controls/updown.c][include/commctrl.h]
	Added UDM_GETRANGE32 and UDM_SETRANGE32.

	* [objects/oembitmaps.c][include/windows.h][include/bitmaps/*]
	Added Win95 icons and fixed Win95 cursor and restore button bug.
	Now they should be visible. Sorry!!!

	* [relay32/comctl32.spec]
	Added most missing function names.

Tue Apr  6 18:48:36 1998  Matthew Becker <mbecker@glasscity.net>

	* [objects/font.c] [if1632/gdi.spec]
	GetOutlineTextMetrics: stub

	* [objects/text.c]
	GetTextCharset should just call GetTextCharsetInfo.

	* [misc/mpr.c] [relay32/mpr.spec]
	WNetCachePassword: stub

	* [scheduler/thread.c] [relay32/user32.spec]
	AttachThreadInput: stub
	Updated documentation.

	* [objects/palette.c]
	Updated documentation.

Tue Mar 31 17:06:30 1998  James Juran <jrj120@psu.edu>

	* [*/*.c]
	Finished fixing USER32 ordinal numbers in function documentation.

Mon Mar 30 20:27:38 1998  Morten Welinder  <terra@diku.dk>

	* [misc/debugstr.c] [include/debugstr.h]
	Moved _dumpstr from relay32/relay386.c.  Improved control
	character handling.

	* [msdos/int21.c]
	Implement 215E00 -- get machine name.

	* [windows/winpos.c]
	SetWindowPos32: Make an extra sync when mapping managed
	windows.  This makes sure the reconfigure event has been
	handled.  See Mshearts' what's-your-name window.

Mon Mar 30 01:13:50 1998  Alexander V. Lukyanov <lav@long.yar.ru>

	* [Makefile.in]
	Install includes from TOPSRCDIR.
diff --git a/ANNOUNCE b/ANNOUNCE
index 002be69..78ee48c 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,14 +1,14 @@
-This is release 980329 of Wine, the MS Windows emulator.  This is still a
+This is release 980413 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-980329: (see ChangeLog for details)
-	- More ImageLists support.
-	- More Win32 metafile support.
-	- Still some debugging output changes.
+WHAT'S NEW with Wine-980413: (see ChangeLog for details)
+	- Flat thunks support.
+	- Many more autoconf checks for better portability.
+	- DIALOGEX resource support.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -17,10 +17,10 @@
 the release is available at the ftp sites.  The sources will be available
 from the following locations:
 
-  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-980329.tar.gz
-  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-980329.tar.gz
-  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-980329.tar.gz
-  ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-980329.tar.gz
+  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-980413.tar.gz
+  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-980413.tar.gz
+  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-980413.tar.gz
+  ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-980413.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/ChangeLog b/ChangeLog
index dc618c5..6119f63 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,218 @@
 ----------------------------------------------------------------------
+Sun Apr 12 12:22:23 1997  Andreas Mohr <100.30936@germany.net>
+
+	* [files/drive.c]
+	Fixed "no free space" problem with partition sizes between 1 and 2 GB
+	(cluster_sectors may not exceed 0x40).
+
+	* [windows/msgbox.c] [if1632/user.spec] [include/windows.h]
+	Implemented MessageBoxIndirect16, corrected MSGBOXPARAMS16.
+
+	* [loader/task.c]
+	DOS environment strings may never exceed 127 chars
+	-> truncate Unix environment strings if necessary.
+
+Sun Apr 12 02:51:44 1998  Dimitrie O. Paun  <dimi@mail.cs.toronto.edu>
+
+	* [files/*.c]
+	All fprintf statements were converted to appropriate debug
+	messages.
+
+	* [tools/find_debug_channels]
+	Updated comments at the beginning of the file.
+
+Sat Apr 11 15:27:21 1998  Alexandre Julliard  <julliard@lrc.epfl.ch>
+
+	* [loader/module.c] [loader/task.c] [scheduler/process.c]
+	Moved some code around to prepare the ground for CreateProcess().
+
+	* [memory/environ.c] [loader/task.c]
+	Moved Win32 environment strings functions to environ.c.
+	Unified Win16 and Win32 environment management.
+
+	* [scheduler/handle.c] [scheduler/k32obj.c] [scheduler/*.c]
+	Implemented handle inheritance and DuplicateHandle().
+
+	* [scheduler/thread.c]
+	Create a 16-bit stack for all threads.
+
+	* [windows/dialog.c]
+	Implemented DIALOGEX resource format.
+
+Fri Apr 10 20:21:51 1998  Marcus Meissner <marcus@mud.de>
+
+	* [configure.in][include/acconfig.h][*/*][multimedia/*]
+	Cleaned up the OSS detection stuff, added some more checks for
+	headerfiles/functions.
+	Removed a lot of OS specific #ifdefs.
+	Lots of dependend multimedia cleanups.
+
+	* [loader/pe_image.c]
+	Enhanced comment, added missing reference count increase.
+
+	* [ole/compobj.c]
+	Replaced broken StringFromGUID2 by working one.
+
+	* [misc/winsock.c]
+	SO_LINGER uses unsigned 16 bit in Win16 and Win32, but unsigned
+	int (32bit) for UNIX.
+
+	* [memory/global.c]
+	Allow realloc for lockcount 1 too.
+
+Fri Apr 10 15:27:34 1998  Morten Welinder  <terra@diku.dk>
+
+	* [graphics/x11drv/text.c]
+	Handle control characters in trace.  Ignore terminating newline.
+
+	* [multimedia/init.c]
+	(MULTIMEDIA_Init): Correct allocations.
+
+	* [tools/examine-relay]
+ 	Tidy up.
+
+	* [windows/syscolor.c]
+	Change highlight colour from lightblue to lightgray.  This
+	looks correct for menus.
+
+Fri Apr 10 01:49:58 1998  Douglas Ridgway  <ridgway@winehq.com>
+
+	* [configure.in] [Make.rules.in]
+	Add check for c2man before using it.
+
+Fri Apr 10 02:59:21 1998  Douglas Ridgway  <ridgway@winehq.com>
+
+	* [DEVELOPERS-HINTS]
+	Simple description of adding API calls.
+
+	* [include/wintypes.h] [include/windows.h]
+	Get rid of Winelib16, avoid declaring some illegal functions in
+	Winelib, add prototypes for some enhanced metafile functions, fix
+	GetTextExtentPoint32 declarations.
+
+	* [relay32/gdi32.spec] [objects/enhmetafile.c]
+	Cosmetic and functional improvements.
+
+	* [include/wincon.h] [programs/view/*]
+	Fixes, improved compatibility with native compilers.
+
+Thu Apr  9 15:48:49 1998  Ulrich Weigand <weigand@informatik.uni-erlangen.de>
+
+	* [win32/kernel32.c]
+	Implemented FT_Thunk / FT_Prolog / FT_Exit / FT_PrologPrime.
+	Fixed Common32ThkLS thunk function.
+
+	* [tools/build.c] [relay32/relay386.c] [if1632/relay.c]
+	Changed relay code to allow register functions to modify stack layout.
+
+	* [memory/selector.c]
+	Implemented AllocMappedBuffer / FreeMappedBuffer.
+
+	* [relay32/kernel32.spec] [if1632/kernel.spec] [win32/ordinals.c]
+	Added names for undocumented functions.
+
+	* [loader/module.c]
+	Bugfix: LoadLibrary16 should *not* silently load 32-bit DLL.
+
+Thu Apr  9 03:54:58 1998  Jim Peterson <jspeter@birch.ee.vt.edu>
+
+	* [windows/keyboard.c]
+	Fix an erroneous test in TranslateAccelerator{16,32} for the end
+	of the accelerator table.
+
+Thu Apr  8 20:36:28 1998  Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de> 
+
+	* [misc/crtdll.c]
+	Implement getenv.
+
+	* [misc/commdlg.c]
+	Make Get[Save/Open]FileName work in most situations.
+
+	* [misc/lstr.c]
+	Use wvsprintf32A instead of vsprintf in FormatMessage32X
+
+	* [misc/version]
+	Make NT3.50 a recognised version
+
+	* [graphics/x11drv/graphics.c]
+	Change the algorithme to draw arcs
+
+	* [loader/resource.c]
+	Return an empty buffer in LoadString32A if no resource found.
+
+	* [win32/code_page.c]
+	Try harder to get the right size in MultiByteToWideChar.
+
+	* [win32/process.c]
+	Call WinExec32 for CreateProcess32A.
+
+	* [windows/user.c]
+	Install default Int0 Handler in InitApp().
+
+Thu Apr  8 19:29:48 1998  Eric Kohl <ekohl@abo.rhein-zeitung.de>
+
+	* [misc/imagelist.c]
+	Preliminary fix for drawing selected images.
+	Various improvements.
+
+	* [controls/progress.c][include/progress.c][include/commctrl.h]
+	Added progress bar messages and styles for IE4.01 (dll version 4.72)
+	compatibility.
+	Fixed led size problem.
+
+	* [controls/updown.c][include/commctrl.h]
+	Added UDM_GETRANGE32 and UDM_SETRANGE32.
+
+	* [objects/oembitmaps.c][include/windows.h][include/bitmaps/*]
+	Added Win95 icons and fixed Win95 cursor and restore button bug.
+	Now they should be visible. Sorry!!!
+
+	* [relay32/comctl32.spec]
+	Added most missing function names.
+
+Tue Apr  6 18:48:36 1998  Matthew Becker <mbecker@glasscity.net>
+
+	* [objects/font.c] [if1632/gdi.spec]
+	GetOutlineTextMetrics: stub
+
+	* [objects/text.c]
+	GetTextCharset should just call GetTextCharsetInfo.
+
+	* [misc/mpr.c] [relay32/mpr.spec]
+	WNetCachePassword: stub
+
+	* [scheduler/thread.c] [relay32/user32.spec]
+	AttachThreadInput: stub
+	Updated documentation.
+
+	* [objects/palette.c]
+	Updated documentation.
+
+Tue Mar 31 17:06:30 1998  James Juran <jrj120@psu.edu>
+
+	* [*/*.c]
+	Finished fixing USER32 ordinal numbers in function documentation.
+
+Mon Mar 30 20:27:38 1998  Morten Welinder  <terra@diku.dk>
+
+	* [misc/debugstr.c] [include/debugstr.h]
+	Moved _dumpstr from relay32/relay386.c.  Improved control
+	character handling.
+
+	* [msdos/int21.c]
+	Implement 215E00 -- get machine name.
+
+	* [windows/winpos.c]
+	SetWindowPos32: Make an extra sync when mapping managed
+	windows.  This makes sure the reconfigure event has been
+	handled.  See Mshearts' what's-your-name window.
+
+Mon Mar 30 01:13:50 1998  Alexander V. Lukyanov <lav@long.yar.ru>
+
+	* [Makefile.in]
+	Install includes from TOPSRCDIR.
+
+----------------------------------------------------------------------
 Sun Mar 29 15:18:57 1998  Uwe Bonnes <elektron.ikp.physik.tu-darmstadt.de>
 
 	* [msdos/int21.c]
diff --git a/DEVELOPERS-HINTS b/DEVELOPERS-HINTS
index 40ccb6a..3070e8d 100644
--- a/DEVELOPERS-HINTS
+++ b/DEVELOPERS-HINTS
@@ -60,6 +60,60 @@
 	programs/		- utilities (Progman, WinHelp)
 	libtest/		- Winelib test samples
 
+IMPLEMENTING NEW API CALLS
+==========================
+
+This is the simple version, and covers only Win32. Win16 is slightly uglier,
+because of the Pascal heritage and the segmented memory model.
+
+All of the Win32 APIs known to Wine are listed in [relay32/*.spec]. An
+unimplemented call will look like (from gdi32.spec)
+  269 stub PolyBezierTo
+To implement this call, you need to do the following four things.
+
+1. Find the appropriate parameters for the call, and add a prototype to
+[include/windows.h]. In this case, it might look like
+  BOOL32 WINAPI PolyBezierTo32(HDC32, LPCVOID, DWORD);
+  #define       PolyBezierTo WINELIB_NAME(PolyBezierTo)
+Note the use of the #define for Winelib. See below for discussion of
+function naming conventions.
+  
+2. Modify the .spec file to tell Wine that the function has an
+implementation, what the parameters look like and what Wine function
+to use for the implementation. In Win32, things are simple--everything
+is 32-bits. However, the relay code handles pointers and pointers to
+strings slightly differently, so you should use 'str' and 'wstr' for
+strings, 'ptr' for other pointer types, and 'long' for everything else.
+  269 stdcall PolyBezierTo(long ptr long) PolyBezierTo32
+The 'PolyBezierTo32' at the end of the line is which Wine function to use
+for the implementation.
+
+3. Implement the function as a stub. Once you add the function to the .spec
+file, you must add the function to the Wine source before it will link.
+Add a function called 'PolyBezierTo32' somewhere. Good things to put
+into a stub:
+  o a correct prototype, including the WINAPI
+  o header comments, including full documentation for the function and
+    arguments
+  o A FIXME message and an appropriate return value are good things to
+    put in a stub.
+
+  /************************************************************
+   *  PolyBezierTo32   (GDI32.269)  Draw many Bezier curves
+   *
+   * BUGS
+   *   Unimplemented
+   */
+   BOOL32 WINAPI PolyBezierTo32(HDC32 hdc, LPCVOID p, DWORD count) {
+	/* tell the user they've got a substandard implementation */
+      FIXME(gdi, ":(%x,%p,%d): stub\n", hdc, p, count);
+	/* some programs may be able to compensate, 
+           if they know what happened */
+      SetLastError(ERROR_CALL_NOT_IMPLEMENTED);  
+      return FALSE;    /* error value */
+   }
+
+4. Implement and test the function.
 
 MEMORY AND SEGMENTS
 ===================
@@ -147,8 +201,10 @@
 emulator, 'xxx' is _not_ defined, meaning that you must always specify
 explicitly whether you want the 16-bit or 32-bit version.
 
-Note: if 'xxx' is the same in Win16 and Win32, you can simply use the
-same name as Windows.
+If 'xxx' is the same in Win16 and Win32, or if 'xxx' is Win16 only,
+you can simply use the same name as Windows, i.e. just 'xxx'.  If
+'xxx' is Win32 only, you can use 'xxx' if there are no strings
+involved, otherwise you must use the 'xxx32A' and 'xxx32W' forms.
 
 Examples:
 
@@ -173,7 +229,7 @@
     RegisterClass( &wc );
 
 and this will use the correct declaration depending on the definition
-of the symbols WINELIB16, WINELIB32 and UNICODE.
+of the symbols WINELIB and UNICODE.
 
 
 API ENTRY POINTS
diff --git a/Make.rules.in b/Make.rules.in
index 0006fce..d8e6e93 100644
--- a/Make.rules.in
+++ b/Make.rules.in
@@ -36,7 +36,7 @@
 AR        = ar rc
 RM        = rm -f
 MKDIR     = mkdir
-C2MAN     = c2man
+C2MAN     = @C2MAN@
 BUILD     = $(TOPOBJDIR)/tools/build@PROGEXT@
 MAKEDEP   = $(TOPOBJDIR)/tools/makedep@PROGEXT@
 WINERC    = $(TOPOBJDIR)/rc/winerc@PROGEXT@
diff --git a/Makefile.in b/Makefile.in
index 2b65fae..003637c 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -128,7 +128,7 @@
 
 install_includes: dummy
 	if [ -d $(includedir) ]; then : ; else $(MKDIR) $(includedir); fi 
-	cd include; $(INSTALL_DATA) windows.h wintypes.h $(includedir)
+	cd $(TOPSRCDIR)/include; $(INSTALL_DATA) windows.h wintypes.h $(includedir)
 
 $(ALLSUBDIRS): dummy
 	@cd $@; $(SUBMAKE)
diff --git a/configure b/configure
index f1a2e6f..1d32b1c 100755
--- a/configure
+++ b/configure
@@ -1896,10 +1896,39 @@
   echo "$ac_t""no" 1>&6
 fi
 
+# Extract the first word of "c2man", so it can be a program name with args.
+set dummy c2man; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1903: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_C2MAN'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$C2MAN"; then
+  ac_cv_prog_C2MAN="$C2MAN" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_C2MAN="c2man"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_C2MAN" && ac_cv_prog_C2MAN="true"
+fi
+fi
+C2MAN="$ac_cv_prog_C2MAN"
+if test -n "$C2MAN"; then
+  echo "$ac_t""$C2MAN" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
 
 
 echo $ac_n "checking for i386_set_ldt in -li386""... $ac_c" 1>&6
-echo "configure:1903: checking for i386_set_ldt in -li386" >&5
+echo "configure:1932: checking for i386_set_ldt in -li386" >&5
 ac_lib_var=`echo i386'_'i386_set_ldt | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1907,7 +1936,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-li386  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1911 "configure"
+#line 1940 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1918,7 +1947,7 @@
 i386_set_ldt()
 ; return 0; }
 EOF
-if { (eval echo configure:1922: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1951: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1946,7 +1975,7 @@
 fi
 
 echo $ac_n "checking for iswalnum in -lw""... $ac_c" 1>&6
-echo "configure:1950: checking for iswalnum in -lw" >&5
+echo "configure:1979: checking for iswalnum in -lw" >&5
 ac_lib_var=`echo w'_'iswalnum | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1954,7 +1983,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lw  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1958 "configure"
+#line 1987 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1965,7 +1994,7 @@
 iswalnum()
 ; return 0; }
 EOF
-if { (eval echo configure:1969: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1998: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1993,7 +2022,7 @@
 fi
 
 echo $ac_n "checking for XF86DGAQueryExtension in -lXxf86dga""... $ac_c" 1>&6
-echo "configure:1997: checking for XF86DGAQueryExtension in -lXxf86dga" >&5
+echo "configure:2026: checking for XF86DGAQueryExtension in -lXxf86dga" >&5
 ac_lib_var=`echo Xxf86dga'_'XF86DGAQueryExtension | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2001,7 +2030,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lXxf86dga $X_LIBS -lXext -lX11 $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2005 "configure"
+#line 2034 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2012,7 +2041,7 @@
 XF86DGAQueryExtension()
 ; return 0; }
 EOF
-if { (eval echo configure:2016: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2045: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2036,18 +2065,66 @@
 fi
 
 
+for ac_hdr in sys/soundcard.h machine/soundcard.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2073: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2078 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2083: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
 
 echo $ac_n "checking "for Open Sound System"""... $ac_c" 1>&6
-echo "configure:2042: checking "for Open Sound System"" >&5
+echo "configure:2111: checking "for Open Sound System"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_opensoundsystem'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2047 "configure"
+#line 2116 "configure"
 #include "confdefs.h"
-#include <sys/soundcard.h>
+
+	#ifdef HAVE_SYS_SOUNDCARD_H
+		#include <sys/soundcard.h>
+	#endif
+	#ifdef HAVE_MACHINE_SOUNDCARD_H
+		#include <machine/soundcard.h>
+	#endif
+	
 int main() {
 
+
 /* check for one of the Open Sound System specific SNDCTL_ defines */
 #if !defined(SNDCTL_DSP_STEREO)
 #error No open sound system
@@ -2055,75 +2132,33 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2059: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2136: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_opensoundsystem="yes"
+	cat >> confdefs.h <<\EOF
+#define HAVE_OSS 1
+EOF
+
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   ac_cv_c_opensoundsystem="no"
+
 fi
 rm -f conftest*
 fi
 
 echo "$ac_t""$ac_cv_c_opensoundsystem" 1>&6
 
-echo $ac_n "checking "for Open Sound System on *BSD"""... $ac_c" 1>&6
-echo "configure:2074: checking "for Open Sound System on *BSD"" >&5
-if eval "test \"`echo '$''{'ac_cv_c_opensoundsystem_bsd'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 2079 "configure"
-#include "confdefs.h"
-#include <machine/soundcard.h>
-int main() {
-
-/* check for one of the Open Sound System specific SNDCTL_ defines */
-#if !defined(SNDCTL_DSP_STEREO)
-#error No open sound system
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:2091: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
-  rm -rf conftest*
-  ac_cv_c_opensoundsystem_bsd="yes"
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  ac_cv_c_opensoundsystem_bsd="no"
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$ac_cv_c_opensoundsystem_bsd" 1>&6
-
-if test "$ac_cv_c_opensoundsystem" = "yes" -o "$ac_cv_c_opensoundsystem_bsd" = "yes"
-then
-    cat >> confdefs.h <<\EOF
-#define HAVE_OSS 1
-EOF
-
-    if test "$ac_cv_c_opensoundsystem_bsd" = "yes"
-    then
-        cat >> confdefs.h <<\EOF
-#define HAVE_MACHINE_SOUNDCARD_H 1
-EOF
-
-    fi
-fi
-
 
 echo $ac_n "checking "for union semun"""... $ac_c" 1>&6
-echo "configure:2122: checking "for union semun"" >&5
+echo "configure:2157: checking "for union semun"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_union_semun'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2127 "configure"
+#line 2162 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/sem.h>
@@ -2131,7 +2166,7 @@
 union semun foo
 ; return 0; }
 EOF
-if { (eval echo configure:2135: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2170: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_union_semun="yes"
 else
@@ -2159,7 +2194,7 @@
 then
   CFLAGS="$CFLAGS -Wall"
   echo $ac_n "checking "for gcc strength-reduce bug"""... $ac_c" 1>&6
-echo "configure:2163: checking "for gcc strength-reduce bug"" >&5
+echo "configure:2198: checking "for gcc strength-reduce bug"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_gcc_strength_bug'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2167,7 +2202,7 @@
   ac_cv_c_gcc_strength_bug="yes"
 else
   cat > conftest.$ac_ext <<EOF
-#line 2171 "configure"
+#line 2206 "configure"
 #include "confdefs.h"
 
 int main(void) {
@@ -2178,7 +2213,7 @@
   exit( Array[1] != -2 );
 }
 EOF
-if { (eval echo configure:2182: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2217: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_gcc_strength_bug="no"
 else
@@ -2201,7 +2236,7 @@
 
 
 echo $ac_n "checking "whether external symbols need an underscore prefix"""... $ac_c" 1>&6
-echo "configure:2205: checking "whether external symbols need an underscore prefix"" >&5
+echo "configure:2240: checking "whether external symbols need an underscore prefix"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_extern_prefix'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2213,14 +2248,14 @@
 	.long 0
 EOF
 cat > conftest.$ac_ext <<EOF
-#line 2217 "configure"
+#line 2252 "configure"
 #include "confdefs.h"
 extern int ac_test;
 int main() {
 if (ac_test) return 1
 ; return 0; }
 EOF
-if { (eval echo configure:2224: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2259: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_c_extern_prefix="yes"
 else
@@ -2244,7 +2279,7 @@
 
 
 echo $ac_n "checking "whether assembler accepts .string"""... $ac_c" 1>&6
-echo "configure:2248: checking "whether assembler accepts .string"" >&5
+echo "configure:2283: checking "whether assembler accepts .string"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_asm_string'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2254,14 +2289,14 @@
 	.string "test"
 EOF
 cat > conftest.$ac_ext <<EOF
-#line 2258 "configure"
+#line 2293 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:2265: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2300: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_c_asm_string="yes"
 else
@@ -2288,21 +2323,21 @@
 if test "$LIB_TARGET" = "libwine.so.1.0"
 then
   echo $ac_n "checking "whether we can build a dll"""... $ac_c" 1>&6
-echo "configure:2292: checking "whether we can build a dll"" >&5
+echo "configure:2327: checking "whether we can build a dll"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_dll'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   saved_cflags=$CFLAGS
   CFLAGS="$CFLAGS -fPIC -shared -Wl,-soname,conftest.so.1.0"
   cat > conftest.$ac_ext <<EOF
-#line 2299 "configure"
+#line 2334 "configure"
 #include "confdefs.h"
 
 int main() {
 return 1
 ; return 0; }
 EOF
-if { (eval echo configure:2306: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2341: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_c_dll="yes"
 else
@@ -2328,7 +2363,7 @@
 
 
 echo $ac_n "checking "for reentrant X libraries"""... $ac_c" 1>&6
-echo "configure:2332: checking "for reentrant X libraries"" >&5
+echo "configure:2367: checking "for reentrant X libraries"" >&5
 if eval "test \"`echo '$''{'wine_cv_x_reentrant'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2369,15 +2404,15 @@
 fi
 
 
-for ac_func in clone memmove strerror tcgetattr timegm usleep wait4 waitpid
+for ac_func in clone getpagesize memmove sigaltstack strerror tcgetattr timegm usleep wait4 waitpid
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2376: checking for $ac_func" >&5
+echo "configure:2411: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2381 "configure"
+#line 2416 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2400,7 +2435,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2404: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2439: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2424,21 +2459,21 @@
 fi
 done
 
-for ac_hdr in wctype.h
+for ac_hdr in wctype.h sys/syscall.h syscall.h sys/param.h sys/vfs.h sys/mount.h sys/statfs.h float.h linux/cdrom.h sys/cdio.h sys/filio.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2432: checking for $ac_hdr" >&5
+echo "configure:2467: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2437 "configure"
+#line 2472 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2442: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2477: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2465,12 +2500,12 @@
 done
 
 echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6
-echo "configure:2469: checking whether stat file-mode macros are broken" >&5
+echo "configure:2504: checking whether stat file-mode macros are broken" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2474 "configure"
+#line 2509 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -2521,12 +2556,12 @@
 fi
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:2525: checking for working const" >&5
+echo "configure:2560: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2530 "configure"
+#line 2565 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -2575,7 +2610,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2579: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2614: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -2596,12 +2631,12 @@
 fi
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:2600: checking for ANSI C header files" >&5
+echo "configure:2635: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2605 "configure"
+#line 2640 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -2609,7 +2644,7 @@
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2613: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2648: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2626,7 +2661,7 @@
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 2630 "configure"
+#line 2665 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -2644,7 +2679,7 @@
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 2648 "configure"
+#line 2683 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -2665,7 +2700,7 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 2669 "configure"
+#line 2704 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -2676,7 +2711,7 @@
 exit (0); }
 
 EOF
-if { (eval echo configure:2680: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2715: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -2700,12 +2735,12 @@
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:2704: checking for size_t" >&5
+echo "configure:2739: checking for size_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2709 "configure"
+#line 2744 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -2732,6 +2767,160 @@
 
 fi
 
+echo $ac_n "checking size of long long""... $ac_c" 1>&6
+echo "configure:2772: checking size of long long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_sizeof_long_long=0
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2780 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(long long));
+  exit(0);
+}
+EOF
+if { (eval echo configure:2791: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_long_long=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_long_long=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_long_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+EOF
+
+
+
+echo $ac_n "checking "for statfs.f_bavail"""... $ac_c" 1>&6
+echo "configure:2812: checking "for statfs.f_bavail"" >&5
+if eval "test \"`echo '$''{'wine_cv_statfs_bavail'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+   if test "x$statfs_bavail" = "xno"
+    then
+        wine_cv_statfs_bavail=no
+    else
+    	cat > conftest.$ac_ext <<EOF
+#line 2821 "configure"
+#include "confdefs.h"
+
+	#ifdef HAVE_SYS_PARAM_H
+	# include <sys/param.h>
+	#endif
+	#ifdef HAVE_SYS_STATFS_H
+	# include <sys/statfs.h>
+	#endif
+	#ifdef HAVE_SYS_MOUNT_H
+	# include <sys/mount.h>
+	#endif
+	#ifdef HAVE_SYS_VFS_H
+	# include <sys/vfs.h>
+	#endif
+	
+int main() {
+
+		struct statfs stfs;
+
+		stfs.f_bavail++;
+	
+; return 0; }
+EOF
+if { (eval echo configure:2845: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  wine_cv_statfs_bavail=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  wine_cv_statfs_bavail=no
+	
+fi
+rm -f conftest*
+    fi  
+fi
+
+echo "$ac_t""$wine_cv_statfs_bavail" 1>&6
+if test "$wine_cv_statfs_bavail" = "yes"
+then
+  cat >> confdefs.h <<\EOF
+#define STATFS_HAS_BAVAIL 1
+EOF
+
+fi
+
+echo $ac_n "checking "for statfs.f_bfree"""... $ac_c" 1>&6
+echo "configure:2869: checking "for statfs.f_bfree"" >&5
+if eval "test \"`echo '$''{'wine_cv_statfs_bfree'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+   if test "x$statfs_bfree" = "xno"
+    then
+        wine_cv_statfs_bfree=no
+    else
+    	cat > conftest.$ac_ext <<EOF
+#line 2878 "configure"
+#include "confdefs.h"
+
+	#ifdef HAVE_SYS_PARAM_H
+	# include <sys/param.h>
+	#endif
+	#ifdef HAVE_SYS_STATFS_H
+	# include <sys/statfs.h>
+	#endif
+	#ifdef HAVE_SYS_MOUNT_H
+	# include <sys/mount.h>
+	#endif
+	#ifdef HAVE_SYS_VFS_H
+	# include <sys/vfs.h>
+	#endif
+	
+int main() {
+
+		struct statfs stfs;
+
+		stfs.f_bfree++;
+	
+; return 0; }
+EOF
+if { (eval echo configure:2902: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  wine_cv_statfs_bfree=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  wine_cv_statfs_bfree=no
+	
+fi
+rm -f conftest*
+    fi  
+fi
+
+echo "$ac_t""$wine_cv_statfs_bfree" 1>&6
+if test "$wine_cv_statfs_bfree" = "yes"
+then
+  cat >> confdefs.h <<\EOF
+#define STATFS_HAS_BFREE 1
+EOF
+
+fi
+
 
 
 MAKE_RULES=Make.rules
@@ -2923,6 +3112,7 @@
 s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
 s%@INSTALL_DATA@%$INSTALL_DATA%g
 s%@LN_S@%$LN_S%g
+s%@C2MAN@%$C2MAN%g
 s%@DLLFLAGS@%$DLLFLAGS%g
 /@MAKE_RULES@/r $MAKE_RULES
 s%@MAKE_RULES@%%g
diff --git a/configure.in b/configure.in
index 78a2c96..5dba6fa 100644
--- a/configure.in
+++ b/configure.in
@@ -46,6 +46,7 @@
 AC_PROG_RANLIB
 AC_PROG_INSTALL
 AC_PROG_LN_S
+AC_CHECK_PROG(C2MAN,c2man,c2man,true)
 
 dnl **** Check for some libraries ****
 
@@ -57,33 +58,28 @@
 AC_CHECK_LIB(Xxf86dga,XF86DGAQueryExtension,AC_DEFINE(HAVE_LIBXXF86DGA) X_PRE_LIBS="$X_PRE_LIBS -lXxf86dga",,$X_LIBS -lXext -lX11)
 
 dnl **** Check for Open Sound System ****
+AC_CHECK_HEADERS(sys/soundcard.h machine/soundcard.h)
 
 AC_CACHE_CHECK("for Open Sound System",
 	ac_cv_c_opensoundsystem,
-	AC_TRY_COMPILE([#include <sys/soundcard.h>],[
+	AC_TRY_COMPILE([
+	#ifdef HAVE_SYS_SOUNDCARD_H
+		#include <sys/soundcard.h>
+	#endif
+	#ifdef HAVE_MACHINE_SOUNDCARD_H
+		#include <machine/soundcard.h>
+	#endif
+	],[
+
 /* check for one of the Open Sound System specific SNDCTL_ defines */
 #if !defined(SNDCTL_DSP_STEREO)
 #error No open sound system
 #endif
-],ac_cv_c_opensoundsystem="yes",ac_cv_c_opensoundsystem="no"))
-
-AC_CACHE_CHECK("for Open Sound System on *BSD",
-	ac_cv_c_opensoundsystem_bsd,
-	AC_TRY_COMPILE([#include <machine/soundcard.h>],[
-/* check for one of the Open Sound System specific SNDCTL_ defines */
-#if !defined(SNDCTL_DSP_STEREO)
-#error No open sound system
-#endif
-],ac_cv_c_opensoundsystem_bsd="yes",ac_cv_c_opensoundsystem_bsd="no"))
-
-if test "$ac_cv_c_opensoundsystem" = "yes" -o "$ac_cv_c_opensoundsystem_bsd" = "yes"
-then
-    AC_DEFINE(HAVE_OSS)
-    if test "$ac_cv_c_opensoundsystem_bsd" = "yes"
-    then
-        AC_DEFINE(HAVE_MACHINE_SOUNDCARD_H)
-    fi
-fi
+],
+	ac_cv_c_opensoundsystem="yes"
+	AC_DEFINE(HAVE_OSS),
+	ac_cv_c_opensoundsystem="no"
+))
 
 dnl **** Check for union semun ****
 
@@ -217,11 +213,74 @@
 
 dnl **** Check for functions and header files ****
 
-AC_CHECK_FUNCS(clone memmove strerror tcgetattr timegm usleep wait4 waitpid)
-AC_CHECK_HEADERS(wctype.h)
+AC_CHECK_FUNCS(clone getpagesize memmove sigaltstack strerror tcgetattr timegm usleep wait4 waitpid)
+AC_CHECK_HEADERS(wctype.h sys/syscall.h syscall.h sys/param.h sys/vfs.h sys/mount.h sys/statfs.h float.h linux/cdrom.h sys/cdio.h sys/filio.h)
 AC_HEADER_STAT()
 AC_C_CONST()
 AC_TYPE_SIZE_T()
+AC_CHECK_SIZEOF(long long,0)
+
+dnl **** Dependent checks ****
+AC_CACHE_CHECK( "for statfs.f_bavail", wine_cv_statfs_bavail,
+  [ if test "x$statfs_bavail" = "xno"
+    then
+        wine_cv_statfs_bavail=no
+    else
+    	AC_TRY_COMPILE([
+	#ifdef HAVE_SYS_PARAM_H
+	# include <sys/param.h>
+	#endif
+	#ifdef HAVE_SYS_STATFS_H
+	# include <sys/statfs.h>
+	#endif
+	#ifdef HAVE_SYS_MOUNT_H
+	# include <sys/mount.h>
+	#endif
+	#ifdef HAVE_SYS_VFS_H
+	# include <sys/vfs.h>
+	#endif
+	],[
+		struct statfs stfs;
+
+		stfs.f_bavail++;
+	],wine_cv_statfs_bavail=yes,wine_cv_statfs_bavail=no
+	)
+    fi ] )
+if test "$wine_cv_statfs_bavail" = "yes"
+then
+  AC_DEFINE(STATFS_HAS_BAVAIL)
+fi
+
+AC_CACHE_CHECK( "for statfs.f_bfree", wine_cv_statfs_bfree,
+  [ if test "x$statfs_bfree" = "xno"
+    then
+        wine_cv_statfs_bfree=no
+    else
+    	AC_TRY_COMPILE([
+	#ifdef HAVE_SYS_PARAM_H
+	# include <sys/param.h>
+	#endif
+	#ifdef HAVE_SYS_STATFS_H
+	# include <sys/statfs.h>
+	#endif
+	#ifdef HAVE_SYS_MOUNT_H
+	# include <sys/mount.h>
+	#endif
+	#ifdef HAVE_SYS_VFS_H
+	# include <sys/vfs.h>
+	#endif
+	],[
+		struct statfs stfs;
+
+		stfs.f_bfree++;
+	],wine_cv_statfs_bfree=yes,wine_cv_statfs_bfree=no
+	)
+    fi ] )
+if test "$wine_cv_statfs_bfree" = "yes"
+then
+  AC_DEFINE(STATFS_HAS_BFREE)
+fi
+
 
 dnl **** Generate output files ****
 
diff --git a/controls/button.c b/controls/button.c
index 16e6e97..0466339 100644
--- a/controls/button.c
+++ b/controls/button.c
@@ -100,7 +100,7 @@
         if (!hbitmapCheckBoxes)
         {
             BITMAP32 bmp;
-            hbitmapCheckBoxes = LoadBitmap32A(0, MAKEINTRESOURCE(OBM_CHECKBOXES));
+            hbitmapCheckBoxes = LoadBitmap32A(0, MAKEINTRESOURCE32A(OBM_CHECKBOXES));
             GetObject32A( hbitmapCheckBoxes, sizeof(bmp), &bmp );
             checkBoxWidth  = bmp.bmWidth / 4;
             checkBoxHeight = bmp.bmHeight / 3;
diff --git a/controls/combo.c b/controls/combo.c
index 3001b5b..db24ec3 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -52,7 +52,7 @@
   if( (hDC = CreateCompatibleDC32(0)) )
   {
     BOOL32	bRet = FALSE;
-    if( (hComboBmp = LoadBitmap32A(0, MAKEINTRESOURCE(OBM_COMBO))) )
+    if( (hComboBmp = LoadBitmap32A(0, MAKEINTRESOURCE32A(OBM_COMBO))) )
     {
       BITMAP32      bm;
       HBITMAP32     hPrevB;
diff --git a/controls/commctrl.c b/controls/commctrl.c
index f9400fd..a720660 100644
--- a/controls/commctrl.c
+++ b/controls/commctrl.c
@@ -114,7 +114,7 @@
 HWND32 WINAPI CreateStatusWindow32W( INT32 style, LPCWSTR text, HWND32 parent,
                                      UINT32 wid )
 {
-    return CreateWindow32W(STATUSCLASSNAME32W, text, style, 
+    return CreateWindow32W((LPCWSTR)STATUSCLASSNAME32W, text, style, 
 			   CW_USEDEFAULT32, CW_USEDEFAULT32,
 			   CW_USEDEFAULT32, CW_USEDEFAULT32, 
 			   parent, wid, 0, 0);
@@ -156,7 +156,7 @@
         old_name = class32->lpszClassName;
         strcpy( name, (char *)class32->lpszClassName );
         class32->lpszClassName = name;
-        class32->hCursor = LoadCursor32A( 0, (LPCSTR)IDC_ARROW );
+        class32->hCursor = LoadCursor32A( 0, IDC_ARROW32A );
         RegisterClass32A( class32 );
         class32->lpszClassName = old_name;	
     }
diff --git a/controls/desktop.c b/controls/desktop.c
index 1535b9a..520bb56 100644
--- a/controls/desktop.c
+++ b/controls/desktop.c
@@ -160,7 +160,7 @@
 	ExitWindows16( 0, 0 ); 
 
     case WM_SETCURSOR:
-        return (LRESULT)SetCursor16( LoadCursor16( 0, IDC_ARROW ) );
+        return (LRESULT)SetCursor16( LoadCursor16( 0, IDC_ARROW16 ) );
     }
     
     return 0;
diff --git a/controls/menu.c b/controls/menu.c
index 3508d4d..f9efbf8 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -329,9 +329,9 @@
 					    0x55, 0, 0xAA, 0 };
 
     /* Load menu bitmaps */
-    hStdCheck = LoadBitmap32A(0, (LPSTR)MAKEINTRESOURCE(OBM_CHECK));
-    hStdRadioCheck = LoadBitmap32A(0, (LPSTR)MAKEINTRESOURCE(OBM_RADIOCHECK));
-    hStdMnArrow = LoadBitmap32A(0, (LPSTR)MAKEINTRESOURCE(OBM_MNARROW));
+    hStdCheck = LoadBitmap32A(0, MAKEINTRESOURCE32A(OBM_CHECK));
+    hStdRadioCheck = LoadBitmap32A(0, MAKEINTRESOURCE32A(OBM_RADIOCHECK));
+    hStdMnArrow = LoadBitmap32A(0, MAKEINTRESOURCE32A(OBM_MNARROW));
 
     if (hStdCheck)
     {
@@ -2542,7 +2542,7 @@
 
 
 /**********************************************************************
- *           TrackPopupMenu32   (USER32.548)
+ *           TrackPopupMenu32   (USER32.549)
  */
 BOOL32 WINAPI TrackPopupMenu32( HMENU32 hMenu, UINT32 wFlags, INT32 x, INT32 y,
                            INT32 nReserved, HWND32 hWnd, const RECT32 *lpRect )
@@ -2558,7 +2558,7 @@
 }
 
 /**********************************************************************
- *           TrackPopupMenuEx   (USER32.549)
+ *           TrackPopupMenuEx   (USER32.550)
  */
 BOOL32 WINAPI TrackPopupMenuEx( HMENU32 hMenu, UINT32 wFlags, INT32 x, INT32 y,
                                 HWND32 hWnd, LPTPMPARAMS lpTpm )
@@ -2702,7 +2702,7 @@
 
 
 /*******************************************************************
- *         ChangeMenu32A    (USER32.22)
+ *         ChangeMenu32A    (USER32.23)
  */
 BOOL32 WINAPI ChangeMenu32A( HMENU32 hMenu, UINT32 pos, LPCSTR data,
                              UINT32 id, UINT32 flags )
@@ -2723,7 +2723,7 @@
 
 
 /*******************************************************************
- *         ChangeMenu32W    (USER32.23)
+ *         ChangeMenu32W    (USER32.24)
  */
 BOOL32 WINAPI ChangeMenu32W( HMENU32 hMenu, UINT32 pos, LPCWSTR data,
                              UINT32 id, UINT32 flags )
@@ -2753,7 +2753,7 @@
 
 
 /*******************************************************************
- *         CheckMenuItem32    (USER32.45)
+ *         CheckMenuItem32    (USER32.46)
  */
 DWORD WINAPI CheckMenuItem32( HMENU32 hMenu, UINT32 id, UINT32 flags )
 {
@@ -2779,7 +2779,7 @@
 
 
 /**********************************************************************
- *         EnableMenuItem32    (USER32.169)
+ *         EnableMenuItem32    (USER32.170)
  */
 BOOL32 WINAPI EnableMenuItem32( HMENU32 hMenu, UINT32 wItemID, UINT32 wFlags )
 {
@@ -2827,7 +2827,7 @@
 
 
 /*******************************************************************
- *         GetMenuString32A    (USER32.267)
+ *         GetMenuString32A    (USER32.268)
  */
 INT32 WINAPI GetMenuString32A( HMENU32 hMenu, UINT32 wItemID,
                                LPSTR str, INT32 nMaxSiz, UINT32 wFlags )
@@ -2847,7 +2847,7 @@
 
 
 /*******************************************************************
- *         GetMenuString32W    (USER32.268)
+ *         GetMenuString32W    (USER32.269)
  */
 INT32 WINAPI GetMenuString32W( HMENU32 hMenu, UINT32 wItemID,
                                LPWSTR str, INT32 nMaxSiz, UINT32 wFlags )
@@ -2876,7 +2876,7 @@
 
 
 /**********************************************************************
- *         HiliteMenuItem32    (USER32.317)
+ *         HiliteMenuItem32    (USER32.318)
  */
 BOOL32 WINAPI HiliteMenuItem32( HWND32 hWnd, HMENU32 hMenu, UINT32 wItemID,
                                 UINT32 wHilite )
@@ -2903,7 +2903,7 @@
 
 
 /**********************************************************************
- *         GetMenuState32    (USER32.266)
+ *         GetMenuState32    (USER32.267)
  */
 UINT32 WINAPI GetMenuState32( HMENU32 hMenu, UINT32 wItemID, UINT32 wFlags )
 {
@@ -2942,7 +2942,7 @@
 
 
 /**********************************************************************
- *         GetMenuItemCount32    (USER32.261)
+ *         GetMenuItemCount32    (USER32.262)
  */
 INT32 WINAPI GetMenuItemCount32( HMENU32 hMenu )
 {
@@ -2969,7 +2969,7 @@
 
 
 /**********************************************************************
- *         GetMenuItemID32    (USER32.262)
+ *         GetMenuItemID32    (USER32.263)
  */
 UINT32 WINAPI GetMenuItemID32( HMENU32 hMenu, INT32 nPos )
 {
@@ -2997,7 +2997,7 @@
 
 
 /*******************************************************************
- *         InsertMenu32A    (USER32.321)
+ *         InsertMenu32A    (USER32.322)
  */
 BOOL32 WINAPI InsertMenu32A( HMENU32 hMenu, UINT32 pos, UINT32 flags,
                              UINT32 id, LPCSTR str )
@@ -3030,7 +3030,7 @@
 
 
 /*******************************************************************
- *         InsertMenu32W    (USER32.324)
+ *         InsertMenu32W    (USER32.325)
  */
 BOOL32 WINAPI InsertMenu32W( HMENU32 hMenu, UINT32 pos, UINT32 flags,
                              UINT32 id, LPCWSTR str )
@@ -3058,7 +3058,7 @@
 
 
 /*******************************************************************
- *         AppendMenu32A    (USER32.4)
+ *         AppendMenu32A    (USER32.5)
  */
 BOOL32 WINAPI AppendMenu32A( HMENU32 hMenu, UINT32 flags,
                              UINT32 id, LPCSTR data )
@@ -3068,7 +3068,7 @@
 
 
 /*******************************************************************
- *         AppendMenu32W    (USER32.5)
+ *         AppendMenu32W    (USER32.6)
  */
 BOOL32 WINAPI AppendMenu32W( HMENU32 hMenu, UINT32 flags,
                              UINT32 id, LPCWSTR data )
@@ -3087,7 +3087,7 @@
 
 
 /**********************************************************************
- *         RemoveMenu32    (USER32.440)
+ *         RemoveMenu32    (USER32.441)
  */
 BOOL32 WINAPI RemoveMenu32( HMENU32 hMenu, UINT32 nPos, UINT32 wFlags )
 {
@@ -3132,7 +3132,7 @@
 
 
 /**********************************************************************
- *         DeleteMenu32    (USER32.128)
+ *         DeleteMenu32    (USER32.129)
  */
 BOOL32 WINAPI DeleteMenu32( HMENU32 hMenu, UINT32 nPos, UINT32 wFlags )
 {
@@ -3159,7 +3159,7 @@
 
 
 /*******************************************************************
- *         ModifyMenu32A    (USER32.396)
+ *         ModifyMenu32A    (USER32.397)
  */
 BOOL32 WINAPI ModifyMenu32A( HMENU32 hMenu, UINT32 pos, UINT32 flags,
                              UINT32 id, LPCSTR str )
@@ -3184,7 +3184,7 @@
 
 
 /*******************************************************************
- *         ModifyMenu32W    (USER32.397)
+ *         ModifyMenu32W    (USER32.398)
  */
 BOOL32 WINAPI ModifyMenu32W( HMENU32 hMenu, UINT32 pos, UINT32 flags,
                              UINT32 id, LPCWSTR str )
@@ -3212,7 +3212,7 @@
 
 
 /**********************************************************************
- *         CreatePopupMenu32    (USER32.81)
+ *         CreatePopupMenu32    (USER32.82)
  */
 HMENU32 WINAPI CreatePopupMenu32(void)
 {
@@ -3227,7 +3227,7 @@
 
 
 /**********************************************************************
- *         GetMenuCheckMarkDimensions    (USER.417) (USER32.257)
+ *         GetMenuCheckMarkDimensions    (USER.417) (USER32.258)
  */
 DWORD WINAPI GetMenuCheckMarkDimensions(void)
 {
@@ -3246,7 +3246,7 @@
 
 
 /**********************************************************************
- *         SetMenuItemBitmaps32    (USER32.489)
+ *         SetMenuItemBitmaps32    (USER32.490)
  */
 BOOL32 WINAPI SetMenuItemBitmaps32( HMENU32 hMenu, UINT32 nPos, UINT32 wFlags,
                                     HBITMAP32 hNewUnCheck, HBITMAP32 hNewCheck)
@@ -3280,7 +3280,7 @@
 
 
 /**********************************************************************
- *         CreateMenu32    (USER32.80)
+ *         CreateMenu32    (USER32.81)
  */
 HMENU32 WINAPI CreateMenu32(void)
 {
@@ -3312,7 +3312,7 @@
 
 
 /**********************************************************************
- *         DestroyMenu32    (USER32.133)
+ *         DestroyMenu32    (USER32.134)
  */
 BOOL32 WINAPI DestroyMenu32( HMENU32 hMenu )
 {
@@ -3364,7 +3364,7 @@
 
 
 /**********************************************************************
- *         GetSystemMenu32    (USER32.290)
+ *         GetSystemMenu32    (USER32.291)
  */
 HMENU32 WINAPI GetSystemMenu32( HWND32 hWnd, BOOL32 bRevert )
 {
@@ -3408,7 +3408,7 @@
 
 
 /*******************************************************************
- *         SetSystemMenu32    (USER32.507)
+ *         SetSystemMenu32    (USER32.508)
  */
 BOOL32 WINAPI SetSystemMenu32( HWND32 hwnd, HMENU32 hMenu )
 {
@@ -3437,7 +3437,7 @@
 
 
 /**********************************************************************
- *         GetMenu32    (USER32.256)
+ *         GetMenu32    (USER32.257)
  */
 HMENU32 WINAPI GetMenu32( HWND32 hWnd ) 
 { 
@@ -3458,7 +3458,7 @@
 
 
 /**********************************************************************
- *         SetMenu32    (USER32.486)
+ *         SetMenu32    (USER32.487)
  */
 BOOL32 WINAPI SetMenu32( HWND32 hWnd, HMENU32 hMenu )
 {
@@ -3500,7 +3500,7 @@
 
 
 /**********************************************************************
- *         GetSubMenu32    (USER32.287)
+ *         GetSubMenu32    (USER32.288)
  */
 HMENU32 WINAPI GetSubMenu32( HMENU32 hMenu, INT32 nPos )
 {
@@ -3523,7 +3523,7 @@
 
 
 /**********************************************************************
- *         DrawMenuBar32    (USER32.160)
+ *         DrawMenuBar32    (USER32.161)
  */
 BOOL32 WINAPI DrawMenuBar32( HWND32 hWnd )
 {
@@ -3544,7 +3544,7 @@
 
 
 /***********************************************************************
- *           EndMenu   (USER.187) (USER32.174)
+ *           EndMenu   (USER.187) (USER32.175)
  */
 void WINAPI EndMenu(void)
 {
@@ -3589,7 +3589,7 @@
         return LoadMenu32A(instance,PTR_SEG_TO_LIN(name));
     instance = GetExePtr( instance );
 
-    if (!(hRsrc = FindResource16( instance, name, RT_MENU ))) return 0;
+    if (!(hRsrc = FindResource16( instance, name, RT_MENU16 ))) return 0;
     if (!(handle = LoadResource16( instance, hRsrc ))) return 0;
     hMenu = LoadMenuIndirect16(LockResource16(handle));
     FreeResource16( handle );
@@ -3602,18 +3602,18 @@
  */
 HMENU32 WINAPI LoadMenu32A( HINSTANCE32 instance, LPCSTR name )
 {
-    HRSRC32 hrsrc = FindResource32A( instance, name, (LPSTR)RT_MENU );
+    HRSRC32 hrsrc = FindResource32A( instance, name, RT_MENU32A );
     if (!hrsrc) return 0;
     return LoadMenuIndirect32A( (LPCVOID)LoadResource32( instance, hrsrc ));
 }
 
 
 /*****************************************************************
- *        LoadMenu32W   (USER32.372)
+ *        LoadMenu32W   (USER32.373)
  */
 HMENU32 WINAPI LoadMenu32W( HINSTANCE32 instance, LPCWSTR name )
 {
-    HRSRC32 hrsrc = FindResource32W( instance, name, (LPWSTR)RT_MENU );
+    HRSRC32 hrsrc = FindResource32W( instance, name, RT_MENU32W );
     if (!hrsrc) return 0;
     return LoadMenuIndirect32W( (LPCVOID)LoadResource32( instance, hrsrc ));
 }
@@ -3649,7 +3649,7 @@
 
 
 /**********************************************************************
- *	    LoadMenuIndirect32A    (USER32.370)
+ *	    LoadMenuIndirect32A    (USER32.371)
  */
 HMENU32 WINAPI LoadMenuIndirect32A( LPCVOID template )
 {
@@ -3690,7 +3690,7 @@
 
 
 /**********************************************************************
- *	    LoadMenuIndirect32W    (USER32.371)
+ *	    LoadMenuIndirect32W    (USER32.372)
  */
 HMENU32 WINAPI LoadMenuIndirect32W( LPCVOID template )
 {
@@ -3710,7 +3710,7 @@
 
 
 /**********************************************************************
- *		IsMenu32    (USER32.345)
+ *		IsMenu32    (USER32.346)
  */
 BOOL32 WINAPI IsMenu32(HMENU32 hmenu)
 {
@@ -3775,7 +3775,7 @@
 }
 
 /**********************************************************************
- *		GetMenuItemInfo32A    (USER32.263)
+ *		GetMenuItemInfo32A    (USER32.264)
  */
 BOOL32 WINAPI GetMenuItemInfo32A( HMENU32 hmenu, UINT32 item, BOOL32 bypos,
                                   LPMENUITEMINFO32A lpmii)
@@ -3784,7 +3784,7 @@
 }
 
 /**********************************************************************
- *		GetMenuItemInfo32W    (USER32.264)
+ *		GetMenuItemInfo32W    (USER32.265)
  */
 BOOL32 WINAPI GetMenuItemInfo32W( HMENU32 hmenu, UINT32 item, BOOL32 bypos,
                                   LPMENUITEMINFO32W lpmii)
@@ -3840,7 +3840,7 @@
 }
 
 /**********************************************************************
- *		SetMenuItemInfo32A    (USER32.490)
+ *		SetMenuItemInfo32A    (USER32.491)
  */
 BOOL32 WINAPI SetMenuItemInfo32A(HMENU32 hmenu, UINT32 item, BOOL32 bypos,
                                  const MENUITEMINFO32A *lpmii) 
@@ -3850,7 +3850,7 @@
 }
 
 /**********************************************************************
- *		SetMenuItemInfo32W    (USER32.491)
+ *		SetMenuItemInfo32W    (USER32.492)
  */
 BOOL32 WINAPI SetMenuItemInfo32W(HMENU32 hmenu, UINT32 item, BOOL32 bypos,
                                  const MENUITEMINFO32W *lpmii)
@@ -3860,7 +3860,7 @@
 }
 
 /**********************************************************************
- *		SetMenuDefaultItem32    (USER32.488)
+ *		SetMenuDefaultItem32    (USER32.489)
  */
 BOOL32 WINAPI SetMenuDefaultItem32(HMENU32 hmenu, UINT32 item, BOOL32 bypos)
 {
@@ -3900,7 +3900,7 @@
 
 
 /**********************************************************************
- *		InsertMenuItem32A    (USER32.322)
+ *		InsertMenuItem32A    (USER32.323)
  */
 BOOL32 WINAPI InsertMenuItem32A(HMENU32 hMenu, UINT32 uItem, BOOL32 bypos,
                                 const MENUITEMINFO32A *lpmii)
@@ -3911,7 +3911,7 @@
 
 
 /**********************************************************************
- *		InsertMenuItem32W    (USER32.323)
+ *		InsertMenuItem32W    (USER32.324)
  */
 BOOL32 WINAPI InsertMenuItem32W(HMENU32 hMenu, UINT32 uItem, BOOL32 bypos,
                                 const MENUITEMINFO32W *lpmii)
diff --git a/controls/progress.c b/controls/progress.c
index 38812a0..80a2fc4 100644
--- a/controls/progress.c
+++ b/controls/progress.c
@@ -5,8 +5,6 @@
  *
  * TODO:
  *   - I do not know what to to on WM_[SG]ET_FONT
- * Problems:
- *   - I think I do not compute correctly the numer of leds to be drawn
  */
 
 #include <stdlib.h>
@@ -21,7 +19,6 @@
 
 /* Control configuration constants */
 
-#define LED_WIDTH  8
 #define LED_GAP    2
 
 /* Work constants */
@@ -41,8 +38,8 @@
 static void PROGRESS_Paint(WND *wndPtr, HDC32 dc)
 {
   PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(wndPtr);
-  HBRUSH32 ledBrush;
-  int rightBar, rightMost;
+  HBRUSH32 hbrBar, hbrBk;
+  int rightBar, rightMost, ledWidth;
   PAINTSTRUCT32 ps;
   RECT32 rect;
   HDC32 hdc;
@@ -53,29 +50,90 @@
   /* get a dc */
   hdc = dc==0 ? BeginPaint32(wndPtr->hwndSelf, &ps) : dc;
 
-  /* get the required brush */
-  ledBrush = GetSysColorBrush32(COLOR_HIGHLIGHT);
+  /* get the required bar brush */
+  if (infoPtr->ColorBar == CLR_DEFAULT)
+    hbrBar = GetSysColorBrush32(COLOR_HIGHLIGHT);
+  else
+    hbrBar = CreateSolidBrush32 (infoPtr->ColorBar);
+
+  /* get the required background brush */
+  if (infoPtr->ColorBk != CLR_DEFAULT)
+    hbrBk = CreateSolidBrush32 (infoPtr->ColorBk);
+  else
+    hbrBk = 0; /* to keep the compiler happy ;-) */
 
   /* get rect for the bar, adjusted for the border */
-  GetClientRect32(wndPtr->hwndSelf, &rect);
+  GetClientRect32 (wndPtr->hwndSelf, &rect);
+
+  /* Hack because of missing top border */
+  rect.top++;
 
   /* draw the border */
-  DrawEdge32(hdc, &rect, BDR_SUNKENOUTER, BF_RECT|BF_ADJUST|BF_MIDDLE);
+  if (infoPtr->ColorBk == CLR_DEFAULT)
+    DrawEdge32(hdc, &rect, BDR_SUNKENOUTER, BF_RECT|BF_ADJUST|BF_MIDDLE);
+  else
+  {
+    DrawEdge32(hdc, &rect, BDR_SUNKENOUTER, BF_RECT|BF_ADJUST);
+    FillRect32(hdc, &rect, hbrBk);
+  }
   rect.left++; rect.right--; rect.top++; rect.bottom--;
-  rightMost = rect.right;
 
   /* compute extent of progress bar */
-  rightBar = rect.left + 
-    MulDiv32(infoPtr->CurVal-infoPtr->MinVal,
-	     rect.right - rect.left,
-	     infoPtr->MaxVal-infoPtr->MinVal);
+  if (wndPtr->dwStyle & PBS_VERTICAL)
+  {
+    rightBar = rect.bottom - 
+      MulDiv32(infoPtr->CurVal-infoPtr->MinVal,
+	       rect.bottom - rect.top,
+	       infoPtr->MaxVal-infoPtr->MinVal);
+    ledWidth = MulDiv32 ((rect.right - rect.left), 2, 3);
+    rightMost = rect.top;
+  }
+  else
+  {
+    rightBar = rect.left + 
+      MulDiv32(infoPtr->CurVal-infoPtr->MinVal,
+	       rect.right - rect.left,
+	       infoPtr->MaxVal-infoPtr->MinVal);
+    ledWidth = MulDiv32 ((rect.bottom - rect.top), 2, 3);
+    rightMost = rect.right;
+  }
 
   /* now draw the bar */
-  while(rect.left < rightBar) { 
-    rect.right = rect.left+LED_WIDTH;
-    FillRect32(hdc, &rect, ledBrush);
-    rect.left  = rect.right+LED_GAP;
+  if (wndPtr->dwStyle & PBS_SMOOTH)
+  {
+    if (wndPtr->dwStyle & PBS_VERTICAL)
+      rect.top = rightBar;
+    else
+      rect.right = rightBar;
+    FillRect32(hdc, &rect, hbrBar);
   }
+  else
+  {
+    if (wndPtr->dwStyle & PBS_VERTICAL)
+      while(rect.bottom > rightBar) { 
+        rect.top = rect.bottom-ledWidth;
+        if (rect.top < rightMost)
+          rect.top = rightMost;
+        FillRect32(hdc, &rect, hbrBar);
+        rect.bottom = rect.top-LED_GAP;
+      }
+    else
+      while(rect.left < rightBar) { 
+        rect.right = rect.left+ledWidth;
+        if (rect.right > rightMost)
+          rect.right = rightMost;
+        FillRect32(hdc, &rect, hbrBar);
+        rect.left  = rect.right+LED_GAP;
+      }
+  }
+
+  /* delete bar brush */
+  if (infoPtr->ColorBar != CLR_DEFAULT)
+      DeleteObject32 (hbrBar);
+
+  /* delete background brush */
+  if (infoPtr->ColorBk != CLR_DEFAULT)
+      DeleteObject32 (hbrBk);
 
   /* clean-up */  
   if(!dc)
@@ -114,6 +172,8 @@
       infoPtr->MaxVal=100;
       infoPtr->CurVal=0; 
       infoPtr->Step=10;
+      infoPtr->ColorBar=CLR_DEFAULT;
+      infoPtr->ColorBk=CLR_DEFAULT;
       TRACE(updown, "Progress Ctrl creation, hwnd=%04x\n", hwnd);
       break;
     
@@ -145,7 +205,9 @@
       if(wParam != 0){
 	infoPtr->CurVal += (UINT16)wParam;
 	PROGRESS_CoercePos(wndPtr);
-	PROGRESS_Paint(wndPtr, 0);
+        InvalidateRect32 (hwnd, NULL, FALSE);
+        UpdateWindow32 (hwnd);
+//	PROGRESS_Paint(wndPtr, 0);
       }
       return temp;
 
@@ -156,7 +218,8 @@
       if(temp != wParam){
 	infoPtr->CurVal = (UINT16)wParam;
 	PROGRESS_CoercePos(wndPtr);
-	PROGRESS_Paint(wndPtr, 0);
+        InvalidateRect32 (hwnd, NULL, FALSE);
+        UpdateWindow32 (hwnd);
       }
       return temp;          
       
@@ -170,7 +233,8 @@
 	if(infoPtr->MaxVal <= infoPtr->MinVal)
 	  infoPtr->MaxVal = infoPtr->MinVal+1;
 	PROGRESS_CoercePos(wndPtr);
-	PROGRESS_Paint(wndPtr, 0);
+        InvalidateRect32 (hwnd, NULL, FALSE);
+        UpdateWindow32 (hwnd);
       }
       return temp;
 
@@ -189,9 +253,54 @@
       if(infoPtr->CurVal > infoPtr->MaxVal)
 	infoPtr->CurVal = infoPtr->MinVal;
       if(temp != infoPtr->CurVal)
-	PROGRESS_Paint(wndPtr, 0);
+      {
+        InvalidateRect32 (hwnd, NULL, FALSE);
+        UpdateWindow32 (hwnd);
+      }
+      return temp;
+
+    case PBM_SETRANGE32:
+      temp = MAKELONG(infoPtr->MinVal, infoPtr->MaxVal);
+      if((infoPtr->MinVal != (INT32)wParam) ||
+         (infoPtr->MaxVal != (INT32)lParam)) {
+	infoPtr->MinVal = (INT32)wParam;
+	infoPtr->MaxVal = (INT32)lParam;
+	if(infoPtr->MaxVal <= infoPtr->MinVal)
+	  infoPtr->MaxVal = infoPtr->MinVal+1;
+	PROGRESS_CoercePos(wndPtr);
+        InvalidateRect32 (hwnd, NULL, FALSE);
+        UpdateWindow32 (hwnd);
+      }
       return temp;
     
+    case PBM_GETRANGE:
+      if (lParam){
+        ((PPBRANGE)lParam)->iLow = infoPtr->MinVal;
+        ((PPBRANGE)lParam)->iHigh = infoPtr->MaxVal;
+      }
+      return (wParam) ? infoPtr->MinVal : infoPtr->MaxVal;
+
+    case PBM_GETPOS:
+      if (wParam || lParam)
+	UNKNOWN_PARAM(PBM_STEPIT, wParam, lParam);
+      return (infoPtr->CurVal);
+
+    case PBM_SETBARCOLOR:
+      if (wParam)
+	UNKNOWN_PARAM(PBM_SETBARCOLOR, wParam, lParam);
+      infoPtr->ColorBar = (COLORREF)lParam;     
+      InvalidateRect32 (hwnd, NULL, FALSE);
+      UpdateWindow32 (hwnd);
+      break;
+
+    case PBM_SETBKCOLOR:
+      if (wParam)
+	UNKNOWN_PARAM(PBM_SETBKCOLOR, wParam, lParam);
+      infoPtr->ColorBk = (COLORREF)lParam;
+      InvalidateRect32 (hwnd, NULL, FALSE);
+      UpdateWindow32 (hwnd);
+      break;
+
     default: 
       if (message >= WM_USER) 
 	ERR(progress, "unknown msg %04x wp=%04x lp=%08lx\n", 
@@ -202,5 +311,3 @@
     return 0;
 }
 
-
-
diff --git a/controls/scroll.c b/controls/scroll.c
index 8e5a366..ec71eb4 100644
--- a/controls/scroll.c
+++ b/controls/scroll.c
@@ -81,18 +81,18 @@
  */
 static void SCROLL_LoadBitmaps(void)
 {
-    hUpArrow  = LoadBitmap32A( 0, MAKEINTRESOURCE(OBM_UPARROW) );
-    hDnArrow  = LoadBitmap32A( 0, MAKEINTRESOURCE(OBM_DNARROW) );
-    hLfArrow  = LoadBitmap32A( 0, MAKEINTRESOURCE(OBM_LFARROW) );
-    hRgArrow  = LoadBitmap32A( 0, MAKEINTRESOURCE(OBM_RGARROW) );
-    hUpArrowD = LoadBitmap32A( 0, MAKEINTRESOURCE(OBM_UPARROWD) );
-    hDnArrowD = LoadBitmap32A( 0, MAKEINTRESOURCE(OBM_DNARROWD) );
-    hLfArrowD = LoadBitmap32A( 0, MAKEINTRESOURCE(OBM_LFARROWD) );
-    hRgArrowD = LoadBitmap32A( 0, MAKEINTRESOURCE(OBM_RGARROWD) );
-    hUpArrowI = LoadBitmap32A( 0, MAKEINTRESOURCE(OBM_UPARROWI) );
-    hDnArrowI = LoadBitmap32A( 0, MAKEINTRESOURCE(OBM_DNARROWI) );
-    hLfArrowI = LoadBitmap32A( 0, MAKEINTRESOURCE(OBM_LFARROWI) );
-    hRgArrowI = LoadBitmap32A( 0, MAKEINTRESOURCE(OBM_RGARROWI) );
+    hUpArrow  = LoadBitmap32A( 0, MAKEINTRESOURCE32A(OBM_UPARROW) );
+    hDnArrow  = LoadBitmap32A( 0, MAKEINTRESOURCE32A(OBM_DNARROW) );
+    hLfArrow  = LoadBitmap32A( 0, MAKEINTRESOURCE32A(OBM_LFARROW) );
+    hRgArrow  = LoadBitmap32A( 0, MAKEINTRESOURCE32A(OBM_RGARROW) );
+    hUpArrowD = LoadBitmap32A( 0, MAKEINTRESOURCE32A(OBM_UPARROWD) );
+    hDnArrowD = LoadBitmap32A( 0, MAKEINTRESOURCE32A(OBM_DNARROWD) );
+    hLfArrowD = LoadBitmap32A( 0, MAKEINTRESOURCE32A(OBM_LFARROWD) );
+    hRgArrowD = LoadBitmap32A( 0, MAKEINTRESOURCE32A(OBM_RGARROWD) );
+    hUpArrowI = LoadBitmap32A( 0, MAKEINTRESOURCE32A(OBM_UPARROWI) );
+    hDnArrowI = LoadBitmap32A( 0, MAKEINTRESOURCE32A(OBM_DNARROWI) );
+    hLfArrowI = LoadBitmap32A( 0, MAKEINTRESOURCE32A(OBM_LFARROWI) );
+    hRgArrowI = LoadBitmap32A( 0, MAKEINTRESOURCE32A(OBM_RGARROWI) );
 }
 
 
@@ -1018,7 +1018,7 @@
 
 
 /*************************************************************************
- *           GetScrollInfo32   (USER32.283)
+ *           GetScrollInfo32   (USER32.284)
  */
 BOOL32 WINAPI GetScrollInfo32( HWND32 hwnd, INT32 nBar, LPSCROLLINFO info )
 {
@@ -1082,7 +1082,7 @@
 
 
 /*************************************************************************
- *           GetScrollPos32   (USER32.284)
+ *           GetScrollPos32   (USER32.285)
  */
 INT32 WINAPI GetScrollPos32( HWND32 hwnd, INT32 nBar )
 {
@@ -1171,7 +1171,7 @@
 
 
 /*************************************************************************
- *           GetScrollRange32   (USER32.285)
+ *           GetScrollRange32   (USER32.286)
  */
 BOOL32 WINAPI GetScrollRange32( HWND32 hwnd, INT32 nBar,
                                 LPINT32 lpMin, LPINT32 lpMax)
@@ -1200,7 +1200,7 @@
 
 
 /*************************************************************************
- *           ShowScrollBar32   (USER32.531)
+ *           ShowScrollBar32   (USER32.532)
  */
 BOOL32 WINAPI ShowScrollBar32( HWND32 hwnd, INT32 nBar, BOOL32 fShow )
 {
@@ -1276,7 +1276,7 @@
 
 
 /*************************************************************************
- *           EnableScrollBar32   (USER32.170)
+ *           EnableScrollBar32   (USER32.171)
  */
 BOOL32 WINAPI EnableScrollBar32( HWND32 hwnd, INT32 nBar, UINT32 flags )
 {
diff --git a/controls/uitools.c b/controls/uitools.c
index 4354426..dd58668 100644
--- a/controls/uitools.c
+++ b/controls/uitools.c
@@ -558,7 +558,7 @@
 }
 
 /**********************************************************************
- *          DrawEdge32   (USER32.154)
+ *          DrawEdge32   (USER32.155)
  */
 BOOL32 WINAPI DrawEdge32( HDC32 hdc, LPRECT32 rc, UINT32 edge, UINT32 flags )
 {
@@ -1364,7 +1364,7 @@
 
 
 /**********************************************************************
- *          DrawFrameControl32  (USER32.157)
+ *          DrawFrameControl32  (USER32.158)
  */
 BOOL32 WINAPI DrawFrameControl32( HDC32 hdc, LPRECT32 rc, UINT32 uType,
                                   UINT32 uState )
diff --git a/controls/updown.c b/controls/updown.c
index e3b95cb..83e2a6d 100644
--- a/controls/updown.c
+++ b/controls/updown.c
@@ -105,7 +105,7 @@
 }
 
 /***********************************************************************
- *           UPDOWN_GetArrawRect
+ *           UPDOWN_GetArrowRect
  * wndPtr   - pointer to the up-down wnd
  * rect     - will hold the rectangle
  * incr     - TRUE  get the "increment" rect (up or right)
@@ -759,6 +759,22 @@
 		     infoPtr->MinVal, infoPtr->MaxVal, hwnd);
       break;                             
 
+    case UDM_GETRANGE32:
+      if (wParam)
+	*(LPINT32)wParam = infoPtr->MinVal;
+      if (lParam)
+	*(LPINT32)lParam = infoPtr->MaxVal;
+      break;
+
+    case UDM_SETRANGE32:
+      infoPtr->MinVal = (INT32)wParam;
+      infoPtr->MaxVal = (INT32)lParam;
+      if (infoPtr->MaxVal <= infoPtr->MinVal)
+	infoPtr->MaxVal = infoPtr->MinVal + 1;
+      TRACE(updown, "UpDown Ctrl new range(%d to %d), hwnd=%04x\n", 
+		     infoPtr->MinVal, infoPtr->MaxVal, hwnd);
+      break;
+
     default: 
       if (message >= WM_USER) 
 	WARN(updown, "unknown msg %04x wp=%04x lp=%08lx\n", 
diff --git a/controls/widgets.c b/controls/widgets.c
index b8fcfc4..daa89d9 100644
--- a/controls/widgets.c
+++ b/controls/widgets.c
@@ -38,40 +38,45 @@
 {
     /* BIC32_BUTTON */
     { CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC,
-      ButtonWndProc, 0, sizeof(BUTTONINFO), 0, 0, IDC_ARROW, 0, 0, "Button" },
+      ButtonWndProc, 0, sizeof(BUTTONINFO), 0, 0,
+      (HCURSOR32)IDC_ARROW32A, 0, 0, "Button" },
     /* BIC32_EDIT */
     { CS_GLOBALCLASS | CS_DBLCLKS /*| CS_PARENTDC*/,
-      EditWndProc, 0, sizeof(void *), 0, 0, IDC_IBEAM, 0, 0, "Edit" },
+      EditWndProc, 0, sizeof(void *), 0, 0,
+      (HCURSOR32)IDC_IBEAM32A, 0, 0, "Edit" },
     /* BIC32_LISTBOX */
     { CS_GLOBALCLASS | CS_DBLCLKS /*| CS_PARENTDC*/,
-      ListBoxWndProc, 0, sizeof(void *), 0, 0, IDC_ARROW, 0, 0, "ListBox" },
+      ListBoxWndProc, 0, sizeof(void *), 0, 0,
+      (HCURSOR32)IDC_ARROW32A, 0, 0, "ListBox" },
     /* BIC32_COMBO */
     { CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, 
-      ComboWndProc, 0, sizeof(void *), 0, 0, IDC_ARROW, 0, 0, "ComboBox" },
+      ComboWndProc, 0, sizeof(void *), 0, 0,
+      (HCURSOR32)IDC_ARROW32A, 0, 0, "ComboBox" },
     /* BIC32_COMBOLB */
-    { CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS,
-      ComboLBWndProc, 0, sizeof(void *), 0, 0, IDC_ARROW, 0, 0, "ComboLBox" },
+    { CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS, ComboLBWndProc,
+      0, sizeof(void *), 0, 0, (HCURSOR32)IDC_ARROW32A, 0, 0, "ComboLBox" },
     /* BIC32_POPUPMENU */
-    { CS_GLOBALCLASS | CS_SAVEBITS, PopupMenuWndProc, 0,
-      sizeof(HMENU32), 0, 0, IDC_ARROW, NULL_BRUSH, 0, POPUPMENU_CLASS_NAME },
+    { CS_GLOBALCLASS | CS_SAVEBITS, PopupMenuWndProc, 0, sizeof(HMENU32),
+      0, 0, (HCURSOR32)IDC_ARROW32A, NULL_BRUSH, 0, POPUPMENU_CLASS_NAME },
     /* BIC32_STATIC */
     { CS_GLOBALCLASS | CS_PARENTDC, StaticWndProc,
-      0, sizeof(STATICINFO), 0, 0, IDC_ARROW, 0, 0, "Static" },
+      0, sizeof(STATICINFO), 0, 0, (HCURSOR32)IDC_ARROW32A, 0, 0, "Static" },
     /* BIC32_SCROLL */
     { CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC,
-      ScrollBarWndProc, 0, sizeof(SCROLLBAR_INFO), 0, 0, IDC_ARROW, 0, 0, "ScrollBar"},
+      ScrollBarWndProc, 0, sizeof(SCROLLBAR_INFO), 0, 0,
+      (HCURSOR32)IDC_ARROW32A, 0, 0, "ScrollBar"},
     /* BIC32_MDICLIENT */
     { CS_GLOBALCLASS, MDIClientWndProc,
       0, sizeof(MDICLIENTINFO), 0, 0, 0, STOCK_LTGRAY_BRUSH, 0, "MDIClient" },
     /* BIC32_DESKTOP */
     { CS_GLOBALCLASS, DesktopWndProc, 0, sizeof(DESKTOPINFO),
-      0, 0, IDC_ARROW, 0, 0, DESKTOP_CLASS_NAME },
+      0, 0, (HCURSOR32)IDC_ARROW32A, 0, 0, DESKTOP_CLASS_NAME },
     /* BIC32_DIALOG */
     { CS_GLOBALCLASS | CS_SAVEBITS, DefDlgProc32A, 0, DLGWINDOWEXTRA,
-      0, 0, IDC_ARROW, 0, 0, DIALOG_CLASS_NAME },
+      0, 0, (HCURSOR32)IDC_ARROW32A, 0, 0, DIALOG_CLASS_NAME },
     /* BIC32_ICONTITLE */
     { CS_GLOBALCLASS, IconTitleWndProc, 0, 0, 
-      0, 0, IDC_ARROW, 0, 0, ICONTITLE_CLASS_NAME }
+      0, 0, (HCURSOR32)IDC_ARROW32A, 0, 0, ICONTITLE_CLASS_NAME }
 };
 
 static ATOM bicAtomTable[BIC32_NB_CLASSES];
diff --git a/documentation/debugging b/documentation/debugging
index 7142179..3e2b5a2 100644
--- a/documentation/debugging
+++ b/documentation/debugging
@@ -83,7 +83,9 @@
  6. If that isn't enough add more debug output for yourself into the
     functions you find relevant.
     You might also try to run the program in gdb instead of using the
-    WINE-debugger.
+    WINE-debugger. If you don't use the "-desktop" or "-managed" option,
+    start the WINE process with "-sync", or chances are good to get X into
+    an unusable state.
   
  7. You can also set a breakpoint for that function. Start wine with the
     "-debug" option added to the commandline. After loading the executable
diff --git a/files/directory.c b/files/directory.c
index 12c2902..a780e36 100644
--- a/files/directory.c
+++ b/files/directory.c
@@ -4,6 +4,7 @@
  * Copyright 1995 Alexandre Julliard
  */
 
+#include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
@@ -20,18 +21,9 @@
 #include "options.h"
 #include "debug.h"
 
-#define MAX_PATH_ELEMENTS 20
+static DOS_FULL_NAME DIR_Windows;
+static DOS_FULL_NAME DIR_System;
 
-static char *DIR_WindowsDosDir;
-static char *DIR_WindowsUnixDir;
-static char *DIR_SystemDosDir;
-static char *DIR_SystemUnixDir;
-static char *DIR_TempDosDir;
-static char *DIR_TempUnixDir;
-
-static char *DIR_DosPath[MAX_PATH_ELEMENTS];  /* Path in DOS format */
-static char *DIR_UnixPath[MAX_PATH_ELEMENTS]; /* Path in Unix format */
-static int DIR_PathElements = 0;
 
 /***********************************************************************
  *           DIR_GetPath
@@ -39,78 +31,30 @@
  * Get a path name from the wine.ini file and make sure it is valid.
  */
 static int DIR_GetPath( const char *keyname, const char *defval,
-                        char **dos_path, char **unix_path )
+                        DOS_FULL_NAME *full_name )
 {
     char path[MAX_PATHNAME_LEN];
-    DOS_FULL_NAME full_name;
-
     BY_HANDLE_FILE_INFORMATION info;
 
     PROFILE_GetWineIniString( "wine", keyname, defval, path, sizeof(path) );
-    if (!DOSFS_GetFullName( path, TRUE, &full_name ) ||
-        !FILE_Stat( full_name.long_name, &info ) ||
+    if (!DOSFS_GetFullName( path, TRUE, full_name ) ||
+        !FILE_Stat( full_name->long_name, &info ) ||
         !(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
     {
-        fprintf(stderr, "Invalid path '%s' for %s directory\n", path, keyname);
+        MSG("Invalid path '%s' for %s directory\n", path, keyname);
         return 0;
     }
-    *unix_path = HEAP_strdupA( SystemHeap, 0, full_name.long_name );
-    *dos_path  = HEAP_strdupA( SystemHeap, 0, full_name.short_name );
     return 1;
 }
 
 
 /***********************************************************************
- *           DIR_ParseWindowsPath
- */
-void DIR_ParseWindowsPath( char *path )
-{
-    char *p;
-    DOS_FULL_NAME full_name;
-    BY_HANDLE_FILE_INFORMATION info;
-    int i;
-
-    for ( ; path && *path; path = p)
-    {
-        p = strchr( path, ';' );
-        if (p) while (*p == ';') *p++ = '\0';
-
-        if (DIR_PathElements >= MAX_PATH_ELEMENTS)
-        {
-            fprintf( stderr, "Warning: path has more than %d elements.\n",
-                     MAX_PATH_ELEMENTS );
-            break;
-        }
-        if (!DOSFS_GetFullName( path, TRUE, &full_name ) ||
-            !FILE_Stat( full_name.long_name, &info ) ||
-            !(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
-        {
-            fprintf(stderr,"Warning: invalid dir '%s' in path, deleting it.\n",
-                    path );
-            continue;
-        }
-        DIR_UnixPath[DIR_PathElements] = HEAP_strdupA( SystemHeap, 0,
-                                                       full_name.long_name );
-        DIR_DosPath[DIR_PathElements]  = HEAP_strdupA( SystemHeap, 0,
-                                                       full_name.short_name );
-        DIR_PathElements++;
-    }
-
-    if (TRACE_ON(dosfs))
-        for (i = 0; i < DIR_PathElements; i++)
-        {
-            TRACE(dosfs, "Path[%d]: %s = %s\n",
-                           i, DIR_DosPath[i], DIR_UnixPath[i] );
-        }
-}
-
-
-/***********************************************************************
  *           DIR_Init
  */
 int DIR_Init(void)
 {
-    char path[MAX_PATHNAME_LEN], *env_p;
+    char path[MAX_PATHNAME_LEN];
+    DOS_FULL_NAME tmp_dir;
     int drive;
     const char *cwd;
 
@@ -122,8 +66,8 @@
     cwd = path;
     if ((drive = DRIVE_FindDriveRoot( &cwd )) == -1)
     {
-        fprintf( stderr, "Warning: could not find DOS drive for cwd %s; starting in windows directory.\n",
-                 cwd );
+        MSG("Warning: could not find DOS drive for cwd %s; "
+	    "starting in windows directory.\n", cwd );
     }
     else
     {
@@ -131,50 +75,47 @@
         DRIVE_Chdir( drive, cwd );
     }
 
-    if (!(DIR_GetPath( "windows", "c:\\windows",
-                       &DIR_WindowsDosDir, &DIR_WindowsUnixDir ))) return 0;
-    if (!(DIR_GetPath( "system", "c:\\windows\\system",
-                       &DIR_SystemDosDir, &DIR_SystemUnixDir ))) return 0;
-    if (!(DIR_GetPath( "temp", "c:\\windows",
-                       &DIR_TempDosDir, &DIR_TempUnixDir ))) return 0;
-    if (-1==access(DIR_TempUnixDir,W_OK)) {
+    if (!(DIR_GetPath( "windows", "c:\\windows", &DIR_Windows )))
+        return 0;
+    if (!(DIR_GetPath( "system", "c:\\windows\\system", &DIR_System )))
+        return 0;
+    if (!(DIR_GetPath( "temp", "c:\\windows", &tmp_dir )))
+        return 0;
+    if (-1 == access( tmp_dir.long_name, W_OK ))
+    {
     	if (errno==EACCES)
-		fprintf(stderr,"Warning: The Temporary Directory (as specified in wine.conf) is NOT writeable. Please check your configuration.\n");
+		MSG("Warning: The Temporary Directory (as specified in wine.conf) is NOT writeable. Please check your configuration.\n");
 	else
-		fprintf(stderr,"Warning: Access to Temporary Directory failed (%s).\n",strerror(errno));
+		MSG("Warning: Access to Temporary Directory failed (%s).\n",
+		    strerror(errno));
     }
-   
+
     if (drive == -1)
     {
-        drive = DIR_WindowsDosDir[0] - 'A';
+        drive = DIR_Windows.drive;
         DRIVE_SetCurrentDrive( drive );
-        DRIVE_Chdir( drive, DIR_WindowsDosDir + 2 );
+        DRIVE_Chdir( drive, DIR_Windows.short_name + 2 );
     }
 
     PROFILE_GetWineIniString("wine", "path", "c:\\windows;c:\\windows\\system",
                              path, sizeof(path) );
-    DIR_ParseWindowsPath( path );
 
-    TRACE(dosfs, "WindowsDir = %s\n", DIR_WindowsDosDir);
-    TRACE(dosfs, "SystemDir  = %s\n", DIR_SystemDosDir);
-    TRACE(dosfs, "TempDir    = %s\n", DIR_TempDosDir);
+    /* Set the environment variables */
+
+    SetEnvironmentVariable32A( "PATH", path );
+    SetEnvironmentVariable32A( "TEMP", tmp_dir.short_name );
+    SetEnvironmentVariable32A( "windir", DIR_Windows.short_name );
+    SetEnvironmentVariable32A( "winsysdir", DIR_System.short_name );
+
+    TRACE(dosfs, "WindowsDir = %s (%s)\n",
+          DIR_Windows.short_name, DIR_Windows.long_name );
+    TRACE(dosfs, "SystemDir  = %s (%s)\n",
+          DIR_System.short_name, DIR_System.long_name );
+    TRACE(dosfs, "TempDir    = %s (%s)\n",
+          tmp_dir.short_name, tmp_dir.long_name );
+    TRACE(dosfs, "Path       = %s\n", path );
     TRACE(dosfs, "Cwd        = %c:\\%s\n",
-		 'A' + drive, DRIVE_GetDosCwd( drive ) );
-
-    /* Put the temp and Windows and system directories into the environment */
-
-    env_p = HEAP_xalloc( SystemHeap, 0, strlen(DIR_TempDosDir) + 6 );
-    strcpy( env_p, "TEMP=" );
-    strcpy( env_p + 5, DIR_TempDosDir );
-    putenv( env_p );
-    env_p = HEAP_xalloc( SystemHeap, 0, strlen(DIR_WindowsDosDir) + 8 );
-    strcpy( env_p, "windir=" );
-    strcpy( env_p + 7, DIR_WindowsDosDir );
-    putenv( env_p );
-    env_p = HEAP_xalloc( SystemHeap, 0, strlen(DIR_SystemDosDir) + 11 );
-    strcpy( env_p, "winsysdir=" );
-    strcpy( env_p + 10, DIR_SystemDosDir );
-    putenv( env_p );
+          'A' + drive, DRIVE_GetDosCwd( drive ) );
 
     return 1;
 }
@@ -185,8 +126,11 @@
  */
 UINT32 WINAPI GetTempPath32A( UINT32 count, LPSTR path )
 {
-    if (path) lstrcpyn32A( path, DIR_TempDosDir, count );
-    return strlen( DIR_TempDosDir );
+    UINT32 ret;
+    if (!(ret = GetEnvironmentVariable32A( "TMP", path, count )))
+        if (!(ret = GetEnvironmentVariable32A( "TEMP", path, count )))
+            ret = GetCurrentDirectory32A( count, path );
+    return ret;
 }
 
 
@@ -195,18 +139,13 @@
  */
 UINT32 WINAPI GetTempPath32W( UINT32 count, LPWSTR path )
 {
-    if (path) lstrcpynAtoW( path, DIR_TempDosDir, count );
-    return strlen( DIR_TempDosDir );
-}
-
-
-/***********************************************************************
- *           DIR_GetTempUnixDir
- */
-UINT32 DIR_GetTempUnixDir( LPSTR path, UINT32 count )
-{
-    if (path) lstrcpyn32A( path, DIR_TempUnixDir, count );
-    return strlen( DIR_TempUnixDir );
+    static const WCHAR tmp[]  = { 'T', 'M', 'P', 0 };
+    static const WCHAR temp[] = { 'T', 'E', 'M', 'P', 0 };
+    UINT32 ret;
+    if (!(ret = GetEnvironmentVariable32W( tmp, path, count )))
+        if (!(ret = GetEnvironmentVariable32W( temp, path, count )))
+            ret = GetCurrentDirectory32W( count, path );
+    return ret;
 }
 
 
@@ -215,8 +154,8 @@
  */
 UINT32 DIR_GetWindowsUnixDir( LPSTR path, UINT32 count )
 {
-    if (path) lstrcpyn32A( path, DIR_WindowsUnixDir, count );
-    return strlen( DIR_WindowsUnixDir );
+    if (path) lstrcpyn32A( path, DIR_Windows.long_name, count );
+    return strlen( DIR_Windows.long_name );
 }
 
 
@@ -225,19 +164,8 @@
  */
 UINT32 DIR_GetSystemUnixDir( LPSTR path, UINT32 count )
 {
-    if (path) lstrcpyn32A( path, DIR_SystemUnixDir, count );
-    return strlen( DIR_SystemUnixDir );
-}
-
-
-/***********************************************************************
- *           DIR_GetDosPath
- */
-UINT32 DIR_GetDosPath( INT32 element, LPSTR path, UINT32 count )
-{
-    if ((element < 0) || (element >= DIR_PathElements)) return 0;
-    if (path) lstrcpyn32A( path, DIR_DosPath[element], count );
-    return strlen( DIR_DosPath[element] );
+    if (path) lstrcpyn32A( path, DIR_System.long_name, count );
+    return strlen( DIR_System.long_name );
 }
 
 
@@ -246,8 +174,10 @@
  */
 BYTE WINAPI GetTempDrive( BYTE ignored )
 {
+    char buffer[2];
     /* FIXME: apparently Windows does something with the ignored byte */
-    return DIR_TempDosDir[0];
+    if (!GetTempPath32A( sizeof(buffer), buffer )) buffer[0] = 'C';
+    return toupper(buffer[0]) - 'A';
 }
 
 
@@ -279,8 +209,8 @@
  */
 UINT32 WINAPI GetWindowsDirectory32A( LPSTR path, UINT32 count )
 {
-    if (path) lstrcpyn32A( path, DIR_WindowsDosDir, count );
-    return strlen( DIR_WindowsDosDir );
+    if (path) lstrcpyn32A( path, DIR_Windows.short_name, count );
+    return strlen( DIR_Windows.short_name );
 }
 
 
@@ -289,8 +219,8 @@
  */
 UINT32 WINAPI GetWindowsDirectory32W( LPWSTR path, UINT32 count )
 {
-    if (path) lstrcpynAtoW( path, DIR_WindowsDosDir, count );
-    return strlen( DIR_WindowsDosDir );
+    if (path) lstrcpynAtoW( path, DIR_Windows.short_name, count );
+    return strlen( DIR_Windows.short_name );
 }
 
 
@@ -308,8 +238,8 @@
  */
 UINT32 WINAPI GetSystemDirectory32A( LPSTR path, UINT32 count )
 {
-    if (path) lstrcpyn32A( path, DIR_SystemDosDir, count );
-    return strlen( DIR_SystemDosDir );
+    if (path) lstrcpyn32A( path, DIR_System.short_name, count );
+    return strlen( DIR_System.short_name );
 }
 
 
@@ -318,8 +248,8 @@
  */
 UINT32 WINAPI GetSystemDirectory32W( LPWSTR path, UINT32 count )
 {
-    if (path) lstrcpynAtoW( path, DIR_SystemDosDir, count );
-    return strlen( DIR_SystemDosDir );
+    if (path) lstrcpynAtoW( path, DIR_System.short_name, count );
+    return strlen( DIR_System.short_name );
 }
 
 
@@ -443,11 +373,11 @@
  *
  * Helper function for DIR_SearchPath.
  */
-static BOOL32 DIR_TryPath( LPCSTR unix_dir, LPCSTR dos_dir, LPCSTR name,
+static BOOL32 DIR_TryPath( const DOS_FULL_NAME *dir, LPCSTR name,
                            DOS_FULL_NAME *full_name )
 {
-    LPSTR p_l = full_name->long_name + strlen(unix_dir) + 1;
-    LPSTR p_s = full_name->short_name + strlen(dos_dir) + 1;
+    LPSTR p_l = full_name->long_name + strlen(dir->long_name) + 1;
+    LPSTR p_s = full_name->short_name + strlen(dir->short_name) + 1;
 
     if ((p_s >= full_name->short_name + sizeof(full_name->short_name) - 14) ||
         (p_l >= full_name->long_name + sizeof(full_name->long_name) - 1))
@@ -455,19 +385,57 @@
         DOS_ERROR( ER_PathNotFound, EC_NotFound, SA_Abort, EL_Disk );
         return FALSE;
     }
-    if (!DOSFS_FindUnixName( unix_dir, name, p_l,
+    if (!DOSFS_FindUnixName( dir->long_name, name, p_l,
                    sizeof(full_name->long_name) - (p_l - full_name->long_name),
-                   p_s, DRIVE_GetFlags( dos_dir[0] - 'A' ) ))
+                   p_s, DRIVE_GetFlags( dir->drive ) ))
         return FALSE;
-    strcpy( full_name->long_name, unix_dir );
+    strcpy( full_name->long_name, dir->long_name );
     p_l[-1] = '/';
-    strcpy( full_name->short_name, dos_dir );
+    strcpy( full_name->short_name, dir->short_name );
     p_s[-1] = '\\';
     return TRUE;
 }
 
 
 /***********************************************************************
+ *           DIR_TryEnvironmentPath
+ *
+ * Helper function for DIR_SearchPath.
+ */
+static BOOL32 DIR_TryEnvironmentPath( LPCSTR name, DOS_FULL_NAME *full_name )
+{
+    LPSTR path, next, buffer;
+    BOOL32 ret = FALSE;
+    INT32 len = strlen(name);
+    DWORD size = GetEnvironmentVariable32A( "PATH", NULL, 0 );
+
+    if (!size) return FALSE;
+    if (!(path = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE;
+    if (!GetEnvironmentVariable32A( "PATH", path, size )) goto done;
+    next = path;
+    while (!ret && next)
+    {
+        LPSTR cur = next;
+        while (*cur == ';') cur++;
+        if (!*cur) break;
+        next = strchr( cur, ';' );
+        if (next) *next++ = '\0';
+        if (!(buffer = HeapAlloc( GetProcessHeap(), 0, strlen(cur) + len + 2)))
+            goto done;
+        strcpy( buffer, cur );
+        strcat( buffer, "\\" );
+        strcat( buffer, name );
+        ret = DOSFS_GetFullName( buffer, TRUE, full_name );
+        HeapFree( GetProcessHeap(), 0, buffer );
+    }
+
+done:
+    HeapFree( GetProcessHeap(), 0, path );
+    return ret;
+}
+
+
+/***********************************************************************
  *           DIR_TryModulePath
  *
  * Helper function for DIR_SearchPath.
@@ -501,7 +469,6 @@
 {
     DWORD len;
     LPCSTR p;
-    int i;
     LPSTR tmp = NULL;
     BOOL32 ret = TRUE;
 
@@ -558,12 +525,12 @@
 
     /* Try the Windows directory */
 
-    if (DIR_TryPath( DIR_WindowsUnixDir, DIR_WindowsDosDir, name, full_name ))
+    if (DIR_TryPath( &DIR_Windows, name, full_name ))
         goto done;
 
     /* Try the Windows system directory */
 
-    if (DIR_TryPath( DIR_SystemUnixDir, DIR_SystemDosDir, name, full_name ))
+    if (DIR_TryPath( &DIR_System, name, full_name ))
         goto done;
 
     /* Try the path of the current executable (for Win16 search order) */
@@ -572,13 +539,8 @@
 
     /* Try all directories in path */
 
-    for (i = 0; i < DIR_PathElements; i++)
-    {
-        if (DIR_TryPath( DIR_UnixPath[i], DIR_DosPath[i], name, full_name ))
-            goto done;
-    }
+    ret = DIR_TryEnvironmentPath( name, full_name );
 
-    ret = FALSE;
 done:
     if (tmp) HeapFree( GetProcessHeap(), 0, tmp );
     return ret;
diff --git a/files/dos_fs.c b/files/dos_fs.c
index 8ca3fb9..e7b5a4f 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -5,6 +5,7 @@
  * Copyright 1996 Alexandre Julliard
  */
 
+#include "config.h"
 #include <sys/types.h>
 #include <ctype.h>
 #include <dirent.h>
@@ -17,8 +18,8 @@
 #include <sys/ioctl.h>
 #include <time.h>
 #include <unistd.h>
-#if defined(__svr4__) || defined(_SCO_DS)
-#include <sys/statfs.h>
+#ifdef HAVE_SYS_STATFS_H
+# include <sys/statfs.h>
 #endif
 
 #include "windows.h"
@@ -646,8 +647,7 @@
     {
         if ((drive = DRIVE_FindDriveRoot( name )) == -1)
         {
-            fprintf( stderr, "Warning: %s not accessible from a DOS drive\n",
-                     *name );
+            MSG("Warning: %s not accessible from a DOS drive\n", *name );
             /* Assume it really was a DOS name */
             drive = DRIVE_GetCurrentDrive();            
         }
@@ -1335,7 +1335,7 @@
        Claus Fischer, fischer@iue.tuwien.ac.at
        */
 
-#if __GNUC__
+#if (SIZEOF_LONG_LONG >= 8)
 #  define USE_LONG_LONG 1
 #else
 #  define USE_LONG_LONG 0
diff --git a/files/drive.c b/files/drive.c
index 68dfeb6..47b543d 100644
--- a/files/drive.c
+++ b/files/drive.c
@@ -5,6 +5,8 @@
  * Copyright 1996 Alexandre Julliard
  */
 
+#include "config.h"
+
 #include <assert.h>
 #include <ctype.h>
 #include <string.h>
@@ -12,17 +14,19 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <errno.h>
 
-#if defined(__linux__) || defined(sun) || defined(hpux)
-#include <sys/vfs.h>
+#ifdef HAVE_SYS_VFS_H
+# include <sys/vfs.h>
 #endif
-#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
-#include <sys/param.h>
-#include <sys/mount.h>
-#include <sys/errno.h>
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
 #endif
-#if defined(__svr4__) || defined(_SCO_DS) || defined(__EMX__)
-#include <sys/statfs.h>
+#ifdef HAVE_SYS_MOUNT_H
+# include <sys/mount.h>
+#endif
+#ifdef HAVE_SYS_STATFS_H
+# include <sys/statfs.h>
 #endif
 
 #include "windows.h"
@@ -98,8 +102,7 @@
     {
         if (!lstrcmpi32A( buffer, DRIVE_Types[i] )) return (DRIVETYPE)i;
     }
-    fprintf( stderr, "%s: unknown type '%s', defaulting to 'hd'.\n",
-             name, buffer );
+    MSG("%s: unknown type '%s', defaulting to 'hd'.\n", name, buffer );
     return TYPE_HD;
 }
 
@@ -113,8 +116,8 @@
 
     for (descr = DRIVE_Filesystems; descr->name; descr++)
         if (!lstrcmpi32A( value, descr->name )) return descr->flags;
-    fprintf( stderr, "%s: unknown filesystem type '%s', defaulting to 'unix'.\n",
-             name, value );
+    MSG("%s: unknown filesystem type '%s', defaulting to 'unix'.\n",
+	name, value );
     return DRIVE_CASE_SENSITIVE | DRIVE_CASE_PRESERVING;
 }
 
@@ -143,14 +146,13 @@
 
             if (stat( path, &drive_stat_buffer ))
             {
-                fprintf( stderr, "Could not stat %s, ignoring drive %c:\n",
-                         path, 'A' + i );
+                MSG("Could not stat %s, ignoring drive %c:\n", path, 'A' + i );
                 continue;
             }
             if (!S_ISDIR(drive_stat_buffer.st_mode))
             {
-                fprintf( stderr, "%s is not a directory, ignoring drive %c:\n",
-                         path, 'A' + i );
+                MSG("%s is not a directory, ignoring drive %c:\n",
+		    path, 'A' + i );
                 continue;
             }
 
@@ -203,7 +205,7 @@
 
     if (!count) 
     {
-        fprintf( stderr, "Warning: no valid DOS drive found, check your configuration file.\n" );
+        MSG("Warning: no valid DOS drive found, check your configuration file.\n" );
         /* Create a C drive pointing to Unix root dir */
         DOSDrives[2].root     = HEAP_strdupA( SystemHeap, 0, "/" );
         DOSDrives[2].dos_cwd  = HEAP_strdupA( SystemHeap, 0, "" );
@@ -583,6 +585,7 @@
         return 0;
     }
 
+/* FIXME: add autoconf check for this */
 #if defined(__svr4__) || defined(_SCO_DS)
     if (statfs( DOSDrives[drive].root, &info, 0, 0) < 0)
 #else
@@ -590,15 +593,19 @@
 #endif
     {
         FILE_SetDosError();
-        fprintf(stderr,"dosfs: cannot do statfs(%s)\n", DOSDrives[drive].root);
+        WARN(dosfs, "cannot do statfs(%s)\n", DOSDrives[drive].root);
         return 0;
     }
 
     *size = info.f_bsize * info.f_blocks;
-#if defined(__svr4__) || defined(_SCO_DS) || defined(__EMX__)
-    *available = info.f_bfree * info.f_bsize;
-#else
+#ifdef STATFS_HAS_BAVAIL
     *available = info.f_bavail * info.f_bsize;
+#else
+# ifdef STATFS_HAS_BFREE
+    *available = info.f_bfree * info.f_bsize;
+# else
+#  error "statfs has no bfree/bavail member!"
+# endif
 #endif
     return 1;
 }
@@ -631,7 +638,7 @@
     {
         if ((root[1]) && ((root[1] != ':') || (root[2] != '\\')))
         {
-            fprintf( stderr, "GetDiskFreeSpaceA: invalid root '%s'\n", root );
+            WARN(dosfs, "invalid root '%s'\n", root );
             return FALSE;
         }
         drive = toupper(root[0]) - 'A';
@@ -653,7 +660,7 @@
     }
     /* fixme: probably have to adjust those variables too for CDFS */
     *cluster_sectors = 1;
-    while (*cluster_sectors * 65530 < size) *cluster_sectors *= 2;
+    while (*cluster_sectors * 65536 < size) *cluster_sectors *= 2;
     *free_clusters   = available/ *cluster_sectors;
     *total_clusters  = size/ *cluster_sectors;
     return TRUE;
@@ -694,8 +701,7 @@
     {
         if ((root[1]) && ((root[1] != ':') || (root[2] != '\\')))
         {
-            fprintf( stderr, "GetDiskFreeSpaceExA: invalid root '%s'\n",
-		     root );
+            WARN(dosfs, "invalid root '%s'\n", root );
             return FALSE;
         }
         drive = toupper(root[0]) - 'A';
@@ -755,7 +761,7 @@
     TRACE(dosfs, "(%s)\n", root );
     if ((root[1]) && (root[1] != ':'))
     {
-        fprintf( stderr, "GetDriveType32A: invalid root '%s'\n", root );
+        WARN(dosfs, "invalid root '%s'\n", root );
         return DRIVE_DOESNOTEXIST;
     }
     switch(DRIVE_GetType(toupper(root[0]) - 'A'))
@@ -949,7 +955,7 @@
     {
         if ((root[1]) && (root[1] != ':'))
         {
-            fprintf( stderr, "GetVolumeInformation: invalid root '%s'\n",root);
+            WARN(dosfs, "invalid root '%s'\n",root);
             return FALSE;
         }
         drive = toupper(root[0]) - 'A';
diff --git a/files/file.c b/files/file.c
index 1d6b97e..721f11a 100644
--- a/files/file.c
+++ b/files/file.c
@@ -89,8 +89,9 @@
     (*file)->unix_name = NULL;
     (*file)->type = FILE_TYPE_DISK;
 
-    handle = HANDLE_Alloc( &(*file)->header, FILE_ALL_ACCESS | GENERIC_READ |
-                           GENERIC_WRITE | GENERIC_EXECUTE /*FIXME*/, FALSE );
+    handle = HANDLE_Alloc( PROCESS_Current(), &(*file)->header,
+                           FILE_ALL_ACCESS | GENERIC_READ |
+                           GENERIC_WRITE | GENERIC_EXECUTE /*FIXME*/, TRUE );
     /* If the allocation failed, the object is already destroyed */
     if (handle == INVALID_HANDLE_VALUE32) *file = NULL;
     return handle;
@@ -187,7 +188,8 @@
  */
 static FILE_OBJECT *FILE_GetFile( HFILE32 handle )
 {
-    return (FILE_OBJECT *)HANDLE_GetObjPtr( handle, K32OBJ_FILE, 0 /*FIXME*/ );
+    return (FILE_OBJECT *)HANDLE_GetObjPtr( PROCESS_Current(), handle,
+                                            K32OBJ_FILE, 0 /*FIXME*/ );
 }
 
 
@@ -359,7 +361,7 @@
 		return ret;
 
 	/* Do not silence this please. It is a critical error. -MM */
-        fprintf(stderr, "FILE_Open: Couldn't open device '%s'!\n",path);
+        ERR(file, "Couldn't open device '%s'!\n",path);
         DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk );
         return HFILE_ERROR32;
 	
@@ -389,7 +391,7 @@
 
     if (DOSFS_IsDevice( path ))
     {
-        fprintf(stderr, "FILE_Create: cannot create DOS device '%s'!\n", path);
+        WARN(file, "cannot create DOS device '%s'!\n", path);
         DOS_ERROR( ER_AccessDenied, EC_NotFound, SA_Abort, EL_Disk );
         return INVALID_HANDLE_VALUE32;
     }
@@ -579,13 +581,12 @@
  */
 HFILE32 FILE_Dup( HFILE32 hFile )
 {
-    FILE_OBJECT *file;
     HFILE32 handle;
 
     TRACE(file, "FILE_Dup for handle %d\n", hFile );
-    if (!(file = FILE_GetFile( hFile ))) return HFILE_ERROR32;
-    handle = HANDLE_Alloc( &file->header, FILE_ALL_ACCESS /*FIXME*/, FALSE );
-    FILE_ReleaseFile( file );
+    if (!DuplicateHandle( GetCurrentProcess(), hFile, GetCurrentProcess(),
+                          &handle, FILE_ALL_ACCESS /* FIXME */, FALSE, 0 ))
+        handle = HFILE_ERROR32;
     TRACE(file, "FILE_Dup return handle %d\n", handle );
     return handle;
 }
@@ -603,7 +604,8 @@
     TRACE(file, "FILE_Dup2 for handle %d\n", hFile1 );
     /* FIXME: should use DuplicateHandle */
     if (!(file = FILE_GetFile( hFile1 ))) return HFILE_ERROR32;
-    if (!HANDLE_SetObjPtr( hFile2, &file->header, 0 )) hFile2 = HFILE_ERROR32;
+    if (!HANDLE_SetObjPtr( PROCESS_Current(), hFile2, &file->header, 0 ))
+        hFile2 = HFILE_ERROR32;
     FILE_ReleaseFile( file );
     return hFile2;
 }
@@ -624,8 +626,7 @@
         !DRIVE_IsValid( toupper(drive & ~TF_FORCEDRIVE) - 'A' ))
     {
         drive &= ~TF_FORCEDRIVE;
-        fprintf( stderr, "Warning: GetTempFileName: invalid drive %d specified\n",
-                 drive );
+        WARN(file, "invalid drive %d specified\n", drive );
     }
 
     if (drive & TF_FORCEDRIVE)
@@ -691,10 +692,8 @@
         /* Check if we have write access in the directory */
         if ((p = strrchr( full_name.long_name, '/' ))) *p = '\0';
         if (access( full_name.long_name, W_OK ) == -1)
-            fprintf( stderr,
-                     "Warning: GetTempFileName returns '%s', which doesn't seem to be writeable.\n"
-                     "Please check your configuration file if this generates a failure.\n",
-                     buffer);
+            WARN(file, "returns '%s', which doesn't seem to be writeable.\n",
+		 buffer);
     }
     TRACE(file, "returning %s\n", buffer );
     return unique ? unique : num;
@@ -745,8 +744,7 @@
     if (mode & OF_REOPEN) name = ofs->szPathName;
 
     if (!name) {
-	fprintf(stderr, "ERROR: FILE_DoOpenFile() called with `name' set to NULL ! Please debug.\n");
- 
+	ERR(file, "called with `name' set to NULL ! Please debug.\n");
 	return HFILE_ERROR32;
     }
 
@@ -930,7 +928,8 @@
     BOOL32 result = FALSE;
 
     TRACE( file, "%d %p %d\n", handle, buffer, count);
-    if (!(ptr = HANDLE_GetObjPtr( handle, K32OBJ_UNKNOWN, 0))) return -1;
+    if (!(ptr = HANDLE_GetObjPtr( PROCESS_Current(), handle,
+                                  K32OBJ_UNKNOWN, 0))) return -1;
     if (K32OBJ_OPS(ptr)->read)
         result = K32OBJ_OPS(ptr)->read(ptr, buffer, count, &numWritten, NULL);
     K32OBJ_DecCount( ptr );
@@ -992,12 +991,12 @@
 
     if (highword && *highword)
     {
-        fprintf( stderr, "SetFilePointer: 64-bit offsets not supported yet\n");
+        FIXME(file, "64-bit offsets not supported yet\n");
         SetLastError( ERROR_INVALID_PARAMETER );
         return 0xffffffff;
     }
     TRACE(file, "handle %d offset %ld origin %ld\n",
-                  hFile, distance, method );
+	  hFile, distance, method );
 
     if (!(file = FILE_GetFile( hFile ))) return 0xffffffff;
     switch(method)
@@ -1143,7 +1142,8 @@
 		}
 	}
 	
-	if (!(ioptr = HANDLE_GetObjPtr( handle, K32OBJ_UNKNOWN, 0 )))
+	if (!(ioptr = HANDLE_GetObjPtr( PROCESS_Current(), handle,
+                                        K32OBJ_UNKNOWN, 0 )))
             return HFILE_ERROR32;
         if (K32OBJ_OPS(ioptr)->write)
             status = K32OBJ_OPS(ioptr)->write(ioptr, buffer, count, &result, NULL);
@@ -1276,7 +1276,7 @@
 
     if (DOSFS_IsDevice( path ))
     {
-        fprintf(stderr, "DeleteFile: cannot remove DOS device '%s'!\n", path);
+        WARN(file, "cannot remove DOS device '%s'!\n", path);
         DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk );
         return FALSE;
     }
@@ -1347,7 +1347,7 @@
     LPVOID ret;
 
     if (size_high || offset_high)
-        fprintf( stderr, "FILE_mmap: offsets larger than 4Gb not supported\n");
+        FIXME(file, "offsets larger than 4Gb not supported\n");
 
     if (!file)
     {
@@ -1420,7 +1420,7 @@
 int FILE_munmap( LPVOID start, DWORD size_high, DWORD size_low )
 {
     if (size_high)
-      fprintf( stderr, "FILE_munmap: offsets larger than 4Gb not supported\n");
+      FIXME(file, "offsets larger than 4Gb not supported\n");
     return munmap( start, size_low );
 }
 
@@ -1470,8 +1470,7 @@
     else /* fn2 == NULL means delete source */
       if (flag & MOVEFILE_DELAY_UNTIL_REBOOT) {
 	if (flag & MOVEFILE_COPY_ALLOWED) {  
-	  fprintf( stderr,
-		   "MoveFileEx32A: Illegal flag\n");
+	  WARN(file, "Illegal flag\n");
 	  DOS_ERROR( ER_GeneralFailure, EC_SystemFailure, SA_Abort,
 		     EL_Unknown );
 	  return FALSE;
@@ -1480,11 +1479,8 @@
 	   Perhaps we should queue these command and execute it 
 	   when exiting... What about using on_exit(2)
 	   */
-	fprintf( stderr,"MoveFileEx32A: Please delete file %s\n",
-		 full_name1.long_name);
-	fprintf( stderr,"               when Wine has finished\n");
-	fprintf( stderr,"               like \"rm %s\"\n",
-		 full_name1.long_name);
+	FIXME(file, "Please delete file '%s' when Wine has finished\n",
+	      full_name1.long_name);
 	return TRUE;
       }
       else if (unlink( full_name1.long_name ) == -1)
@@ -1499,13 +1495,9 @@
 	   Perhaps we should queue these command and execute it 
 	   when exiting... What about using on_exit(2)
 	   */
-	fprintf( stderr,"MoveFileEx32A: Please move existing file %s\n"
-		 ,full_name1.long_name);
-	fprintf( stderr,"               to file %s\n"
-		 ,full_name2.long_name);
-	fprintf( stderr,"               when Wine has finished\n");
-	fprintf( stderr,"               like \" mv %s %s\"\n",
-		 full_name1.long_name,full_name2.long_name);
+	FIXME(file,"Please move existing file '%s' to file '%s'"
+	      "when Wine has finished\n", 
+	      full_name1.long_name, full_name2.long_name);
 	return TRUE;
     }
 
diff --git a/files/profile.c b/files/profile.c
index 29e2f06..123ab91 100644
--- a/files/profile.c
+++ b/files/profile.c
@@ -184,8 +184,8 @@
         {
             if (!(p2 = strrchr( p, ']' )))
             {
-                fprintf( stderr, "PROFILE_Load: Invalid section header at line %d: '%s'\n",
-                         line, p );
+                WARN(profile, "Invalid section header at line %d: '%s'\n",
+		     line, p );
             }
             else
             {
@@ -352,13 +352,11 @@
     
     if (!file)
     {
-        fprintf( stderr, "Warning: could not save profile file %s\n",
-                 CurProfile.dos_name );
+        WARN(profile, "could not save profile file %s\n", CurProfile.dos_name);
         return FALSE;
     }
 
-    TRACE(profile, "Saving '%s' into '%s'\n",
-                     CurProfile.dos_name, unix_name );
+    TRACE(profile, "Saving '%s' into '%s'\n", CurProfile.dos_name, unix_name );
     PROFILE_Save( file, CurProfile.section );
     fclose( file );
     CurProfile.changed = FALSE;
@@ -452,7 +450,7 @@
     else
     {
         /* Does not exist yet, we will create it in PROFILE_FlushFile */
-        fprintf( stderr, "Warning: profile file %s not found\n", newdos_name );
+        WARN(profile, "profile file %s not found\n", newdos_name );
     }
     return TRUE;
 }
@@ -479,6 +477,13 @@
                 PROFILE_CopyEntry( buffer, key->name, len - 1, handle_env );
                 len -= strlen(buffer) + 1;
                 buffer += strlen(buffer) + 1;
+                if (key->value)
+                {
+                    buffer[-1] = '=';
+                    PROFILE_CopyEntry(buffer, key->value, len - 1, handle_env);
+                    len -= strlen(buffer) + 1; 
+                    buffer += strlen(buffer) + 1;
+                }
             }
             *buffer = '\0';
             return oldlen - len + 1;
@@ -738,7 +743,7 @@
             return 1;
         }
     }
-    else fprintf( stderr, "Warning: could not get $HOME value for config file.\n" );
+    else WARN(profile, "could not get $HOME value for config file.\n" );
 
     /* Try global file */
 
@@ -748,8 +753,8 @@
         fclose( f );
         return 1;
     }
-    fprintf( stderr, "Can't open configuration file %s or $HOME%s\n",
-             WINE_INI_GLOBAL, PROFILE_WineIniName );
+    WARN(profile, "Can't open configuration file %s or $HOME%s\n",
+	 WINE_INI_GLOBAL, PROFILE_WineIniName );
     return 0;
 }
 
diff --git a/graphics/painting.c b/graphics/painting.c
index b6ac7d8..b343023 100644
--- a/graphics/painting.c
+++ b/graphics/painting.c
@@ -267,7 +267,7 @@
 
 
 /***********************************************************************
- *           FillRect32    (USER32.196)
+ *           FillRect32    (USER32.197)
  */
 INT32 WINAPI FillRect32( HDC32 hdc, const RECT32 *rect, HBRUSH32 hbrush )
 {
@@ -292,7 +292,7 @@
 
 
 /***********************************************************************
- *           InvertRect32    (USER32.329)
+ *           InvertRect32    (USER32.330)
  */
 void WINAPI InvertRect32( HDC32 hdc, const RECT32 *rect )
 {
@@ -337,7 +337,7 @@
 
 
 /***********************************************************************
- *           FrameRect32    (USER32.202)
+ *           FrameRect32    (USER32.203)
  */
 INT32 WINAPI FrameRect32( HDC32 hdc, const RECT32 *rect, HBRUSH32 hbrush )
 {
@@ -510,7 +510,7 @@
 
 
 /***********************************************************************
- *           DrawFocusRect32    (USER32.155)
+ *           DrawFocusRect32    (USER32.156)
  *
  * FIXME: PatBlt(PATINVERT) with background brush.
  */
diff --git a/graphics/win16drv/prtdrv.c b/graphics/win16drv/prtdrv.c
index b7fe5ff..9a7bde1 100644
--- a/graphics/win16drv/prtdrv.c
+++ b/graphics/win16drv/prtdrv.c
@@ -26,7 +26,7 @@
 static void GetPrinterDriverFunctions(HINSTANCE16 hInst, LOADED_PRINTER_DRIVER *pLPD)
 {
 #define LoadPrinterDrvFunc(A) pLPD->fn[FUNC_##A] = \
-      GetProcAddress16(hInst, MAKEINTRESOURCE(ORD_##A))
+      GetProcAddress16(hInst, MAKEINTRESOURCE16(ORD_##A))
 
       LoadPrinterDrvFunc(BITBLT);
       LoadPrinterDrvFunc(COLORINFO);
diff --git a/graphics/x11drv/graphics.c b/graphics/x11drv/graphics.c
index 083c6ba..ba8ec8a 100644
--- a/graphics/x11drv/graphics.c
+++ b/graphics/x11drv/graphics.c
@@ -5,8 +5,8 @@
  */
 
 #include <math.h>
-#if defined(__EMX__)
-#include <float.h>
+#ifdef HAVE_FLOAT_H
+# include <float.h>
 #endif
 #include <stdlib.h>
 #include "ts_xlib.h"
@@ -92,17 +92,32 @@
     yend   = YLPTODP( dc, yend );
     if ((left == right) || (top == bottom)) return FALSE;
 
+    if (left > right) { tmp=left; left=right; right=tmp; }
+    if (top > bottom) { tmp=top; top=bottom; bottom=tmp; } 
     xcenter = (right + left) / 2;
     ycenter = (bottom + top) / 2;
     start_angle = atan2( (double)(ycenter-ystart)*(right-left),
 			 (double)(xstart-xcenter)*(bottom-top) );
     end_angle   = atan2( (double)(ycenter-yend)*(right-left),
 			 (double)(xend-xcenter)*(bottom-top) );
+    if ((xstart==xend)&&(ystart==yend))
+      { /* A lazy program delivers xstart=xend=ystart=yend=0) */
+	start_angle = 0;
+	end_angle = 2* PI;
+      }
+    else /* notorious cases */
+      if ((start_angle == PI)&&( end_angle <0))
+	start_angle = - PI;
+    else
+      if ((end_angle == PI)&&( start_angle <0))
+	end_angle = - PI;
     istart_angle = (INT32)(start_angle * 180 * 64 / PI);
     idiff_angle  = (INT32)((end_angle - start_angle) * 180 * 64 / PI );
-    if (idiff_angle <= 0) idiff_angle += 360 * 64;
-    if (left > right) { tmp=left; left=right; right=tmp; }
-    if (top > bottom) { tmp=top; top=bottom; bottom=tmp; }
+    if (idiff_angle < 0) 
+      {
+	istart_angle+= idiff_angle;
+	idiff_angle = abs(idiff_angle);
+      }
 
       /* Fill arc with brush if Chord() or Pie() */
 
@@ -227,12 +242,14 @@
 
     if ((left == right) || (top == bottom))
     {
+#if 0
 	if (DC_SetupGCForPen( dc ))
 	    TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, 
 		  dc->w.DCOrgX + left,
 		  dc->w.DCOrgY + top,
 		  dc->w.DCOrgX + right,
 		  dc->w.DCOrgY + bottom);
+#endif
 	return TRUE;
     }
     width = dc->u.x.pen.width;
diff --git a/graphics/x11drv/text.c b/graphics/x11drv/text.c
index a056d95..f4a243c 100644
--- a/graphics/x11drv/text.c
+++ b/graphics/x11drv/text.c
@@ -13,6 +13,7 @@
 /*#include "callback.h"*/
 #include "heap.h"
 #include "x11font.h"
+#include "debugstr.h"
 #include "debug.h"
 
 #define SWAP_INT(a,b)  { int t = a; a = b; b = t; }
@@ -43,10 +44,16 @@
     lfUnderline = (pfo->fo_flags & FO_SYNTH_UNDERLINE) ? 1 : 0;
     lfStrikeOut = (pfo->fo_flags & FO_SYNTH_STRIKEOUT) ? 1 : 0;
 
-    TRACE(text,"hdc=%04x df=%04x %d,%d '%.*s', %d  flags=%d\n",
-                 dc->hSelf, (UINT16)(dc->u.x.font), x, y, (int)count, str, count, flags);
+    TRACE(text,"hdc=%04x df=%04x %d,%d %s, %d  flags=%d\n",
+	  dc->hSelf, (UINT16)(dc->u.x.font), x, y,
+	  debugstr_an (str, count), count, flags);
 
-    if (lprect != NULL) TRACE(text, "\trect=(%d,%d- %d,%d)\n",
+    /* some strings sent here end in a newline for whatever reason.  I have no
+       clue what the right treatment should be in general, but ignoring
+       terminating newlines seems ok.  MW, April 1998.  */
+    if (count > 0 && str[count - 1] == '\n') count--;
+
+    if (lprect != NULL) TRACE(text, "\trect=(%d,%d - %d,%d)\n",
                                      lprect->left, lprect->top,
                                      lprect->right, lprect->bottom );
       /* Setup coordinates */
@@ -85,7 +92,7 @@
     x = XLPTODP( dc, x );
     y = YLPTODP( dc, y );
 
-    TRACE(text,"\treal coord: x=%i, y=%i, rect=(%d,%d-%d,%d)\n",
+    TRACE(text,"\treal coord: x=%i, y=%i, rect=(%d,%d - %d,%d)\n",
 			  x, y, rect.left, rect.top, rect.right, rect.bottom);
 
       /* Draw the rectangle */
diff --git a/graphics/x11drv/xfont.c b/graphics/x11drv/xfont.c
index 01c547d..58093b0 100644
--- a/graphics/x11drv/xfont.c
+++ b/graphics/x11drv/xfont.c
@@ -2105,9 +2105,6 @@
 }
 
 
-static char* test_string = "Abc Def Ghi Jkl Mno Pqr Stu Vwx Yz";
-
-
 /***********************************************************************
  *           X11DRV_GetTextExtentPoint
  */
@@ -2213,7 +2210,7 @@
  */
 INT32 WINAPI AddFontResource32A( LPCSTR str )
 {
-    FIXME(font, "(%s): stub\n", debugres(str));
+    FIXME(font, "(%s): stub\n", debugres_a(str));
     return 1;
 }
 
@@ -2223,7 +2220,7 @@
  */
 INT32 WINAPI AddFontResource32W( LPCWSTR str )
 {
-    FIXME(font, "(%p): stub\n", str );
+    FIXME(font, "(%s): stub\n", debugres_w(str) );
     return 1;
 }
 
@@ -2232,7 +2229,7 @@
  */
 BOOL16 WINAPI RemoveFontResource16( SEGPTR str )
 {
-    FIXME(font, "(%s): stub\n",	debugres(PTR_SEG_TO_LIN(str)));
+    FIXME(font, "(%s): stub\n",	debugres_a(PTR_SEG_TO_LIN(str)));
     return TRUE;
 }
 
@@ -2242,7 +2239,7 @@
  */
 BOOL32 WINAPI RemoveFontResource32A( LPCSTR str )
 {
-    FIXME(font, "(%s): stub\n", debugres(str));
+    FIXME(font, "(%s): stub\n", debugres_a(str));
     return TRUE;
 }
 
@@ -2252,7 +2249,7 @@
  */
 BOOL32 WINAPI RemoveFontResource32W( LPCWSTR str )
 {
-    FIXME(font, "(%p): stub\n", str );
+    FIXME(font, "(%s): stub\n", debugres_w(str) );
     return TRUE;
 }
 
diff --git a/if1632/commdlg.spec b/if1632/commdlg.spec
index 9f8be62..aec5ffd 100644
--- a/if1632/commdlg.spec
+++ b/if1632/commdlg.spec
@@ -8,10 +8,10 @@
 7   pascal   FileSaveDlgProc(word word word long) FileSaveDlgProc
 8   pascal   ColorDlgProc(word word word long) ColorDlgProc
 #9   pascal  LOADALTERBITMAP exported, shared data
-11  pascal16 FindText(segptr) FindText
-12  pascal16 ReplaceText(segptr) ReplaceText
-13  pascal   FindTextDlgProc(word word word long) FindTextDlgProc
-14  pascal   ReplaceTextDlgProc(word word word long) ReplaceTextDlgProc
+11  pascal16 FindText(segptr) FindText16
+12  pascal16 ReplaceText(segptr) ReplaceText16
+13  pascal   FindTextDlgProc(word word word long) FindTextDlgProc16
+14  pascal   ReplaceTextDlgProc(word word word long) ReplaceTextDlgProc16
 15  pascal16 ChooseFont(ptr) ChooseFont
 16  pascal16 FormatCharDlgProc(word word word long) FormatCharDlgProc
 18  pascal16 FontStyleEnumProc(ptr ptr word long)   FontStyleEnumProc
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index 2b6c962..02bbbef 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -218,7 +218,7 @@
 305 stub ENGINEGETGLYPHBMP
 306 stub ENGINEMAKEFONTDIR
 307 pascal16 GetCharABCWidths(word word word ptr) GetCharABCWidths16
-308 stub GetOutLineTextMetrics
+308 pascal   GetOutlineTextMetrics(word word ptr) GetOutlineTextMetrics
 309 pascal   GetGlyphOutline(word word word ptr long ptr ptr) GetGlyphOutline16
 310 pascal16 CreateScalableFontResource(word str str str) CreateScalableFontResource16
 311 stub GetFontData
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index ab0ebdd..3e4ab9d 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -278,8 +278,8 @@
 355 pascal16 GetWinDebugInfo(ptr word) GetWinDebugInfo
 356 pascal16 SetWinDebugInfo(ptr) SetWinDebugInfo
 357 stub KERNEL_357
-358 pascal KERNEL_358(long) _KERNEL_358
-359 pascal KERNEL_359(long) _KERNEL_359
+358 pascal MapLS(long) MapLS
+359 pascal UnMapLS(ptr) UnMapLS
 360 stub OpenFileEx
 #361 PIGLET_361
 365 stub KERNEL_365
diff --git a/if1632/relay.c b/if1632/relay.c
index 0975e08..6a40aef 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -13,6 +13,7 @@
 #include "module.h"
 #include "stackframe.h"
 #include "task.h"
+#include "debugstr.h"
 #include "debug.h"
 
 #if 0
@@ -33,8 +34,10 @@
 
     extern void CALLTO16_Start(), CALLTO16_End();
     extern void CALLTO16_Ret_word(), CALLTO16_Ret_long();
+    extern void CALLTO16_Ret_eax();
     extern DWORD CALLTO16_RetAddr_word;
     extern DWORD CALLTO16_RetAddr_long;
+    extern DWORD CALLTO16_RetAddr_eax;
 
     codesel = GLOBAL_CreateBlock( GMEM_FIXED, (void *)CALLTO16_Start,
                                    (int)CALLTO16_End - (int)CALLTO16_Start,
@@ -47,6 +50,8 @@
                                     codesel );
     CALLTO16_RetAddr_long=MAKELONG( (int)CALLTO16_Ret_long-(int)CALLTO16_Start,
                                     codesel );
+    CALLTO16_RetAddr_eax =MAKELONG( (int)CALLTO16_Ret_eax -(int)CALLTO16_Start,
+                                    codesel );
 
     /* Create built-in modules */
     if (!BUILTIN_Init()) return FALSE;
@@ -56,19 +61,6 @@
 }
 
 
- 
-static void RELAY_dumpstr( unsigned char *s )
-{
-    fputc( '\"', stdout );
-    for ( ; *s; s++)
-    {
-        if (*s < ' ') printf( "\\0x%02x", *s );
-        else if (*s == '\\') fputs( "\\\\", stdout );
-        else fputc( *s, stdout );
-    }
-    fputc( '\"', stdout );
-}
-
 
 /***********************************************************************
  *           RELAY_DebugCallFrom16
@@ -107,7 +99,7 @@
             case 't':
                 printf( "%04x:%04x", *(WORD *)(args16+2), *(WORD *)args16 );
                 if (HIWORD(*(SEGPTR *)args16))
-                    RELAY_dumpstr( (LPBYTE)PTR_SEG_TO_LIN(*(SEGPTR *)args16 ));
+                    debug_dumpstr( (LPSTR)PTR_SEG_TO_LIN(*(SEGPTR *)args16 ));
                 args16 += 4;
                 break;
             case 'p':
@@ -117,7 +109,7 @@
             case 'T':
                 printf( "%04x:%04x", *(WORD *)(args16+2), *(WORD *)args16 );
                 if (HIWORD( *(SEGPTR *)args16 ))
-                    RELAY_dumpstr( (LPBYTE)PTR_SEG_TO_LIN(*(SEGPTR *)args16 ));
+                    debug_dumpstr( (LPSTR)PTR_SEG_TO_LIN(*(SEGPTR *)args16 ));
                 args16 += 4;
                 break;
             }
@@ -162,7 +154,7 @@
                 args16 -= 4;
                 printf( "0x%08x", *(int *)args16 );
                 if (HIWORD(*(SEGPTR *)args16))
-                    RELAY_dumpstr( (LPBYTE)PTR_SEG_TO_LIN(*(SEGPTR *)args16 ));
+                    debug_dumpstr( (LPSTR)PTR_SEG_TO_LIN(*(SEGPTR *)args16 ));
                 break;
             case 'p':
                 args16 -= 4;
@@ -172,7 +164,7 @@
                 args16 -= 4;
                 printf( "%04x:%04x", *(WORD *)(args16+2), *(WORD *)args16 );
                 if (HIWORD( *(SEGPTR *)args16 ))
-                    RELAY_dumpstr( (LPBYTE)PTR_SEG_TO_LIN(*(SEGPTR *)args16 ));
+                    debug_dumpstr( (LPSTR)PTR_SEG_TO_LIN(*(SEGPTR *)args16 ));
                 break;
             }
             args++;
diff --git a/if1632/signal.c b/if1632/signal.c
index 06a36d3..431565a 100644
--- a/if1632/signal.c
+++ b/if1632/signal.c
@@ -17,15 +17,6 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 
-#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__svr4__) || defined(_SCO_DS) || defined(__EMX__)
-# if !defined(_SCO_DS) && !defined(__EMX__)
-#  include <sys/syscall.h>
-# endif
-# include <sys/param.h>
-#else
-# include <syscall.h>
-#endif
-
 #include "debugger.h"
 #include "options.h"
 #include "sig_context.h"
diff --git a/if1632/user.spec b/if1632/user.spec
index 2335bdb..84b32e5 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -521,10 +521,10 @@
 821 stub TranslateMessage32	
 #821 stub IsDialogMessage32		# FIXME: two ordinal 821???
 822 stub DispatchMessage32
+823 stub CallMsgFilter32
 825 stub PostMessage32
 826 stub PostThreadMessage32
-827 stub MessageBoxIndirect
-823 stub CallMsgFilter32
+827 pascal16 MessageBoxIndirect(ptr) MessageBoxIndirect16
 851 stub MsgThkConnectionDataLS
 853 stub FT_USRFTHKTHKCONNECTIONDATA
 854 stub FT__USRF2THKTHKCONNECTIONDATA
diff --git a/if1632/wprocs.spec b/if1632/wprocs.spec
index ee24229..40fa9b5 100644
--- a/if1632/wprocs.spec
+++ b/if1632/wprocs.spec
@@ -4,8 +4,8 @@
 14 pascal FileOpenDlgProc(word word word long) FileOpenDlgProc
 15 pascal FileSaveDlgProc(word word word long) FileSaveDlgProc
 16 pascal ColorDlgProc(word word word long) ColorDlgProc
-17 pascal FindTextDlgProc(word word word long) FindTextDlgProc
-18 pascal ReplaceTextDlgProc(word word word long) ReplaceTextDlgProc
+17 pascal FindTextDlgProc(word word word long) FindTextDlgProc16
+18 pascal ReplaceTextDlgProc(word word word long) ReplaceTextDlgProc16
 19 pascal PrintSetupDlgProc(word word word long) PrintSetupDlgProc
 20 pascal PrintDlgProc(word word word long) PrintDlgProc
 24 pascal16 TASK_Reschedule() TASK_Reschedule
diff --git a/include/acconfig.h b/include/acconfig.h
index 512364b..45489fd 100644
--- a/include/acconfig.h
+++ b/include/acconfig.h
@@ -21,5 +21,8 @@
 /* Define if X libraries are not reentrant (compiled without -D_REENTRANT).  */
 #undef NO_REENTRANT_X11
 
-/* Define if you have machine/soundcard.h instead of sys/soundcard.h.  */
-#undef HAVE_MACHINE_SOUNDCARD_H
+/* Define if the struct statfs has the member bavail */
+#undef STATFS_HAS_BAVAIL
+
+/* Define if the struct statfs has the member bfree */
+#undef STATFS_HAS_BFREE
diff --git a/include/bitmaps/oic_bang_95 b/include/bitmaps/oic_bang_95
new file mode 100644
index 0000000..2233cf3
--- /dev/null
+++ b/include/bitmaps/oic_bang_95
@@ -0,0 +1,41 @@
+/* XPM */
+static char * oic_bang_95[] = {
+"32 32 6 1",
+" 	s None		c None",
+".	s black		c black",
+"X	s yellow	c yellow",
+"x	s dkgreen	c #008000",
+"o	s ltgray	c #c0c0c0",
+"O	s dkgray	c #808080",
+"             xxx                ",
+"            xXXo.               ",
+"           xXXXXo.O             ",
+"           xXXXXX.OO            ",
+"          xXXXXXXo.OO           ",
+"          xXXXXXXX.OO           ",
+"         xXXXXXXXXo.OO          ",
+"         xXXXXXXXXX.OO          ",
+"        xXXXXXXXXXXo.OO         ",
+"        xXXXo...oXXX.OO         ",
+"       xXXXX.....XXXo.OO        ",
+"       xXXXX.....XXXX.OO        ",
+"      xXXXXX.....XXXXo.OO       ",
+"      xXXXXX.....XXXXX.OO       ",
+"     xXXXXXX.....XXXXXo.OO      ",
+"     xXXXXXXx...xXXXXXX.OO      ",
+"    xXXXXXXXo...oXXXXXXo.OO     ",
+"    xXXXXXXXX...XXXXXXXX.OO     ",
+"   xXXXXXXXXXx.xXXXXXXXXo.OO    ",
+"   xXXXXXXXXXo.oXXXXXXXXX.OO    ",
+"  xXXXXXXXXXXX.XXXXXXXXXXo.OO   ",
+"  xXXXXXXXXXXXXXXXXXXXXXXX.OO   ",
+" xXXXXXXXXXXXo..oXXXXXXXXXo.OO  ",
+" xXXXXXXXXXXX....XXXXXXXXXX.OO  ",
+"xXXXXXXXXXXXX....XXXXXXXXXXo.OO ",
+"xXXXXXXXXXXXXo..oXXXXXXXXXXX.OO ",
+"xXXXXXXXXXXXXXXXXXXXXXXXXXXX.OOO",
+"xXXXXXXXXXXXXXXXXXXXXXXXXXXo.OOO",
+" xXXXXXXXXXXXXXXXXXXXXXXXXo.OOOO",
+"  x........................OOOOO",
+"    OOOOOOOOOOOOOOOOOOOOOOOOOOO ",
+"     OOOOOOOOOOOOOOOOOOOOOOOOO  "};
diff --git a/include/bitmaps/oic_hand_95 b/include/bitmaps/oic_hand_95
new file mode 100644
index 0000000..9265a66
--- /dev/null
+++ b/include/bitmaps/oic_hand_95
@@ -0,0 +1,40 @@
+/* XPM */
+static char * oic_hand_95[] = {
+"32 32 5 1",
+" 	s None	 c None",
+"o	s white	 c white",
+"O	s dkgray c #808080",
+"+	s dkred  c #800000",
+"X	s red	 c red",
+"           ++++++++             ",
+"        +++XXXXXXXX+++          ",
+"       +XXXXXXXXXXXXXX+         ",
+"     ++XXXXXXXXXXXXXXXX++       ",
+"    +XXXXXXXXXXXXXXXXXXXX+      ",
+"   +XXXXXXXXXXXXXXXXXXXXXX+     ",
+"   +XXXXXXXXXXXXXXXXXXXXXX+O    ",
+"  +XXXXXXoXXXXXXXXXXoXXXXXX+O   ",
+" +XXXXXXoooXXXXXXXXoooXXXXXX+   ",
+" +XXXXXoooooXXXXXXoooooXXXXX+O  ",
+" +XXXXXXoooooXXXXoooooXXXXXX+OO ",
+"+XXXXXXXXoooooXXoooooXXXXXXXX+O ",
+"+XXXXXXXXXooooooooooXXXXXXXXX+O ",
+"+XXXXXXXXXXooooooooXXXXXXXXXX+OO",
+"+XXXXXXXXXXXooooooXXXXXXXXXXX+OO",
+"+XXXXXXXXXXXooooooXXXXXXXXXXX+OO",
+"+XXXXXXXXXXooooooooXXXXXXXXXX+OO",
+"+XXXXXXXXXooooooooooXXXXXXXXX+OO",
+"+XXXXXXXXoooooXXoooooXXXXXXXX+OO",
+" +XXXXXXoooooXXXXoooooXXXXXX+OOO",
+" +XXXXXoooooXXXXXXoooooXXXXX+OOO",
+" +XXXXXXoooXXXXXXXXoooXXXXXX+OO ",
+"  +XXXXXXoXXXXXXXXXXoXXXXXX+OOO ",
+"   +XXXXXXXXXXXXXXXXXXXXXX+OOOO ",
+"   +XXXXXXXXXXXXXXXXXXXXXX+OOO  ",
+"    +XXXXXXXXXXXXXXXXXXXX+OOO   ",
+"     ++XXXXXXXXXXXXXXXX++OOOO   ",
+"      O+XXXXXXXXXXXXXX+OOOOO    ",
+"       O+++XXXXXXXX+++OOOOO     ",
+"         OO++++++++OOOOOO       ",
+"          OOOOOOOOOOOOOO        ",
+"             OOOOOOOO           "};
diff --git a/include/bitmaps/oic_note_95 b/include/bitmaps/oic_note_95
new file mode 100644
index 0000000..4b80207
--- /dev/null
+++ b/include/bitmaps/oic_note_95
@@ -0,0 +1,41 @@
+/* XPM */
+static char * oic_note_95[] = {
+"32 32 6 1",
+" 	s None	 c None",
+".	s black	 c black",
+"X	s white	 c white",
+"o	s ltgray c #c0c0c0",
+"O	s dkgray c #808080",
+"x	s blue   c blue",
+"           OOOOOOOO             ",
+"        OOOoXXXXXXoOOO          ",
+"      OOoXXXXXXXXXXXXoOO        ",
+"     OoXXXXXXXXXXXXXXXXoO       ",
+"    OXXXXXXXXXXXXXXXXXXXX.      ",
+"   OXXXXXXXXoxxxxoXXXXXXXX.     ",
+"  OXXXXXXXXXxxxxxxXXXXXXXXX.    ",
+" OoXXXXXXXXXxxxxxxXXXXXXXXXo.   ",
+" OXXXXXXXXXXoxxxxoXXXXXXXXXX.O  ",
+"OoXXXXXXXXXXXXXXXXXXXXXXXXXXo.O ",
+"OXXXXXXXXXXXXXXXXXXXXXXXXXXXX.O ",
+"OXXXXXXXXXXxxxxxxxXXXXXXXXXXX.OO",
+"OXXXXXXXXXXXXxxxxxXXXXXXXXXXX.OO",
+"OXXXXXXXXXXXXxxxxxXXXXXXXXXXX.OO",
+"OXXXXXXXXXXXXxxxxxXXXXXXXXXXX.OO",
+"OXXXXXXXXXXXXxxxxxXXXXXXXXXXo.OO",
+" OXXXXXXXXXXXxxxxxXXXXXXXXXX.OOO",
+" OoXXXXXXXXXXxxxxxXXXXXXXXXo.OOO",
+"  OXXXXXXXXXXxxxxxXXXXXXXXX.OOO ",
+"   .XXXXXXXxxxxxxxxxXXXXXX.OOOO ",
+"    .XXXXXXXXXXXXXXXXXXXX.OOOO  ",
+"     .oXXXXXXXXXXXXXXXXo.OOOO   ",
+"      ..oXXXXXXXXXXXXo..OOOO    ",
+"       O...oXXXXXXo...OOOO      ",
+"        OOO...oXXX.OOOOOO       ",
+"          OOOO.XXX.OOOOO        ",
+"             O.XXX.OO           ",
+"               .XX.OO           ",
+"                .X.OO           ",
+"                 ..OO           ",
+"                  OOO           ",
+"                   OO           "};
diff --git a/include/bitmaps/oic_ques_95 b/include/bitmaps/oic_ques_95
new file mode 100644
index 0000000..6aa874d
--- /dev/null
+++ b/include/bitmaps/oic_ques_95
@@ -0,0 +1,41 @@
+/* XPM */
+static char * oic_ques_95[] = {
+"32 32 6 1",
+" 	s None	 c None",
+".	s black	 c black",
+"X	s white	 c white",
+"o	s ltgray c #c0c0c0",
+"O	s dkgray c #808080",
+"x	s blue   c blue",
+"           OOOOOOOO             ",
+"        OOOoXXXXXXoOOO          ",
+"      OOoXXXXXXXXXXXXoOO        ",
+"     OoXXXXXXXXXXXXXXXXoO       ",
+"    OXXXXXXXXXXXXXXXXXXXX.      ",
+"   OXXXXXXXoxxxxxxoXXXXXXX.     ",
+"  OXXXXXXXoxoXXxxxxoXXXXXXX.    ",
+" OoXXXXXXXxxXXXXxxxxXXXXXXXo.   ",
+" OXXXXXXXXxxxxXXxxxxXXXXXXXX.O  ",
+"OoXXXXXXXXxxxxXXxxxxXXXXXXXXo.O ",
+"OXXXXXXXXXoxxoXxxxxXXXXXXXXXX.O ",
+"OXXXXXXXXXXXXXoxxxXXXXXXXXXXX.OO",
+"OXXXXXXXXXXXXXxxxXXXXXXXXXXXX.OO",
+"OXXXXXXXXXXXXXxxoXXXXXXXXXXXX.OO",
+"OXXXXXXXXXXXXXxxXXXXXXXXXXXXX.OO",
+"OXXXXXXXXXXXXXXXXXXXXXXXXXXXo.OO",
+" OXXXXXXXXXXXoxxoXXXXXXXXXXX.OOO",
+" OoXXXXXXXXXXxxxxXXXXXXXXXXo.OOO",
+"  OXXXXXXXXXXxxxxXXXXXXXXXX.OOO ",
+"   .XXXXXXXXXoxxoXXXXXXXXX.OOOO ",
+"    .XXXXXXXXXXXXXXXXXXXX.OOOO  ",
+"     .oXXXXXXXXXXXXXXXXo.OOOO   ",
+"      ..oXXXXXXXXXXXXo..OOOO    ",
+"       O...oXXXXXXo...OOOO      ",
+"        OOO...oXXX.OOOOOO       ",
+"          OOOO.XXX.OOOOO        ",
+"             O.XXX.OO           ",
+"               .XX.OO           ",
+"                .X.OO           ",
+"                 ..OO           ",
+"                  OOO           ",
+"                   OO           "};
diff --git a/include/commctrl.h b/include/commctrl.h
index 33404f5..2ed95f6 100644
--- a/include/commctrl.h
+++ b/include/commctrl.h
@@ -24,6 +24,13 @@
 #define CCS_NOMOVEX         (CCS_VERT|CCS_NOMOVEY)
 
 
+/* common control shared messages */
+
+#define CCM_FIRST           0x2000
+
+#define CCM_SETBKCOLOR      (CCM_FIRST+1)     // lParam = bkColor
+
+
 /* StatusWindow */
 
 #define STATUSCLASSNAME16     "msctls_statusbar"
@@ -93,6 +100,9 @@
 #define UDM_GETACCEL       (WM_USER+108)
 #define UDM_SETBASE        (WM_USER+109)
 #define UDM_GETBASE        (WM_USER+110)
+#define UDM_SETRANGE32     (WM_USER+111)
+#define UDM_GETRANGE32     (WM_USER+112)
+
 
 /* Progress Bar */
 
@@ -107,6 +117,21 @@
 #define PBM_DELTAPOS        (WM_USER+3)
 #define PBM_SETSTEP         (WM_USER+4)
 #define PBM_STEPIT          (WM_USER+5)
+#define PBM_SETRANGE32      (WM_USER+6)
+#define PBM_GETRANGE        (WM_USER+7)
+#define PBM_GETPOS          (WM_USER+8)
+#define PBM_SETBARCOLOR     (WM_USER+9)
+#define PBM_SETBKCOLOR      CCM_SETBKCOLOR
+
+#define PBS_SMOOTH          0x01
+#define PBS_VERTICAL        0x04
+
+typedef struct
+{
+  INT32 iLow;
+  INT32 iHigh;
+} PBRANGE, *PPBRANGE;
+
  
 /* Functions prototypes */
 
diff --git a/include/commdlg.h b/include/commdlg.h
index e5ca4f6..126b940 100644
--- a/include/commdlg.h
+++ b/include/commdlg.h
@@ -150,9 +150,41 @@
 	LPARAM 		lCustData;              /* data passed to hook fn.  */
         WNDPROC16       lpfnHook;
 	SEGPTR 		lpTemplateName;         /* custom template name     */
-	} FINDREPLACE;
-typedef FINDREPLACE *LPFINDREPLACE;
+	} FINDREPLACE16, *LPFINDREPLACE16;
 
+typedef struct {
+	DWORD		lStructSize;
+	HWND32		hwndOwner;
+	HINSTANCE32	hInstance;
+
+	DWORD		Flags;
+	LPSTR		lpstrFindWhat;
+	LPSTR		lpstrReplaceWith;
+	WORD		wFindWhatLen;
+	WORD 		wReplaceWithLen;
+	LPARAM 		lCustData;
+        WNDPROC32       lpfnHook;
+	LPCSTR 		lpTemplateName;
+	} FINDREPLACE32A, *LPFINDREPLACE32A;
+
+typedef struct {
+	DWORD		lStructSize;
+	HWND32		hwndOwner;
+	HINSTANCE32	hInstance;
+
+	DWORD		Flags;
+	LPWSTR		lpstrFindWhat;
+	LPWSTR		lpstrReplaceWith;
+	WORD		wFindWhatLen;
+	WORD 		wReplaceWithLen;
+	LPARAM 		lCustData;
+        WNDPROC32       lpfnHook;
+	LPCWSTR		lpTemplateName;
+	} FINDREPLACE32W, *LPFINDREPLACE32W;
+	
+DECL_WINELIB_TYPE_AW(FINDREPLACE);
+DECL_WINELIB_TYPE_AW(LPFINDREPLACE);
+	
 #define FR_DOWN                         0x00000001
 #define FR_WHOLEWORD                    0x00000002
 #define FR_MATCHCASE                    0x00000004
@@ -393,7 +425,10 @@
 
 BOOL16  WINAPI ChooseColor(LPCHOOSECOLOR lpChCol);
 DWORD   WINAPI CommDlgExtendedError(void);
-HWND16  WINAPI FindText( SEGPTR find);
+HWND16  WINAPI FindText16( SEGPTR find);
+HWND32  WINAPI FindText32A(LPFINDREPLACE32A lpFind);
+HWND32  WINAPI FindText32W(LPFINDREPLACE32W lpFind);
+#define FindText WINELIB_NAME_AW(FindText)
 INT16   WINAPI GetFileTitle16(LPCSTR lpFile, LPSTR lpTitle, UINT16 cbBuf);
 INT16   WINAPI GetFileTitle32A(LPCSTR lpFile, LPSTR lpTitle, UINT32 cbBuf);
 INT16   WINAPI GetFileTitle32W(LPCWSTR lpFile, LPWSTR lpTitle, UINT32 cbBuf);
@@ -407,13 +442,22 @@
 BOOL32  WINAPI GetSaveFileName32W(LPOPENFILENAME32W ofn);
 #define GetSaveFileName WINELIB_NAME_AW(GetSaveFileName)
 BOOL16  WINAPI PrintDlg( SEGPTR print);
-HWND16  WINAPI ReplaceText( SEGPTR find);
+HWND16  WINAPI ReplaceText16( SEGPTR find);
+HWND32  WINAPI ReplaceText32A( LPFINDREPLACE32A lpFind);
+HWND32  WINAPI ReplaceText32W( LPFINDREPLACE32W lpFind);
+#define ReplaceText WINELIB_NAME_AW(ReplaceText)
 BOOL16  WINAPI ChooseFont(LPCHOOSEFONT lpChFont);
 LRESULT WINAPI FileOpenDlgProc(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam, LPARAM lParam);
 LRESULT WINAPI FileSaveDlgProc(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam, LPARAM lParam);
 LRESULT WINAPI ColorDlgProc(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam, LPARAM lParam);
-LRESULT WINAPI FindTextDlgProc(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam, LPARAM lParam);
-LRESULT WINAPI ReplaceTextDlgProc(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam, LPARAM lParam);
+LRESULT WINAPI FindTextDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam, LPARAM lParam);
+LRESULT WINAPI FindTextDlgProc32A(HWND32 hWnd, UINT32 wMsg, WPARAM32 wParam, LPARAM lParam);
+LRESULT WINAPI FindTextDlgProc32W(HWND32 hWnd, UINT32 wMsg, WPARAM32 wParam, LPARAM lParam);
+#define FindTextDlgProc WINELIB_NAME_AW(FindTextDlgProc)
+LRESULT WINAPI ReplaceTextDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam, LPARAM lParam);
+LRESULT WINAPI ReplaceTextDlgProc32A(HWND32 hWnd, UINT32 wMsg, WPARAM32 wParam, LPARAM lParam);
+LRESULT WINAPI ReplaceTextDlgProc32W(HWND32 hWnd, UINT32 wMsg, WPARAM32 wParam, LPARAM lParam);
+#define ReplaceTextProc WINELIB_NAME_AW(ReplaceTextDlgProc)
 LRESULT WINAPI PrintDlgProc(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam, LPARAM lParam);
 LRESULT WINAPI PrintSetupDlgProc(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam, LPARAM lParam);
 LRESULT WINAPI FormatCharDlgProc(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam, LPARAM lParam);
diff --git a/include/compobj.h b/include/compobj.h
index 6925b1e..ecd57eb 100644
--- a/include/compobj.h
+++ b/include/compobj.h
@@ -24,8 +24,7 @@
 
 OLESTATUS WINAPI WINE_StringFromCLSID(const CLSID *id, LPSTR);
 
-OLESTATUS WINAPI StringFromGUID2(const REFGUID *id, LPOLESTR32 *str, INT32 cmax);
-// #define StringFromGUID2 WINELIB_NAME(StringFromGUID2)
+INT32 WINAPI StringFromGUID2(REFGUID id, LPOLESTR32 str, INT32 cmax);
 
 
 #ifdef INITGUID
diff --git a/include/config.h.in b/include/config.h.in
index de3ec65..26f0a8f 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -33,15 +33,27 @@
 /* Define if X libraries are not reentrant (compiled without -D_REENTRANT).  */
 #undef NO_REENTRANT_X11
 
-/* Define if you have machine/soundcard.h instead of sys/soundcard.h.  */
-#undef HAVE_MACHINE_SOUNDCARD_H
+/* Define if the struct statfs has the member bavail */
+#undef STATFS_HAS_BAVAIL
+
+/* Define if the struct statfs has the member bfree */
+#undef STATFS_HAS_BFREE
+
+/* The number of bytes in a long long.  */
+#undef SIZEOF_LONG_LONG
 
 /* Define if you have the clone function.  */
 #undef HAVE_CLONE
 
+/* Define if you have the getpagesize function.  */
+#undef HAVE_GETPAGESIZE
+
 /* Define if you have the memmove function.  */
 #undef HAVE_MEMMOVE
 
+/* Define if you have the sigaltstack function.  */
+#undef HAVE_SIGALTSTACK
+
 /* Define if you have the strerror function.  */
 #undef HAVE_STRERROR
 
@@ -60,6 +72,42 @@
 /* Define if you have the waitpid function.  */
 #undef HAVE_WAITPID
 
+/* Define if you have the <float.h> header file.  */
+#undef HAVE_FLOAT_H
+
+/* Define if you have the <linux/cdrom.h> header file.  */
+#undef HAVE_LINUX_CDROM_H
+
+/* Define if you have the <machine/soundcard.h> header file.  */
+#undef HAVE_MACHINE_SOUNDCARD_H
+
+/* Define if you have the <sys/cdio.h> header file.  */
+#undef HAVE_SYS_CDIO_H
+
+/* Define if you have the <sys/filio.h> header file.  */
+#undef HAVE_SYS_FILIO_H
+
+/* Define if you have the <sys/mount.h> header file.  */
+#undef HAVE_SYS_MOUNT_H
+
+/* Define if you have the <sys/param.h> header file.  */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <sys/soundcard.h> header file.  */
+#undef HAVE_SYS_SOUNDCARD_H
+
+/* Define if you have the <sys/statfs.h> header file.  */
+#undef HAVE_SYS_STATFS_H
+
+/* Define if you have the <sys/syscall.h> header file.  */
+#undef HAVE_SYS_SYSCALL_H
+
+/* Define if you have the <sys/vfs.h> header file.  */
+#undef HAVE_SYS_VFS_H
+
+/* Define if you have the <syscall.h> header file.  */
+#undef HAVE_SYSCALL_H
+
 /* Define if you have the <wctype.h> header file.  */
 #undef HAVE_WCTYPE_H
 
diff --git a/include/ddraw.h b/include/ddraw.h
index f22fb36..f17f035 100644
--- a/include/ddraw.h
+++ b/include/ddraw.h
@@ -1049,48 +1049,49 @@
 
 typedef struct IDirectDrawSurface3_VTable {
     /*** IUnknown methods ***/
-    STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE;
-    STDMETHOD_(ULONG,AddRef) (THIS)  PURE;
-    STDMETHOD_(ULONG,Release) (THIS) PURE;
+/*00*/STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE;
+/*04*/STDMETHOD_(ULONG,AddRef) (THIS)  PURE;
+/*08*/STDMETHOD_(ULONG,Release) (THIS) PURE;
     /*** IDirectDrawSurface methods ***/
-    STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE3) PURE;
-    STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT32) PURE;
-    STDMETHOD(Blt)(THIS_ LPRECT32,LPDIRECTDRAWSURFACE3, LPRECT32,DWORD, LPDDBLTFX) PURE;
-    STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH, DWORD, DWORD ) PURE;
-    STDMETHOD(BltFast)(THIS_ DWORD,DWORD,LPDIRECTDRAWSURFACE3, LPRECT32,DWORD) PURE;
-    STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD,LPDIRECTDRAWSURFACE3) PURE;
-    STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID,LPDDENUMSURFACESCALLBACK) PURE;    STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD,LPVOID,LPDDENUMSURFACESCALLBACK) PURE;
-    STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE3, DWORD) PURE;
-    STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS, LPDIRECTDRAWSURFACE3 FAR *) PURE;
-    STDMETHOD(GetBltStatus)(THIS_ DWORD) PURE;
-    STDMETHOD(GetCaps)(THIS_ LPDDSCAPS) PURE;
-    STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER FAR*) PURE;
-    STDMETHOD(GetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE;
-    STDMETHOD(GetDC)(THIS_ HDC32 FAR *) PURE;
-    STDMETHOD(GetFlipStatus)(THIS_ DWORD) PURE;
-    STDMETHOD(GetOverlayPosition)(THIS_ LPLONG, LPLONG ) PURE;
-    STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE FAR*) PURE;
-    STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT) PURE;
-    STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC) PURE;
-    STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, LPDDSURFACEDESC) PURE;
-    STDMETHOD(IsLost)(THIS) PURE;
-    STDMETHOD(Lock)(THIS_ LPRECT32,LPDDSURFACEDESC,DWORD,HANDLE32) PURE;
-    STDMETHOD(ReleaseDC)(THIS_ HDC32) PURE;
-    STDMETHOD(Restore)(THIS) PURE;
-    STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER) PURE;
-    STDMETHOD(SetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE;
-    STDMETHOD(SetOverlayPosition)(THIS_ LONG, LONG ) PURE;
-    STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE) PURE;
-    STDMETHOD(Unlock)(THIS_ LPVOID) PURE;
-    STDMETHOD(UpdateOverlay)(THIS_ LPRECT32, LPDIRECTDRAWSURFACE3,LPRECT32,DWORD, LPDDOVERLAYFX) PURE;
-    STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD) PURE;
-    STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD, LPDIRECTDRAWSURFACE3) PURE;
+/*0c*/STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE3) PURE;
+/*10*/STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT32) PURE;
+/*14*/STDMETHOD(Blt)(THIS_ LPRECT32,LPDIRECTDRAWSURFACE3, LPRECT32,DWORD, LPDDBLTFX) PURE;
+/*18*/STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH, DWORD, DWORD ) PURE;
+/*1c*/STDMETHOD(BltFast)(THIS_ DWORD,DWORD,LPDIRECTDRAWSURFACE3, LPRECT32,DWORD) PURE;
+/*20*/STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD,LPDIRECTDRAWSURFACE3) PURE;
+/*24*/STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID,LPDDENUMSURFACESCALLBACK) PURE;    
+/*28*/STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD,LPVOID,LPDDENUMSURFACESCALLBACK) PURE;
+/*2c*/STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE3, DWORD) PURE;
+/*30*/STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS, LPDIRECTDRAWSURFACE3 FAR *) PURE;
+/*34*/STDMETHOD(GetBltStatus)(THIS_ DWORD) PURE;
+/*38*/STDMETHOD(GetCaps)(THIS_ LPDDSCAPS) PURE;
+/*3c*/STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER FAR*) PURE;
+/*40*/STDMETHOD(GetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE;
+/*44*/STDMETHOD(GetDC)(THIS_ HDC32 FAR *) PURE;
+/*48*/STDMETHOD(GetFlipStatus)(THIS_ DWORD) PURE;
+/*4c*/STDMETHOD(GetOverlayPosition)(THIS_ LPLONG, LPLONG ) PURE;
+/*50*/STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE FAR*) PURE;
+/*54*/STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT) PURE;
+/*58*/STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC) PURE;
+/*5c*/STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, LPDDSURFACEDESC) PURE;
+/*60*/STDMETHOD(IsLost)(THIS) PURE;
+/*64*/STDMETHOD(Lock)(THIS_ LPRECT32,LPDDSURFACEDESC,DWORD,HANDLE32) PURE;
+/*68*/STDMETHOD(ReleaseDC)(THIS_ HDC32) PURE;
+/*6c*/STDMETHOD(Restore)(THIS) PURE;
+/*70*/STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER) PURE;
+/*74*/STDMETHOD(SetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE;
+/*78*/STDMETHOD(SetOverlayPosition)(THIS_ LONG, LONG ) PURE;
+/*7c*/STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE) PURE;
+/*80*/STDMETHOD(Unlock)(THIS_ LPVOID) PURE;
+/*84*/STDMETHOD(UpdateOverlay)(THIS_ LPRECT32, LPDIRECTDRAWSURFACE3,LPRECT32,DWORD, LPDDOVERLAYFX) PURE;
+/*88*/STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD) PURE;
+/*8c*/STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD, LPDIRECTDRAWSURFACE3) PURE;
     /*** Added in the v2 interface ***/
-    STDMETHOD(GetDDInterface)(THIS_ LPVOID FAR *) PURE;
-    STDMETHOD(PageLock)(THIS_ DWORD) PURE;
-    STDMETHOD(PageUnlock)(THIS_ DWORD) PURE;
+/*90*/STDMETHOD(GetDDInterface)(THIS_ LPVOID FAR *) PURE;
+/*94*/STDMETHOD(PageLock)(THIS_ DWORD) PURE;
+/*98*/STDMETHOD(PageUnlock)(THIS_ DWORD) PURE;
     /*** Added in the V3 interface ***/
-    STDMETHOD(SetSurfaceDesc)(THIS_ LPDDSURFACEDESC, DWORD) PURE;
+/*9c*/STDMETHOD(SetSurfaceDesc)(THIS_ LPDDSURFACEDESC, DWORD) PURE;
 } *LPDIRECTDRAWSURFACE3_VTABLE,IDirectDrawSurface3_VTable;
 
 struct IDirectDrawSurface3 {
diff --git a/include/debugstr.h b/include/debugstr.h
index 7bb3996..4483283 100644
--- a/include/debugstr.h
+++ b/include/debugstr.h
@@ -11,8 +11,8 @@
 LPSTR debugstr_a (LPCSTR s);
 LPSTR debugstr_wn (LPCWSTR s, int n);
 LPSTR debugstr_w (LPCWSTR s);
-LPSTR debugres (const void *res);
+LPSTR debugres_a (LPCSTR res);
+LPSTR debugres_w (LPCWSTR res);
+void debug_dumpstr (LPCSTR s);
 
 #endif /* __WINE_DEBUGSTR_H */
-
-
diff --git a/include/debugtools.h b/include/debugtools.h
index 8dec4ac..b6b50d8 100644
--- a/include/debugtools.h
+++ b/include/debugtools.h
@@ -2,6 +2,8 @@
 #ifndef __WINE_DEBUGTOOLS_H
 #define __WINE_DEBUGTOOLS_H
 
+#ifdef __WINE__  /* Debugging interface is internal to Wine */
+
 #include <stdio.h>
 #include "debugstr.h"
 
@@ -50,4 +52,6 @@
 #define WARN_ON(ch)   DEBUGGING(warn, ch)
 #define TRACE_ON(ch)  DEBUGGING(trace, ch)
 
+#endif  /* __WINE__ */
+
 #endif  /* __WINE_DEBUGTOOLS_H */
diff --git a/include/file.h b/include/file.h
index 7b9c6e4..7ba0c0b 100644
--- a/include/file.h
+++ b/include/file.h
@@ -58,9 +58,6 @@
 extern int DIR_Init(void);
 extern UINT32 DIR_GetWindowsUnixDir( LPSTR path, UINT32 count );
 extern UINT32 DIR_GetSystemUnixDir( LPSTR path, UINT32 count );
-extern UINT32 DIR_GetTempUnixDir( LPSTR path, UINT32 count );
-extern UINT32 DIR_GetDosPath( INT32 element, LPSTR path, UINT32 count );
-extern UINT32 DIR_GetUnixPath( INT32 element, LPSTR path, UINT32 count );
 extern DWORD DIR_SearchPath( LPCSTR path, LPCSTR name, LPCSTR ext,
                              DOS_FULL_NAME *full_name, BOOL32 win32 );
 
diff --git a/include/global.h b/include/global.h
index dc8c939..7acb6a7 100644
--- a/include/global.h
+++ b/include/global.h
@@ -16,6 +16,7 @@
     int shmid;
 } SHMDATA;
 
+/* memory/global.c */
 extern HGLOBAL16 GLOBAL_CreateBlock( UINT16 flags, const void *ptr, DWORD size,
                                      HGLOBAL16 hOwner, BOOL16 isCode,
                                      BOOL16 is32Bit, BOOL16 isReadOnly,
@@ -26,4 +27,8 @@
                                BOOL16 isReadOnly );
 extern WORD GlobalHandleToSel( HGLOBAL16 handle );
 
+/* memory/virtual.c */
+extern DWORD VIRTUAL_GetPageSize(void);
+extern DWORD VIRTUAL_GetGranularity(void);
+
 #endif  /* __WINE_GLOBAL_H */
diff --git a/include/imagelist.h b/include/imagelist.h
index 362ce4b..ce07a6e 100644
--- a/include/imagelist.h
+++ b/include/imagelist.h
@@ -11,8 +11,8 @@
 {
     HBITMAP32 hbmImage;
     HBITMAP32 hbmMask;
-    HBRUSH32  hbrushBlend25;
-    HBRUSH32  hbrushBlend50;
+    HBRUSH32  hbrBlend25;
+    HBRUSH32  hbrBlend50;
     COLORREF  clrBk;
     INT32     cInitial;
     INT32     cGrow;
diff --git a/include/k32obj.h b/include/k32obj.h
index 3e4dc28..0e1dad3 100644
--- a/include/k32obj.h
+++ b/include/k32obj.h
@@ -62,7 +62,8 @@
 extern BOOL32 K32OBJ_IsValid( K32OBJ *ptr, K32OBJ_TYPE type );
 extern BOOL32 K32OBJ_AddName( K32OBJ *obj, LPCSTR name );
 extern K32OBJ *K32OBJ_Create( K32OBJ_TYPE type, DWORD size, LPCSTR name,
-                              DWORD access, HANDLE32 *handle );
+                              DWORD access, SECURITY_ATTRIBUTES *sa,
+                              HANDLE32 *handle );
 extern K32OBJ *K32OBJ_FindName( LPCSTR name );
 extern K32OBJ *K32OBJ_FindNameType( LPCSTR name, K32OBJ_TYPE type );
 
diff --git a/include/module.h b/include/module.h
index e79aa47..017b3c2 100644
--- a/include/module.h
+++ b/include/module.h
@@ -11,7 +11,7 @@
 #include "pe_image.h"
 
   /* In-memory module structure. See 'Windows Internals' p. 219 */
-typedef struct
+typedef struct _NE_MODULE
 {
     WORD    magic;            /* 00 'NE' signature */
     WORD    count;            /* 02 Usage count */
@@ -128,10 +128,11 @@
 extern LPSTR MODULE_GetModuleName( HMODULE32 hModule );
 extern void MODULE_RegisterModule( NE_MODULE *pModule );
 extern HMODULE32 MODULE_FindModule( LPCSTR path );
-extern HINSTANCE16 MODULE_CreateInstance( HMODULE16 hModule, LOADPARAMS* paramBlock );
+extern HINSTANCE16 MODULE_CreateInstance( HMODULE16 hModule, BOOL32 lib_only );
 extern HINSTANCE16 MODULE_GetInstance( HMODULE32 hModule );
 extern HMODULE32 MODULE_CreateDummyModule( const OFSTRUCT *ofs );
-extern HINSTANCE16 MODULE_Load( LPCSTR name, LPVOID paramBlock, UINT16 flags );
+extern HINSTANCE16 MODULE_Load( LPCSTR name, UINT16 uFlags, LPCSTR cmd_line,
+                                LPCSTR env, UINT32 show_cmd );
 extern WORD MODULE_GetOrdinal( HMODULE32 hModule, const char *name );
 extern FARPROC16 MODULE_GetEntryPoint( HMODULE32 hModule, WORD ordinal );
 extern BOOL16 MODULE_SetEntryPoint( HMODULE32 hModule, WORD ordinal,
diff --git a/include/multimedia.h b/include/multimedia.h
index 8c62070..cb70d5c 100644
--- a/include/multimedia.h
+++ b/include/multimedia.h
@@ -20,18 +20,16 @@
 #define MAX_MIDIOUTDRV 	(16)
 #define MAX_MCIMIDIDRV 	(1)
 
-#if defined (linux)
-#define __HAS_SOUNDCARD_H__
-#include <sys/soundcard.h>
-#elif defined (__FreeBSD__)
-#define __HAS_SOUNDCARD_H__
-#include <machine/soundcard.h>
-#include <sys/errno.h>
+#ifdef HAVE_SYS_SOUNDCARD_H
+# include <sys/soundcard.h>
+#endif
+#ifdef HAVE_MACHINE_SOUNDCARD_H
+# include <machine/soundcard.h>
 #endif
 
-#if defined (__HAS_SOUNDCARD_H__)
+#include <sys/errno.h>
 
-#define MIDI_DEV "/dev/sequencer"
+#define MIDI_DEV "/dev/midi"
 
 #ifdef SOUND_VERSION
 #define IOCTL(a,b,c)		ioctl(a,b,&c)
@@ -75,7 +73,4 @@
 	HLOCAL16	hMidiHdr;
 	WORD	dwStatus;
 } LINUX_MCIMIDI;
-
-#endif
-
 #endif /* __WINE_MULTIMEDIA_H */
diff --git a/include/pe_image.h b/include/pe_image.h
index ceab086..61c5912 100644
--- a/include/pe_image.h
+++ b/include/pe_image.h
@@ -42,6 +42,8 @@
 extern DWORD PE_SizeofResource32(HINSTANCE32,HRSRC32);
 extern HMODULE32 PE_LoadLibraryEx32A(LPCSTR,struct _PDB32*,HFILE32,DWORD);
 extern HGLOBAL32 PE_LoadResource32(HINSTANCE32,HRSRC32);
+extern HINSTANCE16 PE_LoadModule( HFILE32 hFile, OFSTRUCT *ofs,
+                                  LPCSTR cmd_line, LPCSTR env, UINT16 showCmd);
 
 struct _PDB32; /* forward definition */
 struct _THDB; /* forward definition */
diff --git a/include/process.h b/include/process.h
index 0323a98..54c699f 100644
--- a/include/process.h
+++ b/include/process.h
@@ -12,7 +12,8 @@
 #include "winnt.h"
 #include "k32obj.h"
 #include "pe_image.h"
-#include "task.h"
+
+struct _NE_MODULE;
 
 /* Process handle entry */
 typedef struct
@@ -31,21 +32,25 @@
 /* Win32 process environment database */
 typedef struct
 {
-    LPSTR           environ;          /* 00 Process environment strings */
-    DWORD           env_size;         /* 04 Environment size (was: Unknown) */
-    LPSTR           cmd_line;         /* 08 Command line */
-    LPSTR           cur_dir;          /* 0c Current directory */
-    STARTUPINFO32A *startup_info;     /* 10 Startup information */
-    HANDLE32        hStdin;           /* 14 Handle for standard input */
-    HANDLE32        hStdout;          /* 18 Handle for standard output */
-    HANDLE32        hStderr;          /* 1c Handle for standard error */
-    DWORD           unknown2;         /* 20 Unknown */
-    DWORD           inherit_console;  /* 24 Inherit console flag */
-    DWORD           break_type;       /* 28 Console events flag */
-    K32OBJ         *break_sem;        /* 2c SetConsoleCtrlHandler semaphore */
-    K32OBJ         *break_event;      /* 30 SetConsoleCtrlHandler event */
-    K32OBJ         *break_thread;     /* 34 SetConsoleCtrlHandler thread */
-    void           *break_handlers;   /* 38 List of console handlers */
+    LPSTR            environ;          /* 00 Process environment strings */
+    DWORD            unknown1;         /* 04 Unknown */
+    LPSTR            cmd_line;         /* 08 Command line */
+    LPSTR            cur_dir;          /* 0c Current directory */
+    STARTUPINFO32A  *startup_info;     /* 10 Startup information */
+    HANDLE32         hStdin;           /* 14 Handle for standard input */
+    HANDLE32         hStdout;          /* 18 Handle for standard output */
+    HANDLE32         hStderr;          /* 1c Handle for standard error */
+    DWORD            unknown2;         /* 20 Unknown */
+    DWORD            inherit_console;  /* 24 Inherit console flag */
+    DWORD            break_type;       /* 28 Console events flag */
+    K32OBJ          *break_sem;        /* 2c SetConsoleCtrlHandler semaphore */
+    K32OBJ          *break_event;      /* 30 SetConsoleCtrlHandler event */
+    K32OBJ          *break_thread;     /* 34 SetConsoleCtrlHandler thread */
+    void            *break_handlers;   /* 38 List of console handlers */
+    /* The following are Wine-specific fields */
+    CRITICAL_SECTION section;          /* 3c Env DB critical section */
+    LPWSTR           cmd_lineW;        /* 40 Unicode command line */
+    WORD             env_sel;          /* 44 Environment strings selector */
 } ENVDB;
 
 /* Win32 process database */
@@ -103,17 +108,27 @@
 #define PROCESS_ID_TO_PDB(id)  ((PDB32 *)((id) ^ PROCESS_OBFUSCATOR))
 #define PDB_TO_PROCESS_ID(pdb) ((DWORD)(pdb) ^ PROCESS_OBFUSCATOR)
 
+/* scheduler/environ.c */
+extern BOOL32 ENV_BuildEnvironment( PDB32 *pdb );
+extern BOOL32 ENV_InheritEnvironment( PDB32 *pdb, LPCSTR env );
+extern void ENV_FreeEnvironment( PDB32 *pdb );
+
 /* scheduler/handle.c */
-extern HANDLE_TABLE *HANDLE_AllocTable( PDB32 *process );
-extern HANDLE32 HANDLE_Alloc( K32OBJ *ptr, DWORD access, BOOL32 inherit );
-extern K32OBJ *HANDLE_GetObjPtr( HANDLE32 handle, K32OBJ_TYPE type,
-                                 DWORD access );
-extern BOOL32 HANDLE_SetObjPtr( HANDLE32 handle, K32OBJ *ptr, DWORD access );
+extern BOOL32 HANDLE_CreateTable( PDB32 *pdb, BOOL32 inherit );
+extern HANDLE32 HANDLE_Alloc( PDB32 *pdb, K32OBJ *ptr, DWORD access,
+                              BOOL32 inherit );
+extern K32OBJ *HANDLE_GetObjPtr( PDB32 *pdb, HANDLE32 handle,
+                                 K32OBJ_TYPE type, DWORD access );
+extern BOOL32 HANDLE_SetObjPtr( PDB32 *pdb, HANDLE32 handle,
+                                K32OBJ *ptr, DWORD access );
+extern void HANDLE_CloseAll( PDB32 *pdb, K32OBJ *ptr );
 
 /* scheduler/process.c */
 extern PDB32 *PROCESS_Current(void);
 extern PDB32 *PROCESS_GetPtr( HANDLE32 handle, DWORD access );
 extern PDB32 *PROCESS_IdToPDB( DWORD id );
-extern PDB32 *PROCESS_Create( TDB *pTask, LPCSTR cmd_line );
-extern void PROCESS_CloseObjHandles(PDB32 *pdb, K32OBJ *ptr);
+extern PDB32 *PROCESS_Create( struct _NE_MODULE *pModule, LPCSTR cmd_line,
+                              LPCSTR env, HINSTANCE16 hInstance,
+                              HINSTANCE16 hPrevInstance, UINT32 cmdShow );
+
 #endif  /* __WINE_PROCESS_H */
diff --git a/include/progress.h b/include/progress.h
index 0aadb15..36b7063 100644
--- a/include/progress.h
+++ b/include/progress.h
@@ -16,6 +16,8 @@
   INT32       MinVal;       /* Minimum progress value */
   INT32       MaxVal;       /* Maximum progress value */
   INT32       Step;         /* Step to use on PMB_STEPIT */
+  COLORREF    ColorBar;     /* Bar color */
+  COLORREF    ColorBk;      /* Background color */
 } PROGRESS_INFO;
 
 LRESULT WINAPI ProgressWindowProc(HWND32, UINT32, WPARAM32, LPARAM);
diff --git a/include/selectors.h b/include/selectors.h
index 8ca897f..a203354 100644
--- a/include/selectors.h
+++ b/include/selectors.h
@@ -16,6 +16,7 @@
 extern WORD SELECTOR_ReallocBlock( WORD sel, const void *base, DWORD size,
                                    enum seg_type type, BOOL32 is32bit,
                                    BOOL32 readonly );
+extern void SELECTOR_MoveBlock( WORD sel, const void *new_base );
 extern void SELECTOR_FreeBlock( WORD sel, WORD count );
 
 #ifdef __i386__
diff --git a/include/task.h b/include/task.h
index 460f5de..0a3cc86 100644
--- a/include/task.h
+++ b/include/task.h
@@ -50,6 +50,7 @@
 
 struct _THDB;
 struct _WSINFO;
+struct _NE_MODULE;
 
   /* signal proc typedef */
 typedef void (CALLBACK *USERSIGNALPROC)(HANDLE16, UINT16, UINT16,
@@ -124,11 +125,9 @@
 
 #pragma pack(4)
 
-extern BOOL32 TASK_Init(void);
-extern HTASK16 TASK_CreateTask( HMODULE16 hModule, HINSTANCE16 hInstance,
-                                HINSTANCE16 hPrevInstance,
-                                HANDLE16 hEnvironment, LPCSTR cmdLine,
-                                UINT16 cmdShow );
+extern HTASK16 TASK_Create( struct _THDB *thdb, struct _NE_MODULE *pModule,
+                            HINSTANCE16 hInstance, HINSTANCE16 hPrevInstance,
+                            UINT16 cmdShow );
 extern void TASK_KillCurrentTask( INT16 exitCode );
 extern HTASK16 TASK_GetNextTask( HTASK16 hTask );
 extern void TASK_Reschedule(void);
diff --git a/include/thread.h b/include/thread.h
index 84d5dae..090ce62 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -121,6 +121,7 @@
 
 /* scheduler/thread.c */
 extern THDB *THREAD_Create( struct _PDB32 *pdb, DWORD stack_size,
+                            BOOL32 alloc_stack16,
                             LPTHREAD_START_ROUTINE start_addr, LPVOID param );
 extern THDB *THREAD_Current(void);
 extern THDB *THREAD_GetPtr( HANDLE32 handle, DWORD access );
diff --git a/include/ver.h b/include/ver.h
index 60d0dee..5f5dd97 100644
--- a/include/ver.h
+++ b/include/ver.h
@@ -8,9 +8,9 @@
 #include "windows.h"
 
 /* resource ids for different version infos */
-#define	VS_FILE_INFO	MAKEINTRESOURCE(16)
-#define	VS_VERSION_INFO	MAKEINTRESOURCE(1)
-#define	VS_USER_INFO	MAKEINTRESOURCE(100)
+#define	VS_FILE_INFO	MAKEINTRESOURCE16(16)
+#define	VS_VERSION_INFO	MAKEINTRESOURCE16(1)
+#define	VS_USER_INFO	MAKEINTRESOURCE16(100)
 
 #define	VS_FFI_SIGNATURE	0xfeef04bdL	/* FileInfo Magic */
 #define	VS_FFI_STRUCVERSION	0x00010000L	/* struc version 1.0 */
diff --git a/include/version.h b/include/version.h
index 4fcacf6..c098d61 100644
--- a/include/version.h
+++ b/include/version.h
@@ -1 +1 @@
-#define WINE_RELEASE_INFO "Wine release 980329"
+#define WINE_RELEASE_INFO "Wine release 980413"
diff --git a/include/win.h b/include/win.h
index c1f9186..ebe47ce 100644
--- a/include/win.h
+++ b/include/win.h
@@ -76,6 +76,7 @@
     DWORD          dwStyle;       /* Window style (from CreateWindow) */
     DWORD          dwExStyle;     /* Extended style (from CreateWindowEx) */
     UINT32         wIDmenu;       /* ID or hmenu (from CreateWindow) */
+    DWORD          helpContext;   /* Help context ID */
     WORD           flags;         /* Misc. flags (see below) */
     Window         window;        /* X window (only for top-level windows) */
     HMENU16        hSysMenu;      /* window's copy of System Menu */
diff --git a/include/winbase.h b/include/winbase.h
index d1c3004..0983276 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -100,6 +100,15 @@
 #define HANDLE_FLAG_INHERIT             0x00000001
 #define HANDLE_FLAG_PROTECT_FROM_CLOSE  0x00000002
 
+#define THREAD_PRIORITY_LOWEST          THREAD_BASE_PRIORITY_MIN
+#define THREAD_PRIORITY_BELOW_NORMAL    (THREAD_PRIORITY_LOWEST+1)
+#define THREAD_PRIORITY_NORMAL          0
+#define THREAD_PRIORITY_HIGHEST         THREAD_BASE_PRIORITY_MAX
+#define THREAD_PRIORITY_ABOVE_NORMAL    (THREAD_PRIORITY_HIGHEST-1)
+#define THREAD_PRIORITY_ERROR_RETURN    (0x7fffffff)
+#define THREAD_PRIORITY_TIME_CRITICAL   THREAD_BASE_PRIORITY_LOWRT
+#define THREAD_PRIORITY_IDLE            THREAD_BASE_PRIORITY_IDLE
+
 typedef struct 
 {
   int type;
diff --git a/include/wincon.h b/include/wincon.h
index b7c46e5..da8b20e 100644
--- a/include/wincon.h
+++ b/include/wincon.h
@@ -40,8 +40,8 @@
 typedef struct tagSMALL_RECT
 {
     INT16 Left;
-    INT16 Right;
     INT16 Top;
+    INT16 Right;
     INT16 Bottom;
 } SMALL_RECT,*LPSMALL_RECT;
 
diff --git a/include/windows.h b/include/windows.h
index 21bf27d..e1861ae 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -2461,45 +2461,147 @@
 #define	WF_WIN32WOW     0x4000	/* undoc */
 #define	WF_WLO          0x8000
 
-#define MAKEINTRESOURCE(i) (SEGPTR)((DWORD)((WORD)(i)))
+#define MAKEINTRESOURCE16(i)  (SEGPTR)((DWORD)((WORD)(i)))
+#define MAKEINTRESOURCE32A(i) (LPSTR)((DWORD)((WORD)(i)))
+#define MAKEINTRESOURCE32W(i) (LPWSTR)((DWORD)((WORD)(i)))
+#define MAKEINTRESOURCE WINELIB_NAME_AW(MAKEINTRESOURCE)
 
 /* Predefined resource types */
-#define RT_CURSOR	    MAKEINTRESOURCE(1)
-#define RT_BITMAP	    MAKEINTRESOURCE(2)
-#define RT_ICON 	    MAKEINTRESOURCE(3)
-#define RT_MENU 	    MAKEINTRESOURCE(4)
-#define RT_DIALOG	    MAKEINTRESOURCE(5)
-#define RT_STRING	    MAKEINTRESOURCE(6)
-#define RT_FONTDIR	    MAKEINTRESOURCE(7)
-#define RT_FONT 	    MAKEINTRESOURCE(8)
-#define RT_ACCELERATOR	    MAKEINTRESOURCE(9)
-#define RT_RCDATA	    MAKEINTRESOURCE(10)
-#define RT_MESSAGELIST      MAKEINTRESOURCE(11)
-#define RT_GROUP_CURSOR     MAKEINTRESOURCE(12)
-#define RT_GROUP_ICON	    MAKEINTRESOURCE(14)
+#define RT_CURSOR16          MAKEINTRESOURCE16(1)
+#define RT_CURSOR32A         MAKEINTRESOURCE32A(1)
+#define RT_CURSOR32W         MAKEINTRESOURCE32W(1)
+#define RT_CURSOR            WINELIB_NAME_AW(RT_CURSOR)
+#define RT_BITMAP16          MAKEINTRESOURCE16(2)
+#define RT_BITMAP32A         MAKEINTRESOURCE32A(2)
+#define RT_BITMAP32W         MAKEINTRESOURCE32W(2)
+#define RT_BITMAP            WINELIB_NAME_AW(RT_BITMAP)
+#define RT_ICON16            MAKEINTRESOURCE16(3)
+#define RT_ICON32A           MAKEINTRESOURCE32A(3)
+#define RT_ICON32W           MAKEINTRESOURCE32W(3)
+#define RT_ICON              WINELIB_NAME_AW(RT_ICON)
+#define RT_MENU16            MAKEINTRESOURCE16(4)
+#define RT_MENU32A           MAKEINTRESOURCE32A(4)
+#define RT_MENU32W           MAKEINTRESOURCE32W(4)
+#define RT_MENU              WINELIB_NAME_AW(RT_MENU)
+#define RT_DIALOG16          MAKEINTRESOURCE16(5)
+#define RT_DIALOG32A         MAKEINTRESOURCE32A(5)
+#define RT_DIALOG32W         MAKEINTRESOURCE32W(5)
+#define RT_DIALOG            WINELIB_NAME_AW(RT_DIALOG)
+#define RT_STRING16          MAKEINTRESOURCE16(6)
+#define RT_STRING32A         MAKEINTRESOURCE32A(6)
+#define RT_STRING32W         MAKEINTRESOURCE32W(6)
+#define RT_STRING            WINELIB_NAME_AW(RT_STRING)
+#define RT_FONTDIR16         MAKEINTRESOURCE16(7)
+#define RT_FONTDIR32A        MAKEINTRESOURCE32A(7)
+#define RT_FONTDIR32W        MAKEINTRESOURCE32W(7)
+#define RT_FONTDIR           WINELIB_NAME_AW(RT_FONTDIR)
+#define RT_FONT16            MAKEINTRESOURCE16(8)
+#define RT_FONT32A           MAKEINTRESOURCE32A(8)
+#define RT_FONT32W           MAKEINTRESOURCE32W(8)
+#define RT_FONT              WINELIB_NAME_AW(RT_FONT)
+#define RT_ACCELERATOR16     MAKEINTRESOURCE16(9)
+#define RT_ACCELERATOR32A    MAKEINTRESOURCE32A(9)
+#define RT_ACCELERATOR32W    MAKEINTRESOURCE32W(9)
+#define RT_ACCELERATOR       WINELIB_NAME_AW(RT_ACCELERATOR)
+#define RT_RCDATA16          MAKEINTRESOURCE16(10)
+#define RT_RCDATA32A         MAKEINTRESOURCE32A(10)
+#define RT_RCDATA32W         MAKEINTRESOURCE32W(10)
+#define RT_RCDATA            WINELIB_NAME_AW(RT_RCDATA)
+#define RT_MESSAGELIST16     MAKEINTRESOURCE16(11)
+#define RT_MESSAGELIST32A    MAKEINTRESOURCE32A(11)
+#define RT_MESSAGELIST32W    MAKEINTRESOURCE32W(11)
+#define RT_MESSAGELIST       WINELIB_NAME_AW(RT_MESSAGELIST)
+#define RT_GROUP_CURSOR16    MAKEINTRESOURCE16(12)
+#define RT_GROUP_CURSOR32A   MAKEINTRESOURCE32A(12)
+#define RT_GROUP_CURSOR32W   MAKEINTRESOURCE32W(12)
+#define RT_GROUP_CURSOR      WINELIB_NAME_AW(RT_GROUP_CURSOR)
+#define RT_GROUP_ICON16      MAKEINTRESOURCE16(14)
+#define RT_GROUP_ICON32A     MAKEINTRESOURCE32A(14)
+#define RT_GROUP_ICON32W     MAKEINTRESOURCE32W(14)
+#define RT_GROUP_ICON        WINELIB_NAME_AW(RT_GROUP_ICON)
 
 /* Predefined resources */
-#define IDI_APPLICATION  MAKEINTRESOURCE(32512)
-#define IDI_HAND         MAKEINTRESOURCE(32513)
-#define IDI_QUESTION     MAKEINTRESOURCE(32514)
-#define IDI_EXCLAMATION  MAKEINTRESOURCE(32515)
-#define IDI_ASTERISK     MAKEINTRESOURCE(32516)
+#define IDI_APPLICATION16  MAKEINTRESOURCE16(32512)
+#define IDI_APPLICATION32A MAKEINTRESOURCE32A(32512)
+#define IDI_APPLICATION32W MAKEINTRESOURCE32W(32512)
+#define IDI_APPLICATION    WINELIB_NAME_AW(IDI_APPLICATION)
+#define IDI_HAND16         MAKEINTRESOURCE16(32513)
+#define IDI_HAND32A        MAKEINTRESOURCE32A(32513)
+#define IDI_HAND32W        MAKEINTRESOURCE32W(32513)
+#define IDI_HAND           WINELIB_NAME_AW(IDI_HAND)
+#define IDI_QUESTION16     MAKEINTRESOURCE16(32514)
+#define IDI_QUESTION32A    MAKEINTRESOURCE32A(32514)
+#define IDI_QUESTION32W    MAKEINTRESOURCE32W(32514)
+#define IDI_QUESTION       WINELIB_NAME_AW(IDI_QUESTION)
+#define IDI_EXCLAMATION16  MAKEINTRESOURCE16(32515)
+#define IDI_EXCLAMATION32A MAKEINTRESOURCE32A(32515)
+#define IDI_EXCLAMATION32W MAKEINTRESOURCE32W(32515)
+#define IDI_EXCLAMATION    WINELIB_NAME_AW(IDI_EXCLAMATION)
+#define IDI_ASTERISK16     MAKEINTRESOURCE16(32516)
+#define IDI_ASTERISK32A    MAKEINTRESOURCE32A(32516)
+#define IDI_ASTERISK32W    MAKEINTRESOURCE32W(32516)
+#define IDI_ASTERISK       WINELIB_NAME_AW(IDI_ASTERISK)
 
-#define IDC_BUMMER	 MAKEINTRESOURCE(100)
-#define IDC_ARROW        MAKEINTRESOURCE(32512)
-#define IDC_IBEAM        MAKEINTRESOURCE(32513)
-#define IDC_WAIT         MAKEINTRESOURCE(32514)
-#define IDC_CROSS        MAKEINTRESOURCE(32515)
-#define IDC_UPARROW      MAKEINTRESOURCE(32516)
-#define IDC_SIZE         MAKEINTRESOURCE(32640)
-#define IDC_ICON         MAKEINTRESOURCE(32641)
-#define IDC_SIZENWSE     MAKEINTRESOURCE(32642)
-#define IDC_SIZENESW     MAKEINTRESOURCE(32643)
-#define IDC_SIZEWE       MAKEINTRESOURCE(32644)
-#define IDC_SIZENS       MAKEINTRESOURCE(32645)
-#define IDC_NO           MAKEINTRESOURCE(32648)
-#define IDC_APPSTARTING  MAKEINTRESOURCE(32650)
-#define IDC_HELP         MAKEINTRESOURCE(32651)
+#define IDC_BUMMER16       MAKEINTRESOURCE16(100)
+#define IDC_BUMMER32A      MAKEINTRESOURCE32A(100)
+#define IDC_BUMMER32W      MAKEINTRESOURCE32W(100)
+#define IDC_BUMMER         WINELIB_NAME_AW(IDC_BUMMER)
+#define IDC_ARROW16        MAKEINTRESOURCE16(32512)
+#define IDC_ARROW32A       MAKEINTRESOURCE32A(32512)
+#define IDC_ARROW32W       MAKEINTRESOURCE32W(32512)
+#define IDC_ARROW          WINELIB_NAME_AW(IDC_ARROW)
+#define IDC_IBEAM16        MAKEINTRESOURCE16(32513)
+#define IDC_IBEAM32A       MAKEINTRESOURCE32A(32513)
+#define IDC_IBEAM32W       MAKEINTRESOURCE32W(32513)
+#define IDC_IBEAM          WINELIB_NAME_AW(IDC_IBEAM)
+#define IDC_WAIT16         MAKEINTRESOURCE16(32514)
+#define IDC_WAIT32A        MAKEINTRESOURCE32A(32514)
+#define IDC_WAIT32W        MAKEINTRESOURCE32W(32514)
+#define IDC_WAIT           WINELIB_NAME_AW(IDC_WAIT)
+#define IDC_CROSS16        MAKEINTRESOURCE16(32515)
+#define IDC_CROSS32A       MAKEINTRESOURCE32A(32515)
+#define IDC_CROSS32W       MAKEINTRESOURCE32W(32515)
+#define IDC_CROSS          WINELIB_NAME_AW(IDC_CROSS)
+#define IDC_UPARROW16      MAKEINTRESOURCE16(32516)
+#define IDC_UPARROW32A     MAKEINTRESOURCE32A(32516)
+#define IDC_UPARROW32W     MAKEINTRESOURCE32W(32516)
+#define IDC_UPARROW        WINELIB_NAME_AW(IDC_UPARROW)
+#define IDC_SIZE16         MAKEINTRESOURCE16(32640)
+#define IDC_SIZE32A        MAKEINTRESOURCE32A(32640)
+#define IDC_SIZE32W        MAKEINTRESOURCE32W(32640)
+#define IDC_SIZE           WINELIB_NAME_AW(IDC_SIZE)
+#define IDC_ICON16         MAKEINTRESOURCE16(32641)
+#define IDC_ICON32A        MAKEINTRESOURCE32A(32641)
+#define IDC_ICON32W        MAKEINTRESOURCE32W(32641)
+#define IDC_ICON           WINELIB_NAME_AW(IDC_ICON)
+#define IDC_SIZENWSE16     MAKEINTRESOURCE16(32642)
+#define IDC_SIZENWSE32A    MAKEINTRESOURCE32A(32642)
+#define IDC_SIZENWSE32W    MAKEINTRESOURCE32W(32642)
+#define IDC_SIZENWSE       WINELIB_NAME_AW(IDC_SIZENWSE)
+#define IDC_SIZENESW16     MAKEINTRESOURCE16(32643)
+#define IDC_SIZENESW32A    MAKEINTRESOURCE32A(32643)
+#define IDC_SIZENESW32W    MAKEINTRESOURCE32W(32643)
+#define IDC_SIZENESW       WINELIB_NAME_AW(IDC_SIZENESW)
+#define IDC_SIZEWE16       MAKEINTRESOURCE16(32644)
+#define IDC_SIZEWE32A      MAKEINTRESOURCE32A(32644)
+#define IDC_SIZEWE32W      MAKEINTRESOURCE32W(32644)
+#define IDC_SIZEWE         WINELIB_NAME_AW(IDC_SIZEWE)
+#define IDC_SIZENS16       MAKEINTRESOURCE16(32645)
+#define IDC_SIZENS32A      MAKEINTRESOURCE32A(32645)
+#define IDC_SIZENS32W      MAKEINTRESOURCE32W(32645)
+#define IDC_SIZENS         WINELIB_NAME_AW(IDC_SIZENS)
+#define IDC_NO16           MAKEINTRESOURCE16(32648)
+#define IDC_NO32A          MAKEINTRESOURCE32A(32648)
+#define IDC_NO32W          MAKEINTRESOURCE32W(32648)
+#define IDC_NO             WINELIB_NAME_AW(IDC_NO)
+#define IDC_APPSTARTING16  MAKEINTRESOURCE16(32650)
+#define IDC_APPSTARTING32A MAKEINTRESOURCE32A(32650)
+#define IDC_APPSTARTING32W MAKEINTRESOURCE32W(32650)
+#define IDC_APPSTARTING    WINELIB_NAME_AW(IDC_APPSTARTING)
+#define IDC_HELP16         MAKEINTRESOURCE16(32651)
+#define IDC_HELP32A        MAKEINTRESOURCE32A(32651)
+#define IDC_HELP32W        MAKEINTRESOURCE32W(32651)
+#define IDC_HELP           WINELIB_NAME_AW(IDC_HELP)
 
 /* OEM Resource Ordinal Numbers */
 #define OBM_CLOSE           32754
@@ -4259,6 +4361,7 @@
 #define CF_PENDATA          10
 #define CF_RIFF             11
 #define CF_WAVE             12
+#define CF_ENHMETAFILE      14
 
 #define CF_OWNERDISPLAY     0x0080
 #define CF_DSPTEXT          0x0081
@@ -4430,6 +4533,7 @@
 #define META_CREATEBITMAPINDIRECT    0x02FD
 #define META_CREATEBITMAP            0x06FE
 #define META_CREATEREGION            0x06FF
+#define META_UNKNOWN                 0x0529  /* FIXME: unknown meta magic */
 
 typedef INT16 (CALLBACK *MFENUMPROC16)(HDC16,HANDLETABLE16*,METARECORD*,
                                        INT16,LPARAM);
@@ -5587,13 +5691,13 @@
 
 typedef struct /* not sure if the 16bit version is correct */
 {
-    UINT16	cbSize;
+    UINT32	cbSize;
     HWND16	hwndOwner;
     HINSTANCE16	hInstance;
-    LPCSTR	lpszText;
-    LPCSTR	lpszCaption;
+    SEGPTR	lpszText;
+    SEGPTR	lpszCaption;
     DWORD	dwStyle;
-    LPCSTR	lpszIcon;
+    SEGPTR	lpszIcon;
     DWORD	dwContextHelpId;
     MSGBOXCALLBACK	lpfnMsgBoxCallback;
     DWORD	dwLanguageId;
@@ -5659,6 +5763,7 @@
 
 /* Declarations for functions that exist only in Win16 */
 
+#ifndef WINELIB
 WORD        WINAPI AllocCStoDSAlias(WORD);
 WORD        WINAPI AllocDStoCSAlias(WORD);
 WORD        WINAPI AllocSelector(WORD);
@@ -5811,7 +5916,7 @@
 INT16       WINAPI WriteComm(INT16,LPSTR,INT16);
 VOID        WINAPI WriteOutProfiles(VOID);
 VOID        WINAPI hmemcpy(LPVOID,LPCVOID,LONG);
-
+#endif /* WINELIB */
 
 /* Declarations for functions that exist only in Win32 */
 
@@ -5823,6 +5928,8 @@
 INT32       WINAPI CopyAcceleratorTable32A(HACCEL32,LPACCEL32,INT32);
 INT32       WINAPI CopyAcceleratorTable32W(HACCEL32,LPACCEL32,INT32);
 #define     CopyAcceleratorTable WINELIB_NAME_AW(CopyAcceleratorTable)
+HENHMETAFILE32 WINAPI CopyEnhMetaFile32A(HENHMETAFILE32,LPCSTR);
+#define     CopyEnhMetaFile WINELIB_NAME_AW(CopyEnhMetaFile)
 BOOL32      WINAPI CopyFile32A(LPCSTR,LPCSTR,BOOL32);
 BOOL32      WINAPI CopyFile32W(LPCWSTR,LPCWSTR,BOOL32);
 #define     CopyFile WINELIB_NAME_AW(CopyFile)
@@ -5849,9 +5956,11 @@
 HANDLE32    WINAPI CreateSemaphore32W(LPSECURITY_ATTRIBUTES,LONG,LONG,LPCWSTR);
 #define     CreateSemaphore WINELIB_NAME_AW(CreateSemaphore)
 HANDLE32    WINAPI CreateThread(LPSECURITY_ATTRIBUTES,DWORD,LPTHREAD_START_ROUTINE,LPVOID,DWORD,LPDWORD);
+BOOL32      WINAPI DeleteEnhMetaFile(HENHMETAFILE32);
 BOOL32      WINAPI DestroyAcceleratorTable(HACCEL32);
 BOOL32      WINAPI DisableThreadLibraryCalls(HMODULE32);
 BOOL32      WINAPI DosDateTimeToFileTime(WORD,WORD,LPFILETIME);
+BOOL32      WINAPI DuplicateHandle(HANDLE32,HANDLE32,HANDLE32,HANDLE32*,DWORD,BOOL32,DWORD);
 INT32       WINAPI EnumPropsEx32A(HWND32,PROPENUMPROCEX32A,LPARAM);
 INT32       WINAPI EnumPropsEx32W(HWND32,PROPENUMPROCEX32W,LPARAM);
 #define     EnumPropsEx WINELIB_NAME_AW(EnumPropsEx)
@@ -5921,6 +6030,10 @@
 INT32       WINAPI GetDateFormat32W(LCID,DWORD,LPSYSTEMTIME,LPCWSTR,LPWSTR,INT32);
 #define     GetDateFormat WINELIB_NAME_AW(GetDateFormat)
 BOOL32      WINAPI GetDCOrgEx(HDC32,LPPOINT32);
+HENHMETAFILE32 WINAPI GetEnhMetaFile32A(LPCSTR);
+HENHMETAFILE32 WINAPI GetEnhMetaFile32W(LPCWSTR);
+#define     GetEnhMetaFile WINELIB_NAME_AW(GetEnhMetaFile)
+UINT32      WINAPI GetEnhMetaFileHeader(HENHMETAFILE32,UINT32,LPENHMETAHEADER);
 LPSTR       WINAPI GetEnvironmentStrings32A(void);
 LPWSTR      WINAPI GetEnvironmentStrings32W(void);
 #define     GetEnvironmentStrings WINELIB_NAME_AW(GetEnvironmentStrings)
@@ -5976,6 +6089,7 @@
 BOOL32      WINAPI GetUserName32A(LPSTR,LPDWORD);
 BOOL32      WINAPI GetUserName32W(LPWSTR,LPDWORD);
 #define     GetUserName WINELIB_NAME_AW(GetUserName)
+DWORD       WINAPI GetWindowContextHelpId(HWND32);
 DWORD       WINAPI GetWindowThreadProcessId(HWND32,LPDWORD);
 BOOL32      WINAPI GetWorldTransform(HDC32,LPXFORM);
 VOID        WINAPI GlobalMemoryStatus(LPMEMORYSTATUS);
@@ -6027,6 +6141,8 @@
 HANDLE32    WINAPI OpenSemaphore32A(DWORD,BOOL32,LPCSTR);
 HANDLE32    WINAPI OpenSemaphore32W(DWORD,BOOL32,LPCWSTR);
 #define     OpenSemaphore WINELIB_NAME_AW(OpenSemaphore)
+BOOL32      WINAPI PlayEnhMetaFile(HDC32,HENHMETAFILE32,const RECT32*);
+BOOL32      WINAPI PlayEnhMetaFileRecord(HDC32,LPHANDLETABLE32,const ENHMETARECORD*,UINT32);
 BOOL32      WINAPI PulseEvent(HANDLE32);
 DWORD       WINAPI QueryDosDevice32A(LPCSTR,LPSTR,DWORD);
 DWORD       WINAPI QueryDosDevice32W(LPCWSTR,LPWSTR,DWORD);
@@ -6087,12 +6203,14 @@
 BOOL32      WINAPI SetMenuItemInfo32A(HMENU32,UINT32,BOOL32,const MENUITEMINFO32A*);
 BOOL32      WINAPI SetMenuItemInfo32W(HMENU32,UINT32,BOOL32,const MENUITEMINFO32W*);
 #define     SetMenuItemInfo WINELIB_NAME_AW(SetMenuItemInfo)
+HMETAFILE32 WINAPI SetMetaFileBitsEx(UINT32,const BYTE*);
 BOOL32      WINAPI SetPriorityClass(HANDLE32,DWORD);
 BOOL32      WINAPI SetStdHandle(DWORD,HANDLE32);
 BOOL32      WINAPI SetSystemPowerState(BOOL32,BOOL32);
 BOOL32      WINAPI SetSystemTime(const SYSTEMTIME*);
 BOOL32      WINAPI SetThreadPriority(HANDLE32,INT32);
 BOOL32      WINAPI SetTimeZoneInformation(const LPTIME_ZONE_INFORMATION);
+BOOL32      WINAPI SetWindowContextHelpId(HWND32,DWORD);
 BOOL32      WINAPI SetWorldTransform(HDC32,const XFORM*);
 VOID        WINAPI Sleep(DWORD);
 BOOL32      WINAPI SystemTimeToFileTime(const SYSTEMTIME*,LPFILETIME);
@@ -6126,6 +6244,8 @@
 BOOL32      WINAPI WriteConsole32W(HANDLE32,LPCVOID,DWORD,LPDWORD,LPVOID);
 #define     WriteConsole WINELIB_NAME_AW(WriteConsole)
 BOOL32      WINAPI WriteFile(HANDLE32,LPCVOID,DWORD,LPDWORD,LPOVERLAPPED);
+VOID        WINAPI ZeroMemory(LPVOID,UINT32);
+#define     ZeroMemory RtlZeroMemory
 
 /* Declarations for functions that are the same in Win16 and Win32 */
 
@@ -7240,10 +7360,21 @@
 COLORREF    WINAPI GetTextColor16(HDC16);
 COLORREF    WINAPI GetTextColor32(HDC32);
 #define     GetTextColor WINELIB_NAME(GetTextColor)
+/* this one is different, because Win32 has *both* 
+ * GetTextExtentPoint and GetTextExtentPoint32 !
+ */
 BOOL16      WINAPI GetTextExtentPoint16(HDC16,LPCSTR,INT16,LPSIZE16);
 BOOL32      WINAPI GetTextExtentPoint32A(HDC32,LPCSTR,INT32,LPSIZE32);
 BOOL32      WINAPI GetTextExtentPoint32W(HDC32,LPCWSTR,INT32,LPSIZE32);
-#define     GetTextExtentPoint WINELIB_NAME_AW(GetTextExtentPoint)
+BOOL32      WINAPI GetTextExtentPoint32ABuggy(HDC32,LPCSTR,INT32,LPSIZE32);
+BOOL32      WINAPI GetTextExtentPoint32WBuggy(HDC32,LPCWSTR,INT32,LPSIZE32);
+#ifdef UNICODE
+#define     GetTextExtentPoint GetTextExtentPoint32WBuggy
+#define     GetTextExtentPoint32 GetTextExtentPoint32W
+#else
+#define     GetTextExtentPoint GetTextExtentPoint32ABuggy
+#define     GetTextExtentPoint32 GetTextExtentPoint32A
+#endif
 INT16       WINAPI GetTextFace16(HDC16,INT16,LPSTR);
 INT32       WINAPI GetTextFace32A(HDC32,INT32,LPSTR);
 INT32       WINAPI GetTextFace32W(HDC32,INT32,LPWSTR);
diff --git a/include/wintypes.h b/include/wintypes.h
index 3dac52d..3586b4a 100644
--- a/include/wintypes.h
+++ b/include/wintypes.h
@@ -10,38 +10,29 @@
 #ifdef __WINE__
 # include "config.h"
 # undef WINELIB
-# undef WINELIB16
-# undef WINELIB32
 # undef UNICODE
 #else  /* __WINE__ */
 # ifndef WINELIB
 #  define WINELIB
 # endif
-# ifdef WINELIB16
-#  undef WINELIB32
-# else
-#  define WINELIB32
-# endif
 #endif  /* __WINE__ */
 
 /* Macros to map Winelib names to the correct implementation name */
-/* depending on WINELIB16, WINELIB32 and UNICODE macros.          */
+/* depending on WINELIB and UNICODE macros.                       */
+/* Note that WINELIB is purely Win32.                             */
 
 #ifdef __WINE__
 # define WINELIB_NAME(func)      this is a syntax error
 # define WINELIB_NAME_AW(func)   this is a syntax error
 #else  /* __WINE__ */
-# ifdef WINELIB32
+# ifdef WINELIB
 #  define WINELIB_NAME(func)     func##32
 #  ifdef UNICODE
 #   define WINELIB_NAME_AW(func) func##32W
 #  else
 #   define WINELIB_NAME_AW(func) func##32A
 #  endif  /* UNICODE */
-# else   /* WINELIB32 */
-#  define WINELIB_NAME(func)     func##16
-#  define WINELIB_NAME_AW(func)  func##16
-# endif  /* WINELIB32 */
+# endif  /* WINELIB */
 #endif  /* __WINE__ */
 
 #ifdef __WINE__
diff --git a/loader/main.c b/loader/main.c
index 35ac05d..5ab11da 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -27,7 +27,6 @@
 #include "miscemu.h"
 #include "options.h"
 #include "spy.h"
-#include "task.h"
 #include "tweak.h"
 #include "user.h"
 #include "dce.h"
@@ -60,9 +59,6 @@
     /* Initialise DOS directories */
     if (!DIR_Init()) return FALSE;
 
-    /* Initialize tasks */
-    if (!TASK_Init()) return FALSE;
-
       /* Initialize event handling */
     if (!EVENT_Init()) return FALSE;
 
diff --git a/loader/module.c b/loader/module.c
index 6482610..1e1db94 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -18,6 +18,7 @@
 #include "heap.h"
 #include "module.h"
 #include "neexe.h"
+#include "pe_image.h"
 #include "process.h"
 #include "thread.h"
 #include "resource.h"
@@ -28,8 +29,6 @@
 #include "debug.h"
 #include "callback.h"
 
-extern HINSTANCE16 PE_LoadModule( HFILE32 hf, OFSTRUCT *ofs, LOADPARAMS* params );
-
 extern BOOL32 THREAD_InitDone;
 
 static HMODULE16 hFirstModule = 0;
@@ -375,8 +374,10 @@
 
 /***********************************************************************
  *           MODULE_CreateInstance
+ *
+ * If lib_only is TRUE, handle the module like a library even if it is a .EXE
  */
-HINSTANCE16 MODULE_CreateInstance( HMODULE16 hModule, LOADPARAMS *params )
+HINSTANCE16 MODULE_CreateInstance( HMODULE16 hModule, BOOL32 lib_only )
 {
     SEGTABLEENTRY *pSegment;
     NE_MODULE *pModule;
@@ -393,7 +394,7 @@
     if (hPrevInstance)
     {
         if (pModule->flags & NE_FFLAGS_LIBMODULE) return hPrevInstance;
-        if (params == (LOADPARAMS*)-1) return hPrevInstance;
+        if (lib_only) return hPrevInstance;
     }
 
     minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
@@ -533,6 +534,7 @@
       fprintf(stderr, "Sorry, this is an OS/2 linear executable (LX) file !\n");
       return (HMODULE32)12;
     }
+
     /* We now have a valid NE header */
 
     size = sizeof(NE_MODULE) +
@@ -929,10 +931,10 @@
         extern LRESULT ColorDlgProc(HWND16,UINT16,WPARAM16,LPARAM);
         extern LRESULT FileOpenDlgProc(HWND16,UINT16,WPARAM16,LPARAM);
         extern LRESULT FileSaveDlgProc(HWND16,UINT16,WPARAM16,LPARAM);
-        extern LRESULT FindTextDlgProc(HWND16,UINT16,WPARAM16,LPARAM);
+        extern LRESULT FindTextDlgProc16(HWND16,UINT16,WPARAM16,LPARAM);
         extern LRESULT PrintDlgProc(HWND16,UINT16,WPARAM16,LPARAM);
         extern LRESULT PrintSetupDlgProc(HWND16,UINT16,WPARAM16,LPARAM);
-        extern LRESULT ReplaceTextDlgProc(HWND16,UINT16,WPARAM16,LPARAM);
+        extern LRESULT ReplaceTextDlgProc16(HWND16,UINT16,WPARAM16,LPARAM);
 
         if (!strcmp(name,"ColorDlgProc"))
             return (FARPROC16)ColorDlgProc;
@@ -941,13 +943,13 @@
         if (!strcmp(name,"FileSaveDlgProc"))
             return (FARPROC16)FileSaveDlgProc;
         if (!strcmp(name,"FindTextDlgProc"))
-            return (FARPROC16)FindTextDlgProc;
+            return (FARPROC16)FindTextDlgProc16;
         if (!strcmp(name,"PrintDlgProc"))
             return (FARPROC16)PrintDlgProc;
         if (!strcmp(name,"PrintSetupDlgProc"))
             return (FARPROC16)PrintSetupDlgProc;
         if (!strcmp(name,"ReplaceTextDlgProc"))
-            return (FARPROC16)ReplaceTextDlgProc;
+            return (FARPROC16)ReplaceTextDlgProc16;
         fprintf(stderr,"warning: No mapping for %s(), add one in library/miscstubs.c\n",name);
         assert( FALSE );
         return NULL;
@@ -1135,14 +1137,18 @@
 /**********************************************************************
  *	    MODULE_Load
  *
- * Implementation of LoadModule()
+ * Implementation of LoadModule().
+ *
+ * cmd_line must contain the whole command-line, including argv[0] (and
+ * without a preceding length byte).
+ * If cmd_line is NULL, the module is loaded as a library even if it is a .exe
  */
-HINSTANCE16 MODULE_Load( LPCSTR name, LPVOID paramBlock, UINT16 uFlags)
+HINSTANCE16 MODULE_Load( LPCSTR name, UINT16 uFlags,
+                         LPCSTR cmd_line, LPCSTR env, UINT32 show_cmd )
 {
     HMODULE32 hModule;
     HINSTANCE16 hInstance, hPrevInstance;
     NE_MODULE *pModule;
-    LOADPARAMS *params = (LOADPARAMS *)paramBlock;
     OFSTRUCT ofs;
     HFILE32 hFile;
 
@@ -1152,7 +1158,7 @@
         if ((hModule = MODULE_CreateDummyModule( &ofs )) < 32) return hModule;
         pModule = (NE_MODULE *)GlobalLock16( hModule );
         hPrevInstance = 0;
-        hInstance = MODULE_CreateInstance( hModule, params );
+        hInstance = MODULE_CreateInstance( hModule, (cmd_line == NULL) );
     }
     else
     {
@@ -1180,9 +1186,10 @@
             hModule = MODULE_LoadExeHeader( hFile, &ofs );
             if (hModule < 32)
             {
-                if (hModule == 21)
-                    hModule = PE_LoadModule( hFile, &ofs, paramBlock );
-                else _lclose32( hFile );
+                if ((hModule == 21) && cmd_line)
+                    hModule = PE_LoadModule( hFile, &ofs, cmd_line,
+                                             env, show_cmd );
+                _lclose32( hFile );
 
                 if (hModule < 32)
                     fprintf( stderr, "LoadModule: can't load '%s', error=%d\n",
@@ -1197,7 +1204,7 @@
 
             MODULE_CreateSegments( hModule );
             hPrevInstance = 0;
-            hInstance = MODULE_CreateInstance(hModule,(LOADPARAMS*)paramBlock);
+            hInstance = MODULE_CreateInstance( hModule, (cmd_line == NULL) );
 
             /* Load the referenced DLLs */
 
@@ -1228,7 +1235,7 @@
         {
             pModule = MODULE_GetPtr( hModule );
             hPrevInstance = MODULE_GetInstance( hModule );
-            hInstance = MODULE_CreateInstance( hModule, params );
+            hInstance = MODULE_CreateInstance( hModule, (cmd_line == NULL) );
             if (hInstance != hPrevInstance)  /* not a library */
                 NE_LoadSegment( pModule, pModule->dgroup );
             pModule->count++;
@@ -1237,25 +1244,15 @@
 
     /* Create a task for this instance */
 
-    if (!(pModule->flags & NE_FFLAGS_LIBMODULE) && (paramBlock != (LPVOID)-1))
+    if (cmd_line && !(pModule->flags & NE_FFLAGS_LIBMODULE))
     {
-	HTASK16 hTask;
-        WORD	showcmd;
+        PDB32 *pdb;
 
 	pModule->flags |= NE_FFLAGS_GUI;
 
-	/* PowerPoint passes NULL as showCmd */
-	if (params->showCmd)
-		showcmd = *((WORD *)PTR_SEG_TO_LIN(params->showCmd)+1);
-	else
-		showcmd = 0; /* FIXME: correct */
-
-        hTask = TASK_CreateTask( hModule, hInstance, hPrevInstance,
-                                 params->hEnvironment,
-                                (LPSTR)PTR_SEG_TO_LIN( params->cmdLine ),
-                                 showcmd );
-
-	if( hTask && TASK_GetNextTask(hTask)) Yield16();
+        pdb = PROCESS_Create( pModule, cmd_line, env, hInstance,
+                              hPrevInstance, show_cmd );
+        if (pdb && (GetNumTasks() > 1)) Yield16();
     }
 
     return hInstance;
@@ -1267,7 +1264,37 @@
  */
 HINSTANCE16 LoadModule16( LPCSTR name, LPVOID paramBlock )
 {
-    return MODULE_Load( name, paramBlock, 0 );
+    LOADPARAMS *params = (LOADPARAMS *)paramBlock;
+    LPSTR cmd_line = (LPSTR)PTR_SEG_TO_LIN( params->cmdLine );
+    LPSTR new_cmd_line;
+    UINT16 show_cmd = 0;
+    LPCVOID env = NULL;
+    HINSTANCE16 hInstance;
+
+    if (!paramBlock || (paramBlock == (LPVOID)-1))
+        return LoadLibrary16( name );
+
+    params = (LOADPARAMS *)paramBlock;
+    cmd_line = (LPSTR)PTR_SEG_TO_LIN( params->cmdLine );
+    /* PowerPoint passes NULL as showCmd */
+    if (params->showCmd)
+        show_cmd = *((UINT16 *)PTR_SEG_TO_LIN(params->showCmd)+1);
+
+    if (!cmd_line) cmd_line = "";
+    else if (*cmd_line) cmd_line++;  /* skip the length byte */
+
+    if (!(new_cmd_line = HeapAlloc( GetProcessHeap(), 0,
+                                    strlen(cmd_line) + strlen(name) + 2 )))
+        return 0;
+    strcpy( new_cmd_line, name );
+    strcat( new_cmd_line, " " );
+    strcat( new_cmd_line, cmd_line );
+
+    if (params->hEnvironment) env = GlobalLock16( params->hEnvironment );
+    hInstance = MODULE_Load( name, 0, new_cmd_line, env, show_cmd );
+    if (params->hEnvironment) GlobalUnlock16( params->hEnvironment );
+    HeapFree( GetProcessHeap(), 0, new_cmd_line );
+    return hInstance;
 }
 
 /**********************************************************************
@@ -1280,8 +1307,8 @@
  */
 DWORD LoadModule32( LPCSTR name, LPVOID paramBlock ) 
 {
-#ifdef 0
-  LOADPARAMS32 *p = paramBlock;
+    LOADPARAMS32 *params = (LOADPARAMS32 *)paramBlock;
+#if 0
   STARTUPINFO st;
   PROCESSINFORMATION pi;
   st.cb = sizeof(STARTUPINFO);
@@ -1297,7 +1324,8 @@
   CloseHandle32(pi.hThread); 
 
 #else
-    return MODULE_Load( name, paramBlock, 0 );
+  return MODULE_Load( name, 0, params->lpCmdLine, params->lpEnvAddress, 
+                        *((UINT16 *)params->lpCmdShow + 1) );
 #endif
 }
 
@@ -1455,7 +1483,7 @@
     HMODULE32 hmod;
     
     hmod = PE_LoadLibraryEx32A(libname,PROCESS_Current(),hfile,flags);
-    if (hmod <= 32) {
+    if (hmod < 32) {
 	char buffer[256];
 
 	strcpy( buffer, libname );
@@ -1463,7 +1491,8 @@
 	hmod = PE_LoadLibraryEx32A(buffer,PROCESS_Current(),hfile,flags);
     }
     /* initialize all DLLs, which haven't been initialized yet. */
-    PE_InitializeDLLs( PROCESS_Current(), DLL_PROCESS_ATTACH, NULL);
+    if (hmod >= 32)
+        PE_InitializeDLLs( PROCESS_Current(), DLL_PROCESS_ATTACH, NULL);
     return hmod;
 }
 
@@ -1519,13 +1548,13 @@
     }
     TRACE(module, "(%08x) %s\n", (int)libname, libname);
 
-    handle = MODULE_Load( libname, (LPVOID)-1, 0 );
+    handle = MODULE_Load( libname, 0, NULL, NULL, 0 );
     if (handle == (HINSTANCE16)2)  /* file not found */
     {
         char buffer[256];
         lstrcpyn32A( buffer, libname, 252 );
         strcat( buffer, ".dll" );
-        handle = MODULE_Load( buffer, (LPVOID)-1, 0 );
+        handle = MODULE_Load( buffer, 0, NULL, NULL, 0 );
     }
     return handle;
 }
@@ -1577,23 +1606,13 @@
  */
 HINSTANCE32 WINAPI WinExec32( LPCSTR lpCmdLine, UINT32 nCmdShow )
 {
-    LOADPARAMS params;
-    HGLOBAL16 cmdShowHandle, cmdLineHandle;
     HINSTANCE32 handle = 2;
-    WORD *cmdShowPtr;
-    char *p, *cmdline, filename[256];
+    char *p, filename[256];
     static int use_load_module = 1;
     int  spacelimit = 0, exhausted = 0;
 
     if (!lpCmdLine)
         return 2;  /* File not found */
-    if (!(cmdShowHandle = GlobalAlloc16( 0, 2 * sizeof(WORD) )))
-        return 8;  /* Out of memory */
-    if (!(cmdLineHandle = GlobalAlloc16( 0, 2048 )))
-    {
-        GlobalFree16( cmdShowHandle );
-        return 8;  /* Out of memory */
-    }
 
     /* Keep trying to load a file by trying different filenames; e.g.,
        for the cmdline "abcd efg hij", try "abcd" with args "efg hij",
@@ -1603,15 +1622,8 @@
     while(!exhausted && handle == 2) {
 	int spacecount = 0;
 
-	/* Store nCmdShow */
-
-	cmdShowPtr = (WORD *)GlobalLock16( cmdShowHandle );
-	cmdShowPtr[0] = 2;
-	cmdShowPtr[1] = nCmdShow;
-
 	/* Build the filename and command-line */
 
-	cmdline = (char *)GlobalLock16( cmdLineHandle );
 	lstrcpyn32A(filename, lpCmdLine,
 		    sizeof(filename) - 4 /* for extension */);
 
@@ -1633,18 +1645,7 @@
 	    }
 	}
 
-	if (*p)
-	    lstrcpyn32A( cmdline + 1, p + 1, 255 );
-	else
-	    cmdline[1] = '\0';
-
-	cmdline[0] = strlen( cmdline + 1 );
 	*p = '\0';
-	/* this is a (hopefully acceptable hack to get the whole
-	   commandline for PROCESS_Create
-	   we put it after the processed one */
-	lstrcpyn32A(cmdline + (unsigned char)cmdline[0] +2,
-		    lpCmdLine, 2048 - 256);
 
 	/* Now load the executable file */
 
@@ -1652,11 +1653,7 @@
 	{
 	    /* Winelib: Use LoadModule() only for the program itself */
 	    if (__winelib) use_load_module = 0;
-	    params.hEnvironment = (HGLOBAL16)SELECTOROF( GetDOSEnvironment() );
-	    params.cmdLine  = (SEGPTR)WIN16_GlobalLock16( cmdLineHandle );
-	    params.showCmd  = (SEGPTR)WIN16_GlobalLock16( cmdShowHandle );
-	    params.reserved = 0;
-	    handle = LoadModule32( filename, &params );
+            handle = MODULE_Load( filename, 0, lpCmdLine, NULL, nCmdShow );
 	    if (handle == 2)  /* file not found */
 	    {
 		/* Check that the original file name did not have a suffix */
@@ -1666,8 +1663,9 @@
 		{
 		    p = filename + strlen(filename);
 		    strcpy( p, ".exe" );
-		    handle = LoadModule16( filename, &params );
-		    *p = '\0';  /* Remove extension */
+                    handle = MODULE_Load( filename, 0, lpCmdLine,
+                                          NULL, nCmdShow );
+                    *p = '\0';  /* Remove extension */
 		}
 	    }
 	}
@@ -1703,7 +1701,7 @@
 		    argptr = argv;
 		    if (iconic) *argptr++ = "-iconic";
 		    *argptr++ = unixfilename;
-		    p = cmdline + 1;
+		    p = strdup(lpCmdLine);
 		    while (1)
 		    {
 			while (*p && (*p == ' ' || *p == '\t')) *p++ = '\0';
@@ -1740,8 +1738,6 @@
 	}
     } /* while (!exhausted && handle < 32) */
 
-    GlobalFree16( cmdShowHandle );
-    GlobalFree16( cmdLineHandle );
     return handle;
 }
 
diff --git a/loader/ne_image.c b/loader/ne_image.c
index 3f00e22..5bb1088 100644
--- a/loader/ne_image.c
+++ b/loader/ne_image.c
@@ -28,15 +28,33 @@
 
 
 /***********************************************************************
+ *           NE_GetRelocAddrName
+ */
+static const char *NE_GetRelocAddrName( BYTE addr_type, int additive )
+{
+    switch(addr_type & 0x7f)
+    {
+    case NE_RADDR_LOWBYTE:   return additive ? "BYTE add" : "BYTE";
+    case NE_RADDR_OFFSET16:  return additive ? "OFFSET16 add" : "OFFSET16";
+    case NE_RADDR_POINTER32: return additive ? "POINTER32 add" : "POINTER32";
+    case NE_RADDR_SELECTOR:  return additive ? "SELECTOR add" : "SELECTOR";
+    case NE_RADDR_POINTER48: return additive ? "POINTER48 add" : "POINTER48";
+    case NE_RADDR_OFFSET32:  return additive ? "OFFSET32 add" : "OFFSET32";
+    }
+    return "???";
+}
+
+
+/***********************************************************************
  *           NE_LoadSegment
  */
 BOOL32 NE_LoadSegment( NE_MODULE *pModule, WORD segnum )
 {
     SEGTABLEENTRY *pSegTable, *pSeg;
     WORD *pModuleTable;
-    WORD count, i, offset;
+    WORD count, i, offset, next_offset;
     HMODULE16 module;
-    FARPROC16 address;
+    FARPROC16 address = 0;
     int fd;
     struct relocation_entry_s *rep, *reloc_entries;
     BYTE *func_name;
@@ -170,7 +188,7 @@
 	   and target */
 	additive = rep->relocation_type & NE_RELFLAG_ADDITIVE;
 	rep->relocation_type &= 0x3;
-	
+
 	switch (rep->relocation_type)
 	{
 	  case NE_RELTYPE_ORDINAL:
@@ -187,8 +205,7 @@
                              *((BYTE *)pModule + pModule->name_table),
                              (char *)pModule + pModule->name_table + 1 );
                 else
-                    fprintf( stderr, "Warning: no handler for %*.*s.%d, setting to 0:0\n",
-                            *((BYTE *)pTarget + pTarget->name_table),
+                    fprintf( stderr, "Warning: no handler for %.*s.%d, setting to 0:0\n",
                             *((BYTE *)pTarget + pTarget->name_table),
                             (char *)pTarget + pTarget->name_table + 1,
                             ordinal );
@@ -196,11 +213,11 @@
             if (TRACE_ON(fixup))
             {
                 NE_MODULE *pTarget = MODULE_GetPtr( module );
-                TRACE(fixup, "%d: %*.*s.%d=%04x:%04x\n", i + 1, 
-			     *((BYTE *)pTarget + pTarget->name_table),
-			     *((BYTE *)pTarget + pTarget->name_table),
-			     (char *)pTarget + pTarget->name_table + 1,
-			     ordinal, HIWORD(address), LOWORD(address) );
+                TRACE( fixup, "%d: %.*s.%d=%04x:%04x %s\n", i + 1, 
+                       *((BYTE *)pTarget + pTarget->name_table),
+                       (char *)pTarget + pTarget->name_table + 1,
+                       ordinal, HIWORD(address), LOWORD(address),
+                       NE_GetRelocAddrName( rep->address_type, additive ) );
             }
 	    break;
 	    
@@ -218,16 +235,17 @@
             {
                 NE_MODULE *pTarget = MODULE_GetPtr( module );
                 ERR(fixup, "Warning: no handler for %.*s.%s, setting to 0:0\n",
-			    *((BYTE *)pTarget + pTarget->name_table),
-			    (char *)pTarget + pTarget->name_table + 1, func_name );
+                    *((BYTE *)pTarget + pTarget->name_table),
+                    (char *)pTarget + pTarget->name_table + 1, func_name );
             }
             if (TRACE_ON(fixup))
             {
 	        NE_MODULE *pTarget = MODULE_GetPtr( module );
-                TRACE(fixup, "%d: %.*s.%s=%04x:%04x\n", i + 1, 
-			     *((BYTE *)pTarget + pTarget->name_table),
-			     (char *)pTarget + pTarget->name_table + 1,
-			     func_name, HIWORD(address), LOWORD(address) );
+                TRACE( fixup, "%d: %.*s.%s=%04x:%04x %s\n", i + 1, 
+                       *((BYTE *)pTarget + pTarget->name_table),
+                       (char *)pTarget + pTarget->name_table + 1,
+                       func_name, HIWORD(address), LOWORD(address),
+                       NE_GetRelocAddrName( rep->address_type, additive ) );
             }
 	    break;
 	    
@@ -241,8 +259,9 @@
                 address = (FARPROC16)PTR_SEG_OFF_TO_SEGPTR( pSegTable[rep->target1-1].selector, rep->target2 );
 	    }
 	    
-	    TRACE(fixup,"%d: %04x:%04x\n", 
-			  i + 1, HIWORD(address), LOWORD(address) );
+	    TRACE( fixup,"%d: %04x:%04x %s\n", 
+                   i + 1, HIWORD(address), LOWORD(address),
+                   NE_GetRelocAddrName( rep->address_type, additive ) );
 	    break;
 
 	  case NE_RELTYPE_OSFIXUP:
@@ -254,18 +273,11 @@
 	     * successfully emulate the coprocessor if it doesn't
 	     * exist.
 	     */
-	    TRACE(fixup, "%d: ADDR TYPE %d,  TYPE %d,  OFFSET %04x,  "
-			 "TARGET %04x %04x\n", i + 1, rep->address_type, 
-			 rep->relocation_type, rep->offset, rep->target1, rep->target2);
+	    TRACE( fixup, "%d: TYPE %d, OFFSET %04x, TARGET %04x %04x %s\n",
+                   i + 1, rep->relocation_type, rep->offset,
+                   rep->target1, rep->target2,
+                   NE_GetRelocAddrName( rep->address_type, additive ) );
 	    continue;
-	    
-	  default:
-	    WARN(fixup, "WARNING: %d: ADDR TYPE %d,  "
-			  "unknown TYPE %d, OFFSET %04x, TARGET %04x %04x\n",
-			  i + 1, rep->address_type, rep->relocation_type, 
-			  rep->offset, rep->target1, rep->target2);
-	    free(reloc_entries);
-	    return FALSE;
 	}
 
 	offset  = rep->offset;
@@ -273,76 +285,76 @@
         /* Apparently, high bit of address_type is sometimes set; */
         /* we ignore it for now */
 	if (rep->address_type > NE_RADDR_OFFSET32)
-            fprintf( stderr, "WARNING: module %s: unknown reloc addr type = 0x%02x. Please report.\n",
-                     MODULE_GetModuleName(pModule->self), rep->address_type );
+            ERR( fixup, "WARNING: module %s: unknown reloc addr type = 0x%02x. Please report.\n",
+                 MODULE_GetModuleName(pModule->self), rep->address_type );
 
-	switch (rep->address_type & 0x7f)
-	{
-	  case NE_RADDR_LOWBYTE:
-            do {
-                sp = PTR_SEG_OFF_TO_LIN( pSeg->selector, offset );
-                TRACE(fixup,"    %04x:%04x:%04x BYTE%s\n",
-                              pSeg->selector, offset, *sp, additive ? " additive":"");
-                offset = *sp;
-		if(additive)
-                    *(unsigned char*)sp = (unsigned char)(((int)address+offset) & 0xFF);
-		else
-                    *(unsigned char*)sp = (unsigned char)((int)address & 0xFF);
-            }
-            while (offset && offset != 0xffff && !additive);
-            break;
-
-	  case NE_RADDR_OFFSET16:
-	    do {
-                sp = PTR_SEG_OFF_TO_LIN( pSeg->selector, offset );
-		TRACE(fixup,"    %04x:%04x:%04x OFFSET16%s\n",
-                              pSeg->selector, offset, *sp, additive ? " additive" : "" );
-		offset = *sp;
-		*sp = LOWORD(address);
-		if (additive) *sp += offset;
-	    } 
-	    while (offset && offset != 0xffff && !additive);
-	    break;
-	    
-	  case NE_RADDR_POINTER32:
-	    do {
-                sp = PTR_SEG_OFF_TO_LIN( pSeg->selector, offset );
-		TRACE(fixup,"    %04x:%04x:%04x POINTER32%s\n",
-                              pSeg->selector, offset, *sp, additive ? " additive" : "" );
-		offset = *sp;
-		*sp    = LOWORD(address);
-		if (additive) *sp += offset;
+        if (additive)
+        {
+            sp = PTR_SEG_OFF_TO_LIN( pSeg->selector, offset );
+            TRACE( fixup,"    %04x:%04x\n", offset, *sp );
+            switch (rep->address_type & 0x7f)
+            {
+            case NE_RADDR_LOWBYTE:
+                *(BYTE *)sp += LOBYTE((int)address);
+                break;
+            case NE_RADDR_OFFSET16:
+		*sp += LOWORD(address);
+                break;
+            case NE_RADDR_POINTER32:
+		*sp += LOWORD(address);
 		*(sp+1) = HIWORD(address);
-	    } 
-	    while (offset && offset != 0xffff && !additive);
-	    break;
-	    
-	  case NE_RADDR_SELECTOR:
-	    do {
-                sp = PTR_SEG_OFF_TO_LIN( pSeg->selector, offset );
-		TRACE(fixup,"    %04x:%04x:%04x SELECTOR%s\n",
-                              pSeg->selector, offset, *sp, additive ? " additive" : "" );
-		offset = *sp;
-		*sp    = HIWORD(address);
+                break;
+            case NE_RADDR_SELECTOR:
 		/* Borland creates additive records with offset zero. Strange, but OK */
-		if(additive && offset)
-        	fprintf(stderr,"Additive selector to %4.4x.Please report\n",offset);
-	    } 
-	    while (offset && offset != 0xffff && !additive);
-	    break;
-	    
-	  default:
-	    WARN(fixup, "WARNING: %d: unknown ADDR TYPE %d,  "
-			 "TYPE %d,  OFFSET %04x,  TARGET %04x %04x\n",
-			 i + 1, rep->address_type, rep->relocation_type, 
-			 rep->offset, rep->target1, rep->target2);
-	    free(reloc_entries);
-	    return FALSE;
-	}
+                if (*sp)
+                    ERR(fixup,"Additive selector to %04x.Please report\n",*sp);
+		else
+                    *sp = HIWORD(address);
+            default:
+                goto unknown;
+            }
+        }
+        else  /* non-additive fixup */
+        {
+            do
+            {
+                sp = PTR_SEG_OFF_TO_LIN( pSeg->selector, offset );
+                next_offset = *sp;
+                TRACE( fixup,"    %04x:%04x\n", offset, *sp );
+                switch (rep->address_type & 0x7f)
+                {
+                case NE_RADDR_LOWBYTE:
+                    *(BYTE *)sp = LOBYTE((int)address);
+                    break;
+                case NE_RADDR_OFFSET16:
+                    *sp = LOWORD(address);
+                    break;
+                case NE_RADDR_POINTER32:
+                    *(FARPROC16 *)sp = address;
+                    break;
+                case NE_RADDR_SELECTOR:
+                    *sp = SELECTOROF(address);
+                    break;
+                default:
+                    goto unknown;
+                }
+                if (next_offset == offset) break;  /* avoid infinite loop */
+                if (next_offset >= GlobalSize16(pSeg->selector)) break;
+                offset = next_offset;
+            } while (offset && (offset != 0xffff));
+        }
     }
 
     free(reloc_entries);
     return TRUE;
+
+unknown:
+    WARN(fixup, "WARNING: %d: unknown ADDR TYPE %d,  "
+         "TYPE %d,  OFFSET %04x,  TARGET %04x %04x\n",
+         i + 1, rep->address_type, rep->relocation_type, 
+         rep->offset, rep->target1, rep->target2);
+    free(reloc_entries);
+    return FALSE;
 }
 
 
@@ -429,7 +441,8 @@
             /* its handle in the list of DLLs to initialize.   */
             HMODULE16 hDLL;
 
-            if ((hDLL = MODULE_Load( buffer, (LPVOID)-1, NE_FFLAGS_IMPLICIT )) == 2)
+            if ((hDLL = MODULE_Load( buffer, NE_FFLAGS_IMPLICIT,
+                                     NULL, NULL, 0 )) == 2)
             {
                 /* file not found */
                 char *p;
@@ -439,7 +452,7 @@
                 if (!(p = strrchr( buffer, '\\' ))) p = buffer;
                 memcpy( p + 1, pstr + 1, *pstr );
                 strcpy( p + 1 + *pstr, ".dll" );
-                hDLL = MODULE_Load( buffer, (LPVOID)-1, NE_FFLAGS_IMPLICIT );
+                hDLL = MODULE_Load( buffer, NE_FFLAGS_IMPLICIT, NULL, NULL, 0);
             }
             if (hDLL < 32)
             {
diff --git a/loader/pe_image.c b/loader/pe_image.c
index e1923f1..43cc74c 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -21,15 +21,23 @@
  *   state MUST be correct since this function can be called with the SAME image
  *   AGAIN. (Thats recursion for you.) That means MODREF.module and
  *   NE_MODULE.module32.
- * - No, you cannot use Linux mmap() to mmap() the images directly. Linux aligns
- *   them at pagesize (4096), Win32 requires 512 byte alignment.
+ * - No, you (usually) cannot use Linux mmap() to mmap() the images directly.
+ *
+ *   The problem is, that there is not direct 1:1 mapping from a diskimage and
+ *   a memoryimage. The headers at the start are mapped linear, but the sections
+ *   are not. For x86 the sections are 512 byte aligned in file and 4096 byte
+ *   aligned in memory. Linux likes them 4096 byte aligned in memory (due to
+ *   x86 pagesize, this cannot be fixed without a rather large kernel rewrite)
+ *   and 'blocksize' file-aligned (offsets). Since we have 512/1024/2048 (CDROM)
+ *   and other byte blocksizes, we can't do this. However, this could be less
+ *   difficult to support... (See mm/filemap.c).
  * - All those function map things into a new addresspace. From the wrong
  *   process and the wrong thread. So calling other API functions will mess 
  *   things up badly sometimes.
  */
 
-/*#include <ctype.h>*/
 #include <errno.h>
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -49,9 +57,7 @@
 #include "module.h"
 #include "global.h"
 #include "task.h"
-#include "ldt.h"
 #include "debug.h"
-#include "xmalloc.h"
 
 static void PE_InitDLL(PE_MODREF* modref, DWORD type, LPVOID lpReserved);
 
@@ -721,8 +727,6 @@
         return 1;
 }
 
-HINSTANCE16 MODULE_CreateInstance(HMODULE16 hModule,LOADPARAMS *params);
-
 /******************************************************************************
  * The PE Library Loader frontend. 
  * FIXME: handle the flags.
@@ -743,11 +747,14 @@
 			return hModule;
 		/* check if this module is already mapped */
 		pem 	= process->modref_list;
+		pModule = MODULE_GetPtr(hModule);
 		while (pem) {
-			if (pem->module == hModule) return hModule;
+			if (pem->module == hModule) {
+				pModule->count++;
+				return hModule;
+			}
 			pem = pem->next;
 		}
-		pModule = MODULE_GetPtr(hModule);
 		if (pModule->flags & NE_FFLAGS_BUILTIN) {
 			IMAGE_DOS_HEADER	*dh;
 			IMAGE_NT_HEADERS	*nh;
@@ -804,9 +811,10 @@
 /*****************************************************************************
  * Load the PE main .EXE. All other loading is done by PE_LoadLibraryEx32A
  * FIXME: this function should use PE_LoadLibraryEx32A, but currently can't
- * due to the TASK_CreateTask stuff.
+ * due to the PROCESS_Create stuff.
  */
-HINSTANCE16 PE_LoadModule( HFILE32 hFile, OFSTRUCT *ofs, LOADPARAMS* params )
+HINSTANCE16 PE_LoadModule( HFILE32 hFile, OFSTRUCT *ofs, LPCSTR cmd_line,
+                           LPCSTR env, UINT16 show_cmd )
 {
     HMODULE16 hModule16;
     HMODULE32 hModule32;
@@ -819,17 +827,15 @@
     pModule->flags = NE_FFLAGS_WIN32;
 
     pModule->module32 = hModule32 = PE_LoadImage( hFile );
-    CloseHandle( hFile );
     if (hModule32 < 32) return 21;
 
-    hInstance = MODULE_CreateInstance( hModule16, params );
-    if (!(PE_HEADER(hModule32)->FileHeader.Characteristics & IMAGE_FILE_DLL))
+    hInstance = MODULE_CreateInstance( hModule16, (cmd_line == NULL) );
+    if (cmd_line &&
+        !(PE_HEADER(hModule32)->FileHeader.Characteristics & IMAGE_FILE_DLL))
     {
-        HTASK16 hTask = TASK_CreateTask( hModule16, hInstance, 0,
-                                         params->hEnvironment,
-                                      (LPSTR)PTR_SEG_TO_LIN( params->cmdLine ),
-                               *((WORD*)PTR_SEG_TO_LIN(params->showCmd) + 1) );
-        TDB *pTask = (TDB *)GlobalLock16( hTask );
+        PDB32 *pdb = PROCESS_Create( pModule, cmd_line, env,
+                                     hInstance, 0, show_cmd );
+        TDB *pTask = (TDB *)GlobalLock16( pdb->task );
         thdb = pTask->thdb;
     }
     if (!PE_MapImage( &(pModule->module32), thdb->process, ofs, 0 ))
diff --git a/loader/resource.c b/loader/resource.c
index 24d87f2..e3591b0 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -61,8 +61,8 @@
     }
 
     TRACE(resource, "module=%04x name=%s type=%s\n", 
-		 hModule, debugres(PTR_SEG_TO_LIN(name)), 
-		 debugres(PTR_SEG_TO_LIN(type)) );
+		 hModule, debugres_a(PTR_SEG_TO_LIN(name)), 
+		 debugres_a(PTR_SEG_TO_LIN(type)) );
 
     if ((pModule = MODULE_GetPtr( hModule )))
     {
@@ -414,7 +414,6 @@
 HACCEL16 WINAPI LoadAccelerators16(HINSTANCE16 instance, SEGPTR lpTableName)
 {
     HRSRC16	hRsrc;
-    HACCEL16    hAccel;
 
     if (HIWORD(lpTableName))
         TRACE(accel, "%04x '%s'\n",
@@ -423,7 +422,7 @@
         TRACE(accel, "%04x %04x\n",
                        instance, LOWORD(lpTableName) );
 
-    if (!(hRsrc = FindResource16( instance, lpTableName, RT_ACCELERATOR ))) {
+    if (!(hRsrc = FindResource16( instance, lpTableName, RT_ACCELERATOR16 ))) {
       WARN(accel, "couldn't find accelerator table resource\n");
       return 0;
     }
@@ -453,8 +452,8 @@
         TRACE(accel, "%p 0x%04x\n",
                        (LPVOID)instance, LOWORD(lpTableName) );
 
-    if (!(hRsrc = FindResource32W( instance, lpTableName, 
-				   (LPCWSTR)RT_ACCELERATOR ))) {
+    if (!(hRsrc = FindResource32W( instance, lpTableName, RT_ACCELERATOR32W )))
+    {
       WARN(accel, "couldn't find accelerator table resource\n");
       hRetval = 0;
     }
@@ -625,7 +624,7 @@
     TRACE(resource,"inst=%04x id=%04x buff=%08x len=%d\n",
                      instance, resource_id, (int) buffer, buflen);
 
-    hrsrc = FindResource16( instance, (SEGPTR)((resource_id>>4)+1), RT_STRING );
+    hrsrc = FindResource16( instance, (SEGPTR)((resource_id>>4)+1), RT_STRING16 );
     if (!hrsrc) return 0;
     hmem = LoadResource16( instance, hrsrc );
     if (!hmem) return 0;
@@ -658,7 +657,7 @@
 }
 
 /**********************************************************************
- *	LoadString32W		(USER32.375)
+ *	LoadString32W		(USER32.376)
  */
 INT32 WINAPI LoadString32W( HINSTANCE32 instance, UINT32 resource_id,
                             LPWSTR buffer, INT32 buflen )
@@ -674,8 +673,8 @@
     TRACE(resource, "instance = %04x, id = %04x, buffer = %08x, "
 	   "length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
 
-    hrsrc = FindResource32W( instance, (LPCWSTR)((resource_id>>4)+1), 
-		(LPCWSTR)RT_STRING );
+    hrsrc = FindResource32W( instance, (LPCWSTR)((resource_id>>4)+1),
+                             RT_STRING32W );
     if (!hrsrc) return 0;
     hmem = LoadResource32( instance, hrsrc );
     if (!hmem) return 0;
@@ -709,7 +708,7 @@
 }
 
 /**********************************************************************
- *	LoadString32A	(USER32.374)
+ *	LoadString32A	(USER32.375)
  */
 INT32 WINAPI LoadString32A( HINSTANCE32 instance, UINT32 resource_id,
                             LPSTR buffer, INT32 buflen )
@@ -726,6 +725,8 @@
 	    lstrcpynWtoA( buffer, buffer2, buflen );
 	    retval = lstrlen32A( buffer );
 	}
+	else
+	    *buffer = 0;
 	HeapFree( GetProcessHeap(), 0, buffer2 );
     }
     return retval;
@@ -777,7 +778,7 @@
     TRACE(resource, "instance = %08lx, id = %08lx, buffer = %p, length = %ld\n", (DWORD)instance, (DWORD)id, buffer, (DWORD)buflen);
 
     /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/
-    hrsrc = FindResourceEx32W(instance,(LPWSTR)1,(LPCWSTR)RT_MESSAGELIST,lang);
+    hrsrc = FindResourceEx32W(instance,(LPWSTR)1,RT_MESSAGELIST32W,lang);
     if (!hrsrc) return 0;
     hmem = LoadResource32( instance, hrsrc );
     if (!hmem) return 0;
@@ -854,7 +855,7 @@
     hModule = GetExePtr( hModule );
 
     TRACE(resource, "module=%04x type=%s\n", 
-		 hModule, debugres(PTR_SEG_TO_LIN(s)) );
+		 hModule, debugres_a(PTR_SEG_TO_LIN(s)) );
 
     if ((pModule = MODULE_GetPtr( hModule )))
     {
diff --git a/loader/signal.c b/loader/signal.c
index 931a461..05cf70a 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -3,6 +3,8 @@
  *
  */
 
+#include "config.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <signal.h>
@@ -16,13 +18,15 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 
-#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__svr4__) || defined(_SCO_DS) || defined(__EMX__)
-#if !defined(_SCO_DS) && !defined(__EMX__)
-#include <sys/syscall.h>
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
 #endif
-#include <sys/param.h>
+#ifdef HAVE_SYSCALL_H
+# include <syscall.h>
 #else
-#include <syscall.h>
+# ifdef HAVE_SYS_SYSCALL_H
+#  include <sys/syscall.h>
+# endif
 #endif
 
 #include "miscemu.h"
@@ -154,9 +158,7 @@
 {
     extern void SYNC_SetupSignals(void);
 
-    sigemptyset(&async_signal_set);
-
-#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined (__svr4__) || defined(_SCO_DS)
+#ifdef HAVE_SIGALTSTACK
     struct sigaltstack ss;
     ss.ss_sp    = SIGNAL_Stack;
     ss.ss_size  = sizeof(SIGNAL_Stack);
@@ -166,8 +168,10 @@
         perror("sigstack");
         return FALSE;
     }
-#endif  /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __svr4__ || _SCO_DS */
+#endif  /* HAVE_SIGALTSTACK */
     
+    sigemptyset(&async_signal_set);
+
     SIGNAL_SetHandler( SIGCHLD, (void (*)())SIGNAL_child, 1);
 #ifdef CONFIG_IPC
     sigaddset(&async_signal_set, SIGUSR2);
diff --git a/loader/task.c b/loader/task.c
index 31218b6..f168427 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -25,6 +25,7 @@
 #include "queue.h"
 #include "selectors.h"
 #include "stackframe.h"
+#include "task.h"
 #include "thread.h"
 #include "toolhelp.h"
 #include "winnt.h"
@@ -46,21 +47,8 @@
 static HTASK16 hTaskToKill = 0;
 static HTASK16 hLockedTask = 0;
 static UINT16 nTaskCount = 0;
-static HGLOBAL16 hDOSEnvironment = 0;
 
-static HGLOBAL16 TASK_CreateDOSEnvironment(void);
-static void	 TASK_YieldToSystem(TDB*);
-
-
-/***********************************************************************
- *           TASK_Init
- */
-BOOL32 TASK_Init(void)
-{
-    if (!(hDOSEnvironment = TASK_CreateDOSEnvironment()))
-        fprintf( stderr, "Not enough memory for DOS Environment\n" );
-    return (hDOSEnvironment != 0);
-}
+static void TASK_YieldToSystem(TDB*);
 
 
 /***********************************************************************
@@ -76,115 +64,6 @@
 
 
 /***********************************************************************
- *           TASK_CreateDOSEnvironment
- *
- * Create the original DOS environment.
- */
-static HGLOBAL16 TASK_CreateDOSEnvironment(void)
-{
-    static const char program_name[] = "KRNL386.EXE";
-    char **e, *p;
-    int initial_size, size, i, winpathlen, sysdirlen;
-    HGLOBAL16 handle;
-
-    extern char **environ;
-
-    /* DOS environment format:
-     * ASCIIZ   string 1
-     * ASCIIZ   string 2
-     * ...
-     * ASCIIZ   string n
-     * ASCIIZ   PATH=xxx
-     * BYTE     0
-     * WORD     1
-     * ASCIIZ   program name (e.g. C:\WINDOWS\SYSTEM\KRNL386.EXE)
-     */
-
-    /* First compute the size of the fixed part of the environment */
-
-    for (i = winpathlen = 0; ; i++)
-    {
-        int len = DIR_GetDosPath( i, NULL, 0 );
-        if (!len) break;
-        winpathlen += len + 1;
-    }
-    if (!winpathlen) winpathlen = 1;
-    sysdirlen  = GetSystemDirectory32A( NULL, 0 ) + 1;
-    initial_size = 5 + winpathlen +           /* PATH=xxxx */
-                   1 +                        /* BYTE 0 at end */
-                   sizeof(WORD) +             /* WORD 1 */
-                   sysdirlen +                /* program directory */
-                   strlen(program_name) + 1;  /* program name */
-
-    /* Compute the total size of the Unix environment (except path) */
-
-    for (e = environ, size = initial_size; *e; e++)
-    {
-	if (lstrncmpi32A(*e, "path=", 5))
-	{
-            int len = strlen(*e) + 1;
-            if (size + len >= 32767)
-            {
-                fprintf( stderr, "Warning: environment larger than 32k.\n" );
-                break;
-            }
-            size += len;
-	}
-    }
-
-
-    /* Now allocate the environment */
-
-    if (!(handle = GlobalAlloc16( GMEM_FIXED, size ))) return 0;
-    p = (char *)GlobalLock16( handle );
-
-    /* And fill it with the Unix environment */
-
-    for (e = environ, size = initial_size; *e; e++)
-    {
-	if (lstrncmpi32A(*e, "path=", 5))
-	{
-            int len = strlen(*e) + 1;
-            if (size + len >= 32767) break;
-            strcpy( p, *e );
-            size += len;
-            p    += len;
-	}
-    }
-
-    /* Now add the path */
-
-    strcpy( p, "PATH=" );
-    for (i = 0, p += 5; ; i++)
-    {
-        if (!DIR_GetDosPath( i, p, winpathlen )) break;
-        p += strlen(p);
-        *p++ = ';';
-    }
-    if (p[-1] == ';') p[-1] = '\0';
-    else p++;
-
-    /* Now add the program name */
-
-    *p++ = '\0';
-    PUT_WORD( p, 1 );
-    p += sizeof(WORD);
-    GetSystemDirectory32A( p, sysdirlen );
-    strcat( p, "\\" );
-    strcat( p, program_name );
-
-    /* Display it */
-
-    p = (char *) GlobalLock16( handle );
-    TRACE(task, "Master DOS environment at %p\n", p);
-    for (; *p; p += strlen(p) + 1) TRACE(task, "    %s\n", p);
-    TRACE(task, "Progname: %s\n", p+3 );
-
-    return handle;
-}
-
-
-/***********************************************************************
  *           TASK_LinkTask
  */
 static void TASK_LinkTask( HTASK16 hTask )
@@ -390,51 +269,28 @@
 
 
 /***********************************************************************
- *           TASK_CreateTask
+ *           TASK_Create
  */
-HTASK16 TASK_CreateTask( HMODULE16 hModule, HINSTANCE16 hInstance,
-                         HINSTANCE16 hPrevInstance, HANDLE16 hEnvironment,
-                         LPCSTR cmdLine, UINT16 cmdShow )
+HTASK16 TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance,
+                     HINSTANCE16 hPrevInstance, UINT16 cmdShow)
 {
     HTASK16 hTask;
     TDB *pTask;
-    PDB32 *pdb32;
-    HGLOBAL16 hParentEnv;
-    NE_MODULE *pModule;
-    SEGTABLEENTRY *pSegTable;
-    LPSTR name;
+    LPSTR name, cmd_line;
     WORD sp;
     char *stack32Top;
     STACK16FRAME *frame16;
     STACK32FRAME *frame32;
-    
-    if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
-    pSegTable = NE_SEG_TABLE( pModule );
+    PDB32 *pdb32 = thdb->process;
+    SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
 
       /* Allocate the task structure */
 
     hTask = GLOBAL_Alloc( GMEM_FIXED | GMEM_ZEROINIT, sizeof(TDB),
-                          hModule, FALSE, FALSE, FALSE );
+                          pModule->self, FALSE, FALSE, FALSE );
     if (!hTask) return 0;
     pTask = (TDB *)GlobalLock16( hTask );
 
-      /* Allocate the new environment block */
-
-    if (!(hParentEnv = hEnvironment))
-    {
-        TDB *pParent = (TDB *)GlobalLock16( hCurrentTask );
-        hParentEnv = pParent ? pParent->pdb.environment : hDOSEnvironment;
-    }
-    /* FIXME: do we really need to make a copy also when */
-    /*        we don't use the parent environment? */
-    if (!(hEnvironment = GlobalAlloc16( GMEM_FIXED, GlobalSize16(hParentEnv))))
-    {
-        GlobalFree16( hTask );
-        return 0;
-    }
-    memcpy( GlobalLock16( hEnvironment ), GlobalLock16( hParentEnv ),
-            GlobalSize16( hParentEnv ) );
-
     /* Fill the task structure */
 
     pTask->nEvents       = 1;  /* So the task can be started */
@@ -447,10 +303,11 @@
     pTask->version       = pModule->expected_version;
     pTask->hInstance     = hInstance;
     pTask->hPrevInstance = hPrevInstance;
-    pTask->hModule       = hModule;
+    pTask->hModule       = pModule->self;
     pTask->hParent       = hCurrentTask;
     pTask->magic         = TDB_MAGIC;
     pTask->nCmdShow      = cmdShow;
+    pTask->thdb          = thdb;
     pTask->curdrive      = DRIVE_GetCurrentDrive() | 0x80;
     strcpy( pTask->curdir, "\\" );
     lstrcpyn32A( pTask->curdir + 1, DRIVE_GetDosCwd( DRIVE_GetCurrentDrive() ),
@@ -462,13 +319,13 @@
 
       /* Copy the module name */
 
-    name = MODULE_GetModuleName( hModule );
+    name = MODULE_GetModuleName( pModule->self );
     strncpy( pTask->module_name, name, sizeof(pTask->module_name) );
 
       /* Allocate a selector for the PDB */
 
     pTask->hPDB = GLOBAL_CreateBlock( GMEM_FIXED, &pTask->pdb, sizeof(PDB),
-                                      hModule, FALSE, FALSE, FALSE, NULL );
+                                    pModule->self, FALSE, FALSE, FALSE, NULL );
 
       /* Fill the PDB */
 
@@ -484,9 +341,15 @@
                                (int)&((PDB *)0)->fileHandles );
     pTask->pdb.hFileHandles = 0;
     memset( pTask->pdb.fileHandles, 0xff, sizeof(pTask->pdb.fileHandles) );
-    pTask->pdb.environment    = hEnvironment;
+    pTask->pdb.environment    = pdb32->env_db->env_sel;
     pTask->pdb.nbFiles        = 20;
-    lstrcpyn32A( pTask->pdb.cmdLine, cmdLine, sizeof(pTask->pdb.cmdLine) );
+
+    /* Fill the command line */
+
+    cmd_line = pdb32->env_db->cmd_line;
+    while (*cmd_line && (*cmd_line != ' ') && (*cmd_line != '\t')) cmd_line++;
+    lstrcpyn32A( pTask->pdb.cmdLine+1, cmd_line, sizeof(pTask->pdb.cmdLine)-1);
+    pTask->pdb.cmdLine[0] = strlen( pTask->pdb.cmdLine + 1 );
 
       /* Get the compatibility flags */
 
@@ -507,33 +370,12 @@
     pTask->dta = PTR_SEG_OFF_TO_SEGPTR( pTask->hPDB, 
                                 (int)&pTask->pdb.cmdLine - (int)&pTask->pdb );
 
-    /* Create the Win32 part of the task */
-
-    pdb32 = PROCESS_Create( pTask, cmdLine );
-    /* FIXME: check for pdb32 == NULL.  */
-    pdb32->task = hTask;
-    if (pModule->flags & NE_FFLAGS_WIN32)
-    {
-    /*
-        LPTHREAD_START_ROUTINE start =
-            (LPTHREAD_START_ROUTINE)(
-	    	PROCESS_Current()->exe_modref->load_addr +
-		PROCESS_Current()->exe_modref->pe_module->pe_header->OptionalHeader.AddressOfEntryPoint);
-     */
-        pTask->thdb = THREAD_Create( pdb32,
-          PE_HEADER(pModule->module32)->OptionalHeader.SizeOfStackReserve,
-                                     NULL, NULL );
-    }
-    else
-        pTask->thdb = THREAD_Create( pdb32, 0, NULL, NULL );
-    /* FIXME: check for pTask->thdb == NULL.  */
-
     /* Create the 16-bit stack frame */
 
     if (!(sp = pModule->sp))
         sp = pSegTable[pModule->ss-1].minsize + pModule->stack_size;
     sp &= ~1;
-    pTask->thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( hInstance, sp );
+    pTask->thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( pTask->hInstance, sp );
     pTask->thdb->cur_stack -= sizeof(STACK16FRAME) + sizeof(STACK32FRAME *);
     frame16 = (STACK16FRAME *)PTR_SEG_TO_LIN( pTask->thdb->cur_stack );
     frame16->ebp = sp + (int)&((STACK16FRAME *)0)->bp;
@@ -564,7 +406,7 @@
     TASK_LinkTask( hTask );
 
     TRACE(task, "module='%s' cmdline='%s' task=%04x\n",
-                  name, cmdLine, hTask );
+          name, cmd_line, hTask );
 
     return hTask;
 }
@@ -840,6 +682,14 @@
          */
         EAX_reg(context) = 1;
         EBX_reg(context) = pTask->pdb.cmdLine[0] ? 0x81 : 0x80;
+        
+	if (!pTask->pdb.cmdLine[0]) EBX_reg(context) = 0x80;
+	else
+        {
+            LPBYTE p = &pTask->pdb.cmdLine[1];
+            while ((*p == ' ') || (*p == '\t')) p++;
+            EBX_reg(context) = 0x80 + (p - pTask->pdb.cmdLine);
+        }
         ECX_reg(context) = pModule->stack_size;
         EDX_reg(context) = pTask->nCmdShow;
         ESI_reg(context) = (DWORD)pTask->hPrevInstance;
@@ -1294,7 +1144,7 @@
     TDB *pTask;
 
     if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0;
-    return (SEGPTR)WIN16_GlobalLock16( pTask->pdb.environment );
+    return PTR_SEG_OFF_TO_SEGPTR( pTask->pdb.environment, 0 );
 }
 
 
@@ -1491,7 +1341,7 @@
 
 
 /***********************************************************************
- *           GetAppCompatFlags32   (USER32.205)
+ *           GetAppCompatFlags32   (USER32.206)
  */
 DWORD WINAPI GetAppCompatFlags32( HTASK32 hTask )
 {
diff --git a/memory/Makefile.in b/memory/Makefile.in
index 01235a2..5157bf0 100644
--- a/memory/Makefile.in
+++ b/memory/Makefile.in
@@ -7,6 +7,7 @@
 
 C_SRCS = \
 	atom.c \
+	environ.c \
 	global.c \
 	heap.c \
 	ldt.c \
diff --git a/memory/environ.c b/memory/environ.c
new file mode 100644
index 0000000..8e4a28a
--- /dev/null
+++ b/memory/environ.c
@@ -0,0 +1,437 @@
+/*
+ * Process environment management
+ *
+ * Copyright 1996, 1998 Alexandre Julliard
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include "process.h"
+#include "heap.h"
+#include "selectors.h"
+#include "winerror.h"
+
+/* Format of an environment block:
+ * ASCIIZ   string 1 (xx=yy format)
+ * ...
+ * ASCIIZ   string n
+ * BYTE     0
+ * WORD     1
+ * ASCIIZ   program name (e.g. C:\WINDOWS\SYSTEM\KRNL386.EXE)
+ *
+ * Notes:
+ * - contrary to Microsoft docs, the environment strings do not appear
+ *   to be sorted on Win95 (although they are on NT); so we don't bother
+ *   to sort them either.
+ */
+
+static const char ENV_program_name[] = "C:\\WINDOWS\\SYSTEM\\KRNL386.EXE";
+
+/* Maximum length of an environment string (including NULL) */
+#define MAX_STR_LEN  128
+
+/* Extra bytes to reserve at the end of an environment */
+#define EXTRA_ENV_SIZE (sizeof(BYTE) + sizeof(WORD) + sizeof(ENV_program_name))
+
+/* Fill the extra bytes with the program name and stuff */
+#define FILL_EXTRA_ENV(p) \
+    *(p) = '\0'; \
+    PUT_WORD( (p) + 1, 1 ); \
+    strcpy( (p) + 3, ENV_program_name );
+
+
+/***********************************************************************
+ *           ENV_FindVariable
+ *
+ * Find a variable in the environment and return a pointer to the value.
+ * Helper function for GetEnvironmentVariable and ExpandEnvironmentStrings.
+ */
+static LPCSTR ENV_FindVariable( LPCSTR env, LPCSTR name, INT32 len )
+{
+    while (*env)
+    {
+        if (!lstrncmpi32A( name, env, len ) && (env[len] == '='))
+            return env + len + 1;
+        env += strlen(env) + 1;
+    }
+    return NULL;
+}
+
+
+/***********************************************************************
+ *           ENV_BuildEnvironment
+ *
+ * Build the environment for the initial process
+ */
+BOOL32 ENV_BuildEnvironment( PDB32 *pdb )
+{
+    extern char **environ;
+    LPSTR p, *e;
+    int size, len;
+
+    /* Compute the total size of the Unix environment */
+
+    size = EXTRA_ENV_SIZE;
+    for (e = environ; *e; e++)
+    {
+        len = strlen(*e) + 1;
+        size += MIN( len, MAX_STR_LEN );
+    }
+
+    /* Now allocate the environment */
+
+    if (!(p = HeapAlloc( SystemHeap, 0, size ))) return FALSE;
+    pdb->env_db->environ = p;
+    pdb->env_db->env_sel = SELECTOR_AllocBlock( p, 0x10000, SEGMENT_DATA,
+                                                FALSE, FALSE );
+
+    /* And fill it with the Unix environment */
+
+    for (e = environ; *e; e++)
+    {
+        lstrcpyn32A( p, *e, MAX_STR_LEN );
+        p += strlen(p) + 1;
+    }
+
+    /* Now add the program name */
+
+    FILL_EXTRA_ENV( p );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           ENV_InheritEnvironment
+ *
+ * Make a process inherit the environment from its parent or from an
+ * explicit environment.
+ */
+BOOL32 ENV_InheritEnvironment( PDB32 *pdb, LPCSTR env )
+{
+    DWORD size;
+    LPCSTR p;
+
+    /* FIXME: should lock the parent environment */
+    if (!env) env = pdb->parent->env_db->environ;
+
+    /* Compute the environment size */
+
+    p = env;
+    while (*p) p += strlen(p) + 1;
+    size = (p - env);
+
+    /* Copy the environment */
+
+    if (!(pdb->env_db->environ = HeapAlloc( pdb->heap, 0,
+                                            size + EXTRA_ENV_SIZE )))
+        return FALSE;
+    pdb->env_db->env_sel = SELECTOR_AllocBlock( pdb->env_db->environ,
+                                                0x10000, SEGMENT_DATA,
+                                                FALSE, FALSE );
+    memcpy( pdb->env_db->environ, env, size );
+    FILL_EXTRA_ENV( pdb->env_db->environ + size );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           ENV_FreeEnvironment
+ *
+ * Free a process environment.
+ */
+void ENV_FreeEnvironment( PDB32 *pdb )
+{
+    if (!pdb->env_db) return;
+    if (pdb->env_db->env_sel) SELECTOR_FreeBlock( pdb->env_db->env_sel, 1 );
+    DeleteCriticalSection( &pdb->env_db->section );
+    HeapFree( pdb->heap, 0, pdb->env_db );
+}
+
+
+/***********************************************************************
+ *           GetCommandLine32A      (KERNEL32.289)
+ */
+LPCSTR WINAPI GetCommandLine32A(void)
+{
+    return PROCESS_Current()->env_db->cmd_line;
+}
+
+/***********************************************************************
+ *           GetCommandLine32W      (KERNEL32.290)
+ */
+LPCWSTR WINAPI GetCommandLine32W(void)
+{
+    PDB32 *pdb = PROCESS_Current();
+    EnterCriticalSection( &pdb->env_db->section );
+    if (!pdb->env_db->cmd_lineW)
+        pdb->env_db->cmd_lineW = HEAP_strdupAtoW( pdb->heap, 0,
+                                                  pdb->env_db->cmd_line );
+    LeaveCriticalSection( &pdb->env_db->section );
+    return pdb->env_db->cmd_lineW;
+}
+
+
+/***********************************************************************
+ *           GetEnvironmentStrings32A   (KERNEL32.319) (KERNEL32.320)
+ */
+LPSTR WINAPI GetEnvironmentStrings32A(void)
+{
+    PDB32 *pdb = PROCESS_Current();
+    return pdb->env_db->environ;
+}
+
+
+/***********************************************************************
+ *           GetEnvironmentStrings32W   (KERNEL32.321)
+ */
+LPWSTR WINAPI GetEnvironmentStrings32W(void)
+{
+    INT32 size;
+    LPWSTR ret;
+    PDB32 *pdb = PROCESS_Current();
+
+    EnterCriticalSection( &pdb->env_db->section );
+    size = HeapSize( pdb->heap, 0, pdb->env_db->environ );
+    if ((ret = HeapAlloc( pdb->heap, 0, size * sizeof(WCHAR) )) != NULL)
+    {
+        LPSTR pA = pdb->env_db->environ;
+        LPWSTR pW = ret;
+        while (size--) *pW++ = (WCHAR)(BYTE)*pA++;
+    }
+    LeaveCriticalSection( &pdb->env_db->section );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           FreeEnvironmentStrings32A   (KERNEL32.268)
+ */
+BOOL32 WINAPI FreeEnvironmentStrings32A( LPSTR ptr )
+{
+    PDB32 *pdb = PROCESS_Current();
+    if (ptr != pdb->env_db->environ)
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return FALSE;
+    }
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           FreeEnvironmentStrings32W   (KERNEL32.269)
+ */
+BOOL32 WINAPI FreeEnvironmentStrings32W( LPWSTR ptr )
+{
+    return HeapFree( GetProcessHeap(), 0, ptr );
+}
+
+
+/***********************************************************************
+ *           GetEnvironmentVariable32A   (KERNEL32.322)
+ */
+DWORD WINAPI GetEnvironmentVariable32A( LPCSTR name, LPSTR value, DWORD size )
+{
+    LPCSTR p;
+    INT32 ret = 0;
+    PDB32 *pdb = PROCESS_Current();
+
+    if (!name || !*name)
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return 0;
+    }
+    EnterCriticalSection( &pdb->env_db->section );
+    if ((p = ENV_FindVariable( pdb->env_db->environ, name, strlen(name) )))
+    {
+        ret = strlen(p);
+        if (size <= ret)
+        {
+            /* If not enough room, include the terminating null
+             * in the returned size and return an empty string */
+            ret++;
+            if (value) *value = '\0';
+        }
+        else if (value) strcpy( value, p );
+    }
+    LeaveCriticalSection( &pdb->env_db->section );
+    return ret;  /* FIXME: SetLastError */
+}
+
+
+/***********************************************************************
+ *           GetEnvironmentVariable32W   (KERNEL32.323)
+ */
+DWORD WINAPI GetEnvironmentVariable32W( LPCWSTR nameW, LPWSTR valW, DWORD size)
+{
+    LPSTR name = HEAP_strdupWtoA( GetProcessHeap(), 0, nameW );
+    LPSTR val  = valW ? HeapAlloc( GetProcessHeap(), 0, size ) : NULL;
+    DWORD res  = GetEnvironmentVariable32A( name, val, size );
+    HeapFree( GetProcessHeap(), 0, name );
+    if (val)
+    {
+        lstrcpynAtoW( valW, val, size );
+        HeapFree( GetProcessHeap(), 0, val );
+    }
+    return res;
+}
+
+
+/***********************************************************************
+ *           SetEnvironmentVariable32A   (KERNEL32.641)
+ */
+BOOL32 WINAPI SetEnvironmentVariable32A( LPCSTR name, LPCSTR value )
+{
+    INT32 old_size, len, res;
+    LPSTR p, env, new_env;
+    BOOL32 ret = FALSE;
+    PDB32 *pdb = PROCESS_Current();
+
+    EnterCriticalSection( &pdb->env_db->section );
+    env = p = pdb->env_db->environ;
+
+    /* Find a place to insert the string */
+
+    res = -1;
+    len = strlen(name);
+    while (*p)
+    {
+        if (!lstrncmpi32A( name, p, len ) && (p[len] == '=')) break;
+        p += strlen(p) + 1;
+    }
+    if (!value && !*p) goto done;  /* Value to remove doesn't exist */
+
+    /* Realloc the buffer */
+
+    len = value ? strlen(name) + strlen(value) + 2 : 0;
+    if (*p) len -= strlen(p) + 1;  /* The name already exists */
+    old_size = HeapSize( pdb->heap, 0, env );
+    if (len < 0)
+    {
+        LPSTR next = p + strlen(p) + 1;  /* We know there is a next one */
+        memmove( next + len, next, old_size - (next - env) );
+    }
+    if (!(new_env = HeapReAlloc( pdb->heap, 0, env, old_size + len )))
+        goto done;
+    SELECTOR_MoveBlock( pdb->env_db->env_sel, new_env );
+    p = new_env + (p - env);
+    if (len > 0) memmove( p + len, p, old_size - (p - new_env) );
+
+    /* Set the new string */
+
+    if (value)
+    {
+        strcpy( p, name );
+        strcat( p, "=" );
+        strcat( p, value );
+    }
+    pdb->env_db->environ = new_env;
+    ret = TRUE;
+
+done:
+    LeaveCriticalSection( &pdb->env_db->section );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           SetEnvironmentVariable32W   (KERNEL32.642)
+ */
+BOOL32 WINAPI SetEnvironmentVariable32W( LPCWSTR name, LPCWSTR value )
+{
+    LPSTR nameA  = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
+    LPSTR valueA = HEAP_strdupWtoA( GetProcessHeap(), 0, value );
+    BOOL32 ret = SetEnvironmentVariable32A( nameA, valueA );
+    HeapFree( GetProcessHeap(), 0, nameA );
+    HeapFree( GetProcessHeap(), 0, valueA );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           ExpandEnvironmentStrings32A   (KERNEL32.216)
+ *
+ * Note: overlapping buffers are not supported; this is how it should be.
+ */
+DWORD WINAPI ExpandEnvironmentStrings32A( LPCSTR src, LPSTR dst, DWORD count )
+{
+    DWORD len, total_size = 1;  /* 1 for terminating '\0' */
+    LPCSTR p, var;
+    PDB32 *pdb = PROCESS_Current();
+
+    if (!count) dst = NULL;
+    EnterCriticalSection( &pdb->env_db->section );
+
+    while (*src)
+    {
+        if (*src != '%')
+        {
+            if ((p = strchr( src, '%' ))) len = p - src;
+            else len = strlen(src);
+            var = src;
+            src += len;
+        }
+        else  /* we are at the start of a variable */
+        {
+            if ((p = strchr( src + 1, '%' )))
+            {
+                len = p - src - 1;  /* Length of the variable name */
+                if ((var = ENV_FindVariable( pdb->env_db->environ,
+                                             src + 1, len )))
+                {
+                    src += len + 2;  /* Skip the variable name */
+                    len = strlen(var);
+                }
+                else
+                {
+                    var = src;  /* Copy original name instead */
+                    len += 2;
+                    src += len;
+                }
+            }
+            else  /* unfinished variable name, ignore it */
+            {
+                var = src;
+                len = strlen(src);  /* Copy whole string */
+                src += len;
+            }
+        }
+        total_size += len;
+        if (dst)
+        {
+            if (count < len) len = count;
+            memcpy( dst, var, len );
+            dst += len;
+            count -= len;
+        }
+    }
+    LeaveCriticalSection( &pdb->env_db->section );
+
+    /* Null-terminate the string */
+    if (dst)
+    {
+        if (!count) dst--;
+        *dst = '\0';
+    }
+    return total_size;
+}
+
+
+/***********************************************************************
+ *           ExpandEnvironmentStrings32W   (KERNEL32.217)
+ */
+DWORD WINAPI ExpandEnvironmentStrings32W( LPCWSTR src, LPWSTR dst, DWORD len )
+{
+    LPSTR srcA = HEAP_strdupWtoA( GetProcessHeap(), 0, src );
+    LPSTR dstA = dst ? HeapAlloc( GetProcessHeap(), 0, len ) : NULL;
+    DWORD ret  = ExpandEnvironmentStrings32A( srcA, dstA, len );
+    if (dstA)
+    {
+        lstrcpyAtoW( dst, dstA );
+        HeapFree( GetProcessHeap(), 0, dstA );
+    }
+    HeapFree( GetProcessHeap(), 0, srcA );
+    return ret;
+}
+
diff --git a/memory/global.c b/memory/global.c
index 54a4b46..fdb0208 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -282,7 +282,7 @@
     HANDLE16 owner = GetCurrentPDB();
 
     if (flags & GMEM_DDESHARE)
-        owner = MODULE_HANDLEtoHMODULE16(owner);  /* Make it a module handle */
+        owner = GetExePtr(owner);  /* Make it a module handle */
     return GLOBAL_Alloc( flags, size, owner, FALSE, FALSE, FALSE );
 }
 
@@ -963,11 +963,7 @@
      * (under Windows) always fills the structure and returns true.
      */
     GlobalMemoryStatus( &status );
-#ifdef __svr4__
-    info->wPageSize            = sysconf(_SC_PAGESIZE);
-#else
-    info->wPageSize            = getpagesize();
-#endif
+    info->wPageSize            = VIRTUAL_GetPageSize();
     info->dwLargestFreeBlock   = status.dwAvailVirtual;
     info->dwMaxPagesAvailable  = info->dwLargestFreeBlock / info->wPageSize;
     info->dwMaxPagesLockable   = info->dwMaxPagesAvailable;
@@ -1225,9 +1221,10 @@
       {
 	 /* reallocate a moveable block */
 	 pintern=HANDLE_TO_INTERN(hmem);
-	 if(pintern->LockCount!=0)
+	 if(pintern->LockCount>1) {
+	    ERR(global,"handle 0x%08lx is still locked, cannot realloc!\n",(DWORD)hmem);
 	    SetLastError(ERROR_INVALID_HANDLE);
-	 else if(size!=0)
+	 } else if(size!=0)
 	 {
 	    hnew=hmem;
 	    if(pintern->Pointer)
diff --git a/memory/heap.c b/memory/heap.c
index 446b63d..2c2556d 100644
--- a/memory/heap.c
+++ b/memory/heap.c
@@ -1225,7 +1225,7 @@
               LPCVOID block  /* [in] Optional pointer to memory block to validate */
 ) {
     SUBHEAP *subheap;
-    HEAP *heapPtr = HEAP_GetPtr(heap);
+    HEAP *heapPtr = (HEAP *)(heap);
 
     if (!heapPtr || (heapPtr->magic != HEAP_MAGIC))
     {
diff --git a/memory/local.c b/memory/local.c
index 910665f..8f5213d 100644
--- a/memory/local.c
+++ b/memory/local.c
@@ -26,10 +26,6 @@
 #include "toolhelp.h"
 #include "debug.h"
 
-/* needed only  for GDI_HeapSel and USER_HeapSel */
-#include "gdi.h"
-#include "user.h"
-
 typedef struct
 {
 /* Arena header */
@@ -103,6 +99,8 @@
 
 #define LOCAL_HEAP_MAGIC  0x484c  /* 'LH' */
 
+WORD USER_HeapSel = 0;  /* USER heap selector */
+WORD GDI_HeapSel = 0;   /* GDI heap selector */
 
   /* All local heap allocations are aligned on 4-byte boundaries */
 #define LALIGN(word)          (((word) + 3) & ~3)
@@ -1099,7 +1097,7 @@
     char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
     LOCALHEAPINFO *pInfo;
     LOCALARENA *pArena, *pNext;
-    LOCALHANDLEENTRY *pEntry;
+    LOCALHANDLEENTRY *pEntry = NULL;
     WORD arena, oldsize;
     HLOCAL16 hmem, blockhandle;
     LONG nextarena;
diff --git a/memory/selector.c b/memory/selector.c
index e277ea5..0fbb9bb 100644
--- a/memory/selector.c
+++ b/memory/selector.c
@@ -138,6 +138,25 @@
 
 
 /***********************************************************************
+ *           SELECTOR_MoveBlock
+ *
+ * Move a block of selectors in linear memory.
+ */
+void SELECTOR_MoveBlock( WORD sel, const void *new_base )
+{
+    WORD i, count = (GET_SEL_LIMIT(sel) >> 16) + 1;
+
+    for (i = 0; i < count; i++)
+    {
+        ldt_entry entry;
+        LDT_GetEntry( SELECTOR_TO_ENTRY(sel) + i, &entry );
+        entry.base = (unsigned long)new_base;
+        LDT_SetEntry( SELECTOR_TO_ENTRY(sel) + i, &entry );
+    }
+}
+
+
+/***********************************************************************
  *           SELECTOR_FreeBlock
  *
  * Free a block of selectors.
@@ -496,13 +515,10 @@
 
 /************************************* Win95 pointer mapping functions *
  *
- * NOTE: MapSLFix and UnMapSLFixArray are probably needed to prevent
- * unexpected linear address change when GlobalCompact() shuffles
- * moveable blocks.
  */
 
 /***********************************************************************
- *           MapSL   (KERNEL32.662)
+ *           MapSL   (KERNEL32.523)
  *
  * Maps fixed segmented pointer to linear.
  */
@@ -511,27 +527,53 @@
     return (LPVOID)PTR_SEG_TO_LIN(sptr);
 }
 
+/***********************************************************************
+ *           MapSLFix   (KERNEL32.524)
+ *
+ * FIXME: MapSLFix and UnMapSLFixArray should probably prevent
+ * unexpected linear address change when GlobalCompact() shuffles
+ * moveable blocks.
+ */
+
+LPVOID WINAPI MapSLFix( SEGPTR sptr )
+{
+    return (LPVOID)PTR_SEG_TO_LIN(sptr);
+}
 
 /***********************************************************************
- *           MapLS   (KERNEL32.679)
+ *           UnMapSLFixArray   (KERNEL32.701)
+ */
+
+void WINAPI UnMapSLFixArray( SEGPTR sptr[], INT32 length )
+{
+}
+
+/***********************************************************************
+ *           MapLS   (KERNEL32.522)
  *
  * Maps linear pointer to segmented.
  */
 SEGPTR WINAPI MapLS( LPVOID ptr )
 {
-    WORD sel = SELECTOR_AllocBlock( ptr, 0x10000, SEGMENT_DATA, FALSE, FALSE );
-    return PTR_SEG_OFF_TO_SEGPTR( sel, 0 );
+    if (!HIWORD(ptr))
+        return (SEGPTR)ptr;
+    else
+    {
+        WORD sel = SELECTOR_AllocBlock( ptr, 0x10000, SEGMENT_DATA, FALSE, FALSE );
+        return PTR_SEG_OFF_TO_SEGPTR( sel, 0 );
+    }
 }
 
 
 /***********************************************************************
- *           UnMapLS   (KERNEL32.680)
+ *           UnMapLS   (KERNEL32.700)
  *
  * Free mapped selector.
  */
 void WINAPI UnMapLS( SEGPTR sptr )
 {
-    if (!__winelib) SELECTOR_FreeBlock( SELECTOROF(sptr), 1 );
+    if (SELECTOROF(sptr)) 
+        SELECTOR_FreeBlock( SELECTOROF(sptr), 1 );
 }
 
 /***********************************************************************
@@ -626,6 +668,71 @@
 void WINAPI SUnMapLS_IP_EBP_40(CONTEXT *context) { x_SUnMapLS_IP_EBP_x(context,40); }
 
 /**********************************************************************
+ * 		AllocMappedBuffer	(KERNEL32.38)
+ *
+ * This is a undocumented KERNEL32 function that 
+ * SMapLS's a GlobalAlloc'ed buffer.
+ *
+ * Input:   EDI register: size of buffer to allocate
+ * Output:  EDI register: pointer to buffer
+ *
+ * Note: The buffer is preceeded by 8 bytes:
+ *        ...
+ *       edi+0   buffer
+ *       edi-4   SEGPTR to buffer
+ *       edi-8   some magic Win95 needs for SUnMapLS
+ *               (we use it for the memory handle)
+ *
+ *       The SEGPTR is used by the caller!
+ */
+
+void WINAPI AllocMappedBuffer(CONTEXT *context)
+{
+    HGLOBAL32 handle = GlobalAlloc32(0, EDI_reg(context) + 8);
+    DWORD *buffer = (DWORD *)GlobalLock32(handle);
+    SEGPTR ptr = 0;
+
+    if (buffer)
+        if (!(ptr = MapLS(buffer + 2)))
+        {
+            GlobalUnlock32(handle);
+            GlobalFree32(handle);
+        }
+
+    if (!ptr)
+        EAX_reg(context) = EDI_reg(context) = 0;
+    else
+    {
+        buffer[0] = handle;
+        buffer[1] = ptr;
+
+        EAX_reg(context) = (DWORD) ptr;
+        EDI_reg(context) = (DWORD)(buffer + 2);
+    }
+}
+
+/**********************************************************************
+ * 		FreeMappedBuffer	(KERNEL32.39)
+ *
+ * Free a buffer allocated by AllocMappedBuffer
+ *
+ * Input: EDI register: pointer to buffer
+ */
+
+void WINAPI FreeMappedBuffer(CONTEXT *context)
+{
+    if (EDI_reg(context))
+    {
+        DWORD *buffer = (DWORD *)EDI_reg(context) - 2;
+
+        UnMapLS(buffer[1]);
+
+        GlobalUnlock32(buffer[0]);
+        GlobalFree32(buffer[0]);
+    }
+}
+
+/**********************************************************************
  *           WOWGetVDMPointer	(KERNEL32.55)
  * Get linear from segmented pointer. (MSDN lib)
  */
diff --git a/memory/string.c b/memory/string.c
index 6e063a8..ee0db67 100644
--- a/memory/string.c
+++ b/memory/string.c
@@ -542,7 +542,7 @@
 
 
 /***********************************************************************
- *           CharToOem32A   (USER32.36)
+ *           CharToOem32A   (USER32.37)
  */
 BOOL32 WINAPI CharToOem32A( LPCSTR s, LPSTR d )
 {
@@ -556,7 +556,7 @@
 
 
 /***********************************************************************
- *           CharToOemBuff32A   (USER32.37)
+ *           CharToOemBuff32A   (USER32.38)
  */
 BOOL32 WINAPI CharToOemBuff32A( LPCSTR s, LPSTR d, DWORD len )
 {
@@ -566,7 +566,7 @@
 
 
 /***********************************************************************
- *           CharToOemBuff32W   (USER32.38)
+ *           CharToOemBuff32W   (USER32.39)
  */
 BOOL32 WINAPI CharToOemBuff32W( LPCWSTR s, LPSTR d, DWORD len )
 {
@@ -576,7 +576,7 @@
 
 
 /***********************************************************************
- *           CharToOem32W   (USER32.39)
+ *           CharToOem32W   (USER32.40)
  */
 BOOL32 WINAPI CharToOem32W( LPCWSTR s, LPSTR d )
 {
@@ -590,7 +590,7 @@
 
 
 /***********************************************************************
- *           OemToChar32A   (USER32.401)
+ *           OemToChar32A   (USER32.402)
  */
 BOOL32 WINAPI OemToChar32A( LPCSTR s, LPSTR d )
 {
@@ -603,7 +603,7 @@
 
 
 /***********************************************************************
- *           OemToCharBuff32A   (USER32.402)
+ *           OemToCharBuff32A   (USER32.403)
  */
 BOOL32 WINAPI OemToCharBuff32A( LPCSTR s, LPSTR d, DWORD len )
 {
@@ -614,7 +614,7 @@
 
 
 /***********************************************************************
- *           OemToCharBuff32W   (USER32.403)
+ *           OemToCharBuff32W   (USER32.404)
  */
 BOOL32 WINAPI OemToCharBuff32W( LPCSTR s, LPWSTR d, DWORD len )
 {
@@ -625,7 +625,7 @@
 
 
 /***********************************************************************
- *           OemToChar32W   (USER32.404)
+ *           OemToChar32W   (USER32.405)
  */
 BOOL32 WINAPI OemToChar32W( LPCSTR s, LPWSTR d )
 {
diff --git a/memory/virtual.c b/memory/virtual.c
index f128cc1..fac4ee7 100644
--- a/memory/virtual.c
+++ b/memory/virtual.c
@@ -84,9 +84,16 @@
 
 static FILE_VIEW *VIRTUAL_FirstView;
 
+#ifdef __i386___
+/* These are always the same on an i386, and it will be faster this way */
+# define page_mask  0xfff
+# define page_shift 12
+# define granularity_mask 0xffff
+#else
 static UINT32 page_shift;
 static UINT32 page_mask;
 static UINT32 granularity_mask;  /* Allocation granularity (usually 64k) */
+#endif  /* __i386__ */
 
 #define ROUND_ADDR(addr) \
    ((UINT32)(addr) & ~page_mask)
@@ -415,16 +422,25 @@
  */
 BOOL32 VIRTUAL_Init(void)
 {
-    SYSTEM_INFO sysinfo;
-    GetSystemInfo( &sysinfo );
+#ifndef __i386__
+    DWORD page_size;
 
-    page_mask = sysinfo.dwPageSize - 1;
-    granularity_mask = sysinfo.dwAllocationGranularity - 1;
+# ifdef HAVE_GETPAGESIZE
+    page_size = getpagesize();
+# else
+#  ifdef __svr4__
+    page_size = sysconf(_SC_PAGESIZE);
+#  else
+#   error Cannot get the page size on this platform
+#  endif
+# endif
+    page_mask = page_size - 1;
+    granularity_mask = 0xffff;  /* hard-coded for now */
     /* Make sure we have a power of 2 */
-    assert( !(sysinfo.dwPageSize & page_mask) );
-    assert( !(sysinfo.dwAllocationGranularity & granularity_mask) );
+    assert( !(page_size & page_mask) );
     page_shift = 0;
-    while ((1 << page_shift) != sysinfo.dwPageSize) page_shift++;
+    while ((1 << page_shift) != page_size) page_shift++;
+#endif  /* !__i386__ */
 
 #ifdef linux
     {
@@ -468,6 +484,24 @@
 
 
 /***********************************************************************
+ *           VIRTUAL_GetPageSize
+ */
+DWORD VIRTUAL_GetPageSize(void)
+{
+    return 1 << page_shift;
+}
+
+
+/***********************************************************************
+ *           VIRTUAL_GetGranularity
+ */
+DWORD VIRTUAL_GetGranularity(void)
+{
+    return granularity_mask + 1;
+}
+
+
+/***********************************************************************
  *             VirtualAlloc   (KERNEL32.548)
  * Reserves or commits a region of pages in virtual address space
  *
@@ -1013,15 +1047,16 @@
  */
 HANDLE32 WINAPI CreateFileMapping32A(
                 HFILE32 hFile,   /* [in] Handle of file to map */
-                LPSECURITY_ATTRIBUTES attr, /* [in] Optional security attributes */
+                SECURITY_ATTRIBUTES *sa, /* [in] Optional security attributes*/
                 DWORD protect,   /* [in] Protection for mapping object */
                 DWORD size_high, /* [in] High-order 32 bits of object size */
                 DWORD size_low,  /* [in] Low-order 32 bits of object size */
-                LPCSTR name      /* [in] Name of file-mapping object */
-) {
+                LPCSTR name      /* [in] Name of file-mapping object */ )
+{
     FILE_MAPPING *mapping = NULL;
     HANDLE32 handle;
     BYTE vprot;
+    BOOL32 inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
 
     /* First search for an object with the same name */
 
@@ -1031,7 +1066,8 @@
         if (obj->type == K32OBJ_MEM_MAPPED_FILE)
         {
             SetLastError( ERROR_ALREADY_EXISTS );
-            handle = HANDLE_Alloc( obj, FILE_MAP_ALL_ACCESS /*FIXME*/, FALSE );
+            handle = HANDLE_Alloc( PROCESS_Current(), obj,
+                                   FILE_MAP_ALL_ACCESS /*FIXME*/, inherit );
         }
         else
         {
@@ -1045,7 +1081,7 @@
     /* Check parameters */
 
     TRACE(virtual,"(%x,%p,%08lx,%08lx%08lx,%s)\n",
-                    hFile, attr, protect, size_high, size_low, name );
+          hFile, sa, protect, size_high, size_low, name );
 
     vprot = VIRTUAL_GetProt( protect );
     if (protect & SEC_RESERVE)
@@ -1080,7 +1116,8 @@
             ((protect & 0xff) == PAGE_EXECUTE_READWRITE) ||
             ((protect & 0xff) == PAGE_EXECUTE_WRITECOPY))
                 access |= GENERIC_WRITE;
-        if (!(obj = HANDLE_GetObjPtr( hFile, K32OBJ_FILE, access )))
+        if (!(obj = HANDLE_GetObjPtr( PROCESS_Current(), hFile,
+                                      K32OBJ_FILE, access )))
             goto error;
 
         if (!GetFileInformationByHandle( hFile, &info )) goto error;
@@ -1111,8 +1148,8 @@
     mapping->file            = (FILE_OBJECT *)obj;
 
     if (!K32OBJ_AddName( &mapping->header, name )) handle = 0;
-    else handle = HANDLE_Alloc( &mapping->header,
-                                FILE_MAP_ALL_ACCESS /*FIXME*/, FALSE );
+    else handle = HANDLE_Alloc( PROCESS_Current(), &mapping->header,
+                                FILE_MAP_ALL_ACCESS /*FIXME*/, inherit );
     K32OBJ_DecCount( &mapping->header );
     return handle;
 
@@ -1157,7 +1194,7 @@
     SYSTEM_LOCK();
     if ((obj = K32OBJ_FindNameType( name, K32OBJ_MEM_MAPPED_FILE )))
     {
-        handle = HANDLE_Alloc( obj, access, inherit );
+        handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit );
         K32OBJ_DecCount( obj );
     }
     SYSTEM_UNLOCK();
@@ -1244,7 +1281,8 @@
         return NULL;
     }
 
-    if (!(mapping = (FILE_MAPPING *)HANDLE_GetObjPtr( handle,
+    if (!(mapping = (FILE_MAPPING *)HANDLE_GetObjPtr( PROCESS_Current(),
+                                                      handle,
                                                       K32OBJ_MEM_MAPPED_FILE,
                                                       0  /* FIXME */ )))
         return NULL;
diff --git a/misc/comm.c b/misc/comm.c
index 1fb36c7..169d733 100644
--- a/misc/comm.c
+++ b/misc/comm.c
@@ -16,6 +16,8 @@
  *                                     <lawson_whitney@juno.com>
  */
 
+#include "config.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <termios.h>
@@ -24,8 +26,8 @@
 #include <errno.h>
 #include <ctype.h>
 #include <sys/stat.h>
-#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__svr4__)
-#include <sys/filio.h>
+#ifdef HAVE_SYS_FILIO_H
+# include <sys/filio.h>
 #endif
 #include <sys/ioctl.h>
 #include <unistd.h>
diff --git a/misc/commdlg.c b/misc/commdlg.c
index 5e3ca51..e7122a6 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -27,6 +27,7 @@
 static HBITMAP16 hHDisk = 0;
 static HBITMAP16 hCDRom = 0;
 static HBITMAP16 hBitmapTT = 0;
+static const char defaultfilter[]=" \0\0";
 
 /***********************************************************************
  * 				FileDlg_Init			[internal]
@@ -36,11 +37,11 @@
     static BOOL32 initialized = 0;
     
     if (!initialized) {
-	if (!hFolder) hFolder = LoadBitmap16(0, MAKEINTRESOURCE(OBM_FOLDER));
-	if (!hFolder2) hFolder2 = LoadBitmap16(0, MAKEINTRESOURCE(OBM_FOLDER2));
-	if (!hFloppy) hFloppy = LoadBitmap16(0, MAKEINTRESOURCE(OBM_FLOPPY));
-	if (!hHDisk) hHDisk = LoadBitmap16(0, MAKEINTRESOURCE(OBM_HDISK));
-	if (!hCDRom) hCDRom = LoadBitmap16(0, MAKEINTRESOURCE(OBM_CDROM));
+	if (!hFolder) hFolder = LoadBitmap16(0, MAKEINTRESOURCE16(OBM_FOLDER));
+	if (!hFolder2) hFolder2 = LoadBitmap16(0, MAKEINTRESOURCE16(OBM_FOLDER2));
+	if (!hFloppy) hFloppy = LoadBitmap16(0, MAKEINTRESOURCE16(OBM_FLOPPY));
+	if (!hHDisk) hHDisk = LoadBitmap16(0, MAKEINTRESOURCE16(OBM_HDISK));
+	if (!hCDRom) hCDRom = LoadBitmap16(0, MAKEINTRESOURCE16(OBM_CDROM));
 	if (hFolder == 0 || hFolder2 == 0 || hFloppy == 0 || 
 	    hHDisk == 0 || hCDRom == 0)
 	{	
@@ -63,6 +64,8 @@
     HWND32 hwndDialog;
     LPOPENFILENAME16 lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(ofn);
     LPCVOID template;
+    char defaultopen[]="Open File";
+    char *str=0,*str1=0;
 
     if (!lpofn || !FileDlg_Init()) return FALSE;
 
@@ -78,7 +81,7 @@
 	    else if (lpofn->Flags & OFN_ENABLETEMPLATE)
 	    {
 		if (!(hResInfo = FindResource32A(lpofn->hInstance,
-						PTR_SEG_TO_LIN(lpofn->lpTemplateName), (LPSTR)RT_DIALOG)))
+						PTR_SEG_TO_LIN(lpofn->lpTemplateName), RT_DIALOG32A)))
 		{
 		    CommDlgLastError = CDERR_FINDRESFAILURE;
 		    return FALSE;
@@ -105,7 +108,8 @@
 	    else if (lpofn->Flags & OFN_ENABLETEMPLATE)
 	    {
 		if (!(hResInfo = FindResource16(lpofn->hInstance,
-						lpofn->lpTemplateName, RT_DIALOG)))
+						lpofn->lpTemplateName,
+                                                RT_DIALOG16)))
 		{
 		    CommDlgLastError = CDERR_FINDRESFAILURE;
 		    return FALSE;
@@ -123,6 +127,23 @@
     }
 
     hInst = WIN_GetWindowInstance( lpofn->hwndOwner );
+
+    if (!(lpofn->lpstrFilter))
+      {
+       str = SEGPTR_ALLOC(sizeof(defaultfilter));
+       TRACE(commdlg,"Alloc %p default for Filetype in GetOpenFileName\n",str);
+       memcpy(str,defaultfilter,sizeof(defaultfilter));
+       lpofn->lpstrFilter=SEGPTR_GET(str);
+      }
+
+    if (!(lpofn->lpstrTitle))
+      {
+       str1 = SEGPTR_ALLOC(strlen(defaultopen)+1);
+       TRACE(commdlg,"Alloc %p default for Title in GetOpenFileName\n",str1);
+       strcpy(str1,defaultopen);
+       lpofn->lpstrTitle=SEGPTR_GET(str1);
+      }
+
     /* FIXME: doesn't handle win32 format correctly yet */
     hwndDialog = DIALOG_CreateIndirect( hInst, template, win32Format,
                                         lpofn->hwndOwner,
@@ -130,6 +151,20 @@
                                         ofn, WIN_PROC_16 );
     if (hwndDialog) bRet = DIALOG_DoDialogBox( hwndDialog, lpofn->hwndOwner );
 
+    if (str1)
+      {
+       TRACE(commdlg,"Freeing %p default for Title in GetOpenFileName\n",str1);
+        SEGPTR_FREE(str1);
+       lpofn->lpstrTitle=0;
+      }
+
+    if (str)
+      {
+       TRACE(commdlg,"Freeing %p default for Filetype in GetOpenFileName\n",str);
+        SEGPTR_FREE(str);
+       lpofn->lpstrFilter=0;
+      }
+
     if (hDlgTmpl) {
 	    if (lpofn->Flags & OFN_WINE32)
 		    FreeResource32( hDlgTmpl );
@@ -154,6 +189,8 @@
     LPOPENFILENAME16 lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(ofn);
     LPCVOID template;
     HWND32 hwndDialog;
+    char defaultsave[]="Save as";
+    char *str =0,*str1=0;
 
     if (!lpofn || !FileDlg_Init()) return FALSE;
 
@@ -170,7 +207,8 @@
 	    {
 		HANDLE32 hResInfo;
 		if (!(hResInfo = FindResource32A(lpofn->hInstance,
-						 PTR_SEG_TO_LIN(lpofn->lpTemplateName), (LPSTR)RT_DIALOG)))
+						 PTR_SEG_TO_LIN(lpofn->lpTemplateName),
+                                                 RT_DIALOG32A)))
 		{
 		    CommDlgLastError = CDERR_FINDRESFAILURE;
 		    return FALSE;
@@ -199,7 +237,8 @@
 	    {
 		HANDLE16 hResInfo;
 		if (!(hResInfo = FindResource16(lpofn->hInstance,
-						lpofn->lpTemplateName, RT_DIALOG)))
+						lpofn->lpTemplateName,
+                                                RT_DIALOG16)))
 		{
 		    CommDlgLastError = CDERR_FINDRESFAILURE;
 		    return FALSE;
@@ -218,12 +257,42 @@
 
     hInst = WIN_GetWindowInstance( lpofn->hwndOwner );
 
+    if (!(lpofn->lpstrFilter))
+      {
+       str = SEGPTR_ALLOC(sizeof(defaultfilter));
+       TRACE(commdlg,"Alloc default for Filetype in GetSaveFileName\n");
+       memcpy(str,defaultfilter,sizeof(defaultfilter));
+       lpofn->lpstrFilter=SEGPTR_GET(str);
+      }
+
+    if (!(lpofn->lpstrTitle))
+      {
+       str1 = SEGPTR_ALLOC(sizeof(defaultsave)+1);
+       TRACE(commdlg,"Alloc default for Title in GetSaveFileName\n");
+       strcpy(str1,defaultsave);
+       lpofn->lpstrTitle=SEGPTR_GET(str1);
+      }
+
     hwndDialog = DIALOG_CreateIndirect( hInst, template, win32Format,
                                         lpofn->hwndOwner,
                                         (DLGPROC16)MODULE_GetWndProcEntry16("FileSaveDlgProc"),
                                         ofn, WIN_PROC_16 );
     if (hwndDialog) bRet = DIALOG_DoDialogBox( hwndDialog, lpofn->hwndOwner );
 
+    if (str1)
+      {
+       TRACE(commdlg,"Freeing %p default for Title in GetSaveFileName\n",str1);
+        SEGPTR_FREE(str1);
+       lpofn->lpstrTitle=0;
+      }
+ 
+    if (str)
+      {
+       TRACE(commdlg,"Freeing %p default for Filetype in GetSaveFileName\n",str);
+        SEGPTR_FREE(str);
+       lpofn->lpstrFilter=0;
+      }
+    
     if (hDlgTmpl) {
 	    if (lpofn->Flags & OFN_WINE32)
 		    FreeResource32( hDlgTmpl );
@@ -561,6 +630,9 @@
 /***********************************************************************
  *                              FILEDLG_WMCommand               [internal]
  */
+BOOL32 in_lst1=FALSE;
+BOOL32 in_update=FALSE;
+
 static LRESULT FILEDLG_WMCommand(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam) 
 {
   LONG lRet;
@@ -580,7 +652,10 @@
     case lst1: /* file list */
       FILEDLG_StripEditControl(hWnd);
       if (notification == LBN_DBLCLK)
+	{
+	  in_lst1=TRUE;
 	goto almost_ok;
+	}
       lRet = SendDlgItemMessage16(hWnd, lst1, LB_GETCURSEL16, 0, 0);
       if (lRet == LB_ERR) return TRUE;
       if ((pstr = SEGPTR_ALLOC(512)))
@@ -623,6 +698,10 @@
 	  goto reset_scan;
 	}
       return TRUE;
+    case chx1:
+      return TRUE;
+    case pshHelp:
+      return TRUE;
     case cmb2: /* disk drop list */
       FILEDLG_StripEditControl(hWnd);
       lRet = SendDlgItemMessage16(hWnd, cmb2, CB_GETCURSEL16, 0, 0L);
@@ -640,11 +719,7 @@
       TRACE(commdlg,"Selected filter : %s\n", pstr);
       SetDlgItemText32A( hWnd, edt1, pstr );
       FILEDLG_ScanDir(hWnd, tmpstr);
-      return TRUE;
-    case chx1:
-      return TRUE;
-    case pshHelp:
-      return TRUE;
+      in_update=TRUE;
     case IDOK:
     almost_ok:
       ofn2=*lpofn; /* for later restoring */
@@ -684,8 +759,12 @@
 				 PTR_SEG_TO_LIN(lpofn->lpstrFilter),
 				 lRet), sizeof(tmpstr2));
       SetDlgItemText32A( hWnd, edt1, tmpstr2 );
+      if (in_lst1)
+	{
       /* if ScanDir succeeds, we have changed the directory */
+	  in_lst1 = FALSE;
       if (FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
+	}
       /* if not, this must be a filename */
       *pstr2 = 0;
       if (pstr != NULL)
@@ -711,9 +790,13 @@
 	if (strlen(tmpstr2) > 3)
 	   strcat(tmpstr2, "\\");
 	strncat(tmpstr2, tmpstr, 511-strlen(tmpstr2)); tmpstr2[511]=0;
-	strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFile), tmpstr2);
+	if (lpofn->lpstrFile)
+	  {
+	    strncpy(PTR_SEG_TO_LIN(lpofn->lpstrFile), tmpstr2,lpofn->nMaxFile-1);
+	    *((LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile)+lpofn->nMaxFile) ='\0';
       }
-      lpofn->nFileOffset = 0;
+      }
+      lpofn->nFileOffset = strrchr(tmpstr2,'\\') - tmpstr2 +1;
       lpofn->nFileExtension = 0;
       while(tmpstr2[lpofn->nFileExtension] != '.' && tmpstr2[lpofn->nFileExtension] != '\0')
         lpofn->nFileExtension++;
@@ -721,6 +804,17 @@
 	lpofn->nFileExtension = 0;
       else
 	lpofn->nFileExtension++;
+
+      if(in_update)
+       {
+         if (FILEDLG_HookCallChk(lpofn))
+           FILEDLG_CallWindowProc(lpofn,hWnd,
+                                  RegisterWindowMessage32A( LBSELCHSTRING ),
+                                  control, MAKELONG(lRet,CD_LBSELCHANGE));
+
+         in_update = FALSE;
+         return TRUE;
+       }
       if (PTR_SEG_TO_LIN(lpofn->lpstrFileTitle) != NULL) 
 	{
 	  lRet = SendDlgItemMessage16(hWnd, lst1, LB_GETCURSEL16, 0, 0);
@@ -843,13 +937,13 @@
 
 
 /***********************************************************************
- *           FindTextDlg   (COMMDLG.11)
+ *           FindText16   (COMMDLG.11)
  */
-HWND16 WINAPI FindText( SEGPTR find )
+HWND16 WINAPI FindText16( SEGPTR find )
 {
     HANDLE16 hInst;
     LPCVOID ptr;
-    LPFINDREPLACE lpFind = (LPFINDREPLACE)PTR_SEG_TO_LIN(find);
+    LPFINDREPLACE16 lpFind = (LPFINDREPLACE16)PTR_SEG_TO_LIN(find);
 
     /*
      * FIXME : Should respond to FR_ENABLETEMPLATE and FR_ENABLEHOOK here
@@ -866,15 +960,58 @@
                                   find, WIN_PROC_16 );
 }
 
-
 /***********************************************************************
- *           ReplaceText   (COMMDLG.12)
+ *           FindText32A   (COMMDLG.6)
  */
-HWND16 WINAPI ReplaceText( SEGPTR find )
+HWND32 WINAPI FindText32A( LPFINDREPLACE32A lpFind )
 {
     HANDLE16 hInst;
     LPCVOID ptr;
-    LPFINDREPLACE lpFind = (LPFINDREPLACE)PTR_SEG_TO_LIN(find);
+
+    /*
+     * FIXME : Should respond to FR_ENABLETEMPLATE and FR_ENABLEHOOK here
+     * For now, only the standard dialog works.
+     */
+    /*
+     * FIXME : We should do error checking on the lpFind structure here
+     * and make CommDlgExtendedError() return the error condition.
+     */
+    ptr = SYSRES_GetResPtr( SYSRES_DIALOG_FIND_TEXT );
+    hInst = WIN_GetWindowInstance( lpFind->hwndOwner );
+    return DIALOG_CreateIndirect( hInst, ptr, TRUE, lpFind->hwndOwner,
+                (DLGPROC16)FindTextDlgProc32A, (LPARAM)lpFind, WIN_PROC_32A );
+}
+
+/***********************************************************************
+ *           FindText32W   (COMMDLG.7)
+ */
+HWND32 WINAPI FindText32W( LPFINDREPLACE32W lpFind )
+{
+    HANDLE16 hInst;
+    LPCVOID ptr;
+
+    /*
+     * FIXME : Should respond to FR_ENABLETEMPLATE and FR_ENABLEHOOK here
+     * For now, only the standard dialog works.
+     */
+    /*
+     * FIXME : We should do error checking on the lpFind structure here
+     * and make CommDlgExtendedError() return the error condition.
+     */
+    ptr = SYSRES_GetResPtr( SYSRES_DIALOG_FIND_TEXT );
+    hInst = WIN_GetWindowInstance( lpFind->hwndOwner );
+    return DIALOG_CreateIndirect( hInst, ptr, TRUE, lpFind->hwndOwner,
+                (DLGPROC16)FindTextDlgProc32W, (LPARAM)lpFind, WIN_PROC_32W );
+}
+
+/***********************************************************************
+ *           ReplaceText16   (COMMDLG.12)
+ */
+HWND16 WINAPI ReplaceText16( SEGPTR find )
+{
+    HANDLE16 hInst;
+    LPCVOID ptr;
+    LPFINDREPLACE16 lpFind = (LPFINDREPLACE16)PTR_SEG_TO_LIN(find);
 
     /*
      * FIXME : Should respond to FR_ENABLETEMPLATE and FR_ENABLEHOOK here
@@ -891,44 +1028,87 @@
                                   find, WIN_PROC_16 );
 }
 
+/***********************************************************************
+ *           ReplaceText32A   (COMDLG32.19)
+ */
+HWND32 WINAPI ReplaceText32A( LPFINDREPLACE32A lpFind )
+{
+    HANDLE16 hInst;
+    LPCVOID ptr;
+
+    /*
+     * FIXME : Should respond to FR_ENABLETEMPLATE and FR_ENABLEHOOK here
+     * For now, only the standard dialog works.
+     */
+    /*
+     * FIXME : We should do error checking on the lpFind structure here
+     * and make CommDlgExtendedError() return the error condition.
+     */
+    ptr = SYSRES_GetResPtr( SYSRES_DIALOG_REPLACE_TEXT );
+    hInst = WIN_GetWindowInstance( lpFind->hwndOwner );
+    return DIALOG_CreateIndirect( hInst, ptr, TRUE, lpFind->hwndOwner,
+		(DLGPROC16)ReplaceTextDlgProc32A, (LPARAM)lpFind, WIN_PROC_32A );
+}
+
+/***********************************************************************
+ *           ReplaceText32W   (COMDLG32.20)
+ */
+HWND32 WINAPI ReplaceText32W( LPFINDREPLACE32W lpFind )
+{
+    HANDLE16 hInst;
+    LPCVOID ptr;
+
+    /*
+     * FIXME : Should respond to FR_ENABLETEMPLATE and FR_ENABLEHOOK here
+     * For now, only the standard dialog works.
+     */
+    /*
+     * FIXME : We should do error checking on the lpFind structure here
+     * and make CommDlgExtendedError() return the error condition.
+     */
+    ptr = SYSRES_GetResPtr( SYSRES_DIALOG_REPLACE_TEXT );
+    hInst = WIN_GetWindowInstance( lpFind->hwndOwner );
+    return DIALOG_CreateIndirect( hInst, ptr, TRUE, lpFind->hwndOwner,
+		(DLGPROC16)ReplaceTextDlgProc32W, (LPARAM)lpFind, WIN_PROC_32W );
+}
+
 
 /***********************************************************************
  *                              FINDDLG_WMInitDialog            [internal]
  */
-static LRESULT FINDDLG_WMInitDialog(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam)
+static LRESULT FINDDLG_WMInitDialog(HWND32 hWnd, LPARAM lParam, LPDWORD lpFlags,
+                                    LPSTR lpstrFindWhat, BOOL32 fUnicode)
 {
-    LPFINDREPLACE lpfr;
-
     SetWindowLong32A(hWnd, DWL_USER, lParam);
-    lpfr = (LPFINDREPLACE)PTR_SEG_TO_LIN(lParam);
-    lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
+    *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
     /*
      * FIXME : If the initial FindWhat string is empty, we should disable the
      * FindNext (IDOK) button.  Only after typing some text, the button should be
      * enabled.
      */
-    SetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat);
-    CheckRadioButton32(hWnd, rad1, rad2, (lpfr->Flags & FR_DOWN) ? rad2 : rad1);
-    if (lpfr->Flags & (FR_HIDEUPDOWN | FR_NOUPDOWN)) {
+    if (fUnicode) SetDlgItemText32W(hWnd, edt1, (LPWSTR)lpstrFindWhat);
+	else SetDlgItemText32A(hWnd, edt1, lpstrFindWhat);
+    CheckRadioButton32(hWnd, rad1, rad2, (*lpFlags & FR_DOWN) ? rad2 : rad1);
+    if (*lpFlags & (FR_HIDEUPDOWN | FR_NOUPDOWN)) {
 	EnableWindow32(GetDlgItem32(hWnd, rad1), FALSE);
 	EnableWindow32(GetDlgItem32(hWnd, rad2), FALSE);
     }
-    if (lpfr->Flags & FR_HIDEUPDOWN) {
+    if (*lpFlags & FR_HIDEUPDOWN) {
 	ShowWindow32(GetDlgItem32(hWnd, rad1), SW_HIDE);
 	ShowWindow32(GetDlgItem32(hWnd, rad2), SW_HIDE);
 	ShowWindow32(GetDlgItem32(hWnd, grp1), SW_HIDE);
     }
-    CheckDlgButton32(hWnd, chx1, (lpfr->Flags & FR_WHOLEWORD) ? 1 : 0);
-    if (lpfr->Flags & (FR_HIDEWHOLEWORD | FR_NOWHOLEWORD))
+    CheckDlgButton32(hWnd, chx1, (*lpFlags & FR_WHOLEWORD) ? 1 : 0);
+    if (*lpFlags & (FR_HIDEWHOLEWORD | FR_NOWHOLEWORD))
 	EnableWindow32(GetDlgItem32(hWnd, chx1), FALSE);
-    if (lpfr->Flags & FR_HIDEWHOLEWORD)
+    if (*lpFlags & FR_HIDEWHOLEWORD)
 	ShowWindow32(GetDlgItem32(hWnd, chx1), SW_HIDE);
-    CheckDlgButton32(hWnd, chx2, (lpfr->Flags & FR_MATCHCASE) ? 1 : 0);
-    if (lpfr->Flags & (FR_HIDEMATCHCASE | FR_NOMATCHCASE))
+    CheckDlgButton32(hWnd, chx2, (*lpFlags & FR_MATCHCASE) ? 1 : 0);
+    if (*lpFlags & (FR_HIDEMATCHCASE | FR_NOMATCHCASE))
 	EnableWindow32(GetDlgItem32(hWnd, chx2), FALSE);
-    if (lpfr->Flags & FR_HIDEMATCHCASE)
+    if (*lpFlags & FR_HIDEMATCHCASE)
 	ShowWindow32(GetDlgItem32(hWnd, chx2), SW_HIDE);
-    if (!(lpfr->Flags & FR_SHOWHELP)) {
+    if (!(*lpFlags & FR_SHOWHELP)) {
 	EnableWindow32(GetDlgItem32(hWnd, pshHelp), FALSE);
 	ShowWindow32(GetDlgItem32(hWnd, pshHelp), SW_HIDE);
     }
@@ -940,40 +1120,43 @@
 /***********************************************************************
  *                              FINDDLG_WMCommand               [internal]
  */
-static LRESULT FINDDLG_WMCommand(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam)
+static LRESULT FINDDLG_WMCommand(HWND32 hWnd, WPARAM32 wParam, 
+			HWND32 hwndOwner, LPDWORD lpFlags,
+			LPSTR lpstrFindWhat, WORD wFindWhatLen, 
+			BOOL32 fUnicode)
 {
-    LPFINDREPLACE lpfr;
     int uFindReplaceMessage = RegisterWindowMessage32A( FINDMSGSTRING );
     int uHelpMessage = RegisterWindowMessage32A( HELPMSGSTRING );
 
-    lpfr = (LPFINDREPLACE)PTR_SEG_TO_LIN(GetWindowLong32A(hWnd, DWL_USER));
     switch (wParam) {
 	case IDOK:
-	    GetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
+	    if (fUnicode) 
+	      GetDlgItemText32W(hWnd, edt1, (LPWSTR)lpstrFindWhat, wFindWhatLen/2);
+	      else GetDlgItemText32A(hWnd, edt1, lpstrFindWhat, wFindWhatLen);
 	    if (IsDlgButtonChecked32(hWnd, rad2))
-		lpfr->Flags |= FR_DOWN;
-		else lpfr->Flags &= ~FR_DOWN;
+		*lpFlags |= FR_DOWN;
+		else *lpFlags &= ~FR_DOWN;
 	    if (IsDlgButtonChecked32(hWnd, chx1))
-		lpfr->Flags |= FR_WHOLEWORD; 
-		else lpfr->Flags &= ~FR_WHOLEWORD;
+		*lpFlags |= FR_WHOLEWORD; 
+		else *lpFlags &= ~FR_WHOLEWORD;
 	    if (IsDlgButtonChecked32(hWnd, chx2))
-		lpfr->Flags |= FR_MATCHCASE; 
-		else lpfr->Flags &= ~FR_MATCHCASE;
-            lpfr->Flags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
-	    lpfr->Flags |= FR_FINDNEXT;
-	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0,
+		*lpFlags |= FR_MATCHCASE; 
+		else *lpFlags &= ~FR_MATCHCASE;
+            *lpFlags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
+	    *lpFlags |= FR_FINDNEXT;
+	    SendMessage32A(hwndOwner, uFindReplaceMessage, 0,
                           GetWindowLong32A(hWnd, DWL_USER) );
 	    return TRUE;
 	case IDCANCEL:
-            lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);
-	    lpfr->Flags |= FR_DIALOGTERM;
-	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0,
+            *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);
+	    *lpFlags |= FR_DIALOGTERM;
+	    SendMessage32A(hwndOwner, uFindReplaceMessage, 0,
                           GetWindowLong32A(hWnd, DWL_USER) );
-	    DestroyWindow16(hWnd);
+	    DestroyWindow32(hWnd);
 	    return TRUE;
 	case pshHelp:
 	    /* FIXME : should lpfr structure be passed as an argument ??? */
-	    SendMessage16(lpfr->hwndOwner, uHelpMessage, 0, 0);
+	    SendMessage32A(hwndOwner, uHelpMessage, 0, 0);
 	    return TRUE;
     }
     return FALSE;
@@ -981,16 +1164,64 @@
 
 
 /***********************************************************************
- *           FindTextDlgProc   (COMMDLG.13)
+ *           FindTextDlgProc16   (COMMDLG.13)
  */
-LRESULT WINAPI FindTextDlgProc(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
-                               LPARAM lParam)
+LRESULT WINAPI FindTextDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
+                                 LPARAM lParam)
 {
+    LPFINDREPLACE16 lpfr;
     switch (wMsg) {
 	case WM_INITDIALOG:
-	    return FINDDLG_WMInitDialog(hWnd, wParam, lParam);
+            lpfr=(LPFINDREPLACE16)PTR_SEG_TO_LIN(lParam);
+	    return FINDDLG_WMInitDialog(hWnd, lParam, &(lpfr->Flags),
+		PTR_SEG_TO_LIN(lpfr->lpstrFindWhat), FALSE);
 	case WM_COMMAND:
-	    return FINDDLG_WMCommand(hWnd, wParam, lParam);
+	    lpfr=(LPFINDREPLACE16)PTR_SEG_TO_LIN(GetWindowLong32A(hWnd, DWL_USER));
+	    return FINDDLG_WMCommand(hWnd, wParam, lpfr->hwndOwner,
+		&lpfr->Flags, PTR_SEG_TO_LIN(lpfr->lpstrFindWhat),
+		lpfr->wFindWhatLen, FALSE);
+    }
+    return FALSE;
+}
+
+/***********************************************************************
+ *           FindTextDlgProc32A
+ */
+LRESULT WINAPI FindTextDlgProc32A(HWND32 hWnd, UINT32 wMsg, WPARAM32 wParam,
+                                 LPARAM lParam)
+{
+    LPFINDREPLACE32A lpfr;
+    switch (wMsg) {
+	case WM_INITDIALOG:
+	    lpfr=(LPFINDREPLACE32A)lParam;
+	    return FINDDLG_WMInitDialog(hWnd, lParam, &(lpfr->Flags),
+	      lpfr->lpstrFindWhat, FALSE);
+	case WM_COMMAND:
+	    lpfr=(LPFINDREPLACE32A)GetWindowLong32A(hWnd, DWL_USER);
+	    return FINDDLG_WMCommand(hWnd, wParam, lpfr->hwndOwner,
+		&lpfr->Flags, lpfr->lpstrFindWhat, lpfr->wFindWhatLen,
+		FALSE);
+    }
+    return FALSE;
+}
+
+/***********************************************************************
+ *           FindTextDlgProc32W
+ */
+LRESULT WINAPI FindTextDlgProc32W(HWND32 hWnd, UINT32 wMsg, WPARAM32 wParam,
+                                 LPARAM lParam)
+{
+    LPFINDREPLACE32W lpfr;
+    switch (wMsg) {
+	case WM_INITDIALOG:
+	    lpfr=(LPFINDREPLACE32W)lParam;
+	    return FINDDLG_WMInitDialog(hWnd, lParam, &(lpfr->Flags),
+	      (LPSTR)lpfr->lpstrFindWhat, TRUE);
+	case WM_COMMAND:
+	    lpfr=(LPFINDREPLACE32W)GetWindowLong32A(hWnd, DWL_USER);
+	    return FINDDLG_WMCommand(hWnd, wParam, lpfr->hwndOwner,
+		&lpfr->Flags, (LPSTR)lpfr->lpstrFindWhat, lpfr->wFindWhatLen,
+		TRUE);
     }
     return FALSE;
 }
@@ -999,31 +1230,37 @@
 /***********************************************************************
  *                              REPLACEDLG_WMInitDialog         [internal]
  */
-static LRESULT REPLACEDLG_WMInitDialog(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam)
+static LRESULT REPLACEDLG_WMInitDialog(HWND32 hWnd, LPARAM lParam,
+		    LPDWORD lpFlags, LPSTR lpstrFindWhat, 
+		    LPSTR lpstrReplaceWith, BOOL32 fUnicode)
 {
-    LPFINDREPLACE lpfr;
-
     SetWindowLong32A(hWnd, DWL_USER, lParam);
-    lpfr = (LPFINDREPLACE)PTR_SEG_TO_LIN(lParam);
-    lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
+    *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
     /*
      * FIXME : If the initial FindWhat string is empty, we should disable the FinNext /
      * Replace / ReplaceAll buttons.  Only after typing some text, the buttons should be
      * enabled.
      */
-    SetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat);
-    SetDlgItemText16(hWnd, edt2, lpfr->lpstrReplaceWith);
-    CheckDlgButton32(hWnd, chx1, (lpfr->Flags & FR_WHOLEWORD) ? 1 : 0);
-    if (lpfr->Flags & (FR_HIDEWHOLEWORD | FR_NOWHOLEWORD))
+    if (fUnicode)     
+    {
+	SetDlgItemText32W(hWnd, edt1, (LPWSTR)lpstrFindWhat);
+	SetDlgItemText32W(hWnd, edt2, (LPWSTR)lpstrReplaceWith);
+    } else
+    {
+	SetDlgItemText32A(hWnd, edt1, lpstrFindWhat);
+	SetDlgItemText32A(hWnd, edt2, lpstrReplaceWith);
+    }
+    CheckDlgButton32(hWnd, chx1, (*lpFlags & FR_WHOLEWORD) ? 1 : 0);
+    if (*lpFlags & (FR_HIDEWHOLEWORD | FR_NOWHOLEWORD))
 	EnableWindow32(GetDlgItem32(hWnd, chx1), FALSE);
-    if (lpfr->Flags & FR_HIDEWHOLEWORD)
+    if (*lpFlags & FR_HIDEWHOLEWORD)
 	ShowWindow32(GetDlgItem32(hWnd, chx1), SW_HIDE);
-    CheckDlgButton32(hWnd, chx2, (lpfr->Flags & FR_MATCHCASE) ? 1 : 0);
-    if (lpfr->Flags & (FR_HIDEMATCHCASE | FR_NOMATCHCASE))
+    CheckDlgButton32(hWnd, chx2, (*lpFlags & FR_MATCHCASE) ? 1 : 0);
+    if (*lpFlags & (FR_HIDEMATCHCASE | FR_NOMATCHCASE))
 	EnableWindow32(GetDlgItem32(hWnd, chx2), FALSE);
-    if (lpfr->Flags & FR_HIDEMATCHCASE)
+    if (*lpFlags & FR_HIDEMATCHCASE)
 	ShowWindow32(GetDlgItem32(hWnd, chx2), SW_HIDE);
-    if (!(lpfr->Flags & FR_SHOWHELP)) {
+    if (!(*lpFlags & FR_SHOWHELP)) {
 	EnableWindow32(GetDlgItem32(hWnd, pshHelp), FALSE);
 	ShowWindow32(GetDlgItem32(hWnd, pshHelp), SW_HIDE);
     }
@@ -1035,66 +1272,89 @@
 /***********************************************************************
  *                              REPLACEDLG_WMCommand            [internal]
  */
-static LRESULT REPLACEDLG_WMCommand(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam)
+static LRESULT REPLACEDLG_WMCommand(HWND32 hWnd, WPARAM16 wParam,
+		    HWND32 hwndOwner, LPDWORD lpFlags,
+		    LPSTR lpstrFindWhat, WORD wFindWhatLen,
+		    LPSTR lpstrReplaceWith, WORD wReplaceWithLen,
+		    BOOL32 fUnicode)
 {
-    LPFINDREPLACE lpfr;
     int uFindReplaceMessage = RegisterWindowMessage32A( FINDMSGSTRING );
     int uHelpMessage = RegisterWindowMessage32A( HELPMSGSTRING );
 
-    lpfr = (LPFINDREPLACE)PTR_SEG_TO_LIN(GetWindowLong32A(hWnd, DWL_USER));
     switch (wParam) {
 	case IDOK:
-	    GetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
-	    GetDlgItemText16(hWnd, edt2, lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen);
+	    if (fUnicode)
+	    {
+		GetDlgItemText32W(hWnd, edt1, (LPWSTR)lpstrFindWhat, wFindWhatLen/2);
+		GetDlgItemText32W(hWnd, edt2, (LPWSTR)lpstrReplaceWith, wReplaceWithLen/2);
+	    }  else
+	    {
+		GetDlgItemText32A(hWnd, edt1, lpstrFindWhat, wFindWhatLen);
+		GetDlgItemText32A(hWnd, edt2, lpstrReplaceWith, wReplaceWithLen);
+	    }
 	    if (IsDlgButtonChecked32(hWnd, chx1))
-		lpfr->Flags |= FR_WHOLEWORD; 
-		else lpfr->Flags &= ~FR_WHOLEWORD;
+		*lpFlags |= FR_WHOLEWORD; 
+		else *lpFlags &= ~FR_WHOLEWORD;
 	    if (IsDlgButtonChecked32(hWnd, chx2))
-		lpfr->Flags |= FR_MATCHCASE; 
-		else lpfr->Flags &= ~FR_MATCHCASE;
-            lpfr->Flags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
-	    lpfr->Flags |= FR_FINDNEXT;
-	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0,
+		*lpFlags |= FR_MATCHCASE; 
+		else *lpFlags &= ~FR_MATCHCASE;
+            *lpFlags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
+	    *lpFlags |= FR_FINDNEXT;
+	    SendMessage32A(hwndOwner, uFindReplaceMessage, 0,
                           GetWindowLong32A(hWnd, DWL_USER) );
 	    return TRUE;
 	case IDCANCEL:
-            lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);
-	    lpfr->Flags |= FR_DIALOGTERM;
-	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0,
+            *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);
+	    *lpFlags |= FR_DIALOGTERM;
+	    SendMessage32A(hwndOwner, uFindReplaceMessage, 0,
                           GetWindowLong32A(hWnd, DWL_USER) );
-	    DestroyWindow16(hWnd);
+	    DestroyWindow32(hWnd);
 	    return TRUE;
 	case psh1:
-	    GetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
-	    GetDlgItemText16(hWnd, edt2, lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen);
+	    if (fUnicode)
+	    {
+		GetDlgItemText32W(hWnd, edt1, (LPWSTR)lpstrFindWhat, wFindWhatLen/2);
+		GetDlgItemText32W(hWnd, edt2, (LPWSTR)lpstrReplaceWith, wReplaceWithLen/2);
+	    }  else
+	    {	
+		GetDlgItemText32A(hWnd, edt1, lpstrFindWhat, wFindWhatLen);
+		GetDlgItemText32A(hWnd, edt2, lpstrReplaceWith, wReplaceWithLen);
+	    }
 	    if (IsDlgButtonChecked32(hWnd, chx1))
-		lpfr->Flags |= FR_WHOLEWORD; 
-		else lpfr->Flags &= ~FR_WHOLEWORD;
+		*lpFlags |= FR_WHOLEWORD; 
+		else *lpFlags &= ~FR_WHOLEWORD;
 	    if (IsDlgButtonChecked32(hWnd, chx2))
-		lpfr->Flags |= FR_MATCHCASE; 
-		else lpfr->Flags &= ~FR_MATCHCASE;
-            lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACEALL | FR_DIALOGTERM);
-	    lpfr->Flags |= FR_REPLACE;
-	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0,
+		*lpFlags |= FR_MATCHCASE; 
+		else *lpFlags &= ~FR_MATCHCASE;
+            *lpFlags &= ~(FR_FINDNEXT | FR_REPLACEALL | FR_DIALOGTERM);
+	    *lpFlags |= FR_REPLACE;
+	    SendMessage32A(hwndOwner, uFindReplaceMessage, 0,
                           GetWindowLong32A(hWnd, DWL_USER) );
 	    return TRUE;
 	case psh2:
-	    GetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
-	    GetDlgItemText16(hWnd, edt2, lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen);
+	    if (fUnicode)
+	    {
+		GetDlgItemText32W(hWnd, edt1, (LPWSTR)lpstrFindWhat, wFindWhatLen/2);
+		GetDlgItemText32W(hWnd, edt2, (LPWSTR)lpstrReplaceWith, wReplaceWithLen/2);
+	    }  else
+	    {
+		GetDlgItemText32A(hWnd, edt1, lpstrFindWhat, wFindWhatLen);
+		GetDlgItemText32A(hWnd, edt2, lpstrReplaceWith, wReplaceWithLen);
+	    }
 	    if (IsDlgButtonChecked32(hWnd, chx1))
-		lpfr->Flags |= FR_WHOLEWORD; 
-		else lpfr->Flags &= ~FR_WHOLEWORD;
+		*lpFlags |= FR_WHOLEWORD; 
+		else *lpFlags &= ~FR_WHOLEWORD;
 	    if (IsDlgButtonChecked32(hWnd, chx2))
-		lpfr->Flags |= FR_MATCHCASE; 
-		else lpfr->Flags &= ~FR_MATCHCASE;
-            lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_DIALOGTERM);
-	    lpfr->Flags |= FR_REPLACEALL;
-	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0,
+		*lpFlags |= FR_MATCHCASE; 
+		else *lpFlags &= ~FR_MATCHCASE;
+            *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_DIALOGTERM);
+	    *lpFlags |= FR_REPLACEALL;
+	    SendMessage32A(hwndOwner, uFindReplaceMessage, 0,
                           GetWindowLong32A(hWnd, DWL_USER) );
 	    return TRUE;
 	case pshHelp:
 	    /* FIXME : should lpfr structure be passed as an argument ??? */
-	    SendMessage16(lpfr->hwndOwner, uHelpMessage, 0, 0);
+	    SendMessage32A(hwndOwner, uHelpMessage, 0, 0);
 	    return TRUE;
     }
     return FALSE;
@@ -1102,16 +1362,67 @@
 
 
 /***********************************************************************
- *           ReplaceTextDlgProc   (COMMDLG.14)
+ *           ReplaceTextDlgProc16   (COMMDLG.14)
  */
-LRESULT WINAPI ReplaceTextDlgProc(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
-                                  LPARAM lParam)
+LRESULT WINAPI ReplaceTextDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
+                                    LPARAM lParam)
 {
+    LPFINDREPLACE16 lpfr;
     switch (wMsg) {
 	case WM_INITDIALOG:
-	    return REPLACEDLG_WMInitDialog(hWnd, wParam, lParam);
+            lpfr=(LPFINDREPLACE16)PTR_SEG_TO_LIN(lParam);
+	    return REPLACEDLG_WMInitDialog(hWnd, lParam, &lpfr->Flags,
+		    PTR_SEG_TO_LIN(lpfr->lpstrFindWhat),
+		    PTR_SEG_TO_LIN(lpfr->lpstrReplaceWith), FALSE);
 	case WM_COMMAND:
-	    return REPLACEDLG_WMCommand(hWnd, wParam, lParam);
+	    lpfr=(LPFINDREPLACE16)PTR_SEG_TO_LIN(GetWindowLong32A(hWnd, DWL_USER));
+	    return REPLACEDLG_WMCommand(hWnd, wParam, lpfr->hwndOwner, 
+		    &lpfr->Flags, PTR_SEG_TO_LIN(lpfr->lpstrFindWhat),
+		    lpfr->wFindWhatLen, PTR_SEG_TO_LIN(lpfr->lpstrReplaceWith),
+		    lpfr->wReplaceWithLen, FALSE);
+    }
+    return FALSE;
+}
+
+/***********************************************************************
+ *           ReplaceTextDlgProc32A
+ */ 
+LRESULT WINAPI ReplaceTextDlgProc32A(HWND32 hWnd, UINT32 wMsg, WPARAM32 wParam,
+                                    LPARAM lParam)
+{
+    LPFINDREPLACE32A lpfr;
+    switch (wMsg) {
+	case WM_INITDIALOG:
+            lpfr=(LPFINDREPLACE32A)lParam;
+	    return REPLACEDLG_WMInitDialog(hWnd, lParam, &lpfr->Flags,
+		    lpfr->lpstrFindWhat, lpfr->lpstrReplaceWith, FALSE);
+	case WM_COMMAND:
+	    lpfr=(LPFINDREPLACE32A)GetWindowLong32A(hWnd, DWL_USER);
+	    return REPLACEDLG_WMCommand(hWnd, wParam, lpfr->hwndOwner, 
+		    &lpfr->Flags, lpfr->lpstrFindWhat, lpfr->wFindWhatLen,
+		    lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen, FALSE);
+    }
+    return FALSE;
+}
+
+/***********************************************************************
+ *           ReplaceTextDlgProc32W
+ */ 
+LRESULT WINAPI ReplaceTextDlgProc32W(HWND32 hWnd, UINT32 wMsg, WPARAM32 wParam,
+                                    LPARAM lParam)
+{
+    LPFINDREPLACE32W lpfr;
+    switch (wMsg) {
+	case WM_INITDIALOG:
+            lpfr=(LPFINDREPLACE32W)lParam;
+	    return REPLACEDLG_WMInitDialog(hWnd, lParam, &lpfr->Flags,
+		    (LPSTR)lpfr->lpstrFindWhat, (LPSTR)lpfr->lpstrReplaceWith,
+		    TRUE);
+	case WM_COMMAND:
+	    lpfr=(LPFINDREPLACE32W)GetWindowLong32A(hWnd, DWL_USER);
+	    return REPLACEDLG_WMCommand(hWnd, wParam, lpfr->hwndOwner, 
+		    &lpfr->Flags, (LPSTR)lpfr->lpstrFindWhat, lpfr->wFindWhatLen,
+		    (LPSTR)lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen, TRUE);
     }
     return FALSE;
 }
@@ -1321,7 +1632,8 @@
     {
         HANDLE16 hResInfo;
         if (!(hResInfo = FindResource16(lpChCol->hInstance,
-                                        lpChCol->lpTemplateName, RT_DIALOG)))
+                                        lpChCol->lpTemplateName,
+                                        RT_DIALOG16)))
         {
             CommDlgLastError = CDERR_FINDRESFAILURE;
             return FALSE;
@@ -1798,7 +2110,7 @@
  HBRUSH32 hbrush;
  HDC32 hdc ;
  RECT16 rect,client;
- HCURSOR16 hcursor=SetCursor16(LoadCursor16(0,IDC_WAIT));
+ HCURSOR16 hcursor=SetCursor16(LoadCursor16(0,IDC_WAIT16));
 
  GetClientRect16(hwnd,&client);
  hdc=GetDC32(hwnd);
@@ -2416,7 +2728,8 @@
     {
         HANDLE16 hResInfo;
         if (!(hResInfo = FindResource16( lpChFont->hInstance,
-                                         lpChFont->lpTemplateName, RT_DIALOG)))
+                                         lpChFont->lpTemplateName,
+                                         RT_DIALOG16)))
         {
             CommDlgLastError = CDERR_FINDRESFAILURE;
             return FALSE;
@@ -2635,7 +2948,7 @@
   int i,j,res,init=0;
   long l;
   LPLOGFONT16 lpxx;
-  HCURSOR16 hcursor=SetCursor16(LoadCursor16(0,IDC_WAIT));
+  HCURSOR16 hcursor=SetCursor16(LoadCursor16(0,IDC_WAIT16));
   LPCHOOSEFONT lpcf;
 
   SetWindowLong32A(hDlg, DWL_USER, lParam); 
@@ -2650,7 +2963,7 @@
     return FALSE;
   }
   if (!hBitmapTT)
-    hBitmapTT = LoadBitmap16(0, MAKEINTRESOURCE(OBM_TRTYPE));
+    hBitmapTT = LoadBitmap16(0, MAKEINTRESOURCE16(OBM_TRTYPE));
 			 
   if (!(lpcf->Flags & CF_SHOWHELP) || !IsWindow32(lpcf->hwndOwner))
     ShowWindow32(GetDlgItem32(hDlg,pshHelp),SW_HIDE);
@@ -2754,7 +3067,7 @@
   BITMAP16 bm;
   LPMEASUREITEMSTRUCT16 lpmi=PTR_SEG_TO_LIN((LPMEASUREITEMSTRUCT16)lParam);
   if (!hBitmapTT)
-    hBitmapTT = LoadBitmap16(0, MAKEINTRESOURCE(OBM_TRTYPE));
+    hBitmapTT = LoadBitmap16(0, MAKEINTRESOURCE16(OBM_TRTYPE));
   GetObject16( hBitmapTT, sizeof(bm), &bm );
   lpmi->itemHeight=bm.bmHeight;
   /* FIXME: use MAX of bm.bmHeight and tm.tmHeight .*/
@@ -2896,7 +3209,7 @@
 		      i=SendDlgItemMessage16(hDlg,cmb1,CB_GETCURSEL16,0,0);
 		      if (i!=CB_ERR)
 		      {
-		        HCURSOR16 hcursor=SetCursor16(LoadCursor16(0,IDC_WAIT));
+		        HCURSOR16 hcursor=SetCursor16(LoadCursor16(0,IDC_WAIT16));
                         char *str = SEGPTR_ALLOC(256);
                         SendDlgItemMessage16(hDlg,cmb1,CB_GETLBTEXT16,i,
                                              (LPARAM)SEGPTR_GET(str));
@@ -3084,11 +3397,14 @@
 	}								\
 	ofn16->nMaxCustFilter = ofn->nMaxCustFilter;			\
 	ofn16->nFilterIndex = ofn->nFilterIndex;			\
+	if (ofn->nMaxFile)                                              \
 	ofn16->lpstrFile = SEGPTR_GET(SEGPTR_ALLOC(ofn->nMaxFile));	\
 	ofn16->nMaxFile = ofn->nMaxFile;				\
-	if (ofn->lpstrFileTitle)					\
+	if (ofn16->lpstrFileTitle)					\
 		ofn16->lpstrFileTitle= SEGPTR_GET(SEGPTR_STRDUP(ofn->lpstrFileTitle));\
 	ofn16->nMaxFileTitle = ofn->nMaxFileTitle;			\
+        if (ofn16->nMaxFileTitle)                                       \
+                ofn16->lpstrFileTitle = SEGPTR_GET(SEGPTR_ALLOC(ofn->nMaxFileTitle));\
 	if (ofn->lpstrInitialDir)					\
 		ofn16->lpstrInitialDir = SEGPTR_GET(SEGPTR_STRDUP(ofn->lpstrInitialDir));\
 	if (ofn->lpstrTitle)						\
@@ -3106,6 +3422,8 @@
 									\
 	ret = xxx##16(SEGPTR_GET(ofn16));				\
 									\
+	ofn->nFileOffset = ofn16->nFileOffset;				\
+	ofn->nFileExtension = ofn16->nFileExtension;			\
 	if (ofn16->lpstrFilter)						\
 		SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFilter));	\
 	if (ofn16->lpTemplateName)					\
@@ -3119,11 +3437,15 @@
 	if (ofn16->lpstrCustomFilter)					\
 		SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrCustomFilter));	\
 									\
+	if (ofn16->lpstrFile) {                                         \
 	strcpy(ofn->lpstrFile,PTR_SEG_TO_LIN(ofn16->lpstrFile));	\
 	SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFile));			\
+	}                                                               \
 									\
-	if (ofn16->lpstrFileTitle)					\
+	if (ofn16->lpstrFileTitle) {         				\
+                strcpy(ofn->lpstrFileTitle,PTR_SEG_TO_LIN(ofn16->lpstrFileTitle));\
 		SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFileTitle));	\
+	}                                                               \
 	SEGPTR_FREE(ofn16);						\
 	return ret;							\
 }									\
@@ -3182,11 +3504,14 @@
 	}								\
 	ofn16->nMaxCustFilter = ofn->nMaxCustFilter;			\
 	ofn16->nFilterIndex = ofn->nFilterIndex;			\
+        if (ofn->nMaxFile)                                              \
 	ofn16->lpstrFile = SEGPTR_GET(SEGPTR_ALLOC(ofn->nMaxFile));	\
 	ofn16->nMaxFile = ofn->nMaxFile;				\
-	if (ofn->lpstrFileTitle)					\
+	if (ofn16->lpstrFileTitle)					\
 		ofn16->lpstrFileTitle= SEGPTR_GET(SEGPTR_STRDUP_WtoA(ofn->lpstrFileTitle));\
 	ofn16->nMaxFileTitle = ofn->nMaxFileTitle;			\
+        if (ofn->nMaxFileTitle)                                         \
+		ofn16->lpstrFileTitle = SEGPTR_GET(SEGPTR_ALLOC(ofn->nMaxFileTitle));\
 	if (ofn->lpstrInitialDir)					\
 		ofn16->lpstrInitialDir = SEGPTR_GET(SEGPTR_STRDUP_WtoA(ofn->lpstrInitialDir));\
 	if (ofn->lpstrTitle)						\
@@ -3203,6 +3528,8 @@
 	}								\
 	ret = xxx##16(SEGPTR_GET(ofn16));				\
 									\
+	ofn->nFileOffset = ofn16->nFileOffset;				\
+	ofn->nFileExtension = ofn16->nFileExtension;			\
 	if (ofn16->lpstrFilter)						\
 		SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFilter));	\
 	if (ofn16->lpTemplateName)					\
@@ -3216,11 +3543,15 @@
 	if (ofn16->lpstrCustomFilter)					\
 		SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrCustomFilter));	\
 									\
+	if (ofn16->lpstrFile) {                                         \
 	lstrcpyAtoW(ofn->lpstrFile,PTR_SEG_TO_LIN(ofn16->lpstrFile));	\
 	SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFile));			\
+	}                                                               \
 									\
-	if (ofn16->lpstrFileTitle)					\
+	if (ofn16->lpstrFileTitle) {					\
+                lstrcpyAtoW(ofn->lpstrFileTitle,PTR_SEG_TO_LIN(ofn16->lpstrFileTitle));\
 		SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFileTitle));	\
+	}                                                               \
 	SEGPTR_FREE(ofn16);						\
 	return ret;							\
 }
diff --git a/misc/cpu.c b/misc/cpu.c
index 65e9ac4..0369b49 100644
--- a/misc/cpu.c
+++ b/misc/cpu.c
@@ -8,6 +8,7 @@
 #include <stdio.h>
 #include <ctype.h>
 #include <string.h>
+#include "global.h"
 #include "windows.h"
 #include "winnt.h"
 #include "winreg.h"
@@ -34,7 +35,7 @@
 	 * FIXME: perhaps overrideable with precompiler flags?
 	 */
 	cachedsi.u.x.wProcessorArchitecture	= PROCESSOR_ARCHITECTURE_INTEL;
-	cachedsi.dwPageSize 			= 4096;
+	cachedsi.dwPageSize 			= VIRTUAL_GetPageSize();
 
 	/* FIXME: better values for the two entries below... */
 	cachedsi.lpMinimumApplicationAddress	= (void *)0x40000000;
diff --git a/misc/crtdll.c b/misc/crtdll.c
index e4cdda0..2c00a32 100644
--- a/misc/crtdll.c
+++ b/misc/crtdll.c
@@ -1703,3 +1703,29 @@
   TRACE(crtdll,"CRTDLL__sleep for %ld milliseconds\n",timeout);
   Sleep((timeout)?timeout:1);
 }
+/*********************************************************************
+ *                  getenv           (CRTDLL.437)
+ */
+LPSTR __cdecl CRTDLL_getenv(const char *name) 
+{
+     LPSTR environ = GetEnvironmentStrings32A();
+     LPSTR pp,pos = NULL;
+     unsigned int length;
+  
+     for (pp = environ; (*pp); pp = pp + strlen(pp) +1)
+       {
+	 pos =strchr(pp,'=');
+	 if (pos)
+	   length = pos -pp;
+	 else
+	   length = strlen(pp);
+	 if (!strncmp(pp,name,length)) break;
+       }
+     if ((pp)&& (pos)) 
+       {
+	 pp = pos+1;
+	 TRACE(crtdll,"got %s\n",pp);
+       }
+     FreeEnvironmentStrings32A( environ );
+     return pp;
+}
diff --git a/misc/ddeml.c b/misc/ddeml.c
index fb94286..87b1f84 100644
--- a/misc/ddeml.c
+++ b/misc/ddeml.c
@@ -12,6 +12,9 @@
 #include "debug.h"
 
 
+static LONG     DDE_current_handle;
+
+
 /*****************************************************************
  *            DdeInitialize16   (DDEML.2)
  */
@@ -174,7 +177,8 @@
 HSZ WINAPI DdeCreateStringHandle32A( DWORD idInst, LPCSTR psz, INT32 codepage )
 {
     FIXME( ddeml, "empty stub\n" );
-    return 0;
+    DDE_current_handle++;
+    return DDE_current_handle;
 }
 
 
@@ -184,7 +188,8 @@
 HSZ WINAPI DdeCreateStringHandle32W( DWORD idInst, LPCWSTR psz, INT32 codepage)
 {
     FIXME( ddeml, "empty stub\n" );
-    return 0;
+    DDE_current_handle++;
+    return DDE_current_handle;
 }
 
 
diff --git a/misc/debugstr.c b/misc/debugstr.c
index e720a33..d5d8e69 100644
--- a/misc/debugstr.c
+++ b/misc/debugstr.c
@@ -129,15 +129,57 @@
 /* This routine returns a nicely formated name of the resource res
    If the resource name is a string, it will return '<res-name>'
    If it is a number, it will return #<4-digit-hex-number> */
-LPSTR
-debugres (const void *res)
+LPSTR debugres_a( LPCSTR res )
 {
-  if (HIWORD((DWORD)res))
-    return debugstr_a((LPCSTR)res);
-  else{
     char resname[10];
+    if (HIWORD(res)) return debugstr_a(res);
     sprintf(resname, "#%04x", LOWORD(res));
     return debugstr_a (resname);
-  }
 }
 
+LPSTR debugres_w( LPCWSTR res )
+{
+    char resname[10];
+    if (HIWORD(res)) return debugstr_w(res);
+    sprintf(resname, "#%04x", LOWORD(res));
+    return debugstr_a (resname);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void debug_dumpstr (LPCSTR s)
+{
+  fputc ('"', stderr);
+  while (*s)
+    {
+      switch (*s)
+	{
+	case '\\':
+	case '"':
+	  fputc ('\\', stderr);
+	  fputc (*s, stderr);
+	  break;
+	case '\n':
+	  fputc ('\\', stderr);
+	  fputc ('n', stderr);
+	  break;
+	case '\r':
+	  fputc ('\\', stderr);
+	  fputc ('r', stderr);
+	  break;
+	case '\t':
+	  fputc ('\\', stderr);
+	  fputc ('t', stderr);
+	  break;
+	default:
+	  if (*s<' ')
+	    printf ("\\0x%02x", *s);
+	  else
+	    fputc (*s, stderr);
+	}
+      s++;
+    }
+  fputc ('"', stderr);
+}
+
+/* ---------------------------------------------------------------------- */
diff --git a/misc/imagelist.c b/misc/imagelist.c
index db4c8b4..474de9e 100644
--- a/misc/imagelist.c
+++ b/misc/imagelist.c
@@ -5,28 +5,21 @@
  *
  *  TODO:
  *    - Improve the documentation.
- *    - Fix ImageList_DrawIndirect.
- *        - Drawing selected images is awfully slow since it has to
- *          be done pixel by pixel.
- *    - Fix ImageList_GetIcon (almost fixed).
- *    - Fix all other stubs.
+ *    - Improve error checking in some functions.
+ *    - Fix ILD_TRANSPARENT error in ImageList_DrawIndirect.
+ *    - Fix offsets in ImageList_DrawIndirect.
+ *    - Fix ImageList_GetIcon (might be a result of the
+ *      ILD_TRANSPARENT error in ImageList_DrawIndirect).
  *    - Fix drag functions.
- *    - Improve error checking in most functions.
+ *    - Fix all other stubs.
  *    - Add ImageList_SetFilter (undocumented).
  *      BTW does anybody know anything about this function???
  *        - It removes 12 Bytes from the stack (3 Parameters).
  *        - First parameter SHOULD be a HIMAGELIST.
  *        - Second parameter COULD be an index?????
  *        - Third parameter.... ?????????????????????
- *    - Add undocumented functions.
- *        Are there any other undocumented ImageList functions?
  *
  *  Testing:
- *    - Test ImageList_LoadImageA/W with Icons and Cursors.
- *    - Test ImageList_Copy.
- *    - Test ImageList_Duplicate.
- *    - Test ImageList_Remove.
- *    - Test ImageList_SetImageCount.
  *    - Test ImageList_GetImageRect (undocumented).
  *    - Test all the other functions.
  *
@@ -54,7 +47,6 @@
 #include "imagelist.h"
 #include "commctrl.h"
 #include "debug.h"
-#include "heap.h"
 
 #ifdef __GET_ICON_INFO_HACK__
 #include "bitmap.h"
@@ -76,8 +68,16 @@
 static HCURSOR32  hcurInternal = 0;
 
 
-static void
-IMAGELIST_InternalGrowBitmaps (HIMAGELIST himl, INT32 nImageCount)
+/*************************************************************************
+ *	 		 IMAGELIST_InternalGrowBitmaps   [Internal]
+ *
+ *  Grows the bitmaps of the given image list by the given number of 
+ *  images. Can NOT be used to reduce the number of images.
+ */
+
+static void IMAGELIST_InternalGrowBitmaps (
+	HIMAGELIST himl,    /* image list handle */
+	INT32 nImageCount)  /* number of images to grow by */
 {
     HDC32     hdcImageList, hdcBitmap;
     HBITMAP32 hbmNewBitmap;
@@ -126,44 +126,14 @@
 }
 
 
-static void
-IMAGELIST_InternalDrawMask (HIMAGELIST himl, INT32 i, HDC32 hdc,
-                            INT32 x, INT32 y)
-{
-    HDC32 hdcImageList;
-
-    if (himl->hbmMask)
-    {
-        hdcImageList = CreateCompatibleDC32 (0);
-        SelectObject32 (hdcImageList, himl->hbmMask);
-        BitBlt32 (hdc, x, y, himl->cx, himl->cy, hdcImageList,
-                  himl->cx * i, 0, SRCCOPY);
-        DeleteDC32 (hdcImageList);
-    }  
-}
-
-
-static void
-IMAGELIST_InternalDrawImage (HIMAGELIST himl, INT32 i, HDC32 hdc,
-                             INT32 x, INT32 y, UINT32 fStyle)
-{
-    HDC32 hdcImageList;
-
-    hdcImageList = CreateCompatibleDC32 (0);
-    SelectObject32 (hdcImageList, himl->hbmImage);
-    BitBlt32 (hdc, x, y, himl->cx, himl->cy, hdcImageList,
-              himl->cx * i, 0, SRCCOPY);
-    DeleteDC32 (hdcImageList);
-}
-
-
 /*************************************************************************
  *	 		 ImageList_Add   [COMCTL32.39]
  *
  *  Add an image (and a mask) to an image list.
  *
  *  RETURNS
- *    Index of the first image that was added, -1 if an error occurred.
+ *    Index of the first image that was added.
+ *    -1 if an error occurred.
  */
 
 INT32 WINAPI ImageList_Add (
@@ -174,17 +144,17 @@
     HDC32    hdcImageList, hdcImage, hdcMask;
     INT32    nFirstIndex, nImageCount;
     INT32    nStartX, nRunX, nRunY;
-    COLORREF clrColor;
     BITMAP32 bmp;
 
     if (himl == NULL) return (-1);
 
+    hdcMask = 0; /* to keep compiler happy ;-) */
+
     GetObject32A (hbmImage, sizeof(BITMAP32), (LPVOID)&bmp);
     nImageCount = bmp.bmWidth / himl->cx;
 
     if (himl->cCurImage + nImageCount >= himl->cMaxImage)
         IMAGELIST_InternalGrowBitmaps (himl, nImageCount);
-//        ImageList_SetImageCount (himl, himl->cCurImage + nImageCount);
 
     hdcImageList = CreateCompatibleDC32 (0);
     hdcImage = CreateCompatibleDC32 (0);
@@ -203,6 +173,21 @@
             SelectObject32 (hdcImage, hbmMask);
             BitBlt32 (hdcImageList, himl->cCurImage * himl->cx, 0,
                       bmp.bmWidth, himl->cy, hdcImage, 0, 0, SRCCOPY);
+
+            /* fix transparent areas of the image bitmap*/
+            SelectObject32 (hdcMask, himl->hbmMask);
+            SelectObject32 (hdcImage, himl->hbmImage);
+            nStartX = himl->cCurImage * himl->cx;
+            for (nRunY = 0; nRunY < himl->cy; nRunY++)
+            {
+                for (nRunX = 0; nRunX < bmp.bmWidth; nRunX++)
+                {
+                    if (GetPixel32 (hdcMask, nStartX + nRunX, nRunY) ==
+                        RGB(255, 255, 255))
+                        SetPixel32 (hdcImage, nStartX + nRunX, nRunY, 
+                                    RGB(0, 0, 0));
+                }
+            }
         }
         else
         {
@@ -214,8 +199,8 @@
             {
                 for (nRunX = 0; nRunX < bmp.bmWidth; nRunX++)
                 {
-                    clrColor = GetPixel32 (hdcImageList, nStartX + nRunX, nRunY);
-                    if (clrColor == himl->clrBk)
+                    if (GetPixel32 (hdcImageList, nStartX + nRunX, nRunY) ==
+                        himl->clrBk)
                     {
                         SetPixel32 (hdcImageList, nStartX + nRunX, nRunY, 
                                     RGB(0, 0, 0));
@@ -248,7 +233,8 @@
  *  mask color.
  *
  *  RETURNS
- *    Index of the first image that was added, -1 if an error occurred.
+ *    Index of the first image that was added.
+ *    -1 if an error occurred.
  */
 
 INT32 WINAPI ImageList_AddMasked (
@@ -260,7 +246,6 @@
     INT32    nIndex, nImageCount;
     BITMAP32 bmp;
     INT32    nStartX, nRunX, nRunY;
-    COLORREF clrColor;
 
     if (himl == NULL) return (-1);
 
@@ -291,8 +276,8 @@
         {
             for (nRunX = 0; nRunX < bmp.bmWidth; nRunX++)
             {
-                clrColor = GetPixel32 (hdcImageList, nStartX + nRunX, nRunY);
-                if (clrColor == clrMask)
+                if (GetPixel32 (hdcImageList, nStartX + nRunX, nRunY) ==
+                    clrMask)
                 {
                     SetPixel32 (hdcImageList, nStartX + nRunX, nRunY,
                                 RGB(0, 0, 0));
@@ -316,8 +301,11 @@
 /*************************************************************************
  *	 		 ImageList_BeginDrag   [COMCTL32.42]
  *
- * Creates a temporary imagelist with an image in it, which will be used
- * as a drag image.
+ *  Creates a temporary imagelist with an image in it, which will be used
+ *  as a drag image.
+ *
+ *  RETURNS
+ *    ...
  */
 
 BOOL32 WINAPI ImageList_BeginDrag (
@@ -377,6 +365,9 @@
  *  Copying from one imagelist to another is allowed, in contrary to
  *  M$'s original implementation. They just allow copying or swapping
  *  within one imagelist (himlDst and himlSrc must be the same).
+ *
+ *  RETURNS
+ *    ...
  */
 
 BOOL32 WINAPI ImageList_Copy (
@@ -491,7 +482,8 @@
  *  Creates an imagelist of the given image size and number of images.
  *
  *  RETURNS
- *    Handle of the created image list, 0 if an error occurred.
+ *    Handle of the created image list.
+ *    0 if an error occurred.
  */
 
 HIMAGELIST WINAPI ImageList_Create (
@@ -505,6 +497,13 @@
     HIMAGELIST himl;
     HDC32      hdc;
     INT32      nCount;
+    HBITMAP32  hbmTemp;
+    WORD       aBitBlend25[16] = 
+        {0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD,
+         0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD};
+    WORD       aBitBlend50[16] =
+        {0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA,
+         0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA};
 
     himl = (HIMAGELIST)LocalAlloc32 (LMEM_FIXED | LMEM_ZEROINIT,
                                      sizeof(struct _IMAGELIST));
@@ -553,6 +552,15 @@
     else
         himl->hbmMask = 0;
 
+    /* create blending brushes */
+    hbmTemp = CreateBitmap32 (16, 16, 1, 1, &aBitBlend25);
+    himl->hbrBlend25 = CreatePatternBrush32 (hbmTemp);
+    DeleteObject32 (hbmTemp);
+
+    hbmTemp = CreateBitmap32 (16, 16, 1, 1, &aBitBlend50);
+    himl->hbrBlend50 = CreatePatternBrush32 (hbmTemp);
+    DeleteObject32 (hbmTemp);
+
     return (himl);    
 }
 
@@ -563,7 +571,8 @@
  *  Destroy the given imagelist.
  *
  *  RETURNS
- *    TRUE if the image list was destryed, FALSE if an error occurred.
+ *    TRUE if the image list was destroyed.
+ *    FALSE if an error occurred.
  */
 
 BOOL32 WINAPI ImageList_Destroy (
@@ -614,7 +623,6 @@
     FIXME (imagelist, "empty stub!\n");
 
 
-
     SetCursor32 (hcurInternal);
     hcurInternal = 0;
  
@@ -727,23 +735,24 @@
 
 
 /*************************************************************************
- *	 		 ImageList_Drawindirect   [COMCTL32.52]
+ *	 		 ImageList_DrawIndirect   [COMCTL32.52]
  */
 
 BOOL32 WINAPI ImageList_DrawIndirect (
 	IMAGELISTDRAWPARAMS *pimldp)
 {
     HIMAGELIST himlLocal;
-    HDC32      hdcImageList,hdcMask, hdcTempImage;
-    HBITMAP32  hbmMask, hbmTempImage;
+    HDC32      hdcImageList, hdcTempImage;
+    HBITMAP32  hbmTempImage;
     HBRUSH32   hBrush, hOldBrush;
-    INT32      nOvlIdx, nStartX, nRunX, nRunY;
-    COLORREF   clrBlend, clrImage;
+    INT32      nOvlIdx;
+    COLORREF   clrBlend;
     BOOL32     bImage;       /* draw image ? */
     BOOL32     bImageTrans;  /* draw image transparent ? */
     BOOL32     bMask;        /* draw mask ? */
     BOOL32     bMaskTrans;   /* draw mask transparent ? */
-    BOOL32     bBlend = FALSE;
+    BOOL32     bBlend25;
+    BOOL32     bBlend50;
 
     if (pimldp == NULL) return (FALSE);
     if (pimldp->cbSize < sizeof(IMAGELISTDRAWPARAMS)) return (FALSE);
@@ -755,6 +764,8 @@
     bImageTrans = FALSE;
     bMask       = FALSE;
     bMaskTrans  = FALSE;
+    bBlend25    = FALSE;
+    bBlend50    = FALSE;
     if ((himlLocal->clrBk == CLR_NONE) && (himlLocal->hbmMask))
     {
         bImageTrans = TRUE;
@@ -778,90 +789,92 @@
         bImage = FALSE;
     }
     if ((pimldp->fStyle & ILD_TRANSPARENT) && (himlLocal->hbmMask))
+    {
         bMaskTrans = TRUE;
+        bImageTrans = TRUE;
+    }
     if ((himlLocal->clrBk == CLR_NONE) && (himlLocal->hbmMask))
         bMaskTrans = TRUE;
 
-
-    if ((pimldp->fStyle & ILD_BLEND25) || (pimldp->fStyle & ILD_BLEND50))
-        bBlend = TRUE;
+    if (pimldp->fStyle & ILD_BLEND50)
+        bBlend50 = TRUE;
+    else if (pimldp->fStyle & ILD_BLEND25)
+        bBlend25 = TRUE;
 
     hdcImageList = CreateCompatibleDC32 (0);
 
-
     if (bMask)
     {
         /* draw the mask */
         SelectObject32 (hdcImageList, himlLocal->hbmMask);
         
-        BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y, pimldp->himl->cx,
-                  pimldp->himl->cy, hdcImageList,
-                  pimldp->himl->cx * pimldp->i, 0,
+        BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y,
+                  himlLocal->cx, himlLocal->cy, hdcImageList,
+                  himlLocal->cx * pimldp->i, 0,
                   bMaskTrans ? SRCAND : SRCCOPY);
     }
+
     if (bImage)
     {
         /* draw the image */
         SelectObject32 (hdcImageList, himlLocal->hbmImage);
-        if (!bBlend)
+
+        if (!bImageTrans)
         {
-            if (!bImageTrans)
-            {
-                hBrush = CreateSolidBrush32 (himlLocal->clrBk);
-                hOldBrush = SelectObject32 (pimldp->hdcDst, hBrush);
-                PatBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y,
-                          himlLocal->cx, himlLocal->cy, PATCOPY);
-                DeleteObject32 (SelectObject32 (pimldp->hdcDst, hOldBrush));
-            }
-            BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y, himlLocal->cx,
-                      himlLocal->cy, hdcImageList, himlLocal->cx * pimldp->i, 0,
-                      SRCPAINT);
+            hBrush = CreateSolidBrush32 (himlLocal->clrBk);
+            hOldBrush = SelectObject32 (pimldp->hdcDst, hBrush);
+            PatBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y,
+                      himlLocal->cx, himlLocal->cy, PATCOPY);
+            DeleteObject32 (SelectObject32 (pimldp->hdcDst, hOldBrush));
         }
-        else
+
+        BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y, himlLocal->cx,
+                  himlLocal->cy, hdcImageList, himlLocal->cx * pimldp->i, 0,
+                  SRCPAINT);
+
+        if (bBlend25 || bBlend50)
         {
             if (pimldp->rgbFg == CLR_DEFAULT)
-                clrBlend = (GetSysColor32 (COLOR_HIGHLIGHT) & 0xFEFEFEFE)>>1;
+                clrBlend = GetSysColor32 (COLOR_HIGHLIGHT);
             else
-                clrBlend = (pimldp->rgbFg & 0xFEFEFEFE)>>1;
+                clrBlend = pimldp->rgbFg;
 
             hdcTempImage = CreateCompatibleDC32 (0);
             hbmTempImage = CreateBitmap32 (himlLocal->cx, himlLocal->cy,
                                            1, himlLocal->uBitsPixel, NULL);
             SelectObject32 (hdcTempImage, hbmTempImage);
-            PatBlt32 (hdcTempImage, 0, 0, himlLocal->cx, himlLocal->cy, BLACKNESS);
 
-#if 0
-            if (bImageTrans)
-            {
-#endif
-                hdcMask = CreateCompatibleDC32 (0);           
-                SelectObject32 (hdcMask, himlLocal->hbmMask);
-                nStartX = pimldp->i * himlLocal->cx;
 
-                for (nRunY = 0; nRunY < himlLocal->cy; nRunY++)
-                {
-                    for (nRunX = 0; nRunX < himlLocal->cx; nRunX++)
-                    {
-                        if (GetPixel32 (hdcMask, nStartX + nRunX, nRunY) == 0)
-                        {
-                            clrImage = GetPixel32 (hdcImageList, nStartX + nRunX, nRunY);
-                            clrImage = ((clrImage & 0xFEFEFEFE)>>1) + clrBlend;
+            /* mask */
+            SelectObject32 (hdcTempImage,
+                            bBlend50 ? himlLocal->hbrBlend50 : himlLocal->hbrBlend25);
+            PatBlt32 (hdcTempImage, 0, 0, himlLocal->cx, himlLocal->cy, PATCOPY);
 
-                            SetPixel32 (hdcTempImage, nRunX, nRunY, clrImage);
-                        }
-                    }
-                }
+            SelectObject32 (hdcImageList, himlLocal->hbmMask);
+            BitBlt32 (hdcTempImage, 0, 0, himlLocal->cx,
+                      himlLocal->cy, hdcImageList, 
+                      pimldp->i * himlLocal->cx, 0, SRCPAINT);
 
-                DeleteDC32 (hdcMask);
-                BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y, himlLocal->cx,
-                          himlLocal->cy, hdcTempImage, 0, 0, SRCPAINT);
-#if 0
-            }
-            else
-            {
+            BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y, himlLocal->cx,
+                      himlLocal->cy, hdcTempImage, 0, 0, SRCAND);
 
-            }
-#endif
+            /* fill */
+            hBrush = CreateSolidBrush32 (clrBlend);
+            SelectObject32 (hdcTempImage, hBrush);
+            PatBlt32 (hdcTempImage, 0, 0, himlLocal->cx, himlLocal->cy, PATCOPY);
+            DeleteObject32 (hBrush);
+
+            SelectObject32 (hdcTempImage,
+                            bBlend50 ? himlLocal->hbrBlend50 : himlLocal->hbrBlend25);
+            PatBlt32 (hdcTempImage, 0, 0, himlLocal->cx, himlLocal->cy, 0x0A0329);
+
+            SelectObject32 (hdcImageList, himlLocal->hbmMask);
+            BitBlt32 (hdcTempImage, 0, 0, himlLocal->cx,
+                      himlLocal->cy, hdcImageList, 
+                      pimldp->i * himlLocal->cx, 0, SRCPAINT);
+
+            BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y, himlLocal->cx,
+                      himlLocal->cy, hdcTempImage, 0, 0, SRCPAINT);
 
             DeleteObject32 (hbmTempImage);
             DeleteDC32 (hdcTempImage);
@@ -946,6 +959,15 @@
 }
 
 
+/*************************************************************************
+ *	 		 ImageList_EndDrag   [COMCTL32.54]
+ *
+ *  Finishes a drag operation.
+ *
+ *  FIXME
+ *    semi-stub.
+ */
+
 BOOL32 WINAPI ImageList_EndDrag (VOID)
 {
     FIXME (imagelist, "partially implemented!\n");
@@ -965,6 +987,15 @@
 }
 
 
+/*************************************************************************
+ *	 		 ImageList_GetBkColor   [COMCTL32.55]
+ *
+ *  Returns the background color of an image list.
+ *
+ *  RETURNS
+ *    Background color.
+ */
+
 COLORREF WINAPI ImageList_GetBkColor (
 	HIMAGELIST himl)
 {
@@ -972,6 +1003,15 @@
 }
 
 
+/*************************************************************************
+ *	 		 ImageList_GetDragImage   [COMCTL32.56]
+ *
+ *  Returns the handle to the internal drag image list.
+ *
+ *  FIXME
+ *    semi-stub.
+ */
+
 HIMAGELIST WINAPI ImageList_GetDragImage (
 	POINT32 *ppt,
 	POINT32 *pptHotspot)
@@ -985,6 +1025,10 @@
 }
 
 
+/*************************************************************************
+ *	 		 ImageList_GetIcon   [COMCTL32.57]
+ */
+
 HICON32 WINAPI ImageList_GetIcon (
 	HIMAGELIST himl, 
 	INT32 i, 
@@ -1002,8 +1046,7 @@
     ii.xHotspot = 0;
     ii.yHotspot = 0;
     ii.hbmMask  = CreateBitmap32 (nWidth, nHeight, 1, 1, NULL);
-    ii.hbmColor = CreateBitmap32 (nWidth, nHeight,
-                                  1, 1, NULL);
+    ii.hbmColor = CreateBitmap32 (nWidth, nHeight, 1, 1, NULL);
 
     hdc = CreateCompatibleDC32(0);
 
@@ -1027,6 +1070,10 @@
 }
 
 
+/*************************************************************************
+ *	 		 ImageList_GetIconSize   [COMCTL32.58]
+ */
+
 BOOL32 WINAPI ImageList_GetIconSize (
 	HIMAGELIST himl,
 	INT32 *cx,
@@ -1044,6 +1091,10 @@
 }
 
 
+/*************************************************************************
+ *	 		 ImageList_GetIconCount   [COMCTL32.59]
+ */
+
 INT32 WINAPI ImageList_GetImageCount (
 	HIMAGELIST himl)
 {
@@ -1051,6 +1102,10 @@
 }
 
 
+/*************************************************************************
+ *	 		 ImageList_GetImageInfo   [COMCTL32.60]
+ */
+
 BOOL32 WINAPI ImageList_GetImageInfo (
 	HIMAGELIST himl,
 	INT32 i,
@@ -1070,7 +1125,12 @@
 }
 
 
-/* I don't know if it is really a BOOL32 or something else!!!?? */
+/*************************************************************************
+ *	 		 ImageList_GetImageRect   [COMCTL32.61]
+ *
+ *  COMMENTS
+ *    I don't know if it really returns a BOOL32 or something else!!!??
+ */
 
 BOOL32 WINAPI ImageList_GetImageRect (
 	HIMAGELIST himl,
@@ -1090,6 +1150,10 @@
 }
 
 
+/*************************************************************************
+ *	 		 ImageList_LoadImage32A   [COMCTL32.63]
+ */
+
 HIMAGELIST WINAPI ImageList_LoadImage32A (
 	HINSTANCE32 hi,
 	LPCSTR lpbmp,
@@ -1152,6 +1216,10 @@
 }
 
 
+/*************************************************************************
+ *	 		 ImageList_LoadImage32W   [COMCTL32.64]
+ */
+
 HIMAGELIST WINAPI ImageList_LoadImage32W (
 	HINSTANCE32 hi,
 	LPCWSTR lpbmp,
@@ -1217,6 +1285,10 @@
 }
 
 
+/*************************************************************************
+ *	 		 ImageList_Merge   [COMCTL32.65]
+ */
+
 HIMAGELIST WINAPI ImageList_Merge (
 	HIMAGELIST himl1,
 	INT32 i1,
@@ -1234,7 +1306,15 @@
     if ((himl1 == NULL) || (himl2 == NULL)) return (NULL);
 
     /* check indices */
+    if ((i1 < 0) || (i1 >= himl1->cCurImage)) {
+        ERR (imagelist, "Index 1 out of range! %d\n", i1);
+        return (NULL);
+    }
 
+    if ((i2 < 0) || (i2 >= himl2->cCurImage)) {
+        ERR (imagelist, "Index 2 out of range! %d\n", i2);
+        return (NULL);
+    }
 
     if (xOffs > 0) {
         cxDst = _MAX (himl1->cx, xOffs + himl2->cx);
@@ -1435,9 +1515,6 @@
 
         himl->cCurImage--;
         himl->cMaxImage = himl->cCurImage + himl->cGrow;
-
-        TRACE (imagelist, "Number of images: %d\n", himl->cCurImage);
-        TRACE (imagelist, "Max. number of images: %d\n", himl->cMaxImage);
     }
 
     return (TRUE);
@@ -1507,6 +1584,7 @@
     BITMAP32 bmp;
 #endif
 
+    if (himl == NULL) return (-1);
     if ((i >= himl->cCurImage) || (i < -1)) return (-1);
 
 #ifdef __GET_ICON_INFO_HACK__
@@ -1525,8 +1603,9 @@
     if (i == -1) {
         if (himl->cCurImage + 1 >= himl->cMaxImage)
             IMAGELIST_InternalGrowBitmaps (himl, 1);
+
         nIndex = himl->cCurImage;
-        himl->cCurImage ++;
+        himl->cCurImage++;
     }
     else
         nIndex = i;
@@ -1645,24 +1724,25 @@
 {
     HDC32     hdcImageList, hdcBitmap;
     HBITMAP32 hbmNewBitmap;
-    INT32     nNewWidth;
+    INT32     nNewCount, nCopyCount;
 
     if (himl == NULL) return (FALSE);
     if (himl->cCurImage <= iImageCount) return (FALSE);
     if (himl->cMaxImage > iImageCount) return (TRUE);
 
-    nNewWidth = (iImageCount + himl->cGrow) * himl->cx;
+    nNewCount = iImageCount + himl->cGrow;
+    nCopyCount = _MIN(himl->cCurImage, iImageCount);
 
     hdcImageList = CreateCompatibleDC32 (0);
     hdcBitmap = CreateCompatibleDC32 (0);
 
-    hbmNewBitmap =
-        CreateBitmap32 (nNewWidth, himl->cy, 1, himl->uBitsPixel, NULL);
+    hbmNewBitmap = CreateBitmap32 (nNewCount * himl->cx, himl->cy,
+                                   1, himl->uBitsPixel, NULL);
     if (hbmNewBitmap == 0)
     {
         SelectObject32 (hdcImageList, himl->hbmImage);
         SelectObject32 (hdcBitmap, hbmNewBitmap);
-        BitBlt32 (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, himl->cy,
+        BitBlt32 (hdcBitmap, 0, 0, nCopyCount * himl->cx, himl->cy,
                   hdcImageList, 0, 0, SRCCOPY);
         DeleteObject32 (himl->hbmImage);
         himl->hbmImage = hbmNewBitmap;
@@ -1674,14 +1754,13 @@
 
     if (himl->hbmMask)
     {
-        hbmNewBitmap = 
-            CreateBitmap32 (nNewWidth, himl->cy, 1, 1, NULL);
-
+        hbmNewBitmap = CreateBitmap32 (nNewCount * himl->cx, himl->cy,
+                                       1, 1, NULL);
         if (hbmNewBitmap != 0)
         {
             SelectObject32 (hdcImageList, himl->hbmMask);
             SelectObject32 (hdcBitmap, hbmNewBitmap);
-            BitBlt32 (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, himl->cy,
+            BitBlt32 (hdcBitmap, 0, 0, nCopyCount * himl->cx, himl->cy,
                       hdcImageList, 0, 0, SRCCOPY);
             DeleteObject32 (himl->hbmMask);
             himl->hbmMask = hbmNewBitmap;
@@ -1695,8 +1774,10 @@
     DeleteDC32 (hdcImageList);
     DeleteDC32 (hdcBitmap);
 
-    /* Update max image count */
-    himl->cMaxImage = iImageCount + himl->cx;
+    /* Update max image count and current image count */
+    himl->cMaxImage = nNewCount;
+    if (himl->cCurImage > nCopyCount)
+        himl->cCurImage = nCopyCount;
 
     return (TRUE);
 }
diff --git a/misc/lstr.c b/misc/lstr.c
index ff3576a..05b7fb3 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -5,12 +5,13 @@
  * Copyright 1996 Marcus Meissner
  */
 
+#include "config.h"
+
 #include <stdio.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
-#include "config.h"
 
 #ifdef HAVE_WCTYPE_H
 # include <wctype.h>
@@ -187,7 +188,7 @@
 
 
 /***********************************************************************
- *           CharNext32A   (USER32.28)
+ *           CharNext32A   (USER32.29)
  */
 LPSTR WINAPI CharNext32A( LPCSTR ptr )
 {
@@ -198,7 +199,7 @@
 
 
 /***********************************************************************
- *           CharNextEx32A   (USER32.29)
+ *           CharNextEx32A   (USER32.30)
  */
 LPSTR WINAPI CharNextEx32A( WORD codepage, LPCSTR ptr, DWORD flags )
 {
@@ -209,7 +210,7 @@
 
 
 /***********************************************************************
- *           CharNextExW   (USER32.30)
+ *           CharNextExW   (USER32.31)
  */
 LPWSTR WINAPI CharNextEx32W(WORD codepage,LPCWSTR x,DWORD flags)
 {
@@ -219,7 +220,7 @@
 }
 
 /***********************************************************************
- *           CharNextW   (USER32.31)
+ *           CharNextW   (USER32.32)
  */
 LPWSTR WINAPI CharNext32W(LPCWSTR x)
 {
@@ -228,7 +229,7 @@
 }
 
 /***********************************************************************
- *           CharPrev32A   (USER32.32)
+ *           CharPrev32A   (USER32.33)
  */
 LPSTR WINAPI CharPrev32A( LPCSTR start, LPCSTR ptr )
 {
@@ -243,7 +244,7 @@
 
 
 /***********************************************************************
- *           CharPrevEx32A   (USER32.33)
+ *           CharPrevEx32A   (USER32.34)
  */
 LPSTR WINAPI CharPrevEx32A( WORD codepage, LPCSTR start, LPCSTR ptr, DWORD flags )
 {
@@ -258,7 +259,7 @@
 
 
 /***********************************************************************
- *           CharPrevExW   (USER32.34)
+ *           CharPrevExW   (USER32.35)
  */
 LPWSTR WINAPI CharPrevEx32W(WORD codepage,LPCWSTR start,LPCWSTR x,DWORD flags)
 {
@@ -268,7 +269,7 @@
 }
 
 /***********************************************************************
- *           CharPrevW   (USER32.35)
+ *           CharPrevW   (USER32.36)
  */
 LPWSTR WINAPI CharPrev32W(LPCWSTR start,LPCWSTR x)
 {
@@ -277,7 +278,7 @@
 }
 
 /***********************************************************************
- *           CharLowerA   (USER32.24)
+ *           CharLowerA   (USER32.25)
  * FIXME: handle current locale
  */
 LPSTR WINAPI CharLower32A(LPSTR x)
@@ -298,7 +299,7 @@
 }
 
 /***********************************************************************
- *           CharLowerBuffA   (USER32.25)
+ *           CharLowerBuffA   (USER32.26)
  * FIXME: handle current locale
  */
 DWORD WINAPI CharLowerBuff32A(LPSTR x,DWORD buflen)
@@ -316,7 +317,7 @@
 }
 
 /***********************************************************************
- *           CharLowerBuffW   (USER32.26)
+ *           CharLowerBuffW   (USER32.27)
  * FIXME: handle current locale
  */
 DWORD WINAPI CharLowerBuff32W(LPWSTR x,DWORD buflen)
@@ -334,7 +335,7 @@
 }
 
 /***********************************************************************
- *           CharLowerW   (USER32.27)
+ *           CharLowerW   (USER32.28)
  * FIXME: handle current locale
  */
 LPWSTR WINAPI CharLower32W(LPWSTR x)
@@ -353,7 +354,7 @@
 }
 
 /***********************************************************************
- *           CharUpper32A   (USER32.40)
+ *           CharUpper32A   (USER32.41)
  * FIXME: handle current locale
  */
 LPSTR WINAPI CharUpper32A(LPSTR x)
@@ -372,7 +373,7 @@
 }
 
 /***********************************************************************
- *           CharUpperBuffA   (USER32.41)
+ *           CharUpperBuffA   (USER32.42)
  * FIXME: handle current locale
  */
 DWORD WINAPI CharUpperBuff32A(LPSTR x,DWORD buflen)
@@ -390,7 +391,7 @@
 }
 
 /***********************************************************************
- *           CharUpperBuffW   (USER32.42)
+ *           CharUpperBuffW   (USER32.43)
  * FIXME: handle current locale
  */
 DWORD WINAPI CharUpperBuff32W(LPWSTR x,DWORD buflen)
@@ -408,7 +409,7 @@
 }
 
 /***********************************************************************
- *           CharUpperW   (USER32.43)
+ *           CharUpperW   (USER32.44)
  * FIXME: handle current locale
  */
 LPWSTR WINAPI CharUpper32W(LPWSTR x)
@@ -427,7 +428,7 @@
 }
 
 /***********************************************************************
- *           IsCharAlphaA   (USER32.330)
+ *           IsCharAlphaA   (USER32.331)
  * FIXME: handle current locale
  */
 BOOL32 WINAPI IsCharAlpha32A(CHAR x)
@@ -436,7 +437,7 @@
 }
 
 /***********************************************************************
- *           IsCharAlphaNumericA   (USER32.331)
+ *           IsCharAlphaNumericA   (USER32.332)
  * FIXME: handle current locale
  */
 BOOL32 WINAPI IsCharAlphaNumeric32A(CHAR x)
@@ -445,7 +446,7 @@
 }
 
 /***********************************************************************
- *           IsCharAlphaNumericW   (USER32.332)
+ *           IsCharAlphaNumericW   (USER32.333)
  * FIXME: handle current locale
  */
 BOOL32 WINAPI IsCharAlphaNumeric32W(WCHAR x)
@@ -454,7 +455,7 @@
 }
 
 /***********************************************************************
- *           IsCharAlphaW   (USER32.333)
+ *           IsCharAlphaW   (USER32.334)
  * FIXME: handle current locale
  */
 BOOL32 WINAPI IsCharAlpha32W(WCHAR x)
@@ -463,7 +464,7 @@
 }
 
 /***********************************************************************
- *           IsCharLower32A   (USER32.334)
+ *           IsCharLower32A   (USER32.335)
  * FIXME: handle current locale
  */
 BOOL32 WINAPI IsCharLower32A(CHAR x)
@@ -472,7 +473,7 @@
 }
 
 /***********************************************************************
- *           IsCharLower32W   (USER32.335)
+ *           IsCharLower32W   (USER32.336)
  * FIXME: handle current locale
  */
 BOOL32 WINAPI IsCharLower32W(WCHAR x)
@@ -481,7 +482,7 @@
 }
 
 /***********************************************************************
- *           IsCharUpper32A   (USER32.336)
+ *           IsCharUpper32A   (USER32.337)
  * FIXME: handle current locale
  */
 BOOL32 WINAPI IsCharUpper32A(CHAR x)
@@ -490,7 +491,7 @@
 }
 
 /***********************************************************************
- *           IsCharUpper32W   (USER32.337)
+ *           IsCharUpper32W   (USER32.338)
  * FIXME: handle current locale
  */
 BOOL32 WINAPI IsCharUpper32W(WCHAR x)
@@ -610,7 +611,7 @@
 							sprintfbuf=HeapAlloc(GetProcessHeap(),0,100);
 
 						/* CMF - This makes a BIG assumption about va_list */
-						vsprintf(sprintfbuf, fmtstr, (va_list) argliststart);
+						wvsprintf32A(sprintfbuf, fmtstr, (va_list) argliststart);
 						x=sprintfbuf;
 						while (*x) {
 							ADD_TO_T(*x++);
@@ -620,7 +621,7 @@
 						/* NULL args - copy formatstr 
 						 * (probably wrong)
 						 */
-						while (lastf<f) {
+						while ((lastf<f)&&(*lastf)) {
 							ADD_TO_T(*lastf++);
 						}
 					}
@@ -787,7 +788,7 @@
 						sprintfbuf=HeapAlloc(GetProcessHeap(),0,100);
 
 						/* CMF - This makes a BIG assumption about va_list */
-						vsprintf(sprintfbuf, fmtstr, (va_list) argliststart);
+						wvsprintf32A(sprintfbuf, fmtstr, (va_list) argliststart);
 					}
 					x=sprintfbuf;
 					while (*x) {
diff --git a/misc/main.c b/misc/main.c
index 292a4d0..1d843ec 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -626,7 +626,7 @@
 
 
 /***********************************************************************
- *           MessageBeep32   (USER32.389)
+ *           MessageBeep32   (USER32.390)
  */
 BOOL32 WINAPI MessageBeep32( UINT32 i )
 {
@@ -655,7 +655,7 @@
 }
 
 /***********************************************************************
- *	SystemParametersInfo32A   (USER32.539)
+ *	SystemParametersInfo32A   (USER32.540)
  */
 BOOL32 WINAPI SystemParametersInfo32A( UINT32 uAction, UINT32 uParam,
                                        LPVOID lpvParam, UINT32 fuWinIni )
@@ -999,7 +999,7 @@
 }
 
 /***********************************************************************
- *	SystemParametersInfo32W   (USER32.540)
+ *	SystemParametersInfo32W   (USER32.541)
  */
 BOOL32 WINAPI SystemParametersInfo32W( UINT32 uAction, UINT32 uParam,
                                        LPVOID lpvParam, UINT32 fuWinIni )
diff --git a/misc/mpr.c b/misc/mpr.c
index e5cf26e..dce6dc1 100644
--- a/misc/mpr.c
+++ b/misc/mpr.c
@@ -6,23 +6,66 @@
 #include <stdio.h>
 #include "win.h"
 #include "debug.h"
+#include "wnet.h"
 
+
+/**************************************************************************
+ * WNetCachePassword [MPR.52]  Saves password in cache
+ *
+ * RETURNS
+ *    Success: WN_SUCCESS
+ *    Failure: WNACCESS_DENIED, WN_BAD_PASSWORD, WN_BADVALUE, WN_NET_ERROR,
+ *             WN_NOT_SUPPORTED, WN_OUT_OF_MEMORY
+ */
+DWORD WINAPI WNetCachePassword(
+    LPSTR pbResource, /* [in] Name of workgroup, computer, or resource */
+    WORD cbResource,  /* [in] Size of name */
+    LPSTR pbPassword, /* [in] Buffer containing password */
+    WORD cbPassword,  /* [in] Size of password */
+    BYTE nType)       /* [in] Type of password to cache */
+{
+    FIXME(mpr,"(%s,%d,%s,%d,%d): stub\n", pbResource,cbResource,
+          pbPassword,cbPassword,nType);
+    return WN_SUCCESS;
+}
+
+
+/**************************************************************************
+ * WNetGetCachedPassword [MPR.???]  Retrieves password from cache
+ *
+ * RETURNS
+ *    Success: WN_SUCCESS
+ *    Failure: WNACCESS_DENIED, WN_BAD_PASSWORD, WN_BAD_VALUE, WN_NET_ERROR,
+ *             WN_NOT_SUPPORTED, WN_OUT_OF_MEMORY
+ */
 DWORD WINAPI WNetGetCachedPassword(
-	LPSTR	pbResource,
-	WORD	cbResource,
-	LPSTR	pbPassword,
-	LPWORD	pcbPassword,
-	BYTE	nType
-) {
-	FIXME(mpr,"(%s,%d,%p,%d,%d): stub\n",
-		pbResource,cbResource,pbPassword,*pcbPassword,nType);
-	return 0;
+    LPSTR pbResource,   /* [in]  Name of workgroup, computer, or resource */
+    WORD cbResource,    /* [in]  Size of name */
+    LPSTR pbPassword,   /* [out] Buffer to receive password */
+    LPWORD pcbPassword, /* [out] Receives size of password */
+    BYTE nType)         /* [in]  Type of password to retrieve */
+{
+    FIXME(mpr,"(%s,%d,%p,%d,%d): stub\n",
+          pbResource,cbResource,pbPassword,*pcbPassword,nType);
+    return WN_ACCESS_DENIED;
 }
 
+
+/**************************************************************************
+ * MultinetGetConnectionPerformance32A [MPR.???]
+ *
+ * RETURNS
+ *    Success: NO_ERROR
+ *    Failure: ERROR_NOT_SUPPORTED, ERROR_NOT_CONNECTED,
+ *             ERROR_NO_NET_OR_BAD_PATH, ERROR_BAD_DEVICE,
+ *             ERROR_BAD_NET_NAME, ERROR_INVALID_PARAMETER, 
+ *             ERROR_NO_NETWORK, ERROR_EXTENDED_ERROR
+ */
 DWORD WINAPI MultinetGetConnectionPerformance32A(
-	LPNETRESOURCE32A lpNetResource,
-	LPNETCONNECTINFOSTRUCT lpNetConnectInfoStruct
-) {
-	FIXME(mpr,"(%p,%p): stub\n",lpNetResource,lpNetConnectInfoStruct);
-	return 1;
+    LPNETRESOURCE32A lpNetResource,                /* [in] Specifies resource */
+    LPNETCONNECTINFOSTRUCT lpNetConnectInfoStruct) /* [in] Pointer to struct */
+{
+    FIXME(mpr,"(%p,%p): stub\n",lpNetResource,lpNetConnectInfoStruct);
+    return WN_NOT_SUPPORTED;
 }
+
diff --git a/misc/registry.c b/misc/registry.c
index 3f7ac03..b73c7f5 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -199,9 +199,6 @@
 	case HKEY_CURRENT_CONFIG:
 		return key_current_config;
 	default:
-		WARN(reg, "(%lx), special key!\n",
-			(LONG)hkey
-		);
 		return get_handle(hkey);
 	}
 	/*NOTREACHED*/
diff --git a/misc/shell.c b/misc/shell.c
index 545ecdc..ecea14d 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -620,7 +620,7 @@
 
 		    if( pstr )
 		    {
-			HCURSOR16 hCursor = LoadCursor16( 0, MAKEINTRESOURCE(OCR_DRAGOBJECT) );
+			HCURSOR16 hCursor = LoadCursor16( 0, MAKEINTRESOURCE16(OCR_DRAGOBJECT) );
 			SendMessage32A( hWndCtl, LB_GETTEXT32, (WPARAM32)idx, (LPARAM)pstr );
 			SendMessage32A( hWndCtl, LB_DELETESTRING32, (WPARAM32)idx, 0 );
 			UpdateWindow32( hWndCtl );
@@ -729,7 +729,7 @@
     info.szApp        = szApp;
     info.szOtherStuff = szOtherStuff;
     info.hIcon        = hIcon;
-    if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE(OIC_WINEICON) );
+    if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) );
     return DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd ),
                          SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX ),
                                       hWnd, AboutDlgProc32, (LPARAM)&info );
@@ -748,7 +748,7 @@
     info.szApp        = HEAP_strdupWtoA( GetProcessHeap(), 0, szApp );
     info.szOtherStuff = HEAP_strdupWtoA( GetProcessHeap(), 0, szOtherStuff );
     info.hIcon        = hIcon;
-    if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE(OIC_WINEICON) );
+    if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) );
     ret = DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd ),
                          SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX ),
                                       hWnd, AboutDlgProc32, (LPARAM)&info );
@@ -1074,7 +1074,8 @@
 		_lclose32( hFile);
 		return 0;
 	}
-	icongroupresdir = GetResDirEntryW(rootresdir,(LPWSTR)RT_GROUP_ICON,(DWORD)rootresdir,FALSE);
+	icongroupresdir = GetResDirEntryW(rootresdir,RT_GROUP_ICON32W,
+                                          (DWORD)rootresdir,FALSE);
 	if (!icongroupresdir) {
 		WARN(reg,"No Icongroupresourcedirectory!\n");
 		UnmapViewOfFile(peimage);
@@ -1143,7 +1144,8 @@
 		cids[i] = cid;
 		RetPtr[i] = LookupIconIdFromDirectoryEx32(igdata,TRUE,SYSMETRICS_CXICON,SYSMETRICS_CYICON,0);
 	}
-	iconresdir=GetResDirEntryW(rootresdir,(LPWSTR)RT_ICON,(DWORD)rootresdir,FALSE);
+	iconresdir=GetResDirEntryW(rootresdir,RT_ICON32W,
+                                   (DWORD)rootresdir,FALSE);
 	if (!iconresdir) {
 	    WARN(reg,"No Iconresourcedirectory!\n");
 	    UnmapViewOfFile(peimage);
@@ -1270,7 +1272,7 @@
 	    *lpiIcon = 6;   /* generic icon - found nothing */
 
 	GetModuleFileName16(hInst, lpIconPath, 0x80);
-	hIcon = LoadIcon16( hInst, MAKEINTRESOURCE(*lpiIcon));
+	hIcon = LoadIcon16( hInst, MAKEINTRESOURCE16(*lpiIcon));
     }
 
     return hIcon;
diff --git a/misc/version.c b/misc/version.c
index 77c7986..2b125e2 100644
--- a/misc/version.c
+++ b/misc/version.c
@@ -133,6 +133,7 @@
         /* Win3.10 */
         if (peheader->OptionalHeader.MinorSubsystemVersion <= 11) return WIN31;
         /* NT 3.51 */
+        if (peheader->OptionalHeader.MinorSubsystemVersion == 50) return NT351;
         if (peheader->OptionalHeader.MinorSubsystemVersion == 51) return NT351;
     }
     ERR(ver,"unknown subsystem version: %04x.%04x, please report.\n",
diff --git a/misc/winsock.c b/misc/winsock.c
index 9f9fdcf..79a7a10 100644
--- a/misc/winsock.c
+++ b/misc/winsock.c
@@ -10,21 +10,30 @@
  *
  */
  
+#include "config.h"
+
 #include <stdio.h>
 #include <string.h>
 #include <signal.h>
 #include <sys/types.h>
 #include <sys/ipc.h>
 #include <sys/ioctl.h>
+#ifdef HAVE_SYS_FILIO_H
+# include <sys/filio.h>
+#endif
 #if defined(__svr4__)
-#include <sys/filio.h>
 #include <sys/ioccom.h>
 #include <sys/sockio.h>
 #endif
+
 #if defined(__EMX__)
-#include <sys/so_ioctl.h>
-#include <sys/param.h>
+# include <sys/so_ioctl.h>
 #endif
+
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+
 #include <sys/msg.h>
 #include <sys/wait.h>
 #include <sys/socket.h>
@@ -1227,7 +1236,16 @@
 			  (unsigned)pwsi, s, level, optname, (int) optval, optlen);
     if( _check_ws(pwsi, pws) )
     {
+	struct	linger linger;
+
 	convert_sockopt(&level, &optname);
+	if (optname == SO_LINGER) {
+		/* yes, uses unsigned short in both win16/win32 */
+		linger.l_onoff	= ((UINT16*)optval)[0];
+		linger.l_linger	= ((UINT16*)optval)[1];
+		optval = (char*)&linger;
+		optlen = sizeof(struct linger);
+	}
 	if (setsockopt(pws->fd, level, optname, optval, optlen) == 0) return 0;
 	pwsi->err = wsaErrno();
     }
@@ -1241,16 +1259,7 @@
 INT16 WINAPI WINSOCK_setsockopt16(SOCKET16 s, INT16 level, INT16 optname,
                                   char *optval, INT16 optlen)
 {
-    INT32 linger32[2];
     if( !optval ) return SOCKET_ERROR;
-    if( optname == SO_LINGER )
-    {
-	INT16* ptr = (INT16*)optval;
-	linger32[0] = ptr[0];
-	linger32[1] = ptr[1];
-	optval = (char*)&linger32;
-	optlen = sizeof(linger32);
-    }
     return (INT16)WINSOCK_setsockopt32( s, (UINT16)level, optname, optval, optlen );
 }
 
@@ -2668,5 +2677,3 @@
 		return WSAEOPNOTSUPP;
     }
 }
-
-
diff --git a/misc/winsock_dns.c b/misc/winsock_dns.c
index 8a42a79..d01b8f7 100644
--- a/misc/winsock_dns.c
+++ b/misc/winsock_dns.c
@@ -9,6 +9,8 @@
  *       Netscape 4.0).
  */
 
+#include "config.h"
+
 #include <unistd.h>
 #include <string.h>
 #include <signal.h>
@@ -19,12 +21,16 @@
 #include <sys/wait.h>
 #include <errno.h>
 #ifdef __EMX__
-#include <sys/so_ioctl.h>
-#include <sys/param.h>
+# include <sys/so_ioctl.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+# include <sys/filio.h>
 #endif
 #ifdef __svr4__
-#include <sys/file.h>
-#include <sys/filio.h>
+# include <sys/file.h>
 #endif
 
 extern int h_errno;
@@ -364,6 +370,9 @@
 	    }
 	    else
 	    {
+	    	extern BOOL32 THREAD_InitDone;
+
+	        THREAD_InitDone = FALSE;
 		/* child process */
 
 		close(async_ctl.ws_aop->fd[0]);  /* read endpoint */
diff --git a/misc/wsprintf.c b/misc/wsprintf.c
index fffa2e6..540dc4a 100644
--- a/misc/wsprintf.c
+++ b/misc/wsprintf.c
@@ -483,7 +483,7 @@
 
 
 /***********************************************************************
- *           wvsprintf32A   (USER32.586)
+ *           wvsprintf32A   (USER32.587)
  */
 INT32 WINAPI wvsprintf32A( LPSTR buffer, LPCSTR spec, va_list args )
 {
@@ -493,7 +493,7 @@
 
 
 /***********************************************************************
- *           wvsprintf32W   (USER32.587)
+ *           wvsprintf32W   (USER32.588)
  */
 INT32 WINAPI wvsprintf32W( LPWSTR buffer, LPCWSTR spec, va_list args )
 {
diff --git a/msdos/int21.c b/msdos/int21.c
index e226cc1..8a7c0a2 100644
--- a/msdos/int21.c
+++ b/msdos/int21.c
@@ -824,6 +824,38 @@
      }
 } 
 
+static BOOL32
+INT21_networkfunc (CONTEXT *context)
+{
+     switch (AL_reg(context)) {
+     case 0x00: /* Get machine name. */
+     {
+	  char *dst = PTR_SEG_OFF_TO_LIN (DS_reg(context),DX_reg(context));
+	  TRACE(int21, "getting machine name to %p\n", dst);
+	  if (gethostname (dst, 15))
+	  {
+	       WARN(int21,"failed!\n");
+	       DOS_ERROR( ER_NoNetwork, EC_NotFound, SA_Abort, EL_Network );
+	       return TRUE;
+	  } else {
+	       int len = strlen (dst);
+	       while (len < 15)
+		    dst[len++] = ' ';
+	       dst[15] = 0;
+	       CH_reg(context) = 1; /* Valid */
+	       CL_reg(context) = 1; /* NETbios number??? */
+	       TRACE(int21, "returning %s\n", debugstr_an (dst, 16));
+	       return FALSE;
+	  }
+     }
+
+     default:
+	  DOS_ERROR( ER_NoNetwork, EC_NotFound, SA_Abort, EL_Network );
+	  return TRUE;
+     }
+}
+
+
 SEGPTR INT21_GetListOfLists()
 {
 	static DOS_LISTOFLISTS *LOL;
@@ -891,13 +923,15 @@
 {
     BOOL32	bSetDOSExtendedError = FALSE;
 
-    /*    TRACE(int21, "AX=%04x BX=%04x CX=%04x DX=%04x "
-                 "SI=%04x DI=%04x DS=%04x ES=%04x EFL=%08lx\n",
-                 AX_reg(context), BX_reg(context), CX_reg(context),
-                 DX_reg(context), SI_reg(context), DI_reg(context),
-                 (WORD)DS_reg(context), (WORD)ES_reg(context),
-                 EFL_reg(context) );
-		 */
+#if 0
+    TRACE(int21, "AX=%04x BX=%04x CX=%04x DX=%04x "
+	  "SI=%04x DI=%04x DS=%04x ES=%04x EFL=%08lx\n",
+	  AX_reg(context), BX_reg(context), CX_reg(context), DX_reg(context),
+	  SI_reg(context), DI_reg(context),
+	  (WORD)DS_reg(context), (WORD)ES_reg(context),
+	  EFL_reg(context) );
+#endif
+
     if (AH_reg(context) == 0x59)  /* Get extended error info */
     {
         TRACE(int21, "GET EXTENDED ERROR code 0x%02x class 0x%02x action 0x%02x locus %02x\n",
@@ -1526,13 +1560,16 @@
         break;
 
     case 0x5d: /* NETWORK */
-    case 0x5e:
-        TRACE(int21,"Network function AX=%04x\n",AX_reg(context));
-        /* network software not installed */
+        FIXME(int21,"Function 0x%04x not implemented.\n", AX_reg (context));
+	/* Fix the following while you're at it.  */
         DOS_ERROR( ER_NoNetwork, EC_NotFound, SA_Abort, EL_Network );
 	bSetDOSExtendedError = TRUE;
         break;
 
+    case 0x5e:
+	bSetDOSExtendedError = INT21_networkfunc (context);
+        break;
+
     case 0x5f: /* NETWORK */
         switch (AL_reg(context))
         {
diff --git a/multimedia/audio.c b/multimedia/audio.c
index cd55ce8..780e035 100644
--- a/multimedia/audio.c
+++ b/multimedia/audio.c
@@ -28,11 +28,13 @@
 #include "debug.h"
 
 #ifdef HAVE_OSS
+
 #ifdef HAVE_MACHINE_SOUNDCARD_H
-#include <machine/soundcard.h>
-#else /* HAVE_MACHINE_SOUNDCARD_H */
-#include <sys/soundcard.h>
-#endif /* HAVE_MACHINE_SOUNDCARD_H */
+# include <machine/soundcard.h>
+#endif
+#ifdef HAVE_SYS_SOUNDCARD_H
+# include <sys/soundcard.h>
+#endif
 
 #define SOUND_DEV "/dev/dsp"
 #define MIXER_DEV "/dev/mixer"
diff --git a/multimedia/dsound.c b/multimedia/dsound.c
index 831dabf..c541d27 100644
--- a/multimedia/dsound.c
+++ b/multimedia/dsound.c
@@ -28,6 +28,7 @@
  *   Sound works for the intromovie.
  */
 
+#include "config.h"
 #include <stdio.h>
 #include <assert.h>
 #include <sys/types.h>
@@ -45,12 +46,13 @@
 #include "debug.h"
 
 #ifdef HAVE_OSS
-#include <sys/ioctl.h>
-#ifdef HAVE_MACHINE_SOUNDCARD_H
-#include <machine/soundcard.h>
-#else /* HAVE_MACHINE_SOUNDCARD_H */
-#include <sys/soundcard.h>
-#endif /* HAVE_MACHINE_SOUNDCARD_H */
+# include <sys/ioctl.h>
+# ifdef HAVE_MACHINE_SOUNDCARD_H
+#  include <machine/soundcard.h>
+# endif
+# ifdef HAVE_SYS_SOUNDCARD_H
+#  include <sys/soundcard.h>
+# endif
 
 static int audiofd = -1;
 static LPDIRECTSOUND	dsound = NULL;
@@ -845,7 +847,7 @@
 #endif /* HAVE_OSS */
 
 HRESULT WINAPI DirectSoundCreate(LPGUID lpGUID,LPDIRECTSOUND *ppDS,IUnknown *pUnkOuter ) {
-	int	xx;
+	int xx;
 	if (lpGUID)
 		fprintf(stderr,"DirectSoundCreate(%p,%p,%p)\n",lpGUID,ppDS,pUnkOuter);
 #ifdef HAVE_OSS
diff --git a/multimedia/init.c b/multimedia/init.c
index dc31efb..7e48550 100644
--- a/multimedia/init.c
+++ b/multimedia/init.c
@@ -13,7 +13,7 @@
 #include "xmalloc.h"
 #include "debug.h"
 
-#if defined (__HAS_SOUNDCARD_H__)
+#ifdef HAVE_OSS
 
 extern int MODM_NUMDEVS;
 extern LPMIDIOUTCAPS16 midiDevices[MAX_MIDIOUTDRV];
@@ -26,7 +26,7 @@
  * return the Windows equivalent to a Unix Device Type
  *
  */
-#if defined (__HAS_SOUNDCARD_H__)
+#ifdef HAVE_OSS
 int unixToWindowsDeviceType(int type)
 {
   /* MOD_MIDIPORT     output port 
@@ -57,12 +57,11 @@
  */
 BOOL32 MULTIMEDIA_Init (void)
 {
-#if defined (__HAS_SOUNDCARD_H__)
+#ifdef HAVE_OSS
   int i, status, numsynthdevs, nummididevs;
   struct synth_info sinfo;
   struct midi_info minfo;
   int fd;        /* file descriptor for MIDI_DEV */
-  LPMIDIOUTCAPS16 tmplpCaps = NULL;
 
   TRACE (midi, "Initializing the MIDI variables.\n");
   /* try to open device */
@@ -86,6 +85,8 @@
   }
 
   for (i = 0 ; i < numsynthdevs ; i++) {
+    LPMIDIOUTCAPS16 tmplpCaps;
+
     sinfo.device = i;
     status = ioctl(fd, SNDCTL_SYNTH_INFO, &sinfo);
     if (status == -1) {
@@ -144,12 +145,16 @@
   MODM_NUMDEVS = numsynthdevs + nummididevs;
   
   for (i = 0 ; i < nummididevs ; i++) {
+    LPMIDIOUTCAPS16 tmplpCaps;
+
     minfo.device = i;
     status = ioctl(fd, SNDCTL_MIDI_INFO, &minfo);
     if (status == -1) {
       ERR(midi, "ioctl failed.\n");
       return TRUE;
     }
+
+    tmplpCaps = xmalloc (sizeof (MIDIOUTCAPS16));
     /* This whole part is somewhat obscure to me. I'll keep trying to dig
        info about it. If you happen to know, please tell us. The very descritive
        minfo.dev_type was not used here.
@@ -174,7 +179,7 @@
   /* close file and exit */
   close(fd);
 
-#endif /* __HAS_SOUNDCARD_H__ */
+#endif /* HAVE_OSS */
   
   return TRUE;
   
diff --git a/multimedia/mcianim.c b/multimedia/mcianim.c
index 7b9379b..dc915a3 100644
--- a/multimedia/mcianim.c
+++ b/multimedia/mcianim.c
@@ -22,7 +22,6 @@
 #define ANIMFRAMES_PERMIN 	1800
 #define SECONDS_PERMIN	 	60
 
-#if defined(linux) || defined(__FreeBSD__)
 typedef struct {
     int     nUseCount;          /* Incremented for each shared open */
     BOOL16  fShareable;         /* TRUE if first open was shareable */
@@ -40,7 +39,6 @@
 } LINUX_ANIM;
 
 static LINUX_ANIM	AnimDev[MAX_ANIMDRV];
-#endif
 
 
 /*-----------------------------------------------------------------------*/
@@ -50,7 +48,6 @@
 */
 static DWORD ANIM_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS16 lpParms)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	LPSTR		lpstrElementName;
 	char		str[128];
 
@@ -102,9 +99,6 @@
 		}
 */
  	return 0;
-#else
-	return MCIERR_HARDWARE;
-#endif
 }
 
 /**************************************************************************
@@ -112,12 +106,10 @@
 */
 static DWORD ANIM_mciClose(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	TRACE(mcianim,"(%u, %08lX, %p);\n", 
 				wDevID, dwParam, lpParms);
 	if (AnimDev[wDevID].lpdwTrackLen != NULL) free(AnimDev[wDevID].lpdwTrackLen);
 	if (AnimDev[wDevID].lpdwTrackPos != NULL) free(AnimDev[wDevID].lpdwTrackPos);
-#endif
         return 0;
 }
 
@@ -127,7 +119,6 @@
 static DWORD ANIM_mciGetDevCaps(UINT16 wDevID, DWORD dwFlags, 
 						LPMCI_GETDEVCAPS_PARMS lpParms)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	TRACE(mcianim,"(%u, %08lX, %p);\n", 
 				wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
@@ -169,9 +160,6 @@
 	TRACE(mcianim, "lpParms->dwReturn=%08lX;\n", 
 		lpParms->dwReturn);
  	return 0;
-#else
-	return MCIERR_INTERNAL;
-#endif
 }
 
 
@@ -181,7 +169,6 @@
 static DWORD ANIM_CalcTime(UINT16 wDevID, DWORD dwFormatType, DWORD dwFrame)
 {
 	DWORD	dwTime = 0;
-#if defined(linux) || defined(__FreeBSD__)
 	UINT16	wTrack;
 	UINT16	wMinutes;
 	UINT16	wSeconds;
@@ -222,7 +209,6 @@
 				wTrack, wMinutes, wSeconds, wFrames);
 			break;
 		}
-#endif
 	return dwTime;
 }
 
@@ -233,7 +219,6 @@
 static DWORD ANIM_CalcFrame(UINT16 wDevID, DWORD dwFormatType, DWORD dwTime)
 {
 	DWORD	dwFrame = 0;
-#if defined(linux) || defined(__FreeBSD__)
 	UINT16	wTrack;
 	TRACE(mcianim,"(%u, %08lX, %lu);\n", 
 			wDevID, dwFormatType, dwTime);
@@ -267,7 +252,6 @@
 			dwFrame += MCI_TMSF_FRAME(dwTime);
 			break;
 		}
-#endif
 	return dwFrame;
 }
 
@@ -277,7 +261,6 @@
 */
 static DWORD ANIM_mciInfo(UINT16 wDevID, DWORD dwFlags, LPMCI_INFO_PARMS16 lpParms)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	TRACE(mcianim,"(%u, %08lX, %p);\n", 
 		wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
@@ -301,9 +284,6 @@
 	else
 		lpParms->dwRetSize = 0;
  	return 0;
-#else
-	return MCIERR_INTERNAL;
-#endif
 }
 
 /**************************************************************************
@@ -311,7 +291,6 @@
 */
 static DWORD ANIM_mciStatus(UINT16 wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	TRACE(mcianim,"(%u, %08lX, %p);\n", 
 			wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
@@ -388,9 +367,6 @@
 		}
     fprintf(stderr,"ANIM_mciStatus // not MCI_STATUS_ITEM !\n");
  	return 0;
-#else
-	return MMSYSERR_NOTENABLED;
-#endif
 }
 
 
@@ -399,7 +375,6 @@
 */
 static DWORD ANIM_mciPlay(UINT16 wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	int 	start, end;
 	TRACE(mcianim,"(%u, %08lX, %p);\n", 
 		wDevID, dwFlags, lpParms);
@@ -426,9 +401,6 @@
 			AnimDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
 		}
 	return 0;
-#else
-	return MCIERR_HARDWARE;
-#endif
 }
 
 /**************************************************************************
@@ -436,7 +408,6 @@
 */
 static DWORD ANIM_mciStop(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	TRACE(mcianim,"(%u, %08lX, %p);\n", 
 			wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
@@ -448,9 +419,6 @@
 			AnimDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
 		}
  	return 0;
-#else
-	return MCIERR_HARDWARE;
-#endif
 }
 
 /**************************************************************************
@@ -458,7 +426,6 @@
 */
 static DWORD ANIM_mciPause(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	TRACE(mcianim,"(%u, %08lX, %p);\n", 
 		wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
@@ -470,9 +437,6 @@
 			AnimDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
 		}
 	return 0;
-#else
-	return MCIERR_HARDWARE;
-#endif
 }
 
 /**************************************************************************
@@ -480,7 +444,6 @@
 */
 static DWORD ANIM_mciResume(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	TRACE(mcianim,"(%u, %08lX, %p);\n", 
 		wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
@@ -492,9 +455,6 @@
 			AnimDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
 		}
 	return 0;
-#else
-	return MCIERR_HARDWARE;
-#endif
 }
 
 /**************************************************************************
@@ -502,7 +462,6 @@
 */
 static DWORD ANIM_mciSeek(UINT16 wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	DWORD	dwRet;
 	MCI_PLAY_PARMS PlayParms;
 	TRACE(mcianim,"(%u, %08lX, %p);\n", 
@@ -530,9 +489,6 @@
 			AnimDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
 		}
 	return dwRet;
-#else
-	return MCIERR_HARDWARE;
-#endif
 }
 
 
@@ -541,7 +497,6 @@
 */
 static DWORD ANIM_mciSet(UINT16 wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	TRACE(mcianim,"(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 /*
@@ -575,9 +530,6 @@
 			AnimDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
 		}
 	return 0;
-#else
-	return MCIERR_HARDWARE;
-#endif
 }
 
 
@@ -587,7 +539,6 @@
 LONG ANIM_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
 		     DWORD dwParam1, DWORD dwParam2)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	switch(wMsg) {
 		case DRV_LOAD:
 			return 1;
@@ -647,9 +598,6 @@
 		default:
 			return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
 		}
-#else
-	return MCIERR_HARDWARE;
-#endif
 }
 
 
diff --git a/multimedia/mcicda.c b/multimedia/mcicda.c
index 39a1f09..48e6ea1 100644
--- a/multimedia/mcicda.c
+++ b/multimedia/mcicda.c
@@ -16,24 +16,26 @@
 #include "mmsystem.h"
 #include "debug.h"
 
-#ifdef linux
-#include <linux/soundcard.h>
-#include <linux/cdrom.h>
-#elif __FreeBSD__
-#include <machine/soundcard.h>
-#include <sys/cdio.h>
+#ifdef HAVE_LINUX_CDROM_H
+# include <linux/cdrom.h>
+#endif
+#ifdef HAVE_MACHINE_SOUNDCARD_H
+# include <machine/soundcard.h>
+#endif
+#ifdef HAVE_SYS_CDIO_H
+# include <sys/cdio.h>
 #endif
 
 #ifdef __FreeBSD__
-#define CDAUDIO_DEV "/dev/rcd0c"
+# define CDAUDIO_DEV "/dev/rcd0c"
 #else
-#define CDAUDIO_DEV "/dev/cdrom"
+# define CDAUDIO_DEV "/dev/cdrom"
 #endif
 
 #ifdef SOUND_VERSION
-#define IOCTL(a,b,c)		ioctl(a,b,&c)
+# define IOCTL(a,b,c)		ioctl(a,b,&c)
 #else
-#define IOCTL(a,b,c)		(c = ioctl(a,b,c) )
+# define IOCTL(a,b,c)		(c = ioctl(a,b,c) )
 #endif
 
 #define MAX_CDAUDIODRV 		(1)
diff --git a/multimedia/midi.c b/multimedia/midi.c
index 0a2f897..5bea87c 100644
--- a/multimedia/midi.c
+++ b/multimedia/midi.c
@@ -11,7 +11,6 @@
 #include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
-#include <sys/ioctl.h>
 #include "windows.h"
 #include "ldt.h"
 #include "multimedia.h"
@@ -21,14 +20,10 @@
 #include "xmalloc.h"
 #include "debug.h"
 
-#if defined (__HAS_SOUNDCARD_H__)
-
 static LINUX_MIDIIN	MidiInDev[MAX_MIDIINDRV];
 static LINUX_MIDIOUT	MidiOutDev[MAX_MIDIOUTDRV];
 static LINUX_MCIMIDI	MCIMidiDev[MAX_MCIMIDIDRV];
 
-#endif
-
 /* this is the total number of MIDI devices found */
 int MODM_NUMDEVS = 0;
 
@@ -45,8 +40,6 @@
 {
 	TRACE(midi,"wDevID = %04X wMsg = %d dwParm1 = %04lX dwParam2 = %04lX\n",wDevID, wMsg, dwParam1, dwParam2);
 
-#if defined(linux) || defined(__FreeBSD__)
-
 	switch (wMsg) {
 	case MOM_OPEN:
 	case MOM_CLOSE:
@@ -80,9 +73,6 @@
 	  break;
 	}
         return 0;
-#else
-	return MMSYSERR_NOTENABLED;
-#endif
 }
 
 
@@ -91,7 +81,6 @@
  */
 static DWORD MIDI_ReadByte(UINT16 wDevID, BYTE *lpbyt)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	if (lpbyt != NULL) {
 		if (mmioRead(MCIMidiDev[wDevID].hFile, (HPSTR)lpbyt,
 			(long) sizeof(BYTE)) == (long) sizeof(BYTE)) {
@@ -101,9 +90,6 @@
 	WARN(midi, "error reading wDevID=%04X\n", wDevID);
 	return MCIERR_INTERNAL;
 
-#else
-        return MMSYSERR_NOTENABLED;
-#endif
 }
 
 
@@ -178,7 +164,6 @@
  */
 static DWORD MIDI_ReadMThd(UINT16 wDevID, DWORD dwOffset)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	DWORD	toberead;
 	FOURCC	fourcc;
 	TRACE(midi, "(%04X, %08lX);\n", wDevID, dwOffset);
@@ -207,15 +192,11 @@
 		Mf_division = division = read16bit ();
 */
 	return 0;
-#else
-	return MMSYSERR_NOTENABLED;
-#endif
 }
 
 
 static DWORD MIDI_ReadMTrk(UINT16 wDevID, DWORD dwOffset)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	DWORD	toberead;
 	FOURCC	fourcc;
 	if (mmioSeek(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
@@ -232,9 +213,6 @@
 	toberead -= 3 * sizeof(WORD);
 	MCIMidiDev[wDevID].dwTotalLen = toberead;
 	return 0;
-#else
-         return MMSYSERR_NOTENABLED;
-#endif
 }
 
 
@@ -243,7 +221,6 @@
  */
 static DWORD MIDI_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS16 lpParms)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	MIDIOPENDESC 	MidiDesc;
 	DWORD		dwRet;
 	DWORD		dwOffset;
@@ -330,9 +307,6 @@
 /*	dwRet = midMessage(wDevID, MIDM_OPEN, 0, (DWORD)&MidiDesc, CALLBACK_NULL);*/
 
 	return 0;
-#else
-	return MMSYSERR_NOTENABLED;
-#endif
 }
 
 /**************************************************************************
@@ -340,16 +314,12 @@
  */
 static DWORD MIDI_mciStop(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
 	TRACE(midi, "MCIMidiDev[wDevID].dwStatus=%p %d\n",
 			&MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
 	return 0;
-#else
-	return MCIERR_INTERNAL;
-#endif
 }
 
 
@@ -358,7 +328,6 @@
  */
 static DWORD MIDI_mciClose(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	DWORD		dwRet;
 
 	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwParam, lpParms);
@@ -382,9 +351,6 @@
 */
 		}
 	return 0;
-#else
-	return 0;
-#endif
 }
 
 
@@ -393,7 +359,6 @@
  */
 static DWORD MIDI_mciPlay(UINT16 wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	int		count,start,end;
 	LPMIDIHDR	lpMidiHdr;
 	DWORD		dwData,dwRet;
@@ -494,14 +459,8 @@
 		TRACE(midi, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
 		mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback), 
 			MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
-#if 0
-		exit(1);
-#endif
 	}
 	return 0;
-#else
-	return MMSYSERR_NOTENABLED;
-#endif
       }
 
 
@@ -510,7 +469,6 @@
  */
 static DWORD MIDI_mciRecord(UINT16 wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	int			start, end;
 	LPMIDIHDR	lpMidiHdr;
 	DWORD		dwRet;
@@ -561,9 +519,6 @@
 			MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
 	}
 	return 0;
-#else
-	return MMSYSERR_NOTENABLED;
-#endif
 }
 
 
@@ -572,13 +527,9 @@
  */
 static DWORD MIDI_mciPause(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	return 0;
-#else
-	return MCIERR_INTERNAL;
-#endif
 }
 
 
@@ -587,13 +538,9 @@
  */
 static DWORD MIDI_mciResume(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	return 0;
-#else
-	return MCIERR_INTERNAL;
-#endif
 }
 
 
@@ -602,7 +549,6 @@
  */
 static DWORD MIDI_mciSet(UINT16 wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	TRACE(midi, "dwTimeFormat=%08lX\n", lpParms->dwTimeFormat);
@@ -648,9 +594,6 @@
 	if (dwFlags & MCI_SEQ_SET_TEMPO)
 		TRACE(midi, "MCI_SEQ_SET_TEMPO !\n");
  	return 0;
-#else
-	return MCIERR_INTERNAL;
-#endif
 }
 
 
@@ -659,7 +602,6 @@
  */
 static DWORD MIDI_mciStatus(UINT16 wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	if (dwFlags & MCI_STATUS_ITEM) {
@@ -736,9 +678,6 @@
 			MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
 	}
  	return 0;
-#else
-	return MCIERR_INTERNAL;
-#endif
 }
 
 /**************************************************************************
@@ -747,7 +686,6 @@
 static DWORD MIDI_mciGetDevCaps(UINT16 wDevID, DWORD dwFlags, 
 					LPMCI_GETDEVCAPS_PARMS lpParms)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	if (dwFlags & MCI_GETDEVCAPS_ITEM) {
@@ -784,9 +722,6 @@
 		}
 	}
  	return 0;
-#else
-	return MCIERR_INTERNAL;
-#endif
 }
 
 
@@ -795,7 +730,6 @@
  */
 static DWORD MIDI_mciInfo(UINT16 wDevID, DWORD dwFlags, LPMCI_INFO_PARMS16 lpParms)
 {
-# if defined(__FreeBSD__) || defined (linux)
 	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	lpParms->lpstrReturn = NULL;
@@ -814,9 +748,6 @@
 	else
 		lpParms->dwRetSize = 0;
  	return 0;
-#else
-	return MCIERR_INTERNAL;
-#endif
 }
 
 
@@ -842,7 +773,6 @@
  */
 static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	int		midi;
 	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
 	if (lpDesc == NULL) {
@@ -883,9 +813,6 @@
 		return MMSYSERR_INVALPARAM;
 	}
 	return MMSYSERR_NOERROR;
-#else
-	return MMSYSERR_NOTENABLED;
-#endif
 }
 
 /**************************************************************************
@@ -893,7 +820,6 @@
  */
 static DWORD midClose(WORD wDevID)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	TRACE(midi, "(%04X);\n", wDevID);
 	if (MidiInDev[wDevID].unixdev == 0) {
 		WARN(midi,"can't close !\n");
@@ -907,9 +833,6 @@
 		return MMSYSERR_INVALPARAM;
 	}
 	return MMSYSERR_NOERROR;
-#else
-	return MMSYSERR_NOTENABLED;
-#endif
 }
 
 /**************************************************************************
@@ -1043,7 +966,6 @@
  */
 static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	int		midi;
 
 	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
@@ -1086,9 +1008,6 @@
 	}
 	TRACE(midi, "Succesful unixdev=%d !\n", midi);
 	return MMSYSERR_NOERROR;
-#else
-	return MMSYSERR_NOTENABLED;
-#endif
 }
 
 
@@ -1097,7 +1016,6 @@
  */
 static DWORD modClose(WORD wDevID)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	TRACE(midi, "(%04X);\n", wDevID);
 	if (MidiOutDev[wDevID].unixdev == 0) {
 		WARN(midi,"can't close !\n");
@@ -1111,9 +1029,6 @@
 		return MMSYSERR_INVALPARAM;
 	}
 	return MMSYSERR_NOERROR;
-#else
-	return MMSYSERR_NOTENABLED;
-#endif
 }
 
 /**************************************************************************
@@ -1121,7 +1036,6 @@
  */
 static DWORD modData(WORD wDevID, DWORD dwParam)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	WORD	event;
 
 	TRACE(midi, "(%04X, %08lX);\n", wDevID, dwParam);
@@ -1135,9 +1049,6 @@
 		WARN(midi, "error writting unixdev !\n");
 	}
 	return MMSYSERR_NOTENABLED;
-#else
-        return MMSYSERR_NOTENABLED;
-#endif
 }
 
 /**************************************************************************
@@ -1145,7 +1056,6 @@
  */
 static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	int		count;
 	LPWORD	ptr;
 	int     en;
@@ -1191,9 +1101,6 @@
 		return MMSYSERR_INVALPARAM;
 	}
 	return MMSYSERR_NOERROR;
-#else
-	return MMSYSERR_NOTENABLED;
-#endif
 }
 
 /**************************************************************************
@@ -1201,7 +1108,6 @@
  */
 static DWORD modPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
 	if (MidiOutDev[wDevID].unixdev == 0) {
 		WARN(midi,"can't prepare !\n");
@@ -1217,9 +1123,6 @@
 	lpMidiHdr->dwFlags |= MHDR_PREPARED;
 	lpMidiHdr->dwFlags &= ~MHDR_DONE;
 	return MMSYSERR_NOERROR;
-#else
-	return MMSYSERR_NOTENABLED;
-#endif
 }
 
 /**************************************************************************
@@ -1227,16 +1130,12 @@
  */
 static DWORD modUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
 	if (MidiOutDev[wDevID].unixdev == 0) {
 		WARN(midi,"can't unprepare !\n");
 		return MMSYSERR_NOTENABLED;
 	}
 	return MMSYSERR_NOERROR;
-#else
-	return MMSYSERR_NOTENABLED;
-#endif
 }
 
 /**************************************************************************
@@ -1291,7 +1190,6 @@
 LONG MIDI_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
 		     DWORD dwParam1, DWORD dwParam2)
 {
-#if defined(linux) || defined(__FreeBSD__)
 	switch(wMsg) {
 	case DRV_LOAD:
 		return 1;
@@ -1342,10 +1240,5 @@
 	default:
 		return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
 	}
-#else
-	return MMSYSERR_NOTENABLED;
-#endif
 }
-
-
 /*-----------------------------------------------------------------------*/
diff --git a/multimedia/mixer.c b/multimedia/mixer.c
index f37b931..1233531 100644
--- a/multimedia/mixer.c
+++ b/multimedia/mixer.c
@@ -15,10 +15,11 @@
 #include "mmsystem.h"
 #include "debug.h"
 
-#ifdef linux
-#include <linux/soundcard.h>
-#elif __FreeBSD__
-#include <machine/soundcard.h>
+#ifdef HAVE_SYS_SOUNDCARD_H
+# include <sys/soundcard.h>
+#endif
+#ifdef HAVE_MACHINE_SOUNDCARD_H
+# include <machine/soundcard.h>
 #endif
 
 #define MIXER_DEV "/dev/mixer"
@@ -35,7 +36,7 @@
  */
 static DWORD MIX_GetDevCaps(WORD wDevID, LPMIXERCAPS16 lpCaps, DWORD dwSize)
 {
-#ifdef linux
+#ifdef HAVE_OSS
 	int 		mixer,mask;
 
 	TRACE(mmaux,"(%04X, %p, %lu);\n", wDevID, lpCaps, dwSize);
@@ -64,7 +65,7 @@
 #endif
 }
 
-#ifdef linux
+#ifdef HAVE_OSS
 static char *sdlabels[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_LABELS;
 static char *sdnames[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
 #endif
@@ -74,7 +75,7 @@
  */
 static DWORD MIX_GetLineInfo(WORD wDevID, LPMIXERLINE16 lpml, DWORD fdwInfo)
 {
-#ifdef linux
+#ifdef HAVE_OSS
 	int 		mixer,i,j,devmask,recsrc,recmask;
 
 	TRACE(mmaux,"(%04X, %p, %lu);\n", wDevID, lpml, fdwInfo);
@@ -176,7 +177,7 @@
  */
 static DWORD MIX_Open(WORD wDevID, LPMIXEROPENDESC lpmod, DWORD flags)
 {
-#ifdef linux
+#ifdef HAVE_OSS
 
 	TRACE(mmaux,"(%04X, %p, %lu);\n",wDevID,lpmod,flags);
 	if (lpmod == NULL) return MMSYSERR_NOTENABLED;
diff --git a/multimedia/mmaux.c b/multimedia/mmaux.c
index de953b3..8d2673d 100644
--- a/multimedia/mmaux.c
+++ b/multimedia/mmaux.c
@@ -1,5 +1,5 @@
 /*
- * Sample AUXILARY Wine Driver for Linux
+ * Sample AUXILARY Wine Driver
  *
  * Copyright 1994 Martin Ayotte
  */
@@ -17,10 +17,11 @@
 #include "mmsystem.h"
 #include "debug.h"
 
-#ifdef linux
-#include <linux/soundcard.h>
-#elif __FreeBSD__
-#include <machine/soundcard.h>
+#ifdef HAVE_SYS_SOUNDCARD_H
+# include <sys/soundcard.h>
+#endif
+#ifdef HAVE_MACHINE_SOUNDCARD_H
+# include <machine/soundcard.h>
 #endif
 
 #define MIXER_DEV "/dev/mixer"
@@ -42,7 +43,7 @@
  */
 static DWORD AUX_GetDevCaps(WORD wDevID, LPAUXCAPS16 lpCaps, DWORD dwSize)
 {
-#ifdef linux
+#ifdef HAVE_OSS
 	int 	mixer,volume;
 
 	TRACE(mmaux,"(%04X, %p, %lu);\n", wDevID, lpCaps, dwSize);
@@ -113,7 +114,7 @@
  */
 static DWORD AUX_GetVolume(WORD wDevID, LPDWORD lpdwVol)
 {
-#ifdef linux
+#ifdef HAVE_OSS
 	int 	mixer,volume,left,right,cmd;
 
 	TRACE(mmaux,"(%04X, %p);\n", wDevID, lpdwVol);
@@ -171,7 +172,7 @@
  */
 static DWORD AUX_SetVolume(WORD wDevID, DWORD dwParam)
 {
-#ifdef linux
+#ifdef HAVE_OSS
 	int 	mixer;
 	int		volume;
 	int		cmd;
diff --git a/objects/bitmap.c b/objects/bitmap.c
index 8b62e8d..71fc644 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -515,7 +515,7 @@
 	
 }
 /**********************************************************************
- *	    LoadImage32A    (USER32.364)
+ *	    LoadImage32A    (USER32.365)
  * FIXME: implementation still lacks nearly all features, see LR_*
  * defines in windows.h
  */
@@ -584,7 +584,7 @@
 }
 
 /**********************************************************************
- *	    CopyImage32    (USER32.60)
+ *	    CopyImage32    (USER32.61)
  *
  * FIXME: implementation still lacks nearly all features, see LR_*
  * defines in windows.h
@@ -632,7 +632,7 @@
         return OBM_LoadBitmap( LOWORD((int)name) );
     }
 
-    if (!(hRsrc = FindResource16( instance, name, RT_BITMAP ))) return 0;
+    if (!(hRsrc = FindResource16( instance, name, RT_BITMAP16 ))) return 0;
     if (!(handle = LoadResource16( instance, hRsrc ))) return 0;
 
     info = (BITMAPINFO *)LockResource16( handle );
@@ -648,7 +648,7 @@
 }
 
 /**********************************************************************
- *	    LoadBitmap32W   (USER32.357)
+ *	    LoadBitmap32W   (USER32.358)
  */
 HBITMAP32 WINAPI LoadBitmap32W( HINSTANCE32 instance, LPCWSTR name )
 {
@@ -664,8 +664,7 @@
         return OBM_LoadBitmap( LOWORD((int)name) );
     }
 
-    if (!(hRsrc = FindResource32W( instance, name,
-		(LPWSTR)RT_BITMAP ))) return 0;
+    if (!(hRsrc = FindResource32W( instance, name, RT_BITMAP32W ))) return 0;
     if (!(handle = LoadResource32( instance, hRsrc ))) return 0;
 
     info = (BITMAPINFO *)LockResource32( handle );
@@ -681,7 +680,7 @@
 
 
 /**********************************************************************
- *	    LoadBitmap32A   (USER32.356)
+ *	    LoadBitmap32A   (USER32.357)
  */
 HBITMAP32 WINAPI LoadBitmap32A( HINSTANCE32 instance, LPCSTR name )
 {
diff --git a/objects/cursoricon.c b/objects/cursoricon.c
index c25333f..84170bf 100644
--- a/objects/cursoricon.c
+++ b/objects/cursoricon.c
@@ -217,7 +217,7 @@
     CURSORICONDIRENTRY *entry = NULL;
 
     if (!(hRsrc = FindResource16( hInstance, name,
-                                fCursor ? RT_GROUP_CURSOR : RT_GROUP_ICON )))
+                              fCursor ? RT_GROUP_CURSOR16 : RT_GROUP_ICON16 )))
         return FALSE;
     if (!(hMem = LoadResource16( hInstance, hRsrc ))) return FALSE;
     if ((dir = (CURSORICONDIR *)LockResource16( hMem )))
@@ -251,7 +251,7 @@
     CURSORICONDIRENTRY *entry = NULL;
 
     if (!(hRsrc = FindResource32W( hInstance, name,
-                (LPCWSTR)(fCursor ? RT_GROUP_CURSOR : RT_GROUP_ICON) )))
+                            fCursor ? RT_GROUP_CURSOR32W : RT_GROUP_ICON32W )))
         return FALSE;
     if (!(hMem = LoadResource32( hInstance, hRsrc ))) return FALSE;
     if ((dir = (CURSORICONDIR*)LockResource32( hMem )))
@@ -441,7 +441,7 @@
 
 
 /**********************************************************************
- *          CreateIconFromResource          (USER32.???)
+ *          CreateIconFromResource          (USER32.76)
  * FIXME:
  *  	bon@elektron.ikp.physik.tu-darmstadt.de 971130: Test with weditres
  *	showed only blank layout. Couldn't determine if this is a problem
@@ -461,7 +461,7 @@
 
 
 /**********************************************************************
- *          CreateIconFromResourceEx32          (USER32.76)
+ *          CreateIconFromResourceEx32          (USER32.77)
  */
 HICON32 WINAPI CreateIconFromResourceEx32( LPBYTE bits, UINT32 cbSize,
                                            BOOL32 bIcon, DWORD dwVersion,
@@ -503,8 +503,8 @@
     /* Load the resource */
 
     if ( (hRsrc = FindResource16( hInstance,
-                                MAKEINTRESOURCE( dirEntry.icon.wResId ),
-                                fCursor ? RT_CURSOR : RT_ICON )) )
+                                MAKEINTRESOURCE16( dirEntry.icon.wResId ),
+                                fCursor ? RT_CURSOR16 : RT_ICON16 )) )
     {
 	/* 16-bit icon or cursor resources are processed
 	 * transparently by the LoadResource16() via custom
@@ -558,8 +558,8 @@
     /* Load the resource */
 
     if ( (hRsrc = FindResource32W( hInstance,
-                      (LPWSTR) (DWORD) dirEntry.icon.wResId,
-                      (LPWSTR) (fCursor ? RT_CURSOR : RT_ICON ))) )
+                                   MAKEINTRESOURCE32W( dirEntry.icon.wResId ),
+                                   fCursor ? RT_CURSOR32W : RT_ICON32W )) )
     {
 	HANDLE32 h = 0;
 	if ( (handle = LoadResource32( hInstance, hRsrc )) )
@@ -689,7 +689,7 @@
 
            if( !hRet ) /* fall back on default drag cursor */
                 hRet = CURSORICON_Copy( pTask->hInstance ,
-                              CURSORICON_Load16(0,MAKEINTRESOURCE(OCR_DRAGOBJECT),
+                              CURSORICON_Load16(0,MAKEINTRESOURCE16(OCR_DRAGOBJECT),
                                          SYSMETRICS_CXCURSOR, SYSMETRICS_CYCURSOR, 1, TRUE) );
        }
 
@@ -749,7 +749,7 @@
 
 
 /***********************************************************************
- *           CreateCursor32    (USER32.66)
+ *           CreateCursor32    (USER32.67)
  */
 HCURSOR32 WINAPI CreateCursor32( HINSTANCE32 hInstance,
                                  INT32 xHotSpot, INT32 yHotSpot,
@@ -781,7 +781,7 @@
 
 
 /***********************************************************************
- *           CreateIcon32    (USER32.74)
+ *           CreateIcon32    (USER32.75)
  */
 HICON32 WINAPI CreateIcon32( HINSTANCE32 hInstance, INT32 nWidth,
                              INT32 nHeight, BYTE bPlanes, BYTE bBitsPixel,
@@ -836,7 +836,7 @@
 
 
 /***********************************************************************
- *           CopyIcon32    (USER32.59)
+ *           CopyIcon32    (USER32.60)
  */
 HICON32 WINAPI CopyIcon32( HICON32 hIcon )
 {
@@ -867,7 +867,7 @@
 
 
 /***********************************************************************
- *           DestroyIcon32    (USER32.132)
+ *           DestroyIcon32    (USER32.133)
  */
 BOOL32 WINAPI DestroyIcon32( HICON32 hIcon )
 {
@@ -887,7 +887,7 @@
 
 
 /***********************************************************************
- *           DestroyCursor32    (USER32.131)
+ *           DestroyCursor32    (USER32.132)
  */
 BOOL32 WINAPI DestroyCursor32( HCURSOR32 hCursor )
 {
@@ -907,7 +907,7 @@
 
 
 /***********************************************************************
- *           DrawIcon32    (USER32.158)
+ *           DrawIcon32    (USER32.159)
  */
 BOOL32 WINAPI DrawIcon32( HDC32 hdc, INT32 x, INT32 y, HICON32 hIcon )
 {
@@ -1117,7 +1117,7 @@
 
 
 /***********************************************************************
- *           SetCursor32    (USER32.471)
+ *           SetCursor32    (USER32.472)
  * RETURNS:
  *	A handle to the previous cursor shape.
  */
@@ -1151,7 +1151,7 @@
 
 
 /***********************************************************************
- *           SetCursorPos32    (USER32.473)
+ *           SetCursorPos32    (USER32.474)
  */
 BOOL32 WINAPI SetCursorPos32( INT32 x, INT32 y )
 {
@@ -1171,7 +1171,7 @@
 
 
 /***********************************************************************
- *           ShowCursor32    (USER32.529)
+ *           ShowCursor32    (USER32.530)
  */
 INT32 WINAPI ShowCursor32( BOOL32 bShow )
 {
@@ -1204,7 +1204,7 @@
 
 
 /***********************************************************************
- *           GetCursor32    (USER32.226)
+ *           GetCursor32    (USER32.227)
  */
 HCURSOR32 WINAPI GetCursor32(void)
 {
@@ -1224,7 +1224,7 @@
 
 
 /***********************************************************************
- *           ClipCursor32    (USER32.52)
+ *           ClipCursor32    (USER32.53)
  */
 BOOL32 WINAPI ClipCursor32( const RECT32 *rect )
 {
@@ -1269,7 +1269,7 @@
 
 
 /***********************************************************************
- *           GetCursorPos32    (USER32.228)
+ *           GetCursorPos32    (USER32.229)
  */
 void WINAPI GetCursorPos32( POINT32 *pt )
 {
@@ -1289,7 +1289,7 @@
 
 
 /***********************************************************************
- *           GetClipCursor32    (USER32.220)
+ *           GetClipCursor32    (USER32.221)
  */
 void WINAPI GetClipCursor32( RECT32 *rect )
 {
@@ -1327,7 +1327,7 @@
 }
 
 /**********************************************************************
- *          LookupIconIdFromDirectoryEx32       (USER32.379)
+ *          LookupIconIdFromDirectoryEx32       (USER32.380)
  */
 INT32 WINAPI LookupIconIdFromDirectoryEx32( LPBYTE dir, BOOL32 bIcon,
              INT32 width, INT32 height, UINT32 cFlag )
@@ -1346,7 +1346,7 @@
 }
 
 /**********************************************************************
- *          LookupIconIdFromDirectory		(USER32.378)
+ *          LookupIconIdFromDirectory		(USER32.379)
  */
 INT32 WINAPI LookupIconIdFromDirectory32( LPBYTE dir, BOOL32 bIcon )
 {
@@ -1367,10 +1367,10 @@
 
     switch(resType)
     {
-	case RT_CURSOR:
+	case RT_CURSOR16:
 	     return (WORD)LookupIconIdFromDirectoryEx16( lpDir, FALSE, 
 			  SYSMETRICS_CXCURSOR, SYSMETRICS_CYCURSOR, LR_MONOCHROME );
-	case RT_ICON:
+	case RT_ICON16:
 	     return (WORD)LookupIconIdFromDirectoryEx16( lpDir, TRUE,
 			  SYSMETRICS_CXICON, SYSMETRICS_CYICON, 0 );
 	default:
@@ -1448,7 +1448,7 @@
 }
 
 /***********************************************************************
- *           LoadCursorW                (USER32.361)
+ *           LoadCursorW                (USER32.362)
  */
 HCURSOR32 WINAPI LoadCursor32W(HINSTANCE32 hInstance, LPCWSTR name)
 {
@@ -1457,7 +1457,7 @@
 }
 
 /***********************************************************************
- *           LoadCursorA                (USER32.358)
+ *           LoadCursorA                (USER32.359)
  */
 HCURSOR32 WINAPI LoadCursor32A(HINSTANCE32 hInstance, LPCSTR name)
 {
@@ -1474,7 +1474,7 @@
 }
 
 /***********************************************************************
- *           LoadIconW          (USER32.363)
+ *           LoadIconW          (USER32.364)
  */
 HICON32 WINAPI LoadIcon32W(HINSTANCE32 hInstance, LPCWSTR name)
 {
@@ -1484,7 +1484,7 @@
 }
 
 /***********************************************************************
- *           LoadIconA          (USER32.362)
+ *           LoadIconA          (USER32.363)
  */
 HICON32 WINAPI LoadIcon32A(HINSTANCE32 hInstance, LPCSTR name)
 {
@@ -1502,7 +1502,7 @@
 }
 
 /**********************************************************************
- *          GetIconInfo		(USER32.241)
+ *          GetIconInfo		(USER32.242)
  */
 BOOL32 WINAPI GetIconInfo(HICON32 hIcon,LPICONINFO iconinfo) {
     CURSORICONINFO	*ciconinfo;
diff --git a/objects/enhmetafile.c b/objects/enhmetafile.c
index 8266275..9745666 100644
--- a/objects/enhmetafile.c
+++ b/objects/enhmetafile.c
@@ -16,7 +16,7 @@
  *
  *
  */
-HENHMETAFILE32 GetEnhMetaFile32A( 
+HENHMETAFILE32 WINAPI GetEnhMetaFile32A( 
 	     LPCSTR lpszMetaFile  /* filename of enhanced metafile */
     )
 {
@@ -39,13 +39,13 @@
 }
 
 /*****************************************************************************
- *        GetEnhMetaFileHeader32  (GDI32.178)
+ *        GetEnhMetaFileHeader  (GDI32.178)
  *
  *  If _buf_ is NULL, returns the size of buffer required.
  *  Otherwise, copy up to _bufsize_ bytes of enhanced metafile header into 
  *  _buf.
  */
-UINT32 GetEnhMetaFileHeader32( 
+UINT32 WINAPI GetEnhMetaFileHeader( 
        HENHMETAFILE32 hmf, /* enhanced metafile */
        UINT32 bufsize,     /* size of buffer */
        LPENHMETAHEADER buf /* buffer */ 
@@ -60,29 +60,53 @@
 
 /*****************************************************************************
  *          GetEnhMetaFileDescription32A  (GDI32.176)
- *
- *  Copies the description string of an enhanced metafile into a buffer 
- *  _buf_.
- *
- * FIXME
- *   doesn't work. description is wide, with substructure
  */
-UINT32 GetEnhMetaFileDescription32A( 
+UINT32 WINAPI GetEnhMetaFileDescription32A( 
        HENHMETAFILE32 hmf, /* enhanced metafile */
        UINT32 size, /* size of buf */ 
        LPSTR buf /* buffer to receive description */
     )
 {
   LPENHMETAHEADER p = GlobalLock32(hmf);
-  
+  INT32 first  = lstrlen32W( (void *)p+p->offDescription);
+
   if (!buf || !size) return p->nDescription;
+
   lstrcpynWtoA(buf, (void *)p+p->offDescription, size);
-  /*  memmove(buf, (void *)p+p->offDescription, MIN(size,p->nDescription));*/
+  buf += first +1;
+  lstrcpynWtoA(buf, (void *)p+p->offDescription+2*(first+1), size-first-1);
+
+  /*  memmove(buf, (void *)p+p->offDescription, MIN(size,p->nDescription)); */
+  GlobalUnlock32(hmf);
   return MIN(size,p->nDescription);
 }
 
 /*****************************************************************************
- *           PlayEnhMetaFileRecord32  (GDI32.264)
+ *          GetEnhMetaFileDescription32W  (GDI32.xxx)
+ *
+ *  Copies the description string of an enhanced metafile into a buffer 
+ *  _buf_.
+ *
+ *  If _buf_ is NULL, returns size of _buf_ required. Otherwise, returns
+ *  number of characters copied.
+ */
+UINT32 WINAPI GetEnhMetaFileDescription32W( 
+       HENHMETAFILE32 hmf, /* enhanced metafile */
+       UINT32 size, /* size of buf */ 
+       LPWSTR buf /* buffer to receive description */
+    )
+{
+  LPENHMETAHEADER p = GlobalLock32(hmf);
+
+  if (!buf || !size) return p->nDescription;
+
+  memmove(buf, (void *)p+p->offDescription, MIN(size,p->nDescription));
+  GlobalUnlock32(hmf);
+  return MIN(size,p->nDescription);
+}
+
+/*****************************************************************************
+ *           PlayEnhMetaFileRecord  (GDI32.264)
  *
  *  Render a single enhanced metafile record in the device context hdc.
  *
@@ -91,7 +115,7 @@
  *  BUGS
  *    Many unimplemented records.
  */
-BOOL32 PlayEnhMetaFileRecord32( 
+BOOL32 WINAPI PlayEnhMetaFileRecord( 
      HDC32 hdc, 
      /* device context in which to render EMF record */
      LPHANDLETABLE32 handletable, 
@@ -345,7 +369,7 @@
  * BUGS
  *   Ignores rect.
  */
-BOOL32 EnumEnhMetaFile32( 
+BOOL32 WINAPI EnumEnhMetaFile32( 
      HDC32 hdc, /* device context to pass to _EnhMetaFunc_ */
      HENHMETAFILE32 hmf, /* EMF to walk */
      ENHMFENUMPROC32 callback, /* callback function */ 
@@ -370,7 +394,7 @@
 
 
 /**************************************************************************
- *    PlayEnhMetaFile32  (GDI32.263)
+ *    PlayEnhMetaFile  (GDI32.263)
  *
  *    Renders an enhanced metafile into a specified rectangle *lpRect
  *    in device context hdc.
@@ -379,7 +403,7 @@
  *    Almost entirely unimplemented
  *
  */
-BOOL32 PlayEnhMetaFile32( 
+BOOL32 WINAPI PlayEnhMetaFile( 
        HDC32 hdc, /* DC to render into */
        HENHMETAFILE32 hmf, /* metafile to render */
        const RECT32 *lpRect  /* rectangle to place metafile inside */
@@ -391,7 +415,7 @@
 				    sizeof(HANDLETABLE32)*count);
   ht->objectHandle[0] = hmf;
   while (1) {
-    PlayEnhMetaFileRecord32(hdc, ht, p, count);
+    PlayEnhMetaFileRecord(hdc, ht, p, count);
     if (p->iType == EMR_EOF) break;
     p = (void *) p + p->nSize; /* casted so that arithmetic is in bytes */
   }
@@ -399,16 +423,16 @@
 }
 
 /*****************************************************************************
- *  DeleteEnhMetaFile32 (GDI32.68)
+ *  DeleteEnhMetaFile (GDI32.68)
  */
-BOOL32 DeleteEnhMetaFile32(HENHMETAFILE32 hmf) {
+BOOL32 WINAPI DeleteEnhMetaFile(HENHMETAFILE32 hmf) {
   return !GlobalFree32(hmf);
 }
 
 /*****************************************************************************
  *  CopyEnhMetaFileA (GDI32.21)
  */
-HENHMETAFILE32 CopyEnhMetaFile32A(HENHMETAFILE32 hmf, LPCSTR file) {
+HENHMETAFILE32 WINAPI CopyEnhMetaFile32A(HENHMETAFILE32 hmf, LPCSTR file) {
   return 0;
 }
 
diff --git a/objects/font.c b/objects/font.c
index 564a43c..76948e8 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -722,10 +722,19 @@
 
 
 /***********************************************************************
- *           GetTextExtentPoint32W    (GDI32.231)
+ * GetTextExtentPoint32W [GDI32.231]  Computes width/height for a string
+ *
+ * Computes width and height of the specified string.
+ *
+ * RETURNS
+ *    Success: TRUE
+ *    Failure: FALSE
  */
-BOOL32 WINAPI GetTextExtentPoint32W( HDC32 hdc, LPCWSTR str, INT32 count,
-                                     LPSIZE32 size )
+BOOL32 WINAPI GetTextExtentPoint32W(
+    HDC32 hdc,     /* [in]  Handle of device context */
+    LPCWSTR str,   /* [in]  Address of text string */
+    INT32 count,   /* [in]  Number of characters in string */
+    LPSIZE32 size) /* [out] Address of structure for string size */
 {
     LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
     BOOL32 ret = GetTextExtentPoint32A( hdc, p, count, size );
@@ -896,6 +905,26 @@
 
 
 /***********************************************************************
+ * GetOutlineTextMetrics [GDI.308]  Gets metrics for TrueType fonts.
+ *
+ * NOTES
+ *    lpOTM should be LPOUTLINETEXTMETRIC
+ *
+ * RETURNS
+ *    Success: Non-zero or size of required buffer
+ *    Failure: 0
+ */
+INT16 WINAPI GetOutlineTextMetrics(
+    HDC16 hdc,    /* [in]  Handle of device context */
+    INT16 cbData, /* [in]  Size of metric data array */
+    void *lpOTM)  /* [out] Address of metric data array */
+{
+    FIXME(font, "(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
+    return 0;
+}
+
+
+/***********************************************************************
  *           GetCharWidth16    (GDI.350)
  */
 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index 283dcd1..8d060b0 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -19,7 +19,6 @@
 #include "debug.h"
 #include "gdi.h"
 
-WORD GDI_HeapSel = 0;
 
 /***********************************************************************
  *          GDI stock objects 
@@ -897,7 +896,7 @@
 	     INT32 nMultiplier,
 	     INT32 nDivisor
 ) {
-#ifdef __GNUC__
+#if (SIZEOF_LONG_LONG >= 8)
     long long ret;
     if (!nDivisor) return -1;
     ret = ((long long)nMultiplicand * nMultiplier) / nDivisor;
diff --git a/objects/metafile.c b/objects/metafile.c
index cd0a80b..ea424bc 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -950,6 +950,9 @@
 
 /******************************************************************
  *         SetMetaFileBitsEx    (GDI32.323)
+ * 
+ *  Create a metafile from raw data. No checking of the data is performed.
+ *  Use _GetMetaFileBitsEx_ to get raw data from a metafile.
  */
 HMETAFILE32 WINAPI SetMetaFileBitsEx( 
      UINT32 size, /* size of metafile, in bytes */
diff --git a/objects/oembitmap.c b/objects/oembitmap.c
index d362f77..f7b83ce 100644
--- a/objects/oembitmap.c
+++ b/objects/oembitmap.c
@@ -68,6 +68,8 @@
 #include "bitmaps/obm_reduce_95"
 #include "bitmaps/obm_close_95"
 #include "bitmaps/obm_closed_95"
+#include "bitmaps/obm_restore_95"
+#include "bitmaps/obm_restored_95"
 
 
 #define OBM_FIRST  OBM_RADIOCHECK  /* First OEM bitmap */
@@ -131,11 +133,15 @@
 #include "bitmaps/oic_portrait"
 #include "bitmaps/oic_landscape"
 #include "bitmaps/oic_wineicon"
+#include "bitmaps/oic_hand_95"
+#include "bitmaps/oic_ques_95"
+#include "bitmaps/oic_bang_95"
+#include "bitmaps/oic_note_95"
 
 #define OIC_FIRST  OIC_SAMPLE      /* First OEM icon */
 #define OIC_LAST   OIC_WINEICON   /* Last OEM icon */
 
-static char ** const OBM_Icons_Data[OIC_LAST-OIC_FIRST+1] =
+static char **OBM_Icons_Data[OIC_LAST-OIC_FIRST+1] =
 {
     oic_sample,    /* OIC_SAMPLE */
     oic_hand,      /* OIC_HAND */
@@ -164,6 +170,9 @@
 #include "bitmaps/ocr_dragobject"
 /*#include "bitmaps/ocr_sizeall"*/
 /*#include "bitmaps/ocr_icocur"*/
+#include "bitmaps/ocr_no"
+#include "bitmaps/ocr_appstarting"
+#include "bitmaps/ocr_help"
 
 /* Cursor are not all contiguous (go figure...) */
 #define OCR_FIRST0 OCR_BUMMER
@@ -178,26 +187,41 @@
 #define OCR_LAST2  OCR_SIZENS 
 #define OCR_BASE2	(OCR_BASE1 + OCR_LAST1 - OCR_FIRST1 + 1)
 
-#define NB_CURSORS (OCR_BASE2 + OCR_LAST2 - OCR_FIRST2 + 1)
+#define OCR_FIRST3 OCR_NO
+#define OCR_LAST3  OCR_NO
+#define OCR_BASE3       (OCR_BASE2 + OCR_LAST2 - OCR_FIRST2 + 1)
+
+#define OCR_FIRST4 OCR_APPSTARTING
+#define OCR_LAST4  OCR_APPSTARTING
+#define OCR_BASE4       (OCR_BASE3 + OCR_LAST3 - OCR_FIRST3 + 1)
+
+#define OCR_FIRST5 OCR_HELP
+#define OCR_LAST5  OCR_HELP
+#define OCR_BASE5       (OCR_BASE4 + OCR_LAST4 - OCR_FIRST4 + 1)
+
+#define NB_CURSORS (OCR_BASE5 + OCR_LAST5 - OCR_FIRST5 + 1)
 static char **OBM_Cursors_Data[NB_CURSORS] = 
 {
-    ocr_bummer,	   /* OCR_BUMMER */
-    ocr_dragobject,/* OCR_DRAGOBJECT */ 
-    ocr_normal,    /* OCR_NORMAL */
-    ocr_ibeam,     /* OCR_IBEAM */
-    ocr_wait,      /* OCR_WAIT */
-    ocr_cross,     /* OCR_CROSS */
-    ocr_up,        /* OCR_UP */
-    ocr_size,      /* OCR_SIZE */
-    ocr_icon,      /* OCR_ICON */
-    ocr_sizenwse,  /* OCR_SIZENWSE */
-    ocr_sizenesw,  /* OCR_SIZENESW */
-    ocr_sizewe,    /* OCR_SIZEWE */
-    ocr_sizens     /* OCR_SIZENS */
+    ocr_bummer,	     /* OCR_BUMMER */
+    ocr_dragobject,  /* OCR_DRAGOBJECT */ 
+    ocr_normal,      /* OCR_NORMAL */
+    ocr_ibeam,       /* OCR_IBEAM */
+    ocr_wait,        /* OCR_WAIT */
+    ocr_cross,       /* OCR_CROSS */
+    ocr_up,          /* OCR_UP */
+    ocr_size,        /* OCR_SIZE */
+    ocr_icon,        /* OCR_ICON */
+    ocr_sizenwse,    /* OCR_SIZENWSE */
+    ocr_sizenesw,    /* OCR_SIZENESW */
+    ocr_sizewe,      /* OCR_SIZEWE */
+    ocr_sizens,      /* OCR_SIZENS */
 #if 0
-    ocr_sizeall,   /* OCR_SIZEALL */
-    ocr_icocur     /* OCR_ICOCUR */
+    ocr_sizeall,     /* OCR_SIZEALL */
+    ocr_icocur       /* OCR_ICOCUR */
 #endif
+    ocr_no,          /* OCR_NO */
+    ocr_appstarting, /* OCR_APPSTARTING */
+    ocr_help         /* OCR_HELP */
 };
 
 static HGLOBAL16 OBM_Cursors[NB_CURSORS];
@@ -413,6 +437,12 @@
                   id = OCR_BASE2 + id - OCR_FIRST2;
 	     else if ((id >= OCR_FIRST0) && (id <= OCR_LAST0))
 		       id = OCR_BASE0 + id - OCR_FIRST0;
+		  else if ((id >= OCR_FIRST3) && (id <= OCR_LAST3))
+			    id = OCR_BASE3 + id - OCR_FIRST3;
+		       else if ((id >= OCR_FIRST4) && (id <= OCR_LAST4))
+				 id = OCR_BASE4 + id - OCR_FIRST4;
+			    else if ((id >= OCR_FIRST5) && (id <= OCR_LAST5))
+				      id = OCR_BASE5 + id - OCR_FIRST5;
         else return 0;
         if (OBM_Cursors[id]) return OBM_Cursors[id];
     }
@@ -498,7 +528,7 @@
 /***********************************************************************
  *           OBM_Init
  *
- * Initializes the OBM_Pixmaps_Data struct
+ * Initializes the OBM_Pixmaps_Data and OBM_Icons_Data struct
  */
 BOOL32 OBM_Init()
 {
@@ -508,6 +538,13 @@
 	OBM_Pixmaps_Data[OBM_ZOOM - OBM_FIRST].data = obm_zoom_95;
 	OBM_Pixmaps_Data[OBM_REDUCE - OBM_FIRST].data = obm_reduce_95;
 	OBM_Pixmaps_Data[OBM_CLOSE - OBM_FIRST].data = obm_close_95;
+        OBM_Pixmaps_Data[OBM_RESTORE - OBM_FIRST].data = obm_restore_95;
+        OBM_Pixmaps_Data[OBM_RESTORED - OBM_FIRST].data = obm_restored_95;
+
+        OBM_Icons_Data[OIC_HAND - OIC_FIRST] = oic_hand_95;
+        OBM_Icons_Data[OIC_QUES - OIC_FIRST] = oic_ques_95;
+        OBM_Icons_Data[OIC_BANG - OIC_FIRST] = oic_bang_95;
+        OBM_Icons_Data[OIC_NOTE - OIC_FIRST] = oic_note_95;
     }
     else {
 	OBM_Pixmaps_Data[OBM_ZOOMD - OBM_FIRST].data = obm_zoomd;
@@ -515,6 +552,13 @@
 	OBM_Pixmaps_Data[OBM_ZOOM - OBM_FIRST].data = obm_zoom;
 	OBM_Pixmaps_Data[OBM_REDUCE - OBM_FIRST].data = obm_reduce;
 	OBM_Pixmaps_Data[OBM_CLOSE - OBM_FIRST].data = obm_close;
+        OBM_Pixmaps_Data[OBM_RESTORE - OBM_FIRST].data = obm_restore;
+        OBM_Pixmaps_Data[OBM_RESTORED - OBM_FIRST].data = obm_restored;
+
+        OBM_Icons_Data[OIC_HAND - OIC_FIRST] = oic_hand;
+        OBM_Icons_Data[OIC_QUES - OIC_FIRST] = oic_ques;
+        OBM_Icons_Data[OIC_BANG - OIC_FIRST] = oic_bang;
+        OBM_Icons_Data[OIC_NOTE - OIC_FIRST] = oic_note;
     }
 
     return 1;
diff --git a/objects/palette.c b/objects/palette.c
index 3775e9f..e471148 100644
--- a/objects/palette.c
+++ b/objects/palette.c
@@ -85,16 +85,20 @@
 
 
 /***********************************************************************
- *           CreatePalette32    (GDI32.53)
+ * CreatePalette32 [GDI32.53]  Creates a logical color palette
+ *
+ * RETURNS
+ *    Success: Handle to logical palette
+ *    Failure: NULL
  */
-HPALETTE32 WINAPI CreatePalette32( const LOGPALETTE* palette )
+HPALETTE32 WINAPI CreatePalette32(
+    const LOGPALETTE* palette) /* [in] Pointer to logical color palette */
 {
     PALETTEOBJ * palettePtr;
     HPALETTE32 hpalette;
     int size = sizeof(LOGPALETTE) + (palette->palNumEntries - 1) * sizeof(PALETTEENTRY);
 
-    TRACE(palette,"%i entries \n",
-                    palette->palNumEntries);
+    TRACE(palette,"entries=%i\n", palette->palNumEntries);
 
     hpalette = GDI_AllocObject( size + sizeof(int*) +sizeof(GDIOBJHDR) , PALETTE_MAGIC );
     if (!hpalette) return 0;
@@ -110,15 +114,22 @@
     return hpalette;
 }
 
+
 /***********************************************************************
- *           CreateHalftonePalette   (GDI32.47)
+ * CreateHalftonePalette [GDI32.47]  Creates a halftone palette
+ *
+ * RETURNS
+ *    Success: Handle to logical halftone palette
+ *    Failure: 0
  */
-HPALETTE32 WINAPI CreateHalftonePalette(HDC32 hdc)
+HPALETTE32 WINAPI CreateHalftonePalette(
+    HDC32 hdc) /* [in] Handle to device context */
 {
-  FIXME(palette,"(%x): empty stub!\n", hdc);
-  return NULL;
+    FIXME(palette,"(%x): stub\n", hdc);
+    return NULL;
 }
 
+
 /***********************************************************************
  *           GetPaletteEntries16    (GDI.363)
  */
@@ -130,16 +141,22 @@
 
 
 /***********************************************************************
- *           GetPaletteEntries32    (GDI32.209)
+ * GetPaletteEntries32 [GDI32.209]  Retrieves palette entries
+ *
+ * RETURNS
+ *    Success: Number of entries from logical palette
+ *    Failure: 0
  */
-UINT32 WINAPI GetPaletteEntries32( HPALETTE32 hpalette, UINT32 start,
-                                   UINT32 count, LPPALETTEENTRY entries )
+UINT32 WINAPI GetPaletteEntries32(
+    HPALETTE32 hpalette,    /* [in]  Handle of logical palette */
+    UINT32 start,           /* [in]  First entry to receive */
+    UINT32 count,           /* [in]  Number of entries to receive */
+    LPPALETTEENTRY entries) /* [out] Address of array receiving entries */
 {
     PALETTEOBJ * palPtr;
     INT32 numEntries;
 
-    TRACE(palette,"hpal = %04x, %i entries\n",
-                     hpalette, count );
+    TRACE(palette,"hpal = %04x, count=%i\n", hpalette, count );
         
     palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
     if (!palPtr) return 0;
@@ -172,16 +189,22 @@
 
 
 /***********************************************************************
- *           SetPaletteEntries32    (GDI32.326)
+ * SetPaletteEntries32 [GDI32.326]  Sets color values for range in palette
+ *
+ * RETURNS
+ *    Success: Number of entries that were set
+ *    Failure: 0
  */
-UINT32 WINAPI SetPaletteEntries32( HPALETTE32 hpalette, UINT32 start,
-                                   UINT32 count, LPPALETTEENTRY entries )
+UINT32 WINAPI SetPaletteEntries32(
+    HPALETTE32 hpalette,    /* [in] Handle of logical palette */
+    UINT32 start,           /* [in] Index of first entry to set */
+    UINT32 count,           /* [in] Number of entries to set */
+    LPPALETTEENTRY entries) /* [in] Address of array of structures */
 {
     PALETTEOBJ * palPtr;
     INT32 numEntries;
 
-    TRACE(palette,"hpal = %04x, %i entries\n",
-                     hpalette, count );
+    TRACE(palette,"hpal=%04x,start=%i,count=%i\n",hpalette,start,count );
 
     palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
     if (!palPtr) return 0;
@@ -214,9 +237,15 @@
 
 
 /***********************************************************************
- *           ResizePalette32   (GDI32.289)
+ * ResizePalette32 [GDI32.289]  Resizes logical palette
+ *
+ * RETURNS
+ *    Success: TRUE
+ *    Failure: FALSE
  */
-BOOL32 WINAPI ResizePalette32( HPALETTE32 hPal, UINT32 cEntries )
+BOOL32 WINAPI ResizePalette32(
+    HPALETTE32 hPal, /* [in] Handle of logical palette */
+    UINT32 cEntries) /* [in] Number of entries in logical palette */
 {
     PALETTEOBJ * palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hPal, PALETTE_MAGIC );
     UINT32	 cPrevEnt, prevVer;
@@ -268,15 +297,22 @@
 
 
 /***********************************************************************
- *           AnimatePalette32   (GDI32.6)
+ * AnimatePalette32 [GDI32.6]  Replaces entries in logical palette
  *
- * FIXME: should use existing mapping when animating a primary palette
+ * RETURNS
+ *    Success: TRUE
+ *    Failure: FALSE
+ *
+ * FIXME
+ *    Should use existing mapping when animating a primary palette
  */
-BOOL32 WINAPI AnimatePalette32( HPALETTE32 hPal, UINT32 StartIndex,
-                               UINT32 NumEntries, LPPALETTEENTRY PaletteColors)
+BOOL32 WINAPI AnimatePalette32(
+    HPALETTE32 hPal,              /* [in] Handle to logical palette */
+    UINT32 StartIndex,            /* [in] First entry in palette */
+    UINT32 NumEntries,            /* [in] Count of entries in palette */
+    LPPALETTEENTRY PaletteColors) /* [in] Pointer to first replacement */
 {
-    TRACE(palette, "%04x (%i - %i)\n", hPal, 
-                    StartIndex, StartIndex + NumEntries );
+    TRACE(palette, "%04x (%i - %i)\n", hPal, StartIndex,StartIndex+NumEntries);
 
     if( hPal != STOCK_DEFAULT_PALETTE ) 
     {
@@ -307,12 +343,18 @@
 
 
 /***********************************************************************
- *           SetSystemPaletteUse32   (GDI32.335)
+ * SetSystemPaletteUse32 [GDI32.335]
+ *
+ * RETURNS
+ *    Success: Previous system palette
+ *    Failure: SYSPAL_ERROR
  */
-UINT32 WINAPI SetSystemPaletteUse32( HDC32 hdc, UINT32 use )
+UINT32 WINAPI SetSystemPaletteUse32(
+    HDC32 hdc,  /* [in] Handle of device context */
+    UINT32 use) /* [in] Palette-usage flag */
 {
     UINT32 old = SystemPaletteUse;
-    FIXME(palette,"(%04x,%04x): empty stub !!!\n", hdc, use );
+    FIXME(palette,"(%04x,%04x): stub\n", hdc, use );
     SystemPaletteUse = use;
     return old;
 }
@@ -328,9 +370,13 @@
 
 
 /***********************************************************************
- *           GetSystemPaletteUse32   (GDI32.223)
+ * GetSystemPaletteUse32 [GDI32.223]  Gets state of system palette
+ *
+ * RETURNS
+ *    Current state of system palette
  */
-UINT32 WINAPI GetSystemPaletteUse32( HDC32 hdc )
+UINT32 WINAPI GetSystemPaletteUse32(
+    HDC32 hdc) /* [in] Handle of device context */
 {
     return SystemPaletteUse;
 }
@@ -347,16 +393,22 @@
 
 
 /***********************************************************************
- *           GetSystemPaletteEntries32   (GDI32.222)
+ * GetSystemPaletteEntries32 [GDI32.222]  Gets range of palette entries
+ *
+ * RETURNS
+ *    Success: Number of entries retrieved from palette
+ *    Failure: 0
  */
-UINT32 WINAPI GetSystemPaletteEntries32( HDC32 hdc, UINT32 start, UINT32 count,
-                                         LPPALETTEENTRY entries )
+UINT32 WINAPI GetSystemPaletteEntries32(
+    HDC32 hdc,              /* [in]  Handle of device context */
+    UINT32 start,           /* [in]  Index of first entry to be retrieved */
+    UINT32 count,           /* [in]  Number of entries to be retrieved */
+    LPPALETTEENTRY entries) /* [out] Array receiving system-palette entries */
 {
     UINT32 i;
     DC *dc;
 
-    TRACE(palette, "hdc = %04x, "
-		    "cound = %i\n", hdc, count );
+    TRACE(palette, "hdc=%04x,start=%i,count=%i\n", hdc,start,count);
 
     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
     if (start >= dc->w.devCaps->sizePalette)
@@ -388,9 +440,18 @@
 
 
 /***********************************************************************
- *           GetNearestPaletteIndex32   (GDI32.203)
+ * GetNearestPaletteIndex32 [GDI32.203]  Gets palette index for color
+ *
+ * NOTES
+ *    Should index be initialized to CLR_INVALID instead of 0?
+ *
+ * RETURNS
+ *    Success: Index of entry in logical palette
+ *    Failure: CLR_INVALID
  */
-UINT32 WINAPI GetNearestPaletteIndex32( HPALETTE32 hpalette, COLORREF color )
+UINT32 WINAPI GetNearestPaletteIndex32(
+    HPALETTE32 hpalette, /* [in] Handle of logical color palette */
+    COLORREF color)      /* [in] Color to be matched */
 {
     PALETTEOBJ*	palObj = (PALETTEOBJ*)GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
     UINT32 index  = 0;
@@ -400,8 +461,7 @@
 				          palObj->logpalette.palNumEntries,
                                           NULL, color, FALSE );
 
-    TRACE(palette,"(%04x,%06lx): returning %d\n", 
-                    hpalette, color, index );
+    TRACE(palette,"(%04x,%06lx): returning %d\n", hpalette, color, index );
     GDI_HEAP_UNLOCK( hpalette );
     return index;
 }
@@ -417,9 +477,18 @@
 
 
 /***********************************************************************
- *           GetNearestColor32   (GDI32.202)
+ * GetNearestColor32 [GDI32.202]  Gets a system color to match
+ *
+ * NOTES
+ *    Should this return CLR_INVALID instead of FadeCafe?
+ *
+ * RETURNS
+ *    Success: Color from system palette that corresponds to given color
+ *    Failure: CLR_INVALID
  */
-COLORREF WINAPI GetNearestColor32( HDC32 hdc, COLORREF color )
+COLORREF WINAPI GetNearestColor32(
+    HDC32 hdc,      /* [in] Handle of device context */
+    COLORREF color) /* [in] Color to be matched */
 {
     COLORREF 	 nearest = 0xFADECAFE;
     DC 		*dc;
@@ -436,8 +505,7 @@
       GDI_HEAP_UNLOCK( dc->w.hPalette );
     }
 
-    TRACE(palette,"(%06lx): returning %06lx\n", 
-                    color, nearest );
+    TRACE(palette,"(%06lx): returning %06lx\n", color, nearest );
     GDI_HEAP_UNLOCK( hdc );    
     return nearest;
 }
@@ -610,20 +678,24 @@
 
 
 /***********************************************************************
- *           SelectPalette32    (GDI32.300)
+ * SelectPalette32 [GDI32.300]  Selects logical palette into DC
+ *
+ * RETURNS
+ *    Success: Previous logical palette
+ *    Failure: NULL
  */
-HPALETTE32 WINAPI SelectPalette32( HDC32 hDC, HPALETTE32 hPal,
-                                   BOOL32 bForceBackground )
+HPALETTE32 WINAPI SelectPalette32(
+    HDC32 hDC,               /* [in] Handle of device context */
+    HPALETTE32 hPal,         /* [in] Handle of logical color palette */
+    BOOL32 bForceBackground) /* [in] Foreground/background mode */
 {
     WORD	wBkgPalette = 1;
     PALETTEOBJ* lpt = (PALETTEOBJ*) GDI_GetObjPtr( hPal, PALETTE_MAGIC );
 
-    TRACE(palette,"dc %04x pal %04x, force=%i \n", 
-			    hDC, hPal, bForceBackground);
+    TRACE(palette,"dc=%04x,pal=%04x,force=%i\n", hDC, hPal, bForceBackground);
     if( !lpt ) return 0;
 
-    TRACE(palette," entries = %d\n", 
-			    lpt->logpalette.palNumEntries);
+    TRACE(palette," entries = %d\n", lpt->logpalette.palNumEntries);
     GDI_HEAP_UNLOCK( hPal );
 
     if( hPal != STOCK_DEFAULT_PALETTE )
@@ -651,9 +723,14 @@
 
 
 /***********************************************************************
- *           RealizePalette32    (GDI32.280)
+ * RealizePalette32 [GDI32.280]  Maps palette entries to system palette
+ *
+ * RETURNS
+ *    Success: Number of entries in logical palette
+ *    Failure: GDI_ERROR
  */
-UINT32 WINAPI RealizePalette32( HDC32 hDC )
+UINT32 WINAPI RealizePalette32(
+    HDC32 hDC) /* [in] Handle of device context */
 {
     UINT32 realized = GDIRealizePalette( hDC );
 
@@ -689,10 +766,16 @@
 
 
 /**********************************************************************
- *            UpdateColors32   (GDI32.359)
+ * UpdateColors32 [GDI32.359]  Remaps current colors to logical palette
+ *
+ * RETURNS
+ *    Success: TRUE
+ *    Failure: FALSE
  */
-BOOL32 WINAPI UpdateColors32( HDC32 hDC )
+BOOL32 WINAPI UpdateColors32(
+    HDC32 hDC) /* [in] Handle of device context */
 {
     UpdateColors16( hDC );
     return TRUE;
 }
+
diff --git a/objects/text.c b/objects/text.c
index c6e8b26..2172379 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -285,7 +285,7 @@
 
 
 /***********************************************************************
- *           DrawText32A    (USER32.163)
+ *           DrawText32A    (USER32.164)
  */
 INT32 WINAPI DrawText32A( HDC32 hdc, LPCSTR str, INT32 count,
                           LPRECT32 rect, UINT32 flags )
@@ -303,7 +303,7 @@
 
 
 /***********************************************************************
- *           DrawText32W    (USER32.166)
+ *           DrawText32W    (USER32.167)
  */
 INT32 WINAPI DrawText32W( HDC32 hdc, LPCWSTR str, INT32 count,
                           LPRECT32 rect, UINT32 flags )
@@ -315,7 +315,7 @@
 }
 
 /***********************************************************************
- *           DrawTextEx32A    (USER32.164)
+ *           DrawTextEx32A    (USER32.165)
  */
 INT32 DrawTextEx32A( HDC32 hdc, LPCSTR str, INT32 count,
                      LPRECT32 rect, UINT32 flags, LPDRAWTEXTPARAMS dtp )
@@ -326,7 +326,7 @@
 }
 
 /***********************************************************************
- *           DrawTextEx32W    (USER32.165)
+ *           DrawTextEx32W    (USER32.166)
  */
 INT32 DrawTextEx32W( HDC32 hdc, LPCWSTR str, INT32 count,
                      LPRECT32 rect, UINT32 flags, LPDRAWTEXTPARAMS dtp )
@@ -530,7 +530,7 @@
 
 
 /***********************************************************************
- *           GrayString32A   (USER32.314)
+ *           GrayString32A   (USER32.315)
  */
 BOOL32 WINAPI GrayString32A( HDC32 hdc, HBRUSH32 hbr, GRAYSTRINGPROC32 gsprc,
                              LPARAM lParam, INT32 cch, INT32 x, INT32 y,
@@ -541,7 +541,7 @@
 
 
 /***********************************************************************
- *           GrayString32W   (USER32.315)
+ *           GrayString32W   (USER32.316)
  */
 BOOL32 WINAPI GrayString32W( HDC32 hdc, HBRUSH32 hbr, GRAYSTRINGPROC32 gsprc,
                              LPARAM lParam, INT32 cch, INT32 x, INT32 y,
@@ -640,7 +640,7 @@
 
 
 /***********************************************************************
- *           TabbedTextOut32A    (USER32.541)
+ *           TabbedTextOut32A    (USER32.542)
  */
 LONG WINAPI TabbedTextOut32A( HDC32 hdc, INT32 x, INT32 y, LPCSTR lpstr,
                               INT32 count, INT32 cTabStops,
@@ -654,7 +654,7 @@
 
 
 /***********************************************************************
- *           TabbedTextOut32W    (USER32.542)
+ *           TabbedTextOut32W    (USER32.543)
  */
 LONG WINAPI TabbedTextOut32W( HDC32 hdc, INT32 x, INT32 y, LPCWSTR str,
                               INT32 count, INT32 cTabStops,
@@ -684,7 +684,7 @@
 
 
 /***********************************************************************
- *           GetTabbedTextExtent32A    (USER32.292)
+ *           GetTabbedTextExtent32A    (USER32.293)
  */
 DWORD WINAPI GetTabbedTextExtent32A( HDC32 hdc, LPCSTR lpstr, INT32 count, 
                                      INT32 cTabStops, const INT32 *lpTabPos )
@@ -697,7 +697,7 @@
 
 
 /***********************************************************************
- *           GetTabbedTextExtent32W    (USER32.293)
+ *           GetTabbedTextExtent32W    (USER32.294)
  */
 DWORD WINAPI GetTabbedTextExtent32W( HDC32 hdc, LPCWSTR lpstr, INT32 count, 
                                      INT32 cTabStops, const INT32 *lpTabPos )
@@ -711,25 +711,47 @@
 }
 
 /***********************************************************************
- *           GetTextCharset    (GDI32.226) (GDI.612)
+ * GetTextCharset32 [GDI32.226]  Gets character set for font in DC
+ *
+ * NOTES
+ *    Should it return a UINT32 instead of an INT32?
+ *
+ * RETURNS
+ *    Success: Character set identifier
+ *    Failure: DEFAULT_CHARSET
  */
-INT32 WINAPI GetTextCharset32(HDC32 hdc)
+INT32 WINAPI GetTextCharset32(
+    HDC32 hdc) /* [in] Handle to device context */
 {
-    FIXME(text,"(0x%x): stub\n",hdc);
-    return DEFAULT_CHARSET; 
+    /* MSDN docs say this is equivalent */
+    return GetTextCharsetInfo(hdc, NULL, 0);
 }
 
+/***********************************************************************
+ * GetTextCharset16 [GDI.612]
+ */
 INT16 WINAPI GetTextCharset16(HDC16 hdc)
 {
     return GetTextCharset32(hdc);
 }
 
 /***********************************************************************
- *           GetTextCharsetInfo    (GDI32.381)
+ * GetTextCharsetInfo [GDI32.381]  Gets character set for font
+ *
+ * NOTES
+ *    Should csi be an LPFONTSIGNATURE instead of an LPCHARSETINFO?
+ *    Should it return a UINT32 instead of an INT32?
+ *
+ * RETURNS
+ *    Success: Character set identifier
+ *    Failure: DEFAULT_CHARSET
  */
-INT32 WINAPI GetTextCharsetInfo(HDC32 hdc,LPCHARSETINFO csi,DWORD flags)
+INT32 WINAPI GetTextCharsetInfo(
+    HDC32 hdc,         /* [in]  Handle to device context */
+    LPCHARSETINFO csi, /* [out] Pointer to struct to receive data */
+    DWORD flags)       /* [in]  Reserved - must be 0 */
 {
-    FIXME(text,"(0x%x,%p,%08lx): stub!\n",hdc,csi,flags);
+    FIXME(text,"(0x%x,%p,%08lx): stub\n",hdc,csi,flags);
     if (csi) {
 	csi->ciCharset = DEFAULT_CHARSET;
 	csi->ciACP = GetACP();
diff --git a/ole/compobj.c b/ole/compobj.c
index 2f10e31..fc6346b 100644
--- a/ole/compobj.c
+++ b/ole/compobj.c
@@ -324,34 +324,23 @@
  *           StringFromGUID2 (OLE32.152)
  *
  * Converts a global unique identifier into a string of an API-
- * specified fixed format.
+ * specified fixed format. (The usual {.....} stuff.)
  *
- * mortene@pvv.org 980318
+ * RETURNS
+ *	The (UNICODE) string representation of the GUID in 'str'
+ *	The length of the resulting string, 0 if there was any problem.
  */
-OLESTATUS WINAPI
-StringFromGUID2(const REFGUID *id, LPOLESTR32 *str, INT32 cmax)
+INT32 WINAPI
+StringFromGUID2(REFGUID id, LPOLESTR32 str, INT32 cmax)
 {
-  int chars_in_string = strlen("[DDDDDDDD-WWWW-WWWW-WWWW-WWWWDDDDDDDD]")+1;
-  DWORD dwtmp[2];
-  WORD wtmp[4];
+  char		xguid[80];
 
-  if(cmax >= chars_in_string) {
-    dwtmp[0] = *(DWORD *)id;
-    wtmp[0] = *(WORD *)(id + sizeof(DWORD));
-    wtmp[1] = *(WORD *)(id + sizeof(DWORD) + sizeof(WORD));
-    wtmp[2] = *(WORD *)(id + sizeof(DWORD) + 2*sizeof(WORD));
-    wtmp[3] = *(WORD *)(id + sizeof(DWORD) + 3*sizeof(WORD));
-    dwtmp[1] = *(DWORD *)(id + sizeof(DWORD) + 4*sizeof(WORD));
-    sprintf(*(char **)str, "[%08lx-%04x-%04x-%04x-%04x%08lx]",
-	    dwtmp[0], wtmp[0], wtmp[1], wtmp[2], wtmp[3], dwtmp[1]);
-    TRACE(ole, "'%s'\n", *str);
-    return chars_in_string;
-  }
-  else {
-    WARN(ole, "Too little space in the string: need %d chars, got: %d\n",
-	 chars_in_string, cmax);
-    return 0;
-  }
+  if (WINE_StringFromCLSID(id,xguid))
+  	return 0;
+  if (strlen(xguid)>=cmax)
+  	return 0;
+  lstrcpyAtoW(str,xguid);
+  return strlen(xguid);
 }
 
 /***********************************************************************
diff --git a/ole/ole2disp.c b/ole/ole2disp.c
index e07538f..38d3399 100644
--- a/ole/ole2disp.c
+++ b/ole/ole2disp.c
@@ -94,7 +94,11 @@
 	return strlen(BSTR_GetAddr(str));
 }
 
-OLESTATUS WINAPI CreateDispTypeInfo(INTERFACEDATA * pidata,LCID lcid,LPVOID/*ITypeInfo*/ * * pptinfo) {
+OLESTATUS WINAPI CreateDispTypeInfo(
+    INTERFACEDATA * pidata,
+    LCID lcid,
+    LPVOID * * pptinfo) /* ITypeInfo */
+{
 	fprintf(stderr,"CreateDispTypeInfo(%p,%ld,%p),stub\n",pidata,lcid,pptinfo);
 	return 0;
 }
diff --git a/ole/typelib.c b/ole/typelib.c
index d988d03..4ad759d 100644
--- a/ole/typelib.c
+++ b/ole/typelib.c
@@ -34,7 +34,7 @@
 		WINE_StringFromCLSID(guid,xguid);
 	else
 		sprintf(xguid,"<guid 0x%08lx>",(DWORD)guid);
-	FIXME(ole,"(%s,%d,%d,0x%04x,%p),stub!\n",xguid,wMaj,wMin,lcid,path);
+	FIXME(ole,"(%s,%d,%d,0x%04lx,%p),stub!\n",xguid,wMaj,wMin,lcid,path);
 	return E_FAIL;
 }
 
diff --git a/programs/notepad/ChangeLog b/programs/notepad/ChangeLog
index 710022d..2c2987b 100644
--- a/programs/notepad/ChangeLog
+++ b/programs/notepad/ChangeLog
@@ -1,3 +1,7 @@
+Sun Mar 29 20:29:41 1998  Laurent Buffler <laurent@bluewin.ch>
+	* [Fr.rc]
+	Added French language support.
+
 Fri Feb 27 21:03:37 1998  Karl Backström <karl_b@geocities.com>
 	* Fixed some minor features.
 
diff --git a/programs/notepad/Fr.rc b/programs/notepad/Fr.rc
new file mode 100644
index 0000000..03102f6
--- /dev/null
+++ b/programs/notepad/Fr.rc
@@ -0,0 +1,90 @@
+/*
+ * Notepad (French resources)
+ *
+ * Copyright 1997 Marcel Baur <mbaur@g26.ethz.ch>
+ * Translation by Laurent Buffler <laurent@bluewin.ch>
+ */
+
+#define LANGUAGE_ID                  Fr
+#define LANGUAGE_NUMBER              3
+#define LANGUAGE_MENU_ITEM           "&Français"
+
+/* Menu */
+
+#define MENU_FILE                    "&Fichier"
+#define MENU_FILE_NEW                "&Nouveau..."
+#define MENU_FILE_OPEN               "&Ouvrir"
+#define MENU_FILE_SAVE               "&Sauver"
+#define MENU_FILE_SAVEAS             "S&auver sous..."
+#define MENU_FILE_PRINT              "Im&primer"
+#define MENU_FILE_PAGESETUP          "&Mise en page..."
+#define MENU_FILE_PRINTSETUP         "Imp&rimante..."
+#define MENU_FILE_EXIT               "&Quitter"
+
+#define MENU_EDIT                    "&Edition"
+#define MENU_EDIT_UNDO               "&Annuler\tCtrl+Z"
+#define MENU_EDIT_CUT                "Coupe&r\tCtrl+X"
+#define MENU_EDIT_COPY               "&Copier\tCtrl+C"
+#define MENU_EDIT_PASTE              "C&oller\tCtrl+V"
+#define MENU_EDIT_DELETE             "E&ffacer\tDel"
+#define MENU_EDIT_SELECTALL          "Tout &selectionner"
+#define MENU_EDIT_TIMEDATE           "&Heure/Date\tF5"
+#define MENU_EDIT_WRAP               "&Retour à la ligne"
+
+#define MENU_SEARCH                  "&Recherche"
+#define MENU_SEARCH_SEARCH           "&Chercher..."
+#define MENU_SEARCH_NEXT             "&Suivant\tF3"
+
+#define MENU_LANGUAGE                "&Langue"
+
+#define MENU_HELP                    "&Aide"
+#define MENU_HELP_CONTENTS           "&Sommaire"
+#define MENU_HELP_SEARCH             "&Chercher..."
+#define MENU_HELP_HELP_ON_HELP       "&Aide sur l'aide"
+
+#define MENU_INFO                    "Inf&o..."
+#define MENU_INFO_LICENSE            "&License"
+#define MENU_INFO_NO_WARRANTY        "&SANS GARANTIE"
+#define MENU_INFO_ABOUT_WINE         "&A propos de Wine"
+
+/* Dialogs */
+
+#define DIALOG_OK                    "OK"
+#define DIALOG_CANCEL                "Annuler"
+#define DIALOG_BROWSE                "&Parcourir..."
+#define DIALOG_HELP                  "&Aide"
+
+#define DIALOG_PAGESETUP_CAPTION     "Mise en page"
+#define DIALOG_PAGESETUP_HEAD        "&En-tête:"
+#define DIALOG_PAGESETUP_TAIL        "&Pied de page:"
+#define DIALOG_PAGESETUP_MARGIN      "&Marges:"
+#define DIALOG_PAGESETUP_LEFT        "&Gauche:"
+#define DIALOG_PAGESETUP_RIGHT       "&Droite:"
+#define DIALOG_PAGESETUP_TOP         "&Haut:"
+#define DIALOG_PAGESETUP_BOTTOM      "&Bas:"
+
+
+/* Strings */
+#define STRING_NOTEPAD               "Notepad"
+#define STRING_ERROR                 "ERREUR"
+#define STRING_WARNING               "AVERTISSEMENT"
+#define STRING_INFO                  "Information"
+
+#define STRING_UNTITLED              "(sans titre)"
+
+#define STRING_ALL_FILES              "Tous (*.*)"
+#define STRING_TEXT_FILES_TXT         "Fichiers texte (*.txt)"
+
+#define STRING_TOOLARGE         "Le fichier '%s' est trop grand pour le bloc note.\n \
+Veuillez utiliser un autre éditeur."
+
+#define STRING_NOTEXT           "Vous n'avez pas entré de texte. \
+\nVeuillez taper quelque chose et recommencer"
+
+#define STRING_NOTFOUND         "'%s' introuvable."
+
+#define STRING_OUT_OF_MEMORY    "Pas assez de mémoire pour finir cette tâche. \
+\nFermez une ou plusier applications pour libérer \n \
+de la mémoire."
+
+#include "notepad.rc"
diff --git a/programs/notepad/Makefile.in b/programs/notepad/Makefile.in
index fa945ad..3d62b9a 100644
--- a/programs/notepad/Makefile.in
+++ b/programs/notepad/Makefile.in
@@ -8,7 +8,7 @@
 ALL_LIBS  = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS)
 RCFLAGS   = -w32 -h
 
-LANGUAGES   = En De Sw
+LANGUAGES   = En De Fr Sw
 LICENSELANG = En
 
 MOSTSRCS = \
diff --git a/programs/notepad/TODO b/programs/notepad/TODO
index bb55f48..c7a2bc3 100644
--- a/programs/notepad/TODO
+++ b/programs/notepad/TODO
@@ -1,4 +1,6 @@
 
+ - Logfile feature
+
  - Notepad segfaults when selecting "Find" button in "Search" dialog.
  
  - create new *.rc files for all languages you know.
diff --git a/programs/notepad/license.c b/programs/notepad/license.c
index b10f2e3..9ff62a6 100644
--- a/programs/notepad/license.c
+++ b/programs/notepad/license.c
@@ -7,23 +7,25 @@
 
 static LICENSE* SelectLanguage(LPCSTR Language)
 {
-/*  if (lstrcmp(Language, "Cz")) return(&WineLicense_Cz); */
-/*  if (lstrcmp(Language, "Da")) return(&WineLicense_Da); */
-/*  if (lstrcmp(Language, "De")) return(&WineLicense_En); */
-/*  if (lstrcmp(Language, "En")) return(&WineLicense_En); */
-/*  if (lstrcmp(Language, "Eo")) return(&WineLicense_Eo); */
-/*  if (lstrcmp(Language, "Es")) return(&WineLicense_Es); */
-/*  if (lstrcmp(Language, "Fi")) return(&WineLicense_Fi); */
-/*  if (lstrcmp(Language, "Fr")) return(&WineLicense_Fr); */
-/*  if (lstrcmp(Language, "Hu")) return(&WineLicense_Hu); */
-/*  if (lstrcmp(Language, "It")) return(&WineLicense_It); */
-/*  if (lstrcmp(Langauge, "Ko")) return(&WineLicense_Ko); */
-/*  if (lstrcmp(Language, "No")) return(&WineLicense_No); */
-/*  if (lstrcmp(Language, "Pl")) return(&WineLicense_Pl); */
-/*  if (lstrcmp(Language, "Po")) return(&WineLicense_Po); */
-/*  if (lstrcmp(Language, "Va")) return(&WineLicense_Va); */
-/*  if (lstrcmp(Language, "Sw")) return(&WineLicense_Sw); */
-/*  if (lstrcmp(Language, "Ca")) return(&WineLicense_Ca); */
+/*  
+  if (lstrcmp(Language, "Ca")) return(&WineLicense_Ca);
+  if (lstrcmp(Language, "Cz")) return(&WineLicense_Cz);
+  if (lstrcmp(Language, "Da")) return(&WineLicense_Da);
+  if (lstrcmp(Language, "De")) return(&WineLicense_En);
+  if (lstrcmp(Language, "En")) return(&WineLicense_En);
+  if (lstrcmp(Language, "Eo")) return(&WineLicense_Eo);
+  if (lstrcmp(Language, "Es")) return(&WineLicense_Es);
+  if (lstrcmp(Language, "Fi")) return(&WineLicense_Fi);
+  if (lstrcmp(Language, "Fr")) return(&WineLicense_Fr);
+  if (lstrcmp(Language, "Hu")) return(&WineLicense_Hu);
+  if (lstrcmp(Language, "It")) return(&WineLicense_It);
+  if (lstrcmp(Langauge, "Ko")) return(&WineLicense_Ko); 
+  if (lstrcmp(Language, "No")) return(&WineLicense_No);   
+  if (lstrcmp(Language, "Pl")) return(&WineLicense_Pl);
+  if (lstrcmp(Language, "Po")) return(&WineLicense_Po);
+  if (lstrcmp(Language, "Va")) return(&WineLicense_Va);
+  if (lstrcmp(Language, "Sw")) return(&WineLicense_Sw);
+*/
   return(&WineLicense_En);
 }
 
diff --git a/programs/notepad/license.h b/programs/notepad/license.h
index 5f99cdf..20fac2e 100644
--- a/programs/notepad/license.h
+++ b/programs/notepad/license.h
@@ -11,20 +11,26 @@
   LPCSTR Warranty, WarrantyCaption;
 } LICENSE;
 
-/* extern LICENSE WineLicense_Cz; */
-/* extern LICENSE WineLicense_Da; */
-/* extern LICENSE WineLicense_De; */
+/* 
+extern LICENSE WineLicense_Ca;
+extern LICENSE WineLicense_Cz;
+extern LICENSE WineLicense_Da;
+extern LICENSE WineLicense_De;
+*/
+
 extern LICENSE WineLicense_En;
-/* extern LICENSE WineLicense_Eo; */
-/* extern LICENSE WineLicense_Es; */
-/* extern LICENSE WineLicense_Fi; */
-/* extern LICENSE WineLicense_Fr; */
-/* extern LICENSE WineLicense_Hu; */
-/* extern LICENSE WineLicense_It; */
-/* extern LICENSE WineLicense_Ko; */
-/* extern LICENSE WineLicense_No; */
-/* extern LICENSE WineLicense_Pl; */
-/* extern LICENSE WineLicense_Po; */
-/* extern LICENSE WineLicense_Va; */
-/* extern LICENSE WineLicense_Sw; */
-/* extern LICENSE WineLicense_Ca; */
+
+/* 
+extern LICENSE WineLicense_Eo;
+extern LICENSE WineLicense_Es;
+extern LICENSE WineLicense_Fi;
+extern LICENSE WineLicense_Fr;
+extern LICENSE WineLicense_Hu;
+extern LICENSE WineLicense_It;
+extern LICENSE WineLicense_Ko;
+extern LICENSE WineLicense_No;
+extern LICENSE WineLicense_Pl;
+extern LICENSE WineLicense_Po;
+extern LICENSE WineLicense_Va;
+extern LICENSE WineLicense_Sw;
+*/
diff --git a/programs/notepad/main.c b/programs/notepad/main.c
index 88493c4..4b434a2 100644
--- a/programs/notepad/main.c
+++ b/programs/notepad/main.c
@@ -30,8 +30,6 @@
 
 int NOTEPAD_MenuCommand (WPARAM wParam)
 {  
-//   printf("NOTEPAD_MenuCommand()\n");
-
    switch (wParam) {
      case NP_FILE_NEW:          DIALOG_FileNew(); break;
      case NP_FILE_OPEN:         DIALOG_FileOpen(); break;
@@ -82,22 +80,18 @@
     switch (msg) {
 
        case WM_CREATE:
-        printf("WM_CREATE\n");
    	break;
 
-        case WM_PAINT:
-	  printf("WM_PAINT\n");
+       case WM_PAINT:
           BeginPaint(hWnd, &ps);
           EndPaint(hWnd, &ps);
    	break;
 
        case WM_COMMAND:
-          printf("WM_COMMAND\n");
           NOTEPAD_MenuCommand(wParam);
           break;
 
        case WM_DESTROY:
-          printf("WM_DESTROY\n");
           PostQuitMessage (0);
           break;
 
diff --git a/programs/view/globals.h b/programs/view/globals.h
index 9889911..5577af6 100644
--- a/programs/view/globals.h
+++ b/programs/view/globals.h
@@ -1,4 +1,7 @@
 
+/* for SMALL_RECT */
+#include "wincon.h" 
+
 /*  Add global function prototypes here */
 
 BOOL InitApplication(HINSTANCE);
@@ -16,18 +19,7 @@
 extern char      szTitle[];      /* The title bar text */
 
 
-#ifdef WINELIB
-typedef struct
-{
-	DWORD	key WINE_PACKED;
-	HANDLE16	hmf WINE_PACKED;
-	RECT16	bbox WINE_PACKED;
-	WORD	inch WINE_PACKED;
-	DWORD	reserved WINE_PACKED;
-	WORD	checksum WINE_PACKED;
-} APMFILEHEADER WINE_PACKED;
-#else
-#pragma pack( 2 )
+#pragma pack(1)
 typedef struct
 {
 	DWORD		key;
@@ -37,7 +29,6 @@
 	DWORD		reserved;
 	WORD		checksum;
 } APMFILEHEADER;
-#endif
 
 #define APMHEADER_KEY	0x9AC6CDD7l
 
diff --git a/programs/view/init.c b/programs/view/init.c
index eeaa149..e6e20da 100644
--- a/programs/view/init.c
+++ b/programs/view/init.c
@@ -24,7 +24,7 @@
 
   /* Load small icon image */
   wc.hIconSm = LoadImage(hInstance,		
-			 MAKEINTRESOURCE(IDI_APPICON),
+			 MAKEINTRESOURCE32A(IDI_APPICON),
 			 IMAGE_ICON,
 			 16, 16,
 			 0);
diff --git a/programs/view/resource.h b/programs/view/resource.h
index 0ff2b5c..d11da04 100644
--- a/programs/view/resource.h
+++ b/programs/view/resource.h
@@ -4,6 +4,7 @@
 #define IDM_EXIT                        1000
 #define IDM_HELLO                       501
 #define IDM_OPEN                        502
+#define IDM_SET_EXT_TO_WIN              503
 #define IDM_LEFT                        601
 #define IDM_RIGHT                       602
 #define IDM_UP                          603
diff --git a/programs/view/view.c b/programs/view/view.c
index d49483c..3963293 100644
--- a/programs/view/view.c
+++ b/programs/view/view.c
@@ -14,7 +14,7 @@
 #include <stdio.h>
 
 BOOL FileIsPlaceable( LPCSTR szFileName );
-HMETAFILE GetPlaceableMetaFile( LPCSTR szFileName );
+HMETAFILE GetPlaceableMetaFile( HWND hwnd, LPCSTR szFileName );
 
 #define FN_LENGTH 80
 
@@ -26,7 +26,7 @@
 BOOL FileOpen(HWND hWnd, char *fn)
 {
   OPENFILENAME ofn = { sizeof(OPENFILENAME),
-		       0, NULL, "Metafiles\0*.wmf\0", NULL, 0, 0, NULL, 
+		       0, 0, "Metafiles\0*.wmf\0", NULL, 0, 0, NULL, 
 		       FN_LENGTH, NULL, 0, NULL, NULL, OFN_CREATEPROMPT |
 		       OFN_SHOWHELP, 0, 0, NULL, 0, NULL };
   ofn.hwndOwner = hWnd;
@@ -47,7 +47,7 @@
 	PAINTSTRUCT ps; 
 	BeginPaint(hwnd, &ps);
 	SetMapMode(ps.hdc, MM_ANISOTROPIC);
-	SetViewportExt(ps.hdc, width, height);
+	SetViewportExtEx(ps.hdc, width, height, NULL);
 	SetViewportOrgEx(ps.hdc, deltax, deltay, NULL);
 	if(hmf) PlayMetaFile(ps.hdc, hmf);
 	EndPaint(hwnd, &ps);
@@ -68,7 +68,7 @@
 	    if (FileOpen(hwnd, filename)) {
 	      isAldus = FileIsPlaceable(filename);
 	      if (isAldus) {
-		hmf = GetPlaceableMetaFile(filename);
+		hmf = GetPlaceableMetaFile(hwnd, filename);
 	      } else {
 		RECT r;
 		hmf = GetMetaFile(filename);
@@ -81,6 +81,17 @@
 	  }
 	  break;
 	  
+	case IDM_SET_EXT_TO_WIN:
+	  {
+	    RECT r;
+	    GetClientRect(hwnd, &r);
+	    width = r.right - r.left;
+	    height = r.bottom - r.top;
+	    InvalidateRect( hwnd, NULL, TRUE );
+	  }
+	  break;
+
+	  
 	case IDM_LEFT:
 	  deltax += 100;
 	  InvalidateRect( hwnd, NULL, TRUE );
@@ -138,7 +149,7 @@
   return (apmh.key == APMHEADER_KEY);
 }
 
-HMETAFILE GetPlaceableMetaFile( LPCSTR szFileName )
+HMETAFILE GetPlaceableMetaFile( HWND hwnd, LPCSTR szFileName )
 {
   LPSTR	lpData;
   METAHEADER mfHeader;
@@ -162,31 +173,34 @@
     char msg[128];
     sprintf(msg, "Computed checksum %04x != stored checksum %04x\n", 
 	   checksum, APMHeader.checksum);
-    /*    MessageBox(hwnd, msg, "Checksum failed", MB_OK); */
+        MessageBox(hwnd, msg, "Checksum failed", MB_OK);
     return 0;
   }
 
   if (!_lread(fh, (LPSTR)&mfHeader, sizeof(METAHEADER))) return 0;
 
-  if (!(lpData = GlobalAlloc(GPTR, (mfHeader.mtSize * 2L)))) return 0;
+  if (!(lpData = (LPSTR) GlobalAlloc(GPTR, (mfHeader.mtSize * 2L)))) return 0;
 
   _llseek(fh, sizeof(APMFILEHEADER), 0);
   if (!_lread(fh, lpData, (UINT)(mfHeader.mtSize * 2L)))
   {
     GlobalFree(lpData);
     _lclose(fh);
-    return NULL;
+    return 0;
   }
   _lclose(fh);
 
   if (!(hmf = SetMetaFileBitsEx(mfHeader.mtSize*2, lpData))) 
-    return NULL;
+    return 0;
 
   
-  width = APMHeader.bbox.right - APMHeader.bbox.left;
-  height = APMHeader.bbox.bottom - APMHeader.bbox.top;
+  width = APMHeader.bbox.Right - APMHeader.bbox.Left;
+  height = APMHeader.bbox.Bottom - APMHeader.bbox.Top;
 
-  /*  printf("Ok! width %d height %d\n", width, height); */
+  /*      printf("Ok! width %d height %d inch %d\n", width, height, APMHeader.inch);  */
+  width = width*96/APMHeader.inch;
+  height = height*96/APMHeader.inch;
+
   deltax = 0;
   deltay = 0 ;
   return hmf;
diff --git a/programs/view/viewrc.rc b/programs/view/viewrc.rc
index c493950..c3eb400 100644
--- a/programs/view/viewrc.rc
+++ b/programs/view/viewrc.rc
@@ -21,6 +21,8 @@
     END
     POPUP "&Pan"
     BEGIN
+      MENUITEM "&Scale to Window",              IDM_SET_EXT_TO_WIN
+      MENUITEM SEPARATOR
       MENUITEM "&Left",				IDM_LEFT
       MENUITEM "&Right",			IDM_RIGHT
       MENUITEM "&Up",				IDM_UP
diff --git a/rc/winerc.c b/rc/winerc.c
index 4a9fa3f..8a801ef 100644
--- a/rc/winerc.c
+++ b/rc/winerc.c
@@ -850,15 +850,15 @@
         int type;
         switch(it->type)
         {
-        case acc:type=(int)RT_ACCELERATOR;break;
-        case bmp:type=(int)RT_BITMAP;break;
-        case cur:type=(int)RT_CURSOR;break;
-        case dlg:type=(int)RT_DIALOG;break;
-        case fnt:type=(int)RT_FONT;break;
-        case ico:type=(int)RT_ICON;break;
-        case men:type=(int)RT_MENU;break;
-        case rdt:type=(int)RT_RCDATA;break;
-        case str:type=(int)RT_STRING;break;
+        case acc:type=(int)RT_ACCELERATOR16;break;
+        case bmp:type=(int)RT_BITMAP16;break;
+        case cur:type=(int)RT_CURSOR16;break;
+        case dlg:type=(int)RT_DIALOG16;break;
+        case fnt:type=(int)RT_FONT16;break;
+        case ico:type=(int)RT_ICON16;break;
+        case men:type=(int)RT_MENU16;break;
+        case rdt:type=(int)RT_RCDATA16;break;
+        case str:type=(int)RT_STRING16;break;
         default:fprintf(stderr,"Unknown restype\n");type=-1;break;
         }
 	if(win32)
diff --git a/relay32/builtin32.c b/relay32/builtin32.c
index b5e79aa..baa32d7 100644
--- a/relay32/builtin32.c
+++ b/relay32/builtin32.c
@@ -93,7 +93,7 @@
     { &W32SKRNL_Descriptor, NULL, TRUE  },
     { &WINMM_Descriptor,    NULL, TRUE  },
     { &WINSPOOL_Descriptor, NULL, TRUE  },
-    { &WOW32_Descriptor,    NULL, FALSE },
+    { &WOW32_Descriptor,    NULL, TRUE },
     { &WSOCK32_Descriptor,  NULL, TRUE  },
     /* Last entry */
     { NULL, NULL, FALSE }
diff --git a/relay32/comctl32.spec b/relay32/comctl32.spec
index 34f968d..5f3956c 100644
--- a/relay32/comctl32.spec
+++ b/relay32/comctl32.spec
@@ -13,9 +13,9 @@
   6 stdcall CreateStatusWindowA(long ptr long long) CreateStatusWindow32A
   7 stub CreateToolbar
   8 stub CreateMappedBitmap
-#  9 stub COMCTL32_9
-# 10 stub COMCTL32_10
-# 11 stub COMCTL32_11
+  9 stub COMCTL32_9
+ 10 stub COMCTL32_10
+ 11 stub COMCTL32_11
  12 stub Cctl1632_ThunkData32
  13 stub MakeDragList
  14 stub LBItemFromPt
@@ -72,15 +72,16 @@
  63 stdcall ImageList_LoadImageA(long ptr long long long long long) ImageList_LoadImage32A
  64 stdcall ImageList_LoadImageW(long ptr long long long long long) ImageList_LoadImage32W
  65 stdcall ImageList_Merge(ptr long ptr long long long) ImageList_Merge
+# 66 stdcall ImageList_Read(ptr) ImageList_Read
  66 stub ImageList_Read
  67 stdcall ImageList_Remove(ptr long) ImageList_Remove
  68 stdcall ImageList_Replace(ptr long long long) ImageList_Replace
  69 stdcall ImageList_ReplaceIcon(ptr long long) ImageList_ReplaceIcon
  70 stdcall ImageList_SetBkColor(ptr long) ImageList_SetBkColor
-# 71
-# 72
-# 73
-# 74 stub GetSize # 1 parameter
+ 71 stub Alloc
+ 72 stub ReAlloc
+ 73 stub Free
+ 74 stub GetSize
  75 stdcall ImageList_SetDragCursorImage(ptr long long long) ImageList_SetDragCursorImage
  76 stub ImageList_SetFilter
  77 stdcall ImageList_SetIconSize(ptr long long) ImageList_SetIconSize
@@ -95,58 +96,95 @@
  86 stub UninitializeFlatSB
  87 stub _TrackMouseEvent
 
-#151
-#152 stub FreeMRUList  # 1 parameter
-#153
-#154
-#155 stub FindMRUStringA  # 3 parameters
-#156
-#157
-#163
-#164
-#167
-#169 stub FindMRUData
-#233 - 236
+151 stub CreateMRUList
+152 stub FreeMRUList
+153 stub AddMRUStringA
+154 stub EnumMRUListA
+155 stub FindMRUStringA
+156 stub DelMRUString
+157 stub COMCTL32_157
 
-#320
-#321
-#322
-#323
-#324
-#325
-#326
-#327
-#328
-#329 stub DPA_Create
-#330 stub DPA_Destroy
-#331
-#332 stub DPA_GetPtr
-#333
-#334 stub DPA_InsertPtr
-#335
-#336 stub DPA_DeletePtr
-#337
-#338
-#339 stub DPA_Search
-#340
-#341
-#342
+163 stub CreatePage
+164 stub CreateProxyPage
 
-#350 stub StrChrA
-#351
-#352 stub StrCmpA
-#353
-#354 stub StrStrA
-#355
-#356
-#357 stub StrToIntA
-#358 - 369
+167 stub AddMRUData
+169 stub FindMRUData
 
-#372 - 375
-#376 stub IntlStrEqWorkerA
-#377 stub IntlStrEqWorkerW
-#382
-#383 stub DoReaderMode
-#384 - 390
-#400 - 404
-#410 - 413
+233 stub Str_GetPtrA
+234 stub Str_SetPtrA
+235 stub Str_GetPtrW
+236 stub Str_SetPtrW
+
+320 stub DSA_Create
+321 stub DSA_Destroy
+322 stub DSA_GetItem
+323 stub DSA_GetItemPtr
+324 stub DSA_InsertItem
+325 stub DSA_SetItem
+326 stub DSA_DeleteItem
+327 stub DSA_DeleteAllItems
+328 stub DPA_Create
+329 stub DPA_Destroy
+330 stub DPA_Grow
+331 stub DPA_Clone
+332 stub DPA_GetPtr
+333 stub DPA_GetPtrIndex
+334 stub DPA_InsertPtr
+335 stub DPA_SetPtr
+336 stub DPA_DeletePtr
+337 stub DPA_DeleteAllPtrs
+338 stub DPA_Sort
+339 stub DPA_Search
+340 stub DPA_CreateEx
+341 stub SendNotify
+342 stub SendNotifyEx
+
+350 stub StrChrA
+351 stub StrRChr
+352 stub StrCmpNA
+353 stub StrCmpNIA
+354 stub StrStrA
+355 stub StrStrIA
+356 stub StrCSpnA
+357 stub StrToIntA
+358 stub StrChrW
+359 stub StrRChrW
+360 stub StrCmpNW
+361 stub StrCmpNIW
+362 stub StrStrW
+363 stub StrStrIW
+364 stub StrSpnW
+365 stub StrToIntW
+366 stub StrChrIA
+367 stub StrChrIW
+368 stub StrRChrIA
+369 stub StrRChrIW
+
+372 stub StrRStrIA
+373 stub StrRStrIW
+374 stub StrCSpnIA
+375 stub StrCSpnIW
+376 stub IntlStrEqWorkerA
+377 stub IntlStrEqWorkerW
+
+382 stub SmoothScrollWindow
+383 stub DoReaderMode
+384 stub SetPathWordBreakProc
+385 stub COMCTL32_385
+386 stub COMCTL32_386
+387 stub COMCTL32_387
+388 stub COMCTL32_388
+389 stub COMCTL32_389
+390 stub COMCTL32_390
+
+400 stub COMCTL32_400
+401 stub COMCTL32_401
+402 stub COMCTL32_402
+403 stub COMCTL32_403
+404 stub COMCTL32_404
+
+410 stub COMCTL32_410
+411 stub COMCTL32_411
+412 stub COMCTL32_412
+413 stub COMCTL32_413
+
diff --git a/relay32/comdlg32.spec b/relay32/comdlg32.spec
index c5aeb46..14de9bd 100644
--- a/relay32/comdlg32.spec
+++ b/relay32/comdlg32.spec
@@ -7,8 +7,8 @@
  3 stdcall ChooseFontA(ptr) ChooseFont32A
  4 stub ChooseFontW
  5 stdcall CommDlgExtendedError() CommDlgExtendedError
- 6 stub FindTextA
- 7 stub FindTextW
+ 6 stdcall FindTextA(ptr) FindText32A
+ 7 stdcall FindTextW(ptr) FindText32W
  8 stdcall GetFileTitleA(ptr ptr long) GetFileTitle32A
  9 stdcall GetFileTitleW(ptr ptr long) GetFileTitle32W
 10 stdcall GetOpenFileNameA(ptr) GetOpenFileName32A
@@ -20,8 +20,8 @@
 16 stub PageSetupDlgW
 17 stdcall PrintDlgA(ptr) PrintDlg32A
 18 stdcall PrintDlgW(ptr) PrintDlg32W
-19 stub ReplaceTextA
-20 stub ReplaceTextW
+19 stdcall ReplaceTextA(ptr) ReplaceText32A
+20 stdcall ReplaceTextW(ptr) ReplaceText32W
 21 stub WantArrows
 22 stub dwLBSubclass
 23 stub dwOKSubclass
diff --git a/relay32/crtdll.spec b/relay32/crtdll.spec
index b80e9fc..01274c5 100644
--- a/relay32/crtdll.spec
+++ b/relay32/crtdll.spec
@@ -391,7 +391,7 @@
 387 stub fwscanf
 388 cdecl getc(ptr) CRTDLL_getc
 389 stub getchar
-390 stub getenv
+390 cdecl getenv (str) CRTDLL_getenv
 391 cdecl gets(ptr) CRTDLL_gets
 392 cdecl gmtime(ptr) gmtime
 393 stub is_wctype
diff --git a/relay32/gdi32.spec b/relay32/gdi32.spec
index 51a55ce..a741b2d 100644
--- a/relay32/gdi32.spec
+++ b/relay32/gdi32.spec
@@ -72,7 +72,7 @@
  65 stdcall DPtoLP(long ptr long) DPtoLP32
  66 stub DeleteColorSpace
  67 stdcall DeleteDC(long) DeleteDC32
- 68 stdcall DeleteEnhMetaFile(long) DeleteEnhMetaFile32
+ 68 stdcall DeleteEnhMetaFile(long) DeleteEnhMetaFile
  69 stdcall DeleteMetaFile(long) DeleteMetaFile32
  70 stdcall DeleteObject(long)	DeleteObject32
  71 stub DescribePixelFormat
@@ -182,7 +182,7 @@
 175 stub GetEnhMetaFileBits
 176 stdcall GetEnhMetaFileDescriptionA(long long ptr) GetEnhMetaFileDescription32A
 177 stub GetEnhMetaFileDescriptionW
-178 stdcall GetEnhMetaFileHeader(long long ptr) GetEnhMetaFileHeader32
+178 stdcall GetEnhMetaFileHeader(long long ptr) GetEnhMetaFileHeader
 179 stub GetEnhMetaFilePaletteEntries
 180 stub GetEnhMetaFileW
 181 stub GetFontData
@@ -267,8 +267,8 @@
 260 stdcall PatBlt(long long long long long long) PatBlt32
 261 stdcall PathToRegion(long) PathToRegion32
 262 stdcall Pie(long long long long long long long long long) Pie32
-263 stdcall PlayEnhMetaFile(long long ptr) PlayEnhMetaFile32
-264 stdcall PlayEnhMetaFileRecord(long ptr ptr long) PlayEnhMetaFileRecord32
+263 stdcall PlayEnhMetaFile(long long ptr) PlayEnhMetaFile
+264 stdcall PlayEnhMetaFileRecord(long ptr ptr long) PlayEnhMetaFileRecord
 265 stdcall PlayMetaFile(long long) PlayMetaFile32
 266 stdcall PlayMetaFileRecord(long ptr ptr long) PlayMetaFileRecord32
 267 stub PlgBlt
diff --git a/relay32/kernel32.spec b/relay32/kernel32.spec
index 8b0f1b3..b4cbeb2 100644
--- a/relay32/kernel32.spec
+++ b/relay32/kernel32.spec
@@ -6,8 +6,11 @@
 #  import kernel32.dll by ordinal)
 # the base is NOT included in these ordinals
 
-# undocumented ordinal only calls (names taken from k32exp.h by Andrew
-# Schulman.
+# names of undocumented ordinal only calls are taken from:
+# - k32exp.h by Andrew Schulman
+# - error messages and strings from the debug version of kernel32.dll
+# - code generated by the MS Thunk Compiler
+
   1 stub VxDCall0
   2 stub VxDCall1
   3 stub VxDCall2
@@ -17,33 +20,50 @@
   7 stub VxDCall6
   8 stub VxDCall7
   9 stub VxDCall8
- 
- 10 stub _KERNEL32_stringconv1 #ansi2oem or reverse?
- 
- 17 stub _KERNEL32_17
- 18 stdcall _KERNEL32_18(long long) _KERNEL32_18
- 19 stub _KERNEL32_getheapsegment
- 
- 31 stub _KERNEL32_31
- 
- 34 stdcall _KERNEL32_34() _KERNEL32_34
+ 10 stdcall CharToOemA(str str) CharToOem32A
+ 11 stdcall CharToOemBuffA(str str long) CharToOemBuff32A
+ 12 stdcall OemToCharA(ptr ptr) OemToChar32A
+ 13 stdcall OemToCharBuffA(ptr ptr long) OemToCharBuff32A
+ 14 stdcall LoadStringA(long long ptr long) LoadString32A
+ 15 varargs wsprintfA() wsprintf32A
+ 16 stdcall wvsprintfA() wvsprintf32A
+ 17 stub _KERNEL32_17_VDMCall
+ 18 stdcall GetProcessDWORD(long long) GetProcessDWORD
+ 19 stub TheTemplateHandle
+ 20 stub _KERNEL32_20_FakeWin32HandleFromDOSFileHandle
+ 21 stub _KERNEL32_21_GetDOSFileHandleFromWin32Handle
+ 22 stub _KERNEL32_22_CleanupFakeWin32Handle
+ 23 stub _KERNEL32_23
+ 24 stdcall GlobalAlloc16(long long) GlobalAlloc16
+ 25 stdcall GlobalLock16(long) GlobalLock16
+ 26 stdcall GlobalUnlock16(long) GlobalUnlock16
+ 27 stdcall GlobalFix16(long) GlobalFix16
+ 28 stdcall GlobalUnfix16(long) GlobalUnfix16
+ 29 stdcall GlobalWire16(long) GlobalWire16
+ 30 stdcall GlobalUnWire16(long) GlobalUnWire16
+ 31 stdcall GlobalFree16(long) GlobalFree16
+ 32 stdcall GlobalSize16(long) GlobalSize16
+ 33 stub _KERNEL32_33
+ 34 stdcall GetWin16DOSEnv() GetWin16DOSEnv
  35 stdcall LoadLibrary16(str) LoadLibrary16
  36 stdcall FreeLibrary16(long) FreeLibrary16
  37 stdcall GetProcAddress16(long str) WIN32_GetProcAddress16
- 
+ 38 register AllocMappedBuffer() AllocMappedBuffer
+ 39 register FreeMappedBuffer() FreeMappedBuffer
  40 register _KERNEL32_40() _KERNEL32_40
- 41 stdcall _KERNEL32_41(long str long str str) _KERNEL32_41
- 42 stub _KERNEL32_42
- 43 stdcall _KERNEL32_43(long str long str str) _KERNEL32_43
- 45 register _KERNEL32_45() _KERNEL32_45 
- 46 stdcall _KERNEL32_46(long str long str str) _KERNEL32_46
- 47 stub _KERNEL32_47
- 
+ 41 stdcall ThunkInitLSF(long str long str str) ThunkInitLSF
+ 42 stub _DebugThunkLSF
+ 43 stdcall ThunkInitLS(long str long str str) ThunkInitLS
+ 44 stub _DebugThunkLS
+ 45 register Common32ThkLS() Common32ThkLS 
+ 46 stdcall ThunkInitSL(long str long str str) ThunkInitSL
+ 47 stub _DebugThunkSL
+ 48 stub ReleaseThunkLock
+ 49 stub RestoreThunkLock
  50 stdcall AddAtomA(str) AddAtom32A
-
+ 51 stub _KERNEL32_51
  52 stdcall _KERNEL32_52() _KERNEL32_52
-
-# WOW calls
+ 53 stub _KERNEL32_53_LoadLibraryAndGetProc16
  54 stdcall WOWCallback16(long long) WOWCallback16
  55 stdcall WOWCallback16Ex(ptr long long ptr ptr) WOWCallback16Ex
  56 stdcall WOWGetVDMPointer(long long long) WOWGetVDMPointer
@@ -61,7 +81,7 @@
  68 stdcall WOWGetVDMPointerFix(long long long) WOWGetVDMPointerFix
  69 stdcall WOWGetVDMPointerUnfix(long) WOWGetVDMPointerUnfix
  70 stdcall WOW32_1(long long) WOW32_1
- 
+ 71 stub IsThreadId
  72 stub RtlLargeIntegerAdd
  73 stub RtlEnlargedIntegerMultiply
  74 stub RtlEnlargedUnsignedMultiply
@@ -76,20 +96,22 @@
  83 stub RtlLargeIntegerSubtract
  84 stub RtlConvertLongToLargeInteger
  85 stub RtlConvertUlongToLargeInteger
-
- 87 stdcall _KERNEL32_87() _KERNEL32_87
- 88 varargs _KERNEL32_88() _KERNEL32_88
- 89 stdcall FT_PrologPrime(ptr ptr) FT_PrologPrime
- 90 register _KERNEL32_90() _KERNEL32_90
- 91 stub _KERNEL32_91
+ 86 stub _KERNEL32_86_EnterSysLevelSpecial
+ 87 stdcall SSOnBigStack() SSOnBigStack
+ 88 varargs SSCall() SSCall
+ 89 register FT_PrologPrime() FT_PrologPrime
+ 90 register QT_ThunkPrime() QT_ThunkPrime
+ 91 stub PK16FNF
  92 stub _KERNEL32_92
- 93 stdcall GETPWIN16LOCK(ptr) GetPWinLock
- 97 stub ENTERSYSLEVEL
- 98 stub LEAVESYSLEVEL
- 99 stdcall _KERNEL32_98(long) _KERNEL32_98
-100 stdcall _KERNEL32_99(long long long) _KERNEL32_99
-101 stub _KERNEL32_100
-
+ 93 stdcall GetPWin16Lock(ptr) GetPWinLock
+ 94 stub _DebugCheckNotSysLevel
+ 95 stub _DebugAssertCriticalSection
+ 96 stub ConfirmWin16Lock
+ 97 stub EnterSysLevel
+ 98 stub LeaveSysLevel
+ 99 stdcall _KERNEL32_99(long) _KERNEL32_99
+100 stdcall _KERNEL32_100(long long long) _KERNEL32_100
+101 stub _KERNEL32_101
 
 102 stdcall AddAtomW(wstr) AddAtom32W
 103 stdcall AllocConsole() AllocConsole
@@ -207,23 +229,23 @@
 215 stdcall ExitThread(long) ExitThread
 216 stdcall ExpandEnvironmentStringsA(str ptr long) ExpandEnvironmentStrings32A
 217 stdcall ExpandEnvironmentStringsW(wstr ptr long) ExpandEnvironmentStrings32W
-218 stub FT_Exit0
-219 stub FT_Exit12
-220 stub FT_Exit16
-221 stub FT_Exit20
-222 stub FT_Exit24
-223 stub FT_Exit28
-224 stub FT_Exit32
-225 stub FT_Exit36
-227 stub FT_Exit40
-228 stub FT_Exit44
-229 stub FT_Exit48
-226 stub FT_Exit4
-230 stub FT_Exit52
-231 stub FT_Exit56
-232 stub FT_Exit8
-233 stub FT_Prolog
-234 stub FT_Thunk
+218 register FT_Exit0() FT_Exit0
+219 register FT_Exit12() FT_Exit12
+220 register FT_Exit16() FT_Exit16
+221 register FT_Exit20() FT_Exit20
+222 register FT_Exit24() FT_Exit24
+223 register FT_Exit28() FT_Exit28
+224 register FT_Exit32() FT_Exit32
+225 register FT_Exit36() FT_Exit36
+227 register FT_Exit40() FT_Exit40
+228 register FT_Exit44() FT_Exit44
+229 register FT_Exit48() FT_Exit48
+226 register FT_Exit4() FT_Exit4
+230 register FT_Exit52() FT_Exit52
+231 register FT_Exit56() FT_Exit56
+232 register FT_Exit8() FT_Exit8
+233 register FT_Prolog() FT_Prolog
+234 register FT_Thunk() FT_Thunk
 235 stdcall FatalAppExitA(long str) FatalAppExit32A
 236 stdcall FatalAppExitW(long wstr) FatalAppExit32W
 237 stub FatalExit
@@ -308,9 +330,9 @@
 316 stdcall GetDiskFreeSpaceW(wstr ptr ptr ptr ptr) GetDiskFreeSpace32W
 317 stdcall GetDriveTypeA(str) GetDriveType32A
 318 stdcall GetDriveTypeW(wstr) GetDriveType32W
+319 stdcall GetEnvironmentStrings() GetEnvironmentStrings32A
 320 stdcall GetEnvironmentStringsA() GetEnvironmentStrings32A
 321 stdcall GetEnvironmentStringsW() GetEnvironmentStrings32W
-319 stdcall GetEnvironmentStrings() GetEnvironmentStrings32A
 322 stdcall GetEnvironmentVariableA(str ptr long) GetEnvironmentVariable32A
 323 stdcall GetEnvironmentVariableW(wstr ptr long) GetEnvironmentVariable32W
 324 stub GetErrorMode
@@ -344,7 +366,7 @@
 352 stub GetNamedPipeHandleStateA
 353 stub GetNamedPipeHandleStateW
 354 stub GetNamedPipeInfo
-355 stub GetNumberFormatA
+355 stdcall GetNumberFormatA(long long str ptr ptr long) GetNumberFormat32A
 356 stub GetNumberFormatW
 357 stdcall GetNumberOfConsoleInputEvents(long ptr) GetNumberOfConsoleInputEvents
 358 stdcall GetNumberOfConsoleMouseButtons(long ptr) GetNumberOfConsoleMouseButtons
@@ -513,7 +535,7 @@
 521 stub MapHModuleSL
 522 stdcall MapLS(ptr) MapLS
 523 stdcall MapSL(long) MapSL
-524 stub MapSLFix
+524 stdcall MapSLFix(long) MapSLFix
 525 stdcall MapViewOfFile(long long long long long) MapViewOfFile
 526 stdcall MapViewOfFileEx(long long long long long ptr) MapViewOfFileEx
 527 stub Module32First
@@ -690,7 +712,7 @@
 698 stdcall UTRegister(long str str str ptr ptr ptr) UTRegister
 699 stdcall UTUnRegister(long) UTUnRegister
 700 stdcall UnMapLS(long) UnMapLS
-701 stub UnMapSLFixArray
+701 stdcall UnMapSLFixArray(ptr long) UnMapSLFixArray
 702 stdcall UnhandledExceptionFilter(ptr) UnhandledExceptionFilter
 703 stub UninitializeCriticalSection
 704 stdcall UnlockFile(long long long long long) UnlockFile
diff --git a/relay32/mpr.spec b/relay32/mpr.spec
index c7f0fd1..2be81b5 100644
--- a/relay32/mpr.spec
+++ b/relay32/mpr.spec
@@ -30,7 +30,7 @@
 0049 stub WNetAddConnection3W
 0050 stub WNetAddConnectionA
 0051 stub WNetAddConnectionW
-0052 stub WNetCachePassword
+0052 stdcall WNetCachePassword(ptr long ptr long long) WNetCachePassword
 0053 stub WNetCancelConnection2A
 0054 stub WNetCancelConnection2W
 0055 stub WNetCancelConnectionA
diff --git a/relay32/relay386.c b/relay32/relay386.c
index 4115c7b..5177ac2 100644
--- a/relay32/relay386.c
+++ b/relay32/relay386.c
@@ -11,25 +11,9 @@
 #include "windows.h"
 #include "builtin32.h"
 #include "selectors.h"
+#include "debugstr.h"
 #include "debug.h"
 
-static void _dumpstr(unsigned char *s) {
-	fputs("\"",stdout);
-	while (*s) {
-		if (*s<' ') {
-			printf("\\0x%02x",*s++);
-			continue;
-		}
-		if (*s=='\\') {
-			fputs("\\\\",stdout);
-			s++;
-			continue;
-		}
-		fputc(*s++,stdout);
-	}
-	fputs("\"",stdout);
-}
-
 /***********************************************************************
  *           RELAY_CallFrom32
  *
@@ -69,11 +53,11 @@
                 lstrcpynWtoA( buff, (LPWSTR)args[i], sizeof(buff) );
 		buff[sizeof(buff)-1]='\0';
 	    	printf( "%08x L", args[i] );
-		_dumpstr((unsigned char*)buff);
+		debug_dumpstr( buff );
 	    }
             else {
 	    	printf( "%08x ", args[i] );
-		_dumpstr((unsigned char*)args[i]);
+		debug_dumpstr((LPCSTR)args[i]);
 	    }
 	}
         else printf( "%08x", args[i] );
@@ -170,19 +154,45 @@
 /***********************************************************************
  *           RELAY_CallFrom32Regs
  *
- * 'stack' points to the relay addr on the stack.
- * Stack layout:
- *  ...      ...
- * (esp+216) ret_addr
- * (esp+212) return to relay debugging code (only when debugging(relay))
- * (esp+208) entry point to call
- * (esp+4)   CONTEXT
- * (esp)     return addr to relay code
+ * 'context' contains the register contents at the point of call of
+ * the REG_ENTRY_POINT. The stack layout of the stack pointed to by
+ * ESP_reg(&context) is as follows:
+ *
+ * If debugmsg(relay) is OFF:
+ *  ...    ...
+ * (esp+4) args
+ * (esp)   return addr to caller
+ * (esp-4) function entry point
+ *
+ * If debugmsg(relay) is ON:
+ *  ...    ...
+ * (esp+8) args
+ * (esp+4) return addr to caller
+ * (esp)   return addr to DEBUG_ENTRY_POINT
+ * (esp-4) function entry point
+ *
+ * As the called function might change the stack layout
+ * (e.g. FT_Prolog, FT_ExitNN), we remove all modifications to the stack,
+ * so that the called function sees (in both cases):
+ *
+ *  ...    ...
+ * (esp+4) args
+ * (esp)   return addr to caller
+ *  ...    >128 bytes space free to be modified (ensured by the assembly glue)
+ *
+ * NOTE: This routine makes no assumption about the relative position of
+ *       its own stack to the stack pointed to by ESP_reg(&context),
+ *	 except that the latter must have >128 bytes space to grow.
+ *	 This means the assembly glue could even switch stacks completely
+ *	 (e.g. to allow for large stacks).
+ *
  */
-void RELAY_CallFrom32Regs( CONTEXT context,
-                           void (CALLBACK *entry_point)(CONTEXT *),
-                           BYTE *relay_addr, int ret_addr )
+
+void RELAY_CallFrom32Regs( CONTEXT context )
 {
+    void (CALLBACK *entry_point)(CONTEXT *) = 
+	 *(void (CALLBACK **)(CONTEXT *)) (ESP_reg(&context) - 4);
+
     if (!TRACE_ON(relay))
     {
         /* Simply call the entry point */
@@ -192,16 +202,25 @@
     {
         char buffer[80];
         unsigned int typemask;
+	BYTE *relay_addr;
 
     	__RESTORE_ES;
-        /* Fixup the context structure because of the extra parameter */
-        /* pushed by the relay debugging code */
 
-        EIP_reg(&context) = ret_addr;
-        ESP_reg(&context) += sizeof(int);
+        /*
+	 * Fixup the context structure because of the extra parameter
+         * pushed by the relay debugging code.
+	 * Note that this implicitly does a RET on the CALL from the
+	 * DEBUG_ENTRY_POINT to the REG_ENTRY_POINT;  setting the EIP register
+	 * ensures that the assembly glue will directly return to the
+	 * caller, just as in the non-debugging case.
+	 */
+
+        relay_addr = *(BYTE **) ESP_reg(&context); 
+        ESP_reg(&context) += sizeof(BYTE *);
+	EIP_reg(&context) = *(DWORD *)ESP_reg(&context);
 
         BUILTIN32_GetEntryPoint( buffer, relay_addr - 5, &typemask );
-        printf("Call %s(regs) ret=%08x\n", buffer, ret_addr );
+        printf("Call %s(regs) ret=%08x\n", buffer, *(int *)ESP_reg(&context) );
         printf(" EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx ESI=%08lx EDI=%08lx\n",
                 EAX_reg(&context), EBX_reg(&context), ECX_reg(&context),
                 EDX_reg(&context), ESI_reg(&context), EDI_reg(&context) );
@@ -213,7 +232,7 @@
         /* Now call the real function */
         entry_point( &context );
 
-        printf("Ret  %s() retval=regs ret=%08x\n", buffer, ret_addr );
+        printf("Ret  %s() retval=regs ret=%08x\n", buffer, *(int *)ESP_reg(&context) );
         printf(" EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx ESI=%08lx EDI=%08lx\n",
                 EAX_reg(&context), EBX_reg(&context), ECX_reg(&context),
                 EDX_reg(&context), ESI_reg(&context), EDI_reg(&context) );
diff --git a/relay32/user32.spec b/relay32/user32.spec
index 3340dd1..1b3e611 100644
--- a/relay32/user32.spec
+++ b/relay32/user32.spec
@@ -8,7 +8,7 @@
   5 stdcall AppendMenuA(long long long ptr) AppendMenu32A
   6 stdcall AppendMenuW(long long long ptr) AppendMenu32W
   7 stdcall ArrangeIconicWindows(long) ArrangeIconicWindows32
-  8 stub AttachThreadInput
+  8 stdcall AttachThreadInput(long long long) AttachThreadInput
   9 stdcall BeginDeferWindowPos(long) BeginDeferWindowPos32
  10 stdcall BeginPaint(long ptr) BeginPaint32
  11 stdcall BringWindowToTop(long) BringWindowToTop32
@@ -305,7 +305,7 @@
 300 stub GetUserObjectInformationW
 301 stub GetUserObjectSecurity
 302 stdcall GetWindow(long long) GetWindow32
-303 stub GetWindowContextHelpId
+303 stdcall GetWindowContextHelpId(long) GetWindowContextHelpId
 304 stdcall GetWindowDC(long) GetWindowDC32
 305 stdcall GetWindowLongA(long long) GetWindowLong32A
 306 stdcall GetWindowLongW(long long) GetWindowLong32W
@@ -517,7 +517,7 @@
 512 stub SetUserObjectInformationA
 513 stub SetUserObjectInformationW
 514 stub SetUserObjectSecurity
-515 stub SetWindowContextHelpId
+515 stdcall SetWindowContextHelpId(long long) SetWindowContextHelpId
 516 stub SetWindowFullScreenState
 517 stdcall SetWindowLongA(long long long) SetWindowLong32A
 518 stdcall SetWindowLongW(long long long) SetWindowLong32W
diff --git a/scheduler/event.c b/scheduler/event.c
index 9cf505c..d5ad9c8 100644
--- a/scheduler/event.c
+++ b/scheduler/event.c
@@ -88,7 +88,7 @@
 
     SYSTEM_LOCK();
     event = (EVENT *)K32OBJ_Create( K32OBJ_EVENT, sizeof(*event),
-                                    name, EVENT_ALL_ACCESS, &handle );
+                                    name, EVENT_ALL_ACCESS, sa, &handle );
     if (event)
     {
         /* Finish initializing it */
@@ -125,7 +125,7 @@
     SYSTEM_LOCK();
     if ((obj = K32OBJ_FindNameType( name, K32OBJ_EVENT )) != NULL)
     {
-        handle = HANDLE_Alloc( obj, access, inherit );
+        handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit );
         K32OBJ_DecCount( obj );
     }
     SYSTEM_UNLOCK();
@@ -152,8 +152,8 @@
 {
     EVENT *event;
     SYSTEM_LOCK();
-    if (!(event = (EVENT *)HANDLE_GetObjPtr( handle, K32OBJ_EVENT,
-                                             EVENT_MODIFY_STATE )))
+    if (!(event = (EVENT *)HANDLE_GetObjPtr(PROCESS_Current(), handle,
+                                            K32OBJ_EVENT, EVENT_MODIFY_STATE)))
     {
         SYSTEM_UNLOCK();
         return FALSE;
@@ -174,8 +174,8 @@
 {
     EVENT *event;
     SYSTEM_LOCK();
-    if (!(event = (EVENT *)HANDLE_GetObjPtr( handle, K32OBJ_EVENT,
-                                             EVENT_MODIFY_STATE )))
+    if (!(event = (EVENT *)HANDLE_GetObjPtr(PROCESS_Current(), handle,
+                                            K32OBJ_EVENT, EVENT_MODIFY_STATE)))
     {
         SYSTEM_UNLOCK();
         return FALSE;
@@ -195,8 +195,8 @@
 {
     EVENT *event;
     SYSTEM_LOCK();
-    if (!(event = (EVENT *)HANDLE_GetObjPtr( handle, K32OBJ_EVENT,
-                                             EVENT_MODIFY_STATE )))
+    if (!(event = (EVENT *)HANDLE_GetObjPtr(PROCESS_Current(), handle,
+                                            K32OBJ_EVENT, EVENT_MODIFY_STATE)))
     {
         SYSTEM_UNLOCK();
         return FALSE;
diff --git a/scheduler/handle.c b/scheduler/handle.c
index 6c1d641..e6630aa 100644
--- a/scheduler/handle.c
+++ b/scheduler/handle.c
@@ -22,23 +22,9 @@
 
 
 /***********************************************************************
- *           HANDLE_AllocTable
- */
-HANDLE_TABLE *HANDLE_AllocTable( PDB32 *process )
-{
-    HANDLE_TABLE *table = HeapAlloc( process->system_heap, HEAP_ZERO_MEMORY,
-                                     sizeof(HANDLE_TABLE) +
-                                     (HTABLE_SIZE-1) * sizeof(HANDLE_ENTRY) );
-    if (!table) return NULL;
-    table->count = HTABLE_SIZE;
-    return table;
-}
-
-
-/***********************************************************************
  *           HANDLE_GrowTable
  */
-static BOOL32 HANDLE_GrowTable( PDB32 *process )
+static BOOL32 HANDLE_GrowTable( PDB32 *process, INT32 incr )
 {
     HANDLE_TABLE *table;
 
@@ -47,10 +33,10 @@
     table = HeapReAlloc( process->system_heap,
                          HEAP_ZERO_MEMORY | HEAP_NO_SERIALIZE, table,
                          sizeof(HANDLE_TABLE) +
-                         (table->count+HTABLE_INC-1) * sizeof(HANDLE_ENTRY) );
+                         (table->count + incr - 1) * sizeof(HANDLE_ENTRY) );
     if (table)
     {
-        table->count += HTABLE_INC;
+        table->count += incr;
         process->handle_table = table;
     }
     SYSTEM_UNLOCK();
@@ -59,15 +45,67 @@
 
 
 /***********************************************************************
+ *           HANDLE_CreateTable
+ *
+ * Create a process handle table, optionally inheriting the parent's handles.
+ */
+BOOL32 HANDLE_CreateTable( PDB32 *pdb, BOOL32 inherit )
+{
+    DWORD size;
+
+    /* Process must not already have a handle table */
+    assert( !pdb->handle_table );
+
+    /* If this is the first process, simply allocate a table */
+    if (!pdb->parent) inherit = FALSE;
+
+    SYSTEM_LOCK();
+    size = inherit ? pdb->parent->handle_table->count : HTABLE_SIZE;
+    if ((pdb->handle_table = HeapAlloc( pdb->system_heap,
+                                        HEAP_ZERO_MEMORY | HEAP_NO_SERIALIZE,
+                                        sizeof(HANDLE_TABLE) +
+                                        (size-1) * sizeof(HANDLE_ENTRY) )))
+    {
+        pdb->handle_table->count = size;
+        if (inherit)
+        {
+            HANDLE_ENTRY *src = pdb->parent->handle_table->entries;
+            HANDLE_ENTRY *dst = pdb->handle_table->entries;
+            HANDLE32 h;
+
+            for (h = 0; h < size; h++, src++, dst++)
+            {
+                /* Check if handle is valid and inheritable */
+                if (src->ptr && (src->access & RESERVED_INHERIT))
+                {
+                    dst->access = src->access;
+                    dst->ptr    = src->ptr;
+                    K32OBJ_IncCount( dst->ptr );
+                }
+            }
+        }
+        /* Handle 1 is the process itself (unless the parent decided otherwise) */
+        if (!pdb->handle_table->entries[1].ptr)
+        {
+            pdb->handle_table->entries[1].ptr    = &pdb->header;
+            pdb->handle_table->entries[1].access = PROCESS_ALL_ACCESS;
+            K32OBJ_IncCount( &pdb->header );
+        }
+    }
+    SYSTEM_UNLOCK();
+    return (pdb->handle_table != NULL);
+}
+
+
+/***********************************************************************
  *           HANDLE_Alloc
  *
  * Allocate a handle for a kernel object and increment its refcount.
  */
-HANDLE32 HANDLE_Alloc( K32OBJ *ptr, DWORD access, BOOL32 inherit )
+HANDLE32 HANDLE_Alloc( PDB32 *pdb, K32OBJ *ptr, DWORD access, BOOL32 inherit )
 {
     HANDLE32 h;
     HANDLE_ENTRY *entry;
-    PDB32 *pdb = PROCESS_Current();
 
     assert( ptr );
 
@@ -77,16 +115,17 @@
 
     SYSTEM_LOCK();
     K32OBJ_IncCount( ptr );
-    entry = pdb->handle_table->entries;
-    for (h = 0; h < pdb->handle_table->count; h++, entry++)
+    /* Don't try to allocate handle 0 */
+    entry = pdb->handle_table->entries + 1;
+    for (h = 1; h < pdb->handle_table->count; h++, entry++)
         if (!entry->ptr) break;
-    if ((h < pdb->handle_table->count) || HANDLE_GrowTable( pdb ))
+    if ((h < pdb->handle_table->count) || HANDLE_GrowTable( pdb, HTABLE_INC ))
     {
         entry = &pdb->handle_table->entries[h];
         entry->access = access;
         entry->ptr    = ptr;
         SYSTEM_UNLOCK();
-        return h + 1;  /* Avoid handle 0 */
+        return h;
     }
     K32OBJ_DecCount( ptr );
     SYSTEM_UNLOCK();
@@ -101,15 +140,15 @@
  * Retrieve a pointer to a kernel object and increments its reference count.
  * The refcount must be decremented when the pointer is no longer used.
  */
-K32OBJ *HANDLE_GetObjPtr( HANDLE32 handle, K32OBJ_TYPE type, DWORD access )
+K32OBJ *HANDLE_GetObjPtr( PDB32 *pdb, HANDLE32 handle,
+                          K32OBJ_TYPE type, DWORD access )
 {
     K32OBJ *ptr = NULL;
-    PDB32 *pdb = PROCESS_Current();
 
     SYSTEM_LOCK();
     if ((handle > 0) && (handle <= pdb->handle_table->count))
     {
-        HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle-1];
+        HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle];
         if ((entry->access & access) != access)
             fprintf( stderr, "Warning: handle %08x bad access (acc=%08lx req=%08lx)\n",
                      handle, entry->access, access );
@@ -131,15 +170,15 @@
  * Change the object pointer of a handle, and increment the refcount.
  * Use with caution!
  */
-BOOL32 HANDLE_SetObjPtr( HANDLE32 handle, K32OBJ *ptr, DWORD access )
+BOOL32 HANDLE_SetObjPtr( PDB32 *pdb, HANDLE32 handle, K32OBJ *ptr,
+                         DWORD access )
 {
     BOOL32 ret = FALSE;
-    PDB32 *pdb = PROCESS_Current();
 
     SYSTEM_LOCK();
     if ((handle > 0) && (handle <= pdb->handle_table->count))
     {
-        HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle-1];
+        HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle];
         K32OBJ *old_ptr = entry->ptr;
         K32OBJ_IncCount( ptr );
         entry->access = access;
@@ -154,18 +193,40 @@
 
 
 /*********************************************************************
- *           CloseHandle   (KERNEL32.23)
+ *           HANDLE_GetAccess
  */
-BOOL32 WINAPI CloseHandle( HANDLE32 handle )
+static BOOL32 HANDLE_GetAccess( PDB32 *pdb, HANDLE32 handle, LPDWORD access )
 {
     BOOL32 ret = FALSE;
-    PDB32 *pdb = PROCESS_Current();
+
+    SYSTEM_LOCK();
+    if ((handle > 0) && (handle <= pdb->handle_table->count))
+    {
+        HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle];
+        if (entry->ptr)
+        {
+            *access = entry->access & ~RESERVED_ALL;
+            ret = TRUE;
+        }
+    }
+    SYSTEM_UNLOCK();
+    if (!ret) SetLastError( ERROR_INVALID_HANDLE );
+    return ret;
+}
+
+
+/*********************************************************************
+ *           HANDLE_Close
+ */
+static BOOL32 HANDLE_Close( PDB32 *pdb, HANDLE32 handle )
+{
+    BOOL32 ret = FALSE;
     K32OBJ *ptr;
 
     SYSTEM_LOCK();
     if ((handle > 0) && (handle <= pdb->handle_table->count))
     {
-        HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle-1];
+        HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle];
         if ((ptr = entry->ptr))
         {
             if (!(entry->access & RESERVED_CLOSE_PROTECT))
@@ -185,6 +246,41 @@
 
 
 /*********************************************************************
+ *           HANDLE_CloseAll
+ *
+ * Close all handles pointing to a given object (or all handles of the
+ * process if the object is NULL)
+ */
+void HANDLE_CloseAll( PDB32 *pdb, K32OBJ *obj )
+{
+    HANDLE_ENTRY *entry;
+    K32OBJ *ptr;
+    HANDLE32 handle;
+
+    SYSTEM_LOCK();
+    entry = pdb->handle_table->entries;
+    for (handle = 0; handle < pdb->handle_table->count; handle++, entry++)
+    {
+        if (!(ptr = entry->ptr)) continue;  /* empty slot */
+        if (obj && (ptr != obj)) continue;  /* not the right object */
+        entry->access = 0;
+        entry->ptr    = NULL;
+        K32OBJ_DecCount( ptr );
+    }
+    SYSTEM_UNLOCK();
+}
+
+
+/*********************************************************************
+ *           CloseHandle   (KERNEL32.23)
+ */
+BOOL32 WINAPI CloseHandle( HANDLE32 handle )
+{
+    return HANDLE_Close( PROCESS_Current(), handle );
+}
+
+
+/*********************************************************************
  *           GetHandleInformation   (KERNEL32.336)
  */
 BOOL32 WINAPI GetHandleInformation( HANDLE32 handle, LPDWORD flags )
@@ -195,7 +291,7 @@
     SYSTEM_LOCK();
     if ((handle > 0) && (handle <= pdb->handle_table->count))
     {
-        HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle-1];
+        HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle];
         if (entry->ptr)
         {
             if (flags)
@@ -222,7 +318,7 @@
     SYSTEM_LOCK();
     if ((handle > 0) && (handle <= pdb->handle_table->count))
     {
-        HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle-1];
+        HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle];
         if (entry->ptr)
         {
             entry->access = (entry->access & ~mask) | flags;
@@ -233,3 +329,49 @@
     if (!ret) SetLastError( ERROR_INVALID_HANDLE );
     return ret;
 }
+
+
+/*********************************************************************
+ *           DuplicateHandle   (KERNEL32.192)
+ */
+BOOL32 WINAPI DuplicateHandle( HANDLE32 source_process, HANDLE32 source,
+                               HANDLE32 dest_process, HANDLE32 *dest,
+                               DWORD access, BOOL32 inherit, DWORD options )
+{
+    PDB32 *src_pdb = NULL, *dst_pdb = NULL;
+    K32OBJ *obj = NULL;
+    BOOL32 ret = FALSE;
+    HANDLE32 handle;
+
+    SYSTEM_LOCK();
+
+    if (!(src_pdb = PROCESS_GetPtr( source_process, PROCESS_DUP_HANDLE )))
+        goto done;
+    if (!(obj = HANDLE_GetObjPtr( src_pdb, source, K32OBJ_UNKNOWN, 0 )))
+        goto done;
+
+    /* Now that we are sure the source is valid, handle the options */
+
+    if (options & DUPLICATE_CLOSE_SOURCE)
+        HANDLE_Close( src_pdb, source );
+    if (options & DUPLICATE_SAME_ACCESS)
+        HANDLE_GetAccess( src_pdb, source, &access );
+
+    /* And duplicate the handle in the dest process */
+
+    if (!(dst_pdb = PROCESS_GetPtr( dest_process, PROCESS_DUP_HANDLE )))
+        goto done;
+    if ((handle = HANDLE_Alloc( dst_pdb, obj,
+                                access, inherit )) != INVALID_HANDLE_VALUE32)
+    {
+        if (dest) *dest = handle;
+        ret = TRUE;
+    }
+
+done:
+    if (dst_pdb) K32OBJ_DecCount( &dst_pdb->header );
+    if (obj) K32OBJ_DecCount( obj );
+    if (src_pdb) K32OBJ_DecCount( &src_pdb->header );
+    SYSTEM_UNLOCK();
+    return ret;
+}
diff --git a/scheduler/k32obj.c b/scheduler/k32obj.c
index 30717fb..98053a4 100644
--- a/scheduler/k32obj.c
+++ b/scheduler/k32obj.c
@@ -162,8 +162,10 @@
  * The refcount of the object must be decremented once it is initialized.
  */
 K32OBJ *K32OBJ_Create( K32OBJ_TYPE type, DWORD size, LPCSTR name,
-                       DWORD access, HANDLE32 *handle )
+                       DWORD access, SECURITY_ATTRIBUTES *sa, HANDLE32 *handle)
 {
+    BOOL32 inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
+
     /* Check if the name already exists */
 
     K32OBJ *obj = K32OBJ_FindName( name );
@@ -172,7 +174,7 @@
         if (obj->type == type)
         {
             SetLastError( ERROR_ALREADY_EXISTS );
-            *handle = HANDLE_Alloc( obj, access, FALSE );
+            *handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit );
         }
         else
         {
@@ -209,7 +211,7 @@
 
     /* Allocate a handle */
 
-    *handle = HANDLE_Alloc( obj, access, FALSE );
+    *handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit );
     SYSTEM_UNLOCK();
     return obj;
 }
diff --git a/scheduler/mutex.c b/scheduler/mutex.c
index ae69498..407e50e 100644
--- a/scheduler/mutex.c
+++ b/scheduler/mutex.c
@@ -86,7 +86,7 @@
 
     SYSTEM_LOCK();
     mutex = (MUTEX *)K32OBJ_Create( K32OBJ_MUTEX, sizeof(*mutex),
-                                    name, MUTEX_ALL_ACCESS, &handle );
+                                    name, MUTEX_ALL_ACCESS, sa, &handle );
     if (mutex)
     {
         /* Finish initializing it */
@@ -140,7 +140,7 @@
     SYSTEM_LOCK();
     if ((obj = K32OBJ_FindNameType( name, K32OBJ_MUTEX )) != NULL)
     {
-        handle = HANDLE_Alloc( obj, access, inherit );
+        handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit );
         K32OBJ_DecCount( obj );
     }
     SYSTEM_UNLOCK();
@@ -167,8 +167,8 @@
 {
     MUTEX *mutex;
     SYSTEM_LOCK();
-    if (!(mutex = (MUTEX *)HANDLE_GetObjPtr( handle, K32OBJ_MUTEX,
-                                             MUTEX_MODIFY_STATE )))
+    if (!(mutex = (MUTEX *)HANDLE_GetObjPtr(PROCESS_Current(), handle,
+                                            K32OBJ_MUTEX, MUTEX_MODIFY_STATE)))
     {
         SYSTEM_UNLOCK();
         return FALSE;
diff --git a/scheduler/process.c b/scheduler/process.c
index 270fdc9..ce6fc50 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -1,7 +1,7 @@
 /*
  * Win32 processes
  *
- * Copyright 1996 Alexandre Julliard
+ * Copyright 1996, 1998 Alexandre Julliard
  */
 
 #include <assert.h>
@@ -17,6 +17,8 @@
 #include "thread.h"
 #include "winerror.h"
 #include "pe_image.h"
+#include "task.h"
+#include "debug.h"
 
 /* Process self-handle */
 #define PROCESS_SELF ((HANDLE32)0x7fffffff)
@@ -55,15 +57,14 @@
  */
 PDB32 *PROCESS_GetPtr( HANDLE32 handle, DWORD access )
 {
-    PDB32 *pdb;
+    PDB32 *pdb = PROCESS_Current();
 
     if (handle == PROCESS_SELF)
     {
-        pdb = PROCESS_Current();
         K32OBJ_IncCount( &pdb->header );
         return pdb;
     }
-    return (PDB32 *)HANDLE_GetObjPtr( handle, K32OBJ_PROCESS, access );
+    return (PDB32 *)HANDLE_GetObjPtr( pdb, handle, K32OBJ_PROCESS, access );
 }
 
 
@@ -87,58 +88,59 @@
 }
 
 
-static int pstr_cmp( const void *ps1, const void *ps2 )
-{
-    return lstrcmpi32A( *(LPSTR *)ps1, *(LPSTR *)ps2 );
-}
 
 /***********************************************************************
- *           PROCESS_FillEnvDB
+ *           PROCESS_BuildEnvDB
+ *
+ * Build the env DB for the initial process
  */
-static BOOL32 PROCESS_FillEnvDB( PDB32 *pdb, TDB *pTask, LPCSTR cmd_line )
+static BOOL32 PROCESS_BuildEnvDB( PDB32 *pdb )
 {
-    LPSTR p, env;
-    INT32 count = 0;
-    LPSTR *pp, *array = NULL;
+    /* Allocate the env DB (FIXME: should not be on the system heap) */
 
-    /* Copy the Win16 environment, sorting it in the process */
+    if (!(pdb->env_db = HeapAlloc(SystemHeap,HEAP_ZERO_MEMORY,sizeof(ENVDB))))
+        return FALSE;
+    InitializeCriticalSection( &pdb->env_db->section );
 
-    env = p = GlobalLock16( pTask->pdb.environment );
-    for (p = env; *p; p += strlen(p) + 1) count++;
-    pdb->env_db->env_size = (p - env) + 1;
-    pdb->env_db->environ = HeapAlloc( pdb->heap, 0, pdb->env_db->env_size );
-    if (!pdb->env_db->environ) goto error;
-    if (!(array = HeapAlloc( pdb->heap, 0, count * sizeof(array[0]) )))
-        goto error;
-    for (p = env, pp = array; *p; p += strlen(p) + 1) *pp++ = p;
-    qsort( array, count, sizeof(LPSTR), pstr_cmp );
-    p = pdb->env_db->environ;
-    for (pp = array; count; count--, pp++)
-    {
-        strcpy( p, *pp );
-        p += strlen(p) + 1;
-    }
-    *p = '\0';
-    HeapFree( pdb->heap, 0, array );
-    array = NULL;
+    /* Allocate the standard handles */
+
+    pdb->env_db->hStdin  = FILE_DupUnixHandle( 0 );
+    pdb->env_db->hStdout = FILE_DupUnixHandle( 1 );
+    pdb->env_db->hStderr = FILE_DupUnixHandle( 2 );
+    FILE_SetFileType( pdb->env_db->hStdin,  FILE_TYPE_CHAR );
+    FILE_SetFileType( pdb->env_db->hStdout, FILE_TYPE_CHAR );
+    FILE_SetFileType( pdb->env_db->hStderr, FILE_TYPE_CHAR );
+
+    /* Build the environment strings */
+
+    return ENV_BuildEnvironment( pdb );
+}
+
+
+/***********************************************************************
+ *           PROCESS_InheritEnvDB
+ */
+static BOOL32 PROCESS_InheritEnvDB( PDB32 *pdb, LPCSTR cmd_line, LPCSTR env )
+{
+    if (!(pdb->env_db = HeapAlloc(pdb->heap, HEAP_ZERO_MEMORY, sizeof(ENVDB))))
+        return FALSE;
+    InitializeCriticalSection( &pdb->env_db->section );
+
+    /* Copy the parent environment */
+
+    if (!ENV_InheritEnvironment( pdb, env )) return FALSE;
 
     /* Copy the command line */
-    /* Fixme: Here we rely on the hack that loader/module.c put's the unprocessed
-       commandline after the processed one in Pascal notation.
-       We may access Null data if we get called another way.
-       If we have a real CreateProcess sometimes, the problem to get an unrestricted
-       commandline will go away and we won't need that hack any longer
-       */
-    if (!(pdb->env_db->cmd_line =
-	  HEAP_strdupA( pdb->heap, 0, cmd_line + (unsigned char)cmd_line[0] + 2)))
-        goto error;
-    return TRUE;
 
-error:
-    if (pdb->env_db->cmd_line) HeapFree( pdb->heap, 0, pdb->env_db->cmd_line );
-    if (array) HeapFree( pdb->heap, 0, array );
-    if (pdb->env_db->environ) HeapFree( pdb->heap, 0, pdb->env_db->environ );
-    return FALSE;
+    if (!(pdb->env_db->cmd_line = HEAP_strdupA( pdb->heap, 0, cmd_line )))
+        return FALSE;
+
+    /* Inherit the standard handles */
+    pdb->env_db->hStdin  = pdb->parent->env_db->hStdin;
+    pdb->env_db->hStdout = pdb->parent->env_db->hStdout;
+    pdb->env_db->hStderr = pdb->parent->env_db->hStderr;
+
+    return TRUE;
 }
 
 
@@ -150,8 +152,9 @@
 static void PROCESS_FreePDB( PDB32 *pdb )
 {
     pdb->header.type = K32OBJ_UNKNOWN;
+    if (pdb->handle_table) HANDLE_CloseAll( pdb, NULL );
+    ENV_FreeEnvironment( pdb );
     if (pdb->heap && (pdb->heap != pdb->system_heap)) HeapDestroy( pdb->heap );
-    if (pdb->handle_table) HeapFree( pdb->system_heap, 0, pdb->handle_table );
     if (pdb->load_done_evt) K32OBJ_DecCount( pdb->load_done_evt );
     if (pdb->event) K32OBJ_DecCount( pdb->event );
     DeleteCriticalSection( &pdb->crit_section );
@@ -163,6 +166,7 @@
  *           PROCESS_CreatePDB
  *
  * Allocate and fill a PDB structure.
+ * Runs in the context of the parent process.
  */
 static PDB32 *PROCESS_CreatePDB( PDB32 *parent )
 {
@@ -188,9 +192,10 @@
     if (!(pdb->event = EVENT_Create( TRUE, FALSE ))) goto error;
     if (!(pdb->load_done_evt = EVENT_Create( TRUE, FALSE ))) goto error;
 
-    /* Allocate the handle table */
+    /* Create the handle table */
 
-    if (!(pdb->handle_table = HANDLE_AllocTable( pdb ))) goto error;
+    if (!HANDLE_CreateTable( pdb, TRUE )) goto error;
+
     return pdb;
 
 error:
@@ -218,10 +223,13 @@
 
     /* Create the initial process and thread structures */
     if (!(pdb = PROCESS_CreatePDB( NULL ))) return FALSE;
-    if (!(thdb = THREAD_Create( pdb, 0, NULL, NULL ))) return FALSE;
+    if (!(thdb = THREAD_Create( pdb, 0, FALSE, NULL, NULL ))) return FALSE;
     SET_CUR_THREAD( thdb );
     THREAD_InitDone = TRUE;
 
+    /* Create the environment DB of the first process */
+    if (!PROCESS_BuildEnvDB( pdb )) return FALSE;
+
     return TRUE;
 }
 
@@ -231,14 +239,16 @@
  *
  * Create a new process database and associated info.
  */
-PDB32 *PROCESS_Create( TDB *pTask, LPCSTR cmd_line )
+PDB32 *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
+                       HINSTANCE16 hInstance, HINSTANCE16 hPrevInstance,
+                       UINT32 cmdShow )
 {
     DWORD size, commit;
-    NE_MODULE *pModule;
-    PDB32 *pdb = PROCESS_CreatePDB( PROCESS_Current() );
+    THDB *thdb = NULL;
+    PDB32 *parent = PROCESS_Current();
+    PDB32 *pdb = PROCESS_CreatePDB( parent );
 
     if (!pdb) return NULL;
-    if (!(pModule = MODULE_GetPtr( pTask->hModule ))) return 0;
 
     /* Create the heap */
 
@@ -255,12 +265,27 @@
     if (!(pdb->heap = HeapCreate( HEAP_GROWABLE, size, commit ))) goto error;
     pdb->heap_list = pdb->heap;
 
-    if (!(pdb->env_db = HeapAlloc(pdb->heap, HEAP_ZERO_MEMORY, sizeof(ENVDB))))
-        goto error;
-    if (!PROCESS_FillEnvDB( pdb, pTask, cmd_line )) goto error;
+    /* Inherit the env DB from the parent */
+
+    if (!PROCESS_InheritEnvDB( pdb, cmd_line, env )) goto error;
+
+    /* Create the main thread */
+
+    if (pModule->module32)
+        size = PE_HEADER(pModule->module32)->OptionalHeader.SizeOfStackReserve;
+    else
+        size = 0;
+    if (!(thdb = THREAD_Create( pdb, size, FALSE, NULL, NULL ))) goto error;
+
+    /* Create a Win16 task for this process */
+
+    pdb->task = TASK_Create( thdb, pModule, hInstance, hPrevInstance, cmdShow);
+    if (!pdb->task) goto error;
+
     return pdb;
 
 error:
+    if (thdb) K32OBJ_DecCount( &thdb->header );
     PROCESS_FreePDB( pdb );
     return NULL;
 }
@@ -315,40 +340,15 @@
     return K32OBJ_OPS( pdb->event )->remove_wait( pdb->event, thread_id );
 }
 
-/***********************************************************************
- *		PROCESS_CloseObjHandles
- *
- *	closes all handles that reference "ptr"
- * note: need to add 1 to the array entry to get to what
- * CloseHandle expects (there is no zero handle)
- */
-void PROCESS_CloseObjHandles(PDB32 *pdb, K32OBJ *ptr)
-{
-	HANDLE32 handle;
-
-	assert( pdb->header.type == K32OBJ_PROCESS );
-
-	/* Close all handles that have a pointer to ptr */
-	for (handle = 0; handle < pdb->handle_table->count; handle++)
-		if (pdb->handle_table->entries[handle].ptr == ptr) 
-			CloseHandle( handle+1 );
-}
 
 /***********************************************************************
  *           PROCESS_Destroy
- * note: need to add 1 to the array entry to get to what
- * CloseHandle expects (there is no zero handle)
  */
 static void PROCESS_Destroy( K32OBJ *ptr )
 {
     PDB32 *pdb = (PDB32 *)ptr;
-    HANDLE32 handle;
     assert( ptr->type == K32OBJ_PROCESS );
 
-    /* Close all handles */
-    for (handle = 0; handle < pdb->handle_table->count; handle++)
-        if (pdb->handle_table->entries[handle].ptr) CloseHandle( handle+1 );
-
     /* Free everything */
 
     ptr->type = K32OBJ_UNKNOWN;
@@ -395,7 +395,7 @@
         SetLastError( ERROR_INVALID_HANDLE );
         return 0;
     }
-    return HANDLE_Alloc( &pdb->header, access, inherit );
+    return HANDLE_Alloc( PROCESS_Current(), &pdb->header, access, inherit );
 }			      
 
 
@@ -410,278 +410,6 @@
 
 
 /***********************************************************************
- *      GetEnvironmentStrings32A   (KERNEL32.210) (KERNEL32.211)
- */
-LPSTR WINAPI GetEnvironmentStrings32A(void)
-{
-    PDB32 *pdb = PROCESS_Current();
-    return pdb->env_db->environ;
-}
-
-
-/***********************************************************************
- *      GetEnvironmentStrings32W   (KERNEL32.212)
- */
-LPWSTR WINAPI GetEnvironmentStrings32W(void)
-{
-    INT32 size;
-    LPWSTR ret, pW;
-    LPSTR pA;
-    PDB32 *pdb = PROCESS_Current();
-
-    size = HeapSize( GetProcessHeap(), 0, pdb->env_db->environ );
-    if (!(ret = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) )))
-        return NULL;
-    pA = pdb->env_db->environ;
-    pW = ret;
-    while (*pA)
-    {
-        lstrcpyAtoW( pW, pA );
-        size = strlen(pA);
-        pA += size + 1;
-        pW += size + 1;
-    }
-    *pW = 0;
-    return ret;
-}
-
-
-/***********************************************************************
- *           FreeEnvironmentStrings32A   (KERNEL32.141)
- */
-BOOL32 WINAPI FreeEnvironmentStrings32A( LPSTR ptr )
-{
-    PDB32 *pdb = PROCESS_Current();
-    if (ptr != pdb->env_db->environ)
-    {
-        SetLastError( ERROR_INVALID_PARAMETER );
-        return FALSE;
-    }
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           FreeEnvironmentStrings32W   (KERNEL32.142)
- */
-BOOL32 WINAPI FreeEnvironmentStrings32W( LPWSTR ptr )
-{
-    return HeapFree( GetProcessHeap(), 0, ptr );
-}
-
-
-/***********************************************************************
- *          GetEnvironmentVariable32A   (KERNEL32.213)
- */
-DWORD WINAPI GetEnvironmentVariable32A( LPCSTR name, LPSTR value, DWORD size )
-{
-    LPSTR p;
-    INT32 len, res;
-
-    p = PROCESS_Current()->env_db->environ;
-    if (!name || !*name)
-    {
-        SetLastError( ERROR_INVALID_PARAMETER );
-        return 0;
-    }
-    len = strlen(name);
-    while (*p)
-    {
-        res = lstrncmpi32A( name, p, len );
-        if (res < 0) goto not_found;
-        if (!res && (p[len] == '=')) break;
-        p += strlen(p) + 1;
-    }
-    if (!*p) goto not_found;
-    if (value) lstrcpyn32A( value, p + len + 1, size );
-    len = strlen(p);
-    /* According to the Win32 docs, if there is not enough room, return
-     * the size required to hold the string plus the terminating null
-     */
-    if (size <= len) len++;
-    return len;
-	
-not_found:
-    return 0;  /* FIXME: SetLastError */
-}
-
-
-/***********************************************************************
- *           GetEnvironmentVariable32W   (KERNEL32.214)
- */
-DWORD WINAPI GetEnvironmentVariable32W( LPCWSTR nameW, LPWSTR valW, DWORD size)
-{
-    LPSTR name = HEAP_strdupWtoA( GetProcessHeap(), 0, nameW );
-    LPSTR val  = HeapAlloc( GetProcessHeap(), 0, size );
-    DWORD res  = GetEnvironmentVariable32A( name, val, size );
-    HeapFree( GetProcessHeap(), 0, name );
-    if (valW) lstrcpynAtoW( valW, val, size );
-    HeapFree( GetProcessHeap(), 0, val );
-    return res;
-}
-
-
-/***********************************************************************
- *           SetEnvironmentVariable32A   (KERNEL32.484)
- */
-BOOL32 WINAPI SetEnvironmentVariable32A( LPCSTR name, LPCSTR value )
-{
-    INT32 size, len, res;
-    LPSTR p, env, new_env;
-    PDB32 *pdb = PROCESS_Current();
-
-    env = p = pdb->env_db->environ;
-
-    /* Find a place to insert the string */
-
-    res = -1;
-    len = strlen(name);
-    while (*p)
-    {
-        res = lstrncmpi32A( name, p, len );
-        if (res < 0) break;
-        if (!res && (p[len] == '=')) break;
-        res = 1;
-        p += strlen(p) + 1;
-    }
-    if (!value && res)  /* Value to remove doesn't exist already */
-        return FALSE;
-
-    /* Realloc the buffer */
-
-    len = value ? strlen(name) + strlen(value) + 2 : 0;
-    if (!res) len -= strlen(p) + 1;  /* The name already exists */
-    size = pdb->env_db->env_size + len;
-    if (len < 0)
-    {
-        LPSTR next = p + strlen(p) + 1;
-        memmove( next + len, next, pdb->env_db->env_size - (next - env) );
-    }
-    if (!(new_env = HeapReAlloc( GetProcessHeap(), 0, env, size )))
-        return FALSE;
-    p = new_env + (p - env);
-    if (len > 0) memmove( p + len, p, pdb->env_db->env_size - (p-new_env) );
-
-    /* Set the new string */
-
-    if (value)
-    {
-        strcpy( p, name );
-        strcat( p, "=" );
-        strcat( p, value );
-    }
-    pdb->env_db->env_size = size;
-    pdb->env_db->environ  = new_env;
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           SetEnvironmentVariable32W   (KERNEL32.485)
- */
-BOOL32 WINAPI SetEnvironmentVariable32W( LPCWSTR name, LPCWSTR value )
-{
-    LPSTR nameA  = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
-    LPSTR valueA = HEAP_strdupWtoA( GetProcessHeap(), 0, value );
-    BOOL32 ret = SetEnvironmentVariable32A( nameA, valueA );
-    HeapFree( GetProcessHeap(), 0, nameA );
-    HeapFree( GetProcessHeap(), 0, valueA );
-    return ret;
-}
-
-
-/***********************************************************************
- *           ExpandEnvironmentVariablesA   (KERNEL32.103)
- */
-DWORD WINAPI ExpandEnvironmentStrings32A( LPCSTR src, LPSTR dst, DWORD len)
-{
-	LPCSTR s;
-        LPSTR d;
-	HANDLE32	heap = GetProcessHeap();
-	LPSTR		xdst = HeapAlloc(heap,0,10);
-	DWORD		cursize = 10;
-	DWORD		ret;
-
-	fprintf(stderr,"ExpandEnvironmentStrings32A(%s)\n",src);
-	s=src;
-	d=xdst;
-	memset(dst,'\0',len);
-#define CHECK_FREE(n)  {				\
-	DWORD	_needed = (n);				\
-							\
-	while (cursize-(d-xdst)<_needed) {		\
-		DWORD	ind = d-xdst;			\
-							\
-		cursize+=100;				\
-		xdst=(LPSTR)HeapReAlloc(heap,0,xdst,cursize);\
-		d = xdst+ind;				\
-	}						\
-}
-
-	while (*s) {
-		if (*s=='%') {
-			LPCSTR end;
-
-			end = s;do { end++; } while (*end && *end!='%');
-			if (*end=='%') {
-				LPSTR	x = HeapAlloc(heap,0,end-s+1);
-				char	buf[2];
-
-				lstrcpyn32A(x,s+1,end-s);
-				x[end-s]=0;
-
-				/* put expanded variable directly into 
-				 * destination string, so we don't have
-				 * to use temporary buffers.
-				 */
-				ret = GetEnvironmentVariable32A(x,buf,2);
-				CHECK_FREE(ret+2);
-				ret = GetEnvironmentVariable32A(x,d,cursize-(d-xdst));
-				if (ret) {
-					d+=strlen(d);
-					s=end;
-				} else {
-					CHECK_FREE(strlen(x)+2);
-					*d++='%';
-					lstrcpy32A(d,x);
-					d+=strlen(x);
-					*d++='%';
-				}
-				HeapFree(heap,0,x);
-			} else
-				*d++=*s;
-
-			s++;
-		} else {
-			CHECK_FREE(1);
-			*d++=*s++;
-		}
-	}
-	*d	= '\0';
-	ret	= lstrlen32A(xdst)+1;
-	if (d-xdst<len)
-		lstrcpy32A(dst,xdst);
-	HeapFree(heap,0,xdst);
-	return ret;
-}
-
-/***********************************************************************
- *           ExpandEnvironmentVariablesA   (KERNEL32.104)
- */
-DWORD WINAPI ExpandEnvironmentStrings32W( LPCWSTR src, LPWSTR dst, DWORD len)
-{
-	HANDLE32	heap = GetProcessHeap();
-	LPSTR		srcA = HEAP_strdupWtoA(heap,0,src);
-	LPSTR		dstA = HeapAlloc(heap,0,len);
-	DWORD		ret = ExpandEnvironmentStrings32A(srcA,dstA,len);
-
-	lstrcpyAtoW(dst,dstA);
-	HeapFree(heap,0,dstA);
-	HeapFree(heap,0,srcA);
-	return ret;
-}
-
-/***********************************************************************
  *           GetProcessHeap    (KERNEL32.259)
  */
 HANDLE32 WINAPI GetProcessHeap(void)
@@ -910,7 +638,7 @@
  * FIXME: check this, if we ever run win32 binaries in different addressspaces
  *	  ... and add a sizecheck
  */
-BOOL32 WINAPI WriteProcessMemory(HANDLE32 hProcess, LPCVOID lpBaseAddress,
+BOOL32 WINAPI WriteProcessMemory(HANDLE32 hProcess, LPVOID lpBaseAddress,
                                  LPVOID lpBuffer, DWORD nSize,
                                  LPDWORD lpNumberOfBytesWritten )
 {
diff --git a/scheduler/semaphore.c b/scheduler/semaphore.c
index 361bf1f..a456ebf 100644
--- a/scheduler/semaphore.c
+++ b/scheduler/semaphore.c
@@ -57,7 +57,7 @@
 
     SYSTEM_LOCK();
     sem = (SEMAPHORE *)K32OBJ_Create( K32OBJ_SEMAPHORE, sizeof(*sem),
-                                      name, SEMAPHORE_ALL_ACCESS, &handle );
+                                      name, SEMAPHORE_ALL_ACCESS, sa, &handle);
     if (sem)
     {
         /* Finish initializing it */
@@ -94,7 +94,7 @@
     SYSTEM_LOCK();
     if ((obj = K32OBJ_FindNameType( name, K32OBJ_SEMAPHORE )) != NULL)
     {
-        handle = HANDLE_Alloc( obj, access, inherit );
+        handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit );
         K32OBJ_DecCount( obj );
     }
     SYSTEM_UNLOCK();
@@ -122,7 +122,8 @@
     SEMAPHORE *sem;
 
     SYSTEM_LOCK();
-    if (!(sem = (SEMAPHORE *)HANDLE_GetObjPtr( handle, K32OBJ_SEMAPHORE,
+    if (!(sem = (SEMAPHORE *)HANDLE_GetObjPtr( PROCESS_Current(), handle,
+                                               K32OBJ_SEMAPHORE,
                                                SEMAPHORE_MODIFY_STATE )))
     {
         SYSTEM_UNLOCK();
diff --git a/scheduler/synchro.c b/scheduler/synchro.c
index 2a82a41..0220503 100644
--- a/scheduler/synchro.c
+++ b/scheduler/synchro.c
@@ -31,8 +31,8 @@
     SYSTEM_LOCK();
     for (i = 0, ptr = wait->objs; i < count; i++, ptr++)
     {
-        if (!(*ptr = HANDLE_GetObjPtr( handles[i], K32OBJ_UNKNOWN,
-                                       SYNCHRONIZE )))
+        if (!(*ptr = HANDLE_GetObjPtr( PROCESS_Current(), handles[i],
+                                       K32OBJ_UNKNOWN, SYNCHRONIZE )))
             break;
         if (!K32OBJ_OPS( *ptr )->signaled)
         {
diff --git a/scheduler/thread.c b/scheduler/thread.c
index 8774b83..5e065ff 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -38,6 +38,8 @@
     THREAD_Destroy      /* destroy */
 };
 
+/* The pseudohandle used for the current thread, see GetCurrentThread */
+#define CURRENT_THREAD_PSEUDOHANDLE 0xfffffffe
 
 /* Is threading code initialized? */
 BOOL32 THREAD_InitDone = FALSE;
@@ -52,12 +54,13 @@
 {
     THDB *thread;
 
-    if (handle == 0xfffffffe)  /* Self-thread handle */
+    if (handle == CURRENT_THREAD_PSEUDOHANDLE)  /* Self-thread handle */
     {
         thread = THREAD_Current();
         K32OBJ_IncCount( &thread->header );
     }
-    else thread = (THDB *)HANDLE_GetObjPtr( handle, K32OBJ_THREAD, access );
+    else thread = (THDB *)HANDLE_GetObjPtr( PROCESS_Current(), handle,
+                                            K32OBJ_THREAD, access );
     return thread;
 }
 
@@ -130,7 +133,7 @@
 /***********************************************************************
  *           THREAD_Create
  */
-THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size,
+THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size, BOOL32 alloc_stack16,
                      LPTHREAD_START_ROUTINE start_addr, LPVOID param )
 {
     DWORD old_prot;
@@ -143,7 +146,6 @@
     thdb->process         = pdb;
     thdb->teb.except      = (void *)-1;
     thdb->teb.htask16     = 0; /* FIXME */
-    thdb->teb.stack_sel   = 0; /* FIXME */
     thdb->teb.self        = &thdb->teb;
     thdb->teb.tls_ptr     = thdb->tls_array;
     thdb->teb.process     = pdb;
@@ -166,8 +168,9 @@
     	stack_size = 1024 * 1024;
     if (stack_size >= 16*1024*1024)
     	fprintf(stderr,"Warning:Thread stack size is %ld MB.\n",stack_size/1024/1024);
-    thdb->stack_base = VirtualAlloc( NULL, stack_size, MEM_COMMIT,
-                                     PAGE_EXECUTE_READWRITE );
+    thdb->stack_base = VirtualAlloc(NULL,
+                                    stack_size + (alloc_stack16 ? 0x10000 : 0),
+                                    MEM_COMMIT, PAGE_EXECUTE_READWRITE );
     if (!thdb->stack_base) goto error;
     /* Set a guard page at the bottom of the stack */
     VirtualProtect( thdb->stack_base, 1, PAGE_EXECUTE_READWRITE | PAGE_GUARD,
@@ -182,6 +185,17 @@
                                          TRUE, FALSE );
     if (!thdb->teb_sel) goto error;
 
+    /* Allocate the 16-bit stack selector */
+
+    if (alloc_stack16)
+    {
+        thdb->teb.stack_sel = SELECTOR_AllocBlock( thdb->teb.stack_top,
+                                                   0x10000, SEGMENT_DATA,
+                                                   FALSE, FALSE );
+        if (!thdb->teb.stack_sel) goto error;
+        thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( thdb->teb.stack_sel, 0xfffc );
+    }
+
     /* Allocate the event */
 
     if (!(thdb->event = EVENT_Create( TRUE, FALSE ))) goto error;
@@ -204,6 +218,7 @@
 
 error:
     if (thdb->event) K32OBJ_DecCount( thdb->event );
+    if (thdb->teb.stack_sel) SELECTOR_FreeBlock( thdb->teb.stack_sel, 1 );
     if (thdb->teb_sel) SELECTOR_FreeBlock( thdb->teb_sel, 1 );
     if (thdb->stack_base) VirtualFree( thdb->stack_base, 0, MEM_RELEASE );
     HeapFree( SystemHeap, 0, thdb );
@@ -287,6 +302,7 @@
 #endif
     K32OBJ_DecCount( thdb->event );
     SELECTOR_FreeBlock( thdb->teb_sel, 1 );
+    if (thdb->teb.stack_sel) SELECTOR_FreeBlock( thdb->teb.stack_sel, 1 );
     HeapFree( SystemHeap, 0, thdb );
 
 }
@@ -295,14 +311,18 @@
 /***********************************************************************
  *           CreateThread   (KERNEL32.63)
  */
-HANDLE32 WINAPI CreateThread( LPSECURITY_ATTRIBUTES attribs, DWORD stack,
+HANDLE32 WINAPI CreateThread( SECURITY_ATTRIBUTES *sa, DWORD stack,
                               LPTHREAD_START_ROUTINE start, LPVOID param,
                               DWORD flags, LPDWORD id )
 {
     HANDLE32 handle;
-    THDB *thread = THREAD_Create( PROCESS_Current(), stack, start, param );
+    BOOL32 inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
+
+    THDB *thread = THREAD_Create( PROCESS_Current(), stack,
+                                  TRUE, start, param );
     if (!thread) return INVALID_HANDLE_VALUE32;
-    handle = HANDLE_Alloc( &thread->header, THREAD_ALL_ACCESS, FALSE );
+    handle = HANDLE_Alloc( PROCESS_Current(), &thread->header,
+                           THREAD_ALL_ACCESS, inherit );
     if (handle == INVALID_HANDLE_VALUE32) goto error;
     if (SYSDEPS_SpawnThread( thread ) == -1) goto error;
     *id = THDB_TO_THREAD_ID( thread );
@@ -315,9 +335,13 @@
 
 
 /***********************************************************************
- *           ExitThread   (KERNEL32.215)
+ * ExitThread [KERNEL32.215]  Ends a thread
+ *
+ * RETURNS
+ *    None
  */
-void WINAPI ExitThread( DWORD code )
+void WINAPI ExitThread(
+    DWORD code) /* [in] Exit code for this thread */
 {
     THDB *thdb = THREAD_Current();
     LONG count;
@@ -343,16 +367,22 @@
 
 
 /***********************************************************************
- *           GetCurrentThread   (KERNEL32.200)
+ * GetCurrentThread [KERNEL32.200]  Gets pseudohandle for current thread
+ *
+ * RETURNS
+ *    Pseudohandle for the current thread
  */
 HANDLE32 WINAPI GetCurrentThread(void)
 {
-    return 0xFFFFFFFE;
+    return CURRENT_THREAD_PSEUDOHANDLE;
 }
 
 
 /***********************************************************************
- *           GetCurrentThreadId   (KERNEL32.201)
+ * GetCurrentThreadId [KERNEL32.201]  Returns thread identifier.
+ *
+ * RETURNS
+ *    Thread identifier of calling thread
  */
 DWORD WINAPI GetCurrentThreadId(void)
 {
@@ -361,7 +391,10 @@
 
 
 /**********************************************************************
- *           GetLastError   (KERNEL.148) (KERNEL32.227)
+ * GetLastError [KERNEL.148] [KERNEL32.227]  Returns last-error code.
+ *
+ * RETURNS
+ *     Calling thread's last error code value.
  */
 DWORD WINAPI GetLastError(void)
 {
@@ -371,9 +404,13 @@
 
 
 /**********************************************************************
- *           SetLastError   (KERNEL.147) (KERNEL32.497)
+ * SetLastError [KERNEL.147] [KERNEL32.497]  Sets the last-error code.
+ *
+ * RETURNS
+ *    None.
  */
-void WINAPI SetLastError( DWORD error )
+void WINAPI SetLastError(
+    DWORD error) /* [in] Per-thread error code */
 {
     THDB *thread = THREAD_Current();
     /* This one must work before we have a thread (FIXME) */
@@ -382,11 +419,27 @@
 
 
 /**********************************************************************
- *           SetLastErrorEx   (USER32.484)
+ * SetLastErrorEx [USER32.485]  Sets the last-error code.
+ *
+ * RETURNS
+ *    None.
  */
-void WINAPI SetLastErrorEx( DWORD error, DWORD type )
+void WINAPI SetLastErrorEx(
+    DWORD error, /* [in] Per-thread error code */
+    DWORD type)  /* [in] Error type */
 {
-    /* FIXME: what about 'type'? */
+    TRACE(thread, "(%08lx, %08lx)\n", error,type);
+    switch(type) {
+        case 0:
+            break;
+        case SLE_ERROR:
+        case SLE_MINORERROR:
+        case SLE_WARNING:
+            /* Fall through for now */
+        default:
+            FIXME(thread, "(error=%08lx, type=%08lx): Unhandled type\n", error,type);
+            break;
+    }
     SetLastError( error );
 }
 
@@ -416,14 +469,15 @@
     return ret + i;
 }
 
+
 /**********************************************************************
- *           TlsAlloc   (KERNEL32.530)
+ * TlsAlloc [KERNEL32.530]  Allocates a TLS index.
  *
  * Allocates a thread local storage index
  *
  * RETURNS
- *	TLS Index
- *	0xFFFFFFFF: Failure
+ *    Success: TLS Index
+ *    Failure: 0xFFFFFFFF
  */
 DWORD WINAPI TlsAlloc(void)
 {
@@ -432,9 +486,16 @@
 
 
 /**********************************************************************
- *           TlsFree   (KERNEL32.531)
+ * TlsFree [KERNEL32.531]  Releases a TLS index.
+ *
+ * Releases a thread local storage index, making it available for reuse
+ * 
+ * RETURNS
+ *    Success: TRUE
+ *    Failure: FALSE
  */
-BOOL32 WINAPI TlsFree( DWORD index )
+BOOL32 WINAPI TlsFree(
+    DWORD index) /* [in] TLS Index to free */
 {
     DWORD mask;
     THDB *thread = THREAD_Current();
@@ -462,14 +523,15 @@
 
 
 /**********************************************************************
- *           TlsGetValue   (KERNEL32.532)
+ * TlsGetValue [KERNEL32.532]  Gets value in a thread's TLS slot
+ *
  * RETURNS
- *	!0: Value stored in calling thread's TLS slot for index
- *	0: Check GetLastError() for error code
+ *    Success: Value stored in calling thread's TLS slot for index
+ *    Failure: 0 and GetLastError returns NO_ERROR
  */
 LPVOID WINAPI TlsGetValue(
-	      DWORD index /* TLS index to retrieve value for */
-) {
+    DWORD index) /* [in] TLS index to retrieve value for */
+{
     THDB *thread = THREAD_Current();
     if (index >= 64)
     {
@@ -482,15 +544,16 @@
 
 
 /**********************************************************************
- *           TlsSetValue   (KERNEL32.533)
+ * TlsSetValue [KERNEL32.533]  Stores a value in the thread's TLS slot.
+ *
  * RETURNS
- *	TRUE: Successful
- *      FALSE: Failure
+ *    Success: TRUE
+ *    Failure: FALSE
  */
 BOOL32 WINAPI TlsSetValue(
-	      DWORD index, /* TLS index to set value for */
-	      LPVOID value /* value to be stored */
-) {
+    DWORD index,  /* [in] TLS index to set value for */
+    LPVOID value) /* [in] Value to be stored */
+{
     THDB *thread = THREAD_Current();
     if (index >= 64)
     {
@@ -503,9 +566,15 @@
 
 
 /***********************************************************************
- *           GetThreadContext   (KERNEL32.294)
+ * GetThreadContext [KERNEL32.294]  Retrieves context of thread.
+ *
+ * RETURNS
+ *    Success: TRUE
+ *    Failure: FALSE
  */
-BOOL32 WINAPI GetThreadContext( HANDLE32 handle, CONTEXT *context )
+BOOL32 WINAPI GetThreadContext(
+    HANDLE32 handle,  /* [in]  Handle to thread with context */
+    CONTEXT *context) /* [out] Address of context structure */
 {
     THDB *thread = THREAD_GetPtr( handle, THREAD_GET_CONTEXT );
     if (!thread) return FALSE;
@@ -516,15 +585,20 @@
 
 
 /**********************************************************************
- *           GetThreadPriority   (KERNEL32.296)
+ * GetThreadPriority [KERNEL32.296]  Returns priority for thread.
+ *
+ * RETURNS
+ *    Success: Thread's priority level.
+ *    Failure: THREAD_PRIORITY_ERROR_RETURN
  */
-INT32 WINAPI GetThreadPriority(HANDLE32 hthread)
+INT32 WINAPI GetThreadPriority(
+    HANDLE32 hthread) /* [in] Handle to thread */
 {
     THDB *thread;
     INT32 ret;
     
     if (!(thread = THREAD_GetPtr( hthread, THREAD_QUERY_INFORMATION )))
-        return 0;
+        return THREAD_PRIORITY_ERROR_RETURN;
     ret = thread->delta_priority;
     K32OBJ_DecCount( &thread->header );
     return ret;
@@ -532,9 +606,15 @@
 
 
 /**********************************************************************
- *           SetThreadPriority   (KERNEL32.514)
+ * SetThreadPriority [KERNEL32.514]  Sets priority for thread.
+ *
+ * RETURNS
+ *    Success: TRUE
+ *    Failure: FALSE
  */
-BOOL32 WINAPI SetThreadPriority(HANDLE32 hthread,INT32 priority)
+BOOL32 WINAPI SetThreadPriority(
+    HANDLE32 hthread, /* [in] Handle to thread */
+    INT32 priority)   /* [in] Thread priority level */
 {
     THDB *thread;
     
@@ -545,19 +625,34 @@
     return TRUE;
 }
 
+
 /**********************************************************************
- *           TerminateThread   (KERNEL32)
+ * TerminateThread [KERNEL32.???]  Terminates a thread
+ *
+ * RETURNS
+ *    Success: TRUE
+ *    Failure: FALSE
  */
-BOOL32 WINAPI TerminateThread(HANDLE32 handle,DWORD exitcode)
+BOOL32 WINAPI TerminateThread(
+    HANDLE32 handle, /* [in] Handle to thread */
+    DWORD exitcode)  /* [in] Exit code for thread */
 {
-    FIXME(thread,"(0x%08x,%ld): STUB!\n",handle,exitcode);
+    FIXME(thread,"(0x%08x,%ld): stub\n",handle,exitcode);
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     return TRUE;
 }
 
+
 /**********************************************************************
- *           GetExitCodeThread   (KERNEL32)
+ * GetExitCodeThread [KERNEL32.???]  Gets termination status of thread.
+ * 
+ * RETURNS
+ *    Success: TRUE
+ *    Failure: FALSE
  */
-BOOL32 WINAPI GetExitCodeThread(HANDLE32 hthread,LPDWORD exitcode)
+BOOL32 WINAPI GetExitCodeThread(
+    HANDLE32 hthread, /* [in]  Handle to thread */
+    LPDWORD exitcode) /* [out] Address to receive termination status */
 {
     THDB *thread;
     
@@ -568,34 +663,90 @@
     return TRUE;
 }
 
-/**********************************************************************
- *           ResumeThread   (KERNEL32)
- */
-BOOL32 WINAPI ResumeThread( HANDLE32 handle )
-{
-    FIXME(thread,"(0x%08x): STUB!\n",handle);
-    return TRUE;
-}
 
 /**********************************************************************
- *           SuspendThread   (KERNEL32)
+ * ResumeThread [KERNEL32.587]  Resumes a thread.
+ *
+ * Decrements a thread's suspend count.  When count is zero, the
+ * execution of the thread is resumed.
+ *
+ * RETURNS
+ *    Success: Previous suspend count
+ *    Failure: 0xFFFFFFFF
  */
-BOOL32 WINAPI SuspendThread( HANDLE32 handle )
+DWORD WINAPI ResumeThread(
+    HANDLE32 handle) /* [in] Indentifies thread to restart */
 {
-    FIXME(thread,"(0x%08x): STUB!\n",handle);
-    return TRUE;
+    FIXME(thread,"(0x%08x): stub\n",handle);
+    return 0xFFFFFFFF;
 }
 
+
 /**********************************************************************
- *           GetThreadTimes   (KERNEL32)
+ * SuspendThread [KERNEL32.681]  Suspends a thread.
+ *
+ * RETURNS
+ *    Success: Previous suspend count
+ *    Failure: 0xFFFFFFFF
+ */
+DWORD WINAPI SuspendThread(
+    HANDLE32 handle) /* [in] Handle to the thread */
+{
+    FIXME(thread,"(0x%08x): stub\n",handle);
+    return 0xFFFFFFFF;
+}
+
+
+/**********************************************************************
+ * GetThreadTimes [KERNEL32.???]  Obtains timing information.
+ *
+ * NOTES
+ *    What are the fields where these values are stored?
+ *
+ * RETURNS
+ *    Success: TRUE
+ *    Failure: FALSE
  */
 BOOL32 WINAPI GetThreadTimes( 
-	HANDLE32 thread, 
-	LPFILETIME creationtime,
-	LPFILETIME exittime,
-	LPFILETIME kerneltime,
-	LPFILETIME usertime
-) {
-	SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-	return FALSE;
+    HANDLE32 thread,         /* [in]  Specifies the thread of interest */
+    LPFILETIME creationtime, /* [out] When the thread was created */
+    LPFILETIME exittime,     /* [out] When the thread was destroyed */
+    LPFILETIME kerneltime,   /* [out] Time thread spent in kernel mode */
+    LPFILETIME usertime)     /* [out] Time thread spent in user mode */
+{
+    FIXME(thread,"(0x%08x): stub\n",thread);
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
+
+
+/**********************************************************************
+ * AttachThreadInput [KERNEL32.8]  Attaches input of 1 thread to other
+ *
+ * Attaches the input processing mechanism of one thread to that of
+ * another thread.
+ *
+ * RETURNS
+ *    Success: TRUE
+ *    Failure: FALSE
+ */
+BOOL32 WINAPI AttachThreadInput( 
+    DWORD idAttach,   /* [in] Thread to attach */
+    DWORD idAttachTo, /* [in] Thread to attach to */
+    BOOL32 fAttach)   /* [in] Attach or detach */
+{
+    BOOL32 ret;
+
+    FIXME(thread, "(0x%08lx,0x%08lx,%d): stub\n",idAttach,idAttachTo,fAttach);
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    if (fAttach) {
+        /* Attach threads */
+        ret = FALSE;
+    }
+    else {
+        /* Detach threads */
+        ret = FALSE;
+    };
+    return ret;
+}
+
diff --git a/tools/build.c b/tools/build.c
index 154f679..814a5b0 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -1872,9 +1872,9 @@
 	else 
 	{
 	    fprintf( outfile, "\tpushw $0\n" );
-	    fprintf( outfile, "\tpushw " PREFIX "CALLTO16_RetAddr_long+2\n" );
+	    fprintf( outfile, "\tpushw " PREFIX "CALLTO16_RetAddr_eax+2\n" );
 	    fprintf( outfile, "\tpushw $0\n" );
-	    fprintf( outfile, "\tpushw " PREFIX "CALLTO16_RetAddr_long\n" );
+	    fprintf( outfile, "\tpushw " PREFIX "CALLTO16_RetAddr_eax\n" );
 	}
 
         /* Push the called routine address */
@@ -1957,6 +1957,7 @@
 {
     fprintf( outfile, "\t.globl " PREFIX "CALLTO16_Ret_word\n" );
     fprintf( outfile, "\t.globl " PREFIX "CALLTO16_Ret_long\n" );
+    fprintf( outfile, "\t.globl " PREFIX "CALLTO16_Ret_eax\n" );
 
     fprintf( outfile, PREFIX "CALLTO16_Ret_word:\n" );
     fprintf( outfile, "\txorl %%edx,%%edx\n" );
@@ -1967,6 +1968,7 @@
     fprintf( outfile, "\tshll $16,%%edx\n" );
     fprintf( outfile, "\tmovw %%ax,%%dx\n" );
     fprintf( outfile, "\tmovl %%edx,%%eax\n" );
+    fprintf( outfile, PREFIX "CALLTO16_Ret_eax:\n" );
 
     /* Restore 32-bit segment registers */
 
@@ -2007,9 +2009,11 @@
     fprintf( outfile, "\t.data\n" );
     fprintf( outfile, "\t.globl " PREFIX "CALLTO16_RetAddr_word\n" );
     fprintf( outfile, "\t.globl " PREFIX "CALLTO16_RetAddr_long\n" );
+    fprintf( outfile, "\t.globl " PREFIX "CALLTO16_RetAddr_eax\n" );
     fprintf( outfile, "\t.globl " PREFIX "CALLTO16_Current_fs\n" );
     fprintf( outfile, PREFIX "CALLTO16_RetAddr_word:\t.long 0\n" );
     fprintf( outfile, PREFIX "CALLTO16_RetAddr_long:\t.long 0\n" );
+    fprintf( outfile, PREFIX "CALLTO16_RetAddr_eax:\t.long 0\n" );
     fprintf( outfile, PREFIX "CALLTO16_Current_fs:\t.long 0\n" );
     fprintf( outfile, "\t.text\n" );
 }
@@ -2095,12 +2099,15 @@
  *
  * Stack layout:
  *   ...     ...
- * (esp+208) ret addr (or relay addr when debugging(relay) is on)
- * (esp+204) entry point
+ * (esp+336) ret addr (or relay addr when debugging(relay) is on)
+ * (esp+332) entry point
+ * (esp+204) buffer area to allow stack frame manipulation
  * (esp+0)   CONTEXT struct
  */
 static void BuildCallFrom32Regs( FILE *outfile )
 {
+#define STACK_SPACE 128
+
     /* Function header */
 
     fprintf( outfile, "\n\t.align 4\n" );
@@ -2110,6 +2117,10 @@
     fprintf( outfile, "\t.globl " PREFIX "CALL32_Regs\n" );
     fprintf( outfile, PREFIX "CALL32_Regs:\n" );
 
+    /* Allocate some buffer space on the stack */
+   
+    fprintf( outfile, "\tleal -%d(%%esp), %%esp\n", STACK_SPACE );
+    
     /* Build the context structure */
 
     fprintf( outfile, "\tpushw $0\n" );
@@ -2118,7 +2129,7 @@
     fprintf( outfile, "\tpushfl\n" );
     fprintf( outfile, "\tpushw $0\n" );
     fprintf( outfile, "\t.byte 0x66\n\tpushl %%cs\n" );
-    fprintf( outfile, "\tpushl 20(%%esp)\n" );  /* %eip at time of call */
+    fprintf( outfile, "\tpushl %d(%%esp)\n", 16+STACK_SPACE+4 );  /* %eip at time of call */
     fprintf( outfile, "\tpushl %%ebp\n" );
 
     fprintf( outfile, "\tpushl %%eax\n" );
@@ -2145,7 +2156,7 @@
     fprintf( outfile, "\tfsave %d(%%esp)\n", CONTEXTOFFSET(FloatSave) );
 
     fprintf( outfile, "\tleal %d(%%esp),%%eax\n",
-             sizeof(CONTEXT) + 4 ); /* %esp at time of call */
+             sizeof(CONTEXT) + STACK_SPACE + 4 ); /* %esp at time of call */
     fprintf( outfile, "\tmovl %%eax,%d(%%esp)\n", CONTEXTOFFSET(Esp) );
 
     fprintf( outfile, "\tcall " PREFIX "RELAY_CallFrom32Regs\n" );
@@ -2184,6 +2195,8 @@
     fprintf( outfile, "\tpopfl\n" );
     fprintf( outfile, "\tpopl %%esp\n" );
     fprintf( outfile, "\tret\n" );
+
+#undef STACK_SPACE
 }
 
 
diff --git a/tools/examine-relay b/tools/examine-relay
index 6030f08..85e7ff7 100755
--- a/tools/examine-relay
+++ b/tools/examine-relay
@@ -1,33 +1,57 @@
 #!/usr/bin/perl -w
 # -----------------------------------------------------------------------------
+#
+# Relay-checker.
+#
+# This program will inspect a log file with relay information and tell you
+# whether calls and returns match.  If not, this suggests that the parameter
+# list might be incorrect.  (It could be something else also.)
+#
+# Copyright 1997-1998 Morten Welinder (terra@diku.dk)
+#
+# -----------------------------------------------------------------------------
 
 my $srcfile = $ARGV[0];
 my @callstack = ();
+my $newlineerror = 0;
+my $indentp = 1;
 
 open (IN, "<$srcfile") || die "Cannot open $srcfile for reading: $!\n";
 LINE:
 while (<IN>) {
-    if (/^Call ([A-Za-z0-9]+\.[0-9]+): .*\)/) {
+    if (/^Call ([A-Za-z0-9]+\.\d+): .*\)/) {
 	my $func = $1;
 	if (/ ret=(........)$/ ||
-	    / ret=(....:....) ds=....$/) {
+	    / ret=(....:....) (ds=....)$/ ||
+	    / ret=(........) (fs=....)$/) {
 	    my $retaddr = $1;
-	    push @callstack, [$func,$retaddr];
+	    my $segreg = $2;
+
+	    $segreg = "none" unless defined $segreg;
+	    push @callstack, [$func,$retaddr, $segreg];
 	    next;
 	} else {
 	    # Assume a line got cut by a line feed in a string.
 	    $_ .= scalar (<IN>);
-	    print "[$_]";
+	    if (!$newlineerror) {
+		print "Error: string probably cut by newline.\n";
+		$newlineerror = 1;
+	    }	    
+	    # print "[$_]";
 	    redo;
 	}
     }
 
 
-    if (/^Ret  ([A-Za-z0-9]+\.[0-9]+): .* ret=(........)$/ ||
-	/^Ret  ([A-Za-z0-9]+\.[0-9]+): .* ret=(....:....) ds=....$/) {
+    if (/^Ret  ([A-Za-z0-9]+\.\d+): .* ret=(........)$/ ||
+	/^Ret  ([A-Za-z0-9]+\.\d+): .* ret=(....:....) (ds=....)$/ ||
+	/^Ret  ([A-Za-z0-9]+\.\d+): .* ret=(........) (fs=....)$/) {
 	my $func = $1;
 	my $retaddr = $2;
-	my ($topfunc,$topaddr);
+	my $segreg = $3;
+	my ($topfunc,$topaddr,$topseg);
+
+	$segreg = "none" unless defined $segreg;
 
       POP:
 	while (1) {
@@ -36,7 +60,7 @@
 		next LINE;
 	    }
 
-	    ($topfunc,$topaddr) = @{pop @callstack};
+	    ($topfunc,$topaddr,$topseg) = @{pop @callstack};
 
 	    if ($topfunc ne $func) {
 		print "Error: Return from $topfunc, but call from $func.\n";
@@ -45,10 +69,16 @@
 	    last POP;
 	}
 
-	if ($topaddr eq $retaddr) {
-	    print "OK: $func from $retaddr.\n";
+	my $addrok = ($topaddr eq $retaddr);
+	my $segok = ($topseg eq $segreg);
+	if ($addrok && $segok) {
+	    print "OK: ", ($indentp ? (' ' x (1 + $#callstack)) : '');
+	    print "$func from $retaddr with $segreg.\n";
 	} else {
-	    print "Error: Return from $func is to $retaddr, not $topaddr.\n";
+	    print "Error: Return from $func is to $retaddr, not $topaddr.\n"
+		if !$addrok;
+	    print "Error: Return from $func with segreg $segreg, not $topseg.\n"
+		if !$segok;
 	}    
     }
 }
diff --git a/tools/find_debug_channels b/tools/find_debug_channels
index dbec877..c5e72e9 100644
--- a/tools/find_debug_channels
+++ b/tools/find_debug_channels
@@ -1,10 +1,12 @@
 #!/bin/bash
 #
 # This script scans the whole source code for symbols of the form 
-# 'dprintf_xxx(yyy' where yyy is a C identifier and outputs, on the
-# standard output a sorted list of the identifiers found in the .c 
-# files. Each identifier is reported once. Header files are not
-# scanned.
+# 'xxx(yyy' where:
+#        xxx is either TRACE, WARN, ERR or WARN
+#        yyy is a C identifier 
+# It outputs on the standard output a sorted list of the 
+# yyy identifiers found in the .c files. 
+# Each identifier is reported once. Header files are not scanned.
 #
 # The script can be given an argument that specify the files to be
 # searched according to the following scheme:
diff --git a/win32/Makefile.in b/win32/Makefile.in
index b9acdb9..bebf632 100644
--- a/win32/Makefile.in
+++ b/win32/Makefile.in
@@ -9,7 +9,6 @@
 	advapi.c \
 	code_page.c \
 	console.c \
-	environment.c \
 	error.c \
 	except.c \
 	file.c \
diff --git a/win32/code_page.c b/win32/code_page.c
index 05e1ac2..a43c226 100644
--- a/win32/code_page.c
+++ b/win32/code_page.c
@@ -91,7 +91,7 @@
     int ret;
 
     if (srclen == -1)
-	srclen = lstrlen32A(src)+1;
+	srclen = lstrlen32A(src);
     if (!dstlen || !dst)
 	return srclen;
 
@@ -103,7 +103,7 @@
 	dst++;    src++;
 	dstlen--; srclen--;
     }
-    if (dstlen == 0) {
+    if ((dstlen == 0) && *src) {
 	SetLastError(ERROR_INSUFFICIENT_BUFFER);
 	return 0;
     }
diff --git a/win32/console.c b/win32/console.c
index 6c2719b..1ab7d84 100644
--- a/win32/console.c
+++ b/win32/console.c
@@ -223,7 +223,7 @@
 		return FALSE;
 	}
 
-	PROCESS_CloseObjHandles(pdb, &console->header);
+        HANDLE_CloseAll( pdb, &console->header );
 
 	K32OBJ_DecCount( &console->header );
 	pdb->console = NULL;
@@ -335,7 +335,7 @@
 	SYSTEM_LOCK();
 	if (pdb->console != NULL) {
 		CONSOLE *console = (CONSOLE *)pdb->console;
-		handle = (HFILE32)HANDLE_Alloc(&console->header, 0, TRUE);
+		handle = (HFILE32)HANDLE_Alloc(pdb, &console->header, 0, TRUE);
 	}
 	SYSTEM_UNLOCK();
 	return handle;
@@ -392,14 +392,14 @@
 	console->slave = slave;
 	console->pid = pid;
 
-	if ((hIn = HANDLE_Alloc(&console->header, 0, TRUE)) == INVALID_HANDLE_VALUE32)
+	if ((hIn = HANDLE_Alloc(pdb,&console->header, 0, TRUE)) == INVALID_HANDLE_VALUE32)
         {
             K32OBJ_DecCount(&console->header);
             SYSTEM_UNLOCK();
             return FALSE;
 	}
 
-	if ((hOut = HANDLE_Alloc(&console->header, 0, TRUE)) == INVALID_HANDLE_VALUE32)
+	if ((hOut = HANDLE_Alloc(pdb,&console->header, 0, TRUE)) == INVALID_HANDLE_VALUE32)
         {
             CloseHandle(hIn);
             K32OBJ_DecCount(&console->header);
@@ -408,7 +408,7 @@
 	}
 
 
-	if ((hErr = HANDLE_Alloc(&console->header, 0, TRUE)) == INVALID_HANDLE_VALUE32)
+	if ((hErr = HANDLE_Alloc(pdb,&console->header, 0, TRUE)) == INVALID_HANDLE_VALUE32)
         {
             CloseHandle(hIn);
             CloseHandle(hOut);
diff --git a/win32/environment.c b/win32/environment.c
deleted file mode 100644
index 70c253a..0000000
--- a/win32/environment.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Win32 kernel functions
- *
- * Copyright 1995 Martin von Loewis and Cameron Heide
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include "windows.h"
-#include "winerror.h"
-#include "module.h"
-#include "task.h"
-#include "debug.h"
-#include "process.h"  /* for PROCESS_Current() */
-
-
-/***********************************************************************
- *           GetCommandLineA      (KERNEL32.161)
- */
-LPCSTR WINAPI GetCommandLine32A(void)
-{
-    return PROCESS_Current()->env_db->cmd_line;
-}
-
-/***********************************************************************
- *           GetCommandLineW      (KERNEL32.162)
- */
-LPCWSTR WINAPI GetCommandLine32W(void)
-{
-    static WCHAR buffer[1024];
-
-    lstrcpynAtoW(buffer,GetCommandLine32A(),1024);
-    return buffer;
-}
-
-
-/***********************************************************************
- *           GetSystemPowerStatus      (KERNEL32.621)
- */
-BOOL32 WINAPI GetSystemPowerStatus(LPSYSTEM_POWER_STATUS sps_ptr)
-{
-    return FALSE;   /* no power management support */
-}
-
-
-/***********************************************************************
- *           SetSystemPowerState      (KERNEL32.630)
- */
-BOOL32 WINAPI SetSystemPowerState(BOOL32 suspend_or_hibernate,
-                                  BOOL32 force_flag)
-{
-    /* suspend_or_hibernate flag: w95 does not support
-       this feature anyway */
-
-    for ( ;0; )
-    {
-        if ( force_flag )
-        {
-        }
-        else
-        {
-        }
-    }
-    return TRUE;
-}
-
diff --git a/win32/file.c b/win32/file.c
index 03dfa3e..c0eb932 100644
--- a/win32/file.c
+++ b/win32/file.c
@@ -40,7 +40,8 @@
 	TRACE(file, "%d %p %ld\n", hFile, lpBuffer, 
 		     numberOfBytesToWrite);
 	
-	if (!(ioptr = HANDLE_GetObjPtr( hFile, K32OBJ_UNKNOWN, 0 ))) 
+	if (!(ioptr = HANDLE_GetObjPtr( PROCESS_Current(), hFile,
+                                        K32OBJ_UNKNOWN, 0 ))) 
 		return HFILE_ERROR32;
         if (K32OBJ_OPS(ioptr)->write)
             status = K32OBJ_OPS(ioptr)->write(ioptr, lpBuffer, numberOfBytesToWrite, 
@@ -61,7 +62,8 @@
 	TRACE(file, "%d %p %ld\n", hFile, lpBuffer, 
 		     numberOfBytesToRead);
 	
-	if (!(ioptr = HANDLE_GetObjPtr( hFile, K32OBJ_UNKNOWN, 0 ))) 
+	if (!(ioptr = HANDLE_GetObjPtr( PROCESS_Current(), hFile,
+                                        K32OBJ_UNKNOWN, 0 ))) 
 		return HFILE_ERROR32;
         if (K32OBJ_OPS(ioptr)->read)
             status = K32OBJ_OPS(ioptr)->read(ioptr, lpBuffer, numberOfBytesToRead, 
diff --git a/win32/kernel32.c b/win32/kernel32.c
index beabee6..5b67179 100644
--- a/win32/kernel32.c
+++ b/win32/kernel32.c
@@ -2,6 +2,7 @@
  * KERNEL32 thunks and other undocumented stuff
  *
  * Copyright 1997-1998 Marcus Meissner
+ * Copyright 1998      Ulrich Weigand
  */
 
 #include <stdio.h>
@@ -30,17 +31,17 @@
  * Generates a FT_Prolog call.
  *	
  *  0FB6D1                  movzbl edx,cl
- *  8B1495xxxxxxxx	    mov edx,[4*edx + xxxxxxxx]
+ *  8B1495xxxxxxxx	    mov edx,[4*edx + targetTable]
  *  68xxxxxxxx		    push FT_Prolog
  *  C3			    lret
  */
-static void _write_ftprolog(LPBYTE thunk,DWORD thunkstart) {
+static void _write_ftprolog(LPBYTE relayCode ,DWORD *targetTable) {
 	LPBYTE	x;
 
-	x	= thunk;
+	x	= relayCode;
 	*x++	= 0x0f;*x++=0xb6;*x++=0xd1; /* movzbl edx,cl */
-	*x++	= 0x8B;*x++=0x14;*x++=0x95;*(DWORD*)x= thunkstart;
-	x+=4;	/* mov edx, [4*edx + thunkstart] */
+	*x++	= 0x8B;*x++=0x14;*x++=0x95;*(DWORD**)x= targetTable;
+	x+=4;	/* mov edx, [4*edx + targetTable] */
 	*x++	= 0x68; *(DWORD*)x = (DWORD)GetProcAddress32(GetModuleHandle32A("KERNEL32"),"FT_Prolog");
 	x+=4; 	/* push FT_Prolog */
 	*x++	= 0xC3;		/* lret */
@@ -48,36 +49,26 @@
 }
 
 /***********************************************************************
- *			FT_PrologPrime			(KERNEL32.89)
- */
-void WINAPI FT_PrologPrime(
-	DWORD startind,		/* [in] start of thunktable */
-	LPBYTE thunk		/* [in] thunk codestart */
-) {
-	_write_ftprolog(thunk,*(DWORD*)(startind+thunk));
-}
-
-/***********************************************************************
  *	_write_qtthunk					(internal)
  * Generates a QT_Thunk style call.
  *
  *  33C9                    xor ecx, ecx
  *  8A4DFC                  mov cl , [ebp-04]
- *  8B148Dxxxxxxxx          mov edx, [4*ecx + (EAX+EDX)]
+ *  8B148Dxxxxxxxx          mov edx, [4*ecx + targetTable]
  *  B8yyyyyyyy              mov eax, QT_Thunk
  *  FFE0                    jmp eax
  */
 static void _write_qtthunk(
-	LPBYTE start,		/* [in] start of QT_Thunk stub */
-	DWORD thunkstart	/* [in] start of thunk (for index lookup) */
+	LPBYTE relayCode,	/* [in] start of QT_Thunk stub */
+	DWORD *targetTable	/* [in] start of thunk (for index lookup) */
 ) {
 	LPBYTE	x;
 
-	x	= start;
+	x	= relayCode;
 	*x++	= 0x33;*x++=0xC9; /* xor ecx,ecx */
 	*x++	= 0x8A;*x++=0x4D;*x++=0xFC; /* movb cl,[ebp-04] */
-	*x++	= 0x8B;*x++=0x14;*x++=0x8D;*(DWORD*)x= thunkstart;
-	x+=4;	/* mov edx, [4*ecx + (EAX+EDX) */
+	*x++	= 0x8B;*x++=0x14;*x++=0x8D;*(DWORD**)x= targetTable;
+	x+=4;	/* mov edx, [4*ecx + targetTable */
 	*x++	= 0xB8; *(DWORD*)x = (DWORD)GetProcAddress32(GetModuleHandle32A("KERNEL32"),"QT_Thunk");
 	x+=4; 	/* mov eax , QT_Thunk */
 	*x++	= 0xFF; *x++ = 0xE0;	/* jmp eax */
@@ -153,9 +144,9 @@
 			return 0;
 		ths->ptr = (DWORD)PTR_SEG_TO_LIN(ths16->ptr);
 		/* code offset for QT_Thunk is at 0x1C...  */
-		_write_qtthunk (((LPBYTE)ths) + ths->x1C,ths->ptr);
+		_write_qtthunk (((LPBYTE)ths) + ths->x1C,(DWORD *)ths->ptr);
 		/* code offset for FT_Prolog is at 0x20...  */
-		_write_ftprolog(((LPBYTE)ths) + ths->x20,ths->ptr);
+		_write_ftprolog(((LPBYTE)ths) + ths->x20,(DWORD *)ths->ptr);
 		return 1;
 	}
 	return TRUE;
@@ -193,6 +184,185 @@
 
 
 /**********************************************************************
+ * 		FT_Prolog			(KERNEL32.233)
+ * 
+ * The set of FT_... thunk routines is used instead of QT_Thunk,
+ * if structures have to be converted from 32-bit to 16-bit
+ * (change of member alignment, conversion of members).
+ *
+ * The thunk function (as created by the thunk compiler) calls
+ * FT_Prolog at the beginning, to set up a stack frame and
+ * allocate a 64 byte buffer on the stack.
+ * The input parameters (target address and some flags) are
+ * saved for later use by FT_Thunk.
+ *
+ * Input:  EDX  16-bit target address (SEGPTR)
+ *         CX   bits  0..7   target number (in target table)
+ *              bits  8..9   some flags (unclear???)
+ *              bits 10..15  number of DWORD arguments
+ *
+ * Output: A new stackframe is created, and a 64 byte buffer
+ *         allocated on the stack. The layout of the stack 
+ *         on return is as follows:
+ *
+ *  (ebp+4)  return address to caller of thunk function
+ *  (ebp)    old EBP
+ *  (ebp-4)  saved EBX register of caller
+ *  (ebp-8)  saved ESI register of caller
+ *  (ebp-12) saved EDI register of caller
+ *  (ebp-16) saved ECX register, containing flags
+ *  (ebp-20) bitmap containing parameters that are to be converted
+ *           by FT_Thunk; it is initialized to 0 by FT_Prolog and
+ *           filled in by the thunk code before calling FT_Thunk
+ *  (ebp-24)
+ *    ...    (unclear)
+ *  (ebp-44)
+ *  (ebp-48) saved EAX register of caller (unclear, never restored???)
+ *  (ebp-52) saved EDX register, containing 16-bit thunk target
+ *  (ebp-56)
+ *    ...    (unclear)
+ *  (ebp-64)
+ *
+ *  ESP is EBP-68 on return.
+ *         
+ */
+
+#define POP_DWORD(ctx)		(*((DWORD *)ESP_reg(ctx))++)
+#define PUSH_DWORD(ctx, val) 	*--((DWORD *)ESP_reg(ctx)) = (val)
+
+VOID WINAPI FT_Prolog(CONTEXT *context)
+{
+    /* Pop return address to thunk code */
+    EIP_reg(context) = POP_DWORD(context);
+
+    /* Build stack frame */
+    PUSH_DWORD(context, EBP_reg(context));
+    EBP_reg(context) = ESP_reg(context);
+
+    /* Allocate 64-byte Thunk Buffer */
+    ESP_reg(context) -= 64;
+    memset((char *)ESP_reg(context), '\0', 64);
+
+    /* Store Flags (ECX) and Target Address (EDX) */
+    /* Save other registers to be restored later */
+    *(DWORD *)(EBP_reg(context) -  4) = EBX_reg(context);
+    *(DWORD *)(EBP_reg(context) -  8) = ESI_reg(context);
+    *(DWORD *)(EBP_reg(context) - 12) = EDI_reg(context);
+    *(DWORD *)(EBP_reg(context) - 16) = ECX_reg(context);
+
+    *(DWORD *)(EBP_reg(context) - 48) = EAX_reg(context);
+    *(DWORD *)(EBP_reg(context) - 52) = EDX_reg(context);
+    
+    /* Push return address back onto stack */
+    PUSH_DWORD(context, EIP_reg(context));
+}
+
+/**********************************************************************
+ * 		FT_Thunk			(KERNEL32.234)
+ *
+ * This routine performs the actual call to 16-bit code, 
+ * similar to QT_Thunk. The differences are:
+ *  - The call target is taken from the buffer created by FT_Prolog
+ *  - Those arguments requested by the thunk code (by setting the
+ *    corresponding bit in the bitmap at EBP-20) are converted
+ *    from 32-bit pointers to segmented pointers (those pointers
+ *    are guaranteed to point to structures copied to the stack
+ *    by the thunk code, so we always use the 16-bit stack selector
+ *    for those addresses).
+ * 
+ *    The bit #i of EBP-20 corresponds here to the DWORD starting at
+ *    ESP+4 + 2*i.
+ * 
+ * FIXME: It is unclear what happens if there are more than 32 WORDs 
+ *        of arguments, so that the single DWORD bitmap is no longer
+ *        sufficient ...
+ */
+
+VOID WINAPI FT_Thunk(CONTEXT *context)
+{
+    DWORD mapESPrelative = *(DWORD *)(EBP_reg(context) - 20);
+    DWORD callTarget     = *(DWORD *)(EBP_reg(context) - 52);
+
+    CONTEXT context16;
+    DWORD i, argsize;
+    LPBYTE newstack;
+    THDB *thdb = THREAD_Current();
+
+    memcpy(&context16,context,sizeof(context16));
+
+    CS_reg(&context16)  = HIWORD(callTarget);
+    IP_reg(&context16)  = LOWORD(callTarget);
+    EBP_reg(&context16) = OFFSETOF( thdb->cur_stack )
+                           + (WORD)&((STACK16FRAME*)0)->bp;
+
+    argsize  = EBP_reg(context)-ESP_reg(context)-0x44;
+    newstack = ((LPBYTE)THREAD_STACK16(thdb))-argsize;
+
+    memcpy( newstack, (LPBYTE)ESP_reg(context)+4, argsize );
+
+    for (i = 0; i < 32; i++)	/* NOTE: What about > 32 arguments? */
+	if (mapESPrelative & (1 << i))
+	{
+	    SEGPTR *arg = (SEGPTR *)(newstack + 2*i);
+	    *arg = PTR_SEG_OFF_TO_SEGPTR(SELECTOROF(thdb->cur_stack), 
+					 *(LPBYTE *)arg - newstack);
+	}
+
+    EAX_reg(context) = Callbacks->CallRegisterShortProc( &context16, argsize );
+}
+
+/**********************************************************************
+ * 		FT_ExitNN		(KERNEL32.218 - 232)
+ *
+ * One of the FT_ExitNN functions is called at the end of the thunk code.
+ * It removes the stack frame created by FT_Prolog, moves the function
+ * return from EBX to EAX (yes, FT_Thunk did use EAX for the return 
+ * value, but the thunk code has moved it from EAX to EBX in the 
+ * meantime ... :-), restores the caller's EBX, ESI, and EDI registers,
+ * and perform a return to the CALLER of the thunk code (while removing
+ * the given number of arguments from the caller's stack).
+ */
+
+VOID WINAPI FT_Exit(CONTEXT *context, int nPopArgs)
+{
+    /* Return value is in EBX */
+    EAX_reg(context) = EBX_reg(context);
+
+    /* Restore EBX, ESI, and EDI registers */
+    EBX_reg(context) = *(DWORD *)(EBP_reg(context) -  4);
+    ESI_reg(context) = *(DWORD *)(EBP_reg(context) -  8);
+    EDI_reg(context) = *(DWORD *)(EBP_reg(context) - 12);
+
+    /* Clean up stack frame */
+    ESP_reg(context) = EBP_reg(context);
+    EBP_reg(context) = POP_DWORD(context);
+
+    /* Pop return address to CALLER of thunk code */
+    EIP_reg(context) = POP_DWORD(context);
+    /* Remove arguments */
+    ESP_reg(context) += nPopArgs;
+    /* Push return address back onto stack */
+    PUSH_DWORD(context, EIP_reg(context));
+}
+
+VOID WINAPI FT_Exit0 (CONTEXT *context) { FT_Exit(context,  0); }
+VOID WINAPI FT_Exit4 (CONTEXT *context) { FT_Exit(context,  4); }
+VOID WINAPI FT_Exit8 (CONTEXT *context) { FT_Exit(context,  8); }
+VOID WINAPI FT_Exit12(CONTEXT *context) { FT_Exit(context, 12); }
+VOID WINAPI FT_Exit16(CONTEXT *context) { FT_Exit(context, 16); }
+VOID WINAPI FT_Exit20(CONTEXT *context) { FT_Exit(context, 20); }
+VOID WINAPI FT_Exit24(CONTEXT *context) { FT_Exit(context, 24); }
+VOID WINAPI FT_Exit28(CONTEXT *context) { FT_Exit(context, 28); }
+VOID WINAPI FT_Exit32(CONTEXT *context) { FT_Exit(context, 32); }
+VOID WINAPI FT_Exit36(CONTEXT *context) { FT_Exit(context, 36); }
+VOID WINAPI FT_Exit40(CONTEXT *context) { FT_Exit(context, 40); }
+VOID WINAPI FT_Exit44(CONTEXT *context) { FT_Exit(context, 44); }
+VOID WINAPI FT_Exit48(CONTEXT *context) { FT_Exit(context, 48); }
+VOID WINAPI FT_Exit52(CONTEXT *context) { FT_Exit(context, 52); }
+VOID WINAPI FT_Exit56(CONTEXT *context) { FT_Exit(context, 56); }
+
+
+/**********************************************************************
  *           WOWCallback16 (KERNEL32.62)(WOW32.2)
  * Calls a win16 function with a single DWORD argument.
  * RETURNS
@@ -242,7 +412,7 @@
 }
 
 /***********************************************************************
- * 		_KERNEL32_43 	(KERNEL32.42)
+ * 		ThunkInitLS 	(KERNEL32.43)
  * A thunkbuffer link routine 
  * The thunkbuf looks like:
  *
@@ -254,7 +424,7 @@
  * RETURNS
  *	segmented pointer to thunk?
  */
-DWORD WINAPI _KERNEL32_43(
+DWORD WINAPI ThunkInitLS(
 	LPDWORD thunk,	/* [in] win32 thunk */
 	LPCSTR thkbuf,	/* [in] thkbuffer name in win16 dll */
 	DWORD len,	/* [in] thkbuffer length */
@@ -293,39 +463,70 @@
 }
 
 /***********************************************************************
- * 		_KERNEL32_45 	(KERNEL32.44)
- * Another 32->16 thunk, the difference to QT_Thunk is, that the called routine
- * uses 0x66 lret, and that we have to pass CX in DI.
- * (there seems to be some kind of BL/BX return magic too...)
+ * 		Common32ThkLS 	(KERNEL32.45)
+ * 
+ * This is another 32->16 thunk, independent of the QT_Thunk/FT_Thunk
+ * style thunks. The basic difference is that the parameter conversion 
+ * is done completely on the *16-bit* side here. Thus we do not call
+ * the 16-bit target directly, but call a common entry point instead.
+ * This entry function then calls the target according to the target
+ * number passed in the DI register.
+ * 
+ * Input:  EAX    SEGPTR to the common 16-bit entry point
+ *         CX     offset in thunk table (target number * 4)
+ *         DX     error return value if execution fails (unclear???)
+ *         EDX.HI number of DWORD parameters
  *
- * [crashes]
+ * (Note that we need to move the thunk table offset from CX to DI !)
+ *
+ * The called 16-bit stub expects its stack to look like this:
+ *     ...
+ *   (esp+40)  32-bit arguments
+ *     ...
+ *   (esp+8)   32 byte of stack space available as buffer
+ *   (esp)     8 byte return address for use with 0x66 lret 
+ * 
+ * The called 16-bit stub uses a 0x66 lret to return to 32-bit code,
+ * and uses the EAX register to return a DWORD return value.
+ * Thus we need to use a special assembly glue routine 
+ * (CallRegisterLongProc instead of CallRegisterShortProc).
+ *
+ * Finally, we return to the caller, popping the arguments off 
+ * the stack.
+ *
+ * FIXME: The called function uses EBX to return the number of 
+ *        arguments that are to be popped off the caller's stack.
+ *        This is clobbered by the assembly glue, so we simply use
+ *        the original EDX.HI to get the number of arguments.
+ *        (Those two values should be equal anyway ...?)
+ * 
  */
-VOID WINAPI _KERNEL32_45(CONTEXT *context)
+VOID WINAPI Common32ThkLS(CONTEXT *context)
 {
-	CONTEXT	context16;
-	LPBYTE	curstack;
-        DWORD ret,stacksize;
-	THDB *thdb = THREAD_Current();
+    CONTEXT context16;
+    DWORD argsize;
+    THDB *thdb = THREAD_Current();
 
-	TRACE(thunk,"(%%eax=0x%08lx(%%cx=0x%04lx,%%edx=0x%08lx))\n",
-		(DWORD)EAX_reg(context),(DWORD)CX_reg(context),(DWORD)EDX_reg(context)
-	);
-	stacksize = EBP_reg(context)-ESP_reg(context);
-	TRACE(thunk,"	stacksize = %ld\n",stacksize);
+    memcpy(&context16,context,sizeof(context16));
 
-	memcpy(&context16,context,sizeof(context16));
+    DI_reg(&context16)  = CX_reg(context);
+    CS_reg(&context16)  = HIWORD(EAX_reg(context));
+    IP_reg(&context16)  = LOWORD(EAX_reg(context));
+    EBP_reg(&context16) = OFFSETOF( thdb->cur_stack )
+                           + (WORD)&((STACK16FRAME*)0)->bp;
 
-	DI_reg(&context16)	 = CX_reg(context);
-	CS_reg(&context16)	 = HIWORD(EAX_reg(context));
-	IP_reg(&context16)	 = LOWORD(EAX_reg(context));
+    argsize = HIWORD(EDX_reg(context)) * 4;
 
-	curstack = PTR_SEG_TO_LIN(STACK16_PUSH( thdb, stacksize ));
-	memcpy(curstack - stacksize,(LPBYTE)ESP_reg(context),stacksize);
-	ret = Callbacks->CallRegisterLongProc(&context16,0);
-	STACK16_POP( thdb, stacksize );
+    memcpy( ((LPBYTE)THREAD_STACK16(thdb))-argsize,
+            (LPBYTE)ESP_reg(context)+4, argsize );
 
-	TRACE(thunk,". returned %08lx\n",ret);
-	EAX_reg(context) 	 = ret;
+    EAX_reg(context) = Callbacks->CallRegisterLongProc(&context16, argsize + 32);
+
+    /* Clean up caller's stack frame */
+
+    EIP_reg(context) = POP_DWORD(context);
+    ESP_reg(context) += argsize;
+    PUSH_DWORD(context, EIP_reg(context));
 }
 
 /***********************************************************************
@@ -364,7 +565,7 @@
 
 
 /***********************************************************************
- *		(KERNEL32.41)
+ *		ThunkInitLSF		(KERNEL32.41)
  * A thunk setup routine.
  * Expects a pointer to a preinitialized thunkbuffer in the first argument
  * looking like:
@@ -401,7 +602,7 @@
  * RETURNS
  *	unclear, pointer to win16 thkbuffer?
  */
-LPVOID WINAPI _KERNEL32_41(
+LPVOID WINAPI ThunkInitLSF(
 	LPBYTE thunk,	/* [in] win32 thunk */
 	LPCSTR thkbuf,	/* [in] thkbuffer name in win16 dll */
 	DWORD len,	/* [in] length of thkbuffer */
@@ -447,33 +648,73 @@
 }
 
 /***********************************************************************
- *							(KERNEL32.90)
- * QT Thunk priming function
- * Rewrites the first part of the thunk to use the QT_Thunk interface
- * and jumps to the start of that code.
- * [ok]
+ *		FT_PrologPrime			(KERNEL32.89)
+ * 
+ * This function is called from the relay code installed by
+ * ThunkInitLSF. It replaces the location from where it was 
+ * called by a standard FT_Prolog call stub (which is 'primed'
+ * by inserting the correct target table pointer).
+ * Finally, it calls that stub.
+ * 
+ * Input:  ECX    target number + flags (passed through to FT_Prolog)
+ *        (ESP)   offset of location where target table pointer 
+ *                is stored, relative to the start of the relay code
+ *        (ESP+4) pointer to start of relay code
+ *                (this is where the FT_Prolog call stub gets written to)
+ * 
+ * Note: The two DWORD arguments get popped from the stack.
+ *        
  */
-VOID WINAPI _KERNEL32_90(CONTEXT *context)
+VOID WINAPI FT_PrologPrime(CONTEXT *context)
 {
-	TRACE(thunk, "QT Thunk priming; context %p\n", context);
-	
-	_write_qtthunk((LPBYTE)EAX_reg(context),*(DWORD*)(EAX_reg(context)+EDX_reg(context)));
-	/* we just call the real QT_Thunk right now 
-	 * we can bypass the relaycode, for we already have the registercontext
-	 */
-	EDX_reg(context) = *(DWORD*)((*(DWORD*)(EAX_reg(context)+EDX_reg(context)))+4*(((BYTE*)EBP_reg(context))[-4]));
-	return QT_Thunk(context);
+    DWORD  targetTableOffset = POP_DWORD(context);
+    LPBYTE relayCode = (LPBYTE)POP_DWORD(context);
+    DWORD *targetTable = *(DWORD **)(relayCode+targetTableOffset);
+    DWORD  targetNr = LOBYTE(ECX_reg(context));
+
+    _write_ftprolog(relayCode, targetTable);
+
+    /* We should actually call the relay code now, */
+    /* but we skip it and go directly to FT_Prolog */
+    EDX_reg(context) = targetTable[targetNr];
+    FT_Prolog(context);
 }
 
 /***********************************************************************
- *							(KERNEL32.45)
+ *		QT_ThunkPrime			(KERNEL32.90)
+ *
+ * This function corresponds to FT_PrologPrime, but installs a 
+ * call stub for QT_Thunk instead.
+ *
+ * Input: (EBP-4) target number (passed through to QT_Thunk)
+ *         EDX    target table pointer location offset
+ *         EAX    start of relay code
+ *      
+ */
+VOID WINAPI QT_ThunkPrime(CONTEXT *context)
+{
+    DWORD  targetTableOffset = EDX_reg(context);
+    LPBYTE relayCode = (LPBYTE)EAX_reg(context);
+    DWORD *targetTable = *(DWORD **)(relayCode+targetTableOffset);
+    DWORD  targetNr = *(DWORD *)(EBP_reg(context) - 4);
+
+    _write_qtthunk(relayCode, targetTable);
+
+    /* We should actually call the relay code now, */
+    /* but we skip it and go directly to QT_Thunk */
+    EDX_reg(context) = targetTable[targetNr];
+    QT_Thunk(context);
+}
+
+/***********************************************************************
+ *							(KERNEL32.46)
  * Another thunkbuf link routine.
  * The start of the thunkbuf looks like this:
  * 	00: DWORD	length
  *	04: SEGPTR	address for thunkbuffer pointer
  * [ok probably]
  */
-VOID WINAPI _KERNEL32_46(
+VOID WINAPI ThunkInitSL(
 	LPBYTE thunk,		/* [in] start of thunkbuffer */
 	LPCSTR thkbuf,		/* [in] name/ordinal of thunkbuffer in win16 dll */
 	DWORD len,		/* [in] length of thunkbuffer */
@@ -508,28 +749,28 @@
 }
 
 /**********************************************************************
- *           _KERNEL32_87
+ *           SSOnBigStack	KERNEL32.87
  * Check if thunking is initialized (ss selector set up etc.)
  * We do that differently, so just return TRUE.
  * [ok]
  * RETURNS
  *	TRUE for success.
  */
-BOOL32 WINAPI _KERNEL32_87()
+BOOL32 WINAPI SSOnBigStack()
 {
     TRACE(thunk, "Yes, thunking is initialized\n");
     return TRUE;
 }
 
 /**********************************************************************
- *           _KERNEL32_88
+ *           SSCall
  * One of the real thunking functions. This one seems to be for 32<->32
  * thunks. It should probably be capable of crossing processboundaries.
  *
  * And YES, I've seen nr=48 (somewhere in the Win95 32<->16 OLE coupling)
  * [ok]
  */
-DWORD WINAPIV _KERNEL32_88(
+DWORD WINAPIV SSCall(
 	DWORD nr,	/* [in] number of argument bytes */
 	DWORD flags,	/* [in] FIXME: flags ? */
 	FARPROC32 fun,	/* [in] function to call */
@@ -655,40 +896,6 @@
 	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.
- * RETURNS
- *	a segmented pointer 
- */
-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 PTR_SEG_OFF_TO_SEGPTR( sel, 0 );
-}
-
-/**********************************************************************
- * 		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	/* [in] segmented pointer? */
-) {
-	fprintf(stderr,"_KERNEL_359(0x%08lx),stub\n",x);
-	if ((HIWORD(x) & 7)!=7)
-		return;
-	SELECTOR_FreeBlock(x>>16,1);
-	return;
-}
 
 /**********************************************************************
  * 		KERNEL_471		(KERNEL.471)
diff --git a/win32/newfns.c b/win32/newfns.c
index adedb07..3e6b9fd 100644
--- a/win32/newfns.c
+++ b/win32/newfns.c
@@ -8,6 +8,7 @@
 at a later date. */
 
 #include <stdio.h>
+#include <string.h>
 #include <sys/time.h>
 #include <unistd.h>
 #include "windows.h"
@@ -131,3 +132,57 @@
   SetLastError (ERROR_UNKNOWN);
   return INVALID_HANDLE_VALUE32;
 }
+
+/***********************************************************************
+ *           GetSystemPowerStatus      (KERNEL32.621)
+ */
+BOOL32 WINAPI GetSystemPowerStatus(LPSYSTEM_POWER_STATUS sps_ptr)
+{
+    return FALSE;   /* no power management support */
+}
+
+
+/***********************************************************************
+ *           SetSystemPowerState      (KERNEL32.630)
+ */
+BOOL32 WINAPI SetSystemPowerState(BOOL32 suspend_or_hibernate,
+                                  BOOL32 force_flag)
+{
+    /* suspend_or_hibernate flag: w95 does not support
+       this feature anyway */
+
+    for ( ;0; )
+    {
+        if ( force_flag )
+        {
+        }
+        else
+        {
+        }
+    }
+    return TRUE;
+}
+
+/**************************************************************************
+ *              GetNumberFormat32A	(KERNEL32.355)
+ */
+INT32 WINAPI GetNumberFormat32A(LCID locale, DWORD dwflags,
+			       LPCSTR lpvalue,  char *lpFormat,
+			       LPSTR lpNumberStr, int cchNumber)
+/* NOTE: type of lpFormat should be CONST NUMBERFORMAT */
+
+{
+ int n;
+
+ FIXME(file,"%s: stub, no reformating done\n",lpvalue);
+
+ n = strlen(lpvalue);
+ if (cchNumber) { 
+   strncpy(lpNumberStr,lpvalue,cchNumber);
+   if (cchNumber <= n) {
+     lpNumberStr[cchNumber-1] = 0;
+     n = cchNumber-1;
+   }
+ }
+ return n;
+}
diff --git a/win32/ordinals.c b/win32/ordinals.c
index 6ac155b..7d94d54 100644
--- a/win32/ordinals.c
+++ b/win32/ordinals.c
@@ -13,6 +13,7 @@
 #include "winnt.h"
 #include "process.h"
 #include "module.h"
+#include "task.h"
 #include "callback.h"
 #include "debug.h"
 
@@ -20,7 +21,7 @@
 static SEGPTR segWin16Mutex = NULL;
 
 /***********************************************
- *           GetPWinLock    (KERNEL32)
+ *           GetPWinLock    (KERNEL32.93)
  * Return the infamous Win16Mutex.
  */
 VOID WINAPI GetPWinLock(CRITICAL_SECTION **lock)
@@ -30,7 +31,7 @@
 }
 
 /**********************************************************************
- *           _KERNEL32_88
+ *           WOW32_1        (KERNEL32.88)
  */
 BOOL32 WINAPI WOW32_1(SEGPTR segptr,LPLDT_ENTRY ldtent)
 {
@@ -39,11 +40,11 @@
 
 
 /***********************************************************************
- *           _KERNEL32_18    (KERNEL32.18)
+ *           GetProcessDWORD    (KERNEL32.18)
  * 'Of course you cannot directly access Windows internal structures'
  */
 
-DWORD WINAPI _KERNEL32_18(DWORD processid,DWORD action)
+DWORD WINAPI GetProcessDWORD(DWORD processid,DWORD action)
 {
 	PDB32	*process;
 	TDB	*pTask;
@@ -114,22 +115,22 @@
 
 
 /***********************************************************************
- *							(KERNEL32.33)
+ *		GetWin16DOSEnv			(KERNEL32.34)
  * Returns some internal value.... probably the default environment database?
  */
-DWORD WINAPI _KERNEL32_34()
+DWORD WINAPI GetWin16DOSEnv()
 {
-	fprintf(stderr,"KERNEL32_34(), STUB returning 0\n");
+	fprintf(stderr,"GetWin16DOSEnv(), 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);
+BOOL32 WINAPI _KERNEL32_100(HANDLE32 threadid,DWORD exitcode,DWORD x) {
+	fprintf(stderr,"KERNEL32_100(%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);
+DWORD WINAPI _KERNEL32_99(DWORD x) {
+	fprintf(stderr,"KERNEL32_99(0x%08lx),stub\n",x);
 	return 1;
 }
 
diff --git a/win32/process.c b/win32/process.c
index 2326f9f..18bd5c2 100644
--- a/win32/process.c
+++ b/win32/process.c
@@ -19,7 +19,7 @@
 
 
 /***********************************************************************
- *           MsgWaitForMultipleObjects    (USER32.399)
+ *           MsgWaitForMultipleObjects    (USER32.400)
  */
 DWORD WINAPI MsgWaitForMultipleObjects(
 	DWORD nCount,HANDLE32 *pHandles,BOOL32 fWaitAll,DWORD dwMilliseconds,
@@ -33,16 +33,6 @@
 	return 0;
 }
 
-/***********************************************************************
- *           DuplicateHandle    (KERNEL32.78)
- */
-BOOL32 WINAPI DuplicateHandle(HANDLE32 a, HANDLE32 b, HANDLE32 c, HANDLE32 * d, DWORD e, BOOL32 f, DWORD g)
-{
-	fprintf(stderr,"DuplicateHandle(%d,%d,%d,%p,%ld,%d,%ld) stub\n",a,b,c,d,e,f,g);
-	*d = b;
-	return TRUE;
-}
-
 /**********************************************************************
  *          GetProcessAffinityMask
  */
@@ -87,13 +77,18 @@
 	DWORD creationflags,LPVOID env,LPCSTR curdir,
 	LPSTARTUPINFO32A startupinfo,LPPROCESS_INFORMATION processinfo
 ) {
-	fprintf(stderr,"CreateProcessA(%s,%s,%p,%p,%d,%08lx,%p,%s,%p,%p), stub\n",
+	WARN(win32,"CreateProcessA(%s,%s,%p,%p,%d,%08lx,%p,%s,%p,%p),\n
+		calling WinExec32 instead\n",
 		appname,cmdline,processattributes,threadattributes,
 		inherithandles,creationflags,env,curdir,startupinfo,processinfo
 	);
+        WinExec32(cmdline,TRUE);
+        return TRUE;
+#if 0
 	/* make from lcc uses system as fallback if CreateProcess returns
 	   FALSE, so return false */
 	return FALSE;
+#endif
 }
 
 BOOL32 WINAPI CreateProcess32W(
diff --git a/win32/user32.c b/win32/user32.c
index 86ee37f..a37c599 100644
--- a/win32/user32.c
+++ b/win32/user32.c
@@ -18,7 +18,7 @@
 #include "debug.h"
 
 /***********************************************************************
- *          GetMessage32A   (USER32.269)
+ *          GetMessage32A   (USER32.270)
  */
 BOOL32 WINAPI GetMessage32A(MSG32* lpmsg,HWND32 hwnd,UINT32 min,UINT32 max)
 {
@@ -33,7 +33,7 @@
 }
 
 /***********************************************************************
- *          GetMessage32W   (USER32.273)
+ *          GetMessage32W   (USER32.274)
  */
 BOOL32 WINAPI GetMessage32W(MSG32* lpmsg,HWND32 hwnd,UINT32 min,UINT32 max)
 {
diff --git a/windows/dce.c b/windows/dce.c
index da1bee7..1e9b316 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -590,7 +590,7 @@
 
 
 /***********************************************************************
- *           GetDCEx32    (USER32.230)
+ *           GetDCEx32    (USER32.231)
  *
  * Unimplemented flags: DCX_LOCKWINDOWUPDATE
  *
@@ -808,7 +808,7 @@
 
 
 /***********************************************************************
- *           GetDC32    (USER32.229)
+ *           GetDC32    (USER32.230)
  * RETURNS
  *	:Handle to DC
  *	NULL: Failure
@@ -833,7 +833,7 @@
 
 
 /***********************************************************************
- *           GetWindowDC32    (USER32.)
+ *           GetWindowDC32    (USER32.304)
  */
 HDC32 WINAPI GetWindowDC32( HWND32 hwnd )
 {
@@ -852,7 +852,7 @@
 
 
 /***********************************************************************
- *           ReleaseDC32    (USER32.439)
+ *           ReleaseDC32    (USER32.440)
  *
  * RETURNS
  *	1: Success
@@ -937,7 +937,7 @@
 
 
 /**********************************************************************
- *          WindowFromDC16   (USER32.580)
+ *          WindowFromDC16   (USER.117)
  */
 HWND16 WINAPI WindowFromDC16( HDC16 hDC )
 {
@@ -946,7 +946,7 @@
 
 
 /**********************************************************************
- *          WindowFromDC32   (USER32.580)
+ *          WindowFromDC32   (USER32.581)
  */
 HWND32 WINAPI WindowFromDC32( HDC32 hDC )
 {
@@ -966,7 +966,7 @@
 
 
 /***********************************************************************
- *           LockWindowUpdate32   (USER32.377)
+ *           LockWindowUpdate32   (USER32.378)
  */
 BOOL32 WINAPI LockWindowUpdate32( HWND32 hwnd )
 {
diff --git a/windows/defdlg.c b/windows/defdlg.c
index 36c146a..ede0e09 100644
--- a/windows/defdlg.c
+++ b/windows/defdlg.c
@@ -302,7 +302,7 @@
 
 
 /***********************************************************************
- *           DefDlgProc32A   (USER32.119)
+ *           DefDlgProc32A   (USER32.120)
  */
 LRESULT WINAPI DefDlgProc32A( HWND32 hwnd, UINT32 msg,
                               WPARAM32 wParam, LPARAM lParam )
@@ -357,7 +357,7 @@
 
 
 /***********************************************************************
- *           DefDlgProc32W   (USER32.120)
+ *           DefDlgProc32W   (USER32.121)
  */
 LRESULT WINAPI DefDlgProc32W( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
                               LPARAM lParam )
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 9b41bf1..5ce2179 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -352,11 +352,14 @@
 
     case WM_QUERYDRAGICON:
         {
-            HICON16 hI = 0;
-            UINT16 len = 1;
-            while(len < 64)
-		if( (hI = LoadIcon16(wndPtr->hInstance,MAKEINTRESOURCE(len))) )
-                    return (LRESULT)hI;
+            HICON16 hIcon=0;
+            UINT16 len;
+
+            if( (hIcon=wndPtr->class->hCursor) ) return (LRESULT)hIcon;
+            for(len=1; len<64; len++)
+                if((hIcon=LoadIcon16(wndPtr->hInstance,MAKEINTRESOURCE16(len))))
+                    return (LRESULT)hIcon;
+            return (LRESULT)LoadIcon16(NULL,IDI_APPLICATION16);
         }
         break;
 
@@ -440,7 +443,7 @@
 
 
 /***********************************************************************
- *           DefWindowProc32A   (USER32.125)
+ *           DefWindowProc32A   (USER32.126)
  */
 LRESULT WINAPI DefWindowProc32A( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
                                  LPARAM lParam )
@@ -501,7 +504,7 @@
 
 
 /***********************************************************************
- *           DefWindowProc32W   (USER32.126)
+ *           DefWindowProc32W   (USER32.127)
  */
 LRESULT WINAPI DefWindowProc32W( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
                                  LPARAM lParam )
diff --git a/windows/dialog.c b/windows/dialog.c
index c6ad70c..a1b67f9 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -29,11 +29,12 @@
 {
     DWORD      style;
     DWORD      exStyle;
+    DWORD      helpId;
     INT16      x;
     INT16      y;
     INT16      cx;
     INT16      cy;
-    UINT16     id;
+    UINT32     id;
     LPCSTR     className;
     LPCSTR     windowName;
     LPVOID     data;
@@ -44,6 +45,7 @@
 {
     DWORD      style;
     DWORD      exStyle;
+    DWORD      helpId;
     UINT16     nbItems;
     INT16      x;
     INT16      y;
@@ -53,7 +55,10 @@
     LPCSTR     className;
     LPCSTR     caption;
     WORD       pointSize;
+    WORD       weight;
+    BOOL32     italic;
     LPCSTR     faceName;
+    BOOL32     dialogEx;
 } DLG_TEMPLATE;
 
   /* Dialog base units */
@@ -166,32 +171,57 @@
  * Return the class and text of the control pointed to by ptr,
  * fill the header structure and return a pointer to the next control.
  */
-static const WORD *DIALOG_GetControl32( const WORD *p, DLG_CONTROL_INFO *info )
+static const WORD *DIALOG_GetControl32( const WORD *p, DLG_CONTROL_INFO *info,
+                                        BOOL32 dialogEx )
 {
-    static WCHAR buffer[10];
-    int int_id;
-
-    info->style   = GET_DWORD(p); p += 2;
-    info->exStyle = GET_DWORD(p); p += 2;
+    if (dialogEx)
+    {
+        info->helpId  = GET_DWORD(p); p += 2;
+        info->exStyle = GET_DWORD(p); p += 2;
+        info->style   = GET_DWORD(p); p += 2;
+    }
+    else
+    {
+        info->helpId  = 0;
+        info->style   = GET_DWORD(p); p += 2;
+        info->exStyle = GET_DWORD(p); p += 2;
+    }
     info->x       = GET_WORD(p); p++;
     info->y       = GET_WORD(p); p++;
     info->cx      = GET_WORD(p); p++;
     info->cy      = GET_WORD(p); p++;
-    info->id      = GET_WORD(p); p++;
+
+    if (dialogEx)
+    {
+        /* id is a DWORD for DIALOGEX */
+        info->id = GET_DWORD(p);
+        p += 2;
+    }
+    else
+    {
+        info->id = GET_WORD(p);
+        p++;
+    }
 
     if (GET_WORD(p) == 0xffff)
     {
-        switch(GET_WORD(p+1))
+        static const WCHAR class_names[6][10] =
         {
-            case 0x80: lstrcpyAtoW( buffer, "Button" ); break;
-            case 0x81: lstrcpyAtoW( buffer, "Edit" ); break;
-            case 0x82: lstrcpyAtoW( buffer, "Static" ); break;
-            case 0x83: lstrcpyAtoW( buffer, "ListBox" ); break;
-            case 0x84: lstrcpyAtoW( buffer, "ScrollBar" ); break;
-            case 0x85: lstrcpyAtoW( buffer, "ComboBox" ); break;
-            default:   buffer[0] = '\0'; break;
+            { 'B','u','t','t','o','n', },             /* 0x80 */
+            { 'E','d','i','t', },                     /* 0x81 */
+            { 'S','t','a','t','i','c', },             /* 0x82 */
+            { 'L','i','s','t','B','o','x', },         /* 0x83 */
+            { 'S','c','r','o','l','l','B','a','r', }, /* 0x84 */
+            { 'C','o','m','b','o','B','o','x', }      /* 0x85 */
+        };
+        WORD id = GET_WORD(p+1);
+        if ((id >= 0x80) && (id <= 0x85))
+            info->className = (LPCSTR)class_names[id - 0x80];
+        else
+        {
+            info->className = NULL;
+            ERR( dialog, "Unknown built-in class id %04x\n", id );
         }
-        info->className = (LPCSTR)buffer;
         p += 2;
     }
     else
@@ -200,10 +230,9 @@
         p += lstrlen32W( (LPCWSTR)p ) + 1;
     }
 
-    int_id = (GET_WORD(p) == 0xffff);
-    if (int_id)
+    if (GET_WORD(p) == 0xffff)  /* Is it an integer id? */
     {
-	info->windowName = (LPCSTR)(p + 1);
+	info->windowName = (LPCSTR)(UINT32)GET_WORD(p + 1);
 	p += 2;
     }
     else
@@ -212,25 +241,29 @@
         p += lstrlen32W( (LPCWSTR)p ) + 1;
     }
 
+    TRACE(dialog,"    %s %s %d, %d, %d, %d, %d, %08lx, %08lx, %08lx\n", 
+          debugstr_w( (LPCWSTR)info->className ),
+          debugres_w( (LPCWSTR)info->windowName ),
+          info->id, info->x, info->y, info->cx, info->cy,
+          info->style, info->exStyle, info->helpId );
+
     if (GET_WORD(p))
     {
+        if (TRACE_ON(dialog))
+        {
+            WORD i, count = GET_WORD(p) / sizeof(WORD);
+            TRACE(dialog, "  BEGIN\n");
+            TRACE(dialog, "    ");
+            for (i = 0; i < count; i++) DUMP( "%04x,", GET_WORD(p+i+1) );
+            DUMP("\n");
+            TRACE(dialog, "  END\n" );
+        }
         info->data = (LPVOID)(p + 1);
         p += GET_WORD(p) / sizeof(WORD);
     }
     else info->data = NULL;
     p++;
 
-    if(int_id)
-      TRACE(dialog,"   %p %04x %d, %d, %d, %d, %d, %08lx, %08lx, %08lx\n", 
-		      info->className, LOWORD(info->windowName),
-		      info->id, info->x, info->y, info->cx, info->cy,
-		      info->style, info->exStyle, (DWORD)info->data);
-    else
-      TRACE(dialog,"   %p '%p' %d, %d, %d, %d, %d, %08lx, %08lx, %08lx\n", 
-		      info->className, info->windowName,
-		      info->id, info->x, info->y, info->cx, info->cy,
-		      info->style, info->exStyle, (DWORD)info->data);
-
     /* Next control is on dword boundary */
     return (const WORD *)((((int)p) + 3) & ~3);
 }
@@ -241,12 +274,14 @@
  *
  * Create the control windows for a dialog.
  */
-static BOOL32 DIALOG_CreateControls( WND *pWnd, LPCSTR template, INT32 items,
+static BOOL32 DIALOG_CreateControls( WND *pWnd, LPCSTR template,
+                                     const DLG_TEMPLATE *dlgTemplate,
                                      HINSTANCE32 hInst, BOOL32 win32 )
 {
     DIALOGINFO *dlgInfo = (DIALOGINFO *)pWnd->wExtra;
     DLG_CONTROL_INFO info;
     HWND32 hwndCtrl, hwndDefButton = 0;
+    INT32 items = dlgTemplate->nbItems;
 
     TRACE(dialog, " BEGIN\n" );
     while (items--)
@@ -284,7 +319,8 @@
         }
         else
         {
-            template = (LPCSTR)DIALOG_GetControl32( (WORD *)template, &info );
+            template = (LPCSTR)DIALOG_GetControl32( (WORD *)template, &info,
+                                                    dlgTemplate->dialogEx );
             hwndCtrl = CreateWindowEx32W( info.exStyle | WS_EX_NOPARENTNOTIFY,
                                           (LPCWSTR)info.className,
                                           (LPCWSTR)info.windowName,
@@ -397,17 +433,30 @@
 {
     const WORD *p = (const WORD *)template;
 
-    result->style   = GET_DWORD(p); p += 2;
-    result->exStyle = GET_DWORD(p); p += 2;
+    result->style = GET_DWORD(p); p += 2;
+    if (result->style == 0xffff0001)  /* DIALOGEX resource */
+    {
+        result->dialogEx = TRUE;
+        result->helpId   = GET_DWORD(p); p += 2;
+        result->exStyle  = GET_DWORD(p); p += 2;
+        result->style    = GET_DWORD(p); p += 2;
+    }
+    else
+    {
+        result->dialogEx = FALSE;
+        result->helpId   = 0;
+        result->exStyle  = GET_DWORD(p); p += 2;
+    }
     result->nbItems = GET_WORD(p); p++;
     result->x       = GET_WORD(p); p++;
     result->y       = GET_WORD(p); p++;
     result->cx      = GET_WORD(p); p++;
     result->cy      = GET_WORD(p); p++;
-    TRACE(dialog, "DIALOG %d, %d, %d, %d\n",
-                    result->x, result->y, result->cx, result->cy );
-    TRACE(dialog, " STYLE %08lx\n", result->style );
-    TRACE(dialog, " EXSTYLE %08lx\n", result->exStyle );
+    TRACE( dialog, "DIALOG%s %d, %d, %d, %d, %ld\n",
+           result->dialogEx ? "EX" : "", result->x, result->y,
+           result->cx, result->cy, result->helpId );
+    TRACE( dialog, " STYLE 0x%08lx\n", result->style );
+    TRACE( dialog, " EXSTYLE 0x%08lx\n", result->exStyle );
 
     /* Get the menu name */
 
@@ -424,7 +473,7 @@
         break;
     default:
         result->menuName = (LPCSTR)p;
-        TRACE(dialog, " MENU '%p'\n", p );
+        TRACE(dialog, " MENU %s\n", debugstr_w( (LPCWSTR)p ));
         p += lstrlen32W( (LPCWSTR)p ) + 1;
         break;
     }
@@ -444,7 +493,7 @@
         break;
     default:
         result->className = (LPCSTR)p;
-        TRACE(dialog, " CLASS '%p'\n", p );
+        TRACE(dialog, " CLASS %s\n", debugstr_w( (LPCWSTR)p ));
         p += lstrlen32W( (LPCWSTR)p ) + 1;
         break;
     }
@@ -453,7 +502,7 @@
 
     result->caption = (LPCSTR)p;
     p += lstrlen32W( (LPCWSTR)p ) + 1;
-    TRACE(dialog, " CAPTION '%p'\n", result->caption );
+    TRACE(dialog, " CAPTION %s\n", debugstr_w( (LPCWSTR)result->caption ) );
 
     /* Get the font name */
 
@@ -461,11 +510,23 @@
     {
 	result->pointSize = GET_WORD(p);
         p++;
+        if (result->dialogEx)
+        {
+            result->weight = GET_WORD(p); p++;
+            result->italic = LOBYTE(GET_WORD(p)); p++;
+        }
+        else
+        {
+            result->weight = FW_DONTCARE;
+            result->italic = FALSE;
+        }
 	result->faceName = (LPCSTR)p;
         p += lstrlen32W( (LPCWSTR)p ) + 1;
-	TRACE(dialog, " FONT %d,'%p'\n",
-                        result->pointSize, result->faceName );
+	TRACE(dialog, " FONT %d, %s, %d, %s\n",
+              result->pointSize, debugstr_w( (LPCWSTR)result->faceName ),
+              result->weight, result->italic ? "TRUE" : "FALSE" );
     }
+
     /* First control is on dword boundary */
     return (LPCSTR)((((int)p) + 3) & ~3);
 }
@@ -517,10 +578,10 @@
           /* The font height must be negative as it is a point size */
           /* (see CreateFont() documentation in the Windows SDK).   */
 	if (win32Template)
-	    hFont = CreateFont32W( -template.pointSize, 0, 0, 0, FW_DONTCARE,
-			    FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
-			    PROOF_QUALITY, FF_DONTCARE,
-                            (LPCWSTR)template.faceName );
+	    hFont = CreateFont32W( -template.pointSize, 0, 0, 0,
+                                   template.weight, template.italic, FALSE,
+                                   FALSE, DEFAULT_CHARSET, 0, 0, PROOF_QUALITY,
+                                   FF_DONTCARE, (LPCWSTR)template.faceName );
 	else
 	    hFont = CreateFont16( -template.pointSize, 0, 0, 0, FW_DONTCARE,
 			    FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
@@ -602,6 +663,7 @@
     }
     wndPtr = WIN_FindWndPtr( hwnd );
     wndPtr->flags |= WIN_ISDIALOG;
+    wndPtr->helpContext = template.helpId;
 
       /* Initialise dialog extra data */
 
@@ -621,8 +683,8 @@
 
     /* Create controls */
 
-    if (DIALOG_CreateControls( wndPtr, dlgTemplate, template.nbItems,
-                                hInst, win32Template ))
+    if (DIALOG_CreateControls( wndPtr, dlgTemplate, &template,
+                               hInst, win32Template ))
     {
        /* Send initialisation messages and set focus */
 
@@ -669,7 +731,7 @@
     TRACE(dialog, "%04x,%08lx,%04x,%08lx,%ld\n",
                    hInst, (DWORD)dlgTemplate, owner, (DWORD)dlgProc, param );
 
-    if (!(hRsrc = FindResource16( hInst, dlgTemplate, RT_DIALOG ))) return 0;
+    if (!(hRsrc = FindResource16( hInst, dlgTemplate, RT_DIALOG16 ))) return 0;
     if (!(hmem = LoadResource16( hInst, hRsrc ))) return 0;
     if (!(data = LockResource16( hmem ))) hwnd = 0;
     else hwnd = CreateDialogIndirectParam16( hInst, data, owner,
@@ -680,7 +742,7 @@
 
 
 /***********************************************************************
- *           CreateDialogParam32A   (USER32.72)
+ *           CreateDialogParam32A   (USER32.73)
  */
 HWND32 WINAPI CreateDialogParam32A( HINSTANCE32 hInst, LPCSTR name,
                                     HWND32 owner, DLGPROC32 dlgProc,
@@ -698,13 +760,13 @@
 
 
 /***********************************************************************
- *           CreateDialogParam32W   (USER32.73)
+ *           CreateDialogParam32W   (USER32.74)
  */
 HWND32 WINAPI CreateDialogParam32W( HINSTANCE32 hInst, LPCWSTR name,
                                     HWND32 owner, DLGPROC32 dlgProc,
                                     LPARAM param )
 {
-    HANDLE32 hrsrc = FindResource32W( hInst, name, (LPWSTR)RT_DIALOG );
+    HANDLE32 hrsrc = FindResource32W( hInst, name, RT_DIALOG32W );
     if (!hrsrc) return 0;
     return CreateDialogIndirectParam32W( hInst,
                                          (LPVOID)LoadResource32(hInst, hrsrc),
@@ -749,7 +811,7 @@
 
 
 /***********************************************************************
- *           CreateDialogIndirectParam32W   (USER32.71)
+ *           CreateDialogIndirectParam32W   (USER32.72)
  */
 HWND32 WINAPI CreateDialogIndirectParam32W( HINSTANCE32 hInst,
                                             LPCVOID dlgTemplate,
@@ -818,7 +880,7 @@
 
 
 /***********************************************************************
- *           DialogBoxParam32A   (USER32.138)
+ *           DialogBoxParam32A   (USER32.139)
  */
 INT32 WINAPI DialogBoxParam32A( HINSTANCE32 hInst, LPCSTR name,
                                 HWND32 owner, DLGPROC32 dlgProc, LPARAM param )
@@ -830,7 +892,7 @@
 
 
 /***********************************************************************
- *           DialogBoxParam32W   (USER32.139)
+ *           DialogBoxParam32W   (USER32.140)
  */
 INT32 WINAPI DialogBoxParam32W( HINSTANCE32 hInst, LPCWSTR name,
                                 HWND32 owner, DLGPROC32 dlgProc, LPARAM param )
@@ -870,7 +932,7 @@
 
 
 /***********************************************************************
- *           DialogBoxIndirectParam32A   (USER32.135)
+ *           DialogBoxIndirectParam32A   (USER32.136)
  */
 INT32 WINAPI DialogBoxIndirectParam32A(HINSTANCE32 hInstance, LPCVOID template,
                                        HWND32 owner, DLGPROC32 dlgProc,
@@ -884,7 +946,7 @@
 
 
 /***********************************************************************
- *           DialogBoxIndirectParam32W   (USER32.137)
+ *           DialogBoxIndirectParam32W   (USER32.138)
  */
 INT32 WINAPI DialogBoxIndirectParam32W(HINSTANCE32 hInstance, LPCVOID template,
                                        HWND32 owner, DLGPROC32 dlgProc,
@@ -907,7 +969,7 @@
 
 
 /***********************************************************************
- *           EndDialog32   (USER32.173)
+ *           EndDialog32   (USER.88)
  */
 BOOL32 WINAPI EndDialog32( HWND32 hwnd, INT32 retval )
 {
@@ -1053,7 +1115,7 @@
 
 
 /***********************************************************************
- *           IsDialogMessage32A   (USER32.341)
+ *           IsDialogMessage32A   (USER32.342)
  */
 BOOL32 WINAPI IsDialogMessage32A( HWND32 hwndDlg, LPMSG32 msg )
 {
@@ -1072,7 +1134,7 @@
 
 
 /***********************************************************************
- *           IsDialogMessage32W   (USER32.342)
+ *           IsDialogMessage32W   (USER32.343)
  */
 BOOL32 WINAPI IsDialogMessage32W( HWND32 hwndDlg, LPMSG32 msg )
 {
@@ -1102,7 +1164,7 @@
  
 
 /****************************************************************
- *         GetDlgCtrlID32   (USER32.233)
+ *         GetDlgCtrlID32   (USER32.234)
  */
 INT32 WINAPI GetDlgCtrlID32( HWND32 hwnd )
 {
@@ -1127,7 +1189,7 @@
 
 
 /***********************************************************************
- *           GetDlgItem32   (USER32.234)
+ *           GetDlgItem32   (USER32.235)
  */
 HWND32 WINAPI GetDlgItem32( HWND32 hwndDlg, INT32 id )
 {
@@ -1153,7 +1215,7 @@
 
 
 /*******************************************************************
- *           SendDlgItemMessage32A   (USER32.451)
+ *           SendDlgItemMessage32A   (USER32.452)
  */
 LRESULT WINAPI SendDlgItemMessage32A( HWND32 hwnd, INT32 id, UINT32 msg,
                                       WPARAM32 wParam, LPARAM lParam )
@@ -1165,7 +1227,7 @@
 
 
 /*******************************************************************
- *           SendDlgItemMessage32W   (USER32.452)
+ *           SendDlgItemMessage32W   (USER32.453)
  */
 LRESULT WINAPI SendDlgItemMessage32W( HWND32 hwnd, INT32 id, UINT32 msg,
                                       WPARAM32 wParam, LPARAM lParam )
@@ -1186,7 +1248,7 @@
 
 
 /*******************************************************************
- *           SetDlgItemText32A   (USER32.477)
+ *           SetDlgItemText32A   (USER32.478)
  */
 void WINAPI SetDlgItemText32A( HWND32 hwnd, INT32 id, LPCSTR lpString )
 {
@@ -1195,7 +1257,7 @@
 
 
 /*******************************************************************
- *           SetDlgItemText32W   (USER32.478)
+ *           SetDlgItemText32W   (USER32.479)
  */
 void WINAPI SetDlgItemText32W( HWND32 hwnd, INT32 id, LPCWSTR lpString )
 {
@@ -1214,7 +1276,7 @@
 
 
 /***********************************************************************
- *           GetDlgItemText32A   (USER32.236)
+ *           GetDlgItemText32A   (USER32.237)
  */
 INT32 WINAPI GetDlgItemText32A( HWND32 hwnd, INT32 id, LPSTR str, UINT32 len )
 {
@@ -1224,7 +1286,7 @@
 
 
 /***********************************************************************
- *           GetDlgItemText32W   (USER32.237)
+ *           GetDlgItemText32W   (USER32.238)
  */
 INT32 WINAPI GetDlgItemText32W( HWND32 hwnd, INT32 id, LPWSTR str, UINT32 len )
 {
@@ -1243,7 +1305,7 @@
 
 
 /*******************************************************************
- *           SetDlgItemInt32   (USER32.476)
+ *           SetDlgItemInt32   (USER32.477)
  */
 void WINAPI SetDlgItemInt32( HWND32 hwnd, INT32 id, UINT32 value,
                              BOOL32 fSigned )
@@ -1282,7 +1344,7 @@
 
 
 /***********************************************************************
- *           GetDlgItemInt32   (USER32.235)
+ *           GetDlgItemInt32   (USER32.236)
  */
 UINT32 WINAPI GetDlgItemInt32( HWND32 hwnd, INT32 id, BOOL32 *translated,
                                BOOL32 fSigned )
@@ -1325,7 +1387,7 @@
 
 
 /***********************************************************************
- *           CheckDlgButton32   (USER32.44)
+ *           CheckDlgButton32   (USER32.45)
  */
 BOOL32 WINAPI CheckDlgButton32( HWND32 hwnd, INT32 id, UINT32 check )
 {
@@ -1344,7 +1406,7 @@
 
 
 /***********************************************************************
- *           IsDlgButtonChecked32   (USER32.343)
+ *           IsDlgButtonChecked32   (USER32.344)
  */
 UINT32 WINAPI IsDlgButtonChecked32( HWND32 hwnd, UINT32 id )
 {
@@ -1363,7 +1425,7 @@
 
 
 /***********************************************************************
- *           CheckRadioButton32   (USER32.47)
+ *           CheckRadioButton32   (USER32.48)
  */
 BOOL32 WINAPI CheckRadioButton32( HWND32 hwndDlg, UINT32 firstID,
                                   UINT32 lastID, UINT32 checkID )
@@ -1389,7 +1451,7 @@
 
 
 /***********************************************************************
- *           GetDialogBaseUnits   (USER.243) (USER32.232)
+ *           GetDialogBaseUnits   (USER.243) (USER32.233)
  */
 DWORD WINAPI GetDialogBaseUnits(void)
 {
@@ -1414,7 +1476,7 @@
 
 
 /***********************************************************************
- *           MapDialogRect32   (USER32.381)
+ *           MapDialogRect32   (USER32.382)
  */
 void WINAPI MapDialogRect32( HWND32 hwnd, LPRECT32 rect )
 {
@@ -1440,7 +1502,7 @@
 
 
 /***********************************************************************
- *           GetNextDlgGroupItem32   (USER32.274)
+ *           GetNextDlgGroupItem32   (USER32.275)
  */
 HWND32 WINAPI GetNextDlgGroupItem32( HWND32 hwndDlg, HWND32 hwndCtrl,
                                      BOOL32 fPrevious )
@@ -1501,7 +1563,7 @@
 
 
 /***********************************************************************
- *           GetNextDlgTabItem32   (USER32.275)
+ *           GetNextDlgTabItem32   (USER32.276)
  */
 HWND32 WINAPI GetNextDlgTabItem32( HWND32 hwndDlg, HWND32 hwndCtrl,
                                    BOOL32 fPrevious )
@@ -1759,7 +1821,7 @@
 
 
 /**********************************************************************
- *           DlgDirSelectEx32A    (USER32.148)
+ *           DlgDirSelectEx32A    (USER32.149)
  */
 BOOL32 WINAPI DlgDirSelectEx32A( HWND32 hwnd, LPSTR str, INT32 len, INT32 id )
 {
@@ -1768,7 +1830,7 @@
 
 
 /**********************************************************************
- *           DlgDirSelectEx32W    (USER32.149)
+ *           DlgDirSelectEx32W    (USER32.150)
  */
 BOOL32 WINAPI DlgDirSelectEx32W( HWND32 hwnd, LPWSTR str, INT32 len, INT32 id )
 {
@@ -1787,7 +1849,7 @@
 
 
 /**********************************************************************
- *           DlgDirSelectComboBoxEx32A    (USER32.146)
+ *           DlgDirSelectComboBoxEx32A    (USER32.147)
  */
 BOOL32 WINAPI DlgDirSelectComboBoxEx32A( HWND32 hwnd, LPSTR str, INT32 len,
                                          INT32 id )
@@ -1797,7 +1859,7 @@
 
 
 /**********************************************************************
- *           DlgDirSelectComboBoxEx32W    (USER32.147)
+ *           DlgDirSelectComboBoxEx32W    (USER32.148)
  */
 BOOL32 WINAPI DlgDirSelectComboBoxEx32W( HWND32 hwnd, LPWSTR str, INT32 len,
                                          INT32 id)
@@ -1817,7 +1879,7 @@
 
 
 /**********************************************************************
- *	    DlgDirList32A    (USER32.142)
+ *	    DlgDirList32A    (USER32.143)
  */
 INT32 WINAPI DlgDirList32A( HWND32 hDlg, LPSTR spec, INT32 idLBox,
                             INT32 idStatic, UINT32 attrib )
@@ -1827,7 +1889,7 @@
 
 
 /**********************************************************************
- *	    DlgDirList32W    (USER32.145)
+ *	    DlgDirList32W    (USER32.146)
  */
 INT32 WINAPI DlgDirList32W( HWND32 hDlg, LPWSTR spec, INT32 idLBox,
                             INT32 idStatic, UINT32 attrib )
@@ -1847,7 +1909,7 @@
 
 
 /**********************************************************************
- *	    DlgDirListComboBox32A    (USER32.143)
+ *	    DlgDirListComboBox32A    (USER32.144)
  */
 INT32 WINAPI DlgDirListComboBox32A( HWND32 hDlg, LPSTR spec, INT32 idCBox,
                                     INT32 idStatic, UINT32 attrib )
@@ -1857,7 +1919,7 @@
 
 
 /**********************************************************************
- *	    DlgDirListComboBox32W    (USER32.144)
+ *	    DlgDirListComboBox32W    (USER32.145)
  */
 INT32 WINAPI DlgDirListComboBox32W( HWND32 hDlg, LPWSTR spec, INT32 idCBox,
                                     INT32 idStatic, UINT32 attrib )
diff --git a/windows/dinput.c b/windows/dinput.c
index 101435f..e034aeb 100644
--- a/windows/dinput.c
+++ b/windows/dinput.c
@@ -238,7 +238,6 @@
 static HRESULT WINAPI SysKeyboardA_SetProperty(
 	LPDIRECTINPUTDEVICE32A this,REFGUID rguid,LPCDIPROPHEADER ph
 ) {
-	LPSYSKEYBOARD32A	kthis = (LPSYSKEYBOARD32A)this;
 	char			xbuf[50];
 
 	if (HIWORD(rguid))
diff --git a/windows/event.c b/windows/event.c
index e55c048..94e1e52 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -1177,7 +1177,7 @@
 
 
 /**********************************************************************
- *		SetCapture32   (USER32.463)
+ *		SetCapture32   (USER32.464)
  */
 HWND32 WINAPI SetCapture32( HWND32 hwnd )
 {
@@ -1186,7 +1186,7 @@
 
 
 /**********************************************************************
- *		ReleaseCapture   (USER.19) (USER32.438)
+ *		ReleaseCapture   (USER.19) (USER32.439)
  */
 void WINAPI ReleaseCapture(void)
 {
@@ -1205,7 +1205,7 @@
 
 
 /**********************************************************************
- *		GetCapture32   (USER32.207)
+ *		GetCapture32   (USER32.208)
  */
 HWND32 WINAPI GetCapture32(void)
 {
@@ -1288,7 +1288,7 @@
 
 
 /***********************************************************************
- *	     SwapMouseButton32   (USER32.536)
+ *	     SwapMouseButton32   (USER32.537)
  */
 BOOL32 WINAPI SwapMouseButton32( BOOL32 fSwap )
 {
diff --git a/windows/focus.c b/windows/focus.c
index 38ef5c5..92c757a 100644
--- a/windows/focus.c
+++ b/windows/focus.c
@@ -91,7 +91,7 @@
 
 
 /*****************************************************************
- *               SetFocus32   (USER32.480)
+ *               SetFocus32   (USER32.481)
  */
 HWND32 WINAPI SetFocus32( HWND32 hwnd )
 {
@@ -147,7 +147,7 @@
 
 
 /*****************************************************************
- *               GetFocus32   (USER32.239)
+ *               GetFocus32   (USER32.240)
  */
 HWND32 WINAPI GetFocus32(void)
 {
diff --git a/windows/hook.c b/windows/hook.c
index 79f1a7b..a9e1089 100644
--- a/windows/hook.c
+++ b/windows/hook.c
@@ -1185,7 +1185,7 @@
 
 
 /***********************************************************************
- *           SetWindowsHook32A   (USER32.524)
+ *           SetWindowsHook32A   (USER32.525)
  *
  * FIXME: I don't know if this is correct
  */
@@ -1202,7 +1202,7 @@
 
 
 /***********************************************************************
- *           SetWindowsHook32W   (USER32.527)
+ *           SetWindowsHook32W   (USER32.528)
  *
  * FIXME: I don't know if this is correct
  */
@@ -1230,7 +1230,7 @@
 
 
 /***********************************************************************
- *           SetWindowsHookEx32A   (USER32.525)
+ *           SetWindowsHookEx32A   (USER32.526)
  */
 HHOOK WINAPI SetWindowsHookEx32A( INT32 id, HOOKPROC32 proc, HINSTANCE32 hInst,
                                   DWORD dwThreadID )
@@ -1249,7 +1249,7 @@
 
 
 /***********************************************************************
- *           SetWindowsHookEx32W   (USER32.526)
+ *           SetWindowsHookEx32W   (USER32.527)
  */
 HHOOK WINAPI SetWindowsHookEx32W( INT32 id, HOOKPROC32 proc, HINSTANCE32 hInst,
                                   DWORD dwThreadID )
@@ -1288,7 +1288,7 @@
 
 
 /***********************************************************************
- *           UnhookWindowsHook32   (USER32.556)
+ *           UnhookWindowsHook32   (USER32.557)
  */
 BOOL32 WINAPI UnhookWindowsHook32( INT32 id, HOOKPROC32 proc )
 {
@@ -1318,7 +1318,7 @@
 
 
 /***********************************************************************
- *           UnhookWindowHookEx32   (USER32.557)
+ *           UnhookWindowHookEx32   (USER32.558)
  */
 BOOL32 WINAPI UnhookWindowsHookEx32( HHOOK hhook )
 {
@@ -1345,7 +1345,7 @@
 
 
 /***********************************************************************
- *           CallNextHookEx32    (USER32.16)
+ *           CallNextHookEx32    (USER32.17)
  *
  * There aren't ANSI and UNICODE versions of this.
  */
@@ -1396,7 +1396,7 @@
 
 
 /***********************************************************************
- *           CallMsgFilter32A   (USER32.14)
+ *           CallMsgFilter32A   (USER32.15)
  */
 /*
  * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
@@ -1412,7 +1412,7 @@
 
 
 /***********************************************************************
- *           CallMsgFilter32W   (USER32.15)
+ *           CallMsgFilter32W   (USER32.16)
  */
 BOOL32 WINAPI CallMsgFilter32W( LPMSG32 msg, INT32 code )
 {
diff --git a/windows/keyboard.c b/windows/keyboard.c
index 6d91398..06de1f7 100644
--- a/windows/keyboard.c
+++ b/windows/keyboard.c
@@ -310,6 +310,9 @@
 
 static BOOL32 NumState=FALSE, CapsState=FALSE;
 
+/**********************************************************************
+ *		KEYBOARD_GenerateMsg
+ */
 void KEYBOARD_GenerateMsg( WORD vkey, int Evtype, INT32 event_x, INT32 event_y,
                            DWORD event_time, KEYLP localkeylp )
 {
@@ -492,7 +495,7 @@
 
 
 /**********************************************************************
- *		GetKeyState			[USER.106]
+ *           GetKeyState      (USER.106)
  */
 WORD WINAPI GetKeyState16(INT16 vkey)
 {
@@ -500,7 +503,8 @@
 }
 
 /**********************************************************************
- *		GetKeyState			[USER32.248]
+ *           GetKeyState      (USER32.249)
+ *
  * An application calls the GetKeyState function in response to a
  * keyboard-input message.  This function retrieves the state of the key
  * at the time the input message was generated.  (SDK 3.1 Vol 2. p 390)
@@ -531,7 +535,8 @@
 }
 
 /**********************************************************************
- *		GetKeyboardState	[USER.222][USER32.253]
+ *           GetKeyboardState      (USER.222)(USER32.254)
+ *
  * An application calls the GetKeyboardState function in response to a
  * keyboard-input message.  This function retrieves the state of the keyboard
  * at the time the input message was generated.  (SDK 3.1 Vol 2. p 387)
@@ -548,7 +553,7 @@
 }
 
 /**********************************************************************
- *      SetKeyboardState            [USER.223][USER32.483]
+ *          SetKeyboardState      (USER.223)(USER32.484)
  */
 VOID WINAPI SetKeyboardState(LPBYTE lpKeyState)
 {
@@ -562,7 +567,7 @@
 }
 
 /**********************************************************************
- *            GetAsyncKeyState        (USER32.206)
+ *           GetAsyncKeyState32      (USER32.207)
  *
  *	Determine if a key is or was pressed.  retval has high-order 
  * bit set to 1 if currently pressed, low-order bit set to 1 if key has
@@ -606,7 +611,7 @@
 }
 
 /**********************************************************************
- *            GetAsyncKeyState        (USER.249)
+ *            GetAsyncKeyState16        (USER.249)
  */
 WORD WINAPI GetAsyncKeyState16(INT16 nKey)
 {
@@ -614,7 +619,7 @@
 }
 
 /**********************************************************************
- *			TranslateAccelerator 	[USER.178][USER32.551..]
+ *           KBD_translate_accelerator
  *
  * FIXME: should send some WM_INITMENU or/and WM_INITMENUPOPUP  -messages
  */
@@ -734,6 +739,9 @@
     return FALSE;
 }
 
+/**********************************************************************
+ *      TranslateAccelerator32      (USER32.551)(USER32.552)(USER32.553)
+ */
 INT32 WINAPI TranslateAccelerator32(HWND32 hWnd, HACCEL32 hAccel, LPMSG32 msg)
 {
     LPACCEL32	lpAccelTbl = (LPACCEL32)LockResource32(hAccel);
@@ -754,14 +762,20 @@
 	  "msg->hwnd=%04x, msg->message=%04x\n",
 	  hAccel,hWnd,msg->hwnd,msg->message);
 
-    for (i = 0; lpAccelTbl[i].key ; i++)
+    i = 0;
+    do
+    {
     	if (KBD_translate_accelerator(hWnd,msg,lpAccelTbl[i].fVirt,
                                       lpAccelTbl[i].key,lpAccelTbl[i].cmd))
 		return 1;
+    } while ((lpAccelTbl[i++].fVirt & 0x80) == 0);
     WARN(accel, "couldn't translate accelerator key");
     return 0;
 }
-	
+
+/**********************************************************************
+ *           TranslateAccelerator16      (USER.178)
+ */	
 INT16 WINAPI TranslateAccelerator16(HWND16 hWnd, HACCEL16 hAccel, LPMSG16 msg)
 {
     LPACCEL16	lpAccelTbl = (LPACCEL16)LockResource16(hAccel);
@@ -784,17 +798,20 @@
     STRUCT32_MSG16to32(msg,&msg32);
 
 
-    for (i=0;lpAccelTbl[i].key;i++) 
+    i = 0;
+    do
+    {
     	if (KBD_translate_accelerator(hWnd,&msg32,lpAccelTbl[i].fVirt,
                                       lpAccelTbl[i].key,lpAccelTbl[i].cmd))
 		return 1;
+    } while ((lpAccelTbl[i++].fVirt & 0x80) == 0);
     WARN(accel, "couldn't translate accelerator key");
     return 0;
 }
 
 
-/******************************************************************************
- *    	OemKeyScan			[KEYBOARD.128][USER32.400]
+/**********************************************************************
+ *           OemKeyScan      (KEYBOARD.128)(USER32.401)
  */
 DWORD WINAPI OemKeyScan(WORD wOemChar)
 {
@@ -803,8 +820,8 @@
     return wOemChar;
 }
 
-/******************************************************************************
- *    	VkKeyScanA			[USER32.572]
+/**********************************************************************
+ *           VkKeyScanA      (USER32.573)
  */
 /* VkKeyScan translates an ANSI character to a virtual-key and shift code
  * for the current keyboard.
@@ -874,7 +891,7 @@
 }
 
 /******************************************************************************
- *    	VkKeyScanW			[USER32.575]
+ *    	VkKeyScanW      (USER32.576)
  */
 WORD WINAPI VkKeyScan32W(WCHAR cChar)
 {
@@ -882,7 +899,7 @@
 }
 
 /******************************************************************************
- *    	GetKeyboardType			[KEYBOARD.130]
+ *    	GetKeyboardType16      (KEYBOARD.130)
  */
 INT16 WINAPI GetKeyboardType16(INT16 nTypeFlag)
 {
@@ -890,7 +907,7 @@
 }
 
 /******************************************************************************
- *    	GetKeyboardType			[USER32.254]
+ *    	GetKeyboardType32      (USER32.255)
  */
 INT32 WINAPI GetKeyboardType32(INT32 nTypeFlag)
 {
@@ -914,7 +931,7 @@
 
 
 /******************************************************************************
- *    	MapVirtualKeyA			[USER32.382]
+ *    	MapVirtualKey32A      (USER32.383)
  */
 UINT32 WINAPI MapVirtualKey32A(UINT32 code, UINT32 maptype)
 {
@@ -922,7 +939,7 @@
 }
 
 /******************************************************************************
- *    	MapVirtualKeyA			[USER32.384]
+ *    	MapVirtualKey32W      (USER32.385)
  */
 UINT32 WINAPI MapVirtualKey32W(UINT32 code, UINT32 maptype)
 {
@@ -930,7 +947,8 @@
 }
 
 /******************************************************************************
- *    	MapVirtualKeyA			[KEYBOARD.131]
+ *    	MapVirtualKey16      (KEYBOARD.131)
+ *
  * MapVirtualKey translates keycodes from one format to another
  */
 UINT16 WINAPI MapVirtualKey16(UINT16 wCode, UINT16 wMapType)
@@ -988,7 +1006,7 @@
 
 
 /****************************************************************************
- *	GetKBCodePage32   (USER32.245)
+ *	GetKBCodePage32   (USER32.246)
  */
 UINT32 WINAPI GetKBCodePage32(void)
 {
@@ -996,9 +1014,16 @@
     return 850;
 }
 
+/****************************************************************************
+ *	GetKeyNameText32A   (USER32.247)
+ */
+INT32 WINAPI GetKeyNameText32A(LONG lParam, LPSTR lpBuffer, INT32 nSize)
+{
+	return GetKeyNameText16(lParam,lpBuffer,nSize);
+}
 
 /****************************************************************************
- *	GetKeyNameText32W   (USER32.247)
+ *	GetKeyNameText32W   (USER32.248)
  */
 INT32 WINAPI GetKeyNameText32W(LONG lParam, LPWSTR lpBuffer, INT32 nSize)
 {
@@ -1010,13 +1035,6 @@
 	return res;
 }
 
-/****************************************************************************
- *	GetKeyNameText32A   (USER32.246)
- */
-INT32 WINAPI GetKeyNameText32A(LONG lParam, LPSTR lpBuffer, INT32 nSize)
-{
-	return GetKeyNameText16(lParam,lpBuffer,nSize);
-}
 
 /****************************************************************************
  *	GetKeyNameText16   (KEYBOARD.133)
@@ -1053,7 +1071,7 @@
 }
 
 /****************************************************************************
- *	ToAscii   (USER32.545)
+ *	ToAscii32      (USER32.546)
  */
 INT32 WINAPI ToAscii32( UINT32 virtKey,UINT32 scanCode,LPBYTE lpKeyState,
                         LPWORD lpChar,UINT32 flags )
@@ -1224,7 +1242,7 @@
 
 
 /***********************************************************************
- *           GetKeyboardLayout			(USER32.249)
+ *           GetKeyboardLayout			(USER32.250)
  */
 HKL32 WINAPI GetKeyboardLayout(DWORD dwLayout)
 {
@@ -1233,7 +1251,7 @@
 }
 
 /***********************************************************************
- *           GetKeyboardLayoutList		(USER32.250)
+ *           GetKeyboardLayoutList		(USER32.251)
  * FIXME
  */
 INT32 WINAPI GetKeyboardLayoutList(INT32 nBuff,HKL32 *layouts)
diff --git a/windows/mdi.c b/windows/mdi.c
index 739aa66..ac848c3 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -571,7 +571,7 @@
 {
  HDC32 		hDCSrc  = CreateCompatibleDC32(0);
  HDC32		hDCDest	= CreateCompatibleDC32(hDCSrc);
- HBITMAP16	hbClose = LoadBitmap16(0, MAKEINTRESOURCE(OBM_CLOSE) );
+ HBITMAP16	hbClose = LoadBitmap16(0, MAKEINTRESOURCE16(OBM_CLOSE) );
  HBITMAP16	hbCopy;
  HANDLE16	hobjSrc, hobjDest;
 
@@ -915,7 +915,7 @@
 	if (!hBmpClose)
         {
             hBmpClose = CreateMDIMenuBitmap();
-            hBmpRestore = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_RESTORE) );
+            hBmpRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
         }
 	MDI_UpdateFrameText(frameWnd, hwnd, MDI_NOFRAMEREPAINT,frameWnd->text);
 
@@ -1152,7 +1152,7 @@
 
 
 /***********************************************************************
- *           DefFrameProc32A   (USER32.121)
+ *           DefFrameProc32A   (USER32.122)
  */
 LRESULT WINAPI DefFrameProc32A( HWND32 hwnd, HWND32 hwndMDIClient,
                                 UINT32 message, WPARAM32 wParam, LPARAM lParam)
@@ -1192,7 +1192,7 @@
 
 
 /***********************************************************************
- *           DefFrameProc32W   (USER32.122)
+ *           DefFrameProc32W   (USER32.123)
  */
 LRESULT WINAPI DefFrameProc32W( HWND32 hwnd, HWND32 hwndMDIClient,
                                 UINT32 message, WPARAM32 wParam, LPARAM lParam)
@@ -1376,7 +1376,7 @@
 
 
 /***********************************************************************
- *           DefMDIChildProc32A   (USER32.123)
+ *           DefMDIChildProc32A   (USER32.124)
  */
 LRESULT WINAPI DefMDIChildProc32A( HWND32 hwnd, UINT32 message,
                                    WPARAM32 wParam, LPARAM lParam )
@@ -1428,7 +1428,7 @@
 
 
 /***********************************************************************
- *           DefMDIChildProc32W   (USER32.124)
+ *           DefMDIChildProc32W   (USER32.125)
  */
 LRESULT WINAPI DefMDIChildProc32W( HWND32 hwnd, UINT32 message,
                                    WPARAM32 wParam, LPARAM lParam )
@@ -1466,15 +1466,15 @@
 
 
 /**********************************************************************
- *              CreateMDIWindowA (USER32.78)
+ *              CreateMDIWindowA (USER32.79)
  */
 
 /**********************************************************************
- *              CreateMDIWindowW (USER32.79)
+ *              CreateMDIWindowW (USER32.80)
  */
 
 /**********************************************************************
- *             TranslateMDISysAccel32   (USER32.554)
+ *             TranslateMDISysAccel32   (USER32.555)
  */
 BOOL32 WINAPI TranslateMDISysAccel32( HWND32 hwndClient, LPMSG32 msg )
 {
@@ -1594,7 +1594,7 @@
 
 
 /***********************************************************************
- *           ScrollChildren32   (USER32.447)
+ *           ScrollChildren32   (USER32.448)
  */
 void WINAPI ScrollChildren32(HWND32 hWnd, UINT32 uMsg, WPARAM32 wParam,
                              LPARAM lParam)
diff --git a/windows/message.c b/windows/message.c
index e96fe52..15ef48e 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -551,7 +551,7 @@
 
 
 /**********************************************************************
- *           SetDoubleClickTime32   (USER32.479)
+ *           SetDoubleClickTime32   (USER32.480)
  */
 BOOL32 WINAPI SetDoubleClickTime32( UINT32 interval )
 {
@@ -570,7 +570,7 @@
 
 
 /**********************************************************************
- *           GetDoubleClickTime32   (USER32.238)
+ *           GetDoubleClickTime32   (USER32.239)
  */
 UINT32 WINAPI GetDoubleClickTime32(void)
 {
@@ -990,7 +990,7 @@
 
 
 /***********************************************************************
- *           PostMessage32A   (USER32.418)
+ *           PostMessage32A   (USER32.419)
  */
 BOOL32 WINAPI PostMessage32A( HWND32 hwnd, UINT32 message, WPARAM32 wParam,
                               LPARAM lParam )
@@ -1001,7 +1001,7 @@
 
 
 /***********************************************************************
- *           PostMessage32W   (USER32.419)
+ *           PostMessage32W   (USER32.420)
  */
 BOOL32 WINAPI PostMessage32W( HWND32 hwnd, UINT32 message, WPARAM32 wParam,
                               LPARAM lParam )
@@ -1141,7 +1141,7 @@
 }
 
 /***********************************************************************
- *           SendMessage32A   (USER32.453)
+ *           SendMessage32A   (USER32.454)
  */
 LRESULT WINAPI SendMessage32A( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
                                LPARAM lParam )
@@ -1278,7 +1278,7 @@
 
 
 /***********************************************************************
- *           WaitMessage    (USER.112) (USER32.577)
+ *           WaitMessage    (USER.112) (USER32.578)
  */
 void WINAPI WaitMessage( void )
 {
@@ -1489,7 +1489,7 @@
 
 
 /***********************************************************************
- *           TranslateMessage32   (USER32.555)
+ *           TranslateMessage32   (USER32.556)
  */
 BOOL32 WINAPI TranslateMessage32( const MSG32 *msg )
 {
@@ -1544,7 +1544,7 @@
 
 
 /***********************************************************************
- *           DispatchMessage32A   (USER32.140)
+ *           DispatchMessage32A   (USER32.141)
  */
 LONG WINAPI DispatchMessage32A( const MSG32* msg )
 {
@@ -1591,7 +1591,7 @@
 
 
 /***********************************************************************
- *           DispatchMessage32W   (USER32.141)
+ *           DispatchMessage32W   (USER32.142)
  */
 LONG WINAPI DispatchMessage32W( const MSG32* msg )
 {
@@ -1648,7 +1648,7 @@
 
 
 /***********************************************************************
- *           RegisterWindowMessage32A   (USER32.436)
+ *           RegisterWindowMessage32A   (USER32.437)
  */
 WORD WINAPI RegisterWindowMessage32A( LPCSTR str )
 {
@@ -1658,7 +1658,7 @@
 
 
 /***********************************************************************
- *           RegisterWindowMessage32W   (USER32.437)
+ *           RegisterWindowMessage32W   (USER32.438)
  */
 WORD WINAPI RegisterWindowMessage32W( LPCWSTR str )
 {
@@ -1699,7 +1699,7 @@
 
 
 /***********************************************************************
- *           InSendMessage32    (USER32.319)
+ *           InSendMessage32    (USER32.320)
  */
 BOOL32 WINAPI InSendMessage32(void)
 {
diff --git a/windows/msgbox.c b/windows/msgbox.c
index 01f45e2..5ebf5e2 100644
--- a/windows/msgbox.c
+++ b/windows/msgbox.c
@@ -69,20 +69,20 @@
     switch(lpmb->dwStyle & MB_ICONMASK) {
      case MB_ICONEXCLAMATION:
       SendDlgItemMessage16(hwnd, stc1, STM_SETICON16,
-                           (WPARAM16)LoadIcon16(0, IDI_EXCLAMATION), 0);
+                           (WPARAM16)LoadIcon16(0, IDI_EXCLAMATION16), 0);
       break;
      case MB_ICONQUESTION:
       SendDlgItemMessage16(hwnd, stc1, STM_SETICON16,
-                           (WPARAM16)LoadIcon16(0, IDI_QUESTION), 0);
+                           (WPARAM16)LoadIcon16(0, IDI_QUESTION16), 0);
       break;
      case MB_ICONASTERISK:
       SendDlgItemMessage16(hwnd, stc1, STM_SETICON16,
-                           (WPARAM16)LoadIcon16(0, IDI_ASTERISK), 0);
+                           (WPARAM16)LoadIcon16(0, IDI_ASTERISK16), 0);
       break;
      case MB_ICONHAND:
      default:
       SendDlgItemMessage16(hwnd, stc1, STM_SETICON16,
-                           (WPARAM16)LoadIcon16(0, IDI_HAND), 0);
+                           (WPARAM16)LoadIcon16(0, IDI_HAND16), 0);
       break;
     }
     
@@ -189,7 +189,7 @@
 
 
 /**************************************************************************
- *           MessageBox32A   (USER32.390)
+ *           MessageBox32A   (USER32.391)
  */
 INT32 WINAPI MessageBox32A(HWND32 hWnd, LPCSTR text, LPCSTR title, UINT32 type)
 {
@@ -208,7 +208,7 @@
 
 
 /**************************************************************************
- *           MessageBox32W   (USER32.395)
+ *           MessageBox32W   (USER32.396)
  */
 INT32 WINAPI MessageBox32W( HWND32 hwnd, LPCWSTR text, LPCWSTR title,
                             UINT32 type )
@@ -223,7 +223,7 @@
 
 
 /**************************************************************************
- *           MessageBoxEx32A   (USER32.391)
+ *           MessageBoxEx32A   (USER32.392)
  */
 INT32 WINAPI MessageBoxEx32A( HWND32 hWnd, LPCSTR text, LPCSTR title,
                               UINT32 type, WORD langid )
@@ -233,7 +233,7 @@
 }
 
 /**************************************************************************
- *           MessageBoxEx32W   (USER32.392)
+ *           MessageBoxEx32W   (USER32.393)
  */
 INT32 WINAPI MessageBoxEx32W( HWND32 hWnd, LPCWSTR text, LPCWSTR title,
                               UINT32 type, WORD langid )
@@ -243,6 +243,30 @@
 }
 
 /**************************************************************************
+ *           MessageBoxIndirect16   (USER.827)
+ */
+INT16 WINAPI MessageBoxIndirect16( LPMSGBOXPARAMS16 msgbox )
+{
+    MSGBOXPARAMS32A msgbox32;
+    
+    msgbox32.cbSize		= msgbox->cbSize;
+    msgbox32.hwndOwner		= msgbox->hwndOwner;
+    msgbox32.hInstance		= msgbox->hInstance;
+    msgbox32.lpszText		= PTR_SEG_TO_LIN(msgbox->lpszText);
+    msgbox32.lpszCaption	= PTR_SEG_TO_LIN(msgbox->lpszCaption);
+    msgbox32.dwStyle		= msgbox->dwStyle;
+    msgbox32.lpszIcon		= PTR_SEG_TO_LIN(msgbox->lpszIcon);
+    msgbox32.dwContextHelpId	= msgbox->dwContextHelpId;
+    msgbox32.lpfnMsgBoxCallback	= msgbox->lpfnMsgBoxCallback;
+    msgbox32.dwLanguageId	= msgbox->dwLanguageId;
+
+    return DialogBoxIndirectParam32A( msgbox32.hInstance,
+                                      SYSRES_GetResPtr( SYSRES_DIALOG_MSGBOX ),
+                                      msgbox32.hwndOwner, MSGBOX_DlgProc,
+                                      (LPARAM)&msgbox32 );
+}
+
+/**************************************************************************
  *           MessageBoxIndirect32A   (USER32.394)
  */
 INT32 WINAPI MessageBoxIndirect32A( LPMSGBOXPARAMS32A msgbox )
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 6d75fc1..fe7e7c9 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -158,7 +158,7 @@
 
 
 /***********************************************************************
- *           DrawCaptionTempA    (USER32.)
+ *           DrawCaptionTempA    (USER32.599)
  */
 DWORD
 DrawCaptionTemp32A(HWND32 hwnd,HDC32 hdc,LPRECT32 rect,HFONT32 hfont,DWORD x1,LPCSTR str,DWORD x2) {
@@ -179,7 +179,7 @@
 
 
 /***********************************************************************
- *           AdjustWindowRect32    (USER32.)
+ *           AdjustWindowRect32    (USER32.2)
  */
 BOOL32 WINAPI AdjustWindowRect32( LPRECT32 rect, DWORD style, BOOL32 menu )
 {
@@ -215,7 +215,7 @@
 
 
 /***********************************************************************
- *           AdjustWindowRectEx32    (USER32.)
+ *           AdjustWindowRectEx32    (USER32.3)
  */
 BOOL32 WINAPI AdjustWindowRectEx32( LPRECT32 rect, DWORD style,
                                     BOOL32 menu, DWORD exStyle )
@@ -854,14 +854,14 @@
 
     if (!hbitmapClose)
     {
-	if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_CLOSE) )))
+	if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
 	    return;
-	hbitmapMinimize  = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_REDUCE) );
-	hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_REDUCED) );
-	hbitmapMaximize  = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_ZOOM) );
-	hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_ZOOMD) );
-	hbitmapRestore   = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_RESTORE) );
-	hbitmapRestoreD  = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_RESTORED) );
+	hbitmapMinimize  = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
+	hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
+	hbitmapMaximize  = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
+	hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
+	hbitmapRestore   = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
+	hbitmapRestoreD  = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
     }
     
     if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
@@ -950,14 +950,14 @@
 					    COLOR_INACTIVECAPTION) );
 
     if (!hbitmapClose) {
-	if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_CLOSE) )))
+	if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
 	    return;
-	hbitmapMinimize  = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_REDUCE) );
-	hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_REDUCED) );
-	hbitmapMaximize  = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_ZOOM) );
-	hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_ZOOMD) );
-	hbitmapRestore   = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_RESTORE) );
-	hbitmapRestoreD  = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_RESTORED) );
+	hbitmapMinimize  = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
+	hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
+	hbitmapMaximize  = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
+	hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
+	hbitmapRestore   = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
+	hbitmapRestoreD  = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
     }
     
     if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME) {
@@ -1297,23 +1297,23 @@
 
     case HTLEFT:
     case HTRIGHT:
-	return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZEWE ) );
+	return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZEWE16 ) );
 
     case HTTOP:
     case HTBOTTOM:
-	return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENS ) );
+	return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENS16 ) );
 
     case HTTOPLEFT:
     case HTBOTTOMRIGHT:	
-	return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENWSE ) );
+	return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENWSE16 ) );
 
     case HTTOPRIGHT:
     case HTBOTTOMLEFT:
-	return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENESW ) );
+	return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENESW16 ) );
     }
 
     /* Default cursor: arrow */
-    return (LONG)SetCursor16( LoadCursor16( 0, IDC_ARROW ) );
+    return (LONG)SetCursor16( LoadCursor16( 0, IDC_ARROW16 ) );
 }
 
 /***********************************************************************
diff --git a/windows/painting.c b/windows/painting.c
index a78982f3..5bfeed2 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -160,7 +160,7 @@
 
 
 /***********************************************************************
- *           BeginPaint32    (USER32.9)
+ *           BeginPaint32    (USER32.10)
  */
 HDC32 WINAPI BeginPaint32( HWND32 hwnd, PAINTSTRUCT32 *lps )
 {
@@ -191,7 +191,7 @@
 
 
 /***********************************************************************
- *           EndPaint32    (USER32.175)
+ *           EndPaint32    (USER32.176)
  */
 BOOL32 WINAPI EndPaint32( HWND32 hwnd, const PAINTSTRUCT32 *lps )
 {
@@ -496,7 +496,7 @@
 
 
 /***********************************************************************
- *           RedrawWindow32    (USER32.425)
+ *           RedrawWindow32    (USER32.426)
  */
 BOOL32 WINAPI RedrawWindow32( HWND32 hwnd, const RECT32 *rectUpdate,
                               HRGN32 hrgnUpdate, UINT32 flags )
@@ -531,7 +531,7 @@
 }
 
 /***********************************************************************
- *           UpdateWindow32   (USER32.566)
+ *           UpdateWindow32   (USER32.567)
  */
 void WINAPI UpdateWindow32( HWND32 hwnd )
 {
@@ -549,7 +549,7 @@
 
 
 /***********************************************************************
- *           InvalidateRgn32   (USER32.328)
+ *           InvalidateRgn32   (USER32.329)
  */
 void WINAPI InvalidateRgn32( HWND32 hwnd, HRGN32 hrgn, BOOL32 erase )
 {
@@ -567,7 +567,7 @@
 
 
 /***********************************************************************
- *           InvalidateRect32   (USER32.327)
+ *           InvalidateRect32   (USER32.328)
  */
 void WINAPI InvalidateRect32( HWND32 hwnd, const RECT32 *rect, BOOL32 erase )
 {
@@ -587,7 +587,7 @@
 
 
 /***********************************************************************
- *           ValidateRgn32   (USER32.571)
+ *           ValidateRgn32   (USER32.572)
  */
 void WINAPI ValidateRgn32( HWND32 hwnd, HRGN32 hrgn )
 {
@@ -605,7 +605,7 @@
 
 
 /***********************************************************************
- *           ValidateRect32   (USER32.570)
+ *           ValidateRect32   (USER32.571)
  */
 void WINAPI ValidateRect32( HWND32 hwnd, const RECT32 *rect )
 {
@@ -629,7 +629,7 @@
 
 
 /***********************************************************************
- *           GetUpdateRect32   (USER32.296)
+ *           GetUpdateRect32   (USER32.297)
  */
 BOOL32 WINAPI GetUpdateRect32( HWND32 hwnd, LPRECT32 rect, BOOL32 erase )
 {
@@ -661,7 +661,7 @@
 
 
 /***********************************************************************
- *           GetUpdateRgn32   (USER32.297)
+ *           GetUpdateRgn32   (USER32.298)
  */
 INT32 WINAPI GetUpdateRgn32( HWND32 hwnd, HRGN32 hrgn, BOOL32 erase )
 {
@@ -690,7 +690,7 @@
 
 
 /***********************************************************************
- *           ExcludeUpdateRgn32   (USER32.194)
+ *           ExcludeUpdateRgn32   (USER32.195)
  */
 INT32 WINAPI ExcludeUpdateRgn32( HDC32 hdc, HWND32 hwnd )
 {
diff --git a/windows/property.c b/windows/property.c
index 9c3ac18..43bc978 100644
--- a/windows/property.c
+++ b/windows/property.c
@@ -66,7 +66,7 @@
 
 
 /***********************************************************************
- *           GetProp32A   (USER32.280)
+ *           GetProp32A   (USER32.281)
  */
 HANDLE32 WINAPI GetProp32A( HWND32 hwnd, LPCSTR str )
 {
@@ -84,7 +84,7 @@
 
 
 /***********************************************************************
- *           GetProp32W   (USER32.281)
+ *           GetProp32W   (USER32.282)
  */
 HANDLE32 WINAPI GetProp32W( HWND32 hwnd, LPCWSTR str )
 {
@@ -109,7 +109,7 @@
 
 
 /***********************************************************************
- *           SetProp32A   (USER32.496)
+ *           SetProp32A   (USER32.497)
  */
 BOOL32 WINAPI SetProp32A( HWND32 hwnd, LPCSTR str, HANDLE32 handle )
 {
@@ -141,7 +141,7 @@
 
 
 /***********************************************************************
- *           SetProp32W   (USER32.497)
+ *           SetProp32W   (USER32.498)
  */
 BOOL32 WINAPI SetProp32W( HWND32 hwnd, LPCWSTR str, HANDLE32 handle )
 {
@@ -167,7 +167,7 @@
 
 
 /***********************************************************************
- *           RemoveProp32A   (USER32.441)
+ *           RemoveProp32A   (USER32.442)
  */
 HANDLE32 WINAPI RemoveProp32A( HWND32 hwnd, LPCSTR str )
 {
@@ -218,7 +218,7 @@
 
 
 /***********************************************************************
- *           RemoveProp32W   (USER32.442)
+ *           RemoveProp32W   (USER32.443)
  */
 HANDLE32 WINAPI RemoveProp32W( HWND32 hwnd, LPCWSTR str )
 {
@@ -280,7 +280,7 @@
 
 
 /***********************************************************************
- *           EnumProps32A   (USER32.185)
+ *           EnumProps32A   (USER32.186)
  */
 INT32 WINAPI EnumProps32A( HWND32 hwnd, PROPENUMPROC32A func )
 {
@@ -289,7 +289,7 @@
 
 
 /***********************************************************************
- *           EnumProps32W   (USER32.188)
+ *           EnumProps32W   (USER32.189)
  */
 INT32 WINAPI EnumProps32W( HWND32 hwnd, PROPENUMPROC32W func )
 {
@@ -298,7 +298,7 @@
 
 
 /***********************************************************************
- *           EnumPropsEx32A   (USER32.186)
+ *           EnumPropsEx32A   (USER32.187)
  */
 INT32 WINAPI EnumPropsEx32A(HWND32 hwnd, PROPENUMPROCEX32A func, LPARAM lParam)
 {
@@ -325,7 +325,7 @@
 
 
 /***********************************************************************
- *           EnumPropsEx32W   (USER32.187)
+ *           EnumPropsEx32W   (USER32.188)
  */
 INT32 WINAPI EnumPropsEx32W(HWND32 hwnd, PROPENUMPROCEX32W func, LPARAM lParam)
 {
diff --git a/windows/queue.c b/windows/queue.c
index 0937f93..1bf2270 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -675,7 +675,7 @@
 
 
 /***********************************************************************
- *           PostQuitMessage32   (USER32.420)
+ *           PostQuitMessage32   (USER32.421)
  */
 void WINAPI PostQuitMessage32( INT32 exitCode )
 {
@@ -699,7 +699,7 @@
 }
 
 /***********************************************************************
- *           GetWindowThreadProcessId   (USER32.312)
+ *           GetWindowThreadProcessId   (USER32.313)
  */
 DWORD WINAPI GetWindowThreadProcessId( HWND32 hwnd, LPDWORD process )
 {
@@ -727,7 +727,7 @@
 
 
 /***********************************************************************
- *           SetMessageQueue32   (USER32.493)
+ *           SetMessageQueue32   (USER32.494)
  */
 BOOL32 WINAPI SetMessageQueue32( INT32 size )
 {
@@ -822,7 +822,7 @@
 
 
 /***********************************************************************
- *           GetInputState32   (USER32.243)
+ *           GetInputState32   (USER32.244)
  */
 BOOL32 WINAPI GetInputState32(void)
 {
@@ -835,7 +835,7 @@
 
 
 /***********************************************************************
- *           GetMessagePos   (USER.119) (USER32.271)
+ *           GetMessagePos   (USER.119) (USER32.272)
  */
 DWORD WINAPI GetMessagePos(void)
 {
@@ -847,7 +847,7 @@
 
 
 /***********************************************************************
- *           GetMessageTime   (USER.120) (USER32.272)
+ *           GetMessageTime   (USER.120) (USER32.273)
  */
 LONG WINAPI GetMessageTime(void)
 {
@@ -859,7 +859,7 @@
 
 
 /***********************************************************************
- *           GetMessageExtraInfo   (USER.288) (USER32.270)
+ *           GetMessageExtraInfo   (USER.288) (USER32.271)
  */
 LONG WINAPI GetMessageExtraInfo(void)
 {
diff --git a/windows/rect.c b/windows/rect.c
index 7605666..e783e85 100644
--- a/windows/rect.c
+++ b/windows/rect.c
@@ -22,7 +22,7 @@
 
 
 /***********************************************************************
- *           SetRect32    (USER32.498)
+ *           SetRect32    (USER32.499)
  */
 void WINAPI SetRect32( LPRECT32 rect, INT32 left, INT32 top,
                        INT32 right, INT32 bottom )
@@ -44,7 +44,7 @@
 
 
 /***********************************************************************
- *           SetRectEmpty32    (USER32.499)
+ *           SetRectEmpty32    (USER32.500)
  */
 void WINAPI SetRectEmpty32( LPRECT32 rect )
 {
@@ -63,7 +63,7 @@
 
 
 /***********************************************************************
- *           CopyRect32    (USER32.61)
+ *           CopyRect32    (USER32.62)
  */
 BOOL32 WINAPI CopyRect32( RECT32 *dest, const RECT32 *src )
 {
@@ -82,7 +82,7 @@
 
 
 /***********************************************************************
- *           IsRectEmpty32    (USER32.346)
+ *           IsRectEmpty32    (USER32.347)
  */
 BOOL32 WINAPI IsRectEmpty32( const RECT32 *rect )
 {
@@ -101,7 +101,7 @@
 
 
 /***********************************************************************
- *           PtInRect32    (USER32.423)
+ *           PtInRect32    (USER32.424)
  */
 BOOL32 WINAPI PtInRect32( const RECT32 *rect, POINT32 pt )
 {
@@ -123,7 +123,7 @@
 
 
 /***********************************************************************
- *           OffsetRect32    (USER32.405)
+ *           OffsetRect32    (USER32.406)
  */
 void WINAPI OffsetRect32( LPRECT32 rect, INT32 x, INT32 y )
 {
@@ -147,7 +147,7 @@
 
 
 /***********************************************************************
- *           InflateRect32    (USER32.320)
+ *           InflateRect32    (USER32.321)
  */
 void WINAPI InflateRect32( LPRECT32 rect, INT32 x, INT32 y )
 {
@@ -180,7 +180,7 @@
 
 
 /***********************************************************************
- *           IntersectRect32    (USER32.326)
+ *           IntersectRect32    (USER32.327)
  */
 BOOL32 WINAPI IntersectRect32( LPRECT32 dest, const RECT32 *src1,
                                const RECT32 *src2 )
@@ -231,7 +231,7 @@
 
 
 /***********************************************************************
- *           UnionRect32    (USER32.558)
+ *           UnionRect32    (USER32.559)
  */
 BOOL32 WINAPI UnionRect32( LPRECT32 dest, const RECT32 *src1,
                            const RECT32 *src2 )
@@ -271,7 +271,7 @@
 
 
 /***********************************************************************
- *           EqualRect32    (USER32.193)
+ *           EqualRect32    (USER32.194)
  */
 BOOL32 WINAPI EqualRect32( const RECT32* rect1, const RECT32* rect2 )
 {
@@ -317,7 +317,7 @@
 
 
 /***********************************************************************
- *           SubtractRect32    (USER32.535)
+ *           SubtractRect32    (USER32.536)
  */
 BOOL32 WINAPI SubtractRect32( LPRECT32 dest, const RECT32 *src1,
                               const RECT32 *src2 )
diff --git a/windows/scroll.c b/windows/scroll.c
index 701e69b..885968c 100644
--- a/windows/scroll.c
+++ b/windows/scroll.c
@@ -37,7 +37,7 @@
 }
 
 /*************************************************************************
- *             ScrollWindow32   (USER32.449)
+ *             ScrollWindow32   (USER32.450)
  *
  * FIXME: verify clipping region calculations
  */
@@ -140,7 +140,7 @@
 
 
 /*************************************************************************
- *             ScrollDC32   (USER32.448)
+ *             ScrollDC32   (USER32.449)
  * 
  * Both 'rc' and 'prLClip' are in logical units but update info is 
  * returned in device coordinates.
@@ -344,7 +344,7 @@
 }
 
 /*************************************************************************
- *             ScrollWindowEx32   (USER32.450)
+ *             ScrollWindowEx32   (USER32.451)
  *
  * NOTE: Use this function instead of ScrollWindow32
  */
diff --git a/windows/syscolor.c b/windows/syscolor.c
index dd490a9..baf3ae5 100644
--- a/windows/syscolor.c
+++ b/windows/syscolor.c
@@ -27,7 +27,7 @@
     "ActiveBorder", "128 128 128",   /* COLOR_ACTIVEBORDER        */
     "InactiveBorder", "255 255 255", /* COLOR_INACTIVEBORDER      */
     "AppWorkspace", "255 255 232",   /* COLOR_APPWORKSPACE        */
-    "Hilight", "166 202 240",        /* COLOR_HIGHLIGHT           */
+    "Hilight", "224 224 224",        /* COLOR_HIGHLIGHT           */
     "HilightText", "0 0 0",          /* COLOR_HIGHLIGHTTEXT       */
     "ButtonFace", "192 192 192",     /* COLOR_BTNFACE             */
     "ButtonShadow", "128 128 128",   /* COLOR_BTNSHADOW           */
@@ -56,7 +56,7 @@
     "ActiveBorder", "128 128 128",   /* COLOR_ACTIVEBORDER        */
     "InactiveBorder", "255 255 255", /* COLOR_INACTIVEBORDER      */
     "AppWorkspace", "255 255 232",   /* COLOR_APPWORKSPACE        */
-    "Hilight", "166 202 240",        /* COLOR_HIGHLIGHT           */
+    "Hilight", "224 224 224",        /* COLOR_HIGHLIGHT           */
     "HilightText", "0 0 0",          /* COLOR_HIGHLIGHTTEXT       */
     "ButtonFace", "192 192 192",     /* COLOR_BTNFACE             */
     "ButtonShadow", "128 128 128",   /* COLOR_BTNSHADOW           */
@@ -123,7 +123,7 @@
 
 
 /*************************************************************************
- *             GetSysColor32   (USER32.288)
+ *             GetSysColor32   (USER32.289)
  */
 COLORREF WINAPI GetSysColor32( INT32 nIndex )
 {
@@ -159,7 +159,7 @@
 
 
 /*************************************************************************
- *             SetSysColors32   (USER32.504)
+ *             SetSysColors32   (USER32.505)
  */
 BOOL32 WINAPI SetSysColors32( INT32 nChanges, const INT32 *lpSysColor,
                               const COLORREF *lpColorValues )
@@ -193,7 +193,7 @@
 
 
 /***********************************************************************
- *           GetSysColorBrush32    (USER32.289)
+ *           GetSysColorBrush32    (USER32.290)
  */
 HBRUSH32 WINAPI GetSysColorBrush32( INT32 index )
 {
diff --git a/windows/sysmetrics.c b/windows/sysmetrics.c
index 9a9cff6..b1f4ea9 100644
--- a/windows/sysmetrics.c
+++ b/windows/sysmetrics.c
@@ -146,7 +146,7 @@
 
 
 /***********************************************************************
- *           GetSystemMetrics32    (USER32.291)
+ *           GetSystemMetrics32    (USER32.292)
  */
 INT32 WINAPI GetSystemMetrics32( INT32 index )
 {
diff --git a/windows/timer.c b/windows/timer.c
index a14aa6a..488b430 100644
--- a/windows/timer.c
+++ b/windows/timer.c
@@ -310,7 +310,7 @@
 
 
 /***********************************************************************
- *           SetTimer32   (USER32.510)
+ *           SetTimer32   (USER32.511)
  */
 UINT32 WINAPI SetTimer32( HWND32 hwnd, UINT32 id, UINT32 timeout,
                           TIMERPROC32 proc )
@@ -336,7 +336,7 @@
 
 
 /***********************************************************************
- *           SetSystemTimer32   (USER32.508)
+ *           SetSystemTimer32   (USER32.509)
  */
 UINT32 WINAPI SetSystemTimer32( HWND32 hwnd, UINT32 id, UINT32 timeout,
                                 TIMERPROC32 proc )
@@ -359,7 +359,7 @@
 
 
 /***********************************************************************
- *           KillTimer32   (USER32.353)
+ *           KillTimer32   (USER32.354)
  */
 BOOL32 WINAPI KillTimer32( HWND32 hwnd, UINT32 id )
 {
@@ -379,7 +379,7 @@
 
 
 /***********************************************************************
- *           KillSystemTimer32   (USER32.352)
+ *           KillSystemTimer32   (USER32.353)
  */
 BOOL32 WINAPI KillSystemTimer32( HWND32 hwnd, UINT32 id )
 {
diff --git a/windows/user.c b/windows/user.c
index ec801d6..249cfa7 100644
--- a/windows/user.c
+++ b/windows/user.c
@@ -20,10 +20,9 @@
 #include "debug.h"
 #include "toolhelp.h"
 #include "message.h"
+#include "miscemu.h"
 #include "shell.h"
 
-WORD USER_HeapSel = 0;
-
 extern BOOL32 MENU_PatchResidentPopup( HQUEUE16, WND* );
 extern void QUEUE_FlushMessages(HQUEUE16);
 
@@ -117,10 +116,12 @@
     /* SetResourceHandler() returns previous function which is set
      * when a module's resource table is loaded. */
 
-    proc = SetResourceHandler( hInstance, RT_ICON, (FARPROC32)LoadDIBIconHandler );
+    proc = SetResourceHandler( hInstance, RT_ICON16,
+                               (FARPROC32)LoadDIBIconHandler );
     if(!__r16loader ) 
 	__r16loader = (RESOURCEHANDLER16)proc;
-    proc = SetResourceHandler( hInstance, RT_CURSOR, (FARPROC32)LoadDIBCursorHandler );
+    proc = SetResourceHandler( hInstance, RT_CURSOR16,
+                               (FARPROC32)LoadDIBCursorHandler );
     if(!__r16loader )
 	__r16loader = (RESOURCEHANDLER16)proc;
 }
@@ -141,6 +142,10 @@
 
     USER_InstallRsrcHandler( hInstance );
 
+    /* Hack: restore the divide-by-zero handler */
+    /* FIXME: should set a USER-specific handler that displays a msg box */
+    INT_SetHandler( 0, INT_GetHandler( 0xff ) );
+
       /* Create task message queue */
     queueSize = GetProfileInt32A( "windows", "DefaultQueueSize", 8 );
     if (!SetMessageQueue32( queueSize )) return 0;
@@ -264,7 +269,7 @@
 
 
 /***********************************************************************
- *           ExitWindowsEx   (USER32.195)
+ *           ExitWindowsEx   (USER32.196)
  */
 BOOL32 WINAPI ExitWindowsEx( UINT32 flags, DWORD reserved )
 {
diff --git a/windows/win.c b/windows/win.c
index b15181d..c251cba 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -438,6 +438,7 @@
     pWndDesktop->pHScroll          = NULL;
     pWndDesktop->pProp             = NULL;
     pWndDesktop->wIDmenu           = 0;
+    pWndDesktop->helpContext       = 0;
     pWndDesktop->flags             = 0;
     pWndDesktop->window            = rootWindow;
     pWndDesktop->hSysMenu          = 0;
@@ -467,8 +468,8 @@
     LRESULT (WINAPI *localSend32)(HWND32, UINT32, WPARAM32, LPARAM);
 
     TRACE(win, "%s %s %08lx %08lx %d,%d %dx%d "
-		 "%04x %04x %08x %p\n", debugres(cs->lpszName), 
-		 debugres(cs->lpszClass), cs->dwExStyle, 
+		 "%04x %04x %08x %p\n", debugres_a(cs->lpszName), 
+		 debugres_a(cs->lpszClass), cs->dwExStyle, 
 		 cs->style, cs->x, cs->y, cs->cx, cs->cy,
 		 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams);
 
@@ -551,6 +552,7 @@
     wndPtr->dwStyle        = cs->style & ~WS_VISIBLE;
     wndPtr->dwExStyle      = cs->dwExStyle;
     wndPtr->wIDmenu        = 0;
+    wndPtr->helpContext    = 0;
     wndPtr->flags          = win32 ? WIN_ISWIN32 : 0;
     wndPtr->pVScroll       = NULL;
     wndPtr->pHScroll       = NULL;
@@ -2300,6 +2302,29 @@
 
 
 /*******************************************************************
+ *           GetWindowContextHelpId   (USER32.303)
+ */
+DWORD WINAPI GetWindowContextHelpId( HWND32 hwnd )
+{
+    WND *wnd = WIN_FindWndPtr( hwnd );
+    if (!wnd) return 0;
+    return wnd->helpContext;
+}
+
+
+/*******************************************************************
+ *           SetWindowContextHelpId   (USER32.515)
+ */
+BOOL32 WINAPI SetWindowContextHelpId( HWND32 hwnd, DWORD id )
+{
+    WND *wnd = WIN_FindWndPtr( hwnd );
+    if (!wnd) return FALSE;
+    wnd->helpContext = id;
+    return TRUE;
+}
+
+
+/*******************************************************************
  *			DRAG_QueryUpdate
  *
  * recursively find a child that contains spDragInfo->pt point 
@@ -2440,7 +2465,7 @@
 
     if( !lpDragInfo || !spDragInfo ) return 0L;
 
-    hBummer = LoadCursor16(0, IDC_BUMMER);
+    hBummer = LoadCursor16(0, IDC_BUMMER16);
 
     if( !hBummer || !wndPtr )
     {
diff --git a/windows/winhelp.c b/windows/winhelp.c
index d8521d4..2ef305b 100644
--- a/windows/winhelp.c
+++ b/windows/winhelp.c
@@ -23,7 +23,7 @@
 
 
 /**********************************************************************
- *             WinHelp32A   (USER32.578)
+ *             WinHelp32A   (USER32.579)
  */
 BOOL32 WINAPI WinHelp32A( HWND32 hWnd, LPCSTR lpHelpFile, UINT32 wCommand,
                           DWORD dwData )
@@ -109,7 +109,7 @@
 
 
 /**********************************************************************
- *             WinHelp32W   (USER32.579)
+ *             WinHelp32W   (USER32.580)
  */
 BOOL32 WINAPI WinHelp32W( HWND32 hWnd, LPCWSTR helpFile, UINT32 command,
                           DWORD dwData )
diff --git a/windows/winpos.c b/windows/winpos.c
index aebdca8..e992acc 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -153,7 +153,7 @@
     return ArrangeIconicWindows32(parent);
 }
 /***********************************************************************
- *           ArrangeIconicWindows32   (USER32.6)
+ *           ArrangeIconicWindows32   (USER32.7)
  */
 UINT32 WINAPI ArrangeIconicWindows32( HWND32 parent )
 {
@@ -201,7 +201,7 @@
 
 
 /***********************************************************************
- *             SwitchToThisWindow32   (USER32.538)
+ *             SwitchToThisWindow32   (USER32.539)
  */
 void WINAPI SwitchToThisWindow32( HWND32 hwnd, BOOL32 restore )
 {
@@ -254,7 +254,7 @@
 
 
 /***********************************************************************
- *           GetClientRect32   (USER32.219)
+ *           GetClientRect32   (USER32.220)
  */
 void WINAPI GetClientRect32( HWND32 hwnd, LPRECT32 rect ) 
 {
@@ -279,7 +279,7 @@
 
 
 /*******************************************************************
- *         ClientToScreen32   (USER32.51)
+ *         ClientToScreen32   (USER32.52)
  */
 BOOL32 WINAPI ClientToScreen32( HWND32 hwnd, LPPOINT32 lppnt )
 {
@@ -298,7 +298,7 @@
 
 
 /*******************************************************************
- *         ScreenToClient32   (USER32.446)
+ *         ScreenToClient32   (USER32.447)
  */
 void WINAPI ScreenToClient32( HWND32 hwnd, LPPOINT32 lppnt )
 {
@@ -394,7 +394,7 @@
 
 
 /*******************************************************************
- *         WindowFromPoint32   (USER32.581)
+ *         WindowFromPoint32   (USER32.582)
  */
 HWND32 WINAPI WindowFromPoint32( POINT32 pt )
 {
@@ -418,7 +418,7 @@
 
 
 /*******************************************************************
- *         ChildWindowFromPoint32   (USER32.48)
+ *         ChildWindowFromPoint32   (USER32.49)
  */
 HWND32 WINAPI ChildWindowFromPoint32( HWND32 hwndParent, POINT32 pt )
 {
@@ -513,7 +513,7 @@
 
 
 /*******************************************************************
- *         MapWindowPoints32   (USER32.385)
+ *         MapWindowPoints32   (USER32.386)
  */
 void WINAPI MapWindowPoints32( HWND32 hwndFrom, HWND32 hwndTo,
                                LPPOINT32 lppt, UINT32 count )
@@ -540,7 +540,7 @@
 
 
 /***********************************************************************
- *           IsIconic32   (USER32.344)
+ *           IsIconic32   (USER32.345)
  */
 BOOL32 WINAPI IsIconic32(HWND32 hWnd)
 {
@@ -560,7 +560,7 @@
 
 
 /***********************************************************************
- *           IsZoomed   (USER32.351)
+ *           IsZoomed   (USER32.352)
  */
 BOOL32 WINAPI IsZoomed32(HWND32 hWnd)
 {
@@ -579,7 +579,7 @@
 }
 
 /*******************************************************************
- *         GetActiveWindow    (USER32.204)
+ *         GetActiveWindow    (USER32.205)
  */
 HWND32 WINAPI GetActiveWindow32(void)
 {
@@ -608,7 +608,7 @@
 
 
 /*******************************************************************
- *         SetActiveWindow32    (USER32.462)
+ *         SetActiveWindow32    (USER32.463)
  */
 HWND32 WINAPI SetActiveWindow32( HWND32 hwnd )
 {
@@ -668,7 +668,7 @@
 }
 
 /*******************************************************************
- *         SetShellWindow32    (USER32.287)
+ *         SetShellWindow32    (USER32.504)
  */
 HWND32 WINAPI SetShellWindow32(HWND32 hwndshell)
 {
@@ -697,7 +697,7 @@
 
 
 /***********************************************************************
- *           BringWindowToTop32   (USER32.10)
+ *           BringWindowToTop32   (USER32.11)
  */
 BOOL32 WINAPI BringWindowToTop32( HWND32 hwnd )
 {
@@ -716,7 +716,7 @@
 
 
 /***********************************************************************
- *           MoveWindow32   (USER32.398)
+ *           MoveWindow32   (USER32.399)
  */
 BOOL32 WINAPI MoveWindow32( HWND32 hwnd, INT32 x, INT32 y, INT32 cx, INT32 cy,
                             BOOL32 repaint )
@@ -1111,7 +1111,7 @@
 
 
 /***********************************************************************
- *           GetInternalWindowPos32   (USER32.244)
+ *           GetInternalWindowPos32   (USER32.245)
  */
 UINT32 WINAPI GetInternalWindowPos32( HWND32 hwnd, LPRECT32 rectWnd,
                                       LPPOINT32 ptIcon )
@@ -1156,7 +1156,7 @@
 
 
 /***********************************************************************
- *           GetWindowPlacement32   (USER32.306)
+ *           GetWindowPlacement32   (USER32.307)
  */
 BOOL32 WINAPI GetWindowPlacement32( HWND32 hwnd, WINDOWPLACEMENT32 *pwpl32 )
 {
@@ -1238,7 +1238,7 @@
 }
 
 /***********************************************************************
- *           SetWindowPlacement32   (USER32.518)
+ *           SetWindowPlacement32   (USER32.519)
  */
 BOOL32 WINAPI SetWindowPlacement32( HWND32 hwnd, const WINDOWPLACEMENT32 *pwpl32 )
 {
@@ -1289,7 +1289,7 @@
 
 
 /***********************************************************************
- *           SetInternalWindowPos32   (USER32.482)
+ *           SetInternalWindowPos32   (USER32.483)
  */
 void WINAPI SetInternalWindowPos32( HWND32 hwnd, UINT32 showCmd,
                                     LPRECT32 rect, LPPOINT32 pt )
@@ -2042,7 +2042,7 @@
 }
 
 /***********************************************************************
- *           SetWindowPos   (USER32.519)
+ *           SetWindowPos   (USER32.520)
  */
 BOOL32 WINAPI SetWindowPos32( HWND32 hwnd, HWND32 hwndInsertAfter,
                               INT32 x, INT32 y, INT32 cx, INT32 cy, WORD flags)
@@ -2054,6 +2054,7 @@
     HWND32	tempInsertAfter= 0;
     int 	result = 0;
     UINT32 	uFlags = 0;
+    BOOL32      resync = FALSE;
 
     TRACE(win,"hwnd %04x, (%i,%i)-(%i,%i) flags %08x\n", 
 						 hwnd, x, y, x+cx, y+cy, flags);  
@@ -2324,6 +2325,7 @@
               winpos.hwndInsertAfter = tempInsertAfter;
 	    }
             TSXMapWindow( display, wndPtr->window );
+            if (wndPtr->flags & WIN_MANAGED) resync = TRUE;
 
 	    /* If focus was set to an unmapped window, reset X focus now */
 	    focus = curr = GetFocus32();
@@ -2398,9 +2400,13 @@
 
     TRACE(win,"\tstatus flags = %04x\n", winpos.flags & SWP_AGG_STATUSFLAGS);
 
-    if ( ((winpos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) && 
-	 !(winpos.flags & SWP_NOSENDCHANGING))
+    if ( resync ||
+        (((winpos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) && 
+         !(winpos.flags & SWP_NOSENDCHANGING)) )
+    {
         SendMessage32A( winpos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&winpos );
+        if (resync) EVENT_Synchronize ();
+    }
 
     return TRUE;
 }
@@ -2416,7 +2422,7 @@
 
 
 /***********************************************************************
- *           BeginDeferWindowPos32   (USER32.8)
+ *           BeginDeferWindowPos32   (USER32.9)
  */
 HDWP32 WINAPI BeginDeferWindowPos32( INT32 count )
 {
@@ -2449,7 +2455,7 @@
 
 
 /***********************************************************************
- *           DeferWindowPos32   (USER32.127)
+ *           DeferWindowPos32   (USER32.128)
  */
 HDWP32 WINAPI DeferWindowPos32( HDWP32 hdwp, HWND32 hwnd, HWND32 hwndAfter,
                                 INT32 x, INT32 y, INT32 cx, INT32 cy,
@@ -2537,7 +2543,7 @@
 
 
 /***********************************************************************
- *           EndDeferWindowPos32   (USER32.172)
+ *           EndDeferWindowPos32   (USER32.173)
  */
 BOOL32 WINAPI EndDeferWindowPos32( HDWP32 hdwp )
 {
diff --git a/windows/winproc.c b/windows/winproc.c
index 3b627de..66df775 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -1855,7 +1855,7 @@
 
 
 /**********************************************************************
- *	     CallWindowProc32A    (USER32.17)
+ *	     CallWindowProc32A    (USER32.18)
  */
 LRESULT WINAPI CallWindowProc32A( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
                                   WPARAM32 wParam, LPARAM lParam )
@@ -1891,7 +1891,7 @@
 
 
 /**********************************************************************
- *	     CallWindowProc32W    (USER32.18)
+ *	     CallWindowProc32W    (USER32.19)
  */
 LRESULT WINAPI CallWindowProc32W( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
                                   WPARAM32 wParam, LPARAM lParam )