Release 980517

Sun May 17 16:23:56 1998  Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>

	* [file/profile.c]
	Fix the return value of PROFILE_GetSection

	* [misc/crtdll.c]
	Do _getdrive, fix _chdrive.

	* [misc/commdlg.c]
	First cut at ChooseColor[WA].

	* [misc/network.c]
	Do something sensible for WNetGetDirectoryType16.

Sun May 17 10:21:35 1998  Andreas Mohr <100.30936@germany.net>

	* [controls/menu.c]
	Fixed disabled sub menus with MF_BYPOSITION that were not disabled.

	* [misc/crtdll.c] [relay32/crtdll.spec] [include/winerror.h]
	Implemented fscanf, fsetpos, _access, _fpreset (thanks to Uwe Bonnes),
	and _ltoa. 

	* [loader/task.c]
	MakeProcInstance: must use CURRENT_DS if hInst == NULL.

	* [misc/shell.c]
	SHELL_GetResourceTable, InternalExtractIcon: fixed broken .ICO handling

	* [windows/winpos.c]
	DeferWindowPos: removed "same parent" requirement.
	Which doc states that this is required ?

Sat May 16 20:08:11 1998  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [loader/module.c] [loader/ne/module.c]
	More NE module cleanups.

	* [loader/task.c]
	Fixed SwitchStackBack().

Fri May 15 10:04:27 1998  Marcus Meissner <marcus@jet.franken.de>

	* [configure.in][inlcude/acconfig.h]
	Fixed broken OSS check, added check for working sigaltstack,
	fixed broken statfs checks on some linux systems.

	* [files/directory.c][loader/pe_image.c][relay32/builtin.c]
	  [loader/module.c]
	Added handling of win32 module pathnames.

	* [relay32/wnaspi32.spec]
	New file.

	* [misc/lzexpand.c]
	LZCopy auto-decompresses LZ compressed files, even if they are not
	specially flagged. Fixes some InstallShield problems.

	* [misc/registry.c]
	Some fixes for RegQueryInfoKey (reference program monkey.exe
	from Win32 SDK works now better). Probably still has faults.

Fri May 15 08:58:58 1998  Martin Boehme <boehme@informatik.mu-luebeck.de>

	* [graphics/mapping.c] [include/dc.h] [include/gdi.h] [objects/dc.c]
	Reworked the way world transformations and mapping modes are handled
	so that both of these transformations can be computed in a single
	step.

	* [graphics/painting.c] [graphics/path.c] [include/path.h]
	More GDI path support.

	* [graphics/x11drv/graphics.c]
	Fixed the return value of GRAPH_DrawArc for the zero height /
	zero width case to reflect Windows' behaviour.

	* [include/windows.h] [relay32/gdi32.spec] [objects/dc.c]
	Implemented ModifyWorldTransform and CombineTransform.

Tue May 14 18:03:46 1998  Eric Kohl <ekohl@abo.rhein-zeitung.de>

	* [controls/commctrl.c][relay32/comctl32.spec]
	  [controls/*.c][include/*.h]
	Implemented InitCommonControlsEx (dll version 4.72 compatible).
	InitCommonControls calls ImageCommonControlsEx.
	Registering code of the common controls had to be changed
	(see XXXX_Register functions).

	* [controls/status.c][include/commctrl.h][include/status.h]
	Implemented most new features and fixed the look and feel.

	* [contols/commctrl.c][include/commctrl.h][relay32/comctl32.spec]
	Implemented MenuHelp (incomplete).

	* [controls/status.c][controls/progress.c]
	Changed allocation strategy for control specific memory.

	* [controls/header.c][include/header.h][include/commctrl.h]
	First implementation of header control.

	* [windows/defwnd.c][windows/syscolors.c]
	Fixed default control colors for Win95 look.

	* [windows/nonclient.c]
	Fixed off by one error for Win95 look. Top border of child windows
	should be visible.

	* [misc/imagelist.h]
	Improved documentation and fixed some bugs.

Thu May 14 15:42:21 1998  Robert Wilhelm  <robert@physiol.med.tu-muenchen.de>

	* [relay32/crtdll.spec]
	Added hypot,j0,j1,jn and ceil.

Wed May 13 19:10:10 1998  Pascal Cuoq <pcuoq@ens-lyon.fr>

	* [controls/listbox.c]
	Item height is now exactly font height.
	Wine listboxes now behave like Windows' when they are 
	created without WS_VSCROLL but the program subsequently 
	calls ShowScrollBar or SetScrollInfo.

Wed May 13 18:33:01 1998  Ulrich Weigand <weigand@informatik.uni-erlangen.de>

	* [relay32/relay386.c]
	Restore ES also in the non-debug case.

	* [windows/event.c]
	Bugfix: Blocking TSXNextEvent could deadlock Wine.

	* [win32/process.c] [windows/message.c]
	Silly stubs for MsgWaitForMultipleObjects / PostThreadMessage
	that make some programs run better.

	* [windows/winproc.c]
	WINPROC_MapMsg32Ato16/16To32A: added WM_NOTIFY.  

        * [win32/kernel32.c]
	Added 16->32 thunking and improved 32->16 thunking functions.

	* [tools/build.c]
	Added new variant of CallFrom16 stub for use with Win95 thunks.

	* [if1632/kernel.spec] [if1632/builtin.c] [win32/kernel32.c]
	Added a few undocumented KERNEL functions.

	* [loader/ne/module.c] [loader/ne/segment.c]
	Call DllEntryPoint for 16-bit DLLs with subsystem >= 4.0.

	* [win32/kernel32.spec] [win32/wow32.spec] [win32/ordinals.c]
	Use names from the Oct 94 beta release for undoc. functions.

Wed May 13 14:18:26 1998  Matthew Becker <mbecker@glasscity.net>

	* [misc/registry.c]
	Code cleanup.

	* [misc/cpu.c]
	Commented out the registry puts temporarily.

	* [programs/regtest/*]
	New registry testing program.

Tue May 12 22:54:03 1998  Michael Mess <michael@kawo2.rwth-aachen.de>

	* [multimedia/audio.c]
	ioctl's do not commute in /dev/dsp initialization.

Tue May 12 20:11:42 1998  Karl Garrison <karlos@eznet.net>

	* [win32/console.c]
	Implemented SetConsoleTextAttribute, FillConsoleOutputCharacter.
	Improved cursor positioning.
	This allows for text colors in an xterm, rxvt, or console.

Tue May 12 17:57:52 1998  Petter Reinholdtsen <pere@td.org.uit.no>

	* [Makefile.in]
	Create prefix/{bin|lib} directories if missing during install.

Sun May 10 19:37:51 1998  Jan Willamowius <jan@janhh.shnet.org>

	* [multimedia/mmio.c]
	Have mmioSetBuffer return success (0), so Corel Draw 4
	keeps working. (IO is still unbuffered)

Wed May  6 16:57:55 1998  James Juran <jrj120@psu.edu>

        * [Makefile.in] [Make.rules.in]
	Changed "make clean" to remove `textedit` backup files (*%)

	* [controls/menu.c][graphics/x11drv/xfont.c][include/libres.h]
	  [loader/main.c][loader/ne/module.c][scheduler/synchro.c]
	  [win32/time.c][windows/winpos.c][include/windows.h]
	Fixed miscellaneous compilation warnings.

	* [misc/main.c][miscemu/main.c][include/main.h]
	Moved prototypes to new include file main.h, various cleanups.

Tue May  5 21:05:06 1998  Morten Welinder  <terra@diku.dk>

	* [misc/winsock.c]
	Don't refer to __FreeBSD__ when HAVE_STRERROR is meant.

	* [misc/debugstr.c]
	For debug_dumpstrSend, send strings to stderr.

Tue May  5 21:47:40 1998  Huw D M Davies <h.davies1@physics.oxford.ac.uk>

	* [objects/region.c]
	Fix for REGION_RegionOp() if newReg is one of the source regions.

Tue May  5 18:27:32 1998  Jim Peterson <jspeter@roanoke.infi.net>

	* [misc/main.c]
	Add '-h/-help' option and print WINE_RELEASE_INFO with usage message.

	* [misc/spy.c]
	Realign trace messages.

Tue May  5 15:46:47 1998  Donnie V. Savage <dsavage@cisco.com>

	* [graphics/ddraw.c]
	Fixed compile warnings

	* [misc/winsock.c]
	Warnings should not be errors.

Tue May  5 13:40:42 1998  Jim Peterson <jspeter@roanoke.infi.net>

	* [*/*]
	Remove many warnings through explicit casts, added #include's,
	and corrected printf formats.

Tue May  5 05:18:12 1998  Insomnia (Stea Greene) <insomnia@core.binghamton.edu>

	* [graphics/ddraw.c]
	Kept unchanged portion of old palette when changing only a few
	palette entries.  Really should only deallocate the changed cells.
	This make StarCraft work almost perfectly (sound overflows still
	cause static).

Mon May  4 15:04:57 1998  Alexander V. Lukyanov <lav@long.yar.ru>

	* [misc/lstr.c]
	FormatMessage: terminate string on %0, undo linefeed strip.
diff --git a/ANNOUNCE b/ANNOUNCE
index 1e0549f..e199bae 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,14 +1,13 @@
-This is release 980503 of Wine, the MS Windows emulator.  This is still a
+This is release 980517 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-980503: (see ChangeLog for details)
-	- Module loading restructuration.
-	- Some rotated text support.
-	- Documentation for many more functions.
+WHAT'S NEW with Wine-980517: (see ChangeLog for details)
+	- Lots of common controls improvements.
+	- Better thunking support.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -17,10 +16,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-980503.tar.gz
-  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-980503.tar.gz
-  ftp://ftp.infomagic.com/pub/mirrors/linux/sunsite/ALPHA/wine/development/Wine-980503.tar.gz
-  ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-980503.tar.gz
+  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-980517.tar.gz
+  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-980517.tar.gz
+  ftp://ftp.infomagic.com/pub/mirrors/linux/sunsite/ALPHA/wine/development/Wine-980517.tar.gz
+  ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-980517.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/ChangeLog b/ChangeLog
index 7f3f722..b5888c3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,253 @@
 ----------------------------------------------------------------------
+Sun May 17 16:23:56 1998  Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>
+
+	* [file/profile.c]
+	Fix the return value of PROFILE_GetSection
+
+	* [misc/crtdll.c]
+	Do _getdrive, fix _chdrive.
+
+	* [misc/commdlg.c]
+	First cut at ChooseColor[WA].
+
+	* [misc/network.c]
+	Do something sensible for WNetGetDirectoryType16.
+
+Sun May 17 10:21:35 1998  Andreas Mohr <100.30936@germany.net>
+
+	* [controls/menu.c]
+	Fixed disabled sub menus with MF_BYPOSITION that were not disabled.
+
+	* [misc/crtdll.c] [relay32/crtdll.spec] [include/winerror.h]
+	Implemented fscanf, fsetpos, _access, _fpreset (thanks to Uwe Bonnes),
+	and _ltoa. 
+
+	* [loader/task.c]
+	MakeProcInstance: must use CURRENT_DS if hInst == NULL.
+
+	* [misc/shell.c]
+	SHELL_GetResourceTable, InternalExtractIcon: fixed broken .ICO handling
+
+	* [windows/winpos.c]
+	DeferWindowPos: removed "same parent" requirement.
+	Which doc states that this is required ?
+
+Sat May 16 20:08:11 1998  Alexandre Julliard  <julliard@lrc.epfl.ch>
+
+	* [loader/module.c] [loader/ne/module.c]
+	More NE module cleanups.
+
+	* [loader/task.c]
+	Fixed SwitchStackBack().
+
+Fri May 15 10:04:27 1998  Marcus Meissner <marcus@jet.franken.de>
+
+	* [configure.in][inlcude/acconfig.h]
+	Fixed broken OSS check, added check for working sigaltstack,
+	fixed broken statfs checks on some linux systems.
+
+	* [files/directory.c][loader/pe_image.c][relay32/builtin.c]
+	  [loader/module.c]
+	Added handling of win32 module pathnames.
+
+	* [relay32/wnaspi32.spec]
+	New file.
+
+	* [misc/lzexpand.c]
+	LZCopy auto-decompresses LZ compressed files, even if they are not
+	specially flagged. Fixes some InstallShield problems.
+
+	* [misc/registry.c]
+	Some fixes for RegQueryInfoKey (reference program monkey.exe
+	from Win32 SDK works now better). Probably still has faults.
+
+Fri May 15 08:58:58 1998  Martin Boehme <boehme@informatik.mu-luebeck.de>
+
+	* [graphics/mapping.c] [include/dc.h] [include/gdi.h] [objects/dc.c]
+	Reworked the way world transformations and mapping modes are handled
+	so that both of these transformations can be computed in a single
+	step.
+
+	* [graphics/painting.c] [graphics/path.c] [include/path.h]
+	More GDI path support.
+
+	* [graphics/x11drv/graphics.c]
+	Fixed the return value of GRAPH_DrawArc for the zero height /
+	zero width case to reflect Windows' behaviour.
+
+	* [include/windows.h] [relay32/gdi32.spec] [objects/dc.c]
+	Implemented ModifyWorldTransform and CombineTransform.
+
+Tue May 14 18:03:46 1998  Eric Kohl <ekohl@abo.rhein-zeitung.de>
+
+	* [controls/commctrl.c][relay32/comctl32.spec]
+	  [controls/*.c][include/*.h]
+	Implemented InitCommonControlsEx (dll version 4.72 compatible).
+	InitCommonControls calls ImageCommonControlsEx.
+	Registering code of the common controls had to be changed
+	(see XXXX_Register functions).
+
+	* [controls/status.c][include/commctrl.h][include/status.h]
+	Implemented most new features and fixed the look and feel.
+
+	* [contols/commctrl.c][include/commctrl.h][relay32/comctl32.spec]
+	Implemented MenuHelp (incomplete).
+
+	* [controls/status.c][controls/progress.c]
+	Changed allocation strategy for control specific memory.
+
+	* [controls/header.c][include/header.h][include/commctrl.h]
+	First implementation of header control.
+
+	* [windows/defwnd.c][windows/syscolors.c]
+	Fixed default control colors for Win95 look.
+
+	* [windows/nonclient.c]
+	Fixed off by one error for Win95 look. Top border of child windows
+	should be visible.
+
+	* [misc/imagelist.h]
+	Improved documentation and fixed some bugs.
+
+Thu May 14 15:42:21 1998  Robert Wilhelm  <robert@physiol.med.tu-muenchen.de>
+
+	* [relay32/crtdll.spec]
+	Added hypot,j0,j1,jn and ceil.
+
+Wed May 13 19:10:10 1998  Pascal Cuoq <pcuoq@ens-lyon.fr>
+
+	* [controls/listbox.c]
+	Item height is now exactly font height.
+	Wine listboxes now behave like Windows' when they are 
+	created without WS_VSCROLL but the program subsequently 
+	calls ShowScrollBar or SetScrollInfo.
+
+Wed May 13 18:33:01 1998  Ulrich Weigand <weigand@informatik.uni-erlangen.de>
+
+	* [relay32/relay386.c]
+	Restore ES also in the non-debug case.
+
+	* [windows/event.c]
+	Bugfix: Blocking TSXNextEvent could deadlock Wine.
+
+	* [win32/process.c] [windows/message.c]
+	Silly stubs for MsgWaitForMultipleObjects / PostThreadMessage
+	that make some programs run better.
+
+	* [windows/winproc.c]
+	WINPROC_MapMsg32Ato16/16To32A: added WM_NOTIFY.  
+
+        * [win32/kernel32.c]
+	Added 16->32 thunking and improved 32->16 thunking functions.
+
+	* [tools/build.c]
+	Added new variant of CallFrom16 stub for use with Win95 thunks.
+
+	* [if1632/kernel.spec] [if1632/builtin.c] [win32/kernel32.c]
+	Added a few undocumented KERNEL functions.
+
+	* [loader/ne/module.c] [loader/ne/segment.c]
+	Call DllEntryPoint for 16-bit DLLs with subsystem >= 4.0.
+
+	* [win32/kernel32.spec] [win32/wow32.spec] [win32/ordinals.c]
+	Use names from the Oct 94 beta release for undoc. functions.
+
+Wed May 13 14:18:26 1998  Matthew Becker <mbecker@glasscity.net>
+
+	* [misc/registry.c]
+	Code cleanup.
+
+	* [misc/cpu.c]
+	Commented out the registry puts temporarily.
+
+	* [programs/regtest/*]
+	New registry testing program.
+
+Tue May 12 22:54:03 1998  Michael Mess <michael@kawo2.rwth-aachen.de>
+
+	* [multimedia/audio.c]
+	ioctl's do not commute in /dev/dsp initialization.
+
+Tue May 12 20:11:42 1998  Karl Garrison <karlos@eznet.net>
+
+	* [win32/console.c]
+	Implemented SetConsoleTextAttribute, FillConsoleOutputCharacter.
+	Improved cursor positioning.
+	This allows for text colors in an xterm, rxvt, or console.
+
+Tue May 12 17:57:52 1998  Petter Reinholdtsen <pere@td.org.uit.no>
+
+	* [Makefile.in]
+	Create prefix/{bin|lib} directories if missing during install.
+
+Sun May 10 19:37:51 1998  Jan Willamowius <jan@janhh.shnet.org>
+
+	* [multimedia/mmio.c]
+	Have mmioSetBuffer return success (0), so Corel Draw 4
+	keeps working. (IO is still unbuffered)
+
+Wed May  6 16:57:55 1998  James Juran <jrj120@psu.edu>
+
+        * [Makefile.in] [Make.rules.in]
+	Changed "make clean" to remove `textedit` backup files (*%)
+
+	* [controls/menu.c][graphics/x11drv/xfont.c][include/libres.h]
+	  [loader/main.c][loader/ne/module.c][scheduler/synchro.c]
+	  [win32/time.c][windows/winpos.c][include/windows.h]
+	Fixed miscellaneous compilation warnings.
+
+	* [misc/main.c][miscemu/main.c][include/main.h]
+	Moved prototypes to new include file main.h, various cleanups.
+
+Tue May  5 21:05:06 1998  Morten Welinder  <terra@diku.dk>
+
+	* [misc/winsock.c]
+	Don't refer to __FreeBSD__ when HAVE_STRERROR is meant.
+
+	* [misc/debugstr.c]
+	For debug_dumpstrSend, send strings to stderr.
+
+Tue May  5 21:47:40 1998  Huw D M Davies <h.davies1@physics.oxford.ac.uk>
+
+	* [objects/region.c]
+	Fix for REGION_RegionOp() if newReg is one of the source regions.
+
+Tue May  5 18:27:32 1998  Jim Peterson <jspeter@roanoke.infi.net>
+
+	* [misc/main.c]
+	Add '-h/-help' option and print WINE_RELEASE_INFO with usage message.
+
+	* [misc/spy.c]
+	Realign trace messages.
+
+Tue May  5 15:46:47 1998  Donnie V. Savage <dsavage@cisco.com>
+
+	* [graphics/ddraw.c]
+	Fixed compile warnings
+
+	* [misc/winsock.c]
+	Warnings should not be errors.
+
+Tue May  5 13:40:42 1998  Jim Peterson <jspeter@roanoke.infi.net>
+
+	* [*/*]
+	Remove many warnings through explicit casts, added #include's,
+	and corrected printf formats.
+
+Tue May  5 05:18:12 1998  Insomnia (Stea Greene) <insomnia@core.binghamton.edu>
+
+	* [graphics/ddraw.c]
+	Kept unchanged portion of old palette when changing only a few
+	palette entries.  Really should only deallocate the changed cells.
+	This make StarCraft work almost perfectly (sound overflows still
+	cause static).
+
+Mon May  4 15:04:57 1998  Alexander V. Lukyanov <lav@long.yar.ru>
+
+	* [misc/lstr.c]
+	FormatMessage: terminate string on %0, undo linefeed strip.
+
+----------------------------------------------------------------------
 Thu Apr 30 16:28:12 1998  James Juran <jrj120@psu.edu>
 
 	* [scheduler/process.c]
diff --git a/Make.rules.in b/Make.rules.in
index 76a2f1c..9080b93 100644
--- a/Make.rules.in
+++ b/Make.rules.in
@@ -132,7 +132,7 @@
 	$(MAKEDEP) $(DIVINCL) -C$(SRCDIR) $(C_SRCS) $(RC_SRCS) $(EXTRA_SRCS)
 
 clean::
-	$(RM) *.o \#*\# *~ *.bak *.orig *.rej *.flc *-tmp.c y.tab.c y.tab.h lex.yy.c core $(GEN_ASM_SRCS) $(RC_SRCS:.rc=.c) $(RC_SRCS:.rc=.h) $(PROGRAMS)
+	$(RM) *.o \#*\# *~ *% *.bak *.orig *.rej *.flc *-tmp.c y.tab.c y.tab.h lex.yy.c core $(GEN_ASM_SRCS) $(RC_SRCS:.rc=.c) $(RC_SRCS:.rc=.h) $(PROGRAMS)
 
 dummy:
 
diff --git a/Makefile.in b/Makefile.in
index c9548fa..ad023d9 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -122,6 +122,8 @@
 	$(CC) -shared -Wl,-soname,libwine.so -o$@ $(LIBOBJS) $(LDOPTIONS) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS)
 
 install_emu: install_lib
+	-mkdirhier $(bindir)
+	-mkdirhier $(libdir)
 	$(INSTALL_PROGRAM) wine $(bindir)/wine
 	$(INSTALL_DATA) wine.sym $(libdir)/wine.sym
 
@@ -157,7 +159,7 @@
 
 clean::
 	for i in $(ALLSUBDIRS); do (cd $$i; $(MAKE) clean) || exit 1; done
-	for i in include; do (cd $$i; $(RM) *.o \#*\# *~ *.bak *.orig *.rej *.flc); done
+	for i in include; do (cd $$i; $(RM) *.o \#*\# *~ *% *.bak *.orig *.rej *.flc); done
 	$(RM) wine wine.sym libwine.a libwine.so.1.0 TAGS
 
 distclean: clean
diff --git a/configure b/configure
index 8a11a0c..5863cb2 100755
--- a/configure
+++ b/configure
@@ -2135,30 +2135,33 @@
 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
 
+if test "$ac_cv_c_opensoundsystem" = "yes"
+then
+    cat >> confdefs.h <<\EOF
+#define HAVE_OSS 1
+EOF
+
+fi
+
 
 echo $ac_n "checking "for union semun"""... $ac_c" 1>&6
-echo "configure:2157: checking "for union semun"" >&5
+echo "configure:2160: 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 2162 "configure"
+#line 2165 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/sem.h>
@@ -2166,7 +2169,7 @@
 union semun foo
 ; return 0; }
 EOF
-if { (eval echo configure:2170: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2173: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_union_semun="yes"
 else
@@ -2194,7 +2197,7 @@
 then
   CFLAGS="$CFLAGS -Wall"
   echo $ac_n "checking "for gcc strength-reduce bug"""... $ac_c" 1>&6
-echo "configure:2198: checking "for gcc strength-reduce bug"" >&5
+echo "configure:2201: 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
@@ -2202,7 +2205,7 @@
   ac_cv_c_gcc_strength_bug="yes"
 else
   cat > conftest.$ac_ext <<EOF
-#line 2206 "configure"
+#line 2209 "configure"
 #include "confdefs.h"
 
 int main(void) {
@@ -2213,7 +2216,7 @@
   exit( Array[1] != -2 );
 }
 EOF
-if { (eval echo configure:2217: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2220: \"$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
@@ -2236,7 +2239,7 @@
 
 
 echo $ac_n "checking "whether external symbols need an underscore prefix"""... $ac_c" 1>&6
-echo "configure:2240: checking "whether external symbols need an underscore prefix"" >&5
+echo "configure:2243: 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
@@ -2248,14 +2251,14 @@
 	.long 0
 EOF
 cat > conftest.$ac_ext <<EOF
-#line 2252 "configure"
+#line 2255 "configure"
 #include "confdefs.h"
 extern int ac_test;
 int main() {
 if (ac_test) return 1
 ; return 0; }
 EOF
-if { (eval echo configure:2259: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2262: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_c_extern_prefix="yes"
 else
@@ -2279,7 +2282,7 @@
 
 
 echo $ac_n "checking "whether assembler accepts .string"""... $ac_c" 1>&6
-echo "configure:2283: checking "whether assembler accepts .string"" >&5
+echo "configure:2286: 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
@@ -2289,14 +2292,14 @@
 	.string "test"
 EOF
 cat > conftest.$ac_ext <<EOF
-#line 2293 "configure"
+#line 2296 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:2300: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2303: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_c_asm_string="yes"
 else
@@ -2323,21 +2326,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:2327: checking "whether we can build a dll"" >&5
+echo "configure:2330: 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 2334 "configure"
+#line 2337 "configure"
 #include "confdefs.h"
 
 int main() {
 return 1
 ; return 0; }
 EOF
-if { (eval echo configure:2341: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2344: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_c_dll="yes"
 else
@@ -2363,7 +2366,7 @@
 
 
 echo $ac_n "checking "for reentrant X libraries"""... $ac_c" 1>&6
-echo "configure:2367: checking "for reentrant X libraries"" >&5
+echo "configure:2370: 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
@@ -2407,12 +2410,12 @@
 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:2411: checking for $ac_func" >&5
+echo "configure:2414: 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 2416 "configure"
+#line 2419 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2435,7 +2438,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2439: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2442: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2463,17 +2466,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2467: checking for $ac_hdr" >&5
+echo "configure:2470: 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 2472 "configure"
+#line 2475 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2477: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2480: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2500,12 +2503,12 @@
 done
 
 echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6
-echo "configure:2504: checking whether stat file-mode macros are broken" >&5
+echo "configure:2507: 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 2509 "configure"
+#line 2512 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -2556,12 +2559,12 @@
 fi
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:2560: checking for working const" >&5
+echo "configure:2563: 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 2565 "configure"
+#line 2568 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -2610,7 +2613,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2614: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2617: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -2631,12 +2634,12 @@
 fi
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:2635: checking for ANSI C header files" >&5
+echo "configure:2638: 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 2640 "configure"
+#line 2643 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -2644,7 +2647,7 @@
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2648: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2651: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2661,7 +2664,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 2665 "configure"
+#line 2668 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -2679,7 +2682,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 2683 "configure"
+#line 2686 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -2700,7 +2703,7 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 2704 "configure"
+#line 2707 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -2711,7 +2714,7 @@
 exit (0); }
 
 EOF
-if { (eval echo configure:2715: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2718: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -2735,12 +2738,12 @@
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:2739: checking for size_t" >&5
+echo "configure:2742: 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 2744 "configure"
+#line 2747 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -2768,7 +2771,7 @@
 fi
 
 echo $ac_n "checking size of long long""... $ac_c" 1>&6
-echo "configure:2772: checking size of long long" >&5
+echo "configure:2775: 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
@@ -2776,7 +2779,7 @@
   ac_cv_sizeof_long_long=0
 else
   cat > conftest.$ac_ext <<EOF
-#line 2780 "configure"
+#line 2783 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -2787,7 +2790,7 @@
   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
+if { (eval echo configure:2794: \"$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
@@ -2807,8 +2810,213 @@
 
 
 
+
+if test "$ac_cv_header_sys_vfs_h" = "yes"
+then
+    echo $ac_n "checking "whether sys/vfs.h defines statfs"""... $ac_c" 1>&6
+echo "configure:2818: checking "whether sys/vfs.h defines statfs"" >&5
+if eval "test \"`echo '$''{'wine_cv_sys_vfs_has_statfs'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2823 "configure"
+#include "confdefs.h"
+
+	#include <sys/types.h>
+	#ifdef HAVE_SYS_PARAM_H
+	# include <sys/param.h>
+	#endif
+	#include <sys/vfs.h>
+	
+int main() {
+
+		struct statfs stfs;
+
+		memset(&stfs,0,sizeof(stfs));
+	
+; return 0; }
+EOF
+if { (eval echo configure:2840: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  wine_cv_sys_vfs_has_statfs=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  wine_cv_sys_vfs_has_statfs=no
+	
+fi
+rm -f conftest*
+    
+fi
+
+echo "$ac_t""$wine_cv_sys_vfs_has_statfs" 1>&6
+    if test "$wine_cv_sys_vfs_has_statfs" = "yes"
+    then
+      cat >> confdefs.h <<\EOF
+#define STATFS_DEFINED_BY_SYS_VFS 1
+EOF
+
+    fi
+fi
+
+if test "$ac_cv_header_sys_statfs_h" = "yes"
+then
+    echo $ac_n "checking "whether sys/statfs.h defines statfs"""... $ac_c" 1>&6
+echo "configure:2867: checking "whether sys/statfs.h defines statfs"" >&5
+if eval "test \"`echo '$''{'wine_cv_sys_statfs_has_statfs'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2872 "configure"
+#include "confdefs.h"
+
+	#include <sys/types.h>
+	#ifdef HAVE_SYS_PARAM_H
+	# include <sys/param.h>
+	#endif
+	#include <sys/statfs.h>
+	
+int main() {
+
+		struct statfs stfs;
+	
+; return 0; }
+EOF
+if { (eval echo configure:2887: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  wine_cv_sys_statfs_has_statfs=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  wine_cv_sys_statfs_has_statfs=no
+	
+fi
+rm -f conftest*
+    
+fi
+
+echo "$ac_t""$wine_cv_sys_statfs_has_statfs" 1>&6
+    if test "$wine_cv_sys_statfs_has_statfs" = "yes"
+    then
+      cat >> confdefs.h <<\EOF
+#define STATFS_DEFINED_BY_SYS_STATFS 1
+EOF
+
+    fi
+fi
+
+if test "$ac_cv_header_sys_mount_h" = "yes"
+then
+    echo $ac_n "checking "whether sys/mount.h defines statfs"""... $ac_c" 1>&6
+echo "configure:2914: checking "whether sys/mount.h defines statfs"" >&5
+if eval "test \"`echo '$''{'wine_cv_sys_mount_has_statfs'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2919 "configure"
+#include "confdefs.h"
+
+	#include <sys/types.h>
+	#ifdef HAVE_SYS_PARAM_H
+	# include <sys/param.h>
+	#endif
+	#include <sys/mount.h>
+	
+int main() {
+
+		struct statfs stfs;
+	
+; return 0; }
+EOF
+if { (eval echo configure:2934: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  wine_cv_sys_mount_has_statfs=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  wine_cv_sys_mount_has_statfs=no
+	
+fi
+rm -f conftest*
+    
+fi
+
+echo "$ac_t""$wine_cv_sys_mount_has_statfs" 1>&6
+    if test "$wine_cv_sys_mount_has_statfs" = "yes"
+    then
+      cat >> confdefs.h <<\EOF
+#define STATFS_DEFINED_BY_SYS_MOUNT 1
+EOF
+
+    fi
+fi
+
+
+echo $ac_n "checking "for statfs.f_bfree"""... $ac_c" 1>&6
+echo "configure:2960: 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 2969 "configure"
+#include "confdefs.h"
+
+	#include <sys/types.h>
+	#ifdef HAVE_SYS_PARAM_H
+	# include <sys/param.h>
+	#endif
+	#ifdef STATFS_DEFINED_BY_SYS_MOUNT
+	# include <sys/mount.h>
+	#else
+	# ifdef STATFS_DEFINED_BY_SYS_VFS
+	#  include <sys/vfs.h>
+	# else
+	#  ifdef STATFS_DEFINED_BY_SYS_STATFS
+	#   include <sys/statfs.h>
+	#  endif
+	# endif
+	#endif
+	
+int main() {
+
+		struct statfs stfs;
+
+		stfs.f_bfree++;
+	
+; return 0; }
+EOF
+if { (eval echo configure:2996: \"$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
+
 echo $ac_n "checking "for statfs.f_bavail"""... $ac_c" 1>&6
-echo "configure:2812: checking "for statfs.f_bavail"" >&5
+echo "configure:3020: 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
@@ -2817,21 +3025,23 @@
         wine_cv_statfs_bavail=no
     else
     	cat > conftest.$ac_ext <<EOF
-#line 2821 "configure"
+#line 3029 "configure"
 #include "confdefs.h"
 
 	#include <sys/types.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
+	#ifdef STATFS_DEFINED_BY_SYS_MOUNT
 	# include <sys/mount.h>
-	#endif
-	#ifdef HAVE_SYS_VFS_H
-	# include <sys/vfs.h>
+	#else
+	# ifdef STATFS_DEFINED_BY_SYS_VFS
+	#  include <sys/vfs.h>
+	# else
+	#  ifdef STATFS_DEFINED_BY_SYS_STATFS
+	#   include <sys/statfs.h>
+	#  endif
+	# endif
 	#endif
 	
 int main() {
@@ -2842,7 +3052,7 @@
 	
 ; return 0; }
 EOF
-if { (eval echo configure:2846: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3056: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_statfs_bavail=yes
 else
@@ -2865,60 +3075,75 @@
 
 fi
 
-echo $ac_n "checking "for statfs.f_bfree"""... $ac_c" 1>&6
-echo "configure:2870: checking "for statfs.f_bfree"" >&5
-if eval "test \"`echo '$''{'wine_cv_statfs_bfree'+set}'`\" = set"; then
+
+echo $ac_n "checking "for working sigaltstack"""... $ac_c" 1>&6
+echo "configure:3081: checking "for working sigaltstack"" >&5
+if eval "test \"`echo '$''{'ac_cv_c_working_sigaltstack'+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 2879 "configure"
+  if test "$cross_compiling" = yes; then
+  ac_cv_c_working_sigaltstack="no"
+
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3090 "configure"
 #include "confdefs.h"
 
+	#include <stdio.h>
+	#include <time.h> /* <sys/time.h> ? bad magic without end */
 	#include <sys/types.h>
+	#include <sys/signal.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>
+	#ifdef HAVE_SYSCALL_H
+	# include <syscall.h>
+	#else
+	# ifdef HAVE_SYS_SYSCALL_H
+	#  include <sys/syscall.h>
+	# endif
 	#endif
 	
-int main() {
+	unsigned char *xaltstack;
 
-		struct statfs stfs;
+	int
+	main(int argc,char **argv) {
+	    struct sigaltstack	ss;
 
-		stfs.f_bfree++;
+	    xaltstack = malloc(16384);
+	    ss.ss_sp    = xaltstack;
+	    ss.ss_size  = 16384;
+	    ss.ss_flags = 0;
+	    if (sigaltstack(&ss, NULL) < 0) {
+	    	/* this catches the glibc case */
+		perror("sigaltstack");
+	    	return (1); /* aka exit(1) aka fail */
+	    }
+	    /* assume it works. */
+	    return 0; /* OK */
+	}
 	
-; return 0; }
 EOF
-if { (eval echo configure:2904: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
-  rm -rf conftest*
-  wine_cv_statfs_bfree=yes
+if { (eval echo configure:3128: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_c_working_sigaltstack="yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  wine_cv_statfs_bfree=no
-	
+  rm -fr conftest*
+  ac_cv_c_working_sigaltstack="no"
 fi
-rm -f conftest*
-    fi  
+rm -fr conftest*
 fi
 
-echo "$ac_t""$wine_cv_statfs_bfree" 1>&6
-if test "$wine_cv_statfs_bfree" = "yes"
+fi
+
+echo "$ac_t""$ac_cv_c_working_sigaltstack" 1>&6
+
+if test "$ac_cv_c_working_sigaltstack" = "yes"
 then
-  cat >> confdefs.h <<\EOF
-#define STATFS_HAS_BFREE 1
+    cat >> confdefs.h <<\EOF
+#define HAVE_WORKING_SIGALTSTACK 1
 EOF
 
 fi
@@ -3057,6 +3282,7 @@
 programs/clock/Makefile
 programs/notepad/Makefile
 programs/progman/Makefile
+programs/regtest/Makefile
 programs/view/Makefile
 programs/winhelp/Makefile
 programs/winver/Makefile
@@ -3187,6 +3413,7 @@
 programs/clock/Makefile
 programs/notepad/Makefile
 programs/progman/Makefile
+programs/regtest/Makefile
 programs/view/Makefile
 programs/winhelp/Makefile
 programs/winver/Makefile
diff --git a/configure.in b/configure.in
index d783a00..43e2627 100644
--- a/configure.in
+++ b/configure.in
@@ -75,11 +75,12 @@
 #if !defined(SNDCTL_DSP_STEREO)
 #error No open sound system
 #endif
-],
-	ac_cv_c_opensoundsystem="yes"
-	AC_DEFINE(HAVE_OSS),
-	ac_cv_c_opensoundsystem="no"
-))
+],ac_cv_c_opensoundsystem="yes",ac_cv_c_opensoundsystem="no"))
+
+if test "$ac_cv_c_opensoundsystem" = "yes"
+then
+    AC_DEFINE(HAVE_OSS)
+fi
 
 dnl **** Check for union semun ****
 
@@ -220,7 +221,108 @@
 AC_TYPE_SIZE_T()
 AC_CHECK_SIZEOF(long long,0)
 
-dnl **** Dependent checks ****
+dnl **** statfs checks ****
+
+if test "$ac_cv_header_sys_vfs_h" = "yes"
+then
+    AC_CACHE_CHECK( "whether sys/vfs.h defines statfs",
+		    wine_cv_sys_vfs_has_statfs,
+	AC_TRY_COMPILE([
+	#include <sys/types.h>
+	#ifdef HAVE_SYS_PARAM_H
+	# include <sys/param.h>
+	#endif
+	#include <sys/vfs.h>
+	],[
+		struct statfs stfs;
+
+		memset(&stfs,0,sizeof(stfs));
+	],wine_cv_sys_vfs_has_statfs=yes,wine_cv_sys_vfs_has_statfs=no
+	)
+    )
+    if test "$wine_cv_sys_vfs_has_statfs" = "yes"
+    then
+      AC_DEFINE(STATFS_DEFINED_BY_SYS_VFS)
+    fi
+fi
+
+if test "$ac_cv_header_sys_statfs_h" = "yes"
+then
+    AC_CACHE_CHECK( "whether sys/statfs.h defines statfs",
+		    wine_cv_sys_statfs_has_statfs,
+	AC_TRY_COMPILE([
+	#include <sys/types.h>
+	#ifdef HAVE_SYS_PARAM_H
+	# include <sys/param.h>
+	#endif
+	#include <sys/statfs.h>
+	],[
+		struct statfs stfs;
+	],wine_cv_sys_statfs_has_statfs=yes,wine_cv_sys_statfs_has_statfs=no
+	)
+    )
+    if test "$wine_cv_sys_statfs_has_statfs" = "yes"
+    then
+      AC_DEFINE(STATFS_DEFINED_BY_SYS_STATFS)
+    fi
+fi
+
+if test "$ac_cv_header_sys_mount_h" = "yes"
+then
+    AC_CACHE_CHECK( "whether sys/mount.h defines statfs",
+		    wine_cv_sys_mount_has_statfs,
+	AC_TRY_COMPILE([
+	#include <sys/types.h>
+	#ifdef HAVE_SYS_PARAM_H
+	# include <sys/param.h>
+	#endif
+	#include <sys/mount.h>
+	],[
+		struct statfs stfs;
+	],wine_cv_sys_mount_has_statfs=yes,wine_cv_sys_mount_has_statfs=no
+	)
+    )
+    if test "$wine_cv_sys_mount_has_statfs" = "yes"
+    then
+      AC_DEFINE(STATFS_DEFINED_BY_SYS_MOUNT)
+    fi
+fi
+
+dnl **** FIXME: what about mixed cases, where we need two of them? ***
+
+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([
+	#include <sys/types.h>
+	#ifdef HAVE_SYS_PARAM_H
+	# include <sys/param.h>
+	#endif
+	#ifdef STATFS_DEFINED_BY_SYS_MOUNT
+	# include <sys/mount.h>
+	#else
+	# ifdef STATFS_DEFINED_BY_SYS_VFS
+	#  include <sys/vfs.h>
+	# else
+	#  ifdef STATFS_DEFINED_BY_SYS_STATFS
+	#   include <sys/statfs.h>
+	#  endif
+	# endif
+	#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
+
 AC_CACHE_CHECK( "for statfs.f_bavail", wine_cv_statfs_bavail,
   [ if test "x$statfs_bavail" = "xno"
     then
@@ -231,14 +333,16 @@
 	#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
+	#ifdef STATFS_DEFINED_BY_SYS_MOUNT
 	# include <sys/mount.h>
-	#endif
-	#ifdef HAVE_SYS_VFS_H
-	# include <sys/vfs.h>
+	#else
+	# ifdef STATFS_DEFINED_BY_SYS_VFS
+	#  include <sys/vfs.h>
+	# else
+	#  ifdef STATFS_DEFINED_BY_SYS_STATFS
+	#   include <sys/statfs.h>
+	#  endif
+	# endif
 	#endif
 	],[
 		struct statfs stfs;
@@ -252,35 +356,54 @@
   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([
+dnl *** check for working sigaltstack
+dnl glibc 2.0x defines it, but it always fails... so it is useless for us.
+
+AC_CACHE_CHECK("for working sigaltstack",
+	ac_cv_c_working_sigaltstack,
+	AC_TRY_RUN([
+	#include <stdio.h>
+	#include <time.h> /* <sys/time.h> ? bad magic without end */
 	#include <sys/types.h>
+	#include <sys/signal.h>
 	#ifdef HAVE_SYS_PARAM_H
 	# include <sys/param.h>
 	#endif
-	#ifdef HAVE_SYS_STATFS_H
-	# include <sys/statfs.h>
+	#ifdef HAVE_SYSCALL_H
+	# include <syscall.h>
+	#else
+	# ifdef HAVE_SYS_SYSCALL_H
+	#  include <sys/syscall.h>
+	# endif
 	#endif
-	#ifdef HAVE_SYS_MOUNT_H
-	# include <sys/mount.h>
-	#endif
-	#ifdef HAVE_SYS_VFS_H
-	# include <sys/vfs.h>
-	#endif
-	],[
-		struct statfs stfs;
+	
+	unsigned char *xaltstack;
 
-		stfs.f_bfree++;
-	],wine_cv_statfs_bfree=yes,wine_cv_statfs_bfree=no
-	)
-    fi ] )
-if test "$wine_cv_statfs_bfree" = "yes"
+	int
+	main(int argc,char **argv) {
+	    struct sigaltstack	ss;
+
+	    xaltstack = malloc(16384);
+	    ss.ss_sp    = xaltstack;
+	    ss.ss_size  = 16384;
+	    ss.ss_flags = 0;
+	    if (sigaltstack(&ss, NULL) < 0) {
+	    	/* this catches the glibc case */
+		perror("sigaltstack");
+	    	return (1); /* aka exit(1) aka fail */
+	    }
+	    /* assume it works. */
+	    return 0; /* OK */
+	}
+	],
+	ac_cv_c_working_sigaltstack="yes",
+	ac_cv_c_working_sigaltstack="no",
+	ac_cv_c_working_sigaltstack="no"
+))
+
+if test "$ac_cv_c_working_sigaltstack" = "yes"
 then
-  AC_DEFINE(STATFS_HAS_BFREE)
+    AC_DEFINE(HAVE_WORKING_SIGALTSTACK)
 fi
 
 
@@ -317,6 +440,7 @@
 programs/clock/Makefile
 programs/notepad/Makefile
 programs/progman/Makefile
+programs/regtest/Makefile
 programs/view/Makefile
 programs/winhelp/Makefile
 programs/winver/Makefile
diff --git a/controls/Makefile.in b/controls/Makefile.in
index 3a64a7b..736c00b 100644
--- a/controls/Makefile.in
+++ b/controls/Makefile.in
@@ -11,6 +11,7 @@
 	commctrl.c \
 	desktop.c \
 	edit.c \
+	header.c \
 	icontitle.c \
 	listbox.c \
 	menu.c \
diff --git a/controls/commctrl.c b/controls/commctrl.c
index a720660..245eb86 100644
--- a/controls/commctrl.c
+++ b/controls/commctrl.c
@@ -8,24 +8,11 @@
 #include "win.h"
 #include "heap.h"
 #include "commctrl.h"
+#include "header.h"
 #include "progress.h"
 #include "status.h"
 #include "updown.h"
-
-/* Win32 common controls */
-
-static WNDCLASS32A WIDGETS_CommonControls32[] =
-{
-    { CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW, StatusWindowProc, 0,
-      sizeof(STATUSWINDOWINFO), 0, 0, 0, 0, 0, STATUSCLASSNAME32A },
-    { CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW, UpDownWindowProc, 0,
-      sizeof(UPDOWN_INFO), 0, 0, 0, 0, 0, UPDOWN_CLASS32A },
-    { CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW, ProgressWindowProc, 0,
-      sizeof(PROGRESS_INFO), 0, 0, 0, 0, 0, PROGRESS_CLASS32A }
-};
-
-#define NB_COMMON_CONTROLS32 \
-         (sizeof(WIDGETS_CommonControls32)/sizeof(WIDGETS_CommonControls32[0]))
+#include "debug.h"
 
 
 /***********************************************************************
@@ -37,8 +24,6 @@
     RECT32 r = *lprc;
     UINT32 border = BDR_SUNKENOUTER;
 
-    DrawEdge32(hdc, &r, BDR_RAISEDINNER, BF_RECT|BF_ADJUST|BF_FLAT);
-
     if(style==SBT_POPOUT)
       border = BDR_RAISEDOUTER;
     else if(style==SBT_NOBORDERS)
@@ -59,7 +44,7 @@
 }
 
 /***********************************************************************
- *           DrawStatusText32W   (COMCTL32.24)
+ *           DrawStatusText32W   (COMCTL32.28)
  */
 void WINAPI DrawStatusText32W( HDC32 hdc, LPRECT32 lprc, LPCWSTR text,
                                UINT32 style )
@@ -70,7 +55,7 @@
 }
 
 /***********************************************************************
- *           DrawStatusText16   (COMCTL32.23)
+ *           DrawStatusText16   (COMCTL32.27)
  */
 void WINAPI DrawStatusText16( HDC16 hdc, LPRECT16 lprc, LPCSTR text,
 			      UINT16 style )
@@ -97,7 +82,7 @@
 }
 
 /***********************************************************************
- *           CreateStatusWindow16   (COMCTL32.18)
+ *           CreateStatusWindow16   (COMCTL32.21)
  */
 HWND16 WINAPI CreateStatusWindow16( INT16 style, LPCSTR text, HWND16 parent,
 				    UINT16 wid )
@@ -109,7 +94,7 @@
 }
 
 /***********************************************************************
- *           CreateStatusWindow32W   (COMCTL32.19)
+ *           CreateStatusWindow32W   (COMCTL32.22)
  */
 HWND32 WINAPI CreateStatusWindow32W( INT32 style, LPCWSTR text, HWND32 parent,
                                      UINT32 wid )
@@ -141,24 +126,165 @@
 
 
 /***********************************************************************
- *           InitCommonControls   (COMCTL32.17)
+ * InitCommonControls [COMCTL32.17]
+ *
+ *
+ *
  */
-void WINAPI InitCommonControls(void)
-{
-    int i;
-    char name[30];
-    const char *old_name;
-    WNDCLASS32A *class32 = WIDGETS_CommonControls32;
 
-    for (i = 0; i < NB_COMMON_CONTROLS32; i++, class32++)
-    {
-        /* Just to make sure the string is > 0x10000 */
-        old_name = class32->lpszClassName;
-        strcpy( name, (char *)class32->lpszClassName );
-        class32->lpszClassName = name;
-        class32->hCursor = LoadCursor32A( 0, IDC_ARROW32A );
-        RegisterClass32A( class32 );
-        class32->lpszClassName = old_name;	
-    }
+VOID WINAPI
+InitCommonControls (VOID)
+{
+    INITCOMMONCONTROLSEX icc;
+
+    icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
+    icc.dwICC = ICC_WIN95_CLASSES;
+
+    InitCommonControlsEx (&icc);
 }
 
+
+/***********************************************************************
+ * InitCommonControlsEx [COMCTL32.81]
+ *
+ *
+ *
+ */
+
+BOOL32 WINAPI
+InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
+{
+  INT32 cCount;
+  DWORD dwMask;
+
+  if (lpInitCtrls == NULL) return (FALSE);
+  if (lpInitCtrls->dwSize < sizeof(INITCOMMONCONTROLSEX)) return (FALSE);
+
+  for (cCount = 0; cCount <= 31; cCount++) {
+    dwMask = 1 << cCount;
+    if (!(lpInitCtrls->dwICC & dwMask))
+      continue;
+
+    switch (lpInitCtrls->dwICC & dwMask) {
+      case ICC_LISTVIEW_CLASSES:
+        TRACE (commctrl, "No listview class implemented!\n");
+        HEADER_Register();
+        break;
+
+      case ICC_TREEVIEW_CLASSES:
+        TRACE (commctrl, "No treeview class implemented!\n");
+        TRACE (commctrl, "No tooltip class implemented!\n");
+        break;
+
+      case ICC_BAR_CLASSES:
+        TRACE (commctrl, "No toolbar class implemented!\n");
+	STATUS_Register ();
+        TRACE (commctrl, "No trackbar class implemented!\n");
+        TRACE (commctrl, "No tooltip class implemented!\n");
+        break;
+
+      case ICC_TAB_CLASSES:
+        TRACE (commctrl, "No tab class implemented!\n");
+        TRACE (commctrl, "No tooltip class implemented!\n");
+        break;
+
+      case ICC_UPDOWN_CLASS:
+        UPDOWN_Register ();
+        break;
+
+      case ICC_PROGRESS_CLASS:
+        PROGRESS_Register ();
+        break;
+
+      case ICC_HOTKEY_CLASS:
+        TRACE (commctrl, "No hotkey class implemented!\n");
+        break;
+
+      case ICC_ANIMATE_CLASS:
+        TRACE (commctrl, "No animation class implemented!\n");
+        break;
+
+      case ICC_DATE_CLASSES:
+        TRACE (commctrl, "No month calendar class implemented!\n");
+        TRACE (commctrl, "No date picker class implemented!\n");
+        TRACE (commctrl, "No time picker class implemented!\n");
+        break;
+
+      case ICC_USEREX_CLASSES:
+        TRACE (commctrl, "No comboex class implemented!\n");
+        break;
+
+      case ICC_COOL_CLASSES:
+        TRACE (commctrl, "No rebar class implemented!\n");
+        break;
+
+      case ICC_INTERNET_CLASSES:
+        TRACE (commctrl, "No internet classes implemented!\n");
+        break;
+
+      case ICC_PAGESCROLLER_CLASS:
+        TRACE (commctrl, "No page scroller class implemented!\n");
+        break;
+
+      case ICC_NATIVEFNTCTL_CLASS:
+        TRACE (commctrl, "No native font class implemented!\n");
+        break;
+
+      default:
+        WARN (commctrl, "Unknown class! dwICC=0x%lX\n", dwMask);
+        break;
+    }
+  }
+
+  return (TRUE);
+}
+
+
+/***********************************************************************
+ * MenuHelp (COMCTL32.2)
+ *
+ *
+ *
+ *
+ */
+
+VOID WINAPI
+MenuHelp (UINT32 uMsg, WPARAM32 wParam, LPARAM lParam, HMENU32 hMainMenu,
+	  HINSTANCE32 hInst, HWND32 hwndStatus, LPUINT32 lpwIDs)
+{
+    char szStatusText[128];
+
+    if (!IsWindow32 (hwndStatus)) return;
+
+    switch (uMsg) {
+        case WM_MENUSELECT:
+            TRACE (commctrl, "WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
+                   wParam, lParam);
+
+            if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
+                /* menu was closed */
+                SendMessage32A (hwndStatus, SB_SIMPLE, FALSE, 0);
+            }
+            else {
+                if (HIWORD(wParam) & MF_POPUP) {
+                    TRACE (commctrl, "Popup menu selected!\n");
+                    FIXME (commctrl, "No popup menu texts!\n");
+
+                    szStatusText[0] = 0;
+                }
+                else {
+                    TRACE (commctrl, "Menu item selected!\n");
+                    if (!LoadString32A (hInst, LOWORD(wParam), szStatusText, 128))
+                        szStatusText[0] = 0;
+                }
+                SendMessage32A (hwndStatus, SB_SETTEXT32A, 255 | SBT_NOBORDERS,
+                                (LPARAM)szStatusText);
+                SendMessage32A (hwndStatus, SB_SIMPLE, TRUE, 0);
+            }
+            break;
+
+        default:
+            WARN (commctrl, "Invalid Message!\n");
+            break;
+    }
+}
diff --git a/controls/header.c b/controls/header.c
new file mode 100644
index 0000000..35a1357
--- /dev/null
+++ b/controls/header.c
@@ -0,0 +1,1278 @@
+/*
+ *  Header control
+ *
+ *  Copyright 1998 Eric Kohl
+ *
+ *  TODO:
+ *   - Bitmap support (partially).
+ *   - Imagelist support (partially).
+ *   - Hottrack support (partially).
+ *   - Control specific cursors (over dividers).
+ *   - Owner draw support.
+ *   - Order list support.
+ *   - Custom draw support (including Notifications).
+ *   - Drag and Drop support (including Notifications).
+ *   - Unicode support.
+ */
+
+#include "windows.h"
+#include "commctrl.h"
+#include "header.h"
+#include "heap.h"
+#include "win.h"
+#include "debug.h"
+
+
+#define __HDM_LAYOUT_HACK__
+
+
+#define VERT_BORDER     4
+#define DIVIDER_WIDTH  10
+
+#define UNKNOWN_PARAM(msg, wParam, lParam) WARN(header, \
+        "Unknown parameter(s) for message " #msg     \
+	"(%04x): wp=%04x lp=%08lx\n", msg, wParam, lParam); 
+
+#define HEADER_GetInfoPtr(wndPtr) ((HEADER_INFO *)wndPtr->wExtra[0])
+
+
+static INT32
+HEADER_DrawItem (WND *wndPtr, HDC32 hdc, HEADER_ITEM *phdi, BOOL32 bHotTrack)
+{
+    RECT32 r;
+    INT32  oldBkMode;
+
+    r = phdi->rect;
+    if (r.right - r.left == 0)
+	return phdi->rect.right;
+
+    if (wndPtr->dwStyle & HDS_BUTTONS) {
+	if (phdi->bDown) {
+	    DrawEdge32 (hdc, &r, BDR_RAISEDOUTER,
+			BF_RECT | BF_FLAT | BF_MIDDLE | BF_ADJUST);
+	    r.left += 2;
+            r.top  += 2;
+	}
+	else
+	    DrawEdge32 (hdc, &r, EDGE_RAISED,
+			BF_RECT | BF_SOFT | BF_MIDDLE | BF_ADJUST);
+    }
+    else
+        DrawEdge32 (hdc, &r, EDGE_ETCHED, BF_BOTTOM | BF_RIGHT | BF_ADJUST);
+
+    if (phdi->fmt & HDF_OWNERDRAW) {
+        /* FIXME: owner drawn items */
+    }
+    else {
+        UINT32 uTextJustify = DT_LEFT;
+
+        if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_CENTER)
+            uTextJustify = DT_CENTER;
+        else if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_RIGHT)
+            uTextJustify = DT_RIGHT;
+
+	if ((phdi->fmt & HDF_BITMAP) && (phdi->hbm)) {
+	    BITMAP32 bmp;
+	    HDC32    hdcBitmap;
+	    INT32    yD, yS, cx, cy, rx, ry;
+
+	    ry = r.bottom - r.top;
+	    rx = r.right - r.left;
+
+	    if (ry >= bmp.bmHeight) {
+		cy = bmp.bmHeight;
+		yD = r.top + (ry - bmp.bmHeight) / 2;
+		yS = 0;
+	    }
+	    else {
+		cy = ry;
+		yD = r.top;
+		yS = (bmp.bmHeight - ry) / 2;
+
+	    }
+
+	    if (rx >= bmp.bmWidth + 6) {
+		cx = bmp.bmWidth;
+	    }
+	    else {
+		cx = rx - 6;
+	    }
+
+	    GetObject32A (phdi->hbm, sizeof(BITMAP32), (LPVOID)&bmp);
+	    hdcBitmap = CreateCompatibleDC32 (hdc);
+	    SelectObject32 (hdcBitmap, phdi->hbm);
+	    BitBlt32 (hdc, r.left + 3, yD, cx, cy, hdcBitmap, 0, yS, SRCCOPY);
+	    DeleteDC32 (hdcBitmap);
+
+	    r.left += (bmp.bmWidth + 3);
+	}
+
+/*
+	if ((phdi->fmt & HDF_BITMAP_ON_RIGHT) && (phdi->hbm)) {
+	    BITMAP32 bmp;
+	    HDC32    hdcBitmap;
+
+	    GetObject32A (phdi->hbm, sizeof(BITMAP32), (LPVOID)&bmp);
+
+
+	}
+*/
+
+/*
+	if (phdi->fmt & HDF_IMAGE) {
+
+	    ImageList_Draw (....);
+
+	}
+*/
+
+        if ((phdi->fmt & HDF_STRING) && (phdi->pszText)) {
+            oldBkMode = SetBkMode32(hdc, TRANSPARENT);
+            r.left += 3;
+	    r.right -= 3;
+	    SetTextColor32 (hdc, bHotTrack ? COLOR_HIGHLIGHT : COLOR_BTNTEXT);
+            DrawText32A(hdc, phdi->pszText, lstrlen32A(phdi->pszText),
+	   	  &r, uTextJustify|DT_VCENTER|DT_SINGLELINE);
+            if (oldBkMode != TRANSPARENT)
+                SetBkMode32(hdc, oldBkMode);
+        }
+    }
+    return phdi->rect.right;
+}
+
+
+static void 
+HEADER_Refresh (WND *wndPtr, HDC32 hdc)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+    HFONT32 hFont, hOldFont;
+    RECT32 rect;
+    HBRUSH32 hbrBk;
+    INT32 i, x;
+
+    /* get rect for the bar, adjusted for the border */
+    GetClientRect32 (wndPtr->hwndSelf, &rect);
+
+    hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject32 (SYSTEM_FONT);
+    hOldFont = SelectObject32 (hdc, hFont);
+
+    /* draw Background */
+    hbrBk = GetSysColorBrush32(COLOR_3DFACE);
+    FillRect32(hdc, &rect, hbrBk);
+
+    x = rect.left;
+    for (i = 0; i < infoPtr->uNumItem; i++) {
+        x = HEADER_DrawItem (wndPtr, hdc, &infoPtr->items[i], FALSE);
+    }
+
+    if ((x <= rect.right) && (infoPtr->uNumItem > 0)) {
+        rect.left = x;
+        if (wndPtr->dwStyle & HDS_BUTTONS)
+            DrawEdge32 (hdc, &rect, EDGE_RAISED, BF_TOP|BF_LEFT|BF_BOTTOM|BF_SOFT);
+        else
+            DrawEdge32 (hdc, &rect, EDGE_ETCHED, BF_BOTTOM);
+    }
+
+    SelectObject32 (hdc, hOldFont);
+}
+
+
+static void
+HEADER_RefreshItem (WND *wndPtr, HDC32 hdc, HEADER_ITEM *phdi)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+    HFONT32 hFont, hOldFont;
+
+    hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject32 (SYSTEM_FONT);
+    hOldFont = SelectObject32 (hdc, hFont);
+    HEADER_DrawItem (wndPtr, hdc, phdi, FALSE);
+    SelectObject32 (hdc, hOldFont);
+}
+
+
+static void
+HEADER_SetItemBounds (WND *wndPtr)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+    HEADER_ITEM *phdi;
+    RECT32 rect;
+    int i, x;
+
+    if (infoPtr->uNumItem == 0)
+        return;
+
+    GetClientRect32 (wndPtr->hwndSelf, &rect);
+
+    x = rect.left;
+    for (i = 0; i < infoPtr->uNumItem; i++) {
+        phdi = &infoPtr->items[i];
+        phdi->rect.top = rect.top;
+        phdi->rect.bottom = rect.bottom;
+        phdi->rect.left = x;
+        phdi->rect.right = phdi->rect.left + phdi->cxy;
+        x = phdi->rect.right;
+    }
+}
+
+
+static void
+HEADER_ForceItemBounds (WND *wndPtr, INT32 cy)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+    HEADER_ITEM *phdi;
+    int i, x;
+
+    if (infoPtr->uNumItem == 0)
+	return;
+
+    x = 0;
+    for (i = 0; i < infoPtr->uNumItem; i++) {
+	phdi = &infoPtr->items[i];
+	phdi->rect.top = 0;
+	phdi->rect.bottom = cy;
+	phdi->rect.left = x;
+	phdi->rect.right = phdi->rect.left + phdi->cxy;
+	x = phdi->rect.right;
+    }
+}
+
+
+static void
+HEADER_InternalHitTest (WND *wndPtr, LPPOINT32 lpPt, UINT32 *pFlags, INT32 *pItem)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+    RECT32 rect, rcTest;
+    INT32  iCount, width;
+    BOOL32 bNoWidth;
+
+    GetClientRect32 (wndPtr->hwndSelf, &rect);
+
+    *pFlags = 0;
+    bNoWidth = FALSE;
+    if (PtInRect32 (&rect, *lpPt))
+    {
+	if (infoPtr->uNumItem == 0) {
+	    *pFlags |= HHT_NOWHERE;
+	    *pItem = 1;
+	    TRACE (header, "NOWHERE\n");
+	    return;
+	}
+	else {
+	    /* somewhere inside */
+	    for (iCount = 0; iCount < infoPtr->uNumItem; iCount++) {
+		rect = infoPtr->items[iCount].rect;
+		width = rect.right - rect.left;
+		if (width == 0) {
+		    bNoWidth = TRUE;
+		    continue;
+		}
+		if (PtInRect32 (&rect, *lpPt)) {
+		    if (width <= 2 * DIVIDER_WIDTH) {
+			*pFlags |= HHT_ONHEADER;
+			*pItem = iCount;
+			TRACE (header, "ON HEADER %d\n", iCount);
+			return;
+		    }
+		    if (iCount > 0) {
+			rcTest = rect;
+			rcTest.right = rcTest.left + DIVIDER_WIDTH;
+			if (PtInRect32 (&rcTest, *lpPt)) {
+			    if (bNoWidth) {
+				*pFlags |= HHT_ONDIVOPEN;
+				*pItem = iCount - 1;
+				TRACE (header, "ON DIVOPEN %d\n", *pItem);
+				return;
+			    }
+			    else {
+				*pFlags |= HHT_ONDIVIDER;
+				*pItem = iCount - 1;
+				TRACE (header, "ON DIVIDER %d\n", *pItem);
+				return;
+			    }
+			}
+		    }
+		    rcTest = rect;
+		    rcTest.left = rcTest.right - DIVIDER_WIDTH;
+		    if (PtInRect32 (&rcTest, *lpPt)) {
+			*pFlags |= HHT_ONDIVIDER;
+			*pItem = iCount;
+			TRACE (header, "ON DIVIDER %d\n", *pItem);
+			return;
+		    }
+
+		    *pFlags |= HHT_ONHEADER;
+		    *pItem = iCount;
+		    TRACE (header, "ON HEADER %d\n", iCount);
+		    return;
+		}
+	    }
+
+	    /* check for last divider part (on nowhere) */
+	    rect = infoPtr->items[infoPtr->uNumItem-1].rect;
+	    rect.left = rect.right;
+	    rect.right += DIVIDER_WIDTH;
+	    if (PtInRect32 (&rect, *lpPt)) {
+		if (bNoWidth) {
+		    *pFlags |= HHT_ONDIVOPEN;
+		    *pItem = infoPtr->uNumItem - 1;
+		    TRACE (header, "ON DIVOPEN %d\n", *pItem);
+		    return;
+		}
+		else {
+		    *pFlags |= HHT_ONDIVIDER;
+		    *pItem = infoPtr->uNumItem-1;
+		    TRACE (header, "ON DIVIDER %d\n", *pItem);
+		    return;
+		}
+	    }
+
+	    *pFlags |= HHT_NOWHERE;
+	    *pItem = 1;
+	    TRACE (header, "NOWHERE\n");
+	    return;
+	}
+    }
+    else {
+	if (lpPt->x < rect.left) {
+	   TRACE (header, "TO LEFT\n");
+	   *pFlags |= HHT_TOLEFT;
+	}
+	else if (lpPt->x > rect.right) {
+	    TRACE (header, "TO LEFT\n");
+	    *pFlags |= HHT_TORIGHT;
+	}
+
+	if (lpPt->y < rect.top) {
+	    TRACE (header, "ABOVE\n");
+	    *pFlags |= HHT_ABOVE;
+	}
+	else if (lpPt->y > rect.bottom) {
+	    TRACE (header, "BELOW\n");
+	    *pFlags |= HHT_BELOW;
+	}
+    }
+
+    *pItem = 1;
+    TRACE (header, "flags=0x%X\n", *pFlags);
+    return;
+}
+
+
+static void
+HEADER_DrawTrackLine (WND *wndPtr, HDC32 hdc, INT32 x)
+{
+    RECT32 rect;
+    HPEN32 hOldPen;
+    INT32  oldRop;
+
+    GetClientRect32 (wndPtr->hwndSelf, &rect);
+
+    hOldPen = SelectObject32 (hdc, GetStockObject32 (BLACK_PEN));
+    oldRop = SetROP232 (hdc, R2_XORPEN);
+    MoveToEx32 (hdc, x, rect.top, NULL);
+    LineTo32 (hdc, x, rect.bottom);
+    SetROP232 (hdc, oldRop);
+    SelectObject32 (hdc, hOldPen);
+}
+
+
+static BOOL32
+HEADER_SendSimpleNotify (WND *wndPtr, UINT32 code)
+{
+    NMHDR nmhdr;
+
+    nmhdr.hwndFrom = wndPtr->hwndSelf;
+    nmhdr.idFrom   = wndPtr->wIDmenu;
+    nmhdr.code     = code;
+
+    return (BOOL32)SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
+				   (WPARAM32)nmhdr.idFrom, (LPARAM)&nmhdr);
+}
+
+
+static BOOL32
+HEADER_SendHeaderNotify (WND *wndPtr, UINT32 code, INT32 iItem)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);   
+    NMHEADERA nmhdr;
+    HD_ITEMA  nmitem;
+
+    nmhdr.hdr.hwndFrom = wndPtr->hwndSelf;
+    nmhdr.hdr.idFrom = wndPtr->wIDmenu;
+    nmhdr.hdr.code = code;
+    nmhdr.iItem = iItem;
+    nmhdr.iButton = 0;
+    nmhdr.pitem = &nmitem;
+    nmitem.mask = infoPtr->items[iItem].mask;
+    nmitem.cxy = infoPtr->items[iItem].cxy;
+    nmitem.hbm = infoPtr->items[iItem].hbm;
+    nmitem.pszText = infoPtr->items[iItem].pszText;
+    nmitem.cchTextMax = infoPtr->items[iItem].cchTextMax;
+    nmitem.fmt = infoPtr->items[iItem].fmt;
+    nmitem.lParam = infoPtr->items[iItem].lParam;
+    nmitem.iOrder = infoPtr->items[iItem].iOrder;
+    nmitem.iImage = infoPtr->items[iItem].iImage;
+
+    return (BOOL32)SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
+				   (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmhdr);
+}
+
+
+static BOOL32
+HEADER_SendClickNotify (WND *wndPtr, UINT32 code, INT32 iItem)
+{
+    NMHEADERA nmhdr;
+
+    nmhdr.hdr.hwndFrom = wndPtr->hwndSelf;
+    nmhdr.hdr.idFrom = wndPtr->wIDmenu;
+    nmhdr.hdr.code = code;
+    nmhdr.iItem = iItem;
+    nmhdr.iButton = 0;
+    nmhdr.pitem = NULL;
+
+    return (BOOL32)SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
+				   (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmhdr);
+}
+
+
+static LRESULT
+HEADER_CreateDragImage (WND *wndPtr, WPARAM32 wParam)
+{
+    FIXME (header, "empty stub!\n");
+    return 0;
+}
+
+
+static LRESULT
+HEADER_DeleteItem (WND *wndPtr, WPARAM32 wParam)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+    HDC32 hdc;
+    INT32 iItem;
+
+    iItem = (INT32)wParam;
+
+    TRACE(header, "[iItem=%d]\n", iItem);
+    
+    if ((iItem < 0) || (iItem > infoPtr->uNumItem - 1))
+        return FALSE;
+
+    if (infoPtr->uNumItem == 1) {
+        TRACE(header, "Simple delete!\n");
+        if (infoPtr->items[0].pszText)
+            HeapFree (SystemHeap, 0, infoPtr->items[0].pszText);
+        HeapFree (SystemHeap, 0, infoPtr->items);
+        infoPtr->items = 0;
+        infoPtr->uNumItem = 0;
+    }
+    else {
+        HEADER_ITEM *oldItems = infoPtr->items;
+        TRACE(header, "Complex delete! [iItem=%d]\n", iItem);
+
+        if (infoPtr->items[iItem].pszText)
+            HeapFree (SystemHeap, 0, infoPtr->items[iItem].pszText);
+
+        infoPtr->uNumItem--;
+        infoPtr->items = HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
+                                    sizeof (HEADER_ITEM) * infoPtr->uNumItem);
+        /* pre delete copy */
+        if (iItem > 0) {
+            memcpy (&infoPtr->items[0], &oldItems[0],
+                    iItem * sizeof(HEADER_ITEM));
+        }
+
+        /* post delete copy */
+        if (iItem < infoPtr->uNumItem) {
+            memcpy (&infoPtr->items[iItem], &oldItems[iItem+1],
+                    (infoPtr->uNumItem - iItem) * sizeof(HEADER_ITEM));
+        }
+
+        HeapFree (SystemHeap, 0, oldItems);
+    }
+
+    HEADER_SetItemBounds (wndPtr);
+
+    hdc = GetDC32 (wndPtr->hwndSelf);
+    HEADER_Refresh (wndPtr, hdc);
+    ReleaseDC32 (wndPtr->hwndSelf, hdc);
+    
+    return TRUE;
+}
+
+
+static LRESULT
+HEADER_GetImageList (WND *wndPtr)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+
+    return (LRESULT)infoPtr->himl;
+}
+
+
+static LRESULT
+HEADER_GetItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+    HD_ITEMA *phdi;
+    INT32    iItem;
+    UINT32   uMask;
+
+    phdi = (HD_ITEMA*)lParam;
+    iItem = (INT32)wParam;
+
+    if ((iItem < 0) || (iItem > infoPtr->uNumItem - 1))
+        return FALSE;
+
+    TRACE (header, "[iItem=%d]\n", iItem);
+
+    uMask = phdi->mask;
+    if (uMask == 0)
+	return TRUE;
+    phdi->mask = 0;
+
+    if (uMask & infoPtr->items[iItem].mask & HDI_BITMAP) {
+	phdi->hbm = infoPtr->items[iItem].hbm;
+        phdi->mask |= HDI_BITMAP;
+    }
+
+    if (uMask & infoPtr->items[iItem].mask & HDI_FORMAT) {
+	phdi->fmt = infoPtr->items[iItem].fmt;
+        phdi->mask |= HDI_FORMAT;
+    }
+
+    if (uMask & infoPtr->items[iItem].mask & HDI_WIDTH) {
+	phdi->cxy = infoPtr->items[iItem].cxy;
+        phdi->mask |= HDI_WIDTH;
+    }
+
+    if (uMask & infoPtr->items[iItem].mask & HDI_LPARAM) {
+	phdi->lParam = infoPtr->items[iItem].lParam;
+        phdi->mask |= HDI_LPARAM;
+    }
+
+    if (uMask & infoPtr->items[iItem].mask & HDI_TEXT) {
+	phdi->pszText = infoPtr->items[iItem].pszText;
+	phdi->cchTextMax = infoPtr->items[iItem].cchTextMax;
+        phdi->mask |= HDI_TEXT;
+    }
+
+    if (uMask & infoPtr->items[iItem].mask & HDI_IMAGE) {
+	phdi->iImage = infoPtr->items[iItem].iImage;
+        phdi->mask |= HDI_IMAGE;
+    }
+
+    if (uMask & infoPtr->items[iItem].mask & HDI_ORDER) {
+	phdi->iOrder = infoPtr->items[iItem].iOrder;
+        phdi->mask |= HDI_ORDER;
+    }
+
+    return TRUE;
+}
+
+
+static LRESULT
+HEADER_GetItemCount (WND *wndPtr)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+
+    return (infoPtr->uNumItem);
+}
+
+
+static LRESULT
+HEADER_GetItemRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+    INT32 iItem;
+    LPRECT32 lpRect;
+
+    iItem = (INT32)wParam;
+    lpRect = (LPRECT32)lParam;
+
+    if ((iItem < 0) || (iItem > infoPtr->uNumItem - 1))
+        return FALSE;
+
+    lpRect->left   = infoPtr->items[iItem].rect.left;
+    lpRect->right  = infoPtr->items[iItem].rect.right;
+    lpRect->top    = infoPtr->items[iItem].rect.top;
+    lpRect->bottom = infoPtr->items[iItem].rect.bottom;
+
+    return TRUE;
+}
+
+
+static LRESULT
+HEADER_HitTest (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LPHDHITTESTINFO phti = (LPHDHITTESTINFO)lParam;
+
+    HEADER_InternalHitTest (wndPtr, &phti->pt, &phti->flags, &phti->iItem);
+
+    return phti->flags;
+}
+
+
+static LRESULT
+HEADER_InsertItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+    HD_ITEMA *phdi;
+    HDC32    hdc;
+    INT32    iItem, len;
+
+    phdi = (HD_ITEMA*)lParam;
+    iItem = (INT32)wParam;
+    
+    if (iItem < 0) return -1;
+    if (iItem > infoPtr->uNumItem)
+        iItem = infoPtr->uNumItem;
+
+    if (infoPtr->uNumItem == 0) {
+        infoPtr->items = HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
+                                    sizeof (HEADER_ITEM));
+        infoPtr->uNumItem++;
+    }
+    else {
+        HEADER_ITEM *oldItems = infoPtr->items;
+
+        infoPtr->uNumItem++;
+        infoPtr->items = HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
+                                    sizeof (HEADER_ITEM) * infoPtr->uNumItem);
+        /* pre insert copy */
+        if (iItem > 0) {
+            memcpy (&infoPtr->items[0], &oldItems[0],
+                    iItem * sizeof(HEADER_ITEM));
+        }
+
+        /* post insert copy */
+        if (iItem < infoPtr->uNumItem - 1) {
+            memcpy (&infoPtr->items[iItem+1], &oldItems[iItem],
+                    (infoPtr->uNumItem - iItem) * sizeof(HEADER_ITEM));
+        }
+
+        HeapFree (SystemHeap, 0, oldItems);
+    }
+
+    infoPtr->items[iItem].bDown = FALSE;
+
+    infoPtr->items[iItem].mask = phdi->mask;
+    if (phdi->mask & HDI_WIDTH)
+        infoPtr->items[iItem].cxy = phdi->cxy;
+
+    if (phdi->mask & HDI_TEXT) {
+        len = lstrlen32A (phdi->pszText);
+        infoPtr->items[iItem].pszText =
+            HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY, len+1);
+        lstrcpy32A (infoPtr->items[iItem].pszText, phdi->pszText);
+        infoPtr->items[iItem].cchTextMax = phdi->cchTextMax;
+    }
+
+    if (phdi->mask & HDI_FORMAT)
+        infoPtr->items[iItem].fmt = phdi->fmt;
+
+    if (phdi->mask & HDI_BITMAP)
+        infoPtr->items[iItem].hbm = phdi->hbm;
+
+    if (phdi->mask & HDI_LPARAM)
+        infoPtr->items[iItem].lParam = phdi->lParam;
+
+    if (phdi->mask & HDI_IMAGE)
+        infoPtr->items[iItem].iImage = phdi->iImage;
+
+    if (phdi->mask & HDI_ORDER)
+        infoPtr->items[iItem].iOrder = phdi->iOrder;
+
+    HEADER_SetItemBounds (wndPtr);
+
+    hdc = GetDC32 (wndPtr->hwndSelf);
+    HEADER_Refresh (wndPtr, hdc);
+    ReleaseDC32 (wndPtr->hwndSelf, hdc);
+
+    return iItem;
+}
+
+
+static LRESULT
+HEADER_Layout (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+    LPHDLAYOUT lpLayout = (LPHDLAYOUT)lParam;
+
+    lpLayout->pwpos->hwnd = wndPtr->hwndSelf;
+    lpLayout->pwpos->hwndInsertAfter = 0;
+    lpLayout->pwpos->x = lpLayout->prc->left;
+    lpLayout->pwpos->y = lpLayout->prc->top;
+    lpLayout->pwpos->cx = lpLayout->prc->right - lpLayout->prc->left;
+    if (wndPtr->dwStyle & HDS_HIDDEN)
+        lpLayout->pwpos->cy = 0;
+    else
+        lpLayout->pwpos->cy = infoPtr->nHeight;
+    lpLayout->pwpos->flags = SWP_NOACTIVATE|SWP_NOZORDER;
+
+    TRACE (header, "Layout x=%d y=%d cx=%d cy=%d\n",
+           lpLayout->pwpos->x, lpLayout->pwpos->y,
+           lpLayout->pwpos->cx, lpLayout->pwpos->cy);
+
+    HEADER_ForceItemBounds (wndPtr, lpLayout->pwpos->cy);
+
+    /* hack */
+#ifdef __HDM_LAYOUT_HACK__
+    MoveWindow32 (lpLayout->pwpos->hwnd, lpLayout->pwpos->x, lpLayout->pwpos->y,
+                  lpLayout->pwpos->cx, lpLayout->pwpos->cy, TRUE);
+#endif
+
+    return TRUE;
+}
+
+
+static LRESULT
+HEADER_SetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+    HIMAGELIST himlOld;
+
+    himlOld = infoPtr->himl;
+    infoPtr->himl = (HIMAGELIST)lParam;
+
+    /* FIXME: Refresh needed??? */
+
+    return (LRESULT)himlOld;
+}
+
+
+static LRESULT
+HEADER_SetItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+    HD_ITEMA *phdi;
+    INT32    iItem;
+    HDC32    hdc;
+
+    phdi = (HD_ITEMA*)lParam;
+    iItem = (INT32)wParam;
+
+    if ((iItem < 0) || (iItem > infoPtr->uNumItem - 1))
+        return FALSE;
+
+    TRACE (header, "[iItem=%d]\n", iItem);
+
+    if (HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGING32A, iItem))
+	return FALSE;
+
+    if (phdi->mask & HDI_BITMAP) {
+	infoPtr->items[iItem].hbm = phdi->hbm;
+	infoPtr->items[iItem].mask  |= HDI_BITMAP;
+    }
+
+    if (phdi->mask & HDI_FORMAT) {
+	infoPtr->items[iItem].fmt = phdi->fmt;
+	infoPtr->items[iItem].mask  |= HDI_FORMAT;
+    }
+
+    if (phdi->mask & HDI_LPARAM) {
+	infoPtr->items[iItem].lParam = phdi->lParam;
+	infoPtr->items[iItem].mask  |= HDI_LPARAM;
+    }
+
+    if (phdi->mask & HDI_TEXT) {
+        INT32 len = lstrlen32A (phdi->pszText);
+        if (infoPtr->items[iItem].pszText)
+	    HeapFree (SystemHeap, 0, infoPtr->items[iItem].pszText);
+        infoPtr->items[iItem].pszText =
+            HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY, len+1);
+        lstrcpy32A (infoPtr->items[iItem].pszText, phdi->pszText);
+        infoPtr->items[iItem].cchTextMax = phdi->cchTextMax;
+    }
+
+    if (phdi->mask & HDI_WIDTH) {
+	infoPtr->items[iItem].cxy = phdi->cxy;
+	infoPtr->items[iItem].mask  |= HDI_WIDTH;
+    }
+
+    if (phdi->mask & HDI_IMAGE) {
+	infoPtr->items[iItem].iImage = phdi->iImage;
+	infoPtr->items[iItem].mask  |= HDI_IMAGE;
+    }
+
+    if (phdi->mask & HDI_ORDER) {
+	infoPtr->items[iItem].iOrder = phdi->iOrder;
+	infoPtr->items[iItem].mask  |= HDI_ORDER;
+    }
+
+    HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGED32A, iItem);
+
+    HEADER_SetItemBounds (wndPtr);
+    hdc = GetDC32 (wndPtr->hwndSelf);
+    HEADER_Refresh (wndPtr, hdc);
+    ReleaseDC32 (wndPtr->hwndSelf, hdc);
+
+    return TRUE;
+}
+
+
+static LRESULT
+HEADER_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    HEADER_INFO *infoPtr;
+    TEXTMETRIC32A tm;
+    HFONT32 hOldFont;
+    HDC32   hdc;
+
+    infoPtr = (HEADER_INFO *)HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY,
+                                        sizeof(HEADER_INFO));
+    wndPtr->wExtra[0] = (DWORD)infoPtr;
+
+    infoPtr->uNumItem = 0;
+    infoPtr->nHeight = 20;
+    infoPtr->hFont = 0;
+    infoPtr->items = 0;
+    infoPtr->hcurArrow = LoadCursor32A (0, IDC_ARROW32A);
+    infoPtr->hcurDivider = LoadCursor32A (0, IDC_SIZEWE32A);
+    infoPtr->hcurDivopen = LoadCursor32A (0, IDC_SIZENS32A);
+    infoPtr->bPressed  = FALSE;
+    infoPtr->bTracking = FALSE;
+    infoPtr->iMoveItem = 0;
+    infoPtr->himl = 0;
+    infoPtr->iHotItem = -1;
+
+    hdc = GetDC32 (0);
+    hOldFont = SelectObject32 (hdc, GetStockObject32 (SYSTEM_FONT));
+    GetTextMetrics32A (hdc, &tm);
+    infoPtr->nHeight = tm.tmHeight + VERT_BORDER;
+    SelectObject32 (hdc, hOldFont);
+    ReleaseDC32 (0, hdc);
+
+    return 0;
+}
+
+
+static LRESULT
+HEADER_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+    INT32 iItem;
+
+    if (infoPtr->items) {
+        for (iItem = 0; iItem < infoPtr->uNumItem; iItem++) {
+            if (infoPtr->items[iItem].pszText)
+                HeapFree (SystemHeap, 0, infoPtr->items[iItem].pszText);
+        }
+        HeapFree (SystemHeap, 0, infoPtr->items);
+    }
+
+    if (infoPtr->himl)
+	ImageList_Destroy (infoPtr->himl);
+
+    HeapFree (SystemHeap, 0, infoPtr);
+
+    return 0;
+}
+
+
+static LRESULT
+HEADER_GetFont (WND *wndPtr)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+
+    return (LRESULT)infoPtr->hFont;
+}
+
+
+static LRESULT
+HEADER_LButtonDblClk (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    POINT32 pt;
+    UINT32  flags;
+    INT32   iItem;
+
+    pt.x = (INT32)LOWORD(lParam); 
+    pt.y = (INT32)HIWORD(lParam);
+    HEADER_InternalHitTest (wndPtr, &pt, &flags, &iItem);
+
+    if ((wndPtr->dwStyle & HDS_BUTTONS) && (flags == HHT_ONHEADER))
+	HEADER_SendHeaderNotify (wndPtr, HDN_ITEMDBLCLICK32A, iItem);
+    else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN))
+	HEADER_SendHeaderNotify (wndPtr, HDN_DIVIDERDBLCLICK32A, iItem);
+
+    return 0;
+}
+
+
+static LRESULT
+HEADER_LButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+    POINT32 pt;
+    UINT32  flags;
+    INT32   iItem;
+    HDC32   hdc;
+
+    pt.x = (INT32)LOWORD(lParam); 
+    pt.y = (INT32)HIWORD(lParam);
+    HEADER_InternalHitTest (wndPtr, &pt, &flags, &iItem);
+
+    if ((wndPtr->dwStyle & HDS_BUTTONS) && (flags == HHT_ONHEADER)) {
+	SetCapture32 (wndPtr->hwndSelf);
+	infoPtr->bCaptured = TRUE;   
+	infoPtr->bPressed  = TRUE;
+	infoPtr->iMoveItem = iItem;
+
+	infoPtr->items[iItem].bDown = TRUE;
+
+	/* Send WM_CUSTOMDRAW */
+	hdc = GetDC32 (wndPtr->hwndSelf);
+	HEADER_RefreshItem (wndPtr, hdc, &infoPtr->items[iItem]);
+	ReleaseDC32 (wndPtr->hwndSelf, hdc);
+
+	TRACE (header, "Pressed item %d!\n", iItem);
+    } 
+    else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN)) {
+	if (!(HEADER_SendHeaderNotify (wndPtr, HDN_BEGINTRACK32A, iItem))) {
+	    SetCapture32 (wndPtr->hwndSelf);
+	    infoPtr->bCaptured = TRUE;   
+	    infoPtr->bTracking = TRUE;
+	    infoPtr->iMoveItem = iItem;
+	    infoPtr->nOldWidth = infoPtr->items[iItem].cxy;
+	    infoPtr->xTrackOffset = infoPtr->items[iItem].rect.right - pt.x;
+
+	    if (!(wndPtr->dwStyle & HDS_FULLDRAG)) {
+		infoPtr->xOldTrack = infoPtr->items[iItem].rect.right;
+		hdc = GetDC32 (wndPtr->hwndSelf);
+		HEADER_DrawTrackLine (wndPtr, hdc, infoPtr->xOldTrack);
+		ReleaseDC32 (wndPtr->hwndSelf, hdc);
+	    }
+
+	    TRACE (header, "Begin tracking item %d!\n", iItem);
+	}
+    }
+
+
+
+    return 0;
+}
+
+
+static LRESULT
+HEADER_LButtonUp (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+    POINT32 pt;
+    UINT32  flags;
+    INT32   iItem, nWidth;
+    HDC32   hdc;
+
+    pt.x = (INT32)LOWORD(lParam);
+    pt.y = (INT32)HIWORD(lParam);
+    HEADER_InternalHitTest (wndPtr, &pt, &flags, &iItem);
+
+    if (infoPtr->bPressed) {
+	if ((iItem == infoPtr->iMoveItem) && (flags == HHT_ONHEADER)) {
+	    infoPtr->items[infoPtr->iMoveItem].bDown = FALSE;
+	    hdc = GetDC32 (wndPtr->hwndSelf);
+	    HEADER_RefreshItem (wndPtr, hdc, &infoPtr->items[infoPtr->iMoveItem]);
+	    ReleaseDC32 (wndPtr->hwndSelf, hdc);
+
+	    HEADER_SendClickNotify (wndPtr, HDN_ITEMCLICK32A, infoPtr->iMoveItem);
+	}
+	TRACE (header, "Released item %d!\n", infoPtr->iMoveItem);
+	infoPtr->bPressed = FALSE;
+    }
+    else if (infoPtr->bTracking) {
+	TRACE (header, "End tracking item %d!\n", infoPtr->iMoveItem);
+	infoPtr->bTracking = FALSE;
+
+	HEADER_SendHeaderNotify (wndPtr, HDN_ENDTRACK32A, infoPtr->iMoveItem);
+
+	if (!(wndPtr->dwStyle & HDS_FULLDRAG)) {
+	    hdc = GetDC32 (wndPtr->hwndSelf);
+	    HEADER_DrawTrackLine (wndPtr, hdc, infoPtr->xOldTrack);
+	    ReleaseDC32 (wndPtr->hwndSelf, hdc);
+	    if (HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGING32A, infoPtr->iMoveItem))
+		infoPtr->items[infoPtr->iMoveItem].cxy = infoPtr->nOldWidth;
+	    else {
+		nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left +
+		infoPtr->xTrackOffset;
+		if (nWidth < 0)
+		    nWidth = 0;
+		infoPtr->items[infoPtr->iMoveItem].cxy = nWidth;
+		HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGED32A, infoPtr->iMoveItem);
+	    }
+
+	    HEADER_SetItemBounds (wndPtr);
+	    hdc = GetDC32 (wndPtr->hwndSelf);
+	    HEADER_Refresh (wndPtr, hdc);
+	    ReleaseDC32 (wndPtr->hwndSelf, hdc);
+	}
+    }
+
+    if (infoPtr->bCaptured) {
+	infoPtr->bCaptured = FALSE;
+	ReleaseCapture ();
+	HEADER_SendSimpleNotify (wndPtr, NM_RELEASEDCAPTURE);
+    }
+
+    return 0;
+}
+
+
+static LRESULT
+HEADER_MouseMove (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+    POINT32 pt;
+    UINT32  flags;
+    INT32   iItem, nWidth;
+    HDC32   hdc;
+
+    pt.x = (INT32)LOWORD(lParam);
+    pt.y = (INT32)HIWORD(lParam);
+    HEADER_InternalHitTest (wndPtr, &pt, &flags, &iItem);
+
+    if ((wndPtr->dwStyle & HDS_BUTTONS) && (wndPtr->dwStyle & HDS_HOTTRACK)) {
+	if (flags & (HHT_ONHEADER | HHT_ONDIVIDER | HHT_ONDIVOPEN))
+	    infoPtr->iHotItem = iItem;
+	else
+	    infoPtr->iHotItem = -1;
+	hdc = GetDC32 (wndPtr->hwndSelf);
+	HEADER_Refresh (wndPtr, hdc);
+	ReleaseDC32 (wndPtr->hwndSelf, hdc);
+    }
+
+    if (infoPtr->bCaptured) {
+	if (infoPtr->bPressed) {
+	    if ((iItem == infoPtr->iMoveItem) && (flags == HHT_ONHEADER))
+		infoPtr->items[infoPtr->iMoveItem].bDown = TRUE;
+	    else
+		infoPtr->items[infoPtr->iMoveItem].bDown = FALSE;
+	    hdc = GetDC32 (wndPtr->hwndSelf);
+	    HEADER_RefreshItem (wndPtr, hdc, &infoPtr->items[infoPtr->iMoveItem]);
+	    ReleaseDC32 (wndPtr->hwndSelf, hdc);
+
+	    TRACE (header, "Moving pressed item %d!\n", infoPtr->iMoveItem);
+	}
+	else if (infoPtr->bTracking) {
+	    if (wndPtr->dwStyle & HDS_FULLDRAG) {
+		if (HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGING32A, infoPtr->iMoveItem))
+		    infoPtr->items[infoPtr->iMoveItem].cxy = infoPtr->nOldWidth;
+		else {
+		    nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left +
+		    infoPtr->xTrackOffset;
+		    if (nWidth < 0)
+			nWidth = 0;
+		    infoPtr->items[infoPtr->iMoveItem].cxy = nWidth;
+		    HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGED32A,
+					     infoPtr->iMoveItem);
+		}
+		HEADER_SetItemBounds (wndPtr);
+		hdc = GetDC32 (wndPtr->hwndSelf);
+		HEADER_Refresh (wndPtr, hdc);
+		ReleaseDC32 (wndPtr->hwndSelf, hdc);
+	    }
+	    else {
+		hdc = GetDC32 (wndPtr->hwndSelf);
+		HEADER_DrawTrackLine (wndPtr, hdc, infoPtr->xOldTrack);
+		infoPtr->xOldTrack = pt.x + infoPtr->xTrackOffset;
+		if (infoPtr->xOldTrack < infoPtr->items[infoPtr->iMoveItem].rect.left)
+		    infoPtr->xOldTrack = infoPtr->items[infoPtr->iMoveItem].rect.left;
+		infoPtr->items[infoPtr->iMoveItem].cxy = 
+		    infoPtr->xOldTrack - infoPtr->items[infoPtr->iMoveItem].rect.left;
+		HEADER_DrawTrackLine (wndPtr, hdc, infoPtr->xOldTrack);
+		ReleaseDC32 (wndPtr->hwndSelf, hdc);
+	    }
+
+	    HEADER_SendHeaderNotify (wndPtr, HDN_TRACK32A, infoPtr->iMoveItem);
+	    TRACE (header, "Tracking item %d!\n", infoPtr->iMoveItem);
+	}
+    }
+
+    if ((wndPtr->dwStyle & HDS_BUTTONS) && (wndPtr->dwStyle & HDS_HOTTRACK)) {
+
+    }
+
+    return 0;
+}
+
+
+static LRESULT
+HEADER_Paint (WND *wndPtr, WPARAM32 wParam)
+{
+    HDC32 hdc;
+    PAINTSTRUCT32 ps;
+
+    hdc = wParam==0 ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam;
+    HEADER_Refresh (wndPtr, hdc);
+    if(!wParam)
+	EndPaint32 (wndPtr->hwndSelf, &ps);
+    return 0;
+}
+
+
+static LRESULT
+HEADER_RButtonUp (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    return HEADER_SendSimpleNotify (wndPtr, NM_RCLICK);
+}
+
+
+static LRESULT
+HEADER_SetCursor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+    POINT32 pt;
+    UINT32  flags;
+    INT32   iItem;
+
+    TRACE (header, "code=0x%X  id=0x%X\n", LOWORD(lParam), HIWORD(lParam));
+
+    GetCursorPos32 (&pt);
+    ScreenToClient32 (wndPtr->hwndSelf, &pt);
+
+    HEADER_InternalHitTest (wndPtr, &pt, &flags, &iItem);
+
+    if (flags == HHT_ONDIVIDER)
+        SetCursor32 (infoPtr->hcurDivider);
+    else if (flags == HHT_ONDIVOPEN)
+        SetCursor32 (infoPtr->hcurDivopen);
+    else
+        SetCursor32 (infoPtr->hcurArrow);
+
+    return 0;
+}
+
+
+static LRESULT
+HEADER_SetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+    TEXTMETRIC32A tm;
+    HFONT32 hFont, hOldFont;
+    HDC32 hdc;
+
+    infoPtr->hFont = (HFONT32)wParam;
+
+    hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject32 (SYSTEM_FONT);
+
+    hdc = GetDC32 (0);
+    hOldFont = SelectObject32 (hdc, hFont);
+    GetTextMetrics32A (hdc, &tm);
+    infoPtr->nHeight = tm.tmHeight + VERT_BORDER;
+    SelectObject32 (hdc, hOldFont);
+    ReleaseDC32 (0, hdc);
+
+    if (lParam) {
+        HEADER_ForceItemBounds (wndPtr, infoPtr->nHeight);
+        hdc = GetDC32 (wndPtr->hwndSelf);
+        HEADER_Refresh (wndPtr, hdc);
+        ReleaseDC32 (wndPtr->hwndSelf, hdc);
+    }
+
+    return 0;
+}
+
+
+LRESULT WINAPI
+HeaderWindowProc (HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+
+    switch (msg) {
+	case HDM_CREATEDRAGIMAGE:
+	    return HEADER_CreateDragImage (wndPtr, wParam);
+
+	case HDM_DELETEITEM:
+	    return HEADER_DeleteItem (wndPtr, wParam);
+
+	case HDM_GETIMAGELIST:
+	    return HEADER_GetImageList (wndPtr);
+
+	case HDM_GETITEM32A:
+	    return HEADER_GetItem32A (wndPtr, wParam, lParam);
+
+	case HDM_GETITEMCOUNT:
+	    return HEADER_GetItemCount (wndPtr);
+
+	case HDM_GETITEMRECT:
+	    return HEADER_GetItemRect (wndPtr, wParam, lParam);
+
+	case HDM_HITTEST:
+	    return HEADER_HitTest (wndPtr, wParam, lParam);
+
+	case HDM_INSERTITEM32A:
+	    return HEADER_InsertItem32A (wndPtr, wParam, lParam);
+
+	case HDM_LAYOUT:
+	    return HEADER_Layout (wndPtr, wParam, lParam);
+
+	case HDM_SETIMAGELIST:
+	    return HEADER_SetImageList (wndPtr, wParam, lParam);
+
+	case HDM_SETITEM32A:
+	    return HEADER_SetItem32A (wndPtr, wParam, lParam);
+
+
+        case WM_CREATE:
+            return HEADER_Create (wndPtr, wParam, lParam);
+
+        case WM_DESTROY:
+            return HEADER_Destroy (wndPtr, wParam, lParam);
+
+        case WM_ERASEBKGND:
+            return 1;
+
+        case WM_GETDLGCODE:
+            return DLGC_WANTTAB | DLGC_WANTARROWS;
+
+        case WM_GETFONT:
+            return HEADER_GetFont (wndPtr);
+
+        case WM_LBUTTONDBLCLK:
+            return HEADER_LButtonDblClk (wndPtr, wParam, lParam);
+
+        case WM_LBUTTONDOWN:
+            return HEADER_LButtonDown (wndPtr, wParam, lParam);
+
+        case WM_LBUTTONUP:
+            return HEADER_LButtonUp (wndPtr, wParam, lParam);
+
+        case WM_MOUSEMOVE:
+            return HEADER_MouseMove (wndPtr, wParam, lParam);
+
+        case WM_PAINT:
+            return HEADER_Paint (wndPtr, wParam);
+
+        case WM_RBUTTONUP:
+            return HEADER_RButtonUp (wndPtr, wParam, lParam);
+
+        case WM_SETCURSOR:
+            return HEADER_SetCursor (wndPtr, wParam, lParam);
+
+        case WM_SETFONT:
+            return HEADER_SetFont (wndPtr, wParam, lParam);
+
+        default:
+            if (msg >= WM_USER) 
+		ERR (header, "unknown msg %04x wp=%04x lp=%08lx\n",
+		     msg, wParam, lParam );
+	    return DefWindowProc32A (hwnd, msg, wParam, lParam);
+    }
+    return 0;
+}
+
+
+void HEADER_Register( void )
+{
+    WNDCLASS32A wndClass;
+
+    if (GlobalFindAtom32A (WC_HEADER32A)) return;
+
+    ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
+    wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS;
+    wndClass.lpfnWndProc   = (WNDPROC32)HeaderWindowProc;
+    wndClass.cbClsExtra    = 0;
+    wndClass.cbWndExtra    = sizeof(HEADER_INFO *);
+    wndClass.hCursor       = LoadCursor32A (0, IDC_ARROW32A);
+    wndClass.lpszClassName = WC_HEADER32A;
+ 
+    RegisterClass32A (&wndClass);
+}
+
diff --git a/controls/listbox.c b/controls/listbox.c
index 58b650e..e6301a7 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -171,6 +171,15 @@
 {
     SCROLLINFO info;
 
+    if (!(descr->style & WS_VSCROLL)) return; 
+    /*   It is important that we check descr->style, and not wnd->dwStyle, 
+       for WS_VSCROLL, as the former is exactly the one passed in 
+       argument to CreateWindow.  
+         In Windows (and from now on in Wine :) a listbox created 
+       with such a style (no WS_SCROLL) does not update 
+       the scrollbar with listbox-related data, thus letting 
+       the programmer use it for his/her own purposes. */
+
     if (descr->style & LBS_NOREDRAW) return;
     info.cbSize = sizeof(info);
 
@@ -1089,8 +1098,8 @@
     if (oldFont) SelectObject32( hdc, oldFont );
     ReleaseDC32( wnd->hwndSelf, hdc );
     if (!IS_OWNERDRAW(descr))
-        LISTBOX_SetItemHeight( wnd, descr, 0, tm.tmHeight + 2 );
-    return tm.tmHeight + 2;
+        LISTBOX_SetItemHeight( wnd, descr, 0, tm.tmHeight );
+    return tm.tmHeight ;
 }
 
 
diff --git a/controls/menu.c b/controls/menu.c
index 3cfe51f..78aaf0a 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -855,10 +855,10 @@
         dis.hDC        = hdc;
         dis.rcItem     = lpitem->rect;
         TRACE(menu, "Ownerdraw: itemID=%d, itemState=%d, itemAction=%d, "
-	      "hwndItem=%04x, hdc=%04x, rcItem={%d,%d,%d,%d}, rcItem=%p\n",dis.itemID,
+	      "hwndItem=%04x, hdc=%04x, rcItem={%d,%d,%d,%d}\n",dis.itemID,
 	      dis.itemState, dis.itemAction, dis.hwndItem, dis.hDC,
 	      dis.rcItem.left, dis.rcItem.top, dis.rcItem.right,
-	      dis.rcItem.bottom, dis.rcItem );
+	      dis.rcItem.bottom );
         SendMessage32A( GetWindow32(hwnd,GW_OWNER), WM_DRAWITEM, 0, (LPARAM)&dis );
         return;
     }
@@ -2799,7 +2799,7 @@
 
     while( (item = MENU_FindItem( &hMenu, &wItemID, wFlags )) )
     {
-      if( !(item->fType & MF_POPUP) )
+      if( (wFlags & MF_BYPOSITION) || !(item->fType & MF_POPUP) )
       {
            /* We can't have MF_GRAYED and MF_DISABLED together */
            if (wFlags & MF_GRAYED)
diff --git a/controls/progress.c b/controls/progress.c
index 80a2fc4..7937d2b 100644
--- a/controls/progress.c
+++ b/controls/progress.c
@@ -7,16 +7,14 @@
  *   - I do not know what to to on WM_[SG]ET_FONT
  */
 
-#include <stdlib.h>
-#include <stdio.h>
 #include "windows.h"
-#include "sysmetrics.h"
 #include "progress.h"
-#include "graphics.h"
+#include "commctrl.h"
 #include "heap.h"
 #include "win.h"
 #include "debug.h"
 
+
 /* Control configuration constants */
 
 #define LED_GAP    2
@@ -27,7 +25,7 @@
         "Unknown parameter(s) for message " #msg     \
 	"(%04x): wp=%04x lp=%08lx\n", msg, wParam, lParam); 
 
-#define PROGRESS_GetInfoPtr(wndPtr) ((PROGRESS_INFO *)wndPtr->wExtra)
+#define PROGRESS_GetInfoPtr(wndPtr) ((PROGRESS_INFO *)wndPtr->wExtra[0])
 
 
 /***********************************************************************
@@ -57,25 +55,18 @@
     hbrBar = CreateSolidBrush32 (infoPtr->ColorBar);
 
   /* get the required background brush */
-  if (infoPtr->ColorBk != CLR_DEFAULT)
-    hbrBk = CreateSolidBrush32 (infoPtr->ColorBk);
+  if (infoPtr->ColorBk == CLR_DEFAULT)
+    hbrBk = GetSysColorBrush32 (COLOR_3DFACE);
   else
-    hbrBk = 0; /* to keep the compiler happy ;-) */
+    hbrBk = CreateSolidBrush32 (infoPtr->ColorBk);
 
   /* get rect for the bar, adjusted for the border */
   GetClientRect32 (wndPtr->hwndSelf, &rect);
 
-  /* Hack because of missing top border */
-  rect.top++;
-
   /* draw the border */
-  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);
-  }
+  DrawEdge32(hdc, &rect, BDR_SUNKENOUTER, BF_RECT|BF_ADJUST);
+  FillRect32(hdc, &rect, hbrBk);
+
   rect.left++; rect.right--; rect.top++; rect.bottom--;
 
   /* compute extent of progress bar */
@@ -167,6 +158,10 @@
   switch(message)
     {
     case WM_CREATE:
+      /* allocate memory for info struct */
+      wndPtr->wExtra[0] = HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
+                                     sizeof(PROGRESS_INFO));
+      infoPtr = (PROGRESS_INFO *)wndPtr->wExtra[0];
       /* initialize the info struct */
       infoPtr->MinVal=0; 
       infoPtr->MaxVal=100;
@@ -179,6 +174,7 @@
     
     case WM_DESTROY:
       TRACE(updown, "Progress Ctrl destruction, hwnd=%04x\n", hwnd);
+      HeapFree (SystemHeap, 0, infoPtr);
       break;
 
     case WM_ERASEBKGND:
@@ -207,7 +203,6 @@
 	PROGRESS_CoercePos(wndPtr);
         InvalidateRect32 (hwnd, NULL, FALSE);
         UpdateWindow32 (hwnd);
-//	PROGRESS_Paint(wndPtr, 0);
       }
       return temp;
 
@@ -311,3 +306,27 @@
     return 0;
 }
 
+
+/***********************************************************************
+ *           PROGRESS_Register [Internal]
+ *
+ * Registers the progress bar window class.
+ * 
+ */
+void PROGRESS_Register(void)
+{
+    WNDCLASS32A wndClass;
+
+    if( GlobalFindAtom32A( PROGRESS_CLASS32A ) ) return;
+
+    ZeroMemory( &wndClass, sizeof( WNDCLASS32A ) );
+    wndClass.style         = CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW;
+    wndClass.lpfnWndProc   = (WNDPROC32)ProgressWindowProc;
+    wndClass.cbClsExtra    = 0;
+    wndClass.cbWndExtra    = sizeof(PROGRESS_INFO *);
+    wndClass.hCursor       = LoadCursor32A( 0, IDC_ARROW32A );
+    wndClass.lpszClassName = PROGRESS_CLASS32A;
+
+    RegisterClass32A( &wndClass );
+}
+
diff --git a/controls/status.c b/controls/status.c
index 395ebce..e1d8b95 100644
--- a/controls/status.c
+++ b/controls/status.c
@@ -2,10 +2,11 @@
  * Interface code to StatusWindow widget/control
  *
  * Copyright 1996 Bruce Milner
+ * Copyright 1998 Eric Kohl
  */
 
 #include <stdio.h>
-#include <stdlib.h>
+
 #include "windows.h"
 #include "status.h"
 #include "commctrl.h"
@@ -20,44 +21,206 @@
 
 /*
  * Fixme/Todo
- * 1) Add size grip to status bar - SBARS_SIZEGRIP
- * 2) Don't hard code bar to bottom of window, allow CCS_TOP also
- * 3) Fix SBT_OWNERDRAW
- * 4) Add DrawStatusText32A funtion
+ * 1) Don't hard code bar to bottom of window, allow CCS_TOP also
+ * 2) Add 'non hack' version of icon drawing code
  */
 
+#define __GET_ICON_INFO_HACK__
+
+#ifdef __GET_ICON_INFO_HACK__
+#include "bitmap.h"
+#endif
+
+#define _MAX(a,b) (((a)>(b))?(a):(b))
+#define _MIN(a,b) (((a)>(b))?(b):(a))
+
+#define HORZ_BORDER 0
+#define VERT_BORDER 2
+#define HORZ_GAP    2
+
+
 static STATUSWINDOWINFO *GetStatusInfo(HWND32 hwnd)
 {
     WND *wndPtr;
 
     wndPtr = WIN_FindWndPtr(hwnd);
-    return ((STATUSWINDOWINFO *) &wndPtr->wExtra[0]);
+    return ((STATUSWINDOWINFO *) wndPtr->wExtra[0]);
 }
 
-static BOOL32 SW_Refresh( HWND32 hwnd, HDC32 hdc, STATUSWINDOWINFO *self )
+
+static void
+STATUS_DrawSizeGrip (HDC32 hdc, LPRECT32 lpRect)
 {
-	int	i;
+    HPEN32 hOldPen;
+    POINT32 pt;
+    INT32 i;
 
-	if (!IsWindowVisible32(hwnd)) {
-	    return (TRUE);
-	}
+    pt.x = lpRect->right - 1;
+    pt.y = lpRect->bottom - 1;
 
-	if (self->simple) {
-	    DrawStatusText32A(hdc,
-			      &self->part0.bound,
-			      self->part0.text,
-			      self->part0.style);
+    hOldPen = SelectObject32 (hdc, GetSysColorPen32 (COLOR_3DFACE));
+    MoveToEx32 (hdc, pt.x - 12, pt.y, NULL);
+    LineTo32 (hdc, pt.x, pt.y);
+    LineTo32 (hdc, pt.x, pt.y - 12);
+
+    pt.x--;
+    pt.y--;
+
+    SelectObject32 (hdc, GetSysColorPen32 (COLOR_3DSHADOW));
+    for (i = 1; i < 11; i += 4) {
+	MoveToEx32 (hdc, pt.x - i, pt.y, NULL);
+	LineTo32 (hdc, pt.x, pt.y - i);
+
+	MoveToEx32 (hdc, pt.x - i-1, pt.y, NULL);
+	LineTo32 (hdc, pt.x, pt.y - i-1);
+    }
+
+    SelectObject32 (hdc, GetSysColorPen32 (COLOR_3DHIGHLIGHT));
+    for (i = 3; i < 13; i += 4) {
+	MoveToEx32 (hdc, pt.x - i, pt.y, NULL);
+	LineTo32 (hdc, pt.x, pt.y - i);
+    }
+
+    SelectObject32 (hdc, hOldPen);
+}
+
+
+static void 
+SB_DrawPart( HDC32 hdc, LPRECT32 lprc, HICON32 hIcon,
+             LPCSTR text, UINT32 style )
+{
+    RECT32 r = *lprc;
+    UINT32 border = BDR_SUNKENOUTER;
+
+    if(style==SBT_POPOUT)
+      border = BDR_RAISEDOUTER;
+    else if(style==SBT_NOBORDERS)
+      border = 0;
+
+    DrawEdge32(hdc, &r, border, BF_RECT|BF_ADJUST);
+
+    /* draw the icon */
+    if (hIcon) {
+#ifdef __GET_ICON_INFO_HACK__
+        HBITMAP32 hbmImage;
+        HBITMAP32 hbmMask;
+        CURSORICONINFO *ptr;
+        HDC32 hdcSrc;
+	INT32 y, cy, ry, ty;
+
+        if (ptr = (CURSORICONINFO *)GlobalLock16(hIcon)) {
+        hbmMask  = CreateBitmap32 (ptr->nWidth, ptr->nHeight, 1, 1, 
+                                   (char *)(ptr + 1));
+        hbmImage = CreateBitmap32 (ptr->nWidth, ptr->nHeight, ptr->bPlanes,
+                                   ptr->bBitsPerPixel,
+                                   (char *)(ptr + 1) + ptr->nHeight * 
+                                   BITMAP_WIDTH_BYTES(ptr->nWidth, 1));
+	r.left += 2;
+	ry = r.bottom - r.top;
+	if (ry >= ptr->nHeight) {
+	    /* full view of icon */
+	    y = 0;
+	    cy = ptr->nHeight;
+	    ty = r.top + (ry - ptr->nHeight) / 2;
 	}
 	else {
-	    for (i = 0; i < self->numParts; i++) {
-		DrawStatusText32A(hdc,
-				  &self->parts[i].bound,
-				  self->parts[i].text,
-				  self->parts[i].style);
-	    }
+	    /* partial view of icon */
+	    y = (ptr->nHeight - ry) / 2;
+	    cy = ry;
+	    ty = r.top;
 	}
 
-	return TRUE;
+	    hdcSrc = CreateCompatibleDC32 (hdc);
+	    SelectObject32 (hdcSrc, hbmMask);
+	    BitBlt32 (hdc, r.left, r.top, ptr->nWidth, cy,
+		      hdcSrc, 0, y, SRCAND);
+	    SelectObject32 (hdcSrc, hbmImage);
+	    BitBlt32 (hdc, r.left, r.top, ptr->nWidth, cy,
+		      hdcSrc, 0, y, SRCPAINT);
+	    DeleteDC32 (hdcSrc);
+
+	    r.left += ptr->nWidth;
+	    DeleteObject32 (hbmImage);
+	    DeleteObject32 (hbmMask);
+	    GlobalUnlock16 (hIcon);
+	}
+#else
+	/* FIXME: no "non hack" version available!!! */
+#endif
+    }
+
+    /* now draw text */
+    if (text) {
+      int oldbkmode = SetBkMode32(hdc, TRANSPARENT);
+      r.left += 3;
+      DrawText32A(hdc, text, lstrlen32A(text),
+		  &r, DT_LEFT|DT_VCENTER|DT_SINGLELINE);  
+      if (oldbkmode != TRANSPARENT)
+	SetBkMode32(hdc, oldbkmode);
+    }
+}
+
+
+static BOOL32
+SW_Refresh( HWND32 hwnd, HDC32 hdc, STATUSWINDOWINFO *self )
+{
+    int      i;
+    RECT32   rect;
+    HBRUSH32 hbrBk;
+    WND *wndPtr;
+
+    wndPtr = WIN_FindWndPtr(hwnd);
+
+    if (!IsWindowVisible32(hwnd)) {
+        return (TRUE);
+    }
+
+    GetClientRect32 (hwnd, &rect);
+
+    if (self->clrBk != CLR_DEFAULT)
+	hbrBk = CreateSolidBrush32 (self->clrBk);
+    else
+	hbrBk = GetSysColorBrush32 (COLOR_3DFACE);
+    FillRect32(hdc, &rect, hbrBk);
+
+    if (self->simple) {
+	SB_DrawPart (hdc,
+		     &self->part0.bound,
+		     self->part0.hIcon,
+		     self->part0.text,
+		     self->part0.style);
+    }
+    else {
+	for (i = 0; i < self->numParts; i++) {
+	    if (self->parts[i].style == SBT_OWNERDRAW) {
+		DRAWITEMSTRUCT32 dis;
+		WND *wndPtr = WIN_FindWndPtr(hwnd);
+
+		dis.CtlID = wndPtr->wIDmenu;
+		dis.itemID = -1;
+		dis.hwndItem = hwnd;
+		dis.hDC = hdc;
+		dis.rcItem = self->part0.bound;
+		dis.itemData = (INT32)self->part0.text;
+		SendMessage32A (GetParent32 (hwnd), WM_DRAWITEM, 
+				(WPARAM32)wndPtr->wIDmenu, (LPARAM)&dis);
+	    }
+	    else
+		SB_DrawPart (hdc,
+			     &self->parts[i].bound,
+			     self->parts[i].hIcon,
+			     self->parts[i].text,
+			     self->parts[i].style);
+	}
+    }
+
+    if (self->clrBk != CLR_DEFAULT)
+	DeleteObject32 (hbrBk);
+
+    if (wndPtr->dwStyle & SBARS_SIZEGRIP)
+	STATUS_DrawSizeGrip (hdc, &rect);
+
+    return TRUE;
 }
 
 
@@ -66,11 +229,10 @@
 {
     LPINT32	out;
 
-    /* FIXME for sizegrips */
     out = (LPINT32) lParam;
-    out[0] = 1; /* vertical border width */
-    out[1] = 1; /* horizontal border width */
-    out[2] = 1; /* width of border between rectangles */
+    out[0] = HORZ_BORDER; /* horizontal border width */
+    out[1] = VERT_BORDER; /* vertical border width */
+    out[2] = HORZ_GAP; /* width of border between rectangles */
     return TRUE;
 }
 
@@ -80,11 +242,12 @@
     int	i;
     RECT32	rect, *r;
     STATUSWINDOWPART *part;
-    int	sep = 1;
 
     /* get our window size */
     GetClientRect32(hwnd, &rect);
 
+    rect.top += VERT_BORDER;
+
     /* set bounds for simple rectangle */
     self->part0.bound = rect;
 
@@ -97,7 +260,7 @@
 	if (i == 0)
 	    r->left = 0;
 	else
-	    r->left = self->parts[i-1].bound.right+sep;
+	    r->left = self->parts[i-1].bound.right + HORZ_GAP;
 	if (part->x == -1)
 	    r->right = rect.right;
 	else
@@ -204,17 +367,26 @@
 }
 
 static LRESULT
-SW_Create(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+SW_Create(HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
 {
     RECT32	rect;
     LPCREATESTRUCT32A lpCreate = (LPCREATESTRUCT32A) lParam;
-    int	height, width;
+    int	height, width, len;
     HDC32	hdc;
     HWND32	parent;
+    WND *wndPtr;
+    STATUSWINDOWINFO *self;
 
-    self->numParts = 0;
+    wndPtr = WIN_FindWndPtr(hwnd);
+    wndPtr->wExtra[0] = HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
+				   sizeof(STATUSWINDOWINFO));
+
+    self = (STATUSWINDOWINFO*)wndPtr->wExtra[0];
+    self->numParts = 1;
     self->parts = 0;
-    self->simple = TRUE;
+    self->simple = FALSE;
+    self->clrBk = CLR_DEFAULT;
+    self->hFont = 0;
     GetClientRect32(hwnd, &rect);
 
     /* initialize simple case */
@@ -222,8 +394,23 @@
     self->part0.text = 0;
     self->part0.x = 0;
     self->part0.style = 0;
+    self->part0.hIcon = 0;
 
-    height = 40;
+    /* initialize first part */
+    self->parts = HeapAlloc(SystemHeap, HEAP_ZERO_MEMORY,
+			    sizeof(STATUSWINDOWPART));
+    self->parts[0].bound = rect;
+    self->parts[0].text = 0;
+    self->parts[0].x = -1;
+    self->parts[0].style = 0;
+    self->parts[0].hIcon = 0;
+
+    if (len = lstrlen32A( lpCreate->lpszName ) ) {
+        self->parts[0].text = HeapAlloc( SystemHeap, 0, len + 1 );
+        lstrcpy32A( self->parts[0].text, lpCreate->lpszName );
+    }
+
+    height = 20;
     if ((hdc = GetDC32(0))) {
 	TEXTMETRIC32A tm;
 	GetTextMetrics32A(hdc, &tm);
@@ -234,8 +421,8 @@
     parent = GetParent32(hwnd);
     GetClientRect32(parent, &rect);
     width = rect.right - rect.left;
-    height = (self->textHeight * 3)/2;
-    MoveWindow32(hwnd, lpCreate->x, lpCreate->y-1, width, height, FALSE);
+    self->height = self->textHeight + 4 + VERT_BORDER;
+    MoveWindow32(hwnd, lpCreate->x, lpCreate->y-1, width, self->height, FALSE);
     SW_SetPartBounds(hwnd, self);
     return 0;
 }
@@ -308,25 +495,242 @@
 static LRESULT
 SW_SetMinHeight(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
 {
-    /* FIXME */
-    /* size is wParam | 2*pixels_of_horz_border */
+    INT32	width, height, x, y;
+    RECT32	parent_rect;
+    HWND32	parent;
+
+    if (IsWindowVisible32 (hwnd)) {
+	/* width and height don't apply */
+	parent = GetParent32(hwnd);
+	GetClientRect32(parent, &parent_rect);
+	self->height = (INT32)wParam + VERT_BORDER;
+	width = parent_rect.right - parent_rect.left;
+	x = parent_rect.left;
+	y = parent_rect.bottom - self->height;
+	MoveWindow32(hwnd, parent_rect.left, parent_rect.bottom - self->height,
+		     width, self->height, TRUE);
+	SW_SetPartBounds(hwnd, self);
+    }
+
     return TRUE;
 }
 
 static LRESULT
+SW_SetBkColor(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+    COLORREF oldBkColor;
+    HDC32    hdc;
+
+    oldBkColor = self->clrBk;
+    self->clrBk = (COLORREF)lParam;
+    hdc = GetDC32(hwnd);
+    SW_Refresh(hwnd, hdc, self);
+    ReleaseDC32(hwnd, hdc);
+    return oldBkColor;
+}
+
+
+static LRESULT
+SW_SetIcon(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+    HDC32    hdc;
+    INT32    nPart;
+
+    nPart = (INT32)wParam & 0x00ff;
+    if ((nPart < -1) || (nPart >= self->numParts)) return FALSE;
+
+    if (nPart == -1) {
+        self->part0.hIcon = (HICON32)lParam;
+        if (self->simple) 
+            InvalidateRect32(hwnd, &self->part0.bound, FALSE);
+    }
+    else {
+        self->parts[nPart].hIcon = (HICON32)lParam;
+        if (!(self->simple))
+            InvalidateRect32(hwnd, &self->parts[nPart].bound, FALSE);
+    }
+    return TRUE;
+}
+
+static LRESULT
+SW_GetIcon(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+    INT32    nPart;
+
+    nPart = (INT32)wParam & 0x00ff;
+    if ((nPart < -1) || (nPart >= self->numParts)) return NULL;
+
+    if (nPart == -1)
+        return (self->part0.hIcon);
+    else
+        return (self->parts[nPart].hIcon);
+}
+
+static LRESULT
 SW_Simple(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
 {
+    WND *wndPtr;
     BOOL32 simple;
-    HDC32	hdc;
+    HDC32  hdc;
+    NMHDR  nmhdr;
+
+    wndPtr = WIN_FindWndPtr(hwnd);
 
     simple = (BOOL32) wParam;
     self->simple = simple;
+
+    /* send notification */
+    nmhdr.hwndFrom = hwnd;
+    nmhdr.idFrom = wndPtr->wIDmenu;
+    nmhdr.code = SBN_SIMPLEMODECHANGE;
+    SendMessage32A (GetParent32 (hwnd), WM_NOTIFY, 0, (LPARAM)&nmhdr);
+
     hdc = GetDC32(hwnd);
     SW_Refresh(hwnd, hdc, self);
     ReleaseDC32(hwnd, hdc);
+
     return TRUE;
 }
 
+
+static LRESULT
+SW_Destroy(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+    int	i;
+
+    for (i = 0; i < self->numParts; i++) {
+	if (self->parts[i].text && (self->parts[i].style != SBT_OWNERDRAW))
+	    HeapFree(SystemHeap, 0, self->parts[i].text);
+    }
+    if (self->part0.text && (self->part0.style != SBT_OWNERDRAW))
+	HeapFree(SystemHeap, 0, self->part0.text);
+    HeapFree(SystemHeap, 0, self->parts);
+    HeapFree(SystemHeap, 0, self);
+    return 0;
+}
+
+
+static LRESULT
+SW_WMGetText (STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+    INT32 len;
+
+    if (!(self->parts[0].text))
+        return 0;
+    len = lstrlen32A (self->parts[0].text);
+    if (wParam > len) {
+        lstrcpy32A ((LPSTR)lParam, self->parts[0].text);
+        return len;
+    }
+    else
+        return -1;
+}
+
+
+static LRESULT
+SW_WMGetTextLength (STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+    if (!(self->parts[0].text))
+        return 0;
+    return (lstrlen32A (self->parts[0].text));
+}
+
+
+static LRESULT
+SW_NcHitTest (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    RECT32  rect;
+    POINT32 pt;
+
+    if (wndPtr->dwStyle & SBARS_SIZEGRIP) {
+	GetClientRect32 (wndPtr->hwndSelf, &rect);
+
+	pt.x = (INT32)LOWORD(lParam);
+	pt.y = (INT32)HIWORD(lParam);
+	ScreenToClient32 (wndPtr->hwndSelf, &pt);
+
+	rect.left = rect.right - 13;
+	rect.top += 2;
+
+	if (PtInRect32 (&rect, pt))
+	    return HTBOTTOMRIGHT;
+    }
+
+    return DefWindowProc32A (wndPtr->hwndSelf, WM_NCHITTEST, wParam, lParam);
+}
+
+
+static LRESULT
+SW_NcLButtonDown (HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+//    TRACE (status, "WM_NCLBUTTONDOWN\n");
+    PostMessage32A (GetParent32 (hwnd), WM_NCLBUTTONDOWN,
+		    wParam, lParam);
+    return 0;
+}
+
+
+static LRESULT
+SW_NcLButtonUp (HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+//    TRACE (status, "WM_NCLBUTTONUP\n");
+    PostMessage32A (GetParent32 (hwnd), WM_NCLBUTTONUP,
+		    wParam, lParam);
+    return 0;
+}
+
+
+static LRESULT
+SW_Paint(STATUSWINDOWINFO *self, HWND32 hwnd)
+{
+    HDC32 hdc;
+    PAINTSTRUCT32	ps;
+
+    hdc = BeginPaint32(hwnd, &ps);
+    SW_Refresh(hwnd, hdc, self);
+    EndPaint32(hwnd, &ps);
+    return 0;
+}
+
+
+static LRESULT
+SW_WMSetFont (STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+    HDC32 hdc;
+
+    self->hFont = (HFONT32)wParam;
+    if (LOWORD(lParam) == TRUE) {
+        hdc = GetDC32(hwnd);
+        SW_Refresh(hwnd, hdc, self);
+        ReleaseDC32(hwnd, hdc);
+    }
+    return 0;
+}
+
+
+static LRESULT
+SW_WMSetText (STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+    int len;
+    STATUSWINDOWPART *part;
+
+    if (self->numParts == 0) return FALSE;
+
+    part = &self->parts[0];
+    /* duplicate string */
+    if (part->text)
+        HeapFree(SystemHeap, 0, part->text);
+    part->text = 0;
+    if (lParam && (len = lstrlen32A((LPCSTR)lParam))) {
+        part->text = HeapAlloc(SystemHeap, 0, len+1);
+        lstrcpy32A(part->text, (LPCSTR)lParam);
+    }
+    InvalidateRect32(hwnd, &part->bound, FALSE);
+
+    return TRUE;
+}
+
+
 static LRESULT
 SW_Size(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
 {
@@ -347,56 +751,48 @@
 	/* width and height don't apply */
 	parent = GetParent32(hwnd);
 	GetClientRect32(parent, &parent_rect);
-	height = (self->textHeight * 3)/2;
 	width = parent_rect.right - parent_rect.left;
 	x = parent_rect.left;
-	y = parent_rect.bottom - height;
-	MoveWindow32(hwnd, parent_rect.left, parent_rect.bottom - height - 1,
-		     width, height, TRUE);
+	y = parent_rect.bottom - self->height;
+	MoveWindow32(hwnd, parent_rect.left, parent_rect.bottom - self->height,
+		     width, self->height, TRUE);
 	SW_SetPartBounds(hwnd, self);
     }
     return 0;
 }
 
-static LRESULT
-SW_Destroy(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
-{
-    int	i;
 
-    for (i = 0; i < self->numParts; i++) {
-	if (self->parts[i].text && (self->parts[i].style != SBT_OWNERDRAW))
-	    HeapFree(SystemHeap, 0, self->parts[i].text);
-    }
-    if (self->part0.text && (self->part0.style != SBT_OWNERDRAW))
-	HeapFree(SystemHeap, 0, self->part0.text);
-    HeapFree(SystemHeap, 0, self->parts);
+static LRESULT
+SW_SendNotify (HWND32 hwnd, UINT32 code)
+{
+    WND    *wndPtr;
+    NMHDR  nmhdr;
+
+    wndPtr = WIN_FindWndPtr(hwnd);
+    nmhdr.hwndFrom = hwnd;
+    nmhdr.idFrom = wndPtr->wIDmenu;
+    nmhdr.code = code;
+    SendMessage32A (GetParent32 (hwnd), WM_NOTIFY, 0, (LPARAM)&nmhdr);
+
     return 0;
 }
 
 
 
-static LRESULT
-SW_Paint(STATUSWINDOWINFO *self, HWND32 hwnd)
-{
-    HDC32 hdc;
-    PAINTSTRUCT32	ps;
-
-    hdc = BeginPaint32(hwnd, &ps);
-    SW_Refresh(hwnd, hdc, self);
-    EndPaint32(hwnd, &ps);
-    return 0;
-}
-
-LRESULT WINAPI StatusWindowProc( HWND32 hwnd, UINT32 msg,
-                                 WPARAM32 wParam, LPARAM lParam )
+LRESULT WINAPI
+StatusWindowProc (HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
 {
     STATUSWINDOWINFO *self;
+    WND *wndPtr;
 
+    wndPtr = WIN_FindWndPtr(hwnd);
     self = GetStatusInfo(hwnd);
 
     switch (msg) {
     case SB_GETBORDERS:
 	return SW_GetBorders(self, hwnd, wParam, lParam);
+    case SB_GETICON:
+        return SW_GetIcon(self, hwnd, wParam, lParam);
     case SB_GETPARTS:
 	return SW_GetParts(self, hwnd, wParam, lParam);
     case SB_GETRECT:
@@ -405,6 +801,12 @@
 	return SW_GetText(self, hwnd, wParam, lParam);
     case SB_GETTEXTLENGTH32A:
 	return SW_GetTextLength(self, hwnd, wParam, lParam);
+    case SB_ISSIMPLE:
+        return self->simple;
+    case SB_SETBKCOLOR:
+        return SW_SetBkColor(self, hwnd, wParam, lParam);
+    case SB_SETICON:
+        return SW_SetIcon(self, hwnd, wParam, lParam);
     case SB_SETMINHEIGHT:
 	return SW_SetMinHeight(self, hwnd, wParam, lParam);
     case SB_SETPARTS:	
@@ -415,18 +817,70 @@
 	return SW_Simple(self, hwnd, wParam, lParam);
 
     case WM_CREATE:
-	return SW_Create(self, hwnd, wParam, lParam);
+	return SW_Create(hwnd, wParam, lParam);
     case WM_DESTROY:
 	return SW_Destroy(self, hwnd, wParam, lParam);
+    case WM_GETFONT:
+        return self->hFont;
+    case WM_GETTEXT:
+        return SW_WMGetText(self, hwnd, wParam, lParam);
+    case WM_GETTEXTLENGTH:
+        return SW_WMGetTextLength(self, hwnd, wParam, lParam);
+
+    case WM_LBUTTONDBLCLK:
+        return SW_SendNotify (hwnd, NM_DBLCLK);
+
+    case WM_LBUTTONUP:
+	return SW_SendNotify (hwnd, NM_CLICK);
+
+    case WM_NCHITTEST:
+        return SW_NcHitTest (wndPtr, wParam, lParam);
+
+   case WM_NCLBUTTONDOWN:
+	return SW_NcLButtonDown (hwnd, wParam, lParam);
+
+    case WM_NCLBUTTONUP:
+	return SW_NcLButtonUp (hwnd, wParam, lParam);
+
     case WM_PAINT:
 	return SW_Paint(self, hwnd);
+    case WM_RBUTTONDBLCLK:
+        return SW_SendNotify (hwnd, NM_RDBLCLK);
+    case WM_RBUTTONUP:
+        return SW_SendNotify (hwnd, NM_RCLICK);
+    case WM_SETFONT:
+        return SW_WMSetFont(self, hwnd, wParam, lParam);
+    case WM_SETTEXT:
+        return SW_WMSetText(self, hwnd, wParam, lParam);
     case WM_SIZE:
 	return SW_Size(self, hwnd, wParam, lParam);
     default:
-	return DefWindowProc32A(hwnd, msg, wParam, lParam);
+	return DefWindowProc32A (hwnd, msg, wParam, lParam);
     }
     return 0;
 }
 
 
+/***********************************************************************
+ *           STATUS_Register [Internal]
+ *
+ * Registers the status window class.
+ */
+void STATUS_Register(void)
+{
+    WNDCLASS32A wndClass;
+
+    if( GlobalFindAtom32A( STATUSCLASSNAME32A ) ) return;
+
+    ZeroMemory( &wndClass, sizeof( WNDCLASS32A ) );
+    wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW;
+    wndClass.lpfnWndProc   = (WNDPROC32)StatusWindowProc;
+    wndClass.cbClsExtra    = 0;
+    wndClass.cbWndExtra    = sizeof(STATUSWINDOWINFO *);
+    wndClass.hCursor       = LoadCursor32A( 0, IDC_ARROW32A );
+    wndClass.hbrBackground = (HBRUSH32)(COLOR_3DFACE + 1);
+    wndClass.lpszClassName = STATUSCLASSNAME32A;
+ 
+    RegisterClass32A( &wndClass );
+}
 
diff --git a/controls/updown.c b/controls/updown.c
index 83e2a6d..66c2532 100644
--- a/controls/updown.c
+++ b/controls/updown.c
@@ -785,3 +785,26 @@
     return 0;
 }
 
+/***********************************************************************
+ *           UPDOWN_Register [Internal]
+ *
+ * Registers the updown window class.
+ */
+void UPDOWN_Register(void)
+{
+    WNDCLASS32A wndClass;
+
+    if( GlobalFindAtom32A( UPDOWN_CLASS32A ) ) return;
+
+    ZeroMemory( &wndClass, sizeof( WNDCLASS32A ) );
+    wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW;
+    wndClass.lpfnWndProc   = (WNDPROC32)UpDownWindowProc;
+    wndClass.cbClsExtra    = 0;
+    wndClass.cbWndExtra    = sizeof(UPDOWN_INFO);
+    wndClass.hCursor       = LoadCursor32A( 0, IDC_ARROW32A );
+    wndClass.hbrBackground = (HBRUSH32)(COLOR_3DFACE + 1);
+    wndClass.lpszClassName = UPDOWN_CLASS32A;
+ 
+    RegisterClass32A( &wndClass );
+}
+
diff --git a/debugger/break.c b/debugger/break.c
index 17e055e..acbfcb3 100644
--- a/debugger/break.c
+++ b/debugger/break.c
@@ -343,7 +343,7 @@
 
     for (ok = ModuleFirst(&entry); ok; ok = ModuleNext(&entry))
     {
-        if (!(pModule = MODULE_GetPtr16( entry.hModule ))) continue;
+        if (!(pModule = NE_GetPtr( entry.hModule ))) continue;
         if (pModule->flags & NE_FFLAGS_LIBMODULE) continue;  /* Library */
 
         if (!(pModule->flags & NE_FFLAGS_WIN32))  /* NE module */
diff --git a/debugger/dbg.y b/debugger/dbg.y
index f7963ef..7a06c40 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -548,24 +548,16 @@
 }
 
 
-/***********************************************************************
- *           DebugBreak32   (KERNEL32)
- */
-void DebugBreak32( CONTEXT *regs )
-{
-    const char *module = MODULE_GetModuleName( GetCurrentTask() );
-    fprintf( stderr, "%s called DebugBreak\n", module ? module : "???" );
-    DEBUG_context = *regs;
-    DEBUG_Main( SIGTRAP );
-}
 
 /***********************************************************************
- *           DebugBreak16   (KERNEL.203)
+ *           DebugBreak   (KERNEL.203) (KERNEL32.181)
  */
-void DebugBreak16( CONTEXT *regs )
+void DebugBreak( CONTEXT *regs )
 {
-    const char *module = MODULE_GetModuleName( GetCurrentTask() );
-    fprintf( stderr, "%s called DebugBreak\n", module ? module : "???" );
+    char module[10];
+    if (!GetModuleName( GetCurrentTask(), module, sizeof(module) ))
+        strcpy( module, "???" );
+    fprintf( stderr, "%s called DebugBreak\n", module );
     DEBUG_context = *regs;
     DEBUG_Main( SIGTRAP );
 }
diff --git a/debugger/dbgmain.c b/debugger/dbgmain.c
index 2f47132..1785714 100644
--- a/debugger/dbgmain.c
+++ b/debugger/dbgmain.c
@@ -50,11 +50,6 @@
   exit(0);
 }
 
-LPSTR MODULE_GetModuleName( HMODULE16 hModule )
-{
-  exit(0);
-}
-
 int PROFILE_GetWineIniString( const char *section, const char *key_name,
                                      const char *def, char *buffer, int len )
 {
@@ -103,7 +98,7 @@
   exit(0);
 }
 
-NE_MODULE *MODULE_GetPtr16( HMODULE16 hModule )
+NE_MODULE *NE_GetPtr( HMODULE16 hModule )
 {
   exit(0);
 }
diff --git a/debugger/hash.c b/debugger/hash.c
index 492769c..4befa47 100644
--- a/debugger/hash.c
+++ b/debugger/hash.c
@@ -877,7 +877,7 @@
 
     for (ok = ModuleFirst(&entry); ok; ok = ModuleNext(&entry))
     {
-        if (!(pModule = MODULE_GetPtr16( entry.hModule ))) continue;
+        if (!(pModule = NE_GetPtr( entry.hModule ))) continue;
         fprintf( stderr, " %s", entry.szModule );
 
         if (!(pModule->flags & NE_FFLAGS_WIN32))  /* NE module */
diff --git a/debugger/stabs.c b/debugger/stabs.c
index bb670f1..36fbe2c 100644
--- a/debugger/stabs.c
+++ b/debugger/stabs.c
@@ -1144,7 +1144,7 @@
    */
   ehptr = (Elf32_Ehdr *) addr;
 
-  if( load_offset == NULL )
+  if( load_offset == 0 )
     {
       DEBUG_RegisterELFDebugInfo(ehptr->e_entry, statbuf.st_size, filename);
     }
@@ -1271,7 +1271,7 @@
     }
 
   if(    (dynpnt->d_tag != DT_DEBUG)
-      || (dynpnt->d_un.d_ptr == NULL) )
+      || (dynpnt->d_un.d_ptr == 0) )
     {
       goto leave;
     }
@@ -1296,7 +1296,7 @@
        * shared libraries which may be loaded.
        */
       ehdr = (Elf32_Ehdr *) lpnt->l_addr;
-      if( (lpnt->l_addr == NULL) || (ehdr->e_type != ET_DYN) )
+      if( (lpnt->l_addr == 0) || (ehdr->e_type != ET_DYN) )
 	{
 	  continue;
 	}
diff --git a/documentation/programs b/documentation/programs
new file mode 100644
index 0000000..5b5ce98
--- /dev/null
+++ b/documentation/programs
@@ -0,0 +1,12 @@
+
+May, 1998	Matthew Becker (mbecker@glasscity.net
+
+Help, this does not work!  What am I missing?
+
+How to add a new test program
+- create the directory under .../programs
+- add the directory to WINEROOT/programs/Makefile.in
+- add the directory to WINEROOT/configure.in
+- when creating the diff, use -N to force the entire text to be included in 
+  the diff
+
diff --git a/files/directory.c b/files/directory.c
index 0f211d7..1c98caa 100644
--- a/files/directory.c
+++ b/files/directory.c
@@ -14,6 +14,7 @@
 
 #include "windows.h"
 #include "winerror.h"
+#include "process.h"
 #include "drive.h"
 #include "file.h"
 #include "heap.h"
@@ -454,13 +455,20 @@
  */
 static BOOL32 DIR_TryModulePath( LPCSTR name, DOS_FULL_NAME *full_name )
 {
+    PDB32	*pdb = PROCESS_Current();
+
     /* FIXME: for now, GetModuleFileName32A can't return more */
     /* than OFS_MAXPATHNAME. This may change with Win32. */
+
     char buffer[OFS_MAXPATHNAME];
     LPSTR p;
 
-    if (!GetCurrentTask()) return FALSE;
-    GetModuleFileName32A( GetCurrentTask(), buffer, sizeof(buffer) );
+    if (pdb->flags & PDB32_WIN16_PROC) {
+	if (!GetCurrentTask()) return FALSE;
+	GetModuleFileName16( GetCurrentTask(), buffer, sizeof(buffer) );
+    } else {
+	GetModuleFileName32A( 0, buffer, sizeof(buffer) );
+    }
     if (!(p = strrchr( buffer, '\\' ))) return FALSE;
     if (sizeof(buffer) - (++p - buffer) <= strlen(name)) return FALSE;
     strcpy( p, name );
diff --git a/files/dos_fs.c b/files/dos_fs.c
index e7b5a4f..39fba17 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -18,9 +18,6 @@
 #include <sys/ioctl.h>
 #include <time.h>
 #include <unistd.h>
-#ifdef HAVE_SYS_STATFS_H
-# include <sys/statfs.h>
-#endif
 
 #include "windows.h"
 #include "winerror.h"
@@ -619,7 +616,7 @@
 				break;
 			}
 		}
-		/* FIXME: the rest of the devices ... lptX, comX et.al. */
+		FIXME(dosfs,"device open %s not supported (yet)\n",DOSFS_Devices[i]);
     		return HFILE_ERROR32;
 	    }
         }
@@ -837,7 +834,7 @@
 {
     DOS_FULL_NAME full_name;
 
-    /* FIXME: is it correct to always return a fully qualified short path? */
+    /* FIXME: Is it correct to return a UNIX style path here? */
     if (!DOSFS_GetFullName( shortpath, TRUE, &full_name )) return 0;
     lstrcpyn32A( longpath, full_name.long_name, longlen );
     return strlen( full_name.long_name );
diff --git a/files/drive.c b/files/drive.c
index c07d350..a5168bc 100644
--- a/files/drive.c
+++ b/files/drive.c
@@ -16,17 +16,19 @@
 #include <fcntl.h>
 #include <errno.h>
 
-#ifdef HAVE_SYS_VFS_H
-# include <sys/vfs.h>
-#endif
 #ifdef HAVE_SYS_PARAM_H
 # include <sys/param.h>
 #endif
-#ifdef HAVE_SYS_MOUNT_H
-# include <sys/mount.h>
-#endif
-#ifdef HAVE_SYS_STATFS_H
-# include <sys/statfs.h>
+#ifdef STATFS_DEFINED_BY_SYS_VFS
+# include <sys/vfs.h>
+#else
+# ifdef STATFS_DEFINED_BY_SYS_MOUNT
+#  include <sys/mount.h>
+# else
+#  ifdef STATFS_DEFINED_BY_SYS_STATFS
+#   include <sys/statfs.h>
+#  endif
+# endif
 #endif
 
 #include "windows.h"
diff --git a/files/profile.c b/files/profile.c
index 037cfb0..e1c3544 100644
--- a/files/profile.c
+++ b/files/profile.c
@@ -494,7 +494,7 @@
         section = section->next;
     }
     buffer[0] = buffer[1] = '\0';
-    return 2;
+    return 0;
 }
 
 
diff --git a/graphics/ddraw.c b/graphics/ddraw.c
index 92c118f..66df804 100644
--- a/graphics/ddraw.c
+++ b/graphics/ddraw.c
@@ -144,7 +144,7 @@
 	};
 	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
 		if (flags[i].mask & flagmask)
-			DUMP("%s ",i,flags[i].name);
+			DUMP("%s ",flags[i].name);
 	DUMP("\n");
 }
 
@@ -184,7 +184,7 @@
 	};
 	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
 		if (flags[i].mask & flagmask)
-			DUMP("%s ",i,flags[i].name);
+			DUMP("%s ",flags[i].name);
 }
 
 static void _dump_DDSCAPS(DWORD flagmask) {
@@ -231,7 +231,7 @@
 	DUMP("\n");
 }
 
-static void _dump_DDCAPS(DWORD flagmask) {
+void _dump_DDCAPS(DWORD flagmask) {
 	int	i;
 	const struct {
 		DWORD	mask;
@@ -302,7 +302,7 @@
 	};
 	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
 		if (flags[i].mask & flagmask)
-			DUMP("%s ",i,flags[i].name);
+			DUMP("%s ",flags[i].name);
 	DUMP("\n");
 }
 
@@ -1031,6 +1031,29 @@
 		this->palents[i].peBlue = palent[i-start].peBlue;
 		this->palents[i].peGreen = palent[i-start].peGreen;
 	}
+
+/* Insomnia's (Stea Greene's) Mods Start Here */
+/* FIXME: Still should free individual cells, but this fixes loss of */
+/*        unchange sections of old palette */
+
+	for (i=0;i<start;i++) {
+		xc.red = this->palents[i].peRed<<8;
+		xc.blue = this->palents[i].peBlue<<8;
+		xc.green = this->palents[i].peGreen<<8;
+		xc.flags = DoRed|DoBlue|DoGreen;
+		xc.pixel = i;
+		TSXStoreColor(display,this->cm,&xc);
+	}
+	for (i=end;i<256;i++) {
+		xc.red = this->palents[i].peRed<<8;
+		xc.blue = this->palents[i].peBlue<<8;
+		xc.green = this->palents[i].peGreen<<8;
+		xc.flags = DoRed|DoBlue|DoGreen;
+		xc.pixel = i;
+		TSXStoreColor(display,this->cm,&xc);
+	}
+/* End Insomnia's Mods */
+
 	XF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
 	return 0;
 }
@@ -1248,7 +1271,6 @@
 	LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
 ) {
 	int	i,*depths,depcount;
-	char	buf[200];
 
 	TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n",
 		      this, width, height, depth);
diff --git a/graphics/mapping.c b/graphics/mapping.c
index 0600e94..52eb7a3 100644
--- a/graphics/mapping.c
+++ b/graphics/mapping.c
@@ -56,35 +56,13 @@
  */
 BOOL32 WINAPI DPtoLP32( HDC32 hdc, LPPOINT32 points, INT32 count )
 {
-    FLOAT determinant=1.0, x, y;
-    
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) return FALSE;
 
-    if (dc->w.UseWorldXform)
-    {
-        determinant = dc->w.WorldXform.eM11*dc->w.WorldXform.eM22 -
-            dc->w.WorldXform.eM12*dc->w.WorldXform.eM21;
-        if (determinant > -1e-12 && determinant < 1e-12)
-            return FALSE;
-    }
-
     while (count--)
     {
-	if (dc->w.UseWorldXform)
-	{
-            x = (FLOAT)XDPTOLP( dc, points->x ) - dc->w.WorldXform.eDx;
-	    y = (FLOAT)YDPTOLP( dc, points->y ) - dc->w.WorldXform.eDy;
-	    points->x = (INT32)( (x*dc->w.WorldXform.eM22 -
-	       y*dc->w.WorldXform.eM21) / determinant );
-	    points->y = (INT32)( (-x*dc->w.WorldXform.eM12 +
-	       y*dc->w.WorldXform.eM11) / determinant );
-	}
-	else
-	{
-	    points->x = XDPTOLP( dc, points->x );
-	    points->y = YDPTOLP( dc, points->y );
-	}
+        if (!INTERNAL_DPTOLP( dc, points ))
+	    return FALSE;
         points++;
     }
     return TRUE;
@@ -114,30 +92,12 @@
  */
 BOOL32 WINAPI LPtoDP32( HDC32 hdc, LPPOINT32 points, INT32 count )
 {
-    FLOAT x, y;
-
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) return FALSE;
 
     while (count--)
     {
-	if (dc->w.UseWorldXform)
-	{
-	    x = (FLOAT)points->x * dc->w.WorldXform.eM11 +
-	    	(FLOAT)points->y * dc->w.WorldXform.eM21 +
-		dc->w.WorldXform.eDx;
-	    y = (FLOAT)points->x * dc->w.WorldXform.eM12 +
-	        (FLOAT)points->y * dc->w.WorldXform.eM22 +
-		dc->w.WorldXform.eDy;
-	    points->x = XLPTODP( dc, (INT32)x );
-	    points->y = YLPTODP( dc, (INT32)y );
-	    
-	}
-	else
-	{
-	    points->x = XLPTODP( dc, points->x );
-	    points->y = YLPTODP( dc, points->y );
-	}
+	INTERNAL_LPTODP( dc, points );
         points++;
     }
     return TRUE;
@@ -230,6 +190,7 @@
 	  return prevMode;
     }
     dc->w.MapMode = mode;
+    DC_UpdateXforms( dc );
     return prevMode;
 }
 
@@ -277,6 +238,7 @@
     dc->vportExtX = x;
     dc->vportExtY = y;
     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
+    DC_UpdateXforms( dc );
     return TRUE;
 }
 
@@ -320,6 +282,7 @@
     }
     dc->vportOrgX = x;
     dc->vportOrgY = y;
+    DC_UpdateXforms( dc );
     return TRUE;
 }
 
@@ -366,6 +329,7 @@
     dc->wndExtX = x;
     dc->wndExtY = y;
     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
+    DC_UpdateXforms( dc );
     return TRUE;
 }
 
@@ -408,6 +372,7 @@
     }
     dc->wndOrgX = x;
     dc->wndOrgY = y;
+    DC_UpdateXforms( dc );
     return TRUE;
 }
 
@@ -451,6 +416,7 @@
     }
     dc->vportOrgX += x;
     dc->vportOrgY += y;
+    DC_UpdateXforms( dc );
     return TRUE;
 }
 
@@ -494,6 +460,7 @@
     }
     dc->wndOrgX += x;
     dc->wndOrgY += y;
+    DC_UpdateXforms( dc );
     return TRUE;
 }
 
@@ -548,6 +515,7 @@
     if (dc->vportExtX == 0) dc->vportExtX = 1;
     if (dc->vportExtY == 0) dc->vportExtY = 1;
     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
+    DC_UpdateXforms( dc );
     return TRUE;
 }
 
@@ -602,5 +570,6 @@
     if (dc->wndExtX == 0) dc->wndExtX = 1;
     if (dc->wndExtY == 0) dc->wndExtY = 1;
     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
+    DC_UpdateXforms( dc );
     return TRUE;
 }
diff --git a/graphics/metafiledrv/init.c b/graphics/metafiledrv/init.c
index 77ecba5..a789159 100644
--- a/graphics/metafiledrv/init.c
+++ b/graphics/metafiledrv/init.c
@@ -270,7 +270,7 @@
 				   HDC32 hdc /* Metafile DC to close */
 )
 {
-  return CloseMetaFile32(hdc);
+  return CloseMetaFile16(hdc);
 }
 
 
diff --git a/graphics/painting.c b/graphics/painting.c
index a142c91..4d75ddd 100644
--- a/graphics/painting.c
+++ b/graphics/painting.c
@@ -219,6 +219,10 @@
 {
     DC * dc = DC_GetDCPtr( hdc );
   
+    if(dc && PATH_IsPathOpen(dc->w.path))
+        if(!PATH_Rectangle(hdc, left, top, right, bottom))
+           return FALSE;
+
     return dc && dc->funcs->pRectangle &&
     	   dc->funcs->pRectangle(dc,left,top,right,bottom);
 }
@@ -959,7 +963,8 @@
     /* before it is displayed */
     fg = SetTextColor32(hdc, RGB(0, 0, 0));
     bg = SetBkColor32(hdc, RGB(255, 255, 255));
-    hbm = NULL; hbmsave = NULL; memdc = NULL; memdc = NULL; hbsave = NULL;
+    hbm = (HBITMAP32)NULL; hbmsave = (HBITMAP32)NULL;
+    memdc = (HDC32)NULL; hbsave = (HBRUSH32)NULL;
     retval = FALSE; /* assume failure */
     
     /* From here on we must use "goto cleanup" when something goes wrong */
diff --git a/graphics/path.c b/graphics/path.c
index a795af8..b68d286 100644
--- a/graphics/path.c
+++ b/graphics/path.c
@@ -62,15 +62,16 @@
 static BOOL32 PATH_PathToRegion(const GdiPath *pPath, INT32 nPolyFillMode,
    HRGN32 *pHrgn);
 static void   PATH_EmptyPath(GdiPath *pPath);
-static BOOL32 PATH_AddEntry(GdiPath *pPath, POINT32 point, BYTE flags);
+static BOOL32 PATH_AddEntry(GdiPath *pPath, const POINT32 *pPoint,
+   BYTE flags);
 static BOOL32 PATH_ReserveEntries(GdiPath *pPath, INT32 numEntries);
 static BOOL32 PATH_GetPathFromHDC(HDC32 hdc, GdiPath **ppPath);
-static BOOL32 PATH_DoArcPart(GdiPath *pPath, POINT32 corners[],
+static BOOL32 PATH_DoArcPart(GdiPath *pPath, FLOAT_POINT corners[],
    double angleStart, double angleEnd, BOOL32 addMoveTo);
-static void PATH_ScaleNormalizedPoint(POINT32 corners[], double x, double y,
-   POINT32 *pPoint);
-static void PATH_NormalizePoint(POINT32 corners[], const POINT32 *pPoint,
-   double *pX, double *pY);
+static void PATH_ScaleNormalizedPoint(FLOAT_POINT corners[], double x,
+   double y, POINT32 *pPoint);
+static void PATH_NormalizePoint(FLOAT_POINT corners[], const FLOAT_POINT
+   *pPoint, double *pX, double *pY);
 
 
 /***********************************************************************
@@ -218,6 +219,8 @@
       return FALSE;
    }
    
+   /* FIXME: Shouldn't we draw a line to the beginning of the figure? */
+   
    /* Set PT_CLOSEFIGURE on the last entry and start a new stroke */
    if(pPath->numEntriesUsed)
    {
@@ -436,7 +439,7 @@
    if(PATH_PathToRegion(pPath, GetPolyFillMode32(hdc), &hrgnPath))
    {
       hrgnClip=CreateRectRgn32(0, 0, 0, 0);
-      if(hrgnClip==NULL)
+      if(hrgnClip==(HRGN32)0)
          success=FALSE;
       else
       {
@@ -564,7 +567,6 @@
    
    /* Check that path is open */
    if(pPath->state!=PATH_Open)
-      /* FIXME: Do we have to call SetLastError? */
       return FALSE;
 
    /* Convert point to device coordinates */
@@ -580,12 +582,93 @@
       if(!GetCurrentPositionEx32(hdc, &pointCurPos) ||
          !LPtoDP32(hdc, &pointCurPos, 1))
          return FALSE;
-      if(!PATH_AddEntry(pPath, pointCurPos, PT_MOVETO))
+      if(!PATH_AddEntry(pPath, &pointCurPos, PT_MOVETO))
          return FALSE;
    }
    
    /* Add a PT_LINETO entry */
-   return PATH_AddEntry(pPath, point, PT_LINETO);
+   return PATH_AddEntry(pPath, &point, PT_LINETO);
+}
+
+/* PATH_Rectangle
+ *
+ * Should be called when a call to Rectangle is performed on a DC that has
+ * an open path. Returns TRUE if successful, else FALSE.
+ */
+BOOL32 PATH_Rectangle(HDC32 hdc, INT32 x1, INT32 y1, INT32 x2, INT32 y2)
+{
+   GdiPath *pPath;
+   POINT32 corners[2], pointTemp;
+   INT32   temp;
+
+   /* Get pointer to path */
+   if(!PATH_GetPathFromHDC(hdc, &pPath))
+      return FALSE;
+   
+   /* Check that path is open */
+   if(pPath->state!=PATH_Open)
+      return FALSE;
+
+   /* Convert points to device coordinates */
+   corners[0].x=x1;
+   corners[0].y=y1;
+   corners[1].x=x2;
+   corners[1].y=y2;
+   if(!LPtoDP32(hdc, corners, 2))
+      return FALSE;
+   
+   /* Make sure first corner is top left and second corner is bottom right */
+   if(corners[0].x>corners[1].x)
+   {
+      temp=corners[0].x;
+      corners[0].x=corners[1].x;
+      corners[1].x=temp;
+   }
+   if(corners[0].y>corners[1].y)
+   {
+      temp=corners[0].y;
+      corners[0].y=corners[1].y;
+      corners[1].y=temp;
+   }
+   
+   /* In GM_COMPATIBLE, don't include bottom and right edges */
+   if(GetGraphicsMode(hdc)==GM_COMPATIBLE)
+   {
+      corners[1].x--;
+      corners[1].y--;
+   }
+
+   /* Close any previous figure */
+   if(!CloseFigure32(hdc))
+   {
+      /* The CloseFigure call shouldn't have failed */
+      assert(FALSE);
+      return FALSE;
+   }
+
+   /* Add four points to the path */
+   pointTemp.x=corners[1].x;
+   pointTemp.y=corners[0].y;
+   if(!PATH_AddEntry(pPath, &pointTemp, PT_MOVETO))
+      return FALSE;
+   if(!PATH_AddEntry(pPath, corners, PT_LINETO))
+      return FALSE;
+   pointTemp.x=corners[0].x;
+   pointTemp.y=corners[1].y;
+   if(!PATH_AddEntry(pPath, &pointTemp, PT_LINETO))
+      return FALSE;
+   if(!PATH_AddEntry(pPath, corners+1, PT_LINETO))
+      return FALSE;
+
+   /* Close the rectangle figure */
+   if(!CloseFigure32(hdc))
+   {
+      /* The CloseFigure call shouldn't have failed */
+      assert(FALSE);
+      return FALSE;
+   }
+
+   return TRUE;
 }
 
 /* PATH_Ellipse
@@ -596,7 +679,9 @@
  */
 BOOL32 PATH_Ellipse(HDC32 hdc, INT32 x1, INT32 y1, INT32 x2, INT32 y2)
 {
-   return PATH_Arc(hdc, x1, y1, x2, y2, x1, 0, x1, 0);
+   // TODO: This should probably be revised to call PATH_AngleArc
+   // (once it exists)
+   return PATH_Arc(hdc, x1, y1, x2, y2, x1, (y1+y2)/2, x1, (y1+y2)/2);
 }
 
 /* PATH_Arc
@@ -608,16 +693,23 @@
 BOOL32 PATH_Arc(HDC32 hdc, INT32 x1, INT32 y1, INT32 x2, INT32 y2,
    INT32 xStart, INT32 yStart, INT32 xEnd, INT32 yEnd)
 {
-   GdiPath *pPath;
-   double  angleStart, angleEnd, angleStartQuadrant, angleEndQuadrant=0.0;
-           /* Initialize angleEndQuadrant to silence gcc's warning */
-   double  x, y;
-   POINT32 corners[2], pointStart, pointEnd;
-   BOOL32  start, end;
-   INT32   temp;
+   GdiPath     *pPath;
+   DC          *pDC;
+   double      angleStart, angleEnd, angleStartQuadrant, angleEndQuadrant=0.0;
+               /* Initialize angleEndQuadrant to silence gcc's warning */
+   double      x, y;
+   FLOAT_POINT corners[2], pointStart, pointEnd;
+   BOOL32      start, end;
+   INT32       temp;
 
    /* FIXME: This function should check for all possible error returns */
+   /* FIXME: Do we have to respect newStroke? */
    
+   /* Get pointer to DC */
+   pDC=DC_GetDCPtr(hdc);
+   if(pDC==NULL)
+      return FALSE;
+
    /* Get pointer to path */
    if(!PATH_GetPathFromHDC(hdc, &pPath))
       return FALSE;
@@ -626,34 +718,28 @@
    if(pPath->state!=PATH_Open)
       return FALSE;
 
+   /* FIXME: Do we have to close the current figure? */
+   
    /* Check for zero height / width */
-   /* FIXME: Should we do this before or after LPtoDP? */
+   /* FIXME: Only in GM_COMPATIBLE? */
    if(x1==x2 || y1==y2)
       return TRUE;
    
-   /* In GM_COMPATIBLE, don't include bottom and right edges */
-   if(GetGraphicsMode(hdc)==GM_COMPATIBLE)
-   {
-      /* FIXME: Should we do this before or after LPtoDP? */
-      x2--;
-      y2--;
-   }
-
    /* Convert points to device coordinates */
-   corners[0].x=x1;
-   corners[0].y=y1;
-   corners[1].x=x2;
-   corners[1].y=y2;
-   pointStart.x=xStart;
-   pointStart.y=yStart;
-   pointEnd.x=xEnd;
-   pointEnd.y=yEnd;
-   if(!LPtoDP32(hdc, corners, 2) || !LPtoDP32(hdc, &pointStart, 1) ||
-      !LPtoDP32(hdc, &pointEnd, 1))
-      return FALSE;
+   corners[0].x=(FLOAT)x1;
+   corners[0].y=(FLOAT)y1;
+   corners[1].x=(FLOAT)x2;
+   corners[1].y=(FLOAT)y2;
+   pointStart.x=(FLOAT)xStart;
+   pointStart.y=(FLOAT)yStart;
+   pointEnd.x=(FLOAT)xEnd;
+   pointEnd.y=(FLOAT)yEnd;
+   INTERNAL_LPTODP_FLOAT(pDC, corners);
+   INTERNAL_LPTODP_FLOAT(pDC, corners+1);
+   INTERNAL_LPTODP_FLOAT(pDC, &pointStart);
+   INTERNAL_LPTODP_FLOAT(pDC, &pointEnd);
 
-   /* Make sure first corner is top left and right corner is bottom right */
-   /* FIXME: Should we do this before or after LPtoDP? */
+   /* Make sure first corner is top left and second corner is bottom right */
    if(corners[0].x>corners[1].x)
    {
       temp=corners[0].x;
@@ -691,6 +777,13 @@
       }
    }
 
+   /* In GM_COMPATIBLE, don't include bottom and right edges */
+   if(GetGraphicsMode(hdc)==GM_COMPATIBLE)
+   {
+      corners[1].x--;
+      corners[1].y--;
+   }
+   
    /* Add the arc to the path with one Bezier spline per quadrant that the
     * arc spans */
    start=TRUE;
@@ -717,9 +810,9 @@
 
       /* Have we reached the last part of the arc? */
       if((GetArcDirection32(hdc)==AD_CLOCKWISE &&
-         angleEnd<=angleEndQuadrant) ||
+         angleEnd<angleEndQuadrant) ||
 	 (GetArcDirection32(hdc)==AD_COUNTERCLOCKWISE &&
-	 angleEnd>=angleEndQuadrant))
+	 angleEnd>angleEndQuadrant))
       {
 	 /* Adjust the end angle for this quadrant */
          angleEndQuadrant=angleEnd;
@@ -791,7 +884,7 @@
    /* Create a region from the strokes */
    hrgn=CreatePolyPolygonRgn32(pPath->pPoints, pNumPointsInStroke,
       numStrokes, nPolyFillMode);
-   if(hrgn==NULL)
+   if(hrgn==(HRGN32)0)
    {
       SetLastError(ERROR_NOT_ENOUGH_MEMORY);
       return FALSE;
@@ -823,10 +916,14 @@
  * or PT_BEZIERTO, optionally ORed with PT_CLOSEFIGURE. Returns TRUE if
  * successful, FALSE otherwise (e.g. if not enough memory was available).
  */
-BOOL32 PATH_AddEntry(GdiPath *pPath, POINT32 point, BYTE flags)
+BOOL32 PATH_AddEntry(GdiPath *pPath, const POINT32 *pPoint, BYTE flags)
 {
    assert(pPath!=NULL);
    
+   /* FIXME: If newStroke is true, perhaps we want to check that we're
+    * getting a PT_MOVETO
+    */
+
    /* Check that path is open */
    if(pPath->state!=PATH_Open)
       return FALSE;
@@ -836,9 +933,13 @@
       return FALSE;
 
    /* Store information in path entry */
-   pPath->pPoints[pPath->numEntriesUsed]=point;
+   pPath->pPoints[pPath->numEntriesUsed]=*pPoint;
    pPath->pFlags[pPath->numEntriesUsed]=flags;
 
+   /* If this is PT_CLOSEFIGURE, we have to start a new stroke next time */
+   if((flags & PT_CLOSEFIGURE) == PT_CLOSEFIGURE)
+      pPath->newStroke=TRUE;
+
    /* Increment entry count */
    pPath->numEntriesUsed++;
 
@@ -936,7 +1037,7 @@
  * point is added to the path; otherwise, it is assumed that the current
  * position is equal to the first control point.
  */
-static BOOL32 PATH_DoArcPart(GdiPath *pPath, POINT32 corners[],
+static BOOL32 PATH_DoArcPart(GdiPath *pPath, FLOAT_POINT corners[],
    double angleStart, double angleEnd, BOOL32 addMoveTo)
 {
    double  halfAngle, a;
@@ -950,21 +1051,30 @@
 
    /* Compute control points */
    halfAngle=(angleEnd-angleStart)/2.0;
-   a=4.0/3.0*(1-cos(halfAngle))/sin(halfAngle);
-   xNorm[0]=cos(angleStart);
-   yNorm[0]=sin(angleStart);
-   xNorm[1]=xNorm[0] - a*yNorm[0];
-   yNorm[1]=yNorm[0] + a*xNorm[0];
-   xNorm[3]=cos(angleEnd);
-   yNorm[3]=sin(angleEnd);
-   xNorm[2]=xNorm[3] + a*yNorm[3];
-   yNorm[2]=yNorm[3] - a*xNorm[3];
+   if(fabs(halfAngle)>1e-8)
+   {
+      a=4.0/3.0*(1-cos(halfAngle))/sin(halfAngle);
+      xNorm[0]=cos(angleStart);
+      yNorm[0]=sin(angleStart);
+      xNorm[1]=xNorm[0] - a*yNorm[0];
+      yNorm[1]=yNorm[0] + a*xNorm[0];
+      xNorm[3]=cos(angleEnd);
+      yNorm[3]=sin(angleEnd);
+      xNorm[2]=xNorm[3] + a*yNorm[3];
+      yNorm[2]=yNorm[3] - a*xNorm[3];
+   }
+   else
+      for(i=0; i<4; i++)
+      {
+	 xNorm[i]=cos(angleStart);
+	 yNorm[i]=sin(angleStart);
+      }
    
    /* Add starting point to path if desired */
    if(addMoveTo)
    {
       PATH_ScaleNormalizedPoint(corners, xNorm[0], yNorm[0], &point);
-      if(!PATH_AddEntry(pPath, point, PT_MOVETO))
+      if(!PATH_AddEntry(pPath, &point, PT_MOVETO))
          return FALSE;
    }
 
@@ -972,7 +1082,7 @@
    for(i=1; i<4; i++)
    {
       PATH_ScaleNormalizedPoint(corners, xNorm[i], yNorm[i], &point);
-      if(!PATH_AddEntry(pPath, point, PT_BEZIERTO))
+      if(!PATH_AddEntry(pPath, &point, PT_BEZIERTO))
          return FALSE;
    }
 
@@ -986,12 +1096,12 @@
  * coordinates (-1.0, -1.0) correspond to corners[0], the coordinates
  * (1.0, 1.0) correspond to corners[1].
  */
-static void PATH_ScaleNormalizedPoint(POINT32 corners[], double x, double y,
-   POINT32 *pPoint)
+static void PATH_ScaleNormalizedPoint(FLOAT_POINT corners[], double x,
+   double y, POINT32 *pPoint)
 {
-   pPoint->x=(INT32)floor( (double)corners[0].x +
+   pPoint->x=GDI_ROUND( (double)corners[0].x +
       (double)(corners[1].x-corners[0].x)*0.5*(x+1.0) );
-   pPoint->y=(INT32)floor( (double)corners[0].y +
+   pPoint->y=GDI_ROUND( (double)corners[0].y +
       (double)(corners[1].y-corners[0].y)*0.5*(y+1.0) );
 }
 
@@ -1000,7 +1110,8 @@
  * Normalizes a point with respect to the box whose corners are passed in
  * "corners". The normalized coordinates are stored in "*pX" and "*pY".
  */
-static void PATH_NormalizePoint(POINT32 corners[], const POINT32 *pPoint,
+static void PATH_NormalizePoint(FLOAT_POINT corners[],
+   const FLOAT_POINT *pPoint,
    double *pX, double *pY)
 {
    *pX=(double)(pPoint->x-corners[0].x)/(double)(corners[1].x-corners[0].x) *
diff --git a/graphics/win16drv/font.c b/graphics/win16drv/font.c
index 7ed9f71..fb9d1e5 100644
--- a/graphics/win16drv/font.c
+++ b/graphics/win16drv/font.c
@@ -200,8 +200,8 @@
  */
 
 
-WORD WINAPI WineEnumDFontCallback(LPLOGFONT16 lpLogFont,
-                                  LPTEXTMETRIC16 lpTextMetrics,
+WORD WINAPI WineEnumDFontCallback(LPENUMLOGFONT16 lpLogFont,
+                                  LPNEWTEXTMETRIC16 lpTextMetrics,
                                   WORD wFontType, LONG lpClientData) 
 {
     TRACE(win16drv, "In WineEnumDFontCallback plf=%p\n", lpLogFont);
diff --git a/graphics/win16drv/prtdrv.c b/graphics/win16drv/prtdrv.c
index 9a7bde1..43bb7e8 100644
--- a/graphics/win16drv/prtdrv.c
+++ b/graphics/win16drv/prtdrv.c
@@ -674,7 +674,7 @@
     if (wStyle < 0) { /* Free extra memory of given object's structure */
 	switch ( -wStyle ) {
             case DRVOBJ_PEN:    {
-                                LPLOGPEN16 DeletePen = (LPLOGPEN16)lpInObj;
+                                /* LPLOGPEN16 DeletePen = (LPLOGPEN16)lpInObj; */
 
                                 fprintf(stderr, "DRVOBJ_PEN_delete\n");
 				break;
@@ -684,8 +684,8 @@
                                 break;
 				}
             case DRVOBJ_FONT:	{
-				LPTEXTXFORM16 TextXForm
-					= (LPTEXTXFORM16)lpTextXForm;
+				/* LPTEXTXFORM16 TextXForm
+					= (LPTEXTXFORM16)lpTextXForm; */
 				fprintf(stderr, "DRVOBJ_FONT_delete\n");
                                 break;
 				}
@@ -720,7 +720,7 @@
 	    case DRVOBJ_BRUSH: {
 				LPLOGBRUSH16 InBrush  = (LPLOGBRUSH16)lpInObj;
 				LPLOGBRUSH16 OutBrush = (LPLOGBRUSH16)lpOutObj;
-                                LPPOINT16 Point = (LPPOINT16)lpTextXForm;
+                                /* LPPOINT16 Point = (LPPOINT16)lpTextXForm; */
 
 				fprintf(stderr, "DRVOBJ_BRUSH\n");
 				if (!lpOutObj) return sizeof(LOGBRUSH16);
@@ -734,8 +734,8 @@
 				}
 		               }
 	    case DRVOBJ_FONT: {
-                                LPTEXTXFORM16 TextXForm
-                                        = (LPTEXTXFORM16)lpTextXForm;
+                                /* LPTEXTXFORM16 TextXForm
+                                        = (LPTEXTXFORM16)lpTextXForm; */
                                 fprintf(stderr, "DRVOBJ_FONT\n");
 				return 0;/* DISPLAY.DRV doesn't realize fonts */
 			      }
diff --git a/graphics/wing.c b/graphics/wing.c
index da9c315..962a752 100644
--- a/graphics/wing.c
+++ b/graphics/wing.c
@@ -70,7 +70,7 @@
   __initWinG();
 
   if( __WinGOK > 0 )
-	return CreateCompatibleDC16(NULL);
+	return CreateCompatibleDC16(0);
   return (HDC16)NULL;
 }
 
diff --git a/graphics/x11drv/graphics.c b/graphics/x11drv/graphics.c
index 8442320..8874368 100644
--- a/graphics/x11drv/graphics.c
+++ b/graphics/x11drv/graphics.c
@@ -91,7 +91,7 @@
     xend   = XLPTODP( dc, xend );
     yend   = YLPTODP( dc, yend );
 
-    if ((left == right) || (top == bottom)) return FALSE;
+    if ((left == right) || (top == bottom)) return TRUE;
 
     if (left > right) { tmp=left; left=right; right=tmp; }
     if (top > bottom) { tmp=top; top=bottom; bottom=tmp; } 
diff --git a/graphics/x11drv/xfont.c b/graphics/x11drv/xfont.c
index 505f444..aaf0e20 100644
--- a/graphics/x11drv/xfont.c
+++ b/graphics/x11drv/xfont.c
@@ -460,8 +460,8 @@
      char *s;
      sprintf(h_string, "[%+f%+f%+f%+f]", h_matrix[0], h_matrix[1], h_matrix[2], h_matrix[3]);
      sprintf(point_string, "[%+f%+f%+f%+f]", point_matrix[0], point_matrix[1], point_matrix[2], point_matrix[3]);
-     while (s = strchr(h_string, '-')) *s='~';
-     while (s = strchr(point_string, '-')) *s='~';
+     while ((s = strchr(h_string, '-'))) *s='~';
+     while ((s = strchr(point_string, '-'))) *s='~';
    } else {
      sprintf(h_string, "%d", h);
      sprintf(point_string, "%d", point);
diff --git a/if1632/builtin.c b/if1632/builtin.c
index c06d91c..74fdbd6 100644
--- a/if1632/builtin.c
+++ b/if1632/builtin.c
@@ -186,6 +186,7 @@
     NE_MODULE *pModule;
     WORD vector;
     HMODULE16 hModule;
+    WORD cs, ds;
 
     fnBUILTIN_LoadModule = BUILTIN_LoadModule;
 
@@ -197,9 +198,9 @@
 
     /* Set the USER and GDI heap selectors */
 
-    pModule      = MODULE_GetPtr16( GetModuleHandle16( "USER" ));
+    pModule      = NE_GetPtr( GetModuleHandle16( "USER" ));
     USER_HeapSel = (NE_SEG_TABLE( pModule ) + pModule->dgroup - 1)->selector;
-    pModule      = MODULE_GetPtr16( GetModuleHandle16( "GDI" ));
+    pModule      = NE_GetPtr( GetModuleHandle16( "GDI" ));
     GDI_HeapSel  = (NE_SEG_TABLE( pModule ) + pModule->dgroup - 1)->selector;
 
     /* Initialize KERNEL.178 (__WINFLAGS) with the correct flags value */
@@ -207,6 +208,12 @@
     hModule = GetModuleHandle16( "KERNEL" );
     NE_SetEntryPoint( hModule, 178, GetWinFlags() );
 
+    /* Initialize KERNEL.454/455 (__FLATCS/__FLATDS) */
+
+    GET_CS(cs); GET_DS(ds);
+    NE_SetEntryPoint( hModule, 454, cs );
+    NE_SetEntryPoint( hModule, 455, ds );
+  
     /* Initialize the real-mode selector entry points */
 
 #define SET_ENTRY_POINT( num, addr ) \
@@ -247,7 +254,7 @@
  * Load a built-in module. If the 'force' parameter is FALSE, we only
  * load the module if it has not been disabled via the -dll option.
  */
-HMODULE32 BUILTIN_LoadModule( LPCSTR name, BOOL32 force )
+HMODULE16 BUILTIN_LoadModule( LPCSTR name, BOOL32 force )
 {
     BUILTIN16_DLL *table;
     char dllname[16], *p;
@@ -260,8 +267,7 @@
 
     for (table = BuiltinDLLs; table->descr; table++)
         if (!lstrcmpi32A( table->descr->name, dllname )) break;
-    if (!table->descr) return BUILTIN32_LoadModule( name, force,
-                                                    PROCESS_Current() );
+    if (!table->descr) return 0;
     if ((table->flags & DLL_FLAG_NOT_USED) && !force) return 0;
 
     return BUILTIN_DoLoadModule16( table->descr );
@@ -281,7 +287,7 @@
     register BYTE *p;
     NE_MODULE *pModule;
 
-    if (!(pModule = MODULE_GetPtr16( FarGetOwner( GlobalHandle16(cs) ))))
+    if (!(pModule = NE_GetPtr( FarGetOwner( GlobalHandle16(cs) ))))
         return NULL;
 
     /* Search for the ordinal */
diff --git a/if1632/commdlg.spec b/if1632/commdlg.spec
index 01c97ae..7e0a3ba 100644
--- a/if1632/commdlg.spec
+++ b/if1632/commdlg.spec
@@ -3,7 +3,7 @@
 
 1   pascal16 GetOpenFileName(segptr) GetOpenFileName16
 2   pascal16 GetSaveFileName(segptr) GetSaveFileName16
-5   pascal16 ChooseColor(ptr) ChooseColor
+5   pascal16 ChooseColor(ptr) ChooseColor16
 6   pascal   FileOpenDlgProc(word word word long) FileOpenDlgProc
 7   pascal   FileSaveDlgProc(word word word long) FileSaveDlgProc
 8   pascal   ColorDlgProc(word word word long) ColorDlgProc
diff --git a/if1632/ddeml.spec b/if1632/ddeml.spec
index 30498d1..34aa4f9 100644
--- a/if1632/ddeml.spec
+++ b/if1632/ddeml.spec
@@ -4,7 +4,7 @@
 2 pascal16 DdeInitialize(ptr segptr long long) DdeInitialize16
 3 pascal16 DdeUninitialize(long) DdeUninitialize16
 4 pascal DdeConnectList(long word word word ptr) DdeConnectList16
-5 pascal DdeQueryNextServer(word word) DdeQueryNextServer
+5 pascal DdeQueryNextServer(word word) DdeQueryNextServer16
 6 pascal DdeDisconnectList(word) DdeDisconnectList16
 7 pascal   DdeConnect(long long long ptr) DdeConnect16
 8 pascal16 DdeDisconnect(long) DdeDisconnect16
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index 8a82169..ad451d3 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -202,7 +202,7 @@
 200 return ValidateFreeSpaces 0 0
 201 stub ReplaceInst
 202 stub RegisterPtrace
-203 register DebugBreak() DebugBreak16
+203 register DebugBreak() DebugBreak
 204 stub SwapRecording
 205 stub CVWBreak
 206 pascal16 AllocSelectorArray(word) AllocSelectorArray
@@ -277,9 +277,9 @@
 354 pascal   GetAppCompatFlags(word) GetAppCompatFlags16
 355 pascal16 GetWinDebugInfo(ptr word) GetWinDebugInfo
 356 pascal16 SetWinDebugInfo(ptr) SetWinDebugInfo
-357 stub KERNEL_357
+357 pascal MapSL(segptr) MapSL
 358 pascal MapLS(long) MapLS
-359 pascal UnMapLS(ptr) UnMapLS
+359 pascal UnMapLS(segptr) UnMapLS
 360 stub OpenFileEx
 #361 PIGLET_361
 365 stub KERNEL_365
@@ -311,15 +311,15 @@
 447 stub KERNEL_447
 449 pascal KERNEL_449() KERNEL_449
 450 pascal16 KERNEL_450() stub_KERNEL_450
-454 stub KERNEL_454
-455 stub KERNEL_455
+454 equate __FLATCS 0   # initialized by BUILTIN_Init()
+455 equate __FLATDS 0   # initialized by BUILTIN_Init()
 471 pascal KERNEL_471() _KERNEL_471
 472 register KERNEL_472() _KERNEL_472
 473 stub KERNEL_473
-475 stub KERNEL_475
+475 return KERNEL_475 0 0
 480 stub KERNEL_480
 481 stub KERNEL_481
-482 stub KERNEL_482
+482 pascal LoadLibrary32(str) LoadLibrary32A
 485 stub KERNEL_485
 491 stub RegisterServiceProcess
 500 stub KERNEL_500
@@ -346,16 +346,16 @@
 604 stub KERNEL_604
 605 stub KERNEL_605
 606 stub KERNEL_606
-607 stub KERNEL_607
-608 stub KERNEL_608
-611 stub KERNEL_611
+607 pascal KERNEL_607(long long long) _KERNEL_607
+608 pascal KERNEL_608(long long long) _KERNEL_608
+611 pascal KERNEL_611(long long) _KERNEL_611
 612 stub KERNEL_612
 613 stub KERNEL_613
 614 stub KERNEL_614
 619 pascal KERNEL_619(word long long) _KERNEL_619
 621 stub KERNEL_621
 627 stub IsBadFlatReadWritePtr
-630 stub KERNEL_630
-631 register FUNC004(word word word) FUNC004	#C16ThkSl01?
-651 stub KERNEL_651				#ThunkConnect16?
+630 register C16ThkSL() C16ThkSL
+631 register C16ThkSL01() C16ThkSL01
+651 pascal ThunkConnect16(str str word long ptr str word) ThunkConnect16
 700 pascal KERNEL_700() stub_KERNEL_700
diff --git a/if1632/signal.c b/if1632/signal.c
index e07d41a..9c22d82 100644
--- a/if1632/signal.c
+++ b/if1632/signal.c
@@ -86,6 +86,7 @@
  *
  * Set the register values from a sigcontext. 
  */
+#ifdef UNUSED_FUNCTIONS
 static void SIGNAL_SetSigContext( const SIGCONTEXT *sigcontext,
                                   CONTEXT *context )
 {
@@ -116,6 +117,7 @@
     GS_reg(context) &= 0xffff;
 #endif
 }
+#endif
 
 
 /***********************************************************************
@@ -123,6 +125,7 @@
  *
  * Build a sigcontext from the register values.
  */
+#ifdef UNUSED_FUNCTIONS
 static void SIGNAL_GetSigContext( SIGCONTEXT *sigcontext,
                                   const CONTEXT *context )
 {
@@ -151,6 +154,7 @@
     SET_GS( GS_reg(&DEBUG_context) );
 #endif
 }
+#endif
 
 
 /***********************************************************************
diff --git a/include/acconfig.h b/include/acconfig.h
index 45489fd..20faa2f 100644
--- a/include/acconfig.h
+++ b/include/acconfig.h
@@ -26,3 +26,15 @@
 
 /* Define if the struct statfs has the member bfree */
 #undef STATFS_HAS_BFREE
+
+/* Define if we have a working sigaltstack */
+#undef HAVE_WORKING_SIGALTSTACK
+
+/* Define if the struct statfs is defined by <sys/vfs.h> */
+#undef STATFS_DEFINED_BY_SYS_VFS
+
+/* Define if the struct statfs is defined by <sys/statfs.h> */
+#undef STATFS_DEFINED_BY_SYS_STATFS
+
+/* Define if the struct statfs is defined by <sys/mount.h> */
+#undef STATFS_DEFINED_BY_SYS_MOUNT
diff --git a/include/commctrl.h b/include/commctrl.h
index 2ed95f6..a2670e8 100644
--- a/include/commctrl.h
+++ b/include/commctrl.h
@@ -9,6 +9,30 @@
 
 void WINAPI InitCommonControls(void);
 
+typedef struct tagINITCOMMONCONTROLSEX {
+    DWORD dwSize;
+    DWORD dwICC;
+} INITCOMMONCONTROLSEX, *LPINITCOMMONCONTROLSEX;
+
+BOOL32 WINAPI InitCommonControlsEx(LPINITCOMMONCONTROLSEX);
+
+#define ICC_LISTVIEW_CLASSES   0x00000001  /* listview, header */
+#define ICC_TREEVIEW_CLASSES   0x00000002  /* treeview, tooltips */
+#define ICC_BAR_CLASSES        0x00000004  /* toolbar, statusbar, trackbar, tooltips */
+#define ICC_TAB_CLASSES        0x00000008  /* tab, tooltips */
+#define ICC_UPDOWN_CLASS       0x00000010  /* updown */
+#define ICC_PROGRESS_CLASS     0x00000020  /* progress */
+#define ICC_HOTKEY_CLASS       0x00000040  /* hotkey */
+#define ICC_ANIMATE_CLASS      0x00000080  /* animate */
+#define ICC_WIN95_CLASSES      0x000000FF
+#define ICC_DATE_CLASSES       0x00000100  /* month picker, date picker, time picker, updown */
+#define ICC_USEREX_CLASSES     0x00000200  /* comboex */
+#define ICC_COOL_CLASSES       0x00000400  /* rebar (coolbar) */
+#define ICC_INTERNET_CLASSES   0x00000800  /* IP address, ... */
+#define ICC_PAGESCROLLER_CLASS 0x00001000  /* page scroller */
+#define ICC_NATIVEFNTCTL_CLASS 0x00002000  /* native font control ???*/
+
+
 /* common control styles */
 
 #define CCS_TOP             0x00000001L
@@ -25,10 +49,31 @@
 
 
 /* common control shared messages */
-
 #define CCM_FIRST           0x2000
 
-#define CCM_SETBKCOLOR      (CCM_FIRST+1)     // lParam = bkColor
+#define CCM_SETBKCOLOR      (CCM_FIRST+1)     /* lParam = bkColor */
+
+
+/* common notification codes */
+#define NM_FIRST             (0U-0U)
+#define NM_LAST              (0U-99U)
+
+#define NM_OUTOFMEMORY       (NM_FIRST-1)
+#define NM_CLICK             (NM_FIRST-2)
+#define NM_DBLCLK            (NM_FIRST-3)
+#define NM_RETURN            (NM_FIRST-4)
+#define NM_RCLICK            (NM_FIRST-5)
+#define NM_RDBLCLK           (NM_FIRST-6)
+#define NM_SETFOCUS          (NM_FIRST-7)
+#define NM_KILLFOCUS         (NM_FIRST-8)
+#define NM_CUSTOMDRAW        (NM_FIRST-12)
+#define NM_HOVER             (NM_FIRST-13)
+#define NM_NCHITTEST         (NM_FIRST-14)
+#define NM_KEYDOWN           (NM_FIRST-15)
+#define NM_RELEASEDCAPTURE   (NM_FIRST-16)
+#define NM_SETCURSOR         (NM_FIRST-17)
+#define NM_CHAR              (NM_FIRST-18)
+#define NM_TOOLTIPSCREATED   (NM_FIRST-19)
 
 
 /* StatusWindow */
@@ -54,14 +99,26 @@
 #define SB_SETMINHEIGHT       (WM_USER+8)
 #define SB_SIMPLE             (WM_USER+9)
 #define SB_GETRECT            (WM_USER+10)
+#define SB_ISSIMPLE           (WM_USER+14)
+#define SB_SETICON            (WM_USER+15)
+#define SB_GETICON            (WM_USER+20)
+#define SB_SETBKCOLOR         CCM_SETBKCOLOR   /* lParam = bkColor */
 
 #define SBT_NOBORDERS         0x0100
 #define SBT_POPOUT            0x0200
-#define SBT_RTLREADING        0x0400
+#define SBT_RTLREADING        0x0400  /* not supported */
 #define SBT_OWNERDRAW         0x1000
 
 #define SBARS_SIZEGRIP        0x0100
 
+#define SBN_FIRST             (0U-880U)
+#define SBN_LAST              (0U-899U)
+#define SBN_SIMPLEMODECHANGE  (SBN_FIRST-0)
+
+void WINAPI MenuHelp (UINT32, WPARAM32, LPARAM, HMENU32,
+                      HINSTANCE32, HWND32, LPUINT32);
+
+
 /* UpDown */
 
 #define UPDOWN_CLASS16        "msctls_updown"
@@ -200,22 +257,22 @@
 
 
 typedef struct _IMAGELISTDRAWPARAMS
-{ 
-    DWORD       cbSize; 
-    HIMAGELIST  himl; 
-    INT32       i; 
-    HDC32       hdcDst; 
-    INT32       x; 
-    INT32       y; 
-    INT32       cx; 
-    INT32       cy; 
-    INT32       xBitmap;        // x offest from the upperleft of bitmap 
-    INT32       yBitmap;        // y offset from the upperleft of bitmap 
-    COLORREF    rgbBk; 
-    COLORREF    rgbFg; 
-    UINT32      fStyle; 
-    DWORD       dwRop; 
-} IMAGELISTDRAWPARAMS, *LPIMAGELISTDRAWPARAMS; 
+{
+    DWORD       cbSize;
+    HIMAGELIST  himl;
+    INT32       i;
+    HDC32       hdcDst;
+    INT32       x;
+    INT32       y;
+    INT32       cx;
+    INT32       cy;
+    INT32       xBitmap;  /* x offest from the upperleft of bitmap */
+    INT32       yBitmap;  /* y offset from the upperleft of bitmap */
+    COLORREF    rgbBk;
+    COLORREF    rgbFg;
+    UINT32      fStyle;
+    DWORD       dwRop;
+} IMAGELISTDRAWPARAMS, *LPIMAGELISTDRAWPARAMS;
 
  
 INT32      WINAPI ImageList_Add(HIMAGELIST,HBITMAP32,HBITMAP32);
@@ -265,4 +322,144 @@
 #define ImageList_RemoveAll(himl) ImageList_Remove(himl,-1)
 
 
+/* Header control */
+
+#define WC_HEADER16    "SysHeader" 
+#define WC_HEADER32A   "SysHeader32" 
+#define WC_HEADER32W  L"SysHeader32" 
+
+#define WC_HEADER     WINELIB_NAME_AW(WC_HEADER)
+ 
+#define HDS_HORZ                0x0000 
+#define HDS_BUTTONS             0x0002 
+#define HDS_HOTTRACK            0x0004 
+#define HDS_HIDDEN              0x0008 
+#define HDS_DRAGDROP            0x0040 
+#define HDS_FULLDRAG            0x0080 
+
+#define HDI_WIDTH               0x0001
+#define HDI_HEIGHT              HDI_WIDTH
+#define HDI_TEXT                0x0002
+#define HDI_FORMAT              0x0004
+#define HDI_LPARAM              0x0008
+#define HDI_BITMAP              0x0010
+#define HDI_IMAGE               0x0020
+#define HDI_DI_SETITEM          0x0040
+#define HDI_ORDER               0x0080
+
+#define HDF_LEFT                0x0000
+#define HDF_RIGHT               0x0001
+#define HDF_CENTER              0x0002
+#define HDF_JUSTIFYMASK         0x0003
+
+#define HDF_IMAGE               0x0800
+#define HDF_BITMAP_ON_RIGHT     0x1000
+#define HDF_BITMAP              0x2000
+#define HDF_STRING              0x4000
+#define HDF_OWNERDRAW           0x8000
+
+#define HHT_NOWHERE             0x0001
+#define HHT_ONHEADER            0x0002
+#define HHT_ONDIVIDER           0x0004
+#define HHT_ONDIVOPEN           0x0008
+#define HHT_ABOVE               0x0100
+#define HHT_BELOW               0x0200
+#define HHT_TORIGHT             0x0400
+#define HHT_TOLEFT              0x0800
+
+#define HDM_FIRST               0x1200
+#define HDM_GETITEMCOUNT        (HDM_FIRST+0)
+#define HDM_INSERTITEM32A       (HDM_FIRST+1)
+#define HDM_INSERTITEM32W       (HDM_FIRST+10)
+#define HDM_INSERTITEM WINELIB_NAME_AW(HDM_INSERTITEM)
+#define HDM_DELETEITEM          (HDM_FIRST+2)
+#define HDM_GETITEM32A          (HDM_FIRST+3)
+#define HDM_GETITEM32W          (HDM_FIRST+11)
+#define HDM_GETITEM WINELIB_NAME_AW(HDM_GETITEM)
+#define HDM_SETITEM32A          (HDM_FIRST+4)
+#define HDM_SETITEM32W          (HDM_FIRST+12)
+#define HDM_SETITEM WINELIB_NAME_AW(HDM_SETITEM)
+#define HDM_LAYOUT              (HDM_FIRST+5)
+#define HDM_HITTEST             (HDM_FIRST+6)
+#define HDM_GETITEMRECT         (HDM_FIRST+7)
+#define HDM_SETIMAGELIST        (HDM_FIRST+8)
+#define HDM_GETIMAGELIST        (HDM_FIRST+9)
+
+
+#define HDM_ORDERTOINDEX        (HDM_FIRST+15)
+#define HDM_CREATEDRAGIMAGE     (HDM_FIRST+16)
+#define HDM_GETORDERARRAY       (HDM_FIRST+17)
+#define HDM_SETORDERARRAY       (HDM_FIRST+18)
+#define HDM_SETHOTDIVIDER       (HDM_FIRST+19)
+
+#define HDN_FIRST               (0U-300U)
+#define HDN_LAST                (0U-399U)
+#define HDN_ITEMCHANGING32A     (HDN_FIRST-0)
+#define HDN_ITEMCHANGING32W     (HDN_FIRST-20)
+#define HDN_ITEMCHANGED32A      (HDN_FIRST-1)
+#define HDN_ITEMCHANGED32W      (HDN_FIRST-21)
+#define HDN_ITEMCLICK32A        (HDN_FIRST-2)
+#define HDN_ITEMCLICK32W        (HDN_FIRST-22)
+#define HDN_ITEMDBLCLICK32A     (HDN_FIRST-3)
+#define HDN_ITEMDBLCLICK32W     (HDN_FIRST-23)
+#define HDN_DIVIDERDBLCLICK32A  (HDN_FIRST-5)
+#define HDN_DIVIDERDBLCLICK32W  (HDN_FIRST-25)
+#define HDN_BEGINTRACK32A       (HDN_FIRST-6)
+#define HDN_BEGINTRACK32W       (HDN_FIRST-26)
+#define HDN_ENDTRACK32A         (HDN_FIRST-7)
+#define HDN_ENDTRACK32W         (HDN_FIRST-27)
+#define HDN_TRACK32A            (HDN_FIRST-8)
+#define HDN_TRACK32W            (HDN_FIRST-28)
+#define HDN_GETDISPINFO32A      (HDN_FIRST-9)
+#define HDN_GETDISPINFO32W      (HDN_FIRST-29)
+#define HDN_BEGINDRACK          (HDN_FIRST-10)
+#define HDN_ENDDRACK            (HDN_FIRST-11)
+
+
+#define Header_Layout(hwndHD,playout) \
+  (BOOL32)SendMessage32A((hwndHD),HDM_LAYOUT,0,(LPARAM)(LPHDLAYOUT)(playout))
+
+
+typedef struct _HD_LAYOUT
+{
+    RECT32      *prc;
+    WINDOWPOS32 *pwpos;
+} HDLAYOUT, *LPHDLAYOUT;
+
+#define HD_LAYOUT   HDLAYOUT
+
+
+typedef struct _HD_ITEMA
+{
+    UINT32    mask;
+    INT32     cxy;
+    LPSTR     pszText;
+    HBITMAP32 hbm;
+    INT32     cchTextMax;
+    INT32     fmt;
+    LPARAM    lParam;
+    INT32     iImage;
+    INT32     iOrder;
+} HD_ITEMA;
+
+
+typedef struct _HD_HITTESTINFO
+{
+    POINT32 pt;
+    UINT32  flags;
+    INT32   iItem;
+} HDHITTESTINFO, *LPHDHITTESTINFO;
+
+#define HD_HITTESTINFO   HDHITTESTINFO
+
+
+typedef struct tagNMHEADERA
+{
+    NMHDR    hdr;
+    INT32    iItem;
+    INT32    iButton;
+    HD_ITEMA *pitem;
+} NMHEADERA, *LPNMHEADERA;
+
+
 #endif  /* __WINE_COMMCTRL_H */
diff --git a/include/commdlg.h b/include/commdlg.h
index 7edc7ba..b0cbfdd 100644
--- a/include/commdlg.h
+++ b/include/commdlg.h
@@ -116,6 +116,8 @@
 DECL_WINELIB_TYPE_AW(OPENFILENAME);
 DECL_WINELIB_TYPE_AW(LPOPENFILENAME);
 
+typedef UINT32 (CALLBACK *LPCCHOOKPROC) (HWND32, UINT32, WPARAM32, LPARAM);
+
 typedef struct {
 	DWORD		lStructSize;
 	HWND16		hwndOwner;
@@ -126,8 +128,38 @@
 	LPARAM		lCustData;
         WNDPROC16       lpfnHook;
 	SEGPTR 		lpTemplateName;
-} CHOOSECOLOR;
-typedef CHOOSECOLOR *LPCHOOSECOLOR;
+} CHOOSECOLOR16;
+typedef CHOOSECOLOR16 *LPCHOOSECOLOR16;
+
+typedef struct {
+	DWORD		lStructSize;
+	HWND32		hwndOwner;
+	HWND32		hInstance;
+	DWORD	        rgbResult;
+	LPDWORD         lpCustColors;
+	DWORD 		Flags;
+	DWORD		lCustData;
+        LPCCHOOKPROC    lpfnHook;
+	LPCSTR 		lpTemplateName;
+} CHOOSECOLOR32A;
+typedef CHOOSECOLOR32A *LPCHOOSECOLOR32A;
+
+typedef struct {
+	DWORD		lStructSize;
+	HWND32		hwndOwner;
+	HWND32		hInstance;
+	DWORD	        rgbResult;
+	LPDWORD         *lpCustColors;
+	DWORD 		Flags;
+	DWORD		lCustData;
+        LPCCHOOKPROC    lpfnHook;
+	LPCWSTR 	lpTemplateName;
+} CHOOSECOLOR32W;
+typedef CHOOSECOLOR32W *LPCHOOSECOLOR32W;
+
+DECL_WINELIB_TYPE_AW(CHOOSECOLOR);
+DECL_WINELIB_TYPE_AW(LPCHOOSECOLOR);
+
 
 #define CC_RGBINIT               0x00000001
 #define CC_FULLOPEN              0x00000002
@@ -230,6 +262,7 @@
 							/* CF_LIMITSIZE is used      */
 } CHOOSEFONT16, *LPCHOOSEFONT16;
 
+
 typedef struct
 {
 	UINT32  	lStructSize; 
@@ -452,7 +485,10 @@
 #define CDERR_NOHOOK           0x000B
 #define CDERR_REGISTERMSGFAIL  0x000C
 
-BOOL16  WINAPI ChooseColor(LPCHOOSECOLOR lpChCol);
+BOOL16  WINAPI ChooseColor16(LPCHOOSECOLOR16 lpChCol);
+BOOL32  WINAPI ChooseColor32A(LPCHOOSECOLOR32A lpChCol);
+BOOL32  WINAPI ChooseColor32W(LPCHOOSECOLOR32W lpChCol);
+#define ChooseColor WINELIB_NAME_AW(ChooseColor)
 DWORD   WINAPI CommDlgExtendedError(void);
 HWND16  WINAPI FindText16( SEGPTR find);
 HWND32  WINAPI FindText32A(LPFINDREPLACE32A lpFind);
diff --git a/include/config.h.in b/include/config.h.in
index 26f0a8f..1642cb4 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -39,6 +39,18 @@
 /* Define if the struct statfs has the member bfree */
 #undef STATFS_HAS_BFREE
 
+/* Define if we have a working sigaltstack */
+#undef HAVE_WORKING_SIGALTSTACK
+
+/* Define if the struct statfs is defined by <sys/vfs.h> */
+#undef STATFS_DEFINED_BY_SYS_VFS
+
+/* Define if the struct statfs is defined by <sys/statfs.h> */
+#undef STATFS_DEFINED_BY_SYS_STATFS
+
+/* Define if the struct statfs is defined by <sys/mount.h> */
+#undef STATFS_DEFINED_BY_SYS_MOUNT
+
 /* The number of bytes in a long long.  */
 #undef SIZEOF_LONG_LONG
 
diff --git a/include/dc.h b/include/dc.h
index f04a318..ea1a393 100644
--- a/include/dc.h
+++ b/include/dc.h
@@ -21,6 +21,7 @@
 extern BOOL32 DC_SetupGCForBrush( DC * dc );
 extern BOOL32 DC_SetupGCForPen( DC * dc );
 extern BOOL32 DC_SetupGCForText( DC * dc );
+extern void DC_UpdateXforms( DC * dc );
 
 extern const int DC_XROPfunction[];
 
diff --git a/include/debug.h b/include/debug.h
index 6c6289c..e9e1b33 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -19,102 +19,105 @@
 #define dbch_clipping 11
 #define dbch_combo 12
 #define dbch_comm 13
-#define dbch_commdlg 14
-#define dbch_console 15
-#define dbch_crtdll 16
-#define dbch_cursor 17
-#define dbch_dc 18
-#define dbch_dde 19
-#define dbch_ddeml 20
-#define dbch_ddraw 21
-#define dbch_debug 22
-#define dbch_dialog 23
-#define dbch_dll 24
-#define dbch_dosfs 25
-#define dbch_dosmem 26
-#define dbch_driver 27
-#define dbch_dsound 28
-#define dbch_edit 29
-#define dbch_event 30
-#define dbch_exec 31
-#define dbch_file 32
-#define dbch_fixup 33
-#define dbch_font 34
-#define dbch_gdi 35
-#define dbch_global 36
-#define dbch_graphics 37
-#define dbch_heap 38
-#define dbch_hook 39
-#define dbch_icon 40
-#define dbch_imagelist 41
-#define dbch_int 42
-#define dbch_int21 43
-#define dbch_int31 44
-#define dbch_key 45
-#define dbch_keyboard 46
-#define dbch_ldt 47
-#define dbch_listbox 48
-#define dbch_local 49
-#define dbch_mci 50
-#define dbch_mcianim 51
-#define dbch_mciwave 52
-#define dbch_mdi 53
-#define dbch_menu 54
-#define dbch_message 55
-#define dbch_metafile 56
-#define dbch_midi 57
-#define dbch_mmaux 58
-#define dbch_mmio 59
-#define dbch_mmsys 60
-#define dbch_mmtime 61
-#define dbch_module 62
-#define dbch_mpr 63
-#define dbch_msg 64
-#define dbch_nonclient 65
-#define dbch_ntdll 66
-#define dbch_ole 67
-#define dbch_palette 68
-#define dbch_print 69
-#define dbch_profile 70
-#define dbch_progress 71
-#define dbch_prop 72
-#define dbch_reg 73
-#define dbch_region 74
-#define dbch_relay 75
-#define dbch_resource 76
-#define dbch_scroll 77
-#define dbch_security 78
-#define dbch_segment 79
-#define dbch_selector 80
-#define dbch_sem 81
-#define dbch_sendmsg 82
-#define dbch_shell 83
-#define dbch_shm 84
-#define dbch_sound 85
-#define dbch_static 86
-#define dbch_stress 87
-#define dbch_string 88
-#define dbch_system 89
-#define dbch_task 90
-#define dbch_text 91
-#define dbch_thread 92
-#define dbch_thunk 93
-#define dbch_timer 94
-#define dbch_toolhelp 95
-#define dbch_tweak 96
-#define dbch_uitools 97
-#define dbch_updown 98
-#define dbch_ver 99
-#define dbch_virtual 100
-#define dbch_vxd 101
-#define dbch_win 102
-#define dbch_win16drv 103
-#define dbch_win32 104
-#define dbch_wing 105
-#define dbch_winsock 106
-#define dbch_wnet 107
-#define dbch_x11 108
-#define dbch_x11drv 109
+#define dbch_commctrl 14
+#define dbch_commdlg 15
+#define dbch_console 16
+#define dbch_crtdll 17
+#define dbch_cursor 18
+#define dbch_dc 19
+#define dbch_dde 20
+#define dbch_ddeml 21
+#define dbch_ddraw 22
+#define dbch_debug 23
+#define dbch_dialog 24
+#define dbch_dll 25
+#define dbch_dosfs 26
+#define dbch_dosmem 27
+#define dbch_driver 28
+#define dbch_dsound 29
+#define dbch_edit 30
+#define dbch_event 31
+#define dbch_exec 32
+#define dbch_file 33
+#define dbch_fixup 34
+#define dbch_font 35
+#define dbch_gdi 36
+#define dbch_global 37
+#define dbch_graphics 38
+#define dbch_header 39
+#define dbch_heap 40
+#define dbch_hook 41
+#define dbch_icon 42
+#define dbch_imagelist 43
+#define dbch_int 44
+#define dbch_int21 45
+#define dbch_int31 46
+#define dbch_key 47
+#define dbch_keyboard 48
+#define dbch_ldt 49
+#define dbch_listbox 50
+#define dbch_local 51
+#define dbch_mci 52
+#define dbch_mcianim 53
+#define dbch_mciwave 54
+#define dbch_mdi 55
+#define dbch_menu 56
+#define dbch_message 57
+#define dbch_metafile 58
+#define dbch_midi 59
+#define dbch_mmaux 60
+#define dbch_mmio 61
+#define dbch_mmsys 62
+#define dbch_mmtime 63
+#define dbch_module 64
+#define dbch_mpr 65
+#define dbch_msg 66
+#define dbch_nonclient 67
+#define dbch_ntdll 68
+#define dbch_ole 69
+#define dbch_palette 70
+#define dbch_print 71
+#define dbch_profile 72
+#define dbch_progress 73
+#define dbch_prop 74
+#define dbch_reg 75
+#define dbch_region 76
+#define dbch_relay 77
+#define dbch_resource 78
+#define dbch_scroll 79
+#define dbch_security 80
+#define dbch_segment 81
+#define dbch_selector 82
+#define dbch_sem 83
+#define dbch_sendmsg 84
+#define dbch_shell 85
+#define dbch_shm 86
+#define dbch_sound 87
+#define dbch_static 88
+#define dbch_status 89
+#define dbch_stress 90
+#define dbch_string 91
+#define dbch_system 92
+#define dbch_task 93
+#define dbch_text 94
+#define dbch_thread 95
+#define dbch_thunk 96
+#define dbch_timer 97
+#define dbch_toolhelp 98
+#define dbch_tweak 99
+#define dbch_uitools 100
+#define dbch_updown 101
+#define dbch_ver 102
+#define dbch_virtual 103
+#define dbch_vxd 104
+#define dbch_win 105
+#define dbch_win16drv 106
+#define dbch_win32 107
+#define dbch_wing 108
+#define dbch_winsock 109
+#define dbch_wnet 110
+#define dbch_x11 111
+#define dbch_x11drv 112
 /* Definitions for classes identifiers */
 #define dbcl_fixme 0
 #define dbcl_err 1
diff --git a/include/debugdefs.h b/include/debugdefs.h
index 2b8f5fc..ea98744 100644
--- a/include/debugdefs.h
+++ b/include/debugdefs.h
@@ -4,7 +4,7 @@
 #include "debugtools.h"
 #endif
 
-#define DEBUG_CHANNEL_COUNT 110
+#define DEBUG_CHANNEL_COUNT 113
 #ifdef DEBUG_RUNTIME
 short debug_msg_enabled[][DEBUG_CLASS_COUNT] = {
 {1, 1, 0, 0},
@@ -117,6 +117,9 @@
 {1, 1, 0, 0},
 {1, 1, 0, 0},
 {1, 1, 0, 0},
+{1, 1, 0, 0},
+{1, 1, 0, 0},
+{1, 1, 0, 0},
 };
 const char* debug_ch_name[] = {
 "accel",
@@ -133,6 +136,7 @@
 "clipping",
 "combo",
 "comm",
+"commctrl",
 "commdlg",
 "console",
 "crtdll",
@@ -157,6 +161,7 @@
 "gdi",
 "global",
 "graphics",
+"header",
 "heap",
 "hook",
 "icon",
@@ -206,6 +211,7 @@
 "shm",
 "sound",
 "static",
+"status",
 "stress",
 "string",
 "system",
diff --git a/include/gdi.h b/include/gdi.h
index 4ea7c7b..07ab5a2 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -12,6 +12,7 @@
 #include "local.h"
 #include "x11drv.h"
 #include "path.h"
+#include <math.h>
 
   /* GDI objects magic numbers */
 #define PEN_MAGIC             0x4f47
@@ -132,10 +133,10 @@
     INT32         CursPosX;          /* Current position */
     INT32         CursPosY;
     INT32         ArcDirection;
-    BOOL32        UseWorldXform;     /* Should we use the world transform? */
-                                     /* (i.e. is it not equal to the       */
-				     /* identity transformation?)          */
-    XFORM         WorldXform;        /* World transform */
+    XFORM         xformWorld2Wnd;    /* World-to-window transformation */
+    XFORM         xformWorld2Vport;  /* World-to-viewport transformation */
+    XFORM         xformVport2World;  /* Inverse of the above transformation */
+    BOOL32        vport2WorldValid;  /* Is xformVport2World valid? */
 } WIN_DC_INFO;
 
 typedef X11DRV_PDEVICE X_DC_INFO;  /* Temporary */
@@ -283,6 +284,100 @@
 
   /* Device <-> logical coords conversion */
 
+/* A floating point version of the POINT structure */
+typedef struct tagFLOAT_POINT
+{
+   FLOAT x, y;
+} FLOAT_POINT;
+
+/* Rounds a floating point number to integer. The world-to-viewport
+ * transformation process is done in floating point internally. This function
+ * is then used to round these coordinates to integer values.
+ */
+static __inline__ INT32 GDI_ROUND(FLOAT val)
+{
+   return (int)floor(val + 0.5);
+}
+
+/* Performs a viewport-to-world transformation on the specified point (which
+ * is in floating point format). Returns TRUE if successful, else FALSE.
+ */
+static __inline__ BOOL32 INTERNAL_DPTOLP_FLOAT(DC *dc, FLOAT_POINT *point)
+{
+    FLOAT x, y;
+    
+    /* Check that the viewport-to-world transformation is valid */
+    if (!dc->w.vport2WorldValid)
+        return FALSE;
+
+    /* Perform the transformation */
+    x = point->x;
+    y = point->y;
+    point->x = x * dc->w.xformVport2World.eM11 +
+               y * dc->w.xformVport2World.eM21 +
+	       dc->w.xformVport2World.eDx;
+    point->y = x * dc->w.xformVport2World.eM12 +
+               y * dc->w.xformVport2World.eM22 +
+	       dc->w.xformVport2World.eDy;
+
+    return TRUE;
+}
+
+/* Performs a viewport-to-world transformation on the specified point (which
+ * is in integer format). Returns TRUE if successful, else FALSE.
+ */
+static __inline__ BOOL32 INTERNAL_DPTOLP(DC *dc, LPPOINT32 point)
+{
+    FLOAT_POINT floatPoint;
+    
+    /* Perform operation with floating point */
+    floatPoint.x=(FLOAT)point->x;
+    floatPoint.y=(FLOAT)point->y;
+    if (!INTERNAL_DPTOLP_FLOAT(dc, &floatPoint))
+        return FALSE;
+    
+    /* Round to integers */
+    point->x = GDI_ROUND(floatPoint.x);
+    point->y = GDI_ROUND(floatPoint.y);
+
+    return TRUE;
+}
+
+/* Performs a world-to-viewport transformation on the specified point (which
+ * is in floating point format).
+ */
+static __inline__ void INTERNAL_LPTODP_FLOAT(DC *dc, FLOAT_POINT *point)
+{
+    FLOAT x, y;
+    
+    /* Perform the transformation */
+    x = point->x;
+    y = point->y;
+    point->x = x * dc->w.xformWorld2Vport.eM11 +
+               y * dc->w.xformWorld2Vport.eM21 +
+	       dc->w.xformWorld2Vport.eDx;
+    point->y = x * dc->w.xformWorld2Vport.eM12 +
+               y * dc->w.xformWorld2Vport.eM22 +
+	       dc->w.xformWorld2Vport.eDy;
+}
+
+/* Performs a world-to-viewport transformation on the specified point (which
+ * is in integer format).
+ */
+static __inline__ void INTERNAL_LPTODP(DC *dc, LPPOINT32 point)
+{
+    FLOAT_POINT floatPoint;
+    
+    /* Perform operation with floating point */
+    floatPoint.x=(FLOAT)point->x;
+    floatPoint.y=(FLOAT)point->y;
+    INTERNAL_LPTODP_FLOAT(dc, &floatPoint);
+    
+    /* Round to integers */
+    point->x = GDI_ROUND(floatPoint.x);
+    point->y = GDI_ROUND(floatPoint.y);
+}
+
 #define XDPTOLP(dc,x) \
     (((x)-(dc)->vportOrgX) * (dc)->wndExtX / (dc)->vportExtX+(dc)->wndOrgX)
 #define YDPTOLP(dc,y) \
diff --git a/include/header.h b/include/header.h
new file mode 100644
index 0000000..498ea0f
--- /dev/null
+++ b/include/header.h
@@ -0,0 +1,52 @@
+/*
+ * Header window definitions
+ *
+ * Copyright 1998 Eric Kohl
+ *
+ */
+
+#ifndef __WINE_HEADER_H_
+#define __WINE_HEADER_H_
+
+typedef struct 
+{
+    UINT32    mask;
+    INT32     cxy;
+    HBITMAP32 hbm;
+    LPSTR     pszText;
+    INT32     cchTextMax;
+    INT32     fmt;
+    LPARAM    lParam;
+    INT32     iImage;
+    INT32     iOrder;
+
+    BOOL32    bDown;
+    RECT32    rect;
+} HEADER_ITEM;
+
+
+typedef struct
+{
+    UINT32      uNumItem;
+    INT32       nHeight;
+    HFONT32     hFont;
+    HCURSOR32   hcurArrow;
+    HCURSOR32   hcurDivider;
+    HCURSOR32   hcurDivopen;
+    BOOL32      bCaptured;
+    BOOL32      bPressed;
+    BOOL32      bTracking;
+    INT32       iMoveItem;
+    INT32       xTrackOffset;
+    INT32       xOldTrack;
+    INT32       nOldWidth;
+    INT32       iHotItem;
+
+    HIMAGELIST  himl;
+    HEADER_ITEM *items;
+} HEADER_INFO;
+
+
+void HEADER_Register( void );
+
+#endif /* __WINE_HEADER_H_ */
diff --git a/include/libres.h b/include/libres.h
index addeb84..d70ef87 100644
--- a/include/libres.h
+++ b/include/libres.h
@@ -7,13 +7,8 @@
 #include "wintypes.h"
 #include "resource.h"
 
-extern INT32 LIBRES_AccessResource( HINSTANCE32 hModule, HRSRC32 hRsrc );
-extern HGLOBAL32 LIBRES_AllocResource( HINSTANCE32 hModule, HRSRC32 hRsrc, DWORD size );
-extern HRSRC32 LIBRES_FindResource16( HINSTANCE32 hModule, LPCSTR name, LPCSTR type );
-extern HRSRC32 LIBRES_FindResource32( HINSTANCE32 hModule, LPCWSTR name, LPCWSTR type );
-extern BOOL32 LIBRES_FreeResource( HGLOBAL32 handle );
+extern HRSRC32 LIBRES_FindResource( HINSTANCE32 hModule, LPCWSTR name, LPCWSTR type );
 extern HGLOBAL32 LIBRES_LoadResource( HINSTANCE32 hModule, HRSRC32 hRsrc );
-extern LPVOID LIBRES_LockResource( HGLOBAL32 handle );
 extern DWORD LIBRES_SizeofResource( HINSTANCE32 hModule, HRSRC32 hRsrc );
 
-#endif
+#endif /* __WINE_LIBRES_H */
diff --git a/include/lzexpand.h b/include/lzexpand.h
index a026793..e518bc3 100644
--- a/include/lzexpand.h
+++ b/include/lzexpand.h
@@ -6,13 +6,13 @@
 #ifndef __WINE_LZEXPAND_H
 #define __WINE_LZEXPAND_H
 
-#define LZERROR_BADINHANDLE	0xFFFF	/* -1 */
-#define LZERROR_BADOUTHANDLE	0xFFFE	/* -2 */
-#define LZERROR_READ		0xFFFD	/* -3 */
-#define LZERROR_WRITE		0xFFFC	/* -4 */
-#define LZERROR_GLOBALLOC	0xFFFB	/* -5 */
-#define LZERROR_GLOBLOCK	0xFFFA	/* -6 */
-#define LZERROR_BADVALUE	0xFFF9	/* -7 */
-#define LZERROR_UNKNOWNALG	0xFFF8	/* -8 */
+#define LZERROR_BADINHANDLE	-1	/* -1 */
+#define LZERROR_BADOUTHANDLE	-2	/* -2 */
+#define LZERROR_READ		-3	/* -3 */
+#define LZERROR_WRITE		-4	/* -4 */
+#define LZERROR_GLOBALLOC	-5	/* -5 */
+#define LZERROR_GLOBLOCK	-6	/* -6 */
+#define LZERROR_BADVALUE	-7	/* -7 */
+#define LZERROR_UNKNOWNALG	-8	/* -8 */
 
 #endif  /* __WINE_LZEXPAND_H */
diff --git a/include/main.h b/include/main.h
new file mode 100644
index 0000000..ea3a29c
--- /dev/null
+++ b/include/main.h
@@ -0,0 +1,13 @@
+/*
+ * Wine initialization definitions
+ */
+
+#ifndef __WINE_MAIN_H
+#define __WINE_MAIN_H
+
+extern BOOL32 MAIN_KernelInit(void);
+extern void MAIN_Usage(char*);
+extern BOOL32 MAIN_UserInit(void);
+extern BOOL32 MAIN_WineInit( int *argc, char *argv[] );
+
+#endif  /* __WINE_MAIN_H */
diff --git a/include/module.h b/include/module.h
index 5666695..b998b6f 100644
--- a/include/module.h
+++ b/include/module.h
@@ -115,9 +115,8 @@
 	HMODULE32		module;
 
 	char			*modname;
-	char 			*fullname;
 	char			*shortname;
-	char			*unixname;
+	char 			*longname;
 } WINE_MODREF;
 
 /* Resource types */
@@ -134,35 +133,28 @@
     (((OFSTRUCT *)((char*)(pModule) + (pModule)->fileinfo))->szPathName)
 
 /* module.c */
-extern NE_MODULE *MODULE_GetPtr16( HMODULE16 hModule );
-extern NE_MODULE *MODULE_GetPtr32( HMODULE32 hModule );
-extern HMODULE16 MODULE_HANDLEtoHMODULE16( HANDLE32 handle );
-extern int MODULE_OpenFile( HMODULE32 hModule );
-extern LPSTR MODULE_GetModuleName( HMODULE32 hModule );
 extern FARPROC32 MODULE_GetProcAddress32( struct _PDB32*pdb,HMODULE32 hModule,LPCSTR function );
 extern WINE_MODREF *MODULE32_LookupHMODULE( struct _PDB32 *process, HMODULE32 hModule );
-extern HMODULE32 MODULE_FindModule16( LPCSTR path );
 extern HMODULE32 MODULE_FindModule32( struct _PDB32 *process, LPCSTR path );
-extern HINSTANCE16 MODULE_CreateInstance( HMODULE16 hModule, HINSTANCE16 *prev,
-                                          BOOL32 lib_only );
 extern HMODULE32 MODULE_CreateDummyModule( const OFSTRUCT *ofs );
-extern HINSTANCE16 MODULE_Load( LPCSTR name, UINT16 uFlags, LPCSTR cmd_line,
+extern HINSTANCE16 MODULE_Load( LPCSTR name, BOOL32 implicit, LPCSTR cmd_line,
                                 LPCSTR env, UINT32 show_cmd );
 extern FARPROC16 MODULE_GetWndProcEntry16( const char *name );
-extern FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE32 hmodule, LPSTR name );
+extern FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE32 hmodule, LPCSTR name );
 
 typedef HGLOBAL16 (CALLBACK *RESOURCEHANDLER16)(HGLOBAL16,HMODULE16,HRSRC16);
 
 /* loader/ne/module.c */
+extern NE_MODULE *NE_GetPtr( HMODULE16 hModule );
 extern void NE_DumpModule( HMODULE16 hModule );
 extern void NE_WalkModules(void);
 extern void NE_RegisterModule( NE_MODULE *pModule );
 extern WORD NE_GetOrdinal( HMODULE16 hModule, const char *name );
 extern FARPROC16 NE_GetEntryPoint( HMODULE16 hModule, WORD ordinal );
 extern BOOL16 NE_SetEntryPoint( HMODULE16 hModule, WORD ordinal, WORD offset );
-extern HINSTANCE16 NE_LoadModule( HFILE32 hFile, OFSTRUCT *ofs, UINT16 flags,
-                                  LPCSTR cmd_line, LPCSTR env,
-                                  UINT32 show_cmd );
+extern int NE_OpenFile( NE_MODULE *pModule );
+extern HINSTANCE16 NE_LoadModule( LPCSTR name, HINSTANCE16 *hPrevInstance,
+                                  BOOL32 implicit, BOOL32 lib_only );
 
 /* loader/ne/resource.c */
 extern HGLOBAL16 WINAPI NE_DefResourceHandler(HGLOBAL16,HMODULE16,HRSRC16);
@@ -173,14 +165,14 @@
 extern BOOL32 NE_LoadAllSegments( NE_MODULE *pModule );
 extern void NE_FixupPrologs( NE_MODULE *pModule );
 extern void NE_InitializeDLLs( HMODULE16 hModule );
-extern BOOL32 NE_CreateSegments( HMODULE16 hModule );
+extern BOOL32 NE_CreateSegments( NE_MODULE *pModule );
+extern HINSTANCE16 NE_CreateInstance( NE_MODULE *pModule, HINSTANCE16 *prev,
+                                      BOOL32 lib_only );
 
-/* builtin.c */
+/* if1632/builtin.c */
 extern BOOL32 BUILTIN_Init(void);
-extern HMODULE32 BUILTIN_LoadModule( LPCSTR name, BOOL32 force );
+extern HMODULE16 BUILTIN_LoadModule( LPCSTR name, BOOL32 force );
 extern LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, WORD *pOrd );
-extern FARPROC32 BUILTIN_GetEntryPoint32( char *buffer, void *relay,
-                                          DWORD *typemask );
 extern BOOL32 BUILTIN_ParseDLLOptions( const char *str );
 extern void BUILTIN_PrintDLLs(void);
 
@@ -189,6 +181,6 @@
                                        struct _PDB32 *process );
 
 /* if1632/builtin.c */
-extern HMODULE32 (*fnBUILTIN_LoadModule)(LPCSTR name, BOOL32 force);
+extern HMODULE16 (*fnBUILTIN_LoadModule)(LPCSTR name, BOOL32 force);
 
 #endif  /* __WINE_MODULE_H */
diff --git a/include/neexe.h b/include/neexe.h
index 7a428fd..6faf332 100644
--- a/include/neexe.h
+++ b/include/neexe.h
@@ -88,7 +88,6 @@
 #define NE_FFLAGS_MULTIPLEDATA	0x0002
 #define NE_FFLAGS_WIN32         0x0010
 #define NE_FFLAGS_BUILTIN       0x0020  /* Wine built-in module */
-#define NE_FFLAGS_IMPLICIT	0x0040
 #define NE_FFLAGS_FRAMEBUF	0x0100  /* OS/2 fullscreen app */
 #define NE_FFLAGS_CONSOLE	0x0200  /* OS/2 console app */
 #define NE_FFLAGS_GUI		0x0300	/* right, (NE_FFLAGS_FRAMEBUF | NE_FFLAGS_CONSOLE) */
diff --git a/include/ntdll.h b/include/ntdll.h
index 28f3583..1791a6d 100644
--- a/include/ntdll.h
+++ b/include/ntdll.h
@@ -15,16 +15,20 @@
 
 /* Security Ids of NT */
 
+/* Moved to windows.h
 typedef struct {
 	BYTE	Value[6];
 } SID_IDENTIFIER_AUTHORITY,*PSID_IDENTIFIER_AUTHORITY,*LPSID_IDENTIFIER_AUTHORITY;
+*/
 
+/* Moved to windows.h
 typedef struct _SID {
 	BYTE	Revision;
 	BYTE	SubAuthorityCount;
 	SID_IDENTIFIER_AUTHORITY	IdentifierAuthority;
-	DWORD	SubAuthority[1];	/* more than one */
+	DWORD	SubAuthority[1];
 } SID,*PSID,*LPSID;
+*/
 
 #define	SID_REVISION			(1)	/* Current revision */
 #define	SID_MAX_SUB_AUTHORITIES		(15)	/* current max subauths */
@@ -37,6 +41,7 @@
 #define	ACL_REVISION1	1
 #define	ACL_REVISION2	2
 
+/* Moved to windows.h
 typedef struct _ACL {
 	BYTE	AclRevision;
 	BYTE	Sbz1;
@@ -44,6 +49,7 @@
 	WORD	AceCount;
 	WORD	Sbz2;
 } ACL,*LPACL;
+*/
 
 /* ACEs, directly starting after an ACL */
 typedef struct _ACE_HEADER {
@@ -103,7 +109,9 @@
 #define	SECURITY_DESCRIPTOR_REVISION	1
 #define	SECURITY_DESCRIPTOR_REVISION1	1
 
+/*
 typedef WORD SECURITY_DESCRIPTOR_CONTROL;
+ */
 
 #define	SE_OWNER_DEFAULTED	0x0001
 #define	SE_GROUP_DEFAULTED	0x0002
@@ -113,6 +121,7 @@
 #define	SE_SACL_DEFAULTED	0x0020
 #define	SE_SELF_RELATIVE	0x8000
 
+/* This was moved to windows.h
 typedef struct {
 	BYTE	Revision;
 	BYTE	Sbz1;
@@ -122,6 +131,7 @@
 	LPACL	Sacl;
 	LPACL	Dacl;
 } SECURITY_DESCRIPTOR,*PSECURITY_DESCRIPTOR,*LPSECURITY_DESCRIPTOR;
+*/
 
 typedef enum tagSID_NAME_USE {
 	SidTypeUser = 1,
diff --git a/include/ole2.h b/include/ole2.h
index f669929..e80454d 100644
--- a/include/ole2.h
+++ b/include/ole2.h
@@ -5,8 +5,6 @@
 #ifndef __WINE_OLE2_H
 #define __WINE_OLE2_H
 
-typedef LONG HRESULT;
-
 /* to be implemented */
 typedef LPVOID LPMESSAGEFILTER;
 typedef LPVOID LPDROPTARGET;
diff --git a/include/path.h b/include/path.h
index 4ddfc28..8263e2a 100644
--- a/include/path.h
+++ b/include/path.h
@@ -42,6 +42,8 @@
 
 extern BOOL32 PATH_MoveTo(HDC32 hdc);
 extern BOOL32 PATH_LineTo(HDC32 hdc, INT32 x, INT32 y);
+extern BOOL32 PATH_Rectangle(HDC32 hdc, INT32 x1, INT32 y1,
+   INT32 x2, INT32 y2);
 extern BOOL32 PATH_Ellipse(HDC32 hdc, INT32 x1, INT32 y1,
    INT32 x2, INT32 y2);
 extern BOOL32 PATH_Arc(HDC32 hdc, INT32 x1, INT32 y1, INT32 x2, INT32 y2,
diff --git a/include/pe_image.h b/include/pe_image.h
index bf276f6..5b91461 100644
--- a/include/pe_image.h
+++ b/include/pe_image.h
@@ -40,8 +40,8 @@
 extern DWORD PE_SizeofResource32(HMODULE32,HRSRC32);
 extern HMODULE32 PE_LoadLibraryEx32A(LPCSTR,struct _PDB32*,HFILE32,DWORD);
 extern HGLOBAL32 PE_LoadResource32(struct _wine_modref *wm,HRSRC32);
-extern HINSTANCE16 PE_LoadModule( HFILE32 hFile, OFSTRUCT *ofs,
-                                  LPCSTR cmd_line, LPCSTR env, UINT16 showCmd);
+extern HINSTANCE16 PE_LoadModule( LPCSTR name, LPCSTR cmd_line,
+                                  LPCSTR env, UINT16 showCmd );
 
 struct _PDB32; /* forward definition */
 struct _THDB; /* forward definition */
diff --git a/include/progress.h b/include/progress.h
index 36b7063..319367e 100644
--- a/include/progress.h
+++ b/include/progress.h
@@ -20,6 +20,6 @@
   COLORREF    ColorBk;      /* Background color */
 } PROGRESS_INFO;
 
-LRESULT WINAPI ProgressWindowProc(HWND32, UINT32, WPARAM32, LPARAM);
+extern void PROGRESS_Register (void);
 
 #endif  /* __WINE_PROGRESS_H */
diff --git a/include/status.h b/include/status.h
index 24a2290..a53ceae 100644
--- a/include/status.h
+++ b/include/status.h
@@ -7,8 +7,7 @@
 #ifndef __WINE_STATUS_H
 #define __WINE_STATUS_H
 
-LRESULT WINAPI StatusWindowProc( HWND32 hwnd, UINT32 msg,
-                                 WPARAM32 wParam, LPARAM lParam );
+extern void STATUS_Register(void);
 
 typedef struct
 {
@@ -16,13 +15,17 @@
     INT32	style;
     RECT32	bound;
     LPSTR	text;
+    HICON32     hIcon;
 } STATUSWINDOWPART;
 
 typedef struct
 {
     UINT16              numParts;
     UINT16              textHeight;
+    UINT32              height;
     BOOL32              simple;
+    HFONT32             hFont;
+    COLORREF            clrBk;  /* background color */
     STATUSWINDOWPART	part0;	/* simple window */
     STATUSWINDOWPART   *parts;
 } STATUSWINDOWINFO;
diff --git a/include/updown.h b/include/updown.h
index bb56e13..22a1e3d 100644
--- a/include/updown.h
+++ b/include/updown.h
@@ -29,7 +29,6 @@
   int iDelta;
 } NM_UPDOWN;
 
-LRESULT WINAPI UpDownWindowProc(HWND32 hwnd, UINT32 message, WPARAM32 wParam,
-                                LPARAM lParam);
+extern void UPDOWN_Register (void);
 
 #endif  /* __WINE_UPDOWN_H */
diff --git a/include/version.h b/include/version.h
index aed6733..31e094f 100644
--- a/include/version.h
+++ b/include/version.h
@@ -1 +1 @@
-#define WINE_RELEASE_INFO "Wine release 980503"
+#define WINE_RELEASE_INFO "Wine release 980517"
diff --git a/include/windows.h b/include/windows.h
index 6a66752..957eb19 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -1259,6 +1259,11 @@
   FONTSIGNATURE	fs;
 } CHARSETINFO,*LPCHARSETINFO;
 
+/* Flags for ModifyWorldTransform */
+#define MWT_IDENTITY      1
+#define MWT_LEFTMULTIPLY  2
+#define MWT_RIGHTMULTIPLY 3
+
 typedef struct
 {
     FLOAT  eM11;
@@ -2212,8 +2217,26 @@
 #define DDL_DRIVES	0x4000
 #define DDL_EXCLUSIVE	0x8000
 
-/* The security attributes structure 
- */
+typedef struct _ACL {
+    BYTE AclRevision;
+    BYTE Sbz1;
+    WORD AclSize;
+    WORD AceCount;
+    WORD Sbz2;
+} ACL, *LPACL;
+
+typedef struct {
+    BYTE Value[6];
+} SID_IDENTIFIER_AUTHORITY,*PSID_IDENTIFIER_AUTHORITY,*LPSID_IDENTIFIER_AUTHORITY;
+
+typedef struct _SID {
+    BYTE Revision;
+    BYTE SubAuthorityCount;
+    SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
+    DWORD SubAuthority[1];
+} SID,*PSID,*LPSID;
+
+/* The security attributes structure */
 typedef struct
 {
     DWORD   nLength;
@@ -2221,6 +2244,19 @@
     BOOL32  bInheritHandle;
 } SECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
 
+typedef WORD SECURITY_DESCRIPTOR_CONTROL;
+
+/* The security descriptor structure */
+typedef struct {
+    BYTE Revision;
+    BYTE Sbz1;
+    SECURITY_DESCRIPTOR_CONTROL Control;
+    LPSID Owner;
+    LPSID Group;
+    LPACL Sacl;
+    LPACL Dacl;
+} SECURITY_DESCRIPTOR, *LPSECURITY_DESCRIPTOR;
+
 typedef DWORD   SECURITY_INFORMATION;
 
 
@@ -6064,7 +6100,6 @@
 BOOL16      WINAPI SetWinDebugInfo(LPWINDEBUGINFO);
 DWORD       WINAPI SetWindowExt(HDC16,INT16,INT16);
 DWORD       WINAPI SetWindowOrg(HDC16,INT16,INT16);
-VOID        WINAPI SwitchStackBack(void);
 VOID        WINAPI SwitchStackTo(WORD,WORD,WORD);
 VOID        WINAPI TileChildWindows(HWND16,WORD);
 INT16       WINAPI UngetCommChar(INT16,CHAR);
@@ -6083,6 +6118,7 @@
 BOOL32      WINAPI ClearCommError(INT32,LPDWORD,LPCOMSTAT);
 BOOL32      WINAPI CloseHandle(HANDLE32);
 BOOL32      WINAPI CloseServiceHandle(HANDLE32);
+BOOL32      WINAPI CombineTransform(LPXFORM,const XFORM *,const XFORM *);
 INT32       WINAPI CopyAcceleratorTable32A(HACCEL32,LPACCEL32,INT32);
 INT32       WINAPI CopyAcceleratorTable32W(HACCEL32,LPACCEL32,INT32);
 #define     CopyAcceleratorTable WINELIB_NAME_AW(CopyAcceleratorTable)
@@ -6215,6 +6251,9 @@
 DWORD       WINAPI GetLargestConsoleWindowSize(HANDLE32);
 VOID        WINAPI GetLocalTime(LPSYSTEMTIME);
 DWORD       WINAPI GetLogicalDrives(void);
+DWORD       WINAPI GetLongPathName32A(LPCSTR,LPSTR,DWORD);
+DWORD       WINAPI GetLongPathName32W(LPCWSTR,LPWSTR,DWORD);
+#define     GetLongPathName WINELIB_NAME_AW(GetLongPathName)
 BOOL32      WINAPI GetMenuItemInfo32A(HMENU32,UINT32,BOOL32,MENUITEMINFO32A*);
 BOOL32      WINAPI GetMenuItemInfo32W(HMENU32,UINT32,BOOL32,MENUITEMINFO32W*);
 #define     GetMenuItemInfo WINELIB_NAME_AW(GetMenuItemInfo)
@@ -6239,6 +6278,7 @@
 VOID        WINAPI GetSystemInfo(LPSYSTEM_INFO);
 BOOL32      WINAPI GetSystemPowerStatus(LPSYSTEM_POWER_STATUS);
 VOID        WINAPI GetSystemTime(LPSYSTEMTIME);
+INT32       WINAPI GetTextCharsetInfo(HDC32,LPCHARSETINFO,DWORD);
 BOOL32      WINAPI GetTextExtentExPoint32A(HDC32,LPCSTR,INT32,INT32,
                                            LPINT32,LPINT32,LPSIZE32);
 BOOL32      WINAPI GetTextExtentExPoint32W(HDC32,LPCWSTR,INT32,INT32,
@@ -6286,6 +6326,7 @@
 INT32       WINAPI MessageBoxEx32A(HWND32,LPCSTR,LPCSTR,UINT32,WORD);
 INT32       WINAPI MessageBoxEx32W(HWND32,LPCWSTR,LPCWSTR,UINT32,WORD);
 #define     MessageBoxEx WINELIB_NAME_AW(MessageBoxEx)
+BOOL32      WINAPI ModifyWorldTransform(HDC32,const XFORM *, DWORD);
 BOOL32      WINAPI MoveFile32A(LPCSTR,LPCSTR);
 BOOL32      WINAPI MoveFile32W(LPCWSTR,LPCWSTR);
 #define     MoveFile WINELIB_NAME_AW(MoveFile)
@@ -6326,6 +6367,9 @@
 BOOL32      WINAPI ReadConsole32W(HANDLE32,LPVOID,DWORD,LPDWORD,LPVOID);
 #define     ReadConsole WINELIB_NAME_AW(ReadConsole)
 BOOL32      WINAPI ReadFile(HANDLE32,LPVOID,DWORD,LPDWORD,LPOVERLAPPED);
+LONG        WINAPI RegConnectRegistry32A(LPCSTR,HKEY,LPHKEY);
+LONG        WINAPI RegConnectRegistry32W(LPCWSTR,HKEY,LPHKEY);
+#define     RegConnectRegistry WINELIB_NAME_AW(RegConnectRegistry)
 DWORD       WINAPI RegCreateKeyEx32A(HKEY,LPCSTR,DWORD,LPSTR,DWORD,REGSAM,
                                      LPSECURITY_ATTRIBUTES,LPHKEY,LPDWORD);
 DWORD       WINAPI RegCreateKeyEx32W(HKEY,LPCWSTR,DWORD,LPWSTR,DWORD,REGSAM,
@@ -6336,10 +6380,14 @@
 DWORD       WINAPI RegEnumKeyEx32W(HKEY,DWORD,LPWSTR,LPDWORD,LPDWORD,LPWSTR,
                                    LPDWORD,LPFILETIME);
 #define     RegEnumKeyEx WINELIB_NAME_AW(RegEnumKeyEx)
-LONG        WINAPI RegGetKeySecurity(HKEY,SECURITY_INFORMATION,LPVOID,LPDWORD);
+LONG        WINAPI RegGetKeySecurity(HKEY,SECURITY_INFORMATION,LPSECURITY_DESCRIPTOR,LPDWORD);
 HANDLE32    WINAPI RegisterEventSource32A(LPCSTR,LPCSTR);
 HANDLE32    WINAPI RegisterEventSource32W(LPCWSTR,LPCWSTR);
 #define     RegisterEventSource WINELIB_NAME_AW(RegisterEventSource)
+LONG        WINAPI RegLoadKey32A(HKEY,LPCSTR,LPCSTR);
+LONG        WINAPI RegLoadKey32W(HKEY,LPCWSTR,LPCWSTR);
+#define     RegLoadKey WINELIB_NAME_AW(RegLoadKey)
+LONG        WINAPI RegNotifyChangeKeyValue(HKEY,BOOL32,DWORD,HANDLE32,BOOL32);
 DWORD       WINAPI RegOpenKeyEx32W(HKEY,LPCWSTR,DWORD,REGSAM,LPHKEY);
 DWORD       WINAPI RegOpenKeyEx32A(HKEY,LPCSTR,DWORD,REGSAM,LPHKEY);
 #define     RegOpenKeyEx WINELIB_NAME_AW(RegOpenKeyEx)
@@ -7553,6 +7601,9 @@
 INT16       WINAPI GetTextCharacterExtra16(HDC16);
 INT32       WINAPI GetTextCharacterExtra32(HDC32);
 #define     GetTextCharacterExtra WINELIB_NAME(GetTextCharacterExtra)
+INT16       WINAPI GetTextCharset16(HDC16);
+INT32       WINAPI GetTextCharset32(HDC32);
+#define     GetTextCharset WINELIB_NAME(GetTextCharset)
 COLORREF    WINAPI GetTextColor16(HDC16);
 COLORREF    WINAPI GetTextColor32(HDC32);
 #define     GetTextColor WINELIB_NAME(GetTextColor)
@@ -8738,7 +8789,7 @@
 INT32       WINAPI LoadMessage32A(HMODULE32,UINT32,WORD,LPSTR,INT32);
 INT32       WINAPI LoadMessage32W(HMODULE32,UINT32,WORD,LPWSTR,INT32);
 SEGPTR      WINAPI WIN16_GlobalLock16(HGLOBAL16);
-SEGPTR      WINAPI WIN16_LockResource(HGLOBAL16);
+SEGPTR      WINAPI WIN16_LockResource16(HGLOBAL16);
 LONG        WINAPI WIN16_hread(HFILE16,SEGPTR,LONG);
 INT32       WINAPI lstrncmp32A(LPCSTR,LPCSTR,INT32);
 INT32       WINAPI lstrncmp32W(LPCWSTR,LPCWSTR,INT32);
diff --git a/include/winerror.h b/include/winerror.h
index 763a124..34ae239 100644
--- a/include/winerror.h
+++ b/include/winerror.h
@@ -30,11 +30,13 @@
 #define ERROR_INVALID_HANDLE        6
 #define ERROR_NOT_ENOUGH_MEMORY     8
 #define ERROR_BAD_FORMAT            11
+#define ERROR_INVALID_ACCESS        12
 #define ERROR_OUTOFMEMORY           14
 #define ERROR_NO_MORE_FILES         18
 #define ERROR_SHARING_VIOLATION     32
 #define ERROR_LOCK_VIOLATION        33
 #define ERROR_DUP_NAME              52
+#define ERROR_BAD_NETPATH           53
 #define ERROR_FILE_EXISTS           80
 #define ERROR_CANNOT_MAKE           82
 #define ERROR_INVALID_PARAMETER     87
@@ -44,6 +46,7 @@
 #define ERROR_INSUFFICIENT_BUFFER   122
 #define ERROR_SEEK_ON_DEVICE        132
 #define ERROR_DIR_NOT_EMPTY         145
+#define ERROR_BAD_PATHNAME          161
 #define ERROR_BUSY                  170
 #define ERROR_ALREADY_EXISTS        183
 #define ERROR_FILENAME_EXCED_RANGE  206
@@ -53,11 +56,14 @@
 #define ERROR_TOO_MANY_POSTS        298
 #define ERROR_INVALID_ADDRESS       487
 #define ERROR_CAN_NOT_COMPLETE      1003
+#define ERROR_BADKEY                1010 /* Config reg key invalid */
+#define ERROR_CANTWRITE             1013 /* Config reg key couldn't be written */
 #define ERROR_IO_DEVICE             1117
 #define ERROR_POSSIBLE_DEADLOCK     1131
 #define ERROR_BAD_DEVICE            1200
 #define ERROR_NO_NETWORK            1222
 #define ERROR_ALREADY_INITIALIZED   1247
+#define ERROR_PRIVILEGE_NOT_HELD    1314
 #define ERROR_COMMITMENT_LIMIT      1455
 
 /* HRESULT values for OLE, SHELL and other Interface stuff */
diff --git a/include/winreg.h b/include/winreg.h
index f5954ad..66c8fc4 100644
--- a/include/winreg.h
+++ b/include/winreg.h
@@ -62,6 +62,9 @@
 #define REG_CREATED_NEW_KEY	0x00000001
 #define REG_OPENED_EXISTING_KEY	0x00000002
 
+/* For RegNotifyChangeKeyValue */
+#define REG_NOTIFY_CHANGE_NAME	0x1
+
 #define KEY_QUERY_VALUE         0x00000001
 #define KEY_SET_VALUE           0x00000002
 #define KEY_CREATE_SUB_KEY      0x00000004
diff --git a/include/wintypes.h b/include/wintypes.h
index 655f7b2..b4804ba 100644
--- a/include/wintypes.h
+++ b/include/wintypes.h
@@ -88,6 +88,7 @@
 typedef UINT16          WPARAM16;
 typedef UINT32          WPARAM32;
 typedef LONG            LPARAM;
+typedef LONG            HRESULT;
 typedef LONG            LRESULT;
 typedef WORD            ATOM;
 typedef WORD            CATCHBUF[9];
diff --git a/include/wnet.h b/include/wnet.h
index 6f6b951..9895a69 100644
--- a/include/wnet.h
+++ b/include/wnet.h
@@ -107,6 +107,9 @@
 #define WNNC_ERR_GetError                       0x0001
 #define WNNC_ERR_GetErrorText                   0x0002
 
+#define WNDT_NORMAL                             0x0
+#define WNDT_NETWORK                            0x1
+
 #define WIN30X                                  0x0
 #define WIN31X                                  0x1
 #define WIN311X                                 0x2
diff --git a/loader/libres.c b/loader/libres.c
index 5dafc8f..eb9598b 100644
--- a/loader/libres.c
+++ b/loader/libres.c
@@ -76,7 +76,7 @@
     for(Res=ResBlock->Resources; *Res; Res++)
       if(name)
       {
-	if((*Res)->type==typeid && !lstrcmpi32W((*Res)->name,name))
+	if((*Res)->type==typeid && !lstrcmpi32W((LPCWSTR)(*Res)->name,name))
 	  return (HRSRC32)*Res;
       }
       else
diff --git a/loader/main.c b/loader/main.c
index 5ab11da..5b1eaec 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -14,6 +14,7 @@
 #include "bitmap.h"
 #include "comm.h"
 #include "win.h"
+#include "main.h"
 #include "menu.h"
 #include "atom.h"
 #include "dialog.h"
diff --git a/loader/module.c b/loader/module.c
index 63568ee..17f1bb0 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -25,18 +25,11 @@
 #include "selectors.h"
 #include "stackframe.h"
 #include "task.h"
-#include "toolhelp.h"
 #include "debug.h"
 #include "callback.h"
 
 extern BOOL32 THREAD_InitDone;
 
-extern HMODULE16 hFirstModule;  /* FIXME */
-static HMODULE16 hCachedModule = 0;  /* Module cached by MODULE_OpenFile */
-
-static HMODULE32 MODULE_LoadModule(LPCSTR name,BOOL32 force) { return 0; }
-HMODULE32 (*fnBUILTIN_LoadModule)(LPCSTR name,BOOL32 force) = MODULE_LoadModule;
-
 
 /*************************************************************************
  *		MODULE32_LookupHMODULE
@@ -58,116 +51,6 @@
     return NULL;
 }
 
-/***********************************************************************
- *           MODULE_GetPtr16
- */
-NE_MODULE *MODULE_GetPtr16( HMODULE16 hModule )
-{
-    return (NE_MODULE*)GlobalLock16( GetExePtr(hModule) );
-}
-
-
-/***********************************************************************
- *           MODULE_GetPtr32
- */
-NE_MODULE *MODULE_GetPtr32( HMODULE32 hModule )
-{
-    return (NE_MODULE*)GlobalLock16( MODULE_HANDLEtoHMODULE16(hModule) );
-}
-
-/***********************************************************************
- *           MODULE_HANDLEtoHMODULE16
- */
-HMODULE16
-MODULE_HANDLEtoHMODULE16(HANDLE32 handle) {
-    NE_MODULE	*pModule;
-
-    if (HIWORD(handle))
-    {
-        WARN(module,"looking up 0x%08x in win16 function!\n",handle);
-	/* this is a HMODULE32 */
-
-        /* walk the list looking for the correct startaddress */
-    	pModule = (NE_MODULE *)GlobalLock16( hFirstModule );
-	while (pModule)
-        {
-            if (pModule->module32 == handle) return pModule->self;
-            pModule = (NE_MODULE*)GlobalLock16(pModule->next);
-	}
-	return 0;
-    }
-    return GetExePtr(handle);
-}
-
-/***********************************************************************
- *           MODULE_OpenFile
- */
-int MODULE_OpenFile( HMODULE32 hModule )
-{
-    NE_MODULE *pModule;
-    DOS_FULL_NAME full_name;
-    char *name;
-
-    static int cachedfd = -1;
-
-    hModule = MODULE_HANDLEtoHMODULE16(hModule);
-    TRACE(module, "(%04x) cache: mod=%04x fd=%d\n",
-                    hModule, hCachedModule, cachedfd );
-    if (!(pModule = MODULE_GetPtr32( hModule ))) return -1;
-    if (hCachedModule == hModule) return cachedfd;
-    close( cachedfd );
-    hCachedModule = hModule;
-    name = NE_MODULE_NAME( pModule );
-    if (!DOSFS_GetFullName( name, TRUE, &full_name ) ||
-        (cachedfd = open( full_name.long_name, O_RDONLY )) == -1)
-        WARN( module, "Can't open file '%s' for module %04x\n",
-                 name, hModule );
-    TRACE(module, "opened '%s' -> %d\n",
-                    name, cachedfd );
-    return cachedfd;
-}
-
-
-/***********************************************************************
- *           MODULE_CreateInstance
- *
- * If lib_only is TRUE, handle the module like a library even if it is a .EXE
- */
-HINSTANCE16 MODULE_CreateInstance( HMODULE16 hModule, HINSTANCE16 *prev,
-                                   BOOL32 lib_only )
-{
-    SEGTABLEENTRY *pSegment;
-    NE_MODULE *pModule;
-    int minsize;
-    HINSTANCE16 hNewInstance;
-
-    if (!(pModule = MODULE_GetPtr16( hModule ))) return 0;
-    if (pModule->dgroup == 0)
-    {
-        if (prev) *prev = hModule;
-        return hModule;
-    }
-
-    pSegment = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
-    if (prev) *prev = pSegment->selector;
-
-      /* if it's a library, create a new instance only the first time */
-    if (pSegment->selector)
-    {
-        if (pModule->flags & NE_FFLAGS_LIBMODULE) return pSegment->selector;
-        if (lib_only) return pSegment->selector;
-    }
-
-    minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
-    if (pModule->ss == pModule->dgroup) minsize += pModule->stack_size;
-    minsize += pModule->heap_size;
-    hNewInstance = GLOBAL_Alloc( GMEM_ZEROINIT | GMEM_FIXED,
-                                 minsize, hModule, FALSE, FALSE, FALSE );
-    if (!hNewInstance) return 0;
-    pSegment->selector = hNewInstance;
-    return hNewInstance;
-}
-
 
 /***********************************************************************
  *           MODULE_CreateDummyModule
@@ -312,63 +195,6 @@
 }
 
 
-/***********************************************************************
- *           MODULE_GetModuleName
- */
-LPSTR MODULE_GetModuleName( HMODULE32 hModule )
-{
-    NE_MODULE *pModule;
-    BYTE *p, len;
-    static char buffer[10];
-
-    if (!(pModule = MODULE_GetPtr32( hModule ))) return NULL;
-    p = (BYTE *)pModule + pModule->name_table;
-    len = MIN( *p, 8 );
-    memcpy( buffer, p + 1, len );
-    buffer[len] = '\0';
-    return buffer;
-}
-
-
-/**********************************************************************
- *	    MODULE_FindModule
- *
- * Find a module from a path name.
- * RETURNS
- *	the win16 module handle if found
- * 	0 if not
- */
-HMODULE32 MODULE_FindModule16(
-	LPCSTR path	/* [in] path of the module to be found */
-) {
-    HMODULE32 hModule = hFirstModule;
-    LPCSTR	filename, dotptr, modulepath, modulename;
-    BYTE	len, *name_table;
-
-    if (!(filename = strrchr( path, '\\' ))) filename = path;
-    else filename++;
-    if ((dotptr = strrchr( filename, '.' )) != NULL)
-        len = (BYTE)(dotptr - filename);
-    else len = strlen( filename );
-
-    while(hModule)
-    {
-        NE_MODULE *pModule = MODULE_GetPtr16( hModule );
-        if (!pModule) break;
-        modulepath = NE_MODULE_NAME(pModule);
-        if (!(modulename = strrchr( modulepath, '\\' )))
-            modulename = modulepath;
-        else modulename++;
-        if (!lstrcmpi32A( modulename, filename )) return hModule;
-
-        name_table = (BYTE *)pModule + pModule->name_table;
-        if ((*name_table == len) && !lstrncmpi32A(filename, name_table+1, len))
-            return hModule;
-        hModule = pModule->next;
-    }
-    return 0;
-}
-
 /**********************************************************************
  *	    MODULE_FindModule32
  *
@@ -427,105 +253,6 @@
 
 
 /**********************************************************************
- *	    MODULE_CallWEP
- *
- * Call a DLL's WEP, allowing it to shut down.
- * FIXME: we always pass the WEP WEP_FREE_DLL, never WEP_SYSTEM_EXIT
- */
-static BOOL16 MODULE_CallWEP( HMODULE16 hModule )
-{
-    FARPROC16 WEP = (FARPROC16)0;
-    WORD ordinal = NE_GetOrdinal( hModule, "WEP" );
-
-    if (ordinal) WEP = NE_GetEntryPoint( hModule, ordinal );
-    if (!WEP)
-    {
-	WARN(module, "module %04x doesn't have a WEP\n", hModule );
-	return FALSE;
-    }
-    return Callbacks->CallWindowsExitProc( WEP, WEP_FREE_DLL );
-}
-
-
-/**********************************************************************
- *	    MODULE_FreeModule
- *
- * Remove a module from memory.
- */
-BOOL16 MODULE_FreeModule( HMODULE32 hModule, TDB* pTaskContext )
-{
-    HMODULE16 *hPrevModule;
-    NE_MODULE *pModule;
-    SEGTABLEENTRY *pSegment;
-    HMODULE16 *pModRef;
-    int i;
-
-    if (!(pModule = MODULE_GetPtr32( hModule ))) return FALSE;
-    hModule = pModule->self;
-
-    if (((INT16)(--pModule->count)) > 0 ) return TRUE;
-    else pModule->count = 0;
-
-    if (pModule->flags & NE_FFLAGS_BUILTIN)
-        return FALSE;  /* Can't free built-in module */
-
-    if (pModule->flags & NE_FFLAGS_LIBMODULE) 
-    {
-	MODULE_CallWEP( hModule );
-
-	/* Free the objects owned by the DLL module */
-
-	if( pTaskContext && pTaskContext->userhandler )
-	{
-            pTaskContext->userhandler( hModule, USIG_DLL_UNLOAD, 0,
-                                       pTaskContext->hInstance,
-                                       pTaskContext->hQueue );
-	}
-    }
-    /* Clear magic number just in case */
-
-    pModule->magic = pModule->self = 0;
-
-      /* Remove it from the linked list */
-
-    hPrevModule = &hFirstModule;
-    while (*hPrevModule && (*hPrevModule != hModule))
-    {
-        hPrevModule = &(MODULE_GetPtr16( *hPrevModule ))->next;
-    }
-    if (*hPrevModule) *hPrevModule = pModule->next;
-
-      /* Free all the segments */
-
-    pSegment = NE_SEG_TABLE( pModule );
-    for (i = 1; i <= pModule->seg_count; i++, pSegment++)
-    {
-        GlobalFree16( pSegment->selector );
-    }
-
-      /* Free the referenced modules */
-
-    pModRef = (HMODULE16*)NE_MODULE_TABLE( pModule );
-    for (i = 0; i < pModule->modref_count; i++, pModRef++)
-    {
-        FreeModule16( *pModRef );
-    }
-
-      /* Free the module storage */
-
-    if (pModule->nrname_handle) GlobalFree16( pModule->nrname_handle );
-    if (pModule->dlls_to_init) GlobalFree16( pModule->dlls_to_init );
-    GlobalFree16( hModule );
-
-      /* Remove module from cache */
-
-    if (hCachedModule == hModule) hCachedModule = 0;
-
-    return TRUE;
-}
-
-
-/**********************************************************************
  *	    MODULE_Load
  *
  * Implementation of LoadModule().
@@ -534,74 +261,34 @@
  * 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, UINT16 uFlags,
+HINSTANCE16 MODULE_Load( LPCSTR name, BOOL32 implicit,
                          LPCSTR cmd_line, LPCSTR env, UINT32 show_cmd )
 {
-    HMODULE32 hModule;
+    HMODULE16 hModule;
     HINSTANCE16 hInstance, hPrevInstance;
     NE_MODULE *pModule;
-    OFSTRUCT ofs;
-    HFILE32 hFile;
 
     if (__winelib)
     {
+        OFSTRUCT ofs;
         lstrcpyn32A( ofs.szPathName, name, sizeof(ofs.szPathName) );
         if ((hModule = MODULE_CreateDummyModule( &ofs )) < 32) return hModule;
         pModule = (NE_MODULE *)GlobalLock16( hModule );
-        hInstance = MODULE_CreateInstance( hModule, &hPrevInstance,
-                                           (cmd_line == NULL) );
+        hInstance = NE_CreateInstance( pModule, &hPrevInstance,
+                                       (cmd_line == NULL) );
     }
     else
     {
-        hModule = MODULE_FindModule16( name );
-
-        if (!hModule)  /* We have to load the module */
-        {
-            /* Try to load the built-in first if not disabled */
-            if ((hModule = fnBUILTIN_LoadModule( name, FALSE )))
-                return MODULE_HANDLEtoHMODULE16( hModule );
-            
-            if ((hFile = OpenFile32( name, &ofs, OF_READ )) == HFILE_ERROR32)
-            {
-                /* Now try the built-in even if disabled */
-                if ((hModule = fnBUILTIN_LoadModule( name, TRUE )))
-                {
-                    WARN(module, "Could not load Windows DLL '%s', using built-in module.\n", name );
-                    return MODULE_HANDLEtoHMODULE16( hModule );
-                }
-                return 2;  /* File not found */
-            }
-
-            /* Create the module structure */
-
-            hModule = NE_LoadModule( hFile, &ofs, uFlags, cmd_line,
-                                     env, show_cmd );
-            if (hModule < 32)
-            {
-                if ((hModule == 21) && cmd_line)
-                    hModule = PE_LoadModule( hFile, &ofs, cmd_line,
-                                             env, show_cmd );
-            }
-
-            if (hModule < 32)
-                fprintf( stderr, "LoadModule: can't load '%s', error=%d\n",
-                         name, hModule );
-            _lclose32( hFile );
-            return hModule;
-        }
-        else /* module is already loaded, just create a new data segment if it's a task */
-        {
-            pModule = MODULE_GetPtr32( hModule );
-            hInstance = MODULE_CreateInstance( hModule, &hPrevInstance,
-                                               (cmd_line == NULL) );
-            if (hInstance != hPrevInstance)  /* not a library */
-                NE_LoadSegment( pModule, pModule->dgroup );
-            pModule->count++;
-        }
-    } /* !winelib */
+        hInstance = NE_LoadModule( name, &hPrevInstance, implicit,
+                                 (cmd_line == NULL) );
+        if ((hInstance == 21) && cmd_line)
+            return PE_LoadModule( name, cmd_line, env, show_cmd );
+    }
 
     /* Create a task for this instance */
 
+    if (hInstance < 32) return hInstance;
+    pModule = NE_GetPtr( hInstance );
     if (cmd_line && !(pModule->flags & NE_FFLAGS_LIBMODULE))
     {
         PDB32 *pdb;
@@ -622,9 +309,8 @@
  */
 HINSTANCE16 LoadModule16( LPCSTR name, LPVOID paramBlock )
 {
-    LOADPARAMS *params = (LOADPARAMS *)paramBlock;
-    LPSTR cmd_line = (LPSTR)PTR_SEG_TO_LIN( params->cmdLine );
-    LPSTR new_cmd_line;
+    LOADPARAMS *params;
+    LPSTR cmd_line, new_cmd_line;
     UINT16 show_cmd = 0;
     LPCVOID env = NULL;
     HINSTANCE16 hInstance;
@@ -649,7 +335,7 @@
     strcat( new_cmd_line, cmd_line );
 
     if (params->hEnvironment) env = GlobalLock16( params->hEnvironment );
-    hInstance = MODULE_Load( name, 0, new_cmd_line, env, show_cmd );
+    hInstance = MODULE_Load( name, FALSE, new_cmd_line, env, show_cmd );
     if (params->hEnvironment) GlobalUnlock16( params->hEnvironment );
     HeapFree( GetProcessHeap(), 0, new_cmd_line );
     return hInstance;
@@ -682,41 +368,12 @@
   CloseHandle32(pi.hThread); 
 
 #else
-  return MODULE_Load( name, 0, params->lpCmdLine, params->lpEnvAddress, 
+  return MODULE_Load( name, FALSE, params->lpCmdLine, params->lpEnvAddress, 
                         *((UINT16 *)params->lpCmdShow + 1) );
 #endif
 }
 
 
-/**********************************************************************
- *	    FreeModule16    (KERNEL.46)
- */
-BOOL16 WINAPI FreeModule16( HMODULE16 hModule )
-{
-    NE_MODULE *pModule;
-
-    if (!(pModule = MODULE_GetPtr16( hModule ))) return FALSE;
-    TRACE(module, "%s count %d\n", 
-		    MODULE_GetModuleName(hModule), pModule->count );
-
-    return MODULE_FreeModule( hModule, GlobalLock16(GetCurrentTask()) );
-}
-
-
-/**********************************************************************
- *	    GetModuleHandle16    (KERNEL.47)
- */
-HMODULE16 WINAPI WIN16_GetModuleHandle( SEGPTR name )
-{
-    if (HIWORD(name) == 0) return GetExePtr( (HINSTANCE16)name );
-    return MODULE_FindModule16( PTR_SEG_TO_LIN(name) );
-}
-
-HMODULE16 WINAPI GetModuleHandle16( LPCSTR name )
-{
-    return MODULE_FindModule16( name );
-}
-
 /***********************************************************************
  *              GetModuleHandle         (KERNEL32.237)
  */
@@ -740,52 +397,23 @@
 }
 
 
-/**********************************************************************
- *	    GetModuleUsage    (KERNEL.48)
- */
-INT16 WINAPI GetModuleUsage( HINSTANCE16 hModule )
-{
-    NE_MODULE *pModule;
-
-    if (!(pModule = MODULE_GetPtr16( hModule ))) return 0;
-    TRACE(module, "(%04x): returning %d\n",
-                    hModule, pModule->count );
-    return pModule->count;
-}
-
-
-/**********************************************************************
- *	    GetModuleFileName16    (KERNEL.49)
- */
-INT16 WINAPI GetModuleFileName16( HINSTANCE16 hModule, LPSTR lpFileName,
-                                  INT16 nSize )
-{
-    NE_MODULE *pModule;
-
-    if (!hModule) hModule = GetCurrentTask();
-    if (!(pModule = MODULE_GetPtr16( hModule ))) return 0;
-    lstrcpyn32A( lpFileName, NE_MODULE_NAME(pModule), nSize );
-    TRACE(module, "%s\n", lpFileName );
-    return strlen(lpFileName);
-}
-
-
 /***********************************************************************
  *              GetModuleFileName32A      (KERNEL32.235)
- * FIXME FIXME
  */
-DWORD WINAPI GetModuleFileName32A( HMODULE32 hModule, LPSTR lpFileName,
-                                   DWORD size )
-{                   
-    NE_MODULE *pModule;
-           
-    if (!hModule)
-    {
-        TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
-        hModule = pTask->hInstance;
-    }
-    if (!(pModule = MODULE_GetPtr32( hModule ))) return 0;
-    lstrcpyn32A( lpFileName, NE_MODULE_NAME(pModule), size );
+DWORD WINAPI GetModuleFileName32A( 
+	HMODULE32 hModule,	/* [in] module handle (32bit) */
+	LPSTR lpFileName,	/* [out] filenamebuffer */
+        DWORD size		/* [in] size of filenamebuffer */
+) {                   
+    WINE_MODREF *wm = MODULE32_LookupHMODULE(PROCESS_Current(),hModule);
+
+    if (!wm) /* can happen on start up or the like */
+    	return 0;
+
+    /* FIXME: we should probably get a real long name, but wm->longname
+     * is currently a UNIX filename!
+     */
+    lstrcpyn32A( lpFileName, wm->shortname, size );
     TRACE(module, "%s\n", lpFileName );
     return strlen(lpFileName);
 }                   
@@ -805,19 +433,6 @@
 }
 
 
-/**********************************************************************
- *	    GetModuleName    (KERNEL.27)
- */
-BOOL16 WINAPI GetModuleName( HINSTANCE16 hinst, LPSTR buf, INT16 nSize )
-{
-    LPSTR name = MODULE_GetModuleName(hinst);
-
-    if (!name) return FALSE;
-    lstrcpyn32A( buf, name, nSize );
-    return TRUE;
-}
-
-
 /***********************************************************************
  *           LoadLibraryEx32W   (KERNEL.513)
  * FIXME
@@ -882,29 +497,8 @@
  */
 BOOL32 WINAPI FreeLibrary32(HINSTANCE32 hLibModule)
 {
-    TRACE(module,"hLibModule=%08x\n", hLibModule);
-    return MODULE_FreeModule(hLibModule,GlobalLock16(GetCurrentTask()) );
-}
-
-
-/***********************************************************************
- *           LoadLibrary   (KERNEL.95)
- */
-HINSTANCE16 WINAPI LoadLibrary16( LPCSTR libname )
-{
-    HINSTANCE16 handle;
-
-    TRACE(module, "(%08x) %s\n", (int)libname, libname);
-
-    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, 0, NULL, NULL, 0 );
-    }
-    return handle;
+    WARN(module,"(%08x): stub\n", hLibModule);
+    return TRUE;  /* FIXME */
 }
 
 
@@ -919,15 +513,6 @@
 }
 
 
-/***********************************************************************
- *           FreeLibrary16   (KERNEL.96)
- */
-void WINAPI FreeLibrary16( HINSTANCE16 handle )
-{
-    TRACE(module,"%04x\n", handle );
-    FreeModule16( handle );
-}
-
 
 /***********************************************************************
  *           PrivateFreeLibrary       (KERNEL32)
@@ -1001,7 +586,7 @@
 	{
 	    /* Winelib: Use LoadModule() only for the program itself */
 	    if (__winelib) use_load_module = 0;
-            handle = MODULE_Load( filename, 0, lpCmdLine, NULL, nCmdShow );
+            handle = MODULE_Load( filename, FALSE, lpCmdLine, NULL, nCmdShow );
 	    if (handle == 2)  /* file not found */
 	    {
 		/* Check that the original file name did not have a suffix */
@@ -1011,7 +596,7 @@
 		{
 		    p = filename + strlen(filename);
 		    strcpy( p, ".exe" );
-                    handle = MODULE_Load( filename, 0, lpCmdLine,
+                    handle = MODULE_Load( filename, FALSE, lpCmdLine,
                                           NULL, nCmdShow );
                     *p = '\0';  /* Remove extension */
 		}
@@ -1094,7 +679,7 @@
  *           WIN32_GetProcAddress16   (KERNEL32.36)
  * Get procaddress in 16bit module from win32... (kernel32 undoc. ordinal func)
  */
-FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE32 hModule, LPSTR name )
+FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE32 hModule, LPCSTR name )
 {
     WORD	ordinal;
     FARPROC16	ret;
@@ -1103,7 +688,12 @@
     	WARN(module,"hModule may not be 0!\n");
 	return (FARPROC16)0;
     }
-    hModule = MODULE_HANDLEtoHMODULE16(hModule);
+    if (HIWORD(hModule))
+    {
+    	WARN( module, "hModule is Win32 handle (%08x)\n", hModule );
+	return (FARPROC16)0;
+    }
+    hModule = GetExePtr( hModule );
     if (HIWORD(name)) {
         ordinal = NE_GetOrdinal( hModule, name );
         TRACE(module, "%04x '%s'\n",
@@ -1201,78 +791,3 @@
     if (!wm || (wm->type != MODULE32_PE)) return (LPIMAGE_NT_HEADERS)0;
     return PE_HEADER(wm->module);
 }
-
-
-/**********************************************************************
- *	    GetExpWinVer    (KERNEL.167)
- */
-WORD WINAPI GetExpWinVer( HMODULE16 hModule )
-{
-    NE_MODULE *pModule = MODULE_GetPtr16( hModule );
-    return pModule ? pModule->expected_version : 0;
-}
-
-
-/**********************************************************************
- *	    IsSharedSelector    (KERNEL.345)
- */
-BOOL16 WINAPI IsSharedSelector( HANDLE16 selector )
-{
-    /* Check whether the selector belongs to a DLL */
-    NE_MODULE *pModule = MODULE_GetPtr16( selector );
-    if (!pModule) return FALSE;
-    return (pModule->flags & NE_FFLAGS_LIBMODULE) != 0;
-}
-
-
-/**********************************************************************
- *	    ModuleFirst    (TOOLHELP.59)
- */
-BOOL16 WINAPI ModuleFirst( MODULEENTRY *lpme )
-{
-    lpme->wNext = hFirstModule;
-    return ModuleNext( lpme );
-}
-
-
-/**********************************************************************
- *	    ModuleNext    (TOOLHELP.60)
- */
-BOOL16 WINAPI ModuleNext( MODULEENTRY *lpme )
-{
-    NE_MODULE *pModule;
-    char *name;
-
-    if (!lpme->wNext) return FALSE;
-    if (!(pModule = MODULE_GetPtr16( lpme->wNext ))) return FALSE;
-    name = (char *)pModule + pModule->name_table;
-    memcpy( lpme->szModule, name + 1, *name );
-    lpme->szModule[(BYTE)*name] = '\0';
-    lpme->hModule = lpme->wNext;
-    lpme->wcUsage = pModule->count;
-    strncpy( lpme->szExePath, NE_MODULE_NAME(pModule), MAX_PATH );
-    lpme->szExePath[MAX_PATH] = '\0';
-    lpme->wNext = pModule->next;
-    return TRUE;
-}
-
-
-/**********************************************************************
- *	    ModuleFindName    (TOOLHELP.61)
- */
-BOOL16 WINAPI ModuleFindName( MODULEENTRY *lpme, LPCSTR name )
-{
-    lpme->wNext = GetModuleHandle16( name );
-    return ModuleNext( lpme );
-}
-
-
-/**********************************************************************
- *	    ModuleFindHandle    (TOOLHELP.62)
- */
-BOOL16 WINAPI ModuleFindHandle( MODULEENTRY *lpme, HMODULE16 hModule )
-{
-    hModule = GetExePtr( hModule );
-    lpme->wNext = hModule;
-    return ModuleNext( lpme );
-}
diff --git a/loader/ne/module.c b/loader/ne/module.c
index 5cd97f8..0a2fe70 100644
--- a/loader/ne/module.c
+++ b/loader/ne/module.c
@@ -5,15 +5,36 @@
  */
 
 #include <assert.h>
+#include <fcntl.h>
 #include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 #include "module.h"
+#include "file.h"
 #include "ldt.h"
+#include "callback.h"
 #include "heap.h"
+#include "task.h"
 #include "global.h"
 #include "process.h"
+#include "toolhelp.h"
 #include "debug.h"
 
-HMODULE16 hFirstModule = 0;
+static HMODULE16 hFirstModule = 0;
+static NE_MODULE *pCachedModule = 0;  /* Module cached by NE_OpenFile */
+
+static HMODULE16 NE_LoadBuiltin(LPCSTR name,BOOL32 force) { return 0; }
+HMODULE16 (*fnBUILTIN_LoadModule)(LPCSTR name,BOOL32 force) = NE_LoadBuiltin;
+
+
+/***********************************************************************
+ *           NE_GetPtr
+ */
+NE_MODULE *NE_GetPtr( HMODULE16 hModule )
+{
+    return (NE_MODULE *)GlobalLock16( GetExePtr(hModule) );
+}
+
 
 /***********************************************************************
  *           NE_DumpModule
@@ -26,7 +47,7 @@
     WORD *pword;
     NE_MODULE *pModule;
 
-    if (!(pModule = MODULE_GetPtr16( hModule )))
+    if (!(pModule = NE_GetPtr( hModule )))
     {
         fprintf( stderr, "**** %04x is not a module handle\n", hModule );
         return;
@@ -99,8 +120,9 @@
         pword = (WORD *)((BYTE *)pModule + pModule->modref_table);
         for (i = 0; i < pModule->modref_count; i++, pword++)
         {
-	    DUMP( "%d: %04x -> '%s'\n", i, *pword,
-		    MODULE_GetModuleName(*pword));
+            char name[10];
+            GetModuleName( *pword, name, sizeof(name) );
+	    DUMP( "%d: %04x -> '%s'\n", i, *pword, name );
         }
     }
     else DUMP( "None\n" );
@@ -170,7 +192,7 @@
     fprintf( stderr, "Module Flags Name\n" );
     while (hModule)
     {
-        NE_MODULE *pModule = MODULE_GetPtr16( hModule );
+        NE_MODULE *pModule = NE_GetPtr( hModule );
         if (!pModule)
         {
             fprintf( stderr, "**** Bad module %04x in list\n", hModule );
@@ -205,7 +227,7 @@
     BYTE len;
     NE_MODULE *pModule;
 
-    if (!(pModule = MODULE_GetPtr16( hModule ))) return 0;
+    if (!(pModule = NE_GetPtr( hModule ))) return 0;
     assert( !(pModule->flags & NE_FFLAGS_WIN32) );
 
     TRACE( module, "(%04x,'%s')\n", hModule, name );
@@ -270,7 +292,7 @@
     BYTE *p;
     WORD sel, offset;
 
-    if (!(pModule = MODULE_GetPtr16( hModule ))) return 0;
+    if (!(pModule = NE_GetPtr( hModule ))) return 0;
     assert( !(pModule->flags & NE_FFLAGS_WIN32) );
 
     p = (BYTE *)pModule + pModule->entry_table;
@@ -321,7 +343,7 @@
     WORD curOrdinal = 1;
     BYTE *p;
 
-    if (!(pModule = MODULE_GetPtr16( hModule ))) return FALSE;
+    if (!(pModule = NE_GetPtr( hModule ))) return FALSE;
     assert( !(pModule->flags & NE_FFLAGS_WIN32) );
 
     p = (BYTE *)pModule + pModule->entry_table;
@@ -356,9 +378,35 @@
 
 
 /***********************************************************************
+ *           NE_OpenFile
+ */
+int NE_OpenFile( NE_MODULE *pModule )
+{
+    DOS_FULL_NAME full_name;
+    char *name;
+
+    static int cachedfd = -1;
+
+    TRACE( module, "(%p) cache: mod=%p fd=%d\n",
+           pModule, pCachedModule, cachedfd );
+    if (pCachedModule == pModule) return cachedfd;
+    close( cachedfd );
+    pCachedModule = pModule;
+    name = NE_MODULE_NAME( pModule );
+    if (!DOSFS_GetFullName( name, TRUE, &full_name ) ||
+        (cachedfd = open( full_name.long_name, O_RDONLY )) == -1)
+        WARN( module, "Can't open file '%s' for module %04x\n",
+              name, pModule->self );
+    TRACE(module, "opened '%s' -> %d\n",
+                    name, cachedfd );
+    return cachedfd;
+}
+
+
+/***********************************************************************
  *           NE_LoadExeHeader
  */
-static HMODULE16 NE_LoadExeHeader( HFILE32 hFile, OFSTRUCT *ofs )
+static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs )
 {
     IMAGE_DOS_HEADER mz_header;
     IMAGE_OS2_HEADER ne_header;
@@ -374,23 +422,23 @@
        ((fastload && ((offset) >= fastload_offset) && \
          ((offset)+(size) <= fastload_offset+fastload_length)) ? \
         (memcpy( buffer, fastload+(offset)-fastload_offset, (size) ), TRUE) : \
-        (_llseek32( hFile, (offset), SEEK_SET), \
-         _lread32( hFile, (buffer), (size) ) == (size)))
+        (_llseek16( hFile, (offset), SEEK_SET), \
+         _hread16( hFile, (buffer), (size) ) == (size)))
 
-    _llseek32( hFile, 0, SEEK_SET );
-    if ((_lread32(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
+    _llseek16( hFile, 0, SEEK_SET );
+    if ((_hread16(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
         (mz_header.e_magic != IMAGE_DOS_SIGNATURE))
         return (HMODULE16)11;  /* invalid exe */
 
-    _llseek32( hFile, mz_header.e_lfanew, SEEK_SET );
-    if (_lread32( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
+    _llseek16( hFile, mz_header.e_lfanew, SEEK_SET );
+    if (_hread16( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
         return (HMODULE16)11;  /* invalid exe */
 
     if (ne_header.ne_magic == IMAGE_NT_SIGNATURE) return (HMODULE16)21;  /* win32 exe */
     if (ne_header.ne_magic != IMAGE_OS2_SIGNATURE) return (HMODULE16)11;  /* invalid exe */
 
     if (ne_header.ne_magic == IMAGE_OS2_SIGNATURE_LX) {
-      fprintf(stderr, "Sorry, this is an OS/2 linear executable (LX) file !\n");
+      MSG("Sorry, this is an OS/2 linear executable (LX) file !\n");
       return (HMODULE16)12;
     }
 
@@ -425,7 +473,7 @@
 
     /* Clear internal Wine flags in case they are set in the EXE file */
 
-    pModule->flags &= ~(NE_FFLAGS_BUILTIN|NE_FFLAGS_WIN32|NE_FFLAGS_IMPLICIT);
+    pModule->flags &= ~(NE_FFLAGS_BUILTIN | NE_FFLAGS_WIN32);
 
     /* Read the fast-load area */
 
@@ -437,11 +485,11 @@
                         fastload_offset, fastload_length );
         if ((fastload = HeapAlloc( SystemHeap, 0, fastload_length )) != NULL)
         {
-            _llseek32( hFile, fastload_offset, SEEK_SET);
-            if (_lread32(hFile, fastload, fastload_length) != fastload_length)
+            _llseek16( hFile, fastload_offset, SEEK_SET);
+            if (_hread16(hFile, fastload, fastload_length) != fastload_length)
             {
                 HeapFree( SystemHeap, 0, fastload );
-                fprintf(stderr, "Error reading fast-load area !\n");
+                WARN( module, "Error reading fast-load area!\n");
                 fastload = NULL;
             }
         }
@@ -575,8 +623,8 @@
             return (HMODULE16)11;  /* invalid exe */
         }
         buffer = GlobalLock16( pModule->nrname_handle );
-        _llseek32( hFile, ne_header.nrname_tab_offset, SEEK_SET );
-        if (_lread32( hFile, buffer, ne_header.nrname_tab_length )
+        _llseek16( hFile, ne_header.nrname_tab_offset, SEEK_SET );
+        if (_hread16( hFile, buffer, ne_header.nrname_tab_length )
               != ne_header.nrname_tab_length)
         {
             GlobalFree16( pModule->nrname_handle );
@@ -620,19 +668,18 @@
 
     for (i = 0; i < pModule->modref_count; i++, pModRef++)
     {
-        char buffer[256];
+        char buffer[260];
         BYTE *pstr = (BYTE *)pModule + pModule->import_table + *pModRef;
         memcpy( buffer, pstr + 1, *pstr );
         strcpy( buffer + *pstr, ".dll" );
         TRACE(module, "Loading '%s'\n", buffer );
-        if (!(*pModRef = MODULE_FindModule16( buffer )))
+        if (!(*pModRef = GetModuleHandle16( buffer )))
         {
             /* If the DLL is not loaded yet, load it and store */
             /* its handle in the list of DLLs to initialize.   */
             HMODULE16 hDLL;
 
-            if ((hDLL = MODULE_Load( buffer, NE_FFLAGS_IMPLICIT,
-                                     NULL, NULL, 0 )) == 2)
+            if ((hDLL = NE_LoadModule( buffer, NULL, TRUE, TRUE )) == 2)
             {
                 /* file not found */
                 char *p;
@@ -642,13 +689,13 @@
                 if (!(p = strrchr( buffer, '\\' ))) p = buffer;
                 memcpy( p + 1, pstr + 1, *pstr );
                 strcpy( p + 1 + *pstr, ".dll" );
-                hDLL = MODULE_Load( buffer, NE_FFLAGS_IMPLICIT, NULL, NULL, 0);
+                hDLL = NE_LoadModule( buffer, NULL, TRUE, TRUE );
             }
             if (hDLL < 32)
             {
                 /* FIXME: cleanup what was done */
 
-                fprintf( stderr, "Could not load '%s' required by '%.*s', error = %d\n",
+               WARN( module, "Could not load '%s' required by '%.*s', error=%d\n",
                          buffer, *((BYTE*)pModule + pModule->name_table),
                          (char *)pModule + pModule->name_table + 1, hDLL );
                 return FALSE;
@@ -658,7 +705,7 @@
         }
         else  /* Increment the reference count of the DLL */
         {
-            NE_MODULE *pOldDLL = MODULE_GetPtr16( *pModRef );
+            NE_MODULE *pOldDLL = NE_GetPtr( *pModRef );
             if (pOldDLL) pOldDLL->count++;
         }
     }
@@ -675,24 +722,60 @@
  * without a preceding length byte).
  * If cmd_line is NULL, the module is loaded as a library even if it is a .exe
  */
-HINSTANCE16 NE_LoadModule( HFILE32 hFile, OFSTRUCT *ofs, UINT16 flags,
-                           LPCSTR cmd_line, LPCSTR env, UINT32 show_cmd )
+HINSTANCE16 NE_LoadModule( LPCSTR name, HINSTANCE16 *hPrevInstance,
+                           BOOL32 implicit, BOOL32 lib_only )
 {
     HMODULE16 hModule;
     HINSTANCE16 hInstance;
     NE_MODULE *pModule;
+    HFILE16 hFile;
+    OFSTRUCT ofs;
+
+    /* Check if the module is already loaded */
+
+    if ((hModule = GetModuleHandle16( name )) != 0)
+    {
+        HINSTANCE16 prev;
+        pModule = NE_GetPtr( hModule );
+        hInstance = NE_CreateInstance( pModule, &prev, lib_only );
+        if (hInstance != prev)  /* not a library */
+            NE_LoadSegment( pModule, pModule->dgroup );
+        pModule->count++;
+        if (hPrevInstance) *hPrevInstance = prev;
+        return hInstance;
+    }
+    if (hPrevInstance) *hPrevInstance = 0;
+
+    /* Try to load the built-in first if not disabled */
+
+    if ((hModule = fnBUILTIN_LoadModule( name, FALSE ))) return hModule;
+
+    if ((hFile = OpenFile16( name, &ofs, OF_READ )) == HFILE_ERROR16)
+    {
+        /* Now try the built-in even if disabled */
+        if ((hModule = fnBUILTIN_LoadModule( name, TRUE )))
+        {
+            WARN(module, "Could not load Windows DLL '%s', using built-in module.\n", name );
+            return hModule;
+        }
+        return 2;  /* File not found */
+    }
 
     /* Create the module structure */
 
-    if ((hModule = NE_LoadExeHeader( hFile, ofs )) < 32) return hModule;
-
-    pModule = MODULE_GetPtr16( hModule );
-    pModule->flags |= flags; /* stamp implicitly loaded modules */
+    hModule = NE_LoadExeHeader( hFile, &ofs );
+    _lclose16( hFile );
+    if (hModule < 32) return hModule;
+    pModule = NE_GetPtr( hModule );
 
     /* Allocate the segments for this module */
 
-    NE_CreateSegments( hModule );
-    hInstance = MODULE_CreateInstance( hModule, NULL, (cmd_line == NULL) );
+    if (!NE_CreateSegments( pModule ) ||
+        !(hInstance = NE_CreateInstance( pModule, NULL, lib_only )))
+    {
+        GlobalFreeAll( hModule );
+        return 8;  /* Insufficient memory */
+    }
 
     /* Load the referenced DLLs */
 
@@ -716,21 +799,307 @@
      * when we load implicitly linked DLLs this will be done by InitTask().
      */
 
-    if ((pModule->flags & (NE_FFLAGS_LIBMODULE | NE_FFLAGS_IMPLICIT)) ==
-                                                           NE_FFLAGS_LIBMODULE)
+    if (!implicit && (pModule->flags & NE_FFLAGS_LIBMODULE))
         NE_InitializeDLLs( hModule );
 
-    /* Create a task for this instance */
+    return hInstance;
+}
 
-    if (cmd_line && !(pModule->flags & NE_FFLAGS_LIBMODULE))
+
+/***********************************************************************
+ *           LoadLibrary   (KERNEL.95)
+ */
+HINSTANCE16 WINAPI LoadLibrary16( LPCSTR libname )
+{
+    HINSTANCE16 handle;
+    LPCSTR p;
+    char *new_name;
+
+    TRACE(module, "(%08x) %s\n", (int)libname, libname);
+
+    /* Check for an extension */
+
+    if ((p = strrchr( libname, '.')) && !strchr( p, '/' ) && !strchr( p, '\\'))
     {
-        PDB32 *pdb;
-
-	pModule->flags |= NE_FFLAGS_GUI;
-
-        pdb = PROCESS_Create( pModule, cmd_line, env, hInstance, 0, show_cmd );
-        if (pdb && (GetNumTasks() > 1)) Yield16();
+        /* An extension is present -> use the name as is */
+        return NE_LoadModule( libname, NULL, FALSE, TRUE );
     }
 
-    return hInstance;
+    /* Now append .dll before loading */
+
+    if (!(new_name = HeapAlloc( GetProcessHeap(), 0, strlen(libname) + 4 )))
+        return 0;
+    strcpy( new_name, libname );
+    strcat( new_name, ".dll" );
+    handle = NE_LoadModule( new_name, NULL, FALSE, TRUE );
+    HeapFree( GetProcessHeap(), 0, new_name );
+    return handle;
+}
+
+
+/**********************************************************************
+ *	    MODULE_CallWEP
+ *
+ * Call a DLL's WEP, allowing it to shut down.
+ * FIXME: we always pass the WEP WEP_FREE_DLL, never WEP_SYSTEM_EXIT
+ */
+static BOOL16 MODULE_CallWEP( HMODULE16 hModule )
+{
+    FARPROC16 WEP = (FARPROC16)0;
+    WORD ordinal = NE_GetOrdinal( hModule, "WEP" );
+
+    if (ordinal) WEP = NE_GetEntryPoint( hModule, ordinal );
+    if (!WEP)
+    {
+	WARN(module, "module %04x doesn't have a WEP\n", hModule );
+	return FALSE;
+    }
+    return Callbacks->CallWindowsExitProc( WEP, WEP_FREE_DLL );
+}
+
+
+/**********************************************************************
+ *	    NE_FreeModule
+ *
+ * Implementation of FreeModule16().
+ */
+static BOOL16 NE_FreeModule( HMODULE16 hModule, BOOL32 call_wep )
+{
+    HMODULE16 *hPrevModule;
+    NE_MODULE *pModule;
+    HMODULE16 *pModRef;
+    int i;
+
+    if (!(pModule = NE_GetPtr( hModule ))) return FALSE;
+    hModule = pModule->self;
+
+    TRACE( module, "%04x count %d\n", hModule, pModule->count );
+
+    if (((INT16)(--pModule->count)) > 0 ) return TRUE;
+    else pModule->count = 0;
+
+    if (pModule->flags & NE_FFLAGS_BUILTIN)
+        return FALSE;  /* Can't free built-in module */
+
+    if (call_wep)
+    {
+        if (pModule->flags & NE_FFLAGS_LIBMODULE)
+        {
+            TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
+            MODULE_CallWEP( hModule );
+
+            /* Free the objects owned by the DLL module */
+
+            if (pTask && pTask->userhandler)
+                pTask->userhandler( hModule, USIG_DLL_UNLOAD, 0,
+                                    pTask->hInstance, pTask->hQueue );
+        }
+        else
+            call_wep = FALSE;  /* We are freeing a task -> no more WEPs */
+    }
+    
+
+    /* Clear magic number just in case */
+
+    pModule->magic = pModule->self = 0;
+
+      /* Remove it from the linked list */
+
+    hPrevModule = &hFirstModule;
+    while (*hPrevModule && (*hPrevModule != hModule))
+    {
+        hPrevModule = &(NE_GetPtr( *hPrevModule ))->next;
+    }
+    if (*hPrevModule) *hPrevModule = pModule->next;
+
+    /* Free the referenced modules */
+
+    pModRef = (HMODULE16*)NE_MODULE_TABLE( pModule );
+    for (i = 0; i < pModule->modref_count; i++, pModRef++)
+    {
+        NE_FreeModule( *pModRef, call_wep );
+    }
+
+    /* Free the module storage */
+
+    GlobalFreeAll( hModule );
+
+    /* Remove module from cache */
+
+    if (pCachedModule == pModule) pCachedModule = NULL;
+    return TRUE;
+}
+
+
+/**********************************************************************
+ *	    FreeModule16    (KERNEL.46)
+ */
+BOOL16 WINAPI FreeModule16( HMODULE16 hModule )
+{
+    return NE_FreeModule( hModule, TRUE );
+}
+
+
+/***********************************************************************
+ *           FreeLibrary16   (KERNEL.96)
+ */
+void WINAPI FreeLibrary16( HINSTANCE16 handle )
+{
+    TRACE(module,"%04x\n", handle );
+    FreeModule16( handle );
+}
+
+
+/**********************************************************************
+ *	    GetModuleName    (KERNEL.27)
+ */
+BOOL16 WINAPI GetModuleName( HINSTANCE16 hinst, LPSTR buf, INT16 count )
+{
+    NE_MODULE *pModule;
+    BYTE *p;
+
+    if (!(pModule = NE_GetPtr( hinst ))) return FALSE;
+    p = (BYTE *)pModule + pModule->name_table;
+    if (count > *p) count = *p + 1;
+    if (count > 0)
+    {
+        memcpy( buf, p + 1, count - 1 );
+        buf[count-1] = '\0';
+    }
+    return TRUE;
+}
+
+
+/**********************************************************************
+ *	    GetModuleUsage    (KERNEL.48)
+ */
+INT16 WINAPI GetModuleUsage( HINSTANCE16 hModule )
+{
+    NE_MODULE *pModule = NE_GetPtr( hModule );
+    return pModule ? pModule->count : 0;
+}
+
+
+/**********************************************************************
+ *	    GetExpWinVer    (KERNEL.167)
+ */
+WORD WINAPI GetExpWinVer( HMODULE16 hModule )
+{
+    NE_MODULE *pModule = NE_GetPtr( hModule );
+    return pModule ? pModule->expected_version : 0;
+}
+
+
+/**********************************************************************
+ *	    GetModuleFileName16    (KERNEL.49)
+ */
+INT16 WINAPI GetModuleFileName16( HINSTANCE16 hModule, LPSTR lpFileName,
+                                  INT16 nSize )
+{
+    NE_MODULE *pModule;
+
+    if (!hModule) hModule = GetCurrentTask();
+    if (!(pModule = NE_GetPtr( hModule ))) return 0;
+    lstrcpyn32A( lpFileName, NE_MODULE_NAME(pModule), nSize );
+    TRACE(module, "%s\n", lpFileName );
+    return strlen(lpFileName);
+}
+
+
+/**********************************************************************
+ *	    GetModuleHandle16    (KERNEL.47)
+ *
+ * Find a module from a path name.
+ *
+ * RETURNS
+ *	the win16 module handle if found
+ * 	0 if not
+ */
+HMODULE16 WINAPI WIN16_GetModuleHandle( SEGPTR name )
+{
+    if (HIWORD(name) == 0) return GetExePtr( (HINSTANCE16)name );
+    return GetModuleHandle16( PTR_SEG_TO_LIN(name) );
+}
+
+HMODULE16 WINAPI GetModuleHandle16( LPCSTR name )
+{
+    HMODULE16 hModule = hFirstModule;
+    LPCSTR filename, dotptr, modulepath, modulename;
+    BYTE len, *name_table;
+
+    if (!(filename = strrchr( name, '\\' ))) filename = name;
+    else filename++;
+    if ((dotptr = strrchr( filename, '.' )) != NULL)
+        len = (BYTE)(dotptr - filename);
+    else len = strlen( filename );
+
+    while (hModule)
+    {
+        NE_MODULE *pModule = NE_GetPtr( hModule );
+        if (!pModule) break;
+        modulepath = NE_MODULE_NAME(pModule);
+        if (!(modulename = strrchr( modulepath, '\\' )))
+            modulename = modulepath;
+        else modulename++;
+        if (!lstrcmpi32A( modulename, filename )) return hModule;
+
+        name_table = (BYTE *)pModule + pModule->name_table;
+        if ((*name_table == len) && !lstrncmpi32A(filename, name_table+1, len))
+            return hModule;
+        hModule = pModule->next;
+    }
+    return 0;
+}
+
+
+/**********************************************************************
+ *	    ModuleFirst    (TOOLHELP.59)
+ */
+BOOL16 WINAPI ModuleFirst( MODULEENTRY *lpme )
+{
+    lpme->wNext = hFirstModule;
+    return ModuleNext( lpme );
+}
+
+
+/**********************************************************************
+ *	    ModuleNext    (TOOLHELP.60)
+ */
+BOOL16 WINAPI ModuleNext( MODULEENTRY *lpme )
+{
+    NE_MODULE *pModule;
+    char *name;
+
+    if (!lpme->wNext) return FALSE;
+    if (!(pModule = NE_GetPtr( lpme->wNext ))) return FALSE;
+    name = (char *)pModule + pModule->name_table;
+    memcpy( lpme->szModule, name + 1, *name );
+    lpme->szModule[(BYTE)*name] = '\0';
+    lpme->hModule = lpme->wNext;
+    lpme->wcUsage = pModule->count;
+    strncpy( lpme->szExePath, NE_MODULE_NAME(pModule), MAX_PATH );
+    lpme->szExePath[MAX_PATH] = '\0';
+    lpme->wNext = pModule->next;
+    return TRUE;
+}
+
+
+/**********************************************************************
+ *	    ModuleFindName    (TOOLHELP.61)
+ */
+BOOL16 WINAPI ModuleFindName( MODULEENTRY *lpme, LPCSTR name )
+{
+    lpme->wNext = GetModuleHandle16( name );
+    return ModuleNext( lpme );
+}
+
+
+/**********************************************************************
+ *	    ModuleFindHandle    (TOOLHELP.62)
+ */
+BOOL16 WINAPI ModuleFindHandle( MODULEENTRY *lpme, HMODULE16 hModule )
+{
+    hModule = GetExePtr( hModule );
+    lpme->wNext = hModule;
+    return ModuleNext( lpme );
 }
diff --git a/loader/ne/resource.c b/loader/ne/resource.c
index 832be3b..807871d 100644
--- a/loader/ne/resource.c
+++ b/loader/ne/resource.c
@@ -183,8 +183,8 @@
                                         HRSRC16 hRsrc )
 {
     int  fd;
-    NE_MODULE* pModule = MODULE_GetPtr16( hModule );
-    if ( pModule && (fd = MODULE_OpenFile( hModule )) >= 0)
+    NE_MODULE* pModule = NE_GetPtr( hModule );
+    if (pModule && (fd = NE_OpenFile( pModule )) >= 0)
     {
 	HGLOBAL16 handle;
 	WORD sizeShift = *(WORD *)((char *)pModule + pModule->res_table);
@@ -215,7 +215,7 @@
  */
 BOOL32 NE_InitResourceHandler( HMODULE16 hModule )
 {
-    NE_MODULE *pModule = MODULE_GetPtr16( hModule );
+    NE_MODULE *pModule = NE_GetPtr( hModule );
     NE_TYPEINFO *pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2);
 
     TRACE(resource,"InitResourceHandler[%04x]\n", hModule );
@@ -236,7 +236,7 @@
                                      FARPROC16 resourceHandler )
 {
     FARPROC16 prevHandler = NULL;
-    NE_MODULE *pModule = MODULE_GetPtr16( hModule );
+    NE_MODULE *pModule = NE_GetPtr( hModule );
     NE_TYPEINFO *pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2);
 
     if (!pModule || !pModule->res_table) return NULL;
@@ -264,7 +264,7 @@
     NE_TYPEINFO *pTypeInfo;
     HRSRC16 hRsrc;
 
-    NE_MODULE *pModule = MODULE_GetPtr16( hModule );
+    NE_MODULE *pModule = NE_GetPtr( hModule );
     if (!pModule || !pModule->res_table) return 0;
 
     assert( !__winelib );  /* Can't use Win16 resource functions in Winelib */
@@ -333,7 +333,7 @@
     NE_NAMEINFO *pNameInfo=NULL;
     WORD sizeShift;
 
-    NE_MODULE *pModule = MODULE_GetPtr16( hModule );
+    NE_MODULE *pModule = NE_GetPtr( hModule );
     if (!pModule || !pModule->res_table || !hRsrc) return 0;
 
     TRACE( resource, "module=%04x res=%04x size=%ld\n", hModule, hRsrc, size );
@@ -361,7 +361,7 @@
     if (!(hInstance = GetExePtr( hInstance ))) return 0;
     if(wType != 0x10)	/* 0x10 is the only observed value, passed from
                            CreateCursorIndirect. */
-        fprintf(stderr, "DirectResAlloc: wType = %x\n", wType);
+        TRACE(resource, "(wType=%x)\n", wType);
     return GLOBAL_Alloc(GMEM_MOVEABLE, wSize, hInstance, FALSE, FALSE, FALSE);
 }
 
@@ -373,7 +373,7 @@
 {
     HFILE32 fd;
 
-    NE_MODULE *pModule = MODULE_GetPtr16( hModule );
+    NE_MODULE *pModule = NE_GetPtr( hModule );
     if (!pModule || !pModule->res_table || !hRsrc) return -1;
 
     TRACE(resource, "module=%04x res=%04x\n", hModule, hRsrc );
@@ -398,7 +398,7 @@
     NE_NAMEINFO *pNameInfo=NULL;
     WORD sizeShift;
 
-    NE_MODULE *pModule = MODULE_GetPtr16( hModule );
+    NE_MODULE *pModule = NE_GetPtr( hModule );
     if (!pModule || !pModule->res_table) return 0;
 
     TRACE(resource, "module=%04x res=%04x\n", hModule, hRsrc );
@@ -418,7 +418,7 @@
 {
     NE_TYPEINFO *pTypeInfo;
     NE_NAMEINFO *pNameInfo = NULL;
-    NE_MODULE *pModule = MODULE_GetPtr16( hModule );
+    NE_MODULE *pModule = NE_GetPtr( hModule );
     int d;
 
     TRACE( resource, "module=%04x res=%04x\n", hModule, hRsrc );
@@ -464,7 +464,7 @@
 	  	loader = (RESOURCEHANDLER16)pTypeInfo->resloader;
 	    else /* this is really bad */
 	    {
-		fprintf( stderr, "[%04x]: Missing resource handler!!!...\n", hModule);
+		ERR(resource, "[%04x]: Missing resource handler!\n", hModule);
 		loader = NE_DefResourceHandler;
 	    }
 
@@ -513,8 +513,7 @@
     NE_TYPEINFO *pTypeInfo;
     NE_NAMEINFO *pNameInfo;
     WORD count;
-    HMODULE16 hModule  = GetExePtr( handle );
-    NE_MODULE *pModule = MODULE_GetPtr16( hModule );
+    NE_MODULE *pModule = NE_GetPtr( GetExePtr(handle) );
 
     if (!handle || !pModule || !pModule->res_table) return handle;
 
@@ -545,7 +544,7 @@
     }
 
     TRACE(resource, "[%04x]: no intrinsic resource for %04x, assuming DirectResAlloc()!\n", 
-		 hModule, handle );
+          pModule->self, handle );
     GlobalFree16( handle ); 
     return handle;
 }
diff --git a/loader/ne/segment.c b/loader/ne/segment.c
index 99f78ce..a6478a5 100644
--- a/loader/ne/segment.c
+++ b/loader/ne/segment.c
@@ -72,7 +72,7 @@
 
     if (!pSeg->filepos) return TRUE;  /* No file image, just return */
 	
-    fd = MODULE_OpenFile( pModule->self );
+    fd = NE_OpenFile( pModule );
     TRACE(module, "Loading segment %d, selector=%04x, flags=%04x\n",
                     segnum, pSeg->selector, pSeg->flags );
     lseek( fd, pSeg->filepos << pModule->alignment, SEEK_SET );
@@ -118,8 +118,8 @@
  		   pSeg->minsize ? pSeg->minsize : 0x10000);
  	    FreeSelector(newselector);
  	    pSeg->selector = oldselector;
- 	    fprintf(stderr, "A new selector was allocated for the dgroup segment\n"
- 		    "Old selector is %d, new one is %d", oldselector, newselector);
+ 	    TRACE(module, "New selector allocated for dgroup segment:Old=%d,New=%d\n", 
+                oldselector, newselector);
  	  } else {
  	    FreeSelector(pSeg->selector);
  	    pSeg->selector = newselector;
@@ -201,22 +201,22 @@
             address = NE_GetEntryPoint( module, ordinal );
             if (!address)
             {
-                NE_MODULE *pTarget = MODULE_GetPtr16( module );
+                NE_MODULE *pTarget = NE_GetPtr( module );
                 if (!pTarget)
-                    fprintf( stderr, "Module not found: %04x, reference %d of module %*.*s\n",
+                    WARN(module, "Module not found: %04x, reference %d of module %*.*s\n",
                              module, rep->target1, 
                              *((BYTE *)pModule + pModule->name_table),
                              *((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",
+                    WARN(module, "No handler for %.*s.%d, setting to 0:0\n",
                             *((BYTE *)pTarget + pTarget->name_table),
                             (char *)pTarget + pTarget->name_table + 1,
                             ordinal );
             }
             if (TRACE_ON(fixup))
             {
-                NE_MODULE *pTarget = MODULE_GetPtr16( module );
+                NE_MODULE *pTarget = NE_GetPtr( module );
                 TRACE( fixup, "%d: %.*s.%d=%04x:%04x %s\n", i + 1, 
                        *((BYTE *)pTarget + pTarget->name_table),
                        (char *)pTarget + pTarget->name_table + 1,
@@ -236,14 +236,14 @@
 
             if (ERR_ON(fixup) && !address)
             {
-                NE_MODULE *pTarget = MODULE_GetPtr16( module );
+                NE_MODULE *pTarget = NE_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 );
             }
             if (TRACE_ON(fixup))
             {
-	        NE_MODULE *pTarget = MODULE_GetPtr16( module );
+	        NE_MODULE *pTarget = NE_GetPtr( module );
                 TRACE( fixup, "%d: %.*s.%s=%04x:%04x %s\n", i + 1, 
                        *((BYTE *)pTarget + pTarget->name_table),
                        (char *)pTarget + pTarget->name_table + 1,
@@ -288,8 +288,12 @@
         /* Apparently, high bit of address_type is sometimes set; */
         /* we ignore it for now */
 	if (rep->address_type > NE_RADDR_OFFSET32)
+        {
+            char module[10];
+            GetModuleName( pModule->self, module, sizeof(module) );
             ERR( fixup, "WARNING: module %s: unknown reloc addr type = 0x%02x. Please report.\n",
-                 MODULE_GetModuleName(pModule->self), rep->address_type );
+                 module, rep->address_type );
+        }
 
         if (additive)
         {
@@ -405,7 +409,7 @@
         stack16Top->ip = 0;
         stack16Top->cs = 0;
 
-        hf = FILE_DupUnixHandle( MODULE_OpenFile( pModule->self ) );
+        hf = FILE_DupUnixHandle( NE_OpenFile( pModule ) );
         Callbacks->CallBootAppProc(selfloadheader->BootApp, pModule->self, hf);
         _lclose32(hf);
         /* some BootApp procs overwrite the selector of dgroup */
@@ -490,7 +494,7 @@
 			if (pModule->flags & NE_FFLAGS_MULTIPLEDATA)
                         {
 			    /* can this happen? */
-			    fprintf( stderr, "FixupPrologs got confused\n" );
+			    ERR(fixup, "FixupPrologs got confused\n" );
 			}
                         else if (pModule->flags & NE_FFLAGS_SINGLEDATA)
                         {
@@ -523,9 +527,8 @@
  *
  * Call the DLL initialization code
  */
-static BOOL32 NE_InitDLL( TDB* pTask, HMODULE16 hModule )
+static BOOL32 NE_InitDLL( TDB* pTask, NE_MODULE *pModule )
 {
-    NE_MODULE *pModule;
     SEGTABLEENTRY *pSegTable;
     CONTEXT context;
 
@@ -536,7 +539,6 @@
      * es:si  command line (always 0)
      */
 
-    if (!(pModule = MODULE_GetPtr16( hModule ))) return FALSE;
     pSegTable = NE_SEG_TABLE( pModule );
 
     if (!(pModule->flags & NE_FFLAGS_LIBMODULE) ||
@@ -548,7 +550,7 @@
 
     if (pTask && pTask->userhandler)
     {
-        pTask->userhandler( hModule, USIG_DLL_LOAD, 0, pTask->hInstance,
+        pTask->userhandler( pModule->self, USIG_DLL_LOAD, 0, pTask->hInstance,
                             pTask->hQueue );
     }
 
@@ -561,7 +563,7 @@
         if (pModule->flags & NE_FFLAGS_MULTIPLEDATA || pModule->dgroup)
         {
             /* Not SINGLEDATA */
-            fprintf(stderr, "Library is not marked SINGLEDATA\n");
+            ERR(dll, "Library is not marked SINGLEDATA\n");
             exit(1);
         }
         else  /* DATA NONE DLL */
@@ -589,7 +591,7 @@
     EIP_reg(&context) = pModule->ip;
     EBP_reg(&context) = OFFSETOF(THREAD_Current()->cur_stack)
                           + (WORD)&((STACK16FRAME*)0)->bp;
-    EDI_reg(&context) = DS_reg(&context) ? DS_reg(&context) : hModule;
+    EDI_reg(&context) = DS_reg(&context) ? DS_reg(&context) : pModule->self;
 
 
     pModule->cs = 0;  /* Don't initialize it twice */
@@ -600,6 +602,44 @@
     return TRUE;
 }
 
+/***********************************************************************
+ *           NE_CallDllEntryPoint
+ *
+ * Call the DllEntryPoint of DLLs with subsystem >= 4.0 
+ */
+
+static void NE_CallDllEntryPoint( NE_MODULE *pModule, DWORD dwReason )
+{
+    FARPROC16 entryPoint;
+    WORD ordinal;
+    CONTEXT context;
+    THDB *thdb = THREAD_Current();
+    LPBYTE stack = (LPBYTE)THREAD_STACK16(thdb);
+
+    if (pModule->expected_version < 0x0400) return;
+    if (!(ordinal = NE_GetOrdinal( pModule->self, "DllEntryPoint" ))) return;
+    if (!(entryPoint = NE_GetEntryPoint( pModule->self, ordinal ))) return;
+
+    memset( &context, 0, sizeof(context) );
+
+    CS_reg(&context) = HIWORD(entryPoint);
+    IP_reg(&context) = LOWORD(entryPoint);
+    EBP_reg(&context) =  OFFSETOF( thdb->cur_stack )
+                         + (WORD)&((STACK16FRAME*)0)->bp;
+
+    *(DWORD *)(stack -  4) = dwReason;      /* dwReason */
+    *(WORD *) (stack -  6) = pModule->self; /* hInst */
+    *(WORD *) (stack -  8) = 0;             /* wDS */
+    *(WORD *) (stack - 10) = 0;             /* wHeapSize */
+    *(DWORD *)(stack - 14) = 0;             /* dwReserved1 */
+    *(WORD *) (stack - 16) = 0;             /* wReserved2 */
+
+    TRACE(dll, "Calling DllEntryPoint, cs:ip=%04lx:%04x\n",
+          CS_reg(&context), IP_reg(&context));
+
+    Callbacks->CallRegisterShortProc( &context, 16 );
+}
+
 
 /***********************************************************************
  *           NE_InitializeDLLs
@@ -613,8 +653,8 @@
     NE_MODULE *pModule;
     HMODULE16 *pDLL;
 
-    if (!(pModule = MODULE_GetPtr16( hModule ))) return;
-    if (pModule->flags & NE_FFLAGS_WIN32) return;
+    if (!(pModule = NE_GetPtr( hModule ))) return;
+    assert( !(pModule->flags & NE_FFLAGS_WIN32) );
 
     if (pModule->dlls_to_init)
     {
@@ -626,7 +666,47 @@
         }
         GlobalFree16( to_init );
     }
-    NE_InitDLL( pTask, hModule );
+    NE_InitDLL( pTask, pModule );
+    NE_CallDllEntryPoint( pModule, DLL_PROCESS_ATTACH );
+}
+
+
+/***********************************************************************
+ *           NE_CreateInstance
+ *
+ * If lib_only is TRUE, handle the module like a library even if it is a .EXE
+ */
+HINSTANCE16 NE_CreateInstance( NE_MODULE *pModule, HINSTANCE16 *prev,
+                               BOOL32 lib_only )
+{
+    SEGTABLEENTRY *pSegment;
+    int minsize;
+    HINSTANCE16 hNewInstance;
+
+    if (pModule->dgroup == 0)
+    {
+        if (prev) *prev = pModule->self;
+        return pModule->self;
+    }
+
+    pSegment = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
+    if (prev) *prev = pSegment->selector;
+
+      /* if it's a library, create a new instance only the first time */
+    if (pSegment->selector)
+    {
+        if (pModule->flags & NE_FFLAGS_LIBMODULE) return pSegment->selector;
+        if (lib_only) return pSegment->selector;
+    }
+
+    minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
+    if (pModule->ss == pModule->dgroup) minsize += pModule->stack_size;
+    minsize += pModule->heap_size;
+    hNewInstance = GLOBAL_Alloc( GMEM_ZEROINIT | GMEM_FIXED, minsize,
+                                 pModule->self, FALSE, FALSE, FALSE );
+    if (!hNewInstance) return 0;
+    pSegment->selector = hNewInstance;
+    return hNewInstance;
 }
 
 
@@ -639,7 +719,7 @@
 /* It does nothing */
 void WINAPI PatchCodeHandle(HANDLE16 hSel)
 {
-	fprintf(stderr,"PatchCodeHandle(%04x),stub!\n",hSel);
+    FIXME(module,"(%04x): stub.\n",hSel);
 }
 
 
@@ -682,13 +762,11 @@
 /***********************************************************************
  *           NE_CreateSegments
  */
-BOOL32 NE_CreateSegments( HMODULE16 hModule )
+BOOL32 NE_CreateSegments( NE_MODULE *pModule )
 {
     SEGTABLEENTRY *pSegment;
-    NE_MODULE *pModule;
     int i, minsize;
 
-    if (!(pModule = MODULE_GetPtr16( hModule ))) return FALSE;
     assert( !(pModule->flags & NE_FFLAGS_WIN32) );
 
     pSegment = NE_SEG_TABLE( pModule );
@@ -696,10 +774,10 @@
     {
         minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
         if (i == pModule->ss) minsize += pModule->stack_size;
-	/* The DGROUP is allocated by MODULE_CreateInstance */
+	/* The DGROUP is allocated by NE_CreateInstance */
         if (i == pModule->dgroup) continue;
         pSegment->selector = GLOBAL_Alloc( NE_Ne2MemFlags(pSegment->flags),
-                                      minsize, hModule,
+                                      minsize, pModule->self,
                                       !(pSegment->flags & NE_SEGFLAGS_DATA),
                                       FALSE,
                             FALSE /*pSegment->flags & NE_SEGFLAGS_READONLY*/ );
@@ -710,3 +788,15 @@
                             (pModule->dgroup - 1) * sizeof(SEGTABLEENTRY) : 0;
     return TRUE;
 }
+
+
+/**********************************************************************
+ *	    IsSharedSelector    (KERNEL.345)
+ */
+BOOL16 WINAPI IsSharedSelector( HANDLE16 selector )
+{
+    /* Check whether the selector belongs to a DLL */
+    NE_MODULE *pModule = NE_GetPtr( selector );
+    if (!pModule) return FALSE;
+    return (pModule->flags & NE_FFLAGS_LIBMODULE) != 0;
+}
diff --git a/loader/pe_image.c b/loader/pe_image.c
index 12c962e..3d2dfbd 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -241,18 +241,14 @@
 	/* don't use MODULE_Load, Win32 creates new task differently */
 	res = PE_LoadLibraryEx32A( name, process, 0, 0 );
 	if (res <= (HMODULE32) 32) {
-	    char buffer[1024];
-
-	    /* Try with prepending the path of the current module */
-	    if (GetModuleFileName32A( wm->module, buffer, sizeof (buffer))) {
-	        char *p;
-
-		if (!(p = strrchr (buffer, '\\')))
-		    p = buffer;
-		strcpy (p + 1, name);
-		res = PE_LoadLibraryEx32A( buffer, process, 0, 0 );
-	    } else
-	    	ERR(win32,"cannot find the module just loaded!\n");
+	    char *p,buffer[2000];
+	    
+	    /* GetModuleFileName would use the wrong process, so don't use it */
+	    strcpy(buffer,wm->shortname);
+	    if (!(p = strrchr (buffer, '\\')))
+		p = buffer;
+	    strcpy (p + 1, name);
+	    res = PE_LoadLibraryEx32A( buffer, process, 0, 0 );
 	}
 	if (res <= (HMODULE32) 32) {
 	    WARN (module, "Module %s not found\n", name);
@@ -533,36 +529,32 @@
 /**********************************************************************
  * This maps a loaded PE dll into the address space of the specified process.
  */
-static BOOL32 PE_MapImage( HMODULE32 *phModule, PDB32 *process,
-                           OFSTRUCT *ofs, DWORD flags )
+static BOOL32 PE_MapImage( PDB32 *process,WINE_MODREF *wm, OFSTRUCT *ofs, DWORD flags )
 {
-	WINE_MODREF		*wm;
 	PE_MODREF		*pem;
 	int			i, result;
 	DWORD			load_addr;
 	IMAGE_DATA_DIRECTORY	dir;
 	char			*modname;
 	int			vma_size;
-	HMODULE32		hModule = *phModule;
+	HMODULE32		hModule = wm->module;
 
         IMAGE_SECTION_HEADER *pe_seg;
         IMAGE_DOS_HEADER *dos_header = (IMAGE_DOS_HEADER *)hModule;
         IMAGE_NT_HEADERS *nt_header = PE_HEADER(hModule);
 	
-
-	wm = (WINE_MODREF*)HeapAlloc(process->heap,HEAP_ZERO_MEMORY,
-                                    sizeof(*wm));
-	wm->type= MODULE32_PE;
 	pem 	= &(wm->binfmt.pe);
 
-	/* NOTE: fixup_imports takes care of the correct order */
-	wm->next	= process->modref_list;
-	process->modref_list = wm;
+	result = GetLongPathName32A(ofs->szPathName,NULL,0);
+	wm->longname = (char*)HeapAlloc(process->heap,0,result+1);
+	GetLongPathName32A(ofs->szPathName,wm->longname,result+1);
+
+	wm->shortname = HEAP_strdupA(process->heap,0,ofs->szPathName);
 
 	if (!(nt_header->FileHeader.Characteristics & IMAGE_FILE_DLL))
         {
 		if (process->exe_modref)
-			WARN(win32,"overwriting old exe_modref... arrgh\n");
+			FIXME(win32,"overwriting old exe_modref... arrgh\n");
 		process->exe_modref = wm;
 	}
 
@@ -577,10 +569,10 @@
 						 MEM_RESERVE | MEM_COMMIT,
 						 PAGE_EXECUTE_READWRITE );
 	}
-	/* *phModule is the module32 entry in the NE_MODULE. We need to
-	 * change it here, since it can get referenced by fixup_imports()
+	/* NOTE: this changes a value in the process modref chain, which can
+	 * be accessed independently from this function
 	 */
-	wm->module = *phModule = (HMODULE32)load_addr;
+	wm->module = (HMODULE32)load_addr;
 
 	TRACE(win32, "Load addr is really %lx, range %x\n",
                       load_addr, vma_size);
@@ -713,8 +705,6 @@
 		modname = s = ofs->szPathName;
 		while ((s=strchr(modname,'\\')))
 			modname = s+1;
-		if ((s=strchr(modname,'.')))
-			*s='\0';
 		wm->modname = HEAP_strdupA(process->heap,0,modname);
 	}
 	if(pem->pe_import)	{
@@ -760,13 +750,9 @@
 	WINE_MODREF	*wm;
 
 	if ((hModule = MODULE_FindModule32( process, name ))) {
-		
-		pModule = MODULE_GetPtr32(hModule);
 		for (wm= process->modref_list;wm;wm=wm->next)
-			if (wm->module == hModule) {
-				pModule->count++;
+			if (wm->module == hModule)
 				return hModule;
-			}
 		/* Since MODULE_FindModule32 uses the modref chain too, the
 		 * module MUST have been found above. If not, something has gone
 		 * terribly wrong.
@@ -781,31 +767,55 @@
 	if (HFILE_ERROR32==(hFile=OpenFile32(name,&ofs,OF_READ))) {
 		/* Now try the built-in even if disabled */
 		if ((hModule = BUILTIN32_LoadModule( name, TRUE, process ))) {
-			fprintf( stderr, "Warning: could not load external DLL '%s', using built-in module.\n", name );
-			return hModule;
+		    WARN( module, "Could not load external DLL '%s', using built-in module.\n", name );
+		    return hModule;
 		}
 		return 1;
 	}
+	/* will go away ... */
 	if ((hModule = MODULE_CreateDummyModule( &ofs )) < 32) {
 		_lclose32(hFile);
 		return hModule;
 	}
-	pModule		= (NE_MODULE *)GlobalLock16( hModule );
-	pModule->flags	= NE_FFLAGS_WIN32;
-	pModule->module32 = PE_LoadImage( hFile );
+	pModule         = (NE_MODULE *)GlobalLock16( hModule );
+	pModule->flags  = NE_FFLAGS_WIN32;
+	/* .. */
+
+	wm=(WINE_MODREF*)HeapAlloc(process->heap,HEAP_ZERO_MEMORY,sizeof(*wm));
+	wm->type = MODULE32_PE;
+	/* NOTE: fixup_imports takes care of the correct order */
+	wm->next = process->modref_list;
+	process->modref_list = wm;
+
+	wm->module = pModule->module32 = PE_LoadImage( hFile );
+
 	CloseHandle( hFile );
-        if (pModule->module32 < 32) 
+        if (wm->module < 32) 
         {
-            FreeLibrary32( hModule);
+	    process->modref_list = wm->next;
+	    HeapFree(process->heap,0,wm);
+	    ERR(win32,"can't load %s\n",ofs.szPathName);
             return 21; /* FIXME: probably 0 */
         }
 
 	/* (possible) recursion */
-	if (!PE_MapImage( &(pModule->module32), process, &ofs,flags)) {
-		/* FIXME: should free this module and its referenced ones */
-		return 0;
+	if (!PE_MapImage(process,wm,&ofs,flags)) {
+	    /* ERROR cleanup ... */
+	    WINE_MODREF	**xwm;
+
+	    ERR(win32,"couldn't load %s\n",ofs.szPathName);
+	    /* unlink from process modref chain */
+	    for (    xwm=&(process->modref_list);
+		     *xwm && (*xwm!=wm);
+		     xwm=&((*xwm)->next)
+	    ) /* EMPTY */;
+	    if (*xwm)
+	    	*xwm=(*xwm)->next;
+	    	
+	    return 0;
 	}
-	return pModule->module32;
+        pModule->module32 = wm->module;
+	return wm->module;
 }
 
 /*****************************************************************************
@@ -813,23 +823,30 @@
  * FIXME: this function should use PE_LoadLibraryEx32A, but currently can't
  * due to the PROCESS_Create stuff.
  */
-HINSTANCE16 PE_LoadModule( HFILE32 hFile, OFSTRUCT *ofs, LPCSTR cmd_line,
+HINSTANCE16 PE_LoadModule( LPCSTR name, LPCSTR cmd_line,
                            LPCSTR env, UINT16 show_cmd )
 {
     HMODULE16 hModule16;
     HMODULE32 hModule32;
     HINSTANCE16 hInstance;
     NE_MODULE *pModule;
+    HFILE32 hFile;
+    OFSTRUCT ofs;
     THDB *thdb = THREAD_Current();
-    
-    if ((hModule16 = MODULE_CreateDummyModule( ofs )) < 32) return hModule16;
+    PDB32 *process;
+    WINE_MODREF	*wm;
+
+    if ((hFile = OpenFile32( name, &ofs, OF_READ )) == HFILE_ERROR32)
+        return 2;  /* File not found */
+
+    if ((hModule16 = MODULE_CreateDummyModule( &ofs )) < 32) return hModule16;
     pModule = (NE_MODULE *)GlobalLock16( hModule16 );
     pModule->flags = NE_FFLAGS_WIN32;
 
     pModule->module32 = hModule32 = PE_LoadImage( hFile );
     if (hModule32 < 32) return 21;
 
-    hInstance = MODULE_CreateInstance( hModule16, NULL, (cmd_line == NULL) );
+    hInstance = NE_CreateInstance( pModule, NULL, (cmd_line == NULL) );
     if (cmd_line &&
         !(PE_HEADER(hModule32)->FileHeader.Characteristics & IMAGE_FILE_DLL))
     {
@@ -838,11 +855,21 @@
         TDB *pTask = (TDB *)GlobalLock16( pdb->task );
         thdb = pTask->thdb;
     }
-    if (!PE_MapImage( &(pModule->module32), thdb->process, ofs, 0 ))
+
+    process = thdb->process;
+
+    wm=(WINE_MODREF*)HeapAlloc(process->heap,HEAP_ZERO_MEMORY,sizeof(*wm));
+    wm->type = MODULE32_PE;
+    /* NOTE: fixup_imports takes care of the correct order */
+    wm->next = process->modref_list;
+    wm->module = hModule32;
+    process->modref_list = wm;
+    if (!PE_MapImage( process, wm, &ofs, 0 ))
     {
      	/* FIXME: should destroy the task created and free referenced stuff */
         return 0;
     }
+    pModule->module32 = wm->module;
     /* FIXME: Yuck. Is there no other good place to do that? */
     PE_InitTls( thdb );
     return hInstance;
diff --git a/loader/resource.c b/loader/resource.c
index 32f2a6d..c4bec2f 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -187,7 +187,7 @@
 	    break;
 	}
     if (__winelib)
-        fprintf(stderr,"SizeofResource32: not implemented for WINELIB\n");
+        FIXME(module,"Not implemented for WINELIB\n");
     return 0;
 }
 
diff --git a/loader/signal.c b/loader/signal.c
index 05cf70a..2e3dec6 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -158,7 +158,7 @@
 {
     extern void SYNC_SetupSignals(void);
 
-#ifdef HAVE_SIGALTSTACK
+#ifdef HAVE_WORKING_SIGALTSTACK
     struct sigaltstack ss;
     ss.ss_sp    = SIGNAL_Stack;
     ss.ss_size  = sizeof(SIGNAL_Stack);
diff --git a/loader/task.c b/loader/task.c
index 99c7611..2d25eac 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -37,7 +37,6 @@
 #define MIN_THUNKS  32
 
 extern INT32 WINSOCK_DeleteTaskWSI( TDB* pTask, struct _WSINFO* );
-extern BOOL32 MODULE_FreeModule( HMODULE16 hModule, TDB* ptaskContext );
 
   /* Pointer to function to switch to a larger stack */
 int (*IF1632_CallLargeStack)( int (*func)(), void *arg ) = NULL;
@@ -208,7 +207,7 @@
 {
     int exit_code = 1;
     TDB *pTask = (TDB *)GlobalLock16( hCurrentTask );
-    NE_MODULE *pModule = MODULE_GetPtr16( pTask->hModule );
+    NE_MODULE *pModule = NE_GetPtr( pTask->hModule );
     SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
 
     SET_CUR_THREAD( pTask->thdb );
@@ -276,9 +275,10 @@
 {
     HTASK16 hTask;
     TDB *pTask;
-    LPSTR name, cmd_line;
+    LPSTR cmd_line;
     WORD sp;
     char *stack32Top;
+    char name[10];
     STACK16FRAME *frame16;
     STACK32FRAME *frame32;
     PDB32 *pdb32 = thdb->process;
@@ -319,7 +319,7 @@
 
       /* Copy the module name */
 
-    name = MODULE_GetModuleName( pModule->self );
+    GetModuleName( pModule->self, name, sizeof(name) );
     strncpy( pTask->module_name, name, sizeof(pTask->module_name) );
 
       /* Allocate a selector for the PDB */
@@ -432,7 +432,7 @@
 
     /* Free the task module */
 
-    MODULE_FreeModule( pTask->hModule, pTask );
+    FreeModule16( pTask->hModule );
 
     /* Free the selector aliases */
 
@@ -660,7 +660,7 @@
 
     if (context) EAX_reg(context) = 0;
     if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return;
-    if (!(pModule = MODULE_GetPtr16( pTask->hModule ))) return;
+    if (!(pModule = NE_GetPtr( pTask->hModule ))) return;
 
     /* This is a hack to install task USER signal handler before 
      * implicitly loaded DLLs are initialized (see windows/user.c) */
@@ -855,7 +855,7 @@
     BYTE *thunk,*lfunc;
     SEGPTR thunkaddr;
 
-    if (!hInstance) return 0;
+    if (!hInstance) hInstance = CURRENT_DS;
     thunkaddr = TASK_AllocThunk( hCurrentTask );
     if (!thunkaddr) return (FARPROC16)0;
     thunk = PTR_SEG_TO_LIN( thunkaddr );
@@ -995,12 +995,8 @@
 
 /***********************************************************************
  *           SwitchStackBack   (KERNEL.109)
- *
- * Note: the function is declared as 'register' in the spec file in order
- * to make sure all registers are preserved, but we don't use them in any
- * way, so we don't need a CONTEXT* argument.
  */
-void WINAPI SwitchStackBack(void)
+void WINAPI SwitchStackBack( CONTEXT *context )
 {
     TDB *pTask;
     STACK16FRAME *oldFrame, *newFrame;
@@ -1022,6 +1018,8 @@
     /* Switch back to the old stack */
 
     pTask->thdb->cur_stack = pData->old_ss_sp;
+    SS_reg(context)  = SELECTOROF(pData->old_ss_sp);
+    ESP_reg(context) = OFFSETOF(pData->old_ss_sp);
     pData->old_ss_sp = 0;
 
     /* Build a stack frame for the return */
diff --git a/memory/local.c b/memory/local.c
index f20cda6..5e4192c 100644
--- a/memory/local.c
+++ b/memory/local.c
@@ -342,7 +342,7 @@
     if (start == 0) {
       /* Check if the segment is the DGROUP of a module */
 
-	if ((pModule = MODULE_GetPtr16( selector )))
+	if ((pModule = NE_GetPtr( selector )))
 	{
 	    SEGTABLEENTRY *pSeg = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
 	    if (pModule->dgroup && (pSeg->selector == selector)) {
@@ -1601,7 +1601,7 @@
     NE_MODULE *pModule;
     WORD ds;
 
-    if (!(pModule = MODULE_GetPtr16( module ))) return 0;
+    if (!(pModule = NE_GetPtr( module ))) return 0;
     ds = (NE_SEG_TABLE( pModule ) + pModule->dgroup - 1)->selector;
     return MAKELONG( LOCAL_CountFree( ds ), LOCAL_HeapSize( ds ) );
 }
diff --git a/memory/selector.c b/memory/selector.c
index 218ee71..8edbc2e 100644
--- a/memory/selector.c
+++ b/memory/selector.c
@@ -193,11 +193,10 @@
 
     /* Clear the saved 16-bit selector */
     frame = CURRENT_STACK16;
-    while (frame)
+    while (frame && frame->frame32)
     {
         if ((frame->ds >= sel) && (frame->ds < nextsel)) frame->ds = 0;
         if ((frame->es >= sel) && (frame->es < nextsel)) frame->es = 0;
-        if (!frame->frame32) break;
         frame = PTR_SEG_TO_LIN( frame->frame32->frame16 );
     }
 }
diff --git a/misc/comm.c b/misc/comm.c
index 333adb9..21ca5e8 100644
--- a/misc/comm.c
+++ b/misc/comm.c
@@ -823,7 +823,7 @@
         if ((act = GetCommPort(fd)) == -1) {
             WARN(comm," fd %d not comm port\n",act);
             return NULL;}
-        stol =  unknown[act];
+        stol = (unsigned char *)unknown[act];
         stol += msr;    
 	repid = ioctl(fd,TIOCMGET,&mstat);
 	TRACE(comm, " ioctl  %d, msr %x at %p %p\n",repid,mstat,stol,unknown[act]);
diff --git a/misc/commdlg.c b/misc/commdlg.c
index d8ec825..ff5e275 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -1589,7 +1589,7 @@
 /***********************************************************************
  *           ChooseColor   (COMMDLG.5)
  */
-BOOL16 WINAPI ChooseColor(LPCHOOSECOLOR lpChCol)
+BOOL16 WINAPI ChooseColor16(LPCHOOSECOLOR16 lpChCol)
 {
     HINSTANCE16 hInst;
     HANDLE16 hDlgTmpl = 0;
@@ -1662,7 +1662,7 @@
 
 struct CCPRIVATE
 {
- LPCHOOSECOLOR lpcc;  /* points to public known data structure */
+ LPCHOOSECOLOR16 lpcc;  /* points to public known data structure */
  int nextuserdef;     /* next free place in user defined color array */
  HDC16 hdcMem;        /* color graph used for BitBlt() */
  HBITMAP16 hbmMem;    /* color graph bitmap */    
@@ -2342,7 +2342,7 @@
 /***********************************************************************
  *                             CC_HookCallChk                 [internal]
  */
-static BOOL32 CC_HookCallChk(LPCHOOSECOLOR lpcc)
+static BOOL32 CC_HookCallChk(LPCHOOSECOLOR16 lpcc)
 {
  if (lpcc)
   if(lpcc->Flags & CC_ENABLEHOOK)
@@ -2364,8 +2364,8 @@
    
    TRACE(commdlg,"WM_INITDIALOG lParam=%08lX\n", lParam);
    lpp=calloc(1,sizeof(struct CCPRIVATE));
-   lpp->lpcc=(LPCHOOSECOLOR)lParam;
-   if (lpp->lpcc->lStructSize != sizeof(CHOOSECOLOR))
+   lpp->lpcc=(LPCHOOSECOLOR16)lParam;
+   if (lpp->lpcc->lStructSize != sizeof(CHOOSECOLOR16))
    {
       EndDialog32 (hDlg, 0) ;
       return FALSE;
@@ -3642,7 +3642,7 @@
 	ofn16->lStructSize = sizeof(*ofn16);
 	ofn16->hwndOwner = ofn->hwndOwner;
 	/* FIXME: OPENFILENAME16 got only 16 bit for HINSTANCE... */
-	ofn16->hInstance = MODULE_HANDLEtoHMODULE16(ofn->hInstance);
+	ofn16->hInstance = 0;
 	if (ofn->lpstrFilter) {
 		LPSTR	s,x;
 
@@ -3732,7 +3732,7 @@
 	ofn16->lStructSize = sizeof(*ofn16);
 	ofn16->hwndOwner = ofn->hwndOwner;
 	/* FIXME: OPENFILENAME16 got only 16 bit for HINSTANCE... */
-	ofn16->hInstance = MODULE_HANDLEtoHMODULE16(ofn->hInstance);
+	ofn16->hInstance = 0;
 	if (ofn->lpstrFilter) {
 		LPWSTR	s;
 		LPSTR	x,y;
@@ -3861,3 +3861,71 @@
    BOOL16 (WINAPI * dofunction)(SEGPTR ofn16) = GetSaveFileName16;
    return Commdlg_GetFileName32W(dofunction,ofn);
 }
+
+/***********************************************************************
+ *            ChooseColorA  (COMDLG32.1)
+ */
+BOOL32 WINAPI ChooseColor32A(LPCHOOSECOLOR32A lpChCol )
+
+{
+  BOOL16 ret;
+  char *str = NULL;
+  COLORREF* ccref=SEGPTR_ALLOC(64);
+  LPCHOOSECOLOR16 lpcc16=SEGPTR_ALLOC(sizeof(CHOOSECOLOR16));
+
+  memset(lpcc16,'\0',sizeof(*lpcc16));
+  lpcc16->lStructSize=sizeof(*lpcc16);
+  lpcc16->hwndOwner=lpChCol->hwndOwner;
+  lpcc16->hInstance=0; /* FIXME:MODULE_HANDLEtoHMODULE16(lpChCol->hInstance)*/
+  lpcc16->rgbResult=lpChCol->rgbResult;
+  memcpy(ccref,lpChCol->lpCustColors,64);
+  lpcc16->lpCustColors=(COLORREF*)SEGPTR_GET(ccref);
+  lpcc16->Flags=lpChCol->Flags;
+  lpcc16->lCustData=lpChCol->lCustData;
+  lpcc16->lpfnHook=(WNDPROC16)lpChCol->lpfnHook;
+  if (lpChCol->lpTemplateName)
+    str = SEGPTR_STRDUP(lpChCol->lpTemplateName );
+  lpcc16->lpTemplateName=SEGPTR_GET(str);
+  
+  ret = ChooseColor16(lpcc16);
+  if(str)
+    SEGPTR_FREE(str);
+  memcpy(lpChCol->lpCustColors,ccref,64);
+  SEGPTR_FREE(ccref);
+  SEGPTR_FREE(lpcc16);
+  return (BOOL32)ret;
+}
+
+/***********************************************************************
+ *            ChooseColorW  (COMDLG32.2)
+ */
+BOOL32 WINAPI ChooseColor32W(LPCHOOSECOLOR32W lpChCol )
+
+{
+  BOOL16 ret;
+  char *str = NULL;
+  COLORREF* ccref=SEGPTR_ALLOC(64);
+  LPCHOOSECOLOR16 lpcc16=SEGPTR_ALLOC(sizeof(CHOOSECOLOR16));
+
+  memset(lpcc16,'\0',sizeof(*lpcc16));
+  lpcc16->lStructSize=sizeof(*lpcc16);
+  lpcc16->hwndOwner=lpChCol->hwndOwner;
+  lpcc16->hInstance=0; /*FIXME:MODULE_HANDLEtoHMODULE16(lpChCol->hInstance)*/
+  lpcc16->rgbResult=lpChCol->rgbResult;
+  memcpy(ccref,lpChCol->lpCustColors,64);
+  lpcc16->lpCustColors=(COLORREF*)SEGPTR_GET(ccref);
+  lpcc16->Flags=lpChCol->Flags;
+  lpcc16->lCustData=lpChCol->lCustData;
+  lpcc16->lpfnHook=(WNDPROC16)lpChCol->lpfnHook;
+  if (lpChCol->lpTemplateName)
+    str = SEGPTR_STRDUP_WtoA(lpChCol->lpTemplateName );
+  lpcc16->lpTemplateName=SEGPTR_GET(str);
+  
+  ret = ChooseColor16(lpcc16);
+  if(str)
+    SEGPTR_FREE(str);
+  memcpy(lpChCol->lpCustColors,ccref,64);
+  SEGPTR_FREE(ccref);
+  SEGPTR_FREE(lpcc16);
+  return (BOOL32)ret;
+}
diff --git a/misc/cpu.c b/misc/cpu.c
index 0369b49..390c477 100644
--- a/misc/cpu.c
+++ b/misc/cpu.c
@@ -11,7 +11,12 @@
 #include "global.h"
 #include "windows.h"
 #include "winnt.h"
+#include "winerror.h"
 #include "winreg.h"
+#include "debug.h"
+
+/* Should this write to the registry? */
+#define DO_REG FALSE
 
 static BYTE PF[64] = {0,};
 
@@ -22,7 +27,7 @@
 {
 	static int cache = 0;
 	static SYSTEM_INFO cachedsi;
-	HKEY	xhkey=0,hkey;
+	HKEY	hkey;
 	char	buf[20];
 
 	if (cache) {
@@ -52,6 +57,16 @@
 
 	/* hmm, reasonable processor feature defaults? */
 
+        /* The registry calls were removed because they were being called 
+           before the registries were loaded, and they were giving errors */
+        /* Create this registry key for all systems */
+
+#if DO_REG
+	if (RegCreateKey16(HKEY_LOCAL_MACHINE,"HARDWARE\\DESCRIPTION\\System\\CentralProcessor",&hkey)!=ERROR_SUCCESS) {
+            WARN(reg,"Unable to register CPU information\n");
+        }
+#endif
+
 #ifdef linux
 	{
 	char line[200];
@@ -59,8 +74,7 @@
 
 	if (!f)
 		return;
-        xhkey = 0;
-	RegCreateKey16(HKEY_LOCAL_MACHINE,"\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor",&hkey);
+        /*xhkey = 0;*/
 	while (fgets(line,200,f)!=NULL) {
 		char	*s,*value;
 
@@ -94,10 +108,12 @@
 					break;
 				}
 			}
+#if DO_REG
 			/* set the CPU type of the current processor */
 			sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
-			if (xhkey)
-				RegSetValueEx32A(xhkey,"Identifier",0,REG_SZ,buf,strlen(buf));
+			if (hkey)
+				RegSetValueEx32A(hkey,"Identifier",0,REG_SZ,buf,strlen(buf));
+#endif
 			continue;
 		}
 		/* old 2.0 method */
@@ -122,10 +138,12 @@
 					break;
 				}
 			}
+#if DO_REG
 			/* set the CPU type of the current processor */
 			sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
-			if (xhkey)
-				RegSetValueEx32A(xhkey,"Identifier",0,REG_SZ,buf,strlen(buf));
+			if (hkey)
+				RegSetValueEx32A(hkey,"Identifier",0,REG_SZ,buf,strlen(buf));
+#endif
 			continue;
 		}
 		if (!lstrncmpi32A(line,"fdiv_bug",strlen("fdiv_bug"))) {
@@ -148,11 +166,14 @@
 				if (x+1>cachedsi.dwNumberOfProcessors)
 					cachedsi.dwNumberOfProcessors=x+1;
 
+#if 0
 			/* create a new processor subkey */
+                        /* What exactly is trying to be done here? */
 			sprintf(buf,"%d",x);
 			if (xhkey)
 				RegCloseKey(xhkey);
 			RegCreateKey16(hkey,buf,&xhkey);
+#endif
 		}
 		if (!lstrncmpi32A(line,"stepping",strlen("stepping"))) {
 			int	x;
@@ -174,14 +195,24 @@
 #else  /* linux */
 	/* FIXME: how do we do this on other systems? */
 
-	RegCreateKey16(hkey,"0",&xhkey);
+#if 0
 	RegSetValueEx32A(xhkey,"Identifier",0,REG_SZ,"CPU 386",strlen("CPU 386"));
+#endif
+
 #endif  /* !linux */
-	if (xhkey)
+
+#if 0
+	(xhkey)
 		RegCloseKey(xhkey);
-	RegCloseKey(hkey);
+#endif
+#if DO_REG
+    if (hkey)
+        RegCloseKey(hkey);
+#endif
+
 }
 
+
 /***********************************************************************
  * 			IsProcessorFeaturePresent	[KERNELL32.880]
  */
diff --git a/misc/crtdll.c b/misc/crtdll.c
index e9f1dd3..0acad29 100644
--- a/misc/crtdll.c
+++ b/misc/crtdll.c
@@ -20,6 +20,7 @@
 
 /* FIXME: all the file handling is hopelessly broken -- AJ */
 
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
@@ -34,6 +35,7 @@
 #include <setjmp.h>
 #include "win.h"
 #include "windows.h"
+#include "winerror.h"
 #include "debug.h"
 #include "module.h"
 #include "heap.h"
@@ -305,6 +307,20 @@
 }
   
 /*********************************************************************
+ *                  fscanf     (CRTDLL.381)
+ */
+INT32 __cdecl CRTDLL_fscanf( LPVOID stream, LPSTR format, ... )
+{
+    va_list valist;
+    INT32 res;
+
+    va_start( valist, format );
+    res = vfscanf( xlat_file_ptr(stream), format, valist );
+    va_end( valist );
+    return res;
+}
+
+/*********************************************************************
  *                  fseek     (CRTDLL.382)
  */
 LONG __cdecl CRTDLL_fseek(LPVOID stream, LONG offset, INT32 whence)
@@ -323,6 +339,15 @@
 }
   
 /*********************************************************************
+ *                  fsetpos     (CRTDLL.383)
+ */
+INT32 __cdecl CRTDLL_fsetpos(LPVOID stream, fpos_t *pos)
+{
+  TRACE(crtdll, "file %p\n", stream);
+  return fseek(xlat_file_ptr(stream), *pos, SEEK_SET);
+}
+
+/*********************************************************************
  *                  ftell     (CRTDLL.384)
  */
 LONG __cdecl CRTDLL_ftell(LPVOID stream)
@@ -514,7 +539,7 @@
 
 
 /*********************************************************************
- *                  _abnormal_termination          (CRTDLL.36 )
+ *                  _abnormal_termination          (CRTDLL.36)
  */
 INT32 __cdecl CRTDLL__abnormal_termination(void)
 {
@@ -524,6 +549,32 @@
 
 
 /*********************************************************************
+ *                  _access          (CRTDLL.37)
+ */
+INT32 __cdecl CRTDLL__access(LPCSTR filename, INT32 mode)
+{
+    DWORD attr = GetFileAttributes32A(filename);
+
+    if (attr == -1)
+    {
+        if (GetLastError() == ERROR_INVALID_ACCESS)
+            errno = EACCES;
+        else
+            errno = ENOENT;
+        return -1;
+    }
+
+    if ((attr & FILE_ATTRIBUTE_READONLY) && (mode & W_OK))
+    {
+        errno = EACCES;
+        return -1;
+    }
+    else
+        return 0;
+}
+
+
+/*********************************************************************
  *                  fflush        (CRTDLL.365)
  */
 INT32 __cdecl CRTDLL_fflush(LPVOID stream)
@@ -1366,6 +1417,14 @@
 }
 
 /*********************************************************************
+ *                  _fpreset           (CRTDLL.107)
+ */
+VOID __cdecl CRTDLL__fpreset(void)
+{
+       FIXME(crtdll," STUB.\n");
+}
+
+/*********************************************************************
  *                  atexit           (CRTDLL.345)
  */
 INT32 __cdecl CRTDLL_atexit(LPVOID x)
@@ -1475,11 +1534,14 @@
 
 /*********************************************************************
  *                  _chdrive           (CRTDLL.52)
+ *
+ *  newdir      [I] drive to change to, A=1
+ *
  */
 BOOL32 __cdecl CRTDLL__chdrive(INT32 newdrive)
 {
 	/* FIXME: generates errnos */
-	return DRIVE_SetCurrentDrive(newdrive);
+	return DRIVE_SetCurrentDrive(newdrive-1);
 }
 
 /*********************************************************************
@@ -1488,7 +1550,7 @@
 INT32 __cdecl CRTDLL__chdir(LPCSTR newdir)
 {
 	if (!SetCurrentDirectory32A(newdir))
-		return -1;
+		return 1;
 	return 0;
 }
 
@@ -1604,6 +1666,16 @@
 }
 
 /*********************************************************************
+ *                  _getdrive           (CRTDLL.124)
+ *
+ *  Return current drive, 1 for A, 2 for B
+ */
+INT32 __cdecl CRTDLL__getdrive(VOID)
+{
+    return DRIVE_GetCurrentDrive() + 1;
+}
+
+/*********************************************************************
  *                  _mkdir           (CRTDLL.234)
  */
 INT32 __cdecl CRTDLL__mkdir(LPCSTR newdir)
@@ -1701,6 +1773,25 @@
     return buf;
 }
 
+/*********************************************************************
+ *                  _ltoa           (CRTDLL.180)
+ */
+LPSTR  __cdecl CRTDLL__ltoa(long x,LPSTR buf,INT32 radix)
+{
+    switch(radix) {
+        case  2: FIXME(crtdll, "binary format not implemented !\n");
+                 break;
+        case  8: wsnprintf32A(buf,0x80,"%o",x);
+                 break;
+        case 10: wsnprintf32A(buf,0x80,"%d",x);
+                 break;
+        case 16: wsnprintf32A(buf,0x80,"%x",x);
+                 break;
+        default: FIXME(crtdll, "radix %d not implemented !\n", radix);
+    }
+    return buf;
+}
+
 typedef VOID (*sig_handler_type)(VOID);
 
 /*********************************************************************
@@ -1725,6 +1816,7 @@
   TRACE(crtdll,"CRTDLL__sleep for %ld milliseconds\n",timeout);
   Sleep((timeout)?timeout:1);
 }
+
 /*********************************************************************
  *                  getenv           (CRTDLL.437)
  */
@@ -1751,3 +1843,11 @@
      FreeEnvironmentStrings32A( environ );
      return pp;
 }
+
+/*********************************************************************
+ *                  _mbsrchr           (CRTDLL.223)
+ */
+LPSTR __cdecl CRTDLL__mbsrchr(LPSTR s,CHAR x) {
+	/* FIXME: handle multibyte strings */
+	return strrchr(s,x);
+}
diff --git a/misc/ddeml.c b/misc/ddeml.c
index 5d59940..4bbc1fe 100644
--- a/misc/ddeml.c
+++ b/misc/ddeml.c
@@ -121,14 +121,24 @@
 
 
 /*****************************************************************
- *            DdeQueryNextServer (DDEML.5)
+ * DdeQueryNextServer16 [DDEML.5]
  */
-HCONV WINAPI DdeQueryNextServer( HCONVLIST hConvList, HCONV hConvPrev )
+HCONV WINAPI DdeQueryNextServer16( HCONVLIST hConvList, HCONV hConvPrev )
 {
-    FIXME( ddeml, "empty stub\n" );
+    return DdeQueryNextServer32(hConvList, hConvPrev);
+}
+
+
+/*****************************************************************
+ * DdeQueryNextServer32 [USER32.112]
+ */
+HCONV WINAPI DdeQueryNextServer32( HCONVLIST hConvList, HCONV hConvPrev )
+{
+    FIXME(ddeml, "(%ld,%ld): stub\n",hConvList,hConvPrev);
     return 0;
 }
 
+
 /*****************************************************************
  *            DdeDisconnectList (DDEML.6)
  */
@@ -273,7 +283,7 @@
  */
 BOOL32 WINAPI DdeFreeStringHandle32( DWORD idInst, HSZ hsz )
 {
-    FIXME( ddeml, "empty stub\n" );
+    FIXME( ddeml, "(%d,%d): stub\n",idInst, hsz );
     return TRUE;
 }
 
@@ -511,5 +521,3 @@
      return 0;
 }
 
-
-
diff --git a/misc/debugstr.c b/misc/debugstr.c
index d5d8e69..7882b0f 100644
--- a/misc/debugstr.c
+++ b/misc/debugstr.c
@@ -173,7 +173,7 @@
 	  break;
 	default:
 	  if (*s<' ')
-	    printf ("\\0x%02x", *s);
+	    fprintf (stderr, "\\0x%02x", *s);
 	  else
 	    fputc (*s, stderr);
 	}
diff --git a/misc/imagelist.c b/misc/imagelist.c
index 17f6d2c..95c27d9 100644
--- a/misc/imagelist.c
+++ b/misc/imagelist.c
@@ -4,7 +4,6 @@
  *  Copyright 1998 Eric Kohl
  *
  *  TODO:
- *    - Improve the documentation.
  *    - Improve error checking in some functions.
  *    - Fix ILD_TRANSPARENT error in ImageList_DrawIndirect.
  *    - Fix offsets in ImageList_DrawIndirect.
@@ -38,7 +37,7 @@
 #define __WINE_IMAGELIST_C
  
 /* This must be defined until "GetIconInfo" is implemented completely.
- * To do that the Cursor and Icon code in objects/cursoricon.c must
+ * To do that the cursor and icon code in objects/cursoricon.c must
  * be rewritten.
  */
 #define __GET_ICON_INFO_HACK__ 
@@ -59,31 +58,37 @@
 #define MAX_OVERLAYIMAGE 15
 
 
-/*
- * internal ImageList data used for dragging
- */
+/* internal image list data used for Drag & Drop operations */
+
 static HIMAGELIST himlInternalDrag = NULL;
 static INT32      nInternalDragHotspotX = 0;
 static INT32      nInternalDragHotspotY = 0;
-static HCURSOR32  hcurInternal = 0;
 
 
 /*************************************************************************
- *	 		 IMAGELIST_InternalGrowBitmaps   [Internal]
+ * IMAGELIST_InternalExpandBitmaps [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.
+ * Expands the bitmaps of an image list by the given number of images.
+ *
+ * PARAMS
+ *     himl        [I] image list handle
+ *     nImageCount [I] Number of images to add.
+ *
+ * RETURNS
+ *     nothing
+ *
+ * NOTES
+ *     This function 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 */
+static VOID
+IMAGELIST_InternalExpandBitmaps (HIMAGELIST himl, INT32 nImageCount)
 {
     HDC32     hdcImageList, hdcBitmap;
     HBITMAP32 hbmNewBitmap;
     INT32     nNewWidth, nNewCount;
 
-    TRACE(imagelist, "Create grown bitmaps!\n");
+    TRACE(imagelist, "Create expanded bitmaps!\n");
 
     nNewCount = himl->cCurImage + nImageCount + himl->cGrow;
     nNewWidth = nNewCount * himl->cx;
@@ -94,7 +99,7 @@
     hbmNewBitmap =
         CreateBitmap32 (nNewWidth, himl->cy, 1, himl->uBitsPixel, NULL);
     if (hbmNewBitmap == 0)
-        ERR (imagelist, "Error creating new image bitmap!\n");
+        ERR (imagelist, "creating new image bitmap!\n");
 
     SelectObject32 (hdcImageList, himl->hbmImage);
     SelectObject32 (hdcBitmap, hbmNewBitmap);
@@ -109,7 +114,7 @@
             CreateBitmap32 (nNewWidth, himl->cy, 1, 1, NULL);
 
         if (hbmNewBitmap == 0)
-            ERR (imagelist, "Error creating new mask bitmap!");
+            ERR (imagelist, "creating new mask bitmap!");
 
         SelectObject32 (hdcImageList, himl->hbmMask);
         SelectObject32 (hdcBitmap, hbmNewBitmap);
@@ -127,97 +132,92 @@
 
 
 /*************************************************************************
- *	 		 ImageList_Add   [COMCTL32.39]
+ * ImageList_Add [COMCTL32.39]
  *
- *  Add an image (and a mask) to an image list.
+ * Add an image or images to an image list.
  *
- *  RETURNS
- *    Index of the first image that was added.
- *    -1 if an error occurred.
+ * PARAMS
+ *     himl     [I] image list handle
+ *     hbmImage [I] image bitmap handle
+ *     hbmMask  [I] mask bitmap handle
+ *
+ * RETURNS
+ *     Success: Index of the first new image.
+ *     Failure: -1
  */
 
-INT32 WINAPI ImageList_Add (
-	HIMAGELIST himl,     /* imagelist handle */
-	HBITMAP32 hbmImage,  /* image bitmap */
-	HBITMAP32 hbmMask)   /* mask bitmap */
+INT32 WINAPI
+ImageList_Add (HIMAGELIST himl,	HBITMAP32 hbmImage, HBITMAP32 hbmMask)
 {
-    HDC32    hdcImageList, hdcImage, hdcMask;
+    HDC32    hdcSrc, hdcDst;
     INT32    nFirstIndex, nImageCount;
     INT32    nStartX, nRunX, nRunY;
     BITMAP32 bmp;
 
     if (himl == NULL) return (-1);
-
-    hdcMask = 0; /* to keep compiler happy ;-) */
+    if (hbmImage == 0) return (-1);
 
     GetObject32A (hbmImage, sizeof(BITMAP32), (LPVOID)&bmp);
     nImageCount = bmp.bmWidth / himl->cx;
 
     if (himl->cCurImage + nImageCount >= himl->cMaxImage)
-        IMAGELIST_InternalGrowBitmaps (himl, nImageCount);
+        IMAGELIST_InternalExpandBitmaps (himl, nImageCount);
 
-    hdcImageList = CreateCompatibleDC32 (0);
-    hdcImage = CreateCompatibleDC32 (0);
+    hdcSrc = CreateCompatibleDC32 (0);
+    hdcDst = CreateCompatibleDC32 (0);
 
-    SelectObject32 (hdcImageList, himl->hbmImage);
-    SelectObject32 (hdcImage, hbmImage);
+    SelectObject32 (hdcDst, himl->hbmImage);
+    SelectObject32 (hdcSrc, hbmImage);
 
-    BitBlt32 (hdcImageList, himl->cCurImage * himl->cx, 0,
-              bmp.bmWidth, himl->cy, hdcImage, 0, 0, SRCCOPY);
+    BitBlt32 (hdcDst, himl->cCurImage * himl->cx, 0,
+              bmp.bmWidth, himl->cy, hdcSrc, 0, 0, SRCCOPY);
           
-    if (himl->hbmMask)
-    {
-        if (hbmMask)
-        {
-            SelectObject32 (hdcImageList, himl->hbmMask);
-            SelectObject32 (hdcImage, hbmMask);
-            BitBlt32 (hdcImageList, himl->cCurImage * himl->cx, 0,
-                      bmp.bmWidth, himl->cy, hdcImage, 0, 0, SRCCOPY);
+    if (himl->hbmMask) {
+        if (hbmMask) {
+            SelectObject32 (hdcDst, himl->hbmMask);
+            SelectObject32 (hdcSrc, hbmMask);
+            BitBlt32 (hdcDst, himl->cCurImage * himl->cx, 0,
+                      bmp.bmWidth, himl->cy, hdcSrc, 0, 0, SRCCOPY);
 
             /* fix transparent areas of the image bitmap*/
-            SelectObject32 (hdcMask, himl->hbmMask);
-            SelectObject32 (hdcImage, himl->hbmImage);
+            SelectObject32 (hdcSrc, himl->hbmMask);
+            SelectObject32 (hdcDst, 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, 
+
+            for (nRunY = 0; nRunY < himl->cy; nRunY++) {
+                for (nRunX = 0; nRunX < bmp.bmWidth; nRunX++) {
+                    if (GetPixel32 (hdcSrc, nStartX + nRunX, nRunY) !=
+                        RGB(0, 0, 0))
+                        SetPixel32 (hdcDst, nStartX + nRunX, nRunY, 
                                     RGB(0, 0, 0));
                 }
             }
         }
-        else
-        {
+        else {
             /* create mask from the imagelist's background color */
-            hdcMask = CreateCompatibleDC32 (0);
-            SelectObject32 (hdcMask, himl->hbmMask);
+            SelectObject32 (hdcDst, himl->hbmMask);
+            SelectObject32 (hdcSrc, himl->hbmImage);
             nStartX = himl->cCurImage * himl->cx;
-            for (nRunY = 0; nRunY < himl->cy; nRunY++)
-            {
-                for (nRunX = 0; nRunX < bmp.bmWidth; nRunX++)
-                {
-                    if (GetPixel32 (hdcImageList, nStartX + nRunX, nRunY) ==
+            for (nRunY = 0; nRunY < himl->cy; nRunY++) {
+                for (nRunX = 0; nRunX < bmp.bmWidth; nRunX++) {
+                    if (GetPixel32 (hdcSrc, nStartX + nRunX, nRunY) ==
                         himl->clrBk)
                     {
-                        SetPixel32 (hdcImageList, nStartX + nRunX, nRunY, 
+                        SetPixel32 (hdcSrc, nStartX + nRunX, nRunY, 
                                     RGB(0, 0, 0));
-                        SetPixel32 (hdcMask, nStartX + nRunX, nRunY, 
+                        SetPixel32 (hdcDst, nStartX + nRunX, nRunY, 
                                     RGB(255, 255, 255));
                     }
                     else
-                        SetPixel32 (hdcMask, nStartX + nRunX, nRunY, 
+                        SetPixel32 (hdcDst, nStartX + nRunX, nRunY, 
                                     RGB(0, 0, 0));        
                 }
             }
-            DeleteDC32 (hdcMask);
         }
     }
 
-    DeleteDC32 (hdcImageList);
-    DeleteDC32 (hdcImage);
+    DeleteDC32 (hdcSrc);
+    DeleteDC32 (hdcDst);
 
     nFirstIndex = himl->cCurImage;
     himl->cCurImage += nImageCount;
@@ -227,33 +227,37 @@
 
 
 /*************************************************************************
- *	 		 ImageList_AddMasked   [COMCTL32.41]
+ * ImageList_AddMasked [COMCTL32.41] 
  *
- *  Adds an image to an imagelist and creates a mask from the given
- *  mask color.
+ * Adds an image or images to an image list and creates a mask from the
+ * specified bitmap using the mask color.
  *
- *  RETURNS
- *    Index of the first image that was added.
- *    -1 if an error occurred.
+ * PARAMS
+ *     himl     [I] image list handle.
+ *     hbmImage [I] image bitmap handle.
+ *     clrMask  [I] mask color.
+ *
+ * RETURNS
+ *     Success: Index of the first new image.
+ *     Failure: -1
  */
 
-INT32 WINAPI ImageList_AddMasked (
-	HIMAGELIST himl,    /* image list handle */
-	HBITMAP32 hbmImage, /* bitmap handle */
-	COLORREF clrMask)   /* backround color of the image */
+INT32 WINAPI
+ImageList_AddMasked (HIMAGELIST himl, HBITMAP32 hbmImage, COLORREF clrMask)
 {
     HDC32    hdcImageList, hdcImage, hdcMask;
     INT32    nIndex, nImageCount;
     BITMAP32 bmp;
     INT32    nStartX, nRunX, nRunY;
 
-    if (himl == NULL) return (-1);
+    if (himl == NULL)
+	return (-1);
 
     GetObject32A (hbmImage, sizeof(BITMAP32), &bmp);
     nImageCount = bmp.bmWidth / himl->cx;
 
     if (himl->cCurImage + nImageCount >= himl->cMaxImage)
-        IMAGELIST_InternalGrowBitmaps (himl, nImageCount);
+        IMAGELIST_InternalExpandBitmaps (himl, nImageCount);
 
     nIndex = himl->cCurImage;
     himl->cCurImage += nImageCount;
@@ -266,16 +270,13 @@
     BitBlt32 (hdcImageList, nIndex * himl->cx, 0, bmp.bmWidth, himl->cy,
               hdcImage, 0, 0, SRCCOPY);
 
-    if (himl->hbmMask)
-    {
+    if (himl->hbmMask) {
         /* create Mask */
         hdcMask = CreateCompatibleDC32 (0);
         SelectObject32 (hdcMask, himl->hbmMask);
         nStartX = nIndex * himl->cx;
-        for (nRunY = 0; nRunY < himl->cy; nRunY++)
-        {
-            for (nRunX = 0; nRunX < bmp.bmWidth; nRunX++)
-            {
+        for (nRunY = 0; nRunY < himl->cy; nRunY++) {
+            for (nRunX = 0; nRunX < bmp.bmWidth; nRunX++) {
                 if (GetPixel32 (hdcImageList, nStartX + nRunX, nRunY) ==
                     clrMask)
                 {
@@ -299,33 +300,40 @@
 
 
 /*************************************************************************
- *	 		 ImageList_BeginDrag   [COMCTL32.42]
+ * ImageList_BeginDrag [COMCTL32.42] 
  *
- *  Creates a temporary imagelist with an image in it, which will be used
- *  as a drag image.
+ * Creates a temporary image list that contains one image. It will be used
+ * as a drag image.
  *
- *  RETURNS
- *    ...
+ * PARAMS
+ *     himlTrack [I] Handle of the source image list
+ *     iTrack    [I] Index of the drag image in the source image list
+ *     dxHotspot [I] X position of the hot spot of the drag image
+ *     dyHotspot [I] Y position of the hot spot of the drag image
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
  */
 
-BOOL32 WINAPI ImageList_BeginDrag (
-	HIMAGELIST himlTrack, /* Handle of the source imagelist */
-	INT32 iTrack,         /* Index of the image in the source imagelist */
-	INT32 dxHotspot,      /* Position of the hot spot of the */
-	INT32 dyHotspot)      /* drag image */
+BOOL32 WINAPI
+ImageList_BeginDrag (HIMAGELIST himlTrack, INT32 iTrack,
+	             INT32 dxHotspot, INT32 dyHotspot)
 {
     HDC32 hdcSrc, hdcDst;
 
-    FIXME(imagelist, "ImageList_BeginDrag: partially implemented!\n");
+    FIXME(imagelist, "partially implemented!\n");
 
-    if (himlTrack == NULL) return (FALSE);
+    if (himlTrack == NULL)
+	return (FALSE);
+
     if (himlInternalDrag)
         ImageList_EndDrag ();
 
-    himlInternalDrag = ImageList_Create (himlTrack->cx, himlTrack->cy,
-                                         himlTrack->flags, 1, 1);
-    if (himlInternalDrag == NULL)
-    {
+    himlInternalDrag =
+	ImageList_Create (himlTrack->cx, himlTrack->cy,
+			  himlTrack->flags, 1, 1);
+    if (himlInternalDrag == NULL) {
         ERR(imagelist, "Error creating drag image list!\n");
         return (FALSE);
     }
@@ -358,24 +366,31 @@
 
 
 /*************************************************************************
- *	 		 ImageList_Copy   [COMCTL32.43]
+ * ImageList_Copy [COMCTL32.43] 
  *
- *  Copies an image of the source imagelist to an image of the 
- *  destination imagelist. Images can be copied or swapped.
- *  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).
+ *  Copies an image of the source image list to an image of the 
+ *  destination image list. Images can be copied or swapped.
  *
- *  RETURNS
- *    ...
+ * PARAMS
+ *     himlDst [I] destination image list handle.
+ *     iDst    [I] destination image index.
+ *     himlSrc [I] source image list handle
+ *     iSrc    [I] source image index
+ *     uFlags  [I] flags for the copy operation
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ *
+ * NOTES
+ *     Copying from one image list to another is possible. The original
+ *     implementation just copies or swapps within one image list.
+ *     Could this feature become a bug??? ;-)
  */
 
-BOOL32 WINAPI ImageList_Copy (
-	HIMAGELIST himlDst,  /* Handle of the destination imagelist */
-	INT32 iDst,          /* Index of the destination image */
-	HIMAGELIST himlSrc,  /* Handel od the source imagelist */
-	INT32 iSrc,          /* Index of the source image */
-	INT32 uFlags)        /* Flags used for the copy operation */
+BOOL32 WINAPI
+ImageList_Copy (HIMAGELIST himlDst, INT32 iDst,	HIMAGELIST himlSrc,
+		INT32 iSrc, INT32 uFlags)
 {
     HDC32 hdcSrc, hdcDst;    
 
@@ -391,8 +406,7 @@
     else
         hdcDst = CreateCompatibleDC32 (0);
 
-    if (uFlags & ILCF_SWAP)
-    {
+    if (uFlags & ILCF_SWAP) {
         /* swap */
         HBITMAP32 hbmTempImage, hbmTempMask;
 
@@ -445,8 +459,7 @@
         DeleteObject32 (hbmTempMask);
         DeleteObject32 (hbmTempImage);
     }
-    else
-    {
+    else {
         /* copy image */
         SelectObject32 (hdcSrc, himlSrc->hbmImage);
         if (himlSrc == himlDst)
@@ -477,22 +490,25 @@
 
 
 /*************************************************************************
- *	 		 ImageList_Create   [COMCTL32.44]
+ * ImageList_Create [COMCTL32.44] 
  *
- *  Creates an imagelist of the given image size and number of images.
+ * Creates a new image list.
  *
- *  RETURNS
- *    Handle of the created image list.
- *    0 if an error occurred.
+ * PARAMS
+ *     cx       [I] image height
+ *     cy       [I] image width
+ *     flags    [I] creation flags
+ *     cInitial [I] initial number of images in the image list
+ *     cGrow    [I] number of images by which image list grows
+ *
+ * RETURNS
+ *     Success: Handle of the created image list
+ *     Failure: 0
  */
 
-HIMAGELIST WINAPI ImageList_Create (
-	INT32 cx,        /* Width of an image */
-	INT32 cy,        /* Height of an image */
-	UINT32 flags,    /* Flags for imagelist creation */
-	INT32 cInitial,  /* Initial number of images in the imaglist */
-	INT32 cGrow)     /* Number of images that is added to the */
-	                 /* imagelist when it grows */
+HIMAGELIST WINAPI
+ImageList_Create (INT32 cx, INT32 cy, UINT32 flags,
+		  INT32 cInitial, INT32 cGrow)
 {
     HIMAGELIST himl;
     HDC32      hdc;
@@ -531,18 +547,15 @@
     himl->hbmImage =
         CreateBitmap32 (himl->cx * himl->cMaxImage, himl->cy,
                         1, himl->uBitsPixel, NULL);
-    if (himl->hbmImage == 0)
-    {
+    if (himl->hbmImage == 0) {
         ERR(imagelist, "Error creating image bitmap!\n");
         return (0);
     }
 
-    if (himl->flags & ILC_MASK)
-    {
+    if (himl->flags & ILC_MASK) {
         himl->hbmMask = 
             CreateBitmap32 (himl->cx * himl->cMaxImage, himl->cy, 1, 1, NULL);
-        if (himl->hbmMask == 0)
-        {
+        if (himl->hbmMask == 0) {
             ERR(imagelist, "Error creating mask bitmap!\n");
             if (himl->hbmImage)
                 DeleteObject32 (himl->hbmImage);
@@ -566,17 +579,20 @@
 
 
 /*************************************************************************
- *	 		 ImageList_Destroy   [COMCTL32.45]
+ * ImageList_Destroy [COMCTL32.45] 
  *
- *  Destroy the given imagelist.
+ * Destroys an image list.
  *
- *  RETURNS
- *    TRUE if the image list was destroyed.
- *    FALSE if an error occurred.
+ * PARAMS
+ *     himl [I] image list handle
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
  */
 
-BOOL32 WINAPI ImageList_Destroy (
-	HIMAGELIST himl)  /* Handle of the imagelist */
+BOOL32 WINAPI
+ImageList_Destroy (HIMAGELIST himl)
 { 
     if (himl == NULL) return (FALSE);
 
@@ -591,68 +607,105 @@
 
 
 /*************************************************************************
- *	 		 ImageList_DragEnter   [COMCTL32.46]
+ * ImageList_DragEnter [COMCTL32.46] 
  *
- *  FIXME
- *    This is still an empty stub.
+ * Locks window update and displays the drag image at the given position.
+ *
+ * PARAMS
+ *     hwndLock [I] handle of the window that owns the drag image.
+ *     x        [I] X position of the drag image.
+ *     y        [I] Y position of the drag image.
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ *
+ * FIXME
+ *     This is still an empty stub.
+ *
+ * NOTES
+ *     The position of the drag image is relative to the window, not
+ *     the client area.
  */
 
-BOOL32 WINAPI ImageList_DragEnter (
-	HWND32 hwndLock, 
-	INT32 x, 
-	INT32 y)
+BOOL32 WINAPI
+ImageList_DragEnter (HWND32 hwndLock, INT32 x, INT32 y)
 {
     FIXME (imagelist, "empty stub!\n");
 
-    hcurInternal = GetCursor32 ();
-
-
-    ShowCursor32 (TRUE);
-
     return (FALSE);
 }
 
 
 /*************************************************************************
- *	 		 ImageList_DragLeave   [COMCTL32.47]
+ * ImageList_DragLeave [COMCTL32.47] 
+ *
+ * Unlocks window update and hides the drag image.
+ *
+ * PARAMS
+ *     hwndLock [I] handle of the window that owns the drag image.
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ *
+ * FIXME
+ *     This is still an empty stub.
  */
 
-BOOL32 WINAPI ImageList_DragLeave (
-	HWND32 hwndLock)
+BOOL32 WINAPI
+ImageList_DragLeave (HWND32 hwndLock)
 {
     FIXME (imagelist, "empty stub!\n");
 
-
-    SetCursor32 (hcurInternal);
-    hcurInternal = 0;
- 
-    ShowCursor32 (FALSE);
-
     return (FALSE);
 }
 
 
 /*************************************************************************
- *	 		 ImageList_DragMove   [COMCTL32.48]
+ * ImageList_DragMove [COMCTL32.48] 
+ *
+ * Moves the drag image.
+ *
+ * PARAMS
+ *     x [I] X position of the drag image.
+ *     y [I] Y position of the drag image.
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ *
+ * NOTES
+ *     The position of the drag image is relative to the window, not
+ *     the client area.
+ *
+ * FIXME
+ *     This is still an empty stub.
  */
 
-BOOL32 WINAPI ImageList_DragMove (
-	INT32 x,
-	INT32 y)
+BOOL32 WINAPI
+ImageList_DragMove (INT32 x, INT32 y)
 {
     FIXME (imagelist, "empty stub!\n");
 
-//    if (hcurInternal)
-//        SetCursor32 (hcurInternal);
-//    ImageList_Draw (himlInternalDrag, 0, x, y, 0);
-
-
     return (FALSE);
 }
 
 
 /*************************************************************************
- *	 		 ImageList_DragShowNolock   [COMCTL32.49]
+ * ImageList_DragShowNolock [COMCTL32.49] 
+ *
+ * Shows or hides the drag image.
+ *
+ * PARAMS
+ *     bShow [I] TRUE shows the drag image, FALSE hides it.
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ *
+ * FIXME
+ *     This is still an empty stub.
  */
 
 BOOL32 WINAPI
@@ -665,16 +718,30 @@
 
 
 /*************************************************************************
- *	 		 ImageList_Draw   [COMCTL32.50]
+ * ImageList_Draw [COMCTL32.50] Draws an image.
+ *
+ * PARAMS
+ *     himl   [I] image list handle
+ *     i      [I] image index
+ *     hdc    [I] display context handle
+ *     x      [I] x position
+ *     y      [I] y position
+ *     fStyle [I] drawing flags
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ *
+ * NOTES
+ *     Calls ImageList_DrawIndirect.
+ *
+ * SEE
+ *     ImageList_DrawIndirect.
  */
 
-BOOL32 WINAPI ImageList_Draw (
-	HIMAGELIST himl,
-	INT32 i,
-	HDC32 hdc, 
-	INT32 x,
-	INT32 y,
-	UINT32 fStyle)
+BOOL32 WINAPI
+ImageList_Draw (HIMAGELIST himl, INT32 i, HDC32 hdc,
+		INT32 x, INT32 y, UINT32 fStyle)
 {
     IMAGELISTDRAWPARAMS imldp;
 
@@ -698,20 +765,37 @@
 
 
 /*************************************************************************
- *	 		 ImageList_DrawEx   [COMCTL32.51]
+ * ImageList_DrawEx [COMCTL32.51]
+ *
+ * Draws an image and allows to use extended drawing features.
+ *
+ * PARAMS
+ *     himl   [I] image list handle
+ *     i      [I] image index
+ *     hdc    [I] device context handle
+ *     x      [I] X position
+ *     y      [I] Y position
+ *     xOffs  [I] 
+ *     yOffs  [I]
+ *     rgbBk  [I] background color
+ *     rgbFg  [I] foreground color
+ *     fStyle [I] drawing flags
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ *
+ * NOTES
+ *     Calls ImageList_DrawIndirect.
+ *
+ * SEE
+ *     ImageList_DrawIndirect.
  */
 
-BOOL32 WINAPI ImageList_DrawEx (
-	HIMAGELIST himl,
-	INT32 i,
-	HDC32 hdc,
-	INT32 x,
-	INT32 y,
-	INT32 xOffs,
-	INT32 yOffs,
-	COLORREF rgbBk,
-	COLORREF rgbFg,
-	UINT32 fStyle)
+BOOL32 WINAPI
+ImageList_DrawEx (HIMAGELIST himl, INT32 i, HDC32 hdc, INT32 x, INT32 y,
+		  INT32 xOffs, INT32 yOffs, COLORREF rgbBk, COLORREF rgbFg,
+		  UINT32 fStyle)
 {
     IMAGELISTDRAWPARAMS imldp;
 
@@ -735,11 +819,20 @@
 
 
 /*************************************************************************
- *	 		 ImageList_DrawIndirect   [COMCTL32.52]
+ * ImageList_DrawIndirect [COMCTL32.52] 
+ *
+ * Draws an image using ...
+ *
+ * PARAMS
+ *     pimldp [I] pointer to ...
+ *
+ * RETURNS
+ *     Success:
+ *     Failure:
  */
 
-BOOL32 WINAPI ImageList_DrawIndirect (
-	IMAGELISTDRAWPARAMS *pimldp)
+BOOL32 WINAPI
+ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
 {
     HIMAGELIST himlLocal;
     HDC32      hdcImageList, hdcTempImage;
@@ -756,6 +849,7 @@
 
     if (pimldp == NULL) return (FALSE);
     if (pimldp->cbSize < sizeof(IMAGELISTDRAWPARAMS)) return (FALSE);
+    if (pimldp->himl == NULL) return (FALSE);
 
     himlLocal = pimldp->himl;
     
@@ -912,16 +1006,18 @@
 
 
 /*************************************************************************
- *	 		 ImageList_Duplicate   [COMCTL32.53]
+ * ImageList_Duplicate [COMCTL32.53] Duplicates an image list.
  *
- *  Duplicates an image list.
+ * PARAMS
+ *     himlSrc [I] source image list handle
  *
- *  RETURNS
- *    Handle of duplicate image list, 0 if an error occurred.
+ * RETURNS
+ *     Success: Handle of duplicated image list.
+ *     Failure: 0
  */
 
-HIMAGELIST WINAPI ImageList_Duplicate (
-	HIMAGELIST himlSrc)
+HIMAGELIST WINAPI
+ImageList_Duplicate (HIMAGELIST himlSrc)
 {
     HIMAGELIST himlDst;
     HDC32 hdcSrc, hdcDst;
@@ -960,15 +1056,23 @@
 
 
 /*************************************************************************
- *	 		 ImageList_EndDrag   [COMCTL32.54]
+ * ImageList_EndDrag [COMCTL32.54] Finishes a drag operation.
  *
- *  Finishes a drag operation.
+ * Finishes a drag operation.
  *
- *  FIXME
- *    semi-stub.
+ * PARAMS
+ *     no
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ *
+ * BUGS
+ *     semi-stub.
  */
 
-BOOL32 WINAPI ImageList_EndDrag (VOID)
+BOOL32 WINAPI
+ImageList_EndDrag (VOID)
 {
     FIXME (imagelist, "partially implemented!\n");
 
@@ -988,33 +1092,46 @@
 
 
 /*************************************************************************
- *	 		 ImageList_GetBkColor   [COMCTL32.55]
+ * ImageList_GetBkColor [COMCTL32.55]
  *
- *  Returns the background color of an image list.
+ * Returns the background color of an image list.
  *
- *  RETURNS
- *    Background color.
+ * PARAMS
+ *     himl [I] Image list handle.
+ *
+ * RETURNS
+ *     Background color.
  */
 
-COLORREF WINAPI ImageList_GetBkColor (
-	HIMAGELIST himl)
+COLORREF WINAPI
+ImageList_GetBkColor (HIMAGELIST himl)
 {
+//    if (himl == NULL)
+//	return CLR_NONE;
+
     return (himl->clrBk);
 }
 
 
 /*************************************************************************
- *	 		 ImageList_GetDragImage   [COMCTL32.56]
+ * ImageList_GetDragImage [COMCTL32.56]
  *
- *  Returns the handle to the internal drag image list.
+ * Returns the handle to the internal drag image list.
  *
- *  FIXME
- *    semi-stub.
+ * PARAMS
+ *     ppt        [O] Pointer to the drag position. Can be NULL.
+ *     pptHotspot [O] Pointer to the position of the hot spot. Can be NULL.
+ *
+ * RETURNS
+ *     Success: Handle of the drag image list.
+ *     Failure: NULL.
+ *
+ * BUGS
+ *     semi-stub.
  */
 
-HIMAGELIST WINAPI ImageList_GetDragImage (
-	POINT32 *ppt,
-	POINT32 *pptHotspot)
+HIMAGELIST WINAPI
+ImageList_GetDragImage (POINT32 *ppt, POINT32 *pptHotspot)
 {
     FIXME (imagelist, "partially imlemented!\n");
 
@@ -1026,13 +1143,22 @@
 
 
 /*************************************************************************
- *	 		 ImageList_GetIcon   [COMCTL32.57]
+ * ImageList_GetIcon [COMCTL32.57] 
+ *
+ * Creates an icon from a masked image of an image list.
+ *
+ * PARAMS
+ *     himl  [I] image list handle
+ *     i     [I] image index
+ *     flags [I] drawing style flags
+ *
+ * RETURNS
+ *     Success: icon handle
+ *     Failure: NULL
  */
 
-HICON32 WINAPI ImageList_GetIcon (
-	HIMAGELIST himl, 
-	INT32 i, 
-	UINT32 fStyle)
+HICON32 WINAPI
+ImageList_GetIcon (HIMAGELIST himl, INT32 i, UINT32 fStyle)
 {
     ICONINFO ii;
     HICON32  hIcon;
@@ -1071,13 +1197,25 @@
 
 
 /*************************************************************************
- *	 		 ImageList_GetIconSize   [COMCTL32.58]
+ * ImageList_GetIconSize [COMCTL32.58]
+ *
+ * Retrieves the size of an image in an image list.
+ *
+ * PARAMS
+ *     himl [I] image list handle
+ *     cx   [O] pointer to the image width.
+ *     cy   [O] pointer to the image height.
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ *
+ * NOTES
+ *     All images in an image list have the same size.
  */
 
-BOOL32 WINAPI ImageList_GetIconSize (
-	HIMAGELIST himl,
-	INT32 *cx,
-	INT32 *cy)
+BOOL32 WINAPI
+ImageList_GetIconSize (HIMAGELIST himl, INT32 *cx, INT32 *cy)
 {
 
     if (himl == NULL) return (FALSE);
@@ -1092,24 +1230,45 @@
 
 
 /*************************************************************************
- *	 		 ImageList_GetIconCount   [COMCTL32.59]
+ * ImageList_GetIconCount [COMCTL32.59]
+ *
+ * Returns the number of images in an image list.
+ *
+ * PARAMS
+ *     himl [I] image list handle.
+ *
+ * RETURNS
+ *     Success: Number of images.
+ *     Failure: ???? (Number of what...)
  */
 
-INT32 WINAPI ImageList_GetImageCount (
-	HIMAGELIST himl)
+INT32 WINAPI
+ImageList_GetImageCount (HIMAGELIST himl)
 {
+//    if (himl == NULL)
+//	return -1;
+
     return (himl->cCurImage);
 }
 
 
 /*************************************************************************
- *	 		 ImageList_GetImageInfo   [COMCTL32.60]
+ * ImageList_GetImageInfo [COMCTL32.60]
+ *
+ * Returns information about an image in an image list.
+ *
+ * PARAMS
+ *     himl       [I] image list handle.
+ *     i          [I] image index
+ *     pImageInfo [O] pointer to the image information.
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
  */
 
-BOOL32 WINAPI ImageList_GetImageInfo (
-	HIMAGELIST himl,
-	INT32 i,
-	IMAGEINFO *pImageInfo)
+BOOL32 WINAPI
+ImageList_GetImageInfo (HIMAGELIST himl, INT32 i, IMAGEINFO *pImageInfo)
 {
     if ((himl == NULL) || (pImageInfo == NULL)) return (FALSE);
 
@@ -1126,16 +1285,28 @@
 
 
 /*************************************************************************
- *	 		 ImageList_GetImageRect   [COMCTL32.61]
+ * ImageList_GetImageRect [COMCTL32.61] 
  *
- *  COMMENTS
+ * Retrieves the rectangle of the specified image in an image list.
+ *
+ * PARAMS
+ *     himl   [I] image list handle
+ *     i      [I] image index
+ *     lpRect [O] pointer to the image rectangle
+ *
+ * RETURNS
+ *    Success: TRUE ????
+ *    Failure: FALSE ????
+ *
+ * NOTES
+ *    This is an UNDOCUMENTED function!!!
+ *
+ * BUGS
  *    I don't know if it really returns a BOOL32 or something else!!!??
  */
 
-BOOL32 WINAPI ImageList_GetImageRect (
-	HIMAGELIST himl,
-	INT32 i,
-	LPRECT32 lpRect)
+BOOL32 WINAPI
+ImageList_GetImageRect (HIMAGELIST himl, INT32 i, LPRECT32 lpRect)
 {
     if (himl == NULL) return (FALSE);
     if ((i < 0) || (i >= himl->cCurImage)) return (FALSE);
@@ -1151,17 +1322,28 @@
 
 
 /*************************************************************************
- *	 		 ImageList_LoadImage32A   [COMCTL32.63]
+ * ImageList_LoadImage32A   [COMCTL32.63]
+ *
+ * Creates an image list from a bitmap, icon or cursor.
+ *
+ * PARAMS
+ *     hi      [I]
+ *     lpbmp   [I]
+ *     cx      [I]
+ *     cy      [I]
+ *     cGrow   [I]
+ *     clrMask [I]
+ *     uType   [I]
+ *     uFlags  [I]
+ *
+ * RETURNS
+ *     Success:
+ *     Failure:
  */
 
-HIMAGELIST WINAPI ImageList_LoadImage32A (
-	HINSTANCE32 hi,
-	LPCSTR lpbmp,
-	INT32 cx,
-	INT32 cGrow, 
-	COLORREF clrMask,
-	UINT32 uType,
-	UINT32 uFlags)
+HIMAGELIST WINAPI
+ImageList_LoadImage32A (HINSTANCE32 hi, LPCSTR lpbmp, INT32 cx,	INT32 cGrow,
+			COLORREF clrMask, UINT32 uType,	UINT32 uFlags)
 {
     HIMAGELIST himl = NULL;
     HANDLE32   handle;
@@ -1217,17 +1399,28 @@
 
 
 /*************************************************************************
- *	 		 ImageList_LoadImage32W   [COMCTL32.64]
+ * ImageList_LoadImage32W [COMCTL32.64]
+ *
+ * Creates an image list from a bitmap, icon or cursor.
+ *
+ * PARAMS
+ *     hi      [I]
+ *     lpbmp   [I]
+ *     cx      [I]
+ *     cy      [I]
+ *     cGrow   [I]
+ *     clrMask [I]
+ *     uType   [I]
+ *     uFlags  [I]
+ *
+ * RETURNS
+ *     Success:
+ *     Failure:
  */
 
-HIMAGELIST WINAPI ImageList_LoadImage32W (
-	HINSTANCE32 hi,
-	LPCWSTR lpbmp,
-	INT32 cx,
-	INT32 cGrow,
-	COLORREF clrMask,
-	UINT32 uType,
-	UINT32 uFlags)
+HIMAGELIST WINAPI
+ImageList_LoadImage32W (HINSTANCE32 hi, LPCWSTR lpbmp, INT32 cx, INT32 cGrow,
+			COLORREF clrMask, UINT32 uType,	UINT32 uFlags)
 {
     HIMAGELIST himl = NULL;
     HANDLE32   handle;
@@ -1286,16 +1479,27 @@
 
 
 /*************************************************************************
- *	 		 ImageList_Merge   [COMCTL32.65]
+ * ImageList_Merge [COMCTL32.65] 
+ *
+ * Creates a new image list that contains a merged image from the specified
+ * images of both source image lists.
+ *
+ * PARAMS
+ *     himl1 [I] first image list handle
+ *     i1    [I] first image index
+ *     himl2 [I] second image list handle
+ *     i2    [I] second image index
+ *     dx    [I] X offset of the second image relative to the first.
+ *     dy    [I] Y offset of the second image relative to the first.
+ *
+ * RETURNS
+ *     Success:
+ *     Failure:
  */
 
-HIMAGELIST WINAPI ImageList_Merge (
-	HIMAGELIST himl1,
-	INT32 i1,
-	HIMAGELIST himl2,
-	INT32 i2,
-	INT32 xOffs,
-	INT32 yOffs)
+HIMAGELIST WINAPI
+ImageList_Merge (HIMAGELIST himl1, INT32 i1, HIMAGELIST himl2, INT32 i2,
+		 INT32 dx, INT32 dy)
 {
     HIMAGELIST himlDst = NULL;
     HDC32      hdcSrcImage, hdcDstImage;
@@ -1316,34 +1520,34 @@
         return (NULL);
     }
 
-    if (xOffs > 0) {
-        cxDst = _MAX (himl1->cx, xOffs + himl2->cx);
+    if (dx > 0) {
+        cxDst = _MAX (himl1->cx, dx + himl2->cx);
         xOff1 = 0;
-        xOff2 = xOffs;
+        xOff2 = dx;
     }
-    else if (xOffs < 0) {
-        cxDst = _MAX (himl2->cx, himl1->cx - xOffs);
-        xOff1 = -xOffs;
+    else if (dx < 0) {
+        cxDst = _MAX (himl2->cx, himl1->cx - dx);
+        xOff1 = -dx;
         xOff2 = 0;
     }
     else {
-        cxDst = 0;
+        cxDst = _MAX (himl1->cx, himl2->cx);
         xOff1 = 0;
         xOff2 = 0;
     }
 
-    if (yOffs > 0) {
-        cyDst = _MAX (himl1->cy, yOffs + himl2->cy);
+    if (dy > 0) {
+        cyDst = _MAX (himl1->cy, dy + himl2->cy);
         yOff1 = 0;
-        yOff2 = yOffs;
+        yOff2 = dy;
     }
-    else if (yOffs < 0) {
-        cyDst = _MAX (himl2->cy, himl1->cy - yOffs);
-        yOff1 = -yOffs;
+    else if (dy < 0) {
+        cyDst = _MAX (himl2->cy, himl1->cy - dy);
+        yOff1 = -dy;
         yOff2 = 0;
     }
     else {
-        cyDst = 0;
+        cyDst = _MAX (himl1->cy, himl2->cy);
         yOff1 = 0;
         yOff2 = 0;
     }
@@ -1392,10 +1596,22 @@
 }
 
 
+/*************************************************************************
+ * ImageList_Read [COMCTL32.66]
+ *
+ * Reads an image list from a stream.
+ *
+ * PARAMS
+ *     pstm [I] pointer to a stream
+ *
+ * RETURNS
+ *     Success: image list handle
+ *     Failure: NULL
+ */
+
 #if 0
 #if __IStream_INTERFACE_DEFINED__
-HIMAGELIST WINAPI ImageList_Read (
-	LPSTREAM pstm)
+HIMAGELIST WINAPI ImageList_Read (LPSTREAM pstm)
 {
     FIXME (imagelist, "empty stub!\n");
 
@@ -1406,9 +1622,20 @@
 #endif /* 0 */
 
 
-BOOL32 WINAPI ImageList_Remove (
-	HIMAGELIST himl,
-	INT32 i)
+/*************************************************************************
+ * ImageList_Remove [COMCTL32.67] Removes an image from an image list
+ *
+ * PARAMS
+ *     himl [I] image list handle
+ *     i    [I] image index
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ */
+
+BOOL32 WINAPI
+ImageList_Remove (HIMAGELIST himl, INT32 i)
 {
     HBITMAP32 hbmNewImage, hbmNewMask;
     HDC32     hdcSrc, hdcDst;
@@ -1521,11 +1748,25 @@
 }
 
 
-BOOL32 WINAPI ImageList_Replace (
-	HIMAGELIST himl,
-	INT32 i,
-	HBITMAP32 hbmImage, 
-	HBITMAP32 hbmMask)
+/*************************************************************************
+ * ImageList_Replace [COMCTL32.68] 
+ *
+ * Replaces an image in an image list with a new image.
+ *
+ * PARAMS
+ *     himl     [I] image list handle
+ *     i        [I] image index
+ *     hbmImage [I] image bitmap handle
+ *     hbmMask  [I] mask bitmap handle. Can be NULL.
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ */
+
+BOOL32 WINAPI
+ImageList_Replace (HIMAGELIST himl, INT32 i, HBITMAP32 hbmImage,
+		   HBITMAP32 hbmMask)
 {
     HDC32 hdcImageList, hdcImage;
     BITMAP32 bmp;
@@ -1568,10 +1809,23 @@
 }
 
 
-INT32 WINAPI ImageList_ReplaceIcon (
-	HIMAGELIST himl,
-	INT32 i,
-	HICON32 hIcon)
+/*************************************************************************
+ * ImageList_ReplaceIcon [COMCTL32.69]
+ *
+ * Replaces an image in an image list using an icon.
+ *
+ * PARAMS
+ *     himl  [I] image list handle
+ *     i     [I] image index
+ *     hIcon [I] icon handle
+ *
+ * RETURNS
+ *     Success: index of the replaced image
+ *     Failure: -1
+ */
+
+INT32 WINAPI
+ImageList_ReplaceIcon (HIMAGELIST himl, INT32 i, HICON32 hIcon)
 {
     HDC32     hdcImageList, hdcImage;
     INT32     nIndex;
@@ -1602,7 +1856,7 @@
 
     if (i == -1) {
         if (himl->cCurImage + 1 >= himl->cMaxImage)
-            IMAGELIST_InternalGrowBitmaps (himl, 1);
+            IMAGELIST_InternalExpandBitmaps (himl, 1);
 
         nIndex = himl->cCurImage;
         himl->cCurImage++;
@@ -1648,35 +1902,101 @@
 }
 
 
-COLORREF WINAPI ImageList_SetBkColor (
-	HIMAGELIST himl,
-	COLORREF clrBk)
+/*************************************************************************
+ * ImageList_SetBkColor [COMCTL32.70] 
+ *
+ * Sets the background color of an image list.
+ *
+ * PARAMS
+ *     himl  [I] image list handle
+ *     clrBk [I] background color
+ *
+ * RETURNS
+ *     Success: previous background color
+ *     Failure: CLR_NONE
+ */
+
+COLORREF WINAPI
+ImageList_SetBkColor (HIMAGELIST himl, COLORREF clrBk)
 {
     COLORREF clrOldBk;
 
+    if (himl == NULL)
+	return (CLR_NONE);
+
     clrOldBk = himl->clrBk;
     himl->clrBk = clrBk;
     return (clrOldBk);
 }
 
 
-BOOL32 WINAPI ImageList_SetDragCursorImage (
-	HIMAGELIST himlDrag,
-	INT32 iDrag,
-	INT32 dxHotspot,
-	INT32 dyHotspot)
+/*************************************************************************
+ * ImageList_SetDragCursorImage [COMCTL32.75]
+ *
+ * Combines the specified image with the current drag image
+ *
+ * PARAMS
+ *     himlDrag  [I] drag image list handle
+ *     iDrag     [I] drag image index
+ *     dxHotspot [I] X position of the hot spot
+ *     dyHotspot [I] Y position of the hot spot
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ *
+ * BUGS
+ *     empty stub.
+ */
+
+BOOL32 WINAPI
+ImageList_SetDragCursorImage (HIMAGELIST himlDrag, INT32 iDrag,
+			      INT32 dxHotspot, INT32 dyHotspot)
 {
+    HIMAGELIST himlTemp;
+
     FIXME (imagelist, "empty stub!\n");
 
+    if (himlInternalDrag == NULL) return (FALSE);
+
+    TRACE (imagelist, " dxH=%d dyH=%d nX=%d nY=%d\n",
+	   dxHotspot, dyHotspot, nInternalDragHotspotX, nInternalDragHotspotY);
+
+    himlTemp = ImageList_Merge (himlInternalDrag, 0, himlDrag, iDrag,
+				dxHotspot, dyHotspot);
+
+    ImageList_Destroy (himlInternalDrag);
+    himlInternalDrag = himlTemp;
+
+    nInternalDragHotspotX = dxHotspot;
+    nInternalDragHotspotY = dyHotspot;
+
     return (FALSE);
 }
 
 
+/*************************************************************************
+ * ImageList_SetFilter [COMCTL32.76] 
+ *
+ * Sets a filter (or does something completely different)!!???
+ *
+ * PARAMS
+ *     himl     [I] ???
+ *     i        [I] ???
+ *     dwFilter [I] ???
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ *
+ * BUGS
+ *     undocumented!!!!
+ *     empty stub.
+ */
+
 #if 0
-BOOL32 WINAPI ImageList_SetFilter (
-	HIMAGELIST himl, 
-	INT32 iIndex, 
-	INT32 iFilter)
+BOOL32 WINAPI
+ImageList_SetFilter (HIMAGELIST himl, INT32 i, DWORD dwFilter)
 {
     FIXME (imagelist, "empty stub!\n");
 
@@ -1685,10 +2005,23 @@
 #endif /* 0 */
 
 
-BOOL32 WINAPI ImageList_SetIconSize (
-	HIMAGELIST himl, 
-	INT32 cx, 
-	INT32 cy)
+/*************************************************************************
+ * ImageList_SetIconSize [COMCTL32.77]
+ *
+ * Sets the image size of the bitmap and deletes all images.
+ *
+ * PARAMS
+ *     himl [I] image list handle
+ *     cx   [I] image width
+ *     cy   [I] image height
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ */
+
+BOOL32 WINAPI
+ImageList_SetIconSize (HIMAGELIST himl, INT32 cx, INT32 cy)
 {
     INT32 nCount;
 
@@ -1718,9 +2051,22 @@
 }
 
 
-BOOL32 WINAPI ImageList_SetImageCount (
-	HIMAGELIST himl, 
-	INT32 iImageCount)
+/*************************************************************************
+ * ImageList_SetImageCount [COMCTL32.78]
+ *
+ * Resizes an image list to the specified number of images.
+ *
+ * PARAMS
+ *     himl        [I] image list handle
+ *     iImageCount [I] number of images in the image list
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ */
+
+BOOL32 WINAPI
+ImageList_SetImageCount (HIMAGELIST himl, INT32 iImageCount)
 {
     HDC32     hdcImageList, hdcBitmap;
     HBITMAP32 hbmNewBitmap;
@@ -1783,10 +2129,23 @@
 }
 
 
-BOOL32 WINAPI ImageList_SetOverlayImage (
-	HIMAGELIST himl, 
-	INT32 iImage, 
-	INT32 iOverlay)
+/*************************************************************************
+ * ImageList_SetOverlayImage [COMCTL32.79]
+ *
+ * Assigns an overlay mask index to an existing image in an image list.
+ *
+ * PARAMS
+ *     himl     [I] image list handle
+ *     iImage   [I] image index
+ *     iOverlay [I] overlay mask index
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ */
+
+BOOL32 WINAPI
+ImageList_SetOverlayImage (HIMAGELIST himl, INT32 iImage, INT32 iOverlay)
 {
     if ((iOverlay < 1) || (iOverlay > MAX_OVERLAYIMAGE)) return (FALSE);
     if ((iImage < 0) || (iImage > himl->cCurImage)) return (FALSE);
@@ -1796,11 +2155,27 @@
 }
 
 
+/*************************************************************************
+ * ImageList_Write [COMCTL32.80]
+ *
+ * Writes an image list to a stream.
+ *
+ * PARAMS
+ *     himl [I] Image list handle.
+ *     pstm [O] Pointer to a stream.
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ *
+ * BUGS
+ *     empty stub.
+ */
+
 #if 0
 #if __IStream_INTERFACE_DEFINED__
-BOOL32 WINAPI ImageList_Write (
-	HIMAGELIST himl, 
-	LPSTREAM pstm)
+BOOL32 WINAPI
+ImageList_Write (HIMAGELIST himl, LPSTREAM pstm)
 {
     FIXME (imagelist, "empty stub!\n");
 
@@ -1809,3 +2184,4 @@
 }
 #endif  /* __IStream_INTERFACE_DEFINED__ */
 #endif  /* 0 */
+
diff --git a/misc/lstr.c b/misc/lstr.c
index 98d8748..1491d4f 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -152,15 +152,15 @@
  */
 void WINAPI OutputDebugString16( LPCSTR str )
 {
-    char *module;
+    char module[10];
     char *p, *buffer = HeapAlloc( GetProcessHeap(), 0, strlen(str)+2 );
     /* Remove CRs */
     for (p = buffer; *str; str++) if (*str != '\r') *p++ = *str;
     *p = '\0';
     if ((p > buffer) && (p[-1] == '\n')) p[1] = '\0'; /* Remove trailing \n */
-    module = MODULE_GetModuleName( GetCurrentTask() );
-    TRACE(resource, "%s says '%s'\n",
-             module ? module : "???", buffer );
+    if (!GetModuleName( GetCurrentTask(), module, sizeof(module) ))
+        strcpy( module, "???" );
+    TRACE(resource, "%s says '%s'\n", module, buffer );
     HeapFree( GetProcessHeap(), 0, buffer );
 }
 
@@ -553,7 +553,7 @@
 
 	if (from) {
 		f=from;
-		while (*f) {
+		while (*f && !nolinefeed) {
 			if (*f=='%') {
 				int	insertnr;
 				char	*fmtstr,*sprintfbuf,*x,*lastf;
@@ -646,14 +646,7 @@
 		}
 		*t='\0';
 	}
-	if (nolinefeed) {
-	    /* remove linefeed */
-	    if(t>target && t[-1]=='\n') {
-		*--t=0;
-		if(t>target && t[-1]=='\r')
-		    *--t=0;
-	    }
-	} else {
+	if (!nolinefeed) {
 	    /* add linefeed */
 	    if(t==target || t[-1]!='\n')
 		ADD_TO_T('\n'); /* FIXME: perhaps add \r too? */
@@ -732,7 +725,7 @@
 
 	if (from) {
 		f=from;
-		while (*f) {
+		while (*f && !nolinefeed) {
 			if (*f=='%') {
 				int	insertnr;
 				char	*fmtstr,*sprintfbuf,*x;
@@ -826,14 +819,7 @@
 		}
 		*t='\0';
 	}
-	if (nolinefeed) {
-	    /* remove linefeed */
-	    if(t>target && t[-1]=='\n') {
-		*--t=0;
-		if(t>target && t[-1]=='\r')
-		    *--t=0;
-	    }
-	} else {
+	if (!nolinefeed) {
 	    /* add linefeed */
 	    if(t==target || t[-1]!='\n')
 		ADD_TO_T('\n'); /* FIXME: perhaps add \r too? */
diff --git a/misc/lzexpand.c b/misc/lzexpand.c
index dcf6675..6bc9f44 100644
--- a/misc/lzexpand.c
+++ b/misc/lzexpand.c
@@ -473,17 +473,25 @@
  */
 LONG WINAPI LZCopy32( HFILE32 src, HFILE32 dest )
 {
-	int	i,ret,wret;
+	int	usedlzinit=0,i,ret,wret;
 	LONG	len;
+	HFILE32	oldsrc = src;
 #define BUFLEN	1000
 	BYTE	buf[BUFLEN];
 	INT32	WINAPI (*xread)(HFILE32,LPVOID,UINT32);
 
 	TRACE(file,"(%d,%d)\n",src,dest);
+	if (src<0x400) {
+		src = LZInit32(src);
+		if (src!=oldsrc)
+			usedlzinit=1;
+		if (src>0xfff0)
+			return 0;
+	}
+
 	for (i=0;i<nroflzstates;i++)
 		if (src==lzstates[i].lzfd)
 			break;
-
 	/* not compressed? just copy */
 	if (i==nroflzstates)
 		xread=(INT32(*)(HFILE32,LPVOID,UINT32))_lread32;
@@ -504,6 +512,8 @@
 		if (wret!=ret)
 			return LZERROR_WRITE;
 	}
+	if (usedlzinit)
+		LZClose32(src);
 	return len;
 #undef BUFLEN
 }
diff --git a/misc/main.c b/misc/main.c
index eea58b9..6d7f47d 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -116,6 +116,7 @@
 #define NB_OPTIONS  (sizeof(optionsTable) / sizeof(optionsTable[0]))
 
 #define USAGE \
+  "%s\n" \
   "Usage:  %s [options] \"program_name [arguments]\"\n" \
   "\n" \
   "Options:\n" \
@@ -128,6 +129,7 @@
   "    -dll name       Enable or disable built-in DLLs\n" \
   "    -failreadonly   Read only files may not be opened in write mode\n" \
   "    -fixedmap       Use a \"standard\" color map\n" \
+  "    -help           Show this help message\n" \
   "    -iconic         Start as an icon\n" \
   "    -language xx    Set the language (one of En,Es,De,No,Fr,Fi,Da,Cz,Eo,It,Ko,\n                    Hu,Pl,Po,Sw,Ca)\n" \
   "    -managed        Allow the window manager to manage created windows\n" \
@@ -146,7 +148,7 @@
  */
 void MAIN_Usage( char *name )
 {
-    MSG( USAGE, name );
+    MSG( USAGE, WINE_RELEASE_INFO, name );
     exit(1);
 }
 
@@ -199,12 +201,14 @@
 
 
 /***********************************************************************
- *                    ParseDebugOptions
+ *          MAIN_ParseDebugOptions
  *
  *  Turns specific debug messages on or off, according to "options".
- *  Returns TRUE if parsing was successful
+ *  
+ *  RETURNS
+ *    TRUE if parsing was successful
  */
-BOOL32 ParseDebugOptions(char *options)
+static BOOL32 MAIN_ParseDebugOptions(char *options)
 {
   int l, cls;
   if (strlen(options)<3)
@@ -330,6 +334,11 @@
             MSG( "%s\n", WINE_RELEASE_INFO );
             exit(0);
         }
+        if (!strcmp( argv[i], "-h" ) || !strcmp( argv[i], "-help" ))
+        {
+            MAIN_Usage(argv[0]);
+            exit(0);
+        }
     }
 
       /* Open display */
@@ -383,7 +392,7 @@
     if (MAIN_GetResource( db, ".mode", &value))
         MAIN_ParseModeOption( (char *)value.addr );
     if (MAIN_GetResource( db, ".debugoptions", &value))
-	ParseDebugOptions((char*)value.addr);
+	MAIN_ParseDebugOptions((char*)value.addr);
     if (MAIN_GetResource( db, ".debugmsg", &value))
       {
 #ifndef DEBUG_RUNTIME
@@ -392,7 +401,7 @@
 	  argv[0]);
 	exit(1);
 #else
-	if (ParseDebugOptions((char*)value.addr)==FALSE)
+	if (MAIN_ParseDebugOptions((char*)value.addr)==FALSE)
 	  {
 	    int i;
 	    MSG("%s: Syntax: -debugmsg [class]+xxx,...  or "
@@ -531,6 +540,9 @@
 }
 
 
+/***********************************************************************
+ *           called_at_exit
+ */
 static void called_at_exit(void)
 {
     MAIN_RestoreSetup();
diff --git a/misc/network.c b/misc/network.c
index 1df5a1c..2c17dcb 100644
--- a/misc/network.c
+++ b/misc/network.c
@@ -478,9 +478,14 @@
  */
 int WINAPI WNetGetDirectoryType16(LPSTR lpName, LPINT16 lpType)
 {
-	FIXME(wnet, "('%s',%p): stub\n",lpName,lpType);
-	*lpType = 0;
-	return WN_NO_NETWORK;
+        UINT32 type = GetDriveType32A(lpName);
+
+	if (type == DRIVE_DOESNOTEXIST)
+	  type = GetDriveType32A(NULL);
+	*lpType = (type==DRIVE_REMOTE)?WNDT_NETWORK:WNDT_NORMAL;
+	TRACE(wnet,"%s is %s\n",lpName,(*lpType==WNDT_NETWORK)?
+	      "WNDT_NETWORK":"WNDT_NORMAL");
+	return WN_SUCCESS;
 }
 
 /*****************************************************************
diff --git a/misc/registry.c b/misc/registry.c
index 537c4ed..d4569e6 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -6,6 +6,17 @@
  * December 21, 1997 - Kevin Cozens
  * Fixed bugs in the _w95_loadreg() function. Added extra information
  * regarding the format of the Windows '95 registry files.
+ *
+ * May 5, 1998 - Matthew Becker
+ * Changed optionflags to DWORD instead of int because it could be 0x8000000
+ * All error return values must come from winerror.h
+ *
+ * NOTES
+ *    When changing this file, please re-run the regtest program to ensure
+ *    the conditions are handled properly.
+ *
+ * TODO
+ *    Security access
  */
 
 #include <stdlib.h>
@@ -29,6 +40,9 @@
 #include "xmalloc.h"
 #include "winreg.h"
 
+void SHELL_StartupRegistry();
+
+/* This is not used anywhere */
 #define	DEBUG_W95_LOADREG	0
 
 /* FIXME: following defines should be configured global ... */
@@ -83,8 +97,12 @@
 /* what valuetypes do we need to convert? */
 #define UNICONVMASK	((1<<REG_SZ)|(1<<REG_MULTI_SZ)|(1<<REG_EXPAND_SZ))
 
-extern LPWSTR __cdecl CRTDLL_wcschr(LPWSTR a,WCHAR c);
 
+/*
+ * FIXME
+ *   Are these doing the same as HEAP_strdupAtoW and HEAP_strdupWtoA?
+ *   If so, can we remove them?
+ */
 static LPWSTR strdupA2W(LPCSTR src)
 {
 	LPWSTR dest=xmalloc(2*strlen(src)+2);
@@ -111,61 +129,97 @@
 static int	nrofopenhandles=0;
 static int	currenthandle=1;
 
-static void
-add_handle(HKEY hkey,LPKEYSTRUCT lpkey,REGSAM accessmask) {
-	int	i;
 
-	for (i=0;i<nrofopenhandles;i++) {
-		if (openhandles[i].lpkey==lpkey) {
-			WARN(reg, "Tried to add %p twice!\n",lpkey);
-		}
-		if (openhandles[i].hkey==hkey) {
-			WARN(reg, "Tried to add %lx twice!\n",(LONG)hkey);
-		}
-	}
-	openhandles=xrealloc(	openhandles,
-				sizeof(struct openhandle)*(nrofopenhandles+1)
-		);
-	openhandles[i].lpkey	= lpkey;
-	openhandles[i].hkey	= hkey;
-	openhandles[i].accessmask= accessmask;
-	nrofopenhandles++;
+/******************************************************************************
+ * add_handle [Internal]
+ */
+static void add_handle( HKEY hkey, LPKEYSTRUCT lpkey, REGSAM accessmask )
+{
+    int i;
+
+    TRACE(reg,"(%x,%p,%lx)\n",hkey,lpkey,accessmask);
+    if (lpkey)
+        TRACE(reg," (%s)\n",debugstr_w(lpkey->keyname));
+
+    /* Check for duplicates */
+    for (i=0;i<nrofopenhandles;i++) {
+        if (openhandles[i].lpkey==lpkey) {
+            /* This is not really an error - the user is allowed to create
+               two (or more) handles to the same key */
+            /*WARN(reg, "Adding key %p twice\n",lpkey);*/
+        }
+        if (openhandles[i].hkey==hkey) {
+            WARN(reg, "Adding handle %x twice\n",hkey);
+        }
+    }
+    openhandles=xrealloc( openhandles, 
+                          sizeof(struct openhandle)*(nrofopenhandles+1));
+
+    openhandles[i].lpkey = lpkey;
+    openhandles[i].hkey = hkey;
+    openhandles[i].accessmask = accessmask;
+    nrofopenhandles++;
 }
 
-static LPKEYSTRUCT
-get_handle(HKEY hkey) {
-	int	i;
 
-	for (i=0;i<nrofopenhandles;i++)
-		if (openhandles[i].hkey==hkey)
-			return openhandles[i].lpkey;
-	WARN(reg, "Didn't find handle %lx?\n",(LONG)hkey);
-	return NULL;
+/******************************************************************************
+ * get_handle [Internal]
+ *
+ * RETURNS
+ *    Success: Pointer to key
+ *    Failure: NULL
+ */
+static LPKEYSTRUCT get_handle( HKEY hkey )
+{
+    int i;
+
+    for (i=0; i<nrofopenhandles; i++)
+        if (openhandles[i].hkey == hkey)
+            return openhandles[i].lpkey;
+    WARN(reg, "Could not find handle %x\n",hkey);
+    return NULL;
 }
 
-static void
-remove_handle(HKEY hkey) {
-	int	i;
 
-	for (i=0;i<nrofopenhandles;i++)
-		if (openhandles[i].hkey==hkey)
-			break;
-	if (i==nrofopenhandles) {
-		WARN(reg, "Didn't find handle %08x?\n",hkey);
-		return;
-	}
-	memcpy(	openhandles+i,
-		openhandles+i+1,
-		sizeof(struct openhandle)*(nrofopenhandles-i-1)
-	);
-	openhandles=xrealloc(openhandles,sizeof(struct openhandle)*(nrofopenhandles-1));
-	nrofopenhandles--;
-	return;
+/******************************************************************************
+ * remove_handle [Internal]
+ *
+ * PARAMS
+ *    hkey [I] Handle of key to remove
+ *
+ * RETURNS
+ *    Success: ERROR_SUCCESS
+ *    Failure: ERROR_INVALID_HANDLE
+ */
+static DWORD remove_handle( HKEY hkey )
+{
+    int i;
+
+    for (i=0;i<nrofopenhandles;i++)
+        if (openhandles[i].hkey==hkey)
+            break;
+
+    if (i == nrofopenhandles) {
+        WARN(reg, "Could not find handle %x\n",hkey);
+        return ERROR_INVALID_HANDLE;
+    }
+
+    memcpy( openhandles+i,
+            openhandles+i+1,
+            sizeof(struct openhandle)*(nrofopenhandles-i-1)
+    );
+    openhandles=xrealloc(openhandles,sizeof(struct openhandle)*(nrofopenhandles-1));
+    nrofopenhandles--;
+    return ERROR_SUCCESS;
 }
 
 
 /* debug function, converts a unicode into a static memory area 
  * (sub for using two static strings, in case we need them in a single call)
+ *
+ * FIXME
+ *    This seems to be used the same as debugstr_w.
+ *    If so, can this one go away?
  */
 LPSTR
 W2C(LPCWSTR x,int sub) {
@@ -179,11 +233,20 @@
 	return unicodedebug[sub];
 }
 
-static LPKEYSTRUCT
-lookup_hkey(HKEY hkey) {
+
+/******************************************************************************
+ * lookup_hkey [Internal]
+ *
+ * RETURNS
+ *    Success: Pointer to key structure
+ *    Failure: NULL
+ */
+static LPKEYSTRUCT lookup_hkey( HKEY hkey )
+{
 	switch (hkey) {
-	case 0x00000000:
-	case 0x00000001:
+    /* These seem erroneous */
+    /*	case 0x00000000: */
+    /*	case 0x00000001: */
 	case HKEY_CLASSES_ROOT:
 		return key_classes_root;
 	case HKEY_CURRENT_USER:
@@ -204,42 +267,65 @@
 	/*NOTREACHED*/
 }
 
-/* 
+
+/******************************************************************************
+ * split_keypath [Internal]
  * splits the unicode string 'wp' into an array of strings.
  * the array is allocated by this function. 
- * the number of components will be stored in 'wpc'
  * Free the array using FREE_KEY_PATH
+ *
+ * PARAMS
+ *    wp  [I] String to split up
+ *    wpv [O] Array of pointers to strings
+ *    wpc [O] Number of components
  */
-static void
-split_keypath(LPCWSTR wp,LPWSTR **wpv,int *wpc) {
-	int	i,j,len;
-	LPWSTR	ws;
+static void split_keypath( LPCWSTR wp, LPWSTR **wpv, int *wpc)
+{
+    int	i,j,len;
+    LPWSTR ws;
 
-	ws	= HEAP_strdupW( SystemHeap, 0, wp );
-	*wpc	= 1;
-	for (i=0;ws[i];i++) {
-		if (ws[i]=='\\') {
-			ws[i]=0;
-			(*wpc)++;
-		}
-	}
-	len	= i;
-	*wpv	= (LPWSTR*)HeapAlloc( SystemHeap, 0, sizeof(LPWSTR)*(*wpc+2));
-	(*wpv)[0]= ws;
-	j	= 1;
-	for (i=1;i<len;i++)
-		if (ws[i-1]==0)
-			(*wpv)[j++]=ws+i;
-	(*wpv)[j]=NULL;
+    TRACE(reg,"(%s,%p,%p)\n",debugstr_w(wp),wpv,wpc);
+
+    ws	= HEAP_strdupW( SystemHeap, 0, wp );
+
+    /* We know we have at least one substring */
+    *wpc = 1;
+
+    /* Replace each backslash with NULL, and increment the count */
+    for (i=0;ws[i];i++) {
+        if (ws[i]=='\\') {
+            ws[i]=0;
+            (*wpc)++;
+        }
+    }
+
+    len = i;
+
+    /* Allocate the space for the array of pointers, leaving room for the
+       NULL at the end */
+    *wpv = (LPWSTR*)HeapAlloc( SystemHeap, 0, sizeof(LPWSTR)*(*wpc+2));
+    (*wpv)[0]= ws;
+
+    /* Assign each pointer to the appropriate character in the string */
+    j = 1;
+    for (i=1;i<len;i++)
+        if (ws[i-1]==0) {
+            (*wpv)[j++]=ws+i;
+            /* TRACE(reg, " Subitem %d = %s\n",j-1,debugstr_w((*wpv)[j-1])); */
+        }
+
+    (*wpv)[j]=NULL;
 }
 #define FREE_KEY_PATH HeapFree(SystemHeap,0,wps[0]);HeapFree(SystemHeap,0,wps);
 
-/*
+
+
+
+/******************************************************************************
+ * SHELL_Init [Internal]
  * Shell initialisation, allocates keys. 
  */
-void SHELL_StartupRegistry();
-void
-SHELL_Init() {
+void SHELL_Init() {
 	struct	passwd	*pwd;
 
 	HKEY	cl_r_hkey,c_u_hkey;
@@ -249,8 +335,8 @@
 	xx->keyname= strdupA2W("<should_not_appear_anywhere>");
 
 	ADD_ROOT_KEY(key_local_machine);
-	if (RegCreateKey16(HKEY_LOCAL_MACHINE,"\\SOFTWARE\\Classes",&cl_r_hkey)!=ERROR_SUCCESS) {
-		ERR(reg,"couldn't create HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes. This is impossible.\n");
+	if (RegCreateKey16(HKEY_LOCAL_MACHINE,"SOFTWARE\\Classes",&cl_r_hkey)!=ERROR_SUCCESS) {
+		ERR(reg,"Could not create HKLM\\SOFTWARE\\Classes. This is impossible.\n");
 		exit(1);
 	}
 	key_classes_root = lookup_hkey(cl_r_hkey);
@@ -283,17 +369,25 @@
 }
 
 
-void
-SHELL_StartupRegistry() {
+/******************************************************************************
+ * SHELL_StartupRegistry [Internal]
+ */
+void SHELL_StartupRegistry( void )
+{
 	HKEY	hkey;
 	char	buf[200];
 
-	RegCreateKey16(HKEY_DYN_DATA,"\\PerfStats\\StatData",&hkey);
+    TRACE(reg,"(void)\n");
+
+	RegCreateKey16(HKEY_DYN_DATA,"PerfStats\\StatData",&hkey);
 	RegCloseKey(hkey);
 
-	RegOpenKey16(HKEY_LOCAL_MACHINE,"\\HARDWARE\\DESCRIPTION\\System",&hkey);
+        /* This was an Open, but since it is called before the real registries
+           are loaded, it was changed to a Create - MTB 980507*/
+	RegCreateKey16(HKEY_LOCAL_MACHINE,"HARDWARE\\DESCRIPTION\\System",&hkey);
 	RegSetValueEx32A(hkey,"Identifier",0,REG_SZ,"SystemType WINE",strlen("SystemType WINE"));
 	RegCloseKey(hkey);
+
 	/* \\SOFTWARE\\Microsoft\\Window NT\\CurrentVersion
 	 *						CurrentVersion
 	 *						CurrentBuildNumber
@@ -313,6 +407,8 @@
 		RegCloseKey(hkey);
 	}
 }
+
+
 /************************ SAVE Registry Function ****************************/
 
 #define REGISTRY_SAVE_VERSION	0x00000001
@@ -454,14 +550,20 @@
         return TRUE;
 }
 
-void
-SHELL_SaveRegistry() {
+
+/******************************************************************************
+ * SHELL_SaveRegistry [Internal]
+ */
+void SHELL_SaveRegistry( void )
+{
 	char	*fn;
 	struct	passwd	*pwd;
 	char	buf[4];
 	HKEY	hkey;
 	int	all;
 
+    TRACE(reg,"(void)\n");
+
 	all=0;
 	if (RegOpenKey16(HKEY_CURRENT_USER,KEY_REGISTRY,&hkey)!=ERROR_SUCCESS) {
 		strcpy(buf,"yes");
@@ -524,11 +626,15 @@
 
 /************************ LOAD Registry Function ****************************/
 
-static LPKEYSTRUCT
-_find_or_add_key(LPKEYSTRUCT lpkey,LPWSTR keyname) {
+
+/******************************************************************************
+ * _find_or_add_key [Internal]
+ */
+static LPKEYSTRUCT _find_or_add_key( LPKEYSTRUCT lpkey, LPWSTR keyname )
+{
 	LPKEYSTRUCT	lpxkey,*lplpkey;
 
-	if (keyname[0]==0) {
+	if ((!keyname) || (keyname[0]==0)) {
 		free(keyname);
 		return lpkey;
 	}
@@ -695,33 +801,47 @@
 	return s;
 }
 
-static int
-_wine_loadsubkey(
-	FILE *F,LPKEYSTRUCT lpkey,int level,char **buf,int *buflen,int optflag
-) {
+
+/******************************************************************************
+ * _wine_loadsubkey [Internal]
+ *
+ * NOTES
+ *    It seems like this is returning a boolean.  Should it?
+ *
+ * RETURNS
+ *    Success: 1
+ *    Failure: 0
+ */
+static int _wine_loadsubkey( FILE *F, LPKEYSTRUCT lpkey, int level, char **buf,
+                             int *buflen, DWORD optflag )
+{
 	LPKEYSTRUCT	lpxkey;
 	int		i;
 	char		*s;
 	LPWSTR		name;
 
-	lpkey->flags |= optflag;
+    TRACE(reg,"(%p,%p,%d,%s,%d,%lx)\n", F, lpkey, level, debugstr_a(*buf),
+          *buflen, optflag);
 
-	/* good. we already got a line here ... so parse it */
-	lpxkey	= NULL;
-	while (1) {
-		i=0;s=*buf;
-		while (*s=='\t') {
-			s++;
-			i++;
-		}
-		if (i>level) {
-			if (lpxkey==NULL) {
-				WARN(reg,"Got a subhierarchy without resp. key?\n");
-				return 0;
-			}
-			_wine_loadsubkey(F,lpxkey,level+1,buf,buflen,optflag);
-			continue;
-		}
+    lpkey->flags |= optflag;
+
+    /* Good.  We already got a line here ... so parse it */
+    lpxkey = NULL;
+    while (1) {
+        i=0;s=*buf;
+        while (*s=='\t') {
+            s++;
+            i++;
+        }
+        if (i>level) {
+            if (lpxkey==NULL) {
+                WARN(reg,"Got a subhierarchy without resp. key?\n");
+                return 0;
+            }
+            _wine_loadsubkey(F,lpxkey,level+1,buf,buflen,optflag);
+            continue;
+        }
+
 		/* let the caller handle this line */
 		if (i<level || **buf=='\0')
 			return 1;
@@ -783,12 +903,16 @@
 		/* read the next line */
 		if (!_wine_read_line(F,buf,buflen))
 			return 1;
-	}
-	return 1;
+    }
+    return 1;
 }
 
-static int
-_wine_loadsubreg(FILE *F,LPKEYSTRUCT lpkey,int optflag) {
+
+/******************************************************************************
+ * _wine_loadsubreg [Internal]
+ */
+static int _wine_loadsubreg( FILE *F, LPKEYSTRUCT lpkey, DWORD optflag )
+{
 	int	ver;
 	char	*buf;
 	int	buflen;
@@ -819,27 +943,35 @@
 	return 1;
 }
 
-static void
-_wine_loadreg(LPKEYSTRUCT lpkey,char *fn,int optflag) {
-	FILE	*F;
 
-	F=fopen(fn,"rb");
-	if (F==NULL) {
-		WARN(reg,"Couldn't open %s for reading: %s\n",
-		       fn,strerror(errno)
-		);
-		return;
-	}
-	if (!_wine_loadsubreg(F,lpkey,optflag)) {
-		fclose(F);
-		unlink(fn);
-		return;
-	}
-	fclose(F);
+/******************************************************************************
+ * _wine_loadreg [Internal]
+ */
+static void _wine_loadreg( LPKEYSTRUCT lpkey, char *fn, DWORD optflag )
+{
+    FILE *F;
+
+    TRACE(reg,"(%p,%s,%lx)\n",lpkey,debugstr_a(fn),optflag);
+
+    F = fopen(fn,"rb");
+    if (F==NULL) {
+        WARN(reg,"Couldn't open %s for reading: %s\n",fn,strerror(errno) );
+        return;
+    }
+    if (!_wine_loadsubreg(F,lpkey,optflag)) {
+        fclose(F);
+        unlink(fn);
+        return;
+    }
+    fclose(F);
 }
 
-static void
-_copy_registry(LPKEYSTRUCT from,LPKEYSTRUCT to) {
+
+/******************************************************************************
+ * _copy_registry [Internal]
+ */
+static void _copy_registry( LPKEYSTRUCT from, LPKEYSTRUCT to )
+{
 	LPKEYSTRUCT	lpxkey;
 	int		j;
 	LPKEYVALUE	valfrom;
@@ -872,6 +1004,7 @@
 	}
 }
 
+
 /* WINDOWS 95 REGISTRY LOADER */
 /* 
  * Structure of a win95 registry database.
@@ -998,6 +1131,10 @@
    return dest;
 }
 
+
+/******************************************************************************
+ * _w95_processKey [Internal]
+ */
 static LPKEYSTRUCT _w95_processKey ( LPKEYSTRUCT lpkey, 
                                    int nrLS, int nrMS, struct _w95_info *info )
 
@@ -1222,6 +1359,7 @@
 	free (info.rgknbuffer);
 }
 
+
 /* WINDOWS 31 REGISTRY LOADER, supplied by Tor Sjøwall, tor@sn.no */
 
 /*
@@ -1357,8 +1495,11 @@
 	}
 }
 
-void
-_w31_loadreg() {
+
+/******************************************************************************
+ * _w31_loadreg [Internal]
+ */
+void _w31_loadreg() {
 	HFILE32			hf;
 	struct _w31_header	head;
 	struct _w31_tabent	*tab;
@@ -1370,6 +1511,8 @@
 	HKEY			hkey;
 	LPKEYSTRUCT		lpkey;
 
+    TRACE(reg,"(void)\n");
+
 	hf = OpenFile32("reg.dat",&ofs,OF_READ);
 	if (hf==HFILE_ERROR32)
 		return;
@@ -1422,7 +1565,7 @@
 	}
 	lastmodified = DOSFS_FileTimeToUnixTime(&hfinfo.ftLastWriteTime,NULL);
 
-	if (RegCreateKey16(HKEY_LOCAL_MACHINE,"\\SOFTWARE\\Classes",&hkey)!=ERROR_SUCCESS)
+	if (RegCreateKey16(HKEY_LOCAL_MACHINE,"SOFTWARE\\Classes",&hkey)!=ERROR_SUCCESS)
 		return;
 	lpkey = lookup_hkey(hkey);
 	__w31_dumptree(tab[0].w1,txt,tab,&head,lpkey,lastmodified,0);
@@ -1432,13 +1575,18 @@
 	return;
 }
 
-void
-SHELL_LoadRegistry() {
+
+/**********************************************************************************
+ * SHELL_LoadRegistry [Internal]
+ */
+void SHELL_LoadRegistry( void )
+{
 	char	*fn;
 	struct	passwd	*pwd;
 	LPKEYSTRUCT	lpkey;
 	HKEY		hkey;
 
+    TRACE(reg,"(void)\n");
 
 	if (key_classes_root==NULL)
 		SHELL_Init();
@@ -1453,6 +1601,8 @@
 	/* the global user default is loaded under HKEY_USERS\\.Default */
 	RegCreateKey16(HKEY_USERS,".Default",&hkey);
 	lpkey = lookup_hkey(hkey);
+        if(!lpkey)
+            WARN(reg,"Could not create global user default key\n");
 	_wine_loadreg(lpkey,SAVE_USERS_DEFAULT,0);
 
 	/* HKEY_USERS\\.Default is copied to HKEY_CURRENT_USER */
@@ -1515,114 +1665,127 @@
  *                                  RegOpenKey32W   -> RegOpenKeyEx32W 
  */
 
-/* RegOpenKeyExW		[ADVAPI32.150] */
-DWORD WINAPI RegOpenKeyEx32W(
-	HKEY	hkey,
-	LPCWSTR	lpszSubKey,
-	DWORD	dwReserved,
-	REGSAM	samDesired,
-	LPHKEY	retkey
-) {
+
+/******************************************************************************
+ * RegOpenKeyEx32W [ADVAPI32.150]
+ * Opens the specified key
+ *
+ * Unlike RegCreateKeyEx, this does not create the key if it does not exist.
+ *
+ * PARAMS
+ *    hkey       [I] Handle of open key
+ *    lpszSubKey [I] Name of subkey to open
+ *    dwReserved [I] Reserved - must be zero
+ *    samDesired [I] Security access mask
+ *    retkey     [O] Address of handle of open key
+ *
+ * RETURNS
+ *    Success: ERROR_SUCCESS
+ *    Failure: Error code
+ */
+DWORD WINAPI RegOpenKeyEx32W( HKEY hkey, LPCWSTR lpszSubKey, DWORD dwReserved,
+                              REGSAM samDesired, LPHKEY retkey )
+{
 	LPKEYSTRUCT	lpNextKey,lpxkey;
 	LPWSTR		*wps;
 	int		wpc,i;
-	TRACE(reg,"(%lx,%s,%ld,%lx,%p)\n",
-		(LONG)hkey,W2C(lpszSubKey,0),dwReserved,samDesired,retkey
-	);
 
-	lpNextKey	= lookup_hkey(hkey);
-	if (!lpNextKey)
-		return SHELL_ERROR_BADKEY;
-	if (!lpszSubKey || !*lpszSubKey) {
-		add_handle(++currenthandle,lpNextKey,samDesired);
-		*retkey=currenthandle;
-		return SHELL_ERROR_SUCCESS;
-	}
+    TRACE(reg,"(%x,%s,%ld,%lx,%p)\n", hkey,debugstr_w(lpszSubKey),dwReserved,
+          samDesired,retkey);
+
+    lpNextKey = lookup_hkey(hkey);
+    if (!lpNextKey) {
+        WARN(reg,"Invalid handle: %x\n",hkey);
+        return ERROR_INVALID_HANDLE;
+    }
+
+    if (!lpszSubKey || !*lpszSubKey) {
+        /* Either NULL or pointer to empty string, so return a new handle
+           to the original hkey */
+        add_handle(++currenthandle,lpNextKey,samDesired);
+        *retkey=currenthandle;
+        return ERROR_SUCCESS;
+    }
+
 	split_keypath(lpszSubKey,&wps,&wpc);
-	i 	= 0;
+	i = 0;
 	while ((i<wpc) && (wps[i][0]=='\0')) i++;
-	lpxkey	= lpNextKey;
-	while (wps[i]) {
-		lpxkey=lpNextKey->nextsub;
-		while (lpxkey) {
-			if (!lstrcmpi32W(wps[i],lpxkey->keyname))
-				break;
-			lpxkey=lpxkey->next;
-		}
-		if (!lpxkey) {
-			FREE_KEY_PATH;
-			return SHELL_ERROR_BADKEY;
-		}
-		i++;
-		lpNextKey	= lpxkey;
-	}
-	add_handle(++currenthandle,lpxkey,samDesired);
-	*retkey	= currenthandle;
-	FREE_KEY_PATH;
-	return	SHELL_ERROR_SUCCESS;
-}
+	lpxkey = lpNextKey;
 
-/* RegOpenKeyW			[ADVAPI32.151] */
-DWORD WINAPI RegOpenKey32W(
-	HKEY	hkey,
-	LPCWSTR	lpszSubKey,
-	LPHKEY	retkey
-) {
-	TRACE(reg,"(%lx,%s,%p)\n",
-		(LONG)hkey,W2C(lpszSubKey,0),retkey
-	);
-	return RegOpenKeyEx32W(hkey,lpszSubKey,0,KEY_ALL_ACCESS,retkey);
+    while (wps[i]) {
+        lpxkey=lpNextKey->nextsub;
+        while (lpxkey) {
+            if (!lstrcmpi32W(wps[i],lpxkey->keyname)) {
+                break;
+            }
+            lpxkey=lpxkey->next;
+        }
+
+        if (!lpxkey) {
+            TRACE(reg,"Could not find subkey %s\n",debugstr_w(wps[i]));
+            FREE_KEY_PATH;
+            return ERROR_BADKEY;
+        }
+        i++;
+        lpNextKey = lpxkey;
+    }
+
+    add_handle(++currenthandle,lpxkey,samDesired);
+    *retkey = currenthandle;
+    TRACE(reg,"  Returning %x\n", currenthandle);
+    FREE_KEY_PATH;
+    return ERROR_SUCCESS;
 }
 
 
-/* RegOpenKeyExA		[ADVAPI32.149] */
-DWORD WINAPI RegOpenKeyEx32A(
-	HKEY	hkey,
-	LPCSTR	lpszSubKey,
-	DWORD	dwReserved,
-	REGSAM	samDesired,
-	LPHKEY	retkey
-) {
-	LPWSTR	lpszSubKeyW;
-	DWORD	ret;
-
-	TRACE(reg,"(%lx,%s,%ld,%lx,%p)\n",
-		(LONG)hkey,lpszSubKey,dwReserved,samDesired,retkey
-	);
-	if (lpszSubKey)
-		lpszSubKeyW=strdupA2W(lpszSubKey);
-	else
-		lpszSubKeyW=NULL;
-	ret=RegOpenKeyEx32W(hkey,lpszSubKeyW,dwReserved,samDesired,retkey);
-	if (lpszSubKeyW)
-		free(lpszSubKeyW);
-	return ret;
+/******************************************************************************
+ * RegOpenKey32W [ADVAPI32.151]
+ */
+DWORD WINAPI RegOpenKey32W( HKEY hkey, LPCWSTR lpszSubKey, LPHKEY retkey )
+{
+    TRACE(reg,"(%x,%s,%p)\n",hkey,debugstr_w(lpszSubKey),retkey);
+    return RegOpenKeyEx32W(hkey,lpszSubKey,0,KEY_ALL_ACCESS,retkey);
 }
 
-/* RegOpenKeyA			[ADVAPI32.148] */
-DWORD WINAPI RegOpenKey32A(
-	HKEY	hkey,
-	LPCSTR	lpszSubKey,
-	LPHKEY	retkey
-) {
-	TRACE(reg,"(%lx,%s,%p)\n",
-		(LONG)hkey,lpszSubKey,retkey
-	);
-	return	RegOpenKeyEx32A(hkey,lpszSubKey,0,KEY_ALL_ACCESS,retkey);
+
+/******************************************************************************
+ * RegOpenKeyEx32A [ADVAPI32.149]
+ */
+DWORD WINAPI RegOpenKeyEx32A( HKEY hkey, LPCSTR lpszSubKey, DWORD dwReserved,
+                              REGSAM samDesired, LPHKEY retkey )
+{
+    LPWSTR lpszSubKeyW = HEAP_strdupAtoW(GetProcessHeap(),0,lpszSubKey);
+    DWORD ret;
+
+    TRACE(reg,"(%x,%s,%ld,%lx,%p)\n",hkey,debugstr_a(lpszSubKey),dwReserved,
+          samDesired,retkey);
+
+    ret = RegOpenKeyEx32W(hkey,lpszSubKeyW,dwReserved,samDesired,retkey);
+    HeapFree(GetProcessHeap(),0,lpszSubKeyW);
+    return ret;
 }
 
-/* RegOpenKey			[SHELL.1] [KERNEL.217] */
-DWORD WINAPI RegOpenKey16(
-	HKEY	hkey,
-	LPCSTR	lpszSubKey,
-	LPHKEY	retkey
-) {
-	TRACE(reg,"(%lx,%s,%p)\n",
-		(LONG)hkey,lpszSubKey,retkey
-	);
-	return RegOpenKey32A(hkey,lpszSubKey,retkey);
+
+/******************************************************************************
+ * RegOpenKey32A [ADVAPI32.148]
+ */
+DWORD WINAPI RegOpenKey32A( HKEY hkey, LPCSTR lpszSubKey, LPHKEY retkey )
+{
+    TRACE(reg,"(%x,%s,%p)\n",hkey,debugstr_a(lpszSubKey),retkey);
+    return RegOpenKeyEx32A(hkey,lpszSubKey,0,KEY_ALL_ACCESS,retkey);
 }
 
+
+/******************************************************************************
+ * RegOpenKey16 [SHELL.1] [KERNEL.217]
+ */
+DWORD WINAPI RegOpenKey16( HKEY hkey, LPCSTR lpszSubKey, LPHKEY retkey )
+{
+    TRACE(reg,"(%x,%s,%p)\n",hkey,debugstr_a(lpszSubKey),retkey);
+    return RegOpenKey32A(hkey,lpszSubKey,retkey);
+}
+
+
 /* 
  * Create keys
  * 
@@ -1636,44 +1799,48 @@
  *                                      RegCreateKey32W   -> RegCreateKeyEx32W
  */
 
-/* RegCreateKeyExW		[ADVAPI32.131] */
-DWORD WINAPI RegCreateKeyEx32W(
-	HKEY	hkey,
-	LPCWSTR	lpszSubKey,
-	DWORD	dwReserved,
-	LPWSTR	lpszClass,
-	DWORD	fdwOptions,
-	REGSAM	samDesired,
-	LPSECURITY_ATTRIBUTES lpSecAttribs,
-	LPHKEY	retkey,
-	LPDWORD	lpDispos
-) {
+
+/******************************************************************************
+ * RegCreateKeyEx32W [ADVAPI32.131]
+ *
+ * PARAMS
+ *    ...
+ *    retkey   [O] Address of buffer for opened handle
+ *    lpDispos [O] Receives REG_CREATED_NEW_KEY or REG_OPENED_EXISTING_KEY
+ */
+DWORD WINAPI RegCreateKeyEx32W( HKEY hkey, LPCWSTR lpszSubKey, 
+                                DWORD dwReserved, LPWSTR lpszClass, 
+                                DWORD fdwOptions, REGSAM samDesired,
+                                LPSECURITY_ATTRIBUTES lpSecAttribs, 
+                                LPHKEY retkey, LPDWORD lpDispos )
+{
 	LPKEYSTRUCT	*lplpPrevKey,lpNextKey,lpxkey;
 	LPWSTR		*wps;
 	int		wpc,i;
 
-/*FIXME: handle security/access/whatever */
-	TRACE(reg,"(%lx,%s,%ld,%s,%lx,%lx,%p,%p,%p)\n",
-		(LONG)hkey,
-		W2C(lpszSubKey,0),
-		dwReserved,
-		W2C(lpszClass,1),
-		fdwOptions,
-		samDesired,
-		lpSecAttribs,
-		retkey,
-		lpDispos
-	);
+    /*FIXME: handle security/access/whatever */
 
-	lpNextKey	= lookup_hkey(hkey);
-	if (!lpNextKey)
-		return SHELL_ERROR_BADKEY;
+    TRACE(reg,"(%x,%s,%ld,%s,%lx,%lx,%p,%p,%p)\n", hkey,
+		debugstr_w(lpszSubKey), dwReserved, debugstr_w(lpszClass),
+		fdwOptions, samDesired, lpSecAttribs, retkey, lpDispos);
+
+    lpNextKey = lookup_hkey(hkey);
+    if (!lpNextKey)
+        return ERROR_BADKEY;
+
+    if (lpszSubKey[0] == '\\') {
+        WARN(reg,"Subkey %s must not begin with backslash.\n",debugstr_w(lpszSubKey));
+        return ERROR_BAD_PATHNAME;
+    }
+
 	if (!lpszSubKey || !*lpszSubKey) {
 		add_handle(++currenthandle,lpNextKey,samDesired);
 		*retkey=currenthandle;
+                TRACE(reg, "Returning %x\n", currenthandle);
 		lpNextKey->flags|=REG_OPTION_TAINTED;
-		return SHELL_ERROR_SUCCESS;
+		return ERROR_SUCCESS;
 	}
+
 	split_keypath(lpszSubKey,&wps,&wpc);
 	i 	= 0;
 	while ((i<wpc) && (wps[i][0]=='\0')) i++;
@@ -1694,12 +1861,14 @@
 		add_handle(++currenthandle,lpxkey,samDesired);
 		lpxkey->flags  |= REG_OPTION_TAINTED;
 		*retkey		= currenthandle;
+                TRACE(reg, "Returning %x\n", currenthandle);
 		if (lpDispos)
 			*lpDispos	= REG_OPENED_EXISTING_KEY;
 		FREE_KEY_PATH;
-		return	SHELL_ERROR_SUCCESS;
+		return ERROR_SUCCESS;
 	}
-	/* good. now the hard part */
+
+	/* Good.  Now the hard part */
 	while (wps[i]) {
 		lplpPrevKey	= &(lpNextKey->nextsub);
 		lpxkey		= *lplpPrevKey;
@@ -1710,9 +1879,11 @@
 		*lplpPrevKey=malloc(sizeof(KEYSTRUCT));
 		if (!*lplpPrevKey) {
 			FREE_KEY_PATH;
-			return SHELL_ERROR_OUTOFMEMORY;
+                        TRACE(reg, "Returning OUTOFMEMORY\n");
+			return ERROR_OUTOFMEMORY;
 		}
 		memset(*lplpPrevKey,'\0',sizeof(KEYSTRUCT));
+                TRACE(reg,"Adding %s\n", debugstr_w(wps[i]));
 		(*lplpPrevKey)->keyname	= strdupW(wps[i]);
 		(*lplpPrevKey)->next	= NULL;
 		(*lplpPrevKey)->nextsub	= NULL;
@@ -1735,100 +1906,78 @@
 	else
 		lpNextKey->class = NULL;
 	*retkey		= currenthandle;
+        TRACE(reg, "Returning %x\n", currenthandle);
 	if (lpDispos)
 		*lpDispos	= REG_CREATED_NEW_KEY;
 	FREE_KEY_PATH;
-	return SHELL_ERROR_SUCCESS;
+	return ERROR_SUCCESS;
 }
 
-/* RegCreateKeyW		[ADVAPI32.132] */
-DWORD WINAPI RegCreateKey32W(
-	HKEY	hkey,
-	LPCWSTR	lpszSubKey,
-	LPHKEY	retkey
-) {
-	DWORD	junk,ret;
 
-	TRACE(reg,"(%lx,%s,%p)\n",
-		(LONG)hkey,W2C(lpszSubKey,0),retkey
-	);
-	ret=RegCreateKeyEx32W(
-		hkey,		/* key handle */
-		lpszSubKey,	/* subkey name */
-		0,		/* reserved = 0 */
-		NULL,		/* lpszClass? FIXME: ? */
-		REG_OPTION_NON_VOLATILE,	/* options */
-		KEY_ALL_ACCESS,	/* desired access attribs */
-		NULL,		/* lpsecurity attributes */
-		retkey,		/* lpretkey */
-		&junk		/* disposition value */
-	);
-	return	ret;
+/******************************************************************************
+ * RegCreateKey32W [ADVAPI32.132]
+ */
+DWORD WINAPI RegCreateKey32W( HKEY hkey, LPCWSTR lpszSubKey, LPHKEY retkey )
+{
+    DWORD junk;
+
+    TRACE(reg,"(%x,%s,%p)\n", hkey,debugstr_w(lpszSubKey),retkey);
+    return RegCreateKeyEx32W( hkey, lpszSubKey, 0, NULL, 
+                              REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,NULL,
+                              retkey, &junk);
 }
 
-/* RegCreateKeyExA		[ADVAPI32.130] */
-DWORD WINAPI RegCreateKeyEx32A(
-	HKEY	hkey,
-	LPCSTR	lpszSubKey,
-	DWORD	dwReserved,
-	LPSTR	lpszClass,
-	DWORD	fdwOptions,
-	REGSAM	samDesired,
-	LPSECURITY_ATTRIBUTES lpSecAttribs,
-	LPHKEY	retkey,
-	LPDWORD	lpDispos
-) {
-	LPWSTR	lpszSubKeyW,lpszClassW;
-	DWORD	ret;
 
-	TRACE(reg,"(%lx,%s,%ld,%s,%lx,%lx,%p,%p,%p)\n",
-		(LONG)hkey,
-		lpszSubKey,
-		dwReserved,
-		lpszClass,
-		fdwOptions,
-		samDesired,
-		lpSecAttribs,
-		retkey,
-		lpDispos
-	);
+/******************************************************************************
+ * RegCreateKeyEx32A [ADVAPI32.130]
+ */
+DWORD WINAPI RegCreateKeyEx32A( HKEY hkey, LPCSTR lpszSubKey, DWORD dwReserved,
+                                LPSTR lpszClass, DWORD fdwOptions, 
+                                REGSAM samDesired, 
+                                LPSECURITY_ATTRIBUTES lpSecAttribs, 
+                                LPHKEY retkey, LPDWORD lpDispos )
+{
+    LPWSTR lpszSubKeyW, lpszClassW;
+    DWORD  ret;
+
+    TRACE(reg,"(%x,%s,%ld,%s,%lx,%lx,%p,%p,%p)\n",hkey,debugstr_a(lpszSubKey),
+          dwReserved,debugstr_a(lpszClass),fdwOptions,samDesired,lpSecAttribs,
+          retkey,lpDispos);
+
+    lpszSubKeyW = HEAP_strdupAtoW(GetProcessHeap(),0,lpszSubKey);
+/*
 	if (lpszSubKey)
 		lpszSubKeyW=strdupA2W(lpszSubKey);
 	else
 		lpszSubKeyW=NULL;
+*/
 	if (lpszClass)
 		lpszClassW=strdupA2W(lpszClass);
 	else
 		lpszClassW=NULL;
-	ret=RegCreateKeyEx32W(
-		hkey,
-		lpszSubKeyW,
-		dwReserved,
-		lpszClassW,
-		fdwOptions,
-		samDesired,
-		lpSecAttribs,
-		retkey,
-		lpDispos
-	);
+    ret = RegCreateKeyEx32W( hkey, lpszSubKeyW, dwReserved, lpszClassW, 
+                             fdwOptions, samDesired, lpSecAttribs, retkey, 
+                             lpDispos );
+    HeapFree(GetProcessHeap(),0,lpszSubKeyW);
+/*
 	if (lpszSubKeyW)
 		free(lpszSubKeyW);
+*/
 	if (lpszClassW)
 		free(lpszClassW);
-	return ret;
+    return ret;
 }
 
-/* RegCreateKeyA		[ADVAPI32.129] */
-DWORD WINAPI RegCreateKey32A(
-	HKEY	hkey,
-	LPCSTR	lpszSubKey,
-	LPHKEY	retkey
-) {
-	DWORD	junk;
 
-	TRACE(reg,"(%lx,%s,%p)\n",
-		(LONG)hkey,lpszSubKey,retkey
-	);
+/******************************************************************************
+ * RegCreateKey32A [ADVAPI32.129]
+ */
+DWORD WINAPI RegCreateKey32A( HKEY hkey, LPCSTR lpszSubKey, LPHKEY retkey )
+{
+    DWORD junk;
+
+    TRACE(reg,"(%x,%s,%p)\n",hkey,debugstr_a(lpszSubKey),retkey);
+
 	return	RegCreateKeyEx32A(
 		hkey,		/* key handle */
 		lpszSubKey,	/* subkey name */
@@ -1842,18 +1991,17 @@
 	);
 }
 
-/* RegCreateKey			[SHELL.2] [KERNEL.218] */
-DWORD WINAPI RegCreateKey16(
-	HKEY	hkey,
-	LPCSTR	lpszSubKey,
-	LPHKEY	retkey
-) {
-	TRACE(reg,"(%lx,%s,%p)\n",
-		(LONG)hkey,lpszSubKey,retkey
-	);
-	return RegCreateKey32A(hkey,lpszSubKey,retkey);
+
+/******************************************************************************
+ * RegCreateKey16 [SHELL.2] [KERNEL.218]
+ */
+DWORD WINAPI RegCreateKey16( HKEY hkey, LPCSTR lpszSubKey, LPHKEY retkey )
+{
+    TRACE(reg,"(%x,%s,%p)\n",hkey,debugstr_a(lpszSubKey),retkey);
+    return RegCreateKey32A( hkey, lpszSubKey, retkey );
 }
 
+
 /* 
  * Query Value Functions
  * Win32 differs between keynames and valuenames. 
@@ -1866,81 +2014,140 @@
  *                                          RegQueryValue32W -> RegQueryValueEx32W
  */
 
-/* RegQueryValueExW		[ADVAPI32.158] */
-DWORD WINAPI RegQueryValueEx32W(
-	HKEY	hkey,
-	LPWSTR	lpszValueName,
-	LPDWORD	lpdwReserved,
-	LPDWORD	lpdwType,
-	LPBYTE	lpbData,
-	LPDWORD	lpcbData
-) {
+
+/******************************************************************************
+ * RegQueryValueEx32W [ADVAPI32.158]
+ * Retrieves type and data for a specified name associated with an open key
+ *
+ * PARAMS
+ *    hkey          [I]   Handle of key to query
+ *    lpValueName   [I]   Name of value to query
+ *    lpdwReserved  [I]   Reserved - must be NULL
+ *    lpdwType      [O]   Address of buffer for value type.  If NULL, the type
+ *                        is not required.
+ *    lpbData       [O]   Address of data buffer.  If NULL, the actual data is
+ *                        not required.
+ *    lpcbData      [I/O] Address of data buffer size
+ *
+ * RETURNS 
+ *    ERROR_SUCCESS:   Success
+ *    ERROR_MORE_DATA: The specified buffer is not big enough to hold the data
+ */
+DWORD WINAPI RegQueryValueEx32W( HKEY hkey, LPWSTR lpValueName,
+                                 LPDWORD lpdwReserved, LPDWORD lpdwType,
+                                 LPBYTE lpbData, LPDWORD lpcbData )
+{
 	LPKEYSTRUCT	lpkey;
 	int		i;
 
-	TRACE(reg,"(%x,%s,%p,%p,%p,%ld)\n",
-		     hkey,W2C(lpszValueName,0),lpdwReserved,lpdwType,lpbData,
-		     lpcbData?*lpcbData:0);
+    TRACE(reg,"(%x,%s,%p,%p,%p,%ld)\n", hkey, debugstr_w(lpValueName),
+          lpdwReserved, lpdwType, lpbData, lpcbData?*lpcbData:0);
 
-	lpkey	= lookup_hkey(hkey);
-	if (!lpkey)
-		return SHELL_ERROR_BADKEY;
-	if (lpszValueName && !*lpszValueName)
-		lpszValueName = NULL;
-	if (lpszValueName==NULL) {
+    lpkey = lookup_hkey(hkey);
+    if (!lpkey) {
+        TRACE(reg, "Invalid handle(%x)\n",hkey);
+        return ERROR_INVALID_HANDLE;
+    }
+
+    /* An empty name string is equivalent to NULL */
+    if (lpValueName && !*lpValueName)
+        lpValueName = NULL;
+
+	if (lpValueName==NULL) {
+                /* Use key's unnamed or default value, if any */
 		for (i=0;i<lpkey->nrofvalues;i++)
 			if (lpkey->values[i].name==NULL)
 				break;
 	} else {
+                /* Search for the key name */
 		for (i=0;i<lpkey->nrofvalues;i++)
 			if (	lpkey->values[i].name &&
-				!lstrcmpi32W(lpszValueName,lpkey->values[i].name)
+				!lstrcmpi32W(lpValueName,lpkey->values[i].name)
 			)
 				break;
 	}
+
 	if (i==lpkey->nrofvalues) {
-		if (lpszValueName==NULL) {
+                TRACE(reg,"Key not found\n");
+		if (lpValueName==NULL) {
+                        /* Empty keyname not found */
 			if (lpbData) {
 				*(WCHAR*)lpbData = 0;
 				*lpcbData	= 2;
 			}
 			if (lpdwType)
 				*lpdwType	= REG_SZ;
-			return SHELL_ERROR_SUCCESS;
+                        TRACE(reg, "Returning an empty string\n");
+			return ERROR_SUCCESS;
 		}
-		return SHELL_ERROR_BADKEY;/*FIXME: correct return? */
+		return ERROR_BADKEY; /* FIXME */
 	}
-	if (lpdwType)
-		*lpdwType	= lpkey->values[i].type;
-	if (lpbData==NULL) {
-		if (lpcbData==NULL)
-			return SHELL_ERROR_SUCCESS;
-		*lpcbData	= lpkey->values[i].len;
-		return SHELL_ERROR_SUCCESS;
-	}
-	if (*lpcbData<lpkey->values[i].len) {
-		*(WCHAR*)lpbData= 0;
-		*lpcbData	= lpkey->values[i].len;
-		return ERROR_MORE_DATA;
-	}
-	memcpy(lpbData,lpkey->values[i].data,lpkey->values[i].len);
-	*lpcbData	= lpkey->values[i].len;
-	return SHELL_ERROR_SUCCESS;
+
+    if (lpdwType)
+        *lpdwType = lpkey->values[i].type;
+
+    if (lpbData==NULL) {
+        /* Data is not required */
+        if (lpcbData==NULL) {
+            /* And data size is not required */
+            /* So all that is returned is the type (set above) */
+            return ERROR_SUCCESS;
+        }
+        /* Set the size required and return success */
+        *lpcbData = lpkey->values[i].len;
+        return ERROR_SUCCESS;
+    }
+
+    if (*lpcbData<lpkey->values[i].len) {
+        /* The size was specified, but the data is too big for it */
+        /* Instead of setting it to NULL, fill in with as much as possible */
+        /* But the docs do not specify how to handle the lpbData here */
+        /* *(WCHAR*)lpbData= 0; */
+        memcpy(lpbData,lpkey->values[i].data,*lpcbData);
+        *lpcbData = lpkey->values[i].len;
+        return ERROR_MORE_DATA;
+    }
+
+    memcpy(lpbData,lpkey->values[i].data,lpkey->values[i].len);
+
+    /* Extra debugging output */
+    if (lpdwType) {
+        switch(*lpdwType){
+            case REG_SZ:
+                TRACE(reg," Data(sz)=%s\n",debugstr_w((LPCWSTR)lpbData));
+                break;
+            case REG_DWORD:
+                TRACE(reg," Data(dword)=%lx\n", (DWORD)*lpbData);
+                break;
+            case REG_BINARY:
+                TRACE(reg," Data(binary)\n");
+                /* Is there a way of printing this in readable form? */
+                break;
+            default:
+                TRACE(reg, "Unknown data type %ld\n", *lpdwType);
+        } /* switch */
+    } /* if */
+
+    /* Set the actual size */
+    *lpcbData = lpkey->values[i].len;
+    return ERROR_SUCCESS;
 }
 
-/* RegQueryValueW		[ADVAPI32.159] */
-DWORD WINAPI RegQueryValue32W(
-	HKEY	hkey,
-	LPWSTR	lpszSubKey,
-	LPWSTR	lpszData,
-	LPDWORD	lpcbData
-) {
+
+/******************************************************************************
+ * RegQueryValue32W [ADVAPI32.159]
+ *
+ * NOTES
+ *    Why is this calling RegOpenKey32W?
+ */
+DWORD WINAPI RegQueryValue32W( HKEY hkey, LPWSTR lpszSubKey, LPWSTR lpszData,
+                               LPDWORD lpcbData )
+{
 	HKEY	xhkey;
 	DWORD	ret,lpdwType;
 
-	TRACE(reg,"(%x,%s,%p,%ld)\n",
-		     hkey,W2C(lpszSubKey,0),lpszData,
-		     lpcbData?*lpcbData:0);
+    TRACE(reg,"(%x,%s,%p,%ld)\n",hkey,debugstr_w(lpszSubKey),lpszData,
+          lpcbData?*lpcbData:0);
 
 	/* only open subkey, if we really do descend */
 	if (lpszSubKey && *lpszSubKey) {
@@ -1964,37 +2171,38 @@
 	return ret;
 }
 
-/* RegQueryValueExA		[ADVAPI32.157] */
-DWORD WINAPI RegQueryValueEx32A(
-	HKEY	hkey,
-	LPSTR	lpszValueName,
-	LPDWORD	lpdwReserved,
-	LPDWORD	lpdwType,
-	LPBYTE	lpbData,
-	LPDWORD	lpcbData
-) {
+
+/******************************************************************************
+ * RegQueryValueEx32A [ADVAPI32.157]
+ *
+ * Can this use HEAP_strdupAtoW?
+ */
+DWORD WINAPI RegQueryValueEx32A( HKEY hkey, LPSTR lpszValueName,
+                                 LPDWORD lpdwReserved, LPDWORD lpdwType,
+                                 LPBYTE lpbData, LPDWORD lpcbData )
+{
 	LPWSTR	lpszValueNameW;
 	LPBYTE	buf;
 	DWORD	ret,myxlen;
 	DWORD	*mylen;
 	DWORD	type;
 
-	TRACE(reg,"(%x,%s,%p,%p,%p,%ld)\n",
-		     hkey,lpszValueName,lpdwReserved,lpdwType,lpbData,
-		     lpcbData?*lpcbData:0);
+    TRACE(reg,"(%x,%s,%p,%p,%p,%ld)\n", hkey,debugstr_a(lpszValueName),
+          lpdwReserved,lpdwType,lpbData,lpcbData?*lpcbData:0);
 
-	if (lpszValueName)
-		lpszValueNameW=strdupA2W(lpszValueName);
-	else 
-		lpszValueNameW=NULL;
+    if (lpszValueName)
+        lpszValueNameW=strdupA2W(lpszValueName);
+    else 
+        lpszValueNameW=NULL;
 
-	if (lpdwType)
-		type=*lpdwType;
+    if (lpdwType)
+        type=*lpdwType;
 
 	if (lpbData) {
 		myxlen  = 0;
 		mylen	= &myxlen;
 		buf	= xmalloc(4);
+                /* Only get the size for now */
 		ret=RegQueryValueEx32W(
 			hkey,
 			lpszValueNameW,
@@ -2018,6 +2226,7 @@
 		} else
 			mylen	= NULL;
 	}
+        /* Now get the data */
 	ret=RegQueryValueEx32W(
 		hkey,
 		lpszValueNameW,
@@ -2028,6 +2237,7 @@
 	);
 	if (lpdwType) 
 		*lpdwType=type;
+
 	if (ret==ERROR_SUCCESS) {
 		if (buf) {
 			if (UNICONVMASK & (1<<(type))) {
@@ -2052,33 +2262,31 @@
 	}
 	if (buf)
 		free(buf);
-	return ret;
+
+    return ret;
 }
 
-/* RegQueryValueEx		[KERNEL.225] */
-DWORD WINAPI RegQueryValueEx16(
-	HKEY	hkey,
-	LPSTR	lpszValueName,
-	LPDWORD	lpdwReserved,
-	LPDWORD	lpdwType,
-	LPBYTE	lpbData,
-	LPDWORD	lpcbData
-) {
-	TRACE(reg,"(%x,%s,%p,%p,%p,%ld)\n",
-		     hkey,lpszValueName,lpdwReserved,lpdwType,lpbData,
-		     lpcbData?*lpcbData:0);
 
-	return RegQueryValueEx32A(
-		hkey,
-		lpszValueName,
-		lpdwReserved,
-		lpdwType,
-		lpbData,
-		lpcbData
-	);
+/******************************************************************************
+ * RegQueryValueEx16 [KERNEL.225]
+ */
+DWORD WINAPI RegQueryValueEx16( HKEY hkey, LPSTR lpszValueName,
+                                LPDWORD lpdwReserved, LPDWORD lpdwType,
+                                LPBYTE lpbData, LPDWORD lpcbData )
+{
+    TRACE(reg,"(%x,%s,%p,%p,%p,%ld)\n",hkey,debugstr_a(lpszValueName),
+          lpdwReserved,lpdwType,lpbData,lpcbData?*lpcbData:0);
+    return RegQueryValueEx32A( hkey, lpszValueName, lpdwReserved, lpdwType,
+                               lpbData, lpcbData );
 }
 
-/* RegQueryValueA		[ADVAPI32.156] */
+
+/******************************************************************************
+ * RegQueryValue32A [ADVAPI32.156]
+ *
+ * NOTES
+ *    Why is this calling RegOpenKey16?
+ */
 DWORD WINAPI RegQueryValue32A(
 	HKEY	hkey,
 	LPSTR	lpszSubKey,
@@ -2088,13 +2296,12 @@
 	HKEY	xhkey;
 	DWORD	ret,lpdwType;
 
-	TRACE(reg,"(%x,%s,%p,%ld)\n",
-		     hkey,lpszSubKey,lpszData,
-		     lpcbData?*lpcbData:0);
+    TRACE(reg,"(%x,%s,%p,%ld)\n",hkey,debugstr_a(lpszSubKey),lpszData,
+          lpcbData?*lpcbData:0);
 
 	/* only open subkey, if we really do descend */
 	if (lpszSubKey && *lpszSubKey) {
-		ret	= RegOpenKey16(hkey,lpszSubKey,&xhkey);
+		ret = RegOpenKey16(hkey,lpszSubKey,&xhkey);
 		if (ret!=ERROR_SUCCESS)
 			return ret;
 	} else
@@ -2114,25 +2321,30 @@
 	return ret;
 }
 
-/* RegQueryValue		[SHELL.6] [KERNEL.224] */
-DWORD WINAPI RegQueryValue16(
-	HKEY	hkey,
-	LPSTR	lpszSubKey,
-	LPSTR	lpszData,
-	LPDWORD	lpcbData
-) {
-	TRACE(reg,"(%x,%s,%p,%ld)\n",
-		     hkey,lpszSubKey,lpszData,lpcbData?*lpcbData:0);
 
-	/* HACK: the 16bit RegQueryValue doesn't handle selectorblocks
-	 *       anyway, so we just mask out the high 16 bit.
-	 *       (this (not so much incidently;) hopefully fixes Aldus FH4)
-	 */
-	if (lpcbData)
-		*lpcbData &= 0xFFFF;
-	return RegQueryValue32A(hkey,lpszSubKey,lpszData,lpcbData);
+/******************************************************************************
+ * RegQueryValue16 [SHELL.6] [KERNEL.224]
+ *
+ * NOTES
+ *    Is this HACK still applicable?
+ *
+ * HACK
+ *    The 16bit RegQueryValue doesn't handle selectorblocks anyway, so we just
+ *    mask out the high 16 bit.  This (not so much incidently) hopefully fixes
+ *    Aldus FH4)
+ */
+DWORD WINAPI RegQueryValue16( HKEY hkey, LPSTR lpszSubKey, LPSTR lpszData,
+                              LPDWORD lpcbData )
+{
+    TRACE(reg,"(%x,%s,%p,%ld)\n",hkey,debugstr_a(lpszSubKey),lpszData,
+          lpcbData?*lpcbData:0);
+
+    if (lpcbData)
+        *lpcbData &= 0xFFFF;
+    return RegQueryValue32A(hkey,lpszSubKey,lpszData,lpcbData);
 }
 
+
 /*
  * Setting values of Registry keys
  *
@@ -2141,29 +2353,57 @@
  *                                    RegSetValue32W   -> RegSetValueEx32W
  */
 
-/* RegSetValueExW		[ADVAPI32.170] */
-DWORD WINAPI RegSetValueEx32W(
-	HKEY	hkey,
-	LPWSTR	lpszValueName,
-	DWORD	dwReserved,
-	DWORD	dwType,
-	LPBYTE	lpbData,
-	DWORD	cbData
-) {
-	LPKEYSTRUCT	lpkey;
-	int		i;
 
-	TRACE(reg,"(%x,%s,%ld,%ld,%p,%ld)\n",
-		hkey,W2C(lpszValueName,0),dwReserved,dwType,lpbData,cbData
-	);
-	/* we no longer care about the lpbData type here... */
-	lpkey	= lookup_hkey(hkey);
-	if (!lpkey)
-		return SHELL_ERROR_BADKEY;
+/******************************************************************************
+ * RegSetValueEx32W [ADVAPI32.170]
+ * Sets the data and type of a value under a register key
+ *
+ * PARAMS
+ *    hkey          [I] Handle of key to set value for
+ *    lpszValueName [I] Name of value to set
+ *    dwReserved    [I] Reserved - must be zero
+ *    dwType        [I] Flag for value type
+ *    lpbData       [I] Address of value data
+ *    cbData        [I] Size of value data
+ *
+ * RETURNS
+ *    Success: ERROR_SUCCESS
+ *    Failure: Error code
+ */
+DWORD WINAPI RegSetValueEx32W( HKEY hkey, LPWSTR lpszValueName, 
+                               DWORD dwReserved, DWORD dwType, LPBYTE lpbData,
+                               DWORD cbData)
+{
+    LPKEYSTRUCT lpkey;
+    int i;
+
+    TRACE(reg,"(%x,%s,%ld,%ld,%p,%ld)\n", hkey, debugstr_w(lpszValueName),
+          dwReserved, dwType, lpbData, cbData);
+
+    switch (dwType) {
+        case REG_SZ:
+            TRACE(reg," Data(sz)=%s\n", debugstr_w((LPCWSTR)lpbData));
+            break;
+        case REG_BINARY:
+            TRACE(reg," Data(binary)\n");
+            break;
+        case REG_DWORD:
+            TRACE(reg," Data(dword)=%lx\n", (DWORD)*lpbData);
+            break;
+        default:
+            TRACE(reg,"Unknown type: %ld\n", dwType);
+    }
+
+	lpkey = lookup_hkey(hkey);
+	if (!lpkey) {
+            WARN(reg,"Returning badkey\n");
+            return ERROR_INVALID_HANDLE;
+        }
 
 	lpkey->flags |= REG_OPTION_TAINTED;
 
 	if (lpszValueName==NULL) {
+             /* Sets type and name for key's unnamed or default value */
 		for (i=0;i<lpkey->nrofvalues;i++)
 			if (lpkey->values[i].name==NULL)
 				break;
@@ -2194,25 +2434,27 @@
 	lpkey->values[i].data	= (LPBYTE)xmalloc(cbData);
 	lpkey->values[i].lastmodified = time(NULL);
 	memcpy(lpkey->values[i].data,lpbData,cbData);
-	return SHELL_ERROR_SUCCESS;
+	return ERROR_SUCCESS;
 }
 
-/* RegSetValueExA		[ADVAPI32.169] */
-DWORD WINAPI RegSetValueEx32A(
-	HKEY	hkey,
-	LPSTR	lpszValueName,
-	DWORD	dwReserved,
-	DWORD	dwType,
-	LPBYTE	lpbData,
-	DWORD	cbData
-) {
+
+/******************************************************************************
+ * RegSetValueEx32A [ADVAPI32.169]
+ *
+ * NOTES
+ *    Can this use the standard HEAP_strdupAtoW instead?
+ */
+DWORD WINAPI RegSetValueEx32A( HKEY hkey, LPSTR lpszValueName,
+                               DWORD dwReserved, DWORD dwType, LPBYTE lpbData,
+                               DWORD cbData )
+{
 	LPBYTE	buf;
 	LPWSTR	lpszValueNameW;
 	DWORD	ret;
 
-	TRACE(reg,"(%x,%s,%ld,%ld,%p,%ld)\n",
-		hkey,lpszValueName,dwReserved,dwType,lpbData,cbData
-	);
+    TRACE(reg,"(%x,%s,%ld,%ld,%p,%ld)\n",hkey,debugstr_a(lpszValueName),
+          dwReserved,dwType,lpbData,cbData);
+
 	if ((1<<dwType) & UNICONVMASK) {
 		buf=(LPBYTE)strdupA2W(lpbData);
 		cbData=2*strlen(lpbData)+2;
@@ -2230,22 +2472,23 @@
 	return ret;
 }
 
-/* RegSetValueEx		[KERNEL.226] */
-DWORD WINAPI RegSetValueEx16(
-	HKEY	hkey,
-	LPSTR	lpszValueName,
-	DWORD	dwReserved,
-	DWORD	dwType,
-	LPBYTE	lpbData,
-	DWORD	cbData
-) {
-	TRACE(reg,"(%x,%s,%ld,%ld,%p,%ld)\n",
-		hkey,lpszValueName,dwReserved,dwType,lpbData,cbData
-	);
-	return RegSetValueEx32A(hkey,lpszValueName,dwReserved,dwType,lpbData,cbData);
+
+/******************************************************************************
+ * RegSetValueEx16 [KERNEL.226]
+ */
+DWORD WINAPI RegSetValueEx16( HKEY hkey, LPSTR lpszValueName, DWORD dwReserved,
+                              DWORD dwType, LPBYTE lpbData, DWORD cbData )
+{
+    TRACE(reg,"(%x,%s,%ld,%ld,%p,%ld)\n",hkey,debugstr_a(lpszValueName),
+          dwReserved,dwType,lpbData,cbData);
+    return RegSetValueEx32A( hkey, lpszValueName, dwReserved, dwType, lpbData,
+                             cbData );
 }
 
-/* RegSetValueW			[ADVAPI32.171] */
+
+/******************************************************************************
+ * RegSetValue32W	[ADVAPI32.171]
+ */
 DWORD WINAPI RegSetValue32W(
 	HKEY	hkey,
 	LPCWSTR	lpszSubKey,
@@ -2279,9 +2522,15 @@
 	if (hkey!=xhkey)
 		RegCloseKey(xhkey);
 	return ret;
-
 }
-/* RegSetValueA			[ADVAPI32.168] */
+
+
+/******************************************************************************
+ * RegSetValue32A [ADVAPI32.168]
+ *
+ * NOTES
+ *    Why is this calling RegCreateKey16?
+ */
 DWORD WINAPI RegSetValue32A(
 	HKEY	hkey,
 	LPCSTR	lpszSubKey,
@@ -2314,22 +2563,19 @@
 	return ret;
 }
 
-/* RegSetValue			[KERNEL.221] [SHELL.5] */
-DWORD WINAPI RegSetValue16(
-	HKEY	hkey,
-	LPCSTR	lpszSubKey,
-	DWORD	dwType,
-	LPCSTR	lpszData,
-	DWORD	cbData
-) {
-	DWORD	ret;
-	TRACE(reg,"(%x,%s,%ld,%s,%ld)\n",
-		hkey,lpszSubKey,dwType,lpszData,cbData
-	);
-	ret=RegSetValue32A(hkey,lpszSubKey,dwType,lpszData,cbData);
-	return ret;
+
+/******************************************************************************
+ * RegSetValue16 [KERNEL.221] [SHELL.5]
+ */
+DWORD WINAPI RegSetValue16( HKEY hkey, LPCSTR lpszSubKey, DWORD	dwType,
+                            LPCSTR lpszData, DWORD cbData )
+{
+    TRACE(reg,"(%x,%s,%ld,%s,%ld)\n",hkey,debugstr_a(lpszSubKey),dwType,
+          debugstr_a(lpszData),cbData);
+    return RegSetValue32A(hkey,lpszSubKey,dwType,lpszData,cbData);
 }
 
+
 /* 
  * Key Enumeration
  *
@@ -2338,25 +2584,24 @@
  *                              RegEnumKey32W   -> RegEnumKeyEx32W
  */
 
-/* RegEnumKeyExW		[ADVAPI32.139] */
-DWORD WINAPI RegEnumKeyEx32W(
-	HKEY	hkey,
-	DWORD	iSubkey,
-	LPWSTR	lpszName,
-	LPDWORD	lpcchName,
-	LPDWORD	lpdwReserved,
-	LPWSTR	lpszClass,
-	LPDWORD	lpcchClass,
-	FILETIME	*ft
-) {
+
+/******************************************************************************
+ * RegEnumKeyEx32W [ADVAPI32.139]
+ */
+DWORD WINAPI RegEnumKeyEx32W( HKEY hkey, DWORD iSubkey, LPWSTR lpszName,
+                              LPDWORD lpcchName, LPDWORD lpdwReserved,
+                              LPWSTR lpszClass, LPDWORD lpcchClass, 
+                              FILETIME *ft )
+{
 	LPKEYSTRUCT	lpkey,lpxkey;
 
-	TRACE(reg,"(%x,%ld,%p,%ld,%p,%p,%p,%p)\n",
-		hkey,iSubkey,lpszName,*lpcchName,lpdwReserved,lpszClass,lpcchClass,ft
-	);
-	lpkey=lookup_hkey(hkey);
-	if (!lpkey)
-		return SHELL_ERROR_BADKEY;
+    TRACE(reg,"(%x,%ld,%p,%ld,%p,%p,%p,%p)\n",hkey,iSubkey,lpszName,
+          *lpcchName,lpdwReserved,lpszClass,lpcchClass,ft);
+
+    lpkey = lookup_hkey(hkey);
+    if (!lpkey)
+        return ERROR_INVALID_HANDLE;
+
 	if (!lpkey->nextsub)
 		return ERROR_NO_MORE_ITEMS;
 	lpxkey=lpkey->nextsub;
@@ -2375,23 +2620,22 @@
 		*lpcchClass	= 2;
 	}
 	return ERROR_SUCCESS;
-
 }
 
-/* RegEnumKeyW			[ADVAPI32.140] */
-DWORD WINAPI RegEnumKey32W(
-	HKEY	hkey,
-	DWORD	iSubkey,
-	LPWSTR	lpszName,
-	DWORD	lpcchName
-) {
-	FILETIME	ft;
 
-	TRACE(reg,"(%x,%ld,%p,%ld)\n",
-		hkey,iSubkey,lpszName,lpcchName
-	);
-	return RegEnumKeyEx32W(hkey,iSubkey,lpszName,&lpcchName,NULL,NULL,NULL,&ft);
+/******************************************************************************
+ * RegEnumKey32W [ADVAPI32.140]
+ */
+DWORD WINAPI RegEnumKey32W( HKEY hkey, DWORD iSubkey, LPWSTR lpszName, 
+                            DWORD lpcchName )
+{
+    FILETIME	ft;
+
+    TRACE(reg,"(%x,%ld,%p,%ld)\n",hkey,iSubkey,lpszName,lpcchName);
+    return RegEnumKeyEx32W(hkey,iSubkey,lpszName,&lpcchName,NULL,NULL,NULL,&ft);
 }
+
+
 /* RegEnumKeyExA		[ADVAPI32.138] */
 DWORD WINAPI RegEnumKeyEx32A(
 	HKEY	hkey,
@@ -2449,43 +2693,32 @@
 	return ret;
 }
 
-/* RegEnumKeyA			[ADVAPI32.137] */
-DWORD WINAPI RegEnumKey32A(
-	HKEY	hkey,
-	DWORD	iSubkey,
-	LPSTR	lpszName,
-	DWORD	lpcchName
-) {
-	FILETIME	ft;
 
-	TRACE(reg,"(%x,%ld,%p,%ld)\n",
-		hkey,iSubkey,lpszName,lpcchName
-	);
-	return	RegEnumKeyEx32A(
-		hkey,
-		iSubkey,
-		lpszName,
-		&lpcchName,
-		NULL,
-		NULL,
-		NULL,
-		&ft
-	);
+/******************************************************************************
+ * RegEnumKey32A [ADVAPI32.137]
+ */
+DWORD WINAPI RegEnumKey32A( HKEY hkey, DWORD iSubkey, LPSTR lpszName,
+                            DWORD lpcchName )
+{
+    FILETIME	ft;
+
+    TRACE(reg,"(%x,%ld,%p,%ld)\n",hkey,iSubkey,lpszName,lpcchName);
+    return RegEnumKeyEx32A( hkey, iSubkey, lpszName, &lpcchName, NULL, NULL, 
+                            NULL, &ft );
 }
 
-/* RegEnumKey			[SHELL.7] [KERNEL.216] */
-DWORD WINAPI RegEnumKey16(
-	HKEY	hkey,
-	DWORD	iSubkey,
-	LPSTR	lpszName,
-	DWORD	lpcchName
-) {
-	TRACE(reg,"(%x,%ld,%p,%ld)\n",
-		hkey,iSubkey,lpszName,lpcchName
-	);
-	return RegEnumKey32A(hkey,iSubkey,lpszName,lpcchName);
+
+/******************************************************************************
+ * RegEnumKey16 [SHELL.7] [KERNEL.216]
+ */
+DWORD WINAPI RegEnumKey16( HKEY hkey, DWORD iSubkey, LPSTR lpszName,
+                           DWORD lpcchName )
+{
+    TRACE(reg,"(%x,%ld,%p,%ld)\n",hkey,iSubkey,lpszName,lpcchName);
+    return RegEnumKey32A( hkey, iSubkey, lpszName, lpcchName);
 }
 
+
 /* 
  * Enumerate Registry Values
  *
@@ -2493,11 +2726,14 @@
  * RegEnumValue16 -> RegEnumValue32A -> RegEnumValue32W
  */
 
-/* RegEnumValueW		[ADVAPI32.142] */
+
+/******************************************************************************
+ * RegEnumValue32W [ADVAPI32.142]
+ */
 DWORD WINAPI RegEnumValue32W(
-	HKEY	hkey,
-	DWORD	iValue,
-	LPWSTR	lpszValue,
+	HKEY hkey,
+	DWORD iValue,
+	LPWSTR lpszValue,
 	LPDWORD	lpcchValue,
 	LPDWORD	lpdReserved,
 	LPDWORD	lpdwType,
@@ -2512,7 +2748,8 @@
 	);
 	lpkey = lookup_hkey(hkey);
 	if (!lpkey)
-		return SHELL_ERROR_BADKEY;
+		return ERROR_INVALID_HANDLE;
+
 	if (lpkey->nrofvalues<=iValue)
 		return ERROR_NO_MORE_ITEMS;
 	val	= lpkey->values+iValue;
@@ -2536,9 +2773,10 @@
 		memcpy(lpbData,val->data,val->len);
 		*lpcbData = val->len;
 	}
-	return SHELL_ERROR_SUCCESS;
+	return ERROR_SUCCESS;
 }
 
+
 /* RegEnumValueA		[ADVAPI32.141] */
 DWORD WINAPI RegEnumValue32A(
 	HKEY	hkey,
@@ -2596,65 +2834,77 @@
 	return ret;
 }
 
-/* RegEnumValue			[KERNEL.223] */
-DWORD WINAPI RegEnumValue16(
-	HKEY	hkey,
-	DWORD	iValue,
-	LPSTR	lpszValue,
-	LPDWORD	lpcchValue,
-	LPDWORD	lpdReserved,
-	LPDWORD	lpdwType,
-	LPBYTE	lpbData,
-	LPDWORD	lpcbData
-) {
-	TRACE(reg,"(%x,%ld,%p,%p,%p,%p,%p,%p)\n",
-		hkey,iValue,lpszValue,lpcchValue,lpdReserved,lpdwType,lpbData,lpcbData
-	);
-	return RegEnumValue32A(
-		hkey,
-		iValue,
-		lpszValue,
-		lpcchValue,
-		lpdReserved,
-		lpdwType,
-		lpbData,
-		lpcbData
-	);
+
+/******************************************************************************
+ * RegEnumValue16 [KERNEL.223]
+ */
+DWORD WINAPI RegEnumValue16( HKEY hkey, DWORD iValue, LPSTR lpszValue, 
+                             LPDWORD lpcchValue, LPDWORD lpdReserved, 
+                             LPDWORD lpdwType, LPBYTE lpbData, 
+                             LPDWORD lpcbData )
+{
+    TRACE(reg,"(%x,%ld,%p,%p,%p,%p,%p,%p)\n",hkey,iValue,lpszValue,lpcchValue,
+          lpdReserved,lpdwType,lpbData,lpcbData);
+    return RegEnumValue32A( hkey, iValue, lpszValue, lpcchValue, lpdReserved, 
+                            lpdwType, lpbData, lpcbData );
 }
 
-/* 
- *  Close registry key
+
+/******************************************************************************
+ * RegCloseKey [SHELL.3] [KERNEL.220] [ADVAPI32.126]
+ * Releases the handle of the specified key
+ *
+ * PARAMS
+ *    hkey [I] Handle of key to close
+ *
+ * RETURNS
+ *    Success: ERROR_SUCCESS
+ *    Failure: Error code
  */
-/* RegCloseKey			[SHELL.3] [KERNEL.220] [ADVAPI32.126] */
-DWORD WINAPI RegCloseKey(HKEY hkey) {
-	TRACE(reg,"(%x)\n",hkey);
-	remove_handle(hkey);
-	return ERROR_SUCCESS;
+DWORD WINAPI RegCloseKey( HKEY hkey )
+{
+    TRACE(reg,"(%x)\n",hkey);
+    return remove_handle(hkey);
 }
+
+
 /* 
  * Delete registry key
  *
  * Callpath:
  * RegDeleteKey16 -> RegDeleteKey32A -> RegDeleteKey32W
  */
-/* RegDeleteKeyW		[ADVAPI32.134] */
-DWORD WINAPI RegDeleteKey32W(HKEY hkey,LPWSTR lpszSubKey) {
+
+
+/******************************************************************************
+ * RegDeleteKey32W [ADVAPI32.134]
+ *
+ * PARAMS
+ *    hkey       [I]
+ *    lpszSubKey [I]
+ *
+ * RETURNS
+ *    Success: ERROR_SUCCESS
+ *    Failure: Error code
+ */
+DWORD WINAPI RegDeleteKey32W( HKEY hkey, LPWSTR lpszSubKey )
+{
 	LPKEYSTRUCT	*lplpPrevKey,lpNextKey,lpxkey;
 	LPWSTR		*wps;
 	int		wpc,i;
 
-	TRACE(reg,"(%x,%s)\n",
-		hkey,W2C(lpszSubKey,0)
-	);
-	lpNextKey	= lookup_hkey(hkey);
-	if (!lpNextKey) {
-		TRACE(reg, "  Badkey[1].\n");
-		return SHELL_ERROR_BADKEY;
-	}
+    TRACE(reg,"(%x,%s)\n",hkey,debugstr_w(lpszSubKey));
+
+    lpNextKey = lookup_hkey(hkey);
+    if (!lpNextKey) {
+        TRACE(reg, "  Invalid handle.\n");
+        return ERROR_INVALID_HANDLE;
+    }
+
 	/* we need to know the previous key in the hier. */
 	if (!lpszSubKey || !*lpszSubKey) {
 		TRACE(reg, "  Badkey[2].\n");
-		return SHELL_ERROR_BADKEY;
+		return ERROR_BADKEY;
 	}
 	split_keypath(lpszSubKey,&wps,&wpc);
 	i 	= 0;
@@ -2672,7 +2922,7 @@
 			FREE_KEY_PATH;
 			TRACE(reg, "  Not found.\n");
 			/* not found is success */
-			return SHELL_ERROR_SUCCESS;
+			return ERROR_SUCCESS;
 		}
 		i++;
 		lpNextKey	= lpxkey;
@@ -2687,15 +2937,17 @@
 		lplpPrevKey	= &(lpxkey->next);
 		lpxkey		= lpxkey->next;
 	}
+
 	if (!lpxkey) {
 		FREE_KEY_PATH;
 		WARN(reg , "  Not found.\n");
-		return SHELL_ERROR_BADKEY;
+		return ERROR_FILE_NOT_FOUND;
 	}
+
 	if (lpxkey->nextsub) {
 		FREE_KEY_PATH;
 		WARN(reg , "  Not empty.\n");
-		return SHELL_ERROR_CANTWRITE;
+		return ERROR_CANTWRITE;
 	}
 	*lplpPrevKey	= lpxkey->next;
 	free(lpxkey->keyname);
@@ -2706,50 +2958,65 @@
 	free(lpxkey);
 	FREE_KEY_PATH;
 	TRACE(reg, "  Done.\n");
-	return	SHELL_ERROR_SUCCESS;
+	return	ERROR_SUCCESS;
 }
 
-/* RegDeleteKeyA		[ADVAPI32.133] */
-DWORD WINAPI RegDeleteKey32A(HKEY hkey,LPCSTR lpszSubKey) {
-	LPWSTR	lpszSubKeyW;
-	DWORD	ret;
 
-	TRACE(reg,"(%x,%s)\n",
-		hkey,lpszSubKey
-	);
-	lpszSubKeyW=HEAP_strdupAtoW(GetProcessHeap(),0,lpszSubKey);
-	ret=RegDeleteKey32W(hkey,lpszSubKeyW);
-	HeapFree(GetProcessHeap(),0,lpszSubKeyW);
-	return ret;
+/******************************************************************************
+ * RegDeleteKey32A [ADVAPI32.133]
+ */
+DWORD WINAPI RegDeleteKey32A( HKEY hkey, LPCSTR lpszSubKey )
+{
+    LPWSTR lpszSubKeyW;
+    DWORD  ret;
+
+    TRACE(reg,"(%x,%s)\n",hkey,lpszSubKey);
+    lpszSubKeyW = HEAP_strdupAtoW( GetProcessHeap(), 0, lpszSubKey );
+    ret = RegDeleteKey32W( hkey, lpszSubKeyW );
+    HeapFree( GetProcessHeap(), 0, lpszSubKeyW );
+    return ret;
 }
 
-/* RegDeleteKey			[SHELL.4] [KERNEL.219] */
-DWORD WINAPI RegDeleteKey16(HKEY hkey,LPCSTR lpszSubKey) {
-	TRACE(reg,"(%x,%s)\n",
-		hkey,lpszSubKey
-	);
-	return RegDeleteKey32A(hkey,lpszSubKey);
+
+/******************************************************************************
+ * RegDeleteKey16 [SHELL.4] [KERNEL.219]
+ */
+DWORD WINAPI RegDeleteKey16( HKEY hkey, LPCSTR lpszSubKey )
+{
+    TRACE(reg,"(%x,%s)\n",hkey,debugstr_a(lpszSubKey));
+    return RegDeleteKey32A( hkey, lpszSubKey );
 }
 
+
 /* 
  * Delete registry value
  *
  * Callpath:
  * RegDeleteValue16 -> RegDeleteValue32A -> RegDeleteValue32W
  */
-/* RegDeleteValueW		[ADVAPI32.136] */
-DWORD WINAPI RegDeleteValue32W(HKEY hkey,LPWSTR lpszValue)
+
+
+/******************************************************************************
+ * RegDeleteValue32W [ADVAPI32.136]
+ *
+ * PARAMS
+ *    hkey      [I]
+ *    lpszValue [I]
+ *
+ * RETURNS
+ */
+DWORD WINAPI RegDeleteValue32W( HKEY hkey, LPWSTR lpszValue )
 {
 	DWORD		i;
 	LPKEYSTRUCT	lpkey;
 	LPKEYVALUE	val;
 
-	TRACE(reg,"(%x,%s)\n",
-		hkey,W2C(lpszValue,0)
-	);
-	lpkey=lookup_hkey(hkey);
-	if (!lpkey)
-		return SHELL_ERROR_BADKEY;
+    TRACE(reg,"(%x,%s)\n",hkey,debugstr_w(lpszValue));
+
+    lpkey = lookup_hkey(hkey);
+    if (!lpkey)
+        return ERROR_INVALID_HANDLE;
+
 	if (lpszValue) {
 		for (i=0;i<lpkey->nrofvalues;i++)
 			if (	lpkey->values[i].name &&
@@ -2761,8 +3028,10 @@
 			if (lpkey->values[i].name==NULL)
 				break;
 	}
-	if (i==lpkey->nrofvalues)
-		return SHELL_ERROR_BADKEY;/*FIXME: correct errorcode? */
+
+    if (i == lpkey->nrofvalues)
+        return ERROR_FILE_NOT_FOUND;
+
 	val	= lpkey->values+i;
 	if (val->name) free(val->name);
 	if (val->data) free(val->data);
@@ -2776,27 +3045,33 @@
 				(lpkey->nrofvalues-1)*sizeof(KEYVALUE)
 			);
 	lpkey->nrofvalues--;
-	return SHELL_ERROR_SUCCESS;
+	return ERROR_SUCCESS;
 }
 
-/* RegDeleteValueA		[ADVAPI32.135] */
-DWORD WINAPI RegDeleteValue32A(HKEY hkey,LPSTR lpszValue)
-{
-	LPWSTR	lpszValueW;
-	DWORD	ret;
 
-	TRACE(reg, "(%x,%s)\n", hkey,lpszValue );
-        lpszValueW=HEAP_strdupAtoW(GetProcessHeap(),0,lpszValue);
-	ret=RegDeleteValue32W(hkey,lpszValueW);
-        HeapFree(GetProcessHeap(),0,lpszValueW);
-	return ret;
+/******************************************************************************
+ * RegDeleteValue32A [ADVAPI32.135]
+ */
+DWORD WINAPI RegDeleteValue32A( HKEY hkey, LPSTR lpszValue )
+{
+    LPWSTR lpszValueW;
+    DWORD  ret;
+
+    TRACE(reg, "(%x,%s)\n",hkey,debugstr_a(lpszValue));
+    lpszValueW=HEAP_strdupAtoW(GetProcessHeap(),0,lpszValue);
+    ret = RegDeleteValue32W( hkey, lpszValueW );
+    HeapFree(GetProcessHeap(),0,lpszValueW);
+    return ret;
 }
 
-/* RegDeleteValue		[KERNEL.222] */
-DWORD WINAPI RegDeleteValue16(HKEY hkey,LPSTR lpszValue)
+
+/******************************************************************************
+ * RegDeleteValue16 [KERNEL.222]
+ */
+DWORD WINAPI RegDeleteValue16( HKEY hkey, LPSTR lpszValue )
 {
-	TRACE(reg,"(%x,%s)\n", hkey,lpszValue );
-	return RegDeleteValue32A(hkey,lpszValue);
+    TRACE(reg,"(%x,%s)\n", hkey,debugstr_a(lpszValue));
+    return RegDeleteValue32A(hkey,lpszValue);
 }
 
 
@@ -2820,7 +3095,9 @@
 
 /* FIXME: lpcchXXXX ... is this counting in WCHARS or in BYTEs ?? */
 
-/* RegQueryInfoKeyW		[ADVAPI32.153] */
+/******************************************************************************
+ * RegQueryInfoKey32W [ADVAPI32.153]
+ */
 DWORD WINAPI RegQueryInfoKey32W(
 	HKEY	hkey,
 	LPWSTR	lpszClass,
@@ -2836,13 +3113,13 @@
 	FILETIME	*ft
 ) {
 	LPKEYSTRUCT	lpkey,lpxkey;
-	int		nrofkeys,maxsubkey,maxclass,maxvalues,maxvname,maxvdata;
+	int		nrofkeys,maxsubkey,maxclass,maxvname,maxvdata;
 	int		i;
 
 	TRACE(reg,"(%x,......)\n",hkey);
-	lpkey=lookup_hkey(hkey);
+	lpkey = lookup_hkey(hkey);
 	if (!lpkey)
-		return SHELL_ERROR_BADKEY;
+		return ERROR_INVALID_HANDLE;
 	if (lpszClass) {
 		if (lpkey->class) {
 			if (lstrlen32W(lpkey->class)*2+2>*lpcchClass) {
@@ -2860,42 +3137,41 @@
 			*lpcchClass	= lstrlen32W(lpkey->class)*2;
 	}
 	lpxkey=lpkey->nextsub;
-	nrofkeys=maxsubkey=maxclass=maxvalues=maxvname=maxvdata=0;
+	nrofkeys=maxsubkey=maxclass=maxvname=maxvdata=0;
 	while (lpxkey) {
 		nrofkeys++;
 		if (lstrlen32W(lpxkey->keyname)>maxsubkey)
 			maxsubkey=lstrlen32W(lpxkey->keyname);
 		if (lpxkey->class && lstrlen32W(lpxkey->class)>maxclass)
 			maxclass=lstrlen32W(lpxkey->class);
-		if (lpxkey->nrofvalues>maxvalues)
-			maxvalues=lpxkey->nrofvalues;
-		for (i=0;i<lpxkey->nrofvalues;i++) {
-			LPKEYVALUE	val=lpxkey->values+i;
-
-			if (val->name && lstrlen32W(val->name)>maxvname)
-				maxvname=lstrlen32W(val->name);
-			if (val->len>maxvdata)
-				maxvdata=val->len;
-		}
 		lpxkey=lpxkey->next;
 	}
+	for (i=0;i<lpkey->nrofvalues;i++) {
+		LPKEYVALUE	val=lpkey->values+i;
+
+		if (val->name && lstrlen32W(val->name)>maxvname)
+			maxvname=lstrlen32W(val->name);
+		if (val->len>maxvdata)
+			maxvdata=val->len;
+	}
 	if (!maxclass) maxclass	= 1;
 	if (!maxvname) maxvname	= 1;
+	if (lpcValues)
+		*lpcValues	= lpkey->nrofvalues;
 	if (lpcSubKeys)
 		*lpcSubKeys	= nrofkeys;
 	if (lpcchMaxSubkey)
 		*lpcchMaxSubkey	= maxsubkey*2;
 	if (lpcchMaxClass)
 		*lpcchMaxClass	= maxclass*2;
-	if (lpcValues)
-		*lpcValues	= maxvalues;
 	if (lpcchMaxValueName)
 		*lpcchMaxValueName= maxvname;
 	if (lpccbMaxValueData)
 		*lpccbMaxValueData= maxvdata;
-	return SHELL_ERROR_SUCCESS;
+	return ERROR_SUCCESS;
 }
 
+
 /* RegQueryInfoKeyA		[ADVAPI32.152] */
 DWORD WINAPI RegQueryInfoKey32A(
 	HKEY	hkey,
@@ -2949,11 +3225,28 @@
 		free(lpszClassW);
 	return ret;
 }
-/* RegConnectRegistryA		[ADVAPI32.127] */
-DWORD WINAPI RegConnectRegistry32A(LPCSTR machine,HKEY hkey,LPHKEY reskey)
+
+
+/******************************************************************************
+ * RegConnectRegistry32W [ADVAPI32.128]
+ */
+LONG WINAPI RegConnectRegistry32W( LPCWSTR machine, HKEY hkey, LPHKEY reskey )
 {
-	FIXME(reg,"(%s,%08x,%p):stub.\n",machine,hkey,reskey);
-	return ERROR_FILE_NOT_FOUND; /* FIXME */
+    FIXME(reg,"(%s,%x,%p): stub\n",debugstr_w(machine),hkey,reskey);
+    return ERROR_BAD_NETPATH; /* FIXME */
+}
+
+
+/******************************************************************************
+ * RegConnectRegistry32A [ADVAPI32.127]
+ */
+LONG WINAPI RegConnectRegistry32A( LPCSTR machine, HKEY hkey, LPHKEY reskey )
+{
+    DWORD ret;
+    LPWSTR machineW = HEAP_strdupAtoW(GetProcessHeap(),0,machine);
+    ret = RegConnectRegistry32W( machineW, hkey, reskey );
+    HeapFree(GetProcessHeap(),0,machineW);
+    return ret;
 }
 
 
@@ -2961,20 +3254,61 @@
  * RegGetKeySecurity [ADVAPI32.144]
  * Retrieves a copy of security descriptor protecting the registry key
  *
- * NOTES
- *    pSecurityDescriptor should be PSECURITY_DESCRIPTOR
- *
  * RETURNS
  *    Success: ERROR_SUCCESS
  *    Failure: Error code
  */
-LONG WINAPI RegGetKeySecurity( HKEY hKey, 
+LONG WINAPI RegGetKeySecurity( HKEY hkey, 
                                SECURITY_INFORMATION SecurityInformation,
-                               LPVOID pSecurityDescriptor,
+                               LPSECURITY_DESCRIPTOR pSecurityDescriptor,
                                LPDWORD lpcbSecurityDescriptor )
 {
-    FIXME(reg, "(%d,%ld,%p,%p): stub\n", hKey, SecurityInformation,
+    LPKEYSTRUCT	lpkey;
+    lpkey = lookup_hkey(hkey);
+    if (!lpkey)
+        return ERROR_INVALID_HANDLE;
+
+    FIXME(reg, "(%d,%ld,%p,%p): stub\n", hkey, SecurityInformation,
           pSecurityDescriptor, lpcbSecurityDescriptor);
     return ERROR_SUCCESS;
 }
 
+
+/******************************************************************************
+ * RegLoadKey32W [ADVAPI32.???]
+ */
+LONG WINAPI RegLoadKey32W( HKEY hkey, LPCWSTR lpszSubKey, LPCWSTR lpszFile )
+{
+    FIXME(reg,"(%x,%s,%s): stub\n",hkey,debugstr_w(lpszSubKey),
+          debugstr_w(lpszFile));
+    return ERROR_SUCCESS;
+}
+
+
+/******************************************************************************
+ * RegLoadKey32A [ADVAPI32.???]
+ */
+LONG WINAPI RegLoadKey32A( HKEY hkey, LPCSTR lpszSubKey, LPCSTR lpszFile )
+{
+    LONG ret;
+    LPWSTR lpszSubKeyW = HEAP_strdupAtoW(GetProcessHeap(),0,lpszSubKey);
+    LPWSTR lpszFileW = HEAP_strdupAtoW(GetProcessHeap(),0,lpszFile);
+    ret = RegLoadKey32W( hkey, lpszSubKeyW, lpszFileW );
+    HeapFree(GetProcessHeap(),0,lpszFileW);
+    HeapFree(GetProcessHeap(),0,lpszSubKeyW);
+    return ret;
+}
+
+
+/******************************************************************************
+ * RegNotifyChangeKeyValue [ADVAPI32.???]
+ */
+LONG WINAPI RegNotifyChangeKeyValue( HKEY hkey, BOOL32 fWatchSubTree, 
+                                     DWORD fdwNotifyFilter, HANDLE32 hEvent,
+                                     BOOL32 fAsync )
+{
+    FIXME(reg,"(%x,%i,%ld,%d,%i): stub\n",hkey,fWatchSubTree,fdwNotifyFilter,
+          hEvent,fAsync);
+    return ERROR_SUCCESS;
+}
+
diff --git a/misc/shell.c b/misc/shell.c
index ecea14d..0520d69 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -794,9 +794,14 @@
   _llseek32( hFile, 0, SEEK_SET );
   if (	(_lread32(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
   	(mz_header.e_magic != IMAGE_DOS_SIGNATURE)
-  )
-  	return 0;
-
+  ) { /* .ICO file ? */
+        if (mz_header.e_cblp == 1) { /* ICONHEADER.idType, must be 1 */
+	    *retptr = (LPBYTE)-1;
+  	    return 1;
+	}
+	else
+	    return 0; /* failed */
+  }
   _llseek32( hFile, mz_header.e_lfanew, SEEK_SET );
   if (_lread32( hFile, magic, sizeof(magic) ) != sizeof(magic))
 	return 0;
@@ -825,10 +830,9 @@
 	    }
 	}
   	*retptr = pTypeInfo;
+        return IMAGE_OS2_SIGNATURE;
   } else
-  	*retptr = (LPBYTE)-1;
-  return IMAGE_OS2_SIGNATURE; /* handles .ICO too */
-
+  	return 0; /* failed */
 }
 
 /*************************************************************************
@@ -945,7 +949,8 @@
 
   sig = SHELL_GetResourceTable(hFile,&pData);
 
-  if(sig == IMAGE_OS2_SIGNATURE)
+  if((sig == IMAGE_OS2_SIGNATURE)
+  || (sig == 1)) /* .ICO file */
   {
     HICON16	 hIcon = 0;
     NE_TYPEINFO* pTInfo = (NE_TYPEINFO*)(pData + 2);
diff --git a/misc/shellord.c b/misc/shellord.c
index a21ab8a..344ea11 100644
--- a/misc/shellord.c
+++ b/misc/shellord.c
@@ -521,7 +521,7 @@
 		strcpy(buf,"Desktop");
 	LoadString32A(hmod,id,buf2,100);
 	/* FIXME: the varargs handling doesn't. */
-	FormatMessage32A(0x500,buf2,0,0,&buf3,256,&args);
+	FormatMessage32A(0x500,buf2,0,0,(LPSTR)&buf3,256,(LPDWORD)&args);
 
 	FIXME(shell,"(%08lx,%08lx,%08lx(%s),%08lx(%s),%08lx,%p):stub.\n",
 		(DWORD)hmod,(DWORD)hwnd,id,buf2,x,buf,type,arglist
@@ -660,3 +660,14 @@
 	return SHELL32_195(x);
 }
 
+/*************************************************************************
+ * SHELL32_85 [SHELL32.85]
+ * unknown
+ */
+DWORD WINAPI SHELL32_85(DWORD x1,DWORD x2,DWORD x3,DWORD x4) {
+    FIXME(shell,"(0x%08lx,0x%08lx,0x%08lx,0x%08lx):stub.\n",
+    	x1,x2,x3,x4
+    );
+    return 0;
+}
+
diff --git a/misc/spy.c b/misc/spy.c
index 2d5357c..979ad23 100644
--- a/misc/spy.c
+++ b/misc/spy.c
@@ -669,8 +669,11 @@
 
             if (hTask == GetCurrentTask()) strcpy( taskName, "self" );
             else if (!hTask) strcpy( taskName, "Wine" );
-            else sprintf( taskName, "task %04x %s",
-                          hTask, MODULE_GetModuleName(hTask) );
+            else
+            {
+                sprintf( taskName, "task %04x ???", hTask );
+                GetModuleName( hTask, taskName + 10, sizeof(taskName) - 10 );
+            }
 	    pname = SPY_GetWndName(hWnd);
 
             if (iFlag == SPY_SENDMESSAGE16)
@@ -718,39 +721,39 @@
     switch(iFlag)
     {
     case SPY_RESULT_DEFWND16:
-	TRACE(message,"%*s(%04x)  DefWindowProc16: %s [%04x] returned %08lx\n",
+	TRACE(message," %*s(%04x)  DefWindowProc16: %s [%04x] returned %08lx\n",
 			SPY_IndentLevel, "", hWnd, SPY_GetMsgName( msg ), msg, lReturn );
 	break;
 
     case SPY_RESULT_DEFWND32:
-	TRACE(message,"%*s(%08x)  DefWindowProc32: %s [%04x] returned %08lx\n",
+	TRACE(message," %*s(%08x)  DefWindowProc32: %s [%04x] returned %08lx\n",
 			SPY_IndentLevel, "", hWnd, SPY_GetMsgName( msg ), msg, lReturn );
 	break;
 
     case SPY_RESULT_OK16:
 	pname = SPY_GetWndName(hWnd);
-        TRACE(message,"%*s(%04x) %-16s message [%04x] %s returned %08lx\n",
+        TRACE(message," %*s(%04x) %-16s message [%04x] %s returned %08lx\n",
                         SPY_IndentLevel, "", hWnd, pname, msg,
                         SPY_GetMsgName( msg ), lReturn );
         break;
 
     case SPY_RESULT_OK32:
 	pname = SPY_GetWndName(hWnd);
-        TRACE(message,"%*s(%08x) %-16s message [%04x] %s returned %08lx\n",
+        TRACE(message," %*s(%08x) %-16s message [%04x] %s returned %08lx\n",
                         SPY_IndentLevel, "", hWnd, pname, msg,
                         SPY_GetMsgName( msg ), lReturn );
         break; 
 
     case SPY_RESULT_INVALIDHWND16:
 	pname = SPY_GetWndName(hWnd);
-        WARN(message, "%*s(%04x) %-16s message [%04x] %s HAS INVALID HWND\n",
+        WARN(message, " %*s(%04x) %-16s message [%04x] %s HAS INVALID HWND\n",
                         SPY_IndentLevel, "", hWnd, pname, msg,
                         SPY_GetMsgName( msg ) );
         break;
 
     case SPY_RESULT_INVALIDHWND32:
 	pname = SPY_GetWndName(hWnd);
-        WARN(message, "%*s(%08x) %-16s message [%04x] %s HAS INVALID HWND\n",
+        WARN(message, " %*s(%08x) %-16s message [%04x] %s HAS INVALID HWND\n",
                         SPY_IndentLevel, "", hWnd, pname, msg,
                         SPY_GetMsgName( msg ) );
         break;
diff --git a/misc/winsock.c b/misc/winsock.c
index 505adfd..24d5242 100644
--- a/misc/winsock.c
+++ b/misc/winsock.c
@@ -2581,11 +2581,10 @@
 UINT16 wsaErrno(void)
 {
     int	loc_errno = errno; 
-#if defined(__FreeBSD__)
-       ERR(winsock, "errno %d, (%s).\n", 
-                			 errno, strerror(errno));
+#ifdef HAVE_STRERROR
+    WARN(winsock, "errno %d, (%s).\n", errno, strerror(errno));
 #else
-       ERR(winsock, "errno %d\n", errno);
+    WARN(winsock, "errno %d\n", errno);
 #endif
 
     switch(loc_errno)
@@ -2657,11 +2656,10 @@
 {
     int		loc_errno = h_errno;
 
-#if defined(__FreeBSD__)
-    ERR(winsock, "h_errno %d, (%s).\n", 
-               	    h_errno, strerror(h_errno));
+#ifdef HAVE_STRERROR
+    WARN(winsock, "h_errno %d, (%s).\n", h_errno, strerror(h_errno));
 #else
-    ERR(winsock, "h_errno %d.\n", h_errno);
+    WARN(winsock, "h_errno %d.\n", h_errno);
 #endif
 
     switch(loc_errno)
diff --git a/miscemu/main.c b/miscemu/main.c
index e7c6e9f..1f53c89 100644
--- a/miscemu/main.c
+++ b/miscemu/main.c
@@ -3,10 +3,10 @@
  *
  */
 
-#include <stdio.h>
 #include "windows.h"
 #include "callback.h"
 #include "debugger.h"
+#include "main.h"
 #include "miscemu.h"
 #include "module.h"
 #include "options.h"
@@ -18,8 +18,6 @@
  */
 BOOL32 MAIN_EmulatorInit(void)
 {
-    extern BOOL32 MAIN_KernelInit(void);
-    extern BOOL32 MAIN_UserInit(void);
     extern BOOL32 WIN16DRV_Init(void);
     extern BOOL32 RELAY_Init(void);
 
@@ -46,7 +44,6 @@
 int main( int argc, char *argv[] )
 {
     extern BOOL32 PROCESS_Init(void);
-    extern BOOL32 MAIN_WineInit( int *argc, char *argv[] );
     extern void *CALL32_Init(void);
     extern char * DEBUG_argv0;
 
@@ -107,7 +104,6 @@
     }
 
     if (!loaded) { /* nothing loaded */
-    	extern void MAIN_Usage(char*);
     	MAIN_Usage(argv[0]);
 	return 1;
     }
diff --git a/msdos/dpmi.c b/msdos/dpmi.c
index a452592..36d7058 100644
--- a/msdos/dpmi.c
+++ b/msdos/dpmi.c
@@ -224,13 +224,14 @@
         break;
     }
 
-    if (EFL_reg(context)&1)
+    if (EFL_reg(context)&1) {
       FIXME(int31,"%02x: EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n",
 	    BL_reg(context), EAX_reg(&realmode_ctx), EBX_reg(&realmode_ctx), 
 	    ECX_reg(&realmode_ctx), EDX_reg(&realmode_ctx));
       FIXME(int31,"      ESI=%08lx EDI=%08lx DS=%04lx ES=%04lx\n",
 	    ESI_reg(&realmode_ctx), EDI_reg(&realmode_ctx), 
 	    DS_reg(&realmode_ctx), ES_reg(&realmode_ctx) );
+    }
     INT_SetRealModeContext( call, &realmode_ctx );
 }
 
diff --git a/msdos/int21.c b/msdos/int21.c
index 5ccf18f..bd3c772 100644
--- a/msdos/int21.c
+++ b/msdos/int21.c
@@ -1318,7 +1318,7 @@
         case 0x01:
             break;
 	case 0x05:{	/* IOCTL - WRITE TO BLOCK DEVICE CONTROL CHANNEL */
-	    BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context));
+	    /*BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context));*/
 	    int	drive = DOS_GET_DRIVE(BL_reg(context));
 
 	    FIXME(int21,"program tried to write to block device control channel of drive %d:\n",drive);
diff --git a/msdos/int2f.c b/msdos/int2f.c
index fb8cf67..7ab8ede 100644
--- a/msdos/int2f.c
+++ b/msdos/int2f.c
@@ -72,6 +72,16 @@
             INT_BARF( context, 0x2f );
         }
         break;
+    case 0x56:  /* INTERLNK */
+	switch(AL_reg(context))
+	{
+	case 0x01:  /* check if redirected drive */
+	    AL_reg(context) = 0; /* not redirected */
+	    break;
+	default:
+	    INT_BARF( context, 0x2f );
+	}
+	break;
     case 0xb7:  /* append */
         AL_reg(context) = 0; /* not installed */
         break;
@@ -217,7 +227,7 @@
             break;
 
         default:
-            FIXME(int, "Unimplemented MSCDEX function 0x%02.2X.\n", AL_reg(context));
+            FIXME(int, "Unimplemented MSCDEX function 0x%02X.\n", AL_reg(context));
             break;
     }
 }
diff --git a/multimedia/audio.c b/multimedia/audio.c
index c192a5c..92d6e6e 100644
--- a/multimedia/audio.c
+++ b/multimedia/audio.c
@@ -780,9 +780,13 @@
 	lpCaps->vDriverVersion = 0x0100;
 	lpCaps->dwFormats = 0x00000000;
 	lpCaps->dwSupport = WAVECAPS_VOLUME;
+
+	/* First bytespersampl, then stereo */
+	bytespersmpl = (IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize) != 0) ? 1 : 2;
+
 	lpCaps->wChannels = (IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo) != 0) ? 1 : 2;
 	if (lpCaps->wChannels > 1) lpCaps->dwSupport |= WAVECAPS_LRVOLUME;
-	bytespersmpl = (IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize) != 0) ? 1 : 2;
+
 	smplrate = 44100;
 	if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
 		lpCaps->dwFormats |= WAVE_FORMAT_4M08;
@@ -901,9 +905,12 @@
 	samplesize = WOutDev[wDevID].Format.wBitsPerSample;
 	smplrate = WOutDev[wDevID].Format.wf.nSamplesPerSec;
 	dsp_stereo = (WOutDev[wDevID].Format.wf.nChannels > 1) ? TRUE : FALSE;
-	IOCTL(audio, SNDCTL_DSP_SPEED, smplrate);
+
+	/* First size and stereo then samplerate */
 	IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize);
 	IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo);
+	IOCTL(audio, SNDCTL_DSP_SPEED, smplrate);
+
 	TRACE(mciwave,"wBitsPerSample=%u !\n",
 		     WOutDev[wDevID].Format.wBitsPerSample);
 	TRACE(mciwave,"nAvgBytesPerSec=%lu !\n",
diff --git a/multimedia/mmio.c b/multimedia/mmio.c
index b1f6941..0e67f41 100644
--- a/multimedia/mmio.c
+++ b/multimedia/mmio.c
@@ -375,9 +375,12 @@
 UINT16 WINAPI mmioSetBuffer(HMMIO16 hmmio, LPSTR pchBuffer, 
                             LONG cchBuffer, UINT16 uFlags)
 {
-	FIXME(mmio, "(hmmio=%d, pchBuf=%p, cchBuf=%d, uFlags=%#08x): stub\n",
+	FIXME(mmio, "(hmmio=%d, pchBuf=%p, cchBuf=%ld, uFlags=%#08x): stub\n",
 	      hmmio, pchBuffer, cchBuffer, uFlags);
+	return (UINT16) 0;
+/*	stops Corel Draw 4 (16 bit) from working
 	return MMIOERR_OUTOFMEMORY;
+*/
 }
 
 /**************************************************************************
diff --git a/multimedia/mmsystem.c b/multimedia/mmsystem.c
index f13aefa..d40000e 100644
--- a/multimedia/mmsystem.c
+++ b/multimedia/mmsystem.c
@@ -1412,7 +1412,7 @@
       LPSTR           segstr;
       SEGPTR          xmem;
       LPBYTE          lmem;
-      static          mcidevtype = 0;
+      static UINT16   mcidevtype = 0;
 
       FIXME(mmsys,"(%04x,%s,%d): stub!\n",hinst,resname,type);
       if (!lstrcmpi32A(resname,"core")) {
diff --git a/objects/cursoricon.c b/objects/cursoricon.c
index 36918ef..74da477 100644
--- a/objects/cursoricon.c
+++ b/objects/cursoricon.c
@@ -761,8 +761,7 @@
 
     TRACE(cursor, "%dx%d spot=%d,%d xor=%p and=%p\n",
                     nWidth, nHeight, xHotSpot, yHotSpot, lpXORbits, lpANDbits);
-    return CreateCursorIconIndirect( MODULE_HANDLEtoHMODULE16( hInstance ),
-                                     &info, lpANDbits, lpXORbits );
+    return CreateCursorIconIndirect( 0, &info, lpANDbits, lpXORbits );
 }
 
 
@@ -792,8 +791,7 @@
 
     TRACE(icon, "%dx%dx%d, xor=%p, and=%p\n",
                   nWidth, nHeight, bPlanes * bBitsPixel, lpXORbits, lpANDbits);
-    return CreateCursorIconIndirect( MODULE_HANDLEtoHMODULE16( hInstance ),
-                                     &info, lpANDbits, lpXORbits );
+    return CreateCursorIconIndirect( 0, &info, lpANDbits, lpXORbits );
 }
 
 
@@ -810,13 +808,14 @@
     int sizeAnd, sizeXor;
 
     hInstance = GetExePtr( hInstance );  /* Make it a module handle */
-    if (!hInstance || !lpXORbits || !lpANDbits || info->bPlanes != 1) return 0;
+    if (!lpXORbits || !lpANDbits || info->bPlanes != 1) return 0;
     info->nWidthBytes = BITMAP_WIDTH_BYTES(info->nWidth,info->bBitsPerPixel);
     sizeXor = info->nHeight * info->nWidthBytes;
     sizeAnd = info->nHeight * BITMAP_WIDTH_BYTES( info->nWidth, 1 );
-    if (!(handle = DirectResAlloc(hInstance, 0x10,
+    if (!(handle = GlobalAlloc16( GMEM_MOVEABLE,
                                   sizeof(CURSORICONINFO) + sizeXor + sizeAnd)))
         return 0;
+    if (hInstance) FarSetOwner( handle, hInstance );
     ptr = (char *)GlobalLock16( handle );
     memcpy( ptr, info, sizeof(*info) );
     memcpy( ptr + sizeof(CURSORICONINFO), lpANDbits, sizeAnd );
diff --git a/objects/dc.c b/objects/dc.c
index 6c71c18..f608b09 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -100,50 +100,52 @@
  */
 static void DC_Init_DC_INFO( WIN_DC_INFO *win_dc_info )
 {
-    win_dc_info->flags           = 0;
-    win_dc_info->devCaps         = NULL;
-    win_dc_info->hClipRgn        = 0;
-    win_dc_info->hVisRgn         = 0;
-    win_dc_info->hGCClipRgn      = 0;
-    win_dc_info->hPen            = STOCK_BLACK_PEN;
-    win_dc_info->hBrush          = STOCK_WHITE_BRUSH;
-    win_dc_info->hFont           = STOCK_SYSTEM_FONT;
-    win_dc_info->hBitmap         = 0;
-    win_dc_info->hFirstBitmap    = 0;
-    win_dc_info->hDevice         = 0;
-    win_dc_info->hPalette        = STOCK_DEFAULT_PALETTE;
-    win_dc_info->ROPmode         = R2_COPYPEN;
-    win_dc_info->polyFillMode    = ALTERNATE;
-    win_dc_info->stretchBltMode  = BLACKONWHITE;
-    win_dc_info->relAbsMode      = ABSOLUTE;
-    win_dc_info->backgroundMode  = OPAQUE;
-    win_dc_info->backgroundColor = RGB( 255, 255, 255 );
-    win_dc_info->textColor       = RGB( 0, 0, 0 );
-    win_dc_info->backgroundPixel = 0;
-    win_dc_info->textPixel       = 0;
-    win_dc_info->brushOrgX       = 0;
-    win_dc_info->brushOrgY       = 0;
-    win_dc_info->textAlign       = TA_LEFT | TA_TOP | TA_NOUPDATECP;
-    win_dc_info->charExtra       = 0;
-    win_dc_info->breakTotalExtra = 0;
-    win_dc_info->breakCount      = 0;
-    win_dc_info->breakExtra      = 0;
-    win_dc_info->breakRem        = 0;
-    win_dc_info->bitsPerPixel    = 1;
-    win_dc_info->MapMode         = MM_TEXT;
-    win_dc_info->GraphicsMode    = GM_COMPATIBLE;
-    win_dc_info->DCOrgX          = 0;
-    win_dc_info->DCOrgY          = 0;
-    win_dc_info->CursPosX        = 0;
-    win_dc_info->CursPosY        = 0;
-    win_dc_info->ArcDirection    = AD_COUNTERCLOCKWISE;
-    win_dc_info->UseWorldXform   = FALSE;
-    win_dc_info->WorldXform.eM11 = 1.0f;
-    win_dc_info->WorldXform.eM12 = 0.0f;
-    win_dc_info->WorldXform.eM21 = 0.0f;
-    win_dc_info->WorldXform.eM22 = 1.0f;
-    win_dc_info->WorldXform.eDx  = 0.0f;
-    win_dc_info->WorldXform.eDy  = 0.0f;
+    win_dc_info->flags               = 0;
+    win_dc_info->devCaps             = NULL;
+    win_dc_info->hClipRgn            = 0;
+    win_dc_info->hVisRgn             = 0;
+    win_dc_info->hGCClipRgn          = 0;
+    win_dc_info->hPen                = STOCK_BLACK_PEN;
+    win_dc_info->hBrush              = STOCK_WHITE_BRUSH;
+    win_dc_info->hFont               = STOCK_SYSTEM_FONT;
+    win_dc_info->hBitmap             = 0;
+    win_dc_info->hFirstBitmap        = 0;
+    win_dc_info->hDevice             = 0;
+    win_dc_info->hPalette            = STOCK_DEFAULT_PALETTE;
+    win_dc_info->ROPmode             = R2_COPYPEN;
+    win_dc_info->polyFillMode        = ALTERNATE;
+    win_dc_info->stretchBltMode      = BLACKONWHITE;
+    win_dc_info->relAbsMode          = ABSOLUTE;
+    win_dc_info->backgroundMode      = OPAQUE;
+    win_dc_info->backgroundColor     = RGB( 255, 255, 255 );
+    win_dc_info->textColor           = RGB( 0, 0, 0 );
+    win_dc_info->backgroundPixel     = 0;
+    win_dc_info->textPixel           = 0;
+    win_dc_info->brushOrgX           = 0;
+    win_dc_info->brushOrgY           = 0;
+    win_dc_info->textAlign           = TA_LEFT | TA_TOP | TA_NOUPDATECP;
+    win_dc_info->charExtra           = 0;
+    win_dc_info->breakTotalExtra     = 0;
+    win_dc_info->breakCount          = 0;
+    win_dc_info->breakExtra          = 0;
+    win_dc_info->breakRem            = 0;
+    win_dc_info->bitsPerPixel        = 1;
+    win_dc_info->MapMode             = MM_TEXT;
+    win_dc_info->GraphicsMode        = GM_COMPATIBLE;
+    win_dc_info->DCOrgX              = 0;
+    win_dc_info->DCOrgY              = 0;
+    win_dc_info->CursPosX            = 0;
+    win_dc_info->CursPosY            = 0;
+    win_dc_info->ArcDirection        = AD_COUNTERCLOCKWISE;
+    win_dc_info->xformWorld2Wnd.eM11 = 1.0f;
+    win_dc_info->xformWorld2Wnd.eM12 = 0.0f;
+    win_dc_info->xformWorld2Wnd.eM21 = 0.0f;
+    win_dc_info->xformWorld2Wnd.eM22 = 1.0f;
+    win_dc_info->xformWorld2Wnd.eDx  = 0.0f;
+    win_dc_info->xformWorld2Wnd.eDy  = 0.0f;
+    win_dc_info->xformWorld2Vport    = win_dc_info->xformWorld2Wnd;
+    win_dc_info->xformVport2World    = win_dc_info->xformWorld2Wnd;
+    win_dc_info->vport2WorldValid    = TRUE;
 
     PATH_InitGdiPath(&win_dc_info->path);
 }
@@ -434,6 +436,72 @@
 
 
 /***********************************************************************
+ *           DC_InvertXform
+ *
+ * Computes the inverse of the transformation xformSrc and stores it to
+ * xformDest. Returns TRUE if successful or FALSE if the xformSrc matrix
+ * is singular.
+ */
+static BOOL32 DC_InvertXform( const XFORM *xformSrc, XFORM *xformDest )
+{
+    FLOAT determinant;
+    
+    determinant = xformSrc->eM11*xformSrc->eM22 -
+        xformSrc->eM12*xformSrc->eM21;
+    if (determinant > -1e-12 && determinant < 1e-12)
+        return FALSE;
+
+    xformDest->eM11 =  xformSrc->eM22 / determinant;
+    xformDest->eM12 = -xformSrc->eM12 / determinant;
+    xformDest->eM21 = -xformSrc->eM21 / determinant;
+    xformDest->eM22 =  xformSrc->eM11 / determinant;
+    xformDest->eDx  = -xformSrc->eDx * xformDest->eM11 -
+                       xformSrc->eDy * xformDest->eM21;
+    xformDest->eDy  = -xformSrc->eDx * xformDest->eM12 -
+                       xformSrc->eDy * xformDest->eM22;
+
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           DC_UpdateXforms
+ *
+ * Updates the xformWorld2Vport, xformVport2World and vport2WorldValid
+ * fields of the specified DC by creating a transformation that
+ * represents the current mapping mode and combining it with the DC's
+ * world transform. This function should be called whenever the
+ * parameters associated with the mapping mode (window and viewport
+ * extents and origins) or the world transform change.
+ */
+void DC_UpdateXforms( DC *dc )
+{
+    XFORM xformWnd2Vport;
+    FLOAT scaleX, scaleY;
+    
+    /* Construct a transformation to do the window-to-viewport conversion */
+    scaleX = (FLOAT)dc->vportExtX / (FLOAT)dc->wndExtX;
+    scaleY = (FLOAT)dc->vportExtY / (FLOAT)dc->wndExtY;
+    xformWnd2Vport.eM11 = scaleX;
+    xformWnd2Vport.eM12 = 0.0;
+    xformWnd2Vport.eM21 = 0.0;
+    xformWnd2Vport.eM22 = scaleY;
+    xformWnd2Vport.eDx  = (FLOAT)dc->vportOrgX -
+        scaleX * (FLOAT)dc->wndOrgX;
+    xformWnd2Vport.eDy  = (FLOAT)dc->vportOrgY -
+        scaleY * (FLOAT)dc->wndOrgY;
+
+    /* Combine with the world transformation */
+    CombineTransform( &dc->w.xformWorld2Vport, &dc->w.xformWorld2Wnd,
+        &xformWnd2Vport );
+
+    /* Create inverse of world-to-viewport transformation */
+    dc->w.vport2WorldValid = DC_InvertXform( &dc->w.xformWorld2Vport,
+        &dc->w.xformVport2World );
+}
+
+
+/***********************************************************************
  *           GetDCState    (GDI.179)
  */
 HDC16 WINAPI GetDCState( HDC16 hdc )
@@ -452,50 +520,52 @@
     TRACE(dc, "(%04x): returning %04x\n", hdc, handle );
 
     memset( &newdc->u.x, 0, sizeof(newdc->u.x) );
-    newdc->w.flags           = dc->w.flags | DC_SAVED;
-    newdc->w.devCaps         = dc->w.devCaps;
-    newdc->w.hPen            = dc->w.hPen;       
-    newdc->w.hBrush          = dc->w.hBrush;     
-    newdc->w.hFont           = dc->w.hFont;      
-    newdc->w.hBitmap         = dc->w.hBitmap;    
-    newdc->w.hFirstBitmap    = dc->w.hFirstBitmap;
-    newdc->w.hDevice         = dc->w.hDevice;
-    newdc->w.hPalette        = dc->w.hPalette;   
-    newdc->w.bitsPerPixel    = dc->w.bitsPerPixel;
-    newdc->w.ROPmode         = dc->w.ROPmode;
-    newdc->w.polyFillMode    = dc->w.polyFillMode;
-    newdc->w.stretchBltMode  = dc->w.stretchBltMode;
-    newdc->w.relAbsMode      = dc->w.relAbsMode;
-    newdc->w.backgroundMode  = dc->w.backgroundMode;
-    newdc->w.backgroundColor = dc->w.backgroundColor;
-    newdc->w.textColor       = dc->w.textColor;
-    newdc->w.backgroundPixel = dc->w.backgroundPixel;
-    newdc->w.textPixel       = dc->w.textPixel;
-    newdc->w.brushOrgX       = dc->w.brushOrgX;
-    newdc->w.brushOrgY       = dc->w.brushOrgY;
-    newdc->w.textAlign       = dc->w.textAlign;
-    newdc->w.charExtra       = dc->w.charExtra;
-    newdc->w.breakTotalExtra = dc->w.breakTotalExtra;
-    newdc->w.breakCount      = dc->w.breakCount;
-    newdc->w.breakExtra      = dc->w.breakExtra;
-    newdc->w.breakRem        = dc->w.breakRem;
-    newdc->w.MapMode         = dc->w.MapMode;
-    newdc->w.GraphicsMode    = dc->w.GraphicsMode;
-    newdc->w.DCOrgX          = dc->w.DCOrgX;
-    newdc->w.DCOrgY          = dc->w.DCOrgY;
-    newdc->w.CursPosX        = dc->w.CursPosX;
-    newdc->w.CursPosY        = dc->w.CursPosY;
-    newdc->w.ArcDirection    = dc->w.ArcDirection;
-    newdc->w.UseWorldXform   = dc->w.UseWorldXform;
-    newdc->w.WorldXform      = dc->w.WorldXform;
-    newdc->wndOrgX           = dc->wndOrgX;
-    newdc->wndOrgY           = dc->wndOrgY;
-    newdc->wndExtX           = dc->wndExtX;
-    newdc->wndExtY           = dc->wndExtY;
-    newdc->vportOrgX         = dc->vportOrgX;
-    newdc->vportOrgY         = dc->vportOrgY;
-    newdc->vportExtX         = dc->vportExtX;
-    newdc->vportExtY         = dc->vportExtY;
+    newdc->w.flags            = dc->w.flags | DC_SAVED;
+    newdc->w.devCaps          = dc->w.devCaps;
+    newdc->w.hPen             = dc->w.hPen;       
+    newdc->w.hBrush           = dc->w.hBrush;     
+    newdc->w.hFont            = dc->w.hFont;      
+    newdc->w.hBitmap          = dc->w.hBitmap;    
+    newdc->w.hFirstBitmap     = dc->w.hFirstBitmap;
+    newdc->w.hDevice          = dc->w.hDevice;
+    newdc->w.hPalette         = dc->w.hPalette;   
+    newdc->w.bitsPerPixel     = dc->w.bitsPerPixel;
+    newdc->w.ROPmode          = dc->w.ROPmode;
+    newdc->w.polyFillMode     = dc->w.polyFillMode;
+    newdc->w.stretchBltMode   = dc->w.stretchBltMode;
+    newdc->w.relAbsMode       = dc->w.relAbsMode;
+    newdc->w.backgroundMode   = dc->w.backgroundMode;
+    newdc->w.backgroundColor  = dc->w.backgroundColor;
+    newdc->w.textColor        = dc->w.textColor;
+    newdc->w.backgroundPixel  = dc->w.backgroundPixel;
+    newdc->w.textPixel        = dc->w.textPixel;
+    newdc->w.brushOrgX        = dc->w.brushOrgX;
+    newdc->w.brushOrgY        = dc->w.brushOrgY;
+    newdc->w.textAlign        = dc->w.textAlign;
+    newdc->w.charExtra        = dc->w.charExtra;
+    newdc->w.breakTotalExtra  = dc->w.breakTotalExtra;
+    newdc->w.breakCount       = dc->w.breakCount;
+    newdc->w.breakExtra       = dc->w.breakExtra;
+    newdc->w.breakRem         = dc->w.breakRem;
+    newdc->w.MapMode          = dc->w.MapMode;
+    newdc->w.GraphicsMode     = dc->w.GraphicsMode;
+    newdc->w.DCOrgX           = dc->w.DCOrgX;
+    newdc->w.DCOrgY           = dc->w.DCOrgY;
+    newdc->w.CursPosX         = dc->w.CursPosX;
+    newdc->w.CursPosY         = dc->w.CursPosY;
+    newdc->w.ArcDirection     = dc->w.ArcDirection;
+    newdc->w.xformWorld2Wnd   = dc->w.xformWorld2Wnd;
+    newdc->w.xformWorld2Vport = dc->w.xformWorld2Vport;
+    newdc->w.xformVport2World = dc->w.xformVport2World;
+    newdc->w.vport2WorldValid = dc->w.vport2WorldValid;
+    newdc->wndOrgX            = dc->wndOrgX;
+    newdc->wndOrgY            = dc->wndOrgY;
+    newdc->wndExtX            = dc->wndExtX;
+    newdc->wndExtY            = dc->wndExtY;
+    newdc->vportOrgX          = dc->vportOrgX;
+    newdc->vportOrgY          = dc->vportOrgY;
+    newdc->vportExtX          = dc->vportExtX;
+    newdc->vportExtY          = dc->vportExtY;
 
     newdc->hSelf = (HDC32)handle;
     newdc->saveLevel = 0;
@@ -539,45 +609,47 @@
     }
     TRACE(dc, "%04x %04x\n", hdc, hdcs );
 
-    dc->w.flags           = dcs->w.flags & ~DC_SAVED;
-    dc->w.devCaps         = dcs->w.devCaps;
-    dc->w.hFirstBitmap    = dcs->w.hFirstBitmap;
-    dc->w.hDevice         = dcs->w.hDevice;
-    dc->w.ROPmode         = dcs->w.ROPmode;
-    dc->w.polyFillMode    = dcs->w.polyFillMode;
-    dc->w.stretchBltMode  = dcs->w.stretchBltMode;
-    dc->w.relAbsMode      = dcs->w.relAbsMode;
-    dc->w.backgroundMode  = dcs->w.backgroundMode;
-    dc->w.backgroundColor = dcs->w.backgroundColor;
-    dc->w.textColor       = dcs->w.textColor;
-    dc->w.backgroundPixel = dcs->w.backgroundPixel;
-    dc->w.textPixel       = dcs->w.textPixel;
-    dc->w.brushOrgX       = dcs->w.brushOrgX;
-    dc->w.brushOrgY       = dcs->w.brushOrgY;
-    dc->w.textAlign       = dcs->w.textAlign;
-    dc->w.charExtra       = dcs->w.charExtra;
-    dc->w.breakTotalExtra = dcs->w.breakTotalExtra;
-    dc->w.breakCount      = dcs->w.breakCount;
-    dc->w.breakExtra      = dcs->w.breakExtra;
-    dc->w.breakRem        = dcs->w.breakRem;
-    dc->w.MapMode         = dcs->w.MapMode;
-    dc->w.GraphicsMode    = dcs->w.GraphicsMode;
-    dc->w.DCOrgX          = dcs->w.DCOrgX;
-    dc->w.DCOrgY          = dcs->w.DCOrgY;
-    dc->w.CursPosX        = dcs->w.CursPosX;
-    dc->w.CursPosY        = dcs->w.CursPosY;
-    dc->w.ArcDirection    = dcs->w.ArcDirection;
-    dc->w.UseWorldXform   = dcs->w.UseWorldXform;
-    dc->w.WorldXform      = dcs->w.WorldXform;
+    dc->w.flags            = dcs->w.flags & ~DC_SAVED;
+    dc->w.devCaps          = dcs->w.devCaps;
+    dc->w.hFirstBitmap     = dcs->w.hFirstBitmap;
+    dc->w.hDevice          = dcs->w.hDevice;
+    dc->w.ROPmode          = dcs->w.ROPmode;
+    dc->w.polyFillMode     = dcs->w.polyFillMode;
+    dc->w.stretchBltMode   = dcs->w.stretchBltMode;
+    dc->w.relAbsMode       = dcs->w.relAbsMode;
+    dc->w.backgroundMode   = dcs->w.backgroundMode;
+    dc->w.backgroundColor  = dcs->w.backgroundColor;
+    dc->w.textColor        = dcs->w.textColor;
+    dc->w.backgroundPixel  = dcs->w.backgroundPixel;
+    dc->w.textPixel        = dcs->w.textPixel;
+    dc->w.brushOrgX        = dcs->w.brushOrgX;
+    dc->w.brushOrgY        = dcs->w.brushOrgY;
+    dc->w.textAlign        = dcs->w.textAlign;
+    dc->w.charExtra        = dcs->w.charExtra;
+    dc->w.breakTotalExtra  = dcs->w.breakTotalExtra;
+    dc->w.breakCount       = dcs->w.breakCount;
+    dc->w.breakExtra       = dcs->w.breakExtra;
+    dc->w.breakRem         = dcs->w.breakRem;
+    dc->w.MapMode          = dcs->w.MapMode;
+    dc->w.GraphicsMode     = dcs->w.GraphicsMode;
+    dc->w.DCOrgX           = dcs->w.DCOrgX;
+    dc->w.DCOrgY           = dcs->w.DCOrgY;
+    dc->w.CursPosX         = dcs->w.CursPosX;
+    dc->w.CursPosY         = dcs->w.CursPosY;
+    dc->w.ArcDirection     = dcs->w.ArcDirection;
+    dc->w.xformWorld2Wnd   = dcs->w.xformWorld2Wnd;
+    dc->w.xformWorld2Vport = dcs->w.xformWorld2Vport;
+    dc->w.xformVport2World = dcs->w.xformVport2World;
+    dc->w.vport2WorldValid = dcs->w.vport2WorldValid;
 
-    dc->wndOrgX           = dcs->wndOrgX;
-    dc->wndOrgY           = dcs->wndOrgY;
-    dc->wndExtX           = dcs->wndExtX;
-    dc->wndExtY           = dcs->wndExtY;
-    dc->vportOrgX         = dcs->vportOrgX;
-    dc->vportOrgY         = dcs->vportOrgY;
-    dc->vportExtX         = dcs->vportExtX;
-    dc->vportExtY         = dcs->vportExtY;
+    dc->wndOrgX            = dcs->wndOrgX;
+    dc->wndOrgY            = dcs->wndOrgY;
+    dc->wndExtX            = dcs->wndExtX;
+    dc->wndExtY            = dcs->wndExtY;
+    dc->vportOrgX          = dcs->vportOrgX;
+    dc->vportOrgY          = dcs->vportOrgY;
+    dc->vportExtX          = dcs->vportExtX;
+    dc->vportExtY          = dcs->vportExtY;
 
     if (!(dc->w.flags & DC_MEMORY)) dc->w.bitsPerPixel = dcs->w.bitsPerPixel;
     SelectClipRgn32( hdc, dcs->w.hClipRgn );
@@ -1208,21 +1280,17 @@
 
 /***********************************************************************
  *           GetWorldTransform    (GDI32.244)
- * FIXME
- *	Check that SetLastError is being called correctly
  */
 BOOL32 WINAPI GetWorldTransform( HDC32 hdc, LPXFORM xform )
 {
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     
     if (!dc)
-        /* FIXME: Call SetLastError? */
         return FALSE;
     if (!xform)
-        /* FIXME: Call SetLastError? */
 	return FALSE;
 
-    *xform = dc->w.WorldXform;
+    *xform = dc->w.xformWorld2Wnd;
     
     return TRUE;
 }
@@ -1248,16 +1316,125 @@
     if (dc->w.GraphicsMode!=GM_ADVANCED)
        return FALSE;
 
-    dc->w.WorldXform = *xform;
-
-    /* We only have to use the new world transform if it's not the
-     * identity transformation
-     */
-    dc->w.UseWorldXform=
-       (xform->eM11!=1.0f || xform->eM12!=0.0f ||
-        xform->eM21!=0.0f || xform->eM22!=1.0f ||
-        xform->eDx!=0.0f  || xform->eDy!=0.0f);
+    dc->w.xformWorld2Wnd = *xform;
     
+    DC_UpdateXforms( dc );
+
+    return TRUE;
+}
+
+
+/****************************************************************************
+ * ModifyWorldTransform [GDI32.253]
+ * Modifies the world transformation for a device context.
+ *
+ * PARAMS
+ *    hdc   [I] Handle to device context
+ *    xform [I] XFORM structure that will be used to modify the world
+ *              transformation
+ *    iMode [I] Specifies in what way to modify the world transformation
+ *              Possible values:
+ *              MWT_IDENTITY
+ *                 Resets the world transformation to the identity matrix.
+ *                 The parameter xform is ignored.
+ *              MWT_LEFTMULTIPLY
+ *                 Multiplies xform into the world transformation matrix from
+ *                 the left.
+ *              MWT_RIGHTMULTIPLY
+ *                 Multiplies xform into the world transformation matrix from
+ *                 the right.
+ *
+ * RETURNS STD
+ */
+BOOL32 WINAPI ModifyWorldTransform( HDC32 hdc, const XFORM *xform,
+    DWORD iMode )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    
+    /* Check for illegal parameters */
+    if (!dc)
+    {
+        SetLastError( ERROR_INVALID_HANDLE );
+        return FALSE;
+    }
+    if (!xform)
+	return FALSE;
+    
+    /* Check that graphics mode is GM_ADVANCED */
+    if (dc->w.GraphicsMode!=GM_ADVANCED)
+       return FALSE;
+       
+    switch (iMode)
+    {
+        case MWT_IDENTITY:
+	    dc->w.xformWorld2Wnd.eM11 = 1.0f;
+	    dc->w.xformWorld2Wnd.eM12 = 0.0f;
+	    dc->w.xformWorld2Wnd.eM21 = 0.0f;
+	    dc->w.xformWorld2Wnd.eM22 = 1.0f;
+	    dc->w.xformWorld2Wnd.eDx  = 0.0f;
+	    dc->w.xformWorld2Wnd.eDy  = 0.0f;
+	    break;
+        case MWT_LEFTMULTIPLY:
+	    CombineTransform( &dc->w.xformWorld2Wnd, xform,
+	        &dc->w.xformWorld2Wnd );
+	    break;
+	case MWT_RIGHTMULTIPLY:
+	    CombineTransform( &dc->w.xformWorld2Wnd, &dc->w.xformWorld2Wnd,
+	        xform );
+	    break;
+        default:
+	    return FALSE;
+    }
+
+    DC_UpdateXforms( dc );
+
+    return TRUE;
+}
+
+
+/****************************************************************************
+ * CombineTransform [GDI32.20]
+ * Combines two transformation matrices.
+ *
+ * PARAMS
+ *    xformResult [O] Stores the result of combining the two matrices
+ *    xform1      [I] Specifies the first matrix to apply
+ *    xform2      [I] Specifies the second matrix to apply
+ *
+ * REMARKS
+ *    The same matrix can be passed in for more than one of the parameters.
+ *
+ * RETURNS STD
+ */
+BOOL32 WINAPI CombineTransform( LPXFORM xformResult, const XFORM *xform1,
+    const XFORM *xform2 )
+{
+    XFORM xformTemp;
+    
+    /* Check for illegal parameters */
+    if (!xformResult || !xform1 || !xform2)
+        return FALSE;
+
+    /* Create the result in a temporary XFORM, since xformResult may be
+     * equal to xform1 or xform2 */
+    xformTemp.eM11 = xform1->eM11 * xform2->eM11 +
+                     xform1->eM12 * xform2->eM21;
+    xformTemp.eM12 = xform1->eM11 * xform2->eM12 +
+                     xform1->eM12 * xform2->eM22;
+    xformTemp.eM21 = xform1->eM21 * xform2->eM11 +
+                     xform1->eM22 * xform2->eM21;
+    xformTemp.eM22 = xform1->eM21 * xform2->eM12 +
+                     xform1->eM22 * xform2->eM22;
+    xformTemp.eDx  = xform1->eDx  * xform2->eM11 +
+                     xform1->eDy  * xform2->eM21 +
+                     xform2->eDx;
+    xformTemp.eDy  = xform1->eDx  * xform2->eM12 +
+                     xform1->eDy  * xform2->eM22 +
+                     xform2->eDy;
+
+    /* Copy the result to xformResult */
+    *xformResult = xformTemp;
+
     return TRUE;
 }
 
diff --git a/objects/enhmetafile.c b/objects/enhmetafile.c
index d6b784f..8c34bf9 100644
--- a/objects/enhmetafile.c
+++ b/objects/enhmetafile.c
@@ -164,7 +164,7 @@
     {
     case EMR_HEADER:
       {
-	ENHMETAHEADER *h = (LPENHMETAHEADER) mr;
+	/* ENHMETAHEADER *h = (LPENHMETAHEADER) mr; */
 	break;
       }
     case EMR_EOF:
@@ -418,7 +418,7 @@
     if (p->iType == EMR_EOF) break;
     p = (void *) p + p->nSize;
   }
-  GlobalFree32(ht);
+  GlobalFree32((HGLOBAL32)ht);
   GlobalUnlock32(hmf);
   return ret;
 }
@@ -465,7 +465,8 @@
     p = (void *) p + p->nSize; /* casted so that arithmetic is in bytes */
   }
   GlobalUnlock32(hmf);
-  return TRUE;
+  ret = TRUE; /* FIXME: calculate a more accurate return value */
+  return ret;
 }
 
 /*****************************************************************************
diff --git a/objects/metafile.c b/objects/metafile.c
index 6e3d0b8..0308660 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -444,7 +444,7 @@
     HFONT32 hFont;
 
     TRACE(metafile,"(%08x,%08x,%p,%p)\n",
-		     hdc, hmf, lpEnumFunc, lpData);
+		     hdc, hmf, lpEnumFunc, (void*)lpData);
     if (!mh) return 0;
 
     /* save the current pen, brush and font */
@@ -484,7 +484,7 @@
         DeleteObject32(*(ht->objectHandle + i));
 
     /* free handle table */
-    GlobalFree32(ht);
+    GlobalFree32((HGLOBAL32)ht);
     GlobalUnlock16(hmf);
     return result;
 }
@@ -968,7 +968,7 @@
   PlayMetaFileRecord16(hdc, ht, metarecord, handles);
   for (i=0; i<handles; i++) 
     handletable->objectHandle[i] = ht->objectHandle[i];
-  GlobalFree32(ht);
+  GlobalFree32((HGLOBAL32)ht);
   return TRUE;
 }
 
@@ -1060,7 +1060,7 @@
   if (!h) return 0;  /* FIXME: error code */
   if (!buf) {
     GlobalUnlock16(hmf);
-    TRACE(metafile,"returning size %d\n", h->mtSize);
+    TRACE(metafile,"returning size %ld\n", h->mtSize);
     return h->mtSize;
   }
   memmove(buf, h, MIN(nSize, h->mtSize));
diff --git a/objects/oembitmap.c b/objects/oembitmap.c
index 9f2cd4b..862ec52 100644
--- a/objects/oembitmap.c
+++ b/objects/oembitmap.c
@@ -335,7 +335,7 @@
     bmpObjPtr->bitmap.bmWidthBytes = BITMAP_WIDTH_BYTES( width, bpp );
     bmpObjPtr->bitmap.bmPlanes     = 1;
     bmpObjPtr->bitmap.bmBitsPixel  = bpp;
-    bmpObjPtr->bitmap.bmBits       = NULL;
+    bmpObjPtr->bitmap.bmBits       = (SEGPTR)NULL;
     GDI_HEAP_UNLOCK( hbitmap );
     return hbitmap;
 }
diff --git a/objects/palette.c b/objects/palette.c
index e471148..5752cb7 100644
--- a/objects/palette.c
+++ b/objects/palette.c
@@ -126,7 +126,7 @@
     HDC32 hdc) /* [in] Handle to device context */
 {
     FIXME(palette,"(%x): stub\n", hdc);
-    return NULL;
+    return (HPALETTE32)NULL;
 }
 
 
diff --git a/objects/region.c b/objects/region.c
index 9f771ed..a9aee1c 100644
--- a/objects/region.c
+++ b/objects/region.c
@@ -1151,9 +1151,15 @@
     r1End = r1 + reg1->numRects;
     r2End = r2 + reg2->numRects;
     
+
+    /*
+     * newReg may be one of the src regions so we can't empty it. We keep a 
+     * note of its rects pointer (so that we can free them later), preserve its
+     * extents and simply set numRects to zero. 
+     */
+
     oldRects = newReg->rects;
-    
-    EMPTY_REGION(newReg);
+    newReg->numRects = 0;
 
     /*
      * Allocate a reasonable number of rectangles for the new region. The idea
diff --git a/ole/compobj.c b/ole/compobj.c
index ce44806..35eb290 100644
--- a/ole/compobj.c
+++ b/ole/compobj.c
@@ -72,7 +72,7 @@
 }
 
 /***********************************************************************
- *           CoGetMalloc    [COMPOBJ.4]
+ *           CoGetMalloc16    [COMPOBJ.4]
  * RETURNS
  *	The current win16 IMalloc
  */
@@ -87,7 +87,7 @@
 }
 
 /***********************************************************************
- *           CoGetMalloc    (OLE32.4]
+ *           CoGetMalloc32    [OLE32.4]
  * RETURNS
  *	The current win32 IMalloc
  */
diff --git a/ole/ifs.c b/ole/ifs.c
index 2980ed1..157e515 100644
--- a/ole/ifs.c
+++ b/ole/ifs.c
@@ -121,6 +121,8 @@
 	return NULL;
 }
 
+#ifdef OLD_TABLE
+/* FIXME: This is unused */
 static IMalloc16_VTable mvt16 = {
 	IMalloc16_QueryInterface,
 	IMalloc16_AddRef,
@@ -132,6 +134,7 @@
 	IMalloc16_DidAlloc,
 	IMalloc16_HeapMinimize,
 };
+#endif
 static IMalloc16_VTable *msegvt16 = NULL;
 
 LPMALLOC16
diff --git a/ole/ole2.c b/ole/ole2.c
index 577c41d..5bfe3c7 100644
--- a/ole/ole2.c
+++ b/ole/ole2.c
@@ -28,8 +28,14 @@
     return S_OK;
 }
 
+/***********************************************************************
+ * CoGetCurrentProcess [OLE2.2][OLE32.108]
+ *
+ * NOTES
+ *   Is DWORD really the correct return type for this function?
+ */
 DWORD WINAPI CoGetCurrentProcess() {
-	return PROCESS_Current();
+	return (DWORD)PROCESS_Current();
 }
 
 /***********************************************************************
diff --git a/ole/ole2nls.c b/ole/ole2nls.c
index ec8d038..c1d6fca 100644
--- a/ole/ole2nls.c
+++ b/ole/ole2nls.c
@@ -7,7 +7,6 @@
 
 #include <string.h>
 #include <ctype.h>
-#include <stdio.h>
 #include <stdlib.h>
 #include "windows.h"
 #include "heap.h"
@@ -2318,24 +2317,25 @@
    return outpos;
 }
 
-/*  OLE_GetFormatW  [internal]  */
-
+/**************************************************************
+ * OLE_GetFormatW  [internal]  
+ */
 INT32 WINAPI OLE_GetFormatW(LCID locale, DWORD flags,
 			    LPSYSTEMTIME xtime,
 			    LPCWSTR format,
 			    LPWSTR output, INT32 outlen)
 {
    INT32   inpos, outpos;
-   int     count, type, inquote;
+   int     count, type=0, inquote;
    int     Overflow; /* loop check */
    int usedate, usetime;
    WCHAR   buf[40];
-   int     buflen;
+   int     buflen=0;
    char    abuf[40];
    WCHAR   arg0[] = {0}, arg1[] = {'%','d',0};
    WCHAR   arg2[] = {'%','0','2','d',0};
    WCHAR  *argarr[] = {arg0, arg1, arg2};
-   int     datevars, timevars;
+   int     datevars=0, timevars=0;
 
    /* make a debug report */
    lstrcpynWtoA(abuf, format, sizeof(format));
@@ -2716,7 +2716,7 @@
 {
    char debugbuf[40];
    WCHAR buf[20];
-   LPCWSTR realformat;
+   LPCWSTR realformat=0;
    SYSTEMTIME t;
    LPSYSTEMTIME realtime;
    WCHAR * fmt_buf = NULL;
diff --git a/ole/storage.c b/ole/storage.c
index d7fcdc6..04dfd3f 100644
--- a/ole/storage.c
+++ b/ole/storage.c
@@ -282,7 +282,8 @@
 	return -1;
 }
 
-static void
+/* FIXME: Function is unused */
+void
 STORAGE_dump_pps_entry(struct storage_pps_entry *stde) {
 	char	name[33],xguid[50];
 
@@ -1102,7 +1103,7 @@
 	TRACE(ole,"(%p)->(%p,0x%08lx)\n",
 		this,pstatstg,grfStatFlag
 	);
-	pstatstg->pwcsName=SEGPTR_GET(SEGPTR_STRDUP_WtoA(this->stde.pps_rawname));
+	pstatstg->pwcsName=(LPOLESTR16)SEGPTR_GET(SEGPTR_STRDUP_WtoA(this->stde.pps_rawname));
 	pstatstg->type = this->stde.pps_type;
 	pstatstg->cbSize.LowPart = this->stde.pps_size;
 	pstatstg->mtime = this->stde.pps_ft1; /* FIXME */ /* why? */
diff --git a/ole/typelib.c b/ole/typelib.c
index 9e529fe..0f674ab 100644
--- a/ole/typelib.c
+++ b/ole/typelib.c
@@ -43,7 +43,7 @@
 		);
 	} else {
 		sprintf(xguid,"<guid 0x%08lx>",(DWORD)guid);
-		FIXME(ole,"(%s,%d,%d,0x%04x,%p),can't handle non-string guids.\n",xguid,wMaj,wMin,lcid,path);
+		FIXME(ole,"(%s,%d,%d,0x%04x,%p),can't handle non-string guids.\n",xguid,wMaj,wMin,(DWORD)lcid,path);
 		return E_FAIL;
 	}
 	plen = sizeof(pathname);
@@ -80,7 +80,7 @@
 		);
 	} 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%04x,%p),stub!\n",xguid,wMaj,wMin,(DWORD)lcid,path);
 		return E_FAIL;
 	}
 	plen = sizeof(pathname);
diff --git a/programs/Makefile.in b/programs/Makefile.in
index 653c7f3..aaf3c7c 100644
--- a/programs/Makefile.in
+++ b/programs/Makefile.in
@@ -2,6 +2,7 @@
 	clock \
 	notepad \
 	progman \
+	regtest \
 	view \
 	winhelp \
 	winver
diff --git a/programs/notepad/ChangeLog b/programs/notepad/ChangeLog
index 2c2987b..ba72d95 100644
--- a/programs/notepad/ChangeLog
+++ b/programs/notepad/ChangeLog
@@ -1,35 +1,45 @@
+Fri May 15 23:59:22 1998  Marcel Baur <mbaur@g26.ethz.ch>
+        * Date/Time now uses locale-specific formats
+        * Language-specific window caption, displays file being edited.
+        * Started with parsing of command line settings
+        * Started with DoOpenFile, DoCloseFile, DoSaveFile logics
+        * Prompt user to save settings when closing a file
+          -> Introduced a new message box (not yet finished)
+        * Fixed minor features (missing IDS in main.h, ...)
+
 Sun Mar 29 20:29:41 1998  Laurent Buffler <laurent@bluewin.ch>
-	* [Fr.rc]
-	Added French language support.
+        * [Fr.rc]
+        Added French language support.
 
 Fri Feb 27 21:03:37 1998  Karl Backström <karl_b@geocities.com>
-	* Fixed some minor features.
+        * Fixed some minor features.
 
 Sat Feb 14 17:42:29 1998  Karl Backström <karl_b@geocities.com>
         * NEW [language.c] [language.h]
-	Takes care of all language related stuff.
-	A new [programs] in .winerc is in use.
+        Takes care of all language related stuff.
+        A new [programs] in .winerc is in use.
 
 Tue Feb 10 23:34:08 1998  Marcel Baur <mbaur@g26.ethz.ch>
         * Fixed broken language menus
 
 Fri Feb 06 23.54.35 1998  Karl Backström <karl_b@geocities.com>
-	* [main.c] [main.h] [notepad.rc]
-	Fixed language support for menus.     
-	* NEW [dialog.c] [dialog.h]
-	Moved all menu and dialog related stuff here.
+        * [main.c] [main.h] [notepad.rc]
+        Fixed language support for menus.     
+        * NEW [dialog.c] [dialog.h]
+        Moved all menu and dialog related stuff here.
 
 Sun Jan 18 23:05:04 1998  Karl Backström <karl_b@geocities.com>
-	* [Sw.rc]
-	Added/updated Swedish language support.
+        * [Sw.rc]
+        Added/updated Swedish language support.
 
 Tue Dec 23 23:35:04 1997  Marcel Baur <mbaur@g26.ethz.ch>
-       * Fixed lots of bugs w/ resources in *.rc
-       * moved [notepad.c] into [main.c]
-       * moved [notepad.h] into [main.h]
+        * Fixed lots of bugs w/ resources in *.rc
+        * moved [notepad.c] into [main.c]
+        * moved [notepad.h] into [main.h]
        
 Fri Dec 05 20:51:55 1997  Marcel Baur <mbaur@g26.ethz.ch>
-       * [notepad.c] [notepad.h] [notepad.rc] [En.rc] [De.rc]
-         [license.c] [license.h] [License_En.c]
-         [README] [TODO] [ChangeLog]
-         Originals by Marcel Baur
+        * [notepad.c] [notepad.h] [notepad.rc] [En.rc] [De.rc]
+          [license.c] [license.h] [License_En.c]
+          [README] [TODO] [ChangeLog]
+          Originals by Marcel Baur
+
diff --git a/programs/notepad/TODO b/programs/notepad/TODO
index c7a2bc3..27e8fff 100644
--- a/programs/notepad/TODO
+++ b/programs/notepad/TODO
@@ -1,6 +1,19 @@
 
  - Logfile feature
+   if Notepad opens a file with ".LOG" (really?) in the first line, the
+   current date/time should automatically be inserted into the last line
+   of the file at startup. This feature is not well documented.
 
  - Notepad segfaults when selecting "Find" button in "Search" dialog.
+   This is probably a problem related to Winelib.
  
+ - There is still something wrong with the 2nd format string of Date/Time.
+   With some languages, twice the date is printed (instead of time).
+   Other languages, such as french do not support any locales -> annoying.
+
+ - Page Setup dialog box should exchange strings with the corresponding
+   Globals.szMargin???-strings (needed to evaluate strings when printing)
+   
+ - Fields in "Page Setup" dialog box should be initialized.
+   
  - create new *.rc files for all languages you know.
diff --git a/programs/notepad/dialog.c b/programs/notepad/dialog.c
index 62790d8..1721dcd 100644
--- a/programs/notepad/dialog.c
+++ b/programs/notepad/dialog.c
@@ -7,261 +7,386 @@
 #include <stdio.h>
 #include "windows.h"
 #include "commdlg.h"
+#include "winnls.h"
+#include "winerror.h"
 #ifdef WINELIB
 #include "shell.h"
 #include "options.h"
 #endif
 #include "main.h"
 #include "license.h"
+#include "language.h"
 #include "dialog.h"
 #include "version.h"
 #include "debug.h"
 
+
 static LRESULT DIALOG_PAGESETUP_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
 
+
+int AlertIDS(UINT ids_message, UINT ids_caption, WORD type) {
+/*
+ * Given some ids strings, this acts as a language-aware wrapper for 
+ * "MessageBox"
+ */
+   CHAR szMessage[MAX_STRING_LEN];
+   CHAR szCaption[MAX_STRING_LEN];
+   
+   LoadString(Globals.hInstance, ids_message, szMessage, sizeof(szMessage));
+   LoadString(Globals.hInstance, ids_caption, szCaption, sizeof(szCaption));
+   
+   return (MessageBox(Globals.hMainWnd, szMessage, szCaption, type));
+}
+
+void AlertFileNotFound(LPCSTR szFilename) {
+
+   int nResult;
+   
+   nResult = AlertIDS(IDS_NOTFOUND, IDS_ERROR, 0);
+}
+
+
+VOID AlertOutOfMemory(void) {
+
+   int nResult;
+   
+   nResult = AlertIDS(IDS_OUT_OF_MEMORY, IDS_ERROR, 0);
+   PostQuitMessage(1);
+}
+
+
+BOOL ExistFile(LPCSTR szFilename) {
+/*
+ *  Returns: TRUE  - if "szFileName" exists
+ *           FALSE - if it does not
+ */
+   WIN32_FIND_DATA32A entry;
+   HANDLE32 handle;
+   
+   handle = FindFirstFile32A(szFilename, &entry);
+   
+   return (handle!=INVALID_HANDLE_VALUE32);
+}
+
+VOID DoSaveFile(VOID) {
+   // Really Save the file 
+   
+   // ... (Globals.szFileName);
+}
+
+
+BOOL DoCloseFile(void) {
+// Return value: TRUE  - User agreed to close (both save/don't save)
+//               FALSE - User cancelled close by selecting "Cancel"
+
+   CHAR szMessage[MAX_STRING_LEN];
+   CHAR szCaption[MAX_STRING_LEN];
+
+   INT nResult;
+   
+   if (strlen(Globals.szFileName)>0) {
+
+   // prompt user to save changes
+   
+   // FIXME: The following resources are not yet in the .rc files
+   // szMessage, szCaption show up random values. Please keep these lines!
+   
+//  LoadString(Globals.hInstance, ids_savechanges, szMessage, sizeof(szMessage));
+//  LoadString(Globals.hInstance, ids_savetitle, szCaption, sizeof(szCaption));
+   
+   nResult = MessageBox(Globals.hMainWnd, szMessage, szCaption, MB_YESNOCANCEL);
+
+   switch (nResult) {
+          case IDYES:     DoSaveFile();
+                     break;
+          case IDNO:      break;
+          case IDCANCEL:  return(FALSE);
+                     break;
+                      
+         default:    return(FALSE);
+                     break;
+      }
+      
+    
+  }
+  
+  // Forget file name
+  
+  lstrcpyn(Globals.szFileName, "\0", 1);
+  LANGUAGE_UpdateWindowCaption();
+
+  return(TRUE);
+  
+}
+
+
+void DoOpenFile(LPCSTR szFileName) {
+
+    // Close any files and prompt to save changes
+    if (DoCloseFile) {
+
+        // Open file
+        lstrcpyn(Globals.szFileName, szFileName, strlen(szFileName)+1); 
+        LANGUAGE_UpdateWindowCaption();
+    
+    }
+}
+
+
 VOID DIALOG_FileNew(VOID)
 {
-//  dprintf_fixme(Global, "FileNew() not yet implemented\n");
-  printf("FileNew()\n");
+    // Close any files and promt to save changes
+    if (DoCloseFile()) {
+    
+        // do nothing yet
+    
+    }
 }
 
+
 VOID DIALOG_FileOpen(VOID)
 {
-	  OPENFILENAME openfilename;
-	  CHAR szPath[MAX_PATHNAME_LEN];
-	  CHAR szDir[MAX_PATHNAME_LEN];
-	  CHAR szzFilter[2 * MAX_STRING_LEN + 100];
-	  LPSTR p = szzFilter;
 
-	  LoadString(Globals.hInstance, IDS_TEXT_FILES_TXT, p, MAX_STRING_LEN);
-	  p += strlen(p) + 1;
-	  lstrcpy(p, "*.txt");
-	  p += strlen(p) + 1;
-	  LoadString(Globals.hInstance, IDS_ALL_FILES, p, MAX_STRING_LEN);
-	  p += strlen(p) + 1;
-	  lstrcpy(p, "*.*");
-	  p += strlen(p) + 1;
-	  *p = '\0';
+        OPENFILENAME openfilename;
+        CHAR szPath[MAX_PATHNAME_LEN];
+        CHAR szDir[MAX_PATHNAME_LEN];
+        CHAR szzFilter[2 * MAX_STRING_LEN + 100];
+        LPSTR p = szzFilter;
 
-	  GetWindowsDirectory(szDir, sizeof(szDir));
+        LoadString(Globals.hInstance, IDS_TEXT_FILES_TXT, p, MAX_STRING_LEN);
+        p += strlen(p) + 1;
+        lstrcpy(p, "*.txt");
+        p += strlen(p) + 1;
+        LoadString(Globals.hInstance, IDS_ALL_FILES, p, MAX_STRING_LEN);
+        p += strlen(p) + 1;
+        lstrcpy(p, "*.*");
+        p += strlen(p) + 1;
+        *p = '\0';
 
-	  openfilename.lStructSize       = 0;
-	  openfilename.hwndOwner         = Globals.hMainWnd;
-	  openfilename.hInstance         = Globals.hInstance;
-	  openfilename.lpstrFilter       = szzFilter;
-	  openfilename.lpstrCustomFilter = 0;
-	  openfilename.nMaxCustFilter    = 0;
-	  openfilename.nFilterIndex      = 0;
-	  openfilename.lpstrFile         = szPath;
-	  openfilename.nMaxFile          = sizeof(szPath);
-	  openfilename.lpstrFileTitle    = 0;
-	  openfilename.nMaxFileTitle     = 0;
-	  openfilename.lpstrInitialDir   = szDir;
-	  openfilename.lpstrTitle        = 0;
-	  openfilename.Flags             = 0;
-	  openfilename.nFileOffset       = 0;
-	  openfilename.nFileExtension    = 0;
-	  openfilename.lpstrDefExt       = 0;
-	  openfilename.lCustData         = 0;
-	  openfilename.lpfnHook          = 0;
- 	  openfilename.lpTemplateName    = 0;
+        GetWindowsDirectory(szDir, sizeof(szDir));
 
-  	  if (GetOpenFileName(&openfilename)) {
-            lstrcpyn(Globals.szFileName, openfilename.lpstrFile, 
-                     strlen(openfilename.lpstrFile)+1);
-          printf("OpenFile: %s\n", Globals.szFileName);
-	  }
+        openfilename.lStructSize       = sizeof(openfilename);
+        openfilename.hwndOwner         = Globals.hMainWnd;
+        openfilename.hInstance         = Globals.hInstance;
+        openfilename.lpstrFilter       = szzFilter;
+        openfilename.lpstrCustomFilter = 0;
+        openfilename.nMaxCustFilter    = 0;
+        openfilename.nFilterIndex      = 0;
+        openfilename.lpstrFile         = szPath;
+        openfilename.nMaxFile          = sizeof(szPath);
+        openfilename.lpstrFileTitle    = 0;
+        openfilename.nMaxFileTitle     = 0;
+        openfilename.lpstrInitialDir   = szDir;
+        openfilename.lpstrTitle        = 0;
+        openfilename.Flags             = 0;
+        openfilename.nFileOffset       = 0;
+        openfilename.nFileExtension    = 0;
+        openfilename.lpstrDefExt       = 0;
+        openfilename.lCustData         = 0;
+        openfilename.lpfnHook          = 0;
+        openfilename.lpTemplateName    = 0;
+
+        if (GetOpenFileName(&openfilename)) {
+                
+                if (ExistFile(openfilename.lpstrFile))
+                    DoOpenFile(openfilename.lpstrFile);
+                else 
+                    AlertFileNotFound(openfilename.lpstrFile);
+                    
+        }
+          
 }
 
 VOID DIALOG_FileSave(VOID)
 {
-  fprintf(stderr, "FileSave()\n");
+        fprintf(stderr, "FileSave()\n");
 }
 
 VOID DIALOG_FileSaveAs(VOID)
 {
-          OPENFILENAME saveas;
-          CHAR szPath[MAX_PATHNAME_LEN];
-          CHAR szDir[MAX_PATHNAME_LEN];
-          CHAR szzFilter[2 * MAX_STRING_LEN + 100];
-          LPSTR p = szzFilter;
+        OPENFILENAME saveas;
+        CHAR szPath[MAX_PATHNAME_LEN];
+        CHAR szDir[MAX_PATHNAME_LEN];
+        CHAR szzFilter[2 * MAX_STRING_LEN + 100];
+        LPSTR p = szzFilter;
 
-          LoadString(Globals.hInstance, IDS_TEXT_FILES_TXT, p, MAX_STRING_LEN);
-          p += strlen(p) + 1;
-          lstrcpy(p, "*.txt");
-          p += strlen(p) + 1;
-          LoadString(Globals.hInstance, IDS_ALL_FILES, p, MAX_STRING_LEN);
-          p += strlen(p) + 1;
-          lstrcpy(p, "*.*");
-          p += strlen(p) + 1;
-          *p = '\0';
+        LoadString(Globals.hInstance, IDS_TEXT_FILES_TXT, p, MAX_STRING_LEN);
+        p += strlen(p) + 1;
+        lstrcpy(p, "*.txt");
+        p += strlen(p) + 1;
+        LoadString(Globals.hInstance, IDS_ALL_FILES, p, MAX_STRING_LEN);
+        p += strlen(p) + 1;
+        lstrcpy(p, "*.*");
+        p += strlen(p) + 1;
+        *p = '\0';
 
-          GetWindowsDirectory(szDir, sizeof(szDir));
+        GetWindowsDirectory(szDir, sizeof(szDir));
 
-          saveas.lStructSize       = 0;
-          saveas.hwndOwner         = Globals.hMainWnd;
-          saveas.hInstance         = Globals.hInstance;
-          saveas.lpstrFilter       = szzFilter;
-          saveas.lpstrCustomFilter = 0;
-          saveas.nMaxCustFilter    = 0;
-          saveas.nFilterIndex      = 0;
-          saveas.lpstrFile         = szPath;
-          saveas.nMaxFile          = sizeof(szPath);
-          saveas.lpstrFileTitle    = 0;
-          saveas.nMaxFileTitle     = 0;
-          saveas.lpstrInitialDir   = szDir;
-          saveas.lpstrTitle        = 0;
-          saveas.Flags             = 0;
-          saveas.nFileOffset       = 0;
-          saveas.nFileExtension    = 0;
-          saveas.lpstrDefExt       = 0;
-          saveas.lCustData         = 0;
-          saveas.lpfnHook          = 0;
-          saveas.lpTemplateName    = 0;
+        saveas.lStructSize       = 0;
+        saveas.hwndOwner         = Globals.hMainWnd;
+        saveas.hInstance         = Globals.hInstance;
+        saveas.lpstrFilter       = szzFilter;
+        saveas.lpstrCustomFilter = 0;
+        saveas.nMaxCustFilter    = 0;
+        saveas.nFilterIndex      = 0;
+        saveas.lpstrFile         = szPath;
+        saveas.nMaxFile          = sizeof(szPath);
+        saveas.lpstrFileTitle    = 0;
+        saveas.nMaxFileTitle     = 0;
+        saveas.lpstrInitialDir   = szDir;
+        saveas.lpstrTitle        = 0;
+        saveas.Flags             = 0;
+        saveas.nFileOffset       = 0;
+        saveas.nFileExtension    = 0;
+        saveas.lpstrDefExt       = 0;
+        saveas.lCustData         = 0;
+        saveas.lpfnHook          = 0;
+        saveas.lpTemplateName    = 0;
 
-          if (GetSaveFileName(&saveas)) {
+        if (GetSaveFileName(&saveas)) {
             lstrcpyn(Globals.szFileName, saveas.lpstrFile, 
-                     strlen(saveas.lpstrFile)+1);
-            printf("SaveAs(%s)\n", Globals.szFileName);
-          }
+            strlen(saveas.lpstrFile)+1);
+            LANGUAGE_UpdateWindowCaption();
+            DIALOG_FileSave();
+        }
 }
 
 VOID DIALOG_FilePrint(VOID)
 {
-	PRINTDLG printer;
-	printer.lStructSize           = sizeof(printer);
+        PRINTDLG printer;
+        printer.lStructSize           = sizeof(printer);
         printer.hwndOwner             = Globals.hMainWnd;
         printer.hInstance             = Globals.hInstance;
         printer.hDevMode              = 0;
-	printer.hDevNames             = 0;
-	printer.hDC                   = 0;
+        printer.hDevNames             = 0;
+        printer.hDC                   = 0;
         printer.Flags                 = 0;
-	printer.nFromPage             = 0;
+        printer.nFromPage             = 0;
         printer.nToPage               = 0;
-	printer.nMinPage              = 0;
-	printer.nMaxPage              = 0;
-	printer.nCopies               = 0;
-	printer.lCustData             = 0;
-	printer.lpfnPrintHook       = 0;
-	printer.lpfnSetupHook         = 0;
-	printer.lpPrintTemplateName   = 0;
-	printer.lpSetupTemplateName   = 0;
-	printer.hPrintTemplate        = 0;
-	printer.hSetupTemplate        = 0;
-	
-	if(PrintDlg16(&printer)) {
-          /* do nothing */
+        printer.nMinPage              = 0;
+        printer.nMaxPage              = 0;
+        printer.nCopies               = 0;
+        printer.lCustData             = 0;
+        printer.lpfnPrintHook         = 0;
+        printer.lpfnSetupHook         = 0;
+        printer.lpPrintTemplateName   = 0;
+        printer.lpSetupTemplateName   = 0;
+        printer.hPrintTemplate        = 0;
+        printer.hSetupTemplate        = 0;
+        
+        if (PrintDlg16(&printer)) {
+            // do nothing
         };
 }
 
 VOID DIALOG_FilePageSetup(VOID)
 {
-  DIALOG_PageSetup();
+        DIALOG_PageSetup();
 }
 
 VOID DIALOG_FilePrinterSetup(VOID)
 {
-  fprintf(stderr, "FilePrinterSetup()\n");
+        fprintf(stderr, "FilePrinterSetup()\n");
 }
 
 VOID DIALOG_FileExit(VOID)
 {
-  PostQuitMessage(0);
+        if (DoCloseFile()) {
+               PostQuitMessage(0);
+        }
 }
 
 VOID DIALOG_EditUndo(VOID)
 {
-  fprintf(stderr, "EditUndo()\n");
+        fprintf(stderr, "EditUndo()\n");
 }
 
 VOID DIALOG_EditCut(VOID)
 {
-  fprintf(stderr, "EditCut()\n");
+        fprintf(stderr, "EditCut()\n");
 }
 
 VOID DIALOG_EditCopy(VOID)
 {
-  fprintf(stderr, "EditCopy()\n");
+        fprintf(stderr, "EditCopy()\n");
 }
 
 VOID DIALOG_EditPaste(VOID)
 {
-  fprintf(stderr, "EditPaste()\n");
+        fprintf(stderr, "EditPaste()\n");
 }
 
 VOID DIALOG_EditDelete(VOID)
 {
-  fprintf(stderr, "EditDelete()\n");
+        fprintf(stderr, "EditDelete()\n");
 }
 
 VOID DIALOG_EditSelectAll(VOID)
 {
-   fprintf(stderr, "EditSelectAll()\n");
+        fprintf(stderr, "EditSelectAll()\n");
 }
 
 VOID DIALOG_EditTimeDate(VOID)
 {
-  DIALOG_TimeDate();   
+        DIALOG_TimeDate();   
 }
 
 VOID DIALOG_EditWrap(VOID)
 {
-  Globals.bWrapLongLines = !Globals.bWrapLongLines;
-	CheckMenuItem(Globals.hEditMenu, NP_EDIT_WRAP, MF_BYCOMMAND | 
+        Globals.bWrapLongLines = !Globals.bWrapLongLines;
+        CheckMenuItem(Globals.hEditMenu, NP_EDIT_WRAP, MF_BYCOMMAND | 
         (Globals.bWrapLongLines ? MF_CHECKED : MF_UNCHECKED));
 }
 
 VOID DIALOG_Search(VOID)
 {
-          FINDREPLACE find;
-	  CHAR szFind[MAX_PATHNAME_LEN];
+        FINDREPLACE find;
+        CHAR szFind[MAX_PATHNAME_LEN];
           
-          lstrcpyn(szFind, Globals.szFindText, strlen(Globals.szFindText)+1);
+        lstrcpyn(szFind, Globals.szFindText, strlen(Globals.szFindText)+1);
           
-	  find.lStructSize               = 0;
-          find.hwndOwner                 = Globals.hMainWnd;
-          find.hInstance                 = Globals.hInstance;
-          find.lpstrFindWhat             = szFind;
-          find.wFindWhatLen              = sizeof(szFind);
-          find.Flags                     = 0;
-          find.lCustData                 = 0;
-          find.lpfnHook                  = 0;
-          find.lpTemplateName            = 0;
+        find.lStructSize      = sizeof(find);
+        find.hwndOwner        = Globals.hMainWnd;
+        find.hInstance        = Globals.hInstance;
+        find.lpstrFindWhat    = szFind;
+        find.wFindWhatLen     = sizeof(szFind);
+        find.Flags            = 0;
+        find.lCustData        = 0;
+        find.lpfnHook         = 0;
+        find.lpTemplateName   = 0;
 
-	  if (FindText(&find)) {
+        if (FindText(&find)) {
              lstrcpyn(Globals.szFindText, szFind, strlen(szFind)+1);
-          } 
+        } 
              else 
-          { 
-             /* do nothing */ 
-          };
+        { 
+             // do nothing yet
+        };
 }
 
 VOID DIALOG_SearchNext(VOID)
 {
-  fprintf(stderr, "SearchNext()\n");
+        fprintf(stderr, "SearchNext()\n");
 }
 
 VOID DIALOG_HelpContents(VOID)
 {
-  printf("NP_HELP_CONTENTS\n");
-  WinHelp(Globals.hMainWnd, HELPFILE, HELP_INDEX, 0);
+        WinHelp(Globals.hMainWnd, HELPFILE, HELP_INDEX, 0);
 }
 
 VOID DIALOG_HelpSearch(VOID)
 {
-  fprintf(stderr, "HelpSearch()\n");
+        fprintf(stderr, "HelpSearch()\n");
 }
 
 VOID DIALOG_HelpHelp(VOID)
 {
-  printf("NP_HELP_ON_HELP\n");
-  WinHelp(Globals.hMainWnd, HELPFILE, HELP_HELPONHELP, 0);
+        WinHelp(Globals.hMainWnd, HELPFILE, HELP_HELPONHELP, 0);
 }
 
 VOID DIALOG_HelpLicense(VOID)
 {
-  WineLicense(Globals.hMainWnd, Globals.lpszLanguage);
+        WineLicense(Globals.hMainWnd, Globals.lpszLanguage);
 }
 
 VOID DIALOG_HelpNoWarranty(VOID)
@@ -271,7 +396,7 @@
 
 VOID DIALOG_HelpAboutWine(VOID)
 {
-  ShellAbout(Globals.hMainWnd, "Notepad", "Notepad\n" WINE_RELEASE_INFO, 0);
+        ShellAbout(Globals.hMainWnd, "Notepad", "Notepad\n" WINE_RELEASE_INFO, 0);
 }
 
 /***********************************************************************
@@ -282,8 +407,7 @@
 VOID DIALOG_PageSetup(VOID)
 {
   WNDPROC lpfnDlg = MakeProcInstance(DIALOG_PAGESETUP_DlgProc, Globals.hInstance);
-  DialogBox(Globals.hInstance,  STRING_PAGESETUP_Xx,
-	    Globals.hMainWnd, lpfnDlg);
+  DialogBox(Globals.hInstance, STRING_PAGESETUP_Xx, Globals.hMainWnd, lpfnDlg);
   FreeProcInstance(lpfnDlg);
 }
 
@@ -294,17 +418,22 @@
 
 VOID DIALOG_TimeDate(VOID)
 {
-  SYSTEMTIME st;
-   int H, Min, Y, M, D;
-   GetLocalTime(&st);
-   H = st.wHour; Min = st.wMinute; Y  = st.wYear; M = st.wMonth; D = st.wDay;
-   printf("TimeDate=%i:", H);
-   if (Min < 10) printf("0");
-   printf("%i  %i/", Min, Y);
-   if (M < 10) printf("0");
-   printf("%i/", M);
-   if (D < 10) printf("0");
-   printf("%i\n", D);
+  // uses [KERNEL32.310] (ole2nls.c)
+  
+  SYSTEMTIME   st;
+  LPSYSTEMTIME lpst = &st;
+  CHAR         szDate[MAX_STRING_LEN];
+  LPSTR        date = szDate;
+  
+  GetLocalTime(&st);
+  GetDateFormat(LOCALE_USER_DEFAULT, LOCALE_SLONGDATE, lpst, NULL, date, MAX_STRING_LEN);
+  
+  printf("Date: %s\n", date);
+  
+  GetDateFormat(LOCALE_USER_DEFAULT, LOCALE_STIMEFORMAT, lpst, NULL, date, MAX_STRING_LEN);
+  
+  printf("Time: %s\n", date);
+
 }
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
@@ -318,15 +447,15 @@
     {
     case WM_COMMAND:
       switch (wParam)
-	{
-	case IDOK:
-	  EndDialog(hDlg, IDOK);
-	  return TRUE;
+        {
+        case IDOK:
+          EndDialog(hDlg, IDOK);
+          return TRUE;
 
-	case IDCANCEL:
-	  EndDialog(hDlg, IDCANCEL);
-	  return TRUE;
-	}
+        case IDCANCEL:
+          EndDialog(hDlg, IDCANCEL);
+          return TRUE;
+        }
     }
   return FALSE;
 }
diff --git a/programs/notepad/language.c b/programs/notepad/language.c
index 39f1746..854053d 100644
--- a/programs/notepad/language.c
+++ b/programs/notepad/language.c
@@ -16,6 +16,35 @@
 CHAR STRING_MENU_Xx[]      = "MENU_Xx";
 CHAR STRING_PAGESETUP_Xx[] = "DIALOG_PAGESETUP_Xx";
 
+void LANGUAGE_UpdateWindowCaption(void) {
+  /* Sets the caption of the main window according to Globals.szFileName:
+      Notepad - (untitled)      if no file is open
+      Notepad - [filename]      if a file is given
+  */
+  
+  CHAR szCaption[MAX_STRING_LEN];
+  CHAR szUntitled[MAX_STRING_LEN];
+
+  LoadString(Globals.hInstance, IDS_NOTEPAD, szCaption, sizeof(szCaption));
+  
+  if (strlen(Globals.szFileName)>0) {
+      lstrcat(szCaption, " - [");
+      lstrcat(szCaption, Globals.szFileName);
+      lstrcat(szCaption, "]");
+  }
+  else
+  {
+      LoadString(Globals.hInstance, IDS_UNTITLED, szUntitled, sizeof(szUntitled));
+      lstrcat(szCaption, " - ");
+      lstrcat(szCaption, szUntitled);
+  }
+    
+  SetWindowText(Globals.hMainWnd, szCaption);
+  
+}
+
+
+
 static BOOL LANGUAGE_LoadStringOther(UINT num, UINT ids, LPSTR str, UINT len)
 {
   ids -= Globals.wStringTableOffset;
@@ -23,6 +52,8 @@
   return(LoadString(Globals.hInstance, ids, str, len));
 };
 
+
+
 VOID LANGUAGE_SelectByName(LPCSTR lang)
 {
   INT i;
@@ -30,18 +61,18 @@
 
   for (i = 0; i <= MAX_LANGUAGE_NUMBER; i++)
     if (LANGUAGE_LoadStringOther(i, IDS_LANGUAGE_ID, newlang, sizeof(newlang)) &&
-	!lstrcmp(lang, newlang))
+        !lstrcmp(lang, newlang))
       {
         LANGUAGE_SelectByNumber(i);
-	return;
+        return;
       }
 
   /* Fallback */
     for (i = 0; i <= MAX_LANGUAGE_NUMBER; i++)
     if (LANGUAGE_LoadStringOther(i, IDS_LANGUAGE_ID, newlang, sizeof(newlang)))
       {
-	LANGUAGE_SelectByNumber(i);
-	return;
+        LANGUAGE_SelectByNumber(i);
+        return;
       }
 
   MessageBox(Globals.hMainWnd, "No language found", "FATAL ERROR", MB_OK);
@@ -52,7 +83,6 @@
 {
   INT    i;
   CHAR   lang[3];
-  CHAR   caption[MAX_STRING_LEN];
   CHAR   item[MAX_STRING_LEN];
   HMENU  hMainMenu;
 
@@ -64,12 +94,11 @@
   Globals.lpszLanguage = lang;
 
   /* Set frame caption */
-  LoadString(Globals.hInstance, IDS_NOTEPAD, caption, sizeof(caption));
-  SetWindowText(Globals.hMainWnd, caption);
-
+  LANGUAGE_UpdateWindowCaption();
+  
   /* Change Resource names */
-  lstrcpyn(STRING_MENU_Xx    + sizeof(STRING_MENU_Xx)    - 3, lang, 3);
-  lstrcpyn(STRING_PAGESETUP_Xx    + sizeof(STRING_PAGESETUP_Xx)    - 3, lang, 3);
+  lstrcpyn(STRING_MENU_Xx      + sizeof(STRING_MENU_Xx)      - 3, lang, 3);
+  lstrcpyn(STRING_PAGESETUP_Xx + sizeof(STRING_PAGESETUP_Xx) - 3, lang, 3);
 
   /* Create menu */
   hMainMenu = LoadMenu(Globals.hInstance, STRING_MENU_Xx);
@@ -85,7 +114,7 @@
   for (i = 0; i <= MAX_LANGUAGE_NUMBER; i++)
     if (LANGUAGE_LoadStringOther(i, IDS_LANGUAGE_MENU_ITEM, item, sizeof(item)))
       AppendMenu(Globals.hLanguageMenu, MF_STRING | MF_BYCOMMAND,
-		 NP_FIRST_LANGUAGE + i, item);
+                 NP_FIRST_LANGUAGE + i, item);
 
   SetMenu(Globals.hMainWnd, hMainMenu);
 
@@ -125,3 +154,4 @@
 /* Local Variables:    */
 /* c-file-style: "GNU" */
 /* End:                */
+
diff --git a/programs/notepad/language.h b/programs/notepad/language.h
index 848c4f4..3515d68 100644
--- a/programs/notepad/language.h
+++ b/programs/notepad/language.h
@@ -5,6 +5,7 @@
  * Copyright 1998 Karl Backström <karl_b@geocities.com>
  */
 
+VOID LANGUAGE_UpdateWindowCaption(VOID);
 VOID LANGUAGE_SelectByNumber(UINT num);
 VOID LANGUAGE_SelectByName(LPCSTR lang);
 VOID LANGUAGE_DefaultHandle(WPARAM wParam);
diff --git a/programs/notepad/license.h b/programs/notepad/license.h
index 20fac2e..82ad054 100644
--- a/programs/notepad/license.h
+++ b/programs/notepad/license.h
@@ -31,6 +31,6 @@
 extern LICENSE WineLicense_No;
 extern LICENSE WineLicense_Pl;
 extern LICENSE WineLicense_Po;
-extern LICENSE WineLicense_Va;
 extern LICENSE WineLicense_Sw;
+extern LICENSE WineLicense_Va;
 */
diff --git a/programs/notepad/main.c b/programs/notepad/main.c
index 8cd5fcd..b737c72 100644
--- a/programs/notepad/main.c
+++ b/programs/notepad/main.c
@@ -80,12 +80,12 @@
     switch (msg) {
 
        case WM_CREATE:
-   	break;
+        break;
 
        case WM_PAINT:
           BeginPaint(hWnd, &ps);
           EndPaint(hWnd, &ps);
-   	break;
+        break;
 
        case WM_COMMAND:
           NOTEPAD_MenuCommand(wParam);
@@ -136,38 +136,68 @@
     if (!Globals.hMainIcon) Globals.hMainIcon = 
                                   LoadIcon(0, MAKEINTRESOURCE(DEFAULTICON));
 
-    lstrcpyn(Globals.szFindText, "\0", 1);
-    lstrcpyn(Globals.szFileName, "\0", 1);
+    lstrcpyn(Globals.szFindText,     "\0", 1);
+    lstrcpyn(Globals.szFileName,     "\0", 1);
+    lstrcpyn(Globals.szMarginTop,    "\0", 1);
+    lstrcpyn(Globals.szMarginBottom, "\0", 1);
+    lstrcpyn(Globals.szMarginLeft,   "\0", 1);
+    lstrcpyn(Globals.szMarginRight,  "\0", 1);
+    lstrcpyn(Globals.szHeader,       "\0", 1);
+    lstrcpyn(Globals.szFooter,       "\0", 1);
 
     if (!prev){
-	class.style         = CS_HREDRAW | CS_VREDRAW;
-	class.lpfnWndProc   = NOTEPAD_WndProc;
-	class.cbClsExtra    = 0;
-	class.cbWndExtra    = 0;
-	class.hInstance     = Globals.hInstance;
-	class.hIcon         = LoadIcon (0, IDI_APPLICATION);
-	class.hCursor       = LoadCursor (0, IDC_ARROW);
-	class.hbrBackground = GetStockObject (WHITE_BRUSH);
-	class.lpszMenuName  = 0;
-	class.lpszClassName = className;
+        class.style         = CS_HREDRAW | CS_VREDRAW;
+        class.lpfnWndProc   = NOTEPAD_WndProc;
+        class.cbClsExtra    = 0;
+        class.cbWndExtra    = 0;
+        class.hInstance     = Globals.hInstance;
+        class.hIcon         = LoadIcon (0, IDI_APPLICATION);
+        class.hCursor       = LoadCursor (0, IDC_ARROW);
+        class.hbrBackground = GetStockObject (WHITE_BRUSH);
+        class.lpszMenuName  = 0;
+        class.lpszClassName = className;
     }
 
     if (!RegisterClass (&class))
-	return FALSE;
+        return FALSE;
 
     Globals.hMainWnd = CreateWindow (className, winName, WS_OVERLAPPEDWINDOW,
-			CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 
-			LoadMenu(Globals.hInstance, STRING_MENU_Xx),
-			Globals.hInstance, 0);
+                        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 
+                        LoadMenu(Globals.hInstance, STRING_MENU_Xx),
+                        Globals.hInstance, 0);
 
     LANGUAGE_SelectByName(Globals.lpszLanguage);
 
-    SetMenu(Globals.hMainWnd, Globals.hMainMenu);		
-			
+    SetMenu(Globals.hMainWnd, Globals.hMainMenu);               
+                        
     ShowWindow (Globals.hMainWnd, show);
     UpdateWindow (Globals.hMainWnd);
 
+    // now handle command line
+    
+    while (*cmdline && (*cmdline == ' ' || *cmdline == '-')) 
+    
+    {
+        CHAR   option;
+        LPCSTR topic_id;
 
+        if (*cmdline++ == ' ') continue;
+
+        option = *cmdline;
+        if (option) cmdline++;
+        while (*cmdline && *cmdline == ' ') cmdline++;
+
+        switch(option)
+        {
+            case 'p':
+            case 'P': printf("Print file: ");
+                      // Not yet able to print a file
+                      break;
+        }
+    }
+
+    
+    
     while (GetMessage (&msg, 0, 0, 0)) {
         TranslateMessage (&msg);
         DispatchMessage (&msg);
@@ -178,3 +208,4 @@
 /* Local Variables:    */
 /* c-file-style: "GNU" */
 /* End:                */
+
diff --git a/programs/notepad/main.h b/programs/notepad/main.h
index 7c76b30..6bb3763 100644
--- a/programs/notepad/main.h
+++ b/programs/notepad/main.h
@@ -33,6 +33,12 @@
   BOOL    bWrapLongLines;
   CHAR    szFindText[MAX_PATHNAME_LEN];
   CHAR    szFileName[MAX_PATHNAME_LEN];
+  CHAR    szMarginTop[MAX_PATHNAME_LEN];
+  CHAR    szMarginBottom[MAX_PATHNAME_LEN];
+  CHAR    szMarginLeft[MAX_PATHNAME_LEN];
+  CHAR    szMarginRight[MAX_PATHNAME_LEN];
+  CHAR    szHeader[MAX_PATHNAME_LEN];
+  CHAR    szFooter[MAX_PATHNAME_LEN];
 } NOTEPAD_GLOBALS;
 
 extern NOTEPAD_GLOBALS Globals;
@@ -54,18 +60,19 @@
 #endif
 
 /* string table index */
-#define IDS_LANGUAGE_ID                	STRINGID(00)
-#define IDS_LANGUAGE_MENU_ITEM         	STRINGID(01)
-#define IDS_NOTEPAD                    	STRINGID(02)
-#define IDS_TEXT_FILES_TXT	       	STRINGID(03)
-#define IDS_ALL_FILES                  	STRINGID(04)
-#define IDS_ERROR			STRINGID(05)
-#define IDS_WARNING			STRINGID(06)
-#define IDS_INFO			STRINGID(07)
-#define IDS_TOOLARGE			STRINGID(08)
-#define IDS_NOTEXT			STRINGID(09)
-#define IDS_NOTFOUND			STRINGID(0A)
-#define IDS_OUT_OF_MEMORY		STRINGID(0B)
+#define IDS_LANGUAGE_ID                 STRINGID(00)
+#define IDS_LANGUAGE_MENU_ITEM          STRINGID(01)
+#define IDS_NOTEPAD                     STRINGID(02)
+#define IDS_TEXT_FILES_TXT              STRINGID(03)
+#define IDS_ALL_FILES                   STRINGID(04)
+#define IDS_ERROR                       STRINGID(05)
+#define IDS_WARNING                     STRINGID(06)
+#define IDS_INFO                        STRINGID(07)
+#define IDS_TOOLARGE                    STRINGID(08)
+#define IDS_NOTEXT                      STRINGID(09)
+#define IDS_NOTFOUND                    STRINGID(0A)
+#define IDS_OUT_OF_MEMORY               STRINGID(0B)
+#define IDS_UNTITLED                    STRINGID(0C)
 
 /* main menu */
 
@@ -103,20 +110,20 @@
 
 /* Dialog `Page Setup' */
 
-#define NP_PAGESETUP_HEAD	1000
-#define NP_PAGESETUP_HEAD_TXT	1001
-#define NP_PAGESETUP_TAIL	1002
-#define NP_PAGESETUP_TAIL_TXT	1003
+#define NP_PAGESETUP_HEAD       1000
+#define NP_PAGESETUP_HEAD_TXT   1001
+#define NP_PAGESETUP_TAIL       1002
+#define NP_PAGESETUP_TAIL_TXT   1003
 #define NP_PAGESETUP_LEFT       1005
-#define NP_PAGESETUP_LEFT_TXT	1006
-#define NP_PAGESETUP_RIGHT   	1007
-#define NP_PAGESETUP_RIGHT_TXT	1008
-#define NP_PAGESETUP_TOP      	1009
-#define NP_PAGESETUP_TOP_TXT	1010
+#define NP_PAGESETUP_LEFT_TXT   1006
+#define NP_PAGESETUP_RIGHT      1007
+#define NP_PAGESETUP_RIGHT_TXT  1008
+#define NP_PAGESETUP_TOP        1009
+#define NP_PAGESETUP_TOP_TXT    1010
 #define NP_PAGESETUP_BOTTOM     1011
-#define NP_PAGESETUP_BOTTOM_TXT	1012
-#define NP_HELP			1013
-#define NP_PAGESETUP_MARGIN 	1014
+#define NP_PAGESETUP_BOTTOM_TXT 1012
+#define NP_HELP                 1013
+#define NP_PAGESETUP_MARGIN     1014
 
 
 /* Local Variables:    */
diff --git a/programs/notepad/notepad.rc b/programs/notepad/notepad.rc
index 3ff284e..26ade63 100644
--- a/programs/notepad/notepad.rc
+++ b/programs/notepad/notepad.rc
@@ -112,4 +112,5 @@
 ADDSTRING(NOTEXT)
 ADDSTRING(NOTFOUND)
 ADDSTRING(OUT_OF_MEMORY)
+ADDSTRING(UNTITLED)
 }
diff --git a/programs/regtest/ChangeLog b/programs/regtest/ChangeLog
new file mode 100644
index 0000000..ef84110
--- /dev/null
+++ b/programs/regtest/ChangeLog
@@ -0,0 +1,4 @@
+Wed May 13 22:58:05 1997  Matthew Becker <mbecker@glasscity.net>
+
+	* [regtest.c] (new)
+
diff --git a/programs/regtest/Makefile.in b/programs/regtest/Makefile.in
new file mode 100644
index 0000000..0749c8c
--- /dev/null
+++ b/programs/regtest/Makefile.in
@@ -0,0 +1,25 @@
+DEFS      = -DWINELIB
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+MODULE    = none
+PROGRAMS  = regtest
+ALL_LIBS  = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS)
+RCFLAGS   = -w32 -h
+
+C_SRCS = regtest.c
+
+all: $(PROGRAMS)
+
+@MAKE_RULES@
+
+regtest: $(OBJS)
+	$(CC) -o regtest $(OBJS) $(LDOPTIONS) $(ALL_LIBS)
+
+install: dummy
+	$(INSTALL_PROGRAM) regtest $(bindir)/program
+
+dummy:
+
+### Dependencies:
diff --git a/programs/regtest/regtest.c b/programs/regtest/regtest.c
new file mode 100644
index 0000000..f879d9c
--- /dev/null
+++ b/programs/regtest/regtest.c
@@ -0,0 +1,452 @@
+/*
+ * Registry testing program
+ *
+ * The return codes were generated in an NT40 environment, using lcc-win32
+ *
+ * Copyright 1998 by Matthew Becker (mbecker@glasscity.net)
+ *
+*/
+
+#include <stdio.h>
+#include <malloc.h>
+#include <windows.h>
+#include <winreg.h>
+#include <winerror.h>
+
+/*
+ * NOTES: These individual routines are listed in alphabetical order.
+ */
+
+/******************************************************************************
+ * TestCloseKey
+ */
+void TestCloseKey()
+{
+    long lSts;
+    HKEY hkey;
+    fprintf(stderr, "Testing RegCloseKey...\n");
+
+    hkey = (HKEY)0;
+    lSts = RegCloseKey(hkey);
+    if (lSts != ERROR_INVALID_HANDLE) fprintf(stderr, " 1:%ld\n",lSts);
+
+    hkey = (HKEY)-2;
+    lSts = RegCloseKey(hkey);
+    if (lSts != ERROR_INVALID_HANDLE) fprintf(stderr, " 2:%ld\n",lSts);
+
+    lSts = RegCloseKey(HKEY_LOCAL_MACHINE);
+    if (lSts != ERROR_SUCCESS) fprintf(stderr, " 3:%ld\n",lSts);
+
+    lSts = RegCloseKey(HKEY_LOCAL_MACHINE);
+    if (lSts != ERROR_SUCCESS) fprintf(stderr, " 4:%ld\n",lSts);
+}
+
+/******************************************************************************
+ * TestConnectRegistry
+ */
+void TestConnectRegistry()
+{
+    long lSts;
+    HKEY hkey;
+    fprintf(stderr, "Testing RegConnectRegistry...\n");
+
+    lSts = RegConnectRegistry("",0,&hkey);
+    if (lSts != ERROR_SUCCESS) fprintf(stderr, " 1:%ld\n",lSts);
+
+    lSts = RegConnectRegistry("",HKEY_LOCAL_MACHINE,&hkey);
+    if (lSts != ERROR_SUCCESS) fprintf(stderr, " 2:%ld\n",lSts);
+}
+
+/******************************************************************************
+ * TestCreateKey
+ */
+void TestCreateKey()
+{
+    HKEY hKeyIn;
+    long lSts;
+    HKEY hkey;
+
+    fprintf(stderr, "Testing RegCreateKey...\n");
+
+    hKeyIn = (HKEY)1;
+    lSts = RegCreateKey(hKeyIn,"",&hkey);
+    if (lSts != ERROR_BADKEY) fprintf(stderr, " 1:%ld\n",lSts);
+
+    lSts = RegCreateKey(HKEY_LOCAL_MACHINE,"\\asdf",&hkey);
+    if (lSts != ERROR_BAD_PATHNAME) fprintf(stderr, " 2:%ld\n",lSts);
+}
+
+/******************************************************************************
+ * TestCreateKeyEx
+ */
+void TestCreateKeyEx()
+{
+    HKEY hKeyIn;
+    long lSts;
+    HKEY hkey;
+    DWORD dwDisp;
+
+    fprintf(stderr, "Testing RegCreateKeyEx...\n");
+
+    hKeyIn = (HKEY)1;
+    lSts = RegCreateKeyEx(hKeyIn,"",0,"",0,0,NULL,&hkey,&dwDisp);
+    if (lSts != ERROR_SUCCESS) fprintf(stderr, " 1:%ld\n",lSts);
+
+    lSts = RegCreateKeyEx(hKeyIn,"regtest",0,"",0,0,NULL,&hkey,&dwDisp);
+    if (lSts != ERROR_SUCCESS) fprintf(stderr, " 2:%ld\n",lSts);
+
+    lSts = RegCreateKeyEx(hKeyIn,"regtest",0,"asdf",0,KEY_ALL_ACCESS,NULL,&hkey,&dwDisp);
+    if (lSts != ERROR_SUCCESS) fprintf(stderr, " 3:%ld\n",lSts);
+}
+
+/******************************************************************************
+ * TestDeleteKey
+ */
+void TestDeleteKey()
+{
+    long lSts;
+    HKEY hkey;
+    fprintf(stderr, "Testing RegDeleteKey...\n");
+
+    hkey = (HKEY)0;
+    lSts = RegDeleteKey(hkey, "asdf");
+    if (lSts != ERROR_INVALID_HANDLE) fprintf(stderr, " 1:%ld\n",lSts);
+
+    lSts = RegDeleteKey(HKEY_CURRENT_USER, "asdf");
+    if (lSts != ERROR_FILE_NOT_FOUND) fprintf(stderr, " 2:%ld\n",lSts);
+}
+
+/******************************************************************************
+ * TestDeleteValue
+ */
+void TestDeleteValue()
+{
+    long lSts;
+    HKEY hkey;
+    fprintf(stderr, "Testing RegDeleteValue...\n");
+
+    hkey = (HKEY)0;
+    lSts = RegDeleteValue(hkey, "asdf");
+    if (lSts != ERROR_INVALID_HANDLE) fprintf(stderr, " 1:%ld\n",lSts);
+
+    lSts = RegDeleteValue(HKEY_CURRENT_USER, "asdf");
+    if (lSts != ERROR_FILE_NOT_FOUND) fprintf(stderr, " 2:%ld\n",lSts);
+}
+
+/******************************************************************************
+ * TestEnumKey
+ */
+void TestEnumKey()
+{
+    long lSts;
+    char *sVal;
+    long lVal;
+    HKEY hkey;
+
+    fprintf(stderr, "Testing RegEnumKey...\n");
+    sVal = (char *)malloc(1 * sizeof(char));
+    lVal = sizeof(sVal);
+
+    hkey = (HKEY)0;
+    lSts = RegEnumKey(hkey,3,sVal,lVal);
+    if (lSts != ERROR_INVALID_HANDLE) fprintf(stderr, " 1:%ld\n",lSts);
+
+    lSts = RegEnumKey(HKEY_CURRENT_USER,-1,sVal,lVal);
+    if (lSts != ERROR_NO_MORE_ITEMS) fprintf(stderr, " 2:%ld\n",lSts);
+
+    lSts = RegEnumKey(HKEY_CURRENT_USER,0,sVal,lVal);
+    if (lSts != ERROR_MORE_DATA) fprintf(stderr, " 3:%ld\n",lSts);
+}
+
+/******************************************************************************
+ * TestEnumKeyEx
+ */
+void TestEnumKeyEx()
+{
+    long lSts;
+    char *sVal;
+    char *sClass;
+    unsigned long lLen1;
+    unsigned long lLen2;
+    FILETIME ft;
+
+    fprintf(stderr, "Testing RegEnumKeyEx...\n");
+    sVal = (char *)malloc(80 * sizeof(char));
+    lLen1= sizeof(sVal);
+    sClass = (char *)malloc(10 * sizeof(char));
+    lLen2 = sizeof(sClass);
+
+    lSts = RegEnumKeyEx(0,0,sVal,&lLen1,0,sClass,&lLen2,&ft);
+    if (lSts != ERROR_INVALID_HANDLE) fprintf(stderr, " 1:%ld\n",lSts);
+}
+
+/******************************************************************************
+ * TestEnumValue
+ */
+void TestEnumValue()
+{
+    long lSts;
+    char *sVal;
+    unsigned long lVal;
+    unsigned long lType;
+    unsigned long lLen1;
+    char *bVal;
+    HKEY hkey;
+
+    fprintf(stderr, "Testing RegEnumValue...\n");
+    sVal = (char *)malloc(80 * sizeof(char));
+    bVal = (char *)malloc(80 * sizeof(char));
+    lVal = sizeof(sVal);
+    lLen1 = sizeof(bVal);
+
+    hkey = (HKEY)0;
+    lSts = RegEnumValue(hkey,-1,sVal,&lVal,0,&lType,NULL,&lLen1);
+    if (lSts != ERROR_INVALID_HANDLE) fprintf(stderr, " 1:%ld\n",lSts);
+
+    lSts = RegEnumValue(HKEY_LOCAL_MACHINE,-1,sVal,&lVal,0,&lType,NULL,&lLen1);
+    if (lSts != ERROR_NO_MORE_ITEMS) fprintf(stderr, " 2:%ld\n",lSts);
+
+    lSts = RegEnumValue(HKEY_LOCAL_MACHINE,0,sVal,&lVal,0,&lType,NULL,&lLen1);
+    if (lSts != ERROR_NO_MORE_ITEMS) fprintf(stderr, " 3:%ld\n",lSts);
+
+    lSts = RegEnumValue(HKEY_LOCAL_MACHINE,1,sVal,&lVal,0,&lType,bVal,&lLen1);
+    if (lSts != ERROR_NO_MORE_ITEMS) fprintf(stderr, " 4:%ld\n",lSts);
+}
+
+/******************************************************************************
+ * TestFlushKey
+ */
+void TestFlushKey()
+{
+    long lSts;
+    fprintf(stderr, "Testing RegFlushKey...\n");
+
+    lSts = RegFlushKey(0);
+    if (lSts != ERROR_INVALID_HANDLE) fprintf(stderr, " 1:%ld\n",lSts);
+
+    lSts = RegFlushKey(HKEY_LOCAL_MACHINE);
+    if (lSts != ERROR_SUCCESS) fprintf(stderr, " 2:%ld\n",lSts);
+}
+
+/******************************************************************************
+ * TestGetKeySecurity
+ */
+void TestGetKeySecurity()
+{
+    long lSts;
+    SECURITY_INFORMATION si;
+    SECURITY_DESCRIPTOR sd;
+    unsigned long lLen;
+    HKEY hkey;
+
+    fprintf(stderr, "Testing RegGetKeySecurity...\n");
+    lLen = sizeof(sd);
+
+    hkey = (HKEY)0;
+    lSts = RegGetKeySecurity(hkey,si,&sd,&lLen);
+    if (lSts != ERROR_INVALID_HANDLE) fprintf(stderr, " 1:%ld\n",lSts);
+
+    lSts = RegGetKeySecurity(HKEY_LOCAL_MACHINE,si,&sd,&lLen);
+    if (lSts != ERROR_INSUFFICIENT_BUFFER) fprintf(stderr, " 2:%ld\n",lSts);
+
+#if 0
+    si = GROUP_SECURITY_INFORMATION;
+#endif
+    lSts = RegGetKeySecurity(HKEY_LOCAL_MACHINE,si,&sd,&lLen);
+    if (lSts != ERROR_SUCCESS) fprintf(stderr, " 3:%ld\n",lSts);
+}
+
+/******************************************************************************
+ * TestLoadKey
+ */
+void TestLoadKey()
+{
+    long lSts;
+    fprintf(stderr, "Testing RegLoadKey...\n");
+
+    lSts = RegLoadKey(0,"","");
+    if (lSts != ERROR_INVALID_HANDLE) fprintf(stderr, " 1:%ld\n",lSts);
+
+    lSts = RegLoadKey(HKEY_CURRENT_USER,"","");
+    if (lSts != ERROR_INVALID_PARAMETER) fprintf(stderr, " 2:%ld\n",lSts);
+
+    lSts = RegLoadKey(HKEY_CURRENT_USER,"regtest","");
+    if (lSts != ERROR_INVALID_PARAMETER) fprintf(stderr, " 3:%ld\n",lSts);
+
+    lSts = RegLoadKey(HKEY_CURRENT_USER,"regtest","regtest.dat");
+    if (lSts != ERROR_PRIVILEGE_NOT_HELD) fprintf(stderr, " 4:%ld\n",lSts);
+}
+
+/******************************************************************************
+ * TestNotifyChangeKeyValue
+ */
+void TestNotifyChangeKeyValue()
+{
+    long lSts;
+    HANDLE hEvent;
+    HKEY hkey;
+
+    fprintf(stderr, "Testing RegNotifyChangeKeyValue...\n");
+    hEvent = 0;
+
+    hkey = (HKEY)2;
+    lSts = RegNotifyChangeKeyValue(hkey, TRUE, REG_NOTIFY_CHANGE_NAME, 0, 0);
+    if (lSts != ERROR_INVALID_HANDLE) fprintf(stderr, " 1:%ld\n",lSts);
+
+    lSts = RegNotifyChangeKeyValue(HKEY_CURRENT_USER, TRUE, REG_NOTIFY_CHANGE_NAME, 0, 1);
+    if (lSts != ERROR_INVALID_PARAMETER) fprintf(stderr, " 2:%ld\n",lSts);
+
+    lSts = RegNotifyChangeKeyValue(HKEY_CURRENT_USER, TRUE, REG_NOTIFY_CHANGE_NAME, hEvent, 1);
+    if (lSts != ERROR_INVALID_PARAMETER) fprintf(stderr, " 3:%ld\n",lSts);
+}
+
+/******************************************************************************
+ * TestOpenKey
+ */
+void TestOpenKey()
+{
+    long lSts;
+    HKEY hkey;
+    fprintf(stderr, "Testing RegOpenKey...\n");
+
+    lSts = RegOpenKey(0, "",&hkey);
+    if (lSts != ERROR_SUCCESS) fprintf(stderr, " 1:%ld\n",lSts);
+
+    lSts = RegOpenKey(0, "regtest",&hkey);
+    if (lSts != ERROR_INVALID_HANDLE) fprintf(stderr, " 2:%ld\n",lSts);
+
+    lSts = RegOpenKey(HKEY_CURRENT_USER, "regtest1",&hkey);
+    if (lSts != ERROR_FILE_NOT_FOUND) fprintf(stderr, " 3:%ld\n",lSts);
+
+    lSts = RegOpenKey(HKEY_CURRENT_USER, "\\regtest",&hkey);
+    if (lSts != ERROR_BAD_PATHNAME) fprintf(stderr, " 4:%ld\n",lSts);
+}
+
+/******************************************************************************
+ * TestOpenKeyEx
+ */
+void TestOpenKeyEx()
+{
+    long lSts;
+    HKEY hkeyIn;
+    HKEY hkey;
+    fprintf(stderr, "Testing RegOpenKeyEx...\n");
+
+    hkeyIn = (HKEY)0;
+    lSts = RegOpenKeyEx(hkeyIn,"",0,KEY_ALL_ACCESS,&hkey);
+    if (lSts != ERROR_INVALID_HANDLE) fprintf(stderr, " 1:%ld\n",lSts);
+
+    lSts = RegOpenKeyEx(HKEY_CURRENT_USER,"\\regtest",0,KEY_ALL_ACCESS,&hkey);
+    if (lSts != ERROR_BAD_PATHNAME) fprintf(stderr, " 2:%ld\n",lSts);
+}
+
+/******************************************************************************
+ * TestQueryInfoKey
+ */
+void TestQueryInfoKey()
+{
+    fprintf(stderr, "Testing RegQueryInfoKey...\n");
+}
+
+/******************************************************************************
+ * TestQueryValue
+ */
+void TestQueryValue()
+{
+    long lSts;
+    HKEY hkey;
+    long lLen;
+    char *sVal;
+
+    fprintf(stderr, "Testing RegQueryValue...\n");
+    hkey = (HKEY)0;
+    sVal = (char *)malloc(80 * sizeof(char));
+    lLen = strlen(sVal);
+
+    lSts = RegQueryValue(hkey,"",NULL,&lLen);
+    if (lSts != ERROR_INVALID_HANDLE) fprintf(stderr, " 1:%ld\n",lSts);
+
+    lSts = RegQueryValue(HKEY_CURRENT_USER,"",NULL,&lLen);
+    if (lSts != ERROR_SUCCESS) fprintf(stderr, " 2:%ld\n",lSts);
+
+    lSts = RegQueryValue(HKEY_CURRENT_USER,"\\regtest",NULL,&lLen);
+    if (lSts != ERROR_BAD_PATHNAME) fprintf(stderr, " 3:%ld\n",lSts);
+
+    lSts = RegQueryValue(HKEY_CURRENT_USER,"",sVal,&lLen);
+    if (lSts != ERROR_SUCCESS) fprintf(stderr, " 4:%ld\n",lSts);
+}
+
+/******************************************************************************
+ * TestQueryValueEx
+ */
+void TestQueryValueEx()
+{
+    fprintf(stderr, "Testing RegQueryValueEx...\n");
+}
+
+/******************************************************************************
+ * TestReplaceKey
+ */
+void TestReplaceKey()
+{
+    fprintf(stderr, "Testing RegReplaceKey...\n");
+}
+
+/******************************************************************************
+ * TestRestoreKey
+ */
+void TestRestoreKey()
+{
+    fprintf(stderr, "Testing RegRestoreKey...\n");
+}
+
+void TestSequence1()
+{
+    HKEY hkey;
+    long lSts;
+
+    fprintf(stderr, "Testing Sequence1...\n");
+
+    lSts = RegCreateKey(HKEY_CURRENT_USER,"regtest",&hkey);
+    if (lSts != ERROR_SUCCESS) fprintf(stderr, " 1:%ld\n",lSts);
+}
+
+
+int PASCAL WinMain (HANDLE inst, HANDLE prev, LPSTR cmdline, int show)
+{
+
+    /* These can be in any order */
+    TestCloseKey();
+    TestConnectRegistry();
+    TestCreateKey();
+    TestCreateKeyEx();
+    TestDeleteKey();
+    TestDeleteValue();
+    TestEnumKey();
+    TestEnumKeyEx();
+    TestEnumValue();
+    TestFlushKey();
+    TestGetKeySecurity();
+    TestLoadKey();
+    TestNotifyChangeKeyValue();
+    TestOpenKey();
+    TestOpenKeyEx();
+    TestQueryInfoKey();
+    TestQueryValue();
+    TestQueryValueEx();
+    TestReplaceKey();
+    TestRestoreKey();
+/*
+    TestSaveKey();
+    TestSetKeySecurity();
+    TestSetValue();
+    TestSetValueEx();
+    TestUnloadKey();
+*/
+
+    /* Now we have some sequence testing */
+    TestSequence1();
+
+    return 0;
+}
+
diff --git a/relay32/Makefile.in b/relay32/Makefile.in
index b42f3c4..95fa16c 100644
--- a/relay32/Makefile.in
+++ b/relay32/Makefile.in
@@ -33,6 +33,7 @@
 	w32skrnl.spec \
 	winmm.spec \
 	winspool.spec \
+	wnaspi32.spec \
 	wow32.spec \
 	wsock32.spec
 
diff --git a/relay32/advapi32.spec b/relay32/advapi32.spec
index 53a9508..cadd3aa 100644
--- a/relay32/advapi32.spec
+++ b/relay32/advapi32.spec
@@ -129,7 +129,7 @@
 0125 stub ReadEventLogW
 0126 stdcall RegCloseKey(long) RegCloseKey
 0127 stdcall RegConnectRegistryA(str long ptr) RegConnectRegistry32A
-0128 stub RegConnectRegistryW
+0128 stdcall RegConnectRegistryW(wstr long ptr) RegConnectRegistry32W
 0129 stdcall RegCreateKeyA(long str ptr) RegCreateKey32A
 0130 stdcall RegCreateKeyExA(long str long ptr long long ptr ptr ptr) RegCreateKeyEx32A
 0131 stdcall RegCreateKeyExW(long wstr long ptr long long ptr ptr ptr) RegCreateKeyEx32W
@@ -146,9 +146,9 @@
 0142 stdcall RegEnumValueW(long long ptr ptr ptr ptr ptr ptr) RegEnumValue32W
 0143 stdcall RegFlushKey(long) RegFlushKey
 0144 stdcall RegGetKeySecurity(long long ptr ptr) RegGetKeySecurity
-0145 stub RegLoadKeyA
-0146 stub RegLoadKeyW
-0147 stub RegNotifyChangeKeyValue
+0145 stdcall RegLoadKeyA(long str str) RegLoadKey32A
+0146 stdcall RegLoadKeyW(long wstr wstr) RegLoadKey32W
+0147 stdcall RegNotifyChangeKeyValue(long long long long long) RegNotifyChangeKeyValue
 0148 stdcall RegOpenKeyA(long str ptr) RegOpenKey32A
 0149 stdcall RegOpenKeyExA(long str long long ptr) RegOpenKeyEx32A
 0150 stdcall RegOpenKeyExW(long wstr long long ptr) RegOpenKeyEx32W
diff --git a/relay32/builtin32.c b/relay32/builtin32.c
index 593cc10..ee17a69 100644
--- a/relay32/builtin32.c
+++ b/relay32/builtin32.c
@@ -66,6 +66,7 @@
 extern const BUILTIN32_DESCRIPTOR W32SKRNL_Descriptor;
 extern const BUILTIN32_DESCRIPTOR WINMM_Descriptor;
 extern const BUILTIN32_DESCRIPTOR WINSPOOL_Descriptor;
+extern const BUILTIN32_DESCRIPTOR WNASPI32_Descriptor;
 extern const BUILTIN32_DESCRIPTOR WOW32_Descriptor;
 extern const BUILTIN32_DESCRIPTOR WSOCK32_Descriptor;
 
@@ -98,6 +99,7 @@
     { &W32SKRNL_Descriptor, NULL, TRUE  },
     { &WINMM_Descriptor,    NULL, TRUE  },
     { &WINSPOOL_Descriptor, NULL, TRUE  },
+    { &WNASPI32_Descriptor, NULL, TRUE  },
     { &WOW32_Descriptor,    NULL, TRUE  },
     { &WSOCK32_Descriptor,  NULL, TRUE  },
     /* Last entry */
@@ -289,6 +291,9 @@
     wm->next		= pdb->modref_list;
     pdb->modref_list	= wm;
     wm->modname		= HEAP_strdupA(pdb->heap,0,dll->descr->name);
+    /* FIXME: hmm ... probably add windows directory? don't know ... -MM */
+    wm->shortname	= HEAP_strdupA(pdb->heap,0,wm->modname);
+    wm->longname	= HEAP_strdupA(pdb->heap,0,wm->modname);
 
     pem->pe_export	= exp;
     pem->flags		= PE_MODREF_INTERNAL;
diff --git a/relay32/comctl32.spec b/relay32/comctl32.spec
index 5f3956c..f4448c3 100644
--- a/relay32/comctl32.spec
+++ b/relay32/comctl32.spec
@@ -6,7 +6,7 @@
 #  import comctl32.dll by ordinal)
 #   This list was created from a comctl32.dll v4.72 (IE4.01).
 
-  2 stub MenuHelp
+  2 stdcall MenuHelp(long long long long long long ptr) MenuHelp
   3 stub ShowHideMenuCtl
   4 stub GetEffectiveClientRect
   5 stdcall DrawStatusTextA(long ptr ptr long) DrawStatusText32A
@@ -72,7 +72,6 @@
  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
@@ -88,7 +87,7 @@
  78 stdcall ImageList_SetImageCount(ptr long) ImageList_SetImageCount
  79 stdcall ImageList_SetOverlayImage(ptr long long) ImageList_SetOverlayImage
  80 stub ImageList_Write
- 81 stub InitCommonControlsEx
+ 81 stdcall InitCommonControlsEx(ptr) InitCommonControlsEx
  82 stub InitializeFlatSB
  83 stub PropertySheet
  84 stub PropertySheetA
diff --git a/relay32/comdlg32.spec b/relay32/comdlg32.spec
index 696d149..f3c6223 100644
--- a/relay32/comdlg32.spec
+++ b/relay32/comdlg32.spec
@@ -2,8 +2,8 @@
 type	win32
 
  0 stub ArrowBtnWndProc
- 1 stub ChooseColorA
- 2 stub ChooseColorW
+ 1 stdcall ChooseColorA(ptr) ChooseColor32A
+ 2 stdcall ChooseColorW(ptr) ChooseColor32W
  3 stdcall ChooseFontA(ptr) ChooseFont32A
  4 stdcall ChooseFontW(ptr) ChooseFont32W
  5 stdcall CommDlgExtendedError() CommDlgExtendedError
diff --git a/relay32/crtdll.spec b/relay32/crtdll.spec
index 2c4b15d..84d6025 100644
--- a/relay32/crtdll.spec
+++ b/relay32/crtdll.spec
@@ -38,7 +38,7 @@
  34 stub __threadid
  35 stub __toascii
  36 cdecl _abnormal_termination() CRTDLL__abnormal_termination
- 37 stub _access
+ 37 cdecl _access(str long) CRTDLL__access
  38 extern _acmdln_dll CRTDLL_acmdln_dll
  39 stub _aexit_rtn_dll
  40 stub _amsg_exit
@@ -108,7 +108,7 @@
 104 extern _fmode_dll CRTDLL_fmode_dll
 105 stub _fpclass
 106 stub _fpieee_flt
-107 stub _fpreset
+107 cdecl _fpreset() CRTDLL__fpreset
 108 stub _fputchar
 109 stub _fputwchar
 110 stub _fsopen
@@ -125,7 +125,7 @@
 121 stub _getdcwd
 122 stub _getdiskfree
 123 stub _getdllprocaddr
-124 stub _getdrive
+124 cdecl _getdrive() CRTDLL__getdrive
 125 stub _getdrives
 126 stub _getpid
 127 stub _getsystime
@@ -135,7 +135,7 @@
 131 stub _heapmin
 132 stub _heapset
 133 stub _heapwalk
-134 stub _hypot
+134 cdecl _hypot(double double) hypot
 135 cdecl _initterm(ptr ptr) CRTDLL__initterm
 136 extern _iob CRTDLL_iob
 137 cdecl _isatty(long) CRTDLL__isatty
@@ -168,9 +168,9 @@
 164 stub _isnan
 165 cdecl _itoa(long ptr long) CRTDLL__itoa
 166 stub _itow
-167 stub _j0
-168 stub _j1
-169 stub _jn
+167 cdecl _j0(double) j0
+168 cdecl _j1(double) j1
+169 cdecl _jn(long double) jn
 170 stub _kbhit
 171 stub _lfind
 172 stub _loaddll
@@ -181,7 +181,7 @@
 177 stub _lrotr
 178 stub _lsearch
 179 stub _lseek
-180 stub _ltoa
+180 cdecl _ltoa(long str long) CRTDLL__ltoa
 181 stub _ltow
 182 stub _makepath
 183 stub _matherr
@@ -224,7 +224,7 @@
 220 stub _mbsninc
 221 stub _mbsnset
 222 stub _mbspbrk
-223 stub _mbsrchr
+223 cdecl _mbsrchr(str long) CRTDLL__mbsrchr
 224 stub _mbsrev
 225 stub _mbsset
 226 stub _mbsspn
@@ -352,7 +352,7 @@
 348 cdecl atol(str) atol
 349 stub bsearch
 350 cdecl calloc(long long) CRTDLL_calloc
-351 stub ceil
+351 cdecl ceil(double) ceil
 352 stub clearerr
 353 cdecl clock() CRTDLL_clock
 354 cdecl cos(double) cos
@@ -382,9 +382,9 @@
 378 cdecl free(ptr) CRTDLL_free
 379 stub freopen
 380 cdecl frexp(double ptr) frexp
-381 stub fscanf
+381 varargs fscanf() CRTDLL_fscanf
 382 cdecl fseek(ptr long long) CRTDLL_fseek
-383 stub fsetpos
+383 cdecl fsetpos(ptr ptr) CRTDLL_fsetpos
 384 cdecl ftell(ptr) CRTDLL_ftell
 385 stub fwprintf
 386 cdecl fwrite(ptr long long ptr) CRTDLL_fwrite 
diff --git a/relay32/gdi32.spec b/relay32/gdi32.spec
index a447b8d..576ecb4 100644
--- a/relay32/gdi32.spec
+++ b/relay32/gdi32.spec
@@ -21,7 +21,7 @@
  17 stdcall CloseMetaFile(long) CloseMetaFile32
  18 stub ColorMatchToTarget
  19 stdcall CombineRgn(long long long long) CombineRgn32
- 20 stub CombineTransform
+ 20 stdcall CombineTransform(ptr ptr ptr) CombineTransform
  21 stdcall CopyEnhMetaFileA(long str) CopyEnhMetaFile32A
  22 stub CopyEnhMetaFileW
  23 stdcall CopyMetaFileA(long str) CopyMetaFile32A
@@ -257,7 +257,7 @@
 250 stub LoadImageColorMatcherA
 251 stub LoadImageColorMatcherW
 252 stub MaskBlt
-253 stub ModifyWorldTransform
+253 stdcall ModifyWorldTransform(long ptr long) ModifyWorldTransform
 254 stdcall MoveToEx(long long long ptr) MoveToEx32
 255 stdcall OffsetClipRgn(long long long) OffsetClipRgn32
 256 stdcall OffsetRgn(long long long) OffsetRgn32
diff --git a/relay32/kernel32.spec b/relay32/kernel32.spec
index 5a996b4..5ec21f3 100644
--- a/relay32/kernel32.spec
+++ b/relay32/kernel32.spec
@@ -10,6 +10,7 @@
 # - k32exp.h by Andrew Schulman
 # - error messages and strings from the debug version of kernel32.dll
 # - code generated by the MS Thunk Compiler
+# - symbols exported by the Oct 94 beta version of kernel32.dll
 
   1 stub VxDCall0
   2 stub VxDCall1
@@ -20,20 +21,20 @@
   7 stub VxDCall6
   8 stub VxDCall7
   9 stub VxDCall8
- 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
+ 10 stdcall k32CharToOemA(str str) CharToOem32A
+ 11 stdcall k32CharToOemBuffA(str str long) CharToOemBuff32A
+ 12 stdcall k32OemToCharA(ptr ptr) OemToChar32A
+ 13 stdcall k32OemToCharBuffA(ptr ptr long) OemToCharBuff32A
+ 14 stdcall k32LoadStringA(long long ptr long) LoadString32A
+ 15 varargs k32wsprintfA() wsprintf32A
+ 16 stdcall k32wvsprintfA() wvsprintf32A
+ 17 stub CommonUnimpStub
+ 18 stdcall GetProcessDword(long long) GetProcessDword
+ 19 stub ThunkTheTemplateHandle
+ 20 stub DosFileHandleToWin32Handle
+ 21 stub Win32HandleToDosFileHandle
+ 22 stub DisposeLZ32Handle
+ 23 stub GDIReallyCares
  24 stdcall GlobalAlloc16(long long) GlobalAlloc16
  25 stdcall GlobalLock16(long) GlobalLock16
  26 stdcall GlobalUnlock16(long) GlobalUnlock16
@@ -43,72 +44,72 @@
  30 stdcall GlobalUnWire16(long) GlobalUnWire16
  31 stdcall GlobalFree16(long) GlobalFree16
  32 stdcall GlobalSize16(long) GlobalSize16
- 33 stub _KERNEL32_33
+ 33 stub HouseCleanLogicallyDeadHandles
  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
+ 40 register OT_32ThkLSF() OT_32ThkLSF
  41 stdcall ThunkInitLSF(long str long str str) ThunkInitLSF
- 42 stub _DebugThunkLSF
+ 42 stub LogApiThkLSF
  43 stdcall ThunkInitLS(long str long str str) ThunkInitLS
- 44 stub _DebugThunkLS
+ 44 stub LogApiThkSL
  45 register Common32ThkLS() Common32ThkLS 
  46 stdcall ThunkInitSL(long str long str str) ThunkInitSL
- 47 stub _DebugThunkSL
+ 47 stub LogCBThkSL
  48 stub ReleaseThunkLock
  49 stub RestoreThunkLock
  50 stdcall AddAtomA(str) AddAtom32A
- 51 stub _KERNEL32_51
- 52 stdcall _KERNEL32_52() _KERNEL32_52
- 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
- 57 stdcall WOWHandle32(long long) WOWHandle32
- 58 stub WOWHandle16
- 59 stdcall WOWGlobalAlloc16(long long) GlobalAlloc16
- 60 stdcall WOWGlobalLock16(long) WIN16_GlobalLock16
- 61 stdcall WOWGlobalUnlock16(long) GlobalUnlock16
- 62 stdcall WOWGlobalFree16(long) GlobalFree16
- 63 stdcall WOWGlobalAllocLock16(long long ptr) WOWGlobalAllocLock16
- 64 stdcall WOWGlobalUnlockFree16(long) WOWGlobalUnlockFree16
- 65 stub WOWGlobalLockSize16
- 66 stub WOWYield16
- 67 stub WOWDirectedYield16
- 68 stdcall WOWGetVDMPointerFix(long long long) WOWGetVDMPointerFix
- 69 stdcall WOWGetVDMPointerUnfix(long) WOWGetVDMPointerUnfix
- 70 stdcall WOW32_1(long long) WOW32_1
+ 51 stub W32S_BackTo32
+ 52 stdcall GetThunkBuff() GetThunkBuff
+ 53 stdcall GetThunkStuff(str str) GetThunkStuff
+ 54 stdcall K32WOWCallback16(long long) WOWCallback16
+ 55 stdcall K32WOWCallback16Ex(ptr long long ptr ptr) WOWCallback16Ex
+ 56 stdcall K32WOWGetVDMPointer(long long long) WOWGetVDMPointer
+ 57 stdcall K32WOWHandle32(long long) WOWHandle32
+ 58 stub K32WOWHandle16
+ 59 stdcall K32WOWGlobalAlloc16(long long) GlobalAlloc16
+ 60 stdcall K32WOWGlobalLock16(long) WIN16_GlobalLock16
+ 61 stdcall K32WOWGlobalUnlock16(long) GlobalUnlock16
+ 62 stdcall K32WOWGlobalFree16(long) GlobalFree16
+ 63 stdcall K32WOWGlobalAllocLock16(long long ptr) WOWGlobalAllocLock16
+ 64 stdcall K32WOWGlobalUnlockFree16(long) WOWGlobalUnlockFree16
+ 65 stub K32WOWGlobalLockSize16
+ 66 stub K32WOWYield16
+ 67 stub K32WOWDirectedYield16
+ 68 stdcall K32WOWGetVDMPointerFix(long long long) WOWGetVDMPointerFix
+ 69 stdcall K32WOWGetVDMPointerUnfix(long) WOWGetVDMPointerUnfix
+ 70 stdcall K32WOWGetDescriptor(long long) WOWGetDescriptor
  71 stub IsThreadId
- 72 stub RtlLargeIntegerAdd
- 73 stub RtlEnlargedIntegerMultiply
- 74 stub RtlEnlargedUnsignedMultiply
- 75 stub RtlEnlargedUnsignedDivide
- 76 stub RtlExtendedLargeIntegerDivide
- 77 stub RtlExtendedMagicDivide
- 78 stub RtlExtendedIntegerMultiply
- 79 stub RtlLargeIntegerShiftLeft
- 80 stub RtlLargeIntegerShiftRight
- 81 stub RtlLargeIntegerArithmeticShift
- 82 stub RtlLargeIntegerNegate
- 83 stub RtlLargeIntegerSubtract
- 84 stub RtlConvertLongToLargeInteger
- 85 stub RtlConvertUlongToLargeInteger
- 86 stub _KERNEL32_86_EnterSysLevelSpecial
+ 72 stub K32RtlLargeIntegerAdd
+ 73 stub K32RtlEnlargedIntegerMultiply
+ 74 stub K32RtlEnlargedUnsignedMultiply
+ 75 stub K32RtlEnlargedUnsignedDivide
+ 76 stub K32RtlExtendedLargeIntegerDivide
+ 77 stub K32RtlExtendedMagicDivide
+ 78 stub K32RtlExtendedIntegerMultiply
+ 79 stub K32RtlLargeIntegerShiftLeft
+ 80 stub K32RtlLargeIntegerShiftRight
+ 81 stub K32RtlLargeIntegerArithmeticShift
+ 82 stub K32RtlLargeIntegerNegate
+ 83 stub K32RtlLargeIntegerSubtract
+ 84 stub K32RtlConvertLongToLargeInteger
+ 85 stub K32RtlConvertUlongToLargeInteger
+ 86 stub _KERNEL32_86
  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
- 94 stub _DebugCheckNotSysLevel
- 95 stub _DebugAssertCriticalSection
- 96 stub ConfirmWin16Lock
- 97 stub EnterSysLevel
- 98 stub LeaveSysLevel
+ 92 stdcall GetPK16SysVar() GetPK16SysVar
+ 93 stdcall GetpWin16Lock(ptr) GetpWin16Lock
+ 94 stub _CheckNotSysLevel
+ 95 stub _ConfirmSysLevel
+ 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
@@ -192,7 +193,7 @@
 178 stdcall CreateThread(ptr long ptr long long ptr) CreateThread
 179 stub CreateToolhelp32Snapshot
 180 stub DebugActiveProcess
-181 stub DebugBreak
+181 register DebugBreak() DebugBreak
 182 stub DefineDosDeviceA
 183 stub DefineDosDeviceW
 184 stdcall DeleteAtom(long) DeleteAtom32
@@ -501,8 +502,8 @@
 487 stub IsSLCallback
 488 stdcall IsValidCodePage(long) IsValidCodePage
 489 stdcall IsValidLocale(long long) IsValidLocale
-490 stub K32Thk1632Epilog
-491 stub K32Thk1632Prolog
+490 register K32Thk1632Epilog() K32Thk1632Epilog
+491 register K32Thk1632Prolog() K32Thk1632Prolog
 492 stdcall LCMapStringA(long long str long ptr long) LCMapString32A
 493 stdcall LCMapStringW(long long wstr long ptr long) LCMapString32W
 494 stdcall LeaveCriticalSection(ptr) LeaveCriticalSection
@@ -770,7 +771,7 @@
 756 stdcall _lclose(long) _lclose32
 757 stdcall _lcreat(ptr long) _lcreat32
 758 stdcall _llseek(long long long) _llseek32
-759 stdcall _lopen(ptr long) _lopen32
+759 stdcall _lopen(str long) _lopen32
 760 stdcall _lread(long ptr long) _lread32
 761 stdcall _lwrite(long ptr long) _lwrite32
 762 stub dprintf
diff --git a/relay32/relay386.c b/relay32/relay386.c
index 8203e40..bbe9933 100644
--- a/relay32/relay386.c
+++ b/relay32/relay386.c
@@ -193,6 +193,8 @@
     typedef void (CALLBACK *entry_point_t)(CONTEXT *);
     entry_point_t entry_point = *(entry_point_t*) (ESP_reg(&context) - 4);
 
+    __RESTORE_ES;
+
     if (!TRACE_ON(relay))
     {
         /* Simply call the entry point */
@@ -204,8 +206,6 @@
         unsigned int typemask;
 	BYTE *relay_addr;
 
-    	__RESTORE_ES;
-
         /*
 	 * Fixup the context structure because of the extra parameter
          * pushed by the relay debugging code.
diff --git a/relay32/shell32.spec b/relay32/shell32.spec
index f31d8a3..c815d0c 100644
--- a/relay32/shell32.spec
+++ b/relay32/shell32.spec
@@ -84,7 +84,7 @@
   82 stub ExtractAssociatedIconA
   83 stub SHELL32_83
   84 stub SHELL32_84
-  85 stub SHELL32_85
+  85 stdcall SHELL32_85(long long long long) SHELL32_85
   86 stub SHELL32_86
   87 stub SHELL32_87
   88 stub SHELL32_88
diff --git a/relay32/user32.spec b/relay32/user32.spec
index e73bd80..910a6a1 100644
--- a/relay32/user32.spec
+++ b/relay32/user32.spec
@@ -114,7 +114,7 @@
 109 stdcall DdeNameService(long long long long) DdeNameService32
 110 stdcall DdePostAdvise(long long long) DdePostAdvise32
 111 stub DdeQueryConvInfo
-112 stub DdeQueryNextServer
+112 stdcall DdeQueryNextServer(long long) DdeQueryNextServer32
 113 stub DdeQueryStringA
 114 stub DdeQueryStringW
 115 stdcall DdeReconnect(long) DdeReconnect
@@ -537,7 +537,7 @@
 532 stdcall ShowScrollBar(long long long) ShowScrollBar32
 533 stub ShowStartGlass
 534 stdcall ShowWindow(long long) ShowWindow32
-535 stub ShowWindowAsync
+535 stdcall ShowWindowAsync(long long) ShowWindowAsync32
 536 stdcall SubtractRect(ptr ptr ptr) SubtractRect32
 537 stdcall SwapMouseButton(long) SwapMouseButton32
 538 stub SwitchDesktop
diff --git a/relay32/wnaspi32.spec b/relay32/wnaspi32.spec
new file mode 100644
index 0000000..e9349ba
--- /dev/null
+++ b/relay32/wnaspi32.spec
@@ -0,0 +1,6 @@
+name	wnaspi32
+type	win32
+
+0 stub GetASPI32SupportInfo
+1 stub SendASPI32Command
+3 stub GetASPI32DLLVersion
diff --git a/relay32/wow32.spec b/relay32/wow32.spec
index 9b5bace..339e8a3 100644
--- a/relay32/wow32.spec
+++ b/relay32/wow32.spec
@@ -1,7 +1,7 @@
 name	wow32
 type	win32
 
-  1 stdcall WOW_1(long long) WOW32_1
+  1 stdcall WOWGetDescriptor(long long) WOWGetDescriptor
   2 stdcall WOWCallback16(long long) WOWCallback16
   3 stdcall WOWCallback16Ex(ptr long long ptr ptr) WOWCallback16Ex
   4 stub    WOWDirectedYield16
diff --git a/tools/build.c b/tools/build.c
index 814a5b0..319b6e7 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -1496,6 +1496,16 @@
  * For register functions, the arguments are ignored, but they are still
  * removed from the stack upon return.
  *
+ * A special variant of the callback function is generated by the function 
+ * profile "t_long_". This is used by the Win95 16->32 thunk
+ * functions C16ThkSL and C16ThkSL01 and is implemented as follows:
+ * On entry, the EBX register is set up to contain a flat pointer to the
+ * 16-bit stack such that EBX+22 points to the first argument.
+ * Then, the entry point is called, while EBP is set up to point
+ * to the return address (on the 32-bit stack).
+ * The called function returns with CX set to the number of bytes
+ * to be popped of the caller's stack.
+ *
  * Stack layout upon entry to the callback function:
  *  ...           ...
  * (sp+18) word   first 16-bit arg
@@ -1518,11 +1528,13 @@
     int short_ret = 0;
     int reg_func = 0;
     int cdecl = 0;
+    int thunk = 0;
     char *args = profile + 7;
 
     /* Parse function type */
 
     if (!strncmp( "c_", profile, 2 )) cdecl = 1;
+    else if (!strncmp( "t_", profile, 2 )) thunk = 1;
     else if (strncmp( "p_", profile, 2 ))
     {
         fprintf( stderr, "Invalid function name '%s', ignored\n", profile );
@@ -1594,6 +1606,17 @@
 
     if (reg_func) BuildContext16( outfile );
     else if (*args) argsize = TransferArgs16To32( outfile, args, cdecl );
+    else if (thunk)
+    {
+        /* Get the stack selector base */
+        fprintf( outfile, "\tmovw %%ss,%%ax\n" );
+        fprintf( outfile, "\tandl $0xfff8,%%eax\n" );
+        fprintf( outfile, "\tmovl " PREFIX "ldt_copy(%%eax),%%eax\n" );
+        fprintf( outfile, "\tmovl %%eax,-20(%%ebp)\n" );
+        /* Add the offset */
+        fprintf( outfile, "\tleal -16(%%ebp),%%eax\n" );
+        fprintf( outfile, "\taddl %%eax,-20(%%ebp)\n" );
+    }
 
     /* Get the address of the API function */
 
@@ -1625,7 +1648,7 @@
 
     /* Print the debug information before the call */
 
-    if (debugging)
+    if (debugging && !thunk)
     {
         int ftype = 0;
 
@@ -1644,11 +1667,20 @@
 
     /* Call the entry point */
 
-    fprintf( outfile, "\tcall *%%eax\n" );
+    if (thunk)
+    {
+        fprintf( outfile, "\tpushl %%ebp\n" );
+        fprintf( outfile, "\tleal -4(%%esp), %%ebp\n" );
+        fprintf( outfile, "\tcall *%%eax\n" );
+        fprintf( outfile, "\tpopl %%ebp\n" );
+    }
+    else
+        fprintf( outfile, "\tcall *%%eax\n" );
+
 
     /* Print the debug information after the call */
 
-    if (debugging)
+    if (debugging && !thunk)
     {
         if (reg_func)
         {
@@ -1728,8 +1760,17 @@
     }
 
     /* Remove the arguments and return */
-
-    if (argsize && !cdecl)
+    
+    if (thunk)
+    {
+        fprintf( outfile, "\tpopl %%ebx\n" );
+        fprintf( outfile, "\txorb %%ch,%%ch\n" );
+        fprintf( outfile, "\taddw %%cx, %%sp\n" );
+        fprintf( outfile, "\tpushl %%ebx\n" );
+        fprintf( outfile, "\t.byte 0x66\n" );
+        fprintf( outfile, "\tlret\n" );
+    }
+    else if (argsize && !cdecl)
     {
         fprintf( outfile, "\t.byte 0x66\n" );
         fprintf( outfile, "\tlret $%d\n", argsize );
@@ -2248,6 +2289,10 @@
 
     for (i = 2; i < argc; i++) BuildCallFrom16Func( outfile, argv[i] );
 
+    /* Build the thunk callback function */
+
+    BuildCallFrom16Func( outfile, "t_long_" );
+
     /* Output the argument debugging strings */
 
     if (debugging)
diff --git a/win32/console.c b/win32/console.c
index 89d70dc..18cb158 100644
--- a/win32/console.c
+++ b/win32/console.c
@@ -796,15 +796,10 @@
     TRACE(console, "%d (%d x %d)\n", hConsoleOutput, dwCursorPosition.x, 
           dwCursorPosition.y);
     /* x are columns, y rows */
-    if (!dwCursorPosition.y) {
     	fprintf(stderr,"\r");
-	if (dwCursorPosition.x)
             /* note: 0x1B == ESC */
-            fprintf(stderr,"%c[%dC", 0x1B, dwCursorPosition.x);
+    fprintf(stdout,"%c[%d;%dH", 0x1B, dwCursorPosition.y, dwCursorPosition.x);
 	return TRUE;
-    }
-    FIXME(console, "Unhandled case: y=%d\n", dwCursorPosition.y);
-    return FALSE;
 }
 
 
@@ -928,11 +923,103 @@
  *    Success: TRUE
  *    Failure: FALSE
  */
-BOOL32 WINAPI SetConsoleTextAttribute32(
-    HANDLE32 hcon,    /* [in] Handle to console screen buffer */
-    DWORD attributes) /* [in] Text and background colors */
+BOOL32 WINAPI SetConsoleTextAttribute32(HANDLE32 hConsoleOutput,WORD wAttr)
 {
-    FIXME(console, "(%x,%lx): stub\n", hcon, attributes);
+    int forecolor = 0;
+    int backcolor = 0;
+    int boldtext = 0;
+    unsigned int attrib;
+    
+    attrib = wAttr;
+    if( attrib >= BACKGROUND_INTENSITY )
+        attrib -= BACKGROUND_INTENSITY; /* Background intensity is ignored */
+    if( attrib >= BACKGROUND_RED )
+    {
+        attrib -= BACKGROUND_RED;
+        if( attrib >= BACKGROUND_GREEN )
+        {
+            attrib -= BACKGROUND_GREEN;
+            if( attrib >= BACKGROUND_BLUE )
+            {
+                attrib -= BACKGROUND_BLUE;
+                backcolor = 47; /* White background */
+            }
+            else
+                backcolor = 43; /* Yellow background */
+        }
+        else if( attrib >= BACKGROUND_BLUE )
+        {
+            attrib -= BACKGROUND_BLUE;
+            backcolor = 45; /* Magenta background */
+        }
+        else
+            backcolor = 41; /* Red Background */
+    }
+    else if( attrib >= BACKGROUND_GREEN )
+    {
+        attrib -= BACKGROUND_GREEN;
+        if( attrib >= BACKGROUND_BLUE )
+        {
+            attrib -= BACKGROUND_BLUE;
+            backcolor = 46; /* Cyan background */
+        }
+        else
+            backcolor = 42; /* Green background */
+    }
+    else if( attrib >= BACKGROUND_BLUE )
+    {
+        attrib -= BACKGROUND_BLUE;
+        backcolor = 44; /* Blue background */
+    }
+    else
+        backcolor = 40; /* Black background */
+    if( attrib >= FOREGROUND_INTENSITY )
+    {
+        attrib -= FOREGROUND_INTENSITY;
+        boldtext = 1;   /* Bold attribute is on */
+    }
+    if( attrib >= FOREGROUND_RED )
+    {
+        attrib -= FOREGROUND_RED;
+        if( attrib >= FOREGROUND_GREEN )
+        {
+            attrib -= FOREGROUND_GREEN;
+            if( attrib >= FOREGROUND_BLUE )
+            {
+                attrib -= FOREGROUND_BLUE;
+                forecolor = 37; /* White foreground */
+            }
+            else
+                forecolor = 33; /* Yellow foreground */
+        }
+        else if( attrib >= FOREGROUND_BLUE )
+        {
+            attrib -= FOREGROUND_BLUE;
+            forecolor = 35; /* Magenta foreground */
+        }
+        else
+            forecolor = 31; /* Red foreground */
+    }
+    else if( attrib >= FOREGROUND_GREEN )
+    {
+        attrib -= FOREGROUND_GREEN;
+        if( attrib >= FOREGROUND_BLUE )
+        {
+            attrib -= FOREGROUND_BLUE;
+            forecolor = 36; /* Cyan foreground */
+        }
+        else
+            forecolor = 32; /* Green foreground */
+    }
+    else if( attrib >= FOREGROUND_BLUE )
+    {
+        attrib -= FOREGROUND_BLUE;
+        forecolor = 34; /* Blue foreground */
+    }
+    else
+        forecolor = 30; /* Black foreground */
+
+    fprintf(stdout,"%c[%d;%d;%dm",0x1B,boldtext,forecolor,backcolor);
     return TRUE;
 }
 
@@ -958,17 +1045,30 @@
 
 /******************************************************************************
  * FillConsoleOutputCharacterA [KERNEL32.242]
+ *
+ * PARAMS
+ *    hConsoleOutput    [I] Handle to screen buffer
+ *    cCharacter        [I] Character to write
+ *    nLength           [I] Number of cells to write to
+ *    dwCoord           [I] Coords of first cell
+ *    lpNumCharsWritten [O] Pointer to number of cells written
+ *
+ * RETURNS
+ *    Success: TRUE
+ *    Failure: FALSE
  */
 BOOL32 WINAPI FillConsoleOutputCharacterA(
     HANDLE32 hConsoleOutput,
-    CHAR cCharacter,
+    BYTE cCharacter,
     DWORD nLength,
-    COORD dwWriteCoord,
-    LPDWORD lpNumberOfCharsWritten)
+    COORD dwCoord,
+    LPDWORD lpNumCharsWritten)
 {
-    FIXME(console, "(%d,%c,%ld,%dx%d,%p): stub\n", hConsoleOutput,cCharacter,
-          nLength,dwWriteCoord.x,dwWriteCoord.y,lpNumberOfCharsWritten);
-    *lpNumberOfCharsWritten = 0;
+    long count;
+    SetConsoleCursorPosition(hConsoleOutput,dwCoord);
+    for(count=0;count<nLength;count++)
+        putc(cCharacter,stdout);
+    *lpNumCharsWritten = nLength;
     return TRUE;
 }
 
@@ -987,14 +1087,17 @@
  *    Success: TRUE
  *    Failure: FALSE
  */
-BOOL32 WINAPI FillConsoleOutputCharacterW( HANDLE32 hConsoleOutput,
-                                           WCHAR cCharacter, DWORD nLength,
+BOOL32 WINAPI FillConsoleOutputCharacterW(HANDLE32 hConsoleOutput,
+                                            WCHAR cCharacter,
+                                            DWORD nLength,
                                            COORD dwCoord, 
-                                           LPDWORD lpNumCharsWritten )
+                                            LPDWORD lpNumCharsWritten)
 {
-    FIXME(console, "(%d,%c,%ld,%dx%d,%p): stub\n", hConsoleOutput,
-          cCharacter,nLength,dwCoord.x,dwCoord.y,lpNumCharsWritten);
-    *lpNumCharsWritten = 0;
+    long count;
+    SetConsoleCursorPosition(hConsoleOutput,dwCoord);
+    for(count=0;count<nLength;count++)
+        putc(cCharacter,stdout);
+    *lpNumCharsWritten = nLength;
     return TRUE;
 }
 
diff --git a/win32/kernel32.c b/win32/kernel32.c
index 5b67179..133d6a0 100644
--- a/win32/kernel32.c
+++ b/win32/kernel32.c
@@ -75,81 +75,307 @@
 	/* should fill the rest of the 32 bytes with 0xCC */
 }
 
-struct thunkstruct
-{
-	char	magic[4];
-	DWORD	length;
-	DWORD	ptr;
-	DWORD	x0C;
 
-	DWORD	x10;
-	DWORD	x14;
-	DWORD	x18;
-	DWORD	x1C;
-	DWORD	x20;
+/***********************************************************************
+ * ThunkConnect data structures
+ */
+
+struct ThunkDataCommon
+{
+    char                   magic[4];         /* 00 */
+    DWORD                  checksum;         /* 04 */
 };
 
+struct ThunkDataLS16
+{
+    struct ThunkDataCommon common;           /* 00 */
+    SEGPTR                 targetTable;      /* 08 */
+    DWORD                  firstTime;        /* 0C */
+};
+
+struct ThunkDataLS32
+{
+    struct ThunkDataCommon common;           /* 00 */
+    DWORD *                targetTable;      /* 08 */
+    char                   lateBinding[4];   /* 0C */
+    DWORD                  flags;            /* 10 */
+    DWORD                  reserved1;        /* 14 */
+    DWORD                  reserved2;        /* 18 */
+    DWORD                  offsetQTThunk;    /* 1C */
+    DWORD                  offsetFTProlog;   /* 20 */
+};
+
+struct ThunkDataSL16
+{
+    struct ThunkDataCommon common;            /* 00 */
+    DWORD                  flags1;            /* 08 */
+    DWORD                  reserved1;         /* 0C */
+    struct ThunkDataSL *   fpData;            /* 10 */
+    SEGPTR                 spData;            /* 14 */
+    DWORD                  reserved2;         /* 18 */
+    char                   lateBinding[4];    /* 1C */
+    DWORD                  flags2;            /* 20 */
+    DWORD                  reserved3;         /* 20 */
+    SEGPTR                 apiDatabase;       /* 28 */
+};
+
+struct ThunkDataSL32
+{
+    struct ThunkDataCommon common;            /* 00 */
+    DWORD                  reserved1;         /* 08 */
+    struct ThunkDataSL *   data;              /* 0C */
+    char                   lateBinding[4];    /* 10 */
+    DWORD                  flags;             /* 14 */
+    DWORD                  reserved2;         /* 18 */
+    DWORD                  reserved3;         /* 1C */
+    DWORD                  offsetTargetTable; /* 20 */
+};
+
+struct ThunkDataSL
+{
+#if 0
+    This structure differs from the Win95 original,
+    but this should not matter since it is strictly internal to 
+    the thunk handling routines in KRNL386 / KERNEL32.
+
+    For reference, here is the Win95 layout:
+
+    struct ThunkDataCommon common;            /* 00 */
+    DWORD                  flags1;            /* 08 */
+    SEGPTR                 apiDatabase;       /* 0C */
+    WORD                   exePtr;            /* 10 */
+    WORD                   segMBA;            /* 12 */
+    DWORD                  lenMBATotal;       /* 14 */
+    DWORD                  lenMBAUsed;        /* 18 */
+    DWORD                  flags2;            /* 1C */
+    char                   pszDll16[256];     /* 20 */
+    char                   pszDll32[256];     /*120 */
+  
+    We do it differently since all our thunk handling is done
+    by 32-bit code. Therefore we do not need do provide
+    easy access to this data, especially the process target
+    table database, for 16-bit code.
+#endif
+    
+    struct ThunkDataCommon common;
+    DWORD                  flags1;
+    struct SLApiDB *       apiDB;
+    struct SLTargetDB *    targetDB;
+    DWORD                  flags2;
+    char                   pszDll16[256];
+    char                   pszDll32[256];
+};
+
+struct SLTargetDB
+{
+     struct SLTargetDB *   next;
+     PDB32 *               process;
+     DWORD *               targetTable;
+};
+
+struct SLApiDB
+{
+    DWORD                  nrArgBytes;
+    DWORD                  errorReturnValue;
+};
+
+/***********************************************************************
+ *           GetThunkStuff    (KERNEL32.53)
+ */
+LPVOID WINAPI GetThunkStuff(LPSTR module, LPSTR func)
+{
+    HMODULE32 hmod = LoadLibrary16(module);
+    if (hmod <= 32) return 0;
+
+    return PTR_SEG_TO_LIN(WIN32_GetProcAddress16(hmod, func));
+}
+
+/***********************************************************************
+ *           GetThunkBuff    (KERNEL32.52)
+ * Returns a pointer to ThkBuf in the 16bit library SYSTHUNK.DLL.
+ */
+LPVOID WINAPI GetThunkBuff(void)
+{
+    return GetThunkStuff("SYSTHUNK.DLL", "ThkBuf");
+}
+
 /***********************************************************************
  *		ThunkConnect32		(KERNEL32)
  * Connects a 32bit and a 16bit thunkbuffer.
  */
 UINT32 WINAPI ThunkConnect32( 
-	struct thunkstruct *ths,	/* [in/out] thunkbuffer */
-	LPCSTR thunkfun16,		/* [in] win16 thunkfunction */
-	LPCSTR module16,		/* [in] name of win16 dll */
-	LPCSTR module32,		/* [in] name of win32 dll */
-	HMODULE32 hmod32,		/* [in] hmodule of win32 dll (used?) */
-	DWORD dllinitarg1		/* [in] initialisation argument */
+	struct ThunkDataCommon *TD,  /* [in/out] thunkbuffer */
+	LPSTR thunkfun16,            /* [in] win16 thunkfunction */
+	LPSTR module16,              /* [in] name of win16 dll */
+	LPSTR module32,              /* [in] name of win32 dll */
+	HMODULE32 hmod32,            /* [in] hmodule of win32 dll */
+	DWORD dwReason               /* [in] initialisation argument */
 ) {
-	HINSTANCE16	hmm;
-	SEGPTR		thkbuf;
-	struct	thunkstruct	*ths16;
+    BOOL32 directionSL;
 
-	TRACE(thunk,"(<struct>,%s,%s,%s,%x,%lx)\n",
-		thunkfun16,module32,module16,hmod32,dllinitarg1
-	);
-	TRACE(thunk,"	magic = %c%c%c%c\n",
-		ths->magic[0],
-		ths->magic[1],
-		ths->magic[2],
-		ths->magic[3]
-	);
-	TRACE(thunk,"	length = %lx\n",ths->length);
-	if (lstrncmp32A(ths->magic,"SL01",4)&&lstrncmp32A(ths->magic,"LS01",4))
-		return 0;
-	hmm=LoadModule16(module16,NULL);
-	if (hmm<=32)
-		return 0;
-	thkbuf=(SEGPTR)WIN32_GetProcAddress16(hmm,thunkfun16);
-	if (!thkbuf)
-		return 0;
-	ths16=(struct thunkstruct*)PTR_SEG_TO_LIN(thkbuf);
-	if (lstrncmp32A(ths16->magic,ths->magic,4))
-		return 0;
+    if (!lstrncmp32A(TD->magic, "SL01", 4))
+    {
+        directionSL = TRUE;
 
-	if (!lstrncmp32A(ths->magic,"SL01",4))  {
-		if (ths16->length != ths->length)
-			return 0;
-		ths->x0C = (DWORD)ths16;
+        TRACE(thunk, "SL01 thunk %s (%lx) <- %s (%s), Reason: %ld\n",
+                     module32, (DWORD)TD, module16, thunkfun16, dwReason);
+    }
+    else if (!lstrncmp32A(TD->magic, "LS01", 4))
+    {
+        directionSL = FALSE;
 
-		TRACE(thunk,"	ths16 magic is 0x%08lx\n",*(DWORD*)ths16->magic);
-		if (*((DWORD*)ths16->magic) != 0x0000304C)
-			return 0;
-		if (!*(WORD*)(((LPBYTE)ths16)+0x12))
-			return 0;
-		
-	}
-	if (!lstrncmp32A(ths->magic,"LS01",4))  {
-		if (ths16->length != ths->length)
-			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,(DWORD *)ths->ptr);
-		/* code offset for FT_Prolog is at 0x20...  */
-		_write_ftprolog(((LPBYTE)ths) + ths->x20,(DWORD *)ths->ptr);
-		return 1;
-	}
-	return TRUE;
+        TRACE(thunk, "LS01 thunk %s (%lx) -> %s (%s), Reason: %ld\n",
+                     module32, (DWORD)TD, module16, thunkfun16, dwReason);
+    }
+    else
+    {
+        ERR(thunk, "Invalid magic %c%c%c%c\n", 
+                   TD->magic[0], TD->magic[1], TD->magic[2], TD->magic[3]);
+        return 0;
+    }
+    
+    switch (dwReason)
+    {
+        case DLL_PROCESS_ATTACH:
+        {
+            struct ThunkDataCommon *TD16 = GetThunkStuff(module16, thunkfun16);
+            if (!TD16 || TD16->checksum != TD->checksum
+                      || memcmp(TD16->magic, TD->magic, 4))
+            {
+                ERR(thunk, "Problem loading 16-bit thunk buffer!\n");
+                return 0;
+            }
+
+            if (directionSL)
+            {
+                struct ThunkDataSL32 *SL32 = (struct ThunkDataSL32 *)TD;
+                struct ThunkDataSL16 *SL16 = (struct ThunkDataSL16 *)TD16;
+                struct SLTargetDB *tdb;
+
+                if (SL16->fpData == NULL)
+                {
+                    ERR(thunk, "ThunkConnect16 was not called!\n");
+                    return 0;
+                }
+
+                SL32->data = SL16->fpData;
+
+                tdb = HeapAlloc(GetProcessHeap(), 0, sizeof(*tdb));
+                tdb->process = PROCESS_Current();
+                tdb->targetTable = (DWORD *)(thunkfun16 + SL32->offsetTargetTable);
+
+                tdb->next = SL32->data->targetDB;   /* FIXME: not thread-safe! */
+                SL32->data->targetDB = tdb;
+
+                TRACE(thunk, "Process %08lx allocated TargetDB entry for ThunkDataSL %08lx\n", 
+                             (DWORD)PROCESS_Current(), (DWORD)SL32->data);
+            }
+            else
+            {
+                struct ThunkDataLS32 *LS32 = (struct ThunkDataLS32 *)TD;
+                struct ThunkDataLS16 *LS16 = (struct ThunkDataLS16 *)TD16;
+
+                LS32->targetTable = PTR_SEG_TO_LIN(LS16->targetTable);
+
+                /* write QT_Thunk and FT_Prolog stubs */
+                _write_qtthunk ((LPBYTE)TD + LS32->offsetQTThunk,  LS32->targetTable);
+                _write_ftprolog((LPBYTE)TD + LS32->offsetFTProlog, LS32->targetTable);
+            }
+            break;
+        }
+
+        case DLL_PROCESS_DETACH:
+            /* FIXME: cleanup */
+            break;
+    }
+
+    return 1;
+}
+
+/***********************************************************************
+ *		ThunkConnect16		(KERNEL.651)
+ * Connects a 32bit and a 16bit thunkbuffer.
+ */
+UINT32 WINAPI ThunkConnect16( 
+	LPSTR module16,              /* [in] name of win16 dll */
+	LPSTR module32,              /* [in] name of win32 dll */
+	HINSTANCE16 hInst16,         /* [in] hInst of win16 dll */
+	DWORD dwReason,              /* [in] initialisation argument */
+	struct ThunkDataCommon *TD,  /* [in/out] thunkbuffer */
+	LPSTR thunkfun32,            /* [in] win32 thunkfunction */
+        WORD CS                      /* [in] CS of win16 dll */
+) {
+    BOOL32 directionSL;
+
+    if (!lstrncmp32A(TD->magic, "SL01", 4))
+    {
+        directionSL = TRUE;
+
+        TRACE(thunk, "SL01 thunk %s (%lx) -> %s (%s), Reason: %ld\n",
+                     module16, (DWORD)TD, module32, thunkfun32, dwReason);
+    }
+    else if (!lstrncmp32A(TD->magic, "LS01", 4))
+    {
+        directionSL = FALSE;
+
+        TRACE(thunk, "LS01 thunk %s (%lx) <- %s (%s), Reason: %ld\n",
+                     module16, (DWORD)TD, module32, thunkfun32, dwReason);
+    }
+    else
+    {
+        ERR(thunk, "Invalid magic %c%c%c%c\n", 
+                   TD->magic[0], TD->magic[1], TD->magic[2], TD->magic[3]);
+        return 0;
+    }
+    
+    switch (dwReason)
+    {
+        case DLL_PROCESS_ATTACH:
+            if (directionSL)
+            {
+                struct ThunkDataSL16 *SL16 = (struct ThunkDataSL16 *)TD;
+                struct ThunkDataSL   *SL   = SL16->fpData;
+
+                if (SL == NULL)
+                {
+                    SL = HeapAlloc(GetProcessHeap(), 0, sizeof(*SL));
+
+                    SL->common   = SL16->common;
+                    SL->flags1   = SL16->flags1;
+                    SL->flags2   = SL16->flags2;
+
+                    SL->apiDB    = PTR_SEG_TO_LIN(SL16->apiDatabase);
+                    SL->targetDB = NULL;
+
+                    lstrcpyn32A(SL->pszDll16, module16, 255);
+                    lstrcpyn32A(SL->pszDll32, module32, 255);
+
+                    /* We should create a SEGPTR to the ThunkDataSL,
+                       but since the contents are not in the original format,
+                       any access to this by 16-bit code would crash anyway. */
+                    SL16->spData = 0;
+                    SL16->fpData = SL;
+                }
+
+
+                if (SL->flags2 & 0x80000000)
+                {
+                    TRACE(thunk, "Preloading 32-bit library\n");
+                    LoadLibrary32A(module32);
+                }
+            }
+            else
+            {
+                /* nothing to do */
+            }
+            break;
+
+        case DLL_PROCESS_DETACH:
+            /* FIXME: cleanup */
+            break;
+    }
+
+    return 1;
 }
 
 
@@ -396,22 +622,6 @@
 }
 
 /***********************************************************************
- *           _KERNEL32_52    (KERNEL32.52)
- * Returns a pointer to ThkBuf in the 16bit library SYSTHUNK.DLL.
- * [ok probably]
- */
-LPVOID WINAPI _KERNEL32_52()
-{
-	HMODULE32	hmod = LoadLibrary16("systhunk.dll");
-
-	TRACE(thunk, "systhunk.dll module %d\n", hmod);
-	
-	if (hmod<=32)
-		return 0;
-	return PTR_SEG_TO_LIN(WIN32_GetProcAddress16(hmod,"ThkBuf"));
-}
-
-/***********************************************************************
  * 		ThunkInitLS 	(KERNEL32.43)
  * A thunkbuffer link routine 
  * The thunkbuf looks like:
@@ -530,40 +740,56 @@
 }
 
 /***********************************************************************
- * 		_KERNEL32_40 	(KERNEL32.40)
- * YET Another 32->16 thunk, the difference to the others is still mysterious
- * Target address is in EDX.
+ *		OT_32ThkLSF	(KERNEL32.40)
  *
- * [crashes]
+ * YET Another 32->16 thunk. The difference to Common32ThkLS is that
+ * argument processing is done on both the 32-bit and the 16-bit side:
+ * The 32-bit side prepares arguments, copying them onto the stack.
+ * 
+ * When this routine is called, the first word on the stack is the 
+ * number of argument bytes prepared by the 32-bit code, and EDX
+ * contains the 16-bit target address.
+ *
+ * The called 16-bit routine is another relaycode, doing further 
+ * argument processing and then calling the real 16-bit target
+ * whose address is stored at [bp-04].
+ *
+ * The call proceeds using a normal CallRegisterShortProc.
+ * After return from the 16-bit relaycode, the arguments need
+ * to be copied *back* to the 32-bit stack, since the 32-bit
+ * relaycode processes output parameters.
+ * 
+ * Note that we copy twice the number of arguments, since some of the
+ * 16-bit relaycodes in SYSTHUNK.DLL directly access the original
+ * arguments of the caller!
+ *
+ * (Note that this function seems only to be used for
+ *  OLECLI32 -> OLECLI and OLESVR32 -> OLESVR thunking.)
  */
-VOID WINAPI _KERNEL32_40(CONTEXT *context)
+VOID WINAPI OT_32ThkLSF(CONTEXT *context)
 {
-	CONTEXT	context16;
-	LPBYTE	curstack;
-	DWORD	ret,stacksize;
-	THDB *thdb = THREAD_Current();
+    CONTEXT context16;
+    DWORD argsize;
+    THDB *thdb = THREAD_Current();
 
-	__RESTORE_ES;
-	TRACE(thunk,"(EDX=0x%08lx)\n", EDX_reg(context) );
-	stacksize = EBP_reg(context)-ESP_reg(context);
-	TRACE(thunk,"	stacksize = %ld\n",stacksize);
-	TRACE(thunk,"on top of stack: 0x%04x\n",*(WORD*)ESP_reg(context));
+    memcpy(&context16,context,sizeof(context16));
 
-	memcpy(&context16,context,sizeof(context16));
+    CS_reg(&context16)  = HIWORD(EDX_reg(context));
+    IP_reg(&context16)  = LOWORD(EDX_reg(context));
+    EBP_reg(&context16) = OFFSETOF( thdb->cur_stack )
+                           + (WORD)&((STACK16FRAME*)0)->bp;
 
-	CS_reg(&context16)	 = HIWORD(EDX_reg(context));
-	IP_reg(&context16)	 = LOWORD(EDX_reg(context));
+    argsize = 2 * *(WORD *)(ESP_reg(context) + 4) + 2;
 
-	curstack = PTR_SEG_TO_LIN(STACK16_PUSH( thdb, stacksize ));
-	memcpy(curstack-stacksize,(LPBYTE)ESP_reg(context),stacksize);
-	ret = Callbacks->CallRegisterShortProc(&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->CallRegisterShortProc(&context16, argsize);
+
+    memcpy( (LPBYTE)ESP_reg(context)+4, 
+            ((LPBYTE)THREAD_STACK16(thdb))-argsize, argsize );
 }
 
-
 /***********************************************************************
  *		ThunkInitLSF		(KERNEL32.41)
  * A thunk setup routine.
@@ -696,7 +922,7 @@
     DWORD  targetTableOffset = EDX_reg(context);
     LPBYTE relayCode = (LPBYTE)EAX_reg(context);
     DWORD *targetTable = *(DWORD **)(relayCode+targetTableOffset);
-    DWORD  targetNr = *(DWORD *)(EBP_reg(context) - 4);
+    DWORD  targetNr = LOBYTE(*(DWORD *)(EBP_reg(context) - 4));
 
     _write_qtthunk(relayCode, targetTable);
 
@@ -730,7 +956,7 @@
 		ERR(thunk,"couldn't load %s, error %d\n",dll16,hmod);
 		return;
 	}
-	segaddr = (SEGPTR)WIN32_GetProcAddress16(hmod,thkbuf);
+	segaddr = (SEGPTR)WIN32_GetProcAddress16(hmod,(LPSTR)thkbuf);
 	if (!segaddr) {
 		ERR(thunk,"haven't found %s in %s!\n",thkbuf,dll16);
 		return;
@@ -834,6 +1060,55 @@
 }
 
 /**********************************************************************
+ * 		KERNEL_607		(KERNEL)
+ */
+LPVOID WINAPI _KERNEL_607(SEGPTR target, LPVOID relay, DWORD dummy)
+{
+    TDB *pTask = (TDB*)GlobalLock16(GetCurrentTask());
+    LPBYTE thunk = HeapAlloc( GetProcessHeap(), 0, 22 ), x = thunk;
+
+    *x++=0x90; *x++=0x68; *((DWORD*)x)++=(DWORD)relay;	/* nop; pushl relay */
+    *x++=0x90; *x++=0x68; *((DWORD*)x)++=(DWORD)target; /* nop; pushl target */
+    *x++=0x90; *x++=0x58;				/* nop; popl eax */
+    *x++=0xC3;						/* ret */
+    *x++=0xCC; *x++=0xCC;
+    *x++=0x01;						/* type: LS */
+    *((WORD *)x)++ = pTask->hInstance;			/* owner */
+    *((WORD *)x)++ = 0;					/* next */
+
+    return thunk;
+}
+
+/**********************************************************************
+ * 		KERNEL_608		(KERNEL)
+ */
+SEGPTR WINAPI _KERNEL_608(LPVOID target, SEGPTR relay, DWORD dummy)
+{
+    TDB *pTask = (TDB*)GlobalLock16(GetCurrentTask());
+    LPBYTE thunk = HeapAlloc( GetProcessHeap(), 0, 22 ), x = thunk;
+    WORD sel;
+
+    *x++=0x66; *x++=0x68; *((DWORD*)x)++=(DWORD)relay;	/* pushl relay */
+    *x++=0x66; *x++=0x68; *((DWORD*)x)++=(DWORD)target; /* pushl target */
+    *x++=0x66; *x++=0x58;				/* popl eax */
+    *x++=0xCB;						/* ret */
+    *x++=0xCC; *x++=0xCC;
+    *x++=0x02;						/* type: SL */
+    *((WORD *)x)++ = pTask->hInstance;			/* owner */
+    *((WORD *)x)++ = 0;					/* next */
+
+    sel = SELECTOR_AllocBlock( thunk, 22, SEGMENT_CODE, FALSE, FALSE );
+    return PTR_SEG_OFF_TO_SEGPTR( sel, 0 );
+}
+
+/**********************************************************************
+ * 		KERNEL_611		(KERNEL)
+ */
+VOID WINAPI _KERNEL_611(DWORD relay, DWORD target)
+{
+}
+
+/**********************************************************************
  *			AllocSLCallback		(KERNEL32)
  *
  * Win95 uses some structchains for callbacks. It allocates them
@@ -984,44 +1259,236 @@
 }
 
 /***********************************************************************
- *           FUNC004				(KERNEL.631)
- * A 16->32 thunk setup function.
- * Gets called from a thunkbuffer (value of EAX). It overwrites the start
- * with a jmp to a kernel32 function. The kernel32 function gets passed EDX.
- * (and possibly CX).
+ *           C16ThkSL				(KERNEL.630)
  */
-void WINAPI FUNC004(
-	CONTEXT *context	/* [in/out] register context from 1632-relay */
-) {
 
-	FIXME(reg,",STUB (edx is 0x%08lx, eax is 0x%08lx,edx[0x10] is 0x%08lx)!\n",
-		EDX_reg(context),
-		EAX_reg(context),
-		((DWORD*)PTR_SEG_TO_LIN(EDX_reg(context)))[0x10/4]
-	);
-
-#if 0
+void WINAPI C16ThkSL(CONTEXT *context)
 {
-	LPBYTE	x,target = (LPBYTE)PTR_SEG_TO_LIN(EAX_reg(context));
-	WORD	ds,cs;
+    extern void CallFrom16_t_long_(void);
+    LPBYTE stub = PTR_SEG_TO_LIN(EAX_reg(context)), x = stub;
+    WORD cs, ds;
+    GET_CS(cs);
+    GET_DS(ds);
 
-	GET_DS(ds);
-	GET_CS(cs);
-/* Won't work anyway since we don't know the function called in KERNEL32 -Marcus*/
-	x = target;
-	*x++= 0xb8; *(WORD*)x= ds;x+=2;		/* mov ax,KERNEL32_DS */
-	*x++= 0x8e; *x++ = 0xc0; 		/* mov es,ax */
-	*x++= 0x66; *x++ = 0xba; *(DWORD*)x=EDX_reg(context);x+=4;
-						/* mov edx, $EDX */
-	*x++= 0x66; *x++ = 0xea;	/* jmp KERNEL32_CS:kernel32fun */
-		*(DWORD*)x=0;x+=4;/* FIXME: _what_ function does it call? */
-		*(WORD*)x=cs;x+=2;
-					
+    /* We produce the following code:
+     *
+     *   mov ax, __FLATDS
+     *   mov es, ax
+     *   movzx ecx, cx
+     *   mov edx, es:[ecx + $EDX]
+     *   push bp
+     *   push edx
+     *   call __FLATCS:CallFrom16_t_long_
+     */
 
-	IP_reg(context) = LOWORD(EAX_reg(context));
-	CS_reg(context) = HIWORD(EAX_reg(context));
-}
-#endif
-	return;
+    *x++ = 0xB8; *((WORD *)x)++ = ds;
+    *x++ = 0x8E; *x++ = 0xC0;
+    *x++ = 0x60; *x++ = 0x0F; *x++ = 0xB7; *x++ = 0xC9;
+    *x++ = 0x67; *x++ = 0x66; *x++ = 0x26; *x++ = 0x8B;
+                 *x++ = 0x91; *((DWORD *)x)++ = EDX_reg(context);
+
+    *x++ = 0x55;
+    *x++ = 0x66; *x++ = 0x52;
+    *x++ = 0x66; *x++ = 0x9A; *((DWORD *)x)++ = (DWORD)CallFrom16_t_long_;
+                              *((WORD *)x)++ = cs;
+
+    /* Jump to the stub code just created */
+    IP_reg(context) = LOWORD(EAX_reg(context));
+    CS_reg(context) = HIWORD(EAX_reg(context));
+
+    /* Since C16ThkSL got called by a jmp, we need to leave the
+       orginal return address on the stack */
+    SP_reg(context) -= 4;
 }
 
+/***********************************************************************
+ *           C16ThkSL01				(KERNEL.631)
+ */
+
+void WINAPI C16ThkSL01(CONTEXT *context)
+{
+    LPBYTE stub = PTR_SEG_TO_LIN(EAX_reg(context)), x = stub;
+
+    if (stub)
+    {
+        struct ThunkDataSL16 *SL16 = PTR_SEG_TO_LIN(EDX_reg(context));
+        struct ThunkDataSL *td = SL16->fpData;
+
+        extern void CallFrom16_t_long_(void);
+        DWORD procAddress = (DWORD)GetProcAddress16(GetModuleHandle16("KERNEL"), 631);
+        WORD cs;
+        GET_CS(cs);
+
+        if (!td)
+        {
+            ERR(thunk, "ThunkConnect16 was not called!\n");
+            return;
+        }
+
+        TRACE(thunk, "Creating stub for ThunkDataSL %08lx\n", (DWORD)td);
+
+
+        /* We produce the following code:
+         *
+         *   xor eax, eax
+         *   mov edx, $td
+         *   call C16ThkSL01
+         *   push bp
+         *   push edx
+         *   call __FLATCS:CallFrom16_t_long_
+         */
+
+        *x++ = 0x66; *x++ = 0x33; *x++ = 0xC0;
+        *x++ = 0x66; *x++ = 0xBA; *((DWORD *)x)++ = (DWORD)td;
+        *x++ = 0x9A; *((DWORD *)x)++ = procAddress;
+
+        *x++ = 0x55;
+        *x++ = 0x66; *x++ = 0x52;
+        *x++ = 0x66; *x++ = 0x9A; *((DWORD *)x)++ = (DWORD)CallFrom16_t_long_;
+                                  *((WORD *)x)++ = cs;
+        
+        /* Jump to the stub code just created */
+        IP_reg(context) = LOWORD(EAX_reg(context));
+        CS_reg(context) = HIWORD(EAX_reg(context));
+
+        /* Since C16ThkSL01 got called by a jmp, we need to leave the
+           orginal return address on the stack */
+        SP_reg(context) -= 4;
+    }
+    else
+    { 
+        struct ThunkDataSL *td = (struct ThunkDataSL *)EDX_reg(context);
+        DWORD targetNr = CX_reg(context) / 4;
+        struct SLTargetDB *tdb;
+
+        TRACE(thunk, "Process %08lx calling target %ld of ThunkDataSL %08lx\n", 
+                     (DWORD)PROCESS_Current(), targetNr, (DWORD)td);
+
+        for (tdb = td->targetDB; tdb; tdb = tdb->next)
+            if (tdb->process == PROCESS_Current())
+                break;
+
+        if (!tdb)
+        {
+            TRACE(thunk, "Loading 32-bit library %s\n", td->pszDll32);
+            LoadLibrary32A(td->pszDll32);
+
+            for (tdb = td->targetDB; tdb; tdb = tdb->next)
+                if (tdb->process == PROCESS_Current())
+                    break;
+        }
+
+        if (tdb)
+        {
+            EDX_reg(context) = tdb->targetTable[targetNr];
+
+            TRACE(thunk, "Call target is %08lx\n", EDX_reg(context));
+        }
+        else
+        {
+            WORD *stack = PTR_SEG_OFF_TO_LIN(SS_reg(context), SP_reg(context));
+            DX_reg(context) = HIWORD(td->apiDB[targetNr].errorReturnValue);
+            AX_reg(context) = LOWORD(td->apiDB[targetNr].errorReturnValue);
+            IP_reg(context) = stack[2];
+            CS_reg(context) = stack[3];
+            SP_reg(context) += td->apiDB[targetNr].nrArgBytes + 4;
+
+            /* Win95 allows delayed loading of the 32-bit DLL.
+               We don't do that at the moment. */
+            ERR(thunk, "Process %08lx did not ThunkConnect32 %s to %s\n", 
+                       (DWORD)PROCESS_Current(), td->pszDll32, td->pszDll16);
+        }
+    }
+}
+
+
+/***********************************************************************
+ *           K32Thk1632Prolog			(KERNEL32.492)
+ */
+VOID WINAPI K32Thk1632Prolog(CONTEXT *context)
+{
+   LPBYTE code = (LPBYTE)EIP_reg(context) - 5;
+
+   /* Arrrgh! SYSTHUNK.DLL just has to re-implement another method
+      of 16->32 thunks instead of using one of the standard methods!
+      This means that SYSTHUNK.DLL itself switches to a 32-bit stack,
+      and does a far call to the 32-bit code segment of OLECLI32/OLESVR32.
+      Unfortunately, our CallTo/CallFrom mechanism is therefore completely
+      bypassed, which means it will crash the next time the 32-bit OLE 
+      code thunks down again to 16-bit (this *will* happen!).
+
+      The following hack tries to recognize this situation.
+      This is possible since the called stubs in OLECLI32/OLESVR32 all
+      look exactly the same:
+        00   E8xxxxxxxx    call K32Thk1632Prolog
+        05   FF55FC        call [ebp-04]
+        08   E8xxxxxxxx    call K32Thk1632Epilog
+        0D   66CB          retf
+
+      If we recognize this situation, we try to simulate the actions
+      of our CallTo/CallFrom mechanism by copying the 16-bit stack
+      to our 32-bit stack, creating a proper STACK16FRAME and 
+      updating thdb->cur_stack. */ 
+
+   if (   code[5] == 0xFF && code[6] == 0x55 && code[7] == 0xFC
+       && code[13] == 0x66 && code[14] == 0xCB)
+   {
+      WORD  stackSel  = NtCurrentTeb()->stack_sel;
+      DWORD stackBase = GetSelectorBase(stackSel);
+
+      THDB *thdb = THREAD_Current();
+      DWORD argSize = EBP_reg(context) - ESP_reg(context);
+      char *stack16 = (char *)ESP_reg(context);
+      char *stack32 = (char *)thdb->cur_stack - argSize;
+      STACK16FRAME *frame16 = (STACK16FRAME *)stack16 - 1;
+
+      TRACE(thunk, "before SYSTHUNK hack: EBP: %08lx ESP: %08lx cur_stack: %08lx\n",
+                   EBP_reg(context), ESP_reg(context), thdb->cur_stack);
+
+      memset(frame16, '\0', sizeof(STACK16FRAME));
+      frame16->frame32 = (STACK32FRAME *)thdb->cur_stack;
+      frame16->ebp = EBP_reg(context);
+
+      memcpy(stack32, stack16, argSize);
+      thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR(stackSel, (DWORD)frame16 - stackBase);
+
+      ESP_reg(context) = (DWORD)stack32;
+      EBP_reg(context) = ESP_reg(context) + argSize;
+
+      TRACE(thunk, "after  SYSTHUNK hack: EBP: %08lx ESP: %08lx cur_stack: %08lx\n",
+                   EBP_reg(context), ESP_reg(context), thdb->cur_stack);
+   }
+}
+
+/***********************************************************************
+ *           K32Thk1632Epilog			(KERNEL32.491)
+ */
+VOID WINAPI K32Thk1632Epilog(CONTEXT *context)
+{
+   LPBYTE code = (LPBYTE)EIP_reg(context) - 13;
+
+   /* We undo the SYSTHUNK hack if necessary. See K32Thk1632Prolog. */
+
+   if (   code[5] == 0xFF && code[6] == 0x55 && code[7] == 0xFC
+       && code[13] == 0x66 && code[14] == 0xCB)
+   {
+      THDB *thdb = THREAD_Current();
+      STACK16FRAME *frame16 = (STACK16FRAME *)PTR_SEG_TO_LIN(thdb->cur_stack);
+      char *stack16 = (char *)(frame16 + 1);
+      DWORD argSize = frame16->ebp - (DWORD)stack16;
+      char *stack32 = (char *)frame16->frame32 - argSize;
+
+      DWORD nArgsPopped = ESP_reg(context) - (DWORD)stack32;
+
+      TRACE(thunk, "before SYSTHUNK hack: EBP: %08lx ESP: %08lx cur_stack: %08lx\n",
+                   EBP_reg(context), ESP_reg(context), thdb->cur_stack);
+
+      thdb->cur_stack = (DWORD)frame16->frame32;
+
+      ESP_reg(context) = (DWORD)stack16 + nArgsPopped;
+      EBP_reg(context) = frame16->ebp;
+
+      TRACE(thunk, "after  SYSTHUNK hack: EBP: %08lx ESP: %08lx cur_stack: %08lx\n",
+                   EBP_reg(context), ESP_reg(context), thdb->cur_stack);
+   }
+}
diff --git a/win32/newfns.c b/win32/newfns.c
index ed0aa9d..a8c0a63 100644
--- a/win32/newfns.c
+++ b/win32/newfns.c
@@ -109,7 +109,7 @@
 				  DWORD nDafaultTimeOut,
 				  LPSECURITY_ATTRIBUTES lpSecurityAttributes)
 {
-  FIXME (win32, "(Name=%s, OpenMode=%#08x, dwPipeMode=%#08x, MaxInst=%d, OutBSize=%d, InBuffSize=%d, DefTimeOut=%d, SecAttr=%p): stub\n",
+  FIXME (win32, "(Name=%s, OpenMode=%#08lx, dwPipeMode=%#08lx, MaxInst=%ld, OutBSize=%ld, InBuffSize=%ld, DefTimeOut=%ld, SecAttr=%p): stub\n",
 	 debugstr_a(lpName), dwOpenMode, dwPipeMode, nMaxInstances,
 	 nOutBufferSize, nInBufferSize, nDafaultTimeOut, 
 	 lpSecurityAttributes);
@@ -131,7 +131,7 @@
 				  DWORD nDafaultTimeOut,
 				  LPSECURITY_ATTRIBUTES lpSecurityAttributes)
 {
-  FIXME (win32, "(Name=%s, OpenMode=%#08x, dwPipeMode=%#08x, MaxInst=%d, OutBSize=%d, InBuffSize=%d, DefTimeOut=%d, SecAttr=%p): stub\n",
+  FIXME (win32, "(Name=%s, OpenMode=%#08lx, dwPipeMode=%#08lx, MaxInst=%ld, OutBSize=%ld, InBuffSize=%ld, DefTimeOut=%ld, SecAttr=%p): stub\n",
 	 debugstr_w(lpName), dwOpenMode, dwPipeMode, nMaxInstances,
 	 nOutBufferSize, nInBufferSize, nDafaultTimeOut, 
 	 lpSecurityAttributes);
diff --git a/win32/ordinals.c b/win32/ordinals.c
index 6aa184a..c50bac5 100644
--- a/win32/ordinals.c
+++ b/win32/ordinals.c
@@ -22,40 +22,52 @@
 
 
 /***********************************************
- *           GetPWinLock    (KERNEL32.93)
+ *           GetpWin16Lock    (KERNEL32.93)
  * Return the infamous Win16Mutex.
  */
-VOID WINAPI GetPWinLock(CRITICAL_SECTION **lock)
+VOID WINAPI GetpWin16Lock(CRITICAL_SECTION **lock)
 {
     FIXME(win32, "(%p)\n",lock);
     *lock = &Win16Mutex;
 }
 
+/***********************************************
+ *           GetPK16SysVar    (KERNEL32.92)
+ * Return the infamous Win16Mutex.
+ */
+LPVOID WINAPI GetPK16SysVar(void)
+{
+    static BYTE PK16SysVar[128];
+
+    FIXME(win32, "()\n");
+    return PK16SysVar;
+}
+
 
 /**********************************************************************
- *           WOW32_1        (KERNEL32.88)
+ *           WOWGetDescriptor        (KERNEL32.88) (WOW32.1)
  */
-BOOL32 WINAPI WOW32_1(SEGPTR segptr,LPLDT_ENTRY ldtent)
+BOOL32 WINAPI WOWGetDescriptor(SEGPTR segptr,LPLDT_ENTRY ldtent)
 {
     return GetThreadSelectorEntry(GetCurrentThreadId(),segptr>>16,ldtent);
 }
 
 
 /***********************************************************************
- *           GetProcessDWORD    (KERNEL32.18)
+ *           GetProcessDword    (KERNEL32.18)
  * 'Of course you cannot directly access Windows internal structures'
  */
 
-DWORD WINAPI GetProcessDWORD(DWORD processid,DWORD action)
+DWORD WINAPI GetProcessDword(DWORD processid,DWORD action)
 {
-	PDB32	*process;
+	PDB32	*process = processid? PROCESS_IdToPDB( processid )
+                                    : PROCESS_Current();
 	TDB	*pTask;
 
 	action+=56;
 	fprintf(stderr,"KERNEL32_18(%ld,%ld+0x38)\n",processid,action);
-	if (action>56)
+	if (!process || action>56)
 		return 0;
-        if (!(process = PROCESS_IdToPDB( processid ))) return 0;
 	switch (action) {
 	case 0:	/* return app compat flags */
 		pTask = (TDB*)GlobalLock16(process->task);
diff --git a/win32/process.c b/win32/process.c
index 18bd5c2..15d2734 100644
--- a/win32/process.c
+++ b/win32/process.c
@@ -25,12 +25,17 @@
 	DWORD nCount,HANDLE32 *pHandles,BOOL32 fWaitAll,DWORD dwMilliseconds,
 	DWORD dwWakeMask
 ) {
+#if 0
 	int	i;
 	fprintf(stderr,"MsgWaitForMultipleObjects(%ld,[",nCount);
 	for (i=0;i<nCount;i++)
 		fprintf(stderr,"%ld,",(DWORD)pHandles[i]);
 	fprintf(stderr,"],%d,%ld,0x%08lx)\n",fWaitAll,dwMilliseconds,dwWakeMask);
 	return 0;
+#else
+	return WaitForMultipleObjectsEx(nCount, pHandles, fWaitAll, dwMilliseconds,
+					FALSE);
+#endif
 }
 
 /**********************************************************************
diff --git a/win32/time.c b/win32/time.c
index fd53a3e..bfa2765 100644
--- a/win32/time.c
+++ b/win32/time.c
@@ -8,6 +8,7 @@
 #include <time.h>
 #include <sys/time.h>
 #include <unistd.h>
+#include "file.h"
 #include "windows.h"
 #include "winerror.h"
 #include "debug.h"
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 0411b64..bdd35fb 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -16,6 +16,7 @@
 #include "sysmetrics.h"
 #include "debug.h"
 #include "spy.h"
+#include "tweak.h"
 
   /* Last COLOR id */
 #define COLOR_MAX   COLOR_BTNHIGHLIGHT
@@ -84,8 +85,18 @@
         return hb;
     }
 
-    SetBkColor32( hDC, GetSysColor32(COLOR_WINDOW) );
     SetTextColor32( hDC, GetSysColor32(COLOR_WINDOWTEXT));
+
+    if (TWEAK_Win95Look) {
+	if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX))
+	    SetBkColor32( hDC, GetSysColor32(COLOR_WINDOW) );
+	else {
+	    SetBkColor32( hDC, GetSysColor32(COLOR_3DFACE) );
+	    return GetSysColorBrush32(COLOR_3DFACE);
+	}
+    }
+    else
+	SetBkColor32( hDC, GetSysColor32(COLOR_WINDOW) );
     return GetSysColorBrush32(COLOR_WINDOW);
 }
 
diff --git a/windows/event.c b/windows/event.c
index 93a8d03..3877a0e 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -391,7 +391,7 @@
 
     /* Process current X event (and possibly others that occurred in the meantime) */
 
-    do
+    while (TSXPending( display ))
     {
 
 #ifdef CONFIG_IPC
@@ -438,7 +438,6 @@
         }
         else EVENT_ProcessEvent( &event );
     }
-    while (TSXPending( display ));
     return TRUE;
 }
 
diff --git a/windows/message.c b/windows/message.c
index 15ef48e..f6bbc0e 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -23,6 +23,8 @@
 #include "dde.h"
 #include "queue.h"
 #include "winproc.h"
+#include "process.h"
+#include "thread.h"
 #include "options.h"
 #include "debug.h"
 
@@ -1136,8 +1138,11 @@
 BOOL32 WINAPI PostThreadMessage32A(DWORD idThread , UINT32 message,
                                    WPARAM32 wParam, LPARAM lParam )
 {
-   FIXME(sendmsg, "(...): Stub\n");
-   return FALSE;
+   THDB *thdb = THREAD_ID_TO_THDB(idThread);
+   if (!thdb || !thdb->process) return FALSE;
+
+   FIXME(sendmsg, "(...): Should use thread-local message queue!\n");
+   return PostAppMessage16(thdb->process->task, message, wParam, lParam);
 }
 
 /***********************************************************************
diff --git a/windows/nonclient.c b/windows/nonclient.c
index fe7e7c9..752f2cc 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -150,7 +150,7 @@
             rect->top -= SYSMETRICS_CYCAPTION - SYSMETRICS_CYBORDER;
     }
     if (menu) rect->top -= SYSMETRICS_CYMENU + SYSMETRICS_CYBORDER + 2;
-    else rect->top += SYSMETRICS_CYBORDER;
+    else  if (!(style & WS_CHILD)) rect->top += SYSMETRICS_CYBORDER;
 
     if (style & WS_VSCROLL) rect->right  += SYSMETRICS_CXVSCROLL;
     if (style & WS_HSCROLL) rect->bottom += SYSMETRICS_CYHSCROLL;
diff --git a/windows/property.c b/windows/property.c
index 43bc978..f2ffc8a 100644
--- a/windows/property.c
+++ b/windows/property.c
@@ -182,7 +182,7 @@
       TRACE(prop, "%04x #%04x\n", hwnd, LOWORD(str));
 
 
-    if (!pWnd) return NULL;
+    if (!pWnd) return (HANDLE32)0;
     if (HIWORD(str))
     {
         atom = GlobalFindAtom32A( str );
diff --git a/windows/queue.c b/windows/queue.c
index 7ecd256..a34e460 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -72,6 +72,7 @@
  */
 void QUEUE_WalkQueues(void)
 {
+    char module[10];
     HQUEUE16 hQueue = hFirstQueue;
 
     fprintf( stderr, "Queue Size Msgs Task\n" );
@@ -83,9 +84,10 @@
             fprintf( stderr, "*** Bad queue handle %04x\n", hQueue );
             return;
         }
-        fprintf( stderr, "%04x %5d %4d %04x %s\n",
-                 hQueue, queue->msgSize, queue->msgCount, queue->hTask,
-                 MODULE_GetModuleName( queue->hTask ) );
+        if (!GetModuleName( queue->hTask, module, sizeof(module )))
+            strcpy( module, "???" );
+        fprintf( stderr, "%04x %5d %4d %04x %s\n", hQueue, queue->msgSize,
+                 queue->msgCount, queue->hTask, module );
         hQueue = queue->next;
     }
     fprintf( stderr, "\n" );
@@ -816,7 +818,7 @@
  */
 DWORD WINAPI WaitForInputIdle (HANDLE32 hProcess, DWORD dwTimeOut)
 {
-  FIXME (msg, "(hProcess=%d, dwTimeOut=%d): stub\n", hProcess, dwTimeOut);
+  FIXME (msg, "(hProcess=%d, dwTimeOut=%ld): stub\n", hProcess, dwTimeOut);
 
   return WAIT_TIMEOUT;
 }
diff --git a/windows/syscolor.c b/windows/syscolor.c
index baf3ae5..4af477b 100644
--- a/windows/syscolor.c
+++ b/windows/syscolor.c
@@ -43,7 +43,7 @@
 
 static const char * const DefSysColors95[] =
 {
-    "Scrollbar", "224 224 224",      /* COLOR_SCROLLBAR           */
+    "Scrollbar", "223 223 223",      /* COLOR_SCROLLBAR           */
     "Background", "192 192 192",     /* COLOR_BACKGROUND          */
     "ActiveTitle", "0 64 128",       /* COLOR_ACTIVECAPTION       */
     "InactiveTitle", "255 255 255",  /* COLOR_INACTIVECAPTION     */
@@ -56,7 +56,7 @@
     "ActiveBorder", "128 128 128",   /* COLOR_ACTIVEBORDER        */
     "InactiveBorder", "255 255 255", /* COLOR_INACTIVEBORDER      */
     "AppWorkspace", "255 255 232",   /* COLOR_APPWORKSPACE        */
-    "Hilight", "224 224 224",        /* COLOR_HIGHLIGHT           */
+    "Hilight", "223 223 223",        /* COLOR_HIGHLIGHT           */
     "HilightText", "0 0 0",          /* COLOR_HIGHLIGHTTEXT       */
     "ButtonFace", "192 192 192",     /* COLOR_BTNFACE             */
     "ButtonShadow", "128 128 128",   /* COLOR_BTNSHADOW           */
@@ -64,8 +64,8 @@
     "ButtonText", "0 0 0",           /* COLOR_BTNTEXT             */
     "InactiveTitleText", "0 0 0",    /* COLOR_INACTIVECAPTIONTEXT */
     "ButtonHilight", "255 255 255",  /* COLOR_BTNHIGHLIGHT        */
-    "3DDarkShadow", "32 32 32",      /* COLOR_3DDKSHADOW          */
-    "3DLight", "192 192 192",        /* COLOR_3DLIGHT             */
+    "3DDarkShadow", "0 0 0",         /* COLOR_3DDKSHADOW          */
+    "3DLight", "223 223 223",        /* COLOR_3DLIGHT             */
     "InfoText", "0 0 0",             /* COLOR_INFOTEXT            */
     "InfoBackground", "255 255 192"  /* COLOR_INFOBK              */
 };
diff --git a/windows/winpos.c b/windows/winpos.c
index 516f6e8..043cf75 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -5,6 +5,7 @@
  *                       1995, 1996 Alex Korobka
  */
 
+#include <string.h>
 #include "ts_xlib.h"
 #include "ts_xutil.h"
 #include <X11/Xatom.h>
@@ -1010,6 +1011,19 @@
 }
 
 /***********************************************************************
+ *           ShowWindowAsync32   (USER32.535)
+ *
+ * doesn't wait; returns immediately.
+ * used by threads to toggle windows in other (possibly hanging) threads
+ */
+BOOL32 WINAPI ShowWindowAsync32( HWND32 hwnd, INT32 cmd )
+{
+    /* FIXME: does ShowWindow32() return immediately ? */
+    return ShowWindow32(hwnd, cmd);
+}
+
+
+/***********************************************************************
  *           ShowWindow16   (USER.42)
  */
 BOOL16 WINAPI ShowWindow16( HWND16 hwnd, INT16 cmd ) 
@@ -1019,7 +1033,7 @@
 
 
 /***********************************************************************
- *           ShowWindow32   (USER.42)
+ *           ShowWindow32   (USER32.534)
  */
 BOOL32 WINAPI ShowWindow32( HWND32 hwnd, INT32 cmd ) 
 {    
@@ -2499,19 +2513,24 @@
     DWP *pDWP;
     int i;
     HDWP32 newhdwp = hdwp;
-    HWND32 parent;
+    /* HWND32 parent; */
     WND *pWnd;
 
     pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp );
     if (!pDWP) return 0;
     if (hwnd == GetDesktopWindow32()) return 0;
 
-    /* All the windows of a DeferWindowPos() must have the same parent */
     if (!(pWnd=WIN_FindWndPtr( hwnd ))) {
         USER_HEAP_FREE( hdwp );
         return 0;
     }
     	
+/* Numega Bounds Checker Demo dislikes the following code.
+   In fact, I've not been able to find any "same parent" requirement in any docu
+   [AM 980509]
+ */
+#if 0
+    /* All the windows of a DeferWindowPos() must have the same parent */
     parent = pWnd->parent->hwndSelf;
     if (pDWP->actualCount == 0) pDWP->hwndParent = parent;
     else if (parent != pDWP->hwndParent)
@@ -2519,6 +2538,7 @@
         USER_HEAP_FREE( hdwp );
         return 0;
     }
+#endif
 
     for (i = 0; i < pDWP->actualCount; i++)
     {
diff --git a/windows/winproc.c b/windows/winproc.c
index 517272b..7f777cf 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -1406,6 +1406,9 @@
             *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
         /* else nothing to do */
         return 0;
+    case WM_NOTIFY:
+	*plparam = MapLS( (NMHDR *)*plparam ); /* NMHDR is already 32-bit */
+	return 1;
     case WM_SETTEXT:
         {
             LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
@@ -1574,6 +1577,9 @@
             SEGPTR_FREE(wp);
         }
         break;
+    case WM_NOTIFY:
+	UnMapLS(p16->lParam);
+	break;
     }
 }