Release 980822

Sat Aug 22 17:46:19 1998  Ulrich Weigand <weigand@informatik.uni-erlangen.de>

	* [include/dosexe.h] [include/module.h] [include/pe_image.h] 
	  [include/process.h] [include/windows.h] [loader/dos/module.c]
	  [loader/module.c] [loader/ne/module.c] [loader/pe_image.c]
	  [scheduler/process.c] [win32/process.c]
	Partially implemented CreateProcess32.

	* [win32/device.c] [relay32/kernel32.spec] [scheduler/k32obj.c]
	  [misc/registry.c] [win32/file.c]
	Partially implemented VxDCall (VMM registry services).

	* [files/dos_fs.c]
	DOSFS_FindNext made thread-safe.

	* [include/sig_context.h] [include/syslevel.h] [loader/signal.c]
	  [scheduler/syslevel.c] [tools/build.c]
	Replaced CALLTO16_Current_fs by SYSLEVEL_Win16CurrentTeb.

	* [win32/kernel32.c]
	Bugfix: QT_Thunk/FT_Thunk should return 'long' in DX:AX, not EAX.

	* [if1632/relay.c] [relay32/builtin32.c] [windows/msgbox.c]
	  [msdos/int20.c] [msdos/int21.c]
	Use ExitProcess instead of TASK_KillCurrentTask.

	* [include/task.h] [include/thread.h] [loader/task.c] 
	  [scheduler/thread.c] [include/queue.h] [windows/message.c] 
	  [windows/queue.c] [windows/win.c]
	Prevent Win32 threads from entering the TASK_Reschedule loop.
	(Note: Win32 messaging still doesn't work correctly; this patch
	is just preventing the system from crashing when Win32 threads
	call messaging functions. Messages will probably still get lost.)

	* [scheduler/critsection.c]
	Deactivated the use of SEM_UNDO for the SYSTEM_LOCK semaphore;
	for some reason, this leads to problems after threads terminate... 

Sat Aug 22 15:00:00 1998  Jürgen Schmied <juergen.schmied@metronet.de>

	* [include/authors.h]
	New file, includes all names of the developer (former shell.c)

	* [Makefile.in][configure][configure.in][dlls/Makefile.in]
	  [dlls/shell32/Makefile.in][shres.rc]
	Created dlls/shell32 and moved the shell32 stuff in it.
	Started to create internal resources.

	* [dlls/shell32/*]
	Split the shell32 implementation into smaller files.
	New classes: IContextMenu, IExtractIcon, IShellView.
	Implemented Shell_GetImageList().
	shell32 links to comctl32 now dynamically so it can use
	internal/external implementations.

	* [documentation/internal-dll] [documentation/shell32]
	New, could anybody do a spellcheck?

	* [include/commctrl.h]
	Many new LV constants, structures, functions.

	* [controls/comctl32undoc.c]
	Rewrote the DSA* functions.

	* [windows/winpos.c]
	SetShellWindow32, GetShellWindow32.

Sat Aug 22 14:02:15 1998  Alexander Lukyanov <lav@long.yar.ru>

	* [loader/resource.c]
	Mark last accelerator as such in LoadAccelerators32W.

	* [relay32/shell32.spec] [misc/shell.c]
	Add stubs for SHGetSpecialFolderPath[AW].

Sat Aug 22 02:07:42 1998  Adrian Harvey <adrian@select.com.au>

	* [include/file.h] [file/file.c] [msdos/int21.c] [msdos/vxd.c]
	  [misc/lzexpand.c] [win32/kernel32.c] [documentation/filehandles]
	Fixed file handle handling.  Created universal HFILE16 to HFILE32
	translation macro from msdos/int21 code by Ove Kaaven.
	Used macro in all Win16 functions so that win32 handles are translated
	to avoid DOS/Win16 stdxx handles.
	Removed handle translation from int21.c where Win16 functions are
	called.  Changed remaining calls to use new macro names.
	Documented filehandle handling and differences between win 16 & 32.

Fri Aug 21 20:32:49 1998  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [server/process.c] [server/thread.c]
	Implemented object wait queues and synchronization.

Fri Aug 21 18:40:02 1998  Huw D M Davies <daviesh@abacus.physics.ox.ac.uk>

	* [graphics/psdrv/*]
	DEVMODE dmPaper{Width|Length} fields are in 0.1mm.
	Select a 100 pixel default font in CreateDC.

Thu Aug 20 22:47:39 1998  Uwe Bonnes  <bon@elektron.ikp.physik.tu-darmstadt.de>

	* [objects/bitmap.c]
	Handle bits=32 in SetBitmapBits32 and GetBitmapBits32.

	* [msdos/int21.c]
	Add handling of Int21 0A and 37.

	* [misc/commdlg.c]
	Use MapHModuleLS and MapHModuleSL when translating HINSTANCE16 to
	HINSTANCE32 and vice versa.

	* [win32/file.c]
	CreateFile32A: Abort if filename == NULL.

Thu Aug 20 12:28:31 1998  Marcus Meissner <marcus@jet.franken.de>

	* [*/*]
	Lots of missing prototypes added, some parameter types adapted to match
	SDK.

	* [debugger/stabs.c]
	Don't loop forever if we don't find wine or one of the libxxx.so.

	* [loader/ne/module.c]
	Implemented MapHModuleLS,MapHModuleSL,MapHinstLS,MapHinstSL.

	* [misc/network.c]
	Implemented WNetGetUser32A.

	* [misc/shellord.c]
	Implemented ILRemoveLastID.

	* [multimedia/dsound.c]
	Fixed StarCraft memory leak.

	* [graphics/ddraw.c]
	Removed some unnecessary simple relaying functions, tried polishing
	up the Xlib implementation (still doesn't work), temp. removed Xshm
	code (to be remerged with working Xlib code).

Tue Aug 18 22:29:17 1998  Ove Kaaven <ovek@arcticnet.no>

	* [multimedia/mmio.c] [multimedia/mmsystem.c]
	Fixed most mmio bugs, fully implementing mmioSetBuffer
	buffering, ability to read memory files, and the
	sndPlaySound() SND_MEMORY flag. Most mmio-using programs
	now work fine.

	* [include/dosexe.h] [include/miscemu.h] [include/module.h]
	  [loader/module.c] [loader/task.c] [msdos/dosmem.c]
	Improved DOS VM flexibility and portability somewhat. (Did
	I get the #ifdefs right this time, BSD-ers?)

	* [msdos/int21.c]
	Made "Get Current PSP address" work as expected in a DOS VM.

	* [loader/dos/*]
	Began improving flexibility and portability somewhat. It
	should be easier to add DPMI RMCB callbacks now. The
	DOS VM no longer leaves big files lying around in /tmp
	after a crash.

Tue Aug 18 12:38:31 1998 Turchanov Sergey <turchanov@usa.net>

	* [relay32/winmm.spec]
	This patch allows WinAmp to play WAV files (at least in PCM
	format).

Sun Aug 16 05:34:13 1998  Pablo Saratxaga <srtxg@chanae.alphanet.ch>

	* [windows/keyboard.c]
	Corrected keyboard code to properly handle keys : ? ~ and "
	on non US keyboards.

Sat Aug 15 18:47:14 1998  Brian Craft <bcboy@dorothy.wanglab.brandeis.edu>

	* [windows/win.c]
	Fixed severe bug in EnumChildWindwos().

Thu Aug 13 21:05:35 1998  Eric Kohl <ekohl@abo.rhein-zeitung.de>

	* [controls/tooltips.c]
	Fixed some bugs. Added subclassing support.

	* [controls/toolbar.c]
	Improved tooltip integration. Fixed some bugs.

	* [controls/commctrl.c]
	Changed control registration and added some documentation.
	Fixed ShowHideMenuCtl.

	* [controls/rebar.c][include/rebar.h][include/commctrl.h]
	Improved rebar implementation (still no display).

	* [controls/pager.c][include/pager.h][include/commctrl.h]
	Improved pager implementation (still no display).

	* [misc/imagelist.c]
	Fixed a bug.

	* [documentation/common_controls]
	Updated.

Sun Aug  9 19:50:20 1998  James Juran <jrj120@psu.edu>

	* [Makefile.in] [documentation/Makefile.in] 
	  [programs/Makefile.in] [programs/*/Makefile.in]
	Added uninstall rules, cleaned up install rules a little bit.

Sun Aug  9 13:21:35 1998  Andreas Mohr <100.30936@germany.net>

	* [loader/ne/module.c] [if1632/kernel.spec]
	Added the undocumented HIWORD of GetModuleHandle (hFirstModule).

	* [loader/ne/segment.c]
	Wine forgot to set some NE_SEGFLAGS_*.
	Combined with another loader change, this fixed the
	"BLINKER -- error in loading module" or ghost MessageBox problem
	that about 1% of all Windows programs have.
	Some BLINKER programs still don't work, though.
	But I'm working on it, with great help from Blinkinc.

	* [loader/task.c]
	InitTask needs to decrement the SP register by two as Win95 does.

Sun Aug  9 02:41:28 1998  Ulrich Weigand <weigand@informatik.uni-erlangen.de>

	* [if1632/kernel.spec] [relay32/kernel32.spec] [scheduler/syslevel.c]
	  [loader/main.c] [win32/ordinals.c] [include/syslevel.h] 
	  [scheduler/Makefile.in]
	Implemented Win95 'syslevel' routines (including Win16Lock).

	* [if1632/relay.c] [if1632/thunk.c] [tools/build.c] [loader/task.c]
	  [loader/ne/segment.c] [win32/kernel32.c] [memory/selector.c]
	  [include/stackframe.h] [include/thread.h]
	16-bit %fs handling revised.  Use Win16Lock where appropriate.

	* [include/thread.h] [scheduler/synchro.c] [windows/message.c] 
	  [windows/queue.c] [win32/process.c]
	Implemented MsgWaitForMultipleObjects.

	* [files/change.c] [files/Makefile.in] [scheduler/k32obj.c] 
	  [win32/newfns.c]
	Implemented (dummy) file change notification objects.

	* [debugger/dbg.y] [scheduler/process.c] [scheduler/thread.c]
	  [include/process.h] [include/thread.h]
	Suspend all threads except current when hitting debugger break point.

	* [objects/dib.c]
	Bugfix for CreateDIBSection.
diff --git a/ANNOUNCE b/ANNOUNCE
index 303c5bd..5c0bea1 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,16 +1,15 @@
-This is release 980809 of Wine, the MS Windows emulator.  This is still a
+This is release 980822 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-980809: (see ChangeLog for details)
-	- Preliminary DOS executables support.
-	- Postscript driver improvements.
-	- More client/server stuff.
-	- Better shell32.dll builtin support.
-	- Proper Win16 mutex locking.
+WHAT'S NEW with Wine-980822: (see ChangeLog for details)
+	- Improved mmio support.
+	- VxDCall support.
+	- More common controls and shell32 stuff.
+	- Better DOS executables support.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -19,10 +18,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-980809.tar.gz
-  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-980809.tar.gz
-  ftp://ftp.infomagic.com/pub/mirrors/linux/sunsite/ALPHA/wine/development/Wine-980809.tar.gz
-  ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-980809.tar.gz
+  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-980822.tar.gz
+  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-980822.tar.gz
+  ftp://ftp.infomagic.com/pub/mirrors/linux/sunsite/ALPHA/wine/development/Wine-980822.tar.gz
+  ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-980822.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/ChangeLog b/ChangeLog
index bd9cb45..b6e4c54 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,213 @@
 ----------------------------------------------------------------------
+Sat Aug 22 17:46:19 1998  Ulrich Weigand <weigand@informatik.uni-erlangen.de>
+
+	* [include/dosexe.h] [include/module.h] [include/pe_image.h] 
+	  [include/process.h] [include/windows.h] [loader/dos/module.c]
+	  [loader/module.c] [loader/ne/module.c] [loader/pe_image.c]
+	  [scheduler/process.c] [win32/process.c]
+	Partially implemented CreateProcess32.
+
+	* [win32/device.c] [relay32/kernel32.spec] [scheduler/k32obj.c]
+	  [misc/registry.c] [win32/file.c]
+	Partially implemented VxDCall (VMM registry services).
+
+	* [files/dos_fs.c]
+	DOSFS_FindNext made thread-safe.
+
+	* [include/sig_context.h] [include/syslevel.h] [loader/signal.c]
+	  [scheduler/syslevel.c] [tools/build.c]
+	Replaced CALLTO16_Current_fs by SYSLEVEL_Win16CurrentTeb.
+
+	* [win32/kernel32.c]
+	Bugfix: QT_Thunk/FT_Thunk should return 'long' in DX:AX, not EAX.
+
+	* [if1632/relay.c] [relay32/builtin32.c] [windows/msgbox.c]
+	  [msdos/int20.c] [msdos/int21.c]
+	Use ExitProcess instead of TASK_KillCurrentTask.
+
+	* [include/task.h] [include/thread.h] [loader/task.c] 
+	  [scheduler/thread.c] [include/queue.h] [windows/message.c] 
+	  [windows/queue.c] [windows/win.c]
+	Prevent Win32 threads from entering the TASK_Reschedule loop.
+	(Note: Win32 messaging still doesn't work correctly; this patch
+	is just preventing the system from crashing when Win32 threads
+	call messaging functions. Messages will probably still get lost.)
+
+	* [scheduler/critsection.c]
+	Deactivated the use of SEM_UNDO for the SYSTEM_LOCK semaphore;
+	for some reason, this leads to problems after threads terminate... 
+
+Sat Aug 22 15:00:00 1998  Jürgen Schmied <juergen.schmied@metronet.de>
+
+	* [include/authors.h]
+	New file, includes all names of the developer (former shell.c)
+
+	* [Makefile.in][configure][configure.in][dlls/Makefile.in]
+	  [dlls/shell32/Makefile.in][shres.rc]
+	Created dlls/shell32 and moved the shell32 stuff in it.
+	Started to create internal resources.
+
+	* [dlls/shell32/*]
+	Split the shell32 implementation into smaller files.
+	New classes: IContextMenu, IExtractIcon, IShellView.
+	Implemented Shell_GetImageList().
+	shell32 links to comctl32 now dynamically so it can use
+	internal/external implementations.
+
+	* [documentation/internal-dll] [documentation/shell32]
+	New, could anybody do a spellcheck?
+
+	* [include/commctrl.h]
+	Many new LV constants, structures, functions.
+
+	* [controls/comctl32undoc.c]
+	Rewrote the DSA* functions.
+
+	* [windows/winpos.c]
+	SetShellWindow32, GetShellWindow32.
+
+Sat Aug 22 14:02:15 1998  Alexander Lukyanov <lav@long.yar.ru>
+
+	* [loader/resource.c]
+	Mark last accelerator as such in LoadAccelerators32W.
+
+	* [relay32/shell32.spec] [misc/shell.c]
+	Add stubs for SHGetSpecialFolderPath[AW].
+
+Sat Aug 22 02:07:42 1998  Adrian Harvey <adrian@select.com.au>
+
+	* [include/file.h] [file/file.c] [msdos/int21.c] [msdos/vxd.c]
+	  [misc/lzexpand.c] [win32/kernel32.c] [documentation/filehandles]
+	Fixed file handle handling.  Created universal HFILE16 to HFILE32
+	translation macro from msdos/int21 code by Ove Kaaven.
+	Used macro in all Win16 functions so that win32 handles are translated
+	to avoid DOS/Win16 stdxx handles.
+	Removed handle translation from int21.c where Win16 functions are
+	called.  Changed remaining calls to use new macro names.
+	Documented filehandle handling and differences between win 16 & 32.
+
+Fri Aug 21 20:32:49 1998  Alexandre Julliard  <julliard@lrc.epfl.ch>
+
+	* [server/process.c] [server/thread.c]
+	Implemented object wait queues and synchronization.
+
+Fri Aug 21 18:40:02 1998  Huw D M Davies <daviesh@abacus.physics.ox.ac.uk>
+
+	* [graphics/psdrv/*]
+	DEVMODE dmPaper{Width|Length} fields are in 0.1mm.
+	Select a 100 pixel default font in CreateDC.
+
+Thu Aug 20 22:47:39 1998  Uwe Bonnes  <bon@elektron.ikp.physik.tu-darmstadt.de>
+
+	* [objects/bitmap.c]
+	Handle bits=32 in SetBitmapBits32 and GetBitmapBits32.
+
+	* [msdos/int21.c]
+	Add handling of Int21 0A and 37.
+
+	* [misc/commdlg.c]
+	Use MapHModuleLS and MapHModuleSL when translating HINSTANCE16 to
+	HINSTANCE32 and vice versa.
+
+	* [win32/file.c]
+	CreateFile32A: Abort if filename == NULL.
+
+Thu Aug 20 12:28:31 1998  Marcus Meissner <marcus@jet.franken.de>
+
+	* [*/*]
+	Lots of missing prototypes added, some parameter types adapted to match
+	SDK.
+
+	* [debugger/stabs.c]
+	Don't loop forever if we don't find wine or one of the libxxx.so.
+
+	* [loader/ne/module.c]
+	Implemented MapHModuleLS,MapHModuleSL,MapHinstLS,MapHinstSL.
+
+	* [misc/network.c]
+	Implemented WNetGetUser32A.
+
+	* [misc/shellord.c]
+	Implemented ILRemoveLastID.
+
+	* [multimedia/dsound.c]
+	Fixed StarCraft memory leak.
+
+	* [graphics/ddraw.c]
+	Removed some unnecessary simple relaying functions, tried polishing
+	up the Xlib implementation (still doesn't work), temp. removed Xshm
+	code (to be remerged with working Xlib code).
+
+Tue Aug 18 22:29:17 1998  Ove Kaaven <ovek@arcticnet.no>
+
+	* [multimedia/mmio.c] [multimedia/mmsystem.c]
+	Fixed most mmio bugs, fully implementing mmioSetBuffer
+	buffering, ability to read memory files, and the
+	sndPlaySound() SND_MEMORY flag. Most mmio-using programs
+	now work fine.
+
+	* [include/dosexe.h] [include/miscemu.h] [include/module.h]
+	  [loader/module.c] [loader/task.c] [msdos/dosmem.c]
+	Improved DOS VM flexibility and portability somewhat. (Did
+	I get the #ifdefs right this time, BSD-ers?)
+
+	* [msdos/int21.c]
+	Made "Get Current PSP address" work as expected in a DOS VM.
+
+	* [loader/dos/*]
+	Began improving flexibility and portability somewhat. It
+	should be easier to add DPMI RMCB callbacks now. The
+	DOS VM no longer leaves big files lying around in /tmp
+	after a crash.
+
+Tue Aug 18 12:38:31 1998 Turchanov Sergey <turchanov@usa.net>
+
+	* [relay32/winmm.spec]
+	This patch allows WinAmp to play WAV files (at least in PCM
+	format).
+
+Sun Aug 16 05:34:13 1998  Pablo Saratxaga <srtxg@chanae.alphanet.ch>
+
+	* [windows/keyboard.c]
+	Corrected keyboard code to properly handle keys : ? ~ and "
+	on non US keyboards.
+
+Sat Aug 15 18:47:14 1998  Brian Craft <bcboy@dorothy.wanglab.brandeis.edu>
+
+	* [windows/win.c]
+	Fixed severe bug in EnumChildWindwos().
+
+Thu Aug 13 21:05:35 1998  Eric Kohl <ekohl@abo.rhein-zeitung.de>
+
+	* [controls/tooltips.c]
+	Fixed some bugs. Added subclassing support.
+
+	* [controls/toolbar.c]
+	Improved tooltip integration. Fixed some bugs.
+
+	* [controls/commctrl.c]
+	Changed control registration and added some documentation.
+	Fixed ShowHideMenuCtl.
+
+	* [controls/rebar.c][include/rebar.h][include/commctrl.h]
+	Improved rebar implementation (still no display).
+
+	* [controls/pager.c][include/pager.h][include/commctrl.h]
+	Improved pager implementation (still no display).
+
+	* [misc/imagelist.c]
+	Fixed a bug.
+
+	* [documentation/common_controls]
+	Updated.
+
+Sun Aug  9 19:50:20 1998  James Juran <jrj120@psu.edu>
+
+	* [Makefile.in] [documentation/Makefile.in] 
+	  [programs/Makefile.in] [programs/*/Makefile.in]
+	Added uninstall rules, cleaned up install rules a little bit.
+
+----------------------------------------------------------------------
 Sun Aug  9 13:21:35 1998  Andreas Mohr <100.30936@germany.net>
 
 	* [loader/ne/module.c] [if1632/kernel.spec]
@@ -15,6 +224,33 @@
 	* [loader/task.c]
 	InitTask needs to decrement the SP register by two as Win95 does.
 
+Sun Aug  9 02:41:28 1998  Ulrich Weigand <weigand@informatik.uni-erlangen.de>
+
+	* [if1632/kernel.spec] [relay32/kernel32.spec] [scheduler/syslevel.c]
+	  [loader/main.c] [win32/ordinals.c] [include/syslevel.h] 
+	  [scheduler/Makefile.in]
+	Implemented Win95 'syslevel' routines (including Win16Lock).
+
+	* [if1632/relay.c] [if1632/thunk.c] [tools/build.c] [loader/task.c]
+	  [loader/ne/segment.c] [win32/kernel32.c] [memory/selector.c]
+	  [include/stackframe.h] [include/thread.h]
+	16-bit %fs handling revised.  Use Win16Lock where appropriate.
+
+	* [include/thread.h] [scheduler/synchro.c] [windows/message.c] 
+	  [windows/queue.c] [win32/process.c]
+	Implemented MsgWaitForMultipleObjects.
+
+	* [files/change.c] [files/Makefile.in] [scheduler/k32obj.c] 
+	  [win32/newfns.c]
+	Implemented (dummy) file change notification objects.
+
+	* [debugger/dbg.y] [scheduler/process.c] [scheduler/thread.c]
+	  [include/process.h] [include/thread.h]
+	Suspend all threads except current when hitting debugger break point.
+
+	* [objects/dib.c]
+	Bugfix for CreateDIBSection.
+
 Sat Aug  8 19:11:46 1998  Marcus Meissner <marcus@jet.franken.de>
 
  	* [*/*]
diff --git a/Makefile.in b/Makefile.in
index 52a3b6a..3f88e15 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -5,6 +5,7 @@
 # clean:		remove all intermediate files
 # distclean:		also remove all files created by configure
 # install:              install everything
+# uninstall:		uninstall everything
 # depend:		create the dependencies
 # etags:		create a TAGS file for Emacs.
 # manpages:		compile manpages for Wine API
@@ -26,6 +27,7 @@
 	tools \
 	tools/wrc \
 	controls \
+	dlls/shell32 \
 	files \
 	graphics \
 	graphics/metafiledrv \
@@ -75,6 +77,7 @@
 
 LIBOBJS = \
 	controls/controls.o \
+	dlls/shell32/shell32.o \
 	files/files.o \
 	graphics/graphics.o \
 	graphics/metafiledrv/metafiledrv.o \
@@ -112,6 +115,8 @@
 
 install:: install_$(MAIN_TARGET)
 
+uninstall:: uninstall_$(MAIN_TARGET)
+
 emu: wine
 
 lib: $(LIBSUBDIRS) $(LIB_TARGET)
@@ -129,28 +134,47 @@
 	$(CC) -shared -Wl,-soname,libwine.so -o$@ $(LIBOBJS) $(LDOPTIONS) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS)
 
 install_emu: install_lib
-	-mkdirhier $(bindir)
-	-mkdirhier $(libdir)
+	[ -d $(bindir) ] || $(MKDIR) $(bindir)
 	$(INSTALL_PROGRAM) wine $(bindir)/wine
-	$(INSTALL_DATA) wine.sym $(libdir)/wine.sym
 	$(INSTALL_PROGRAM) loader/dos/dosmod $(bindir)/dosmod
 
+uninstall_emu: uninstall_lib
+	$(RM) $(bindir)/wine $(bindir)/dosmod
+
 install_lib: install_includes
+	[ -d $(libdir) ] || $(MKDIR) $(libdir)
 	$(INSTALL_DATA) $(LIB_TARGET) $(libdir)
+	$(INSTALL_DATA) wine.sym $(libdir)/wine.sym
+
+uninstall_lib: uninstall_includes
+	cd $(libdir); $(RM) $(LIB_TARGET)
+	$(RM) $(libdir)/wine.sym
 
 install_includes: dummy
-	if [ -d $(includedir) ]; then : ; else $(MKDIR) $(includedir); fi 
+	[ -d $(includedir) ] || $(MKDIR) $(includedir)
 	cd $(TOPSRCDIR)/include; $(INSTALL_DATA) windows.h wintypes.h $(includedir)
 
+# Don't just do a rm -rf on $(includedir) -- don't want to wipe out 
+# anything extra the user may have put there.
+uninstall_includes: dummy
+	$(RM) $(includedir)/windows.h $(includedir)/wintypes.h
+	-rmdir $(includedir)
+
 $(ALLSUBDIRS): dummy
 	@cd $@; $(SUBMAKE)
 
 install_programs: dummy
 	@cd programs; $(SUBMAKE) install
 
+uninstall_programs: dummy
+	@cd programs; $(SUBMAKE) uninstall
+
 install::
 	for i in $(INSTALLSUBDIRS); do (cd $$i && $(MAKE) install) || exit 1; done
 
+uninstall::
+	for i in $(INSTALLSUBDIRS); do (cd $$i && $(MAKE) uninstall) || exit 1; done
+
 depend:: dummy
 	for i in $(DEPENDSUBDIRS); do (cd $$i && $(MAKE) depend) || exit 1; done
 
diff --git a/configure b/configure
index 840938e..4c6f44c 100755
--- a/configure
+++ b/configure
@@ -3396,6 +3396,8 @@
 Makefile
 controls/Makefile
 debugger/Makefile
+dlls/Makefile
+dlls/shell32/Makefile
 documentation/Makefile
 files/Makefile
 graphics/Makefile
@@ -3531,6 +3533,8 @@
 Makefile
 controls/Makefile
 debugger/Makefile
+dlls/Makefile
+dlls/shell32/Makefile
 documentation/Makefile
 files/Makefile
 graphics/Makefile
diff --git a/configure.in b/configure.in
index 19731df..cf1d414 100644
--- a/configure.in
+++ b/configure.in
@@ -460,6 +460,8 @@
 Makefile
 controls/Makefile
 debugger/Makefile
+dlls/Makefile
+dlls/shell32/Makefile
 documentation/Makefile
 files/Makefile
 graphics/Makefile
diff --git a/controls/comctl32undoc.c b/controls/comctl32undoc.c
index 7027960..aa5c83d 100644
--- a/controls/comctl32undoc.c
+++ b/controls/comctl32undoc.c
@@ -2,7 +2,7 @@
  * Undocumented functions from COMCTL32.DLL
  *
  * Copyright 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de>
- *
+ *           1998 Juergen Schmied <j.schmied@metronet.de>
  * NOTES
  *     All of these functions are UNDOCUMENTED!! And I mean UNDOCUMENTED!!!!
  *     Do NOT rely on names or contents of undocumented structures and types!!!
@@ -22,17 +22,6 @@
 #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;
@@ -47,22 +36,30 @@
 DWORD WINAPI DPA_InsertPtr (DWORD, DWORD, DWORD);
 
 
-
-
+CRITICAL_SECTION cs_comctl_alloc;
+HANDLE32 hComctl32Heap=0;
 /**************************************************************************
  * Alloc [COMCTL32.71]
  *
  */
 
-LPVOID WINAPI
-COMCTL32_Alloc (DWORD dwParam)
-{
-    LPVOID lpPtr;
+LPVOID WINAPI COMCTL32_Alloc (DWORD dwParam)
+{   LPVOID lpPtr;
 
-    lpPtr = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, dwParam);
+    TRACE (commctrl, "(0x%08lx)\n", dwParam);
 
-    TRACE (commctrl, "(0x%08lx) ret=0x%08lx\n", dwParam, (DWORD)lpPtr);
+	if (hComctl32Heap==0)
+	{ EnterCriticalSection((void*)&cs_comctl_alloc);
+      hComctl32Heap=HeapCreate(0,1,0x4000000);
+      LeaveCriticalSection((void*)&cs_comctl_alloc);
+      TRACE (commctrl, "Heap created: 0x%08x\n", hComctl32Heap);
+      if (! hComctl32Heap)
+        return FALSE;        
+	}
 
+//    lpPtr = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, dwParam);
+    lpPtr = HeapAlloc (hComctl32Heap, HEAP_ZERO_MEMORY, dwParam);
+    TRACE (commctrl, "-- ret=%p\n", lpPtr);
     return lpPtr;
 }
 
@@ -76,16 +73,16 @@
 COMCTL32_ReAlloc (LPVOID dwParam1, DWORD dwParam2)
 {
     LPVOID dwPtr;
-
+    TRACE (commctrl, "(0x%08lx 0x%08lx)\n",(DWORD)dwParam1, dwParam2);
+    
     if (dwParam1 == 0)
-	dwPtr = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
+	dwPtr = HeapAlloc (hComctl32Heap, HEAP_ZERO_MEMORY,
 			   dwParam2);
     else
-	dwPtr = HeapReAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
+	dwPtr = HeapReAlloc (hComctl32Heap, HEAP_ZERO_MEMORY,
 			     dwParam1, dwParam2);
 
-    TRACE (commctrl, "(0x%08lx 0x%08lx) ret=0x%08lx\n",
-	   (DWORD)dwParam1, dwParam2, (DWORD)dwPtr);
+    TRACE (commctrl, "-- ret=0x%08lx\n", (DWORD)dwPtr);
 
     return dwPtr;
 }
@@ -100,7 +97,7 @@
 COMCTL32_Free (LPVOID dwParam)
 {
     TRACE (commctrl, "(0x%08lx)\n", (DWORD)dwParam);
-    HeapFree (GetProcessHeap (), 0, dwParam);
+    HeapFree (hComctl32Heap, 0, dwParam);
 
     return 0;
 }
@@ -115,7 +112,7 @@
 COMCTL32_GetSize (LPVOID dwParam)
 {
     TRACE (commctrl, "(0x%08lx)\n", (DWORD)dwParam);
-    return (HeapSize (GetProcessHeap (), 0, dwParam));
+    return (HeapSize (hComctl32Heap, 0, dwParam));
 }
 
 
@@ -155,217 +152,283 @@
     return FALSE;
 }
 
-
+/*************************************************************************
+* The DSA-API is a set of functions to create and manipulate arrays of
+* fix sized memory blocks. This arrays can store any kind of data (strings,
+* icons...) so the name "dynamic string array" is a bit misleading.
+*
+* STATUS 
+*  complete
+*/
+typedef struct _DSA_DATA
+{   DWORD   dwEntryCount;
+    BYTE    * pData;
+    DWORD   dwMaxCount;
+    DWORD   dwElementSize;
+    DWORD   dwGrow;
+} DSA_DATA, *LPDSA_DATA;
 
 /**************************************************************************
  * DSA_Create [COMCTL32.320] Creates a dynamic string array
  *
  * PARAMS
- *     dwParam1 [I]
- *     dwParam2 [I]
+ *     dwSize [I] size of the array elements
+ *     dwGrow [I] 
+ * RETURNS
+ *     pointer to a array control structure. use this like a handle.
  */
 
-DWORD WINAPI
-DSA_Create (DWORD dwParam1, DWORD dwParam2)
-{
-    LPDSA_DATA dsaPtr;
+LPDSA_DATA WINAPI DSA_Create (DWORD dwSize, DWORD dwGrow)
+{   LPDSA_DATA dsaPtr;
 
-    dsaPtr = (LPDSA_DATA)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-				    sizeof(DSA_DATA));
-    dsaPtr->dwInitial = dwParam1;
-    dsaPtr->dwGrow = dwParam2;
+    TRACE (commctrl, "(size=0x%08lx grow=0x%08lx)\n", dwSize, dwGrow);
 
-    TRACE (commctrl, "(0x%08lx 0x%08lx) ret=0x%08lx\n",
-	   dwParam1, dwParam2, (DWORD)dsaPtr);
-
-    return (DWORD)dsaPtr;
+    if ((dsaPtr=(LPDSA_DATA)COMCTL32_Alloc(sizeof(DSA_DATA))));
+    {  dsaPtr->dwEntryCount=0x00;
+       dsaPtr->pData=NULL;
+       dsaPtr->dwMaxCount=0x00;
+       dsaPtr->dwElementSize=dwSize;
+       if ( dwGrow == 0 )
+         dsaPtr->dwGrow=1;
+       else
+         dsaPtr->dwGrow=dwGrow;
+       return dsaPtr;
+    }
+    return FALSE;   
 }
 
-
 /**************************************************************************
  * DSA_Destroy [COMCTL32.321] Destroys a dynamic string array
  *
  * PARAMS
- *     dwParam1 [I]
+ *     dsaPtr [I] pointer to the array control structure
+ * RETURNS
+ *  TRUE if dsaPtr = NULL or success
+ *  FALSE if failure
  */
 
-DWORD WINAPI
-DSA_Destroy (DWORD dwParam1)
-{
-    LPDSA_DATA dsaPtr = (LPDSA_DATA)dwParam1;
-    DWORD i;
+BOOL32 WINAPI DSA_Destroy (const LPDSA_DATA dsaPtr )
+{   TRACE (commctrl, "(%p)\n", dsaPtr);
 
-    TRACE (commctrl, "(0x%08lx):semi-stub!\n", dwParam1);
+	if (! dsaPtr)
+      return FALSE;
 
-    if (dsaPtr->ptrs) {
-	for (i = 0; i < dsaPtr->dwEntryCount; i++) {
-	    if (dsaPtr->ptrs[i])
-		HeapFree (GetProcessHeap (), 0, (LPSTR)dsaPtr->ptrs[i]);
-	}
+    if (dsaPtr->pData && (! COMCTL32_Free(dsaPtr->pData)))
+    { return FALSE;
     }
-
-    HeapFree (GetProcessHeap (), 0, dsaPtr);
-
-    return 0;
+    return COMCTL32_Free (dsaPtr);
 }
 
+/**************************************************************************
+ * DSA_GetItem [COMCTL32.322] 
+ *
+ * PARAMS
+ *  dsaPtr [I] pointer to the array control structure
+ *  dwItem [I] number of the Item to get
++ *  pDest  [O] destination buffer. Has to be >= dwElementSize.
+ */
 
-DWORD WINAPI
-DSA_GetItem (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
-{
-    LPDSA_DATA dsaPtr = (LPDSA_DATA)dwParam1;
+BOOL32 WINAPI DSA_GetItem (const LPDSA_DATA dsaPtr, DWORD dwItem, LPBYTE pDest)
+{   BYTE * pSrc;
 
-    FIXME (commctrl, "(0x%08lx 0x%08lx 0x%08lx): stub!\n",
-	   dwParam1, dwParam2, dwParam3);
-
-    if (dsaPtr == NULL)
-	return 0;
-    if (dsaPtr->ptrs == NULL)
-	return 0;
-    if ((dwParam2 < 0) || (dwParam2 >= dsaPtr->dwEntryCount))
-	return 0;
-
-//    FIXME (commctrl, "\"%s\"\n", (LPSTR)dsaPtr->ptrs[dwParam2]);
-
-    return (DWORD)lstrcpy32A ((LPSTR)dwParam3, (LPSTR)dsaPtr->ptrs[dwParam2]);
+    TRACE (commctrl, "(%p 0x%08lx %p)\n", dsaPtr, dwItem, pDest);
+    
+    if ( (!dsaPtr) || (dwItem < 0) || (dwItem >= dsaPtr->dwEntryCount))
+      return FALSE;
+    
+    pSrc = dsaPtr->pData + (dsaPtr->dwElementSize * dwItem);
+    memmove(pDest,pSrc,dsaPtr->dwElementSize);
+    return TRUE;
 }
 
+/**************************************************************************
+ * DSA_GetItemPtr [COMCTL32.323] 
+ *
+ * PARAMS
+ *  dsaPtr [I] pointer to the array control structure
+ *  dwItem [I] number of the Item to get
+ * RETURNS
+ *  pointer ti a item 
+ */
+LPBYTE WINAPI DSA_GetItemPtr (const LPDSA_DATA dsaPtr, DWORD dwItem)
+{   BYTE * pSrc;
 
-DWORD WINAPI
-DSA_GetItemPtr (DWORD dwParam1, DWORD dwParam2)
-{
-    LPDSA_DATA dsaPtr = (LPDSA_DATA)dwParam1;
+	TRACE (commctrl, "(%p 0x%08lx)\n", dsaPtr, dwItem);
 
-    TRACE (commctrl, "(0x%08lx 0x%08lx)\n", dwParam1, dwParam2);
+    if ((!dsaPtr) || (dwItem < 0) || (dwItem >= dsaPtr->dwEntryCount))
+	  return FALSE;
+    pSrc = dsaPtr->pData + (dsaPtr->dwElementSize * dwItem);
+    
+    TRACE (commctrl, "-- ret=%p\n", pSrc);
 
-    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];
+    return  pSrc;
 }
 
+/**************************************************************************
+ * DSA_SetItem [COMCTL32.325] 
+ *
+ * PARAMS
+ *  dsaPtr [I] pointer to the array control structure
+ *  dwItem [I] index for the new element
+ *  pSrc   [I] the element
+ */
+BOOL32 WINAPI DSA_SetItem (const LPDSA_DATA dsaPtr, DWORD dwItem, LPBYTE pSrc)
+{   LPBYTE pDest;
+ 	DWORD  dwSize, dwNewItems;
+	LPBYTE lpTemp;
+    
+    TRACE (commctrl, "(%p 0x%08lx %p)\n", dsaPtr, dwItem, pSrc);
 
-DWORD WINAPI
-DSA_InsertItem (DWORD dwParam1, DWORD dwParam2, LPSTR lpString)
-{
-    LPDSA_DATA dsaPtr = (LPDSA_DATA)dwParam1;
-    DWORD dwIndex;
-    INT32 len;
-
-    TRACE (commctrl, "(0x%08lx 0x%08lx \"%s\"):semi-stub!\n",
-	   dwParam1, dwParam2, lpString);
-
-    if (dsaPtr->ptrs == NULL) {
-	dsaPtr->ptrs = (LPSTR*)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-					  dsaPtr->dwInitial * sizeof(LPVOID));
-	dsaPtr->dwMaxCount = dsaPtr->dwInitial;
-        dwIndex = 0;
-	len = lstrlen32A (lpString);
-	dsaPtr->ptrs[dwIndex] =
-	    (LPSTR)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len+1);
-	lstrcpy32A (dsaPtr->ptrs[dwIndex], lpString);
+	if ((!dsaPtr) || dwItem<0 )
+      return FALSE;
+      
+    if (dsaPtr->dwEntryCount <= dwItem)	/* within the old array */
+    { if ( dsaPtr->dwMaxCount > dwItem) 
+      { dsaPtr->dwEntryCount = dwItem; /* within the allocated space, set a new boundary */
+      }
+      else
+      { /* resize the block of memory*/
+        dwNewItems = dsaPtr->dwGrow * ( (WORD)((dwItem-1)/dsaPtr->dwGrow) +1);
+        dwSize = dsaPtr->dwElementSize * dwNewItems;
+        lpTemp = (LPBYTE) COMCTL32_ReAlloc(dsaPtr->pData,dwSize);
+        if (! lpTemp )
+        { return FALSE;
+        }
+        dsaPtr->dwMaxCount = dwNewItems;
+        dsaPtr->pData = lpTemp;        
+      }    
     }
-    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 (lpString);
-		dsaPtr->ptrs[dwIndex] =
-		    (LPSTR)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len+1);
-		lstrcpy32A (dsaPtr->ptrs[dwIndex], lpString);
-	    }
-	    else {
-		/* allocate new pointer list and copy all pointers */
-		LPSTR *lpOldPtrs = dsaPtr->ptrs;
-		dsaPtr->ptrs = (LPSTR*)HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
-				(dsaPtr->dwInitial + dsaPtr->dwGrow) *
-				sizeof(LPVOID));
-		memcpy (dsaPtr->ptrs, lpOldPtrs,
-			dsaPtr->dwMaxCount * sizeof(LPVOID));
-		dsaPtr->dwMaxCount += dsaPtr->dwGrow;
-		HeapFree (GetProcessHeap (), 0, lpOldPtrs);
+	/* put the new entry in */
+	pDest = dsaPtr->pData +  (dsaPtr->dwElementSize * dwItem);
+    TRACE (commctrl,"move dest=%p src=%p size=%x",pDest,pSrc,dsaPtr->dwElementSize);
+	memmove(pDest,pSrc,dsaPtr->dwElementSize);
+    return TRUE;
+}
 
-		/* add new string */
-		dwIndex = dsaPtr->dwEntryCount;
-		len = lstrlen32A (lpString);
-		dsaPtr->ptrs[dwIndex] =
-		    (LPSTR)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len+1);
-		lstrcpy32A (dsaPtr->ptrs[dwIndex], lpString);
-	    }
-	}
-	else {
-	    FIXME (commctrl, "inserting! stub!\n");
+/**************************************************************************
+ * DSA_InsertItem [COMCTL32.325] 
+ *
+ * PARAMS
+ *  dsaPtr [I] pointer to the array control structure
+ *  dwItem [I] index for the new element
+ *  pSrc   [I] the element
+ *
+ * RETURNS
+ *  the position of the new element
+ */
+DWORD WINAPI DSA_InsertItem (const LPDSA_DATA dsaPtr, DWORD dwItem, LPBYTE pSrc)
+{	DWORD dwNewItems, dwSize,i;
+	LPBYTE lpTemp, lpDest;
+    LPDWORD p;
+    
+	TRACE(commctrl, "(%p 0x%08lx %p)\n", dsaPtr, dwItem, pSrc);
 
-	    dwIndex = dwParam2;
-	}
+	if ( (!dsaPtr) || dwItem<0 )
+      return -1;
+
+	for (i=0; i<dsaPtr->dwElementSize;i+=4)
+    { p = *(DWORD**)(pSrc+i);
+      if ( IsBadStringPtr32A ((char*)p,256))
+      { TRACE(commctrl,"-- 0x%04lx=%p\n",i,(DWORD*)p);
+      }
+      else
+      { TRACE(commctrl,"-- 0x%04lx=%p [%s]\n",i,p,debugstr_a((char*)p));
+      }
+    }
+    
+    if (dwItem > dsaPtr->dwEntryCount)		/* when dwItem > dwEntryCount then append*/
+      dwItem = dsaPtr->dwEntryCount+1;
+    
+    if (dwItem >= dsaPtr->dwMaxCount)		/* do we need to resize ? */
+    { dwNewItems = dsaPtr->dwMaxCount + dsaPtr->dwGrow;
+      dwSize = dsaPtr->dwElementSize * dwNewItems;
+	  lpTemp = (LPBYTE)COMCTL32_ReAlloc(dsaPtr->pData,dwSize);
+      if (!lpTemp)
+      { return -1;
+      }
+      dsaPtr->dwMaxCount = dwNewItems;
+      dsaPtr->pData = lpTemp;         
     }
 
+    if (dwItem < dsaPtr->dwEntryCount)		/* do we need to move elements ?*/
+	{ lpTemp = dsaPtr->pData + (dsaPtr->dwElementSize * dwItem);
+      lpDest = lpTemp + dsaPtr->dwElementSize;
+      TRACE (commctrl,"-- move dest=%p src=%p size=%x\n",lpDest,lpTemp,dsaPtr->dwElementSize);
+      memmove (lpDest,lpTemp,dsaPtr->dwElementSize);
+    } 
+    /* ok, we can put the new Item in*/
     dsaPtr->dwEntryCount++;
-
-    TRACE (commctrl, "ret=0x%08lx\n", dwIndex);
-
-    return (dwIndex);
+    lpDest = dsaPtr->pData + (dsaPtr->dwElementSize * dwItem);
+    TRACE (commctrl,"-- move dest=%p src=%p size=%x\n",lpDest,pSrc,dsaPtr->dwElementSize);
+	memmove (lpDest,pSrc,dsaPtr->dwElementSize);
+	return dsaPtr->dwEntryCount;
 }
+/**************************************************************************
+ * DSA_DeleteItem [COMCTL32.326] 
+ *
+ * PARAMS
+ *  dsaPtr [I] pointer to the array control structure
+ *  dwItem [I] index for the element to delete
+ * RETURNS
+ *  number of the element deleted
+ */
+DWORD WINAPI DSA_DeleteItem (const LPDSA_DATA dsaPtr, DWORD dwItem)
+{	LPBYTE	lpDest,lpSrc;
+	DWORD	dwSize;
+    
+    TRACE (commctrl, "(%p 0x%08lx)\n", dsaPtr, dwItem);
 
+	if ( (! dsaPtr) || dwItem<0 || dwItem>=dsaPtr->dwEntryCount)
+      return FALSE;
 
-
-
-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 (GetProcessHeap (), 0, dsaPtr->ptrs[dwParam2]);
-	    dsaPtr->dwEntryCount--;
+    if ( dwItem < dsaPtr->dwEntryCount-1 )	/* do we need to move ?*/
+	{ lpDest = dsaPtr->pData + (dsaPtr->dwElementSize * dwItem);
+      lpSrc = lpDest + dsaPtr->dwElementSize;
+      dwSize = dsaPtr->dwElementSize * (dsaPtr->dwEntryCount-dwItem-1);
+      TRACE (commctrl,"-- move dest=%p src=%p size=%x\n",lpDest,lpSrc,dwSize);
+      memmove (lpDest,lpSrc,dwSize);
 	}
-	else {
-	    LPSTR *oldPtrs = dsaPtr->ptrs;
-	    TRACE (commctrl, "complex delete!\n");
+    
+    dsaPtr->dwEntryCount--;
+    
+    if ( (dsaPtr->dwMaxCount-dsaPtr->dwEntryCount) >= dsaPtr->dwGrow) /* free memory ?*/
+    { dwSize = dsaPtr->dwElementSize * dsaPtr->dwEntryCount;
+      lpDest = (LPBYTE) COMCTL32_ReAlloc(dsaPtr->pData,dwSize);
+      if (!lpDest)
+      { return FALSE;
+      }
+      dsaPtr->dwMaxCount = dsaPtr->dwEntryCount;
+      dsaPtr->pData = lpDest;         
 
-	    if (dsaPtr->ptrs[dwParam2])
-		HeapFree (GetProcessHeap (), 0, dsaPtr->ptrs[dwParam2]);
-
-	    dsaPtr->dwEntryCount--;
-	    dsaPtr->ptrs = 
-		(LPSTR*)HeapAlloc (GetProcessHeap (), 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 (GetProcessHeap (), 0, oldPtrs);
-	}
-
-	if (dsaPtr->dwEntryCount == 0) {
-	    HeapFree (GetProcessHeap (), 0, dsaPtr->ptrs);
-	    dsaPtr->ptrs = NULL;
-	}
     }
-
-    return 0;
+    return dwItem;
 }
 
+/**************************************************************************
+ * DSA_DeleteAllItems [COMCTL32.326] 
+ *  deletes all elements and initializes array
+ *
+ * PARAMS
+ *  dsaPtr [I] pointer to the array control structure
+ *
+ * RETURNS
+ *  TRUE/FALSE
+ */
+BOOL32 WINAPI DSA_DeleteAllItems (const LPDSA_DATA dsaPtr)
+{   TRACE (commctrl, "(%p)\n", dsaPtr);
 
+	if (! dsaPtr) 
+      return FALSE;
 
+    if (dsaPtr->pData && (! COMCTL32_Free(dsaPtr->pData)))
+    { return FALSE;
+    }
+	dsaPtr->dwEntryCount=0x00;
+    dsaPtr->pData=NULL;
+    dsaPtr->dwMaxCount=0x00;
+    return TRUE;
+}
+/**************************************************************************/
 
 
 DWORD WINAPI
diff --git a/controls/commctrl.c b/controls/commctrl.c
index 4be6540..629fc50 100644
--- a/controls/commctrl.c
+++ b/controls/commctrl.c
@@ -22,18 +22,43 @@
 #include "updown.h"
 #include "debug.h"
 
+
 /***********************************************************************
- * ComCtl32LibMain
+ * ComCtl32LibMain [Internal] Initializes the internal 'COMCTL32.DLL'.
+ *
+ * PARAMS
+ *     hinstDLL    [I]
+ *     fdwReason   [I]
+ *     lpvReserved [I]
+ *
  */
 
-BOOL32 WINAPI ComCtl32LibMain (HINSTANCE32 hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
-{ TRACE(commctrl,"%x,%lx,%p\n",hinstDLL,fdwReason,lpvReserved);
-  if ( fdwReason == DLL_PROCESS_ATTACH)
-  { InitCommonControls();
-  }
-  return TRUE;
+BOOL32 WINAPI
+ComCtl32LibMain (HINSTANCE32 hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+    TRACE (commctrl, "%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
 
+    switch (fdwReason) {
+	case DLL_PROCESS_ATTACH:
+	    TRACE (commctrl, "No animation class implemented!\n");
+	    HEADER_Register ();
+	    TRACE (commctrl, "No hotkey class implemented!\n");
+	    LISTVIEW_Register ();
+	    PROGRESS_Register ();
+	    STATUS_Register ();
+	    TRACE (commctrl, "No tab class implemented!\n");
+	    TOOLBAR_Register ();
+	    TOOLTIPS_Register ();
+	    TRACKBAR_Register ();
+	    TREEVIEW_Register ();
+	    UPDOWN_Register ();
+	    break;
+    }
+
+    return TRUE;
 }
+
+
 /***********************************************************************
  * DrawStatusText32A [COMCTL32.5][COMCTL32.27]
  *
@@ -73,9 +98,18 @@
 
 /***********************************************************************
  * DrawStatusText32W [COMCTL32.28]
+ *
+ * Draws text with borders, like in a status bar.
+ *
+ * PARAMS
+ *     hdc   [I] handle to the window's display context
+ *     lprc  [I] pointer to a rectangle
+ *     text  [I] pointer to the text
+ *     style [I] 
  */
-void WINAPI DrawStatusText32W( HDC32 hdc, LPRECT32 lprc, LPCWSTR text,
-                               UINT32 style )
+
+VOID WINAPI
+DrawStatusText32W (HDC32 hdc, LPRECT32 lprc, LPCWSTR text, UINT32 style)
 {
   LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, text );
   DrawStatusText32A(hdc, lprc, p, style);
@@ -137,19 +171,14 @@
  *     None.
  *
  * NOTES
- *     Calls InitCommonControlsEx.
- *     InitCommonControlsEx should be used instead.
+ *     This function is just a dummy.
+ *     The Win95 controls are registered at the DLL's initialization.
+ *     To register other controls InitCommonControlsEx must be used.
  */
 
 VOID WINAPI
 InitCommonControls (VOID)
 {
-    INITCOMMONCONTROLSEX icc;
-
-    icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
-    icc.dwICC = ICC_WIN95_CLASSES;
-
-    InitCommonControlsEx (&icc);
 }
 
 
@@ -160,6 +189,10 @@
  *
  * PARAMS
  *     lpInitCtrls [I] pointer to a INITCOMMONCONTROLS structure.
+ *
+ * NOTES
+ *     Only the additinal common controls are registered by this function.
+ *     The Win95 controls are registered at the DLL's initialization.
  */
 
 BOOL32 WINAPI
@@ -173,49 +206,21 @@
   if (lpInitCtrls == NULL) return FALSE;
   if (lpInitCtrls->dwSize < sizeof(INITCOMMONCONTROLSEX)) return FALSE;
 
-  for (cCount = 0; cCount <= 31; cCount++) {
+  for (cCount = 0; cCount < 32; cCount++) {
     dwMask = 1 << cCount;
     if (!(lpInitCtrls->dwICC & dwMask))
       continue;
 
     switch (lpInitCtrls->dwICC & dwMask) {
-      case ICC_LISTVIEW_CLASSES:
-        LISTVIEW_Register ();
-        HEADER_Register ();
-        break;
-
-      case ICC_TREEVIEW_CLASSES:
-        TREEVIEW_Register ();
-	TOOLTIPS_Register ();
-        break;
-
-      case ICC_BAR_CLASSES:
-	TOOLBAR_Register ();
-	STATUS_Register ();
-	TRACKBAR_Register ();
-	TOOLTIPS_Register ();
-        break;
-
-      case ICC_TAB_CLASSES:
-        TRACE (commctrl, "No tab class implemented!\n");
-	TOOLTIPS_Register ();
-        UPDOWN_Register ();
-        break;
-
-      case ICC_UPDOWN_CLASS:
-        UPDOWN_Register ();
-        break;
-
-      case ICC_PROGRESS_CLASS:
-        PROGRESS_Register ();
-        break;
-
-      case ICC_HOTKEY_CLASS:
-        TRACE (commctrl, "No hotkey class implemented!\n");
-        break;
-
+      /* dummy initialization */
       case ICC_ANIMATE_CLASS:
-        TRACE (commctrl, "No animation class implemented!\n");
+      case ICC_BAR_CLASSES:
+      case ICC_LISTVIEW_CLASSES:
+      case ICC_TREEVIEW_CLASSES:
+      case ICC_TAB_CLASSES:
+      case ICC_UPDOWN_CLASS:
+      case ICC_PROGRESS_CLASS:
+      case ICC_HOTKEY_CLASS:
         break;
 
       /* advanced classes - not included in Win95 */
@@ -267,6 +272,10 @@
  *     hInst
  *     hwndStatus
  *     lpwIDs
+ *
+ * NOTES
+ *     Some features are still missing because of incomplete WM_MENUSELECT
+ *     messages (16->32 bit conversion).
  */
 
 VOID WINAPI
@@ -528,32 +537,60 @@
 
 
 /***********************************************************************
- * ShowHideMenuCtl [COMCTL32.3]
+ * ShowHideMenuCtl [COMCTL32.3] 
+ *
+ * Shows or hides controls and updates the corresponding menu item.
  *
  * PARAMS
  *     hwnd   [I] handle to the client window.
- *     uFlags [I] menu command id
- *     lpInfo [I] pointer to an array of integers
+ *     uFlags [I] menu command id.
+ *     lpInfo [I] pointer to an array of integers. (See NOTES.)
  *
  * NOTES
+ *     The official documentation is incomplete! This has been fixed.
+ *
+ *     lpInfo
+ *     The array of integers contains pairs of values. BOTH values of
+ *     the first pair must be the handles to application's main menu.
+ *     Each subsequent pair consists of a menu id and control id.
  */
 
 BOOL32 WINAPI
 ShowHideMenuCtl (HWND32 hwnd, UINT32 uFlags, LPINT32 lpInfo)
 {
+    LPINT32 lpMenuId;
     FIXME (commctrl, "(0x%08x 0x%08x %p): empty stub!\n",
 	   hwnd, uFlags, lpInfo);
-#if 0
-    if (GetMenuState (lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
-	/* checked -> hide control */
 
+    if (lpInfo == NULL)
+	return FALSE;
+
+    if (!(lpInfo[0]) || !(lpInfo[1]))
+	return FALSE;
+
+    /* search for control */
+    lpMenuId = &lpInfo[2];
+    while (*lpMenuId != uFlags)
+	lpMenuId += 2;
+
+    if (GetMenuState32 (lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
+	/* uncheck menu item */
+	CheckMenuItem32 (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
+
+	/* hide control */
+	lpMenuId++;
+	SetWindowPos32 (GetDlgItem32 (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
+			SWP_HIDEWINDOW);
     }
     else {
-	/* not checked -> show control */
+	/* check menu item */
+	CheckMenuItem32 (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
 
+	/* show control */
+	lpMenuId++;
+	SetWindowPos32 (GetDlgItem32 (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
+			SWP_SHOWWINDOW);
     }
 
-#endif
-
-    return FALSE;
+    return TRUE;
 }
diff --git a/controls/menu.c b/controls/menu.c
index fc01e53..45a25c6 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -3852,7 +3852,7 @@
 /**********************************************************************
  *		SetMenuDefaultItem32    (USER32.489)
  */
-BOOL32 WINAPI SetMenuDefaultItem32(HMENU32 hmenu, UINT32 item, BOOL32 bypos)
+BOOL32 WINAPI SetMenuDefaultItem32(HMENU32 hmenu, UINT32 item, UINT32 bypos)
 {
     MENUITEM *menuitem = MENU_FindItem(&hmenu, &item, bypos);
     POPUPMENU *menu;
@@ -3938,7 +3938,7 @@
 
 BOOL32 WINAPI CheckMenuRadioItem32(HMENU32 hMenu,
 				   UINT32 first, UINT32 last, UINT32 check,
-				   BOOL32 bypos)
+				   UINT32 bypos)
 {
      MENUITEM *mifirst, *milast, *micheck;
      HMENU32 mfirst = hMenu, mlast = hMenu, mcheck = hMenu;
diff --git a/controls/pager.c b/controls/pager.c
index 2e335c0..60612c2 100644
--- a/controls/pager.c
+++ b/controls/pager.c
@@ -25,6 +25,17 @@
 
 
 static __inline__ LRESULT
+PAGER_ForwardMouse (WND *wndPtr, WPARAM32 wParam)
+{
+    PAGER_INFO *infoPtr = PAGER_GetInfoPtr(wndPtr);
+
+    infoPtr->bForward = (BOOL32)wParam;
+
+    return 0;
+}
+
+
+static __inline__ LRESULT
 PAGER_GetBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     PAGER_INFO *infoPtr = PAGER_GetInfoPtr(wndPtr);
@@ -51,6 +62,28 @@
 }
 
 
+// << PAGER_GetButtonState >>
+// << PAGER_GetDropTarget >>
+
+
+static __inline__ LRESULT
+PAGER_GetPos (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    PAGER_INFO *infoPtr = PAGER_GetInfoPtr(wndPtr);
+
+    return infoPtr->iPos;
+}
+
+
+static LRESULT
+PAGER_RecalcSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+//    PAGER_INFO *infoPtr = PAGER_GetInfoPtr(wndPtr);
+
+    FIXME (pager, "empty stub!\n");
+
+    return 0;
+}
 
 
 static __inline__ LRESULT
@@ -108,6 +141,18 @@
 }
 
 
+static __inline__ LRESULT
+PAGER_SetPos (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    PAGER_INFO *infoPtr = PAGER_GetInfoPtr(wndPtr);
+
+    infoPtr->iPos = (INT32)lParam;
+
+    /* FIXME: redraw */
+
+    return 0;
+}
+
 
 static LRESULT
 PAGER_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
@@ -120,7 +165,7 @@
     wndPtr->wExtra[0] = (DWORD)infoPtr;
 
     if (infoPtr == NULL) {
-	ERR (treeview, "could not allocate info memory!\n");
+	ERR (pager, "could not allocate info memory!\n");
 	return 0;
     }
 
@@ -134,6 +179,7 @@
     infoPtr->clrBk = GetSysColor32 (COLOR_BTNFACE);
     infoPtr->iBorder = 0;
     infoPtr->iButtonSize = 0;
+    infoPtr->iPos = 0;
 
 
     return 0;
@@ -148,7 +194,7 @@
 
 
 
-    /* free tree view info data */
+    /* free pager info data */
     HeapFree (GetProcessHeap (), 0, infoPtr);
 
     return 0;
@@ -169,15 +215,19 @@
 }
 
 
+// << PAGER_MouseMove >>
+// << PAGER_Paint >>
+
 
 LRESULT WINAPI
-PagerWindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
+PAGER_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
 
     switch (uMsg)
     {
-//	case PGM_FORWARDMOUSE:
+	case PGM_FORWARDMOUSE:
+	    return PAGER_ForwardMouse (wndPtr, wParam);
 
 	case PGM_GETBKCOLOR:
 	    return PAGER_GetBkColor (wndPtr, wParam, lParam);
@@ -190,8 +240,12 @@
 
 //	case PGM_GETBUTTONSTATE:
 //	case PGM_GETDROPTARGET:
-//	case PGM_GETPOS:
-//	case PGM_RECALCSIZE:
+
+	case PGM_GETPOS:
+	    return PAGER_SetPos (wndPtr, wParam, lParam);
+
+	case PGM_RECALCSIZE:
+	    return PAGER_RecalcSize (wndPtr, wParam, lParam);
 
 	case PGM_SETBKCOLOR:
 	    return PAGER_SetBkColor (wndPtr, wParam, lParam);
@@ -205,7 +259,8 @@
 	case PGM_SETCHILD:
 	    return PAGER_SetChild (wndPtr, wParam, lParam);
 
-//	case PGM_SETPOS:
+	case PGM_SETPOS:
+	    return PAGER_SetPos (wndPtr, wParam, lParam);
 
 	case WM_CREATE:
 	    return PAGER_Create (wndPtr, wParam, lParam);
@@ -242,7 +297,7 @@
 
     ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
     wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS;
-    wndClass.lpfnWndProc   = (WNDPROC32)PagerWindowProc;
+    wndClass.lpfnWndProc   = (WNDPROC32)PAGER_WindowProc;
     wndClass.cbClsExtra    = 0;
     wndClass.cbWndExtra    = sizeof(PAGER_INFO *);
     wndClass.hCursor       = LoadCursor32A (0, IDC_ARROW32A);
diff --git a/controls/rebar.c b/controls/rebar.c
index 9280cf9..a36bbff 100644
--- a/controls/rebar.c
+++ b/controls/rebar.c
@@ -24,18 +24,573 @@
 #define REBAR_GetInfoPtr(wndPtr) ((REBAR_INFO *)wndPtr->wExtra[0])
 
 
+// << REBAR_BeginDrag >>
+// << REBAR_DeleteBand >>
+// << REBAR_DragMove >>
+// << REBAR_EndDrag >>
+// << REBAR_GetBandBorders >>
+
+
+__inline__ static LRESULT
+REBAR_GetBandCount (WND *wndPtr)
+{
+    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
+
+    TRACE (rebar, "band count %u!\n", infoPtr->uNumBands);
+
+    return infoPtr->uNumBands;
+}
+
+
+static LRESULT
+REBAR_GetBandInfo32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
+    LPREBARBANDINFO32A lprbbi = (LPREBARBANDINFO32A)lParam;
+    REBAR_BAND *lpBand;
+
+    if (lprbbi == NULL)
+	return FALSE;
+    if (lprbbi->cbSize < sizeof (LPREBARBANDINFO32A))
+	return FALSE;
+    if ((UINT32)wParam >= infoPtr->uNumBands)
+	return FALSE;
+
+    TRACE (rebar, "index %u\n", (UINT32)wParam);
+
+    /* copy band information */
+    lpBand = &infoPtr->bands[(UINT32)wParam];
+
+    if (lprbbi->fMask & RBBIM_STYLE)
+	lprbbi->fStyle = lpBand->fStyle;
+
+    if (lprbbi->fMask & RBBIM_COLORS) {
+	lprbbi->clrFore = lpBand->clrFore;
+	lprbbi->clrBack = lpBand->clrBack;
+    }
+
+    if ((lprbbi->fMask & RBBIM_TEXT) && 
+	(lprbbi->lpText) && (lpBand->lpText)) {
+	    lstrcpyn32A (lprbbi->lpText, lpBand->lpText, lprbbi->cch);
+    }
+
+    if (lprbbi->fMask & RBBIM_IMAGE)
+	lprbbi->iImage = lpBand->iImage;
+
+    if (lprbbi->fMask & RBBIM_CHILD)
+	lprbbi->hwndChild = lpBand->hwndChild;
+
+    if (lprbbi->fMask & RBBIM_CHILDSIZE) {
+	lprbbi->cxMinChild = lpBand->cxMinChild;
+	lprbbi->cyMinChild = lpBand->cyMinChild;
+	lprbbi->cyMaxChild = lpBand->cyMaxChild;
+	lprbbi->cyChild    = lpBand->cyChild;
+	lprbbi->cyIntegral = lpBand->cyIntegral;
+    }
+
+    if (lprbbi->fMask & RBBIM_SIZE)
+	lprbbi->cx = lpBand->cx;
+
+    if (lprbbi->fMask & RBBIM_BACKGROUND)
+	lprbbi->hbmBack = lpBand->hbmBack;
+
+    if (lprbbi->fMask & RBBIM_ID)
+	lprbbi->wID = lpBand->wID;
+
+    /* FIXME: check for size of band info structure */
+
+    if (lprbbi->fMask & RBBIM_IDEALSIZE)
+	lprbbi->cxIdeal = lpBand->cxIdeal;
+
+    if (lprbbi->fMask & RBBIM_LPARAM)
+	lprbbi->lParam = lpBand->lParam;
+
+    if (lprbbi->fMask & RBBIM_HEADERSIZE)
+	lprbbi->cxHeader = lpBand->cxHeader;
+
+    return TRUE;
+}
+
+
+// << REBAR_GetBandInfo32W >>
+
+// << REBAR_GetBarHeight >>
+
+
+static LRESULT
+REBAR_GetBarInfo (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
+    LPREBARINFO lpInfo = (LPREBARINFO)lParam;
+
+    if (lpInfo == NULL)
+	return FALSE;
+
+    if (lpInfo->cbSize < sizeof (REBARINFO))
+	return FALSE;
+
+    TRACE (rebar, "getting bar info!\n");
+
+    if (infoPtr->himl) {
+	lpInfo->himl = infoPtr->himl;
+	lpInfo->fMask |= RBIM_IMAGELIST;
+    }
+
+    return TRUE;
+}
+
+
+__inline__ static LRESULT
+REBAR_GetBkColor (WND *wndPtr)
+{
+    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
+
+    TRACE (rebar, "background color 0x%06lx!\n", infoPtr->clrBk);
+
+    return infoPtr->clrBk;
+}
+
+
+// << REBAR_GetColorScheme >>
+
+// << REBAR_GetRowHeight >>
+
+
+__inline__ static LRESULT
+REBAR_GetTextColor (WND *wndPtr)
+{
+    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
+
+    TRACE (rebar, "text color 0x%06lx!\n", infoPtr->clrText);
+
+    return infoPtr->clrText;
+}
+
+
+// << REBAR_GetToolTips >>
+// << REBAR_GetUnicodeFormat >>
+// << REBAR_HitTest >>
+
+
+static LRESULT
+REBAR_IdToIndex (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
+    UINT32 i;
+
+    if (infoPtr == NULL)
+	return -1;
+
+    if (infoPtr->uNumBands < 1)
+	return -1;
+
+    TRACE (rebar, "id %u\n", (UINT32)wParam);
+
+    for (i = 0; i < infoPtr->uNumBands; i++) {
+	if (infoPtr->bands[i].wID == (UINT32)wParam)
+	    return i;
+    }
+
+    return -1;
+}
+
+
+static LRESULT
+REBAR_InsertBand32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
+    LPREBARBANDINFO32A lprbbi = (LPREBARBANDINFO32A)lParam;
+    UINT32 uIndex = (UINT32)wParam;
+    REBAR_BAND *lpBand;
+
+    if (infoPtr == NULL)
+	return FALSE;
+    if (lprbbi == NULL)
+	return FALSE;
+    if (lprbbi->cbSize < sizeof (REBARBANDINFO32A))
+	return FALSE;
+
+    if (infoPtr->uNumBands == 0) {
+	infoPtr->bands =
+	    (REBAR_BAND *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
+				     sizeof (REBAR_BAND));
+	uIndex = 0;
+    }
+    else {
+	REBAR_BAND *oldBands = infoPtr->bands;
+	infoPtr->bands =
+	    (REBAR_BAND *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
+				     (infoPtr->uNumBands+1)*sizeof(REBAR_BAND));
+	if ((INT32)uIndex == -1)
+	    uIndex = infoPtr->uNumBands;
+
+	/* pre copy */
+
+	/* post copy */
+
+	HeapFree (GetProcessHeap (), 0, &oldBands);
+    }
+
+    infoPtr->uNumBands++;
+
+    TRACE (rebar, "index %u!\n", uIndex);
+
+    /* initialize band (infoPtr->bands[uIndex])*/
+    lpBand = &infoPtr->bands[uIndex];
+
+    if (lprbbi->fMask & RBBIM_STYLE)
+	lpBand->fStyle = lprbbi->fStyle;
+
+    if (lprbbi->fMask & RBBIM_COLORS) {
+	lpBand->clrFore = lprbbi->clrFore;
+	lpBand->clrBack = lprbbi->clrBack;
+    }
+
+    if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
+	INT32 len = lstrlen32A (lprbbi->lpText);
+	if (len > 0) {
+	    lpBand->lpText = 
+		(LPSTR)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len + 1);
+	    lstrcpy32A (lpBand->lpText, lprbbi->lpText);
+	}
+    }
+
+    if (lprbbi->fMask & RBBIM_IMAGE)
+	lpBand->iImage = lprbbi->iImage;
+
+    if (lprbbi->fMask & RBBIM_CHILD)
+	lpBand->hwndChild = lprbbi->hwndChild;
+
+    if (lprbbi->fMask & RBBIM_CHILDSIZE) {
+	lpBand->cxMinChild = lprbbi->cxMinChild;
+	lpBand->cyMinChild = lprbbi->cyMinChild;
+	lpBand->cyMaxChild = lprbbi->cyMaxChild;
+	lpBand->cyChild    = lprbbi->cyChild;
+	lpBand->cyIntegral = lprbbi->cyIntegral;
+    }
+
+    if (lprbbi->fMask & RBBIM_SIZE)
+	lpBand->cx = lprbbi->cx;
+
+    if (lprbbi->fMask & RBBIM_BACKGROUND)
+	lpBand->hbmBack = lprbbi->hbmBack;
+
+    if (lprbbi->fMask & RBBIM_ID)
+	lpBand->wID = lprbbi->wID;
+
+    /* FIXME: check for size of band info structure */
+
+    if (lprbbi->fMask & RBBIM_IDEALSIZE)
+	lpBand->cxIdeal = lprbbi->cxIdeal;
+
+    if (lprbbi->fMask & RBBIM_LPARAM)
+	lpBand->lParam = lprbbi->lParam;
+
+    if (lprbbi->fMask & RBBIM_HEADERSIZE)
+	lpBand->cxHeader = lprbbi->cxHeader;
+
+    return TRUE;
+}
+
+
+// << REBAR_InsertBand32W >>
+// << REBAR_MaximizeBand >>
+// << REBAR_MinimizeBand >>
+// << REBAR_MoveBand >>
+
+
+static LRESULT
+REBAR_SetBandInfo32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
+    LPREBARBANDINFO32A lprbbi = (LPREBARBANDINFO32A)lParam;
+    REBAR_BAND *lpBand;
+
+    if (lprbbi == NULL)
+	return FALSE;
+    if (lprbbi->cbSize < sizeof (LPREBARBANDINFO32A))
+	return FALSE;
+    if ((UINT32)wParam >= infoPtr->uNumBands)
+	return FALSE;
+
+    TRACE (rebar, "index %u\n", (UINT32)wParam);
+
+    /* set band information */
+    lpBand = &infoPtr->bands[(UINT32)wParam];
+
+    if (lprbbi->fMask & RBBIM_STYLE)
+	lpBand->fStyle = lprbbi->fStyle;
+
+    if (lprbbi->fMask & RBBIM_COLORS) {
+	lpBand->clrFore = lprbbi->clrFore;
+	lpBand->clrBack = lprbbi->clrBack;
+    }
+
+    if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
+/*
+	INT32 len = lstrlen32A (lprbbi->lpText);
+	if (len > 0) {
+	    lpBand->lpText = 
+		(LPSTR)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len + 1);
+	    lstrcpy32A (lpBand->lpText, lprbbi->lpText);
+	}
+*/
+    }
+
+    if (lprbbi->fMask & RBBIM_IMAGE)
+	lpBand->iImage = lprbbi->iImage;
+
+    if (lprbbi->fMask & RBBIM_CHILD)
+	lpBand->hwndChild = lprbbi->hwndChild;
+
+    if (lprbbi->fMask & RBBIM_CHILDSIZE) {
+	lpBand->cxMinChild = lprbbi->cxMinChild;
+	lpBand->cyMinChild = lprbbi->cyMinChild;
+	lpBand->cyMaxChild = lprbbi->cyMaxChild;
+	lpBand->cyChild    = lprbbi->cyChild;
+	lpBand->cyIntegral = lprbbi->cyIntegral;
+    }
+
+    if (lprbbi->fMask & RBBIM_SIZE)
+	lpBand->cx = lprbbi->cx;
+
+    if (lprbbi->fMask & RBBIM_BACKGROUND)
+	lpBand->hbmBack = lprbbi->hbmBack;
+
+    if (lprbbi->fMask & RBBIM_ID)
+	lpBand->wID = lprbbi->wID;
+
+    /* FIXME: check for size of band info structure */
+
+    if (lprbbi->fMask & RBBIM_IDEALSIZE)
+	lpBand->cxIdeal = lprbbi->cxIdeal;
+
+    if (lprbbi->fMask & RBBIM_LPARAM)
+	lpBand->lParam = lprbbi->lParam;
+
+    if (lprbbi->fMask & RBBIM_HEADERSIZE)
+	lpBand->cxHeader = lprbbi->cxHeader;
+
+    return TRUE;
+}
+
+
+// << REBAR_SetBandInfo32W >>
+
+
+static LRESULT
+REBAR_SetBarInfo (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
+    LPREBARINFO lpInfo = (LPREBARINFO)lParam;
+
+    if (lpInfo == NULL)
+	return FALSE;
+
+    if (lpInfo->cbSize < sizeof (REBARINFO))
+	return FALSE;
+
+    TRACE (rebar, "setting bar info!\n");
+
+    if (lpInfo->fMask & RBIM_IMAGELIST)
+	infoPtr->himl = lpInfo->himl;
+
+    return TRUE;
+}
+
+
+static LRESULT
+REBAR_SetBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
+    COLORREF clrTemp;
+
+    clrTemp = infoPtr->clrBk;
+    infoPtr->clrBk = (COLORREF)lParam;
+
+    TRACE (rebar, "background color 0x%06lx!\n", infoPtr->clrBk);
+
+    return clrTemp;
+}
+
+
+// << REBAR_SetColorScheme >>
+// << REBAR_SetPalette >>
+// << REBAR_SetParent >>
+
+
+static LRESULT
+REBAR_SetTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
+    COLORREF clrTemp;
+
+    clrTemp = infoPtr->clrText;
+    infoPtr->clrText = (COLORREF)lParam;
+
+    TRACE (rebar, "text color 0x%06lx!\n", infoPtr->clrText);
+
+    return clrTemp;
+}
+
+
+// << REBAR_SetTooltips >>
+// << REBAR_SetUnicodeFormat >>
+// << REBAR_ShowBand >>
+// << REBAR_SizeToRect >>
+
+
+
+static LRESULT
+REBAR_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    REBAR_INFO *infoPtr;
+
+    /* allocate memory for info structure */
+    infoPtr = (REBAR_INFO *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
+				       sizeof(REBAR_INFO));
+    wndPtr->wExtra[0] = (DWORD)infoPtr;
+
+    if (infoPtr == NULL) {
+	ERR (rebar, "could not allocate info memory!\n");
+	return 0;
+    }
+
+    if ((REBAR_INFO*)wndPtr->wExtra[0] != infoPtr) {
+	ERR (rebar, "pointer assignment error!\n");
+	return 0;
+    }
+
+
+    infoPtr->clrText = CLR_NONE;
+    infoPtr->clrText = RGB(0, 0, 0);
+
+    TRACE (rebar, "created!\n");
+    return 0;
+}
+
+
+static LRESULT
+REBAR_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    REBAR_INFO *infoPtr = REBAR_GetInfoPtr(wndPtr);
+    REBAR_BAND *lpBand;
+    INT32 i;
+
+
+    /* free rebar bands */
+    if ((infoPtr->uNumBands > 0) && infoPtr->bands) {
+	/* clean up each band */
+	for (i = 0; i < infoPtr->uNumBands; i++) {
+	    lpBand = &infoPtr->bands[i];
+
+	    /* delete text strings */
+	    if (lpBand->lpText) {
+		HeapFree (GetProcessHeap (), 0, lpBand->lpText);
+		lpBand->lpText = NULL;
+	    }
+	}
+
+	/* free band array */
+	HeapFree (GetProcessHeap (), 0, infoPtr->bands);
+	infoPtr->bands = NULL;
+    }
+
+    /* free rebar info data */
+    HeapFree (GetProcessHeap (), 0, infoPtr);
+
+    TRACE (rebar, "destroyed!\n");
+    return 0;
+}
+
+
+
+
 LRESULT WINAPI
-RebarWindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
+REBAR_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
 
     switch (uMsg)
     {
-//	case WM_CREATE:
-//	    return REBAR_Create (wndPtr, wParam, lParam);
+//	case RB_BEGINDRAG:
+//	case RB_DELETEBAND:
+//	case RB_DRAGMOVE:
+//	case RB_ENDDRAG:
+//	case RB_GETBANDBORDERS:
 
-//	case WM_DESTROY:
-//	    return REBAR_Destroy (wndPtr, wParam, lParam);
+	case RB_GETBANDCOUNT:
+	    return REBAR_GetBandCount (wndPtr);
+
+//	case RB_GETBANDINFO32:  /* outdated, just for compatibility */
+
+	case RB_GETBANDINFO32A:
+	    return REBAR_GetBandInfo32A (wndPtr, wParam, lParam);
+
+
+//	case RB_GETBANDINFO32W:
+//	case RB_GETBARHEIGHT:
+
+	case RB_GETBARINFO:
+	    return REBAR_GetBarInfo (wndPtr, wParam, lParam);
+
+	case RB_GETBKCOLOR:
+	    return REBAR_GetBkColor (wndPtr);
+
+//	case RB_GETCOLORSCHEME:
+//	case RB_GETDROPTARGET:
+//	case RB_GETPALETTE:
+//	case RB_GETRECT:
+//	case RB_GETROWCOUNT:
+//	case RB_GETROWHEIGHT:
+
+	case RB_GETTEXTCOLOR:
+	    return REBAR_GetTextColor (wndPtr);
+
+//	case RB_GETTOOLTIPS:
+//	case RB_GETUNICODEFORMAT:
+//	case RB_HITTEST:
+
+	case RB_IDTOINDEX:
+	    return REBAR_IdToIndex (wndPtr, wParam, lParam);
+
+	case RB_INSERTBAND32A:
+	    return REBAR_InsertBand32A (wndPtr, wParam, lParam);
+
+//	case RB_INSERTBAND32W:
+//	case RB_MAXIMIZEBAND:
+//	case RB_MINIMIZEBAND:
+//	case RB_MOVEBAND:
+
+	case RB_SETBANDINFO32A:
+	    return REBAR_SetBandInfo32A (wndPtr, wParam, lParam);
+
+//	case RB_SETBANDINFO32W:
+
+	case RB_SETBARINFO:
+	    return REBAR_SetBarInfo (wndPtr, wParam, lParam);
+
+	case RB_SETBKCOLOR:
+	    return REBAR_SetBkColor (wndPtr, wParam, lParam);
+
+//	case RB_SETCOLORSCHEME:
+//	case RB_SETPALETTE:
+//	case RB_SETPARENT:
+
+	case RB_SETTEXTCOLOR:
+	    return REBAR_SetTextColor (wndPtr, wParam, lParam);
+
+//	case RB_SETTOOLTIPS:
+//	case RB_SETUNICODEFORMAT:
+//	case RB_SHOWBAND:
+//	case RB_SIZETORECT:
+
+
+	case WM_CREATE:
+	    return REBAR_Create (wndPtr, wParam, lParam);
+
+	case WM_DESTROY:
+	    return REBAR_Destroy (wndPtr, wParam, lParam);
 
 //	case WM_GETFONT:
 
@@ -70,7 +625,7 @@
 
     ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
     wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS;
-    wndClass.lpfnWndProc   = (WNDPROC32)RebarWindowProc;
+    wndClass.lpfnWndProc   = (WNDPROC32)REBAR_WindowProc;
     wndClass.cbClsExtra    = 0;
     wndClass.cbWndExtra    = sizeof(REBAR_INFO *);
     wndClass.hCursor       = LoadCursor32A (0, IDC_ARROW32A);
diff --git a/controls/toolbar.c b/controls/toolbar.c
index 6a883d5..142ffb6 100644
--- a/controls/toolbar.c
+++ b/controls/toolbar.c
@@ -10,7 +10,7 @@
  *   - Notifications.
  *   - Fix TB_GETBITMAPFLAGS.
  *   - Fix TB_GETROWS and TB_SETROWS.
- *   - Tooltip support (under contruction).
+ *   - Tooltip support (almost complete).
  *   - Unicode suppport.
  *   - Internal COMMCTL32 bitmaps.
  *   - Fix TOOLBAR_Customize. (Customize dialog.)
@@ -22,7 +22,7 @@
  *     enablebtn.exe, getbmp.exe, getbtn.exe, getflags.exe, hidebtn.exe,
  *     indetbtn.exe, insbtn.exe, pressbtn.exe, setbtnsz.exe, setcmdid.exe,
  *     setparnt.exe, setrows.exe, toolwnd.exe.
- *   - additional features.
+ *   - Microsofts controlspy examples.
  */
 
 #include "windows.h"
@@ -248,20 +248,29 @@
     INT32 x, y, cx, cy;
     BOOL32 bVertical;
     SIZE32  sizeString;
+    RECT32 rect = {0, 0, 0, 0};
 
     TOOLBAR_CalcStrings (wndPtr, &sizeString);
 
     if (sizeString.cy > 0)
 	infoPtr->nButtonHeight = sizeString.cy + infoPtr->nBitmapHeight + 6;
+    else if (infoPtr->nButtonHeight < infoPtr->nBitmapHeight + 6)
+	infoPtr->nButtonHeight = infoPtr->nBitmapHeight + 6;
 
     if (sizeString.cx > infoPtr->nBitmapWidth)
 	infoPtr->nButtonWidth = sizeString.cx + 6;
+    else if (infoPtr->nButtonWidth < infoPtr->nBitmapWidth + 6)
+	infoPtr->nButtonWidth = infoPtr->nBitmapWidth + 6;
 
     x  = infoPtr->nIndent;
     y  = TOP_BORDER;
     cx = infoPtr->nButtonWidth;
     cy = infoPtr->nButtonHeight;
     nRows = 1;
+    rect.top = y;
+    rect.left = x;
+    rect.bottom = y + cy;
+    rect.right = x;
 
     btnPtr = infoPtr->buttons;
     for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
@@ -279,14 +288,14 @@
 		x = 0;
 		y += cy;
 		cx = infoPtr->nWidth;
-		cy = ((btnPtr->iBitmap == 0) ?
-		    SEPARATOR_WIDTH : btnPtr->iBitmap) * 2 / 3;
+		cy = ((btnPtr->iBitmap > 0) ?
+		     btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 / 3;
 		nRows++;
 		bVertical = TRUE;
 	    }
 	    else
-		cx = (btnPtr->iBitmap == 0) ?
-		    SEPARATOR_WIDTH : btnPtr->iBitmap;
+		cx = (btnPtr->iBitmap > 0) ?
+		     btnPtr->iBitmap : SEPARATOR_WIDTH;
 	}
 	else {
 	    /* this must be a button */
@@ -299,6 +308,13 @@
 	btnPtr->rect.right  = x + cx;
 	btnPtr->rect.bottom = y + cy;
 
+	if (rect.left > x)
+	    rect.left = x;
+	if (rect.right < x + cx)
+	    rect.right = x + cx;
+	if (rect.bottom < y + cy)
+	    rect.bottom = y + cy;
+
 	if (infoPtr->hwndToolTip) {
 	    TTTOOLINFO32A ti;
 
@@ -322,6 +338,8 @@
     }
 
     infoPtr->nHeight = y + cy + BOTTOM_BORDER;
+    infoPtr->maxSize.cx = rect.right - rect.left;
+    infoPtr->maxSize.cy = rect.bottom - rect.top;
     TRACE (toolbar, "toolbar height %d\n", infoPtr->nHeight);
 }
 
@@ -541,13 +559,13 @@
 	infoPtr->buttons[nOldButtons+nCount].dwData    = lpTbb[nCount].dwData;
 	infoPtr->buttons[nOldButtons+nCount].iString   = lpTbb[nCount].iString;
 
-	if (infoPtr->hwndToolTip) {
+	if ((infoPtr->hwndToolTip) && !(lpTbb[nCount].fsStyle & TBSTYLE_SEP)) {
 	    TTTOOLINFO32A ti;
 
 	    ZeroMemory (&ti, sizeof(TTTOOLINFO32A));
 	    ti.cbSize   = sizeof (TTTOOLINFO32A);
 	    ti.hwnd     = wndPtr->hwndSelf;
-	    ti.uId      = (LPSTR)lpTbb[nCount].idCommand;
+	    ti.uId      = lpTbb[nCount].idCommand;
 	    ti.hinst    = 0;
 	    ti.lpszText = LPSTR_TEXTCALLBACK32A;
 
@@ -654,7 +672,7 @@
     INT32  x, y, cx, cy;
     UINT32 uPosFlags = 0;
 
-    FIXME (toolbar, "auto size!\n");
+    TRACE (toolbar, "resizing!\n");
 
     parent = GetParent32 (wndPtr->hwndSelf);
     GetClientRect32(parent, &parent_rect);
@@ -805,7 +823,8 @@
     if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
 	return FALSE;
 
-    if (infoPtr->hwndToolTip) {
+    if ((infoPtr->hwndToolTip) && 
+	!(infoPtr->buttons[nIndex].fsStyle & TBSTYLE_SEP)) {
 	TTTOOLINFO32A ti;
 
 	ZeroMemory (&ti, sizeof(TTTOOLINFO32A));
@@ -1102,7 +1121,14 @@
     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
     LPSIZE32 lpSize = (LPSIZE32)lParam;
 
-    FIXME (toolbar, "empty stub!\n");
+    if (lpSize == NULL)
+	return FALSE;
+
+    lpSize->cx = infoPtr->maxSize.cx;
+    lpSize->cx = infoPtr->maxSize.cy;
+
+    TRACE (toolbar, "maximum size %d x %d\n",
+	   infoPtr->maxSize.cx, infoPtr->maxSize.cy);
 
     return TRUE;
 }
@@ -1110,7 +1136,31 @@
 
 // << TOOLBAR_GetObject >>
 // << TOOLBAR_GetPadding >>
-// << TOOLBAR_GetRect >>
+
+
+static LRESULT
+TOOLBAR_GetRect (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;
+    
+    lpRect->left   = btnPtr->rect.left;
+    lpRect->right  = btnPtr->rect.right;
+    lpRect->bottom = btnPtr->rect.bottom;
+    lpRect->top    = btnPtr->rect.top;
+
+    return TRUE;
+}
 
 
 static LRESULT
@@ -1151,7 +1201,16 @@
 }
 
 
-// << TOOLBAR_GetTextRows >>
+static LRESULT
+TOOLBAR_GetTextRows (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+
+    if (infoPtr == NULL)
+	return 0;
+
+    return infoPtr->nMaxTextRows;
+}
 
 
 static LRESULT
@@ -1164,7 +1223,16 @@
 }
 
 
-// << TOOLBAR_GetUnicodeFormat >>
+static LRESULT
+TOOLBAR_GetUnicodeFormat (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+
+    TRACE (toolbar, "%s hwnd=0x%04x stub!\n", 
+	   infoPtr->bUnicode ? "TRUE" : "FALSE", wndPtr->hwndSelf);
+
+    return infoPtr->bUnicode;
+}
 
 
 static LRESULT
@@ -1193,7 +1261,7 @@
 }
 
 
-static LRESULT
+__inline__ static LRESULT
 TOOLBAR_HitTest (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     return TOOLBAR_InternalHitTest (wndPtr, (LPPOINT32)lParam);
@@ -1262,7 +1330,7 @@
     infoPtr->buttons[nIndex].dwData    = lpTbb->dwData;
     infoPtr->buttons[nIndex].iString   = lpTbb->iString;
 
-    if (infoPtr->hwndToolTip) {
+    if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
 	TTTOOLINFO32A ti;
 
 	ZeroMemory (&ti, sizeof(TTTOOLINFO32A));
@@ -1482,7 +1550,19 @@
 }
 
 
-// << TOOLBAR_SetButtonWidth >>
+static LRESULT
+TOOLBAR_SetButtonWidth (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+
+    if (infoPtr == NULL)
+	return FALSE;
+
+    infoPtr->cxMin = (INT32)LOWORD(lParam);
+    infoPtr->cxMax = (INT32)HIWORD(lParam);
+
+    return TRUE;
+}
 
 
 static LRESULT
@@ -1496,6 +1576,12 @@
 
     infoPtr->buttons[nIndex].idCommand = (INT32)lParam;
 
+    if (infoPtr->hwndToolTip) {
+
+	FIXME (toolbar, "change tool tip!\n");
+
+    }
+
     return TRUE;
 }
 
@@ -1608,7 +1694,20 @@
 }
 
 
-// << TOOLBAR_SetMaxTextRows >>
+static LRESULT
+TOOLBAR_SetMaxTextRows (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+
+    if (infoPtr == NULL)
+	return FALSE;
+
+    infoPtr->nMaxTextRows = (INT32)wParam;
+
+    return TRUE;
+}
+
+
 // << TOOLBAR_SetPadding >>
 
 
@@ -1679,6 +1778,12 @@
     TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
     ReleaseDC32 (wndPtr->hwndSelf, hdc);
 
+    if (infoPtr->hwndToolTip) {
+
+	FIXME (toolbar, "change tool tip!\n");
+
+    }
+
     return TRUE;
 }
 
@@ -1698,10 +1803,15 @@
 TOOLBAR_SetUnicodeFormat (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+    BOOL32 bTemp;
 
-    FIXME (toolbar, "hwnd=0x%04x stub!\n", wndPtr->hwndSelf);
+    TRACE (toolbar, "%s hwnd=0x%04x stub!\n", 
+	   ((BOOL32)wParam) ? "TRUE" : "FALSE", wndPtr->hwndSelf);
 
-    return 0;
+    bTemp = infoPtr->bUnicode;
+    infoPtr->bUnicode = (BOOL32)wParam;
+
+    return bTemp;
 }
 
 
@@ -1719,8 +1829,12 @@
 
     infoPtr->nHeight = infoPtr->nButtonHeight + TOP_BORDER + BOTTOM_BORDER;
     infoPtr->nMaxRows = 1;
+    infoPtr->nMaxTextRows = 1;
+    infoPtr->cxMin = -1;
+    infoPtr->cxMax = -1;
 
-    infoPtr->bCaptured = 0;
+    infoPtr->bCaptured = FALSE;
+    infoPtr->bUnicode = FALSE;
     infoPtr->nButtonDown = -1;
     infoPtr->nOldHit = -1;
 
@@ -1737,8 +1851,7 @@
 	    CreateWindowEx32A (0, TOOLTIPS_CLASS32A, NULL, TTS_ALWAYSTIP,
 			       CW_USEDEFAULT32, CW_USEDEFAULT32,
 			       CW_USEDEFAULT32, CW_USEDEFAULT32,
-			       wndPtr->hwndSelf, 0,
-			       wndPtr->hInstance, 0);
+			       wndPtr->hwndSelf, 0, 0, 0);
 
 	/* Send NM_TOOLTIPSCREATED notification */
 	if (infoPtr->hwndToolTip) {
@@ -1997,7 +2110,7 @@
 }
 
 
-
+// << TOOLBAR_NCActivate >>
 
 
 static LRESULT
@@ -2005,8 +2118,7 @@
 {
     if (!(wndPtr->dwStyle & CCS_NODIVIDER)) {
 	LPRECT32 winRect  = (LPRECT32)lParam;
-	winRect->top    += 2;   
-	winRect->bottom += 2;   
+	winRect->top += 2;   
     }
 
     return DefWindowProc32A (wndPtr->hwndSelf, WM_NCCALCSIZE, wParam, lParam);
@@ -2096,11 +2208,25 @@
     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
     LPNMHDR lpnmh = (LPNMHDR)lParam;
 
-    if ((infoPtr->hwndToolTip) && ((lpnmh->code == TTN_GETDISPINFO32A) ||
-	(lpnmh->code == TTN_GETDISPINFO32W))) {
+    TRACE (toolbar, "passing WM_NOTIFY!\n");
 
-	SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
-			wParam, lParam);
+    if ((infoPtr->hwndToolTip) && (lpnmh->hwndFrom == infoPtr->hwndToolTip)) {
+	SendMessage32A (infoPtr->hwndNotify, WM_NOTIFY,	wParam, lParam);
+
+#if 0
+	if (lpnmh->code == TTN_GETDISPINFO32A) {
+	    LPNMTTDISPINFO32A lpdi = (LPNMTTDISPINFO32A)lParam;
+
+	    FIXME (toolbar, "retrieving ASCII string\n");
+
+	}
+	else if (lpnmh->code == TTN_GETDISPINFO32W) {
+	    LPNMTTDISPINFO32W lpdi = (LPNMTTDISPINFO32W)lParam;
+
+	    FIXME (toolbar, "retrieving UNICODE string\n");
+
+	}
+#endif
     }
 
     return 0;
@@ -2286,7 +2412,9 @@
 
 //	case TB_GETOBJECT:			/* 4.71 */
 //	case TB_GETPADDING:			/* 4.71 */
-//	case TB_GETRECT:			/* 4.70 */
+
+	case TB_GETRECT:
+	    return TOOLBAR_GetRect (wndPtr, wParam, lParam);
 
 	case TB_GETROWS:
 	    return TOOLBAR_GetRows (wndPtr, wParam, lParam);
@@ -2297,12 +2425,14 @@
 	case TB_GETSTYLE:
 	    return TOOLBAR_GetStyle (wndPtr, wParam, lParam);
 
-//	case TB_GETTEXTROWS:			/* 4.70 */
+	case TB_GETTEXTROWS:
+	    return TOOLBAR_GetTextRows (wndPtr, wParam, lParam);
 
 	case TB_GETTOOLTIPS:
 	    return TOOLBAR_GetToolTips (wndPtr, wParam, lParam);
 
-//	case TB_GETUNICODEFORMAT:
+	case TB_GETUNICODEFORMAT:
+	    return TOOLBAR_GetUnicodeFormat (wndPtr, wParam, lParam);
 
 	case TB_HIDEBUTTON:
 	    return TOOLBAR_HideButton (wndPtr, wParam, lParam);
@@ -2363,7 +2493,8 @@
 	case TB_SETBUTTONSIZE:
 	    return TOOLBAR_SetButtonSize (wndPtr, wParam, lParam);
 
-//	case TB_SETBUTTONWIDTH:			/* 4.70 */
+	case TB_SETBUTTONWIDTH:
+	    return TOOLBAR_SetButtonWidth (wndPtr, wParam, lParam);
 
 	case TB_SETCMDID:
 	    return TOOLBAR_SetCmdId (wndPtr, wParam, lParam);
@@ -2394,7 +2525,9 @@
 	case TB_SETINSERTMARKCOLOR:
 	    return TOOLBAR_SetInsertMarkColor (wndPtr, wParam, lParam);
 
-//	case TB_SETMAXTEXTROWS:			/* 4.70 */
+	case TB_SETMAXTEXTROWS:
+	    return TOOLBAR_SetMaxTextRows (wndPtr, wParam, lParam);
+
 //	case TB_SETPADDING:			/* 4.71 */
 
 	case TB_SETPARENT:
diff --git a/controls/tooltips.c b/controls/tooltips.c
index e0e8477..baf6971 100644
--- a/controls/tooltips.c
+++ b/controls/tooltips.c
@@ -4,24 +4,18 @@
  * Copyright 1998 Eric Kohl
  *
  * TODO:
- *   - Subclassing.
  *   - Tracking tooltips (under construction).
  *   - TTS_ALWAYSTIP (undefined).
  *   - Unicode support.
  *   - Custom draw support.
+ *   - The "lParam" variable from NMTTDISPINFO32A is not handled
+ *     in TOOLTIPS_GetTipText.
  *
  * Testing:
  *   - Run tests using Waite Group Windows95 API Bible Volume 2.
  *     The second cdrom (chapter 3) contains executables activate.exe,
  *     curtool.exe, deltool.exe, enumtools.exe, getinfo.exe, getiptxt.exe,
  *     hittest.exe, needtext.exe, newrect.exe, updtext.exe and winfrpt.exe.
- *
- *   - Activate.exe, deltool.exe, enumtool.exe, getinfo.exe and getiptxt.exe
- *     are the only working examples, since subclassing is not implemented.
- *
- * Fixme:
- *   - The "lParam" variable from NMTTDISPINFO32A is not handled
- *     in TOOLTIPS_GetTipText.
  */
 
 #include "windows.h"
@@ -35,10 +29,15 @@
 #define ID_TIMER1  1    /* show delay timer */
 #define ID_TIMER2  2    /* auto pop timer */
 #define ID_TIMER3  3    /* tool leave timer */
+#define TT_SUBCLASS_PROP "CC32SubclassInfo"   /* property name of tooltip window handle */
 
 #define TOOLTIPS_GetInfoPtr(wndPtr) ((TOOLTIPS_INFO *)wndPtr->wExtra[0])
 
 
+LRESULT CALLBACK
+TOOLTIPS_SubclassProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam);
+
+
 static VOID
 TOOLTIPS_Refresh (WND *wndPtr, HDC32 hdc)
 {
@@ -91,8 +90,8 @@
 	    ttnmdi.lpszText = infoPtr->szTipText;
 
 	    TRACE (tooltips, "hdr.idFrom = %x\n", ttnmdi.hdr.idFrom);
-	    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
-			    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&ttnmdi);
+	    SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
+			    (WPARAM32)toolPtr->uId, (LPARAM)&ttnmdi);
 
 	    if (ttnmdi.hinst) {
 		LoadString32A (ttnmdi.hinst, (UINT32)ttnmdi.szText,
@@ -195,17 +194,17 @@
 	return;
     }
 
-    TRACE (tooltips, "Show tooltip %d!\n", infoPtr->nTool);
+    TRACE (tooltips, "Show tooltip %d!\n", infoPtr->nCurrentTool);
+    toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
 
     hdr.hwndFrom = wndPtr->hwndSelf;
-    hdr.idFrom = infoPtr->nTool;
+    hdr.idFrom = toolPtr->uId;
     hdr.code = TTN_SHOW;
-    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
-		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&hdr);
+    SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
+		    (WPARAM32)toolPtr->uId, (LPARAM)&hdr);
 
     TRACE (tooltips, "\"%s\"\n", infoPtr->szTipText);
 
-    toolPtr = &infoPtr->tools[infoPtr->nTool];
     TOOLTIPS_CalcTipSize (wndPtr, infoPtr, &size);
     TRACE (tooltips, "size %d - %d\n", size.cx, size.cy);
 
@@ -232,9 +231,8 @@
 
     TRACE (tooltips, "pos %d - %d\n", pt.x, pt.y);
 
-//    SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, pt.x, pt.y,
-//		    size.cx, size.cy, SWP_SHOWWINDOW);
-    SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 1, 1,
+//    SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 1, 1,
+    SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, pt.x, pt.y,
 		    size.cx, size.cy, SWP_SHOWWINDOW);
 
     SetTimer32 (wndPtr->hwndSelf, ID_TIMER2, infoPtr->nAutoPopTime, 0);
@@ -244,19 +242,21 @@
 static VOID
 TOOLTIPS_Hide (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
 {
+    TTTOOL_INFO *toolPtr;
     NMHDR hdr;
 
     if (infoPtr->nCurrentTool == -1)
 	return;
 
+    toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
     TRACE (tooltips, "Hide tooltip %d!\n", infoPtr->nCurrentTool);
     KillTimer32 (wndPtr->hwndSelf, ID_TIMER2);
 
     hdr.hwndFrom = wndPtr->hwndSelf;
-    hdr.idFrom = infoPtr->nCurrentTool;
+    hdr.idFrom = toolPtr->uId;
     hdr.code = TTN_POP;
-    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
-		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&hdr);
+    SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
+		    (WPARAM32)toolPtr->uId, (LPARAM)&hdr);
 
     infoPtr->nCurrentTool = -1;
 
@@ -270,22 +270,6 @@
     TTTOOL_INFO *toolPtr;
     INT32 nTool;
 
-#if 0
-    for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
-	toolPtr = &infoPtr->tools[nTool];
-
-	if (toolPtr->uFlags & TTF_IDISHWND) {
-	    if (lpToolInfo->uId == toolPtr->uId)
-		return nTool;
-	}
-	else {
-	    if ((lpToolInfo->hwnd == toolPtr->hwnd) &&
-		(lpToolInfo->uId == toolPtr->uId))
-		return nTool;
-	}
-    }
-#endif
-
     for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
 	toolPtr = &infoPtr->tools[nTool];
 
@@ -316,11 +300,7 @@
     for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
 	toolPtr = &infoPtr->tools[nTool];
 
-	if (toolPtr->uFlags & TTF_IDISHWND) {
-	    if ((HWND32)toolPtr->uId == hwnd)
-		return nTool;
-	}
-	else {
+	if (!(toolPtr->uFlags & TTF_IDISHWND)) {
 	    if (hwnd != toolPtr->hwnd)
 		continue;
 	    if (!PtInRect32 (&toolPtr->rect, *lpPt))
@@ -329,10 +309,34 @@
 	}
     }
 
+    for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
+	toolPtr = &infoPtr->tools[nTool];
+
+	if (toolPtr->uFlags & TTF_IDISHWND) {
+	    if ((HWND32)toolPtr->uId == hwnd)
+		return nTool;
+	}
+    }
+
     return -1;
 }
 
 
+static INT32
+TOOLTIPS_GetToolFromMessage (TOOLTIPS_INFO *infoPtr, HWND32 hwndTool)
+{
+    DWORD   dwPos;
+    POINT32 pt;
+
+    dwPos = GetMessagePos ();
+    pt.x = (INT32)LOWORD(dwPos);
+    pt.y = (INT32)HIWORD(dwPos);
+    ScreenToClient32 (hwndTool, &pt);
+
+    return TOOLTIPS_GetToolFromPoint (infoPtr, hwndTool, &pt);
+}
+
+
 static BOOL32
 TOOLTIPS_CheckTool (WND *wndPtr)
 {
@@ -381,9 +385,6 @@
 
     if (lpToolInfo == NULL) return FALSE;
 
-    if (lpToolInfo->uFlags & TTF_SUBCLASS)
-	FIXME (tooltips, "subclassing not supported!\n");
-
     TRACE (tooltips, "add tool (%x) %x %d%s!\n",
 	   wndPtr->hwndSelf, lpToolInfo->hwnd, lpToolInfo->uId,
 	   (lpToolInfo->uFlags & TTF_IDISHWND) ? " TTF_IDISHWND" : "");
@@ -435,6 +436,44 @@
     if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32A))
 	toolPtr->lParam = lpToolInfo->lParam;
 
+    /* install subclassing */
+    if (toolPtr->uFlags & TTF_SUBCLASS) {
+	if (toolPtr->uFlags & TTF_IDISHWND) {
+	    LPTT_SUBCLASS_INFO lpttsi =
+		(LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP);
+	    if (lpttsi == NULL) {
+		lpttsi = (LPTT_SUBCLASS_INFO)HeapAlloc (GetProcessHeap(),
+		    HEAP_ZERO_MEMORY, sizeof(TT_SUBCLASS_INFO));
+		lpttsi->wpOrigProc = 
+		    (WNDPROC32)SetWindowLong32A ((HWND32)toolPtr->uId,
+		    GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc);
+		lpttsi->hwndToolTip = wndPtr->hwndSelf;
+		lpttsi->uRefCount++;
+		SetProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP,
+			    (HANDLE32)lpttsi);
+	    }
+	    else
+		ERR (tooltips, "A window tool must only be listed once!\n");
+	}
+	else {
+	    LPTT_SUBCLASS_INFO lpttsi =
+		(LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, TT_SUBCLASS_PROP);
+	    if (lpttsi == NULL) {
+		lpttsi = (LPTT_SUBCLASS_INFO)HeapAlloc (GetProcessHeap(),
+		    HEAP_ZERO_MEMORY, sizeof(TT_SUBCLASS_INFO));
+		lpttsi->wpOrigProc = 
+		    (WNDPROC32)SetWindowLong32A (toolPtr->hwnd,
+		    GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc);
+		lpttsi->hwndToolTip = wndPtr->hwndSelf;
+		lpttsi->uRefCount++;
+		SetProp32A (toolPtr->hwnd, TT_SUBCLASS_PROP, (HANDLE32)lpttsi);
+	    }
+	    else
+		lpttsi->uRefCount++;
+	}
+	TRACE (tooltips, "subclassing installed!\n");
+    }
+
     return TRUE;
 }
 
@@ -465,6 +504,38 @@
 	    HeapFree (GetProcessHeap (), 0, toolPtr->lpszText);
     }
 
+    /* remove subclassing */
+    if (toolPtr->uFlags & TTF_SUBCLASS) {
+	if (toolPtr->uFlags & TTF_IDISHWND) {
+	    LPTT_SUBCLASS_INFO lpttsi =
+		(LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP);
+	    if (lpttsi) {
+		SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
+				  (LONG)lpttsi->wpOrigProc);
+		RemoveProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP);
+		HeapFree (GetProcessHeap(), 0, &lpttsi);
+	    }
+	    else
+		ERR (tooltips, "Invalid data handle!\n");
+	}
+	else {
+	    LPTT_SUBCLASS_INFO lpttsi =
+		(LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, TT_SUBCLASS_PROP);
+	    if (lpttsi) {
+		if (lpttsi->uRefCount == 1) {
+		    SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
+				      (LONG)lpttsi->wpOrigProc);
+		    RemoveProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP);
+		    HeapFree (GetProcessHeap(), 0, &lpttsi);
+		}
+		else
+		    lpttsi->uRefCount--;
+	    }
+	    else
+		ERR (tooltips, "Invalid data handle!\n");
+	}
+    }
+
     /* delete tool from tool list */
     if (infoPtr->uNumTools == 1) {
 	HeapFree (GetProcessHeap (), 0, infoPtr->tools);
@@ -734,7 +805,9 @@
     INT32 nTool;
 
     if (!(lpti)) return 0;
+#if 0
     if (lpti->cbSize < sizeof(TTTOOLINFO32A)) return 0;
+#endif
 
     nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpti);
     if (nTool == -1) return 0;
@@ -766,17 +839,11 @@
     LPMSG32 lpMsg = (LPMSG32)lParam;
     POINT32 pt;
 
-    if (lpMsg == NULL) {
+    if (lParam == NULL) {
 	ERR (tooltips, "lpMsg == NULL!\n");
 	return 0;
     }
 
-    pt = lpMsg->pt;
-    ScreenToClient32 (lpMsg->hwnd, &pt);
-    infoPtr->nOldTool = infoPtr->nTool;
-    infoPtr->nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lpMsg->hwnd, &pt);
-    TRACE (tooltips, "tool (%x) %d %d\n", wndPtr->hwndSelf, infoPtr->nOldTool, infoPtr->nTool);
-
     switch (lpMsg->message) {
 	case WM_LBUTTONDOWN:
 	case WM_LBUTTONUP:
@@ -784,10 +851,22 @@
 	case WM_MBUTTONUP:
 	case WM_RBUTTONDOWN:
 	case WM_RBUTTONUP:
+	    pt = lpMsg->pt;
+	    ScreenToClient32 (lpMsg->hwnd, &pt);
+	    infoPtr->nOldTool = infoPtr->nTool;
+	    infoPtr->nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lpMsg->hwnd, &pt);
+	    TRACE (tooltips, "tool (%x) %d %d\n",
+		   wndPtr->hwndSelf, infoPtr->nOldTool, infoPtr->nTool);
 	    TOOLTIPS_Hide (wndPtr, infoPtr);
 	    break;
 
 	case WM_MOUSEMOVE:
+	    pt = lpMsg->pt;
+	    ScreenToClient32 (lpMsg->hwnd, &pt);
+	    infoPtr->nOldTool = infoPtr->nTool;
+	    infoPtr->nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lpMsg->hwnd, &pt);
+	    TRACE (tooltips, "tool (%x) %d %d\n",
+		   wndPtr->hwndSelf, infoPtr->nOldTool, infoPtr->nTool);
 	    TRACE (tooltips, "WM_MOUSEMOVE (%04x %d %d)\n",
 		   wndPtr->hwndSelf, pt.x, pt.y);
 	    if ((infoPtr->bActive) && (infoPtr->nTool != infoPtr->nOldTool)) {
@@ -1103,14 +1182,33 @@
 TOOLTIPS_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
+    TTTOOL_INFO *toolPtr;
 
     /* free tools */
     if (infoPtr->tools) {
 	INT32 i;
 	for (i = 0; i < infoPtr->uNumTools; i++) {
-	    if ((infoPtr->tools[i].hinst) && (infoPtr->tools[i].lpszText)) {
-		if (infoPtr->tools[i].lpszText != LPSTR_TEXTCALLBACK32A)
-		    HeapFree (GetProcessHeap (), 0, infoPtr->tools[i].lpszText);
+	    toolPtr = &infoPtr->tools[i];
+	    if ((toolPtr->hinst) && (toolPtr->lpszText)) {
+		if (toolPtr->lpszText != LPSTR_TEXTCALLBACK32A)
+		    HeapFree (GetProcessHeap (), 0, toolPtr->lpszText);
+	    }
+
+	    /* remove subclassing */
+	    if (toolPtr->uFlags & TTF_SUBCLASS) {
+		LPTT_SUBCLASS_INFO lpttsi;
+
+		if (toolPtr->uFlags & TTF_IDISHWND)
+		    lpttsi = (LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP);
+		else
+		    lpttsi = (LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, TT_SUBCLASS_PROP);
+
+		if (lpttsi) {
+		    SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
+				      (LONG)lpttsi->wpOrigProc);
+		    RemoveProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP);
+		    HeapFree (GetProcessHeap(), 0, &lpttsi);
+		}
 	    }
 	}
 	HeapFree (GetProcessHeap (), 0, infoPtr->tools);
@@ -1249,8 +1347,72 @@
 }
 
 
-LRESULT WINAPI
-ToolTipsWindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
+LRESULT CALLBACK
+TOOLTIPS_SubclassProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
+{
+    LPTT_SUBCLASS_INFO lpttsi =
+	(LPTT_SUBCLASS_INFO)GetProp32A (hwnd, TT_SUBCLASS_PROP);
+    WND *wndPtr;
+    TOOLTIPS_INFO *infoPtr;
+    UINT32 nTool;
+
+    switch (uMsg) {
+	case WM_LBUTTONDOWN:
+	case WM_LBUTTONUP:
+	case WM_MBUTTONDOWN:
+	case WM_MBUTTONUP:
+	case WM_RBUTTONDOWN:
+	case WM_RBUTTONUP:
+	    {
+		wndPtr = WIN_FindWndPtr(lpttsi->hwndToolTip);
+		infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
+		nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd);
+
+		TRACE (tooltips, "subclassed mouse message %04x\n", uMsg);
+		infoPtr->nOldTool = infoPtr->nTool;
+		infoPtr->nTool = nTool;
+		TOOLTIPS_Hide (wndPtr, infoPtr);
+	    }
+	    break;
+
+	case WM_MOUSEMOVE:
+	    {
+		wndPtr = WIN_FindWndPtr(lpttsi->hwndToolTip);
+		infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
+		nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd);
+
+		TRACE (tooltips, "subclassed WM_MOUSEMOVE\n");
+		infoPtr->nOldTool = infoPtr->nTool;
+		infoPtr->nTool = nTool;
+
+		if ((infoPtr->bActive) &&
+		    (infoPtr->nTool != infoPtr->nOldTool)) {
+		    if (infoPtr->nOldTool == -1) {
+			SetTimer32 (wndPtr->hwndSelf, ID_TIMER1,
+				    infoPtr->nInitialTime, 0);
+			TRACE (tooltips, "timer 1 started!\n");
+		    }
+		    else {
+			TOOLTIPS_Hide (wndPtr, infoPtr);
+			SetTimer32 (wndPtr->hwndSelf, ID_TIMER1,
+				infoPtr->nReshowTime, 0);
+			TRACE (tooltips, "timer 2 started!\n");
+		    }
+		}
+		if (infoPtr->nCurrentTool != -1) {
+		    SetTimer32 (wndPtr->hwndSelf, ID_TIMER3, 100, 0);
+		    TRACE (tooltips, "timer 3 started!\n");
+		}
+	    }
+	    break;
+    }
+
+    return CallWindowProc32A (lpttsi->wpOrigProc, hwnd, uMsg, wParam, lParam);
+}
+
+
+LRESULT CALLBACK
+TOOLTIPS_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
 
@@ -1423,7 +1585,7 @@
 
     ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
     wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS;
-    wndClass.lpfnWndProc   = (WNDPROC32)ToolTipsWindowProc;
+    wndClass.lpfnWndProc   = (WNDPROC32)TOOLTIPS_WindowProc;
     wndClass.cbClsExtra    = 0;
     wndClass.cbWndExtra    = sizeof(TOOLTIPS_INFO *);
     wndClass.hCursor       = LoadCursor32A (0, IDC_ARROW32A);
diff --git a/debugger/stabs.c b/debugger/stabs.c
index f3d080b..8fb9c96 100644
--- a/debugger/stabs.c
+++ b/debugger/stabs.c
@@ -1075,7 +1075,7 @@
 		goto leave;
 	}
 	free(fn);
-	if (t) s = t+1;
+	if (t) s = t+1; else break;
       }
       if (!s || !*s) fprintf(stderr," not found");
       free(paths);
diff --git a/dlls/Makefile.in b/dlls/Makefile.in
new file mode 100644
index 0000000..efbafbc
--- /dev/null
+++ b/dlls/Makefile.in
@@ -0,0 +1,21 @@
+SUBDIRS = \
+	shell32
+
+all: $(SUBDIRS)
+
+$(SUBDIRS): dummy
+	@cd $@; $(MAKE)
+
+depend:
+	for i in $(SUBDIRS); do (cd $$i; $(MAKE) depend) || exit 1; done
+
+install:
+	for i in $(SUBDIRS); do (cd $$i; $(MAKE) install) || exit 1; done
+
+uninstall:
+	for i in $(SUBDIRS); do (cd $$i; $(MAKE) uninstall) || exit 1; done
+
+clean:
+	for i in $(SUBDIRS); do (cd $$i; $(MAKE) clean) || exit 1; done
+
+dummy:
diff --git a/dlls/shell32/Makefile.in b/dlls/shell32/Makefile.in
new file mode 100644
index 0000000..59a0004
--- /dev/null
+++ b/dlls/shell32/Makefile.in
@@ -0,0 +1,30 @@
+DEFS      = @DLLFLAGS@ -D__WINE__
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+MODULE    = shell32
+WRCEXTRA  = -A -p $*
+
+C_SRCS = \
+	contmenu.c \
+	enumidlist.c \
+	folders.c \
+	pidl.c \
+	shell32_main.c \
+	shellole.c \
+	shellord.c \
+	shlfolder.c \
+	shlview.c
+
+RC_SRCS = \
+	shres.rc
+
+all: check_wrc $(MODULE).o
+
+@MAKE_RULES@
+
+$(RC_SRCS:.rc=.s): $(WRC)
+
+### Dependencies:
+
diff --git a/dlls/shell32/contmenu.c b/dlls/shell32/contmenu.c
new file mode 100644
index 0000000..52ce253
--- /dev/null
+++ b/dlls/shell32/contmenu.c
@@ -0,0 +1,383 @@
+/*
+ *	IContextMenu
+ *
+ *	Copyright 1998	Juergen Schmied <juergen.schmied@metronet.de>
+ */
+#include "windows.h"
+#include "winerror.h"
+#include "debug.h"
+#include "shlobj.h"
+#include "shell32_main.h"
+
+#define IDM_EXPLORE  0
+#define IDM_OPEN     1
+#define IDM_RENAME   2
+#define IDM_LAST     IDM_RENAME
+
+#define __T(x)      x
+#define _T(x)       __T(x)
+#define TEXT        _T
+
+static HRESULT WINAPI IContextMenu_QueryInterface(LPCONTEXTMENU ,REFIID , LPVOID *);
+static ULONG WINAPI IContextMenu_AddRef(LPCONTEXTMENU);
+static ULONG WINAPI IContextMenu_Release(LPCONTEXTMENU);
+static HRESULT WINAPI IContextMenu_QueryContextMenu(LPCONTEXTMENU , HMENU32 ,UINT32 ,UINT32 ,UINT32 ,UINT32);
+static HRESULT WINAPI IContextMenu_InvokeCommand(LPCONTEXTMENU, LPCMINVOKECOMMANDINFO);
+static HRESULT WINAPI IContextMenu_GetCommandString(LPCONTEXTMENU , UINT32 ,UINT32 ,LPUINT32 ,LPSTR ,UINT32);
+
+BOOL32 IContextMenu_AllocPidlTable(LPCONTEXTMENU, DWORD);
+void IContextMenu_FreePidlTable(LPCONTEXTMENU);
+BOOL32 IContextMenu_CanRenameItems(LPCONTEXTMENU);
+BOOL32 IContextMenu_FillPidlTable(LPCONTEXTMENU, LPCITEMIDLIST *, UINT32);
+
+static struct IContextMenu_VTable cmvt = 
+{	IContextMenu_QueryInterface,
+	IContextMenu_AddRef,
+    IContextMenu_Release,
+	IContextMenu_QueryContextMenu,
+	IContextMenu_InvokeCommand,
+	IContextMenu_GetCommandString
+};
+/**************************************************************************
+*  IContextMenu_QueryInterface
+*/
+static HRESULT WINAPI IContextMenu_QueryInterface(LPCONTEXTMENU this,REFIID riid, LPVOID *ppvObj)
+{ char    xriid[50];
+  WINE_StringFromCLSID((LPCLSID)riid,xriid);
+  TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);
+
+  *ppvObj = NULL;
+
+  if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
+  { *ppvObj = (LPUNKNOWN)(LPCONTEXTMENU)this; 
+  }
+  else if(IsEqualIID(riid, &IID_IContextMenu))  /*IContextMenu*/
+  { *ppvObj = (LPCONTEXTMENU)this;
+  }   
+  else if(IsEqualIID(riid, &IID_IShellExtInit))  /*IShellExtInit*/
+  { *ppvObj = (LPSHELLEXTINIT)this;
+  }   
+
+  if(*ppvObj)
+  { (*(LPCONTEXTMENU*)ppvObj)->lpvtbl->fnAddRef(this);      
+    TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
+    return S_OK;
+  }
+  TRACE(shell,"-- Interface: E_NOINTERFACE\n");
+  return E_NOINTERFACE;
+}   
+
+/**************************************************************************
+*  IContextMenu_AddRef
+*/
+static ULONG WINAPI IContextMenu_AddRef(LPCONTEXTMENU this)
+{ TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
+  return ++(this->ref);
+}
+/**************************************************************************
+*  IContextMenu_Release
+*/
+static ULONG WINAPI IContextMenu_Release(LPCONTEXTMENU this)
+{ TRACE(shell,"(%p)->()\n",this);
+  if (!--(this->ref)) 
+  { TRACE(shell," destroying IContextMenu(%p)\n",this);
+
+	if(this->pSFParent)
+	  this->pSFParent->lpvtbl->fnRelease(this->pSFParent);
+
+	/*make sure the pidl is freed*/
+	if(this->aPidls)
+	{ IContextMenu_FreePidlTable(this);
+	}
+
+	if(this->pPidlMgr)
+   	  PidlMgr_Destructor(this->pPidlMgr);
+
+    HeapFree(GetProcessHeap(),0,this);
+    return 0;
+  }
+  return this->ref;
+}
+
+/**************************************************************************
+*   IContextMenu_Constructor()
+*/
+LPCONTEXTMENU IContextMenu_Constructor(LPSHELLFOLDER pSFParent, LPCITEMIDLIST *aPidls, UINT32 uItemCount)
+{	LPCONTEXTMENU cm;
+	UINT32  u;
+    
+	cm = (LPCONTEXTMENU)HeapAlloc(GetProcessHeap(),0,sizeof(IContextMenu));
+	cm->lpvtbl=&cmvt;
+	cm->ref = 1;
+
+	cm->pSFParent = pSFParent;
+	if(cm->pSFParent)
+	   cm->pSFParent->lpvtbl->fnAddRef(cm->pSFParent);
+
+	cm->aPidls = NULL;
+	cm->pPidlMgr = PidlMgr_Constructor();
+
+	IContextMenu_AllocPidlTable(cm, uItemCount);
+    
+	if(cm->aPidls)
+	{ IContextMenu_FillPidlTable(cm, aPidls, uItemCount);
+	}
+
+	cm->bAllValues = 1;
+	for(u = 0; u < uItemCount; u++)
+    { cm->bAllValues &= (cm->pPidlMgr->lpvtbl->fnIsValue(cm->pPidlMgr, aPidls[u]) ? 1 : 0);
+	}
+    TRACE(shell,"(%p)->()\n",cm);
+    return cm;
+}
+
+
+/**************************************************************************
+* IContextMenu_QueryContextMenu()
+*/
+
+static HRESULT WINAPI  IContextMenu_QueryContextMenu( LPCONTEXTMENU this, HMENU32 hmenu,
+							UINT32 indexMenu,UINT32 idCmdFirst,UINT32 idCmdLast,UINT32 uFlags)
+{	BOOL32			fExplore ;
+	MENUITEMINFO32A	mii;
+
+	TRACE(shell,"(%p)->(hmenu=%x indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n",this, hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
+	if(!(CMF_DEFAULTONLY & uFlags))
+	{ if(!this->bAllValues)
+      { fExplore = uFlags & CMF_EXPLORE;
+        if(fExplore)
+        { ZeroMemory(&mii, sizeof(mii));
+          mii.cbSize = sizeof(mii);
+          mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
+          mii.wID = idCmdFirst + IDM_EXPLORE;
+          mii.fType = MFT_STRING;
+          mii.dwTypeData = TEXT("&Explore");
+          mii.fState = MFS_ENABLED | MFS_DEFAULT;
+          InsertMenuItem32A( hmenu, indexMenu++, TRUE, &mii);
+
+          ZeroMemory(&mii, sizeof(mii));
+          mii.cbSize = sizeof(mii);
+          mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
+          mii.wID = idCmdFirst + IDM_OPEN;
+          mii.fType = MFT_STRING;
+          mii.dwTypeData = TEXT("&Open");
+          mii.fState = MFS_ENABLED;
+          InsertMenuItem32A( hmenu, indexMenu++, TRUE, &mii);
+        }
+        else
+        { ZeroMemory(&mii, sizeof(mii));
+          mii.cbSize = sizeof(mii);
+          mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
+          mii.wID = idCmdFirst + IDM_OPEN;
+          mii.fType = MFT_STRING;
+          mii.dwTypeData = TEXT("&Open");
+          mii.fState = MFS_ENABLED | MFS_DEFAULT;
+          InsertMenuItem32A( hmenu, indexMenu++, TRUE, &mii);
+
+          ZeroMemory(&mii, sizeof(mii));
+          mii.cbSize = sizeof(mii);
+          mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
+          mii.wID = idCmdFirst + IDM_EXPLORE;
+          mii.fType = MFT_STRING;
+          mii.dwTypeData = TEXT("&Explore");
+          mii.fState = MFS_ENABLED;
+          InsertMenuItem32A( hmenu, indexMenu++, TRUE, &mii);
+        }
+
+        if(uFlags & CMF_CANRENAME)
+        { ZeroMemory(&mii, sizeof(mii));
+          mii.cbSize = sizeof(mii);
+          mii.fMask = MIIM_ID | MIIM_TYPE;
+          mii.wID = 0;
+          mii.fType = MFT_SEPARATOR;
+          InsertMenuItem32A( hmenu, indexMenu++, TRUE, &mii);
+ 
+          ZeroMemory(&mii, sizeof(mii));
+          mii.cbSize = sizeof(mii);
+          mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
+          mii.wID = idCmdFirst + IDM_RENAME;
+          mii.fType = MFT_STRING;
+          mii.dwTypeData = TEXT("&Rename");
+          mii.fState = (IContextMenu_CanRenameItems(this) ? MFS_ENABLED : MFS_DISABLED);
+          InsertMenuItem32A( hmenu, indexMenu++, TRUE, &mii);
+        }
+      }
+      return MAKE_HRESULT(SEVERITY_SUCCESS, 0, (IDM_LAST + 1));
+    }
+	return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 0);
+}
+
+/**************************************************************************
+* IContextMenu_InvokeCommand()
+*/
+static HRESULT WINAPI IContextMenu_InvokeCommand(LPCONTEXTMENU this, LPCMINVOKECOMMANDINFO lpcmi)
+{	LPITEMIDLIST      pidlTemp,pidlFQ;
+	SHELLEXECUTEINFO  sei;
+	int   i;
+
+ 	TRACE(shell,"(%p)->(execinfo=%p)\n",this,lpcmi);    
+
+	if(HIWORD(lpcmi->lpVerb))
+	{ //the command is being sent via a verb
+	  return NOERROR;
+	}
+
+	if(LOWORD(lpcmi->lpVerb) > IDM_LAST)
+	  return E_INVALIDARG;
+
+	switch(LOWORD(lpcmi->lpVerb))
+	{ case IDM_EXPLORE:
+	  case IDM_OPEN:
+        /* Find the first item in the list that is not a value. These commands 
+      	should never be invoked if there isn't at least one key item in the list.*/
+
+        for(i = 0; this->aPidls[i]; i++)
+	    { if(!this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr, this->aPidls[i]))
+            break;
+        }
+      
+		pidlTemp = ILCombine(this->pSFParent->mpidl, this->aPidls[i]);
+		pidlFQ = ILCombine(this->pSFParent->mpidlNSRoot, pidlTemp);
+		SHFree(pidlTemp);
+      
+		ZeroMemory(&sei, sizeof(sei));
+		sei.cbSize = sizeof(sei);
+		sei.fMask = SEE_MASK_IDLIST | SEE_MASK_CLASSNAME;
+		sei.lpIDList = pidlFQ;
+		sei.lpClass = TEXT("folder");
+		sei.hwnd = lpcmi->hwnd;
+		sei.nShow = SW_SHOWNORMAL;
+      
+		if(LOWORD(lpcmi->lpVerb) == IDM_EXPLORE)
+	    { sei.lpVerb = TEXT("explore");
+        }
+		else
+        { sei.lpVerb = TEXT("open");
+        }
+        ShellExecuteEx32A(&sei);
+		SHFree(pidlFQ);
+        break;
+
+	  case IDM_RENAME:
+        MessageBeep32(MB_OK);
+        /*handle rename for the view here*/
+        break;
+   	}
+	return NOERROR;
+}
+
+/**************************************************************************
+*  IContextMenu_GetCommandString()
+*/
+static HRESULT WINAPI IContextMenu_GetCommandString( LPCONTEXTMENU this, UINT32 idCommand,
+						UINT32 uFlags,LPUINT32 lpReserved,LPSTR lpszName,UINT32 uMaxNameLen)
+{	HRESULT  hr = E_INVALIDARG;
+
+	TRACE(shell,"(%p)->(idcom=%x flags=%x %p name=%s len=%x)\n",this, idCommand, uFlags, lpReserved, lpszName, uMaxNameLen);
+
+ 	switch(uFlags)
+	{ case GCS_HELPTEXT:
+        hr = E_NOTIMPL;
+        break;
+   
+	  case GCS_VERBA:
+        switch(idCommand)
+        { case IDM_RENAME:
+            strcpy((LPSTR)lpszName, "rename");
+            hr = NOERROR;
+            break;
+        }
+        break;
+
+   /* NT 4.0 with IE 3.0x or no IE will always call this with GCS_VERBW. In this 
+   case, you need to do the lstrcpyW to the pointer passed.*/
+	  case GCS_VERBW:
+        switch(idCommand)
+        { case IDM_RENAME:
+            lstrcpyAtoW((LPWSTR)lpszName, "rename");
+            hr = NOERROR;
+            break;
+        }
+        break;
+
+	  case GCS_VALIDATE:
+        hr = NOERROR;
+        break;
+	}
+	return hr;
+}
+
+/**************************************************************************
+*  IContextMenu_AllocPidlTable()
+*/
+BOOL32 IContextMenu_AllocPidlTable(LPCONTEXTMENU this, DWORD dwEntries)
+{	//add one for NULL terminator
+	TRACE(shell,"(%p)->(entrys=%u)\n",this, dwEntries);
+	dwEntries++;
+
+	this->aPidls = (LPITEMIDLIST*)SHAlloc(dwEntries * sizeof(LPITEMIDLIST));
+
+	if(this->aPidls)
+	{ ZeroMemory(this->aPidls, dwEntries * sizeof(LPITEMIDLIST));	/*set all of the entries to NULL*/
+	}
+	return (this->aPidls != NULL);
+}
+
+/**************************************************************************
+* IContextMenu_FreePidlTable()
+*/
+void IContextMenu_FreePidlTable(LPCONTEXTMENU this)
+{   int   i;
+
+	TRACE(shell,"(%p)->()\n",this);
+
+	if(this->aPidls)
+	{ for(i = 0; this->aPidls[i]; i++)
+      { SHFree(this->aPidls[i]);
+      }
+   
+	SHFree(this->aPidls);
+	this->aPidls = NULL;
+	}
+}
+
+/**************************************************************************
+* IContextMenu_FillPidlTable()
+*/
+BOOL32 IContextMenu_FillPidlTable(LPCONTEXTMENU this, LPCITEMIDLIST *aPidls, UINT32 uItemCount)
+{   UINT32  i;
+	TRACE(shell,"(%p)->(apidl=%p count=%u)\n",this, aPidls, uItemCount);
+	if(this->aPidls)
+	{ for(i = 0; i < uItemCount; i++)
+      { this->aPidls[i] = ILClone(aPidls[i]);
+      }
+      return TRUE;
+ 	}
+	return FALSE;
+}
+
+/**************************************************************************
+* IContextMenu_CanRenameItems()
+*/
+BOOL32 IContextMenu_CanRenameItems(LPCONTEXTMENU this)
+{	UINT32  i;
+	DWORD dwAttributes;
+
+	TRACE(shell,"(%p)->()\n",this);
+
+	if(this->aPidls)
+	{ if(this->pPidlMgr)
+	  { for(i = 0; this->aPidls[i]; i++){} /*get the number of items assigned to this object*/
+        if(i > 1)	/*you can't rename more than one item at a time*/
+        { return FALSE;
+        }
+	    dwAttributes = SFGAO_CANRENAME;
+	    this->pSFParent->lpvtbl->fnGetAttributesOf(this->pSFParent, i,
+        						 (LPCITEMIDLIST*)this->aPidls, &dwAttributes);
+      
+      return dwAttributes & SFGAO_CANRENAME;
+      }
+	}	
+	return FALSE;
+}
+
diff --git a/dlls/shell32/enumidlist.c b/dlls/shell32/enumidlist.c
new file mode 100644
index 0000000..4afff0c
--- /dev/null
+++ b/dlls/shell32/enumidlist.c
@@ -0,0 +1,357 @@
+/*
+ *	IEnumIDList
+ *
+ *	Copyright 1998	Juergen Schmied <juergen.schmied@metronet.de>
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ole.h"
+#include "ole2.h"
+#include "debug.h"
+#include "compobj.h"
+#include "interfaces.h"
+#include "shlobj.h"
+#include "shell.h"
+#include "winerror.h"
+#include "winnls.h"
+#include "winproc.h"
+#include "commctrl.h"
+
+#include "shell32_main.h"
+
+/* IEnumIDList Implementation */
+static HRESULT WINAPI IEnumIDList_QueryInterface(LPENUMIDLIST,REFIID,LPVOID*);
+static ULONG WINAPI IEnumIDList_AddRef(LPENUMIDLIST);
+static ULONG WINAPI IEnumIDList_Release(LPENUMIDLIST);
+static HRESULT WINAPI IEnumIDList_Next(LPENUMIDLIST,ULONG,LPITEMIDLIST*,ULONG*);
+static HRESULT WINAPI IEnumIDList_Skip(LPENUMIDLIST,ULONG);
+static HRESULT WINAPI IEnumIDList_Reset(LPENUMIDLIST);
+static HRESULT WINAPI IEnumIDList_Clone(LPENUMIDLIST,LPENUMIDLIST*);
+static BOOL32 WINAPI IEnumIDList_CreateEnumList(LPENUMIDLIST,LPCSTR, DWORD);
+static BOOL32 WINAPI IEnumIDList_AddToEnumList(LPENUMIDLIST,LPITEMIDLIST);
+static BOOL32 WINAPI IEnumIDList_DeleteList(LPENUMIDLIST);
+
+/**************************************************************************
+ *  IEnumIDList_VTable
+ */
+static IEnumIDList_VTable eidlvt = 
+{ IEnumIDList_QueryInterface,
+  IEnumIDList_AddRef,
+  IEnumIDList_Release,
+  IEnumIDList_Next,
+  IEnumIDList_Skip,
+  IEnumIDList_Reset,
+  IEnumIDList_Clone,
+  IEnumIDList_CreateEnumList,
+  IEnumIDList_AddToEnumList,
+  IEnumIDList_DeleteList
+};
+
+/**************************************************************************
+ *  IEnumIDList_Constructor
+ */
+
+LPENUMIDLIST IEnumIDList_Constructor( LPCSTR lpszPath, DWORD dwFlags, HRESULT* pResult)
+{	LPENUMIDLIST	lpeidl;
+
+	lpeidl = (LPENUMIDLIST)HeapAlloc(GetProcessHeap(),0,sizeof(IEnumIDList));
+	lpeidl->ref = 1;
+	lpeidl->lpvtbl = &eidlvt;
+	lpeidl->mpFirst=NULL;
+	lpeidl->mpLast=NULL;
+	lpeidl->mpCurrent=NULL;
+
+  TRACE(shell,"(%p)->(%s 0x%08lx %p)\n",lpeidl,debugstr_a(lpszPath),dwFlags,pResult);
+
+	lpeidl->mpPidlMgr=PidlMgr_Constructor();
+  if (!lpeidl->mpPidlMgr)
+	{ if (pResult)
+	  { *pResult=E_OUTOFMEMORY;
+			HeapFree(GetProcessHeap(),0,lpeidl);
+			return NULL;
+		}
+	}
+
+	if(!IEnumIDList_CreateEnumList(lpeidl, lpszPath, dwFlags))
+  { if(pResult)
+    { *pResult = E_OUTOFMEMORY;
+			HeapFree(GetProcessHeap(),0,lpeidl->mpPidlMgr);
+			HeapFree(GetProcessHeap(),0,lpeidl);
+			return NULL;
+		}
+  }
+
+  TRACE(shell,"-- (%p)->()\n",lpeidl);
+	return lpeidl;
+}
+
+/**************************************************************************
+ *  EnumIDList::QueryInterface
+ */
+static HRESULT WINAPI IEnumIDList_QueryInterface(
+  LPENUMIDLIST this, REFIID riid, LPVOID *ppvObj)
+{  char	xriid[50];
+   WINE_StringFromCLSID((LPCLSID)riid,xriid);
+   TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);
+
+  *ppvObj = NULL;
+
+  if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
+  { *ppvObj = this; 
+  }
+  else if(IsEqualIID(riid, &IID_IEnumIDList))  /*IEnumIDList*/
+  {    *ppvObj = (IEnumIDList*)this;
+  }   
+
+  if(*ppvObj)
+  { (*(LPENUMIDLIST*)ppvObj)->lpvtbl->fnAddRef(this);  	
+    TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
+    return S_OK;
+  }
+	TRACE(shell,"-- Interface: E_NOINTERFACE\n");
+	return E_NOINTERFACE;
+}   
+
+/******************************************************************************
+ * IEnumIDList_AddRef
+ */
+static ULONG WINAPI IEnumIDList_AddRef(LPENUMIDLIST this)
+{ TRACE(shell,"(%p)->()\n",this);
+	return ++(this->ref);
+}
+/******************************************************************************
+ * IEnumIDList_Release
+ */
+static ULONG WINAPI IEnumIDList_Release(LPENUMIDLIST this)
+{	TRACE(shell,"(%p)->()\n",this);
+	if (!--(this->ref)) 
+	{ TRACE(shell," destroying IEnumIDList(%p)\n",this);
+		HeapFree(GetProcessHeap(),0,this);
+		return 0;
+	}
+	return this->ref;
+}
+   
+/**************************************************************************
+ *  IEnumIDList_Next
+ */
+
+static HRESULT WINAPI IEnumIDList_Next(
+	LPENUMIDLIST this,ULONG celt,LPITEMIDLIST * rgelt,ULONG *pceltFetched) 
+{ ULONG    i;
+  HRESULT  hr = S_OK;
+  LPITEMIDLIST  temp;
+
+	TRACE(shell,"(%p)->(%ld,%p, %p)\n",this,celt,rgelt,pceltFetched);
+
+  /* It is valid to leave pceltFetched NULL when celt is 1. Some of explorer's
+     subsystems actually use it (and so may a third party browser)
+   */
+  if(pceltFetched)
+    *pceltFetched = 0;
+
+	*rgelt=0;
+	
+  if(celt > 1 && !pceltFetched)
+  { return E_INVALIDARG;
+	}
+
+  for(i = 0; i < celt; i++)
+  { if(!(this->mpCurrent))
+    { hr =  S_FALSE;
+      break;
+    }
+    temp = ILClone(this->mpCurrent->pidl);
+    rgelt[i] = temp;
+    this->mpCurrent = this->mpCurrent->pNext;
+  }
+  if(pceltFetched)
+  {  *pceltFetched = i;
+	}
+
+  return hr;
+}
+
+/**************************************************************************
+*  IEnumIDList_Skip
+*/
+static HRESULT WINAPI IEnumIDList_Skip(
+	LPENUMIDLIST this,ULONG celt)
+{ DWORD    dwIndex;
+  HRESULT  hr = S_OK;
+
+  TRACE(shell,"(%p)->(%lu)\n",this,celt);
+
+  for(dwIndex = 0; dwIndex < celt; dwIndex++)
+  { if(!this->mpCurrent)
+    { hr = S_FALSE;
+      break;
+    }
+    this->mpCurrent = this->mpCurrent->pNext;
+  }
+  return hr;
+}
+/**************************************************************************
+*  IEnumIDList_Reset
+*/
+static HRESULT WINAPI IEnumIDList_Reset(LPENUMIDLIST this)
+{ TRACE(shell,"(%p)\n",this);
+  this->mpCurrent = this->mpFirst;
+  return S_OK;
+}
+/**************************************************************************
+*  IEnumIDList_Clone
+*/
+static HRESULT WINAPI IEnumIDList_Clone(
+	LPENUMIDLIST this,LPENUMIDLIST * ppenum)
+{ TRACE(shell,"(%p)->() to (%p)->() E_NOTIMPL\n",this,ppenum);
+	return E_NOTIMPL;
+}
+/**************************************************************************
+ *  EnumIDList_CreateEnumList()
+ *  fixme: devices not handled
+ *  fixme: add wildcards to path
+ */
+static BOOL32 WINAPI IEnumIDList_CreateEnumList(LPENUMIDLIST this, LPCSTR lpszPath, DWORD dwFlags)
+{ LPITEMIDLIST   pidl=NULL;
+  WIN32_FIND_DATA32A stffile;	
+  HANDLE32 hFile;
+  DWORD dwDrivemap;
+  CHAR  szDriveName[4];
+  CHAR  szPath[MAX_PATH];
+    
+  TRACE(shell,"(%p)->(%s 0x%08lx) \n",this,debugstr_a(lpszPath),dwFlags);
+
+  if (lpszPath && lpszPath[0]!='\0')
+  { strcpy(szPath, lpszPath);
+    PathAddBackslash(szPath);
+    strcat(szPath,"*.*");
+  }
+
+  /*enumerate the folders*/
+  if(dwFlags & SHCONTF_FOLDERS)
+  {	/* special case - we can't enumerate the Desktop level Objects (MyComputer,Nethood...
+    so we need to fake an enumeration of those.*/
+	  if(!lpszPath)
+    { TRACE (shell,"-- (%p)-> enumerate SHCONTF_FOLDERS (special) items\n",this);
+  		//create the pidl for this item
+      pidl = this->mpPidlMgr->lpvtbl->fnCreateMyComputer(this->mpPidlMgr);
+      if(pidl)
+      { if(!IEnumIDList_AddToEnumList(this, pidl))
+        return FALSE;
+      }
+    }   
+    else if (lpszPath[0]=='\0') /* enumerate the drives*/
+    { TRACE (shell,"-- (%p)-> enumerate SHCONTF_FOLDERS (drives)\n",this);
+      dwDrivemap = GetLogicalDrives();
+      strcpy (szDriveName,"A:\\");
+      while (szDriveName[0]<='Z')
+      { if(dwDrivemap & 0x00000001L)
+        { pidl = this->mpPidlMgr->lpvtbl->fnCreateDrive(this->mpPidlMgr,szDriveName );
+      if(pidl)
+      { if(!IEnumIDList_AddToEnumList(this, pidl))
+          return FALSE;
+      }
+      }
+        szDriveName[0]++;
+        dwDrivemap = dwDrivemap >> 1;
+     }   
+    }
+    
+     else
+    { TRACE (shell,"-- (%p)-> enumerate SHCONTF_FOLDERS of %s\n",this,debugstr_a(szPath));
+      hFile = FindFirstFile32A(szPath,&stffile);
+      if ( hFile != INVALID_HANDLE_VALUE32 )
+      { do
+        { if ( (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && strcmp (stffile.cFileName, ".") && strcmp (stffile.cFileName, ".."))
+          { pidl = this->mpPidlMgr->lpvtbl->fnCreateFolder(this->mpPidlMgr, stffile.cFileName);
+         if(pidl)
+         { if(!IEnumIDList_AddToEnumList(this, pidl))
+               {  return FALSE;
+               }
+         }
+         else
+         { return FALSE;
+         }   
+           }
+      } while( FindNextFile32A(hFile,&stffile));
+			FindClose32 (hFile);
+    }
+  }   
+  }   
+  //enumerate the non-folder items (values)
+  if(dwFlags & SHCONTF_NONFOLDERS)
+  { if(lpszPath)
+    { TRACE (shell,"-- (%p)-> enumerate SHCONTF_NONFOLDERS of %s\n",this,debugstr_a(szPath));
+      hFile = FindFirstFile32A(szPath,&stffile);
+      if ( hFile != INVALID_HANDLE_VALUE32 )
+      { do
+    { if (! (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
+          { pidl = this->mpPidlMgr->lpvtbl->fnCreateValue(this->mpPidlMgr, stffile.cFileName);
+      if(pidl)
+      { if(!IEnumIDList_AddToEnumList(this, pidl))
+        { return FALSE;
+			  }
+      }
+      else
+      { return FALSE;
+      }   
+          }
+    } while( FindNextFile32A(hFile,&stffile));
+	  FindClose32 (hFile);
+  } 
+    }
+  } 
+  return TRUE;
+}
+
+/**************************************************************************
+ *  EnumIDList_AddToEnumList()
+ */
+static BOOL32 WINAPI IEnumIDList_AddToEnumList(LPENUMIDLIST this,LPITEMIDLIST pidl)
+{ LPENUMLIST  pNew;
+
+  TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl);
+  pNew = (LPENUMLIST)HeapAlloc(GetProcessHeap(),0,sizeof(ENUMLIST));
+  if(pNew)
+  { //set the next pointer
+    pNew->pNext = NULL;
+    pNew->pidl = pidl;
+
+    //is this the first item in the list?
+    if(!this->mpFirst)
+    { this->mpFirst = pNew;
+      this->mpCurrent = pNew;
+    }
+   
+    if(this->mpLast)
+    { //add the new item to the end of the list
+      this->mpLast->pNext = pNew;
+    }
+   
+    //update the last item pointer
+    this->mpLast = pNew;
+    TRACE(shell,"-- (%p)->(first=%p, last=%p)\n",this,this->mpFirst,this->mpLast);
+    return TRUE;
+  }
+  return FALSE;
+}
+/**************************************************************************
+*   EnumIDList_DeleteList()
+*/
+static BOOL32 WINAPI IEnumIDList_DeleteList(LPENUMIDLIST this)
+{ LPENUMLIST  pDelete;
+
+  TRACE(shell,"(%p)->()\n",this);
+	
+  while(this->mpFirst)
+  { pDelete = this->mpFirst;
+    this->mpFirst = pDelete->pNext;
+    SHFree(pDelete->pidl);
+    SHFree(pDelete);
+  }
+  this->mpFirst = this->mpLast = this->mpCurrent = NULL;
+  return TRUE;
+}
diff --git a/dlls/shell32/folders.c b/dlls/shell32/folders.c
new file mode 100644
index 0000000..e9e078c
--- /dev/null
+++ b/dlls/shell32/folders.c
@@ -0,0 +1,224 @@
+/*
+ *	Shell Folder stuff (...and all the OLE-Objects of SHELL32.DLL)
+ *
+ *	Copyright 1997	Marcus Meissner
+ *	Copyright 1998	Juergen Schmied
+ *
+ *  !!! currently work in progress on all classes !!!
+ *  <contact juergen.schmied@metronet.de, 980801>
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ole.h"
+#include "ole2.h"
+#include "debug.h"
+#include "compobj.h"
+#include "interfaces.h"
+#include "shlobj.h"
+#include "shell.h"
+#include "winerror.h"
+#include "winnls.h"
+#include "winproc.h"
+#include "commctrl.h"
+
+#include "shell32_main.h"
+
+
+/******************************************************************************
+* foreward declaration
+*/
+
+/* IExtractIcon implementation*/
+static HRESULT WINAPI IExtractIcon_QueryInterface(LPEXTRACTICON, REFIID, LPVOID *);
+static ULONG WINAPI IExtractIcon_AddRef(LPEXTRACTICON);
+static ULONG WINAPI IExtractIcon_AddRef(LPEXTRACTICON);
+static ULONG WINAPI IExtractIcon_Release(LPEXTRACTICON);
+static HRESULT IExtractIcon_GetIconLocation(LPEXTRACTICON, UINT32, LPSTR, UINT32, int *, UINT32 *);
+static HRESULT IExtractIcon_Extract(LPEXTRACTICON, LPCSTR, UINT32, HICON32 *, HICON32 *, UINT32);
+
+/* IShellLink Implementation */
+static HRESULT WINAPI IShellLink_QueryInterface(LPSHELLLINK,REFIID,LPVOID*);
+static ULONG WINAPI IShellLink_AddRef(LPSHELLLINK);
+static ULONG WINAPI IShellLink_Release(LPSHELLLINK);
+
+
+/***********************************************************************
+*   IExtractIcon implementation
+*/
+static struct IExtractIcon_VTable eivt = 
+{ IExtractIcon_QueryInterface,
+  IExtractIcon_AddRef,
+  IExtractIcon_Release,
+  IExtractIcon_GetIconLocation,
+  IExtractIcon_Extract
+};
+/**************************************************************************
+*  IExtractIcon_Constructor
+*/
+LPEXTRACTICON IExtractIcon_Constructor(LPCITEMIDLIST pidl)
+{ LPEXTRACTICON ei;
+  ei=(LPEXTRACTICON)HeapAlloc(GetProcessHeap(),0,sizeof(IExtractIcon));
+  ei->ref=1;
+  ei->lpvtbl=&eivt;
+  ei->pidl=ILClone(pidl);
+  
+  TRACE(shell,"(%p)\n",ei);
+  return ei;
+}
+/**************************************************************************
+ *  IExtractIcon_QueryInterface
+ */
+static HRESULT WINAPI IExtractIcon_QueryInterface( LPEXTRACTICON this, REFIID riid, LPVOID *ppvObj)
+{  char	xriid[50];
+   WINE_StringFromCLSID((LPCLSID)riid,xriid);
+   TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);
+
+  *ppvObj = NULL;
+
+  if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
+  { *ppvObj = this; 
+  }
+  else if(IsEqualIID(riid, &IID_IExtractIcon))  /*IExtractIcon*/
+  {    *ppvObj = (IExtractIcon*)this;
+  }   
+
+  if(*ppvObj)
+  { (*(LPEXTRACTICON*)ppvObj)->lpvtbl->fnAddRef(this);  	
+    TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
+    return S_OK;
+  }
+	TRACE(shell,"-- Interface: E_NOINTERFACE\n");
+	return E_NOINTERFACE;
+}   
+
+/**************************************************************************
+*  IExtractIcon_AddRef
+*/
+static ULONG WINAPI IExtractIcon_AddRef(LPEXTRACTICON this)
+{ TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
+  return ++(this->ref);
+}
+/**************************************************************************
+*  IExtractIcon_Release
+*/
+static ULONG WINAPI IExtractIcon_Release(LPEXTRACTICON this)
+{ TRACE(shell,"(%p)->()\n",this);
+  if (!--(this->ref)) 
+  { TRACE(shell," destroying IExtractIcon(%p)\n",this);
+    SHFree(this->pidl);
+    HeapFree(GetProcessHeap(),0,this);
+    return 0;
+  }
+  return this->ref;
+}
+/**************************************************************************
+*  IExtractIcon_GetIconLocation
+* NOTE
+*  FIXME returns allways the icon no. 3 (closed Folder)
+*/
+static HRESULT IExtractIcon_GetIconLocation(LPEXTRACTICON this, UINT32 uFlags, LPSTR szIconFile, UINT32 cchMax, int * piIndex, UINT32 * pwFlags)
+{ FIXME (shell,"(%p) (flags=%u file=%s max=%u %p %p) semi-stub\n", this, uFlags, szIconFile, cchMax, piIndex, pwFlags);
+  *pwFlags = GIL_NOTFILENAME;
+  *piIndex = 3;
+  return NOERROR;
+}
+/**************************************************************************
+*  IExtractIcon_Extract
+*/
+static HRESULT IExtractIcon_Extract(LPEXTRACTICON this, LPCSTR pszFile, UINT32 nIconIndex, HICON32 *phiconLarge, HICON32 *phiconSmall, UINT32 nIconSize)
+{ FIXME (shell,"(%p) (file=%s index=%u %p %p size=%u) semi-stub\n", this, pszFile, nIconIndex, phiconLarge, phiconSmall, nIconSize);
+  *phiconLarge = pImageList_GetIcon(ShellBigIconList, nIconIndex, ILD_TRANSPARENT);
+  *phiconSmall = pImageList_GetIcon(ShellSmallIconList, nIconIndex, ILD_TRANSPARENT);
+  return S_OK;
+}
+
+/**************************************************************************
+* IShellLink Implementation
+*/
+
+static struct IShellLink_VTable slvt = {
+  IShellLink_QueryInterface,
+  IShellLink_AddRef,
+  IShellLink_Release,
+    (void *)0xcafe0004,
+    (void *)0xcafe0005,
+    (void *)0xcafe0006,
+    (void *)0xcafe0007,
+    (void *)0xcafe0008,
+    (void *)0xcafe0009,
+    (void *)0xcafe0010,
+    (void *)0xcafe0011,
+    (void *)0xcafe0012,
+    (void *)0xcafe0013,
+    (void *)0xcafe0014,
+    (void *)0xcafe0015,
+    (void *)0xcafe0016,
+    (void *)0xcafe0017,
+    (void *)0xcafe0018,
+    (void *)0xcafe0019,
+    (void *)0xcafe0020,
+    (void *)0xcafe0021
+};
+
+/**************************************************************************
+ *	  IShellLink_Constructor
+ */
+LPSHELLLINK IShellLink_Constructor() 
+{	LPSHELLLINK sl;
+
+	sl = (LPSHELLLINK)HeapAlloc(GetProcessHeap(),0,sizeof(IShellLink));
+	sl->ref = 1;
+	sl->lpvtbl = &slvt;
+	TRACE(shell,"(%p)->()\n",sl);
+	return sl;
+}
+
+/**************************************************************************
+ *  IShellLink::QueryInterface
+ */
+static HRESULT WINAPI IShellLink_QueryInterface(
+  LPSHELLLINK this, REFIID riid, LPVOID *ppvObj)
+{  char    xriid[50];
+   WINE_StringFromCLSID((LPCLSID)riid,xriid);
+   TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",this,xriid);
+
+  *ppvObj = NULL;
+
+  if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
+  { *ppvObj = this; 
+  }
+  else if(IsEqualIID(riid, &IID_IShellLink))  /*IShellLink*/
+  {    *ppvObj = (LPSHELLLINK)this;
+  }   
+
+  if(*ppvObj)
+  { (*(LPSHELLLINK*)ppvObj)->lpvtbl->fnAddRef(this);      
+    TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
+    return S_OK;
+  }
+    TRACE(shell,"-- Interface: E_NOINTERFACE\n");
+  return E_NOINTERFACE;
+}  
+/******************************************************************************
+ * IShellLink_AddRef
+ */
+static ULONG WINAPI IShellLink_AddRef(LPSHELLLINK this)
+{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
+    return ++(this->ref);
+}
+/******************************************************************************
+ * IClassFactory_Release
+ */
+static ULONG WINAPI IShellLink_Release(LPSHELLLINK this)
+{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
+  if (!--(this->ref)) 
+  { TRACE(shell,"-- destroying IShellLink(%p)\n",this);
+    HeapFree(GetProcessHeap(),0,this);
+    return 0;
+  }
+  return this->ref;
+}
+
+
diff --git a/dlls/shell32/pidl.c b/dlls/shell32/pidl.c
new file mode 100644
index 0000000..7b1440a
--- /dev/null
+++ b/dlls/shell32/pidl.c
@@ -0,0 +1,846 @@
+/*
+ *	pidl Handling
+ *
+ *	Copyright 1998	Juergen Schmied
+ *
+ *  !!! currently work in progress on all classes !!!
+ *  <contact juergen.schmied@metronet.de, 980801>
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ole.h"
+#include "ole2.h"
+#include "debug.h"
+#include "compobj.h"
+#include "interfaces.h"
+#include "shlobj.h"
+#include "shell.h"
+#include "winerror.h"
+#include "winnls.h"
+#include "winproc.h"
+#include "commctrl.h"
+#include "shell32_main.h"
+
+#include "pidl.h"
+
+void pdump (LPCITEMIDLIST pidl)
+{ DWORD type;
+  CHAR * szData;
+  LPITEMIDLIST pidltemp = pidl;
+  TRACE(pidl,"---------- pidl=%p \n", pidl);
+  do
+  { szData = ((LPPIDLDATA )(pidltemp->mkid.abID))->szText;
+    type   = ((LPPIDLDATA )(pidltemp->mkid.abID))->type;
+    TRACE(pidl,"---- pidl=%p size=%u type=%lx %s\n",pidltemp, pidltemp->mkid.cb,type,debugstr_a(szData));
+    pidltemp = (LPITEMIDLIST)(((BYTE*)pidltemp)+pidltemp->mkid.cb);
+  } while (pidltemp->mkid.cb);
+}
+/*************************************************************************
+ * ILGetDisplayName			[SHELL32.15]
+ */
+BOOL32 WINAPI ILGetDisplayName(LPCITEMIDLIST iil,LPSTR path)
+{	FIXME(pidl,"(%p,%p),stub, return e:!\n",iil,path);
+	strcpy(path,"e:\\");
+	return TRUE;
+}
+/*************************************************************************
+ * ILFindLastID [SHELL32.16]
+ */
+LPSHITEMID WINAPI ILFindLastID(LPITEMIDLIST iil) 
+{	LPSHITEMID	lastsii,sii;
+
+ 	TRACE(pidl,"%p\n",iil);
+	if (!iil)
+	{ return NULL;
+    }
+	sii = &(iil->mkid);
+	lastsii = sii;
+	while (sii->cb)
+    { lastsii = sii;
+	  sii = (LPSHITEMID)(((char*)sii)+sii->cb);
+	}
+	return lastsii;
+}
+/*************************************************************************
+ * ILRemoveLastID [SHELL32.17]
+ * NOTES
+ *  Removes the last item 
+ */
+BOOL32 WINAPI ILRemoveLastID(LPCITEMIDLIST pidl)
+{ LPCITEMIDLIST	xpidl;
+   
+  TRACE(shell,"pidl=%p\n",pidl);
+  if (!pidl || !pidl->mkid.cb)
+    return 0;
+  ILFindLastID(pidl)->cb = 0;
+  return 1;
+}
+
+/*************************************************************************
+ * ILClone [SHELL32.18]
+ *
+ * NOTES
+ *    dupicate an idlist
+ */
+LPITEMIDLIST WINAPI ILClone (LPCITEMIDLIST pidl)
+{ DWORD    len;
+  LPITEMIDLIST  newpidl;
+
+  TRACE(pidl,"%p\n",pidl);
+
+  if (!pidl)
+    return NULL;
+    
+  len = ILGetSize(pidl);
+  newpidl = (LPITEMIDLIST)SHAlloc(len);
+  if (newpidl)
+    memcpy(newpidl,pidl,len);
+  return newpidl;
+}
+/*************************************************************************
+ * ILCloneFirst [SHELL32.19]
+ *
+ * NOTES
+ *  duplicates the first idlist of a complex pidl
+ */
+LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST pidl)
+{ FIXME(pidl,"pidl=%p\n",pidl);
+  return NULL;
+}
+
+/*************************************************************************
+ * ILCombine [SHELL32.25]
+ *
+ * NOTES
+ *  Concatenates two complex idlists.
+ *  The pidl is the first one, pidlsub the next one
+ *  Does not destroy the passed in idlists!
+ */
+LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2)
+{ DWORD    len1,len2;
+  LPITEMIDLIST  pidlNew;
+  
+  TRACE(pidl,"pidl=%p pidl=%p\n",pidl1,pidl2);
+
+  if(!pidl1 && !pidl2)
+  {  return NULL;
+  }
+ 
+  if(!pidl1)
+  { pidlNew = ILClone(pidl2);
+    return pidlNew;
+  }
+
+  if(!pidl2)
+  { pidlNew = ILClone(pidl1);
+    return pidlNew;
+  }
+
+  len1  = ILGetSize(pidl1)-2;
+  len2  = ILGetSize(pidl2);
+  pidlNew  = SHAlloc(len1+len2);
+  
+  if (pidlNew)
+  { memcpy(pidlNew,pidl1,len1);
+    memcpy(((BYTE *)pidlNew)+len1,pidl2,len2);
+  }
+
+/*  TRACE(pidl,"--new pidl=%p\n",pidlNew);*/
+  return pidlNew;
+}
+/*************************************************************************
+ * ILGetSize [SHELL32.152]
+ *  gets the byte size of an idlist including zero terminator (pidl)
+ *
+ * PARAMETERS
+ *  pidl ITEMIDLIST
+ *
+ * RETURNS
+ *  size of pidl
+ *
+ * NOTES
+ *  exported by ordinal
+ */
+DWORD WINAPI ILGetSize(LPITEMIDLIST pidl)
+{ LPSHITEMID si = &(pidl->mkid);
+  DWORD  len=0;
+
+  TRACE(pidl,"pidl=%p\n",pidl);
+
+  if (pidl)
+  { while (si->cb) 
+    { len += si->cb;
+      si  = (LPSHITEMID)(((LPBYTE)si)+si->cb);
+    }
+    len += 2;
+	}
+/*  TRACE(pidl,"-- size=%lu\n",len);*/
+	return len;
+}
+/*************************************************************************
+ * ILGetNext [SHELL32.153]
+ *  gets the next simple pidl ot of a complex pidl
+ *
+ * PARAMETERS
+ *  pidl ITEMIDLIST
+ *
+ * RETURNS
+ *  pointer to next element
+ *
+ */
+LPITEMIDLIST WINAPI ILGetNext(LPITEMIDLIST pidl)
+{ LPITEMIDLIST nextpidl;
+
+  TRACE(pidl,"(pidl=%p)\n",pidl);
+  if(pidl)
+  { nextpidl = (LPITEMIDLIST)(LPBYTE)(((LPBYTE)pidl) + pidl->mkid.cb);
+	return nextpidl;
+  }
+  else
+  {  return (NULL);
+  }
+}
+/*************************************************************************
+ * ILAppend [SHELL32.154]
+ *
+ * NOTES
+ *  Adds the single item to the idlist indicated by pidl.
+ *  if bEnd is 0, adds the item to the front of the list,
+ *  otherwise adds the item to the end.
+ *  Destroys the passed in idlist!
+ */
+LPITEMIDLIST WINAPI ILAppend(LPITEMIDLIST pidl,LPCITEMIDLIST item,BOOL32 bEnd)
+{ TRACE(pidl,"(pidl=%p,pidl=%p,%08u)\n",pidl,item,bEnd);
+  return NULL;
+}
+/*************************************************************************
+ * ILFree [SHELL32.155]
+ *
+ * NOTES
+ *     free_check_ptr - frees memory (if not NULL)
+ *     allocated by SHMalloc allocator
+ *     exported by ordinal
+ */
+DWORD WINAPI ILFree(LPVOID pidl) 
+{ TRACE(pidl,"(pidl=0x%08lx)\n",(DWORD)pidl);
+  if (!pidl)
+		return 0;
+  return SHFree(pidl);
+}
+
+/**************************************************************************
+*	  INTERNAL CLASS pidlmgr
+*/
+
+static struct PidlMgr_VTable pmgrvt = {
+    PidlMgr_CreateDesktop,
+    PidlMgr_CreateMyComputer,
+	PidlMgr_CreateDrive,
+    PidlMgr_CreateFolder,
+    PidlMgr_CreateValue,
+    PidlMgr_GetDesktop,
+	PidlMgr_GetDrive,
+    PidlMgr_GetLastItem,
+    PidlMgr_GetItemText,
+    PidlMgr_IsDesktop,
+    PidlMgr_IsMyComputer,
+	PidlMgr_IsDrive,
+    PidlMgr_IsFolder,
+    PidlMgr_IsValue,
+    PidlMgr_HasFolders,
+    PidlMgr_GetFolderText,
+    PidlMgr_GetValueText,
+    PidlMgr_GetValueType,
+    PidlMgr_GetDataText,
+    PidlMgr_GetPidlPath,
+    PidlMgr_Create,
+    PidlMgr_GetData,
+    PidlMgr_GetDataPointer,
+    PidlMgr_SeparatePathAndValue
+};
+/**************************************************************************
+ *	  PidlMgr_Constructor
+ */
+LPPIDLMGR PidlMgr_Constructor() 
+{	LPPIDLMGR pmgr;
+	pmgr = (LPPIDLMGR)HeapAlloc(GetProcessHeap(),0,sizeof(pidlmgr));
+	pmgr->lpvtbl = &pmgrvt;
+	TRACE(pidl,"(%p)->()\n",pmgr);
+  /** FIXMEDllRefCount++;*/
+	return pmgr;
+}
+/**************************************************************************
+ *	  PidlMgr_Destructor
+ */
+void PidlMgr_Destructor(LPPIDLMGR this) 
+{	HeapFree(GetProcessHeap(),0,this);
+ 	TRACE(pidl,"(%p)->()\n",this);
+  /** FIXMEDllRefCount--;*/
+}
+
+/**************************************************************************
+ *  PidlMgr_CreateDesktop()
+ *  PidlMgr_CreateMyComputer()
+ *  PidlMgr_CreateDrive()
+ *  PidlMgr_CreateFolder() 
+ *  PidlMgr_CreateValue()
+ */
+LPITEMIDLIST PidlMgr_CreateDesktop(LPPIDLMGR this)
+{ TRACE(pidl,"(%p)->()\n",this);
+    return PidlMgr_Create(this,PT_DESKTOP, NULL, 0);
+}
+LPITEMIDLIST PidlMgr_CreateMyComputer(LPPIDLMGR this)
+{ TRACE(pidl,"(%p)->()\n",this);
+  return PidlMgr_Create(this,PT_MYCOMP, (void *)"My Computer", strlen ("My Computer")+1);
+}
+LPITEMIDLIST PidlMgr_CreateDrive(LPPIDLMGR this, LPCSTR lpszNew)
+{ char sTemp[4];
+  strncpy (sTemp,lpszNew,4);
+	sTemp[2]='\\';
+	sTemp[3]=0x00;
+  TRACE(pidl,"(%p)->(%s)\n",this,sTemp);
+  return PidlMgr_Create(this,PT_DRIVE,(LPVOID)&sTemp[0],4);
+}
+LPITEMIDLIST PidlMgr_CreateFolder(LPPIDLMGR this, LPCSTR lpszNew)
+{ TRACE(pidl,"(%p)->(%s)\n",this,lpszNew);
+  return PidlMgr_Create(this,PT_FOLDER, (LPVOID)lpszNew, strlen(lpszNew)+1);
+}
+LPITEMIDLIST PidlMgr_CreateValue(LPPIDLMGR this,LPCSTR lpszNew)
+{ TRACE(pidl,"(%p)->(%s)\n",this,lpszNew);
+  return PidlMgr_Create(this,PT_VALUE, (LPVOID)lpszNew, strlen(lpszNew)+1);
+}
+
+/**************************************************************************
+ *  PidlMgr_GetDesktop()
+ * 
+ *  FIXME: quick hack
+ */
+BOOL32 PidlMgr_GetDesktop(LPPIDLMGR this,LPCITEMIDLIST pidl,LPSTR pOut)
+{ TRACE(pidl,"(%p)->(%p %p)\n",this,pidl,pOut);
+  return (BOOL32)PidlMgr_GetData(this,PT_DESKTOP, pidl, (LPVOID)pOut, 255);
+}
+/**************************************************************************
+ *  PidlMgr_GetDrive()
+ *
+ *  FIXME: quick hack
+ */
+BOOL32 PidlMgr_GetDrive(LPPIDLMGR this,LPCITEMIDLIST pidl,LPSTR pOut, UINT16 uSize)
+{ LPITEMIDLIST   pidlTemp=NULL;
+
+  TRACE(pidl,"(%p)->(%p,%p,%u)\n",this,pidl,pOut,uSize);
+  if(PidlMgr_IsMyComputer(this,pidl))
+  { pidlTemp = ILGetNext(pidl);
+	}
+  else if (pidlTemp && PidlMgr_IsDrive(this,pidlTemp))
+  { return (BOOL32)PidlMgr_GetData(this,PT_DRIVE, pidlTemp, (LPVOID)pOut, uSize);
+	}
+	return FALSE;
+}
+/**************************************************************************
+ *  PidlMgr_GetLastItem()
+ *  Gets the last item in the list
+ */
+LPITEMIDLIST PidlMgr_GetLastItem(LPPIDLMGR this,LPCITEMIDLIST pidl)
+{ LPITEMIDLIST   pidlLast = NULL;
+
+  TRACE(pidl,"(%p)->(pidl=%p)\n",this,pidl);
+
+  if(pidl)
+  { while(pidl->mkid.cb)
+    { pidlLast = (LPITEMIDLIST)pidl;
+      pidl = ILGetNext(pidl);
+    }  
+  }
+  return pidlLast;
+}
+/**************************************************************************
+ *  PidlMgr_GetItemText()
+ *  Gets the text for only this item
+ */
+DWORD PidlMgr_GetItemText(LPPIDLMGR this,LPCITEMIDLIST pidl, LPSTR lpszText, UINT16 uSize)
+{ TRACE(pidl,"(%p)->(pidl=%p %p %x)\n",this,pidl,lpszText,uSize);
+  if (PidlMgr_IsMyComputer(this, pidl))
+  { return PidlMgr_GetData(this,PT_MYCOMP, pidl, (LPVOID)lpszText, uSize);
+	}
+	if (PidlMgr_IsDrive(this, pidl))
+	{ return PidlMgr_GetData(this,PT_DRIVE, pidl, (LPVOID)lpszText, uSize);
+	}
+	return PidlMgr_GetData(this,PT_TEXT, pidl, (LPVOID)lpszText, uSize);	
+}
+/**************************************************************************
+ *  PidlMgr_IsDesktop()
+ *  PidlMgr_IsDrive()
+ *  PidlMgr_IsFolder()
+ *  PidlMgr_IsValue()
+*/
+BOOL32 PidlMgr_IsDesktop(LPPIDLMGR this,LPCITEMIDLIST pidl)
+{ TRACE(pidl,"%p->(%p)\n",this,pidl);
+
+  if (! pidl)
+    return FALSE;
+
+  return (  pidl->mkid.cb == 0x00 );
+}
+
+BOOL32 PidlMgr_IsMyComputer(LPPIDLMGR this,LPCITEMIDLIST pidl)
+{ LPPIDLDATA  pData;
+  TRACE(pidl,"%p->(%p)\n",this,pidl);
+
+  if (! pidl)
+    return FALSE;
+
+  pData = PidlMgr_GetDataPointer(this,pidl);
+  return (PT_MYCOMP == pData->type);
+}
+
+BOOL32 PidlMgr_IsDrive(LPPIDLMGR this,LPCITEMIDLIST pidl)
+{ LPPIDLDATA  pData;
+  TRACE(pidl,"%p->(%p)\n",this,pidl);
+
+  if (! pidl)
+    return FALSE;
+
+  pData = PidlMgr_GetDataPointer(this,pidl);
+  return (PT_DRIVE == pData->type);
+}
+
+BOOL32 PidlMgr_IsFolder(LPPIDLMGR this,LPCITEMIDLIST pidl)
+{ LPPIDLDATA  pData;
+  TRACE(pidl,"%p->(%p)\n",this,pidl);
+
+  if (! pidl)
+    return FALSE;
+
+  pData = PidlMgr_GetDataPointer(this,pidl);
+  return (PT_FOLDER == pData->type);
+}
+
+BOOL32 PidlMgr_IsValue(LPPIDLMGR this,LPCITEMIDLIST pidl)
+{ LPPIDLDATA  pData;
+  TRACE(pidl,"%p->(%p)\n",this,pidl);
+
+  if (! pidl)
+    return FALSE;
+
+  pData = PidlMgr_GetDataPointer(this,pidl);
+  return (PT_VALUE == pData->type);
+}
+/**************************************************************************
+ * PidlMgr_HasFolders()
+ * fixme: quick hack
+ */
+BOOL32 PidlMgr_HasFolders(LPPIDLMGR this, LPSTR pszPath, LPCITEMIDLIST pidl)
+{ BOOL32 bResult= FALSE;
+  WIN32_FIND_DATA32A stffile;	
+  HANDLE32 hFile;
+
+  TRACE(pidl,"(%p)->%p %p\n",this, pszPath, pidl);
+	
+  hFile = FindFirstFile32A(pszPath,&stffile);
+  do
+  { if (! (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
+    {  bResult= TRUE;
+		}
+  } while( FindNextFile32A(hFile,&stffile));
+  FindClose32 (hFile);
+	
+	return bResult;
+}
+
+
+/**************************************************************************
+ *  PidlMgr_GetFolderText()
+ *  Creates a Path string from a PIDL, filtering out the special Folders 
+ */
+DWORD PidlMgr_GetFolderText(LPPIDLMGR this,LPCITEMIDLIST pidl,
+   LPSTR lpszPath, DWORD dwSize)
+{ LPITEMIDLIST   pidlTemp;
+  DWORD          dwCopied = 0;
+ 
+  TRACE(pidl,"(%p)->(%p)\n",this,pidl);
+ 
+  if(!pidl)
+  { return 0;
+  }
+
+  if(PidlMgr_IsMyComputer(this,pidl))
+  { pidlTemp = ILGetNext(pidl);
+    TRACE(pidl,"-- (%p)->skip My Computer\n",this);
+  }
+  else
+  { pidlTemp = (LPITEMIDLIST)pidl;
+  }
+
+  //if this is NULL, return the required size of the buffer
+  if(!lpszPath)
+  { while(pidlTemp->mkid.cb)
+    { LPPIDLDATA  pData = PidlMgr_GetDataPointer(this,pidlTemp);
+      
+      //add the length of this item plus one for the backslash
+      dwCopied += strlen(pData->szText) + 1;  /* FIXME pData->szText is not every time a string*/
+
+      pidlTemp = ILGetNext(pidlTemp);
+    }
+
+    //add one for the NULL terminator
+	TRACE(pidl,"-- (%p)->(size=%lu)\n",this,dwCopied);
+    return dwCopied + 1;
+  }
+
+  *lpszPath = 0;
+
+  while(pidlTemp->mkid.cb && (dwCopied < dwSize))
+  { LPPIDLDATA  pData = PidlMgr_GetDataPointer(this,pidlTemp);
+
+    //if this item is a value, then skip it and finish
+    if(PT_VALUE == pData->type)
+    { break;
+	}
+   
+    strcat(lpszPath, pData->szText);
+    strcat(lpszPath, "\\");
+    dwCopied += strlen(pData->szText) + 1;
+    pidlTemp = ILGetNext(pidlTemp);
+
+	TRACE(pidl,"-- (%p)->(size=%lu,%s)\n",this,dwCopied,lpszPath);
+  }
+
+  //remove the last backslash if necessary
+  if(dwCopied)
+  { if(*(lpszPath + strlen(lpszPath) - 1) == '\\')
+    { *(lpszPath + strlen(lpszPath) - 1) = 0;
+      dwCopied--;
+    }
+  }
+  TRACE(pidl,"-- (%p)->(path=%s)\n",this,lpszPath);
+  return dwCopied;
+}
+
+
+/**************************************************************************
+ *  PidlMgr_GetValueText()
+ *  Gets the text for the last item in the list
+ */
+DWORD PidlMgr_GetValueText(LPPIDLMGR this,
+    LPCITEMIDLIST pidl, LPSTR lpszValue, DWORD dwSize)
+{ LPITEMIDLIST  pidlTemp=pidl;
+  CHAR          szText[MAX_PATH];
+
+  TRACE(pidl,"(%p)->(pidl=%p %p 0x%08lx)\n",this,pidl,lpszValue,dwSize);
+
+  if(!pidl)
+  { return 0;
+	}
+		
+  while(pidlTemp->mkid.cb && !PidlMgr_IsValue(this,pidlTemp))
+  { pidlTemp = ILGetNext(pidlTemp);
+  }
+
+  if(!pidlTemp->mkid.cb)
+  { return 0;
+	}
+
+  PidlMgr_GetItemText(this, pidlTemp, szText, sizeof(szText));
+
+  if(!lpszValue)
+  { return strlen(szText) + 1;
+  }
+  strcpy(lpszValue, szText);
+	TRACE(pidl,"-- (%p)->(pidl=%p %p=%s 0x%08lx)\n",this,pidl,lpszValue,lpszValue,dwSize);
+  return strlen(lpszValue);
+}
+/**************************************************************************
+ *  PidlMgr_GetValueType()
+ */
+BOOL32 PidlMgr_GetValueType( LPPIDLMGR this,
+   LPCITEMIDLIST pidlPath,
+   LPCITEMIDLIST pidlValue,
+   LPDWORD pdwType)
+{ LPSTR    lpszFolder,
+           lpszValueName;
+  DWORD    dwNameSize;
+ 
+  FIXME(pidl,"(%p)->(%p %p %p) stub\n",this,pidlPath,pidlValue,pdwType);
+	
+  if(!pidlPath)
+  { return FALSE;
+	}
+
+  if(!pidlValue)
+  { return FALSE;
+	}
+
+  if(!pdwType)
+  { return FALSE;
+	}
+
+  //get the Desktop
+  //PidlMgr_GetDesktop(this,pidlPath);
+
+  /* fixme: add the driveletter here*/
+	
+  //assemble the Folder string
+  dwNameSize = PidlMgr_GetFolderText(this,pidlPath, NULL, 0);
+  lpszFolder = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize);
+  if(!lpszFolder)
+  {  return FALSE;
+	}
+  PidlMgr_GetFolderText(this,pidlPath, lpszFolder, dwNameSize);
+
+  //assemble the value name
+  dwNameSize = PidlMgr_GetValueText(this,pidlValue, NULL, 0);
+  lpszValueName = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize);
+  if(!lpszValueName)
+  { HeapFree(GetProcessHeap(),0,lpszFolder);
+    return FALSE;
+  }
+  PidlMgr_GetValueText(this,pidlValue, lpszValueName, dwNameSize);
+
+  /* fixme: we've got the path now do something with it
+	  -like get the filetype*/
+	
+	pdwType=NULL;
+	
+  HeapFree(GetProcessHeap(),0,lpszFolder);
+  HeapFree(GetProcessHeap(),0,lpszValueName);
+  return TRUE;
+}
+/**************************************************************************
+ *  PidlMgr_GetDataText()
+ */
+DWORD PidlMgr_GetDataText( LPPIDLMGR this,
+ LPCITEMIDLIST pidlPath, LPCITEMIDLIST pidlValue, LPSTR lpszOut, DWORD dwOutSize)
+{ LPSTR    lpszFolder,
+           lpszValueName;
+  DWORD    dwNameSize;
+
+  FIXME(pidl,"(%p)->(pidl=%p pidl=%p) stub\n",this,pidlPath,pidlValue);
+
+  if(!lpszOut || !pidlPath || !pidlValue)
+  { return FALSE;
+	}
+
+  /* fixme: get the driveletter*/
+
+  //assemble the Folder string
+  dwNameSize = PidlMgr_GetFolderText(this,pidlPath, NULL, 0);
+  lpszFolder = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize);
+  if(!lpszFolder)
+  {  return FALSE;
+	}
+  PidlMgr_GetFolderText(this,pidlPath, lpszFolder, dwNameSize);
+
+  //assemble the value name
+  dwNameSize = PidlMgr_GetValueText(this,pidlValue, NULL, 0);
+  lpszValueName = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize);
+  if(!lpszValueName)
+  { HeapFree(GetProcessHeap(),0,lpszFolder);
+    return FALSE;
+  }
+  PidlMgr_GetValueText(this,pidlValue, lpszValueName, dwNameSize);
+
+  /* fixme: we've got the path now do something with it*/
+	
+  HeapFree(GetProcessHeap(),0,lpszFolder);
+  HeapFree(GetProcessHeap(),0,lpszValueName);
+
+  TRACE(pidl,"-- (%p)->(%p=%s 0x%08lx)\n",this,lpszOut,lpszOut,dwOutSize);
+
+	return TRUE;
+}
+
+/**************************************************************************
+ *   CPidlMgr::GetPidlPath()
+ *  Create a string that includes the Drive name, the folder text and 
+ *  the value text.
+ */
+DWORD PidlMgr_GetPidlPath(LPPIDLMGR this,
+    LPCITEMIDLIST pidl, LPSTR lpszOut, DWORD dwOutSize)
+{ LPSTR lpszTemp;
+  WORD	len;
+
+  TRACE(pidl,"(%p)->(%p,%lu)\n",this,lpszOut,dwOutSize);
+
+  if(!lpszOut)
+  { return 0;
+	}
+
+  *lpszOut = 0;
+  lpszTemp = lpszOut;
+
+  dwOutSize -= PidlMgr_GetFolderText(this,pidl, lpszTemp, dwOutSize);
+
+  //add a backslash if necessary
+  len = strlen(lpszTemp);
+  if (len && lpszTemp[len-1]!='\\')
+	{ lpszTemp[len+0]='\\';
+    lpszTemp[len+1]='\0';
+		dwOutSize--;
+  }
+
+  lpszTemp = lpszOut + strlen(lpszOut);
+
+  //add the value string
+  PidlMgr_GetValueText(this,pidl, lpszTemp, dwOutSize);
+
+  //remove the last backslash if necessary
+  if(*(lpszOut + strlen(lpszOut) - 1) == '\\')
+  { *(lpszOut + strlen(lpszOut) - 1) = 0;
+  }
+
+  TRACE(pidl,"-- (%p)->(%p=%s,%lu)\n",this,lpszOut,lpszOut,dwOutSize);
+
+  return strlen(lpszOut);
+
+}
+
+/**************************************************************************
+ *  PidlMgr_Create()
+ *  Creates a new PIDL
+ *  type = PT_DESKTOP | PT_DRIVE | PT_FOLDER | PT_VALUE
+ *  pIn = data
+ *  uInSize = size of data
+ */
+
+LPITEMIDLIST PidlMgr_Create(LPPIDLMGR this,PIDLTYPE type, LPVOID pIn, UINT16 uInSize)
+{ LPITEMIDLIST   pidlOut=NULL;
+  UINT16         uSize;
+  LPITEMIDLIST   pidlTemp=NULL;
+  LPPIDLDATA     pData;
+
+  TRACE(pidl,"(%p)->(%x %p %x)\n",this,type,pIn,uInSize);
+
+  if ( type == PT_DESKTOP)
+  {   pidlOut = SHAlloc(2);
+      pidlOut->mkid.cb=0x0000;
+      return pidlOut;
+	}
+
+  if (! pIn)
+	{ return NULL;
+	}	
+
+  uSize = 2 + (sizeof(PIDLTYPE)) + uInSize + 2;  /* cb + PIDLTYPE + uInSize +2 */
+  pidlOut = SHAlloc(uSize);
+  pidlTemp = pidlOut;
+  if(pidlOut)
+  { pidlTemp->mkid.cb = uSize - 2;
+    pData =(LPPIDLDATA) &(pidlTemp->mkid.abID[0]);
+    pData->type = type;
+    switch(type)
+    { case PT_MYCOMP:
+        memcpy(pData->szText, pIn, uInSize);
+                       TRACE(pidl,"- (%p)->create My Computer: %s\n",this,debugstr_a(pData->szText));
+                       break;
+      case PT_DRIVE:
+        memcpy(pData->szText, pIn, uInSize);
+                       TRACE(pidl,"- (%p)->create Drive: %s\n",this,debugstr_a(pData->szText));
+											 break;
+      case PT_FOLDER:
+      case PT_VALUE:   
+        memcpy(pData->szText, pIn, uInSize);
+                       TRACE(pidl,"- (%p)->create Value: %s\n",this,debugstr_a(pData->szText));
+											 break;
+      default: 
+        FIXME(pidl,"- (%p) wrong argument\n",this);
+			                 break;
+    }
+   
+    pidlTemp = ILGetNext(pidlTemp);
+  pidlTemp->mkid.cb = 0x00;
+  }
+  TRACE(pidl,"-- (%p)->(pidl=%p, size=%u)\n",this,pidlOut,uSize-2);
+  return pidlOut;
+}
+/**************************************************************************
+ *  PidlMgr_GetData(PIDLTYPE, LPCITEMIDLIST, LPVOID, UINT16)
+ */
+DWORD PidlMgr_GetData(
+    LPPIDLMGR this,
+		PIDLTYPE type, 
+    LPCITEMIDLIST pidl,
+		LPVOID pOut,
+		UINT16 uOutSize)
+{ LPPIDLDATA  pData;
+  DWORD       dwReturn=0; 
+
+	TRACE(pidl,"(%p)->(%x %p %p %x)\n",this,type,pidl,pOut,uOutSize);
+	
+  if(!pidl)
+  {  return 0;
+	}
+
+  pData = PidlMgr_GetDataPointer(this,pidl);
+
+  //copy the data
+  switch(type)
+  { case PT_MYCOMP:  if(uOutSize < 1)
+                       return 0;
+                     if(PT_MYCOMP != pData->type)
+                       return 0;
+										 *(LPSTR)pOut = 0;	 
+                     strncpy((LPSTR)pOut, "My Computer", uOutSize);
+										 dwReturn = strlen((LPSTR)pOut);
+                     break;
+
+	 case PT_DRIVE:    if(uOutSize < 1)
+                       return 0;
+                     if(PT_DRIVE != pData->type)
+                       return 0;
+										 *(LPSTR)pOut = 0;	 
+                     strncpy((LPSTR)pOut, pData->szText, uOutSize);
+										 dwReturn = strlen((LPSTR)pOut);
+                     break;
+
+   case PT_FOLDER:
+   case PT_VALUE: 
+	 case PT_TEXT:     *(LPSTR)pOut = 0;
+                     strncpy((LPSTR)pOut, pData->szText, uOutSize);
+                     dwReturn = strlen((LPSTR)pOut);
+                     break;
+   default:     break;										 
+  }
+	TRACE(pidl,"-- (%p)->(%p=%s 0x%08lx)\n",this,pOut,(char*)pOut,dwReturn);
+  return dwReturn;
+}
+
+
+/**************************************************************************
+ *  PidlMgr_GetDataPointer()
+ */
+LPPIDLDATA PidlMgr_GetDataPointer(LPPIDLMGR this,LPITEMIDLIST pidl)
+{ if(!pidl)
+  {  return NULL;
+	}
+	TRACE(pidl,"(%p)->(%p)\n"	,this, pidl);
+  return (LPPIDLDATA)(pidl->mkid.abID);
+}
+
+/**************************************************************************
+ *  CPidlMgr_SeparatePathAndValue)
+ *  Creates a separate path and value PIDL from a fully qualified PIDL.
+ */
+BOOL32 PidlMgr_SeparatePathAndValue(LPPIDLMGR this, 
+   LPITEMIDLIST pidlFQ, LPITEMIDLIST *ppidlPath, LPITEMIDLIST *ppidlValue)
+{ LPITEMIDLIST   pidlTemp;
+	TRACE(pidl,"(%p)->(pidl=%p pidl=%p pidl=%p)",this,pidlFQ,ppidlPath,ppidlValue);
+  if(!pidlFQ)
+  {  return FALSE;
+	}
+
+  *ppidlValue = PidlMgr_GetLastItem(this,pidlFQ);
+
+  if(!PidlMgr_IsValue(this,*ppidlValue))
+  { return FALSE;
+	}
+
+  *ppidlValue = ILClone(*ppidlValue);
+  *ppidlPath = ILClone(pidlFQ);
+
+  pidlTemp = PidlMgr_GetLastItem(this,*ppidlPath);
+  pidlTemp->mkid.cb = 0x00;
+
+  return TRUE;
+}
diff --git a/dlls/shell32/pidl.h b/dlls/shell32/pidl.h
new file mode 100644
index 0000000..0817b53
--- /dev/null
+++ b/dlls/shell32/pidl.h
@@ -0,0 +1,31 @@
+/*	  INTERNAL CLASS pidlmgr */
+
+#ifndef __WINE_PIDL_H
+#define __WINE_PIDL_H
+
+extern LPITEMIDLIST PidlMgr_CreateDesktop(LPPIDLMGR);
+extern LPITEMIDLIST PidlMgr_CreateMyComputer(LPPIDLMGR);
+extern LPITEMIDLIST PidlMgr_CreateDrive(LPPIDLMGR,LPCSTR);
+extern LPITEMIDLIST PidlMgr_CreateFolder(LPPIDLMGR,LPCSTR);
+extern LPITEMIDLIST PidlMgr_CreateValue(LPPIDLMGR,LPCSTR);
+extern BOOL32 PidlMgr_GetDesktop(LPPIDLMGR,LPCITEMIDLIST,LPSTR);
+extern BOOL32 PidlMgr_GetDrive(LPPIDLMGR,LPCITEMIDLIST,LPSTR,UINT16);
+extern LPITEMIDLIST PidlMgr_GetLastItem(LPPIDLMGR,LPCITEMIDLIST);
+extern DWORD PidlMgr_GetItemText(LPPIDLMGR,LPCITEMIDLIST,LPSTR,UINT16);
+extern BOOL32 PidlMgr_IsDesktop(LPPIDLMGR,LPCITEMIDLIST);
+extern BOOL32 PidlMgr_IsMyComputer(LPPIDLMGR,LPCITEMIDLIST);
+extern BOOL32 PidlMgr_IsDrive(LPPIDLMGR,LPCITEMIDLIST);
+extern BOOL32 PidlMgr_IsFolder(LPPIDLMGR,LPCITEMIDLIST);
+extern BOOL32 PidlMgr_IsValue(LPPIDLMGR,LPCITEMIDLIST);
+extern BOOL32 PidlMgr_HasFolders(LPPIDLMGR,LPSTR,LPCITEMIDLIST);
+extern DWORD PidlMgr_GetFolderText(LPPIDLMGR,LPCITEMIDLIST,LPSTR,DWORD);
+extern DWORD PidlMgr_GetValueText(LPPIDLMGR,LPCITEMIDLIST,LPSTR,DWORD);
+extern BOOL32 PidlMgr_GetValueType(LPPIDLMGR,LPCITEMIDLIST,LPCITEMIDLIST,LPDWORD);
+extern DWORD PidlMgr_GetDataText(LPPIDLMGR,LPCITEMIDLIST,LPCITEMIDLIST,LPSTR,DWORD);
+extern DWORD PidlMgr_GetPidlPath(LPPIDLMGR,LPCITEMIDLIST,LPSTR,DWORD);
+extern LPITEMIDLIST PidlMgr_Create(LPPIDLMGR,PIDLTYPE,LPVOID,UINT16);
+extern DWORD PidlMgr_GetData(LPPIDLMGR,PIDLTYPE,LPCITEMIDLIST,LPVOID,UINT16);
+extern LPPIDLDATA PidlMgr_GetDataPointer(LPPIDLMGR,LPCITEMIDLIST);
+extern BOOL32 PidlMgr_SeparatePathAndValue(LPPIDLMGR,LPITEMIDLIST,LPITEMIDLIST*,LPITEMIDLIST*);
+
+#endif
diff --git a/dlls/shell32/shell32_main.c b/dlls/shell32/shell32_main.c
new file mode 100644
index 0000000..2a348f8
--- /dev/null
+++ b/dlls/shell32/shell32_main.c
@@ -0,0 +1,962 @@
+/*
+ * 				Shell basics
+ *
+ *  1998 Marcus Meissner
+ *  1998 Juergen Schmied (jsch)  *  <juergen.schmied@metronet.de>
+ */
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+#include "windows.h"
+#include "winerror.h"
+#include "file.h"
+#include "shell.h"
+#include "heap.h"
+#include "module.h"
+#include "neexe.h"
+#include "resource.h"
+#include "dlgs.h"
+#include "win.h"
+#include "graphics.h"
+#include "cursoricon.h"
+#include "interfaces.h"
+#include "sysmetrics.h"
+#include "shlobj.h"
+#include "debug.h"
+#include "winreg.h"
+#include "imagelist.h"
+#include "commctrl.h"
+#include "authors.h"
+
+#include "shell32_main.h"
+
+/*************************************************************************
+ *				CommandLineToArgvW	[SHELL32.7]
+ */
+LPWSTR* WINAPI CommandLineToArgvW(LPWSTR cmdline,LPDWORD numargs)
+{ LPWSTR  *argv,s,t;
+	int	i;
+  TRACE(shell,"\n");
+
+        /* to get writeable copy */
+	cmdline = HEAP_strdupW( GetProcessHeap(), 0, cmdline);
+	s=cmdline;i=0;
+  while (*s)
+  { /* space */
+    if (*s==0x0020) 
+    { i++;
+			s++;
+			while (*s && *s==0x0020)
+				s++;
+			continue;
+		}
+		s++;
+	}
+	argv=(LPWSTR*)HeapAlloc( GetProcessHeap(), 0, sizeof(LPWSTR)*(i+1) );
+	s=t=cmdline;
+	i=0;
+  while (*s)
+  { if (*s==0x0020)
+    { *s=0;
+			argv[i++]=HEAP_strdupW( GetProcessHeap(), 0, t );
+			*s=0x0020;
+			while (*s && *s==0x0020)
+				s++;
+			if (*s)
+				t=s+1;
+			else
+				t=s;
+			continue;
+		}
+		s++;
+	}
+	if (*t)
+		argv[i++]=(LPWSTR)HEAP_strdupW( GetProcessHeap(), 0, t );
+	HeapFree( GetProcessHeap(), 0, cmdline );
+	argv[i]=NULL;
+	*numargs=i;
+	return argv;
+}
+
+/*************************************************************************
+ *				Control_RunDLL		[SHELL32.12]
+ *
+ * Wild speculation in the following!
+ *
+ * http://premium.microsoft.com/msdn/library/techart/msdn193.htm
+ */
+
+void WINAPI Control_RunDLL (HWND32 hwnd, LPCVOID code, LPCSTR cmd, DWORD arg4)
+{ FIXME(shell, "(%08x, %p, \"%s\", %08lx)\n",
+	hwnd, code ? code : "(null)", cmd ? cmd : "(null)", arg4);
+}
+
+/*************************************************************************
+ * Shell_GetImageList [SHELL32.71]
+ *
+ * PARAMETERS
+ *  imglist[1|2] [OUT] pointer which recive imagelist handles
+ *
+ * NOTES
+ *  undocumented
+ *  I don't know, which pointer is which. They may have to be
+ *  exchanged. (jsch)
+ */
+BOOL32 WINAPI Shell_GetImageList(HIMAGELIST * imglist1,HIMAGELIST * imglist2)
+{	WARN(shell,"(%p,%p):semi-stub.\n",imglist1,imglist2);
+	if (imglist1)
+	{ *imglist1=ShellBigIconList;
+    }
+    if (imglist2)
+    { *imglist2=ShellSmallIconList;
+    }
+
+	return TRUE;
+}
+
+/*************************************************************************
+ *				SHGetFileInfoA		[SHELL32.218]
+ *
+ * FIXME
+ *   
+ */
+HIMAGELIST ShellSmallIconList = 0;
+HIMAGELIST ShellBigIconList = 0;
+
+DWORD WINAPI SHGetFileInfo32A(LPCSTR path,DWORD dwFileAttributes,
+                              SHFILEINFO32A *psfi, UINT32 sizeofpsfi,
+                              UINT32 flags )
+{ CHAR szTemp[MAX_PATH];
+  DWORD ret=0;
+  
+  TRACE(shell,"(%s,0x%lx,%p,0x%x,0x%x)\n",
+	      path,dwFileAttributes,psfi,sizeofpsfi,flags);
+
+  /* translate the pidl to a path*/
+  if (flags & SHGFI_PIDL)
+  { SHGetPathFromIDList32A ((LPCITEMIDLIST)path,szTemp);
+    TRACE(shell,"pidl=%p is %s\n",path,szTemp);
+  }
+  else
+  { TRACE(shell,"path=%p\n",path);
+  }
+
+  if (flags & SHGFI_ATTRIBUTES)
+  { FIXME(shell,"file attributes, stub\n");
+    psfi->dwAttributes=SFGAO_FILESYSTEM;
+    ret=TRUE;    
+  }
+
+  if (flags & SHGFI_DISPLAYNAME)
+  { if (flags & SHGFI_PIDL)
+    { strcpy(psfi->szDisplayName,szTemp);
+    }
+    else
+    { strcpy(psfi->szDisplayName,path);
+      TRACE(shell,"displayname=%s\n", szTemp);
+    }
+    ret=TRUE;
+  }
+  
+  if (flags & SHGFI_TYPENAME)
+  { FIXME(shell,"get the file type, stub\n");
+    strcpy(psfi->szTypeName,"");
+    ret=TRUE;
+  }
+  
+  if (flags & SHGFI_ICONLOCATION)
+  { FIXME(shell,"location of icon, stub\n");
+    strcpy(psfi->szDisplayName,"");
+    ret=TRUE;
+  }
+
+  if (flags & SHGFI_EXETYPE)
+    FIXME(shell,"type of executable, stub\n");
+
+  if (flags & SHGFI_LINKOVERLAY)
+    FIXME(shell,"set icon to link, stub\n");
+
+  if (flags & SHGFI_OPENICON)
+    FIXME(shell,"set to open icon, stub\n");
+
+  if (flags & SHGFI_SELECTED)
+    FIXME(shell,"set icon to selected, stub\n");
+
+  if (flags & SHGFI_SHELLICONSIZE)
+    FIXME(shell,"set icon to shell size, stub\n");
+
+  if (flags & SHGFI_USEFILEATTRIBUTES)
+    FIXME(shell,"use the dwFileAttributes, stub\n");
+ 
+  if (flags & SHGFI_ICON)
+  { FIXME(shell,"icon handle\n");
+    if (flags & SHGFI_SMALLICON)
+     { TRACE(shell,"set to small icon\n"); 
+       psfi->hIcon=pImageList_GetIcon(ShellSmallIconList,32,ILD_NORMAL);
+       ret = (DWORD) ShellSmallIconList;
+     }
+     else
+     { TRACE(shell,"set to big icon\n");
+       psfi->hIcon=pImageList_GetIcon(ShellBigIconList,32,ILD_NORMAL);
+       ret = (DWORD) ShellBigIconList;
+     }      
+  }
+
+  if (flags & SHGFI_SYSICONINDEX)
+  {  FIXME(shell,"get the SYSICONINDEX\n");
+     psfi->iIcon=32;
+     if (flags & SHGFI_SMALLICON)
+     { TRACE(shell,"set to small icon\n"); 
+       ret = (DWORD) ShellSmallIconList;
+     }
+     else        
+     { TRACE(shell,"set to big icon\n");
+       ret = (DWORD) ShellBigIconList;
+     }
+  }
+
+ 
+  return ret;
+}
+
+/*************************************************************************
+ *             ExtractIcon32A   (SHELL32.133)
+ */
+HICON32 WINAPI ExtractIcon32A( HINSTANCE32 hInstance, LPCSTR lpszExeFileName,
+	UINT32 nIconIndex )
+{   HGLOBAL16 handle = InternalExtractIcon(hInstance,lpszExeFileName,nIconIndex, 1);
+    TRACE(shell,"\n");
+    if( handle )
+    {
+	HICON16* ptr = (HICON16*)GlobalLock16(handle);
+	HICON16  hIcon = *ptr;
+
+	GlobalFree16(handle);
+	return hIcon;
+    }
+    return 0;
+}
+
+/*************************************************************************
+ *             ExtractIcon32W   (SHELL32.180)
+ */
+HICON32 WINAPI ExtractIcon32W( HINSTANCE32 hInstance, LPCWSTR lpszExeFileName,
+	UINT32 nIconIndex )
+{ LPSTR  exefn;
+  HICON32  ret;
+  TRACE(shell,"\n");
+
+  exefn = HEAP_strdupWtoA(GetProcessHeap(),0,lpszExeFileName);
+  ret = ExtractIcon32A(hInstance,exefn,nIconIndex);
+
+	HeapFree(GetProcessHeap(),0,exefn);
+	return ret;
+}
+
+/*************************************************************************
+ *             FindExecutable32A   (SHELL32.184)
+ */
+HINSTANCE32 WINAPI FindExecutable32A( LPCSTR lpFile, LPCSTR lpDirectory,
+                                      LPSTR lpResult )
+{ HINSTANCE32 retval=31;    /* default - 'No association was found' */
+    char old_dir[1024];
+
+  TRACE(shell, "File %s, Dir %s\n", 
+		 (lpFile != NULL?lpFile:"-"), 
+		 (lpDirectory != NULL?lpDirectory:"-"));
+
+    lpResult[0]='\0'; /* Start off with an empty return string */
+
+    /* trap NULL parameters on entry */
+    if (( lpFile == NULL ) || ( lpResult == NULL ))
+  { /* FIXME - should throw a warning, perhaps! */
+	return 2; /* File not found. Close enough, I guess. */
+    }
+
+    if (lpDirectory)
+  { GetCurrentDirectory32A( sizeof(old_dir), old_dir );
+        SetCurrentDirectory32A( lpDirectory );
+    }
+
+    retval = SHELL_FindExecutable( lpFile, "open", lpResult );
+
+  TRACE(shell, "returning %s\n", lpResult);
+  if (lpDirectory)
+    SetCurrentDirectory32A( old_dir );
+    return retval;
+}
+
+typedef struct
+{ LPCSTR  szApp;
+    LPCSTR  szOtherStuff;
+    HICON32 hIcon;
+} ABOUT_INFO;
+
+#define		IDC_STATIC_TEXT		100
+#define		IDC_LISTBOX		99
+#define		IDC_WINE_TEXT		98
+
+#define		DROP_FIELD_TOP		(-15)
+#define		DROP_FIELD_HEIGHT	15
+
+extern HICON32 hIconTitleFont;
+
+static BOOL32 __get_dropline( HWND32 hWnd, LPRECT32 lprect )
+{ HWND32 hWndCtl = GetDlgItem32(hWnd, IDC_WINE_TEXT);
+    if( hWndCtl )
+  { GetWindowRect32( hWndCtl, lprect );
+	MapWindowPoints32( 0, hWnd, (LPPOINT32)lprect, 2 );
+	lprect->bottom = (lprect->top += DROP_FIELD_TOP);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*************************************************************************
+ *				SHAppBarMessage32	[SHELL32.207]
+ */
+UINT32 WINAPI SHAppBarMessage32(DWORD msg, PAPPBARDATA data)
+{ FIXME(shell,"(0x%08lx,%p): stub\n", msg, data);
+#if 0
+  switch (msg)
+  { case ABM_ACTIVATE:
+        case ABM_GETAUTOHIDEBAR:
+        case ABM_GETSTATE:
+        case ABM_GETTASKBARPOS:
+        case ABM_NEW:
+        case ABM_QUERYPOS:
+        case ABM_REMOVE:
+        case ABM_SETAUTOHIDEBAR:
+        case ABM_SETPOS:
+        case ABM_WINDOWPOSCHANGED:
+	    ;
+    }
+#endif
+    return 0;
+}
+
+/*************************************************************************
+ * SHBrowseForFolderA [SHELL32.209]
+ *
+ */
+LPITEMIDLIST WINAPI SHBrowseForFolder32A (LPBROWSEINFO32A lpbi)
+{ FIXME (shell, "(%lx,%s) empty stub!\n", (DWORD)lpbi, lpbi->lpszTitle);
+  return NULL;
+}
+
+/*************************************************************************
+ *  SHGetDesktopFolder		[SHELL32.216]
+ * 
+ *  SDK header win95/shlobj.h: This is equivalent to call CoCreateInstance with
+ *  CLSID_ShellDesktop
+ *  CoCreateInstance(CLSID_Desktop, NULL, CLSCTX_INPROC, IID_IShellFolder, &pshf);
+ *
+ * RETURNS
+ *   the interface to the shell desktop folder.
+ *
+ * FIXME
+ *   the pdesktopfolder has to be released at the end (at dll unloading???)
+ */
+LPSHELLFOLDER pdesktopfolder=NULL;
+
+DWORD WINAPI SHGetDesktopFolder(LPSHELLFOLDER *shellfolder)
+{ HRESULT	hres = E_OUTOFMEMORY;
+  LPCLASSFACTORY lpclf;
+	TRACE(shell,"%p->(%p)\n",shellfolder,*shellfolder);
+
+  if (pdesktopfolder)
+	{	hres = NOERROR;
+	}
+	else
+  { lpclf = IClassFactory_Constructor();
+    /* fixme: the buildin IClassFactory_Constructor is at the moment only 
+ 		for rclsid=CLSID_ShellDesktop, so we get the right Interface (jsch)*/
+    if(lpclf)
+    { hres = lpclf->lpvtbl->fnCreateInstance(lpclf,NULL,(REFIID)&IID_IShellFolder, (void*)&pdesktopfolder);
+	 	  lpclf->lpvtbl->fnRelease(lpclf);
+	  }  
+  }
+	
+  if (pdesktopfolder)
+	{ *shellfolder = pdesktopfolder;
+    pdesktopfolder->lpvtbl->fnAddRef(pdesktopfolder);
+	}
+  else
+	{ *shellfolder=NULL;
+	}	
+
+  TRACE(shell,"-- %p->(%p)\n",shellfolder, *shellfolder);
+	return hres;
+}
+/*************************************************************************
+ *			 SHGetPathFromIDList		[SHELL32.221][NT 4.0: SHELL32.219]
+ */
+BOOL32 WINAPI SHGetPathFromIDList32(LPCITEMIDLIST pidl,LPSTR pszPath)     
+{ TRACE(shell,"(pidl=%p,%p)\n",pidl,pszPath);
+  return SHGetPathFromIDList32A(pidl,pszPath);
+}
+
+/*************************************************************************
+ *			 SHGetSpecialFolderLocation	[SHELL32.223]
+ * gets the folder locations from the registry and creates a pidl
+ * creates missing reg keys and directorys
+ * 
+ * PARAMS
+ *   hwndOwner [I]
+ *   nFolder   [I] CSIDL_xxxxx
+ *   ppidl     [O] PIDL of a special folder
+ *
+ * RETURNS
+ *    HResult
+ *
+ * FIXME
+ *   - look for "User Shell Folder" first
+ *
+ */
+HRESULT WINAPI SHGetSpecialFolderLocation(HWND32 hwndOwner, INT32 nFolder, LPITEMIDLIST * ppidl)
+{ LPSHELLFOLDER shellfolder;
+  DWORD pchEaten,tpathlen=MAX_PATH,type,dwdisp,res;
+  CHAR pszTemp[256],buffer[256],tpath[MAX_PATH],npath[MAX_PATH];
+  LPWSTR lpszDisplayName = (LPWSTR)&pszTemp[0];
+  HKEY key;
+
+  enum 
+	{	FT_UNKNOWN= 0x00000000,
+	  FT_DIR=     0x00000001, 
+	  FT_DESKTOP= 0x00000002
+	} tFolder; 
+
+  TRACE(shell,"(%04x,%d,%p)\n", hwndOwner,nFolder,ppidl);
+
+  strcpy(buffer,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\");
+
+  res=RegCreateKeyEx32A(HKEY_CURRENT_USER,buffer,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&key,&dwdisp);
+	if (res)
+	{ ERR(shell,"Could not create key %s %08lx \n",buffer,res);
+	  return E_OUTOFMEMORY;
+	}
+
+	tFolder=FT_DIR;	
+	switch (nFolder)
+	{	case CSIDL_BITBUCKET:
+			strcpy (buffer,"xxx");			/*not in the registry*/
+			TRACE (shell,"looking for Recycler\n");
+			tFolder=FT_UNKNOWN;
+      break;
+		case CSIDL_CONTROLS:
+			strcpy (buffer,"xxx");			/*virtual folder*/
+      TRACE (shell,"looking for Control\n");
+			tFolder=FT_UNKNOWN;
+      break;
+		case CSIDL_DESKTOP:
+			strcpy (buffer,"xxx");			/*virtual folder*/
+			TRACE (shell,"looking for Desktop\n");
+			tFolder=FT_DESKTOP;			
+      break;
+		case CSIDL_DESKTOPDIRECTORY:
+			strcpy (buffer,"Desktop");
+      break;
+		case CSIDL_DRIVES:
+			strcpy (buffer,"xxx");			/*virtual folder*/
+      TRACE (shell,"looking for Drives\n");
+			tFolder=FT_UNKNOWN;
+      break;
+		case CSIDL_FONTS:
+			strcpy (buffer,"Fonts");			
+      break;
+		case CSIDL_NETHOOD:
+			strcpy (buffer,"NetHood");			
+      break;
+		case CSIDL_NETWORK:
+			strcpy (buffer,"xxx");				/*virtual folder*/
+			TRACE (shell,"looking for Network\n");
+			tFolder=FT_UNKNOWN;
+      break;
+		case CSIDL_PERSONAL:
+			strcpy (buffer,"Personal");			
+      break;
+		case CSIDL_FAVORITES:
+			strcpy (buffer,"Favorites");			
+      break;
+		case CSIDL_PRINTERS:
+			strcpy (buffer,"PrintHood");			
+      break;
+		case CSIDL_PROGRAMS:
+			strcpy (buffer,"Programs");			
+      break;
+		case CSIDL_RECENT:
+			strcpy (buffer,"Recent");
+      break;
+		case CSIDL_SENDTO:
+			strcpy (buffer,"SendTo");
+ 		  break;
+		case CSIDL_STARTMENU:
+			strcpy (buffer,"Start Menu");
+      break;
+		case CSIDL_STARTUP:
+			strcpy (buffer,"Startup");			
+      break;
+		case CSIDL_TEMPLATES:
+			strcpy (buffer,"Templates");			
+      break;
+		default:
+      ERR (shell,"unknown CSIDL\n");
+			tFolder=FT_UNKNOWN;			
+      break;
+	}
+
+  TRACE(shell,"Key=%s\n",buffer);
+
+  type=REG_SZ;
+
+  switch (tFolder)
+	{ case FT_DIR:
+	    /* Directory: get the value from the registry, if its not there 
+			create it and the directory*/
+    	if (RegQueryValueEx32A(key,buffer,NULL,&type,tpath,&tpathlen))
+  	  { GetWindowsDirectory32A(npath,MAX_PATH);
+	      PathAddBackslash(npath);
+  			switch (nFolder)
+  			{	case CSIDL_DESKTOPDIRECTORY:
+      			strcat (npath,"Desktop");
+            break;
+      		case CSIDL_FONTS:
+      			strcat (npath,"Fonts");			
+            break;
+      		case CSIDL_NETHOOD:
+      			strcat (npath,"NetHood");			
+            break;
+  		    case CSIDL_PERSONAL:
+      			strcpy (npath,"C:\\Personal");			
+            break;
+      		case CSIDL_FAVORITES:
+      			strcat (npath,"Favorites");			
+            break;
+  		    case CSIDL_PRINTERS:
+      			strcat (npath,"PrintHood");			
+            break;
+      		case CSIDL_PROGRAMS:
+      			strcat (npath,"Start Menu");			
+  					CreateDirectory32A(npath,NULL);
+      			strcat (npath,"\\Programs");			
+            break;
+      		case CSIDL_RECENT:
+      			strcat (npath,"Recent");
+            break;
+      		case CSIDL_SENDTO:
+      			strcat (npath,"SendTo");
+      			break;
+      		case CSIDL_STARTMENU:
+      			strcat (npath,"Start Menu");
+            break;
+      		case CSIDL_STARTUP:
+      			strcat (npath,"Start Menu");			
+  					CreateDirectory32A(npath,NULL);
+      			strcat (npath,"\\Startup");			
+            break;
+      		case CSIDL_TEMPLATES:
+      			strcat (npath,"Templates");			
+            break;
+  				default:
+         	  RegCloseKey(key);
+        	  return E_OUTOFMEMORY;
+  			}
+    		if (RegSetValueEx32A(key,buffer,0,REG_SZ,npath,sizeof(npath)+1))
+        {	ERR(shell,"could not create value %s\n",buffer);
+      	  RegCloseKey(key);
+      	  return E_OUTOFMEMORY;
+    		}
+    		TRACE(shell,"value %s=%s created\n",buffer,npath);
+    	  CreateDirectory32A(npath,NULL);
+      }
+			break;
+		case FT_DESKTOP:
+			strcpy (tpath,"Desktop");			
+		  break;
+	  default:
+      RegCloseKey(key);
+      return E_OUTOFMEMORY;
+		  break;
+  }
+
+	RegCloseKey(key);
+
+  TRACE(shell,"Value=%s\n",tpath);
+  LocalToWideChar32(lpszDisplayName, tpath, 256);
+  
+	if (SHGetDesktopFolder(&shellfolder)==S_OK)
+	{ shellfolder->lpvtbl->fnParseDisplayName(shellfolder,hwndOwner, NULL,lpszDisplayName,&pchEaten,ppidl,NULL);
+	  shellfolder->lpvtbl->fnRelease(shellfolder);
+	}
+
+	TRACE(shell, "-- (new pidl %p)\n",*ppidl);
+	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;
+}
+
+/*************************************************************************
+ * SHLoadInProc [SHELL32.225]
+ *
+ */
+
+DWORD WINAPI SHLoadInProc (DWORD dwArg1)
+{ FIXME (shell, "(%lx) empty stub!\n", dwArg1);
+    return 0;
+}
+
+/*************************************************************************
+ *             ShellExecute32A   (SHELL32.245)
+ */
+HINSTANCE32 WINAPI ShellExecute32A( HWND32 hWnd, LPCSTR lpOperation,
+                                    LPCSTR lpFile, LPCSTR lpParameters,
+                                    LPCSTR lpDirectory, INT32 iShowCmd )
+{   TRACE(shell,"\n");
+    return ShellExecute16( hWnd, lpOperation, lpFile, lpParameters,
+                           lpDirectory, iShowCmd );
+}
+
+
+/*************************************************************************
+ *             AboutDlgProc32  (not an exported API function)
+ */
+LRESULT WINAPI AboutDlgProc32( HWND32 hWnd, UINT32 msg, WPARAM32 wParam,
+                               LPARAM lParam )
+{   HWND32 hWndCtl;
+    char Template[512], AppTitle[512];
+
+    TRACE(shell,"\n");
+
+    switch(msg)
+    { case WM_INITDIALOG:
+      { ABOUT_INFO *info = (ABOUT_INFO *)lParam;
+            if (info)
+        { const char* const *pstr = SHELL_People;
+                SendDlgItemMessage32A(hWnd, stc1, STM_SETICON32,info->hIcon, 0);
+                GetWindowText32A( hWnd, Template, sizeof(Template) );
+                sprintf( AppTitle, Template, info->szApp );
+                SetWindowText32A( hWnd, AppTitle );
+                SetWindowText32A( GetDlgItem32(hWnd, IDC_STATIC_TEXT),
+                                  info->szOtherStuff );
+                hWndCtl = GetDlgItem32(hWnd, IDC_LISTBOX);
+                SendMessage32A( hWndCtl, WM_SETREDRAW, 0, 0 );
+                SendMessage32A( hWndCtl, WM_SETFONT, hIconTitleFont, 0 );
+                while (*pstr)
+          { SendMessage32A( hWndCtl, LB_ADDSTRING32, (WPARAM32)-1, (LPARAM)*pstr );
+                    pstr++;
+                }
+                SendMessage32A( hWndCtl, WM_SETREDRAW, 1, 0 );
+            }
+        }
+        return 1;
+
+    case WM_PAINT:
+      { RECT32 rect;
+	    PAINTSTRUCT32 ps;
+	    HDC32 hDC = BeginPaint32( hWnd, &ps );
+
+	    if( __get_dropline( hWnd, &rect ) )
+		GRAPH_DrawLines( hDC, (LPPOINT32)&rect, 1, GetStockObject32( BLACK_PEN ) );
+	    EndPaint32( hWnd, &ps );
+	}
+	break;
+
+    case WM_LBTRACKPOINT:
+	hWndCtl = GetDlgItem32(hWnd, IDC_LISTBOX);
+	if( (INT16)GetKeyState16( VK_CONTROL ) < 0 )
+      { if( DragDetect32( hWndCtl, *((LPPOINT32)&lParam) ) )
+        { INT32 idx = SendMessage32A( hWndCtl, LB_GETCURSEL32, 0, 0 );
+		if( idx != -1 )
+          { INT32 length = SendMessage32A( hWndCtl, LB_GETTEXTLEN32, (WPARAM32)idx, 0 );
+		    HGLOBAL16 hMemObj = GlobalAlloc16( GMEM_MOVEABLE, length + 1 );
+		    char* pstr = (char*)GlobalLock16( hMemObj );
+
+		    if( pstr )
+            { HCURSOR16 hCursor = LoadCursor16( 0, MAKEINTRESOURCE16(OCR_DRAGOBJECT) );
+			SendMessage32A( hWndCtl, LB_GETTEXT32, (WPARAM32)idx, (LPARAM)pstr );
+			SendMessage32A( hWndCtl, LB_DELETESTRING32, (WPARAM32)idx, 0 );
+			UpdateWindow32( hWndCtl );
+			if( !DragObject16((HWND16)hWnd, (HWND16)hWnd, DRAGOBJ_DATA, 0, (WORD)hMemObj, hCursor) )
+			    SendMessage32A( hWndCtl, LB_ADDSTRING32, (WPARAM32)-1, (LPARAM)pstr );
+		    }
+            if( hMemObj )
+              GlobalFree16( hMemObj );
+		}
+	    }
+	}
+	break;
+
+    case WM_QUERYDROPOBJECT:
+	if( wParam == 0 )
+      { LPDRAGINFO lpDragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN((SEGPTR)lParam);
+	    if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA )
+        { RECT32 rect;
+		if( __get_dropline( hWnd, &rect ) )
+          { POINT32 pt = { lpDragInfo->pt.x, lpDragInfo->pt.y };
+		    rect.bottom += DROP_FIELD_HEIGHT;
+		    if( PtInRect32( &rect, pt ) )
+            { SetWindowLong32A( hWnd, DWL_MSGRESULT, 1 );
+			return TRUE;
+		    }
+		}
+	    }
+	}
+	break;
+
+    case WM_DROPOBJECT:
+	if( wParam == hWnd )
+      { LPDRAGINFO lpDragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN((SEGPTR)lParam);
+	    if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA && lpDragInfo->hList )
+        { char* pstr = (char*)GlobalLock16( (HGLOBAL16)(lpDragInfo->hList) );
+		if( pstr )
+          { static char __appendix_str[] = " with";
+
+		    hWndCtl = GetDlgItem32( hWnd, IDC_WINE_TEXT );
+		    SendMessage32A( hWndCtl, WM_GETTEXT, 512, (LPARAM)Template );
+		    if( !lstrncmp32A( Template, "WINE", 4 ) )
+			SetWindowText32A( GetDlgItem32(hWnd, IDC_STATIC_TEXT), Template );
+		    else
+          { char* pch = Template + strlen(Template) - strlen(__appendix_str);
+			*pch = '\0';
+			SendMessage32A( GetDlgItem32(hWnd, IDC_LISTBOX), LB_ADDSTRING32, 
+					(WPARAM32)-1, (LPARAM)Template );
+		    }
+
+		    lstrcpy32A( Template, pstr );
+		    lstrcat32A( Template, __appendix_str );
+		    SetWindowText32A( hWndCtl, Template );
+		    SetWindowLong32A( hWnd, DWL_MSGRESULT, 1 );
+		    return TRUE;
+		}
+	    }
+	}
+	break;
+
+    case WM_COMMAND:
+        if (wParam == IDOK)
+    {  EndDialog32(hWnd, TRUE);
+            return TRUE;
+        }
+        break;
+    }
+    return 0;
+}
+
+
+/*************************************************************************
+ *             ShellAbout32A   (SHELL32.243)
+ */
+BOOL32 WINAPI ShellAbout32A( HWND32 hWnd, LPCSTR szApp, LPCSTR szOtherStuff,
+                             HICON32 hIcon )
+{   ABOUT_INFO info;
+    TRACE(shell,"\n");
+    info.szApp        = szApp;
+    info.szOtherStuff = szOtherStuff;
+    info.hIcon        = hIcon;
+    if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) );
+    return DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd ),
+                         SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX ),
+                                      hWnd, AboutDlgProc32, (LPARAM)&info );
+}
+
+
+/*************************************************************************
+ *             ShellAbout32W   (SHELL32.244)
+ */
+BOOL32 WINAPI ShellAbout32W( HWND32 hWnd, LPCWSTR szApp, LPCWSTR szOtherStuff,
+                             HICON32 hIcon )
+{   BOOL32 ret;
+    ABOUT_INFO info;
+
+    TRACE(shell,"\n");
+    
+    info.szApp        = HEAP_strdupWtoA( GetProcessHeap(), 0, szApp );
+    info.szOtherStuff = HEAP_strdupWtoA( GetProcessHeap(), 0, szOtherStuff );
+    info.hIcon        = hIcon;
+    if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) );
+    ret = DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd ),
+                         SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX ),
+                                      hWnd, AboutDlgProc32, (LPARAM)&info );
+    HeapFree( GetProcessHeap(), 0, (LPSTR)info.szApp );
+    HeapFree( GetProcessHeap(), 0, (LPSTR)info.szOtherStuff );
+    return ret;
+}
+
+/*************************************************************************
+ *				Shell_NotifyIcon	[SHELL32.296]
+ *	FIXME
+ *	This function is supposed to deal with the systray.
+ *	Any ideas on how this is to be implimented?
+ */
+BOOL32 WINAPI Shell_NotifyIcon(	DWORD dwMessage, PNOTIFYICONDATA pnid )
+{   TRACE(shell,"\n");
+    return FALSE;
+}
+
+/*************************************************************************
+ *				Shell_NotifyIcon	[SHELL32.297]
+ *	FIXME
+ *	This function is supposed to deal with the systray.
+ *	Any ideas on how this is to be implimented?
+ */
+BOOL32 WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATA pnid )
+{   TRACE(shell,"\n");
+    return FALSE;
+}
+
+/*************************************************************************
+ * FreeIconList
+ */
+void WINAPI FreeIconList( DWORD dw )
+{ FIXME(shell, "(%lx): stub\n",dw);
+}
+
+/*************************************************************************
+ * SHGetPathFromIDList32A        [SHELL32.261][NT 4.0: SHELL32.220]
+ *
+ * PARAMETERS
+ *  pidl,   [IN] pidl 
+ *  pszPath [OUT] path
+ *
+ * RETURNS 
+ *  path from a passed PIDL.
+ *
+ * NOTES
+ *     exported by name
+ *
+ * FIXME
+ *  fnGetDisplayNameOf can return different types of OLEString
+ */
+DWORD WINAPI SHGetPathFromIDList32A (LPCITEMIDLIST pidl,LPSTR pszPath)
+{	STRRET lpName;
+	LPSHELLFOLDER shellfolder;
+  CHAR  buffer[MAX_PATH],tpath[MAX_PATH];
+  DWORD type,tpathlen=MAX_PATH,dwdisp;
+  HKEY  key;
+
+	TRACE(shell,"(pidl=%p,%p)\n",pidl,pszPath);
+
+  if (!pidl)
+  {  strcpy(buffer,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\");
+
+     if (RegCreateKeyEx32A(HKEY_CURRENT_USER,buffer,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&key,&dwdisp))
+     { return E_OUTOFMEMORY;
+     }
+     type=REG_SZ;    
+     strcpy (buffer,"Desktop");					/*registry name*/
+     if ( RegQueryValueEx32A(key,buffer,NULL,&type,tpath,&tpathlen))
+     { GetWindowsDirectory32A(tpath,MAX_PATH);
+       PathAddBackslash(tpath);
+       strcat (tpath,"Desktop");				/*folder name*/
+       RegSetValueEx32A(key,buffer,0,REG_SZ,tpath,tpathlen);
+       CreateDirectory32A(tpath,NULL);
+     }
+     RegCloseKey(key);
+     strcpy(pszPath,tpath);
+  }
+  else
+  { if (SHGetDesktopFolder(&shellfolder)==S_OK)
+	{ shellfolder->lpvtbl->fnGetDisplayNameOf(shellfolder,pidl,SHGDN_FORPARSING,&lpName);
+	  shellfolder->lpvtbl->fnRelease(shellfolder);
+	}
+  /*WideCharToLocal32(pszPath, lpName.u.pOleStr, MAX_PATH);*/
+	strcpy(pszPath,lpName.u.cStr);
+	/* fixme free the olestring*/
+  }
+	TRACE(shell,"-- (%s)\n",pszPath);
+	return NOERROR;
+}
+/*************************************************************************
+ * SHGetPathFromIDList32W [SHELL32.262]
+ */
+DWORD WINAPI SHGetPathFromIDList32W (LPCITEMIDLIST pidl,LPWSTR pszPath)
+{ FIXME (shell,"(pidl=%p %s):stub.\n", pidl, debugstr_w(pszPath));
+  return 0;
+}
+
+
+void (CALLBACK* pDLLInitComctl)();
+INT32 (CALLBACK* pImageList_AddIcon) (HIMAGELIST himl, HICON32 hIcon);
+INT32(CALLBACK* pImageList_ReplaceIcon) (HIMAGELIST, INT32, HICON32);
+HIMAGELIST (CALLBACK * pImageList_Create) (INT32,INT32,UINT32,INT32,INT32);
+HICON32 (CALLBACK * pImageList_GetIcon) (HIMAGELIST, INT32, UINT32);
+
+/*************************************************************************
+ * SHELL32 LibMain
+ *
+ * FIXME
+ *  at the moment the icons are extracted from shell32.dll
+ *  free the imagelists
+ */
+HINSTANCE32 shell32_hInstance; 
+
+BOOL32 WINAPI Shell32LibMain(HINSTANCE32 hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{ HICON32 htmpIcon;
+  UINT32 iiconindex;
+  UINT32 index;
+  CHAR   szShellPath[MAX_PATH];
+  HINSTANCE32 hComctl32;
+  
+
+  TRACE(shell,"0x%x 0x%lx %p\n", hinstDLL, fdwReason, lpvReserved);
+
+  shell32_hInstance = hinstDLL;
+  
+  GetWindowsDirectory32A(szShellPath,MAX_PATH);
+  PathAddBackslash(szShellPath);
+  strcat(szShellPath,"system\\shell32.dll");
+       
+  if (fdwReason==DLL_PROCESS_ATTACH)
+  { hComctl32 = LoadLibrary32A("COMCTL32.DLL");	
+    if (hComctl32)
+    { pDLLInitComctl=GetProcAddress32(hComctl32,"InitCommonControlsEx");
+      if (pDLLInitComctl)
+      { pDLLInitComctl();
+      }
+      pImageList_Create=GetProcAddress32(hComctl32,"ImageList_Create");
+      pImageList_AddIcon=GetProcAddress32(hComctl32,"ImageList_AddIcon");
+      pImageList_ReplaceIcon=GetProcAddress32(hComctl32,"ImageList_ReplaceIcon");
+      pImageList_GetIcon=GetProcAddress32(hComctl32,"ImageList_GetIcon");
+      FreeLibrary32(hComctl32);
+    }
+    else
+    { /* panic, imediately exit wine*/
+      ERR(shell,"P A N I C error getting functionpointers\n");
+      exit (1);
+    }
+    if ( ! ShellSmallIconList )
+    { if ( (ShellSmallIconList = pImageList_Create(sysMetrics[SM_CXSMICON],sysMetrics[SM_CYSMICON],0x101,0,0x20)) )
+      { for (index=0;index < 40; index++)
+        { if ( ! ( htmpIcon = ExtractIcon32A(hinstDLL, szShellPath, index))
+          || ( -1 == (iiconindex = pImageList_AddIcon (ShellSmallIconList, htmpIcon))) )
+          { ERR(shell,"could not initialize iconlist (is shell32.dll in the system directory?)\n");
+            break;
+          }
+        }
+      }
+    }
+    if ( ! ShellBigIconList )
+    { if ( (ShellBigIconList = pImageList_Create(SYSMETRICS_CXSMICON, SYSMETRICS_CYSMICON,0x101,0,0x20)) )
+      { for (index=0;index < 40; index++)
+        { if ( ! (htmpIcon = ExtractIcon32A( hinstDLL, szShellPath, index)) 
+           || (-1 == (iiconindex = pImageList_AddIcon (ShellBigIconList, htmpIcon))) )
+          { ERR(shell,"could not initialize iconlist (is shell32.dll in the system directory?)\n");
+            break;
+          }
+        }
+      }
+    }
+    TRACE(shell,"hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList);
+  }
+  return TRUE;
+}
diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h
new file mode 100644
index 0000000..da0d843
--- /dev/null
+++ b/dlls/shell32/shell32_main.h
@@ -0,0 +1,31 @@
+/*
+ * 	internal Shell32 Library definitions
+ */
+
+#ifndef __WINE_SHELL_MAIN_H
+#define __WINE_SHELL_MAIN_H
+
+/*******************************************
+*  global SHELL32.DLL variables
+*/
+extern HINSTANCE32 shell32_hInstance;
+extern UINT32      shell32_DllRefCount;
+extern HIMAGELIST ShellSmallIconList;
+extern HIMAGELIST ShellBigIconList;
+
+/*******************************************
+* pointer to functions dynamically loaded
+*/
+extern void (CALLBACK* pDLLInitComctl)();
+extern INT32 (CALLBACK* pImageList_AddIcon) (HIMAGELIST himl, HICON32 hIcon);
+extern INT32(CALLBACK* pImageList_ReplaceIcon) (HIMAGELIST, INT32, HICON32);
+extern HIMAGELIST (CALLBACK * pImageList_Create) (INT32,INT32,UINT32,INT32,INT32);
+extern HICON32 (CALLBACK * pImageList_GetIcon) (HIMAGELIST, INT32, UINT32);
+
+/* FIXME should be moved to a header file. IsEqualGUID 
+is declared but not exported in compobj.c !!!*/
+#define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID)))
+#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2)
+#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2)
+
+#endif
diff --git a/dlls/shell32/shellole.c b/dlls/shell32/shellole.c
new file mode 100644
index 0000000..fbbc42e
--- /dev/null
+++ b/dlls/shell32/shellole.c
@@ -0,0 +1,346 @@
+/*
+ *	Shell Folder stuff (...and all the OLE-Objects of SHELL32.DLL)
+ *
+ *	Copyright 1997	Marcus Meissner
+ *	Copyright 1998	Juergen Schmied  <juergen.schmied@metronet.de>
+ *
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ole.h"
+#include "ole2.h"
+#include "debug.h"
+#include "compobj.h"
+#include "interfaces.h"
+#include "shlobj.h"
+#include "shell.h"
+#include "winerror.h"
+#include "winnls.h"
+#include "winproc.h"
+#include "commctrl.h"
+
+#include "shell32_main.h"
+
+/*************************************************************************
+ *
+ */
+typedef DWORD (* WINAPI GetClassPtr)(REFCLSID,REFIID,LPVOID);
+
+static GetClassPtr SH_find_moduleproc(LPSTR dllname,HMODULE32 *xhmod,LPSTR name)
+{ HMODULE32  hmod;
+	FARPROC32	dllunload,nameproc;
+
+	if (xhmod)
+    { *xhmod = 0;
+    }
+	if (!strcasecmp(PathFindFilename(dllname),"shell32.dll"))
+	{ return (GetClassPtr)SHELL32_DllGetClassObject;
+    }
+
+	hmod = LoadLibraryEx32A(dllname,0,LOAD_WITH_ALTERED_SEARCH_PATH);
+	if (!hmod)
+	{ return NULL;
+    }
+	dllunload = GetProcAddress32(hmod,"DllCanUnloadNow");
+	if (!dllunload)
+	{ if (xhmod)
+      { *xhmod = hmod;
+      }
+    }
+	nameproc = GetProcAddress32(hmod,name);
+	if (!nameproc)
+    { FreeLibrary32(hmod);
+	  return NULL;
+	}
+	/* register unloadable dll with unloadproc ... */
+	return (GetClassPtr)nameproc;
+}
+/*************************************************************************
+ *
+ */
+static DWORD SH_get_instance(REFCLSID clsid,LPSTR dllname,LPVOID unknownouter,REFIID refiid,LPVOID inst) 
+{	GetClassPtr     dllgetclassob;
+	DWORD		hres;
+	LPCLASSFACTORY	classfac;
+
+	char	xclsid[50],xrefiid[50];
+	WINE_StringFromCLSID((LPCLSID)clsid,xclsid);
+	WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
+	TRACE(shell,"\n\tCLSID:%s,%s,%p,\n\tIID:%s,%p\n",xclsid, dllname,unknownouter,xrefiid,inst);
+	
+	dllgetclassob = SH_find_moduleproc(dllname,NULL,"DllGetClassObject");
+	if (!dllgetclassob)
+	{ return 0x80070000|GetLastError();
+    }
+
+/* FIXME */
+/*
+	hres = (*dllgetclassob)(clsid,(REFIID)&IID_IClassFactory,inst);
+	if (hres<0)
+		return hres;
+
+ */
+	hres = (*dllgetclassob)(clsid,(REFIID)&IID_IClassFactory,&classfac);
+	if (hres<0 || (hres>=0x80000000))
+	{ return hres;
+    }
+	if (!classfac)
+    { FIXME(shell,"no classfactory, but hres is 0x%ld!\n",hres);
+	  return E_FAIL;
+	}
+	classfac->lpvtbl->fnCreateInstance(classfac,unknownouter,refiid,inst);
+	classfac->lpvtbl->fnRelease(classfac);
+	return 0;
+}
+
+/*************************************************************************
+ * SHCoCreateInstance [SHELL32.102]
+ * 
+ * NOTES
+ *     exported by ordinal
+ */
+LRESULT WINAPI SHCoCreateInstance(LPSTR aclsid,CLSID *clsid,LPUNKNOWN unknownouter,REFIID refiid,LPVOID inst)
+{	char	buffer[256],xclsid[48],xiid[48],path[260],tmodel[100];
+	HKEY	inprockey;
+	DWORD	pathlen,type,tmodellen;
+	DWORD	hres;
+	
+	WINE_StringFromCLSID(refiid,xiid);
+
+	if (clsid)
+	{ WINE_StringFromCLSID(clsid,xclsid);
+    }
+	else
+	{ if (!aclsid)
+	  {	return 0x80040154;
+      }
+	  strcpy(xclsid,aclsid);
+	}
+	TRACE(shell,"(%p,\n\tSID:\t%s,%p,\n\tIID:\t%s,%p)\n",aclsid,xclsid,unknownouter,xiid,inst);
+
+	sprintf(buffer,"CLSID\\%s\\InProcServer32",xclsid);
+
+	if (RegOpenKeyEx32A(HKEY_CLASSES_ROOT,buffer,0,0x02000000,&inprockey))
+	{ return SH_get_instance(clsid,"shell32.dll",unknownouter,refiid,inst);
+    }
+	pathlen=sizeof(path);
+
+	if (RegQueryValue32A(inprockey,NULL,path,&pathlen))
+    { RegCloseKey(inprockey);
+	  return SH_get_instance(clsid,"shell32.dll",unknownouter,refiid,inst);
+	}
+
+	TRACE(shell, "Server dll is %s\n",path);
+	tmodellen=sizeof(tmodel);
+	type=REG_SZ;
+	if (RegQueryValueEx32A(inprockey,"ThreadingModel",NULL,&type,tmodel,&tmodellen))
+    { RegCloseKey(inprockey);
+	  return SH_get_instance(clsid,"shell32.dll",unknownouter,refiid,inst);
+	}
+
+	TRACE(shell, "Threading model is %s\n",tmodel);
+
+	hres=SH_get_instance(clsid,path,unknownouter,refiid,inst);
+	if (hres<0)
+    { hres=SH_get_instance(clsid,"shell32.dll",unknownouter,refiid,inst);
+    }
+	RegCloseKey(inprockey);
+	return hres;
+}
+
+
+/*************************************************************************
+ * SHELL32_DllGetClassObject   [SHELL32.128]
+ *
+ * [Standart OLE/COM Interface Method]
+ * This Function retrives the pointer to a specified interface (iid) of
+ * a given class (rclsid).
+ * With this pointer it's possible to call the IClassFactory_CreateInstance
+ * method to get a instance of the requested Class.
+ * This function does NOT instantiate the Class!!!
+ * 
+ * RETURNS
+ *   HRESULT
+ *
+ */
+DWORD WINAPI SHELL32_DllGetClassObject(REFCLSID rclsid,REFIID iid,LPVOID *ppv)
+{	HRESULT	hres = E_OUTOFMEMORY;
+	LPCLASSFACTORY lpclf;
+
+	char xclsid[50],xiid[50];
+	WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
+	WINE_StringFromCLSID((LPCLSID)iid,xiid);
+	TRACE(shell,"\n\tCLSID:\t%s,\n\tIID:\t%s\n",xclsid,xiid);
+	
+	*ppv = NULL;
+	if(IsEqualCLSID(rclsid, &CLSID_ShellDesktop)|| 
+	   IsEqualCLSID(rclsid, &CLSID_ShellLink))
+	{ if(IsEqualCLSID(rclsid, &CLSID_ShellDesktop))      /*debug*/
+	  { TRACE(shell,"requested CLSID_ShellDesktop\n");
+      }
+	  if(IsEqualCLSID(rclsid, &CLSID_ShellLink))         /*debug*/
+	  { TRACE(shell,"requested CLSID_ShellLink\n");
+      }
+	  lpclf = IClassFactory_Constructor();
+	  if(lpclf)
+	  { hres = lpclf->lpvtbl->fnQueryInterface(lpclf,iid, ppv);
+		lpclf->lpvtbl->fnRelease(lpclf);
+	  }
+	}
+	else
+	{ WARN(shell, "clsid(%s) not in buildin SHELL32\n",xclsid);
+	  hres = CLASS_E_CLASSNOTAVAILABLE;
+	}
+	TRACE(shell,"RETURN pointer to interface: %p\n",ppv);
+	return hres;
+}
+
+/*************************************************************************
+ *			 SHGetMalloc			[SHELL32.220]
+ * returns the interface to shell malloc.
+ *
+ * [SDK header win95/shlobj.h:
+ * equivalent to:  #define SHGetMalloc(ppmem)   CoGetMalloc(MEMCTX_TASK, ppmem)
+ * ]
+ * What we are currently doing is not very wrong, since we always use the same
+ * heap (ProcessHeap).
+ */
+DWORD WINAPI SHGetMalloc(LPMALLOC32 *lpmal) 
+{	TRACE(shell,"(%p)\n", lpmal);
+	return CoGetMalloc32(0,lpmal);
+}
+
+/**************************************************************************
+*  IClassFactory Implementation
+*/
+static HRESULT WINAPI IClassFactory_QueryInterface(LPCLASSFACTORY,REFIID,LPVOID*);
+static ULONG WINAPI IClassFactory_AddRef(LPCLASSFACTORY);
+static ULONG WINAPI IClassFactory_Release(LPCLASSFACTORY);
+static HRESULT WINAPI IClassFactory_CreateInstance();
+static HRESULT WINAPI IClassFactory_LockServer();
+/**************************************************************************
+ *  IClassFactory_VTable
+ */
+static IClassFactory_VTable clfvt = 
+{	IClassFactory_QueryInterface,
+	IClassFactory_AddRef,
+	IClassFactory_Release,
+	IClassFactory_CreateInstance,
+	IClassFactory_LockServer
+};
+
+/**************************************************************************
+ *  IClassFactory_Constructor
+ */
+
+LPCLASSFACTORY IClassFactory_Constructor()
+{	LPCLASSFACTORY	lpclf;
+
+	lpclf= (LPCLASSFACTORY)HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactory));
+	lpclf->ref = 1;
+	lpclf->lpvtbl = &clfvt;
+  TRACE(shell,"(%p)->()\n",lpclf);
+	return lpclf;
+}
+/**************************************************************************
+ *  IClassFactory::QueryInterface
+ */
+static HRESULT WINAPI IClassFactory_QueryInterface(
+  LPCLASSFACTORY this, REFIID riid, LPVOID *ppvObj)
+{  char	xriid[50];
+   WINE_StringFromCLSID((LPCLSID)riid,xriid);
+   TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",this,xriid);
+
+  *ppvObj = NULL;
+
+  if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
+  { *ppvObj = this; 
+  }
+  else if(IsEqualIID(riid, &IID_IClassFactory))  /*IClassFactory*/
+  {    *ppvObj = (IClassFactory*)this;
+  }   
+
+  if(*ppvObj)
+  { (*(LPCLASSFACTORY*)ppvObj)->lpvtbl->fnAddRef(this);  	
+    TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
+    return S_OK;
+  }
+	TRACE(shell,"-- Interface: E_NOINTERFACE\n");
+  return E_NOINTERFACE;
+}  
+/******************************************************************************
+ * IClassFactory_AddRef
+ */
+static ULONG WINAPI IClassFactory_AddRef(LPCLASSFACTORY this)
+{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
+	return ++(this->ref);
+}
+/******************************************************************************
+ * IClassFactory_Release
+ */
+static ULONG WINAPI IClassFactory_Release(LPCLASSFACTORY this)
+{	TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
+	if (!--(this->ref)) 
+	{ TRACE(shell,"-- destroying IClassFactory(%p)\n",this);
+		HeapFree(GetProcessHeap(),0,this);
+		return 0;
+	}
+	return this->ref;
+}
+/******************************************************************************
+ * IClassFactory_CreateInstance
+ */
+static HRESULT WINAPI IClassFactory_CreateInstance(
+  LPCLASSFACTORY this, LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject)
+{ IUnknown *pObj = NULL;
+	HRESULT hres;
+	char	xriid[50];
+
+  WINE_StringFromCLSID((LPCLSID)riid,xriid);
+  TRACE(shell,"%p->(%p,\n\tIID:\t%s,%p)\n",this,pUnknown,xriid,ppObject);
+
+	*ppObject = NULL;
+		
+	if(pUnknown)
+	{	return(CLASS_E_NOAGGREGATION);
+	}
+
+	if (IsEqualIID(riid, &IID_IShellFolder))
+  { pObj = (IUnknown *)IShellFolder_Constructor(NULL,NULL);
+  } 
+  else if (IsEqualIID(riid, &IID_IShellView))
+  { pObj = (IUnknown *)IShellView_Constructor();
+  } 
+  else if (IsEqualIID(riid, &IID_IShellLink))
+  { pObj = (IUnknown *)IShellLink_Constructor();
+  } 
+  else if (IsEqualIID(riid, &IID_IExtractIcon))
+  { pObj = (IUnknown *)IExtractIcon_Constructor(NULL);
+  } 
+  else if (IsEqualIID(riid, &IID_IContextMenu))
+  { pObj = (IUnknown *)IContextMenu_Constructor(NULL, NULL, 0);
+  } 
+  else
+  { ERR(shell,"unknown IID requested\n\tIID:\t%s\n",xriid);
+    return(E_NOINTERFACE);
+  }
+	
+  if (!pObj)
+  { return(E_OUTOFMEMORY);
+  }
+	 
+	hres = pObj->lpvtbl->fnQueryInterface(pObj,riid, ppObject);
+  pObj->lpvtbl->fnRelease(pObj);
+  TRACE(shell,"-- Object created: (%p)->%p\n",this,*ppObject);
+
+  return hres;
+}
+/******************************************************************************
+ * IClassFactory_LockServer
+ */
+static HRESULT WINAPI IClassFactory_LockServer(LPCLASSFACTORY this, BOOL32 fLock)
+{ TRACE(shell,"%p->(0x%x), not implemented\n",this, fLock);
+  return E_NOTIMPL;
+}
diff --git a/misc/shellord.c b/dlls/shell32/shellord.c
similarity index 71%
rename from misc/shellord.c
rename to dlls/shell32/shellord.c
index 9076838..ae9990f 100644
--- a/misc/shellord.c
+++ b/dlls/shell32/shellord.c
@@ -30,19 +30,8 @@
 #include "shlobj.h"
 #include "debug.h"
 #include "winreg.h"
+#include "shell32_main.h"
 
-void pdump (LPCITEMIDLIST pidl)
-{ DWORD type;
-  CHAR * szData;
-  LPITEMIDLIST pidltemp = pidl;
-  TRACE(shell,"---------- pidl=%p \n", pidl);
-  do
-  { szData = ((LPPIDLDATA )(pidltemp->mkid.abID))->szText;
-    type   = ((LPPIDLDATA )(pidltemp->mkid.abID))->type;
-    TRACE (shell,"---- pidl=%p size=%u type=%lx %s\n",pidltemp, pidltemp->mkid.cb,type,debugstr_a(szData));
-    pidltemp = (LPITEMIDLIST)(((BYTE*)pidltemp)+pidltemp->mkid.cb);
-  } while (pidltemp->mkid.cb);
-}
 /*************************************************************************
  * SHChangeNotifyRegister [SHELL32.2]
  * NOTES
@@ -69,116 +58,6 @@
 {	FIXME(shell,"(0x%08lx,0x%08lx):stub.\n",x1,x2);
 	return 0;
 }
-/*************************************************************************
- *	 		 ILGetDisplayName			[SHELL32.15]
- * get_path_from_itemlist(itemlist,path); ? not sure...
- */
-BOOL32 WINAPI ILGetDisplayName(LPCITEMIDLIST iil,LPSTR path) {
-	FIXME(shell,"(%p,%p),stub, return e:!\n",iil,path);
-	strcpy(path,"e:\\");
-	return TRUE;
-}
-/*************************************************************************
- * ILFindLastID [SHELL32.16]
- */
-LPSHITEMID WINAPI ILFindLastID(LPITEMIDLIST iil) {
-	LPSHITEMID	lastsii,sii;
-
-  TRACE(shell,"%p\n",iil);
-	if (!iil)
-		return NULL;
-	sii = &(iil->mkid);
-	lastsii = sii;
-	while (sii->cb) {
-		lastsii = sii;
-		sii = (LPSHITEMID)(((char*)sii)+sii->cb);
-	}
-	return lastsii;
-}
-/*************************************************************************
- * ILFindLastID [SHELL32.17]
- * NOTES
- *  Creates a new list with the last item removed
- */
-LPITEMIDLIST WINAPI ILRemoveLastID(LPCITEMIDLIST pidl)
-{ TRACE(shell,"pidl=%p\n",pidl);
-  return NULL;
-}
-
-
-/*************************************************************************
- * ILClone [SHELL32.18]
- *
- * NOTES
- *    dupicate an idlist
- */
-LPITEMIDLIST WINAPI ILClone (LPCITEMIDLIST pidl)
-{ DWORD    len;
-  LPITEMIDLIST  newpidl;
-
-  TRACE(shell,"%p\n",pidl);
-
-  if (!pidl)
-    return NULL;
-    
-  len = ILGetSize(pidl);
-  newpidl = (LPITEMIDLIST)SHAlloc(len);
-  if (newpidl)
-    memcpy(newpidl,pidl,len);
-  return newpidl;
-}
-
-/*************************************************************************
- * ILCloneFirst [SHELL32.19]
- *
- * NOTES
- *  duplicates the first idlist of a complex pidl
- */
-LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST pidl)
-{ FIXME(shell,"pidl=%p\n",pidl);
-  return NULL;
-}
-
-/*************************************************************************
- * ILCombine [SHELL32.25]
- *
- * NOTES
- *  Concatenates two complex idlists.
- *  The pidl is the first one, pidlsub the next one
- *  Does not destroy the passed in idlists!
- */
-LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2)
-{ DWORD    len1,len2;
-  LPITEMIDLIST  pidlNew;
-  
-  TRACE(shell,"pidl=%p pidl=%p\n",pidl1,pidl2);
-
-  if(!pidl1 && !pidl2)
-  {  return NULL;
-  }
- 
-  if(!pidl1)
-  { pidlNew = ILClone(pidl2);
-    return pidlNew;
-  }
-
-  if(!pidl2)
-  { pidlNew = ILClone(pidl1);
-    return pidlNew;
-  }
-
-  len1  = ILGetSize(pidl1)-2;
-  len2  = ILGetSize(pidl2);
-  pidlNew  = SHAlloc(len1+len2);
-  
-  if (pidlNew)
-  { memcpy(pidlNew,pidl1,len1);
-    memcpy(((BYTE *)pidlNew)+len1,pidl2,len2);
-  }
-
-/*  TRACE(shell,"--new pidl=%p\n",pidlNew);*/
-  return pidlNew;
-}
 
 /*************************************************************************
  * PathIsRoot [SHELL32.29]
@@ -279,14 +158,14 @@
  * NOTES
  *     basename(char *fn);
  */
-LPSTR WINAPI PathFindFilename(LPSTR fn) {
-    LPSTR basefn;
-  TRACE(shell,"%s\n",fn);
+LPSTR WINAPI PathFindFilename(LPSTR fn)
+{	LPSTR basefn;
+	TRACE(shell,"%s\n",fn);
     basefn = fn;
-    while (fn[0]) {
-    	if (((fn[0]=='\\') || (fn[0]==':')) && fn[1] && fn[1]!='\\')
-	    basefn = fn+1;
-	fn++;
+    while (fn[0]) 
+    { if (((fn[0]=='\\') || (fn[0]==':')) && fn[1] && fn[1]!='\\')
+	  basefn = fn+1;
+	  fn++;
     }
     return basefn;
 }
@@ -486,17 +365,6 @@
 	);
 	return 0;
 }
-/*************************************************************************
- * Shell_GetImageList [SHELL32.71]
- * 
- * NOTES
- *     returns internal shell values in the passed pointers
- */
-BOOL32 WINAPI Shell_GetImageList(LPDWORD x,LPDWORD y) {
-
-	FIXME(shell,"(%p,%p):stub.\n",x,y);
-	return TRUE;
-}
 
 /*************************************************************************
  * Shell_GetCachedImageIndex [SHELL32.72]
@@ -558,6 +426,8 @@
  * 
  * NOTES
  *     exported by ordinal
+ * FIXME
+ *  wrong implemented OleStr is NOT wide string !!!! (jsch)
  */
 BOOL32 WINAPI
 OleStrToStrN (LPSTR lpMulti, INT32 nMulti, LPCWSTR lpWide, INT32 nWide) {
@@ -570,7 +440,9 @@
  *
  * NOTES
  *     exported by ordinal
- */
+ * FIXME
+ *  wrong implemented OleStr is NOT wide string !!!! (jsch)
+*/
 BOOL32 WINAPI
 StrToOleStrN (LPWSTR lpWide, INT32 nWide, LPCSTR lpMulti, INT32 nMulti) {
     return MultiByteToWideChar (0, 0, lpMulti, nMulti, lpWide, nWide);
@@ -632,125 +504,6 @@
 }
 
 /*************************************************************************
- *
- */
-typedef DWORD (* WINAPI GetClassPtr)(REFCLSID,REFIID,LPVOID);
-
-static GetClassPtr SH_find_moduleproc(LPSTR dllname,HMODULE32 *xhmod,
-                                      LPSTR name)
-{ HMODULE32  hmod;
-	FARPROC32	dllunload,nameproc;
-
-	if (xhmod) *xhmod = 0;
-	if (!strcasecmp(PathFindFilename(dllname),"shell32.dll"))
-		return (GetClassPtr)SHELL32_DllGetClassObject;
-
-	hmod = LoadLibraryEx32A(dllname,0,LOAD_WITH_ALTERED_SEARCH_PATH);
-	if (!hmod)
-		return NULL;
-	dllunload = GetProcAddress32(hmod,"DllCanUnloadNow");
-	if (!dllunload)
-		if (xhmod) *xhmod = hmod;
-	nameproc = GetProcAddress32(hmod,name);
-	if (!nameproc) {
-		FreeLibrary32(hmod);
-		return NULL;
-	}
-	/* register unloadable dll with unloadproc ... */
-	return (GetClassPtr)nameproc;
-}
-/*************************************************************************
- *
- */
-static DWORD SH_get_instance(
-    REFCLSID clsid,
-		LPSTR dllname,
-	  LPVOID unknownouter,
-		REFIID refiid,
-		LPVOID inst) 
-{ GetClassPtr     dllgetclassob;
-	DWORD		hres;
-	LPCLASSFACTORY	classfac;
-
-  char	xclsid[50],xrefiid[50];
-  WINE_StringFromCLSID((LPCLSID)clsid,xclsid);
-  WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
-  TRACE(shell,"\n\tCLSID:%s,%s,%p,\n\tIID:%s,%p\n",
-	   xclsid, dllname,unknownouter,xrefiid,inst);
-	
-	dllgetclassob = SH_find_moduleproc(dllname,NULL,"DllGetClassObject");
-	if (!dllgetclassob)
-		return 0x80070000|GetLastError();
-
-/* FIXME */
-/*
-	hres = (*dllgetclassob)(clsid,(REFIID)&IID_IClassFactory,inst);
-	if (hres<0)
-		return hres;
-
- */
-	hres = (*dllgetclassob)(clsid,(REFIID)&IID_IClassFactory,&classfac);
-	if (hres<0 || (hres>=0x80000000))
-		return hres;
-	if (!classfac) {
-		FIXME(shell,"no classfactory, but hres is 0x%ld!\n",hres);
-		return E_FAIL;
-	}
-	classfac->lpvtbl->fnCreateInstance(classfac,unknownouter,refiid,inst);
-	classfac->lpvtbl->fnRelease(classfac);
-	return 0;
-}
-
-/*************************************************************************
- * SHCoCreateInstance [SHELL32.102]
- * 
- * NOTES
- *     exported by ordinal
- */
-LRESULT WINAPI SHCoCreateInstance(
-	LPSTR aclsid,CLSID *clsid,LPUNKNOWN unknownouter,REFIID refiid,LPVOID inst
-) {
-	char	buffer[256],xclsid[48],xiid[48],path[260],tmodel[100];
-	HKEY	inprockey;
-	DWORD	pathlen,type,tmodellen;
-	DWORD	hres;
-	
-	WINE_StringFromCLSID(refiid,xiid);
-
-	if (clsid)
-		WINE_StringFromCLSID(clsid,xclsid);
-	else {
-		if (!aclsid)
-		    return 0x80040154;
-		strcpy(xclsid,aclsid);
-	}
-	TRACE(shell,"(%p,\n\tSID:\t%s,%p,\n\tIID:\t%s,%p)\n",aclsid,xclsid,unknownouter,xiid,inst);
-
-	sprintf(buffer,"CLSID\\%s\\InProcServer32",xclsid);
-	if (RegOpenKeyEx32A(HKEY_CLASSES_ROOT,buffer,0,0x02000000,&inprockey))
-		return SH_get_instance(clsid,"shell32.dll",unknownouter,refiid,inst);
-	pathlen=sizeof(path);
-	if (RegQueryValue32A(inprockey,NULL,path,&pathlen)) {
-		RegCloseKey(inprockey);
-		return SH_get_instance(clsid,"shell32.dll",unknownouter,refiid,inst);
-	}
-	TRACE(shell, "Server dll is %s\n",path);
-	tmodellen=sizeof(tmodel);
-	type=REG_SZ;
-	if (RegQueryValueEx32A(inprockey,"ThreadingModel",NULL,&type,tmodel,&tmodellen)) {
-		RegCloseKey(inprockey);
-		return SH_get_instance(clsid,"shell32.dll",unknownouter,refiid,inst);
-	}
-	TRACE(shell, "Threading model is %s\n",tmodel);
-	hres=SH_get_instance(clsid,path,unknownouter,refiid,inst);
-	if (hres<0)
-		hres=SH_get_instance(clsid,"shell32.dll",unknownouter,refiid,inst);
-	RegCloseKey(inprockey);
-	return hres;
-}
-
-
-/*************************************************************************
  * ShellMessageBoxA [SHELL32.183]
  *
  * Format and output errormessage.
@@ -775,7 +528,6 @@
 	/*MessageBox32A(hwnd,buf3,buf,id|0x10000);*/
 }
 
-
 /*************************************************************************
  * SHRestricted [SHELL32.100]
  *
@@ -817,49 +569,6 @@
 }
 
 /*************************************************************************
- * ILGetSize [SHELL32.152]
- *  gets the byte size of an idlist including zero terminator (pidl)
- *
- * PARAMETERS
- *  pidl ITEMIDLIST
- *
- * RETURNS
- *  size of pidl
- *
- * NOTES
- *  exported by ordinal
- */
-DWORD WINAPI ILGetSize(LPITEMIDLIST pidl)
-{ LPSHITEMID si = &(pidl->mkid);
-  DWORD  len=0;
-
-  TRACE(shell,"pidl=%p\n",pidl);
-
-  if (pidl)
-  { while (si->cb) 
-    { len += si->cb;
-      si  = (LPSHITEMID)(((LPBYTE)si)+si->cb);
-    }
-    len += 2;
-	}
-/*  TRACE(shell,"-- size=%lu\n",len);*/
-	return len;
-}
-/*************************************************************************
- * ILAppend [SHELL32.154]
- *
- * NOTES
- *  Adds the single item to the idlist indicated by pidl.
- *  if bEnd is 0, adds the item to the front of the list,
- *  otherwise adds the item to the end.
- *  Destroys the passed in idlist!
- */
-LPITEMIDLIST WINAPI ILAppend(LPITEMIDLIST pidl,LPCITEMIDLIST item,BOOL32 bEnd)
-{ TRACE(shell,"(pidl=%p,pidl=%p,%08u)\n",pidl,item,bEnd);
-  return NULL;
-}
-
-/*************************************************************************
  * PathGetExtension [SHELL32.158]
  *
  * NOTES
@@ -918,22 +627,6 @@
   return ret;
 }
 
-
-/*************************************************************************
- * ILFree [SHELL32.155]
- *
- * NOTES
- *     free_check_ptr - frees memory (if not NULL)
- *     allocated by SHMalloc allocator
- *     exported by ordinal
- */
-DWORD WINAPI ILFree(LPVOID pidl) 
-{ TRACE (shell,"(pidl=0x%08lx)\n",(DWORD)pidl);
-  if (!pidl)
-		return 0;
-  return SHFree(pidl);
-}
-
 /*************************************************************************
  * OpenRegStream [SHELL32.85]
  *
@@ -969,7 +662,6 @@
     return 0;
 }
 
-
 /*************************************************************************
  * RunFileDlg [SHELL32.61]
  *
@@ -985,7 +677,6 @@
     return 0;
 }
 
-
 /*************************************************************************
  * ExitWindowsDialog [SHELL32.60]
  *
@@ -999,7 +690,6 @@
     return 0;
 }
 
-
 /*************************************************************************
  * ArrangeWindows [SHELL32.184]
  * 
@@ -1013,7 +703,6 @@
     return 0;
 }
 
-
 /*************************************************************************
  * SHCLSIDFromString [SHELL32.147]
  *
@@ -1024,7 +713,6 @@
 SHCLSIDFromString (DWORD dwParam1, DWORD dwParam2)
 {
     FIXME (shell,"(0x%lx 0x%lx):stub.\n", dwParam1, dwParam2);
-
     FIXME (shell,"(\"%s\" \"%s\"):stub.\n", (LPSTR)dwParam1, (LPSTR)dwParam2);
 
     return 0;
@@ -1123,8 +811,8 @@
  * ShellExecuteEx [SHELL32.291]
  *
  */
-HRESULT WINAPI ShellExecuteEx (DWORD u)
-{ FIXME(shell,"0x%08lx stub\n",u);
+BOOL32 WINAPI ShellExecuteEx32A (LPSHELLEXECUTEINFOA u)
+{ FIXME(shell,"%p stub\n",u);
   return 0;
 }
 /*************************************************************************
diff --git a/dlls/shell32/shlfolder.c b/dlls/shell32/shlfolder.c
new file mode 100644
index 0000000..4a516cf
--- /dev/null
+++ b/dlls/shell32/shlfolder.c
@@ -0,0 +1,782 @@
+/*
+ *	Shell Folder stuff (...and all the OLE-Objects of SHELL32.DLL)
+ *
+ *	Copyright 1997	Marcus Meissner
+ *	Copyright 1998	Juergen Schmied
+ *
+ *  !!! currently work in progress on all classes 980818 !!!
+ *  <contact juergen.schmied@metronet.de>
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ole.h"
+#include "ole2.h"
+#include "debug.h"
+#include "compobj.h"
+#include "interfaces.h"
+#include "shlobj.h"
+#include "shell.h"
+#include "winerror.h"
+#include "winnls.h"
+#include "winproc.h"
+#include "commctrl.h"
+
+#include "shell32_main.h"
+
+static HRESULT WINAPI IShellFolder_QueryInterface(LPSHELLFOLDER,REFIID,LPVOID*);
+static ULONG WINAPI IShellFolder_AddRef(LPSHELLFOLDER);
+static ULONG WINAPI IShellFolder_Release(LPSHELLFOLDER);
+static HRESULT WINAPI IShellFolder_Initialize(LPSHELLFOLDER,LPCITEMIDLIST);
+static HRESULT WINAPI IShellFolder_ParseDisplayName(LPSHELLFOLDER,HWND32,LPBC,LPOLESTR32,DWORD*,LPITEMIDLIST*,DWORD*);
+static HRESULT WINAPI IShellFolder_EnumObjects(LPSHELLFOLDER,HWND32,DWORD,LPENUMIDLIST*);
+static HRESULT WINAPI IShellFolder_BindToObject(LPSHELLFOLDER,LPCITEMIDLIST,LPBC,REFIID,LPVOID*);
+static HRESULT WINAPI IShellFolder_BindToStorage(LPSHELLFOLDER,LPCITEMIDLIST,LPBC,REFIID,LPVOID*);
+static HRESULT WINAPI IShellFolder_CompareIDs(LPSHELLFOLDER,LPARAM,LPCITEMIDLIST,LPCITEMIDLIST);
+static HRESULT WINAPI IShellFolder_CreateViewObject(LPSHELLFOLDER,HWND32,REFIID,LPVOID*);
+static HRESULT WINAPI IShellFolder_GetAttributesOf(LPSHELLFOLDER,UINT32,LPCITEMIDLIST*,DWORD*);
+static HRESULT WINAPI IShellFolder_GetUIObjectOf(LPSHELLFOLDER,HWND32,UINT32,LPCITEMIDLIST*,REFIID,UINT32*,LPVOID*);
+static HRESULT WINAPI IShellFolder_GetDisplayNameOf(LPSHELLFOLDER,LPCITEMIDLIST,DWORD,LPSTRRET);
+static HRESULT WINAPI IShellFolder_SetNameOf(LPSHELLFOLDER,HWND32,LPCITEMIDLIST,LPCOLESTR32,DWORD,LPITEMIDLIST*);
+static BOOL32 WINAPI IShellFolder_GetFolderPath(LPSHELLFOLDER,LPSTR,DWORD);
+
+/***************************************************************************
+ *  GetNextElement (internal function)
+ *
+ * gets a part of a string till the first backslash
+ *
+ * PARAMETERS
+ *  pszNext [IN] string to get the element from
+ *  pszOut  [IN] pointer to buffer whitch receives string
+ *  dwOut   [IN] length of pszOut
+ *
+ *  RETURNS
+ *    LPSTR pointer to first, not yet parsed char
+ */
+LPSTR GetNextElement(LPSTR pszNext,LPSTR pszOut,DWORD dwOut)
+{ LPSTR   pszTail = pszNext;
+  DWORD dwCopy;
+  TRACE(shell,"(%s %p 0x%08lx)\n",debugstr_a(pszNext),pszOut,dwOut);
+
+  if(!pszNext || !*pszNext)
+    return NULL;
+
+  while(*pszTail && (*pszTail != '\\'))
+  { pszTail++;
+  }
+  dwCopy=((LPBYTE)pszTail-(LPBYTE)pszNext)/sizeof(CHAR)+1;
+  lstrcpyn32A(pszOut, pszNext, (dwOut<dwCopy)? dwOut : dwCopy);
+
+  if(*pszTail)
+  {  pszTail++;
+	}
+
+  TRACE(shell,"--(%s %s 0x%08lx)\n",debugstr_a(pszNext),debugstr_a(pszOut),dwOut);
+  return pszTail;
+}
+
+/***********************************************************************
+*   IShellFolder implementation
+*/
+static struct IShellFolder_VTable sfvt = 
+{ IShellFolder_QueryInterface,
+  IShellFolder_AddRef,
+  IShellFolder_Release,
+  IShellFolder_ParseDisplayName,
+  IShellFolder_EnumObjects,
+  IShellFolder_BindToObject,
+  IShellFolder_BindToStorage,
+  IShellFolder_CompareIDs,
+  IShellFolder_CreateViewObject,
+  IShellFolder_GetAttributesOf,
+  IShellFolder_GetUIObjectOf,
+  IShellFolder_GetDisplayNameOf,
+  IShellFolder_SetNameOf,
+  IShellFolder_GetFolderPath
+};
+/**************************************************************************
+*	  IShellFolder_Constructor
+*/
+
+LPSHELLFOLDER IShellFolder_Constructor(LPSHELLFOLDER pParent,LPITEMIDLIST pidl) 
+{ LPSHELLFOLDER    sf;
+	DWORD dwSize=0;
+  sf=(LPSHELLFOLDER)HeapAlloc(GetProcessHeap(),0,sizeof(IShellFolder));
+  sf->ref=1;
+  sf->lpvtbl=&sfvt;
+  sf->mlpszFolder=NULL;
+	sf->mpSFParent=pParent;
+
+	TRACE(shell,"(%p)->(parent=%p, pidl=%p)\n",sf,pParent, pidl);
+	
+	/* create own pidl-manager*/
+  sf->pPidlMgr  = PidlMgr_Constructor();
+	if (! sf->pPidlMgr )
+	{ HeapFree(GetProcessHeap(),0,sf);
+	  ERR (shell,"-- Could not initialize PidMGR\n");
+	  return NULL;
+	}
+
+  /* keep a copy of the pidl in the instance*/
+  sf->mpidl = ILClone(pidl);
+	sf->mpidlNSRoot = NULL;
+	
+  if(sf->mpidl)        /* do we have a pidl?*/
+  { dwSize = 0;
+    if(sf->mpSFParent->mlpszFolder)
+    { dwSize += strlen(sf->mpSFParent->mlpszFolder) + 1;
+    }   
+    dwSize += sf->pPidlMgr->lpvtbl->fnGetFolderText(sf->pPidlMgr,sf->mpidl,NULL,0);
+    sf->mlpszFolder = SHAlloc(dwSize);
+    if(sf->mlpszFolder)
+    { *(sf->mlpszFolder)=0x00;
+      if(sf->mpSFParent->mlpszFolder)
+      {  strcpy(sf->mlpszFolder, sf->mpSFParent->mlpszFolder);
+         PathAddBackslash (sf->mlpszFolder);
+      }
+      sf->pPidlMgr->lpvtbl->fnGetFolderText(sf->pPidlMgr, sf->mpidl, sf->mlpszFolder+strlen(sf->mlpszFolder), dwSize-strlen(sf->mlpszFolder));
+    }
+  }
+	
+  TRACE(shell,"-- (%p)->(%p,%p,parent=%s)\n",sf,pParent, pidl, debugstr_a(sf->mlpszFolder));
+	return sf;
+}
+/**************************************************************************
+*  IShellFolder::QueryInterface
+* PARAMETERS
+*  REFIID riid,        //[in ] Requested InterfaceID
+*  LPVOID* ppvObject)  //[out] Interface* to hold the result
+*/
+static HRESULT WINAPI IShellFolder_QueryInterface(
+  LPSHELLFOLDER this, REFIID riid, LPVOID *ppvObj)
+{  char	xriid[50];
+   WINE_StringFromCLSID((LPCLSID)riid,xriid);
+   TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);
+
+  *ppvObj = NULL;
+
+  if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
+  { *ppvObj = this; 
+  }
+  else if(IsEqualIID(riid, &IID_IShellFolder))  /*IShellFolder*/
+  {    *ppvObj = (IShellFolder*)this;
+  }   
+
+  if(*ppvObj)
+  { (*(LPSHELLFOLDER*)ppvObj)->lpvtbl->fnAddRef(this);  	
+    TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
+		return S_OK;
+  }
+	TRACE(shell,"-- Interface: E_NOINTERFACE\n");
+	return E_NOINTERFACE;
+}   
+
+/**************************************************************************
+*  IShellFolder::AddRef
+*/
+
+static ULONG WINAPI IShellFolder_AddRef(LPSHELLFOLDER this)
+{	TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
+	return ++(this->ref);
+}
+
+/**************************************************************************
+ *  IShellFolder_Release
+ */
+static ULONG WINAPI IShellFolder_Release(LPSHELLFOLDER this) 
+{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
+  if (!--(this->ref)) 
+  { TRACE(shell,"-- destroying IShellFolder(%p)\n",this);
+
+		if (pdesktopfolder==this)
+		{ pdesktopfolder=NULL;
+		  TRACE(shell,"-- destroyed IShellFolder(%p) was Desktopfolder\n",this);
+		}
+    if (this->pPidlMgr)
+    { PidlMgr_Destructor(this->pPidlMgr);
+    }
+    if(this->mpidlNSRoot)
+    { SHFree(this->mpidlNSRoot);
+    }
+    if(this->mpidl)
+    { SHFree(this->mpidl);
+    }
+    if(this->mlpszFolder)
+    { SHFree(this->mlpszFolder);
+    }
+
+		HeapFree(GetProcessHeap(),0,this);
+
+		return 0;
+	}
+	return this->ref;
+}
+/**************************************************************************
+*		IShellFolder_ParseDisplayName
+* PARAMETERS
+*  HWND          hwndOwner,      //[in ] Parent window for any message's
+*  LPBC          pbc,            //[in ] reserved
+*  LPOLESTR      lpszDisplayName,//[in ] "Unicode" displayname.
+*  ULONG*        pchEaten,       //[out] (unicode) characters processed
+*  LPITEMIDLIST* ppidl,          //[out] complex pidl to item
+*  ULONG*        pdwAttributes   //[out] items attributes
+*
+* FIXME: 
+*    pdwAttributes: not used
+*/
+static HRESULT WINAPI IShellFolder_ParseDisplayName(
+	LPSHELLFOLDER this,
+	HWND32 hwndOwner,
+	LPBC pbcReserved,
+    LPOLESTR32 lpszDisplayName,
+    DWORD *pchEaten,
+    LPITEMIDLIST *ppidl,
+	DWORD *pdwAttributes)
+{	HRESULT        hr=E_OUTOFMEMORY;
+  LPITEMIDLIST   pidlFull=NULL, pidlTemp = NULL, pidlOld = NULL;
+  LPSTR          pszNext=NULL;
+  CHAR           szElement[MAX_PATH];
+  BOOL32         bType;
+
+  DWORD          dwChars=lstrlen32W(lpszDisplayName) + 1;
+  LPSTR          pszTemp=(LPSTR)HeapAlloc(GetProcessHeap(),0,dwChars * sizeof(CHAR));
+       
+  TRACE(shell,"(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
+	this,hwndOwner,pbcReserved,lpszDisplayName,debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
+
+  if(pszTemp)
+  { hr = E_FAIL;
+    WideCharToLocal32(pszTemp, lpszDisplayName, dwChars);
+    if(*pszTemp)
+    { if (strcmp(pszTemp,"Desktop")==0)
+      { pidlFull = (LPITEMIDLIST)HeapAlloc(GetProcessHeap(),0,2);
+			  pidlFull->mkid.cb = 0;
+			}
+		  else
+			{ pidlFull = this->pPidlMgr->lpvtbl->fnCreateMyComputer(this->pPidlMgr);
+
+        /* check if the lpszDisplayName is Folder or File*/
+  			bType = ! (GetFileAttributes32A(pszNext)&FILE_ATTRIBUTE_DIRECTORY);
+  			pszNext = GetNextElement(pszTemp, szElement, MAX_PATH);
+  
+        pidlTemp = this->pPidlMgr->lpvtbl->fnCreateDrive(this->pPidlMgr,szElement);			
+        pidlOld = pidlFull;
+        pidlFull = ILCombine(pidlFull,pidlTemp);
+        SHFree(pidlOld);
+  
+  			if(pidlFull)
+        { while((pszNext=GetNextElement(pszNext, szElement, MAX_PATH)))
+          { if(!*pszNext && bType)
+  					{ pidlTemp = this->pPidlMgr->lpvtbl->fnCreateValue(this->pPidlMgr,szElement);
+  					}
+  					else				
+            { pidlTemp = this->pPidlMgr->lpvtbl->fnCreateFolder(this->pPidlMgr,szElement);
+  					}
+            pidlOld = pidlFull;
+            pidlFull = ILCombine(pidlFull,pidlTemp);
+            SHFree(pidlOld);
+          }
+          hr = S_OK;
+        }
+      }
+		}
+  }
+	HeapFree(GetProcessHeap(),0,pszTemp);
+  *ppidl = pidlFull;
+  return hr;
+}
+
+/**************************************************************************
+*		IShellFolder_EnumObjects
+* PARAMETERS
+*  HWND          hwndOwner,    //[in ] Parent Window
+*  DWORD         grfFlags,     //[in ] SHCONTF enumeration mask
+*  LPENUMIDLIST* ppenumIDList  //[out] IEnumIDList interface
+*/
+static HRESULT WINAPI IShellFolder_EnumObjects(
+	LPSHELLFOLDER this,
+	HWND32 hwndOwner,
+	DWORD dwFlags,
+	LPENUMIDLIST* ppEnumIDList)
+{ HRESULT  hr;
+	TRACE(shell,"(%p)->(HWND=0x%08x,0x%08lx,%p)\n",this,hwndOwner,dwFlags,ppEnumIDList);
+
+  *ppEnumIDList = NULL;
+	*ppEnumIDList = IEnumIDList_Constructor (this->mlpszFolder, dwFlags, &hr);
+  TRACE(shell,"-- (%p)->(new ID List: %p)\n",this,*ppEnumIDList);
+  if(!*ppEnumIDList)
+  { return hr;
+  }
+  return S_OK;		
+}
+/**************************************************************************
+ *  IShellFolder_Initialize()
+ *  IPersistFolder Method
+ */
+static HRESULT WINAPI IShellFolder_Initialize(
+	LPSHELLFOLDER this,
+	LPCITEMIDLIST pidl)
+{ TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl);
+  if(this->mpidlNSRoot)
+  { SHFree(this->mpidlNSRoot);
+    this->mpidlNSRoot = NULL;
+  }
+  this->mpidlNSRoot=ILClone(pidl);
+  return S_OK;
+}
+
+/**************************************************************************
+*		IShellFolder_BindToObject
+* PARAMETERS
+*  LPCITEMIDLIST pidl,       //[in ] complex pidl to open
+*  LPBC          pbc,        //[in ] reserved
+*  REFIID        riid,       //[in ] Initial Interface
+*  LPVOID*       ppvObject   //[out] Interface*
+*/
+static HRESULT WINAPI IShellFolder_BindToObject(
+	LPSHELLFOLDER this,
+	LPCITEMIDLIST pidl,
+	LPBC pbcReserved,
+	REFIID riid,
+	LPVOID * ppvOut)
+{	char	        xriid[50];
+  HRESULT       hr;
+	LPSHELLFOLDER pShellFolder;
+	
+	WINE_StringFromCLSID(riid,xriid);
+
+	TRACE(shell,"(%p)->(pidl=%p,%p,\n\tIID:%s,%p)\n",this,pidl,pbcReserved,xriid,ppvOut);
+
+  *ppvOut = NULL;
+  pShellFolder = IShellFolder_Constructor(this, pidl);
+  if(!pShellFolder)
+    return E_OUTOFMEMORY;
+  /*  pShellFolder->lpvtbl->fnInitialize(pShellFolder, this->mpidlNSRoot);*/
+  IShellFolder_Initialize(pShellFolder, this->mpidlNSRoot);
+  hr = pShellFolder->lpvtbl->fnQueryInterface(pShellFolder, riid, ppvOut);
+  pShellFolder->lpvtbl->fnRelease(pShellFolder);
+	TRACE(shell,"-- (%p)->(interface=%p)\n",this, ppvOut);
+  return hr;
+}
+
+/**************************************************************************
+*  IShellFolder_BindToStorage
+* PARAMETERS
+*  LPCITEMIDLIST pidl,       //[in ] complex pidl to store
+*  LPBC          pbc,        //[in ] reserved
+*  REFIID        riid,       //[in ] Initial storage interface 
+*  LPVOID*       ppvObject   //[out] Interface* returned
+*/
+static HRESULT WINAPI IShellFolder_BindToStorage(
+  	LPSHELLFOLDER this,
+    LPCITEMIDLIST pidl, /*simple/complex pidl*/
+    LPBC pbcReserved, 
+    REFIID riid, 
+    LPVOID *ppvOut)
+{	char xriid[50];
+	WINE_StringFromCLSID(riid,xriid);
+
+	FIXME(shell,"(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",this,pidl,pbcReserved,xriid,ppvOut);
+
+  *ppvOut = NULL;
+  return E_NOTIMPL;
+}
+
+/**************************************************************************
+*  IShellFolder_CompareIDs
+*
+* PARMETERS
+*  LPARAM        lParam, //[in ] Column?
+*  LPCITEMIDLIST pidl1,  //[in ] simple pidl
+*  LPCITEMIDLIST pidl2)  //[in ] simple pidl
+* FIXME
+*  we have to handle simple pidl's only
+*/
+static HRESULT WINAPI  IShellFolder_CompareIDs(
+  	LPSHELLFOLDER this,
+		LPARAM lParam, 
+    LPCITEMIDLIST pidl1, /*simple pidl*/
+    LPCITEMIDLIST pidl2) /*simple pidl*/
+{ CHAR szString1[MAX_PATH] = "";
+  CHAR szString2[MAX_PATH] = "";
+  int   nReturn;
+  LPCITEMIDLIST  pidlTemp1 = pidl1, pidlTemp2 = pidl2;
+
+  TRACE(shell,"(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",this,lParam,pidl1,pidl2);
+
+  /*Special case - If one of the items is a Path and the other is a File, always 
+  make the Path come before the File.*/
+
+  /* get the last item in each list */
+  while((ILGetNext(pidlTemp1))->mkid.cb)
+    pidlTemp1 = ILGetNext(pidlTemp1);
+  while((ILGetNext(pidlTemp2))->mkid.cb)
+    pidlTemp2 = ILGetNext(pidlTemp2);
+
+  /* at this point, both pidlTemp1 and pidlTemp2 point to the last item in the list */
+  if(this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr,pidlTemp1) != this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr,pidlTemp2))
+  { if(this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr,pidlTemp1))
+      return 1;
+   return -1;
+  }
+
+  this->pPidlMgr->lpvtbl->fnGetDrive(this->pPidlMgr, pidl1,szString1,sizeof(szString1));
+  this->pPidlMgr->lpvtbl->fnGetDrive(this->pPidlMgr, pidl2,szString1,sizeof(szString2));
+  nReturn = strcasecmp(szString1, szString2);
+  if(nReturn)
+    return nReturn;
+
+  this->pPidlMgr->lpvtbl->fnGetFolderText(this->pPidlMgr, pidl1,szString1,sizeof(szString1));
+  this->pPidlMgr->lpvtbl->fnGetFolderText(this->pPidlMgr, pidl2,szString2,sizeof(szString2));
+  nReturn = strcasecmp(szString1, szString2);
+  if(nReturn)
+    return nReturn;
+
+  this->pPidlMgr->lpvtbl->fnGetValueText(this->pPidlMgr,pidl1,szString1,sizeof(szString1));
+  this->pPidlMgr->lpvtbl->fnGetValueText(this->pPidlMgr,pidl2,szString2,sizeof(szString2));
+  return strcasecmp(szString1, szString2);
+}
+
+/**************************************************************************
+*	  IShellFolder_CreateViewObject
+* Creates an View Object representing the ShellFolder
+*  IShellView / IShellBrowser / IContextMenu
+*
+* PARAMETERS
+*  HWND    hwndOwner,  // Handle of owner window
+*  REFIID  riid,       // Requested initial interface
+*  LPVOID* ppvObject)  // Resultant interface*
+*
+* NOTES
+*  the same as SHCreateShellFolderViewEx ???
+*/
+static HRESULT WINAPI IShellFolder_CreateViewObject(
+	LPSHELLFOLDER this,
+	HWND32 hwndOwner,
+	REFIID riid,
+	LPVOID *ppvOut)
+{ LPSHELLVIEW pShellView;
+  char    xriid[50];
+  HRESULT       hr;
+
+	WINE_StringFromCLSID(riid,xriid);
+  TRACE(shell,"(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",this,hwndOwner,xriid,ppvOut);
+	
+	*ppvOut = NULL;
+
+  pShellView = IShellView_Constructor(this, this->mpidl);
+  if(!pShellView)
+    return E_OUTOFMEMORY;
+  hr = pShellView->lpvtbl->fnQueryInterface(pShellView, riid, ppvOut);
+  pShellView->lpvtbl->fnRelease(pShellView);
+  TRACE(shell,"-- (%p)->(interface=%p)\n",this, ppvOut);
+  return hr; 
+}
+
+/**************************************************************************
+*  IShellFolder_GetAttributesOf
+*
+* PARAMETERS
+*  UINT            cidl,     //[in ] num elements in pidl array
++  LPCITEMIDLIST*  apidl,    //[in ] simple pidl array 
+*  ULONG*          rgfInOut) //[out] result array  
+*
+* FIXME: quick hack
+*  Note: rgfInOut is documented as being an array of ULONGS.
+*  This does not seem to be the case. Testing this function using the shell to 
+*  call it with cidl > 1 (by deleting multiple items) reveals that the shell
+*  passes ONE element in the array and writing to further elements will
+*  cause the shell to fail later.
+*/
+static HRESULT WINAPI IShellFolder_GetAttributesOf(
+	LPSHELLFOLDER this,
+	UINT32 cidl,
+    LPCITEMIDLIST *apidl, /*simple pidl's*/
+	DWORD *rgfInOut)
+{ LPCITEMIDLIST * pidltemp;
+  DWORD i;
+
+  TRACE(shell,"(%p)->(%d,%p,%p)\n",this,cidl,apidl,rgfInOut);
+
+  if ((! cidl )| (!apidl) | (!rgfInOut))
+    return E_INVALIDARG;
+
+  pidltemp=apidl;
+  *rgfInOut = 0x00;
+  i=cidl;
+
+  TRACE(shell,"-- mask=0x%08lx\n",*rgfInOut);
+  
+  do
+  { if (*pidltemp)
+    { if (this->pPidlMgr->lpvtbl->fnIsDesktop(this->pPidlMgr, *pidltemp))
+      { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR);
+      }
+      else if (this->pPidlMgr->lpvtbl->fnIsMyComputer(this->pPidlMgr, *pidltemp))
+      { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER);
+      }
+      else if (this->pPidlMgr->lpvtbl->fnIsDrive(this->pPidlMgr, *pidltemp))
+      { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR | SFGAO_FILESYSTEM);
+      }
+      else if (this->pPidlMgr->lpvtbl->fnIsFolder(this->pPidlMgr, *pidltemp))
+      { *rgfInOut |= (SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER);
+      }
+      else if (this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr, *pidltemp))
+      { *rgfInOut |= (SFGAO_FILESYSTEM);
+      }
+    }
+    pidltemp++;
+    cidl--;
+  } while (cidl > 0 && *pidltemp);
+
+  return S_OK;
+}
+/**************************************************************************
+*  IShellFolder_GetUIObjectOf
+*
+* PARAMETERS
+*  HWND           hwndOwner, //[in ] Parent window for any output
+*  UINT           cidl,      //[in ] array size
+*  LPCITEMIDLIST* apidl,     //[in ] simple pidl array
+*  REFIID         riid,      //[in ] Requested Interface
+*  UINT*          prgfInOut, //[   ] reserved 
+*  LPVOID*        ppvObject) //[out] Resulting Interface
+*
+* NOTES
+*  This function gets asked to return "view objects" for one or more (multiple select)
+*  items:
+*  The viewobject typically is an COM object with one of the following interfaces:
+*  IExtractIcon,IDataObject,IContextMenu
+*  In order to support icon positions in the default Listview your DataObject
+*  must implement the SetData method (in addition to GetData :) - the shell passes
+*  a barely documented "Icon positions" structure to SetData when the drag starts,
+*  and GetData's it if the drop is in another explorer window that needs the positions.
+*/
+static HRESULT WINAPI IShellFolder_GetUIObjectOf( LPSHELLFOLDER this,HWND32 hwndOwner,UINT32 cidl,
+ LPCITEMIDLIST * apidl, REFIID riid, UINT32 * prgfInOut,LPVOID * ppvOut)
+{ char	        xclsid[50];
+  LPEXTRACTICON	pei;
+  LPCONTEXTMENU	pcm;
+  LPITEMIDLIST	pidl;
+   
+  WINE_StringFromCLSID(riid,xclsid);
+
+  TRACE(shell,"(%p)->(%u,%u,pidl=%p,\n\tIID:%s,%p,%p)\n",
+	  this,hwndOwner,cidl,apidl,xclsid,prgfInOut,ppvOut);
+
+  *ppvOut = NULL;
+
+  if(IsEqualIID(riid, &IID_IContextMenu))
+  { pcm  = IContextMenu_Constructor(this, apidl, cidl);
+    if(pcm)
+    { *ppvOut = pcm;
+      return S_OK;
+    }
+  }
+
+  if(cidl != 1)
+    return E_FAIL;
+
+  if(IsEqualIID(riid, &IID_IExtractIcon))
+  { pidl = ILCombine(this->mpidl, apidl[0]);
+    pei = IExtractIcon_Constructor(pidl);
+
+    /* The temp PIDL can be deleted because the new CExtractIcon either failed or 
+    made its own copy of it. */
+    SHFree(pidl);
+
+    if(pei)
+    { *ppvOut = pei;
+       return S_OK;
+    }
+    return E_OUTOFMEMORY;
+  }
+
+/*  if(IsEqualIID(riid, IID_IQueryInfo))
+  { CQueryInfo     *pqit;
+    LPITEMIDLIST   pidl;
+    pidl = m_pPidlMgr->Concatenate(m_pidl, pPidl[0]);
+    pqit = new CQueryInfo(pidl);
+ */
+    /* The temp PIDL can be deleted because the new CQueryInfo either failed or 
+    made its own copy of it. */
+ /*   m_pPidlMgr->Delete(pidl);
+ 
+    if(pqit)
+    { *ppvReturn = pqit;
+      return S_OK;
+    }
+    return E_OUTOFMEMORY;
+  }
+*/
+  ERR(shell,"(%p)->E_NOINTERFACE\n",this);
+  return E_NOINTERFACE;
+}
+/**************************************************************************
+*  IShellFolder_GetDisplayNameOf
+*  Retrieves the display name for the specified file object or subfolder
+*
+* PARAMETERS
+*  LPCITEMIDLIST pidl,    //[in ] complex pidl to item
+*  DWORD         dwFlags, //[in ] SHGNO formatting flags
+*  LPSTRRET      lpName)  //[out] Returned display name
+*
+* FIXME
+*  if the name is in the pidl the ret value should be a STRRET_OFFSET
+*/
+#define GET_SHGDN_FOR(dwFlags)         ((DWORD)dwFlags & (DWORD)0x0000FF00)
+#define GET_SHGDN_RELATION(dwFlags)    ((DWORD)dwFlags & (DWORD)0x000000FF)
+
+static HRESULT WINAPI IShellFolder_GetDisplayNameOf( 
+  	LPSHELLFOLDER this,
+    LPCITEMIDLIST pidl, /* simple/complex pidl*/
+    DWORD dwFlags, 
+    LPSTRRET lpName)
+{ CHAR           szText[MAX_PATH];
+  CHAR           szTemp[MAX_PATH];
+	CHAR           szSpecial[MAX_PATH];
+	CHAR           szDrive[MAX_PATH];
+  DWORD          dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags;
+  LPITEMIDLIST   pidlTemp=NULL;
+	BOOL32				 bSimplePidl=FALSE;
+		
+  TRACE(shell,"(%p)->(pidl=%p,0x%08lx,%p)\n",this,pidl,dwFlags,lpName);
+
+  if (!pidl)
+  {  return E_OUTOFMEMORY;
+  } 
+
+  szSpecial[0]=0x00; 
+  szDrive[0]=0x00;
+
+  /* test if simple(relative) or complex(absolute) pidl */
+  pidlTemp = ILGetNext(pidl);
+	if (pidlTemp->mkid.cb==0x00)
+	{ bSimplePidl = TRUE;
+	}
+	if (this->pPidlMgr->lpvtbl->fnIsDesktop(this->pPidlMgr, pidl))
+	{ strcpy (szText,"Desktop");
+	}
+	else
+  { if (this->pPidlMgr->lpvtbl->fnIsMyComputer(this->pPidlMgr, pidl))
+    { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidl, szSpecial, MAX_PATH);
+    }
+	  if (this->pPidlMgr->lpvtbl->fnIsDrive(this->pPidlMgr, pidl))
+		{ pidlTemp = this->pPidlMgr->lpvtbl->fnGetLastItem(this->pPidlMgr,pidl);
+  		if (pidlTemp)
+      { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidlTemp, szTemp, MAX_PATH);
+  		}
+		  if ( dwFlags==SHGDN_NORMAL || dwFlags==SHGDN_INFOLDER)
+  		{ GetVolumeInformation32A(szTemp,szDrive,MAX_PATH,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
+				if (szTemp[2]=='\\')
+        { szTemp[2]=0x00;
+				}
+        strcat (szDrive," (");
+				strcat (szDrive,szTemp);
+				strcat (szDrive,")"); 
+  		}
+			else
+			{  PathAddBackslash (szTemp);
+			   strcpy(szDrive,szTemp);
+			}
+		}
+		
+  	switch(dwFlags)
+    { case SHGDN_NORMAL:
+        this->pPidlMgr->lpvtbl->fnGetPidlPath(this->pPidlMgr, pidl, szText, MAX_PATH);
+        break;
+      case SHGDN_INFOLDER:
+        pidlTemp = this->pPidlMgr->lpvtbl->fnGetLastItem(this->pPidlMgr,pidl);
+  			if (pidlTemp)
+        { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidlTemp, szText, MAX_PATH);
+  			}
+   			break;				
+   		case	SHGDN_FORPARSING:
+			  if (bSimplePidl)
+				{ /* if the IShellFolder has parents, get the path from the
+				  parent and add the ItemName*/
+          szText[0]=0x00;
+				  if (this->mlpszFolder && strlen (this->mlpszFolder))
+          { if (strcmp(this->mlpszFolder,"My Computer"))
+  			  { strcpy (szText,this->mlpszFolder);
+  			    PathAddBackslash (szText);
+  			  }
+  		  	}
+          pidlTemp = this->pPidlMgr->lpvtbl->fnGetLastItem(this->pPidlMgr,pidl);
+        	if (pidlTemp)
+          { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidlTemp, szTemp, MAX_PATH );
+        	} 
+					strcat(szText,szTemp);
+				}
+				else					
+				{ /* if the pidl is absolute, get everything from the pidl*/
+				  this->pPidlMgr->lpvtbl->fnGetPidlPath(this->pPidlMgr, pidl, szText, MAX_PATH);
+				}
+        break;
+      default:    return E_INVALIDARG;
+    }
+		if ((szText[0]==0x00 && szDrive[0]!=0x00)|| (bSimplePidl && szDrive[0]!=0x00))
+		{ strcpy(szText,szDrive);
+		}
+		if (szText[0]==0x00 && szSpecial[0]!=0x00)
+		{ strcpy(szText,szSpecial);
+		}
+  }
+  
+  TRACE(shell,"-- (%p)->(%s,%s,%s)\n",this,szSpecial,szDrive,szText);
+
+  if(!(lpName))
+  {  return E_OUTOFMEMORY;
+  }
+  lpName->uType = STRRET_CSTR;	
+  strcpy(lpName->u.cStr,szText);
+  return S_OK;
+}
+
+/**************************************************************************
+*  IShellFolder_SetNameOf
+*  Changes the name of a file object or subfolder, possibly changing its item
+*  identifier in the process.
+*
+* PARAMETERS
+*  HWND          hwndOwner,  //[in ] Owner window for output
+*  LPCITEMIDLIST pidl,       //[in ] simple pidl of item to change
+*  LPCOLESTR     lpszName,   //[in ] the items new display name
+*  DWORD         dwFlags,    //[in ] SHGNO formatting flags
+*  LPITEMIDLIST* ppidlOut)   //[out] simple pidl returned
+*/
+static HRESULT WINAPI IShellFolder_SetNameOf(
+  	LPSHELLFOLDER this,
+		HWND32 hwndOwner, 
+    LPCITEMIDLIST pidl, /*simple pidl*/
+    LPCOLESTR32 lpName, 
+    DWORD dw, 
+    LPITEMIDLIST *pPidlOut)
+{  FIXME(shell,"(%p)->(%u,pidl=%p,%s,%lu,%p),stub!\n",
+	  this,hwndOwner,pidl,debugstr_w(lpName),dw,pPidlOut);
+	 return E_NOTIMPL;
+}
+/**************************************************************************
+*  IShellFolder_GetFolderPath
+*  FIXME: drive not included
+*/
+static BOOL32 WINAPI IShellFolder_GetFolderPath(LPSHELLFOLDER this, LPSTR lpszOut, DWORD dwOutSize)
+{	CHAR szTemp[MAX_PATH];
+	DWORD dwSize;
+    
+    TRACE(shell,"(%p)->(%p %lu)\n",this, lpszOut, dwOutSize);
+    if (!lpszOut)
+    { return FALSE;
+    }
+    
+    *lpszOut=0;
+    
+    dwSize = strlen (this->mlpszFolder) +1;
+    if ( dwSize > dwOutSize)
+      return FALSE;
+    strcpy(lpszOut, this->mlpszFolder);
+
+    TRACE(shell,"-- (%p)->(return=%s)\n",this, lpszOut);
+    return TRUE;
+}
diff --git a/dlls/shell32/shlview.c b/dlls/shell32/shlview.c
new file mode 100644
index 0000000..90796db
--- /dev/null
+++ b/dlls/shell32/shlview.c
@@ -0,0 +1,1185 @@
+/*
+ *	ShellView
+ *
+ *	Copyright 1998	Juergen Schmied
+ *
+ *  !!! currently work in progress on all classes 980801 !!!
+ *  <contact juergen.schmied@metronet.de>
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ole.h"
+#include "ole2.h"
+#include "debug.h"
+#include "compobj.h"
+#include "interfaces.h"
+#include "shlobj.h"
+#include "shell.h"
+#include "winerror.h"
+#include "winnls.h"
+#include "winproc.h"
+#include "commctrl.h"
+
+#include "shell32_main.h"
+#include "pidl.h"
+#include "shresdef.h"
+
+/***********************************************************************
+*   IShellView implementation
+*/
+static HRESULT WINAPI IShellView_QueryInterface(LPSHELLVIEW,REFIID, LPVOID *);
+static ULONG WINAPI IShellView_AddRef(LPSHELLVIEW) ;
+static ULONG WINAPI IShellView_Release(LPSHELLVIEW);
+    /* IOleWindow methods */
+static HRESULT WINAPI IShellView_GetWindow(LPSHELLVIEW,HWND32 * lphwnd);
+static HRESULT WINAPI IShellView_ContextSensitiveHelp(LPSHELLVIEW,BOOL32 fEnterMode);
+    /* IShellView methods */
+static HRESULT WINAPI IShellView_TranslateAccelerator(LPSHELLVIEW,LPMSG32 lpmsg);
+static HRESULT WINAPI IShellView_EnableModeless(LPSHELLVIEW,BOOL32 fEnable);
+static HRESULT WINAPI IShellView_UIActivate(LPSHELLVIEW,UINT32 uState);
+static HRESULT WINAPI IShellView_Refresh(LPSHELLVIEW);
+static HRESULT WINAPI IShellView_CreateViewWindow(LPSHELLVIEW, IShellView *lpPrevView,LPCFOLDERSETTINGS lpfs, IShellBrowser * psb,RECT32 * prcView, HWND32  *phWnd);
+static HRESULT WINAPI IShellView_DestroyViewWindow(LPSHELLVIEW);
+static HRESULT WINAPI IShellView_GetCurrentInfo(LPSHELLVIEW, LPFOLDERSETTINGS lpfs);
+static HRESULT WINAPI IShellView_AddPropertySheetPages(LPSHELLVIEW, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam);
+static HRESULT WINAPI IShellView_SaveViewState(LPSHELLVIEW);
+static HRESULT WINAPI IShellView_SelectItem(LPSHELLVIEW, LPCITEMIDLIST pidlItem, UINT32 uFlags);
+static HRESULT WINAPI IShellView_GetItemObject(LPSHELLVIEW, UINT32 uItem, REFIID riid,LPVOID *ppv);
+
+static struct IShellView_VTable svvt = 
+{ IShellView_QueryInterface,
+  IShellView_AddRef,
+  IShellView_Release,
+  IShellView_GetWindow,
+  IShellView_ContextSensitiveHelp,
+  IShellView_TranslateAccelerator,
+  IShellView_EnableModeless,
+  IShellView_UIActivate,
+  IShellView_Refresh,
+  IShellView_CreateViewWindow,
+  IShellView_DestroyViewWindow,
+  IShellView_GetCurrentInfo,
+  IShellView_AddPropertySheetPages,
+  IShellView_SaveViewState,
+  IShellView_SelectItem,
+  IShellView_GetItemObject
+};
+
+//menu items
+#define IDM_VIEW_FILES  (FCIDM_SHVIEWFIRST + 0x500)
+#define IDM_VIEW_IDW    (FCIDM_SHVIEWFIRST + 0x501)
+#define IDM_MYFILEITEM  (FCIDM_SHVIEWFIRST + 0x502)
+
+#define TOOLBAR_ID   (L"ShellView")
+typedef struct
+{  int   idCommand;
+   int   iImage;
+   int   idButtonString;
+   int   idMenuString;
+   int   nStringOffset;
+   BYTE  bState;
+   BYTE  bStyle;
+} MYTOOLINFO, *LPMYTOOLINFO;
+
+MYTOOLINFO g_Tools[] = 
+{ {IDM_VIEW_FILES, 0, IDS_TB_VIEW_FILES, IDS_MI_VIEW_FILES, 0, TBSTATE_ENABLED, TBSTYLE_BUTTON},
+  {-1, 0, 0, 0, 0, 0, 0}   
+};
+/**************************************************************************
+*  IShellView_Constructor
+*/
+LPSHELLVIEW IShellView_Constructor(LPSHELLFOLDER pFolder, LPCITEMIDLIST pidl)
+{ LPSHELLVIEW sv;
+  sv=(LPSHELLVIEW)HeapAlloc(GetProcessHeap(),0,sizeof(IShellView));
+  sv->ref=1;
+  sv->lpvtbl=&svvt;
+  
+  sv->mpidl = ILClone(pidl);
+
+  sv->pSFParent = pFolder;
+  if(sv->pSFParent)
+    sv->pSFParent->lpvtbl->fnAddRef(sv->pSFParent);
+
+  TRACE(shell,"(%p)->(%p pidl=%p)\n",sv, pFolder, pidl);
+  return sv;
+}
+/**************************************************************************
+* ShellView_CreateList()
+*
+* NOTES
+*  internal
+*/
+#define ID_LISTVIEW     2000
+
+BOOL32 ShellView_CreateList (LPSHELLVIEW this)
+{ DWORD dwStyle;
+
+  TRACE(shell,"%p\n",this);
+
+  dwStyle = WS_TABSTOP | WS_VISIBLE |WS_CHILD | WS_BORDER | LVS_REPORT |
+            LVS_SHAREIMAGELISTS | LVS_EDITLABELS ;
+
+  this->hWndList=CreateWindowEx32A( WS_EX_CLIENTEDGE,WC_LISTVIEW32A,NULL,dwStyle,
+  								0,0,0,0,
+  								this->hWnd,(HMENU32)ID_LISTVIEW,shell32_hInstance,NULL);
+
+  if(!this->hWndList)
+     return FALSE;
+
+//  UpdateShellSettings();
+  return TRUE;
+}
+/**************************************************************************
+* ShellView_InitList()
+*
+* NOTES
+*  internal
+*/
+int  nColumn1=100; /* width of column */
+int  nColumn2=100;
+int  nColumn3=100;
+int  nColumn4=100;
+
+BOOL32 ShellView_InitList(LPSHELLVIEW this)
+{ LV_COLUMN   lvColumn;
+  CHAR        szString[50];
+
+  TRACE(shell,"%p\n",this);
+
+
+  ListView_DeleteAllItems(this->hWndList);		/*empty the list*/
+
+  //initialize the columns
+  lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT |  LVCF_SUBITEM;
+  lvColumn.fmt = LVCFMT_LEFT;
+  lvColumn.pszText = szString;
+
+  lvColumn.cx = nColumn1;
+  strcpy(szString,"File");
+  /*LoadString32A(shell32_hInstance, IDS_COLUMN1, szString, sizeof(szString));*/
+  ListView_InsertColumn(this->hWndList, 0, &lvColumn);
+
+  lvColumn.cx = nColumn2;
+  strcpy(szString,"IDS_COLUMN2");
+  ListView_InsertColumn(this->hWndList, 1, &lvColumn);
+
+  lvColumn.cx = nColumn3;
+  strcpy(szString,"IDS_COLUMN3");
+  ListView_InsertColumn(this->hWndList, 2, &lvColumn);
+
+  lvColumn.cx = nColumn4;
+  strcpy(szString,"IDS_COLUMN4");
+  ListView_InsertColumn(this->hWndList, 3, &lvColumn);
+
+  ListView_SetImageList(this->hWndList, ShellBigIconList, LVSIL_SMALL);
+
+  return TRUE;
+}
+/**************************************************************************
+* ShellView_CompareItems()
+*
+* NOTES
+*  internal
+*/   
+int CALLBACK ShellView_CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
+{ LPSHELLFOLDER  pFolder = (LPSHELLFOLDER)lpData;
+
+  TRACE(shell,"\n");
+  if(!pFolder)
+    return 0;
+
+ return (int)pFolder->lpvtbl->fnCompareIDs(pFolder, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2);
+}
+
+/**************************************************************************
+* ShellView_FillList()
+*
+* NOTES
+*  internal
+*/   
+
+void ShellView_FillList(LPSHELLVIEW this)
+{ LPENUMIDLIST   pEnumIDList;
+  LPITEMIDLIST   pidl;
+  DWORD          dwFetched;
+  LV_ITEM  lvItem;
+  
+  TRACE(shell,"%p\n",this);
+  
+  if(S_OK == this->pSFParent->lpvtbl->fnEnumObjects(this->pSFParent,this->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList))
+  { SendMessage32A(this->hWndList, WM_SETREDRAW, FALSE, 0); /*turn the listview's redrawing off*/
+
+    while((S_OK == pEnumIDList->lpvtbl->fnNext(pEnumIDList,1, &pidl, &dwFetched)) && dwFetched)
+    { ZeroMemory(&lvItem, sizeof(lvItem));
+
+      lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;       /*set the mask*/
+      lvItem.iItem = ListView_GetItemCount(this->hWndList); /*add the item to the end of the list*/
+      lvItem.lParam = (LPARAM)ILClone(pidl);		/*set the item's data*/
+      lvItem.pszText = LPSTR_TEXTCALLBACK32A;		/*get text on a callback basis*/
+      lvItem.iImage = I_IMAGECALLBACK;				/*get the image on a callback basis*/
+      ListView_InsertItem(this->hWndList, &lvItem);	/*add the item*/    
+   }
+
+   /*sort the items*/
+   ListView_SortItems(this->hWndList, ShellView_CompareItems, (LPARAM)this->pSFParent);
+     
+   /*turn the listview's redrawing back on and force it to draw*/
+   SendMessage32A(this->hWndList, WM_SETREDRAW, TRUE, 0);
+   InvalidateRect32(this->hWndList, NULL, TRUE);
+   UpdateWindow32(this->hWndList);
+
+   pEnumIDList->lpvtbl->fnRelease(pEnumIDList);
+ }
+}
+
+/**************************************************************************
+*  ShellView_OnCreate()
+*
+* NOTES
+*  internal
+*/   
+LRESULT ShellView_OnCreate(LPSHELLVIEW this)
+{ TRACE(shell,"%p\n",this);
+  if(ShellView_CreateList(this))
+  {  if(ShellView_InitList(this))
+     { ShellView_FillList(this);
+     }
+  }
+  return S_OK;
+}
+/**************************************************************************
+*  ShellView_OnSize()
+*/   
+LRESULT ShellView_OnSize(LPSHELLVIEW this, WORD wWidth, WORD wHeight)
+{ TRACE(shell,"%p width=%u height=%u\n",this, wWidth,wHeight);
+  //resize the ListView to fit our window
+  if(this->hWndList)
+  { MoveWindow32(this->hWndList, 0, 0, wWidth, wHeight, TRUE);
+  }
+  return S_OK;
+}
+/**************************************************************************
+* ShellView_BuildFileMenu()
+*/   
+HMENU32 ShellView_BuildFileMenu(LPSHELLVIEW this)
+{   CHAR			szText[MAX_PATH];
+	MENUITEMINFO32A	mii;
+	int				nTools,i;
+	HMENU32 		hSubMenu = CreatePopupMenu32();
+
+	TRACE(shell,"(%p) stub\n",this);
+	if(hSubMenu)
+	{ /*get the number of items in our global array*/
+	  for(nTools = 0; g_Tools[nTools].idCommand != -1; nTools++){}
+
+	  //add the menu items
+	  for(i = 0; i < nTools; i++)
+      { strcpy(szText, "dummy 44");
+      
+	    ZeroMemory(&mii, sizeof(mii));
+	    mii.cbSize = sizeof(mii);
+	    mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
+
+	    if(TBSTYLE_SEP != g_Tools[i].bStyle)
+	    { mii.fType = MFT_STRING;
+          mii.fState = MFS_ENABLED;
+          mii.dwTypeData = szText;
+          mii.wID = g_Tools[i].idCommand;
+        }
+	    else
+        { mii.fType = MFT_SEPARATOR;
+        }
+        /* tack this item onto the end of the menu */
+        InsertMenuItem32A(hSubMenu, (UINT32)-1, TRUE, &mii);
+      }
+	}
+	return hSubMenu;
+}
+/**************************************************************************
+* ShellView_MergeFileMenu()
+*/   
+void ShellView_MergeFileMenu(LPSHELLVIEW this, HMENU32 hSubMenu)
+{   MENUITEMINFO32A   mii;
+	CHAR          szText[MAX_PATH];
+
+	TRACE(shell,"(%p)->(submenu=0x%08x) stub\n",this,hSubMenu);
+	if(hSubMenu)
+	{ ZeroMemory(&mii, sizeof(mii));
+
+	  /* add a separator */
+	  mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
+	  mii.fType = MFT_SEPARATOR;
+	  mii.fState = MFS_ENABLED;
+
+	  /*insert this item at the beginning of the menu */
+	  InsertMenuItem32A(hSubMenu, 0, TRUE, &mii);
+
+	  /*add the file menu items */
+      strcpy(szText,"dummy 45");
+      
+	  mii.cbSize = sizeof(mii);
+	  mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
+	  mii.fType = MFT_STRING;
+	  mii.fState = MFS_ENABLED;
+	  mii.dwTypeData = szText;
+	  mii.wID = IDM_MYFILEITEM;
+
+	  /*insert this item at the beginning of the menu */
+	  InsertMenuItem32A(hSubMenu, 0, TRUE, &mii);
+	}
+}
+
+/**************************************************************************
+* ShellView_MergeViewMenu()
+*/   
+void ShellView_MergeViewMenu(LPSHELLVIEW this, HMENU32 hSubMenu)
+{   MENUITEMINFO32A   mii;
+    CHAR          szText[MAX_PATH];
+
+	TRACE(shell,"(%p)->(submenu=0x%08x) stub\n",this,hSubMenu);
+	if(hSubMenu)
+	{ ZeroMemory(&mii, sizeof(mii));
+
+	  /*add a separator at the correct position in the menu*/
+	  mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
+	  mii.fType = MFT_SEPARATOR;
+	  mii.fState = MFS_ENABLED;
+	  InsertMenuItem32A(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
+
+	  /*add the view menu items at the correct position in the menu*/
+      strcpy(szText,"Dummy 46");
+      
+	  mii.cbSize = sizeof(mii);
+	  mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
+	  mii.fType = MFT_STRING;
+	  mii.fState = MFS_ENABLED;
+	  mii.dwTypeData = szText;
+	  mii.wID = IDM_VIEW_FILES;
+	  InsertMenuItem32A(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
+	}
+}
+/**************************************************************************
+* ShellView_OnDeactivate()
+*
+* NOTES
+*  internal
+*/   
+void ShellView_OnDeactivate(LPSHELLVIEW this)
+{ TRACE(shell,"%p\n",this);
+  if(this->uState != SVUIA_DEACTIVATE)
+  { if(this->hMenu)
+    { this->pShellBrowser->lpvtbl->fnSetMenuSB(this->pShellBrowser,0, 0, 0);
+      this->pShellBrowser->lpvtbl->fnRemoveMenusSB(this->pShellBrowser,this->hMenu);
+      DestroyMenu32(this->hMenu);
+      this->hMenu = 0;
+      }
+
+   this->uState = SVUIA_DEACTIVATE;
+   }
+}
+
+/**************************************************************************
+* CShellView_OnActivate()
+*/   
+LRESULT ShellView_OnActivate(LPSHELLVIEW this, UINT32 uState)
+{	OLEMENUGROUPWIDTHS32   omw = { {0, 0, 0, 0, 0, 0} };
+    MENUITEMINFO32A         mii;
+    CHAR                szText[MAX_PATH];
+
+	TRACE(shell,"%p uState=%x\n",this,uState);    
+
+	//don't do anything if the state isn't really changing
+	if(this->uState == uState)
+	{ return S_OK;
+    }
+
+	ShellView_OnDeactivate(this);
+
+	//only do this if we are active
+	if(uState != SVUIA_DEACTIVATE)
+	{ //merge the menus
+      this->hMenu = CreateMenu32();
+   
+	  if(this->hMenu)
+	  { this->pShellBrowser->lpvtbl->fnInsertMenusSB(this->pShellBrowser, this->hMenu, &omw);
+
+        //build the top level menu
+        //get the menu item's text
+        strcpy(szText,"dummy 31");
+      
+        ZeroMemory(&mii, sizeof(mii));
+        mii.cbSize = sizeof(mii);
+        mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
+        mii.fType = MFT_STRING;
+        mii.fState = MFS_ENABLED;
+        mii.dwTypeData = szText;
+        mii.hSubMenu = ShellView_BuildFileMenu(this);
+
+        //insert our menu into the menu bar
+        if(mii.hSubMenu)
+        { InsertMenuItem32A(this->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
+        }
+
+        //get the view menu so we can merge with it
+        ZeroMemory(&mii, sizeof(mii));
+        mii.cbSize = sizeof(mii);
+        mii.fMask = MIIM_SUBMENU;
+      
+	    if(GetMenuItemInfo32A(this->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
+	    { ShellView_MergeViewMenu(this, mii.hSubMenu);
+        }
+
+        //add the items that should only be added if we have the focus
+        if(SVUIA_ACTIVATE_FOCUS == uState)
+	    { //get the file menu so we can merge with it
+	      ZeroMemory(&mii, sizeof(mii));
+          mii.cbSize = sizeof(mii);
+	      mii.fMask = MIIM_SUBMENU;
+      
+	      if(GetMenuItemInfo32A(this->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
+	      { ShellView_MergeFileMenu(this, mii.hSubMenu);
+          }
+        }
+        this->pShellBrowser->lpvtbl->fnSetMenuSB(this->pShellBrowser, this->hMenu, 0, this->hWnd);
+	  }
+	}
+	this->uState = uState;
+	return 0;
+}
+
+/**************************************************************************
+*  ShellView_OnSetFocus()
+*
+* NOTES
+*  internal
+*/
+LRESULT ShellView_OnSetFocus(LPSHELLVIEW this)
+{ TRACE(shell,"%p\n",this);
+  /* Tell the browser one of our windows has received the focus. This should always 
+  be done before merging menus (OnActivate merges the menus) if one of our 
+  windows has the focus.*/
+  this->pShellBrowser->lpvtbl->fnOnViewWindowActive(this->pShellBrowser,this);
+  ShellView_OnActivate(this, SVUIA_ACTIVATE_FOCUS);
+
+  return 0;
+}
+
+BOOL32 g_bViewKeys;
+BOOL32 g_bShowIDW;
+/**************************************************************************
+* ShellView_OnKillFocus()
+*/   
+LRESULT ShellView_OnKillFocus(LPSHELLVIEW this)
+{	TRACE(shell,"(%p) stub\n",this);
+	ShellView_OnActivate(this, SVUIA_ACTIVATE_NOFOCUS);
+	return 0;
+}
+
+/**************************************************************************
+* CShellView::AddRemoveDockingWindow()
+*/   
+BOOL32 ShellView_AddRemoveDockingWindow(LPSHELLVIEW this, BOOL32 bAdd)
+{	TRACE(shell,"(%p)->(badd=0x%08x) stub\n",this,bAdd);
+	return FALSE;
+/*
+	BOOL32              bReturn = FALSE;
+	HRESULT32           hr;
+	IServiceProvider  *pSP;
+*/
+	/* get the browser's IServiceProvider */
+/*	hr = this->pShellBrowser->QueryInterface((REFIID)IID_IServiceProvider, (LPVOID*)&pSP);
+	if(SUCCEEDED(hr))
+	{
+	IDockingWindowFrame *pFrame;
+*/
+	/*get the IDockingWindowFrame pointer*/
+/*
+	hr = pSP->QueryService(SID_SShellBrowser, IID_IDockingWindowFrame, (LPVOID*)&pFrame);
+	if(SUCCEEDED(hr))
+	{ if(bAdd)
+	  { hr = S_OK;
+		if(!this->pDockingWindow)
+		{ //create the toolbar object
+	      this->pDockingWindow = new CDockingWindow(this, this->hWnd);
+	    }
+
+	    if(this->pDockingWindow)
+        { //add the toolbar object
+	      hr = pFrame->AddToolbar((IDockingWindow*)this->pDockingWindow, TOOLBAR_ID, 0);
+
+	      if(SUCCEEDED(hr))
+          { bReturn = TRUE;
+	      }
+	    }
+	  }
+      else
+      { if(this->pDockingWindow)
+        { hr = pFrame->RemoveToolbar((IDockingWindow*)this->pDockingWindow, DWFRF_NORMAL);
+
+	      if(SUCCEEDED(hr))
+          {*/
+            /* RemoveToolbar should release the toolbar object which will cause 
+            it to destroy itself. Our toolbar object is no longer valid at 
+            this point.*/
+            
+/*          this->pDockingWindow = NULL;
+	        bReturn = TRUE;
+                             }
+	      }
+	    }
+	    pFrame->Release();
+      }
+	  pSP->Release();
+	}
+	return bReturn;*/
+}
+
+/**************************************************************************
+* ShellView_OnCommand()
+*/   
+LRESULT ShellView_OnCommand(LPSHELLVIEW this,DWORD dwCmdID, DWORD dwCmd, HWND32 hwndCmd)
+{	TRACE(shell,"(%p)->(0x%08lx 0x%08lx 0x%08x) stub\n",this, dwCmdID, dwCmd, hwndCmd);
+	switch(dwCmdID)
+    { case IDM_VIEW_FILES:
+        g_bViewKeys = ! g_bViewKeys;
+        IShellView_Refresh(this);
+        break;
+
+	  case IDM_VIEW_IDW:
+        g_bShowIDW = ! g_bShowIDW;
+        ShellView_AddRemoveDockingWindow(this, g_bShowIDW);
+        break;
+   
+	  case IDM_MYFILEITEM:
+        MessageBeep32(MB_OK);
+        break;
+	}
+	return 0;
+}
+/**************************************************************************
+* ShellView_CanDoIDockingWindow()
+*/   
+BOOL32 ShellView_CanDoIDockingWindow(LPSHELLVIEW this)
+{	TRACE(shell,"(%p) stub\n",this);
+	return FALSE;
+/*
+	BOOL32              bReturn = FALSE;
+	HRESULT32           hr;
+	IServiceProvider	*pSP;
+	IDockingWindowFrame *pFrame;
+
+	//get the browser's IServiceProvider
+	hr = this->pShellBrowser->lpvtbl->fnQueryInterface(this->pShellBrowser, (REFIID)IID_IServiceProvider, (LPVOID*)&pSP);
+	if(hr==S_OK)
+	{ hr = pSP->lpvtbl->fnQueryService(pSP, SID_SShellBrowser, IID_IDockingWindowFrame, (LPVOID*)&pFrame);
+   	  if(SUCCEEDED(hr))
+      { bReturn = TRUE;
+        pFrame->lpvtbl->fnRelease(pFrame);
+      }
+	pSP->lpvtbl->fnRelease(pSP);
+	}
+	return bReturn;*/
+}
+/**************************************************************************
+* ShellView_UpdateMenu()
+*/
+LRESULT ShellView_UpdateMenu(LPSHELLVIEW this, HMENU32 hMenu)
+{	TRACE(shell,"(%p)->(menu=0x%08x\n",this,hMenu);
+	CheckMenuItem32(hMenu, IDM_VIEW_FILES, MF_BYCOMMAND | (g_bViewKeys ? MF_CHECKED: MF_UNCHECKED));
+
+	if(ShellView_CanDoIDockingWindow(this))
+    { EnableMenuItem32(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_ENABLED);
+      CheckMenuItem32(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | (g_bShowIDW ? MF_CHECKED: MF_UNCHECKED));
+	}
+	else
+	{ EnableMenuItem32(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
+      CheckMenuItem32(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_UNCHECKED);
+	}
+	return 0;
+}
+
+/**************************************************************************
+*  ShellView_UpdateShellSettings()
+   
+**************************************************************************/
+typedef void (WINAPI *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
+
+
+void ShellView_UpdateShellSettings(LPSHELLVIEW this)
+{	TRACE(shell,"(%p) stub\n",this);
+	return ;
+/*
+	SHELLFLAGSTATE       sfs;
+	HINSTANCE            hinstShell32;
+*/
+	/* Since SHGetSettings is not implemented in all versions of the shell, get the 
+	function address manually at run time. This allows the code to run on all 
+	platforms.*/
+/*
+	ZeroMemory(&sfs, sizeof(sfs));
+*/
+	/* The default, in case any of the following steps fails, is classic Windows 95 
+	style.*/
+/*
+	sfs.fWin95Classic = TRUE;
+
+	hinstShell32 = LoadLibrary(TEXT("shell32.dll"));
+	if(hinstShell32)
+	{ PFNSHGETSETTINGSPROC pfnSHGetSettings;
+
+      pfnSHGetSettings = (PFNSHGETSETTINGSPROC)GetProcAddress(hinstShell32, "SHGetSettings");
+	  if(pfnSHGetSettings)
+      { (*pfnSHGetSettings)(&sfs, SSF_DOUBLECLICKINWEBVIEW | SSF_WIN95CLASSIC);
+      }
+	  FreeLibrary(hinstShell32);
+	}
+
+	DWORD dwExStyles = 0;
+
+	if(!sfs.fWin95Classic && !sfs.fDoubleClickInWebView)
+	  dwExStyles |= LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT | LVS_EX_UNDERLINEHOT;
+
+	ListView_SetExtendedListViewStyle(this->hWndList, dwExStyles);
+*/
+}
+
+/**************************************************************************
+*   ShellView_OnSettingChange()
+*/   
+LRESULT ShellView_OnSettingChange(LPSHELLVIEW this, LPCSTR lpszSection)
+{	TRACE(shell,"(%p) stub\n",this);
+	//if(0 == lstrcmpi(lpszSection, TEXT("ShellState")))
+	{ ShellView_UpdateShellSettings(this);
+	  return 0;
+	}
+	return 0;
+}
+
+#define MENU_OFFSET  1
+#define MENU_MAX     100
+
+/**************************************************************************
+*   ShellView_DoContextMenu()
+*/   
+void ShellView_DoContextMenu(LPSHELLVIEW this, WORD x, WORD y, BOOL32 fDefault)
+{	UINT32			uSelected = ListView_GetSelectedCount(this->hWndList);
+	LPITEMIDLIST	*aSelectedItems;
+	UINT32			i;
+	LPCONTEXTMENU	pContextMenu = NULL;
+	LVITEM			lvItem;
+	UINT32  		uCommand;
+	MENUITEMINFO32A	mii;
+	int            	nMenuIndex;
+    CMINVOKECOMMANDINFO  cmi;
+
+	TRACE(shell,"(%p)->(0x%08x 0x%08x 0x%08x) stub\n",this, x, y, fDefault);
+	aSelectedItems = (LPITEMIDLIST*)SHAlloc(uSelected * sizeof(LPITEMIDLIST));
+
+	if(aSelectedItems)
+	{ ZeroMemory(&lvItem, sizeof(lvItem));
+	  lvItem.mask = LVIF_STATE | LVIF_PARAM;
+	  lvItem.stateMask = LVIS_SELECTED;
+	  lvItem.iItem = 0;
+
+	  i = 0;
+   
+	  while(ListView_GetItem(this->hWndList, &lvItem) && (i < uSelected))
+      { if(lvItem.state & LVIS_SELECTED)
+        { aSelectedItems[i] = (LPITEMIDLIST)lvItem.lParam;
+          i++;
+        }
+        lvItem.iItem++;
+      }
+
+	  this->pSFParent->lpvtbl->fnGetUIObjectOf(this->pSFParent, this->hWndParent, uSelected,
+      				(LPCITEMIDLIST*)aSelectedItems, &IID_IContextMenu, NULL,(LPVOID*)&pContextMenu);
+   
+	  if(pContextMenu)
+      { HMENU32 hMenu = CreatePopupMenu32();
+
+        /* See if we are in Explore or Open mode. If the browser's tree is present, 
+        then we are in Explore mode.*/
+        
+	    BOOL32  fExplore = FALSE;
+	    HWND32  hwndTree = 0;
+	    if(S_OK==(this->pShellBrowser->lpvtbl->fnGetControlWindow(this->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
+        { fExplore = TRUE;
+        }
+
+	    if(hMenu && S_OK==(pContextMenu->lpvtbl->fnQueryContextMenu(pContextMenu,
+        					hMenu,0,MENU_OFFSET,MENU_MAX,CMF_NORMAL | 
+							(uSelected != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0))))
+        { if(fDefault)
+            { uCommand = 0;
+            
+              ZeroMemory(&mii, sizeof(mii));
+              mii.cbSize = sizeof(mii);
+              mii.fMask = MIIM_STATE | MIIM_ID;
+
+              nMenuIndex = 0;
+
+              //find the default item in the menu
+              while(GetMenuItemInfo32A(hMenu, nMenuIndex, TRUE, &mii))
+              { if(mii.fState & MFS_DEFAULT)
+                { uCommand = mii.wID;
+                  break;
+                }
+                nMenuIndex++;
+              }
+            }
+            else
+            { uCommand = TrackPopupMenu32( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,this->hWnd,NULL);
+            }
+         
+            if(uCommand > 0)
+            { ZeroMemory(&cmi, sizeof(cmi));
+              cmi.cbSize = sizeof(cmi);
+              cmi.hwnd = this->hWndParent;
+              cmi.lpVerb = (LPCSTR)MAKEINTRESOURCE32A(uCommand - MENU_OFFSET);
+			  pContextMenu->lpvtbl->fnInvokeCommand(pContextMenu, &cmi);
+            }
+            DestroyMenu32(hMenu);
+         }
+         pContextMenu->lpvtbl->fnRelease(pContextMenu);
+      }
+      SHFree(aSelectedItems);
+	}
+}
+
+/**************************************************************************
+* ShellView_OnNotify()
+*/
+   
+LRESULT ShellView_OnNotify(LPSHELLVIEW this, UINT32 CtlID, LPNMHDR lpnmh)
+{ NM_LISTVIEW *lpnmlv = (NM_LISTVIEW*)lpnmh;
+  LV_DISPINFO *lpdi = (LV_DISPINFO *)lpnmh;
+  LPITEMIDLIST pidl;
+  DWORD dwCursor; 
+  STRRET   str;  
+  UINT32  uFlags;
+  IExtractIcon *pei;
+  
+  TRACE(shell,"%p CtlID=%u lpnmh->code=%x\n",this,CtlID,lpnmh->code);
+  
+  switch(lpnmh->code)
+  { case NM_SETFOCUS:
+	  TRACE(shell,"NM_SETFOCUS %p\n",this);
+      ShellView_OnSetFocus(this);
+      break;
+
+    case NM_KILLFOCUS:
+	  TRACE(shell,"NM_KILLFOCUS %p\n",this);
+      ShellView_OnDeactivate(this);
+      break;
+
+    case HDN_ENDTRACK:
+	  TRACE(shell,"HDN_ENDTRACK %p\n",this);
+      /*nColumn1 = ListView_GetColumnWidth(this->hWndList, 0);
+      nColumn2 = ListView_GetColumnWidth(this->hWndList, 1);*/
+	  return 0;
+   
+   case LVN_DELETEITEM:
+	  TRACE(shell,"LVN_DELETEITEM %p\n",this);
+      SHFree((LPITEMIDLIST)lpnmlv->lParam);     /*delete the pidl because we made a copy of it*/
+      break;
+   
+#ifdef LVN_ITEMACTIVATE
+   case LVN_ITEMACTIVATE:
+
+#else    //LVN_ITEMACTIVATE
+   case NM_DBLCLK:
+   case NM_RETURN:
+#endif   //LVN_ITEMACTIVATE
+	  TRACE(shell,"LVN_ITEMACTIVATE | NM_RETURN %p\n",this);
+      ShellView_DoContextMenu(this, 0, 0, TRUE);
+      return 0;
+   
+   case LVN_GETDISPINFO:
+      TRACE(shell,"LVN_GETDISPINFO %p\n",this);
+      pidl = (LPITEMIDLIST)lpdi->item.lParam;
+
+
+      if(lpdi->item.iSubItem)	      /*is the sub-item information being requested?*/
+      { if(lpdi->item.mask & LVIF_TEXT)	 /*is the text being requested?*/
+        { if(PidlMgr_IsValue(NULL,pidl))	/*is this a value or a folder?*/
+          {  PidlMgr_GetDataText(NULL,this->mpidl, pidl, lpdi->item.pszText, lpdi->item.cchTextMax);
+             if(!*lpdi->item.pszText)
+               sprintf(lpdi->item.pszText, "file attrib %u", lpdi->item.iSubItem );
+          }
+          else  /*its a folder*/
+          { sprintf(lpdi->item.pszText, "folder attrib %u", lpdi->item.iSubItem );
+          }
+        }
+      }
+      else       /*the item text is being requested*/
+      { if(lpdi->item.mask & LVIF_TEXT)       /*is the text being requested?*/
+        { if(S_OK==this->pSFParent->lpvtbl->fnGetDisplayNameOf(this->pSFParent,pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &str))
+          { if(STRRET_WSTR == str.uType)
+            { WideCharToLocal32(lpdi->item.pszText, str.u.pOleStr, lpdi->item.cchTextMax);
+              SHFree(str.u.pOleStr);
+            }
+            if(STRRET_CSTR == str.uType)
+            { strncpy(lpdi->item.pszText, str.u.cStr, lpdi->item.cchTextMax);
+            }
+          }
+        }
+
+        if(lpdi->item.mask & LVIF_IMAGE) 		/*is the image being requested?*/
+        { if(S_OK == (this->pSFParent->lpvtbl->fnGetUIObjectOf(this->pSFParent,this->hWnd,1,
+        						(LPCITEMIDLIST*)&pidl, (REFIID)&IID_IExtractIcon, NULL, (LPVOID*)&pei)))
+          { //GetIconLoaction will give us the index into our image list
+            pei->lpvtbl->fnGetIconLocation(pei, GIL_FORSHELL, NULL, 0, &lpdi->item.iImage, &uFlags);
+	        pei->lpvtbl->fnRelease(pei);
+          }
+        }
+      }
+      TRACE(shell,"-- text=%s image=%x\n",lpdi->item.pszText, lpdi->item.iImage);
+      return 0;
+
+    case NM_RCLICK:
+	  TRACE(shell,"NM_RCLICK %p\n",this);
+      dwCursor = GetMessagePos();
+      ShellView_DoContextMenu(this, LOWORD(dwCursor), HIWORD(dwCursor), FALSE);
+
+    case NM_CLICK:
+	  TRACE(shell,"NM_CLICK %p\n",this);
+      break;
+
+    case LVN_ITEMCHANGING:
+	  TRACE(shell,"LVN_ITEMCHANGING %p\n",this);
+      break;
+
+    case NM_CUSTOMDRAW:
+	  TRACE(shell,"NM_CUSTOMDRAW %p\n",this);
+      break;
+
+	default:
+      WARN (shell,"-- WM_NOTIFY unhandled\n");
+    return 0;
+  }
+  return 0;
+}
+
+/**************************************************************************
+*  ShellView_WndProc
+*/
+//windowsx.h
+#define GET_WM_COMMAND_ID(wp, lp)               LOWORD(wp)
+#define GET_WM_COMMAND_HWND(wp, lp)             (HWND32)(lp)
+#define GET_WM_COMMAND_CMD(wp, lp)              HIWORD(wp)
+// winuser.h
+#define WM_SETTINGCHANGE                WM_WININICHANGE
+
+LRESULT CALLBACK ShellView_WndProc(HWND32 hWnd, UINT32 uMessage, WPARAM32 wParam, LPARAM lParam)
+{ LPSHELLVIEW pThis = (LPSHELLVIEW)GetWindowLong32A(hWnd, GWL_USERDATA);
+  LPCREATESTRUCT32A lpcs;
+
+  FIXME(shell,"(hwnd=%x msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
+    
+  switch (uMessage)
+  { case WM_NCCREATE:
+      { TRACE(shell,"WM_NCCREATE\n");
+        lpcs = (LPCREATESTRUCT32A)lParam;
+        pThis = (LPSHELLVIEW)(lpcs->lpCreateParams);
+        SetWindowLong32A(hWnd, GWL_USERDATA, (LONG)pThis);
+        pThis->hWnd = hWnd;        /*set the window handle*/
+      }
+      break;
+   
+   case WM_SIZE:
+      TRACE(shell,"WM_SIZE\n");
+      return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
+   
+   case WM_SETFOCUS:
+      TRACE(shell,"WM_SETFOCUS\n");   
+      return ShellView_OnSetFocus(pThis);
+ 
+   case WM_KILLFOCUS:
+      TRACE(shell,"WM_KILLFOCUS\n");
+  	  return ShellView_OnKillFocus(pThis);
+
+   case WM_CREATE:
+      TRACE(shell,"WM_CREATE\n");
+      return ShellView_OnCreate(pThis);
+
+   case WM_SHOWWINDOW:
+      TRACE(shell,"WM_SHOWWINDOW\n");
+      UpdateWindow32(pThis->hWndList);
+      break;
+
+   case WM_ACTIVATE:
+      TRACE(shell,"WM_ACTIVATE\n");
+      return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
+   
+   case WM_COMMAND:
+      TRACE(shell,"WM_COMMAND\n");
+      return ShellView_OnCommand(pThis, GET_WM_COMMAND_ID(wParam, lParam), 
+                                  GET_WM_COMMAND_CMD(wParam, lParam), 
+                                  GET_WM_COMMAND_HWND(wParam, lParam));
+   
+   case WM_INITMENUPOPUP:
+      TRACE(shell,"WM_INITMENUPOPUP\n");
+      return ShellView_UpdateMenu(pThis, (HMENU32)wParam);
+   
+   case WM_NOTIFY:
+      TRACE(shell,"WM_NOTIFY\n");
+      return ShellView_OnNotify(pThis,(UINT32)wParam, (LPNMHDR)lParam);
+
+   case WM_SETTINGCHANGE:
+      TRACE(shell,"WM_SETTINGCHANGE\n");
+      return ShellView_OnSettingChange(pThis,(LPCSTR)lParam);
+
+/* -------------*/
+   case WM_MOVE:
+      TRACE(shell,"WM_MOVE\n");   
+      break;
+   
+   case WM_ACTIVATEAPP:
+      TRACE(shell,"WM_ACTIVATEAPP\n");
+      break;
+
+   case WM_NOTIFYFORMAT:
+      TRACE(shell,"WM_NOTIFYFORMAT\n");
+      break;
+
+   case WM_NCPAINT:
+      TRACE(shell,"WM_NCPAINT\n");
+      break;
+
+   case WM_ERASEBKGND:
+      TRACE(shell,"WM_ERASEBKGND\n");
+      break;
+
+   case WM_PAINT:
+      TRACE(shell,"WM_PAINT\n");
+      break;
+
+   case WM_NCCALCSIZE:
+      TRACE(shell,"WM_NCCALCSIZE\n");
+      break;
+
+   case WM_WINDOWPOSCHANGING:
+      TRACE(shell,"WM_WINDOWPOSCHANGING\n");
+      break;
+
+   case WM_WINDOWPOSCHANGED:
+      TRACE(shell,"WM_WINDOWPOSCHANGED\n");
+      break;
+
+   case WM_PARENTNOTIFY:
+      TRACE(shell,"WM_PARENTNOTIFY\n");
+      break;
+
+   case WM_MOUSEACTIVATE:
+      TRACE(shell,"WM_MOUSEACTIVATE\n");
+      break;
+
+   case WM_SETCURSOR:
+      TRACE(shell,"WM_SETCURSOR\n");
+      break;
+  }
+  return DefWindowProc32A (hWnd, uMessage, wParam, lParam);
+}
+
+
+/**************************************************************************
+*  IShellView::QueryInterface
+*/
+static HRESULT WINAPI IShellView_QueryInterface(LPSHELLVIEW this,REFIID riid, LPVOID *ppvObj)
+{ char    xriid[50];
+  WINE_StringFromCLSID((LPCLSID)riid,xriid);
+  TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);
+
+  *ppvObj = NULL;
+
+  if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
+  { *ppvObj = this; 
+  }
+  else if(IsEqualIID(riid, &IID_IShellView))  /*IShellView*/
+  { *ppvObj = (IShellView*)this;
+  }   
+
+  if(*ppvObj)
+  { (*(LPSHELLVIEW*)ppvObj)->lpvtbl->fnAddRef(this);      
+    TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
+    return S_OK;
+  }
+  TRACE(shell,"-- Interface: E_NOINTERFACE\n");
+  return E_NOINTERFACE;
+}   
+/**************************************************************************
+*  IShellView::AddRef
+*/
+static ULONG WINAPI IShellView_AddRef(LPSHELLVIEW this)
+{ TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
+  return ++(this->ref);
+}
+/**************************************************************************
+*  IShellView::Release
+*/
+static ULONG WINAPI IShellView_Release(LPSHELLVIEW this)
+{ TRACE(shell,"(%p)->()\n",this);
+  if (!--(this->ref)) 
+  { TRACE(shell," destroying IEnumIDList(%p)\n",this);
+
+    if(this->pSFParent)
+       this->pSFParent->lpvtbl->fnRelease(this->pSFParent);
+
+    HeapFree(GetProcessHeap(),0,this);
+    return 0;
+  }
+  return this->ref;
+}
+/**************************************************************************
+*  IShellView::GetWindow
+*/
+static HRESULT WINAPI IShellView_GetWindow(LPSHELLVIEW this,HWND32 * phWnd)
+{ TRACE(shell,"(%p) stub\n",this);
+ *phWnd = this->hWnd;
+
+ return S_OK;
+}
+static HRESULT WINAPI IShellView_ContextSensitiveHelp(LPSHELLVIEW this,BOOL32 fEnterMode)
+{ FIXME(shell,"(%p) stub\n",this);
+  return E_NOTIMPL;
+}
+static HRESULT WINAPI IShellView_TranslateAccelerator(LPSHELLVIEW this,LPMSG32 lpmsg)
+{ FIXME(shell,"(%p)->(%p) stub\n",this,lpmsg);
+  return E_NOTIMPL;
+}
+static HRESULT WINAPI IShellView_EnableModeless(LPSHELLVIEW this,BOOL32 fEnable)
+{ FIXME(shell,"(%p) stub\n",this);
+  return E_NOTIMPL;
+}
+static HRESULT WINAPI IShellView_UIActivate(LPSHELLVIEW this,UINT32 uState)
+{	CHAR	szName[MAX_PATH];
+	LRESULT	lResult;
+	int		nPartArray[1] = {-1};
+
+	FIXME(shell,"(%p) stub\n",this);
+	//don't do anything if the state isn't really changing
+	if(this->uState == uState)
+	{ return S_OK;
+    }
+
+	//OnActivate handles the menu merging and internal state
+	ShellView_OnActivate(this, uState);
+
+	//remove the docking window
+	if(g_bShowIDW)
+	{ ShellView_AddRemoveDockingWindow(this, FALSE);
+    }
+
+	//only do this if we are active
+	if(uState != SVUIA_DEACTIVATE)
+	{ //update the status bar
+	   strcpy(szName, "dummy32");
+   
+	  this->pSFParent->lpvtbl->fnGetFolderPath(this->pSFParent, szName + strlen(szName), sizeof(szName) - strlen(szName));
+
+	  /* set the number of parts */
+	  this->pShellBrowser->lpvtbl->fnSendControlMsg(this->pShellBrowser,FCW_STATUS,
+      				 SB_SETPARTS, 1, (LPARAM)nPartArray, &lResult);
+
+	  /* set the text for the parts */
+	  this->pShellBrowser->lpvtbl->fnSendControlMsg(this->pShellBrowser,FCW_STATUS,
+      				 SB_SETTEXT32A, 0, (LPARAM)szName, &lResult);
+
+	  //add the docking window if necessary
+	  if(g_bShowIDW)
+	  { ShellView_AddRemoveDockingWindow(this, TRUE);
+      }
+	}
+	return S_OK;
+}
+static HRESULT WINAPI IShellView_Refresh(LPSHELLVIEW this)
+{	TRACE(shell,"(%p) stub\n",this);
+	ListView_DeleteAllItems(this->hWndList);
+	ShellView_FillList(this);
+	return S_OK;
+}
+static HRESULT WINAPI IShellView_CreateViewWindow(LPSHELLVIEW this, IShellView *lpPrevView,
+                     LPCFOLDERSETTINGS lpfs, IShellBrowser * psb,RECT32 * prcView, HWND32  *phWnd)
+{  WNDCLASS32A wc;
+   *phWnd = 0;
+
+   TRACE(shell,"(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",this, lpPrevView,lpfs, psb, prcView, phWnd);
+   TRACE(shell,"-- left=%i top=%i right=%i bottom=%i\n",prcView->left,prcView->top, prcView->right, prcView->bottom);
+   
+//if our window class has not been registered, then do so
+  if(!GetClassInfo32A(shell32_hInstance, SV_CLASS_NAME, &wc))
+  { ZeroMemory(&wc, sizeof(wc));
+    wc.style          = CS_HREDRAW | CS_VREDRAW;
+    wc.lpfnWndProc    = (WNDPROC32) ShellView_WndProc;
+    wc.cbClsExtra     = 0;
+    wc.cbWndExtra     = 0;
+    wc.hInstance      = shell32_hInstance;
+    wc.hIcon          = 0;
+    wc.hCursor        = LoadCursor32A (0, IDC_ARROW32A);
+    wc.hbrBackground  = (HBRUSH32) (COLOR_WINDOW + 1);
+    wc.lpszMenuName   = NULL;
+    wc.lpszClassName  = SV_CLASS_NAME;
+   
+    if(!RegisterClass32A(&wc))
+      return E_FAIL;
+   }
+   //set up the member variables
+   this->pShellBrowser = psb;
+   this->FolderSettings = *lpfs;
+
+   //get our parent window
+   this->pShellBrowser->lpvtbl->fnGetWindow(this->pShellBrowser, &(this->hWndParent));
+
+   *phWnd = CreateWindowEx32A(0, SV_CLASS_NAME, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
+                           prcView->left, prcView->top, prcView->right - prcView->left, prcView->bottom - prcView->top,
+                           this->hWndParent, 0, shell32_hInstance, (LPVOID)this);
+                           
+   if(!*phWnd)
+     return E_FAIL;
+
+   this->pShellBrowser->lpvtbl->fnAddRef(this->pShellBrowser);
+
+   return S_OK;
+}
+
+static HRESULT WINAPI IShellView_DestroyViewWindow(LPSHELLVIEW this)
+{	TRACE(shell,"(%p) stub\n",this);
+
+	/*Make absolutely sure all our UI is cleaned up.*/
+	IShellView_UIActivate(this, SVUIA_DEACTIVATE);
+	if(this->hMenu)
+   	{ DestroyMenu32(this->hMenu);
+    }
+	DestroyWindow32(this->hWnd);
+	this->pShellBrowser->lpvtbl->fnRelease(this->pShellBrowser);
+	return S_OK;
+}
+static HRESULT WINAPI IShellView_GetCurrentInfo(LPSHELLVIEW this, LPFOLDERSETTINGS lpfs)
+{ FIXME(shell,"(%p)->(%p)stub\n",this, lpfs);
+
+  *lpfs = this->FolderSettings;
+  return S_OK;
+}
+static HRESULT WINAPI IShellView_AddPropertySheetPages(LPSHELLVIEW this, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
+{ FIXME(shell,"(%p) stub\n",this);
+  return E_NOTIMPL;
+}
+static HRESULT WINAPI IShellView_SaveViewState(LPSHELLVIEW this)
+{ FIXME(shell,"(%p) stub\n",this);
+  return S_OK;
+}
+static HRESULT WINAPI IShellView_SelectItem(LPSHELLVIEW this, LPCITEMIDLIST pidlItem, UINT32 uFlags)
+{ FIXME(shell,"(%p)->(pidl=%p, 0x%08x) stub\n",this, pidlItem, uFlags);
+  return E_NOTIMPL;
+}
+static HRESULT WINAPI IShellView_GetItemObject(LPSHELLVIEW this, UINT32 uItem, REFIID riid,LPVOID *ppvOut)
+{ char    xriid[50];
+  WINE_StringFromCLSID((LPCLSID)riid,xriid);
+
+  FIXME(shell,"(%p)->(0x%08x,\n\t%s, %p)stub\n",this, uItem, xriid, ppvOut);
+
+  *ppvOut = NULL;
+  return E_NOTIMPL;
+}
diff --git a/dlls/shell32/shres.rc b/dlls/shell32/shres.rc
new file mode 100644
index 0000000..508a31d
--- /dev/null
+++ b/dlls/shell32/shres.rc
@@ -0,0 +1,21 @@
+#include "shresdef.h"
+
+// we have to find a solution for the icons
+// IDI_FOLDER              ICON    DISCARDABLE     "folder.ico"
+// IDI_FOLDEROPEN          ICON    DISCARDABLE     "folderop.ico"
+
+STRINGTABLE DISCARDABLE 
+BEGIN
+    IDS_FILE_TITLE      	"Files: "
+    IDS_MI_FILE         	"&Files"
+    IDS_MI_VIEW_FILES       "&View Files"
+    IDS_TB_VIEW_FILES       "View Filess"
+    IDS_MI_VIEW_IDW         "Show &Docking Window"
+    IDS_TB_VIEW_IDW         "Show Docking Window"
+    IDS_COLUMN1             "Name"
+    IDS_COLUMN2             "Date"
+    IDS_COLUMN3             "Size"
+    IDS_COLUMN4             "Attributes"
+END
+
+
diff --git a/dlls/shell32/shresdef.h b/dlls/shell32/shresdef.h
new file mode 100644
index 0000000..7ce0202
--- /dev/null
+++ b/dlls/shell32/shresdef.h
@@ -0,0 +1,21 @@
+#ifndef __WINE_SHELL_RES_H
+#define __WINE_SHELL_RES_H
+
+#define IDS_FILE_TITLE              	1
+#define IDS_MI_FILE                 	2
+#define IDS_MI_VIEW_FILES               3
+#define IDS_TB_VIEW_FILES               4
+#define IDS_MI_VIEW_IDW                 5
+#define IDS_TB_VIEW_IDW                 6
+
+#define IDS_COLUMN1                     7
+#define IDS_COLUMN2                     8
+#define IDS_COLUMN3                     9
+#define IDS_COLUMN4                     10
+
+#define IDS_MI_FILEITEM                 12
+
+#define IDI_FOLDER                      101
+#define IDI_FOLDEROPEN                  102
+
+#endif
diff --git a/documentation/Makefile.in b/documentation/Makefile.in
index fdf44b1..fb551bd 100644
--- a/documentation/Makefile.in
+++ b/documentation/Makefile.in
@@ -52,10 +52,16 @@
 install:: 
 	$(INSTALL_DATA) $(SRCDIR)/wine.man $(mandir)/wine$(manext)
 
+uninstall::
+	$(RM) $(mandir)/wine$(manext)
+
 # Not done by default because of makeinfo bugs
 install_info: $(INFOFILES)
 	for i in $(INFOFILES); do $(INSTALL_DATA) $$i $(infodir)/$$i; done
 
+uninstall_info:
+	for i in $(INFOFILES); do $(RM) $(infodir)/$$i; done
+
 clean::
 	$(RM) $(INFOFILES) $(DVIFILES) $(INCLUDES)
 	$(RM) wine.aux wine.cp wine.cps wine.fn wine.fns wine.ky wine.log \
diff --git a/documentation/common_controls b/documentation/common_controls
index 6f854a2..43b4430 100644
--- a/documentation/common_controls
+++ b/documentation/common_controls
@@ -199,7 +199,7 @@
       - Basic functionality is almost done. (dll version 4.0)
 
   Notes:
-      Bitmaps are not correctly displayed.
+      - Bitmaps are not correctly displayed.
 
 
 3.19 Tooltip Control
@@ -212,7 +212,6 @@
 
   Notes:
       - Unicode support is still missing.
-      - No subclassing.
 
 
 3.20 Trackbar Control
@@ -236,9 +235,6 @@
   Status:
       - Dummy control. No functionality.
 
-  Notes:
-      Author needed!! Any volunteers??
-
 
 3.22 Updown Control
 -------------------
@@ -270,7 +266,7 @@
 ------------------------
 
   There are quite a lot of undocumented functions like:
-     - DSA (Dynnamic String Array?) functions.
+     - DSA (Dynnamic Structure Array) functions.
      - DPA (Dymnamic Pointer Array?) functions.
      - MRU ("Most Recently Used" List) functions.
      - other unknown functions.
@@ -278,12 +274,13 @@
   Have a look at relay32/comctl32.spec.
 
 
-5.1 Dymnamic String Arrays ??? (DSA)
+5.1 Dymnamic Structure Arrays (DSA)
 ------------------------------------
   Most of the DSA functions are implemented. I used TASKMAN.EXE to write them.
   Since TASKMAN.EXE doesn't bail out or crash I think I've done it right.
 
   Have a look at the source code to get more information.
+
   Further documentation will be written...
 
 
@@ -298,16 +295,32 @@
   Further documentation will be written...
 
 
-5.3 MenuHelp
+5.3 "Most Recently Used" - List (MRU)
+-------------------------------------
+  Currently no information available!
+
+
+5.4 MenuHelp
 ------------
   Has to be written...
 
 
-5.4 GetEffectiveClientRect
+5.5 GetEffectiveClientRect
 --------------------------
   Has to be written...
 
 
+5.6 ShowHideMenuCtl
+-------------------
+  The official documentation provided by MS is incomplete.
+
+  lpInfo:
+  ...
+  Both values of the first pair must be the handle to the applications main
+  menu.
+  ...
+
+
 6. Epilogue
 -----------
   You see, much work has still to be done. If you are interested in writing
diff --git a/documentation/filehandles b/documentation/filehandles
new file mode 100644
index 0000000..d002e4a
--- /dev/null
+++ b/documentation/filehandles
@@ -0,0 +1,26 @@
+DOS treats the first 5 file handles as special cases.  They map directly
+to stdin, stdout, stderr, stdaux and stdprn.  Windows 16 inherits this
+behavoir, and in fact, win16 handles are interchangable with DOS handles.
+Some nasty windows programs even do this!
+
+Windows32 issues file handles starting from 1, on the grounds that
+most GUI processes don't need a stdin, out, etc.
+
+The wine handle code is implemented in the Win32 style, and the Win16
+functions use two macros to convert to and from the two types.
+
+The macros are defined in file.h as follows.:
+#define HFILE16_TO_HFILE32(handle) \
+(((handle)==0) ? GetStdHandle(STD_INPUT_HANDLE) : \
+ ((handle)==1) ? GetStdHandle(STD_OUTPUT_HANDLE) : \
+ ((handle)==2) ? GetStdHandle(STD_ERROR_HANDLE) : \
+ (handle)-5)
+
+#define HFILE32_TO_HFILE16(handle) ({ HFILE32 hnd=handle; \
+      ((hnd==HFILE_ERROR32) ? HFILE_ERROR16 : \
+       (HFILE16)hnd+5); })
+
+WARNING: be careful not to use the macro HFILE16_TO_HFILE32 on
+functions with side-effects, as it will cause them to be evaluated
+several times.  This could be considered a bug, but the use of this
+macro is limited enough not to need a rewrite.
diff --git a/documentation/internal-dll b/documentation/internal-dll
new file mode 100644
index 0000000..d90b70b
--- /dev/null
+++ b/documentation/internal-dll
@@ -0,0 +1,75 @@
+This document describes some points you should know when you are going to
+implement the internal counterparts to external DLL's. Only 32  bit DLL's
+are considered.
+
+1. The LibMain function
+-----------------------
+These are the way to do some initialising when a process or thread is attached
+to the dll. The function name is taken from a *.spec file line:
+
+init    YourFunctionName
+
+the you have to implement the function:
+
+
+BOOL32 WINAPI YourLibMain(HINSTANCE32 hinstDLL,
+			 DWORD fdwReason, LPVOID lpvReserved)
+{ if (fdwReason==DLL_PROCESS_ATTACH)
+  { ...
+  } 
+  ....
+}
+
+
+2. Using functions from other build-in DLL's
+--------------------------------------------
+The problem here is, that you can't know if you have to call the function from
+the internal or the external DLL. If you just call the function you will get
+the internal implementation. If the external DLL is loaded the executed program
+will use the external and you the internal DLL. 
+When you -as example- fill a iconlist placed in the internal DLL the
+application wont get the icons from the external DLL.
+
+To go around this you have to call the functions over pointer.
+
+/* definition of the pointer type*/
+void (CALLBACK* pDLLInitComctl)();
+
+/* getting the function address  this should be done in the
+ LibMain function when called with DLL_PROCESS_ATTACH*/
+ 
+BOOL32 WINAPI Shell32LibMain(HINSTANCE32 hinstDLL, DWORD fdwReason,
+							 LPVOID lpvReserved)
+{ HINSTANCE32 hComctl32;
+  if (fdwReason==DLL_PROCESS_ATTACH)
+  { /* load the external / internal DLL*/
+    hComctl32 = LoadLibrary32A("COMCTL32.DLL"); 
+    if (hComctl32)
+    { /* get the function pointer */
+      pDLLInitComctl=GetProcAddress32(hComctl32,"InitCommonControlsEx");
+
+	  /* check it */
+      if (pDLLInitComctl)
+      { /* use it */
+        pDLLInitComctl();
+      }
+      
+      /* free the DLL / decrease the ref count */
+      FreeLibrary32(hComctl32);
+    }
+    else
+    { /* do some panic*/
+      ERR(shell,"P A N I C error getting functionpointers\n");
+      exit (1);
+    }
+  }
+ ....
+
+3. Getting resources from a *.rc file linked to the DLL
+-------------------------------------------------------
+< If you know how, write some lines>
+
+
+
+----------
+<juergen.schmied@metronet.de>
diff --git a/documentation/shell32 b/documentation/shell32
new file mode 100644
index 0000000..4fcb2ef
--- /dev/null
+++ b/documentation/shell32
@@ -0,0 +1,71 @@
+				SHELL32
+			development status
+
+      Author needed!! Any volunteers?? 
+      mail to <juergen.schmied@metronet.de>
+            
+1. Introduction
+---------------
+All parts of this DLL are currently under development. About a third of
+base functionality is roughly in place. The missing parts are the icon
+(shell icon cache) handling and the dialogs provided from the dll like
+the file copy status window.
+
+The basis comes from Marcus Meissner and I <juergen.schmied@metronet.de>
+implemented the classes and filled function stubs.
+            
+2. General Information
+----------------------
+
+3. Functions
+------------
+
+4. Classes
+----------
+
+4.1 IContextMenu
+----------------
+    Status:
+	- development started
+ 
+4.2 IShellExtInit
+-----------------
+ only interface definition
+ 
+4.3 IEnumIDList
+---------------
+  Status:
+      - Almost finished.
+
+ 
+4.4.IShellFolder
+----------------
+  Status:
+      - roughly finished.
+
+
+4.5 IShellView
+--------------
+  Status:
+      - under development
+
+
+4.6 IShellBrowser
+-----------------
+  Status:
+	- only interface definition
+	  it's implemented by the explorer
+	  don't know if we need it 
+ 
+4.7. PIDL Manager
+-----------------
+  Status:
+	- roughly complete will be migrated to a set of functions because it's
+    not holding any instance data,
+
+
+5. Structures
+-------------
+
+5.1 PIDL
+--------
diff --git a/files/dos_fs.c b/files/dos_fs.c
index e61e8e7..fd168c4 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -24,6 +24,7 @@
 #include "file.h"
 #include "heap.h"
 #include "msdos.h"
+#include "syslevel.h"
 #include "debug.h"
 
 /* Define the VFAT ioctl to get both short and long file names */
@@ -74,16 +75,6 @@
 BYTE DOS_ErrorAction;
 BYTE DOS_ErrorLocus;
 
-/* Info structure for FindFirstFile handle */
-typedef struct
-{
-    LPSTR path;
-    LPSTR mask;
-    int   drive;
-    int   skip;
-} FIND_FIRST_INFO;
-
-
 /* Directory info for DOSFS_ReadDir */
 typedef struct
 {
@@ -95,6 +86,19 @@
 #endif
 } DOS_DIR;
 
+/* Info structure for FindFirstFile handle */
+typedef struct
+{
+    LPSTR path;
+    LPSTR long_mask;
+    LPSTR short_mask;
+    BYTE  attr;
+    int   drive;
+    int   cur_pos;
+    DOS_DIR *dir;
+} FIND_FIRST_INFO;
+
+
 
 /***********************************************************************
  *           DOSFS_ValidDOSName
@@ -1016,33 +1020,23 @@
     return ret;
 }
 
-
 /***********************************************************************
- *           DOSFS_FindNext
- *
- * Find the next matching file. Return the number of entries read to find
- * the matching one, or 0 if no more entries.
- * 'short_mask' is the 8.3 mask (in FCB format), 'long_mask' is the long
- * file name mask. Either or both can be NULL.
+ *           DOSFS_FindNextEx
  */
-int DOSFS_FindNext( const char *path, const char *short_mask,
-                    const char *long_mask, int drive, BYTE attr,
-                    int skip, WIN32_FIND_DATA32A *entry )
+static int DOSFS_FindNextEx( FIND_FIRST_INFO *info, WIN32_FIND_DATA32A *entry )
 {
-    static DOS_DIR *dir = NULL;
-    int count = 0;
-    static char buffer[MAX_PATHNAME_LEN];
-    static int cur_pos = 0;
-    static int drive_root = 0;
-    char *p;
-    char dos_name[13];
+    BYTE attr = info->attr | FA_UNUSED | FA_ARCHIVE | FA_RDONLY;
+    UINT32 flags = DRIVE_GetFlags( info->drive );
+    char *p, buffer[MAX_PATHNAME_LEN];
+    const char *drive_path;
+    int drive_root;
     LPCSTR long_name, short_name;
-    UINT32 flags;
-    BY_HANDLE_FILE_INFORMATION info;
+    BY_HANDLE_FILE_INFORMATION fileinfo;
+    char dos_name[13];
 
-    if ((attr & ~(FA_UNUSED | FA_ARCHIVE | FA_RDONLY)) == FA_LABEL)
+    if ((info->attr & ~(FA_UNUSED | FA_ARCHIVE | FA_RDONLY)) == FA_LABEL)
     {
-        if (skip) return 0;
+        if (info->cur_pos) return 0;
         entry->dwFileAttributes  = FILE_ATTRIBUTE_LABEL;
         DOSFS_UnixTimeToFileTime( (time_t)0, &entry->ftCreationTime, 0 );
         DOSFS_UnixTimeToFileTime( (time_t)0, &entry->ftLastAccessTime, 0 );
@@ -1051,37 +1045,23 @@
         entry->nFileSizeLow      = 0;
         entry->dwReserved0       = 0;
         entry->dwReserved1       = 0;
-        DOSFS_ToDosDTAFormat( DRIVE_GetLabel( drive ), entry->cFileName );
-        strcpy( entry->cAlternateFileName, entry->cFileName );
+        DOSFS_ToDosDTAFormat( DRIVE_GetLabel( info->drive ), entry->cFileName );
+        strcpy( entry->cAlternateFileName, entry->cFileName ); 
+        info->cur_pos++;
         return 1;
     }
 
-    /* Check the cached directory */
-    if (dir && !strcmp( buffer, path ) && (cur_pos <= skip)) skip -= cur_pos;
-    else  /* Not in the cache, open it anew */
-    {
-        const char *drive_path;
-        TRACE(dosfs, "cache miss, path=%s skip=%d buf=%s cur=%d\n",
-                       path, skip, buffer, cur_pos );
-        cur_pos = skip;
-        if (dir) DOSFS_CloseDir(dir);
-        if (!*path) path = "/";
-        if (!(dir = DOSFS_OpenDir(path))) return 0;
-        drive_path = path + strlen(DRIVE_GetRoot(drive));
-        while ((*drive_path == '/') || (*drive_path == '\\')) drive_path++;
-        drive_root = !*drive_path;
-        TRACE(dosfs, "drive_root = %d\n", drive_root);
-        lstrcpyn32A( buffer, path, sizeof(buffer) - 1 );
-    }
+    drive_path = info->path + strlen(DRIVE_GetRoot( info->drive ));
+    while ((*drive_path == '/') || (*drive_path == '\\')) drive_path++;
+    drive_root = !*drive_path;
+
+    lstrcpyn32A( buffer, info->path, sizeof(buffer) - 1 );
     strcat( buffer, "/" );
     p = buffer + strlen(buffer);
-    attr |= FA_UNUSED | FA_ARCHIVE | FA_RDONLY;
-    flags = DRIVE_GetFlags( drive );
 
-    while (DOSFS_ReadDir( dir, &long_name, &short_name ))
+    while (DOSFS_ReadDir( info->dir, &long_name, &short_name ))
     {
-        if (skip-- > 0) continue;
-        count++;
+        info->cur_pos++;
 
         /* Don't return '.' and '..' in the root of the drive */
         if (drive_root && (long_name[0] == '.') &&
@@ -1090,15 +1070,15 @@
 
         /* Check the long mask */
 
-        if (long_mask)
+        if (info->long_mask)
         {
-            if (!DOSFS_MatchLong( long_mask, long_name,
+            if (!DOSFS_MatchLong( info->long_mask, long_name,
                                   flags & DRIVE_CASE_SENSITIVE )) continue;
         }
 
         /* Check the short mask */
 
-        if (short_mask)
+        if (info->short_mask)
         {
             if (!short_name)
             {
@@ -1106,27 +1086,27 @@
                             !(flags & DRIVE_CASE_SENSITIVE) );
                 short_name = dos_name;
             }
-            if (!DOSFS_MatchShort( short_mask, short_name )) continue;
+            if (!DOSFS_MatchShort( info->short_mask, short_name )) continue;
         }
 
         /* Check the file attributes */
 
         lstrcpyn32A( p, long_name, sizeof(buffer) - (int)(p - buffer) );
-        if (!FILE_Stat( buffer, &info ))
+        if (!FILE_Stat( buffer, &fileinfo ))
         {
             WARN(dosfs, "can't stat %s\n", buffer);
             continue;
         }
-        if (info.dwFileAttributes & ~attr) continue;
+        if (fileinfo.dwFileAttributes & ~attr) continue;
 
         /* We now have a matching entry; fill the result and return */
 
-        entry->dwFileAttributes = info.dwFileAttributes;
-        entry->ftCreationTime   = info.ftCreationTime;
-        entry->ftLastAccessTime = info.ftLastAccessTime;
-        entry->ftLastWriteTime  = info.ftLastWriteTime;
-        entry->nFileSizeHigh    = info.nFileSizeHigh;
-        entry->nFileSizeLow     = info.nFileSizeLow;
+        entry->dwFileAttributes = fileinfo.dwFileAttributes;
+        entry->ftCreationTime   = fileinfo.ftCreationTime;
+        entry->ftLastAccessTime = fileinfo.ftLastAccessTime;
+        entry->ftLastWriteTime  = fileinfo.ftLastWriteTime;
+        entry->nFileSizeHigh    = fileinfo.nFileSizeHigh;
+        entry->nFileSizeLow     = fileinfo.nFileSizeLow;
 
         if (short_name)
             DOSFS_ToDosDTAFormat( short_name, entry->cAlternateFileName );
@@ -1139,15 +1119,75 @@
         TRACE(dosfs, "returning %s (%s) %02lx %ld\n",
                        entry->cFileName, entry->cAlternateFileName,
                        entry->dwFileAttributes, entry->nFileSizeLow );
-        cur_pos += count;
-        p[-1] = '\0';  /* Remove trailing slash in buffer */
-        return count;
+        return 1;
     }
-    DOSFS_CloseDir( dir );
-    dir = NULL;
     return 0;  /* End of directory */
 }
 
+/***********************************************************************
+ *           DOSFS_FindNext
+ *
+ * Find the next matching file. Return the number of entries read to find
+ * the matching one, or 0 if no more entries.
+ * 'short_mask' is the 8.3 mask (in FCB format), 'long_mask' is the long
+ * file name mask. Either or both can be NULL.
+ *
+ * NOTE: This is supposed to be only called by the int21 emulation
+ *       routines. Thus, we should own the Win16Mutex anyway.
+ *       Nevertheless, we explicitly enter it to ensure the static
+ *       directory cache is protected.
+ */
+int DOSFS_FindNext( const char *path, const char *short_mask,
+                    const char *long_mask, int drive, BYTE attr,
+                    int skip, WIN32_FIND_DATA32A *entry )
+{
+    static FIND_FIRST_INFO info = { NULL };
+    LPCSTR short_name, long_name;
+    int count;
+
+    SYSLEVEL_EnterWin16Lock();
+
+    /* Check the cached directory */
+    if (!(info.dir && info.path == path && info.short_mask == short_mask
+                   && info.long_mask == long_mask && info.drive == drive
+                   && info.attr == attr && info.cur_pos <= skip))
+    {  
+        /* Not in the cache, open it anew */
+        if (info.dir) DOSFS_CloseDir( info.dir );
+
+        info.path = (LPSTR)path;
+        info.long_mask = (LPSTR)long_mask;
+        info.short_mask = (LPSTR)short_mask;
+        info.attr = attr;
+        info.drive = drive;
+        info.cur_pos = 0;
+        info.dir = DOSFS_OpenDir( info.path );
+    }
+
+    /* Skip to desired position */
+    while (info.cur_pos < skip)
+        if (DOSFS_ReadDir( info.dir, &long_name, &short_name ))
+            info.cur_pos++;
+        else
+            break;
+
+    if (info.cur_pos == skip && DOSFS_FindNextEx( &info, entry ))
+        count = info.cur_pos - skip;
+    else
+        count = 0;
+
+    if (!count)
+    {
+        DOSFS_CloseDir( info.dir );
+        memset( &info, '\0', sizeof(info) );
+    }
+
+    SYSLEVEL_LeaveWin16Lock();
+
+    return count;
+}
+
+
 
 /*************************************************************************
  *           FindFirstFile16   (KERNEL.413)
@@ -1165,11 +1205,16 @@
         return INVALID_HANDLE_VALUE16;
     info = (FIND_FIRST_INFO *)GlobalLock16( handle );
     info->path = HEAP_strdupA( SystemHeap, 0, full_name.long_name );
-    info->mask = strrchr( info->path, '/' );
-    *(info->mask++) = '\0';
+    info->long_mask = strrchr( info->path, '/' );
+    *(info->long_mask++) = '\0';
+    info->short_mask = NULL;
+    info->attr = 0xff;
     if (path[0] && (path[1] == ':')) info->drive = toupper(*path) - 'A';
     else info->drive = DRIVE_GetCurrentDrive();
-    info->skip = 0;
+    info->cur_pos = 0;
+
+    info->dir = DOSFS_OpenDir( info->path );
+
     GlobalUnlock16( handle );
     if (!FindNextFile16( handle, data ))
     {
@@ -1222,7 +1267,6 @@
 BOOL16 WINAPI FindNextFile16( HANDLE16 handle, WIN32_FIND_DATA32A *data )
 {
     FIND_FIRST_INFO *info;
-    int count;
 
     if (!(info = (FIND_FIRST_INFO *)GlobalLock16( handle )))
     {
@@ -1230,20 +1274,19 @@
         return FALSE;
     }
     GlobalUnlock16( handle );
-    if (!info->path)
+    if (!info->path || !info->dir)
     {
         DOS_ERROR( ER_NoMoreFiles, EC_MediaError, SA_Abort, EL_Disk );
         return FALSE;
     }
-    if (!(count = DOSFS_FindNext( info->path, NULL, info->mask, info->drive,
-                                  0xff, info->skip, data )))
+    if (!DOSFS_FindNextEx( info, data ))
     {
+        DOSFS_CloseDir( info->dir ); info->dir = NULL;
         HeapFree( SystemHeap, 0, info->path );
-        info->path = info->mask = NULL;
+        info->path = info->long_mask = NULL;
         DOS_ERROR( ER_NoMoreFiles, EC_MediaError, SA_Abort, EL_Disk );
         return FALSE;
     }
-    info->skip += count;
     return TRUE;
 }
 
@@ -1289,6 +1332,7 @@
         DOS_ERROR( ER_InvalidHandle, EC_ProgramError, SA_Abort, EL_Disk );
         return FALSE;
     }
+    if (info->dir) DOSFS_CloseDir( info->dir );
     if (info->path) HeapFree( SystemHeap, 0, info->path );
     GlobalUnlock16( handle );
     GlobalFree16( handle );
diff --git a/files/file.c b/files/file.c
index 6ae8d60..a2bd5dd 100644
--- a/files/file.c
+++ b/files/file.c
@@ -871,7 +871,7 @@
  */
 HFILE16 WINAPI OpenFile16( LPCSTR name, OFSTRUCT *ofs, UINT16 mode )
 {
-    return FILE_DoOpenFile( name, ofs, mode, FALSE );
+    return HFILE32_TO_HFILE16(FILE_DoOpenFile( name, ofs, mode, FALSE ));
 }
 
 
@@ -890,7 +890,7 @@
 HFILE16 WINAPI _lclose16( HFILE16 hFile )
 {
     TRACE(file, "handle %d\n", hFile );
-    return CloseHandle( hFile ) ? 0 : HFILE_ERROR16;
+    return CloseHandle( HFILE16_TO_HFILE32( hFile )  ) ? 0 : HFILE_ERROR16;
 }
 
 
@@ -917,7 +917,7 @@
     /* Some programs pass a count larger than the allocated buffer */
     maxlen = GetSelectorLimit( SELECTOROF(buffer) ) - OFFSETOF(buffer) + 1;
     if (count > maxlen) count = maxlen;
-    return _lread32( hFile, PTR_SEG_TO_LIN(buffer), count );
+    return _lread32(HFILE16_TO_HFILE32(hFile), PTR_SEG_TO_LIN(buffer), count );
 }
 
 
@@ -955,7 +955,7 @@
  */
 UINT16 WINAPI _lread16( HFILE16 hFile, LPVOID buffer, UINT16 count )
 {
-    return (UINT16)_lread32( hFile, buffer, (LONG)count );
+    return (UINT16)_lread32(HFILE16_TO_HFILE32(hFile), buffer, (LONG)count );
 }
 
 
@@ -966,7 +966,7 @@
 {
     int mode = (attr & 1) ? 0444 : 0666;
     TRACE(file, "%s %02x\n", path, attr );
-    return (HFILE16)FILE_Create( path, mode, FALSE );
+    return (HFILE16) HFILE32_TO_HFILE16(FILE_Create( path, mode, FALSE ));
 }
 
 
@@ -1038,7 +1038,7 @@
  */
 LONG WINAPI _llseek16( HFILE16 hFile, LONG lOffset, INT16 nOrigin )
 {
-    return SetFilePointer( hFile, lOffset, NULL, nOrigin );
+    return SetFilePointer( HFILE16_TO_HFILE32(hFile), lOffset, NULL, nOrigin );
 }
 
 
@@ -1056,7 +1056,7 @@
  */
 HFILE16 WINAPI _lopen16( LPCSTR path, INT16 mode )
 {
-    return _lopen32( path, mode );
+    return HFILE32_TO_HFILE16(_lopen32( path, mode ));
 }
 
 
@@ -1091,7 +1091,7 @@
  */
 UINT16 WINAPI _lwrite16( HFILE16 hFile, LPCSTR buffer, UINT16 count )
 {
-    return (UINT16)_hwrite32( hFile, buffer, (LONG)count );
+    return (UINT16)_hwrite32( HFILE16_TO_HFILE32(hFile), buffer, (LONG)count );
 }
 
 /***********************************************************************
@@ -1108,7 +1108,7 @@
  */
 LONG WINAPI _hread16( HFILE16 hFile, LPVOID buffer, LONG count)
 {
-    return _lread32( hFile, buffer, count );
+    return _lread32( HFILE16_TO_HFILE32(hFile), buffer, count );
 }
 
 
@@ -1126,7 +1126,7 @@
  */
 LONG WINAPI _hwrite16( HFILE16 hFile, LPCSTR buffer, LONG count )
 {
-    return _hwrite32( hFile, buffer, count );
+    return _hwrite32( HFILE16_TO_HFILE32(hFile), buffer, count );
 }
 
 
diff --git a/files/profile.c b/files/profile.c
index ecdd09c..49b58d7 100644
--- a/files/profile.c
+++ b/files/profile.c
@@ -945,7 +945,7 @@
 /***********************************************************************
  *           GetProfileSection32A   (KERNEL32.268)
  */
-INT32 WINAPI GetProfileSection32A( LPCSTR section, LPSTR buffer, UINT32 len )
+INT32 WINAPI GetProfileSection32A( LPCSTR section, LPSTR buffer, DWORD len )
 {
     return GetPrivateProfileSection32A( section, buffer, len, "win.ini" );
 }
@@ -1080,7 +1080,7 @@
  *           GetPrivateProfileSection32A   (KERNEL32.255)
  */
 INT32 WINAPI GetPrivateProfileSection32A( LPCSTR section, LPSTR buffer,
-                                          UINT32 len, LPCSTR filename )
+                                          DWORD len, LPCSTR filename )
 {
     if (PROFILE_Open( filename ))
         return PROFILE_GetSection(CurProfile->section, section, buffer, len,
@@ -1186,7 +1186,7 @@
 /***********************************************************************
  *           GetPrivateProfileStruct32A (KERNEL32.370)
  */
-WORD WINAPI GetPrivateProfileStruct32A (LPCSTR section, LPCSTR key, 
+BOOL32 WINAPI GetPrivateProfileStruct32A (LPCSTR section, LPCSTR key, 
 	LPVOID buf, UINT32 len, LPCSTR filename)
 {
     PROFILEKEY *k;
@@ -1204,7 +1204,7 @@
 /***********************************************************************
  *           WritePrivateProfileStruct32A (KERNEL32.744)
  */
-WORD WINAPI WritePrivateProfileStruct32A (LPCSTR section, LPCSTR key, 
+BOOL32 WINAPI WritePrivateProfileStruct32A (LPCSTR section, LPCSTR key, 
 	LPVOID buf, UINT32 bufsize, LPCSTR filename)
 {
     if ((!section) && (!key) && (!buf)) {	/* flush the cache */
diff --git a/graphics/ddraw.c b/graphics/ddraw.c
index 4420891..3c64fcc 100644
--- a/graphics/ddraw.c
+++ b/graphics/ddraw.c
@@ -1,4 +1,4 @@
-/*		DirectDraw using DGA, XShm, or Xlib
+/*		DirectDraw using DGA or Xlib
  *
  * Copyright 1997,1998 Marcus Meissner
  */
@@ -10,52 +10,20 @@
  * - A terminal connected to the serial port. Can be bought used for cheap.
  *   (This is the method I am using.)
  * - Another machine connected over some kind of network.
- */
-/* Progress on following programs:
  *
- * - Diablo [640x480x8]:
- *   The movies play. The game doesn't work, it somehow tries to write
- *   into 2 lines _BEFORE_ the start of the surface. Don't know why.
+ * FIXME: The Xshm implementation has been temporarily removed. It will be
+ * later reintegrated into the Xlib implementation.
  *
- * - WingCommander 4 / Win95 Patch [640x480x8]:
- *   The intromovie plays, in 8 bit mode (to reconfigure wc4, run wine
- *   "wc4w.exe -I"). The 16bit mode looks broken, but I think this is due to
- *   my Matrox Mystique which uses 565 (rgb) colorweight instead of the usual
- *   555. Specifying it in DDPIXELFORMAT didn't help.
- *   Requires to be run in 640x480xdepth mode (doesn't seem to heed
- *   DDSURFACEDESC.lPitch). You can fly the first mission with Maniac, but
- *   it crashes as soon as you arrive at Blue Point Station...
- *
- * - Monkey Island 3 [640x480x8]:
- *   Goes to the easy/hard selection screen, then hangs due to MT problems.
- * 
- * - DiscWorld 2 [640x480x8]:
- *   [Crashes with 'cli' in released version. Yes. Privileged instructions
- *    in 32bit code. Will they ever learn...]
- *   Plays through nearly all intro movies. Sound and animation skip a lot of
- *   stuff (possible DirectSound problem).
- * 
- * - XvT [640x480x16]:
- *   Shows the splash screen, then fails with missing Joystick.
- *
- * - Tomb Raider 2 Demo (using 8 bit renderer) [640x480x8]:
- *   Playable. Sound is weird.
- *
- * - WingCommander Prophecy Demo (using software renderer) [640x480x16]:
- *   [Crashes with an invalid opcode (outb) in the release version.]
- *   Plays intromovie, hangs in selection screen (no keyboard input, probably
- *   DirectInput problem).
+ * FIXME: The Xlib implementation hangs the windowmanager and all other 
+ *	  running X clients, even though I am polling X events and answering
+ *	  them. But you can switch to another console (ctrl-alt-fx) and
+ *	  "killall wine" processes. Any help on this one appreciated. -Marcus
  */
 
 #include "config.h"
 #include <unistd.h>
 #include <assert.h>
 #include "ts_xlib.h"
-#ifdef HAVE_LIBXXSHM
-#include "ts_xshm.h"
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#endif
 #include <sys/signal.h>
 
 #include "windows.h"
@@ -78,6 +46,9 @@
 #include "ts_xf86dga.h"
 #endif
 
+/* define this if you want to play Diablo using XF86DGA. (bug workaround) */
+#undef DIABLO_HACK
+
 /* restore signal handlers overwritten by XF86DGA 
  * this is a define, for it will only work in emulator mode
  */
@@ -93,12 +64,7 @@
 	0x11d1,
 	{0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
 };
-static GUID XSHM_DirectDraw_GUID = { /* 2e494ff0-dc61-11d1-8407-860cf3f59f7a */
-    0x2e494ff0,
-    0xdc61,
-    0x11d1,
-    {0x84, 0x07, 0x86, 0x0c, 0xf3, 0xf5, 0x9f, 0x7a}
-};
+
 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
     0x1574a740,
     0xdc61,
@@ -106,25 +72,26 @@
     {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
 };
 
-static struct IDirectDrawSurface3_VTable	dga_dds3vt, xshm_dds3vt, xlib_dds3vt;
-static struct IDirectDraw_VTable		dga_ddvt, xshm_ddvt, xlib_ddvt;
-static struct IDirectDraw2_VTable		dga_dd2vt, xshm_dd2vt, xlib_dd2vt;
+static struct IDirectDrawSurface3_VTable	dga_dds3vt, xlib_dds3vt;
+static struct IDirectDraw_VTable		dga_ddvt, xlib_ddvt;
+static struct IDirectDraw2_VTable		dga_dd2vt, xlib_dd2vt;
 static struct IDirectDrawClipper_VTable	ddclipvt;
-static struct IDirectDrawPalette_VTable dga_ddpalvt, xshm_ddpalvt, xlib_ddpalvt;
+static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt;
 static struct IDirect3D_VTable			d3dvt;
 static struct IDirect3D2_VTable			d3d2vt;
 
 void Xlib_MessagePump(HWND32 hwnd) {
 	MSG32	msg32;
 
-	while (PeekMessage32A(&msg32,0,0,0,PM_NOYIELD)) {
-		GetMessage32A(&msg32,0,0,0);
-		TranslateMessage32(&msg32);
-		DispatchMessage32A(&msg32);
+	while (EVENT_WaitNetEvent(FALSE,FALSE)) {
+		while (PeekMessage32A(&msg32,0,0,0,0)) {
+			GetMessage32A(&msg32,0,0,0);
+			TranslateMessage32(&msg32);
+			DispatchMessage32A(&msg32);
+		}
 	}
 }
 
-
 BOOL32
 DDRAW_DGA_Available()
 {
@@ -136,24 +103,11 @@
 #endif /* defined(HAVE_LIBXXF86DGA) */
 }
 
-BOOL32
-DDRAW_XShm_Available()
-{
-#ifdef HAVE_LIBXXSHM
-	return TSXShmQueryExtension(display);
-#else /* defined(HAVE_LIBXXSHM) */
-	return 0;
-#endif /* defined(HAVE_LIBXXSHM) */
-}
-
 HRESULT WINAPI
 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
 	if (DDRAW_DGA_Available()) {
 		ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data);
 	}
-	if (DDRAW_XShm_Available()) {
-		ddenumproc(&XSHM_DirectDraw_GUID,"WINE with MIT XShm","display",data);
-	}
 	ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data);
 	ddenumproc(NULL,"WINE","display",data);
 	return 0;
@@ -326,7 +280,7 @@
 	DUMP("\n");
 }
 
-static int _getpixelformat(LPDIRECTDRAW ddraw,LPDDPIXELFORMAT pf) {
+static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) {
 	static XVisualInfo	*vi;
 	XVisualInfo		vt;
 	int			nitems;
@@ -353,7 +307,7 @@
 		pf->xy.dwRGBAlphaBitMask= 0;
 		return 0;
 	}
-	FIXME(ddraw,"_getpixelformat:oops?\n");
+	FIXME(ddraw,"_getpixelformat:unknown depth %ld?\n",ddraw->d.depth);
 	return DDERR_GENERIC;
 }
 
@@ -374,7 +328,7 @@
 			 this,lprect,lpddsd,flags,(DWORD)hnd);
 
 	if (lprect) {
-		TRACE(ddraw,"	lprect: %dx%d-%dx%d\n",
+		FIXME(ddraw,"	lprect: %dx%d-%dx%d\n",
 			lprect->top,lprect->left,lprect->bottom,lprect->right
 		);
 		lpddsd->y.lpSurface = this->s.surface +
@@ -399,40 +353,14 @@
 	return 0;
 }
 
-static HRESULT WINAPI XShm_IDirectDrawSurface3_Unlock(
-	LPDIRECTDRAWSURFACE3 this,LPVOID surface
-) {
-#ifdef HAVE_LIBXXSHM
-	TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
-	/* FIXME: is it really right to display the image on unlock?
-	 * or should it wait for a Flip()? */
-	TSXShmPutImage(display,
-				   this->s.ddraw->e.xshm.drawable,
-				   DefaultGCOfScreen(screen),
-				   this->t.xshm.image,
-				   0, 0, 0, 0,
-				   this->t.xshm.image->width,
-				   this->t.xshm.image->height,
-				   False);
-/*
-	if (this->s.palette && this->s.palette->cm) {
-		TSXInstallColormap(display,this->s.palette->cm);
-	}
-*/
-	/*TSXSync(display,False);*/
-	EVENT_Synchronize();
-	return 0;
-#else /* defined(HAVE_LIBXXSHM) */
-	return E_UNEXPECTED;
-#endif /* defined(HAVE_LIBXXSHM) */
-}
-
 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Unlock(
 	LPDIRECTDRAWSURFACE3 this,LPVOID surface
 ) {
 	Xlib_MessagePump(this->s.ddraw->e.xlib.window);
 
 	TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
+	if (!this->s.ddraw->e.xlib.paintable)
+		return 0;
 	TSXPutImage(		display,
 				this->s.ddraw->e.xlib.drawable,
 				DefaultGCOfScreen(screen),
@@ -441,8 +369,6 @@
 				this->t.xlib.image->width,
 				this->t.xlib.image->height
 	);
-	/*TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);*/
-	EVENT_Synchronize();
 	return 0;
 }
 
@@ -482,47 +408,14 @@
 #endif /* defined(HAVE_LIBXXF86DGA) */
 }
 
-static HRESULT WINAPI XShm_IDirectDrawSurface3_Flip(
-	LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
-) {
-#ifdef HAVE_LIBXXSHM
-	TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
-	if (!flipto) {
-		if (this->s.backbuffer)
-			flipto = this->s.backbuffer;
-		else
-			flipto = this;
-	}
-	TSXShmPutImage(display,
-				   this->s.ddraw->e.xshm.drawable,
-				   DefaultGCOfScreen(screen),
-				   flipto->t.xshm.image,
-				   0, 0, 0, 0,
-				   flipto->t.xshm.image->width,
-				   flipto->t.xshm.image->height,
-				   False);
-/*
-	if (flipto->s.palette && flipto->s.palette->cm) {
-		TSXInstallColormap(display,flipto->s.palette->cm);
-	}
-*/
-	EVENT_Synchronize();
-	if (flipto!=this) {
-		XImage *tmp;
-		tmp = this->t.xshm.image;
-		this->t.xshm.image = flipto->t.xshm.image;
-		flipto->t.xshm.image = tmp;
-	}
-	return 0;
-#else /* defined(HAVE_LIBXXSHM) */
-	return E_UNEXPECTED;
-#endif /* defined(HAVE_LIBXXSHM) */
-}
-
 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Flip(
 	LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
 ) {
 	TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
+	Xlib_MessagePump(this->s.ddraw->e.xlib.window);
+	if (!this->s.ddraw->e.xlib.paintable)
+		return 0;
+
 	if (!flipto) {
 		if (this->s.backbuffer)
 			flipto = this->s.backbuffer;
@@ -537,7 +430,6 @@
 				flipto->t.xlib.image->width,
 				flipto->t.xlib.image->height);
 	TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
-	EVENT_Synchronize();
 	if (flipto!=this) {
 		XImage *tmp;
 		LPVOID	*surf;
@@ -712,24 +604,6 @@
 	return this->ref;
 }
 
-static ULONG WINAPI XShm_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
-	TRACE(ddraw,"(%p)->Release()\n",this);
-#ifdef HAVE_LIBXXSHM
-	if (!--(this->ref)) {
-		this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
-		HeapFree(GetProcessHeap(),0,this->s.surface);
-		this->t.xshm.image->data = NULL;
-		TSXShmDetach(display,&this->t.xshm.shminfo);
-		TSXDestroyImage(this->t.xshm.image);
-		shmdt(this->t.xshm.shminfo.shmaddr);
-		shmctl(this->t.xshm.shminfo.shmid, IPC_RMID, 0);
-		HeapFree(GetProcessHeap(),0,this);
-		return 0;
-	}
-#endif /* defined(HAVE_LIBXXSHM) */
-	return this->ref;
-}
-
 static ULONG WINAPI Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
 	TRACE(ddraw,"(%p)->Release()\n",this);
 	if (!--(this->ref)) {
@@ -803,13 +677,13 @@
 
 static HRESULT WINAPI IDirectDrawSurface3_GetDC(LPDIRECTDRAWSURFACE3 this,HDC32* lphdc) {
 	FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
-	*lphdc = GetDC32(this->s.ddraw->e.xlib.window);
+	*lphdc = BeginPaint32(this->s.ddraw->e.xlib.window,&this->s.ddraw->e.xlib.ps);
 	return 0;
 }
 
 static HRESULT WINAPI IDirectDrawSurface3_ReleaseDC(LPDIRECTDRAWSURFACE3 this,HDC32 hdc) {
 	FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
-	ReleaseDC32(this->s.ddraw->e.xlib.window,hdc);
+	EndPaint32(this->s.ddraw->e.xlib.window,&this->s.ddraw->e.xlib.ps);
 	return 0;
 }
 
@@ -901,49 +775,6 @@
 	(void*)40,
 };
 
-static struct IDirectDrawSurface3_VTable xshm_dds3vt = {
-	IDirectDrawSurface3_QueryInterface,
-	IDirectDrawSurface3_AddRef,
-	XShm_IDirectDrawSurface3_Release,
-	IDirectDrawSurface3_AddAttachedSurface,
-	(void*)5,
-	IDirectDrawSurface3_Blt,
-	IDirectDrawSurface3_BltBatch,
-	IDirectDrawSurface3_BltFast,
-	(void*)9,
-	IDirectDrawSurface3_EnumAttachedSurfaces,
-	(void*)11,
-	XShm_IDirectDrawSurface3_Flip,
-	IDirectDrawSurface3_GetAttachedSurface,
-	IDirectDrawSurface3_GetBltStatus,
-	IDirectDrawSurface3_GetCaps,
-	(void*)16,
-	(void*)17,
-	IDirectDrawSurface3_GetDC,
-	(void*)19,
-	IDirectDrawSurface3_GetOverlayPosition,
-	(void*)21,
-	IDirectDrawSurface3_GetPixelFormat,
-	IDirectDrawSurface3_GetSurfaceDesc,
-	IDirectDrawSurface3_Initialize,
-	IDirectDrawSurface3_IsLost,
-	IDirectDrawSurface3_Lock,
-	IDirectDrawSurface3_ReleaseDC,
-	IDirectDrawSurface3_Restore,
-	IDirectDrawSurface3_SetClipper,
-	IDirectDrawSurface3_SetColorKey,
-	(void*)31,
-	IDirectDrawSurface3_SetPalette,
-	XShm_IDirectDrawSurface3_Unlock,
-	(void*)34,
-	(void*)35,
-	(void*)36,
-	(void*)37,
-	(void*)38,
-	(void*)39,
-	(void*)40,
-};
-
 static struct IDirectDrawSurface3_VTable xlib_dds3vt = {
 	IDirectDrawSurface3_QueryInterface,
 	IDirectDrawSurface3_AddRef,
@@ -1036,7 +867,7 @@
  *			IDirectDrawPalette
  */
 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
-	LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD end,LPPALETTEENTRY palent
+	LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
 ) {
 	XColor xc;
 	int	i;
@@ -1045,52 +876,76 @@
 		FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
 		return DDERR_GENERIC;
 	}
-	for (i=start;i<end;i++) {
-		xc.pixel = i;
+	for (i=0;i<count;i++) {
+		xc.pixel = i+start;
 		TSXQueryColor(display,this->cm,&xc);
-		palent[i-start].peRed = xc.red>>8;
-		palent[i-start].peGreen = xc.green>>8;
-		palent[i-start].peBlue = xc.blue>>8;
+		palent[i].peRed = xc.red>>8;
+		palent[i].peGreen = xc.green>>8;
+		palent[i].peBlue = xc.blue>>8;
 	}
 	return 0;
 }
 
-static HRESULT WINAPI common_IDirectDrawPalette_SetEntries(
-	LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD end,LPPALETTEENTRY palent
+static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
+	LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
 ) {
 	XColor		xc;
 	int		i;
 
 	TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
-		this,x,start,end,palent
+		this,x,start,count,palent
+	);
+	if (!this->cm) /* should not happen */ {
+		FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
+		return DDERR_GENERIC;
+	}
+	if (!this->ddraw->e.xlib.paintable)
+		return 0;
+	for (i=0;i<count;i++) {
+		xc.red = palent[i].peRed<<8;
+		xc.blue = palent[i].peBlue<<8;
+		xc.green = palent[i].peGreen<<8;
+		xc.flags = DoRed|DoBlue|DoGreen;
+		xc.pixel = start+i;
+		TSXStoreColor(display,this->cm,&xc);
+		this->palents[start+i].peRed = palent[i].peRed;
+		this->palents[start+i].peBlue = palent[i].peBlue;
+		this->palents[start+i].peGreen = palent[i].peGreen;
+	}
+	return 0;
+}
+
+static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
+	LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
+) {
+#ifdef HAVE_LIBXXF86DGA
+	XColor		xc;
+	Colormap	cm;
+	int		i;
+
+	TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
+		this,x,start,count,palent
 	);
 	if (!this->cm) /* should not happen */ {
 		FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
 		return DDERR_GENERIC;
 	}
 	/* FIXME: free colorcells instead of freeing whole map */
-	/*this->cm = TSXCopyColormapAndFree(display,this->cm);*/
-	for (i=start;i<end;i++) {
-		xc.red = palent[i-start].peRed<<8;
-		xc.blue = palent[i-start].peBlue<<8;
-		xc.green = palent[i-start].peGreen<<8;
-		xc.flags = DoRed|DoBlue|DoGreen;
-		xc.pixel = i;
-		TSXStoreColor(display,this->cm,&xc);
-		this->palents[i].peRed = palent[i-start].peRed;
-		this->palents[i].peBlue = palent[i-start].peBlue;
-		this->palents[i].peGreen = palent[i-start].peGreen;
-	}
-	return 0;
-}
+	cm = this->cm;
+	this->cm = TSXCopyColormapAndFree(display,this->cm);
+	TSXFreeColormap(display,cm);
 
-static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
-	LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD end,LPPALETTEENTRY palent
-) {
-#ifdef HAVE_LIBXXF86DGA
-	HRESULT hres;
-	hres = common_IDirectDrawPalette_SetEntries(this,x,start,end,palent);
-	if (hres != 0) return hres;
+	for (i=0;i<count;i++) {
+		xc.red = palent[i].peRed<<8;
+		xc.blue = palent[i].peBlue<<8;
+		xc.green = palent[i].peGreen<<8;
+		xc.flags = DoRed|DoBlue|DoGreen;
+		xc.pixel = i+start;
+		TSXStoreColor(display,this->cm,&xc);
+		this->palents[start+i].peRed = palent[i].peRed;
+		this->palents[start+i].peBlue = palent[i].peBlue;
+		this->palents[start+i].peGreen = palent[i].peGreen;
+	}
 	TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
 	return 0;
 #else /* defined(HAVE_LIBXXF86DGA) */
@@ -1130,16 +985,6 @@
 	DGA_IDirectDrawPalette_SetEntries
 };
 
-static struct IDirectDrawPalette_VTable xshm_ddpalvt = {
-	(void*)1,
-	IDirectDrawPalette_AddRef,
-	IDirectDrawPalette_Release,
-	(void*)4,
-	IDirectDrawPalette_GetEntries,
-	IDirectDrawPalette_Initialize,
-	common_IDirectDrawPalette_SetEntries
-};
-
 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
 	(void*)1,
 	IDirectDrawPalette_AddRef,
@@ -1147,7 +992,7 @@
 	(void*)4,
 	IDirectDrawPalette_GetEntries,
 	IDirectDrawPalette_Initialize,
-	common_IDirectDrawPalette_SetEntries
+	Xlib_IDirectDrawPalette_SetEntries
 };
 
 /*******************************************************************************
@@ -1189,7 +1034,7 @@
 
 	d2.dwSize	= sizeof(d2);
 	d2.dwFlags	= 0;
-	cb(&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context);
+	cb((void*)&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context);
 	return 0;
 }
 
@@ -1208,8 +1053,8 @@
 /*******************************************************************************
  *				IDirectDraw
  */
-static HRESULT WINAPI DGA_IDirectDraw_CreateSurface(
-	LPDIRECTDRAW this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
+static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
+	LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
 ) {
 #ifdef HAVE_LIBXXF86DGA
 	int	i;
@@ -1288,50 +1133,8 @@
 #endif /* defined(HAVE_LIBXXF86DGA) */
 }
 
-static HRESULT WINAPI XShm_IDirectDraw_CreateSurface(
-	LPDIRECTDRAW this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
-) {
-#ifdef HAVE_LIBXXSHM
-	XImage *img;
-	int shmid;
-	TRACE(ddraw,"(%p)->CreateSurface(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
-	if (TRACE_ON(ddraw)) {
-		fprintf(stderr,"[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
-		_dump_DDSD(lpddsd->dwFlags);
-		fprintf(stderr,"caps ");
-		_dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
-		fprintf(stderr,"]\n");
-	}
-
-	TRACE(ddraw,"using shared XImage for a primary surface\n");
-	*lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
-	this->lpvtbl->fnAddRef(this);
-	(*lpdsf)->ref = 1;
-	(*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xshm_dds3vt;
-	(*lpdsf)->t.xshm.image = img =
-		XShmCreateImage(display, /*FIXME:visual*/0, /*FIXME:depth*/8, ZPixmap,
-						NULL, &(*lpdsf)->t.xshm.shminfo,
-						/*FIXME:width*/640, /*FIXME:height*/480);
-	(*lpdsf)->t.xshm.shminfo.shmid = shmid =
-		shmget(IPC_PRIVATE, img->bytes_per_line*img->height, IPC_CREAT|0777);
-	(*lpdsf)->t.xshm.shminfo.shmaddr = img->data = shmat(shmid, 0, 0);
-	TSXShmAttach(display, &(*lpdsf)->t.xshm.shminfo);
-	/* POOLE FIXME: XShm: this will easily break */
-	(*lpdsf)->s.surface = img->data;
-	/* END FIXME: XShm */
-	(*lpdsf)->s.lpitch = img->bytes_per_line;
-	(*lpdsf)->s.width = img->width;
-	(*lpdsf)->s.height = img->height;
-	(*lpdsf)->s.ddraw = this;
-	(*lpdsf)->s.backbuffer = NULL;
-	return 0;
-#else /* defined(HAVE_LIBXXSHM) */
-	return E_UNEXPECTED;
-#endif /* defined(HAVE_LIBXXSHM) */
-}
-
-static HRESULT WINAPI Xlib_IDirectDraw_CreateSurface(
-	LPDIRECTDRAW this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
+static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
+	LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
 ) {
 	XImage *img;
 	TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
@@ -1360,11 +1163,17 @@
 	} else {
 		TRACE(ddraw,"using standard XImage for a primary surface\n");
 			/* FIXME: !8 bit images */
+		if (!(lpddsd->dwFlags & DDSD_WIDTH))
+			lpddsd->dwWidth	 = this->d.width;
+		if (!(lpddsd->dwFlags & DDSD_HEIGHT))
+			lpddsd->dwHeight = this->d.height;
 		(*lpdsf)->s.surface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,lpddsd->dwHeight*lpddsd->dwWidth);
-		(*lpdsf)->s.width = this->d.width;
-		(*lpdsf)->s.height = this->d.height;
+		(*lpdsf)->s.width	= lpddsd->dwWidth;
+		(*lpdsf)->s.height	= lpddsd->dwHeight;
 	}
 	(*lpdsf)->s.ddraw = this;
+
+	{
 	(*lpdsf)->t.xlib.image = img =
 		TSXCreateImage(	display,
 				DefaultVisualOfScreen(screen),
@@ -1379,8 +1188,8 @@
 		/* FIXME: !8 bit images */
 		);
 		/* END FIXME: Xlib */
+	}
 	(*lpdsf)->s.lpitch = img->bytes_per_line;
-	assert(img);
 	if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
 		LPDIRECTDRAWSURFACE3	back;
 
@@ -1418,16 +1227,16 @@
 	return 0;
 }
 
-static HRESULT WINAPI IDirectDraw_DuplicateSurface(
-	LPDIRECTDRAW this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
+static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
+	LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
 ) {
 	FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
 	*dst = src; /* FIXME */
 	return 0;
 }
 
-static HRESULT WINAPI IDirectDraw_SetCooperativeLevel(
-	LPDIRECTDRAW this,HWND32 hwnd,DWORD cooplevel
+static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
+	LPDIRECTDRAW2 this,HWND32 hwnd,DWORD cooplevel
 ) {
 	int	i;
 	const struct {
@@ -1445,9 +1254,7 @@
 		FE(DDSCL_CREATEDEVICEWINDOW)
 	};
 
-	TRACE(ddraw,"(%p)->(%08lx,%08lx)\n",
-		this,(DWORD)hwnd,cooplevel
-	);
+	TRACE(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
 	if(TRACE_ON(ddraw)){
 	  dbg_decl_str(ddraw, 512);
 	  for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
@@ -1455,7 +1262,7 @@
 	      dsprintf(ddraw, "%s ", flagmap[i].name);
 	  TRACE(ddraw,"	cooperative level %s\n", dbg_str(ddraw));
 	}
-	this->d.mainwindow = hwnd;
+/*	this->d.mainwindow = hwnd;*/
 	return 0;
 }
 
@@ -1493,9 +1300,9 @@
 	 * it works for the library too?
 	 */
 	TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
-/*
-	TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->d.fb_height);
- */
+#ifdef DIABLO_HACK
+	TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
+#endif
 
 #ifdef RESTORE_SIGNALS
 	SIGNAL_InitEmulator();
@@ -1506,44 +1313,6 @@
 #endif /* defined(HAVE_LIBXXF86DGA) */
 }
 
-static HRESULT WINAPI XShm_IDirectDraw_SetDisplayMode(
-	LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
-) {
-#ifdef HAVE_LIBXXSHM
-	int	i,*depths,depcount;
-	char	buf[200];
-
-	TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
-		      this, width, height, depth);
-
-	depths = TSXListDepths(display,DefaultScreen(display),&depcount);
-	for (i=0;i<depcount;i++)
-		if (depths[i]==depth)
-			break;
-	TSXFree(depths);
-	if (i==depcount) {/* not found */
-		sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
-		MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
-		return DDERR_UNSUPPORTEDMODE;
-	}
-	if (this->d.width < width) {
-		sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld",width,height,depth,width,this->d.width);
-		MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
-		return DDERR_UNSUPPORTEDMODE;
-	}
-	this->d.width	= width;
-	this->d.height	= height;
-	/* adjust fb_height, so we don't overlap */
-	if (this->e.dga.fb_height < height)
-		this->e.dga.fb_height = height;
-	this->d.depth	= depth;
-	/* END FIXME: XShm */
-	return 0;
-#else /* defined(HAVE_LIBXXSHM) */
-	return E_UNEXPECTED;
-#endif /* defined(HAVE_LIBXXSHM) */
-}
-
 static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
 	LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
 ) {
@@ -1581,6 +1350,8 @@
 		0,
 		NULL
 	);
+	SetWindowLong32A(this->e.xlib.window,0,(LONG)this);
+	this->e.xlib.paintable = 1;
 	ShowWindow32(this->e.xlib.window,TRUE);
 	UpdateWindow32(this->e.xlib.window);
 	assert(this->e.xlib.window);
@@ -1594,8 +1365,8 @@
 	return 0;
 }
 
-static HRESULT WINAPI DGA_IDirectDraw_GetCaps(
-	LPDIRECTDRAW this,LPDDCAPS caps1,LPDDCAPS caps2
+static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
+	LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
 ) {
 #ifdef HAVE_LIBXXF86DGA
 	TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
@@ -1613,29 +1384,8 @@
 #endif /* defined(HAVE_LIBXXF86DGA) */
 }
 
-static HRESULT WINAPI XShm_IDirectDraw_GetCaps(
-	LPDIRECTDRAW this,LPDDCAPS caps1,LPDDCAPS caps2
-)  {
-#ifdef HAVE_LIBXXSHM
-	TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
-	/* FIXME: XShm */
-	caps1->dwVidMemTotal = 2048*1024;
-	caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED);		/* we can do anything */
-	caps1->ddsCaps.dwCaps = 0xffffffff;	/* we can do anything */
-	if (caps2) {
-		caps2->dwVidMemTotal = 2048*1024;
-		caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED);		/* we can do anything */
-		caps2->ddsCaps.dwCaps = 0xffffffff;	/* we can do anything */
-	}
-	/* END FIXME: XShm */
-	return 0;
-#else /* defined(HAVE_LIBXXSHM) */
-	return E_UNEXPECTED;
-#endif /* defined(HAVE_LIBXXSHM) */
-}
-
-static HRESULT WINAPI Xlib_IDirectDraw_GetCaps(
-	LPDIRECTDRAW this,LPDDCAPS caps1,LPDDCAPS caps2
+static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
+	LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
 )  {
 	TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
 	/* FIXME: Xlib */
@@ -1651,8 +1401,8 @@
 	return 0;
 }
 
-static HRESULT WINAPI IDirectDraw_CreateClipper(
-	LPDIRECTDRAW this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
+static HRESULT WINAPI IDirectDraw2_CreateClipper(
+	LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
 ) {
 	FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
 		this,x,lpddclip,lpunk
@@ -1663,13 +1413,13 @@
 	return 0;
 }
 
-static HRESULT WINAPI common_IDirectDraw_CreatePalette(
-	LPDIRECTDRAW this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
+static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
+	LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
 ) {
 	*lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
 	if (*lpddpal == NULL) return E_OUTOFMEMORY;
 	(*lpddpal)->ref = 1;
-	(*lpddpal)->ddraw = this;
+	(*lpddpal)->ddraw = (LPDIRECTDRAW)this;
 	(*lpddpal)->installed = 0;
 	if (this->d.depth<=8) {
 		(*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
@@ -1680,43 +1430,32 @@
 	return 0;
 }
 
-static HRESULT WINAPI DGA_IDirectDraw_CreatePalette(
-	LPDIRECTDRAW this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
+static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
+	LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
 ) {
 	HRESULT res;
-	TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",
-		this,x,palent,lpddpal,lpunk
-	);
-	res = common_IDirectDraw_CreatePalette(this,x,palent,lpddpal,lpunk);
+	TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
+	res = common_IDirectDraw2_CreatePalette(this,x,palent,lpddpal,lpunk);
 	if (res != 0) return res;
 	(*lpddpal)->lpvtbl = &dga_ddpalvt;
 	return 0;
 }
 
-static HRESULT WINAPI XShm_IDirectDraw_CreatePalette(
-	LPDIRECTDRAW this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
-) {
-	HRESULT res;
-	TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
-	res = common_IDirectDraw_CreatePalette(this,x,palent,lpddpal,lpunk);
-	if (res != 0) return res;
-	(*lpddpal)->lpvtbl = &xshm_ddpalvt;
-	return 0;
-}
-
-static HRESULT WINAPI Xlib_IDirectDraw_CreatePalette(
-	LPDIRECTDRAW this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
+static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
+	LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
 ) {
 	TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
 	*lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
 	if (*lpddpal == NULL) return E_OUTOFMEMORY;
 	(*lpddpal)->ref = 1;
 	(*lpddpal)->installed = 0;
-	(*lpddpal)->ddraw = this;
+	(*lpddpal)->ddraw = (LPDIRECTDRAW)this;
 	if (this->d.depth<=8) {
 		(*lpddpal)->cm = TSXCreateColormap(display,this->e.xlib.drawable,DefaultVisualOfScreen(screen),AllocAll);
-		TSXInstallColormap(display,(*lpddpal)->cm);
-		TSXSetWindowColormap(display,this->e.xlib.drawable,(*lpddpal)->cm);
+		/* later installed ... 
+		 * TSXInstallColormap(display,(*lpddpal)->cm);
+		 * TSXSetWindowColormap(display,this->e.xlib.drawable,(*lpddpal)->cm);
+		 */
 	} else
 		/* we don't want palettes in hicolor or truecolor */
 		(*lpddpal)->cm = 0;
@@ -1724,7 +1463,7 @@
 	return 0;
 }
 
-static HRESULT WINAPI DGA_IDirectDraw_RestoreDisplayMode(LPDIRECTDRAW this) {
+static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
 #ifdef HAVE_LIBXXF86DGA
 	TRACE(ddraw, "(%p)->()\n",this);
 	Sleep(1000);
@@ -1738,33 +1477,24 @@
 #endif
 }
 
-static HRESULT WINAPI XShm_IDirectDraw_RestoreDisplayMode(LPDIRECTDRAW this) {
-#ifdef HAVE_LIBXXF86DGA
+static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
 	TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
 	Sleep(1000);
 	return 0;
-#else /* defined(HAVE_LIBXXF86DGA) */
-	return E_UNEXPECTED;
-#endif
 }
 
-static HRESULT WINAPI Xlib_IDirectDraw_RestoreDisplayMode(LPDIRECTDRAW this) {
-	TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
-	return 0;
-}
-
-static HRESULT WINAPI IDirectDraw_WaitForVerticalBlank(
-	LPDIRECTDRAW this,DWORD x,HANDLE32 h
+static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
+	LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
 ) {
 	TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
 	return 0;
 }
 
-static ULONG WINAPI IDirectDraw_AddRef(LPDIRECTDRAW this) {
+static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
 	return ++(this->ref);
 }
 
-static ULONG WINAPI DGA_IDirectDraw_Release(LPDIRECTDRAW this) {
+static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
 #ifdef HAVE_LIBXXF86DGA
 	if (!--(this->ref)) {
 		TSXF86DGADirectVideo(display,DefaultScreen(display),0);
@@ -1778,26 +1508,17 @@
 	return this->ref;
 }
 
-static ULONG WINAPI XShm_IDirectDraw_Release(LPDIRECTDRAW this) {
-#ifdef HAVE_LIBXXSHM
+static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
 	if (!--(this->ref)) {
 		HeapFree(GetProcessHeap(),0,this);
 		return 0;
 	}
-#endif /* defined(HAVE_LIBXXSHM) */
+	/* FIXME: destroy window ... */
 	return this->ref;
 }
 
-static ULONG WINAPI Xlib_IDirectDraw_Release(LPDIRECTDRAW this) {
-	if (!--(this->ref)) {
-		HeapFree(GetProcessHeap(),0,this);
-		return 0;
-	}
-	return this->ref;
-}
-
-static HRESULT WINAPI DGA_IDirectDraw_QueryInterface(
-	LPDIRECTDRAW this,REFIID refiid,LPVOID *obj
+static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
+	LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
 ) {
 	char    xrefiid[50];
 
@@ -1809,12 +1530,13 @@
 		return 0;
 	}
 	if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
-		*obj = this;
+		this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
 		this->lpvtbl->fnAddRef(this);
+		*obj = this;
 		return 0;
 	}
 	if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
-		this->lpvtbl = (LPDIRECTDRAW_VTABLE)&dga_dd2vt;
+		this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
 		this->lpvtbl->fnAddRef(this);
 		*obj = this;
 		return 0;
@@ -1824,7 +1546,7 @@
 
 		d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
 		d3d->ref = 1;
-		d3d->ddraw = this;
+		d3d->ddraw = (LPDIRECTDRAW)this;
 		this->lpvtbl->fnAddRef(this);
 		d3d->lpvtbl = &d3dvt;
 		*obj = d3d;
@@ -1835,7 +1557,7 @@
 
 		d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
 		d3d->ref = 1;
-		d3d->ddraw = this;
+		d3d->ddraw = (LPDIRECTDRAW)this;
 		this->lpvtbl->fnAddRef(this);
 		d3d->lpvtbl = &d3d2vt;
 		*obj = d3d;
@@ -1845,57 +1567,8 @@
         return OLE_E_ENUM_NOMORE;
 }
 
-static HRESULT WINAPI XShm_IDirectDraw_QueryInterface(
-	LPDIRECTDRAW this,REFIID refiid,LPVOID *obj
-	) {
-	char    xrefiid[50];
-
-	WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
-	TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
-	if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
-		*obj = this;
-		this->lpvtbl->fnAddRef(this);
-		return 0;
-	}
-	if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
-		*obj = this;
-		this->lpvtbl->fnAddRef(this);
-		return 0;
-	}
-	if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
-		this->lpvtbl = (LPDIRECTDRAW_VTABLE)&xshm_dd2vt;
-		this->lpvtbl->fnAddRef(this);
-		*obj = this;
-		return 0;
-	}
-	if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
-		LPDIRECT3D	d3d;
-
-		d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
-		d3d->ref = 1;
-		d3d->ddraw = this;
-		this->lpvtbl->fnAddRef(this);
-		d3d->lpvtbl = &d3dvt;
-		*obj = d3d;
-		return 0;
-	}
-	if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
-		LPDIRECT3D2	d3d;
-
-		d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
-		d3d->ref = 1;
-		d3d->ddraw = this;
-		this->lpvtbl->fnAddRef(this);
-		d3d->lpvtbl = &d3d2vt;
-		*obj = d3d;
-		return 0;
-	}
-	WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
-	return OLE_E_ENUM_NOMORE;
-}
-
-static HRESULT WINAPI Xlib_IDirectDraw_QueryInterface(
-	LPDIRECTDRAW this,REFIID refiid,LPVOID *obj
+static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
+	LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
 ) {
 	char    xrefiid[50];
 
@@ -1907,12 +1580,13 @@
 		return 0;
 	}
 	if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
-		*obj = this;
+		this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
 		this->lpvtbl->fnAddRef(this);
+		*obj = this;
 		return 0;
 	}
 	if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
-		this->lpvtbl = (LPDIRECTDRAW_VTABLE)&xlib_dd2vt;
+		this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
 		this->lpvtbl->fnAddRef(this);
 		*obj = this;
 		return 0;
@@ -1922,7 +1596,7 @@
 
 		d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
 		d3d->ref = 1;
-		d3d->ddraw = this;
+		d3d->ddraw = (LPDIRECTDRAW)this;
 		this->lpvtbl->fnAddRef(this);
 		d3d->lpvtbl = &d3dvt;
 		*obj = d3d;
@@ -1933,7 +1607,7 @@
 
 		d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
 		d3d->ref = 1;
-		d3d->ddraw = this;
+		d3d->ddraw = (LPDIRECTDRAW)this;
 		this->lpvtbl->fnAddRef(this);
 		d3d->lpvtbl = &d3d2vt;
 		*obj = d3d;
@@ -1943,16 +1617,16 @@
         return OLE_E_ENUM_NOMORE;
 }
 
-static HRESULT WINAPI IDirectDraw_GetVerticalBlankStatus(
-	LPDIRECTDRAW this,BOOL32 *status
+static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
+	LPDIRECTDRAW2 this,BOOL32 *status
 ) {
         TRACE(ddraw,"(%p)->(%p)\n",this,status);
 	*status = TRUE;
 	return 0;
 }
 
-static HRESULT WINAPI IDirectDraw_EnumDisplayModes(
-	LPDIRECTDRAW this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
+static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
+	LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
 ) {
 	DDSURFACEDESC	ddsfd;
 
@@ -1987,8 +1661,8 @@
 	return DD_OK;
 }
 
-static HRESULT WINAPI DGA_IDirectDraw_GetDisplayMode(
-	LPDIRECTDRAW this,LPDDSURFACEDESC lpddsfd
+static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
+	LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
 ) {
 #ifdef HAVE_LIBXXF86DGA
 	TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
@@ -2006,29 +1680,8 @@
 #endif /* defined(HAVE_LIBXXF86DGA) */
 }
 
-static HRESULT WINAPI XShm_IDirectDraw_GetDisplayMode(
-	LPDIRECTDRAW this,LPDDSURFACEDESC lpddsfd
-) {
-#ifdef HAVE_LIBXXSM
-	TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
-	lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
-	lpddsfd->dwHeight = screenHeight;
-	lpddsfd->dwWidth = screenWidth;
-	/* POOLE FIXME: XShm */
-	lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
-	/* END FIXME: XShm */
-	lpddsfd->dwBackBufferCount = 1;
-	lpddsfd->x.dwRefreshRate = 60;
-	lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
-	_getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
-	return DD_OK;
-#else /* defined(HAVE_LIBXXSHM) */
-	return E_UNEXPECTED;
-#endif /* defined(HAVE_LIBXXSHM) */
-}
-
-static HRESULT WINAPI Xlib_IDirectDraw_GetDisplayMode(
-	LPDIRECTDRAW this,LPDDSURFACEDESC lpddsfd
+static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
+	LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
 ) {
 	TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
 	lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
@@ -2044,13 +1697,13 @@
 	return DD_OK;
 }
 
-static HRESULT WINAPI IDirectDraw_FlipToGDISurface(LPDIRECTDRAW this) {
+static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
 	TRACE(ddraw,"(%p)->()\n",this);
 	return DD_OK;
 }
 
-static HRESULT WINAPI IDirectDraw_GetMonitorFrequency(
-	LPDIRECTDRAW this,LPDWORD freq
+static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
+	LPDIRECTDRAW2 this,LPDWORD freq
 ) {
 	FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
 	*freq = 60*100; /* 60 Hz */
@@ -2058,225 +1711,13 @@
 }
 
 /* what can we directly decompress? */
-static HRESULT WINAPI IDirectDraw_GetFourCCCodes(
-	LPDIRECTDRAW this,LPDWORD x,LPDWORD y
+static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
+	LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
 ) {
 	FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
 	return 0;
 }
 
-static struct IDirectDraw_VTable dga_ddvt = {
-	DGA_IDirectDraw_QueryInterface,
-	IDirectDraw_AddRef,
-	DGA_IDirectDraw_Release,
-	(void*)4,
-	IDirectDraw_CreateClipper,
-	DGA_IDirectDraw_CreatePalette,
-	DGA_IDirectDraw_CreateSurface,
-	IDirectDraw_DuplicateSurface,
-	IDirectDraw_EnumDisplayModes,
-	(void*)10,
-	IDirectDraw_FlipToGDISurface,
-	DGA_IDirectDraw_GetCaps,
-	DGA_IDirectDraw_GetDisplayMode,
-	IDirectDraw_GetFourCCCodes,
-	(void*)15,
-	IDirectDraw_GetMonitorFrequency,
-	(void*)17,
-	IDirectDraw_GetVerticalBlankStatus,
-	(void*)19,
-	DGA_IDirectDraw_RestoreDisplayMode,
-	IDirectDraw_SetCooperativeLevel,
-	DGA_IDirectDraw_SetDisplayMode,
-	IDirectDraw_WaitForVerticalBlank,
-};
-
-static struct IDirectDraw_VTable xshm_ddvt = {
-	XShm_IDirectDraw_QueryInterface,
-	IDirectDraw_AddRef,
-	XShm_IDirectDraw_Release,
-	(void*)4,
-	IDirectDraw_CreateClipper,
-	XShm_IDirectDraw_CreatePalette,
-	XShm_IDirectDraw_CreateSurface,
-	IDirectDraw_DuplicateSurface,
-	IDirectDraw_EnumDisplayModes,
-	(void*)10,
-	IDirectDraw_FlipToGDISurface,
-	XShm_IDirectDraw_GetCaps,
-	XShm_IDirectDraw_GetDisplayMode,
-	IDirectDraw_GetFourCCCodes,
-	(void*)15,
-	IDirectDraw_GetMonitorFrequency,
-	(void*)17,
-	IDirectDraw_GetVerticalBlankStatus,
-	(void*)19,
-	XShm_IDirectDraw_RestoreDisplayMode,
-	IDirectDraw_SetCooperativeLevel,
-	XShm_IDirectDraw_SetDisplayMode,
-	IDirectDraw_WaitForVerticalBlank,
-};
-
-static struct IDirectDraw_VTable xlib_ddvt = {
-	Xlib_IDirectDraw_QueryInterface,
-	IDirectDraw_AddRef,
-	Xlib_IDirectDraw_Release,
-	(void*)4,
-	IDirectDraw_CreateClipper,
-	Xlib_IDirectDraw_CreatePalette,
-	Xlib_IDirectDraw_CreateSurface,
-	IDirectDraw_DuplicateSurface,
-	IDirectDraw_EnumDisplayModes,
-	(void*)10,
-	IDirectDraw_FlipToGDISurface,
-	Xlib_IDirectDraw_GetCaps,
-	Xlib_IDirectDraw_GetDisplayMode,
-	IDirectDraw_GetFourCCCodes,
-	(void*)15,
-	IDirectDraw_GetMonitorFrequency,
-	(void*)17,
-	IDirectDraw_GetVerticalBlankStatus,
-	(void*)19,
-	Xlib_IDirectDraw_RestoreDisplayMode,
-	IDirectDraw_SetCooperativeLevel,
-	Xlib_IDirectDraw_SetDisplayMode,
-	IDirectDraw_WaitForVerticalBlank,
-};
-
-/*****************************************************************************
- * 	IDirectDraw2
- *
- */
-static HRESULT WINAPI IDirectDraw2_CreateClipper(
-	LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
-) {
-	return IDirectDraw_CreateClipper((LPDIRECTDRAW)this,x,lpddclip,lpunk);
-}
-
-static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
-	LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
-) {
-	return DGA_IDirectDraw_CreateSurface((LPDIRECTDRAW)this,lpddsd,(LPDIRECTDRAWSURFACE*)lpdsf,lpunk);
-}
-
-static HRESULT WINAPI XShm_IDirectDraw2_CreateSurface(
-	LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
-) {
-	return XShm_IDirectDraw_CreateSurface((LPDIRECTDRAW)this,lpddsd,(LPDIRECTDRAWSURFACE*)lpdsf,lpunk);
-}
-
-static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
-	LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
-) {
-	return Xlib_IDirectDraw_CreateSurface((LPDIRECTDRAW)this,lpddsd,(LPDIRECTDRAWSURFACE*)lpdsf,lpunk);
-}
-
-static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
-	LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
-) {
-	return DGA_IDirectDraw_QueryInterface((LPDIRECTDRAW)this,refiid,obj);
-}
-
-static HRESULT WINAPI XShm_IDirectDraw2_QueryInterface(
-	LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
-) {
-	return XShm_IDirectDraw_QueryInterface((LPDIRECTDRAW)this,refiid,obj);
-}
-
-static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
-	LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
-) {
-	return Xlib_IDirectDraw_QueryInterface((LPDIRECTDRAW)this,refiid,obj);
-}
-
-static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
-	return IDirectDraw_AddRef((LPDIRECTDRAW)this);
-}
-
-static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
-	return DGA_IDirectDraw_Release((LPDIRECTDRAW)this);
-}
-
-static ULONG WINAPI XShm_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
-	return XShm_IDirectDraw_Release((LPDIRECTDRAW)this);
-}
-
-static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
-	return Xlib_IDirectDraw_Release((LPDIRECTDRAW)this);
-}
-
-static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
-	LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
-)  {
-	return DGA_IDirectDraw_GetCaps((LPDIRECTDRAW)this,caps1,caps2);
-}
-
-static HRESULT WINAPI XShm_IDirectDraw2_GetCaps(
-	LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
-)  {
-	return XShm_IDirectDraw_GetCaps((LPDIRECTDRAW)this,caps1,caps2);
-}
-
-static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
-	LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
-)  {
-	return Xlib_IDirectDraw_GetCaps((LPDIRECTDRAW)this,caps1,caps2);
-}
-
-static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
-	LPDIRECTDRAW2 this,HWND32 hwnd,DWORD x
-) {
-	return IDirectDraw_SetCooperativeLevel((LPDIRECTDRAW)this,hwnd,x);
-}
-
-static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
-	LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
-) {
-	return DGA_IDirectDraw_CreatePalette((LPDIRECTDRAW)this,x,palent,lpddpal,lpunk);
-}
-
-static HRESULT WINAPI XShm_IDirectDraw2_CreatePalette(
-	LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
-) {
-	return XShm_IDirectDraw_CreatePalette((LPDIRECTDRAW)this,x,palent,lpddpal,lpunk);
-}
-
-static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
-	LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
-) {
-	return Xlib_IDirectDraw_CreatePalette((LPDIRECTDRAW)this,x,palent,lpddpal,lpunk);
-}
-
-static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
-	LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
-) {
-	return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
-}
-
-static HRESULT WINAPI XShm_IDirectDraw2_SetDisplayMode(
-	LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
-) {
-	return XShm_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
-}
-
-static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
-	LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
-) {
-	return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
-}
-
-static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
-	return DGA_IDirectDraw_RestoreDisplayMode((LPDIRECTDRAW)this);
-}
-
-static HRESULT WINAPI XShm_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
-	return XShm_IDirectDraw_RestoreDisplayMode((LPDIRECTDRAW)this);
-}
-
-static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
-	return Xlib_IDirectDraw_RestoreDisplayMode((LPDIRECTDRAW)this);
-}
-
 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
 	LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
 ) {
@@ -2284,28 +1725,80 @@
 	return 0;
 }
 
-static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
-	LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
+/* Note: Hack so we can reuse the old functions without compiler warnings */
+#ifdef __GNUC__
+# define XCAST(fun)	(typeof(dga_ddvt.fn##fun))
+#else
+# define XCAST(fun)	(void*)
+#endif
+
+static struct IDirectDraw_VTable dga_ddvt = {
+	XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
+	XCAST(AddRef)IDirectDraw2_AddRef,
+	XCAST(Release)DGA_IDirectDraw2_Release,
+	XCAST(Compact)4,
+	XCAST(CreateClipper)IDirectDraw2_CreateClipper,
+	XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
+	XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
+	XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
+	XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
+	XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
+	XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
+	XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
+	XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
+	XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
+	XCAST(GetGDISurface)15,
+	XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
+	XCAST(GetScanLine)17,
+	XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
+	XCAST(Initialize)19,
+	XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
+	XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
+	DGA_IDirectDraw_SetDisplayMode,
+	XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
+};
+
+static struct IDirectDraw_VTable xlib_ddvt = {
+	XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
+	XCAST(AddRef)IDirectDraw2_AddRef,
+	XCAST(Release)Xlib_IDirectDraw2_Release,
+	XCAST(Compact)4,
+	XCAST(CreateClipper)IDirectDraw2_CreateClipper,
+	XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
+	XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
+	XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
+	XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
+	XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
+	XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
+	XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
+	XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
+	XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
+	XCAST(GetGDISurface)15,
+	XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
+	XCAST(GetScanLine)17,
+	XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
+	XCAST(Initialize)19,
+	XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
+	XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
+	Xlib_IDirectDraw_SetDisplayMode,
+	XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
+};
+
+/*****************************************************************************
+ * 	IDirectDraw2
+ *
+ */
+
+static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
+	LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
 ) {
-	return IDirectDraw_EnumDisplayModes((LPDIRECTDRAW)this,dwFlags,lpddsfd,context,modescb);
+	return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
 }
 
-static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
-	LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
+static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
+	LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
 ) {
-	return DGA_IDirectDraw_GetDisplayMode((LPDIRECTDRAW)this,lpddsfd);
-}
-
-static HRESULT WINAPI XShm_IDirectDraw2_GetDisplayMode(
-	LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
-) {
-	return XShm_IDirectDraw_GetDisplayMode((LPDIRECTDRAW)this,lpddsfd);
-}
-
-static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
-	LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
-) {
-	return Xlib_IDirectDraw_GetDisplayMode((LPDIRECTDRAW)this,lpddsfd);
+	return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
 }
 
 static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
@@ -2330,24 +1823,6 @@
 	return 0;
 }
 
-static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
-	LPDIRECTDRAW2 this,LPDWORD freq
-) {
-	return IDirectDraw_GetMonitorFrequency((LPDIRECTDRAW)this,freq);
-}
-
-static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
-	LPDIRECTDRAW2 this,BOOL32 *status
-) {
-	return IDirectDraw_GetVerticalBlankStatus((LPDIRECTDRAW)this,status);
-}
-
-static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
-	LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
-) {
-	return IDirectDraw_WaitForVerticalBlank((LPDIRECTDRAW)this,x,h);
-}
-
 static IDirectDraw2_VTable dga_dd2vt = {
 	DGA_IDirectDraw2_QueryInterface,
 	IDirectDraw2_AddRef,
@@ -2359,10 +1834,10 @@
 	(void*)8,
 	IDirectDraw2_EnumDisplayModes,
 	IDirectDraw2_EnumSurfaces,
-	(void*)11,
+	IDirectDraw2_FlipToGDISurface,
 	DGA_IDirectDraw2_GetCaps,
 	DGA_IDirectDraw2_GetDisplayMode,
-	(void*)14,
+	IDirectDraw2_GetFourCCCodes,
 	(void*)15,
 	IDirectDraw2_GetMonitorFrequency,
 	(void*)17,
@@ -2375,33 +1850,6 @@
 	DGA_IDirectDraw2_GetAvailableVidMem
 };
 
-static IDirectDraw2_VTable xshm_dd2vt = {
-	XShm_IDirectDraw2_QueryInterface,
-	IDirectDraw2_AddRef,
-	XShm_IDirectDraw2_Release,
-	(void*)4,
-	IDirectDraw2_CreateClipper,
-	XShm_IDirectDraw2_CreatePalette,
-	XShm_IDirectDraw2_CreateSurface,
-	(void*)8,
-	IDirectDraw2_EnumDisplayModes,
-	IDirectDraw2_EnumSurfaces,
-	(void*)11,
-	XShm_IDirectDraw2_GetCaps,
-	XShm_IDirectDraw2_GetDisplayMode,
-	(void*)14,
-	(void*)15,
-	IDirectDraw2_GetMonitorFrequency,
-	(void*)17,
-	IDirectDraw2_GetVerticalBlankStatus,
-	(void*)19,
-	XShm_IDirectDraw2_RestoreDisplayMode,
-	IDirectDraw2_SetCooperativeLevel,
-	XShm_IDirectDraw2_SetDisplayMode,
-	IDirectDraw2_WaitForVerticalBlank,
-	Xlib_IDirectDraw2_GetAvailableVidMem
-};
-
 static struct IDirectDraw2_VTable xlib_dd2vt = {
 	Xlib_IDirectDraw2_QueryInterface,
 	IDirectDraw2_AddRef,
@@ -2413,10 +1861,10 @@
 	(void*)8,
 	IDirectDraw2_EnumDisplayModes,
 	IDirectDraw2_EnumSurfaces,
-	(void*)11,
+	IDirectDraw2_FlipToGDISurface,
 	Xlib_IDirectDraw2_GetCaps,
 	Xlib_IDirectDraw2_GetDisplayMode,
-	(void*)14,
+	IDirectDraw2_GetFourCCCodes,
 	(void*)15,
 	IDirectDraw2_GetMonitorFrequency,
 	(void*)17,
@@ -2468,7 +1916,11 @@
 	TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
 	TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
 	(*lplpDD)->e.dga.fb_height = screenHeight;
+#ifdef DIABLO_HACK
+	(*lplpDD)->e.dga.vpmask = 1;
+#else
 	(*lplpDD)->e.dga.vpmask = 0;
+#endif
 
 	/* just assume the default depth is the DGA depth too */
 	(*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
@@ -2481,38 +1933,28 @@
 #endif /* defined(HAVE_LIBXXF86DGA) */
 }
 
-HRESULT WINAPI XShm_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
-#ifdef HAVE_LIBXXSHM
-	if (!DDRAW_XShm_Available()) {
-		fprintf(stderr,"No XShm detected.\n");
-		return DDERR_GENERIC;
-	}
-	*lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
-	(*lplpDD)->lpvtbl = &xshm_ddvt;
-	(*lplpDD)->ref = 1;
-	(*lplpDD)->e.xshm.drawable = DefaultRootWindow(display); /* FIXME: make a window */
-	(*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
-	(*lplpDD)->d.height = screenHeight;
-	(*lplpDD)->d.width = screenWidth;
-	return 0;
-#else /* defined(HAVE_LIBXXSHM) */
-	return DDERR_INVALIDDIRECTDRAWGUID;
-#endif /* defined(HAVE_LIBXXSHM) */
-}
 LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam) {
 	LRESULT	ret;
 	/*FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
+	if (msg==WM_PAINT){
+		LPDIRECTDRAW ddraw = (LPDIRECTDRAW)GetWindowLong32A(hwnd,0);
+
+		if (ddraw)
+			ddraw->e.xlib.paintable = 1;
+	}
 	ret = DefWindowProc32A(hwnd,msg,wParam,lParam);
 	return ret;
 }
 
 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
 	WNDCLASS32A	wc;
+	int		have_xshm = 0;
 
 	*lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
 	(*lplpDD)->lpvtbl = &xlib_ddvt;
 	(*lplpDD)->ref = 1;
 	(*lplpDD)->e.xlib.drawable = 0; /* in SetDisplayMode */
+	(*lplpDD)->e.xlib.use_xshm = have_xshm;
 	wc.style	= CS_GLOBALCLASS;
 	wc.lpfnWndProc	= Xlib_DDWndProc;
 	wc.cbClsExtra	= 0;
@@ -2549,16 +1991,12 @@
 		 * supported one */
 		if (DDRAW_DGA_Available())
 			lpGUID = &DGA_DirectDraw_GUID;
-		else if (DDRAW_XShm_Available())
-			lpGUID = &XSHM_DirectDraw_GUID;
 		else
 			lpGUID = &XLIB_DirectDraw_GUID;
 	}
 
 	if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
 		return DGA_DirectDrawCreate(lplpDD, pUnkOuter);
-	else if (!memcmp(lpGUID, &XSHM_DirectDraw_GUID, sizeof(GUID)))
-		return XShm_DirectDrawCreate(lplpDD, pUnkOuter);
 	else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
 		return Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
 
diff --git a/graphics/painting.c b/graphics/painting.c
index 6797fcc..57b3316 100644
--- a/graphics/painting.c
+++ b/graphics/painting.c
@@ -755,8 +755,8 @@
 /**********************************************************************
  *          PolyPolyline32  (GDI32.272)
  */
-BOOL32 WINAPI PolyPolyline32( HDC32 hdc, LPPOINT32 pt, LPINT32 counts,
-                             UINT32 polylines )
+BOOL32 WINAPI PolyPolyline32( HDC32 hdc, LPPOINT32 pt, LPDWORD counts,
+                             DWORD polylines )
 {
     DC * dc = DC_GetDCPtr( hdc );
 
diff --git a/graphics/psdrv/driver.c b/graphics/psdrv/driver.c
index ead31bb..ee62d63 100644
--- a/graphics/psdrv/driver.c
+++ b/graphics/psdrv/driver.c
@@ -44,8 +44,10 @@
 	}
 	if(page) {
 	    dm1->dmPublic.dmPaperSize = dm2->dmPublic.dmPaperSize;
-	    dm1->dmPublic.dmPaperWidth = page->PaperDimension->x * 25.4 / 72.0;
-	    dm1->dmPublic.dmPaperLength = page->PaperDimension->y * 25.4 / 72.0;
+	    dm1->dmPublic.dmPaperWidth = page->PaperDimension->x * 
+								254.0 / 72.0;
+	    dm1->dmPublic.dmPaperLength = page->PaperDimension->y *
+								254.0 / 72.0;
 	    TRACE(psdrv, "Changing page to %s %d x %d\n", page->FullName,
 		     dm1->dmPublic.dmPaperWidth, dm1->dmPublic.dmPaperLength );
 	} else {
diff --git a/graphics/psdrv/init.c b/graphics/psdrv/init.c
index 3195200..6a62a5a 100644
--- a/graphics/psdrv/init.c
+++ b/graphics/psdrv/init.c
@@ -169,6 +169,12 @@
 
 HANDLE32 PSDRV_Heap = 0;
 
+static HANDLE32 PSDRV_DefaultFont = 0;
+static LOGFONT32A DefaultLogFont = {
+    100, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, 0, 0,
+    DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, ""
+};
+
 /*********************************************************************
  *	     PSDRV_Init
  *
@@ -180,6 +186,7 @@
     TRACE(psdrv, "\n");
     PSDRV_Heap = HeapCreate(0, 0x10000, 0);
     PSDRV_GetFontMetrics();
+    PSDRV_DefaultFont = CreateFontIndirect32A(&DefaultLogFont);
     return DRIVER_RegisterDriver( "WINEPS", &PSDRV_Funcs );
 }
 
@@ -225,11 +232,11 @@
     memcpy(devCaps, &PSDRV_DevCaps, sizeof(PSDRV_DevCaps));
 
     if(physDev->Devmode->dmPublic.dmOrientation == DMORIENT_PORTRAIT) {
-        devCaps->horzSize = physDev->Devmode->dmPublic.dmPaperWidth;
-	devCaps->vertSize = physDev->Devmode->dmPublic.dmPaperLength;
+        devCaps->horzSize = physDev->Devmode->dmPublic.dmPaperWidth / 10;
+	devCaps->vertSize = physDev->Devmode->dmPublic.dmPaperLength / 10;
     } else {
-        devCaps->horzSize = physDev->Devmode->dmPublic.dmPaperLength;
-	devCaps->vertSize = physDev->Devmode->dmPublic.dmPaperWidth;
+        devCaps->horzSize = physDev->Devmode->dmPublic.dmPaperLength / 10;
+	devCaps->vertSize = physDev->Devmode->dmPublic.dmPaperWidth / 10;
     }
 
     devCaps->horzRes = physDev->pi->ppd->DefaultResolution * 
@@ -252,6 +259,7 @@
     dc->w.hVisRgn = CreateRectRgn32(0, 0, dc->w.devCaps->horzRes,
     			    dc->w.devCaps->vertRes);
     
+    dc->w.hFont = PSDRV_DefaultFont;
     physDev->job.output = HEAP_strdupA( PSDRV_Heap, 0, output );
     physDev->job.hJob = 0;
     return TRUE;
diff --git a/graphics/x11drv/graphics.c b/graphics/x11drv/graphics.c
index ef1cf1c..3e5f189 100644
--- a/graphics/x11drv/graphics.c
+++ b/graphics/x11drv/graphics.c
@@ -753,7 +753,7 @@
  *          X11DRV_PolyPolyline
  */
 BOOL32 
-X11DRV_PolyPolyline( DC *dc, LPPOINT32 pt, LPINT32 counts, UINT32 polylines )
+X11DRV_PolyPolyline( DC *dc, LPPOINT32 pt, LPDWORD counts, DWORD polylines )
 {
     if (DC_SetupGCForPen ( dc ))
     {
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index d0a7ef1..8fdcc88 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -218,7 +218,7 @@
 305 stub ENGINEGETGLYPHBMP
 306 stub ENGINEMAKEFONTDIR
 307 pascal16 GetCharABCWidths(word word word ptr) GetCharABCWidths16
-308 pascal   GetOutlineTextMetrics(word word ptr) GetOutlineTextMetrics
+308 pascal   GetOutlineTextMetrics(word word ptr) GetOutlineTextMetrics16
 309 pascal   GetGlyphOutline(word word word ptr long ptr ptr) GetGlyphOutline16
 310 pascal16 CreateScalableFontResource(word str str str) CreateScalableFontResource16
 311 stub GetFontData
diff --git a/if1632/keyboard.spec b/if1632/keyboard.spec
index 354c5af..50e9960 100644
--- a/if1632/keyboard.spec
+++ b/if1632/keyboard.spec
@@ -8,7 +8,7 @@
 5   pascal16 AnsiToOem(str ptr) AnsiToOem16
 6   pascal16 OemToAnsi(str ptr) OemToAnsi16
 7   return   SetSpeed 2 65535
-#100	pascal	ScreenSwitchEnable
+100	pascal	ScreenSwitchEnable(word) ScreenSwitchEnable
 #126	pascal	GetTableSeg
 #127	pascal	NewTable
 128 pascal   OemKeyScan(word) OemKeyScan
diff --git a/if1632/relay.c b/if1632/relay.c
index ca9f6bb..2d5e33e 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -236,7 +236,7 @@
     MSG("No handler for Win16 routine %s (called from %04x:%04x)\n",
             BUILTIN_GetEntryPoint16(frame->entry_cs,frame->entry_ip,&ordinal),
             frame->cs, frame->ip );
-    TASK_KillCurrentTask(1);
+    ExitProcess(1);
 }
 
 
diff --git a/if1632/user.spec b/if1632/user.spec
index 299977b..3c925a42 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -368,7 +368,7 @@
 398 pascal16 GetClassInfoEx(word segstr ptr) GetClassInfoEx16
 399 stub ChildWindowFromPointEx
 400 stub FinalUserInit
-402 pascal16 GetPriorityClipboardFormat(word ptr s_word) GetPriorityClipboardFormat16
+402 pascal16 GetPriorityClipboardFormat(ptr s_word) GetPriorityClipboardFormat16
 403 pascal16 UnregisterClass(segstr word) UnregisterClass16
 404 pascal16 GetClassInfo(word segstr ptr) GetClassInfo16
 406 pascal16 CreateCursor(word word word word word ptr ptr) CreateCursor16
diff --git a/include/authors.h b/include/authors.h
new file mode 100644
index 0000000..2cfc70b
--- /dev/null
+++ b/include/authors.h
@@ -0,0 +1,147 @@
+#ifndef __WINE_AUTHORS_H
+#define __WINE_AUTHORS_H
+
+static const char * const SHELL_People[] =
+{
+    "Bob Amstadt",
+    "Dag Asheim",
+    "Martin Ayotte",
+    "Karl Backström",
+    "Peter Bajusz",
+    "Marcel Baur",
+    "Georg Beyerle",
+    "Ross Biro",
+    "Martin Boehme",
+    "Uwe Bonnes",
+    "Erik Bos",
+    "Fons Botman",
+    "John Brezak",
+    "Andrew Bulhak",
+    "John Burton",
+    "Niels de Carpentier",
+    "Gordon Chaffee",
+    "Jimen Ching",
+    "Pascal Cuoq",
+    "David A. Cuthbert",
+    "Huw D. M. Davies",
+    "Roman Dolejsi",
+    "Frans van Dorsselaer",
+    "Chris Faherty",
+    "Carsten Fallesen",
+    "Paul Falstad",
+    "David Faure",
+    "Claus Fischer",
+    "Olaf Flebbe",
+    "Chad Fraleigh",
+    "Matthew Francis",
+    "Peter Galbavy",
+    "Ramon Garcia",
+    "Matthew Ghio",
+    "Jody Goldberg",
+    "Hans de Graaff",
+    "Charles M. Hannum",
+    "Adrian Harvey",
+    "John Harvey",
+    "Bill Hawes",
+    "Cameron Heide",
+    "Jochen Hoenicke",
+    "Onno Hovers",
+    "Jeffrey Hsu",
+    "Miguel de Icaza",
+    "Jukka Iivonen",
+    "Lee Jaekil",
+    "Alexandre Julliard",
+    "Bang Jun-Young",
+    "Pavel Kankovsky",
+    "Jochen Karrer",
+    "Andreas Kirschbaum",
+    "Rein Klazes",
+    "Albrecht Kleine",
+    "Eric Kohl",
+    "Jon Konrath",
+    "Alex Korobka",
+    "Greg Kreider",
+    "Anand Kumria",
+    "Ove Kåven",
+    "Scott A. Laird",
+    "David Lee Lambert",
+    "Andrew Lewycky",
+    "Per Lindström",
+    "Martin von Loewis",
+    "Michiel van Loon",
+    "Kenneth MacDonald",
+    "Peter MacDonald",
+    "William Magro",
+    "Juergen Marquardt",
+    "Ricardo Massaro",
+    "Marcus Meissner",
+    "Graham Menhennitt",
+    "David Metcalfe",
+    "Bruce Milner",
+    "Steffen Moeller",
+    "Andreas Mohr",
+    "James Moody",
+    "Philippe De Muyter",
+    "Itai Nahshon",
+    "Kristian Nielsen",
+    "Henrik Olsen",
+    "Michael Patra",
+    "Dimitrie O. Paun",
+    "Jim Peterson",
+    "Robert Pouliot",
+    "Keith Reynolds",
+    "Slaven Rezic",
+    "John Richardson",
+    "Rick Richardson",
+    "Doug Ridgway",
+    "Bernhard Rosenkraenzer",
+    "Johannes Ruscheinski",
+    "Thomas Sandford",
+    "Constantine Sapuntzakis",
+    "Pablo Saratxaga",
+    "Daniel Schepler",
+    "Peter Schlaile",
+    "Ulrich Schmid",
+    "Bernd Schmidt",
+    "Juergen Schmied",
+    "Ingo Schneider",
+    "Victor Schneider",
+    "Yngvi Sigurjonsson",
+    "Stephen Simmons",
+    "Rick Sladkey",
+    "William Smith",
+    "Dominik Strasser",
+    "Vadim Strizhevsky",
+    "Bertho Stultiens",
+    "Erik Svendsen",
+    "Tristan Tarrant",
+    "Andrew Taylor",
+    "Duncan C Thomson",
+    "Goran Thyni",
+    "Jimmy Tirtawangsa",
+    "Jon Tombs",
+    "Linus Torvalds",
+    "Gregory Trubetskoy",
+    "Petri Tuomola",
+    "Michael Veksler",
+    "Sven Verdoolaege",
+    "Ronan Waide",
+    "Eric Warnke",
+    "Manfred Weichel",
+    "Ulrich Weigand",
+    "Morten Welinder",
+    "Len White",
+    "Lawson Whitney",
+    "Jan Willamowius",
+    "Carl Williams",
+    "Karl Guenter Wuensch",
+    "Eric Youngdale",
+    "James Youngman",
+    "Nikita V. Youshchenko",
+    "Mikolaj Zalewski",
+    "John Zero",
+    "Luiz Otavio L. Zorzella",
+    NULL
+};
+
+#endif  /* __WINE_AUTHORS_H */
diff --git a/include/commctrl.h b/include/commctrl.h
index 04f29ff..3284c98 100644
--- a/include/commctrl.h
+++ b/include/commctrl.h
@@ -55,14 +55,64 @@
 #define CCM_FIRST            0x2000
 
 #define CCM_SETBKCOLOR       (CCM_FIRST+1)     /* lParam = bkColor */
-
+#define CCM_SETCOLORSCHEME   (CCM_FIRST+2)
+#define CCM_GETCOLORSCHEME   (CCM_FIRST+3)
+#define CCM_GETDROPTARGET    (CCM_FIRST+4)
 #define CCM_SETUNICODEFORMAT (CCM_FIRST+5)
 #define CCM_GETUNICODEFORMAT (CCM_FIRST+6)
 
 
-/* common notification codes */
-#define NM_FIRST             (0U-0U)
-#define NM_LAST              (0U-99U)
+/* common notification codes (WM_NOTIFY)*/
+#define NM_FIRST                (0U-  0U)       // generic to all controls
+#define NM_LAST                 (0U- 99U)
+
+#define LVN_FIRST               (0U-100U)       // listview
+#define LVN_LAST                (0U-199U)
+
+#define HDN_FIRST               (0U-300U)       // header
+#define HDN_LAST                (0U-399U)
+
+#define TVN_FIRST               (0U-400U)       // treeview
+#define TVN_LAST                (0U-499U)
+
+#define TTN_FIRST               (0U-520U)       // tooltips
+#define TTN_LAST                (0U-549U)
+
+#define TCN_FIRST               (0U-550U)       // tab control
+#define TCN_LAST                (0U-580U)
+
+// Shell reserved               (0U-580U) -  (0U-589U)
+
+#define CDN_FIRST               (0U-601U)       // common dialog (new)
+#define CDN_LAST                (0U-699U)
+
+#define TBN_FIRST               (0U-700U)       // toolbar
+#define TBN_LAST                (0U-720U)
+
+#define UDN_FIRST               (0U-721)        // updown
+#define UDN_LAST                (0U-740)
+
+#define MCN_FIRST               (0U-750U)       // monthcal
+#define MCN_LAST                (0U-759U)
+
+#define DTN_FIRST               (0U-760U)       // datetimepick
+#define DTN_LAST                (0U-799U)
+
+#define CBEN_FIRST              (0U-800U)       // combo box ex
+#define CBEN_LAST               (0U-830U)
+
+#define RBN_FIRST               (0U-831U)       // rebar
+#define RBN_LAST                (0U-859U)
+
+#define IPN_FIRST               (0U-860U)       // internet address
+#define IPN_LAST                (0U-879U)       // internet address
+
+#define SBN_FIRST               (0U-880U)       // status bar
+#define SBN_LAST                (0U-899U)
+
+#define PGN_FIRST               (0U-900U)       // Pager Control
+#define PGN_LAST                (0U-950U)
+
 
 #define NM_OUTOFMEMORY       (NM_FIRST-1)
 #define NM_CLICK             (NM_FIRST-2)
@@ -81,6 +131,66 @@
 #define NM_CHAR              (NM_FIRST-18)
 #define NM_TOOLTIPSCREATED   (NM_FIRST-19)
 
+#define HDN_ITEMCHANGINGA       (HDN_FIRST-0)
+#define HDN_ITEMCHANGINGW       (HDN_FIRST-20)
+#define HDN_ITEMCHANGEDA        (HDN_FIRST-1)
+#define HDN_ITEMCHANGEDW        (HDN_FIRST-21)
+#define HDN_ITEMCLICKA          (HDN_FIRST-2)
+#define HDN_ITEMCLICKW          (HDN_FIRST-22)
+#define HDN_ITEMDBLCLICKA       (HDN_FIRST-3)
+#define HDN_ITEMDBLCLICKW       (HDN_FIRST-23)
+#define HDN_DIVIDERDBLCLICKA    (HDN_FIRST-5)
+#define HDN_DIVIDERDBLCLICKW    (HDN_FIRST-25)
+#define HDN_BEGINTRACKA         (HDN_FIRST-6)
+#define HDN_BEGINTRACKW         (HDN_FIRST-26)
+#define HDN_ENDTRACKA           (HDN_FIRST-7)
+#define HDN_ENDTRACKW           (HDN_FIRST-27)
+#define HDN_TRACKA              (HDN_FIRST-8)
+#define HDN_TRACKW              (HDN_FIRST-28)
+#define HDN_GETDISPINFOA        (HDN_FIRST-9)
+#define HDN_GETDISPINFOW        (HDN_FIRST-29)
+#define HDN_BEGINDRAG           (HDN_FIRST-10)
+#define HDN_ENDDRAG             (HDN_FIRST-11)
+
+
+#define HDN_ITEMCHANGING         HDN_ITEMCHANGINGA
+#define HDN_ITEMCHANGED          HDN_ITEMCHANGEDA
+#define HDN_ITEMCLICK            HDN_ITEMCLICKA
+#define HDN_ITEMDBLCLICK         HDN_ITEMDBLCLICKA
+#define HDN_DIVIDERDBLCLICK      HDN_DIVIDERDBLCLICKA
+#define HDN_BEGINTRACK           HDN_BEGINTRACKA
+#define HDN_ENDTRACK             HDN_ENDTRACKA
+#define HDN_TRACK                HDN_TRACKA
+#define HDN_GETDISPINFO          HDN_GETDISPINFOA
+
+#define LVN_ITEMCHANGING        (LVN_FIRST-0)
+#define LVN_ITEMCHANGED         (LVN_FIRST-1)
+#define LVN_INSERTITEM          (LVN_FIRST-2)
+#define LVN_DELETEITEM          (LVN_FIRST-3)
+#define LVN_DELETEALLITEMS      (LVN_FIRST-4)
+#define LVN_BEGINLABELEDITA     (LVN_FIRST-5)
+#define LVN_BEGINLABELEDITW     (LVN_FIRST-75)
+#define LVN_ENDLABELEDITA       (LVN_FIRST-6)
+#define LVN_ENDLABELEDITW       (LVN_FIRST-76)
+#define LVN_COLUMNCLICK         (LVN_FIRST-8)
+#define LVN_BEGINDRAG           (LVN_FIRST-9)
+#define LVN_BEGINRDRAG          (LVN_FIRST-11)
+#define LVN_ODCACHEHINT         (LVN_FIRST-13)
+#define LVN_ODFINDITEMA         (LVN_FIRST-52)
+#define LVN_ODFINDITEMW         (LVN_FIRST-79)
+#define LVN_ITEMACTIVATE        (LVN_FIRST-14)
+#define LVN_ODSTATECHANGED      (LVN_FIRST-15)
+#define LVN_HOTTRACK            (LVN_FIRST-21)
+#define LVN_GETDISPINFOA        (LVN_FIRST-50)
+#define LVN_GETDISPINFOW        (LVN_FIRST-77)
+#define LVN_SETDISPINFOA        (LVN_FIRST-51)
+#define LVN_SETDISPINFOW        (LVN_FIRST-78)
+
+#define LVN_ODFINDITEM          LVN_ODFINDITEMA
+#define LVN_BEGINLABELEDIT      LVN_BEGINLABELEDITA
+#define LVN_ENDLABELEDIT        LVN_ENDLABELEDITA
+#define LVN_GETDISPINFO         LVN_GETDISPINFOA
+#define LVN_SETDISPINFO         LVN_SETDISPINFOA
 
 /* callback constants */
 #define LPSTR_TEXTCALLBACK32A    ((LPSTR)-1L)
@@ -952,6 +1062,103 @@
 #define REBARCLASSNAME32W       L"ReBarWindow32"
 #define REBARCLASSNAME  WINELIB_NAME_AW(REBARCLASSNAME)
 
+#define RBIM_IMAGELIST          0x00000001
+
+#define RBBIM_STYLE             0x00000001
+#define RBBIM_COLORS            0x00000002
+#define RBBIM_TEXT              0x00000004
+#define RBBIM_IMAGE             0x00000008
+#define RBBIM_CHILD             0x00000010
+#define RBBIM_CHILDSIZE         0x00000020
+#define RBBIM_SIZE              0x00000040
+#define RBBIM_BACKGROUND        0x00000080
+#define RBBIM_ID                0x00000100
+#define RBBIM_IDEALSIZE         0x00000200
+#define RBBIM_LPARAM            0x00000400
+#define RBBIM_HEADERSIZE        0x00000800
+
+
+#define RB_INSERTBAND32A        (WM_USER+1)
+#define RB_INSERTBAND32W        (WM_USER+10)
+#define RB_INSERTBANND WINELIB_NAME_AW(RB_INSERTBAND)
+#define RB_DELETEBAND           (WM_USER+2)
+#define RB_GETBARINFO           (WM_USER+3)
+#define RB_SETBARINFO           (WM_USER+4)
+#define RB_GETBANDINFO32        (WM_USER+5)   /* just for compatibility */
+#define RB_SETBANDINFO32A       (WM_USER+6)
+#define RB_SETBANDINFO32W       (WM_USER+11)
+#define RB_SETBANDINFO WINELIB_NAME_AW(RB_SETBANDINFO)
+#define RB_SETPARENT            (WM_USER+7)
+#define RB_HITTEST              (WM_USER+8)
+#define RB_GETRECT              (WM_USER+9)
+#define RB_GETBANDCOUNT         (WM_USER+12)
+#define RB_GETROWCOUNT          (WM_USER+13)
+#define RB_GETROWHEIGHT         (WM_USER+14)
+#define RB_IDTOINDEX            (WM_USER+16)
+#define RB_GETTOOLTIPS          (WM_USER+17)
+#define RB_SETTOOLTIPS          (WM_USER+18)
+#define RB_SETBKCOLOR           (WM_USER+19)
+#define RB_GETBKCOLOR           (WM_USER+20)
+#define RB_SETTEXTCOLOR         (WM_USER+21)
+#define RB_GETTEXTCOLOR         (WM_USER+22)
+#define RB_SIZETORECT           (WM_USER+23)
+#define RB_BEGINDRAG            (WM_USER+24)
+#define RB_ENDDRAG              (WM_USER+25)
+#define RB_DRAGMOVE             (WM_USER+26)
+#define RB_GETBARHEIGHT         (WM_USER+27)
+#define RB_GETBANDINFO32W       (WM_USER+28)
+#define RB_GETBANDINFO32A       (WM_USER+29)
+#define RB_GETBANDINFO WINELIB_NAME_AW(RB_GETBANDINFO)
+#define RB_MINIMIZEBAND         (WM_USER+30)
+#define RB_MAXIMIZEBAND         (WM_USER+31)
+
+#define RB_GETBANDORDERS        (WM_USER+34)
+#define RB_SHOWBAND             (WM_USER+35)
+
+#define RB_SETPALETTE           (WM_USER+37)
+#define RB_GETPALETTE           (WM_USER+38)
+#define RB_MOVEBAND             (WM_USER+39)
+#define RB_GETDROPTARGET        CCS_GETDROPTARGET
+#define RB_SETCOLORSCHEME       CCS_SETCOLORSCHEME
+#define RB_GETCOLORSCHEME       CCS_GETCOLORSCHEME
+#define RB_SETUNICODEFORMAT     CCS_SETUNICODEFORMAT
+#define RB_GETUNICODEFORMAT     CCS_GETUNICODEFORMAT
+
+
+typedef struct tagREBARINFO
+{
+    UINT32     cbSize;
+    UINT32     fMask;
+    HIMAGELIST himl;
+} REBARINFO, *LPREBARINFO;
+
+typedef struct tagREBARBANDINFOA
+{
+    UINT32    cbSize;
+    UINT32    fMask;
+    UINT32    fStyle;
+    COLORREF  clrFore;
+    COLORREF  clrBack;
+    LPSTR     lpText;
+    UINT32    cch;
+    INT32     iImage;
+    HWND32    hwndChild;
+    UINT32    cxMinChild;
+    UINT32    cyMinChild;
+    UINT32    cx;
+    HBITMAP32 hbmBack;
+    UINT32    wID;
+    UINT32    cyChild;
+    UINT32    cyMaxChild;
+    UINT32    cyIntegral;
+    UINT32    cxIdeal;
+    LPARAM    lParam;
+    UINT32    cxHeader;
+} REBARBANDINFO32A, *LPREBARBANDINFO32A;
+
+
+
+
 
 /* Trackbar control */
 
@@ -1119,8 +1326,196 @@
 #define LVM_FIRST               0x1000
 
 #define LVM_SETBKCOLOR          (LVM_FIRST+1)
+#define LVM_GETIMAGELIST        (LVM_FIRST+2)
 #define LVM_SETIMAGELIST        (LVM_FIRST+3)
+#define LVM_GETITEMCOUNT        (LVM_FIRST+4)
+#define LVM_GETITEM             (LVM_FIRST+5)
+#define LVM_INSERTITEM          (LVM_FIRST+7)
+#define LVM_DELETEALLITEMS      (LVM_FIRST+9)
+#define LVM_SETITEMPOSITION     (LVM_FIRST+15)
+#define LVM_INSERTCOLUMN        (LVM_FIRST+27)
+#define LVM_SORTITEMS           (LVM_FIRST+48)
+#define LVM_GETSELECTEDCOUNT    (LVM_FIRST+50)
 
+#define LVS_ICON                0x0000
+#define LVS_REPORT              0x0001
+#define LVS_SMALLICON           0x0002
+#define LVS_LIST                0x0003
+#define LVS_TYPEMASK            0x0003
+#define LVS_SINGLESEL           0x0004
+#define LVS_SHOWSELALWAYS       0x0008
+#define LVS_SORTASCENDING       0x0010
+#define LVS_SORTDESCENDING      0x0020
+#define LVS_SHAREIMAGELISTS     0x0040
+#define LVS_NOLABELWRAP         0x0080
+#define LVS_AUTOARRANGE         0x0100
+#define LVS_EDITLABELS          0x0200
+#define LVS_OWNERDATA           0x1000
+#define LVS_NOSCROLL            0x2000
+#define LVS_TYPESTYLEMASK       0xfc00
+#define LVS_ALIGNTOP            0x0000
+#define LVS_ALIGNLEFT           0x0800
+#define LVS_ALIGNMASK           0x0c00
+#define LVS_OWNERDRAWFIXED      0x0400
+#define LVS_NOCOLUMNHEADER      0x4000
+#define LVS_NOSORTHEADER        0x8000
+
+#define I_IMAGECALLBACK         (-1)
+#define I_INDENTCALLBACK        (-1)
+#define LV_ITEMA LVITEMA
+#define LV_ITEMW LVITEMW
+
+#define LV_ITEM LVITEM
+
+#define LVITEMA_V1_SIZE CCSIZEOF_STRUCT(LVITEMA, lParam)
+#define LVITEMW_V1_SIZE CCSIZEOF_STRUCT(LVITEMW, lParam)
+
+typedef struct tagLVITEMA
+{
+    UINT32 mask;
+    int iItem;
+    int iSubItem;
+    UINT32 state;
+    UINT32 stateMask;
+    LPSTR pszText;
+    int cchTextMax;
+    int iImage;
+    LPARAM lParam;
+    int iIndent;	//(_WIN32_IE >= 0x0300)
+} LVITEMA, * LPLVITEMA;
+
+typedef struct tagLVITEMW
+{
+    UINT32 mask;
+    int iItem;
+    int iSubItem;
+    UINT32 state;
+    UINT32 stateMask;
+    LPWSTR pszText;
+    int cchTextMax;
+    int iImage;
+    LPARAM lParam;
+    int iIndent;	//(_WIN32_IE >= 0x0300)
+} LVITEMW, * LPLVITEMW;
+
+#define LVITEM    LVITEMA
+#define LPLVITEM  LPLVITEMA
+#define LVITEM_V1_SIZE LVITEMA_V1_SIZE
+
+#define LV_COLUMNA      LVCOLUMNA
+#define LV_COLUMNW      LVCOLUMNW
+#define LV_COLUMN       LVCOLUMN
+#define LVCOLUMNA_V1_SIZE CCSIZEOF_STRUCT(LVCOLUMNA, iSubItem)
+#define LVCOLUMNW_V1_SIZE CCSIZEOF_STRUCT(LVCOLUMNW, iSubItem)
+
+typedef struct tagLVCOLUMNA
+{   UINT32 mask;
+    int fmt;
+    int cx;
+    LPSTR pszText;
+    int cchTextMax;
+    int iSubItem;
+    int iImage;  //(_WIN32_IE >= 0x0300)
+    int iOrder;  //(_WIN32_IE >= 0x0300)
+} LVCOLUMNA,* LPLVCOLUMNA;
+
+typedef struct tagLVCOLUMNW
+{   UINT32 mask;
+    int fmt;
+    int cx;
+    LPWSTR pszText;
+    int cchTextMax;
+    int iSubItem;
+    int iImage;	//(_WIN32_IE >= 0x0300)
+    int iOrder;	//(_WIN32_IE >= 0x0300)
+} LVCOLUMNW,* LPLVCOLUMNW;
+
+#define  LVCOLUMN               LVCOLUMNA
+#define  LPLVCOLUMN             LPLVCOLUMNA
+#define LVCOLUMN_V1_SIZE LVCOLUMNA_V1_SIZE
+
+#define LVCF_FMT                0x0001
+#define LVCF_WIDTH              0x0002
+#define LVCF_TEXT               0x0004
+#define LVCF_SUBITEM            0x0008
+#define LVCF_IMAGE              0x0010
+#define LVCF_ORDER              0x0020
+
+
+#define LVCFMT_LEFT             0x0000
+#define LVCFMT_RIGHT            0x0001
+#define LVCFMT_CENTER           0x0002
+#define LVCFMT_JUSTIFYMASK      0x0003
+#define LVCFMT_IMAGE            0x0800
+#define LVCFMT_BITMAP_ON_RIGHT  0x1000
+#define LVCFMT_COL_HAS_IMAGES   0x8000
+
+#define SNDMSG SendMessage32A
+#define ListView_GetImageList(hwnd, iImageList) (HIMAGELIST)SNDMSG((hwnd), LVM_GETIMAGELIST, (WPARAM)(INT)(iImageList), 0L)
+
+#define LVSIL_NORMAL            0
+#define LVSIL_SMALL             1
+#define LVSIL_STATE             2
+
+
+#define ListView_SetImageList(hwnd, himl, iImageList) (HIMAGELIST)(UINT32)SNDMSG((hwnd), LVM_SETIMAGELIST, (WPARAM32)(iImageList), (LPARAM)(UINT32)(HIMAGELIST)(himl))
+#define ListView_GetItemCount(hwnd)(int)SNDMSG((hwnd), LVM_GETITEMCOUNT, 0, 0L)
+#define ListView_GetItem(hwnd, pitem)(BOOL32)SNDMSG((hwnd), LVM_GETITEM, 0, (LPARAM)(LV_ITEM *)(pitem))
+#define ListView_InsertItem(hwnd, pitem) (int)SNDMSG((hwnd), LVM_INSERTITEM, 0, (LPARAM)(const LV_ITEM *)(pitem))
+#define ListView_DeleteAllItems(hwnd) (BOOL32)SNDMSG((hwnd), LVM_DELETEALLITEMS, 0, 0L)
+#define ListView_InsertColumn(hwnd, iCol, pcol)(int)SNDMSG((hwnd), LVM_INSERTCOLUMN, (WPARAM32)(int)(iCol), (LPARAM)(const LV_COLUMN *)(pcol))
+typedef int (CALLBACK *PFNLVCOMPARE)(LPARAM, LPARAM, LPARAM);
+#define ListView_SortItems(hwndLV, _pfnCompare, _lPrm)(BOOL32)SNDMSG((hwndLV), LVM_SORTITEMS, (WPARAM32)(LPARAM)_lPrm,(LPARAM)(PFNLVCOMPARE)_pfnCompare)
+#define ListView_SetItemPosition(hwndLV, i, x, y)(BOOL32)SNDMSG((hwndLV), LVM_SETITEMPOSITION, (WPARAM32)(int)(i), MAKELPARAM((x), (y)))
+#define ListView_GetSelectedCount(hwndLV)(UINT32)SNDMSG((hwndLV), LVM_GETSELECTEDCOUNT, 0, 0L)
+
+#define LVIF_TEXT               0x0001
+#define LVIF_IMAGE              0x0002
+#define LVIF_PARAM              0x0004
+#define LVIF_STATE              0x0008
+#define LVIF_INDENT             0x0010
+#define LVIF_NORECOMPUTE        0x0800
+
+#define LVIS_FOCUSED            0x0001
+#define LVIS_SELECTED           0x0002
+#define LVIS_CUT                0x0004
+#define LVIS_DROPHILITED        0x0008
+#define LVIS_ACTIVATING         0x0020
+
+#define LVIS_OVERLAYMASK        0x0F00
+#define LVIS_STATEIMAGEMASK     0xF000
+
+#define LPNM_LISTVIEW   LPNMLISTVIEW
+#define NM_LISTVIEW     NMLISTVIEW
+
+typedef struct tagNMLISTVIEW
+{   NMHDR   hdr;
+    int     iItem;
+    int     iSubItem;
+    UINT32  uNewState;
+    UINT32  uOldState;
+    UINT32  uChanged;
+    POINT32 ptAction;
+    LPARAM  lParam;
+} NMLISTVIEW,*LPNMLISTVIEW;
+
+
+#define LV_DISPINFOA    NMLVDISPINFOA
+#define LV_DISPINFOW    NMLVDISPINFOW
+
+#define LV_DISPINFO     NMLVDISPINFO
+
+typedef struct tagLVDISPINFO {
+    NMHDR hdr;
+    LVITEMA item;
+} NMLVDISPINFOA, *LPNMLVDISPINFOA;
+
+typedef struct tagLVDISPINFOW {
+    NMHDR hdr;
+    LVITEMW item;
+} NMLVDISPINFOW, * LPNMLVDISPINFOW;
+
+#define  NMLVDISPINFO           NMLVDISPINFOA
 
 
 #endif  /* __WINE_COMMCTRL_H */
diff --git a/include/ddraw.h b/include/ddraw.h
index 58ea6ff..db87666 100644
--- a/include/ddraw.h
+++ b/include/ddraw.h
@@ -876,7 +876,6 @@
 struct _common_directdrawdata {
     DWORD			depth;
     DWORD			height,width;	/* SetDisplayMode */
-    HWND32			mainwindow;
 };
 
 struct _dga_directdrawdata {
@@ -887,12 +886,16 @@
 
 struct _xlib_directdrawdata {
     Window		drawable;
+    int			use_xshm;
     /* are these needed for anything? (draw_surf is the active surface)
-       IDirectDrawSurface	*surfs;
-       DWORD		num_surfs, alloc_surfs, draw_surf; */
+    IDirectDrawSurface	*surfs;
+    DWORD		num_surfs, alloc_surfs, draw_surf; */
+    int			paintable;
 
-       ATOM		winclass;
-       HWND32		window;
+/* current window implementation */
+    ATOM		winclass;
+    HWND32		window;
+    PAINTSTRUCT32	ps;
 };
 
 struct IDirectDraw {
@@ -901,7 +904,6 @@
 	struct _common_directdrawdata d;
 	union {
 		struct _xlib_directdrawdata xlib;
-		struct _xlib_directdrawdata xshm;
 		struct _dga_directdrawdata  dga;
 	} e;
 };
@@ -957,8 +959,6 @@
 	struct _common_directdrawdata	d;
 	union {
 		struct _xlib_directdrawdata xlib;
-		/* only different in image create&put */
-		struct _xlib_directdrawdata xshm;
 		struct _dga_directdrawdata dga;
 	} e;
 };
@@ -967,7 +967,7 @@
 #define THIS LPDIRECTDRAWSURFACE this
 struct _common_directdrawsurface {
     LPDIRECTDRAWPALETTE		palette;
-    LPDIRECTDRAW		ddraw;
+    LPDIRECTDRAW2		ddraw;
     LPDIRECTDRAWSURFACE3	backbuffer;
     LPVOID			surface;
     DWORD			lpitch,width,height;
@@ -977,16 +977,12 @@
     DWORD		fb_height;
 };
 
-struct _xshm_directdrawsurface {
+struct _xlib_directdrawsurface {
     XImage		*image;
 #ifdef HAVE_LIBXXSHM
     XShmSegmentInfo	shminfo;
 #endif
 };
-struct _xlib_directdrawsurface {
-    XImage		*image;
-    BOOL32		surface_is_image_data;
-};
 
 typedef struct IDirectDrawSurface_VTable {
     /*** IUnknown methods ***/
@@ -1034,7 +1030,6 @@
     struct _common_directdrawsurface	s;
     union {
 	struct _dga_directdrawsurface	dga;
-	struct _xshm_directdrawsurface	xshm;
 	struct _xlib_directdrawsurface	xlib;
     } t;
 };
@@ -1181,5 +1176,8 @@
 #undef STDMETHOD
 #undef STDMETHOD_
 
-extern HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID,LPDIRECTDRAW *lplpDD,LPUNKNOWN pUnkOuter );
+HRESULT WINAPI DirectDrawCreate(LPGUID,LPDIRECTDRAW*,LPUNKNOWN);
+HRESULT WINAPI DirectDrawEnumerate32A(LPDDENUMCALLBACK32A,LPVOID);
+HRESULT WINAPI DirectDrawEnumerate32W(LPDDENUMCALLBACK32W,LPVOID);
+#define DirectDrawEnumerate WINELIB_NAME_AW(DirectDrawEnumerate)
 #endif
diff --git a/include/debug.h b/include/debug.h
index 9056a5c..962d826 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -87,58 +87,59 @@
 #define dbch_ole 79
 #define dbch_pager 80
 #define dbch_palette 81
-#define dbch_print 82
-#define dbch_process 83
-#define dbch_profile 84
-#define dbch_progress 85
-#define dbch_prop 86
-#define dbch_psdrv 87
-#define dbch_rebar 88
-#define dbch_reg 89
-#define dbch_region 90
-#define dbch_relay 91
-#define dbch_resource 92
-#define dbch_s 93
-#define dbch_scroll 94
-#define dbch_security 95
-#define dbch_segment 96
-#define dbch_selector 97
-#define dbch_sem 98
-#define dbch_sendmsg 99
-#define dbch_shell 100
-#define dbch_shm 101
-#define dbch_snoop 102
-#define dbch_sound 103
-#define dbch_static 104
-#define dbch_statusbar 105
-#define dbch_stress 106
-#define dbch_string 107
-#define dbch_syscolor 108
-#define dbch_system 109
-#define dbch_task 110
-#define dbch_text 111
-#define dbch_thread 112
-#define dbch_thunk 113
-#define dbch_timer 114
-#define dbch_toolbar 115
-#define dbch_toolhelp 116
-#define dbch_tooltips 117
-#define dbch_trackbar 118
-#define dbch_treeview 119
-#define dbch_tweak 120
-#define dbch_uitools 121
-#define dbch_updown 122
-#define dbch_ver 123
-#define dbch_virtual 124
-#define dbch_vxd 125
-#define dbch_win 126
-#define dbch_win16drv 127
-#define dbch_win32 128
-#define dbch_wing 129
-#define dbch_winsock 130
-#define dbch_wnet 131
-#define dbch_x11 132
-#define dbch_x11drv 133
+#define dbch_pidl 82
+#define dbch_print 83
+#define dbch_process 84
+#define dbch_profile 85
+#define dbch_progress 86
+#define dbch_prop 87
+#define dbch_psdrv 88
+#define dbch_rebar 89
+#define dbch_reg 90
+#define dbch_region 91
+#define dbch_relay 92
+#define dbch_resource 93
+#define dbch_s 94
+#define dbch_scroll 95
+#define dbch_security 96
+#define dbch_segment 97
+#define dbch_selector 98
+#define dbch_sem 99
+#define dbch_sendmsg 100
+#define dbch_shell 101
+#define dbch_shm 102
+#define dbch_snoop 103
+#define dbch_sound 104
+#define dbch_static 105
+#define dbch_statusbar 106
+#define dbch_stress 107
+#define dbch_string 108
+#define dbch_syscolor 109
+#define dbch_system 110
+#define dbch_task 111
+#define dbch_text 112
+#define dbch_thread 113
+#define dbch_thunk 114
+#define dbch_timer 115
+#define dbch_toolbar 116
+#define dbch_toolhelp 117
+#define dbch_tooltips 118
+#define dbch_trackbar 119
+#define dbch_treeview 120
+#define dbch_tweak 121
+#define dbch_uitools 122
+#define dbch_updown 123
+#define dbch_ver 124
+#define dbch_virtual 125
+#define dbch_vxd 126
+#define dbch_win 127
+#define dbch_win16drv 128
+#define dbch_win32 129
+#define dbch_wing 130
+#define dbch_winsock 131
+#define dbch_wnet 132
+#define dbch_x11 133
+#define dbch_x11drv 134
 /* Definitions for classes identifiers */
 #define dbcl_fixme 0
 #define dbcl_err 1
diff --git a/include/debugdefs.h b/include/debugdefs.h
index 14450de..60ceded 100644
--- a/include/debugdefs.h
+++ b/include/debugdefs.h
@@ -4,7 +4,7 @@
 #include "debugtools.h"
 #endif
 
-#define DEBUG_CHANNEL_COUNT 134
+#define DEBUG_CHANNEL_COUNT 135
 #ifdef DEBUG_RUNTIME
 short debug_msg_enabled[][DEBUG_CLASS_COUNT] = {
 {1, 1, 0, 0},
@@ -141,6 +141,7 @@
 {1, 1, 0, 0},
 {1, 1, 0, 0},
 {1, 1, 0, 0},
+{1, 1, 0, 0},
 };
 const char* debug_ch_name[] = {
 "1",
@@ -225,6 +226,7 @@
 "ole",
 "pager",
 "palette",
+"pidl",
 "print",
 "process",
 "profile",
diff --git a/include/dosexe.h b/include/dosexe.h
index 56cd478..ad3a892 100644
--- a/include/dosexe.h
+++ b/include/dosexe.h
@@ -15,24 +15,25 @@
 typedef struct _DOSTASK {
  LPVOID img;
  unsigned img_ofs;
+ WORD psp_seg,load_seg;
  HMODULE16 hModule;
  struct vm86plus_struct VM86;
  int fn, state;
-#ifdef MZ_USESYSV
- /* SYSV IPC is not quite supported yet... */
- key_t shm_key;
- int shm_id;
-#else
  char mm_name[128];
  int mm_fd;
-#endif
  int read_pipe,write_pipe;
  pid_t task;
 } DOSTASK, *LPDOSTASK;
 
-extern HINSTANCE16 MZ_LoadModule( LPCSTR name, LPCSTR cmdline, LPCSTR env, UINT16 show_cmd );
+#define MZ_SUPPORTED
+
+extern int MZ_InitTask( LPDOSTASK lpDosTask );
 extern int MZ_RunModule( LPDOSTASK lpDosTask );
 extern void MZ_KillModule( LPDOSTASK lpDosTask );
 extern int DOSVM_Process( LPDOSTASK lpDosTask );
 
 #endif /* linux */
+
+extern HINSTANCE16 MZ_CreateProcess( LPCSTR name, LPCSTR cmdline, LPCSTR env,
+                                     LPSTARTUPINFO32A startup, LPPROCESS_INFORMATION info );
+extern int DOSVM_Enter( PCONTEXT context );
diff --git a/include/file.h b/include/file.h
index 564314f..fc5f806 100644
--- a/include/file.h
+++ b/include/file.h
@@ -40,6 +40,17 @@
     int flags;
 } DOS_DEVICE;
 
+/* Macros to convert 16 bit to 32 bit file handles and back */
+#define HFILE16_TO_HFILE32(handle) \
+(((handle)==0) ? GetStdHandle(STD_INPUT_HANDLE) : \
+ ((handle)==1) ? GetStdHandle(STD_OUTPUT_HANDLE) : \
+ ((handle)==2) ? GetStdHandle(STD_ERROR_HANDLE) : \
+ (handle)-5)
+
+#define HFILE32_TO_HFILE16(handle) ({ HFILE32 hnd=handle; \
+      ((hnd==HFILE_ERROR32) ? HFILE_ERROR16 : \
+       (HFILE16)hnd+5); })
+
 
 /* files/file.c */
 extern FILE_OBJECT *FILE_GetFile( HFILE32 handle );
diff --git a/include/gdi.h b/include/gdi.h
index fcb1786..c8ca418 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -200,7 +200,7 @@
     BOOL32     (*pPatBlt)(DC*,INT32,INT32,INT32,INT32,DWORD);
     BOOL32     (*pPie)(DC*,INT32,INT32,INT32,INT32,INT32,INT32,INT32,INT32);
     BOOL32     (*pPolyPolygon)(DC*,LPPOINT32,LPINT32,UINT32);
-    BOOL32     (*pPolyPolyline)(DC*,LPPOINT32,LPINT32,UINT32);
+    BOOL32     (*pPolyPolyline)(DC*,LPPOINT32,LPDWORD,DWORD);
     BOOL32     (*pPolygon)(DC*,LPPOINT32,INT32);
     BOOL32     (*pPolyline)(DC*,LPPOINT32,INT32);
     BOOL32     (*pPolyBezier)(DC*,POINT32, LPPOINT32,DWORD);
diff --git a/include/header.h b/include/header.h
index 710b1e4..298f67b 100644
--- a/include/header.h
+++ b/include/header.h
@@ -18,32 +18,32 @@
     INT32     fmt;
     LPARAM    lParam;
     INT32     iImage;
-    INT32     iOrder;
+    INT32     iOrder;		/* see documentation of HD_ITEM */
 
-    BOOL32    bDown;
-    RECT32    rect;
+    BOOL32    bDown;		/* is item pressed? (used for drawing) */
+    RECT32    rect;		/* bounding rectangle of the item */
 } HEADER_ITEM;
 
 
 typedef struct
 {
-    UINT32      uNumItem;
-    INT32       nHeight;
-    HFONT32     hFont;
-    HCURSOR32   hcurArrow;
-    HCURSOR32   hcurDivider;
-    HCURSOR32   hcurDivopen;
-    BOOL32      bCaptured;
-    BOOL32      bPressed;
-    BOOL32      bTracking;
-    INT32       iMoveItem;
-    INT32       xTrackOffset;
-    INT32       xOldTrack;
-    INT32       nOldWidth;
-    INT32       iHotItem;
+    UINT32      uNumItem;	/* number of items (columns) */
+    INT32       nHeight;	/* height of the header (pixels) */
+    HFONT32     hFont;		/* handle to the current font */
+    HCURSOR32   hcurArrow;	/* handle to the arrow cursor */
+    HCURSOR32   hcurDivider;	/* handle to a cursor (used over dividers) <-|-> */
+    HCURSOR32   hcurDivopen;	/* handle to a cursor (used over dividers) <-||-> */
+    BOOL32      bCaptured;	/* Is the mouse captured? */
+    BOOL32      bPressed;	/* Is a header item pressed (down)? */
+    BOOL32      bTracking;	/* Is in tracking mode? */
+    INT32       iMoveItem;	/* index of tracked item. (Tracking mode) */
+    INT32       xTrackOffset;	/* distance between the right side of the tracked item and the cursor */
+    INT32       xOldTrack;	/* track offset (see above) after the last WM_MOUSEMOVE */
+    INT32       nOldWidth;	/* width of a sizing item after the last WM_MOUSEMOVE */
+    INT32       iHotItem;	/* index of hot item (cursor is over this item) */
 
-    HIMAGELIST  himl;
-    HEADER_ITEM *items;
+    HIMAGELIST  himl;		/* handle to a image list (may be 0) */
+    HEADER_ITEM *items;		/* pointer to array of HEADER_ITEM's */
 } HEADER_INFO;
 
 
diff --git a/include/miscemu.h b/include/miscemu.h
index 5f4c766..6855762 100644
--- a/include/miscemu.h
+++ b/include/miscemu.h
@@ -17,6 +17,7 @@
 extern BOOL32 DOSMEM_Init(HMODULE16 hModule);
 extern void   DOSMEM_Tick(void);
 extern WORD   DOSMEM_AllocSelector(WORD);
+extern char * DOSMEM_MemoryBase(HMODULE16 hModule);
 extern LPVOID DOSMEM_GetBlock(HMODULE16 hModule, UINT32 size, UINT16* p);
 extern BOOL32 DOSMEM_FreeBlock(HMODULE16 hModule, void* ptr);
 extern LPVOID DOSMEM_ResizeBlock(HMODULE16 hModule, void* ptr, UINT32 size, UINT16* p);
@@ -36,6 +37,10 @@
 
 /* msdos/int1a.c */
 extern DWORD INT1A_GetTicksSinceMidnight(void);
+extern void WINAPI INT_Int1aHandler(CONTEXT*);
+
+/* msdos/int2f.c */
+extern void WINAPI INT_Int2fHandler(CONTEXT*);
 
 /* loader/signal.c */
 extern BOOL32 SIGNAL_Init(void);
diff --git a/include/module.h b/include/module.h
index 485d784..bc0e25f 100644
--- a/include/module.h
+++ b/include/module.h
@@ -52,6 +52,7 @@
     HMODULE16  self;          /* 44 Handle for this module */
     WORD    self_loading_sel; /* 46 Selector used for self-loading apps. */
     struct _DOSTASK *lpDosTask;
+    LPVOID  dos_image;        /* pointer to DOS memory (for DOS apps) */
 } NE_MODULE;
 
 
@@ -98,7 +99,7 @@
 {
     LPSTR lpEnvAddress;
     LPSTR lpCmdLine;
-    LPSTR lpCmdShow;
+    UINT16 *lpCmdShow;
     DWORD dwReserved;
 } LOADPARAMS32;
 
@@ -140,8 +141,6 @@
 extern WINE_MODREF *MODULE32_LookupHMODULE( struct _PDB32 *process, HMODULE32 hModule );
 extern HMODULE32 MODULE_FindModule32( struct _PDB32 *process, LPCSTR path );
 extern HMODULE32 MODULE_CreateDummyModule( const OFSTRUCT *ofs );
-extern HINSTANCE16 MODULE_Load( LPCSTR name, BOOL32 implicit, LPCSTR cmd_line,
-                                LPCSTR env, UINT32 show_cmd );
 extern FARPROC16 MODULE_GetWndProcEntry16( const char *name );
 extern FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE32 hmodule, LPCSTR name );
 
diff --git a/include/pager.h b/include/pager.h
index fe992ff..0808084 100644
--- a/include/pager.h
+++ b/include/pager.h
@@ -14,7 +14,8 @@
     COLORREF clrBk;
     INT32    iBorder;
     INT32    iButtonSize;
-
+    INT32    iPos;
+    BOOL32   bForward;
 
 } PAGER_INFO;
 
diff --git a/include/pe_image.h b/include/pe_image.h
index 5b91461..bba5733 100644
--- a/include/pe_image.h
+++ b/include/pe_image.h
@@ -40,8 +40,9 @@
 extern DWORD PE_SizeofResource32(HMODULE32,HRSRC32);
 extern HMODULE32 PE_LoadLibraryEx32A(LPCSTR,struct _PDB32*,HFILE32,DWORD);
 extern HGLOBAL32 PE_LoadResource32(struct _wine_modref *wm,HRSRC32);
-extern HINSTANCE16 PE_LoadModule( LPCSTR name, LPCSTR cmd_line,
-                                  LPCSTR env, UINT16 showCmd );
+extern HINSTANCE16 PE_CreateProcess( LPCSTR name, LPCSTR cmd_line,
+                                     LPCSTR env, LPSTARTUPINFO32A startup,
+                                     LPPROCESS_INFORMATION info );
 
 struct _PDB32; /* forward definition */
 struct _THDB; /* forward definition */
diff --git a/include/process.h b/include/process.h
index 8f82294..539aee1 100644
--- a/include/process.h
+++ b/include/process.h
@@ -142,7 +142,7 @@
 extern PDB32 *PROCESS_IdToPDB( DWORD id );
 extern PDB32 *PROCESS_Create( struct _NE_MODULE *pModule, LPCSTR cmd_line,
                               LPCSTR env, HINSTANCE16 hInstance,
-                              HINSTANCE16 hPrevInstance, UINT32 cmdShow,
+                              HINSTANCE16 hPrevInstance, STARTUPINFO32A *startup,
                               PROCESS_INFORMATION *info );
 extern void PROCESS_SuspendOtherThreads(void);
 extern void PROCESS_ResumeOtherThreads(void);
diff --git a/include/queue.h b/include/queue.h
index 38136c5..f864dfe 100644
--- a/include/queue.h
+++ b/include/queue.h
@@ -80,6 +80,8 @@
 extern BOOL32 QUEUE_IsExitingQueue( HQUEUE16 hQueue );
 extern void QUEUE_SetExitingQueue( HQUEUE16 hQueue );
 extern MESSAGEQUEUE *QUEUE_GetSysQueue(void);
+extern void QUEUE_Signal( HTASK16 hTask );
+extern void QUEUE_Wait(void);
 extern void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD bit );
 extern void QUEUE_ClearWakeBit( MESSAGEQUEUE *queue, WORD bit );
 extern void QUEUE_ReceiveMessage( MESSAGEQUEUE *queue );
diff --git a/include/rebar.h b/include/rebar.h
index 152d6ee..ff92512 100644
--- a/include/rebar.h
+++ b/include/rebar.h
@@ -7,10 +7,38 @@
 #ifndef __WINE_REBAR_H
 #define __WINE_REBAR_H
 
+typedef struct tagREBAR_BAND
+{
+    UINT32    fStyle;
+    COLORREF  clrFore;
+    COLORREF  clrBack;
+    INT32     iImage;
+    HWND32    hwndChild;
+    UINT32    cxMinChild;
+    UINT32    cyMinChild;
+    UINT32    cx;
+    HBITMAP32 hbmBack;
+    UINT32    wID;
+    UINT32    cyChild;
+    UINT32    cyMaxChild;
+    UINT32    cyIntegral;
+    UINT32    cxIdeal;
+    LPARAM    lParam;
+    UINT32    cxHeader;
+
+    LPSTR     lpText;
+
+} REBAR_BAND;
+
 
 typedef struct tagREBAR_INFO
 {
-    UINT32  uDummy;   /* this is just a dummy to keep the compiler happy */
+    COLORREF   clrBk;      /* background color */
+    COLORREF   clrText;    /* text color */
+    HIMAGELIST himl;       /* handle to imagelist */
+    UINT32     uNumBands;  /* number of bands in the rebar */
+
+    REBAR_BAND *bands;     /* pointer to the array of rebar bands */
 
 } REBAR_INFO;
 
diff --git a/include/server.h b/include/server.h
index 0b80e48..30e09ac 100644
--- a/include/server.h
+++ b/include/server.h
@@ -86,6 +86,18 @@
 };
 
 
+/* Retrieve information about a thread */
+struct get_thread_info_request
+{
+    int          handle;       /* thread handle */
+};
+struct get_thread_info_reply
+{
+    void*        pid;          /* server thread id */
+    int          exit_code;    /* thread exit code */
+};
+
+
 /* Close a handle for the current process */
 struct close_handle_request
 {
@@ -123,6 +135,23 @@
 };
 
 
+/* Wait for handles */
+struct select_request
+{
+    int          count;        /* handles count */
+    int          flags;        /* wait flags (see below) */
+    int          timeout;      /* timeout in ms */
+    /* int handles[] */
+};
+struct select_reply
+{
+    int          signaled;     /* signaled handle */
+};
+#define SELECT_ALL       1
+#define SELECT_MSG       2
+#define SELECT_ALERTABLE 4
+#define SELECT_TIMEOUT   8
+
 /* client-side functions */
 
 #ifndef __WINE_SERVER__
@@ -134,8 +163,10 @@
 extern int CLIENT_CloseHandle( int handle );
 extern int CLIENT_DuplicateHandle( int src_process, int src_handle, int dst_process,
                                    int dst_handle, DWORD access, BOOL32 inherit, DWORD options );
+extern int CLIENT_GetThreadInfo( int handle, struct get_thread_info_reply *reply );
 extern int CLIENT_GetProcessInfo( int handle, struct get_process_info_reply *reply );
 extern int CLIENT_OpenProcess( void *pid, DWORD access, BOOL32 inherit );
+extern int CLIENT_Select( int count, int *handles, int flags, int timeout );
 #endif  /* __WINE_SERVER__ */
 
 #endif  /* __WINE_SERVER_H */
diff --git a/include/server/object.h b/include/server/object.h
index bf6dcd3..5268061 100644
--- a/include/server/object.h
+++ b/include/server/object.h
@@ -18,17 +18,22 @@
 
 struct object;
 struct object_name;
+struct thread;
 
 struct object_ops
 {
-    void (*dump)(struct object *,int);   /* dump the object (for debugging) */
-    void (*destroy)(struct object *);    /* destroy on refcount == 0 */
+    void (*dump)(struct object *,int);                  /* dump the object (for debugging) */
+    int  (*signaled)(struct object *,struct thread *);  /* is object signaled? */
+    int  (*satisfied)(struct object *,struct thread *); /* wait satisfied; return 1 if abandoned */
+    void (*destroy)(struct object *);                   /* destroy on refcount == 0 */
 };
 
 struct object
 {
     unsigned int              refcount;
     const struct object_ops  *ops;
+    struct wait_queue_entry  *head;
+    struct wait_queue_entry  *tail;
     struct object_name       *name;
 };
 
diff --git a/include/server/request.h b/include/server/request.h
index 574b732..b882ebc 100644
--- a/include/server/request.h
+++ b/include/server/request.h
@@ -10,9 +10,11 @@
     REQ_TERMINATE_PROCESS,
     REQ_TERMINATE_THREAD,
     REQ_GET_PROCESS_INFO,
+    REQ_GET_THREAD_INFO,
     REQ_CLOSE_HANDLE,
     REQ_DUP_HANDLE,
     REQ_OPEN_PROCESS,
+    REQ_SELECT,
     REQ_NB_REQUESTS
 };
 
@@ -26,9 +28,11 @@
 DECL_HANDLER(terminate_process);
 DECL_HANDLER(terminate_thread);
 DECL_HANDLER(get_process_info);
+DECL_HANDLER(get_thread_info);
 DECL_HANDLER(close_handle);
 DECL_HANDLER(dup_handle);
 DECL_HANDLER(open_process);
+DECL_HANDLER(select);
 
 static const struct handler {
     void       (*handler)();
@@ -39,9 +43,11 @@
     { (void(*)())req_terminate_process, sizeof(struct terminate_process_request) },
     { (void(*)())req_terminate_thread, sizeof(struct terminate_thread_request) },
     { (void(*)())req_get_process_info, sizeof(struct get_process_info_request) },
+    { (void(*)())req_get_thread_info, sizeof(struct get_thread_info_request) },
     { (void(*)())req_close_handle, sizeof(struct close_handle_request) },
     { (void(*)())req_dup_handle, sizeof(struct dup_handle_request) },
     { (void(*)())req_open_process, sizeof(struct open_process_request) },
+    { (void(*)())req_select, sizeof(struct select_request) },
 };
 #endif  /* WANT_REQUEST_HANDLERS */
 
diff --git a/include/server/thread.h b/include/server/thread.h
index 9edbfdf..7f7df8d 100644
--- a/include/server/thread.h
+++ b/include/server/thread.h
@@ -16,21 +16,26 @@
 /* thread structure */
 
 struct process;
+struct thread_wait;
+
+enum run_state { STARTING, RUNNING, TERMINATED };
 
 struct thread
 {
-    struct object   obj;       /* object header */
-    struct thread  *next;      /* system-wide thread list */
-    struct thread  *prev;
-    struct thread  *proc_next; /* per-process thread list */
-    struct thread  *proc_prev;
-    struct process *process;
-    int             error;     /* current error code */
-    int             exit_code; /* thread exit code */
-    int             client_fd; /* client fd for socket communications */
-    int             unix_pid;  /* Unix pid of client */
-    enum request    last_req;  /* last request received (for debugging) */
-    char           *name;
+    struct object       obj;       /* object header */
+    struct thread      *next;      /* system-wide thread list */
+    struct thread      *prev;
+    struct thread      *proc_next; /* per-process thread list */
+    struct thread      *proc_prev;
+    struct process     *process;
+    struct thread_wait *wait;      /* current wait condition if sleeping */
+    int                 error;     /* current error code */
+    enum run_state      state;     /* running state */
+    int                 exit_code; /* thread exit code */
+    int                 client_fd; /* client fd for socket communications */
+    int                 unix_pid;  /* Unix pid of client */
+    enum request        last_req;  /* last request received (for debugging) */
+    char               *name;
 };
 
 extern struct thread *current;
@@ -41,10 +46,16 @@
                                      int *process_handle );
 extern struct thread *get_thread_from_id( void *id );
 extern struct thread *get_thread_from_handle( int handle, unsigned int access );
+extern void get_thread_info( struct thread *thread,
+                             struct get_thread_info_reply *reply );
 extern int send_reply( struct thread *thread, int pass_fd,
                        int n, ... /* arg_1, len_1, ..., arg_n, len_n */ );
 extern void kill_thread( struct thread *thread, int exit_code );
 extern void thread_killed( struct thread *thread, int exit_code );
+extern void thread_timeout(void);
+extern void sleep_on( struct thread *thread, int count, int *handles,
+                      int flags, int timeout );
+extern void wake_up( struct object *obj, int max );
 
 #define SET_ERROR(err)  (current->error = (err))
 #define CLEAR_ERROR()   (current->error = 0)
diff --git a/include/shell.h b/include/shell.h
index cda641c..e9dc4c5 100644
--- a/include/shell.h
+++ b/include/shell.h
@@ -6,15 +6,29 @@
 
 #include "windows.h"
 #include "winreg.h"
+#include "imagelist.h"
 
 #ifndef MAX_PATH
 #define MAX_PATH 260
 #endif
 
+/****************************************************************************
+* shell 16
+*/
 extern void SHELL_LoadRegistry();
 extern void SHELL_SaveRegistry();
 extern void SHELL_Init();
 
+/* global functions used from shell32 */
+extern HINSTANCE32 SHELL_FindExecutable(LPCSTR,LPCSTR ,LPSTR);
+extern HGLOBAL16 WINAPI InternalExtractIcon(HINSTANCE16,LPCSTR,UINT16,WORD);
+
+/****************************************************************************
+* shell 32
+*/
+/****************************************************************************
+* common return codes 
+*/
 #define SHELL_ERROR_SUCCESS           0L
 #define SHELL_ERROR_BADDB             1L
 #define SHELL_ERROR_BADKEY            2L
@@ -25,8 +39,8 @@
 #define SHELL_ERROR_INVALID_PARAMETER 7L
 #define SHELL_ERROR_ACCESS_DENIED     8L
 
-/******************************
-* common shell file structures
+/****************************************************************************
+* common shell file structures 
 */
 #define FO_MOVE           0x0001
 #define FO_COPY           0x0002
@@ -63,8 +77,8 @@
 	/* memory block with filenames follows */     
 } DROPFILESTRUCT, *LPDROPFILESTRUCT; 
 
-/******************************
-* NOTIFYICONDATA
+/****************************************************************************
+* NOTIFYICONDATA 
 */
 typedef struct _NOTIFYICONDATA {
 	DWORD cbSize;
@@ -76,8 +90,8 @@
 	CHAR szTip[64];
 } NOTIFYICONDATA, *PNOTIFYICONDATA;
 
-/*******************************
-* SHITEMID, ITEMIDLIST, PIDL API
+/****************************************************************************
+* SHITEMID, ITEMIDLIST, PIDL API 
 */
 typedef struct 
 { WORD		cb;	/* nr of bytes in this item */
@@ -89,6 +103,7 @@
 } ITEMIDLIST,*LPITEMIDLIST,*LPCITEMIDLIST;
 
 LPITEMIDLIST WINAPI ILClone (LPCITEMIDLIST pidl);
+LPITEMIDLIST WINAPI ILGetNext(LPITEMIDLIST pidl);
 LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST iil1,LPCITEMIDLIST iil2);
 DWORD WINAPI ILGetSize(LPITEMIDLIST pidl);
 
@@ -97,7 +112,7 @@
 #define  SHGetPathFromIDList WINELIB_NAME_AW(SHGetPathFromIDList)
 
 /****************************************************************************
-* SHFILEINFO API
+* SHFILEINFO API 
 */
 typedef struct tagSHFILEINFO32A {
 	HICON32	hIcon;			/* icon */
@@ -122,7 +137,7 @@
 #define  SHGetFileInfo WINELIB_NAME_AW(SHGetFileInfo)
 
 /****************************************************************************
-* SHFILEOPSTRUCT API
+* SHFILEOPSTRUCT API 
 */
 typedef struct _SHFILEOPSTRUCTA
 { HWND32          hwnd;
@@ -153,7 +168,7 @@
 
 DWORD WINAPI SHFileOperation32(LPSHFILEOPSTRUCT32 lpFileOp);
 
-/****************
+/****************************************************************************
 * APPBARDATA 
 */
 typedef struct _AppBarData {
@@ -188,6 +203,7 @@
 { LPITEMIDLIST pidl;
   DWORD unknown;
 } IDSTRUCT;
+
 DWORD WINAPI SHChangeNotifyRegister(HWND32 hwnd,LONG events1,LONG events2,DWORD msg,int count,IDSTRUCT *idlist);
 DWORD WINAPI SHChangeNotifyDeregister(LONG x1,LONG x2);
 
@@ -200,13 +216,17 @@
 DWORD WINAPI SHAddToRecentDocs(UINT32 uFlags, LPCVOID pv);
 
 /****************************************************************************
+*  string and path functions
+*/
+LPSTR WINAPI PathAddBackslash(LPSTR path);	
+LPSTR WINAPI PathCombine(LPSTR target,LPSTR x1,LPSTR x2);
+LPSTR WINAPI PathRemoveBlanks(LPSTR str);
+LPSTR WINAPI PathFindFilename(LPSTR fn);
+/****************************************************************************
 *  other functions
 */
 LPVOID WINAPI SHAlloc(DWORD len);
 DWORD WINAPI SHFree(LPVOID x);
-LPSTR WINAPI PathAddBackslash(LPSTR path);	
-LPSTR WINAPI PathCombine(LPSTR target,LPSTR x1,LPSTR x2);
-LPSTR WINAPI PathRemoveBlanks(LPSTR str);
 
 #define SE_ERR_SHARE            26
 #define SE_ERR_ASSOCINCOMPLETE  27
@@ -233,10 +253,4 @@
 #define	CSIDL_FONTS		0x0014
 #define	CSIDL_TEMPLATES		0x0015
 
-/*******************************************
-*  global SHELL32.DLL variables
-*/
-extern HINSTANCE32 shell32_hInstance;
-extern UINT32      shell32_DllRefCount;
-
 #endif  /* __WINE_SHELL_H */
diff --git a/include/shlobj.h b/include/shlobj.h
index 350fe57..4a900ac 100644
--- a/include/shlobj.h
+++ b/include/shlobj.h
@@ -7,6 +7,7 @@
 #include "compobj.h"
 #include "storage.h"
 #include "commctrl.h"
+#include "interfaces.h"
 
 #define STDMETHOD(xfn) HRESULT (CALLBACK *fn##xfn)
 #define STDMETHOD_(type,xfn) type (CALLBACK *fn##xfn)
@@ -25,11 +26,15 @@
 typedef LPVOID	LPBC; /* *IBindCtx really */
 
 /* foreward declaration of the objects*/
-typedef struct IEnumIDList IEnumIDList,*LPENUMIDLIST;
-typedef struct tagSHELLFOLDER *LPSHELLFOLDER,IShellFolder;
-typedef struct tagSHELLVIEW *LPSHELLVIEW,IShellView;
-typedef struct tagSHELLBROWSER *LPSHELLBROWSER,IShellBrowser;
 
+typedef struct IContextMenu		IContextMenu,	*LPCONTEXTMENU;
+typedef struct IShellExtInit	IShellExtInit, 	*LPSHELLEXTINIT;
+typedef struct IEnumIDList		IEnumIDList,	*LPENUMIDLIST;
+typedef struct tagSHELLFOLDER	*LPSHELLFOLDER,	IShellFolder;
+typedef struct tagSHELLVIEW		*LPSHELLVIEW,	IShellView;
+typedef struct tagSHELLBROWSER	*LPSHELLBROWSER,IShellBrowser;
+
+typedef struct IDataObject		IDataObject,	*LPDATAOBJECT;
 /****************************************************************************
 *  SHELL ID
 */
@@ -114,17 +119,18 @@
    STDMETHOD_(LPITEMIDLIST, CreateDrive) (THIS_ LPCSTR);
    STDMETHOD_(LPITEMIDLIST, CreateFolder) (THIS_ LPCSTR);
    STDMETHOD_(LPITEMIDLIST, CreateValue) (THIS_ LPCSTR);
-/*   STDMETHOD_(void, Delete) (THIS_ LPITEMIDLIST);*/
-   STDMETHOD_(LPITEMIDLIST, GetNextItem) (THIS_ LPCITEMIDLIST);
+
    STDMETHOD_(BOOL32, GetDesktop) (THIS_ LPCITEMIDLIST, LPSTR);
    STDMETHOD_(BOOL32, GetDrive) (THIS_ LPCITEMIDLIST, LPSTR, UINT16);
    STDMETHOD_(LPITEMIDLIST, GetLastItem) (THIS_ LPCITEMIDLIST);
    STDMETHOD_(DWORD, GetItemText) (THIS_ LPCITEMIDLIST, LPSTR, UINT16);
+
    STDMETHOD_(BOOL32, IsDesktop) (THIS_ LPCITEMIDLIST);
    STDMETHOD_(BOOL32, IsMyComputer) (THIS_ LPCITEMIDLIST);
    STDMETHOD_(BOOL32, IsDrive) (THIS_ LPCITEMIDLIST);
    STDMETHOD_(BOOL32, IsFolder) (THIS_ LPCITEMIDLIST);
    STDMETHOD_(BOOL32, IsValue) (THIS_ LPCITEMIDLIST);
+
    STDMETHOD_(BOOL32, HasFolders) (THIS_ LPSTR, LPCITEMIDLIST);
    STDMETHOD_(DWORD, GetFolderText) (THIS_ LPCITEMIDLIST, LPSTR, DWORD);
    STDMETHOD_(DWORD, GetValueText) (THIS_ LPCITEMIDLIST, LPSTR, DWORD);
@@ -148,6 +154,136 @@
 #endif
 
 #undef THIS
+/*****************************************************************************
+ * IContextMenu interface
+ */
+#define THIS LPCONTEXTMENU this
+
+/* QueryContextMenu uFlags */
+#define CMF_NORMAL              0x00000000
+#define CMF_DEFAULTONLY         0x00000001
+#define CMF_VERBSONLY           0x00000002
+#define CMF_EXPLORE             0x00000004
+#define CMF_NOVERBS             0x00000008
+#define CMF_CANRENAME           0x00000010
+#define CMF_NODEFAULT           0x00000020
+#define CMF_INCLUDESTATIC       0x00000040
+#define CMF_RESERVED            0xffff0000      // View specific
+
+/* GetCommandString uFlags */
+#define GCS_VERBA        0x00000000     // canonical verb
+#define GCS_HELPTEXTA    0x00000001     // help text (for status bar)
+#define GCS_VALIDATEA    0x00000002     // validate command exists
+#define GCS_VERBW        0x00000004     // canonical verb (unicode)
+#define GCS_HELPTEXTW    0x00000005     // help text (unicode version)
+#define GCS_VALIDATEW    0x00000006     // validate command exists (unicode)
+#define GCS_UNICODE      0x00000004     // for bit testing - Unicode string
+
+#define GCS_VERB        GCS_VERBA
+#define GCS_HELPTEXT    GCS_HELPTEXTA
+#define GCS_VALIDATE    GCS_VALIDATEA
+
+#define CMDSTR_NEWFOLDERA   "NewFolder"
+#define CMDSTR_VIEWLISTA    "ViewList"
+#define CMDSTR_VIEWDETAILSA "ViewDetails"
+#define CMDSTR_NEWFOLDERW   L"NewFolder"
+#define CMDSTR_VIEWLISTW    L"ViewList"
+#define CMDSTR_VIEWDETAILSW L"ViewDetails"
+
+#define CMDSTR_NEWFOLDER    CMDSTR_NEWFOLDERA
+#define CMDSTR_VIEWLIST     CMDSTR_VIEWLISTA
+#define CMDSTR_VIEWDETAILS  CMDSTR_VIEWDETAILSA
+
+#define CMIC_MASK_HOTKEY        SEE_MASK_HOTKEY
+#define CMIC_MASK_ICON          SEE_MASK_ICON
+#define CMIC_MASK_FLAG_NO_UI    SEE_MASK_FLAG_NO_UI
+#define CMIC_MASK_UNICODE       SEE_MASK_UNICODE
+#define CMIC_MASK_NO_CONSOLE    SEE_MASK_NO_CONSOLE
+#define CMIC_MASK_HASLINKNAME   SEE_MASK_HASLINKNAME
+#define CMIC_MASK_FLAG_SEP_VDM  SEE_MASK_FLAG_SEPVDM
+#define CMIC_MASK_HASTITLE      SEE_MASK_HASTITLE
+#define CMIC_MASK_ASYNCOK       SEE_MASK_ASYNCOK
+
+#define CMIC_MASK_PTINVOKE      0x20000000
+
+/*NOTE: When SEE_MASK_HMONITOR is set, hIcon is treated as hMonitor */
+typedef struct _CMINVOKECOMMANDINFO 
+{   DWORD cbSize;        // sizeof(CMINVOKECOMMANDINFO)
+    DWORD fMask;         // any combination of CMIC_MASK_*
+    HWND32 hwnd;         // might be NULL (indicating no owner window)
+    LPCSTR lpVerb;       // either a string or MAKEINTRESOURCE(idOffset)
+    LPCSTR lpParameters; // might be NULL (indicating no parameter)
+    LPCSTR lpDirectory;  // might be NULL (indicating no specific directory)
+    int nShow;           // one of SW_ values for ShowWindow() API
+
+    DWORD dwHotKey;
+    HANDLE32 hIcon;
+} CMINVOKECOMMANDINFO,  *LPCMINVOKECOMMANDINFO;
+
+typedef struct _CMInvokeCommandInfoEx 
+{   DWORD cbSize;        // must be sizeof(CMINVOKECOMMANDINFOEX)
+    DWORD fMask;         // any combination of CMIC_MASK_*
+    HWND32 hwnd;         // might be NULL (indicating no owner window)
+    LPCSTR lpVerb;       // either a string or MAKEINTRESOURCE(idOffset)
+    LPCSTR lpParameters; // might be NULL (indicating no parameter)
+    LPCSTR lpDirectory;  // might be NULL (indicating no specific directory)
+    int nShow;           // one of SW_ values for ShowWindow() API
+
+    DWORD dwHotKey;
+    
+    HANDLE32 hIcon;
+    LPCSTR lpTitle;        // For CreateProcess-StartupInfo.lpTitle
+    LPCWSTR lpVerbW;       // Unicode verb (for those who can use it)
+    LPCWSTR lpParametersW; // Unicode parameters (for those who can use it)
+    LPCWSTR lpDirectoryW;  // Unicode directory (for those who can use it)
+    LPCWSTR lpTitleW;      // Unicode title (for those who can use it)
+    POINT32 ptInvoke;      // Point where it's invoked
+
+} CMINVOKECOMMANDINFOEX,  *LPCMINVOKECOMMANDINFOEX;
+
+
+typedef struct IContextMenu_VTable
+{   // *** IUnknown methods ***
+    STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef) (THIS)  PURE;
+    STDMETHOD_(ULONG,Release) (THIS) PURE;
+
+    STDMETHOD(QueryContextMenu)(THIS_ HMENU32 hmenu,UINT32 indexMenu,UINT32 idCmdFirst, UINT32 idCmdLast,UINT32 uFlags) PURE;
+    STDMETHOD(InvokeCommand)(THIS_ LPCMINVOKECOMMANDINFO lpici) PURE;
+    STDMETHOD(GetCommandString)(THIS_ UINT32 idCmd,UINT32 uType,UINT32 * pwReserved,LPSTR pszName,UINT32 cchMax) PURE;
+} IContextMenu_VTable,*LPCONTEXTMENU_VTABLE;
+
+struct IContextMenu
+{ LPCONTEXTMENU_VTABLE	lpvtbl;
+  DWORD			ref;
+  LPSHELLFOLDER	pSFParent;
+  LPITEMIDLIST	*aPidls;
+  LPPIDLMGR		pPidlMgr;
+  BOOL32		bAllValues;
+};
+
+#undef THIS
+/*****************************************************************************
+ * IShellExtInit interface
+ */
+#define THIS LPSHELLEXTINIT this
+
+typedef struct IShellExtInit_VTable 
+{   // *** IUnknown methods ***
+    STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef) (THIS)  PURE;
+    STDMETHOD_(ULONG,Release) (THIS) PURE;
+
+    // *** IShellExtInit methods ***
+    STDMETHOD(Initialize)(THIS_ LPCITEMIDLIST pidlFolder, LPDATAOBJECT lpdobj, HKEY hkeyProgID) PURE;
+} IShellExtInit_VTable,*LPSHELLEXTINIT_VTABLE;
+
+struct IShellExtInit
+{ LPSHELLEXTINIT_VTABLE	lpvtbl;
+  DWORD			 ref;
+};
+
+#undef THIS
 
 /*****************************************************************************
  * IEnumIDList interface
@@ -310,16 +446,20 @@
     STDMETHOD(GetUIObjectOf)(THIS_ HWND32 hwndOwner, UINT32 cidl, LPCITEMIDLIST * apidl,REFIID riid, UINT32 * prgfInOut, LPVOID * ppvOut) PURE;
     STDMETHOD(GetDisplayNameOf)(THIS_ LPCITEMIDLIST pidl, DWORD uFlags, LPSTRRET lpName) PURE;
     STDMETHOD(SetNameOf)(THIS_ HWND32 hwndOwner, LPCITEMIDLIST pidl,LPCOLESTR32 lpszName, DWORD uFlags,LPITEMIDLIST * ppidlOut) PURE;
+
+	/* utility functions */
+   STDMETHOD_(BOOL32,GetFolderPath)(THIS_ LPSTR, DWORD);
+   
 } *LPSHELLFOLDER_VTABLE,IShellFolder_VTable;
 
 struct tagSHELLFOLDER {
 	LPSHELLFOLDER_VTABLE	lpvtbl;
-	DWORD			   ref;
-	LPSTR        mlpszFolder;
-    LPPIDLMGR	   pPidlMgr;
-	LPITEMIDLIST mpidl;
-	LPITEMIDLIST mpidlNSRoot;
-	LPSHELLFOLDER mpSFParent;
+	DWORD			ref;
+	LPSTR			mlpszFolder;
+    LPPIDLMGR		pPidlMgr;
+	LPITEMIDLIST	mpidl;
+	LPITEMIDLIST	mpidlNSRoot;
+	LPSHELLFOLDER	mpSFParent;
 };
 
 extern LPSHELLFOLDER pdesktopfolder;
@@ -330,6 +470,12 @@
 */
 #define THIS LPSHELLBROWSER this
 
+#define FCW_STATUS      0x0001
+#define FCW_TOOLBAR     0x0002
+#define FCW_TREE        0x0003
+#define FCW_INTERNETBAR 0x0006
+#define FCW_PROGRESS    0x0008
+
 typedef struct IShellBrowser_VTable 
 {    // *** IUnknown methods ***
     STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
@@ -383,6 +529,42 @@
 #define SVGIO_SELECTION     0x00000001
 #define SVGIO_ALLVIEW       0x00000002
 
+/* The explorer dispatches WM_COMMAND messages based on the range of
+ command/menuitem IDs. All the IDs of menuitems that the view (right
+ pane) inserts must be in FCIDM_SHVIEWFIRST/LAST (otherwise, the explorer
+ won't dispatch them). The view should not deal with any menuitems
+ in FCIDM_BROWSERFIRST/LAST (otherwise, it won't work with the future
+ version of the shell).
+
+  FCIDM_SHVIEWFIRST/LAST      for the right pane (IShellView)
+  FCIDM_BROWSERFIRST/LAST     for the explorer frame (IShellBrowser)
+  FCIDM_GLOBAL/LAST           for the explorer's submenu IDs
+*/
+#define FCIDM_SHVIEWFIRST           0x0000
+#define FCIDM_SHVIEWLAST            0x7fff
+#define FCIDM_BROWSERFIRST          0xa000
+#define FCIDM_BROWSERLAST           0xbf00
+#define FCIDM_GLOBALFIRST           0x8000
+#define FCIDM_GLOBALLAST            0x9fff
+
+/*
+* Global submenu IDs and separator IDs
+*/
+#define FCIDM_MENU_FILE             (FCIDM_GLOBALFIRST+0x0000)
+#define FCIDM_MENU_EDIT             (FCIDM_GLOBALFIRST+0x0040)
+#define FCIDM_MENU_VIEW             (FCIDM_GLOBALFIRST+0x0080)
+#define FCIDM_MENU_VIEW_SEP_OPTIONS (FCIDM_GLOBALFIRST+0x0081)
+#define FCIDM_MENU_TOOLS            (FCIDM_GLOBALFIRST+0x00c0)
+#define FCIDM_MENU_TOOLS_SEP_GOTO   (FCIDM_GLOBALFIRST+0x00c1)
+#define FCIDM_MENU_HELP             (FCIDM_GLOBALFIRST+0x0100)
+#define FCIDM_MENU_FIND             (FCIDM_GLOBALFIRST+0x0140)
+#define FCIDM_MENU_EXPLORE          (FCIDM_GLOBALFIRST+0x0150)
+#define FCIDM_MENU_FAVORITES        (FCIDM_GLOBALFIRST+0x0170)
+
+/* control IDs known to the view */
+#define FCIDM_TOOLBAR      (FCIDM_BROWSERFIRST + 0)
+#define FCIDM_STATUS       (FCIDM_BROWSERFIRST + 1)
+
 /* uState values for IShellView::UIActivate */
 typedef enum 
 { SVUIA_DEACTIVATE       = 0,
@@ -424,8 +606,11 @@
   LPSHELLFOLDER      pSFParent;
   LPSHELLBROWSER     pShellBrowser;
   HWND32             hWnd;
+  HWND32             hWndList;
   FOLDERSETTINGS     FolderSettings;
   HWND32             hWndParent;
+  HMENU32            hMenu;
+  UINT32			 uState;
 };
 
 typedef GUID SHELLVIEWID;
@@ -498,19 +683,173 @@
 
 #undef THIS
 
-#ifdef __WINE__
+/****************************************************************************
+ * IExtractIcon interface
+ *
+ * FIXME
+ *  Is the ExtractIconA interface
+ */
+#define THIS LPEXTRACTICON this
 
+/* GetIconLocation() input flags*/
+#define GIL_OPENICON     0x0001      // allows containers to specify an "open" look
+#define GIL_FORSHELL     0x0002      // icon is to be displayed in a ShellFolder
+#define GIL_ASYNC        0x0020      // this is an async extract, return E_ASYNC
+
+/* GetIconLocation() return flags */
+#define GIL_SIMULATEDOC  0x0001      // simulate this document icon for this
+#define GIL_PERINSTANCE  0x0002      // icons from this class are per instance (each file has its own)
+#define GIL_PERCLASS     0x0004      // icons from this class per class (shared for all files of this type)
+#define GIL_NOTFILENAME  0x0008      // location is not a filename, must call ::ExtractIcon
+#define GIL_DONTCACHE    0x0010      // this icon should not be cached
+
+typedef struct IExtractIcon IExtractIcon,*LPEXTRACTICON;
+typedef struct IExtractIcon_VTable
+{ /*** IUnknown methods ***/
+  STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+  STDMETHOD_(ULONG,AddRef) (THIS)  PURE;
+  STDMETHOD_(ULONG,Release) (THIS) PURE;
+
+  /*** IExtractIcon methods ***/
+  STDMETHOD(GetIconLocation)(THIS_ UINT32 uFlags, LPSTR szIconFile, UINT32 cchMax, int * piIndex, UINT32 * pwFlags) PURE;
+  STDMETHOD(Extract)(THIS_ LPCSTR pszFile, UINT32 nIconIndex, HICON32 *phiconLarge, HICON32 *phiconSmall, UINT32 nIconSize) PURE;
+}IExtractIccon_VTable,*LPEXTRACTICON_VTABLE;
+
+struct IExtractIcon 
+{ LPEXTRACTICON_VTABLE lpvtbl;
+  DWORD ref;
+  LPITEMIDLIST pidl;
+};
+
+#undef THIS
+/****************************************************************************
+ * IShellIcon interface
+ */
+
+#define THIS LPSHELLICON this
+typedef struct IShellIcon IShellIcon,*LPSHELLICON;
+typedef struct IShellIcon_VTable
+{ /*** IUnknown methods ***/
+  STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+  STDMETHOD_(ULONG,AddRef) (THIS)  PURE;
+  STDMETHOD_(ULONG,Release) (THIS) PURE;
+
+  /*** IShellIcon methods ***/
+  STDMETHOD(GetIconOf)(THIS_ LPCITEMIDLIST pidl, UINT32 flags, LPINT32 lpIconIndex) PURE;
+} IShellIcon_VTable,*LPSHELLICON_VTABLE;
+
+struct IShellIcon
+{ LPSHELLICON_VTABLE lpvtbl;
+  DWORD ref;
+};
+#undef THIS
+
+
+/****************************************************************************
+ * Class constructors
+ */
+#ifdef __WINE__
 extern LPCLASSFACTORY IClassFactory_Constructor();
+extern LPCONTEXTMENU IContextMenu_Constructor(LPSHELLFOLDER, LPCITEMIDLIST *, UINT32);
 extern LPSHELLFOLDER IShellFolder_Constructor(LPSHELLFOLDER,LPITEMIDLIST);
 extern LPSHELLVIEW IShellView_Constructor();
 extern LPSHELLLINK IShellLink_Constructor();
 extern LPENUMIDLIST IEnumIDList_Constructor(LPCSTR,DWORD,HRESULT*);
+extern LPEXTRACTICON IExtractIcon_Constructor(LPITEMIDLIST);
 #endif
+/****************************************************************************
+ * Shell Execute API
+ */
+#define SE_ERR_FNF              2       // file not found
+#define SE_ERR_PNF              3       // path not found
+#define SE_ERR_ACCESSDENIED     5       // access denied
+#define SE_ERR_OOM              8       // out of memory
+#define SE_ERR_DLLNOTFOUND      32
+#define SE_ERR_SHARE                    26
+#define SE_ERR_ASSOCINCOMPLETE          27
+#define SE_ERR_DDETIMEOUT               28
+#define SE_ERR_DDEFAIL                  29
+#define SE_ERR_DDEBUSY                  30
+#define SE_ERR_NOASSOC                  31
+
+#define SEE_MASK_CLASSNAME        0x00000001
+#define SEE_MASK_CLASSKEY         0x00000003
+#define SEE_MASK_IDLIST           0x00000004
+#define SEE_MASK_INVOKEIDLIST     0x0000000c
+#define SEE_MASK_ICON             0x00000010
+#define SEE_MASK_HOTKEY           0x00000020
+#define SEE_MASK_NOCLOSEPROCESS   0x00000040
+#define SEE_MASK_CONNECTNETDRV    0x00000080
+#define SEE_MASK_FLAG_DDEWAIT     0x00000100
+#define SEE_MASK_DOENVSUBST       0x00000200
+#define SEE_MASK_FLAG_NO_UI       0x00000400
+#define SEE_MASK_UNICODE          0x00004000
+#define SEE_MASK_NO_CONSOLE       0x00008000
+#define SEE_MASK_ASYNCOK          0x00100000
+#define SEE_MASK_HMONITOR         0x00200000
+
+typedef struct _SHELLEXECUTEINFOA
+{       DWORD cbSize;
+        ULONG fMask;
+        HWND32 hwnd;
+        LPCSTR   lpVerb;
+        LPCSTR   lpFile;
+        LPCSTR   lpParameters;
+        LPCSTR   lpDirectory;
+        int nShow;
+        HINSTANCE32 hInstApp;
+        /* Optional fields */
+        LPVOID lpIDList;
+        LPCSTR   lpClass;
+        HKEY hkeyClass;
+        DWORD dwHotKey;
+        union 
+        { HANDLE32 hIcon;
+          HANDLE32 hMonitor;
+        } u;
+        HANDLE32 hProcess;
+} SHELLEXECUTEINFOA, *LPSHELLEXECUTEINFOA;
+
+typedef struct _SHELLEXECUTEINFOW
+{       DWORD cbSize;
+        ULONG fMask;
+        HWND32 hwnd;
+        LPCWSTR  lpVerb;
+        LPCWSTR  lpFile;
+        LPCWSTR  lpParameters;
+        LPCWSTR  lpDirectory;
+        int nShow;
+        HINSTANCE32 hInstApp;
+        /* Optional fields*/
+        LPVOID lpIDList;
+        LPCWSTR  lpClass;
+        HKEY hkeyClass;
+        DWORD dwHotKey;
+        union
+        { HANDLE32 hIcon;
+          HANDLE32 hMonitor;
+        } u;
+        HANDLE32 hProcess;
+} SHELLEXECUTEINFOW, *LPSHELLEXECUTEINFOW;
+
+DECL_WINELIB_TYPE_AW(SHELLEXECUTEINFO)
+
+typedef SHELLEXECUTEINFOA SHELLEXECUTEINFO;
+typedef LPSHELLEXECUTEINFOA LPSHELLEXECUTEINFO;
+
+BOOL32 WINAPI ShellExecuteEx32A(LPSHELLEXECUTEINFOA lpExecInfo);
+BOOL32 WINAPI ShellExecuteEx32W(LPSHELLEXECUTEINFOW lpExecInfo);
+#define ShellExecuteEx  WINELIB_NAME_AW(ShellExecuteEx)
+
+void WINAPI WinExecErrorA(HWND32 hwnd, int error, LPCSTR lpstrFileName, LPCSTR lpstrTitle);
+void WINAPI WinExecErrorW(HWND32 hwnd, int error, LPCWSTR lpstrFileName, LPCWSTR lpstrTitle);
+#define WinExecError  WINELIB_NAME_AW(WinExecError)
+
+
 
 /****************************************************************************
  * SHBrowseForFolder API
  */
-
 typedef int (CALLBACK* BFFCALLBACK)(HWND32 hwnd, UINT32 uMsg, LPARAM lParam, LPARAM lpData);
 
 typedef struct tagBROWSEINFO32A {
@@ -585,8 +924,9 @@
 #define  SHBrowseForFolder WINELIB_NAME_AW(SHBrowseForFolder)
 
 /****************************************************************************
- * shlview structures
- */
+* shlview structures
+*/
+
 /*
 * IShellFolderViewCallback Callback
 *  This "callback" is called by the shells default IShellView implementation (that
@@ -619,6 +959,29 @@
   DWORD           viewmode;  // NF_* enum
 } SHELLVIEWDATA, * LPSHELLVIEWDATA;
 
+/*
+ The shell keeps track of some per-user state to handle display
+ options that is of major interest to ISVs.
+ The key one requested right now is "DoubleClickInWebView".
+*/
+typedef struct 
+{   BOOL32 fShowAllObjects : 1;
+    BOOL32 fShowExtensions : 1;
+    BOOL32 fNoConfirmRecycle : 1;
+    BOOL32 fShowSysFiles : 1;
+    BOOL32 fShowCompColor : 1;
+    BOOL32 fDoubleClickInWebView : 1;
+    BOOL32 fDesktopHTML : 1;
+    BOOL32 fWin95Classic : 1;
+    BOOL32 fDontPrettyPath : 1;
+    BOOL32 fShowAttribCol : 1;
+    BOOL32 fMapNetDrvBtn : 1;
+    BOOL32 fShowInfoTip : 1;
+    BOOL32 fHideIcons : 1;
+    UINT32 fRestFlags : 3;
+} SHELLFLAGSTATE, * LPSHELLFLAGSTATE;
+
+
 #undef PURE
 #undef FAR
 #undef THIS
diff --git a/include/sig_context.h b/include/sig_context.h
index 595d91c..315564f 100644
--- a/include/sig_context.h
+++ b/include/sig_context.h
@@ -217,10 +217,10 @@
 #define FL_sig(context)      (*(WORD*)&EFL_sig(context))
 
 #ifdef FS_sig
-extern WORD CALLTO16_Current_fs;
+#include "syslevel.h"
 #define HANDLER_INIT() \
     SET_FS(IS_SELECTOR_SYSTEM(CS_sig(HANDLER_CONTEXT)) ? \
-           FS_sig(HANDLER_CONTEXT) : CALLTO16_Current_fs)
+           FS_sig(HANDLER_CONTEXT) : SYSLEVEL_Win16CurrentTeb)
 #else
 #define HANDLER_INIT() /* nothing */
 #endif
diff --git a/include/syslevel.h b/include/syslevel.h
index 56ac846..e151075 100644
--- a/include/syslevel.h
+++ b/include/syslevel.h
@@ -10,6 +10,8 @@
 #include "wintypes.h"
 #include "winbase.h"
 
+extern WORD SYSLEVEL_Win16CurrentTeb;
+
 void SYSLEVEL_Init(void);
 VOID SYSLEVEL_EnterWin16Lock(VOID);
 VOID SYSLEVEL_LeaveWin16Lock(VOID);
diff --git a/include/task.h b/include/task.h
index 85f38cb..bde0351 100644
--- a/include/task.h
+++ b/include/task.h
@@ -147,6 +147,7 @@
 extern HTASK16 TASK_Create( struct _THDB *thdb, struct _NE_MODULE *pModule,
                             HINSTANCE16 hInstance, HINSTANCE16 hPrevInstance,
                             UINT16 cmdShow );
+extern void TASK_StartTask( HTASK16 hTask );
 extern void TASK_KillCurrentTask( INT16 exitCode );
 extern HTASK16 TASK_GetNextTask( HTASK16 hTask );
 extern void TASK_Reschedule(void);
diff --git a/include/thread.h b/include/thread.h
index e033b29..58ad89a 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -44,6 +44,7 @@
     BOOL32        wait_all;  /* Wait for all objects flag */
     BOOL32        wait_msg;  /* Wait for message flag */
     K32OBJ       *objs[MAXIMUM_WAIT_OBJECTS];  /* Object pointers */
+    int           server[MAXIMUM_WAIT_OBJECTS];  /* Server handles */
 } WAIT_STRUCT;
 
 /* Thread database */
@@ -128,6 +129,7 @@
                             int *server_thandle, int *server_phandle,
                             LPTHREAD_START_ROUTINE start_addr, LPVOID param );
 extern THDB *THREAD_Current(void);
+extern BOOL32 THREAD_IsWin16( THDB *thdb );
 extern void THREAD_Start( THDB *thdb );
 extern THDB *THREAD_GetPtr( HANDLE32 handle, DWORD access, int *server_handle );
 extern void THREAD_AddQueue( THREAD_QUEUE *queue, THDB *thread );
diff --git a/include/toolbar.h b/include/toolbar.h
index fc05739..4af9f98 100644
--- a/include/toolbar.h
+++ b/include/toolbar.h
@@ -32,17 +32,18 @@
     INT32      nBitmapHeight;
     INT32      nBitmapWidth;
     INT32      nIndent;
-    INT32      nMaxRows;        /* maximum number of rows */
-
+    INT32      nMaxRows;        /* maximum number of button rows */
+    INT32      nMaxTextRows;    /* maximum number of text rows */
+    INT32      cxMin;           /* minimum button width */
+    INT32      cxMax;           /* maximum button width */
     INT32      nNumButtons;     /* number of buttons */
     INT32      nNumBitmaps;     /* number of bitmaps */
     INT32      nNumStrings;     /* number of strings */
-
-    BOOL32     bCaptured;
+    BOOL32     bUnicode;        /* ASCII (FALSE) or Unicode (TRUE)? */
+    BOOL32     bCaptured;       /* mouse captured? */
     INT32      nButtonDown;
     INT32      nOldHit;
     INT32      nHotItem;        /* index of the "hot" item */
-
     HFONT32    hFont;           /* text font */
     HIMAGELIST himlDef;         /* default image list */
     HIMAGELIST himlHot;         /* hot image list */
@@ -50,12 +51,13 @@
     HWND32     hwndToolTip;     /* handle to tool tip control */
     HWND32     hwndNotify;      /* handle to the window that gets notifications */
     BOOL32     bTransparent;    /* background transparency flag */
-    BOOL32     bAutoSize;
+    BOOL32     bAutoSize;       /* auto size deadlock indicator */
     DWORD      dwExStyle;       /* extended toolbar style */
+    SIZE32     maxSize;         /* maximum toolbar size */
 
     COLORREF   clrInsertMark;   /* insert mark color */
 
-    TBUTTON_INFO *buttons;
+    TBUTTON_INFO *buttons;      /* pointer to button array */
     CHAR         **strings;
 } TOOLBAR_INFO;
 
diff --git a/include/tooltips.h b/include/tooltips.h
index b4875c0..2750cb4 100644
--- a/include/tooltips.h
+++ b/include/tooltips.h
@@ -8,6 +8,14 @@
 #define __WINE_TOOLTIPS_H
 
 
+typedef struct tagTT_SUBCLASS_INFO
+{
+    WNDPROC32 wpOrigProc;
+    HWND32    hwndToolTip;
+    UINT32    uRefCount;
+} TT_SUBCLASS_INFO, *LPTT_SUBCLASS_INFO;
+
+
 typedef struct tagTTTOOL_INFO
 {
     UINT32 uFlags;
@@ -17,8 +25,6 @@
     HINSTANCE32 hinst;
     LPSTR  lpszText;
     LPARAM lParam;
-
-    WNDPROC32 lpfnOrigProc;
 } TTTOOL_INFO; 
 
 
diff --git a/include/tweak.h b/include/tweak.h
index 346f6a0..06bffee 100644
--- a/include/tweak.h
+++ b/include/tweak.h
@@ -11,8 +11,8 @@
 
 #include "wintypes.h"
 
-int  TWEAK_Init();
-int  TWEAK_CheckConfiguration();
+int  TWEAK_Init(void);
+int  TWEAK_CheckConfiguration(void);
 void  TWEAK_DrawReliefRect95(HDC32, RECT32 const *);
 void  TWEAK_DrawRevReliefRect95(HDC32, RECT32 const *);
 void  TWEAK_DrawMenuSeparatorHoriz95(HDC32, UINT32, UINT32, UINT32);
diff --git a/include/version.h b/include/version.h
index 2311c01..a6ca120 100644
--- a/include/version.h
+++ b/include/version.h
@@ -1 +1 @@
-#define WINE_RELEASE_INFO "Wine release 980809"
+#define WINE_RELEASE_INFO "Wine release 980822"
diff --git a/include/winbase.h b/include/winbase.h
index b4cc236..16938f2 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -7,6 +7,7 @@
 #define WAIT_OBJECT_0		0
 #define WAIT_ABANDONED		STATUS_ABANDONED_WAIT_0
 #define WAIT_ABANDONED_0	STATUS_ABANDONED_WAIT_0
+#define WAIT_IO_COMPLETION	STATUS_USER_APC
 #define WAIT_TIMEOUT		STATUS_TIMEOUT
 
 #define	PAGE_NOACCESS		0x01
@@ -189,6 +190,7 @@
 void      WINAPI LeaveCriticalSection(CRITICAL_SECTION *lpCrit);
 HANDLE32  WINAPI OpenProcess(DWORD access, BOOL32 inherit, DWORD id);
 void      WINAPI RaiseException(DWORD,DWORD,DWORD,const LPDWORD);
-int       WINAPI TerminateProcess(HANDLE32 h, int ret);
+BOOL32    WINAPI TerminateProcess(HANDLE32,DWORD);
+BOOL32    WINAPI TerminateThread(HANDLE32,DWORD);
 
 #endif  /* __WINE_WINBASE_H */
diff --git a/include/windows.h b/include/windows.h
index a94c819..e5c9f74 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -1073,6 +1073,10 @@
 #define CTLCOLOR_SCROLLBAR          5
 #define CTLCOLOR_STATIC             6
 
+#define ICM_OFF   1
+#define ICM_ON    2
+#define ICM_QUERY 3
+
   /* Bitmaps */
 
 typedef struct
@@ -2165,6 +2169,7 @@
     BYTE   pad0;
     WORD   key;
     WORD   cmd;
+    WORD   pad1;
 } ACCEL32, *LPACCEL32;
 
 DECL_WINELIB_TYPE(ACCEL)
@@ -3178,6 +3183,7 @@
 #define WM_MDICASCADE	    0x0227
 #define WM_MDIICONARRANGE   0x0228
 #define WM_MDIGETACTIVE     0x0229
+#define WM_MDIREFRESHMENU   0x0234
 
   /* D&D messages */
 #define WM_DROPOBJECT	    0x022A
@@ -5282,6 +5288,27 @@
 #define TIME_ZONE_ID_STANDARD   1
 #define TIME_ZONE_ID_DAYLIGHT   2
 
+/* CreateProcess: dwCreationFlag values
+ */
+#define DEBUG_PROCESS               0x00000001
+#define DEBUG_ONLY_THIS_PROCESS     0x00000002
+#define CREATE_SUSPENDED            0x00000004
+#define DETACHED_PROCESS            0x00000008
+#define CREATE_NEW_CONSOLE          0x00000010
+#define NORMAL_PRIORITY_CLASS       0x00000020
+#define IDLE_PRIORITY_CLASS         0x00000040
+#define HIGH_PRIORITY_CLASS         0x00000080
+#define REALTIME_PRIORITY_CLASS     0x00000100
+#define CREATE_NEW_PROCESS_GROUP    0x00000200
+#define CREATE_UNICODE_ENVIRONMENT  0x00000400
+#define CREATE_SEPARATE_WOW_VDM     0x00000800
+#define CREATE_SHARED_WOW_VDM       0x00001000
+#define CREATE_DEFAULT_ERROR_MODE   0x04000000
+#define CREATE_NO_WINDOW            0x08000000
+#define PROFILE_USER                0x10000000
+#define PROFILE_KERNEL              0x20000000
+#define PROFILE_SERVER              0x40000000
+
 
 /* File object type definitions
  */
@@ -6312,6 +6339,7 @@
 UINT16      WINAPI GetCommEventMask(INT16,UINT16);
 HBRUSH16    WINAPI GetControlBrush(HWND16,HDC16,UINT16);
 VOID        WINAPI GetCodeInfo(FARPROC16,LPVOID);
+HFONT16     WINAPI GetCurLogFont(HDC16);
 HANDLE16    WINAPI GetCurrentPDB(void);
 DWORD       WINAPI GetCurrentPosition(HDC16);
 HTASK16     WINAPI GetCurrentTask(void);
@@ -6336,6 +6364,7 @@
 UINT16      WINAPI GetNumTasks(void);
 DWORD       WINAPI GetSelectorBase(WORD);
 DWORD       WINAPI GetSelectorLimit(WORD);
+FARPROC16   WINAPI GetSetKernelDOSProc(FARPROC16 DosProc);
 HINSTANCE16 WINAPI GetTaskDS(void);
 HQUEUE16    WINAPI GetTaskQueue(HTASK16);
 BYTE        WINAPI GetTempDrive(BYTE);
@@ -6375,6 +6404,7 @@
 WORD        WINAPI LocalHeapSize(void);
 HICON16     WINAPI LoadIconHandler(HGLOBAL16,BOOL16);
 BOOL16      WINAPI LocalInit(HANDLE16,WORD,WORD);
+HMODULE32   WINAPI LoadLibraryEx32W16(LPCSTR,HANDLE16,DWORD);
 FARPROC16   WINAPI LocalNotify(FARPROC16);
 HTASK16     WINAPI LockCurrentTask(BOOL16);
 HMENU16     WINAPI LookupMenuHandle(HMENU16,INT16);
@@ -6467,6 +6497,13 @@
 HANDLE32    WINAPI CreateMutex32A(LPSECURITY_ATTRIBUTES,BOOL32,LPCSTR);
 HANDLE32    WINAPI CreateMutex32W(LPSECURITY_ATTRIBUTES,BOOL32,LPCWSTR);
 #define     CreateMutex WINELIB_NAME_AW(CreateMutex)
+BOOL32      WINAPI CreateProcess32A(LPCSTR,LPSTR,LPSECURITY_ATTRIBUTES,
+                                    LPSECURITY_ATTRIBUTES,BOOL32,DWORD,LPVOID,LPCSTR,
+                                    LPSTARTUPINFO32A,LPPROCESS_INFORMATION);
+BOOL32      WINAPI CreateProcess32W(LPCWSTR,LPWSTR,LPSECURITY_ATTRIBUTES,
+                                    LPSECURITY_ATTRIBUTES,BOOL32,DWORD,LPVOID,LPCWSTR,
+                                    LPSTARTUPINFO32W,LPPROCESS_INFORMATION);
+#define     CreateProcess WINELIB_NAME_AW(CreateProcess)
 HANDLE32    WINAPI CreateSemaphore32A(LPSECURITY_ATTRIBUTES,LONG,LONG,LPCSTR);
 HANDLE32    WINAPI CreateSemaphore32W(LPSECURITY_ATTRIBUTES,LONG,LONG,LPCWSTR);
 #define     CreateSemaphore WINELIB_NAME_AW(CreateSemaphore)
@@ -6508,12 +6545,19 @@
 DWORD       WINAPI ExpandEnvironmentStrings32W(LPCWSTR,LPWSTR,DWORD);
 #define     ExpandEnvironmentStrings WINELIB_NAME_AW(ExpandEnvironmentStrings)
 HRGN32      WINAPI ExtCreateRegion(LPXFORM,DWORD,LPRGNDATA);
+INT32       WINAPI ExtEscape32(HDC32,INT32,INT32,LPCSTR,INT32,LPSTR);
 BOOL32      WINAPI FileTimeToDosDateTime(const FILETIME*,LPWORD,LPWORD);
 BOOL32      WINAPI FileTimeToLocalFileTime(const FILETIME*,LPFILETIME);
 BOOL32      WINAPI FileTimeToSystemTime(const FILETIME*,LPSYSTEMTIME);
+HANDLE32    WINAPI FindFirstChangeNotification32A(LPCSTR,BOOL32,DWORD);
+HANDLE32    WINAPI FindFirstChangeNotification32W(LPCWSTR,BOOL32,DWORD);
+#define     FindFirstChangeNotification WINELIB_NAME_AW(FindFirstChangeNotification)
+BOOL32      WINAPI FindNextChangeNotification(HANDLE32);
+BOOL32      WINAPI FindCloseChangeNotification(HANDLE32);
 HRSRC32     WINAPI FindResourceEx32A(HMODULE32,LPCSTR,LPCSTR,WORD);
 HRSRC32     WINAPI FindResourceEx32W(HMODULE32,LPCWSTR,LPCWSTR,WORD);
 #define     FindResourceEx WINELIB_NAME_AW(FindResourceEx)
+BOOL32      WINAPI FixBrushOrgEx(HDC32,INT32,INT32,LPPOINT32);
 BOOL32      WINAPI FlushConsoleInputBuffer(HANDLE32);
 BOOL32      WINAPI FlushFileBuffers(HFILE32);
 BOOL32      WINAPI FlushViewOfFile(LPCVOID, DWORD);
@@ -6525,16 +6569,16 @@
 BOOL32      WINAPI FreeEnvironmentStrings32W(LPWSTR);
 #define     FreeEnvironmentStrings WINELIB_NAME_AW(FreeEnvironmentStrings)
 UINT32      WINAPI GetACP(void);
-LPCSTR      WINAPI GetCommandLine32A();
-LPCWSTR     WINAPI GetCommandLine32W();
+LPCSTR      WINAPI GetCommandLine32A(void);
+LPCWSTR     WINAPI GetCommandLine32W(void);
 #define     GetCommandLine WINELIB_NAME_AW(GetCommandLine)
 BOOL32      WINAPI GetCommTimeouts(INT32,LPCOMMTIMEOUTS);
 BOOL32      WINAPI GetComputerName32A(LPSTR,LPDWORD);
 BOOL32      WINAPI GetComputerName32W(LPWSTR,LPDWORD);
 #define     GetComputerName WINELIB_NAME_AW(GetComputerName)
-UINT32      WINAPI GetConsoleCP();
+UINT32      WINAPI GetConsoleCP(void);
 BOOL32      WINAPI GetConsoleMode(HANDLE32,LPDWORD);
-UINT32      WINAPI GetConsoleOutputCP();
+UINT32      WINAPI GetConsoleOutputCP(void);
 DWORD       WINAPI GetConsoleTitle32A(LPSTR,DWORD);
 DWORD       WINAPI GetConsoleTitle32W(LPWSTR,DWORD);
 #define     GetConsoleTitle WINELIB_NAME_AW(GetConsoleTitle)
@@ -6580,6 +6624,8 @@
 DWORD       WINAPI GetLongPathName32A(LPCSTR,LPSTR,DWORD);
 DWORD       WINAPI GetLongPathName32W(LPCWSTR,LPWSTR,DWORD);
 #define     GetLongPathName WINELIB_NAME_AW(GetLongPathName)
+UINT32      WINAPI GetMenuDefaultItem32(HMENU32,UINT32,UINT32);
+#define     GetMenuDefaultItem WINELIB_NAME(GetMenuDefaultItem)
 BOOL32      WINAPI GetMenuItemInfo32A(HMENU32,UINT32,BOOL32,MENUITEMINFO32A*);
 BOOL32      WINAPI GetMenuItemInfo32W(HMENU32,UINT32,BOOL32,MENUITEMINFO32W*);
 #define     GetMenuItemInfo WINELIB_NAME_AW(GetMenuItemInfo)
@@ -6589,9 +6635,6 @@
 DWORD       WINAPI GetObjectType(HANDLE32);
 UINT32      WINAPI GetOEMCP(void);
 DWORD       WINAPI GetPriorityClass(HANDLE32);
-INT32       WINAPI GetPrivateProfileSection32A(LPCSTR,LPSTR,UINT32,LPCSTR);
-INT32       WINAPI GetPrivateProfileSection32W(LPCWSTR,LPWSTR,UINT32,LPCWSTR);
-#define     GetPrivateProfileSection WINELIB_NAME_AW(GetPrivateProfileSection)
 HANDLE32    WINAPI GetProcessHeap(void);
 DWORD       WINAPI GetRegionData(HRGN32,DWORD,LPRGNDATA);
 DWORD       WINAPI GetShortPathName32A(LPCSTR,LPSTR,DWORD);
@@ -6613,7 +6656,7 @@
 INT32       WINAPI GetTimeFormat32A(LCID,DWORD,LPSYSTEMTIME,LPCSTR,LPSTR,INT32);
 INT32       WINAPI GetTimeFormat32W(LCID,DWORD,LPSYSTEMTIME,LPCWSTR,LPWSTR,INT32);
 #define     GetTimeFormat WINELIB_NAME_AW(GetTimeFormat)
-LCID        WINAPI GetThreadLocale();
+LCID        WINAPI GetThreadLocale(void);
 INT32       WINAPI GetThreadPriority(HANDLE32);
 BOOL32      WINAPI GetThreadSelectorEntry(HANDLE32,DWORD,LPLDT_ENTRY);
 BOOL32      WINAPI GetUserName32A(LPSTR,LPDWORD);
@@ -6645,6 +6688,8 @@
 BOOL32      WINAPI LookupPrivilegeValue32A(LPCSTR,LPCSTR,LPVOID);
 BOOL32      WINAPI LookupPrivilegeValue32W(LPCWSTR,LPCWSTR,LPVOID);
 #define     LookupPrivilegeValue WINELIB_NAME_AW(LookupPrivilegeValue)
+HMODULE32   WINAPI MapHModuleSL(HMODULE16);
+HMODULE16   WINAPI MapHModuleLS(HMODULE32);
 SEGPTR      WINAPI MapLS(LPVOID);
 LPVOID      WINAPI MapSL(SEGPTR);
 LPVOID      WINAPI MapViewOfFile(HANDLE32,DWORD,DWORD,DWORD,DWORD);
@@ -6682,8 +6727,10 @@
 HANDLE32    WINAPI OpenService32A(HANDLE32,LPCSTR,DWORD);
 HANDLE32    WINAPI OpenService32W(HANDLE32,LPCWSTR,DWORD);
 #define     OpenService WINELIB_NAME_AW(OpenService)
+BOOL32      WINAPI PaintDesktop(HDC32);
 BOOL32      WINAPI PlayEnhMetaFile(HDC32,HENHMETAFILE32,const RECT32*);
 BOOL32      WINAPI PlayEnhMetaFileRecord(HDC32,LPHANDLETABLE32,const ENHMETARECORD*,UINT32);
+BOOL32      WINAPI PolyPolyline32(HDC32,LPPOINT32,LPDWORD,DWORD);
 BOOL32      WINAPI PulseEvent(HANDLE32);
 DWORD       WINAPI QueryDosDevice32A(LPCSTR,LPSTR,DWORD);
 DWORD       WINAPI QueryDosDevice32W(LPCWSTR,LPWSTR,DWORD);
@@ -6775,6 +6822,8 @@
 INT32       WINAPI SetGraphicsMode(HDC32,INT32);
 BOOL32      WINAPI SetHandleInformation(HANDLE32,DWORD,DWORD);
 VOID        WINAPI SetLastErrorEx(DWORD,DWORD);
+BOOL32      WINAPI SetMenuDefaultItem32(HMENU32,UINT32,UINT32);
+#define     SetMenuDefaultItem WINELIB_NAME(SetMenuDefaultItem)
 BOOL32      WINAPI SetMenuItemInfo32A(HMENU32,UINT32,BOOL32,const MENUITEMINFO32A*);
 BOOL32      WINAPI SetMenuItemInfo32W(HMENU32,UINT32,BOOL32,const MENUITEMINFO32W*);
 #define     SetMenuItemInfo WINELIB_NAME_AW(SetMenuItemInfo)
@@ -6802,6 +6851,7 @@
 BOOL32      WINAPI TlsFree(DWORD);
 LPVOID      WINAPI TlsGetValue(DWORD);
 BOOL32      WINAPI TlsSetValue(DWORD,LPVOID);
+BOOL32      WINAPI TranslateCharsetInfo(LPDWORD,LPCHARSETINFO,DWORD);
 VOID        WINAPI UnMapLS(SEGPTR);
 BOOL32      WINAPI UnlockFile(HFILE32,DWORD,DWORD,DWORD,DWORD);
 BOOL32      WINAPI UnmapViewOfFile(LPVOID);
@@ -6862,6 +6912,7 @@
 LCID        WINAPI GetUserDefaultLCID(void);
 ATOM        WINAPI GlobalDeleteAtom(ATOM);
 VOID        WINAPI LZDone(void);
+VOID        WINAPI ScreenSwitchEnable(WORD);
 DWORD       WINAPI OemKeyScan(WORD);
 DWORD       WINAPI RegCloseKey(HKEY);
 DWORD       WINAPI RegFlushKey(HKEY);
@@ -7023,6 +7074,9 @@
 BOOL16      WINAPI CheckMenuRadioButton16(HMENU16,UINT16,UINT16,UINT16,BOOL16);
 BOOL32      WINAPI CheckMenuRadioButton32(HMENU32,UINT32,UINT32,UINT32,BOOL32);
 #define     CheckMenuRadioButton WINELIB_NAME(CheckMenuRadioButton)
+BOOL16      WINAPI CheckMenuRadioItem16(HMENU16,UINT16,UINT16,UINT16,UINT16);
+BOOL32      WINAPI CheckMenuRadioItem32(HMENU32,UINT32,UINT32,UINT32,UINT32);
+#define     CheckMenuRadioItem WINELIB_NAME(CheckMenuRadioItem)
 BOOL16      WINAPI CheckRadioButton16(HWND16,UINT16,UINT16,UINT16);
 BOOL32      WINAPI CheckRadioButton32(HWND32,UINT32,UINT32,UINT32);
 #define     CheckRadioButton WINELIB_NAME(CheckRadioButton)
@@ -7067,6 +7121,9 @@
 HICON16     WINAPI CopyIcon16(HINSTANCE16,HICON16);
 HICON32     WINAPI CopyIcon32(HICON32);
 #define     CopyIcon WINELIB_NAME(CopyIcon)
+HICON16     WINAPI CopyImage16(HANDLE16,UINT16,INT16,INT16,UINT16);
+HICON32     WINAPI CopyImage32(HANDLE32,UINT32,INT32,INT32,UINT32);
+#define     CopyImage WINELIB_NAME(CopyImage)
 LONG        WINAPI CopyLZFile16(HFILE16,HFILE16);
 LONG        WINAPI CopyLZFile32(HFILE32,HFILE32);
 #define     CopyLZFile WINELIB_NAME(CopyLZFile)
@@ -7377,6 +7434,10 @@
 VOID        WINAPI DrawMenuBar16(HWND16);
 BOOL32      WINAPI DrawMenuBar32(HWND32);
 #define     DrawMenuBar WINELIB_NAME(DrawMenuBar)
+BOOL16      WINAPI DrawState16A(HDC16,HBRUSH16,DRAWSTATEPROC16,LPARAM,WPARAM16,INT16,INT16,INT16,INT16,UINT16);
+BOOL32      WINAPI DrawState32A(HDC32,HBRUSH32,DRAWSTATEPROC32,LPARAM,WPARAM32,INT32,INT32,INT32,INT32,UINT32);
+BOOL32      WINAPI DrawState32W(HDC32,HBRUSH32,DRAWSTATEPROC32,LPARAM,WPARAM32,INT32,INT32,INT32,INT32,UINT32);
+#define     DrawState WINELIB_NAME_AW(DrawState)
 INT16       WINAPI DrawText16(HDC16,LPCSTR,INT16,LPRECT16,UINT16);
 INT32       WINAPI DrawText32A(HDC32,LPCSTR,INT32,LPRECT32,UINT32);
 INT32       WINAPI DrawText32W(HDC32,LPCWSTR,INT32,LPRECT32,UINT32);
@@ -7572,6 +7633,9 @@
 UINT32      WINAPI GetAtomName32A(ATOM,LPSTR,INT32);
 UINT32      WINAPI GetAtomName32W(ATOM,LPWSTR,INT32);
 #define     GetAtomName WINELIB_NAME_AW(GetAtomName)
+BOOL16      WINAPI GetAspectRatioFilterEx16(HDC16,LPSIZE16);
+BOOL32      WINAPI GetAspectRatioFilterEx32(HDC32,LPSIZE32);
+#define     GetAspectRatioFilterEx WINELIB_NAME(GetAspectRatioFilterEx)
 LONG        WINAPI GetBitmapBits16(HBITMAP16,LONG,LPVOID);
 LONG        WINAPI GetBitmapBits32(HBITMAP32,LONG,LPVOID);
 #define     GetBitmapBits WINELIB_NAME(GetBitmapBits)
@@ -7600,6 +7664,9 @@
 BOOL32      WINAPI GetCharABCWidths32A(HDC32,UINT32,UINT32,LPABC32);
 BOOL32      WINAPI GetCharABCWidths32W(HDC32,UINT32,UINT32,LPABC32);
 #define     GetCharABCWidths WINELIB_NAME_AW(GetCharABCWidths)
+DWORD       WINAPI GetCharacterPlacement32A(HDC32,LPCSTR,INT32,INT32,GCP_RESULTS32A*,DWORD);
+DWORD       WINAPI GetCharacterPlacement32W(HDC32,LPCWSTR,INT32,INT32,GCP_RESULTS32W*,DWORD);
+#define     GetCharacterPlacement WINELIB_NAME_AW(GetCharacterPlacement)
 BOOL16      WINAPI GetCharWidth16(HDC16,UINT16,UINT16,LPINT16);
 BOOL32      WINAPI GetCharWidth32A(HDC32,UINT32,UINT32,LPINT32);
 BOOL32      WINAPI GetCharWidth32W(HDC32,UINT32,UINT32,LPINT32);
@@ -7689,6 +7756,9 @@
 BOOL32      WINAPI GetDiskFreeSpace32A(LPCSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD);
 BOOL32      WINAPI GetDiskFreeSpace32W(LPCWSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD);
 #define     GetDiskFreeSpace WINELIB_NAME_AW(GetDiskFreeSpace)
+BOOL32      WINAPI GetDiskFreeSpaceEx32A(LPCSTR,LPULARGE_INTEGER,LPULARGE_INTEGER,LPULARGE_INTEGER);
+BOOL32      WINAPI GetDiskFreeSpaceEx32W(LPCWSTR,LPULARGE_INTEGER,LPULARGE_INTEGER,LPULARGE_INTEGER);
+#define     GetDiskFreeSpaceEx WINELIB_NAME_AW(GetDiskFreeSpaceEx)
 INT16       WINAPI GetDlgCtrlID16(HWND16);
 INT32       WINAPI GetDlgCtrlID32(HWND32);
 #define     GetDlgCtrlID WINELIB_NAME(GetDlgCtrlID)
@@ -7728,6 +7798,11 @@
 HWND16      WINAPI GetFocus16(void);
 HWND32      WINAPI GetFocus32(void);
 #define     GetFocus WINELIB_NAME(GetFocus)
+DWORD       WINAPI GetFontData32(HDC32,DWORD,DWORD,LPVOID,DWORD);
+#define     GetFontData WINELIB_NAME(GetFontData)
+DWORD       WINAPI GetFontLanguageInfo16(HDC16);
+DWORD       WINAPI GetFontLanguageInfo32(HDC32);
+#define     GetFontLanguageInfo WINELIB_NAME(GetFontLanguageInfo)
 HWND16      WINAPI GetForegroundWindow16(void);
 HWND32      WINAPI GetForegroundWindow32(void);
 #define     GetForegroundWindow WINELIB_NAME(GetForegroundWindow)
@@ -7831,6 +7906,11 @@
 HWND16      WINAPI GetOpenClipboardWindow16(void);
 HWND32      WINAPI GetOpenClipboardWindow32(void);
 #define     GetOpenClipboardWindow WINELIB_NAME(GetOpenClipboardWindow)
+/* FIXME: LPVOID should be LPOUTLINETEXTMETRIC{16,32A,32W} */
+UINT16      WINAPI GetOutlineTextMetrics16(HDC16,UINT16,LPVOID);
+UINT32      WINAPI GetOutlineTextMetrics32A(HDC32,UINT32,LPVOID);
+UINT32      WINAPI GetOutlineTextMetrics32W(HDC32,UINT32,LPVOID);
+#define     GetOutlineTextMetrics WINELIB_NAME_AW(GetOutlineTextMetrics)
 UINT16      WINAPI GetPaletteEntries16(HPALETTE16,UINT16,UINT16,LPPALETTEENTRY);
 UINT32      WINAPI GetPaletteEntries32(HPALETTE32,UINT32,UINT32,LPPALETTEENTRY);
 #define     GetPaletteEntries WINELIB_NAME(GetPaletteEntries)
@@ -7854,10 +7934,22 @@
 UINT32      WINAPI GetPrivateProfileInt32A(LPCSTR,LPCSTR,INT32,LPCSTR);
 UINT32      WINAPI GetPrivateProfileInt32W(LPCWSTR,LPCWSTR,INT32,LPCWSTR);
 #define     GetPrivateProfileInt WINELIB_NAME_AW(GetPrivateProfileInt)
+INT16       WINAPI GetPrivateProfileSection16(LPCSTR,LPSTR,UINT16,LPCSTR);
+INT32       WINAPI GetPrivateProfileSection32A(LPCSTR,LPSTR,DWORD,LPCSTR);
+INT32       WINAPI GetPrivateProfileSection32W(LPCWSTR,LPWSTR,DWORD,LPCWSTR);
+#define     GetPrivateProfileSection WINELIB_NAME_AW(GetPrivateProfileSection)
+WORD        WINAPI GetPrivateProfileSectionNames16(LPSTR,UINT16,LPCSTR);
+DWORD       WINAPI GetPrivateProfileSectionNames32A(LPSTR,DWORD,LPCSTR);
+DWORD       WINAPI GetPrivateProfileSectionNames32W(LPWSTR,DWORD,LPCWSTR);
+#define     GetPrivateProfileSectionNames WINELIB_NAME_AW(GetPrivateProfileSectionNames)
 INT16       WINAPI GetPrivateProfileString16(LPCSTR,LPCSTR,LPCSTR,LPSTR,UINT16,LPCSTR);
 INT32       WINAPI GetPrivateProfileString32A(LPCSTR,LPCSTR,LPCSTR,LPSTR,UINT32,LPCSTR);
 INT32       WINAPI GetPrivateProfileString32W(LPCWSTR,LPCWSTR,LPCWSTR,LPWSTR,UINT32,LPCWSTR);
 #define     GetPrivateProfileString WINELIB_NAME_AW(GetPrivateProfileString)
+BOOL16      WINAPI GetPrivateProfileStruct16(LPCSTR,LPCSTR,LPVOID,UINT16,LPCSTR);
+BOOL32      WINAPI GetPrivateProfileStruct32A(LPCSTR,LPCSTR,LPVOID,UINT32,LPCSTR);
+BOOL32      WINAPI GetPrivateProfileStruct32W(LPCWSTR,LPCWSTR,LPVOID,UINT32,LPCWSTR);
+#define     GetPrivateProfileStruct WINELIB_NAME_AW(GetPrivateProfileStruct)
 FARPROC16   WINAPI GetProcAddress16(HMODULE16,SEGPTR);
 FARPROC32   WINAPI GetProcAddress32(HMODULE32,LPCSTR);
 #define     GetProcAddress WINELIB_NAME(GetProcAddress)
@@ -7866,6 +7958,9 @@
 UINT32      WINAPI GetProfileInt32W(LPCWSTR,LPCWSTR,INT32);
 #define     GetProfileInt WINELIB_NAME_AW(GetProfileInt)
 INT16       WINAPI GetProfileString16(LPCSTR,LPCSTR,LPCSTR,LPSTR,UINT16);
+INT32       WINAPI GetProfileSection32A(LPCSTR,LPSTR,DWORD);
+INT32       WINAPI GetProfileSection32W(LPCWSTR,LPWSTR,DWORD);
+#define     GetProfileSection WINELIB_NAME_AW(GetProfileSection)
 INT32       WINAPI GetProfileString32A(LPCSTR,LPCSTR,LPCSTR,LPSTR,UINT32);
 INT32       WINAPI GetProfileString32W(LPCWSTR,LPCWSTR,LPCWSTR,LPWSTR,UINT32);
 #define     GetProfileString WINELIB_NAME_AW(GetProfileString)
@@ -8033,6 +8128,9 @@
 void        WINAPI GetWindowRect16(HWND16,LPRECT16);
 void        WINAPI GetWindowRect32(HWND32,LPRECT32);
 #define     GetWindowRect WINELIB_NAME(GetWindowRect)
+INT16       WINAPI GetWindowRgn16(HWND16,HRGN16);
+INT32       WINAPI GetWindowRgn32(HWND32,HRGN32);
+#define     GetWindowRgn WINELIB_NAME(GetWindowRgn)
 UINT16      WINAPI GetWindowsDirectory16(LPSTR,UINT16);
 UINT32      WINAPI GetWindowsDirectory32A(LPSTR,UINT32);
 UINT32      WINAPI GetWindowsDirectory32W(LPWSTR,UINT32);
@@ -8283,7 +8381,7 @@
 HMENU32     WINAPI LoadMenuIndirect32W(LPCVOID);
 #define     LoadMenuIndirect WINELIB_NAME_AW(LoadMenuIndirect)
 HINSTANCE16 WINAPI LoadModule16(LPCSTR,LPVOID);
-DWORD       WINAPI LoadModule32(LPCSTR,LPVOID);
+HINSTANCE32 WINAPI LoadModule32(LPCSTR,LPVOID);
 #define     LoadModule WINELIB_NAME(LoadModule)
 HGLOBAL16   WINAPI LoadResource16(HINSTANCE16,HRSRC16);
 HGLOBAL32   WINAPI LoadResource32(HMODULE32,HRSRC32);
@@ -8546,6 +8644,9 @@
 UINT32      WINAPI RegisterClipboardFormat32A(LPCSTR);
 UINT32      WINAPI RegisterClipboardFormat32W(LPCWSTR);
 #define     RegisterClipboardFormat WINELIB_NAME_AW(RegisterClipboardFormat)
+HRESULT     WINAPI RegisterDragDrop16(HWND16,LPVOID);
+HRESULT     WINAPI RegisterDragDrop32(HWND32,LPVOID);
+#define     RegisterDragDrop WINELIB_NAME(RegisterDragDrop)
 WORD        WINAPI RegisterWindowMessage16(SEGPTR);
 WORD        WINAPI RegisterWindowMessage32A(LPCSTR);
 WORD        WINAPI RegisterWindowMessage32W(LPCWSTR);
@@ -8782,6 +8883,7 @@
 COLORREF    WINAPI SetPixel16(HDC16,INT16,INT16,COLORREF);
 COLORREF    WINAPI SetPixel32(HDC32,INT32,INT32,COLORREF);
 #define     SetPixel WINELIB_NAME(SetPixel)
+BOOL32      WINAPI SetPixelV32(HDC32,INT32,INT32,COLORREF);
 BOOL32      WINAPI SetPixelFormat(HDC32,int,PIXELFORMATDESCRIPTOR*);
 INT16       WINAPI SetPolyFillMode16(HDC16,INT16);
 INT32       WINAPI SetPolyFillMode32(HDC32,INT32);
@@ -8901,6 +9003,9 @@
 BOOL16      WINAPI SetWindowPos16(HWND16,HWND16,INT16,INT16,INT16,INT16,WORD);
 BOOL32      WINAPI SetWindowPos32(HWND32,HWND32,INT32,INT32,INT32,INT32,WORD);
 #define     SetWindowPos WINELIB_NAME(SetWindowPos)
+INT16       WINAPI SetWindowRgn16(HWND16,HRGN16,BOOL16);
+INT32       WINAPI SetWindowRgn32(HWND32,HRGN32,BOOL32);
+#define     SetWindowRgn WINELIB_NAME(SetWindowRgn)
 void        WINAPI SetWindowText16(HWND16,SEGPTR);
 void        WINAPI SetWindowText32A(HWND32,LPCSTR);
 void        WINAPI SetWindowText32W(HWND32,LPCWSTR);
@@ -9057,10 +9162,18 @@
 HWND16      WINAPI WindowFromPoint16(POINT16);
 HWND32      WINAPI WindowFromPoint32(POINT32);
 #define     WindowFromPoint WINELIB_NAME(WindowFromPoint)
+BOOL16      WINAPI WritePrivateProfileSection16(LPCSTR,LPCSTR,LPCSTR);
+BOOL32      WINAPI WritePrivateProfileSection32A(LPCSTR,LPCSTR,LPCSTR);
+BOOL32      WINAPI WritePrivateProfileSection32W(LPCWSTR,LPCWSTR,LPCWSTR);
+#define     WritePrivateProfileSection WINELIB_NAME_AW(WritePrivateProfileSection)
 BOOL16      WINAPI WritePrivateProfileString16(LPCSTR,LPCSTR,LPCSTR,LPCSTR);
 BOOL32      WINAPI WritePrivateProfileString32A(LPCSTR,LPCSTR,LPCSTR,LPCSTR);
 BOOL32      WINAPI WritePrivateProfileString32W(LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR);
 #define     WritePrivateProfileString WINELIB_NAME_AW(WritePrivateProfileString)
+BOOL16      WINAPI WritePrivateProfileStruct16(LPCSTR,LPCSTR,LPVOID,UINT16,LPCSTR);
+BOOL32      WINAPI WritePrivateProfileStruct32A(LPCSTR,LPCSTR,LPVOID,UINT32,LPCSTR);
+BOOL32      WINAPI WritePrivateProfileStruct32W(LPCWSTR,LPCWSTR,LPVOID,UINT32,LPCWSTR);
+#define     WritePrivateProfileStruct WINELIB_NAME_AW(WritePrivateProfileStruct)
 BOOL16      WINAPI WriteProfileString16(LPCSTR,LPCSTR,LPCSTR);
 BOOL32      WINAPI WriteProfileString32A(LPCSTR,LPCSTR,LPCSTR);
 BOOL32      WINAPI WriteProfileString32W(LPCWSTR,LPCWSTR,LPCWSTR);
@@ -9154,9 +9267,11 @@
 HPEN32      WINAPI GetSysColorPen32(INT32);
 INT32       WINAPI LoadMessage32A(HMODULE32,UINT32,WORD,LPSTR,INT32);
 INT32       WINAPI LoadMessage32W(HMODULE32,UINT32,WORD,LPWSTR,INT32);
+UINT32      WINAPI WIN16_GetTempDrive(BYTE);
 SEGPTR      WINAPI WIN16_GlobalLock16(HGLOBAL16);
 SEGPTR      WINAPI WIN16_LockResource16(HGLOBAL16);
 LONG        WINAPI WIN16_hread(HFILE16,SEGPTR,LONG);
+UINT16      WINAPI WIN16_lread(HFILE16,SEGPTR,UINT16);
 INT32       WINAPI lstrncmp32A(LPCSTR,LPCSTR,INT32);
 INT32       WINAPI lstrncmp32W(LPCWSTR,LPCWSTR,INT32);
 INT32       WINAPI lstrncmpi32A(LPCSTR,LPCSTR,INT32);
diff --git a/include/winerror.h b/include/winerror.h
index 12f1727..91db795 100644
--- a/include/winerror.h
+++ b/include/winerror.h
@@ -22,6 +22,9 @@
  */
 #define ERROR_UNKNOWN               99999
 
+#define SEVERITY_SUCCESS    0
+#define SEVERITY_ERROR      1
+
 #define ERROR_SUCCESS               0
 #define ERROR_FILE_NOT_FOUND        2
 #define ERROR_PATH_NOT_FOUND        3
diff --git a/include/wintypes.h b/include/wintypes.h
index b4804ba..895676d 100644
--- a/include/wintypes.h
+++ b/include/wintypes.h
@@ -135,6 +135,7 @@
 DECLARE_HANDLE(HACCEL);
 DECLARE_HANDLE(HBITMAP);
 DECLARE_HANDLE(HBRUSH);
+DECLARE_HANDLE(HCOLORSPACE);
 DECLARE_HANDLE(HCURSOR);
 DECLARE_HANDLE(HDC);
 DECLARE_HANDLE(HDROP);
@@ -243,6 +244,7 @@
 DECL_WINELIB_TYPE(HANDLE)
 DECL_WINELIB_TYPE(HBITMAP)
 DECL_WINELIB_TYPE(HBRUSH)
+DECL_WINELIB_TYPE(HCOLORSPACE)
 DECL_WINELIB_TYPE(HCURSOR)
 DECL_WINELIB_TYPE(HDC)
 DECL_WINELIB_TYPE(HDROP)
diff --git a/include/x11drv.h b/include/x11drv.h
index 0bb9b24..5968388 100644
--- a/include/x11drv.h
+++ b/include/x11drv.h
@@ -98,7 +98,7 @@
 extern BOOL32 X11DRV_PolyPolygon( struct tagDC *dc, LPPOINT32 pt,
 				  LPINT32 counts, UINT32 polygons);
 extern BOOL32 X11DRV_PolyPolyline( struct tagDC *dc, LPPOINT32 pt,
-				  LPINT32 counts, UINT32 polylines);
+				  LPDWORD counts, DWORD polylines);
 
 extern HGDIOBJ32 X11DRV_SelectObject( struct tagDC *dc, HGDIOBJ32 handle );
 
diff --git a/loader/dos/Makefile.in b/loader/dos/Makefile.in
index c605049..67b4c7a 100644
--- a/loader/dos/Makefile.in
+++ b/loader/dos/Makefile.in
@@ -9,7 +9,9 @@
 	module.c \
 	dosvm.c
 
-all: $(MODULE).o dosmod
+PROGRAMS = dosmod
+
+all: $(MODULE).o $(PROGRAMS)
 
 dosmod: dosmod.c
 	$(CC) $(ALLCFLAGS) -o dosmod $<
diff --git a/loader/dos/dosmod.c b/loader/dos/dosmod.c
index b5ad24f..9807ecf 100644
--- a/loader/dos/dosmod.c
+++ b/loader/dos/dosmod.c
@@ -6,18 +6,26 @@
 
 #ifdef linux
 
-/* force dosmod at high addresses */
+/* apparently ELF images are usually loaded high anyway */
+#ifndef __ELF__
+/* if not, force dosmod at high addresses */
 asm(".org 0x110000");
+#endif __ELF__
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <signal.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
 #include <sys/vm86.h>
 #include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/wait.h>
 
 /* FIXME: hack because libc vm86 may be the old syscall version */
 static __inline__ int vm86plus( int func, struct vm86plus_struct *ptr )
@@ -50,16 +58,37 @@
  void*img;
  struct vm86plus_struct VM86;
  int func,ret;
+ off_t fofs=0;
+ pid_t ppid=getppid();
  
 /* fprintf(stderr,"main is at %08lx, file is %s, fd=%d\n",(unsigned long)&main,argv[0],mfd); */
  if (mfd<0) return 1;
 /* Map in our DOS image at the start of the process address space */
- img=mmap(NULL,0x110000,PROT_EXEC|PROT_READ|PROT_WRITE,MAP_FIXED|MAP_SHARED,mfd,0);
+ if (argv[1]) {
+  /* Ulrich Weigand suggested mapping in the DOS image directly from the Wine
+     address space */
+  fofs=atol(argv[1]);
+  /* linux currently only allows mapping a process memory if it's being ptraced */
+  /* Linus doesn't like it, so this probably won't work in the future */
+  /* it doesn't even work for me right now */
+  ptrace(PTRACE_ATTACH,ppid,0,0);
+  kill(ppid,SIGSTOP);
+  waitpid(ppid,NULL,0);
+ }
+ img=mmap(NULL,0x110000,PROT_EXEC|PROT_READ|PROT_WRITE,MAP_FIXED|MAP_SHARED,mfd,fofs);
+ if (argv[1]) {
+  ptrace(PTRACE_DETACH,ppid,0,0);
+  kill(ppid,SIGCONT);
+ }
  if (img==(void*)-1) {
   fprintf(stderr,"DOS memory map failed, error=%s\n",strerror(errno));
+  fprintf(stderr,"in attempt to map %s, offset %08lX, length 110000, to offset 0\n",argv[0],fofs);
   return 1;
  }
 /* fprintf(stderr,"Successfully mapped DOS memory, entering vm86 loop\n"); */
+/* report back to the main program that we're ready */
+ ret=0;
+ write(1,&ret,sizeof(ret));
 /* context exchange loop */
  do {
   if (read(0,&func,sizeof(func))!=sizeof(func)) return 1;
diff --git a/loader/dos/dosvm.c b/loader/dos/dosvm.c
index 3818daa..ec2e91d 100644
--- a/loader/dos/dosvm.c
+++ b/loader/dos/dosvm.c
@@ -2,6 +2,8 @@
  * DOS Virtual Machine
  *
  * Copyright 1998 Ove Kåven
+ *
+ * This code hasn't been completely cleaned up yet.
  */
 
 #ifdef linux
@@ -17,14 +19,16 @@
 #include <sys/stat.h>
 #include "windows.h"
 #include "winbase.h"
+#include "winnt.h"
 #include "msdos.h"
 #include "miscemu.h"
 #include "debug.h"
 #include "module.h"
+#include "task.h"
 #include "ldt.h"
 #include "dosexe.h"
 
-void DOSVM_Dump( LPDOSTASK lpDosTask)
+static void DOSVM_Dump( LPDOSTASK lpDosTask)
 {
  unsigned iofs;
  BYTE*inst;
@@ -48,6 +52,7 @@
  fprintf(stderr,"AX=%04lX CX=%04lX DX=%04lX BX=%04lX\n",REGS.eax,REGS.ebx,REGS.ecx,REGS.edx);
  fprintf(stderr,"SI=%04lX DI=%04lX SP=%04lX BP=%04lX\n",REGS.esi,REGS.edi,REGS.esp,REGS.ebp);
  fprintf(stderr,"CS=%04X DS=%04X ES=%04X SS=%04X\n",REGS.cs,REGS.ds,REGS.es,REGS.ss);
+ fprintf(stderr,"EIP=%04lX EFLAGS=%08lX\n",REGS.eip,REGS.eflags);
 
  iofs=((DWORD)REGS.cs<<4)+REGS.eip;
 #undef REGS
@@ -59,8 +64,10 @@
  exit(0);
 }
 
-int DOSVM_Int(int vect, LPDOSTASK lpDosTask, PCONTEXT context )
+static int DOSVM_Int(int vect, LPDOSTASK lpDosTask, PCONTEXT context )
 {
+ /* we should really map to if1632/wprocs.spec, but not all
+    interrupt handlers are adapted to support our VM yet */
  switch (vect) {
   case 0x20:
    return -1;
@@ -68,21 +75,30 @@
    if (AH_reg(context)==0x4c) return -1;
    DOS3Call(context);
    break;
+  case 0x1a:
+   INT_Int1aHandler(context);
+   break;
+  case 0x2f:
+   INT_Int2fHandler(context);
+   break;
  }
  return 0;
 }
 
+#define CV CP(eax,Eax); CP(ecx,Ecx); CP(edx,Edx); CP(ebx,Ebx); \
+           CP(esi,Esi); CP(edi,Edi); CP(esp,Esp); CP(ebp,Ebp); \
+           CP(cs,SegCs); CP(ds,SegDs); CP(es,SegEs); \
+           CP(ss,SegSs); CP(fs,SegFs); CP(gs,SegGs); \
+           CP(eip,Eip); CP(eflags,EFlags)
+
 int DOSVM_Process( LPDOSTASK lpDosTask )
 {
  CONTEXT context;
  int ret=0;
 
-#define REGS lpDosTask->VM86.regs
- context.Eax=REGS.eax; context.Ecx=REGS.ecx; context.Edx=REGS.edx; context.Ebx=REGS.ebx;
- context.Esi=REGS.esi; context.Edi=REGS.edi; context.Esp=REGS.esp; context.Ebp=REGS.ebp;
- context.SegCs=REGS.cs; context.SegDs=REGS.ds; context.SegEs=REGS.es;
- context.SegSs=REGS.ss; context.SegFs=REGS.fs; context.SegGs=REGS.gs;
- context.Eip=REGS.eip; context.EFlags=REGS.eflags;
+#define CP(x,y) context.y = lpDosTask->VM86.regs.x
+ CV;
+#undef CP
  (void*)V86BASE(&context)=lpDosTask->img;
 
  switch (VM86_TYPE(lpDosTask->fn)) {
@@ -106,13 +122,67 @@
  }
 
  lpDosTask->fn=VM86_ENTER;
- REGS.eax=context.Eax; REGS.ecx=context.Ecx; REGS.edx=context.Edx; REGS.ebx=context.Ebx;
- REGS.esi=context.Esi; REGS.edi=context.Edi; REGS.esp=context.Esp; REGS.ebp=context.Ebp;
- REGS.cs=context.SegCs; REGS.ds=context.SegDs; REGS.es=context.SegEs;
- REGS.ss=context.SegSs; REGS.fs=context.SegFs; REGS.gs=context.SegGs;
- REGS.eip=context.Eip; REGS.eflags=context.EFlags;
-#undef REGS
+#define CP(x,y) lpDosTask->VM86.regs.x = context.y
+ CV;
+#undef CP
  return ret;
 }
 
+int DOSVM_Enter( PCONTEXT context )
+{
+ TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
+ NE_MODULE *pModule = NE_GetPtr( pTask->hModule );
+ LPDOSTASK lpDosTask;
+ int stat;
+
+ GlobalUnlock16( GetCurrentTask() );
+ if (!pModule) {
+  ERR(module,"No task is currently active!\n");
+  return -1;
+ }
+ if (!pModule->lpDosTask) {
+  /* no VM86 (dosmod) task is currently running, start one */
+  if ((lpDosTask = calloc(1, sizeof(DOSTASK))) == NULL)
+    return 0;
+  lpDosTask->img=DOSMEM_MemoryBase(pModule->self);
+  lpDosTask->hModule=pModule->self;
+  stat=MZ_InitTask(lpDosTask);
+  if (stat<32) {
+   free(lpDosTask);
+   return -1;
+  }
+  pModule->lpDosTask = lpDosTask;
+  pModule->dos_image = lpDosTask->img;
+  /* Note: we're leaving it running after this, in case we need it again,
+     as this minimizes the overhead of starting it up every time...
+     it will be killed automatically when the current task terminates */
+ } else lpDosTask=pModule->lpDosTask;
+
+ if (context) {
+#define CP(x,y) lpDosTask->VM86.regs.x = context->y
+  CV;
+#undef CP
+ }
+
+ /* main loop */
+ while ((stat = MZ_RunModule(lpDosTask)) >= 0)
+  if (stat > 0 && DOSVM_Process(lpDosTask) < 0)
+   break;
+
+ if (context) {
+#define CP(x,y) context->y = lpDosTask->VM86.regs.x
+  CV;
+#undef CP
+ }
+ return 0;
+}
+
+#else /* !linux */
+
+int DOSVM_Enter( PCONTEXT context )
+{
+ ERR(module,"DOS realmode not supported on this architecture!\n");
+ return -1;
+}
+
 #endif /* linux */
diff --git a/loader/dos/module.c b/loader/dos/module.c
index 053c2c3..cce308f 100644
--- a/loader/dos/module.c
+++ b/loader/dos/module.c
@@ -2,6 +2,8 @@
  * DOS (MZ) loader
  *
  * Copyright 1998 Ove Kåven
+ *
+ * This code hasn't been completely cleaned up yet.
  */
 
 #ifdef linux
@@ -15,16 +17,8 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#ifdef MZ_USESYSV
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#else
 #include <sys/mman.h>
-#endif
 #include <sys/vm86.h>
-#ifdef MZ_USESYSV
-#include <linux/mm.h> /* FIXME: where else should I fetch the PAGE_SIZE define? */
-#endif
 #include "windows.h"
 #include "winbase.h"
 #include "module.h"
@@ -35,15 +29,14 @@
 #include "debug.h"
 #include "dosexe.h"
 
+/* define this to try mapping through /proc/pid/mem instead of a temp file,
+   but Linus doesn't like mmapping /proc/pid/mem, so it doesn't work for me */
+#undef MZ_MAPSELF
+
 #define BIOS_DATA_SEGMENT 0x40
 #define BIOS_SEGMENT BIOSSEG /* BIOSSEG is defined to 0xf000 in sys/vm86.h */
 #define STUB_SEGMENT BIOS_SEGMENT
-#ifdef MZ_USESYSV
-/* it might be that SYSV supports START_OFFSET 0 after all, haven't checked */
-#define START_OFFSET PAGE_SIZE
-#else
 #define START_OFFSET 0
-#endif
 #define PSP_SIZE 0x10
 
 #define SEG16(ptr,seg) ((LPVOID)((BYTE*)ptr+((DWORD)(seg)<<4)))
@@ -80,7 +73,10 @@
  psp->nextParagraph=0x9FFF;
  /* copy parameters */
  if (cmd) {
+#if 0
+  /* command.com doesn't do this */
   while (*cmd == ' ') cmd++;
+#endif
   psp->cmdLine[0]=strlen(cmd);
   strcpy(psp->cmdLine+1,cmd);
   psp->cmdLine[psp->cmdLine[0]+1]='\r';
@@ -89,11 +85,11 @@
  /* FIXME: integrate the PDB stuff from Wine (loader/task.c) */
 }
 
-static int MZ_LoadImage( HFILE16 hFile, LPCSTR cmdline, LPCSTR env, LPDOSTASK lpDosTask )
+static int MZ_LoadImage( HFILE16 hFile, LPCSTR cmdline, LPCSTR env,
+                         LPDOSTASK lpDosTask, NE_MODULE *pModule )
 {
  IMAGE_DOS_HEADER mz_header;
  DWORD image_start,image_size,min_size,max_size,avail;
- WORD psp_seg,load_seg;
  BYTE*psp_start,*load_start;
  int x;
  SEGPTR reloc;
@@ -111,10 +107,10 @@
 
  /* allocate 1MB+64K shared memory */
  lpDosTask->img_ofs=START_OFFSET;
-#ifdef MZ_USESYSV
- lpDosTask->key=ftok(".",'d'); /* FIXME: this is from my IPC intro doc */
- lpDosTask->shm_id=shmget(lpDosTask->key,0x110000-START_OFFSET,IPC_CREAT|SHM_R|SHM_W);
- lpDosTask->img=shmat(lpDosTask->shm_id,NULL,0);
+#ifdef MZ_MAPSELF
+ lpDosTask->img=VirtualAlloc(NULL,0x110000,MEM_COMMIT,PAGE_READWRITE);
+ /* make sure mmap accepts it */
+ ((char*)lpDosTask->img)[0x10FFFF]=0;
 #else
  tmpnam(lpDosTask->mm_name);
 /* strcpy(lpDosTask->mm_name,"/tmp/mydosimage"); */
@@ -131,6 +127,7 @@
   return 0;
  }
  TRACE(module,"DOS VM86 image mapped at %08lx\n",(DWORD)lpDosTask->img);
+ pModule->dos_image=lpDosTask->img;
 
  /* initialize the memory */
  MZ_InitSystem(lpDosTask->img);
@@ -147,12 +144,12 @@
   return 0;
  }
  if (avail>max_size) avail=max_size;
- psp_start=DOSMEM_GetBlock(lpDosTask->hModule,avail,&psp_seg);
+ psp_start=DOSMEM_GetBlock(lpDosTask->hModule,avail,&lpDosTask->psp_seg);
  if (!psp_start) {
   ERR(module, "error allocating DOS memory\n");
   return 0;
  }
- load_seg=psp_seg+PSP_SIZE;
+ lpDosTask->load_seg=lpDosTask->psp_seg+PSP_SIZE;
  load_start=psp_start+(PSP_SIZE<<4);
  MZ_InitPSP(psp_start, cmdline, env);
 
@@ -169,26 +166,27 @@
  for (x=0; x<mz_header.e_crlc; x++) {
   if (_lread16(hFile,&reloc,sizeof(reloc)) != sizeof(reloc))
    return 11; /* invalid exe */
-  *(WORD*)SEGPTR16(load_start,reloc)+=load_seg;
+  *(WORD*)SEGPTR16(load_start,reloc)+=lpDosTask->load_seg;
  }
 
  /* initialize vm86 struct */
  memset(&lpDosTask->VM86,0,sizeof(lpDosTask->VM86));
- lpDosTask->VM86.regs.cs=load_seg+mz_header.e_cs;
+ lpDosTask->VM86.regs.cs=lpDosTask->load_seg+mz_header.e_cs;
  lpDosTask->VM86.regs.eip=mz_header.e_ip;
- lpDosTask->VM86.regs.ss=load_seg+mz_header.e_ss;
+ lpDosTask->VM86.regs.ss=lpDosTask->load_seg+mz_header.e_ss;
  lpDosTask->VM86.regs.esp=mz_header.e_sp;
- lpDosTask->VM86.regs.ds=psp_seg;
- lpDosTask->VM86.regs.es=psp_seg;
+ lpDosTask->VM86.regs.ds=lpDosTask->psp_seg;
+ lpDosTask->VM86.regs.es=lpDosTask->psp_seg;
  /* hmm, what else do we need? */
 
  return 32;
 }
 
-static int MZ_InitTask( LPDOSTASK lpDosTask )
+int MZ_InitTask( LPDOSTASK lpDosTask )
 {
  int read_fd[2],write_fd[2];
  pid_t child;
+ char *fname,*farg,arg[16],fproc[64];
 
  /* create read pipe */
  if (pipe(read_fd)<0) return 0;
@@ -199,15 +197,36 @@
  lpDosTask->write_pipe=write_fd[1];
  lpDosTask->fn=VM86_ENTER;
  lpDosTask->state=1;
- TRACE(module,"Preparing to load DOS EXE support module: forking\n");
+ /* if we have a mapping file, use it */
+ fname=lpDosTask->mm_name; farg=NULL;
+ if (!fname[0]) {
+  /* otherwise, map our own memory image */
+  sprintf(fproc,"/proc/%d/mem",getpid());
+  sprintf(arg,"%ld",(unsigned long)lpDosTask->img);
+  fname=fproc; farg=arg;
+ }
+
+ TRACE(module,"Preparing to load DOS VM support module: forking\n");
  if ((child=fork())<0) {
   close(write_fd[0]); close(write_fd[1]);
   close(read_fd[0]); close(read_fd[1]); return 0;
  }
  if (child!=0) {
   /* parent process */
+  int ret;
+
   close(read_fd[1]); close(write_fd[0]);
   lpDosTask->task=child;
+  /* wait for child process to signal readiness */
+  do {
+   if (read(lpDosTask->read_pipe,&ret,sizeof(ret))!=sizeof(ret)) {
+    if ((errno==EINTR)||(errno==EAGAIN)) continue;
+    /* failure */
+    ERR(module,"dosmod has failed to initialize\n");
+    return 0;
+   }
+  } while (0);
+  /* all systems are now go */
  } else {
   /* child process */
   close(read_fd[0]); close(write_fd[1]);
@@ -215,9 +234,9 @@
   dup2(write_fd[0],0);      /* stdin */
   dup2(read_fd[1],1);       /* stdout */
   /* now load dosmod */
-  execlp("dosmod",lpDosTask->mm_name,NULL);
-  execl("dosmod",lpDosTask->mm_name,NULL);
-  execl("loader/dos/dosmod",lpDosTask->mm_name,NULL);
+  execlp("dosmod",fname,farg,NULL);
+  execl("dosmod",fname,farg,NULL);
+  execl("loader/dos/dosmod",fname,farg,NULL);
   /* if failure, exit */
   ERR(module,"Failed to spawn dosmod, error=%s\n",strerror(errno));
   exit(1);
@@ -225,8 +244,8 @@
  return 32;
 }
 
-HINSTANCE16 MZ_LoadModule( LPCSTR name, LPCSTR cmdline, 
-                           LPCSTR env, UINT16 show_cmd )
+HINSTANCE16 MZ_CreateProcess( LPCSTR name, LPCSTR cmdline, LPCSTR env, 
+                              LPSTARTUPINFO32A startup, LPPROCESS_INFORMATION info )
 {
  LPDOSTASK lpDosTask;
  HMODULE16 hModule;
@@ -234,7 +253,6 @@
  NE_MODULE *pModule;
  HFILE16 hFile;
  OFSTRUCT ofs;
- PROCESS_INFORMATION info;
  int err;
 
  if ((lpDosTask = calloc(1, sizeof(DOSTASK))) == NULL)
@@ -252,29 +270,41 @@
  pModule->lpDosTask = lpDosTask;
  
  lpDosTask->img=NULL; lpDosTask->mm_name[0]=0; lpDosTask->mm_fd=-1;
- err = MZ_LoadImage( hFile, cmdline, env, lpDosTask );
+ err = MZ_LoadImage( hFile, cmdline, env, lpDosTask, pModule );
  _lclose16(hFile);
+ pModule->dos_image = lpDosTask->img;
  if (err<32) {
-  if (lpDosTask->img!=NULL) munmap(lpDosTask->img,0x110000-START_OFFSET);
-  if (lpDosTask->mm_fd>=0) close(lpDosTask->mm_fd);
-  if (lpDosTask->mm_name[0]!=0) unlink(lpDosTask->mm_name);
+  if (lpDosTask->mm_name[0]!=0) {
+   if (lpDosTask->img!=NULL) munmap(lpDosTask->img,0x110000-START_OFFSET);
+   if (lpDosTask->mm_fd>=0) close(lpDosTask->mm_fd);
+   unlink(lpDosTask->mm_name);
+  } else
+   if (lpDosTask->img!=NULL) VirtualFree(lpDosTask->img,0x110000,MEM_RELEASE);
   return err;
  }
- MZ_InitTask( lpDosTask );
+ err = MZ_InitTask( lpDosTask );
+ if (lpDosTask->mm_name[0]!=0) {
+  /* we unlink the temp file here to avoid leaving a mess in /tmp
+     if/when Wine crashes; the mapping still remains open, though */
+  unlink(lpDosTask->mm_name);
+ }
+ if (err<32) {
+  MZ_KillModule( lpDosTask );
+  /* FIXME: cleanup hModule */
+  return err;
+ }
 
  hInstance = NE_CreateInstance(pModule, NULL, (cmdline == NULL));
- PROCESS_Create( pModule, cmdline, env, hInstance, 0, show_cmd, &info );
- /* we don't need the handles for now */
- CloseHandle( info.hThread );
- CloseHandle( info.hProcess );
+ PROCESS_Create( pModule, cmdline, env, hInstance, 0, startup, info );
  return hInstance;
 }
 
 void MZ_KillModule( LPDOSTASK lpDosTask )
 {
- munmap(lpDosTask->img,0x110000-START_OFFSET);
- close(lpDosTask->mm_fd);
- unlink(lpDosTask->mm_name);
+ if (lpDosTask->mm_name[0]!=0) {
+  munmap(lpDosTask->img,0x110000-START_OFFSET);
+  close(lpDosTask->mm_fd);
+ } else VirtualFree(lpDosTask->img,0x110000,MEM_RELEASE);
  close(lpDosTask->read_pipe);
  close(lpDosTask->write_pipe);
  kill(lpDosTask->task,SIGTERM);
@@ -310,4 +340,13 @@
  return 0;
 }
 
-#endif /* linux */
+#else /* !linux */
+
+HINSTANCE16 MZ_CreateProcess( LPCSTR name, LPCSTR cmdline, LPCSTR env, 
+                              LPSTARTUPINFO32A startup, LPPROCESS_INFORMATION info )
+{
+ WARN(module,"DOS executables not supported on this architecture\n");
+ return (HMODULE16)11;  /* invalid exe */
+}
+
+#endif
diff --git a/loader/module.c b/loader/module.c
index 21d5665..0804df3 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -11,6 +11,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 #include "windows.h"
+#include "winerror.h"
 #include "class.h"
 #include "file.h"
 #include "global.h"
@@ -284,16 +285,11 @@
 
 
 /**********************************************************************
- *	    MODULE_Load
- *
- * Implementation of LoadModule().
- *
- * cmd_line must contain the whole command-line, including argv[0] (and
- * without a preceding length byte).
- * If cmd_line is NULL, the module is loaded as a library even if it is a .exe
+ *	    NE_CreateProcess
  */
-HINSTANCE16 MODULE_Load( LPCSTR name, BOOL32 implicit,
-                         LPCSTR cmd_line, LPCSTR env, UINT32 show_cmd )
+static HINSTANCE16 NE_CreateProcess( LPCSTR name, LPCSTR cmd_line, LPCSTR env, 
+                                     LPSTARTUPINFO32A startup, 
+                                     LPPROCESS_INFORMATION info )
 {
     HMODULE16 hModule;
     HINSTANCE16 hInstance, hPrevInstance;
@@ -305,38 +301,24 @@
         lstrcpyn32A( ofs.szPathName, name, sizeof(ofs.szPathName) );
         if ((hModule = MODULE_CreateDummyModule( &ofs )) < 32) return hModule;
         pModule = (NE_MODULE *)GlobalLock16( hModule );
-        hInstance = NE_CreateInstance( pModule, &hPrevInstance,
-                                       (cmd_line == NULL) );
+        hInstance = NE_CreateInstance( pModule, &hPrevInstance, FALSE );
     }
     else
     {
-        hInstance = NE_LoadModule( name, &hPrevInstance, implicit,
-                                 (cmd_line == NULL) );
-        if ((hInstance == 21) && cmd_line)
-            return PE_LoadModule( name, cmd_line, env, show_cmd );
-#ifdef linux
-        if (hInstance == 11)
-            return MZ_LoadModule(name, cmd_line, env, show_cmd );
-#endif
+        hInstance = NE_LoadModule( name, &hPrevInstance, FALSE, FALSE );
+        pModule = hInstance >= 32 ? NE_GetPtr( hInstance ) : NULL;
     }
 
     /* Create a task for this instance */
 
-    if (hInstance < 32) return hInstance;
-    pModule = NE_GetPtr( hInstance );
-    if (cmd_line && !(pModule->flags & NE_FFLAGS_LIBMODULE))
+    if (pModule && !(pModule->flags & NE_FFLAGS_LIBMODULE))
     {
         PDB32 *pdb;
-        PROCESS_INFORMATION info;
 
 	pModule->flags |= NE_FFLAGS_GUI;
 
         pdb = PROCESS_Create( pModule, cmd_line, env, hInstance,
-                              hPrevInstance, show_cmd, &info );
-        /* we don't need the handles for now */
-        CloseHandle( info.hThread );
-        CloseHandle( info.hProcess );
-        if (pdb && (GetNumTasks() > 1)) Yield16();
+                              hPrevInstance, startup, info );
     }
 
     return hInstance;
@@ -349,77 +331,239 @@
 HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
 {
     LOADPARAMS *params;
-    LPSTR cmd_line, new_cmd_line;
-    UINT16 show_cmd = 0;
-    LPCVOID env = NULL;
+    LOADPARAMS32 params32;
     HINSTANCE16 hInstance;
+    LPSTR cmd_line;
 
     if (!paramBlock || (paramBlock == (LPVOID)-1))
         return LoadLibrary16( name );
 
+    /* Transfer arguments to 32-bit param-block */
     params = (LOADPARAMS *)paramBlock;
-    cmd_line = (LPSTR)PTR_SEG_TO_LIN( params->cmdLine );
-    /* PowerPoint passes NULL as showCmd */
-    if (params->showCmd)
-        show_cmd = *((UINT16 *)PTR_SEG_TO_LIN(params->showCmd)+1);
+    memset( &params32, '\0', sizeof(params32) );
 
+    cmd_line = (LPSTR)PTR_SEG_TO_LIN( params->cmdLine );
     if (!cmd_line) cmd_line = "";
     else if (*cmd_line) cmd_line++;  /* skip the length byte */
 
-    if (!(new_cmd_line = HeapAlloc( GetProcessHeap(), 0,
-                                    strlen(cmd_line) + strlen(name) + 2 )))
+    if (!(params32.lpCmdLine = HeapAlloc( GetProcessHeap(), 0,
+                                          strlen(cmd_line)+strlen(name)+2 )))
         return 0;
-    strcpy( new_cmd_line, name );
-    strcat( new_cmd_line, " " );
-    strcat( new_cmd_line, cmd_line );
+    strcpy( params32.lpCmdLine, name );
+    strcat( params32.lpCmdLine, " " );
+    strcat( params32.lpCmdLine, cmd_line );
 
-    if (params->hEnvironment) env = GlobalLock16( params->hEnvironment );
-    hInstance = MODULE_Load( name, FALSE, new_cmd_line, env, show_cmd );
+    if (params->hEnvironment)
+        params32.lpEnvAddress = GlobalLock16( params->hEnvironment );
+    if (params->showCmd)
+        params32.lpCmdShow = PTR_SEG_TO_LIN( params->showCmd );
+
+    /* Call LoadModule32 */
+    hInstance = LoadModule32( name, &params32 );
+
+    /* Clean up */
     if (params->hEnvironment) GlobalUnlock16( params->hEnvironment );
-    HeapFree( GetProcessHeap(), 0, new_cmd_line );
+    HeapFree( GetProcessHeap(), 0, params32.lpCmdLine );
+
     return hInstance;
 }
 
 /**********************************************************************
  *	    LoadModule32    (KERNEL32.499)
- *
- * FIXME
- *
- *  This should get implemented via CreateProcess -- MODULE_Load
- *  is resolutely 16-bit.
  */
-DWORD WINAPI LoadModule32( LPCSTR name, LPVOID paramBlock ) 
+HINSTANCE32 WINAPI LoadModule32( LPCSTR name, LPVOID paramBlock ) 
 {
     LOADPARAMS32 *params = (LOADPARAMS32 *)paramBlock;
-#if 0
-  STARTUPINFO st;
-  PROCESSINFORMATION pi;
-  st.cb = sizeof(STARTUPINFO);
-  st.wShowWindow = p->lpCmdShow[2] ; WRONG
+    PROCESS_INFORMATION info;
+    STARTUPINFO32A startup;
+    HINSTANCE32 hInstance;
+    PDB32 *pdb;
+    TDB *tdb;
 
-  BOOL32 ret = CreateProcess32A( name, p->lpCmdLine, 
-				 NULL, NULL, FALSE, 0, p->lpEnvAddress,
-				 NULL, &st, &pi);
-  if (!ret) {
-    /*    handle errors appropriately */
-  }
-  CloseHandle32(pi.hProcess);
-  CloseHandle32(pi.hThread); 
+    memset( &startup, '\0', sizeof(startup) );
+    startup.cb = sizeof(startup);
+    startup.dwFlags = STARTF_USESHOWWINDOW;
+    startup.wShowWindow = params->lpCmdShow? params->lpCmdShow[1] : 0;
 
-#else
-  return MODULE_Load( name, FALSE, params->lpCmdLine, params->lpEnvAddress, 
-                        *((UINT16 *)params->lpCmdShow + 1) );
-#endif
+    if (!CreateProcess32A( name, params->lpCmdLine,
+                           NULL, NULL, FALSE, 0, params->lpEnvAddress,
+                           NULL, &startup, &info ))
+        return GetLastError();  /* guaranteed to be < 32 */
+    
+    /* Get hInstance from process */
+    pdb = PROCESS_IdToPDB( info.dwProcessId );
+    tdb = pdb? (TDB *)GlobalLock16( pdb->task ) : NULL;
+    hInstance = tdb? tdb->hInstance : 0;
+
+    /* Close off the handles */
+    CloseHandle( info.hThread );
+    CloseHandle( info.hProcess );
+
+    return hInstance;
 }
 
+/**********************************************************************
+ *       CreateProcess32A          (KERNEL32.171)
+ */
+BOOL32 WINAPI CreateProcess32A( LPCSTR lpApplicationName, LPSTR lpCommandLine, 
+                                LPSECURITY_ATTRIBUTES lpProcessAttributes,
+                                LPSECURITY_ATTRIBUTES lpThreadAttributes,
+                                BOOL32 bInheritHandles, DWORD dwCreationFlags,
+                                LPVOID lpEnvironment, LPCSTR lpCurrentDirectory,
+                                LPSTARTUPINFO32A lpStartupInfo,
+                                LPPROCESS_INFORMATION lpProcessInfo )
+{
+    HINSTANCE16 hInstance;
+    LPCSTR cmdline;
+    PDB32 *pdb;
+    char name[256];
+
+    /* Get name and command line */
+
+    if (!lpApplicationName && !lpCommandLine)
+    {
+        SetLastError( ERROR_FILE_NOT_FOUND );
+        return FALSE;
+    }
+
+    cmdline = lpCommandLine? lpCommandLine : lpApplicationName;
+
+    if (lpApplicationName)
+        lstrcpyn32A(name, lpApplicationName, sizeof(name) - 4);
+    else
+    {
+        char *ptr = strchr(lpCommandLine, ' ');
+        int len = (ptr? ptr-lpCommandLine : strlen(lpCommandLine)) + 1;
+        if (len > sizeof(name) - 4) len = sizeof(name) - 4;
+        lstrcpyn32A(name, lpCommandLine, len);
+    }
+
+    if (!strchr(name, '\\') && !strchr(name, '.'))
+        strcat(name, ".exe");
+
+
+    /* Warn if unsupported features are used */
+
+    if (lpProcessAttributes)
+        FIXME(module, "(%s,...): lpProcessAttributes ignored\n", name);
+    if (lpThreadAttributes)
+        FIXME(module, "(%s,...): lpThreadAttributes ignored\n", name);
+    if (bInheritHandles)
+        FIXME(module, "(%s,...): bInheritHandles ignored\n", name);
+    if (dwCreationFlags & DEBUG_PROCESS)
+        FIXME(module, "(%s,...): DEBUG_PROCESS ignored\n", name);
+    if (dwCreationFlags & DEBUG_ONLY_THIS_PROCESS)
+        FIXME(module, "(%s,...): DEBUG_ONLY_THIS_PROCESS ignored\n", name);
+    if (dwCreationFlags & CREATE_SUSPENDED)
+        FIXME(module, "(%s,...): CREATE_SUSPENDED ignored\n", name);
+    if (dwCreationFlags & DETACHED_PROCESS)
+        FIXME(module, "(%s,...): DETACHED_PROCESS ignored\n", name);
+    if (dwCreationFlags & CREATE_NEW_CONSOLE)
+        FIXME(module, "(%s,...): CREATE_NEW_CONSOLE ignored\n", name);
+    if (dwCreationFlags & NORMAL_PRIORITY_CLASS)
+        FIXME(module, "(%s,...): NORMAL_PRIORITY_CLASS ignored\n", name);
+    if (dwCreationFlags & IDLE_PRIORITY_CLASS)
+        FIXME(module, "(%s,...): IDLE_PRIORITY_CLASS ignored\n", name);
+    if (dwCreationFlags & HIGH_PRIORITY_CLASS)
+        FIXME(module, "(%s,...): HIGH_PRIORITY_CLASS ignored\n", name);
+    if (dwCreationFlags & REALTIME_PRIORITY_CLASS)
+        FIXME(module, "(%s,...): REALTIME_PRIORITY_CLASS ignored\n", name);
+    if (dwCreationFlags & CREATE_NEW_PROCESS_GROUP)
+        FIXME(module, "(%s,...): CREATE_NEW_PROCESS_GROUP ignored\n", name);
+    if (dwCreationFlags & CREATE_UNICODE_ENVIRONMENT)
+        FIXME(module, "(%s,...): CREATE_UNICODE_ENVIRONMENT ignored\n", name);
+    if (dwCreationFlags & CREATE_SEPARATE_WOW_VDM)
+        FIXME(module, "(%s,...): CREATE_SEPARATE_WOW_VDM ignored\n", name);
+    if (dwCreationFlags & CREATE_SHARED_WOW_VDM)
+        FIXME(module, "(%s,...): CREATE_SHARED_WOW_VDM ignored\n", name);
+    if (dwCreationFlags & CREATE_DEFAULT_ERROR_MODE)
+        FIXME(module, "(%s,...): CREATE_DEFAULT_ERROR_MODE ignored\n", name);
+    if (dwCreationFlags & CREATE_NO_WINDOW)
+        FIXME(module, "(%s,...): CREATE_NO_WINDOW ignored\n", name);
+    if (dwCreationFlags & PROFILE_USER)
+        FIXME(module, "(%s,...): PROFILE_USER ignored\n", name);
+    if (dwCreationFlags & PROFILE_KERNEL)
+        FIXME(module, "(%s,...): PROFILE_KERNEL ignored\n", name);
+    if (dwCreationFlags & PROFILE_SERVER)
+        FIXME(module, "(%s,...): PROFILE_SERVER ignored\n", name);
+    if (lpCurrentDirectory)
+        FIXME(module, "(%s,...): lpCurrentDirectory %s ignored\n", 
+                      name, lpCurrentDirectory);
+    if (lpStartupInfo->lpDesktop)
+        FIXME(module, "(%s,...): lpStartupInfo->lpDesktop %s ignored\n", 
+                      name, lpStartupInfo->lpDesktop);
+    if (lpStartupInfo->lpTitle)
+        FIXME(module, "(%s,...): lpStartupInfo->lpTitle %s ignored\n", 
+                      name, lpStartupInfo->lpTitle);
+    if (lpStartupInfo->dwFlags & STARTF_USECOUNTCHARS)
+        FIXME(module, "(%s,...): STARTF_USECOUNTCHARS (%ld,%ld) ignored\n", 
+                      name, lpStartupInfo->dwXCountChars, lpStartupInfo->dwYCountChars);
+    if (lpStartupInfo->dwFlags & STARTF_USEFILLATTRIBUTE)
+        FIXME(module, "(%s,...): STARTF_USEFILLATTRIBUTE %lx ignored\n", 
+                      name, lpStartupInfo->dwFillAttribute);
+    if (lpStartupInfo->dwFlags & STARTF_RUNFULLSCREEN)
+        FIXME(module, "(%s,...): STARTF_RUNFULLSCREEN ignored\n", name);
+    if (lpStartupInfo->dwFlags & STARTF_FORCEONFEEDBACK)
+        FIXME(module, "(%s,...): STARTF_FORCEONFEEDBACK ignored\n", name);
+    if (lpStartupInfo->dwFlags & STARTF_FORCEOFFFEEDBACK)
+        FIXME(module, "(%s,...): STARTF_FORCEOFFFEEDBACK ignored\n", name);
+    if (lpStartupInfo->dwFlags & STARTF_USEHOTKEY)
+        FIXME(module, "(%s,...): STARTF_USEHOTKEY ignored\n", name);
+
+
+    /* Try NE (or winelib) module */
+    hInstance = NE_CreateProcess( name, cmdline, lpEnvironment, 
+                                  lpStartupInfo, lpProcessInfo );
+
+    /* Try PE module */
+    if (hInstance == 21)
+        hInstance = PE_CreateProcess( name, cmdline, lpEnvironment, 
+                                      lpStartupInfo, lpProcessInfo );
+
+    /* Try DOS module */
+#ifdef linux
+    if (hInstance == 11)
+        hInstance = MZ_CreateProcess( name, cmdline, lpEnvironment, 
+                                      lpStartupInfo, lpProcessInfo );
+#endif
+
+    if (hInstance < 32)
+    {
+        SetLastError( hInstance );
+        return FALSE;
+    }
+
+    /* Get hTask from process and start the task */
+    pdb = PROCESS_IdToPDB( lpProcessInfo->dwProcessId );
+    if (pdb) TASK_StartTask( pdb->task );
+
+    return TRUE;
+}
+
+/**********************************************************************
+ *       CreateProcess32W          (KERNEL32.172)
+ */
+BOOL32 WINAPI CreateProcess32W( LPCWSTR lpApplicationName, LPWSTR lpCommandLine, 
+                                LPSECURITY_ATTRIBUTES lpProcessAttributes,
+                                LPSECURITY_ATTRIBUTES lpThreadAttributes,
+                                BOOL32 bInheritHandles, DWORD dwCreationFlags,
+                                LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory,
+                                LPSTARTUPINFO32W lpStartupInfo,
+                                LPPROCESS_INFORMATION lpProcessInfo )
+{
+    FIXME(win32, "(%s,%s,...): stub\n", debugstr_w(lpApplicationName),
+                 debugstr_w(lpCommandLine));
+
+    /* make from lcc uses system as fallback if CreateProcess returns
+       FALSE, so return false */
+    return FALSE;
+}
 
 /***********************************************************************
  *              GetModuleHandle         (KERNEL32.237)
  */
 HMODULE32 WINAPI GetModuleHandle32A(LPCSTR module)
 {
-
-    TRACE(win32, "%s\n", module ? module : "NULL");
     if (module == NULL)
     	return PROCESS_Current()->exe_modref->module;
     else
@@ -582,10 +726,21 @@
     char *p, filename[256];
     static int use_load_module = 1;
     int  spacelimit = 0, exhausted = 0;
+    LOADPARAMS32 params;
+    UINT16 paramCmdShow[2];
 
     if (!lpCmdLine)
         return 2;  /* File not found */
 
+    /* Set up LOADPARAMS32 buffer for LoadModule32 */
+
+    memset( &params, '\0', sizeof(params) );
+    params.lpCmdLine    = (LPSTR)lpCmdLine;
+    params.lpCmdShow    = paramCmdShow;
+    params.lpCmdShow[0] = 2;
+    params.lpCmdShow[1] = nCmdShow;
+
+
     /* Keep trying to load a file by trying different filenames; e.g.,
        for the cmdline "abcd efg hij", try "abcd" with args "efg hij",
        then "abcd efg" with arg "hij", and finally "abcd efg hij" with
@@ -625,7 +780,7 @@
 	{
 	    /* Winelib: Use LoadModule() only for the program itself */
 	    if (__winelib) use_load_module = 0;
-            handle = MODULE_Load( filename, FALSE, lpCmdLine, NULL, nCmdShow );
+            handle = LoadModule32( filename, &params );
 	    if (handle == 2)  /* file not found */
 	    {
 		/* Check that the original file name did not have a suffix */
@@ -635,8 +790,7 @@
 		{
 		    p = filename + strlen(filename);
 		    strcpy( p, ".exe" );
-                    handle = MODULE_Load( filename, FALSE, lpCmdLine,
-                                          NULL, nCmdShow );
+                    handle = LoadModule32( filename, &params );
                     *p = '\0';  /* Remove extension */
 		}
 	    }
diff --git a/loader/ne/module.c b/loader/ne/module.c
index c085678..fb3b168 100644
--- a/loader/ne/module.c
+++ b/loader/ne/module.c
@@ -19,6 +19,7 @@
 #include "process.h"
 #include "toolhelp.h"
 #include "snoop.h"
+#include "stackframe.h"
 #include "debug.h"
 
 FARPROC16 (*fnSNOOP16_GetProcAddress16)(HMODULE16,DWORD,FARPROC16) = NULL;
@@ -744,6 +745,8 @@
     {
         HINSTANCE16 prev;
         pModule = NE_GetPtr( hModule );
+        if ( pModule->module32 ) return (HINSTANCE16)21;
+
         hInstance = NE_CreateInstance( pModule, &prev, lib_only );
         if (hInstance != prev)  /* not a library */
             NE_LoadSegment( pModule, pModule->dgroup );
@@ -1115,3 +1118,55 @@
     lpme->wNext = hModule;
     return ModuleNext( lpme );
 }
+
+/***************************************************************************
+ *		MapHModuleLS			(KERNEL32.520)
+ */
+HMODULE16 WINAPI MapHModuleLS(HMODULE32 hmod) {
+	NE_MODULE	*pModule;
+
+	if (!hmod)
+		return ((TDB*)GlobalLock16(GetCurrentTask()))->hInstance;
+	if (!HIWORD(hmod))
+		return hmod; /* we already have a 16 bit module handle */
+	pModule = (NE_MODULE*)GlobalLock16(hFirstModule);
+	while (pModule)  {
+		if (pModule->module32 == hmod)
+			return pModule->self;
+		pModule = (NE_MODULE*)GlobalLock16(pModule->next);
+	}
+	return 0;
+}
+
+/***************************************************************************
+ *		MapHModuleSL			(KERNEL32.521)
+ */
+HMODULE32 WINAPI MapHModuleSL(HMODULE16 hmod) {
+	NE_MODULE	*pModule;
+
+	if (!hmod) {
+		TDB *pTask = (TDB*)GlobalLock16(GetCurrentTask());
+
+		hmod = pTask->hInstance;
+	}
+	pModule = (NE_MODULE*)GlobalLock16(hmod);
+	if (	(pModule->magic!=IMAGE_OS2_SIGNATURE)	||
+		!(pModule->flags & NE_FFLAGS_WIN32)
+	)
+		return 0;
+	return pModule->module32;
+}
+
+/***************************************************************************
+ *		MapHInstLS			(KERNEL32.516)
+ */
+REGS_ENTRYPOINT(MapHInstLS) {
+	EAX_reg(context) = MapHModuleLS(EAX_reg(context));
+}
+
+/***************************************************************************
+ *		MapHInstLS			(KERNEL32.518)
+ */
+REGS_ENTRYPOINT(MapHInstSL) {
+	EAX_reg(context) = MapHModuleSL(EAX_reg(context));
+}
diff --git a/loader/ne/resource.c b/loader/ne/resource.c
index c5d3fce..90fb416 100644
--- a/loader/ne/resource.c
+++ b/loader/ne/resource.c
@@ -374,7 +374,7 @@
  */
 INT16 WINAPI AccessResource16( HINSTANCE16 hModule, HRSRC16 hRsrc )
 {
-    HFILE32 fd;
+    HFILE16 fd;
 
     NE_MODULE *pModule = NE_GetPtr( hModule );
     if (!pModule || !pModule->res_table || !hRsrc) return -1;
@@ -383,11 +383,11 @@
 
     assert( !__winelib );  /* Can't use Win16 resource functions in Winelib */
 
-    if ((fd = _lopen32( NE_MODULE_NAME(pModule), OF_READ )) != -1)
+    if ((fd = _lopen16( NE_MODULE_NAME(pModule), OF_READ )) != -1)
     {
         WORD sizeShift = *(WORD *)((char *)pModule + pModule->res_table);
         NE_NAMEINFO *pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc);
-        _llseek32( fd, (int)pNameInfo->offset << sizeShift, SEEK_SET );
+        _llseek16( fd, (int)pNameInfo->offset << sizeShift, SEEK_SET );
     }
     return fd;
 }
diff --git a/loader/pe_image.c b/loader/pe_image.c
index 76dc87e..8ef9b73 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -827,8 +827,9 @@
  * FIXME: this function should use PE_LoadLibraryEx32A, but currently can't
  * due to the PROCESS_Create stuff.
  */
-HINSTANCE16 PE_LoadModule( LPCSTR name, LPCSTR cmd_line,
-                           LPCSTR env, UINT16 show_cmd )
+HINSTANCE16 PE_CreateProcess( LPCSTR name, LPCSTR cmd_line,
+                              LPCSTR env, LPSTARTUPINFO32A startup,
+                              LPPROCESS_INFORMATION info )
 {
     HMODULE16 hModule16;
     HMODULE32 hModule32;
@@ -836,8 +837,8 @@
     NE_MODULE *pModule;
     HFILE32 hFile;
     OFSTRUCT ofs;
-    THDB *thdb = THREAD_Current();
     PDB32 *process;
+    TDB *pTask;
     WINE_MODREF	*wm;
 
     if ((hFile = OpenFile32( name, &ofs, OF_READ )) == HFILE_ERROR32)
@@ -850,21 +851,13 @@
     pModule->module32 = hModule32 = PE_LoadImage( hFile );
     if (hModule32 < 32) return 21;
 
-    hInstance = NE_CreateInstance( pModule, NULL, (cmd_line == NULL) );
-    if (cmd_line &&
-        !(PE_HEADER(hModule32)->FileHeader.Characteristics & IMAGE_FILE_DLL))
-    {
-        PROCESS_INFORMATION info;
-        PDB32 *pdb = PROCESS_Create( pModule, cmd_line, env,
-                                     hInstance, 0, show_cmd, &info );
-        TDB *pTask = (TDB *)GlobalLock16( pdb->task );
-        thdb = pTask->thdb;
-        /* we don't need the handles for now */
-        CloseHandle( info.hThread );
-        CloseHandle( info.hProcess );
-    }
+    if (PE_HEADER(hModule32)->FileHeader.Characteristics & IMAGE_FILE_DLL)
+        return 11;
 
-    process = thdb->process;
+    hInstance = NE_CreateInstance( pModule, NULL, FALSE );
+    process = PROCESS_Create( pModule, cmd_line, env,
+                              hInstance, 0, startup, info );
+    pTask = (TDB *)GlobalLock16( process->task );
 
     wm=(WINE_MODREF*)HeapAlloc(process->heap,HEAP_ZERO_MEMORY,sizeof(*wm));
     wm->type = MODULE32_PE;
@@ -878,8 +871,10 @@
         return 0;
     }
     pModule->module32 = wm->module;
+
     /* FIXME: Yuck. Is there no other good place to do that? */
-    PE_InitTls( thdb );
+    PE_InitTls( pTask->thdb );
+
     return hInstance;
 }
 
@@ -916,7 +911,7 @@
     if ((PE_HEADER(wm->module)->FileHeader.Characteristics & IMAGE_FILE_DLL) &&
         (PE_HEADER(wm->module)->OptionalHeader.AddressOfEntryPoint)
     ) {
-        FARPROC32 entry = (FARPROC32)RVA_PTR( wm->module,
+        DWORD (CALLBACK *entry)(HMODULE32,DWORD,LPVOID) = (void*)RVA_PTR( wm->module,
                                           OptionalHeader.AddressOfEntryPoint );
         TRACE(relay, "CallTo32(entryproc=%p,module=%08x,type=%ld,res=%p)\n",
                        entry, wm->module, type, lpReserved );
diff --git a/loader/resource.c b/loader/resource.c
index bff00b9..798b8a5 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -66,7 +66,7 @@
  */
 HRSRC32 WINAPI FindResourceEx32W( HMODULE32 hModule, LPCWSTR name,
                                   LPCWSTR type, WORD lang )
-{
+{	HRSRC32 ret;
     WINE_MODREF	*wm = MODULE32_LookupHMODULE(PROCESS_Current(),hModule);
     HRSRC32	hrsrc;
 
@@ -83,7 +83,10 @@
     if (wm) {
     	switch (wm->type) {
 	case MODULE32_PE:
-	    return PE_FindResourceEx32W(wm,name,type,lang);
+	    ret =  PE_FindResourceEx32W(wm,name,type,lang);
+        if ( ret==0 )
+          ERR(resource,"%s not found!\n",debugres_w (name));
+	    return ret;
 	default:
 	    ERR(module,"unknown module type %d\n",wm->type);
 	    break;
@@ -229,6 +232,7 @@
 {
     HRSRC32 hRsrc;
     HACCEL32 hRetval;
+    DWORD size;
 
     if (HIWORD(lpTableName))
         TRACE(accel, "%p '%s'\n",
@@ -244,6 +248,13 @@
     }
     else {
       hRetval = LoadResource32( instance, hRsrc );
+      size = SizeofResource32( instance, hRsrc );
+      if(size>=sizeof(ACCEL32))
+      {
+	LPACCEL32 accel_table = (LPACCEL32) hRetval;
+	/* mark last element as such - sometimes it is not marked in image */
+	accel_table[size/sizeof(ACCEL32)-1].fVirt |= 0x80;
+      }
     }
 
     TRACE(accel, "returning HACCEL 0x%x\n", hRsrc);
diff --git a/loader/signal.c b/loader/signal.c
index 0023c65..c626721 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -34,9 +34,6 @@
 #include "sig_context.h"
 #include "winsock.h"
 
-/* Global variable to save %fs register while in 16-bit code */
-WORD CALLTO16_Current_fs;
-
 /* Linux sigaction function */
 
 #if defined(linux) && defined(__i386__)
diff --git a/loader/task.c b/loader/task.c
index 7d1814d..099333e 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -6,6 +6,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <assert.h>
 
 #include "windows.h"
 #include "user.h"
@@ -55,6 +56,9 @@
 
 static void TASK_YieldToSystem(TDB*);
 
+extern BOOL32 THREAD_InitDone;
+
+
 /***********************************************************************
  *	     TASK_InstallTHHook
  */
@@ -78,7 +82,6 @@
     return (hFirstTask != hTask) ? hFirstTask : 0; 
 }
 
-
 /***********************************************************************
  *           TASK_LinkTask
  */
@@ -222,8 +225,7 @@
  */
 static void TASK_CallToStart(void)
 {
-    int exit_code = 1;
-    TDB *pTask = (TDB *)GlobalLock16( hCurrentTask );
+    TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
     NE_MODULE *pModule = NE_GetPtr( pTask->hModule );
     SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
 
@@ -237,7 +239,11 @@
     {
         /* FIXME: all this is an ugly hack */
 
-        FARPROC32 entry = (FARPROC32)RVA_PTR( PROCESS_Current()->exe_modref->module, OptionalHeader.AddressOfEntryPoint );
+        LPTHREAD_START_ROUTINE entry = (LPTHREAD_START_ROUTINE)
+                RVA_PTR(pModule->module32, OptionalHeader.AddressOfEntryPoint);
+        DWORD size = PE_HEADER(pModule->module32)->OptionalHeader.SizeOfStackReserve;
+        DWORD id;
+        THDB *thdb;
 
         pTask->userhandler = (USERSIGNALPROC)&USER_SignalProc;
         if (pModule->heap_size)
@@ -246,22 +252,27 @@
         InitApp( pTask->hModule );
         PE_InitializeDLLs( PROCESS_Current(), DLL_PROCESS_ATTACH, (LPVOID)-1 );
         TRACE(relay, "(entryproc=%p)\n", entry );
-        exit_code = entry();
-        TASK_KillCurrentTask( exit_code );
-    }
-#ifdef linux
-    else if (pModule->lpDosTask)
-    {
-        int stat;
 
-        while ((stat = MZ_RunModule(pModule->lpDosTask)) >= 0)
-            if (stat > 0 && DOSVM_Process(pModule->lpDosTask) < 0)
-                break;
+#if 1
+        ExitProcess( entry(NULL) );
+#else
+        CreateThread( NULL, size, entry, NULL, 0, &id );
+        thdb = THREAD_ID_TO_THDB( id );
 
-        MZ_KillModule(pModule->lpDosTask);
-        TASK_KillCurrentTask( 0 );
-    }
+        while ( thdb->exit_code == 0x103 )
+        {
+            WaitEvent( 0 );
+            QUEUE_Signal( pTask->hSelf );
+        }
+
+        ExitProcess( thdb->exit_code );
 #endif
+    }
+    else if (pModule->dos_image)
+    {
+        DOSVM_Enter( NULL );
+        ExitProcess( 0 );
+    }
     else
     {
         /* Registers at initialization must be:
@@ -295,13 +306,17 @@
         Callbacks->CallRegisterShortProc( &context, 0 );
         /* This should never return */
         ERR( task, "Main program returned! (should never happen)\n" );
-        TASK_KillCurrentTask( 1 );
+        ExitProcess( 1 );
     }
 }
 
 
 /***********************************************************************
  *           TASK_Create
+ *
+ * NOTE: This routine might be called by a Win32 thread. We don't have
+ *       any real problems with that, since we operated merely on a private
+ *       TDB structure that is not yet linked into the task list.
  */
 HTASK16 TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance,
                      HINSTANCE16 hPrevInstance, UINT16 cmdShow)
@@ -339,7 +354,7 @@
     pTask->hInstance     = hInstance;
     pTask->hPrevInstance = hPrevInstance;
     pTask->hModule       = pModule->self;
-    pTask->hParent       = hCurrentTask;
+    pTask->hParent       = GetCurrentTask();
     pTask->magic         = TDB_MAGIC;
     pTask->nCmdShow      = cmdShow;
     pTask->thdb          = thdb;
@@ -439,9 +454,6 @@
     if (!THREAD_Current()->cur_stack)
         THREAD_Current()->cur_stack = pTask->thdb->cur_stack;
 
-    /* Add the task to the linked list */
-
-    TASK_LinkTask( hTask );
 
     TRACE(task, "module='%s' cmdline='%s' task=%04x\n",
           name, cmd_line, hTask );
@@ -449,6 +461,35 @@
     return hTask;
 }
 
+/***********************************************************************
+ *           TASK_StartTask
+ *
+ * NOTE: This routine might be called by a Win32 thread. Thus, we need
+ *       to be careful to protect global data structures. We do this
+ *       by entering the Win16Lock while linking the task into the
+ *       global task list.
+ */
+void TASK_StartTask( HTASK16 hTask )
+{
+    /* Add the task to the linked list */
+
+    SYSLEVEL_EnterWin16Lock();
+    TASK_LinkTask( hTask );
+    SYSLEVEL_LeaveWin16Lock();
+
+    TRACE(task, "linked task %04x\n", hTask );
+
+    /* Get the task up and running. If we ourselves are a 16-bit task,
+       we simply Yield(). If we are 32-bit however, we need to signal
+       the main process somehow (NOT YET IMPLEMENTED!) */
+
+    if ( GetCurrentTask() )
+        if ( THREAD_IsWin16( THREAD_Current() ) )
+            Yield16();
+        else
+            FIXME(task, "Don't know how to start 16-bit task from 32-bit thread. Move the mouse!\n");
+}
+
 
 /***********************************************************************
  *           TASK_DeleteTask
@@ -498,9 +539,25 @@
  */
 void TASK_KillCurrentTask( INT16 exitCode )
 {
-    TDB* pTask = (TDB*) GlobalLock16( hCurrentTask );
+    TDB* pTask = (TDB*) GlobalLock16( GetCurrentTask() );
+    NE_MODULE* pModule = NE_GetPtr( pTask->hModule );
     if (!pTask) USER_ExitWindows();  /* No current task yet */
 
+    if ( !THREAD_IsWin16( THREAD_Current() ) )
+    {
+        FIXME(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel);
+        return;
+    }
+
+    /* Enter the Win16Lock to protect global data structures
+       NOTE: We never explicitly leave it again. This shouldn't matter
+             though, as it will be released in TASK_Reschedule and this
+             task won't ever get scheduled again ... */
+
+    SYSLEVEL_EnterWin16Lock();
+
+    assert(hCurrentTask == GetCurrentTask());
+
     TRACE(task, "Killing task %04x\n", hCurrentTask );
 
     /* Delete active sockets */
@@ -508,6 +565,12 @@
     if( pTask->pwsi )
 	WINSOCK_DeleteTaskWSI( pTask, pTask->pwsi );
 
+#ifdef MZ_SUPPORTED
+    /* Kill DOS VM task */
+    if ( pModule->lpDosTask )
+        MZ_KillModule( pModule->lpDosTask );
+#endif
+
     /* Perform USER cleanup */
 
     if (pTask->userhandler)
@@ -567,9 +630,15 @@
     HTASK16 hTask = 0;
     STACK16FRAME *newframe16;
 
-    SYSLEVEL_ReleaseWin16Lock();
+    /* NOTE: As we are entered from 16-bit code, we hold the Win16Lock.
+             We hang onto it thoughout most of this routine, so that accesses
+             to global variables (most notably the task list) are protected. */
+    assert(hCurrentTask == GetCurrentTask());
+
+    TRACE(task, "entered with hTask %04x (pid %d)\n", hCurrentTask, getpid());
 
 #ifdef CONFIG_IPC
+    /* FIXME: What about the Win16Lock ??? */
     dde_reschedule();
 #endif
       /* First check if there's a task to kill */
@@ -616,13 +685,19 @@
 
         /* No task found, wait for some events to come in */
 
+        /* NOTE: We release the Win16Lock while waiting for events. This is to enable
+                 Win32 threads to thunk down to 16-bit temporarily. Since Win16
+                 tasks won't execute and Win32 threads are not allowed to enter 
+                 TASK_Reschedule anyway, there should be no re-entrancy problem ... */
+
+        SYSLEVEL_ReleaseWin16Lock();
         EVENT_WaitNetEvent( TRUE, TRUE );
+        SYSLEVEL_RestoreWin16Lock();
     }
 
     if (hTask == hCurrentTask) 
     {
        TRACE(task, "returning to the current task(%04x)\n", hTask );
-       SYSLEVEL_RestoreWin16Lock();
        return;  /* Nothing to do */
     }
     pNewTask = (TDB *)GlobalLock16( hTask );
@@ -655,6 +730,12 @@
     
     /* Switch to the new stack */
 
+    /* NOTE: We need to release/restore the Win16Lock, as the task
+             switched to might be at another recursion level than
+             the old task ... */
+
+    SYSLEVEL_ReleaseWin16Lock();
+
     hCurrentTask = hTask;
     SET_CUR_THREAD( pNewTask->thdb );
     pNewTask->ss_sp = pNewTask->thdb->cur_stack;
@@ -673,6 +754,12 @@
 {
   MESSAGEQUEUE*		pQ;
 
+  if ( !THREAD_IsWin16( THREAD_Current() ) )
+  {
+    FIXME(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel);
+    return;
+  }
+
   Callbacks->CallTaskRescheduleProc();
 
   if( pTask )
@@ -702,7 +789,7 @@
     LONG stacklow, stackhi;
 
     if (context) EAX_reg(context) = 0;
-    if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return;
+    if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return;
     if (!(pModule = NE_GetPtr( pTask->hModule ))) return;
 
     /* This is a hack to install task USER signal handler before 
@@ -770,8 +857,15 @@
 {
     TDB *pTask;
 
-    if (!hTask) hTask = hCurrentTask;
+    if (!hTask) hTask = GetCurrentTask();
     pTask = (TDB *)GlobalLock16( hTask );
+
+    if ( !THREAD_IsWin16( THREAD_Current() ) )
+    {
+        FIXME(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel);
+        return TRUE;
+    }
+
     if (pTask->nEvents > 0)
     {
         pTask->nEvents--;
@@ -793,8 +887,16 @@
 {
     TDB *pTask;
 
-    if (!hTask) hTask = hCurrentTask;
+    if (!hTask) hTask = GetCurrentTask();
     if (!(pTask = (TDB *)GlobalLock16( hTask ))) return;
+
+    if ( !THREAD_IsWin16( THREAD_Current() ) )
+    {
+        FIXME(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel);
+        memset(0, 0, 4096);
+        return;
+    }
+
     pTask->nEvents++;
 }
 
@@ -807,7 +909,7 @@
     TDB *pTask;
     INT16 newpriority;
 
-    if (!hTask) hTask = hCurrentTask;
+    if (!hTask) hTask = GetCurrentTask();
     if (!(pTask = (TDB *)GlobalLock16( hTask ))) return;
     newpriority = pTask->priority + delta;
     if (newpriority < -32) newpriority = -32;
@@ -825,7 +927,7 @@
  */
 HTASK16 WINAPI LockCurrentTask( BOOL16 bLock )
 {
-    if (bLock) hLockedTask = hCurrentTask;
+    if (bLock) hLockedTask = GetCurrentTask();
     else hLockedTask = 0;
     return hLockedTask;
 }
@@ -845,9 +947,14 @@
  */
 void WINAPI OldYield(void)
 {
-    TDB *pCurTask;
+    TDB *pCurTask = (TDB *)GlobalLock16( GetCurrentTask() );
 
-    pCurTask = (TDB *)GlobalLock16( hCurrentTask );
+    if ( !THREAD_IsWin16( THREAD_Current() ) )
+    {
+        FIXME(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel);
+        return;
+    }
+
     if (pCurTask) pCurTask->nEvents++;  /* Make sure we get back here */
     TASK_YieldToSystem(pCurTask);
     if (pCurTask) pCurTask->nEvents--;
@@ -859,7 +966,14 @@
  */
 void WINAPI DirectedYield( HTASK16 hTask )
 {
-    TDB *pCurTask = (TDB *)GlobalLock16( hCurrentTask );
+    TDB *pCurTask = (TDB *)GlobalLock16( GetCurrentTask() );
+
+    if ( !THREAD_IsWin16( THREAD_Current() ) )
+    {
+        FIXME(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel);
+        return;
+    }
+
     pCurTask->hYieldTo = hTask;
     OldYield();
 }
@@ -870,8 +984,15 @@
  */
 void WINAPI UserYield(void)
 {
-    TDB *pCurTask = (TDB *)GlobalLock16( hCurrentTask );
+    TDB *pCurTask = (TDB *)GlobalLock16( GetCurrentTask() );
     MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( pCurTask->hQueue );
+
+    if ( !THREAD_IsWin16( THREAD_Current() ) )
+    {
+        FIXME(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel);
+        return;
+    }
+
     /* Handle sent messages */
     while (queue && (queue->wakeBits & QS_SENDMESSAGE))
         QUEUE_ReceiveMessage( queue );
@@ -889,7 +1010,14 @@
  */
 void WINAPI Yield16(void)
 {
-    TDB *pCurTask = (TDB *)GlobalLock16( hCurrentTask );
+    TDB *pCurTask = (TDB *)GlobalLock16( GetCurrentTask() );
+
+    if ( !THREAD_IsWin16( THREAD_Current() ) )
+    {
+        FIXME(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel);
+        return;
+    }
+
     if (pCurTask) pCurTask->hYieldTo = 0;
     if (pCurTask && pCurTask->hQueue) UserYield();
     else OldYield();
@@ -905,7 +1033,7 @@
     SEGPTR thunkaddr;
 
     if (!hInstance) hInstance = CURRENT_DS;
-    thunkaddr = TASK_AllocThunk( hCurrentTask );
+    thunkaddr = TASK_AllocThunk( GetCurrentTask() );
     if (!thunkaddr) return (FARPROC16)0;
     thunk = PTR_SEG_TO_LIN( thunkaddr );
     lfunc = PTR_SEG_TO_LIN( func );
@@ -935,7 +1063,7 @@
 void WINAPI FreeProcInstance16( FARPROC16 func )
 {
     TRACE(task, "(%08lx)\n", (DWORD)func );
-    TASK_FreeThunk( hCurrentTask, (SEGPTR)func );
+    TASK_FreeThunk( GetCurrentTask(), (SEGPTR)func );
 }
 
 
@@ -977,7 +1105,7 @@
     HQUEUE16 hPrev;
     TDB *pTask;
 
-    if (!hTask) hTask = hCurrentTask;
+    if (!hTask) hTask = GetCurrentTask();
     if (!(pTask = (TDB *)GlobalLock16( hTask ))) return 0;
 
     hPrev = pTask->hQueue;
@@ -996,7 +1124,7 @@
 {
     TDB *pTask;
 
-    if (!hTask) hTask = hCurrentTask;
+    if (!hTask) hTask = GetCurrentTask();
     if (!(pTask = (TDB *)GlobalLock16( hTask ))) return 0;
     return pTask->hQueue;
 }
@@ -1012,7 +1140,7 @@
     INSTANCEDATA *pData;
     UINT16 copySize;
 
-    if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return;
+    if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return;
     if (!(pData = (INSTANCEDATA *)GlobalLock16( seg ))) return;
     TRACE(task, "old=%04x:%04x new=%04x:%04x\n",
                   SELECTOROF( pTask->thdb->cur_stack ),
@@ -1056,7 +1184,7 @@
     STACK16FRAME *oldFrame, *newFrame;
     INSTANCEDATA *pData;
 
-    if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return;
+    if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return;
     if (!(pData = (INSTANCEDATA *)GlobalLock16(SELECTOROF(pTask->thdb->cur_stack))))
         return;
     if (!pData->old_ss_sp)
@@ -1116,14 +1244,14 @@
  */
 HTASK16 WINAPI GetCurrentTask(void)
 {
-    return hCurrentTask;
+    return THREAD_InitDone? PROCESS_Current()->task : 0;
 }
 
 DWORD WINAPI WIN16_GetCurrentTask(void)
 {
     /* This is the version used by relay code; the first task is */
     /* returned in the high word of the result */
-    return MAKELONG( hCurrentTask, hFirstTask );
+    return MAKELONG( GetCurrentTask(), hFirstTask );
 }
 
 
@@ -1134,7 +1262,7 @@
 {
     TDB *pTask;
 
-    if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0;
+    if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0;
     return pTask->hPDB;
 }
 
@@ -1159,7 +1287,7 @@
 {
     TDB *pTask;
 
-    if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0;
+    if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0;
     return pTask->version;
 }
 
@@ -1172,7 +1300,7 @@
     TDB *pTask;
     UINT16 oldMode;
 
-    if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0;
+    if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0;
     oldMode = pTask->error_mode;
     pTask->error_mode = mode;
     pTask->thdb->process->error_mode = mode;
@@ -1196,7 +1324,7 @@
 {
     TDB *pTask;
 
-    if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0;
+    if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0;
     return PTR_SEG_OFF_TO_SEGPTR( pTask->pdb.environment, 0 );
 }
 
@@ -1220,7 +1348,7 @@
 {
     TDB *pTask;
 
-    if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0;
+    if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0;
     return pTask->hInstance;
 }
 
@@ -1248,7 +1376,7 @@
     TDB *pTask;
     FARPROC16 oldProc;
 
-    if (!hTask) hTask = hCurrentTask;
+    if (!hTask) hTask = GetCurrentTask();
     if (!(pTask = (TDB *)GlobalLock16( hTask ))) return NULL;
     oldProc = (FARPROC16)pTask->userhandler;
     pTask->userhandler = (USERSIGNALPROC)proc;
@@ -1271,7 +1399,7 @@
     {
         TDB *pTask;
 
-        if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0;
+        if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0;
         if (oldmode) *oldmode = pTask->signal_flags;
         pTask->signal_flags = newmode;
         if (oldhandler) *oldhandler = pTask->sighandler;
@@ -1288,7 +1416,7 @@
 {
     TDB *pTask;
 
-    if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return;
+    if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return;
     pTask->discardhandler = proc;
 }
 
diff --git a/misc/Makefile.in b/misc/Makefile.in
index 420d9e2..c1d3170 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -25,7 +25,6 @@
 	printdrv.c \
 	registry.c \
 	shell.c \
-	shellord.c \
 	sound.c \
 	spy.c \
 	stress.c \
diff --git a/misc/commdlg.c b/misc/commdlg.c
index db21377..007f473 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -73,7 +73,7 @@
     if (lpofn->Flags & OFN_WINE32) {
 	    if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE)
 	    {
-		if (!(template = LockResource32( lpofn->hInstance )))
+		if (!(template = LockResource32( MapHModuleSL(lpofn->hInstance ))))
 		{
 		    CommDlgLastError = CDERR_LOADRESFAILURE;
 		    return FALSE;
@@ -81,13 +81,14 @@
 	    }
 	    else if (lpofn->Flags & OFN_ENABLETEMPLATE)
 	    {
-		if (!(hResInfo = FindResource32A(lpofn->hInstance,
+		if (!(hResInfo = FindResource32A(MapHModuleSL(lpofn->hInstance),
 						PTR_SEG_TO_LIN(lpofn->lpTemplateName), RT_DIALOG32A)))
 		{
 		    CommDlgLastError = CDERR_FINDRESFAILURE;
 		    return FALSE;
 		}
-		if (!(hDlgTmpl = LoadResource32( lpofn->hInstance, hResInfo )) ||
+		if (!(hDlgTmpl = LoadResource32( MapHModuleSL(lpofn->hInstance),
+						 hResInfo )) ||
 		    !(template = LockResource32( hDlgTmpl )))
 		{
 		    CommDlgLastError = CDERR_LOADRESFAILURE;
@@ -198,7 +199,7 @@
     if (lpofn->Flags & OFN_WINE32) {
 	    if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE)
 	    {
-		if (!(template = LockResource32( lpofn->hInstance )))
+		if (!(template = LockResource32( MapHModuleSL(lpofn->hInstance ))))
 		{
 		    CommDlgLastError = CDERR_LOADRESFAILURE;
 		    return FALSE;
@@ -207,14 +208,15 @@
 	    else if (lpofn->Flags & OFN_ENABLETEMPLATE)
 	    {
 		HANDLE32 hResInfo;
-		if (!(hResInfo = FindResource32A(lpofn->hInstance,
+		if (!(hResInfo = FindResource32A(MapHModuleSL(lpofn->hInstance),
 						 PTR_SEG_TO_LIN(lpofn->lpTemplateName),
                                                  RT_DIALOG32A)))
 		{
 		    CommDlgLastError = CDERR_FINDRESFAILURE;
 		    return FALSE;
 		}
-		if (!(hDlgTmpl = LoadResource32(lpofn->hInstance,hResInfo)) ||
+		if (!(hDlgTmpl = LoadResource32(MapHModuleSL(lpofn->hInstance),
+						hResInfo)) ||
 		    !(template = LockResource32(hDlgTmpl)))
 		{
 		    CommDlgLastError = CDERR_LOADRESFAILURE;
@@ -3646,8 +3648,7 @@
 	memset(ofn16,'\0',sizeof(*ofn16));
 	ofn16->lStructSize = sizeof(*ofn16);
 	ofn16->hwndOwner = ofn->hwndOwner;
-	/* FIXME: OPENFILENAME16 got only 16 bit for HINSTANCE... */
-	ofn16->hInstance = 0;
+	ofn16->hInstance = MapHModuleLS(ofn->hInstance);
 	if (ofn->lpstrFilter) {
 		LPSTR	s,x;
 
@@ -3736,8 +3737,7 @@
 	memset(ofn16,'\0',sizeof(*ofn16));
 	ofn16->lStructSize = sizeof(*ofn16);
 	ofn16->hwndOwner = ofn->hwndOwner;
-	/* FIXME: OPENFILENAME16 got only 16 bit for HINSTANCE... */
-	ofn16->hInstance = 0;
+	ofn16->hInstance = MapHModuleLS(ofn->hInstance);
 	if (ofn->lpstrFilter) {
 		LPWSTR	s;
 		LPSTR	x,y;
@@ -3881,7 +3881,7 @@
   memset(lpcc16,'\0',sizeof(*lpcc16));
   lpcc16->lStructSize=sizeof(*lpcc16);
   lpcc16->hwndOwner=lpChCol->hwndOwner;
-  lpcc16->hInstance=0; /* FIXME:MODULE_HANDLEtoHMODULE16(lpChCol->hInstance)*/
+  lpcc16->hInstance=MapHModuleLS(lpChCol->hInstance);
   lpcc16->rgbResult=lpChCol->rgbResult;
   memcpy(ccref,lpChCol->lpCustColors,64);
   lpcc16->lpCustColors=(COLORREF*)SEGPTR_GET(ccref);
@@ -3915,7 +3915,7 @@
   memset(lpcc16,'\0',sizeof(*lpcc16));
   lpcc16->lStructSize=sizeof(*lpcc16);
   lpcc16->hwndOwner=lpChCol->hwndOwner;
-  lpcc16->hInstance=0; /*FIXME:MODULE_HANDLEtoHMODULE16(lpChCol->hInstance)*/
+  lpcc16->hInstance=MapHModuleLS(lpChCol->hInstance);
   lpcc16->rgbResult=lpChCol->rgbResult;
   memcpy(ccref,lpChCol->lpCustColors,64);
   lpcc16->lpCustColors=(COLORREF*)SEGPTR_GET(ccref);
diff --git a/misc/imagelist.c b/misc/imagelist.c
index 4c3125d..8cafd4a 100644
--- a/misc/imagelist.c
+++ b/misc/imagelist.c
@@ -556,7 +556,7 @@
     himl->clrBk = CLR_NONE;
 
     /* initialize overlay mask indices */
-    for (nCount = 0; nCount <= MAX_OVERLAYIMAGE; nCount++)
+    for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
         himl->nOvlIdx[nCount] = -1;
 
     hdc = CreateCompatibleDC32 (0);
@@ -1691,7 +1691,7 @@
 
         himl->cMaxImage = himl->cInitial + himl->cGrow;
         himl->cCurImage = 0;
-        for (nCount = 0; nCount <= MAX_OVERLAYIMAGE; nCount++)
+        for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
              himl->nOvlIdx[nCount] = -1;
 
         DeleteObject32 (himl->hbmImage);
@@ -1921,10 +1921,10 @@
     if (hdcImage)
 	DeleteDC32 (hdcImage);
 
-//    FIXME (imagelist, "deleting hbmColor!\n");
-    DeleteObject32 (ii.hbmColor);
-//    FIXME (imagelist, "deleted hbmColor!\n");
-    DeleteObject32 (ii.hbmMask);
+    if (ii.hbmColor)
+	DeleteObject32 (ii.hbmColor);
+    if (ii.hbmMask)
+	DeleteObject32 (ii.hbmMask);
 
     return (nIndex);
 }
diff --git a/misc/lstr.c b/misc/lstr.c
index 0255049..b2b4ae0 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -668,6 +668,7 @@
 	if (nSize && talloced<nSize) {
 		target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize);
 	}
+    TRACE(resource,"-- %s\n",target);
 	if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
 		/* nSize is the MINIMUM size */
 		*((LPVOID*)lpBuffer) = (LPVOID)LocalAlloc32(GMEM_ZEROINIT,talloced);
diff --git a/misc/lzexpand.c b/misc/lzexpand.c
index 792a7db..495ea9b 100644
--- a/misc/lzexpand.c
+++ b/misc/lzexpand.c
@@ -137,7 +137,7 @@
  */
 HFILE16 WINAPI LZInit16( HFILE16 hfSrc )
 {
-    return LZInit32( hfSrc );
+    return LZInit32( HFILE16_TO_HFILE32(hfSrc) );
 }
 
 
diff --git a/misc/network.c b/misc/network.c
index 89664d0..9dcda9e 100644
--- a/misc/network.c
+++ b/misc/network.c
@@ -7,6 +7,9 @@
  */
 
 #include <ctype.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <unistd.h>
 
 #include "windows.h"
 #include "winerror.h"
@@ -426,6 +429,31 @@
 }
 
 /**************************************************************************
+ *				WNetGetUser			[MPR.86]
+ * FIXME: we should not return ourselves, but the owner of the drive lpLocalName
+ */
+DWORD WINAPI WNetGetUser32A(LPCSTR lpLocalName, LPSTR lpUserName, DWORD *lpSize)
+{
+	struct passwd	*pwd = getpwuid(getuid());
+
+	FIXME(wnet, "(%s, %p, %p), mostly stub\n", lpLocalName, lpUserName, lpSize);
+	if (pwd) {
+		if (strlen(pwd->pw_name)+1>*lpSize) {
+			*lpSize = strlen(pwd->pw_name)+1;
+			SetLastError(ERROR_MORE_DATA);
+			return ERROR_MORE_DATA;
+		}
+		strcpy(lpUserName,pwd->pw_name);
+		if (lpSize)
+			*lpSize = strlen(pwd->pw_name)+1;
+		return WN_SUCCESS;
+	}
+	/* FIXME: wrong return value */
+	SetLastError(ERROR_NO_NETWORK);
+	return ERROR_NO_NETWORK;
+}
+
+/**************************************************************************
  *              WNetGetError       [USER.519]
  */
 int WINAPI WNetGetError(LPWORD nError)
diff --git a/misc/registry.c b/misc/registry.c
index 6f7ff91..b2d1de4 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -99,7 +99,9 @@
 }  *openhandles=NULL;
 static int	nrofopenhandles=0;
 /* Starts after 1 because 0,1 are reserved for Win16 */
-static int	currenthandle=1;
+/* Note: Should always be even, as Win95 ADVAPI32.DLL reserves odd
+         HKEYs for remote registry access */
+static int	currenthandle=2;
 
 
 /*
@@ -1743,7 +1745,8 @@
     if (!lpszSubKey || !*lpszSubKey) {
         /* Either NULL or pointer to empty string, so return a new handle
            to the original hkey */
-        add_handle(++currenthandle,lpNextKey,samDesired);
+        currenthandle += 2;
+        add_handle(currenthandle,lpNextKey,samDesired);
         *retkey=currenthandle;
         return ERROR_SUCCESS;
     }
@@ -1776,7 +1779,8 @@
         lpNextKey = lpxkey;
     }
 
-    add_handle(++currenthandle,lpxkey,samDesired);
+    currenthandle += 2;
+    add_handle(currenthandle,lpxkey,samDesired);
     *retkey = currenthandle;
     TRACE(reg,"  Returning %x\n", currenthandle);
     FREE_KEY_PATH;
@@ -1909,7 +1913,8 @@
         return ERROR_INVALID_PARAMETER;
 
 	if (!lpszSubKey || !*lpszSubKey) {
-		add_handle(++currenthandle,lpNextKey,samDesired);
+                currenthandle += 2;
+		add_handle(currenthandle,lpNextKey,samDesired);
 		*retkey=currenthandle;
                 TRACE(reg, "Returning %x\n", currenthandle);
 		lpNextKey->flags|=REG_OPTION_TAINTED;
@@ -1938,7 +1943,8 @@
 		lpNextKey	= lpxkey;
 	}
 	if (lpxkey) {
-		add_handle(++currenthandle,lpxkey,samDesired);
+                currenthandle += 2;
+		add_handle(currenthandle,lpxkey,samDesired);
 		lpxkey->flags  |= REG_OPTION_TAINTED;
 		*retkey		= currenthandle;
                 TRACE(reg, "Returning %x\n", currenthandle);
@@ -1977,7 +1983,8 @@
 		lpNextKey	= *lplpPrevKey;
 		i++;
 	}
-	add_handle(++currenthandle,lpNextKey,samDesired);
+        currenthandle += 2;
+	add_handle(currenthandle,lpNextKey,samDesired);
 
 	/*FIXME: flag handling correct? */
 	lpNextKey->flags= fdwOptions |REG_OPTION_TAINTED;
diff --git a/misc/shell.c b/misc/shell.c
index 1b8ebbf..6cdeec8 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -2,9 +2,6 @@
  * 				Shell Library Functions
  *
  *  1998 Marcus Meissner
- *  1998 Juergen Schmied (jsch)
- *  currently work in progress on SH* and SHELL32_DllGetClassObject functions
- *  <contact juergen.schmied@metronet.de 980624>
  */
 #include <assert.h>
 #include <stdlib.h>
@@ -31,156 +28,6 @@
 #include "imagelist.h"
 #include "commctrl.h"
 
-/* FIXME should be moved to a header file. IsEqualGUID 
-is declared but not exported in compobj.c !!!*/
-#define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID)))
-#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2)
-#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2)
-
-static const char * const SHELL_People[] =
-{
-    "Bob Amstadt",
-    "Dag Asheim",
-    "Martin Ayotte",
-    "Karl Backström",
-    "Peter Bajusz",
-    "Marcel Baur",
-    "Georg Beyerle",
-    "Ross Biro",
-    "Martin Boehme",
-    "Uwe Bonnes",
-    "Erik Bos",
-    "Fons Botman",
-    "John Brezak",
-    "Andrew Bulhak",
-    "John Burton",
-    "Niels de Carpentier",
-    "Gordon Chaffee",
-    "Jimen Ching",
-    "Pascal Cuoq",
-    "David A. Cuthbert",
-    "Huw D. M. Davies",
-    "Roman Dolejsi",
-    "Frans van Dorsselaer",
-    "Chris Faherty",
-    "Carsten Fallesen",
-    "Paul Falstad",
-    "David Faure",
-    "Claus Fischer",
-    "Olaf Flebbe",
-    "Chad Fraleigh",
-    "Matthew Francis",
-    "Peter Galbavy",
-    "Ramon Garcia",
-    "Matthew Ghio",
-    "Jody Goldberg",
-    "Hans de Graaff",
-    "Charles M. Hannum",
-    "Adrian Harvey",
-    "John Harvey",
-    "Bill Hawes",
-    "Cameron Heide",
-    "Jochen Hoenicke",
-    "Onno Hovers",
-    "Jeffrey Hsu",
-    "Miguel de Icaza",
-    "Jukka Iivonen",
-    "Lee Jaekil",
-    "Alexandre Julliard",
-    "Bang Jun-Young",
-    "Pavel Kankovsky",
-    "Jochen Karrer",
-    "Andreas Kirschbaum",
-    "Rein Klazes",
-    "Albrecht Kleine",
-    "Eric Kohl",
-    "Jon Konrath",
-    "Alex Korobka",
-    "Greg Kreider",
-    "Anand Kumria",
-    "Ove Kåven",
-    "Scott A. Laird",
-    "David Lee Lambert",
-    "Andrew Lewycky",
-    "Per Lindström",
-    "Martin von Loewis",
-    "Michiel van Loon",
-    "Kenneth MacDonald",
-    "Peter MacDonald",
-    "William Magro",
-    "Juergen Marquardt",
-    "Ricardo Massaro",
-    "Marcus Meissner",
-    "Graham Menhennitt",
-    "David Metcalfe",
-    "Bruce Milner",
-    "Steffen Moeller",
-    "Andreas Mohr",
-    "James Moody",
-    "Philippe De Muyter",
-    "Itai Nahshon",
-    "Kristian Nielsen",
-    "Henrik Olsen",
-    "Michael Patra",
-    "Dimitrie O. Paun",
-    "Jim Peterson",
-    "Robert Pouliot",
-    "Keith Reynolds",
-    "Slaven Rezic",
-    "John Richardson",
-    "Rick Richardson",
-    "Doug Ridgway",
-    "Bernhard Rosenkraenzer",
-    "Johannes Ruscheinski",
-    "Thomas Sandford",
-    "Constantine Sapuntzakis",
-    "Pablo Saratxaga",
-    "Daniel Schepler",
-    "Peter Schlaile",
-    "Ulrich Schmid",
-    "Bernd Schmidt",
-    "Juergen Schmied",
-    "Ingo Schneider",
-    "Victor Schneider",
-    "Yngvi Sigurjonsson",
-    "Stephen Simmons",
-    "Rick Sladkey",
-    "William Smith",
-    "Dominik Strasser",
-    "Vadim Strizhevsky",
-    "Bertho Stultiens",
-    "Erik Svendsen",
-    "Tristan Tarrant",
-    "Andrew Taylor",
-    "Duncan C Thomson",
-    "Goran Thyni",
-    "Jimmy Tirtawangsa",
-    "Jon Tombs",
-    "Linus Torvalds",
-    "Gregory Trubetskoy",
-    "Petri Tuomola",
-    "Michael Veksler",
-    "Sven Verdoolaege",
-    "Ronan Waide",
-    "Eric Warnke",
-    "Manfred Weichel",
-    "Ulrich Weigand",
-    "Morten Welinder",
-    "Len White",
-    "Lawson Whitney",
-    "Jan Willamowius",
-    "Carl Williams",
-    "Karl Guenter Wuensch",
-    "Eric Youngdale",
-    "James Youngman",
-    "Nikita V. Youshchenko",
-    "Mikolaj Zalewski",
-    "John Zero",
-    "Luiz Otavio L. Zorzella",
-    NULL
-};
-
-
 /* .ICO file ICONDIR definitions */
 
 #pragma pack(1)
@@ -301,7 +148,7 @@
  *
  * Utility for code sharing between FindExecutable and ShellExecute
  */
-static HINSTANCE32 SHELL_FindExecutable( LPCSTR lpFile, 
+HINSTANCE32 SHELL_FindExecutable( LPCSTR lpFile, 
                                          LPCSTR lpOperation,
                                          LPSTR lpResult)
 { char *extension = NULL; /* pointer to file extension */
@@ -485,18 +332,6 @@
     return retval;
 }
 
-
-/*************************************************************************
- *             ShellExecute32A   (SHELL32.245)
- */
-HINSTANCE32 WINAPI ShellExecute32A( HWND32 hWnd, LPCSTR lpOperation,
-                                    LPCSTR lpFile, LPCSTR lpParameters,
-                                    LPCSTR lpDirectory, INT32 iShowCmd )
-{   TRACE(shell,"\n");
-    return ShellExecute16( hWnd, lpOperation, lpFile, lpParameters,
-                           lpDirectory, iShowCmd );
-}
-
 /*************************************************************************
  *             FindExecutable16   (SHELL.21)
  */
@@ -505,190 +340,6 @@
 { return (HINSTANCE16)FindExecutable32A( lpFile, lpDirectory, lpResult );
 }
 
-/*************************************************************************
- *             FindExecutable32A   (SHELL32.184)
- */
-HINSTANCE32 WINAPI FindExecutable32A( LPCSTR lpFile, LPCSTR lpDirectory,
-                                      LPSTR lpResult )
-{ HINSTANCE32 retval=31;    /* default - 'No association was found' */
-    char old_dir[1024];
-
-  TRACE(shell, "File %s, Dir %s\n", 
-		 (lpFile != NULL?lpFile:"-"), 
-		 (lpDirectory != NULL?lpDirectory:"-"));
-
-    lpResult[0]='\0'; /* Start off with an empty return string */
-
-    /* trap NULL parameters on entry */
-    if (( lpFile == NULL ) || ( lpResult == NULL ))
-  { /* FIXME - should throw a warning, perhaps! */
-	return 2; /* File not found. Close enough, I guess. */
-    }
-
-    if (lpDirectory)
-  { GetCurrentDirectory32A( sizeof(old_dir), old_dir );
-        SetCurrentDirectory32A( lpDirectory );
-    }
-
-    retval = SHELL_FindExecutable( lpFile, "open", lpResult );
-
-  TRACE(shell, "returning %s\n", lpResult);
-  if (lpDirectory)
-    SetCurrentDirectory32A( old_dir );
-    return retval;
-}
-
-typedef struct
-{ LPCSTR  szApp;
-    LPCSTR  szOtherStuff;
-    HICON32 hIcon;
-} ABOUT_INFO;
-
-#define		IDC_STATIC_TEXT		100
-#define		IDC_LISTBOX		99
-#define		IDC_WINE_TEXT		98
-
-#define		DROP_FIELD_TOP		(-15)
-#define		DROP_FIELD_HEIGHT	15
-
-extern HICON32 hIconTitleFont;
-
-static BOOL32 __get_dropline( HWND32 hWnd, LPRECT32 lprect )
-{ HWND32 hWndCtl = GetDlgItem32(hWnd, IDC_WINE_TEXT);
-    if( hWndCtl )
-  { GetWindowRect32( hWndCtl, lprect );
-	MapWindowPoints32( 0, hWnd, (LPPOINT32)lprect, 2 );
-	lprect->bottom = (lprect->top += DROP_FIELD_TOP);
-	return TRUE;
-    }
-    return FALSE;
-}
-
-/*************************************************************************
- *             AboutDlgProc32  (not an exported API function)
- */
-LRESULT WINAPI AboutDlgProc32( HWND32 hWnd, UINT32 msg, WPARAM32 wParam,
-                               LPARAM lParam )
-{   HWND32 hWndCtl;
-    char Template[512], AppTitle[512];
-
-    TRACE(shell,"\n");
-
-    switch(msg)
-    { case WM_INITDIALOG:
-      { ABOUT_INFO *info = (ABOUT_INFO *)lParam;
-            if (info)
-        { const char* const *pstr = SHELL_People;
-                SendDlgItemMessage32A(hWnd, stc1, STM_SETICON32,info->hIcon, 0);
-                GetWindowText32A( hWnd, Template, sizeof(Template) );
-                sprintf( AppTitle, Template, info->szApp );
-                SetWindowText32A( hWnd, AppTitle );
-                SetWindowText32A( GetDlgItem32(hWnd, IDC_STATIC_TEXT),
-                                  info->szOtherStuff );
-                hWndCtl = GetDlgItem32(hWnd, IDC_LISTBOX);
-                SendMessage32A( hWndCtl, WM_SETREDRAW, 0, 0 );
-                SendMessage32A( hWndCtl, WM_SETFONT, hIconTitleFont, 0 );
-                while (*pstr)
-          { SendMessage32A( hWndCtl, LB_ADDSTRING32, (WPARAM32)-1, (LPARAM)*pstr );
-                    pstr++;
-                }
-                SendMessage32A( hWndCtl, WM_SETREDRAW, 1, 0 );
-            }
-        }
-        return 1;
-
-    case WM_PAINT:
-      { RECT32 rect;
-	    PAINTSTRUCT32 ps;
-	    HDC32 hDC = BeginPaint32( hWnd, &ps );
-
-	    if( __get_dropline( hWnd, &rect ) )
-		GRAPH_DrawLines( hDC, (LPPOINT32)&rect, 1, GetStockObject32( BLACK_PEN ) );
-	    EndPaint32( hWnd, &ps );
-	}
-	break;
-
-    case WM_LBTRACKPOINT:
-	hWndCtl = GetDlgItem32(hWnd, IDC_LISTBOX);
-	if( (INT16)GetKeyState16( VK_CONTROL ) < 0 )
-      { if( DragDetect32( hWndCtl, *((LPPOINT32)&lParam) ) )
-        { INT32 idx = SendMessage32A( hWndCtl, LB_GETCURSEL32, 0, 0 );
-		if( idx != -1 )
-          { INT32 length = SendMessage32A( hWndCtl, LB_GETTEXTLEN32, (WPARAM32)idx, 0 );
-		    HGLOBAL16 hMemObj = GlobalAlloc16( GMEM_MOVEABLE, length + 1 );
-		    char* pstr = (char*)GlobalLock16( hMemObj );
-
-		    if( pstr )
-            { HCURSOR16 hCursor = LoadCursor16( 0, MAKEINTRESOURCE16(OCR_DRAGOBJECT) );
-			SendMessage32A( hWndCtl, LB_GETTEXT32, (WPARAM32)idx, (LPARAM)pstr );
-			SendMessage32A( hWndCtl, LB_DELETESTRING32, (WPARAM32)idx, 0 );
-			UpdateWindow32( hWndCtl );
-			if( !DragObject16((HWND16)hWnd, (HWND16)hWnd, DRAGOBJ_DATA, 0, (WORD)hMemObj, hCursor) )
-			    SendMessage32A( hWndCtl, LB_ADDSTRING32, (WPARAM32)-1, (LPARAM)pstr );
-		    }
-            if( hMemObj )
-              GlobalFree16( hMemObj );
-		}
-	    }
-	}
-	break;
-
-    case WM_QUERYDROPOBJECT:
-	if( wParam == 0 )
-      { LPDRAGINFO lpDragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN((SEGPTR)lParam);
-	    if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA )
-        { RECT32 rect;
-		if( __get_dropline( hWnd, &rect ) )
-          { POINT32 pt = { lpDragInfo->pt.x, lpDragInfo->pt.y };
-		    rect.bottom += DROP_FIELD_HEIGHT;
-		    if( PtInRect32( &rect, pt ) )
-            { SetWindowLong32A( hWnd, DWL_MSGRESULT, 1 );
-			return TRUE;
-		    }
-		}
-	    }
-	}
-	break;
-
-    case WM_DROPOBJECT:
-	if( wParam == hWnd )
-      { LPDRAGINFO lpDragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN((SEGPTR)lParam);
-	    if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA && lpDragInfo->hList )
-        { char* pstr = (char*)GlobalLock16( (HGLOBAL16)(lpDragInfo->hList) );
-		if( pstr )
-          { static char __appendix_str[] = " with";
-
-		    hWndCtl = GetDlgItem32( hWnd, IDC_WINE_TEXT );
-		    SendMessage32A( hWndCtl, WM_GETTEXT, 512, (LPARAM)Template );
-		    if( !lstrncmp32A( Template, "WINE", 4 ) )
-			SetWindowText32A( GetDlgItem32(hWnd, IDC_STATIC_TEXT), Template );
-		    else
-          { char* pch = Template + strlen(Template) - strlen(__appendix_str);
-			*pch = '\0';
-			SendMessage32A( GetDlgItem32(hWnd, IDC_LISTBOX), LB_ADDSTRING32, 
-					(WPARAM32)-1, (LPARAM)Template );
-		    }
-
-		    lstrcpy32A( Template, pstr );
-		    lstrcat32A( Template, __appendix_str );
-		    SetWindowText32A( hWndCtl, Template );
-		    SetWindowLong32A( hWnd, DWL_MSGRESULT, 1 );
-		    return TRUE;
-		}
-	    }
-	}
-	break;
-
-    case WM_COMMAND:
-        if (wParam == IDOK)
-    {  EndDialog32(hWnd, TRUE);
-            return TRUE;
-        }
-        break;
-    }
-    return 0;
-}
-
 
 /*************************************************************************
  *             AboutDlgProc16   (SHELL.33)
@@ -708,69 +359,6 @@
 }
 
 /*************************************************************************
- *             ShellAbout32A   (SHELL32.243)
- */
-BOOL32 WINAPI ShellAbout32A( HWND32 hWnd, LPCSTR szApp, LPCSTR szOtherStuff,
-                             HICON32 hIcon )
-{   ABOUT_INFO info;
-    TRACE(shell,"\n");
-    info.szApp        = szApp;
-    info.szOtherStuff = szOtherStuff;
-    info.hIcon        = hIcon;
-    if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) );
-    return DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd ),
-                         SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX ),
-                                      hWnd, AboutDlgProc32, (LPARAM)&info );
-}
-
-
-/*************************************************************************
- *             ShellAbout32W   (SHELL32.244)
- */
-BOOL32 WINAPI ShellAbout32W( HWND32 hWnd, LPCWSTR szApp, LPCWSTR szOtherStuff,
-                             HICON32 hIcon )
-{   BOOL32 ret;
-    ABOUT_INFO info;
-
-    TRACE(shell,"\n");
-    
-    info.szApp        = HEAP_strdupWtoA( GetProcessHeap(), 0, szApp );
-    info.szOtherStuff = HEAP_strdupWtoA( GetProcessHeap(), 0, szOtherStuff );
-    info.hIcon        = hIcon;
-    if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) );
-    ret = DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd ),
-                         SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX ),
-                                      hWnd, AboutDlgProc32, (LPARAM)&info );
-    HeapFree( GetProcessHeap(), 0, (LPSTR)info.szApp );
-    HeapFree( GetProcessHeap(), 0, (LPSTR)info.szOtherStuff );
-    return ret;
-}
-
-/*************************************************************************
- *				Shell_NotifyIcon	[SHELL32.249]
- *	FIXME
- *	This function is supposed to deal with the systray.
- *	Any ideas on how this is to be implimented?
- */
-BOOL32 WINAPI Shell_NotifyIcon(	DWORD dwMessage,
-				PNOTIFYICONDATA pnid )
-{   TRACE(shell,"\n");
-    return FALSE;
-}
-
-/*************************************************************************
- *				Shell_NotifyIcon	[SHELL32.240]
- *	FIXME
- *	This function is supposed to deal with the systray.
- *	Any ideas on how this is to be implimented?
- */
-BOOL32 WINAPI Shell_NotifyIconA(DWORD dwMessage,
-				PNOTIFYICONDATA pnid )
-{   TRACE(shell,"\n");
-    return FALSE;
-}
-
-/*************************************************************************
  *				SHELL_GetResourceTable
  */
 static DWORD SHELL_GetResourceTable(HFILE32 hFile,LPBYTE *retptr)
@@ -1186,40 +774,6 @@
 }
 
 
-/*************************************************************************
- *             ExtractIcon32A   (SHELL32.133)
- */
-HICON32 WINAPI ExtractIcon32A( HINSTANCE32 hInstance, LPCSTR lpszExeFileName,
-	UINT32 nIconIndex )
-{   HGLOBAL16 handle = InternalExtractIcon(hInstance,lpszExeFileName,nIconIndex, 1);
-    TRACE(shell,"\n");
-    if( handle )
-    {
-	HICON16* ptr = (HICON16*)GlobalLock16(handle);
-	HICON16  hIcon = *ptr;
-
-	GlobalFree16(handle);
-	return hIcon;
-    }
-    return 0;
-}
-
-/*************************************************************************
- *             ExtractIcon32W   (SHELL32.180)
- */
-HICON32 WINAPI ExtractIcon32W( HINSTANCE32 hInstance, LPCWSTR lpszExeFileName,
-	UINT32 nIconIndex )
-{ LPSTR  exefn;
-  HICON32  ret;
-  TRACE(shell,"\n");
-
-  exefn = HEAP_strdupWtoA(GetProcessHeap(),0,lpszExeFileName);
-  ret = ExtractIcon32A(hInstance,exefn,nIconIndex);
-
-	HeapFree(GetProcessHeap(),0,exefn);
-	return ret;
-}
-
 
 /*************************************************************************
  *				ExtractAssociatedIcon	[SHELL.36]
@@ -1430,652 +984,3 @@
     }
     return FALSE;
 }
-
-/*************************************************************************
- *				SHGetFileInfoA		[SHELL32.218]
- *
- * FIXME
- *   
- */
-HIMAGELIST ShellSmallIconList = 0;
-HIMAGELIST ShellBigIconList = 0;
-
-DWORD WINAPI SHGetFileInfo32A(LPCSTR path,DWORD dwFileAttributes,
-                              SHFILEINFO32A *psfi, UINT32 sizeofpsfi,
-                              UINT32 flags )
-{ CHAR szTemp[MAX_PATH];
-  DWORD ret=0;
-  
-  TRACE(shell,"(%s,0x%x,%p,0x%x,0x%x)\n",
-	      path,dwFileAttributes,psfi,sizeofpsfi,flags);
-
-  /* translate the pidl to a path*/
-  if (flags & SHGFI_PIDL)
-  { SHGetPathFromIDList32A ((LPCITEMIDLIST)path,szTemp);
-    TRACE(shell,"pidl=%p is %s\n",path,szTemp);
-  }
-
-  if (flags & SHGFI_ATTRIBUTES)
-  { FIXME(shell,"file attributes, stub\n");
-    psfi->dwAttributes=0;
-    ret=TRUE;    
-  }
-
-  if (flags & SHGFI_DISPLAYNAME)
-  { if (flags & SHGFI_PIDL)
-    { strcpy(psfi->szDisplayName,szTemp);
-    }
-    else
-    { strcpy(psfi->szDisplayName,path);
-      TRACE(shell,"displayname=%s\n", szTemp);
-    }
-    ret=TRUE;
-  }
-  
-  if (flags & SHGFI_TYPENAME)
-  { FIXME(shell,"get the file type, stub\n");
-    strcpy(psfi->szTypeName,"");
-    ret=TRUE;
-  }
-  
-  if (flags & SHGFI_ICONLOCATION)
-  { FIXME(shell,"location of icon, stub\n");
-    strcpy(psfi->szDisplayName,"");
-    ret=TRUE;
-  }
-
-  if (flags & SHGFI_EXETYPE)
-    FIXME(shell,"type of executable, stub\n");
-
-  if (flags & SHGFI_LINKOVERLAY)
-    FIXME(shell,"set icon to link, stub\n");
-
-  if (flags & SHGFI_OPENICON)
-    FIXME(shell,"set to open icon, stub\n");
-
-  if (flags & SHGFI_SELECTED)
-    FIXME(shell,"set icon to selected, stub\n");
-
-  if (flags & SHGFI_SHELLICONSIZE)
-    FIXME(shell,"set icon to shell size, stub\n");
-
-  if (flags & SHGFI_USEFILEATTRIBUTES)
-    FIXME(shell,"use the dwFileAttributes, stub\n");
- 
-  if (flags & SHGFI_ICON)
-  { FIXME(shell,"icon handle\n");
-    if (flags & SHGFI_SMALLICON)
-     { TRACE(shell,"set to small icon\n"); 
-       psfi->hIcon=ImageList_GetIcon(ShellSmallIconList,0,ILD_NORMAL);
-       ret = (DWORD) ShellSmallIconList;
-     }
-     else
-     { TRACE(shell,"set to big icon\n");
-       psfi->hIcon=ImageList_GetIcon(ShellBigIconList,0,ILD_NORMAL);
-       ret = (DWORD) ShellBigIconList;
-     }      
-  }
-
-  if (flags & SHGFI_SYSICONINDEX)
-  {  FIXME(shell,"get the SYSICONINDEX\n");
-     psfi->iIcon=1;
-     if (flags & SHGFI_SMALLICON)
-     { TRACE(shell,"set to small icon\n"); 
-       ret = (DWORD) ShellSmallIconList;
-     }
-     else        
-     { TRACE(shell,"set to big icon\n");
-       ret = (DWORD) ShellBigIconList;
-     }
-  }
-
- 
-  return ret;
-}
-
-/*************************************************************************
- *				SHAppBarMessage32	[SHELL32.207]
- */
-UINT32 WINAPI SHAppBarMessage32(DWORD msg, PAPPBARDATA data)
-{ FIXME(shell,"(0x%08lx,%p): stub\n", msg, data);
-#if 0
-  switch (msg)
-  { case ABM_ACTIVATE:
-        case ABM_GETAUTOHIDEBAR:
-        case ABM_GETSTATE:
-        case ABM_GETTASKBARPOS:
-        case ABM_NEW:
-        case ABM_QUERYPOS:
-        case ABM_REMOVE:
-        case ABM_SETAUTOHIDEBAR:
-        case ABM_SETPOS:
-        case ABM_WINDOWPOSCHANGED:
-	    ;
-    }
-#endif
-    return 0;
-}
-
-/*************************************************************************
- *				CommandLineToArgvW	[SHELL32.7]
- */
-LPWSTR* WINAPI CommandLineToArgvW(LPWSTR cmdline,LPDWORD numargs)
-{ LPWSTR  *argv,s,t;
-	int	i;
-  TRACE(shell,"\n");
-
-        /* to get writeable copy */
-	cmdline = HEAP_strdupW( GetProcessHeap(), 0, cmdline);
-	s=cmdline;i=0;
-  while (*s)
-  { /* space */
-    if (*s==0x0020) 
-    { i++;
-			s++;
-			while (*s && *s==0x0020)
-				s++;
-			continue;
-		}
-		s++;
-	}
-	argv=(LPWSTR*)HeapAlloc( GetProcessHeap(), 0, sizeof(LPWSTR)*(i+1) );
-	s=t=cmdline;
-	i=0;
-  while (*s)
-  { if (*s==0x0020)
-    { *s=0;
-			argv[i++]=HEAP_strdupW( GetProcessHeap(), 0, t );
-			*s=0x0020;
-			while (*s && *s==0x0020)
-				s++;
-			if (*s)
-				t=s+1;
-			else
-				t=s;
-			continue;
-		}
-		s++;
-	}
-	if (*t)
-		argv[i++]=(LPWSTR)HEAP_strdupW( GetProcessHeap(), 0, t );
-	HeapFree( GetProcessHeap(), 0, cmdline );
-	argv[i]=NULL;
-	*numargs=i;
-	return argv;
-}
-
-/*************************************************************************
- *				Control_RunDLL		[SHELL32.12]
- *
- * Wild speculation in the following!
- *
- * http://premium.microsoft.com/msdn/library/techart/msdn193.htm
- */
-
-void WINAPI Control_RunDLL (HWND32 hwnd, LPCVOID code, LPCSTR cmd, DWORD arg4)
-{ FIXME(shell, "(%08x, %p, \"%s\", %08lx)\n",
-	hwnd, code ? code : "(null)", cmd ? cmd : "(null)", arg4);
-}
-
-/*************************************************************************
- * FreeIconList
- */
-void WINAPI FreeIconList( DWORD dw )
-{ FIXME(shell, "(%lx): stub\n",dw);
-}
-
-/*************************************************************************
- * SHELL32_DllGetClassObject   [SHELL32.128]
- *
- * [Standart OLE/COM Interface Method]
- * This Function retrives the pointer to a specified interface (iid) of
- * a given class (rclsid).
- * With this pointer it's possible to call the IClassFactory_CreateInstance
- * method to get a instance of the requested Class.
- * This function does NOT instantiate the Class!!!
- * 
- * RETURNS
- *   HRESULT
- *
- */
-DWORD WINAPI SHELL32_DllGetClassObject(REFCLSID rclsid,REFIID iid,LPVOID *ppv)
-{ HRESULT	hres = E_OUTOFMEMORY;
-  LPCLASSFACTORY lpclf;
-
-  char	xclsid[50],xiid[50];
-  WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
-  WINE_StringFromCLSID((LPCLSID)iid,xiid);
-  TRACE(shell,"\n\tCLSID:\t%s,\n\tIID:\t%s\n",xclsid,xiid);
-	
-  *ppv = NULL;
-	if(IsEqualCLSID(rclsid, &CLSID_ShellDesktop)|| 
-	   IsEqualCLSID(rclsid, &CLSID_ShellLink))
-	{ if(IsEqualCLSID(rclsid, &CLSID_ShellDesktop))      /*debug*/
-	    TRACE(shell,"requested CLSID_ShellDesktop\n");
-	  if(IsEqualCLSID(rclsid, &CLSID_ShellLink))         /*debug*/
-	    TRACE(shell,"requested CLSID_ShellLink\n");
-
-	  lpclf = IClassFactory_Constructor();
-    if(lpclf)
-    { hres = lpclf->lpvtbl->fnQueryInterface(lpclf,iid, ppv);
-		  lpclf->lpvtbl->fnRelease(lpclf);
-		}
-	}
-	else
-  { WARN(shell, "clsid(%s) not in buildin SHELL32\n",xclsid);
-    hres = CLASS_E_CLASSNOTAVAILABLE;
-	}
-  TRACE(shell,"RETURN pointer to interface: %p\n",ppv);
-  return hres;
-}
-
-/*************************************************************************
- *  SHGetDesktopFolder		[SHELL32.216]
- * 
- *  SDK header win95/shlobj.h: This is equivalent to call CoCreateInstance with
- *  CLSID_ShellDesktop
- *  CoCreateInstance(CLSID_Desktop, NULL, CLSCTX_INPROC, IID_IShellFolder, &pshf);
- *
- * RETURNS
- *   the interface to the shell desktop folder.
- *
- * FIXME
- *   the pdesktopfolder has to be released at the end (at dll unloading???)
- */
-LPSHELLFOLDER pdesktopfolder=NULL;
-
-DWORD WINAPI SHGetDesktopFolder(LPSHELLFOLDER *shellfolder)
-{ HRESULT	hres = E_OUTOFMEMORY;
-  LPCLASSFACTORY lpclf;
-	TRACE(shell,"%p->(%p)\n",shellfolder,*shellfolder);
-
-  if (pdesktopfolder)
-	{	hres = NOERROR;
-	}
-	else
-  { lpclf = IClassFactory_Constructor();
-    /* fixme: the buildin IClassFactory_Constructor is at the moment only 
- 		for rclsid=CLSID_ShellDesktop, so we get the right Interface (jsch)*/
-    if(lpclf)
-    { hres = lpclf->lpvtbl->fnCreateInstance(lpclf,NULL,(REFIID)&IID_IShellFolder, (void*)&pdesktopfolder);
-	 	  lpclf->lpvtbl->fnRelease(lpclf);
-	  }  
-  }
-	
-  if (pdesktopfolder)
-	{ *shellfolder = pdesktopfolder;
-    pdesktopfolder->lpvtbl->fnAddRef(pdesktopfolder);
-	}
-  else
-	{ *shellfolder=NULL;
-	}	
-
-  TRACE(shell,"-- %p->(%p)\n",shellfolder, *shellfolder);
-	return hres;
-}
-
-/*************************************************************************
- *			 SHGetMalloc			[SHELL32.220]
- * returns the interface to shell malloc.
- *
- * [SDK header win95/shlobj.h:
- * equivalent to:  #define SHGetMalloc(ppmem)   CoGetMalloc(MEMCTX_TASK, ppmem)
- * ]
- * What we are currently doing is not very wrong, since we always use the same
- * heap (ProcessHeap).
- */
-DWORD WINAPI SHGetMalloc(LPMALLOC32 *lpmal) 
-{	TRACE(shell,"(%p)\n", lpmal);
-	return CoGetMalloc32(0,lpmal);
-}
-
-/*************************************************************************
- *			 SHGetSpecialFolderLocation	[SHELL32.223]
- * gets the folder locations from the registry and creates a pidl
- * creates missing reg keys and directorys
- * 
- * PARAMS
- *   hwndOwner [I]
- *   nFolder   [I] CSIDL_xxxxx
- *   ppidl     [O] PIDL of a special folder
- *
- * RETURNS
- *    HResult
- *
- * FIXME
- *   - look for "User Shell Folder" first
- *
- */
-HRESULT WINAPI SHGetSpecialFolderLocation(HWND32 hwndOwner, INT32 nFolder, LPITEMIDLIST * ppidl)
-{	LPSHELLFOLDER shellfolder;
-  DWORD  pchEaten,tpathlen=MAX_PATH,type,dwdisp,res;
-	CHAR   pszTemp[256],buffer[256],tpath[MAX_PATH],npath[MAX_PATH];
-	LPWSTR lpszDisplayName = (LPWSTR)&pszTemp[0];
-	HKEY	 key;
-
-  enum 
-	{	FT_UNKNOWN= 0x00000000,
-	  FT_DIR=     0x00000001, 
-	  FT_DESKTOP= 0x00000002
-	} tFolder; 
-
-  TRACE(shell,"(%04x,%d,%p)\n", hwndOwner,nFolder,ppidl);
-
-  strcpy(buffer,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\");
-
-  res=RegCreateKeyEx32A(HKEY_CURRENT_USER,buffer,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&key,&dwdisp);
-	if (res)
-	{ ERR(shell,"Could not create key %s %08lx \n",buffer,res);
-	  return E_OUTOFMEMORY;
-	}
-
-	tFolder=FT_DIR;	
-	switch (nFolder)
-	{	case CSIDL_BITBUCKET:
-			strcpy (buffer,"xxx");			/*not in the registry*/
-			TRACE (shell,"looking for Recycler\n");
-			tFolder=FT_UNKNOWN;
-      break;
-		case CSIDL_CONTROLS:
-			strcpy (buffer,"xxx");			/*virtual folder*/
-      TRACE (shell,"looking for Control\n");
-			tFolder=FT_UNKNOWN;
-      break;
-		case CSIDL_DESKTOP:
-			strcpy (buffer,"xxx");			/*virtual folder*/
-			TRACE (shell,"looking for Desktop\n");
-			tFolder=FT_DESKTOP;			
-      break;
-		case CSIDL_DESKTOPDIRECTORY:
-			strcpy (buffer,"Desktop");
-      break;
-		case CSIDL_DRIVES:
-			strcpy (buffer,"xxx");			/*virtual folder*/
-      TRACE (shell,"looking for Drives\n");
-			tFolder=FT_UNKNOWN;
-      break;
-		case CSIDL_FONTS:
-			strcpy (buffer,"Fonts");			
-      break;
-		case CSIDL_NETHOOD:
-			strcpy (buffer,"NetHood");			
-      break;
-		case CSIDL_NETWORK:
-			strcpy (buffer,"xxx");				/*virtual folder*/
-			TRACE (shell,"looking for Network\n");
-			tFolder=FT_UNKNOWN;
-      break;
-		case CSIDL_PERSONAL:
-			strcpy (buffer,"Personal");			
-      break;
-		case CSIDL_FAVORITES:
-			strcpy (buffer,"Favorites");			
-      break;
-		case CSIDL_PRINTERS:
-			strcpy (buffer,"PrintHood");			
-      break;
-		case CSIDL_PROGRAMS:
-			strcpy (buffer,"Programs");			
-      break;
-		case CSIDL_RECENT:
-			strcpy (buffer,"Recent");
-      break;
-		case CSIDL_SENDTO:
-			strcpy (buffer,"SendTo");
- 		  break;
-		case CSIDL_STARTMENU:
-			strcpy (buffer,"Start Menu");
-      break;
-		case CSIDL_STARTUP:
-			strcpy (buffer,"Startup");			
-      break;
-		case CSIDL_TEMPLATES:
-			strcpy (buffer,"Templates");			
-      break;
-		default:
-      ERR (shell,"unknown CSIDL\n");
-			tFolder=FT_UNKNOWN;			
-      break;
-	}
-
-  TRACE(shell,"Key=%s\n",buffer);
-
-  type=REG_SZ;
-
-  switch (tFolder)
-	{ case FT_DIR:
-	    /* Directory: get the value from the registry, if its not there 
-			create it and the directory*/
-    	if (RegQueryValueEx32A(key,buffer,NULL,&type,tpath,&tpathlen))
-  	  { GetWindowsDirectory32A(npath,MAX_PATH);
-	      PathAddBackslash(npath);
-  			switch (nFolder)
-  			{	case CSIDL_DESKTOPDIRECTORY:
-      			strcat (npath,"Desktop");
-            break;
-      		case CSIDL_FONTS:
-      			strcat (npath,"Fonts");			
-            break;
-      		case CSIDL_NETHOOD:
-      			strcat (npath,"NetHood");			
-            break;
-  		    case CSIDL_PERSONAL:
-      			strcpy (npath,"C:\\Personal");			
-            break;
-      		case CSIDL_FAVORITES:
-      			strcat (npath,"Favorites");			
-            break;
-  		    case CSIDL_PRINTERS:
-      			strcat (npath,"PrintHood");			
-            break;
-      		case CSIDL_PROGRAMS:
-      			strcat (npath,"Start Menu");			
-  					CreateDirectory32A(npath,NULL);
-      			strcat (npath,"\\Programs");			
-            break;
-      		case CSIDL_RECENT:
-      			strcat (npath,"Recent");
-            break;
-      		case CSIDL_SENDTO:
-      			strcat (npath,"SendTo");
-      			break;
-      		case CSIDL_STARTMENU:
-      			strcat (npath,"Start Menu");
-            break;
-      		case CSIDL_STARTUP:
-      			strcat (npath,"Start Menu");			
-  					CreateDirectory32A(npath,NULL);
-      			strcat (npath,"\\Startup");			
-            break;
-      		case CSIDL_TEMPLATES:
-      			strcat (npath,"Templates");			
-            break;
-  				default:
-         	  RegCloseKey(key);
-        	  return E_OUTOFMEMORY;
-  			}
-    		if (RegSetValueEx32A(key,buffer,0,REG_SZ,npath,sizeof(npath)+1))
-        {	ERR(shell,"could not create value %s\n",buffer);
-      	  RegCloseKey(key);
-      	  return E_OUTOFMEMORY;
-    		}
-    		TRACE(shell,"value %s=%s created\n",buffer,npath);
-    	  CreateDirectory32A(npath,NULL);
-      }
-			break;
-		case FT_DESKTOP:
-			strcpy (tpath,"Desktop");			
-		  break;
-	  default:
-      RegCloseKey(key);
-      return E_OUTOFMEMORY;
-		  break;
-  }
-
-	RegCloseKey(key);
-
-  TRACE(shell,"Value=%s\n",tpath);
-  LocalToWideChar32(lpszDisplayName, tpath, 256);
-  
-	if (SHGetDesktopFolder(&shellfolder)==S_OK)
-	{ shellfolder->lpvtbl->fnParseDisplayName(shellfolder,hwndOwner, NULL,lpszDisplayName,&pchEaten,ppidl,NULL);
-	  shellfolder->lpvtbl->fnRelease(shellfolder);
-	}
-
-	TRACE(shell, "-- (new pidl %p)\n",*ppidl);
-	return NOERROR;
-}
-
-/*************************************************************************
- * SHGetPathFromIDList32A        [SHELL32.261][NT 4.0: SHELL32.220]
- *
- * PARAMETERS
- *  pidl,   [IN] pidl 
- *  pszPath [OUT] path
- *
- * RETURNS 
- *  path from a passed PIDL.
- *
- * NOTES
- *     exported by name
- *
- * FIXME
- *  fnGetDisplayNameOf can return different types of OLEString
- */
-DWORD WINAPI SHGetPathFromIDList32A (LPCITEMIDLIST pidl,LPSTR pszPath)
-{	STRRET lpName;
-	LPSHELLFOLDER shellfolder;
-  CHAR  buffer[MAX_PATH],tpath[MAX_PATH];
-  DWORD type,tpathlen=MAX_PATH,dwdisp;
-  HKEY  key;
-
-	TRACE(shell,"(pidl=%p,%p)\n",pidl,pszPath);
-
-  if (!pidl)
-  {  strcpy(buffer,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\");
-
-     if (RegCreateKeyEx32A(HKEY_CURRENT_USER,buffer,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&key,&dwdisp))
-     { return E_OUTOFMEMORY;
-     }
-     type=REG_SZ;    
-     strcpy (buffer,"Desktop");					/*registry name*/
-     if ( RegQueryValueEx32A(key,buffer,NULL,&type,tpath,&tpathlen))
-     { GetWindowsDirectory32A(tpath,MAX_PATH);
-       PathAddBackslash(tpath);
-       strcat (tpath,"Desktop");				/*folder name*/
-       RegSetValueEx32A(key,buffer,0,REG_SZ,tpath,tpathlen);
-       CreateDirectory32A(tpath,NULL);
-     }
-     RegCloseKey(key);
-     strcpy(pszPath,tpath);
-  }
-  else
-  { if (SHGetDesktopFolder(&shellfolder)==S_OK)
-	{ shellfolder->lpvtbl->fnGetDisplayNameOf(shellfolder,pidl,SHGDN_FORPARSING,&lpName);
-	  shellfolder->lpvtbl->fnRelease(shellfolder);
-	}
-  /*WideCharToLocal32(pszPath, lpName.u.pOleStr, MAX_PATH);*/
-	strcpy(pszPath,lpName.u.cStr);
-	/* fixme free the olestring*/
-  }
-	TRACE(shell,"-- (%s)\n",pszPath);
-	return NOERROR;
-}
-/*************************************************************************
- * SHGetPathFromIDList32W [SHELL32.262]
- */
-DWORD WINAPI SHGetPathFromIDList32W (LPCITEMIDLIST pidl,LPWSTR pszPath)
-{ FIXME (shell,"(pidl=%p %s):stub.\n", pidl, debugstr_w(pszPath));
-  return 0;
-}
-
-/*************************************************************************
- *			 SHGetPathFromIDList		[SHELL32.221][NT 4.0: SHELL32.219]
- */
-BOOL32 WINAPI SHGetPathFromIDList32(LPCITEMIDLIST pidl,LPSTR pszPath)     
-{ TRACE(shell,"(pidl=%p,%p)\n",pidl,pszPath);
-  return SHGetPathFromIDList32A(pidl,pszPath);
-}
-
-/*************************************************************************
- * 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;
-}
-
-/*************************************************************************
- * SHLoadInProc [SHELL32.225]
- *
- */
-
-DWORD WINAPI SHLoadInProc (DWORD dwArg1)
-{ FIXME (shell, "(%lx) empty stub!\n", dwArg1);
-    return 0;
-}
-
-/*************************************************************************
- * SHBrowseForFolderA [SHELL32.209]
- *
- */
-LPITEMIDLIST WINAPI SHBrowseForFolder32A (LPBROWSEINFO32A lpbi)
-{ FIXME (shell, "(%lx,%s) empty stub!\n", (DWORD)lpbi, lpbi->lpszTitle);
-  return NULL;
-}
-
-/*************************************************************************
- * SHELL32 LibMain
- *
- * FIXME
- *  at the moment the icons are extracted from shell32.dll
- */
-HINSTANCE32 shell32_hInstance; 
-
-BOOL32 WINAPI Shell32LibMain(HINSTANCE32 hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
-{ HICON32 htmpIcon;
-  UINT32 iiconindex;
-  UINT32 index;
-  CHAR   szShellPath[MAX_PATH];
-  
-  TRACE(shell,"0x%x 0x%lx %p\n", hinstDLL, fdwReason, lpvReserved);
-
-  shell32_hInstance = hinstDLL;
-  
-  GetWindowsDirectory32A(szShellPath,MAX_PATH);
-  PathAddBackslash(szShellPath);
-  strcat(szShellPath,"system\\shell32.dll");
-       
-  if (fdwReason==DLL_PROCESS_ATTACH)
-  { if ( ! ShellSmallIconList )
-    { if ( (ShellSmallIconList = ImageList_Create(16,16,ILC_COLOR,64,16)) )
-      { for (index=0;index < 40; index++)
-        { if ( ( htmpIcon = ExtractIcon32A(hinstDLL, szShellPath, index)) )
-          { iiconindex = ImageList_AddIcon (ShellSmallIconList, htmpIcon);
-          }
-          else
-          { ERR(shell,"could not initialize iconlist (is shell32.dll in the system directory?)\n");
-            break;
-          }
-        }
-      }
-    }
-    if ( ! ShellBigIconList )
-    { if ( (ShellBigIconList = ImageList_Create(32,32,ILC_COLOR,64,16)) )
-      { for (index=0;index < 40; index++)
-        { if ( (htmpIcon = ExtractIcon32A( hinstDLL, szShellPath, index)) )
-          { iiconindex = ImageList_AddIcon (ShellBigIconList, htmpIcon);
-          }
-          else
-          { ERR(shell,"could not initialize iconlist (is shell32.dll in the system directory?)\n");
-            break;
-          }
-        }
-      }
-    }
-  }
-  return TRUE;
-}
diff --git a/msdos/dosmem.c b/msdos/dosmem.c
index d0bfddd..1affb0a 100644
--- a/msdos/dosmem.c
+++ b/msdos/dosmem.c
@@ -15,7 +15,6 @@
 #include "miscemu.h"
 #include "module.h"
 #include "task.h"
-#include "dosexe.h"
 #include "debug.h"
 
 HANDLE16 DOSMEM_BiosSeg;  /* BIOS data segment at 0x40:0 */
@@ -112,13 +111,14 @@
  *
  * Gets the DOS memory base.
  */
-static char *DOSMEM_MemoryBase(HMODULE16 hModule)
+char *DOSMEM_MemoryBase(HMODULE16 hModule)
 {
     TDB *pTask = hModule ? NULL : (TDB *)GlobalLock16( GetCurrentTask() );
     NE_MODULE *pModule = (hModule || pTask) ? NE_GetPtr( hModule ? hModule : pTask->hModule ) : NULL;
 
-    if (pModule && pModule->lpDosTask)
-        return pModule->lpDosTask->img;
+    GlobalUnlock16( GetCurrentTask() );
+    if (pModule && pModule->dos_image)
+        return pModule->dos_image;
     else
         return DOSMEM_dosmem;
 }
@@ -431,7 +431,6 @@
 UINT32 DOSMEM_Available(HMODULE16 hModule)
 {
    UINT32  	 blocksize, available = 0;
-   char         *block = NULL;
    dosmem_entry *dm;
    
    dm = root_block;
diff --git a/msdos/int20.c b/msdos/int20.c
index e53813a..f6be7ad 100644
--- a/msdos/int20.c
+++ b/msdos/int20.c
@@ -15,5 +15,5 @@
  */
 void WINAPI INT_Int20Handler( CONTEXT *context )
 {
-        TASK_KillCurrentTask( 0 );
+        ExitProcess( 0 );
 }
diff --git a/msdos/int21.c b/msdos/int21.c
index 6bb650e..a4e95f1 100644
--- a/msdos/int21.c
+++ b/msdos/int21.c
@@ -32,14 +32,6 @@
 #endif
 
 
-#define DOS_TO_HANDLE(handle) (((handle)==0) ? GetStdHandle(STD_INPUT_HANDLE) : \
-			      ((handle)==1) ? GetStdHandle(STD_OUTPUT_HANDLE) : \
-			      ((handle)==2) ? GetStdHandle(STD_ERROR_HANDLE) : \
-			       (handle)-5)
-#define HANDLE_TO_DOS(handle) ({ WORD hnd=handle; \
-			      ((hnd==HFILE_ERROR16) ? HFILE_ERROR16 : \
-			        hnd+5); })
-
 #define DOS_GET_DRIVE(reg) ((reg) ? (reg) - 1 : DRIVE_GetCurrentDrive())
 
 /* Define the drive parameter block, as used by int21/1F
@@ -228,7 +220,7 @@
     RESET_CFLAG(context);
 
     /* DOS device ? */
-    if ((file = FILE_GetFile( DOS_TO_HANDLE(BX_reg(context)) )))
+    if ((file = FILE_GetFile( HFILE16_TO_HFILE32(BX_reg(context)) )))
     {
         const DOS_DEVICE *dev = DOSFS_GetDevice( file->unix_name );
         FILE_ReleaseFile( file );
@@ -364,16 +356,16 @@
 }
 static BOOL32 INT21_CreateFile( CONTEXT *context )
 {
-    AX_reg(context) = HANDLE_TO_DOS(_lcreat16( CTX_SEG_OFF_TO_LIN(context,  DS_reg(context),
-                                          DX_reg(context) ), CX_reg(context) ));
+    AX_reg(context) = _lcreat16( CTX_SEG_OFF_TO_LIN(context, DS_reg(context),
+                                          DX_reg(context) ), CX_reg(context) );
     return (AX_reg(context) == (WORD)HFILE_ERROR16);
 }
 
 
 static void OpenExistingFile( CONTEXT *context )
 {
-    AX_reg(context) = HANDLE_TO_DOS(_lopen16( CTX_SEG_OFF_TO_LIN(context, DS_reg(context),DX_reg(context)),
-                              AL_reg(context) ));
+    AX_reg(context) = _lopen16( CTX_SEG_OFF_TO_LIN(context, DS_reg(context),DX_reg(context)),
+                               AL_reg(context) );
     if (AX_reg(context) == (WORD)HFILE_ERROR16)
     {
         AX_reg(context) = DOS_ExtendedError;
@@ -442,7 +434,7 @@
         }
 
 	Error (0,0,0);
-	AX_reg(context) = HANDLE_TO_DOS(handle);
+	AX_reg(context) = handle;
 	RESET_CFLAG(context);
     }
 #endif
@@ -450,7 +442,7 @@
 
 static void CloseFile( CONTEXT *context )
 {
-    if ((AX_reg(context) = _lclose16( DOS_TO_HANDLE(BX_reg(context)) )) != 0)
+    if ((AX_reg(context) = _lclose16( BX_reg(context) )) != 0)
     {
         AX_reg(context) = DOS_ExtendedError;
         SET_CFLAG(context);
@@ -666,7 +658,7 @@
         sprintf( p, "wine%04x.%03d", (int)getpid(), counter );
         counter = (counter + 1) % 1000;
 
-        if ((AX_reg(context) = HANDLE_TO_DOS(_lcreat_uniq( name, 0 ))) != (WORD)HFILE_ERROR16)
+        if ((AX_reg(context) = HFILE32_TO_HFILE16(_lcreat_uniq( name, 0 ))) != (WORD)HFILE_ERROR16)
         {
             TRACE(int21, "created %s\n", name );
             return TRUE;
@@ -844,7 +836,7 @@
 		BX_reg(context),
 		MAKELONG(DX_reg(context),CX_reg(context)),
 		MAKELONG(DI_reg(context),SI_reg(context))) ;
-	  if (!LockFile(DOS_TO_HANDLE(BX_reg(context)),
+          if (!LockFile(HFILE16_TO_HFILE32(BX_reg(context)),
                         MAKELONG(DX_reg(context),CX_reg(context)), 0,
                         MAKELONG(DI_reg(context),SI_reg(context)), 0)) {
 	    AX_reg(context) = DOS_ExtendedError;
@@ -857,7 +849,7 @@
 		BX_reg(context),
 		MAKELONG(DX_reg(context),CX_reg(context)),
 		MAKELONG(DI_reg(context),SI_reg(context))) ;
-	  if (!UnlockFile(DOS_TO_HANDLE(BX_reg(context)),
+          if (!UnlockFile(HFILE16_TO_HFILE32(BX_reg(context)),
                           MAKELONG(DX_reg(context),CX_reg(context)), 0,
                           MAKELONG(DI_reg(context),SI_reg(context)), 0)) {
 	    AX_reg(context) = DOS_ExtendedError;
@@ -902,6 +894,20 @@
      }
 }
 
+static WORD INT21_GetCurrentPSP()
+{
+#ifdef MZ_SUPPORTED
+    TDB *pTask = hModule ? NULL : (TDB *)GlobalLock16( GetCurrentTask() );
+    NE_MODULE *pModule = (hModule || pTask) ? NE_GetPtr( hModule ? hModule : pTask->hModule ) : NULL;
+        
+    GlobalUnlock16( GetCurrentTask() );
+    if (pModule->lpDosTask)
+        return pModule->lpDosTask->psp_seg;
+    else
+#endif
+        return GetCurrentPDB();
+}
+
 
 SEGPTR INT21_GetListOfLists()
 {
@@ -1001,16 +1007,13 @@
     {
     case 0x00: /* TERMINATE PROGRAM */
         TRACE(int21,"TERMINATE PROGRAM\n");
-        TASK_KillCurrentTask( 0 );
+        ExitProcess( 0 );
         break;
 
     case 0x01: /* READ CHARACTER FROM STANDARD INPUT, WITH ECHO */
-    case 0x02: /* WRITE CHARACTER TO STANDARD OUTPUT */
     case 0x03: /* READ CHARACTER FROM STDAUX  */
     case 0x04: /* WRITE CHARACTER TO STDAUX */
     case 0x05: /* WRITE CHARACTER TO PRINTER */
-    case 0x06: /* DIRECT CONSOLE IN/OUTPUT */
-    case 0x0a: /* BUFFERED INPUT */
     case 0x0b: /* GET STDIN STATUS */
     case 0x0f: /* OPEN FILE USING FCB */
     case 0x10: /* CLOSE FILE USING FCB */
@@ -1025,21 +1028,23 @@
     case 0x27: /* RANDOM BLOCK READ FROM FCB FILE */
     case 0x28: /* RANDOM BLOCK WRITE TO FCB FILE */
     case 0x29: /* PARSE FILENAME INTO FCB */
-    case 0x37: /* "SWITCHAR" - GET SWITCH CHARACTER
-                  "SWITCHAR" - SET SWITCH CHARACTER
-                  "AVAILDEV" - SPECIFY \DEV\ PREFIX USE */
     case 0x54: /* GET VERIFY FLAG */
         INT_BARF( context, 0x21 );
         break;
 
+    case 0x02: /* WRITE CHARACTER TO STANDARD OUTPUT */
+    case 0x06: /* DIRECT CONSOLE IN/OUTPUT */
+    	_lwrite16( 1, &DL_reg(context), 1);
+        break;
+
     case 0x07: /* DIRECT CHARACTER INPUT WITHOUT ECHO */
         TRACE(int21,"DIRECT CHARACTER INPUT WITHOUT ECHO\n");
-	_lread16( DOS_TO_HANDLE(0), &AL_reg(context), 1);
+	_lread16( 0, &AL_reg(context), 1);
         break;
 
     case 0x08: /* CHARACTER INPUT WITHOUT ECHO */
         TRACE(int21,"CHARACTER INPUT WITHOUT ECHO\n");
-	_lread16( DOS_TO_HANDLE(0), &AL_reg(context), 1);
+	_lread16( 0, &AL_reg(context), 1);
         break;
 
     case 0x09: /* WRITE STRING TO STANDARD OUTPUT */
@@ -1048,10 +1053,26 @@
         {
             LPSTR data = CTX_SEG_OFF_TO_LIN(context,DS_reg(context),DX_reg(context));
             LONG length = strchr(data,'$')-data;
-            _hwrite16( DOS_TO_HANDLE(1), data, length);
+            _hwrite16( 1, data, length);
         }
         break;
 
+    case 0x0a: /* BUFFERED INPUT */
+      {
+	char *buffer = ((char *)CTX_SEG_OFF_TO_LIN(context,  DS_reg(context), 
+						   DX_reg(context) ));
+	int res;
+	
+	TRACE(int21,"BUFFERED INPUT\n");
+	if (buffer[1])
+	  TRACE(int21,"Handle old chars in buffer!\n");
+	res=_lread16( 0, buffer+2,buffer[0]);
+	buffer[1]=res;
+	if(buffer[res+1] == '\n')
+	  buffer[res+1] = '\r';
+	break;
+      }
+
     case 0x2e: /* SET VERIFY FLAG */
         TRACE(int21,"SET VERIFY FLAG ignored\n");
     	/* we cannot change the behaviour anyway, so just ignore it */
@@ -1241,6 +1262,28 @@
         if (!INT21_GetFreeDiskSpace(context)) AX_reg(context) = 0xffff;
         break;
 
+    case 0x37: 
+      {
+	unsigned char switchchar='/';
+	switch (AL_reg(context))
+	{
+	case 0x00: /* "SWITCHAR" - GET SWITCH CHARACTER */
+	  TRACE(int21,"SWITCHAR - GET SWITCH CHARACTER\n");
+	  AL_reg(context) = 0x00; /* success*/
+	  DL_reg(context) = switchchar;
+	  break;
+	case 0x01: /*"SWITCHAR" - SET SWITCH CHARACTER*/
+	  TRACE(int21,"SWITCHAR - SET SWITCH CHARACTER\n");
+	  switchchar = DL_reg(context);
+	  AL_reg(context) = 0x00; /* success*/
+	  break;
+	default: /*"AVAILDEV" - SPECIFY \DEV\ PREFIX USE*/
+	  INT_BARF( context, 0x21 );
+	  break;
+	}
+	break;
+      }
+
     case 0x38: /* GET COUNTRY-SPECIFIC INFORMATION */
 	TRACE(int21,"GET COUNTRY-SPECIFIC INFORMATION for country 0x%02x\n",
 	      AL_reg(context));
@@ -1271,8 +1314,8 @@
     case 0x3c: /* "CREAT" - CREATE OR TRUNCATE FILE */
         TRACE(int21,"CREAT flag 0x%02x %s\n",CX_reg(context),
 	      (LPCSTR)CTX_SEG_OFF_TO_LIN(context,  DS_reg(context), DX_reg(context)));
-        AX_reg(context) = HANDLE_TO_DOS(_lcreat16( CTX_SEG_OFF_TO_LIN(context,  DS_reg(context),
-                                    DX_reg(context) ), CX_reg(context) ));
+        AX_reg(context) = _lcreat16( CTX_SEG_OFF_TO_LIN(context,  DS_reg(context),
+                                                        DX_reg(context) ), CX_reg(context) );
         bSetDOSExtendedError = (AX_reg(context) == (WORD)HFILE_ERROR16);
         break;
 
@@ -1289,14 +1332,14 @@
 	    DOS_ExtendedError = 0x06;
 	    bSetDOSExtendedError = TRUE;
 	} else
-        bSetDOSExtendedError = ((AX_reg(context) = _lclose16( DOS_TO_HANDLE(BX_reg(context)) )) != 0);
+        bSetDOSExtendedError = ((AX_reg(context) = _lclose16( BX_reg(context) )) != 0);
         break;
 
     case 0x3f: /* "READ" - READ FROM FILE OR DEVICE */
         TRACE(int21,"READ from %d to %04lX:%04X for %d byte\n",BX_reg(context),
 	      DS_reg(context),DX_reg(context),CX_reg(context) );
         {
-            LONG result = _hread16( DOS_TO_HANDLE(BX_reg(context)),
+            LONG result = _hread16( BX_reg(context),
                                     CTX_SEG_OFF_TO_LIN(context, DS_reg(context),
                                                                 DX_reg(context) ),
                                     CX_reg(context) );
@@ -1309,7 +1352,7 @@
         TRACE(int21,"WRITE from %04lX:%04X to handle %d for %d byte\n",
 	      DS_reg(context),DX_reg(context),BX_reg(context),CX_reg(context) );
         {
-            LONG result = _hwrite16( DOS_TO_HANDLE(BX_reg(context)),
+            LONG result = _hwrite16( BX_reg(context),
                                      CTX_SEG_OFF_TO_LIN(context,  DS_reg(context),
                                                          DX_reg(context) ),
                                      CX_reg(context) );
@@ -1331,7 +1374,7 @@
 	      (AL_reg(context)==0)?"start of file":(AL_reg(context)==1)?
 	      "current file position":"end of file");
         {
-            LONG status = _llseek16( DOS_TO_HANDLE(BX_reg(context)),
+            LONG status = _llseek16( BX_reg(context),
                                      MAKELONG(DX_reg(context),CX_reg(context)),
                                      AL_reg(context) );
             if (status == -1) bSetDOSExtendedError = TRUE;
@@ -1381,7 +1424,7 @@
             break;
         case 0x02:{
            FILE_OBJECT *file;
-           file = FILE_GetFile(DOS_TO_HANDLE(BX_reg(context)));
+           file = FILE_GetFile(HFILE16_TO_HFILE32(BX_reg(context)));
            if (!strcasecmp(file->unix_name, "SCSIMGR$"))
                         ASPI_DOS_HandleInt(context);
            FILE_ReleaseFile( file );
@@ -1493,13 +1536,13 @@
 
     case 0x45: /* "DUP" - DUPLICATE FILE HANDLE */
         TRACE(int21,"DUP - DUPLICATE FILE HANDLE %d\n",BX_reg(context));
-        bSetDOSExtendedError = ((AX_reg(context) = HANDLE_TO_DOS(FILE_Dup(DOS_TO_HANDLE(BX_reg(context))))) == (WORD)HFILE_ERROR16);
+        bSetDOSExtendedError = ((AX_reg(context) = HFILE32_TO_HFILE16(FILE_Dup(HFILE16_TO_HFILE32(BX_reg(context))))) == (WORD)HFILE_ERROR16);
         break;
 
     case 0x46: /* "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE */
         TRACE(int21,"FORCEDUP - FORCE DUPLICATE FILE HANDLE %d to %d\n",
 	      BX_reg(context),CX_reg(context));
-        bSetDOSExtendedError = (FILE_Dup2( DOS_TO_HANDLE(BX_reg(context)), DOS_TO_HANDLE(CX_reg(context)) ) == HFILE_ERROR32);
+        bSetDOSExtendedError = (FILE_Dup2( HFILE16_TO_HFILE32(BX_reg(context)), HFILE16_TO_HFILE32(CX_reg(context)) ) == HFILE_ERROR32);
         break;
 
     case 0x47: /* "CWD" - GET CURRENT DIRECTORY */
@@ -1557,7 +1600,7 @@
 	
     case 0x4c: /* "EXIT" - TERMINATE WITH RETURN CODE */
         TRACE(int21,"EXIT with return code %d\n",AL_reg(context));
-        TASK_KillCurrentTask( AL_reg(context) );
+        ExitProcess( AL_reg(context) );
         break;
 
     case 0x4d: /* GET RETURN CODE */
@@ -1586,13 +1629,13 @@
         TRACE(int21,"GET CURRENT PROCESS ID (GET PSP ADDRESS)\n");
         /* FIXME: should we return the original DOS PSP upon */
         /*        Windows startup ? */
-        BX_reg(context) = GetCurrentPDB();
+        BX_reg(context) = INT21_GetCurrentPSP();
         break;
     case 0x62: /* GET PSP ADDRESS */
         TRACE(int21,"GET CURRENT PSP ADDRESS\n");
         /* FIXME: should we return the original DOS PSP upon */
         /*        Windows startup ? */
-        BX_reg(context) = GetCurrentPDB();
+        BX_reg(context) = INT21_GetCurrentPSP();
         break;
 
     case 0x52: /* "SYSVARS" - GET LIST OF LISTS */
@@ -1670,7 +1713,7 @@
         TRACE(int21,"CREATE NEW FILE 0x%02x for %s\n", CX_reg(context),
 	      (LPCSTR)CTX_SEG_OFF_TO_LIN(context,  DS_reg(context), DX_reg(context)));
         bSetDOSExtendedError = ((AX_reg(context) = 
-		HANDLE_TO_DOS(_lcreat_uniq( CTX_SEG_OFF_TO_LIN(context, DS_reg(context),DX_reg(context)), 0 ))) 
+               HFILE32_TO_HFILE16(_lcreat_uniq( CTX_SEG_OFF_TO_LIN(context, DS_reg(context),DX_reg(context)), 0 )))
 								== (WORD)HFILE_ERROR16);
         break;
 
@@ -1789,7 +1832,7 @@
     case 0x68: /* "FFLUSH" - COMMIT FILE */
     case 0x6a: /* COMMIT FILE */
         TRACE(int21,"FFLUSH/COMMIT handle %d\n",BX_reg(context));
-        bSetDOSExtendedError = (!FlushFileBuffers( DOS_TO_HANDLE(BX_reg(context)) ));
+        bSetDOSExtendedError = (!FlushFileBuffers( HFILE16_TO_HFILE32(BX_reg(context)) ));
         break;		
 	
     case 0x69: /* DISK SERIAL NUMBER */
diff --git a/msdos/vxd.c b/msdos/vxd.c
index 3f08ac8..caac7a3 100644
--- a/msdos/vxd.c
+++ b/msdos/vxd.c
@@ -806,7 +806,7 @@
         LARGE_INTEGER *size = (LARGE_INTEGER *)AppToWine(stack[3]);
         DWORD  protect  = stack[4];
         DWORD  flags2   = stack[5];
-        HFILE32 hFile   = stack[6];
+        HFILE32 hFile   = HFILE16_TO_HFILE32(stack[6]);
         DWORD  psp      = stack[7];
 
         HANDLE32 result = INVALID_HANDLE_VALUE32;
diff --git a/multimedia/dsound.c b/multimedia/dsound.c
index d3adc76..654206f 100644
--- a/multimedia/dsound.c
+++ b/multimedia/dsound.c
@@ -242,6 +242,7 @@
 		this->dsound->nrofbuffers--;
 		this->dsound->lpvtbl->fnRelease(this->dsound);
 	}
+	HeapFree(GetProcessHeap(),0,this->buffer);
 	HeapFree(GetProcessHeap(),0,this);
 	return 0;
 }
@@ -784,7 +785,7 @@
 /*			unsigned char	*xbuf = (unsigned char*)(dsb->buffer); */
 			char	*xbuf = dsb->buffer;
 			if (dsb->wfx.nChannels == 1) {
-	printf("Mixing 8-bit stereo into 16!!\n");
+				WARN(dsound,"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)) {
diff --git a/multimedia/mmio.c b/multimedia/mmio.c
index f6bdc77..8443ca1 100644
--- a/multimedia/mmio.c
+++ b/multimedia/mmio.c
@@ -32,7 +32,7 @@
 		case MMIOM_OPEN: {
 			/* Parameters:
 			 * lParam1 = szFileName parameter from mmioOpen
-			 * lParam2 = unused
+			 * lParam2 = reserved (we use it for 16-bitness)
 			 * Returns: zero on success, error code on error
 			 * NOTE: lDiskOffset automatically set to zero
 			 */
@@ -46,8 +46,11 @@
 			}
 
 			/* if filename NULL, assume open file handle in adwInfo[0] */
-			if (!szFileName)
+			if (!szFileName) {
+				if (lParam2) lpmmioinfo->adwInfo[0] =
+					HFILE16_TO_HFILE32(lpmmioinfo->adwInfo[0]);
 				return 0;
+			}
 
 			lpmmioinfo->adwInfo[0] =
 				(DWORD) OpenFile32(szFileName, &ofs, lpmmioinfo->dwFlags);
@@ -110,7 +113,7 @@
 			LONG cch = (LONG) lParam2;
 			LONG count;
 
-			count = _hwrite16((HFILE32)lpmmioinfo->adwInfo[0], pch, cch);
+			count = _hwrite32((HFILE32)lpmmioinfo->adwInfo[0], pch, cch);
 			if (count != -1)
 				lpmmioinfo->lDiskOffset += count;
 
@@ -159,37 +162,97 @@
 *               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);
+	TRACE(mmio,"(%p,0x%04x,0x%08lx,0x%08lx)\n",lpmmioinfo,uMessage,lParam1,lParam2);
+	switch (uMessage) {
+
+		case MMIOM_OPEN: {
+			/* Parameters:
+			 * lParam1 = filename (must be NULL)
+			 * lParam2 = reserved (we use it for 16-bitness)
+			 * Returns: zero on success, error code on error
+			 * NOTE: lDiskOffset automatically set to zero
+			 */
+
+			if (!(lpmmioinfo->dwFlags & MMIO_CREATE))
+				lpmmioinfo->pchEndRead = lpmmioinfo->pchEndWrite;
+
+			return 0;
+		}
+
+		case MMIOM_CLOSE: {
+			/* Parameters:
+			 * lParam1 = wFlags parameter from mmioClose
+			 * lParam2 = unused
+			 * Returns: zero on success, error code on error
+			 */
+
+			return 0;
+
+		}
+
+		case MMIOM_READ: {
+			/* Parameters:
+			 * lParam1 = huge pointer to read buffer
+			 * lParam2 = number of bytes to read
+			 * Returns: number of bytes read, 0 for EOF, -1 for error (error code
+			 *	   in wErrorRet)
+			 * NOTE: lDiskOffset should be updated
+			 */
+
+			HPSTR pch = (HPSTR) lParam1;
+			LONG cch = (LONG) lParam2;
+
+			FIXME(mmio,"MMIOM_READ on memory files should not occur, buffer may be lost!\n");
+			return 0;
+		}
+
+		case MMIOM_WRITE:
+		case MMIOM_WRITEFLUSH: { 
+			/* no internal buffering, so WRITEFLUSH handled same as WRITE */
+
+			/* Parameters:
+			 * lParam1 = huge pointer to write buffer
+			 * lParam2 = number of bytes to write
+			 * Returns: number of bytes written, -1 for error (error code in
+			 *		wErrorRet)
+			 * NOTE: lDiskOffset should be updated
+			 */
+
+			HPSTR pch = (HPSTR) lParam1;
+			LONG cch = (LONG) lParam2;
+
+			FIXME(mmio,"MMIOM_WRITE on memory files should not occur, buffer may be lost!\n");
+			return 0;
+		}
+
+		case MMIOM_SEEK: {
+			/* Parameters:
+			 * lParam1 = new position
+			 * lParam2 = from whence to seek (SEEK_SET, SEEK_CUR, SEEK_END)
+			 * Returns: new file postion, -1 on error
+			 * NOTE: lDiskOffset should be updated
+			 */
+
+			LONG Offset = (LONG) lParam1; 
+			LONG Whence = (LONG) lParam2; 
+
+			FIXME(mmio,"MMIOM_SEEK on memory files should not occur, buffer may be lost!\n");
+			return -1;
+		}
+		  
+		default:
+			FIXME(mmio, "unexpected message %u\n", uMessage);
+			return 0;
+	}
+	
 	return 0;
 }
 
 /**************************************************************************
- * 				mmioOpenW       		[WINMM.123]
+ * 		MMIO_Open      		[internal]
  */
-HMMIO32 WINAPI mmioOpen32W(LPWSTR szFileName, MMIOINFO32 * lpmmioinfo,
-                          DWORD dwOpenFlags)
-{
-	LPSTR	szFn = HEAP_strdupWtoA(GetProcessHeap(),0,szFileName);
-	HMMIO32 ret = mmioOpen16(szFn,(LPMMIOINFO16)lpmmioinfo,dwOpenFlags);
-
-	HeapFree(GetProcessHeap(),0,szFn);
-	return ret;
-}
-
-/**************************************************************************
- * 				mmioOpenA       		[WINMM.122]
- */
-HMMIO32 WINAPI mmioOpen32A(LPSTR szFileName, MMIOINFO32 * lpmmioinfo,
-                          DWORD dwOpenFlags)
-{
-	return mmioOpen16(szFileName,(LPMMIOINFO16)lpmmioinfo,dwOpenFlags);
-}
-
-/**************************************************************************
- * 				mmioOpen       		[MMSYSTEM.1210]
- */
-HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16 * lpmmioinfo,
-                          DWORD dwOpenFlags)
+static HMMIO16 MMIO_Open(LPSTR szFileName, MMIOINFO16 * lpmmioinfo,
+			DWORD dwOpenFlags, int use16)
 {
 	LPMMIOINFO16 lpmminfo;
 	HMMIO16 hmmio;
@@ -207,7 +270,7 @@
 	if (!lpmmioinfo ||
 		(lpmmioinfo->fccIOProc == 0 && lpmmioinfo->pIOProc == NULL)) {
 
-		lpmminfo->fccIOProc = mmioFOURCC('D', 'O', 'S', ' ');
+		lpmminfo->fccIOProc = FOURCC_DOS;
 		lpmminfo->pIOProc = (LPMMIOPROC16) mmioDosIOProc;
 	}
 	/* if just the four character code is present, look up IO proc */
@@ -230,13 +293,20 @@
 				lpmmioinfo->wErrorRet = result;
 			return 0;
 		}
+	} else
+	if (lpmminfo->fccIOProc == FOURCC_MEM) {
+		if ((result = mmioSetBuffer(hmmio, lpmmioinfo->pchBuffer, lpmmioinfo->cchBuffer, 0))) {
+			if (lpmmioinfo)
+				lpmmioinfo->wErrorRet = result;
+			return 0;
+		}
 	}
 
 	lpmminfo->dwFlags = dwOpenFlags;
 	lpmminfo->hmmio = hmmio;
 
 	/* call IO proc to actually open file */
-	result = (UINT16) mmioSendMessage(hmmio, MMIOM_OPEN, (LPARAM) szFileName, (LPARAM) 0);
+	result = (UINT16) mmioSendMessage(hmmio, MMIOM_OPEN, (LPARAM) szFileName, (LPARAM) use16);
 
 	GlobalUnlock16(hmmio);
 
@@ -248,6 +318,37 @@
 	return hmmio;
 }
 
+/**************************************************************************
+ * 				mmioOpenW       		[WINMM.123]
+ */
+HMMIO32 WINAPI mmioOpen32W(LPWSTR szFileName, MMIOINFO32 * lpmmioinfo,
+                          DWORD dwOpenFlags)
+{
+	LPSTR	szFn = HEAP_strdupWtoA(GetProcessHeap(),0,szFileName);
+	HMMIO32 ret = MMIO_Open(szFn,(LPMMIOINFO16)lpmmioinfo,dwOpenFlags,FALSE);
+
+	HeapFree(GetProcessHeap(),0,szFn);
+	return ret;
+}
+
+/**************************************************************************
+ * 				mmioOpenA       		[WINMM.122]
+ */
+HMMIO32 WINAPI mmioOpen32A(LPSTR szFileName, MMIOINFO32 * lpmmioinfo,
+                          DWORD dwOpenFlags)
+{
+	return MMIO_Open(szFileName,(LPMMIOINFO16)lpmmioinfo,dwOpenFlags,FALSE);
+}
+
+/**************************************************************************
+ * 				mmioOpen       		[MMSYSTEM.1210]
+ */
+HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16 * lpmmioinfo,
+                          DWORD dwOpenFlags)
+{
+	return MMIO_Open(szFileName,(LPMMIOINFO16)lpmmioinfo,dwOpenFlags,TRUE);
+}
+
     
 /**************************************************************************
  * 				mmioClose      		[WINMM.114]
@@ -304,7 +405,7 @@
 
 	if (lpmminfo->pchNext != lpmminfo->pchEndRead) {
 		count = lpmminfo->pchEndRead - lpmminfo->pchNext;
-		if (count > cch) count = cch;
+		if (count > cch || count < 0) count = cch;
 		memcpy(pch, lpmminfo->pchNext, count);
 		lpmminfo->pchNext += count;
 		pch += count;
@@ -312,15 +413,19 @@
 	} else
 		count = 0;
 
-	if (cch) {
+	if (cch&&(lpmminfo->fccIOProc!=FOURCC_MEM)) {
 		if (lpmminfo->cchBuffer) {
 			mmioFlush32(hmmio, MMIO_EMPTYBUF);
 
 			while (cch) {
-				LONG size = mmioSendMessage(hmmio, MMIOM_READ,
+				LONG size;
+				lpmminfo->lBufOffset = lpmminfo->lDiskOffset;
+				lpmminfo->pchNext = lpmminfo->pchBuffer;
+				lpmminfo->pchEndRead = lpmminfo->pchBuffer;
+				size = mmioSendMessage(hmmio, MMIOM_READ,
 						(LPARAM) lpmminfo->pchBuffer,
 						(LPARAM) lpmminfo->cchBuffer);
-				lpmminfo->pchNext = lpmminfo->pchBuffer;
+				if (size<=0) break;
 				lpmminfo->pchEndRead = lpmminfo->pchBuffer + size;
 				if (size > cch) size = cch;
 				memcpy(pch, lpmminfo->pchNext, size);
@@ -331,6 +436,7 @@
 			}
 		} else {
 			count += mmioSendMessage(hmmio, MMIOM_READ, (LPARAM) pch, (LPARAM) cch);
+			if (count>0) lpmminfo->lBufOffset += count;
 		}
 	}
 
@@ -366,12 +472,18 @@
 		while (cch) {
 			if (lpmminfo->pchNext != lpmminfo->pchEndWrite) {
 				count = lpmminfo->pchEndWrite - lpmminfo->pchNext;
-				if (count > cch) count = cch;
+				if (count > cch || count < 0) count = cch;
 				memcpy(lpmminfo->pchNext, pch, count);
 				lpmminfo->pchNext += count;
 				pch += count;
 				cch -= count;
 				lpmminfo->dwFlags |= MMIO_DIRTY;
+			} else
+			if (lpmminfo->fccIOProc==FOURCC_MEM) {
+				if (lpmminfo->adwInfo[0]) {
+					/* from where would we get the memory handle? */
+					FIXME(mmio, "memory file expansion not implemented!\n");
+				} else break;
 			}
 
 			if (lpmminfo->pchNext == lpmminfo->pchEndWrite
@@ -379,6 +491,7 @@
 		}
 	} else {
 		count = mmioSendMessage(hmmio, MMIOM_WRITE, (LPARAM) pch, (LPARAM) cch);
+		lpmminfo->lBufOffset = lpmminfo->lDiskOffset;
 	}
 
 	GlobalUnlock16(hmmio);
@@ -404,14 +517,28 @@
 
 	TRACE(mmio, "(%04X, %08lX, %d);\n", hmmio, lOffset, iOrigin);
 
-	if (mmioFlush32(hmmio, MMIO_EMPTYBUF))
-		return -1;
-
 	lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
 	if (lpmminfo == NULL)
-		return 0;
+		return -1;
+
+	offset = (iOrigin==SEEK_SET)?(lOffset - lpmminfo->lBufOffset):
+		 (iOrigin==SEEK_CUR)?(lOffset +
+		 (lpmminfo->pchNext - lpmminfo->pchBuffer)):-1;
+
+	if ((lpmminfo->cchBuffer<0)||
+	    ((offset>=0)&&(offset<=(lpmminfo->pchEndRead-lpmminfo->pchBuffer)))) {
+		lpmminfo->pchNext = lpmminfo->pchBuffer + offset;
+		GlobalUnlock16(hmmio);
+		return lpmminfo->lBufOffset + offset;
+	}
+
+	if ((lpmminfo->fccIOProc==FOURCC_MEM)||mmioFlush32(hmmio, MMIO_EMPTYBUF)) {
+		GlobalUnlock16(hmmio);
+		return -1;
+	}
 
 	offset = mmioSendMessage(hmmio, MMIOM_SEEK, (LPARAM) lOffset, (LPARAM) iOrigin);
+	lpmminfo->lBufOffset = lpmminfo->lDiskOffset;
 
 	GlobalUnlock16(hmmio);
 	return offset;
@@ -554,24 +681,30 @@
 	lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) return 0;
 
+	if ((!lpmminfo->cchBuffer)||(lpmminfo->fccIOProc==FOURCC_MEM)) {
+		GlobalUnlock16(hmmio);
+		return 0;
+	}
 	/* not quite sure what to do here, but I'll guess */
-	if (lpmminfo->dwFlags&MMIO_DIRTY) {
-		if (lpmminfo->pchNext != (lpmminfo->pchBuffer + lpmminfo->lBufOffset)) {
-			if (lpmminfo->dwFlags&MMIO_READWRITE)
-				mmioSendMessage(hmmio, MMIOM_SEEK,
-					(LPARAM) (lpmminfo->pchBuffer - lpmminfo->pchEndRead) + lpmminfo->lBufOffset,
-					(LPARAM) SEEK_CUR );
-			mmioSendMessage(hmmio, MMIOM_WRITE,
-				(LPARAM) lpmminfo->pchBuffer + lpmminfo->lBufOffset,
-				(LPARAM) (lpmminfo->pchNext - lpmminfo->pchBuffer) - lpmminfo->lBufOffset );
-		}
-		lpmminfo->lBufOffset = lpmminfo->pchNext - lpmminfo->pchBuffer;
+	if (lpmminfo->dwFlags & MMIO_DIRTY) {
+		mmioSendMessage(hmmio, MMIOM_SEEK,
+			(LPARAM) lpmminfo->lBufOffset,
+			(LPARAM) SEEK_SET);
+		mmioSendMessage(hmmio, MMIOM_WRITE,
+			(LPARAM) lpmminfo->pchBuffer,
+			(LPARAM) (lpmminfo->pchNext - lpmminfo->pchBuffer) );
 		lpmminfo->dwFlags &= ~MMIO_DIRTY;
 	}
 	if (uFlags & MMIO_EMPTYBUF) {
+		/* seems Windows doesn't do any seeking here, hopefully this
+		   won't matter, otherwise a slight rewrite is necessary */
+		mmioSendMessage(hmmio, MMIOM_SEEK,
+			(LPARAM) (lpmminfo->lBufOffset +
+				  (lpmminfo->pchNext - lpmminfo->pchBuffer)),
+			(LPARAM) SEEK_SET);
 		lpmminfo->pchNext = lpmminfo->pchBuffer;
 		lpmminfo->pchEndRead = lpmminfo->pchBuffer;
-		lpmminfo->lBufOffset = 0;
+		lpmminfo->lBufOffset = lpmminfo->lDiskOffset;
 	}
 
 	GlobalUnlock16(hmmio);
@@ -595,15 +728,26 @@
 	TRACE(mmio, "mmioAdvance\n");
 	lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) return 0;
+	if (!lpmminfo->cchBuffer) {
+		GlobalUnlock16(hmmio);
+		return MMIOERR_UNBUFFERED;
+	}
+	lpmminfo->pchNext = lpmmioinfo->pchNext;
+	if (mmioFlush32(hmmio, MMIO_EMPTYBUF)) {
+		GlobalUnlock16(hmmio);
+		return MMIOERR_CANNOTWRITE;
+	}
 	if (uFlags == MMIO_READ)
 	        lpmmioinfo->pchEndRead = lpmmioinfo->pchBuffer +
 	            mmioSendMessage(hmmio, MMIOM_READ,
 	                (LPARAM) lpmmioinfo->pchBuffer,
 	                (LPARAM) lpmmioinfo->cchBuffer);
+#if 0   /* mmioFlush32 already did the writing */
 	if (uFlags == MMIO_WRITE)
 	            mmioSendMessage(hmmio, MMIOM_WRITE,
 	                (LPARAM) lpmmioinfo->pchBuffer,
 	                (LPARAM) lpmmioinfo->cchBuffer);
+#endif
 	lpmmioinfo->pchNext = lpmmioinfo->pchBuffer;
 	GlobalUnlock16(hmmio);
 	return 0;
@@ -618,15 +762,26 @@
 	TRACE(mmio, "mmioAdvance\n");
 	lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) return 0;
+	if (!lpmminfo->cchBuffer) {
+		GlobalUnlock16(hmmio);
+		return MMIOERR_UNBUFFERED;
+	}
+	lpmminfo->pchNext = lpmmioinfo->pchNext;
+	if (mmioFlush32(hmmio, MMIO_EMPTYBUF)) {
+		GlobalUnlock16(hmmio);
+		return MMIOERR_CANNOTWRITE;
+	}
 	if (uFlags == MMIO_READ)
 	        lpmmioinfo->pchEndRead = lpmmioinfo->pchBuffer +
 	            mmioSendMessage(hmmio, MMIOM_READ,
 	                (LPARAM) lpmmioinfo->pchBuffer,
 	                (LPARAM) lpmmioinfo->cchBuffer);
+#if 0   /* mmioFlush32 already did the writing */
 	if (uFlags == MMIO_WRITE)
 	            mmioSendMessage(hmmio, MMIOM_WRITE,
 	                (LPARAM) lpmmioinfo->pchBuffer,
 	                (LPARAM) lpmmioinfo->cchBuffer);
+#endif
 	lpmmioinfo->pchNext = lpmmioinfo->pchBuffer;
 	GlobalUnlock16(hmmio);
 	return 0;
@@ -786,10 +941,17 @@
 		while (TRUE) {
 		        LONG ix;
 
-			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)) {
-
+			ix = mmioRead32(hmmio, (LPSTR)lpck, 3 * sizeof(DWORD));
+			TRACE(mmio, "after _lread32 ix = %ld req = %d, errno = %d\n",ix,3 * sizeof(DWORD),errno);
+			if (ix < sizeof(DWORD)) {
+				mmioSeek32(hmmio, dwOldPos, SEEK_SET);
+				WARN(mmio, "return ChunkNotFound\n");
+				return MMIOERR_CHUNKNOTFOUND;
+			}
+			lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
+			if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) 
+				lpck->dwDataOffset += sizeof(DWORD);
+			if (ix < lpck->dwDataOffset - dwOldPos) {
 				mmioSeek32(hmmio, dwOldPos, SEEK_SET);
 				WARN(mmio, "return ChunkNotFound\n");
 				return MMIOERR_CHUNKNOTFOUND;
@@ -799,9 +961,7 @@
 			if (dwfcc == lpck->ckid)
 				break;
 
-			dwOldPos += lpck->cksize + 2 * sizeof(DWORD);
-			if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) 
-				dwOldPos += sizeof(DWORD);
+			dwOldPos = lpck->dwDataOffset + lpck->cksize;
 			mmioSeek32(hmmio, dwOldPos, SEEK_SET);
 		}
 	}
@@ -811,10 +971,10 @@
 			WARN(mmio, "return ChunkNotFound 2nd\n");
 			return MMIOERR_CHUNKNOTFOUND;
 		}
+		lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
+		if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) 
+			lpck->dwDataOffset += sizeof(DWORD);
 	}
-	lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
-	if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) 
-		lpck->dwDataOffset += sizeof(DWORD);
 	mmioSeek32(hmmio, lpck->dwDataOffset, SEEK_SET);
 
 	TRACE(mmio, "lpck->ckid=%08lX lpck->cksize=%ld !\n", 
@@ -833,7 +993,8 @@
 				hmmio, lpck, uFlags);
 	if (lpck->dwFlags&MMIO_DIRTY) {
 		DWORD	dwOldPos, dwNewSize, dwSizePos;
-		
+
+		TRACE(mmio, "chunk is marked MMIO_DIRTY, correcting chunk size\n");
 		dwOldPos = mmioSeek32(hmmio, 0, SEEK_CUR);
 		TRACE(mmio, "dwOldPos=%ld\n", dwOldPos);
 		dwNewSize = dwOldPos - lpck->dwDataOffset;
@@ -882,6 +1043,8 @@
 	else if (uFlags == MMIO_CREATERIFF)
 		lpck->ckid = FOURCC_RIFF;
 
+	TRACE(mmio, "ckid=%08lX\n", lpck->ckid);
+
 	lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
 	if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) 
 		lpck->dwDataOffset += sizeof(DWORD);
diff --git a/multimedia/mmsystem.c b/multimedia/mmsystem.c
index 458a5be..40d4424 100644
--- a/multimedia/mmsystem.c
+++ b/multimedia/mmsystem.c
@@ -162,13 +162,17 @@
 		TRACE(mmsys, "Stop !\n");
 		return FALSE;
 		}
-	hmmio = mmioOpen16((LPSTR)lpszSoundName, NULL, 
-		MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
-
 	if (uFlags & SND_MEMORY) {
-		FIXME(mmsys, "SND_MEMORY flag not implemented!\n");
-		return FALSE;
-	}
+		MMIOINFO16 mminfo;
+		memset(&mminfo, 0, sizeof(mminfo));
+		mminfo.fccIOProc = FOURCC_MEM;
+		mminfo.pchBuffer = (LPSTR)lpszSoundName;
+		mminfo.cchBuffer = -1;
+		TRACE(mmsys, "Memory sound %p\n",lpszSoundName);
+		hmmio = mmioOpen16(NULL, &mminfo, MMIO_READ);
+	} else
+		hmmio = mmioOpen16((LPSTR)lpszSoundName, NULL, 
+			MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
 
 	if (hmmio == 0) 
 	{
@@ -233,7 +237,7 @@
 			    {
 				WAVEHDR		waveHdr;
 				HGLOBAL16	hData;
-				INT32		count, bufsize;
+				INT32		count, bufsize, left = mmckInfo.cksize;
 
 				bufsize = 64000;
 				hData = GlobalAlloc16(GMEM_MOVEABLE, bufsize);
@@ -246,10 +250,12 @@
 				dwRet = wodMessage(0,WODM_PREPARE,0,(DWORD)&waveHdr,sizeof(WAVEHDR));
 				if (dwRet == MMSYSERR_NOERROR) 
 				{
-				    while( TRUE )
+				    while( left )
 				    {
+					if (bufsize > left) bufsize = left;
 					count = mmioRead32(hmmio,waveHdr.lpData,bufsize);
 					if (count < 1) break;
+					left -= count;
 					waveHdr.dwBufferLength = count;
 				/*	waveHdr.dwBytesRecorded = count; */
 					/* FIXME: doesn't expect async ops */ 
diff --git a/objects/bitmap.c b/objects/bitmap.c
index a3df02b..2480f27 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -394,6 +394,22 @@
             tbuf += pad;
 	}
         break;
+
+    case 32:
+        for (h=0;h<height;h++)
+        {
+            for (w=0;w<bmp->bitmap.bmWidth;w++)
+            {
+	    	long pixel = XGetPixel(image,w,h);
+
+		*tbuf++ = pixel & 0xff;
+		*tbuf++ = (pixel>> 8) & 0xff;
+		*tbuf++ = (pixel>>16) & 0xff;
+		*tbuf++ = (pixel>>24) & 0xff;
+	    }
+            tbuf += pad;
+	}
+        break;
     default:
         FIXME(bitmap, "Unhandled bits:%d\n", bmp->bitmap.bmBitsPixel);
     }
@@ -524,6 +540,20 @@
             sbuf += pad;
         }
         break;
+    case 32: 
+        for (h=0;h<height;h++)
+        {
+            for (w=0;w<bmp->bitmap.bmWidth;w++)
+            {
+                XPutPixel(image,w,h,(sbuf[3]<<24)+(sbuf[2]<<16)+(sbuf[1]<<8)+sbuf[0]);
+                sbuf += 4;
+            }
+            sbuf += pad;
+        }
+        break;
+    default:
+      FIXME(bitmap, "Unhandled bits:%d\n", bmp->bitmap.bmBitsPixel);
+
     }
 
     descr.bmp    = bmp;
@@ -684,7 +714,7 @@
  * FIXME: implementation still lacks nearly all features, see LR_*
  * defines in windows.h
  */
-HANDLE32 WINAPI CopyImage32( HANDLE32 hnd, UINT32 type, INT32 desiredx,
+HICON32 WINAPI CopyImage32( HANDLE32 hnd, UINT32 type, INT32 desiredx,
                              INT32 desiredy, UINT32 flags )
 {
     switch (type)
@@ -699,7 +729,6 @@
     return 0;
 }
 
-
 /**********************************************************************
  *	    LoadBitmap16    (USER.175)
  *
diff --git a/objects/color.c b/objects/color.c
index 6487adb..65fdccc 100644
--- a/objects/color.c
+++ b/objects/color.c
@@ -816,9 +816,11 @@
 {
     XColor color;
 
+#if 0
     /* truecolor visual */
 
     if (screenDepth >= 24) return pixel;
+#endif
 
     /* check for hicolor visuals first */
 
diff --git a/objects/dc.c b/objects/dc.c
index 20243c3..1899d48 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -1497,3 +1497,24 @@
     return 0;
 }
 
+/***********************************************************************
+ *           SetICMMode    (GDI32.318)
+ */
+INT32 WINAPI SetICMMode(HDC32 hdc, INT32 iEnableICM)
+{
+/*FIXME  Asuming that ICM is always off, and cannot be turned on */
+    if (iEnableICM == ICM_OFF) return ICM_OFF;
+    if (iEnableICM == ICM_ON) return 0;
+    if (iEnableICM == ICM_QUERY) return ICM_OFF;
+    return 0;
+}
+
+
+/***********************************************************************
+ *           GetColorSpace    (GDI32.165)
+ */
+HCOLORSPACE32 WINAPI GetColorSpace(HDC32 hdc)
+{
+/*FIXME    Need to to whatever GetColorSpace actually does */
+    return 0;
+}
diff --git a/objects/font.c b/objects/font.c
index 91434d3..95575b4 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -927,9 +927,9 @@
  *    Success: Non-zero or size of required buffer
  *    Failure: 0
  */
-INT16 WINAPI GetOutlineTextMetrics(
+UINT16 WINAPI GetOutlineTextMetrics16(
     HDC16 hdc,    /* [in]  Handle of device context */
-    INT16 cbData, /* [in]  Size of metric data array */
+    UINT16 cbData, /* [in]  Size of metric data array */
     void *lpOTM)  /* [out] Address of metric data array */
 {
     FIXME(font, "(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
@@ -1036,7 +1036,7 @@
 /***********************************************************************
  *          GetAspectRatioFilterEx16  (GDI.486)
  */
-BOOL16 GetAspectRatioFilterEx16( HDC16 hdc, LPVOID pAspectRatio )
+BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
 {
   FIXME(font, "(%04x, %p): -- Empty Stub !\n",
 		hdc, pAspectRatio);
@@ -1290,8 +1290,8 @@
  * GetCharacterPlacement32A [GDI32.160]
  */
 DWORD WINAPI
-GetCharacterPlacement32A(HDC32 hdc, LPCSTR lpString, UINT32 uCount,
-			 INT32 nMaxExtent, GCP_RESULTS32A lpResults,
+GetCharacterPlacement32A(HDC32 hdc, LPCSTR lpString, INT32 uCount,
+			 INT32 nMaxExtent, GCP_RESULTS32A *lpResults,
 			 DWORD dwFlags)
 {
     /* return value 0 is correct for most cases anyway */
@@ -1303,12 +1303,11 @@
  * GetCharacterPlacement32W [GDI32.161]
  */
 DWORD WINAPI
-GetCharacterPlacement32W(HDC32 hdc, LPCWSTR lpString, UINT32 uCount,
-			 INT32 nMaxExtent, GCP_RESULTS32W lpResults,
+GetCharacterPlacement32W(HDC32 hdc, LPCWSTR lpString, INT32 uCount,
+			 INT32 nMaxExtent, GCP_RESULTS32W *lpResults,
 			 DWORD dwFlags)
 {
     /* return value 0 is correct for most cases anyway */
     FIXME(font,":stub!\n");
     return 0;
 }
-
diff --git a/ole/Makefile.in b/ole/Makefile.in
index bbe7198..134f4fc 100644
--- a/ole/Makefile.in
+++ b/ole/Makefile.in
@@ -8,7 +8,6 @@
 C_SRCS = \
 	compobj.c \
 	ifs.c \
-	folders.c \
 	moniker.c \
 	ole2.c \
 	ole2disp.c \
diff --git a/ole/folders.c b/ole/folders.c
deleted file mode 100644
index 3ddde11..0000000
--- a/ole/folders.c
+++ /dev/null
@@ -1,2215 +0,0 @@
-/*
- *	Shell Folder stuff (...and all the OLE-Objects of SHELL32.DLL)
- *
- *	Copyright 1997	Marcus Meissner
- *	Copyright 1998	Juergen Schmied
- *
- *  !!! currently work in progress on all classes !!!
- *  <contact juergen.schmied@metronet.de, 980801>
- */
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include "ole.h"
-#include "ole2.h"
-#include "debug.h"
-#include "compobj.h"
-#include "interfaces.h"
-#include "shlobj.h"
-#include "winerror.h"
-#include "winnls.h"
-#include "winproc.h"
-
-/* FIXME should be moved to a header file. IsEqualGUID 
-is declared but not exported in compobj.c !!!*/
-#define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID)))
-#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2)
-#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2)
-/***************************************************************************
- *  GetNextElement (internal function)
- *
- * gets a part of a string till the first backslash
- *
- * PARAMETERS
- *  pszNext [IN] string to get the element from
- *  pszOut  [IN] pointer to buffer whitch receives string
- *  dwOut   [IN] length of pszOut
- *
- *  RETURNS
- *    LPSTR pointer to first, not yet parsed char
- */
-LPSTR GetNextElement(LPSTR pszNext,LPSTR pszOut,DWORD dwOut)
-{ LPSTR   pszTail = pszNext;
-  DWORD dwCopy;
-  TRACE(shell,"(%s %p 0x%08lx)\n",debugstr_a(pszNext),pszOut,dwOut);
-
-  if(!pszNext || !*pszNext)
-    return NULL;
-
-  while(*pszTail && (*pszTail != '\\'))
-  { pszTail++;
-  }
-  dwCopy=((LPBYTE)pszTail-(LPBYTE)pszNext)/sizeof(CHAR)+1;
-  lstrcpyn32A(pszOut, pszNext, (dwOut<dwCopy)? dwOut : dwCopy);
-
-  if(*pszTail)
-  {  pszTail++;
-	}
-
-  TRACE(shell,"--(%s %s 0x%08lx)\n",debugstr_a(pszNext),debugstr_a(pszOut),dwOut);
-  return pszTail;
-}
-
-/**************************************************************************
-*  IClassFactory Implementation
-*/
-static HRESULT WINAPI IClassFactory_QueryInterface(LPCLASSFACTORY,REFIID,LPVOID*);
-static ULONG WINAPI IClassFactory_AddRef(LPCLASSFACTORY);
-static ULONG WINAPI IClassFactory_Release(LPCLASSFACTORY);
-static HRESULT WINAPI IClassFactory_CreateInstance();
-static HRESULT WINAPI IClassFactory_LockServer();
-/**************************************************************************
- *  IClassFactory_VTable
- */
-static IClassFactory_VTable clfvt = 
-{ IClassFactory_QueryInterface,
-	IClassFactory_AddRef,
-	IClassFactory_Release,
-	IClassFactory_CreateInstance,
-  IClassFactory_LockServer
-};
-
-/**************************************************************************
- *  IClassFactory_Constructor
- */
-
-LPCLASSFACTORY IClassFactory_Constructor()
-{	LPCLASSFACTORY	lpclf;
-
-	lpclf= (LPCLASSFACTORY)HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactory));
-	lpclf->ref = 1;
-	lpclf->lpvtbl = &clfvt;
-  TRACE(shell,"(%p)->()\n",lpclf);
-	return lpclf;
-}
-/**************************************************************************
- *  IClassFactory::QueryInterface
- */
-static HRESULT WINAPI IClassFactory_QueryInterface(
-  LPCLASSFACTORY this, REFIID riid, LPVOID *ppvObj)
-{  char	xriid[50];
-   WINE_StringFromCLSID((LPCLSID)riid,xriid);
-   TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",this,xriid);
-
-  *ppvObj = NULL;
-
-  if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
-  { *ppvObj = this; 
-  }
-  else if(IsEqualIID(riid, &IID_IClassFactory))  /*IClassFactory*/
-  {    *ppvObj = (IClassFactory*)this;
-  }   
-
-  if(*ppvObj)
-  { (*(LPCLASSFACTORY*)ppvObj)->lpvtbl->fnAddRef(this);  	
-    TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
-    return S_OK;
-  }
-	TRACE(shell,"-- Interface: E_NOINTERFACE\n");
-  return E_NOINTERFACE;
-}  
-/******************************************************************************
- * IClassFactory_AddRef
- */
-static ULONG WINAPI IClassFactory_AddRef(LPCLASSFACTORY this)
-{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
-	return ++(this->ref);
-}
-/******************************************************************************
- * IClassFactory_Release
- */
-static ULONG WINAPI IClassFactory_Release(LPCLASSFACTORY this)
-{	TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
-	if (!--(this->ref)) 
-	{ TRACE(shell,"-- destroying IClassFactory(%p)\n",this);
-		HeapFree(GetProcessHeap(),0,this);
-		return 0;
-	}
-	return this->ref;
-}
-/******************************************************************************
- * IClassFactory_CreateInstance
- */
-static HRESULT WINAPI IClassFactory_CreateInstance(
-  LPCLASSFACTORY this, LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject)
-{ IUnknown *pObj = NULL;
-	HRESULT hres;
-	char	xriid[50];
-
-  WINE_StringFromCLSID((LPCLSID)riid,xriid);
-  TRACE(shell,"%p->(%p,\n\tIID:\t%s,%p)\n",this,pUnknown,xriid,ppObject);
-
-	*ppObject = NULL;
-		
-	if(pUnknown)
-	{	return(CLASS_E_NOAGGREGATION);
-	}
-
-	if (IsEqualIID(riid, &IID_IShellFolder))
-  { pObj = (IUnknown *)IShellFolder_Constructor(NULL,NULL);
-  } 
-  else if (IsEqualIID(riid, &IID_IShellView))
-  { pObj = (IUnknown *)IShellView_Constructor();
-  } 
-  else if (IsEqualIID(riid, &IID_IShellLink))
-  { pObj = (IUnknown *)IShellLink_Constructor();
-  } 
-	else
-	{ ERR(shell,"unknown IID requested\n\tIID:\t%s\n",xriid);
-	  return(E_NOINTERFACE);
-	}
-	
-  if (!pObj)
-  { return(E_OUTOFMEMORY);
-  }
-	 
-	hres = pObj->lpvtbl->fnQueryInterface(pObj,riid, ppObject);
-  pObj->lpvtbl->fnRelease(pObj);
-  TRACE(shell,"-- Object created: (%p)->%p\n",this,*ppObject);
-
-  return hres;
-}
-/******************************************************************************
- * IClassFactory_LockServer
- */
-static HRESULT WINAPI IClassFactory_LockServer(LPCLASSFACTORY this, BOOL32 fLock)
-{ TRACE(shell,"%p->(0x%x), not implemented\n",this, fLock);
-  return E_NOTIMPL;
-}
-
-/**************************************************************************
- *  IEnumIDList Implementation
- */
-static HRESULT WINAPI IEnumIDList_QueryInterface(LPENUMIDLIST,REFIID,LPVOID*);
-static ULONG WINAPI IEnumIDList_AddRef(LPENUMIDLIST);
-static ULONG WINAPI IEnumIDList_Release(LPENUMIDLIST);
-static HRESULT WINAPI IEnumIDList_Next(LPENUMIDLIST,ULONG,LPITEMIDLIST*,ULONG*);
-static HRESULT WINAPI IEnumIDList_Skip(LPENUMIDLIST,ULONG);
-static HRESULT WINAPI IEnumIDList_Reset(LPENUMIDLIST);
-static HRESULT WINAPI IEnumIDList_Clone(LPENUMIDLIST,LPENUMIDLIST*);
-static BOOL32 WINAPI IEnumIDList_CreateEnumList(LPENUMIDLIST,LPCSTR, DWORD);
-static BOOL32 WINAPI IEnumIDList_AddToEnumList(LPENUMIDLIST,LPITEMIDLIST);
-static BOOL32 WINAPI IEnumIDList_DeleteList(LPENUMIDLIST);
-/**************************************************************************
- *  IEnumIDList_VTable
- */
-static IEnumIDList_VTable eidlvt = 
-{ IEnumIDList_QueryInterface,
-	IEnumIDList_AddRef,
-	IEnumIDList_Release,
-	IEnumIDList_Next,
-	IEnumIDList_Skip,
-	IEnumIDList_Reset,
-  IEnumIDList_Clone,
-	IEnumIDList_CreateEnumList,
-  IEnumIDList_AddToEnumList,
-	IEnumIDList_DeleteList
-};
-
-/**************************************************************************
- *  IEnumIDList_Constructor
- */
-
-LPENUMIDLIST IEnumIDList_Constructor( LPCSTR lpszPath, DWORD dwFlags, HRESULT* pResult)
-{	LPENUMIDLIST	lpeidl;
-
-	lpeidl = (LPENUMIDLIST)HeapAlloc(GetProcessHeap(),0,sizeof(IEnumIDList));
-	lpeidl->ref = 1;
-	lpeidl->lpvtbl = &eidlvt;
-	lpeidl->mpFirst=NULL;
-	lpeidl->mpLast=NULL;
-	lpeidl->mpCurrent=NULL;
-
-  TRACE(shell,"(%p)->(%s 0x%08lx %p)\n",lpeidl,debugstr_a(lpszPath),dwFlags,pResult);
-
-	lpeidl->mpPidlMgr=PidlMgr_Constructor();
-  if (!lpeidl->mpPidlMgr)
-	{ if (pResult)
-	  { *pResult=E_OUTOFMEMORY;
-			HeapFree(GetProcessHeap(),0,lpeidl);
-			return NULL;
-		}
-	}
-
-	if(!IEnumIDList_CreateEnumList(lpeidl, lpszPath, dwFlags))
-  { if(pResult)
-    { *pResult = E_OUTOFMEMORY;
-			HeapFree(GetProcessHeap(),0,lpeidl->mpPidlMgr);
-			HeapFree(GetProcessHeap(),0,lpeidl);
-			return NULL;
-		}
-  }
-
-  TRACE(shell,"-- (%p)->()\n",lpeidl);
-	return lpeidl;
-}
-
-/**************************************************************************
- *  EnumIDList::QueryInterface
- */
-static HRESULT WINAPI IEnumIDList_QueryInterface(
-  LPENUMIDLIST this, REFIID riid, LPVOID *ppvObj)
-{  char	xriid[50];
-   WINE_StringFromCLSID((LPCLSID)riid,xriid);
-   TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);
-
-  *ppvObj = NULL;
-
-  if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
-  { *ppvObj = this; 
-  }
-  else if(IsEqualIID(riid, &IID_IEnumIDList))  /*IEnumIDList*/
-  {    *ppvObj = (IEnumIDList*)this;
-  }   
-
-  if(*ppvObj)
-  { (*(LPENUMIDLIST*)ppvObj)->lpvtbl->fnAddRef(this);  	
-    TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
-    return S_OK;
-  }
-	TRACE(shell,"-- Interface: E_NOINTERFACE\n");
-	return E_NOINTERFACE;
-}   
-
-/******************************************************************************
- * IEnumIDList_AddRef
- */
-static ULONG WINAPI IEnumIDList_AddRef(LPENUMIDLIST this)
-{ TRACE(shell,"(%p)->()\n",this);
-	return ++(this->ref);
-}
-/******************************************************************************
- * IEnumIDList_Release
- */
-static ULONG WINAPI IEnumIDList_Release(LPENUMIDLIST this)
-{	TRACE(shell,"(%p)->()\n",this);
-	if (!--(this->ref)) 
-	{ TRACE(shell," destroying IEnumIDList(%p)\n",this);
-		HeapFree(GetProcessHeap(),0,this);
-		return 0;
-	}
-	return this->ref;
-}
-   
-/**************************************************************************
- *  IEnumIDList_Next
- */
-
-static HRESULT WINAPI IEnumIDList_Next(
-	LPENUMIDLIST this,ULONG celt,LPITEMIDLIST * rgelt,ULONG *pceltFetched) 
-{ ULONG    i;
-  HRESULT  hr = S_OK;
-  LPITEMIDLIST  temp;
-
-	TRACE(shell,"(%p)->(%ld,%p, %p)\n",this,celt,rgelt,pceltFetched);
-
-  /* It is valid to leave pceltFetched NULL when celt is 1. Some of explorer's
-     subsystems actually use it (and so may a third party browser)
-   */
-  if(pceltFetched)
-    *pceltFetched = 0;
-
-	*rgelt=0;
-	
-  if(celt > 1 && !pceltFetched)
-  { return E_INVALIDARG;
-	}
-
-  for(i = 0; i < celt; i++)
-  { if(!(this->mpCurrent))
-    { hr =  S_FALSE;
-      break;
-    }
-    temp = ILClone(this->mpCurrent->pidl);
-    rgelt[i] = temp;
-    this->mpCurrent = this->mpCurrent->pNext;
-  }
-  if(pceltFetched)
-  {  *pceltFetched = i;
-	}
-
-  return hr;
-}
-
-/**************************************************************************
-*  IEnumIDList_Skip
-*/
-static HRESULT WINAPI IEnumIDList_Skip(
-	LPENUMIDLIST this,ULONG celt)
-{ DWORD    dwIndex;
-  HRESULT  hr = S_OK;
-
-  TRACE(shell,"(%p)->(%lu)\n",this,celt);
-
-  for(dwIndex = 0; dwIndex < celt; dwIndex++)
-  { if(!this->mpCurrent)
-    { hr = S_FALSE;
-      break;
-    }
-    this->mpCurrent = this->mpCurrent->pNext;
-  }
-  return hr;
-}
-/**************************************************************************
-*  IEnumIDList_Reset
-*/
-static HRESULT WINAPI IEnumIDList_Reset(LPENUMIDLIST this)
-{ TRACE(shell,"(%p)\n",this);
-  this->mpCurrent = this->mpFirst;
-  return S_OK;
-}
-/**************************************************************************
-*  IEnumIDList_Clone
-*/
-static HRESULT WINAPI IEnumIDList_Clone(
-	LPENUMIDLIST this,LPENUMIDLIST * ppenum)
-{ TRACE(shell,"(%p)->() to (%p)->() E_NOTIMPL\n",this,ppenum);
-	return E_NOTIMPL;
-}
-/**************************************************************************
- *  EnumIDList_CreateEnumList()
- *  fixme: devices not handled
- *  fixme: add wildcards to path
- */
-static BOOL32 WINAPI IEnumIDList_CreateEnumList(LPENUMIDLIST this, LPCSTR lpszPath, DWORD dwFlags)
-{ LPITEMIDLIST   pidl=NULL;
-  WIN32_FIND_DATA32A stffile;	
-  HANDLE32 hFile;
-  DWORD dwDrivemap;
-  CHAR  szDriveName[4];
-  CHAR  szPath[MAX_PATH];
-    
-  TRACE(shell,"(%p)->(%s 0x%08lx) \n",this,debugstr_a(lpszPath),dwFlags);
-
-  if (lpszPath && lpszPath[0]!='\0')
-  { strcpy(szPath, lpszPath);
-    PathAddBackslash(szPath);
-    strcat(szPath,"*.*");
-  }
-
-  /*enumerate the folders*/
-  if(dwFlags & SHCONTF_FOLDERS)
-  {	/* special case - we can't enumerate the Desktop level Objects (MyComputer,Nethood...
-    so we need to fake an enumeration of those.*/
-	  if(!lpszPath)
-    { TRACE (shell,"-- (%p)-> enumerate SHCONTF_FOLDERS (special) items\n",this);
-  		//create the pidl for this item
-      pidl = this->mpPidlMgr->lpvtbl->fnCreateMyComputer(this->mpPidlMgr);
-      if(pidl)
-      { if(!IEnumIDList_AddToEnumList(this, pidl))
-        return FALSE;
-      }
-    }   
-    else if (lpszPath[0]=='\0') /* enumerate the drives*/
-    { TRACE (shell,"-- (%p)-> enumerate SHCONTF_FOLDERS (drives)\n",this);
-      dwDrivemap = GetLogicalDrives();
-      strcpy (szDriveName,"A:\\");
-      while (szDriveName[0]<='Z')
-      { if(dwDrivemap & 0x00000001L)
-        { pidl = this->mpPidlMgr->lpvtbl->fnCreateDrive(this->mpPidlMgr,szDriveName );
-      if(pidl)
-      { if(!IEnumIDList_AddToEnumList(this, pidl))
-          return FALSE;
-      }
-      }
-        szDriveName[0]++;
-        dwDrivemap = dwDrivemap >> 1;
-     }   
-    }
-    
-     else
-    { TRACE (shell,"-- (%p)-> enumerate SHCONTF_FOLDERS of %s\n",this,debugstr_a(szPath));
-      hFile = FindFirstFile32A(szPath,&stffile);
-      if ( hFile != INVALID_HANDLE_VALUE32 )
-      { do
-        { if ( (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && strcmp (stffile.cFileName, ".") && strcmp (stffile.cFileName, ".."))
-          { pidl = this->mpPidlMgr->lpvtbl->fnCreateFolder(this->mpPidlMgr, stffile.cFileName);
-         if(pidl)
-         { if(!IEnumIDList_AddToEnumList(this, pidl))
-               {  return FALSE;
-               }
-         }
-         else
-         { return FALSE;
-         }   
-           }
-      } while( FindNextFile32A(hFile,&stffile));
-			FindClose32 (hFile);
-    }
-  }   
-  }   
-  //enumerate the non-folder items (values)
-  if(dwFlags & SHCONTF_NONFOLDERS)
-  { if(lpszPath)
-    { TRACE (shell,"-- (%p)-> enumerate SHCONTF_NONFOLDERS of %s\n",this,debugstr_a(szPath));
-      hFile = FindFirstFile32A(szPath,&stffile);
-      if ( hFile != INVALID_HANDLE_VALUE32 )
-      { do
-    { if (! (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
-          { pidl = this->mpPidlMgr->lpvtbl->fnCreateValue(this->mpPidlMgr, stffile.cFileName);
-      if(pidl)
-      { if(!IEnumIDList_AddToEnumList(this, pidl))
-        { return FALSE;
-			  }
-      }
-      else
-      { return FALSE;
-      }   
-          }
-    } while( FindNextFile32A(hFile,&stffile));
-	  FindClose32 (hFile);
-  } 
-    }
-  } 
-  return TRUE;
-}
-
-/**************************************************************************
- *  EnumIDList_AddToEnumList()
- */
-static BOOL32 WINAPI IEnumIDList_AddToEnumList(LPENUMIDLIST this,LPITEMIDLIST pidl)
-{ LPENUMLIST  pNew;
-
-  TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl);
-  pNew = (LPENUMLIST)HeapAlloc(GetProcessHeap(),0,sizeof(ENUMLIST));
-  if(pNew)
-  { //set the next pointer
-    pNew->pNext = NULL;
-    pNew->pidl = pidl;
-
-    //is this the first item in the list?
-    if(!this->mpFirst)
-    { this->mpFirst = pNew;
-      this->mpCurrent = pNew;
-    }
-   
-    if(this->mpLast)
-    { //add the new item to the end of the list
-      this->mpLast->pNext = pNew;
-    }
-   
-    //update the last item pointer
-    this->mpLast = pNew;
-    TRACE(shell,"-- (%p)->(first=%p, last=%p)\n",this,this->mpFirst,this->mpLast);
-    return TRUE;
-  }
-  return FALSE;
-}
-/**************************************************************************
-*   EnumIDList_DeleteList()
-*/
-static BOOL32 WINAPI IEnumIDList_DeleteList(LPENUMIDLIST this)
-{ LPENUMLIST  pDelete;
-
-  TRACE(shell,"(%p)->()\n",this);
-	
-  while(this->mpFirst)
-  { pDelete = this->mpFirst;
-    this->mpFirst = pDelete->pNext;
-    SHFree(pDelete->pidl);
-    SHFree(pDelete);
-  }
-  this->mpFirst = this->mpLast = this->mpCurrent = NULL;
-  return TRUE;
-}
-/***********************************************************************
-*   IShellView implementation
-*/
-static HRESULT WINAPI IShellView_QueryInterface(LPSHELLVIEW,REFIID riid, LPVOID *ppvObj);
-static ULONG WINAPI IShellView_AddRef(LPSHELLVIEW) ;
-static ULONG WINAPI IShellView_Release(LPSHELLVIEW);
-
-    // *** IOleWindow methods ***
-static HRESULT WINAPI IShellView_GetWindow(LPSHELLVIEW,HWND32 * lphwnd);
-static HRESULT WINAPI IShellView_ContextSensitiveHelp(LPSHELLVIEW,BOOL32 fEnterMode);
-
-    // *** IShellView methods ***
-static HRESULT WINAPI IShellView_TranslateAccelerator(LPSHELLVIEW,LPMSG32 lpmsg);
-static HRESULT WINAPI IShellView_EnableModeless(LPSHELLVIEW,BOOL32 fEnable);
-static HRESULT WINAPI IShellView_UIActivate(LPSHELLVIEW,UINT32 uState);
-static HRESULT WINAPI IShellView_Refresh(LPSHELLVIEW);
-static HRESULT WINAPI IShellView_CreateViewWindow(LPSHELLVIEW, IShellView *lpPrevView,LPCFOLDERSETTINGS lpfs, IShellBrowser * psb,RECT32 * prcView, HWND32  *phWnd);
-static HRESULT WINAPI IShellView_DestroyViewWindow(LPSHELLVIEW);
-static HRESULT WINAPI IShellView_GetCurrentInfo(LPSHELLVIEW, LPFOLDERSETTINGS lpfs);
-static HRESULT WINAPI IShellView_AddPropertySheetPages(LPSHELLVIEW, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam);
-static HRESULT WINAPI IShellView_SaveViewState(LPSHELLVIEW);
-static HRESULT WINAPI IShellView_SelectItem(LPSHELLVIEW, LPCITEMIDLIST pidlItem, UINT32 uFlags);
-static HRESULT WINAPI IShellView_GetItemObject(LPSHELLVIEW, UINT32 uItem, REFIID riid,LPVOID *ppv);
-
-static struct IShellView_VTable svvt = 
-{ IShellView_QueryInterface,
-  IShellView_AddRef,
-  IShellView_Release,
-  IShellView_GetWindow,
-  IShellView_ContextSensitiveHelp,
-  IShellView_TranslateAccelerator,
-  IShellView_EnableModeless,
-  IShellView_UIActivate,
-  IShellView_Refresh,
-  IShellView_CreateViewWindow,
-  IShellView_DestroyViewWindow,
-  IShellView_GetCurrentInfo,
-  IShellView_AddPropertySheetPages,
-  IShellView_SaveViewState,
-  IShellView_SelectItem,
-  IShellView_GetItemObject
-};
-/**************************************************************************
-*  IShellView_Constructor
-*/
-LPSHELLVIEW IShellView_Constructor(LPSHELLFOLDER pFolder, LPCITEMIDLIST pidl)
-{ LPSHELLVIEW sv;
-  sv=(LPSHELLVIEW)HeapAlloc(GetProcessHeap(),0,sizeof(IShellView));
-  sv->ref=1;
-  sv->lpvtbl=&svvt;
-  
-  sv->mpidl = ILClone(pidl);
-
-  sv->pSFParent = pFolder;
-  if(sv->pSFParent)
-    sv->pSFParent->lpvtbl->fnAddRef(sv->pSFParent);
-
-  TRACE(shell,"(%p)->(%p pidl=%p)\n",sv, pFolder, pidl);
-  return sv;
-}
-/**************************************************************************
-*  ShellView_WndProc
-*/
-LRESULT CALLBACK ShellView_WndProc(HWND32 hWnd, UINT32 uMessage, WPARAM32 wParam, LPARAM lParam)
-{ LPSHELLVIEW pThis = (LPSHELLVIEW)GetWindowLong32A(hWnd, GWL_USERDATA);
-  LPCREATESTRUCT32A lpcs;
-
-  FIXME(shell,"(hwnd=%x msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
-    
-  switch (uMessage)
-  { case WM_NCCREATE:
-      { TRACE(shell,"WM_NCCREATE\n");
-        lpcs = (LPCREATESTRUCT32A)lParam;
-        pThis = (LPSHELLVIEW)(lpcs->lpCreateParams);
-        SetWindowLong32A(hWnd, GWL_USERDATA, (LONG)pThis);
-
-        //set the window handle
-        pThis->hWnd = hWnd;
-      }
-      break;
-   
-   case WM_SIZE:
-      TRACE(shell,"WM_SIZE\n");
-      return FALSE;
-   
-   case WM_CREATE:
-      TRACE(shell,"WM_CREATE\n");
-      return FALSE;
-   
-   case WM_SETFOCUS:
-      TRACE(shell,"WM_SETFOCUS\n");   
-      return FALSE;
-   
-   case WM_KILLFOCUS:
-      TRACE(shell,"WM_KILLFOCUS\n");
-      return FALSE;
-
-   case WM_ACTIVATE:
-      TRACE(shell,"WM_ACTIVATE\n");
-      return FALSE;
-   
-   case WM_COMMAND:
-      TRACE(shell,"WM_COMMAND\n");
-      return FALSE;
-   
-   case WM_INITMENUPOPUP:
-      TRACE(shell,"WM_INITMENUPOPUP\n");
-      return FALSE;
-   
-   case WM_NOTIFY:
-      TRACE(shell,"WM_NOTIFY\n");
-      return FALSE;
-   
-/*   case WM_SETTINGCHANGE:
-      return FALSE;*/
-  }
-
-  return DefWindowProc32A (hWnd, uMessage, wParam, lParam);
-}
-
-
-/**************************************************************************
-*  IShellView::QueryInterface
-*/
-static HRESULT WINAPI IShellView_QueryInterface(LPSHELLVIEW this,REFIID riid, LPVOID *ppvObj)
-{ char    xriid[50];
-  WINE_StringFromCLSID((LPCLSID)riid,xriid);
-  TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);
-
-  *ppvObj = NULL;
-
-  if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
-  { *ppvObj = this; 
-  }
-  else if(IsEqualIID(riid, &IID_IShellView))  /*IShellView*/
-  { *ppvObj = (IShellView*)this;
-  }   
-
-  if(*ppvObj)
-  { (*(LPSHELLVIEW*)ppvObj)->lpvtbl->fnAddRef(this);      
-    TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
-    return S_OK;
-  }
-  TRACE(shell,"-- Interface: E_NOINTERFACE\n");
-  return E_NOINTERFACE;
-}   
-/**************************************************************************
-*  IShellView::AddRef
-*/
-static ULONG WINAPI IShellView_AddRef(LPSHELLVIEW this)
-{ TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
-  return ++(this->ref);
-}
-/**************************************************************************
-*  IShellView::Release
-*/
-static ULONG WINAPI IShellView_Release(LPSHELLVIEW this)
-{ TRACE(shell,"(%p)->()\n",this);
-  if (!--(this->ref)) 
-  { TRACE(shell," destroying IEnumIDList(%p)\n",this);
-
-    if(this->pSFParent)
-       this->pSFParent->lpvtbl->fnRelease(this->pSFParent);
-
-    HeapFree(GetProcessHeap(),0,this);
-    return 0;
-  }
-  return this->ref;
-}
-/**************************************************************************
-*  IShellView::GetWindow
-*/
-static HRESULT WINAPI IShellView_GetWindow(LPSHELLVIEW this,HWND32 * phWnd)
-{ TRACE(shell,"(%p) stub\n",this);
- *phWnd = this->hWnd;
-
- return S_OK;
-}
-static HRESULT WINAPI IShellView_ContextSensitiveHelp(LPSHELLVIEW this,BOOL32 fEnterMode)
-{ FIXME(shell,"(%p) stub\n",this);
-  return E_NOTIMPL;
-}
-static HRESULT WINAPI IShellView_TranslateAccelerator(LPSHELLVIEW this,LPMSG32 lpmsg)
-{ FIXME(shell,"(%p)->(%p) stub\n",this,lpmsg);
-  return E_NOTIMPL;
-}
-static HRESULT WINAPI IShellView_EnableModeless(LPSHELLVIEW this,BOOL32 fEnable)
-{ FIXME(shell,"(%p) stub\n",this);
-  return E_NOTIMPL;
-}
-static HRESULT WINAPI IShellView_UIActivate(LPSHELLVIEW this,UINT32 uState)
-{ FIXME(shell,"(%p) stub\n",this);
-  return E_NOTIMPL;
-}
-static HRESULT WINAPI IShellView_Refresh(LPSHELLVIEW this)
-{ FIXME(shell,"(%p) stub\n",this);
-  return S_OK;
-}
-static HRESULT WINAPI IShellView_CreateViewWindow(LPSHELLVIEW this, IShellView *lpPrevView,
-                     LPCFOLDERSETTINGS lpfs, IShellBrowser * psb,RECT32 * prcView, HWND32  *phWnd)
-{  WNDCLASS32A wc;
-   *phWnd = 0;
-
-   TRACE(shell,"(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",this, lpPrevView,lpfs, psb, prcView, phWnd);
-
-//if our window class has not been registered, then do so
-  if(!GetClassInfo32A(shell32_hInstance, SV_CLASS_NAME, &wc))
-  { ZeroMemory(&wc, sizeof(wc));
-    wc.style          = CS_HREDRAW | CS_VREDRAW;
-    wc.lpfnWndProc    = (WNDPROC32) ShellView_WndProc;
-    wc.cbClsExtra     = 0;
-    wc.cbWndExtra     = 0;
-    wc.hInstance      = shell32_hInstance;
-    wc.hIcon          = 0;
-    wc.hCursor        = LoadCursor32A (0, IDC_ARROW32A);
-    wc.hbrBackground  = (HBRUSH32)(COLOR_WINDOW + 1);
-    wc.lpszMenuName   = NULL;
-    wc.lpszClassName  = SV_CLASS_NAME;
-   
-    if(!RegisterClass32A(&wc))
-      return E_FAIL;
-   }
-   //set up the member variables
-   this->pShellBrowser = psb;
-   this->FolderSettings = *lpfs;
-
-   //get our parent window
-   this->pShellBrowser->lpvtbl->fnGetWindow(this->pShellBrowser, &(this->hWndParent));
-
-   *phWnd = CreateWindowEx32A(0, SV_CLASS_NAME, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
-                           prcView->left, prcView->top, prcView->right - prcView->left, prcView->bottom - prcView->top,
-                           this->hWndParent, 0, shell32_hInstance, (LPVOID)this);
-                           
-   if(!*phWnd)
-     return E_FAIL;
-
-   this->pShellBrowser->lpvtbl->fnAddRef(this->pShellBrowser);
-
-   return S_OK;
-}
-
-static HRESULT WINAPI IShellView_DestroyViewWindow(LPSHELLVIEW this)
-{ FIXME(shell,"(%p) stub\n",this);
-
-  this->pShellBrowser->lpvtbl->fnRelease(this->pShellBrowser);
-
-  return S_OK;
-}
-static HRESULT WINAPI IShellView_GetCurrentInfo(LPSHELLVIEW this, LPFOLDERSETTINGS lpfs)
-{ FIXME(shell,"(%p)->(%p)stub\n",this, lpfs);
-
-  *lpfs = this->FolderSettings;
-  return S_OK;
-}
-static HRESULT WINAPI IShellView_AddPropertySheetPages(LPSHELLVIEW this, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
-{ FIXME(shell,"(%p) stub\n",this);
-  return E_NOTIMPL;
-}
-static HRESULT WINAPI IShellView_SaveViewState(LPSHELLVIEW this)
-{ FIXME(shell,"(%p) stub\n",this);
-  return S_OK;
-}
-static HRESULT WINAPI IShellView_SelectItem(LPSHELLVIEW this, LPCITEMIDLIST pidlItem, UINT32 uFlags)
-{ FIXME(shell,"(%p)->(pidl=%p, 0x%08x) stub\n",this, pidlItem, uFlags);
-  return E_NOTIMPL;
-}
-static HRESULT WINAPI IShellView_GetItemObject(LPSHELLVIEW this, UINT32 uItem, REFIID riid,LPVOID *ppvOut)
-{ char    xriid[50];
-  WINE_StringFromCLSID((LPCLSID)riid,xriid);
-
-  FIXME(shell,"(%p)->(0x%08x,\n\t%s, %p)stub\n",this, uItem, xriid, ppvOut);
-
-  *ppvOut = NULL;
-  return E_NOTIMPL;
-}
-
-/***********************************************************************
-*   IShellFolder implementation
-*/
-static HRESULT WINAPI IShellFolder_QueryInterface(LPSHELLFOLDER,REFIID,LPVOID*);
-static ULONG WINAPI IShellFolder_AddRef(LPSHELLFOLDER);
-static ULONG WINAPI IShellFolder_Release(LPSHELLFOLDER);
-static HRESULT WINAPI IShellFolder_Initialize(LPSHELLFOLDER,LPCITEMIDLIST);
-static HRESULT WINAPI IShellFolder_ParseDisplayName(LPSHELLFOLDER,HWND32,LPBC,LPOLESTR32,DWORD*,LPITEMIDLIST*,DWORD*);
-static HRESULT WINAPI IShellFolder_EnumObjects(LPSHELLFOLDER,HWND32,DWORD,LPENUMIDLIST*);
-static HRESULT WINAPI IShellFolder_BindToObject(LPSHELLFOLDER,LPCITEMIDLIST,LPBC,REFIID,LPVOID*);
-static HRESULT WINAPI IShellFolder_BindToStorage(LPSHELLFOLDER,LPCITEMIDLIST,LPBC,REFIID,LPVOID*);
-static HRESULT WINAPI IShellFolder_CompareIDs(LPSHELLFOLDER,LPARAM,LPCITEMIDLIST,LPCITEMIDLIST);
-static HRESULT WINAPI IShellFolder_CreateViewObject(LPSHELLFOLDER,HWND32,REFIID,LPVOID*);
-static HRESULT WINAPI IShellFolder_GetAttributesOf(LPSHELLFOLDER,UINT32,LPCITEMIDLIST*,DWORD*);
-static HRESULT WINAPI IShellFolder_GetUIObjectOf(LPSHELLFOLDER,HWND32,UINT32,LPCITEMIDLIST*,REFIID,UINT32*,LPVOID*);
-static HRESULT WINAPI IShellFolder_GetDisplayNameOf(LPSHELLFOLDER,LPCITEMIDLIST,DWORD,LPSTRRET);
-static HRESULT WINAPI IShellFolder_SetNameOf(LPSHELLFOLDER,HWND32,LPCITEMIDLIST,LPCOLESTR32,DWORD,LPITEMIDLIST*);
-/***********************************************************************
-*
-*	  IShellFolder_VTable
-*/
-static struct IShellFolder_VTable sfvt = 
-{ IShellFolder_QueryInterface,
-	IShellFolder_AddRef,
-	IShellFolder_Release,
-	IShellFolder_ParseDisplayName,
-	IShellFolder_EnumObjects,
-	IShellFolder_BindToObject,
-  IShellFolder_BindToStorage,
-  IShellFolder_CompareIDs,
-	IShellFolder_CreateViewObject,
-	IShellFolder_GetAttributesOf,
-  IShellFolder_GetUIObjectOf,
-  IShellFolder_GetDisplayNameOf,
-  IShellFolder_SetNameOf
-  /*    IShellFolder_Initialize*/
-};
-/**************************************************************************
-*	  IShellFolder_Constructor
-*/
-
-LPSHELLFOLDER IShellFolder_Constructor(LPSHELLFOLDER pParent,LPITEMIDLIST pidl) 
-{ LPSHELLFOLDER    sf;
-	DWORD dwSize=0;
-  sf=(LPSHELLFOLDER)HeapAlloc(GetProcessHeap(),0,sizeof(IShellFolder));
-  sf->ref=1;
-  sf->lpvtbl=&sfvt;
-  sf->mlpszFolder=NULL;
-	sf->mpSFParent=pParent;
-
-	TRACE(shell,"(%p)->(parent=%p, pidl=%p)\n",sf,pParent, pidl);
-	
-	/* create own pidl-manager*/
-  sf->pPidlMgr  = PidlMgr_Constructor();
-	if (! sf->pPidlMgr )
-	{ HeapFree(GetProcessHeap(),0,sf);
-	  ERR (shell,"-- Could not initialize PidMGR\n");
-	  return NULL;
-	}
-
-  /* keep a copy of the pidl in the instance*/
-  sf->mpidl = ILClone(pidl);
-	sf->mpidlNSRoot = NULL;
-	
-  if(sf->mpidl)        /* do we have a pidl?*/
-  { dwSize = 0;
-    if(sf->mpSFParent->mlpszFolder)
-    { dwSize += strlen(sf->mpSFParent->mlpszFolder) + 1;
-    }   
-    dwSize += sf->pPidlMgr->lpvtbl->fnGetFolderText(sf->pPidlMgr,sf->mpidl,NULL,0);
-    sf->mlpszFolder = SHAlloc(dwSize);
-    if(sf->mlpszFolder)
-    { *(sf->mlpszFolder)=0x00;
-      if(sf->mpSFParent->mlpszFolder)
-      {  strcpy(sf->mlpszFolder, sf->mpSFParent->mlpszFolder);
-         PathAddBackslash (sf->mlpszFolder);
-      }
-      sf->pPidlMgr->lpvtbl->fnGetFolderText(sf->pPidlMgr, sf->mpidl, sf->mlpszFolder+strlen(sf->mlpszFolder), dwSize-strlen(sf->mlpszFolder));
-    }
-  }
-	
-  TRACE(shell,"-- (%p)->(%p,%p,parent=%s)\n",sf,pParent, pidl, debugstr_a(sf->mlpszFolder));
-	return sf;
-}
-/**************************************************************************
-*  IShellFolder::QueryInterface
-* PARAMETERS
-*  REFIID riid,        //[in ] Requested InterfaceID
-*  LPVOID* ppvObject)  //[out] Interface* to hold the result
-*/
-static HRESULT WINAPI IShellFolder_QueryInterface(
-  LPSHELLFOLDER this, REFIID riid, LPVOID *ppvObj)
-{  char	xriid[50];
-   WINE_StringFromCLSID((LPCLSID)riid,xriid);
-   TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);
-
-  *ppvObj = NULL;
-
-  if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
-  { *ppvObj = this; 
-  }
-  else if(IsEqualIID(riid, &IID_IShellFolder))  /*IShellFolder*/
-  {    *ppvObj = (IShellFolder*)this;
-  }   
-
-  if(*ppvObj)
-  { (*(LPSHELLFOLDER*)ppvObj)->lpvtbl->fnAddRef(this);  	
-    TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
-		return S_OK;
-  }
-	TRACE(shell,"-- Interface: E_NOINTERFACE\n");
-	return E_NOINTERFACE;
-}   
-
-/**************************************************************************
-*  IShellFolder::AddRef
-*/
-
-static ULONG WINAPI IShellFolder_AddRef(LPSHELLFOLDER this)
-{	TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
-	return ++(this->ref);
-}
-
-/**************************************************************************
- *  IShellFolder_Release
- */
-static ULONG WINAPI IShellFolder_Release(LPSHELLFOLDER this) 
-{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
-  if (!--(this->ref)) 
-  { TRACE(shell,"-- destroying IShellFolder(%p)\n",this);
-
-		if (pdesktopfolder==this)
-		{ pdesktopfolder=NULL;
-		  TRACE(shell,"-- destroyed IShellFolder(%p) was Desktopfolder\n",this);
-		}
-    if (this->pPidlMgr)
-    { PidlMgr_Destructor(this->pPidlMgr);
-    }
-    if(this->mpidlNSRoot)
-    { SHFree(this->mpidlNSRoot);
-    }
-    if(this->mpidl)
-    { SHFree(this->mpidl);
-    }
-    if(this->mlpszFolder)
-    { SHFree(this->mlpszFolder);
-    }
-
-		HeapFree(GetProcessHeap(),0,this);
-
-		return 0;
-	}
-	return this->ref;
-}
-/**************************************************************************
-*		IShellFolder_ParseDisplayName
-* PARAMETERS
-*  HWND          hwndOwner,      //[in ] Parent window for any message's
-*  LPBC          pbc,            //[in ] reserved
-*  LPOLESTR      lpszDisplayName,//[in ] "Unicode" displayname.
-*  ULONG*        pchEaten,       //[out] (unicode) characters processed
-*  LPITEMIDLIST* ppidl,          //[out] complex pidl to item
-*  ULONG*        pdwAttributes   //[out] items attributes
-*
-* FIXME: 
-*    pdwAttributes: not used
-*/
-static HRESULT WINAPI IShellFolder_ParseDisplayName(
-	LPSHELLFOLDER this,
-	HWND32 hwndOwner,
-	LPBC pbcReserved,
-    LPOLESTR32 lpszDisplayName,
-    DWORD *pchEaten,
-    LPITEMIDLIST *ppidl,
-	DWORD *pdwAttributes)
-{	HRESULT        hr=E_OUTOFMEMORY;
-  LPITEMIDLIST   pidlFull=NULL, pidlTemp = NULL, pidlOld = NULL;
-  LPSTR          pszNext=NULL;
-  CHAR           szElement[MAX_PATH];
-  BOOL32         bType;
-
-  DWORD          dwChars=lstrlen32W(lpszDisplayName) + 1;
-  LPSTR          pszTemp=(LPSTR)HeapAlloc(GetProcessHeap(),0,dwChars * sizeof(CHAR));
-       
-  TRACE(shell,"(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
-	this,hwndOwner,pbcReserved,lpszDisplayName,debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
-
-  if(pszTemp)
-  { hr = E_FAIL;
-    WideCharToLocal32(pszTemp, lpszDisplayName, dwChars);
-    if(*pszTemp)
-    { if (strcmp(pszTemp,"Desktop")==0)
-      { pidlFull = (LPITEMIDLIST)HeapAlloc(GetProcessHeap(),0,2);
-			  pidlFull->mkid.cb = 0;
-			}
-		  else
-			{ pidlFull = this->pPidlMgr->lpvtbl->fnCreateMyComputer(this->pPidlMgr);
-
-        /* check if the lpszDisplayName is Folder or File*/
-  			bType = ! (GetFileAttributes32A(pszNext)&FILE_ATTRIBUTE_DIRECTORY);
-  			pszNext = GetNextElement(pszTemp, szElement, MAX_PATH);
-  
-        pidlTemp = this->pPidlMgr->lpvtbl->fnCreateDrive(this->pPidlMgr,szElement);			
-        pidlOld = pidlFull;
-        pidlFull = ILCombine(pidlFull,pidlTemp);
-        SHFree(pidlOld);
-  
-  			if(pidlFull)
-        { while((pszNext=GetNextElement(pszNext, szElement, MAX_PATH)))
-          { if(!*pszNext && bType)
-  					{ pidlTemp = this->pPidlMgr->lpvtbl->fnCreateValue(this->pPidlMgr,szElement);
-  					}
-  					else				
-            { pidlTemp = this->pPidlMgr->lpvtbl->fnCreateFolder(this->pPidlMgr,szElement);
-  					}
-            pidlOld = pidlFull;
-            pidlFull = ILCombine(pidlFull,pidlTemp);
-            SHFree(pidlOld);
-          }
-          hr = S_OK;
-        }
-      }
-		}
-  }
-	HeapFree(GetProcessHeap(),0,pszTemp);
-  *ppidl = pidlFull;
-  return hr;
-}
-
-/**************************************************************************
-*		IShellFolder_EnumObjects
-* PARAMETERS
-*  HWND          hwndOwner,    //[in ] Parent Window
-*  DWORD         grfFlags,     //[in ] SHCONTF enumeration mask
-*  LPENUMIDLIST* ppenumIDList  //[out] IEnumIDList interface
-*/
-static HRESULT WINAPI IShellFolder_EnumObjects(
-	LPSHELLFOLDER this,
-	HWND32 hwndOwner,
-	DWORD dwFlags,
-	LPENUMIDLIST* ppEnumIDList)
-{ HRESULT  hr;
-	TRACE(shell,"(%p)->(HWND=0x%08x,0x%08lx,%p)\n",this,hwndOwner,dwFlags,ppEnumIDList);
-
-  *ppEnumIDList = NULL;
-	*ppEnumIDList = IEnumIDList_Constructor (this->mlpszFolder, dwFlags, &hr);
-  TRACE(shell,"-- (%p)->(new ID List: %p)\n",this,*ppEnumIDList);
-  if(!*ppEnumIDList)
-  { return hr;
-  }
-  return S_OK;		
-}
-/**************************************************************************
- *  IShellFolder_Initialize()
- *  IPersistFolder Method
- */
-static HRESULT WINAPI IShellFolder_Initialize(
-	LPSHELLFOLDER this,
-	LPCITEMIDLIST pidl)
-{ TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl);
-  if(this->mpidlNSRoot)
-  { SHFree(this->mpidlNSRoot);
-    this->mpidlNSRoot = NULL;
-  }
-  this->mpidlNSRoot=ILClone(pidl);
-  return S_OK;
-}
-
-/**************************************************************************
-*		IShellFolder_BindToObject
-* PARAMETERS
-*  LPCITEMIDLIST pidl,       //[in ] complex pidl to open
-*  LPBC          pbc,        //[in ] reserved
-*  REFIID        riid,       //[in ] Initial Interface
-*  LPVOID*       ppvObject   //[out] Interface*
-*/
-static HRESULT WINAPI IShellFolder_BindToObject(
-	LPSHELLFOLDER this,
-	LPCITEMIDLIST pidl,
-	LPBC pbcReserved,
-	REFIID riid,
-	LPVOID * ppvOut)
-{	char	        xriid[50];
-  HRESULT       hr;
-	LPSHELLFOLDER pShellFolder;
-	
-	WINE_StringFromCLSID(riid,xriid);
-
-	TRACE(shell,"(%p)->(pidl=%p,%p,\n\tIID:%s,%p)\n",this,pidl,pbcReserved,xriid,ppvOut);
-
-  *ppvOut = NULL;
-  pShellFolder = IShellFolder_Constructor(this, pidl);
-  if(!pShellFolder)
-    return E_OUTOFMEMORY;
-  /*  pShellFolder->lpvtbl->fnInitialize(pShellFolder, this->mpidlNSRoot);*/
-  IShellFolder_Initialize(pShellFolder, this->mpidlNSRoot);
-  hr = pShellFolder->lpvtbl->fnQueryInterface(pShellFolder, riid, ppvOut);
-  pShellFolder->lpvtbl->fnRelease(pShellFolder);
-	TRACE(shell,"-- (%p)->(interface=%p)\n",this, ppvOut);
-  return hr;
-}
-
-/**************************************************************************
-*  IShellFolder_BindToStorage
-* PARAMETERS
-*  LPCITEMIDLIST pidl,       //[in ] complex pidl to store
-*  LPBC          pbc,        //[in ] reserved
-*  REFIID        riid,       //[in ] Initial storage interface 
-*  LPVOID*       ppvObject   //[out] Interface* returned
-*/
-static HRESULT WINAPI IShellFolder_BindToStorage(
-  	LPSHELLFOLDER this,
-    LPCITEMIDLIST pidl, /*simple/complex pidl*/
-    LPBC pbcReserved, 
-    REFIID riid, 
-    LPVOID *ppvOut)
-{	char xriid[50];
-	WINE_StringFromCLSID(riid,xriid);
-
-	FIXME(shell,"(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",this,pidl,pbcReserved,xriid,ppvOut);
-
-  *ppvOut = NULL;
-  return E_NOTIMPL;
-}
-
-/**************************************************************************
-*  IShellFolder_CompareIDs
-*
-* PARMETERS
-*  LPARAM        lParam, //[in ] Column?
-*  LPCITEMIDLIST pidl1,  //[in ] simple pidl
-*  LPCITEMIDLIST pidl2)  //[in ] simple pidl
-* FIXME
-*  we have to handle simple pidl's only
-*/
-static HRESULT WINAPI  IShellFolder_CompareIDs(
-  	LPSHELLFOLDER this,
-		LPARAM lParam, 
-    LPCITEMIDLIST pidl1, /*simple pidl*/
-    LPCITEMIDLIST pidl2) /*simple pidl*/
-{ CHAR szString1[MAX_PATH] = "";
-  CHAR szString2[MAX_PATH] = "";
-  int   nReturn;
-  LPCITEMIDLIST  pidlTemp1 = pidl1, pidlTemp2 = pidl2;
-
-  TRACE(shell,"(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",this,lParam,pidl1,pidl2);
-
-  /*Special case - If one of the items is a Path and the other is a File, always 
-  make the Path come before the File.*/
-
-  /* get the last item in each list */
-  while((this->pPidlMgr->lpvtbl->fnGetNextItem(this->pPidlMgr,pidlTemp1))->mkid.cb)
-    pidlTemp1 = this->pPidlMgr->lpvtbl->fnGetNextItem(this->pPidlMgr,pidlTemp1);
-  while((this->pPidlMgr->lpvtbl->fnGetNextItem(this->pPidlMgr,pidlTemp2))->mkid.cb)
-    pidlTemp2 = this->pPidlMgr->lpvtbl->fnGetNextItem(this->pPidlMgr,pidlTemp2);
-
-  /* at this point, both pidlTemp1 and pidlTemp2 point to the last item in the list */
-  if(this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr,pidlTemp1) != this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr,pidlTemp2))
-  { if(this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr,pidlTemp1))
-      return 1;
-   return -1;
-  }
-
-  this->pPidlMgr->lpvtbl->fnGetDrive(this->pPidlMgr, pidl1,szString1,sizeof(szString1));
-  this->pPidlMgr->lpvtbl->fnGetDrive(this->pPidlMgr, pidl2,szString1,sizeof(szString2));
-  nReturn = strcasecmp(szString1, szString2);
-  if(nReturn)
-    return nReturn;
-
-  this->pPidlMgr->lpvtbl->fnGetFolderText(this->pPidlMgr, pidl1,szString1,sizeof(szString1));
-  this->pPidlMgr->lpvtbl->fnGetFolderText(this->pPidlMgr, pidl2,szString2,sizeof(szString2));
-  nReturn = strcasecmp(szString1, szString2);
-  if(nReturn)
-    return nReturn;
-
-  this->pPidlMgr->lpvtbl->fnGetValueText(this->pPidlMgr,pidl1,szString1,sizeof(szString1));
-  this->pPidlMgr->lpvtbl->fnGetValueText(this->pPidlMgr,pidl2,szString2,sizeof(szString2));
-  return strcasecmp(szString1, szString2);
-}
-
-/**************************************************************************
-*	  IShellFolder_CreateViewObject
-* Creates an View Object representing the ShellFolder
-*  IShellView / IShellBrowser / IContextMenu
-*
-* PARAMETERS
-*  HWND    hwndOwner,  // Handle of owner window
-*  REFIID  riid,       // Requested initial interface
-*  LPVOID* ppvObject)  // Resultant interface*
-*
-* NOTES
-*  the same as SHCreateShellFolderViewEx ???
-*/
-static HRESULT WINAPI IShellFolder_CreateViewObject(
-	LPSHELLFOLDER this,
-	HWND32 hwndOwner,
-	REFIID riid,
-	LPVOID *ppvOut)
-{ LPSHELLVIEW pShellView;
-  char    xriid[50];
-  HRESULT       hr;
-
-	WINE_StringFromCLSID(riid,xriid);
-  TRACE(shell,"(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",this,hwndOwner,xriid,ppvOut);
-	
-	*ppvOut = NULL;
-
-  pShellView = IShellView_Constructor(this, this->mpidl);
-  if(!pShellView)
-    return E_OUTOFMEMORY;
-  hr = pShellView->lpvtbl->fnQueryInterface(pShellView, riid, ppvOut);
-  pShellView->lpvtbl->fnRelease(pShellView);
-  TRACE(shell,"-- (%p)->(interface=%p)\n",this, ppvOut);
-  return hr; 
-}
-
-/**************************************************************************
-*  IShellFolder_GetAttributesOf
-*
-* PARAMETERS
-*  UINT            cidl,     //[in ] num elements in pidl array
-+  LPCITEMIDLIST*  apidl,    //[in ] simple pidl array 
-*  ULONG*          rgfInOut) //[out] result array  
-*
-* FIXME: quick hack
-*  Note: rgfInOut is documented as being an array of ULONGS.
-*  This does not seem to be the case. Testing this function using the shell to 
-*  call it with cidl > 1 (by deleting multiple items) reveals that the shell
-*  passes ONE element in the array and writing to further elements will
-*  cause the shell to fail later.
-*/
-static HRESULT WINAPI IShellFolder_GetAttributesOf(
-	LPSHELLFOLDER this,
-	UINT32 cidl,
-    LPCITEMIDLIST *apidl, /*simple pidl's*/
-	DWORD *rgfInOut)
-{ LPCITEMIDLIST * pidltemp;
-  DWORD i;
-  TRACE(shell,"(%p)->(%d,%p,%p)\n",this,cidl,apidl,rgfInOut);
-
-  pidltemp=apidl;
-  *rgfInOut = 0x00;
-  i=cidl;
-  if ((! cidl )| (!apidl) | (!rgfInOut))
-    return E_INVALIDARG;
-  
-  do
-  { if (*pidltemp)
-    { if (this->pPidlMgr->lpvtbl->fnIsDesktop(this->pPidlMgr, *pidltemp))
-      { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR);
-      }
-      else if (this->pPidlMgr->lpvtbl->fnIsMyComputer(this->pPidlMgr, *pidltemp))
-      { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER);
-      }
-      else if (this->pPidlMgr->lpvtbl->fnIsDrive(this->pPidlMgr, *pidltemp))
-      { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR | SFGAO_FILESYSTEM);
-      }
-      else if (this->pPidlMgr->lpvtbl->fnIsFolder(this->pPidlMgr, *pidltemp))
-      { *rgfInOut |= (SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER);
-      }
-      else if (this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr, *pidltemp))
-      { *rgfInOut |= (SFGAO_FILESYSTEM);
-      }
-    }
-    pidltemp++;
-    cidl--;
-  } while (cidl > 0 && *pidltemp);
-
-  return S_OK;
-}
-/**************************************************************************
-*  IShellFolder_GetUIObjectOf
-*
-* PARAMETERS
-*  HWND           hwndOwner, //[in ] Parent window for any output
-*  UINT           cidl,      //[in ] array size
-*  LPCITEMIDLIST* apidl,     //[in ] simple pidl array
-*  REFIID         riid,      //[in ] Requested Interface
-*  UINT*          prgfInOut, //[   ] reserved 
-*  LPVOID*        ppvObject) //[out] Resulting Interface
-*
-* NOTES
-*  This function gets asked to return "view objects" for one or more (multiple select)
-*  items:
-*  The viewobject typically is an COM object with one of the following interfaces:
-*  IExtractIcon,IDataObject,IContextMenu
-*  In order to support icon positions in the default Listview your DataObject
-*  must implement the SetData method (in addition to GetData :) - the shell passes
-*  a barely documented "Icon positions" structure to SetData when the drag starts,
-*  and GetData's it if the drop is in another explorer window that needs the positions.
-*/
-static HRESULT WINAPI IShellFolder_GetUIObjectOf(
-	LPSHELLFOLDER this,
-	HWND32 hwndOwner,
-	UINT32 cidl, 
-  LPCITEMIDLIST * apidl, /* simple pidl's*/
-  REFIID riid,
-	UINT32 * prgfInOut,
-	LPVOID * ppvOut)
-{ char	        xclsid[50];
-  
-	WINE_StringFromCLSID(riid,xclsid);
-
-  FIXME(shell,"(%p)->(%u,%u,pidl=%p,\n\tIID:%s,%p,%p),stub!\n",
-	  this,hwndOwner,cidl,apidl,xclsid,prgfInOut,ppvOut);
-
-	*ppvOut = NULL;	
-	return E_NOTIMPL;
-}
-/**************************************************************************
-*  IShellFolder_GetDisplayNameOf
-*  Retrieves the display name for the specified file object or subfolder
-*
-* PARAMETERS
-*  LPCITEMIDLIST pidl,    //[in ] complex pidl to item
-*  DWORD         dwFlags, //[in ] SHGNO formatting flags
-*  LPSTRRET      lpName)  //[out] Returned display name
-*
-* FIXME
-*  if the name is in the pidl the ret value should be a STRRET_OFFSET
-*/
-#define GET_SHGDN_FOR(dwFlags)         ((DWORD)dwFlags & (DWORD)0x0000FF00)
-#define GET_SHGDN_RELATION(dwFlags)    ((DWORD)dwFlags & (DWORD)0x000000FF)
-
-static HRESULT WINAPI IShellFolder_GetDisplayNameOf( 
-  	LPSHELLFOLDER this,
-    LPCITEMIDLIST pidl, /* simple/complex pidl*/
-    DWORD dwFlags, 
-    LPSTRRET lpName)
-{ CHAR           szText[MAX_PATH];
-  CHAR           szTemp[MAX_PATH];
-	CHAR           szSpecial[MAX_PATH];
-	CHAR           szDrive[MAX_PATH];
-  DWORD          dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags;
-  LPITEMIDLIST   pidlTemp=NULL;
-	BOOL32				 bSimplePidl=FALSE;
-		
-  TRACE(shell,"(%p)->(pidl=%p,0x%08lx,%p)\n",this,pidl,dwFlags,lpName);
-
-  if (!pidl)
-  {  return E_OUTOFMEMORY;
-  } 
-
-  szSpecial[0]=0x00; 
-  szDrive[0]=0x00;
-
-  /* test if simple(relative) or complex(absolute) pidl */
-  pidlTemp = this->pPidlMgr->lpvtbl->fnGetNextItem(this->pPidlMgr,pidl);
-	if (pidlTemp->mkid.cb==0x00)
-	{ bSimplePidl = TRUE;
-	}
-	if (this->pPidlMgr->lpvtbl->fnIsDesktop(this->pPidlMgr, pidl))
-	{ strcpy (szText,"Desktop");
-	}
-	else
-  { if (this->pPidlMgr->lpvtbl->fnIsMyComputer(this->pPidlMgr, pidl))
-    { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidl, szSpecial, MAX_PATH);
-    }
-	  if (this->pPidlMgr->lpvtbl->fnIsDrive(this->pPidlMgr, pidl))
-		{ pidlTemp = this->pPidlMgr->lpvtbl->fnGetLastItem(this->pPidlMgr,pidl);
-  		if (pidlTemp)
-      { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidlTemp, szTemp, MAX_PATH);
-  		}
-		  if ( dwFlags==SHGDN_NORMAL || dwFlags==SHGDN_INFOLDER)
-  		{ GetVolumeInformation32A(szTemp,szDrive,MAX_PATH,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
-				if (szTemp[2]=='\\')
-        { szTemp[2]=0x00;
-				}
-        strcat (szDrive," (");
-				strcat (szDrive,szTemp);
-				strcat (szDrive,")"); 
-  		}
-			else
-			{  PathAddBackslash (szTemp);
-			   strcpy(szDrive,szTemp);
-			}
-		}
-		
-  	switch(dwFlags)
-    { case SHGDN_NORMAL:
-        this->pPidlMgr->lpvtbl->fnGetPidlPath(this->pPidlMgr, pidl, szText, MAX_PATH);
-        break;
-      case SHGDN_INFOLDER:
-        pidlTemp = this->pPidlMgr->lpvtbl->fnGetLastItem(this->pPidlMgr,pidl);
-  			if (pidlTemp)
-        { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidlTemp, szText, MAX_PATH);
-  			}
-   			break;				
-   		case	SHGDN_FORPARSING:
-			  if (bSimplePidl)
-				{ /* if the IShellFolder has parents, get the path from the
-				  parent and add the ItemName*/
-          szText[0]=0x00;
-				  if (this->mlpszFolder && strlen (this->mlpszFolder))
-          { if (strcmp(this->mlpszFolder,"My Computer"))
-  			  { strcpy (szText,this->mlpszFolder);
-  			    PathAddBackslash (szText);
-  			  }
-  		  	}
-          pidlTemp = this->pPidlMgr->lpvtbl->fnGetLastItem(this->pPidlMgr,pidl);
-        	if (pidlTemp)
-          { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidlTemp, szTemp, MAX_PATH );
-        	} 
-					strcat(szText,szTemp);
-				}
-				else					
-				{ /* if the pidl is absolute, get everything from the pidl*/
-				  this->pPidlMgr->lpvtbl->fnGetPidlPath(this->pPidlMgr, pidl, szText, MAX_PATH);
-				}
-        break;
-      default:    return E_INVALIDARG;
-    }
-		if ((szText[0]==0x00 && szDrive[0]!=0x00)|| (bSimplePidl && szDrive[0]!=0x00))
-		{ strcpy(szText,szDrive);
-		}
-		if (szText[0]==0x00 && szSpecial[0]!=0x00)
-		{ strcpy(szText,szSpecial);
-		}
-  }
-  
-  TRACE(shell,"-- (%p)->(%s,%s,%s)\n",this,szSpecial,szDrive,szText);
-
-  if(!(lpName))
-  {  return E_OUTOFMEMORY;
-	}
-  lpName->uType = STRRET_CSTR;	
-	strcpy(lpName->u.cStr,szText);
-  return S_OK;
-}
-
-/**************************************************************************
-*  IShellFolder_SetNameOf
-*  Changes the name of a file object or subfolder, possibly changing its item
-*  identifier in the process.
-*
-* PARAMETERS
-*  HWND          hwndOwner,  //[in ] Owner window for output
-*  LPCITEMIDLIST pidl,       //[in ] simple pidl of item to change
-*  LPCOLESTR     lpszName,   //[in ] the items new display name
-*  DWORD         dwFlags,    //[in ] SHGNO formatting flags
-*  LPITEMIDLIST* ppidlOut)   //[out] simple pidl returned
-*/
-static HRESULT WINAPI IShellFolder_SetNameOf(
-  	LPSHELLFOLDER this,
-		HWND32 hwndOwner, 
-    LPCITEMIDLIST pidl, /*simple pidl*/
-    LPCOLESTR32 lpName, 
-    DWORD dw, 
-    LPITEMIDLIST *pPidlOut)
-{  FIXME(shell,"(%p)->(%u,pidl=%p,%s,%lu,%p),stub!\n",
-	  this,hwndOwner,pidl,debugstr_w(lpName),dw,pPidlOut);
-	 return E_NOTIMPL;
-}
-
-/**************************************************************************
-* IShellLink Implementation
-*/
-static HRESULT WINAPI IShellLink_QueryInterface(LPSHELLLINK,REFIID,LPVOID*);
-static ULONG WINAPI IShellLink_AddRef(LPSHELLLINK);
-static ULONG WINAPI IShellLink_Release(LPSHELLLINK);
-
-/**************************************************************************
-*	  IShellLink_VTable
-*/
-static struct IShellLink_VTable slvt = {
-  IShellLink_QueryInterface,
-  IShellLink_AddRef,
-  IShellLink_Release,
-    (void *)0xcafe0004,
-    (void *)0xcafe0005,
-    (void *)0xcafe0006,
-    (void *)0xcafe0007,
-    (void *)0xcafe0008,
-    (void *)0xcafe0009,
-    (void *)0xcafe0010,
-    (void *)0xcafe0011,
-    (void *)0xcafe0012,
-    (void *)0xcafe0013,
-    (void *)0xcafe0014,
-    (void *)0xcafe0015,
-    (void *)0xcafe0016,
-    (void *)0xcafe0017,
-    (void *)0xcafe0018,
-    (void *)0xcafe0019,
-    (void *)0xcafe0020,
-    (void *)0xcafe0021
-};
-
-/**************************************************************************
- *	  IShellLink_Constructor
- */
-LPSHELLLINK IShellLink_Constructor() 
-{	LPSHELLLINK sl;
-
-	sl = (LPSHELLLINK)HeapAlloc(GetProcessHeap(),0,sizeof(IShellLink));
-	sl->ref = 1;
-	sl->lpvtbl = &slvt;
-	TRACE(shell,"(%p)->()\n",sl);
-	return sl;
-}
-
-/**************************************************************************
- *  IShellLink::QueryInterface
- */
-static HRESULT WINAPI IShellLink_QueryInterface(
-  LPSHELLLINK this, REFIID riid, LPVOID *ppvObj)
-{  char    xriid[50];
-   WINE_StringFromCLSID((LPCLSID)riid,xriid);
-   TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",this,xriid);
-
-  *ppvObj = NULL;
-
-  if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
-  { *ppvObj = this; 
-  }
-  else if(IsEqualIID(riid, &IID_IShellLink))  /*IShellLink*/
-  {    *ppvObj = (LPSHELLLINK)this;
-  }   
-
-  if(*ppvObj)
-  { (*(LPSHELLLINK*)ppvObj)->lpvtbl->fnAddRef(this);      
-    TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
-    return S_OK;
-  }
-    TRACE(shell,"-- Interface: E_NOINTERFACE\n");
-  return E_NOINTERFACE;
-}  
-/******************************************************************************
- * IShellLink_AddRef
- */
-static ULONG WINAPI IShellLink_AddRef(LPSHELLLINK this)
-{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
-    return ++(this->ref);
-}
-/******************************************************************************
- * IClassFactory_Release
- */
-static ULONG WINAPI IShellLink_Release(LPSHELLLINK this)
-{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
-  if (!--(this->ref)) 
-  { TRACE(shell,"-- destroying IShellLink(%p)\n",this);
-    HeapFree(GetProcessHeap(),0,this);
-    return 0;
-  }
-  return this->ref;
-}
-
-
-/**************************************************************************
-*	  INTERNAL CLASS pidlmgr
-*/
-LPITEMIDLIST PidlMgr_CreateDesktop(LPPIDLMGR);
-LPITEMIDLIST PidlMgr_CreateMyComputer(LPPIDLMGR);
-LPITEMIDLIST PidlMgr_CreateDrive(LPPIDLMGR,LPCSTR);
-LPITEMIDLIST PidlMgr_CreateFolder(LPPIDLMGR,LPCSTR);
-LPITEMIDLIST PidlMgr_CreateValue(LPPIDLMGR,LPCSTR);
-/*void PidlMgr_Delete(LPPIDLMGR,LPITEMIDLIST);*/
-LPITEMIDLIST PidlMgr_GetNextItem(LPPIDLMGR,LPITEMIDLIST);
-BOOL32 PidlMgr_GetDesktop(LPPIDLMGR,LPCITEMIDLIST,LPSTR);
-BOOL32 PidlMgr_GetDrive(LPPIDLMGR,LPCITEMIDLIST,LPSTR,UINT16);
-LPITEMIDLIST PidlMgr_GetLastItem(LPPIDLMGR,LPCITEMIDLIST);
-DWORD PidlMgr_GetItemText(LPPIDLMGR,LPCITEMIDLIST,LPSTR,UINT16);
-BOOL32 PidlMgr_IsDesktop(LPPIDLMGR,LPCITEMIDLIST);
-BOOL32 PidlMgr_IsMyComputer(LPPIDLMGR,LPCITEMIDLIST);
-BOOL32 PidlMgr_IsDrive(LPPIDLMGR,LPCITEMIDLIST);
-BOOL32 PidlMgr_IsFolder(LPPIDLMGR,LPCITEMIDLIST);
-BOOL32 PidlMgr_IsValue(LPPIDLMGR,LPCITEMIDLIST);
-BOOL32 PidlMgr_HasFolders(LPPIDLMGR,LPSTR,LPCITEMIDLIST);
-DWORD PidlMgr_GetFolderText(LPPIDLMGR,LPCITEMIDLIST,LPSTR,DWORD);
-DWORD PidlMgr_GetValueText(LPPIDLMGR,LPCITEMIDLIST,LPSTR,DWORD);
-BOOL32 PidlMgr_GetValueType(LPPIDLMGR,LPCITEMIDLIST,LPCITEMIDLIST,LPDWORD);
-DWORD PidlMgr_GetDataText(LPPIDLMGR,LPCITEMIDLIST,LPCITEMIDLIST,LPSTR,DWORD);
-DWORD PidlMgr_GetPidlPath(LPPIDLMGR,LPCITEMIDLIST,LPSTR,DWORD);
-LPITEMIDLIST PidlMgr_Create(LPPIDLMGR,PIDLTYPE,LPVOID,UINT16);
-DWORD PidlMgr_GetData(LPPIDLMGR,PIDLTYPE,LPCITEMIDLIST,LPVOID,UINT16);
-LPPIDLDATA PidlMgr_GetDataPointer(LPPIDLMGR,LPCITEMIDLIST);
-BOOL32 PidlMgr_SeparatePathAndValue(LPPIDLMGR,LPITEMIDLIST,LPITEMIDLIST*,LPITEMIDLIST*);
-
-static struct PidlMgr_VTable pmgrvt = {
-    PidlMgr_CreateDesktop,
-    PidlMgr_CreateMyComputer,
-		PidlMgr_CreateDrive,
-    PidlMgr_CreateFolder,
-    PidlMgr_CreateValue,
-  /*  PidlMgr_Delete,*/
-    PidlMgr_GetNextItem,
-    PidlMgr_GetDesktop,
-		PidlMgr_GetDrive,
-    PidlMgr_GetLastItem,
-    PidlMgr_GetItemText,
-    PidlMgr_IsDesktop,
-    PidlMgr_IsMyComputer,
-		PidlMgr_IsDrive,
-    PidlMgr_IsFolder,
-    PidlMgr_IsValue,
-    PidlMgr_HasFolders,
-    PidlMgr_GetFolderText,
-    PidlMgr_GetValueText,
-    PidlMgr_GetValueType,
-    PidlMgr_GetDataText,
-    PidlMgr_GetPidlPath,
-    PidlMgr_Create,
-    PidlMgr_GetData,
-    PidlMgr_GetDataPointer,
-    PidlMgr_SeparatePathAndValue
-};
-/**************************************************************************
- *	  PidlMgr_Constructor
- */
-LPPIDLMGR PidlMgr_Constructor() 
-{	LPPIDLMGR pmgr;
-	pmgr = (LPPIDLMGR)HeapAlloc(GetProcessHeap(),0,sizeof(pidlmgr));
-	pmgr->lpvtbl = &pmgrvt;
-	TRACE(shell,"(%p)->()\n",pmgr);
-  /** FIXME DllRefCount++;*/
-	return pmgr;
-}
-/**************************************************************************
- *	  PidlMgr_Destructor
- */
-void PidlMgr_Destructor(LPPIDLMGR this) 
-{	HeapFree(GetProcessHeap(),0,this);
- 	TRACE(shell,"(%p)->()\n",this);
-  /** FIXME DllRefCount--;*/
-}
-
-/**************************************************************************
- *  PidlMgr_CreateDesktop()
- *  PidlMgr_CreateMyComputer()
- *  PidlMgr_CreateDrive()
- *  PidlMgr_CreateFolder() 
- *  PidlMgr_CreateValue()
- */
-LPITEMIDLIST PidlMgr_CreateDesktop(LPPIDLMGR this)
-{ TRACE(shell,"(%p)->()\n",this);
-    return PidlMgr_Create(this,PT_DESKTOP, NULL, 0);
-}
-LPITEMIDLIST PidlMgr_CreateMyComputer(LPPIDLMGR this)
-{ TRACE(shell,"(%p)->()\n",this);
-  return PidlMgr_Create(this,PT_MYCOMP, (void *)"My Computer", strlen ("My Computer")+1);
-}
-LPITEMIDLIST PidlMgr_CreateDrive(LPPIDLMGR this, LPCSTR lpszNew)
-{ char sTemp[4];
-  strncpy (sTemp,lpszNew,4);
-	sTemp[2]='\\';
-	sTemp[3]=0x00;
-  TRACE(shell,"(%p)->(%s)\n",this,sTemp);
-  return PidlMgr_Create(this,PT_DRIVE,(LPVOID)&sTemp[0],4);
-}
-LPITEMIDLIST PidlMgr_CreateFolder(LPPIDLMGR this, LPCSTR lpszNew)
-{ TRACE(shell,"(%p)->(%s)\n",this,lpszNew);
-  return PidlMgr_Create(this,PT_FOLDER, (LPVOID)lpszNew, strlen(lpszNew)+1);
-}
-LPITEMIDLIST PidlMgr_CreateValue(LPPIDLMGR this,LPCSTR lpszNew)
-{ TRACE(shell,"(%p)->(%s)\n",this,lpszNew);
-  return PidlMgr_Create(this,PT_VALUE, (LPVOID)lpszNew, strlen(lpszNew)+1);
-}
-/**************************************************************************
- *  PidlMgr_Delete()
- *  Deletes a PIDL
- */
-/*void PidlMgr_Delete(LPPIDLMGR this,LPITEMIDLIST pidl)
-{ TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl);
-  HeapFree(GetProcessHeap(),0,pidl);
-}
-*/
-/**************************************************************************
- *  PidlMgr_GetNextItem()
- */
-LPITEMIDLIST PidlMgr_GetNextItem(LPPIDLMGR this, LPITEMIDLIST pidl)
-{ LPITEMIDLIST nextpidl;
-
-  TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl);
-  if(pidl)
-  { nextpidl = (LPITEMIDLIST)(LPBYTE)(((LPBYTE)pidl) + pidl->mkid.cb);
-/*    TRACE(shell,"-- (%p)->(next pidl=%p)\n",this,nextpidl);*/
-		return nextpidl;
-	}
-  else
-  {  return (NULL);
-	}
-}
-/**************************************************************************
- *  PidlMgr_GetDesktop()
- * 
- *  FIXME: quick hack
- */
-BOOL32 PidlMgr_GetDesktop(LPPIDLMGR this,LPCITEMIDLIST pidl,LPSTR pOut)
-{ TRACE(shell,"(%p)->(%p %p)\n",this,pidl,pOut);
-  return (BOOL32)PidlMgr_GetData(this,PT_DESKTOP, pidl, (LPVOID)pOut, 255);
-}
-/**************************************************************************
- *  PidlMgr_GetDrive()
- *
- *  FIXME: quick hack
- */
-BOOL32 PidlMgr_GetDrive(LPPIDLMGR this,LPCITEMIDLIST pidl,LPSTR pOut, UINT16 uSize)
-{ LPITEMIDLIST   pidlTemp=NULL;
-
-  TRACE(shell,"(%p)->(%p,%p,%u)\n",this,pidl,pOut,uSize);
-  if(PidlMgr_IsMyComputer(this,pidl))
-  { pidlTemp = PidlMgr_GetNextItem(this,pidl);
-	}
-  else if (pidlTemp && PidlMgr_IsDrive(this,pidlTemp))
-  { return (BOOL32)PidlMgr_GetData(this,PT_DRIVE, pidlTemp, (LPVOID)pOut, uSize);
-	}
-	return FALSE;
-}
-/**************************************************************************
- *  PidlMgr_GetLastItem()
- *  Gets the last item in the list
- */
-LPITEMIDLIST PidlMgr_GetLastItem(LPPIDLMGR this,LPCITEMIDLIST pidl)
-{ LPITEMIDLIST   pidlLast = NULL;
-
-  TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl);
-
-  if(pidl)
-  { while(pidl->mkid.cb)
-    { pidlLast = (LPITEMIDLIST)pidl;
-      pidl = PidlMgr_GetNextItem(this,pidl);
-    }  
-  }
-  return pidlLast;
-}
-/**************************************************************************
- *  PidlMgr_GetItemText()
- *  Gets the text for only this item
- */
-DWORD PidlMgr_GetItemText(LPPIDLMGR this,LPCITEMIDLIST pidl, LPSTR lpszText, UINT16 uSize)
-{ TRACE(shell,"(%p)->(pidl=%p %p %x)\n",this,pidl,lpszText,uSize);
-  if (PidlMgr_IsMyComputer(this, pidl))
-  { return PidlMgr_GetData(this,PT_MYCOMP, pidl, (LPVOID)lpszText, uSize);
-	}
-	if (PidlMgr_IsDrive(this, pidl))
-	{ return PidlMgr_GetData(this,PT_DRIVE, pidl, (LPVOID)lpszText, uSize);
-	}
-	return PidlMgr_GetData(this,PT_TEXT, pidl, (LPVOID)lpszText, uSize);	
-}
-/**************************************************************************
- *  PidlMgr_IsDesktop()
- *  PidlMgr_IsDrive()
- *  PidlMgr_IsFolder()
- *  PidlMgr_IsValue()
-*/
-BOOL32 PidlMgr_IsDesktop(LPPIDLMGR this,LPCITEMIDLIST pidl)
-{ TRACE(shell,"%p->(%p)\n",this,pidl);
-
-  if (! pidl)
-    return FALSE;
-
-  return (  pidl->mkid.cb == 0x00 );
-}
-
-BOOL32 PidlMgr_IsMyComputer(LPPIDLMGR this,LPCITEMIDLIST pidl)
-{ LPPIDLDATA  pData;
-  TRACE(shell,"%p->(%p)\n",this,pidl);
-
-  if (! pidl)
-    return FALSE;
-
-  pData = PidlMgr_GetDataPointer(this,pidl);
-  return (PT_MYCOMP == pData->type);
-}
-
-BOOL32 PidlMgr_IsDrive(LPPIDLMGR this,LPCITEMIDLIST pidl)
-{ LPPIDLDATA  pData;
-  TRACE(shell,"%p->(%p)\n",this,pidl);
-
-  if (! pidl)
-    return FALSE;
-
-  pData = PidlMgr_GetDataPointer(this,pidl);
-  return (PT_DRIVE == pData->type);
-}
-
-BOOL32 PidlMgr_IsFolder(LPPIDLMGR this,LPCITEMIDLIST pidl)
-{ LPPIDLDATA  pData;
-  TRACE(shell,"%p->(%p)\n",this,pidl);
-
-  if (! pidl)
-    return FALSE;
-
-  pData = PidlMgr_GetDataPointer(this,pidl);
-  return (PT_FOLDER == pData->type);
-}
-
-BOOL32 PidlMgr_IsValue(LPPIDLMGR this,LPCITEMIDLIST pidl)
-{ LPPIDLDATA  pData;
-  TRACE(shell,"%p->(%p)\n",this,pidl);
-
-  if (! pidl)
-    return FALSE;
-
-  pData = PidlMgr_GetDataPointer(this,pidl);
-  return (PT_VALUE == pData->type);
-}
-/**************************************************************************
- * PidlMgr_HasFolders()
- * fixme: quick hack
- */
-BOOL32 PidlMgr_HasFolders(LPPIDLMGR this, LPSTR pszPath, LPCITEMIDLIST pidl)
-{ BOOL32 bResult= FALSE;
-  WIN32_FIND_DATA32A stffile;	
-  HANDLE32 hFile;
-
-  TRACE (shell,"(%p)->%p %p\n",this, pszPath, pidl);
-	
-  hFile = FindFirstFile32A(pszPath,&stffile);
-  do
-  { if (! (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
-    {  bResult= TRUE;
-		}
-  } while( FindNextFile32A(hFile,&stffile));
-  FindClose32 (hFile);
-	
-	return bResult;
-}
-
-
-/**************************************************************************
- *  PidlMgr_GetFolderText()
- *  Creates a Path string from a PIDL, filtering out the special Folders 
- */
-DWORD PidlMgr_GetFolderText(LPPIDLMGR this,LPCITEMIDLIST pidl,
-   LPSTR lpszPath, DWORD dwSize)
-{ LPITEMIDLIST   pidlTemp;
-  DWORD          dwCopied = 0;
- 
-  TRACE(shell,"(%p)->(%p)\n",this,pidl);
- 
-  if(!pidl)
-  { return 0;
-	}
-
-  if(PidlMgr_IsMyComputer(this,pidl))
-  { pidlTemp = PidlMgr_GetNextItem(this,pidl);
-    TRACE(shell,"-- (%p)->skip My Computer\n",this);
-	}
-  else
-  { pidlTemp = (LPITEMIDLIST)pidl;
-	}
-
-  //if this is NULL, return the required size of the buffer
-  if(!lpszPath)
-  { while(pidlTemp->mkid.cb)
-    { LPPIDLDATA  pData = PidlMgr_GetDataPointer(this,pidlTemp);
-      
-      //add the length of this item plus one for the backslash
-      dwCopied += strlen(pData->szText) + 1;  /* fixme pData->szText is not every time a string*/
-
-      pidlTemp = PidlMgr_GetNextItem(this,pidlTemp);
-    }
-
-    //add one for the NULL terminator
-	  TRACE(shell,"-- (%p)->(size=%lu)\n",this,dwCopied);
-    return dwCopied + 1;
-  }
-
-  *lpszPath = 0;
-
-  while(pidlTemp->mkid.cb && (dwCopied < dwSize))
-  { LPPIDLDATA  pData = PidlMgr_GetDataPointer(this,pidlTemp);
-
-    //if this item is a value, then skip it and finish
-    if(PT_VALUE == pData->type)
-    { break;
-		}
-   
-    strcat(lpszPath, pData->szText);
-    strcat(lpszPath, "\\");
-    dwCopied += strlen(pData->szText) + 1;
-    pidlTemp = PidlMgr_GetNextItem(this,pidlTemp);
-
-		TRACE(shell,"-- (%p)->(size=%lu,%s)\n",this,dwCopied,lpszPath);
-  }
-
-  //remove the last backslash if necessary
-  if(dwCopied)
-  { if(*(lpszPath + strlen(lpszPath) - 1) == '\\')
-    { *(lpszPath + strlen(lpszPath) - 1) = 0;
-      dwCopied--;
-    }
-  }
-  TRACE(shell,"-- (%p)->(path=%s)\n",this,lpszPath);
-  return dwCopied;
-}
-
-
-/**************************************************************************
- *  PidlMgr_GetValueText()
- *  Gets the text for the last item in the list
- */
-DWORD PidlMgr_GetValueText(LPPIDLMGR this,
-    LPCITEMIDLIST pidl, LPSTR lpszValue, DWORD dwSize)
-{ LPITEMIDLIST  pidlTemp=pidl;
-  CHAR          szText[MAX_PATH];
-
-  TRACE(shell,"(%p)->(pidl=%p %p 0x%08lx)\n",this,pidl,lpszValue,dwSize);
-
-  if(!pidl)
-  { return 0;
-	}
-		
-  while(pidlTemp->mkid.cb && !PidlMgr_IsValue(this,pidlTemp))
-  { pidlTemp = PidlMgr_GetNextItem(this,pidlTemp);
-  }
-
-  if(!pidlTemp->mkid.cb)
-  { return 0;
-	}
-
-  PidlMgr_GetItemText(this, pidlTemp, szText, sizeof(szText));
-
-  if(!lpszValue)
-  { return strlen(szText) + 1;
-  }
-  strcpy(lpszValue, szText);
-	TRACE(shell,"-- (%p)->(pidl=%p %p=%s 0x%08lx)\n",this,pidl,lpszValue,lpszValue,dwSize);
-  return strlen(lpszValue);
-}
-/**************************************************************************
- *  PidlMgr_GetValueType()
- */
-BOOL32 PidlMgr_GetValueType( LPPIDLMGR this,
-   LPCITEMIDLIST pidlPath,
-   LPCITEMIDLIST pidlValue,
-   LPDWORD pdwType)
-{ LPSTR    lpszFolder,
-           lpszValueName;
-  DWORD    dwNameSize;
- 
-  FIXME(shell,"(%p)->(%p %p %p) stub\n",this,pidlPath,pidlValue,pdwType);
-	
-  if(!pidlPath)
-  { return FALSE;
-	}
-
-  if(!pidlValue)
-  { return FALSE;
-	}
-
-  if(!pdwType)
-  { return FALSE;
-	}
-
-  //get the Desktop
-  //PidlMgr_GetDesktop(this,pidlPath);
-
-  /* fixme: add the driveletter here*/
-	
-  //assemble the Folder string
-  dwNameSize = PidlMgr_GetFolderText(this,pidlPath, NULL, 0);
-  lpszFolder = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize);
-  if(!lpszFolder)
-  {  return FALSE;
-	}
-  PidlMgr_GetFolderText(this,pidlPath, lpszFolder, dwNameSize);
-
-  //assemble the value name
-  dwNameSize = PidlMgr_GetValueText(this,pidlValue, NULL, 0);
-  lpszValueName = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize);
-  if(!lpszValueName)
-  { HeapFree(GetProcessHeap(),0,lpszFolder);
-    return FALSE;
-  }
-  PidlMgr_GetValueText(this,pidlValue, lpszValueName, dwNameSize);
-
-  /* fixme: we've got the path now do something with it
-	  -like get the filetype*/
-	
-	pdwType=NULL;
-	
-  HeapFree(GetProcessHeap(),0,lpszFolder);
-  HeapFree(GetProcessHeap(),0,lpszValueName);
-  return TRUE;
-}
-/**************************************************************************
- *  PidlMgr_GetDataText()
- */
-DWORD PidlMgr_GetDataText( LPPIDLMGR this,
- LPCITEMIDLIST pidlPath, LPCITEMIDLIST pidlValue, LPSTR lpszOut, DWORD dwOutSize)
-{ LPSTR    lpszFolder,
-           lpszValueName;
-  DWORD    dwNameSize;
-
-  FIXME(shell,"(%p)->(pidl=%p pidl=%p) stub\n",this,pidlPath,pidlValue);
-
-  if(!lpszOut || !pidlPath || !pidlValue)
-  { return FALSE;
-	}
-
-  /* fixme: get the driveletter*/
-
-  //assemble the Folder string
-  dwNameSize = PidlMgr_GetFolderText(this,pidlPath, NULL, 0);
-  lpszFolder = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize);
-  if(!lpszFolder)
-  {  return FALSE;
-	}
-  PidlMgr_GetFolderText(this,pidlPath, lpszFolder, dwNameSize);
-
-  //assemble the value name
-  dwNameSize = PidlMgr_GetValueText(this,pidlValue, NULL, 0);
-  lpszValueName = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize);
-  if(!lpszValueName)
-  { HeapFree(GetProcessHeap(),0,lpszFolder);
-    return FALSE;
-  }
-  PidlMgr_GetValueText(this,pidlValue, lpszValueName, dwNameSize);
-
-  /* fixme: we've got the path now do something with it*/
-	
-  HeapFree(GetProcessHeap(),0,lpszFolder);
-  HeapFree(GetProcessHeap(),0,lpszValueName);
-
-  TRACE(shell,"-- (%p)->(%p=%s 0x%08lx)\n",this,lpszOut,lpszOut,dwOutSize);
-
-	return TRUE;
-}
-
-/**************************************************************************
- *   CPidlMgr::GetPidlPath()
- *  Create a string that includes the Drive name, the folder text and 
- *  the value text.
- */
-DWORD PidlMgr_GetPidlPath(LPPIDLMGR this,
-    LPCITEMIDLIST pidl, LPSTR lpszOut, DWORD dwOutSize)
-{ LPSTR lpszTemp;
-  WORD	len;
-
-  TRACE(shell,"(%p)->(%p,%lu)\n",this,lpszOut,dwOutSize);
-
-  if(!lpszOut)
-  { return 0;
-	}
-
-  *lpszOut = 0;
-  lpszTemp = lpszOut;
-
-  dwOutSize -= PidlMgr_GetFolderText(this,pidl, lpszTemp, dwOutSize);
-
-  //add a backslash if necessary
-  len = strlen(lpszTemp);
-  if (len && lpszTemp[len-1]!='\\')
-	{ lpszTemp[len+0]='\\';
-    lpszTemp[len+1]='\0';
-		dwOutSize--;
-  }
-
-  lpszTemp = lpszOut + strlen(lpszOut);
-
-  //add the value string
-  PidlMgr_GetValueText(this,pidl, lpszTemp, dwOutSize);
-
-  //remove the last backslash if necessary
-  if(*(lpszOut + strlen(lpszOut) - 1) == '\\')
-  { *(lpszOut + strlen(lpszOut) - 1) = 0;
-  }
-
-  TRACE(shell,"-- (%p)->(%p=%s,%lu)\n",this,lpszOut,lpszOut,dwOutSize);
-
-  return strlen(lpszOut);
-
-}
-
-/**************************************************************************
- *  PidlMgr_Create()
- *  Creates a new PIDL
- *  type = PT_DESKTOP | PT_DRIVE | PT_FOLDER | PT_VALUE
- *  pIn = data
- *  uInSize = size of data
- */
-
-LPITEMIDLIST PidlMgr_Create(LPPIDLMGR this,PIDLTYPE type, LPVOID pIn, UINT16 uInSize)
-{ LPITEMIDLIST   pidlOut=NULL;
-  UINT16         uSize;
-  LPITEMIDLIST   pidlTemp=NULL;
-  LPPIDLDATA     pData;
-
-  TRACE(shell,"(%p)->(%x %p %x)\n",this,type,pIn,uInSize);
-
-  if ( type == PT_DESKTOP)
-  {   pidlOut = SHAlloc(2);
-      pidlOut->mkid.cb=0x0000;
-      return pidlOut;
-	}
-
-  if (! pIn)
-	{ return NULL;
-	}	
-
-  uSize = 2 + (sizeof(PIDLTYPE)) + uInSize + 2;  /* cb + PIDLTYPE + uInSize +2 */
-  pidlOut = SHAlloc(uSize);
-  pidlTemp = pidlOut;
-  if(pidlOut)
-  { pidlTemp->mkid.cb = uSize - 2;
-    pData =(LPPIDLDATA) &(pidlTemp->mkid.abID[0]);
-    pData->type = type;
-    switch(type)
-    { case PT_MYCOMP:
-        memcpy(pData->szText, pIn, uInSize);
-                       TRACE(shell,"- (%p)->create My Computer: %s\n",this,debugstr_a(pData->szText));
-                       break;
-      case PT_DRIVE:
-        memcpy(pData->szText, pIn, uInSize);
-                       TRACE(shell,"- (%p)->create Drive: %s\n",this,debugstr_a(pData->szText));
-											 break;
-      case PT_FOLDER:
-      case PT_VALUE:   
-        memcpy(pData->szText, pIn, uInSize);
-                       TRACE(shell,"- (%p)->create Value: %s\n",this,debugstr_a(pData->szText));
-											 break;
-      default: 
-        FIXME(shell,"- (%p) wrong argument\n",this);
-			                 break;
-    }
-   
-    pidlTemp = PidlMgr_GetNextItem(this,pidlTemp);
-  pidlTemp->mkid.cb = 0x00;
-  }
-  TRACE(shell,"-- (%p)->(pidl=%p, size=%u)\n",this,pidlOut,uSize-2);
-  return pidlOut;
-}
-/**************************************************************************
- *  PidlMgr_GetData(PIDLTYPE, LPCITEMIDLIST, LPVOID, UINT16)
- */
-DWORD PidlMgr_GetData(
-    LPPIDLMGR this,
-		PIDLTYPE type, 
-    LPCITEMIDLIST pidl,
-		LPVOID pOut,
-		UINT16 uOutSize)
-{ LPPIDLDATA  pData;
-  DWORD       dwReturn=0; 
-
-	TRACE(shell,"(%p)->(%x %p %p %x)\n",this,type,pidl,pOut,uOutSize);
-	
-  if(!pidl)
-  {  return 0;
-	}
-
-  pData = PidlMgr_GetDataPointer(this,pidl);
-
-  //copy the data
-  switch(type)
-  { case PT_MYCOMP:  if(uOutSize < 1)
-                       return 0;
-                     if(PT_MYCOMP != pData->type)
-                       return 0;
-										 *(LPSTR)pOut = 0;	 
-                     strncpy((LPSTR)pOut, "My Computer", uOutSize);
-										 dwReturn = strlen((LPSTR)pOut);
-                     break;
-
-	 case PT_DRIVE:    if(uOutSize < 1)
-                       return 0;
-                     if(PT_DRIVE != pData->type)
-                       return 0;
-										 *(LPSTR)pOut = 0;	 
-                     strncpy((LPSTR)pOut, pData->szText, uOutSize);
-										 dwReturn = strlen((LPSTR)pOut);
-                     break;
-
-   case PT_FOLDER:
-   case PT_VALUE: 
-	 case PT_TEXT:     *(LPSTR)pOut = 0;
-                     strncpy((LPSTR)pOut, pData->szText, uOutSize);
-                     dwReturn = strlen((LPSTR)pOut);
-                     break;
-   default:     break;										 
-  }
-	TRACE(shell,"-- (%p)->(%p=%s 0x%08lx)\n",this,pOut,(char*)pOut,dwReturn);
-  return dwReturn;
-}
-
-
-/**************************************************************************
- *  PidlMgr_GetDataPointer()
- */
-LPPIDLDATA PidlMgr_GetDataPointer(LPPIDLMGR this,LPITEMIDLIST pidl)
-{ if(!pidl)
-  {  return NULL;
-	}
-	TRACE (shell,"(%p)->(%p)\n"	,this, pidl);
-  return (LPPIDLDATA)(pidl->mkid.abID);
-}
-
-/**************************************************************************
- *  CPidlMgr_SeparatePathAndValue)
- *  Creates a separate path and value PIDL from a fully qualified PIDL.
- */
-BOOL32 PidlMgr_SeparatePathAndValue(LPPIDLMGR this, 
-   LPITEMIDLIST pidlFQ, LPITEMIDLIST *ppidlPath, LPITEMIDLIST *ppidlValue)
-{ LPITEMIDLIST   pidlTemp;
-	TRACE (shell,"(%p)->(pidl=%p pidl=%p pidl=%p)",this,pidlFQ,ppidlPath,ppidlValue);
-  if(!pidlFQ)
-  {  return FALSE;
-	}
-
-  *ppidlValue = PidlMgr_GetLastItem(this,pidlFQ);
-
-  if(!PidlMgr_IsValue(this,*ppidlValue))
-  { return FALSE;
-	}
-
-  *ppidlValue = ILClone(*ppidlValue);
-  *ppidlPath = ILClone(pidlFQ);
-
-  pidlTemp = PidlMgr_GetLastItem(this,*ppidlPath);
-  pidlTemp->mkid.cb = 0x00;
-
-  return TRUE;
-}
diff --git a/ole/nls/nor.nls b/ole/nls/nor.nls
index 4925648..f2355b1 100644
--- a/ole/nls/nor.nls
+++ b/ole/nls/nor.nls
@@ -1,14 +1,14 @@
 /*
  *	OLE2NLS library
- *      Norway (Bokmael)
+ *      Norway (Bokmaal)
  *	(Norwegian strings in iso-8859-1)
  */
 
 /* LOCVAL(LOCALE_ILANGUAGE,"") */
-LOCVAL(LOCALE_SLANGUAGE,"Norsk (Bokmæl)")
-LOCVAL(LOCALE_SENGLANGUAGE,"Norwegian (Bokmael)")
+LOCVAL(LOCALE_SLANGUAGE,"Norsk (Bokmål)")
+LOCVAL(LOCALE_SENGLANGUAGE,"Norwegian (Bokmaal)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"nor")
-LOCVAL(LOCALE_SNATIVELANGNAME,"bokmæl")
+LOCVAL(LOCALE_SNATIVELANGNAME,"bokmål")
 LOCVAL(LOCALE_ICOUNTRY,"47")
 LOCVAL(LOCALE_SCOUNTRY,"Norge")
 LOCVAL(LOCALE_SENGCOUNTRY,"Norway")
diff --git a/ole/ole2.c b/ole/ole2.c
index 5bfe3c7..228b01c 100644
--- a/ole/ole2.c
+++ b/ole/ole2.c
@@ -85,7 +85,7 @@
 }
 
 /***********************************************************************
- *           RegisterDragDrop (OLE2.35)
+ *           RegisterDragDrop16 (OLE2.35)
  */
 HRESULT WINAPI RegisterDragDrop16(
 	HWND16 hwnd,
@@ -95,3 +95,13 @@
 	return S_OK;
 }
 
+/***********************************************************************
+ *           RegisterDragDrop32 (OLE32.139)
+ */
+HRESULT WINAPI RegisterDragDrop32(
+	HWND32 hwnd,
+	LPDROPTARGET pDropTarget
+) {
+	FIXME(ole,"(0x%04x,%p),stub!\n",hwnd,pDropTarget);
+	return S_OK;
+}
diff --git a/programs/Makefile.in b/programs/Makefile.in
index aaf3c7c..686f5b3 100644
--- a/programs/Makefile.in
+++ b/programs/Makefile.in
@@ -18,6 +18,9 @@
 install:
 	for i in $(SUBDIRS); do (cd $$i; $(MAKE) install) || exit 1; done
 
+uninstall:
+	for i in $(SUBDIRS); do (cd $$i; $(MAKE) uninstall) || exit 1; done
+
 clean:
 	for i in $(SUBDIRS); do (cd $$i; $(MAKE) clean) || exit 1; done
 
diff --git a/programs/clock/Makefile.in b/programs/clock/Makefile.in
index 6acd6a8..ad759a5 100644
--- a/programs/clock/Makefile.in
+++ b/programs/clock/Makefile.in
@@ -49,6 +49,9 @@
 install: dummy
 	$(INSTALL_PROGRAM) clock $(bindir)/clock
 
+uninstall: dummy
+	$(RM) $(bindir)/clock
+
 $(RC_SRCS:.rc=.s): $(WRC)
 
 dummy:
diff --git a/programs/notepad/Makefile.in b/programs/notepad/Makefile.in
index 46fed24..fe81933 100644
--- a/programs/notepad/Makefile.in
+++ b/programs/notepad/Makefile.in
@@ -49,6 +49,9 @@
 install: dummy
 	$(INSTALL_PROGRAM) notepad $(bindir)/notepad
 
+uninstall: dummy
+	$(RM) $(bindir)/notepad
+
 $(RC_SRCS:.rc=.s): $(WRC)
 
 dummy:
diff --git a/programs/progman/Makefile.in b/programs/progman/Makefile.in
index 0a6e2cd..6662fbd 100644
--- a/programs/progman/Makefile.in
+++ b/programs/progman/Makefile.in
@@ -54,6 +54,9 @@
 install: dummy
 	$(INSTALL_PROGRAM) progman $(bindir)/progman
 
+uninstall: dummy
+	$(RM) $(bindir)/progman
+
 $(RC_SRCS:.rc=.s): $(WRC)
 
 dummy:
diff --git a/programs/regtest/Makefile.in b/programs/regtest/Makefile.in
index 98683d4..a1a1e8d 100644
--- a/programs/regtest/Makefile.in
+++ b/programs/regtest/Makefile.in
@@ -19,7 +19,10 @@
 	$(CC) -o regtest $(OBJS) $(LDOPTIONS) $(ALL_LIBS)
 
 install: dummy
-	$(INSTALL_PROGRAM) regtest $(bindir)/program
+	$(INSTALL_PROGRAM) regtest $(bindir)/regtest
+
+uninstall: dummy
+	$(RM) $(bindir)/regtest
 
 dummy:
 
diff --git a/programs/view/Makefile.in b/programs/view/Makefile.in
index 0aea7f6..b531e80 100644
--- a/programs/view/Makefile.in
+++ b/programs/view/Makefile.in
@@ -37,6 +37,9 @@
 install: dummy
 	$(INSTALL_PROGRAM) view $(bindir)/view
 
+uninstall: dummy
+	$(RM) $(bindir)/view
+
 $(RC_SRCS:.rc=.s): $(WRC)
 
 dummy:
diff --git a/programs/winhelp/Makefile.in b/programs/winhelp/Makefile.in
index 76c40f0..a95fa77 100644
--- a/programs/winhelp/Makefile.in
+++ b/programs/winhelp/Makefile.in
@@ -53,6 +53,9 @@
 	$(INSTALL_PROGRAM) winhelp $(bindir)/winhelp
 	$(INSTALL_PROGRAM) hlp2sgml $(bindir)/hlp2sgml
 
+uninstall: dummy
+	$(RM) $(bindir)/winhelp $(bindir)/hlp2sgml
+
 y.tab.c y.tab.h: macro.yacc.y
 	$(YACC) -d -t $(SRCDIR)/macro.yacc.y
 
diff --git a/programs/winver/Makefile.in b/programs/winver/Makefile.in
index ed5911b..6082004 100644
--- a/programs/winver/Makefile.in
+++ b/programs/winver/Makefile.in
@@ -19,7 +19,10 @@
 	$(CC) -o winver $(OBJS) $(LDOPTIONS) $(ALL_LIBS)
 
 install: dummy
-	$(INSTALL_PROGRAM) winver $(bindir)/program
+	$(INSTALL_PROGRAM) winver $(bindir)/winver
+
+uninstall: dummy
+	$(RM) $(bindir)/winver
 
 dummy:
 
diff --git a/relay32/builtin32.c b/relay32/builtin32.c
index 5ea46b4..04c579e 100644
--- a/relay32/builtin32.c
+++ b/relay32/builtin32.c
@@ -385,7 +385,7 @@
     MSG( " (called from %p)", __builtin_return_address(1) );
 #endif
     MSG( "\n" );
-    TASK_KillCurrentTask(1);
+    ExitProcess(1);
 }
 
 
diff --git a/relay32/comctl32.spec b/relay32/comctl32.spec
index 8c7aa82..c385cf6 100644
--- a/relay32/comctl32.spec
+++ b/relay32/comctl32.spec
@@ -114,11 +114,11 @@
 236 stub Str_SetPtrW
 
 320 stdcall DSA_Create(long long) DSA_Create
-321 stdcall DSA_Destroy(long) DSA_Destroy
-322 stdcall DSA_GetItem(long long long) DSA_GetItem
+321 stdcall DSA_Destroy(ptr) DSA_Destroy
+322 stdcall DSA_GetItem(ptr long long) DSA_GetItem
 323 stdcall DSA_GetItemPtr(long long) DSA_GetItemPtr
 324 stdcall DSA_InsertItem(long long long) DSA_InsertItem
-325 stub DSA_SetItem
+325 stdcall DSA_SetItem (long long long) DSA_SetItem
 326 stdcall DSA_DeleteItem(long long) DSA_DeleteItem
 327 stub DSA_DeleteAllItems
 
diff --git a/relay32/gdi32.spec b/relay32/gdi32.spec
index 087e09b..8f31000 100644
--- a/relay32/gdi32.spec
+++ b/relay32/gdi32.spec
@@ -166,7 +166,7 @@
 162 stdcall GetClipBox(long ptr) GetClipBox32
 163 stdcall GetClipRgn(long long) GetClipRgn32
 164 stub GetColorAdjustment
-165 stub GetColorSpace
+165 stdcall GetColorSpace(long) GetColorSpace
 166 stdcall GetCurrentObject(long long) GetCurrentObject
 167 stdcall GetCurrentPositionEx(long ptr) GetCurrentPositionEx32
 168 stdcall GetDCOrgEx(long ptr) GetDCOrgEx
@@ -319,7 +319,7 @@
 315 stdcall SetEnhMetaFileBits(long ptr) SetEnhMetaFileBits
 316 stub SetFontEnumeration
 317 stdcall SetGraphicsMode(long long) SetGraphicsMode
-318 stub SetICMMode
+318 stdcall SetICMMode(long long) SetICMMode
 319 stub SetICMProfileA
 320 stub SetICMProfileW
 321 stdcall SetMapMode(long long) SetMapMode32
diff --git a/relay32/kernel32.spec b/relay32/kernel32.spec
index 8576577..2c08e16 100644
--- a/relay32/kernel32.spec
+++ b/relay32/kernel32.spec
@@ -12,15 +12,15 @@
 # - code generated by the MS Thunk Compiler
 # - symbols exported by the Oct 94 beta version of kernel32.dll
 
-  1 stdcall VxDCall0(long) VxDCall
-  2 stdcall VxDCall1(long) VxDCall
-  3 stdcall VxDCall2(long) VxDCall
-  4 stdcall VxDCall3(long) VxDCall
-  5 stdcall VxDCall4(long) VxDCall
-  6 stdcall VxDCall5(long) VxDCall
-  7 stdcall VxDCall6(long) VxDCall
-  8 stdcall VxDCall7(long) VxDCall
-  9 stdcall VxDCall8(long) VxDCall
+  1 register VxDCall0() VxDCall0
+  2 register VxDCall1() VxDCall1
+  3 register VxDCall2() VxDCall2
+  4 register VxDCall3() VxDCall3
+  5 register VxDCall4() VxDCall4
+  6 register VxDCall5() VxDCall5
+  7 register VxDCall6() VxDCall6
+  8 register VxDCall7() VxDCall7
+  9 register VxDCall8() VxDCall8
  10 stdcall k32CharToOemA(str str) CharToOem32A
  11 stdcall k32CharToOemBuffA(str str long) CharToOemBuff32A
  12 stdcall k32OemToCharA(ptr ptr) OemToChar32A
@@ -530,12 +530,12 @@
 513 stub LockFileEx
 514 stdcall LockResource(long) LockResource32
 515 stdcall MakeCriticalSectionGlobal(ptr) MakeCriticalSectionGlobal
-516 stub MapHInstLS
+516 register MapHInstLS() MapHInstLS
 517 stub MapHInstLS_PN
-518 stub MapHInstSL
+518 register MapHInstSL() MapHInstSL
 519 stub MapHInstSL_PN
-520 stub MapHModuleLS
-521 stub MapHModuleSL
+520 stdcall MapHModuleLS(long) MapHModuleLS
+521 stdcall MapHModuleSL(long) MapHModuleSL
 522 stdcall MapLS(ptr) MapLS
 523 stdcall MapSL(long) MapSL
 524 stdcall MapSLFix(long) MapSLFix
@@ -698,7 +698,7 @@
 681 stdcall SuspendThread(long) SuspendThread
 682 stdcall SystemTimeToFileTime(ptr ptr) SystemTimeToFileTime
 683 stub SystemTimeToTzSpecificLocalTime
-684 stdcall TerminateProcess(ptr long) TerminateProcess
+684 stdcall TerminateProcess(long long) TerminateProcess
 685 stdcall TerminateThread(long long) TerminateThread
 686 stub Thread32First
 687 stub Thread32Next
diff --git a/relay32/mpr.spec b/relay32/mpr.spec
index d1768b5..51d20e8 100644
--- a/relay32/mpr.spec
+++ b/relay32/mpr.spec
@@ -86,7 +86,7 @@
 0083 stub WNetGetResourceParentW
 0084 stub WNetGetUniversalNameA
 0085 stub WNetGetUniversalNameW
-0086 stub WNetGetUserA
+0086 stdcall WNetGetUserA(str ptr ptr) WNetGetUser32A
 0087 stub WNetGetUserW
 0088 stub WNetLogoffA
 0089 stub WNetLogoffW
diff --git a/relay32/ole32.spec b/relay32/ole32.spec
index bb6197c..4883fdb 100644
--- a/relay32/ole32.spec
+++ b/relay32/ole32.spec
@@ -139,7 +139,7 @@
 136 stub ReadFmtUserTypeStg
 137 stub ReadOleStg
 138 stub ReadStringStream
-139 stub RegisterDragDrop
+139 stdcall RegisterDragDrop(long ptr) RegisterDragDrop32
 140 stub ReleaseStgMedium
 141 stub RevokeDragDrop
 142 stub SetConvertStg
diff --git a/relay32/shell32.spec b/relay32/shell32.spec
index ecfefab..64e3546 100644
--- a/relay32/shell32.spec
+++ b/relay32/shell32.spec
@@ -22,7 +22,7 @@
   14 stub Control_FillCache_RunDLLW@16   # exported by name
   15 stdcall ILGetDisplayName(ptr ptr) ILGetDisplayName
   16 stdcall ILFindLastID(ptr) ILFindLastID
-  17 stub ILRemoveLastID@4
+  17 stdcall ILRemoveLastID@4(ptr) ILRemoveLastID
   18 stdcall ILClone(ptr) ILClone
   19 stub ILCloneFirst@4
   20 stub ILGlobalClone@4
@@ -158,7 +158,7 @@
  150 stub ExtractAssociatedIconExA   # exported by name
  151 stub SHLoadOLE
  152 stdcall ILGetSize(ptr) ILGetSize
- 153 stub ILGetNext
+ 153 stdcall ILGetNext(ptr) ILGetNext
  154 stub ILAppend
  155 stdcall ILFree(ptr) ILFree
  156 stub ILGlobalFree
@@ -297,8 +297,8 @@
  288 stdcall ShellAboutA(long str str long) ShellAbout32A
  289 stdcall ShellAboutW(long wstr wstr long) ShellAbout32W
  290 stdcall ShellExecuteA(long str str str str long) ShellExecute32A
- 291 stdcall ShellExecuteEx (long) ShellExecuteEx
- 292 stub ShellExecuteExA
+ 291 stdcall ShellExecuteEx (long) ShellExecuteEx32A
+ 292 stdcall ShellExecuteExA (long) ShellExecuteEx32A
  293 stub ShellExecuteExW
  294 stub ShellExecuteW
  295 stub ShellHookProc   # exported by name
@@ -373,3 +373,6 @@
  680 stub IsUserAdmin
 
 1217 stub FOOBAR1217   # no joke! This is the real name!!
+
+# later additions ... FIXME: incorrect ordinals
+1218 stdcall SHGetSpecialFolderPathA(long long long long) SHGetSpecialFolderPath
diff --git a/relay32/snoop.c b/relay32/snoop.c
index 534607d..9bc4e38 100644
--- a/relay32/snoop.c
+++ b/relay32/snoop.c
@@ -4,7 +4,6 @@
  * Copyright 1998 Marcus Meissner
  */
 
-#ifdef __i386__
 
 #include <assert.h>
 #include "windows.h"
@@ -19,6 +18,8 @@
 #include "debugstr.h"
 #include "debug.h"
 
+#ifdef __i386__
+
 char **debug_snoop_excludelist = NULL, **debug_snoop_includelist = NULL;
 
 #ifdef NEED_UNDERSCORE_PREFIX
diff --git a/relay32/winmm.spec b/relay32/winmm.spec
index 2ebbdd7..98d51cc 100644
--- a/relay32/winmm.spec
+++ b/relay32/winmm.spec
@@ -5,7 +5,7 @@
   2 stdcall WINMM_2(ptr long long) PlaySound32A
   3 stub WINMM_3
   4 stub CloseDriver
-  5 stub DefDriverProc
+  5 stdcall DefDriverProc(long long long long long) DefDriverProc
   6 stub DriverCallback
   7 stub DrvClose
   8 stub DrvDefDriverProc
@@ -19,7 +19,7 @@
  16 stdcall OpenDriverA(str str long) OpenDriver32A
  17 stdcall PlaySound(ptr long long) PlaySound32A
  18 stdcall PlaySoundW(ptr long long) PlaySound32W
- 19 stub SendDriverMessage
+ 19 stdcall SendDriverMessage(long long long long) SendDriverMessage32
  20 stdcall auxGetDevCapsA(long ptr long) auxGetDevCaps32A
  21 stdcall auxGetDevCapsW(long ptr long) auxGetDevCaps32W
  22 stdcall auxGetNumDevs() auxGetNumDevs32
@@ -127,7 +127,7 @@
 124 stdcall mmioRead(long ptr long) mmioRead32
 125 stub mmioRenameA
 126 stub mmioRenameW
-127 stub mmioSeek
+127 stdcall mmioSeek(long long long) mmioSeek32
 128 stub mmioSendMessage
 129 stub mmioSetBuffer
 130 stub mmioSetInfo
diff --git a/scheduler/client.c b/scheduler/client.c
index 4a35bcf..e39d82d 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -140,8 +140,9 @@
     vec[0].iov_base       = &head;
     vec[0].iov_len        = sizeof(head);
 
-    if ((ret = recvmsg( thdb->socket, &msghdr, 0 )) == -1)
+    while ((ret = recvmsg( thdb->socket, &msghdr, 0 )) == -1)
     {
+        if (errno == EINTR) continue;
         perror("recvmsg");
         CLIENT_ProtocolError( "recvmsg\n" );
     }
@@ -378,6 +379,7 @@
     return reply.handle;
 }
 
+
 /***********************************************************************
  *           CLIENT_GetProcessInfo
  *
@@ -395,6 +397,22 @@
 
 
 /***********************************************************************
+ *           CLIENT_GetThreadInfo
+ *
+ * Send a get thread info request. Return 0 if OK.
+ */
+int CLIENT_GetThreadInfo( int handle, struct get_thread_info_reply *reply )
+{
+    int len, err;
+
+    CLIENT_SendRequest( REQ_GET_THREAD_INFO, -1, 1, &handle, sizeof(handle) );
+    err = CLIENT_WaitReply( &len, NULL, 1, reply, sizeof(*reply) );
+    CHECK_LEN( len, sizeof(*reply) );
+    return err;
+}
+
+
+/***********************************************************************
  *           CLIENT_OpenProcess
  *
  * Open a handle to a process.
@@ -414,3 +432,26 @@
     CHECK_LEN( len, sizeof(reply) );
     return reply.handle;
 }
+
+
+/***********************************************************************
+ *           CLIENT_Select
+ */
+int CLIENT_Select( int count, int *handles, int flags, int timeout )
+{
+    struct select_request req;
+    struct select_reply reply;
+    int len;
+
+    req.count   = count;
+    req.flags   = flags;
+    req.timeout = timeout;
+
+    CLIENT_SendRequest( REQ_SELECT, -1, 2,
+                        &req, sizeof(req),
+                        handles, count * sizeof(int) );
+    CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
+    CHECK_LEN( len, sizeof(reply) );
+    return reply.signaled;
+}
+
diff --git a/scheduler/critsection.c b/scheduler/critsection.c
index e154abe..4cd478a 100644
--- a/scheduler/critsection.c
+++ b/scheduler/critsection.c
@@ -156,7 +156,7 @@
             struct sembuf sop;
             sop.sem_num = 0;
             sop.sem_op  = -1;
-            sop.sem_flg = SEM_UNDO;
+            sop.sem_flg = 0/*SEM_UNDO*/;
             do
             {
                 ret = semop( (int)crit->Reserved, &sop, 1 );
@@ -224,7 +224,7 @@
             struct sembuf sop;
             sop.sem_num = 0;
             sop.sem_op  = 1;
-            sop.sem_flg = SEM_UNDO;
+            sop.sem_flg = 0/*SEM_UNDO*/;
             semop( (int)crit->Reserved, &sop, 1 );
         }
     }
diff --git a/scheduler/k32obj.c b/scheduler/k32obj.c
index 960e962..aebca61 100644
--- a/scheduler/k32obj.c
+++ b/scheduler/k32obj.c
@@ -21,6 +21,7 @@
 extern const K32OBJ_OPS FILE_Ops;
 extern const K32OBJ_OPS CHANGE_Ops;
 extern const K32OBJ_OPS MEM_MAPPED_FILE_Ops;
+extern const K32OBJ_OPS DEVICE_Ops;
 extern const K32OBJ_OPS CONSOLE_Ops;
 
 static const K32OBJ_OPS K32OBJ_NullOps =
@@ -49,7 +50,7 @@
     &K32OBJ_NullOps,        /* K32OBJ_SCREEN_BUFFER */
     &MEM_MAPPED_FILE_Ops,   /* K32OBJ_MEM_MAPPED_FILE */
     &K32OBJ_NullOps,        /* K32OBJ_SERIAL */
-    &K32OBJ_NullOps,        /* K32OBJ_DEVICE_IOCTL */
+    &DEVICE_Ops,            /* K32OBJ_DEVICE_IOCTL */
     &K32OBJ_NullOps,        /* K32OBJ_PIPE */
     &K32OBJ_NullOps,        /* K32OBJ_MAILSLOT */
     &K32OBJ_NullOps,        /* K32OBJ_TOOLHELP_SNAPSHOT */
diff --git a/scheduler/process.c b/scheduler/process.c
index 3ccd3d2..3c1f94a 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -128,7 +128,8 @@
 /***********************************************************************
  *           PROCESS_InheritEnvDB
  */
-static BOOL32 PROCESS_InheritEnvDB( PDB32 *pdb, LPCSTR cmd_line, LPCSTR env )
+static BOOL32 PROCESS_InheritEnvDB( PDB32 *pdb, LPCSTR cmd_line, LPCSTR env,
+                                    STARTUPINFO32A *startup )
 {
     if (!(pdb->env_db = HeapAlloc(pdb->heap, HEAP_ZERO_MEMORY, sizeof(ENVDB))))
         return FALSE;
@@ -143,10 +144,25 @@
     if (!(pdb->env_db->cmd_line = HEAP_strdupA( pdb->heap, 0, cmd_line )))
         return FALSE;
 
+    /* Remember startup info */
+    if (!(pdb->env_db->startup_info = 
+          HeapAlloc( pdb->heap, HEAP_ZERO_MEMORY, sizeof(STARTUPINFO32A) )))
+        return FALSE;
+    *pdb->env_db->startup_info = *startup;
+
     /* Inherit the standard handles */
-    pdb->env_db->hStdin  = pdb->parent->env_db->hStdin;
-    pdb->env_db->hStdout = pdb->parent->env_db->hStdout;
-    pdb->env_db->hStderr = pdb->parent->env_db->hStderr;
+    if (pdb->env_db->startup_info->dwFlags & STARTF_USESTDHANDLES)
+    {
+        pdb->env_db->hStdin  = pdb->env_db->startup_info->hStdInput;
+        pdb->env_db->hStdout = pdb->env_db->startup_info->hStdOutput;
+        pdb->env_db->hStderr = pdb->env_db->startup_info->hStdError;
+    }
+    else
+    {
+        pdb->env_db->hStdin  = pdb->parent->env_db->hStdin;
+        pdb->env_db->hStdout = pdb->parent->env_db->hStdout;
+        pdb->env_db->hStderr = pdb->parent->env_db->hStderr;
+    }
 
     return TRUE;
 }
@@ -249,13 +265,15 @@
  */
 PDB32 *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
                        HINSTANCE16 hInstance, HINSTANCE16 hPrevInstance,
-                       UINT32 cmdShow, PROCESS_INFORMATION *info )
+                       STARTUPINFO32A *startup, PROCESS_INFORMATION *info )
 {
     DWORD size, commit;
     int server_thandle, server_phandle;
+    UINT32 cmdShow = 0;
     THDB *thdb = NULL;
     PDB32 *parent = PROCESS_Current();
     PDB32 *pdb = PROCESS_CreatePDB( parent );
+    TDB *pTask;
 
     if (!pdb) return NULL;
     info->hThread = info->hProcess = INVALID_HANDLE_VALUE32;
@@ -278,7 +296,7 @@
 
     /* Inherit the env DB from the parent */
 
-    if (!PROCESS_InheritEnvDB( pdb, cmd_line, env )) goto error;
+    if (!PROCESS_InheritEnvDB( pdb, cmd_line, env, startup )) goto error;
 
     /* Create the main thread */
 
@@ -295,12 +313,22 @@
                                         FALSE, server_phandle )) == INVALID_HANDLE_VALUE32)
         goto error;
     info->dwProcessId = PDB_TO_PROCESS_ID(pdb);
-    info->dwProcessId = THDB_TO_THREAD_ID(thdb);
+    info->dwThreadId  = THDB_TO_THREAD_ID(thdb);
 
+#if 0
     thdb->unix_pid = getpid(); /* FIXME: wrong here ... */
+#else
+    /* All Win16 'threads' have the same unix_pid, no matter by which thread
+       they were created ! */
+    pTask = (TDB *)GlobalLock16( parent->task );
+    thdb->unix_pid = pTask? pTask->thdb->unix_pid : THREAD_Current()->unix_pid;
+#endif
 
     /* Create a Win16 task for this process */
 
+    if (startup->dwFlags & STARTF_USESHOWWINDOW)
+        cmdShow = startup->wShowWindow;
+
     pdb->task = TASK_Create( thdb, pModule, hInstance, hPrevInstance, cmdShow);
     if (!pdb->task) goto error;
 
@@ -386,6 +414,11 @@
 void WINAPI ExitProcess( DWORD status )
 {
     PDB32 *pdb = PROCESS_Current();
+    TDB *pTask = (TDB *)GlobalLock16( pdb->task );
+    if ( pTask ) pTask->nEvents++;
+
+    if ( pTask && pTask->thdb != THREAD_Current() )
+        ExitThread( status );
 
     SYSTEM_LOCK();
     /* FIXME: should kill all running threads of this process */
@@ -399,6 +432,20 @@
 }
 
 
+/******************************************************************************
+ *           TerminateProcess   (KERNEL32.684)
+ */
+BOOL32 WINAPI TerminateProcess( HANDLE32 handle, DWORD exit_code )
+{
+    int server_handle;
+    BOOL32 ret;
+    PDB32 *pdb = PROCESS_GetPtr( handle, PROCESS_TERMINATE, &server_handle );
+    if (!pdb) return FALSE;
+    ret = !CLIENT_TerminateProcess( server_handle, exit_code );
+    K32OBJ_DecCount( &pdb->header );
+    return ret;
+}
+
 /***********************************************************************
  *           GetCurrentProcess   (KERNEL32.198)
  */
@@ -757,7 +804,7 @@
     entry = pdb->thread_list->next;
     for (;;)
     {
-         if (entry->thread != THREAD_Current())
+         if (entry->thread != THREAD_Current() && !THREAD_IsWin16(entry->thread))
          {
              HANDLE32 handle = HANDLE_Alloc( PROCESS_Current(), 
                                              &entry->thread->header,
@@ -787,7 +834,7 @@
     entry = pdb->thread_list->next;
     for (;;)
     {
-         if (entry->thread != THREAD_Current())
+         if (entry->thread != THREAD_Current() && !THREAD_IsWin16(entry->thread))
          {
              HANDLE32 handle = HANDLE_Alloc( PROCESS_Current(), 
                                              &entry->thread->header,
diff --git a/scheduler/synchro.c b/scheduler/synchro.c
index 229134c..4ed9a25 100644
--- a/scheduler/synchro.c
+++ b/scheduler/synchro.c
@@ -13,6 +13,7 @@
 #include "process.h"
 #include "thread.h"
 #include "winerror.h"
+#include "server.h"
 #include "debug.h"
 
 /***********************************************************************
@@ -25,15 +26,16 @@
     DWORD i;
     K32OBJ **ptr;
 
+    SYSTEM_LOCK();
     wait->count    = count;
     wait->signaled = WAIT_FAILED;
     wait->wait_all = wait_all;
     wait->wait_msg = wait_msg;
-    SYSTEM_LOCK();
     for (i = 0, ptr = wait->objs; i < count; i++, ptr++)
     {
         if (!(*ptr = HANDLE_GetObjPtr( PROCESS_Current(), handles[i],
-                                       K32OBJ_UNKNOWN, SYNCHRONIZE, NULL )))
+                                       K32OBJ_UNKNOWN, SYNCHRONIZE,
+                                       &wait->server[i] )))
         { 
             ERR(win32, "Bad handle %08x\n", handles[i]); 
             break; 
@@ -251,7 +253,7 @@
         THDB *thdb = entry->thread;
         if (SYNC_CheckCondition( &thdb->wait_struct, THDB_TO_THREAD_ID(thdb) ))
         {
-            TRACE(win32, "waking up %04x\n", thdb->teb_sel );
+            TRACE(win32, "waking up %04x (pid %d)\n", thdb->teb_sel, thdb->unix_pid );
             if (thdb->unix_pid)
 	    	kill( thdb->unix_pid, SIGUSR1 );
 	    else
@@ -314,15 +316,51 @@
         wait->signaled = WAIT_FAILED;
     else
     {
-        /* Now wait for it */
-        SYNC_WaitForCondition( wait, timeout );
-        SYNC_FreeWaitStruct( wait );
+        int i;
+        /* Check if we can use a server wait */
+        for (i = 0; i < count; i++)
+            if (wait->server[i] == -1) break;
+        if (i == count)
+        {
+            int flags = 0;
+            SYSTEM_UNLOCK();
+            if (wait_all) flags |= SELECT_ALL;
+            if (alertable) flags |= SELECT_ALERTABLE;
+            if (wait_msg) flags |= SELECT_MSG;
+            if (timeout != INFINITE32) flags |= SELECT_TIMEOUT;
+            return CLIENT_Select( count, wait->server, flags, timeout );
+        }
+        else
+        {
+            /* Now wait for it */
+            SYNC_WaitForCondition( wait, timeout );
+            SYNC_FreeWaitStruct( wait );
+        }
     }
     SYSTEM_UNLOCK();
     return wait->signaled;
 }
 
 /***********************************************************************
+ *              Sleep  (KERNEL32.679)
+ */
+VOID WINAPI Sleep( DWORD timeout )
+{
+    SYNC_DoWait( 0, NULL, FALSE, timeout, FALSE, FALSE );
+}
+
+/******************************************************************************
+ *              SleepEx   (KERNEL32.680)
+ */
+DWORD WINAPI SleepEx( DWORD timeout, BOOL32 alertable )
+{
+    DWORD ret = SYNC_DoWait( 0, NULL, FALSE, timeout, alertable, FALSE );
+    if (ret != WAIT_IO_COMPLETION) ret = 0;
+    return ret;
+}
+
+
+/***********************************************************************
  *           WaitForSingleObject   (KERNEL32.723)
  */
 DWORD WINAPI WaitForSingleObject( HANDLE32 handle, DWORD timeout )
diff --git a/scheduler/sysdeps.c b/scheduler/sysdeps.c
index d63d30f..9ec3b7a 100644
--- a/scheduler/sysdeps.c
+++ b/scheduler/sysdeps.c
@@ -115,6 +115,8 @@
  */
 void SYSDEPS_ExitThread(void)
 {
+    THDB *thdb = THREAD_Current();
+    close( thdb->socket );
     _exit( 0 );
 }
 
diff --git a/scheduler/syslevel.c b/scheduler/syslevel.c
index 50a5dd3..483dbb0 100644
--- a/scheduler/syslevel.c
+++ b/scheduler/syslevel.c
@@ -13,6 +13,9 @@
 static CRITICAL_SECTION Win16Mutex;
 static SEGPTR segpWin16Mutex;
 
+/* Global variable to save current TEB while in 16-bit code */
+WORD SYSLEVEL_Win16CurrentTeb = 0;
+
 
 /************************************************************************
  *           SYSLEVEL_Init
@@ -49,6 +52,9 @@
 VOID WINAPI _EnterSysLevel(CRITICAL_SECTION *lock)
 {
     EnterCriticalSection(lock);
+
+    if (lock == &Win16Mutex)
+        GET_FS( SYSLEVEL_Win16CurrentTeb );
 }
 
 /************************************************************************
diff --git a/scheduler/thread.c b/scheduler/thread.c
index 2fabdbc..60365d5 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -9,6 +9,9 @@
 #include <unistd.h>
 #include "thread.h"
 #include "process.h"
+#include "task.h"
+#include "module.h"
+#include "user.h"
 #include "winerror.h"
 #include "heap.h"
 #include "selectors.h"
@@ -78,6 +81,20 @@
     return (THDB *)((char *)NtCurrentTeb() - (int)&((THDB *)0)->teb);
 }
 
+/***********************************************************************
+ *           THREAD_IsWin16
+ */
+BOOL32 THREAD_IsWin16( THDB *thdb )
+{
+    if (!thdb || !thdb->process)
+        return TRUE;
+    else
+    {
+        TDB* pTask = (TDB*)GlobalLock16( thdb->process->task );
+        return !pTask || pTask->thdb == thdb;
+    }
+}
+
 
 /***********************************************************************
  *           THREAD_AddQueue
@@ -688,7 +705,7 @@
 
 
 /**********************************************************************
- * TerminateThread [KERNEL32.???]  Terminates a thread
+ * TerminateThread [KERNEL32.685]  Terminates a thread
  *
  * RETURNS
  *    Success: TRUE
@@ -698,9 +715,15 @@
     HANDLE32 handle, /* [in] Handle to thread */
     DWORD exitcode)  /* [in] Exit code for thread */
 {
-    FIXME(thread,"(0x%08x,%ld): stub\n",handle,exitcode);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return TRUE;
+    int server_handle;
+    BOOL32 ret;
+    THDB *thread;
+    
+    if (!(thread = THREAD_GetPtr( handle, THREAD_TERMINATE, &server_handle )))
+        return FALSE;
+    ret = !CLIENT_TerminateThread( server_handle, exitcode );
+    K32OBJ_DecCount( &thread->header );
+    return ret;
 }
 
 
@@ -716,10 +739,17 @@
     LPDWORD exitcode) /* [out] Address to receive termination status */
 {
     THDB *thread;
-    
-    if (!(thread = THREAD_GetPtr( hthread, THREAD_QUERY_INFORMATION, NULL )))
+    int server_handle;
+
+    if (!(thread = THREAD_GetPtr( hthread, THREAD_QUERY_INFORMATION, &server_handle )))
         return FALSE;
-    if (exitcode) *exitcode = thread->exit_code;
+    if (server_handle != -1)
+    {
+        struct get_thread_info_reply info;
+        CLIENT_GetThreadInfo( server_handle, &info );
+        if (exitcode) *exitcode = info.exit_code;
+    }
+    else if (exitcode) *exitcode = thread->exit_code;
     K32OBJ_DecCount( &thread->header );
     return TRUE;
 }
diff --git a/server/object.c b/server/object.c
index 17a6843..c05a310 100644
--- a/server/object.c
+++ b/server/object.c
@@ -69,6 +69,8 @@
 {
     obj->refcount = 1;
     obj->ops      = ops;
+    obj->head     = NULL;
+    obj->tail     = NULL;
     if (!name) obj->name = NULL;
     else obj->name = add_name( obj, name );
 }
@@ -89,6 +91,9 @@
     assert( obj->refcount );
     if (!--obj->refcount)
     {
+        /* if the refcount is 0, nobody can be in the wait queue */
+        assert( !obj->head );
+        assert( !obj->tail );
         if (obj->name) free_name( obj );
         obj->ops->destroy( obj );
     }
diff --git a/server/process.c b/server/process.c
index b3adcb2..06d3d63 100644
--- a/server/process.c
+++ b/server/process.c
@@ -6,6 +6,7 @@
 
 #include <assert.h>
 #include <limits.h>
+#include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/time.h>
@@ -54,12 +55,17 @@
 /* process operations */
 
 static void dump_process( struct object *obj, int verbose );
+static int process_signaled( struct object *obj, struct thread *thread );
+static int process_satisfied( struct object *obj, struct thread *thread );
 static void destroy_process( struct object *obj );
 static void free_handles( struct process *process );
+static int copy_handle_table( struct process *process, struct process *parent );
 
 static const struct object_ops process_ops =
 {
     dump_process,
+    process_signaled,
+    process_satisfied,
     destroy_process
 };
 
@@ -67,10 +73,10 @@
 struct process *create_process(void)
 {
     struct process *process;
-    struct handle_entry *entries;
 
     if (!(process = malloc( sizeof(*process) ))) return NULL;
-    if (!(entries = malloc( MIN_HANDLE_ENTRIES * sizeof(struct handle_entry))))
+
+    if (!copy_handle_table( process, current ? current->process : NULL ))
     {
         free( process );
         return NULL;
@@ -81,14 +87,12 @@
     process->thread_list     = NULL;
     process->exit_code       = 0x103;  /* STILL_ACTIVE */
     process->running_threads = 0;
-    process->handle_count    = MIN_HANDLE_ENTRIES;
-    process->handle_last     = -1;
-    process->entries         = entries;
 
     if (first_process) first_process->prev = process;
     first_process = process;
 
     gettimeofday( &process->start_time, NULL );
+    /* alloc a handle for the process itself */
     alloc_handle( process, process, PROCESS_ALL_ACCESS, 0 );
     return process;
 }
@@ -105,6 +109,7 @@
     if (process->prev) process->prev->next = process->next;
     else first_process = process->next;
     free_handles( process );
+    if (debug_level) memset( process, 0xbb, sizeof(process) );  /* catch errors */
     free( process );
 }
 
@@ -117,6 +122,17 @@
     printf( "Process next=%p prev=%p\n", process->next, process->prev );
 }
 
+static int process_signaled( struct object *obj, struct thread *thread )
+{
+    struct process *process = (struct process *)obj;
+    return (process->running_threads > 0);
+}
+
+static int process_satisfied( struct object *obj, struct thread *thread )
+{
+    return 0;
+}
+
 /* get a process from an id (and increment the refcount) */
 struct process *get_process_from_id( void *id )
 {
@@ -140,6 +156,7 @@
     assert( !process->thread_list );
     process->exit_code = exit_code;
     gettimeofday( &process->end_time, NULL );
+    wake_up( &process->obj, 0 );
     free_handles( process );
 }
 
@@ -308,6 +325,45 @@
     return 1;
 }
 
+/* copy the handle table of the parent process */
+/* return 1 if OK, 0 on error */
+static int copy_handle_table( struct process *process, struct process *parent )
+{
+    struct handle_entry *ptr;
+    int i, count, last;
+
+    if (!parent)  /* first process */
+    {
+        count = MIN_HANDLE_ENTRIES;
+        last  = -1;
+    }
+    else
+    {
+        assert( parent->entries );
+        count = parent->handle_count;
+        last  = parent->handle_last;
+    }
+
+    if (!(ptr = malloc( count * sizeof(struct handle_entry)))) return 0;
+    process->entries      = ptr;
+    process->handle_count = count;
+    process->handle_last  = last;
+
+    if (last >= 0)
+    {
+        memcpy( ptr, parent->entries, (last + 1) * sizeof(struct handle_entry) );
+        for (i = 0; i <= last; i++, ptr++)
+        {
+            if (!ptr->ptr) continue;
+            if (ptr->access & RESERVED_INHERIT) grab_object( ptr->ptr );
+            else ptr->ptr = NULL; /* don't inherit this entry */
+        }
+    }
+    /* attempt to shrink the table */
+    shrink_handle_table( process );
+    return 1;
+}
+
 /* close a handle and decrement the refcount of the associated object */
 /* return 1 if OK, 0 on error */
 int close_handle( struct process *process, int handle )
@@ -390,7 +446,7 @@
 
     if (!process->entries) return;
     entry = process->entries;
-    for (i = 0; i < process->handle_last; i++, entry++)
+    for (i = 0; i <= process->handle_last; i++, entry++)
     {
         if (!entry->ptr) continue;
         printf( "%5d: %p %08x ", i + 1, entry->ptr, entry->access );
diff --git a/server/request.c b/server/request.c
index 397fe4f..e481d76 100644
--- a/server/request.c
+++ b/server/request.c
@@ -7,6 +7,7 @@
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/types.h>
 #include <sys/uio.h>
 #include <unistd.h>
 
@@ -71,7 +72,7 @@
     current = thread;
     if (debug_level) trace_timeout();
     CLEAR_ERROR();
-    send_reply( current, -1, 0 );
+    thread_timeout();
     current = NULL;
 }
 
@@ -131,6 +132,12 @@
 /* create a new thread */
 DECL_HANDLER(init_thread)
 {
+    if (current->state != STARTING)
+    {
+        fatal_protocol_error( "init_thread: already running\n" );
+        return;
+    }
+    current->state    = RUNNING;
     current->unix_pid = req->unix_pid;
     if (!(current->name = malloc( len + 1 )))
     {
@@ -213,7 +220,21 @@
     send_reply( current, -1, 1, &reply, sizeof(reply) );
 }
 
-/* open a handle a process */
+/* fetch information about a thread */
+DECL_HANDLER(get_thread_info)
+{
+    struct thread *thread;
+    struct get_thread_info_reply reply = { 0, 0 };
+
+    if ((thread = get_thread_from_handle( req->handle, THREAD_QUERY_INFORMATION )))
+    {
+        get_thread_info( thread, &reply );
+        release_object( thread );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* open a handle to a process */
 DECL_HANDLER(open_process)
 {
     struct open_process_reply reply = { -1 };
@@ -226,3 +247,12 @@
     }
     send_reply( current, -1, 1, &reply, sizeof(reply) );
 }
+
+/* select on a handle list */
+DECL_HANDLER(select)
+{
+    if (len != req->count * sizeof(int))
+        fatal_protocol_error( "select: bad length %d for %d handles\n",
+                              len, req->count );
+    sleep_on( current, req->count, (int *)data, req->flags, req->timeout );
+}
diff --git a/server/socket.c b/server/socket.c
index 5d96a93..fd85741 100644
--- a/server/socket.c
+++ b/server/socket.c
@@ -165,9 +165,6 @@
 #endif
     int ret;
 
-    if (client->state == RUNNING) client->state = SENDING;
-    assert( client->state == SENDING );
-
     if (client->count < sizeof(client->head))
     {
         vec.iov_base = (char *)&client->head + client->count;
@@ -207,6 +204,9 @@
         return;
     }
 
+    if (client->state == RUNNING) client->state = SENDING;
+    assert( client->state == SENDING );
+
     client->count += ret;
 
     /* received the complete header yet? */
diff --git a/server/thread.c b/server/thread.c
index 206e1a9..e250cc8 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -10,6 +10,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/types.h>
 #include <sys/uio.h>
 #include <unistd.h>
 
@@ -19,14 +20,37 @@
 #include "server/thread.h"
 
 
+/* thread queues */
+
+struct wait_queue_entry
+{
+    struct wait_queue_entry *next;
+    struct wait_queue_entry *prev;
+    struct object           *obj;
+    struct thread           *thread;
+};
+
+struct thread_wait
+{
+    int                     count;      /* count of objects */
+    int                     flags;
+    struct timeval          timeout;
+    struct wait_queue_entry queues[1];
+};
+
+
 /* thread operations */
 
 static void dump_thread( struct object *obj, int verbose );
+static int thread_signaled( struct object *obj, struct thread *thread );
+static int thread_satisfied( struct object *obj, struct thread *thread );
 static void destroy_thread( struct object *obj );
 
 static const struct object_ops thread_ops =
 {
     dump_thread,
+    thread_signaled,
+    thread_satisfied,
     destroy_thread
 };
 
@@ -55,7 +79,9 @@
     thread->process   = process;
     thread->unix_pid  = 0;  /* not known yet */
     thread->name      = NULL;
+    thread->wait      = NULL;
     thread->error     = 0;
+    thread->state     = STARTING;
     thread->exit_code = 0x103;  /* STILL_ACTIVE */
     thread->next      = first_thread;
     thread->prev      = NULL;
@@ -104,6 +130,7 @@
     if (thread->prev) thread->prev->next = thread->next;
     else first_thread = thread->next;
     if (thread->name) free( thread->name );
+    if (debug_level) memset( thread, 0xaa, sizeof(thread) );  /* catch errors */
     free( thread );
 }
 
@@ -117,6 +144,17 @@
             thread->unix_pid, thread->client_fd, thread->name );
 }
 
+static int thread_signaled( struct object *obj, struct thread *thread )
+{
+    struct thread *mythread = (struct thread *)obj;
+    return (mythread->state == TERMINATED);
+}
+
+static int thread_satisfied( struct object *obj, struct thread *thread )
+{
+    return 0;
+}
+
 /* get a thread pointer from a thread id (and increment the refcount) */
 struct thread *get_thread_from_id( void *id )
 {
@@ -133,6 +171,14 @@
                                             access, &thread_ops );
 }
 
+/* get all information about a thread */
+void get_thread_info( struct thread *thread,
+                      struct get_thread_info_reply *reply )
+{
+    reply->pid       = thread;
+    reply->exit_code = thread->exit_code;
+}
+
 /* send a reply to a thread */
 int send_reply( struct thread *thread, int pass_fd, int n,
                 ... /* arg_1, len_1, ..., arg_n, len_n */ )
@@ -152,6 +198,201 @@
     return send_reply_v( thread->client_fd, thread->error, pass_fd, vec, n );
 }
 
+/* add a thread to an object wait queue; return 1 if OK, 0 on error */
+static void add_queue( struct object *obj, struct wait_queue_entry *entry )
+{
+    entry->obj    = obj;
+    entry->prev   = obj->tail;
+    entry->next   = NULL;
+    if (obj->tail) obj->tail->next = entry;
+    else obj->head = entry;
+    obj->tail = entry;
+}
+
+/* remove a thread from an object wait queue */
+static void remove_queue( struct wait_queue_entry *entry )
+{
+    struct object *obj = entry->obj;
+
+    if (entry->next) entry->next->prev = entry->prev;
+    else obj->tail = entry->prev;
+    if (entry->prev) entry->prev->next = entry->next;
+    else obj->head = entry->next;
+    release_object( obj );
+}
+
+/* finish waiting */
+static void end_wait( struct thread *thread )
+{
+    struct thread_wait *wait = thread->wait;
+    struct wait_queue_entry *entry;
+    int i;
+
+    assert( wait );
+    for (i = 0, entry = wait->queues; i < wait->count; i++)
+        remove_queue( entry++ );
+    if (wait->flags & SELECT_TIMEOUT) set_timeout( thread->client_fd, NULL );
+    free( wait );
+    thread->wait = NULL;
+}
+
+/* build the thread wait structure */
+static int wait_on( struct thread *thread, int count,
+                    int *handles, int flags, int timeout )
+{
+    struct thread_wait *wait;
+    struct wait_queue_entry *entry;
+    struct object *obj;
+    int i;
+
+    if ((count < 0) || (count > MAXIMUM_WAIT_OBJECTS))
+    {
+        SET_ERROR( ERROR_INVALID_PARAMETER );
+        return 0;
+    }
+    if (!(wait = malloc( sizeof(*wait) + (count-1) * sizeof(*entry) )))
+    {
+        SET_ERROR( ERROR_OUTOFMEMORY );
+        return 0;
+    }
+    thread->wait  = wait;
+    wait->count   = count;
+    wait->flags   = flags;
+    if (flags & SELECT_TIMEOUT)
+    {
+        gettimeofday( &wait->timeout, 0 );
+        if (timeout)
+        {
+            wait->timeout.tv_usec += (timeout % 1000) * 1000;
+            if (wait->timeout.tv_usec >= 1000000)
+            {
+                wait->timeout.tv_usec -= 1000000;
+                wait->timeout.tv_sec++;
+            }
+            wait->timeout.tv_sec += timeout / 1000;
+        }
+    }
+
+    for (i = 0, entry = wait->queues; i < count; i++, entry++)
+    {
+        if (!(obj = get_handle_obj( thread->process, handles[i],
+                                    SYNCHRONIZE, NULL )))
+        {
+            wait->count = i - 1;
+            end_wait( thread );
+            return 0;
+        }
+        entry->thread = thread;
+        add_queue( obj, entry );
+    }
+    return 1;
+}
+
+/* check if the thread waiting condition is satisfied */
+static int check_wait( struct thread *thread, int *signaled )
+{
+    int i;
+    struct thread_wait *wait = thread->wait;
+    struct wait_queue_entry *entry = wait->queues;
+    struct timeval now;
+
+    assert( wait );
+    if (wait->flags & SELECT_ALL)
+    {
+        for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
+            if (!entry->obj->ops->signaled( entry->obj, thread )) goto check_timeout;
+        /* Wait satisfied: tell it to all objects */
+        *signaled = 0;
+        for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
+            if (entry->obj->ops->satisfied( entry->obj, thread ))
+                *signaled = STATUS_ABANDONED_WAIT_0;
+        return 1;
+    }
+    else
+    {
+        for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
+        {
+            if (!entry->obj->ops->signaled( entry->obj, thread )) continue;
+            /* Wait satisfied: tell it to the object */
+            *signaled = i;
+            if (entry->obj->ops->satisfied( entry->obj, thread ))
+                *signaled += STATUS_ABANDONED_WAIT_0;
+            return 1;
+        }
+    }
+ check_timeout:
+    if (!(wait->flags & SELECT_TIMEOUT)) return 0;
+    gettimeofday( &now, NULL );
+    if ((now.tv_sec > wait->timeout.tv_sec) ||
+        ((now.tv_sec == wait->timeout.tv_sec) &&
+         (now.tv_usec >= wait->timeout.tv_usec)))
+    {
+        *signaled = STATUS_TIMEOUT;
+        return 1;
+    }
+    return 0;
+}
+
+/* sleep on a list of objects */
+void sleep_on( struct thread *thread, int count, int *handles, int flags, int timeout )
+{
+    struct select_reply reply;
+
+    assert( !thread->wait );
+    reply.signaled = -1;
+    if (!wait_on( thread, count, handles, flags, timeout )) goto done;
+    if (!check_wait( thread, &reply.signaled ))
+    {
+        /* we need to wait */
+        if (flags & SELECT_TIMEOUT)
+            set_timeout( thread->client_fd, &thread->wait->timeout );
+        return;
+    }
+    end_wait( thread );
+ done:
+    send_reply( thread, -1, 1, &reply, sizeof(reply) );
+}
+
+/* attempt to wake up a thread */
+/* return 1 if OK, 0 if the wait condition is still not satisfied */
+static int wake_thread( struct thread *thread )
+{
+    struct select_reply reply;
+
+    if (!check_wait( thread, &reply.signaled )) return 0;
+    end_wait( thread );
+    send_reply( thread, -1, 1, &reply, sizeof(reply) );
+    return 1;
+}
+
+/* timeout for the current thread */
+void thread_timeout(void)
+{
+    struct select_reply reply;
+
+    assert( current->wait );
+
+    reply.signaled = STATUS_TIMEOUT;
+    end_wait( current );
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* attempt to wake threads sleeping on the object wait queue */
+void wake_up( struct object *obj, int max )
+{
+    struct wait_queue_entry *entry = obj->head;
+
+    while (entry)
+    {
+        struct wait_queue_entry *next = entry->next;
+        if (wake_thread( entry->thread ))
+        {
+            if (max && !--max) break;
+        }
+        entry = next;
+    }
+}
+
 /* kill a thread on the spot */
 void kill_thread( struct thread *thread, int exit_code )
 {
@@ -162,7 +403,10 @@
 /* a thread has been killed */
 void thread_killed( struct thread *thread, int exit_code )
 {
+    thread->state = TERMINATED;
     thread->exit_code = exit_code;
+    if (thread->wait) end_wait( thread );
     remove_process_thread( thread->process, thread );
+    wake_up( &thread->obj, 0 );
     release_object( thread );
 }
diff --git a/server/trace.c b/server/trace.c
index 712edea..a9158ce 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1,6 +1,7 @@
 /* File generated automatically by tools/make_requests; DO NOT EDIT!! */
 
 #include <stdio.h>
+#include <sys/types.h>
 #include <sys/uio.h>
 #include "server.h"
 #include "server/thread.h"
@@ -46,6 +47,17 @@
     printf( " exit_code=%d", req->exit_code );
 }
 
+static void dump_get_thread_info_request( struct get_thread_info_request *req )
+{
+    printf( " handle=%d", req->handle );
+}
+
+static void dump_get_thread_info_reply( struct get_thread_info_reply *req )
+{
+    printf( " pid=%p,", req->pid );
+    printf( " exit_code=%d", req->exit_code );
+}
+
 static void dump_close_handle_request( struct close_handle_request *req )
 {
     printf( " handle=%d", req->handle );
@@ -79,6 +91,18 @@
     printf( " handle=%d", req->handle );
 }
 
+static void dump_select_request( struct select_request *req )
+{
+    printf( " count=%d,", req->count );
+    printf( " flags=%d,", req->flags );
+    printf( " timeout=%d", req->timeout );
+}
+
+static void dump_select_reply( struct select_reply *req )
+{
+    printf( " signaled=%d", req->signaled );
+}
+
 struct dumper
 {
     void (*dump_req)();
@@ -103,6 +127,9 @@
     { (void(*)())dump_get_process_info_request,
       (void(*)())dump_get_process_info_reply,
       sizeof(struct get_process_info_request) },
+    { (void(*)())dump_get_thread_info_request,
+      (void(*)())dump_get_thread_info_reply,
+      sizeof(struct get_thread_info_request) },
     { (void(*)())dump_close_handle_request,
       (void(*)())0,
       sizeof(struct close_handle_request) },
@@ -112,6 +139,9 @@
     { (void(*)())dump_open_process_request,
       (void(*)())dump_open_process_reply,
       sizeof(struct open_process_request) },
+    { (void(*)())dump_select_request,
+      (void(*)())dump_select_reply,
+      sizeof(struct select_request) },
 };
 
 static const char * const req_names[REQ_NB_REQUESTS] =
@@ -121,9 +151,11 @@
     "terminate_process",
     "terminate_thread",
     "get_process_info",
+    "get_thread_info",
     "close_handle",
     "dup_handle",
     "open_process",
+    "select",
 };
 
 void trace_request( enum request req, void *data, int len, int fd )
diff --git a/tools/build.c b/tools/build.c
index 76d8b7e..bd7f1e9 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -1630,7 +1630,7 @@
 #endif
     fprintf( outfile, "\tmovw %%bx,%%es\n" );
 
-    fprintf( outfile, "\tmovw " PREFIX "CALLTO16_Current_fs,%%fs\n" );
+    fprintf( outfile, "\tmovw " PREFIX "SYSLEVEL_Win16CurrentTeb,%%fs\n" );
 
     /* Get the 32-bit stack pointer from the TEB */
 
@@ -1747,7 +1747,6 @@
     fprintf( outfile, "\t.byte 0x64\n\tmovw (%d),%%ss\n", STACKOFFSET + 2 );
     fprintf( outfile, "\t.byte 0x64\n\tmovw (%d),%%sp\n", STACKOFFSET );
     fprintf( outfile, "\t.byte 0x64\n\tpopl (%d)\n", STACKOFFSET );
-    fprintf( outfile, "\tmovw %%fs," PREFIX "CALLTO16_Current_fs\n" );
 
     if (reg_func)
     {
@@ -1948,12 +1947,11 @@
 
     fprintf( outfile, "do_callto16_%s:\n", profile );
 
-    /* Save the 32-bit stack and %fs */
+    /* Save the 32-bit stack */
 
     fprintf( outfile, "\t.byte 0x64\n\tpushl (%d)\n", STACKOFFSET );
     fprintf( outfile, "\tmovl %%ebp,%%ebx\n" );
     fprintf( outfile, "\tmovl %%esp,%%edx\n" );
-    fprintf( outfile, "\tmovw %%fs," PREFIX "CALLTO16_Current_fs\n" );
 
     if (reg_func)
     {
@@ -2106,7 +2104,7 @@
 #endif
     fprintf( outfile, "\tmovw %%bx,%%es\n" );
 
-    fprintf( outfile, "\tmovw " PREFIX "CALLTO16_Current_fs,%%fs\n" );
+    fprintf( outfile, "\tmovw " PREFIX "SYSLEVEL_Win16CurrentTeb,%%fs\n" );
 
     /* Restore the 32-bit stack */
 
diff --git a/tools/make_requests b/tools/make_requests
index 1cba580..f02bd43 100755
--- a/tools/make_requests
+++ b/tools/make_requests
@@ -1,4 +1,4 @@
-#! /usr/bin/perl
+#! /usr/bin/perl -w
 #
 # Build the server/trace.c and include/server/request.h files
 # from the contents of include/server.h.
@@ -26,6 +26,7 @@
 /* File generated automatically by $0; DO NOT EDIT!! */
 
 #include <stdio.h>
+#include <sys/types.h>
 #include <sys/uio.h>
 #include "server.h"
 #include "server/thread.h"
@@ -194,6 +195,7 @@
 	last if /^};$/;
         next if /^{$/;
 	s!/\*.*\*/!!g;
+	next if /^\s*$/;
 	/ *(\w+\**( +\w+\**)*) +(\w+);/ or die "Unrecognized syntax $_";
 	my $type = $1;
 	my $var = $3;
@@ -215,6 +217,7 @@
 	last if /^};$/;
         next if /^{$/;
 	s!/\*.*\*/!!g;
+	next if /^\s*$/;
 	/ *(\w+\**( +\w+\**)*) +(\w+);/ or die "Unrecognized syntax $_";
 	my $type = $1;
 	my $var = $3;
@@ -238,7 +241,6 @@
 	print TRACE "    printf( \" $var=$formats{$type}";
 	print TRACE "," if ($#_ > 0);
 	print TRACE "\", req->$var );\n";
-	$size .= "+sizeof($type)";
     }
     print TRACE "}\n";
 }
diff --git a/tools/testrun b/tools/testrun
index 499e134..6508c01 100755
--- a/tools/testrun
+++ b/tools/testrun
@@ -223,31 +223,6 @@
 		#print "skipping $exe, already done.\n";
 		next;
 	}
-
-	# check runfile if the exe is a DOS executeable or 
-	# of different architecture (win32)
-	if (open(RUNFILE,"runs/$runfile.out")) {
-		while ($xrun=<RUNFILE>) {
-			chop($xrun);
-			if ($xrun=~ /LoadModule:.*error=11$/) {
-				$flag=1;
-				last;
-			}
-			if ($xrun=~ /LoadModule:.*error=21$/) {
-				$flag=2;
-				last;
-			}
-		}
-		close(RUNFILE);
-		if ($flag==1) {
-			#print "skipping $exe, seems to be a DOS executable.\n";
-			next;
-		}
-		if ($flag==2) {
-			#print "skipping $exe, seems to be a non i386 executable.\n";
-			next;
-		}
-	}
 	# now testrun...
 	print "$exe:\n";
 	$dir = $exe;
diff --git a/win32/device.c b/win32/device.c
index 7574bb5..9ce240e 100644
--- a/win32/device.c
+++ b/win32/device.c
@@ -2,6 +2,8 @@
  * Win32 device functions
  *
  * Copyright 1998 Marcus Meissner
+ * Copyright 1998 Ulrich Weigand
+ *
  */
 
 #include <errno.h>
@@ -23,8 +25,9 @@
 #include "heap.h"
 #include "debug.h"
 #include "winioctl.h"
+#include "stackframe.h"
 
-void DEVICE_Destroy(K32OBJ *dev);
+static void DEVICE_Destroy(K32OBJ *dev);
 const K32OBJ_OPS DEVICE_Ops =
 {
     NULL,		/* signaled */
@@ -40,22 +43,240 @@
 typedef struct
 {
     K32OBJ    header;
-    int       mode;
+
+    struct VxDInfo *info;
     char     *devname;
+    int       mode;
+
 } 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;
+static BOOL32 DeviceIo_VTDAPI(DEVICE_OBJECT *dev, DWORD dwIoControlCode, 
+			      LPVOID lpvInBuffer, DWORD cbInBuffer,
+			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
+			      LPDWORD lpcbBytesReturned,
+			      LPOVERLAPPED lpOverlapped);
+
+static BOOL32 VxDCall_VMM( DWORD *retv, DWORD service, CONTEXT *context );
+
+/*
+ * VxD names are taken from the Win95 DDK
+ */
+
+struct VxDInfo
+{
+    LPCSTR  name;
+    WORD    id;
+    BOOL32  (*vxdcall)(DWORD *, DWORD, CONTEXT *);
+    BOOL32  (*deviceio)(DEVICE_OBJECT *, DWORD, LPVOID, DWORD, 
+                        LPVOID, DWORD, LPDWORD, LPOVERLAPPED);
+}   
+    VxDList[] = 
+{
+    /* Standard VxD IDs */
+    { "VMM",      0x0001, VxDCall_VMM, NULL },
+    { "DEBUG",    0x0002, NULL, NULL },
+    { "VPICD",    0x0003, NULL, NULL },
+    { "VDMAD",    0x0004, NULL, NULL },
+    { "VTD",      0x0005, NULL, NULL },
+    { "V86MMGR",  0x0006, NULL, NULL },
+    { "PAGESWAP", 0x0007, NULL, NULL },
+    { "PARITY",   0x0008, NULL, NULL },
+    { "REBOOT",   0x0009, NULL, NULL },
+    { "VDD",      0x000A, NULL, NULL },
+    { "VSD",      0x000B, NULL, NULL },
+    { "VMD",      0x000C, NULL, NULL },
+    { "VKD",      0x000D, NULL, NULL },
+    { "VCD",      0x000E, NULL, NULL },
+    { "VPD",      0x000F, NULL, NULL },
+    { "BLOCKDEV", 0x0010, NULL, NULL },
+    { "VMCPD",    0x0011, NULL, NULL },
+    { "EBIOS",    0x0012, NULL, NULL },
+    { "BIOSXLAT", 0x0013, NULL, NULL },
+    { "VNETBIOS", 0x0014, NULL, NULL },
+    { "DOSMGR",   0x0015, NULL, NULL },
+    { "WINLOAD",  0x0016, NULL, NULL },
+    { "SHELL",    0x0017, NULL, NULL },
+    { "VMPOLL",   0x0018, NULL, NULL },
+    { "VPROD",    0x0019, NULL, NULL },
+    { "DOSNET",   0x001A, NULL, NULL },
+    { "VFD",      0x001B, NULL, NULL },
+    { "VDD2",     0x001C, NULL, NULL },
+    { "WINDEBUG", 0x001D, NULL, NULL },
+    { "TSRLOAD",  0x001E, NULL, NULL },
+    { "BIOSHOOK", 0x001F, NULL, NULL },
+    { "INT13",    0x0020, NULL, NULL },
+    { "PAGEFILE", 0x0021, NULL, NULL },
+    { "SCSI",     0x0022, NULL, NULL },
+    { "MCA_POS",  0x0023, NULL, NULL },
+    { "SCSIFD",   0x0024, NULL, NULL },
+    { "VPEND",    0x0025, NULL, NULL },
+    { "VPOWERD",  0x0026, NULL, NULL },
+    { "VXDLDR",   0x0027, NULL, NULL },
+    { "NDIS",     0x0028, NULL, NULL },
+    { "BIOS_EXT", 0x0029, NULL, NULL },
+    { "VWIN32",   0x002A, NULL, NULL },
+    { "VCOMM",    0x002B, NULL, NULL },
+    { "SPOOLER",  0x002C, NULL, NULL },
+    { "WIN32S",   0x002D, NULL, NULL },
+    { "DEBUGCMD", 0x002E, NULL, NULL },
+
+    { "VNB",      0x0031, NULL, NULL },
+    { "SERVER",   0x0032, NULL, NULL },
+    { "CONFIGMG", 0x0033, NULL, NULL },
+    { "DWCFGMG",  0x0034, NULL, NULL },
+    { "SCSIPORT", 0x0035, NULL, NULL },
+    { "VFBACKUP", 0x0036, NULL, NULL },
+    { "ENABLE",   0x0037, NULL, NULL },
+    { "VCOND",    0x0038, NULL, NULL },
+
+    { "EFAX",     0x003A, NULL, NULL },
+    { "DSVXD",    0x003B, NULL, NULL },
+    { "ISAPNP",   0x003C, NULL, NULL },
+    { "BIOS",     0x003D, NULL, NULL },
+    { "WINSOCK",  0x003E, NULL, NULL },
+    { "WSOCK",    0x003E, NULL, NULL },
+    { "WSIPX",    0x003F, NULL, NULL },
+    { "IFSMgr",   0x0040, NULL, NULL },
+    { "VCDFSD",   0x0041, NULL, NULL },
+    { "MRCI2",    0x0042, NULL, NULL },
+    { "PCI",      0x0043, NULL, NULL },
+    { "PELOADER", 0x0044, NULL, NULL },
+    { "EISA",     0x0045, NULL, NULL },
+    { "DRAGCLI",  0x0046, NULL, NULL },
+    { "DRAGSRV",  0x0047, NULL, NULL },
+    { "PERF",     0x0048, NULL, NULL },
+    { "AWREDIR",  0x0049, NULL, NULL },
+
+    /* Far East support */
+    { "ETEN",     0x0060, NULL, NULL },
+    { "CHBIOS",   0x0061, NULL, NULL },
+    { "VMSGD",    0x0062, NULL, NULL },
+    { "VPPID",    0x0063, NULL, NULL },
+    { "VIME",     0x0064, NULL, NULL },
+    { "VHBIOSD",  0x0065, NULL, NULL },
+
+    /* Multimedia OEM IDs */
+    { "VTDAPI",   0x0442, NULL, DeviceIo_VTDAPI },
+
+    /* Network Device IDs */
+    { "VNetSup",  0x0480, NULL, NULL },
+    { "VRedir",   0x0481, NULL, NULL },
+    { "VBrowse",  0x0482, NULL, NULL },
+    { "VSHARE",   0x0483, NULL, NULL },
+    { "IFSMgr",   0x0484, NULL, NULL },
+    { "MEMPROBE", 0x0485, NULL, NULL },
+    { "VFAT",     0x0486, NULL, NULL },
+    { "NWLINK",   0x0487, NULL, NULL },
+    { "VNWLINK",  0x0487, NULL, NULL },
+    { "NWSUP",    0x0487, NULL, NULL },
+    { "VTDI",     0x0488, NULL, NULL },
+    { "VIP",      0x0489, NULL, NULL },
+    { "VTCP",     0x048A, NULL, NULL },
+    { "VCache",   0x048B, NULL, NULL },
+    { "VUDP",     0x048C, NULL, NULL },
+    { "VAsync",   0x048D, NULL, NULL },
+    { "NWREDIR",  0x048E, NULL, NULL },
+    { "STAT80",   0x048F, NULL, NULL },
+    { "SCSIPORT", 0x0490, NULL, NULL },
+    { "FILESEC",  0x0491, NULL, NULL },
+    { "NWSERVER", 0x0492, NULL, NULL },
+    { "SECPROV",  0x0493, NULL, NULL },
+    { "NSCL",     0x0494, NULL, NULL },
+    { "WSTCP",    0x0495, NULL, NULL },
+    { "NDIS2SUP", 0x0496, NULL, NULL },
+    { "MSODISUP", 0x0497, NULL, NULL },
+    { "Splitter", 0x0498, NULL, NULL },
+    { "PPP",      0x0499, NULL, NULL },
+    { "VDHCP",    0x049A, NULL, NULL },
+    { "VNBT",     0x049B, NULL, NULL },
+    { "LOGGER",   0x049D, NULL, NULL },
+    { "EFILTER",  0x049E, NULL, NULL },
+    { "FFILTER",  0x049F, NULL, NULL },
+    { "TFILTER",  0x04A0, NULL, NULL },
+    { "AFILTER",  0x04A1, NULL, NULL },
+    { "IRLAMP",   0x04A2, NULL, NULL },
+
+    { NULL,       0,      NULL, NULL }
+};
+
+/*
+ * VMM VxDCall service names are (mostly) taken from Stan Mitchell's
+ * "Inside the Windows 95 File System"
+ */
+
+#define N_VMM_SERVICE 41
+
+LPCSTR VMM_Service_Name[N_VMM_SERVICE] =
+{ 
+    "PageReserve",            /* 0x0000 */
+    "PageCommit",             /* 0x0001 */
+    "PageDecommit",           /* 0x0002 */
+    "PagerRegister",          /* 0x0003 */
+    "PagerQuery",             /* 0x0004 */
+    "HeapAllocate",           /* 0x0005 */
+    "ContextCreate",          /* 0x0006 */
+    "ContextDestroy",         /* 0x0007 */
+    "PageAttach",             /* 0x0008 */
+    "PageFlush",              /* 0x0009 */
+    "PageFree",               /* 0x000A */
+    "ContextSwitch",          /* 0x000B */
+    "HeapReAllocate",         /* 0x000C */
+    "PageModifyPerm",         /* 0x000D */
+    "PageQuery",              /* 0x000E */
+    "GetCurrentContext",      /* 0x000F */
+    "HeapFree",               /* 0x0010 */
+    "RegOpenKey",             /* 0x0011 */
+    "RegCreateKey",           /* 0x0012 */
+    "RegCloseKey",            /* 0x0013 */
+    "RegDeleteKey",           /* 0x0014 */
+    "RegSetValue",            /* 0x0015 */
+    "RegDeleteValue",         /* 0x0016 */
+    "RegQueryValue",          /* 0x0017 */
+    "RegEnumKey",             /* 0x0018 */
+    "RegEnumValue",           /* 0x0019 */
+    "RegQueryValueEx",        /* 0x001A */
+    "RegSetValueEx",          /* 0x001B */
+    "RegFlushKey",            /* 0x001C */
+    "RegQueryInfoKey",        /* 0x001D */
+    "GetDemandPageInfo",      /* 0x001E */
+    "BlockOnID",              /* 0x001F */
+    "SignalID",               /* 0x0020 */
+    "RegLoadKey",             /* 0x0021 */
+    "RegUnLoadKey",           /* 0x0022 */
+    "RegSaveKey",             /* 0x0023 */
+    "RegRemapPreDefKey",      /* 0x0024 */
+    "PageChangePager",        /* 0x0025 */
+    "RegQueryMultipleValues", /* 0x0026 */
+    "RegReplaceKey",          /* 0x0027 */
+    "<KERNEL32.101>"          /* 0x0028 -- What does this do??? */
+};
+
+
+
+HANDLE32 DEVICE_Open(LPCSTR filename, DWORD access) 
+{
+	DEVICE_OBJECT *dev;
+	HANDLE32 handle;
+	int i;
+
+	dev = HeapAlloc( SystemHeap, 0, sizeof(DEVICE_OBJECT) );
+	if (!dev) return INVALID_HANDLE_VALUE32;
+
 	dev->header.type = K32OBJ_DEVICE_IOCTL;
-	dev->header.refcount = 0;
+	dev->header.refcount = 1;
 	dev->mode	= access;
 	dev->devname	= HEAP_strdupA(SystemHeap,0,filename);
+	dev->info       = NULL;
+
+	for (i = 0; VxDList[i].name; i++)
+	    if (!lstrcmpi32A(VxDList[i].name, filename))
+	        break;
+	if (VxDList[i].name)
+	    dev->info = VxDList + i;
+	else
+	    FIXME(win32, "Unknown VxD %s\n", filename);
+
 
 	handle = HANDLE_Alloc( PROCESS_Current(), &(dev->header),
 			       FILE_ALL_ACCESS | GENERIC_READ |
@@ -65,9 +286,19 @@
 	return handle;
 }
 
-void
-DEVICE_Destroy(K32OBJ *dev) {
-	assert(dev->type == K32OBJ_DEVICE_IOCTL);
+static void DEVICE_Destroy(K32OBJ *obj) 
+{
+    DEVICE_OBJECT *dev = (DEVICE_OBJECT *)obj;
+    assert( obj->type == K32OBJ_DEVICE_IOCTL );
+
+    if ( dev->devname )
+    {
+        HeapFree( SystemHeap, 0, dev->devname );
+        dev->devname = NULL;
+    }
+
+    obj->type = K32OBJ_UNKNOWN;
+    HeapFree( SystemHeap, 0, dev );
 }
 
 /****************************************************************************
@@ -80,7 +311,7 @@
  * GetLastError can decypher.
  */
 BOOL32 WINAPI DeviceIoControl(HANDLE32 hDevice, DWORD dwIoControlCode, 
-			      LPVOID lpvlnBuffer, DWORD cblnBuffer,
+			      LPVOID lpvInBuffer, DWORD cbInBuffer,
 			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
 			      LPDWORD lpcbBytesReturned,
 			      LPOVERLAPPED lpOverlapped)
@@ -88,8 +319,8 @@
 	DEVICE_OBJECT	*dev = (DEVICE_OBJECT *)HANDLE_GetObjPtr(
 		PROCESS_Current(), hDevice, K32OBJ_DEVICE_IOCTL, 0 /*FIXME*/, NULL );
 
-        FIXME(win32, "(%ld,%ld,%p,%ld,%p,%ld,%p,%p), stub\n",
-		hDevice,dwIoControlCode,lpvlnBuffer,cblnBuffer,
+        TRACE(win32, "(%d,%ld,%p,%ld,%p,%ld,%p,%p)\n",
+		hDevice,dwIoControlCode,lpvInBuffer,cbInBuffer,
 		lpvOutBuffer,cbOutBuffer,lpcbBytesReturned,lpOverlapped
 	);
 
@@ -102,23 +333,15 @@
 	/* Check if this is a user defined control code for a VxD */
         if( HIWORD( dwIoControlCode ) == 0 )
         {
+	    if ( dev->info && dev->info->deviceio )
+	        return dev->info->deviceio( dev, dwIoControlCode, 
+                                            lpvInBuffer, cbInBuffer, 
+                                            lpvOutBuffer, cbOutBuffer, 
+                                            lpcbBytesReturned, lpOverlapped );
+
 	    /* FIXME: Set appropriate error */
-	    FIXME(win32," VxD device %s msg\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, "Unimplemented control %ld for VxD device %s\n", 
+	                  dwIoControlCode, dev->devname );
 	}
 	else
 	{
@@ -168,3 +391,297 @@
 	}
    	return FALSE;
 }
+ 
+/***********************************************************************
+ *           DeviceIo_VTDAPI
+ */
+static BOOL32 DeviceIo_VTDAPI(DEVICE_OBJECT *dev, DWORD dwIoControlCode, 
+			      LPVOID lpvInBuffer, DWORD cbInBuffer,
+			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
+			      LPDWORD lpcbBytesReturned,
+			      LPOVERLAPPED lpOverlapped)
+{
+    BOOL32 retv = TRUE;
+
+    switch (dwIoControlCode)
+    {
+    case 5:
+        if (lpvOutBuffer && (cbOutBuffer>=4))
+            *(DWORD*)lpvOutBuffer = timeGetTime();
+
+        if (lpcbBytesReturned)
+            *lpcbBytesReturned = 4;
+
+        break;
+
+    default:
+        FIXME(win32, "Control %ld not implemented\n", dwIoControlCode);
+        retv = FALSE;
+        break;
+    }
+
+    return retv;
+}
+
+
+
+
+
+/***********************************************************************
+ *           VxDCall                   (KERNEL32.[1-9])
+ */
+static void VxDCall( CONTEXT *context, int nArgs )
+{
+    DWORD retv, service;
+    int i, ok = FALSE;
+
+    /* Pop return address to caller */
+    EIP_reg(context) = STACK32_POP(context);
+
+    /* Pop requested service ID */
+    service = STACK32_POP(context);
+
+    TRACE(win32, "(%08lx, ...)\n", service);
+
+    for (i = 0; VxDList[i].name; i++)
+        if (VxDList[i].id == HIWORD(service))
+            break;
+
+    if (!VxDList[i].name)
+        FIXME(win32, "Unknown VxD (%08lx)\n", service);
+    else if (!VxDList[i].vxdcall)
+        FIXME(win32, "Unimplemented VxD (%08lx)\n", service);
+    else
+        ok = VxDList[i].vxdcall(&retv, service, context);
+
+    /* If unimplemented, trust the caller to have called the
+       version with the correct number of arguments */
+    if (!ok)
+    {
+        ESP_reg(context) += 4 * nArgs;
+        retv = 0xffffffff;  /* FIXME */
+    }
+
+    /* Push return address back onto stack */
+    STACK32_PUSH(context, EIP_reg(context));
+
+    /* Return to caller */
+    EAX_reg(context) = retv;
+}
+
+REGS_ENTRYPOINT(VxDCall0) { VxDCall( context, 0 ); }
+REGS_ENTRYPOINT(VxDCall1) { VxDCall( context, 1 ); }
+REGS_ENTRYPOINT(VxDCall2) { VxDCall( context, 2 ); }
+REGS_ENTRYPOINT(VxDCall3) { VxDCall( context, 3 ); }
+REGS_ENTRYPOINT(VxDCall4) { VxDCall( context, 4 ); }
+REGS_ENTRYPOINT(VxDCall5) { VxDCall( context, 5 ); }
+REGS_ENTRYPOINT(VxDCall6) { VxDCall( context, 6 ); }
+REGS_ENTRYPOINT(VxDCall7) { VxDCall( context, 7 ); }
+REGS_ENTRYPOINT(VxDCall8) { VxDCall( context, 8 ); }
+
+/***********************************************************************
+ *           VxDCall_VMM
+ */
+BOOL32 VxDCall_VMM( DWORD *retv, DWORD service, CONTEXT *context )
+{
+    BOOL32 ok = TRUE;
+
+    switch ( LOWORD(service) )
+    {
+    case 0x0011:  /* RegOpenKey */
+    {
+        HKEY    hkey       = (HKEY)   STACK32_POP( context );
+        LPCSTR  lpszSubKey = (LPCSTR) STACK32_POP( context );
+        LPHKEY  retkey     = (LPHKEY) STACK32_POP( context );
+        *retv = RegOpenKey32A( hkey, lpszSubKey, retkey );
+    }
+    break;
+
+    case 0x0012:  /* RegCreateKey */
+    {
+        HKEY    hkey       = (HKEY)   STACK32_POP( context );
+        LPCSTR  lpszSubKey = (LPCSTR) STACK32_POP( context );
+        LPHKEY  retkey     = (LPHKEY) STACK32_POP( context );
+        *retv = RegCreateKey32A( hkey, lpszSubKey, retkey );
+    }
+    break;
+
+    case 0x0013:  /* RegCloseKey */
+    {
+        HKEY    hkey       = (HKEY)   STACK32_POP( context );
+        *retv = RegCloseKey( hkey );
+    }
+    break;
+
+    case 0x0014:  /* RegDeleteKey */
+    {
+        HKEY    hkey       = (HKEY)   STACK32_POP( context );
+        LPCSTR  lpszSubKey = (LPCSTR) STACK32_POP( context );
+        *retv = RegDeleteKey32A( hkey, lpszSubKey );
+    }
+    break;
+
+    case 0x0015:  /* RegSetValue */
+    {
+        HKEY    hkey       = (HKEY)   STACK32_POP( context );
+        LPCSTR  lpszSubKey = (LPCSTR) STACK32_POP( context );
+        DWORD   dwType     = (DWORD)  STACK32_POP( context );
+        LPCSTR  lpszData   = (LPCSTR) STACK32_POP( context );
+        DWORD   cbData     = (DWORD)  STACK32_POP( context );
+        *retv = RegSetValue32A( hkey, lpszSubKey, dwType, lpszData, cbData );
+    }
+    break;
+
+    case 0x0016:  /* RegDeleteValue */
+    {
+        HKEY    hkey       = (HKEY)   STACK32_POP( context );
+        LPSTR   lpszValue  = (LPSTR)  STACK32_POP( context );
+        *retv = RegDeleteValue32A( hkey, lpszValue );
+    }
+    break;
+
+    case 0x0017:  /* RegQueryValue */
+    {
+        HKEY    hkey       = (HKEY)   STACK32_POP( context );
+        LPSTR   lpszSubKey = (LPSTR)  STACK32_POP( context );
+        LPSTR   lpszData   = (LPSTR)  STACK32_POP( context );
+        LPDWORD lpcbData   = (LPDWORD)STACK32_POP( context );
+        *retv = RegQueryValue32A( hkey, lpszSubKey, lpszData, lpcbData );
+    }
+    break;
+
+    case 0x0018:  /* RegEnumKey */
+    {
+        HKEY    hkey       = (HKEY)   STACK32_POP( context );
+        DWORD   iSubkey    = (DWORD)  STACK32_POP( context );
+        LPSTR   lpszName   = (LPSTR)  STACK32_POP( context );
+        DWORD   lpcchName  = (DWORD)  STACK32_POP( context );
+        *retv = RegEnumKey32A( hkey, iSubkey, lpszName, lpcchName );
+    }
+    break;
+
+    case 0x0019:  /* RegEnumValue */
+    {
+        HKEY    hkey       = (HKEY)   STACK32_POP( context );
+        DWORD   iValue     = (DWORD)  STACK32_POP( context );
+        LPSTR   lpszValue  = (LPSTR)  STACK32_POP( context );
+        LPDWORD lpcchValue = (LPDWORD)STACK32_POP( context );
+        LPDWORD lpReserved = (LPDWORD)STACK32_POP( context );
+        LPDWORD lpdwType   = (LPDWORD)STACK32_POP( context );
+        LPBYTE  lpbData    = (LPBYTE) STACK32_POP( context );
+        LPDWORD lpcbData   = (LPDWORD)STACK32_POP( context );
+        *retv = RegEnumValue32A( hkey, iValue, lpszValue, lpcchValue, 
+                                 lpReserved, lpdwType, lpbData, lpcbData );
+    }
+    break;
+
+    case 0x001A:  /* RegQueryValueEx */
+    {
+        HKEY    hkey       = (HKEY)   STACK32_POP( context );
+        LPSTR   lpszValue  = (LPSTR)  STACK32_POP( context );
+        LPDWORD lpReserved = (LPDWORD)STACK32_POP( context );
+        LPDWORD lpdwType   = (LPDWORD)STACK32_POP( context );
+        LPBYTE  lpbData    = (LPBYTE) STACK32_POP( context );
+        LPDWORD lpcbData   = (LPDWORD)STACK32_POP( context );
+        *retv = RegQueryValueEx32A( hkey, lpszValue, lpReserved, 
+                                    lpdwType, lpbData, lpcbData );
+    }
+    break;
+
+    case 0x001B:  /* RegSetValueEx */
+    {
+        HKEY    hkey       = (HKEY)   STACK32_POP( context );
+        LPSTR   lpszValue  = (LPSTR)  STACK32_POP( context );
+        DWORD   dwReserved = (DWORD)  STACK32_POP( context );
+        DWORD   dwType     = (DWORD)  STACK32_POP( context );
+        LPBYTE  lpbData    = (LPBYTE) STACK32_POP( context );
+        DWORD   cbData     = (DWORD)STACK32_POP( context );
+        *retv = RegSetValueEx32A( hkey, lpszValue, dwReserved, 
+                                  dwType, lpbData, cbData );
+    }
+    break;
+
+    case 0x001C:  /* RegFlushKey */
+    {
+        HKEY    hkey       = (HKEY)   STACK32_POP( context );
+        *retv = RegFlushKey( hkey );
+    }
+    break;
+
+    case 0x001D:  /* RegQueryInfoKey */
+    {
+        /* NOTE: This VxDCall takes only a subset of the parameters that the
+                 corresponding Win32 API call does. The implementation in Win95
+                 ADVAPI32 sets all output parameters not mentioned here to zero. */
+
+        HKEY    hkey       = (HKEY)   STACK32_POP( context );
+        LPDWORD lpcSubKeys = (LPDWORD)STACK32_POP( context );
+        LPDWORD lpcchMaxSubKey 
+                           = (LPDWORD)STACK32_POP( context );
+        LPDWORD lpcValues  = (LPDWORD)STACK32_POP( context );
+        LPDWORD lpcchMaxValueName 
+                           = (LPDWORD)STACK32_POP( context );
+        LPDWORD lpcchMaxValueData 
+                           = (LPDWORD)STACK32_POP( context );
+        *retv = RegQueryInfoKey32A( hkey, NULL, NULL, NULL, lpcSubKeys, lpcchMaxSubKey,
+                                    NULL, lpcValues, lpcchMaxValueName, lpcchMaxValueData,
+                                    NULL, NULL );
+    }
+    break;
+
+    case 0x0021:  /* RegLoadKey */
+    {
+        HKEY    hkey       = (HKEY)   STACK32_POP( context );
+        LPCSTR  lpszSubKey = (LPCSTR) STACK32_POP( context );
+        LPCSTR  lpszFile   = (LPCSTR) STACK32_POP( context );
+        *retv = RegLoadKey32A( hkey, lpszSubKey, lpszFile );
+    }
+    break;
+
+    case 0x0022:  /* RegUnLoadKey */
+    {
+        HKEY    hkey       = (HKEY)   STACK32_POP( context );
+        LPCSTR  lpszSubKey = (LPCSTR) STACK32_POP( context );
+        *retv = RegUnLoadKey32A( hkey, lpszSubKey );
+    }
+    break;
+
+    case 0x0023:  /* RegSaveKey */
+    {
+        HKEY    hkey       = (HKEY)   STACK32_POP( context );
+        LPCSTR  lpszFile   = (LPCSTR) STACK32_POP( context );
+        LPSECURITY_ATTRIBUTES sa = 
+               (LPSECURITY_ATTRIBUTES)STACK32_POP( context );
+        *retv = RegSaveKey32A( hkey, lpszFile, sa );
+    }
+    break;
+
+#if 0 /* Functions are not yet implemented in misc/registry.c */
+    case 0x0024:  /* RegRemapPreDefKey */
+    case 0x0026:  /* RegQueryMultipleValues */
+#endif
+
+    case 0x0027:  /* RegReplaceKey */
+    {
+        HKEY    hkey       = (HKEY)   STACK32_POP( context );
+        LPCSTR  lpszSubKey = (LPCSTR) STACK32_POP( context );
+        LPCSTR  lpszNewFile= (LPCSTR) STACK32_POP( context );
+        LPCSTR  lpszOldFile= (LPCSTR) STACK32_POP( context );
+        *retv = RegReplaceKey32A( hkey, lpszSubKey, lpszNewFile, lpszOldFile );
+    }
+    break;
+
+    default:
+        if (LOWORD(service) < N_VMM_SERVICE)
+            FIXME(win32, "Unimplemented service %s (%08lx)\n",
+                          VMM_Service_Name[LOWORD(service)], service);
+        else
+            FIXME(win32, "Unknown service %08lx\n", service);
+
+        ok = FALSE;
+        break;
+    }
+
+    return ok;
+}
+
diff --git a/win32/file.c b/win32/file.c
index fd1de18..a595d86 100644
--- a/win32/file.c
+++ b/win32/file.c
@@ -138,16 +138,15 @@
     if(template)
         FIXME(file, "template handles not supported.\n");
 
+    if(!filename)
+      return HFILE_ERROR32;
     /* If the name starts with '\\?\' or '\\.\', ignore the first 4 chars.
      */
     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))
 	{
diff --git a/win32/kernel32.c b/win32/kernel32.c
index 08eca15..1be5f93 100644
--- a/win32/kernel32.c
+++ b/win32/kernel32.c
@@ -18,6 +18,7 @@
 #include "selectors.h"
 #include "task.h"
 #include "win.h"
+#include "file.h"
 #include "debug.h"
 #include "flatthunk.h"
 #include "syslevel.h"
@@ -252,6 +253,7 @@
             (LPBYTE)ESP_reg(context)+4, argsize );
 
     EAX_reg(context) = Callbacks->CallRegisterShortProc( &context16, argsize );
+    EDX_reg(context) = HIWORD(EAX_reg(context));
 }
 
 
@@ -378,6 +380,7 @@
 	}
 
     EAX_reg(context) = Callbacks->CallRegisterShortProc( &context16, argsize );
+    EDX_reg(context) = HIWORD(EAX_reg(context));
 }
 
 /**********************************************************************
@@ -1066,7 +1069,7 @@
 	HFILE16 hf16	/* [in] open file, if filename is NULL */
 ) {
 	IMAGE_DOS_HEADER	mzh;
-	HFILE32			hf=hf16;
+        HFILE32                 hf=HFILE16_TO_HFILE32(hf16);
 	OFSTRUCT		ofs;
 	DWORD			xmagic;
 
@@ -1205,10 +1208,3 @@
    }
 }
 
-/***********************************************************************
- *           VxDCall			(KERNEL32.1-8)
- */
-DWORD WINAPI VxDCall(DWORD x) {
-	FIXME(vxd,"(0x%08lx), stub!\n",x);
-	return 0xffffffff;
-}
diff --git a/win32/newfns.c b/win32/newfns.c
index 693c5f7..ced6b06 100644
--- a/win32/newfns.c
+++ b/win32/newfns.c
@@ -361,32 +361,6 @@
 }
 
 /******************************************************************************
- * SleepEx [KERNEL32.680]
- *
- * BUGS
- *   Unimplemented
- */
-DWORD WINAPI SleepEx(DWORD x1,BOOL32 x2)
-{
-  FIXME(win32,":(%d,%ld): stub\n",x1,x2);
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
-
-/******************************************************************************
- * TerminateProcess [KERNEL32.684]
- * 
- * BUGS
- *   Unimplemented
- */
-int WINAPI TerminateProcess(HANDLE32 h, int ret)
-{
-  FIXME(win32,":(%p,%d): stub\n",h,ret);
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-	return FALSE;
-}
-
-/******************************************************************************
  * OpenDesktop32A [USER32.408]
  *
  * NOTES
diff --git a/win32/ordinals.c b/win32/ordinals.c
index a9699cf..5b7427a 100644
--- a/win32/ordinals.c
+++ b/win32/ordinals.c
@@ -129,4 +129,3 @@
 	FIXME(win32,"(0x%08lx): stub\n",x);
 	return 1;
 }
-
diff --git a/win32/process.c b/win32/process.c
index 3a85430..2e06bb4 100644
--- a/win32/process.c
+++ b/win32/process.c
@@ -59,50 +59,6 @@
 }
 
 /**********************************************************************
- *  CreateProcess32A [KERNEL32.171]
- */
-BOOL32 WINAPI CreateProcess32A(
-	LPCSTR appname,LPSTR cmdline,LPSECURITY_ATTRIBUTES processattributes,
-        LPSECURITY_ATTRIBUTES threadattributes,BOOL32 inherithandles,
-	DWORD creationflags,LPVOID env,LPCSTR curdir,
-	LPSTARTUPINFO32A startupinfo,LPPROCESS_INFORMATION processinfo
-) {
-	HINSTANCE16 hInst = 0;
-	if (processinfo) memset(processinfo, '\0', sizeof(*processinfo));
-
-	FIXME(win32,"(%s,%s,%p,%p,%d,%08lx,%p,%s,%p,%p): calling WinExec32\n",
-		appname,cmdline,processattributes,threadattributes,
-		inherithandles,creationflags,env,curdir,startupinfo,processinfo);
-
-	hInst = WinExec32(cmdline,TRUE);
-
-        return hInst >= 32;
-#if 0
-	/* make from lcc uses system as fallback if CreateProcess returns
-	   FALSE, so return false */
-	return FALSE;
-#endif
-}
-
-/**********************************************************************
- *  CreateProcess32W [KERNEL32.172]
- */
-BOOL32 WINAPI CreateProcess32W(
-	LPCWSTR appname,LPWSTR cmdline,LPSECURITY_ATTRIBUTES processattributes,
-        LPSECURITY_ATTRIBUTES threadattributes,BOOL32 inherithandles,
-	DWORD creationflags,LPVOID env,LPCWSTR curdir,
-	LPSTARTUPINFO32W startupinfo,LPPROCESS_INFORMATION processinfo)
-{
-    FIXME(win32,"(%p,%s,%p,%p,%d,%08lx,%p,%s,%p,%p): stub\n",
-            appname,debugstr_w(cmdline),processattributes,threadattributes,
-            inherithandles,creationflags,env,debugstr_w(curdir),startupinfo,
-	    processinfo );
-    /* make from lcc uses system as fallback if CreateProcess returns
-       FALSE, so return false */
-    return FALSE;
-}
-
-/**********************************************************************
  *  ContinueDebugEvent [KERNEL32.146]
  */
 BOOL32 WINAPI ContinueDebugEvent(DWORD pid,DWORD tid,DWORD contstatus) {
diff --git a/win32/time.c b/win32/time.c
index 9dc1e4c..fc82034 100644
--- a/win32/time.c
+++ b/win32/time.c
@@ -133,16 +133,6 @@
 
 
 /***********************************************************************
- *              Sleep  (KERNEL32.523)
- */
-VOID WINAPI Sleep(DWORD cMilliseconds)
-{
-    if(cMilliseconds == INFINITE32)
-        while(1) sleep(1000); /* Spin forever */
-    usleep(cMilliseconds*1000);
-}
-
-/***********************************************************************
  *              GetSystemTimeAsFileTime  (KERNEL32)
  */
 VOID WINAPI GetSystemTimeAsFileTime(LPFILETIME systemtimeAsfiletime) {
diff --git a/windows/keyboard.c b/windows/keyboard.c
index ac4b542..667f2d5 100644
--- a/windows/keyboard.c
+++ b/windows/keyboard.c
@@ -277,13 +277,13 @@
                 keysym = TSXLookupKeysym(&e2, i);
 		switch (keysym)
 		{
-		case ';': case ':':   vkey = VK_OEM_1; break;
-		case '/': case '?':   vkey = VK_OEM_2; break;
-		case '`': case '~':   vkey = VK_OEM_3; break;
+		case ';':             vkey = VK_OEM_1; break;
+		case '/':             vkey = VK_OEM_2; break;
+		case '`':             vkey = VK_OEM_3; break;
 		case '[':             vkey = VK_OEM_4; break;
 		case '\\':            vkey = VK_OEM_5; break;
 		case ']':             vkey = VK_OEM_6; break;
-		case '\'': case '\"': vkey = VK_OEM_7; break;
+		case '\'':            vkey = VK_OEM_7; break;
 		case ',':             vkey = VK_OEM_COMMA; break;
 		case '.':             vkey = VK_OEM_PERIOD; break;
 		case '-':             vkey = VK_OEM_MINUS; break;
@@ -391,13 +391,19 @@
     WORD vkey = 0;
     KEYLP keylp;
     static BOOL32 force_extended = FALSE; /* hack for AltGr translation */
-
-    int ascii_chars = TSXLookupString(event, Str, 1, &keysym, &cs);
+    
+    int ascii_chars;
 
     INT32 event_x = pWnd->rectWindow.left + event->x;
     INT32 event_y = pWnd->rectWindow.top + event->y;
     DWORD event_time = event->time - MSG_WineStartTicks;
 
+    /* this allows support for dead keys */
+    if ((event->keycode >> 8) == 0x10)
+	event->keycode=(event->keycode & 0xff);
+
+    ascii_chars = TSXLookupString(event, Str, 1, &keysym, &cs);
+
     TRACE(key, "EVENT_key : state = %X\n", event->state);
     if (keysym == XK_Mode_switch)
 	{
@@ -832,6 +838,14 @@
 
 
 /**********************************************************************
+ *           ScreenSwitchEnable      (KEYBOARD.100)
+ */
+VOID WINAPI ScreenSwitchEnable(WORD unused)
+{
+    FIXME(keyboard,"(%04x): stub\n",unused);
+}
+
+/**********************************************************************
  *           OemKeyScan      (KEYBOARD.128)(USER32.401)
  */
 DWORD WINAPI OemKeyScan(WORD wOemChar)
diff --git a/windows/mdi.c b/windows/mdi.c
index 3478cb4..dadc4c8 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -247,6 +247,23 @@
     return 0;
 }
 
+/**********************************************************************
+ *            MDIRefreshMenu
+ */
+static LRESULT MDIRefreshMenu( HWND32 hwnd, HMENU32 hmenuFrame,
+                           HMENU32 hmenuWindow)
+{
+    HWND32 hwndFrame = GetParent32(hwnd);
+    HMENU32 oldFrameMenu = GetMenu32(hwndFrame);
+
+    TRACE(mdi, "%04x %04x %04x\n",
+                hwnd, hmenuFrame, hmenuWindow);
+
+    FIXME(mdi,"partially function stub");
+
+    return oldFrameMenu;
+}
+
 
 /* ------------------ MDI child window functions ---------------------- */
 
@@ -983,6 +1000,9 @@
       case WM_MDISETMENU:
           return MDISetMenu( hwnd, (HMENU32)wParam, (HMENU32)lParam );
 	
+      case WM_MDIREFRESHMENU:
+          return MDIRefreshMenu( hwnd, (HMENU32)wParam, (HMENU32)lParam );
+
       case WM_MDITILE:
 	ci->mdiFlags |= MDIF_NEEDUPDATE;
 	ShowScrollBar32(hwnd,SB_BOTH,FALSE);
diff --git a/windows/message.c b/windows/message.c
index 4e8c632..972e6ef 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -449,7 +449,8 @@
     joySendMessages();
 
     /* If the queue is empty, attempt to fill it */
-    if (!sysMsgQueue->msgCount && TSXPending(display))
+    if (!sysMsgQueue->msgCount && THREAD_IsWin16( THREAD_Current() )
+                               && TSXPending(display))
         EVENT_WaitNetEvent( FALSE, FALSE );
 
     for (i = kbd_msg = 0; i < sysMsgQueue->msgCount; i++, pos++)
@@ -634,7 +635,10 @@
       if (!(queue->wakeBits & QS_SMRESULT))
       {
         queue->changeBits &= ~QS_SMRESULT;
-        DirectedYield( destQ->hTask );
+        if (THREAD_IsWin16( THREAD_Current() ))
+          DirectedYield( destQ->hTask );
+        else
+          QUEUE_Signal( destQ->hTask );
         QUEUE_WaitBits( QS_SMRESULT );
 	TRACE(sendmsg,"\tsm: have result!\n");
       }
@@ -684,7 +688,7 @@
       }
 
       if(!(senderQ->wakeBits & QS_SMRESULT) ) break;
-      OldYield();
+      if (THREAD_IsWin16(THREAD_Current())) OldYield();
     } 
     if( !senderQ ) { TRACE(msg,"\trpm: done\n"); return; }
 
@@ -696,7 +700,7 @@
     queue->InSendMessageHandle = 0;
 
     QUEUE_SetWakeBit( senderQ, QS_SMRESULT );
-    DirectedYield( queue->hSendingTask );
+    if (THREAD_IsWin16(THREAD_Current())) DirectedYield( queue->hSendingTask );
 }
 
 
@@ -729,6 +733,9 @@
 
     if (IsTaskLocked()) flags |= PM_NOYIELD;
 
+    /* Never yield on Win32 threads */
+    if (!THREAD_IsWin16(THREAD_Current())) flags |= PM_NOYIELD;
+
     while(1)
     {    
 	hQueue   = GetTaskQueue(0);
diff --git a/windows/msgbox.c b/windows/msgbox.c
index 441ea4a..831865f 100644
--- a/windows/msgbox.c
+++ b/windows/msgbox.c
@@ -320,7 +320,7 @@
 {
     WARN(dialog,"AppExit\n");
     MessageBox32A( 0, str, NULL, MB_SYSTEMMODAL | MB_OK );
-    TASK_KillCurrentTask(0);
+    ExitProcess(0);
 }
 
 
@@ -331,7 +331,7 @@
 {
     WARN(dialog,"AppExit\n");
     MessageBox32W( 0, str, NULL, MB_SYSTEMMODAL | MB_OK );
-    TASK_KillCurrentTask(0);
+    ExitProcess(0);
 }
 
 
diff --git a/windows/queue.c b/windows/queue.c
index 712dea1..8ab1c80 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -217,6 +217,59 @@
     return sysMsgQueue;
 }
 
+/***********************************************************************
+ *           QUEUE_Signal
+ */
+void QUEUE_Signal( HTASK16 hTask )
+{
+    PDB32 *pdb;
+    THREAD_ENTRY *entry;
+    int wakeup = FALSE;
+
+    TDB *pTask = (TDB *)GlobalLock16( hTask );
+    if ( !pTask ) return;
+
+    TRACE(msg, "calling SYNC_MsgWakeUp\n");
+
+    /* Wake up thread waiting for message */
+    /* NOTE: This should really wake up *the* thread that owns
+             the queue. Since we dont't have thread-local message
+             queues yet, we wake up all waiting threads ... */
+    SYSTEM_LOCK();
+    pdb = pTask->thdb->process;
+    entry = pdb? pdb->thread_list->next : NULL;
+
+    if (entry)
+        for (;;)
+        {
+            if (entry->thread->wait_struct.wait_msg)
+            {
+                SYNC_MsgWakeUp( entry->thread );
+                wakeup = TRUE;
+            }
+            if (entry == pdb->thread_list) break;
+            entry = entry->next;
+        }
+    SYSTEM_UNLOCK();
+
+    if ( !wakeup && THREAD_IsWin16( THREAD_Current() ) )
+        PostEvent( hTask );
+}
+
+/***********************************************************************
+ *           QUEUE_Wait
+ */
+void QUEUE_Wait( void )
+{
+    if ( THREAD_IsWin16( THREAD_Current() ) )
+        WaitEvent( 0 );
+    else
+    {
+        TRACE(msg, "current task is 32-bit, calling SYNC_DoWait\n");
+        SYNC_DoWait( 0, NULL, FALSE, INFINITE32, FALSE, TRUE );
+    }
+}
+
 
 /***********************************************************************
  *           QUEUE_SetWakeBit
@@ -235,28 +288,7 @@
     if (queue->wakeMask & bit)
     {
         queue->wakeMask = 0;
-        PostEvent( queue->hTask );
-
-        /* Wake up thread waiting for message */
-        /* NOTE: This should really wake up *the* thread that owns
-                 the queue. Since we dont't have thread-local message
-                 queues yet, we wake up all waiting threads ... */
-        SYSTEM_LOCK();
-        {
-            TDB *pTask = (TDB *)GlobalLock16( queue->hTask );
-            PDB32 *pdb = pTask? pTask->thdb->process : NULL;
-            THREAD_ENTRY *entry = pdb? pdb->thread_list->next : NULL;
-
-            if (entry)
-                for (;;)
-                {
-                    if (entry->thread->wait_struct.wait_msg)
-                        SYNC_MsgWakeUp( entry->thread );
-                    if (entry == pdb->thread_list) break;
-                    entry = entry->next;
-                }
-        }
-        SYSTEM_UNLOCK();
+        QUEUE_Signal( queue->hTask );
     }
 }
 
@@ -306,7 +338,7 @@
 	
 	TRACE(msg,"%04x) wakeMask is %04x, waiting\n", queue->self, queue->wakeMask);
 
-        WaitEvent( 0 );
+        QUEUE_Wait();
     }
 }
 
diff --git a/windows/win.c b/windows/win.c
index 1b09c8a..456f215 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -29,6 +29,7 @@
 #include "clipboard.h"
 #include "winproc.h"
 #include "thread.h"
+#include "process.h"
 #include "debug.h"
 #include "winerror.h"
 
@@ -291,7 +292,6 @@
     PROPERTY_RemoveWindowProps( wndPtr );
 
     wndPtr->dwMagic = 0;  /* Mark it as invalid */
-    wndPtr->hwndSelf = 0;
 
     if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
     {
@@ -326,10 +326,9 @@
        if (wndPtr->wIDmenu) DestroyMenu32( (HMENU32)wndPtr->wIDmenu );
     if (wndPtr->hSysMenu) DestroyMenu32( wndPtr->hSysMenu );
     if (wndPtr->window) EVENT_DestroyWindow( wndPtr );
-    if (wndPtr->class->style & CS_OWNDC) DCE_FreeWindowDCE( wndPtr );
-
+    DCE_FreeWindowDCE( wndPtr );    /* Always do this to catch orphaned DCs */ 
     WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW );
-
+    wndPtr->hwndSelf = 0;
     wndPtr->class->cWindows--;
     wndPtr->class = NULL;
     pWnd = wndPtr->next;
@@ -493,13 +492,33 @@
 
     /* Fix the coordinates */
 
-    if (cs->x == CW_USEDEFAULT32) cs->x = cs->y = 0;
+    if (cs->x == CW_USEDEFAULT32) 
+    {
+        PDB32 *pdb = PROCESS_Current();
+        if (   !(cs->style & (WS_CHILD | WS_POPUP))
+            &&  (pdb->env_db->startup_info->dwFlags & STARTF_USEPOSITION) )
+        {
+            cs->x = pdb->env_db->startup_info->dwX;
+            cs->y = pdb->env_db->startup_info->dwY;
+        }
+        else
+        {
+            cs->x = 0;
+            cs->y = 0;
+        }
+    }
     if (cs->cx == CW_USEDEFAULT32)
     {
-/*        if (!(cs->style & (WS_CHILD | WS_POPUP))) cs->cx = cs->cy = 0;
-        else */
+        PDB32 *pdb = PROCESS_Current();
+        if (   !(cs->style & (WS_CHILD | WS_POPUP))
+            &&  (pdb->env_db->startup_info->dwFlags & STARTF_USESIZE) )
         {
-            cs->cx = 600;
+            cs->cx = pdb->env_db->startup_info->dwXSize;
+            cs->cy = pdb->env_db->startup_info->dwYSize;
+        }
+        else
+        {
+            cs->cx = 600; /* FIXME */
             cs->cy = 400;
         }
     }
@@ -2274,11 +2293,13 @@
         /* Make sure that the window still exists */
         if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
         /* Build children list first */
-        if (!(childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL )))
-            return FALSE;
-        if (!func( (*ppWnd)->hwndSelf, lParam )) return FALSE;
-        ret = WIN_EnumChildWindows( childList, func, lParam );
-        HeapFree( SystemHeap, 0, childList );
+        childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL );
+        ret = func( (*ppWnd)->hwndSelf, lParam );
+        if (childList)
+        {
+            if (ret) ret = WIN_EnumChildWindows( childList, func, lParam );
+            HeapFree( SystemHeap, 0, childList );
+        }
         if (!ret) return FALSE;
     }
     return TRUE;
diff --git a/windows/winpos.c b/windows/winpos.c
index 8bec519..74af90a 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -53,6 +53,7 @@
 
 static HWND32 hwndActive      = 0;  /* Currently active window */
 static HWND32 hwndPrevActive  = 0;  /* Previously active window */
+static HWND32 hGlobalShellWindow=0; /*the shell*/
 
 static LPCSTR atomInternalPos;
 
@@ -702,9 +703,10 @@
  *         SetShellWindow32    (USER32.504)
  */
 HWND32 WINAPI SetShellWindow32(HWND32 hwndshell)
-{
-    FIXME(win, "(%08x): empty stub\n",hwndshell );
-    return 0;
+{   WARN(win, "(hWnd=%08x) semi stub\n",hwndshell );
+
+    hGlobalShellWindow = hwndshell;
+    return hGlobalShellWindow;
 }
 
 
@@ -712,9 +714,9 @@
  *         GetShellWindow32    (USER32.287)
  */
 HWND32 WINAPI GetShellWindow32(void)
-{
-    FIXME(win, "(void): empty stub\n" );
-    return 0;
+{   WARN(win, "(hWnd=%x) semi stub\n",hGlobalShellWindow );
+
+    return hGlobalShellWindow;
 }
 
 
diff --git a/windows/winproc.c b/windows/winproc.c
index f62f86f..bb6ff92 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -730,6 +730,8 @@
         *plparam = (LPARAM)HeapAlloc( SystemHeap, 0, sizeof(BOOL32) );
         return 1;
     case WM_MDISETMENU:
+        if(wParam16==TRUE)
+           *pmsg32=WM_MDIREFRESHMENU;
         *pwparam32 = (WPARAM32)(HMENU32)LOWORD(*plparam);
         *plparam   = (LPARAM)(HMENU32)HIWORD(*plparam);
         return 0;