Release 980614

Sun Jun 15 10:30:35 1998  Andreas Mohr <100.30936@germany.net>

	* [files/dos_fs.c] [files/file.c] [if1632/wprocs.spec]
	  [misc/aspi.c]
	Added support for scanners that need Adaptec's ASPI2DOS.

	* [graphics/env.c] [misc/printerdrv.c] [graphics/win16drv/init.c]
	  [if1632/gdi.spec] [include/gdi.h]
	Enhanced printer support (especially Win95):
	Drv[GS]etPrinterData, [GS]etEnvironment; added AbortProc handling.

	* [misc/tapi32.c] [relay32/tapi32.spec]
	Added some stubs.

	* [configure.in] [graphics/fontengine.c] [include/windows.h]
	  [misc/comm.c] [misc/w32skrnl.c] [misc/win32s16.c]
	Made Wine compile on HP-UX (just for fun ;)

	* [controls/menu.c] [include/windows.h]
	Complete rewrite of EnableMenuItem32.
	Free Agent 32 still doesn't work :(

	* [misc/version.c] [if1632/kernel.spec] [include/winbase.h]
	Implemented GetVersionEx16.

	* [misc/network.c] [if1632/user.spec]
	Fixed arguments of WNetGetPropertyText.

	* [misc/version.c] [relay32/comctl32.spec] [relay32/oleaut32.spec]
	Implemented COMCTL32_DllGetVersion, OaBuildVersion.

	* [win32/file.c]
	Fixed UNC handling of CreateFile32.

Sat Jun 13 22:35:12 1998  Douglas Ridgway  <ridgway@winehq.com>

	* [Makefile.in] [Make.rules.in]
	Added pattern for CVS merge files to 'make clean'

	* [ole/olecli.c] [windows/scroll.c] [windows/grahics.c]
	Add some DC handle unlocking. (When hdc's are always unlocked,
	they can be made moveable.)

	* [documentation/wine.texinfo] 
	Started a Wine Design chapter with discussion of 
	graphics driver model.

Sat Jun 13 11:19:25 1998  David Luyer <luyer@ucs.uwa.edu.au>

	* [misc/main.c] [relay32/relay386.c]
	Added new option -debugmsg +relay=.... or -debugmsg -relay=...

Fri Jun 12 22:56:09 1998  Marcus Meissner <marcus@jet.franken.de>

	* [relay32/snoop.c][relay32/builtin.c][loader/pe_image.c]
	Added inter win32 dll snooping. Use -debugmsg +snoop.
	Number of arguments and string references are autodetected.
	Some small bugfixes in the PE loader.

	* [misc/system.c]
	Disabled SystemTimers. They do not work with the current
	%fs handling in the 32->16 relaycode. (helps labview)

	* [msdos/dpmi.c][msdos/int2f.c][files/drive.c]
	Added a monoton linear increasing memory allocator for DPMI (required
	for LabView, HAFAS, ...)
	mscdex handling in emulated realmode interrupts (for mcicda.drv)
	allocate logical drives only once. (helps Myst)

	* [files/profile.c]
	Handle ^Z as space. Found on CDROMS (helps Myst Installer).

	* [multimedia/mmio.c]
	mmio* partially updated to win32. No funny additions.

	* [windows/driver.c]
	Added win32 driver handling (will be used for win32 multimedia/
	msvideo drivers).

	* [win32/device.c]
	Added device handling (K32OBJ_DEVICE_IOCTL). Implemented 
	VTDAPI.5 (used by win95' WINMM.timeGetTime())

Fri Jun 12 18:01:18 1998 Rein Klazes <rklazes@casema.net>

	* [ole/compobj.c relay32/ole32.spec]
	Add a stub for CoLockObjectExternal32.

	* [objects/clipping.c]
	Fix in IntersectClipRect(), when there is no initial clipping
	region.

	* [graphics/x11drv/graphics.c]
	Corrected several "one-off" errors for the Ellipse, Rectangle
	and RoundRectangle (especially small ones) draw routines. 
	Arc and friends still have to be done.

Fri Jun 12 06:23:19 1998  Matthew Becker <mbecker@glasscity.net>

	* [misc/ntdll.c]
	Fixed some of the parameter counts.

	* [misc/registry.c]
	General cleanup, documentation.
	Standard keys are allowed to be 'closed' and succeed.

	* [misc/shell.c]
	Check for correct return values from Reg* functions.

	* [win32/newfns.c]
	Added stubs for OpenDesktopA, SetThreadDesktop, and
	SetUserObjectInformationA.

Wed Jun 10  20:28:08 1998  James Juran  <jrj120@psu.edu>

	* [debugger/break.c]
	Fixed bug introduced in 980503 that broke the -debug command 
	line option for PE executable files.

	* [configure.in] [include/acconfig.h] [include/debugtools.h]
	  [documentation/debug-msgs]
	Added 'configure' options to compile out debugging messages.
	Use --disable-debug to disable all debugging messages, and
	--disable-trace to just disable TRACE messages.  This results
	in a stripped executable that is 15-20% smaller.  This option
	is very much untested--don't expect it to work.

	* [documentation/debug-msgs] [documentation/debugging]
	Minor updates.

	* [*/*.c]
	Fixed some compile warnings.  This also includes the
	compile_warnings_trivial patch from WineHQ.

Tue Jun 10 22:00:18 1998  Eric Kohl <ekohl@abo.rhein-zeitung.de>

	* [windows/sysmetrics.c][include/sysmetrics.h]
	Fixed some Win95 values.

	* [windows/nonclient.c][include/windows.h]
	Fixed some Win95 drawing bugs.
	Added extended window style flags (WS_EX_xxx).

	* [misc/printdrv.c][relay32/winspool.spec]
	Added stubs for DeletePrinterDriver32A, DeleteMonitor32A
	and DeletePort32A.

	* [windows/mdi.c][include/windows.h][relay32/user32.spec]
	Added stubs for CascadeWindows and TileWindows.

	* [controls/toolbar.c][include/toolbar.h]
	Fixed a few bugs and implemented new features.

	* [misc/shellord.c][relay32/shell32.spec]
	Added stubs for SHELL32_60, SHELL32_61 and SHELL32_184.

	* [controls/comctl32undoc.c][relay32/comctl32.spec]
	New file comctl32undoc.c. Contains undocumented functions
	of COMCTL32.DLL. These functions are needed to run EXPLORER.EXE
	IEXPLORE.EXE and TASKMAN.EXE.

	* [controls/status.c]
	Added text alignment.

Tue Jun  8 22:00:00 1998  Bertho Stultiens <bertho@akhphd.au.dk>

	* [programs/*/Makefile.in]
	Changed the rules to use wrc as resource compiler but
	passing the source through gcc first for macro expansion.

	* [programs/*/*.rc]
	Added #include "windows.h" for the resource compiler in the
	appropriate files.

	* [tools/wrc/wrc.[ch]] [tools/wrc/writeres.c]
	Added commandline option -A for autoregister code.
	Corrected the underscore problem by checking the proper define
	from config.h.

Sun Jun  7 22:09:29 1998  Pascal Cuoq <pcuoq@ens-lyon.fr>

	* [ole/ole2nls.c] [memory/string.c]
	Improved LCMapString32A, and changed CompareString32A,
	lstrcmp, lstrcmpi to use it.

Sat Jun  6 19:00:50 1998  Martin Strömberg <ams@ludd.luth.se>

	* [include/winnt.h]
	Added typedefs for security and tokens.

Sat Jun  6 12:26:31 1998  Morten Welinder  <terra@diku.dk>

	* [objects/text.c]
	Use debugstr_an in DrawText16.

	* [loader/resource.c]
	Use debugres_w in FindResourceEx32W.  Avoid crashing during
	debug when wm is NULL.

	* [if1632/relay.c]
	In RELAY_DebugCallTo16, send output to the right place and
	avoid side effects in macro arguments.

Wed Jun  3 20:56:03 1998  Huw D M Davies <daviesh@abacus.physics.ox.ac.uk>

	* [controls/scroll.c] [windows/nonclient.c]
	Fix several off by one errors in scrollbar painting.

Tue Jun  2 23:58:59 1998  Insomnia (Stea Greene) <insomnia@core.binghamton.edu>

	* [graphics/dsound.c]
	Rewrote mixer code to handle panning and volume for 16->16, 16->8,
	8->16, and 8->8 bit mixes.  Conforms to DirectX's "logarithmic
	hearing scale" as specified in M$VC docs.  Still does not handle
	mixing of different frequencies (I am still working on that). 
	Tested 16->16 extensively with StarCraft.  Other mixing combinations
	untested but should work fine.  Still kind of a work in progress,
	so be warned.

Tue Jun  2 03:31:33 1998  Alexander V. Lukyanov <lav@long.yar.ru>

	* [tools/wrc/utils.c]
	dup_basename: fix to strip directory.

Mon Jun  1 20:00:00 1998  Juergen Schmied <juergen.schmied@metronet.de>

	* [include/windows.h] [objects/cursoricon.c] [relay32/user32.spec]
	Added stubs LoadCursorFromFileW and LoadCursorFromFileA.
diff --git a/ANNOUNCE b/ANNOUNCE
index 6fd775c..1697c1e 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,14 +1,13 @@
-This is release 980601 of Wine, the MS Windows emulator.  This is still a
+This is release 980614 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-980601: (see ChangeLog for details)
-	- New resource compiler.
-	- Toolbar control.
-	- Partial implementation of CreateDIBSection.
+WHAT'S NEW with Wine-980614: (see ChangeLog for details)
+	- Many drawing fixes.
+	- Inter-DLL calls snooping.
 	- 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-980601.tar.gz
-  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-980601.tar.gz
-  ftp://ftp.infomagic.com/pub/mirrors/linux/sunsite/ALPHA/wine/development/Wine-980601.tar.gz
-  ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-980601.tar.gz
+  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-980614.tar.gz
+  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-980614.tar.gz
+  ftp://ftp.infomagic.com/pub/mirrors/linux/sunsite/ALPHA/wine/development/Wine-980614.tar.gz
+  ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-980614.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/BUGS b/BUGS
index 7ca200c..8e26b04 100644
--- a/BUGS
+++ b/BUGS
@@ -5,26 +5,27 @@
 add new entries and, more importantly, remove those for the 
 bugs you fixed ;-)
 ------------------------------------------------------------
-As of Dec 1997 -
+As of Jun 1998 -
 
 General:
 
  * TrueType, .FON rasterizer.
 
- * No thread/process scheduling support in Win32 code. 
+ * Incomplete thread/process scheduling support in Win32 code.
 
- * Very alpha printing code. [john@division.co.uk]
+ * Very alpha printing code using win16 drivers.
+   We should add a WINE internal PostScript driver (all other printers
+   can be supported using ghostscript filters).
 
  * Extremely alpha Win95 interface code.
 
  * No OLE2 and OLE32 support (including OLE2 interfaces etc.).
 
- * No MS Video support (perhaps interface with xanim, don't hold
-   your breath for this one).
+ * No MS Video support. [just started, marcus@jet.franken.de]
 
- * COMDLG32 support not complete yet.
+ * COMDLG32 support not complete yet [bertho@akhphd.au.dk?]
 
- * No COMMCTRL/COMCTL32 support.
+ * COMMCTRL/COMCTL32 support in progress [ekohl@abo.rhein-zeitung.de].
 
  * No manual pages describing the various Windows calls.
 	- You can find information about most of the Win32 API calls
@@ -38,6 +39,7 @@
 
  * 16-bit Eudora 1.5.2 goes into recursion trying to display
    a horizontal scrollbar (SetScrollPos() artifact).
+   Windows95 telnet.exe and NT 3.51 telnet.exe exhibit the same behaviour.
 
  * mIRC 'commands' menu stays on top and will not refresh.
 
@@ -53,7 +55,7 @@
    (probably because of bytes width stuff).
 
  * Netscape displays partially downloaded inline graphics with
-   wrong offsets. 
+   wrong offsets.
 
  * Text alignment problems in Word and Write (variable pitch fonts).
 
diff --git a/ChangeLog b/ChangeLog
index ca76271..2c4b965 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,213 @@
 ----------------------------------------------------------------------
+Sun Jun 15 10:30:35 1998  Andreas Mohr <100.30936@germany.net>
+
+	* [files/dos_fs.c] [files/file.c] [if1632/wprocs.spec]
+	  [misc/aspi.c]
+	Added support for scanners that need Adaptec's ASPI2DOS.
+
+	* [graphics/env.c] [misc/printerdrv.c] [graphics/win16drv/init.c]
+	  [if1632/gdi.spec] [include/gdi.h]
+	Enhanced printer support (especially Win95):
+	Drv[GS]etPrinterData, [GS]etEnvironment; added AbortProc handling.
+
+	* [misc/tapi32.c] [relay32/tapi32.spec]
+	Added some stubs.
+
+	* [configure.in] [graphics/fontengine.c] [include/windows.h]
+	  [misc/comm.c] [misc/w32skrnl.c] [misc/win32s16.c]
+	Made Wine compile on HP-UX (just for fun ;)
+
+	* [controls/menu.c] [include/windows.h]
+	Complete rewrite of EnableMenuItem32.
+	Free Agent 32 still doesn't work :(
+
+	* [misc/version.c] [if1632/kernel.spec] [include/winbase.h]
+	Implemented GetVersionEx16.
+
+	* [misc/network.c] [if1632/user.spec]
+	Fixed arguments of WNetGetPropertyText.
+
+	* [misc/version.c] [relay32/comctl32.spec] [relay32/oleaut32.spec]
+	Implemented COMCTL32_DllGetVersion, OaBuildVersion.
+
+	* [win32/file.c]
+	Fixed UNC handling of CreateFile32.
+
+Sat Jun 13 22:35:12 1998  Douglas Ridgway  <ridgway@winehq.com>
+
+	* [Makefile.in] [Make.rules.in]
+	Added pattern for CVS merge files to 'make clean'
+
+	* [ole/olecli.c] [windows/scroll.c] [windows/grahics.c]
+	Add some DC handle unlocking. (When hdc's are always unlocked,
+	they can be made moveable.)
+
+	* [documentation/wine.texinfo] 
+	Started a Wine Design chapter with discussion of 
+	graphics driver model.
+
+Sat Jun 13 11:19:25 1998  David Luyer <luyer@ucs.uwa.edu.au>
+
+	* [misc/main.c] [relay32/relay386.c]
+	Added new option -debugmsg +relay=.... or -debugmsg -relay=...
+
+Fri Jun 12 22:56:09 1998  Marcus Meissner <marcus@jet.franken.de>
+
+	* [relay32/snoop.c][relay32/builtin.c][loader/pe_image.c]
+	Added inter win32 dll snooping. Use -debugmsg +snoop.
+	Number of arguments and string references are autodetected.
+	Some small bugfixes in the PE loader.
+
+	* [misc/system.c]
+	Disabled SystemTimers. They do not work with the current
+	%fs handling in the 32->16 relaycode. (helps labview)
+
+	* [msdos/dpmi.c][msdos/int2f.c][files/drive.c]
+	Added a monoton linear increasing memory allocator for DPMI (required
+	for LabView, HAFAS, ...)
+	mscdex handling in emulated realmode interrupts (for mcicda.drv)
+	allocate logical drives only once. (helps Myst)
+
+	* [files/profile.c]
+	Handle ^Z as space. Found on CDROMS (helps Myst Installer).
+
+	* [multimedia/mmio.c]
+	mmio* partially updated to win32. No funny additions.
+
+	* [windows/driver.c]
+	Added win32 driver handling (will be used for win32 multimedia/
+	msvideo drivers).
+
+	* [win32/device.c]
+	Added device handling (K32OBJ_DEVICE_IOCTL). Implemented 
+	VTDAPI.5 (used by win95' WINMM.timeGetTime())
+
+Fri Jun 12 18:01:18 1998 Rein Klazes <rklazes@casema.net>
+
+	* [ole/compobj.c relay32/ole32.spec]
+	Add a stub for CoLockObjectExternal32.
+
+	* [objects/clipping.c]
+	Fix in IntersectClipRect(), when there is no initial clipping
+	region.
+
+	* [graphics/x11drv/graphics.c]
+	Corrected several "one-off" errors for the Ellipse, Rectangle
+	and RoundRectangle (especially small ones) draw routines. 
+	Arc and friends still have to be done.
+
+Fri Jun 12 06:23:19 1998  Matthew Becker <mbecker@glasscity.net>
+
+	* [misc/ntdll.c]
+	Fixed some of the parameter counts.
+
+	* [misc/registry.c]
+	General cleanup, documentation.
+	Standard keys are allowed to be 'closed' and succeed.
+
+	* [misc/shell.c]
+	Check for correct return values from Reg* functions.
+
+	* [win32/newfns.c]
+	Added stubs for OpenDesktopA, SetThreadDesktop, and
+	SetUserObjectInformationA.
+
+Tue Jun 10 22:00:18 1998  Eric Kohl <ekohl@abo.rhein-zeitung.de>
+
+	* [windows/sysmetrics.c][include/sysmetrics.h]
+	Fixed some Win95 values.
+
+	* [windows/nonclient.c][include/windows.h]
+	Fixed some Win95 drawing bugs.
+	Added extended window style flags (WS_EX_xxx).
+
+	* [misc/printdrv.c][relay32/winspool.spec]
+	Added stubs for DeletePrinterDriver32A, DeleteMonitor32A
+	and DeletePort32A.
+
+	* [windows/mdi.c][include/windows.h][relay32/user32.spec]
+	Added stubs for CascadeWindows and TileWindows.
+
+	* [controls/toolbar.c][include/toolbar.h]
+	Fixed a few bugs and implemented new features.
+
+	* [misc/shellord.c][relay32/shell32.spec]
+	Added stubs for SHELL32_60, SHELL32_61 and SHELL32_184.
+
+	* [controls/comctl32undoc.c][relay32/comctl32.spec]
+	New file comctl32undoc.c. Contains undocumented functions
+	of COMCTL32.DLL. These functions are needed to run EXPLORER.EXE
+	IEXPLORE.EXE and TASKMAN.EXE.
+
+	* [controls/status.c]
+	Added text alignment.
+
+Tue Jun  8 22:00:00 1998  Bertho Stultiens <bertho@akhphd.au.dk>
+
+	* [programs/*/Makefile.in]
+	Changed the rules to use wrc as resource compiler but
+	passing the source through gcc first for macro expansion.
+
+	* [programs/*/*.rc]
+	Added #include "windows.h" for the resource compiler in the
+	appropriate files.
+
+	* [tools/wrc/wrc.[ch]] [tools/wrc/writeres.c]
+	Added commandline option -A for autoregister code.
+	Corrected the underscore problem by checking the proper define
+	from config.h.
+
+Sun Jun  7 22:09:29 1998  Pascal Cuoq <pcuoq@ens-lyon.fr>
+
+	* [ole/ole2nls.c] [memory/string.c]
+	Improved LCMapString32A, and changed CompareString32A,
+	lstrcmp, lstrcmpi to use it.
+
+Sat Jun  6 19:00:50 1998  Martin Strömberg <ams@ludd.luth.se>
+
+	* [include/winnt.h]
+	Added typedefs for security and tokens.
+
+Sat Jun  6 12:26:31 1998  Morten Welinder  <terra@diku.dk>
+
+	* [objects/text.c]
+	Use debugstr_an in DrawText16.
+
+	* [loader/resource.c]
+	Use debugres_w in FindResourceEx32W.  Avoid crashing during
+	debug when wm is NULL.
+
+	* [if1632/relay.c]
+	In RELAY_DebugCallTo16, send output to the right place and
+	avoid side effects in macro arguments.
+
+Wed Jun  3 20:56:03 1998  Huw D M Davies <daviesh@abacus.physics.ox.ac.uk>
+
+	* [controls/scroll.c] [windows/nonclient.c]
+	Fix several off by one errors in scrollbar painting.
+
+Tue Jun  2 23:58:59 1998  Insomnia (Stea Greene) <insomnia@core.binghamton.edu>
+
+	* [graphics/dsound.c]
+	Rewrote mixer code to handle panning and volume for 16->16, 16->8,
+	8->16, and 8->8 bit mixes.  Conforms to DirectX's "logarithmic
+	hearing scale" as specified in M$VC docs.  Still does not handle
+	mixing of different frequencies (I am still working on that). 
+	Tested 16->16 extensively with StarCraft.  Other mixing combinations
+	untested but should work fine.  Still kind of a work in progress,
+	so be warned.
+
+Tue Jun  2 03:31:33 1998  Alexander V. Lukyanov <lav@long.yar.ru>
+
+	* [tools/wrc/utils.c]
+	dup_basename: fix to strip directory.
+
+Mon Jun  1 20:00:00 1998  Juergen Schmied <juergen.schmied@metronet.de>
+
+	* [include/windows.h] [objects/cursoricon.c] [relay32/user32.spec]
+	Added stubs LoadCursorFromFileW and LoadCursorFromFileA.
+
+----------------------------------------------------------------------
 Sun May 31 13:40:13 1998  Alexandre Julliard  <julliard@lrc.epfl.ch>
 
 	* [if1632/signal.c]
diff --git a/Make.rules.in b/Make.rules.in
index 5fefa53..4fc1b6c 100644
--- a/Make.rules.in
+++ b/Make.rules.in
@@ -155,7 +155,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=.s) $(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=.s) $(RC_SRCS:.rc=.h) $(PROGRAMS)
 
 dummy:
 
diff --git a/Makefile.in b/Makefile.in
index 9fe1c38..a0674fe 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -24,7 +24,6 @@
 MODULE    = none
 
 LIBSUBDIRS = \
-	rc \
 	tools \
 	tools/wrc \
 	controls \
@@ -160,8 +159,8 @@
 
 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
-	$(RM) wine wine.sym libwine.a libwine.so.1.0 TAGS
+	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
 	$(RM) config.* Make.rules include/config.h
diff --git a/configure b/configure
index 338b548..409b3f5 100755
--- a/configure
+++ b/configure
@@ -17,6 +17,10 @@
 ac_help="$ac_help
   --enable-dll            build the Wine library as a DLL"
 ac_help="$ac_help
+  --disable-debug         compile out all debugging messages"
+ac_help="$ac_help
+  --disable-trace         compile out TRACE messages"
+ac_help="$ac_help
   --without-reentrant-x   Compile for use with non-reentrant X libraries"
 ac_help="$ac_help
   --with-x                use the X Window System"
@@ -555,6 +559,8 @@
 
 MAIN_TARGET=emu
 LIB_TARGET=libwine.a
+TRACE_MSGS=yes	# the TRACE() macro
+DEBUG_MSGS=yes	# the TRACE(), WARN(), and FIXME() macros.
 
 # Check whether --enable-emulator or --disable-emulator was given.
 if test "${enable_emulator+set}" = set; then
@@ -571,6 +577,20 @@
 
 
 
+# Check whether --enable-debug or --disable-debug was given.
+if test "${enable_debug+set}" = set; then
+  enableval="$enable_debug"
+  if test "$enableval" = "no"; then DEBUG_MSGS="no"; fi
+fi
+
+
+# Check whether --enable-trace or --disable-trace was given.
+if test "${enable_trace+set}" = set; then
+  enableval="$enable_trace"
+  if test "$enableval" = "no"; then TRACE_MSGS="no"; fi
+fi
+
+
 # Check whether --with-reentrant-x or --without-reentrant-x was given.
 if test "${with_reentrant_x+set}" = set; then
   withval="$with_reentrant_x"
@@ -582,9 +602,29 @@
 
 
 
+if test "$DEBUG_MSGS" = "no"
+then
+    cat >> confdefs.h <<\EOF
+#define NO_DEBUG_MSGS 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define NO_TRACE_MSGS 1
+EOF
+
+else
+    if test "$TRACE_MSGS" = "no"
+    then
+        cat >> confdefs.h <<\EOF
+#define NO_TRACE_MSGS 1
+EOF
+
+    fi
+fi
+
 
 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:588: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:628: checking whether ${MAKE-make} sets \${MAKE}" >&5
 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -613,7 +653,7 @@
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:617: checking for $ac_word" >&5
+echo "configure:657: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -642,7 +682,7 @@
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:646: checking for $ac_word" >&5
+echo "configure:686: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -690,7 +730,7 @@
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:694: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:734: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -700,11 +740,11 @@
 cross_compiling=$ac_cv_prog_cc_cross
 
 cat > conftest.$ac_ext <<EOF
-#line 704 "configure"
+#line 744 "configure"
 #include "confdefs.h"
 main(){return(0);}
 EOF
-if { (eval echo configure:708: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:748: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -724,12 +764,12 @@
   { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:728: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:768: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:733: checking whether we are using GNU C" >&5
+echo "configure:773: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -738,7 +778,7 @@
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:742: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:782: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -753,7 +793,7 @@
   ac_save_CFLAGS="$CFLAGS"
   CFLAGS=
   echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:757: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:797: checking whether ${CC-cc} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -781,7 +821,7 @@
 fi
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:785: checking how to run the C preprocessor" >&5
+echo "configure:825: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -796,13 +836,13 @@
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 800 "configure"
+#line 840 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:806: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:846: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -813,13 +853,13 @@
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 817 "configure"
+#line 857 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:823: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:863: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -846,7 +886,7 @@
 # Uses ac_ vars as temps to allow command line to override cache and checks.
 # --without-x overrides everything else, but does not touch the cache.
 echo $ac_n "checking for X""... $ac_c" 1>&6
-echo "configure:850: checking for X" >&5
+echo "configure:890: checking for X" >&5
 
 # Check whether --with-x or --without-x was given.
 if test "${with_x+set}" = set; then
@@ -908,12 +948,12 @@
 
   # First, try using that file with no special directory specified.
 cat > conftest.$ac_ext <<EOF
-#line 912 "configure"
+#line 952 "configure"
 #include "confdefs.h"
 #include <$x_direct_test_include>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:917: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:957: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -982,14 +1022,14 @@
   ac_save_LIBS="$LIBS"
   LIBS="-l$x_direct_test_library $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 986 "configure"
+#line 1026 "configure"
 #include "confdefs.h"
 
 int main() {
 ${x_direct_test_function}()
 ; return 0; }
 EOF
-if { (eval echo configure:993: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1033: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   LIBS="$ac_save_LIBS"
 # We can link X programs with no special library path.
@@ -1095,17 +1135,17 @@
     case "`(uname -sr) 2>/dev/null`" in
     "SunOS 5"*)
       echo $ac_n "checking whether -R must be followed by a space""... $ac_c" 1>&6
-echo "configure:1099: checking whether -R must be followed by a space" >&5
+echo "configure:1139: checking whether -R must be followed by a space" >&5
       ac_xsave_LIBS="$LIBS"; LIBS="$LIBS -R$x_libraries"
       cat > conftest.$ac_ext <<EOF
-#line 1102 "configure"
+#line 1142 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:1109: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1149: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_R_nospace=yes
 else
@@ -1121,14 +1161,14 @@
       else
 	LIBS="$ac_xsave_LIBS -R $x_libraries"
 	cat > conftest.$ac_ext <<EOF
-#line 1125 "configure"
+#line 1165 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:1132: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1172: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_R_space=yes
 else
@@ -1160,7 +1200,7 @@
     # libraries were built with DECnet support.  And karl@cs.umb.edu says
     # the Alpha needs dnet_stub (dnet does not exist).
     echo $ac_n "checking for dnet_ntoa in -ldnet""... $ac_c" 1>&6
-echo "configure:1164: checking for dnet_ntoa in -ldnet" >&5
+echo "configure:1204: checking for dnet_ntoa in -ldnet" >&5
 ac_lib_var=`echo dnet'_'dnet_ntoa | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1168,7 +1208,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-ldnet  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1172 "configure"
+#line 1212 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1179,7 +1219,7 @@
 dnet_ntoa()
 ; return 0; }
 EOF
-if { (eval echo configure:1183: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1223: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1201,7 +1241,7 @@
 
     if test $ac_cv_lib_dnet_dnet_ntoa = no; then
       echo $ac_n "checking for dnet_ntoa in -ldnet_stub""... $ac_c" 1>&6
-echo "configure:1205: checking for dnet_ntoa in -ldnet_stub" >&5
+echo "configure:1245: checking for dnet_ntoa in -ldnet_stub" >&5
 ac_lib_var=`echo dnet_stub'_'dnet_ntoa | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1209,7 +1249,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-ldnet_stub  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1213 "configure"
+#line 1253 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1220,7 +1260,7 @@
 dnet_ntoa()
 ; return 0; }
 EOF
-if { (eval echo configure:1224: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1264: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1249,12 +1289,12 @@
     # The nsl library prevents programs from opening the X display
     # on Irix 5.2, according to dickey@clark.net.
     echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6
-echo "configure:1253: checking for gethostbyname" >&5
+echo "configure:1293: checking for gethostbyname" >&5
 if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1258 "configure"
+#line 1298 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char gethostbyname(); below.  */
@@ -1277,7 +1317,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:1281: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1321: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_gethostbyname=yes"
 else
@@ -1298,7 +1338,7 @@
 
     if test $ac_cv_func_gethostbyname = no; then
       echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6
-echo "configure:1302: checking for gethostbyname in -lnsl" >&5
+echo "configure:1342: checking for gethostbyname in -lnsl" >&5
 ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1306,7 +1346,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lnsl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1310 "configure"
+#line 1350 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1317,7 +1357,7 @@
 gethostbyname()
 ; return 0; }
 EOF
-if { (eval echo configure:1321: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1361: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1347,12 +1387,12 @@
     # -lsocket must be given before -lnsl if both are needed.
     # We assume that if connect needs -lnsl, so does gethostbyname.
     echo $ac_n "checking for connect""... $ac_c" 1>&6
-echo "configure:1351: checking for connect" >&5
+echo "configure:1391: checking for connect" >&5
 if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1356 "configure"
+#line 1396 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char connect(); below.  */
@@ -1375,7 +1415,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:1379: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1419: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_connect=yes"
 else
@@ -1396,7 +1436,7 @@
 
     if test $ac_cv_func_connect = no; then
       echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6
-echo "configure:1400: checking for connect in -lsocket" >&5
+echo "configure:1440: checking for connect in -lsocket" >&5
 ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1404,7 +1444,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lsocket $X_EXTRA_LIBS $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1408 "configure"
+#line 1448 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1415,7 +1455,7 @@
 connect()
 ; return 0; }
 EOF
-if { (eval echo configure:1419: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1459: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1439,12 +1479,12 @@
 
     # gomez@mi.uni-erlangen.de says -lposix is necessary on A/UX.
     echo $ac_n "checking for remove""... $ac_c" 1>&6
-echo "configure:1443: checking for remove" >&5
+echo "configure:1483: checking for remove" >&5
 if eval "test \"`echo '$''{'ac_cv_func_remove'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1448 "configure"
+#line 1488 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char remove(); below.  */
@@ -1467,7 +1507,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:1471: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1511: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_remove=yes"
 else
@@ -1488,7 +1528,7 @@
 
     if test $ac_cv_func_remove = no; then
       echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6
-echo "configure:1492: checking for remove in -lposix" >&5
+echo "configure:1532: checking for remove in -lposix" >&5
 ac_lib_var=`echo posix'_'remove | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1496,7 +1536,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lposix  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1500 "configure"
+#line 1540 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1507,7 +1547,7 @@
 remove()
 ; return 0; }
 EOF
-if { (eval echo configure:1511: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1551: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1531,12 +1571,12 @@
 
     # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
     echo $ac_n "checking for shmat""... $ac_c" 1>&6
-echo "configure:1535: checking for shmat" >&5
+echo "configure:1575: checking for shmat" >&5
 if eval "test \"`echo '$''{'ac_cv_func_shmat'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1540 "configure"
+#line 1580 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char shmat(); below.  */
@@ -1559,7 +1599,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:1563: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1603: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_shmat=yes"
 else
@@ -1580,7 +1620,7 @@
 
     if test $ac_cv_func_shmat = no; then
       echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6
-echo "configure:1584: checking for shmat in -lipc" >&5
+echo "configure:1624: checking for shmat in -lipc" >&5
 ac_lib_var=`echo ipc'_'shmat | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1588,7 +1628,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lipc  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1592 "configure"
+#line 1632 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1599,7 +1639,7 @@
 shmat()
 ; return 0; }
 EOF
-if { (eval echo configure:1603: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1643: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1632,7 +1672,7 @@
   # libraries we check for below, so use a different variable.
   #  --interran@uluru.Stanford.EDU, kb@cs.umb.edu.
   echo $ac_n "checking for IceConnectionNumber in -lICE""... $ac_c" 1>&6
-echo "configure:1636: checking for IceConnectionNumber in -lICE" >&5
+echo "configure:1676: checking for IceConnectionNumber in -lICE" >&5
 ac_lib_var=`echo ICE'_'IceConnectionNumber | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1640,7 +1680,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lICE  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1644 "configure"
+#line 1684 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1651,7 +1691,7 @@
 IceConnectionNumber()
 ; return 0; }
 EOF
-if { (eval echo configure:1655: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1695: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1680,7 +1720,7 @@
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1684: checking for $ac_word" >&5
+echo "configure:1724: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1712,7 +1752,7 @@
 # Extract the first word of "flex", so it can be a program name with args.
 set dummy flex; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1716: checking for $ac_word" >&5
+echo "configure:1756: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1745,7 +1785,7 @@
   *) ac_lib=l ;;
   esac
   echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6
-echo "configure:1749: checking for yywrap in -l$ac_lib" >&5
+echo "configure:1789: checking for yywrap in -l$ac_lib" >&5
 ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1753,7 +1793,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-l$ac_lib  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1757 "configure"
+#line 1797 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1764,7 +1804,7 @@
 yywrap()
 ; return 0; }
 EOF
-if { (eval echo configure:1768: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1808: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1789,7 +1829,7 @@
 # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1793: checking for $ac_word" >&5
+echo "configure:1833: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1826,7 +1866,7 @@
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:1830: checking for a BSD compatible install" >&5
+echo "configure:1870: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1876,7 +1916,7 @@
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:1880: checking whether ln -s works" >&5
+echo "configure:1920: checking whether ln -s works" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1899,7 +1939,7 @@
 # Extract the first word of "c2man", so it can be a program name with args.
 set dummy c2man; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1903: checking for $ac_word" >&5
+echo "configure:1943: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_C2MAN'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1928,7 +1968,7 @@
 
 
 echo $ac_n "checking for i386_set_ldt in -li386""... $ac_c" 1>&6
-echo "configure:1932: checking for i386_set_ldt in -li386" >&5
+echo "configure:1972: checking for i386_set_ldt in -li386" >&5
 ac_lib_var=`echo i386'_'i386_set_ldt | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1936,7 +1976,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-li386  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1940 "configure"
+#line 1980 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1947,7 +1987,7 @@
 i386_set_ldt()
 ; return 0; }
 EOF
-if { (eval echo configure:1951: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1991: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1975,7 +2015,7 @@
 fi
 
 echo $ac_n "checking for iswalnum in -lw""... $ac_c" 1>&6
-echo "configure:1979: checking for iswalnum in -lw" >&5
+echo "configure:2019: checking for iswalnum in -lw" >&5
 ac_lib_var=`echo w'_'iswalnum | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1983,7 +2023,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lw  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1987 "configure"
+#line 2027 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1994,7 +2034,7 @@
 iswalnum()
 ; return 0; }
 EOF
-if { (eval echo configure:1998: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2038: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2022,7 +2062,7 @@
 fi
 
 echo $ac_n "checking for XF86DGAQueryExtension in -lXxf86dga""... $ac_c" 1>&6
-echo "configure:2026: checking for XF86DGAQueryExtension in -lXxf86dga" >&5
+echo "configure:2066: checking for XF86DGAQueryExtension in -lXxf86dga" >&5
 ac_lib_var=`echo Xxf86dga'_'XF86DGAQueryExtension | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2030,7 +2070,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lXxf86dga $X_LIBS -lXext -lX11 $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2034 "configure"
+#line 2074 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2041,7 +2081,7 @@
 XF86DGAQueryExtension()
 ; return 0; }
 EOF
-if { (eval echo configure:2045: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2085: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2069,17 +2109,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2073: checking for $ac_hdr" >&5
+echo "configure:2113: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2078 "configure"
+#line 2118 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2083: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2123: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2107,12 +2147,12 @@
 
 
 echo $ac_n "checking "for Open Sound System"""... $ac_c" 1>&6
-echo "configure:2111: checking "for Open Sound System"" >&5
+echo "configure:2151: checking "for Open Sound System"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_opensoundsystem'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2116 "configure"
+#line 2156 "configure"
 #include "confdefs.h"
 
 	#ifdef HAVE_SYS_SOUNDCARD_H
@@ -2132,7 +2172,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2136: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2176: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_opensoundsystem="yes"
 else
@@ -2156,12 +2196,12 @@
 
 
 echo $ac_n "checking "for union semun"""... $ac_c" 1>&6
-echo "configure:2160: checking "for union semun"" >&5
+echo "configure:2200: 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 2165 "configure"
+#line 2205 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/sem.h>
@@ -2169,7 +2209,7 @@
 union semun foo
 ; return 0; }
 EOF
-if { (eval echo configure:2173: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2213: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_union_semun="yes"
 else
@@ -2197,7 +2237,7 @@
 then
   CFLAGS="$CFLAGS -Wall"
   echo $ac_n "checking "for gcc strength-reduce bug"""... $ac_c" 1>&6
-echo "configure:2201: checking "for gcc strength-reduce bug"" >&5
+echo "configure:2241: 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
@@ -2205,7 +2245,7 @@
   ac_cv_c_gcc_strength_bug="yes"
 else
   cat > conftest.$ac_ext <<EOF
-#line 2209 "configure"
+#line 2249 "configure"
 #include "confdefs.h"
 
 int main(void) {
@@ -2216,7 +2256,7 @@
   exit( Array[1] != -2 );
 }
 EOF
-if { (eval echo configure:2220: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2260: \"$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
@@ -2239,7 +2279,7 @@
 
 
 echo $ac_n "checking "whether external symbols need an underscore prefix"""... $ac_c" 1>&6
-echo "configure:2243: checking "whether external symbols need an underscore prefix"" >&5
+echo "configure:2283: 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
@@ -2251,14 +2291,14 @@
 	.long 0
 EOF
 cat > conftest.$ac_ext <<EOF
-#line 2255 "configure"
+#line 2295 "configure"
 #include "confdefs.h"
 extern int ac_test;
 int main() {
 if (ac_test) return 1
 ; return 0; }
 EOF
-if { (eval echo configure:2262: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2302: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_c_extern_prefix="yes"
 else
@@ -2282,7 +2322,7 @@
 
 
 echo $ac_n "checking "whether assembler accepts .string"""... $ac_c" 1>&6
-echo "configure:2286: checking "whether assembler accepts .string"" >&5
+echo "configure:2326: 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
@@ -2292,14 +2332,14 @@
 	.string "test"
 EOF
 cat > conftest.$ac_ext <<EOF
-#line 2296 "configure"
+#line 2336 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:2303: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2343: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_c_asm_string="yes"
 else
@@ -2326,21 +2366,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:2330: checking "whether we can build a dll"" >&5
+echo "configure:2370: 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 2337 "configure"
+#line 2377 "configure"
 #include "confdefs.h"
 
 int main() {
 return 1
 ; return 0; }
 EOF
-if { (eval echo configure:2344: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2384: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_c_dll="yes"
 else
@@ -2366,7 +2406,7 @@
 
 
 echo $ac_n "checking "for reentrant X libraries"""... $ac_c" 1>&6
-echo "configure:2370: checking "for reentrant X libraries"" >&5
+echo "configure:2410: 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
@@ -2410,12 +2450,12 @@
 for ac_func in clone getpagesize memmove sigaltstack strerror stricmp tcgetattr timegm usleep wait4 waitpid
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2414: checking for $ac_func" >&5
+echo "configure:2454: 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 2419 "configure"
+#line 2459 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2438,7 +2478,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2442: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2482: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2462,21 +2502,21 @@
 fi
 done
 
-for ac_hdr in wctype.h sys/syscall.h syscall.h sys/param.h sys/vfs.h sys/mount.h sys/statfs.h float.h linux/cdrom.h sys/cdio.h sys/filio.h
+for ac_hdr in wctype.h sys/syscall.h syscall.h sys/param.h sys/vfs.h sys/mount.h sys/statfs.h float.h linux/cdrom.h sys/cdio.h sys/filio.h sys/modem.h strings.h sys/strtio.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2470: checking for $ac_hdr" >&5
+echo "configure:2510: 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 2475 "configure"
+#line 2515 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2480: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2520: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2503,12 +2543,12 @@
 done
 
 echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6
-echo "configure:2507: checking whether stat file-mode macros are broken" >&5
+echo "configure:2547: 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 2512 "configure"
+#line 2552 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -2559,12 +2599,12 @@
 fi
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:2563: checking for working const" >&5
+echo "configure:2603: 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 2568 "configure"
+#line 2608 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -2613,7 +2653,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2617: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2657: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -2634,12 +2674,12 @@
 fi
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:2638: checking for ANSI C header files" >&5
+echo "configure:2678: 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 2643 "configure"
+#line 2683 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -2647,7 +2687,7 @@
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2651: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2691: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2664,7 +2704,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 2668 "configure"
+#line 2708 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -2682,7 +2722,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 2686 "configure"
+#line 2726 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -2703,7 +2743,7 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 2707 "configure"
+#line 2747 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -2714,7 +2754,7 @@
 exit (0); }
 
 EOF
-if { (eval echo configure:2718: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2758: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -2738,12 +2778,12 @@
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:2742: checking for size_t" >&5
+echo "configure:2782: 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 2747 "configure"
+#line 2787 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -2771,7 +2811,7 @@
 fi
 
 echo $ac_n "checking size of long long""... $ac_c" 1>&6
-echo "configure:2775: checking size of long long" >&5
+echo "configure:2815: 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
@@ -2779,7 +2819,7 @@
   ac_cv_sizeof_long_long=0
 else
   cat > conftest.$ac_ext <<EOF
-#line 2783 "configure"
+#line 2823 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -2790,7 +2830,7 @@
   exit(0);
 }
 EOF
-if { (eval echo configure:2794: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2834: \"$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
@@ -2814,12 +2854,12 @@
 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
+echo "configure:2858: 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"
+#line 2863 "configure"
 #include "confdefs.h"
 
 	#include <sys/types.h>
@@ -2836,7 +2876,7 @@
 	
 ; return 0; }
 EOF
-if { (eval echo configure:2840: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2880: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_sys_vfs_has_statfs=yes
 else
@@ -2863,12 +2903,12 @@
 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
+echo "configure:2907: 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"
+#line 2912 "configure"
 #include "confdefs.h"
 
 	#include <sys/types.h>
@@ -2883,7 +2923,7 @@
 	
 ; return 0; }
 EOF
-if { (eval echo configure:2887: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2927: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_sys_statfs_has_statfs=yes
 else
@@ -2910,12 +2950,12 @@
 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
+echo "configure:2954: 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"
+#line 2959 "configure"
 #include "confdefs.h"
 
 	#include <sys/types.h>
@@ -2930,7 +2970,7 @@
 	
 ; return 0; }
 EOF
-if { (eval echo configure:2934: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2974: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_sys_mount_has_statfs=yes
 else
@@ -2956,7 +2996,7 @@
 
 
 echo $ac_n "checking "for statfs.f_bfree"""... $ac_c" 1>&6
-echo "configure:2960: checking "for statfs.f_bfree"" >&5
+echo "configure:3000: 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
@@ -2965,7 +3005,7 @@
         wine_cv_statfs_bfree=no
     else
     	cat > conftest.$ac_ext <<EOF
-#line 2969 "configure"
+#line 3009 "configure"
 #include "confdefs.h"
 
 	#include <sys/types.h>
@@ -2992,7 +3032,7 @@
 	
 ; return 0; }
 EOF
-if { (eval echo configure:2996: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3036: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_statfs_bfree=yes
 else
@@ -3016,7 +3056,7 @@
 fi
 
 echo $ac_n "checking "for statfs.f_bavail"""... $ac_c" 1>&6
-echo "configure:3020: checking "for statfs.f_bavail"" >&5
+echo "configure:3060: 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
@@ -3025,7 +3065,7 @@
         wine_cv_statfs_bavail=no
     else
     	cat > conftest.$ac_ext <<EOF
-#line 3029 "configure"
+#line 3069 "configure"
 #include "confdefs.h"
 
 	#include <sys/types.h>
@@ -3052,7 +3092,7 @@
 	
 ; return 0; }
 EOF
-if { (eval echo configure:3056: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3096: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_statfs_bavail=yes
 else
@@ -3077,7 +3117,7 @@
 
 
 echo $ac_n "checking "for working sigaltstack"""... $ac_c" 1>&6
-echo "configure:3081: checking "for working sigaltstack"" >&5
+echo "configure:3121: 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
@@ -3086,7 +3126,7 @@
 
 else
   cat > conftest.$ac_ext <<EOF
-#line 3090 "configure"
+#line 3130 "configure"
 #include "confdefs.h"
 
 	#include <stdio.h>
@@ -3124,7 +3164,7 @@
 	}
 	
 EOF
-if { (eval echo configure:3128: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3168: \"$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
diff --git a/configure.in b/configure.in
index 91bc37d..ae9944c 100644
--- a/configure.in
+++ b/configure.in
@@ -15,6 +15,8 @@
 dnl Default values
 MAIN_TARGET=emu
 LIB_TARGET=libwine.a
+TRACE_MSGS=yes	# the TRACE() macro
+DEBUG_MSGS=yes	# the TRACE(), WARN(), and FIXME() macros.
 
 AC_ARG_ENABLE(emulator,
 [  --disable-emulator      build only the Wine library, not the emulator],
@@ -28,6 +30,14 @@
 dnl [  --enable-ipc            use inter-process communication for DDE],
 dnl [if test "$enableval" = "no"; then : ; else OPTIONS="-DCONFIG_IPC"; fi])
 
+AC_ARG_ENABLE(debug,
+[  --disable-debug         compile out all debugging messages],
+[if test "$enableval" = "no"; then DEBUG_MSGS="no"; fi])
+
+AC_ARG_ENABLE(trace,
+[  --disable-trace         compile out TRACE messages],
+[if test "$enableval" = "no"; then TRACE_MSGS="no"; fi])
+
 AC_ARG_WITH(reentrant-x,
 [  --without-reentrant-x   Compile for use with non-reentrant X libraries])
 
@@ -35,6 +45,17 @@
 AC_SUBST(LIB_TARGET)
 AC_SUBST(OPTIONS)
 
+if test "$DEBUG_MSGS" = "no"
+then
+    AC_DEFINE(NO_DEBUG_MSGS)
+    AC_DEFINE(NO_TRACE_MSGS)
+else
+    if test "$TRACE_MSGS" = "no"
+    then
+        AC_DEFINE(NO_TRACE_MSGS)
+    fi
+fi
+
 dnl **** Check for some programs ****
 
 AC_PROG_MAKE_SET
@@ -215,7 +236,7 @@
 dnl **** Check for functions and header files ****
 
 AC_CHECK_FUNCS(clone getpagesize memmove sigaltstack strerror stricmp tcgetattr timegm usleep wait4 waitpid)
-AC_CHECK_HEADERS(wctype.h sys/syscall.h syscall.h sys/param.h sys/vfs.h sys/mount.h sys/statfs.h float.h linux/cdrom.h sys/cdio.h sys/filio.h)
+AC_CHECK_HEADERS(wctype.h sys/syscall.h syscall.h sys/param.h sys/vfs.h sys/mount.h sys/statfs.h float.h linux/cdrom.h sys/cdio.h sys/filio.h sys/modem.h strings.h sys/strtio.h)
 AC_HEADER_STAT()
 AC_C_CONST()
 AC_TYPE_SIZE_T()
diff --git a/controls/Makefile.in b/controls/Makefile.in
index ff92f5c..f36a382 100644
--- a/controls/Makefile.in
+++ b/controls/Makefile.in
@@ -8,6 +8,7 @@
 C_SRCS = \
 	button.c \
 	combo.c \
+	comctl32undoc.c \
 	commctrl.c \
 	desktop.c \
 	edit.c \
diff --git a/controls/comctl32undoc.c b/controls/comctl32undoc.c
new file mode 100644
index 0000000..2719e3b
--- /dev/null
+++ b/controls/comctl32undoc.c
@@ -0,0 +1,333 @@
+/*
+ * Undocumented functions from COMCTL32.DLL
+ *
+ * Copyright 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de>
+ *
+ * NOTES
+ *     All of these functions are UNDOCUMENTED!! And I mean UNDOCUMENTED!!!!
+ *     Do NOT rely on names of undocumented structures and types!!!
+ *     These functions are used by EXPLORER.EXE, IEXPLORE.EXE and
+ *     COMCTL32.DLL (internally).
+ *
+ * TODO
+ *     - Fix DSA_InsertItem.
+ *     - Write documentation.
+ */
+
+#include <string.h>
+#include "windows.h"
+#include "heap.h"
+#include "debug.h"
+
+
+typedef struct _DSA_DATA
+{
+    DWORD   dwEntryCount;
+    DWORD   dwMaxCount;
+    DWORD   dwInitial;
+    DWORD   dwGrow;
+    LPSTR   *ptrs;
+} DSA_DATA, *LPDSA_DATA;
+
+
+typedef struct _DPA_DATA
+{
+    DWORD   dwEntryCount;
+    DWORD   dwMaxCount;
+    DWORD   dwGrow;
+    LPDWORD ptrs; 
+} DPA_DATA, *LPDPA_DATA;
+
+
+DWORD WINAPI Alloc (DWORD);
+DWORD WINAPI ReAlloc (DWORD, DWORD);
+DWORD WINAPI Free (DWORD);
+
+DWORD WINAPI DSA_Create (DWORD, DWORD);
+
+
+DWORD WINAPI DPA_Create (DWORD);
+DWORD WINAPI DPA_GetPtr (DWORD, DWORD);
+DWORD WINAPI DPA_InsertPtr (DWORD, DWORD, DWORD);
+
+
+LPSTR WINAPI COMCTL32_StrChrA (LPSTR lpString, CHAR cChar);
+
+
+DWORD WINAPI
+Alloc (DWORD dwParam1)
+{
+    DWORD dwPtr;
+
+    dwPtr = (DWORD)HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY, dwParam1);
+
+    TRACE (commctrl, "(0x%08lx) ret=0x%08lx\n", dwParam1, dwPtr);
+
+    return dwPtr;
+}
+
+
+DWORD WINAPI
+ReAlloc (DWORD dwParam1, DWORD dwParam2)
+{
+    DWORD dwPtr;
+
+    if (dwParam1 == 0)
+	dwPtr = (DWORD)HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY, dwParam2);
+    else
+	dwPtr = (DWORD)HeapReAlloc (SystemHeap, HEAP_ZERO_MEMORY, 
+				    (LPVOID)dwParam1, dwParam2);
+
+    TRACE (commctrl, "(0x%08lx 0x%08lx) ret=0x%08lx\n",
+	   dwParam1, dwParam2, dwPtr);
+
+    return dwPtr;
+}
+
+
+DWORD WINAPI
+Free (DWORD dwParam1)
+{
+    TRACE (commctrl, "(0x%08lx)\n", dwParam1);
+    HeapFree (SystemHeap, 0, (LPVOID)dwParam1);
+
+    return 0;
+}
+
+
+
+
+
+DWORD WINAPI
+DSA_Create (DWORD dwParam1, DWORD dwParam2)
+{
+    LPDSA_DATA dsaPtr;
+
+    dsaPtr = (LPDSA_DATA)HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY, sizeof(DSA_DATA));
+    dsaPtr->dwInitial = dwParam1;
+    dsaPtr->dwGrow = dwParam2;
+
+    TRACE (commctrl, "(0x%08lx 0x%08lx) ret=0x%08lx\n",
+	   dwParam1, dwParam2, (DWORD)dsaPtr);
+
+    return (DWORD)dsaPtr;
+}
+
+
+DWORD WINAPI
+DSA_Destroy (DWORD dwParam1)
+{
+    LPDSA_DATA dsaPtr = (LPDSA_DATA)dwParam1;
+    DWORD i;
+
+    TRACE (commctrl, "(0x%08lx):semi-stub!\n", dwParam1);
+
+    if (dsaPtr->ptrs) {
+	for (i = 0; i < dsaPtr->dwEntryCount; i++) {
+	    if (dsaPtr->ptrs[i])
+		HeapFree (SystemHeap, 0, (LPSTR)dsaPtr->ptrs[i]);
+	}
+    }
+
+    HeapFree (SystemHeap, 0, dsaPtr);
+
+    return 0;
+}
+
+
+DWORD WINAPI
+DSA_InsertItem (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
+{
+    LPDSA_DATA dsaPtr = (LPDSA_DATA)dwParam1;
+    DWORD dwIndex;
+    INT32 len;
+
+    TRACE (commctrl, "(0x%08lx 0x%08lx \"%s\"):semi-stub!\n",
+	   dwParam1, dwParam2, (LPSTR)dwParam3);
+
+    if (dsaPtr->ptrs == NULL) {
+	dsaPtr->ptrs = (LPSTR*)HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
+					  dsaPtr->dwInitial * sizeof(LPVOID));
+	dsaPtr->dwMaxCount = dsaPtr->dwInitial;
+        dwIndex = 0;
+	len = lstrlen32A ((LPSTR)dwParam3);
+	dsaPtr->ptrs[dwIndex] =
+	    (LPSTR)HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY, len+1);
+	lstrcpy32A (dsaPtr->ptrs[dwIndex], (LPSTR)dwParam3);
+    }
+    else {
+	TRACE (commctrl, "(0x%08lx 0x%08lx)\n",
+	       dsaPtr->dwEntryCount, dsaPtr->dwMaxCount);
+	if (dwParam2 >= dsaPtr->dwEntryCount) {
+	    if (dsaPtr->dwEntryCount < dsaPtr->dwMaxCount) {
+		dwIndex = dsaPtr->dwEntryCount;
+		len = lstrlen32A ((LPSTR)dwParam3);
+		dsaPtr->ptrs[dwIndex] =
+		    (LPSTR)HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY, len+1);
+		lstrcpy32A (dsaPtr->ptrs[dwIndex], (LPSTR)dwParam3);
+	    }
+	    else {
+		FIXME (commctrl, "resizing array! stub!\n");
+
+		dwIndex = dwParam2;
+
+	    }
+	}
+	else {
+	    FIXME (commctrl, "inserting! stub!\n");
+
+	    dwIndex = dwParam2;
+	}
+    }
+
+    dsaPtr->dwEntryCount++;
+
+    TRACE (commctrl, "ret=0x%08lx\n", dwIndex);
+
+    return (dwIndex);
+}
+
+
+DWORD WINAPI
+DSA_GetItemPtr (DWORD dwParam1, DWORD dwParam2)
+{
+    LPDSA_DATA dsaPtr = (LPDSA_DATA)dwParam1;
+
+    TRACE (commctrl, "(0x%08lx 0x%08lx)\n", dwParam1, dwParam2);
+
+    if (dsaPtr == NULL)
+	return 0;
+    if (dsaPtr->ptrs == NULL)
+	return 0;
+    if ((dwParam2 < 0) || (dwParam2 >= dsaPtr->dwEntryCount))
+	return 0;
+
+    TRACE (commctrl, "ret=0x%08lx\n", (DWORD)dsaPtr->ptrs[dwParam2]);
+
+    return (DWORD)dsaPtr->ptrs[dwParam2];
+}
+
+
+DWORD WINAPI
+DSA_DeleteItem (DWORD dwParam1, DWORD dwParam2)
+{
+    LPDSA_DATA dsaPtr = (LPDSA_DATA)dwParam1;
+
+    TRACE (commctrl, "(0x%08lx 0x%08lx):semi-stub!\n",
+	   dwParam1, dwParam2);
+
+    if (dsaPtr->ptrs) {
+	if (dsaPtr->dwEntryCount == 1) {
+	    if (dsaPtr->ptrs[dwParam2])
+		HeapFree (SystemHeap, 0, dsaPtr->ptrs[dwParam2]);
+	    dsaPtr->dwEntryCount--;
+	}
+	else {
+	    LPSTR *oldPtrs = dsaPtr->ptrs;
+	    TRACE (commctrl, "complex delete!\n");
+
+	    if (dsaPtr->ptrs[dwParam2])
+		HeapFree (SystemHeap, 0, dsaPtr->ptrs[dwParam2]);
+
+	    dsaPtr->dwEntryCount--;
+	    dsaPtr->ptrs = 
+		(LPSTR*)HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
+				   dsaPtr->dwEntryCount * sizeof(LPVOID));
+	    if (dwParam2 > 0) {
+		memcpy (&dsaPtr->ptrs[0], &oldPtrs[0],
+			dwParam2 * sizeof(LPSTR));
+	    }
+
+	    if (dwParam2 < dsaPtr->dwEntryCount) {
+		memcpy (&dsaPtr->ptrs[dwParam2], &oldPtrs[dwParam2+1],
+			(dsaPtr->dwEntryCount - dwParam2) * sizeof(LPSTR));
+	    }
+	    HeapFree (SystemHeap, 0, oldPtrs);
+	}
+
+	if (dsaPtr->dwEntryCount == 0) {
+	    HeapFree (SystemHeap, 0, dsaPtr->ptrs);
+	    dsaPtr->ptrs = NULL;
+	}
+    }
+
+    return 0;
+}
+
+
+
+
+
+DWORD WINAPI
+DPA_Create (DWORD dwParam1)
+{
+    LPDPA_DATA dpaPtr;
+
+    TRACE (commctrl, "(0x%08lx)\n", dwParam1);
+
+    dpaPtr = (LPDPA_DATA)HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY, sizeof(DPA_DATA));
+    dpaPtr->dwGrow = dwParam1;
+
+    TRACE (commctrl, "ret=0x%08lx\n", (DWORD)dpaPtr);
+
+    return (DWORD)dpaPtr;
+}
+
+
+
+DWORD WINAPI
+DPA_GetPtr (DWORD dwParam1, DWORD dwParam2)
+{
+    LPDPA_DATA dpaPtr = (LPDPA_DATA)dwParam1;
+
+    TRACE (commctrl, "(0x%08lx 0x%08lx)\n", dwParam1, dwParam2);
+
+    if (dpaPtr == NULL)
+	return 0;
+    if (dpaPtr->ptrs == NULL)
+	return 0;
+    if ((dwParam2 < 0) || (dwParam2 >= dpaPtr->dwEntryCount))
+	return 0;
+
+    TRACE (commctrl, "ret=0x%08lx\n", (DWORD)dpaPtr->ptrs[dwParam2]);
+
+    return (DWORD)dpaPtr->ptrs[dwParam2];
+}
+
+
+
+DWORD WINAPI
+DPA_InsertPtr (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
+{
+    LPDPA_DATA dpaPtr = (LPDPA_DATA)dwParam1;
+    DWORD dwIndex;
+
+    TRACE (commctrl, "(0x%08lx 0x%08lx 0x%lx)\n",
+	   dwParam1, dwParam2, dwParam3);
+
+    if (dpaPtr->ptrs == NULL) {
+	dpaPtr->ptrs = (LPDWORD)HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
+					   dpaPtr->dwGrow * sizeof(LPVOID));
+	dpaPtr->dwMaxCount = dpaPtr->dwGrow;
+        dwIndex = 0;
+        dpaPtr->ptrs[dwIndex] = dwParam3;
+    }
+    else {
+	FIXME (commctrl, "adding to existing array! stub!\n");
+
+
+	dwIndex = dwParam2;
+    }
+
+    dpaPtr->dwEntryCount++;
+
+    return (dwIndex);
+}
+
+
+LPSTR WINAPI
+COMCTL32_StrChrA (LPSTR lpString, CHAR cChar)
+{
+    return strchr (lpString, cChar);
+}
+
diff --git a/controls/commctrl.c b/controls/commctrl.c
index 93de092..22ef4c4 100644
--- a/controls/commctrl.c
+++ b/controls/commctrl.c
@@ -131,8 +131,8 @@
   INT32 cCount;
   DWORD dwMask;
 
-  if (lpInitCtrls == NULL) return (FALSE);
-  if (lpInitCtrls->dwSize < sizeof(INITCOMMONCONTROLSEX)) return (FALSE);
+  if (lpInitCtrls == NULL) return FALSE;
+  if (lpInitCtrls->dwSize < sizeof(INITCOMMONCONTROLSEX)) return FALSE;
 
   for (cCount = 0; cCount <= 31; cCount++) {
     dwMask = 1 << cCount;
@@ -160,6 +160,7 @@
       case ICC_TAB_CLASSES:
         TRACE (commctrl, "No tab class implemented!\n");
         TRACE (commctrl, "No tooltip class implemented!\n");
+        UPDOWN_Register ();
         break;
 
       case ICC_UPDOWN_CLASS:
@@ -178,6 +179,7 @@
         TRACE (commctrl, "No animation class implemented!\n");
         break;
 
+      /* advanced classes - not included in Win95 */
       case ICC_DATE_CLASSES:
         TRACE (commctrl, "No month calendar class implemented!\n");
         TRACE (commctrl, "No date picker class implemented!\n");
@@ -211,7 +213,7 @@
     }
   }
 
-  return (TRUE);
+  return TRUE;
 }
 
 
@@ -242,13 +244,13 @@
             }
             else {
                 if (HIWORD(wParam) & MF_POPUP) {
-                    TRACE (commctrl, "Popup menu selected!\n");
-                    FIXME (commctrl, "No popup menu texts!\n");
+                    TRACE (commctrl, "popup menu selected!\n");
+                    FIXME (commctrl, "no popup menu texts!\n");
 
                     szStatusText[0] = 0;
                 }
                 else {
-                    TRACE (commctrl, "Menu item selected!\n");
+                    TRACE (commctrl, "menu item selected!\n");
                     if (!LoadString32A (hInst, LOWORD(wParam), szStatusText, 128))
                         szStatusText[0] = 0;
                 }
@@ -284,7 +286,8 @@
     if(hwndTB) {
 	TBADDBITMAP tbab;
 
-        SendMessage32A (hwndTB, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
+        SendMessage32A (hwndTB, TB_BUTTONSTRUCTSIZE,
+			(WPARAM32)uStructSize, 0);
 
 	/* set bitmap and button size */
 
@@ -296,10 +299,10 @@
 
 	/* add buttons */
 	SendMessage32A (hwndTB, TB_ADDBUTTONS32A,
-			(WPARAM32)iNumButtons, (LPARAM)&lpButtons);
+			(WPARAM32)iNumButtons, (LPARAM)lpButtons);
     }
 
-    return (hwndTB);
+    return hwndTB;
 }
 
 
@@ -341,3 +344,39 @@
 			    iNumButtons, 0, 0, 0, 0, sizeof (OLDTBBUTTON));
 }
 
+
+/***********************************************************************
+ * GetEffectiveClientRect [COMCTL32.4]
+ *
+ *
+ *
+ */
+
+VOID WINAPI
+GetEffectiveClientRect (HWND32 hwnd, LPRECT32 lpRect, LPINT32 lpInfo)
+{
+    RECT32  rcClient, rcCtrl;
+    HWND32  hwndCtrl;
+    LPINT32 lpRun;
+
+    TRACE (commctrl, "hwnd=0x%08lx lpRect=0x%08lx lpInfo=0x%08lx\n",
+	   (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);
+
+    GetClientRect32 (hwnd, &rcClient);
+
+    lpRun = lpInfo;
+    TRACE (commctrl, "*lpRun=0x%08x\n", *lpRun);
+    while (*lpRun) {
+	lpRun++;
+	TRACE (commctrl, "control id 0x%08x\n", *lpRun);
+	hwndCtrl = GetDlgItem32 (hwnd, *lpRun);
+	GetWindowRect32 (hwndCtrl, &rcCtrl);
+	MapWindowPoints32 (NULL, hwnd, (LPPOINT32)&rcCtrl, 2);
+	SubtractRect32 (&rcClient, &rcClient, &rcCtrl);
+	lpRun++;
+	TRACE (commctrl, "*lpRun=0x%08x\n", *lpRun);
+    }
+
+    CopyRect32 (lpRect, &rcClient);
+}
+
diff --git a/controls/menu.c b/controls/menu.c
index 81bc680..ee407e2 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -2784,7 +2784,7 @@
 /**********************************************************************
  *         EnableMenuItem16    (USER.155)
  */
-BOOL16 WINAPI EnableMenuItem16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
+UINT16 WINAPI EnableMenuItem16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
 {
     return EnableMenuItem32( hMenu, wItemID, wFlags );
 }
@@ -2793,38 +2793,20 @@
 /**********************************************************************
  *         EnableMenuItem32    (USER32.170)
  */
-BOOL32 WINAPI EnableMenuItem32( HMENU32 hMenu, UINT32 wItemID, UINT32 wFlags )
+UINT32 WINAPI EnableMenuItem32( HMENU32 hMenu, UINT32 wItemID, UINT32 wFlags )
 {
-    BOOL32    bRet = FALSE;
-    MENUITEM *item, *first = NULL;
+    UINT32    oldflags;
+    MENUITEM *item;
 
     TRACE(menu,"(%04x, %04X, %04X) !\n", 
 		 hMenu, wItemID, wFlags);
 
-    while( (item = MENU_FindItem( &hMenu, &wItemID, wFlags )) )
-    {
-      if( (wFlags & MF_BYPOSITION) || !(item->fType & MF_POPUP) )
-      {
-           /* We can't have MF_GRAYED and MF_DISABLED together */
-           if (wFlags & MF_GRAYED)
-           {
-  	     item->fState = (item->fState & ~MF_DISABLED) | MF_GRAYED;
-           }
-           else if (wFlags & MF_DISABLED)
-           {
-	     item->fState = (item->fState & ~MF_GRAYED) | MF_DISABLED;
-           }
-           else   /* MF_ENABLED */
-           {
-	     item->fState &= ~(MF_GRAYED | MF_DISABLED);
-           } 
-	   bRet = TRUE;
-	   break;
-      }
-      if( !first ) first = item;
-      else if( first == item ) break;
-    }
-    return bRet;
+    if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags )))
+	return (UINT32)-1;
+
+    oldflags = item->fState & (MF_GRAYED | MF_DISABLED);
+    item->fState ^= (oldflags ^ wFlags) & (MF_GRAYED | MF_DISABLED);
+    return oldflags;
 }
 
 
diff --git a/controls/scroll.c b/controls/scroll.c
index 4f844cf..0cade01 100644
--- a/controls/scroll.c
+++ b/controls/scroll.c
@@ -46,6 +46,9 @@
   /* Minimum size of the thumb in pixels */
 #define SCROLL_MIN_THUMB 6
 
+  /* Overlap between arrows and thumb */
+#define SCROLL_ARROW_THUMB_OVERLAP 1
+
   /* Delay (in ms) before first repetition when holding the button down */
 #define SCROLL_FIRST_DELAY   200
 
@@ -159,18 +162,28 @@
     switch(nBar)
     {
       case SB_HORZ:
-        lprect->left   = wndPtr->rectClient.left - wndPtr->rectWindow.left - 1;
+        lprect->left   = wndPtr->rectClient.left - wndPtr->rectWindow.left;
         lprect->top    = wndPtr->rectClient.bottom - wndPtr->rectWindow.top;
-        lprect->right  = wndPtr->rectClient.right - wndPtr->rectWindow.left +1;
-        lprect->bottom = lprect->top + SYSMETRICS_CYHSCROLL + 1;
+        lprect->right  = wndPtr->rectClient.right - wndPtr->rectWindow.left;
+        lprect->bottom = lprect->top + SYSMETRICS_CYHSCROLL;
+	if(wndPtr->dwStyle & WS_BORDER) {
+	  lprect->left--;
+	  lprect->right++;
+	} else if(wndPtr->dwStyle & WS_VSCROLL)
+	  lprect->right++;
         vertical = FALSE;
 	break;
 
       case SB_VERT:
         lprect->left   = wndPtr->rectClient.right - wndPtr->rectWindow.left;
-        lprect->top    = wndPtr->rectClient.top - wndPtr->rectWindow.top - 1;
-        lprect->right  = lprect->left + SYSMETRICS_CXVSCROLL + 1;
-        lprect->bottom = wndPtr->rectClient.bottom - wndPtr->rectWindow.top +1;
+        lprect->top    = wndPtr->rectClient.top - wndPtr->rectWindow.top;
+        lprect->right  = lprect->left + SYSMETRICS_CXVSCROLL;
+        lprect->bottom = wndPtr->rectClient.bottom - wndPtr->rectWindow.top;
+	if(wndPtr->dwStyle & WS_BORDER) {
+	  lprect->top--;
+	  lprect->bottom++;
+	} else if(wndPtr->dwStyle & WS_HSCROLL)
+	  lprect->bottom++;
         vertical = TRUE;
 	break;
 
@@ -199,7 +212,7 @@
         SCROLLBAR_INFO *info = SCROLL_GetPtrScrollInfo( wndPtr, nBar );
 
         *arrowSize = SYSMETRICS_CXVSCROLL;
-        pixels -= 2 * SYSMETRICS_CXVSCROLL;
+        pixels -= (2 * (SYSMETRICS_CXVSCROLL - SCROLL_ARROW_THUMB_OVERLAP));
 
         if (info->Page)
         {
@@ -208,7 +221,7 @@
         }
         else *thumbSize = SYSMETRICS_CXVSCROLL;
 
-        if (((pixels -= *thumbSize + 1) < 0) ||
+        if (((pixels -= *thumbSize ) < 0) ||
             ((info->flags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH))
         {
             /* Rectangle too small or scrollbar disabled -> no thumb */
@@ -218,10 +231,10 @@
         {
             INT32 max = info->MaxVal - MAX( info->Page-1, 0 );
             if (info->MinVal >= max)
-                *thumbPos = *arrowSize;
+                *thumbPos = *arrowSize - SCROLL_ARROW_THUMB_OVERLAP;
             else
-                *thumbPos = *arrowSize + pixels * (info->CurVal-info->MinVal) /
-                                                  (max - info->MinVal);
+                *thumbPos = *arrowSize - SCROLL_ARROW_THUMB_OVERLAP
+		 + pixels * (info->CurVal-info->MinVal) / (max - info->MinVal);
         }
     }
     return vertical;
@@ -240,7 +253,8 @@
     INT32 thumbSize;
     INT32 pixels = vertical ? rect->bottom-rect->top : rect->right-rect->left;
 
-    if ((pixels -= 2*SYSMETRICS_CXVSCROLL) <= 0) return infoPtr->MinVal;
+    if ((pixels -= 2*(SYSMETRICS_CXVSCROLL - SCROLL_ARROW_THUMB_OVERLAP)) <= 0)
+        return infoPtr->MinVal;
 
     if (infoPtr->Page)
     {
@@ -249,9 +263,9 @@
     }
     else thumbSize = SYSMETRICS_CXVSCROLL;
 
-    if ((pixels -= thumbSize + 1) <= 0) return infoPtr->MinVal;
+    if ((pixels -= thumbSize) <= 0) return infoPtr->MinVal;
 
-    pos = MAX( 0, pos - SYSMETRICS_CXVSCROLL );
+    pos = MAX( 0, pos - (SYSMETRICS_CXVSCROLL - SCROLL_ARROW_THUMB_OVERLAP) );
     if (pos > pixels) pos = pixels;
 
     if (!infoPtr->Page) pos *= infoPtr->MaxVal - infoPtr->MinVal;
@@ -277,22 +291,22 @@
 
     if (vertical)
     {
-        if (pt.y <= rect.top + arrowSize + 1) return SCROLL_TOP_ARROW;
+        if (pt.y < rect.top + arrowSize) return SCROLL_TOP_ARROW;
         if (pt.y >= rect.bottom - arrowSize) return SCROLL_BOTTOM_ARROW;
         if (!thumbPos) return SCROLL_TOP_RECT;
         pt.y -= rect.top;
         if (pt.y < thumbPos) return SCROLL_TOP_RECT;
-        if (pt.y > thumbPos + thumbSize) return SCROLL_BOTTOM_RECT;
+        if (pt.y >= thumbPos + thumbSize) return SCROLL_BOTTOM_RECT;
         return SCROLL_THUMB;
     }
     else  /* horizontal */
     {
-        if (pt.x <= rect.left + arrowSize) return SCROLL_TOP_ARROW;
+        if (pt.x < rect.left + arrowSize) return SCROLL_TOP_ARROW;
         if (pt.x >= rect.right - arrowSize) return SCROLL_BOTTOM_ARROW;
         if (!thumbPos) return SCROLL_TOP_RECT;
         pt.x -= rect.left;
         if (pt.x < thumbPos) return SCROLL_TOP_RECT;
-        if (pt.x > thumbPos + thumbSize) return SCROLL_BOTTOM_RECT;
+        if (pt.x >= thumbPos + thumbSize) return SCROLL_BOTTOM_RECT;
         return SCROLL_THUMB;
     }
 }
@@ -313,26 +327,26 @@
                                     : LEFT_ARROW(infoPtr->flags, top_pressed));
     SetStretchBltMode32( hdc, STRETCH_DELETESCANS );
     StretchBlt32( hdc, rect->left, rect->top,
-                  vertical ? rect->right-rect->left : arrowSize+1,
-                  vertical ? arrowSize+1 : rect->bottom-rect->top,
+                  vertical ? rect->right-rect->left : arrowSize,
+                  vertical ? arrowSize : rect->bottom-rect->top,
                   hdcMem, 0, 0,
-                  SYSMETRICS_CXVSCROLL + 1, SYSMETRICS_CYHSCROLL + 1,
+                  SYSMETRICS_CXVSCROLL, SYSMETRICS_CYHSCROLL,
                   SRCCOPY );
 
     SelectObject32( hdcMem, vertical ?
                     BOTTOM_ARROW( infoPtr->flags, bottom_pressed )
                     : RIGHT_ARROW( infoPtr->flags, bottom_pressed ) );
     if (vertical)
-        StretchBlt32( hdc, rect->left, rect->bottom - arrowSize - 1,
-                      rect->right - rect->left, arrowSize + 1,
+        StretchBlt32( hdc, rect->left, rect->bottom - arrowSize,
+                      rect->right - rect->left, arrowSize,
                       hdcMem, 0, 0,
-                      SYSMETRICS_CXVSCROLL + 1, SYSMETRICS_CYHSCROLL + 1,
+                      SYSMETRICS_CXVSCROLL, SYSMETRICS_CYHSCROLL,
                       SRCCOPY );
     else
-        StretchBlt32( hdc, rect->right - arrowSize - 1, rect->top,
-                      arrowSize + 1, rect->bottom - rect->top,
+        StretchBlt32( hdc, rect->right - arrowSize, rect->top,
+                      arrowSize, rect->bottom - rect->top,
                       hdcMem, 0, 0,
-                      SYSMETRICS_CXVSCROLL + 1, SYSMETRICS_CYHSCROLL + 1,
+                      SYSMETRICS_CXVSCROLL, SYSMETRICS_CYHSCROLL,
                       SRCCOPY );
     SelectObject32( hdcMem, hbmpPrev );
     DeleteDC32( hdcMem );
@@ -351,20 +365,25 @@
     if (vertical)
     {
         r.top += SCROLL_TrackingPos;
-        if (r.top < rect->top + arrowSize) r.top = rect->top + arrowSize;
-        if (r.top + thumbSize >= rect->bottom - arrowSize)
-            r.top = rect->bottom - arrowSize - thumbSize - 1;
-        r.bottom = r.top + thumbSize + 1;
+        if (r.top < rect->top + arrowSize - SCROLL_ARROW_THUMB_OVERLAP)
+	    r.top = rect->top + arrowSize - SCROLL_ARROW_THUMB_OVERLAP;
+        if (r.top + thumbSize >
+	               rect->bottom - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP))
+            r.top = rect->bottom - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP)
+	                                                          - thumbSize;
+        r.bottom = r.top + thumbSize;
     }
     else
     {
         r.left += SCROLL_TrackingPos;
-        if (r.left < rect->left + arrowSize) r.left = rect->left + arrowSize;
-        if (r.left + thumbSize >= rect->right - arrowSize)
-            r.left = rect->right - arrowSize - thumbSize - 1;
-        r.right = r.left + thumbSize + 1;
+        if (r.left < rect->left + arrowSize - SCROLL_ARROW_THUMB_OVERLAP)
+	    r.left = rect->left + arrowSize - SCROLL_ARROW_THUMB_OVERLAP;
+        if (r.left + thumbSize >
+	               rect->right - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP))
+            r.left = rect->right - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP) 
+	                                                          - thumbSize;
+        r.right = r.left + thumbSize;
     }
-    InflateRect32( &r, -1, -1 );
     DrawFocusRect32( hdc, &r );
     SCROLL_MovingThumb = !SCROLL_MovingThumb;
 }
@@ -407,15 +426,13 @@
     r = *rect;
     if (vertical)
     {
-        r.top    += arrowSize - 1;
-        r.bottom -= arrowSize;
-	r.right--;
+        r.top    += arrowSize - SCROLL_ARROW_THUMB_OVERLAP;
+        r.bottom -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
     }
     else
     {
-        r.left  += arrowSize - 1;
-        r.right -= arrowSize;
-	r.bottom--;
+        r.left  += arrowSize - SCROLL_ARROW_THUMB_OVERLAP;
+        r.right -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
     }
 
       /* Draw the scroll bar frame */
@@ -435,27 +452,27 @@
     {
         PatBlt32( hdc, r.left + 1, r.top + 1,
                   r.right - r.left - 2,
-                  thumbPos - arrowSize,
+                  thumbPos - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP) - 1,
                   top_selected ? 0x0f0000 : PATCOPY );
-        r.top += thumbPos - arrowSize;
-        PatBlt32( hdc, r.left + 1, r.top + thumbSize + 1,
+        r.top += thumbPos - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
+        PatBlt32( hdc, r.left + 1, r.top + thumbSize,
                   r.right - r.left - 2,
-                  r.bottom - r.top - thumbSize - 2,
+                  r.bottom - r.top - thumbSize - 1,
                   bottom_selected ? 0x0f0000 : PATCOPY );
-        r.bottom = r.top + thumbSize + 2;
+        r.bottom = r.top + thumbSize;
     }
     else  /* horizontal */
     {
         PatBlt32( hdc, r.left + 1, r.top + 1,
-                  thumbPos - arrowSize,
+                  thumbPos - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP) - 1,
                   r.bottom - r.top - 2,
                   top_selected ? 0x0f0000 : PATCOPY );
-        r.left += thumbPos - arrowSize;
-        PatBlt32( hdc, r.left + thumbSize + 1, r.top + 1,
-                  r.right - r.left - thumbSize - 2,
+        r.left += thumbPos - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
+        PatBlt32( hdc, r.left + thumbSize, r.top + 1,
+                  r.right - r.left - thumbSize - 1,
                   r.bottom - r.top - 2,
                   bottom_selected ? 0x0f0000 : PATCOPY );
-        r.right = r.left + thumbSize + 2;
+        r.right = r.left + thumbSize;
     }
 
       /* Draw the thumb */
@@ -493,6 +510,7 @@
 
     vertical = SCROLL_GetScrollBarRect( hwnd, nBar, &rect,
                                         &arrowSize, &thumbSize, &thumbPos );
+
       /* Draw the arrows */
 
     if (arrows && arrowSize) SCROLL_DrawArrows( hdc, infoPtr, &rect, arrowSize,
diff --git a/controls/status.c b/controls/status.c
index a24a47b..6df39b0 100644
--- a/controls/status.c
+++ b/controls/status.c
@@ -103,9 +103,19 @@
     /* now draw text */
     if (text) {
       int oldbkmode = SetBkMode32(hdc, TRANSPARENT);
+      LPSTR p = text;
+      UINT32 align = DT_LEFT;
+      if (*p == '\t') {
+	p++;
+	align = DT_CENTER;
+
+	if (*p == '\t') {
+	  p++;
+	  align = DT_RIGHT;
+	}
+      }
       r.left += 3;
-      DrawText32A(hdc, text, lstrlen32A(text),
-		  &r, DT_LEFT|DT_VCENTER|DT_SINGLELINE);  
+      DrawText32A(hdc, p, lstrlen32A(p), &r, align|DT_VCENTER|DT_SINGLELINE);
       if (oldbkmode != TRANSPARENT)
 	SetBkMode32(hdc, oldbkmode);
     }
@@ -118,6 +128,7 @@
     int      i;
     RECT32   rect;
     HBRUSH32 hbrBk;
+    HFONT32 hOldFont;
     WND *wndPtr;
 
     wndPtr = WIN_FindWndPtr(hwnd);
@@ -134,6 +145,8 @@
 	hbrBk = GetSysColorBrush32 (COLOR_3DFACE);
     FillRect32(hdc, &rect, hbrBk);
 
+    hOldFont = SelectObject32 (hdc, self->hFont ? self->hFont : self->hDefaultFont);
+
     if (self->simple) {
 	SB_DrawPart (hdc,
 		     &self->part0.bound,
@@ -165,6 +178,8 @@
 	}
     }
 
+    SelectObject32 (hdc, hOldFont);
+
     if (self->clrBk != CLR_DEFAULT)
 	DeleteObject32 (hbrBk);
 
@@ -252,6 +267,7 @@
 	}
     }
     InvalidateRect32(hwnd, &part->bound, FALSE);
+//    SW_RefreshPart (hdc, part);
     return TRUE;
 }
 
@@ -320,9 +336,10 @@
 static LRESULT
 SW_Create(HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
 {
-    RECT32	rect;
     LPCREATESTRUCT32A lpCreate = (LPCREATESTRUCT32A) lParam;
-    int	height, width, len;
+    NONCLIENTMETRICS32A nclm;
+    RECT32	rect;
+    int	        width, len;
     HDC32	hdc;
     HWND32	parent;
     WND *wndPtr;
@@ -331,7 +348,6 @@
     wndPtr = WIN_FindWndPtr(hwnd);
     self = (STATUSWINDOWINFO*)HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
 					 sizeof(STATUSWINDOWINFO));
-
     wndPtr->wExtra[0] = (DWORD)self;
 
     self->numParts = 1;
@@ -341,6 +357,10 @@
     self->hFont = 0;
     GetClientRect32(hwnd, &rect);
 
+    nclm.cbSize = sizeof(NONCLIENTMETRICS32A);
+    SystemParametersInfo32A (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
+    self->hDefaultFont = CreateFontIndirect32A (&nclm.lfStatusFont);
+
     /* initialize simple case */
     self->part0.bound = rect;
     self->part0.text = 0;
@@ -362,11 +382,14 @@
         lstrcpy32A (self->parts[0].text, lpCreate->lpszName);
     }
 
-    height = 20;
     if ((hdc = GetDC32 (0))) {
 	TEXTMETRIC32A tm;
+	HFONT32 hOldFont;
+
+	hOldFont = SelectObject32 (hdc,self->hDefaultFont);
 	GetTextMetrics32A(hdc, &tm);
 	self->textHeight = tm.tmHeight;
+	SelectObject32 (hdc, hOldFont);
 	ReleaseDC32(0, hdc);
     }
 
@@ -554,6 +577,11 @@
     if (self->part0.text && (self->part0.style != SBT_OWNERDRAW))
 	HeapFree(SystemHeap, 0, self->part0.text);
     HeapFree(SystemHeap, 0, self->parts);
+
+    /* delete default font */
+    if (self->hDefaultFont)
+	DeleteObject32 (self->hDefaultFont);
+
     HeapFree(SystemHeap, 0, self);
     return 0;
 }
@@ -673,6 +701,7 @@
         lstrcpy32A (part->text, (LPCSTR)lParam);
     }
     InvalidateRect32(hwnd, &part->bound, FALSE);
+//    SW_RefreshPart (hdc, part);
 
     return TRUE;
 }
diff --git a/controls/toolbar.c b/controls/toolbar.c
index 86a1e6c..3c5d134 100644
--- a/controls/toolbar.c
+++ b/controls/toolbar.c
@@ -13,7 +13,9 @@
  * TODO:
  *   - Many messages.
  *   - All notifications.
- *   - Tooltip support.
+ *   - Fix TB_GETBITMAPFLAGS.
+ *   - Fix TB_GETROWS and TB_SETROWS.
+ *   - Tooltip support (partially).
  *   - Unicode suppport.
  *   - Internal COMMCTL32 bitmaps.
  *   - Customize dialog.
@@ -30,14 +32,15 @@
 
 #include "windows.h"
 #include "commctrl.h"
+#include "cache.h"
 #include "toolbar.h"
 #include "heap.h"
 #include "win.h"
 #include "debug.h"
 
 
-#define SEPARATOR_WIDTH  12
-
+#define SEPARATOR_WIDTH  8
+#define SEPARATOR_HEIGHT 5
 
 
 
@@ -60,10 +63,15 @@
     else {
 	if (!(btnPtr->fsState & TBSTATE_ENABLED)) {
 	    /* button is disabled */
+	    HICON32 hIcon;
 	    DrawEdge32 (hdc, &rc, EDGE_RAISED,
 			BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
-	    ImageList_Draw (infoPtr->himlDis, btnPtr->iBitmap, hdc,
-			    rc.left+2, rc.top+2, ILD_NORMAL);
+	    hIcon = ImageList_GetIcon (infoPtr->himlDef, btnPtr->iBitmap, ILD_IMAGE);
+	    DrawState32A (hdc, (HBRUSH32)NULL, NULL, MAKELONG(hIcon, 0), 0,
+		rc.left+1, rc.top+1,
+		infoPtr->nBitmapWidth, infoPtr->nBitmapHeight, DST_ICON|DSS_DISABLED);
+//	    ImageList_Draw (infoPtr->himlDis, btnPtr->iBitmap, hdc,
+//			    rc.left+1, rc.top+1, ILD_NORMAL);
 	    return;
 	}
 
@@ -72,15 +80,44 @@
 	    DrawEdge32 (hdc, &rc, EDGE_SUNKEN,
 			BF_RECT | BF_MIDDLE | BF_ADJUST);
 	    ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
-			    rc.left+3, rc.top+3, ILD_NORMAL);
+			    rc.left+2, rc.top+2, ILD_NORMAL);
 	    return;
 	}
-	else {
-	    DrawEdge32 (hdc, &rc, EDGE_RAISED,
-			BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
+
+	if ((btnPtr->fsStyle & TBSTYLE_CHECK) &&
+	    (btnPtr->fsState & TBSTATE_CHECKED)) {
+	    HBRUSH32 hbr;
+	    DrawEdge32 (hdc, &rc, EDGE_SUNKEN,
+			BF_RECT | BF_MIDDLE | BF_ADJUST);
+
+	    hbr = SelectObject32 (hdc, CACHE_GetPattern55AABrush ());
+	    PatBlt32 (hdc, rc.left, rc.top, rc.right - rc.left,
+		      rc.bottom - rc.top, 0x00FA0089);
+	    SelectObject32 (hdc, hbr);
 	    ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
 			    rc.left+2, rc.top+2, ILD_NORMAL);
+	    return;
 	}
+	
+	if (btnPtr->fsState & TBSTATE_INDETERMINATE) {
+	    HBRUSH32 hbr;
+	    DrawEdge32 (hdc, &rc, EDGE_RAISED,
+			BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
+
+	    hbr = SelectObject32 (hdc, CACHE_GetPattern55AABrush ());
+	    PatBlt32 (hdc, rc.left, rc.top, rc.right - rc.left,
+		      rc.bottom - rc.top, 0x00FA0089);
+	    SelectObject32 (hdc, hbr);
+//	    ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
+//			    rc.left+1, rc.top+1, ILD_NORMAL);
+	    return;
+	}
+
+	/* normal state */
+	DrawEdge32 (hdc, &rc, EDGE_RAISED,
+		    BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
+	ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
+			rc.left+1, rc.top+1, ILD_NORMAL);
     }
 }
 
@@ -134,6 +171,8 @@
 	    btnPtr->rect.right = btnPtr->rect.left + infoPtr->nButtonWidth;
 	rect.left = btnPtr->rect.right;
     }
+
+    infoPtr->nHeight = rect.bottom + 8;
 }
 
 
@@ -149,13 +188,13 @@
     for (i = 0; i < infoPtr->nNumButtons; i++) {
 	if (btnPtr->fsStyle & TBSTYLE_SEP) {
 	    if (PtInRect32 (&btnPtr->rect, *lpPt)) {
-//		TRACE (toolbar, " ON SEPARATOR %d!\n", i);
+		TRACE (toolbar, " ON SEPARATOR %d!\n", i);
 		return -i;
 	    }
 	}
 	else {
 	    if (PtInRect32 (&btnPtr->rect, *lpPt)) {
-//		TRACE (toolbar, " ON BUTTON %d!\n", i);
+		TRACE (toolbar, " ON BUTTON %d!\n", i);
 		return i;
 	    }
 
@@ -164,7 +203,7 @@
 	btnPtr++;
     }
 
-//    TRACE (toolbar, " NOWHERE!\n");
+    TRACE (toolbar, " NOWHERE!\n");
     return -1;
 }
 
@@ -177,10 +216,59 @@
 
     btnPtr = infoPtr->buttons;
     for (i = 0; i < infoPtr->nNumButtons; i++) {
-	if (btnPtr->idCommand == idCommand)
+	if (btnPtr->idCommand == idCommand) {
+	    TRACE (toolbar, "command=%d index=%d\n", idCommand, i);
 	    return i;
+	}
 	btnPtr++;
     }
+    TRACE (toolbar, "no index found for command=%d\n", idCommand);
+    return -1;
+}
+
+
+static INT32
+TOOLBAR_GetCheckedGroupButtonIndex (TOOLBAR_INFO *infoPtr, INT32 nIndex)
+{
+    TBUTTON_INFO *btnPtr;
+    INT32 nRunIndex;
+
+    if ((nIndex < 0) || (nIndex > infoPtr->nNumButtons))
+	return -1;
+
+    /* check index button */
+    btnPtr = &infoPtr->buttons[nIndex];
+    if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
+	if (btnPtr->fsState & TBSTATE_CHECKED)
+	    return nIndex;
+    }
+
+    /* check previous buttons */
+    nRunIndex = nIndex - 1;
+    while (nRunIndex >= 0) {
+	btnPtr = &infoPtr->buttons[nRunIndex];
+	if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
+	    if (btnPtr->fsState & TBSTATE_CHECKED)
+		return nRunIndex;
+	}
+	else
+	    break;
+	nRunIndex--;
+    }
+
+    /* check next buttons */
+    nRunIndex = nIndex + 1;
+    while (nRunIndex < infoPtr->nNumButtons) {
+	btnPtr = &infoPtr->buttons[nRunIndex];	
+	if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
+	    if (btnPtr->fsState & TBSTATE_CHECKED)
+		return nRunIndex;
+	}
+	else
+	    break;
+	nRunIndex++;
+    }
+
     return -1;
 }
 
@@ -190,6 +278,7 @@
 {
     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
     LPTBADDBITMAP lpAddBmp = (LPTBADDBITMAP)lParam;
+    INT32 nIndex = 0;
 
     if ((!lpAddBmp) || ((INT32)wParam <= 0))
 	return -1;
@@ -205,6 +294,7 @@
 			      (INT32)wParam, 2);
     }
 
+#if 0
     if (!(infoPtr->himlDis)) {
 	/* create new disabled image list */
 	TRACE (toolbar, "creating disabled image list!\n");
@@ -213,12 +303,14 @@
 			      infoPtr->nBitmapHeight, ILC_COLOR | ILC_MASK,
 			      (INT32)wParam, 2);
     }
-
+#endif
 
     /* Add bitmaps to the default image list */
     if (lpAddBmp->hInst == (HINSTANCE32)0) {
-
-	ImageList_Add (infoPtr->himlDef, (HBITMAP32)lpAddBmp->nID, 0);
+	nIndex = 
+	    ImageList_AddMasked (infoPtr->himlDef, (HBITMAP32)lpAddBmp->nID,
+				 0xC0C0C0);
+//				 GetSysColor32 (COLOR_3DFACE));
     }
     else if (lpAddBmp->hInst == HINST_COMMCTRL) {
 	/* add internal bitmaps */
@@ -226,23 +318,22 @@
 
 	/* Hack to "add" some reserved images within the image list 
 	   to get the right image indices */
-	ImageList_SetImageCount (infoPtr->himlDef,
-	    ImageList_GetImageCount (infoPtr->himlDef) + (INT32)wParam);
+	nIndex = ImageList_GetImageCount (infoPtr->himlDef);
+	ImageList_SetImageCount (infoPtr->himlDef, nIndex + (INT32)wParam);
     }
     else {
 	HBITMAP32 hBmp =
 	    LoadBitmap32A (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID);
 
-	ImageList_Add (infoPtr->himlDef, hBmp, (HBITMAP32)0);
+	nIndex = ImageList_Add (infoPtr->himlDef, hBmp, (HBITMAP32)0);
 
 	DeleteObject32 (hBmp); 
     }
 
 
-    /* Add bitmaps to the disabled image list */
+    infoPtr->nNumBitmaps += (INT32)wParam;
 
-
-    return 0;
+    return nIndex;
 }
 
 
@@ -297,8 +388,95 @@
 }
 
 
-// << TOOLBAR_AddString32A >>
-// << TOOLBAR_AutoSize >>
+// << TOOLBAR_AddButtons32W >>
+
+
+static LRESULT
+TOOLBAR_AddString32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+    INT32 nIndex;
+
+    if (wParam) {
+	char szString[256];
+	INT32 len;
+	TRACE (toolbar, "adding string from resource!\n");
+
+	len = LoadString32A ((HINSTANCE32)wParam, (UINT32)lParam,
+			     szString, 256);
+
+	TRACE (toolbar, "len=%d\n", len);
+	nIndex = infoPtr->nNumStrings;
+	if (infoPtr->nNumStrings == 0) {
+	    infoPtr->strings =
+		HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY, sizeof(char *));
+	}
+	else {
+	    char **oldStrings = infoPtr->strings;
+	    infoPtr->strings =
+		HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
+			   sizeof(char *) * (infoPtr->nNumStrings + 1));
+	    memcpy (&infoPtr->strings[0], &oldStrings[0],
+		    sizeof(char *) * infoPtr->nNumStrings);
+	    HeapFree (SystemHeap, 0, oldStrings);
+	}
+
+	infoPtr->strings[infoPtr->nNumStrings] =
+	    HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY, sizeof(char)*(len+1));
+	lstrcpy32A (infoPtr->strings[infoPtr->nNumStrings], szString);
+	infoPtr->nNumStrings++;
+    }
+    else {
+	char *p = (char*)lParam;
+	INT32 len;
+
+	if (p == NULL) return -1;
+	TRACE (toolbar, "adding string(s) from array!\n");
+	nIndex = infoPtr->nNumStrings;
+	while (*p) {
+	    len = lstrlen32A (p);
+	    TRACE (toolbar, "len=%d\n", len);
+
+	    if (infoPtr->nNumStrings == 0) {
+		infoPtr->strings =
+		    HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY, sizeof(char *));
+	    }
+	    else {
+		char **oldStrings = infoPtr->strings;
+		infoPtr->strings =
+		    HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
+			       sizeof(char *) * (infoPtr->nNumStrings + 1));
+		memcpy (&infoPtr->strings[0], &oldStrings[0],
+			sizeof(char *) * infoPtr->nNumStrings);
+		HeapFree (SystemHeap, 0, oldStrings);
+	    }
+
+	    infoPtr->strings[infoPtr->nNumStrings] =
+		HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY, sizeof(char)*(len+1));
+	    lstrcpy32A (infoPtr->strings[infoPtr->nNumStrings], p);
+	    infoPtr->nNumStrings++;
+
+	    p += (len+1);
+	}
+
+    }
+
+    return nIndex;
+}
+
+
+// << TOOLBAR_AddString32W >>
+
+
+static LRESULT
+TOOLBAR_AutoSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+
+    TRACE (toolbar, "auto size!\n");
+
+    return 0;
+}
 
 
 static LRESULT
@@ -344,7 +522,6 @@
 }
 
 
-/*
 static LRESULT
 TOOLBAR_CheckButton (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
@@ -352,24 +529,41 @@
     TBUTTON_INFO *btnPtr;
     HDC32 hdc;
     INT32 nIndex;
+    INT32 nOldIndex = -1;
 
     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
     if (nIndex == -1)
 	return FALSE;
 
     btnPtr = &infoPtr->buttons[nIndex];
+
+    if (!(btnPtr->fsStyle & TBSTYLE_CHECK))
+	return FALSE;
+
     if (LOWORD(lParam) == FALSE)
 	btnPtr->fsState &= ~TBSTATE_CHECKED;
-    else
+    else {
+	if (btnPtr->fsStyle & TBSTYLE_GROUP) {
+	    nOldIndex = 
+		TOOLBAR_GetCheckedGroupButtonIndex (infoPtr, nIndex);
+	    if (nOldIndex == nIndex)
+		return 0;
+	    if (nOldIndex != -1)
+		infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
+	}
 	btnPtr->fsState |= TBSTATE_CHECKED;
+    }
 
     hdc = GetDC32 (wndPtr->hwndSelf);
+    if (nOldIndex != -1)
+	TOOLBAR_DrawButton (wndPtr, &infoPtr->buttons[nOldIndex], hdc);
     TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
     ReleaseDC32 (wndPtr->hwndSelf, hdc);
 
+    /* FIXME: Send a WM_COMMAND or WM_NOTIFY */
+
     return TRUE;
 }
-*/
 
 
 static LRESULT
@@ -388,9 +582,9 @@
 TOOLBAR_DeleteButton (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
-    INT32 iIndex = (INT32)wParam;
+    INT32 nIndex = (INT32)wParam;
 
-    if ((iIndex < 0) || (iIndex >= infoPtr->nNumButtons))
+    if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
 	return FALSE;
 
     if (infoPtr->nNumButtons == 1) {
@@ -400,9 +594,23 @@
 	infoPtr->nNumButtons = 0;
     }
     else {
+	TBUTTON_INFO *oldButtons = infoPtr->buttons;
+        TRACE(toolbar, "complex delete! [nIndex=%d]\n", nIndex);
 
-        TRACE(header, "complex delete! [iIndex=%d]\n", iIndex);
+	infoPtr->nNumButtons--;
+	infoPtr->buttons = HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
+				      sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
+        if (nIndex > 0) {
+            memcpy (&infoPtr->buttons[0], &oldButtons[0],
+                    nIndex * sizeof(TBUTTON_INFO));
+        }
 
+        if (nIndex < infoPtr->nNumButtons) {
+            memcpy (&infoPtr->buttons[nIndex], &oldButtons[nIndex+1],
+                    (infoPtr->nNumButtons - nIndex) * sizeof(TBUTTON_INFO));
+        }
+
+        HeapFree (SystemHeap, 0, oldButtons);
     }
 
     TOOLBAR_CalcToolbar (wndPtr);
@@ -457,9 +665,164 @@
 }
 
 
-// << TOOLBAR_GetBitmapFlags >>
-// << TOOLBAR_GetButton >>
-// << ... >>
+static LRESULT
+TOOLBAR_GetBitmapFlags (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    FIXME (toolbar, "stub!\n");
+    return 0;
+}
+
+
+static LRESULT
+TOOLBAR_GetButton (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+    LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
+    INT32 nIndex = (INT32)wParam;
+    TBUTTON_INFO *btnPtr;
+
+    if (infoPtr == NULL) return FALSE;
+    if (lpTbb == NULL) return FALSE;
+
+    if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
+	return FALSE;
+
+    btnPtr = &infoPtr->buttons[nIndex];
+    lpTbb->iBitmap   = btnPtr->iBitmap;
+    lpTbb->idCommand = btnPtr->idCommand;
+    lpTbb->fsState   = btnPtr->fsState;
+    lpTbb->fsStyle   = btnPtr->fsStyle;
+    lpTbb->dwData    = btnPtr->dwData;
+    lpTbb->iString   = btnPtr->iString;
+
+    return TRUE;
+}
+
+
+// << TOOLBAR_GetButtonInfo >>
+// << TOOLBAR_GetButtonSize >>
+
+
+static LRESULT
+TOOLBAR_GetButtonText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+    INT32 nIndex, nStringIndex;
+
+    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
+    if (nIndex == -1)
+	return -1;
+
+    nStringIndex = infoPtr->buttons[nIndex].iString;
+
+    TRACE (toolbar, "index=%d stringIndex=%d\n", nIndex, nStringIndex);
+
+    if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
+	return -1;
+
+    if (lParam == 0) return -1;
+
+    lstrcpy32A ((LPSTR)lParam, (LPSTR)infoPtr->strings[nStringIndex]);
+
+    return lstrlen32A ((LPSTR)infoPtr->strings[nStringIndex]);
+}
+
+
+// << TOOLBAR_GetButtonText32W >>
+// << TOOLBAR_GetColorScheme >>
+// << TOOLBAR_GetDisabledImageList >>
+// << TOOLBAR_GetExtendedStyle >>
+// << TOOLBAR_GetHotImageList >>
+// << TOOLBAR_GetHotItem >>
+// << TOOLBAR_GetImageList >>
+// << TOOLBAR_GetInsertMark >>
+// << TOOLBAR_GetInsertMarkColor >>
+
+
+static LRESULT
+TOOLBAR_GetItemRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+    TBUTTON_INFO *btnPtr;
+    LPRECT32     lpRect;
+    INT32        nIndex;
+
+    if (infoPtr == NULL) return FALSE;
+    nIndex = (INT32)wParam;
+    btnPtr = &infoPtr->buttons[nIndex];
+    if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
+	return FALSE;
+    lpRect = (LPRECT32)lParam;
+    if (lpRect == NULL) return FALSE;
+    if (btnPtr->fsState & TBSTATE_HIDDEN) return FALSE;
+    
+    lpRect->left   = btnPtr->rect.left;
+    lpRect->right  = btnPtr->rect.right;
+    lpRect->bottom = btnPtr->rect.bottom;
+    lpRect->top    = btnPtr->rect.top;
+
+    return TRUE;
+}
+
+
+// << TOOLBAR_GetMaxSize >>
+// << TOOLBAR_GetObject >>
+// << TOOLBAR_GetPadding >>
+// << TOOLBAR_GetRect >>
+
+
+static LRESULT
+TOOLBAR_GetRows (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+
+    if (wndPtr->dwStyle & TBSTYLE_WRAPABLE)
+	return infoPtr->nMaxRows;
+    else
+	return 1;
+}
+
+
+static LRESULT
+TOOLBAR_GetState (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+    INT32 nIndex;
+
+    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
+    if (nIndex == -1) return -1;
+
+    return infoPtr->buttons[nIndex].fsState;
+}
+
+
+static LRESULT
+TOOLBAR_GetStyle (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+    INT32 nIndex;
+
+    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
+    if (nIndex == -1) return -1;
+
+    return infoPtr->buttons[nIndex].fsStyle;
+}
+
+
+// << TOOLBAR_GetTextRows >>
+
+
+static LRESULT
+TOOLBAR_GetToolTips (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+
+    if (infoPtr == NULL) return 0;
+    return infoPtr->hwndToolTip;
+}
+
+
+// << TOOLBAR_GetUnicodeFormat >>
 
 
 static LRESULT
@@ -496,6 +859,90 @@
 
 
 static LRESULT
+TOOLBAR_Indeterminate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+    TBUTTON_INFO *btnPtr;
+    HDC32 hdc;
+    INT32 nIndex;
+
+    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
+    if (nIndex == -1)
+	return FALSE;
+
+    btnPtr = &infoPtr->buttons[nIndex];
+    if (LOWORD(lParam) == FALSE)
+	btnPtr->fsState &= ~TBSTATE_INDETERMINATE;
+    else
+	btnPtr->fsState |= TBSTATE_INDETERMINATE;
+
+    hdc = GetDC32 (wndPtr->hwndSelf);
+    TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
+    ReleaseDC32 (wndPtr->hwndSelf, hdc);
+
+    return TRUE;
+}
+
+
+static LRESULT
+TOOLBAR_InsertButton32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+    LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
+    INT32 nIndex = (INT32)wParam;
+    TBUTTON_INFO *oldButtons;
+    HDC32 hdc;
+
+    if (lpTbb == NULL) return FALSE;
+    if (nIndex < 0) return FALSE;
+
+    TRACE (toolbar, "inserting button index=%d\n", nIndex);
+    if (nIndex > infoPtr->nNumButtons) {
+	nIndex = infoPtr->nNumButtons;
+	TRACE (toolbar, "adjust index=%d\n", nIndex);
+    }
+
+    oldButtons = infoPtr->buttons;
+    infoPtr->nNumButtons++;
+    infoPtr->buttons = HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
+				  sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
+    /* pre insert copy */
+    if (nIndex > 0) {
+	memcpy (&infoPtr->buttons[0], &oldButtons[0],
+		nIndex * sizeof(TBUTTON_INFO));
+    }
+
+    /* insert new button */
+    infoPtr->buttons[nIndex].iBitmap   = lpTbb->iBitmap;
+    infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand;
+    infoPtr->buttons[nIndex].fsState   = lpTbb->fsState;
+    infoPtr->buttons[nIndex].fsStyle   = lpTbb->fsStyle;
+    infoPtr->buttons[nIndex].dwData    = lpTbb->dwData;
+    infoPtr->buttons[nIndex].iString   = lpTbb->iString;
+
+    /* post insert copy */
+    if (nIndex < infoPtr->nNumButtons - 1) {
+	memcpy (&infoPtr->buttons[nIndex+1], &oldButtons[nIndex],
+		(infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO));
+    }
+
+    HeapFree (SystemHeap, 0, oldButtons);
+
+    TOOLBAR_CalcToolbar (wndPtr);
+
+    hdc = GetDC32 (wndPtr->hwndSelf);
+    TOOLBAR_Refresh (wndPtr, hdc);
+    ReleaseDC32 (wndPtr->hwndSelf, hdc);
+
+    return TRUE;
+}
+
+
+// << TOOLBAR_InsertButton32W >>
+// << TOOLBAR_InsertMarkHitTest >>
+
+
+static LRESULT
 TOOLBAR_IsButtonChecked (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
@@ -615,6 +1062,7 @@
 // << TOOLBAR_SaveRestore >>
 // << TOOLBAR_SetAnchorHighlight >>
 
+
 static LRESULT
 TOOLBAR_SetBitmapSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
@@ -666,6 +1114,14 @@
 }
 
 
+// << TOOLBAR_SetColorScheme >>
+// << TOOLBAR_SetDisabledImageList >>
+// << TOOLBAR_SetDrawTextFlags >>
+// << TOOLBAR_SetExtendedStyle >>
+// << TOOLBAR_SetHotImageList >>
+// << TOOLBAR_SetHotItem >>
+// << TOOLBAR_SetImageList >>
+
 
 static LRESULT
 TOOLBAR_SetIndent (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
@@ -683,6 +1139,36 @@
 }
 
 
+// << TOOLBAR_SetInsertMark >>
+// << TOOLBAR_SetInsertMarkColor >>
+// << TOOLBAR_SetMaxTextRows >>
+// << TOOLBAR_SetPadding >>
+
+
+static LRESULT
+TOOLBAR_SetParent (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+    HWND32 hwndOldNotify;
+
+    if (infoPtr == NULL) return 0;
+    hwndOldNotify = infoPtr->hwndNotify;
+    infoPtr->hwndNotify = (HWND32)wParam;
+
+    return hwndOldNotify;
+}
+
+
+static LRESULT
+TOOLBAR_SetRows (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+
+    FIXME (toolbar, "support multiple rows!\n");
+
+    return 0;
+}
+
 
 static LRESULT
 TOOLBAR_SetState (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
@@ -730,7 +1216,17 @@
 }
 
 
-// << TOOLBAR_SetToolTips >>
+static LRESULT
+TOOLBAR_SetToolTips (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+
+    if (infoPtr == NULL) return 0;
+    infoPtr->hwndToolTip = (HWND32)wParam;
+    return 0;
+}
+
+
 // << TOOLBAR_SetUnicodeFormat >>
 
 
@@ -744,18 +1240,27 @@
                                    sizeof(TOOLBAR_INFO));
     wndPtr->wExtra[0] = (DWORD)infoPtr;
 
+    if (infoPtr == NULL) {
+	ERR (toolbar, "could not allocate info memory!\n");
+	return 0;
+    }
+
+    /* initialize info structure */
     infoPtr->nButtonHeight = 22;
-    infoPtr->nButtonWidth = 24;
+    infoPtr->nButtonWidth = 23;
     infoPtr->nButtonTop = 2;
     infoPtr->nBitmapHeight = 15;
     infoPtr->nBitmapWidth = 16;
 
     infoPtr->nHeight = infoPtr->nButtonHeight + 6;
+    infoPtr->nMaxRows = 1;
 
     infoPtr->bCaptured = 0;
     infoPtr->nButtonDown = -1;
     infoPtr->nOldHit = -1;
 
+    infoPtr->hwndNotify = GetParent32 (wndPtr->hwndSelf);
+
     return 0;
 }
 
@@ -765,10 +1270,24 @@
 {
     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
 
+    /* delete tool tip */
+    if (infoPtr->hwndToolTip)
+	DestroyWindow32 (infoPtr->hwndToolTip);
+
     /* delete button data */
     if (infoPtr->buttons)
 	HeapFree (SystemHeap, 0, infoPtr->buttons);
 
+    /* delete strings */
+    if (infoPtr->strings) {
+	INT32 i;
+	for (i = 0; i < infoPtr->nNumStrings; i++)
+	    if (infoPtr->strings[i])
+		HeapFree (SystemHeap, 0, infoPtr->strings[i]);
+
+	HeapFree (SystemHeap, 0, infoPtr->strings);
+    }
+
     /* destroy default image list */
     if (infoPtr->himlDef)
 	ImageList_Destroy (infoPtr->himlDef);
@@ -867,6 +1386,7 @@
     TBUTTON_INFO *btnPtr;
     POINT32 pt;
     INT32   nHit;
+    INT32   nOldIndex = -1;
     HDC32   hdc;
 
     pt.x = (INT32)LOWORD(lParam);
@@ -874,20 +1394,34 @@
     nHit = TOOLBAR_InternalHitTest (wndPtr, &pt);
 
     if ((infoPtr->bCaptured) && (infoPtr->nButtonDown >= 0)) {
-
+	infoPtr->bCaptured = FALSE;
+	ReleaseCapture ();
 	btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
-
-
-
-
 	btnPtr->fsState &= ~TBSTATE_PRESSED;
+
+	if (btnPtr->fsStyle & TBSTYLE_CHECK) {
+	    if (btnPtr->fsStyle & TBSTYLE_GROUP) {
+		nOldIndex = TOOLBAR_GetCheckedGroupButtonIndex (infoPtr, infoPtr->nButtonDown);
+		if (nOldIndex == infoPtr->nButtonDown)
+		    return 0;
+		if (nOldIndex != -1)
+		    infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
+		btnPtr->fsState |= TBSTATE_CHECKED;
+	    }
+	    else {
+		if (btnPtr->fsState & TBSTATE_CHECKED)
+		    btnPtr->fsState &= ~TBSTATE_CHECKED;
+		else
+		    btnPtr->fsState |= TBSTATE_CHECKED;
+	    }
+	}
+
 	infoPtr->nButtonDown = -1;
 	infoPtr->nOldHit = -1;
 
-	infoPtr->bCaptured = FALSE;
-	ReleaseCapture ();
-
 	hdc = GetDC32 (wndPtr->hwndSelf);
+	if (nOldIndex != -1)
+	    TOOLBAR_DrawButton (wndPtr, &infoPtr->buttons[nOldIndex], hdc);
 	TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
 	ReleaseDC32 (wndPtr->hwndSelf, hdc);
 
@@ -1047,6 +1581,7 @@
 	parent = GetParent32 (wndPtr->hwndSelf);
 	GetClientRect32(parent, &parent_rect);
         infoPtr->nWidth = parent_rect.right - parent_rect.left;
+	TOOLBAR_CalcToolbar (wndPtr);
 	MoveWindow32(wndPtr->hwndSelf, parent_rect.left, parent_rect.top, //0, 0,
 		     infoPtr->nWidth, infoPtr->nHeight, TRUE);
 //    }
@@ -1072,11 +1607,15 @@
 	case TB_ADDBUTTONS32A:
 	    return TOOLBAR_AddButtons32A (wndPtr, wParam, lParam);
 
-//	case TB_ADDSTRING32A:
-//	    return TOOLBAR_AddString32A (wndPtr, wParam, lParam);
+//	case TB_ADDBUTTONS32W:
 
-//	case TB_AUTOSIZE:
-//	    return TOOLBAR_AutoSize (wndPtr, wParam, lParam);
+	case TB_ADDSTRING32A:
+	    return TOOLBAR_AddString32A (wndPtr, wParam, lParam);
+
+//	case TB_ADDSTRING32W:
+
+	case TB_AUTOSIZE:
+	    return TOOLBAR_AutoSize (wndPtr, wParam, lParam);
 
 	case TB_BUTTONCOUNT:
 	    return TOOLBAR_ButtonCount (wndPtr, wParam, lParam);
@@ -1087,8 +1626,8 @@
 	case TB_CHANGEBITMAP:
 	    return TOOLBAR_ChangeBitmap (wndPtr, wParam, lParam);
 
-//	case TB_CHECKBUTTON:
-//	    return TOOLBAR_CheckButton (wndPtr, wParam, lParam);
+	case TB_CHECKBUTTON:
+	    return TOOLBAR_CheckButton (wndPtr, wParam, lParam);
 
 	case TB_COMMANDTOINDEX:
 	    return TOOLBAR_CommandToIndex (wndPtr, wParam, lParam);
@@ -1106,7 +1645,20 @@
 	case TB_GETBITMAP:
 	    return TOOLBAR_GetBitmap (wndPtr, wParam, lParam);
 
-//	case TB_GETBITMAPFLAGS:
+	case TB_GETBITMAPFLAGS:
+	    return TOOLBAR_GetBitmapFlags (wndPtr, wParam, lParam);
+
+	case TB_GETBUTTON:
+	    return TOOLBAR_GetButton (wndPtr, wParam, lParam);
+
+//	case TB_GETBUTTONINFO:			/* 4.71 */
+//	case TB_GETBUTTONSIZE:			/* 4.70 */
+
+	case TB_GETBUTTONTEXT32A:
+	    return TOOLBAR_GetButtonText32A (wndPtr, wParam, lParam);
+
+//	case TB_GETBUTTONTEXT32W:
+//	case TB_GETCOLORSCHEME:			/* 4.71 */
 //	case TB_GETDISABLEDIMAGELIST:		/* 4.70 */
 //	case TB_GETEXTENDEDSTYLE:		/* 4.71 */
 //	case TB_GETHOTIMAGELIST:		/* 4.70 */
@@ -1114,16 +1666,29 @@
 //	case TB_GETIMAGELIST:			/* 4.70 */
 //	case TB_GETINSERTMARK:			/* 4.71 */
 //	case TB_GETINSERTMARKCOLOR:		/* 4.71 */
-//	case TB_GETITEMRECT:
+
+	case TB_GETITEMRECT:
+	    return TOOLBAR_GetItemRect (wndPtr, wParam, lParam);
+
 //	case TB_GETMAXSIZE:			/* 4.71 */
 //	case TB_GETOBJECT:			/* 4.71 */
 //	case TB_GETPADDING:			/* 4.71 */
 //	case TB_GETRECT:			/* 4.70 */
-//	case TB_GETROWS:
-//	case TB_GETSTATE:
-//	case TB_GETSTYLE:			/* 4.70 */
+
+	case TB_GETROWS:
+	    return TOOLBAR_GetRows (wndPtr, wParam, lParam);
+
+	case TB_GETSTATE:
+	    return TOOLBAR_GetState (wndPtr, wParam, lParam);
+
+	case TB_GETSTYLE:
+	    return TOOLBAR_GetStyle (wndPtr, wParam, lParam);
+
 //	case TB_GETTEXTROWS:			/* 4.70 */
-//	case TB_GETTOOLTIPS:
+
+	case TB_GETTOOLTIPS:
+	    return TOOLBAR_GetToolTips (wndPtr, wParam, lParam);
+
 //	case TB_GETUNICODEFORMAT:
 
 	case TB_HIDEBUTTON:
@@ -1132,12 +1697,13 @@
 	case TB_HITTEST:
 	    return TOOLBAR_HitTest (wndPtr, wParam, lParam);
 
-//	case TB_INDETERMINATE:
-//	    return TOOLBAR_Indeterminate (wndPtr, wParam, lParam);
+	case TB_INDETERMINATE:
+	    return TOOLBAR_Indeterminate (wndPtr, wParam, lParam);
 
-//	case TB_INSERTBUTTON:
-//	    return TOOLBAR_InsertButton (wndPtr, wParam, lParam);
+	case TB_INSERTBUTTON32A:
+	    return TOOLBAR_InsertButton32A (wndPtr, wParam, lParam);
 
+//	case TB_INSERTBUTTON32W:
 //	case TB_INSERTMARKHITTEST:		/* 4.71 */
 
 	case TB_ISBUTTONCHECKED:
@@ -1159,18 +1725,17 @@
 	    return TOOLBAR_IsButtonPressed (wndPtr, wParam, lParam);
 
 //	case TB_LOADIMAGES:			/* 4.70 */
-//	case TB_MAPACCELERATOR:			/* 4.71 */
-
+//	case TB_MAPACCELERATOR32A:		/* 4.71 */
+//	case TB_MAPACCELERATOR32W:		/* 4.71 */
 //	case TB_MARKBUTTON:			/* 4.71 */
-//	    return TOOLBAR_MarkButton (wndPtr, wParam, lParam);
-
 //	case TB_MOVEBUTTON:			/* 4.71 */
 
 	case TB_PRESSBUTTON:
 	    return TOOLBAR_PressButton (wndPtr, wParam, lParam);
 
 //	case TB_REPLACEBITMAP:
-//	case TB_SAVERESTORE:
+//	case TB_SAVERESTORE32A:
+//	case TB_SAVERESTORE32W:
 //	case TB_SETANCHORHIGHLIGHT:		/* 4.71 */
 
 	case TB_SETBITMAPSIZE:
@@ -1201,8 +1766,12 @@
 //	case TB_SETINSERTMARKCOLOR:		/* 4.71 */
 //	case TB_SETMAXTEXTROWS:			/* 4.70 */
 //	case TB_SETPADDING:			/* 4.71 */
-//	case TB_SETPARENT:
-//	case TB_SETROWS:
+
+	case TB_SETPARENT:
+	    return TOOLBAR_SetParent (wndPtr, wParam, lParam);
+
+	case TB_SETROWS:
+	    return TOOLBAR_SetRows (wndPtr, wParam, lParam);
 
 	case TB_SETSTATE:
 	    return TOOLBAR_SetState (wndPtr, wParam, lParam);
@@ -1210,7 +1779,9 @@
 	case TB_SETSTYLE:
 	    return TOOLBAR_SetStyle (wndPtr, wParam, lParam);
 
-//	case TB_SETTOOLTIPS:
+	case TB_SETTOOLTIPS:
+	    return TOOLBAR_SetToolTips (wndPtr, wParam, lParam);
+
 //	case TB_SETUNICODEFORMAT:
 
 	case WM_CREATE:
diff --git a/debugger/break.c b/debugger/break.c
index acbfcb3..68dc588 100644
--- a/debugger/break.c
+++ b/debugger/break.c
@@ -352,13 +352,31 @@
             addr.off = pModule->ip;
             fprintf( stderr, "Win16 task '%s': ", entry.szModule );
             DEBUG_AddBreakpoint( &addr );
-        }
-    }
-    for (wm=PROCESS_Current()->modref_list;wm;wm=wm->next) {
-	addr.seg = 0;
-	addr.off =(DWORD)RVA_PTR(wm->module,OptionalHeader.AddressOfEntryPoint);
-        fprintf( stderr, "Win32 module '%s': ", wm->modname );
-        DEBUG_AddBreakpoint( &addr );
+	}
+	else /* PE module */
+	{
+    
+	    if (!(wm = PROCESS_Current()->modref_list))
+	    {
+		addr.seg = 0;
+		addr.off = (DWORD)RVA_PTR( pModule->module32,
+			   OptionalHeader.AddressOfEntryPoint);
+	    }
+	    else
+	    {
+		while (wm)
+		{
+		    if (wm->module == pModule->module32) break;
+		    wm = wm->next;
+		}
+		if (!wm) continue;
+		addr.seg = 0;
+		addr.off = (DWORD)RVA_PTR( wm->module,
+			   OptionalHeader.AddressOfEntryPoint);
+	    }
+	    fprintf( stderr, "Win32 task '%s': ", entry.szModule );
+	    DEBUG_AddBreakpoint( &addr );
+	}
     }
 
     DEBUG_SetBreakpoints( TRUE );  /* Setup breakpoints */
diff --git a/debugger/memory.c b/debugger/memory.c
index 9f0cb52..0b26748 100644
--- a/debugger/memory.c
+++ b/debugger/memory.c
@@ -47,7 +47,7 @@
 
   while (fgets( buf, 79, fp)) {
     sscanf(buf, "%x-%x %3s", (int *) &start, (int *) &end, prot);
-    if ( end < addr)
+    if ( end <= addr)
       continue;
     if (start <= addr && addr+size < end) {
       if (rwflag) 
diff --git a/debugger/stabs.c b/debugger/stabs.c
index 3af1ef9..10ada5d 100644
--- a/debugger/stabs.c
+++ b/debugger/stabs.c
@@ -6,7 +6,6 @@
 
 #include <sys/types.h>
 #include <fcntl.h>
-#include <assert.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
 #include <limits.h>
@@ -178,9 +177,9 @@
 	    x--;
 	x++;				/* '(' */
 	filenr=strtol(x,&x,10);		/* <int> */
-	assert(*(x++)==',');		/* ',' */
+	x++;				/* ',' */
 	subnr=strtol(x,&x,10);		/* <int> */
-	assert(*(x++)==')');		/* ')' */
+	x++;				/* ')' */
     } else {
 	while ((*x>='0') && (*x<='9'))
 	    x--;
@@ -478,13 +477,13 @@
 	     /* ar<typeinfo_nodef>;<int>;<int>;<typeinfo>,<int>,<int>;; */
 
 	     tc  = c + 3;
-	     assert(c[2]=='r');
+	     						/* 'r' */
 	     DEBUG_ReadTypeEnum(&tc);
-	     assert(*(tc++)==';'); 			/* ';' */
+	     tc++;		 			/* ';' */
 	     arrmin = strtol(tc, &tc, 10); 		/* <int> */
-	     assert(*(tc++)==';'); 			/* ';' */
+	     tc++;		 			/* ';' */
 	     arrmax = strtol(tc, &tc, 10);		/* <int> */
-	     assert(*(tc++)==';'); 			/* ';' */
+	     tc++;		 			/* ';' */
 	     datatype = stab_types[DEBUG_ReadTypeEnum(&tc)]; /* <typeinfo> */
 	     if( *tc == '\0' )
 		 *c = '\0';
diff --git a/documentation/aspi b/documentation/aspi
index 942357e..a0b9d43 100644
--- a/documentation/aspi
+++ b/documentation/aspi
@@ -23,6 +23,8 @@
 (ASPI). At least with Mustek, they allow you the choice of using
 the builtin card or the "Adaptec (AHA)" compatible drivers. This will not
 work any other way.
+Software that accesses the scanner via a DOS ASPI driver (e.g. ASPI2DOS)
+is supported, too. [AM]
 
 1) You probably need a real windows install of the software to set the
 LUN's/SCSI id's up correctly. I'm not exactly sure.
@@ -70,9 +72,15 @@
 The biggest is that it only works under linux at the moment.
 The ASPI code was only tested using a Mustek 800SP with a Buslogic
 controller under Linux.
+The ASPI code has only been tested with:
+- a Mustek 800SP with a Buslogic controller under Linux [BM]
+- a Siemens Nixdorf 9036 with Adaptec AVA-1505 under Linux
+  accessed via DOSASPI.
+  Note that I had color problems, though (barely readable result). [AM]
 
 I make no warranty to the aspi code. It makes my scanner work. Your scanner
 may explode. I have no way of determining this. I take zero responsibility!
 
 
 Bruce Milner
+Additions by Andreas Mohr
diff --git a/documentation/debug-msgs b/documentation/debug-msgs
index da00b7f..eacf370 100644
--- a/documentation/debug-msgs
+++ b/documentation/debug-msgs
@@ -1,14 +1,12 @@
 Note: The new debugging interface can be considered to be stable,
       with the exception of the in-memory message construction functions.
       However, there is still a lot of work to be done to polish
-      things up and to convert the remaining fprintf. To make my life 
-      easier, please follow the guidelines described in this document. 
+      things up. To make my life easier, please follow the guidelines
+      described in this document. 
 
-      Read this document before writing new code.
-      Also, DO NOT USE fprintf (or printf) to output things. All these
-      will have to be translated to the new interface and there are already
-      about 1000 of them! Also, instead of writing FIXMEs in the source,
-      output a FIXME message if you can. 
+      Read this document before writing new code. DO NOT USE fprintf 
+      (or printf) to output things. Also, instead of writing 
+      FIXMEs in the source, output a FIXME message if you can. 
 
       IMPORTANT: at the end of the document, there is a "Style Guide"
       for debugging messages. Please read it.
@@ -349,9 +347,24 @@
 Also, note that at the moment:
    - the fixme and err classes are enabled by default
    - the trace and warn  classes are disabled by default
-   - there is no way to compile out the messages. All are 
-     runtime configurable. This will (hopefully) come next 
-     release.
+
+
+Compiling Out Debugging Messages
+--------------------------------
+
+To compile out the debugging messages, provide configure with the
+following options:
+
+--disable-debug      -- turns off TRACE, WARN, and FIXME (and DUMP).
+
+--disable-trace      -- turns off TRACE only.
+
+This will result in an executable that, when stripped, is about 15%-20%
+smaller.  Note, however, that you will not be able to effectively debug
+Wine without these messages.  
+
+This feature has not been extensively tested--it may subtly break some
+things.
 
 
 A Few Notes on Style
diff --git a/documentation/debugging b/documentation/debugging
index 6de0cb5..dcc9de0 100644
--- a/documentation/debugging
+++ b/documentation/debugging
@@ -68,10 +68,9 @@
 
  3. If you have found a misbehaving function, try to find out why it
     misbehaves. Find the function in the source code. Try to make sense of
-    the arguments passed. Usually there is a
-    "dprintf_xyz(stddeb,"Function(...)"...);" at the beginning of the
-    function. Rerun wine with "-debugmsg +xyz,+relay" added to the
-    commandline.
+    the arguments passed. Usually there is a 'TRACE(<channel>,"(...)\n");' 
+    at the beginning of the function. Rerun wine with 
+    "-debugmsg +xyz,+relay" added to the commandline.
 
  4. Additional information on how to debug using the internal debugger can be 
     found in debugger/README.
@@ -81,7 +80,7 @@
     +all", which dumps ALL included debug information in wine.
 
  6. If that isn't enough add more debug output for yourself into the
-    functions you find relevant.
+    functions you find relevant.  See documentation/debug-msgs.
     You might also try to run the program in gdb instead of using the
     WINE-debugger. If you don't use the "-desktop" or "-managed" option,
     start the WINE process with "-sync", or chances are good to get X into
diff --git a/documentation/wine.texinfo b/documentation/wine.texinfo
index 1425f84..dcf76a1 100644
--- a/documentation/wine.texinfo
+++ b/documentation/wine.texinfo
@@ -271,6 +271,7 @@
 @menu
 * Copying::                     License, Warranty, and Authors of Wine.
 * Introduction::                A short overview.
+* Wine Design::                 The design of Wine.
 * Reference Manual::            The Wine reference manual.
 * Installation::                Installing and configuring Wine.
 * The Wine Project::            How to contribute to Wine.
@@ -340,54 +341,37 @@
 
 
 
-@node Introduction, Reference Manual, Copying, Top
+@node Introduction, Wine Design, Copying, Top
 @chapter Introduction
 
-@center Wine:
-@center the WINdows Emulator,
-@center or Wine Is Not an Emulator
-
-FIXME: make an easy-readable fluent text out of this.
-
-Welcome to @winemanualtitle{}. This is edition @winemanualversion{},
-last updated @winemanualdate{}.
-
 @strong{What is Wine?}
 
-Wine is a program that allows running MS-Windows programs under X11.
-
-
-Wine incorporates two features, the program loader and @winelib{}:
+Wine is a Windows-compatibility layer for Unix and X11.
+The Wine system consists of several thing:
 @enumerate
 @item
-You can run @mswindows{} binaries (programs) in Wine. Wine contains a
-program loader which loads and executes an @mswindows{} binary. It uses
-the @winelib{} features of Wine to translate @WIN32{} and @WIN16{} calls
-to their @unix{}/X11 equivalent.
-
-Both 16 bit and 32 bit binaries can be loaded.
+An API, sometimes referred to as the Wine API,
+designed to be as compatible as possible with the
+@mswindows{} API
 @item
-@winelib{}: Wine can also be used as a library which implements the 
-@mswindows{} API on top of a @unix{} or @unix{}-like operating system
-with X11. @winelib{} (i.e. the Wine library) translates @WIN16{} or
-@WIN32{} API calls to their @unix{}/X11 equivalent.
+A library, called @winelib{}, which implements this API
+@item
+A binary compatibility layer, sometimes referred to as the Wine
+emulator, which acts as a program loader for native Windows binaries.
+The emulator works for both 16 and 32 bit Intel binaries, and
+provides all the appropriate translation between 16 and 32 bit code
+(thunking). Real mode interrupts are also supported, and their
+functionality is implemented in @winelib{}.
 
-You can write a user-level application program that calls the @WIN16{}
-or @WIN32{} API functions and compile it on a @unix{} box.
 @end enumerate
 
-@strong{Status}
+@strong{System Requirements}
 
-Wine is still at development stage. The file @file{ANNOUNCE} says,
-``This is still a developer's only release.  There are many bugs and
-many unimplemented API features.  Most applications still do not work
-correctly.''
-@xref{Warranty}, for additional information.
 
-@strong{Requirements}
-
-Wine needs an 80x86 CPU to run on. Emulating the CPU is currently not
-possible.
+Wine provides binary support for Intel code on Intel hardware only. 
+Neither hardware emulation
+nor non-Intel binaries are supported.
+@winelib{} should be possible to port to just about any Unix system.
 
 Currently, you must have one of:
 @itemize @bullet
@@ -397,46 +381,161 @@
 NetBSD-current
 @item
 FreeBSD-current or FreeBSD 1.1
+@item
+OpenBSD/i386 2.1 or later
+@item
+Solaris x86 2.5 or later
 @end itemize
 You need X11, and you must have @file{libXpm} installed on your system.
 
 @strong{Availability}
 
-Wine is free software. The file @file{README} says, ``Basically, you can do
-anything with it, except claim that you wrote it.''
+Wine is free software; the license is BSD-style. Basically, you can do
+anything with it, except claim that you wrote it.
 @xref{Copying}, for more information.
 
-@strong{Performance}
-
-Wine is expected to run @mswindows{} binaries about the same speed as
-@mswindows{} would. However, be aware that the 16 bit versions of
-@mswindows{} programs are generally slower than their 32 bit
-counterparts.
-
 @strong{Further information}
 
 You should consult the files @file{README}, @file{ANNOUNCE},
 @file{RELEASE-NOTES}, @file{BUGS}, @file{LICENSE}, and @file{WARRANTY},
 in the root directory of the Wine distribution.
 
-The Wine FAQ, available from @*
-@url{ftp://ftp.asgardpro.com/wine/dave/Wine.FAQ}, @*
-@url{ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/Wine.FAQ}, @*
-@url{ftp://rtfm.mit.edu/pub/usenet-by-group/comp.emulators.ms-windows.wine/WINE_(WINdows_Emulator)_Frequently_Asked_Questions}, @*
-@url{ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/Wine.FAQ}, @*
-@url{http://www.asgardpro.com/wine/index.html}, @*
-gives answer to a lot of questions.
+The Wine USENET newsgroup  @url{news:comp.emulators.ms-windows.wine} 
+is useful for both Wine developers and Wine users. The Wine home page
+is @url{http://www.winehq.com/}.
 
-The Wine USENET newsgroup is interesting for developers. It discusses technical
-matters about Wine. The address is: @url{news:comp.emulators.ms-windows.wine}.
+@node Wine Design,  Reference Manual,  Introduction,  Top
+@chapter Wine Design
+
+@subsection The Wine Graphics Driver Model
+
+Wine, like Windows, abstracts drawing code so that applications may access
+a wide variety of devices, from different kinds of graphics cards,
+X displays and printers, using a single unified graphics model.
+This model is referred to as GDI: _G_raphics _D_river _I_nterface.
+This section discusses the Wine implementation of GDI.
+There are 61 functions in the Wine graphics model, including Arc, BitBlt,
+Chord, etc. For a complete list and prototypes, see the definition
+of DC_FUNCTIONS in [include/gdi.h].
+
+Wine, as of 2Q1998, has three native drivers: these provide support
+for rendering to X displays, metafiles, and Win16 native printer drivers.
+As far as Wine is concerned, a driver
+simply consists of a name and a table of function pointers 
+(see [graphics/driver.c]). These functions
+are the driver's implementation of the various Wine graphics
+operations (the GDI).  Wine maintains a linked list of all drivers which
+register themselves with Wine, as well as a ``generic''
+driver. Currently, the X11 driver registers itself as DISPLAY, the
+win16 driver registers itself as the generic driver, and the metafile
+driver doesn't register itself at all.
+
+@subsubsection How a driver function gets invoked
+
+All drawing by Wine applications 
+is done in terms of a Device Context (DC).
+Before an application can draw, it must create a DC, and all drawing calls
+must pass a handle to the DC they wish to draw to.
+[include/gdi.h] defines several structures relating to DCs, including
+DC, WIN_DC_INFO, and DeviceCaps. The DeviceCaps structure is at the lowest
+level: it holds
+information relating to specifics of the graphics display 
+hardware and associated
+driver. 
+WIN_DC_INFO holds information about several device independent
+modes the DC can be in, plus a pointer to DeviceCaps.
+Finally,
+the DC structure is the toplevel structure usually passed around.
+It holds viewport information, a pointer to WIN_DC_INFO, and a
+pointer to the function table to be used while rendering that DC.
+This function table is filled at the time of creating the DC.
+
+@c Modes
+
+@c  Some discussion of the various modalities available to a DC would be nice.
+
+@c Coordinate Systems
+
+@c  Some discussion of the maze of coordinate systems would also be nice.
+
+@c  Device Coordinates
+
+@c  Logical Coordinates
+
+@c  World transforms
 
 
+@subsubsection The X11 driver
 
-@xref{The Wine Project}, if you consider contributing some work.
+As a part of the Wine loading process,
+X11DRV_Init in [graphics/x11drv/init.c] is called. 
+This initializes various aspects of the X11 driver and
+registers it as DISPLAY.  This function first 
+calls initialization procedures for various parts of the X11 driver.
+It then
+creates and 
+fills a static DeviceCaps
+structure to be used for every X11 DC.
+Finally, it fills the table of GDI functions to be used for X11
+rendering and registers itself as ``DISPLAY''.
+
+@subsubsection The Metafile Driver
+
+The metafile driver is unusual, in that it is not a driver for any
+kind of display device, but rather a mechanism which allows using
+the Wine graphics model as a file format for saving graphics.
+The advantage of this is that it allows using identical formats for
+saving pictures as is actually used to display them; it is analogous
+to Display PostScript.
+
+The metafile driver is invoked explicitly by the application. The
+application calls CreateMetaFile() to create a special DC for recording
+graphics drawing operations in a metafile. Any drawing operations
+performed in this DC are not drawn physically anywhere, they are
+instead stored in the metafile.  The DC is explicitly destroyed by a
+call to CloseMetaFile(), which also finishes writing the metafile.
+Metafiles may be written either to a file or to memory. Later, the
+metafile can be rendered (in a physical DC) by PlayMetaFile().
+
+The way that this works is that device contexts contain a pointer
+to the function lookup table for drawing operations appropriate for
+that device.
+
+Not all functions in the Wine graphics model are relevant to metafiles, but
+some relevant but rarely used functions are unimplemented.
+
+@subsubsection The WIN16 Driver
+
+WIN16DRV_Init is called by MAIN_EmulatorInit, and registers the
+WIN16DRV function table WIN16DRV_Funcs [graphics/win16drv/init.c]
+for the generic driver. The WIN16 driver is designed to load 
+specified native Windows printer drivers. I don't understand 
+how the whole scheme works, 
+start studying what happens when a printer DC is
+created via WIN16DRV_CreateDC.
+
+If a DC is created explicitly, via the
+CreateDC() call, the driver name is specified explicitly and Wine
+finds the appropriate driver by leafing through its table of registered
+drivers. Metafile DCs can only be created by the CreateMetaFile function.
+
+Alternatively, most of the time, the DISPLAY driver is invoked
+implicitly. 
+The application creates a window with
+CreateWindow(). If the CS_CLASSDC or CS_OWNDC flag is passed, a new DC
+is created and saved for the window in a structure called DCE, which holds
+a DC, a clipping region, and flags. Whenever the application wants to
+paint in that window, it calls GetDC(hwnd), which returns the DC in the
+DCE saved in the window.
+
+If neither of those flags are used, the window gets a DCE assigned to it
+from a pool of DCEs created during Wine initialization and temporarily
+assigned during the GetDC() call.
+All DCEs, whether part of the Wine DC pool or created by request of a window,
+use the ``DISPLAY'' driver. 
 
 
-
-@node Reference Manual, Installation, Introduction, Top
+@node Reference Manual, Installation, Wine Design, Top
 
 @menu
 * WIN32 Reference Manual::      The @WIN32{} function calls and data types.
diff --git a/files/dos_fs.c b/files/dos_fs.c
index 4d9586f..8c1659d 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -47,7 +47,7 @@
 #define INVALID_DOS_CHARS  "*?<>|\"+=,;[] \345"
 
 static const char *DOSFS_Devices[] = {
-"CON","PRN","NUL","AUX","LPT1","LPT2","LPT3","LPT4","COM1","COM2","COM3","COM4",
+"CON","PRN","NUL","AUX","LPT1","LPT2","LPT3","LPT4","COM1","COM2","COM3","COM4","SCSIMGR$"
 };
 
 
@@ -587,6 +587,8 @@
 {
     int i;
     const char *p;
+    FILE_OBJECT *file;
+    HFILE32 handle;
 
     if (name[0] && (name[1] == ':')) name += 2;
     if ((p = strrchr( name, '/' ))) name = p + 1;
@@ -615,6 +617,14 @@
 				break;
 			}
 		}
+		if (!strcmp(DOSFS_Devices[i],"SCSIMGR$")) {
+		        if ((handle = FILE_Alloc( &file )) == INVALID_HANDLE_VALUE32)
+				return HFILE_ERROR32;
+			else {
+				file->unix_name = HEAP_strdupA( SystemHeap, 0, name );
+				return handle;
+			}
+		}
 		FIXME(dosfs,"device open %s not supported (yet)\n",DOSFS_Devices[i]);
     		return HFILE_ERROR32;
 	    }
diff --git a/files/drive.c b/files/drive.c
index a5168bc..246b347 100644
--- a/files/drive.c
+++ b/files/drive.c
@@ -542,6 +542,9 @@
 	                        "drive %c already exists\n",
 			'A' + existing_drive, 'A' + new_drive,
 			'A' + new_drive );
+	/* it is already mapped there, so return success */
+	if (!strcmp(old->root,new->root))
+	    return 1;
 	return 0;
     }
 
@@ -851,6 +854,10 @@
 {
     int drive = DRIVE_GetCurrentDrive();
 
+    if (!dir) {
+    	ERR(file,"(NULL)!\n");
+	return FALSE;
+    }
     if (dir[0] && (dir[1]==':'))
     {
         drive = tolower( *dir ) - 'a';
diff --git a/files/file.c b/files/file.c
index 983353e..c48bbc6 100644
--- a/files/file.c
+++ b/files/file.c
@@ -73,14 +73,14 @@
  *
  * Allocate a file.
  */
-static HFILE32 FILE_Alloc( FILE_OBJECT **file )
+HFILE32 FILE_Alloc( FILE_OBJECT **file )
 {
     HFILE32 handle;
     *file = HeapAlloc( SystemHeap, 0, sizeof(FILE_OBJECT) );
     if (!*file)
     {
         DOS_ERROR( ER_TooManyOpenFiles, EC_ProgramError, SA_Abort, EL_Disk );
-        return NULL;
+        return (HFILE32)NULL;
     }
     (*file)->header.type = K32OBJ_FILE;
     (*file)->header.refcount = 0;
@@ -185,7 +185,7 @@
  * Return the DOS file associated to a task file handle. FILE_ReleaseFile must
  * be called to release the file.
  */
-static FILE_OBJECT *FILE_GetFile( HFILE32 handle )
+FILE_OBJECT *FILE_GetFile( HFILE32 handle )
 {
     return (FILE_OBJECT *)HANDLE_GetObjPtr( PROCESS_Current(), handle,
                                             K32OBJ_FILE, 0 /*FIXME*/ );
diff --git a/files/profile.c b/files/profile.c
index f53800f..53e610a 100644
--- a/files/profile.c
+++ b/files/profile.c
@@ -150,6 +150,14 @@
     }
 }
 
+static int
+PROFILE_isspace(char c) {
+	if (isspace(c)) return 1;
+	if (c=='\r' || c==0x1a) return 1;
+	/* CR and ^Z (DOS EOF) are spaces too  (found on CD-ROMs) */
+	return 0;
+}
+
 
 /***********************************************************************
  *           PROFILE_Load
@@ -176,9 +184,9 @@
     {
         line++;
         p = buffer + strlen(buffer) - 1;
-        while ((p > buffer) && ((*p == '\n') || isspace(*p))) *p-- = '\0';
+        while ((p > buffer) && ((*p == '\n') || PROFILE_isspace(*p))) *p--='\0';
         p = buffer;
-        while (*p && isspace(*p)) p++;
+        while (*p && PROFILE_isspace(*p)) p++;
         if (*p == '[')  /* section start */
         {
             if (!(p2 = strrchr( p, ']' )))
@@ -203,9 +211,9 @@
         if ((p2 = strchr( p, '=' )) != NULL)
         {
             char *p3 = p2 - 1;
-            while ((p3 > p) && isspace(*p3)) *p3-- = '\0';
+            while ((p3 > p) && PROFILE_isspace(*p3)) *p3-- = '\0';
             *p2++ = '\0';
-            while (*p2 && isspace(*p2)) p2++;
+            while (*p2 && PROFILE_isspace(*p2)) p2++;
         }
         key = HEAP_xalloc( SystemHeap, 0, sizeof(*key) );
         key->name  = HEAP_strdupA( SystemHeap, 0, p );
@@ -765,7 +773,7 @@
         fclose( f );
         return 1;
     }
-    WARN(profile, "Can't open configuration file %s or $HOME%s\n",
+    MSG( "Can't open configuration file %s or $HOME%s\n",
 	 WINE_INI_GLOBAL, PROFILE_WineIniName );
     return 0;
 }
@@ -787,9 +795,9 @@
         {
             if( lpch ) *lpch = '\0'; else *lpchX = '\0';
             while( *(++lpchX) )
-                if( !isspace(*lpchX) ) return lpchX;
+                if( !PROFILE_isspace(*lpchX) ) return lpchX;
         }
-	else if( isspace( *lpchX ) && !lpch ) lpch = lpchX;
+	else if( PROFILE_isspace( *lpchX ) && !lpch ) lpch = lpchX;
 	     else lpch = NULL;
     }
     if( lpch ) *lpch = '\0';
diff --git a/graphics/ddraw.c b/graphics/ddraw.c
index bd37998..5c46c13 100644
--- a/graphics/ddraw.c
+++ b/graphics/ddraw.c
@@ -960,11 +960,19 @@
 	return 0;
 }
 
+static HRESULT WINAPI IDirectDrawClipper_GetClipList(
+	LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm
+) {
+	FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
+	if (hmm) *hmm=0;
+	return 0;
+}
+
 static struct IDirectDrawClipper_VTable ddclipvt = {
 	(void*)1,
 	(void*)2,
 	IDirectDrawClipper_Release,
-	(void*)4,
+	IDirectDrawClipper_GetClipList,
 	(void*)5,
 	(void*)6,
 	(void*)7,
@@ -1511,6 +1519,14 @@
 	return 0;
 }
 
+/* what can we directly decompress? */
+static HRESULT WINAPI IDirectDraw_GetFourCCCodes(
+	LPDIRECTDRAW this,LPDWORD x,LPDWORD y
+) {
+	FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
+	return 0;
+}
+
 static IDirectDraw_VTable ddvt = {
 	IDirectDraw_QueryInterface,
 	IDirectDraw_AddRef,
@@ -1525,7 +1541,7 @@
 	IDirectDraw_FlipToGDISurface,
 	IDirectDraw_GetCaps,
 	IDirectDraw_GetDisplayMode,
-	(void*)14,
+	IDirectDraw_GetFourCCCodes,
 	(void*)15,
 	IDirectDraw_GetMonitorFrequency,
 	(void*)17,
diff --git a/graphics/env.c b/graphics/env.c
index a004ee8..cb1f498 100644
--- a/graphics/env.c
+++ b/graphics/env.c
@@ -4,80 +4,136 @@
  * Note: This has NOTHING to do with the task/process environment!
  *
  * Copyright 1997 Marcus Meissner
+ * Copyright 1998 Andreas Mohr
  */
 #include <windows.h>
 #include <stdio.h>
+#include <string.h>
 #include <config.h>
 #include <gdi.h>
 #include <debug.h>
 
+typedef struct {
+        ATOM atom;
+	HGLOBAL16 handle;
+} ENVTABLE;
+
+static ENVTABLE EnvTable[20];
+
+static ENVTABLE *SearchEnvTable(ATOM atom)
+{
+    INT16 i;
+    
+    for (i = 20; i; i--) {
+      if (EnvTable[i].atom == atom) return &EnvTable[i];
+    }
+    return NULL;
+}
+
+static ATOM GDI_GetNullPortAtom(void)
+{
+    static ATOM NullPortAtom = 0;
+    if (!NullPortAtom)
+    {
+        char NullPort[256];
+        
+        GetProfileString32A( "windows", "nullport", "none",
+                             NullPort, sizeof(NullPort) );
+        NullPortAtom = AddAtom32A( NullPort );
+    }
+    return NullPortAtom;
+}
+
+static ATOM PortNameToAtom(LPCSTR lpPortName, BOOL16 add)
+{
+    char PortName[256];
+    LPCSTR p;
+
+    if (lpPortName[strlen(lpPortName) - 1] == ':') {
+        strncpy(PortName, lpPortName, strlen(lpPortName) - 1);
+        p = PortName;
+    }
+    else
+        p = lpPortName;
+
+    if (add)
+        return AddAtom32A(p);
+    else
+        return FindAtom32A(p);
+}
+
+
 /***********************************************************************
  *           GetEnvironment   (GDI.134)
  */
-INT16 WINAPI GetEnvironment(LPCSTR lpPortName, LPDEVMODE16 lpdev, UINT16 nMaxSiz)
+INT16 WINAPI GetEnvironment(LPCSTR lpPortName, LPDEVMODE16 lpdev, UINT16 nMaxSize)
 {
-   FIXME(gdi, "('%s','%p',%d),stub\n", lpPortName, lpdev, nMaxSiz);
-    return 0;
+    ATOM atom;
+    LPCSTR p;
+    ENVTABLE *env;
+    WORD size;
+
+    TRACE(gdi, "('%s', %p, %d)\n", lpPortName, lpdev, nMaxSize);
+
+    if (!(atom = PortNameToAtom(lpPortName, FALSE)))
+	return 0;
+    if (atom == GDI_GetNullPortAtom())
+	if (!(atom = FindAtom32A((LPCSTR)lpdev)))
+	    return 0;
+    if (!(env = SearchEnvTable(atom)))
+	return 0;
+    size = GlobalSize16(env->handle);
+    if (!lpdev) return 0;
+    if (size < nMaxSize) nMaxSize = size;
+    if (!(p = GlobalLock16(env->handle))) return 0;
+    memcpy(lpdev, p, nMaxSize);
+    GlobalUnlock16(env->handle);
+    return nMaxSize;
 }
 
+
 /***********************************************************************
  *          SetEnvironment   (GDI.132)
  */
 INT16 WINAPI SetEnvironment(LPCSTR lpPortName, LPDEVMODE16 lpdev, UINT16 nCount)
 {
+    ATOM atom; 
+    BOOL16 nullport = FALSE;
+    LPSTR p;
+    ENVTABLE *env;
+    HGLOBAL16 handle;
 
-   FIXME(gdi, "('%s', '%p', %d) stub!\n", lpPortName, lpdev, nCount);
-   if (TRACE_ON(gdi)) DUMP(
-    	"\tdevmode:\n"
-    	"\tname = %s\n"
-	"\tdmSpecVersion = %d\n"
-	"\tdmDriverVersion = %d\n"
-	"\tdmSize = %d\n"
-	"\tdmDriverExtra = %d\n"
-	"\tdmFields = %ld\n"
-	"\tdmOrientation = %d\n"
-	"\tdmPaperSize = %d\n"
-	"\tdmPaperLength = %d\n"
-	"\tdmPaperWidth = %d\n"
-	"\tdmScale = %d\n"
-	"\tdmCopies = %d\n"
-	"\tdmDefaultSource = %d\n"
-	"\tdmPrintQuality = %d\n"
-	"\tdmColor = %d\n"
-	"\tdmDuplex = %d\n"
-	"\tdmYResolution = %d\n"
-	"\tdmTTOption = %d\n"
-	"\tdmCollate = %d\n"
-	"\tdmFBitsPerPel = %d\n"
-	"\tdmPelsWidth = %ld\n"
-	"\tdmPelsHeight = %ld\n"
-	"\tdmDisplayFlags = %ld\n"
-	"\tdmDisplayFrequency = %ld\n",
-	
-    	lpdev->dmDeviceName,
-    	lpdev->dmSpecVersion,
-    	lpdev->dmDriverVersion,
-    	lpdev->dmSize,
-    	lpdev->dmDriverExtra,
-    	lpdev->dmFields,
-    	lpdev->dmOrientation,
-    	lpdev->dmPaperSize,
-    	lpdev->dmPaperLength,
-    	lpdev->dmPaperWidth,
-    	lpdev->dmScale,
-    	lpdev->dmCopies,
-    	lpdev->dmDefaultSource,
-    	lpdev->dmPrintQuality,
-    	lpdev->dmColor,
-    	lpdev->dmDuplex,
-    	lpdev->dmYResolution,
-    	lpdev->dmTTOption,
-    	lpdev->dmCollate,
-    	lpdev->dmBitsPerPel,
-    	lpdev->dmPelsWidth,
-    	lpdev->dmPelsHeight,
-    	lpdev->dmDisplayFlags,
-    	lpdev->dmDisplayFrequency
-   );
-    return 0;
+    TRACE(gdi, "('%s', %p, %d)\n", lpPortName, lpdev, nCount);
+
+    if ((atom = PortNameToAtom(lpPortName, FALSE))) {
+	if (atom == GDI_GetNullPortAtom()) {
+	    nullport = TRUE;
+	    atom = FindAtom32A((LPCSTR)lpdev);
+	}
+	env = SearchEnvTable(atom);
+        GlobalFree16(env->handle);
+        env->atom = 0;
+    }
+    if (nCount) { /* store DEVMODE struct */
+	if (nullport)
+	    p = (LPSTR)lpdev;
+        else
+	    p = (LPSTR)lpPortName;
+
+        if ((atom = PortNameToAtom(p, TRUE))
+	 && (env = SearchEnvTable(0))
+	 && (handle = GlobalAlloc16(GMEM_SHARE|GMEM_MOVEABLE, nCount))) {
+	    if (!(p = GlobalLock16(handle))) {
+	        GlobalFree16(handle);
+	        return 0;
+	    }
+	    env->atom = atom;
+	    env->handle = handle;
+            memcpy(p, lpdev, nCount);
+            GlobalUnlock16(handle);
+            return handle;
+	}
+	else return 0;
+    }
+    else return -1;
 }
diff --git a/graphics/fontengine.c b/graphics/fontengine.c
index 0a65297..1ea67c7 100644
--- a/graphics/fontengine.c
+++ b/graphics/fontengine.c
@@ -5,10 +5,10 @@
  * Copyright 1998 David Lee Lambert
  * 
  */
-#include "windows.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <debug.h>     
+#include "windows.h"
 #include "font.h"
 
 
diff --git a/graphics/win16drv/init.c b/graphics/win16drv/init.c
index 2b85707..e7ad018 100644
--- a/graphics/win16drv/init.c
+++ b/graphics/win16drv/init.c
@@ -22,6 +22,7 @@
 #include "callback.h"
 #include "options.h"
 #include "debug.h"
+#include "dc.h"
 
 #define SUPPORT_REALIZED_FONTS 1
 #pragma pack(1)
@@ -175,6 +176,7 @@
     if (lstrcmpi32A(printerEnabled,"on"))
     {
         MSG("WIN16DRV_CreateDC disabled in wine.conf file\n");
+	MSG("Enable printing with \"printer=on\"");
         return FALSE;
     }
 
@@ -284,8 +286,12 @@
             nRet = 0;
 	    break;
           case SETABORTPROC:
-	    FIXME(win16drv,"Escape: SetAbortProc ignored should be stored in dc somewhere\n");
-            /* Make calling application believe this worked */
+		/* FIXME: The AbortProc should be called:
+		- After every write to printer port or spool file
+		- Several times when no more disk space
+		- Before every metafile record when GDI does banding
+		*/ 
+/*	    dc->w.lpfnPrint = (FARPROC16)lpInData; FIXME! */
             nRet = 1;
 	    break;
 
@@ -340,9 +346,40 @@
 }
 
 
+/**********************************************************************
+ *           QueryAbort   (GDI.155)
+ *
+ *  Calls the app's AbortProc function if avail.
+ *
+ * RETURNS
+ * TRUE if no AbortProc avail or AbortProc wants to continue printing.
+ * FALSE if AbortProc wants to abort printing.
+ */
+BOOL16 WINAPI QueryAbort(HDC16 hdc, INT16 reserved)
+{
+    DC *dc = DC_GetDCPtr( hdc );
 
+    if ((!dc) || (!dc->w.lpfnPrint))
+	return TRUE;
+    return dc->w.lpfnPrint(hdc, 0);
+}
 
-/****************** misc. printer releated functions */
+/**********************************************************************
+ *           SetAbortProc   (GDI.381)
+ *
+ */
+INT16 WINAPI SetAbortProc(HDC16 hdc, FARPROC16 abrtprc)
+{
+    DC *dc = DC_GetDCPtr( hdc );
+
+    if (dc) {
+	dc->w.lpfnPrint = abrtprc;
+	return 1;
+    }
+    return -1;
+} 
+
+/****************** misc. printer related functions */
 
 /*
  * The following function should implement a queing system
@@ -600,6 +637,15 @@
 	  nRet = SP_OUTOFDISK;
 	else
 	  nRet = cch;
+	if (pPrintJob->hDC == 0) {
+	    ERR(print, "hDC == 0 !\n");
+	    return SP_ERROR;
+	}
+	if (!(QueryAbort(pPrintJob->hDC, (nRet == SP_OUTOFDISK) ? nRet : 0 )))
+	{
+	    CloseJob(hJob); /* printing aborted */
+	    nRet = SP_APPABORT;
+	}
     }
     return nRet;
 }
diff --git a/graphics/x11drv/graphics.c b/graphics/x11drv/graphics.c
index 8874368..4f08fdf 100644
--- a/graphics/x11drv/graphics.c
+++ b/graphics/x11drv/graphics.c
@@ -4,6 +4,12 @@
  * Copyright 1993,1994 Alexandre Julliard
  */
 
+
+/*
+ * FIXME: none of these functions obey the GM_ADVANCED
+ * graphics mode
+ */
+
 #include <math.h>
 #ifdef HAVE_FLOAT_H
 # include <float.h>
@@ -72,6 +78,9 @@
  *
  * Helper functions for Arc(), Chord() and Pie().
  * 'lines' is the number of lines to draw: 0 for Arc, 1 for Chord, 2 for Pie.
+ *
+ * FIXME: incorrect with thick pen and/or PS_INSIDEFRAME style
+ *        see ellipse and rectangle functions
  */
 static BOOL32
 X11DRV_DrawArc( DC *dc, INT32 left, INT32 top, INT32 right,
@@ -191,24 +200,32 @@
 BOOL32
 X11DRV_Ellipse( DC *dc, INT32 left, INT32 top, INT32 right, INT32 bottom )
 {
+    INT32 width, oldwidth;
+
     left   = XLPTODP( dc, left );
     top    = YLPTODP( dc, top );
     right  = XLPTODP( dc, right );
     bottom = YLPTODP( dc, bottom );
-    if ((left == right) || (top == bottom)) return FALSE;
+    if ((left == right) || (top == bottom)) return TRUE;
 
     if (right < left) { INT32 tmp = right; right = left; left = tmp; }
     if (bottom < top) { INT32 tmp = bottom; bottom = top; top = tmp; }
     
-    if ((dc->u.x.pen.style == PS_INSIDEFRAME) &&
-        (dc->u.x.pen.width < right-left-1) &&
-        (dc->u.x.pen.width < bottom-top-1))
+    oldwidth = width = dc->u.x.pen.width;
+    if (!width) width = 1;
+    if(dc->u.x.pen.style == PS_NULL) width = 0;
+
+    if ((dc->u.x.pen.style == PS_INSIDEFRAME))
     {
-        left   += dc->u.x.pen.width / 2;
-        right  -= (dc->u.x.pen.width + 1) / 2;
-        top    += dc->u.x.pen.width / 2;
-        bottom -= (dc->u.x.pen.width + 1) / 2;
+        if (2*width > (right-left)) width=(right-left + 1)/2;
+        if (2*width > (bottom-top)) width=(bottom-top + 1)/2;
+        left   += width / 2;
+        right  -= (width - 1) / 2;
+        top    += width / 2;
+        bottom -= (width - 1) / 2;
     }
+    if(width == 1) width=0;
+    dc->u.x.pen.width=width;
 
     if (DC_SetupGCForBrush( dc ))
 	TSXFillArc( display, dc->u.x.drawable, dc->u.x.gc,
@@ -218,6 +235,7 @@
 	TSXDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
 		  dc->w.DCOrgX + left, dc->w.DCOrgY + top,
 		  right-left-1, bottom-top-1, 0, 360*64 );
+    dc->u.x.pen.width=oldwidth;
     return TRUE;
 }
 
@@ -228,39 +246,36 @@
 BOOL32
 X11DRV_Rectangle(DC *dc, INT32 left, INT32 top, INT32 right, INT32 bottom)
 {
-    INT32 width;
+    INT32 width, oldwidth;
+
+    TRACE(graphics, "(%d %d %d %d)\n", 
+    	left, top, right, bottom);
+
     left   = XLPTODP( dc, left );
     top    = YLPTODP( dc, top );
     right  = XLPTODP( dc, right );
     bottom = YLPTODP( dc, bottom );
 
+    if ((left == right) || (top == bottom)) return TRUE;
+
     if (right < left) { INT32 tmp = right; right = left; left = tmp; }
     if (bottom < top) { INT32 tmp = bottom; bottom = top; top = tmp; }
 
-    if ((left == right) || (top == bottom))
-    {
-#if 0
-	if (DC_SetupGCForPen( dc ))
-	    TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, 
-		  dc->w.DCOrgX + left,
-		  dc->w.DCOrgY + top,
-		  dc->w.DCOrgX + right,
-		  dc->w.DCOrgY + bottom);
-#endif
-	return TRUE;
-    }
-    width = dc->u.x.pen.width;
+    oldwidth = width = dc->u.x.pen.width;
     if (!width) width = 1;
     if(dc->u.x.pen.style == PS_NULL) width = 0;
 
-    if ((dc->u.x.pen.style == PS_INSIDEFRAME) &&
-        (width < right-left) && (width < bottom-top))
+    if ((dc->u.x.pen.style == PS_INSIDEFRAME))
     {
+        if (2*width > (right-left)) width=(right-left + 1)/2;
+        if (2*width > (bottom-top)) width=(bottom-top + 1)/2;
         left   += width / 2;
-        right  -= (width + 1) / 2;
+        right  -= (width - 1) / 2;
         top    += width / 2;
-        bottom -= (width + 1) / 2;
+        bottom -= (width - 1) / 2;
     }
+    if(width == 1) width=0;
+    dc->u.x.pen.width=width;
 
     if ((right > left + width) && (bottom > top + width))
     {
@@ -274,6 +289,8 @@
 	TSXDrawRectangle( display, dc->u.x.drawable, dc->u.x.gc,
 		        dc->w.DCOrgX + left, dc->w.DCOrgY + top,
 		        right-left-1, bottom-top-1 );
+
+    dc->u.x.pen.width=oldwidth;
     return TRUE;
 }
 
@@ -284,6 +301,8 @@
 X11DRV_RoundRect( DC *dc, INT32 left, INT32 top, INT32 right,
                   INT32 bottom, INT32 ell_width, INT32 ell_height )
 {
+    INT32 width, oldwidth;
+
     TRACE(graphics, "(%d %d %d %d  %d %d\n", 
     	left, top, right, bottom, ell_width, ell_height);
 
@@ -291,6 +310,10 @@
     top    = YLPTODP( dc, top );
     right  = XLPTODP( dc, right );
     bottom = YLPTODP( dc, bottom );
+
+    if ((left == right) || (top == bottom))
+	return TRUE;
+
     ell_width  = abs( ell_width * dc->vportExtX / dc->wndExtX );
     ell_height = abs( ell_height * dc->vportExtY / dc->wndExtY );
 
@@ -298,25 +321,62 @@
 
     if (right < left) { INT32 tmp = right; right = left; left = tmp; }
     if (bottom < top) { INT32 tmp = bottom; bottom = top; top = tmp; }
-    if (ell_width > right - left) ell_width = right - left;
-    if (ell_height > bottom - top) ell_height = bottom - top;
+
+    oldwidth=width = dc->u.x.pen.width;
+    if (!width) width = 1;
+    if(dc->u.x.pen.style == PS_NULL) width = 0;
+
+    if ((dc->u.x.pen.style == PS_INSIDEFRAME))
+    {
+        if (2*width > (right-left)) width=(right-left + 1)/2;
+        if (2*width > (bottom-top)) width=(bottom-top + 1)/2;
+        left   += width / 2;
+        right  -= (width - 1) / 2;
+        top    += width / 2;
+        bottom -= (width - 1) / 2;
+    }
+    if(width == 1) width=0;
+    dc->u.x.pen.width=width;
 
     if (DC_SetupGCForBrush( dc ))
     {
-        if (ell_width && ell_height)
-        {
-            TSXFillArc( display, dc->u.x.drawable, dc->u.x.gc,
+        if (ell_width > (right-left) )
+            if (ell_height > (bottom-top) )
+                    TSXFillArc( display, dc->u.x.drawable, dc->u.x.gc,
+                              dc->w.DCOrgX + left, dc->w.DCOrgY + top,
+                              right - left - 1, bottom - top - 1,
+                              0, 360 * 64 );
+            else{
+                    TSXFillArc( display, dc->u.x.drawable, dc->u.x.gc,
+                              dc->w.DCOrgX + left, dc->w.DCOrgY + top,
+                              right - left - 1, ell_height, 0, 180 * 64 );
+                    TSXFillArc( display, dc->u.x.drawable, dc->u.x.gc,
+                              dc->w.DCOrgX + left,
+                              dc->w.DCOrgY + bottom - ell_height - 1,
+                              right - left - 1, ell_height, 180 * 64, 180 * 64 );
+           }
+	else if (ell_height > (bottom-top) ){
+                TSXFillArc( display, dc->u.x.drawable, dc->u.x.gc,
+                      dc->w.DCOrgX + left, dc->w.DCOrgY + top,
+                      ell_width, bottom - top - 1, 90 * 64, 180 * 64 );
+                TSXFillArc( display, dc->u.x.drawable, dc->u.x.gc,
+                      dc->w.DCOrgX + right - ell_width -1, dc->w.DCOrgY + top,
+                      ell_width, bottom - top - 1, 270 * 64, 180 * 64 );
+        }else{
+                TSXFillArc( display, dc->u.x.drawable, dc->u.x.gc,
                       dc->w.DCOrgX + left, dc->w.DCOrgY + top,
                       ell_width, ell_height, 90 * 64, 90 * 64 );
-            TSXFillArc( display, dc->u.x.drawable, dc->u.x.gc,
-                      dc->w.DCOrgX + left, dc->w.DCOrgY + bottom - ell_height,
+                TSXFillArc( display, dc->u.x.drawable, dc->u.x.gc,
+                      dc->w.DCOrgX + left,
+                      dc->w.DCOrgY + bottom - ell_height - 1,
                       ell_width, ell_height, 180 * 64, 90 * 64 );
-            TSXFillArc( display, dc->u.x.drawable, dc->u.x.gc,
-                      dc->w.DCOrgX + right - ell_width,
-                      dc->w.DCOrgY + bottom - ell_height,
+                TSXFillArc( display, dc->u.x.drawable, dc->u.x.gc,
+                      dc->w.DCOrgX + right - ell_width - 1,
+                      dc->w.DCOrgY + bottom - ell_height - 1,
                       ell_width, ell_height, 270 * 64, 90 * 64 );
-            TSXFillArc( display, dc->u.x.drawable, dc->u.x.gc,
-                      dc->w.DCOrgX + right - ell_width, dc->w.DCOrgY + top,
+                TSXFillArc( display, dc->u.x.drawable, dc->u.x.gc,
+                      dc->w.DCOrgX + right - ell_width - 1,
+                      dc->w.DCOrgY + top,
                       ell_width, ell_height, 0, 90 * 64 );
         }
         if (ell_width < right - left)
@@ -328,61 +388,83 @@
             TSXFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
                             dc->w.DCOrgX + left + ell_width / 2,
                             dc->w.DCOrgY + bottom - (ell_height+1) / 2,
-                            right - left - ell_width, (ell_height+1) / 2 );
+                            right - left - ell_width,
+                            (ell_height+1) / 2 - 1 );
         }
         if  (ell_height < bottom - top)
         {
             TSXFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
                             dc->w.DCOrgX + left,
                             dc->w.DCOrgY + top + ell_height / 2,
-                            right - left, bottom - top - ell_height );
+                            right - left - 1, bottom - top - ell_height );
         }
     }
-    if (DC_SetupGCForPen(dc))
-    {
-        if (ell_width && ell_height)
-        {
+    if (DC_SetupGCForPen(dc)) {
+        if (ell_width > (right-left) )
+            if (ell_height > (bottom-top) )
+                TSXDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
+		      dc->w.DCOrgX + left, dc->w.DCOrgY + top,
+		      right - left - 1, bottom -top - 1, 0 , 360 * 64 );
+            else{
+		TSXDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
+		      dc->w.DCOrgX + left, dc->w.DCOrgY + top,
+		      right - left - 1, ell_height - 1, 0 , 180 * 64 );
+		TSXDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
+		      dc->w.DCOrgX + left, 
+                      dc->w.DCOrgY + bottom - ell_height,
+		      right - left - 1, ell_height - 1, 180 * 64 , 180 * 64 );
+            }
+	else if (ell_height > (bottom-top) ){
+                TSXDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
+                      dc->w.DCOrgX + left, dc->w.DCOrgY + top,
+                      ell_width - 1 , bottom - top - 1, 90 * 64 , 180 * 64 );
+                TSXDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
+                      dc->w.DCOrgX + right - ell_width, 
+                      dc->w.DCOrgY + top,
+                      ell_width - 1 , bottom - top - 1, 270 * 64 , 180 * 64 );
+	}else{
             TSXDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
                       dc->w.DCOrgX + left, dc->w.DCOrgY + top,
-                      ell_width, ell_height, 90 * 64, 90 * 64 );
+                      ell_width - 1, ell_height - 1, 90 * 64, 90 * 64 );
             TSXDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
                       dc->w.DCOrgX + left, dc->w.DCOrgY + bottom - ell_height,
-                      ell_width, ell_height, 180 * 64, 90 * 64 );
+                      ell_width - 1, ell_height - 1, 180 * 64, 90 * 64 );
             TSXDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
                       dc->w.DCOrgX + right - ell_width,
                       dc->w.DCOrgY + bottom - ell_height,
-                      ell_width, ell_height, 270 * 64, 90 * 64 );
+                      ell_width - 1, ell_height - 1, 270 * 64, 90 * 64 );
             TSXDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
                       dc->w.DCOrgX + right - ell_width, dc->w.DCOrgY + top,
-                      ell_width, ell_height, 0, 90 * 64 );
+                      ell_width - 1, ell_height - 1, 0, 90 * 64 );
 	}
-        if (ell_width < right - left)
-        {
-            TSXDrawLine( display, dc->u.x.drawable, dc->u.x.gc, 
-                       dc->w.DCOrgX + left + ell_width / 2,
-                       dc->w.DCOrgY + top,
-                       dc->w.DCOrgX + right - ell_width / 2,
-                       dc->w.DCOrgY + top );
-            TSXDrawLine( display, dc->u.x.drawable, dc->u.x.gc, 
-                       dc->w.DCOrgX + left + ell_width / 2,
-                       dc->w.DCOrgY + bottom,
-                       dc->w.DCOrgX + right - ell_width / 2,
-                       dc->w.DCOrgY + bottom );
-        }
-        if (ell_height < bottom - top)
-        {
-            TSXDrawLine( display, dc->u.x.drawable, dc->u.x.gc, 
-                       dc->w.DCOrgX + right,
-                       dc->w.DCOrgY + top + ell_height / 2,
-                       dc->w.DCOrgX + right,
-                       dc->w.DCOrgY + bottom - ell_height / 2 );
-            TSXDrawLine( display, dc->u.x.drawable, dc->u.x.gc, 
-                       dc->w.DCOrgX + left,
-                       dc->w.DCOrgY + top + ell_height / 2,
-                       dc->w.DCOrgX + left,
-                       dc->w.DCOrgY + bottom - ell_height / 2 );
-        }
+	if (ell_width < right - left)
+	{
+	    TSXDrawLine( display, dc->u.x.drawable, dc->u.x.gc, 
+		       dc->w.DCOrgX + left + ell_width / 2 - 2,
+		       dc->w.DCOrgY + top,
+		       dc->w.DCOrgX + right - ell_width / 2,
+		       dc->w.DCOrgY + top);
+	    TSXDrawLine( display, dc->u.x.drawable, dc->u.x.gc, 
+		       dc->w.DCOrgX + left + ell_width / 2 - 2,
+		       dc->w.DCOrgY + bottom - 1,
+		       dc->w.DCOrgX + right - ell_width / 2,
+		       dc->w.DCOrgY + bottom - 1);
+	}
+	if (ell_height < bottom - top)
+	{
+	    TSXDrawLine( display, dc->u.x.drawable, dc->u.x.gc, 
+		       dc->w.DCOrgX + right - 1,
+		       dc->w.DCOrgY + top + ell_height / 2 - 1,
+		       dc->w.DCOrgX + right - 1,
+		       dc->w.DCOrgY + bottom - ell_height / 2);
+	    TSXDrawLine( display, dc->u.x.drawable, dc->u.x.gc, 
+		       dc->w.DCOrgX + left,
+		       dc->w.DCOrgY + top + ell_height / 2 - 1,
+		       dc->w.DCOrgX + left,
+		       dc->w.DCOrgY + bottom - ell_height / 2);
+	}
     }
+    dc->u.x.pen.width=oldwidth;
     return TRUE;
 }
 
diff --git a/if1632/builtin.c b/if1632/builtin.c
index ba9db19..7f40e21 100644
--- a/if1632/builtin.c
+++ b/if1632/builtin.c
@@ -89,7 +89,7 @@
     { &GDI_Descriptor,      DLL_FLAG_ALWAYS_USED },
     { &SYSTEM_Descriptor,   DLL_FLAG_ALWAYS_USED },
     { &WPROCS_Descriptor,   DLL_FLAG_ALWAYS_USED },
-    { &WINDEBUG_Descriptor, DLL_FLAG_ALWAYS_USED },
+    { &WINDEBUG_Descriptor, DLL_FLAG_NOT_USED },
     { &COMMDLG_Descriptor,  DLL_FLAG_NOT_USED },
     { &COMPOBJ_Descriptor,  DLL_FLAG_NOT_USED },
     { &DDEML_Descriptor,    DLL_FLAG_NOT_USED },
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index 34cef32..34322b4 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -139,7 +139,7 @@
 151 pascal16 CopyMetaFile(word str) CopyMetaFile16
 153 pascal16 CreateIC(str str str ptr) CreateIC16
 154 pascal   GetNearestColor(word long) GetNearestColor16
-155 stub QueryAbort
+155 pascal16 QueryAbort(word word) QueryAbort
 156 pascal16 CreateDiscardableBitmap(word word word) CreateDiscardableBitmap16
 158 pascal16 EnumCallback(ptr ptr word long) WineEnumDFontCallback
 159 pascal16 GetMetaFileBits(word) GetMetaFileBits
@@ -207,7 +207,7 @@
 272 stub EndDocPrinter
 274 stub ClosePrinter
 280 stub GetRealDriverInfo
-281 pascal DrvSetPrinterData(ptr ptr ptr ptr long) DrvSetPrinterData
+281 pascal DrvSetPrinterData(ptr ptr long ptr long) DrvSetPrinterData
 282 pascal DrvGetPrinterData(ptr ptr ptr ptr long ptr) DrvGetPrinterData
 299 stub ENGINEGETCHARWIDTHEX
 300 pascal EngineEnumerateFont(ptr segptr long) EngineEnumerateFont
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index 38bd366..88f9cf0 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -149,7 +149,7 @@
 146 pascal16 DeleteFile(ptr) DeleteFile16
 147 pascal16 SetLastError(long) SetLastError
 148 pascal   GetLastError() GetLastError
-149 stub GetVersionEx
+149 pascal16 GetVersionEx(ptr) GetVersionEx16
 150 pascal16 DirectedYield(word) DirectedYield
 151 stub WinOldApCall
 152 pascal16 GetNumTasks() GetNumTasks
diff --git a/if1632/mmsystem.spec b/if1632/mmsystem.spec
index cd9889a..5bd0b24 100644
--- a/if1632/mmsystem.spec
+++ b/if1632/mmsystem.spec
@@ -139,7 +139,7 @@
 1100   pascal  DRVOPEN(str str long) DrvOpen
 1101   pascal  DRVCLOSE(word long long) DrvClose
 1102   pascal  DRVSENDMESSAGE(word word long long) DrvSendMessage
-1103   pascal  DRVGETMODULEHANDLE(word) DrvGetModuleHandle
+1103   pascal  drvGetModuleHandle(word) DrvGetModuleHandle16
 1104   pascal  DRVDEFDRIVERPROC(long word word long long) DrvDefDriverProc
 1120   pascal  mmThreadCreate(ptr ptr long long) mmThreadCreate16
 1121   pascal  mmThreadSignal(word) mmThreadSignal16
@@ -148,23 +148,25 @@
 1124   stub    MMTHREADISVALID
 1125   pascal  mmThreadGetTask(word) mmThreadGetTask16
 1150   stub    MMSHOWMMCPLPROPERTYSHEET
+
 1210   pascal  mmioOpen(str ptr long) mmioOpen16
-1211   pascal  MMIOCLOSE(word word) mmioClose
-1212   pascal  MMIOREAD(word ptr long) mmioRead
-1213   pascal  MMIOWRITE(word ptr long) mmioWrite
-1214   pascal  MMIOSEEK(word long word) mmioSeek
-1215   pascal  MMIOGETINFO(word ptr word) mmioGetInfo
+1211   pascal  mmioClose(word word) mmioClose16
+1212   pascal  mmioRead(word ptr long) mmioRead16
+1213   pascal  mmioWrite(word ptr long) mmioWrite16
+1214   pascal  mmioSeek(word long word) mmioSeek16
+1215   pascal  mmioGetInfo(word ptr word) mmioGetInfo16
 1216   pascal  MMIOSETINFO(word ptr word) mmioSetInfo
 1217   pascal  MMIOSETBUFFER(word ptr long word) mmioSetBuffer
-1218   pascal  MMIOFLUSH(word word) mmioFlush
-1219   pascal  MMIOADVANCE(word ptr word) mmioAdvance
+1218   pascal  mmioFlush(word word) mmioFlush16
+1219   pascal  mmioAdvance(word ptr word) mmioAdvance16
 1220   pascal  mmioStringToFOURCC(str word) mmioStringToFOURCC16
 1221   pascal  MMIOINSTALLIOPROC(long ptr long) mmioInstallIOProc16
 1222   pascal  MMIOSENDMESSAGE(word word long long) mmioSendMessage
 1223   pascal  MMIODESCEND(word ptr ptr word) mmioDescend
-1224   pascal  MMIOASCEND(word ptr word) mmioAscend
+1224   pascal  mmioAscend(word ptr word) mmioAscend16
 1225   pascal  MMIOCREATECHUNK(word ptr word) mmioCreateChunk
 1226   pascal  MMIORENAME(ptr ptr ptr long) mmioRename
+
 #2000   stub    WINMMF_THUNKDATA16
 #2001   stub    RING3_DEVLOADER
 #2002   stub    WINMMTILEBUFFER
diff --git a/if1632/relay.c b/if1632/relay.c
index 3135d9c..c6f02f4 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -253,7 +253,10 @@
         DPRINTF("CallTo16(func=%04lx:%04x,ds=%04lx",
                 CS_reg(context), IP_reg(context), DS_reg(context) );
         nb_args = stack[1] / sizeof(WORD);
-        while (nb_args--) printf( ",0x%04x", *(--stack16) );
+        while (nb_args--) {
+	    --stack16;
+	    DPRINTF( ",0x%04x", *stack16 );
+	}
         DPRINTF(") ss:sp=%04x:%04x\n", SELECTOROF(thdb->cur_stack),
                 OFFSETOF(thdb->cur_stack) );
         DPRINTF("     AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x BP=%04x ES=%04x\n",
@@ -267,7 +270,10 @@
                 HIWORD(stack[0]), LOWORD(stack[0]),
                 SELECTOROF(thdb->cur_stack) );
         stack++;
-        while (nb_args--) DPRINTF(",0x%04x", *stack++ );
+        while (nb_args--) {
+	    DPRINTF(",0x%04x", *stack );
+	    stack++;
+	}
         DPRINTF(") ss:sp=%04x:%04x\n", SELECTOROF(thdb->cur_stack),
                 OFFSETOF(thdb->cur_stack) );
     }
diff --git a/if1632/user.spec b/if1632/user.spec
index 570aa21..83e7603 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -255,10 +255,10 @@
 248 pascal16 GetOpenClipboardWindow() GetOpenClipboardWindow16
 249 pascal16 GetAsyncKeyState(word) GetAsyncKeyState16
 250 pascal16 GetMenuState(word word word) GetMenuState16
-251 pascal   SendDriverMessage(word word long long) SendDriverMessage
-252 pascal16 OpenDriver(str str long) OpenDriver
-253 pascal   CloseDriver(word long long) CloseDriver
-254 pascal16 GetDriverModuleHandle(word) GetDriverModuleHandle
+251 pascal   SendDriverMessage(word word long long) SendDriverMessage16
+252 pascal16 OpenDriver(str str long) OpenDriver16
+253 pascal   CloseDriver(word long long) CloseDriver16
+254 pascal16 GetDriverModuleHandle(word) GetDriverModuleHandle16
 255 pascal   DefDriverProc(long word word long long) DefDriverProc
 256 pascal16 GetDriverInfo(word ptr) GetDriverInfo
 257 pascal16 GetNextDriver(word long) GetNextDriver
@@ -477,7 +477,7 @@
 529 pascal16 WNetPropertyDialog(word word ptr word) WNetPropertyDialog
 530 pascal16 WNetGetDirectoryType(ptr ptr) WNetGetDirectoryType16
 531 pascal16 WNetDirectoryNotify(word ptr word) WNetDirectoryNotify
-532 pascal16 WNetGetPropertyText(word word word ptr word) WNetGetPropertyText
+532 pascal16 WNetGetPropertyText(word word str str word word) WNetGetPropertyText
 533 stub WNetInitialize
 534 stub WNetLogon
 600 pascal16 GetShellWindow() GetShellWindow16
diff --git a/if1632/wprocs.spec b/if1632/wprocs.spec
index db7aa66..7993aea 100644
--- a/if1632/wprocs.spec
+++ b/if1632/wprocs.spec
@@ -13,6 +13,7 @@
 28 pascal MyAlloc(word word word) NE_AllocateSegment
 29 pascal DefResourceHandler(word word word) NE_DefResourceHandler
 30 pascal FormatCharDlgProc(word word word long) FormatCharDlgProc16
+31 pascal16 ASPI_DOS_func(long) ASPI_DOS_func
  
 # Interrupt vectors 0-255 are ordinals 100-355
 # The 'word' parameter are the flags pushed on the stack by the interrupt
diff --git a/include/acconfig.h b/include/acconfig.h
index 20faa2f..1fad5da 100644
--- a/include/acconfig.h
+++ b/include/acconfig.h
@@ -21,6 +21,12 @@
 /* Define if X libraries are not reentrant (compiled without -D_REENTRANT).  */
 #undef NO_REENTRANT_X11
 
+/* Define if all debug messages are to be compiled out */
+#undef NO_DEBUG_MSGS
+
+/* Define if TRACE messages are to be compiled out */
+#undef NO_TRACE_MSGS
+
 /* Define if the struct statfs has the member bavail */
 #undef STATFS_HAS_BAVAIL
 
diff --git a/include/commctrl.h b/include/commctrl.h
index c57c992..ba94bfa 100644
--- a/include/commctrl.h
+++ b/include/commctrl.h
@@ -7,6 +7,9 @@
 
 #include "windows.h"
 
+VOID WINAPI GetEffectiveClientRect (HWND32, LPRECT32, LPINT32);
+
+
 void WINAPI InitCommonControls(void);
 
 typedef struct tagINITCOMMONCONTROLSEX {
@@ -76,11 +79,17 @@
 #define NM_TOOLTIPSCREATED   (NM_FIRST-19)
 
 
+/* callback constants */
+#define LPSTR_TEXTCALLBACK32A    ((LPSTR)-1L)
+#define LPSTR_TEXTCALLBACK32W    ((LPWSTR)-1L)
+#define LPSTR_TEXTCALLBACK WINELIB_NAME_AW(LPSTR_TEXTCALLBACK)
+
+
 /* StatusWindow */
 
 #define STATUSCLASSNAME16     "msctls_statusbar"
 #define STATUSCLASSNAME32A    "msctls_statusbar32"
-#define STATUSCLASSNAME32W   L"msctls_statusbar32"       /*FIXME*/
+#define STATUSCLASSNAME32W   L"msctls_statusbar32"
 #define STATUSCLASSNAME WINELIB_NAME_AW(STATUSCLASSNAME)
 
 #define SB_SETTEXT32A         (WM_USER+1)
@@ -497,47 +506,46 @@
 
 /* Toolbar */
 
-#define TOOLBARCLASSNAME16        "ToolbarWindow" 
-#define TOOLBARCLASSNAME32W       L"ToolbarWindow32" 
-#define TOOLBARCLASSNAME32A       "ToolbarWindow32" 
+#define TOOLBARCLASSNAME16        "ToolbarWindow"
+#define TOOLBARCLASSNAME32W       L"ToolbarWindow32"
+#define TOOLBARCLASSNAME32A       "ToolbarWindow32"
 #define TOOLBARCLASSNAME WINELIB_NAME_AW(TOOLBARCLASSNAME)
 
- 
-#define CMB_MASKED              0x02 
- 
-#define TBSTATE_CHECKED         0x01 
-#define TBSTATE_PRESSED         0x02 
-#define TBSTATE_ENABLED         0x04 
-#define TBSTATE_HIDDEN          0x08 
-#define TBSTATE_INDETERMINATE   0x10 
-#define TBSTATE_WRAP            0x20 
+
+#define CMB_MASKED              0x02
+
+#define TBSTATE_CHECKED         0x01
+#define TBSTATE_PRESSED         0x02
+#define TBSTATE_ENABLED         0x04
+#define TBSTATE_HIDDEN          0x08
+#define TBSTATE_INDETERMINATE   0x10
+#define TBSTATE_WRAP            0x20
 #define TBSTATE_ELLIPSES        0x40
-#define TBSTATE_MARKED          0x80 
+#define TBSTATE_MARKED          0x80
+
+#define TBSTYLE_BUTTON          0x00
+#define TBSTYLE_SEP             0x01
+#define TBSTYLE_CHECK           0x02
+#define TBSTYLE_GROUP           0x04
+#define TBSTYLE_CHECKGROUP      (TBSTYLE_GROUP | TBSTYLE_CHECK)
+#define TBSTYLE_DROPDOWN        0x08
  
- 
-#define TBSTYLE_BUTTON          0x00 
-#define TBSTYLE_SEP             0x01 
-#define TBSTYLE_CHECK           0x02 
-#define TBSTYLE_GROUP           0x04 
-#define TBSTYLE_CHECKGROUP      (TBSTYLE_GROUP | TBSTYLE_CHECK) 
-#define TBSTYLE_DROPDOWN        0x08 
- 
-#define TBSTYLE_TOOLTIPS        0x0100 
-#define TBSTYLE_WRAPABLE        0x0200 
-#define TBSTYLE_ALTDRAG         0x0400 
-#define TBSTYLE_FLAT            0x0800 
-#define TBSTYLE_LIST            0x1000 
-#define TBSTYLE_CUSTOMERASE     0x2000 
- 
+#define TBSTYLE_TOOLTIPS        0x0100
+#define TBSTYLE_WRAPABLE        0x0200
+#define TBSTYLE_ALTDRAG         0x0400
+#define TBSTYLE_FLAT            0x0800
+#define TBSTYLE_LIST            0x1000
+#define TBSTYLE_CUSTOMERASE     0x2000
+
 #define TB_ENABLEBUTTON          (WM_USER+1)
 #define TB_CHECKBUTTON           (WM_USER+2)
 #define TB_PRESSBUTTON           (WM_USER+3)
 #define TB_HIDEBUTTON            (WM_USER+4)
 #define TB_INDETERMINATE         (WM_USER+5)
-#define TB_ISBUTTONENABLED       (WM_USER+9) 
-#define TB_ISBUTTONCHECKED       (WM_USER+10) 
-#define TB_ISBUTTONPRESSED       (WM_USER+11) 
-#define TB_ISBUTTONHIDDEN        (WM_USER+12) 
+#define TB_ISBUTTONENABLED       (WM_USER+9)
+#define TB_ISBUTTONCHECKED       (WM_USER+10)
+#define TB_ISBUTTONPRESSED       (WM_USER+11)
+#define TB_ISBUTTONHIDDEN        (WM_USER+12)
 #define TB_ISBUTTONINDETERMINATE (WM_USER+13)
 #define TB_ISBUTTONHIGHLIGHTED   (WM_USER+14)
 #define TB_SETSTATE              (WM_USER+17)
@@ -558,8 +566,8 @@
 #define TB_SAVERESTORE32W        (WM_USER+76)
 #define TB_SAVERESTORE WINELIB_NAME_AW(TB_SAVERESTORE)
 #define TB_CUSTOMIZE             (WM_USER+27)
-#define TB_ADDSTRING32A          (WM_USER+28) 
-#define TB_ADDSTRING32W          (WM_USER+77) 
+#define TB_ADDSTRING32A          (WM_USER+28)
+#define TB_ADDSTRING32W          (WM_USER+77)
 #define TB_ADDSTRING WINELIB_NAME_AW(TB_ADDSTRING)
 #define TB_GETITEMRECT           (WM_USER+29)
 #define TB_BUTTONSTRUCTSIZE      (WM_USER+30)
@@ -571,6 +579,7 @@
 #define TB_SETPARENT             (WM_USER+37)
 #define TB_SETROWS               (WM_USER+39)
 #define TB_GETROWS               (WM_USER+40)
+#define TB_GETBITMAPFLAGS        (WM_USER+41)
 #define TB_SETCMDID              (WM_USER+42)
 #define TB_CHANGEBITMAP          (WM_USER+43)
 #define TB_GETBITMAP             (WM_USER+44)
@@ -594,6 +603,10 @@
 #define TB_SETMAXTEXTROWS        (WM_USER+60)
 #define TB_GETTEXTROWS           (WM_USER+61)
 
+#define TB_MAPACCELERATOR32A     (WM_USER+78)
+#define TB_MAPACCELERATOR32W     (WM_USER+90)
+#define TB_MAPACCELERATOR WINELIB_NAME_AW(TB_MAPACCELERATOR)
+
 
 /* This is just for old CreateToolbar. */
 /* Don't use it in new programs. */
@@ -633,18 +646,12 @@
 #define HINST_COMMCTRL         ((HINSTANCE32)-1)
 
 
-HWND32 WINAPI
-CreateToolbar(HWND32, DWORD, UINT32, INT32, HINSTANCE32,
-              UINT32, LPCOLDTBBUTTON, INT32); 
- 
-HWND32 WINAPI
-CreateToolbarEx(HWND32, DWORD, UINT32, INT32,
-                HINSTANCE32, UINT32, LPCTBBUTTON, 
-                INT32, INT32, INT32, INT32, INT32, UINT32); 
-
-HBITMAP32 WINAPI
-CreateMappedBitmap (HINSTANCE32, INT32, UINT32, LPCOLORMAP, INT32); 
-
-
+HWND32 WINAPI CreateToolbar(HWND32, DWORD, UINT32, INT32, HINSTANCE32,
+                            UINT32, LPCOLDTBBUTTON, INT32);
+HWND32 WINAPI CreateToolbarEx(HWND32, DWORD, UINT32, INT32, HINSTANCE32,
+                              UINT32, LPCTBBUTTON, INT32, INT32, INT32,
+                              INT32, INT32, UINT32);
+HBITMAP32 WINAPI CreateMappedBitmap (HINSTANCE32, INT32, UINT32,
+                                     LPCOLORMAP, INT32);
 
 #endif  /* __WINE_COMMCTRL_H */
diff --git a/include/commdlg.h b/include/commdlg.h
index a54499d..1bf5d2f 100644
--- a/include/commdlg.h
+++ b/include/commdlg.h
@@ -485,6 +485,76 @@
 #define CDERR_NOHOOK           0x000B
 #define CDERR_REGISTERMSGFAIL  0x000C
 
+/* PageSetupDlg stuff ... */
+#define WM_PSD_PAGESETUPDLG	(WM_USER  )
+#define WM_PSD_FULLPAGERECT	(WM_USER+1)
+#define WM_PSD_MINMARGINRECT	(WM_USER+2)
+#define WM_PSD_MARGINRECT	(WM_USER+3)
+#define WM_PSD_GREEKTEXTRECT	(WM_USER+4)
+#define WM_PSD_ENVSTAMPRECT	(WM_USER+5)
+#define WM_PSD_YAFULLPAGERECT	(WM_USER+6)
+
+typedef UINT32 (CALLBACK* LPPAGEPAINTHOOK)( HWND32, UINT32, WPARAM32, LPARAM );
+typedef UINT32 (CALLBACK* LPPAGESETUPHOOK)( HWND32, UINT32, WPARAM32, LPARAM );
+
+typedef struct tagPSD32A
+{
+	DWORD		lStructSize;
+	HWND32		hwndOwner;
+	HGLOBAL32	hDevMode;
+	HGLOBAL32	hDevNames;
+	DWORD		Flags;
+	POINT32		ptPaperSize;
+	RECT32		rtMinMargin;
+	RECT32		rtMargin;
+	HINSTANCE32	hInstance;
+	LPARAM		lCustData;
+	LPPAGESETUPHOOK	lpfnPageSetupHook;
+	LPPAGEPAINTHOOK	lpfnPagePaintHook;
+	LPCSTR		lpPageSetupTemplateName;
+	HGLOBAL32	hPageSetupTemplate;
+} PAGESETUPDLG32A,*LPPAGESETUPDLG32A;
+
+typedef struct tagPSD32W
+{
+	DWORD		lStructSize;
+	HWND32		hwndOwner;
+	HGLOBAL32	hDevMode;
+	HGLOBAL32	hDevNames;
+	DWORD		Flags;
+	POINT32		ptPaperSize;
+	RECT32		rtMinMargin;
+	RECT32		rtMargin;
+	HINSTANCE32	hInstance;
+	LPARAM		lCustData;
+	LPPAGESETUPHOOK	lpfnPageSetupHook;
+	LPPAGEPAINTHOOK	lpfnPagePaintHook;
+	LPCWSTR		lpPageSetupTemplateName;
+	HGLOBAL32	hPageSetupTemplate;
+} PAGESETUPDLG32W,*LPPAGESETUPDLG32W;
+DECL_WINELIB_TYPE_AW(PAGESETUPDLG)
+DECL_WINELIB_TYPE_AW(LPPAGESETUPDLG)
+
+#define PSD_DEFAULTMINMARGINS             0x00000000
+#define PSD_INWININIINTLMEASURE           0x00000000
+
+#define PSD_MINMARGINS                    0x00000001
+#define PSD_MARGINS                       0x00000002
+#define PSD_INTHOUSANDTHSOFINCHES         0x00000004
+#define PSD_INHUNDREDTHSOFMILLIMETERS     0x00000008
+#define PSD_DISABLEMARGINS                0x00000010
+#define PSD_DISABLEPRINTER                0x00000020
+#define PSD_NOWARNING                     0x00000080
+#define PSD_DISABLEORIENTATION            0x00000100
+#define PSD_RETURNDEFAULT                 0x00000400
+#define PSD_DISABLEPAPER                  0x00000200
+#define PSD_SHOWHELP                      0x00000800
+#define PSD_ENABLEPAGESETUPHOOK           0x00002000
+#define PSD_ENABLEPAGESETUPTEMPLATE       0x00008000
+#define PSD_ENABLEPAGESETUPTEMPLATEHANDLE 0x00020000
+#define PSD_ENABLEPAGEPAINTHOOK           0x00040000
+#define PSD_DISABLEPAGEPAINTING           0x00080000
+
 BOOL16  WINAPI ChooseColor16(LPCHOOSECOLOR16 lpChCol);
 BOOL32  WINAPI ChooseColor32A(LPCHOOSECOLOR32A lpChCol);
 BOOL32  WINAPI ChooseColor32W(LPCHOOSECOLOR32W lpChCol);
@@ -506,6 +576,9 @@
 BOOL32  WINAPI GetSaveFileName32A(LPOPENFILENAME32A ofn);
 BOOL32  WINAPI GetSaveFileName32W(LPOPENFILENAME32W ofn);
 #define GetSaveFileName WINELIB_NAME_AW(GetSaveFileName)
+BOOL32 WINAPI PageSetupDlg32A( LPPAGESETUPDLG32A );
+BOOL32 WINAPI PageSetupDlg32W( LPPAGESETUPDLG32W );
+#define PageSetupDlg WINELIB_NAME_AW(PageSetupDlg)
 BOOL16  WINAPI PrintDlg( SEGPTR print);
 HWND16  WINAPI ReplaceText16( SEGPTR find);
 HWND32  WINAPI ReplaceText32A( LPFINDREPLACE32A lpFind);
diff --git a/include/config.h.in b/include/config.h.in
index 6a7a4c1..e57a78e 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -33,6 +33,12 @@
 /* Define if X libraries are not reentrant (compiled without -D_REENTRANT).  */
 #undef NO_REENTRANT_X11
 
+/* Define if all debug messages are to be compiled out */
+#undef NO_DEBUG_MSGS
+
+/* Define if TRACE messages are to be compiled out */
+#undef NO_TRACE_MSGS
+
 /* Define if the struct statfs has the member bavail */
 #undef STATFS_HAS_BAVAIL
 
@@ -96,12 +102,18 @@
 /* Define if you have the <machine/soundcard.h> header file.  */
 #undef HAVE_MACHINE_SOUNDCARD_H
 
+/* Define if you have the <strings.h> header file.  */
+#undef HAVE_STRINGS_H
+
 /* Define if you have the <sys/cdio.h> header file.  */
 #undef HAVE_SYS_CDIO_H
 
 /* Define if you have the <sys/filio.h> header file.  */
 #undef HAVE_SYS_FILIO_H
 
+/* Define if you have the <sys/modem.h> header file.  */
+#undef HAVE_SYS_MODEM_H
+
 /* Define if you have the <sys/mount.h> header file.  */
 #undef HAVE_SYS_MOUNT_H
 
@@ -114,6 +126,9 @@
 /* Define if you have the <sys/statfs.h> header file.  */
 #undef HAVE_SYS_STATFS_H
 
+/* Define if you have the <sys/strtio.h> header file.  */
+#undef HAVE_SYS_STRTIO_H
+
 /* Define if you have the <sys/syscall.h> header file.  */
 #undef HAVE_SYS_SYSCALL_H
 
diff --git a/include/debug.h b/include/debug.h
index 3d1702a..ff4b508 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -94,33 +94,34 @@
 #define dbch_sendmsg 86
 #define dbch_shell 87
 #define dbch_shm 88
-#define dbch_sound 89
-#define dbch_static 90
-#define dbch_stress 91
-#define dbch_string 92
-#define dbch_syscolor 93
-#define dbch_system 94
-#define dbch_task 95
-#define dbch_text 96
-#define dbch_thread 97
-#define dbch_thunk 98
-#define dbch_timer 99
-#define dbch_toolbar 100
-#define dbch_toolhelp 101
-#define dbch_tweak 102
-#define dbch_uitools 103
-#define dbch_updown 104
-#define dbch_ver 105
-#define dbch_virtual 106
-#define dbch_vxd 107
-#define dbch_win 108
-#define dbch_win16drv 109
-#define dbch_win32 110
-#define dbch_wing 111
-#define dbch_winsock 112
-#define dbch_wnet 113
-#define dbch_x11 114
-#define dbch_x11drv 115
+#define dbch_snoop 89
+#define dbch_sound 90
+#define dbch_static 91
+#define dbch_stress 92
+#define dbch_string 93
+#define dbch_syscolor 94
+#define dbch_system 95
+#define dbch_task 96
+#define dbch_text 97
+#define dbch_thread 98
+#define dbch_thunk 99
+#define dbch_timer 100
+#define dbch_toolbar 101
+#define dbch_toolhelp 102
+#define dbch_tweak 103
+#define dbch_uitools 104
+#define dbch_updown 105
+#define dbch_ver 106
+#define dbch_virtual 107
+#define dbch_vxd 108
+#define dbch_win 109
+#define dbch_win16drv 110
+#define dbch_win32 111
+#define dbch_wing 112
+#define dbch_winsock 113
+#define dbch_wnet 114
+#define dbch_x11 115
+#define dbch_x11drv 116
 /* Definitions for classes identifiers */
 #define dbcl_fixme 0
 #define dbcl_err 1
diff --git a/include/debugdefs.h b/include/debugdefs.h
index 96704c8..6aae49f 100644
--- a/include/debugdefs.h
+++ b/include/debugdefs.h
@@ -4,7 +4,7 @@
 #include "debugtools.h"
 #endif
 
-#define DEBUG_CHANNEL_COUNT 116
+#define DEBUG_CHANNEL_COUNT 117
 #ifdef DEBUG_RUNTIME
 short debug_msg_enabled[][DEBUG_CLASS_COUNT] = {
 {1, 1, 0, 0},
@@ -123,6 +123,7 @@
 {1, 1, 0, 0},
 {1, 1, 0, 0},
 {1, 1, 0, 0},
+{1, 1, 0, 0},
 };
 const char* debug_ch_name[] = {
 "accel",
@@ -214,6 +215,7 @@
 "sendmsg",
 "shell",
 "shm",
+"snoop",
 "sound",
 "static",
 "stress",
diff --git a/include/debugtools.h b/include/debugtools.h
index b6b50d8..40fcb1e 100644
--- a/include/debugtools.h
+++ b/include/debugtools.h
@@ -5,6 +5,7 @@
 #ifdef __WINE__  /* Debugging interface is internal to Wine */
 
 #include <stdio.h>
+#include "config.h"
 #include "debugstr.h"
 
 #define DEBUG_RUNTIME
@@ -39,18 +40,44 @@
   if(!DEBUGGING(cl, ch)) ; \
   else DPRINTF(# cl ":" # ch ":%s " format, __FUNCTION__ , ## args)
 
+/* use configure to allow user to compile out debugging messages */
+
+#ifndef NO_TRACE_MSGS
 #define TRACE(ch, fmt, args...) DPRINTF_(trace, ch, fmt, ## args)
+#else
+#define TRACE(ch, fmt, args...)
+#endif /* NO_TRACE_MSGS */
+
+#ifndef NO_DEBUG_MSGS
 #define WARN(ch, fmt, args...)  DPRINTF_(warn,  ch, fmt, ## args)
 #define FIXME(ch, fmt, args...) DPRINTF_(fixme, ch, fmt, ## args)
-#define ERR(ch, fmt, args...)   DPRINTF_(err, ch, fmt, ## args)
-
 #define DUMP(format, args...)   DPRINTF(format, ## args)
+#else
+#define WARN(ch, fmt, args...)
+#define FIXME(ch, fmt, args...)
+#define DUMP(format, args...)
+#endif /* NO_DEBUG_MSGS */
+
+/* define error macro regardless of what is configured */
+#define ERR(ch, fmt, args...)   DPRINTF_(err, ch, fmt, ## args)
 #define MSG(format, args...)    fprintf(stderr, format, ## args)
 
-#define FIXME_ON(ch)  DEBUGGING(fixme, ch)
-#define ERR_ON(ch)    DEBUGGING(err, ch)
-#define WARN_ON(ch)   DEBUGGING(warn, ch)
+/* if the debug message is compiled out, make these return false */
+#ifndef NO_TRACE_MSGS
 #define TRACE_ON(ch)  DEBUGGING(trace, ch)
+#else
+#define TRACE_ON(ch) 0
+#endif /* NO_TRACE_MSGS */
+
+#ifndef NO_DEBUG_MSGS
+#define WARN_ON(ch)   DEBUGGING(warn, ch)
+#define FIXME_ON(ch)  DEBUGGING(fixme, ch)
+#else
+#define WARN_ON(ch) 0
+#define FIXME_ON(ch) 0
+#endif /* NO_DEBUG_MSGS */
+
+#define ERR_ON(ch)    DEBUGGING(err, ch)
 
 #endif  /* __WINE__ */
 
diff --git a/include/device.h b/include/device.h
new file mode 100644
index 0000000..b7a88fb
--- /dev/null
+++ b/include/device.h
@@ -0,0 +1,4 @@
+#ifndef __WINE_DEVICE_H
+#define __WINE_DEVICE_H
+extern HANDLE32 DEVICE_Open( LPCSTR name, DWORD flags);
+#endif
diff --git a/include/driver.h b/include/driver.h
index 54fed12..f40c29c 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -34,12 +34,16 @@
 #define GND_FORWARD  			0x00000000
 #define GND_REVERSE    			0x00000002
 
+/* FIXME: unused? */
 typedef struct {
 	DWORD   dwDCISize;
 	LPCSTR  lpszDCISectionName;
 	LPCSTR  lpszDCIAliasName;
-} DRVCONFIGINFO, *LPDRVCONFIGINFO;
+} xDRVCONFIGINFO, *xLPDRVCONFIGINFO;
 
+/* GetDriverInfo16 references this structure, so this a struct defined
+ * in the Win16 API.
+ */
 typedef struct
 {
     UINT16       length;
@@ -48,6 +52,7 @@
     CHAR         szAliasName[128];
 } DRIVERINFOSTRUCT16, *LPDRIVERINFOSTRUCT16;
 
+/* FIXME: Is this a WINE internal struct? */
 typedef struct tagDRIVERITEM
 {
     DRIVERINFOSTRUCT16    dis;
@@ -57,14 +62,45 @@
     DRIVERPROC16          lpDrvProc;
 } DRIVERITEM, *LPDRIVERITEM;
 
+/* internal */
+typedef struct
+{
+    UINT32	length;
+    HDRVR32	hDriver;
+    HMODULE32	hModule;
+    CHAR	szAliasName[128];
+} DRIVERINFOSTRUCT32A, *LPDRIVERINFOSTRUCT32A;
+
+/* internal */
+typedef struct tagDRIVERITEM32A {
+	DRIVERINFOSTRUCT32A	dis;
+	DWORD			count;
+	struct tagDRIVERITEM32A	*next;
+	DRIVERPROC32		driverproc;
+} DRIVERITEM32A,*LPDRIVERITEM32A;
+
 LRESULT WINAPI DefDriverProc(DWORD dwDevID, HDRVR16 hDriv, UINT16 wMsg, 
                              LPARAM dwParam1, LPARAM dwParam2);
-HDRVR16 WINAPI OpenDriver(LPSTR szDriverName, LPSTR szSectionName,
-                          LPARAM lParam2);
-LRESULT WINAPI CloseDriver(HDRVR16 hDriver, LPARAM lParam1, LPARAM lParam2);
-LRESULT WINAPI SendDriverMessage( HDRVR16 hDriver, UINT16 message,
-                                  LPARAM lParam1, LPARAM lParam2 );
-HMODULE16 WINAPI GetDriverModuleHandle(HDRVR16 hDriver);
+HDRVR16 WINAPI OpenDriver16(LPCSTR szDriverName, LPCSTR szSectionName,
+                            LPARAM lParam2);
+HDRVR32 WINAPI OpenDriver32A(LPCSTR szDriverName, LPCSTR szSectionName,
+                             LPARAM lParam2);
+HDRVR32 WINAPI OpenDriver32W(LPCWSTR szDriverName, LPCWSTR szSectionName,
+                             LPARAM lParam2);
+#define OpenDriver WINELIB_NAME_AW(OpenDriver)
+LRESULT WINAPI CloseDriver16(HDRVR16 hDriver, LPARAM lParam1, LPARAM lParam2);
+LRESULT WINAPI CloseDriver32(HDRVR32 hDriver, LPARAM lParam1, LPARAM lParam2);
+#define CloseDriver WINELIB_NAME(CloseDriver)
+LRESULT WINAPI SendDriverMessage16( HDRVR16 hDriver, UINT16 message,
+                                    LPARAM lParam1, LPARAM lParam2 );
+LRESULT WINAPI SendDriverMessage32( HDRVR32 hDriver, UINT32 message,
+                                    LPARAM lParam1, LPARAM lParam2 );
+#define SendDriverMessage WINELIB_NAME(SendDriverMessage)
+HMODULE16 WINAPI GetDriverModuleHandle16(HDRVR16 hDriver);
+HMODULE32 WINAPI GetDriverModuleHandle32(HDRVR32 hDriver);
+#define GetDriverModuleHandle WINELIB_NAME(GetDriverModuleHandle)
+
+/* only win31 version for those below ? */
 HDRVR16 WINAPI GetNextDriver(HDRVR16, DWORD);
 BOOL16 WINAPI GetDriverInfo(HDRVR16, DRIVERINFOSTRUCT16 *);
 
diff --git a/include/file.h b/include/file.h
index 7ba0c0b..9c2abea 100644
--- a/include/file.h
+++ b/include/file.h
@@ -35,6 +35,8 @@
 
 
 /* files/file.c */
+extern FILE_OBJECT *FILE_GetFile( HFILE32 handle );
+extern HFILE32 FILE_Alloc( FILE_OBJECT **file );
 extern void FILE_SetDosError(void);
 extern HFILE32 FILE_DupUnixHandle( int fd );
 extern BOOL32 FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info );
diff --git a/include/gdi.h b/include/gdi.h
index ae40bd1..723aa2f 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -130,6 +130,7 @@
     INT32         GraphicsMode;      /* Graphics mode */
     INT32         DCOrgX;            /* DC origin */
     INT32         DCOrgY;
+    FARPROC16     lpfnPrint;         /* AbortProc for Printing */
     INT32         CursPosX;          /* Current position */
     INT32         CursPosY;
     INT32         ArcDirection;
diff --git a/include/global.h b/include/global.h
index 5c8cc9b..56be65b 100644
--- a/include/global.h
+++ b/include/global.h
@@ -25,7 +25,8 @@
 extern HGLOBAL16 GLOBAL_Alloc( WORD flags, DWORD size, HGLOBAL16 hOwner,
                                BOOL16 isCode, BOOL16 is32Bit,
                                BOOL16 isReadOnly );
-extern WORD GlobalHandleToSel( HGLOBAL16 handle );
+
+extern WORD WINAPI GlobalHandleToSel( HGLOBAL16 handle );
 
 /* memory/virtual.c */
 extern BOOL32 VIRTUAL_Init( void );
diff --git a/include/miscemu.h b/include/miscemu.h
index 3d58a6c..46f232d 100644
--- a/include/miscemu.h
+++ b/include/miscemu.h
@@ -43,6 +43,9 @@
 /* if1632/signal.c */
 extern BOOL32 SIGNAL_InitEmulator(void);
 
+/* misc/aspi.c */
+extern void ASPI_DOS_HandleInt(CONTEXT *context);
+
 #define INT_BARF(context,num) \
     fprintf( stderr, "int%x: unknown/not implemented parameters:\n" \
                      "int%x: AX %04x, BX %04x, CX %04x, DX %04x, " \
diff --git a/include/mmsystem.h b/include/mmsystem.h
index c2011bf..502fb36 100644
--- a/include/mmsystem.h
+++ b/include/mmsystem.h
@@ -1580,54 +1580,64 @@
 LPMMIOPROC32 WINAPI mmioInstallIOProc32W(FOURCC,LPMMIOPROC32,DWORD);
 #define      mmioInstallIOPro WINELIB_NAME_AW(mmioInstallIOProc)
 
-FOURCC WINAPI mmioStringToFOURCC16(LPCSTR sz, UINT16 uFlags);
-FOURCC WINAPI mmioStringToFOURCC32A(LPCSTR sz, UINT32 uFlags);
-FOURCC WINAPI mmioStringToFOURCC32W(LPCWSTR sz, UINT32 uFlags);
+FOURCC WINAPI	mmioStringToFOURCC16(LPCSTR,UINT16);
+FOURCC WINAPI	mmioStringToFOURCC32A(LPCSTR,UINT32);
+FOURCC WINAPI	mmioStringToFOURCC32W(LPCWSTR,UINT32);
 #define mmioStringToFOURCC WINELIB_NAME_AW(mmioStringToFOURCC)
-HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16 * lpmmioinfo, DWORD dwOpenFlags);
-HMMIO32 WINAPI mmioOpen32A(LPSTR szFileName, MMIOINFO32 * lpmmioinfo, DWORD dwOpenFlags);
-HMMIO32 WINAPI mmioOpen32W(LPWSTR szFileName, MMIOINFO32 * lpmmioinfo, DWORD dwOpenFlags);
-#define mmioOpen WINELIB_NAME_AW(mmioOpen)
+HMMIO16	WINAPI	mmioOpen16 (LPSTR ,MMIOINFO16*,DWORD);
+HMMIO32	WINAPI	mmioOpen32A(LPSTR ,MMIOINFO32*,DWORD);
+HMMIO32	WINAPI	mmioOpen32W(LPWSTR,MMIOINFO32*,DWORD);
+#define		mmioOpen WINELIB_NAME_AW(mmioOpen)
 
-UINT16 WINAPI mmioRename(LPCSTR szFileName, LPCSTR szNewFileName,
+UINT16 WINAPI	mmioRename(LPCSTR szFileName, LPCSTR szNewFileName,
      MMIOINFO16 * lpmmioinfo, DWORD dwRenameFlags);
 
-UINT16 WINAPI mmioClose(HMMIO16 hmmio, UINT16 uFlags);
-LONG WINAPI mmioRead(HMMIO16 hmmio, HPSTR pch, LONG cch);
-LONG WINAPI mmioWrite(HMMIO16 hmmio, HPCSTR pch, LONG cch);
-LONG WINAPI mmioSeek(HMMIO16 hmmio, LONG lOffset, int iOrigin);
-UINT16 WINAPI mmioGetInfo(HMMIO16 hmmio, MMIOINFO16 * lpmmioinfo, UINT16 uFlags);
-UINT16 WINAPI mmioSetInfo(HMMIO16 hmmio, const MMIOINFO16 * lpmmioinfo, UINT16 uFlags);
-UINT16 WINAPI mmioSetBuffer(HMMIO16 hmmio, LPSTR pchBuffer, LONG cchBuffer,
-    UINT16 uFlags);
-UINT16 WINAPI mmioFlush(HMMIO16 hmmio, UINT16 uFlags);
-UINT16 WINAPI mmioAdvance(HMMIO16 hmmio, MMIOINFO16 * lpmmioinfo, UINT16 uFlags);
-LONG WINAPI mmioSendMessage(HMMIO16 hmmio, UINT16 uMessage,
-    LPARAM lParam1, LPARAM lParam2);
-UINT16 WINAPI mmioDescend(HMMIO16 hmmio, MMCKINFO * lpck,
-    const MMCKINFO * lpckParent, UINT16 uFlags);
-UINT16 WINAPI mmioAscend(HMMIO16 hmmio, MMCKINFO * lpck, UINT16 uFlags);
-UINT16 WINAPI mmioCreateChunk(HMMIO16 hmmio, MMCKINFO * lpck, UINT16 uFlags);
+MMRESULT16 WINAPI mmioClose16(HMMIO16,UINT16);
+MMRESULT32 WINAPI mmioClose32(HMMIO32,UINT32);
+#define		  mmioClose WINELIB_NAME(mmioClose)
+LONG WINAPI	mmioRead16(HMMIO16,HPSTR,LONG);
+LONG WINAPI	mmioRead32(HMMIO32,HPSTR,LONG);
+#define		mmioRead WINELIB_NAME(mmioRead)
+LONG WINAPI	mmioWrite16(HMMIO16,HPCSTR,LONG);
+LONG WINAPI	mmioWrite32(HMMIO32,HPCSTR,LONG);
+#define		mmioWrite WINELIB_NAME(mmioWrite)
+LONG WINAPI	mmioSeek16(HMMIO16,LONG,INT16);
+LONG WINAPI	mmioSeek32(HMMIO32,LONG,INT32);
+#define		mmioSeek WINELIB_NAME(mmioSeek)
 
-typedef UINT16 (CALLBACK *YIELDPROC) (UINT16 uDeviceID, DWORD dwYieldData);
+MMRESULT16 WINAPI	mmioGetInfo16(HMMIO16,MMIOINFO16*,UINT16);
+MMRESULT32 WINAPI	mmioGetInfo32(HMMIO32,MMIOINFO32*,UINT32);
+#define			mmioGetInfo WINELIB_NAME(mmioGetInfo)
+MMRESULT16 WINAPI	mmioSetInfo(HMMIO16,const MMIOINFO16*,UINT16);
+UINT16 WINAPI mmioSetBuffer(HMMIO16,LPSTR,LONG,UINT16);
+UINT16 WINAPI	mmioFlush16(HMMIO16,UINT16);
+UINT32 WINAPI	mmioFlush32(HMMIO32,UINT32);
+#define		mmioFlush WINELIB_NAME(mmioFlush)
 
-DWORD WINAPI mciSendCommand (UINT16 uDeviceID, UINT16 uMessage,
-                             DWORD dwParam1, DWORD dwParam2);
-DWORD WINAPI mciSendString (LPCSTR lpstrCommand,
-                            LPSTR lpstrReturnString, UINT16 uReturnLength,
-                            HWND16 hwndCallback);
-UINT16 WINAPI mciGetDeviceID (LPCSTR lpstrName);
-UINT16 WINAPI mciGetDeviceIDFromElementID (DWORD dwElementID,
-                                           LPCSTR lpstrType);
+UINT16 WINAPI	mmioAdvance16(HMMIO16,MMIOINFO16*,UINT16);
+UINT32 WINAPI	mmioAdvance32(HMMIO32,MMIOINFO32*,UINT32);
+#define		mmioAdvance WINELIB_NAME(mmioAdvance)
+LONG WINAPI mmioSendMessage(HMMIO16,UINT16,LPARAM,LPARAM);
+UINT16 WINAPI mmioDescend(HMMIO16,MMCKINFO*,const MMCKINFO*,UINT16);
+UINT16 WINAPI	mmioAscend16(HMMIO16,MMCKINFO*,UINT16);
+UINT32 WINAPI	mmioAscend32(HMMIO32,MMCKINFO*,UINT32);
+#define		mmioAscend WINELIB_NAME(mmioAscend)
+UINT16 WINAPI mmioCreateChunk(HMMIO16,MMCKINFO*,UINT16);
+
+typedef UINT16 (CALLBACK *YIELDPROC)(UINT16,DWORD);
+
+DWORD WINAPI mciSendCommand (UINT16,UINT16,DWORD,DWORD);
+DWORD WINAPI mciSendString (LPCSTR,LPSTR,UINT16,HWND16);
+UINT16 WINAPI mciGetDeviceID(LPCSTR);
+UINT16 WINAPI mciGetDeviceIDFromElementID(DWORD,LPCSTR);
 BOOL16 WINAPI mciGetErrorString16 (DWORD,LPSTR,UINT16);
 BOOL32 WINAPI mciGetErrorString32A(DWORD,LPSTR,UINT32);
 BOOL32 WINAPI mciGetErrorString32W(DWORD,LPWSTR,UINT32);
 #define mciGetErrorString WINELIB_NAME_AW(mciGetErrorString)
-BOOL16 WINAPI mciSetYieldProc (UINT16 uDeviceID, YIELDPROC fpYieldProc,
-                               DWORD dwYieldData);
+BOOL16 WINAPI mciSetYieldProc (UINT16,YIELDPROC,DWORD);
 
-HTASK16 WINAPI mciGetCreatorTask(UINT16 uDeviceID);
-YIELDPROC WINAPI mciGetYieldProc (UINT16 uDeviceID, DWORD * lpdwYieldData);
+HTASK16 WINAPI mciGetCreatorTask(UINT16);
+YIELDPROC WINAPI mciGetYieldProc(UINT16,DWORD*);
 
 #define MCIERR_INVALID_DEVICE_ID        (MCIERR_BASE + 1)
 #define MCIERR_UNRECOGNIZED_KEYWORD     (MCIERR_BASE + 3)
diff --git a/include/msdos.h b/include/msdos.h
index ba86fe6..f8276ac 100644
--- a/include/msdos.h
+++ b/include/msdos.h
@@ -193,6 +193,6 @@
 #define EL_Memory            0x05
 
 void WINAPI DOS3Call( CONTEXT *context );
-void do_mscdex( CONTEXT *context );
+void do_mscdex( CONTEXT *context, int dorealmode );
 
 #endif /* __WINE_MSDOS_H */
diff --git a/include/snoop.h b/include/snoop.h
new file mode 100644
index 0000000..0c5fd5f
--- /dev/null
+++ b/include/snoop.h
@@ -0,0 +1,8 @@
+/* 
+ * Definitions for inter-win32-dll snooping
+ */
+#ifndef __WINE_SNOOP_H
+#define __WINE_SNOOP_H
+extern void SNOOP_RegisterDLL(HMODULE32 hmod,LPCSTR name,DWORD nrofordinals);
+extern FARPROC32 SNOOP_GetProcAddress32(HMODULE32 hmod,LPCSTR name,DWORD ordinal,FARPROC32 origfun);
+#endif
diff --git a/include/status.h b/include/status.h
index a53ceae..7bf2b4c 100644
--- a/include/status.h
+++ b/include/status.h
@@ -25,6 +25,7 @@
     UINT32              height;
     BOOL32              simple;
     HFONT32             hFont;
+    HFONT32             hDefaultFont;
     COLORREF            clrBk;  /* background color */
     STATUSWINDOWPART	part0;	/* simple window */
     STATUSWINDOWPART   *parts;
diff --git a/include/sysmetrics.h b/include/sysmetrics.h
index a398235..101f317 100644
--- a/include/sysmetrics.h
+++ b/include/sysmetrics.h
@@ -13,8 +13,8 @@
   /* Constant system metrics */
 #if 0
 #ifdef WIN_95_LOOK
-#define SYSMETRICS_CXDLGFRAME         2
-#define SYSMETRICS_CYDLGFRAME         2
+#define SYSMETRICS_CXDLGFRAME         3
+#define SYSMETRICS_CYDLGFRAME         3
 #define SYSMETRICS_CYVTHUMB          13
 #define SYSMETRICS_CXHTHUMB          13
 #else
@@ -123,8 +123,8 @@
 
 /* Use the following instead of sysMetrics[SM_CXMENUCHECK] GetMenuCheckMarkDimensions()! */
 #define SYSMETRICS_CXMENUCHECK          sysMetrics[SM_CXMENUCHECK]          /* 71 */
-
 #define SYSMETRICS_CYMENUCHECK          sysMetrics[SM_CYMENUCHECK]          /* 72 */
+
 #define SYSMETRICS_SLOWMACHINE          sysMetrics[SM_SLOWMACHINE]          /* 73 */
 #define SYSMETRICS_MIDEASTENABLED       sysMetrics[SM_MIDEASTENABLED]       /* 74 */
 #define SYSMETRICS_MOUSEWHEELPRESENT    sysMetrics[SM_MOUSEWHEELPRESENT]    /* 75 */
diff --git a/include/toolbar.h b/include/toolbar.h
index 0cad32a..14ecd84 100644
--- a/include/toolbar.h
+++ b/include/toolbar.h
@@ -24,19 +24,20 @@
 
 typedef struct tagTOOLBAR_INFO
 {
-    DWORD      dwStructSize;   /* Size of TBBUTTON-Struct */
-    INT32      nHeight;        /* Height of the Toolbar */
-    INT32      nWidth;         /* Width of the Toolbar */
+    DWORD      dwStructSize;   /* size of TBBUTTON struct */
+    INT32      nHeight;        /* height of the toolbar */
+    INT32      nWidth;         /* width of the toolbar */
     INT32      nButtonTop;     /* top of the button rectangle */
     INT32      nButtonHeight;
     INT32      nButtonWidth;
     INT32      nBitmapHeight;
     INT32      nBitmapWidth;
     INT32      nIndent;
+    INT32      nMaxRows;        /* maximum number of rows */
 
-    INT32      nNumButtons;     /* Number of buttons */
-    INT32      nNumBitmaps;
-    INT32      nNumStrings;
+    INT32      nNumButtons;     /* number of buttons */
+    INT32      nNumBitmaps;     /* number of bitmaps */
+    INT32      nNumStrings;     /* number of strings */
 
     BOOL32     bCaptured;
     INT32      nButtonDown;
@@ -45,8 +46,11 @@
     HIMAGELIST himlDef;         /* default image list */
     HIMAGELIST himlHot;         /* hot image list */
     HIMAGELIST himlDis;         /* disabled image list */
+    HWND32     hwndToolTip;     /* handle to tool tip control */
+    HWND32     hwndNotify;      /* handle to the window that gets notifications */
 
     TBUTTON_INFO *buttons;
+    CHAR         **strings;
 } TOOLBAR_INFO;
 
 
diff --git a/include/version.h b/include/version.h
index 0cc36b3..5a092e3 100644
--- a/include/version.h
+++ b/include/version.h
@@ -1 +1 @@
-#define WINE_RELEASE_INFO "Wine release 980601"
+#define WINE_RELEASE_INFO "Wine release 980614"
diff --git a/include/winbase.h b/include/winbase.h
index 22dc183..b4cc236 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -143,6 +143,15 @@
 }CRITICAL_SECTION;
 
 typedef struct {
+        DWORD dwOSVersionInfoSize;
+        DWORD dwMajorVersion;
+        DWORD dwMinorVersion;
+        DWORD dwBuildNumber;
+        DWORD dwPlatformId;
+        CHAR szCSDVersion[128];
+} OSVERSIONINFO16;
+
+typedef struct {
 	DWORD dwOSVersionInfoSize;
 	DWORD dwMajorVersion;
 	DWORD dwMinorVersion;
@@ -167,6 +176,7 @@
 #define VER_PLATFORM_WIN32_NT           2
 
 /*DWORD WINAPI GetVersion( void );*/
+BOOL16 WINAPI GetVersionEx16(OSVERSIONINFO16*);
 BOOL32 WINAPI GetVersionEx32A(OSVERSIONINFO32A*);
 BOOL32 WINAPI GetVersionEx32W(OSVERSIONINFO32W*);
 #define GetVersionEx WINELIB_NAME_AW(GetVersionEx)
diff --git a/include/windows.h b/include/windows.h
index e28a171..9119e41 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -467,6 +467,9 @@
 #define HTZOOM              HTMAXBUTTON
 
   /* WM_SYSCOMMAND parameters */
+#ifdef SC_SIZE /* at least HP-UX: already defined in /usr/include/sys/signal.h */
+#undef SC_SIZE
+#endif
 #define SC_SIZE         0xf000
 #define SC_MOVE         0xf010
 #define SC_MINIMIZE     0xf020
@@ -3611,6 +3614,25 @@
 #define WS_EX_ACCEPTFILES      0x00000010L
 #define WS_EX_TRANSPARENT      0x00000020L
 
+/* New Win95/WinNT4 styles */
+#define WS_EX_MDICHILD         0x00000040L
+#define WS_EX_TOOLWINDOW       0x00000080L
+#define WS_EX_WINDOWEDGE       0x00000100L
+#define WS_EX_CLIENTEDGE       0x00000200L
+#define WS_EX_CONTEXTHELP      0x00000400L
+#define WS_EX_RIGHT            0x00001000L
+#define WS_EX_LEFT             0x00000000L
+#define WS_EX_RTLREADING       0x00002000L
+#define WS_EX_LTRREADING       0x00000000L
+#define WS_EX_LEFTSCROLLBAR    0x00004000L
+#define WS_EX_RIGHTSCROLLBAR   0x00000000L
+#define WS_EX_CONTROLPARENT    0x00010000L
+#define WS_EX_STATICEDGE       0x00020000L
+#define WS_EX_APPWINDOW        0x00040000L
+
+#define WS_EX_OVERLAPPEDWINDOW (WS_EX_WINDOWEDGE|WS_EX_CLIENTEDGE)
+#define WS_EX_PALETTEWINDOW    (WS_EX_WINDOWEDGE|WS_EX_TOOLWINDOW|WS_EX_TOPMOST)
+
 /* Window scrolling */
 #define SW_SCROLLCHILDREN      0x0001
 #define SW_INVALIDATE          0x0002
@@ -6046,6 +6068,13 @@
     DWORD    nFileSizeLow;
 } WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA;
 
+typedef struct _DllVersionInfo {
+    DWORD cbSize;
+    DWORD dwMajorVersion;
+    DWORD dwMinorVersion;
+    DWORD dwBuildNumber;
+    DWORD dwPlatformID;
+} DLLVERSIONINFO;
 
 
 
@@ -6213,6 +6242,8 @@
 BOOL32      WINAPI AllocConsole(void);
 BOOL32      WINAPI AreFileApisANSI(void);
 BOOL32      WINAPI Beep(DWORD,DWORD);
+WORD        WINAPI CascadeWindows (HWND32, UINT32, const LPRECT32,
+                                   UINT32, const HWND32 *);
 BOOL32      WINAPI ClearCommError(INT32,LPDWORD,LPCOMSTAT);
 BOOL32      WINAPI CloseHandle(HANDLE32);
 BOOL32      WINAPI CloseServiceHandle(HANDLE32);
@@ -6341,6 +6372,8 @@
 BOOL32      WINAPI GetFileAttributesEx32W(LPCWSTR,GET_FILEEX_INFO_LEVELS,LPVOID);
 #define     GetFileattributesEx WINELIB_NAME_AW(GetFileAttributesEx)
 DWORD       WINAPI GetFileInformationByHandle(HFILE32,BY_HANDLE_FILE_INFORMATION*);
+BOOL32      WINAPI GetFileSecurityA(LPCSTR,SECURITY_INFORMATION,LPSECURITY_DESCRIPTOR,DWORD,LPDWORD);
+BOOL32      WINAPI GetFileSecurityW(LPCWSTR,SECURITY_INFORMATION,LPSECURITY_DESCRIPTOR,DWORD,LPDWORD);
 DWORD       WINAPI GetFileSize(HFILE32,LPDWORD);
 BOOL32      WINAPI GetFileTime(HFILE32,LPFILETIME,LPFILETIME,LPFILETIME);
 DWORD       WINAPI GetFileType(HFILE32);
@@ -6566,6 +6599,8 @@
 BOOL32      WINAPI StartService32W(HANDLE32,DWORD,LPCWSTR*);
 #define     StartService WINELIB_NAME_AW(StartService)
 BOOL32      WINAPI SystemTimeToFileTime(const SYSTEMTIME*,LPFILETIME);
+WORD        WINAPI TileWindows (HWND32, UINT32, const LPRECT32,
+                                UINT32, const HWND32 *);
 BOOL32      WINAPI TrackPopupMenuEx(HMENU32,UINT32,INT32,INT32,HWND32,
                                     LPTPMPARAMS);
 DWORD       WINAPI TlsAlloc(void);
@@ -7150,8 +7185,8 @@
 BOOL16      WINAPI EmptyClipboard16(void);
 BOOL32      WINAPI EmptyClipboard32(void);
 #define     EmptyClipboard WINELIB_NAME(EmptyClipboard)
-BOOL16      WINAPI EnableMenuItem16(HMENU16,UINT16,UINT16);
-BOOL32      WINAPI EnableMenuItem32(HMENU32,UINT32,UINT32);
+UINT16      WINAPI EnableMenuItem16(HMENU16,UINT16,UINT16);
+UINT32      WINAPI EnableMenuItem32(HMENU32,UINT32,UINT32);
 #define     EnableMenuItem WINELIB_NAME(EnableMenuItem)
 BOOL16      WINAPI EnableScrollBar16(HWND16,INT16,UINT16);
 BOOL32      WINAPI EnableScrollBar32(HWND32,INT32,UINT32);
@@ -8019,6 +8054,9 @@
 HCURSOR32   WINAPI LoadCursor32A(HINSTANCE32,LPCSTR);
 HCURSOR32   WINAPI LoadCursor32W(HINSTANCE32,LPCWSTR);
 #define     LoadCursor WINELIB_NAME_AW(LoadCursor)
+HCURSOR32   WINAPI LoadCursorFromFile32A(LPCSTR);
+HCURSOR32   WINAPI LoadCursorFromFile32W(LPCWSTR);
+#define     LoadCursorFromFile WINELIB_NAME_AW(LoadCursorFromFile)
 HICON16     WINAPI LoadIcon16(HINSTANCE16,SEGPTR);
 HICON32     WINAPI LoadIcon32A(HINSTANCE32,LPCSTR);
 HICON32     WINAPI LoadIcon32W(HINSTANCE32,LPCWSTR);
diff --git a/include/winerror.h b/include/winerror.h
index 34ae239..d5b2cfc 100644
--- a/include/winerror.h
+++ b/include/winerror.h
@@ -31,6 +31,7 @@
 #define ERROR_NOT_ENOUGH_MEMORY     8
 #define ERROR_BAD_FORMAT            11
 #define ERROR_INVALID_ACCESS        12
+#define ERROR_INVALID_DATA          13
 #define ERROR_OUTOFMEMORY           14
 #define ERROR_NO_MORE_FILES         18
 #define ERROR_SHARING_VIOLATION     32
@@ -57,6 +58,7 @@
 #define ERROR_INVALID_ADDRESS       487
 #define ERROR_CAN_NOT_COMPLETE      1003
 #define ERROR_BADKEY                1010 /* Config reg key invalid */
+#define ERROR_CANTREAD              1012 /* Config reg key couldn't be read */
 #define ERROR_CANTWRITE             1013 /* Config reg key couldn't be written */
 #define ERROR_IO_DEVICE             1117
 #define ERROR_POSSIBLE_DEADLOCK     1131
@@ -65,6 +67,7 @@
 #define ERROR_ALREADY_INITIALIZED   1247
 #define ERROR_PRIVILEGE_NOT_HELD    1314
 #define ERROR_COMMITMENT_LIMIT      1455
+#define ERROR_INVALID_PRINTER_NAME  1801
 
 /* HRESULT values for OLE, SHELL and other Interface stuff */
 #define	NOERROR				0
diff --git a/include/winnt.h b/include/winnt.h
index 641df93..44fc732 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -8,6 +8,7 @@
 #define __WINE_WINNT_H
 
 #include "wintypes.h"
+#include "windows.h"
 
 /* Heap flags */
 
@@ -97,6 +98,7 @@
     DWORD   SegSs;
 } CONTEXT, *PCONTEXT;
 
+typedef HANDLE32 *PHANDLE;
 
 #ifdef __WINE__
 
@@ -272,6 +274,164 @@
 LPTOP_LEVEL_EXCEPTION_FILTER
 WINAPI SetUnhandledExceptionFilter( LPTOP_LEVEL_EXCEPTION_FILTER filter );
 
+/*
+ * Here follows typedefs for security and tokens.
+ */ 
+
+/*
+ * First a constant for the following typdefs.
+ */
+
+#define ANYSIZE_ARRAY   1
+
+/*
+ * TOKEN_INFORMATION_CLASS
+ */
+
+typedef enum _TOKEN_INFORMATION_CLASS {
+  TokenUser = 1, 
+  TokenGroups, 
+  TokenPrivileges, 
+  TokenOwner, 
+  TokenPrimaryGroup, 
+  TokenDefaultDacl, 
+  TokenSource, 
+  TokenType, 
+  TokenImpersonationLevel, 
+  TokenStatistics 
+} TOKEN_INFORMATION_CLASS; 
+
+/* 
+ * SID_AND_ATTRIBUTES
+ */
+
+typedef struct _SID_AND_ATTRIBUTES {
+  PSID  Sid; 
+  DWORD Attributes; 
+} SID_AND_ATTRIBUTES ; 
+ 
+/*
+ * TOKEN_USER
+ */
+
+typedef struct _TOKEN_USER {
+  SID_AND_ATTRIBUTES User; 
+} TOKEN_USER; 
+
+/*
+ * TOKEN_GROUPS
+ */
+
+typedef struct _TOKEN_GROUPS  {
+  DWORD GroupCount; 
+  SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY]; 
+} TOKEN_GROUPS; 
+
+/*
+ * LUID_AND_ATTRIBUTES
+ */
+
+typedef struct _LUID_AND_ATTRIBUTES {
+  LUID   Luid; 
+  DWORD  Attributes; 
+} LUID_AND_ATTRIBUTES; 
+
+/*
+ * TOKEN_PRIVILEGES
+ */
+
+typedef struct _TOKEN_PRIVILEGES {
+  DWORD PrivilegeCount; 
+  LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]; 
+} TOKEN_PRIVILEGES; 
+
+/*
+ * TOKEN_OWNER
+ */
+
+typedef struct _TOKEN_OWNER {
+  PSID Owner; 
+} TOKEN_OWNER; 
+
+/*
+ * TOKEN_PRIMARY_GROUP
+ */
+
+typedef struct _TOKEN_PRIMARY_GROUP {
+  PSID PrimaryGroup; 
+} TOKEN_PRIMARY_GROUP; 
+
+
+/*
+ * ACL (and PACL LPACL?).
+ */
+/*
+
+are defined in ntddl.h.
+typedef struct _ACL {
+  BYTE AclRevision;
+  BYTE Sbz1;
+  WORD AclSize;
+  WORD AceCount;
+  WORD Sbz2;
+} ACL, *PACL; PACL <=> LPACL? */
+
+/*
+ * TOKEN_DEFAULT_DACL
+ */
+
+typedef struct _TOKEN_DEFAULT_DACL { 
+  LPACL DefaultDacl; 
+} TOKEN_DEFAULT_DACL; 
+
+/*
+ * TOKEN_SOURCEL
+ */
+
+typedef struct _TOKEN_SOURCE {
+  char Sourcename[8]; 
+  LUID SourceIdentifier; 
+} TOKEN_SOURCE; 
+
+/*
+ * TOKEN_TYPE
+ */
+
+typedef enum tagTOKEN_TYPE {
+  TokenPrimary = 1, 
+  TokenImpersonation 
+} TOKEN_TYPE; 
+
+/*
+ * SECURITY_IMPERSONATION_LEVEL
+ */
+
+typedef enum _SECURITY_IMPERSONATION_LEVEL {
+  SecurityAnonymous, 
+  SecurityIdentification, 
+  SecurityImpersonation, 
+  SecurityDelegation 
+} SECURITY_IMPERSONATION_LEVEL; 
+
+
+/*
+ * TOKEN_STATISTICS
+ */
+
+typedef struct _TOKEN_STATISTICS {
+  LUID  TokenId; 
+  LUID  AuthenticationId; 
+  LARGE_INTEGER ExpirationTime; 
+  TOKEN_TYPE    TokenType; 
+  SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; 
+  DWORD DynamicCharged; 
+  DWORD DynamicAvailable; 
+  DWORD GroupCount; 
+  DWORD PrivilegeCount; 
+  LUID  ModifiedId; 
+} TOKEN_STATISTICS; 
+
+
 /* I moved the Language IDs to winnls.h (David Lee Lambert) */
 
 
diff --git a/include/winreg.h b/include/winreg.h
index 66c8fc4..b594c4a 100644
--- a/include/winreg.h
+++ b/include/winreg.h
@@ -53,11 +53,12 @@
 #define HKEY_CURRENT_CONFIG	0x80000005
 #define HKEY_DYN_DATA		0x80000006
 
-#define	REG_OPTION_RESERVED	0x00000000
-#define	REG_OPTION_NON_VOLATILE	0x00000000
-#define	REG_OPTION_VOLATILE	0x00000001
-#define	REG_OPTION_CREATE_LINK	0x00000002
-#define REG_OPTION_TAINTED	0x80000000
+#define	REG_OPTION_RESERVED		0x00000000
+#define	REG_OPTION_NON_VOLATILE		0x00000000
+#define	REG_OPTION_VOLATILE		0x00000001
+#define	REG_OPTION_CREATE_LINK		0x00000002
+#define	REG_OPTION_BACKUP_RESTORE	0x00000004 /* FIXME */
+#define	REG_OPTION_TAINTED		0x80000000 /* Internal? */
 
 #define REG_CREATED_NEW_KEY	0x00000001
 #define REG_OPENED_EXISTING_KEY	0x00000002
diff --git a/libtest/Makefile.in b/libtest/Makefile.in
index 039c6f9..b398b15 100644
--- a/libtest/Makefile.in
+++ b/libtest/Makefile.in
@@ -20,13 +20,13 @@
 RC_SRCS = \
 	hello3res.rc
 
-all: check_winerc $(PROGRAMS)
+all: check_wrc $(PROGRAMS)
 
 depend:: $(RC_SRCS:.rc=.h)
 
 @MAKE_RULES@
 
-$(RC_SRCS:.rc=.c) $(RC_SRCS:.rc=.h): $(WINERC)
+$(RC_SRCS:.rc=.s): $(WRC)
 
 expand: expand.o
 	$(CC) -o expand expand.o $(LDOPTIONS) $(ALL_LIBS)
diff --git a/libtest/hello3res.rc b/libtest/hello3res.rc
index 020e574..e66c5a1 100644
--- a/libtest/hello3res.rc
+++ b/libtest/hello3res.rc
@@ -1,3 +1,5 @@
+#include "windows.h"
+
 MAIN MENU 
 {
  POPUP "Menu demo" {
@@ -7,7 +9,7 @@
  }
 }
 
-BITDEMO BITMAP "../rc/winelogo.bmp"
+/*BITDEMO BITMAP "../rc/winelogo.bmp"*/
 
 DIADEMO DIALOG 20, 20, 179, 118
 STYLE DS_MODALFRAME | WS_CAPTION | WS_POPUP | WS_VISIBLE | WS_SYSMENU
@@ -20,9 +22,6 @@
 	CONTROL "Edit control", 103, "EDIT", ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 18, 41, 44, 13
 	CONTROL "Radio button", 104, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 17, 23, 58, 12
 	CONTROL "Checkbox", 101, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 19, 76, 47, 12
-#if 1
 	CONTROL "", 106, "COMBOBOX", CBS_DROPDOWN | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 86, 23, 86, 85
-#else
-	CONTROL "", 106, "LISTBOX", LBS_STANDARD | LBS_DISABLENOSCROLL | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 86, 23, 86, 85
-#endif
+/*	CONTROL "", 106, "LISTBOX", LBS_STANDARD | LBS_DISABLENOSCROLL | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 86, 23, 86, 85 */
 END
diff --git a/loader/module.c b/loader/module.c
index c04e2b2..7b7ff65 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -173,7 +173,7 @@
             return (FARPROC16)PrintSetupDlgProc;
         if (!strcmp(name,"ReplaceTextDlgProc"))
             return (FARPROC16)ReplaceTextDlgProc16;
-        WARN(module,"No mapping for %s(), add one in library/miscstubs.c\n",name);
+        FIXME(module,"No mapping for %s(), add one in library/miscstubs.c\n",name);
         assert( FALSE );
         return NULL;
     }
@@ -496,7 +496,7 @@
  */
 BOOL32 WINAPI FreeLibrary32(HINSTANCE32 hLibModule)
 {
-    WARN(module,"(%08x): stub\n", hLibModule);
+    FIXME(module,"(%08x): stub\n", hLibModule);
     return TRUE;  /* FIXME */
 }
 
diff --git a/loader/ne/module.c b/loader/ne/module.c
index 893c834..e9b645c 100644
--- a/loader/ne/module.c
+++ b/loader/ne/module.c
@@ -395,8 +395,7 @@
     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 );
+        MSG( "Can't open file '%s' for module %04x\n", name, pModule->self );
     TRACE(module, "opened '%s' -> %d\n",
                     name, cachedfd );
     return cachedfd;
@@ -695,9 +694,9 @@
             {
                 /* FIXME: cleanup what was done */
 
-               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 );
+                MSG( "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;
             }
             *pModRef = GetExePtr( hDLL );
@@ -751,7 +750,8 @@
         /* 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 );
+            MSG( "Could not load Windows DLL '%s', using built-in module.\n",
+                 name );
             return hModule;
         }
         return 2;  /* File not found */
diff --git a/loader/pe_image.c b/loader/pe_image.c
index ef6734a..aaf2dec 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -57,6 +57,7 @@
 #include "module.h"
 #include "global.h"
 #include "task.h"
+#include "snoop.h"
 #include "debug.h"
 
 static void PE_InitDLL(WINE_MODREF *wm, DWORD type, LPVOID lpReserved);
@@ -162,14 +163,15 @@
                             addr = function[*ordinal];
                             if (!addr) return NULL;
                             if ((addr < rva_start) || (addr >= rva_end))
-                                return (FARPROC32)RVA(addr);
+				return SNOOP_GetProcAddress32(wm->module,ename,*ordinal,(FARPROC32)RVA(addr));
                             forward = (char *)RVA(addr);
                             break;
 			}
 			ordinal++;
 			name++;
 		}
-	} else {
+	} else 	{
+		int i;
 		if (LOWORD(funcName)-exports->Base > exports->NumberOfFunctions) {
 			TRACE(win32,"	ordinal %d out of range!\n",
                                       LOWORD(funcName));
@@ -177,8 +179,20 @@
 		}
 		addr = function[(int)funcName-exports->Base];
                 if (!addr) return NULL;
+		ename = "";
+		if (name) {
+		    for (i=0;i<exports->NumberOfNames;i++) {
+			    ename = (char*)RVA(*name);
+			    if (*ordinal == LOWORD(funcName)-exports->Base)
+			    	break;
+			    ordinal++;
+			    name++;
+		    }
+		    if (i==exports->NumberOfNames)
+		    	ename = "";
+		}
 		if ((addr < rva_start) || (addr >= rva_end))
-			return (FARPROC32)RVA(addr);
+			return SNOOP_GetProcAddress32(wm->module,ename,(DWORD)funcName-exports->Base,(FARPROC32)RVA(addr));
 		forward = (char *)RVA(addr);
 	}
 	if (forward)
@@ -584,6 +598,7 @@
          */
         *(IMAGE_DOS_HEADER *)load_addr = *dos_header;
         *(IMAGE_NT_HEADERS *)(load_addr + dos_header->e_lfanew) = *nt_header;
+	memcpy(PE_SECTIONS(load_addr),PE_SECTIONS(hModule),sizeof(IMAGE_SECTION_HEADER)*nt_header->FileHeader.NumberOfSections);
 
         pe_seg = PE_SECTIONS(hModule);
 	for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++, pe_seg++)
@@ -681,11 +696,11 @@
 
 	if(nt_header->OptionalHeader.DataDirectory
 		[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size)
-		FIXME(win32,"Bound Import directory ignored\n");
+		TRACE(win32,"Bound Import directory ignored\n");
 
 	if(nt_header->OptionalHeader.DataDirectory
 		[IMAGE_DIRECTORY_ENTRY_IAT].Size)
-		FIXME(win32,"Import Address Table directory ignored\n");
+		TRACE(win32,"Import Address Table directory ignored\n");
 	if(nt_header->OptionalHeader.DataDirectory[13].Size)
 		FIXME(win32,"Unknown directory 13 ignored\n");
 	if(nt_header->OptionalHeader.DataDirectory[14].Size)
@@ -769,7 +784,7 @@
 		    WARN( module, "Could not load external DLL '%s', using built-in module.\n", name );
 		    return hModule;
 		}
-		return 1;
+		return 0;
 	}
 	/* will go away ... */
 	if ((hModule = MODULE_CreateDummyModule( &ofs )) < 32) {
@@ -795,7 +810,7 @@
 	    FreeLibrary16( hModule);
 	    HeapFree(process->heap,0,wm);
 	    ERR(win32,"can't load %s\n",ofs.szPathName);
-            return 21; /* FIXME: probably 0 */
+            return 0;
         }
 
 	/* (possible) recursion */
@@ -815,6 +830,8 @@
 	    return 0;
 	}
         pModule->module32 = wm->module;
+	if (wm->binfmt.pe.pe_export)
+		SNOOP_RegisterDLL(wm->module,wm->modname,wm->binfmt.pe.pe_export->NumberOfFunctions);
 	return wm->module;
 }
 
diff --git a/loader/resource.c b/loader/resource.c
index e4b2a2a..4f0d28d 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -24,6 +24,7 @@
 #include "debug.h"
 #include "libres.h"
 #include "winerror.h"
+#include "debugstr.h"
 
 extern WORD WINE_LanguageId;
 
@@ -69,10 +70,11 @@
     WINE_MODREF	*wm = MODULE32_LookupHMODULE(PROCESS_Current(),hModule);
     HRSRC32	hrsrc;
 
-    TRACE(resource, "module=%08x "
-		     "type=%s%p name=%s%p\n", wm->module,
-		     (HIWORD(type))? "" : "#", type,
-		     (HIWORD(name))? "" : "#", name);
+    TRACE(resource, "module=%08x type=%s name=%s\n",
+	  hModule,
+	  debugres_w (type),
+	  debugres_w (name));
+
     if (__winelib) {
     	hrsrc = LIBRES_FindResource( hModule, name, type );
 	if (hrsrc)
@@ -346,7 +348,7 @@
 			       cEntries * sizeof(ACCEL32));
   TRACE(accel, "handle %p\n", (LPVOID)hAccel);
   if(!hAccel) {
-    WARN(accel, "Out of memory.\n");
+    ERR(accel, "Out of memory.\n");
     SetLastError(ERROR_NOT_ENOUGH_MEMORY);
     return (HACCEL32)NULL;
   }
@@ -389,13 +391,15 @@
      from LoadAccelerators(). WTH? */
   
   /* Parameter checking to avoid any embarassing situations. */
-/*   if(!handle) { */
-/*     WARN(accel, "Application sent NULL ptr.\n"); */
-/*     SetLastError(ERROR_INVALID_PARAMETER); */
-/*     return FALSE; */
-/*   } */
+#if 0
+     if(!handle) {
+       WARN(accel, "Application sent NULL ptr.\n");
+       SetLastError(ERROR_INVALID_PARAMETER);
+       return FALSE;
+     }
   
-/*   HeapFree(GetProcessHeap(), 0, (LPACCEL32)handle); */
+     HeapFree(GetProcessHeap(), 0, (LPACCEL32)handle);
+#endif
 
   return TRUE;
 }
diff --git a/memory/ldt.c b/memory/ldt.c
index 1441907..cdbe7f3 100644
--- a/memory/ldt.c
+++ b/memory/ldt.c
@@ -285,10 +285,9 @@
             flags[1] = (ldt_flags_copy[i] & LDT_FLAGS_READONLY) ? '-' : 'w';
             flags[2] = '-';
         }
-        TRACE(ldt,"%04x: sel=%04x base=%08lx limit=%08lx %d-bit %c%c%c\n",
-                i, ENTRY_TO_SELECTOR(i),
-                ldt_copy[i].base, ldt_copy[i].limit,
-                ldt_flags_copy[i] & LDT_FLAGS_32BIT ? 32 : 16,
-                flags[0], flags[1], flags[2] );
+        MSG("%04x: sel=%04x base=%08lx limit=%08lx %d-bit %c%c%c\n",
+            i, ENTRY_TO_SELECTOR(i), ldt_copy[i].base, ldt_copy[i].limit,
+            ldt_flags_copy[i] & LDT_FLAGS_32BIT ? 32 : 16,
+            flags[0], flags[1], flags[2] );
     }
 }
diff --git a/memory/string.c b/memory/string.c
index 92d1a88..262667f 100644
--- a/memory/string.c
+++ b/memory/string.c
@@ -11,6 +11,7 @@
 #include "winerror.h"
 #include "ldt.h"
 #include "debug.h"
+#include "winnls.h"
 
 static const BYTE STRING_Oem2Ansi[256] =
 "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\244"
@@ -144,7 +145,7 @@
  */
 INT16 WINAPI lstrcmp16( LPCSTR str1, LPCSTR str2 )
 {
-    return (INT16)lstrcmp32A( str1, str2 );
+    return (INT16)strcmp( str1, str2 );
 }
 
 
@@ -153,19 +154,14 @@
  */
 INT32 WINAPI lstrcmp32A( LPCSTR str1, LPCSTR str2 )
 {
-    TRACE(string,"%s and %s\n",
-		   debugstr_a (str1), debugstr_a (str2));
-    /* Win95 KERNEL32.DLL does it that way. Hands off! */
-    if (!str1 || !str2) {
-    	SetLastError(ERROR_INVALID_PARAMETER);
-	return 0;
-    }
-    return (INT32)strcmp( str1, str2 );
+    return CompareString32A(LOCALE_SYSTEM_DEFAULT,0,str1,-1,str2,-1) - 2 ;
 }
 
 
 /***********************************************************************
  *           lstrcmp32W   (KERNEL.603)
+ * FIXME : should call CompareString32W, when it is implemented.
+ *    This implementation is not "word sort", as it should.
  */
 INT32 WINAPI lstrcmp32W( LPCWSTR str1, LPCWSTR str2 )
 {
@@ -198,17 +194,7 @@
 
     TRACE(string,"strcmpi %s and %s\n",
 		   debugstr_a (str1), debugstr_a (str2));
-    if (!str1 || !str2) {
-    	SetLastError(ERROR_INVALID_PARAMETER);
-	return 0;
-    }
-    while (*str1)
-    {
-        if ((res = toupper(*str1) - toupper(*str2)) != 0) return res;
-        str1++;
-        str2++;
-    }
-    return toupper(*str1) - toupper(*str2);
+    return CompareString32A(LOCALE_SYSTEM_DEFAULT,NORM_IGNORECASE,str1,-1,str2,-1)-2;
 }
 
 
diff --git a/misc/Makefile.in b/misc/Makefile.in
index ee7f5c5..420d9e2 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -30,6 +30,7 @@
 	spy.c \
 	stress.c \
 	system.c \
+	tapi32.c \
 	toolhelp.c \
 	tweak.c \
 	ver.c \
diff --git a/misc/aspi.c b/misc/aspi.c
index 51e11b0..aad7f05 100644
--- a/misc/aspi.c
+++ b/misc/aspi.c
@@ -12,6 +12,9 @@
 #include "options.h"
 #include "heap.h"
 #include "debug.h"
+#include "selectors.h"
+#include "module.h"
+#include "miscemu.h"
 
 
 /* FIXME!
@@ -95,6 +98,8 @@
 typedef struct ASPI_DEVICE_INFO ASPI_DEVICE_INFO;
 static ASPI_DEVICE_INFO *ASPI_open_devices = NULL;
 
+static BOOL16 DOSASPI = FALSE;
+
 #ifdef linux
 static int
 ASPI_OpenDevice16(SRB_ExecSCSICmd16 *prb)
@@ -157,7 +162,10 @@
   BYTE *lpBuf;
   dbg_decl_str(aspi, 512);
 
-  lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
+  if ((DOSASPI) && (prb->SRB_BufPointer)) /* translate real mode address */
+    lpBuf = (BYTE *)DOSMEM_MapRealToLinear((UINT32)prb->SRB_BufPointer);
+  else
+    lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
 
   switch (prb->CDBByte[0]) {
   case CMD_INQUIRY:
@@ -229,7 +237,10 @@
 {
   BYTE *lpBuf;
 
-  lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
+  if ((DOSASPI) && (prb->SRB_BufPointer)) /* translate real mode address */
+    lpBuf = (BYTE *)DOSMEM_MapRealToLinear((UINT32)prb->SRB_BufPointer);
+  else
+    lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
 
   switch (prb->CDBByte[0]) {
   case CMD_INQUIRY:
@@ -255,6 +266,7 @@
 
   fd = ASPI_OpenDevice16(prb);
   if (fd == -1) {
+      WARN(aspi, "ASPI_ExecScsiCmd16 failed: could not open device.\n");
       prb->SRB_Status = SS_ERR;
       return SS_ERR;
   }
@@ -263,9 +275,13 @@
   sg_reply_hdr = NULL;
 
   prb->SRB_Status = SS_PENDING;
-  lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
+  if ((DOSASPI) && (prb->SRB_BufPointer)) /* translate real mode address */
+    lpBuf = (BYTE *)DOSMEM_MapRealToLinear((UINT32)prb->SRB_BufPointer);
+  else
+    lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
 
   if (!prb->SRB_CDBLen) {
+      WARN(aspi, "ASPI_ExecScsiCmd16 failed: prb->SRB_CDBLen = 0.\n");
       prb->SRB_Status = SS_ERR;
       return SS_ERR;
   }
@@ -406,7 +422,14 @@
 
   switch (lpSRB->common.SRB_cmd) {
   case SC_HA_INQUIRY:
-    FIXME(aspi, "Not implemented SC_HA_INQUIRY\n");
+    lpSRB->inquiry.SRB_Status = 0x1;           /* completed successfully */
+    lpSRB->inquiry.SRB_HaId = 1;               /* bogus value */
+    lpSRB->inquiry.HA_Count = 1;               /* not always */
+    lpSRB->inquiry.HA_SCSI_ID = 7;             /* not always ID 7 */
+    strcat(lpSRB->inquiry.HA_ManagerId, "Wine ASPI"); /* max 15 chars */
+    lpSRB->inquiry.SRB_55AASignature = 0x55aa; /* correct ??? */
+    lpSRB->inquiry.SRB_ExtBufferSize = 0x2000; /* bogus value */
+    FIXME(aspi, "ASPI: Partially implemented SC_HA_INQUIRY\n");
     break;
   case SC_GET_DEV_TYPE:
     FIXME(aspi, "Not implemented SC_GET_DEV_TYPE\n");
@@ -438,3 +461,39 @@
 	return (DWORD)0;
 #endif
 }
+
+
+void WINAPI ASPI_DOS_func(DWORD srb)
+{
+       LPSRB16 lpSRB = (LPSRB16)DOSMEM_MapRealToLinear(srb);
+       SEGPTR spSRB = MapLS(lpSRB);
+
+       TRACE(aspi, "DOSASPI: function #%d\n", lpSRB->common.SRB_cmd);
+       DOSASPI = TRUE;
+       SendASPICommand16(spSRB);
+       DOSASPI = FALSE;
+       UnMapLS(spSRB);
+}
+
+void ASPI_DOS_HandleInt(CONTEXT *context)
+/* returns a real mode call address to ASPI_DOS_func() */
+{
+#ifdef linux
+       FARPROC16 DOS_func;
+       DWORD dos;
+       LPBYTE dosptr;
+
+       DOS_func = MODULE_GetWndProcEntry16("ASPI_DOS_func");
+       dos = GlobalDOSAlloc(5);
+       dosptr = (BYTE *)PTR_SEG_OFF_TO_LIN(LOWORD(dos), 0);
+       *dosptr++ = 0xea; /* ljmp */
+       *(FARPROC16 *)dosptr = DOS_func;
+
+       *(DWORD *)PTR_SEG_OFF_TO_LIN(DS_reg(context), DX_reg(context))
+               = MAKELONG(0, HIWORD(dos)); /* real mode address */
+       RESET_CFLAG(context);
+       AX_reg(context) = CX_reg(context);
+#else
+       SET_CFLAG(context);
+#endif
+}
diff --git a/misc/comm.c b/misc/comm.c
index fe67f6f..a1f69d3 100644
--- a/misc/comm.c
+++ b/misc/comm.c
@@ -22,6 +22,9 @@
 #include <termios.h>
 #include <fcntl.h>
 #include <string.h>
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
 #include <errno.h>
 #include <ctype.h>
 #include <sys/stat.h>
@@ -33,6 +36,12 @@
 
 #include "windows.h"
 #include "comm.h"
+#ifdef HAVE_SYS_MODEM_H
+# include <sys/modem.h>
+#endif
+#ifdef HAVE_SYS_STRTIO_H
+# include <sys/strtio.h>
+#endif
 #include "heap.h"
 #include "options.h"
 #include "debug.h"
diff --git a/misc/commdlg.c b/misc/commdlg.c
index 1e3cfec..03e57f9 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -3928,3 +3928,11 @@
   SEGPTR_FREE(lpcc16);
   return (BOOL32)ret;
 }
+
+/***********************************************************************
+ *            PageSetupDlgA  (COMDLG32.15)
+ */
+BOOL32 WINAPI PageSetupDlg32A(LPPAGESETUPDLG32A setupdlg) {
+	FIXME(commdlg,"(%p), stub!\n",setupdlg);
+	return FALSE;
+}
diff --git a/misc/crtdll.c b/misc/crtdll.c
index 3d410ea..3b88c3f 100644
--- a/misc/crtdll.c
+++ b/misc/crtdll.c
@@ -987,11 +987,18 @@
 /*********************************************************************
  *                  _strdup          (CRTDLL.285)
  */
-LPSTR __cdecl CRTDLL__strdup(LPSTR ptr)
+LPSTR __cdecl CRTDLL__strdup(LPCSTR ptr)
 {
     return HEAP_strdupA(GetProcessHeap(),0,ptr);
 }
 
+/*********************************************************************
+ *                  _wcsdup          (CRTDLL.320)
+ */
+LPWSTR __cdecl CRTDLL__wcsdup(LPCWSTR ptr)
+{
+    return HEAP_strdupW(GetProcessHeap(),0,ptr);
+}
 
 /*********************************************************************
  *                  fclose           (CRTDLL.362)
@@ -1833,3 +1840,27 @@
 	/* FIXME: handle multibyte strings */
 	return strrchr(s,x);
 }
+
+/*********************************************************************
+ *                  _memicmp           (CRTDLL.233)(NTDLL.868)
+ * A stringcompare, without \0 check
+ * RETURNS
+ *	-1:if first string is alphabetically before second string
+ *	1:if second ''    ''      ''          ''   first   ''
+ *      0:if both are equal.
+ */
+INT32 __cdecl CRTDLL__memicmp(
+	LPCSTR s1,	/* [in] first string */
+	LPCSTR s2,	/* [in] second string */
+	DWORD len	/* [in] length to compare */
+) { 
+	int	i;
+
+	for (i=0;i<len;i++) {
+		if (tolower(s1[i])<tolower(s2[i]))
+			return -1;
+		if (tolower(s1[i])>tolower(s2[i]))
+			return  1;
+	}
+	return 0;
+}
diff --git a/misc/lstr.c b/misc/lstr.c
index bffd1e7..043a778 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -178,7 +178,7 @@
     if ((p > buffer) && (p[-1] == '\n')) p[1] = '\0'; /* Remove trailing \n */
     if (!GetModuleName( GetCurrentTask(), module, sizeof(module) ))
         strcpy( module, "???" );
-    TRACE(resource, "%s says '%s'\n", module, buffer );
+    DUMP("%s says '%s'\n", module, buffer );
     HeapFree( GetProcessHeap(), 0, buffer );
 }
 
diff --git a/misc/main.c b/misc/main.c
index 49ef6df..8db0f9d 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -209,6 +209,10 @@
  */
 static BOOL32 MAIN_ParseDebugOptions(char *options)
 {
+  /* defined in relay32/relay386.c */
+  extern char **debug_relay_includelist;
+  extern char **debug_relay_excludelist;
+
   int l, cls;
   if (strlen(options)<3)
     return FALSE;
@@ -243,6 +247,45 @@
 	    if(cls == -1 || cls == j)
 	      debug_msg_enabled[i][j]=(*options=='+');
       }
+    else if (!lstrncmpi32A(options+1, "relay=", 6))
+      {
+	int i, j;
+	char *s, *s2, ***output, c;
+
+	for (i=0; i<DEBUG_CHANNEL_COUNT; i++)
+	  if (debug_ch_name && (!lstrncmpi32A(debug_ch_name[i],"relay",5))){
+	    for(j=0; j<DEBUG_CLASS_COUNT; j++)
+	      if(cls == -1 || cls == j)
+		debug_msg_enabled[i][j]=TRUE;
+	    break;
+	  }
+	/* should never happen, maybe assert(i!=DEBUG_CHANNEL_COUNT)? */
+	if (i==DEBUG_CHANNEL_COUNT)
+	  return FALSE;
+	if (*options == '+')
+	  output = &debug_relay_includelist;
+	else
+	  output = &debug_relay_excludelist;
+	s = options + 7;
+	i = 1;
+	while((s = strchr(s, ':'))) i++, s++;
+	*output = malloc(sizeof(char **) * i + 1);
+	i = 0;
+	s = options + 7;
+	while((s2 = strchr(s, ':'))) {
+          c = *s2;
+          *s2 = '\0';
+	  *((*output)+i) = strdup(s);
+          *s2 = c;
+	  s = s2 + 1;
+	  i++;
+	}
+	c = *(options + l);
+	*(options + l) = '\0';
+	*((*output)+i) = strdup(s);
+	*(options + l) = c;
+	*((*output)+i+1) = NULL;
+      }
     else
       {
 	int i, j;
@@ -758,7 +801,6 @@
 		GetProfileString32A("Desktop", "IconTitleFaceName", "MS Sans Serif", 
 			lpLogFont->lfFaceName, LF_FACESIZE );
 		lpLogFont->lfHeight = -GetProfileInt32A("Desktop","IconTitleSize", 8);
-
 		lpLogFont->lfWidth = 0;
 		lpLogFont->lfEscapement = lpLogFont->lfOrientation = 0;
 		lpLogFont->lfWeight = FW_NORMAL;
@@ -787,6 +829,7 @@
 
 		    SystemParametersInfo32A(SPI_GETICONTITLELOGFONT, 0,
 							(LPVOID)&(lpnm->lfCaptionFont),0);
+		    lpnm->lfCaptionFont.lfWeight = FW_BOLD;
 		    SystemParametersInfo32A(SPI_GETICONTITLELOGFONT, 0,
 							(LPVOID)&(lpnm->lfMenuFont),0);
 		    SystemParametersInfo32A(SPI_GETICONTITLELOGFONT, 0,
@@ -975,7 +1018,6 @@
 		    GetProfileString32A("Desktop", "IconTitleFaceName", "MS Sans Serif", 
 					lpLogFont->lfFaceName, LF_FACESIZE );
                     lpLogFont->lfHeight = -GetProfileInt32A("Desktop","IconTitleSize", 8);
-
                     lpLogFont->lfWidth = 0;
                     lpLogFont->lfEscapement = lpLogFont->lfOrientation = 0;
                     lpLogFont->lfWeight = FW_NORMAL;
@@ -996,6 +1038,7 @@
 			/* FIXME: initialize geometry entries */
 			SystemParametersInfo16( SPI_GETICONTITLELOGFONT, 0, 
 							(LPVOID)&(lpnm->lfCaptionFont),0);
+			lpnm->lfCaptionFont.lfWeight = FW_BOLD;
 			SystemParametersInfo16( SPI_GETICONTITLELOGFONT, 0,
 							(LPVOID)&(lpnm->lfMenuFont),0);
 			SystemParametersInfo16( SPI_GETICONTITLELOGFONT, 0,
@@ -1085,6 +1128,7 @@
 	LPNONCLIENTMETRICS32W	lpnm=(LPNONCLIENTMETRICS32W)lpvParam;
 
 	SystemParametersInfo32W(SPI_GETICONTITLELOGFONT,0,(LPVOID)&(lpnm->lfCaptionFont),0);
+	lpnm->lfCaptionFont.lfWeight = FW_BOLD;
 	SystemParametersInfo32W(SPI_GETICONTITLELOGFONT,0,(LPVOID)&(lpnm->lfMenuFont),0);
 	SystemParametersInfo32W(SPI_GETICONTITLELOGFONT,0,(LPVOID)&(lpnm->lfStatusFont),0);
 	SystemParametersInfo32W(SPI_GETICONTITLELOGFONT,0,(LPVOID)&(lpnm->lfMessageFont),0);
diff --git a/misc/network.c b/misc/network.c
index 7936383..a0eedad 100644
--- a/misc/network.c
+++ b/misc/network.c
@@ -281,6 +281,22 @@
 	return ret;
 }
 
+/**************************************************************************
+ *				WNetGetConnectionW	[MPR.72]
+ */
+DWORD WINAPI
+WNetGetConnection32W(LPCWSTR localnameW,LPSTR remotenameW,LPDWORD buflen)
+{
+	UINT16	x;
+	CHAR	buf[200];	
+	LPSTR	lnA = HEAP_strdupWtoA(GetProcessHeap(),0,localnameW);
+	DWORD	ret = WNetGetConnection16(lnA,buf,&x);
+
+	*buflen = x; /* FIXME: *2 ? */
+	lstrcpyAtoW(remotenameW,buf);
+	HeapFree(GetProcessHeap(),0,lnA);
+	return ret;
+}
 
 /**************************************************************************
  *				WNetGetCaps		[USER.513]
@@ -508,11 +524,11 @@
 /**************************************************************************
  *              WNetGetPropertyText       [USER.532]
  */
-int WINAPI WNetGetPropertyText(HWND16 hwndParent,WORD iButton,WORD nPropSel,
-                               LPSTR lpszName,WORD nType)
+int WINAPI WNetGetPropertyText(WORD iButton, WORD nPropSel, LPSTR lpszName,
+                          LPSTR lpszButtonName, WORD cbButtonName, WORD nType)
 {
-	FIXME(wnet, "(%04x,%x,%x,'%s',%x): stub\n",
-	      hwndParent,iButton,nPropSel,lpszName,nType);
+	FIXME(wnet, "(%04x,%04x,'%s','%s',%04x): stub\n",
+	      iButton,nPropSel,lpszName,lpszButtonName, nType);
 	return WN_NO_NETWORK;
 }
 
diff --git a/misc/ntdll.c b/misc/ntdll.c
index 21efb50..d265d92 100644
--- a/misc/ntdll.c
+++ b/misc/ntdll.c
@@ -332,7 +332,7 @@
 }
 
 /**************************************************************************
- *                 RtlInitString			[NTDLL]
+ *                 RtlInitAnsiString			[NTDLL]
  */
 VOID WINAPI RtlInitAnsiString(LPANSI_STRING target,LPCSTR source)
 {
@@ -429,7 +429,7 @@
  */
 DWORD WINAPI RtlNtStatusToDosError(DWORD error)
 {
-    FIXME(ntdll, "(%x): map STATUS_ to ERROR_\n",error);
+    FIXME(ntdll, "(%lx): map STATUS_ to ERROR_\n",error);
     return error;
 }
 
@@ -556,6 +556,9 @@
 
 /**************************************************************************
  *                 NTDLL_chkstk   (NTDLL.862)
+ *
+ * NOTES
+ *    Should this be WINAPI?
  */
 void NTDLL_chkstk(void)
 {
@@ -574,12 +577,13 @@
 }
 
 
-/**************************************************************************
+/******************************************************************************
  * NtQueryDirectoryObject [NTDLL.149]
  */
-DWORD WINAPI NtQueryDirectoryObject(DWORD x1, DWORD x2)
+DWORD WINAPI NtQueryDirectoryObject( DWORD x1, DWORD x2, DWORD x3, DWORD x4,
+                                     DWORD x5, DWORD x6, DWORD x7 )
 {
-    FIXME(ntdll,"(%lx,%lx): stub\n",x1,x2);
+    FIXME(ntdll,"(%lx,%lx,%lx,%lx,%lx,%lx,%lx): stub\n",x1,x2,x3,x4,x5,x6,x7);
     return 0;
 }
 
@@ -587,19 +591,19 @@
 /**************************************************************************
  * RtlFreeAnsiString [NTDLL.373]
  */
-DWORD WINAPI RtlFreeAnsiString(DWORD x1)
+VOID WINAPI RtlFreeAnsiString(LPANSI_STRING AnsiString)
 {
-    FIXME(ntdll,"(%lx): stub\n",x1);
-    return 0;
+    if( AnsiString->Buffer )
+        HeapFree( GetProcessHeap(),0,AnsiString->Buffer );
 }
 
 
-/**************************************************************************
+/******************************************************************************
  * NtQuerySystemInformation [NTDLL.168]
  */
-DWORD WINAPI NtQuerySystemInformation( DWORD x1 )
+DWORD WINAPI NtQuerySystemInformation( DWORD x1, DWORD x2, DWORD x3, DWORD x4 )
 {
-    FIXME(ntdll,"(%lx): stub\n",x1);
+    FIXME(ntdll,"(%lx,%lx,%lx,%lx): stub\n",x1,x2,x3,x4);
     return 0;
 }
 
@@ -607,9 +611,9 @@
 /******************************************************************************
  * NtQueryObject [NTDLL.161]
  */
-DWORD WINAPI NtQueryObject( DWORD x1, DWORD x2 )
+DWORD WINAPI NtQueryObject( DWORD x1, DWORD x2 ,DWORD x3, DWORD x4, DWORD x5 )
 {
-    FIXME(ntdll,"(%lx,%lx): stub\n",x1,x2);
+    FIXME(ntdll,"(%lx,%lx,%lx,%lx,%lx): stub\n",x1,x2,x3,x4,x5);
     return 0;
 }
 
@@ -617,9 +621,9 @@
 /******************************************************************************
  * RtlTimeToElapsedTimeFields [NTDLL.502]
  */
-DWORD WINAPI RtlTimeToElapsedTimeFields( DWORD x1 )
+DWORD WINAPI RtlTimeToElapsedTimeFields( DWORD x1, DWORD x2 )
 {
-    FIXME(ntdll,"(%lx): stub\n",x1);
+    FIXME(ntdll,"(%lx,%lx): stub\n",x1,x2);
     return 0;
 }
 
@@ -627,10 +631,52 @@
 /******************************************************************************
  * NtSetInformationProcess [NTDLL.207]
  */
-DWORD WINAPI NtSetInformationProcess( DWORD x1 )
+DWORD WINAPI NtSetInformationProcess( DWORD x1, DWORD x2, DWORD x3, DWORD x4 )
 {
-    FIXME(ntdll,"(%lx): stub\n",x1);
+    FIXME(ntdll,"(%lx,%lx,%lx,%lx): stub\n",x1,x2,x3,x4);
     return 0;
 }
 
+/******************************************************************************
+ * NtFsControlFile [NTDLL.108]
+ */
+VOID WINAPI NtFsControlFile(VOID)
+{
+    FIXME(ntdll,"(void): stub\n");
+}
 
+/******************************************************************************
+ * RtlExtendedLargeIntegerDivide [NTDLL.359]
+ */
+INT32 WINAPI RtlExtendedLargeIntegerDivide(
+	LARGE_INTEGER dividend,
+	DWORD divisor,
+	LPDWORD rest
+) {
+#if SIZEOF_LONG_LONG==8
+	long long x1 = *(long long*)&dividend;
+
+	if (*rest)
+		*rest = x1 % divisor;
+	return x1/divisor;
+#else
+	FIXME(ntdll,"((%d<<32)+%d,%d,%p), implement this using normal integer arithmetic!\n",dividend.HighPart,dividend.LowPart,divisor,rest);
+	return 0;
+#endif
+}
+
+/******************************************************************************
+ * RtlExtendedLargeIntegerMultiply [NTDLL.359]
+ * Note: This even works, since gcc returns 64bit values in eax/edx just like
+ * the caller expects. However... The relay code won't grok this I think.
+ */
+long long /*LARGE_INTEGER*/ WINAPI RtlExtendedIntegerMultiply(
+	LARGE_INTEGER factor1,INT32 factor2
+) {
+#if SIZEOF_LONG_LONG==8
+	return (*(long long*)&factor1)*factor2;
+#else
+	FIXME(ntdll,"((%d<<32)+%d,%ld), implement this using normal integer arithmetic!\n",factor1.HighPart,factor1.LowPart,factor2);
+	return 0;
+#endif
+}
diff --git a/misc/printdrv.c b/misc/printdrv.c
index 20c2207..37a1748 100644
--- a/misc/printdrv.c
+++ b/misc/printdrv.c
@@ -10,8 +10,17 @@
 #include "windows.h"
 #include "win.h"
 #include "winerror.h"
+#include "winreg.h"
 #include "debug.h"
 
+#define INT_PD_DEFAULT_DEVMODE	1
+#define INT_PD_DEFAULT_MODEL	2
+
+static char PrinterModel[]	= "Printer Model";
+static char DefaultDevMode[]	= "Default DevMode";
+static char PrinterDriverData[] = "PrinterDriverData";
+static char Printers[]		= "System\\CurrentControlSet\\Control\\Print\\Printers\\";
+
 INT16 WINAPI StartDoc16( HDC16 hdc, const DOCINFO16 *lpdoc )
 {
   INT16 retVal;
@@ -32,42 +41,172 @@
   return  Escape16(hdc, ENDDOC, 0, 0, 0);
 }
 
+WORD DrvGetPrinterDataInternal(LPSTR RegStr_Printer, LPBYTE lpPrinterData, int cbData)
+{
+    WORD res = -1;
+    HKEY hkey;
+    DWORD dwType, cbQueryData;
+
+    if (!(RegOpenKey32A(HKEY_LOCAL_MACHINE, RegStr_Printer, &hkey))) {
+        if (cbData > 1) { /* "Default DevMode" */
+            if (!(RegQueryValueEx32A(hkey, DefaultDevMode, 0, &dwType, 0, &cbQueryData))) {
+                if (!lpPrinterData) res = cbQueryData;
+		else
+		if ((cbQueryData) && (cbQueryData <= cbData)) {
+		    cbQueryData = cbData;
+		    if (RegQueryValueEx32A(hkey, DefaultDevMode, 0,
+				&dwType, lpPrinterData, &cbQueryData))
+		        res = cbQueryData;
+		}
+            }
+            else /* "Printer Driver" */
+	    {
+		cbQueryData = 32;
+	        RegQueryValueEx32A(hkey, "Printer Driver", 0,
+			&dwType, lpPrinterData, &cbQueryData);
+		res = cbQueryData;
+	    }
+	}
+    }
+    if (hkey) RegCloseKey(hkey);
+    return res;
+}
 
 
 DWORD WINAPI DrvGetPrinterData(LPSTR lpPrinter, LPSTR lpProfile,
                                LPDWORD lpType, LPBYTE lpPrinterData,
                                int cbData, LPDWORD lpNeeded)
 {
-    FIXME(print, "stub.\n");
+    LPSTR RegStr_Printer;
+    HKEY hkey = 0, hkey2 = 0;
+    DWORD res = 0;
+    DWORD dwType, PrinterAttr, cbPrinterAttr, SetData, size;
+
     if (HIWORD(lpPrinter))
-	    TRACE(print,"printer %s\n",lpPrinter);
+            TRACE(print,"printer %s\n",lpPrinter);
     else
-	    TRACE(print,"printer %p\n",lpPrinter);
+            TRACE(print,"printer %p\n",lpPrinter);
     if (HIWORD(lpProfile))
-	    TRACE(print,"profile %s\n",lpProfile);
+            TRACE(print,"profile %s\n",lpProfile);
     else
-	    TRACE(print,"profile %p\n",lpProfile);
+            TRACE(print,"profile %p\n",lpProfile);
     TRACE(print,"lpType %p\n",lpType);
-    return 0;
+
+    if ((!lpPrinter) || (!lpProfile) || (!lpNeeded))
+	return ERROR_INVALID_PARAMETER;
+
+    RegStr_Printer = HeapAlloc(GetProcessHeap(), 0,
+                               strlen(Printers) + strlen(lpPrinter) + 2);
+    strcpy(RegStr_Printer, Printers);
+    strcat(RegStr_Printer, lpPrinter);
+
+    if (((DWORD)lpProfile == INT_PD_DEFAULT_DEVMODE) ||
+    (!lstrcmp32A(lpProfile, DefaultDevMode))) {
+	size = DrvGetPrinterDataInternal(RegStr_Printer, lpPrinterData, cbData);
+	if (size+1) {
+	    *lpNeeded = size;
+	    if ((lpPrinterData) && (*lpNeeded > cbData))
+		res = ERROR_MORE_DATA;
+	}
+	else res = ERROR_INVALID_PRINTER_NAME;
+    }
+    else
+    if (((DWORD)lpProfile == INT_PD_DEFAULT_MODEL) ||
+    (!lstrcmp32A(lpProfile, PrinterModel))) {
+	*lpNeeded = 32;
+	if (!lpPrinterData) goto failed;
+	if (cbData < 32) {
+	    res = ERROR_MORE_DATA;
+	    goto failed;
+	}
+	size = DrvGetPrinterDataInternal(RegStr_Printer, lpPrinterData, 1);
+	if ((size+1) && (lpType))
+	    *lpType = REG_SZ;
+	else
+	    res = ERROR_INVALID_PRINTER_NAME;
+    }
+    else
+    {
+	if ((res = RegOpenKey32A(HKEY_LOCAL_MACHINE, RegStr_Printer, &hkey)))
+	    goto failed;
+        cbPrinterAttr = 4;
+	if ((res = RegQueryValueEx32A(hkey, "Attributes", 0, &dwType, (LPBYTE)&PrinterAttr, &cbPrinterAttr)))
+	    goto failed;
+	if ((res = RegOpenKey32A(hkey, PrinterDriverData, &hkey2)))
+	    goto failed;
+        *lpNeeded = cbData;
+	res = RegQueryValueEx32A(hkey2, lpProfile, 0, lpType, lpPrinterData, lpNeeded);
+	if ((res != ERROR_CANTREAD) && ((PrinterAttr & (0x800|0x10)) == 0x10))
+        {
+	    if (!(res) && (*lpType == REG_DWORD) && (*(LPDWORD)lpPrinterData == -1))
+	        res = ERROR_INVALID_DATA;
+	}
+	else
+        {
+	    SetData = -1;
+	    RegSetValueEx32A(hkey2, lpProfile, 0, REG_DWORD, (LPBYTE)&SetData, 4); /* no result returned */
+	}
+    }
+	
+failed:
+    if (hkey2) RegCloseKey(hkey2);
+    if (hkey) RegCloseKey(hkey);
+    HeapFree(GetProcessHeap(), 0, RegStr_Printer);
+    return res;
 }
 
 
 
 DWORD WINAPI DrvSetPrinterData(LPSTR lpPrinter, LPSTR lpProfile,
-                               LPDWORD lpType, LPBYTE lpPrinterData,
+                               DWORD lpType, LPBYTE lpPrinterData,
                                DWORD dwSize)
 {
-    FIXME(print, "stub.\n");
+    LPSTR RegStr_Printer;
+    HKEY hkey = 0;
+    DWORD res = 0;
+
     if (HIWORD(lpPrinter))
-	    TRACE(print,"printer %s\n",lpPrinter);
+            TRACE(print,"printer %s\n",lpPrinter);
     else
-	    TRACE(print,"printer %p\n",lpPrinter);
+            TRACE(print,"printer %p\n",lpPrinter);
     if (HIWORD(lpProfile))
-	    TRACE(print,"profile %s\n",lpProfile);
+            TRACE(print,"profile %s\n",lpProfile);
     else
-	    TRACE(print,"profile %p\n",lpProfile);
-    TRACE(print,"lpType %p\n",lpType);
-    return 0;
+            TRACE(print,"profile %p\n",lpProfile);
+    TRACE(print,"lpType %08lx\n",lpType);
+
+    if ((!lpPrinter) || (!lpProfile) ||
+    ((DWORD)lpProfile == INT_PD_DEFAULT_MODEL) ||
+    (!lstrcmp32A(lpProfile, PrinterModel)))
+	return ERROR_INVALID_PARAMETER;
+
+    RegStr_Printer = HeapAlloc(GetProcessHeap(), 0,
+			strlen(Printers) + strlen(lpPrinter) + 2);
+    strcpy(RegStr_Printer, Printers);
+    strcat(RegStr_Printer, lpPrinter);
+
+    if (((DWORD)lpProfile == INT_PD_DEFAULT_DEVMODE) ||
+    (!lstrcmp32A(lpProfile, DefaultDevMode))) {
+	if (!(RegOpenKey32A(HKEY_LOCAL_MACHINE, RegStr_Printer, &hkey)) ||
+	    (RegSetValueEx32A(hkey, DefaultDevMode, 0, REG_BINARY, lpPrinterData, dwSize)))
+	        res = ERROR_INVALID_PRINTER_NAME;
+    }
+    else
+    {
+	strcat(RegStr_Printer, "\\");
+
+	if (!(res = RegOpenKey32A(HKEY_LOCAL_MACHINE, RegStr_Printer, &hkey))) {
+
+	    if (!lpPrinterData) 
+	        res = RegDeleteValue32A(hkey, lpProfile);
+	    else
+                res = RegSetValueEx32A(hkey, lpProfile, 0, lpType, lpPrinterData, dwSize);
+	}
+    }
+
+    if (hkey) RegCloseKey(hkey);
+    HeapFree(GetProcessHeap(), 0, RegStr_Printer);
+    return res;
 }
 
 
@@ -105,9 +244,39 @@
     *lpdwReturned=0;
     return TRUE;
 }
+
+
 BOOL32 WINAPI AddMonitor32A(LPCSTR pName, DWORD Level, LPBYTE pMonitors)
 {
     FIXME(print, "(%s,%lx,%p):stub!\n", pName, Level, pMonitors);
     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     return FALSE;
 }
+
+
+BOOL32 WINAPI
+DeletePrinterDriver32A (LPSTR pName, LPSTR pEnvironment, LPSTR pDriverName)
+{
+    FIXME(print, "(%s,%s,%s):stub!\n", pName, pEnvironment, pDriverName);
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+
+BOOL32 WINAPI
+DeleteMonitor32A (LPSTR pName, LPSTR pEnvironment, LPSTR pMonitorName)
+{
+    FIXME(print, "(%s,%s,%s):stub!\n", pName, pEnvironment, pMonitorName);
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+
+BOOL32 WINAPI
+DeletePort32A (LPSTR pName, HWND32 hWnd, LPSTR pPortName)
+{
+    FIXME(print, "(%s,0x%08x,%s):stub!\n", pName, hWnd, pPortName);
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
diff --git a/misc/registry.c b/misc/registry.c
index 55307e5..01b7498 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -2,21 +2,19 @@
  * 	Registry Functions
  *
  * Copyright 1996 Marcus Meissner
+ * Copyright 1998 Matthew Becker
  *
  * 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
+ *    Option handling
  */
 
 #include <stdlib.h>
@@ -93,8 +91,18 @@
 #define UNICONVMASK	((1<<REG_SZ)|(1<<REG_MULTI_SZ)|(1<<REG_EXPAND_SZ))
 
 
+static struct openhandle {
+	LPKEYSTRUCT	lpkey;
+	HKEY		hkey;
+	REGSAM		accessmask;
+}  *openhandles=NULL;
+static int	nrofopenhandles=0;
+/* Starts after 1 because 0,1 are reserved for Win16 */
+static int	currenthandle=1;
+
+
 /*
- * FIXME
+ * QUESTION
  *   Are these doing the same as HEAP_strdupAtoW and HEAP_strdupWtoA?
  *   If so, can we remove them?
  * ANSWER
@@ -104,30 +112,59 @@
  */
 static LPWSTR strdupA2W(LPCSTR src)
 {
+    if(src) {
 	LPWSTR dest=xmalloc(2*strlen(src)+2);
 	lstrcpyAtoW(dest,src);
 	return dest;
+    }
+    return NULL;
 }
 
 static LPWSTR strdupW(LPCWSTR a) {
 	LPWSTR	b;
 	int	len;
 
+    if(a) {
 	len=sizeof(WCHAR)*(lstrlen32W(a)+1);
 	b=(LPWSTR)xmalloc(len);
 	memcpy(b,a,len);
 	return b;
+    }
+    return NULL;
+}
+
+LPWSTR strcvtA2W(LPCSTR src, int nchars)
+
+{
+   LPWSTR dest = xmalloc (2 * nchars + 2);
+
+   lstrcpynAtoW(dest,src,nchars+1);
+   dest[nchars] = 0;
+   return dest;
 }
 
 
-static struct openhandle {
-	LPKEYSTRUCT	lpkey;
-	HKEY		hkey;
-	REGSAM		accessmask;
-}  *openhandles=NULL;
-static int	nrofopenhandles=0;
-static int	currenthandle=1;
-
+/******************************************************************************
+ * is_standard_hkey [Internal]
+ * Determines if a hkey is a standard key
+ */
+static BOOL32 is_standard_hkey( HKEY hkey )
+{
+    switch(hkey) {
+        case 0x00000000:
+        case 0x00000001:
+        case HKEY_CLASSES_ROOT:
+        case HKEY_CURRENT_CONFIG:
+        case HKEY_CURRENT_USER:
+        case HKEY_LOCAL_MACHINE:
+        case HKEY_USERS:
+        case HKEY_PERFORMANCE_DATA:
+        case HKEY_DYN_DATA:
+            return TRUE;
+        default:
+            return FALSE;
+    }
+}
 
 /******************************************************************************
  * add_handle [Internal]
@@ -137,9 +174,6 @@
     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) {
@@ -212,7 +246,6 @@
     return ERROR_SUCCESS;
 }
 
-
 /******************************************************************************
  * lookup_hkey [Internal]
  * 
@@ -431,8 +464,12 @@
  * [HKEY_CURRENT_USER\\Software\\The WINE team\\WINE\\Registry]
  * SaveOnlyUpdatedKeys=yes
  */
-static int
-_save_check_tainted(LPKEYSTRUCT lpkey) {
+
+/******************************************************************************
+ * _save_check_tainted [Internal]
+ */
+static int _save_check_tainted( LPKEYSTRUCT lpkey )
+{
 	int		tainted;
 
 	if (!lpkey)
@@ -451,8 +488,11 @@
 	return tainted;
 }
 
-static void
-_save_USTRING(FILE *F,LPWSTR wstr,int escapeeq) {
+/******************************************************************************
+ * _save_USTRING [Internal]
+ */
+static void _save_USTRING( FILE *F, LPWSTR wstr, int escapeeq )
+{
 	LPWSTR	s;
 	int	doescape;
 
@@ -477,8 +517,11 @@
 	}
 }
 
-static int
-_savesubkey(FILE *F,LPKEYSTRUCT lpkey,int level,int all) {
+/******************************************************************************
+ * _savesubkey [Internal]
+ */
+static int _savesubkey( FILE *F, LPKEYSTRUCT lpkey, int level, int all )
+{
 	LPKEYSTRUCT	lpxkey;
 	int		i,tabs,j;
 
@@ -515,15 +558,23 @@
 	return 1;
 }
 
-static int
-_savesubreg(FILE *F,LPKEYSTRUCT lpkey,int all) {
+
+/******************************************************************************
+ * _savesubreg [Internal]
+ */
+static int _savesubreg( FILE *F, LPKEYSTRUCT lpkey, int all )
+{
 	fprintf(F,"WINE REGISTRY Version %d\n",REGISTRY_SAVE_VERSION);
 	_save_check_tainted(lpkey->nextsub);
 	return _savesubkey(F,lpkey->nextsub,0,all);
 }
 
-static BOOL32
-_savereg(LPKEYSTRUCT lpkey,char *fn,int all) {
+
+/******************************************************************************
+ * _savereg [Internal]
+ */
+static BOOL32 _savereg( LPKEYSTRUCT lpkey, char *fn, int all )
+{
 	FILE	*F;
 
 	F=fopen(fn,"w");
@@ -617,9 +668,11 @@
 		WARN(reg,"Failed to get homedirectory of UID %d.\n",getuid());
 }
 
+
 /************************ LOAD Registry Function ****************************/
 
 
+
 /******************************************************************************
  * _find_or_add_key [Internal]
  */
@@ -649,11 +702,12 @@
 	return lpxkey;
 }
 
-static void
-_find_or_add_value(
-	LPKEYSTRUCT lpkey,LPWSTR name,DWORD type,LPBYTE data,DWORD len,
-	DWORD lastmodified
-) {
+/******************************************************************************
+ * _find_or_add_value [Internal]
+ */
+static void _find_or_add_value( LPKEYSTRUCT lpkey, LPWSTR name, DWORD type,
+                                LPBYTE data, DWORD len, DWORD lastmodified )
+{
 	LPKEYVALUE	val=NULL;
 	int		i;
 
@@ -698,11 +752,14 @@
 }
 
 
-/* reads a line including dynamically enlarging the readbuffer and throwing
+/******************************************************************************
+ * _wine_read_line [Internal]
+ *
+ * reads a line including dynamically enlarging the readbuffer and throwing
  * away comments
  */
-static int 
-_wine_read_line(FILE *F,char **buf,int *len) {
+static int _wine_read_line( FILE *F, char **buf, int *len )
+{
 	char	*s,*curread;
 	int	mylen,curoff;
 
@@ -740,11 +797,15 @@
 	return 1;
 }
 
-/* converts a char* into a UNICODE string (up to a special char)
+
+/******************************************************************************
+ * _wine_read_USTRING [Internal]
+ *
+ * converts a char* into a UNICODE string (up to a special char)
  * and returns the position exactly after that string
  */
-static char*
-_wine_read_USTRING(char *buf,LPWSTR *str) {
+static char* _wine_read_USTRING( char *buf, LPWSTR *str )
+{
 	char	*s;
 	LPWSTR	ws;
 
@@ -1114,16 +1175,6 @@
   int  lastmodified;
 };
 
-LPWSTR strcvtA2W(LPCSTR src, int nchars)
-
-{
-   LPWSTR dest = xmalloc (2 * nchars + 2);
-
-   lstrcpynAtoW(dest,src,nchars+1);
-   dest[nchars] = 0;
-   return dest;
-}
-
 
 /******************************************************************************
  * _w95_processKey [Internal]
@@ -1239,8 +1290,11 @@
 	return (lpxkey);
 }
 
-static void
-_w95_walkrgkn(LPKEYSTRUCT prevkey, char *off, struct _w95_info *info)
+/******************************************************************************
+ * _w95_walkrgkn [Internal]
+ */
+static void _w95_walkrgkn( LPKEYSTRUCT prevkey, char *off, 
+                           struct _w95_info *info )
 
 {
   /* Disk Key Entry structure (RGKN part) */
@@ -1286,8 +1340,12 @@
   return;
 }
 
-static void
-_w95_loadreg(char* fn,LPKEYSTRUCT lpkey) {
+
+/******************************************************************************
+ * _w95_loadreg [Internal]
+ */
+static void _w95_loadreg( char* fn, LPKEYSTRUCT lpkey )
+{
 	HFILE32		hfd;
 	char		magic[5];
 	unsigned long	where,version,rgdbsection,end;
@@ -1644,8 +1702,6 @@
  * All functions are stubs to RegOpenKeyEx32W where all the
  * magic happens. 
  *
- * FIXME: security,options,desiredaccess,...
- *
  * Callpath:
  * RegOpenKey16 -> RegOpenKey32A -> RegOpenKeyEx32A \
  *                                  RegOpenKey32W   -> RegOpenKeyEx32W 
@@ -1679,11 +1735,9 @@
     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);
+    lpNextKey = lookup_hkey( hkey );
+    if (!lpNextKey)
         return ERROR_INVALID_HANDLE;
-    }
 
     if (!lpszSubKey || !*lpszSubKey) {
         /* Either NULL or pointer to empty string, so return a new handle
@@ -1693,6 +1747,11 @@
         return ERROR_SUCCESS;
     }
 
+    if (lpszSubKey[0] == '\\') {
+        WARN(reg,"Subkey %s must not begin with backslash.\n",debugstr_w(lpszSubKey));
+        return ERROR_BAD_PATHNAME;
+    }
+
 	split_keypath(lpszSubKey,&wps,&wpc);
 	i = 0;
 	while ((i<wpc) && (wps[i][0]=='\0')) i++;
@@ -1710,7 +1769,7 @@
         if (!lpxkey) {
             TRACE(reg,"Could not find subkey %s\n",debugstr_w(wps[i]));
             FREE_KEY_PATH;
-            return ERROR_BADKEY;
+            return ERROR_FILE_NOT_FOUND;
         }
         i++;
         lpNextKey = lpxkey;
@@ -1725,40 +1784,52 @@
 
 
 /******************************************************************************
- * 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);
-}
-
-
-/******************************************************************************
  * RegOpenKeyEx32A [ADVAPI32.149]
  */
 DWORD WINAPI RegOpenKeyEx32A( HKEY hkey, LPCSTR lpszSubKey, DWORD dwReserved,
                               REGSAM samDesired, LPHKEY retkey )
 {
-    LPWSTR lpszSubKeyW = HEAP_strdupAtoW(GetProcessHeap(),0,lpszSubKey);
+    LPWSTR lpszSubKeyW = strdupA2W(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);
+    ret = RegOpenKeyEx32W( hkey, lpszSubKeyW, dwReserved, samDesired, retkey );
+    free(lpszSubKeyW);
     return ret;
 }
 
 
 /******************************************************************************
+ * RegOpenKey32W [ADVAPI32.151]
+ *
+ * PARAMS
+ *    hkey       [I] Handle of open key
+ *    lpszSubKey [I] Address of name of subkey to open
+ *    retkey     [O] Address of handle of open key
+ *
+ * RETURNS
+ *    Success: ERROR_SUCCESS
+ *    Failure: Error code
+ */
+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 );
+}
+
+
+/******************************************************************************
  * RegOpenKey32A [ADVAPI32.148]
  */
 DWORD WINAPI RegOpenKey32A( HKEY hkey, LPCSTR lpszSubKey, LPHKEY retkey )
 {
+    DWORD ret;
+    LPWSTR lpszSubKeyW = strdupA2W(lpszSubKey);
     TRACE(reg,"(%x,%s,%p)\n",hkey,debugstr_a(lpszSubKey),retkey);
-    return RegOpenKeyEx32A(hkey,lpszSubKey,0,KEY_ALL_ACCESS,retkey);
+    ret =  RegOpenKey32W( hkey, lpszSubKeyW, retkey );
+    free(lpszSubKeyW);
+    return ret;
 }
 
 
@@ -1768,7 +1839,7 @@
 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);
+    return RegOpenKey32A( hkey, lpszSubKey, retkey );
 }
 
 
@@ -1778,11 +1849,12 @@
  * All those functions convert their respective 
  * arguments and call RegCreateKeyExW at the end.
  *
- * FIXME: no security,no access attrib,no optionhandling yet.
+ * We stay away from the Ex functions as long as possible because there are
+ * differences in the return values
  *
  * Callpath:
- * RegCreateKey16 -> RegCreateKey32A -> RegCreateKeyEx32A \
- *                                      RegCreateKey32W   -> RegCreateKeyEx32W
+ *                                      RegCreateKeyEx32A \
+ * RegCreateKey16 -> RegCreateKey32A -> RegCreateKey32W   -> RegCreateKeyEx32W
  */
 
 
@@ -1790,9 +1862,15 @@
  * RegCreateKeyEx32W [ADVAPI32.131]
  *
  * PARAMS
- *    ...
- *    retkey   [O] Address of buffer for opened handle
- *    lpDispos [O] Receives REG_CREATED_NEW_KEY or REG_OPENED_EXISTING_KEY
+ *    hkey         [I] Handle of an open key
+ *    lpszSubKey   [I] Address of subkey name
+ *    dwReserved   [I] Reserved - must be 0
+ *    lpszClass    [I] Address of class string
+ *    fdwOptions   [I] Special options flag
+ *    samDesired   [I] Desired security access
+ *    lpSecAttribs [I] Address of key security structure
+ *    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, 
@@ -1804,15 +1882,30 @@
 	LPWSTR		*wps;
 	int		wpc,i;
 
-    /*FIXME: handle security/access/whatever */
-
     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;
+        return ERROR_INVALID_HANDLE;
+
+    /* Check for valid options */
+    switch(fdwOptions) {
+        case REG_OPTION_NON_VOLATILE:
+        case REG_OPTION_VOLATILE:
+        case REG_OPTION_BACKUP_RESTORE:
+            break;
+        default:
+            return ERROR_INVALID_PARAMETER;
+    }
+
+    /* Sam has to be a combination of the following */
+    if (!(samDesired & 
+          (KEY_ALL_ACCESS | KEY_CREATE_LINK | KEY_CREATE_SUB_KEY | 
+           KEY_ENUMERATE_SUB_KEYS | KEY_EXECUTE | KEY_NOTIFY |
+           KEY_QUERY_VALUE | KEY_READ | KEY_SET_VALUE | KEY_WRITE)))
+        return ERROR_INVALID_PARAMETER;
 
 	if (!lpszSubKey || !*lpszSubKey) {
 		add_handle(++currenthandle,lpNextKey,samDesired);
@@ -1901,20 +1994,6 @@
 
 
 /******************************************************************************
- * 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);
-}
-
-
-/******************************************************************************
  * RegCreateKeyEx32A [ADVAPI32.130]
  */
 DWORD WINAPI RegCreateKeyEx32A( HKEY hkey, LPCSTR lpszSubKey, DWORD dwReserved,
@@ -1930,51 +2009,55 @@
           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;
+    lpszSubKeyW = lpszSubKey?strdupA2W(lpszSubKey):NULL;
+    lpszClassW = lpszClass?strdupA2W(lpszClass):NULL;
+
     ret = RegCreateKeyEx32W( hkey, lpszSubKeyW, dwReserved, lpszClassW, 
                              fdwOptions, samDesired, lpSecAttribs, retkey, 
                              lpDispos );
-    HeapFree(GetProcessHeap(),0,lpszSubKeyW);
-/*
-	if (lpszSubKeyW)
-		free(lpszSubKeyW);
-*/
-	if (lpszClassW)
-		free(lpszClassW);
+
+    if(lpszSubKeyW) free(lpszSubKeyW);
+    if(lpszClassW) free(lpszClassW);
+
     return ret;
 }
 
 
 /******************************************************************************
+ * RegCreateKey32W [ADVAPI32.132]
+ */
+DWORD WINAPI RegCreateKey32W( HKEY hkey, LPCWSTR lpszSubKey, LPHKEY retkey )
+{
+    DWORD junk;
+    LPKEYSTRUCT	lpNextKey;
+
+    TRACE(reg,"(%x,%s,%p)\n", hkey,debugstr_w(lpszSubKey),retkey);
+
+    /* This check is here because the return value is different than the
+       one from the Ex functions */
+    lpNextKey = lookup_hkey(hkey);
+    if (!lpNextKey)
+        return ERROR_BADKEY;
+
+    return RegCreateKeyEx32W( hkey, lpszSubKey, 0, NULL, 
+                              REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
+                              retkey, &junk);
+}
+
+
+/******************************************************************************
  * RegCreateKey32A [ADVAPI32.129]
  */
 DWORD WINAPI RegCreateKey32A( HKEY hkey, LPCSTR lpszSubKey, LPHKEY retkey )
 {
-    DWORD junk;
+    DWORD ret;
+    LPWSTR lpszSubKeyW;
 
     TRACE(reg,"(%x,%s,%p)\n",hkey,debugstr_a(lpszSubKey),retkey);
-
-	return	RegCreateKeyEx32A(
-		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 */
-	);
+    lpszSubKeyW = lpszSubKey?strdupA2W(lpszSubKey):NULL;
+    ret = RegCreateKey32W( hkey, lpszSubKeyW, retkey );
+    if(lpszSubKeyW) free(lpszSubKeyW);
+    return ret;
 }
 
 
@@ -2030,10 +2113,12 @@
           lpdwReserved, lpdwType, lpbData, lpcbData?*lpcbData:0);
 
     lpkey = lookup_hkey(hkey);
-    if (!lpkey) {
-        TRACE(reg, "Invalid handle(%x)\n",hkey);
+    if (!lpkey)
         return ERROR_INVALID_HANDLE;
-    }
+
+    /* Reserved must be NULL (at least for now) */
+    if (lpdwReserved)
+        return ERROR_INVALID_PARAMETER;
 
     /* An empty name string is equivalent to NULL */
     if (lpValueName && !*lpValueName)
@@ -2066,7 +2151,7 @@
                         TRACE(reg, "Returning an empty string\n");
 			return ERROR_SUCCESS;
 		}
-		return ERROR_BADKEY; /* FIXME */
+		return ERROR_BAD_PATHNAME;
 	}
 
     if (lpdwType)
@@ -2122,9 +2207,6 @@
 
 /******************************************************************************
  * RegQueryValue32W [ADVAPI32.159]
- *
- * NOTES
- *    Why is this calling RegOpenKey32W?
  */
 DWORD WINAPI RegQueryValue32W( HKEY hkey, LPWSTR lpszSubKey, LPWSTR lpszData,
                                LPDWORD lpcbData )
@@ -2135,33 +2217,27 @@
     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) {
-		ret	= RegOpenKey32W(hkey,lpszSubKey,&xhkey);
-		if (ret!=ERROR_SUCCESS)
-			return ret;
-	} else
-		xhkey	= hkey;
+    /* Only open subkey, if we really do descend */
+    if (lpszSubKey && *lpszSubKey) {
+        ret = RegOpenKey32W( hkey, lpszSubKey, &xhkey );
+        if (ret != ERROR_SUCCESS) {
+            WARN(reg, "Could not open %s\n", debugstr_w(lpszSubKey));
+            return ret;
+        }
+    } else
+        xhkey = hkey;
 
-	lpdwType	= REG_SZ;
-	ret	= RegQueryValueEx32W(
-		xhkey,
-		NULL,		/* varname NULL -> compat */
-		NULL,		/* lpdwReserved, must be NULL */
-		&lpdwType,
-		(LPBYTE)lpszData,
-		lpcbData
-	);
-	if (xhkey!=hkey)
-		RegCloseKey(xhkey);
-	return ret;
+    lpdwType = REG_SZ;
+    ret = RegQueryValueEx32W( xhkey, NULL, NULL, &lpdwType, (LPBYTE)lpszData,
+                              lpcbData );
+    if (xhkey != hkey)
+        RegCloseKey(xhkey);
+    return ret;
 }
 
 
 /******************************************************************************
  * RegQueryValueEx32A [ADVAPI32.157]
- *
- * Can this use HEAP_strdupAtoW?
  */
 DWORD WINAPI RegQueryValueEx32A( HKEY hkey, LPSTR lpszValueName,
                                  LPDWORD lpdwReserved, LPDWORD lpdwType,
@@ -2176,27 +2252,19 @@
     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;
+    lpszValueNameW = lpszValueName?strdupA2W(lpszValueName):NULL;
 
+    /* Why would this be set? It is just an output */
     if (lpdwType)
-        type=*lpdwType;
+        type = *lpdwType;
 
 	if (lpbData) {
 		myxlen  = 0;
 		mylen	= &myxlen;
 		buf	= xmalloc(4);
                 /* Only get the size for now */
-		ret=RegQueryValueEx32W(
-			hkey,
-			lpszValueNameW,
-			lpdwReserved,
-			&type,
-			buf,
-			mylen
-		);
+		ret = RegQueryValueEx32W( hkey, lpszValueNameW, lpdwReserved,
+                                          &type, buf, mylen );
 		free(buf);
 		if (ret==ERROR_MORE_DATA) {
 			buf	= (LPBYTE)xmalloc(*mylen);
@@ -2205,6 +2273,7 @@
 			myxlen  = 2*(*lpcbData);
 		}
 	} else {
+		/* Data is not required */
 		buf=NULL;
 		if (lpcbData) {
 			myxlen	= *lpcbData*2;
@@ -2212,15 +2281,10 @@
 		} else
 			mylen	= NULL;
 	}
+
         /* Now get the data */
-	ret=RegQueryValueEx32W(
-		hkey,
-		lpszValueNameW,
-		lpdwReserved,
-		&type,
-		buf,
-		mylen
-	);
+	ret = RegQueryValueEx32W( hkey, lpszValueNameW, lpdwReserved, &type,
+                                  buf, mylen );
 	if (lpdwType) 
 		*lpdwType=type;
 
@@ -2246,9 +2310,9 @@
 		if ((UNICONVMASK & (1<<(type))) && lpcbData)
 			*lpcbData	= myxlen/2;
 	}
-	if (buf)
-		free(buf);
 
+    if(buf) free(buf);
+    if(lpszValueNameW) free(lpszValueNameW);
     return ret;
 }
 
@@ -2269,42 +2333,29 @@
 
 /******************************************************************************
  * RegQueryValue32A [ADVAPI32.156]
- *
- * NOTES
- *    Why is this calling RegOpenKey16?
  */
-DWORD WINAPI RegQueryValue32A(
-	HKEY	hkey,
-	LPSTR	lpszSubKey,
-	LPSTR	lpszData,
-	LPDWORD	lpcbData
-) {
-	HKEY	xhkey;
-	DWORD	ret,lpdwType;
+DWORD WINAPI RegQueryValue32A( HKEY hkey, LPSTR lpszSubKey, LPSTR lpszData,
+                               LPDWORD lpcbData )
+{
+    HKEY xhkey;
+    DWORD ret, dwType;
 
     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);
-		if (ret!=ERROR_SUCCESS)
-			return ret;
-	} else
-		xhkey	= hkey;
+    if (lpszSubKey && *lpszSubKey) {
+        ret = RegOpenKey16( hkey, lpszSubKey, &xhkey );
+        if( ret != ERROR_SUCCESS )
+            return ret;
+    } else
+        xhkey = hkey;
 
-	lpdwType	= REG_SZ;
-	ret	= RegQueryValueEx32A(
-		xhkey,
-		NULL,		/* lpszValueName NULL -> compat */
-		NULL,		/* lpdwReserved, must be NULL */
-		&lpdwType,
-		(LPBYTE)lpszData,
-		lpcbData
-	);
-	if (xhkey!=hkey)
-		RegCloseKey(xhkey);
-	return ret;
+    dwType = REG_SZ;
+    ret = RegQueryValueEx32A( xhkey, NULL,NULL, &dwType, (LPBYTE)lpszData,
+                              lpcbData );
+    if( xhkey != hkey )
+        RegCloseKey( xhkey );
+    return ret;
 }
 
 
@@ -2380,11 +2431,9 @@
             TRACE(reg,"Unknown type: %ld\n", dwType);
     }
 
-	lpkey = lookup_hkey(hkey);
-	if (!lpkey) {
-            WARN(reg,"Returning badkey\n");
-            return ERROR_INVALID_HANDLE;
-        }
+    lpkey = lookup_hkey( hkey );
+    if (!lpkey)
+        return ERROR_INVALID_HANDLE;
 
 	lpkey->flags |= REG_OPTION_TAINTED;
 
@@ -2427,8 +2476,6 @@
 /******************************************************************************
  * 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,
@@ -2475,13 +2522,9 @@
 /******************************************************************************
  * RegSetValue32W	[ADVAPI32.171]
  */
-DWORD WINAPI RegSetValue32W(
-	HKEY	hkey,
-	LPCWSTR	lpszSubKey,
-	DWORD	dwType,
-	LPCWSTR	lpszData,
-	DWORD	cbData
-) {
+DWORD WINAPI RegSetValue32W( HKEY hkey, LPCWSTR lpszSubKey, DWORD dwType,
+                             LPCWSTR lpszData, DWORD cbData )
+{
 	HKEY	xhkey;
 	DWORD	ret;
 
@@ -2495,11 +2538,11 @@
 	} else
 		xhkey=hkey;
 	if (dwType!=REG_SZ) {
-		TRACE(reg,"RegSetValueX called with dwType=%ld!\n",dwType);
+		TRACE(reg,"dwType=%ld - Changing to REG_SZ\n",dwType);
 		dwType=REG_SZ;
 	}
 	if (cbData!=2*lstrlen32W(lpszData)+2) {
-		TRACE(reg,"RegSetValueX called with len=%ld != strlen(%s)+1=%d!\n",
+		TRACE(reg,"Len=%ld != strlen(%s)+1=%d!\n",
 			cbData,debugstr_w(lpszData),2*lstrlen32W(lpszData)+2
 		);
 		cbData=2*lstrlen32W(lpszData)+2;
@@ -2514,22 +2557,14 @@
 /******************************************************************************
  * RegSetValue32A [ADVAPI32.168]
  *
- * NOTES
- *    Why is this calling RegCreateKey16?
  */
-DWORD WINAPI RegSetValue32A(
-	HKEY	hkey,
-	LPCSTR	lpszSubKey,
-	DWORD	dwType,
-	LPCSTR	lpszData,
-	DWORD	cbData
-) {
+DWORD WINAPI RegSetValue32A( HKEY hkey, LPCSTR lpszSubKey, DWORD dwType,
+                             LPCSTR lpszData, DWORD cbData )
+{
 	DWORD	ret;
 	HKEY	xhkey;
 
-	TRACE(reg,"(%x,%s,%ld,%s,%ld)\n",
-		hkey,lpszSubKey,dwType,lpszData,cbData
-	);
+	TRACE(reg,"(%x,%s,%ld,%s,%ld)\n",hkey,lpszSubKey,dwType,lpszData,cbData);
 	if (lpszSubKey && *lpszSubKey) {
 		ret=RegCreateKey16(hkey,lpszSubKey,&xhkey);
 		if (ret!=ERROR_SUCCESS)
@@ -2538,7 +2573,7 @@
 		xhkey=hkey;
 
 	if (dwType!=REG_SZ) {
-		TRACE(reg,"RegSetValueA called with dwType=%ld!\n",dwType);
+		TRACE(reg,"dwType=%ld!\n",dwType);
 		dwType=REG_SZ;
 	}
 	if (cbData!=strlen(lpszData)+1)
@@ -2584,7 +2619,7 @@
     TRACE(reg,"(%x,%ld,%p,%ld,%p,%p,%p,%p)\n",hkey,iSubkey,lpszName,
           *lpcchName,lpdwReserved,lpszClass,lpcchClass,ft);
 
-    lpkey = lookup_hkey(hkey);
+    lpkey = lookup_hkey( hkey );
     if (!lpkey)
         return ERROR_INVALID_HANDLE;
 
@@ -2622,17 +2657,14 @@
 }
 
 
-/* RegEnumKeyExA		[ADVAPI32.138] */
-DWORD WINAPI RegEnumKeyEx32A(
-	HKEY	hkey,
-	DWORD	iSubkey,
-	LPSTR	lpszName,
-	LPDWORD	lpcchName,
-	LPDWORD	lpdwReserved,
-	LPSTR	lpszClass,
-	LPDWORD	lpcchClass,
-	FILETIME	*ft
-) {
+/******************************************************************************
+ * RegEnumKeyEx32A [ADVAPI32.138]
+ */
+DWORD WINAPI RegEnumKeyEx32A( HKEY hkey, DWORD iSubkey, LPSTR lpszName,
+                              LPDWORD lpcchName, LPDWORD lpdwReserved, 
+                              LPSTR lpszClass, LPDWORD lpcchClass, 
+                              FILETIME *ft )
+{
 	DWORD	ret,lpcchNameW,lpcchClassW;
 	LPWSTR	lpszNameW,lpszClassW;
 
@@ -2715,29 +2747,34 @@
 
 /******************************************************************************
  * RegEnumValue32W [ADVAPI32.142]
+ *
+ * PARAMS
+ *    hkey   [I]
+ *    iValue [I]
+ *    ...
  */
-DWORD WINAPI RegEnumValue32W(
-	HKEY hkey,
-	DWORD iValue,
-	LPWSTR lpszValue,
-	LPDWORD	lpcchValue,
-	LPDWORD	lpdReserved,
-	LPDWORD	lpdwType,
-	LPBYTE	lpbData,
-	LPDWORD	lpcbData
-) {
+DWORD WINAPI RegEnumValue32W( HKEY hkey, DWORD iValue, LPWSTR lpszValue,
+                              LPDWORD lpcchValue, LPDWORD lpdReserved,
+                              LPDWORD lpdwType, LPBYTE lpbData, 
+                              LPDWORD lpcbData )
+{
 	LPKEYSTRUCT	lpkey;
 	LPKEYVALUE	val;
 
-	TRACE(reg,"(%x,%ld,%p,%p,%p,%p,%p,%p)\n",
-		hkey,iValue,lpszValue,lpcchValue,lpdReserved,lpdwType,lpbData,lpcbData
-	);
-	lpkey = lookup_hkey(hkey);
-	if (!lpkey)
-		return ERROR_INVALID_HANDLE;
+    TRACE(reg,"(%x,%ld,%p,%p,%p,%p,%p,%p)\n",hkey,iValue,debugstr_w(lpszValue),
+          lpcchValue,lpdReserved,lpdwType,lpbData,lpcbData);
+
+    lpkey = lookup_hkey( hkey );
+    if (!lpkey)
+        return ERROR_INVALID_HANDLE;
+
+    /* None asked for */
+    if (!iValue)
+        return ERROR_SUCCESS;
 
 	if (lpkey->nrofvalues<=iValue)
 		return ERROR_NO_MORE_ITEMS;
+
 	val	= lpkey->values+iValue;
 
 	if (val->name) {
@@ -2763,17 +2800,14 @@
 }
 
 
-/* RegEnumValueA		[ADVAPI32.141] */
-DWORD WINAPI RegEnumValue32A(
-	HKEY	hkey,
-	DWORD	iValue,
-	LPSTR	lpszValue,
-	LPDWORD	lpcchValue,
-	LPDWORD	lpdReserved,
-	LPDWORD	lpdwType,
-	LPBYTE	lpbData,
-	LPDWORD	lpcbData
-) {
+/******************************************************************************
+ * RegEnumValue32A [ADVAPI32.141]
+ */
+DWORD WINAPI RegEnumValue32A( HKEY hkey, DWORD iValue, LPSTR lpszValue,
+                              LPDWORD lpcchValue, LPDWORD lpdReserved,
+                              LPDWORD lpdwType, LPBYTE lpbData, 
+                              LPDWORD lpcbData )
+{
 	LPWSTR	lpszValueW;
 	LPBYTE	lpbDataW;
 	DWORD	ret,lpcbDataW;
@@ -2850,6 +2884,12 @@
 DWORD WINAPI RegCloseKey( HKEY hkey )
 {
     TRACE(reg,"(%x)\n",hkey);
+
+    /* The standard handles are allowed to succeed, even though they are not
+       closed */
+    if (is_standard_hkey(hkey))
+        return ERROR_SUCCESS;
+
     return remove_handle(hkey);
 }
 
@@ -2882,16 +2922,13 @@
     TRACE(reg,"(%x,%s)\n",hkey,debugstr_w(lpszSubKey));
 
     lpNextKey = lookup_hkey(hkey);
-    if (!lpNextKey) {
-        TRACE(reg, "  Invalid handle.\n");
+    if (!lpNextKey)
         return ERROR_INVALID_HANDLE;
-    }
 
-	/* we need to know the previous key in the hier. */
-	if (!lpszSubKey || !*lpszSubKey) {
-		TRACE(reg, "  Badkey[2].\n");
-		return ERROR_BADKEY;
-	}
+    /* We need to know the previous key in the hier. */
+    if (!lpszSubKey || !*lpszSubKey)
+        return ERROR_BADKEY;
+
 	split_keypath(lpszSubKey,&wps,&wpc);
 	i 	= 0;
 	lpxkey	= lpNextKey;
@@ -2956,10 +2993,10 @@
     LPWSTR lpszSubKeyW;
     DWORD  ret;
 
-    TRACE(reg,"(%x,%s)\n",hkey,lpszSubKey);
-    lpszSubKeyW = HEAP_strdupAtoW( GetProcessHeap(), 0, lpszSubKey );
+    TRACE(reg,"(%x,%s)\n",hkey,debugstr_a(lpszSubKey));
+    lpszSubKeyW = lpszSubKey?strdupA2W(lpszSubKey):NULL;
     ret = RegDeleteKey32W( hkey, lpszSubKeyW );
-    HeapFree( GetProcessHeap(), 0, lpszSubKeyW );
+    if(lpszSubKeyW) free(lpszSubKeyW);
     return ret;
 }
 
@@ -2999,7 +3036,7 @@
 
     TRACE(reg,"(%x,%s)\n",hkey,debugstr_w(lpszValue));
 
-    lpkey = lookup_hkey(hkey);
+    lpkey = lookup_hkey( hkey );
     if (!lpkey)
         return ERROR_INVALID_HANDLE;
 
@@ -3044,9 +3081,9 @@
     DWORD  ret;
 
     TRACE(reg, "(%x,%s)\n",hkey,debugstr_a(lpszValue));
-    lpszValueW=HEAP_strdupAtoW(GetProcessHeap(),0,lpszValue);
+    lpszValueW = lpszValue?strdupA2W(lpszValue):NULL;
     ret = RegDeleteValue32W( hkey, lpszValueW );
-    HeapFree(GetProcessHeap(),0,lpszValueW);
+    if(lpszValueW) free(lpszValueW);
     return ret;
 }
 
@@ -3057,7 +3094,7 @@
 DWORD WINAPI RegDeleteValue16( HKEY hkey, LPSTR lpszValue )
 {
     TRACE(reg,"(%x,%s)\n", hkey,debugstr_a(lpszValue));
-    return RegDeleteValue32A(hkey,lpszValue);
+    return RegDeleteValue32A( hkey, lpszValue );
 }
 
 
@@ -3074,8 +3111,23 @@
  */
 DWORD WINAPI RegFlushKey( HKEY hkey )
 {
-    FIXME(reg, "(%x): stub\n", hkey);
-    return ERROR_SUCCESS;
+    LPKEYSTRUCT	lpkey;
+    BOOL32 ret;
+
+    TRACE(reg, "(%x)\n", hkey);
+
+    lpkey = lookup_hkey( hkey );
+    if (!lpkey)
+        return ERROR_INVALID_HANDLE;
+
+    ERR(reg, "What is the correct filename?\n");
+
+    ret = _savereg( lpkey, "foo.bar", TRUE);
+
+    if( ret ) {
+        return ERROR_SUCCESS;
+    } else
+        return ERROR_UNKNOWN;  /* FIXME */
 }
 
 
@@ -3215,11 +3267,24 @@
 
 /******************************************************************************
  * RegConnectRegistry32W [ADVAPI32.128]
+ *
+ * PARAMS
+ *    lpMachineName [I] Address of name of remote computer
+ *    hHey          [I] Predefined registry handle
+ *    phkResult     [I] Address of buffer for remote registry handle
  */
-LONG WINAPI RegConnectRegistry32W( LPCWSTR machine, HKEY hkey, LPHKEY reskey )
+LONG WINAPI RegConnectRegistry32W( LPCWSTR lpMachineName, HKEY hKey, 
+                                   LPHKEY phkResult )
 {
-    FIXME(reg,"(%s,%x,%p): stub\n",debugstr_w(machine),hkey,reskey);
-    return ERROR_BAD_NETPATH; /* FIXME */
+    TRACE(reg,"(%s,%x,%p): stub\n",debugstr_w(lpMachineName),hKey,phkResult);
+
+    if (!lpMachineName || !*lpMachineName) {
+        /* Use the local machine name */
+        return RegOpenKey16( hKey, "", phkResult );
+    }
+
+    FIXME(reg,"Cannot connect to %s\n",debugstr_w(lpMachineName));
+    return ERROR_BAD_NETPATH;
 }
 
 
@@ -3229,9 +3294,9 @@
 LONG WINAPI RegConnectRegistry32A( LPCSTR machine, HKEY hkey, LPHKEY reskey )
 {
     DWORD ret;
-    LPWSTR machineW = HEAP_strdupAtoW(GetProcessHeap(),0,machine);
+    LPWSTR machineW = strdupA2W(machine);
     ret = RegConnectRegistry32W( machineW, hkey, reskey );
-    HeapFree(GetProcessHeap(),0,machineW);
+    free(machineW);
     return ret;
 }
 
@@ -3240,6 +3305,12 @@
  * RegGetKeySecurity [ADVAPI32.144]
  * Retrieves a copy of security descriptor protecting the registry key
  *
+ * PARAMS
+ *    hkey                   [I]   Open handle of key to set
+ *    SecurityInformation    [I]   Descriptor contents
+ *    pSecurityDescriptor    [O]   Address of descriptor for key
+ *    lpcbSecurityDescriptor [I/O] Address of size of buffer and description
+ *
  * RETURNS
  *    Success: ERROR_SUCCESS
  *    Failure: Error code
@@ -3250,23 +3321,43 @@
                                LPDWORD lpcbSecurityDescriptor )
 {
     LPKEYSTRUCT	lpkey;
-    lpkey = lookup_hkey(hkey);
+
+    FIXME(reg, "(%x,%ld,%p,%ld): stub\n",hkey,SecurityInformation,
+          pSecurityDescriptor,lpcbSecurityDescriptor?*lpcbSecurityDescriptor:0);
+
+    lpkey = lookup_hkey( hkey );
     if (!lpkey)
         return ERROR_INVALID_HANDLE;
 
-    FIXME(reg, "(%d,%ld,%p,%p): stub\n", hkey, SecurityInformation,
-          pSecurityDescriptor, lpcbSecurityDescriptor);
+    if (*lpcbSecurityDescriptor < sizeof(*pSecurityDescriptor))
+        return ERROR_INSUFFICIENT_BUFFER;
+
     return ERROR_SUCCESS;
 }
 
 
 /******************************************************************************
  * RegLoadKey32W [ADVAPI32.???]
+ *
+ * PARAMS
+ *    hkey       [I] Handle of open key
+ *    lpszSubKey [I] Address of name of subkey
+ *    lpszFile   [I] Address of filename for registry information
  */
 LONG WINAPI RegLoadKey32W( HKEY hkey, LPCWSTR lpszSubKey, LPCWSTR lpszFile )
 {
+    LPKEYSTRUCT	lpkey;
     FIXME(reg,"(%x,%s,%s): stub\n",hkey,debugstr_w(lpszSubKey),
           debugstr_w(lpszFile));
+
+    /* Do this check before the hkey check */
+    if (!lpszSubKey || !*lpszSubKey || !lpszFile || !*lpszFile)
+        return ERROR_INVALID_PARAMETER;
+
+    lpkey = lookup_hkey( hkey );
+    if (!lpkey)
+        return ERROR_INVALID_HANDLE;
+
     return ERROR_SUCCESS;
 }
 
@@ -3277,30 +3368,47 @@
 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);
+    LPWSTR lpszSubKeyW = strdupA2W(lpszSubKey);
+    LPWSTR lpszFileW = strdupA2W(lpszFile);
     ret = RegLoadKey32W( hkey, lpszSubKeyW, lpszFileW );
-    HeapFree(GetProcessHeap(),0,lpszFileW);
-    HeapFree(GetProcessHeap(),0,lpszSubKeyW);
+    if(lpszFileW) free(lpszFileW);
+    if(lpszSubKeyW) free(lpszSubKeyW);
     return ret;
 }
 
 
 /******************************************************************************
  * RegNotifyChangeKeyValue [ADVAPI32.???]
+ *
+ * PARAMS
+ *    hkey            [I] Handle of key to watch
+ *    fWatchSubTree   [I] Flag for subkey notification
+ *    fdwNotifyFilter [I] Changes to be reported
+ *    hEvent          [I] Handle of signaled event
+ *    fAsync          [I] Flag for asynchronous reporting
  */
 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,
+    LPKEYSTRUCT	lpkey;
+    FIXME(reg,"(%x,%i,%ld,%x,%i): stub\n",hkey,fWatchSubTree,fdwNotifyFilter,
           hEvent,fAsync);
+
+    lpkey = lookup_hkey( hkey );
+    if (!lpkey)
+        return ERROR_INVALID_HANDLE;
+
     return ERROR_SUCCESS;
 }
 
 
 /******************************************************************************
  * RegUnLoadKey32W [ADVAPI32.173]
+ *
+ * PARAMS
+ *    hkey     [I] Handle of open key
+ *    lpSubKey [I] Address of name of subkey to unload
  */
 LONG WINAPI RegUnLoadKey32W( HKEY hkey, LPCWSTR lpSubKey )
 {
@@ -3315,31 +3423,71 @@
 LONG WINAPI RegUnLoadKey32A( HKEY hkey, LPCSTR lpSubKey )
 {
     LONG ret;
-    LPWSTR lpSubKeyW = HEAP_strdupAtoW( GetProcessHeap(), 0, lpSubKey );
+    LPWSTR lpSubKeyW = strdupA2W(lpSubKey);
     ret = RegUnLoadKey32W( hkey, lpSubKeyW );
-    HeapFree( GetProcessHeap(), 0, lpSubKeyW );
+    if(lpSubKeyW) free(lpSubKeyW);
     return ret;
 }
 
 
 /******************************************************************************
  * RegSetKeySecurity [ADVAPI32.167]
+ *
+ * PARAMS
+ *    hkey          [I] Open handle of key to set
+ *    SecurityInfo  [I] Descriptor contents
+ *    pSecurityDesc [I] Address of descriptor for key
  */
 LONG WINAPI RegSetKeySecurity( HKEY hkey, SECURITY_INFORMATION SecurityInfo,
                                LPSECURITY_DESCRIPTOR pSecurityDesc )
 {
-    FIXME(reg, "%x,%ld,%p): stub\n", hkey, SecurityInfo, pSecurityDesc);
+    LPKEYSTRUCT	lpkey;
+
+    FIXME(reg, "(%x,%ld,%p): stub\n", hkey, SecurityInfo, pSecurityDesc);
+
+    /* It seems to perform this check before the hkey check */
+    if ((SecurityInfo & OWNER_SECURITY_INFORMATION) ||
+        (SecurityInfo & GROUP_SECURITY_INFORMATION) ||
+        (SecurityInfo & DACL_SECURITY_INFORMATION) ||
+        (SecurityInfo & SACL_SECURITY_INFORMATION)) {
+        /* Param OK */
+    } else
+        return ERROR_INVALID_PARAMETER;
+
+    if (!pSecurityDesc)
+        return ERROR_INVALID_PARAMETER;
+
+    lpkey = lookup_hkey( hkey );
+    if (!lpkey)
+        return ERROR_INVALID_HANDLE;
+
     return ERROR_SUCCESS;
 }
 
 
 /******************************************************************************
  * RegSaveKey32W [ADVAPI32.166]
+ *
+ * PARAMS
+ *    hkey   [I] Handle of key where save begins
+ *    lpFile [I] Address of filename to save to
+ *    sa     [I] Address of security structure
  */
 LONG WINAPI RegSaveKey32W( HKEY hkey, LPCWSTR lpFile, 
                            LPSECURITY_ATTRIBUTES sa )
 {
-    FIXME(reg, "%x,%s,%p): stub\n", hkey, debugstr_w(lpFile), sa);
+    LPKEYSTRUCT	lpkey;
+
+    FIXME(reg, "(%x,%s,%p): stub\n", hkey, debugstr_w(lpFile), sa);
+
+    /* It appears to do this check before the hkey check */
+    if (!lpFile || !*lpFile)
+        return ERROR_INVALID_PARAMETER;
+
+    lpkey = lookup_hkey( hkey );
+    if (!lpkey)
+        return ERROR_INVALID_HANDLE;
+
     return ERROR_SUCCESS;
 }
 
@@ -3351,19 +3499,36 @@
                            LPSECURITY_ATTRIBUTES sa )
 {
     LONG ret;
-    LPWSTR lpFileW = HEAP_strdupAtoW(GetProcessHeap(), 0, lpFile);
+    LPWSTR lpFileW = strdupA2W(lpFile);
     ret = RegSaveKey32W( hkey, lpFileW, sa );
-    HeapFree( GetProcessHeap(), 0, lpFileW );
+    free(lpFileW);
     return ret;
 }
 
 
 /******************************************************************************
  * RegRestoreKey32W [ADVAPI32.164]
+ *
+ * PARAMS
+ *    hkey    [I] Handle of key where restore begins
+ *    lpFile  [I] Address of filename containing saved tree
+ *    dwFlags [I] Optional flags
  */
 LONG WINAPI RegRestoreKey32W( HKEY hkey, LPCWSTR lpFile, DWORD dwFlags )
 {
-    FIXME(reg, "%x,%s,%ld): stub\n", hkey, debugstr_w(lpFile), dwFlags);
+    LPKEYSTRUCT	lpkey;
+    FIXME(reg, "(%x,%s,%ld): stub\n", hkey, debugstr_w(lpFile), dwFlags);
+
+    /* It seems to do this check before the hkey check */
+    if (!lpFile || !*lpFile)
+        return ERROR_INVALID_PARAMETER;
+
+    lpkey = lookup_hkey( hkey );
+    if (!lpkey)
+        return ERROR_INVALID_HANDLE;
+
+    /* Check for file existence */
+
     return ERROR_SUCCESS;
 }
 
@@ -3374,21 +3539,34 @@
 LONG WINAPI RegRestoreKey32A( HKEY hkey, LPCSTR lpFile, DWORD dwFlags )
 {
     LONG ret;
-    LPWSTR lpFileW = HEAP_strdupAtoW(GetProcessHeap(), 0, lpFile);
+    LPWSTR lpFileW = strdupA2W(lpFile);
     ret = RegRestoreKey32W( hkey, lpFileW, dwFlags );
-    HeapFree( GetProcessHeap(), 0, lpFileW );
+    if(lpFileW) free(lpFileW);
     return ret;
 }
 
 
 /******************************************************************************
  * RegReplaceKey32W [ADVAPI32.162]
+ *
+ * PARAMS
+ *    hkey      [I] Handle of open key
+ *    lpSubKey  [I] Address of name of subkey
+ *    lpNewFile [I] Address of filename for file with new data
+ *    lpOldFile [I] Address of filename for backup file
  */
 LONG WINAPI RegReplaceKey32W( HKEY hkey, LPCWSTR lpSubKey, LPCWSTR lpNewFile,
                               LPCWSTR lpOldFile )
 {
-    FIXME(reg, "%x,%s,%s,%s): stub\n", hkey, debugstr_w(lpSubKey), 
+    LPKEYSTRUCT	lpkey;
+
+    FIXME(reg, "(%x,%s,%s,%s): stub\n", hkey, debugstr_w(lpSubKey), 
           debugstr_w(lpNewFile),debugstr_w(lpOldFile));
+
+    lpkey = lookup_hkey( hkey );
+    if (!lpkey)
+        return ERROR_INVALID_HANDLE;
+
     return ERROR_SUCCESS;
 }
 
@@ -3400,13 +3578,13 @@
                               LPCSTR lpOldFile )
 {
     LONG ret;
-    LPWSTR lpSubKeyW = HEAP_strdupAtoW(GetProcessHeap(), 0, lpSubKey);
-    LPWSTR lpNewFileW = HEAP_strdupAtoW(GetProcessHeap(), 0, lpNewFile);
-    LPWSTR lpOldFileW = HEAP_strdupAtoW(GetProcessHeap(), 0, lpOldFile);
+    LPWSTR lpSubKeyW = strdupA2W(lpSubKey);
+    LPWSTR lpNewFileW = strdupA2W(lpNewFile);
+    LPWSTR lpOldFileW = strdupA2W(lpOldFile);
     ret = RegReplaceKey32W( hkey, lpSubKeyW, lpNewFileW, lpOldFileW );
-    HeapFree( GetProcessHeap(), 0, lpOldFileW );
-    HeapFree( GetProcessHeap(), 0, lpNewFileW );
-    HeapFree( GetProcessHeap(), 0, lpSubKeyW );
+    free(lpOldFileW);
+    free(lpNewFileW);
+    free(lpSubKeyW);
     return ret;
 }
 
diff --git a/misc/shell.c b/misc/shell.c
index 4ac0d7c..40a8084 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -375,8 +375,8 @@
 	  }
 
     /* Check registry */
-    if (RegQueryValue16( (HKEY)HKEY_CLASSES_ROOT, tmpext, filetype,
-                         &filetypelen ) == SHELL_ERROR_SUCCESS )
+    if (RegQueryValue16( HKEY_CLASSES_ROOT, tmpext, filetype,
+                         &filetypelen ) == ERROR_SUCCESS )
     {
 	filetype[filetypelen]='\0';
 	TRACE(exec, "File type: %s\n",
@@ -387,8 +387,8 @@
 	strcat( filetype, lpOperation );
 	strcat( filetype, "\\command" );
 	
-	if (RegQueryValue16( (HKEY)HKEY_CLASSES_ROOT, filetype, command,
-                             &commandlen ) == SHELL_ERROR_SUCCESS )
+	if (RegQueryValue16( HKEY_CLASSES_ROOT, filetype, command,
+                             &commandlen ) == ERROR_SUCCESS )
 	{
 	    /* Is there a replace() function anywhere? */
 	    command[commandlen]='\0';
@@ -1172,7 +1172,7 @@
 	for (i=0;i<n;i++) {
 	    LPIMAGE_RESOURCE_DIRECTORY	xresdir;
 
-	    xresdir = GetResDirEntryW(iconresdir,(LPWSTR)RetPtr[i],(DWORD)rootresdir,FALSE);
+	    xresdir = GetResDirEntryW(iconresdir,(LPWSTR)&(RetPtr[i]),(DWORD)rootresdir,FALSE);
 	    xresdir = GetResDirEntryW(xresdir,(LPWSTR)0,(DWORD)rootresdir,TRUE);
 
 	    idataent = (LPIMAGE_RESOURCE_DATA_ENTRY)xresdir;
@@ -1563,11 +1563,11 @@
 }
 
 /*************************************************************************
+ * FreeIconList
  */
-
 void WINAPI FreeIconList( DWORD dw )
 {
-    FIXME(reg, "empty stub\n" );
+    FIXME(reg, "(%lx): stub\n",dw);
 }
 
 /*************************************************************************
@@ -1580,7 +1580,6 @@
     char	xclsid[50],xiid[50];
     HRESULT	hres = E_OUTOFMEMORY;
 
-
     WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
     WINE_StringFromCLSID((LPCLSID)iid,xiid);
     TRACE(shell,"(%s,%s,%p)\n",xclsid,xiid,ppv);
@@ -1610,7 +1609,7 @@
 	return 0;
     }
 
-    FIXME(shell, "   -> clsid not found. returning E_OUTOFMEMORY.\n");
+    FIXME(shell, "clsid(%s) not found.  Returning E_OUTOFMEMORY.\n",xclsid);
     return hres;
 }
 
@@ -1669,3 +1668,18 @@
 	lstrcpy32A(pszPath,"E:\\"); /* FIXME */
 	return NOERROR;
 }
+
+/*************************************************************************
+ * SHHelpShortcuts_RunDLL [SHELL32.224]
+ *
+ */
+
+DWORD WINAPI
+SHHelpShortcuts_RunDLL (DWORD dwArg1, DWORD dwArg2, DWORD dwArg3, DWORD dwArg4)
+{
+    FIXME (exec, "(%lx, %lx, %lx, %lx) empty stub!\n",
+	   dwArg1, dwArg2, dwArg3, dwArg4);
+
+    return 0;
+}
+
diff --git a/misc/shellord.c b/misc/shellord.c
index 41f0538..62de68b 100644
--- a/misc/shellord.c
+++ b/misc/shellord.c
@@ -42,6 +42,9 @@
 /*************************************************************************
  *	 		 SHELL32_16   			[SHELL32.16]
  * find_lastitem_in_itemidlist()
+ *
+ * NOTES
+ *     Original name: ILFindLast (exported by ordinal)
  */
 LPSHITEMID WINAPI SHELL32_16(LPITEMIDLIST iil) {
 	LPSHITEMID	lastsii,sii;
@@ -56,9 +59,13 @@
 	}
 	return lastsii;
 }
+
 /*************************************************************************
  *	 		 SHELL32_29   			[SHELL32.29]
  * is_rootdir(const char*path)
+ *
+ * NOTES
+ *     Original Name: PathIsRoot
  */
 BOOL32 WINAPI SHELL32_29(LPCSTR x) {
 	if (!lstrcmp32A(x+1,":\\"))		/* "X:\" */
@@ -81,6 +88,9 @@
 /*************************************************************************
  *	 		 SHELL32_30   			[SHELL32.30]
  * get_rootdir(char*path,int drive)
+ *
+ * NOTES
+ *     Original Name: PathBuildRoot
  */
 LPSTR WINAPI SHELL32_30(LPSTR root,BYTE drive) {
 	strcpy(root,"A:\\");
@@ -381,9 +391,16 @@
 /*************************************************************************
  *				SHELL32_181	[SHELL32.181]
  * unknown
+ *
+ * PARAMS
+ *      hwnd [I]  window handle
+ *      y    [I]  flag ????
+ *
+ * NOTES
+ *     Original name: RegisterShellHook (exported by ordinal)
  */
-void WINAPI SHELL32_181(DWORD x,DWORD y) {
-    FIXME(shell,"(0x%08lx,0x%08lx):stub.\n",x,y);
+void WINAPI SHELL32_181(HWND32 hwnd, DWORD y) {
+    FIXME(shell,"(0x%08lx,0x%08lx):stub.\n",hwnd,y);
 }
 
 /*************************************************************************
@@ -524,6 +541,9 @@
 /*************************************************************************
  *			 SHELL32_183   			[SHELL32.183]
  * Format and output errormessage.
+ *
+ * NOTES
+ *     Original name: ShellMessageBoxA
  */
 void __cdecl SHELL32_183(HMODULE32 hmod,HWND32 hwnd,DWORD id,DWORD x,DWORD type,LPVOID arglist) {
 	char	buf[100],buf2[100],*buf3;
@@ -701,3 +721,43 @@
     return 0;
 }
 
+
+/*************************************************************************
+ * SHELL32_61 [SHELL32.61]
+ * Shell/Run-Dialog
+ */
+DWORD WINAPI
+SHELL32_61 (HWND32 hwndOwner, DWORD dwParam1, DWORD dwParam2,
+	    LPSTR lpszTitle, LPSTR lpszPrompt, UINT32 uFlags)
+{
+    FIXME (shell,"(0x%08x 0x%lx 0x%lx \"%s\" \"%s\" 0x%lx):stub.\n",
+	   hwndOwner, dwParam1, dwParam2, lpszTitle, lpszPrompt, uFlags);
+    return 0;
+}
+
+
+/*************************************************************************
+ * SHELL32_60 [SHELL32.60]
+ * Shell/Shutdown-Dialog
+ */
+DWORD WINAPI
+SHELL32_60 (HWND32 hwndOwner)
+{
+    FIXME (shell,"(0x%08x):stub.\n", hwndOwner);
+    return 0;
+}
+
+
+/*************************************************************************
+ * SHELL32_184 [SHELL32.184]
+ * unknown
+ */
+DWORD WINAPI
+SHELL32_184 (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3,
+	     DWORD dwParam4, DWORD dwParam5)
+{
+    FIXME (shell,"(0x%lx 0x%lx 0x%lx 0x%lx 0x%lx):stub.\n",
+	   dwParam1, dwParam2, dwParam3, dwParam4, dwParam5);
+    return 0;
+}
+
diff --git a/misc/system.c b/misc/system.c
index 77e4940..22a5dde 100644
--- a/misc/system.c
+++ b/misc/system.c
@@ -15,6 +15,8 @@
 #include "callback.h"
 #include "windows.h"
 #include "miscemu.h"
+#include "selectors.h"
+#include "sig_context.h"
 #include "debug.h"
 
 typedef struct
@@ -33,10 +35,17 @@
 
 /***********************************************************************
  *           SYSTEM_TimerTick
+ * FIXME: It is a very bad idea to call 16bit code in a signal handler:
+ *	  If the signal reached us in 16 bit code, we could have a broken
+ *	  %FS, which is in turned saved into the single global
+ *	  CALLTO16_Current_fs temporary storage, so a single misplaced
+ *	  signal crashes the whole WINE process.
+ *	  This needs more thought. -MM
  */
-static void SYSTEM_TimerTick(void)
+static HANDLER_DEF(SYSTEM_TimerTick)
 {
     int i;
+    HANDLER_INIT();
 
     for (i = 0; i < NB_SYS_TIMERS; i++)
     {
@@ -44,12 +53,15 @@
         if ((SYS_Timers[i].ticks -= SYS_TIMER_RATE) <= 0)
         {
             SYS_Timers[i].ticks += SYS_Timers[i].rate;
-            Callbacks->CallSystemTimerProc( SYS_Timers[i].callback );
+
+	    if (SYS_Timers[i].callback == (FARPROC16)DOSMEM_Tick) {
+	    	DOSMEM_Tick();
+	    } else
+		Callbacks->CallSystemTimerProc( SYS_Timers[i].callback );
         }
     }
 }
 
-
 /**********************************************************************
  *           SYSTEM_StartTicks
  *
@@ -62,7 +74,7 @@
     if (!handler_installed)
     {
         handler_installed = TRUE;
-        SIGNAL_SetHandler( SIGALRM, SYSTEM_TimerTick, 1 );
+	SIGNAL_SetHandler( SIGALRM, SYSTEM_TimerTick, 1 );
     }
 #ifndef __EMX__ /* FIXME: Time don't work... Use BIOS directly instead */
     {
@@ -130,6 +142,14 @@
 {
     int i;
 
+    /* FIXME: HACK: do not create system timers due to problems mentioned
+     * above, except DOSMEM_Tick().
+     */
+    if (callback!=(FARPROC16)DOSMEM_Tick) {
+    	FIXME(system,"are currently broken, returning 0.\n");
+    	return 0;
+    }
+
     for (i = 0; i < NB_SYS_TIMERS; i++)
         if (!SYS_Timers[i].callback)  /* Found one */
         {
diff --git a/misc/tapi32.c b/misc/tapi32.c
new file mode 100644
index 0000000..87e45fb
--- /dev/null
+++ b/misc/tapi32.c
@@ -0,0 +1,42 @@
+/*
+ * TAPI32
+ *
+ * Copyright (c) 1998 Andreas Mohr
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "windows.h"
+#include "debug.h"
+
+UINT32 WINAPI lineInitialize(
+  LPVOID lphLineApp, /* FIXME */
+  HINSTANCE32 hInstance,
+  LPVOID lpfnCallback, /* FIXME */
+  LPCSTR lpszAppName,
+  LPDWORD lpdwNumDevs)
+{
+    FIXME(comm, "stub.\n");
+    return 0;
+}
+
+UINT32 WINAPI lineShutdown( HANDLE32 hLineApp ) /* FIXME */
+{
+    FIXME(comm, "stub.\n");
+    return 0;
+}
+
+UINT32 WINAPI lineNegotiateAPIVersion(
+  HANDLE32 hLineApp, /* FIXME */
+  DWORD dwDeviceID,
+  DWORD dwAPILowVersion,
+  DWORD dwAPIHighVersion,
+  LPDWORD lpdwAPIVersion,
+  LPVOID lpExtensionID /* FIXME */
+)
+{
+    FIXME(comm, "stub.\n");
+    *lpdwAPIVersion = dwAPIHighVersion;
+    return 0;
+}
diff --git a/misc/version.c b/misc/version.c
index 89cb8cd..ea0348c 100644
--- a/misc/version.c
+++ b/misc/version.c
@@ -11,6 +11,7 @@
 #include "process.h"
 #include "options.h"
 #include "debug.h"
+#include "ole.h"
 
 typedef enum
 {
@@ -163,6 +164,26 @@
 
 
 /***********************************************************************
+ *         GetVersionEx16   (KERNEL.149)
+ */
+BOOL16 WINAPI GetVersionEx16(OSVERSIONINFO16 *v)
+{
+    VERSION ver = VERSION_GetVersion();
+    if (v->dwOSVersionInfoSize != sizeof(OSVERSIONINFO16))
+    {
+        WARN(ver,"wrong OSVERSIONINFO size from app");
+        return FALSE;
+    }
+    v->dwMajorVersion = VersionData[ver].getVersionEx.dwMajorVersion;
+    v->dwMinorVersion = VersionData[ver].getVersionEx.dwMinorVersion;
+    v->dwBuildNumber  = VersionData[ver].getVersionEx.dwBuildNumber;
+    v->dwPlatformId   = VersionData[ver].getVersionEx.dwPlatformId;
+    strcpy( v->szCSDVersion, VersionData[ver].getVersionEx.szCSDVersion );
+    return TRUE;
+}
+
+
+/***********************************************************************
  *         GetVersionEx32A   (KERNEL32.428)
  */
 BOOL32 WINAPI GetVersionEx32A(OSVERSIONINFO32A *v)
@@ -300,3 +321,81 @@
         /* FIXME */
 	DPRINTF("DIAGOUTPUT:%s\n",str);
 }
+
+/***********************************************************************
+ * DllGetVersion [COMCTL32.25]
+ *
+ *
+ *
+ */
+HRESULT WINAPI COMCTL32_DllGetVersion(DLLVERSIONINFO *pdvi)
+{
+    VERSION ver = VERSION_GetVersion();
+
+    if (pdvi->cbSize != sizeof(DLLVERSIONINFO))
+    {
+        WARN(ver, "wrong DLLVERSIONINFO size from app");
+        return OLE_ERROR_SIZE; /* FIXME: is this error correct ? */
+    }
+
+    pdvi->dwPlatformID = VersionData[ver].getVersionEx.dwPlatformId;
+    switch(VersionData[ver].getVersion32)
+    {
+        case 0x80000a03: /* Win 3.1 */
+        {
+            pdvi->dwMajorVersion = 3;
+            pdvi->dwMinorVersion = 51;
+            pdvi->dwBuildNumber = 0;
+        }
+        break;
+        case 0xc0000004: /* Win 95 */
+        {
+            pdvi->dwMajorVersion = 4;
+            pdvi->dwMinorVersion = 0;
+            pdvi->dwBuildNumber = 950;
+        }
+        break;
+        case 0x04213303: /* NT 3.51 FIXME: correct ? */
+        {
+            pdvi->dwMajorVersion = 3;
+            pdvi->dwMinorVersion = 51;
+            pdvi->dwBuildNumber = 0x421;
+        }
+        break;
+        case 0x05650004: /* NT 4.0 FIXME: correct ? */
+        {
+            pdvi->dwMajorVersion = 4;
+            pdvi->dwMinorVersion = 0;
+            pdvi->dwBuildNumber = 0x565;
+        }
+        break;
+        default:
+        {
+            ERR(ver, "Unknown Windows version, please add it to the list !\n");
+        }
+        break;
+    }
+    return 0; /* winerror.h: NOERROR */
+}
+
+/***********************************************************************
+ *           OaBuildVersion           [OLEAUT32.170]
+ */
+UINT32 WINAPI OaBuildVersion()
+{
+    VERSION ver = VERSION_GetVersion();
+
+    switch(VersionData[ver].getVersion32)
+    {
+        case 0x80000a03: /* Win 3.1 */
+		return 0x140fd1; /* from Win32s 1.1e */
+        case 0xc0000004: /* Win 95 */
+		return 0x0a0bd3;
+        case 0x04213303: /* NT 3.51 */
+		return 0x0; /* FIXME */
+        case 0x05650004: /* NT 4.0 */
+		return 0x141016;
+	default:
+		return 0x0;
+    }
+}
diff --git a/misc/w32skrnl.c b/misc/w32skrnl.c
index df9d65a..6f3030f 100644
--- a/misc/w32skrnl.c
+++ b/misc/w32skrnl.c
@@ -5,10 +5,10 @@
  * Copyright (c) 1997 Andreas Mohr
  */
 
-#include "windows.h"
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include "windows.h"
 
 LPSTR WINAPI GetWin32sDirectory(void)
 {
diff --git a/misc/win32s16.c b/misc/win32s16.c
index 5fc0484..48b00cb 100644
--- a/misc/win32s16.c
+++ b/misc/win32s16.c
@@ -5,10 +5,10 @@
  * Copyright (c) 1997 Andreas Mohr
  */
 
-#include "windows.h"
-#include "debug.h"
 #include <string.h>
 #include <stdlib.h>
+#include "windows.h"
+#include "debug.h"
 
 void BootTask()
 {
diff --git a/misc/winsock.c b/misc/winsock.c
index 4dae6c4..44c1ecd 100644
--- a/misc/winsock.c
+++ b/misc/winsock.c
@@ -1929,7 +1929,7 @@
 
 INT16 WINAPI WSACancelAsyncRequest16(HANDLE16 hAsyncTaskHandle)
 {
-    return (HANDLE16)WSACancelAsyncRequest16((HANDLE32)hAsyncTaskHandle);
+    return (HANDLE16)WSACancelAsyncRequest32((HANDLE32)hAsyncTaskHandle);
 }
 
 /***********************************************************************
diff --git a/msdos/dpmi.c b/msdos/dpmi.c
index d7128d9..4edbc9e 100644
--- a/msdos/dpmi.c
+++ b/msdos/dpmi.c
@@ -8,6 +8,7 @@
 #include <string.h>
 #include "windows.h"
 #include "heap.h"
+#include "global.h"
 #include "ldt.h"
 #include "module.h"
 #include "miscemu.h"
@@ -24,6 +25,7 @@
 
 void CreateBPB(int drive, BYTE *data, BOOL16 limited);  /* defined in int21.c */
 
+static void* lastvalloced = NULL;
 
 /* Structure for real-mode callbacks */
 typedef struct
@@ -58,6 +60,72 @@
 static RMCB *FirstRMCB = NULL;
 
 /**********************************************************************
+ *	    DPMI_xalloc
+ * special virtualalloc, allocates lineary monoton growing memory.
+ * (the usual VirtualAlloc does not satisfy that restriction)
+ */
+static LPVOID
+DPMI_xalloc(int len) {
+	LPVOID	ret;
+	LPVOID	oldlastv = lastvalloced;
+
+	if (lastvalloced) {
+		int	xflag = 0;
+		ret = NULL;
+		while (!ret) {
+			ret=VirtualAlloc(lastvalloced,len,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
+			if (!ret)
+				lastvalloced+=0x10000;
+			/* we failed to allocate one in the first round. 
+			 * try non-linear
+			 */
+			if (!xflag && (lastvalloced<oldlastv)) { /* wrapped */
+				FIXME(int31,"failed to allocate lineary growing memory (%d bytes), using non-linear growing...\n",len);
+				xflag++;
+			}
+			/* if we even fail to allocate something in the next 
+			 * round, return NULL
+			 */
+			if ((xflag==1) && (lastvalloced >= oldlastv))
+				xflag++;
+			if ((xflag==2) && (lastvalloced < oldlastv)) {
+				FIXME(int31,"failed to allocate any memory of %d bytes!\n",len);
+				return NULL;
+			}
+		}
+	} else
+		 ret=VirtualAlloc(NULL,len,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
+	lastvalloced = (LPVOID)(((DWORD)ret+len+0xffff)&~0xffff);
+	return ret;
+}
+
+static void
+DPMI_xfree(LPVOID ptr) {
+	VirtualFree(ptr,0,MEM_RELEASE);
+}
+
+/* FIXME: perhaps we could grow this mapped area... */
+static LPVOID
+DPMI_xrealloc(LPVOID ptr,int newsize) {
+	MEMORY_BASIC_INFORMATION	mbi;
+	LPVOID				newptr;
+
+	if (!VirtualQuery(ptr,&mbi,sizeof(mbi))) {
+		FIXME(int31,"reallocing non DPMI_xalloced region?\n");
+		return NULL;
+	}
+	/* We do not shrink allocated memory. most reallocs only do grows
+	 * anyway
+	 */
+	if (newsize<=mbi.RegionSize)
+		return ptr;
+
+	newptr = DPMI_xalloc(newsize);
+	memcpy(newptr,ptr,newsize);
+	DPMI_xfree(ptr);
+	return newptr;
+}
+/**********************************************************************
  *	    INT_GetRealModeContext
  */
 static void INT_GetRealModeContext( REALMODECALL *call, CONTEXT *context )
@@ -121,7 +189,7 @@
         {
         case 0x15:
             /* MSCDEX hook */
-            do_mscdex( &realmode_ctx );
+            do_mscdex( &realmode_ctx, 1 );
             break;
         default:
             SET_CFLAG(context);
@@ -207,12 +275,28 @@
                         break;
                     }
                 }
-            break;
+                break;
             default:
                 SET_CFLAG(context);
                 break;
             }
             break;
+	case 0x60: {/* CANONICALIZE PATH */
+		LPCSTR path = (LPCSTR)DOSMEM_MapRealToLinear((DS_reg(&realmode_ctx)<<16)+SI_reg(&realmode_ctx));
+
+		TRACE(int31,"TRUENAME %s\n",path);
+		if (!GetFullPathName32A( 
+		    path,
+		    128,
+		    (LPSTR)DOSMEM_MapRealToLinear(
+		    (ES_reg(&realmode_ctx)<<16)+DI_reg(&realmode_ctx)),
+		    NULL
+		))
+		    SET_CFLAG(context);
+		else
+		    AX_reg(&realmode_ctx) = 0;
+	    }
+	    break;
         default:
             SET_CFLAG(context);
             break;
@@ -525,7 +609,8 @@
 	break;
 
     case 0x0205:  /* Set protected mode interrupt vector */
-    	TRACE(int31,"set protected mode interrupt handler (0x%02x,0x%08lx), stub!\n",BL_reg(context),PTR_SEG_OFF_TO_LIN(CX_reg(context),DX_reg(context)));
+    	TRACE(int31,"set protected mode interrupt handler (0x%02x,0x%08lx), stub!\n",
+            BL_reg(context),PTR_SEG_OFF_TO_LIN(CX_reg(context),DX_reg(context)));
 	INT_SetHandler( BL_reg(context),
                         (FARPROC16)PTR_SEG_OFF_TO_SEGPTR( CX_reg(context),
                                                           DX_reg(context) ));
@@ -584,13 +669,11 @@
         }
     case 0x0501:  /* Allocate memory block */
         TRACE(int31,"allocate memory block (%ld)\n",MAKELONG(CX_reg(context),BX_reg(context)));
-	if (!(ptr = (BYTE *)VirtualAlloc(NULL, MAKELONG(CX_reg(context), BX_reg(context)), MEM_COMMIT, PAGE_EXECUTE_READWRITE)))
+	if (!(ptr = (BYTE *)DPMI_xalloc(MAKELONG(CX_reg(context), BX_reg(context)))))
         {
             AX_reg(context) = 0x8012;  /* linear memory not available */
             SET_CFLAG(context);
-        }
-        else
-        {
+        } else {
             BX_reg(context) = SI_reg(context) = HIWORD(ptr);
             CX_reg(context) = DI_reg(context) = LOWORD(ptr);
         }
@@ -598,20 +681,18 @@
 
     case 0x0502:  /* Free memory block */
         TRACE(int31,"free memory block (0x%08lx)\n",MAKELONG(DI_reg(context),SI_reg(context)));
-	VirtualFree((void *)MAKELONG(DI_reg(context), SI_reg(context)), 0, MEM_RELEASE);
+	DPMI_xfree((void *)MAKELONG(DI_reg(context), SI_reg(context)));
         break;
 
     case 0x0503:  /* Resize memory block */
         TRACE(int31,"resize memory block (0x%08lx,%ld)\n",MAKELONG(DI_reg(context),SI_reg(context)),MAKELONG(CX_reg(context),BX_reg(context)));
-        if (!(ptr = (BYTE *)HeapReAlloc( GetProcessHeap(), 0,
+        if (!(ptr = (BYTE *)DPMI_xrealloc(
                            (void *)MAKELONG(DI_reg(context),SI_reg(context)),
                                    MAKELONG(CX_reg(context),BX_reg(context)))))
         {
             AX_reg(context) = 0x8012;  /* linear memory not available */
             SET_CFLAG(context);
-        }
-        else
-        {
+        } else {
             BX_reg(context) = SI_reg(context) = HIWORD(ptr);
             CX_reg(context) = DI_reg(context) = LOWORD(ptr);
         }
diff --git a/msdos/int21.c b/msdos/int21.c
index 723deb3..31d6a93 100644
--- a/msdos/int21.c
+++ b/msdos/int21.c
@@ -1313,6 +1313,13 @@
 
         case 0x01:
             break;
+        case 0x02:{
+           FILE_OBJECT *file;
+           file = FILE_GetFile(BX_reg(context));
+            if (!lstrcmpi32A(file->unix_name, "SCSIMGR$"))
+                        ASPI_DOS_HandleInt(context);
+           break;
+       }
 	case 0x05:{	/* IOCTL - WRITE TO BLOCK DEVICE CONTROL CHANNEL */
 	    /*BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context));*/
 	    int	drive = DOS_GET_DRIVE(BL_reg(context));
diff --git a/msdos/int2f.c b/msdos/int2f.c
index 40878f1..e6a0dd2 100644
--- a/msdos/int2f.c
+++ b/msdos/int2f.c
@@ -32,7 +32,7 @@
         break;
 
     case 0x15: /* mscdex */
-        do_mscdex(context);
+        do_mscdex(context, FALSE );
         break;
 
     case 0x16:
@@ -184,7 +184,7 @@
     }
 }
 
-void do_mscdex( CONTEXT *context )
+void do_mscdex( CONTEXT *context, int dorealmode )
 {
     int drive, count;
     char *p;
@@ -217,7 +217,10 @@
             break;
 
         case 0x0D: /* get drive letters */
-            p = PTR_SEG_OFF_TO_LIN(ES_reg(context), BX_reg(context));
+	    if (dorealmode)
+	    	p = DOSMEM_MapRealToLinear(MAKELONG(BX_reg(context),ES_reg(context)));
+	    else
+		p = PTR_SEG_OFF_TO_LIN(ES_reg(context), BX_reg(context));
             memset( p, 0, MAX_DOS_DRIVES );
             for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
             {
diff --git a/multimedia/audio.c b/multimedia/audio.c
index caf63c6..7ae0251 100644
--- a/multimedia/audio.c
+++ b/multimedia/audio.c
@@ -212,7 +212,7 @@
 		TRACE(mciwave, "Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
 			     (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType,
 			     mmckInfo.cksize);
-		if (mmioRead(MCIWavDev[wDevID].hFile, (HPSTR) lpWaveFormat,
+		if (mmioRead32(MCIWavDev[wDevID].hFile, (HPSTR) lpWaveFormat,
 		    (long) sizeof(PCMWAVEFORMAT)) != (long) sizeof(PCMWAVEFORMAT))
 			return MCIERR_INTERNAL;
 		mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
@@ -263,7 +263,7 @@
 /* always close elements ? */
 
 	if (MCIWavDev[wDevID].hFile != 0) {
-	  mmioClose(MCIWavDev[wDevID].hFile, 0);
+	  mmioClose32(MCIWavDev[wDevID].hFile, 0);
 	  MCIWavDev[wDevID].hFile = 0;
 	}
 
@@ -300,7 +300,7 @@
 	MCIWavDev[wDevID].nUseCount--;
 	if (MCIWavDev[wDevID].nUseCount == 0) {
 	        if (MCIWavDev[wDevID].hFile != 0) {
-		        mmioClose(MCIWavDev[wDevID].hFile, 0);
+		        mmioClose32(MCIWavDev[wDevID].hFile, 0);
 			MCIWavDev[wDevID].hFile = 0;
 		}
 		if (MCIWavDev[wDevID].fInput)
@@ -370,7 +370,7 @@
 	lpWaveHdr->dwLoops = 0L;
 	dwRet=wodMessage(wDevID,WODM_PREPARE,0,(DWORD)lpWaveHdr,sizeof(WAVEHDR));
 	while(TRUE) {
-		count = mmioRead(MCIWavDev[wDevID].hFile, lpWaveHdr->lpData, bufsize);
+		count = mmioRead32(MCIWavDev[wDevID].hFile, lpWaveHdr->lpData, bufsize);
 		TRACE(mciwave,"mmioRead bufsize=%ld count=%ld\n", bufsize, count);
 		if (count < 1) break;
 		lpWaveHdr->dwBufferLength = count;
@@ -1056,10 +1056,12 @@
 		return MMSYSERR_NOTENABLED;
 	}
 	/* FIXME: is NotifyClient with WOM_DONE right ? (Comet Busters 1.3.3 needs this notification) */
+	/* FIXME: Myst crashes with this ... hmm -MM
        	if (WAVE_NotifyClient(wDevID, WOM_DONE, 0L, 0L) != MMSYSERR_NOERROR) {
                	WARN(mciwave, "can't notify client !\n");
                	return MMSYSERR_INVALPARAM;
         }
+	*/
 
 	return MMSYSERR_NOERROR;
 }
diff --git a/multimedia/dsound.c b/multimedia/dsound.c
index 63519fa..5e248b0 100644
--- a/multimedia/dsound.c
+++ b/multimedia/dsound.c
@@ -36,6 +36,7 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
+#include <math.h>	/* Insomnia - pow() function */
 #include "windows.h"
 #include "winerror.h"
 #include "interfaces.h"
@@ -179,6 +180,7 @@
 	TRACE(dsound,"(%p,%ld)\n",this,vol);
 	this->volume = vol;
 	this->volfac = ((double)vol+10000.0)/10000.0;
+
 	return 0;
 }
 
@@ -340,7 +342,7 @@
 static HRESULT WINAPI IDirectSoundBuffer_Unlock(
 	LPDIRECTSOUNDBUFFER this,LPVOID p1,DWORD x1,LPVOID p2,DWORD x2
 ) {
-	FIXME(dsound,"(%p,%p,%ld,%p,%ld):stub\n", this,p1,x1,p2,x2);
+/*	FIXME(dsound,"(%p,%p,%ld,%p,%ld):stub\n", this,p1,x1,p2,x2); */
 	return 0;
 }
 
@@ -356,6 +358,7 @@
 	LPDIRECTSOUNDBUFFER this,LPDIRECTSOUND dsound,LPDSBUFFERDESC dbsd
 ) {
 	FIXME(dsound,"(%p,%p,%p):stub\n",this,dsound,dbsd);
+	printf("Re-Init!!!\n");
 	return DSERR_ALREADYINITIALIZED;
 }
 
@@ -622,7 +625,29 @@
 	int	j,buflen = dsb->buflen;
 	LPDSBPOSITIONNOTIFY	nextevent;
 	int	xdiff = dsb->wfx.nSamplesPerSec-dsound->wfx.nSamplesPerSec;
-	double	volfac = dsb->volfac;
+
+	/* Insomnia - Going along with REAL author's style */
+	long	Rvoldec, Lvoldec;
+	long	pan = dsb->pan;
+	long samp;	/* temporary sample workspace */
+
+	{
+		double	tmpr=dsb->volume-500;
+		double  tmpl=tmpr;
+		if(pan>0)  tmpl -= (double)pan;
+		else  tmpr += (double)pan;
+		tmpl /= 1000.0;
+		tmpr /= 1000.0;
+		tmpl = pow(2.0, tmpl);
+		tmpr = pow(2.0, tmpr);
+		tmpl *= 65536;	/* Set to the correct multiple times */
+		tmpr *= 65536;	/* 65536 to be convenient for bit shifting */
+		tmpl += 0.5;	/* Add .5 for rounding accuracy */
+		tmpr += 0.5;
+		Lvoldec = (long)tmpl;
+		Rvoldec = (long)tmpr;
+	}
+	/* End Insomnia's mod */
 
 	if (xdiff<0) xdiff=-xdiff;
 	if (xdiff>1500) {
@@ -646,9 +671,26 @@
 						dsb->playpos = buflen;
 						return;
 					}
-					/* FIXME: pan,volume */
-					playbuf8[(j<<1)  ]+=xbuf[dsb->playpos]*volfac;
-					playbuf8[(j<<1)+1]+=xbuf[dsb->playpos]*volfac;
+					/* Insomnia- volume, panning, and correcting against wrap */
+					/* Left Channel */
+					samp = xbuf[dsb->playpos>>1];
+					samp *= Lvoldec;
+					samp >>= 16;
+					samp += playbuf8[(j<<1)];
+					if(samp > 127L)  samp = 127L;
+					else if(samp < -128L)  samp = -128L;
+					playbuf8[(j<<1)] = (short)samp;
+
+					/* Right Channel */
+					samp = xbuf[dsb->playpos>>1];
+					samp *= Rvoldec;
+					samp >>= 16;
+					samp += playbuf8[(j<<1)+1];
+					if(samp > 127L)  samp = 127L;
+					else if(samp < -128L)  samp = -128L;
+					playbuf8[(j<<1)+1] = (short)samp;
+					/* End Insomnia's mod */
+
 					CHECK_EVENT
 				}
 			} else {
@@ -659,8 +701,21 @@
 						dsb->playpos = buflen;
 						return;
 					}
-					/* FIXME: pan,volume */
-					playbuf8[j]+=xbuf[dsb->playpos]*volfac;
+					/* Insomnia- volume, panning, and correcting against wrap */
+					samp = xbuf[dsb->playpos>>1];
+
+					/* Right Channel */
+					if(j&1) samp *= Rvoldec;
+					/* Left Channel */
+					else    samp *= Lvoldec;
+
+					samp >>= 16;
+					samp += playbuf8[j];
+					if(samp > 127L)  samp = 127L;
+					else if(samp < -128L)  samp = -128L;
+					playbuf8[j] = (short)samp;
+					/* End Insomnia's mod */
+
 					CHECK_EVENT
 				}
 			}
@@ -674,9 +729,26 @@
 						dsb->playpos = buflen;
 						return;
 					}
-					/* FIXME: pan,volume */
-					playbuf8[(j<<1)  ]+=(xbuf[dsb->playpos>>1]>>8)*volfac;
-					playbuf8[(j<<1)+1]+=(xbuf[dsb->playpos>>1]>>8)*volfac;
+					/* Insomnia- volume, panning, and correcting against wrap */
+					/* Left Channel */
+					samp = xbuf[dsb->playpos>>1];
+					samp *= Lvoldec;
+					samp >>= 24;
+					samp += playbuf8[(j<<1)];
+					if(samp > 127L)  samp = 127L;
+					else if(samp < -128L)  samp = -128L;
+					playbuf8[(j<<1)] = (short)samp;
+
+					/* Right Channel */
+					samp = xbuf[dsb->playpos>>1];
+					samp *= Rvoldec;
+					samp >>= 24;
+					samp += playbuf8[(j<<1)+1];
+					if(samp > 127L)  samp = 127L;
+					else if(samp < -128L)  samp = -128L;
+					playbuf8[(j<<1)+1] = (short)samp;
+					/* End Insomnia's mod */
+
 					CHECK_EVENT
 				}
 			} else {
@@ -687,16 +759,31 @@
 						dsb->playpos = buflen;
 						return;
 					}
-					/* FIXME: pan,volume */
-					playbuf8[j]+=(xbuf[dsb->playpos>>1]>>8)*volfac;
+					/* Insomnia- volume, panning, and correcting against wrap */
+					samp = xbuf[dsb->playpos>>1];
+
+					/* Right Channel */
+					if(j&1) samp *= Rvoldec;
+					/* Left Channel */
+					else    samp *= Lvoldec;
+
+					samp >>= 24;
+					samp += playbuf8[j];
+					if(samp > 127L)  samp = 127L;
+					else if(samp < -128L)  samp = -128L;
+					playbuf8[j] = (short)samp;
+					/* End Insomnia's mod */
+
 					CHECK_EVENT
 				}
 			}
 		}
 	} else { /* 16 bit */
 		if (dsb->wfx.wBitsPerSample == 8) {
-			unsigned char	*xbuf = (unsigned char*)(dsb->buffer);
+/*			unsigned char	*xbuf = (unsigned char*)(dsb->buffer); */
+			char	*xbuf = dsb->buffer;
 			if (dsb->wfx.nChannels == 1) {
+	printf("Mixing 8-bit stereo into 16!!\n");
 				for (j=0;j<sizeof(playbuf)/sizeof(playbuf[0])/2;j++) {
 					dsb->playpos=(dsb->playpos+1)%buflen;
 					if (!dsb->playpos && !(dsb->playflags&DSBPLAY_LOOPING)) {
@@ -704,10 +791,26 @@
 						dsb->playpos = buflen;
 						return;
 					}
-					/* FIXME: pan,volume */
-					/* FIXME: should be *256 */
-					playbuf[(j<<1)  ]+=(xbuf[dsb->playpos]<<7)*volfac;
-					playbuf[(j<<1)+1]+=(xbuf[dsb->playpos]<<7)*volfac;
+					/* Insomnia- volume, panning, and correcting against wrap */
+					/* Left Channel */
+					samp = xbuf[dsb->playpos>>1];
+					samp *= Lvoldec;
+					samp >>= 8;
+					samp += playbuf[(j<<1)];
+					if(samp > 32767L)  samp = 32767L;
+					else if(samp < -32768L)  samp = -32768L;
+					playbuf[(j<<1)] = (short)samp;
+
+					/* Right Channel */
+					samp = xbuf[dsb->playpos>>1];
+					samp *= Rvoldec;
+					samp >>= 8;
+					samp += playbuf[(j<<1)+1];
+					if(samp > 32767L)  samp = 32767L;
+					else if(samp < -32768L)  samp = -32768L;
+					playbuf[(j<<1)+1] = (short)samp;
+					/* End Insomnia's mod */
+
 					CHECK_EVENT
 				}
 			} else {
@@ -718,9 +821,21 @@
 						dsb->playpos = buflen;
 						return;
 					}
-					/* FIXME: pan,volume */
-					/* FIXME: should be *256 */
-					playbuf[j]+=(xbuf[dsb->playpos]<<7)*volfac;
+					/* Insomnia- volume, panning, and correcting against wrap */
+					samp = xbuf[dsb->playpos>>1];
+
+					/* Right Channel */
+					if(j&1) samp *= Rvoldec;
+					/* Left Channel */
+					else    samp *= Lvoldec;
+
+					samp >>= 8;
+					samp += playbuf[j];
+					if(samp > 32767L)  samp = 32767L;
+					else if(samp < -32768L)  samp = -32768L;
+					playbuf[j] = (short)samp;
+					/* End Insomnia's mod */
+
 					CHECK_EVENT
 				}
 			}
@@ -734,9 +849,26 @@
 						dsb->playpos = buflen;
 						return;
 					}
-					/* FIXME: pan,volume */
-					playbuf[(j<<1)  ]+=(xbuf[dsb->playpos>>1]*volfac);
-					playbuf[(j<<1)+1]+=(xbuf[dsb->playpos>>1]*volfac);
+					/* Insomnia- volume, panning, and correcting against wrap */
+					/* Left Channel */
+					samp = xbuf[dsb->playpos>>1];
+					samp *= Lvoldec;
+					samp >>= 16;
+					samp += playbuf[(j<<1)];
+					if(samp > 32767L)  samp = 32767L;
+					else if(samp < -32768L)  samp = -32768L;
+					playbuf[(j<<1)] = (short)samp;
+
+					/* Right Channel */
+					samp = xbuf[dsb->playpos>>1];
+					samp *= Rvoldec;
+					samp >>= 16;
+					samp += playbuf[(j<<1)+1];
+					if(samp > 32767L)  samp = 32767L;
+					else if(samp < -32768L)  samp = -32768L;
+					playbuf[(j<<1)+1] = (short)samp;
+					/* End Insomnia's mod */
+
 					CHECK_EVENT
 				}
 			} else {
@@ -747,8 +879,21 @@
 						dsb->playpos = buflen;
 						return;
 					}
-					/* FIXME: pan,volume */
-					playbuf[j]+=xbuf[dsb->playpos>>1]/**volfac*/;
+					/* Insomnia- volume, panning, and correcting against wrap */
+					samp = xbuf[dsb->playpos>>1];
+
+					/* Right Channel */
+					if(j&1) samp *= Rvoldec;
+					/* Left Channel */
+					else    samp *= Lvoldec;
+
+					samp >>= 16;
+					samp += playbuf[j];
+					if(samp > 32767L)  samp = 32767L;
+					else if(samp < -32768L)  samp = -32768L;
+					playbuf[j] = (short)samp;
+					/* End Insomnia's mod */
+
 					CHECK_EVENT
 				}
 			}
@@ -784,6 +929,8 @@
 		for (i=dsound->nrofbuffers;i--;) {
 			IDirectSoundBuffer	*dsb = dsound->buffers[i];
 
+			if (!dsb || !dsb->lpvtbl)
+				continue;
 			dsb->lpvtbl->fnAddRef(dsb);
 			if (dsb->playing && dsb->buflen)
 				playing++;
@@ -814,6 +961,8 @@
 		for (i=dsound->nrofbuffers;i--;) {
 			IDirectSoundBuffer	*dsb = dsound->buffers[i];
 
+			if (!dsb || !dsb->lpvtbl)
+				continue;
 			dsb->lpvtbl->fnAddRef(dsb);
 			if (dsb->buflen && dsb->playing) {
 				playing++;
@@ -882,7 +1031,7 @@
 		DWORD		xid;
 
 		dsound = (*ppDS);
-		hnd = CreateThread(NULL,NULL,DSOUND_thread,0,0,&xid);
+		hnd = CreateThread(NULL,0,DSOUND_thread,0,0,&xid);
 	}
 	return 0;
 #else
diff --git a/multimedia/mcistring.c b/multimedia/mcistring.c
index 8343241..e32e99d 100644
--- a/multimedia/mcistring.c
+++ b/multimedia/mcistring.c
@@ -2177,9 +2177,9 @@
 			SEGPTR	dname;
 
 			dname=(SEGPTR)GetOpenDrv(wDevID)->lpstrAlias;
-			if (dname==NULL) 
+			if (dname==(SEGPTR)NULL) 
 				dname=(SEGPTR)GetOpenDrv(wDevID)->lpstrDeviceType;
-			if ((dname!=NULL)&&(!STRCMP(PTR_SEG_TO_LIN(dname),dev)))
+			if ((dname!=(SEGPTR)NULL)&&(!STRCMP(PTR_SEG_TO_LIN(dname),dev)))
 				break;
 			wDevID = MMSYSTEM_NextDevID(wDevID);
 			if (!MMSYSTEM_DevIDValid(wDevID)) {
diff --git a/multimedia/midi.c b/multimedia/midi.c
index eec0f82..abcccb5 100644
--- a/multimedia/midi.c
+++ b/multimedia/midi.c
@@ -81,7 +81,7 @@
 static DWORD MIDI_ReadByte(UINT16 wDevID, BYTE *lpbyt)
 {
 	if (lpbyt != NULL) {
-		if (mmioRead(MCIMidiDev[wDevID].hFile, (HPSTR)lpbyt,
+		if (mmioRead32(MCIMidiDev[wDevID].hFile, (HPSTR)lpbyt,
 			(long) sizeof(BYTE)) == (long) sizeof(BYTE)) {
 			return 0;
 		}
@@ -166,11 +166,11 @@
 	DWORD	toberead;
 	FOURCC	fourcc;
 	TRACE(midi, "(%04X, %08lX);\n", wDevID, dwOffset);
-	if (mmioSeek(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
+	if (mmioSeek32(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
 		WARN(midi, "can't seek at %08lX begin of 'MThd' \n", dwOffset);
 		return MCIERR_INTERNAL;
 	}
-	if (mmioRead(MCIMidiDev[wDevID].hFile, (HPSTR)&fourcc,
+	if (mmioRead32(MCIMidiDev[wDevID].hFile, (HPSTR)&fourcc,
 		(long) sizeof(FOURCC)) != (long) sizeof(FOURCC))
 		return MCIERR_INTERNAL;
 	if (MIDI_ReadLong(wDevID, &toberead) != 0)
@@ -198,10 +198,10 @@
 {
 	DWORD	toberead;
 	FOURCC	fourcc;
-	if (mmioSeek(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
+	if (mmioSeek32(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
 		WARN(midi, "can't seek at %08lX begin of 'MThd' \n", dwOffset);
 		}
-	if (mmioRead(MCIMidiDev[wDevID].hFile, (HPSTR)&fourcc,
+	if (mmioRead32(MCIMidiDev[wDevID].hFile, (HPSTR)&fourcc,
 		(long) sizeof(FOURCC)) != (long) sizeof(FOURCC)) {
 		return MCIERR_INTERNAL;
 		}
@@ -290,12 +290,12 @@
 			WARN(midi, "can't read 'MThd' header \n");
 			return MCIERR_INTERNAL;
 		}
-		dwOffset = mmioSeek(MCIMidiDev[wDevID].hFile, 0, SEEK_CUR);
+		dwOffset = mmioSeek32(MCIMidiDev[wDevID].hFile, 0, SEEK_CUR);
 		if (MIDI_ReadMTrk(wDevID, dwOffset) != 0) {
 			WARN(midi, "can't read 'MTrk' header \n");
 			return MCIERR_INTERNAL;
 		}
-		dwOffset = mmioSeek(MCIMidiDev[wDevID].hFile, 0, SEEK_CUR);
+		dwOffset = mmioSeek32(MCIMidiDev[wDevID].hFile, 0, SEEK_CUR);
 		MCIMidiDev[wDevID].dwBeginData = dwOffset;
 		TRACE(midi, "Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
 				(LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
@@ -337,10 +337,10 @@
 	MCIMidiDev[wDevID].nUseCount--;
 	if (MCIMidiDev[wDevID].nUseCount == 0) {
 		if (MCIMidiDev[wDevID].hFile != 0) {
-			mmioClose(MCIMidiDev[wDevID].hFile, 0);
+			mmioClose32(MCIMidiDev[wDevID].hFile, 0);
 			MCIMidiDev[wDevID].hFile = 0;
 			TRACE(midi, "hFile closed !\n");
-			}
+		}
 		USER_HEAP_FREE(MCIMidiDev[wDevID].hMidiHdr);
 		dwRet = modMessage(wDevID, MODM_CLOSE, 0, 0L, 0L);
 		if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
@@ -417,7 +417,7 @@
 			*ptr = LOWORD(dwData);
 		}
 /*
-		count = mmioRead(MCIMidiDev[wDevID].hFile, lpMidiHdr->lpData, lpMidiHdr->dwBufferLength);
+		count = mmioRead32(MCIMidiDev[wDevID].hFile, lpMidiHdr->lpData, lpMidiHdr->dwBufferLength);
 */
 		TRACE(midi, "after read count = %d\n",count);
 
diff --git a/multimedia/mmio.c b/multimedia/mmio.c
index 32922ed..5d88542 100644
--- a/multimedia/mmio.c
+++ b/multimedia/mmio.c
@@ -22,8 +22,8 @@
 #include "xmalloc.h"
 
 /**************************************************************************
-*               mmioDosIOProc           [internal]
-*/
+ *               mmioDosIOProc           [internal]
+ */
 static LRESULT mmioDosIOProc(LPMMIOINFO16 lpmmioinfo, UINT16 uMessage, LPARAM lParam1, LPARAM lParam2) {
 	TRACE(mmio, "(%p, %X, %ld, %ld);\n", lpmmioinfo, uMessage, lParam1, lParam2);
 
@@ -148,7 +148,7 @@
 		}
 
 		default:
-			WARN(mmio, "unexpected message %u\n", uMessage);
+			FIXME(mmio, "unexpected message %u\n", uMessage);
 			return 0;
 	}
 	
@@ -156,9 +156,10 @@
 }
 
 /**************************************************************************
-*               mmioDosIOProc           [internal]
+*               mmioMemIOProc           [internal]
 */
 static LRESULT mmioMemIOProc(LPMMIOINFO16 lpmmioinfo, UINT16 uMessage, LPARAM lParam1, LPARAM lParam2) {
+	FIXME(mmio,"(%p,0x%04x,0x%08lx,0x%08lx), stub!\n",lpmmioinfo,uMessage,lParam1,lParam2);
 	return 0;
 }
 
@@ -248,12 +249,12 @@
 
     
 /**************************************************************************
-* 				mmioClose      		[MMSYSTEM.1211]
-*/
-UINT16 WINAPI mmioClose(HMMIO16 hmmio, UINT16 uFlags)
+ * 				mmioClose      		[WINMM.114]
+ */
+MMRESULT32 WINAPI mmioClose32(HMMIO32 hmmio, UINT32 uFlags)
 {
 	LPMMIOINFO16 lpmminfo;
-	UINT16 result;
+	MMRESULT32 result;
 
 	TRACE(mmio, "(%04X, %04X);\n", hmmio, uFlags);
 
@@ -262,10 +263,10 @@
 		return 0;
 
 	/* flush the file - if error reported, ignore */
-	if (mmioFlush(hmmio, MMIO_EMPTYBUF) != 0)
+	if (mmioFlush32(hmmio, MMIO_EMPTYBUF) != 0)
 		lpmminfo->dwFlags &= ~MMIO_DIRTY;
 
-	result = (UINT16) mmioSendMessage(hmmio, MMIOM_CLOSE, (LPARAM) uFlags, (LPARAM) 0);
+	result = mmioSendMessage(hmmio,MMIOM_CLOSE,(LPARAM)uFlags,(LPARAM)0);
 
 	mmioSetBuffer(hmmio, NULL, 0, 0);
 
@@ -276,11 +277,20 @@
 }
 
 
+/**************************************************************************
+ * 				mmioClose      		[MMSYSTEM.1211]
+ */
+MMRESULT16 WINAPI mmioClose16(HMMIO16 hmmio, UINT16 uFlags)
+{
+	return mmioClose32(hmmio,uFlags);
+}
+
+
 
 /**************************************************************************
-* 				mmioRead	       	[MMSYSTEM.1212]
-*/
-LONG WINAPI mmioRead(HMMIO16 hmmio, HPSTR pch, LONG cch)
+ * 				mmioRead	       	[WINM.124]
+ */
+LONG WINAPI mmioRead32(HMMIO32 hmmio, HPSTR pch, LONG cch)
 {
 	LONG count;
 	LPMMIOINFO16 lpmminfo;
@@ -298,12 +308,18 @@
 	return count;
 }
 
-
+/**************************************************************************
+ * 				mmioRead	       	[MMSYSTEM.1212]
+ */
+LONG WINAPI mmioRead16(HMMIO16 hmmio, HPSTR pch, LONG cch)
+{
+	return mmioRead32(hmmio,pch,cch);
+}
 
 /**************************************************************************
-* 				mmioWrite      		[MMSYSTEM.1213]
-*/
-LONG WINAPI mmioWrite(HMMIO16 hmmio, HPCSTR pch, LONG cch)
+ * 				mmioWrite      		[WINMM.133]
+ */
+LONG WINAPI mmioWrite32(HMMIO32 hmmio, HPCSTR pch, LONG cch)
 {
 	LONG count;
 	LPMMIOINFO16 lpmminfo;
@@ -322,9 +338,17 @@
 }
 
 /**************************************************************************
-* 				mmioSeek       		[MMSYSTEM.1214]
-*/
-LONG WINAPI mmioSeek(HMMIO16 hmmio, LONG lOffset, int iOrigin)
+ * 				mmioWrite      		[MMSYSTEM.1213]
+ */
+LONG WINAPI mmioWrite16(HMMIO16 hmmio, HPCSTR pch, LONG cch)
+{
+	return mmioWrite32(hmmio,pch,cch);
+}
+
+/**************************************************************************
+ * 				mmioSeek       		[MMSYSTEM.1214]
+ */
+LONG WINAPI mmioSeek32(HMMIO32 hmmio, LONG lOffset, INT32 iOrigin)
 {
 	int offset;
 	LPMMIOINFO16 lpmminfo;
@@ -342,9 +366,17 @@
 }
 
 /**************************************************************************
-* 				mmioGetInfo	       	[MMSYSTEM.1215]
-*/
-UINT16 WINAPI mmioGetInfo(HMMIO16 hmmio, MMIOINFO16 * lpmmioinfo, UINT16 uFlags)
+ * 				mmioSeek       		[MMSYSTEM.1214]
+ */
+LONG WINAPI mmioSeek16(HMMIO16 hmmio, LONG lOffset, INT16 iOrigin)
+{
+	return mmioSeek32(hmmio,lOffset,iOrigin);
+}
+
+/**************************************************************************
+ * 				mmioGetInfo	       	[MMSYSTEM.1215]
+ */
+UINT16 WINAPI mmioGetInfo16(HMMIO16 hmmio, MMIOINFO16 * lpmmioinfo, UINT16 uFlags)
 {
 	LPMMIOINFO16	lpmminfo;
 	TRACE(mmio, "mmioGetInfo\n");
@@ -356,6 +388,38 @@
 }
 
 /**************************************************************************
+ * 				mmioGetInfo	       	[WINMM.118]
+ */
+UINT32 WINAPI mmioGetInfo32(HMMIO32 hmmio, MMIOINFO32*lpmmioinfo, UINT32 uFlags)
+{
+	MMIOINFO16	mmioinfo;
+	LPMMIOINFO16	lpmminfo=&mmioinfo;
+	UINT16		ret;
+
+	TRACE(mmio, "(0x%04x,%p,0x%08x)\n",hmmio,lpmmioinfo,uFlags);
+	ret = mmioGetInfo16(hmmio,&mmioinfo,uFlags);
+	if (!ret)
+		return 0;
+	lpmmioinfo->dwFlags	= lpmminfo->dwFlags;
+	lpmmioinfo->fccIOProc	= lpmminfo->fccIOProc;
+	lpmmioinfo->pIOProc	= (LPMMIOPROC32)lpmminfo->pIOProc;
+	lpmmioinfo->wErrorRet	= lpmminfo->wErrorRet;
+	lpmmioinfo->htask	= lpmminfo->htask;
+	lpmmioinfo->cchBuffer	= lpmminfo->cchBuffer;
+	lpmmioinfo->pchBuffer	= lpmminfo->pchBuffer;
+	lpmmioinfo->pchNext	= lpmminfo->pchNext;
+	lpmmioinfo->pchEndRead	= lpmminfo->pchEndRead;
+	lpmmioinfo->pchEndWrite	= lpmminfo->pchEndWrite;
+	lpmmioinfo->lBufOffset	= lpmminfo->lBufOffset;
+	lpmmioinfo->lDiskOffset	= lpmminfo->lDiskOffset;
+	memcpy(lpmmioinfo->adwInfo,lpmminfo->adwInfo,sizeof(lpmminfo->adwInfo));
+	lpmmioinfo->dwReserved1	= lpmminfo->dwReserved1;
+	lpmmioinfo->dwReserved2	= lpmminfo->dwReserved2;
+	lpmmioinfo->hmmio	= lpmminfo->hmmio;
+	return 0;
+}
+
+/**************************************************************************
 * 				mmioSetInfo    		[MMSYSTEM.1216]
 */
 UINT16 WINAPI mmioSetInfo(HMMIO16 hmmio, const MMIOINFO16 * lpmmioinfo, UINT16 uFlags)
@@ -383,9 +447,9 @@
 }
 
 /**************************************************************************
-* 				mmioFlush      		[MMSYSTEM.1218]
-*/
-UINT16 WINAPI mmioFlush(HMMIO16 hmmio, UINT16 uFlags)
+ * 				mmioFlush      		[WINMM.117]
+ */
+UINT32 WINAPI mmioFlush32(HMMIO32 hmmio, UINT32 uFlags)
 {
 	LPMMIOINFO16	lpmminfo;
 	TRACE(mmio, "(%04X, %04X)\n", hmmio, uFlags);
@@ -396,23 +460,51 @@
 }
 
 /**************************************************************************
-* 				mmioAdvance    		[MMSYSTEM.1219]
-*/
-UINT16 WINAPI mmioAdvance(HMMIO16 hmmio, MMIOINFO16 * lpmmioinfo, UINT16 uFlags)
+ * 				mmioFlush      		[MMSYSTEM.1218]
+ */
+UINT16 WINAPI mmioFlush16(HMMIO16 hmmio, UINT16 uFlags)
+{
+	return mmioFlush32(hmmio,uFlags);
+}
+
+/**************************************************************************
+ * 				mmioAdvance    		[MMSYSTEM.1219]
+ */
+UINT32 WINAPI mmioAdvance32(HMMIO32 hmmio,MMIOINFO32*lpmmioinfo,UINT32 uFlags)
 {
 	int		count = 0;
 	LPMMIOINFO16	lpmminfo;
 	TRACE(mmio, "mmioAdvance\n");
 	lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) return 0;
-	if (uFlags == MMIO_READ) {
+	if (uFlags == MMIO_READ)
 		count = _lread32(LOWORD(lpmminfo->adwInfo[0]), 
 			lpmmioinfo->pchBuffer, lpmmioinfo->cchBuffer);
-		}
-	if (uFlags == MMIO_WRITE) {
+	if (uFlags == MMIO_WRITE)
 		count = _lwrite32(LOWORD(lpmminfo->adwInfo[0]),
 			lpmmioinfo->pchBuffer, lpmmioinfo->cchBuffer);
-		}
+	lpmmioinfo->pchNext	+= count;
+	GlobalUnlock16(hmmio);
+	lpmminfo->lDiskOffset = _llseek32((HFILE32)lpmminfo->adwInfo[0], 0, SEEK_CUR);
+	return 0;
+}
+
+/**************************************************************************
+ * 				mmioAdvance    		[MMSYSTEM.1219]
+ */
+UINT16 WINAPI mmioAdvance16(HMMIO16 hmmio,MMIOINFO16*lpmmioinfo,UINT16 uFlags)
+{
+	int		count = 0;
+	LPMMIOINFO16	lpmminfo;
+	TRACE(mmio, "mmioAdvance\n");
+	lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
+	if (lpmminfo == NULL) return 0;
+	if (uFlags == MMIO_READ)
+		count = _lread32(LOWORD(lpmminfo->adwInfo[0]), 
+			lpmmioinfo->pchBuffer, lpmmioinfo->cchBuffer);
+	if (uFlags == MMIO_WRITE)
+		count = _lwrite32(LOWORD(lpmminfo->adwInfo[0]),
+			lpmmioinfo->pchBuffer, lpmmioinfo->cchBuffer);
 	lpmmioinfo->pchNext	+= count;
 	GlobalUnlock16(hmmio);
 	lpmminfo->lDiskOffset = _llseek32((HFILE32)lpmminfo->adwInfo[0], 0, SEEK_CUR);
@@ -444,8 +536,7 @@
  */
 FOURCC WINAPI mmioStringToFOURCC16(LPCSTR sz, UINT16 uFlags)
 {
-	FIXME(mmio, "empty stub \n");
-	return 0;
+	return mmioFOURCC(sz[0],sz[1],sz[2],sz[3]);
 }
 
 /**************************************************************************
@@ -554,12 +645,12 @@
 	dwfcc = lpck->ckid;
 	TRACE(mmio, "dwfcc=%08lX\n", dwfcc);
 
-	dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
+	dwOldPos = mmioSeek32(hmmio, 0, SEEK_CUR);
 	TRACE(mmio, "dwOldPos=%ld\n", dwOldPos);
 
 	if (lpckParent != NULL) {
 		TRACE(mmio, "seek inside parent at %ld !\n", lpckParent->dwDataOffset);
-		dwOldPos = mmioSeek(hmmio, lpckParent->dwDataOffset, SEEK_SET);
+		dwOldPos = mmioSeek32(hmmio,lpckParent->dwDataOffset,SEEK_SET);
 	}
 /*
 
@@ -574,11 +665,11 @@
 		while (TRUE) {
 		        LONG ix;
 
-			ix = mmioRead(hmmio, (LPSTR)lpck, sizeof(MMCKINFO));
+			ix = mmioRead32(hmmio, (LPSTR)lpck, sizeof(MMCKINFO));
 			TRACE(mmio, "after _lread32 ix = %ld req = %d, errno = %d\n",ix,sizeof(MMCKINFO),errno);
 			if (ix < sizeof(MMCKINFO)) {
 
-				mmioSeek(hmmio, dwOldPos, SEEK_SET);
+				mmioSeek32(hmmio, dwOldPos, SEEK_SET);
 				WARN(mmio, "return ChunkNotFound\n");
 				return MMIOERR_CHUNKNOTFOUND;
 			}
@@ -590,12 +681,12 @@
 			dwOldPos += lpck->cksize + 2 * sizeof(DWORD);
 			if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) 
 				dwOldPos += sizeof(DWORD);
-			mmioSeek(hmmio, dwOldPos, SEEK_SET);
+			mmioSeek32(hmmio, dwOldPos, SEEK_SET);
 		}
 	}
 	else {
-		if (mmioRead(hmmio, (LPSTR)lpck, sizeof(MMCKINFO)) < sizeof(MMCKINFO)) {
-			mmioSeek(hmmio, dwOldPos, SEEK_SET);
+		if (mmioRead32(hmmio, (LPSTR)lpck, sizeof(MMCKINFO)) < sizeof(MMCKINFO)) {
+			mmioSeek32(hmmio, dwOldPos, SEEK_SET);
 			WARN(mmio, "return ChunkNotFound 2nd\n");
 			return MMIOERR_CHUNKNOTFOUND;
 		}
@@ -603,7 +694,7 @@
 	lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
 	if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) 
 		lpck->dwDataOffset += sizeof(DWORD);
-	mmioSeek(hmmio, lpck->dwDataOffset, SEEK_SET);
+	mmioSeek32(hmmio, lpck->dwDataOffset, SEEK_SET);
 
 	TRACE(mmio, "lpck->ckid=%08lX lpck->cksize=%ld !\n", 
 								lpck->ckid, lpck->cksize);
@@ -613,17 +704,25 @@
 }
 
 /**************************************************************************
-* 				mmioAscend     		[MMSYSTEM.1224]
-*/
-UINT16 WINAPI mmioAscend(HMMIO16 hmmio, MMCKINFO * lpck, UINT16 uFlags)
+ * 				mmioAscend     		[WINMM.113]
+ */
+UINT32 WINAPI mmioAscend32(HMMIO32 hmmio, MMCKINFO * lpck, UINT32 uFlags)
 {
 	FIXME(mmio, "empty stub !\n");
 	return 0;
 }
 
 /**************************************************************************
-* 				mmioCreateChunk		[MMSYSTEM.1225]
-*/
+ * 				mmioAscend     		[MMSYSTEM.1224]
+ */
+UINT16 WINAPI mmioAscend16(HMMIO16 hmmio, MMCKINFO * lpck, UINT16 uFlags)
+{
+	return mmioAscend32(hmmio,lpck,uFlags);
+}
+
+/**************************************************************************
+ * 				mmioCreateChunk		[MMSYSTEM.1225]
+ */
 UINT16 WINAPI mmioCreateChunk(HMMIO16 hmmio, MMCKINFO * lpck, UINT16 uFlags)
 {
 	FIXME(mmio, "empty stub \n");
@@ -632,8 +731,8 @@
 
 
 /**************************************************************************
-* 				mmioRename     		[MMSYSTEM.1226]
-*/
+ * 				mmioRename     		[MMSYSTEM.1226]
+ */
 UINT16 WINAPI mmioRename(LPCSTR szFileName, LPCSTR szNewFileName,
                          MMIOINFO16 * lpmmioinfo, DWORD dwRenameFlags)
 {
diff --git a/multimedia/mmsystem.c b/multimedia/mmsystem.c
index 275cc17..5888ca5 100644
--- a/multimedia/mmsystem.c
+++ b/multimedia/mmsystem.c
@@ -201,7 +201,7 @@
 		    TRACE(mmsys, "Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
 				(LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize);
 
-		    if (mmioRead(hmmio, (HPSTR) &pcmWaveFormat,
+		    if (mmioRead32(hmmio,(HPSTR)&pcmWaveFormat,
 			        (long) sizeof(PCMWAVEFORMAT)) == (long) sizeof(PCMWAVEFORMAT))
 		    {
 
@@ -246,7 +246,7 @@
 				{
 				    while( TRUE )
 				    {
-					count = mmioRead(hmmio, waveHdr.lpData, bufsize);
+					count = mmioRead32(hmmio,waveHdr.lpData,bufsize);
 					if (count < 1) break;
 					waveHdr.dwBufferLength = count;
 				/*	waveHdr.dwBytesRecorded = count; */
@@ -269,7 +269,7 @@
 	    }
 	}
 
-	if (hmmio != 0) mmioClose(hmmio, 0);
+	if (hmmio != 0) mmioClose32(hmmio, 0);
 	return bRet;
 }
 
@@ -3631,48 +3631,46 @@
 }
 
 /**************************************************************************
-* 				DrvOpen	       		[MMSYSTEM.1100]
-*/
+ * 				DrvOpen	       		[MMSYSTEM.1100]
+ */
 HDRVR16 WINAPI DrvOpen(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam)
 {
-	TRACE(mmsys, "('%s', '%s', %08lX);\n",
-		lpDriverName, lpSectionName, lParam);
-	return OpenDriver(lpDriverName, lpSectionName, lParam);
+	TRACE(mmsys,"('%s','%s',%08lX);\n",lpDriverName,lpSectionName,lParam);
+	return OpenDriver16(lpDriverName, lpSectionName, lParam);
 }
 
 
 /**************************************************************************
-* 				DrvClose       		[MMSYSTEM.1101]
-*/
+ * 				DrvClose       		[MMSYSTEM.1101]
+ */
 LRESULT WINAPI DrvClose(HDRVR16 hDrvr, LPARAM lParam1, LPARAM lParam2)
 {
 	TRACE(mmsys, "(%04X, %08lX, %08lX);\n", hDrvr, lParam1, lParam2);
-	return CloseDriver(hDrvr, lParam1, lParam2);
+	return CloseDriver16(hDrvr, lParam1, lParam2);
 }
 
 
 /**************************************************************************
-* 				DrvSendMessage		[MMSYSTEM.1102]
-*/
+ * 				DrvSendMessage		[MMSYSTEM.1102]
+ */
 LRESULT WINAPI DrvSendMessage(HDRVR16 hDriver, WORD msg, LPARAM lParam1,
                               LPARAM lParam2)
 {
 	DWORD 	dwDriverID = 0;
-	TRACE(mmsys, "(%04X, %04X, %08lX, %08lX);\n",
+	FIXME(mmsys, "(%04X, %04X, %08lX, %08lX);\n",
 					hDriver, msg, lParam1, lParam2);
+	/* FIXME: wrong ... */
 	return CDAUDIO_DriverProc(dwDriverID, hDriver, msg, lParam1, lParam2);
 }
 
 /**************************************************************************
-* 				DrvGetModuleHandle	[MMSYSTEM.1103]
-*/
-HANDLE16 WINAPI DrvGetModuleHandle(HDRVR16 hDrvr)
+ * 				DrvGetModuleHandle	[MMSYSTEM.1103]
+ */
+HANDLE16 WINAPI DrvGetModuleHandle16(HDRVR16 hDrvr)
 {
-	TRACE(mmsys, "(%04X);\n", hDrvr);
-        return 0;
+        return GetDriverModuleHandle16(hDrvr);
 }
 
-
 /**************************************************************************
  * 				DrvDefDriverProc	[MMSYSTEM.1104]
  */
diff --git a/objects/clipping.c b/objects/clipping.c
index ac7119e..78b3d79 100644
--- a/objects/clipping.c
+++ b/objects/clipping.c
@@ -178,8 +178,14 @@
        {
 	   dc->w.hClipRgn = newRgn;
 	   CLIPPING_UpdateGCRegion( dc );
+           return SIMPLEREGION;
        }
-       return SIMPLEREGION;
+       else if( flags & CLIP_EXCLUDE )
+       {
+           dc->w.hClipRgn = CreateRectRgn32( 0, 0, 0, 0 );
+     	   CombineRgn32( dc->w.hClipRgn, dc->w.hVisRgn, 0, RGN_COPY );
+       }
+       else WARN(clipping,"No hClipRgn and flags are %x\n",flags);
     }
 
     ret = CombineRgn32( newRgn, dc->w.hClipRgn, newRgn, 
diff --git a/objects/cursoricon.c b/objects/cursoricon.c
index 439660f..18f1721 100644
--- a/objects/cursoricon.c
+++ b/objects/cursoricon.c
@@ -43,6 +43,7 @@
 #include "user.h"
 #include "keyboard.h"
 #include "x11drv.h"
+#include "winerror.h"
 
 Cursor CURSORICON_XCursor = None;    /* Current X cursor */
 static HCURSOR32 hActiveCursor = 0;  /* Active cursor */
@@ -1471,8 +1472,26 @@
         }
         return res;
 }
+/***********************************************************************
+*            LoadCursorFromFile32W    (USER32.361)
+*/
+HCURSOR32 WINAPI LoadCursorFromFile32W (LPCWSTR name)
+{       FIXME(cursor, ":stub LoadCursorFromFile32W\n");
+	SetLastError(ERROR_CALL_NOT_IMPLEMENTED);  
+	return 0;
+}
 
 /***********************************************************************
+*            LoadCursorFromFile32A    (USER32.360)
+*/
+HCURSOR32 WINAPI LoadCursorFromFile32A (LPCSTR name)
+{	FIXME(cursor, ":stub LoadCursorFromFile32A %s\n", name);
+	SetLastError(ERROR_CALL_NOT_IMPLEMENTED);  
+	return 0;
+
+}
+  
+/***********************************************************************
  *           LoadIconW          (USER32.364)
  */
 HICON32 WINAPI LoadIcon32W(HINSTANCE32 hInstance, LPCWSTR name)
diff --git a/objects/dc.c b/objects/dc.c
index 80a5b94..751430d 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -132,6 +132,7 @@
     win_dc_info->GraphicsMode        = GM_COMPATIBLE;
     win_dc_info->DCOrgX              = 0;
     win_dc_info->DCOrgY              = 0;
+    win_dc_info->lpfnPrint           = NULL;
     win_dc_info->CursPosX            = 0;
     win_dc_info->CursPosY            = 0;
     win_dc_info->ArcDirection        = AD_COUNTERCLOCKWISE;
diff --git a/objects/dib.c b/objects/dib.c
index e41edeb..4f88ee9 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -1074,6 +1074,7 @@
     DC_SetupGCForText( dc );  /* To have the correct colors */
     TSXSetFunction( display, dc->u.x.gc, DC_XROPfunction[dc->w.ROPmode-1] );
 
+    descr.dc = dc;
     if (descr.infoBpp <= 8)
     {
         descr.colorMap = DIB_BuildColorMap( info, coloruse == DIB_PAL_COLORS?
@@ -1083,8 +1084,6 @@
         if (!descr.colorMap)
             return 0;
     }
-
-    descr.dc        = dc;
     descr.bits      = bits;
     descr.lines     = tmpheight >= 0 ? lines : -lines;
     descr.infoWidth = width;
diff --git a/objects/enhmetafile.c b/objects/enhmetafile.c
index 9275278..eac0c8e 100644
--- a/objects/enhmetafile.c
+++ b/objects/enhmetafile.c
@@ -444,14 +444,16 @@
   HANDLETABLE32 *ht = (HANDLETABLE32 *)GlobalAlloc32(GPTR, 
 				    sizeof(HANDLETABLE32)*count);
   BOOL32 ret = FALSE;
+  INT32 savedMode = 0;
   if (lpRect) {
     LPENHMETAHEADER h = (LPENHMETAHEADER) p;
     FLOAT xscale = (h->rclBounds.right-h->rclBounds.left)/(lpRect->right-lpRect->left);
     FLOAT yscale = (h->rclBounds.bottom-h->rclBounds.top)/(lpRect->bottom-lpRect->top);
     XFORM xform = {xscale, 0, 0, yscale, 0, 0};
-    /*    xform.eDx = lpRect->left;
-	  xform.eDy = lpRect->top; */
+        xform.eDx = lpRect->left;
+	  xform.eDy = lpRect->top; 
     FIXME(metafile, "play into rect doesn't work\n");
+    savedMode = SetGraphicsMode(hdc, GM_ADVANCED);
     if (!SetWorldTransform(hdc, &xform)) {
       WARN(metafile, "World transform failed!\n");
     }
@@ -464,6 +466,7 @@
     p = (void *) p + p->nSize; /* casted so that arithmetic is in bytes */
   }
   GlobalUnlock32(hmf);
+  if (savedMode) SetGraphicsMode(hdc, savedMode);
   ret = TRUE; /* FIXME: calculate a more accurate return value */
   return ret;
 }
diff --git a/objects/text.c b/objects/text.c
index 2172379..f7f0cbf 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -12,6 +12,7 @@
 #include "heap.h"
 #include "debug.h"
 #include "cache.h"
+#include "debugstr.h"
 
 #define TAB     9
 #define LF     10
@@ -198,8 +199,9 @@
     int width = rect->right - rect->left;
     int max_width = 0;
 
-    TRACE(text,"'%s', %d , [(%d,%d),(%d,%d)]\n", str,
-		 count, rect->left, rect->top, rect->right, rect->bottom);
+    TRACE(text,"%s, %d , [(%d,%d),(%d,%d)]\n",
+	  debugstr_an (str, count), count,
+	  rect->left, rect->top, rect->right, rect->bottom);
     
     if (count == -1) count = strlen(str);
     strPtr = str;
diff --git a/ole/compobj.c b/ole/compobj.c
index 35eb290..ba84e5d 100644
--- a/ole/compobj.c
+++ b/ole/compobj.c
@@ -554,3 +554,14 @@
     FIXME(ole,"(%p,%d,%d),stub!\n",pUnk,fLock,fLastUnlockReleases);
     return S_OK;
 }
+/***********************************************************************
+ *           CoLockObjectExternal (OLE32.31)
+ */
+HRESULT WINAPI CoLockObjectExternal32(
+    LPUNKNOWN pUnk,		/* [in] object to be locked */
+    BOOL32 fLock,		/* [in] do lock */
+    BOOL32 fLastUnlockReleases	/* [in] ? */
+) {
+    FIXME(ole,"(%p,%d,%d),stub!\n",pUnk,fLock,fLastUnlockReleases);
+    return S_OK;
+}
diff --git a/ole/ole2nls.c b/ole/ole2nls.c
index abba660..a6318dc 100644
--- a/ole/ole2nls.c
+++ b/ole/ole2nls.c
@@ -1692,72 +1692,6 @@
 }
 
 /***********************************************************************
- *           CompareString16       (OLE2NLS.8)
- */
-UINT16 WINAPI CompareString16(DWORD lcid,DWORD fdwStyle,
-                              LPCSTR s1,DWORD l1,LPCSTR s2,DWORD l2)
-{
-	return (UINT16)CompareString32A(lcid,fdwStyle,s1,l1,s2,l2);
-}
-
-/***********************************************************************
- *           CompareString32A   (KERNEL32.29)
- * This implementation ignores the locale
- * FIXME
- */
-UINT32 WINAPI CompareString32A(DWORD lcid, DWORD fdwStyle, 
-                               LPCSTR s1, DWORD l1, LPCSTR s2,DWORD l2)
-{
-	int len,ret;
-	if(fdwStyle & NORM_IGNORENONSPACE)
-		FIXME(ole, "IGNORENONSPACE not supported\n");
-	if(fdwStyle & NORM_IGNORESYMBOLS)
-		FIXME(ole, "IGNORESYMBOLS not supported\n");
-	/* Is strcmp defaulting to string sort or to word sort?? */
-	/* FIXME: Handle NORM_STRINGSORT */
-	l1 = (l1==-1)?strlen(s1):l1;
-	l2 = (l2==-1)?strlen(s2):l2;
-	len = l1<l2 ? l1:l2;
-	ret = (fdwStyle & NORM_IGNORECASE) ?
-		lstrncmpi32A(s1,s2,len)	: lstrncmp32A(s1,s2,len);
-	/* not equal, return 1 or 3 */
-	if(ret!=0)return ret+2;
-	/* same len, return 2 */
-	if(l1==l2)return 2;
-	/* the longer one is lexically greater */
-	return (l1<l2)? 1 : 3;
-}
-
-/***********************************************************************
- *           CompareString32W       (KERNEL32.30)
- * This implementation ignores the locale
- * FIXME
- */
-UINT32 WINAPI CompareString32W(DWORD lcid, DWORD fdwStyle, 
-                               LPCWSTR s1, DWORD l1, LPCWSTR s2,DWORD l2)
-{
-	int len,ret;
-	if(fdwStyle & NORM_IGNORENONSPACE)
-		FIXME(ole,"IGNORENONSPACE not supprted\n");
-	if(fdwStyle & NORM_IGNORESYMBOLS)
-		FIXME(ole,"IGNORESYMBOLS not supported\n");
-
-	/* Is strcmp defaulting to string sort or to word sort?? */
-	/* FIXME: Handle NORM_STRINGSORT */
-	l1 = (l1==-1)?lstrlen32W(s1):l1;
-	l2 = (l2==-1)?lstrlen32W(s2):l2;
-	len = l1<l2 ? l1:l2;
-	ret = (fdwStyle & NORM_IGNORECASE) ?
-		lstrncmpi32W(s1,s2,len)	: lstrncmp32W(s1,s2,len);
-	/* not equal, return 1 or 3 */
-	if(ret!=0) return ret+2;
-	/* same len, return 2 */
-	if(l1==l2) return 2;
-	/* the longer one is lexically greater */
-	return (l1<l2)? 1 : 3;
-}
-
-/***********************************************************************
  *           SetLocaleInfoA       [KERNEL32.499]
  */
 BOOL16 WINAPI SetLocaleInfoA(DWORD lcid, DWORD lctype, LPCSTR data)
@@ -2027,10 +1961,14 @@
 	return langnamelen;
 }
  
-static int is_punctuation(unsigned char c)
+static int is_punctuation(unsigned char c) 
 {
   /* punctuation characters are :
-     39, 45, 127-129, 141-144, 150-151, 157-158, 173 */
+     1-8, 14-31, 39, 45, 127-129, 141-144, 150-151, 157-158, 173 
+
+     "punctuation character" in this context is a character which is 
+     considered "less important" during word sort comparison.
+     See LCMapString for the precise definition of "less important". */
   if (c>=141)
   {
     if (c<=151)
@@ -2041,7 +1979,9 @@
   }
   if (c>=127)
     return (c<=129);
-  return (c==39) || (c==45);
+  if (c>=14)
+    return (c<=31) || (c==39) || (c==45);
+  return (c<=8);
 }
 
 static int identity(int c)
@@ -2050,6 +1990,37 @@
 }
 
 static const unsigned char LCM_Unicode_LUT[] = {
+  6      ,   3, /*   -   1 */  
+  6      ,   4, /*   -   2 */  
+  6      ,   5, /*   -   3 */  
+  6      ,   6, /*   -   4 */  
+  6      ,   7, /*   -   5 */  
+  6      ,   8, /*   -   6 */  
+  6      ,   9, /*   -   7 */  
+  6      ,  10, /*   -   8 */  
+  7      ,   5, /*   -   9 */  
+  7      ,   6, /*   -  10 */  
+  7      ,   7, /*   -  11 */  
+  7      ,   8, /*   -  12 */  
+  7      ,   9, /*   -  13 */  
+  6      ,  11, /*   -  14 */  
+  6      ,  12, /*   -  15 */  
+  6      ,  13, /*   -  16 */  
+  6      ,  14, /*   -  17 */  
+  6      ,  15, /*   -  18 */  
+  6      ,  16, /*   -  19 */  
+  6      ,  17, /*   -  20 */  
+  6      ,  18, /*   -  21 */  
+  6      ,  19, /*   -  22 */  
+  6      ,  20, /*   -  23 */  
+  6      ,  21, /*   -  24 */  
+  6      ,  22, /*   -  25 */  
+  6      ,  23, /*   -  26 */  
+  6      ,  24, /*   -  27 */  
+  6      ,  25, /*   -  28 */  
+  6      ,  26, /*   -  29 */  
+  6      ,  27, /*   -  30 */  
+  6      ,  28, /*   -  31 */  
   7      ,   2, /*   -  32 */
   7      ,  28, /* ! -  33 */
   7      ,  29, /* " -  34 */ /* " */
@@ -2415,14 +2386,17 @@
  * accordingly to the flags LCMAP_UPPERCASE, LCMAP_LOWERCASE,...
  *
  * RETURNS
- *    Error : (destination buffer too small) 0.
+ *    Error : 0.
  *    Success : length of the result string.
  *
  * REMARKS
  *    If called with scrlen = -1, the function will compute the length
  *      of the 0-terminated string strsrc by itself.      
+ * 
+ *    If called with dstlen = 0, returns the buffer length that 
+ *      would be required.
  */
- INT32 WINAPI LCMapString32A(
+INT32 WINAPI LCMapString32A(
 	LCID lcid /* locale identifier created with MAKELCID; 
 		     LOCALE_SYSTEM_DEFAULT and LOCALE_USER_DEFAULT are predefined
 		     values. */,
@@ -2433,17 +2407,20 @@
 	INT32 dstlen   /* destination buffer length */) 
 {
   int i;
- 
+
   TRACE(string,"(0x%04lx,0x%08lx,%s,%d,%p,%d)\n",
 	lcid,mapflags,srcstr,srclen,dststr,dstlen);
 
-  if ((dststr==NULL) || (srcstr==NULL))
+  if ( ((dstlen!=0) && (dststr==NULL)) || (srcstr==NULL) )
+  {
+    SetLastError(ERROR_INVALID_PARAMETER);
     return 0;
+  }
   if (srclen==-1) 
     srclen = lstrlen32A(srcstr);
 
   if (mapflags & ~ ( LCMAP_UPPERCASE | LCMAP_LOWERCASE | LCMAP_SORTKEY |
-		     SORT_STRINGSORT) )
+		     NORM_IGNORECASE | NORM_IGNORENONSPACE | SORT_STRINGSORT) )
   {
     FIXME(string,"(0x%04lx,0x%08lx,%p,%d,%p,%d): "
 	  "unimplemented flags: 0x%08lx\n",
@@ -2457,7 +2434,10 @@
     if (dstlen==0)
       return srclen;  /* dstlen=0 means "do nothing but return required length" */
     if (dstlen<srclen)
-      return 0;       /* it's an error */
+    {
+      SetLastError(ERROR_INSUFFICIENT_BUFFER);
+      return 0;
+    }
     if (mapflags & LCMAP_UPPERCASE)
       f = toupper;
     else if (mapflags & LCMAP_LOWERCASE)
@@ -2472,8 +2452,10 @@
     int unicode_len=0;
     int case_len=0;
     int diacritic_len=0;
+    int delayed_punctuation_len=0;
     char *case_component;
     char *diacritic_component;
+    char *delayed_punctuation_component;
     int room,count;
     int flag_stringsort = mapflags & SORT_STRINGSORT;
 
@@ -2481,89 +2463,117 @@
     for (i=0;i<srclen;i++)
     {
       int ofs;
-      if ((srcstr[i]!='\0') && (flag_stringsort || !is_punctuation(srcstr[i])))
+      unsigned char source_char = srcstr[i];
+      if (source_char!='\0') 
       {
-	unicode_len++;
-	if(((unsigned char)srcstr[i])<=31)
+	if (flag_stringsort || !is_punctuation(source_char))
 	{
-	  FIXME(string," control characters in argument string\n");
-	  return 0;
+	  unicode_len++;
+	  if ( LCM_Unicode_LUT[-2+2*source_char] & ~15 )
+	    unicode_len++;             /* double letter */
 	}
-	if ( LCM_Unicode_LUT[2*((unsigned char)srcstr[i]-32)] & ~15 )
-	  unicode_len++;             /* double letter */
+	else
+	{
+	  delayed_punctuation_len++;
+	}	  
       }
 	  
-      if (isupper(srcstr[i]))
+      if (isupper(source_char))
 	case_len=unicode_len; 
 
-      ofs = (unsigned char)srcstr[i] - LCM_Diacritic_Start;
+      ofs = source_char - LCM_Diacritic_Start;
       if ((ofs>=0) && (LCM_Diacritic_LUT[ofs]!=2))
 	diacritic_len=unicode_len;
     }
 
-    room =  2 * unicode_len         /* "unicode" component */
-      +     diacritic_len           /* "diacritic" component */
-      +     case_len                /* "case" component */
-      +     4                       /* four '\1' separators */
-      +     1  ;                    /* terminal '\0' */
+    if (mapflags & NORM_IGNORECASE)
+      case_len=0;                   
+    if (mapflags & NORM_IGNORENONSPACE)
+      diacritic_len=0;
+
+    room =  2 * unicode_len              /* "unicode" component */
+      +     diacritic_len                /* "diacritic" component */
+      +     case_len                     /* "case" component */
+      +     4 * delayed_punctuation_len  /* punctuation in word sort mode */
+      +     4                            /* four '\1' separators */
+      +     1  ;                         /* terminal '\0' */
     if (dstlen==0)
       return room;      
     else if (dstlen<room)
-      return 0;   
+    {
+      SetLastError(ERROR_INSUFFICIENT_BUFFER);
+      return 0;
+    }
 
     /* locate each component, write separators */
     diacritic_component = dststr + 2*unicode_len ;
     *diacritic_component++ = '\1'; 
-
     case_component = diacritic_component + diacritic_len ;
     *case_component++ = '\1'; 
+    delayed_punctuation_component = case_component + case_len ;
+    *delayed_punctuation_component++ = '\1';
+    *delayed_punctuation_component++ = '\1';
 
     /* read source string char by char, write 
        corresponding weight in each component. */
-    for (i=0,count=0;count<unicode_len;i++)
+    for (i=0,count=0;i<srclen;i++)
     {
-      unsigned char c=srcstr[i];
-      if ( (c!='\0') && (flag_stringsort || !is_punctuation(c)) )
+      unsigned char source_char=srcstr[i];
+      if (source_char!='\0') 
       {
 	int type,longcode;
-	int LUT_offset = 2*(c-32);
-	type = LCM_Unicode_LUT[LUT_offset];
+	type = LCM_Unicode_LUT[-2+2*source_char];
 	longcode = type >> 4;
 	type &= 15;
-	dststr[2*count] = type;
-	dststr[2*count+1] = LCM_Unicode_LUT[LUT_offset+1];  
-	if (longcode)
+	if (!flag_stringsort && is_punctuation(source_char)) 
 	{
-	  if (count<case_len)
-	    case_component[count] = ( isupper(srcstr[i]) ? 18 : 2 ) ;
-	  if (count<diacritic_len)
-	    diacritic_component[count] = 2; /* assumption: a double letter
-					       is never accented */
-	  count++;
+	  UINT16 encrypted_location = (1<<15) + 7 + 4*count;
+	  *delayed_punctuation_component++ = (unsigned char) (encrypted_location>>8);
+	  *delayed_punctuation_component++ = (unsigned char) (encrypted_location&255);
+                     /* big-endian is used here because it lets string comparison be
+			compatible with numerical comparison */
 
+	  *delayed_punctuation_component++ = type;
+	  *delayed_punctuation_component++ = LCM_Unicode_LUT[-1+2*source_char];  
+                     /* assumption : a punctuation character is never a 
+			double or accented letter */
+	}
+	else
+	{
 	  dststr[2*count] = type;
-	  dststr[2*count+1] = *(LCM_Unicode_LUT_2 - 1 + longcode); 
-	  /* 16 in the first column of LCM_Unicode_LUT  -->  longcode = 1 
-	     32 in the first column of LCM_Unicode_LUT  -->  longcode = 2 
-	     48 in the first column of LCM_Unicode_LUT  -->  longcode = 3 */
-	}
+	  dststr[2*count+1] = LCM_Unicode_LUT[-1+2*source_char];  
+	  if (longcode)
+	  {
+	    if (count<case_len)
+	      case_component[count] = ( isupper(source_char) ? 18 : 2 ) ;
+	    if (count<diacritic_len)
+	      diacritic_component[count] = 2; /* assumption: a double letter
+						 is never accented */
+	    count++;
+	    
+	    dststr[2*count] = type;
+	    dststr[2*count+1] = *(LCM_Unicode_LUT_2 - 1 + longcode); 
+	    /* 16 in the first column of LCM_Unicode_LUT  -->  longcode = 1 
+	       32 in the first column of LCM_Unicode_LUT  -->  longcode = 2 
+	       48 in the first column of LCM_Unicode_LUT  -->  longcode = 3 */
+	  }
 
-	if (count<case_len)
-	  case_component[count] = ( isupper(srcstr[i]) ? 18 : 2 ) ;
-	if (count<diacritic_len)
-	{
-	  int ofs = (unsigned char)srcstr[i] - LCM_Diacritic_Start;
-	  diacritic_component[count] = (ofs>=0 ? LCM_Diacritic_LUT[ofs] : 2);
+	  if (count<case_len)
+	    case_component[count] = ( isupper(source_char) ? 18 : 2 ) ;
+	  if (count<diacritic_len)
+	  {
+	    int ofs = source_char - LCM_Diacritic_Start;
+	    diacritic_component[count] = (ofs>=0 ? LCM_Diacritic_LUT[ofs] : 2);
+	  }
+	  count++;
 	}
-	count++;
       }
     }
-    dststr[room-3] = dststr[room-2] = '\1';
     dststr[room-1] = '\0';
     return room;
   }
 }
- 
+		     
 INT32 WINAPI LCMapString32W(
 	LCID lcid,DWORD mapflags,LPCWSTR srcstr,INT32 srclen,LPWSTR dststr,
 	INT32 dstlen)
@@ -2573,8 +2583,11 @@
   TRACE(string,"(0x%04lx,0x%08lx,%p,%d,%p,%d)\n",
 	lcid,mapflags,srcstr,srclen,dststr,dstlen);
 
-  if ((dststr==NULL) || (srcstr==NULL))
+  if ( ((dstlen!=0) && (dststr==NULL)) || (srcstr==NULL) )
+  {
+    SetLastError(ERROR_INVALID_PARAMETER);
     return 0;
+  }
   if (srclen==-1) 
     srclen = lstrlen32W(srcstr);
   if (mapflags & LCMAP_SORTKEY) 
@@ -2602,6 +2615,90 @@
   }
 }
 
+/***********************************************************************
+ *           CompareString16       (OLE2NLS.8)
+ */
+UINT16 WINAPI CompareString16(DWORD lcid,DWORD fdwStyle,
+                              LPCSTR s1,DWORD l1,LPCSTR s2,DWORD l2)
+{
+	return (UINT16)CompareString32A(lcid,fdwStyle,s1,l1,s2,l2);
+}
+
+/***********************************************************************
+ *           CompareString32A   (KERNEL32.29)
+ * This implementation ignores the locale
+ * FIXME
+ * Moreover it is quite inefficient. FIXME too!
+ */
+UINT32 WINAPI CompareString32A(DWORD lcid, DWORD fdwStyle, 
+                               LPCSTR s1, DWORD l1, LPCSTR s2,DWORD l2)
+{
+  int mapstring_flags;
+  int len1,len2;
+
+  TRACE(ole,"%s and %s\n",
+	debugstr_a (s1), debugstr_a (s2));
+
+  if ( (s1==NULL) || (s2==NULL) )
+  {    
+    SetLastError(ERROR_INVALID_PARAMETER);
+    return 0;
+  }
+
+  if(fdwStyle & NORM_IGNORENONSPACE)
+    FIXME(ole, "IGNORENONSPACE not supported\n");
+  if(fdwStyle & NORM_IGNORESYMBOLS)
+    FIXME(ole, "IGNORESYMBOLS not supported\n");
+  	
+  mapstring_flags = LCMAP_SORTKEY | fdwStyle ;
+  len1 = LCMapString32A(lcid,mapstring_flags,s1,l1,NULL,0);
+  len2 = LCMapString32A(lcid,mapstring_flags,s2,l2,NULL,0);
+
+  if ((len1==0)||(len2==0))
+    return 0;     /* something wrong happened */
+
+  {
+    char sk1[len1];    
+    char sk2[len2];    
+    if ( (!LCMapString32A(lcid,mapstring_flags,s1,l1,sk1,len1))
+	 || (!LCMapString32A(lcid,mapstring_flags,s2,l2,sk2,len2)) )
+    {
+      ERR(ole,"Bug in LCmapString32A.");
+      return 0;
+    }
+    return strcmp(sk1,sk2)+2;
+  }
+}
+
+/***********************************************************************
+ *           CompareString32W       (KERNEL32.30)
+ * This implementation ignores the locale
+ * FIXME :  Does only string sort.  Should
+ * be reimplemented the same way as CompareString32A.
+ */
+UINT32 WINAPI CompareString32W(DWORD lcid, DWORD fdwStyle, 
+                               LPCWSTR s1, DWORD l1, LPCWSTR s2,DWORD l2)
+{
+	int len,ret;
+	if(fdwStyle & NORM_IGNORENONSPACE)
+		FIXME(ole,"IGNORENONSPACE not supprted\n");
+	if(fdwStyle & NORM_IGNORESYMBOLS)
+		FIXME(ole,"IGNORESYMBOLS not supported\n");
+
+	/* Is strcmp defaulting to string sort or to word sort?? */
+	/* FIXME: Handle NORM_STRINGSORT */
+	l1 = (l1==-1)?lstrlen32W(s1):l1;
+	l2 = (l2==-1)?lstrlen32W(s2):l2;
+	len = l1<l2 ? l1:l2;
+	ret = (fdwStyle & NORM_IGNORECASE) ?
+		lstrncmpi32W(s1,s2,len)	: lstrncmp32W(s1,s2,len);
+	/* not equal, return 1 or 3 */
+	if(ret!=0) return ret+2;
+	/* same len, return 2 */
+	if(l1==l2) return 2;
+	/* the longer one is lexically greater */
+	return (l1<l2)? 1 : 3;
+}
 
 /*****************************************************************
  *
diff --git a/ole/olecli.c b/ole/olecli.c
index 010f1eb..d4c55de 100644
--- a/ole/olecli.c
+++ b/ole/olecli.c
@@ -106,7 +106,11 @@
 BOOL16 WINAPI OleIsDcMeta16(HDC16 hdc)
 {
 	TRACE(ole,"(%04x)\n",hdc);
-	return GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC ) != 0;
+	if (GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC ) != 0) {
+	    GDI_HEAP_UNLOCK( hdc );
+	    return TRUE;
+	}
+	return FALSE;
 }
 
 
@@ -116,7 +120,11 @@
 BOOL32 WINAPI OleIsDcMeta32(HDC32 hdc)
 {
         TRACE(ole,"(%04x)\n",hdc);
-        return GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC ) != 0;
+	if (GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC ) != 0) {
+	    GDI_HEAP_UNLOCK( hdc );
+	    return TRUE;
+	}
+	return FALSE;
 }
 
 
diff --git a/ole/typelib.c b/ole/typelib.c
index 0f674ab..1ffdbd1 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,(DWORD)lcid,path);
+		FIXME(ole,"(%s,%d,%d,0x%04lx,%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,(DWORD)lcid,path);
+		FIXME(ole,"(%s,%d,%d,0x%04lx,%p),stub!\n",xguid,wMaj,wMin,(DWORD)lcid,path);
 		return E_FAIL;
 	}
 	plen = sizeof(pathname);
diff --git a/programs/clock/ChangeLog b/programs/clock/ChangeLog
index 1162765..5906d79 100644
--- a/programs/clock/ChangeLog
+++ b/programs/clock/ChangeLog
@@ -1,3 +1,9 @@
+Fri Jun 12 22:47:56 1998  Marcel Baur <mbaur@g26.ethz.ch>
+       * Fixed resource bug in UpdateWindowCaption() that caused wrong (old)
+         locale for the displayed date
+       * The digital clock now shows up (WINE-NLS-UNKNOWN means that there
+         is no locale rule for time string format in /ole/winnls.c)
+
 Thu May 28 20:42:13 1998  Marcel Baur <mbaur@g26.ethz.ch>
        * [language.c]
          UpdateWindowCaption(), locale and date
@@ -31,3 +37,4 @@
 
          Originals by Marcel Baur
 
+
diff --git a/programs/clock/License_En.c b/programs/clock/License_En.c
index bec66d9..511bce4 100644
--- a/programs/clock/License_En.c
+++ b/programs/clock/License_En.c
@@ -44,5 +44,5 @@
  ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.";
 
 LICENSE WineLicense_En = {License_En, LicenseCaption_En,
-			  NoWarranty_En, NoWarrantyCaption_En};
+                          NoWarranty_En, NoWarrantyCaption_En};
 
diff --git a/programs/clock/Makefile.in b/programs/clock/Makefile.in
index fdbd2cc..6acd6a8 100644
--- a/programs/clock/Makefile.in
+++ b/programs/clock/Makefile.in
@@ -7,6 +7,7 @@
 PROGRAMS  = clock
 ALL_LIBS  = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS)
 RCFLAGS   = -w32 -h
+WRCEXTRA  = -A -p $*
 
 LANGUAGES   = En Da De Sw
 LICENSELANG = En
@@ -28,27 +29,18 @@
 MOSTOBJS = $(MOSTSRCS:.c=.o)
 STRINGOBJS = $(STRINGSRCS:.c=.o) $(RC_SRCS:.rc=.o)
 
-all: check_winerc $(PROGRAMS)
+all: check_wrc $(PROGRAMS)
 
-depend:: $(RC_SRCS:.rc=.h)
+depend::
 
 @MAKE_RULES@
 
-# Rules for using old resource compiler
-.rc.c:
-	echo "#include \"windows.h\"" >$*-tmp.c
-	echo WINDOWS_H_ENDS_HERE >>$*-tmp.c
-	cat $< >>$*-tmp.c
-	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P $*-tmp.c | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | $(WINERC) $(RCFLAGS) -c -o $* -p $*
-	$(RM) $*-tmp.c
+# Override resource compiler rules
+.rc.s:
+	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P -x c $< | $(WRC) $(WRCFLAGS) $(WRCEXTRA) -o $*.s
+
 .rc.h:
-	echo "#include \"windows.h\"" >$*-tmp.c
-	echo WINDOWS_H_ENDS_HERE >>$*-tmp.c
-	cat $< >>$*-tmp.c
-	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P $*-tmp.c | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | $(WINERC) $(RCFLAGS) -c -o $* -p $*
-	$(RM) $*-tmp.c
-clean::
-	$(RM) $(RC_SRCS:.rc=.c)
+	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P -x c $< | $(WRC) $(WRCFLAGS) $(WRCEXTRA) -nH $*.h
 
 
 clock: $(MOSTOBJS) $(STRINGOBJS)
@@ -57,7 +49,7 @@
 install: dummy
 	$(INSTALL_PROGRAM) clock $(bindir)/clock
 
-$(RC_SRCS:.rc=.c) $(RC_SRCS:.rc=.h): $(WINERC)
+$(RC_SRCS:.rc=.s): $(WRC)
 
 dummy:
 
diff --git a/programs/clock/README b/programs/clock/README
index 40cc048..296a6a2 100644
--- a/programs/clock/README
+++ b/programs/clock/README
@@ -8,11 +8,5 @@
  Please see file TODO for things to do and keep the file ChangeLog
  up to date.
 
- Code is currently under heavy construction. Nearly all files will 
- change until next release. You can speed up development of clock
- if you send patches and additions directly to my personal email 
- address <mbaur@g26.ethz.ch>.
-
- I also try to read news:comp.emulators.ms-windows.wine frequently, 
- so I can also integrate patches posted via usenet.
-
+ Code is currently under heavy construction. Please direct patches and
+ additions to my personal email address <mbaur@g26.ethz.ch>
diff --git a/programs/clock/TODO b/programs/clock/TODO
index 7d15d1a..f8336f0 100644
--- a/programs/clock/TODO
+++ b/programs/clock/TODO
@@ -2,35 +2,21 @@
 Some ideas for improvements:
 ============================
 
-- Add Font Selection Dialog (should be CommDlg).
-
 - Make "Without Titlebar", Double-clicking the clock should reveal the caption
   again.
 
 - Move the "Without Titlebar" into the System Menu (as in Windows)
-
-- Implement a "digital clock"
+  (Does not work probably due to Winelib)
 
 - Font Handling of Digital Clock.
-
-- Make distinction between analog clock and digital clock according to
-  Globals.bAnalog setting / CL_ANALOG menu event.
-
-- Implement Date (Window caption), but mind the different languages.
-
-- Make distinction between Date / no Date according to
-  Globals.bDate setting / CL_DATE menu event.
+  (Does not work probably due to Winelib)
 
 - Implement Timer Mechanism instead Polling.
   Clock does not run if menu is being selected (?).
 
-- Fix Clock Background (sometimes destroyed).
-  ( This is because the old "Hands" are removed one more time )
-
 - Fix English translation by comparing strings from an original English
   Windows Clock application (I only have a German version).
 
 - Add new .rc resources for all languages you know.
 
-
 Please don't forget a ChangeLog entry.
diff --git a/programs/clock/clock.rc b/programs/clock/clock.rc
index 2d79ea5..756b836 100644
--- a/programs/clock/clock.rc
+++ b/programs/clock/clock.rc
@@ -4,6 +4,7 @@
  * Copyright 1998 Marcel Baur <mbaur@g26.ethz.ch>
  */
 
+#include "windows.h"
 #include "main.h"
  
 #define CONCAT(a, b) CONCAT1(a, b)
diff --git a/programs/clock/language.c b/programs/clock/language.c
index aa920a7..a41ae6f 100644
--- a/programs/clock/language.c
+++ b/programs/clock/language.c
@@ -38,6 +38,9 @@
                        MF_BYCOMMAND | MF_UNCHECKED);
         CheckMenuItem(Globals.hPropertiesMenu, CL_DIGITAL, \
                        MF_BYCOMMAND | MF_CHECKED);
+        EnableMenuItem(Globals.hPropertiesMenu, CL_FONT, \
+                       MF_BYCOMMAND);
+                       
     }
     
     CheckMenuItem(Globals.hPropertiesMenu, CL_WITHOUT_TITLE, MF_BYCOMMAND | \
@@ -123,10 +126,8 @@
   LoadString(Globals.hInstance, IDS_LANGUAGE_ID, lang, sizeof(lang));
   Globals.lpszLanguage = lang;
 
-  LANGUAGE_UpdateWindowCaption();
-
   /* Change Resource names */
-  lstrcpyn(STRING_MENU_Xx    + sizeof(STRING_MENU_Xx)    - 3, lang, 3);
+  lstrcpyn(STRING_MENU_Xx + sizeof(STRING_MENU_Xx) - 3, lang, 3);
 
   /* Create menu */
   hMainMenu = LoadMenu(Globals.hInstance, STRING_MENU_Xx);
@@ -157,6 +158,7 @@
    /* specific for Clock: */
 
    LANGUAGE_UpdateMenuCheckmarks();
+   LANGUAGE_UpdateWindowCaption();   
 }
 
 VOID LANGUAGE_DefaultHandle(WPARAM wParam)
diff --git a/programs/clock/main.c b/programs/clock/main.c
index d73558b..e5c6591 100644
--- a/programs/clock/main.c
+++ b/programs/clock/main.c
@@ -213,8 +213,6 @@
       LIBWINE_Register_Sw();
     #endif
 
-    printf("WinMain()\n");
-    
     /* Setup Globals */
     Globals.bAnalog	    = TRUE;
     Globals.bSeconds        = TRUE;
@@ -255,12 +253,17 @@
     SetMenu(Globals.hMainWnd, Globals.hMainMenu);
 
     Globals.hSystemMenu = GetSystemMenu(Globals.hMainWnd, TRUE);
+
+    /*
+        FIXME: The next few lines are an attempt to add a menu item to the 
+               window system menu. 
+    */
     
     AppendMenu(Globals.hSystemMenu, MF_STRING | MF_BYCOMMAND, 1000, "item");
     SetSystemMenu(Globals.hMainWnd, Globals.hSystemMenu);
 
-    EnableMenuItem(Globals.hPropertiesMenu, CL_FONT, \
-                    MF_BYCOMMAND | MF_GRAYED);
+    LANGUAGE_UpdateMenuCheckmarks();
+
     ShowWindow (Globals.hMainWnd, show);
     UpdateWindow (Globals.hMainWnd);
 
@@ -279,4 +282,3 @@
     return 0;    
 }
 
-
diff --git a/programs/clock/winclock.c b/programs/clock/winclock.c
index 8a3dea0..5baf5eb 100644
--- a/programs/clock/winclock.c
+++ b/programs/clock/winclock.c
@@ -28,6 +28,7 @@
 #include "winclock.h"
 #include "windows.h"
 #include "main.h"
+#include "winnls.h"
 
 COLORREF FaceColor = RGB(192,192,192);
 COLORREF HandColor = RGB(0,0,0);
@@ -153,8 +154,8 @@
     Ex = MidX+sin(Pos*Pi/3000)*XExt;
     Ey = MidY-cos(Pos*Pi/3000)*YExt;
     rv = ( Sx!=OldSecond.StartX || Ex!=OldSecond.EndX ||
-  	 Sy!=OldSecond.StartY || Ey!=OldSecond.EndY );
-    if (Globals.bAnalog && rv)DrawSecondHand(dc);
+           Sy!=OldSecond.StartY || Ey!=OldSecond.EndY );
+    if (Globals.bAnalog && rv) DrawSecondHand(dc);
     OldSecond.StartX = Sx; OldSecond.EndX = Ex;
     OldSecond.StartY = Sy; OldSecond.EndY = Ey;
     OldSecond.DontRedraw=FALSE;
@@ -163,22 +164,40 @@
   return rv;
 }
 
-void Idle(HDC idc)
-{
-  SYSTEMTIME st;
-  TEXTMETRIC tm;
+void DigitalClock(HDC dc) {
+
+  CHAR szTime[MAX_STRING_LEN];
+  LPSTR time = szTime;
   static short xChar, yChar;
+  TEXTMETRIC tm;
+  
+  SYSTEMTIME st;
+  LPSYSTEMTIME lpst = &st;
+  
+  GetLocalTime(&st);
+  GetTimeFormat(LOCALE_USER_DEFAULT, LOCALE_STIMEFORMAT, lpst, NULL, time, 
+                MAX_STRING_LEN);
+                
+  SelectObject(dc,CreatePen(PS_SOLID,1,FaceColor));
+  xChar = tm.tmAveCharWidth;
+  yChar = tm.tmHeight;
+  
+  xChar = 100;
+  yChar = 100;
+  TextOut (dc, xChar, yChar, szTime, strlen (szTime)); 
+  DeleteObject(SelectObject(dc,GetStockObject(NULL_PEN)));
+              
+}
+
+
+
+void AnalogClock(HDC dc) {
+
+  SYSTEMTIME st;
   WORD H, M, S, F;
   int MidX, MidY, DiffX, DiffY;
-  HDC dc;
   BOOL Redraw;
 
-  if(idc)
-    dc=idc;
-  else
-    dc=GetDC(Globals.hMainWnd);
-  if(!dc)return;
-
   GetLocalTime(&st);
   H = st.wHour;
   M = st.wMinute;
@@ -197,26 +216,36 @@
   if(UpdateHourHand(dc,MidX+DiffX,MidY+DiffY,MidX*0.5,MidY*0.5,H)) Redraw = TRUE;
   if(UpdateMinuteHand(dc,MidX+DiffX,MidY+DiffY,MidX*0.65,MidY*0.65,M)) Redraw = TRUE;
   if(UpdateSecondHand(dc,MidX+DiffX,MidY+DiffY,MidX*0.79,MidY*0.79,F)) Redraw = TRUE;
-  if (Globals.bAnalog)
-  {
-    DeleteObject(SelectObject(dc,CreatePen(PS_SOLID,1,HandColor)));
-      if(Redraw)
+
+  DeleteObject(SelectObject(dc,CreatePen(PS_SOLID,1,HandColor)));
+    if(Redraw)
       {
         DrawSecondHand(dc);
         DrawMinuteHand(dc);
         DrawHourHand(dc);
       }
-    DeleteObject(SelectObject(dc,GetStockObject(NULL_PEN))); 
+  DeleteObject(SelectObject(dc,GetStockObject(NULL_PEN))); 
+  
+}
+
+void Idle(HDC idc)
+{
+  HDC context;
+
+  if(idc)
+        context=idc;
+  else
+        context=GetDC(Globals.hMainWnd);
+
+  if (!context) return;
+
+  if (Globals.bAnalog)
+  {
+    AnalogClock(context);
   }
   else 
   {
-    SelectObject(dc,CreatePen(PS_SOLID,1,FaceColor));
-    xChar = tm.tmAveCharWidth;
-    yChar = tm.tmHeight;
-    TextOut (dc, xChar, yChar, "Hola", strlen ("Hola")); 
-    DeleteObject(SelectObject(dc,GetStockObject(NULL_PEN)));
+    DigitalClock(context);
   }
-  if(!idc) ReleaseDC(Globals.hMainWnd,dc);
+  if(!idc) ReleaseDC(Globals.hMainWnd, context);
 }
-
-//    class.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
diff --git a/programs/clock/winclock.h b/programs/clock/winclock.h
index d30fbbc..c5f5117 100644
--- a/programs/clock/winclock.h
+++ b/programs/clock/winclock.h
@@ -21,8 +21,6 @@
 
 
 void DrawFace(HDC dc);
-
-
 void DrawHourHand(HDC dc);
 void DrawMinuteHand(HDC dc);
 void DrawSecondHand(HDC dc);
@@ -30,4 +28,3 @@
 BOOL UpdateMinuteHand(HDC dc,int MidX,int MidY,int XExt,int YExt,WORD Pos);
 BOOL UpdateSecondHand(HDC dc,int MidX,int MidY,int XExt,int YExt,WORD Pos);
 void Idle(HDC idc);
-
diff --git a/programs/notepad/ChangeLog b/programs/notepad/ChangeLog
index 0c2d705..8186dc7 100644
--- a/programs/notepad/ChangeLog
+++ b/programs/notepad/ChangeLog
@@ -1,4 +1,7 @@
-Henrik Olsen <henrik@iaeste.dk>
+Fri Jun 12 23:29:44 1998  Marcel Baur  <mbaur@g26.ethz.ch>
+        * Fixed GetDateFormat()->GetTimeFormat() for locale time.
+
+Mon May 25 14:30:00 1998  Henrik Olsen <henrik@iaeste.dk>
         * [Da.rc]
         Added Danish language support.
 
@@ -46,4 +49,3 @@
           [license.c] [license.h] [License_En.c]
           [README] [TODO] [ChangeLog]
           Originals by Marcel Baur
-
diff --git a/programs/notepad/Makefile.in b/programs/notepad/Makefile.in
index f6fe961..46fed24 100644
--- a/programs/notepad/Makefile.in
+++ b/programs/notepad/Makefile.in
@@ -7,6 +7,7 @@
 PROGRAMS  = notepad
 ALL_LIBS  = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS)
 RCFLAGS   = -w32 -h
+WRCEXTRA  = -A -p $*
 
 LANGUAGES   = En Da De Fr Sw
 LICENSELANG = En
@@ -28,27 +29,18 @@
 MOSTOBJS = $(MOSTSRCS:.c=.o)
 STRINGOBJS = $(STRINGSRCS:.c=.o) $(RC_SRCS:.rc=.o)
 
-all: check_winerc $(PROGRAMS)
+all: check_wrc $(PROGRAMS)
 
-depend:: $(RC_SRCS:.rc=.h)
+depend::
 
 @MAKE_RULES@
 
-# Rules for using old resource compiler
-.rc.c:
-	echo "#include \"windows.h\"" >$*-tmp.c
-	echo WINDOWS_H_ENDS_HERE >>$*-tmp.c
-	cat $< >>$*-tmp.c
-	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P $*-tmp.c | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | $(WINERC) $(RCFLAGS) -c -o $* -p $*
-	$(RM) $*-tmp.c
+# Override resource compiler rules
+.rc.s:
+	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P -x c $< | $(WRC) $(WRCFLAGS) $(WRCEXTRA) -o $*.s
+
 .rc.h:
-	echo "#include \"windows.h\"" >$*-tmp.c
-	echo WINDOWS_H_ENDS_HERE >>$*-tmp.c
-	cat $< >>$*-tmp.c
-	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P $*-tmp.c | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | $(WINERC) $(RCFLAGS) -c -o $* -p $*
-	$(RM) $*-tmp.c
-clean::
-	$(RM) $(RC_SRCS:.rc=.c)
+	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P -x c $< | $(WRC) $(WRCFLAGS) $(WRCEXTRA) -nH $*.h
 
 
 notepad: $(MOSTOBJS) $(STRINGOBJS)
@@ -57,7 +49,7 @@
 install: dummy
 	$(INSTALL_PROGRAM) notepad $(bindir)/notepad
 
-$(RC_SRCS:.rc=.c) $(RC_SRCS:.rc=.h): $(WINERC)
+$(RC_SRCS:.rc=.s): $(WRC)
 
 dummy:
 
diff --git a/programs/notepad/TODO b/programs/notepad/TODO
index 27e8fff..13f15f6 100644
--- a/programs/notepad/TODO
+++ b/programs/notepad/TODO
@@ -7,10 +7,6 @@
  - 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)
    
diff --git a/programs/notepad/dialog.c b/programs/notepad/dialog.c
index 1721dcd..3fb491a 100644
--- a/programs/notepad/dialog.c
+++ b/programs/notepad/dialog.c
@@ -430,7 +430,7 @@
   
   printf("Date: %s\n", date);
   
-  GetDateFormat(LOCALE_USER_DEFAULT, LOCALE_STIMEFORMAT, lpst, NULL, date, MAX_STRING_LEN);
+  GetTimeFormat(LOCALE_USER_DEFAULT, LOCALE_STIMEFORMAT, lpst, NULL, date, MAX_STRING_LEN);
   
   printf("Time: %s\n", date);
 
diff --git a/programs/notepad/notepad.rc b/programs/notepad/notepad.rc
index 26ade63..e79b88d 100644
--- a/programs/notepad/notepad.rc
+++ b/programs/notepad/notepad.rc
@@ -4,6 +4,7 @@
  * Copyright 1997 Marcel Baur <mbaur@g26.ethz.ch>
  */
 
+#include "windows.h"
 #include "main.h"
  
 #define CONCAT(a, b) CONCAT1(a, b)
diff --git a/programs/progman/Makefile.in b/programs/progman/Makefile.in
index 4af58b8..0a6e2cd 100644
--- a/programs/progman/Makefile.in
+++ b/programs/progman/Makefile.in
@@ -7,6 +7,7 @@
 PROGRAMS  = progman
 ALL_LIBS  = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS)
 RCFLAGS   = -w32 -h
+WRCEXTRA  = -A -p $*
 
 LANGUAGES   = En Da De Fr Fi Ko Hu It Va Sw
 LICENSELANG = En
@@ -33,27 +34,18 @@
 MOSTOBJS = $(MOSTSRCS:.c=.o)
 STRINGOBJS = $(STRINGSRCS:.c=.o) $(RC_SRCS:.rc=.o)
 
-all: check_winerc $(PROGRAMS)
+all: check_wrc $(PROGRAMS)
 
 depend:: $(RC_SRCS:.rc=.h)
 
 @MAKE_RULES@
 
-# Rules for using old resource compiler
-.rc.c:
-	echo "#include \"windows.h\"" >$*-tmp.c
-	echo WINDOWS_H_ENDS_HERE >>$*-tmp.c
-	cat $< >>$*-tmp.c
-	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P $*-tmp.c | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | $(WINERC) $(RCFLAGS) -c -o $* -p $*
-	$(RM) $*-tmp.c
+# Override resource compiler rules
+.rc.s:
+	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P -x c $< | $(WRC) $(WRCFLAGS) $(WRCEXTRA) -o $*.s
+
 .rc.h:
-	echo "#include \"windows.h\"" >$*-tmp.c
-	echo WINDOWS_H_ENDS_HERE >>$*-tmp.c
-	cat $< >>$*-tmp.c
-	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P $*-tmp.c | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | $(WINERC) $(RCFLAGS) -c -o $* -p $*
-	$(RM) $*-tmp.c
-clean::
-	$(RM) $(RC_SRCS:.rc=.c)
+	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P -x c $< | $(WRC) $(WRCFLAGS) $(WRCEXTRA) -nH $*.h
 
 
 progman: $(MOSTOBJS) $(STRINGOBJS)
@@ -62,7 +54,7 @@
 install: dummy
 	$(INSTALL_PROGRAM) progman $(bindir)/progman
 
-$(RC_SRCS:.rc=.c) $(RC_SRCS:.rc=.h): $(WINERC)
+$(RC_SRCS:.rc=.s): $(WRC)
 
 dummy:
 
diff --git a/programs/progman/Xx.rc b/programs/progman/Xx.rc
index e08b09e..6f5a96a 100644
--- a/programs/progman/Xx.rc
+++ b/programs/progman/Xx.rc
@@ -4,6 +4,7 @@
  * Copyright 1996 Ulrich Schmid
  */
 
+#include "windows.h"
 #include "progman.h"
 
 #define CONCAT(a, b) CONCAT1(a, b)
diff --git a/programs/progman/accel.rc b/programs/progman/accel.rc
index 3409682..11f0208 100644
--- a/programs/progman/accel.rc
+++ b/programs/progman/accel.rc
@@ -1,3 +1,4 @@
+#include "windows.h"
 #include "progman.h"
 
 ACCEL ACCELERATORS
diff --git a/programs/regtest/Makefile.in b/programs/regtest/Makefile.in
index 0749c8c..98683d4 100644
--- a/programs/regtest/Makefile.in
+++ b/programs/regtest/Makefile.in
@@ -7,6 +7,7 @@
 PROGRAMS  = regtest
 ALL_LIBS  = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS)
 RCFLAGS   = -w32 -h
+WRCEXTRA  = -A -p $*
 
 C_SRCS = regtest.c
 
diff --git a/programs/regtest/regtest.c b/programs/regtest/regtest.c
index d038cbb..161548b 100644
--- a/programs/regtest/regtest.c
+++ b/programs/regtest/regtest.c
@@ -90,8 +90,10 @@
     lSts = RegCreateKey(HKEY_LOCAL_MACHINE,"\\asdf",&hkey);
     if (lSts != ERROR_BAD_PATHNAME) fprintf(stderr, " 3:%ld\n",lSts);
 
+#if 0
     lSts = RegCreateKey(HKEY_LOCAL_MACHINE,"asdf\\",&hkey);
     if (lSts != ERROR_INVALID_PARAMETER) fprintf(stderr, " 4:%ld\n",lSts);
+#endif
 
     lSts = RegCreateKey(HKEY_LOCAL_MACHINE,"\\asdf\\",&hkey);
     if (lSts != ERROR_BAD_PATHNAME) fprintf(stderr, " 5:%ld\n",lSts);
@@ -347,7 +349,7 @@
     HKEY hkey;
     fprintf(stderr, "Testing RegOpenKey...\n");
 
-    lSts = RegOpenKey((HKEY)2, "",&hkey);
+    lSts = RegOpenKey((HKEY)72, "",&hkey);
     if (lSts != ERROR_SUCCESS) fprintf(stderr, " 1:%ld\n",lSts);
     RegCloseKey(hkey);
 
diff --git a/programs/view/Makefile.in b/programs/view/Makefile.in
index df891ad..0aea7f6 100644
--- a/programs/view/Makefile.in
+++ b/programs/view/Makefile.in
@@ -7,6 +7,7 @@
 PROGRAMS  = view
 ALL_LIBS  = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS)
 RCFLAGS   = -w32 -h
+WRCEXTRA  = -A -p $*
 
 C_SRCS = \
 	init.c \
@@ -16,27 +17,18 @@
 RC_SRCS = \
 	viewrc.rc
 
-all: check_winerc $(PROGRAMS)
+all: check_wrc $(PROGRAMS)
 
 depend:: $(RC_SRCS:.rc=.h)
 
 @MAKE_RULES@
 
-# Rules for using old resource compiler
-.rc.c:
-	echo "#include \"windows.h\"" >$*-tmp.c
-	echo WINDOWS_H_ENDS_HERE >>$*-tmp.c
-	cat $< >>$*-tmp.c
-	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P $*-tmp.c | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | $(WINERC) $(RCFLAGS) -c -o $* -p $*
-	$(RM) $*-tmp.c
+# Override resource compiler rules
+.rc.s:
+	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P -x c $< | $(WRC) $(WRCFLAGS) $(WRCEXTRA) -o $*.s
+
 .rc.h:
-	echo "#include \"windows.h\"" >$*-tmp.c
-	echo WINDOWS_H_ENDS_HERE >>$*-tmp.c
-	cat $< >>$*-tmp.c
-	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P $*-tmp.c | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | $(WINERC) $(RCFLAGS) -c -o $* -p $*
-	$(RM) $*-tmp.c
-clean::
-	$(RM) $(RC_SRCS:.rc=.c)
+	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P -x c $< | $(WRC) $(WRCFLAGS) $(WRCEXTRA) -nH $*.h
 
 
 view: $(OBJS)
@@ -45,7 +37,7 @@
 install: dummy
 	$(INSTALL_PROGRAM) view $(bindir)/view
 
-$(RC_SRCS:.rc=.c) $(RC_SRCS:.rc=.h): $(WINERC)
+$(RC_SRCS:.rc=.s): $(WRC)
 
 dummy:
 
diff --git a/programs/view/viewrc.rc b/programs/view/viewrc.rc
index c3eb400..d9782a4 100644
--- a/programs/view/viewrc.rc
+++ b/programs/view/viewrc.rc
@@ -1,3 +1,4 @@
+#include "windows.h"
 #include "resource.h"
 
 /////////////////////////////////////////////////////////////////////////////
diff --git a/programs/winhelp/Makefile.in b/programs/winhelp/Makefile.in
index 2b71249c..76c40f0 100644
--- a/programs/winhelp/Makefile.in
+++ b/programs/winhelp/Makefile.in
@@ -7,6 +7,7 @@
 PROGRAMS  = winhelp hlp2sgml
 ALL_LIBS  = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS)
 RCFLAGS   = -w32 -h
+WRCEXTRA  = -A -p $*
 
 LANGUAGES   = En Da De Fr Fi Ko Hu It Va Sw
 
@@ -28,27 +29,18 @@
 MOSTOBJS = $(MOSTSRCS:.c=.o) $(EXTRA_OBJS)
 STRINGOBJS = $(STRINGSRCS:.c=.o) $(RC_SRCS:.rc=.o)
 
-all: check_winerc $(PROGRAMS)
+all: check_wrc $(PROGRAMS)
 
 depend:: $(RC_SRCS:.rc=.h) y.tab.h
 
 @MAKE_RULES@
 
-# Rules for using old resource compiler
-.rc.c:
-	echo "#include \"windows.h\"" >$*-tmp.c
-	echo WINDOWS_H_ENDS_HERE >>$*-tmp.c
-	cat $< >>$*-tmp.c
-	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P $*-tmp.c | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | $(WINERC) $(RCFLAGS) -c -o $* -p $*
-	$(RM) $*-tmp.c
+# Override resource compiler rules
+.rc.s:
+	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P -x c $< | $(WRC) $(WRCFLAGS) $(WRCEXTRA) -o $*.s
+
 .rc.h:
-	echo "#include \"windows.h\"" >$*-tmp.c
-	echo WINDOWS_H_ENDS_HERE >>$*-tmp.c
-	cat $< >>$*-tmp.c
-	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P $*-tmp.c | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | $(WINERC) $(RCFLAGS) -c -o $* -p $*
-	$(RM) $*-tmp.c
-clean::
-	$(RM) $(RC_SRCS:.rc=.c)
+	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P -x c $< | $(WRC) $(WRCFLAGS) $(WRCEXTRA) -nH $*.h
 
 # Some strings need addresses >= 0x10000
 winhelp: $(MOSTOBJS) $(STRINGOBJS)
@@ -67,7 +59,7 @@
 lex.yy.c: macro.lex.l
 	$(LEX) -8 -i $(SRCDIR)/macro.lex.l
 
-$(RC_SRCS:.rc=.c) $(RC_SRCS:.rc=.h): $(WINERC)
+$(RC_SRCS:.rc=.s): $(WRC)
 
 dummy:
 
diff --git a/programs/winhelp/Xx.rc b/programs/winhelp/Xx.rc
index d2e713b..cfe0b82 100644
--- a/programs/winhelp/Xx.rc
+++ b/programs/winhelp/Xx.rc
@@ -4,6 +4,7 @@
  * Copyright 1996 Ulrich Schmid
  */
 
+#include "windows.h"
 #include "winhelp.h"
 
 #define CONCAT(a, b) CONCAT1(a, b)
diff --git a/programs/winver/Makefile.in b/programs/winver/Makefile.in
index a44ca84..ed5911b 100644
--- a/programs/winver/Makefile.in
+++ b/programs/winver/Makefile.in
@@ -7,10 +7,11 @@
 PROGRAMS  = winver
 ALL_LIBS  = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS)
 RCFLAGS   = -w32 -h
+WRCEXTRA  = -A -p $*
 
 C_SRCS = winver.c
 
-all: check_winerc $(PROGRAMS)
+all: check_wrc $(PROGRAMS)
 
 @MAKE_RULES@
 
diff --git a/relay32/Makefile.in b/relay32/Makefile.in
index 95fa16c..a8aa55b 100644
--- a/relay32/Makefile.in
+++ b/relay32/Makefile.in
@@ -39,7 +39,8 @@
 
 C_SRCS = \
 	builtin32.c \
-	relay386.c
+	relay386.c \
+	snoop.c
 
 SPEC_FILES = $(DLLS:.spec=.c)
 
diff --git a/relay32/advapi32.spec b/relay32/advapi32.spec
index b3fcc0d..2c95902 100644
--- a/relay32/advapi32.spec
+++ b/relay32/advapi32.spec
@@ -46,8 +46,8 @@
 0042 stdcall FreeSid(ptr) FreeSid
 0043 stub GetAce
 0044 stub GetAclInformation
-0045 stub GetFileSecurityA
-0046 stub GetFileSecurityW
+0045 stdcall GetFileSecurityA(str long ptr long ptr) GetFileSecurity32A
+0046 stdcall GetFileSecurityW(wstr long ptr long ptr) GetFileSecurity32W
 0047 stub GetKernelObjectSecurity
 0048 stdcall GetLengthSid(ptr) GetLengthSid
 0049 stub GetNumberOfEventLogRecords
diff --git a/relay32/builtin32.c b/relay32/builtin32.c
index 3e238ca..afac993 100644
--- a/relay32/builtin32.c
+++ b/relay32/builtin32.c
@@ -299,8 +299,11 @@
     for (table = BuiltinDLLs; table->descr; table++)
         if (!lstrcmpi32A( table->descr->name, dllname )) break;
     if (!table->descr) return 0;
-    if (!table->used && !force) return 0;
-
+    if (!table->used)
+    {
+        if (!force) return 0;
+        table->used = TRUE;  /* So next time we use it at once */
+    }
     return BUILTIN32_DoLoadModule( table, process );
 }
 
@@ -339,7 +342,8 @@
             }
         }
     
-    assert(dll->descr);
+    if (!dll->descr)
+    	return (ENTRYPOINT32)NULL;
 
     /* Now find the function */
 
diff --git a/relay32/comctl32.spec b/relay32/comctl32.spec
index a493dcf..cd5871c 100644
--- a/relay32/comctl32.spec
+++ b/relay32/comctl32.spec
@@ -8,9 +8,9 @@
 
   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
-  6 stdcall CreateStatusWindowA(long ptr long long) CreateStatusWindow32A
+  4 stdcall GetEffectiveClientRect(long long long) GetEffectiveClientRect
+  5 stdcall DrawStatusTextA(long ptr str long) DrawStatusText32A
+  6 stdcall CreateStatusWindowA(long str long long) CreateStatusWindow32A
   7 stdcall CreateToolbar(long long long long long long ptr long) CreateToolbar
   8 stdcall CreateMappedBitmap(long long long ptr long) CreateMappedBitmap
   9 stub COMCTL32_9
@@ -25,14 +25,14 @@
  18 stub CreatePropertySheetPage
  19 stub CreatePropertySheetPageA
  20 stub CreatePropertySheetPageW
- 21 stdcall CreateStatusWindow(long ptr long long) CreateStatusWindow32A
- 22 stdcall CreateStatusWindowW(long ptr long long) CreateStatusWindow32W
+ 21 stdcall CreateStatusWindow(long str long long) CreateStatusWindow32A
+ 22 stdcall CreateStatusWindowW(long wstr long long) CreateStatusWindow32W
  23 stdcall CreateToolbarEx(long long long long long long ptr long long long long long long) CreateToolbarEx
  24 stub DestroyPropertySheetPage
- 25 stub DllGetVersion
+ 25 stdcall DllGetVersion(ptr) COMCTL32_DllGetVersion
  26 stub DllInstall
- 27 stdcall DrawStatusText(long ptr ptr long) DrawStatusText32A
- 28 stdcall DrawStatusTextW(long ptr ptr long) DrawStatusText32W
+ 27 stdcall DrawStatusText(long ptr str long) DrawStatusText32A
+ 28 stdcall DrawStatusTextW(long ptr wstr long) DrawStatusText32W
  29 stub FlatSB_EnableScrollBar
  30 stub FlatSB_GetScrollInfo
  31 stub FlatSB_GetScrollPos
@@ -66,18 +66,18 @@
  59 stdcall ImageList_GetImageCount(ptr) ImageList_GetImageCount
  60 stdcall ImageList_GetImageInfo(ptr long ptr) ImageList_GetImageInfo
  61 stdcall ImageList_GetImageRect(ptr long ptr) ImageList_GetImageRect
- 63 stdcall ImageList_LoadImage(long ptr long long long long long) ImageList_LoadImage32A
- 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
+ 63 stdcall ImageList_LoadImage(long str long long long long long) ImageList_LoadImage32A
+ 63 stdcall ImageList_LoadImageA(long str long long long long long) ImageList_LoadImage32A
+ 64 stdcall ImageList_LoadImageW(long wstr 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
  67 stdcall ImageList_Remove(ptr long) ImageList_Remove
  68 stdcall ImageList_Replace(ptr long long long) ImageList_Replace
  69 stdcall ImageList_ReplaceIcon(ptr long long) ImageList_ReplaceIcon
  70 stdcall ImageList_SetBkColor(ptr long) ImageList_SetBkColor
- 71 stub Alloc
- 72 stub ReAlloc
- 73 stub Free
+ 71 stdcall Alloc(long) Alloc
+ 72 stdcall ReAlloc(long long) ReAlloc
+ 73 stdcall Free(long) Free
  74 stub GetSize
  75 stdcall ImageList_SetDragCursorImage(ptr long long long) ImageList_SetDragCursorImage
  76 stub ImageList_SetFilter
@@ -112,22 +112,22 @@
 235 stub Str_GetPtrW
 236 stub Str_SetPtrW
 
-320 stub DSA_Create
-321 stub DSA_Destroy
+320 stdcall DSA_Create(long long) DSA_Create
+321 stdcall DSA_Destroy(long) DSA_Destroy
 322 stub DSA_GetItem
-323 stub DSA_GetItemPtr
-324 stub DSA_InsertItem
+323 stdcall DSA_GetItemPtr(long long) DSA_GetItemPtr
+324 stdcall DSA_InsertItem(long long long) DSA_InsertItem
 325 stub DSA_SetItem
-326 stub DSA_DeleteItem
+326 stdcall DSA_DeleteItem(long long) DSA_DeleteItem
 327 stub DSA_DeleteAllItems
 
-328 stub DPA_Create
+328 stdcall DPA_Create(long) DPA_Create
 329 stub DPA_Destroy
 330 stub DPA_Grow
 331 stub DPA_Clone
-332 stub DPA_GetPtr
+332 stdcall DPA_GetPtr(long long) DPA_GetPtr
 333 stub DPA_GetPtrIndex
-334 stub DPA_InsertPtr
+334 stdcall DPA_InsertPtr(long long long) DPA_InsertPtr
 335 stub DPA_SetPtr
 336 stub DPA_DeletePtr
 337 stub DPA_DeleteAllPtrs
@@ -137,7 +137,7 @@
 341 stub SendNotify
 342 stub SendNotifyEx
 
-350 stub StrChrA
+350 stdcall StrChrA(long long) COMCTL32_StrChrA
 351 stub StrRChr
 352 stub StrCmpNA
 353 stub StrCmpNIA
diff --git a/relay32/comdlg32.spec b/relay32/comdlg32.spec
index f3c6223..c9006ce 100644
--- a/relay32/comdlg32.spec
+++ b/relay32/comdlg32.spec
@@ -16,7 +16,7 @@
 12 stdcall GetSaveFileNameA(ptr) GetSaveFileName32A
 13 stdcall GetSaveFileNameW(ptr) GetSaveFileName32A
 14 stub LoadAlterBitmap
-15 stub PageSetupDlgA
+15 stdcall PageSetupDlgA(ptr) PageSetupDlg32A
 16 stub PageSetupDlgW
 17 stdcall PrintDlgA(ptr) PrintDlg32A
 18 stdcall PrintDlgW(ptr) PrintDlg32W
diff --git a/relay32/crtdll.spec b/relay32/crtdll.spec
index 5259e53..95a5555 100644
--- a/relay32/crtdll.spec
+++ b/relay32/crtdll.spec
@@ -234,7 +234,7 @@
 230 stub _mbstrlen
 231 stub _mbsupr
 232 stub _memccpy
-233 stub _memicmp
+233 cdecl _memicmp(str str long) CRTDLL__memicmp
 234 cdecl _mkdir(str) CRTDLL__mkdir
 235 stub _mktemp
 236 stub _msize
@@ -321,7 +321,7 @@
 317 stub _utime
 318 stub _vsnprintf
 319 stub _vsnwprintf
-320 stub _wcsdup
+320 cdecl _wcsdup(wstr) CRTDLL__wcsdup
 321 cdecl _wcsicmp(wstr wstr) CRTDLL__wcsicmp
 322 cdecl _wcsicoll(wstr wstr) CRTDLL__wcsicoll
 323 cdecl _wcslwr(wstr) CRTDLL__wcslwr
diff --git a/relay32/kernel32.spec b/relay32/kernel32.spec
index 42e0af7..e403451 100644
--- a/relay32/kernel32.spec
+++ b/relay32/kernel32.spec
@@ -87,9 +87,9 @@
  73 stub K32RtlEnlargedIntegerMultiply
  74 stub K32RtlEnlargedUnsignedMultiply
  75 stub K32RtlEnlargedUnsignedDivide
- 76 stub K32RtlExtendedLargeIntegerDivide
+ 76 stdcall K32RtlExtendedLargeIntegerDivide(long long long ptr) RtlExtendedLargeIntegerDivide
  77 stub K32RtlExtendedMagicDivide
- 78 stub K32RtlExtendedIntegerMultiply
+ 78 stdcall K32RtlExtendedIntegerMultiply(long long long) RtlExtendedIntegerMultiply
  79 stub K32RtlLargeIntegerShiftLeft
  80 stub K32RtlLargeIntegerShiftRight
  81 stub K32RtlLargeIntegerArithmeticShift
@@ -182,7 +182,7 @@
 167 stdcall CreateMutexW(ptr long wstr) CreateMutex32W
 168 stdcall CreateNamedPipeA(str long long long long long long ptr) CreateNamedPipeA
 169 stdcall CreateNamedPipeW(wstr long long long long long long ptr) CreateNamedPipeW
-170 stub CreatePipe
+170 stdcall CreatePipe(ptr ptr ptr long) CreatePipe
 171 stdcall CreateProcessA(str str ptr ptr long long ptr str ptr ptr) CreateProcess32A
 172 stdcall CreateProcessW(wstr wstr ptr ptr long long ptr wstr ptr ptr) CreateProcess32W
 173 stub CreateRemoteThread
@@ -263,7 +263,7 @@
 247 stdcall FindCloseChangeNotification(long) FindCloseChangeNotification
 246 stdcall FindClose(long) FindClose32
 248 stdcall FindFirstChangeNotificationA(str long long) FindFirstChangeNotification32A
-249 stub FindFirstChangeNotificationW
+249 stdcall FindFirstChangeNotificationW(wstr long long) FindFirstChangeNotification32W
 250 stdcall FindFirstFileA(str ptr) FindFirstFile32A
 251 stdcall FindFirstFileW(wstr ptr) FindFirstFile32W
 252 stdcall FindNextChangeNotification(long) FindNextChangeNotification
@@ -390,7 +390,7 @@
 373 stdcall GetProcessAffinityMask(long ptr ptr) GetProcessAffinityMask
 374 stdcall GetProcessFlags(long) GetProcessFlags
 375 stdcall GetProcessHeap() GetProcessHeap
-376 stub GetProcessHeaps
+376 stdcall GetProcessHeaps(long ptr) GetProcessHeaps
 377 stub GetProcessShutdownParameters
 378 stdcall GetProcessTimes(long ptr ptr ptr ptr) GetProcessTimes
 379 stdcall GetProcessVersion(long) GetProcessVersion
@@ -841,7 +841,7 @@
 824 stub HeapSummary
 825 stub HeapUsage
 826 stub InvalidateConsoleDIBits
-827 stub IsDebuggerPresent
+827 stdcall IsDebuggerPresent() IsDebuggerPresent
 829 stub OpenConsoleW
 830 stub QueryWin31IniFilesMappedToRegistry
 831 stub RegisterConsoleVDM
diff --git a/relay32/mpr.spec b/relay32/mpr.spec
index aa2516a..aa83c39 100644
--- a/relay32/mpr.spec
+++ b/relay32/mpr.spec
@@ -71,8 +71,8 @@
 0068 stub WNetFormatNetworkNameA
 0069 stub WNetFormatNetworkNameW
 0070 stdcall WNetGetCachedPassword(ptr long ptr ptr long) WNetGetCachedPassword
-0071 stdcall WNetGetConnectionA(ptr ptr ptr) WNetGetConnection32A
-0072 stub WNetGetConnectionW
+0071 stdcall WNetGetConnectionA(str ptr ptr) WNetGetConnection32A
+0072 stdcall WNetGetConnectionW(wstr ptr ptr) WNetGetConnection32W
 0073 stub WNetGetHomeDirectoryA
 0074 stub WNetGetHomeDirectoryW
 0075 stub WNetGetLastErrorA
diff --git a/relay32/ntdll.spec b/relay32/ntdll.spec
index d8aba3b..2e4a7ec 100644
--- a/relay32/ntdll.spec
+++ b/relay32/ntdll.spec
@@ -108,7 +108,7 @@
 105 stub NtFlushVirtualMemory
 106 stub NtFlushWriteBuffer
 107 stub NtFreeVirtualMemory
-108 stub NtFsControlFile
+108 stdcall NtFsControlFile() NtFsControlFile
 109 stub NtGetContextThread
 110 stub NtGetPlugPlayEvent
 111 stub NtGetTickCount
@@ -149,7 +149,7 @@
 146 stub NtQueryAttributesFile
 147 stub NtQueryDefaultLocale
 148 stub NtQueryDirectoryFile
-149 stdcall NtQueryDirectoryObject(long long) NtQueryDirectoryObject
+149 stdcall NtQueryDirectoryObject(long long long long long long long) NtQueryDirectoryObject
 150 stub NtQueryEaFile
 151 stub NtQueryEvent
 152 stub NtQueryInformationFile
@@ -161,14 +161,14 @@
 158 stub NtQueryIoCompletion
 159 stub NtQueryKey
 160 stub NtQueryMutant
-161 stdcall NtQueryObject(long long) NtQueryObject
+161 stdcall NtQueryObject(long long long long long) NtQueryObject
 162 stub NtQueryPerformanceCounter
 163 stub NtQuerySection
 164 stub NtQuerySecurityObject
 165 stub NtQuerySemaphore
 166 stub NtQuerySymbolicLinkObject
 167 stub NtQuerySystemEnvironmentValue
-168 stdcall NtQuerySystemInformation(long) NtQuerySystemInformation
+168 stdcall NtQuerySystemInformation(long long long long) NtQuerySystemInformation
 169 stub NtQuerySystemTime
 170 stub NtQueryTimer
 171 stub NtQueryTimerResolution
@@ -207,7 +207,7 @@
 204 stub NtSetInformationFile
 205 stub NtSetInformationKey
 206 stub NtSetInformationObject
-207 stdcall NtSetInformationProcess(long) NtSetInformationProcess
+207 stdcall NtSetInformationProcess(long long long long) NtSetInformationProcess
 208 stub NtSetInformationThread
 209 stub NtSetInformationToken
 210 stub NtSetIntervalProfile
@@ -358,8 +358,8 @@
 355 stub RtlEraseUnicodeString
 356 stub RtlExpandEnvironmentStrings_U
 357 stub RtlExtendHeap
-358 stub RtlExtendedIntegerMultiply
-359 stub RtlExtendedLargeIntegerDivide
+358 stdcall RtlExtendedIntegerMultiply(long long long) RtlExtendedIntegerMultiply
+359 stdcall RtlExtendedLargeIntegerDivide(long long long ptr) RtlExtendedLargeIntegerDivide
 360 stub RtlExtendedMagicDivide
 361 stdcall RtlFillMemory(ptr long long) RtlFillMemory
 362 stub RtlFillMemoryUlong
@@ -502,7 +502,7 @@
 499 stub RtlSubtreeSuccessor
 500 stub RtlSystemTimeToLocalTime
 501 stub RtlTimeFieldsToTime
-502 stdcall RtlTimeToElapsedTimeFields(long) RtlTimeToElapsedTimeFields
+502 stdcall RtlTimeToElapsedTimeFields(long long) RtlTimeToElapsedTimeFields
 503 stub RtlTimeToSecondsSince1970
 504 stub RtlTimeToSecondsSince1980
 505 stub RtlTimeToTimeFields
@@ -868,7 +868,7 @@
 865 stub _itoa
 866 stub _ltoa
 867 stub _memccpy
-868 stub _memicmp
+868 cdecl _memicmp(str str long) CRTDLL__memicmp
 869 stub _snprintf
 870 stub _snwprintf
 871 stub _splitpath
diff --git a/relay32/ole32.spec b/relay32/ole32.spec
index 7350c10..cbbf832 100644
--- a/relay32/ole32.spec
+++ b/relay32/ole32.spec
@@ -31,7 +31,7 @@
  28 stub CoIsHandlerConnected
  29 stub CoIsOle1Class
  30 stub CoLoadLibrary
- 31 stub CoLockObjectExternal
+ 31 stdcall CoLockObjectExternal(ptr long long) CoLockObjectExternal32
  32 stub CoMarshalHresult
  33 stub CoMarshalInterThreadInterfaceInStream
  34 stub CoMarshalInterface
diff --git a/relay32/oleaut32.spec b/relay32/oleaut32.spec
index a315b0a..af80955 100644
--- a/relay32/oleaut32.spec
+++ b/relay32/oleaut32.spec
@@ -137,7 +137,7 @@
 164 stdcall QueryPathOfRegTypeLib(ptr long long long ptr) QueryPathOfRegTypeLib32
 165 stub LHashValOfNameSys
 166 stub LHashValOfNameSysA
-170 stub OaBuildVersion
+170 stdcall OaBuildVersion() OaBuildVersion
 171 stub ClearCustData
 180 stub CreateTypeLib2
 183 stub LoadTypeLibEx
diff --git a/relay32/relay386.c b/relay32/relay386.c
index 612bbc5..e586d40 100644
--- a/relay32/relay386.c
+++ b/relay32/relay386.c
@@ -7,6 +7,7 @@
 #ifdef __i386__
 
 #include <assert.h>
+#include <string.h>
 #include "winnt.h"
 #include "windows.h"
 #include "builtin32.h"
@@ -14,6 +15,8 @@
 #include "debugstr.h"
 #include "debug.h"
 
+char **debug_relay_excludelist = NULL, **debug_relay_includelist = NULL;
+
 /***********************************************************************
  *           RELAY_CallFrom32
  *
@@ -26,7 +29,7 @@
  */
 int RELAY_CallFrom32( int ret_addr, ... )
 {
-    int i, ret;
+    int i, ret, show = 1;
     char buffer[80];
     FARPROC32 func;
     unsigned int mask, typemask;
@@ -38,12 +41,41 @@
     WORD nb_args = *(WORD *)(relay_addr + 1) / sizeof(int);
 
     assert(TRACE_ON(relay));
+    GET_FS( fs );
     func = (FARPROC32)BUILTIN32_GetEntryPoint( buffer, relay_addr - 5,
                                                &typemask );
-    DPRINTF( "Call %s(", buffer );
-    args++;
-    for (i = 0, mask = 3; i < nb_args; i++, mask <<= 2)
-    {
+    if(debug_relay_excludelist || debug_relay_includelist) {
+      char *term = strchr(buffer, ':'), **listitem;
+      int len, len2, itemlen;
+
+      if(debug_relay_excludelist) {
+	show = 1;
+	listitem = debug_relay_excludelist;
+      } else {
+	show = 0;
+	listitem = debug_relay_includelist;
+      }
+      assert(term);
+      assert(strlen(term) > 2);
+      len = term - buffer;
+      len2 = strchr(buffer, '.') - buffer;
+      assert(len2 && len2 > 0 && len2 < 64);
+      term += 2;
+      for(; *listitem; listitem++) {
+        itemlen = strlen(*listitem);
+        if((itemlen == len && !strncmp(*listitem, buffer, len)) ||
+           (itemlen == len2 && !strncmp(*listitem, buffer, len2)) ||
+           !strcmp(*listitem, term)) {
+          show = !show;
+          break;
+        }
+      }
+    }
+    if(show) {
+      DPRINTF( "Call %s(", buffer );
+      args++;
+      for (i = 0, mask = 3; i < nb_args; i++, mask <<= 2)
+      {
         if (i) DPRINTF( "," );
 	if ((typemask & mask) && HIWORD(args[i]))
         {
@@ -53,9 +85,10 @@
 	    	DPRINTF( "%08x %s", args[i], debugstr_a((LPCSTR)args[i]) );
 	}
         else DPRINTF( "%08x", args[i] );
-    }
-    GET_FS( fs );
-    DPRINTF( ") ret=%08x fs=%04x\n", ret_addr, fs );
+      }
+      DPRINTF( ") ret=%08x fs=%04x\n", ret_addr, fs );
+    } else
+      args++;
     if (*relay_addr == 0xc3) /* cdecl */
     {
         LRESULT (*cfunc)() = (LRESULT(*)())func;
@@ -136,8 +169,9 @@
             assert(FALSE);
         }
     }
-    DPRINTF( "Ret  %s() retval=%08x ret=%08x fs=%04x\n",
-             buffer, ret, ret_addr, fs );
+    if(show)
+      DPRINTF( "Ret  %s() retval=%08x ret=%08x fs=%04x\n",
+               buffer, ret, ret_addr, fs );
     return ret;
 }
 
@@ -207,31 +241,39 @@
 	 */
 
         relay_addr = *(BYTE **) ESP_reg(&context); 
-        ESP_reg(&context) += sizeof(BYTE *);
-	EIP_reg(&context) = *(DWORD *)ESP_reg(&context);
+        if (BUILTIN32_GetEntryPoint( buffer, relay_addr - 5, &typemask )) {
+	    /* correct win32 spec generated register function found. 
+	     * remove extra call stuff from stack
+	     */
+            ESP_reg(&context) += sizeof(BYTE *);
+	    EIP_reg(&context) = *(DWORD *)ESP_reg(&context);
+	    DPRINTF("Call %s(regs) ret=%08x\n", buffer, *(int *)ESP_reg(&context) );
+	    DPRINTF(" EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx ESI=%08lx EDI=%08lx\n",
+		    EAX_reg(&context), EBX_reg(&context), ECX_reg(&context),
+		    EDX_reg(&context), ESI_reg(&context), EDI_reg(&context) );
+	    DPRINTF(" EBP=%08lx ESP=%08lx EIP=%08lx DS=%04lx ES=%04lx FS=%04lx GS=%04lx EFL=%08lx\n",
+		    EBP_reg(&context), ESP_reg(&context), EIP_reg(&context),
+		    DS_reg(&context), ES_reg(&context), FS_reg(&context),
+		    GS_reg(&context), EFL_reg(&context) );
 
-        BUILTIN32_GetEntryPoint( buffer, relay_addr - 5, &typemask );
-        DPRINTF("Call %s(regs) ret=%08x\n", buffer, *(int *)ESP_reg(&context) );
-        DPRINTF(" EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx ESI=%08lx EDI=%08lx\n",
-                EAX_reg(&context), EBX_reg(&context), ECX_reg(&context),
-                EDX_reg(&context), ESI_reg(&context), EDI_reg(&context) );
-        DPRINTF(" EBP=%08lx ESP=%08lx EIP=%08lx DS=%04lx ES=%04lx FS=%04lx GS=%04lx EFL=%08lx\n",
-                EBP_reg(&context), ESP_reg(&context), EIP_reg(&context),
-                DS_reg(&context), ES_reg(&context), FS_reg(&context),
-                GS_reg(&context), EFL_reg(&context) );
+	    /* Now call the real function */
+	    entry_point( &context );
 
-        /* Now call the real function */
-        entry_point( &context );
 
-        DPRINTF("Ret  %s() retval=regs ret=%08x\n", buffer, *(int *)ESP_reg(&context) );
-        DPRINTF(" EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx ESI=%08lx EDI=%08lx\n",
-                EAX_reg(&context), EBX_reg(&context), ECX_reg(&context),
-                EDX_reg(&context), ESI_reg(&context), EDI_reg(&context) );
-        DPRINTF(" EBP=%08lx ESP=%08lx EIP=%08lx DS=%04lx ES=%04lx FS=%04lx GS=%04lx EFL=%08lx\n",
-                EBP_reg(&context), ESP_reg(&context), EIP_reg(&context),
-                DS_reg(&context), ES_reg(&context), FS_reg(&context),
-                GS_reg(&context), EFL_reg(&context) );
+	    DPRINTF("Ret  %s() retval=regs ret=%08x\n", buffer, *(int *)ESP_reg(&context) );
+	    DPRINTF(" EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx ESI=%08lx EDI=%08lx\n",
+		    EAX_reg(&context), EBX_reg(&context), ECX_reg(&context),
+		    EDX_reg(&context), ESI_reg(&context), EDI_reg(&context) );
+	    DPRINTF(" EBP=%08lx ESP=%08lx EIP=%08lx DS=%04lx ES=%04lx FS=%04lx GS=%04lx EFL=%08lx\n",
+		    EBP_reg(&context), ESP_reg(&context), EIP_reg(&context),
+		    DS_reg(&context), ES_reg(&context), FS_reg(&context),
+		    GS_reg(&context), EFL_reg(&context) );
+	} else
+	    /* WINE internal register function found. Do not remove anything.
+	     * Do not print any debuginfo (it is not a normal relayed one).
+	     * Currently only used for snooping.
+	     */
+	   entry_point( &context );
     }
 }
-
 #endif  /* __i386__ */
diff --git a/relay32/shell32.spec b/relay32/shell32.spec
index 703f574..5607578 100644
--- a/relay32/shell32.spec
+++ b/relay32/shell32.spec
@@ -59,8 +59,8 @@
   57 stub SHELL32_57
   58 stdcall SHELL32_58(long long long long) SHELL32_58
   59 stub SHELL32_59
-  60 stub SHELL32_60
-  61 stub SHELL32_61
+  60 stdcall SHELL32_60(long) SHELL32_60
+  61 stdcall SHELL32_61(long long long str str long) SHELL32_61
   62 stdcall SHELL32_62(long long long long) SHELL32_62
   63 stdcall SHELL32_63(long long long long str str str) SHELL32_63
   64 stub SHELL32_64
@@ -183,7 +183,7 @@
  181 stdcall SHELL32_181(long long) SHELL32_181
  182 stub ExtractVersionResource16W
  183 cdecl SHELL32_183(long long long long long long) SHELL32_183
- 184 stub SHELL32_184
+ 184 stdcall SHELL32_184(long long long long long) SHELL32_184
  185 stub SHELL32_185
  186 stdcall FindExecutableA(ptr ptr ptr) FindExecutable32A
  187 stub FindExecutableW
@@ -223,7 +223,7 @@
  221 stdcall SHGetPathFromIDList(ptr ptr) SHGetPathFromIDList
  222 stub SHGetPathFromIDListA
  223 stdcall SHGetSpecialFolderLocation(long long ptr) SHGetSpecialFolderLocation
- 224 stub SHHelpShortcuts_RunDLL
+ 224 stdcall SHHelpShortcuts_RunDLL(long long long long) SHHelpShortcuts_RunDLL
  225 stub SHLoadInProc
  226 stub SheChangeDirA
  227 stub SheChangeDirExA
diff --git a/relay32/snoop.c b/relay32/snoop.c
new file mode 100644
index 0000000..061fad2
--- /dev/null
+++ b/relay32/snoop.c
@@ -0,0 +1,338 @@
+/*
+ * 386-specific Win32 dll<->dll snooping functions
+ *
+ * Copyright 1998 Marcus Meissner
+ */
+
+#ifdef __i386__
+
+#include <assert.h>
+#include "windows.h"
+#include "winbase.h"
+#include "winnt.h"
+#include "heap.h"
+#include "builtin32.h"
+#include "snoop.h"
+#include "peexe.h"
+#include "selectors.h"
+#include "stackframe.h"
+#include "debugstr.h"
+#include "debug.h"
+
+#ifdef NEED_UNDERSCORE_PREFIX
+# define PREFIX "_"
+#else
+# define PREFIX
+#endif
+
+/* Well ,not exactly extern since they are in the same file (in the lines
+ * below). But the C Compiler doesn't see them there, so we have to help a bit.
+ */
+extern void SNOOP_Return();
+extern void SNOOP_Entry();
+__asm__(".align 4\n\t"
+        ".globl "PREFIX"SNOOP_Entry\n\t"
+        ".type "PREFIX"SNOOP_Entry,@function\n\t"
+        PREFIX"SNOOP_Entry:\n\t"
+        "pushl $"PREFIX"__regs_SNOOP_Entry\n\t"
+        "pushl $"PREFIX"CALL32_Regs\n\t"
+        "ret\n\t"
+	".align 4\n\t"
+        ".globl "PREFIX"SNOOP_Return\n\t"
+        ".type "PREFIX"SNOOP_Return,@function\n\t"
+        PREFIX"SNOOP_Return:\n\t"
+        "pushl $"PREFIX"__regs_SNOOP_Return\n\t"
+        "pushl $"PREFIX"CALL32_Regs\n\t"
+        "ret"
+);
+
+#pragma pack(1)
+
+typedef	struct tagSNOOP_FUN {
+	/* code part */
+	BYTE		lcall;		/* 0xe8 call snoopentry (relative) */
+	/* NOTE: If you move snoopentry OR nrofargs fix the relative offset
+	 * calculation!
+	 */
+	DWORD		snoopentry;	/* SNOOP_Entry relative */
+	/* unreached */
+	int		nrofargs;
+	FARPROC32	origfun;
+	char		*name;
+} SNOOP_FUN;
+
+typedef struct tagSNOOP_DLL {
+	HMODULE32	hmod;
+	SNOOP_FUN	*funs;
+	LPCSTR		name;
+	int		nrofordinals;
+	struct tagSNOOP_DLL	*next;
+} SNOOP_DLL;
+typedef struct tagSNOOP_RETURNENTRY {
+	/* code part */
+	BYTE		lcall;		/* 0xe8 call snoopret relative*/
+	/* NOTE: If you move snoopret OR origreturn fix the relative offset
+	 * calculation!
+	 */
+	DWORD		snoopret;	/* SNOOP_Ret relative */
+	/* unreached */
+	FARPROC32	origreturn;
+	SNOOP_DLL	*dll;
+	DWORD		ordinal;
+	DWORD		origESP;
+	DWORD		*args;		/* saved args across a stdcall */
+} SNOOP_RETURNENTRY;
+
+typedef struct tagSNOOP_RETURNENTRIES {
+	SNOOP_RETURNENTRY entry[4092/sizeof(SNOOP_RETURNENTRY)];
+	struct tagSNOOP_RETURNENTRIES	*next;
+} SNOOP_RETURNENTRIES;
+
+#pragma pack(4)
+
+static	SNOOP_DLL		*firstdll = NULL;
+static	SNOOP_RETURNENTRIES 	*firstrets = NULL;
+
+void
+SNOOP_RegisterDLL(HMODULE32 hmod,LPCSTR name,DWORD nrofordinals) {
+	SNOOP_DLL	**dll = &(firstdll);
+	char		*s;
+
+	if (!TRACE_ON(snoop)) return;
+	while (*dll) {
+		if ((*dll)->hmod == hmod)
+			return; /* already registered */
+		dll = &((*dll)->next);
+	}
+	*dll = (SNOOP_DLL*)HeapAlloc(SystemHeap,HEAP_ZERO_MEMORY,sizeof(SNOOP_DLL));
+	(*dll)->next	= NULL;
+	(*dll)->hmod	= hmod;
+	(*dll)->nrofordinals = nrofordinals;
+	(*dll)->name	= HEAP_strdupA(SystemHeap,0,name);
+	if ((s=strrchr((*dll)->name,'.')))
+		*s='\0';
+	(*dll)->funs = VirtualAlloc(NULL,nrofordinals*sizeof(SNOOP_FUN),MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
+	memset((*dll)->funs,0,nrofordinals*sizeof(SNOOP_FUN));
+	if (!(*dll)->funs) {
+		HeapFree(SystemHeap,0,*dll);
+		FIXME(snoop,"out of memory\n");
+		return;
+	}
+}
+
+FARPROC32
+SNOOP_GetProcAddress32(HMODULE32 hmod,LPCSTR name,DWORD ordinal,FARPROC32 origfun) {
+	SNOOP_DLL			*dll = firstdll;
+	SNOOP_FUN			*fun;
+	int				j;
+	IMAGE_SECTION_HEADER		*pe_seg = PE_SECTIONS(hmod);
+
+	if (!TRACE_ON(snoop)) return origfun;
+	if (!*(LPBYTE)origfun) /* 0x00 is an imposs. opcode, poss. dataref. */
+		return origfun;
+	for (j=0;j<PE_HEADER(hmod)->FileHeader.NumberOfSections;j++)
+		if (((DWORD)origfun-hmod>=pe_seg[j].VirtualAddress)&&
+		    ((DWORD)origfun-hmod <pe_seg[j].VirtualAddress+
+		    		   pe_seg[j].SizeOfRawData)
+		)
+			break;
+	/* If we looked through all sections (and didn't find one) 
+	 * or if the sectionname contains "data", we return the
+	 * original function since it is most likely a datareference.
+	 */
+	if (	(j==PE_HEADER(hmod)->FileHeader.NumberOfSections)	||
+		(strstr(pe_seg[j].Name,"data"))				||
+		!(pe_seg[j].Characteristics & IMAGE_SCN_CNT_CODE)
+	)
+		return origfun;
+
+	while (dll) {
+		if (hmod == dll->hmod)
+			break;
+		dll=dll->next;
+	}
+	if (!dll)	/* probably internal */
+		return origfun;
+	assert(ordinal<dll->nrofordinals);
+	fun = dll->funs+ordinal;
+	if (!fun->name) fun->name = HEAP_strdupA(SystemHeap,0,name);
+	fun->lcall	= 0xe8;
+	/* NOTE: origreturn struct member MUST come directly after snoopentry */
+	fun->snoopentry	= (char*)SNOOP_Entry-((char*)(&fun->nrofargs));
+	fun->origfun	= origfun;
+	fun->nrofargs	= -1;
+	return (FARPROC32)&(fun->lcall);
+}
+
+static char*
+SNOOP_PrintArg(DWORD x) {
+	static char	buf[200];
+	int		i,nostring;
+	MEMORY_BASIC_INFORMATION	mbi;
+
+	if (	!HIWORD(x)					||
+		!VirtualQuery((LPVOID)x,&mbi,sizeof(mbi))	||
+		!mbi.Type
+	) {
+		sprintf(buf,"%08lx",x);
+		return buf;
+	}
+	i=0;nostring=0;
+	if (!IsBadStringPtr32A((LPSTR)x,80)) {
+		while (i<80) {
+			LPBYTE	s=(LPBYTE)x;
+
+			if (s[i]==0) break;
+			if (s[i]<0x20) {nostring=1;break;}
+			if (s[i]>=0x80) {nostring=1;break;}
+			i++;
+		}
+		if (!nostring) {
+			if (i>5) {
+				sprintf(buf,"%08lx \"",x);
+				strncat(buf,(LPSTR)x,198-strlen(buf)-2);
+				strcat(buf,"\"");
+				return buf;
+			}
+		}
+	}
+	i=0;nostring=0;
+	if (!IsBadStringPtr32W((LPWSTR)x,80)) {
+		while (i<80) {
+			LPWSTR	s=(LPWSTR)x;
+
+			if (s[i]==0) break;
+			if (s[i]<0x20) {nostring=1;break;}
+			if (s[i]>0x100) {nostring=1;break;}
+			i++;
+		}
+		if (!nostring) {
+			if (i>5) {
+				sprintf(buf,"%08lx L",x);
+				strcat(buf,debugstr_wn((LPWSTR)x,198-strlen(buf)-2));
+				return buf;
+			}
+		}
+	}
+	sprintf(buf,"%08lx",x);
+	return buf;
+}
+
+#define CALLER1REF (*(DWORD*)(ESP_reg(context)+4))
+REGS_ENTRYPOINT(SNOOP_Entry) {
+	DWORD		ordinal=0,entry = EIP_reg(context)-5;
+	SNOOP_DLL	*dll = firstdll;
+	SNOOP_FUN	*fun = NULL;
+	SNOOP_RETURNENTRIES	**rets = &firstrets;
+	SNOOP_RETURNENTRY	*ret;
+	int		i,max;
+
+	while (dll) {
+		if (	((char*)entry>=(char*)dll->funs)	&&
+			((char*)entry<=(char*)(dll->funs+dll->nrofordinals))
+		) {
+			fun = (SNOOP_FUN*)entry;
+			ordinal = fun-dll->funs;
+			break;
+		}
+		dll=dll->next;
+	}
+	if (!dll) {
+		FIXME(snoop,"entrypoint 0x%08lx not found\n",entry);
+		return; /* oops */
+	}
+	/* guess cdecl ... */
+	if (fun->nrofargs<0) {
+		/* Typical cdecl return frame is:
+		 * 	add esp, xxxxxxxx 
+		 * which has (for xxxxxxxx up to 255 the opcode "83 C4 xx".
+		 */
+		LPBYTE	reteip = (LPBYTE)CALLER1REF;
+
+		if ((reteip[0]==0x83)&&(reteip[1]==0xc4))
+			fun->nrofargs=reteip[2]/4;
+	}
+
+	while (*rets) {
+		for (i=0;i<sizeof((*rets)->entry)/sizeof((*rets)->entry[0]);i++)
+			if (!(*rets)->entry[i].origreturn)
+				break;
+		if (i!=sizeof((*rets)->entry)/sizeof((*rets)->entry[0]))
+			break;
+		rets = &((*rets)->next);
+	}
+	if (!*rets) {
+		*rets = VirtualAlloc(NULL,4096,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
+		memset(*rets,0,4096);
+		i = 0;	/* entry 0 is free */
+	}
+	ret = &((*rets)->entry[i]);
+	ret->lcall	= 0xe8;
+	/* NOTE: origreturn struct member MUST come directly after snoopret */
+	ret->snoopret	= ((char*)SNOOP_Return)-(char*)(&ret->origreturn);
+	ret->origreturn	= (FARPROC32)CALLER1REF;
+	CALLER1REF	= (DWORD)&ret->lcall;
+	ret->dll	= dll;
+	ret->args	= NULL;
+	ret->ordinal	= ordinal;
+	ret->origESP	= ESP_reg(context);
+
+	EIP_reg(context)= (DWORD)fun->origfun;
+
+	DPRINTF("Call %s.%ld: %s(",dll->name,ordinal,fun->name);
+	if (fun->nrofargs>0) {
+		max = fun->nrofargs; if (max>16) max=16;
+		for (i=0;i<max;i++)
+			DPRINTF("%s%s",SNOOP_PrintArg(*(DWORD*)(ESP_reg(context)+8+sizeof(DWORD)*i)),(i<fun->nrofargs-1)?",":"");
+		if (max!=fun->nrofargs)
+			DPRINTF(" ...");
+	} else if (fun->nrofargs<0) {
+		DPRINTF("<unknown, check return>");
+		ret->args = HeapAlloc(SystemHeap,0,16*sizeof(DWORD));
+		memcpy(ret->args,(LPBYTE)(ESP_reg(context)+8),sizeof(DWORD)*16);
+	}
+	DPRINTF(") ret=%08lx fs=%04lx\n",(DWORD)(*rets)->entry[i].origreturn,FS_reg(context));
+}
+
+REGS_ENTRYPOINT(SNOOP_Return) {
+	SNOOP_RETURNENTRY	*ret = (SNOOP_RETURNENTRY*)(EIP_reg(context)-5);
+
+	/* We haven't found out the nrofargs yet. If we called a cdecl
+	 * function it is too late anyway and we can just set '0' (which 
+	 * will be the difference between orig and current ESP
+	 * If stdcall -> everything ok.
+	 */
+	if (ret->dll->funs[ret->ordinal].nrofargs<0)
+		ret->dll->funs[ret->ordinal].nrofargs=(ESP_reg(context)-ret->origESP-4)/4;
+	EIP_reg(context) = (DWORD)ret->origreturn;
+	if (ret->args) {
+		int	i,max;
+
+		DPRINTF("Ret  %s.%ld: %s(",ret->dll->name,ret->ordinal,ret->dll->funs[ret->ordinal].name);
+		max = ret->dll->funs[ret->ordinal].nrofargs;
+		if (max>16) max=16;
+
+		for (i=0;i<max;i++)
+			DPRINTF("%s%s",SNOOP_PrintArg(ret->args[i]),(i<max-1)?",":"");
+		DPRINTF(") retval = %08lx ret=%08lx fs=%04lx\n",
+			EAX_reg(context),(DWORD)ret->origreturn,FS_reg(context)
+		);
+		HeapFree(SystemHeap,0,ret->args);
+		ret->args = NULL;
+	} else
+		DPRINTF("Ret  %s.%ld: %s() retval = %08lx ret=%08lx fs=%04lx\n",
+			ret->dll->name,ret->ordinal,ret->dll->funs[ret->ordinal].name,
+			EAX_reg(context),(DWORD)ret->origreturn,FS_reg(context)
+		);
+	ret->origreturn = NULL; /* mark as empty */
+}
+#else	/* !__i386__ */
+void SNOOP_RegisterDLL(HMODULE32 hmod,LPCSTR name,DWORD nrofordinals) {
+	FIXME(snoop,"snooping works only on i386 for now.\n");
+	return;
+}
+
+FARPROC32 SNOOP_GetProcAddress32(HMODULE32 hmod,LPCSTR name,DWORD ordinal,FARPROC32 origfun) {
+	return origfun;
+}
+#endif	/* !__i386__ */
diff --git a/relay32/tapi32.spec b/relay32/tapi32.spec
index 011d0ab..449df0c 100644
--- a/relay32/tapi32.spec
+++ b/relay32/tapi32.spec
@@ -42,12 +42,12 @@
  39 stub    lineGetTranslateCaps
  40 stub    lineHandoff
  41 stub    lineHold
- 42 stub    lineInitialize
+ 42 stdcall lineInitialize(ptr long ptr str ptr) lineInitialize
  43 stub    lineMakeCall
  44 stub    lineMonitorDigits
  45 stub    lineMonitorMedia
  46 stub    lineMonitorTones
- 47 stub    lineNegotiateAPIVersion
+ 47 stdcall lineNegotiateAPIVersion(long long long long ptr ptr) lineNegotiateAPIVersion
  48 stub    lineNegotiateExtVersion
  49 stub    lineOpen
  50 stub    linePark
@@ -74,7 +74,7 @@
  71 stub    lineSetTollList
  72 stub    lineSetupConference
  73 stub    lineSetupTransfer
- 74 stub    lineShutdown
+ 74 stdcall lineShutdown(long) lineShutdown
  75 stub    lineSwapHold
  76 stub    lineTranslateAddress
  77 stub    lineTranslateDialog
diff --git a/relay32/user32.spec b/relay32/user32.spec
index 71e816c..fe241af 100644
--- a/relay32/user32.spec
+++ b/relay32/user32.spec
@@ -21,7 +21,7 @@
  18 stdcall CallWindowProcA(ptr long long long long) CallWindowProc32A
  19 stdcall CallWindowProcW(ptr long long long long) CallWindowProc32W
  20 stub CascadeChildWindows
- 21 stub CascadeWindows
+ 21 stdcall CascadeWindows(long long ptr long ptr) CascadeWindows
  22 stdcall ChangeClipboardChain(long long) ChangeClipboardChain32
  23 stdcall ChangeMenuA(long long ptr long long) ChangeMenu32A
  24 stdcall ChangeMenuW(long long ptr long long) ChangeMenu32W
@@ -328,7 +328,7 @@
 323 stdcall InsertMenuItemA(long long long ptr) InsertMenuItem32A
 324 stdcall InsertMenuItemW(long long long ptr) InsertMenuItem32W
 325 stdcall InsertMenuW(long long long long ptr) InsertMenu32W
-326 stub InternalGetWindowText
+326 stdcall InternalGetWindowText(long long long) InternalGetWindowText
 327 stdcall IntersectRect(ptr ptr ptr) IntersectRect32
 328 stdcall InvalidateRect(long ptr long) InvalidateRect32
 329 stdcall InvalidateRgn(long long long) InvalidateRgn32
@@ -362,8 +362,8 @@
 357 stdcall LoadBitmapA(long str) LoadBitmap32A
 358 stdcall LoadBitmapW(long wstr) LoadBitmap32W
 359 stdcall LoadCursorA(long str) LoadCursor32A
-360 stub LoadCursorFromFileA
-361 stub LoadCursorFromFileW
+360 stdcall LoadCursorFromFileA(str) LoadCursorFromFile32A
+361 stdcall LoadCursorFromFileW(wstr) LoadCursorFromFile32W
 362 stdcall LoadCursorW(long wstr) LoadCursor32W
 363 stdcall LoadIconA(long str) LoadIcon32A
 364 stdcall LoadIconW(long wstr) LoadIcon32W
@@ -410,7 +410,7 @@
 405 stdcall OemToCharW(ptr ptr) OemToChar32W
 406 stdcall OffsetRect(ptr long long) OffsetRect32
 407 stdcall OpenClipboard(long) OpenClipboard32
-408 stub OpenDesktopA
+408 stdcall OpenDesktopA(str long long long) OpenDesktop32A
 409 stub OpenDesktopW
 410 stdcall OpenIcon(long) OpenIcon32
 411 stub OpenInputDesktop
@@ -457,7 +457,7 @@
 452 stdcall SendDlgItemMessageA(long long long long long) SendDlgItemMessage32A
 453 stdcall SendDlgItemMessageW(long long long long long) SendDlgItemMessage32W
 454 stdcall SendMessageA(long long long long) SendMessage32A
-455 stub SendMessageCallbackA
+455 stdcall SendMessageCallbackA(long long long long ptr long) SendMessageCallBack32A
 456 stub SendMessageCallbackW
 457 stdcall SendMessageTimeoutA(long long long long ptr ptr) SendMessageTimeout32A
 458 stdcall SendMessageTimeoutW(long long long long ptr ptr) SendMessageTimeout32W
@@ -512,9 +512,9 @@
 507 stub SetSystemCursor
 508 stdcall SetSystemMenu(long long) SetSystemMenu32
 509 stdcall SetSystemTimer(long long long ptr) SetSystemTimer32
-510 stub SetThreadDesktop
+510 stdcall SetThreadDesktop(long) SetThreadDesktop
 511 stdcall SetTimer(long long long ptr) SetTimer32
-512 stub SetUserObjectInformationA
+512 stdcall SetUserObjectInformationA(long long long long) SetUserObjectInformation32A
 513 stub SetUserObjectInformationW
 514 stub SetUserObjectSecurity
 515 stdcall SetWindowContextHelpId(long long) SetWindowContextHelpId
@@ -547,7 +547,7 @@
 542 stdcall TabbedTextOutA(long long long str long long ptr long) TabbedTextOut32A
 543 stdcall TabbedTextOutW(long long long wstr long long ptr long) TabbedTextOut32W
 544 stub TileChildWindows
-545 stub TileWindows
+545 stdcall TileWindows(long long ptr long ptr) TileWindows
 546 stdcall ToAscii(long long ptr ptr long) ToAscii32
 547 stub ToAsciiEx
 548 stub ToUnicode
diff --git a/relay32/winmm.spec b/relay32/winmm.spec
index f3b494d..fc210e6 100644
--- a/relay32/winmm.spec
+++ b/relay32/winmm.spec
@@ -9,14 +9,14 @@
   6 stub DriverCallback
   7 stub DrvClose
   8 stub DrvDefDriverProc
-  9 stub DrvGetModuleHandle
+  9 stdcall DrvGetModuleHandle(long) GetDriverModuleHandle32
  10 stub DrvOpen
  11 stub DrvOpenA
  12 stub DrvSendMessage
  13 stub GetDriverFlags
- 14 stub GetDriverModuleHandle
- 15 stdcall OpenDriver(ptr ptr long) OpenDriver
- 16 stub OpenDriverA
+ 14 stdcall GetDriverModuleHandle(long) GetDriverModuleHandle32
+ 15 stdcall OpenDriver(wstr wstr long) OpenDriver32W
+ 16 stdcall OpenDriverA(str str long) OpenDriver32A
  17 stdcall PlaySound(ptr long long) PlaySound32A
  18 stdcall PlaySoundW(ptr long long) PlaySound32W
  19 stub SendDriverMessage
@@ -112,19 +112,19 @@
 109 stdcall mixerMessage(long long long long) mixerMessage32
 110 stdcall mixerOpen(ptr long long long long) mixerOpen32
 111 stdcall mixerSetControlDetails(long ptr long) mixerSetControlDetails32
-112 stub mmioAdvance
-113 stub mmioAscend
-114 stub mmioClose
+112 stdcall mmioAdvance(long ptr long) mmioAdvance32
+113 stdcall mmioAscend(long ptr long) mmioAscend32
+114 stdcall mmioClose(long long) mmioClose32
 115 stub mmioCreateChunk
-116 stub mmioDescend
-117 stub mmioFlush
-118 stub mmioGetInfo
+116 stdcall mmioDescend(long ptr ptr long) mmioDescend
+117 stdcall mmioFlush(long long) mmioFlush32
+118 stdcall mmioGetInfo(long ptr long) mmioGetInfo32
 119 stub mmioInstallIOProc16
 120 stdcall mmioInstallIOProcA(long ptr long) mmioInstallIOProc32A
 121 stub mmioInstallIOProcW
 122 stdcall mmioOpenA(str ptr long) mmioOpen32A
 123 stdcall mmioOpenW(wstr ptr long) mmioOpen32W
-124 stub mmioRead
+124 stdcall mmioRead(long ptr long) mmioRead32
 125 stub mmioRenameA
 126 stub mmioRenameW
 127 stub mmioSeek
diff --git a/relay32/winspool.spec b/relay32/winspool.spec
index 9e05933..4575d3f 100644
--- a/relay32/winspool.spec
+++ b/relay32/winspool.spec
@@ -35,9 +35,9 @@
 132 stub DEVICEMODE
 133 stub DeleteFormA
 134 stub DeleteFormW
-135 stub DeleteMonitorA
+135 stdcall DeleteMonitorA(str str str) DeleteMonitor32A
 136 stub DeleteMonitorW
-137 stub DeletePortA
+137 stdcall DeletePortA(str long str) DeletePort32A
 138 stub DeletePortW
 139 stub DeletePrintProcessorA
 140 stub DeletePrintProcessorW
@@ -46,7 +46,7 @@
 143 stub DeletePrinter
 144 stub DeletePrinterConnectionA
 145 stub DeletePrinterConnectionW
-146 stub DeletePrinterDriverA
+146 stdcall DeletePrinterDriverA(str str str) DeletePrinterDriver32A
 147 stub DeletePrinterDriverW
 148 stub DeletePrinterIC
 149 stub DevQueryPrint
diff --git a/scheduler/critsection.c b/scheduler/critsection.c
index 4893712..aceb2c9 100644
--- a/scheduler/critsection.c
+++ b/scheduler/critsection.c
@@ -21,6 +21,7 @@
 #include "winbase.h"
 #include "heap.h"
 #include "k32obj.h"
+#include "debug.h"
 #include "thread.h"
 
 typedef struct
@@ -122,6 +123,10 @@
  */
 void WINAPI EnterCriticalSection( CRITICAL_SECTION *crit )
 {
+    if ((crit->Reserved==-1) && !(crit->LockSemaphore)) {
+    	FIXME(win32,"entering uninitialized section(%p)?\n",crit);
+    	InitializeCriticalSection(crit);
+    }
     if (InterlockedIncrement( &crit->LockCount ))
     {
         if (crit->OwningThread == GetCurrentThreadId())
diff --git a/scheduler/k32obj.c b/scheduler/k32obj.c
index 98053a4..3b91ab5 100644
--- a/scheduler/k32obj.c
+++ b/scheduler/k32obj.c
@@ -234,7 +234,7 @@
     entry = K32OBJ_FirstEntry;
     while (entry)
     {
-        if ((len == entry->len) && !lstrcmp32A( name, entry->name))
+        if ((len == entry->len) && !strcmp( name, entry->name))
         {
             K32OBJ *obj = entry->obj;
             K32OBJ_IncCount( obj );
diff --git a/scheduler/process.c b/scheduler/process.c
index 2254d63..3ebc69b 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -7,6 +7,7 @@
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 #include "process.h"
 #include "module.h"
 #include "file.h"
@@ -690,3 +691,18 @@
     K32OBJ_DecCount( &process->header );
     return TRUE;
 }
+
+/***********************************************************************
+ * GetProcessHeaps [KERNEL32.376]
+ */
+DWORD WINAPI GetProcessHeaps(DWORD nrofheaps,HANDLE32 *heaps) {
+	FIXME(win32,"(%ld,%p), incomplete implementation.\n",nrofheaps,heaps);
+
+	if (nrofheaps) {
+		heaps[0] = GetProcessHeap();
+		/* ... probably SystemHeap too ? */
+		return 1;
+	}
+	/* number of available heaps */
+	return 1;
+}
diff --git a/tools/build.c b/tools/build.c
index bc36294..f0564d4 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -998,7 +998,7 @@
                  "__asm__(\".align 4\\n\\t\"\n"
                  "        \".globl " PREFIX "%s\\n\\t\"\n"
                  "        \".type " PREFIX "%s,@function\\n\\t\"\n"
-                 "        \"%s:\\n\\t\"\n"
+                 "        \"" PREFIX "%s:\\n\\t\"\n"
                  "        \"pushl $" PREFIX "__regs_%s\\n\\t\"\n"
                  "        \"pushl $" PREFIX "CALL32_Regs\\n\\t\"\n"
                  "        \"ret\");\n",
diff --git a/tools/wrc/utils.c b/tools/wrc/utils.c
index fd2832f..1cb8ab8 100644
--- a/tools/wrc/utils.c
+++ b/tools/wrc/utils.c
Binary files differ
diff --git a/tools/wrc/wrc.c b/tools/wrc/wrc.c
index 910cf14..6ffcd29 100644
--- a/tools/wrc/wrc.c
+++ b/tools/wrc/wrc.c
@@ -33,6 +33,7 @@
 #include <ctype.h>
 
 #include <config.h>
+#include <resource.h>	/* For HAVE_WINE_CONSTRUCTOR */
 #include "wrc.h"
 #include "utils.h"
 #include "writeres.h"
@@ -45,6 +46,7 @@
 
 char usage[] = "Usage: wrc [options...] [infile[.rc|.res]]\n"
 	"   -a n        Alignment of resource (win16 only, default is 4)\n"
+	"   -A          Auto register resources (only with gcc 2.7 and better)\n"
 	"   -b          Create a C array from a binary .res file\n"
 	"   -c          Add 'const' prefix to C constants\n"
 	"   -C cp       Set the resource's codepage to cp (default is 0)\n"
@@ -86,7 +88,11 @@
  * Default prefix for resource names used in the C array.
  * Option '-p name' sets it to 'name'
  */
+#ifdef NEED_UNDERSCORE_PREFIX
+char *prefix = "__Resource";
+#else
 char *prefix = "_Resource";
+#endif
 
 /*
  * Set if compiling in 32bit mode (default).
@@ -177,6 +183,11 @@
  */
 int pedantic = 0;
 
+/*
+ * Set when autoregister code must be added to the output (-A option)
+ */
+int auto_register = 0;
+
 char *output_name;		/* The name given by the -o option */
 char *input_name;		/* The name given on the command-line */
 char *header_name;		/* The name given by the -H option */
@@ -212,13 +223,16 @@
 			strcat(cmdline, " ");
 	}
 
-	while((optc = getopt(argc, argv, "a:bcC:d:D:eghH:I:l:no:p:rstTVw:W")) != EOF)
+	while((optc = getopt(argc, argv, "a:AbcC:d:D:eghH:I:l:no:p:rstTVw:W")) != EOF)
 	{
 		switch(optc)
 		{
 		case 'a':
 			alignment = atoi(optarg);
 			break;
+		case 'A':
+			auto_register = 1;
+			break;
 		case 'b':
 			binary = 1;
 			break;
@@ -263,7 +277,13 @@
 			output_name = strdup(optarg);
 			break;
 		case 'p':
-			prefix = strdup(optarg);
+#ifdef NEED_UNDERSCORE_PREFIX
+			prefix = (char *)xmalloc(strlen(optarg)+2);
+			prefix[0] = '_';
+			strcpy(prefix+1, optarg);
+#else
+			prefix = xstrdup(optarg);
+#endif
 			break;
 		case 'r':
 			create_res = 1;
@@ -357,6 +377,14 @@
 		}
 	}
 
+#if !defined(HAVE_WINE_CONSTRUCTOR)
+	if(auto_register)
+	{
+		warning("Autoregister code non-operable (HAVE_WINE_CONSTRUCTOR not defined)");
+		auto_register = 0;
+	}
+#endif
+
 	/* Set alignment power */
 	a = alignment;
 	for(alignment_pwr = 0; alignment_pwr < 10 && a > 1; alignment_pwr++)
diff --git a/tools/wrc/wrc.h b/tools/wrc/wrc.h
index 13ad29e..b3d8ef6 100644
--- a/tools/wrc/wrc.h
+++ b/tools/wrc/wrc.h
@@ -12,8 +12,8 @@
 #include "wrctypes.h"
 #endif
 
-#define WRC_VERSION	"1.0.0"
-#define WRC_RELEASEDATE	"(28-May-1998)"
+#define WRC_VERSION	"1.0.1"
+#define WRC_RELEASEDATE	"(08-Jun-1998)"
 #define WRC_FULLVERSION WRC_VERSION " " WRC_RELEASEDATE
 
 /* Only used in heavy debugging sessions */
@@ -76,6 +76,7 @@
 extern int create_s;
 extern DWORD codepage;
 extern int pedantic;
+extern int auto_register;
 
 extern char *prefix;
 extern char *output_name;
diff --git a/tools/wrc/writeres.c b/tools/wrc/writeres.c
index 18084f0..bd2fa36 100644
--- a/tools/wrc/writeres.c
+++ b/tools/wrc/writeres.c
@@ -32,6 +32,21 @@
 	"# <eof>\n\n"
 	;
 
+char s_file_autoreg_str[] =
+	"\t.text\n"
+	".LAuto_Register:\n"
+	"\tpushl\t$%s%s\n"
+#ifdef NEED_UNDERSCORE_PREFIX
+	"\tcall\t_LIBRES_RegisterResources\n"
+#else
+	"\tcall\tLIBRES_RegisterResources\n"
+#endif
+	"\taddl\t$4,%%esp\n"
+	"\tret\n\n"
+	"\t.section .ctors,\"aw\"\n"
+	"\t.long\t.LAuto_Register\n\n"
+	;
+
 char h_file_head_str[] =
 	"/*\n"
 	" * This file is generated with wrc version " WRC_FULLVERSION ". Do not edit!\n"
@@ -1031,6 +1046,9 @@
 		fprintf(fo, "\n");
 	}
 
+	if(auto_register)
+		fprintf(fo, s_file_autoreg_str, prefix, _ResTable);
+
 	fprintf(fo, s_file_tail_str);
 	fclose(fo);
 }
@@ -1052,24 +1070,12 @@
 	FILE *fo;
 	resource_t *rsc;
 	char *h_prefix;
-	int cnameidx;
 
-	if(prefix[0] == '_')
-	{
-		h_prefix = prefix + 1;
-		cnameidx = 0;
-	}
-	else if(prefix[0] == '\0')
-	{
-		h_prefix = prefix;
-		cnameidx = 1;
-	}
-	else
-	{
-		h_prefix = prefix;
-		cnameidx = 0;
-		warning("Resources might not be visible in c-namespace (missing '_' in prefix)\n");
-	}
+#ifdef NEED_UNDERSCORE_PREFIX
+	h_prefix = prefix + 1;
+#else
+	h_prefix = prefix;
+#endif
 
 	fo = fopen(outname, "wt");
 	if(!fo)
@@ -1086,7 +1092,7 @@
 		fprintf(fo, "extern %schar %s%s[];\n\n",
 			constant ? "const " : "",
 			h_prefix,
-			(win32 ? _PEResTab : _NEResTab) + cnameidx);
+			win32 ? _PEResTab : _NEResTab);
 	}
 
 	/* Write the resource data */
@@ -1098,7 +1104,7 @@
 		fprintf(fo, "extern %schar %s%s_data[];\n",
 			constant ? "const " : "",
 			h_prefix,
-			rsc->c_name + cnameidx);
+			rsc->c_name);
 	}
 
 	if(indirect)
@@ -1113,7 +1119,7 @@
 				constant ? "const " : "",
 				win32 ? 32 : 16,
 				h_prefix,
-				rsc->c_name + cnameidx);
+				rsc->c_name);
 		}
 
 		if(global)
@@ -1124,7 +1130,7 @@
 			constant ? "const " : "",
 			win32 ? 32 : 16,
 			h_prefix,
-			_ResTable + cnameidx);
+			_ResTable);
 	}
 
 	fprintf(fo, h_file_tail_str);
diff --git a/win32/Makefile.in b/win32/Makefile.in
index bebf632..39798aa 100644
--- a/win32/Makefile.in
+++ b/win32/Makefile.in
@@ -9,6 +9,7 @@
 	advapi.c \
 	code_page.c \
 	console.c \
+	device.c \
 	error.c \
 	except.c \
 	file.c \
diff --git a/win32/advapi.c b/win32/advapi.c
index 0b39d0a..368642e 100644
--- a/win32/advapi.c
+++ b/win32/advapi.c
@@ -212,6 +212,40 @@
 
 
 /******************************************************************************
+ * GetFileSecurityA [32.45]
+ * Obtains Specified information about the security of a file or directory
+ * The information obtained is constrained by the callers acces rights and
+ * priviliges
+ */
+
+BOOL32 WINAPI GetFileSecurity32A( LPCSTR lpFileName,
+                                SECURITY_INFORMATION RequestedInformation,
+                                LPSECURITY_DESCRIPTOR pSecurityDescriptor,
+                                DWORD nLength,
+                                LPDWORD lpnLengthNeeded)
+{
+  FIXME(advapi, "(%s) : stub\n", debugstr_a(lpFileName));
+  return TRUE;
+}
+
+/******************************************************************************
+ * GetFileSecurityiW [32.46]
+ * Obtains Specified information about the security of a file or directory
+ * The information obtained is constrained by the callers acces rights and
+ * priviliges
+ */
+
+BOOL32 WINAPI GetFileSecurity32W( LPCWSTR lpFileName,
+                                SECURITY_INFORMATION RequestedInformation,
+                                LPSECURITY_DESCRIPTOR pSecurityDescriptor,
+                                DWORD nLength,
+                                LPDWORD lpnLengthNeeded)
+{
+  FIXME(advapi, "(%s) : stub\n", debugstr_w(lpFileName) ); 
+  return TRUE;
+}
+
+/******************************************************************************
  * OpenService32A [ADVAPI32.112]
  */
 HANDLE32 WINAPI OpenService32A( HANDLE32 hSCManager, LPCSTR lpServiceName,
diff --git a/win32/device.c b/win32/device.c
new file mode 100644
index 0000000..528d36a
--- /dev/null
+++ b/win32/device.c
@@ -0,0 +1,105 @@
+/*
+ * Win32 device functions
+ *
+ * Copyright 1998 Marcus Meissner
+ */
+
+#include <errno.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <string.h>
+#include <time.h>
+#include "windows.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "file.h"
+#include "process.h"
+#include "mmsystem.h"
+#include "heap.h"
+#include "debug.h"
+
+void DEVICE_Destroy(K32OBJ *dev);
+const K32OBJ_OPS DEVICE_Ops =
+{
+    NULL,		/* signaled */
+    NULL,		/* satisfied */
+    NULL,		/* add_wait */
+    NULL,		/* remove_wait */
+    NULL,		/* read */
+    NULL,		/* write */
+    DEVICE_Destroy	/* destroy */
+};
+
+/* The device object */
+typedef struct
+{
+    K32OBJ    header;
+    int       mode;
+    char     *devname;
+} DEVICE_OBJECT;
+
+HANDLE32
+DEVICE_Open(LPCSTR filename, DWORD access) {
+	DEVICE_OBJECT	*dev;
+	HANDLE32 handle;
+
+	dev = HeapAlloc( SystemHeap, 0, sizeof(FILE_OBJECT) );
+	if (!dev)
+	    return INVALID_HANDLE_VALUE32;
+	dev->header.type = K32OBJ_DEVICE_IOCTL;
+	dev->header.refcount = 0;
+	dev->mode	= access;
+	dev->devname	= HEAP_strdupA(SystemHeap,0,filename);
+
+	handle = HANDLE_Alloc( PROCESS_Current(), &(dev->header),
+			       FILE_ALL_ACCESS | GENERIC_READ |
+			       GENERIC_WRITE | GENERIC_EXECUTE /*FIXME*/, TRUE );
+	/* If the allocation failed, the object is already destroyed */
+	if (handle == INVALID_HANDLE_VALUE32) dev = NULL;
+	return handle;
+}
+
+void
+DEVICE_Destroy(K32OBJ *dev) {
+	assert(dev->type == K32OBJ_DEVICE_IOCTL);
+}
+
+/****************************************************************************
+ *		DeviceIoControl (KERNEL32.188)
+ */
+BOOL32 WINAPI DeviceIoControl(HANDLE32 hDevice, DWORD dwIoControlCode, 
+			      LPVOID lpvlnBuffer, DWORD cblnBuffer,
+			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
+			      LPDWORD lpcbBytesReturned,
+			      LPOVERLAPPED lpOverlapped)
+{
+	DEVICE_OBJECT	*dev = (DEVICE_OBJECT *)HANDLE_GetObjPtr(
+		PROCESS_Current(), hDevice, K32OBJ_DEVICE_IOCTL, 0 /*FIXME*/ );
+
+        FIXME(win32, "(%ld,%ld,%p,%ld,%p,%ld,%p,%p), stub\n",
+		hDevice,dwIoControlCode,lpvlnBuffer,cblnBuffer,
+		lpvOutBuffer,cbOutBuffer,lpcbBytesReturned,lpOverlapped
+	);
+	if (!dev)
+		return FALSE;
+	/* FIXME: Set appropriate error */
+	FIXME(win32,"	device %s\n",dev->devname);
+	if (!strcmp(dev->devname,"VTDAPI")) {
+		switch (dwIoControlCode) {
+		case 5:	if (lpvOutBuffer && (cbOutBuffer>=4))
+				*(DWORD*)lpvOutBuffer = timeGetTime();
+			if (lpcbBytesReturned)
+				*lpcbBytesReturned = 4;
+			return TRUE;
+		default:
+			break;
+		}
+	}
+	FIXME(win32,"	(unhandled)\n");
+	return FALSE;
+}
diff --git a/win32/file.c b/win32/file.c
index 49a2d77..cba870f 100644
--- a/win32/file.c
+++ b/win32/file.c
@@ -17,6 +17,7 @@
 #include "winbase.h"
 #include "winerror.h"
 #include "file.h"
+#include "device.h"
 #include "process.h"
 #include "heap.h"
 #include "debug.h"
@@ -115,10 +116,24 @@
     if(template)
         FIXME(file, "template handles not supported.\n");
 
-    /* If the name starts with '\\?' or '\\.', ignore the first 3 chars.
+    /* If the name starts with '\\?\' or '\\.\', ignore the first 4 chars.
      */
-    if(!strncmp(filename, "\\\\?", 3) || !strncmp(filename, "\\\\.", 3))
-        filename += 3;
+    if(!strncmp(filename, "\\\\?\\", 4) || !strncmp(filename, "\\\\.\\", 4))
+    {
+        if (filename[2] == '.')
+        {
+            FIXME(file,"device name? %s\n",filename);
+            /* device? */
+            return DEVICE_Open( filename+4, access_flags | create_flags );
+        }
+        filename += 4;
+	if (!strncmp(filename, "UNC", 3))
+	{
+            FIXME(file, "UNC names not supported.\n");
+            SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+            return HFILE_ERROR32;
+	}	
+    }
 
     /* If the name still starts with '\\', it's a UNC name.
      */
diff --git a/win32/newfns.c b/win32/newfns.c
index 376f4a1..08faf01 100644
--- a/win32/newfns.c
+++ b/win32/newfns.c
@@ -15,6 +15,7 @@
 #include "winerror.h"
 #include "heap.h"
 #include "debug.h"
+#include "debugstr.h"
 
 /****************************************************************************
  *		UTRegister (KERNEL32.697)
@@ -60,6 +61,12 @@
 	return 0xcafebabe;
 }
 
+HANDLE32 WINAPI FindFirstChangeNotification32W(LPCWSTR lpPathName,BOOL32 bWatchSubtree,DWORD dwNotifyFilter) {
+	FIXME(file,"(%s,%d,%08lx): stub\n",
+	      debugstr_w(lpPathName),bWatchSubtree,dwNotifyFilter);
+	return 0xcafebabe;
+}
+
 BOOL32 WINAPI FindNextChangeNotification(HANDLE32 fcnhandle) {
 	FIXME(file,"(%08x): stub!\n",fcnhandle);
 	return FALSE;
@@ -81,22 +88,6 @@
 }
 
 /****************************************************************************
- *		DeviceIoControl (KERNEL32.188)
- */
-BOOL32 WINAPI DeviceIoControl(HANDLE32 hDevice, DWORD dwIoControlCode, 
-			      LPVOID lpvlnBuffer, DWORD cblnBuffer,
-			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
-			      LPDWORD lpcbBytesReturned,
-			      LPOVERLAPPED lpoPverlapped)
-{
-
-        FIXME(comm, "(...): stub!\n");
-	/* FIXME: Set appropriate error */
-	return FALSE;
-
-}
-
-/****************************************************************************
  *		FlushInstructionCache (KERNEL32.261)
  */
 BOOL32 WINAPI FlushInstructionCache(DWORD x,DWORD y,DWORD z) {
@@ -110,12 +101,12 @@
 HANDLE32 WINAPI CreateNamedPipeA (LPCSTR lpName, DWORD dwOpenMode,
 				  DWORD dwPipeMode, DWORD nMaxInstances,
 				  DWORD nOutBufferSize, DWORD nInBufferSize,
-				  DWORD nDafaultTimeOut,
+				  DWORD nDefaultTimeOut,
 				  LPSECURITY_ATTRIBUTES lpSecurityAttributes)
 {
   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, 
+	 nOutBufferSize, nInBufferSize, nDefaultTimeOut, 
 	 lpSecurityAttributes);
   /* if (nMaxInstances > PIPE_UNLIMITED_INSTANCES) {
     SetLastError (ERROR_INVALID_PARAMETER);
@@ -132,12 +123,12 @@
 HANDLE32 WINAPI CreateNamedPipeW (LPCWSTR lpName, DWORD dwOpenMode,
 				  DWORD dwPipeMode, DWORD nMaxInstances,
 				  DWORD nOutBufferSize, DWORD nInBufferSize,
-				  DWORD nDafaultTimeOut,
+				  DWORD nDefaultTimeOut,
 				  LPSECURITY_ATTRIBUTES lpSecurityAttributes)
 {
   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, 
+	 nOutBufferSize, nInBufferSize, nDefaultTimeOut, 
 	 lpSecurityAttributes);
 
   SetLastError (ERROR_UNKNOWN);
@@ -145,6 +136,21 @@
 }
 
 /***********************************************************************
+ *	CreatePipe (KERNEL32.170)
+ */
+
+BOOL32 WINAPI CreatePipe(PHANDLE hReadPipe,
+                         PHANDLE hWritePipe,
+                         LPSECURITY_ATTRIBUTES lpPipeAttributes,
+                         DWORD nSize)
+{
+  FIXME (win32,"ReadPipe=%p WritePipe=%p SecAttr=%p Size=%ld",
+               hReadPipe,hWritePipe,lpPipeAttributes,nSize);
+  SetLastError(ERROR_UNKNOWN);
+  return FALSE;
+}
+
+/***********************************************************************
  *           GetSystemPowerStatus      (KERNEL32.621)
  */
 BOOL32 WINAPI GetSystemPowerStatus(LPSYSTEM_POWER_STATUS sps_ptr)
@@ -299,7 +305,7 @@
  */
 DWORD WINAPI GetThreadDesktop( DWORD dwThreadId )
 {
-    FIXME(win32, "(%ld): stub\n",dwThreadId);
+    FIXME(win32, "(%lx): stub\n",dwThreadId);
     return 1;
 }
 
@@ -363,6 +369,46 @@
 
 
 BOOL32 WINAPI EnumPorts32A(LPSTR name,DWORD level,LPBYTE ports,DWORD bufsize,LPDWORD bufneeded,LPDWORD bufreturned) {
-	FIXME(win32,"(%s,%d,%p,%d,%p,%p), stub!\n",name,level,ports,bufsize,bufneeded,bufreturned);
+	FIXME(win32,"(%s,%ld,%p,%ld,%p,%p), stub!\n",name,level,ports,bufsize,bufneeded,bufreturned);
 	return FALSE;
 }
+
+/******************************************************************************
+ * IsDebuggerPresent [KERNEL32.827]
+ *
+ */
+BOOL32 WINAPI IsDebuggerPresent() {
+	FIXME(win32," ... no debuggers yet, returning FALSE.\n");
+	return FALSE; 
+}
+
+
+/******************************************************************************
+ * OpenDesktop32A [USER32.408]
+ *
+ * NOTES
+ *    Return type should be HDESK
+ */
+HANDLE32 WINAPI OpenDesktop32A( LPCSTR lpszDesktop, DWORD dwFlags, 
+                                BOOL32 fInherit, DWORD dwDesiredAccess )
+{
+    FIXME(win32,"(%s,%lx,%i,%lx): stub\n",debugstr_a(lpszDesktop),dwFlags,
+          fInherit,dwDesiredAccess);
+    return 1;
+}
+
+
+BOOL32 WINAPI SetUserObjectInformation32A( HANDLE32 hObj, int nIndex, 
+                                           LPVOID pvInfo, DWORD nLength )
+{
+    FIXME(win32,"(%x,%d,%p,%lx): stub\n",hObj,nIndex,pvInfo,nLength);
+    return TRUE;
+}
+
+
+BOOL32 WINAPI SetThreadDesktop( HANDLE32 hDesktop )
+{
+    FIXME(win32,"(%x): stub\n",hDesktop);
+    return TRUE;
+}
+
diff --git a/win32/ordinals.c b/win32/ordinals.c
index e0e08f7..481fa08 100644
--- a/win32/ordinals.c
+++ b/win32/ordinals.c
@@ -17,7 +17,7 @@
 #include "debug.h"
 
 static CRITICAL_SECTION Win16Mutex;
-static SEGPTR segWin16Mutex = NULL;
+static SEGPTR segWin16Mutex = (SEGPTR)NULL;
 
 
 /***********************************************
@@ -33,7 +33,7 @@
 /***********************************************
  *           _ConfirmWin16Lock    (KERNEL32.96)
  */
-DWORD _ConfirmWin16Lock(void)
+DWORD WINAPI _ConfirmWin16Lock(void)
 {
     FIXME(win32, "()\n");
     return 1;
@@ -42,7 +42,7 @@
 /***********************************************
  *           _EnterSysLevel    (KERNEL32.97)
  */
-VOID _EnterSysLevel(CRITICAL_SECTION *lock)
+VOID WINAPI _EnterSysLevel(CRITICAL_SECTION *lock)
 {
     FIXME(win32, "(%p)\n", lock);
 }
@@ -50,7 +50,7 @@
 /***********************************************
  *           _EnterSysLevel    (KERNEL32.98)
  */
-VOID _LeaveSysLevel(CRITICAL_SECTION *lock)
+VOID WINAPI _LeaveSysLevel(CRITICAL_SECTION *lock)
 {
     FIXME(win32, "(%p)\n", lock);
 }
@@ -58,7 +58,7 @@
 /***********************************************
  *           ReleaseThunkLock    (KERNEL32.48)
  */
-VOID ReleaseThunkLock(DWORD *mutex_count)
+VOID WINAPI ReleaseThunkLock(DWORD *mutex_count)
 {
     _LeaveSysLevel(&Win16Mutex);
 
@@ -69,7 +69,7 @@
 /***********************************************
  *           RestoreThunkLock    (KERNEL32.49)
  */
-VOID RestoreThunkLock(DWORD mutex_count)
+VOID WINAPI RestoreThunkLock(DWORD mutex_count)
 {
     NtCurrentTeb()->mutex_count = (WORD)mutex_count;
 
diff --git a/win32/time.c b/win32/time.c
index bfa2765..9dc1e4c 100644
--- a/win32/time.c
+++ b/win32/time.c
@@ -146,5 +146,5 @@
  *              GetSystemTimeAsFileTime  (KERNEL32)
  */
 VOID WINAPI GetSystemTimeAsFileTime(LPFILETIME systemtimeAsfiletime) {
-	DOSFS_UnixTimeToFileTime(time(NULL),systemtimeAsfiletime,NULL);
+	DOSFS_UnixTimeToFileTime(time(NULL),systemtimeAsfiletime,0);
 }
diff --git a/windows/defwnd.c b/windows/defwnd.c
index ec0ade8..1a57fa4 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -153,7 +153,7 @@
 
     case WM_RBUTTONDOWN:
     case WM_NCRBUTTONDOWN:
-        if( wndPtr->flags & WIN_ISWIN32 ) 
+        if ((wndPtr->flags & WIN_ISWIN32) || TWEAK_Win95Look)
         {
 	    ClientToScreen16(wndPtr->hwndSelf, (LPPOINT16)&lParam);
             SendMessage32A( wndPtr->hwndSelf, WM_CONTEXTMENU,
@@ -167,7 +167,6 @@
 
      /* else 
       *     FIXME: Track system popup if click was in the caption area. */
-
 	break;
 
     case WM_NCACTIVATE:
diff --git a/windows/dialog.c b/windows/dialog.c
index 53e891e..2226a2e 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -576,6 +576,7 @@
     {
           /* The font height must be negative as it is a point size */
           /* (see CreateFont() documentation in the Windows SDK).   */
+
 	if (win32Template)
 	    hFont = CreateFont32W( -template.pointSize, 0, 0, 0,
                                    template.weight, template.italic, FALSE,
@@ -583,9 +584,9 @@
                                    FF_DONTCARE, (LPCWSTR)template.faceName );
 	else
 	    hFont = CreateFont16( -template.pointSize, 0, 0, 0, FW_DONTCARE,
-			    FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
-			    PROOF_QUALITY, FF_DONTCARE,
-                            template.faceName );
+				  FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
+				  PROOF_QUALITY, FF_DONTCARE,
+				  template.faceName );
 	if (hFont)
 	{
 	    TEXTMETRIC16 tm;
diff --git a/windows/driver.c b/windows/driver.c
index 79333fa..f62b3f1 100644
--- a/windows/driver.c
+++ b/windows/driver.c
@@ -1,10 +1,12 @@
 /*
- * Wine Drivers functions
+ * WINE Drivers functions
  *
  * Copyright 1994 Martin Ayotte
-*/
+ * Copyright 1998 Marcus Meissner
+ */
 
 #include "windows.h"
+#include "heap.h"
 #include "win.h"
 #include "callback.h"
 #include "driver.h"
@@ -12,6 +14,7 @@
 #include "debug.h"
 
 LPDRIVERITEM lpDrvItemList = NULL;
+LPDRIVERITEM32A lpDrvItemList32 = NULL;
 
 /**************************************************************************
  *	LoadStartupDrivers
@@ -33,20 +36,19 @@
     while (lstrlen32A( ptr ) != 0)
     {
 	TRACE(driver, "str='%s'\n", ptr );
-	hDrv = OpenDriver( ptr, "drivers", 0L );
+	hDrv = OpenDriver16( ptr, "drivers", 0L );
 	TRACE(driver, "hDrv=%04x\n", hDrv );
 	ptr += lstrlen32A(ptr) + 1;
     }
     TRACE(driver, "end of list !\n" );
-
     return;
 }
 
 /**************************************************************************
  *				SendDriverMessage		[USER.251]
  */
-LRESULT WINAPI SendDriverMessage(HDRVR16 hDriver, UINT16 msg, LPARAM lParam1,
-                                 LPARAM lParam2)
+LRESULT WINAPI SendDriverMessage16(HDRVR16 hDriver, UINT16 msg, LPARAM lParam1,
+                                   LPARAM lParam2)
 {
     LPDRIVERITEM lpdrv;
     LRESULT retval;
@@ -71,21 +73,48 @@
 }
 
 /**************************************************************************
+ *				SendDriverMessage		[WINMM.19]
+ */
+LRESULT WINAPI SendDriverMessage32(HDRVR32 hDriver, UINT32 msg, LPARAM lParam1,
+                                   LPARAM lParam2)
+{
+    LPDRIVERITEM32A lpdrv;
+    LRESULT retval;
+
+    TRACE(driver, "(%04x, %04X, %08lX, %08lX)\n",
+		    hDriver, msg, lParam1, lParam2 );
+
+    lpdrv = (LPDRIVERITEM32A)hDriver;
+    if (!lpdrv)
+	return 0;
+
+    retval = lpdrv->driverproc(lpdrv->dis.hDriver,hDriver,msg,lParam1,lParam2);
+
+    TRACE(driver, "retval = %ld\n", retval );
+
+    return retval;
+}
+
+/**************************************************************************
  *				OpenDriver		        [USER.252]
  */
-HDRVR16 WINAPI OpenDriver(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam)
-{
+HDRVR16 WINAPI OpenDriver16(
+	LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam
+) {
     HDRVR16 hDrvr;
     LPDRIVERITEM lpdrv, lpnewdrv;
     char DrvName[128];
-    WORD ordinal;
 
     TRACE(driver,"('%s', '%s', %08lX);\n",
 		    lpDriverName, lpSectionName, lParam );
 
-    if (lpSectionName == NULL) lpSectionName = "drivers";
-    GetPrivateProfileString32A( lpSectionName, lpDriverName, "", DrvName,
-			     sizeof(DrvName), "SYSTEM.INI" );
+    if (lpSectionName == NULL) {
+    	lstrcpyn32A(DrvName,lpDriverName,sizeof(DrvName));
+	FIXME(driver,"sectionname NULL, assuming directfilename (%s)\n",lpDriverName);
+    } else {
+        GetPrivateProfileString32A( lpSectionName, lpDriverName, "", DrvName,
+				     sizeof(DrvName), "SYSTEM.INI" );
+    }
     TRACE(driver,"DrvName='%s'\n", DrvName );
     if (lstrlen32A(DrvName) < 1) return 0;
 
@@ -95,7 +124,7 @@
 	if (!lstrcmpi32A( lpDriverName, lpdrv->dis.szAliasName ))
 	{
 	    lpdrv->count++;
-	    SendDriverMessage( lpdrv->dis.hDriver, DRV_OPEN, 0L, lParam );
+	    SendDriverMessage16( lpdrv->dis.hDriver, DRV_OPEN, 0L, lParam );
 	    return lpdrv->dis.hDriver;
 	}
 	lpdrv = lpdrv->lpNextItem;
@@ -120,10 +149,7 @@
     lpnewdrv->dis.hDriver = hDrvr;
     lstrcpy32A( lpnewdrv->dis.szAliasName, lpDriverName );
     lpnewdrv->count = 1;
-    ordinal = NE_GetOrdinal( lpnewdrv->dis.hModule, "DRIVERPROC" );
-    if (!ordinal ||
-        !(lpnewdrv->lpDrvProc = (DRIVERPROC16)NE_GetEntryPoint(
-                                             lpnewdrv->dis.hModule, ordinal )))
+    if (!(lpnewdrv->lpDrvProc = (DRIVERPROC16)WIN32_GetProcAddress16(lpnewdrv->dis.hModule, "DRIVERPROC" )))
     {
 	FreeModule16( lpnewdrv->dis.hModule );
 	GlobalUnlock16( hDrvr );
@@ -143,18 +169,104 @@
 	lpnewdrv->lpPrevItem = lpdrv;
     }
 
-    SendDriverMessage( hDrvr, DRV_LOAD, 0L, lParam );
-    SendDriverMessage( hDrvr, DRV_ENABLE, 0L, lParam );
-    SendDriverMessage( hDrvr, DRV_OPEN, 0L, lParam );
+    SendDriverMessage16( hDrvr, DRV_LOAD, 0L, lParam );
+    SendDriverMessage16( hDrvr, DRV_ENABLE, 0L, lParam );
+    SendDriverMessage16( hDrvr, DRV_OPEN, 0L, lParam );
 
     TRACE(driver, "hDrvr=%04x loaded !\n", hDrvr );
     return hDrvr;
 }
 
 /**************************************************************************
- *				CloseDriver				[USER.253]
+ *				OpenDriver		        [WINMM.15]
+ * (0,1,DRV_LOAD  ,0       ,0)
+ * (0,1,DRV_ENABLE,0       ,0)
+ * (0,1,DRV_OPEN  ,buf[256],0)
  */
-LRESULT WINAPI CloseDriver(HDRVR16 hDrvr, LPARAM lParam1, LPARAM lParam2)
+HDRVR32 WINAPI OpenDriver32A(
+	LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam
+) {
+    HDRVR32 hDrvr;
+    LPDRIVERITEM32A lpdrv, lpnewdrv;
+    char DrvName[128],*tmpbuf;
+
+    TRACE(driver,"('%s', '%s', %08lX);\n",
+		    lpDriverName,lpSectionName,lParam );
+
+    if (lpSectionName == NULL) {
+    	lstrcpyn32A(DrvName,lpDriverName,sizeof(DrvName));
+	FIXME(driver,"sectionname NULL, assuming directfilename (%s)\n",lpDriverName);
+    } else  {
+	GetPrivateProfileString32A( lpSectionName, lpDriverName, "", DrvName,
+				 sizeof(DrvName), "system.ini" );
+    }
+    TRACE(driver,"DrvName='%s'\n", DrvName );
+    if (lstrlen32A(DrvName) < 1) return 0;
+
+    lpdrv = lpDrvItemList32;
+    while (lpdrv) {
+	if (!lstrcmpi32A( lpDriverName, lpdrv->dis.szAliasName )) {
+	    lpdrv->count++;
+	    lpdrv->dis.hDriver = SendDriverMessage32( lpdrv->dis.hDriver, DRV_OPEN, ""/*FIXME*/, 0L );
+	    return (HDRVR32)lpdrv;
+	}
+	lpdrv = lpdrv->next;
+    }
+
+    hDrvr = (HDRVR32)HeapAlloc(SystemHeap,0, sizeof(DRIVERITEM32A) );
+    if (!hDrvr) {
+    	ERR(driver,"out of memory");
+	return 0;
+    }
+    lpnewdrv = (DRIVERITEM32A*)hDrvr;
+    lpnewdrv->dis.length = sizeof( DRIVERINFOSTRUCT32A );
+    lpnewdrv->dis.hModule = LoadLibrary32A( DrvName );
+    if (!lpnewdrv->dis.hModule) {
+    	FIXME(driver,"could not load library %s\n",DrvName);
+	HeapFree( SystemHeap,0,(LPVOID)hDrvr );
+	return 0;
+    }
+    lstrcpy32A( lpnewdrv->dis.szAliasName, lpDriverName );
+    lpnewdrv->count = 1;
+    if (!(lpnewdrv->driverproc = (DRIVERPROC32)GetProcAddress32(lpnewdrv->dis.hModule, "DriverProc" )))
+    {
+    	FIXME(driver,"no 'DriverProc' found in %s\n",DrvName);
+	FreeModule32( lpnewdrv->dis.hModule );
+	HeapFree( SystemHeap,0, (LPVOID)hDrvr );
+	return 0;
+    }
+
+    lpnewdrv->next = lpDrvItemList32;
+    lpDrvItemList32 = lpnewdrv;
+
+    SendDriverMessage32( hDrvr, DRV_LOAD, 0L, lParam );
+    SendDriverMessage32( hDrvr, DRV_ENABLE, 0L, lParam );
+    tmpbuf = HeapAlloc(SystemHeap,0,256);
+    lpnewdrv->dis.hDriver=SendDriverMessage32(hDrvr,DRV_OPEN,tmpbuf,lParam);
+    HeapFree(SystemHeap,0,tmpbuf);
+    TRACE(driver, "hDrvr=%04x loaded !\n", hDrvr );
+    return hDrvr;
+}
+
+/**************************************************************************
+ *				OpenDriver		        [WINMM.15]
+ */
+HDRVR32 WINAPI OpenDriver32W(
+	LPCWSTR lpDriverName, LPCWSTR lpSectionName, LPARAM lParam
+) {
+	LPSTR dn = HEAP_strdupWtoA(GetProcessHeap(),0,lpDriverName);
+	LPSTR sn = HEAP_strdupWtoA(GetProcessHeap(),0,lpSectionName);
+	HDRVR32	ret = OpenDriver32A(dn,sn,lParam);
+
+	if (dn) HeapFree(GetProcessHeap(),0,dn);
+	if (sn) HeapFree(GetProcessHeap(),0,sn);
+	return ret;
+}
+
+/**************************************************************************
+ *			CloseDriver				[USER.253]
+ */
+LRESULT WINAPI CloseDriver16(HDRVR16 hDrvr, LPARAM lParam1, LPARAM lParam2)
 {
     LPDRIVERITEM lpdrv;
 
@@ -164,11 +276,11 @@
     lpdrv = (LPDRIVERITEM)GlobalLock16( hDrvr );
     if (lpdrv != NULL && lpdrv->dis.hDriver == hDrvr)
     {
-	SendDriverMessage( hDrvr, DRV_CLOSE, lParam1, lParam2 );
+	SendDriverMessage16( hDrvr, DRV_CLOSE, lParam1, lParam2 );
 	if (--lpdrv->count == 0)
 	{
-	    SendDriverMessage( hDrvr, DRV_DISABLE, lParam1, lParam2 );
-	    SendDriverMessage( hDrvr, DRV_FREE, lParam1, lParam2 );
+	    SendDriverMessage16( hDrvr, DRV_DISABLE, lParam1, lParam2 );
+	    SendDriverMessage16( hDrvr, DRV_FREE, lParam1, lParam2 );
 
 	    if (lpdrv->lpPrevItem)
 	      lpdrv->lpPrevItem->lpNextItem = lpdrv->lpNextItem;
@@ -192,7 +304,7 @@
 /**************************************************************************
  *				GetDriverModuleHandle	[USER.254]
  */
-HMODULE16 WINAPI GetDriverModuleHandle(HDRVR16 hDrvr)
+HMODULE16 WINAPI GetDriverModuleHandle16(HDRVR16 hDrvr)
 {
     LPDRIVERITEM lpdrv;
     HMODULE16 hModule = 0;
@@ -209,6 +321,19 @@
 }
 
 /**************************************************************************
+ *				GetDriverModuleHandle	[USER.254]
+ */
+HMODULE32 WINAPI GetDriverModuleHandle32(HDRVR32 hDrvr)
+{
+    LPDRIVERITEM32A lpdrv = (LPDRIVERITEM32A)hDrvr;
+
+    TRACE(driver, "(%04x);\n", hDrvr);
+    if (!lpdrv)
+    	return 0;
+    return lpdrv->dis.hModule;
+}
+
+/**************************************************************************
  *				DefDriverProc			[USER.255]
  */
 LRESULT WINAPI DefDriverProc(DWORD dwDevID, HDRVR16 hDriv, UINT16 wMsg, 
diff --git a/windows/graphics.c b/windows/graphics.c
index e3e1d25..fcdf859 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -52,6 +52,7 @@
 	    bRet = TRUE;
 	}
 	if( hPrevPen ) SelectObject32( hdc, hPrevPen );
+	GDI_HEAP_UNLOCK( hdc );
     }
     return bRet;
 }
@@ -69,10 +70,14 @@
 {
     BITMAPOBJ *bmp;
     DC *dc;
+    BOOL32 ret = TRUE;
 
     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return FALSE;
     if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
+    {
+        GDI_HEAP_UNLOCK( hdc );
         return FALSE;
+    }
 
     xdest += dc->w.DCOrgX; ydest += dc->w.DCOrgY;
 
@@ -104,17 +109,19 @@
 			xsrc, ysrc, width, height, xdest, ydest, plane );
 	}
 	else 
+	{
 	    TSXCopyArea( display, bmp->pixmap, dc->u.x.drawable, 
 		       dc->u.x.gc, xsrc, ysrc, width, height, xdest, ydest );
+	}
     }
     else 
     {
-      GDI_HEAP_UNLOCK( hbitmap );
-      return FALSE;
+      ret = FALSE;
     }
 
+    GDI_HEAP_UNLOCK( hdc );
     GDI_HEAP_UNLOCK( hbitmap );
-    return TRUE;
+    return ret;
 }
 
 
@@ -195,6 +202,7 @@
     }
 
     SelectObject32( hdc, hPrevBrush );
+    GDI_HEAP_UNLOCK( hdc );
 }
 
 
@@ -216,6 +224,7 @@
 	    TSXDrawRectangle( display, dc->u.x.drawable, dc->u.x.gc, 
 			    x + dc->w.DCOrgX, y + dc->w.DCOrgY, w - 1, h - 1);
 	if( hPrevPen ) SelectObject32( hdc, hPrevPen );
+	GDI_HEAP_UNLOCK( hdc );
     }
 }
 
@@ -231,13 +240,17 @@
     if ( hMonoBitmap ) 
     {
        if ( !(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hMonoBitmap, BITMAP_MAGIC)) 
-	   || bmp->bitmap.bmBitsPixel != 1 ) return FALSE;
-	  
+	   || bmp->bitmap.bmBitsPixel != 1 ) 
+       {
+	   GDI_HEAP_UNLOCK( hdc );
+	   return FALSE;
+       }
        TSXSetClipOrigin( display, dc->u.x.gc, dc->w.DCOrgX + x, dc->w.DCOrgY + y);
     }
 
     TSXSetClipMask( display, dc->u.x.gc, (bmp) ? bmp->pixmap : None );
 
+    GDI_HEAP_UNLOCK( hdc );
     GDI_HEAP_UNLOCK( hMonoBitmap );
     return TRUE;
 }
diff --git a/windows/mdi.c b/windows/mdi.c
index 185c7ce..47e7e07 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -1708,3 +1708,39 @@
 			SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN );
 }
 
+
+/******************************************************************************
+ * CascadeWindows [USER32.21] Cascades MDI child windows
+ *
+ * RETURNS
+ *    Success: Number of cascaded windows.
+ *    Failure: 0
+ */
+WORD WINAPI
+CascadeWindows (HWND32 hwndParent, UINT32 wFlags, const LPRECT32 lpRect,
+		UINT32 cKids, const HWND32 *lpKids)
+{
+    FIXME (mdi, "(0x%08x,0x%08x,...,%u,...): stub\n",
+	   hwndParent, wFlags, cKids);
+
+    return 0;
+}
+
+
+/******************************************************************************
+ * TileWindows [USER32.545] Tiles MDI child windows
+ *
+ * RETURNS
+ *    Success: Number of tiled windows.
+ *    Failure: 0
+ */
+WORD WINAPI
+TileWindows (HWND32 hwndParent, UINT32 wFlags, const LPRECT32 lpRect,
+	     UINT32 cKids, const HWND32 *lpKids)
+{
+    FIXME (mdi, "(0x%08x,0x%08x,...,%u,...): stub\n",
+	   hwndParent, wFlags, cKids);
+
+    return 0;
+}
+
diff --git a/windows/message.c b/windows/message.c
index ee57696..82638ed 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -1736,3 +1736,13 @@
 	);
 	return 0;
 }
+
+BOOL32 WINAPI SendMessageCallBack32A(
+	HWND32 hWnd,UINT32 Msg,WPARAM32 wParam,LPARAM lParam,
+	/*SENDASYNCPROC*/FARPROC32 lpResultCallBack,DWORD dwData
+) {
+	FIXME(msg,"(0x%04x,0x%04x,0x%08lx,0x%08lx,%p,0x%08lx),stub!\n",
+		hWnd,Msg,wParam,lParam,lpResultCallBack,dwData
+	);
+	return FALSE;
+}
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 8ea40c2..521c0b1 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -98,8 +98,17 @@
     }
     if (menu) rect->top -= SYSMETRICS_CYMENU + SYSMETRICS_CYBORDER;
 
-    if (style & WS_VSCROLL) rect->right  += SYSMETRICS_CXVSCROLL - 1;
-    if (style & WS_HSCROLL) rect->bottom += SYSMETRICS_CYHSCROLL - 1;
+    if (style & WS_VSCROLL) {
+      rect->right  += SYSMETRICS_CXVSCROLL - 1;
+      if(!(style & WS_BORDER))
+	 rect->right++;
+    }
+
+    if (style & WS_HSCROLL) {
+      rect->bottom += SYSMETRICS_CYHSCROLL - 1;
+      if(!(style & WS_BORDER))
+	 rect->bottom++;
+    }
 }
 
 
@@ -149,7 +158,7 @@
             rect->top -= SYSMETRICS_CYCAPTION - SYSMETRICS_CYBORDER;
     }
     if (menu) rect->top -= SYSMETRICS_CYMENU + SYSMETRICS_CYBORDER + 2;
-    else  if (!(style & WS_CHILD)) 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;
@@ -159,7 +168,7 @@
 /***********************************************************************
  *           DrawCaptionTempA    (USER32.599)
  */
-DWORD DrawCaptionTemp32A(HWND32 hwnd,HDC32 hdc,LPRECT32 rect,
+DWORD WINAPI DrawCaptionTemp32A(HWND32 hwnd,HDC32 hdc,LPRECT32 rect,
     HFONT32 hfont,DWORD x1,LPCSTR str,DWORD x2)
 {
     FIXME(nonclient,"(%08x,%08x,%p,%08x,%08lx,\"%s\",%08lx): stub\n",
@@ -197,7 +206,7 @@
     if (!(style & (WS_POPUP | WS_CHILD)))  /* Overlapped window */
 	style |= WS_CAPTION;
     style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
-    exStyle &= WS_EX_DLGMODALFRAME;
+    exStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE);
     if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
 
     TRACE(nonclient, "(%d,%d)-(%d,%d) %08lx %d %08lx\n",
@@ -276,8 +285,6 @@
  * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
  * but without the borders (if any).
  * The rectangle is in window coordinates (for drawing with GetWindowDC()).
- *
- * FIXME:  A Win95 version of this function is needed.
  */
 static void NC_GetInsideRect( HWND32 hwnd, RECT32 *rect )
 {
@@ -309,6 +316,42 @@
 
 
 /***********************************************************************
+ *           NC_GetInsideRect95
+ *
+ * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
+ * but without the borders (if any).
+ * The rectangle is in window coordinates (for drawing with GetWindowDC()).
+ */
+
+static void
+NC_GetInsideRect95 (HWND32 hwnd, RECT32 *rect)
+{
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+
+    rect->top    = rect->left = 0;
+    rect->right  = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
+    rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
+
+    if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) return;
+
+      /* Remove frame from rectangle */
+    if (HAS_DLGFRAME (wndPtr->dwStyle, wndPtr->dwExStyle ))
+    {
+	InflateRect32( rect, -SYSMETRICS_CXFIXEDFRAME, -SYSMETRICS_CYFIXEDFRAME);
+    }
+    else if (HAS_THICKFRAME (wndPtr->dwStyle))
+    {
+	InflateRect32( rect, -SYSMETRICS_CXSIZEFRAME, -SYSMETRICS_CYSIZEFRAME );
+
+	if (wndPtr->dwStyle & WS_BORDER)
+	    InflateRect32( rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER );
+    }
+
+    return;
+}
+
+
+/***********************************************************************
  *           NC_HandleNCHitTest
  *
  * Handle a WM_NCHITTEST message. Called from DefWindowProc().
@@ -526,29 +569,28 @@
  *
  *****************************************************************************/
 
-void  NC_DrawSysButton95(
-    HWND32  hwnd,
-    HDC32  hdc,
-    BOOL32  down )
+void
+NC_DrawSysButton95 (HWND32 hwnd, HDC32 hdc, BOOL32 down)
 {
     RECT32 rect;
     HDC32 hdcMem;
     HBITMAP32 hbitmap;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
-    SIZE32  bmsz;
 
     if( !(wndPtr->flags & WIN_MANAGED) )
     {
-	NC_GetInsideRect( hwnd, &rect );
+	BITMAP32 bmp;
+
+	NC_GetInsideRect95( hwnd, &rect );
 	hdcMem = CreateCompatibleDC32( hdc );
 	hbitmap = SelectObject32( hdcMem, hbitmapClose );
-	if(GetBitmapDimensionEx32( hbitmapClose, &bmsz )) {
-	    BitBlt32(hdc, rect.left + (sysMetrics[SM_CXSIZE] - bmsz.cx) / 2 +
+	GetObject32A (hbitmapClose, sizeof(BITMAP32), &bmp);
+	BitBlt32 (hdc, rect.left + (sysMetrics[SM_CXSIZE] - bmp.bmWidth) / 2 +
 		     NC_SysControlNudge,
-		     rect.top + (sysMetrics[SM_CYSIZE] - bmsz.cy - 1) / 2,
-		     bmsz.cx, bmsz.cy,
+		     rect.top + (sysMetrics[SM_CYSIZE] - bmp.bmHeight - 1) / 2,
+		     bmp.bmWidth, bmp.bmHeight,
 		     hdcMem, 0, 0, down ? NOTSRCCOPY : SRCCOPY );
-	}
+
 	SelectObject32( hdcMem, hbitmap );
 	DeleteDC32( hdcMem );
 	
@@ -594,7 +636,7 @@
 				(down ? hbitmapMaximizeD : hbitmapMaximize)),
 			       &bmsz)) {
 
-	NC_GetInsideRect( hwnd, &rect );
+	NC_GetInsideRect95( hwnd, &rect );
 	
 	GRAPH_DrawBitmap( hdc, bm,
 			  rect.right + NC_MaxControlNudge -
@@ -640,7 +682,7 @@
 	GetBitmapDimensionEx32((bm = down ? hbitmapMinimizeD :
 				hbitmapMinimize), &bmsz)) {
 	
-	NC_GetInsideRect( hwnd, &rect );
+	NC_GetInsideRect95( hwnd, &rect );
 
 	if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
 	    rect.right += -1 + NC_MaxControlNudge -
@@ -764,6 +806,8 @@
  *   Revision history
  *        06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
  *             Original implementation (based on NC_DrawFrame)
+ *        02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ *             Some minor fixes.
  *
  *****************************************************************************/
 
@@ -777,19 +821,18 @@
 
     if (dlgFrame)
     {
-	width = SYSMETRICS_CXDLGFRAME - 1;
-	height = SYSMETRICS_CYDLGFRAME - 1;
-        SelectObject32( hdc, GetSysColorBrush32(active ? COLOR_ACTIVECAPTION :
-						COLOR_INACTIVECAPTION) );
+	width = sysMetrics[SM_CXDLGFRAME] - sysMetrics[SM_CXEDGE];
+	height = sysMetrics[SM_CYDLGFRAME] - sysMetrics[SM_CYEDGE];
     }
     else
     {
 	width = sysMetrics[SM_CXFRAME] - sysMetrics[SM_CXEDGE] - 1;
 	height = sysMetrics[SM_CYFRAME] - sysMetrics[SM_CYEDGE] - 1;
-        SelectObject32( hdc, GetSysColorBrush32(active ? COLOR_ACTIVEBORDER :
-						COLOR_INACTIVEBORDER) );
     }
 
+    SelectObject32( hdc, GetSysColorBrush32(active ? COLOR_ACTIVEBORDER :
+		COLOR_INACTIVEBORDER) );
+
     /* Draw frame */
     PatBlt32( hdc, rect->left, rect->top,
               rect->right - rect->left, height, PATCOPY );
@@ -921,13 +964,14 @@
  *   The correct pen for the window frame must be selected in the DC.
  *
  *   Bugs
- *        Hey, a function that finally works!  Well, almost.  In Win95, the
- *        title has its own font -- not the system font.  It's being worked
- *        on.
+ *        Hey, a function that finally works!  Well, almost.
+ *        It's being worked on.
  *
  *   Revision history
  *        05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
  *             Original implementation.
+ *        02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ *             Some minor fixes.
  *
  *****************************************************************************/
 
@@ -957,16 +1001,6 @@
 	hbitmapRestore   = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
 	hbitmapRestoreD  = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
     }
-    
-    if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME) {
-	HBRUSH32 hbrushOld = SelectObject32(hdc, GetSysColorBrush32(COLOR_WINDOW) );
-	PatBlt32( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
-	PatBlt32( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
-	PatBlt32( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
-	r.left++;
-	r.right--;
-	SelectObject32( hdc, hbrushOld );
-    }
 
     if (style & WS_SYSMENU) {
 	NC_DrawSysButton95( hwnd, hdc, FALSE );
@@ -982,12 +1016,18 @@
     }
 
     if (GetWindowText32A( hwnd, buffer, sizeof(buffer) )) {
+	NONCLIENTMETRICS32A nclm;
+	HFONT32 hFont, hOldFont;
+	nclm.cbSize = sizeof(NONCLIENTMETRICS32A);
+	SystemParametersInfo32A (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
+	hFont = CreateFontIndirect32A (&nclm.lfCaptionFont);
+	hOldFont = SelectObject32 (hdc, hFont);
 	if (active) SetTextColor32( hdc, GetSysColor32( COLOR_CAPTIONTEXT ) );
 	else SetTextColor32( hdc, GetSysColor32( COLOR_INACTIVECAPTIONTEXT ) );
 	SetBkMode32( hdc, TRANSPARENT );
-	r.top += NC_CaptionTopNudge - 2;
-	r.left += NC_CaptionLeftNudge;
+	r.left += 2;
 	DrawText32A( hdc, buffer, -1, &r, NC_CaptionTextFlags );
+	DeleteObject32 (SelectObject32 (hdc, hOldFont));
     }
 }
 
@@ -1075,6 +1115,10 @@
         RECT32 r = rect;
         r.left = r.right - SYSMETRICS_CXVSCROLL + 1;
         r.top  = r.bottom - SYSMETRICS_CYHSCROLL + 1;
+	if(wndPtr->dwStyle & WS_BORDER) {
+	  r.left++;
+	  r.top++;
+	}
         FillRect32( hdc, &r, GetSysColorBrush32(COLOR_SCROLLBAR) );
     }    
 
@@ -1099,6 +1143,8 @@
  *   Revision history
  *        03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
  *             Original implementation
+ *        10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ *             Fixed some bugs.
  *
  *****************************************************************************/
 
@@ -1140,8 +1186,7 @@
     if(!(wndPtr->flags & WIN_MANAGED)) {
         if((wndPtr->dwStyle & WS_BORDER) || (wndPtr->dwStyle & WS_DLGFRAME) ||
 	   (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)) {
-	    TWEAK_DrawReliefRect95(hdc, &rect);
-	    InflateRect32(&rect, -2, -2);
+            DrawEdge32 (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
         }
 
         if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle )) 
@@ -1189,6 +1234,7 @@
 
     InflateRect32(&rect, -1, -1);
 
+
     /* Draw the scroll-bars */
 
     if (wndPtr->dwStyle & WS_VSCROLL)
@@ -1325,7 +1371,10 @@
 	  GetWindowRect32( wndPtr->hwndSelf, rect );
       else
       {
-  	  NC_GetInsideRect( wndPtr->hwndSelf, rect );
+          if(TWEAK_Win95Look)
+              NC_GetInsideRect95( wndPtr->hwndSelf, rect );
+          else
+              NC_GetInsideRect( wndPtr->hwndSelf, rect );
   	  OffsetRect32( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
   	  if (wndPtr->dwStyle & WS_CHILD)
      	      ClientToScreen32( wndPtr->parent->hwndSelf, (POINT32 *)rect );
@@ -1354,7 +1403,10 @@
     {
 	  /* Move pointer at the center of the caption */
 	RECT32 rect;
-	NC_GetInsideRect( wndPtr->hwndSelf, &rect );
+        if(TWEAK_Win95Look)
+            NC_GetInsideRect95( wndPtr->hwndSelf, &rect );
+        else
+            NC_GetInsideRect( wndPtr->hwndSelf, &rect );
 	if (wndPtr->dwStyle & WS_SYSMENU)
 	    rect.left += SYSMETRICS_CXSIZE + 1;
 	if (wndPtr->dwStyle & WS_MINIMIZEBOX)
diff --git a/windows/painting.c b/windows/painting.c
index d35e991..c97dad1 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -300,8 +300,7 @@
     }
     else
     {
-        TRACE(win, "%04x NULL %04x flags=%04x\n",
-                     hwnd, hrgnUpdate, flags);
+        TRACE(win, "%04x NULL %04x flags=%04x\n", hwnd, hrgnUpdate, flags);
     }
 
     GetClientRect32( hwnd, &rectClient );
diff --git a/windows/scroll.c b/windows/scroll.c
index 3acef48..d8b06b3 100644
--- a/windows/scroll.c
+++ b/windows/scroll.c
@@ -10,6 +10,7 @@
 #include <stdlib.h>
 #include "windows.h"
 #include "class.h"
+#include "dc.h"
 #include "win.h"
 #include "gdi.h"
 #include "dce.h"
@@ -193,7 +194,10 @@
     }
 
     if( rDClip.left >= rDClip.right || rDClip.top >= rDClip.bottom )
+    {
+        GDI_HEAP_UNLOCK( hdc );
 	return FALSE;
+    }
     
     hrgnClip = GetClipRgn16(hdc);
     hrgnScrollClip = CreateRectRgnIndirect32(&rDClip);
@@ -236,7 +240,10 @@
 
 	if (!BitBlt32( hdc, dest.x, dest.y, ldx, ldy,
 		       hdc, src.x, src.y, SRCCOPY))
+	{
+	    GDI_HEAP_UNLOCK( hdc );
 	    return FALSE;
+	}
     }
 
     /* restore clipping region */
@@ -287,6 +294,7 @@
     }
 
     DeleteObject32( hrgnScrollClip );     
+    GDI_HEAP_UNLOCK( hdc );
     return TRUE;
 }
 
@@ -415,6 +423,7 @@
 		if( rcUpdate ) GetRgnBox32( hrgnUpdate, rcUpdate );
 	    }
 	    ReleaseDC32(hwnd, hDC);
+	    GDI_HEAP_UNLOCK( hDC );
 	}
 
 	if( wnd->hrgnUpdate > 1 )
diff --git a/windows/sysmetrics.c b/windows/sysmetrics.c
index b1f4ea9..b02f629 100644
--- a/windows/sysmetrics.c
+++ b/windows/sysmetrics.c
@@ -33,7 +33,7 @@
     sysMetrics[SM_CYBORDER] = sysMetrics[SM_CXBORDER];
     sysMetrics[SM_CXDLGFRAME] =
 	PROFILE_GetWineIniInt("Tweak.Layout", "DialogFrameWidth",
-			      TWEAK_Win95Look ? 2 : 4);
+			      TWEAK_Win95Look ? 3 : 4);
     sysMetrics[SM_CYDLGFRAME] = sysMetrics[SM_CXDLGFRAME];
     sysMetrics[SM_CYVTHUMB] = sysMetrics[SM_CXVSCROLL] - 1;
     sysMetrics[SM_CXHTHUMB] = sysMetrics[SM_CYVTHUMB];
@@ -118,8 +118,8 @@
     /* For the following: 0 = ok, 1 = failsafe, 2 = failsafe + network */
     sysMetrics[SM_CLEANBOOT] = 0;
 
-    sysMetrics[SM_CXDRAG] = 0;
-    sysMetrics[SM_CYDRAG] = 0;
+    sysMetrics[SM_CXDRAG] = 2;
+    sysMetrics[SM_CYDRAG] = 2;
     sysMetrics[SM_SHOWSOUNDS] = 0;
     sysMetrics[SM_CXMENUCHECK] = 2;
     sysMetrics[SM_CYMENUCHECK] = 2;
diff --git a/windows/win.c b/windows/win.c
index af2917d..e146e89 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -1647,6 +1647,15 @@
                                   (LPARAM)lpString );
 }
 
+/*******************************************************************
+ *	     InternalGetWindowText    (USER32.326)
+ */
+INT32 WINAPI InternalGetWindowText(HWND32 hwnd,LPWSTR lpString,INT32 nMaxCount )
+{
+	FIXME(win,"(0x%08lx,0x%08lx,%ld),stub!\n",hwnd,lpString,nMaxCount);
+	return GetWindowText32W(hwnd,lpString,nMaxCount);
+}
+
 
 /*******************************************************************
  *	     GetWindowText32W    (USER32.312)
@@ -2557,4 +2566,3 @@
 
     return (DWORD)(msg.lParam);
 }
-