Release 980927

Sun Sep 27 14:25:38 1998  Petter Reinholdtsen <pere@td.org.uit.no>

	* [files/drive.c]
	Make sure GetDriveType32A() handles param NULL.  Added some
	doc on function.

Sun Sep 27 14:07:26 1998  Huw D M Davies <daviesh@abacus.physics.ox.ac.uk>

	* [controls/edit.c] [windows/win.c]
	Don't call SetWindowLong() in EDIT_WM_NCREATE.
	Fix SetWindowLong(GWL_[EX]STYLE) to work for 16bit windows. Remove
	UpdateWindow() call. 

Sun Sep 27 13:41:22 1998  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [scheduler/*.c] [server/event.c] [server/mutex.c]
	  [server/semaphore.c]
	Implemented server-side synchronisation objects.

Sun Sep 27 01:13:35 1998  Alex Priem <alexp@sci.kun.nl>

	* [dlls/comctl32/treeview.c] [include/treeview.h] [include/comctl.h]
	Treeview implementation.

	* [dlls/comctl32/trackbar.c] [include/trackbar.h] 
	Trackbar implementation.

Sat Sep 26 20:49:13 1998  Ulrich Weigand <weigand@informatik.uni-erlangen.de>

	* [if1632/thunk.c] [tools/build.c] [win32/kernel32.c]
	Bugfix: several problems with flat thunks fixed.

	* [memory/selector.c]
	Bugfix: IsBad...Ptr16 didn't work for limit_in_pages segments.

	* [scheduler/thread.c]
	Bugfix: CreateThread: Allow id parameter == NULL.

	* [objects/gdiobj.c]
	Bugfix: IsGDIObject: Return correct object type for stock objects.

	* [msdos/dpmi.c]
	Bugfix: fixed typo in INT_DoRealModeInt.

	* [msdos/int21.c]
	Bugfix: int21 READ *must* use WIN16_hread, not _hread16.

	* [if1632/kernel.spec] [if1632/dummy.c] [if1632/thunk.c]
	  [loader/ne/module.c] [scheduler/event.c] [scheduler/synchro.c]
	  [scheduler/thread.c] [win32/kernel32.c] [win32/ordinals.c]
	Added names/stubs for all undocumented KERNEL routines (Win95).
	Added the following undoc. 16-bit equivalents to Win32 routines:
	KERNEL.441-443,449-453,456-462,471-476,479-486,488.
	Added stubs for some other KERNEL routines.

	* [memory/heap.c] [memory/global.c] [include/global.h]
	Implemented Local32... 32-bit local heap routines (KERNEL.208-215, 229).

	* [miscemu/instr.c] [loader/module.c] [include/module.h]
	Implemented __GP fault handling and HasGPHandler (KERNEL.338).

	* [misc/error.c]
	Implemented LogParamErrorRegs (KERNEL.327).

	* [loader/task.c] [include/windows.h]
	Implemented GetCodeInfo (KERNEL.104).

	* [loader/task.c] [scheduler/thread.c] [include/thread.h]
	Implemented [GS]etThreadQueue and [GS]etFastQueue (KERNEL.463/4, 624/5).

	* [if1632/gdi.spec] [objects/dc.c] [objects/dib.c]
	  [objects/bitmap.c] [include/windows.h]
	Bugfix: fixed wrong parameter for CreateDIBSection16.
	Added [GS]etDIBColorTable16, stub for GetBoundsRect16.
	Partially implemented BITMAP_GetObject16 for DIBs.

	* [if1632/gdi.spec] [relay32/gdi32.spec] [objects/palette.c]
	Added some GDI stubs.

	* [if1632/Makefile.in] [if1632/display.spec] [if1632/mouse.spec]
	  [if1632/keyboard.spec] [if1632/builtin.c] [windows/keyboard.c]
	Added some stubs for Win16 drivers: KEYBOARD, MOUSE, DISPLAY.

	* [if1632/wprocs.spec] [msdos/vxd.c]
	Added some stubs for VxDs: VMM, ConfigMG, TimerAPI.

	* [msdos/int2f.c]
	Added some stubs for real-mode network drivers.

Sat Sep 26 18:18:18 1998  Marcus Meissner <marcus@jet.franken.de>

	* [configure.in]
	Merged in some more of the FreeBSD ports/emulators/wine patches. 
	(Maintainer(s) of this port: You can just submit these
	patches to Alexandre directly.)

	 * [loader/pe_image.c]
	Check filesize of image against size derived from header
	to spot truncated executeables without crashing.

	* [files/directory.c]
	Set envvar "COMSPEC". One win32(!!) program crashes without it.

	* [multimedia/mmio.c]
	Added mmioSetInfo32.

	* [include/file.h]
	Return STD_ERROR_HANDLE for AUX and PRT dos handles.

	* [loader/module.c]
	Handle executeables with spaces in their names a bit better in
	CreateProcess.

	* [relay32/msvfw32.spec][if1632/msvideo.spec][multimedia/msvideo.c][include/vfw.h]
	Started on MS Video support (can load Win32 ICMs).

	* [tools/testrun]
	A bit smarter use of ps.

	* [memory/virtual.c]
	Report PAGE_GUARDed pages as PAGE_PROTECTED (AutoCAD LT R17 fails
	without that check (since Win95 doesn't know about PAGE_GUARD)).

Sat Sep 26 15:04:05 1998  Ove Kaaven <ovek@arcticnet.no>

	* [include/miscemu.h] [if1632/builtin.c] [loader/task.c]
	  [miscemu/instr.c] [msdos/dpmi.c] [msdos/int21.c]
	  [msdos/interrupts.c] [windows/user.c]
	INT_[S|G]etHandler was renamed to INT_[S|G]etPMHandler.
	Added handlers to deal with real-mode interrupts; DOS
	programs are now able to hook real-mode interrupts.

	* [loader/dos/module.c] [msdos/dosmem.c] [msdos/int21.c]
	Moved real-mode interrupt table initialization to
	msdos/dosmem.c, and made new V86 tasks get a full copy
	of the existing "system memory" instead of almost empty
	space. Misc fixes.

	* [include/dosexe.h] [loader/dos/module.c] [msdos/dpmi.c]
	  [msdos/int2f.c]
	First shot at letting DOS programs start up DPMI (but DPMI
	is still disabled for DOS programs, for pkunzip's sake).

	* [include/debugger.h] [debugger/break.c] [debugger/dbg.y]
	  [debugger/registers.c] [debugger/memory.c] [debugger/info.c]
	  [loader/dos/dosvm.c]
	First shot at making Wine's debugger work for DOS programs.
	The -debug flag works, as do "nexti" and "stepi".

Sat Sep 26 13:13:13 1998  Juergen Schmied <juergen.schmied@metronet.de>

	* [dlls/shell32/dataobject.c]
	New classes IEnumFORMATETC implemented, IDataObject stubs.
	
	* [dlls/shell32/*.*][relay32/shell32.spec]
	Bugfixes.
	New: ICM_InsertItem(), ILCreateFromPath().
	Implemented: ILCloneFirst().
	Stubs: ILIsEqual(), ILFindChild(), SHLogILFromFSIL(),
	  PathMatchSpec(), PathIsExe().
	Changed: ILGetSize(), _ILIsDesktop(), PathCombine().

	* [include/shlobj.h]
	New SHLGUID's
	New structures: DVTARGETDEVICE32, STGMEDIUM32, FORMATETC32,
	CLIPFORMAT32.
	New interfaces: IEnumFORMATETC, IDataObject, ICommDlgBrowser
	IDockingWindowFrame, IServiceProvider.

	* [dlls/shell32/folders.c]
	Stubs for IShellLink.

	* [loader/resource.c]
	Small fixes.

	* [misc/crtdll.c][relay32/crtdll.spec]
	New __dllonexit().

	* [windows/message.c]
	SendNotifyMessageA, SendMessageCallBack32A half implemented.

	* [controls/edit.c]
	EDIT_WM_SetText set EF_UPDATE flag not for ES_MULTILINE.

	* [files/file.c]
	Handling of fileposition fixed.

Fri Sep 25 18:13:30 1998  Patrik Stridvall <ps@leissner.se>

	* [include/windows.h] [include/wintypes.h]
	  [ole/ole2nls.h] [relay32/kernel32.spec]
	Implemented EnumDateFormats and EnumTimeFormats.
	Only adds US English support.

	* [Makefile.in] [configure.in] 
	  [dlls/Makefile.in] [dlls/psapi/Makefile.in] 
	  [dlls/psapi/psapi_main.c] 
	New files to implement stubs for PSAPI.DLL (NT only).

	* [relay32/Makefile.in] [relay32/builtin32.c] 
	  [relay32/psapi.spec]
	New spec file for PSAPI.DLL (NT only).

	* [scheduler/handle.c]
	HANDLE_GetObjPtr should only interpret the pseudo handles as the
	current thread or the current process if a thread or a process is
	requested.

	* [include/winversion.h] [misc/version.c]
	Adds the global function VERSION_GetVersion() so functions can
	have different behavior depending on the -winver flag.

	* [include/oledlg.h] [ole/oledlg.c]
	Minor fixes. 

	* [windows/winproc.c]
	Minor changes.

	* [include/imm.h] [misc/imm.c]
	Now returns correct values under both Windows 95 and NT 4.0.

Thu Sep 24 22:11:44 1998  Kristian Nielsen  <kristian.nielsen@risoe.dk>

	* [configure.in] [include/acconfig.h] [include/thread.h]
	  [scheduler/sysdeps.c]
	Autoconfig test for non-reentrant libc.

Wed Sep 23 19:52:12 1998  Matthew Becker <mbecker@glasscity.net>

	* [*/*.c]
	Miscellaneous documentation updates and debugging output 
	standardizations.

	* [objects/clipping.c]
	Added ExtSelectClipRgn.

Wed Sep 23 00:03:28 EDT 1998  Pete Ratzlaff <pratzlaff@cfa.harvard.edu>

	* [include/windows.h] [if1632/user.spec] [relay32/user32.spec]
	  [windows/keyboard.c]
	Added, marginally implemented, GetKeyboardLayoutName().
	Only returns US English keyboard name.

Tue Sep 22 16:32:41 1998  Marcel Baur <mbaur@iiic.ethz.ch>

	* [programs/control/*]
	New Winelib application.

Mon Sep 21 00:29:18 1998  Peter Hunnisett <hunnise@nortel.ca>

	* [include/dplay.h][multimedia/dplay.c][ole/compobj.c]
	Added all DirectPlayLobby interfaces and enhanced DirectPlay
	and DirectPlayLobby support. Still not all that much. Useful
	enough if you just need to start a program, don't try any
	real dplay/lobby stuff.

	* [documentation/status/directplay]
	Added a very little bit.

	* [graphics/ddraw.c]
	- Call to SetWindowLong32A wasn't working because there was no
	  memory set aside when the window class was registered.
	- Fixed some xlib reference counting and change the behaviour
	  of DirectDrawSurface3_SetPalette to mimic observed behaviour
	  (palette is associated will all backbuffers)
	- Also stored all palette colour fields and spit back our saved
	  colour fields rather than query X for them.
	- Added plenty of AddRef and Release traces.
	- Added Xlib support for using -desktop option.
	- Fixed Xlib message handling. Messages weren't being passed to
	  the application. Fixes mouse movements in some xlib DDraw games.
	- Added a few stubs.

	* [windows/win.c][include/winerror.h]
	Fixed up some error handling in WIN_SetWindowLong. SetLastError
	wasn't being used. Could cause problems with 0 return codes.
	Added new error in winerror (1400).

	* [AUTHORS] [include/authors.h]
	Added myself as a Wine author.

Sun Sep 20 21:22:44 1998  Alexander Larsson  <alla@lysator.liu.se>

	* [loader/module.c]
	Changed GetModuleFileName32A so that is returns the
	long version of the filename. Note that just the name
	is long, not the directories.

Sat Sep 19 20:05:30 1998 Per Ångström <pang@mind.nu> 

	* [controls/menu.c]
	Made a couple of fixes to make life easier for applications that alter
	their menus at runtime.

	* [windows/defdlg.c]
	Removed the cast of the return value from dialog procedures to a 16-bit
	bool. The return value needs to retain all its 32 bits, since it is not 
	always a bool, such as when responding to the WM_NCHITTEST message.

Fri Sep 18 11:30:38 1998  Sergey Turchanov <turchanov@usa.net>

	* [loader/resource.c]
	Fixed very funny bug (though gravely affecting further excecution)
	with FindResource[Ex]32 functions.

	* [include/multimon.h] [windows/multimon.c] [relay32/user32.spec]
	  [include/windows.h] [windows/sysmetrics.c]
	Default implementation for Multimonitor API.

	* [include/windows.h] [windows/winpos.c]
	Fixed incorrect declaration (and behaviour) of GetWindowRect32.

Wed Sep 16 10:21:15 1998  Gerard Patel <G.Patel@Wanadoo.fr>

	* [controls/edit.c]
	Fixed EDIT_EM_GetLine to use correctly length of lines.

Tue Sep 15 20:40:16 1998  Eric Kohl <ekohl@abo.rhein-zeitung.de>

	* [misc/tweak.c][include/tweak.h][controls/menu.c]
	Replaced the tweak graphic routines by calls to DrawEdge32().

	* [misc/tweak.c][include/tweak.h][documentation/win95look]
	  [wine.ini][*/*]
	Changed "look and feel" selection. Allows Win3.1, Win95 and
	Win98 (no GUI code implemented) look and feel.

	* [dlls/comctl32/header.c][include/header.h][include/commctrl.h]
	Started callback item support and did some minor improvements.

	* [dlls/comctl32/imagelist.c]
	Fixed bug in transparent image display.
	ImageList_GetIcon is still buggy :-(

	* [dlls/comctl32/toolbar.c]
	Fixed button drawing (partial hack).

	* [dlls/comctl32/commctrl.c]
	Fixed MenuHelp().

	* [controls/button.c]
	Added 3d effect for groupbox.

	* [windows/msgbox.c]
	Added font support for message boxes.

	* [windows/nonclient.c]
	Fixed window moving bug.

	* [dlls/comctl32/*.c]
	Various improvements.

	* [dlls/comctl32/listview.c][dlls/comctl32/rebar.c]
	  [include/commctrl.h]
	More messages.

	* [windows/syscolor.c][include/windows.h]
	Introduced new Win98 system colors.

Tue Sep 15 18:29:45 1998 Wesley Filardo <eightknots@aol.com>

	* [files/profile.c]
	Added support in PROFILE_LoadWineIni for -config option

	* [misc/main.c] [include/options.h]
	Added -config option.

Tue Sep 15 18:22:26 1998  Petter Reinholdtsen <pere@td.org.uit.no>

	* [documentation/Makefile.in]
	Make sure directory exists before installing into it.

Tue Sep 15 01:47:33 1998  Pablo Saratxaga <pablo.sarachaga@ping.be>

	* [ole/nls/*] [ole/ole2nls.c] [include/winnls.h]
	Fixed a few errors and completed some NLS files.

Mon Sep 14 01:23:45 1998  Joseph Pranevich <knight@baltimore.wwaves.com>

	* [include/miscemu.h] [msdos/interrupts.c]
	Removed a compilation warning, added INT 25 to the list of interrupts
	callable from DOS applications, added a debug message when unsupported
	interrupts are used.

Sun Sep 13 19:55:22 1998  Lawson Whitney <lawson_whitney@juno.com>

	* [if1632/relay.c]
	CallProcEx32W should not reverse arguments.

Sun Aug 17 21:18:12 1998  Eric Pouech  <eric.pouech@lemel.fr>

	* [multimedia/midi.c] [multimedia/init.c] [multimedia/mmsys.c] 
	  [include/multimedia.h] [include/mmsystem.h] 
	  [multimedia/Makefile.in] [multimedia/midipatch.c]
	  [if1632/multimedia.spec]
	Made MIDI input and output functional on OSS capable systems.

	* [multimedia/timer.c]
	Changes to trigger callbacks at the accurate pace even when
	fake timers are used.
diff --git a/ANNOUNCE b/ANNOUNCE
index d73d5d4..1325b30 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,14 +1,15 @@
-This is release 980913 of Wine, the MS Windows emulator.  This is still a
+This is release 980927 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-980913: (see ChangeLog for details)
-	- Even more common controls stuff.
-	- Many PostScript driver improvements.
-	- More DOS executables support.
+WHAT'S NEW with Wine-980927: (see ChangeLog for details)
+	- Still more common controls and SHELL32 features.
+	- MIDI I/O support.
+	- Several new undocumented KERNEL functions.
+	- More DOS exe stuff including some debugger support.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -17,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-980913.tar.gz
-  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-980913.tar.gz
-  ftp://ftp.infomagic.com/pub/mirrors/linux/sunsite/ALPHA/wine/development/Wine-980913.tar.gz
-  ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-980913.tar.gz
+  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-980927.tar.gz
+  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-980927.tar.gz
+  ftp://ftp.infomagic.com/pub/mirrors/linux/sunsite/ALPHA/wine/development/Wine-980927.tar.gz
+  ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-980927.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/AUTHORS b/AUTHORS
index d12f9ff..bd8462a 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -32,6 +32,7 @@
 Carsten Fallesen,
 Paul Falstad,
 David Faure,
+Wesley Filardo,
 Claus Fischer,
 Olaf Flebbe,
 Chad Fraleigh,
@@ -49,6 +50,7 @@
 Jochen Hoenicke,
 Onno Hovers,
 Jeffrey Hsu,
+Peter Hunnisett,
 Miguel de Icaza,
 Jukka Iivonen,
 Lee Jaekil,
@@ -91,6 +93,7 @@
 Dimitrie O. Paun,
 Jim Peterson,
 Robert Pouliot,
+Petter Reinholdtsen,
 Keith Reynolds,
 Slaven Rezic,
 John Richardson,
diff --git a/ChangeLog b/ChangeLog
index 2b00865..0eea733 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,406 @@
 ----------------------------------------------------------------------
+Sun Sep 27 14:25:38 1998  Petter Reinholdtsen <pere@td.org.uit.no>
+
+	* [files/drive.c]
+	Make sure GetDriveType32A() handles param NULL.  Added some
+	doc on function.
+
+Sun Sep 27 14:07:26 1998  Huw D M Davies <daviesh@abacus.physics.ox.ac.uk>
+
+	* [controls/edit.c] [windows/win.c]
+	Don't call SetWindowLong() in EDIT_WM_NCREATE.
+	Fix SetWindowLong(GWL_[EX]STYLE) to work for 16bit windows. Remove
+	UpdateWindow() call. 
+
+Sun Sep 27 13:41:22 1998  Alexandre Julliard  <julliard@lrc.epfl.ch>
+
+	* [scheduler/*.c] [server/event.c] [server/mutex.c]
+	  [server/semaphore.c]
+	Implemented server-side synchronisation objects.
+
+Sun Sep 27 01:13:35 1998  Alex Priem <alexp@sci.kun.nl>
+
+	* [dlls/comctl32/treeview.c] [include/treeview.h] [include/comctl.h]
+	Treeview implementation.
+
+	* [dlls/comctl32/trackbar.c] [include/trackbar.h] 
+	Trackbar implementation.
+
+Sat Sep 26 20:49:13 1998  Ulrich Weigand <weigand@informatik.uni-erlangen.de>
+
+	* [if1632/thunk.c] [tools/build.c] [win32/kernel32.c]
+	Bugfix: several problems with flat thunks fixed.
+
+	* [memory/selector.c]
+	Bugfix: IsBad...Ptr16 didn't work for limit_in_pages segments.
+
+	* [scheduler/thread.c]
+	Bugfix: CreateThread: Allow id parameter == NULL.
+
+	* [objects/gdiobj.c]
+	Bugfix: IsGDIObject: Return correct object type for stock objects.
+
+	* [msdos/dpmi.c]
+	Bugfix: fixed typo in INT_DoRealModeInt.
+
+	* [msdos/int21.c]
+	Bugfix: int21 READ *must* use WIN16_hread, not _hread16.
+
+	* [if1632/kernel.spec] [if1632/dummy.c] [if1632/thunk.c]
+	  [loader/ne/module.c] [scheduler/event.c] [scheduler/synchro.c]
+	  [scheduler/thread.c] [win32/kernel32.c] [win32/ordinals.c]
+	Added names/stubs for all undocumented KERNEL routines (Win95).
+	Added the following undoc. 16-bit equivalents to Win32 routines:
+	KERNEL.441-443,449-453,456-462,471-476,479-486,488.
+	Added stubs for some other KERNEL routines.
+
+	* [memory/heap.c] [memory/global.c] [include/global.h]
+	Implemented Local32... 32-bit local heap routines (KERNEL.208-215, 229).
+
+	* [miscemu/instr.c] [loader/module.c] [include/module.h]
+	Implemented __GP fault handling and HasGPHandler (KERNEL.338).
+
+	* [misc/error.c]
+	Implemented LogParamErrorRegs (KERNEL.327).
+
+	* [loader/task.c] [include/windows.h]
+	Implemented GetCodeInfo (KERNEL.104).
+
+	* [loader/task.c] [scheduler/thread.c] [include/thread.h]
+	Implemented [GS]etThreadQueue and [GS]etFastQueue (KERNEL.463/4, 624/5).
+
+	* [if1632/gdi.spec] [objects/dc.c] [objects/dib.c]
+	  [objects/bitmap.c] [include/windows.h]
+	Bugfix: fixed wrong parameter for CreateDIBSection16.
+	Added [GS]etDIBColorTable16, stub for GetBoundsRect16.
+	Partially implemented BITMAP_GetObject16 for DIBs.
+
+	* [if1632/gdi.spec] [relay32/gdi32.spec] [objects/palette.c]
+	Added some GDI stubs.
+
+	* [if1632/Makefile.in] [if1632/display.spec] [if1632/mouse.spec]
+	  [if1632/keyboard.spec] [if1632/builtin.c] [windows/keyboard.c]
+	Added some stubs for Win16 drivers: KEYBOARD, MOUSE, DISPLAY.
+
+	* [if1632/wprocs.spec] [msdos/vxd.c]
+	Added some stubs for VxDs: VMM, ConfigMG, TimerAPI.
+
+	* [msdos/int2f.c]
+	Added some stubs for real-mode network drivers.
+
+Sat Sep 26 18:18:18 1998  Marcus Meissner <marcus@jet.franken.de>
+
+	* [configure.in]
+	Merged in some more of the FreeBSD ports/emulators/wine patches. 
+	(Maintainer(s) of this port: You can just submit these
+	patches to Alexandre directly.)
+
+	 * [loader/pe_image.c]
+	Check filesize of image against size derived from header
+	to spot truncated executeables without crashing.
+
+	* [files/directory.c]
+	Set envvar "COMSPEC". One win32(!!) program crashes without it.
+
+	* [multimedia/mmio.c]
+	Added mmioSetInfo32.
+
+	* [include/file.h]
+	Return STD_ERROR_HANDLE for AUX and PRT dos handles.
+
+	* [loader/module.c]
+	Handle executeables with spaces in their names a bit better in
+	CreateProcess.
+
+	* [relay32/msvfw32.spec][if1632/msvideo.spec][multimedia/msvideo.c][include/vfw.h]
+	Started on MS Video support (can load Win32 ICMs).
+
+	* [tools/testrun]
+	A bit smarter use of ps.
+
+	* [memory/virtual.c]
+	Report PAGE_GUARDed pages as PAGE_PROTECTED (AutoCAD LT R17 fails
+	without that check (since Win95 doesn't know about PAGE_GUARD)).
+
+Sat Sep 26 15:04:05 1998  Ove Kaaven <ovek@arcticnet.no>
+
+	* [include/miscemu.h] [if1632/builtin.c] [loader/task.c]
+	  [miscemu/instr.c] [msdos/dpmi.c] [msdos/int21.c]
+	  [msdos/interrupts.c] [windows/user.c]
+	INT_[S|G]etHandler was renamed to INT_[S|G]etPMHandler.
+	Added handlers to deal with real-mode interrupts; DOS
+	programs are now able to hook real-mode interrupts.
+
+	* [loader/dos/module.c] [msdos/dosmem.c] [msdos/int21.c]
+	Moved real-mode interrupt table initialization to
+	msdos/dosmem.c, and made new V86 tasks get a full copy
+	of the existing "system memory" instead of almost empty
+	space. Misc fixes.
+
+	* [include/dosexe.h] [loader/dos/module.c] [msdos/dpmi.c]
+	  [msdos/int2f.c]
+	First shot at letting DOS programs start up DPMI (but DPMI
+	is still disabled for DOS programs, for pkunzip's sake).
+
+	* [include/debugger.h] [debugger/break.c] [debugger/dbg.y]
+	  [debugger/registers.c] [debugger/memory.c] [debugger/info.c]
+	  [loader/dos/dosvm.c]
+	First shot at making Wine's debugger work for DOS programs.
+	The -debug flag works, as do "nexti" and "stepi".
+
+Sat Sep 26 13:13:13 1998  Juergen Schmied <juergen.schmied@metronet.de>
+
+	* [dlls/shell32/dataobject.c]
+	New classes IEnumFORMATETC implemented, IDataObject stubs.
+	
+	* [dlls/shell32/*.*][relay32/shell32.spec]
+	Bugfixes.
+	New: ICM_InsertItem(), ILCreateFromPath().
+	Implemented: ILCloneFirst().
+	Stubs: ILIsEqual(), ILFindChild(), SHLogILFromFSIL(),
+	  PathMatchSpec(), PathIsExe().
+	Changed: ILGetSize(), _ILIsDesktop(), PathCombine().
+
+	* [include/shlobj.h]
+	New SHLGUID's
+	New structures: DVTARGETDEVICE32, STGMEDIUM32, FORMATETC32,
+	CLIPFORMAT32.
+	New interfaces: IEnumFORMATETC, IDataObject, ICommDlgBrowser
+	IDockingWindowFrame, IServiceProvider.
+
+	* [dlls/shell32/folders.c]
+	Stubs for IShellLink.
+
+	* [loader/resource.c]
+	Small fixes.
+
+	* [misc/crtdll.c][relay32/crtdll.spec]
+	New __dllonexit().
+
+	* [windows/message.c]
+	SendNotifyMessageA, SendMessageCallBack32A half implemented.
+
+	* [controls/edit.c]
+	EDIT_WM_SetText set EF_UPDATE flag not for ES_MULTILINE.
+
+	* [files/file.c]
+	Handling of fileposition fixed.
+
+Fri Sep 25 18:13:30 1998  Patrik Stridvall <ps@leissner.se>
+
+	* [include/windows.h] [include/wintypes.h]
+	  [ole/ole2nls.h] [relay32/kernel32.spec]
+	Implemented EnumDateFormats and EnumTimeFormats.
+	Only adds US English support.
+
+	* [Makefile.in] [configure.in] 
+	  [dlls/Makefile.in] [dlls/psapi/Makefile.in] 
+	  [dlls/psapi/psapi_main.c] 
+	New files to implement stubs for PSAPI.DLL (NT only).
+
+	* [relay32/Makefile.in] [relay32/builtin32.c] 
+	  [relay32/psapi.spec]
+	New spec file for PSAPI.DLL (NT only).
+
+	* [scheduler/handle.c]
+	HANDLE_GetObjPtr should only interpret the pseudo handles as the
+	current thread or the current process if a thread or a process is
+	requested.
+
+	* [include/winversion.h] [misc/version.c]
+	Adds the global function VERSION_GetVersion() so functions can
+	have different behavior depending on the -winver flag.
+
+	* [include/oledlg.h] [ole/oledlg.c]
+	Minor fixes. 
+
+	* [windows/winproc.c]
+	Minor changes.
+
+	* [include/imm.h] [misc/imm.c]
+	Now returns correct values under both Windows 95 and NT 4.0.
+
+Thu Sep 24 22:11:44 1998  Kristian Nielsen  <kristian.nielsen@risoe.dk>
+
+	* [configure.in] [include/acconfig.h] [include/thread.h]
+	  [scheduler/sysdeps.c]
+	Autoconfig test for non-reentrant libc.
+
+Wed Sep 23 19:52:12 1998  Matthew Becker <mbecker@glasscity.net>
+
+	* [*/*.c]
+	Miscellaneous documentation updates and debugging output 
+	standardizations.
+
+	* [objects/clipping.c]
+	Added ExtSelectClipRgn.
+
+Wed Sep 23 00:03:28 EDT 1998  Pete Ratzlaff <pratzlaff@cfa.harvard.edu>
+
+	* [include/windows.h] [if1632/user.spec] [relay32/user32.spec]
+	  [windows/keyboard.c]
+	Added, marginally implemented, GetKeyboardLayoutName().
+	Only returns US English keyboard name.
+
+Tue Sep 22 16:32:41 1998  Marcel Baur <mbaur@iiic.ethz.ch>
+
+	* [programs/control/*]
+	New Winelib application.
+
+Mon Sep 21 00:29:18 1998  Peter Hunnisett <hunnise@nortel.ca>
+
+	* [include/dplay.h][multimedia/dplay.c][ole/compobj.c]
+	Added all DirectPlayLobby interfaces and enhanced DirectPlay
+	and DirectPlayLobby support. Still not all that much. Useful
+	enough if you just need to start a program, don't try any
+	real dplay/lobby stuff.
+
+	* [documentation/status/directplay]
+	Added a very little bit.
+
+	* [graphics/ddraw.c]
+	- Call to SetWindowLong32A wasn't working because there was no
+	  memory set aside when the window class was registered.
+	- Fixed some xlib reference counting and change the behaviour
+	  of DirectDrawSurface3_SetPalette to mimic observed behaviour
+	  (palette is associated will all backbuffers)
+	- Also stored all palette colour fields and spit back our saved
+	  colour fields rather than query X for them.
+	- Added plenty of AddRef and Release traces.
+	- Added Xlib support for using -desktop option.
+	- Fixed Xlib message handling. Messages weren't being passed to
+	  the application. Fixes mouse movements in some xlib DDraw games.
+	- Added a few stubs.
+
+	* [windows/win.c][include/winerror.h]
+	Fixed up some error handling in WIN_SetWindowLong. SetLastError
+	wasn't being used. Could cause problems with 0 return codes.
+	Added new error in winerror (1400).
+
+	* [AUTHORS] [include/authors.h]
+	Added myself as a Wine author.
+
+Sun Sep 20 21:22:44 1998  Alexander Larsson  <alla@lysator.liu.se>
+
+	* [loader/module.c]
+	Changed GetModuleFileName32A so that is returns the
+	long version of the filename. Note that just the name
+	is long, not the directories.
+
+Sat Sep 19 20:05:30 1998 Per Ångström <pang@mind.nu> 
+
+	* [controls/menu.c]
+	Made a couple of fixes to make life easier for applications that alter
+	their menus at runtime.
+
+	* [windows/defdlg.c]
+	Removed the cast of the return value from dialog procedures to a 16-bit
+	bool. The return value needs to retain all its 32 bits, since it is not 
+	always a bool, such as when responding to the WM_NCHITTEST message.
+
+Fri Sep 18 11:30:38 1998  Sergey Turchanov <turchanov@usa.net>
+
+	* [loader/resource.c]
+	Fixed very funny bug (though gravely affecting further excecution)
+	with FindResource[Ex]32 functions.
+
+	* [include/multimon.h] [windows/multimon.c] [relay32/user32.spec]
+	  [include/windows.h] [windows/sysmetrics.c]
+	Default implementation for Multimonitor API.
+
+	* [include/windows.h] [windows/winpos.c]
+	Fixed incorrect declaration (and behaviour) of GetWindowRect32.
+
+Wed Sep 16 10:21:15 1998  Gerard Patel <G.Patel@Wanadoo.fr>
+
+	* [controls/edit.c]
+	Fixed EDIT_EM_GetLine to use correctly length of lines.
+
+Tue Sep 15 20:40:16 1998  Eric Kohl <ekohl@abo.rhein-zeitung.de>
+
+	* [misc/tweak.c][include/tweak.h][controls/menu.c]
+	Replaced the tweak graphic routines by calls to DrawEdge32().
+
+	* [misc/tweak.c][include/tweak.h][documentation/win95look]
+	  [wine.ini][*/*]
+	Changed "look and feel" selection. Allows Win3.1, Win95 and
+	Win98 (no GUI code implemented) look and feel.
+
+	* [dlls/comctl32/header.c][include/header.h][include/commctrl.h]
+	Started callback item support and did some minor improvements.
+
+	* [dlls/comctl32/imagelist.c]
+	Fixed bug in transparent image display.
+	ImageList_GetIcon is still buggy :-(
+
+	* [dlls/comctl32/toolbar.c]
+	Fixed button drawing (partial hack).
+
+	* [dlls/comctl32/commctrl.c]
+	Fixed MenuHelp().
+
+	* [controls/button.c]
+	Added 3d effect for groupbox.
+
+	* [windows/msgbox.c]
+	Added font support for message boxes.
+
+	* [windows/nonclient.c]
+	Fixed window moving bug.
+
+	* [dlls/comctl32/*.c]
+	Various improvements.
+
+	* [dlls/comctl32/listview.c][dlls/comctl32/rebar.c]
+	  [include/commctrl.h]
+	More messages.
+
+	* [windows/syscolor.c][include/windows.h]
+	Introduced new Win98 system colors.
+
+Tue Sep 15 18:29:45 1998 Wesley Filardo <eightknots@aol.com>
+
+	* [files/profile.c]
+	Added support in PROFILE_LoadWineIni for -config option
+
+	* [misc/main.c] [include/options.h]
+	Added -config option.
+
+Tue Sep 15 18:22:26 1998  Petter Reinholdtsen <pere@td.org.uit.no>
+
+	* [documentation/Makefile.in]
+	Make sure directory exists before installing into it.
+
+Tue Sep 15 01:47:33 1998  Pablo Saratxaga <pablo.sarachaga@ping.be>
+
+	* [ole/nls/*] [ole/ole2nls.c] [include/winnls.h]
+	Fixed a few errors and completed some NLS files.
+
+Mon Sep 14 01:23:45 1998  Joseph Pranevich <knight@baltimore.wwaves.com>
+
+	* [include/miscemu.h] [msdos/interrupts.c]
+	Removed a compilation warning, added INT 25 to the list of interrupts
+	callable from DOS applications, added a debug message when unsupported
+	interrupts are used.
+
+Sun Sep 13 19:55:22 1998  Lawson Whitney <lawson_whitney@juno.com>
+
+	* [if1632/relay.c]
+	CallProcEx32W should not reverse arguments.
+
+Sun Aug 17 21:18:12 1998  Eric Pouech  <eric.pouech@lemel.fr>
+
+	* [multimedia/midi.c] [multimedia/init.c] [multimedia/mmsys.c] 
+	  [include/multimedia.h] [include/mmsystem.h] 
+	  [multimedia/Makefile.in] [multimedia/midipatch.c]
+	  [if1632/multimedia.spec]
+	Made MIDI input and output functional on OSS capable systems.
+
+	* [multimedia/timer.c]
+	Changes to trigger callbacks at the accurate pace even when
+	fake timers are used.
+
+----------------------------------------------------------------------
 Fri Sep 11 13:14:35 1998  Andreas Mohr <100.30936@germany.net>
 
 	* [files/file.c] [include/file.h]
diff --git a/Makefile.in b/Makefile.in
index d4433a0..6cc38b2 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -28,7 +28,10 @@
 	tools/wrc \
 	controls \
 	dlls/comctl32 \
+	dlls/psapi \
 	dlls/shell32 \
+	dlls/winaspi \
+	dlls/wnaspi32 \
 	files \
 	graphics \
 	graphics/metafiledrv \
@@ -79,7 +82,10 @@
 LIBOBJS = \
 	controls/controls.o \
 	dlls/comctl32/comctl32.o \
+	dlls/psapi/psapi.o \
 	dlls/shell32/shell32.o \
+	dlls/winaspi/winaspi.o \
+	dlls/wnaspi32/wnaspi32.o \
 	files/files.o \
 	graphics/graphics.o \
 	graphics/metafiledrv/metafiledrv.o \
diff --git a/configure b/configure
index d36a6c7..eaece4d 100755
--- a/configure
+++ b/configure
@@ -2070,8 +2070,55 @@
   echo "$ac_t""no" 1>&6
 fi
 
+echo $ac_n "checking for setrunelocale in -lxpg4""... $ac_c" 1>&6
+echo "configure:2075: checking for setrunelocale in -lxpg4" >&5
+ac_lib_var=`echo xpg4'_'setrunelocale | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lxpg4  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2083 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char setrunelocale();
+
+int main() {
+setrunelocale()
+; return 0; }
+EOF
+if { (eval echo configure:2094: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo xpg4 | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lxpg4 $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
 echo $ac_n "checking for XF86DGAQueryExtension in -lXxf86dga""... $ac_c" 1>&6
-echo "configure:2075: checking for XF86DGAQueryExtension in -lXxf86dga" >&5
+echo "configure:2122: checking for XF86DGAQueryExtension in -lXxf86dga" >&5
 ac_lib_var=`echo Xxf86dga'_'XF86DGAQueryExtension | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2079,7 +2126,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lXxf86dga $X_LIBS -lXext -lX11 $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2083 "configure"
+#line 2130 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2090,7 +2137,7 @@
 XF86DGAQueryExtension()
 ; return 0; }
 EOF
-if { (eval echo configure:2094: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2141: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2118,17 +2165,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2122: checking for $ac_hdr" >&5
+echo "configure:2169: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2127 "configure"
+#line 2174 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2132: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2179: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2156,12 +2203,12 @@
 
 
 echo $ac_n "checking "for Open Sound System"""... $ac_c" 1>&6
-echo "configure:2160: checking "for Open Sound System"" >&5
+echo "configure:2207: checking "for Open Sound System"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_opensoundsystem'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2165 "configure"
+#line 2212 "configure"
 #include "confdefs.h"
 
 	#ifdef HAVE_SYS_SOUNDCARD_H
@@ -2181,7 +2228,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2185: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2232: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_opensoundsystem="yes"
 else
@@ -2205,12 +2252,12 @@
 
 
 echo $ac_n "checking "for union semun"""... $ac_c" 1>&6
-echo "configure:2209: checking "for union semun"" >&5
+echo "configure:2256: checking "for union semun"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_union_semun'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2214 "configure"
+#line 2261 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/sem.h>
@@ -2218,7 +2265,7 @@
 union semun foo
 ; return 0; }
 EOF
-if { (eval echo configure:2222: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2269: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_union_semun="yes"
 else
@@ -2246,7 +2293,7 @@
 then
   CFLAGS="$CFLAGS -Wall"
   echo $ac_n "checking "for gcc strength-reduce bug"""... $ac_c" 1>&6
-echo "configure:2250: checking "for gcc strength-reduce bug"" >&5
+echo "configure:2297: checking "for gcc strength-reduce bug"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_gcc_strength_bug'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2254,7 +2301,7 @@
   ac_cv_c_gcc_strength_bug="yes"
 else
   cat > conftest.$ac_ext <<EOF
-#line 2258 "configure"
+#line 2305 "configure"
 #include "confdefs.h"
 
 int main(void) {
@@ -2265,7 +2312,7 @@
   exit( Array[1] != -2 );
 }
 EOF
-if { (eval echo configure:2269: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2316: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_gcc_strength_bug="no"
 else
@@ -2288,7 +2335,7 @@
 
 
 echo $ac_n "checking "whether external symbols need an underscore prefix"""... $ac_c" 1>&6
-echo "configure:2292: checking "whether external symbols need an underscore prefix"" >&5
+echo "configure:2339: checking "whether external symbols need an underscore prefix"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_extern_prefix'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2300,14 +2347,14 @@
 	.long 0
 EOF
 cat > conftest.$ac_ext <<EOF
-#line 2304 "configure"
+#line 2351 "configure"
 #include "confdefs.h"
 extern int ac_test;
 int main() {
 if (ac_test) return 1
 ; return 0; }
 EOF
-if { (eval echo configure:2311: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2358: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_c_extern_prefix="yes"
 else
@@ -2331,7 +2378,7 @@
 
 
 echo $ac_n "checking "whether assembler accepts .string"""... $ac_c" 1>&6
-echo "configure:2335: checking "whether assembler accepts .string"" >&5
+echo "configure:2382: checking "whether assembler accepts .string"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_asm_string'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2341,14 +2388,14 @@
 	.string "test"
 EOF
 cat > conftest.$ac_ext <<EOF
-#line 2345 "configure"
+#line 2392 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:2352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2399: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_c_asm_string="yes"
 else
@@ -2375,21 +2422,21 @@
 if test "$LIB_TARGET" = "libwine.so.1.0"
 then
   echo $ac_n "checking "whether we can build a dll"""... $ac_c" 1>&6
-echo "configure:2379: checking "whether we can build a dll"" >&5
+echo "configure:2426: checking "whether we can build a dll"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_dll'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   saved_cflags=$CFLAGS
   CFLAGS="$CFLAGS -fPIC -shared -Wl,-soname,conftest.so.1.0"
   cat > conftest.$ac_ext <<EOF
-#line 2386 "configure"
+#line 2433 "configure"
 #include "confdefs.h"
 
 int main() {
 return 1
 ; return 0; }
 EOF
-if { (eval echo configure:2393: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2440: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_c_dll="yes"
 else
@@ -2414,8 +2461,48 @@
 
 
 
+echo $ac_n "checking "for reentrant libc"""... $ac_c" 1>&6
+echo "configure:2466: checking "for reentrant libc"" >&5
+if eval "test \"`echo '$''{'wine_cv_libc_reentrant'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  wine_cv_libc_reentrant=yes 
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2474 "configure"
+#include "confdefs.h"
+int myerrno = 0;
+char buf[256];
+int *__errno_location(){return &myerrno;}
+main(){connect(0,buf,255); exit(!myerrno);}
+EOF
+if { (eval echo configure:2481: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  wine_cv_libc_reentrant=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  wine_cv_libc_reentrant=no
+fi
+rm -fr conftest*
+fi
+  
+fi
+
+echo "$ac_t""$wine_cv_libc_reentrant" 1>&6
+if test "$wine_cv_libc_reentrant" = "no" 
+then
+  cat >> confdefs.h <<\EOF
+#define NO_REENTRANT_LIBC 1
+EOF
+
+fi
+
+
 echo $ac_n "checking "for reentrant X libraries"""... $ac_c" 1>&6
-echo "configure:2419: checking "for reentrant X libraries"" >&5
+echo "configure:2506: checking "for reentrant X libraries"" >&5
 if eval "test \"`echo '$''{'wine_cv_x_reentrant'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2460,12 +2547,12 @@
 for ac_func in clone getpagesize memmove sendmsg sigaltstack strerror stricmp tcgetattr timegm usleep wait4 waitpid vfscanf
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2464: checking for $ac_func" >&5
+echo "configure:2551: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2469 "configure"
+#line 2556 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2488,7 +2575,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2492: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2579: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2516,17 +2603,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2520: checking for $ac_hdr" >&5
+echo "configure:2607: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2525 "configure"
+#line 2612 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2530: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2617: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2553,12 +2640,12 @@
 done
 
 echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6
-echo "configure:2557: checking whether stat file-mode macros are broken" >&5
+echo "configure:2644: checking whether stat file-mode macros are broken" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2562 "configure"
+#line 2649 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -2609,12 +2696,12 @@
 fi
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:2613: checking for working const" >&5
+echo "configure:2700: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2618 "configure"
+#line 2705 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -2663,7 +2750,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2667: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2754: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -2684,12 +2771,12 @@
 fi
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:2688: checking for ANSI C header files" >&5
+echo "configure:2775: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2693 "configure"
+#line 2780 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -2697,7 +2784,7 @@
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2701: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2788: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2714,7 +2801,7 @@
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 2718 "configure"
+#line 2805 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -2732,7 +2819,7 @@
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 2736 "configure"
+#line 2823 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -2753,7 +2840,7 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 2757 "configure"
+#line 2844 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -2764,7 +2851,7 @@
 exit (0); }
 
 EOF
-if { (eval echo configure:2768: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2855: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -2788,12 +2875,12 @@
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:2792: checking for size_t" >&5
+echo "configure:2879: checking for size_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2797 "configure"
+#line 2884 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -2821,7 +2908,7 @@
 fi
 
 echo $ac_n "checking size of long long""... $ac_c" 1>&6
-echo "configure:2825: checking size of long long" >&5
+echo "configure:2912: checking size of long long" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2829,7 +2916,7 @@
   ac_cv_sizeof_long_long=0
 else
   cat > conftest.$ac_ext <<EOF
-#line 2833 "configure"
+#line 2920 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -2840,7 +2927,7 @@
   exit(0);
 }
 EOF
-if { (eval echo configure:2844: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2931: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_long_long=`cat conftestval`
 else
@@ -2863,7 +2950,7 @@
 
 if test $ac_cv_func_sendmsg = no; then
     echo $ac_n "checking for sendmsg in -lsocket""... $ac_c" 1>&6
-echo "configure:2867: checking for sendmsg in -lsocket" >&5
+echo "configure:2954: checking for sendmsg in -lsocket" >&5
 ac_lib_var=`echo socket'_'sendmsg | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2871,7 +2958,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lsocket  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2875 "configure"
+#line 2962 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2882,7 +2969,7 @@
 sendmsg()
 ; return 0; }
 EOF
-if { (eval echo configure:2886: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2973: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2915,12 +3002,12 @@
 if test "$ac_cv_header_sys_vfs_h" = "yes"
 then
     echo $ac_n "checking "whether sys/vfs.h defines statfs"""... $ac_c" 1>&6
-echo "configure:2919: checking "whether sys/vfs.h defines statfs"" >&5
+echo "configure:3006: checking "whether sys/vfs.h defines statfs"" >&5
 if eval "test \"`echo '$''{'wine_cv_sys_vfs_has_statfs'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2924 "configure"
+#line 3011 "configure"
 #include "confdefs.h"
 
 	#include <sys/types.h>
@@ -2937,7 +3024,7 @@
 	
 ; return 0; }
 EOF
-if { (eval echo configure:2941: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3028: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_sys_vfs_has_statfs=yes
 else
@@ -2964,12 +3051,12 @@
 if test "$ac_cv_header_sys_statfs_h" = "yes"
 then
     echo $ac_n "checking "whether sys/statfs.h defines statfs"""... $ac_c" 1>&6
-echo "configure:2968: checking "whether sys/statfs.h defines statfs"" >&5
+echo "configure:3055: checking "whether sys/statfs.h defines statfs"" >&5
 if eval "test \"`echo '$''{'wine_cv_sys_statfs_has_statfs'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2973 "configure"
+#line 3060 "configure"
 #include "confdefs.h"
 
 	#include <sys/types.h>
@@ -2984,7 +3071,7 @@
 	
 ; return 0; }
 EOF
-if { (eval echo configure:2988: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3075: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_sys_statfs_has_statfs=yes
 else
@@ -3011,12 +3098,12 @@
 if test "$ac_cv_header_sys_mount_h" = "yes"
 then
     echo $ac_n "checking "whether sys/mount.h defines statfs"""... $ac_c" 1>&6
-echo "configure:3015: checking "whether sys/mount.h defines statfs"" >&5
+echo "configure:3102: checking "whether sys/mount.h defines statfs"" >&5
 if eval "test \"`echo '$''{'wine_cv_sys_mount_has_statfs'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3020 "configure"
+#line 3107 "configure"
 #include "confdefs.h"
 
 	#include <sys/types.h>
@@ -3031,7 +3118,7 @@
 	
 ; return 0; }
 EOF
-if { (eval echo configure:3035: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3122: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_sys_mount_has_statfs=yes
 else
@@ -3057,7 +3144,7 @@
 
 
 echo $ac_n "checking "for statfs.f_bfree"""... $ac_c" 1>&6
-echo "configure:3061: checking "for statfs.f_bfree"" >&5
+echo "configure:3148: checking "for statfs.f_bfree"" >&5
 if eval "test \"`echo '$''{'wine_cv_statfs_bfree'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3066,7 +3153,7 @@
         wine_cv_statfs_bfree=no
     else
     	cat > conftest.$ac_ext <<EOF
-#line 3070 "configure"
+#line 3157 "configure"
 #include "confdefs.h"
 
 	#include <sys/types.h>
@@ -3093,7 +3180,7 @@
 	
 ; return 0; }
 EOF
-if { (eval echo configure:3097: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3184: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_statfs_bfree=yes
 else
@@ -3117,7 +3204,7 @@
 fi
 
 echo $ac_n "checking "for statfs.f_bavail"""... $ac_c" 1>&6
-echo "configure:3121: checking "for statfs.f_bavail"" >&5
+echo "configure:3208: checking "for statfs.f_bavail"" >&5
 if eval "test \"`echo '$''{'wine_cv_statfs_bavail'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3126,7 +3213,7 @@
         wine_cv_statfs_bavail=no
     else
     	cat > conftest.$ac_ext <<EOF
-#line 3130 "configure"
+#line 3217 "configure"
 #include "confdefs.h"
 
 	#include <sys/types.h>
@@ -3153,7 +3240,7 @@
 	
 ; return 0; }
 EOF
-if { (eval echo configure:3157: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3244: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_statfs_bavail=yes
 else
@@ -3178,7 +3265,7 @@
 
 
 echo $ac_n "checking "for working sigaltstack"""... $ac_c" 1>&6
-echo "configure:3182: checking "for working sigaltstack"" >&5
+echo "configure:3269: checking "for working sigaltstack"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_working_sigaltstack'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3187,7 +3274,7 @@
 
 else
   cat > conftest.$ac_ext <<EOF
-#line 3191 "configure"
+#line 3278 "configure"
 #include "confdefs.h"
 
 	#include <stdio.h>
@@ -3225,7 +3312,7 @@
 	}
 	
 EOF
-if { (eval echo configure:3229: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3316: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_working_sigaltstack="yes"
 else
@@ -3252,12 +3339,12 @@
 
 
 echo $ac_n "checking "for msg_accrights in struct msghdr"""... $ac_c" 1>&6
-echo "configure:3256: checking "for msg_accrights in struct msghdr"" >&5
+echo "configure:3343: checking "for msg_accrights in struct msghdr"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_msg_accrights'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3261 "configure"
+#line 3348 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -3265,7 +3352,7 @@
 struct msghdr hdr; hdr.msg_accrights=0
 ; return 0; }
 EOF
-if { (eval echo configure:3269: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3356: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_msg_accrights="yes"
 else
@@ -3398,7 +3485,10 @@
 debugger/Makefile
 dlls/Makefile
 dlls/comctl32/Makefile
+dlls/psapi/Makefile
 dlls/shell32/Makefile
+dlls/winaspi/Makefile
+dlls/wnaspi32/Makefile
 documentation/Makefile
 files/Makefile
 graphics/Makefile
@@ -3422,6 +3512,7 @@
 ole/Makefile
 programs/Makefile
 programs/clock/Makefile
+programs/control/Makefile
 programs/notepad/Makefile
 programs/progman/Makefile
 programs/regtest/Makefile
@@ -3536,7 +3627,10 @@
 debugger/Makefile
 dlls/Makefile
 dlls/comctl32/Makefile
+dlls/psapi/Makefile
 dlls/shell32/Makefile
+dlls/winaspi/Makefile
+dlls/wnaspi32/Makefile
 documentation/Makefile
 files/Makefile
 graphics/Makefile
@@ -3560,6 +3654,7 @@
 ole/Makefile
 programs/Makefile
 programs/clock/Makefile
+programs/control/Makefile
 programs/notepad/Makefile
 programs/progman/Makefile
 programs/regtest/Makefile
@@ -3754,6 +3849,15 @@
 test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
 
 
+if test "$wine_cv_libc_reentrant" = "no" 
+then
+  echo
+  echo "*** Warning: non-reentrant libc detected. Wine will be build without"
+  echo "*** thread support. Consider upgrading libc to a more recent"
+  echo "*** reentrant version of libc."
+  echo
+fi
+
 echo
 echo "Configure finished.  Do 'make depend; make' to compile Wine."
 echo
diff --git a/configure.in b/configure.in
index d6a0c78..0e0a190 100644
--- a/configure.in
+++ b/configure.in
@@ -79,6 +79,8 @@
 AC_CHECK_LIB(i386,i386_set_ldt)
 dnl Check for -lw for Solaris
 AC_CHECK_LIB(w,iswalnum)
+dnl Check for -lxpg4 for FreeBSD
+AC_CHECK_LIB(xpg4,setrunelocale)
 dnl Check for XFree86 DGA extension
 AC_CHECK_LIB(Xxf86dga,XF86DGAQueryExtension,AC_DEFINE(HAVE_LIBXXF86DGA) X_PRE_LIBS="$X_PRE_LIBS -lXxf86dga",,$X_LIBS -lXext -lX11)
 
@@ -200,6 +202,23 @@
 fi
 AC_SUBST(DLLFLAGS)
 
+dnl **** Check for reentrant libc ****
+dnl
+dnl For cross-compiling we blindly assume that libc is reentrant. This is
+dnl ok since non-reentrant libc is quite rare (mostly old libc5 versions).
+
+AC_CACHE_CHECK("for reentrant libc", wine_cv_libc_reentrant,
+  [AC_TRY_RUN([int myerrno = 0;
+char buf[256];
+int *__errno_location(){return &myerrno;}
+main(){connect(0,buf,255); exit(!myerrno);}],
+  wine_cv_libc_reentrant=yes, wine_cv_libc_reentrant=no,
+  wine_cv_libc_reentrant=yes ) ] )
+if test "$wine_cv_libc_reentrant" = "no" 
+then
+  AC_DEFINE(NO_REENTRANT_LIBC)
+fi
+
 dnl **** Check for reentrant X libraries ****
 dnl
 dnl This may fail to determine whether X libraries are reentrant if
@@ -462,7 +481,10 @@
 debugger/Makefile
 dlls/Makefile
 dlls/comctl32/Makefile
+dlls/psapi/Makefile
 dlls/shell32/Makefile
+dlls/winaspi/Makefile
+dlls/wnaspi32/Makefile
 documentation/Makefile
 files/Makefile
 graphics/Makefile
@@ -486,6 +508,7 @@
 ole/Makefile
 programs/Makefile
 programs/clock/Makefile
+programs/control/Makefile
 programs/notepad/Makefile
 programs/progman/Makefile
 programs/regtest/Makefile
@@ -503,6 +526,15 @@
 win32/Makefile
 windows/Makefile ])
 
+if test "$wine_cv_libc_reentrant" = "no" 
+then
+  echo
+  echo "*** Warning: non-reentrant libc detected. Wine will be build without"
+  echo "*** thread support. Consider upgrading libc to a more recent"
+  echo "*** reentrant version of libc."
+  echo
+fi
+
 echo
 echo "Configure finished.  Do 'make depend; make' to compile Wine."
 echo
diff --git a/controls/button.c b/controls/button.c
index 0466339..9c8b60d 100644
--- a/controls/button.c
+++ b/controls/button.c
@@ -9,6 +9,7 @@
 #include "graphics.h"
 #include "button.h"
 #include "windows.h"
+#include "tweak.h"
 
 static void PB_Paint( WND *wndPtr, HDC32 hDC, WORD action );
 static void PB_PaintGrayOnGray(HDC32 hDC,HFONT32 hFont,RECT32 *rc,char *text);
@@ -485,7 +486,7 @@
 
 static void GB_Paint( WND *wndPtr, HDC32 hDC, WORD action )
 {
-    RECT32 rc;
+    RECT32 rc, rcFrame;
     BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;
 
     if (action != ODA_DRAWENTIRE) return;
@@ -493,8 +494,20 @@
     BUTTON_SEND_CTLCOLOR( wndPtr, hDC );
 
     GetClientRect32( wndPtr->hwndSelf, &rc);
-    GRAPH_DrawRectangle( hDC, rc.left, rc.top + 2, rc.right - 1, rc.bottom - 1,
-			 GetSysColorPen32(COLOR_WINDOWFRAME) );
+    if (TWEAK_WineLook == WIN31_LOOK)
+	GRAPH_DrawRectangle( hDC, rc.left, rc.top + 2, rc.right - 1, rc.bottom - 1,
+			    GetSysColorPen32(COLOR_WINDOWFRAME) );
+    else {
+	TEXTMETRIC32A tm;
+	rcFrame = rc;
+
+	if (infoPtr->hFont)
+	    SelectObject32 (hDC, infoPtr->hFont);
+	GetTextMetrics32A (hDC, &tm);
+	rcFrame.top += (tm.tmHeight / 2) - 1;
+	DrawEdge32 (hDC, &rcFrame, EDGE_ETCHED, BF_RECT);
+    }
+
     if (wndPtr->text)
     {
 	if (infoPtr->hFont) SelectObject32( hDC, infoPtr->hFont );
diff --git a/controls/combo.c b/controls/combo.c
index b7a44db..5af3552 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -158,7 +158,7 @@
 	 mi32.CtlID   = lphc->self->wIDmenu;
 	 mi32.itemID  = -1;
 	 mi32.itemWidth  = size.cx;
-	 mi32.itemHeight = size.cy - 6;	/* ownerdrawn cb is taller */
+	 mi32.itemHeight = u - 6;	/* ownerdrawn cb is taller */
 	 mi32.itemData   = 0;
 	 SendMessage32A(lphc->owner, WM_MEASUREITEM, 
 				(WPARAM32)mi32.CtlID, (LPARAM)&mi32);
@@ -172,12 +172,13 @@
    {
        HDC32    hDC = GetDC32( lphc->self->hwndSelf );
        HFONT32  hPrevFont = 0;
+       SIZE32   font_size;
 
        if( lphc->hFont ) hPrevFont = SelectObject32( hDC, lphc->hFont );
 
-       GetTextExtentPoint32A( hDC, "0", 1, &size);
+       GetTextExtentPoint32A( hDC, "0", 1, &font_size);
 
-       size.cy += size.cy / 4 + 4 * SYSMETRICS_CYBORDER;
+       size.cy = font_size.cy + font_size.cy / 4 + 4 * SYSMETRICS_CYBORDER;
 
        if( hPrevFont ) SelectObject32( hDC, hPrevFont );
        ReleaseDC32( lphc->self->hwndSelf, hDC );
@@ -1069,13 +1070,14 @@
 
   /* CreateWindow() may send a bogus WM_SIZE, ignore it */
 
-  if( w == (lphc->RectCombo.right - lphc->RectCombo.left) )
+  if( w == (lphc->RectCombo.right - lphc->RectCombo.left) ) {
       if( (CB_GETTYPE(lphc) == CBS_SIMPLE) &&
 	  (h == (lphc->RectCombo.bottom - lphc->RectCombo.top)) )
           return;
       else if( (lphc->dwStyle & CBS_DROPDOWN) &&
 	       (h == (lphc->RectEdit.bottom - lphc->RectEdit.top))  )
 	       return;
+  }
   
   lphc->RectCombo = rect;
   CBCalcPlacement( lphc, &lphc->RectEdit, &lphc->RectButton, &rect );
@@ -1141,11 +1143,12 @@
 {
    INT32 index = SendMessage32A( lphc->hWndLBox, LB_SELECTSTRING32, 
 				 (WPARAM32)start, (LPARAM)pText );
-   if( index >= 0 )
+   if( index >= 0 ) {
         if( lphc->wState & CBF_EDIT )
 	    CBUpdateEdit( lphc, index );
 	else
 	    CBPaintText( lphc, 0 );
+   }
    return (LRESULT)index;
 }
 
@@ -1493,15 +1496,15 @@
 				       (LPSTR)lParam, (message == CB_DIR32));
 	case CB_SHOWDROPDOWN16:
 	case CB_SHOWDROPDOWN32:
-		if( CB_GETTYPE(lphc) != CBS_SIMPLE )
-		    if( wParam )
-		    {
+		if( CB_GETTYPE(lphc) != CBS_SIMPLE ) {
+		    if( wParam ) {
 			if( !(lphc->wState & CBF_DROPPED) )
 			    CBDropDown( lphc );
-		    }
-		    else 
+		    } else  {
 			if( lphc->wState & CBF_DROPPED ) 
 		            CBRollUp( lphc, FALSE, TRUE );
+		    }
+		}
 		return TRUE;
 
 	case CB_GETCOUNT16: 
diff --git a/controls/edit.c b/controls/edit.c
index 8a90e01..d7b2829 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -1766,7 +1766,7 @@
 	CopyRect32(&es->format_rect, rc);
 	if (es->style & WS_BORDER) {
 		INT32 bw = GetSystemMetrics32(SM_CXBORDER) + 1;
-		if(!TWEAK_Win95Look)
+		if(TWEAK_WineLook == WIN31_LOOK)
 			bw += 2;
 		es->format_rect.left += bw;
 		es->format_rect.top += bw;
@@ -2066,8 +2066,9 @@
 			return 0;
 	} else
 		line = 0;
-	src = es->text + EDIT_EM_LineIndex(wnd, es, line);
-	len = MIN(*(WORD *)lpch, EDIT_EM_LineLength(wnd, es, line));
+	i = EDIT_EM_LineIndex(wnd, es, line);
+	src = es->text + i;
+	len = MIN(*(WORD *)lpch, EDIT_EM_LineLength(wnd, es, i));
 	for (i = 0 ; i < len ; i++) {
 		*lpch = *src;
 		src++;
@@ -3366,7 +3367,7 @@
 			EDIT_MovePageDown_ML(wnd, es, shift);
 		break;
 	case VK_BACK:
-		if (!(es->style & ES_READONLY) && !control)
+		if (!(es->style & ES_READONLY) && !control) {
 			if (es->selection_start != es->selection_end)
 				EDIT_WM_Clear(wnd, es);
 			else {
@@ -3375,9 +3376,10 @@
 				EDIT_MoveBackward(wnd, es, TRUE);
 				EDIT_WM_Clear(wnd, es);
 			}
+		}
 		break;
 	case VK_DELETE:
-		if (!(es->style & ES_READONLY) && !(shift && control))
+		if (!(es->style & ES_READONLY) && !(shift && control)) {
 			if (es->selection_start != es->selection_end) {
 				if (shift)
 					EDIT_WM_Cut(wnd, es);
@@ -3401,6 +3403,7 @@
 					EDIT_WM_Clear(wnd, es);
 				}
 			}
+		}
 		break;
 	case VK_INSERT:
 		if (shift) {
@@ -3538,13 +3541,19 @@
 	if (!(es = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*es))))
 		return FALSE;
 	*(EDITSTATE **)wnd->wExtra = es;
-	if (!(es->heap = HeapCreate(0, 0x10000, 0)))
-		return FALSE;
-	es->style = cs->style;
 
+       /*
+        *      Note: since the EDITSTATE has not been fully initialized yet,
+        *            we can't use any API calls that may send
+        *            WM_XXX messages before WM_NCCREATE is completed.
+        */
+
+ 	if (!(es->heap = HeapCreate(0, 0x10000, 0)))
+ 		return FALSE;
+ 	es->style = cs->style;
+ 
 	if ((es->style & WS_BORDER) && !(es->style & WS_DLGFRAME))
-		SetWindowLong32A(wnd->hwndSelf, GWL_STYLE, 
-				es->style & ~WS_BORDER);
+		wnd->dwStyle &= ~WS_BORDER;
 
 	if (es->style & ES_MULTILINE) {
 		es->buffer_size = BUFSTART_MULTI;
@@ -3756,7 +3765,7 @@
 	if (font)
 		SelectObject32(dc, old_font);
 	ReleaseDC32(wnd->hwndSelf, dc);
-	if (font & TWEAK_Win95Look)
+	if (font && (TWEAK_WineLook > WIN31_LOOK))
 		EDIT_EM_SetMargins(wnd, es, EC_LEFTMARGIN | EC_RIGHTMARGIN,
 				   EC_USEFONTINFO, EC_USEFONTINFO);
 	if (es->style & ES_MULTILINE)
@@ -3782,6 +3791,13 @@
  *
  *	WM_SETTEXT
  *
+ * NOTES
+ *  For multiline controls (ES_MULTILINE), reception of WM_SETTEXT triggers:
+ *  The modified flag is reset. No notifications are sent.
+ *
+ *  For single-line controls, reception of WM_SETTEXT triggers:
+ *  The modified flag is reset. EN_UPDATE and EN_CHANGE notifications are sent.
+ *
  */
 static void EDIT_WM_SetText(WND *wnd, EDITSTATE *es, LPCSTR text)
 {
@@ -3794,8 +3810,12 @@
 		EDIT_EM_ReplaceSel(wnd, es, FALSE, "");
 	}
 	es->x_offset = 0;
+	if (es->style & ES_MULTILINE) {
+		es->flags &= ~EF_UPDATE;
+	} else {
+		es->flags |= EF_UPDATE;
+	}
 	es->flags &= ~EF_MODIFIED;
-	es->flags &= ~EF_UPDATE;
 	EDIT_EM_SetSel(wnd, es, 0, 0, FALSE);
 	EDIT_EM_ScrollCaret(wnd, es);
 }
diff --git a/controls/listbox.c b/controls/listbox.c
index 9571034..c1ad9d2 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -2486,7 +2486,7 @@
 	break;
 
     case WM_NCCREATE:
-	if (TWEAK_Win95Look)
+	if (TWEAK_WineLook > WIN31_LOOK)
 	    wnd->dwExStyle |= WS_EX_CLIENTEDGE;
         return DefWindowProc32A( hwnd, msg, wParam, lParam );
 
diff --git a/controls/menu.c b/controls/menu.c
index 8940964..1cbb1c4 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -35,15 +35,6 @@
 #include "debug.h"
 
 
-UINT32  MENU_BarItemTopNudge;
-UINT32  MENU_BarItemLeftNudge;
-UINT32  MENU_ItemTopNudge;
-UINT32  MENU_ItemLeftNudge;
-UINT32  MENU_HighlightTopNudge;
-UINT32  MENU_HighlightLeftNudge;
-UINT32  MENU_HighlightBottomNudge;
-UINT32  MENU_HighlightRightNudge;
-
 /* internal popup menu window messages */
 
 #define MM_SETMENUHANDLE	(WM_USER + 0)
@@ -653,10 +644,10 @@
     {
         dwSize = GetTextExtent( hdc, lpitem->text, strlen(lpitem->text) );
         lpitem->rect.right  += LOWORD(dwSize);
-	if (TWEAK_Win95Look)
-            lpitem->rect.bottom += MAX (HIWORD(dwSize), sysMetrics[SM_CYMENU]- 1);
-        else
+	if (TWEAK_WineLook == WIN31_LOOK)
             lpitem->rect.bottom += MAX( HIWORD(dwSize), SYSMETRICS_CYMENU );
+        else
+            lpitem->rect.bottom += MAX (HIWORD(dwSize), sysMetrics[SM_CYMENU]- 1);
         lpitem->xTab = 0;
 
         if (menuBar) lpitem->rect.right += MENU_BAR_ITEMS_SPACE;
@@ -710,7 +701,7 @@
 	    if ((i != start) &&
 		(lpitem->fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
 
-	    if(TWEAK_Win95Look)
+	    if (TWEAK_WineLook > WIN31_LOOK)
 		++orgY;
 
 	    MENU_CalcItemSize( hdc, lpitem, hwndOwner, orgX, orgY, FALSE );
@@ -735,7 +726,7 @@
 	lppop->Height = MAX( lppop->Height, orgY );
     }
 
-    if(TWEAK_Win95Look)
+    if(TWEAK_WineLook > WIN31_LOOK)
 	lppop->Height++;
 
     lppop->Width  = maxX;
@@ -833,7 +824,7 @@
     if (lpitem->fType & MF_SYSMENU)
     {
 	if( !IsIconic32(hwnd) ) {
-	    if(TWEAK_Win95Look)
+	    if (TWEAK_WineLook > WIN31_LOOK)
 		NC_DrawSysButton95( hwnd, hdc,
 				    lpitem->fState &
 				    (MF_HILITE | MF_MOUSESELECT) );
@@ -874,7 +865,7 @@
     rect = lpitem->rect;
 
     /* Draw the background */
-    if(TWEAK_Win95Look) {
+    if (TWEAK_WineLook > WIN31_LOOK) {
 	rect.left += 2;
 	rect.right -= 2;
 
@@ -899,8 +890,13 @@
 
     if (!menuBar && (lpitem->fType & MF_MENUBARBREAK))
     {
-	if(TWEAK_Win95Look)
-	    TWEAK_DrawMenuSeparatorVert95(hdc, rect.left - 1, 3, height - 3);
+	/* vertical separator */
+	if (TWEAK_WineLook > WIN31_LOOK) {
+	    RECT32 rc = rect;
+	    rc.top = 3;
+	    rc.bottom = height - 3;
+	    DrawEdge32 (hdc, &rc, EDGE_ETCHED, BF_LEFT);
+	}
 	else {
 	    SelectObject32( hdc, GetSysColorPen32(COLOR_WINDOWFRAME) );
 	    MoveTo( hdc, rect.left, 0 );
@@ -909,10 +905,14 @@
     }
     if (lpitem->fType & MF_SEPARATOR)
     {
-	if(TWEAK_Win95Look)
-	    TWEAK_DrawMenuSeparatorHoriz95(hdc, rect.left + 1,
-					   rect.top + SEPARATOR_HEIGHT / 2 + 1,
-					   rect.right - 1);
+	/* horizontal separator */
+	if (TWEAK_WineLook > WIN31_LOOK) {
+	    RECT32 rc = rect;
+	    rc.left++;
+	    rc.right--;
+	    rc.top += SEPARATOR_HEIGHT / 2;
+	    DrawEdge32 (hdc, &rc, EDGE_ETCHED, BF_TOP);
+	}
 	else {
 	    SelectObject32( hdc, GetSysColorPen32(COLOR_WINDOWFRAME) );
 	    MoveTo( hdc, rect.left, rect.top + SEPARATOR_HEIGHT/2 );
@@ -1000,21 +1000,15 @@
 	    rect.left += MENU_BAR_ITEMS_SPACE / 2;
 	    rect.right -= MENU_BAR_ITEMS_SPACE / 2;
 	    i = strlen( lpitem->text );
-
-	    rect.top += MENU_BarItemTopNudge;
-	    rect.left += MENU_BarItemLeftNudge;
 	}
 	else
 	{
 	    for (i = 0; lpitem->text[i]; i++)
                 if ((lpitem->text[i] == '\t') || (lpitem->text[i] == '\b'))
                     break;
-
-	    rect.top += MENU_ItemTopNudge;
-	    rect.left += MENU_ItemLeftNudge;
 	}
 
-	if(!TWEAK_Win95Look || !(lpitem->fState & MF_GRAYED)) {
+	if((TWEAK_WineLook == WIN31_LOOK) || !(lpitem->fState & MF_GRAYED)) {
 	    DrawText32A( hdc, lpitem->text, i, &rect,
 			 DT_LEFT | DT_VCENTER | DT_SINGLELINE );
 	}
@@ -1083,7 +1077,7 @@
 	    POPUPMENU *menu;
 
 	    /* draw 3-d shade */
-	    if(!TWEAK_Win95Look) {
+	    if(TWEAK_WineLook == WIN31_LOOK) {
 		SelectObject32( hdc, hShadeBrush );
 		SetBkMode32( hdc, TRANSPARENT );
 		ropPrev = SetROP232( hdc, R2_MASKPEN );
@@ -1144,7 +1138,7 @@
     
     FillRect32(hDC, lprect, GetSysColorBrush32(COLOR_MENU) );
 
-    if(!TWEAK_Win95Look) {
+    if (TWEAK_WineLook == WIN31_LOOK) {
 	SelectObject32( hDC, GetSysColorPen32(COLOR_WINDOWFRAME) );
 	MoveTo( hDC, lprect->left, lprect->bottom );
 	LineTo32( hDC, lprect->right, lprect->bottom );
@@ -1362,10 +1356,10 @@
                                     hmenu) );
         }
     }
-    else if (sendMenuSelect)
+    else if (sendMenuSelect) {
         SendMessage16( hwndOwner, WM_MENUSELECT, hmenu,
                        MAKELONG( lppop->wFlags | MF_MOUSESELECT, hmenu ) ); 
-
+    }
     ReleaseDC32( lppop->hWnd, hdc );
 }
 
@@ -1476,7 +1470,10 @@
     item->fState = (flags & STATE_MASK) &
         ~(MF_HILITE | MF_MOUSESELECT | MF_BYPOSITION);
 
-    SetRectEmpty32( &item->rect );
+
+    /* Don't call SetRectEmpty here! */
+
+
     if (prevText) HeapFree( SystemHeap, 0, prevText );
 
     debug_print_menuitem("MENU_SetItemData to  : ", item, "");
@@ -1741,10 +1738,13 @@
 
     /* message must be send before using item,
        because nearly everything may by changed by the application ! */
-    rect = item->rect;
+
     SendMessage16( hwndOwner, WM_INITMENUPOPUP, (WPARAM16)item->hSubMenu,
 		   MAKELONG( menu->FocusedItem, IS_SYSTEM_MENU(menu) ));
 
+    item = &menu->items[menu->FocusedItem];
+    rect = item->rect;
+
     /* correct item if modified as a reaction to WM_INITMENUPOPUP-message */
     if (!(item->fState & MF_HILITE)) 
     {
diff --git a/controls/static.c b/controls/static.c
index 70c65f0..68e75f4 100644
--- a/controls/static.c
+++ b/controls/static.c
@@ -175,7 +175,7 @@
     switch (uMsg)
     {
     case WM_NCCREATE:
-	if (TWEAK_Win95Look && (wndPtr->dwStyle & SS_SUNKEN))
+	if ((TWEAK_WineLook > WIN31_LOOK) && (wndPtr->dwStyle & SS_SUNKEN))
 	    wndPtr->dwExStyle |= WS_EX_STATICEDGE;
 
         if (style == SS_ICON)
@@ -432,7 +432,8 @@
     HBRUSH32 hbrush;
     HPEN32 hpen;
 
-    if (!TWEAK_Win95Look) return;
+    if (TWEAK_WineLook == WIN31_LOOK)
+	return;
 
     GetClientRect32( wndPtr->hwndSelf, &rc );
     hbrush = SendMessage32A( GetParent32(wndPtr->hwndSelf), WM_CTLCOLORSTATIC,
diff --git a/debugger/break.c b/debugger/break.c
index 68dc588..04c269c 100644
--- a/debugger/break.c
+++ b/debugger/break.c
@@ -11,6 +11,8 @@
 #include <sys/mman.h>
 #include "module.h"
 #include "process.h"
+#include "task.h"
+#include "miscemu.h"
 #include "toolhelp.h"
 #include "windows.h"
 #include "debugger.h"
@@ -42,10 +44,7 @@
  */
 static void DEBUG_SetOpcode( const DBG_ADDR *addr, BYTE op )
 {
-    BYTE *ptr;
-
-    if (addr->seg) ptr = (BYTE *)PTR_SEG_OFF_TO_LIN( addr->seg, addr->off );
-    else ptr = (BYTE *)addr->off;
+    BYTE *ptr = DBG_ADDR_TO_LIN(addr);
 
     /* There are a couple of problems with this. On Linux prior to
        1.1.62, this call fails (ENOACCESS) due to a bug in fs/exec.c.
@@ -72,7 +71,8 @@
  */
 static BOOL32 DEBUG_IsStepOverInstr()
 {
-    BYTE *instr = (BYTE *)PTR_SEG_OFF_TO_LIN( CS_reg(&DEBUG_context),
+    BYTE *instr = (BYTE *)CTX_SEG_OFF_TO_LIN( &DEBUG_context,
+                                              CS_reg(&DEBUG_context),
                                               EIP_reg(&DEBUG_context) );
 
     for (;;)
@@ -138,7 +138,8 @@
  */
 BOOL32 DEBUG_IsFctReturn(void)
 {
-    BYTE *instr = (BYTE *)PTR_SEG_OFF_TO_LIN( CS_reg(&DEBUG_context),
+    BYTE *instr = (BYTE *)CTX_SEG_OFF_TO_LIN( &DEBUG_context,
+                                              CS_reg(&DEBUG_context),
                                               EIP_reg(&DEBUG_context) );
 
     for (;;)
@@ -346,9 +347,16 @@
         if (!(pModule = NE_GetPtr( entry.hModule ))) continue;
         if (pModule->flags & NE_FFLAGS_LIBMODULE) continue;  /* Library */
 
+        if (pModule->dos_image) { /* DOS module */
+            addr.seg = pModule->cs | ((DWORD)pModule->self << 16);
+            addr.off = pModule->ip;
+            fprintf( stderr, "DOS task '%s': ", entry.szModule );
+            DEBUG_AddBreakpoint( &addr );
+        } else
         if (!(pModule->flags & NE_FFLAGS_WIN32))  /* NE module */
         {
-            addr.seg = NE_SEG_TABLE(pModule)[pModule->cs-1].selector;
+            addr.seg =
+		GlobalHandleToSel(NE_SEG_TABLE(pModule)[pModule->cs-1].hSeg);
             addr.off = pModule->ip;
             fprintf( stderr, "Win16 task '%s': ", entry.szModule );
             DEBUG_AddBreakpoint( &addr );
@@ -395,14 +403,18 @@
     DBG_ADDR cond_addr;
     int bpnum;
     struct list_id list;
+    TDB *pTask = (TDB*)GlobalLock16( GetCurrentTask() );
 
       /* If not single-stepping, back up over the int3 instruction */
     if (!(EFL_reg(&DEBUG_context) & STEP_FLAG)) EIP_reg(&DEBUG_context)--;
 
     addr.seg = CS_reg(&DEBUG_context);
     addr.off = EIP_reg(&DEBUG_context);
+    if (ISV86(&DEBUG_context)) addr.seg |= (DWORD)(pTask?(pTask->hModule):0)<<16; else
     if (IS_SELECTOR_SYSTEM(addr.seg)) addr.seg = 0;
 
+    GlobalUnlock16( GetCurrentTask() );
+
     bpnum = DEBUG_FindBreakpoint( &addr );
     breakpoints[0].enabled = 0;  /* disable the step-over breakpoint */
 
@@ -519,11 +531,15 @@
     unsigned int * value;
     enum exec_mode ret_mode;
     BYTE *instr;
+    TDB *pTask = (TDB*)GlobalLock16( GetCurrentTask() );
 
     addr.seg = CS_reg(&DEBUG_context);
     addr.off = EIP_reg(&DEBUG_context);
+    if (ISV86(&DEBUG_context)) addr.seg |= (DWORD)(pTask?(pTask->hModule):0)<<16; else
     if (IS_SELECTOR_SYSTEM(addr.seg)) addr.seg = 0;
 
+    GlobalUnlock16( GetCurrentTask() );
+
     /*
      * This is the mode we will be running in after we finish.  We would like
      * to be able to modify this in certain cases.
@@ -555,7 +571,8 @@
 	mode = ret_mode = EXEC_STEPI_INSTR;
       }
 
-    instr = (BYTE *)PTR_SEG_OFF_TO_LIN( CS_reg(&DEBUG_context),
+    instr = (BYTE *)CTX_SEG_OFF_TO_LIN( &DEBUG_context,
+					CS_reg(&DEBUG_context),
 					EIP_reg(&DEBUG_context) );
     /*
      * See if the function we are stepping into has debug info
diff --git a/debugger/dbg.y b/debugger/dbg.y
index 9aa95f2..c56ce96 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -13,6 +13,7 @@
 #include "winbase.h"
 #include "class.h"
 #include "module.h"
+#include "task.h"
 #include "options.h"
 #include "queue.h"
 #include "win.h"
@@ -465,18 +466,22 @@
 						      &dbg_exec_count ))
     {
         DBG_ADDR addr;
+        TDB *pTask = (TDB*)GlobalLock16( GetCurrentTask() );
 
         addr.seg = CS_reg(&DEBUG_context);
         addr.off = EIP_reg(&DEBUG_context);
+        if (ISV86(&DEBUG_context)) addr.seg |= (DWORD)(pTask?(pTask->hModule):0)<<16;
 	addr.type = NULL;
         DBG_FIX_ADDR_SEG( &addr, 0 );
 
+        GlobalUnlock16( GetCurrentTask() );
+
         /* Put the display in a correct state */
 
-        XUngrabServer( display );
-        XFlush( display );
+        TSXUngrabServer( display );
+        TSXFlush( display );
 
-        newmode = IS_SELECTOR_32BIT(addr.seg) ? 32 : 16;
+        newmode = ISV86(&DEBUG_context) ? 16 : IS_SELECTOR_32BIT(addr.seg) ? 32 : 16;
         if (newmode != dbg_mode)
             fprintf(stderr,"In %d bit mode.\n", dbg_mode = newmode);
 
@@ -526,7 +531,7 @@
             issue_prompt();
             yyparse();
             flush_symbols();
-            addr.seg = CS_reg(&DEBUG_context);
+            addr.seg = CS_reg(&DEBUG_context) | (addr.seg&0xffff0000);
             addr.off = EIP_reg(&DEBUG_context);
             DBG_FIX_ADDR_SEG( &addr, 0 );
             ret_ok = DEBUG_ValidateRegisters();
@@ -565,6 +570,13 @@
 }
 
 
+void ctx_debug( int signal, CONTEXT *regs )
+{
+    DEBUG_context = *regs;
+    DEBUG_Main( signal );
+    *regs = DEBUG_context;
+}
+
 void wine_debug( int signal, SIGCONTEXT *regs )
 {
 #if 0
diff --git a/debugger/info.c b/debugger/info.c
index a1cb378..5dc6247 100644
--- a/debugger/info.c
+++ b/debugger/info.c
@@ -79,7 +79,7 @@
     const char *name = DEBUG_FindNearestSymbol( addr, flag, &rtn.sym, 0, 
 						&rtn.list );
 
-    if (addr->seg) fprintf( stderr, "0x%04lx:", addr->seg );
+    if (addr->seg) fprintf( stderr, "0x%04lx:", addr->seg&0xFFFF );
     if (addrlen == 16) fprintf( stderr, "0x%04lx", addr->off );
     else fprintf( stderr, "0x%08lx", addr->off );
     if (name) fprintf( stderr, " (%s)", name );
diff --git a/debugger/memory.c b/debugger/memory.c
index fbd5047..aa1dd71 100644
--- a/debugger/memory.c
+++ b/debugger/memory.c
@@ -99,6 +99,7 @@
  */
 BOOL32 DEBUG_IsBadReadPtr( const DBG_ADDR *address, int size )
 {
+    if (!IS_SELECTOR_V86(address->seg))
     if (address->seg)  /* segmented addr */
     {
         if (IsBadReadPtr16( (SEGPTR)MAKELONG( (WORD)address->off,
@@ -116,6 +117,7 @@
  */
 BOOL32 DEBUG_IsBadWritePtr( const DBG_ADDR *address, int size )
 {
+    if (!IS_SELECTOR_V86(address->seg))
     if (address->seg)  /* segmented addr */
     {
         /* Note: we use IsBadReadPtr here because we are */
diff --git a/debugger/registers.c b/debugger/registers.c
index b6a8a23..3a7edd1 100644
--- a/debugger/registers.c
+++ b/debugger/registers.c
@@ -156,6 +156,8 @@
     GET_GS( GS_reg(&DEBUG_context) );
     GS_reg(&DEBUG_context) &= 0xffff;
 #endif
+    if (ISV86(&DEBUG_context))
+        (char*)V86BASE(&DEBUG_context) = DOSMEM_MemoryBase(0);
 }
 
 
@@ -298,6 +300,8 @@
 {
     WORD cs, ds;
 
+    if (ISV86(&DEBUG_context)) return TRUE;
+
 /* Check that a selector is a valid ring-3 LDT selector, or a NULL selector */
 #define CHECK_SEG(seg,name) \
     if (((seg) & ~3) && \
@@ -319,6 +323,7 @@
 
     /* Check that CS and SS are not NULL */
 
+    if (!ISV86(&DEBUG_context))
     if (!(CS_reg(&DEBUG_context) & ~3))
     {
         fprintf( stderr, "*** Invalid value for CS register: %04x\n",
diff --git a/dlls/Makefile.in b/dlls/Makefile.in
index 67e3a95..ea8bc46 100644
--- a/dlls/Makefile.in
+++ b/dlls/Makefile.in
@@ -1,6 +1,9 @@
 SUBDIRS = \
 	comctl32 \
-	shell32
+	psapi \
+	shell32 \
+	winaspi \
+	wnaspi32
 
 all: $(SUBDIRS)
 
diff --git a/dlls/comctl32/animate.c b/dlls/comctl32/animate.c
index 9303711..9c2fc19 100644
--- a/dlls/comctl32/animate.c
+++ b/dlls/comctl32/animate.c
@@ -14,6 +14,8 @@
  */
 
 #include "windows.h"
+#include "winnt.h"
+#include "winbase.h"
 #include "commctrl.h"
 #include "animate.h"
 #include "win.h"
@@ -23,34 +25,136 @@
 #define ANIMATE_GetInfoPtr(wndPtr) ((ANIMATE_INFO *)wndPtr->wExtra[0])
 
 
+static BOOL32
+ANIMATE_LoadRes32A (ANIMATE_INFO *infoPtr, HINSTANCE32 hInst, LPSTR lpName)
+{
+    HRSRC32 hrsrc;
+    HGLOBAL32 handle;
+
+    hrsrc = FindResource32A (hInst, lpName, "AVI");
+    if (!hrsrc)
+	return FALSE;
+
+    handle = LoadResource32 (hInst, hrsrc);
+    if (!handle)
+	return FALSE;
+
+    infoPtr->lpAvi = LockResource32 (handle);
+    if (!infoPtr->lpAvi)
+	return FALSE;
+
+    return TRUE;
+}
+
+
+static BOOL32
+ANIMATE_LoadFile32A (ANIMATE_INFO *infoPtr, LPSTR lpName)
+{
+    HANDLE32 handle;
+
+    infoPtr->hFile =
+	CreateFile32A (lpName, GENERIC_READ, 0, NULL, OPEN_EXISTING,
+		       FILE_ATTRIBUTE_NORMAL, 0);
+    if (!infoPtr->hFile)
+	return FALSE;
+
+    handle =
+	CreateFileMapping32A (infoPtr->hFile, NULL, PAGE_READONLY | SEC_COMMIT,
+			      0, 0, NULL);
+    if (!handle) {
+	CloseHandle (infoPtr->hFile);
+	infoPtr->hFile = 0;
+	return FALSE;
+    }
+
+    infoPtr->lpAvi = MapViewOfFile (handle, FILE_MAP_READ, 0, 0, 0);
+    if (!infoPtr->lpAvi) {
+	CloseHandle (infoPtr->hFile);
+	infoPtr->hFile = 0;
+	return FALSE;
+    }
+
+    return TRUE;
+}
+
+
+static VOID
+ANIMATE_Free (ANIMATE_INFO *infoPtr)
+{
+    if (infoPtr->hFile) {
+	UnmapViewOfFile (infoPtr->lpAvi);
+	CloseHandle (infoPtr->hFile);
+	infoPtr->lpAvi = NULL;
+    }
+    else {
+	GlobalFree32 (infoPtr->lpAvi);
+	infoPtr->lpAvi = NULL;
+    }
+}
+
+
+static VOID
+ANIMATE_GetAviInfo (infoPtr)
+{
+
+
+}
+
+
 static LRESULT
 ANIMATE_Open32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(wndPtr);
+    HINSTANCE32 hInstance = (HINSTANCE32)wParam;
+
+    ANIMATE_Free (infoPtr);
 
     if (!lParam) {
-
-	FIXME (animate, "close avi: empty stub!\n");
-
+	TRACE (animate, "closing avi!\n");
 	return TRUE;
     }
     
     if (HIWORD(lParam)) {
-
 	FIXME (animate, "(\"%s\") empty stub!\n", (LPSTR)lParam);
 
+	if (ANIMATE_LoadRes32A (infoPtr, hInstance, (LPSTR)lParam)) {
+
+	    FIXME (animate, "AVI resource found!\n");
+
+	}
+	else {
+	    FIXME (animate, "No AVI resource found!\n");
+	    if (ANIMATE_LoadFile32A (infoPtr, (LPSTR)lParam)) {
+		FIXME (animate, "AVI file found!\n");
+	    }
+	    else {
+		FIXME (animate, "No AVI file found!\n");
+		return FALSE;
+	    }
+	}
     }
     else {
-
 	FIXME (animate, "(%u) empty stub!\n", (WORD)LOWORD(lParam));
 
+	if (ANIMATE_LoadRes32A (infoPtr, hInstance,
+				MAKEINTRESOURCE32A((INT32)lParam))) {
+	    FIXME (animate, "AVI resource found!\n");
+	}
+	else {
+	    FIXME (animate, "No AVI resource found!\n");
+	    return FALSE;
+	}
     }
 
+    ANIMATE_GetAviInfo (infoPtr);
 
     return TRUE;
 }
 
 
+// << ANIMATE_Open32W >>
+
+
 static LRESULT
 ANIMATE_Play (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
@@ -131,7 +235,8 @@
     ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(wndPtr);
 
 
-
+    /* free avi data */
+    ANIMATE_Free (infoPtr);
 
     /* free animate info data */
     COMCTL32_Free (infoPtr);
diff --git a/dlls/comctl32/comctl32undoc.c b/dlls/comctl32/comctl32undoc.c
index e45f77f..430dd67 100644
--- a/dlls/comctl32/comctl32undoc.c
+++ b/dlls/comctl32/comctl32undoc.c
@@ -10,7 +10,8 @@
  *     COMCTL32.DLL (internally).
  *
  * TODO
- *     - Write documentation.
+ *     - Add more functions.
+ *     - Write some documentation.
  */
 
 #include <string.h>
@@ -27,6 +28,22 @@
 
 
 /**************************************************************************
+ * COMCTL32_11 [COMCTL32.11]
+ */
+
+DWORD WINAPI
+COMCTL32_11 (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3,
+	     DWORD dwParam4, DWORD dwParam5, DWORD dwParam6)
+{
+
+    FIXME (commctrl, "(%08lx, %08lx, %08lx, %08lx, %08lx, %08lx): empty stub\n",
+	   dwParam1, dwParam2, dwParam3, dwParam4, dwParam5, dwParam6);
+
+    return 0;
+}
+
+
+/**************************************************************************
  * Alloc [COMCTL32.71]
  *
  * Allocates memory block from the dll's local heap
@@ -153,6 +170,25 @@
 
 
 /**************************************************************************
+ * The MRU-API is a set of functions to manipulate MRU(Most Recently Used)
+ * lists.
+ *
+ *
+ */
+
+typedef struct tagMRUINFO
+{
+    DWORD  dwParam1;
+    DWORD  dwParam2;
+    DWORD  dwParam3;
+    HKEY   hkeyMain;
+    LPCSTR lpszSubKey;
+    DWORD  dwParam6;
+} MRUINFO, *LPMRUINFO;
+ 
+
+
+/**************************************************************************
  * CreateMRUListA [COMCTL32.151]
  *
  * PARAMS
@@ -161,54 +197,233 @@
  * RETURNS
  */
 
-DWORD WINAPI
-CreateMRUList32A (DWORD dwParam)
+LPVOID WINAPI
+CreateMRUListEx32A (LPMRUINFO lpmi, DWORD dwParam2,
+		    DWORD dwParam3, DWORD dwParam4);
+
+LPVOID WINAPI
+CreateMRUList32A (LPMRUINFO lpmi)
 {
-
-    FIXME (commctrl, "(%lx)\n", dwParam);
-
-    return 1;
+     return CreateMRUListEx32A (lpmi, 0, 0, 0);
 }
 
 
 
+DWORD WINAPI
+FreeMRUList32A (LPVOID ptr)
+{
+    FIXME (commctrl, "(%p) empty stub!\n", ptr);
+
+    COMCTL32_Free (ptr);
+
+    return TRUE;
+}
+
+
+
+
+
+
+LPVOID WINAPI
+CreateMRUListEx32A (LPMRUINFO lpmi, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4)
+{
+    DWORD  dwLocal1;
+    HKEY   hkeyResult;
+    DWORD  dwLocal3;
+    LPVOID lMRU;
+    DWORD  dwLocal5;
+    DWORD  dwLocal6;
+    DWORD  dwLocal7;
+    DWORD  dwDisposition;
+
+    /* internal variables */
+    LPVOID ptr;
+
+    FIXME (commctrl, "(%p) empty stub!\n", lpmi);
+
+    if (lpmi) {
+	FIXME (commctrl, "(%lx %lx %lx %lx \"%s\" %lx)\n",
+	       lpmi->dwParam1, lpmi->dwParam2, lpmi->dwParam3,
+	       lpmi->hkeyMain, lpmi->lpszSubKey, lpmi->dwParam6);
+    }
+
+    /* dummy pointer creation */
+    ptr = COMCTL32_Alloc (32);
+
+    FIXME (commctrl, "-- ret = %p\n", ptr);
+
+    return ptr;
+}
+
+
+
+DWORD WINAPI
+AddMRUData (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
+{
+
+    FIXME (commctrl, "(%lx %lx %lx) empty stub!\n",
+	   dwParam1, dwParam2, dwParam3);
+
+    return 0;
+}
+
+
+DWORD WINAPI
+FindMRUData (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4)
+{
+
+    FIXME (commctrl, "(%lx %lx %lx %lx) empty stub!\n",
+	   dwParam1, dwParam2, dwParam3, dwParam4);
+
+    return -1;
+}
+
+
+
+/**************************************************************************
+ * Str_GetPtrA [COMCTL32.233]
+ *
+ * PARAMS
+ *     lpSrc   [I]
+ *     lpDest  [O]
+ *     nMaxLen [I]
+ *
+ * RETURNS
+ */
+
+INT32 WINAPI
+Str_GetPtr32A (LPCSTR lpSrc, LPSTR lpDest, INT32 nMaxLen)
+{
+    INT32 len;
+
+    TRACE (commctrl, "(%p %p %d)\n", lpSrc, lpDest, nMaxLen);
+
+    if (!lpDest && lpSrc)
+	return lstrlen32A (lpSrc);
+
+    if (nMaxLen == 0)
+	return 0;
+
+    if (lpSrc == NULL) {
+	lpDest[0] = '\0';
+	return 0;
+    }
+
+    len = lstrlen32A (lpSrc);
+    if (len >= nMaxLen)
+	len = nMaxLen - 1;
+
+    RtlMoveMemory (lpDest, lpSrc, len);
+    lpDest[len] = '\0';
+
+    return len;
+}
+
 
 /**************************************************************************
  * Str_SetPtrA [COMCTL32.234]
  *
  * PARAMS
- *     dwParam1 [I]
- *     dwParam2 [I]
+ *     lppDest [O]
+ *     lpSrc   [I]
  *
  * RETURNS
  */
 
 BOOL32 WINAPI
-COMCTL32_Str_SetPtrA (LPSTR lpStr, LPVOID *lpPtr)
+Str_SetPtr32A (LPSTR *lppDest, LPCSTR lpSrc)
+{
+    TRACE (commctrl, "(%p %p)\n", lppDest, lpSrc);
+ 
+    if (lpSrc) {
+	LPSTR ptr = COMCTL32_ReAlloc (lppDest, lstrlen32A (lpSrc) + 1);
+	if (!ptr)
+	    return FALSE;
+	lstrcpy32A (ptr, lpSrc);
+	*lppDest = ptr;
+    }
+    else {
+	if (*lppDest) {
+	    COMCTL32_Free (*lppDest);
+	    *lppDest = NULL;
+	}
+    }
+
+    return TRUE;
+}
+
+
+/**************************************************************************
+ * Str_GetPtrW [COMCTL32.235]
+ *
+ * PARAMS
+ *     lpSrc   [I]
+ *     lpDest  [O]
+ *     nMaxLen [I]
+ *
+ * RETURNS
+ */
+
+INT32 WINAPI
+Str_GetPtr32W (LPCWSTR lpSrc, LPWSTR lpDest, INT32 nMaxLen)
 {
     INT32 len;
-    LPSTR ptr;
 
-    TRACE (commctrl, "(%p %p)\n", lpStr, lpPtr);
+    TRACE (commctrl, "(%p %p %d)\n", lpSrc, lpDest, nMaxLen);
+
+    if (!lpDest && lpSrc)
+	return lstrlen32W (lpSrc);
+
+    if (nMaxLen == 0)
+	return 0;
+
+    if (lpSrc == NULL) {
+	lpDest[0] = L'\0';
+	return 0;
+    }
+
+    len = lstrlen32W (lpSrc);
+    if (len >= nMaxLen)
+	len = nMaxLen - 1;
+
+    RtlMoveMemory (lpDest, lpSrc, len*sizeof(WCHAR));
+    lpDest[len] = L'\0';
+
+    return len;
+}
+
+
+/**************************************************************************
+ * Str_SetPtrW [COMCTL32.236]
+ *
+ * PARAMS
+ *     lpDest [O]
+ *     lpSrc  [I]
+ *
+ * RETURNS
+ */
+
+BOOL32 WINAPI
+Str_SetPtr32W (LPWSTR *lppDest, LPCWSTR lpSrc)
+{
+    TRACE (commctrl, "(%p %p)\n", lppDest, lpSrc);
  
-    if (lpStr) {
-	len = lstrlen32A (lpStr);
-	ptr = COMCTL32_ReAlloc (lpPtr, len + 1);
-	if (!(ptr))
+    if (lpSrc) {
+	INT32 len = lstrlen32W (lpSrc) + 1;
+	LPWSTR ptr = COMCTL32_ReAlloc (lppDest, len * sizeof(WCHAR));
+	if (!ptr)
 	    return FALSE;
-	lstrcpy32A (ptr, lpStr);
-	if (!lpPtr)
-	    return FALSE;
-	*lpPtr = ptr;
-	return TRUE;
+	lstrcpy32W (ptr, lpSrc);
+	*lppDest = ptr;
+    }
+    else {
+	if (*lppDest) {
+	    COMCTL32_Free (*lppDest);
+	    *lppDest = NULL;
+	}
     }
 
-    if (*lpPtr) {
-	COMCTL32_Free (*lpPtr);
-	return TRUE;
-    }
-
-    return FALSE;
+    return TRUE;
 }
 
 
@@ -636,7 +851,7 @@
 BOOL32 WINAPI
 DPA_Grow (const HDPA hdpa, INT32 nGrow)
 {
-    FIXME (commctrl, "(%p %d) stub!\n", hdpa, nGrow);
+    TRACE (commctrl, "(%p %d)\n", hdpa, nGrow);
 
     if (!hdpa)
 	return FALSE;
@@ -676,7 +891,7 @@
     if (!hdpa)
 	return NULL;
 
-    FIXME (commctrl, "(%p %p) stub!\n", hdpa, hdpaNew);
+    TRACE (commctrl, "(%p %p)\n", hdpa, hdpaNew);
 
     if (!hdpaNew) {
 	/* create a new DPA */
@@ -1019,7 +1234,7 @@
     LPVOID t, v;
     INT32  i, j;
 
-    if (l > r) {
+    if (r > l) {
 	v = lpPtrs[r];
 	i = l - 1;
 	j = r;
@@ -1064,7 +1279,9 @@
 
     TRACE (commctrl, "(%p %p 0x%lx)\n", hdpa, pfnCompare, lParam);
 
-    DPA_QuickSort (hdpa->ptrs, 0, hdpa->nItemCount - 1, pfnCompare, lParam);
+    if ((hdpa->nItemCount > 1) && (hdpa->ptrs))
+	DPA_QuickSort (hdpa->ptrs, 0, hdpa->nItemCount - 1,
+		       pfnCompare, lParam);
 
     return TRUE;
 }
@@ -1107,6 +1324,8 @@
 	INT32 l, r, x, n;
 	LPVOID *lpPtr;
 
+	TRACE (commctrl, "binary search\n");
+
 	l = (nStart == -1) ? 0 : nStart;
 	r = hdpa->nItemCount - 1;
 	lpPtr = hdpa->ptrs;
@@ -1138,7 +1357,7 @@
 	LPVOID *lpPtr;
 	INT32  nIndex;
 
-	FIXME (commctrl, "linear search\n");
+	TRACE (commctrl, "linear search\n");
 	
 	nIndex = (nStart == -1)? 0 : nStart;
 	lpPtr = hdpa->ptrs;
@@ -1267,3 +1486,63 @@
     return atoi(lpString);
 }
 
+
+/**************************************************************************
+ * COMCTL32_385 [COMCTL32.385]
+ */
+
+DWORD WINAPI
+COMCTL32_385 (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
+{
+
+    FIXME (commctrl, "(%08lx, %08lx, %08lx): empty stub\n",
+	   dwParam1, dwParam2, dwParam3);
+
+    return 0;
+}
+
+
+/**************************************************************************
+ * COMCTL32_386 [COMCTL32.386]
+ */
+
+DWORD WINAPI
+COMCTL32_386 (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
+{
+
+    FIXME (commctrl, "(%08lx, %08lx, %08lx): empty stub\n",
+	   dwParam1, dwParam2, dwParam3);
+
+    return 0;
+}
+
+
+/**************************************************************************
+ * COMCTL32_387 [COMCTL32.387]
+ */
+
+DWORD WINAPI
+COMCTL32_387 (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
+{
+
+    FIXME (commctrl, "(%08lx, %08lx, %08lx): empty stub\n",
+	   dwParam1, dwParam2, dwParam3);
+
+    return 0;
+}
+
+
+/**************************************************************************
+ * COMCTL32_388 [COMCTL32.388]
+ */
+
+DWORD WINAPI
+COMCTL32_388 (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
+{
+
+    FIXME (commctrl, "(%08lx, %08lx, %08lx): empty stub\n",
+	   dwParam1, dwParam2, dwParam3);
+
+    return 0;
+}
+
diff --git a/dlls/comctl32/commctrl.c b/dlls/comctl32/commctrl.c
index 0c6f00e..b0b5c7c 100644
--- a/dlls/comctl32/commctrl.c
+++ b/dlls/comctl32/commctrl.c
@@ -32,10 +32,13 @@
  * ComCtl32LibMain [Internal] Initializes the internal 'COMCTL32.DLL'.
  *
  * PARAMS
- *     hinstDLL    [I]
+ *     hinstDLL    [I] handle to the 'dlls' instance
  *     fdwReason   [I]
  *     lpvReserved [I]
  *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
  */
 
 BOOL32 WINAPI
@@ -68,59 +71,64 @@
  * MenuHelp [COMCTL32.2]
  *
  * PARAMS
- *     uMsg
- *     wParam
- *     lParam
- *     hMainMenu
- *     hInst
- *     hwndStatus
- *     lpwIDs
+ *     uMsg       [I]
+ *     wParam     [I]
+ *     lParam     [I]
+ *     hMainMenu  [I] handle to the applications main menu
+ *     hInst      [I]
+ *     hwndStatus [I] handle to the status bar window
+ *     lpwIDs     [I] pointer to an array of intergers (see NOTES)
  *
  * RETURNS
- *     None
+ *     No return value
  *
  * NOTES
- *     Some features are still missing because of incomplete WM_MENUSELECT
- *     messages (16->32 bit conversion).
+ *     The official documentation is incomplete!
  */
 
 VOID WINAPI
 MenuHelp (UINT32 uMsg, WPARAM32 wParam, LPARAM lParam, HMENU32 hMainMenu,
 	  HINSTANCE32 hInst, HWND32 hwndStatus, LPUINT32 lpwIDs)
 {
-    char szStatusText[128];
+    UINT32 uMenuID = 0;
 
-    if (!IsWindow32 (hwndStatus)) return;
+    if (!IsWindow32 (hwndStatus))
+	return;
 
     switch (uMsg) {
 	case WM_MENUSELECT:
-            TRACE (commctrl, "WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
-                   wParam, lParam);
+	    TRACE (commctrl, "WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
+		   wParam, lParam);
 
             if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
                 /* menu was closed */
+		TRACE (commctrl, "menu was closed!\n");
                 SendMessage32A (hwndStatus, SB_SIMPLE, FALSE, 0);
             }
-            else {
-                if (HIWORD(wParam) & MF_POPUP) {
-		    FIXME (commctrl, "popup 0x%08x 0x%08lx\n", wParam, lParam);
+	    else {
+		/* menu item was selected */
+		if (HIWORD(wParam) & MF_POPUP)
+		    uMenuID = (UINT32)*(lpwIDs+1);
+		else
+		    uMenuID = (UINT32)LOWORD(wParam);
+		TRACE (commctrl, "uMenuID = %u\n", uMenuID);
 
-                    szStatusText[0] = 0;
-                }
-                else {
-                    TRACE (commctrl, "menu item selected!\n");
-                    if (!LoadString32A (hInst, LOWORD(wParam), szStatusText, 128))
-                        szStatusText[0] = 0;
-                }
-                SendMessage32A (hwndStatus, SB_SETTEXT32A, 255 | SBT_NOBORDERS,
-                                (LPARAM)szStatusText);
-                SendMessage32A (hwndStatus, SB_SIMPLE, TRUE, 0);
-            }
-            break;
+		if (uMenuID) {
+		    CHAR szText[256];
 
-        default:
-            WARN (commctrl, "Invalid Message!\n");
-            break;
+		    if (!LoadString32A (hInst, uMenuID, szText, 256))
+			szText[0] = 0;
+
+		    SendMessage32A (hwndStatus, SB_SETTEXT32A,
+				    255 | SBT_NOBORDERS, (LPARAM)szText);
+		    SendMessage32A (hwndStatus, SB_SIMPLE, TRUE, 0);
+		}
+	    }
+	    break;
+
+	default:
+	    WARN (commctrl, "Invalid Message!\n");
+	    break;
     }
 }
 
@@ -198,10 +206,10 @@
  *     lpInfo [I] pointer to an array of integers
  *
  * RETURNS
- *     None.
+ *     No return value.
  *
  * NOTES
- *
+ *     The official documentation is incomplete!
  */
 
 VOID WINAPI
@@ -244,6 +252,9 @@
  *     lprc  [I] pointer to a rectangle
  *     text  [I] pointer to the text
  *     style [I] 
+ *
+ * RETURNS
+ *     No return value.
  */
 
 VOID WINAPI
@@ -281,6 +292,9 @@
  *     lprc  [I] pointer to a rectangle
  *     text  [I] pointer to the text
  *     style [I] 
+ *
+ * RETURNS
+ *     No return value.
  */
 
 VOID WINAPI
@@ -293,8 +307,19 @@
 
 
 /***********************************************************************
- * CreateStatusWindow32A [COMCTL32.6][COMCTL32.21]
+ * CreateStatusWindow32A [COMCTL32.6][COMCTL32.21] Creates a status bar
+ *
+ * PARAMS
+ *     style  [I]
+ *     text   [I]
+ *     parent [I] handle to the parent window
+ *     wid    [I]
+ *
+ * RETURNS
+ *     Success: handle to the control
+ *     Failure: 0
  */
+
 HWND32 WINAPI
 CreateStatusWindow32A (INT32 style, LPCSTR text, HWND32 parent, UINT32 wid)
 {
@@ -306,20 +331,51 @@
 
 
 /***********************************************************************
- *           CreateStatusWindow32W   (COMCTL32.22)
+ * CreateStatusWindow32W [COMCTL32.22] Creates a status bar control
+ *
+ * PARAMS
+ *     style  [I]
+ *     text   [I]
+ *     parent [I]
+ *     wid    [I]
+ *
+ * RETURNS
+ *     Success: handle to the control
+ *     Failure: 0
  */
-HWND32 WINAPI CreateStatusWindow32W( INT32 style, LPCWSTR text, HWND32 parent,
-                                     UINT32 wid )
+
+HWND32 WINAPI
+CreateStatusWindow32W (INT32 style, LPCWSTR text, HWND32 parent, UINT32 wid)
 {
-    return CreateWindow32W((LPCWSTR)STATUSCLASSNAME32W, text, style, 
+    return CreateWindow32W((LPCWSTR)STATUSCLASSNAME32W, text, style,
 			   CW_USEDEFAULT32, CW_USEDEFAULT32,
-			   CW_USEDEFAULT32, CW_USEDEFAULT32, 
+			   CW_USEDEFAULT32, CW_USEDEFAULT32,
 			   parent, wid, 0, 0);
 }
 
+
 /***********************************************************************
- *           CreateUpDownControl  (COMCTL32.16)
+ * CreateUpDownControl [COMCTL32.16] Creates an Up-Down control
+ *
+ * PARAMS
+ *     style
+ *     x
+ *     y
+ *     cx
+ *     cy
+ *     parent
+ *     id
+ *     inst
+ *     buddy
+ *     maxVal [I]
+ *     minVal [I]
+ *     curVal [I]
+ *
+ * RETURNS
+ *     Success: handle to the control
+ *     Failure: 0
  */
+
 HWND32 WINAPI
 CreateUpDownControl (DWORD style, INT32 x, INT32 y, INT32 cx, INT32 cy,
 		     HWND32 parent, INT32 id, HINSTANCE32 inst,
@@ -344,7 +400,10 @@
  * Registers the common controls.
  *
  * PARAMS
- *     None.
+ *     No parameters.
+ *
+ * RETURNS
+ *     No return values.
  *
  * NOTES
  *     This function is just a dummy.
@@ -364,7 +423,11 @@
  * Registers the common controls.
  *
  * PARAMS
- *     lpInitCtrls [I] pointer to a INITCOMMONCONTROLS structure.
+ *     lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
  *
  * NOTES
  *     Only the additinal common controls are registered by this function.
@@ -399,37 +462,36 @@
 	    case ICC_HOTKEY_CLASS:
 		break;
 
-      /* advanced classes - not included in Win95 */
-      case ICC_DATE_CLASSES:
-        TRACE (commctrl, "No month calendar class implemented!\n");
-        TRACE (commctrl, "No date picker class implemented!\n");
-        TRACE (commctrl, "No time picker class implemented!\n");
-        UPDOWN_Register ();
-        break;
+	    /* advanced classes - not included in Win95 */
+	    case ICC_DATE_CLASSES:
+		FIXME (commctrl, "No month calendar class implemented!\n");
+		FIXME (commctrl, "No date picker class implemented!\n");
+		FIXME (commctrl, "No time picker class implemented!\n");
+		break;
 
-      case ICC_USEREX_CLASSES:
-	COMBOEX_Register ();
-        break;
+	    case ICC_USEREX_CLASSES:
+		COMBOEX_Register ();
+		break;
 
-      case ICC_COOL_CLASSES:
-	REBAR_Register ();
-        break;
+	    case ICC_COOL_CLASSES:
+		REBAR_Register ();
+		break;
 
-      case ICC_INTERNET_CLASSES:
-        TRACE (commctrl, "No IPAddress class implemented!\n");
-        break;
+	    case ICC_INTERNET_CLASSES:
+		FIXME (commctrl, "No IPAddress class implemented!\n");
+		break;
 
-      case ICC_PAGESCROLLER_CLASS:
-	PAGER_Register ();
-        break;
+	    case ICC_PAGESCROLLER_CLASS:
+		PAGER_Register ();
+		break;
 
-      case ICC_NATIVEFNTCTL_CLASS:
-        TRACE (commctrl, "No native font class implemented!\n");
-        break;
+	    case ICC_NATIVEFNTCTL_CLASS:
+		FIXME (commctrl, "No native font class implemented!\n");
+		break;
 
-      default:
-        WARN (commctrl, "Unknown class! dwICC=0x%lX\n", dwMask);
-        break;
+	    default:
+		WARN (commctrl, "Unknown class! dwICC=0x%lX\n", dwMask);
+		break;
 	}
     }
 
@@ -438,10 +500,26 @@
 
 
 /***********************************************************************
- * CreateToolbarEx [COMCTL32.32]
+ * CreateToolbarEx [COMCTL32.32] Creates a tool bar window
  *
+ * PARAMS
+ *     hwnd
+ *     style
+ *     wID
+ *     nBitmaps
+ *     hBMInst
+ *     wBMID
+ *     lpButtons
+ *     iNumButtons
+ *     dxButton
+ *     dyButton
+ *     dxBitmap
+ *     dyBitmap
+ *     uStructSize
  *
- *
+ * RETURNS
+ *     Success: handle to the tool bar control
+ *     Failure: 0
  */
 
 HWND32 WINAPI
@@ -600,10 +678,24 @@
 
 
 /***********************************************************************
- * CreateToolbar [COMCTL32.7]
+ * CreateToolbar [COMCTL32.7] Creates a tool bar control
  *
+ * PARAMS
+ *     hwnd
+ *     style
+ *     wID
+ *     nBitmaps
+ *     hBMInst
+ *     wBMID
+ *     lpButtons
+ *     iNumButtons
  *
+ * RETURNS
+ *     Success: handle to the tool bar control
+ *     Failure: 0
  *
+ * NOTES
+ *     Do not use this functions anymore. Use CreateToolbarEx instead.
  */
 
 HWND32 WINAPI
@@ -625,22 +717,25 @@
  * PARAMS
  *     pdvi [O] pointer to version information structure.
  *
- * REURNS
+ * RETURNS
  *     Success: S_OK
  *     Failure: E_INVALIDARG
+ *
+ * NOTES
+ *     Returns version of a comctl32.dll from IE4.01 SP1.
  */
 
 HRESULT WINAPI
 COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)
 {
     if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
-        WARN(ver, "wrong DLLVERSIONINFO size from app");
+        WARN (commctrl, "wrong DLLVERSIONINFO size from app");
 	return E_INVALIDARG;
     }
 
     pdvi->dwMajorVersion = 4;
     pdvi->dwMinorVersion = 72;
-    pdvi->dwBuildNumber = 2106;
+    pdvi->dwBuildNumber = 3110;
     pdvi->dwPlatformID = 1;
 
     TRACE (commctrl, "%lu.%lu.%lu.%lu\n",
diff --git a/dlls/comctl32/header.c b/dlls/comctl32/header.c
index 813512c..a2d86fc 100644
--- a/dlls/comctl32/header.c
+++ b/dlls/comctl32/header.c
@@ -5,7 +5,7 @@
  *
  *  TODO:
  *   - Imagelist support (partially).
- *   - Callback items.
+ *   - Callback items (under construction).
  *   - Order list support.
  *   - Control specific cursors (over dividers).
  *   - Hottrack support (partially).
@@ -22,7 +22,6 @@
 #include "windows.h"
 #include "commctrl.h"
 #include "header.h"
-#include "heap.h"
 #include "win.h"
 #include "debug.h"
 
@@ -446,7 +445,7 @@
 HEADER_SendHeaderNotify (WND *wndPtr, UINT32 code, INT32 iItem)
 {
     HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);   
-    NMHEADERA nmhdr;
+    NMHEADER32A nmhdr;
     HDITEM32A nmitem;
 
     nmhdr.hdr.hwndFrom = wndPtr->hwndSelf;
@@ -455,11 +454,13 @@
     nmhdr.iItem = iItem;
     nmhdr.iButton = 0;
     nmhdr.pitem = &nmitem;
-    nmitem.mask = infoPtr->items[iItem].mask;
+    nmitem.mask = 0;
     nmitem.cxy = infoPtr->items[iItem].cxy;
     nmitem.hbm = infoPtr->items[iItem].hbm;
-    nmitem.pszText = infoPtr->items[iItem].pszText;
-    nmitem.cchTextMax = infoPtr->items[iItem].cchTextMax;
+    nmitem.pszText = NULL;
+    nmitem.cchTextMax = 0;
+//    nmitem.pszText = infoPtr->items[iItem].pszText;
+//    nmitem.cchTextMax = infoPtr->items[iItem].cchTextMax;
     nmitem.fmt = infoPtr->items[iItem].fmt;
     nmitem.lParam = infoPtr->items[iItem].lParam;
     nmitem.iOrder = infoPtr->items[iItem].iOrder;
@@ -473,7 +474,7 @@
 static BOOL32
 HEADER_SendClickNotify (WND *wndPtr, UINT32 code, INT32 iItem)
 {
-    NMHEADERA nmhdr;
+    NMHEADER32A nmhdr;
 
     nmhdr.hdr.hwndFrom = wndPtr->hwndSelf;
     nmhdr.hdr.idFrom = wndPtr->wIDmenu;
@@ -499,21 +500,19 @@
 HEADER_DeleteItem (WND *wndPtr, WPARAM32 wParam)
 {
     HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
+    INT32 iItem = (INT32)wParam;
     HDC32 hdc;
-    INT32 iItem;
-
-    iItem = (INT32)wParam;
 
     TRACE(header, "[iItem=%d]\n", iItem);
     
-    if ((iItem < 0) || (iItem > infoPtr->uNumItem - 1))
+    if ((iItem < 0) || (iItem >= (INT32)infoPtr->uNumItem))
         return FALSE;
 
     if (infoPtr->uNumItem == 1) {
         TRACE(header, "Simple delete!\n");
         if (infoPtr->items[0].pszText)
-            HeapFree (GetProcessHeap (), 0, infoPtr->items[0].pszText);
-        HeapFree (GetProcessHeap (), 0, infoPtr->items);
+            COMCTL32_Free (infoPtr->items[0].pszText);
+        COMCTL32_Free (infoPtr->items);
         infoPtr->items = 0;
         infoPtr->uNumItem = 0;
     }
@@ -522,11 +521,10 @@
         TRACE(header, "Complex delete! [iItem=%d]\n", iItem);
 
         if (infoPtr->items[iItem].pszText)
-            HeapFree (GetProcessHeap (), 0, infoPtr->items[iItem].pszText);
+            COMCTL32_Free (infoPtr->items[iItem].pszText);
 
         infoPtr->uNumItem--;
-        infoPtr->items = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-                                    sizeof (HEADER_ITEM) * infoPtr->uNumItem);
+        infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem);
         /* pre delete copy */
         if (iItem > 0) {
             memcpy (&infoPtr->items[0], &oldItems[0],
@@ -539,7 +537,7 @@
                     (infoPtr->uNumItem - iItem) * sizeof(HEADER_ITEM));
         }
 
-        HeapFree (GetProcessHeap (), 0, oldItems);
+        COMCTL32_Free (oldItems);
     }
 
     HEADER_SetItemBounds (wndPtr);
@@ -565,60 +563,45 @@
 HEADER_GetItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
-    HDITEM32A *phdi;
-    INT32     iItem;
-    UINT32    uMask;
+    HDITEM32A   *phdi = (HDITEM32A*)lParam;
+    INT32       nItem = (INT32)wParam;
+    HEADER_ITEM *lpItem;
 
-    phdi = (HDITEM32A*)lParam;
-    iItem = (INT32)wParam;
-
-    if (phdi == NULL)
+    if (!phdi)
 	return FALSE;
-    if ((iItem < 0) || (iItem > infoPtr->uNumItem - 1))
+    if ((nItem < 0) || (nItem >= (INT32)infoPtr->uNumItem))
         return FALSE;
 
-    TRACE (header, "[iItem=%d]\n", iItem);
+    TRACE (header, "[nItem=%d]\n", nItem);
 
-    uMask = phdi->mask;
-    if (uMask == 0)
+    if (phdi->mask == 0)
 	return TRUE;
-    phdi->mask = 0;
 
-    if (uMask & infoPtr->items[iItem].mask & HDI_BITMAP) {
-	phdi->hbm = infoPtr->items[iItem].hbm;
-        phdi->mask |= HDI_BITMAP;
+    lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
+    if (phdi->mask & HDI_BITMAP)
+	phdi->hbm = lpItem->hbm;
+
+    if (phdi->mask & HDI_FORMAT)
+	phdi->fmt = lpItem->fmt;
+
+    if (phdi->mask & HDI_WIDTH)
+	phdi->cxy = lpItem->cxy;
+
+    if (phdi->mask & HDI_LPARAM)
+	phdi->lParam = lpItem->lParam;
+
+    if (phdi->mask & HDI_TEXT) {
+	if (lpItem->pszText != LPSTR_TEXTCALLBACK32A)
+	    lstrcpyn32A (phdi->pszText, lpItem->pszText, phdi->cchTextMax);
+	else
+	    phdi->pszText = LPSTR_TEXTCALLBACK32A;
     }
 
-    if (uMask & infoPtr->items[iItem].mask & HDI_FORMAT) {
-	phdi->fmt = infoPtr->items[iItem].fmt;
-        phdi->mask |= HDI_FORMAT;
-    }
+    if (phdi->mask & HDI_IMAGE)
+	phdi->iImage = lpItem->iImage;
 
-    if (uMask & infoPtr->items[iItem].mask & HDI_WIDTH) {
-	phdi->cxy = infoPtr->items[iItem].cxy;
-        phdi->mask |= HDI_WIDTH;
-    }
-
-    if (uMask & infoPtr->items[iItem].mask & HDI_LPARAM) {
-	phdi->lParam = infoPtr->items[iItem].lParam;
-        phdi->mask |= HDI_LPARAM;
-    }
-
-    if (uMask & infoPtr->items[iItem].mask & HDI_TEXT) {
-	phdi->pszText = infoPtr->items[iItem].pszText;
-	phdi->cchTextMax = infoPtr->items[iItem].cchTextMax;
-        phdi->mask |= HDI_TEXT;
-    }
-
-    if (uMask & infoPtr->items[iItem].mask & HDI_IMAGE) {
-	phdi->iImage = infoPtr->items[iItem].iImage;
-        phdi->mask |= HDI_IMAGE;
-    }
-
-    if (uMask & infoPtr->items[iItem].mask & HDI_ORDER) {
-	phdi->iOrder = infoPtr->items[iItem].iOrder;
-        phdi->mask |= HDI_ORDER;
-    }
+    if (phdi->mask & HDI_ORDER)
+	phdi->iOrder = lpItem->iOrder;
 
     return TRUE;
 }
@@ -637,13 +620,10 @@
 HEADER_GetItemRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
-    INT32 iItem;
-    LPRECT32 lpRect;
+    INT32 iItem = (INT32)wParam;
+    LPRECT32 lpRect = (LPRECT32)lParam;
 
-    iItem = (INT32)wParam;
-    lpRect = (LPRECT32)lParam;
-
-    if ((iItem < 0) || (iItem > infoPtr->uNumItem - 1))
+    if ((iItem < 0) || (iItem >= (INT32)infoPtr->uNumItem))
         return FALSE;
 
     lpRect->left   = infoPtr->items[iItem].rect.left;
@@ -670,70 +650,72 @@
 HEADER_InsertItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
-    HDITEM32A *phdi = (HDITEM32A*)lParam;
-    INT32     iItem = (INT32)wParam;
-    HDC32     hdc;
-    INT32     len;
+    HDITEM32A   *phdi = (HDITEM32A*)lParam;
+    INT32       nItem = (INT32)wParam;
+    HEADER_ITEM *lpItem;
+    HDC32       hdc;
+    INT32       len;
 
-    if (phdi == NULL) return -1;
-    if (iItem < 0) return -1;
-    if (iItem > infoPtr->uNumItem)
-        iItem = infoPtr->uNumItem;
+    if ((phdi == NULL) || (nItem < 0))
+	return -1;
+
+    if (nItem > infoPtr->uNumItem)
+        nItem = infoPtr->uNumItem;
 
     if (infoPtr->uNumItem == 0) {
-        infoPtr->items = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-                                    sizeof (HEADER_ITEM));
+        infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM));
         infoPtr->uNumItem++;
     }
     else {
         HEADER_ITEM *oldItems = infoPtr->items;
 
         infoPtr->uNumItem++;
-        infoPtr->items = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-                                    sizeof (HEADER_ITEM) * infoPtr->uNumItem);
+        infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem);
         /* pre insert copy */
-        if (iItem > 0) {
+        if (nItem > 0) {
             memcpy (&infoPtr->items[0], &oldItems[0],
-                    iItem * sizeof(HEADER_ITEM));
+                    nItem * sizeof(HEADER_ITEM));
         }
 
         /* post insert copy */
-        if (iItem < infoPtr->uNumItem - 1) {
-            memcpy (&infoPtr->items[iItem+1], &oldItems[iItem],
-                    (infoPtr->uNumItem - iItem) * sizeof(HEADER_ITEM));
+        if (nItem < infoPtr->uNumItem - 1) {
+            memcpy (&infoPtr->items[nItem+1], &oldItems[nItem],
+                    (infoPtr->uNumItem - nItem) * sizeof(HEADER_ITEM));
         }
 
-        HeapFree (GetProcessHeap (), 0, oldItems);
+	COMCTL32_Free (oldItems);
     }
 
-    infoPtr->items[iItem].bDown = FALSE;
+    lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
+    lpItem->bDown = FALSE;
 
-    infoPtr->items[iItem].mask = phdi->mask;
     if (phdi->mask & HDI_WIDTH)
-        infoPtr->items[iItem].cxy = phdi->cxy;
+	lpItem->cxy = phdi->cxy;
 
     if (phdi->mask & HDI_TEXT) {
-        len = lstrlen32A (phdi->pszText);
-        infoPtr->items[iItem].pszText =
-            HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len+1);
-        lstrcpy32A (infoPtr->items[iItem].pszText, phdi->pszText);
-        infoPtr->items[iItem].cchTextMax = phdi->cchTextMax;
+	if (phdi->pszText != LPSTR_TEXTCALLBACK32A) {
+	    len = lstrlen32A (phdi->pszText);
+	    lpItem->pszText = COMCTL32_Alloc (len+1);
+	    lstrcpy32A (lpItem->pszText, phdi->pszText);
+	}
+	else
+	    lpItem->pszText = LPSTR_TEXTCALLBACK32A;
     }
 
     if (phdi->mask & HDI_FORMAT)
-        infoPtr->items[iItem].fmt = phdi->fmt;
+	lpItem->fmt = phdi->fmt;
 
     if (phdi->mask & HDI_BITMAP)
-        infoPtr->items[iItem].hbm = phdi->hbm;
+        lpItem->hbm = phdi->hbm;
 
     if (phdi->mask & HDI_LPARAM)
-        infoPtr->items[iItem].lParam = phdi->lParam;
+        lpItem->lParam = phdi->lParam;
 
     if (phdi->mask & HDI_IMAGE)
-        infoPtr->items[iItem].iImage = phdi->iImage;
+        lpItem->iImage = phdi->iImage;
 
     if (phdi->mask & HDI_ORDER)
-        infoPtr->items[iItem].iOrder = phdi->iOrder;
+        lpItem->iOrder = phdi->iOrder;
 
     HEADER_SetItemBounds (wndPtr);
 
@@ -741,7 +723,7 @@
     HEADER_Refresh (wndPtr, hdc);
     ReleaseDC32 (wndPtr->hwndSelf, hdc);
 
-    return iItem;
+    return nItem;
 }
 
 
@@ -798,60 +780,52 @@
 {
     HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
     HDITEM32A *phdi = (HDITEM32A*)lParam;
-    INT32 iItem = (INT32)wParam;
+    INT32 nItem = (INT32)wParam;
+    HEADER_ITEM *lpItem;
     HDC32 hdc;
 
     if (phdi == NULL)
 	return FALSE;
-    if ((iItem < 0) || (iItem > infoPtr->uNumItem - 1))
+    if ((nItem < 0) || (nItem >= (INT32)infoPtr->uNumItem))
         return FALSE;
 
-    TRACE (header, "[iItem=%d]\n", iItem);
+    TRACE (header, "[nItem=%d]\n", nItem);
 
-    if (HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGING32A, iItem))
+    if (HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGING32A, nItem))
 	return FALSE;
 
-    if (phdi->mask & HDI_BITMAP) {
-	infoPtr->items[iItem].hbm = phdi->hbm;
-	infoPtr->items[iItem].mask  |= HDI_BITMAP;
-    }
+    lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
+    if (phdi->mask & HDI_BITMAP)
+	lpItem->hbm = phdi->hbm;
 
-    if (phdi->mask & HDI_FORMAT) {
-	infoPtr->items[iItem].fmt = phdi->fmt;
-	infoPtr->items[iItem].mask  |= HDI_FORMAT;
-    }
+    if (phdi->mask & HDI_FORMAT)
+	lpItem->fmt = phdi->fmt;
 
-    if (phdi->mask & HDI_LPARAM) {
-	infoPtr->items[iItem].lParam = phdi->lParam;
-	infoPtr->items[iItem].mask  |= HDI_LPARAM;
-    }
+    if (phdi->mask & HDI_LPARAM)
+	lpItem->lParam = phdi->lParam;
 
     if (phdi->mask & HDI_TEXT) {
-        INT32 len = lstrlen32A (phdi->pszText);
-        if (infoPtr->items[iItem].pszText)
-	    HeapFree (GetProcessHeap (), 0, infoPtr->items[iItem].pszText);
-        infoPtr->items[iItem].pszText =
-            HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len+1);
-        lstrcpy32A (infoPtr->items[iItem].pszText, phdi->pszText);
-        infoPtr->items[iItem].cchTextMax = phdi->cchTextMax;
+	if (phdi->pszText != LPSTR_TEXTCALLBACK32A) {
+	    INT32 len = lstrlen32A (phdi->pszText);
+	    if (lpItem->pszText)
+		COMCTL32_Free (lpItem->pszText);
+	    lpItem->pszText = COMCTL32_Alloc (len+1);
+	    lstrcpy32A (lpItem->pszText, phdi->pszText);
+	}
+	else
+	    lpItem->pszText = LPSTR_TEXTCALLBACK32A;
     }
 
-    if (phdi->mask & HDI_WIDTH) {
-	infoPtr->items[iItem].cxy = phdi->cxy;
-	infoPtr->items[iItem].mask  |= HDI_WIDTH;
-    }
+    if (phdi->mask & HDI_WIDTH)
+	lpItem->cxy = phdi->cxy;
 
-    if (phdi->mask & HDI_IMAGE) {
-	infoPtr->items[iItem].iImage = phdi->iImage;
-	infoPtr->items[iItem].mask  |= HDI_IMAGE;
-    }
+    if (phdi->mask & HDI_IMAGE)
+	lpItem->iImage = phdi->iImage;
 
-    if (phdi->mask & HDI_ORDER) {
-	infoPtr->items[iItem].iOrder = phdi->iOrder;
-	infoPtr->items[iItem].mask  |= HDI_ORDER;
-    }
+    if (phdi->mask & HDI_ORDER)
+	lpItem->iOrder = phdi->iOrder;
 
-    HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGED32A, iItem);
+    HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGED32A, nItem);
 
     HEADER_SetItemBounds (wndPtr);
     hdc = GetDC32 (wndPtr->hwndSelf);
@@ -870,8 +844,7 @@
     HFONT32 hOldFont;
     HDC32   hdc;
 
-    infoPtr = (HEADER_INFO *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-                                        sizeof(HEADER_INFO));
+    infoPtr = (HEADER_INFO *)COMCTL32_Alloc (sizeof(HEADER_INFO));
     wndPtr->wExtra[0] = (DWORD)infoPtr;
 
     infoPtr->uNumItem = 0;
@@ -902,26 +875,28 @@
 HEADER_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
-    INT32 iItem;
+    HEADER_ITEM *lpItem;
+    INT32 nItem;
 
     if (infoPtr->items) {
-        for (iItem = 0; iItem < infoPtr->uNumItem; iItem++) {
-            if (infoPtr->items[iItem].pszText)
-                HeapFree (GetProcessHeap (), 0, infoPtr->items[iItem].pszText);
+	lpItem = (HEADER_ITEM*)infoPtr->items;
+        for (nItem = 0; nItem < infoPtr->uNumItem; nItem++, lpItem++) {
+	    if ((lpItem->pszText) && (lpItem->pszText != LPSTR_TEXTCALLBACK32A))
+		COMCTL32_Free (lpItem->pszText);
         }
-        HeapFree (GetProcessHeap (), 0, infoPtr->items);
+        COMCTL32_Free (infoPtr->items);
     }
 
     if (infoPtr->himl)
 	ImageList_Destroy (infoPtr->himl);
 
-    HeapFree (GetProcessHeap (), 0, infoPtr);
+    COMCTL32_Free (infoPtr);
 
     return 0;
 }
 
 
-static LRESULT
+static __inline__ LRESULT
 HEADER_GetFont (WND *wndPtr)
 {
     HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
@@ -935,16 +910,16 @@
 {
     POINT32 pt;
     UINT32  flags;
-    INT32   iItem;
+    INT32   nItem;
 
     pt.x = (INT32)LOWORD(lParam); 
     pt.y = (INT32)HIWORD(lParam);
-    HEADER_InternalHitTest (wndPtr, &pt, &flags, &iItem);
+    HEADER_InternalHitTest (wndPtr, &pt, &flags, &nItem);
 
     if ((wndPtr->dwStyle & HDS_BUTTONS) && (flags == HHT_ONHEADER))
-	HEADER_SendHeaderNotify (wndPtr, HDN_ITEMDBLCLICK32A, iItem);
+	HEADER_SendHeaderNotify (wndPtr, HDN_ITEMDBLCLICK32A, nItem);
     else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN))
-	HEADER_SendHeaderNotify (wndPtr, HDN_DIVIDERDBLCLICK32A, iItem);
+	HEADER_SendHeaderNotify (wndPtr, HDN_DIVIDERDBLCLICK32A, nItem);
 
     return 0;
 }
@@ -956,45 +931,45 @@
     HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
     POINT32 pt;
     UINT32  flags;
-    INT32   iItem;
+    INT32   nItem;
     HDC32   hdc;
 
     pt.x = (INT32)LOWORD(lParam); 
     pt.y = (INT32)HIWORD(lParam);
-    HEADER_InternalHitTest (wndPtr, &pt, &flags, &iItem);
+    HEADER_InternalHitTest (wndPtr, &pt, &flags, &nItem);
 
     if ((wndPtr->dwStyle & HDS_BUTTONS) && (flags == HHT_ONHEADER)) {
 	SetCapture32 (wndPtr->hwndSelf);
 	infoPtr->bCaptured = TRUE;   
 	infoPtr->bPressed  = TRUE;
-	infoPtr->iMoveItem = iItem;
+	infoPtr->iMoveItem = nItem;
 
-	infoPtr->items[iItem].bDown = TRUE;
+	infoPtr->items[nItem].bDown = TRUE;
 
 	/* Send WM_CUSTOMDRAW */
 	hdc = GetDC32 (wndPtr->hwndSelf);
-	HEADER_RefreshItem (wndPtr, hdc, iItem);
+	HEADER_RefreshItem (wndPtr, hdc, nItem);
 	ReleaseDC32 (wndPtr->hwndSelf, hdc);
 
-	TRACE (header, "Pressed item %d!\n", iItem);
+	TRACE (header, "Pressed item %d!\n", nItem);
     } 
     else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN)) {
-	if (!(HEADER_SendHeaderNotify (wndPtr, HDN_BEGINTRACK32A, iItem))) {
+	if (!(HEADER_SendHeaderNotify (wndPtr, HDN_BEGINTRACK32A, nItem))) {
 	    SetCapture32 (wndPtr->hwndSelf);
 	    infoPtr->bCaptured = TRUE;   
 	    infoPtr->bTracking = TRUE;
-	    infoPtr->iMoveItem = iItem;
-	    infoPtr->nOldWidth = infoPtr->items[iItem].cxy;
-	    infoPtr->xTrackOffset = infoPtr->items[iItem].rect.right - pt.x;
+	    infoPtr->iMoveItem = nItem;
+	    infoPtr->nOldWidth = infoPtr->items[nItem].cxy;
+	    infoPtr->xTrackOffset = infoPtr->items[nItem].rect.right - pt.x;
 
 	    if (!(wndPtr->dwStyle & HDS_FULLDRAG)) {
-		infoPtr->xOldTrack = infoPtr->items[iItem].rect.right;
+		infoPtr->xOldTrack = infoPtr->items[nItem].rect.right;
 		hdc = GetDC32 (wndPtr->hwndSelf);
 		HEADER_DrawTrackLine (wndPtr, hdc, infoPtr->xOldTrack);
 		ReleaseDC32 (wndPtr->hwndSelf, hdc);
 	    }
 
-	    TRACE (header, "Begin tracking item %d!\n", iItem);
+	    TRACE (header, "Begin tracking item %d!\n", nItem);
 	}
     }
 
@@ -1008,15 +983,15 @@
     HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
     POINT32 pt;
     UINT32  flags;
-    INT32   iItem, nWidth;
+    INT32   nItem, nWidth;
     HDC32   hdc;
 
     pt.x = (INT32)LOWORD(lParam);
     pt.y = (INT32)HIWORD(lParam);
-    HEADER_InternalHitTest (wndPtr, &pt, &flags, &iItem);
+    HEADER_InternalHitTest (wndPtr, &pt, &flags, &nItem);
 
     if (infoPtr->bPressed) {
-	if ((iItem == infoPtr->iMoveItem) && (flags == HHT_ONHEADER)) {
+	if ((nItem == infoPtr->iMoveItem) && (flags == HHT_ONHEADER)) {
 	    infoPtr->items[infoPtr->iMoveItem].bDown = FALSE;
 	    hdc = GetDC32 (wndPtr->hwndSelf);
 	    HEADER_RefreshItem (wndPtr, hdc, infoPtr->iMoveItem);
@@ -1040,8 +1015,7 @@
 	    if (HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGING32A, infoPtr->iMoveItem))
 		infoPtr->items[infoPtr->iMoveItem].cxy = infoPtr->nOldWidth;
 	    else {
-		nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left +
-		infoPtr->xTrackOffset;
+		nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left + infoPtr->xTrackOffset;
 		if (nWidth < 0)
 		    nWidth = 0;
 		infoPtr->items[infoPtr->iMoveItem].cxy = nWidth;
@@ -1071,16 +1045,16 @@
     HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
     POINT32 pt;
     UINT32  flags;
-    INT32   iItem, nWidth;
+    INT32   nItem, nWidth;
     HDC32   hdc;
 
     pt.x = (INT32)LOWORD(lParam);
     pt.y = (INT32)HIWORD(lParam);
-    HEADER_InternalHitTest (wndPtr, &pt, &flags, &iItem);
+    HEADER_InternalHitTest (wndPtr, &pt, &flags, &nItem);
 
     if ((wndPtr->dwStyle & HDS_BUTTONS) && (wndPtr->dwStyle & HDS_HOTTRACK)) {
 	if (flags & (HHT_ONHEADER | HHT_ONDIVIDER | HHT_ONDIVOPEN))
-	    infoPtr->iHotItem = iItem;
+	    infoPtr->iHotItem = nItem;
 	else
 	    infoPtr->iHotItem = -1;
 	hdc = GetDC32 (wndPtr->hwndSelf);
@@ -1090,7 +1064,7 @@
 
     if (infoPtr->bCaptured) {
 	if (infoPtr->bPressed) {
-	    if ((iItem == infoPtr->iMoveItem) && (flags == HHT_ONHEADER))
+	    if ((nItem == infoPtr->iMoveItem) && (flags == HHT_ONHEADER))
 		infoPtr->items[infoPtr->iMoveItem].bDown = TRUE;
 	    else
 		infoPtr->items[infoPtr->iMoveItem].bDown = FALSE;
@@ -1105,8 +1079,7 @@
 		if (HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGING32A, infoPtr->iMoveItem))
 		    infoPtr->items[infoPtr->iMoveItem].cxy = infoPtr->nOldWidth;
 		else {
-		    nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left +
-		    infoPtr->xTrackOffset;
+		    nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left + infoPtr->xTrackOffset;
 		    if (nWidth < 0)
 			nWidth = 0;
 		    infoPtr->items[infoPtr->iMoveItem].cxy = nWidth;
@@ -1170,14 +1143,14 @@
     HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
     POINT32 pt;
     UINT32  flags;
-    INT32   iItem;
+    INT32   nItem;
 
     TRACE (header, "code=0x%X  id=0x%X\n", LOWORD(lParam), HIWORD(lParam));
 
     GetCursorPos32 (&pt);
     ScreenToClient32 (wndPtr->hwndSelf, &pt);
 
-    HEADER_InternalHitTest (wndPtr, &pt, &flags, &iItem);
+    HEADER_InternalHitTest (wndPtr, &pt, &flags, &nItem);
 
     if (flags == HHT_ONDIVIDER)
         SetCursor32 (infoPtr->hcurDivider);
@@ -1238,18 +1211,25 @@
 	case HDM_GETITEM32A:
 	    return HEADER_GetItem32A (wndPtr, wParam, lParam);
 
+//	case HDM_GETITEM32W:
+
 	case HDM_GETITEMCOUNT:
 	    return HEADER_GetItemCount (wndPtr);
 
 	case HDM_GETITEMRECT:
 	    return HEADER_GetItemRect (wndPtr, wParam, lParam);
 
+//	case HDM_GETORDERARRAY:
+//	case HDM_GETUNICODEFORMAT:
+
 	case HDM_HITTEST:
 	    return HEADER_HitTest (wndPtr, wParam, lParam);
 
 	case HDM_INSERTITEM32A:
 	    return HEADER_InsertItem32A (wndPtr, wParam, lParam);
 
+//	case HDM_INSERTITEM32W:
+
 	case HDM_LAYOUT:
 	    return HEADER_Layout (wndPtr, wParam, lParam);
 
@@ -1259,6 +1239,10 @@
 	case HDM_SETITEM32A:
 	    return HEADER_SetItem32A (wndPtr, wParam, lParam);
 
+//	case HDM_SETITEM32W:
+//	case HDM_SETORDERARRAY:
+//	case HDM_SETUNICODEFORMAT:
+
 
         case WM_CREATE:
             return HEADER_Create (wndPtr, wParam, lParam);
diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c
index 6fbbd33..0aec07d 100644
--- a/dlls/comctl32/imagelist.c
+++ b/dlls/comctl32/imagelist.c
@@ -5,9 +5,7 @@
  *
  *  TODO:
  *    - Fix xBitmap and yBitmap in ImageList_DrawIndirect.
- *    - Fix ILD_TRANSPARENT error in ImageList_DrawIndirect.
- *    - Fix ImageList_GetIcon (might be a result of the
- *      ILD_TRANSPARENT error in ImageList_DrawIndirect).
+ *    - Fix ImageList_GetIcon.
  *    - Fix drag functions.
  *    - Fix ImageList_Read and ImageList_Write.
  *    - Fix ImageList_SetFilter (undocumented).
@@ -146,11 +144,11 @@
 {
     HDC32    hdcSrc, hdcDst;
     INT32    nFirstIndex, nImageCount;
-    INT32    nStartX, nRunX, nRunY;
+    INT32    nStartX;
     BITMAP32 bmp;
 
-    if (himl == NULL) return (-1);
-    if (hbmImage == 0) return (-1);
+    if (!himl || !hbmImage)
+	return -1;
 
     GetObject32A (hbmImage, sizeof(BITMAP32), (LPVOID)&bmp);
     nImageCount = bmp.bmWidth / himl->cx;
@@ -158,56 +156,33 @@
     if (himl->cCurImage + nImageCount >= himl->cMaxImage)
         IMAGELIST_InternalExpandBitmaps (himl, nImageCount);
 
+    nStartX = himl->cCurImage * himl->cx;
+
     hdcSrc = CreateCompatibleDC32 (0);
     hdcDst = CreateCompatibleDC32 (0);
 
+    /* copy image bitmap */
     SelectObject32 (hdcDst, himl->hbmImage);
     SelectObject32 (hdcSrc, hbmImage);
-
     BitBlt32 (hdcDst, himl->cCurImage * himl->cx, 0,
               bmp.bmWidth, himl->cy, hdcSrc, 0, 0, SRCCOPY);
           
     if (himl->hbmMask) {
         if (hbmMask) {
+	    /* copy mask bitmap */
             SelectObject32 (hdcDst, himl->hbmMask);
             SelectObject32 (hdcSrc, hbmMask);
-            BitBlt32 (hdcDst, himl->cCurImage * himl->cx, 0,
-                      bmp.bmWidth, himl->cy, hdcSrc, 0, 0, SRCCOPY);
-
-            /* fix transparent areas of the image bitmap*/
-            SelectObject32 (hdcSrc, himl->hbmMask);
-            SelectObject32 (hdcDst, himl->hbmImage);
-            nStartX = himl->cCurImage * himl->cx;
-
-            for (nRunY = 0; nRunY < himl->cy; nRunY++) {
-                for (nRunX = 0; nRunX < bmp.bmWidth; nRunX++) {
-                    if (GetPixel32 (hdcSrc, nStartX + nRunX, nRunY) !=
-                        RGB(0, 0, 0))
-                        SetPixel32 (hdcDst, nStartX + nRunX, nRunY, 
-                                    RGB(0, 0, 0));
-                }
-            }
+            BitBlt32 (hdcDst, nStartX, 0, bmp.bmWidth, himl->cy,
+		      hdcSrc, 0, 0, SRCCOPY);
         }
         else {
-            /* create mask from the imagelist's background color */
+	    /* copy monochrome image to the mask bitmap */
             SelectObject32 (hdcDst, himl->hbmMask);
-            SelectObject32 (hdcSrc, himl->hbmImage);
-            nStartX = himl->cCurImage * himl->cx;
-            for (nRunY = 0; nRunY < himl->cy; nRunY++) {
-                for (nRunX = 0; nRunX < bmp.bmWidth; nRunX++) {
-                    if (GetPixel32 (hdcSrc, nStartX + nRunX, nRunY) ==
-                        himl->clrBk)
-                    {
-                        SetPixel32 (hdcSrc, nStartX + nRunX, nRunY, 
-                                    RGB(0, 0, 0));
-                        SetPixel32 (hdcDst, nStartX + nRunX, nRunY, 
-                                    RGB(255, 255, 255));
-                    }
-                    else
-                        SetPixel32 (hdcDst, nStartX + nRunX, nRunY, 
-                                    RGB(0, 0, 0));        
-                }
-            }
+            SelectObject32 (hdcSrc, hbmImage);
+	    SetBkColor32 (hdcSrc, GetNearestColor32 (hdcSrc,
+			  GetPixel32 (hdcSrc, 0, 0)));
+	    BitBlt32 (hdcDst, nStartX, 0, bmp.bmWidth, himl->cy,
+		      hdcSrc, nStartX, 0, SRCCOPY);
         }
     }
 
@@ -217,7 +192,7 @@
     nFirstIndex = himl->cCurImage;
     himl->cCurImage += nImageCount;
 
-    return (nFirstIndex);
+    return nFirstIndex;
 }
 
 
@@ -249,9 +224,9 @@
  * specified bitmap using the mask color.
  *
  * PARAMS
- *     himl     [I] image list handle.
- *     hbmImage [I] image bitmap handle.
- *     clrMask  [I] mask color.
+ *     himl    [I] handle to image list.
+ *     hBitmap [I] handle to bitmap
+ *     clrMask [I] mask color.
  *
  * RETURNS
  *     Success: Index of the first new image.
@@ -259,20 +234,18 @@
  */
 
 INT32 WINAPI
-ImageList_AddMasked (HIMAGELIST himl, HBITMAP32 hbmImage, COLORREF clrMask)
+ImageList_AddMasked (HIMAGELIST himl, HBITMAP32 hBitmap, COLORREF clrMask)
 {
-    HDC32    hdcImageList, hdcImage, hdcMask;
+    HDC32    hdcImage, hdcMask, hdcBitmap;
     INT32    nIndex, nImageCount;
     BITMAP32 bmp;
-    INT32    nStartX, nRunX, nRunY;
-    COLORREF bkColor;
 
     if (himl == NULL)
-	return (-1);
+	return -1;
 
-    bkColor = (clrMask == CLR_NONE) ? himl->clrBk : clrMask;
+    if (!GetObject32A (hBitmap, sizeof(BITMAP32), &bmp))
+	return -1;
 
-    GetObject32A (hbmImage, sizeof(BITMAP32), &bmp);
     nImageCount = bmp.bmWidth / himl->cx;
 
     if (himl->cCurImage + nImageCount >= himl->cMaxImage)
@@ -281,39 +254,34 @@
     nIndex = himl->cCurImage;
     himl->cCurImage += nImageCount;
 
-    hdcImageList = CreateCompatibleDC32 (0);
-    hdcImage = CreateCompatibleDC32 (0);
+    hdcImage  = CreateCompatibleDC32 (0);
+    hdcBitmap = CreateCompatibleDC32 (0);
 
-    SelectObject32 (hdcImageList, himl->hbmImage);
-    SelectObject32 (hdcImage, hbmImage);
-    BitBlt32 (hdcImageList, nIndex * himl->cx, 0, bmp.bmWidth, himl->cy,
-              hdcImage, 0, 0, SRCCOPY);
+    SelectObject32 (hdcBitmap, hBitmap);
+    SelectObject32 (hdcImage, himl->hbmImage);
+    BitBlt32 (hdcImage, nIndex * himl->cx, 0, bmp.bmWidth, himl->cy,
+              hdcBitmap, 0, 0, SRCCOPY);
 
     if (himl->hbmMask) {
-        /* create Mask */
+	COLORREF bkColor = (clrMask != CLR_DEFAULT) ? clrMask :
+	    GetNearestColor32 (hdcBitmap, GetPixel32 (hdcBitmap, 0, 0));
+
+	/* create mask from image */
         hdcMask = CreateCompatibleDC32 (0);
         SelectObject32 (hdcMask, himl->hbmMask);
-        nStartX = nIndex * himl->cx;
-        for (nRunY = 0; nRunY < himl->cy; nRunY++) {
-            for (nRunX = 0; nRunX < bmp.bmWidth; nRunX++) {
-                if (GetPixel32 (hdcImageList, nStartX + nRunX, nRunY) ==
-                    bkColor) {
-                    SetPixel32 (hdcImageList, nStartX + nRunX, nRunY,
-                                RGB(0, 0, 0));
-                    SetPixel32 (hdcMask, nStartX + nRunX, nRunY,
-                                RGB(255, 255, 255));
-                }
-                else
-                    SetPixel32 (hdcMask, nStartX + nRunX, nRunY, RGB(0, 0, 0));
-            }
-        }
+
+	/* create monochrome image to the mask bitmap */
+	SetBkColor32 (hdcBitmap, bkColor);
+	BitBlt32 (hdcMask, nIndex * himl->cx, 0, bmp.bmWidth, himl->cy,
+		  hdcBitmap, 0, 0, SRCCOPY);
+
         DeleteDC32 (hdcMask);
     }
 
-    DeleteDC32 (hdcImageList);
     DeleteDC32 (hdcImage);
+    DeleteDC32 (hdcBitmap);
   
-    return (nIndex);
+    return nIndex;
 }
 
 
@@ -969,6 +937,8 @@
     {
 	/* draw the mask */
 	SelectObject32 (hdcImageList, himlLocal->hbmMask);
+	SetBkColor32 (hdcImageList, RGB(255, 255, 255));
+	SetTextColor32 (hdcImageList, RGB(0, 0, 0));
 	BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
 		  hdcImageList, himlLocal->cx * pimldp->i, 0,
 		  bMaskTrans ? SRCAND : SRCCOPY);
@@ -989,8 +959,7 @@
         }
 
         BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
-                  hdcImageList, himlLocal->cx * pimldp->i, 0,
-                  SRCPAINT);
+                  hdcImageList, himlLocal->cx * pimldp->i, 0, SRCPAINT);
 
         if (bBlend25 || bBlend50)
         {
@@ -1225,7 +1194,7 @@
 {
     ICONINFO ii;
     HICON32  hIcon;
-    HDC32    hdc;
+    HDC32    hdcSrc, hdcDst;
     INT32    nWidth, nHeight;
 
     if (himl == NULL) return 0;
@@ -1234,27 +1203,36 @@
     nWidth = GetSystemMetrics32 (SM_CXICON);
     nHeight = GetSystemMetrics32 (SM_CYICON);
 
+    hdcSrc = CreateCompatibleDC32(0);
+    hdcDst = CreateCompatibleDC32(0);
+
     ii.fIcon = TRUE;
     ii.xHotspot = 0;
     ii.yHotspot = 0;
-    ii.hbmMask  = CreateBitmap32 (nWidth, nHeight, 1, 1, NULL);
-    ii.hbmColor = CreateBitmap32 (nWidth, nHeight, 1, himl->uBitsPixel, NULL);
+    ii.hbmMask  = CreateCompatibleBitmap32 (hdcDst, nWidth, nHeight);
+    ii.hbmColor = CreateCompatibleBitmap32 (hdcDst, nWidth, nHeight);
 
-    hdc = CreateCompatibleDC32(0);
-
-    /* draw image*/
-    SelectObject32 (hdc, ii.hbmColor);
-    PatBlt32 (hdc, 0, 0, nWidth, nHeight, BLACKNESS);
-    ImageList_Draw (himl, i, hdc, 0, 0, fStyle | ILD_TRANSPARENT);
 
     /* draw mask*/
-    SelectObject32 (hdc, ii.hbmMask);
-    PatBlt32 (hdc, 0, 0, nWidth, nHeight, WHITENESS);
-    ImageList_Draw (himl, i, hdc, 0, 0, fStyle | ILD_MASK);
+    SelectObject32 (hdcDst, ii.hbmMask);
+    if (himl->hbmMask) {
+	SelectObject32 (hdcSrc, himl->hbmMask);
+	BitBlt32 (hdcDst, 0, 0, nWidth, nHeight,
+		  hdcSrc, i * himl->cx, 0, SRCCOPY);
+    }
+    else
+	PatBlt32 (hdcDst, 0, 0, nWidth, nHeight, BLACKNESS);
+
+    /* draw image*/
+    SelectObject32 (hdcDst, ii.hbmColor);
+    SelectObject32 (hdcSrc, himl->hbmImage);
+    BitBlt32 (hdcDst, 0, 0, nWidth, nHeight,
+	      hdcSrc, i * himl->cx, 0, SRCCOPY);
 
     hIcon = CreateIconIndirect (&ii);    
 
-    DeleteDC32 (hdc);
+    DeleteDC32 (hdcSrc);
+    DeleteDC32 (hdcDst);
     DeleteObject32 (ii.hbmMask);
     DeleteObject32 (ii.hbmColor);
 
@@ -2040,7 +2018,7 @@
  * Sets the image size of the bitmap and deletes all images.
  *
  * PARAMS
- *     himl [I] image list handle
+ *     himl [I] handle to image list
  *     cx   [I] image width
  *     cy   [I] image height
  *
@@ -2054,7 +2032,8 @@
 {
     INT32 nCount;
 
-    if (himl == NULL) return (FALSE);
+    if (!himl)
+	return FALSE;
 
     /* remove all images*/
     himl->cMaxImage  = himl->cInitial + himl->cGrow;
@@ -2088,7 +2067,7 @@
  * Resizes an image list to the specified number of images.
  *
  * PARAMS
- *     himl        [I] image list handle
+ *     himl        [I] handle to image list
  *     iImageCount [I] number of images in the image list
  *
  * RETURNS
@@ -2103,9 +2082,12 @@
     HBITMAP32 hbmNewBitmap;
     INT32     nNewCount, nCopyCount;
 
-    if (himl == NULL) return (FALSE);
-    if (himl->cCurImage <= iImageCount) return (FALSE);
-    if (himl->cMaxImage > iImageCount) return (TRUE);
+    if (!himl)
+	return FALSE;
+    if (himl->cCurImage <= iImageCount)
+	return FALSE;
+    if (himl->cMaxImage > iImageCount)
+	return TRUE;
 
     nNewCount = iImageCount + himl->cGrow;
     nCopyCount = _MIN(himl->cCurImage, iImageCount);
@@ -2126,7 +2108,7 @@
     }
     else
     {
-        WARN (imagelist, "Could not create new image bitmap !\n");
+        ERR (imagelist, "Could not create new image bitmap !\n");
     }
 
     if (himl->hbmMask)
@@ -2144,7 +2126,7 @@
         }
         else
         {
-            WARN (imagelist, "Could not create new mask bitmap!\n");
+            ERR (imagelist, "Could not create new mask bitmap!\n");
         }
     }
 
@@ -2156,7 +2138,7 @@
     if (himl->cCurImage > nCopyCount)
         himl->cCurImage = nCopyCount;
 
-    return (TRUE);
+    return TRUE;
 }
 
 
@@ -2178,8 +2160,12 @@
 BOOL32 WINAPI
 ImageList_SetOverlayImage (HIMAGELIST himl, INT32 iImage, INT32 iOverlay)
 {
-    if ((iOverlay < 1) || (iOverlay > MAX_OVERLAYIMAGE)) return (FALSE);
-    if ((iImage < 0) || (iImage > himl->cCurImage)) return (FALSE);
+    if (!himl)
+	return FALSE;
+    if ((iOverlay < 1) || (iOverlay > MAX_OVERLAYIMAGE))
+	return FALSE;
+    if ((iImage < 0) || (iImage > himl->cCurImage))
+	return FALSE;
     
     himl->nOvlIdx[iOverlay - 1] = iImage;
     return TRUE;
@@ -2210,9 +2196,10 @@
 BOOL32 WINAPI
 ImageList_Write (HIMAGELIST himl, LPSTREAM32 pstm)
 {
-    FIXME (imagelist, "empty stub!\n");
+    if (!himl)
+	return FALSE;
 
-    if (himl == NULL) return (FALSE);
+    FIXME (imagelist, "empty stub!\n");
 
     return FALSE;
 }
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c
index 91fe4cb..0c24d9c 100644
--- a/dlls/comctl32/listview.c
+++ b/dlls/comctl32/listview.c
@@ -9,8 +9,8 @@
  *     Eric <ekohl@abo.rhein-zeitung.de>
  *
  * TODO:
- *   - All messages.
- *   - All notifications.
+ *   - Most messages.
+ *   - Most notifications.
  */
 
 #include "windows.h"
@@ -26,7 +26,7 @@
 static VOID
 LISTVIEW_Refresh (WND *wndPtr, HDC32 hdc)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+//    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
 
 
 
@@ -34,6 +34,124 @@
 
 
 
+// << LISTVIEW_ApproximateViewRect >>
+// << LISTVIEW_Arrange >>
+// << LISTVIEW_CreateDragImage >>
+
+
+static LRESULT
+LISTVIEW_DeleteAllItems (WND *wndPtr)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+    INT32 nItem;
+    LISTVIEW_ITEM *lpItem;
+    NMLISTVIEW nmlv;
+    BOOL32 bNotify;
+
+    if (infoPtr->nItemCount == 0)
+	return TRUE;
+
+    TRACE (listview, "\n");
+
+    /* send LVN_DELETEALLITEMS notification */
+    ZeroMemory (&nmlv, sizeof (NMLISTVIEW));
+    nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
+    nmlv.hdr.idFrom   = wndPtr->wIDmenu;
+    nmlv.hdr.code     = LVN_DELETEALLITEMS;
+    nmlv.iItem        = -1;
+    bNotify =
+	!(BOOL32)SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
+				 (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
+
+    nmlv.hdr.code     = LVN_DELETEITEM;
+
+    for (nItem = 0; nItem < infoPtr->nItemCount; nItem++) {
+	/* send notification */
+	if (bNotify) {
+	    nmlv.iItem = nItem;
+	    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
+			    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
+	}
+
+	/* get item pointer */
+	lpItem = (LISTVIEW_ITEM*)DPA_GetPtr (infoPtr->hdpaItems, nItem);
+
+	/* delete item strings */
+	if ((lpItem->pszText) && (lpItem->pszText != LPSTR_TEXTCALLBACK32A))
+	    COMCTL32_Free (lpItem->pszText);
+
+	/* free item data */
+	COMCTL32_Free (lpItem);
+    }
+
+    DPA_DeleteAllPtrs (infoPtr->hdpaItems);
+    infoPtr->nItemCount = 0;
+
+    return TRUE;
+}
+
+
+static LRESULT
+LISTVIEW_DeleteColumn (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+    INT32 nColumn = (INT32)wParam;
+
+    /* FIXME ??? */
+    if (infoPtr->nItemCount > 0)
+	return FALSE;
+
+    if (!SendMessage32A (infoPtr->hwndHeader, HDM_DELETEITEM, wParam, 0))
+	return FALSE;
+
+    infoPtr->nColumnCount--;
+
+    FIXME (listview, "semi stub!\n");
+
+    return TRUE;
+}
+
+
+static LRESULT
+LISTVIEW_DeleteItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+    INT32 nItem = (INT32)wParam;
+    LISTVIEW_ITEM *lpItem;
+    NMLISTVIEW nmlv;
+
+    if ((nItem < 0) || (nItem >= infoPtr->nItemCount))
+	return FALSE;
+
+    TRACE (listview, "(%d)\n", nItem);
+
+    /* send notification */
+    ZeroMemory (&nmlv, sizeof (NMLISTVIEW));
+    nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
+    nmlv.hdr.idFrom   = wndPtr->wIDmenu;
+    nmlv.hdr.code     = LVN_DELETEITEM;
+    nmlv.iItem        = nItem;
+    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
+		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
+
+    /* remove from item array */
+    lpItem = (LISTVIEW_ITEM*)DPA_DeletePtr (infoPtr->hdpaItems, nItem);
+
+    /* delete item strings */
+    if ((lpItem->pszText) && (lpItem->pszText != LPSTR_TEXTCALLBACK32A))
+	COMCTL32_Free (lpItem->pszText);
+
+    /* free item data */
+    COMCTL32_Free (lpItem);
+
+    infoPtr->nItemCount--;
+
+    return TRUE;
+}
+
+
+// << LISTVIEW_EditLabel >>
+// << LISTVIEW_EnsureVisible >>
 // << LISTVIEW_FindItem >>
 
 
@@ -47,6 +165,75 @@
 
 
 // << LISTVIEW_GetBkImage >>
+// << LISTVIEW_GetCallbackMask >>
+
+
+static LRESULT
+LISTVIEW_GetColumn32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+    LPLVCOLUMN32A lpcol = (LPLVCOLUMN32A)lParam;
+    INT32 nIndex = (INT32)wParam;
+    HDITEM32A hdi;
+
+    if (!lpcol)
+	return FALSE;
+
+    TRACE (listview, "(%d %p)\n", nIndex, lpcol);
+
+    ZeroMemory (&hdi, sizeof(HDITEM32A));
+
+    if (lpcol->mask & LVCF_FMT)
+	hdi.mask |= HDI_FORMAT;
+
+    if (lpcol->mask & LVCF_WIDTH)
+        hdi.mask |= HDI_WIDTH;
+
+    if (lpcol->mask & LVCF_TEXT)
+        hdi.mask |= (HDI_TEXT | HDI_FORMAT);
+
+    if (lpcol->mask & LVCF_IMAGE)
+        hdi.mask |= HDI_IMAGE;
+
+    if (lpcol->mask & LVCF_ORDER)
+        hdi.mask |= HDI_ORDER;
+
+    if (!SendMessage32A (infoPtr->hwndHeader, HDM_GETITEM32A,
+		    wParam, (LPARAM)&hdi))
+	return FALSE;
+
+    if (lpcol->mask & LVCF_FMT) {
+	lpcol->fmt = 0;
+
+	if (hdi.fmt & HDF_LEFT)
+	    lpcol->fmt |= LVCFMT_LEFT;
+	else if (hdi.fmt & HDF_RIGHT)
+	    lpcol->fmt |= LVCFMT_RIGHT;
+	else if (hdi.fmt & HDF_CENTER)
+	    lpcol->fmt |= LVCFMT_CENTER;
+
+	if (hdi.fmt & HDF_IMAGE)
+	    lpcol->fmt |= LVCFMT_COL_HAS_IMAGES;
+    }
+
+    if (lpcol->mask & LVCF_WIDTH)
+	lpcol->cx = hdi.cxy;
+
+    if ((lpcol->mask & LVCF_TEXT) && (lpcol->pszText))
+	lstrcpyn32A (lpcol->pszText, hdi.pszText, lpcol->cchTextMax);
+
+    if (lpcol->mask & LVCF_IMAGE)
+	lpcol->iImage = hdi.iImage;
+
+    if (lpcol->mask & LVCF_ORDER)
+	lpcol->iOrder = hdi.iOrder;
+
+    return TRUE;
+}
+
+
+// << LISTVIEW_GetColumn32W >>
+// << LISTVIEW_GetColumnOrderArray >>
 
 
 __inline__ static LRESULT
@@ -64,6 +251,9 @@
 }
 
 
+// << LISTVIEW_GetCountPerPage >>
+// << LISTVIEW_GetEditControl >>
+// << LISTVIEW_GetExtendedListviewStyle >>
 
 
 __inline__ static LRESULT
@@ -75,6 +265,11 @@
 }
 
 
+// << LISTVIEW_GetHotCursor >>
+// << LISTVIEW_GetHotItem >>
+// << LISTVIEW_GetHoverTime >>
+
+
 static LRESULT
 LISTVIEW_GetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
@@ -97,19 +292,62 @@
 }
 
 
+// << LISTVIEW_GetISearchString >>
+
+
 static LRESULT
 LISTVIEW_GetItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+    LPLVITEM32A lpItem = (LPLVITEM32A)lParam;
+    LISTVIEW_ITEM *lpRow, *lpSubItem;
 
-    FIXME (listview, "(0x%08x) empty stub!\n", wParam);
+    if (!lpItem)
+	return FALSE;
 
+    if ((lpItem->iItem < 0) || (lpItem->iItem >= infoPtr->nItemCount))
+	return FALSE;
 
+    if ((lpItem->iSubItem < 0) || (lpItem->iSubItem >= infoPtr->nColumnCount))
+	return FALSE;
+
+    FIXME (listview, "(%d %d %p)\n",
+	   lpItem->iItem, lpItem->iSubItem, lpItem);
+
+    lpRow = DPA_GetPtr (infoPtr->hdpaItems, lpItem->iItem);
+    if (!lpRow)
+	return FALSE;
+
+    lpSubItem = &lpRow[lpItem->iSubItem];
+    if (!lpSubItem)
+	return FALSE;
+
+    if (lpItem->mask & LVIF_STATE)
+	lpItem->state = lpSubItem->state & lpItem->stateMask;
+
+    if (lpItem->mask & LVIF_TEXT) {
+	if (lpSubItem->pszText == LPSTR_TEXTCALLBACK32A)
+	    lpItem->pszText = LPSTR_TEXTCALLBACK32A;
+	else
+	    Str_GetPtr32A (lpSubItem->pszText, lpItem->pszText,
+			   lpItem->cchTextMax);
+    }
+
+    if (lpItem->mask & LVIF_IMAGE)
+	 lpItem->iImage = lpSubItem->iImage;
+
+    if (lpItem->mask & LVIF_PARAM)
+	lpItem->lParam = lpSubItem->lParam;
+
+    if (lpItem->mask & LVIF_INDENT)
+	lpItem->iIndent = lpSubItem->iIndent;
 
     return TRUE;
 }
 
 
+// << LISTVIEW_GetItem32W >>
+
 
 __inline__ static LRESULT
 LISTVIEW_GetItemCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
@@ -119,6 +357,93 @@
 }
 
 
+static LRESULT
+LISTVIEW_GetItemPosition (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+    LPPOINT32 lpPt = (LPPOINT32)lParam;
+    INT32 nIndex = (INT32)wParam;
+
+    if (!lpPt)
+	return FALSE;
+    if ((nIndex < 0) || (nIndex >= infoPtr->nItemCount))
+	return FALSE;
+
+    FIXME (listview, "returning position [0,0]!\n");
+    lpPt->x = 0;
+    lpPt->y = 0;
+
+    return TRUE;
+}
+
+
+// << LISTVIEW_GetItemRect >>
+// << LISTVIEW_GetItemSpacing >>
+// << LISTVIEW_GetItemState >>
+
+
+static LRESULT
+LISTVIEW_GetItemText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+    LPLVITEM32A lpItem = (LPLVITEM32A)lParam;
+    INT32 nItem = (INT32)wParam;
+    LISTVIEW_ITEM *lpRow, *lpSubItem;
+
+    TRACE (listview, "(%d %p)\n", nItem, lpItem);
+
+    lpRow = DPA_GetPtr (infoPtr->hdpaItems, lpItem->iItem);
+    if (!lpRow)
+	return 0;
+
+    lpSubItem = &lpRow[lpItem->iSubItem];
+    if (!lpSubItem)
+	return 0;
+
+    if (lpSubItem->pszText == LPSTR_TEXTCALLBACK32A) {
+	lpItem->pszText = LPSTR_TEXTCALLBACK32A;
+	return 0;
+    }
+    else
+	return Str_GetPtr32A (lpSubItem->pszText, lpItem->pszText,
+			      lpItem->cchTextMax);
+}
+
+
+// << LISTVIEW_GetItemText32A >>
+
+
+static LRESULT
+LISTVIEW_GetNextItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+    INT32 nStart = (INT32)wParam;
+    UINT32 uFlags = (UINT32)LOWORD(lParam);
+
+    FIXME (listview, "(%d, 0x%x); empty stub!\n", nStart, uFlags);
+
+
+    return -1;
+}
+
+
+// << LISTVIEW_GetNumberOfWorkAreas >>
+// << LISTVIEW_GetOrigin >>
+
+
+static LRESULT
+LISTVIEW_GetSelectedCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+
+    TRACE (listview, ": empty stub (returns 0)!\n");
+
+    return 0;
+}
+
+
+// << LISTVIEW_GetSelectionMark >>
+
 
 static LRESULT
 LISTVIEW_GetStringWidth32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
@@ -132,7 +457,7 @@
     if (!lpsz)
 	return 0;
 
-    TRACE (listview, "(%s) empty stub!\n", lpsz);
+    TRACE (listview, "(%s)\n", lpsz);
 
     hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject32 (SYSTEM_FONT);
     hdc = GetDC32 (0);
@@ -149,22 +474,42 @@
 
 
 
+__inline__ static LRESULT
+LISTVIEW_GetTextBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+
+    return infoPtr->clrTextBk;
+}
+
+
+__inline__ static LRESULT
+LISTVIEW_GetTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+
+    return infoPtr->clrText;
+}
+
+
 static LRESULT
 LISTVIEW_InsertColumn32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
     LPLVCOLUMN32A lpcol = (LPLVCOLUMN32A)lParam;
+    INT32 nIndex = (INT32)wParam;
     HDITEM32A hdi;
+    INT32 nResult;
 
-    if (!lpcol)
+    if ((!lpcol) || (infoPtr->nItemCount > 0))
 	return -1;
 
-    TRACE (listview, "(%d %p) empty stub!\n", (INT32)wParam, lpcol);
+    FIXME (listview, "(%d %p): semi stub!\n", nIndex, lpcol);
 
     ZeroMemory (&hdi, sizeof(HDITEM32A));
 
     if (lpcol->mask & LVCF_FMT) {
-	if (wParam == 0)
+	if (nIndex == 0)
 	    hdi.fmt |= HDF_LEFT;
 	else if (lpcol->fmt & LVCFMT_LEFT)
 	    hdi.fmt |= HDF_LEFT;
@@ -200,11 +545,90 @@
 	hdi.iOrder = lpcol->iOrder;
     }
 
-    return (LRESULT)SendMessage32A (infoPtr->hwndHeader, HDM_INSERTITEM32A,
-				    wParam, (LPARAM)&hdi);
+    nResult = SendMessage32A (infoPtr->hwndHeader, HDM_INSERTITEM32A,
+			      wParam, (LPARAM)&hdi);
+    if (nResult == -1)
+	return -1;
+
+    infoPtr->nColumnCount++;
+
+    return nResult;
 }
 
 
+// << LISTVIEW_InsertColumn32W >>
+
+
+static LRESULT
+LISTVIEW_InsertItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+    LPLVITEM32A lpItem = (LPLVITEM32A)lParam;
+    LISTVIEW_ITEM *lpListItem;
+    INT32 nIndex;
+    NMLISTVIEW nmlv;
+
+    if (!lpItem)
+	return -1;
+
+    if ((!infoPtr->nColumnCount) || (lpItem->iSubItem))
+	return -1;
+
+    FIXME (listview, "(%d %p)\n", lpItem->iItem, lpItem);
+
+    lpListItem = (LISTVIEW_ITEM*)COMCTL32_Alloc (infoPtr->nColumnCount * sizeof(LISTVIEW_ITEM));
+    nIndex = DPA_InsertPtr (infoPtr->hdpaItems, lpItem->iItem, lpListItem);
+    if (nIndex == -1)
+	return -1;
+
+    if (lpItem->mask & LVIF_STATE)
+	lpListItem[0].state = lpItem->state;
+
+    if (lpItem->mask & LVIF_TEXT) {
+	if (lpItem->pszText == LPSTR_TEXTCALLBACK32A)
+	    lpListItem[0].pszText = LPSTR_TEXTCALLBACK32A;
+	else
+	    Str_SetPtr32A (&lpListItem[0].pszText, lpItem->pszText);
+    }
+
+    if (lpItem->mask & LVIF_IMAGE)
+	lpListItem[0].iImage = lpItem->iImage;
+
+    if (lpItem->mask & LVIF_PARAM)
+	lpListItem[0].lParam = lpItem->lParam;
+
+    if (lpItem->mask & LVIF_INDENT)
+	lpListItem[0].iIndent = lpItem->iIndent;
+
+    infoPtr->nItemCount++;
+
+    /* send notification */
+    ZeroMemory (&nmlv, sizeof (NMLISTVIEW));
+    nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
+    nmlv.hdr.idFrom   = wndPtr->wIDmenu;
+    nmlv.hdr.code     = LVN_INSERTITEM;
+    nmlv.iItem        = nIndex;
+    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
+		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
+
+    return nIndex;
+}
+
+
+// << LISTVIEW_InsertItem32W >>
+
+
+static LRESULT
+LISTVIEW_RedrawItems (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+//    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+
+    FIXME (listview, "(%d - %d): empty stub!\n",
+	   (INT32)wParam, (INT32)lParam);
+
+    return TRUE;
+}
+
 
 
 static LRESULT
@@ -212,10 +636,11 @@
 {
     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
 
-    if (!(infoPtr)) return FALSE;
+    if (!infoPtr)
+	return FALSE;
 
     /* set background color */
-    TRACE (listview, "0x%06x\n", (COLORREF)lParam);
+    TRACE (listview, "0x%06lx\n", (COLORREF)lParam);
     infoPtr->clrBk = (COLORREF)lParam;
 
     return TRUE;
@@ -223,6 +648,65 @@
 
 
 static LRESULT
+LISTVIEW_SetColumn32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+    LPLVCOLUMN32A lpcol = (LPLVCOLUMN32A)lParam;
+    INT32 nIndex = (INT32)wParam;
+    HDITEM32A hdi;
+
+    if (!lpcol)
+	return -1;
+
+    FIXME (listview, "(%d %p): semi stub!\n", nIndex, lpcol);
+
+    ZeroMemory (&hdi, sizeof(HDITEM32A));
+
+    if (lpcol->mask & LVCF_FMT) {
+	if (nIndex == 0)
+	    hdi.fmt |= HDF_LEFT;
+	else if (lpcol->fmt & LVCFMT_LEFT)
+	    hdi.fmt |= HDF_LEFT;
+	else if (lpcol->fmt & LVCFMT_RIGHT)
+	    hdi.fmt |= HDF_RIGHT;
+	else if (lpcol->fmt & LVCFMT_CENTER)
+	    hdi.fmt |= HDF_CENTER;
+
+	if (lpcol->fmt & LVCFMT_COL_HAS_IMAGES)
+	    hdi.fmt |= HDF_IMAGE;
+	    
+	hdi.mask |= HDI_FORMAT;
+    }
+
+    if (lpcol->mask & LVCF_WIDTH) {
+        hdi.mask |= HDI_WIDTH;
+	hdi.cxy = lpcol->cx;
+    }
+    
+    if (lpcol->mask & LVCF_TEXT) {
+        hdi.mask |= (HDI_TEXT | HDI_FORMAT);
+	hdi.pszText = lpcol->pszText;
+	hdi.fmt |= HDF_STRING;
+    }
+
+    if (lpcol->mask & LVCF_IMAGE) {
+        hdi.mask |= HDI_IMAGE;
+	hdi.iImage = lpcol->iImage;
+    }
+
+    if (lpcol->mask & LVCF_ORDER) {
+        hdi.mask |= HDI_ORDER;
+	hdi.iOrder = lpcol->iOrder;
+    }
+
+    return (LRESULT)SendMessage32A (infoPtr->hwndHeader, HDM_SETITEM32A,
+				    wParam, (LPARAM)&hdi);
+}
+
+
+
+
+static LRESULT
 LISTVIEW_SetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
@@ -252,6 +736,150 @@
 
 
 
+static LRESULT
+LISTVIEW_SetItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+    LPLVITEM32A lpItem = (LPLVITEM32A)lParam;
+    LISTVIEW_ITEM *lpRow, *lpSubItem;
+    NMLISTVIEW nmlv;
+
+    if (!lpItem)
+	return FALSE;
+
+    if ((lpItem->iItem < 0) || (lpItem->iItem >= infoPtr->nItemCount))
+	return FALSE;
+
+    if ((lpItem->iSubItem < 0) || (lpItem->iSubItem >= infoPtr->nColumnCount))
+	return FALSE;
+
+    /* send LVN_ITEMCHANGING notification */
+    ZeroMemory (&nmlv, sizeof (NMLISTVIEW));
+    nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
+    nmlv.hdr.idFrom   = wndPtr->wIDmenu;
+    nmlv.hdr.code     = LVN_ITEMCHANGING;
+    nmlv.iItem        = lpItem->iItem;
+    nmlv.iSubItem     = lpItem->iSubItem;
+    nmlv.uChanged     = lpItem->mask;
+
+    if (!SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
+			 (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv))
+	return FALSE;
+
+    TRACE (listview, "(%d %d %p)\n",
+	   lpItem->iItem, lpItem->iSubItem, lpItem);
+
+    lpRow = DPA_GetPtr (infoPtr->hdpaItems, lpItem->iItem);
+    if (!lpRow)
+	return FALSE;
+
+    lpSubItem = &lpRow[lpItem->iSubItem];
+    if (!lpSubItem)
+	return FALSE;
+
+    if (lpItem->mask & LVIF_STATE)
+	lpSubItem->state = (lpSubItem->state & lpItem->stateMask) | lpItem->state;
+
+    if (lpItem->mask & LVIF_TEXT) {
+	if (lpItem->pszText == LPSTR_TEXTCALLBACK32A) {
+	    if ((lpSubItem->pszText) &&
+		(lpSubItem->pszText != LPSTR_TEXTCALLBACK32A))
+		COMCTL32_Free (lpSubItem->pszText);
+	    lpSubItem->pszText = LPSTR_TEXTCALLBACK32A;
+	}
+	else {
+	    if (lpSubItem->pszText == LPSTR_TEXTCALLBACK32A)
+		lpSubItem->pszText = NULL;
+	    Str_SetPtr32A (&lpSubItem->pszText, lpItem->pszText);
+	}
+    }
+
+    if (lpItem->mask & LVIF_IMAGE)
+	lpSubItem->iImage = lpItem->iImage;
+
+    if (lpItem->mask & LVIF_PARAM)
+	lpSubItem->lParam = lpItem->lParam;
+
+    if (lpItem->mask & LVIF_INDENT)
+	lpSubItem->iIndent = lpItem->iIndent;
+
+    /* send LVN_ITEMCHANGED notification */
+    nmlv.hdr.code = LVN_ITEMCHANGED;
+    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
+		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
+
+    return TRUE;
+}
+
+
+// << LISTVIEW_SetItem32W >>
+// << LISTVIEW_SetItemCount >>
+
+
+static LRESULT
+LISTVIEW_SetItemPosition (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+    INT32 nIndex = (INT32)wParam;
+
+    if ((nIndex < 0) || (nIndex >= infoPtr->nItemCount))
+	return FALSE;
+
+    FIXME (listview, "setting position [%d, %d]!\n",
+	   (INT32)LOWORD(lParam), (INT32)HIWORD(lParam));
+
+    /* FIXME: set position */
+
+    return TRUE;
+}
+
+
+static LRESULT
+LISTVIEW_SetTextBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+
+    if (!infoPtr)
+	return FALSE;
+
+    /* set text background color */
+    TRACE (listview, "0x%06lx\n", (COLORREF)lParam);
+    infoPtr->clrTextBk = (COLORREF)lParam;
+
+    return TRUE;
+}
+
+
+static LRESULT
+LISTVIEW_SetTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+
+    if (!infoPtr)
+	return FALSE;
+
+    /* set text color */
+    TRACE (listview, "0x%06lx\n", (COLORREF)lParam);
+    infoPtr->clrText = (COLORREF)lParam;
+
+    return TRUE;
+}
+
+
+
+static LRESULT
+LISTVIEW_SortItems (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+//    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+
+    FIXME (listview, "empty stub!\n");
+
+    /* fake success */
+    return TRUE;
+}
+
+
+
 
 static LRESULT
 LISTVIEW_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
@@ -261,9 +889,13 @@
     LOGFONT32A logFont;
     DWORD dwStyle = WS_CHILD | WS_VISIBLE; 
 
+    TRACE (listview, "styles 0x%08lx 0x%08lx\n",
+	   wndPtr->dwStyle, wndPtr->dwExStyle);
 
     /* initialize info structure */
     infoPtr->clrBk = CLR_NONE;
+    infoPtr->clrText = RGB(0, 0, 0); /* preliminary */
+    infoPtr->clrTextBk = RGB(255, 255, 255); /* preliminary */
 
     if (!(wndPtr->dwStyle & LVS_REPORT) ||
 	 (wndPtr->dwStyle & LVS_NOCOLUMNHEADER))
@@ -286,8 +918,7 @@
     SendMessage32A (infoPtr->hwndHeader, WM_SETFONT,
 		    (WPARAM32)infoPtr->hFont, (LPARAM)TRUE);
 
-
-    infoPtr->hdsaItems = DSA_Create (sizeof(LISTVIEW_ITEM), 10);
+    infoPtr->hdpaItems = DPA_Create (10);
 
     return 0;
 }
@@ -298,7 +929,11 @@
 {
     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
 
-    DSA_Destroy (infoPtr->hdsaItems);
+    /* delete all items */
+    LISTVIEW_DeleteAllItems (wndPtr);
+
+    /* destroy dpa */
+    DPA_Destroy (infoPtr->hdpaItems);
 
     /* destroy header */
     if (infoPtr->hwndHeader)
@@ -330,7 +965,8 @@
 	DeleteObject32 (hBrush);
 	return FALSE;
     }
-    return FALSE;
+
+    return TRUE;
 }
 
 
@@ -345,7 +981,78 @@
 
 // << LISTVIEW_HScroll >>
 // << LISTVIEW_KeyDown >>
-// << LISTVIEW_KillFocus >>
+
+
+static LRESULT
+LISTVIEW_KillFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+    NMHDR nmh;
+
+    FIXME (listview, "semi stub!\n");
+
+    nmh.hwndFrom = wndPtr->hwndSelf;
+    nmh.idFrom   = wndPtr->wIDmenu;
+    nmh.code = NM_KILLFOCUS;
+
+    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
+		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmh);
+
+    infoPtr->bFocus = FALSE;
+
+    return 0;
+}
+
+
+static LRESULT
+LISTVIEW_LButtonDblClk (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+    NMLISTVIEW nmlv;
+
+    FIXME (listview, "semi stub!\n");
+
+    ZeroMemory (&nmlv, sizeof(NMLISTVIEW));
+    nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
+    nmlv.hdr.idFrom   = wndPtr->wIDmenu;
+    nmlv.hdr.code = NM_DBLCLK;
+    nmlv.iItem    = -1;
+    nmlv.iSubItem = 0;
+    nmlv.ptAction.x = (INT32)LOWORD(lParam);
+    nmlv.ptAction.y = (INT32)HIWORD(lParam);
+
+    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
+		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
+
+    return 0;
+}
+
+
+static LRESULT
+LISTVIEW_LButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+    NMLISTVIEW nmlv;
+
+    FIXME (listview, "semi stub!\n");
+
+    ZeroMemory (&nmlv, sizeof(NMLISTVIEW));
+    nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
+    nmlv.hdr.idFrom   = wndPtr->wIDmenu;
+    nmlv.hdr.code = NM_CLICK;
+    nmlv.iItem    = -1;
+    nmlv.iSubItem = 0;
+    nmlv.ptAction.x = (INT32)LOWORD(lParam);
+    nmlv.ptAction.y = (INT32)HIWORD(lParam);
+
+    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
+		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
+
+    if (!infoPtr->bFocus)
+	SetFocus32 (wndPtr->hwndSelf);
+
+    return 0;
+}
 
 
 static LRESULT
@@ -387,6 +1094,25 @@
 
 
 static LRESULT
+LISTVIEW_Notify (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+    LPNMHDR lpnmh = (LPNMHDR)lParam;
+
+    if (lpnmh->hwndFrom == infoPtr->hwndHeader) {
+
+	FIXME (listview, "WM_NOTIFY from header!\n");
+    }
+    else {
+
+	FIXME (listview, "WM_NOTIFY from unknown source!\n");
+    }
+
+    return 0;
+}
+
+
+static LRESULT
 LISTVIEW_Paint (WND *wndPtr, WPARAM32 wParam)
 {
     HDC32 hdc;
@@ -400,6 +1126,73 @@
 }
 
 
+static LRESULT
+LISTVIEW_RButtonDblClk (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+    NMLISTVIEW nmlv;
+
+    FIXME (listview, "semi stub!\n");
+
+    ZeroMemory (&nmlv, sizeof(NMLISTVIEW));
+    nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
+    nmlv.hdr.idFrom   = wndPtr->wIDmenu;
+    nmlv.hdr.code = NM_RDBLCLK;
+    nmlv.iItem    = -1;
+    nmlv.iSubItem = 0;
+    nmlv.ptAction.x = (INT32)LOWORD(lParam);
+    nmlv.ptAction.y = (INT32)HIWORD(lParam);
+
+    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
+		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
+
+    return 0;
+}
+
+
+static LRESULT
+LISTVIEW_RButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+    NMLISTVIEW nmlv;
+
+    FIXME (listview, "semi stub!\n");
+
+    ZeroMemory (&nmlv, sizeof(NMLISTVIEW));
+    nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
+    nmlv.hdr.idFrom   = wndPtr->wIDmenu;
+    nmlv.hdr.code = NM_RCLICK;
+    nmlv.iItem    = -1;
+    nmlv.iSubItem = 0;
+    nmlv.ptAction.x = (INT32)LOWORD(lParam);
+    nmlv.ptAction.y = (INT32)HIWORD(lParam);
+
+    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
+		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
+
+    return 0;
+}
+
+
+static LRESULT
+LISTVIEW_SetFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+    NMHDR nmh;
+
+    FIXME (listview, "semi stub!\n");
+
+    nmh.hwndFrom = wndPtr->hwndSelf;
+    nmh.idFrom   = wndPtr->wIDmenu;
+    nmh.code = NM_SETFOCUS;
+
+    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
+		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmh);
+
+    infoPtr->bFocus = TRUE;
+
+    return 0;
+}
 
 
 static LRESULT
@@ -433,24 +1226,28 @@
 LISTVIEW_Size (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-    HDLAYOUT hl;
-    WINDOWPOS32 wp;
-    RECT32 rc;
-
-    rc.top = 0;
-    rc.left = 0;
-    rc.right = LOWORD(lParam);
-    rc.bottom = HIWORD(lParam);
-
-    hl.prc = &rc;
-    hl.pwpos = &wp;
-    SendMessage32A (infoPtr->hwndHeader, HDM_LAYOUT, 0, (LPARAM)&hl);
-
-    SetWindowPos32 (infoPtr->hwndHeader, wndPtr->hwndSelf,
-		    wp.x, wp.y, wp.cx, wp.cy, wp.flags);
 
     GetClientRect32 (wndPtr->hwndSelf, &infoPtr->rcList);
-    infoPtr->rcList.top += wp.cy;
+
+    if (wndPtr->dwStyle & LVS_REPORT) {
+	HDLAYOUT hl;
+	WINDOWPOS32 wp;
+	RECT32 rc;
+
+	rc.top = 0;
+	rc.left = 0;
+	rc.right = LOWORD(lParam);
+	rc.bottom = HIWORD(lParam);
+
+	hl.prc = &rc;
+	hl.pwpos = &wp;
+	SendMessage32A (infoPtr->hwndHeader, HDM_LAYOUT, 0, (LPARAM)&hl);
+
+	SetWindowPos32 (infoPtr->hwndHeader, wndPtr->hwndSelf,
+			wp.x, wp.y, wp.cx, wp.cy, wp.flags);
+
+	infoPtr->rcList.top += wp.cy;
+    }
 
     return 0;
 }
@@ -463,24 +1260,54 @@
 
     switch (uMsg)
     {
-//	case LVM_DELETEALLITEMS:
+//	case LVM_APPROXIMATEVIEWRECT:
+//	case LVM_ARRANGE:
+//	case LVM_CREATEDRAGIMAGE:
 
-        case LVM_GETBKCOLOR:
+	case LVM_DELETEALLITEMS:
+	    return LISTVIEW_DeleteAllItems (wndPtr);
+
+	case LVM_DELETECOLUMN:
+	    return LISTVIEW_DeleteColumn (wndPtr, wParam, lParam);
+
+	case LVM_DELETEITEM:
+	    return LISTVIEW_DeleteItem (wndPtr, wParam, lParam);
+
+//	case LVM_EDITLABEL:
+//	case LVM_ENSUREVISIBLE:
+//	case LVM_FINDITEM:
+
+	case LVM_GETBKCOLOR:
 	    return LISTVIEW_GetBkColor (wndPtr, wParam, lParam);
 
+//	case LVM_GETBKIMAGE:
+//	case LVM_GETCALLBACKMASK:
 
-        case LVM_GETCOLUMNWIDTH:
+	case LVM_GETCOLUMN32A:
+	    return LISTVIEW_GetColumn32A (wndPtr, wParam, lParam);
+
+//	case LVM_GETCOLUMN32W:
+//	case LVM_GETCOLUMNORDERARRAY:
+
+	case LVM_GETCOLUMNWIDTH:
 	    return LISTVIEW_GetColumnWidth (wndPtr, wParam, lParam);
 
+//	case LVM_GETCOUNTPERPAGE:
+//	case LVM_GETEDITCONTROL:
+//	case LVM_GETEXTENDEDLISTVIEWSTYLE:
 
-        case LVM_GETHEADER:
+	case LVM_GETHEADER:
 	    return LISTVIEW_GetHeader (wndPtr, wParam, lParam);
 
-//	case LVM_GETISEARCHSTRING:
+//	case LVM_GETHOTCURSOR:
+//	case LVM_GETHOTITEM:
+//	case LVM_GETHOVERTIME:
 
 	case LVM_GETIMAGELIST:
 	    return LISTVIEW_GetImageList (wndPtr, wParam, lParam);
 
+//	case LVM_GETISEARCHSTRING:
+
 	case LVM_GETITEM32A:
 	    return LISTVIEW_GetItem32A (wndPtr, wParam, lParam);
 
@@ -489,7 +1316,28 @@
 	case LVM_GETITEMCOUNT:
 	    return LISTVIEW_GetItemCount (wndPtr, wParam, lParam);
 
-//	case LVM_GETSELECTEDCOUNT:
+	case LVM_GETITEMPOSITION:
+	    return LISTVIEW_GetItemPosition (wndPtr, wParam, lParam);
+
+//	case LVM_GETITEMRECT:
+//	case LVM_GETITEMSPACING:
+//	case LVM_GETITEMSTATE:
+
+	case LVM_GETITEMTEXT32A:
+	    return LISTVIEW_GetItemText32A (wndPtr, wParam, lParam);
+
+//	case LVM_GETITEMTEXT32W:
+
+	case LVM_GETNEXTITEM:
+	    return LISTVIEW_GetNextItem (wndPtr, wParam, lParam);
+
+//	case LVM_GETNUMBEROFWORKAREAS:
+//	case LVM_GETORIGIN:
+
+	case LVM_GETSELECTEDCOUNT:
+	    return LISTVIEW_GetSelectedCount (wndPtr, wParam, lParam);
+
+//	case LVM_GETSELECTIONMARK:
 
 	case LVM_GETSTRINGWIDTH32A:
 	    return LISTVIEW_GetStringWidth32A (wndPtr, wParam, lParam);
@@ -497,26 +1345,85 @@
 //	case LVM_GETSTRINGWIDTH32W:
 //	case LVM_GETSUBITEMRECT:
 
+	case LVM_GETTEXTBKCOLOR:
+	    return LISTVIEW_GetTextBkColor (wndPtr, wParam, lParam);
+
+	case LVM_GETTEXTCOLOR:
+	    return LISTVIEW_GetTextColor (wndPtr, wParam, lParam);
+
+//	case LVM_GETTOOLTIPS:
+//	case LVM_GETTOPINDEX:
+//	case LVM_GETUNICODEFORMAT:
+//	case LVM_GETVIEWRECT:
+//	case LVM_GETWORKAREAS:
+//	case LVM_HITTEST:
+
 	case LVM_INSERTCOLUMN32A:
 	    return LISTVIEW_InsertColumn32A (wndPtr, wParam, lParam);
 
-
 //	case LVM_INSERTCOLUMN32W:
 
-//	case LVM_INSERTITEM32A:
+	case LVM_INSERTITEM32A:
+	    return LISTVIEW_InsertItem32A (wndPtr, wParam, lParam);
+
 //	case LVM_INSERTITEM32W:
 
+	case LVM_REDRAWITEMS:
+	    return LISTVIEW_RedrawItems (wndPtr, wParam, lParam);
+
+//	case LVM_SCROLL:
 
 	case LVM_SETBKCOLOR:
 	    return LISTVIEW_SetBkColor (wndPtr, wParam, lParam);
 
+//	case LVM_SETBKIMAGE:
+//	case LVM_SETCALLBACKMASK:
+
+	case LVM_SETCOLUMN32A:
+	    return LISTVIEW_SetColumn32A (wndPtr, wParam, lParam);
+
+//	case LVM_SETCOLUMN32W:
+//	case LVM_SETCOLUMNORDERARRAY:
+//	case LVM_SETCOLUMNWIDTH:
+//	case LVM_SETEXTENDEDLISTVIEWSTYLE:
+//	case LVM_SETHOTCURSOR:
+//	case LVM_SETHOTITEM:
+//	case LVM_SETHOVERTIME:
+//	case LVM_SETICONSPACING:
 	
 	case LVM_SETIMAGELIST:
 	    return LISTVIEW_SetImageList (wndPtr, wParam, lParam);
 
-//	case LVM_SETITEMPOSITION:
+	case LVM_SETITEM32A:
+	    return LISTVIEW_SetItem32A (wndPtr, wParam, lParam);
 
-//	case LVM_SORTITEMS:
+//	case LVM_SETITEM32W:
+//	case LVM_SETITEMCOUNT:
+
+	case LVM_SETITEMPOSITION:
+	    return LISTVIEW_SetItemPosition (wndPtr, wParam, lParam);
+
+//	case LVM_SETITEMPOSITION32:
+//	case LVM_SETITEMSTATE:
+//	case LVM_SETITEMTEXT:
+//	case LVM_SETSELECTIONMARK:
+
+	case LVM_SETTEXTBKCOLOR:
+	    return LISTVIEW_SetTextBkColor (wndPtr, wParam, lParam);
+
+	case LVM_SETTEXTCOLOR:
+	    return LISTVIEW_SetTextColor (wndPtr, wParam, lParam);
+
+//	case LVM_SETTOOLTIPS:
+//	case LVM_SETUNICODEFORMAT:
+//	case LVM_SETWORKAREAS:
+
+	case LVM_SORTITEMS:
+	    return LISTVIEW_SortItems (wndPtr, wParam, lParam);
+
+//	case LVM_SUBITEMHITTEST:
+//	case LVM_UPDATE:
+
 
 
 //	case WM_CHAR:
@@ -538,6 +1445,16 @@
 	    return LISTVIEW_GetFont (wndPtr, wParam, lParam);
 
 //	case WM_HSCROLL:
+//	case WM_KEYDOWN:
+
+	case WM_KILLFOCUS:
+	    return LISTVIEW_KillFocus (wndPtr, wParam, lParam);
+
+	case WM_LBUTTONDBLCLK:
+	    return LISTVIEW_LButtonDblClk (wndPtr, wParam, lParam);
+
+	case WM_LBUTTONDOWN:
+	    return LISTVIEW_LButtonDown (wndPtr, wParam, lParam);
 
 //	case WM_MOUSEMOVE:
 //	    return LISTVIEW_MouseMove (wndPtr, wParam, lParam);
@@ -548,13 +1465,20 @@
 	case WM_NCDESTROY:
 	    return LISTVIEW_NCDestroy (wndPtr, wParam, lParam);
 
-//	case WM_NOTIFY:
+	case WM_NOTIFY:
+	    return LISTVIEW_Notify (wndPtr, wParam, lParam);
 
 	case WM_PAINT:
 	    return LISTVIEW_Paint (wndPtr, wParam);
 
-//	case WM_RBUTTONDOWN:
-//	case WM_SETFOCUS:
+	case WM_RBUTTONDBLCLK:
+	    return LISTVIEW_RButtonDblClk (wndPtr, wParam, lParam);
+
+	case WM_RBUTTONDOWN:
+	    return LISTVIEW_RButtonDown (wndPtr, wParam, lParam);
+
+	case WM_SETFOCUS:
+	    return LISTVIEW_SetFocus (wndPtr, wParam, lParam);
 
 	case WM_SETFONT:
 	    return LISTVIEW_SetFont (wndPtr, wParam, lParam);
diff --git a/dlls/comctl32/pager.c b/dlls/comctl32/pager.c
index e5c231e..815a55f 100644
--- a/dlls/comctl32/pager.c
+++ b/dlls/comctl32/pager.c
@@ -169,7 +169,7 @@
     SetParent32 (infoPtr->hwndChild, wndPtr->hwndSelf);
     SetWindowPos32 (infoPtr->hwndChild, wndPtr->hwndSelf,
 		    0, 0, 40, 40, SWP_SHOWWINDOW);
-    RedrawWindow32 (wndPtr->hwndSelf, NULL, 0, RDW_INVALIDATE);
+    RedrawWindow32 (wndPtr->hwndSelf, NULL, NULL, RDW_INVALIDATE);
 
     return 0;
 }
diff --git a/dlls/comctl32/progress.c b/dlls/comctl32/progress.c
index 3acb294..ad08872 100644
--- a/dlls/comctl32/progress.c
+++ b/dlls/comctl32/progress.c
@@ -8,9 +8,8 @@
  */
 
 #include "windows.h"
-#include "progress.h"
 #include "commctrl.h"
-#include "heap.h"
+#include "progress.h"
 #include "win.h"
 #include "debug.h"
 
@@ -185,8 +184,7 @@
     case WM_CREATE:
       /* allocate memory for info struct */
       infoPtr = 
-	(PROGRESS_INFO *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-                                    sizeof(PROGRESS_INFO));
+	(PROGRESS_INFO *)COMCTL32_Alloc (sizeof(PROGRESS_INFO));
       wndPtr->wExtra[0] = (DWORD)infoPtr;
 
       /* initialize the info struct */
@@ -200,8 +198,8 @@
       break;
     
     case WM_DESTROY:
-      TRACE(progress, "Progress Ctrl destruction, hwnd=%04x\n", hwnd);
-      HeapFree (GetProcessHeap (), 0, infoPtr);
+      TRACE (progress, "Progress Ctrl destruction, hwnd=%04x\n", hwnd);
+      COMCTL32_Free (infoPtr);
       break;
 
     case WM_ERASEBKGND:
@@ -328,11 +326,12 @@
 
 
 /***********************************************************************
- *           PROGRESS_Register [Internal]
+ * PROGRESS_Register [Internal]
  *
  * Registers the progress bar window class.
  * 
  */
+
 void 
 PROGRESS_Register(void)
 {
diff --git a/dlls/comctl32/rebar.c b/dlls/comctl32/rebar.c
index b27b5f5..2936d96 100644
--- a/dlls/comctl32/rebar.c
+++ b/dlls/comctl32/rebar.c
@@ -16,7 +16,6 @@
 #include "windows.h"
 #include "commctrl.h"
 #include "rebar.h"
-#include "heap.h"
 #include "win.h"
 #include "debug.h"
 
@@ -42,10 +41,24 @@
 
 
 
-
-
 // << REBAR_BeginDrag >>
-// << REBAR_DeleteBand >>
+
+
+static LRESULT
+REBAR_DeleteBand (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
+    UINT32 uBand = (UINT32)wParam;
+
+    if (uBand >= infoPtr->uNumBands)
+	return FALSE;
+
+    FIXME (rebar, "deleting band %u!\n", uBand);
+
+    return TRUE;
+}
+
+
 // << REBAR_DragMove >>
 // << REBAR_EndDrag >>
 // << REBAR_GetBandBorders >>
@@ -246,16 +259,13 @@
     TRACE (rebar, "insert band at %u!\n", uIndex);
 
     if (infoPtr->uNumBands == 0) {
-	infoPtr->bands =
-	    (REBAR_BAND *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-				     sizeof (REBAR_BAND));
+	infoPtr->bands = (REBAR_BAND *)COMCTL32_Alloc (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));
+	    (REBAR_BAND *)COMCTL32_Alloc ((infoPtr->uNumBands+1)*sizeof(REBAR_BAND));
 	if (((INT32)uIndex == -1) || (uIndex > infoPtr->uNumBands))
 	    uIndex = infoPtr->uNumBands;
 
@@ -271,7 +281,7 @@
 		    (infoPtr->uNumBands - uIndex - 1) * sizeof(REBAR_BAND));
 	}
 
-	HeapFree (GetProcessHeap (), 0, &oldBands);
+	COMCTL32_Free (&oldBands);
     }
 
     infoPtr->uNumBands++;
@@ -292,8 +302,7 @@
     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);
+	    lpBand->lpText = (LPSTR)COMCTL32_Alloc (len + 1);
 	    lstrcpy32A (lpBand->lpText, lprbbi->lpText);
 	}
     }
@@ -377,8 +386,7 @@
 /*
 	INT32 len = lstrlen32A (lprbbi->lpText);
 	if (len > 0) {
-	    lpBand->lpText = 
-		(LPSTR)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len + 1);
+	    lpBand->lpText = (LPSTR)COMCTL32_Alloc (len + 1);
 	    lstrcpy32A (lpBand->lpText, lprbbi->lpText);
 	}
 */
@@ -566,13 +574,13 @@
 
 	    /* delete text strings */
 	    if (lpBand->lpText) {
-		HeapFree (GetProcessHeap (), 0, lpBand->lpText);
+		COMCTL32_Free (lpBand->lpText);
 		lpBand->lpText = NULL;
 	    }
 	}
 
 	/* free band array */
-	HeapFree (GetProcessHeap (), 0, infoPtr->bands);
+	COMCTL32_Free (infoPtr->bands);
 	infoPtr->bands = NULL;
     }
 
@@ -608,7 +616,10 @@
     switch (uMsg)
     {
 //	case RB_BEGINDRAG:
-//	case RB_DELETEBAND:
+
+	case RB_DELETEBAND:
+	    return REBAR_DeleteBand (wndPtr, wParam, lParam);
+
 //	case RB_DRAGMOVE:
 //	case RB_ENDDRAG:
 //	case RB_GETBANDBORDERS:
@@ -621,7 +632,6 @@
 	case RB_GETBANDINFO32A:
 	    return REBAR_GetBandInfo32A (wndPtr, wParam, lParam);
 
-
 //	case RB_GETBANDINFO32W:
 
 	case RB_GETBARHEIGHT:
diff --git a/dlls/comctl32/status.c b/dlls/comctl32/status.c
index 6536fa9..a2c710e 100644
--- a/dlls/comctl32/status.c
+++ b/dlls/comctl32/status.c
@@ -6,9 +6,8 @@
  */
 
 #include "windows.h"
-#include "status.h"
 #include "commctrl.h"
-#include "heap.h"
+#include "status.h"
 #include "win.h"
 #include "debug.h"
 
@@ -528,17 +527,16 @@
     if (oldNumParts > self->numParts) {
 	for (i = self->numParts ; i < oldNumParts; i++) {
 	    if (self->parts[i].text && (self->parts[i].style != SBT_OWNERDRAW))
-		HeapFree(GetProcessHeap (), 0, self->parts[i].text);
+		COMCTL32_Free (self->parts[i].text);
 	}
     }
     else if (oldNumParts < self->numParts) {
-	tmp = HeapAlloc(GetProcessHeap (), HEAP_ZERO_MEMORY,
-			sizeof(STATUSWINDOWPART) * self->numParts);
+	tmp = COMCTL32_Alloc (sizeof(STATUSWINDOWPART) * self->numParts);
 	for (i = 0; i < oldNumParts; i++) {
 	    tmp[i] = self->parts[i];
 	}
 	if (self->parts)
-	    HeapFree(GetProcessHeap (), 0, self->parts);
+	    COMCTL32_Free (self->parts);
 	self->parts = tmp;
     }
     
@@ -614,10 +612,10 @@
     else {
 	/* duplicate string */
 	if (part->text)
-	    HeapFree (GetProcessHeap (), 0, part->text);
+	    COMCTL32_Free (part->text);
 	part->text = 0;
 	if (text && (len = lstrlen32A(text))) {
-	    part->text = HeapAlloc (GetProcessHeap (), 0, len+1);
+	    part->text = COMCTL32_Alloc (len+1);
 	    lstrcpy32A(part->text, text);
 	}
     }
@@ -694,8 +692,7 @@
     HDC32	hdc;
     STATUSWINDOWINFO *self;
 
-    self = (STATUSWINDOWINFO*)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-					 sizeof(STATUSWINDOWINFO));
+    self = (STATUSWINDOWINFO*)COMCTL32_Alloc (sizeof(STATUSWINDOWINFO));
     wndPtr->wExtra[0] = (DWORD)self;
 
     self->numParts = 1;
@@ -717,8 +714,7 @@
     self->part0.hIcon = 0;
 
     /* initialize first part */
-    self->parts = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-			     sizeof(STATUSWINDOWPART));
+    self->parts = COMCTL32_Alloc (sizeof(STATUSWINDOWPART));
     self->parts[0].bound = rect;
     self->parts[0].text = 0;
     self->parts[0].x = -1;
@@ -726,7 +722,7 @@
     self->parts[0].hIcon = 0;
 
     if ((len = lstrlen32A (lpCreate->lpszName))) {
-        self->parts[0].text = HeapAlloc (GetProcessHeap (), 0, len + 1);
+        self->parts[0].text = COMCTL32_Alloc (len + 1);
         lstrcpy32A (self->parts[0].text, lpCreate->lpszName);
     }
 
@@ -781,11 +777,11 @@
 
     for (i = 0; i < self->numParts; i++) {
 	if (self->parts[i].text && (self->parts[i].style != SBT_OWNERDRAW))
-	    HeapFree(GetProcessHeap (), 0, self->parts[i].text);
+	    COMCTL32_Free (self->parts[i].text);
     }
     if (self->part0.text && (self->part0.style != SBT_OWNERDRAW))
-	HeapFree(GetProcessHeap (), 0, self->part0.text);
-    HeapFree(GetProcessHeap (), 0, self->parts);
+	COMCTL32_Free (self->part0.text);
+    COMCTL32_Free (self->parts);
 
     /* delete default font */
     if (self->hDefaultFont)
@@ -795,7 +791,7 @@
     if (self->hwndToolTip)
 	DestroyWindow32 (self->hwndToolTip);
 
-    HeapFree(GetProcessHeap (), 0, self);
+    COMCTL32_Free (self);
 
     return 0;
 }
@@ -939,10 +935,10 @@
     part = &self->parts[0];
     /* duplicate string */
     if (part->text)
-        HeapFree(GetProcessHeap (), 0, part->text);
+        COMCTL32_Free (part->text);
     part->text = 0;
     if (lParam && (len = lstrlen32A((LPCSTR)lParam))) {
-        part->text = HeapAlloc (GetProcessHeap (), 0, len+1);
+        part->text = COMCTL32_Alloc (len+1);
         lstrcpy32A (part->text, (LPCSTR)lParam);
     }
 
diff --git a/dlls/comctl32/toolbar.c b/dlls/comctl32/toolbar.c
index a1ac4e3..2a89d4b 100644
--- a/dlls/comctl32/toolbar.c
+++ b/dlls/comctl32/toolbar.c
@@ -4,11 +4,9 @@
  * Copyright 1998 Eric Kohl
  *
  * TODO:
- *   - Bitmap drawing.
  *   - Button wrapping.
  *   - Messages.
  *   - Notifications.
- *   - Fix TB_GETBITMAPFLAGS.
  *   - Fix TB_GETROWS and TB_SETROWS.
  *   - Tooltip support (almost complete).
  *   - Unicode suppport.
@@ -27,11 +25,10 @@
  */
 
 #include "windows.h"
-#include "sysmetrics.h"
 #include "commctrl.h"
+#include "sysmetrics.h"
 #include "cache.h"
 #include "toolbar.h"
-#include "heap.h"
 #include "win.h"
 #include "debug.h"
 
@@ -67,13 +64,13 @@
 TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
 		    HDC32 hdc, INT32 nState)
 {
-    RECT32 rcText = btnPtr->rect;
-    HFONT32 hOldFont;
-    INT32   nOldBkMode;
+    RECT32   rcText = btnPtr->rect;
+    HFONT32  hOldFont;
+    INT32    nOldBkMode;
+    COLORREF clrOld;
 
     /* draw text */
     if ((btnPtr->iString > -1) && (btnPtr->iString < infoPtr->nNumStrings)) {
-
 	InflateRect32 (&rcText, -3, -3);
 	rcText.top += infoPtr->nBitmapHeight;
 	if (nState & (TBSTATE_PRESSED | TBSTATE_CHECKED))
@@ -82,28 +79,27 @@
 	hOldFont = SelectObject32 (hdc, infoPtr->hFont);
 	nOldBkMode = SetBkMode32 (hdc, TRANSPARENT);
 	if (!(nState & TBSTATE_ENABLED)) {
-	    COLORREF clrOld = 
-		SetTextColor32 (hdc, GetSysColor32 (COLOR_3DHILIGHT));
+	    clrOld = SetTextColor32 (hdc, GetSysColor32 (COLOR_3DHILIGHT));
 	    OffsetRect32 (&rcText, 1, 1);
-	    DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1, &rcText,
-			 DT_CENTER);
+	    DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1,
+			 &rcText, infoPtr->dwDTFlags);
 	    SetTextColor32 (hdc, GetSysColor32 (COLOR_3DSHADOW));
 	    OffsetRect32 (&rcText, -1, -1);
-	    DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1, &rcText,
-			 DT_CENTER);
-	    SetTextColor32 (hdc, clrOld);
+	    DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1,
+			 &rcText, infoPtr->dwDTFlags);
 	}
 	else if (nState & TBSTATE_INDETERMINATE) {
-	    COLORREF clrOld = 
-		SetTextColor32 (hdc, GetSysColor32 (COLOR_3DSHADOW));
-	    DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1, &rcText,
-			 DT_CENTER);
-	    SetTextColor32 (hdc, clrOld);
+	    clrOld = SetTextColor32 (hdc, GetSysColor32 (COLOR_3DSHADOW));
+	    DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1,
+			 &rcText, infoPtr->dwDTFlags);
 	}
-	else
-	    DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1, &rcText,
-			 DT_CENTER);
+	else {
+	    clrOld = SetTextColor32 (hdc, GetSysColor32 (COLOR_BTNTEXT));
+	    DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1,
+			 &rcText, infoPtr->dwDTFlags);
+	}
 
+	SetTextColor32 (hdc, clrOld);
 	SelectObject32 (hdc, hOldFont);
 	if (nOldBkMode != TRANSPARENT)
 	    SetBkMode32 (hdc, nOldBkMode);
@@ -112,6 +108,46 @@
 
 
 static void
+TOOLBAR_DrawPattern (HDC32 hdc, LPRECT32 lpRect)
+{
+    HBRUSH32 hbr = SelectObject32 (hdc, CACHE_GetPattern55AABrush ());
+    INT32 cx = lpRect->right - lpRect->left;
+    INT32 cy = lpRect->bottom - lpRect->top;
+    PatBlt32 (hdc, lpRect->left, lpRect->top, cx, cy, 0x00FA0089);
+    SelectObject32 (hdc, hbr);
+}
+
+
+static void
+TOOLBAR_DrawMasked (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
+		    HDC32 hdc, INT32 x, INT32 y)
+{
+    /* FIXME: this function is a hack since it uses image list
+	      internals directly */
+
+    HDC32 hdcImageList = CreateCompatibleDC32 (0);
+    HIMAGELIST himl = infoPtr->himlDef;
+
+    /* draw the mask */
+    SelectObject32 (hdcImageList, himl->hbmMask);
+    SetBkColor32 (hdcImageList, RGB(255, 255, 255));
+    SetTextColor32 (hdcImageList, RGB(0, 0, 0));
+
+    SelectObject32 (hdc, GetSysColorBrush32 (COLOR_3DHILIGHT));
+    BitBlt32 (hdc, x+1, y+1, himl->cx, himl->cy,
+	      hdcImageList, himl->cx * btnPtr->iBitmap, 0,
+		  0xB8074A);
+
+    SelectObject32 (hdc, GetSysColorBrush32 (COLOR_3DSHADOW));
+    BitBlt32 (hdc, x, y, himl->cx, himl->cy,
+	      hdcImageList, himl->cx * btnPtr->iBitmap, 0,
+		  0xB8074A);
+
+    DeleteDC32 (hdcImageList);
+}
+
+
+static void
 TOOLBAR_DrawButton (WND *wndPtr, TBUTTON_INFO *btnPtr, HDC32 hdc)
 {
     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
@@ -129,12 +165,11 @@
 
     /* disabled */
     if (!(btnPtr->fsState & TBSTATE_ENABLED)) {
-	HICON32 hIcon;
 	DrawEdge32 (hdc, &rc, EDGE_RAISED,
 		    BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
 
-//	ImageList_Draw (infoPtr->himlDis, btnPtr->iBitmap, hdc,
-//			rc.left+1, rc.top+1, ILD_NORMAL);
+	TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
+
 	TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
 	return;
     }
@@ -152,7 +187,6 @@
     /* checked TBSTYLE_CHECK*/
     if ((btnPtr->fsStyle & TBSTYLE_CHECK) &&
 	(btnPtr->fsState & TBSTATE_CHECKED)) {
-	HBRUSH32 hbr;
 	if (bFlat)
 	    DrawEdge32 (hdc, &rc, BDR_SUNKENOUTER,
 			BF_RECT | BF_MIDDLE | BF_ADJUST);
@@ -160,10 +194,7 @@
 	    DrawEdge32 (hdc, &rc, EDGE_SUNKEN,
 			BF_RECT | BF_MIDDLE | BF_ADJUST);
 
-	hbr = SelectObject32 (hdc, CACHE_GetPattern55AABrush ());
-	PatBlt32 (hdc, rc.left, rc.top, rc.right - rc.left,
-		  rc.bottom - rc.top, 0x00FA0089);
-	SelectObject32 (hdc, hbr);
+	TOOLBAR_DrawPattern (hdc, &rc);
 	ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
 			rc.left+2, rc.top+2, ILD_NORMAL);
 	TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
@@ -172,16 +203,11 @@
 
     /* indeterminate */	
     if (btnPtr->fsState & TBSTATE_INDETERMINATE) {
-	HBRUSH32 hbr;
 	DrawEdge32 (hdc, &rc, EDGE_RAISED,
 		    BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
 
-	hbr = SelectObject32 (hdc, CACHE_GetPattern55AABrush ());
-	PatBlt32 (hdc, rc.left, rc.top, rc.right - rc.left,
-		  rc.bottom - rc.top, 0x00FA0089);
-	SelectObject32 (hdc, hbr);
-//	ImageList_Draw (infoPtr->himlDis, btnPtr->iBitmap, hdc,
-//			rc.left+1, rc.top+1, ILD_NORMAL);
+	TOOLBAR_DrawPattern (hdc, &rc);
+	TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
 	TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
 	return;
     }
@@ -495,7 +521,7 @@
     if (lpAddBmp->hInst == (HINSTANCE32)0) {
 	nIndex = 
 	    ImageList_AddMasked (infoPtr->himlDef, (HBITMAP32)lpAddBmp->nID,
-				 GetSysColor32 (COLOR_3DFACE));
+				 CLR_DEFAULT);
     }
     else if (lpAddBmp->hInst == HINST_COMMCTRL) {
 	/* add internal bitmaps */
@@ -510,7 +536,7 @@
 	HBITMAP32 hBmp =
 	    LoadBitmap32A (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID);
 
-	nIndex = ImageList_Add (infoPtr->himlDef, hBmp, (HBITMAP32)0);
+	nIndex = ImageList_AddMasked (infoPtr->himlDef, hBmp, CLR_DEFAULT);
 
 	DeleteObject32 (hBmp); 
     }
@@ -538,17 +564,15 @@
 
     if (infoPtr->nNumButtons == 0) {
 	infoPtr->buttons =
-	    HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-		       sizeof (TBUTTON_INFO) * nNewButtons);
+	    COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
     }
     else {
 	TBUTTON_INFO *oldButtons = infoPtr->buttons;
 	infoPtr->buttons =
-	    HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-		       sizeof (TBUTTON_INFO) * nNewButtons);
+	    COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
 	memcpy (&infoPtr->buttons[0], &oldButtons[0],
 		nOldButtons * sizeof(TBUTTON_INFO));
-        HeapFree (GetProcessHeap (), 0, oldButtons);
+        COMCTL32_Free (oldButtons);
     }
 
     infoPtr->nNumButtons = nNewButtons;
@@ -609,20 +633,19 @@
 	nIndex = infoPtr->nNumStrings;
 	if (infoPtr->nNumStrings == 0) {
 	    infoPtr->strings =
-		HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(char *));
+		COMCTL32_Alloc (sizeof(char *));
 	}
 	else {
 	    char **oldStrings = infoPtr->strings;
 	    infoPtr->strings =
-		HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-			   sizeof(char *) * (infoPtr->nNumStrings + 1));
+		COMCTL32_Alloc (sizeof(char *) * (infoPtr->nNumStrings + 1));
 	    memcpy (&infoPtr->strings[0], &oldStrings[0],
 		    sizeof(char *) * infoPtr->nNumStrings);
-	    HeapFree (GetProcessHeap (), 0, oldStrings);
+	    COMCTL32_Free (oldStrings);
 	}
 
 	infoPtr->strings[infoPtr->nNumStrings] =
-	    HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(char)*(len+1));
+	    COMCTL32_Alloc (sizeof(char)*(len+1));
 	lstrcpy32A (infoPtr->strings[infoPtr->nNumStrings], szString);
 	infoPtr->nNumStrings++;
     }
@@ -639,20 +662,19 @@
 
 	    if (infoPtr->nNumStrings == 0) {
 		infoPtr->strings =
-		    HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(char *));
+		    COMCTL32_Alloc (sizeof(char *));
 	    }
 	    else {
 		char **oldStrings = infoPtr->strings;
 		infoPtr->strings =
-		    HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-			       sizeof(char *) * (infoPtr->nNumStrings + 1));
+		    COMCTL32_Alloc (sizeof(char *) * (infoPtr->nNumStrings + 1));
 		memcpy (&infoPtr->strings[0], &oldStrings[0],
 			sizeof(char *) * infoPtr->nNumStrings);
-		HeapFree (GetProcessHeap (), 0, oldStrings);
+		COMCTL32_Free (oldStrings);
 	    }
 
 	    infoPtr->strings[infoPtr->nNumStrings] =
-		HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(char)*(len+1));
+		COMCTL32_Alloc (sizeof(char)*(len+1));
 	    lstrcpy32A (infoPtr->strings[infoPtr->nNumStrings], p);
 	    infoPtr->nNumStrings++;
 
@@ -841,7 +863,7 @@
 
     if (infoPtr->nNumButtons == 1) {
 	TRACE (toolbar, " simple delete!\n");
-	HeapFree (GetProcessHeap (), 0, infoPtr->buttons);
+	COMCTL32_Free (infoPtr->buttons);
 	infoPtr->buttons = NULL;
 	infoPtr->nNumButtons = 0;
     }
@@ -850,8 +872,7 @@
         TRACE(toolbar, "complex delete! [nIndex=%d]\n", nIndex);
 
 	infoPtr->nNumButtons--;
-	infoPtr->buttons = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-				      sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
+	infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
         if (nIndex > 0) {
             memcpy (&infoPtr->buttons[0], &oldButtons[0],
                     nIndex * sizeof(TBUTTON_INFO));
@@ -862,7 +883,7 @@
                     (infoPtr->nNumButtons - nIndex) * sizeof(TBUTTON_INFO));
         }
 
-        HeapFree (GetProcessHeap (), 0, oldButtons);
+	COMCTL32_Free (oldButtons);
     }
 
     TOOLBAR_CalcToolbar (wndPtr);
@@ -911,17 +932,16 @@
 
     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
     if (nIndex == -1)
-	return 0;
+	return -1;
 
     return infoPtr->buttons[nIndex].iBitmap;
 }
 
 
-static LRESULT
+static __inline__ LRESULT
 TOOLBAR_GetBitmapFlags (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
-    FIXME (toolbar, "stub!\n");
-    return 0;
+    return (GetDeviceCaps32 (0, LOGPIXELSX) >= 120) ? TBBF_LARGE : 0;
 }
 
 
@@ -1312,8 +1332,7 @@
 
     oldButtons = infoPtr->buttons;
     infoPtr->nNumButtons++;
-    infoPtr->buttons = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-				  sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
+    infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
     /* pre insert copy */
     if (nIndex > 0) {
 	memcpy (&infoPtr->buttons[0], &oldButtons[0],
@@ -1348,7 +1367,7 @@
 		(infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO));
     }
 
-    HeapFree (GetProcessHeap (), 0, oldButtons);
+    COMCTL32_Free (oldButtons);
 
     TOOLBAR_CalcToolbar (wndPtr);
 
@@ -1486,6 +1505,7 @@
 static LRESULT
 TOOLBAR_SaveRestore32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
+#if 0
     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
     LPTBSAVEPARAMS32A lpSave = (LPTBSAVEPARAMS32A)lParam;
 
@@ -1506,6 +1526,7 @@
 
 
     }
+#endif
 
     return 0;
 }
@@ -1565,13 +1586,13 @@
 	if ((btnPtr->iString >= 0) || 
 	    (btnPtr->iString < infoPtr->nNumStrings)) {
 #if 0
-	    CHAR *lpString = infoPtr->strings[btnPtr->iString];
+	    CHAR **lpString = &infoPtr->strings[btnPtr->iString];
 	    INT32 len = lstrlen32A (lptbbi->pszText);
-
-	    lpString = HeapReAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(char)*(len+1));
-
+	    *lpString = COMCTL32_ReAlloc (lpString, sizeof(char)*(len+1));
 #endif
 
+	    /* this is the ultimate sollution */
+//	    Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText);
 	}
     }
 
@@ -1654,7 +1675,18 @@
 }
 
 
-// << TOOLBAR_SetDrawTextFlags >>
+static LRESULT
+TOOLBAR_SetDrawTextFlags (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+    DWORD dwTemp;
+
+    dwTemp = infoPtr->dwDTFlags;
+    infoPtr->dwDTFlags =
+	(infoPtr->dwDTFlags & (DWORD)wParam) | (DWORD)lParam;
+
+    return (LRESULT)dwTemp;
+}
 
 
 static LRESULT
@@ -1910,6 +1942,7 @@
     infoPtr->hwndNotify = GetParent32 (wndPtr->hwndSelf);
     infoPtr->bTransparent = (wndPtr->dwStyle & TBSTYLE_FLAT);
     infoPtr->nHotItem = -1;
+    infoPtr->dwDTFlags = DT_CENTER;
 
     SystemParametersInfo32A (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
     infoPtr->hFont = CreateFontIndirect32A (&logFont);
@@ -1951,16 +1984,16 @@
 
     /* delete button data */
     if (infoPtr->buttons)
-	HeapFree (GetProcessHeap (), 0, infoPtr->buttons);
+	COMCTL32_Free (infoPtr->buttons);
 
     /* delete strings */
     if (infoPtr->strings) {
 	INT32 i;
 	for (i = 0; i < infoPtr->nNumStrings; i++)
 	    if (infoPtr->strings[i])
-		HeapFree (GetProcessHeap (), 0, infoPtr->strings[i]);
+		COMCTL32_Free (infoPtr->strings[i]);
 
-	HeapFree (GetProcessHeap (), 0, infoPtr->strings);
+	COMCTL32_Free (infoPtr->strings);
     }
 
     /* destroy default image list */
@@ -1980,7 +2013,7 @@
 	DeleteObject32 (infoPtr->hFont);
 
     /* free toolbar info data */
-    HeapFree (GetProcessHeap (), 0, infoPtr);
+    COMCTL32_Free (infoPtr);
 
     return 0;
 }
@@ -2178,7 +2211,15 @@
 }
 
 
-// << TOOLBAR_NCActivate >>
+__inline__ static LRESULT
+TOOLBAR_NCActivate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+//    if (wndPtr->dwStyle & CCS_NODIVIDER)
+	return DefWindowProc32A (wndPtr->hwndSelf, WM_NCACTIVATE,
+				 wParam, lParam);
+//    else
+//	return TOOLBAR_NCPaint (wndPtr, wParam, lParam);
+}
 
 
 __inline__ static LRESULT
@@ -2197,8 +2238,7 @@
     TOOLBAR_INFO *infoPtr;
 
     /* allocate memory for info structure */
-    infoPtr = (TOOLBAR_INFO *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-                                   sizeof(TOOLBAR_INFO));
+    infoPtr = (TOOLBAR_INFO *)COMCTL32_Alloc (sizeof(TOOLBAR_INFO));
     wndPtr->wExtra[0] = (DWORD)infoPtr;
 
     if (infoPtr == NULL) {
@@ -2568,7 +2608,8 @@
 	case TB_SETDISABLEDIMAGELIST:
 	    return TOOLBAR_SetDisabledImageList (wndPtr, wParam, lParam);
 
-//	case TB_SETDRAWTEXTFLAGS:		/* 4.71 */
+	case TB_SETDRAWTEXTFLAGS:
+	    return TOOLBAR_SetDrawTextFlags (wndPtr, wParam, lParam);
 
 	case TB_SETEXTENDEDSTYLE:
 	    return TOOLBAR_SetExtendedStyle (wndPtr, wParam, lParam);
@@ -2640,8 +2681,8 @@
 	case WM_MOUSEMOVE:
 	    return TOOLBAR_MouseMove (wndPtr, wParam, lParam);
 
-//	case WM_NCACTIVATE:
-//	    return TOOLBAR_NCActivate (wndPtr, wParam, lParam);
+	case WM_NCACTIVATE:
+	    return TOOLBAR_NCActivate (wndPtr, wParam, lParam);
 
 	case WM_NCCALCSIZE:
 	    return TOOLBAR_NCCalcSize (wndPtr, wParam, lParam);
diff --git a/dlls/comctl32/tooltips.c b/dlls/comctl32/tooltips.c
index 93ea5f3..419f605 100644
--- a/dlls/comctl32/tooltips.c
+++ b/dlls/comctl32/tooltips.c
@@ -21,7 +21,6 @@
 #include "windows.h"
 #include "commctrl.h"
 #include "tooltips.h"
-#include "heap.h"
 #include "win.h"
 #include "debug.h"
 
@@ -108,8 +107,7 @@
 		if (ttnmdi.uFlags & TTF_DI_SETITEM) {
 		    INT32 len = lstrlen32A (ttnmdi.szText) + 1;
 		    toolPtr->hinst = 0;
-		    toolPtr->lpszText =	
-			HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len);
+		    toolPtr->lpszText =	COMCTL32_Alloc (len);
 		    lstrcpy32A (toolPtr->lpszText, ttnmdi.szText);
 		}
 	    }
@@ -124,8 +122,7 @@
 		if (ttnmdi.uFlags & TTF_DI_SETITEM) {
 		    INT32 len = lstrlen32A (ttnmdi.lpszText) + 1;
 		    toolPtr->hinst = 0;
-		    toolPtr->lpszText =	
-			HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len);
+		    toolPtr->lpszText =	COMCTL32_Alloc (len);
 		    lstrcpy32A (toolPtr->lpszText, ttnmdi.lpszText);
 		}
 	    }
@@ -177,7 +174,7 @@
 TOOLTIPS_Show (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
 {
     TTTOOL_INFO *toolPtr;
-    POINT32 pt;
+    RECT32 rect;
     SIZE32 size;
     NMHDR hdr;
 
@@ -212,31 +209,37 @@
     TRACE (tooltips, "size %d - %d\n", size.cx, size.cy);
 
     if ((toolPtr->uFlags & TTF_TRACK) && (toolPtr->uFlags & TTF_ABSOLUTE)) {
-	pt.x = infoPtr->xTrackPos;
-	pt.y = infoPtr->yTrackPos;
+	rect.left = infoPtr->xTrackPos;
+	rect.top  = infoPtr->yTrackPos;
     }
     else if (toolPtr->uFlags & TTF_CENTERTIP) {
-	RECT32 rect;
+	RECT32 rc;
 
 	if (toolPtr->uFlags & TTF_IDISHWND)
-	    GetWindowRect32 ((HWND32)toolPtr->uId, &rect);
+	    GetWindowRect32 ((HWND32)toolPtr->uId, &rc);
 	else {
-	    rect = toolPtr->rect;
-	    MapWindowPoints32 (toolPtr->hwnd, (HWND32)0, (LPPOINT32)&rect, 2);
+	    rc = toolPtr->rect;
+	    MapWindowPoints32 (toolPtr->hwnd, (HWND32)0, (LPPOINT32)&rc, 2);
 	}
-	pt.x = (rect.left + rect.right - size.cx) / 2;
-	pt.y = rect.bottom + 2;
+	rect.left = (rc.left + rc.right - size.cx) / 2;
+	rect.top  = rc.bottom + 2;
     }
     else {
-	GetCursorPos32 (&pt);
-	pt.y += 20;
+	GetCursorPos32 ((LPPOINT32)&rect);
+	rect.top += 20;
     }
 
-    TRACE (tooltips, "pos %d - %d\n", pt.x, pt.y);
+    TRACE (tooltips, "pos %d - %d\n", rect.left, rect.top);
+
+    rect.right = rect.left + size.cx;
+    rect.bottom = rect.top + size.cy;
+
+    AdjustWindowRectEx32 (&rect, wndPtr->dwStyle, FALSE, wndPtr->dwExStyle);
 
 //    SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 1, 1,
-    SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, pt.x, pt.y,
-		    size.cx, size.cy, SWP_SHOWWINDOW);
+    SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, rect.left, rect.top,
+		    rect.right - rect.left, rect.bottom - rect.top,
+		    SWP_SHOWWINDOW);
 
     SetTimer32 (wndPtr->hwndSelf, ID_TIMER2, infoPtr->nAutoPopTime, 0);
 }
@@ -263,7 +266,8 @@
 
     infoPtr->nCurrentTool = -1;
 
-    SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0, SWP_HIDEWINDOW);
+    SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0,
+		    SWP_NOZORDER | SWP_HIDEWINDOW);
 }
 
 
@@ -406,19 +410,16 @@
 	   (lpToolInfo->uFlags & TTF_IDISHWND) ? " TTF_IDISHWND" : "");
 
     if (infoPtr->uNumTools == 0) {
-	infoPtr->tools =
-	    HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-		       sizeof(TTTOOL_INFO));
+	infoPtr->tools = COMCTL32_Alloc (sizeof(TTTOOL_INFO));
 	toolPtr = infoPtr->tools;
     }
     else {
 	TTTOOL_INFO *oldTools = infoPtr->tools;
 	infoPtr->tools =
-	    HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-		       sizeof(TTTOOL_INFO) * (infoPtr->uNumTools + 1));
+	    COMCTL32_Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools + 1));
 	memcpy (infoPtr->tools, oldTools,
 		infoPtr->uNumTools * sizeof(TTTOOL_INFO));
-	HeapFree (GetProcessHeap (), 0, oldTools);
+	COMCTL32_Free (oldTools);
 	toolPtr = &infoPtr->tools[infoPtr->uNumTools];
     }
 
@@ -443,8 +444,7 @@
 	else {
 	    INT32 len = lstrlen32A (lpToolInfo->lpszText);
 	    TRACE (tooltips, "add text \"%s\"!\n", lpToolInfo->lpszText);
-	    toolPtr->lpszText =
-		HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len + 1);
+	    toolPtr->lpszText =	COMCTL32_Alloc (len + 1);
 	    lstrcpy32A (toolPtr->lpszText, lpToolInfo->lpszText);
 	}
     }
@@ -458,8 +458,8 @@
 	    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 =
+		    (LPTT_SUBCLASS_INFO)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO));
 		lpttsi->wpOrigProc = 
 		    (WNDPROC32)SetWindowLong32A ((HWND32)toolPtr->uId,
 		    GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc);
@@ -475,8 +475,8 @@
 	    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 =
+		    (LPTT_SUBCLASS_INFO)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO));
 		lpttsi->wpOrigProc = 
 		    (WNDPROC32)SetWindowLong32A (toolPtr->hwnd,
 		    GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc);
@@ -521,7 +521,7 @@
     toolPtr = &infoPtr->tools[nTool]; 
     if ((toolPtr->hinst) && (toolPtr->lpszText)) {
 	if (toolPtr->lpszText != LPSTR_TEXTCALLBACK32A)
-	    HeapFree (GetProcessHeap (), 0, toolPtr->lpszText);
+	    COMCTL32_Free (toolPtr->lpszText);
     }
 
     /* remove subclassing */
@@ -533,7 +533,7 @@
 		SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
 				  (LONG)lpttsi->wpOrigProc);
 		RemoveProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP);
-		HeapFree (GetProcessHeap(), 0, &lpttsi);
+		COMCTL32_Free (&lpttsi);
 	    }
 	    else
 		ERR (tooltips, "Invalid data handle!\n");
@@ -546,7 +546,7 @@
 		    SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
 				      (LONG)lpttsi->wpOrigProc);
 		    RemoveProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP);
-		    HeapFree (GetProcessHeap(), 0, &lpttsi);
+		    COMCTL32_Free (&lpttsi);
 		}
 		else
 		    lpttsi->uRefCount--;
@@ -558,14 +558,13 @@
 
     /* delete tool from tool list */
     if (infoPtr->uNumTools == 1) {
-	HeapFree (GetProcessHeap (), 0, infoPtr->tools);
+	COMCTL32_Free (infoPtr->tools);
 	infoPtr->tools = NULL;
     }
     else {
 	TTTOOL_INFO *oldTools = infoPtr->tools;
 	infoPtr->tools =
-	    HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-		       sizeof(TTTOOL_INFO) * (infoPtr->uNumTools - 1));
+	    COMCTL32_Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools - 1));
 
 	if (nTool > 0)
 	    memcpy (&infoPtr->tools[0], &oldTools[0],
@@ -575,7 +574,7 @@
 	    memcpy (&infoPtr->tools[nTool], &oldTools[nTool + 1],
 		    (infoPtr->uNumTools - nTool - 1) * sizeof(TTTOOL_INFO));
 
-	HeapFree (GetProcessHeap (), 0, oldTools);
+	COMCTL32_Free (oldTools);
     }
 
     infoPtr->uNumTools--;
@@ -1051,9 +1050,8 @@
 	    toolPtr->lpszText = lpToolInfo->lpszText;
 	else {
 	    INT32 len = lstrlen32A (lpToolInfo->lpszText);
-	    HeapFree (GetProcessHeap (), 0, toolPtr->lpszText);
-	    toolPtr->lpszText =
-		HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len + 1);
+	    COMCTL32_Free (toolPtr->lpszText);
+	    toolPtr->lpszText =	COMCTL32_Alloc (len + 1);
 	    lstrcpy32A (toolPtr->lpszText, lpToolInfo->lpszText);
 	}
     }
@@ -1160,9 +1158,8 @@
 	    toolPtr->lpszText = lpToolInfo->lpszText;
 	else {
 	    INT32 len = lstrlen32A (lpToolInfo->lpszText);
-	    HeapFree (GetProcessHeap (), 0, toolPtr->lpszText);
-	    toolPtr->lpszText =
-		HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len + 1);
+	    COMCTL32_Free (toolPtr->lpszText);
+	    toolPtr->lpszText =	COMCTL32_Alloc (len + 1);
 	    lstrcpy32A (toolPtr->lpszText, lpToolInfo->lpszText);
 	}
     }
@@ -1189,8 +1186,7 @@
     NONCLIENTMETRICS32A nclm;
 
     /* allocate memory for info structure */
-    infoPtr = (TOOLTIPS_INFO *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-					  sizeof(TOOLTIPS_INFO));
+    infoPtr = (TOOLTIPS_INFO *)COMCTL32_Alloc (sizeof(TOOLTIPS_INFO));
     wndPtr->wExtra[0] = (DWORD)infoPtr;
 
     if (infoPtr == NULL) {
@@ -1219,7 +1215,8 @@
     infoPtr->nAutoPopTime   = 5000;
     infoPtr->nInitialTime   = 500;
 
-    SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0, SWP_HIDEWINDOW);
+    SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0,
+		    SWP_NOZORDER | SWP_HIDEWINDOW);
 
     return 0;
 }
@@ -1230,15 +1227,15 @@
 {
     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
     TTTOOL_INFO *toolPtr;
+    INT32 i;
 
     /* free tools */
     if (infoPtr->tools) {
-	INT32 i;
 	for (i = 0; i < infoPtr->uNumTools; i++) {
 	    toolPtr = &infoPtr->tools[i];
 	    if ((toolPtr->hinst) && (toolPtr->lpszText)) {
 		if (toolPtr->lpszText != LPSTR_TEXTCALLBACK32A)
-		    HeapFree (GetProcessHeap (), 0, toolPtr->lpszText);
+		    COMCTL32_Free (toolPtr->lpszText);
 	    }
 
 	    /* remove subclassing */
@@ -1254,18 +1251,18 @@
 		    SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
 				      (LONG)lpttsi->wpOrigProc);
 		    RemoveProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP);
-		    HeapFree (GetProcessHeap(), 0, &lpttsi);
+		    COMCTL32_Free (&lpttsi);
 		}
 	    }
 	}
-	HeapFree (GetProcessHeap (), 0, infoPtr->tools);
+	COMCTL32_Free (infoPtr->tools);
     }
 
     /* delete font */
     DeleteObject32 (infoPtr->hFont);
 
     /* free tool tips info data */
-    HeapFree (GetProcessHeap (), 0, infoPtr);
+    COMCTL32_Free (infoPtr);
 
     return 0;
 }
@@ -1327,7 +1324,10 @@
 TOOLTIPS_NcCreate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     wndPtr->dwStyle &= 0x0000FFFF;
-    wndPtr->dwStyle |= (WS_POPUP | WS_BORDER);
+    wndPtr->dwStyle |= (WS_POPUP | WS_BORDER | WS_CLIPSIBLINGS);
+
+//    FIXME (tooltips, "style 0x%08x\n", wndPtr->dwStyle);
+//    SetParent32 (wndPtr->hwndSelf, NULL);
 
     return TRUE;
 }
diff --git a/dlls/comctl32/trackbar.c b/dlls/comctl32/trackbar.c
index f80f433..6470916 100644
--- a/dlls/comctl32/trackbar.c
+++ b/dlls/comctl32/trackbar.c
@@ -1,21 +1,31 @@
 /*
  * Trackbar control
  *
- * Copyright 1998 Eric Kohl
+ * Copyright 1998 Eric Kohli <ekohl@abo.rhein-zeitung.de>
+ * Copyright 1998 Alex Priem <alexp@sci.kun.nl>
  *
  * NOTES
- *   Development in progress. Author needed! Any volunteers?
- *   I will only improve this control once in a while.
- *     Eric <ekohl@abo.rhein-zeitung.de>
+
  *
  * TODO:
  *   - Some messages.
- *   - display code.
- *   - user interaction.
- *   - tic handling.
- *   - All notifications.
+ *   - more display code.
+ *   - dragging slider
+ *   - better tic handling.
+ *   - more notifications.
+ *   - tooltips
  */
 
+/* known bugs:
+
+	-TBM_SETRANGEMAX & TBM_SETRANGEMIN should only change the view of the
+   trackbar, not the actual amount of tics in the list.
+	-TBM_GETTIC & TBM_GETTICPOS shouldn't rely on infoPtr->tics being sorted.
+  	-code currently only handles horizontal trackbars correct.
+*/
+
+
+
 #include "windows.h"
 #include "commctrl.h"
 #include "trackbar.h"
@@ -27,88 +37,303 @@
 #define TRACKBAR_GetInfoPtr(wndPtr) ((TRACKBAR_INFO *)wndPtr->wExtra[0])
 
 
-static VOID
-TRACKBAR_Refresh (WND *wndPtr, HDC32 hdc)
+/* Used by TRACKBAR_Refresh to find out which parts of the control 
+	need to be recalculated */
+
+#define TB_THUMBCHANGED 	1
+#define TB_SELECTIONCHANGED 2
+
+
+
+static BOOL32 TRACKBAR_SendNotify (WND *wndPtr, UINT32 code);
+
+void TRACKBAR_RecalculateTics (TRACKBAR_INFO *infoPtr)
+
 {
-    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
-    RECT32 rcClient, rcChannel;
+    int i,tic,nrTics;
 
-    GetClientRect32 (wndPtr->hwndSelf, &rcClient);
+	if (infoPtr->uTicFreq) 
+    	nrTics=(infoPtr->nRangeMax - infoPtr->nRangeMin)/infoPtr->uTicFreq;
+	else {
+		nrTics=0;
+		HeapFree (SystemHeap,0,infoPtr->tics);
+		infoPtr->tics=NULL;
+		infoPtr->uNumTics=0;
+		return;
+	}
 
-    /* draw channel */
-    rcChannel = infoPtr->rcChannel;
-    DrawEdge32 (hdc, &rcChannel, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
-    if (wndPtr->dwStyle & TBS_ENABLESELRANGE) {
-	/* fill the channel */
-	HBRUSH32 hbr = CreateSolidBrush32 (RGB(255,255,255));
-	FillRect32 (hdc, &rcChannel, hbr);
-	DeleteObject32 (hbr);
+    if (nrTics!=infoPtr->uNumTics) {
+    	infoPtr->tics=HeapReAlloc( SystemHeap, 0, infoPtr->tics,
+                           (nrTics+1)*sizeof (DWORD));
+    	infoPtr->uNumTics=nrTics;
     }
-
-    /* draw ticks */
-    if (!(wndPtr->dwStyle & TBS_NOTICKS)) {
-
-    }
-
-    /* draw thumb */
-    if (!(wndPtr->dwStyle & TBS_NOTHUMB)) {
-
-    }
-
-    if (infoPtr->bFocus)
-	DrawFocusRect32 (hdc, &rcClient);
+	infoPtr->uNumTics=nrTics;
+    tic=infoPtr->nRangeMin+infoPtr->uTicFreq;
+    for (i=0; i<nrTics; i++,tic+=infoPtr->uTicFreq)
+               infoPtr->tics[i]=tic;
 }
 
 
+
+static INT32
+TRACKBAR_ConvertPositionToTic (WND *wndPtr, TRACKBAR_INFO *infoPtr, POINT32 pt) 
+{
+	double newpos,newtic;
+    int i,range,width,delta,currentdelta,currenttic;
+
+/* buggy */
+
+    range=infoPtr->nRangeMax - infoPtr->nRangeMin;
+    width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
+	
+	newpos=(pt.x-infoPtr->rcChannel.left) / (double) width;
+
+	newtic=infoPtr->nRangeMin+newpos*range;
+	currenttic=0;
+	currentdelta=currenttic-infoPtr->nRangeMin;
+	for (i=0; i<infoPtr->uNumTics; i++) {
+		delta=newtic-infoPtr->tics[i];
+		if ((delta>0) && (delta<currentdelta)) {
+			currentdelta=delta;
+			currenttic=i;
+		}
+	}
+	return (INT32) currenttic;
+}
+
 static VOID
-TRACKBAR_Calc (WND *wndPtr, TRACKBAR_INFO *infoPtr, LPRECT32 lpRect)
+TRACKBAR_Calc (WND *wndPtr, TRACKBAR_INFO *infoPtr)
 {
     INT32 cyChannel;
+	RECT32 lpRect,*channel = & infoPtr->rcChannel;
+
+    GetClientRect32 (wndPtr->hwndSelf, &lpRect);
 
     if (wndPtr->dwStyle & TBS_ENABLESELRANGE)
-	cyChannel = MAX(infoPtr->uThumbLen - 8, 4);
+		cyChannel = MAX(infoPtr->uThumbLen - 8, 4);
     else
-	cyChannel = 4;
+		cyChannel = 4;
 
     /* calculate channel rect */
     if (wndPtr->dwStyle & TBS_VERT) {
-	infoPtr->rcChannel.top = lpRect->top + 8;
-	infoPtr->rcChannel.bottom = lpRect->bottom - 8;
+		channel->top    = lpRect.top + 8;
+		channel->bottom = lpRect.bottom - 8;
 
-	if (wndPtr->dwStyle & TBS_BOTH) {
-	    infoPtr->rcChannel.left = (lpRect->bottom - cyChannel ) / 2;
-	    infoPtr->rcChannel.right = (lpRect->bottom + cyChannel) / 2;
+			if (wndPtr->dwStyle & TBS_BOTH) {
+	    		channel->left  = (lpRect.bottom - cyChannel) / 2;
+	    		channel->right = (lpRect.bottom + cyChannel) / 2;
+			}
+			else if (wndPtr->dwStyle & TBS_LEFT) {
+	    			channel->left  = lpRect.left + 10;
+	    			channel->right = channel->left + cyChannel;
+				}
+				else { /* TBS_RIGHT */
+	    			channel->right = lpRect.right - 10;
+	    			channel->left  = channel->right - cyChannel;
+				}
+   	}
+   	else {
+			channel->left = lpRect.left + 8;
+			channel->right = lpRect.right - 8;
+			if (wndPtr->dwStyle & TBS_BOTH) {
+	    		channel->top		= (lpRect.bottom - cyChannel) / 2;
+	    		channel->bottom 	= (lpRect.bottom + cyChannel) / 2;
+			}
+			else if (wndPtr->dwStyle & TBS_TOP) {
+	    			channel->top    = lpRect.top + 10;
+	    			channel->bottom = channel->top + cyChannel;
+				}
+				else { /* TBS_BOTTOM */
+	    			channel->bottom = lpRect.bottom - 10;
+	    			channel->top    = channel->bottom - cyChannel;
+				}
 	}
-	else if (wndPtr->dwStyle & TBS_LEFT) {
-	    infoPtr->rcChannel.left = lpRect->left + 10;
-	    infoPtr->rcChannel.right = infoPtr->rcChannel.left + cyChannel;
-	}
-	else {
-	    /* TBS_RIGHT */
-	    infoPtr->rcChannel.right = lpRect->right - 10;
-	    infoPtr->rcChannel.left = infoPtr->rcChannel.right - cyChannel;
-	}
-    }
-    else {
-	infoPtr->rcChannel.left = lpRect->left + 8;
-	infoPtr->rcChannel.right = lpRect->right - 8;
-
-	if (wndPtr->dwStyle & TBS_BOTH) {
-	    infoPtr->rcChannel.top = (lpRect->bottom - cyChannel ) / 2;
-	    infoPtr->rcChannel.bottom = (lpRect->bottom + cyChannel) / 2;
-	}
-	else if (wndPtr->dwStyle & TBS_TOP) {
-	    infoPtr->rcChannel.top = lpRect->top + 10;
-	    infoPtr->rcChannel.bottom = infoPtr->rcChannel.top + cyChannel;
-	}
-	else {
-	    /* TBS_BOTTOM */
-	    infoPtr->rcChannel.bottom = lpRect->bottom - 10;
-	    infoPtr->rcChannel.top = infoPtr->rcChannel.bottom - cyChannel;
-	}
-    }
 }
 
+static VOID
+TRACKBAR_CalcThumb (WND *wndPtr, TRACKBAR_INFO *infoPtr)
+
+{
+	RECT32 *thumb;
+	int range, width;
+	
+	thumb=&infoPtr->rcThumb;
+	range=infoPtr->nRangeMax - infoPtr->nRangeMin;
+    width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
+
+	thumb->left  = infoPtr->rcChannel.left +
+					width*(65536*infoPtr->nPos/range)/65536 - 5;
+	thumb->right  = thumb->left + 10;
+	thumb->top	  = infoPtr->rcChannel.top - 1;
+	thumb->bottom = infoPtr->rcChannel.top + infoPtr->uThumbLen - 8;
+}
+
+static VOID
+TRACKBAR_CalcSelection (WND *wndPtr, TRACKBAR_INFO *infoPtr)
+{
+	RECT32 *selection;
+	int range, width;
+
+	selection= & infoPtr->rcSelection;
+	range=infoPtr->nRangeMax - infoPtr->nRangeMin;
+    width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
+	
+	selection->left   = infoPtr->rcChannel.left +
+						width*(65536*infoPtr->nSelMin/range)/65536;
+	selection->right  = infoPtr->rcChannel.left +
+						width*(65536*infoPtr->nSelMax/range)/65536;
+	selection->top    = infoPtr->rcChannel.top + 2;
+    selection->bottom = infoPtr->rcChannel.bottom - 2;
+}
+
+
+
+static VOID
+TRACKBAR_Refresh (WND *wndPtr, HDC32 hdc)
+{
+	TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
+	RECT32 rcClient, rcChannel, rcSelection;
+	HBRUSH32 hBrush = CreateSolidBrush32 (infoPtr->clrBk);
+	INT32 x,y,tic;
+	int i,range,width;
+
+    GetClientRect32 (wndPtr->hwndSelf, &rcClient);
+	hBrush = CreateSolidBrush32 (infoPtr->clrBk);
+	FillRect32 (hdc, &rcClient, hBrush);
+    DeleteObject32 (hBrush);
+
+	
+	
+	if (infoPtr->flags & TB_THUMBCHANGED) 
+		TRACKBAR_CalcThumb	(wndPtr, infoPtr);
+	if (infoPtr->flags & TB_SELECTIONCHANGED)
+		TRACKBAR_CalcSelection (wndPtr, infoPtr);
+	infoPtr->flags &= ~ (TB_THUMBCHANGED | TB_SELECTIONCHANGED);
+
+    /* draw channel */
+
+    rcChannel = infoPtr->rcChannel;
+    rcSelection= infoPtr->rcSelection;
+    DrawEdge32 (hdc, &rcChannel, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
+
+    if (wndPtr->dwStyle & TBS_ENABLESELRANGE) {		 /* fill the channel */
+		HBRUSH32 hbr = CreateSolidBrush32 (RGB(255,255,255));
+		FillRect32 (hdc, &rcChannel, hbr);
+		if (rcSelection.left!=rcSelection.right) {
+			hbr=CreateSolidBrush32 (COLOR_HIGHLIGHT); 
+			FillRect32 (hdc, &rcSelection, hbr);
+		}
+		DeleteObject32 (hbr);
+    }
+
+
+    /* draw tics */
+
+    if (!(wndPtr->dwStyle & TBS_NOTICKS)) {
+		COLORREF clrTic=GetSysColor32 (COLOR_3DDKSHADOW);
+
+    	x=rcChannel.left;
+    	y=rcChannel.bottom+2;
+		range=infoPtr->nRangeMax - infoPtr->nRangeMin;
+		width=rcChannel.right - rcChannel.left;
+    	if (wndPtr->dwStyle & TBS_VERT) { /* swap x/y */
+        }
+
+    if ((wndPtr->dwStyle & TBS_TOP) || (wndPtr->dwStyle & TBS_BOTH)) {
+        /* draw upper tics */
+     }
+
+//    if (!((wndPtr->dwStyle & TBS_TOP) || (!(wndPtr->dwStyle & TBS_BOTH)))) 
+        /* draw lower tics */
+//    if (wndPtr->dwStyle & TBS_AUTOTICKS) 
+        for (i=0; i<infoPtr->uNumTics; i++) {
+			tic=infoPtr->tics[i];
+			if ((tic>infoPtr->nRangeMin) && (tic<infoPtr->nRangeMax)) {
+            	x=rcChannel.left + width*(65536*tic/range)/65536;
+            	SetPixel32 (hdc, x,y+5, clrTic);
+            	SetPixel32 (hdc, x,y+6, clrTic);
+            	SetPixel32 (hdc, x,y+7, clrTic);
+			}
+          }
+	   if ((wndPtr->dwStyle & TBS_ENABLESELRANGE) && 
+		   (rcSelection.left!=rcSelection.right)) {
+			x=rcChannel.left + width*(65536*infoPtr->nSelMin/range)/65536 - 1;
+           	SetPixel32 (hdc, x,y+6, clrTic);
+           	SetPixel32 (hdc, x,y+7, clrTic);
+			x=rcChannel.left + width*(65536*infoPtr->nSelMax/range)/65536 + 1; 
+           	SetPixel32 (hdc, x,y+6, clrTic);
+           	SetPixel32 (hdc, x,y+7, clrTic);
+		}
+		
+	   x=rcChannel.left;
+       SetPixel32 (hdc, x,y+5, clrTic);
+       SetPixel32 (hdc, x,y+6, clrTic);
+       SetPixel32 (hdc, x,y+7, clrTic);
+       SetPixel32 (hdc, x,y+8, clrTic);
+	   x=rcChannel.right;
+       SetPixel32 (hdc, x,y+5, clrTic);
+       SetPixel32 (hdc, x,y+6, clrTic);
+       SetPixel32 (hdc, x,y+7, clrTic);
+       SetPixel32 (hdc, x,y+8, clrTic);
+//     }
+    }
+
+ 
+     /* draw thumb */
+
+     if (!(wndPtr->dwStyle & TBS_NOTHUMB)) {
+        HBRUSH32 hbr = CreateSolidBrush32 (COLOR_BACKGROUND);
+		RECT32 thumb = infoPtr->rcThumb;
+
+		SelectObject32 (hdc, hbr);
+		
+		if (wndPtr->dwStyle & TBS_BOTH) {
+        	FillRect32 (hdc, &thumb, hbr);
+  			DrawEdge32 (hdc, &thumb, EDGE_RAISED, BF_TOPLEFT);
+		} else {
+
+		POINT32 points[6];
+		RECT32 triangle;	/* for correct shadows of thumb */
+
+ 			/* first, fill the thumb */
+		
+		SetPolyFillMode32 (hdc,WINDING);
+		points[0].x=thumb.left;
+		points[0].y=thumb.top;
+		points[1].x=thumb.right - 1;
+		points[1].y=thumb.top;
+		points[2].x=thumb.right - 1;
+		points[2].y=thumb.bottom -2;
+		points[3].x=(thumb.right + thumb.left-1)/2;
+		points[3].y=thumb.bottom+4;
+		points[4].x=thumb.left;
+		points[4].y=thumb.bottom -2;
+		points[5].x=points[0].x;
+		points[5].y=points[0].y;
+		Polygon32 (hdc, points, 6);
+		DrawEdge32 (hdc, &thumb, EDGE_RAISED, BF_TOPLEFT);
+//		DrawEdge32 (hdc, &thumb, EDGE_SUNKEN, BF_BOTTOMRIGHT);
+
+			/* draw notch */
+
+		triangle.right = thumb.right+5;
+		triangle.left  = points[3].x+5;
+		triangle.top   = thumb.bottom +5;
+		triangle.bottom= thumb.bottom +1;
+		DrawEdge32 (hdc, &triangle, EDGE_SUNKEN, BF_DIAGONAL | BF_TOP | BF_RIGHT);
+		triangle.left  = thumb.left+6;
+		triangle.right = points[3].x+6;
+		DrawEdge32 (hdc, &triangle, EDGE_RAISED, BF_DIAGONAL | BF_TOP | BF_LEFT);
+		}
+		DeleteObject32 (hbr);
+     }
+
+    if (infoPtr->bFocus)
+		DrawFocusRect32 (hdc, &rcClient);
+}
+
+
+
 
 static VOID
 TRACKBAR_AlignBuddies (WND *wndPtr, TRACKBAR_INFO *infoPtr)
@@ -169,11 +394,12 @@
 
     infoPtr->nSelMin = 0;
     infoPtr->nSelMax = 0;
+	infoPtr->flags |=TB_SELECTIONCHANGED;
 
     if ((BOOL32)wParam) {
-	HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
-	TRACKBAR_Refresh (wndPtr, hdc);
-	ReleaseDC32 (wndPtr->hwndSelf, hdc);
+		HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
+		TRACKBAR_Refresh (wndPtr, hdc);
+		ReleaseDC32 (wndPtr->hwndSelf, hdc);
     }
 
     return 0;
@@ -186,16 +412,15 @@
     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
 
     if (infoPtr->tics) {
-	FIXME (trackbar, "is this correct??\n");
-	HeapFree (GetProcessHeap (), 0, infoPtr->tics);
-	infoPtr->tics = NULL;
-	infoPtr->uNumTics = 2;
+		HeapFree (GetProcessHeap (), 0, infoPtr->tics);
+		infoPtr->tics = NULL;
+		infoPtr->uNumTics = 0;
     }
 
     if (wParam) {
-	HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
-	TRACKBAR_Refresh (wndPtr, hdc);
-	ReleaseDC32 (wndPtr->hwndSelf, hdc);
+		HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
+		TRACKBAR_Refresh (wndPtr, hdc);
+		ReleaseDC32 (wndPtr->hwndSelf, hdc);
     }
 
     return 0;
@@ -207,9 +432,8 @@
 {
     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
 
-    if (wParam)
-	/* buddy is left or above */
-	return (LRESULT)infoPtr->hwndBuddyLA;
+    if (wParam)		 /* buddy is left or above */
+		return (LRESULT)infoPtr->hwndBuddyLA;
 
     /* buddy is right or below */
     return (LRESULT) infoPtr->hwndBuddyRB;
@@ -223,7 +447,7 @@
     LPRECT32 lprc = (LPRECT32)lParam;
 
     if (lprc == NULL)
-	return 0;
+		return 0;
 
     lprc->left   = infoPtr->rcChannel.left;
     lprc->right  = infoPtr->rcChannel.right;
@@ -249,9 +473,9 @@
     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
 
     if (wndPtr->dwStyle & TBS_NOTICKS)
-	return 0;
+		return 0;
 
-    return infoPtr->uNumTics;
+    return infoPtr->uNumTics+2;
 }
 
 
@@ -273,7 +497,6 @@
 }
 
 
-// << TRACKBAR_GetPTics >>
 
 
 static LRESULT
@@ -320,20 +543,78 @@
     return infoPtr->uThumbLen;
 }
 
+static LRESULT
+TRACKBAR_GetPTics (WND *wndPtr)
+{
+    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
+    
+   return (LRESULT) infoPtr->tics;
+}
+
+static LRESULT
+TRACKBAR_GetThumbRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
+    LPRECT32 lprc = (LPRECT32)lParam;
+    
+    if (lprc == NULL)
+   		return 0; 
+   
+    lprc->left   = infoPtr->rcThumb.left;
+    lprc->right  = infoPtr->rcThumb.right;
+    lprc->bottom = infoPtr->rcThumb.bottom;
+    lprc->top    = infoPtr->rcThumb.top;
+   
+    return 0;
+}  
 
 
-// << TRACKBAR_GetThumbRect >>
-//	case TBM_GETTIC:
-//	case TBM_GETTICPOS:
 
 
+
+static LRESULT
+TRACKBAR_GetTic (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+
+{
+ TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
+ INT32 iTic;
+
+ iTic=(INT32) wParam;
+ if ((iTic<0) || (iTic>infoPtr->uNumTics)) 
+	return -1;
+
+ return (LRESULT) infoPtr->tics[iTic];
+
+}
+
+
+static LRESULT
+TRACKBAR_GetTicPos (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+
+{
+ TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
+ INT32 iTic, range, width, pos;
+ 
+
+ iTic=(INT32 ) wParam;
+ if ((iTic<0) || (iTic>infoPtr->uNumTics)) 
+	return -1;
+
+ range=infoPtr->nRangeMax - infoPtr->nRangeMin;
+ width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
+ pos=infoPtr->rcChannel.left + width*(65536*infoPtr->tics[iTic]/range)/65536;
+
+
+ return (LRESULT) pos;
+}
+
 static LRESULT
 TRACKBAR_GetToolTips (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
 
     if (wndPtr->dwStyle & TBS_TOOLTIPS)
-	return (LRESULT)infoPtr->hwndToolTip;
+		return (LRESULT)infoPtr->hwndToolTip;
     return 0;
 }
 
@@ -355,11 +636,11 @@
 	FIXME (trackbar, "move buddy!\n");
     }
     else {
-	/* buddy is right or below */
-	hwndTemp = infoPtr->hwndBuddyRB;
-	infoPtr->hwndBuddyRB = (HWND32)lParam;
+		/* buddy is right or below */
+		hwndTemp = infoPtr->hwndBuddyRB;
+		infoPtr->hwndBuddyRB = (HWND32)lParam;
 
-	FIXME (trackbar, "move buddy!\n");
+		FIXME (trackbar, "move buddy!\n");
     }
 
     TRACKBAR_AlignBuddies (wndPtr, infoPtr);
@@ -404,11 +685,12 @@
 
     if (infoPtr->nPos > infoPtr->nRangeMax)
 	infoPtr->nPos = infoPtr->nRangeMax;
+	infoPtr->flags |=TB_THUMBCHANGED;
 
     if (wParam) {
-	HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
-	TRACKBAR_Refresh (wndPtr, hdc);
-	ReleaseDC32 (wndPtr->hwndSelf, hdc);
+		HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
+		TRACKBAR_Refresh (wndPtr, hdc);
+		ReleaseDC32 (wndPtr->hwndSelf, hdc);
     }
 
     return 0;
@@ -419,20 +701,26 @@
 TRACKBAR_SetRange (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
-
     infoPtr->nRangeMin = (INT32)LOWORD(lParam);
     infoPtr->nRangeMax = (INT32)HIWORD(lParam);
 
-    if (infoPtr->nPos < infoPtr->nRangeMin)
-	infoPtr->nPos = infoPtr->nRangeMin;
+    if (infoPtr->nPos < infoPtr->nRangeMin) {
+		infoPtr->nPos = infoPtr->nRangeMin;
+		infoPtr->flags |=TB_THUMBCHANGED;
+	}
 
-    if (infoPtr->nPos > infoPtr->nRangeMax)
-	infoPtr->nPos = infoPtr->nRangeMax;
+    if (infoPtr->nPos > infoPtr->nRangeMax) {
+		infoPtr->nPos = infoPtr->nRangeMax;
+		infoPtr->flags |=TB_THUMBCHANGED;
+	}
+
+	infoPtr->nPageSize=(infoPtr->nRangeMax -  infoPtr->nRangeMin)/5;
+	TRACKBAR_RecalculateTics (infoPtr);
 
     if (wParam) {
-	HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
-	TRACKBAR_Refresh (wndPtr, hdc);
-	ReleaseDC32 (wndPtr->hwndSelf, hdc);
+		HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
+		TRACKBAR_Refresh (wndPtr, hdc);
+		ReleaseDC32 (wndPtr->hwndSelf, hdc);
     }
 
     return 0;
@@ -445,13 +733,18 @@
     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
 
     infoPtr->nRangeMax = (INT32)lParam;
-    if (infoPtr->nPos > infoPtr->nRangeMax)
-	infoPtr->nPos = infoPtr->nRangeMax;
+    if (infoPtr->nPos > infoPtr->nRangeMax) {
+		infoPtr->nPos = infoPtr->nRangeMax;
+		infoPtr->flags |=TB_THUMBCHANGED;
+	}
+
+	infoPtr->nPageSize=(infoPtr->nRangeMax -  infoPtr->nRangeMin)/5;
+	TRACKBAR_RecalculateTics (infoPtr);
 
     if (wParam) {
-	HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
-	TRACKBAR_Refresh (wndPtr, hdc);
-	ReleaseDC32 (wndPtr->hwndSelf, hdc);
+		HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
+		TRACKBAR_Refresh (wndPtr, hdc);
+		ReleaseDC32 (wndPtr->hwndSelf, hdc);
     }
 
     return 0;
@@ -464,39 +757,62 @@
     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
 
     infoPtr->nRangeMin = (INT32)lParam;
-    if (infoPtr->nPos < infoPtr->nRangeMin)
-	infoPtr->nPos = infoPtr->nRangeMin;
+    if (infoPtr->nPos < infoPtr->nRangeMin) {
+		infoPtr->nPos = infoPtr->nRangeMin;
+		infoPtr->flags |=TB_THUMBCHANGED;
+	}
+
+	infoPtr->nPageSize=(infoPtr->nRangeMax -  infoPtr->nRangeMin)/5;
+	TRACKBAR_RecalculateTics (infoPtr);
 
     if (wParam) {
-	HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
-	TRACKBAR_Refresh (wndPtr, hdc);
-	ReleaseDC32 (wndPtr->hwndSelf, hdc);
+		HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
+		TRACKBAR_Refresh (wndPtr, hdc);
+		ReleaseDC32 (wndPtr->hwndSelf, hdc);
     }
 
     return 0;
 }
 
+static LRESULT
+TRACKBAR_SetTicFreq (WND *wndPtr, WPARAM32 wParam)
+{
+    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
+	HDC32 hdc;
+	
+    if (wndPtr->dwStyle & TBS_AUTOTICKS) 
+           	infoPtr->uTicFreq=(UINT32) wParam; 
+	
+	TRACKBAR_RecalculateTics (infoPtr);
+
+	hdc = GetDC32 (wndPtr->hwndSelf);
+    TRACKBAR_Refresh (wndPtr, hdc);
+    ReleaseDC32 (wndPtr->hwndSelf, hdc);
+	return 0;
+}   
+
 
 static LRESULT
 TRACKBAR_SetSel (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
 
-    if (!wndPtr->dwStyle & TBS_ENABLESELRANGE)
-	return 0;
-
     infoPtr->nSelMin = (INT32)LOWORD(lParam);
     infoPtr->nSelMax = (INT32)HIWORD(lParam);
+	infoPtr->flags |=TB_SELECTIONCHANGED;
+
+    if (!wndPtr->dwStyle & TBS_ENABLESELRANGE)
+		return 0;
 
     if (infoPtr->nSelMin < infoPtr->nRangeMin)
-	infoPtr->nSelMin = infoPtr->nRangeMin;
+		infoPtr->nSelMin = infoPtr->nRangeMin;
     if (infoPtr->nSelMax > infoPtr->nRangeMax)
-	infoPtr->nSelMax = infoPtr->nRangeMax;
+		infoPtr->nSelMax = infoPtr->nRangeMax;
 
     if (wParam) {
-	HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
-	TRACKBAR_Refresh (wndPtr, hdc);
-	ReleaseDC32 (wndPtr->hwndSelf, hdc);
+		HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
+		TRACKBAR_Refresh (wndPtr, hdc);
+		ReleaseDC32 (wndPtr->hwndSelf, hdc);
     }
 
     return 0;
@@ -512,13 +828,15 @@
 	return 0;
 
     infoPtr->nSelMax = (INT32)lParam;
+	infoPtr->flags  |=TB_SELECTIONCHANGED;
+	
     if (infoPtr->nSelMax > infoPtr->nRangeMax)
-	infoPtr->nSelMax = infoPtr->nRangeMax;
+		infoPtr->nSelMax = infoPtr->nRangeMax;
 
     if (wParam) {
-	HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
-	TRACKBAR_Refresh (wndPtr, hdc);
-	ReleaseDC32 (wndPtr->hwndSelf, hdc);
+		HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
+		TRACKBAR_Refresh (wndPtr, hdc);
+		ReleaseDC32 (wndPtr->hwndSelf, hdc);
     }
 
     return 0;
@@ -534,13 +852,14 @@
 	return 0;
 
     infoPtr->nSelMin = (INT32)lParam;
+	infoPtr->flags  |=TB_SELECTIONCHANGED;
     if (infoPtr->nSelMin < infoPtr->nRangeMin)
-	infoPtr->nSelMin = infoPtr->nRangeMin;
+		infoPtr->nSelMin = infoPtr->nRangeMin;
 
     if (wParam) {
-	HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
-	TRACKBAR_Refresh (wndPtr, hdc);
-	ReleaseDC32 (wndPtr->hwndSelf, hdc);
+		HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
+		TRACKBAR_Refresh (wndPtr, hdc);
+		ReleaseDC32 (wndPtr->hwndSelf, hdc);
     }
 
     return 0;
@@ -551,10 +870,16 @@
 TRACKBAR_SetThumbLength (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
+	HDC32 hdc;
 
     if (wndPtr->dwStyle & TBS_FIXEDLENGTH)
-	infoPtr->uThumbLen = (UINT32)wParam;
+		infoPtr->uThumbLen = (UINT32)wParam;
 
+	hdc = GetDC32 (wndPtr->hwndSelf);
+	infoPtr->flags |=TB_THUMBCHANGED;
+	TRACKBAR_Refresh (wndPtr, hdc);
+	ReleaseDC32 (wndPtr->hwndSelf, hdc);
+	
     return 0;
 }
 
@@ -564,19 +889,24 @@
 {
     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
     INT32 nPos = (INT32)lParam;
+	HDC32 hdc;
 
-    if (nPos < infoPtr->nRangeMin)
-	return FALSE;
-    if (nPos > infoPtr->nRangeMax)
-	return FALSE;
+    if ((nPos < infoPtr->nRangeMin) || (nPos> infoPtr->nRangeMax))
+		return FALSE;
 
-    FIXME (trackbar, "%d - empty stub!\n", nPos);
+	infoPtr->uNumTics++;
+    infoPtr->tics=HeapReAlloc( SystemHeap, 0, infoPtr->tics,
+                           (infoPtr->uNumTics)*sizeof (DWORD));
+    infoPtr->tics[infoPtr->uNumTics-1]=nPos;
+
+ 	hdc = GetDC32 (wndPtr->hwndSelf);
+    TRACKBAR_Refresh (wndPtr, hdc);
+    ReleaseDC32 (wndPtr->hwndSelf, hdc);
 
     return TRUE;
 }
 
 
-//	case TBM_SETTICFREQ:
 
 
 static LRESULT
@@ -586,7 +916,7 @@
     INT32 fTemp = infoPtr->fLocation;
 
     infoPtr->fLocation = (INT32)wParam;
-
+	
     return fTemp;
 }
 
@@ -605,6 +935,19 @@
 //	case TBM_SETUNICODEFORMAT:
 
 
+static LRESULT
+TRACKBAR_InitializeThumb (WND *wndPtr)
+{
+    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
+
+    infoPtr->uThumbLen = 23;   /* initial thumb length */
+
+	TRACKBAR_Calc (wndPtr,infoPtr);
+	TRACKBAR_CalcThumb (wndPtr, infoPtr);
+	infoPtr->flags &= ~TB_SELECTIONCHANGED;
+
+	return 0;
+}
 
 
 static LRESULT
@@ -617,18 +960,21 @@
     wndPtr->wExtra[0] = (DWORD)infoPtr;
 
 
-    /* default values */
-    infoPtr->nRangeMin = 0;
+    infoPtr->nRangeMin = 0;			 /* default values */
     infoPtr->nRangeMax = 100;
     infoPtr->nLineSize = 1;
     infoPtr->nPageSize = 20;
     infoPtr->nSelMin   = 0;
     infoPtr->nSelMax   = 0;
     infoPtr->nPos      = 0;
-    infoPtr->uThumbLen = 23;   /* initial thumb length */
-    infoPtr->uNumTics  = 2;    /* default start and end tic */
 
+    infoPtr->uNumTics  = 0;    /* start and end tic are not included in count*/
+	infoPtr->uTicFreq  = 1;
+	infoPtr->tics	   = NULL;
+	infoPtr->clrBk	   = GetSysColor32 (COLOR_BACKGROUND);
 
+	TRACKBAR_InitializeThumb (wndPtr);
+	
     return 0;
 }
 
@@ -667,12 +1013,64 @@
 TRACKBAR_LButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
-
+	int prevPlace,range,width,clickPlace,prevPos;
+	
     SetFocus32 (wndPtr->hwndSelf);
 
+	clickPlace=(INT32)LOWORD(lParam);
+    range=infoPtr->nRangeMax - infoPtr->nRangeMin;
+    width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
+    prevPlace = infoPtr->rcChannel.left +
+                    width*(65536*infoPtr->nPos/range)/65536;
+	printf ("%d->%d\n",prevPlace,clickPlace);
+
+	prevPos	= infoPtr->nPos;
+	if (clickPlace > prevPlace) {					/* similar to VK_NEXT */
+		infoPtr->nPos += infoPtr->nPageSize;
+        if (infoPtr->nPos > infoPtr->nRangeMax)
+			infoPtr->nPos = infoPtr->nRangeMax;
+		TRACKBAR_SendNotify (wndPtr, TB_PAGEUP);  
+	} else {
+        infoPtr->nPos -= infoPtr->nPageSize;	/* similar to VK_PRIOR */
+        if (infoPtr->nPos < infoPtr->nRangeMin)
+            infoPtr->nPos = infoPtr->nRangeMin;
+        TRACKBAR_SendNotify (wndPtr, TB_PAGEDOWN);
+	}
+
+	printf ("%d->%d\n",prevPos,infoPtr->nPos);
+	if (prevPos!=infoPtr->nPos) {
+    	HDC32 hdc;
+
+    	hdc=GetDC32 (wndPtr->hwndSelf);
+		infoPtr->flags |=TB_THUMBCHANGED;
+    	TRACKBAR_Refresh (wndPtr, hdc);
+    	ReleaseDC32 (wndPtr->hwndSelf, hdc);
+ 	}
+
+
     return 0;
 }
 
+static LRESULT
+TRACKBAR_LButtonUp (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
+
+    FIXME (trackbar,"stub\n");
+
+	TRACKBAR_SendNotify (wndPtr, TB_ENDTRACK);
+
+    return 0;
+}
+
+static LRESULT
+TRACKBAR_CaptureChanged (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    FIXME (trackbar,"stub\n");
+
+	TRACKBAR_SendNotify (wndPtr, TB_ENDTRACK);
+	return 0;
+}
 
 static LRESULT
 TRACKBAR_Paint (WND *wndPtr, WPARAM32 wParam)
@@ -708,11 +1106,8 @@
 TRACKBAR_Size (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
-    RECT32 rcClient;
 
-    GetClientRect32 (wndPtr->hwndSelf, &rcClient);
-
-    TRACKBAR_Calc (wndPtr, infoPtr, &rcClient);
+    TRACKBAR_Calc (wndPtr, infoPtr);
     TRACKBAR_AlignBuddies (wndPtr, infoPtr);
 
     return 0;
@@ -720,9 +1115,111 @@
 
 
 // << TRACKBAR_Timer >>
-// << TRACKBAR_WinIniChange >>
 
 
+static BOOL32
+TRACKBAR_SendNotify (WND *wndPtr, UINT32 code)
+
+{
+    TRACE (trackbar, "%x\n",code);
+	if (wndPtr->dwStyle & TBS_VERT) 
+    	return (BOOL32) SendMessage32A (GetParent32 (wndPtr->hwndSelf), 
+						WM_VSCROLL, (WPARAM32)code, (LPARAM) wndPtr->hwndSelf);
+
+   	return (BOOL32) SendMessage32A (GetParent32 (wndPtr->hwndSelf), 
+						WM_HSCROLL, (WPARAM32)code, (LPARAM) wndPtr->hwndSelf);
+}
+
+static LRESULT
+TRACKBAR_MouseMove (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
+			
+	
+ 	return TRUE;
+}
+
+
+static LRESULT
+TRACKBAR_KeyDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
+	INT32 pos;
+
+    TRACE (trackbar, "%x\n",wParam);
+
+	pos=infoPtr->nPos;
+	switch (wParam) {
+		case VK_LEFT:
+		case VK_UP: 
+			if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
+			infoPtr->nPos -= infoPtr->nLineSize;
+			if (infoPtr->nPos < infoPtr->nRangeMin) 
+				infoPtr->nPos = infoPtr->nRangeMin;
+			TRACKBAR_SendNotify (wndPtr, TB_LINEUP);
+			break;
+		case VK_RIGHT:
+		case VK_DOWN: 
+			if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
+			infoPtr->nPos += infoPtr->nLineSize;
+			if (infoPtr->nPos > infoPtr->nRangeMax) 
+				infoPtr->nPos = infoPtr->nRangeMax;
+			TRACKBAR_SendNotify (wndPtr, TB_LINEDOWN);
+            break;
+		case VK_NEXT:
+			if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
+			infoPtr->nPos += infoPtr->nPageSize;
+			if (infoPtr->nPos > infoPtr->nRangeMax) 
+				infoPtr->nPos = infoPtr->nRangeMax;
+			 TRACKBAR_SendNotify (wndPtr, TB_PAGEUP);
+            break;
+		case VK_PRIOR:
+			if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
+			infoPtr->nPos -= infoPtr->nPageSize;
+			if (infoPtr->nPos < infoPtr->nRangeMin) 
+				infoPtr->nPos = infoPtr->nRangeMin;
+			TRACKBAR_SendNotify (wndPtr, TB_PAGEDOWN);
+            break;
+		case VK_HOME: 
+			if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
+			infoPtr->nPos = infoPtr->nRangeMin;
+			TRACKBAR_SendNotify (wndPtr, TB_TOP);
+            break;
+		case VK_END: 
+			if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
+			infoPtr->nPos = infoPtr->nRangeMax;
+	 		TRACKBAR_SendNotify (wndPtr, TB_BOTTOM);
+            break;
+	}
+
+ if (pos!=infoPtr->nPos) { 
+	HDC32 hdc;
+
+	hdc=GetDC32 (wndPtr->hwndSelf);
+	infoPtr->flags |=TB_THUMBCHANGED;
+	TRACKBAR_Refresh (wndPtr, hdc);
+	ReleaseDC32 (wndPtr->hwndSelf, hdc);
+ }
+
+ return TRUE;
+}
+
+static LRESULT
+TRACKBAR_KeyUp (WND *wndPtr, WPARAM32 wParam)
+{
+	switch (wParam) {
+		case VK_LEFT:
+		case VK_UP: 
+		case VK_RIGHT:
+		case VK_DOWN: 
+		case VK_NEXT:
+		case VK_PRIOR:
+		case VK_HOME: 
+		case VK_END: 	TRACKBAR_SendNotify (wndPtr, TB_ENDTRACK);
+	}
+ return TRUE;
+}
+
 LRESULT WINAPI
 TRACKBAR_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
 {
@@ -754,7 +1251,8 @@
 	case TBM_GETPOS:
 	    return TRACKBAR_GetPos (wndPtr, wParam, lParam);
 
-//	case TBM_GETPTICS:
+	case TBM_GETPTICS:
+		 return TRACKBAR_GetPTics (wndPtr);
 
 	case TBM_GETRANGEMAX:
 	    return TRACKBAR_GetRangeMax (wndPtr, wParam, lParam);
@@ -771,10 +1269,15 @@
 	case TBM_GETTHUMBLENGTH:
 	    return TRACKBAR_GetThumbLength (wndPtr, wParam, lParam);
 
-//	case TBM_GETTHUMBRECT:
-//	case TBM_GETTIC:
-//	case TBM_GETTICPOS:
+	case TBM_GETTHUMBRECT:
+        return TRACKBAR_GetThumbRect (wndPtr, wParam, lParam);
 
+    case TBM_GETTIC:
+        return TRACKBAR_GetTic (wndPtr, wParam, lParam);
+ 
+    case TBM_GETTICPOS:
+        return TRACKBAR_GetTicPos (wndPtr, wParam, lParam);
+ 
 	case TBM_GETTOOLTIPS:
 	    return TRACKBAR_GetToolTips (wndPtr, wParam, lParam);
 
@@ -816,7 +1319,9 @@
 	case TBM_SETTIC:
 	    return TRACKBAR_SetTic (wndPtr, wParam, lParam);
 
-//	case TBM_SETTICFREQ:
+    case TBM_SETTICFREQ:
+       return TRACKBAR_SetTicFreq (wndPtr, wParam);
+
 
 	case TBM_SETTIPSIDE:
 	    return TRACKBAR_SetTipSide (wndPtr, wParam, lParam);
@@ -827,7 +1332,8 @@
 //	case TBM_SETUNICODEFORMAT:
 
 
-//	case WM_CAPTURECHANGED:
+	case WM_CAPTURECHANGED:
+	    return TRACKBAR_CaptureChanged (wndPtr, wParam, lParam);
 
 	case WM_CREATE:
 	    return TRACKBAR_Create (wndPtr, wParam, lParam);
@@ -843,9 +1349,11 @@
 	case WM_GETDLGCODE:
 	    return DLGC_WANTARROWS;
 
-//	case WM_KEYDOWN:
-
-//	case WM_KEYUP:
+ 	case WM_KEYDOWN:
+       return TRACKBAR_KeyDown (wndPtr, wParam, lParam);
+        
+  	case WM_KEYUP:
+       return TRACKBAR_KeyUp (wndPtr, wParam);
 
 	case WM_KILLFOCUS:
 	    return TRACKBAR_KillFocus (wndPtr, wParam, lParam);
@@ -853,10 +1361,11 @@
 	case WM_LBUTTONDOWN:
 	    return TRACKBAR_LButtonDown (wndPtr, wParam, lParam);
 
-//	case WM_LBUTTONUP:
+	case WM_LBUTTONUP:
+	    return TRACKBAR_LButtonUp (wndPtr, wParam, lParam);
 
-//	case WM_MOUSEMOVE:
-//	    return TRACKBAR_MouseMove (wndPtr, wParam, lParam);
+	case WM_MOUSEMOVE:
+	    return TRACKBAR_MouseMove (wndPtr, wParam, lParam);
 
 	case WM_PAINT:
 	    return TRACKBAR_Paint (wndPtr, wParam);
@@ -869,7 +1378,8 @@
 
 //	case WM_TIMER:
 
-//	case WM_WININICHANGE:
+	case WM_WININICHANGE:
+		return TRACKBAR_InitializeThumb (wndPtr);
 
 	default:
 	    if (uMsg >= WM_USER)
diff --git a/dlls/comctl32/treeview.c b/dlls/comctl32/treeview.c
index a4eac47..9b5fcf5 100644
--- a/dlls/comctl32/treeview.c
+++ b/dlls/comctl32/treeview.c
@@ -1,16 +1,28 @@
-/*
- * Treeview control
+/* Treeview control
  *
- * Copyright 1998 Eric Kohl
+ * Copyright 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de>
+ * Copyright 1998 Alex Priem <alexp@sci.kun.nl>
  *
- * NOTES
- *   This is just a dummy control. An author is needed! Any volunteers?
- *   I will only improve this control once in a while.
- *     Eric <ekohl@abo.rhein-zeitung.de>
  *
  * TODO:
- *   - All messages.
- *   - All notifications.
+ *   - Nearly all notifications.
+ * 
+ *   list-handling stuff: sort, sorted insertitem.
+ *
+ *   refreshtreeview: 	
+		-small array containing info about positions.
+ 		-better implementation of DrawItem (connecting lines).
+		-implement partial drawing?
+ *   Expand:		-ctlmacro expands twice ->toggle.
+ *  -drag&drop.
+ *  -scrollbars.
+ *  -Unicode messages
+ *  -TVITEMEX 
+ *
+ * FIXMEs:  
+   -GetNextItem: add flag for traversing visible items 
+   -DblClick:	ctlmacro.exe's NM_DBLCLK seems to go wrong (returns FALSE).
+	     
  */
 
 #include "windows.h"
@@ -19,26 +31,225 @@
 #include "heap.h"
 #include "win.h"
 #include "debug.h"
+#include <asm/bitops.h>      /* FIXME: linux specific */
+
+static int TREEVIEW_Timer;
+
 
 
 #define TREEVIEW_GetInfoPtr(wndPtr) ((TREEVIEW_INFO *)wndPtr->wExtra[0])
 
 
 
+#include <asm/bitops.h>      /* FIXME: linux specific */
+
+static int TREEVIEW_Timer;
+
+  
+  #define TREEVIEW_GetInfoPtr(wndPtr) ((TREEVIEW_INFO *)wndPtr->wExtra[0])
+  
+  
+  
+
+static BOOL32
+TREEVIEW_SendSimpleNotify (WND *wndPtr, UINT32 code);
+static BOOL32
+TREEVIEW_SendTreeviewNotify (WND *wndPtr, UINT32 code, UINT32 action, 
+			INT32 oldItem, INT32 newItem, POINT32 pt);
+static LRESULT
+TREEVIEW_SelectItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
+static void
+TREEVIEW_Refresh (WND *wndPtr, HDC32 hdc);
+
+
+
+
+
+/* helper functions. Work with the assumption that validity of operands 
+   is checked beforehand */
+
+
+static TREEVIEW_ITEM *
+TREEVIEW_ValidItem (TREEVIEW_INFO *infoPtr,int  handle)
+{
+ 
+ if ((!handle) || (handle>infoPtr->uMaxHandle)) return NULL;
+ if (test_bit (handle, infoPtr->freeList)) return NULL;
+
+ return & infoPtr->items[handle];
+}
+
+
+
+static TREEVIEW_ITEM *TREEVIEW_GetPrevListItem (TREEVIEW_INFO *infoPtr, 
+					TREEVIEW_ITEM *tvItem)
+
+{
+ TREEVIEW_ITEM *wineItem;
+
+ if (tvItem->upsibling) 
+		return (& infoPtr->items[tvItem->upsibling]);
+
+ wineItem=tvItem;
+ while (wineItem->parent) {
+	wineItem=& infoPtr->items[wineItem->parent];
+	if (wineItem->upsibling) 
+                return (& infoPtr->items[wineItem->upsibling]);
+ } 
+
+ return NULL;
+}
+
+static TREEVIEW_ITEM *TREEVIEW_GetNextListItem (TREEVIEW_INFO *infoPtr, 
+					TREEVIEW_ITEM *tvItem)
+
+{
+ TREEVIEW_ITEM *wineItem;
+
+ if (tvItem->sibling) 
+		return (& infoPtr->items[tvItem->sibling]);
+
+ wineItem=tvItem;
+ while (wineItem->parent) {
+	wineItem=& infoPtr->items [wineItem->parent];
+	if (wineItem->sibling) 
+                return (& infoPtr->items [wineItem->sibling]);
+ } 
+
+ return NULL;
+}
+
+static TREEVIEW_ITEM *TREEVIEW_GetLastListItem (TREEVIEW_INFO *infoPtr)
+
+{
+  TREEVIEW_ITEM *wineItem;
+  
+ wineItem=NULL;
+ if (infoPtr->TopRootItem) 
+	wineItem=& infoPtr->items [infoPtr->TopRootItem];
+ while (wineItem->sibling) 
+	wineItem=& infoPtr->items [wineItem->sibling];
+
+ return wineItem;
+}
+	
+ 
+
+
+static void
+TREEVIEW_RemoveItem (TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem)
+
+{
+ TREEVIEW_ITEM *parentItem, *upsiblingItem, *siblingItem;
+ INT32 iItem;
+
+ iItem=wineItem->hItem;
+ set_bit ( iItem & 31, &infoPtr->freeList[iItem >>5]);
+ infoPtr->uNumItems--;
+ parentItem=NULL;
+ if (wineItem->pszText!=LPSTR_TEXTCALLBACK32A) 
+	HeapFree (GetProcessHeap (), 0, wineItem->pszText);
+
+ if (wineItem->parent) {
+	parentItem=& infoPtr->items[ wineItem->parent];
+	if (parentItem->cChildren==1) {
+		parentItem->cChildren=0;
+		parentItem->firstChild=0;    
+		return;
+	} else {
+		parentItem->cChildren--;
+		if (parentItem->firstChild==iItem) 
+			parentItem->firstChild=wineItem->sibling;
+		}
+ }
+
+ if (iItem==infoPtr->TopRootItem) 
+	infoPtr->TopRootItem=wineItem->sibling;
+ if (wineItem->upsibling) {
+	upsiblingItem=& infoPtr->items [wineItem->upsibling];
+	upsiblingItem->sibling=wineItem->sibling;
+ }
+ if (wineItem->sibling) {
+	siblingItem=& infoPtr->items [wineItem->sibling];
+	siblingItem->upsibling=wineItem->upsibling;
+ }
+}
+
+
+
+static void TREEVIEW_RemoveAllChildren (TREEVIEW_INFO *infoPtr, 
+					   TREEVIEW_ITEM *parentItem)
+
+{
+ TREEVIEW_ITEM *killItem;
+ INT32	kill;
+ 
+ kill=parentItem->firstChild;
+ while (kill) {
+ 	set_bit ( kill & 31, &infoPtr->freeList[kill >>5]);
+ 	killItem=& infoPtr->items[kill];
+	if (killItem->pszText!=LPSTR_TEXTCALLBACK32A) 
+		HeapFree (GetProcessHeap (), 0, killItem->pszText);
+	kill=killItem->sibling;
+ }
+ infoPtr->uNumItems -= parentItem->cChildren;
+ parentItem->firstChild = 0;
+ parentItem->cChildren = 0;
+}
+
+
+
+static void TREEVIEW_RemoveTree (TREEVIEW_INFO *infoPtr)
+					   
+
+{
+ TREEVIEW_ITEM *killItem;
+ int i;
+
+	/* bummer: if we didn't delete anything, test_bit is overhead */
+ 
+    for (i=1; i<=infoPtr->uMaxHandle; i++) 
+	if (!test_bit (i, infoPtr->freeList)) {
+		killItem=& infoPtr->items [i];	
+		if (killItem->pszText!=LPSTR_TEXTCALLBACK32A)
+			HeapFree (GetProcessHeap (), 0, killItem->pszText);
+	} 
+
+    if (infoPtr->uNumPtrsAlloced) {
+        HeapFree (GetProcessHeap (), 0, infoPtr->items);
+        HeapFree (GetProcessHeap (), 0, infoPtr->freeList);
+        infoPtr->uNumItems=0;
+        infoPtr->uNumPtrsAlloced=0;
+        infoPtr->uMaxHandle=0;
+    }   
+
+	/* this function doesn't remove infoPtr itself */
+}
+
+
+
+
+
+
+
+
+
+
 static LRESULT
 TREEVIEW_GetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
-    TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
 
-    switch ((INT32)wParam) {
-	case TVSIL_NORMAL:
-	    return (LRESULT)infoPtr->himlNormal;
+  TRACE (treeview,"\n");
 
-	case TVSIL_STATE:
-	    return (LRESULT)infoPtr->himlState;
-    }
+  if (infoPtr==NULL) return 0;
 
-    return (LRESULT)NULL;
+  if ((INT32)wParam == TVSIL_NORMAL) 
+	return (LRESULT) infoPtr->himlNormal;
+  if ((INT32)wParam == TVSIL_STATE) 
+	return (LRESULT) infoPtr->himlState;
+
+  return 0;
 }
 
 
@@ -68,51 +279,862 @@
 
 
 static LRESULT
-TREEVIEW_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+TREEVIEW_SetItemHeight (WND *wndPtr, WPARAM32 wParam)
 {
-    TREEVIEW_INFO *infoPtr;
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+  INT32 prevHeight=infoPtr->uItemHeight;
+  HDC32 hdc;
+  TEXTMETRIC32A tm;
 
-    /* allocate memory for info structure */
-    infoPtr = (TREEVIEW_INFO *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-                                   sizeof(TREEVIEW_INFO));
-    wndPtr->wExtra[0] = (DWORD)infoPtr;
 
-    if (infoPtr == NULL) {
-	ERR (treeview, "could not allocate info memory!\n");
-	return 0;
+  if (wParam==-1) {
+	hdc=GetDC32 (wndPtr->hwndSelf);
+	infoPtr->uItemHeight=-1;
+	GetTextMetrics32A (hdc, &tm);
+    infoPtr->uRealItemHeight= tm.tmHeight + tm.tmExternalLeading;
+	ReleaseDC32 (wndPtr->hwndSelf, hdc);
+	return prevHeight;
+  }
+
+	/* FIXME: check wParam > imagelist height */
+
+  if (!(wndPtr->dwStyle & TVS_NONEVENHEIGHT))
+	infoPtr->uItemHeight = (INT32) wParam & 0xfffffffe;
+  return prevHeight;
+}
+
+static LRESULT
+TREEVIEW_GetItemHeight (WND *wndPtr)
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+  
+  return infoPtr->uItemHeight;
+}
+  
+static LRESULT
+TREEVIEW_SetTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+  COLORREF prevColor=infoPtr->clrText;
+
+  infoPtr->clrText=(COLORREF) lParam;
+  return (LRESULT) prevColor;
+}
+
+static LRESULT
+TREEVIEW_GetTextColor (WND *wndPtr)
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+	
+  return (LRESULT) infoPtr->clrText;
+}
+
+
+static INT32
+TREEVIEW_DrawItem (WND *wndPtr, HDC32 hdc, TREEVIEW_ITEM *wineItem, 
+		   TREEVIEW_ITEM *upperItem, int indent)
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+  INT32  oldBkMode,center,xpos;
+  COLORREF oldBkColor;
+  UINT32 uTextJustify = DT_LEFT;
+  HPEN32 hOldPen, hnewPen,hRootPen;
+  RECT32 r,upper;
+  
+  hnewPen = CreatePen32(PS_DOT, 0, GetSysColor32(COLOR_WINDOWTEXT) );
+  hOldPen = SelectObject32( hdc, hnewPen );
+ 
+  r=wineItem->rect;
+  if (upperItem) 
+	upper=upperItem->rect;
+  else {
+	upper.top=0;
+	upper.left=8;
+  }
+  center=(r.top+r.bottom)/2;
+  xpos=r.left+8;
+
+  if (wndPtr->dwStyle & TVS_HASLINES) {
+	POINT32 points[3];
+	if ((wndPtr->dwStyle & TVS_LINESATROOT) && (indent==0)) {
+		points[0].y=points[1].y=center;
+		points[2].y=upper.top;
+		points[1].x=points[2].x=upper.left;
+		points[0].x=upper.left+12;
+		points[2].y+=5;
+
+ 		Polyline32 (hdc,points,3);
+	}
+	else {
+		points[0].y=points[1].y=center;
+                points[2].y=upper.top;
+                points[1].x=points[2].x=upper.left+13;
+                points[0].x=upper.left+25;
+                points[2].y+=5;
+ 		Polyline32 (hdc,points,3);
+	}
+ }
+
+  DeleteObject32(hnewPen);
+  SelectObject32(hdc, hOldPen);
+
+  if ((wndPtr->dwStyle & TVS_HASBUTTONS) && (wineItem->cChildren)) {
+/*
+  	hRootPen = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_WINDOW) );
+  	SelectObject32( hdc, hRootPen );
+*/
+
+	Rectangle32 (hdc, xpos-4, center-4, xpos+5, center+5);
+	MoveToEx32 (hdc, xpos-2, center, NULL);
+	LineTo32   (hdc, xpos+3, center);
+	if (!(wineItem->state & TVIS_EXPANDED)) {
+		MoveToEx32 (hdc, xpos,   center-2, NULL);
+		LineTo32   (hdc, xpos,   center+3);
+	}
+ /* 	DeleteObject32(hRootPen); */
+        }
+
+
+  xpos+=13;
+
+  if (wineItem->mask & TVIF_IMAGE) {
+	if (wineItem->iImage!=I_IMAGECALLBACK) {
+  		if (infoPtr->himlNormal) {
+  			ImageList_Draw (infoPtr->himlNormal,wineItem->iImage, hdc,
+                      			xpos-2, r.top+1, ILD_NORMAL);
+  			xpos+=15;
+		}
+	}
+  }
+
+  r.left=xpos;
+  if ((wineItem->mask & TVIF_TEXT) && (wineItem->pszText)) {
+	    if (wineItem->state & TVIS_SELECTED) {
+            	oldBkMode = SetBkMode32(hdc, OPAQUE);
+		oldBkColor= SetBkColor32 (hdc, GetSysColor32( COLOR_HIGHLIGHT));
+		SetTextColor32 (hdc, GetSysColor32(COLOR_HIGHLIGHTTEXT));
+	    }
+	    else {
+            	oldBkMode = SetBkMode32(hdc, TRANSPARENT);
+	    }
+            r.left += 3;
+            r.right -= 3;
+			if (infoPtr->clrText==-1)
+            	SetTextColor32 (hdc, COLOR_BTNTEXT);
+			else 
+				SetTextColor32 (hdc, infoPtr->clrText);  /* FIXME: retval */
+            DrawText32A(hdc, wineItem->pszText, lstrlen32A(wineItem->pszText),
+                  &r, uTextJustify|DT_VCENTER|DT_SINGLELINE);
+            if (oldBkMode != TRANSPARENT)
+                SetBkMode32(hdc, oldBkMode);
+	    if (wineItem->state & TVIS_SELECTED)
+		SetBkColor32 (hdc, oldBkColor);
+        }
+
+ return wineItem->rect.right;
+}
+
+
+
+
+
+
+
+static LRESULT
+TREEVIEW_GetItemRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+  TREEVIEW_ITEM *wineItem;
+  INT32 iItem;
+  LPRECT32 lpRect;
+
+  TRACE (treeview,"\n");
+  if (infoPtr==NULL) return FALSE;
+  
+  iItem = (INT32)lParam;
+  wineItem = TREEVIEW_ValidItem (infoPtr, iItem);
+  if (!wineItem) return FALSE;
+
+  wineItem=& infoPtr->items[ iItem ];
+  if (!wineItem->visible) return FALSE;
+
+  lpRect = (LPRECT32)lParam;
+  if (lpRect == NULL) return FALSE;
+	
+  if ((INT32) wParam) {
+  	lpRect->left	= wineItem->text.left;
+	lpRect->right	= wineItem->text.right;
+	lpRect->bottom	= wineItem->text.bottom;
+	lpRect->top	= wineItem->text.top;
+  } else {
+	lpRect->left 	= wineItem->rect.left;
+	lpRect->right	= wineItem->rect.right;
+	lpRect->bottom  = wineItem->rect.bottom;
+	lpRect->top	= wineItem->rect.top;
+  }
+
+  return TRUE;
+}
+
+
+
+static LRESULT
+TREEVIEW_GetVisibleCount (WND *wndPtr,  WPARAM32 wParam, LPARAM lParam)
+
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+
+  TRACE (treeview,"\n");
+
+  return (LRESULT) infoPtr->uVisibleHeight / infoPtr->uRealItemHeight;
+}
+
+
+
+static LRESULT
+TREEVIEW_SetItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+  TREEVIEW_ITEM *wineItem;
+  TV_ITEM *tvItem;
+  INT32 iItem,len;
+
+  TRACE (treeview,"\n");
+  tvItem=(LPTVITEM) lParam;
+  iItem=tvItem->hItem;
+
+  wineItem = TREEVIEW_ValidItem (infoPtr, iItem);
+  if (!wineItem) return FALSE;
+
+  if (tvItem->mask & TVIF_CHILDREN) {
+        wineItem->cChildren=tvItem->cChildren;
+  }
+
+  if (tvItem->mask & TVIF_IMAGE) {
+       wineItem->iImage=tvItem->iImage;
+  }
+
+  if (tvItem->mask & TVIF_INTEGRAL) {
+/*        wineItem->iIntegral=tvItem->iIntegral; */
+  }
+
+  if (tvItem->mask & TVIF_PARAM) {
+        wineItem->lParam=tvItem->lParam;
+  }
+
+  if (tvItem->mask & TVIF_SELECTEDIMAGE) {
+        wineItem->iSelectedImage=tvItem->iSelectedImage;
+  }
+
+  if (tvItem->mask & TVIF_STATE) {
+        wineItem->state=tvItem->state & tvItem->stateMask;
+  }
+
+  if (tvItem->mask & TVIF_TEXT) {
+        len=tvItem->cchTextMax;
+        if (len>wineItem->cchTextMax) {
+		HeapFree (GetProcessHeap (), 0, wineItem->pszText);
+                wineItem->pszText= HeapAlloc (GetProcessHeap (), 
+				HEAP_ZERO_MEMORY, len+1);
+	}
+        lstrcpyn32A (wineItem->pszText, tvItem->pszText,len);
+   }
+
+  return TRUE;
+}
+
+
+
+
+
+static void
+TREEVIEW_Refresh (WND *wndPtr, HDC32 hdc)
+
+{
+    TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+    HFONT32 hFont, hOldFont;
+    RECT32 rect;
+    HBRUSH32 hbrBk;
+    INT32 iItem, indent, x, y, height;
+    INT32 viewtop,viewbottom,viewleft,viewright;
+    TREEVIEW_ITEM *wineItem, *prevItem;
+
+    TRACE (treeview,"\n");
+
+    if (TREEVIEW_Timer & TV_REFRESH_TIMER_SET) {
+		KillTimer32 (wndPtr->hwndSelf, TV_REFRESH_TIMER);
+		TREEVIEW_Timer &= ~TV_REFRESH_TIMER_SET;
     }
 
-    if ((TREEVIEW_INFO*)wndPtr->wExtra[0] != infoPtr) {
-	ERR (treeview, "pointer assignment error!\n");
-	return 0;
-    }
+    
+    GetClientRect32 (wndPtr->hwndSelf, &rect);
+    if ((rect.left-rect.right ==0) || (rect.top-rect.bottom==0)) return;
+    viewtop=infoPtr->cy;
+    viewbottom=infoPtr->cy + rect.bottom-rect.top;
+    viewleft=infoPtr->cx;
+    viewright=infoPtr->cx + rect.right-rect.left;
 
-    /* set default settings */
-    infoPtr->clrBk = GetSysColor32 (COLOR_WINDOW);
-    infoPtr->clrText = GetSysColor32 (COLOR_BTNTEXT);
-    infoPtr->himlNormal = NULL;
-    infoPtr->himlState = NULL;
+	infoPtr->uVisibleHeight=viewbottom - viewtop;
+
+    hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject32 (DEFAULT_GUI_FONT);
+    hOldFont = SelectObject32 (hdc, hFont);
+
+    /* draw background */
+    hbrBk = GetSysColorBrush32(COLOR_WINDOW);
+    FillRect32(hdc, &rect, hbrBk);
 
 
-    return 0;
+    iItem=infoPtr->TopRootItem;
+    infoPtr->firstVisible=0;
+    wineItem=NULL;
+    indent=0;
+    x=y=0;
+    TRACE (treeview, "[%d %d %d %d]\n",viewtop,viewbottom,viewleft,viewright);
+
+    while (iItem) {
+		prevItem=wineItem;
+        wineItem= & infoPtr->items[iItem];
+
+		TRACE (treeview, "%d %d [%d %d %d %d] (%s)\n",y,x,
+			wineItem->rect.top, wineItem->rect.bottom,
+			wineItem->rect.left, wineItem->rect.right,
+			wineItem->pszText);
+
+		height=infoPtr->uRealItemHeight * wineItem->iIntegral;
+		if ((y >= viewtop) && (y <= viewbottom) &&
+	    	(x >= viewleft  ) && (x <= viewright)) {
+        		wineItem->rect.top = y - infoPtr->cy + rect.top;
+        		wineItem->rect.bottom = wineItem->rect.top + height ;
+         		wineItem->rect.left = x - infoPtr->cx + rect.left;
+        		wineItem->rect.right = rect.right;
+			if (!infoPtr->firstVisible)
+				infoPtr->firstVisible=wineItem->hItem;
+        		TREEVIEW_DrawItem (wndPtr, hdc, wineItem, prevItem, indent);
+		}
+		else {
+			wineItem->rect.top  = wineItem->rect.bottom = -1;
+			wineItem->rect.left = wineItem->rect.right = -1;
+ 		}
+
+		/* look up next item */
+	
+		if ((wineItem->firstChild) && (wineItem->state & TVIS_EXPANDED)) {
+			iItem=wineItem->firstChild;
+			indent++;
+			x+=infoPtr->uIndent;
+		}
+		else {
+			iItem=wineItem->sibling;
+			while ((!iItem) && (indent>0)) {
+				indent--;
+				x-=infoPtr->uIndent;
+				prevItem=wineItem;
+				wineItem=&infoPtr->items[wineItem->parent];
+				iItem=wineItem->sibling;
+			}
+		}
+        y +=height;
+    }				/* while */
+
+    infoPtr->uTotalHeight=y;
+    if (y >= (viewbottom-viewtop)) {
+ 		if (!(infoPtr->uInternalStatus & TV_VSCROLL))
+			ShowScrollBar32 (wndPtr->hwndSelf, SB_VERT, TRUE);
+		infoPtr->uInternalStatus |=TV_VSCROLL;
+ 		SetScrollRange32 (wndPtr->hwndSelf, SB_VERT, 0, 
+					y - infoPtr->uVisibleHeight, FALSE);
+		SetScrollPos32 (wndPtr->hwndSelf, SB_VERT, infoPtr->cy, TRUE);
+	}
+    else {
+		if (infoPtr->uInternalStatus & TV_VSCROLL) 
+			ShowScrollBar32 (wndPtr->hwndSelf, SB_VERT, FALSE);
+		infoPtr->uInternalStatus &= ~TV_VSCROLL;
+	}
+
+
+    SelectObject32 (hdc, hOldFont);
+}
+
+
+static LRESULT 
+TREEVIEW_HandleTimer ( WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+  HDC32 hdc;
+
+  if (!infoPtr) return FALSE;
+ 
+  TRACE (treeview, "timer\n");
+
+  switch (wParam) {
+	case TV_REFRESH_TIMER:
+		KillTimer32 (wndPtr->hwndSelf, TV_REFRESH_TIMER);
+		TREEVIEW_Timer &= ~TV_REFRESH_TIMER_SET;
+		hdc=GetDC32 (wndPtr->hwndSelf);
+		TREEVIEW_Refresh (wndPtr, hdc);
+		ReleaseDC32 (wndPtr->hwndSelf, hdc);
+		return 0;
+	case TV_EDIT_TIMER:
+		KillTimer32 (wndPtr->hwndSelf, TV_EDIT_TIMER);
+		TREEVIEW_Timer &= ~TV_EDIT_TIMER_SET;
+		return 0;
+ }
+		
+ return 1;
+}
+
+
+static void
+TREEVIEW_QueueRefresh (WND *wndPtr)
+
+{
+ 
+ TRACE (treeview,"queued\n");
+ if (TREEVIEW_Timer & TV_REFRESH_TIMER_SET) {
+	KillTimer32 (wndPtr->hwndSelf, TV_REFRESH_TIMER);
+ }
+
+ SetTimer32 (wndPtr->hwndSelf, TV_REFRESH_TIMER, TV_REFRESH_DELAY, 0);
+ TREEVIEW_Timer|=TV_REFRESH_TIMER_SET;
+}
+
+
+
+static LRESULT
+TREEVIEW_GetItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+  LPTVITEM      tvItem;
+  TREEVIEW_ITEM *wineItem;
+  INT32         iItem,len;
+
+  TRACE (treeview,"\n");
+  tvItem=(LPTVITEM) lParam;
+  iItem=tvItem->hItem;
+
+  wineItem = TREEVIEW_ValidItem (infoPtr, iItem);
+  if (!wineItem) return FALSE;
+
+
+   if (tvItem->mask & TVIF_CHILDREN) {
+        tvItem->cChildren=wineItem->cChildren;
+   }
+
+   if (tvItem->mask & TVIF_HANDLE) {
+        tvItem->hItem=wineItem->hItem;
+   }
+
+   if (tvItem->mask & TVIF_IMAGE) {
+        tvItem->iImage=wineItem->iImage;
+   }
+
+   if (tvItem->mask & TVIF_INTEGRAL) {
+/*        tvItem->iIntegral=wineItem->iIntegral; */
+   }
+
+   if (tvItem->mask & TVIF_PARAM) {
+        tvItem->lParam=wineItem->lParam;
+   }
+
+   if (tvItem->mask & TVIF_SELECTEDIMAGE) {
+        tvItem->iSelectedImage=wineItem->iSelectedImage;
+   }
+
+   if (tvItem->mask & TVIF_STATE) {
+        tvItem->state=wineItem->state & tvItem->stateMask;
+   }
+
+   if (tvItem->mask & TVIF_TEXT) {
+	len=wineItem->cchTextMax;
+	if (wineItem->cchTextMax>tvItem->cchTextMax) 
+		len=tvItem->cchTextMax-1;
+        lstrcpyn32A (tvItem->pszText, tvItem->pszText,len);
+   }
+
+  return TRUE;
+}
+
+
+
+static LRESULT
+TREEVIEW_GetNextItem32 (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+  TREEVIEW_ITEM *wineItem;
+  INT32 iItem, flag;
+
+
+  TRACE (treeview,"item:%lu, flags:%x\n", lParam, wParam);
+  if (!infoPtr) return FALSE;
+
+  flag= (INT32) wParam;
+  switch (flag) {
+	case TVGN_ROOT: 	return (LRESULT) infoPtr->TopRootItem;
+	case TVGN_CARET: 	return (LRESULT) infoPtr->selectedItem;
+	case TVGN_FIRSTVISIBLE: return (LRESULT) infoPtr->firstVisible;
+	case TVGN_DROPHILITE:	return (LRESULT) infoPtr->dropItem;
+	}
+	
+  iItem= (INT32) lParam;
+  wineItem = TREEVIEW_ValidItem (infoPtr, iItem);
+  if (!wineItem) return FALSE;
+
+  switch (flag)	{
+	case TVGN_NEXT: 	return (LRESULT) wineItem->sibling;
+	case TVGN_PREVIOUS: 	return (LRESULT) wineItem->upsibling;
+	case TVGN_PARENT: 	return (LRESULT) wineItem->parent;
+	case TVGN_CHILD: 	return (LRESULT) wineItem->firstChild;
+	case TVGN_LASTVISIBLE:  FIXME (treeview,"TVGN_LASTVISIBLE not implemented\n");
+				return 0;
+	case TVGN_NEXTVISIBLE:  wineItem=TREEVIEW_GetNextListItem 
+						(infoPtr,wineItem);
+				if (wineItem) 
+					return (LRESULT) wineItem->hItem;
+				else
+					return (LRESULT) 0;
+	case TVGN_PREVIOUSVISIBLE: wineItem=TREEVIEW_GetPrevListItem
+						(infoPtr, wineItem);
+				if (wineItem) 
+					return (LRESULT) wineItem->hItem;
+				else
+					return (LRESULT) 0;
+	default:	FIXME (treeview,"Unknown msg %x,item %x\n", flag,iItem);
+	}
+
+ return 0;
 }
 
 
 static LRESULT
-TREEVIEW_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+TREEVIEW_GetCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
-    TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+ TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+
+ return (LRESULT) infoPtr->uNumItems;
+}
 
 
 
 
-    /* free tree view info data */
-    HeapFree (GetProcessHeap (), 0, infoPtr);
+/* the method used below isn't the most memory-friendly, but it avoids 
+   a lot of memory reallocations */ 
+
+/* BTW: we waste handle 0; 0 is not an allowed handle. Fix this by
+        decreasing infoptr->items with 1, and increasing it by 1 if 
+        it is referenced in mm-handling stuff? */
+
+static LRESULT
+TREEVIEW_InsertItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+  TVINSERTSTRUCT  *ptdi;
+  TV_ITEM 	*tvItem;
+  TREEVIEW_ITEM *wineItem, *parentItem, *prevsib, *sibItem;
+  INT32		iItem,listItems,i,len;
+  
+  TRACE (treeview,"\n");
+  ptdi = (TVINSERTSTRUCT *) lParam;
+
+	/* check if memory is available */
+
+  if (infoPtr->uNumPtrsAlloced==0) {
+        infoPtr->items = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
+                                    TVITEM_ALLOC*sizeof (TREEVIEW_ITEM));
+        infoPtr->freeList= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
+                                    (1+(TVITEM_ALLOC>>5)) *sizeof (INT32));
+        infoPtr->uNumPtrsAlloced=TVITEM_ALLOC;
+	infoPtr->TopRootItem=1;
+   }
+
+  if (infoPtr->uNumItems == (infoPtr->uNumPtrsAlloced-1) ) {
+   	TREEVIEW_ITEM *oldItems = infoPtr->items;
+	INT32 *oldfreeList = infoPtr->freeList;
+
+	infoPtr->uNumPtrsAlloced*=2;
+        infoPtr->items = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
+                              infoPtr->uNumPtrsAlloced*sizeof (TREEVIEW_ITEM));
+        infoPtr->freeList= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
+                              (1+(infoPtr->uNumPtrsAlloced>>5))*sizeof (INT32));
+
+        memcpy (&infoPtr->items[0], &oldItems[0],
+                    infoPtr->uNumPtrsAlloced/2 * sizeof(TREEVIEW_ITEM));
+        memcpy (&infoPtr->freeList[0], &oldfreeList[0],
+                    infoPtr->uNumPtrsAlloced>>6 * sizeof(INT32));
+
+         HeapFree (GetProcessHeap (), 0, oldItems);  
+         HeapFree (GetProcessHeap (), 0, oldfreeList);  
+    }
+
+  iItem=0;
+  infoPtr->uNumItems++;
+
+  if (infoPtr->uMaxHandle==(infoPtr->uNumItems-1))  { 
+  	iItem=infoPtr->uNumItems;
+  	infoPtr->uMaxHandle++;
+  } 
+  else {					 /* check freelist */
+	for (i=0; i<infoPtr->uNumPtrsAlloced>>5; i++) {
+		if (infoPtr->freeList[i]) {
+			iItem=ffs (infoPtr->freeList[i]);
+			clear_bit (iItem & 31, & infoPtr->freeList[i]);
+			break;
+		}
+  	 } 
+  }
+  if (!iItem) ERR (treeview, "Argh -- can't find free item.\n");
+  
+  tvItem= & ptdi->item;
+  wineItem=& infoPtr->items[iItem];
+
+
+
+  if ((ptdi->hParent==TVI_ROOT) || (ptdi->hParent==0)) {
+	parentItem=NULL;
+	wineItem->parent=0; 
+	sibItem=&infoPtr->items [infoPtr->TopRootItem];
+	listItems=infoPtr->uNumItems;
+  }
+  else  {
+	parentItem= &infoPtr->items[ptdi->hParent];
+	if (!parentItem->firstChild) 
+		parentItem->firstChild=iItem;
+	wineItem->parent=ptdi->hParent;
+	sibItem=&infoPtr->items [parentItem->firstChild];
+	parentItem->cChildren++;
+	listItems=parentItem->cChildren;
+  }
+
+  wineItem->upsibling=0;  /* needed in case we're the first item in a list */ 
+  wineItem->sibling=0;     
+  wineItem->firstChild=0;
+
+  if (listItems>1) {
+     prevsib=NULL;
+     switch (ptdi->hInsertAfter) {
+		case TVI_FIRST: wineItem->sibling=infoPtr->TopRootItem;
+			infoPtr->TopRootItem=iItem;
+			break;
+		case TVI_LAST:  
+			while (sibItem->sibling) {
+				prevsib=sibItem;
+				sibItem=&infoPtr->items [sibItem->sibling];
+			}
+			sibItem->sibling=iItem;
+			if (prevsib!=NULL) 
+				wineItem->upsibling=prevsib->hItem;
+			else
+  				wineItem->sibling=0; 	/* terminate list */
+			break;
+		case TVI_SORT:  
+			FIXME (treeview, "Sorted insert not implemented yet\n");
+			break;
+		default:	
+			while ((sibItem->sibling) && (sibItem->sibling!=iItem)) {
+				prevsib=sibItem;
+                sibItem=&infoPtr->items [sibItem->sibling];
+            }
+			if (sibItem->sibling) 
+				WARN (treeview, "Buggy program tried to insert item after nonexisting handle.");
+			sibItem->upsibling=iItem;
+			wineItem->sibling=sibItem->hItem;
+			if (prevsib!=NULL) 
+				wineItem->upsibling=prevsib->hItem;
+			break;
+   	}
+   }	
+
+
+/* Fill in info structure */
+
+   wineItem->mask=tvItem->mask;
+   wineItem->hItem=iItem;
+   wineItem->iIntegral=1; 
+
+   if (tvItem->mask & TVIF_CHILDREN)
+	 wineItem->cChildren=tvItem->cChildren;
+
+   if (tvItem->mask & TVIF_IMAGE) 
+	wineItem->iImage=tvItem->iImage;
+
+/*   if (tvItem->mask & TVIF_INTEGRAL) 
+   	wineItem->iIntegral=tvItem->iIntegral;  */
+   
+
+   if (tvItem->mask & TVIF_PARAM) 
+	wineItem->lParam=tvItem->lParam;
+
+   if (tvItem->mask & TVIF_SELECTEDIMAGE) 
+	wineItem->iSelectedImage=tvItem->iSelectedImage;
+
+   if (tvItem->mask & TVIF_STATE) {
+	wineItem->state=tvItem->state;
+	wineItem->stateMask=tvItem->stateMask;
+   }
+
+   if (tvItem->mask & TVIF_TEXT) {
+   	TRACE (treeview,"(%s)\n", tvItem->pszText); 
+	if (tvItem->pszText!=LPSTR_TEXTCALLBACK32A) {
+		len = lstrlen32A (tvItem->pszText)+1;
+		wineItem->pszText=
+			HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len+1);
+		lstrcpy32A (wineItem->pszText, tvItem->pszText);
+		wineItem->cchTextMax=len;
+	}
+   }
+
+   TREEVIEW_QueueRefresh (wndPtr);
+
+   return (LRESULT) iItem;
+}
+
+
+
+static LRESULT
+TREEVIEW_DeleteItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+  INT32 iItem;
+  POINT32 pt;
+  TREEVIEW_ITEM *wineItem;
+
+  TRACE (treeview,"\n");
+  if (!infoPtr) return FALSE;
+
+  if ((INT32) lParam == TVI_ROOT) {
+	TREEVIEW_RemoveTree (infoPtr);
+  } else {
+  	iItem= (INT32) lParam;
+  	wineItem = TREEVIEW_ValidItem (infoPtr, iItem);
+  	if (!wineItem) return FALSE;
+	TREEVIEW_SendTreeviewNotify (wndPtr, TVN_DELETEITEM, 0, iItem, 0, pt);
+	TREEVIEW_RemoveItem (infoPtr, wineItem);
+  }
+
+  TREEVIEW_QueueRefresh (wndPtr);
+
+  return TRUE;
+}
+
+
+static LRESULT
+TREEVIEW_GetIndent (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+ TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+
+ return infoPtr->uIndent;
+}
+
+static LRESULT
+TREEVIEW_SetIndent (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+  INT32 newIndent;
+   
+  newIndent=(INT32) wParam;
+  if (newIndent < MINIMUM_INDENT) newIndent=MINIMUM_INDENT;
+  infoPtr->uIndent=newIndent;
+  
+  return 0;
+}
+
+
+
+
+
+static LRESULT
+TREEVIEW_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TREEVIEW_INFO *infoPtr;
+	HDC32 hdc;
+    TEXTMETRIC32A tm;
+  
+    TRACE (treeview,"\n");
+      /* allocate memory for info structure */
+      infoPtr = (TREEVIEW_INFO *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
+                                     sizeof(TREEVIEW_INFO));
+
+    wndPtr->wExtra[0] = (DWORD)infoPtr;
+
+    if (infoPtr == NULL) {
+		ERR (treeview, "could not allocate info memory!\n");
+		return 0;
+    }
+
+    if ((TREEVIEW_INFO*)wndPtr->wExtra[0] != infoPtr) {
+		ERR (treeview, "pointer assignment error!\n");
+		return 0;
+    }
+
+	hdc=GetDC32 (wndPtr->hwndSelf);
+
+    /* set default settings */
+    infoPtr->uInternalStatus=0;
+    infoPtr->uNumItems=0;
+    infoPtr->clrBk = GetSysColor32 (COLOR_WINDOW);
+    infoPtr->clrText = GetSysColor32 (COLOR_BTNTEXT);
+    infoPtr->cy = 0;
+    infoPtr->cx = 0;
+    infoPtr->uIndent = 15;
+    infoPtr->himlNormal = NULL;
+    infoPtr->himlState = NULL;
+	infoPtr->uItemHeight = -1;
+    GetTextMetrics32A (hdc, &tm);
+    infoPtr->uRealItemHeight= tm.tmHeight + tm.tmExternalLeading;
+
+    infoPtr->items = NULL;
+    infoPtr->selectedItem=0;
+    infoPtr->clrText=-1;	/* use system color */
+    infoPtr->dropItem=0;
+
+/*
+    infoPtr->hwndNotify = GetParent32 (wndPtr->hwndSelf);
+    infoPtr->bTransparent = (wndPtr->dwStyle & TBSTYLE_FLAT);
+*/
+
+    if (wndPtr->dwStyle & TBSTYLE_TOOLTIPS) {
+        /* Create tooltip control */
+//      infoPtr->hwndToolTip = CreateWindowEx32A (....);
+
+        /* Send TV_TOOLTIPSCREATED notification */
+
+    }
+    ReleaseDC32 (wndPtr->hwndSelf, hdc);
 
     return 0;
 }
 
 
+
+static LRESULT 
+TREEVIEW_Destroy (WND *wndPtr) 
+{
+   TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+     
+   TREEVIEW_RemoveTree (infoPtr);
+
+   HeapFree (GetProcessHeap (), 0, infoPtr);
+
+   return 0;
+}
+
+
+static LRESULT
+TREEVIEW_Paint (WND *wndPtr, WPARAM32 wParam)
+{
+    HDC32 hdc;
+    PAINTSTRUCT32 ps;
+
+    hdc = wParam==0 ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam;
+    TREEVIEW_QueueRefresh (wndPtr);
+    if(!wParam)
+        EndPaint32 (wndPtr->hwndSelf, &ps);
+    return 0;
+}
+
+
+
 static LRESULT
 TREEVIEW_EraseBackground (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 {
@@ -120,6 +1142,7 @@
     HBRUSH32 hBrush = CreateSolidBrush32 (infoPtr->clrBk);
     RECT32 rect;
 
+    TRACE (treeview,"\n");
     GetClientRect32 (wndPtr->hwndSelf, &rect);
     FillRect32 ((HDC32)wParam, &rect, hBrush);
     DeleteObject32 (hBrush);
@@ -128,161 +1151,653 @@
 
 
 
-LRESULT WINAPI
-TREEVIEW_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
+
+
+  
+
+
+
+static BOOL32
+TREEVIEW_SendSimpleNotify (WND *wndPtr, UINT32 code)
 {
-    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    NMHDR nmhdr;
 
-    switch (uMsg)
-    {
+    TRACE (treeview, "%x\n",code);
+    nmhdr.hwndFrom = wndPtr->hwndSelf;
+    nmhdr.idFrom   = wndPtr->wIDmenu;
+    nmhdr.code     = code;
 
-    case TVM_INSERTITEM32A:
-      FIXME (treeview, "Unimplemented msg TVM_INSERTITEM32A\n");
-      return 0;
+    return (BOOL32) SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
+                                   (WPARAM32)nmhdr.idFrom, (LPARAM)&nmhdr);
+}
 
-    case TVM_INSERTITEM32W:
-      FIXME (treeview, "Unimplemented msg TVM_INSERTITEM32W\n");
-      return 0;
 
-    case TVM_DELETEITEM:
-      FIXME (treeview, "Unimplemented msg TVM_DELETEITEM\n");
-      return 0;
 
-    case TVM_EXPAND:
-      FIXME (treeview, "Unimplemented msg TVM_EXPAND\n");
-      return 0;
 
-    case TVM_GETITEMRECT:
-      FIXME (treeview, "Unimplemented msg TVM_GETITEMRECT\n");
-      return 0;
+static BOOL32
+TREEVIEW_SendTreeviewNotify (WND *wndPtr, UINT32 code, UINT32 action, 
+			INT32 oldItem, INT32 newItem, POINT32 pt)
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+  NMTREEVIEW nmhdr;
+  TREEVIEW_ITEM  *wineItem;
 
-    case TVM_GETCOUNT:
-      FIXME (treeview, "Unimplemented msg TVM_GETCOUNT\n");
-      return 0;
+  TRACE (treeview,"code:%x action:%x olditem:%x newitem:%x\n",
+		  code,action,oldItem,newItem);
+  nmhdr.hdr.hwndFrom = wndPtr->hwndSelf;
+  nmhdr.hdr.idFrom = wndPtr->wIDmenu;
+  nmhdr.hdr.code = code;
+  nmhdr.action = action;
+  if (oldItem) {
+  	wineItem=& infoPtr->items[oldItem];
+  	nmhdr.itemOld.mask 		= wineItem->mask;
+  	nmhdr.itemOld.hItem		= wineItem->hItem;
+  	nmhdr.itemOld.state		= wineItem->state;
+  	nmhdr.itemOld.stateMask	= wineItem->stateMask;
+  	nmhdr.itemOld.iImage 		= wineItem->iImage;
+  	nmhdr.itemOld.pszText 	= wineItem->pszText;
+  	nmhdr.itemOld.cchTextMax 	= wineItem->cchTextMax;
+  	nmhdr.itemOld.iImage 		= wineItem->iImage;
+  	nmhdr.itemOld.iSelectedImage 	= wineItem->iSelectedImage;
+  	nmhdr.itemOld.cChildren 	= wineItem->cChildren;
+  	nmhdr.itemOld.lParam		= wineItem->lParam;
+  }
 
-    case TVM_GETINDENT:
-      FIXME (treeview, "Unimplemented msg TVM_GETINDENT\n");
-      return 0;
+  if (newItem) {
+  	wineItem=& infoPtr->items[newItem];
+  	nmhdr.itemNew.mask 		= wineItem->mask;
+  	nmhdr.itemNew.hItem		= wineItem->hItem;
+  	nmhdr.itemNew.state		= wineItem->state;
+  	nmhdr.itemNew.stateMask	= wineItem->stateMask;
+  	nmhdr.itemNew.iImage 		= wineItem->iImage;
+  	nmhdr.itemNew.pszText 	= wineItem->pszText;
+  	nmhdr.itemNew.cchTextMax 	= wineItem->cchTextMax;
+  	nmhdr.itemNew.iImage 		= wineItem->iImage;
+  	nmhdr.itemNew.iSelectedImage 	= wineItem->iSelectedImage;
+  	nmhdr.itemNew.cChildren 	= wineItem->cChildren;
+  	nmhdr.itemNew.lParam		= wineItem->lParam;
+  }
 
-    case TVM_SETINDENT:
-      FIXME (treeview, "Unimplemented msg TVM_SETINDENT\n");
-      return 0;
+  nmhdr.ptDrag.x = pt.x;
+  nmhdr.ptDrag.y = pt.y;
 
-	case TVM_GETIMAGELIST:
-	    return TREEVIEW_GetImageList (wndPtr, wParam, lParam);
+  return (BOOL32)SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
+                                   (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmhdr);
 
-	case TVM_SETIMAGELIST:
-	    return TREEVIEW_SetImageList (wndPtr, wParam, lParam);
+}
 
-    case TVM_GETNEXTITEM:
-      FIXME (treeview, "Unimplemented msg TVM_GETNEXTITEM\n");
-      return 0;
 
-    case TVM_SELECTITEM:
-      FIXME (treeview, "Unimplemented msg TVM_SELECTITEM \n");
-      return 0;
 
-    case TVM_GETITEM32A:
-      FIXME (treeview, "Unimplemented msg TVM_GETITEM32A\n");
-      return 0;
 
-    case TVM_GETITEM32W:
-      FIXME (treeview, "Unimplemented msg TVM_GETITEM32W\n");
-      return 0;
+static LRESULT
+TREEVIEW_Expand (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+ TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+ TREEVIEW_ITEM *wineItem;
+ UINT32 flag;
+ INT32 expandItem;
+ POINT32 pt;
+ 
+ flag= (UINT32) wParam;
+ expandItem= (INT32) lParam;
+ TRACE (treeview,"flags:%x item:%x\n", expandItem, wParam);
+ wineItem = TREEVIEW_ValidItem (infoPtr, expandItem);
+ if (!wineItem) return 0;
+ if (!wineItem->cChildren) return 0;
 
-    case TVM_SETITEM32A:
-      FIXME (treeview, "Unimplemented msg TVM_SETITEM32A\n");
-      return 0;
+ if (flag & TVE_TOGGLE) {		/* FIXME: check exact behaviour here */
+	flag &= ~TVE_TOGGLE;		/* ie: bitwise ops or 'case' ops */
+	if (wineItem->state & TVIS_EXPANDED) 
+		flag |= TVE_COLLAPSE;
+	else
+		flag |= TVE_EXPAND;
+ }
 
-    case TVM_SETITEM32W:
-      FIXME (treeview, "Unimplemented msg TVM_SETITEM32W\n");
-      return 0;
+ switch (flag) {
+    case TVE_COLLAPSERESET: 
+   		if (!wineItem->state & TVIS_EXPANDED) return 0;
+		wineItem->state &= ~(TVIS_EXPANDEDONCE | TVIS_EXPANDED);
+		TREEVIEW_RemoveAllChildren (infoPtr, wineItem);
+		break;
 
-    case TVM_EDITLABEL32A:
-      FIXME (treeview, "Unimplemented msg TVM_EDITLABEL32A\n");
-      return 0;
+    case TVE_COLLAPSE: 
+		if (!wineItem->state & TVIS_EXPANDED) return 0;
+		wineItem->state &= ~TVIS_EXPANDED;
+		break;
 
-    case TVM_EDITLABEL32W:
-      FIXME (treeview, "Unimplemented msg TVM_EDITLABEL32W\n");
-      return 0;
+    case TVE_EXPAND: 
+		if (wineItem->state & TVIS_EXPANDED) return 0;
+		if (!(wineItem->state & TVIS_EXPANDEDONCE)) {
+    		if (TREEVIEW_SendTreeviewNotify (wndPtr, TVN_ITEMEXPANDING, 
+											0, 0, expandItem, pt))
+					return FALSE; 	/* FIXME: OK? */
+		wineItem->state |= TVIS_EXPANDED | TVIS_EXPANDEDONCE;
+    	TREEVIEW_SendTreeviewNotify (wndPtr, TVN_ITEMEXPANDED, 
+											0, 0, expandItem, pt);
+ 	}
+	wineItem->state |= TVIS_EXPANDED;
+	break;
+   case TVE_EXPANDPARTIAL:
+		FIXME (treeview, "TVE_EXPANDPARTIAL not implemented\n");
+		wineItem->state ^=TVIS_EXPANDED;
+		wineItem->state |=TVIS_EXPANDEDONCE;
+		break;
+  }
+ 
+ TREEVIEW_QueueRefresh (wndPtr);
 
-    case TVM_GETEDITCONTROL:
-      FIXME (treeview, "Unimplemented msg TVM_GETEDITCONTROL\n");
-      return 0;
+ return TRUE;
+}
 
-    case TVM_GETVISIBLECOUNT:
-      FIXME (treeview, "Unimplemented msg TVM_GETVISIBLECOUNT\n");
-      return 0;
 
-    case TVM_HITTEST:
-      FIXME (treeview, "Unimplemented msg TVM_HITTEST\n");
-      return 0;
 
-    case TVM_CREATEDRAGIMAGE:
-      FIXME (treeview, "Unimplemented msg TVM_CREATEDRAGIMAGE\n");
-      return 0;
+static HTREEITEM
+TREEVIEW_HitTest (WND *wndPtr, LPTVHITTESTINFO lpht)
+{
+ TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+ TREEVIEW_ITEM *wineItem;
+ RECT32 rect;
+ UINT32 status,x,y;
+ 
 
-    case TVM_SORTCHILDREN:
-      FIXME (treeview, "Unimplemented msg TVM_SORTCHILDREN\n");
-      return 0;
 
-    case TVM_ENSUREVISIBLE:
-      FIXME (treeview, "Unimplemented msg TVM_ENSUREVISIBLE\n");
-      return 0;
+ GetClientRect32 (wndPtr->hwndSelf, &rect);
+ TRACE (treeview,"(%d,%d)\n",lpht->pt.x, lpht->pt.y);
 
-    case TVM_SORTCHILDRENCB:
-      FIXME (treeview, "Unimplemented msg TVM_SORTCHILDRENCB\n");
-      return 0;
+ status=0;
+ x=lpht->pt.x;
+ y=lpht->pt.y;
+ if (x < rect.left)  status|=TVHT_TOLEFT;
+ if (x > rect.right) status|=TVHT_TORIGHT;
+ if (y < rect.top )  status|=TVHT_ABOVE;
+ if (y > rect.bottom) status|=TVHT_BELOW;
+ if (status) {
+	lpht->flags=status;
+	return 0;
+ }
 
-    case TVM_ENDEDITLABELNOW:
-      FIXME (treeview, "Unimplemented msg TVM_ENDEDITLABELNOW\n");
-      return 0;
+ if (!infoPtr->firstVisible) WARN (treeview,"Can't fetch first visible item");
+ wineItem=&infoPtr->items [infoPtr->firstVisible];
 
-    case TVM_GETISEARCHSTRING32A:
-      FIXME (treeview, "Unimplemented msg TVM_GETISEARCHSTRING32A\n");
-      return 0;
+ while ((wineItem!=NULL) && (y > wineItem->rect.bottom))
+       wineItem=TREEVIEW_GetNextListItem (infoPtr,wineItem);
+	
+ if (wineItem==NULL) {
+	lpht->flags=TVHT_NOWHERE;
+	return 0;
+ }
 
-    case TVM_GETISEARCHSTRING32W:
-      FIXME (treeview, "Unimplemented msg TVM_GETISEARCHSTRING32W\n");
-      return 0;
+ if (x>wineItem->rect.right) {
+	lpht->flags|=TVHT_ONITEMRIGHT;
+	return wineItem->hItem;
+ }
+ 
+	
+ if (x<wineItem->rect.left+10) lpht->flags|=TVHT_ONITEMBUTTON;
 
-    case TVM_SETTOOLTIPS:
-      FIXME (treeview, "Unimplemented msg TVM_SETTOOLTIPS\n");
-      return 0;
+ lpht->flags=TVHT_ONITEMLABEL;    /* FIXME: implement other flags */
+	
 
-    case TVM_GETTOOLTIPS:
-      FIXME (treeview, "Unimplemented msg TVM_GETTOOLTIPS\n");
-      return 0;
+ lpht->hItem=wineItem->hItem;
+ return wineItem->hItem;
+}
 
-	case WM_CREATE:
-	    return TREEVIEW_Create (wndPtr, wParam, lParam);
 
-	case WM_DESTROY:
-	    return TREEVIEW_Destroy (wndPtr, wParam, lParam);
+static LRESULT
+TREEVIEW_HitTest32 (WND *wndPtr, LPARAM lParam)
+{
+ 
+  return (LRESULT) TREEVIEW_HitTest (wndPtr, (LPTVHITTESTINFO) lParam);
+}
 
-//	case EM_ENABLE:
 
-	case WM_ERASEBKGND:
-	    return TREEVIEW_EraseBackground (wndPtr, wParam, lParam);
 
-	case WM_GETDLGCODE:
-	    return DLGC_WANTARROWS | DLGC_WANTCHARS;
 
-//	case WM_PAINT:
-//	    return TREEVIEW_Paint (wndPtr, wParam);
+LRESULT
+TREEVIEW_LButtonDoubleClick (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+  TREEVIEW_ITEM *wineItem;
+  INT32 iItem;
+  TVHITTESTINFO ht;
 
-//	case WM_SETFONT:
+  TRACE (treeview,"\n");
+  ht.pt.x = (INT32)LOWORD(lParam);
+  ht.pt.y = (INT32)HIWORD(lParam);
+  SetFocus32 (wndPtr->hwndSelf);
 
-//	case WM_TIMER:
+  iItem=TREEVIEW_HitTest (wndPtr, &ht);
+  TRACE (treeview,"item %d \n",iItem);
+  wineItem=TREEVIEW_ValidItem (infoPtr, iItem);
+  if (!wineItem) return 0;
+ 
+  if (TREEVIEW_SendSimpleNotify (wndPtr, NM_DBLCLK)!=TRUE) {     /* FIXME!*/
+	wineItem->state &= ~TVIS_EXPANDEDONCE;
+	TREEVIEW_Expand (wndPtr, (WPARAM32) TVE_TOGGLE, (LPARAM) iItem);
+ }
+ return TRUE;
+}
 
-//	case WM_VSCROLL:
 
-	default:
-	    if (uMsg >= WM_USER)
+
+static LRESULT
+TREEVIEW_LButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+  INT32 iItem;
+  TVHITTESTINFO ht;
+
+  TRACE (treeview,"\n");
+  ht.pt.x = (INT32)LOWORD(lParam);
+  ht.pt.y = (INT32)HIWORD(lParam);
+
+  SetFocus32 (wndPtr->hwndSelf);
+  iItem=TREEVIEW_HitTest (wndPtr, &ht);
+  TRACE (treeview,"item %d \n",iItem);
+  if (ht.flags & TVHT_ONITEMBUTTON) {
+	TREEVIEW_Expand (wndPtr, (WPARAM32) TVE_TOGGLE, (LPARAM) iItem);
+  }
+	
+  if (TREEVIEW_SelectItem (wndPtr, (WPARAM32) TVGN_CARET, (LPARAM) iItem))
+	 return 0;
+
+  
+ return 0;
+}
+
+
+static LRESULT
+TREEVIEW_RButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+
+ return 0;
+}
+
+
+
+
+/* FIXME: If the specified item is the child of a collapsed parent item,
+expand parent's list of child items to reveal the specified item.
+*/
+
+static LRESULT
+TREEVIEW_SelectItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+ TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+ TREEVIEW_ITEM *prevItem,*wineItem;
+ INT32 action,prevSelect, newSelect;
+ POINT32 dummy;
+
+  TRACE (treeview,"item %lx, flag %x\n", lParam, wParam);
+  newSelect= (INT32) lParam;
+  wineItem = TREEVIEW_ValidItem (infoPtr, newSelect);
+  if (!wineItem) return FALSE;
+  prevSelect=infoPtr->selectedItem;
+  prevItem= TREEVIEW_ValidItem (infoPtr, prevSelect);
+  dummy.x=0;
+  dummy.y=0;
+
+  action= (INT32) wParam;
+
+  switch (action) {
+	case TVGN_CARET: 
+	    if (TREEVIEW_SendTreeviewNotify (wndPtr, TVN_SELCHANGING, TVC_BYMOUSE, 
+										prevSelect, newSelect,dummy)) 
+			return FALSE;       /* FIXME: OK? */
+		
+	    if (prevItem) prevItem->state &= ~TVIS_SELECTED;
+  		infoPtr->selectedItem=newSelect;
+		wineItem->state |=TVIS_SELECTED;
+		TREEVIEW_SendTreeviewNotify (wndPtr, TVN_SELCHANGED, 
+				TVC_BYMOUSE, prevSelect, newSelect, dummy);
+		break;
+	case TVGN_DROPHILITE: 
+		FIXME (treeview, "DROPHILITE not implemented");
+		break;
+	case TVGN_FIRSTVISIBLE:
+		FIXME (treeview, "FIRSTVISIBLE not implemented");
+		break;
+ }
+ 
+ TREEVIEW_QueueRefresh (wndPtr);
+  
+ return TRUE;
+}
+
+
+
+/* FIXME: does KEYDOWN also send notifications?? If so, use 
+   TREEVIEW_SelectItem.
+*/
+   
+
+static LRESULT
+TREEVIEW_KeyDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+ TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+ TREEVIEW_ITEM *prevItem,*newItem;
+ int prevSelect;
+
+
+ TRACE (treeview,"%x %lx",wParam, lParam);
+ prevSelect=infoPtr->selectedItem;
+ if (!prevSelect) return FALSE;
+
+ prevItem= TREEVIEW_ValidItem (infoPtr, prevSelect);
+ 
+ newItem=NULL;
+ switch (wParam) {
+	case VK_UP: 
+		newItem=TREEVIEW_GetPrevListItem (infoPtr, prevItem);
+		if (!newItem) 
+			newItem=& infoPtr->items[infoPtr->TopRootItem];
+		break;
+	case VK_DOWN: 
+		newItem=TREEVIEW_GetNextListItem (infoPtr, prevItem);
+		if (!newItem) newItem=prevItem;
+		break;
+	case VK_HOME:
+		newItem=& infoPtr->items[infoPtr->TopRootItem];
+		break;
+	case VK_END:
+		newItem=TREEVIEW_GetLastListItem (infoPtr);
+		break;
+	case VK_PRIOR:
+	case VK_NEXT:
+	case VK_BACK:
+	case VK_RETURN:
+		FIXME (treeview, "%x not implemented\n", wParam);
+		break;
+ }
+
+ if (!newItem) return FALSE;
+
+ if (prevItem!=newItem) {
+ 	prevItem->state &= ~TVIS_SELECTED;
+ 	newItem->state |= TVIS_SELECTED;
+ 	infoPtr->selectedItem=newItem->hItem;
+ 	TREEVIEW_QueueRefresh (wndPtr);
+ 	return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+
+static LRESULT
+TREEVIEW_VScroll (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+  int maxHeight;
+
+  TRACE (treeview,"wp %x, lp %lx\n", wParam, lParam);
+  if (!infoPtr->uInternalStatus & TV_VSCROLL) return FALSE;
+
+  switch (LOWORD (wParam)) {
+	case SB_LINEUP: 
+			if (!infoPtr->cy) return FALSE;
+			infoPtr->cy -= infoPtr->uRealItemHeight;
+			if (infoPtr->cy < 0) infoPtr->cy=0;
+			break;
+	case SB_LINEDOWN: 
+			maxHeight=infoPtr->uTotalHeight-infoPtr->uVisibleHeight;
+			if (infoPtr->cy == maxHeight) return FALSE;
+			infoPtr->cy += infoPtr->uRealItemHeight;
+			if (infoPtr->cy > maxHeight) 
+				infoPtr->cy = maxHeight;
+			break;
+	case SB_PAGEUP:	
+			if (!infoPtr->cy) return FALSE;
+			infoPtr->cy -= infoPtr->uVisibleHeight;
+			if (infoPtr->cy < 0) infoPtr->cy=0;
+			break;
+	case SB_PAGEDOWN:
+			maxHeight=infoPtr->uTotalHeight-infoPtr->uVisibleHeight;
+			if (infoPtr->cy == maxHeight) return FALSE;
+			infoPtr->cy += infoPtr->uVisibleHeight;
+            if (infoPtr->cy > maxHeight)
+                infoPtr->cy = maxHeight;
+			break;
+	case SB_THUMBTRACK: 
+			infoPtr->cy = HIWORD (wParam);
+			break;
+			
+  }
+  
+  TREEVIEW_QueueRefresh (wndPtr);
+  return TRUE;
+}
+
+static LRESULT
+TREEVIEW_HScroll (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) 
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr);
+
+  TRACE (treeview,"wp %lx, lp %x\n", lParam, wParam);
+	
+  if (!infoPtr->uInternalStatus & TV_HSCROLL) return FALSE;
+  return TRUE;
+}
+
+
+
+
+  LRESULT WINAPI
+  TREEVIEW_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
+  {
+      WND *wndPtr = WIN_FindWndPtr(hwnd);
+  
+  
+    switch (uMsg) {
+    	case TVM_INSERTITEM32A:
+          return TREEVIEW_InsertItem32A (wndPtr, wParam, lParam);
+
+    	case TVM_INSERTITEM32W:
+      		FIXME (treeview, "Unimplemented msg TVM_INSERTITEM32W\n");
+      		return 0;
+
+    	case TVM_DELETEITEM:
+      		return TREEVIEW_DeleteItem (wndPtr, wParam, lParam);
+
+    	case TVM_EXPAND:
+      		return TREEVIEW_Expand (wndPtr, wParam, lParam);
+
+    	case TVM_GETITEMRECT:
+      		return TREEVIEW_GetItemRect (wndPtr, wParam, lParam);
+
+    	case TVM_GETCOUNT:
+      		return TREEVIEW_GetCount (wndPtr, wParam, lParam);
+
+    	case TVM_GETINDENT:
+      		return TREEVIEW_GetIndent (wndPtr, wParam, lParam);
+
+    	case TVM_SETINDENT:
+      		return TREEVIEW_SetIndent (wndPtr, wParam, lParam);
+
+    	case TVM_GETIMAGELIST:
+      		return TREEVIEW_GetImageList (wndPtr, wParam, lParam);
+
+		case TVM_SETIMAGELIST:
+	    	return TREEVIEW_SetImageList (wndPtr, wParam, lParam);
+
+    	case TVM_GETNEXTITEM:
+      		return TREEVIEW_GetNextItem32 (wndPtr, wParam, lParam);
+
+    	case TVM_SELECTITEM:
+      		return TREEVIEW_SelectItem (wndPtr, wParam, lParam);
+
+    	case TVM_GETITEM32A:
+      		return TREEVIEW_GetItem (wndPtr, wParam, lParam);
+
+    	case TVM_GETITEM32W:
+      		FIXME (treeview, "Unimplemented msg TVM_GETITEM32W\n");
+      		return 0;
+
+    	case TVM_SETITEM32A:
+      		return TREEVIEW_SetItem (wndPtr, wParam, lParam);
+
+    	case TVM_SETITEM32W:
+      		FIXME (treeview, "Unimplemented msg TVM_SETITEMW\n");
+      		return 0;
+
+    	case TVM_EDITLABEL32A:
+      		FIXME (treeview, "Unimplemented msg TVM_EDITLABEL32A \n");
+      		return 0;
+
+    	case TVM_EDITLABEL32W:
+      		FIXME (treeview, "Unimplemented msg TVM_EDITLABEL32W \n");
+      		return 0;
+
+    	case TVM_GETEDITCONTROL:
+      		FIXME (treeview, "Unimplemented msg TVM_GETEDITCONTROL\n");
+      		return 0;
+
+    	case TVM_GETVISIBLECOUNT:
+      		return TREEVIEW_GetVisibleCount (wndPtr, wParam, lParam);
+
+    	case TVM_HITTEST:
+      		return TREEVIEW_HitTest32 (wndPtr, lParam);
+
+    	case TVM_CREATEDRAGIMAGE:
+      		FIXME (treeview, "Unimplemented msg TVM_CREATEDRAGIMAGE\n");
+      		return 0;
+  
+    	case TVM_SORTCHILDREN:
+      		FIXME (treeview, "Unimplemented msg TVM_SORTCHILDREN\n");
+      		return 0;
+  
+    	case TVM_ENSUREVISIBLE:
+      		FIXME (treeview, "Unimplemented msg TVM_ENSUREVISIBLE\n");
+      		return 0;
+  
+    	case TVM_SORTCHILDRENCB:
+      		FIXME (treeview, "Unimplemented msg TVM_SORTCHILDRENCB\n");
+      		return 0;
+  
+    	case TVM_ENDEDITLABELNOW:
+      		FIXME (treeview, "Unimplemented msg TVM_ENDEDITLABELNOW\n");
+      		return 0;
+  
+    	case TVM_GETISEARCHSTRING32A:
+      		FIXME (treeview, "Unimplemented msg TVM_GETISEARCHSTRING32A\n");
+      		return 0;
+  
+    	case TVM_GETISEARCHSTRING32W:
+      		FIXME (treeview, "Unimplemented msg TVM_GETISEARCHSTRING32W\n");
+      		return 0;
+  
+    	case TVM_SETTOOLTIPS:
+      		FIXME (treeview, "Unimplemented msg TVM_SETTOOLTIPS\n");
+      		return 0;
+  
+    	case TVM_GETTOOLTIPS:
+      		FIXME (treeview, "Unimplemented msg TVM_GETTOOLTIPS\n");
+      		return 0;
+  
+    	case TVM_SETINSERTMARK:
+      		FIXME (treeview, "Unimplemented msg TVM_SETINSERTMARK\n");
+      		return 0;
+  
+    	case TVM_SETITEMHEIGHT:
+      		return TREEVIEW_SetItemHeight (wndPtr, wParam);
+  
+    	case TVM_GETITEMHEIGHT:
+      		return TREEVIEW_GetItemHeight (wndPtr);
+  
+    	case TVM_SETBKCOLOR:
+      		FIXME (treeview, "Unimplemented msg TVM_SETBKCOLOR\n");
+      		return 0;
+	
+    	case TVM_SETTEXTCOLOR:
+      		return TREEVIEW_SetTextColor (wndPtr, wParam, lParam);
+  
+    	case TVM_GETBKCOLOR:
+      		FIXME (treeview, "Unimplemented msg TVM_GETBKCOLOR\n");
+      		return 0;
+  
+    	case TVM_GETTEXTCOLOR:
+      		return TREEVIEW_GetTextColor (wndPtr);
+  
+    	case TVM_SETSCROLLTIME:
+      		FIXME (treeview, "Unimplemented msg TVM_SETSCROLLTIME\n");
+      		return 0;
+  
+    	case TVM_GETSCROLLTIME:
+      		FIXME (treeview, "Unimplemented msg TVM_GETSCROLLTIME\n");
+      		return 0;
+  
+    	case TVM_SETINSERTMARKCOLOR:
+      		FIXME (treeview, "Unimplemented msg TVM_SETINSERTMARKCOLOR\n");
+      		return 0;
+  
+    	case TVM_SETUNICODEFORMAT:
+      		FIXME (treeview, "Unimplemented msg TVM_SETUNICODEFORMAT\n");
+      		return 0;
+  
+    	case TVM_GETUNICODEFORMAT:
+      		FIXME (treeview, "Unimplemented msg TVM_GETUNICODEFORMAT\n");
+      		return 0;
+  
+//		case WM_COMMAND:
+  
+		case WM_CREATE:
+			return TREEVIEW_Create (wndPtr, wParam, lParam);
+  
+		case WM_DESTROY:
+			return TREEVIEW_Destroy (wndPtr);
+  
+//		case WM_ENABLE:
+  
+		case WM_ERASEBKGND:
+	    	return TREEVIEW_EraseBackground (wndPtr, wParam, lParam);
+  
+		case WM_GETDLGCODE:
+	    	return DLGC_WANTARROWS | DLGC_WANTCHARS;
+  
+		case WM_PAINT:
+	    	return TREEVIEW_Paint (wndPtr, wParam);
+  
+//		case WM_GETFONT:
+//		case WM_SETFONT:
+  
+		case WM_KEYDOWN:
+			return TREEVIEW_KeyDown (wndPtr, wParam, lParam);
+  
+  
+//		case WM_KILLFOCUS:
+//		case WM_SETFOCUS:
+  
+  
+		case WM_LBUTTONDOWN:
+			return TREEVIEW_LButtonDown (wndPtr, wParam, lParam);
+  
+		case WM_LBUTTONDBLCLK:
+			return TREEVIEW_LButtonDoubleClick (wndPtr, wParam, lParam);
+  
+		case WM_RBUTTONDOWN:
+			return TREEVIEW_RButtonDown (wndPtr, wParam, lParam);
+  
+  
+//		case WM_SYSCOLORCHANGE:
+//		case WM_STYLECHANGED:
+//		case WM_SETREDRAW:
+  
+		case WM_TIMER:
+			return TREEVIEW_HandleTimer (wndPtr, wParam, lParam);
+  
+//		case WM_SIZE:
+		case WM_HSCROLL: 
+			return TREEVIEW_HScroll (wndPtr, wParam, lParam);
+		case WM_VSCROLL: 
+			return TREEVIEW_VScroll (wndPtr, wParam, lParam);
+  
+		default:
+	    	if (uMsg >= WM_USER)
 		FIXME (treeview, "Unknown msg %04x wp=%08x lp=%08lx\n",
-		       uMsg, wParam, lParam);
-	    return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
-    }
+  		     uMsg, wParam, lParam);
+  	    return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
+      }
     return 0;
 }
 
diff --git a/dlls/comctl32/updown.c b/dlls/comctl32/updown.c
index e93b5ef..8ccc64a 100644
--- a/dlls/comctl32/updown.c
+++ b/dlls/comctl32/updown.c
@@ -27,14 +27,12 @@
  */
 
 #include <stdlib.h>
-#include <assert.h>
-#include <string.h>
 #include "windows.h"
+#include "commctrl.h"
 #include "winnls.h"
 #include "sysmetrics.h"
 #include "updown.h"
 #include "graphics.h"
-#include "heap.h"
 #include "win.h"
 #include "debug.h"
 
@@ -249,7 +247,7 @@
     if (!(wndPtr->dwStyle & UDS_NOTHOUSANDS)) {
       char txt2[20], *src = txt1, *dst = txt2;
       if(len%3 > 0){
-	strncpy(dst, src, len%3);
+	lstrcpyn32A (dst, src, len%3);
 	dst += len%3;
 	src += len%3;
       }
@@ -597,9 +595,7 @@
       return TRUE;
 
     case WM_CREATE:
-      infoPtr =
-	(UPDOWN_INFO*)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
-				 sizeof(UPDOWN_INFO));
+      infoPtr = (UPDOWN_INFO*)COMCTL32_Alloc (sizeof(UPDOWN_INFO));
       wndPtr->wExtra[0] = (DWORD)infoPtr;
 
       /* initialize the info struct */
@@ -618,9 +614,9 @@
     
     case WM_DESTROY:
       if(infoPtr->AccelVect)
-	free(infoPtr->AccelVect);
+	COMCTL32_Free (infoPtr->AccelVect);
 
-      HeapFree (GetProcessHeap (), 0, infoPtr);
+      COMCTL32_Free (infoPtr);
       wndPtr->wExtra[0] = 0;
 
       TRACE(updown, "UpDown Ctrl destruction, hwnd=%04x\n", hwnd);
@@ -715,13 +711,13 @@
     case UDM_SETACCEL:
       TRACE(updown, "UpDown Ctrl new accel info, hwnd=%04x\n", hwnd);
       if(infoPtr->AccelVect){
-	free(infoPtr->AccelVect);
+	COMCTL32_Free (infoPtr->AccelVect);
 	infoPtr->AccelCount = 0;
 	infoPtr->AccelVect  = 0;
       }
       if(wParam==0)
 	return TRUE;
-      infoPtr->AccelVect = malloc(wParam*sizeof(UDACCEL));
+      infoPtr->AccelVect = COMCTL32_Alloc (wParam*sizeof(UDACCEL));
       if(infoPtr->AccelVect==0)
 	return FALSE;
       memcpy(infoPtr->AccelVect, (void*)lParam, wParam*sizeof(UDACCEL));
@@ -816,9 +812,9 @@
 
     default: 
       if (message >= WM_USER) 
-	WARN(updown, "unknown msg %04x wp=%04x lp=%08lx\n", 
-		     message, wParam, lParam );
-      return DefWindowProc32A( hwnd, message, wParam, lParam ); 
+	ERR (updown, "unknown msg %04x wp=%04x lp=%08lx\n", 
+	     message, wParam, lParam);
+      return DefWindowProc32A (hwnd, message, wParam, lParam); 
     } 
 
     return 0;
diff --git a/dlls/psapi/Makefile.in b/dlls/psapi/Makefile.in
new file mode 100644
index 0000000..17c618b
--- /dev/null
+++ b/dlls/psapi/Makefile.in
@@ -0,0 +1,16 @@
+DEFS      = @DLLFLAGS@ -D__WINE__
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+MODULE    = psapi
+
+C_SRCS = \
+	psapi_main.c
+
+all: $(MODULE).o
+
+@MAKE_RULES@
+
+### Dependencies:
+
diff --git a/dlls/psapi/psapi_main.c b/dlls/psapi/psapi_main.c
new file mode 100644
index 0000000..94bc7f6
--- /dev/null
+++ b/dlls/psapi/psapi_main.c
@@ -0,0 +1,301 @@
+/*
+ *      PSAPI library
+ *
+ *      Copyright 1998  Patrik Stridvall
+ */
+
+#include "windows.h"
+#include "winbase.h"
+#include "wintypes.h"
+#include "winerror.h"
+#include "debug.h"
+#include "psapi.h"
+
+#include <string.h>
+
+/***********************************************************************
+ *           EmptyWorkingSet (PSAPI.1)
+ */
+BOOL32 WINAPI EmptyWorkingSet32(HANDLE32 hProcess)
+{
+  return SetProcessWorkingSetSize(hProcess, 0xFFFFFFFF, 0xFFFFFFFF);
+}
+
+/***********************************************************************
+ *           EnumDeviceDrivers (PSAPI.2)
+ */
+BOOL32 WINAPI EnumDeviceDrivers(
+  LPVOID *lpImageBase, DWORD cb, LPDWORD lpcbNeeded)
+{
+  FIXME(psapi, "(%p, %ld, %p): stub\n", lpImageBase, cb, lpcbNeeded);
+
+  if(lpcbNeeded)
+    *lpcbNeeded = 0;
+
+  return TRUE;
+}    
+
+
+/***********************************************************************
+ *           EnumProcesses (PSAPI.3)
+ */
+BOOL32 WINAPI EnumProcesses(DWORD *lpidProcess, DWORD cb, DWORD *lpcbNeeded)
+{
+  FIXME(psapi, "(%p, %ld, %p): stub\n", lpidProcess,cb, lpcbNeeded);
+
+  if(lpcbNeeded)
+    *lpcbNeeded = 0;
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *           EnumProcessModules (PSAPI.4)
+ */
+BOOL32 WINAPI EnumProcessModules(
+  HANDLE32 hProcess, HMODULE32 *lphModule, DWORD cb, LPDWORD lpcbNeeded)
+{
+  FIXME(psapi, "(hProcess=0x%08x, %p, %ld, %p): stub\n",
+    hProcess, lphModule, cb, lpcbNeeded
+  );
+
+  if(lpcbNeeded)
+    *lpcbNeeded = 0;
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *          GetDeviceDriverBaseName32A (PSAPI.5)
+ */
+DWORD WINAPI GetDeviceDriverBaseName32A(
+  LPVOID ImageBase, LPSTR lpBaseName, DWORD nSize)
+{
+  FIXME(psapi, "(%p, %s, %ld): stub\n",
+    ImageBase, debugstr_a(lpBaseName), nSize
+  );
+
+  if(lpBaseName && nSize)
+    lpBaseName[0] = '\0';
+
+  return 0;
+}
+
+/***********************************************************************
+ *           GetDeviceDriverBaseName32W (PSAPI.6)
+ */
+DWORD WINAPI GetDeviceDriverBaseName32W(
+  LPVOID ImageBase, LPWSTR lpBaseName, DWORD nSize)
+{
+  FIXME(psapi, "(%p, %s, %ld): stub\n",
+    ImageBase, debugstr_w(lpBaseName), nSize
+  );
+
+  if(lpBaseName && nSize)
+    lpBaseName[0] = '\0';
+
+  return 0;
+}
+
+/***********************************************************************
+ *           GetDeviceDriverFileName32A (PSAPI.7)
+ */
+DWORD WINAPI GetDeviceDriverFileName32A(
+  LPVOID ImageBase, LPSTR lpFilename, DWORD nSize)
+{
+  FIXME(psapi, "(%p, %s, %ld): stub\n",
+    ImageBase, debugstr_a(lpFilename), nSize
+  );
+
+  if(lpFilename && nSize)
+    lpFilename[0] = '\0';
+
+  return 0;
+}
+
+/***********************************************************************
+ *           GetDeviceDriverFileName32W (PSAPI.8)
+ */
+DWORD WINAPI GetDeviceDriverFileName32W(
+  LPVOID ImageBase, LPWSTR lpFilename, DWORD nSize)
+{
+  FIXME(psapi, "(%p, %s, %ld): stub\n",
+    ImageBase, debugstr_w(lpFilename), nSize
+  );
+
+  if(lpFilename && nSize)
+    lpFilename[0] = '\0';
+
+  return 0;
+}
+
+/***********************************************************************
+ *           GetMappedFileName32A (PSAPI.9)
+ */
+DWORD WINAPI GetMappedFileName32A(
+  HANDLE32 hProcess, LPVOID lpv, LPSTR lpFilename, DWORD nSize)
+{
+  FIXME(psapi, "(hProcess=0x%08x, %p, %s, %ld): stub\n",
+    hProcess, lpv, debugstr_a(lpFilename), nSize
+  );
+
+  if(lpFilename && nSize)
+    lpFilename[0] = '\0';
+
+  return 0;
+}
+
+/***********************************************************************
+ *           GetMappedFileName32W (PSAPI.10)
+ */
+DWORD WINAPI GetMappedFileName32W(
+  HANDLE32 hProcess, LPVOID lpv, LPWSTR lpFilename, DWORD nSize)
+{
+  FIXME(psapi, "(hProcess=0x%08x, %p, %s, %ld): stub\n",
+    hProcess, lpv, debugstr_w(lpFilename), nSize
+  );
+
+  if(lpFilename && nSize)
+    lpFilename[0] = '\0';
+
+  return 0;
+}
+
+/***********************************************************************
+ *           GetModuleBaseName32A (PSAPI.11)
+ */
+DWORD WINAPI GetModuleBaseName32A(
+  HANDLE32 hProcess, HMODULE32 hModule, LPSTR lpBaseName, DWORD nSize)
+{
+  FIXME(psapi, "(hProcess=0x%08x, hModule=0x%08x, %s, %ld): stub\n",
+    hProcess, hModule, debugstr_a(lpBaseName), nSize
+  );
+
+  if(lpBaseName && nSize)
+    lpBaseName[0] = '\0';
+
+  return 0;
+}
+
+/***********************************************************************
+ *           GetModuleBaseName32W (PSAPI.12)
+ */
+DWORD WINAPI GetModuleBaseName32W(
+  HANDLE32 hProcess, HMODULE32 hModule, LPWSTR lpBaseName, DWORD nSize)
+{
+  FIXME(psapi, "(hProcess=0x%08x, hModule=0x%08x, %s, %ld): stub\n",
+    hProcess, hModule, debugstr_w(lpBaseName), nSize);
+
+  if(lpBaseName && nSize)
+    lpBaseName[0] = '\0';
+
+  return 0;
+}
+
+/***********************************************************************
+ *           GetModuleFileNameEx32A (PSAPI.13)
+ */
+DWORD WINAPI GetModuleFileNameEx32A(
+  HANDLE32 hProcess, HMODULE32 hModule, LPSTR lpFilename, DWORD nSize)
+{
+  FIXME(psapi, "(hProcess=0x%08x,hModule=0x%08x, %s, %ld): stub\n",
+    hProcess, hModule, debugstr_a(lpFilename), nSize
+  );
+
+  if(lpFilename&&nSize)
+    lpFilename[0]='\0';
+
+  return 0;
+}
+
+/***********************************************************************
+ *           GetModuleFileNameEx32W (PSAPI.14)
+ */
+DWORD WINAPI GetModuleFileNameEx32W(
+  HANDLE32 hProcess, HMODULE32 hModule, LPWSTR lpFilename, DWORD nSize)
+{
+  FIXME(psapi, "(hProcess=0x%08x,hModule=0x%08x, %s, %ld): stub\n",
+    hProcess, hModule, debugstr_w(lpFilename), nSize
+  );
+
+  if(lpFilename && nSize)
+    lpFilename[0] = '\0';
+
+  return 0;
+}
+
+/***********************************************************************
+ *           GetModuleInformation32 (PSAPI.15)
+ */
+BOOL32 WINAPI GetModuleInformation32(
+  HANDLE32 hProcess, HMODULE32 hModule, LPMODULEINFO32 lpmodinfo, DWORD cb)
+{
+  FIXME(psapi, "(hProcess=0x%08x, hModule=0x%08x, %p, %ld): stub\n",
+    hProcess, hModule, lpmodinfo, cb
+  );
+
+  memset(lpmodinfo, 0, cb);
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *           GetProcessMemoryInfo32 (PSAPI.16)
+ */
+BOOL32 WINAPI GetProcessMemoryInfo32(
+  HANDLE32 Process, PPROCESS_MEMORY_COUNTERS32 ppsmemCounters, DWORD cb)
+{
+  FIXME(psapi, "(hProcess=0x%08x, %p, %ld): stub\n",
+    Process, ppsmemCounters, cb
+  );
+
+  memset(ppsmemCounters, 0, cb);
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *           GetWsChanges32 (PSAPI.17)
+ */
+BOOL32 WINAPI GetWsChanges32(
+  HANDLE32 hProcess, PPSAPI_WS_WATCH_INFORMATION32 lpWatchInfo, DWORD cb)
+{
+  FIXME(psapi, "(hProcess=0x%08x, %p, %ld): stub\n",
+    hProcess, lpWatchInfo, cb
+  );
+
+  memset(lpWatchInfo, 0, cb);
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *           InitializeProcessForWsWatch32 (PSAPI.18)
+ */
+BOOL32 WINAPI InitializeProcessForWsWatch32(HANDLE32 hProcess)
+{
+  FIXME(psapi, "(hProcess=0x%08x): stub\n", hProcess);
+
+  return TRUE;
+}
+
+/***********************************************************************
+ *           QueryWorkingSet32 (PSAPI.?)
+ * FIXME
+ *     I haven't been able to find the ordinal for this function,
+ *     This means it can't be called from outside the DLL.
+ */
+BOOL32 WINAPI QueryWorkingSet32(HANDLE32 hProcess, LPVOID pv, DWORD cb)
+{
+  FIXME(psapi, "(hProcess=0x%08x, %p, %ld)", hProcess, pv, cb);
+
+  if(pv && cb)
+    ((DWORD *) pv)[0] = 0; /* Empty WorkingSet */
+
+  return TRUE;
+}
+
+
+
+
+
diff --git a/dlls/shell32/Makefile.in b/dlls/shell32/Makefile.in
index 2a7f204..6a58119 100644
--- a/dlls/shell32/Makefile.in
+++ b/dlls/shell32/Makefile.in
@@ -8,6 +8,7 @@
 
 C_SRCS = \
 	contmenu.c \
+	dataobject.c \
 	enumidlist.c \
 	folders.c \
 	pidl.c \
diff --git a/dlls/shell32/contmenu.c b/dlls/shell32/contmenu.c
index 9aa758c..9bca626 100644
--- a/dlls/shell32/contmenu.c
+++ b/dlls/shell32/contmenu.c
@@ -10,11 +10,6 @@
 #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
@@ -132,8 +127,26 @@
 	TRACE(shell,"(%p)->()\n",cm);
 	return cm;
 }
+/**************************************************************************
+*  ICM_InsertItem()
+*/ 
+static void ICM_InsertItem (HMENU32 hmenu, UINT32 indexMenu, UINT32 wID, UINT32 fType, LPSTR dwTypeData, UINT32 fState)
+{	MENUITEMINFO32A	mii;
 
-
+	ZeroMemory(&mii, sizeof(mii));
+	mii.cbSize = sizeof(mii);
+	if (fType == MFT_SEPARATOR)
+	{ mii.fMask = MIIM_ID | MIIM_TYPE;
+	}
+	else
+	{ mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
+	  mii.dwTypeData = dwTypeData;
+	  mii.fState = MFS_ENABLED | MFS_DEFAULT;
+	}
+	mii.wID = wID;
+	mii.fType = fType;
+	InsertMenuItem32A( hmenu, indexMenu, TRUE, &mii);
+}
 /**************************************************************************
 * IContextMenu_QueryContextMenu()
 */
@@ -141,71 +154,28 @@
 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);
+	  { fExplore = uFlags & CMF_EXPLORE;
+	    if(fExplore)
+	    { ICM_InsertItem(hmenu, indexMenu++, idCmdFirst+IDM_EXPLORE, MFT_STRING, TEXT("&Explore"), MFS_ENABLED|MFS_DEFAULT);
+	      ICM_InsertItem(hmenu, indexMenu++, idCmdFirst+IDM_OPEN, MFT_STRING, TEXT("&Open"), MFS_ENABLED);
+	    }
+	    else
+            { ICM_InsertItem(hmenu, indexMenu++, idCmdFirst+IDM_OPEN, MFT_STRING, TEXT("&Open"), MFS_ENABLED|MFS_DEFAULT);
+	      ICM_InsertItem(hmenu, indexMenu++, idCmdFirst+IDM_EXPLORE, MFT_STRING, TEXT("&Explore"), MFS_ENABLED);
+            }
 
-          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));
-    }
+            if(uFlags & CMF_CANRENAME)
+            { ICM_InsertItem(hmenu, indexMenu++, 0, MFT_SEPARATOR, NULL, 0);
+	      ICM_InsertItem(hmenu, indexMenu++, idCmdFirst+IDM_RENAME, MFT_STRING, TEXT("&Rename"), (IContextMenu_CanRenameItems(this) ? MFS_ENABLED : MFS_DISABLED));
+	    }
+	  }
+	  return MAKE_HRESULT(SEVERITY_SUCCESS, 0, (IDM_LAST + 1));
+	}
 	return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 0);
 }
 
@@ -230,41 +200,41 @@
 	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.*/
+            /* 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 folder item in the list.*/
 
-        for(i = 0; this->aPidls[i]; i++)
+	    for(i = 0; this->aPidls[i]; i++)
 	    { if(!_ILIsValue(this->aPidls[i]))
-            break;
-        }
+                break;
+	    }
       
-		pidlTemp = ILCombine(this->pSFParent->mpidl, this->aPidls[i]);
-		pidlFQ = ILCombine(this->pSFParent->mpidlNSRoot, pidlTemp);
-		SHFree(pidlTemp);
+	    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;
+	    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)
+	    if(LOWORD(lpcmi->lpVerb) == IDM_EXPLORE)
 	    { sei.lpVerb = TEXT("explore");
-        }
-		else
-        { sei.lpVerb = TEXT("open");
-        }
-        ShellExecuteEx32A(&sei);
-		SHFree(pidlFQ);
-        break;
-
+	    }
+	    else
+	    { sei.lpVerb = TEXT("open");
+	    }
+	    ShellExecuteEx32A(&sei);
+	    SHFree(pidlFQ);
+	    break;
+		
 	  case IDM_RENAME:
-        MessageBeep32(MB_OK);
-        /*handle rename for the view here*/
-        break;
-   	}
+	    MessageBeep32(MB_OK);
+	    /*handle rename for the view here*/
+	    break;
+	}
 	return NOERROR;
 }
 
@@ -361,9 +331,9 @@
 	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;
+	  { this->aPidls[i] = ILClone(aPidls[i]);
+	  }
+	  return TRUE;
  	}
 	return FALSE;
 }
diff --git a/dlls/shell32/dataobject.c b/dlls/shell32/dataobject.c
new file mode 100644
index 0000000..f9f790f
--- /dev/null
+++ b/dlls/shell32/dataobject.c
@@ -0,0 +1,259 @@
+/*
+ *	IEnumFORMATETC, IDataObject
+ *
+ * selecting and droping objects within the shell and/or common dialogs
+ *
+ *	Copyright 1998	<juergen.schmied@metronet.de>
+ */
+#include "debug.h"
+#include "shlobj.h"
+#include "winerror.h"
+#include "shell32_main.h"
+/***********************************************************************
+*   IEnumFORMATETC implementation
+*/
+static HRESULT WINAPI IEnumFORMATETC_QueryInterface (LPENUMFORMATETC this, REFIID riid, LPVOID * ppvObj);
+static ULONG WINAPI IEnumFORMATETC_AddRef (LPENUMFORMATETC this);
+static ULONG WINAPI IEnumFORMATETC_Release (LPENUMFORMATETC this);
+static HRESULT WINAPI IEnumFORMATETC_Next(LPENUMFORMATETC this, ULONG celt, FORMATETC32 *rgelt, ULONG *pceltFethed);
+static HRESULT WINAPI IEnumFORMATETC_Skip(LPENUMFORMATETC this, ULONG celt);
+static HRESULT WINAPI IEnumFORMATETC_Reset(LPENUMFORMATETC this);
+static HRESULT WINAPI IEnumFORMATETC_Clone(LPENUMFORMATETC this, LPENUMFORMATETC* ppenum);
+
+static struct IEnumFORMATETC_VTable efvt = 
+{	IEnumFORMATETC_QueryInterface,
+	IEnumFORMATETC_AddRef,
+	IEnumFORMATETC_Release,
+	IEnumFORMATETC_Next,
+	IEnumFORMATETC_Skip,
+	IEnumFORMATETC_Reset,
+	IEnumFORMATETC_Clone
+};
+
+extern LPENUMFORMATETC IEnumFORMATETC_Constructor(UINT32 cfmt, const FORMATETC32 afmt[])
+{	LPENUMFORMATETC ef;
+	DWORD size=cfmt * sizeof(FORMATETC32);
+	
+	ef=(LPENUMFORMATETC)HeapAlloc(GetProcessHeap(),0,sizeof(IEnumFORMATETC));
+	ef->ref=1;
+	ef->lpvtbl=&efvt;
+
+	ef->posFmt = 0;
+	ef->countFmt = cfmt;
+	ef->pFmt = SHAlloc (size);
+
+	if (ef->pFmt)
+	{ memcpy(ef->pFmt, afmt, size);
+	}
+
+	TRACE(shell,"(%p)->()\n",ef);
+	return ef;
+}
+static HRESULT WINAPI IEnumFORMATETC_QueryInterface (LPENUMFORMATETC 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))
+	{ *ppvObj = this; 
+	}
+	else if(IsEqualIID(riid, &IID_IEnumFORMATETC))
+	{ *ppvObj = (IDataObject*)this;
+	}   
+
+	if(*ppvObj)
+	{ (*(LPENUMFORMATETC*)ppvObj)->lpvtbl->fnAddRef(this);      
+	  TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
+	  return S_OK;
+	}
+	TRACE(shell,"-- Interface: E_NOINTERFACE\n");
+	return E_NOINTERFACE;
+
+}
+static ULONG WINAPI IEnumFORMATETC_AddRef (LPENUMFORMATETC this)
+{	TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
+	return ++(this->ref);
+}
+static ULONG WINAPI IEnumFORMATETC_Release (LPENUMFORMATETC this)
+{	TRACE(shell,"(%p)->()\n",this);
+	if (!--(this->ref)) 
+	{ TRACE(shell," destroying IEnumFORMATETC(%p)\n",this);
+	  if (this->pFmt)
+	  { SHFree (this->pFmt);
+	  }
+	  HeapFree(GetProcessHeap(),0,this);
+	  return 0;
+	}
+	return this->ref;
+}
+static HRESULT WINAPI IEnumFORMATETC_Next(LPENUMFORMATETC this, ULONG celt, FORMATETC32 *rgelt, ULONG *pceltFethed)
+{	UINT32 cfetch;
+	HRESULT hres = S_FALSE;
+
+	TRACE (shell, "(%p)->()\n", this);
+
+        if (this->posFmt < this->countFmt)
+        { cfetch = this->countFmt - this->posFmt;
+	  if (cfetch >= celt)
+	  { cfetch = celt;
+	    hres = S_OK;
+	  }
+	  memcpy(rgelt, &this->pFmt[this->posFmt], cfetch * sizeof(FORMATETC32));
+	  this->posFmt += cfetch;
+	}
+	else
+	{ cfetch = 0;
+        }
+
+        if (pceltFethed)
+        { *pceltFethed = cfetch;
+        }
+
+        return hres;
+}
+static HRESULT WINAPI IEnumFORMATETC_Skip(LPENUMFORMATETC this, ULONG celt)
+{	FIXME (shell, "(%p)->(num=%lu)\n", this, celt);
+
+	this->posFmt += celt;
+	if (this->posFmt > this->countFmt)
+        { this->posFmt = this->countFmt;
+	  return S_FALSE;
+	}
+	return S_OK;
+}
+static HRESULT WINAPI IEnumFORMATETC_Reset(LPENUMFORMATETC this)
+{	FIXME (shell, "(%p)->()\n", this);
+
+        this->posFmt = 0;
+        return S_OK;
+}
+static HRESULT WINAPI IEnumFORMATETC_Clone(LPENUMFORMATETC this, LPENUMFORMATETC* ppenum)
+{	FIXME (shell, "(%p)->(ppenum=%p)\n", this, ppenum);
+	return E_NOTIMPL;
+}
+
+/***********************************************************************
+*   IDataObject implementation
+*/
+
+static HRESULT WINAPI IDataObject_QueryInterface (LPDATAOBJECT, REFIID riid, LPVOID * ppvObj);
+static ULONG WINAPI IDataObject_AddRef (LPDATAOBJECT);
+static ULONG WINAPI IDataObject_Release (LPDATAOBJECT);
+static HRESULT WINAPI IDataObject_GetData (LPDATAOBJECT, LPFORMATETC32 pformatetcIn, STGMEDIUM32 *pmedium);
+static HRESULT WINAPI IDataObject_GetDataHere(LPDATAOBJECT, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium);
+static HRESULT WINAPI IDataObject_QueryGetData(LPDATAOBJECT, LPFORMATETC32 pformatetc);
+static HRESULT WINAPI IDataObject_GetCanonicalFormatEtc(LPDATAOBJECT, LPFORMATETC32 pformatectIn, LPFORMATETC32 pformatetcOut);
+static HRESULT WINAPI IDataObject_SetData(LPDATAOBJECT, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium, BOOL32 fRelease);
+static HRESULT WINAPI IDataObject_EnumFormatEtc(LPDATAOBJECT, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc);
+static HRESULT WINAPI IDataObject_DAdvise (LPDATAOBJECT, LPFORMATETC32 *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
+static HRESULT WINAPI IDataObject_DUnadvise(LPDATAOBJECT, DWORD dwConnection);
+static HRESULT WINAPI IDataObject_EnumDAdvise(LPDATAOBJECT, IEnumSTATDATA **ppenumAdvise);
+
+static struct IDataObject_VTable dtovt = 
+{	IDataObject_QueryInterface,
+	IDataObject_AddRef,
+	IDataObject_Release,
+	IDataObject_GetData,
+	IDataObject_GetDataHere,
+	IDataObject_QueryGetData,
+	IDataObject_GetCanonicalFormatEtc,
+	IDataObject_SetData,
+	IDataObject_EnumFormatEtc,
+	IDataObject_DAdvise,
+	IDataObject_DUnadvise,
+	IDataObject_EnumDAdvise
+};
+
+/**************************************************************************
+*  IDataObject_Constructor
+*/
+LPDATAOBJECT IDataObject_Constructor(HWND32 hwndOwner, LPSHELLFOLDER pcf, LPITEMIDLIST * apit, UINT32 cpit)
+{	LPDATAOBJECT dto;
+	dto=(LPDATAOBJECT)HeapAlloc(GetProcessHeap(),0,sizeof(IDataObject));
+	dto->ref=1;
+	dto->lpvtbl=&dtovt;
+	TRACE(shell,"(%p)->()\n",dto);
+	return dto;
+}
+/***************************************************************************
+*  IDataObject_QueryInterface
+*/
+static HRESULT WINAPI IDataObject_QueryInterface (LPDATAOBJECT 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_IDataObject))  /*IDataObject*/
+	{ *ppvObj = (IDataObject*)this;
+	}   
+
+	if(*ppvObj)
+	{ (*(LPDATAOBJECT*)ppvObj)->lpvtbl->fnAddRef(this);      
+	  TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
+	  return S_OK;
+	}
+	TRACE(shell,"-- Interface: E_NOINTERFACE\n");
+	return E_NOINTERFACE;
+}   
+/**************************************************************************
+*  IDataObject_AddRef
+*/
+static ULONG WINAPI IDataObject_AddRef(LPDATAOBJECT this)
+{	TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
+	return ++(this->ref);
+}
+/**************************************************************************
+*  IDataObject_Release
+*/
+static ULONG WINAPI IDataObject_Release(LPDATAOBJECT this)
+{	TRACE(shell,"(%p)->()\n",this);
+	if (!--(this->ref)) 
+	{ TRACE(shell," destroying IDataObject(%p)\n",this);
+	  HeapFree(GetProcessHeap(),0,this);
+	  return 0;
+	}
+	return this->ref;
+}
+static HRESULT WINAPI IDataObject_GetData (LPDATAOBJECT this, LPFORMATETC32 pformatetcIn, STGMEDIUM32 *pmedium)
+{	FIXME (shell, "(%p)->()\n", this);
+	return E_NOTIMPL;
+}
+static HRESULT WINAPI IDataObject_GetDataHere(LPDATAOBJECT this, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium)
+{	FIXME (shell, "(%p)->()\n", this);
+	return E_NOTIMPL;
+}
+static HRESULT WINAPI IDataObject_QueryGetData(LPDATAOBJECT this, LPFORMATETC32 pformatetc)
+{	FIXME (shell, "(%p)->()\n", this);
+	return E_NOTIMPL;
+}
+static HRESULT WINAPI IDataObject_GetCanonicalFormatEtc(LPDATAOBJECT this, LPFORMATETC32 pformatectIn, LPFORMATETC32 pformatetcOut)
+{	FIXME (shell, "(%p)->()\n", this);
+	return E_NOTIMPL;
+}
+static HRESULT WINAPI IDataObject_SetData(LPDATAOBJECT this, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium, BOOL32 fRelease)
+{	FIXME (shell, "(%p)->()\n", this);
+	return E_NOTIMPL;
+}
+static HRESULT WINAPI IDataObject_EnumFormatEtc(LPDATAOBJECT this, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc)
+{	FIXME (shell, "(%p)->()\n", this);
+	return E_NOTIMPL;
+}
+static HRESULT WINAPI IDataObject_DAdvise (LPDATAOBJECT this, LPFORMATETC32 *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
+{	FIXME (shell, "(%p)->()\n", this);
+	return E_NOTIMPL;
+}
+static HRESULT WINAPI IDataObject_DUnadvise(LPDATAOBJECT this, DWORD dwConnection)
+{	FIXME (shell, "(%p)->()\n", this);
+	return E_NOTIMPL;
+}
+static HRESULT WINAPI IDataObject_EnumDAdvise(LPDATAOBJECT this, IEnumSTATDATA **ppenumAdvise)
+{	FIXME (shell, "(%p)->()\n", this);
+	return E_NOTIMPL;
+}
diff --git a/dlls/shell32/enumidlist.c b/dlls/shell32/enumidlist.c
index 960d6ac..365be32 100644
--- a/dlls/shell32/enumidlist.c
+++ b/dlls/shell32/enumidlist.c
@@ -53,24 +53,26 @@
  *  IEnumIDList_Constructor
  */
 
-LPENUMIDLIST IEnumIDList_Constructor( LPCSTR lpszPath, DWORD dwFlags, HRESULT* pResult)
+LPENUMIDLIST IEnumIDList_Constructor( LPCSTR lpszPath, DWORD dwFlags)
 {	LPENUMIDLIST	lpeidl;
 
 	lpeidl = (LPENUMIDLIST)HeapAlloc(GetProcessHeap(),0,sizeof(IEnumIDList));
+	if (! lpeidl)
+	  return NULL;
+
 	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);
+	TRACE(shell,"(%p)->(%s flags=0x%08lx)\n",lpeidl,debugstr_a(lpszPath),dwFlags);
 
 	if(!IEnumIDList_CreateEnumList(lpeidl, lpszPath, dwFlags))
-	{ if(pResult)
-	  { *pResult = E_OUTOFMEMORY;
-	    HeapFree(GetProcessHeap(),0,lpeidl);
-	    return NULL;
+	{ if (lpeidl)
+	  { HeapFree(GetProcessHeap(),0,lpeidl);
 	  }
+	  return NULL;	  
 	}
 
 	TRACE(shell,"-- (%p)->()\n",lpeidl);
@@ -214,7 +216,7 @@
 	CHAR  szDriveName[4];
 	CHAR  szPath[MAX_PATH];
     
-	TRACE(shell,"(%p)->(%s 0x%08lx) \n",this,debugstr_a(lpszPath),dwFlags);
+	TRACE(shell,"(%p)->(path=%s flags=0x%08lx) \n",this,debugstr_a(lpszPath),dwFlags);
 
 	if (lpszPath && lpszPath[0]!='\0')
 	{ strcpy(szPath, lpszPath);
diff --git a/dlls/shell32/folders.c b/dlls/shell32/folders.c
index 75374f9..4373a3a 100644
--- a/dlls/shell32/folders.c
+++ b/dlls/shell32/folders.c
@@ -22,6 +22,7 @@
 #include "winnls.h"
 #include "winproc.h"
 #include "commctrl.h"
+#include "pidl.h"
 
 #include "shell32_main.h"
 
@@ -42,6 +43,24 @@
 static HRESULT WINAPI IShellLink_QueryInterface(LPSHELLLINK,REFIID,LPVOID*);
 static ULONG WINAPI IShellLink_AddRef(LPSHELLLINK);
 static ULONG WINAPI IShellLink_Release(LPSHELLLINK);
+static HRESULT WINAPI IShellLink_GetPath(LPSHELLLINK, LPSTR,INT32, WIN32_FIND_DATA32A *, DWORD);
+static HRESULT WINAPI IShellLink_GetIDList(LPSHELLLINK, LPITEMIDLIST *);
+static HRESULT WINAPI IShellLink_SetIDList(LPSHELLLINK, LPCITEMIDLIST);
+static HRESULT WINAPI IShellLink_GetDescription(LPSHELLLINK, LPSTR,INT32);
+static HRESULT WINAPI IShellLink_SetDescription(LPSHELLLINK, LPCSTR);
+static HRESULT WINAPI IShellLink_GetWorkingDirectory(LPSHELLLINK, LPSTR,INT32);
+static HRESULT WINAPI IShellLink_SetWorkingDirectory(LPSHELLLINK, LPCSTR);
+static HRESULT WINAPI IShellLink_GetArguments(LPSHELLLINK, LPSTR,INT32);
+static HRESULT WINAPI IShellLink_SetArguments(LPSHELLLINK, LPCSTR);
+static HRESULT WINAPI IShellLink_GetHotkey(LPSHELLLINK, WORD *);
+static HRESULT WINAPI IShellLink_SetHotkey(LPSHELLLINK, WORD);
+static HRESULT WINAPI IShellLink_GetShowCmd(LPSHELLLINK, INT32 *);
+static HRESULT WINAPI IShellLink_SetShowCmd(LPSHELLLINK, INT32);
+static HRESULT WINAPI IShellLink_GetIconLocation(LPSHELLLINK, LPSTR,INT32,INT32 *);
+static HRESULT WINAPI IShellLink_SetIconLocation(LPSHELLLINK, LPCSTR,INT32);
+static HRESULT WINAPI IShellLink_SetRelativePath(LPSHELLLINK, LPCSTR, DWORD);
+static HRESULT WINAPI IShellLink_Resolve(LPSHELLLINK, HWND32, DWORD);
+static HRESULT WINAPI IShellLink_SetPath(LPSHELLLINK, LPCSTR);
 
 
 /***********************************************************************
@@ -144,28 +163,28 @@
 * 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
+static struct IShellLink_VTable slvt = 
+{	IShellLink_QueryInterface,
+	IShellLink_AddRef,
+	IShellLink_Release,
+	IShellLink_GetPath,
+	IShellLink_GetIDList,
+	IShellLink_SetIDList,
+	IShellLink_GetDescription,
+	IShellLink_SetDescription,
+	IShellLink_GetWorkingDirectory,
+	IShellLink_SetWorkingDirectory,
+	IShellLink_GetArguments,
+	IShellLink_SetArguments,
+	IShellLink_GetHotkey,
+	IShellLink_SetHotkey,
+	IShellLink_GetShowCmd,
+	IShellLink_SetShowCmd,
+	IShellLink_GetIconLocation,
+	IShellLink_SetIconLocation,
+	IShellLink_SetRelativePath,
+	IShellLink_Resolve,
+	IShellLink_SetPath
 };
 
 /**************************************************************************
@@ -227,4 +246,85 @@
   return this->ref;
 }
 
+static HRESULT WINAPI IShellLink_GetPath(LPSHELLLINK this, LPSTR pszFile,INT32 cchMaxPath, WIN32_FIND_DATA32A *pfd, DWORD fFlags)
+{	FIXME(shell,"(%p)->(pfile=%p len=%u find_data=%p flags=%lu)\n",this, pszFile, cchMaxPath, pfd, fFlags);
+	strncpy(pszFile,"c:\\foo.bar", cchMaxPath);
+	return NOERROR;
+}
+static HRESULT WINAPI IShellLink_GetIDList(LPSHELLLINK this, LPITEMIDLIST * ppidl)
+{	FIXME(shell,"(%p)->(ppidl=%p)\n",this, ppidl);
+	*ppidl = _ILCreateDesktop();
+	return NOERROR;
+}
+static HRESULT WINAPI IShellLink_SetIDList(LPSHELLLINK this, LPCITEMIDLIST pidl)
+{	FIXME(shell,"(%p)->(pidl=%p)\n",this, pidl);
+	return NOERROR;
+}
+static HRESULT WINAPI IShellLink_GetDescription(LPSHELLLINK this, LPSTR pszName,INT32 cchMaxName)
+{	FIXME(shell,"(%p)->(%p len=%u)\n",this, pszName, cchMaxName);
+	strncpy(pszName,"Description, FIXME",cchMaxName);
+	return NOERROR;
+}
+static HRESULT WINAPI IShellLink_SetDescription(LPSHELLLINK this, LPCSTR pszName)
+{	FIXME(shell,"(%p)->(desc=%s)\n",this, pszName);
+	return NOERROR;
+}
+static HRESULT WINAPI IShellLink_GetWorkingDirectory(LPSHELLLINK this, LPSTR pszDir,INT32 cchMaxPath)
+{	FIXME(shell,"(%p)->()\n",this);
+	strncpy(pszDir,"c:\\", cchMaxPath);
+	return NOERROR;
+}
+static HRESULT WINAPI IShellLink_SetWorkingDirectory(LPSHELLLINK this, LPCSTR pszDir)
+{	FIXME(shell,"(%p)->(dir=%s)\n",this, pszDir);
+	return NOERROR;
+}
+static HRESULT WINAPI IShellLink_GetArguments(LPSHELLLINK this, LPSTR pszArgs,INT32 cchMaxPath)
+{	FIXME(shell,"(%p)->(%p len=%u)\n",this, pszArgs, cchMaxPath);
+	strncpy(pszArgs, "", cchMaxPath);
+	return NOERROR;
+}
+static HRESULT WINAPI IShellLink_SetArguments(LPSHELLLINK this, LPCSTR pszArgs)
+{	FIXME(shell,"(%p)->(args=%s)\n",this, pszArgs);
+	return NOERROR;
+}
+static HRESULT WINAPI IShellLink_GetHotkey(LPSHELLLINK this, WORD *pwHotkey)
+{	FIXME(shell,"(%p)->(%p)\n",this, pwHotkey);
+	*pwHotkey=0x0;
+	return NOERROR;
+}
+static HRESULT WINAPI IShellLink_SetHotkey(LPSHELLLINK this, WORD wHotkey)
+{	FIXME(shell,"(%p)->(hotkey=%x)\n",this, wHotkey);
+	return NOERROR;
+}
+static HRESULT WINAPI IShellLink_GetShowCmd(LPSHELLLINK this, INT32 *piShowCmd)
+{	FIXME(shell,"(%p)->(%p)\n",this, piShowCmd);
+	*piShowCmd=0;
+	return NOERROR;
+}
+static HRESULT WINAPI IShellLink_SetShowCmd(LPSHELLLINK this, INT32 iShowCmd)
+{	FIXME(shell,"(%p)->(showcmd=%x)\n",this, iShowCmd);
+	return NOERROR;
+}
+static HRESULT WINAPI IShellLink_GetIconLocation(LPSHELLLINK this, LPSTR pszIconPath,INT32 cchIconPath,INT32 *piIcon)
+{	FIXME(shell,"(%p)->(%p len=%u iicon=%p)\n",this, pszIconPath, cchIconPath, piIcon);
+	strncpy(pszIconPath,"shell32.dll",cchIconPath);
+	*piIcon=1;
+	return NOERROR;
+}
+static HRESULT WINAPI IShellLink_SetIconLocation(LPSHELLLINK this, LPCSTR pszIconPath,INT32 iIcon)
+{	FIXME(shell,"(%p)->(path=%s iicon=%u)\n",this, pszIconPath, iIcon);
+	return NOERROR;
+}
+static HRESULT WINAPI IShellLink_SetRelativePath(LPSHELLLINK this, LPCSTR pszPathRel, DWORD dwReserved)
+{	FIXME(shell,"(%p)->(path=%s %lx)\n",this, pszPathRel, dwReserved);
+	return NOERROR;
+}
+static HRESULT WINAPI IShellLink_Resolve(LPSHELLLINK this, HWND32 hwnd, DWORD fFlags)
+{	FIXME(shell,"(%p)->(hwnd=%x flags=%lx)\n",this, hwnd, fFlags);
+	return NOERROR;
+}
+static HRESULT WINAPI IShellLink_SetPath(LPSHELLLINK this, LPCSTR pszFile)
+{	FIXME(shell,"(%p)->(path=%s)\n",this, pszFile);
+	return NOERROR;
+}
 
diff --git a/dlls/shell32/pidl.c b/dlls/shell32/pidl.c
index caed624..67ccd94 100644
--- a/dlls/shell32/pidl.c
+++ b/dlls/shell32/pidl.c
@@ -3,8 +3,9 @@
  *
  *	Copyright 1998	Juergen Schmied
  *
- *  !!! currently work in progress on all classes !!!
- *  <contact juergen.schmied@metronet.de, 980801>
+ * NOTES
+ *  a pidl == NULL means desktop and is legal
+ *
  */
 
 #include <ctype.h>
@@ -29,15 +30,24 @@
 {	DWORD type;
 	CHAR * szData;
 	LPITEMIDLIST pidltemp = pidl;
-	TRACE(pidl,"---------- pidl=%p \n", pidl);
-	do
-	{ type   = _ILGetDataPointer(pidltemp)->type;
-	  szData = _ILGetTextPointer(type, _ILGetDataPointer(pidltemp));
+	if (! pidltemp)
+	{ TRACE(pidl,"-------- pidl = NULL (Root)\n");
+	  return;
+	}
+	TRACE(pidl,"-------- pidl=%p \n", pidl);
+	if (pidltemp->mkid.cb)
+	{ do
+	  { type   = _ILGetDataPointer(pidltemp)->type;
+	    szData = _ILGetTextPointer(type, _ILGetDataPointer(pidltemp));
 
-	  TRACE(pidl,"---- pidl=%p size=%u type=%lx %s\n",pidltemp, pidltemp->mkid.cb,type,debugstr_a(szData));
+	    TRACE(pidl,"---- pidl=%p size=%u type=%lx %s\n",pidltemp, pidltemp->mkid.cb,type,debugstr_a(szData));
 
-	  pidltemp = ILGetNext(pidltemp);
-	} while (pidltemp->mkid.cb);
+	    pidltemp = ILGetNext(pidltemp);
+	  } while (pidltemp->mkid.cb);
+	  return;
+	}
+	else
+	  TRACE(pidl,"empty pidl (Desktop)\n");	
 }
 /*************************************************************************
  * ILGetDisplayName			[SHELL32.15]
@@ -88,6 +98,8 @@
 
   TRACE(pidl,"%p\n",pidl);
 
+  pdump(pidl);
+
   if (!pidl)
     return NULL;
     
@@ -104,8 +116,40 @@
  *  duplicates the first idlist of a complex pidl
  */
 LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST pidl)
-{ FIXME(pidl,"pidl=%p\n",pidl);
-  return NULL;
+{	DWORD len;
+	LPITEMIDLIST newpidl=NULL;
+	TRACE(pidl,"pidl=%p\n",pidl);
+	
+	if (pidl)
+	{ len = pidl->mkid.cb;	
+	  newpidl = (LPITEMIDLIST) SHAlloc (len+2);
+	  if (newpidl)
+	  { memcpy(newpidl,pidl,len);
+   	    ILGetNext(newpidl)->mkid.cb = 0x00;
+	  }
+	 }
+
+  	return newpidl;
+}
+/*************************************************************************
+ * ILIsEqual [SHELL32.21]
+ *
+ */
+BOOL32 WINAPI ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
+{	FIXME(pidl,"pidl1=%p pidl2=%p stub\n",pidl1, pidl2);
+	pdump (pidl1);
+	pdump (pidl2);
+	return FALSE;
+}
+/*************************************************************************
+ * ILFindChild [SHELL32.24]
+ *
+ */
+DWORD WINAPI ILFindChild(LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2)
+{	FIXME(pidl,"%p %p stub\n",pidl1,pidl2);
+	pdump (pidl1);
+	pdump (pidl2);
+	return 0;
 }
 
 /*************************************************************************
@@ -125,6 +169,9 @@
   if(!pidl1 && !pidl2)
   {  return NULL;
   }
+
+  pdump (pidl1);
+  pdump (pidl2);
  
   if(!pidl1)
   { pidlNew = ILClone(pidl2);
@@ -149,6 +196,18 @@
   return pidlNew;
 }
 /*************************************************************************
+ *  SHLogILFromFSIL [SHELL32.95]
+ *
+ * NOTES
+ *  might be the prepending of MyComputer to a filesystem pidl (?)
+ */
+LPITEMIDLIST WINAPI SHLogILFromFSIL(LPITEMIDLIST pidl)
+{	FIXME(pidl,"(pidl=%p)\n",pidl);
+	pdump(pidl);
+	return ILClone(pidl);
+}
+
+/*************************************************************************
  * ILGetSize [SHELL32.152]
  *  gets the byte size of an idlist including zero terminator (pidl)
  *
@@ -162,19 +221,19 @@
  *  exported by ordinal
  */
 DWORD WINAPI ILGetSize(LPITEMIDLIST pidl)
-{ LPSHITEMID si = &(pidl->mkid);
-  DWORD  len=0;
+{	LPSHITEMID si = &(pidl->mkid);
+	DWORD  len=0;
 
-  TRACE(pidl,"pidl=%p\n",pidl);
+	/*TRACE(pidl,"pidl=%p\n",pidl);*/
 
-  if (pidl)
-  { while (si->cb) 
-    { len += si->cb;
-      si  = (LPSHITEMID)(((LPBYTE)si)+si->cb);
-    }
-    len += 2;
+	if (pidl)
+	{ while (si->cb) 
+	  { len += si->cb;
+	    si  = (LPSHITEMID)(((LPBYTE)si)+si->cb);
+	  }
+	  len += 2;
 	}
-/*  TRACE(pidl,"-- size=%lu\n",len);*/
+	/*TRACE(pidl,"-- size=%lu\n",len);*/
 	return len;
 }
 /*************************************************************************
@@ -191,7 +250,7 @@
 LPITEMIDLIST WINAPI ILGetNext(LPITEMIDLIST pidl)
 {	LPITEMIDLIST nextpidl;
 
-	TRACE(pidl,"(pidl=%p)\n",pidl);
+/*	TRACE(pidl,"(pidl=%p)\n",pidl);*/
 	if(pidl)
 	{ nextpidl = (LPITEMIDLIST)(LPBYTE)(((LPBYTE)pidl) + pidl->mkid.cb);
 	  return nextpidl;
@@ -210,8 +269,8 @@
  *  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;
+{	FIXME(pidl,"(pidl=%p,pidl=%p,%08u)stub\n",pidl,item,bEnd);
+	return NULL;
 }
 /*************************************************************************
  * ILFree [SHELL32.155]
@@ -222,10 +281,31 @@
  *     exported by ordinal
  */
 DWORD WINAPI ILFree(LPVOID pidl) 
-{ TRACE(pidl,"(pidl=0x%08lx)\n",(DWORD)pidl);
-  if (!pidl)
-		return 0;
-  return SHFree(pidl);
+{	TRACE(pidl,"(pidl=0x%08lx)\n",(DWORD)pidl);
+	if (!pidl)
+	  return 0;
+	return SHFree(pidl);
+}
+/*************************************************************************
+ * ILCreateFromPath [SHELL32.157]
+ *
+ */
+LPITEMIDLIST WINAPI ILCreateFromPath(LPSTR path) 
+{	LPSHELLFOLDER shellfolder;
+	LPITEMIDLIST pidlnew;
+	CHAR pszTemp[MAX_PATH*2];
+	LPWSTR lpszDisplayName = (LPWSTR)&pszTemp[0];
+	DWORD pchEaten;
+	
+	TRACE(pidl,"(path=%s)\n",path);
+	
+	LocalToWideChar32(lpszDisplayName, path, MAX_PATH);
+  
+	if (SHGetDesktopFolder(&shellfolder)==S_OK)
+	{ shellfolder->lpvtbl->fnParseDisplayName(shellfolder,0, NULL,lpszDisplayName,&pchEaten,&pidlnew,NULL);
+	  shellfolder->lpvtbl->fnRelease(shellfolder);
+	}
+	return pidlnew;
 }
 
 /**************************************************************************
@@ -303,12 +383,12 @@
  *  _ILIsDrive()
  *  _ILIsFolder()
  *  _ILIsValue()
-*/
+ */
 BOOL32 WINAPI _ILIsDesktop(LPCITEMIDLIST pidl)
 { TRACE(pidl,"(%p)\n",pidl);
 
   if (! pidl)
-    return FALSE;
+    return TRUE;
 
   return (  pidl->mkid.cb == 0x00 );
 }
@@ -695,7 +775,7 @@
 {	if(!pidl)
 	{ return NULL;
 	}
-	TRACE(pidl,"(%p)\n",  pidl);
+/*	TRACE(pidl,"(%p)\n",  pidl);*/
 	return (LPPIDLDATA)(&pidl->mkid.abID);
 }
 /**************************************************************************
@@ -703,7 +783,7 @@
  * gets a pointer to the string stored in the pidl
  */
 LPSTR WINAPI _ILGetTextPointer(PIDLTYPE type, LPPIDLDATA pidldata)
-{	TRACE(pidl,"(type=%x data=%p)\n", type, pidldata);
+{/*	TRACE(pidl,"(type=%x data=%p)\n", type, pidldata);*/
 
 	if(!pidldata)
 	{ return NULL;
diff --git a/dlls/shell32/shell32_main.c b/dlls/shell32/shell32_main.c
index ea39237..49753c5 100644
--- a/dlls/shell32/shell32_main.c
+++ b/dlls/shell32/shell32_main.c
@@ -89,9 +89,10 @@
  * 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);
+void WINAPI Control_RunDLL( HWND32 hwnd, LPCVOID code, LPCSTR cmd, DWORD arg4 )
+{
+    FIXME(shell, "(0x%08x, %p, %s, 0x%08lx): stub\n", hwnd, code,
+          debugstr_a(cmd), arg4);
 }
 
 /*************************************************************************
@@ -108,10 +109,10 @@
 BOOL32 WINAPI Shell_GetImageList(HIMAGELIST * imglist1,HIMAGELIST * imglist2)
 {	WARN(shell,"(%p,%p):semi-stub.\n",imglist1,imglist2);
 	if (imglist1)
-	{ *imglist1=ShellBigIconList;
+	{ *imglist1=ShellSmallIconList;
 	}
 	if (imglist2)
-	{ *imglist2=ShellSmallIconList;
+	{ *imglist2=ShellBigIconList;
 	}
 
 	return TRUE;
@@ -351,7 +352,7 @@
  *
  */
 LPITEMIDLIST WINAPI SHBrowseForFolder32A (LPBROWSEINFO32A lpbi)
-{ FIXME (shell, "(%lx,%s) empty stub!\n", (DWORD)lpbi, lpbi->lpszTitle);
+{ FIXME (shell, "(0x%lx,%s): stub\n", (DWORD)lpbi, debugstr_a(lpbi->lpszTitle));
   return NULL;
 }
 
diff --git a/dlls/shell32/shellole.c b/dlls/shell32/shellole.c
index bf78ba6..73db66a 100644
--- a/dlls/shell32/shellole.c
+++ b/dlls/shell32/shellole.c
@@ -239,7 +239,7 @@
 	return lpclf;
 }
 /**************************************************************************
- *  IClassFactory::QueryInterface
+ *  IClassFactory_QueryInterface
  */
 static HRESULT WINAPI IClassFactory_QueryInterface(
   LPCLASSFACTORY this, REFIID riid, LPVOID *ppvObj)
@@ -316,6 +316,9 @@
 	else if (IsEqualIID(riid, &IID_IContextMenu))
 	{ pObj = (IUnknown *)IContextMenu_Constructor(NULL, NULL, 0);
  	} 
+	else if (IsEqualIID(riid, &IID_IDataObject))
+	{ pObj = (IUnknown *)IDataObject_Constructor();
+ 	} 
 	else
 	{ ERR(shell,"unknown IID requested\n\tIID:\t%s\n",xriid);
 	  return(E_NOINTERFACE);
diff --git a/dlls/shell32/shellord.c b/dlls/shell32/shellord.c
index b8aa3f8..245bd7c 100644
--- a/dlls/shell32/shellord.c
+++ b/dlls/shell32/shellord.c
@@ -231,28 +231,26 @@
  * PathCombine [SHELL32.37]
  * 
  * NOTES
- *     concat_paths(char*target,const char*add);
- *     concats "target\\add" and writes them to target
+ *  if lpszFile='.' skip it
  */
-LPSTR WINAPI PathCombine(LPSTR target,LPSTR x1,LPSTR x2) {
-	char	buf[260];
-  TRACE(shell,"%s %s\n",x1,x2);
-	if (!x2 || !x2[0]) {
-		lstrcpy32A(target,x1);
-		return target;
+LPSTR WINAPI PathCombine(LPSTR szDest, LPCSTR lpszDir, LPCSTR lpszFile) 
+{	TRACE(shell,"%s %s\n",lpszDir,lpszFile);
+
+	if (!lpszFile || !lpszFile[0] || (lpszFile[0]=='.' && !lpszFile[1]) ) 
+	{ strcpy(szDest,lpszDir);
+	  return szDest;
 	}
-	lstrcpy32A(buf,x1);
-	PathAddBackslash(buf); /* append \ if not there */
-	lstrcat32A(buf,x2);
-	lstrcpy32A(target,buf);
-	return target;
+	strcpy(szDest,lpszDir);
+	PathAddBackslash(szDest);
+	strcat(szDest,lpszFile);
+	return szDest;
 }
 
 /*************************************************************************
  * PathIsUNC [SHELL32.39]
  * 
  * NOTES
- *     isUNC(const char*path);
+ *     PathIsUNC(char*path);
  */
 BOOL32 WINAPI PathIsUNC(LPCSTR path) {
   TRACE(shell,"%s\n",path);
@@ -260,6 +258,14 @@
 		return TRUE;
 	return FALSE;
 }
+/*************************************************************************
+ *  PathIsExe [SHELL32.43]
+ * 
+ */
+BOOL32 WINAPI PathIsExe (LPCSTR path)
+{  TRACE(shell,"path=%s\n",path);
+    return FALSE;
+}
 
 /*************************************************************************
  * PathFileExists [SHELL32.45]
@@ -274,6 +280,17 @@
     else
     	return TRUE;
 }
+/*************************************************************************
+ * PathMatchSpec [SHELL32.46]
+ * 
+ * NOTES
+ *     used from COMDLG32
+ */
+
+BOOL32 WINAPI PathMatchSpec(LPSTR x, LPSTR y) 
+{	FIXME(shell,"%s %s stub\n",x,y);
+	return TRUE;
+}
 
 /*************************************************************************
  * PathResolve [SHELL32.51]
@@ -417,7 +434,7 @@
  */
 DWORD WINAPI
 SHMapPIDLToSystemImageListIndex(LPSHELLFOLDER sh,DWORD y,DWORD z)
-{ FIXME(shell,"(folder=%p,%08lx,%08lx):stub.\n",sh,y,z);
+{ FIXME(shell,"(SF=%p,pidl=%08lx,%08lx):stub.\n",sh,y,z);
   return 0;
 }
 
@@ -872,7 +889,8 @@
  */
 BOOL32 WINAPI ShellExecuteEx32A (LPSHELLEXECUTEINFO32A sei)
 { 	CHAR szTemp[MAX_PATH];
-  	FIXME(shell,"%p stub\n",sei);
+
+  	FIXME(shell,"(%p): stub\n",sei);
 
 	if (sei->fMask & SEE_MASK_IDLIST)
 	{ SHGetPathFromIDList32A (sei->lpIDList,szTemp);
diff --git a/dlls/shell32/shlfolder.c b/dlls/shell32/shlfolder.c
index 5b03dcb..f78d3cc 100644
--- a/dlls/shell32/shlfolder.c
+++ b/dlls/shell32/shlfolder.c
@@ -4,7 +4,7 @@
  *	Copyright 1997	Marcus Meissner
  *	Copyright 1998	Juergen Schmied
  *
- *  !!! currently work in progress on all classes 980818 !!!
+ *  !!! currently work in progress on all classes 980930 !!!
  *  <contact juergen.schmied@metronet.de>
  */
 
@@ -105,8 +105,8 @@
 	sf=(LPSHELLFOLDER)HeapAlloc(GetProcessHeap(),0,sizeof(IShellFolder));
 	sf->ref=1;
 	sf->lpvtbl=&sfvt;
-	sf->mlpszFolder=NULL;
-	sf->mpSFParent=pParent;
+	sf->mlpszFolder=NULL;	/* path of the folder */
+	sf->mpSFParent=pParent;	/* parrent shellfolder */
 
 	TRACE(shell,"(%p)->(parent=%p, pidl=%p)\n",sf,pParent, pidl);
 	
@@ -114,24 +114,24 @@
 	sf->mpidl = ILClone(pidl);
 	sf->mpidlNSRoot = NULL;
 	
-	if(sf->mpidl)        /* do we have a pidl?*/
+	if(sf->mpidl)        /* do we have a pidl? */
 	{ dwSize = 0;
-	  if(sf->mpSFParent->mlpszFolder)
+	  if(sf->mpSFParent->mlpszFolder)		/* get the size of the parents path */
 	  { dwSize += strlen(sf->mpSFParent->mlpszFolder) + 1;
+	    TRACE(shell,"-- (%p)->(parent's path=%s)\n",sf, debugstr_a(sf->mpSFParent->mlpszFolder));
 	  }   
-	  dwSize += _ILGetFolderText(sf->mpidl,NULL,0);
+	  dwSize += _ILGetFolderText(sf->mpidl,NULL,0); /* add the size of the foldername*/
 	  sf->mlpszFolder = SHAlloc(dwSize);
 	  if(sf->mlpszFolder)
 	  { *(sf->mlpszFolder)=0x00;
-	    if(sf->mpSFParent->mlpszFolder)
+	    if(sf->mpSFParent->mlpszFolder)		/* if the parent has a path, get it*/
 	    {  strcpy(sf->mlpszFolder, sf->mpSFParent->mlpszFolder);
 	       PathAddBackslash (sf->mlpszFolder);
 	    }
 	    _ILGetFolderText(sf->mpidl, sf->mlpszFolder+strlen(sf->mlpszFolder), dwSize-strlen(sf->mlpszFolder));
+	    TRACE(shell,"-- (%p)->(my path=%s)\n",sf, debugstr_a(sf->mlpszFolder));
 	  }
 	}
-	
-	TRACE(shell,"-- (%p)->(%p,%p,parent=%s)\n",sf,pParent, pidl, debugstr_a(sf->mlpszFolder));
 	return sf;
 }
 /**************************************************************************
@@ -288,16 +288,15 @@
 	HWND32 hwndOwner,
 	DWORD dwFlags,
 	LPENUMIDLIST* ppEnumIDList)
-{ HRESULT  hr;
-	TRACE(shell,"(%p)->(HWND=0x%08x,0x%08lx,%p)\n",this,hwndOwner,dwFlags,ppEnumIDList);
+{	TRACE(shell,"(%p)->(HWND=0x%08x flags=0x%08lx pplist=%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;		
+	*ppEnumIDList = NULL;
+	*ppEnumIDList = IEnumIDList_Constructor (this->mlpszFolder, dwFlags);
+	TRACE(shell,"-- (%p)->(new ID List: %p)\n",this,*ppEnumIDList);
+	if(!*ppEnumIDList)
+	{ return E_OUTOFMEMORY;
+	}
+	return S_OK;		
 }
 /**************************************************************************
  *  IShellFolder_Initialize()
@@ -496,19 +495,21 @@
   do
   { if (*pidltemp)
     { if (_ILIsDesktop( *pidltemp))
-      { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR);
+      { *rgfInOut |= ( SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANLINK );
       }
       else if (_ILIsMyComputer( *pidltemp))
-      { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER);
+      { *rgfInOut |= ( SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR
+      			| SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANRENAME | SFGAO_CANLINK );
       }
       else if (_ILIsDrive( *pidltemp))
-      { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER  | SFGAO_FILESYSTEM);
+      { *rgfInOut |= ( SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM  | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR  | 
+      			SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANLINK );
       }
       else if (_ILIsFolder( *pidltemp))
-      { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM );
+      { *rgfInOut |= ( SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_CAPABILITYMASK );
       }
       else if (_ILIsValue( *pidltemp))
-      { *rgfInOut |= (SFGAO_FILESYSTEM);
+      { *rgfInOut |= (SFGAO_FILESYSTEM | SFGAO_CAPABILITYMASK );
       }
     }
     pidltemp++;
@@ -624,17 +625,14 @@
 		
 	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)
+	if (pidlTemp && pidlTemp->mkid.cb==0x00)
 	{ bSimplePidl = TRUE;
+	  TRACE(shell,"-- simple pidl\n");
 	}
 	if (_ILIsDesktop( pidl))
 	{ strcpy (szText,"Desktop");
@@ -667,12 +665,15 @@
 	  { case SHGDN_NORMAL:
 	      _ILGetPidlPath( pidl, szText, MAX_PATH);
 	      break;
+
+	    case SHGDN_INFOLDER | SHGDN_FORPARSING: /*fall thru*/
 	    case SHGDN_INFOLDER:
 	      pidlTemp = ILFindLastID(pidl);
 	      if (pidlTemp)
 	      { _ILGetItemText( pidlTemp, szText, MAX_PATH);
 	      }
 	      break;				
+
 	    case SHGDN_FORPARSING:
 	      if (bSimplePidl)
 	      { /* if the IShellFolder has parents, get the path from the
@@ -696,6 +697,7 @@
 	      }
 	      break;
 	    default:
+	      TRACE(shell,"--- wrong flags=%lx\n", dwFlags);
 	      return E_INVALIDARG;
 	  }
 	  if ((szText[0]==0x00 && szDrive[0]!=0x00)|| (bSimplePidl && szDrive[0]!=0x00))
@@ -706,7 +708,7 @@
 	  }
 	}
   
-	TRACE(shell,"-- (%p)->(%s,%s,%s)\n",this,szSpecial,szDrive,szText);
+	TRACE(shell,"-- (%p)->(%s)\n",this,szText);
 
 	if(!(lpName))
 	{  return E_OUTOFMEMORY;
diff --git a/dlls/shell32/shlview.c b/dlls/shell32/shlview.c
index 3939b38..13322f5 100644
--- a/dlls/shell32/shlview.c
+++ b/dlls/shell32/shlview.c
@@ -1,10 +1,7 @@
 /*
  *	ShellView
  *
- *	Copyright 1998	Juergen Schmied
- *
- *  !!! currently work in progress on all classes 980801 !!!
- *  <contact juergen.schmied@metronet.de>
+ *	Copyright 1998	<juergen.schmied@metronet.de>
  */
 
 #include <ctype.h>
@@ -48,6 +45,8 @@
 static HRESULT WINAPI IShellView_SelectItem(LPSHELLVIEW, LPCITEMIDLIST pidlItem, UINT32 uFlags);
 static HRESULT WINAPI IShellView_GetItemObject(LPSHELLVIEW, UINT32 uItem, REFIID riid,LPVOID *ppv);
 
+static BOOL32 ShellView_CanDoIDockingWindow(LPSHELLVIEW);
+
 static struct IShellView_VTable svvt = 
 { IShellView_QueryInterface,
   IShellView_AddRef,
@@ -71,8 +70,17 @@
 #define IDM_VIEW_FILES  (FCIDM_SHVIEWFIRST + 0x500)
 #define IDM_VIEW_IDW    (FCIDM_SHVIEWFIRST + 0x501)
 #define IDM_MYFILEITEM  (FCIDM_SHVIEWFIRST + 0x502)
+#define ID_LISTVIEW     2000
+#define MENU_OFFSET  1
+#define MENU_MAX     100
+#define TOOLBAR_ID   (L"SHELLDLL_DefView")
+//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
 
-#define TOOLBAR_ID   (L"ShellView")
 typedef struct
 {  int   idCommand;
    int   iImage;
@@ -87,6 +95,11 @@
 { {IDM_VIEW_FILES, 0, IDS_TB_VIEW_FILES, IDS_MI_VIEW_FILES, 0, TBSTATE_ENABLED, TBSTYLE_BUTTON},
   {-1, 0, 0, 0, 0, 0, 0}   
 };
+BOOL32 g_bViewKeys;
+BOOL32 g_bShowIDW;
+
+typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
+
 /**************************************************************************
 *  IShellView_Constructor
 */
@@ -107,30 +120,70 @@
   return sv;
 }
 /**************************************************************************
+*  helperfunctions for communication with ICommDlgBrowser
+*
+*/
+static BOOL32 IsInCommDlg(LPSHELLVIEW this)
+{	return(this->pCommDlgBrowser != NULL);
+}
+static HRESULT IncludeObject(LPSHELLVIEW this, LPCITEMIDLIST pidl)
+{	if ( IsInCommDlg(this) )
+	{ TRACE(shell,"ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
+	  return (this->pCommDlgBrowser->lpvtbl->fnIncludeObject(this->pCommDlgBrowser, this, pidl));
+	}
+	return S_OK;
+}
+static HRESULT OnDefaultCommand(LPSHELLVIEW this)
+{	if (IsInCommDlg(this))
+	{ TRACE(shell,"ICommDlgBrowser::OnDefaultCommand\n");
+	  return (this->pCommDlgBrowser->lpvtbl->fnOnDefaultCommand(this->pCommDlgBrowser, this));
+	}
+	return S_FALSE;
+}
+static HRESULT OnStateChange(LPSHELLVIEW this, UINT32 uFlags)
+{	if (IsInCommDlg(this))
+	{ TRACE(shell,"ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
+	  return (this->pCommDlgBrowser->lpvtbl->fnOnStateChange(this->pCommDlgBrowser, this, uFlags));
+	}
+	return S_FALSE;
+}
+
+/**************************************************************************
 * ShellView_CreateList()
 *
-* NOTES
-*  internal
 */
-#define ID_LISTVIEW     2000
 
 BOOL32 ShellView_CreateList (LPSHELLVIEW this)
-{ DWORD dwStyle;
+{	DWORD dwStyle;
 
-  TRACE(shell,"%p\n",this);
+	TRACE(shell,"%p\n",this);
 
-  dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILD | WS_BORDER |
-  		 LVS_ICON | LVS_SHAREIMAGELISTS | LVS_EDITLABELS ;
+	dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILD | WS_BORDER | LVS_SHAREIMAGELISTS | LVS_EDITLABELS;
+	switch (this->FolderSettings.ViewMode)
+	{ case FVM_ICON:	dwStyle |= LVS_ICON;		break;
+	  case FVM_SMALLICON: 	dwStyle |= LVS_SMALLICON;	break;
+	  case FVM_LIST: 	dwStyle |= LVS_LIST;		break;
+	  case FVM_DETAILS: 	dwStyle |= LVS_REPORT;		break;
+	}
+	if (this->FolderSettings.fFlags && FWF_AUTOARRANGE)	dwStyle |= LVS_AUTOARRANGE;
+	/*if (this->FolderSettings.fFlags && FWF_DESKTOP); used from explorer*/
+	if (this->FolderSettings.fFlags && FWF_SINGLESEL)	dwStyle |= LVS_SINGLESEL;
 
-  this->hWndList=CreateWindowEx32A( WS_EX_CLIENTEDGE,WC_LISTVIEW32A,NULL,dwStyle,
-  								0,0,0,0,
-  								this->hWnd,(HMENU32)ID_LISTVIEW,shell32_hInstance,NULL);
+	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;
+	if(!this->hWndList)
+	  return FALSE;
 
-//  UpdateShellSettings();
-  return TRUE;
+	//  UpdateShellSettings();
+	return TRUE;
 }
 /**************************************************************************
 * ShellView_InitList()
@@ -177,7 +230,6 @@
 
   ListView_SetImageList(this->hWndList, ShellSmallIconList, LVSIL_SMALL);
   ListView_SetImageList(this->hWndList, ShellBigIconList, LVSIL_NORMAL);
-  ListView_SetBkColor(this->hWndList, 0x00800000 );
   
   return TRUE;
 }
@@ -188,13 +240,13 @@
 *  internal
 */   
 int CALLBACK ShellView_CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
-{ LPSHELLFOLDER  pFolder = (LPSHELLFOLDER)lpData;
+{	LPSHELLFOLDER  pFolder = (LPSHELLFOLDER)lpData;
 
-  TRACE(shell,"\n");
-  if(!pFolder)
-    return 0;
+	TRACE(shell,"\n");
+	if(!pFolder)
+	  return 0;
 
- return (int)pFolder->lpvtbl->fnCompareIDs(pFolder, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2);
+	return (int)pFolder->lpvtbl->fnCompareIDs(pFolder, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2);
 }
 
 /**************************************************************************
@@ -223,12 +275,19 @@
       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_InsertItem32A(this->hWndList, &lvItem);	/*add the item*/    
+      if ( S_OK == IncludeObject(this, ILClone(pidl) ))	/* fixme free the pidl*/
+      { ListView_InsertItem32A(this->hWndList, &lvItem);	/*add the item*/    
+      }
+      else
+      { SHFree(pidl); /* not viewed */
+      }
+
    }
 
    /*sort the items*/
-   ListView_SortItems(this->hWndList, ShellView_CompareItems, (LPARAM)this->pSFParent);
-     
+   /* 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);
@@ -246,43 +305,47 @@
 */   
 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;
+{	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];
+{	CHAR			szText[MAX_PATH];
 	MENUITEMINFO32A	mii;
 	int				nTools,i;
 	HMENU32 		hSubMenu;
 
-	TRACE(shell,"(%p) stub\n",this);
+	TRACE(shell,"(%p) semi-stub\n",this);
 
-    hSubMenu = CreatePopupMenu32();
+	hSubMenu = CreatePopupMenu32();
 	if(hSubMenu)
 	{ /*get the number of items in our global array*/
 	  for(nTools = 0; g_Tools[nTools].idCommand != -1; nTools++){}
 
-	  //add the menu items
+	  /*add the menu items*/
 	  for(i = 0; i < nTools; i++)
-      { strcpy(szText, "dummy 44");
+	  { strcpy(szText, "dummy BuildFileMenu");
       
 	    ZeroMemory(&mii, sizeof(mii));
 	    mii.cbSize = sizeof(mii);
@@ -290,16 +353,16 @@
 
 	    if(TBSTYLE_SEP != g_Tools[i].bStyle)
 	    { mii.fType = MFT_STRING;
-          mii.fState = MFS_ENABLED;
-          mii.dwTypeData = szText;
-          mii.wID = g_Tools[i].idCommand;
-        }
+	      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);
-      }
+	    { mii.fType = MFT_SEPARATOR;
+	    }
+	    /* tack this item onto the end of the menu */
+	    InsertMenuItem32A(hSubMenu, (UINT32)-1, TRUE, &mii);
+	  }
 	}
 	return hSubMenu;
 }
@@ -367,6 +430,24 @@
 	}
 }
 /**************************************************************************
+* 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_OnDeactivate()
 *
 * NOTES
@@ -391,64 +472,63 @@
 */   
 LRESULT ShellView_OnActivate(LPSHELLVIEW this, UINT32 uState)
 {	OLEMENUGROUPWIDTHS32   omw = { {0, 0, 0, 0, 0, 0} };
-    MENUITEMINFO32A         mii;
-    CHAR                szText[MAX_PATH];
+	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();
+	  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");
+	    /*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);
+	    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);
-        }
+	    /*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;
+	    /*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)
+	    /*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.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->pShellBrowser->lpvtbl->fnSetMenuSB(this->pShellBrowser, this->hMenu, 0, this->hWnd);
 	  }
 	}
 	this->uState = uState;
@@ -462,18 +542,16 @@
 *  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);
+{	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;
+	return 0;
 }
 
-BOOL32 g_bViewKeys;
-BOOL32 g_bShowIDW;
 /**************************************************************************
 * ShellView_OnKillFocus()
 */   
@@ -487,112 +565,85 @@
 * ShellView_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;
-*/
+{	BOOL32	bReturn = FALSE;
+	HRESULT	hr;
+	LPSERVICEPROVIDER	pSP;
+	LPDOCKINGWINDOWFRAME	pFrame;
+	
+	FIXME(shell,"(%p)->(badd=0x%08x) stub\n",this,bAdd);
+
 	/* get the browser's IServiceProvider */
-/*	hr = this->pShellBrowser->QueryInterface((REFIID)IID_IServiceProvider, (LPVOID*)&pSP);
+	hr = this->pShellBrowser->lpvtbl->fnQueryInterface(this->pShellBrowser, (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;
+	{ /*get the IDockingWindowFrame pointer*/
+	  hr = pSP->lpvtbl->fnQueryService(pSP, &SID_SShellBrowser, &IID_IDockingWindowFrame, (LPVOID*)&pFrame);
+	  if(SUCCEEDED(hr))
+	  { if(bAdd)
+	    { hr = S_OK;
+	      /*if(!this->pDockingWindow)
+	      { //create the toolbar object
+	        this->pDockingWindow = DockingWindow_Constructor(this, this->hWnd);
 	      }
-	    }
-	  }
-      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.*/
+	      if(this->pDockingWindow)
+	      { //add the toolbar object
+	        hr = pFrame->lpvtbl->fnAddToolbar(pFrame, (IDockingWindow*)this->pDockingWindow, TOOLBAR_ID, 0);
+
+	        if(SUCCEEDED(hr))
+	        { bReturn = TRUE;
+	        }
+	      }*/
+	    }
+	    else
+	    { /*if(this->pDockingWindow)
+	      { hr = pFrame->->lpvtbl->fnRemoveToolbar(pFrame, (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;
-                             }
-	      }
+	          this->pDockingWindow = NULL;
+	          bReturn = TRUE;
+	        }
+	      }*/
 	    }
-	    pFrame->Release();
-      }
-	  pSP->Release();
+	    pFrame->lpvtbl->fnRelease(pFrame);
+	  }
+	  pSP->lpvtbl->fnRelease(pSP);
 	}
-	return bReturn;*/
+	return bReturn;
 }
 
 /**************************************************************************
 * 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);
+{	BOOL32 bReturn = FALSE;
+	HRESULT hr;
+	LPSERVICEPROVIDER pSP;
+	LPDOCKINGWINDOWFRAME pFrame;
+	
+	FIXME(shell,"(%p) stub\n",this);
+	
+	/*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);
+	{ hr = pSP->lpvtbl->fnQueryService(pSP, &SID_SShellBrowser, &IID_IDockingWindowFrame, (LPVOID*)&pFrame);
    	  if(SUCCEEDED(hr))
-      { bReturn = TRUE;
-        pFrame->lpvtbl->fnRelease(pFrame);
-      }
-	pSP->lpvtbl->fnRelease(pSP);
+	  { 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;
+	return bReturn;
 }
 
 /**************************************************************************
 *  ShellView_UpdateShellSettings()
-   
-**************************************************************************/
-typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
-
-
+*/
 void ShellView_UpdateShellSettings(LPSHELLVIEW this)
-{	TRACE(shell,"(%p) stub\n",this);
+{	FIXME(shell,"(%p) stub\n",this);
 	return ;
 /*
 	SHELLFLAGSTATE       sfs;
@@ -641,14 +692,12 @@
 	return 0;
 }
 
-#define MENU_OFFSET  1
-#define MENU_MAX     100
-
 /**************************************************************************
 *   ShellView_DoContextMenu()
 */   
 void ShellView_DoContextMenu(LPSHELLVIEW this, WORD x, WORD y, BOOL32 fDefault)
-{	UINT32		uCommand, i, uSelected = ListView_GetSelectedCount(this->hWndList);
+{	UINT32	uCommand, i, uSelected = ListView_GetSelectedCount(this->hWndList);
+	DWORD	wFlags;
 	HMENU32 hMenu;
 	BOOL32  fExplore = FALSE;
 	HWND32  hwndTree = 0;
@@ -663,7 +712,7 @@
 	aSelectedItems = (LPITEMIDLIST*)SHAlloc(uSelected * sizeof(LPITEMIDLIST));
 
 	if(aSelectedItems)
-	{ TRACE(shell,"-- aSelectedItems\n");
+	{ TRACE(shell,"-- Items selected =%u\n", uSelected);
 	  ZeroMemory(&lvItem, sizeof(lvItem));
 	  lvItem.mask = LVIF_STATE | LVIF_PARAM;
 	  lvItem.stateMask = LVIS_SELECTED;
@@ -675,19 +724,25 @@
 	  { if(lvItem.state & LVIS_SELECTED)
 	    { aSelectedItems[i] = (LPITEMIDLIST)lvItem.lParam;
 	      i++;
+	      TRACE(shell,"-- selected Item found\n");
 	    }
 	    lvItem.iItem++;
 	  }
 
-	  this->pSFParent->lpvtbl->fnGetUIObjectOf(this->pSFParent, this->hWndParent, uSelected,
-      				(LPCITEMIDLIST*)aSelectedItems, &IID_IContextMenu, NULL,(LPVOID*)&pContextMenu);
+	  this->pSFParent->lpvtbl->fnGetUIObjectOf(	this->pSFParent,
+							this->hWndParent,
+							uSelected,
+							(LPCITEMIDLIST*)aSelectedItems,
+							&IID_IContextMenu,
+							NULL,
+							(LPVOID*)&pContextMenu);
    
 	  if(pContextMenu)
 	  { TRACE(shell,"-- pContextMenu\n");
 	    hMenu = CreatePopupMenu32();
 
-        /* See if we are in Explore or Open mode. If the browser's tree is present, 
-        then we are in Explore mode.*/
+            /* See if we are in Explore or Open mode. If the browser's tree is present, 
+            then we are in Explore mode.*/
         
 	    fExplore = FALSE;
 	    hwndTree = 0;
@@ -696,10 +751,12 @@
 	      fExplore = TRUE;
 	    }
 
-	    if(hMenu && SUCCEEDED(pContextMenu->lpvtbl->fnQueryContextMenu(pContextMenu,
-        					hMenu,0,MENU_OFFSET,MENU_MAX,CMF_NORMAL | 
-							(uSelected != 1 ? 0 : CMF_CANRENAME) |
-                            (fExplore ? CMF_EXPLORE : 0))))
+	    if(hMenu && SUCCEEDED(pContextMenu->lpvtbl->fnQueryContextMenu( pContextMenu,
+									    hMenu,
+									    0,
+									    MENU_OFFSET,
+									    MENU_MAX,
+									    CMF_NORMAL | (uSelected != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0))))
 	    { if(fDefault)
 	      { TRACE(shell,"-- fDefault\n");
 	        uCommand = 0;
@@ -725,16 +782,31 @@
 	      }
          
 	      if(uCommand > 0)
-	      { TRACE(shell,"-- ! uCommand\n");
-	        ZeroMemory(&cmi, sizeof(cmi));
-	        cmi.cbSize = sizeof(cmi);
-	        cmi.hwnd = this->hWndParent;
-	        cmi.lpVerb = (LPCSTR)MAKEINTRESOURCE32A(uCommand - MENU_OFFSET);
+	      { TRACE(shell,"-- uCommand=%u\n", uCommand);
+	        if (((uCommand-MENU_OFFSET) == IDM_EXPLORE) || ((uCommand-MENU_OFFSET)  == IDM_OPEN))
+		{ if (IsInCommDlg(this))			/* are we part of a commctrl? */
+		  { TRACE(shell,"-- fnOnDefaultCommand\n");
+		    OnDefaultCommand(this);
+		  }
+		  else					/* we are acting with a full featured IShellBrowser */
+		  { TRACE(shell,"-- fnBrowseObject pidl =%p\n", aSelectedItems[0]);
+		    wFlags = SBSP_DEFBROWSER | SBSP_DEFMODE | SBSP_RELATIVE;
+		    this->pShellBrowser->lpvtbl->fnBrowseObject(	this->pShellBrowser, 
+								aSelectedItems[0], 
+								wFlags);
+		  }
+		}
+		else
+		{ 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);
+	    pContextMenu->lpvtbl->fnRelease(pContextMenu);
 	  }
 	  SHFree(aSelectedItems);
 	}
@@ -761,7 +833,7 @@
 	    break;
 
 	  default:
-	    FIXME(shell,"-- unknown command\n");
+	    FIXME(shell,"-- COMMAND unhandled\n");
 	}
 	return 0;
 }
@@ -782,44 +854,45 @@
 	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);
+	{ case NM_SETFOCUS:
+	    TRACE(shell,"-- NM_SETFOCUS %p\n",this);
 	    ShellView_OnSetFocus(this);
 	    break;
 
 	  case NM_KILLFOCUS:
-	    TRACE(shell,"NM_KILLFOCUS %p\n",this);
+	    TRACE(shell,"-- NM_KILLFOCUS %p\n",this);
 	    ShellView_OnDeactivate(this);
 	    break;
 
 	  case HDN_ENDTRACK32A:
-	    TRACE(shell,"HDN_ENDTRACK32A %p\n",this);
+	    TRACE(shell,"-- HDN_ENDTRACK32A %p\n",this);
 	    /*nColumn1 = ListView_GetColumnWidth(this->hWndList, 0);
 	    nColumn2 = ListView_GetColumnWidth(this->hWndList, 1);*/
-	    return 0;
+	    break;
    
 	  case LVN_DELETEITEM:
-	    TRACE(shell,"LVN_DELETEITEM %p\n",this);
+	    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
 	  case NM_DBLCLK:
 	  case NM_RETURN:
-#endif
-	    TRACE(shell,"LVN_ITEMACTIVATE | NM_RETURN %p\n",this);
+	    TRACE(shell,"-- NM_RETURN|NM_DBLCLK ignored, waiting for LVN_ITEMACTIVATE\n");
+	    break;
+
+	  case LVN_ITEMACTIVATE:
+	    TRACE(shell,"-- LVN_ITEMACTIVATE %p\n",this);
 	    ShellView_DoContextMenu(this, 0, 0, TRUE);
-	    return 0;
+	    break;
    
 	  case NM_RCLICK:
-	    TRACE(shell,"NM_RCLICK %p\n",this);
+	    TRACE(shell,"-- NM_RCLICK %p\n",this);
 	    dwCursor = GetMessagePos();
 	    ShellView_DoContextMenu(this, LOWORD(dwCursor), HIWORD(dwCursor), FALSE);
+	    break;
 
 	  case LVN_GETDISPINFO32A:
-	    TRACE(shell,"LVN_GETDISPINFO32A %p\n",this);
+	    TRACE(shell,"-- LVN_GETDISPINFO32A %p\n",this);
 	    pidl = (LPITEMIDLIST)lpdi->item.lParam;
 
 
@@ -858,27 +931,40 @@
 	      }
 	    }
 	    TRACE(shell,"-- text=%s image=%x\n",lpdi->item.pszText, lpdi->item.iImage);
-	    return 0;
+	    break;
 
 	  case NM_CLICK:
-	    TRACE(shell,"NM_CLICK %p\n",this);
+	    WARN(shell,"-- NM_CLICK %p\n",this);
 	    break;
 
 	  case LVN_ITEMCHANGING:
-	    TRACE(shell,"LVN_ITEMCHANGING %p\n",this);
+	    WARN(shell,"-- LVN_ITEMCHANGING %p\n",this);
 	    break;
 
 	  case LVN_ITEMCHANGED:
-	    TRACE(shell,"LVN_ITEMCHANGED %p\n",this);
+	    WARN(shell,"-- LVN_ITEMCHANGED %p\n",this);
+	    OnStateChange(this, CDBOSC_SELCHANGE);  
+	    break;
+
+	  case LVN_DELETEALLITEMS:
+	    WARN(shell,"-- LVN_DELETEALLITEMS %p\n",this);
+	    break;
+
+	  case LVN_INSERTITEM:
+	    WARN(shell,"-- LVN_INSERTITEM %p\n",this);
+	    break;
+
+	  case LVN_BEGINDRAG:
+	    WARN(shell,"-- LVN_BEGINDRAG %p\n",this);
 	    break;
 
 	  case NM_CUSTOMDRAW:
-	    TRACE(shell,"NM_CUSTOMDRAW %p\n",this);
+	    WARN(shell,"NM_CUSTOMDRAW %p\n",this);
 	    break;
 
 	  default:
-	    WARN (shell,"-- WM_NOTIFY unhandled\n");
-	    return 0;
+	    FIXME (shell,"-- WM_NOTIFY unhandled\n");
+	    break;;
 	}
 	return 0;
 }
@@ -886,23 +972,17 @@
 /**************************************************************************
 *  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;
   DWORD dwCursor;
   
-  FIXME(shell,"(hwnd=%x msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
+  TRACE(shell,"(hwnd=%x msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
     
   switch (uMessage)
   { case WM_NCCREATE:
-      { TRACE(shell,"WM_NCCREATE\n");
+      { TRACE(shell,"-- WM_NCCREATE\n");
         lpcs = (LPCREATESTRUCT32A)lParam;
         pThis = (LPSHELLVIEW)(lpcs->lpCreateParams);
         SetWindowLong32A(hWnd, GWL_USERDATA, (LONG)pThis);
@@ -911,87 +991,50 @@
       break;
    
    case WM_SIZE:
-      TRACE(shell,"WM_SIZE\n");
+      TRACE(shell,"-- WM_SIZE\n");
       return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
    
    case WM_SETFOCUS:
-      TRACE(shell,"WM_SETFOCUS\n");   
+      TRACE(shell,"-- WM_SETFOCUS\n");   
       return ShellView_OnSetFocus(pThis);
  
    case WM_KILLFOCUS:
-      TRACE(shell,"WM_KILLFOCUS\n");
+      TRACE(shell,"-- WM_KILLFOCUS\n");
   	  return ShellView_OnKillFocus(pThis);
 
    case WM_CREATE:
-      TRACE(shell,"WM_CREATE\n");
+      TRACE(shell,"-- WM_CREATE\n");
       return ShellView_OnCreate(pThis);
 
    case WM_SHOWWINDOW:
-      TRACE(shell,"WM_SHOWWINDOW\n");
+      TRACE(shell,"-- WM_SHOWWINDOW\n");
       UpdateWindow32(pThis->hWndList);
       break;
 
    case WM_ACTIVATE:
-      TRACE(shell,"WM_ACTIVATE\n");
+      TRACE(shell,"-- WM_ACTIVATE\n");
       return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
    
    case WM_COMMAND:
-      TRACE(shell,"WM_COMMAND\n");
+      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");
+      TRACE(shell,"-- WM_INITMENUPOPUP\n");
       return ShellView_UpdateMenu(pThis, (HMENU32)wParam);
    
    case WM_NOTIFY:
-      TRACE(shell,"WM_NOTIFY\n");
+      TRACE(shell,"-- WM_NOTIFY\n");
       return ShellView_OnNotify(pThis,(UINT32)wParam, (LPNMHDR)lParam);
 
    case WM_SETTINGCHANGE:
-      TRACE(shell,"WM_SETTINGCHANGE\n");
+      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");
+      TRACE(shell,"-- WM_PARENTNOTIFY\n");
       if ( LOWORD(wParam) == WM_RBUTTONDOWN ) /* fixme: should not be handled here*/
       { dwCursor = GetMessagePos();
 	ShellView_DoContextMenu(pThis, LOWORD(dwCursor), HIWORD(dwCursor), FALSE);
@@ -999,19 +1042,92 @@
       }
       break;
 
+/* -------------*/
+   case WM_MOVE:
+      WARN(shell,"-- WM_MOVE\n");   
+      break;
+   
+   case WM_ACTIVATEAPP:
+      WARN(shell,"-- WM_ACTIVATEAPP\n");
+      break;
+
+   case WM_NOTIFYFORMAT:
+      WARN(shell,"-- WM_NOTIFYFORMAT\n");
+      break;
+
+   case WM_NCPAINT:
+      WARN(shell,"-- WM_NCPAINT\n");
+      break;
+
+   case WM_ERASEBKGND:
+      WARN(shell,"-- WM_ERASEBKGND\n");
+      break;
+
+   case WM_PAINT:
+      WARN(shell,"-- WM_PAINT\n");
+      break;
+
+   case WM_NCCALCSIZE:
+      WARN(shell,"-- WM_NCCALCSIZE\n");
+      break;
+
+   case WM_WINDOWPOSCHANGING:
+      WARN(shell,"-- WM_WINDOWPOSCHANGING\n");
+      break;
+
+   case WM_WINDOWPOSCHANGED:
+      WARN(shell,"-- WM_WINDOWPOSCHANGED\n");
+      break;
+
    case WM_MOUSEACTIVATE:
-      TRACE(shell,"WM_MOUSEACTIVATE\n");
+      WARN(shell,"-- WM_MOUSEACTIVATE\n");
       break;
 
    case WM_SETCURSOR:
-      TRACE(shell,"WM_SETCURSOR\n");
+      WARN(shell,"-- WM_SETCURSOR\n");
+      break;
+
+   case WM_DESTROY:
+      WARN(shell,"-- WM_DESTROY\n");
+      break;
+
+   case WM_NCDESTROY:
+      WARN(shell,"-- WM_NCDESTROY\n");
+      break;
+
+   case WM_CONTEXTMENU:
+      WARN(shell,"-- WM_CONTEXTMENU\n");
+      break;
+
+   case WM_MENUSELECT:
+      WARN(shell,"-- WM_MENUSELECT\n");
+      break;
+
+   case WM_CAPTURECHANGED:
+      WARN(shell,"-- WM_CAPTURECHANGED\n");
+      break;
+
+   case WM_CHILDACTIVATE:
+      WARN(shell,"-- WM_CHILDACTIVATE\n");
+      break;
+
+   case WM_ENTERIDLE:
+      WARN(shell,"-- WM_ENTERIDLE\n");
+      break;
+
+   default:
+      FIXME(shell,"-- MESSAGE unhandled\n");
       break;
   }
   return DefWindowProc32A (hWnd, uMessage, wParam, lParam);
 }
-
-
 /**************************************************************************
+*
+*
+*  The INTERFACE of the IShellView object
+*
+*
+***************************************************************************
 *  IShellView::QueryInterface
 */
 static HRESULT WINAPI IShellView_QueryInterface(LPSHELLVIEW this,REFIID riid, LPVOID *ppvObj)
@@ -1049,7 +1165,7 @@
 static ULONG WINAPI IShellView_Release(LPSHELLVIEW this)
 { TRACE(shell,"(%p)->()\n",this);
   if (!--(this->ref)) 
-  { TRACE(shell," destroying IEnumIDList(%p)\n",this);
+  { TRACE(shell," destroying IShellView(%p)\n",this);
 
     if(this->pSFParent)
        this->pSFParent->lpvtbl->fnRelease(this->pSFParent);
@@ -1063,10 +1179,10 @@
 *  ShellView_GetWindow
 */
 static HRESULT WINAPI IShellView_GetWindow(LPSHELLVIEW this,HWND32 * phWnd)
-{ TRACE(shell,"(%p) stub\n",this);
- *phWnd = this->hWnd;
+{	TRACE(shell,"(%p) stub\n",this);
+	*phWnd = this->hWnd;
 
- return S_OK;
+	return S_OK;
 }
 static HRESULT WINAPI IShellView_ContextSensitiveHelp(LPSHELLVIEW this,BOOL32 fEnterMode)
 { FIXME(shell,"(%p) stub\n",this);
@@ -1095,94 +1211,114 @@
 	LRESULT	lResult;
 	int		nPartArray[1] = {-1};
 
-	FIXME(shell,"(%p) stub\n",this);
-	//don't do anything if the state isn't really changing
+	FIXME(shell,"(%p)->(state=%x) stub\n",this, uState);
+	/*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
+	/*OnActivate handles the menu merging and internal state*/
 	ShellView_OnActivate(this, uState);
 
-	//remove the docking window
+	/*remove the docking window*/
 	if(g_bShowIDW)
 	{ ShellView_AddRemoveDockingWindow(this, FALSE);
-    }
+	}
 
-	//only do this if we are active
+	/*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));
+	  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);
+	  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);
+	  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);
+{	TRACE(shell,"(%p)\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;
+{	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);
+	TRACE(shell,"(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",this, lpPrevView,lpfs, psb, prcView, phWnd);
+	TRACE(shell,"-- vmode=%x flags=%x left=%i top=%i right=%i bottom=%i\n",lpfs->ViewMode, lpfs->fFlags ,prcView->left,prcView->top, prcView->right, prcView->bottom);
+
+	/*set up the member variables*/
+	this->pShellBrowser = psb;
+	this->FolderSettings = *lpfs;
+
+	/*get our parent window*/
+	this->pShellBrowser->lpvtbl->fnAddRef(this->pShellBrowser);
+	this->pShellBrowser->lpvtbl->fnGetWindow(this->pShellBrowser, &(this->hWndParent));
+
+	/* try to get the ICommDlgBrowserInterface */
+	this->pCommDlgBrowser=NULL;
+	if ( SUCCEEDED (this->pShellBrowser->lpvtbl->fnQueryInterface( this->pShellBrowser,
+								        &IID_ICommDlgBrowser,
+									(LPVOID*) &this->pCommDlgBrowser)))
+	{ TRACE(shell,"-- CommDlgBrowser\n");
+	}
+	   
+	/*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 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;
+	  if(!RegisterClass32A(&wc))
+	    return E_FAIL;
+	}
 
-   //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,
+	*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;
+	if(!*phWnd)
+	  return E_FAIL;
 
-   this->pShellBrowser->lpvtbl->fnAddRef(this->pShellBrowser);
-
-   return S_OK;
+	return S_OK;
 }
 
 static HRESULT WINAPI IShellView_DestroyViewWindow(LPSHELLVIEW this)
-{	TRACE(shell,"(%p) stub\n",this);
+{	TRACE(shell,"(%p)\n",this);
 
 	/*Make absolutely sure all our UI is cleaned up.*/
 	IShellView_UIActivate(this, SVUIA_DEACTIVATE);
@@ -1194,10 +1330,15 @@
 	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;
+{	TRACE(shell,"(%p)->(%p) vmode=%x flags=%x\n",this, lpfs, 
+		this->FolderSettings.ViewMode, this->FolderSettings.fFlags);
+  
+	if (lpfs)
+	{ *lpfs = this->FolderSettings;
+	  return NOERROR;
+	}
+	else
+	  return E_INVALIDARG;
 }
 static HRESULT WINAPI IShellView_AddPropertySheetPages(LPSHELLVIEW this, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
 { FIXME(shell,"(%p) stub\n",this);
@@ -1211,11 +1352,11 @@
 { 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)
+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);
+  FIXME(shell,"(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)stub\n",this, uItem, xriid, ppvOut);
 
   *ppvOut = NULL;
   return E_NOTIMPL;
diff --git a/dlls/winaspi/Makefile.in b/dlls/winaspi/Makefile.in
new file mode 100644
index 0000000..eb83e44
--- /dev/null
+++ b/dlls/winaspi/Makefile.in
@@ -0,0 +1,15 @@
+DEFS      = @DLLFLAGS@ -D__WINE__
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+MODULE    = winaspi
+
+C_SRCS = \
+	winaspi16.c
+
+all: $(MODULE).o
+
+@MAKE_RULES@
+
+### Dependencies:
diff --git a/dlls/winaspi/winaspi16.c b/dlls/winaspi/winaspi16.c
new file mode 100644
index 0000000..4a6c3fd
--- /dev/null
+++ b/dlls/winaspi/winaspi16.c
@@ -0,0 +1,492 @@
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <ldt.h>
+#include <memory.h>
+#include <unistd.h>
+#include <callback.h>
+#include "windows.h"
+#include "aspi.h"
+#include "winaspi.h"
+#include "options.h"
+#include "heap.h"
+#include "debug.h"
+#include "selectors.h"
+#include "module.h"
+#include "miscemu.h"
+
+
+/* FIXME!
+ * 1) Residual byte length reporting not handled
+ * 2) Make this code re-entrant for multithreading
+ * 3) Only linux supported so far
+ */
+
+#ifdef linux
+static int
+ASPI_OpenDevice16(SRB_ExecSCSICmd16 *prb)
+{
+    int	fd;
+    char	idstr[20];
+    char	device_str[50];
+    ASPI_DEVICE_INFO *curr;
+
+    /* search list of devices to see if we've opened it already.
+     * There is not an explicit open/close in ASPI land, so hopefully
+     * keeping a device open won't be a problem.
+     */
+
+    for (curr = ASPI_open_devices; curr; curr = curr->next) {
+	if (curr->hostId == prb->SRB_HaId &&
+	    curr->target == prb->SRB_Target &&
+	    curr->lun == prb->SRB_Lun) {
+	    return curr->fd;
+	}
+    }
+
+    /* device wasn't cached, go ahead and open it */
+    sprintf(idstr, "scsi c%1dt%1dd%1d", prb->SRB_HaId, prb->SRB_Target, prb->SRB_Lun);
+
+    if (!PROFILE_GetWineIniString(idstr, "Device", "", device_str, sizeof(device_str))) {
+	TRACE(aspi, "Trying to open unlisted scsi device %s\n", idstr);
+	return -1;
+    }
+
+    TRACE(aspi, "Opening device %s=%s\n", idstr, device_str);
+
+    fd = open(device_str, O_RDWR);
+    if (fd == -1) {
+	int save_error = errno;
+	ERR(aspi, "Error opening device %s, errno=%d\n", device_str, save_error);
+	return -1;
+    }
+
+    /* device is now open */
+    curr = HeapAlloc( SystemHeap, 0, sizeof(ASPI_DEVICE_INFO) );
+    curr->fd = fd;
+    curr->hostId = prb->SRB_HaId;
+    curr->target = prb->SRB_Target;
+    curr->lun = prb->SRB_Lun;
+
+    /* insert new record at beginning of open device list */
+    curr->next = ASPI_open_devices;
+    ASPI_open_devices = curr;
+    return fd;
+}
+
+
+static void
+ASPI_DebugPrintCmd(SRB_ExecSCSICmd16 *prb, UINT16 mode)
+{
+  BYTE	cmd;
+  int	i;
+  BYTE *cdb;
+  BYTE *lpBuf = 0;
+  dbg_decl_str(aspi, 512);
+
+  switch (mode)
+  {
+      case ASPI_DOS:
+	/* translate real mode address */
+	if (prb->SRB_BufPointer)
+	    lpBuf = (BYTE *)DOSMEM_MapRealToLinear((UINT32)prb->SRB_BufPointer);
+	break;
+      case ASPI_WIN16:
+	lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
+	break;
+  }
+
+  switch (prb->CDBByte[0]) {
+  case CMD_INQUIRY:
+    TRACE(aspi, "{\n");
+    TRACE(aspi, "\tEVPD: %d\n", prb->CDBByte[1] & 1);
+    TRACE(aspi, "\tLUN: %d\n", (prb->CDBByte[1] & 0xc) >> 1);
+    TRACE(aspi, "\tPAGE CODE: %d\n", prb->CDBByte[2]);
+    TRACE(aspi, "\tALLOCATION LENGTH: %d\n", prb->CDBByte[4]);
+    TRACE(aspi, "\tCONTROL: %d\n", prb->CDBByte[5]);
+    TRACE(aspi, "}\n");
+    break;
+  case CMD_SCAN_SCAN:
+    TRACE(aspi, "Transfer Length: %d\n", prb->CDBByte[4]);
+    break;
+  }
+
+  TRACE(aspi, "Host Adapter: %d\n", prb->SRB_HaId);
+  TRACE(aspi, "Flags: %d\n", prb->SRB_Flags);
+  if (TARGET_TO_HOST(prb)) {
+    TRACE(aspi, "\tData transfer: Target to host. Length checked.\n");
+  }
+  else if (HOST_TO_TARGET(prb)) {
+    TRACE(aspi, "\tData transfer: Host to target. Length checked.\n");
+  }
+  else if (NO_DATA_TRANSFERED(prb)) {
+    TRACE(aspi, "\tData transfer: none\n");
+  }
+  else {
+    WARN(aspi, "\tTransfer by scsi cmd. Length not checked\n");
+  }
+
+  TRACE(aspi, "\tResidual byte length reporting %s\n", prb->SRB_Flags & 0x4 ? "enabled" : "disabled");
+  TRACE(aspi, "\tLinking %s\n", prb->SRB_Flags & 0x2 ? "enabled" : "disabled");
+  TRACE(aspi, "\tPosting %s\n", prb->SRB_Flags & 0x1 ? "enabled" : "disabled");
+  TRACE(aspi, "Target: %d\n", prb->SRB_Target);
+  TRACE(aspi, "Lun: %d\n", prb->SRB_Lun);
+  TRACE(aspi, "BufLen: %ld\n", prb->SRB_BufLen);
+  TRACE(aspi, "SenseLen: %d\n", prb->SRB_SenseLen);
+  TRACE(aspi, "BufPtr: %lx (%p)\n", prb->SRB_BufPointer, lpBuf);
+  TRACE(aspi, "LinkPointer %lx\n", prb->SRB_Rsvd1);
+  TRACE(aspi, "CDB Length: %d\n", prb->SRB_CDBLen);
+  TRACE(aspi, "POST Proc: %lx\n", (DWORD) prb->SRB_PostProc);
+  cdb = &prb->CDBByte[0];
+  cmd = prb->CDBByte[0];
+  for (i = 0; i < prb->SRB_CDBLen; i++) {
+    if (i != 0) dsprintf(aspi, ",");
+    dsprintf(aspi, "%02x", *cdb++);
+  }
+  TRACE(aspi, "CDB buffer[%s]\n", dbg_str(aspi));
+}
+
+static void
+ASPI_PrintSenseArea16(SRB_ExecSCSICmd16 *prb)
+{
+  int	i;
+  BYTE *cdb;
+  dbg_decl_str(aspi, 512);
+
+  cdb = &prb->CDBByte[0];
+  for (i = 0; i < prb->SRB_SenseLen; i++) {
+    if (i) dsprintf(aspi, ",");
+    dsprintf(aspi, "%02x", *cdb++);
+  }
+  TRACE(aspi, "SenseArea[%s]\n", dbg_str(aspi));
+}
+
+static void
+ASPI_DebugPrintResult(SRB_ExecSCSICmd16 *prb, UINT16 mode)
+{
+  BYTE *lpBuf = 0;
+
+  switch (mode)
+  {
+      case ASPI_DOS:
+	/* translate real mode address */
+	if (prb->SRB_BufPointer)
+	    lpBuf = (BYTE *)DOSMEM_MapRealToLinear((UINT32)prb->SRB_BufPointer);
+	break;
+      case ASPI_WIN16:
+	lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
+	break;
+  }
+
+  switch (prb->CDBByte[0]) {
+  case CMD_INQUIRY:
+    TRACE(aspi, "Vendor: '%s'\n", lpBuf + INQUIRY_VENDOR);
+    break;
+  case CMD_TEST_UNIT_READY:
+    ASPI_PrintSenseArea16(prb);
+    break;
+  }
+}
+
+static WORD
+ASPI_ExecScsiCmd(DWORD ptrPRB, UINT16 mode)
+{
+  SRB_ExecSCSICmd16 *lpPRB = 0;
+  struct sg_header *sg_hd, *sg_reply_hdr;
+  int	status;
+  BYTE *lpBuf = 0;
+  int	in_len, out_len;
+  int	error_code = 0;
+  int	fd;
+
+  switch (mode)
+  {
+      case ASPI_DOS:
+	if (ptrPRB)
+	    lpPRB = (SRB_ExecSCSICmd16 *)DOSMEM_MapRealToLinear(ptrPRB);
+	break;
+      case ASPI_WIN16:
+	lpPRB = PTR_SEG_TO_LIN(ptrPRB);
+	break;
+  }
+
+  ASPI_DebugPrintCmd(lpPRB, mode);
+
+  fd = ASPI_OpenDevice16(lpPRB);
+  if (fd == -1) {
+      ERR(aspi, "Failed: could not open device. Device permissions !?\n");
+      lpPRB->SRB_Status = SS_ERR;
+      return SS_ERR;
+  }
+
+  sg_hd = NULL;
+  sg_reply_hdr = NULL;
+
+  lpPRB->SRB_Status = SS_PENDING;
+
+  switch (mode)
+  {
+      case ASPI_DOS:
+	/* translate real mode address */
+	if (ptrPRB)
+	    lpBuf = (BYTE *)DOSMEM_MapRealToLinear((UINT32)lpPRB->SRB_BufPointer);
+	break;
+      case ASPI_WIN16:
+	lpBuf = PTR_SEG_TO_LIN(lpPRB->SRB_BufPointer);
+	break;
+  }
+
+  if (!lpPRB->SRB_CDBLen) {
+      WARN(aspi, "Failed: lpPRB->SRB_CDBLen = 0.\n");
+      lpPRB->SRB_Status = SS_ERR;
+      return SS_ERR;
+  }
+
+  /* build up sg_header + scsi cmd */
+  if (HOST_TO_TARGET(lpPRB)) {
+    /* send header, command, and then data */
+    in_len = SCSI_OFF + lpPRB->SRB_CDBLen + lpPRB->SRB_BufLen;
+    sg_hd = (struct sg_header *) malloc(in_len);
+    memset(sg_hd, 0, SCSI_OFF);
+    memcpy(sg_hd + 1, &lpPRB->CDBByte[0], lpPRB->SRB_CDBLen);
+    if (lpPRB->SRB_BufLen) {
+      memcpy(((BYTE *) sg_hd) + SCSI_OFF + lpPRB->SRB_CDBLen, lpBuf, lpPRB->SRB_BufLen);
+    }
+  }
+  else {
+    /* send header and command - no data */
+    in_len = SCSI_OFF + lpPRB->SRB_CDBLen;
+    sg_hd = (struct sg_header *) malloc(in_len);
+    memset(sg_hd, 0, SCSI_OFF);
+    memcpy(sg_hd + 1, &lpPRB->CDBByte[0], lpPRB->SRB_CDBLen);
+  }
+
+  if (TARGET_TO_HOST(lpPRB)) {
+    out_len = SCSI_OFF + lpPRB->SRB_BufLen;
+    sg_reply_hdr = (struct sg_header *) malloc(out_len);
+    memset(sg_reply_hdr, 0, SCSI_OFF);
+    sg_hd->reply_len = out_len;
+  }
+  else {
+    out_len = SCSI_OFF;
+    sg_reply_hdr = (struct sg_header *) malloc(out_len);
+    memset(sg_reply_hdr, 0, SCSI_OFF);
+    sg_hd->reply_len = out_len;
+  }
+
+  status = write(fd, sg_hd, in_len);
+  if (status < 0 || status != in_len) {
+      int myerror = errno;
+
+    WARN(aspi, "Not enough bytes written to scsi device bytes=%d .. %d\n", in_len, status);
+    if (status < 0) {
+	if (myerror == ENOMEM) {
+	    MSG("ASPI: Linux generic scsi driver\n  You probably need to re-compile your kernel with a larger SG_BIG_BUFF value (sg.h)\n  Suggest 130560\n");
+	}
+	WARN(aspi, "errno: = %d\n", myerror);
+    }
+    goto error_exit;
+  }
+
+  status = read(fd, sg_reply_hdr, out_len);
+  if (status < 0 || status != out_len) {
+    WARN(aspi, "not enough bytes read from scsi device%d\n", status);
+    goto error_exit;
+  }
+
+  if (sg_reply_hdr->result != 0) {
+    error_code = sg_reply_hdr->result;
+    WARN(aspi, "reply header error (%d)\n", sg_reply_hdr->result);
+    goto error_exit;
+  }
+
+  if (TARGET_TO_HOST(lpPRB) && lpPRB->SRB_BufLen) {
+    memcpy(lpBuf, sg_reply_hdr + 1, lpPRB->SRB_BufLen);
+  }
+
+  /* copy in sense buffer to amount that is available in client */
+  if (lpPRB->SRB_SenseLen) {
+    int sense_len = lpPRB->SRB_SenseLen;
+    if (lpPRB->SRB_SenseLen > 16)
+      sense_len = 16;
+    memcpy(SENSE_BUFFER(lpPRB), &sg_reply_hdr->sense_buffer[0], sense_len);
+  }
+
+
+  lpPRB->SRB_Status = SS_COMP;
+  lpPRB->SRB_HaStat = HASTAT_OK;
+  lpPRB->SRB_TargStat = STATUS_GOOD;
+
+  /* now do posting */
+
+  if (ASPI_POSTING(lpPRB) && lpPRB->SRB_PostProc) {
+    TRACE(aspi, "Post Routine (%lx) called\n", (DWORD) lpPRB->SRB_PostProc);
+    switch (mode)
+    {
+      case ASPI_DOS:
+      {
+	SEGPTR spPRB = MapLS(lpPRB);
+
+	Callbacks->CallASPIPostProc(lpPRB->SRB_PostProc, spPRB);	
+	UnMapLS(spPRB);
+	break;
+      }
+      case ASPI_WIN16:
+        Callbacks->CallASPIPostProc(lpPRB->SRB_PostProc, ptrPRB);
+	break;
+    }
+  }
+
+  free(sg_reply_hdr);
+  free(sg_hd);
+  ASPI_DebugPrintResult(lpPRB, mode);
+  return SS_COMP;
+  
+error_exit:
+  if (error_code == EBUSY) {
+      lpPRB->SRB_Status = SS_ASPI_IS_BUSY;
+      TRACE(aspi, "Device busy\n");
+  }
+  else {
+      WARN(aspi, "Failed\n");
+      lpPRB->SRB_Status = SS_ERR;
+  }
+
+  /* I'm not sure exactly error codes work here
+   * We probably should set lpPRB->SRB_TargStat, SRB_HaStat ?
+   */
+  WARN(aspi, "error_exit\n");
+  free(sg_reply_hdr);
+  free(sg_hd);
+  return lpPRB->SRB_Status;
+}
+#endif
+
+
+/***********************************************************************
+ *             GetASPISupportInfo16   (WINASPI.1)
+ */
+
+WORD WINAPI GetASPISupportInfo16()
+{
+#ifdef linux
+    TRACE(aspi, "GETASPISupportInfo16\n");
+    /* high byte SS_COMP - low byte number of host adapters.
+     * FIXME!!! The number of host adapters is incorrect.
+     * I'm not sure how to determine this under linux etc.
+     */
+    return ((SS_COMP << 8) | 1);
+#else
+    return ((SS_COMP << 8) | 0);
+#endif
+}
+
+
+DWORD ASPI_SendASPICommand(DWORD ptrSRB, UINT16 mode)
+{
+#ifdef linux
+  LPSRB16 lpSRB = 0;
+
+  switch (mode)
+  {
+      case ASPI_DOS:
+	if (ptrSRB)
+	    lpSRB = (LPSRB16)DOSMEM_MapRealToLinear(ptrSRB);
+	break;
+      case ASPI_WIN16:
+	lpSRB = PTR_SEG_TO_LIN(ptrSRB);
+	break;
+  }
+
+  switch (lpSRB->common.SRB_Cmd) {
+  case SC_HA_INQUIRY:
+    lpSRB->inquiry.SRB_Status = SS_COMP;       /* completed successfully */
+    if (lpSRB->inquiry.SRB_55AASignature == 0x55aa) {
+	TRACE(aspi, "Extended request detected (Adaptec's ASPIxDOS).\nWe don't support it at the moment.\n");
+    }
+    lpSRB->inquiry.SRB_ExtBufferSize = 0x2000; /* bogus value */
+    lpSRB->inquiry.HA_Count = 1;               /* not always */
+    lpSRB->inquiry.HA_SCSI_ID = 7;             /* not always ID 7 */
+    strcat(lpSRB->inquiry.HA_ManagerId, "Wine ASPI16"); /* max 15 chars */
+    strcat(lpSRB->inquiry.HA_Identifier, "Wine host"); /* FIXME: return host
+adapter name */
+    memset(lpSRB->inquiry.HA_Unique, 0, 16); /* default HA_Unique content */
+    lpSRB->inquiry.HA_Unique[6] = 0x02; /* Maximum Transfer Length (128K, Byte> 4-7) */
+    FIXME(aspi, "ASPI: Partially implemented SC_HA_INQUIRY for adapter %d.\n", lpSRB->inquiry.SRB_HaId);
+    return SS_COMP;
+  case SC_GET_DEV_TYPE:
+    FIXME(aspi, "Not implemented SC_GET_DEV_TYPE\n");
+    break;
+  case SC_EXEC_SCSI_CMD:
+    return ASPI_ExecScsiCmd((DWORD)ptrSRB, mode);
+    break;
+  case SC_RESET_DEV:
+    FIXME(aspi, "Not implemented SC_RESET_DEV\n");
+    break;
+  default:
+    WARN(aspi, "Unknown command %d\n", lpSRB->common.SRB_Cmd);
+  }
+  return SS_INVALID_SRB;
+#else
+  return SS_INVALID_SRB;
+#endif
+}
+
+
+/***********************************************************************
+ *             SendASPICommand16   (WINASPI.2)
+ */
+WORD WINAPI SendASPICommand16(SEGPTR segptr_srb)
+{
+#ifdef linux
+    return ASPI_SendASPICommand(segptr_srb, ASPI_WIN16);
+#else
+    return 0; 
+#endif
+}
+
+
+/***********************************************************************
+ *             GetASPIDLLVersion16   (WINASPI.4)
+ */
+
+DWORD WINAPI GetASPIDLLVersion16()
+{
+#ifdef linux
+	return (DWORD)2;
+#else
+	return (DWORD)0;
+#endif
+}
+
+
+void WINAPI ASPI_DOS_func(DWORD srb)
+{
+       ASPI_SendASPICommand(srb, ASPI_DOS);
+}
+
+
+/* returns a real mode call address to ASPI_DOS_func() */
+void ASPI_DOS_HandleInt(CONTEXT *context)
+{
+#ifdef linux
+       FARPROC16 DOS_func;
+       DWORD dos;
+       LPBYTE dosptr;
+
+       DOS_func = MODULE_GetWndProcEntry16("ASPI_DOS_func");
+       dos = GlobalDOSAlloc(5);
+       dosptr = (BYTE *)PTR_SEG_OFF_TO_LIN(LOWORD(dos), 0);
+       *dosptr++ = 0xea; /* ljmp */
+       *(FARPROC16 *)dosptr = DOS_func;
+
+       *(DWORD *)PTR_SEG_OFF_TO_LIN(DS_reg(context), DX_reg(context))
+               = MAKELONG(0, HIWORD(dos)); /* real mode address */
+       RESET_CFLAG(context);
+       AX_reg(context) = CX_reg(context);
+#else
+       SET_CFLAG(context);
+#endif
+}
diff --git a/dlls/wnaspi32/Makefile.in b/dlls/wnaspi32/Makefile.in
new file mode 100644
index 0000000..1bf2b9b
--- /dev/null
+++ b/dlls/wnaspi32/Makefile.in
@@ -0,0 +1,15 @@
+DEFS      = @DLLFLAGS@ -D__WINE__
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+MODULE    = wnaspi32
+
+C_SRCS = \
+	winaspi32.c
+
+all: $(MODULE).o
+
+@MAKE_RULES@
+
+### Dependencies:
diff --git a/dlls/wnaspi32/winaspi32.c b/dlls/wnaspi32/winaspi32.c
new file mode 100644
index 0000000..5447f8d
--- /dev/null
+++ b/dlls/wnaspi32/winaspi32.c
@@ -0,0 +1,373 @@
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <ldt.h>
+#include <memory.h>
+#include <unistd.h>
+#include <callback.h>
+#include "windows.h"
+#include "aspi.h"
+#include "wnaspi32.h"
+#include "options.h"
+#include "heap.h"
+#include "debug.h"
+#include "selectors.h"
+#include "module.h"
+#include "miscemu.h"
+
+
+/* FIXME!
+ * 1) Residual byte length reporting not handled
+ * 2) Make this code re-entrant for multithreading
+ * 3) Only linux supported so far
+ */
+
+#ifdef linux
+static int
+ASPI_OpenDevice32(SRB_ExecSCSICmd32 *prb)
+{
+    int	fd;
+    char	idstr[20];
+    char	device_str[50];
+    ASPI_DEVICE_INFO *curr;
+
+    /* search list of devices to see if we've opened it already.
+     * There is not an explicit open/close in ASPI land, so hopefully
+     * keeping a device open won't be a problem.
+     */
+
+    for (curr = ASPI_open_devices; curr; curr = curr->next) {
+	if (curr->hostId == prb->SRB_HaId &&
+	    curr->target == prb->SRB_Target &&
+	    curr->lun == prb->SRB_Lun) {
+	    return curr->fd;
+	}
+    }
+
+    /* device wasn't cached, go ahead and open it */
+    sprintf(idstr, "scsi c%1dt%1dd%1d", prb->SRB_HaId, prb->SRB_Target, prb->SRB_Lun);
+
+    if (!PROFILE_GetWineIniString(idstr, "Device", "", device_str, sizeof(device_str))) {
+	TRACE(aspi, "Trying to open unlisted scsi device %s\n", idstr);
+	return -1;
+    }
+
+    TRACE(aspi, "Opening device %s=%s\n", idstr, device_str);
+
+    fd = open(device_str, O_RDWR);
+    if (fd == -1) {
+	int save_error = errno;
+	ERR(aspi, "Error opening device %s, errno=%d\n", device_str, save_error);
+	return -1;
+    }
+
+    /* device is now open */
+    curr = HeapAlloc( SystemHeap, 0, sizeof(ASPI_DEVICE_INFO) );
+    curr->fd = fd;
+    curr->hostId = prb->SRB_HaId;
+    curr->target = prb->SRB_Target;
+    curr->lun = prb->SRB_Lun;
+
+    /* insert new record at beginning of open device list */
+    curr->next = ASPI_open_devices;
+    ASPI_open_devices = curr;
+    return fd;
+}
+
+
+static void
+ASPI_DebugPrintCmd32(SRB_ExecSCSICmd32 *prb)
+{
+  BYTE	cmd;
+  int	i;
+  BYTE *cdb;
+  dbg_decl_str(aspi, 512);
+
+  switch (prb->CDBByte[0]) {
+  case CMD_INQUIRY:
+    TRACE(aspi, "{\n");
+    TRACE(aspi, "\tEVPD: %d\n", prb->CDBByte[1] & 1);
+    TRACE(aspi, "\tLUN: %d\n", (prb->CDBByte[1] & 0xc) >> 1);
+    TRACE(aspi, "\tPAGE CODE: %d\n", prb->CDBByte[2]);
+    TRACE(aspi, "\tALLOCATION LENGTH: %d\n", prb->CDBByte[4]);
+    TRACE(aspi, "\tCONTROL: %d\n", prb->CDBByte[5]);
+    TRACE(aspi, "}\n");
+    break;
+  case CMD_SCAN_SCAN:
+    TRACE(aspi, "Transfer Length: %d\n", prb->CDBByte[4]);
+    break;
+  }
+
+  TRACE(aspi, "Host Adapter: %d\n", prb->SRB_HaId);
+  TRACE(aspi, "Flags: %d\n", prb->SRB_Flags);
+  if (TARGET_TO_HOST(prb)) {
+    TRACE(aspi, "\tData transfer: Target to host. Length checked.\n");
+  }
+  else if (HOST_TO_TARGET(prb)) {
+    TRACE(aspi, "\tData transfer: Host to target. Length checked.\n");
+  }
+  else if (NO_DATA_TRANSFERED(prb)) {
+    TRACE(aspi, "\tData transfer: none\n");
+  }
+  else {
+    WARN(aspi, "\tTransfer by scsi cmd. Length not checked.\n");
+  }
+
+  TRACE(aspi, "\tResidual byte length reporting %s\n", prb->SRB_Flags & 0x4 ? "enabled" : "disabled");
+  TRACE(aspi, "\tLinking %s\n", prb->SRB_Flags & 0x2 ? "enabled" : "disabled");
+  TRACE(aspi, "\tPosting %s\n", prb->SRB_Flags & 0x1 ? "enabled" : "disabled");
+  TRACE(aspi, "Target: %d\n", prb->SRB_Target);
+  TRACE(aspi, "Lun: %d\n", prb->SRB_Lun);
+  TRACE(aspi, "BufLen: %ld\n", prb->SRB_BufLen);
+  TRACE(aspi, "SenseLen: %d\n", prb->SRB_SenseLen);
+  TRACE(aspi, "BufPtr: %p\n", prb->SRB_BufPointer);
+  TRACE(aspi, "CDB Length: %d\n", prb->SRB_CDBLen);
+  TRACE(aspi, "POST Proc: %lx\n", (DWORD) prb->SRB_PostProc);
+  cdb = &prb->CDBByte[0];
+  cmd = prb->CDBByte[0];
+  for (i = 0; i < prb->SRB_CDBLen; i++) {
+    if (i != 0) dsprintf(aspi, ",");
+    dsprintf(aspi, "%02x", *cdb++);
+  }
+  TRACE(aspi, "CDB buffer[%s]\n", dbg_str(aspi));
+}
+
+static void
+ASPI_PrintSenseArea32(SRB_ExecSCSICmd32 *prb)
+{
+  int	i;
+  BYTE *cdb;
+  dbg_decl_str(aspi, 512);
+
+  cdb = &prb->CDBByte[0];
+  for (i = 0; i < prb->SRB_SenseLen; i++) {
+    if (i) dsprintf(aspi, ",");
+    dsprintf(aspi, "%02x", *cdb++);
+  }
+  TRACE(aspi, "SenseArea[%s]\n", dbg_str(aspi));
+}
+
+static void
+ASPI_DebugPrintResult32(SRB_ExecSCSICmd32 *prb)
+{
+
+  switch (prb->CDBByte[0]) {
+  case CMD_INQUIRY:
+    TRACE(aspi, "Vendor: '%s'\n", prb->SRB_BufPointer + INQUIRY_VENDOR);
+    break;
+  case CMD_TEST_UNIT_READY:
+    ASPI_PrintSenseArea32(prb);
+    break;
+  }
+}
+
+static WORD
+ASPI_ExecScsiCmd32(SRB_ExecSCSICmd32 *lpPRB)
+{
+  struct sg_header *sg_hd, *sg_reply_hdr;
+  int	status;
+  int	in_len, out_len;
+  int	error_code = 0;
+  int	fd;
+
+  ASPI_DebugPrintCmd32(lpPRB);
+
+  fd = ASPI_OpenDevice32(lpPRB);
+  if (fd == -1) {
+      ERR(aspi, "Failed: could not open device. Device permissions !?\n");
+      lpPRB->SRB_Status = SS_ERR;
+      return SS_ERR;
+  }
+
+  sg_hd = NULL;
+  sg_reply_hdr = NULL;
+
+  lpPRB->SRB_Status = SS_PENDING;
+
+  if (!lpPRB->SRB_CDBLen) {
+      WARN(aspi, "Failed: lpPRB->SRB_CDBLen = 0.\n");
+      lpPRB->SRB_Status = SS_ERR;
+      return SS_ERR;
+  }
+
+  /* build up sg_header + scsi cmd */
+  if (HOST_TO_TARGET(lpPRB)) {
+    /* send header, command, and then data */
+    in_len = SCSI_OFF + lpPRB->SRB_CDBLen + lpPRB->SRB_BufLen;
+    sg_hd = (struct sg_header *) malloc(in_len);
+    memset(sg_hd, 0, SCSI_OFF);
+    memcpy(sg_hd + 1, &lpPRB->CDBByte[0], lpPRB->SRB_CDBLen);
+    if (lpPRB->SRB_BufLen) {
+      memcpy(((BYTE *) sg_hd) + SCSI_OFF + lpPRB->SRB_CDBLen, lpPRB->SRB_BufPointer, lpPRB->SRB_BufLen);
+    }
+  }
+  else {
+    /* send header and command - no data */
+    in_len = SCSI_OFF + lpPRB->SRB_CDBLen;
+    sg_hd = (struct sg_header *) malloc(in_len);
+    memset(sg_hd, 0, SCSI_OFF);
+    memcpy(sg_hd + 1, &lpPRB->CDBByte[0], lpPRB->SRB_CDBLen);
+  }
+
+  if (TARGET_TO_HOST(lpPRB)) {
+    out_len = SCSI_OFF + lpPRB->SRB_BufLen;
+    sg_reply_hdr = (struct sg_header *) malloc(out_len);
+    memset(sg_reply_hdr, 0, SCSI_OFF);
+    sg_hd->reply_len = out_len;
+  }
+  else {
+    out_len = SCSI_OFF;
+    sg_reply_hdr = (struct sg_header *) malloc(out_len);
+    memset(sg_reply_hdr, 0, SCSI_OFF);
+    sg_hd->reply_len = out_len;
+  }
+
+  status = write(fd, sg_hd, in_len);
+  if (status < 0 || status != in_len) {
+      int myerror = errno;
+
+    WARN(aspi, "Not enough bytes written to scsi device bytes=%d .. %d\n", in_len, status);
+    if (status < 0) {
+	if (myerror == ENOMEM) {
+	    MSG("ASPI: Linux generic scsi driver\n  You probably need to re-compile your kernel with a larger SG_BIG_BUFF value (sg.h)\n  Suggest 130560\n");
+	}
+	WARN(aspi, "errno: = %d\n", myerror);
+    }
+    goto error_exit;
+  }
+
+  status = read(fd, sg_reply_hdr, out_len);
+  if (status < 0 || status != out_len) {
+    WARN(aspi, "not enough bytes read from scsi device%d\n", status);
+    goto error_exit;
+  }
+
+  if (sg_reply_hdr->result != 0) {
+    error_code = sg_reply_hdr->result;
+    WARN(aspi, "reply header error (%d)\n", sg_reply_hdr->result);
+    goto error_exit;
+  }
+
+  if (TARGET_TO_HOST(lpPRB) && lpPRB->SRB_BufLen) {
+    memcpy(lpPRB->SRB_BufPointer, sg_reply_hdr + 1, lpPRB->SRB_BufLen);
+  }
+
+  /* copy in sense buffer to amount that is available in client */
+  if (lpPRB->SRB_SenseLen) {
+    int sense_len = lpPRB->SRB_SenseLen;
+    if (lpPRB->SRB_SenseLen > 16)
+      sense_len = 16;
+    memcpy(SENSE_BUFFER(lpPRB), &sg_reply_hdr->sense_buffer[0], sense_len);
+  }
+
+
+  lpPRB->SRB_Status = SS_COMP;
+  lpPRB->SRB_HaStat = HASTAT_OK;
+  lpPRB->SRB_TargStat = STATUS_GOOD;
+
+  /* now do posting */
+
+  if (lpPRB->SRB_PostProc) {
+    if (ASPI_POSTING(lpPRB)) {
+      TRACE(aspi, "Post Routine (%lx) called\n", (DWORD) lpPRB->SRB_PostProc);
+      (*lpPRB->SRB_PostProc)(lpPRB);
+    }
+    else
+    if (lpPRB->SRB_Flags & SRB_EVENT_NOTIFY) {
+      TRACE(aspi, "Setting event %04x\n", (HANDLE32)lpPRB->SRB_PostProc);
+      SetEvent((HANDLE32)lpPRB->SRB_PostProc); /* FIXME: correct ? */
+    }
+  }
+  free(sg_reply_hdr);
+  free(sg_hd);
+  ASPI_DebugPrintResult32(lpPRB);
+  return SS_COMP;
+  
+error_exit:
+  if (error_code == EBUSY) {
+      lpPRB->SRB_Status = SS_ASPI_IS_BUSY;
+      TRACE(aspi, "Device busy\n");
+  }
+  else {
+      WARN(aspi, "Failed\n");
+      lpPRB->SRB_Status = SS_ERR;
+  }
+
+  /* I'm not sure exactly error codes work here
+   * We probably should set lpPRB->SRB_TargStat, SRB_HaStat ?
+   */
+  WARN(aspi, "error_exit\n");
+  free(sg_reply_hdr);
+  free(sg_hd);
+  return lpPRB->SRB_Status;
+}
+#endif
+
+
+/*******************************************************************
+ *     GetASPI32SupportInfo32		[WNASPI32.0]
+ *
+ * Checks if the ASPI subsystem is initialized correctly.
+ *
+ * RETURNS
+ *    HIWORD: 0.
+ *    HIBYTE of LOWORD: status (SS_COMP or SS_FAILED_INIT)
+ *    LOBYTE of LOWORD: # of host adapters.  
+ */
+DWORD WINAPI GetASPI32SupportInfo32()
+{
+    return ((SS_COMP << 8) | 1); /* FIXME: get # of host adapters installed */
+}
+
+
+/***********************************************************************
+ *             SendASPI32Command32 (WNASPI32.1)
+ */
+DWORD WINAPI SendASPI32Command32(LPSRB32 lpSRB)
+{
+#ifdef linux
+  switch (lpSRB->common.SRB_Cmd) {
+  case SC_HA_INQUIRY:
+    lpSRB->inquiry.SRB_Status = SS_COMP;       /* completed successfully */
+    lpSRB->inquiry.HA_Count = 1;               /* not always */
+    lpSRB->inquiry.HA_SCSI_ID = 7;             /* not always ID 7 */
+    strcat(lpSRB->inquiry.HA_ManagerId, "ASPI for WIN32"); /* max 15 chars, don't change */
+    strcat(lpSRB->inquiry.HA_Identifier, "Wine host"); /* FIXME: return host adapter name */
+    memset(lpSRB->inquiry.HA_Unique, 0, 16); /* default HA_Unique content */
+    lpSRB->inquiry.HA_Unique[6] = 0x02; /* Maximum Transfer Length (128K, Byte> 4-7) */
+    FIXME(aspi, "ASPI: Partially implemented SC_HA_INQUIRY for adapter %d.\n", lpSRB->inquiry.SRB_HaId);
+    return SS_COMP;
+  case SC_GET_DEV_TYPE:
+    FIXME(aspi, "Not implemented SC_GET_DEV_TYPE\n");
+    break;
+  case SC_EXEC_SCSI_CMD:
+    return ASPI_ExecScsiCmd32(&lpSRB->cmd);
+    break;
+  case SC_RESET_DEV:
+    FIXME(aspi, "Not implemented SC_RESET_DEV\n");
+    break;
+  default:
+    WARN(aspi, "Unknown command %d\n", lpSRB->common.SRB_Cmd);
+  }
+  return SS_INVALID_SRB;
+#else
+  return SS_INVALID_SRB;
+#endif
+}
+
+
+/***********************************************************************
+ *             GetASPI32DLLVersion32   (WNASPI32.3)
+ */
+
+DWORD WINAPI GetASPI32DLLVersion32()
+{
+#ifdef linux
+        return (DWORD)1;
+#else
+        return (DWORD)0;
+#endif
+}
+
diff --git a/documentation/Makefile.in b/documentation/Makefile.in
index fb551bd..5e1e589 100644
--- a/documentation/Makefile.in
+++ b/documentation/Makefile.in
@@ -50,6 +50,7 @@
 	for i in $(INCLUDES); do $(LN_S) $(TOPSRCDIR)/$$i $$i || exit 1; done
 
 install:: 
+	[ -d $(mandir) ] || mkdir -p $(mandir)
 	$(INSTALL_DATA) $(SRCDIR)/wine.man $(mandir)/wine$(manext)
 
 uninstall::
@@ -57,6 +58,7 @@
 
 # Not done by default because of makeinfo bugs
 install_info: $(INFOFILES)
+	[ -d $(infodir) ] || mkdir -p $(infodir)
 	for i in $(INFOFILES); do $(INSTALL_DATA) $$i $(infodir)/$$i; done
 
 uninstall_info:
diff --git a/documentation/cdrom-labels b/documentation/cdrom-labels
index 36297c5..a2f2bca 100644
--- a/documentation/cdrom-labels
+++ b/documentation/cdrom-labels
@@ -1,3 +1,5 @@
+*** VOLUME LABEL
+
 If a program depends on the correct label and/or serial number for the
 CD-Rom, you can use the following command to extract that information:
 
@@ -8,6 +10,8 @@
 wine.ini/.winerc file like:
 Label=<the label>
 
+*** SERIAL NUMBER
+
 [FIXME: if someone knows how to get the serial number in Linux, please
         put this information here].
 
@@ -39,4 +43,18 @@
     }
     return 0;
 }
+
+Probably you can get that information also from the File Manager in
+Windows.
+
 ------------------------- end volinfo.c -----------------------------
+
+
+*** DRIVE LETTER
+
+Some installed programs only look for the CD-Rom in the drive letter
+that the CD-Rom had when the program was installed. In this case, make
+sure you use the correct letter, especially if you installed the
+program under Windows and are now trying to run it in Wine.
+Some programs reportedly store the drive letter in their .INI file,
+so you might look there and try to change it.
diff --git a/documentation/common_controls b/documentation/common_controls
index 69c2c9f..13d11bd 100644
--- a/documentation/common_controls
+++ b/documentation/common_controls
@@ -36,7 +36,7 @@
       Dummy written by Eric Kohl. <ekohl@abo.rhein-zeitung.de>
 
   Status:
-      - Dummy control. No functionality.
+      Dummy control. No functionality.
 
   Notes:
       Author needed!! Any volunteers??
@@ -48,7 +48,7 @@
       Dummy written by Eric Kohl. <ekohl@abo.rhein-zeitung.de>
 
   Status:
-      - Dummy control. No functionality.
+      Dummy control. No functionality.
 
   Notes:
       Author needed!! Any volunteers??
@@ -57,7 +57,7 @@
 3.3 Date and Time Picker Control
 --------------------------------
   Status:
-      - Nothing done at all.
+      Nothing done at all.
 
   Notes:
       Author needed!! Any volunteers??
@@ -66,7 +66,7 @@
 3.4 Drag List Box Control
 -------------------------
   Status:
-      - Nothing done at all.
+      Nothing done at all.
 
   Notes:
       Author needed!! Any volunteers??
@@ -75,7 +75,7 @@
 3.5 Flat Scroll Bar Control
 ---------------------------
   Status:
-      - Nothing done at all.
+      Nothing done at all.
 
   Notes:
       Author needed!! Any volunteers??
@@ -87,7 +87,7 @@
       Eric Kohl <ekohl@abo.rhein-zeitung.de>
 
   Status:
-      - Almost finished.
+      Almost finished.
 
 
 3.7 Hot Key Control
@@ -108,18 +108,13 @@
       Eric Kohl <ekohl@abo.rhein-zeitung.de>
 
   Status:
-      - Almost finished.
-
-  Notes:
-      Most of my test programs work as expected. But when image lists are used
-      in other controls (e.g. Toolbar) they don't seem to be error-free.
-      It looks like I have to do a major re-write (use DIB's instead of DDB's).
+      Almost finished.
 
 
 3.9 IP Address Control
 ----------------------
   Status:
-      - Nothing done at all.
+      Nothing done at all.
 
   Notes:
       Author needed!! Any volunteers??
@@ -129,9 +124,10 @@
 ----------------------
   Author:
       Dummy written by Eric Kohl. <ekohl@abo.rhein-zeitung.de>
+      Ben Williams <.edu>
 
   Status:
-      - Development in progress.
+      Under construction.
 
   Notes:
       Author needed!! Any volunteers??
@@ -140,13 +136,22 @@
 3.11 Month Calendar Control
 ---------------------------
   Status:
-      - Nothing done at all.
+      Nothing done at all.
 
   Notes:
       Author needed!! Any volunteers??
 
 
-3.12 Pager Control
+3.12 Native font control
+------------------------
+  Status:
+      Nothing done at all.
+
+  Notes:
+      Author needed!! Any volunteers??
+
+
+3.13 Pager Control
 ------------------
   Author:
       Dummy written by Eric Kohl.
@@ -158,14 +163,14 @@
       Author needed!! Any volunteers??
 
 
-3.13 Progress Bar Control
+3.14 Progress Bar Control
 -------------------------
   Author:
       Original implementation by Dimitrie O. Paun.
       Fixes and improvements by Eric Kohl.
 
   Status:
-      - Almost finished (should behave like the original).
+      Almost finished (should behave like the original).
 
   Notes:
       WM_GETFONT and WM_SETFONT are not implemented yet. They seem to be
@@ -174,7 +179,7 @@
       textual information (e.g. percentage) these messages would make sense.
 
 
-3.14 Property Sheet
+3.15 Property Sheet
 -------------------
   Author:
       Anders Carlsson <anders.carlsson@linux.nu>
@@ -187,33 +192,33 @@
       Tab control must be implemented first.
 
 
-3.15 Rebar Control (Cool Bar)
+3.16 Rebar Control (Cool Bar)
 -----------------------------
   Author:
       Dummy written by Eric Kohl.
 
   Status:
-      - Dummy control. No functionality.
+      Dummy control. No functionality.
 
   Notes:
       Author needed!! Any volunteers??
 
 
-3.16 Status Bar Control
+3.17 Status Bar Control
 -----------------------
   Author:
       Original implementation by Bruce Milner.
       Fixes and improvements by Eric Kohl.
 
   Status:
-      - Almost finished.
+      Almost finished.
 
   Notes:
       - Unicode support is still missing.
       - Tooltip integration is almost complete.
 
 
-3.17 Tab Control
+3.18 Tab Control
 ----------------
   Author:
       Anders Carlsson <anders.carlsson@linux.nu>
@@ -223,7 +228,7 @@
       - Not yet published.
 
 
-3.18 Toolbar Control
+3.19 Toolbar Control
 --------------------
   Author:
       Eric Kohl <ekohl@abo.rhein-zeitung.de>
@@ -236,7 +241,7 @@
       - Bitmaps are not correctly displayed.
 
 
-3.19 Tooltip Control
+3.20 Tooltip Control
 --------------------
   Author:
       Eric Kohl <ekohl@abo.rhein-zeitung.de>
@@ -248,7 +253,7 @@
       - Unicode support is still missing.
 
 
-3.20 Trackbar Control
+3.21 Trackbar Control
 ---------------------
   Author:
       Dummy written by Eric Kohl <ekohl@abo.rhein-zeitung.de>
@@ -258,7 +263,7 @@
       Under construction.
 
 
-3.21 Tree View Control
+3.22 Tree View Control
 ----------------------
   Author:
       Dummy written by Eric Kohl.
@@ -268,7 +273,7 @@
       Under contstruction.
 
 
-3.22 Updown Control
+3.23 Updown Control
 -------------------
   Author:
       Original implementation by Dimitrie O. Paun.
@@ -306,30 +311,31 @@
   Have a look at relay32/comctl32.spec.
 
 
-5.1 Dymnamic Storage Arrays (DSA)
+5.1 Dymnamic Storage Array (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.
+  The DSA functions are used to store and manage dynamic arrays of fixed size
+  memory blocks. They are used by TASKMAN.EXE, Explorer, IE4 and other
+  Programs and DLL's that are "parts of the Windows Operating System".
+  The implementation should be complete.
 
   Have a look at the source code to get more information.
 
-  Further documentation will be written...
 
-
-5.2 Dynamic Pointer Arrays ??? (DPA)
+5.2 Dynamic Pointer Array (DPA)
 ------------------------------------
-  Similar to the DSA functions, but they just store pointers. I have written
-  some stubs and semi-stubs. They are used by Explorer and IE4 but the 
-  implementation is still incomplete since both programs seem to crash because
-  of other incomplete functions.
+  Similar to the DSA functions, but they just store pointers. They are used by
+  Explorer, IE4 and other Programs and DLL's that are "parts of the Windows
+  Operating System". The implementation should be complete.
 
   Have a look at the source code to get more information.
-  Further documentation will be written...
 
 
 5.3 "Most Recently Used" - List (MRU)
 -------------------------------------
-  Currently no information available!
+  The function 'COMCTL32_157()' could be called 'CreateMRUListEx32A()'.
+  Only stubs are implemented to keep Explorer from bailing out.
+
+  No more information available at this time!
 
 
 5.4 MenuHelp
@@ -353,6 +359,14 @@
   ...
 
 
+5.7 Other undocumented functions
+--------------------------------
+  Several other undocumented functions are used by IE4.
+
+  COMCTL32_11, COMCTL_385, COMCTL32_386 and COMCTL32_388.
+  Their stubs are implemented to keep IE4 from bailing out.
+
+
 6. Epilogue
 -----------
   You see, much work has still to be done. If you are interested in writing
diff --git a/documentation/debugging b/documentation/debugging
index b929c8f..787c3d3 100644
--- a/documentation/debugging
+++ b/documentation/debugging
@@ -1,6 +1,37 @@
 This file describes where to start debugging Wine and how to write
 useful bug reports.
 
+To avoid debugging
+==================
+
+Sometimes you can bring applications to run by using some of the
+native Windows DLL's, together with Wine. Here are some Tips by
+Juergen Schmied on how to proceed. This assumes that your C:\windows
+directory in the configuration file does not point to a native Windows
+installation but is in a separate Unix file system. (For instance,
+C:\windows is really /home/ego/wine/drives/c).
+
+- Create empty C:\windows and C:\windows\system directories.
+  Do not point Wine to a Windows directory full of old installations
+  and a messy registry. (Wine creates a special registry in your home
+  directory, in $HOME/.wine/*.reg. Perhaps you have to remove these
+  files).
+- Run the application with   -debugmsg +module,+file   to find out
+  which files are needed. Copy the required DLL's one by one to the
+  C:\windows\system directory.
+- Note that some network DLL's are not needed even though Wine is
+  looking for them. Do not copy the MPR.DLL into the directory,
+  use the internal implementation.
+- Copy SHELL/SHELL32 and COMDLG/COMDLG32 COMMCTRL/COMCTL32
+  only as pairs to your Wine directory (these DLL's are
+  "clean" to use)
+- Be consistent: Use only DLLS from the same Windows version
+  together.
+- Put regedit.exe in the C:\windows directory (office95 imports
+  a *.reg file when it runs with a empty registry, don't know
+  about office97).
+
+
 Crashes
 =======
 
@@ -336,3 +367,30 @@
 
 pedump: http://oak.oakland.edu/pub/simtelnet/win95/prog/pedump.zip
 Dumps the imports and exports of a PE (Portable Executable) DLL.
+
+
+Some basic debugger usages:
+===========================
+
+After starting you program with
+  wine -debug myprog.exe
+the program loads and you get a prompt at the program starting point.
+Then you can set breakpoints:
+  b RoutineName      (by outine name) OR
+  b *0x812575        (by address)
+Then you hit 'c' (continue) to run the program. It stops at
+the breakpoint. You can type
+  step               (to step one line) OR
+  stepi              (to step one machine instruction at a time;
+                      here, it helps to know the basic 386
+                      instruction set)
+  info reg           (to see registers)
+  info stack         (to see hex values in the stack)
+  info local         (to see local variables)
+  list <line number> (to list source code)
+  x <variable name>  (to examine a variable; only works if code
+                      is not compiled with optimization)
+  x 0x4269978        (to examine a memory location)
+  ?                  (help)
+  q                  (quit)
+By hitting Enter, you repeat the last command.
diff --git a/documentation/status/directplay b/documentation/status/directplay
index 69c859a..6e7f1e9 100644
--- a/documentation/status/directplay
+++ b/documentation/status/directplay
@@ -5,13 +5,18 @@
 to see what has been implemented.  Stay tuned for some information here once
 there is more implementation (and I figure out what the heck I'm doing).
 
-The files are include/dplay.h and multimedia/dplay.c.
+The files are include/dplay.h and multimedia/dplay.c. They're getting a 
+little cumbersome at present perhaps they will be broken out in a later
+version.
 
 I think I can safely say that any application which requires direct play
 or direct play lobby will not work at this point. Priority will be to get
-lserver.exe and star wars rebellion going (at least the direct play portions).
+lserver.exe from the sdk running.
 
 
 
 TODO:
-  Just about everything
+  - Just about everything
+
+
+Peter Hunnisett  -  hunnise@nortel.ca
diff --git a/documentation/status/multimedia b/documentation/status/multimedia
index 04afca9..d45c611 100644
--- a/documentation/status/multimedia
+++ b/documentation/status/multimedia
@@ -57,14 +57,23 @@
    They call the lowlevel driver functions in multimedia/midi.c using the
    midMessage and the modMessage functions.
 
-   The current implementation is completely broken. (I think open(), read()
-   and write() of the /dev/midi device would make this implementation nearly
-   complete...)
+   The lowlevel audio driver is currently only implemented for the
+   OpenSoundSystem (OSS) as supplied in the Linux and FreeBSD kernels by
+   4Front Technologies (http://www.4front-tech.com/). The presence of this
+   driver is checked by configure (depends on the <sys/soundcard.h> file).
+   Both Midi in and Midi out are provided. The type of MIDI devices supported
+   is external MIDI port (requires an MIDI capable device - keyboard...) and
+   OPL/2 synthesis (the OPL/2patches for all instruments are in midiPatch.c).
 
    TODO:
-   	- Implement correct MIDI output
 	- Do not implement a software synthesizer. This should be done
 	  using MIDI loopback devices in an external program (like timidity).
+	  the only trouble is that timidity is GPL'ed...
+        - use better instrument definition for OPL/2 (midiPatch.c)
+        - have a look at OPL/3 ?
+	- a hack is used in mmsystem.c (setting reserved to the 32 bit linear
+	  address of the block whatever the call is made from 16 or 32 bits 
+	  code...). this should be in midi.c I think
 
 1.4 Timers
 
diff --git a/documentation/win95look b/documentation/win95look
index ddab05a..ed87f68 100644
--- a/documentation/win95look
+++ b/documentation/win95look
@@ -1,8 +1,8 @@
-Win95 interface code is being introduced.
+Win95/Win98 interface code is being introduced.
 
 Instead of compiling Wine for Win3.1 vs. Win95 using #define switches,
 the code now looks in a special [Tweaks.Layout] section of wine.conf
-for a "Win95Look=true" entry.
+for a "WineLook=Win95" or "WineLook=Win98" entry.
 
 A few new sections and a number of entries have been added to the
 wine.conf file -- these are for debugging the Win95 tweaks only and may
@@ -20,13 +20,5 @@
 SystemFixed.xxx               # Same parameters for the System fixed typeface
 
 [Tweak.Layout]
-Win95Look=[true|false]        # Enables/disables the Win95 look and feel
-MenuBarItemTopNudge=<pixels>  # Nudges the menu bar items down/up
-MenuBarItemLeftNudge=<pixels> # Nudges the menu bar items left/right
-MenuItemTopNudge=<pixels>     # Nudges the menu items down/up
-MenuItemLeftNudge=<pixels>    # Nudges the menu items left/right
-MenuHighlightTopNudge=<pixels> # Nudges the top of the highlight bar
-MenuHighlightLeftNudge=<pixels> # Nudges the left side of the highlight bar
-MenuHighlightRightNudge=<pixels> # Nudges the right side of the highlight bar
-MenuHighlightBottomNudge=<pixels> # Nudges the bottom of the highlight bar
+WineLook=[Win31|Win95|Win98]  # Changes Wine's look and feel
 
diff --git a/files/directory.c b/files/directory.c
index cdcba08..dbaad90 100644
--- a/files/directory.c
+++ b/files/directory.c
@@ -11,6 +11,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <errno.h>
+#include <sys/errno.h>
 
 #include "windows.h"
 #include "winerror.h"
@@ -76,16 +77,20 @@
         DRIVE_Chdir( drive, cwd );
     }
 
-    if (!(DIR_GetPath( "windows", "c:\\windows", &DIR_Windows )))
+    if (!(DIR_GetPath( "windows", "c:\\windows", &DIR_Windows )) ||
+	!(DIR_GetPath( "system", "c:\\windows\\system", &DIR_System )) ||
+	!(DIR_GetPath( "temp", "c:\\windows", &tmp_dir )))
+    {
+	PROFILE_UsageWineIni();
         return 0;
-    if (!(DIR_GetPath( "system", "c:\\windows\\system", &DIR_System )))
-        return 0;
-    if (!(DIR_GetPath( "temp", "c:\\windows", &tmp_dir )))
-        return 0;
+    }
     if (-1 == access( tmp_dir.long_name, W_OK ))
     {
     	if (errno==EACCES)
-		MSG("Warning: The Temporary Directory (as specified in wine.conf or ~/.winerc) is NOT writeable. Please check your configuration.\n");
+	{
+		MSG("Warning: The Temporary Directory (as specified in your configuration file) is NOT writeable.\n");
+		PROFILE_UsageWineIni();
+	}
 	else
 		MSG("Warning: Access to Temporary Directory failed (%s).\n",
 		    strerror(errno));
@@ -104,6 +109,7 @@
     /* Set the environment variables */
 
     SetEnvironmentVariable32A( "PATH", path );
+    SetEnvironmentVariable32A( "COMSPEC", "c:\\command.com" );
     SetEnvironmentVariable32A( "TEMP", tmp_dir.short_name );
     SetEnvironmentVariable32A( "windir", DIR_Windows.short_name );
     SetEnvironmentVariable32A( "winsysdir", DIR_System.short_name );
diff --git a/files/dos_fs.c b/files/dos_fs.c
index f662eac..1481429 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -10,6 +10,7 @@
 #include <ctype.h>
 #include <dirent.h>
 #include <errno.h>
+#include <sys/errno.h>
 #include <fcntl.h>
 #include <string.h>
 #include <stdlib.h>
diff --git a/files/drive.c b/files/drive.c
index 0fa08c5..359caa5 100644
--- a/files/drive.c
+++ b/files/drive.c
@@ -769,13 +769,43 @@
 
 /***********************************************************************
  *           GetDriveType32A   (KERNEL32.208)
+ *
+ * Returns the type of the disk drive specified.  If root is NULL the
+ * root of the current directory is used.
+ *
+ * RETURNS
+ *
+ *  Type of drive (from Win32 SDK):
+ *
+ *   DRIVE_UNKNOWN     unable to find out anything about the drive
+ *   DRIVE_NO_ROOT_DIR nonexistand root dir
+ *   DRIVE_REMOVABLE   the disk can be removed from the machine
+ *   DRIVE_FIXED       the disk can not be removed from the machine
+ *   DRIVE_REMOTE      network disk
+ *   DRIVE_CDROM       CDROM drive
+ *   DRIVE_RAMDISK     virtual disk in ram
+ *
+ *   DRIVE_DOESNOTEXIST XXX Not valid return value
+ *   
+ * BUGS
+ *
+ *  Currently returns DRIVE_DOESNOTEXIST when it really should return
+ *  DRIVE_UNKNOWN or DRIVE_NO_ROOT_DIR.  DRIVE_RAMDISK is unsupported.
+ *  Should determine current directory and use that root if param is
+ *  NULL.
  */
-UINT32 WINAPI GetDriveType32A( LPCSTR root )
+UINT32 WINAPI GetDriveType32A(LPCSTR root /* String describing drive */)
 {
-    TRACE(dosfs, "(%s)\n", root );
+    TRACE(dosfs, "(%s)\n", NULL != root ? root : "NULL");
+    if (NULL == root)
+    {
+	FIXME(dosfs,"(NULL) should use current dir, hardcoded c: instead\n");
+        root = "C:";
+    }
+
     if ((root[1]) && (root[1] != ':'))
     {
-        WARN(dosfs, "invalid root '%s'\n", root );
+        WARN(dosfs, "invalid root '%s'\n", NULL != root ? root : "NULL");
         return DRIVE_DOESNOTEXIST;
     }
     switch(DRIVE_GetType(toupper(root[0]) - 'A'))
diff --git a/files/file.c b/files/file.c
index 205c630..46b55c3 100644
--- a/files/file.c
+++ b/files/file.c
@@ -119,6 +119,7 @@
             FILE_SetDosError();
             return FALSE;
 	}
+	file->pos += result;
 	*lpNumberOfChars = result;
 	return TRUE;
 }
@@ -156,7 +157,8 @@
 		result = write(file->unix_handle, lpBuffer, nNumberOfChars);
 		if (result != -1) {
 			*lpNumberOfChars = result;
-                        return TRUE;
+			file->pos += result;
+			return TRUE;
 		}
 		if (errno != EINTR) {
 			FILE_SetDosError();
diff --git a/files/profile.c b/files/profile.c
index e921513..66f1d31 100644
--- a/files/profile.c
+++ b/files/profile.c
@@ -15,6 +15,7 @@
 #include "file.h"
 #include "heap.h"
 #include "debug.h"
+#include "options.h"
 
 typedef struct tagPROFILEKEY
 {
@@ -57,6 +58,9 @@
 /* Wine profile name in $HOME directory; must begin with slash */
 static const char PROFILE_WineIniName[] = "/.winerc";
 
+/* Wine profile: the profile file being used */
+static char PROFILE_WineIniUsed[MAX_PATHNAME_LEN] = "";
+
 /* Check for comments in profile */
 #define IS_ENTRY_COMMENT(str)  ((str)[0] == ';')
 
@@ -824,10 +828,20 @@
     const char *p;
     FILE *f;
 
+    if ( (Options.configFileName!=NULL) && (f = fopen(Options.configFileName, "r")) )
+    {
+      /* Open -config specified file */
+      WineProfile = PROFILE_Load ( f);
+      fclose ( f );
+      strncpy(PROFILE_WineIniUsed,Options.configFileName,MAX_PATHNAME_LEN-1);
+      return 1;
+    }
+
     if ( (p = getenv( "WINE_INI" )) && (f = fopen( p, "r" )) )
       {
 	WineProfile = PROFILE_Load( f );
 	fclose( f );
+	strncpy(PROFILE_WineIniUsed,p,MAX_PATHNAME_LEN-1);
 	return 1;
       }
     if ((p = getenv( "HOME" )) != NULL)
@@ -838,6 +852,7 @@
         {
             WineProfile = PROFILE_Load( f );
             fclose( f );
+	    strncpy(PROFILE_WineIniUsed,buffer,MAX_PATHNAME_LEN-1);
             return 1;
         }
     }
@@ -849,6 +864,7 @@
     {
         WineProfile = PROFILE_Load( f );
         fclose( f );
+	strncpy(PROFILE_WineIniUsed,WINE_INI_GLOBAL,MAX_PATHNAME_LEN-1);
         return 1;
     }
     MSG( "Can't open configuration file %s or $HOME%s\n",
@@ -858,6 +874,26 @@
 
 
 /***********************************************************************
+ *           PROFILE_UsageWineIni
+ *
+ * Explain the wine.ini file to those who don't read documentation.
+ * Keep below one screenful in length so that error messages above are
+ * noticed.
+ */
+void PROFILE_UsageWineIni(void)
+{
+    MSG("Perhaps you have not properly edited or created "
+	"your Wine configuration file.\n");
+    MSG("This is either %s or $HOME%s\n",WINE_INI_GLOBAL,PROFILE_WineIniName);
+    MSG("  or it is determined by the -config option or from\n"
+        "  the WINE_INI environment variable.\n");
+    if (*PROFILE_WineIniUsed)
+	MSG("Wine has used %s as configuration file.\n", PROFILE_WineIniUsed);
+    /* RTFM, so to say */
+}
+
+
+/***********************************************************************
  *           PROFILE_GetStringItem
  *
  *  Convenience function that turns a string 'xxx, yyy, zzz' into 
diff --git a/graphics/ddraw.c b/graphics/ddraw.c
index 3e00742..7670832 100644
--- a/graphics/ddraw.c
+++ b/graphics/ddraw.c
@@ -18,6 +18,9 @@
  *	  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
+ *        NOTE: The hanging only seems to happen with -managed. I have 
+ *              implemented support for the -desktop option. This seems
+ *              to not have the hanging problems. - Peter Hunnisett
  */
 
 #include "config.h"
@@ -359,8 +362,12 @@
 	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;
+        {
+		return DD_OK;
+        }
+
 	TSXPutImage(		display,
 				this->s.ddraw->e.xlib.drawable,
 				DefaultGCOfScreen(screen),
@@ -370,7 +377,8 @@
 				this->t.xlib.image->height
 	);
 	TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
-	return 0;
+
+	return DD_OK;
 }
 
 static HRESULT WINAPI DGA_IDirectDrawSurface3_Flip(
@@ -423,6 +431,7 @@
 		else
 			flipto = this;
 	}
+  
 	TSXPutImage(display,
 				this->s.ddraw->e.xlib.drawable,
 				DefaultGCOfScreen(screen),
@@ -444,11 +453,49 @@
 	return 0;
 }
 
+/* The IDirectDrawSurface3::SetPalette method attaches the specified
+ * DirectDrawPalette object to a surface. The surface uses this palette for all
+ * subsequent operations. The palette change takes place immediately.
+ */
 static HRESULT WINAPI IDirectDrawSurface3_SetPalette(
 	LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
 ) {
 	TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
-	this->s.palette = pal; /* probably addref it too */
+
+        /* According to spec, we are only supposed to 
+         * AddRef if this is not the same palette.
+         */
+        if( this->s.palette != pal )
+        {
+          if( pal != NULL )
+          {
+            pal->lpvtbl->fnAddRef( pal );
+          }
+          if( this->s.palette != NULL )
+          {
+            this->s.palette->lpvtbl->fnRelease( this->s.palette );
+          }
+	  this->s.palette = pal; 
+
+          /* I think that we need to attach it to all backbuffers...*/
+          if( this->s.backbuffer )
+          {
+             if( this->s.backbuffer->s.palette )
+             {
+               this->s.backbuffer->s.palette->lpvtbl->fnRelease(
+                 this->s.backbuffer->s.palette );
+             } 
+             this->s.backbuffer->s.palette = pal;
+             if( pal )
+             { 	
+                pal->lpvtbl->fnAddRef( pal );
+             } 
+           }
+      
+          /* Perform the refresh */
+          TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
+        }
+
 	return 0;
 }
 
@@ -583,12 +630,14 @@
 }
 
 static ULONG WINAPI IDirectDrawSurface3_AddRef(LPDIRECTDRAWSURFACE3 this) {
-	TRACE(ddraw,"(%p)->AddRef()\n",this);
+        TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
+
 	return ++(this->ref);
 }
 
 static ULONG WINAPI DGA_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
-	TRACE(ddraw,"(%p)->Release()\n",this);
+        TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
+
 #ifdef HAVE_LIBXXF86DGA
 	if (!--(this->ref)) {
 		this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
@@ -606,13 +655,23 @@
 }
 
 static ULONG WINAPI Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
-	TRACE(ddraw,"(%p)->Release()\n",this);
+        TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
+
 	if (!--(this->ref)) {
 		this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
 		HeapFree(GetProcessHeap(),0,this->s.surface);
+
+                if( this->s.backbuffer )
+ 		{
+		  this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
+ 		}
+
 		this->t.xlib.image->data = NULL;
 		TSXDestroyImage(this->t.xlib.image);
 		this->t.xlib.image = 0;
+
+                this->s.palette->lpvtbl->fnRelease(this->s.palette);
+
 		HeapFree(GetProcessHeap(),0,this);
 		return 0;
 	}
@@ -624,16 +683,25 @@
 ) {
         TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
 		     this, lpddsd, lpdsf);
+
 	if (TRACE_ON(ddraw)) {
 		TRACE(ddraw,"	caps ");
 		_dump_DDSCAPS(lpddsd->dwCaps);
 	}
+
 	if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
 		FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
 		return E_FAIL;
 	}
+
 	/* FIXME: should handle more than one backbuffer */
 	*lpdsf = this->s.backbuffer;
+ 
+        if( this->s.backbuffer )
+        {
+          this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );
+        }
+
 	return 0;
 }
 
@@ -727,10 +795,21 @@
 }
 
 static HRESULT WINAPI IDirectDrawSurface3_SetColorKey(
-	LPDIRECTDRAWSURFACE3 this,DWORD x,LPDDCOLORKEY ckey
+	LPDIRECTDRAWSURFACE3 this, DWORD dwFlags, LPDDCOLORKEY ckey
 ) {
-	FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,x,ckey);
-	return 0;
+	FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,ckey);
+
+        if( dwFlags & DDCKEY_SRCBLT )
+        {
+           dwFlags &= ~DDCKEY_SRCBLT;
+        } 
+
+        if( dwFlags )
+        {
+          TRACE( ddraw, "unhandled dwFlags: %08lx\n", dwFlags );
+        }
+
+	return DD_OK;
 }
 
 static struct IDirectDrawSurface3_VTable dga_dds3vt = {
@@ -830,6 +909,8 @@
 }
 
 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
+        TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
+
 	this->ref--;
 	if (this->ref)
 		return this->ref;
@@ -878,11 +959,20 @@
 		return DDERR_GENERIC;
 	}
 	for (i=0;i<count;i++) {
+#if 0
+PH
 		xc.pixel = i+start;
 		TSXQueryColor(display,this->cm,&xc);
 		palent[i].peRed = xc.red>>8;
 		palent[i].peGreen = xc.green>>8;
 		palent[i].peBlue = xc.blue>>8;
+#endif
+
+                palent[i].peRed   = this->palents[start+i].peRed;
+                palent[i].peBlue  = this->palents[start+i].peBlue;
+                palent[i].peGreen = this->palents[start+i].peGreen;
+                palent[i].peFlags = this->palents[start+i].peFlags;
+
 	}
 	return 0;
 }
@@ -908,10 +998,13 @@
 		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;
+                this->palents[start+i].peFlags = palent[i].peFlags;
 	}
 	return 0;
 }
@@ -942,10 +1035,13 @@
 		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;
+                this->palents[start+i].peFlags = palent[i].peFlags;
 	}
 	TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
 	return 0;
@@ -955,6 +1051,7 @@
 }
 
 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
+        TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
 	if (!--(this->ref)) {
 		if (this->cm) {
 			TSXFreeColormap(display,this->cm);
@@ -967,6 +1064,8 @@
 }
 
 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
+
+        TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
 	return ++(this->ref);
 }
 
@@ -976,21 +1075,39 @@
 	return DDERR_ALREADYINITIALIZED;
 }
 
+static HRESULT WINAPI IDirectDrawPalette_GetCaps(
+         LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
+{
+   FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
+   return DD_OK;
+} 
+
+static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
+        LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj ) 
+{
+  char    xrefiid[50];
+
+  WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
+  FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);
+
+  return S_OK;
+}
+
 static struct IDirectDrawPalette_VTable dga_ddpalvt = {
-	(void*)1,
+	IDirectDrawPalette_QueryInterface,
 	IDirectDrawPalette_AddRef,
 	IDirectDrawPalette_Release,
-	(void*)4,
+	IDirectDrawPalette_GetCaps,
 	IDirectDrawPalette_GetEntries,
 	IDirectDrawPalette_Initialize,
 	DGA_IDirectDrawPalette_SetEntries
 };
 
 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
-	(void*)1,
+	IDirectDrawPalette_QueryInterface,
 	IDirectDrawPalette_AddRef,
 	IDirectDrawPalette_Release,
-	(void*)4,
+	IDirectDrawPalette_GetCaps,
 	IDirectDrawPalette_GetEntries,
 	IDirectDrawPalette_Initialize,
 	Xlib_IDirectDrawPalette_SetEntries
@@ -1036,12 +1153,15 @@
 }
 
 static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
+        TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
+
         return ++(this->ref);
 }
 
 static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
 {
-        TRACE(ddraw,"(%p)->Release()\n",this);
+        TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
+
         if (!--(this->ref)) {
                 this->ddraw->lpvtbl->fnRelease(this->ddraw);
                 HeapFree(GetProcessHeap(),0,this);
@@ -1050,6 +1170,18 @@
         return this->ref;
 }
 
+static HRESULT WINAPI IDirect3D_Initialize(
+         LPDIRECT3D this, REFIID refiid )
+{
+  /* FIXME: Not sure if this is correct */
+  char    xrefiid[50];
+
+  WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
+  FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
+  
+  return DDERR_ALREADYINITIALIZED;
+}
+
 /*******************************************************************************
  *				IDirect3D
  */
@@ -1057,7 +1189,7 @@
 	(void*)IDirect3D_QueryInterface,
 	(void*)IDirect3D_AddRef,
 	(void*)IDirect3D_Release,
-	(void*)4,
+	IDirect3D_Initialize,
 	(void*)5,
 	(void*)6,
 	(void*)7,
@@ -1069,6 +1201,8 @@
  *				IDirect3D2
  */
 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
+        TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
+
 	if (!--(this->ref)) {
 		this->ddraw->lpvtbl->fnRelease(this->ddraw);
 		HeapFree(GetProcessHeap(),0,this);
@@ -1107,6 +1241,12 @@
 /*******************************************************************************
  *				IDirectDraw
  */
+
+/* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
+ * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
+ */
+static INT32 ddrawXlibThisOffset = 0;
+
 static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
 	LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
 ) {
@@ -1191,8 +1331,10 @@
 	LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
 ) {
 	XImage *img;
+
 	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);
@@ -1202,9 +1344,12 @@
 	}
 
 	*lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
+
 	this->lpvtbl->fnAddRef(this);
-	(*lpdsf)->ref = 1;
-	(*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds3vt;
+	(*lpdsf)->s.ddraw             = this;
+	(*lpdsf)->ref                 = 1;
+	(*lpdsf)->lpvtbl              = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds3vt;
+
 	if (	(lpddsd->dwFlags & DDSD_CAPS) && 
 		(lpddsd->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)
 	) {
@@ -1225,7 +1370,6 @@
 		(*lpdsf)->s.width	= lpddsd->dwWidth;
 		(*lpdsf)->s.height	= lpddsd->dwHeight;
 	}
-	(*lpdsf)->s.ddraw = this;
 
 	{
 	(*lpdsf)->t.xlib.image = img =
@@ -1251,7 +1395,10 @@
 			FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
 
 		(*lpdsf)->s.backbuffer = back = (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
+
 		this->lpvtbl->fnAddRef(this);
+		back->s.ddraw = this;
+
 		back->ref = 1;
 		back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&xlib_dds3vt;
 		/* FIXME: !8 bit images */
@@ -1273,7 +1420,6 @@
 		);
 		back->s.width = this->d.width;
 		back->s.height = this->d.height;
-		back->s.ddraw = this;
 		back->s.lpitch = back->t.xlib.image->bytes_per_line;
 		back->s.backbuffer = NULL; /* does not have a backbuffer, it is
 					    * one! */
@@ -1316,7 +1462,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;
 }
 
@@ -1404,12 +1550,25 @@
 		0,
 		NULL
 	);
-	SetWindowLong32A(this->e.xlib.window,0,(LONG)this);
+
+        /* Store this with the window. We'll use it for the window procedure */
+	SetWindowLong32A(this->e.xlib.window,ddrawXlibThisOffset,(LONG)this);
+
 	this->e.xlib.paintable = 1;
+
 	ShowWindow32(this->e.xlib.window,TRUE);
 	UpdateWindow32(this->e.xlib.window);
+
 	assert(this->e.xlib.window);
-	this->e.xlib.drawable = WIN_FindWndPtr(this->e.xlib.window)->window;
+
+        this->e.xlib.drawable  = WIN_FindWndPtr(this->e.xlib.window)->window;  
+
+        /* We don't have a context for this window. Host off the desktop */
+        if( !this->e.xlib.drawable )
+        {
+           this->e.xlib.drawable = WIN_GetDesktop()->window;
+        }
+
 	this->d.width	= width;
 	this->d.height	= height;
 	/* adjust fb_height, so we don't overlap */
@@ -1503,16 +1662,23 @@
 	if (*lpddpal == NULL) return E_OUTOFMEMORY;
 	(*lpddpal)->ref = 1;
 	(*lpddpal)->installed = 0;
+
 	(*lpddpal)->ddraw = (LPDIRECTDRAW)this;
+        this->lpvtbl->fnAddRef(this);
+
 	if (this->d.depth<=8) {
 		(*lpddpal)->cm = TSXCreateColormap(display,this->e.xlib.drawable,DefaultVisualOfScreen(screen),AllocAll);
 		/* later installed ... 
 		 * TSXInstallColormap(display,(*lpddpal)->cm);
 		 * TSXSetWindowColormap(display,this->e.xlib.drawable,(*lpddpal)->cm);
 		 */
-	} else
+	} 
+        else
+        {
 		/* we don't want palettes in hicolor or truecolor */
 		(*lpddpal)->cm = 0;
+        }
+
 	(*lpddpal)->lpvtbl = &xlib_ddpalvt;
 	return 0;
 }
@@ -1545,10 +1711,14 @@
 }
 
 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
+        TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
+
 	return ++(this->ref);
 }
 
 static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
+        TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
+
 #ifdef HAVE_LIBXXF86DGA
 	if (!--(this->ref)) {
 		TSXF86DGADirectVideo(display,DefaultScreen(display),0);
@@ -1563,6 +1733,8 @@
 }
 
 static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
+        TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
+
 	if (!--(this->ref)) {
 		HeapFree(GetProcessHeap(),0,this);
 		return 0;
@@ -1779,6 +1951,15 @@
 	return 0;
 }
 
+static HRESULT WINAPI IDirectDraw2_Compact(
+          LPDIRECTDRAW2 this )
+{
+  FIXME(ddraw,"(%p)->()\n", this );
+ 
+  return DD_OK;
+}
+
+
 /* Note: Hack so we can reuse the old functions without compiler warnings */
 #ifdef __GNUC__
 # define XCAST(fun)	(typeof(dga_ddvt.fn##fun))
@@ -1790,7 +1971,7 @@
 	XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
 	XCAST(AddRef)IDirectDraw2_AddRef,
 	XCAST(Release)DGA_IDirectDraw2_Release,
-	XCAST(Compact)4,
+	XCAST(Compact)IDirectDraw2_Compact,
 	XCAST(CreateClipper)IDirectDraw2_CreateClipper,
 	XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
 	XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
@@ -1816,7 +1997,7 @@
 	XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
 	XCAST(AddRef)IDirectDraw2_AddRef,
 	XCAST(Release)Xlib_IDirectDraw2_Release,
-	XCAST(Compact)4,
+	XCAST(Compact)IDirectDraw2_Compact,
 	XCAST(CreateClipper)IDirectDraw2_CreateClipper,
 	XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
 	XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
@@ -1843,6 +2024,7 @@
  *
  */
 
+
 static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
 	LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
 ) {
@@ -1881,7 +2063,7 @@
 	DGA_IDirectDraw2_QueryInterface,
 	IDirectDraw2_AddRef,
 	DGA_IDirectDraw2_Release,
-	(void*)4,
+	IDirectDraw2_Compact,
 	IDirectDraw2_CreateClipper,
 	DGA_IDirectDraw2_CreatePalette,
 	DGA_IDirectDraw2_CreateSurface,
@@ -1908,7 +2090,7 @@
 	Xlib_IDirectDraw2_QueryInterface,
 	IDirectDraw2_AddRef,
 	Xlib_IDirectDraw2_Release,
-	(void*)4,
+	IDirectDraw2_Compact,
 	IDirectDraw2_CreateClipper,
 	Xlib_IDirectDraw2_CreatePalette,
 	Xlib_IDirectDraw2_CreateSurface,
@@ -1987,22 +2169,65 @@
 #endif /* defined(HAVE_LIBXXF86DGA) */
 }
 
-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);
+LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam)
+{
+   LRESULT ret;
+   LPDIRECTDRAW ddraw = NULL;
+   DWORD lastError;
 
-		if (ddraw)
-			ddraw->e.xlib.paintable = 1;
-	}
+   /*FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
+
+   SetLastError( ERROR_SUCCESS );
+   ddraw  = (LPDIRECTDRAW)GetWindowLong32A( hwnd, ddrawXlibThisOffset );
+   if( (!ddraw)  &&
+       ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
+     ) 
+   {
+     ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
+   }
+
+   if( ddraw )
+   {
+      /* Perform any special direct draw functions */
+      if (msg==WM_PAINT)
+      {
+        ddraw->e.xlib.paintable = 1;
+      } 
+
+      /* Now let the application deal with the rest of this */
+      if( ddraw->d.mainWindow )
+      {
+    
+        /* Don't think that we actually need to call this but... 
+           might as well be on the safe side of things... */
+        ret = DefWindowProc32A( hwnd, msg, wParam, lParam );
+
+        if( !ret )
+        {
+          /* We didn't handle the message - give it to the application */
+          ret = CallWindowProc32A( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
+                                  ddraw->d.mainWindow, msg, wParam, lParam );
+        }
+        
+      }
+      else
+      {
+        ret = DefWindowProc32A( ddraw->d.mainWindow, msg, wParam, lParam );
+      } 
+
+    }
+    else
+    {
 	ret = DefWindowProc32A(hwnd,msg,wParam,lParam);
-	return ret;
+    }
+
+    return ret;
 }
 
 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
 	WNDCLASS32A	wc;
 	int		have_xshm = 0;
+        WND*            pParentWindow; 
 
 	*lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
 	(*lplpDD)->lpvtbl = &xlib_ddvt;
@@ -2012,8 +2237,14 @@
 	wc.style	= CS_GLOBALCLASS;
 	wc.lpfnWndProc	= Xlib_DDWndProc;
 	wc.cbClsExtra	= 0;
-	wc.cbWndExtra	= 0;
-	wc.hInstance	= 0;
+	wc.cbWndExtra	= /* Defines extra mem for window. This is used for storing this */
+                          sizeof( LPDIRECTDRAW ); /*  ddrawXlibThisOffset */
+
+        /* We can be a child of the desktop since we're really important */
+        pParentWindow   = WIN_GetDesktop();
+	wc.hInstance	= pParentWindow ? pParentWindow->hwndSelf : 0;
+        wc.hInstance    = 0; 
+
 	wc.hIcon	= 0;
 	wc.hCursor	= (HCURSOR32)IDC_ARROW32A;
 	wc.hbrBackground= NULL_BRUSH;
diff --git a/graphics/escape.c b/graphics/escape.c
index c7bac2c..d3f54f2 100644
--- a/graphics/escape.c
+++ b/graphics/escape.c
@@ -116,9 +116,27 @@
     return ret;
 }
 
-INT32 WINAPI ExtEscape32(HDC32 hdc,INT32 nEscape,INT32 cbInput,LPCSTR x,INT32 cbOutput,LPSTR out) {
-	FIXME(driver,"(0x%04x,0x%x,%d,%s,%d,%p),stub!\n",
-		hdc,nEscape,cbInput,x,cbOutput,out
-	);
-	return 1;
+/******************************************************************************
+ *		ExtEscape32	[GDI32.95]
+ *
+ * PARAMS
+ *    hdc         [I] Handle to device context
+ *    nEscape     [I] Escape function
+ *    cbInput     [I] Number of bytes in input structure
+ *    lpszInData  [I] Pointer to input structure
+ *    cbOutput    [I] Number of bytes in output structure
+ *    lpszOutData [O] Pointer to output structure
+ *
+ * RETURNS
+ *    Success: >0
+ *    Not implemented: 0
+ *    Failure: <0
+ */
+INT32 WINAPI ExtEscape32( HDC32 hdc, INT32 nEscape, INT32 cbInput, 
+                          LPCSTR lpszInData, INT32 cbOutput, LPSTR lpszOutData )
+{
+    FIXME(driver,"(0x%04x,0x%x,%d,%s,%d,%p):stub\n",
+          hdc,nEscape,cbInput,debugstr_a(lpszInData),cbOutput,lpszOutData);
+    return 0;
 }
+
diff --git a/graphics/painting.c b/graphics/painting.c
index 57b3316..0c7d3a9 100644
--- a/graphics/painting.c
+++ b/graphics/painting.c
@@ -812,8 +812,7 @@
                                    const LPRECT32 lprcFrom,
                                    const LPRECT32 lprcTo )
 {
-    FIXME(gdi,"(%x,%d,%p,%p): empty stub!\n",
-	  hwnd, idAni, lprcFrom, lprcTo );
+    FIXME(gdi,"(0x%x,%d,%p,%p): stub\n",hwnd,idAni,lprcFrom,lprcTo);
     return TRUE;
 }
 
diff --git a/graphics/path.c b/graphics/path.c
index 9fd23ca..bd5dffd 100644
--- a/graphics/path.c
+++ b/graphics/path.c
@@ -239,7 +239,7 @@
 INT16 WINAPI GetPath16(HDC16 hdc, LPPOINT16 pPoints, LPBYTE pTypes,
    INT16 nSize)
 {
-   FIXME(gdi, "Unimplemented stub\n");
+   FIXME(gdi, "(%d,%p,%p): stub\n",hdc,pPoints,pTypes);
 
    return 0;
 }
diff --git a/graphics/x11drv/xfont.c b/graphics/x11drv/xfont.c
index 27c5009..ac86022 100644
--- a/graphics/x11drv/xfont.c
+++ b/graphics/x11drv/xfont.c
@@ -73,18 +73,18 @@
 			  { "-adobe-helvetica-", "Arial" }
 			  };
 
-/* Charset translation table, cp125-.. encoded fonts are produced by
- * the fnt2bdf */
+/* Charset translation table, microsoft-cp125.. encoded fonts are produced by
+ * the fnt2bdf or the True Type X11 font servers */
 
 static int	 numCPTranslation = 8;
-static BYTE	 CPTranslation[] = { EE_CHARSET,	/* cp125-0 */
-				     RUSSIAN_CHARSET,	/* cp125-1 */
-				     ANSI_CHARSET,	/* cp125-2 */
-				     GREEK_CHARSET,	/* cp125-3 */
-				     TURKISH_CHARSET,	/* cp125-4 */
-				     HEBREW_CHARSET,	/* cp125-5 */
-				     ARABIC_CHARSET,	/* cp125-6 */
-				     BALTIC_CHARSET	/* cp125-7 */
+static BYTE	 CPTranslation[] = { EE_CHARSET,	/* cp1250 */
+				     RUSSIAN_CHARSET,	/* cp1251 */
+				     ANSI_CHARSET,	/* cp1252 */
+				     GREEK_CHARSET,	/* cp1253 */
+				     TURKISH_CHARSET,	/* cp1254 */
+				     HEBREW_CHARSET,	/* cp1255 */
+				     ARABIC_CHARSET,	/* cp1256 */
+				     BALTIC_CHARSET	/* cp1257 */
 				   }; 
 
 UINT16			XTextCaps = TC_OP_CHARACTER | TC_OP_STROKE |
@@ -104,7 +104,7 @@
 static const char*	INIGlobalMetrics = "FontMetrics";
 
 static const char*	LFDSeparator = "*-";
-static const char*	localMSEncoding = "cp125-";
+static const char*	localMSEncoding = "microsoft-cp125";
 static const char*	iso8859Encoding = "iso8859-";
 static const char*	iso646Encoding = "iso646.1991-";
 static const char*	ansiEncoding = "ansi-";
@@ -372,7 +372,7 @@
      fi->fi_flags |= FI_ENC_ISO646;
    else if( strstr(lpch, ansiEncoding) )	/* fnt2bdf produces -ansi-0 LFD */
      fi->fi_flags |= FI_ENC_ANSI;
-   else						/* ... and -cp125-x */
+   else						/* ... and -microsoft-cp125x */
    {
 	fi->df.dfCharSet = OEM_CHARSET;
 	if( !strncasecmp(lpch, localMSEncoding, 6) )
@@ -384,7 +384,8 @@
 		fi->df.dfCharSet = CPTranslation[i];
 	    }
 	}
-	else if( strstr(lpch, "fontspecific") )
+	else if( strstr(lpch, "fontspecific") ||
+		 strstr(lpch, "microsoft-symbol") )
 	    fi->df.dfCharSet = SYMBOL_CHARSET;
    }
    return TRUE;					
@@ -1993,14 +1994,14 @@
   int i;
   char *cp, *start;
 
-  XGetFontProperty( pfo->fs, XA_FONT, &nameAtom );
-  fontName = XGetAtomName( display, nameAtom );
+  TSXGetFontProperty( pfo->fs, XA_FONT, &nameAtom );
+  fontName = TSXGetAtomName( display, nameAtom );
   for(i = 0, cp = fontName; i < 7; i++) {
     cp = strchr(cp, '-');
     cp++;
   }
   if(*cp != '[') {
-    XFree(fontName);
+    TSXFree(fontName);
     return FALSE;
   }
   start = cp;
@@ -2010,10 +2011,10 @@
 #define PX pfo->lpX11Trans
 
   sscanf(start, "[%f%f%f%f]", &PX->a, &PX->b, &PX->c, &PX->d);
-  XFree(fontName);
+  TSXFree(fontName);
 
-  XGetFontProperty( pfo->fs, RAW_ASCENT, &PX->RAW_ASCENT );
-  XGetFontProperty( pfo->fs, RAW_DESCENT, &PX->RAW_DESCENT );
+  TSXGetFontProperty( pfo->fs, RAW_ASCENT, &PX->RAW_ASCENT );
+  TSXGetFontProperty( pfo->fs, RAW_DESCENT, &PX->RAW_DESCENT );
 
   PX->pixelsize = hypot(PX->a, PX->b);
   PX->ascent = PX->pixelsize / 1000.0 * PX->RAW_ASCENT;
diff --git a/if1632/Makefile.in b/if1632/Makefile.in
index 392b50a..f9cd618 100644
--- a/if1632/Makefile.in
+++ b/if1632/Makefile.in
@@ -6,9 +6,11 @@
 MODULE    = if1632
 
 DLLS = \
+	avifile.spec \
 	commdlg.spec \
 	compobj.spec \
 	ddeml.spec \
+	display.spec \
 	gdi.spec \
 	kernel.spec \
 	keyboard.spec \
diff --git a/if1632/avifile.spec b/if1632/avifile.spec
new file mode 100644
index 0000000..316e930
--- /dev/null
+++ b/if1632/avifile.spec
@@ -0,0 +1,62 @@
+name	avifile
+type	win16
+
+1   stub     WEP
+2   stub     DLLGETCLASSOBJECT
+3   stub     DLLCANUNLOADNOW
+4   stub     ___EXPORTEDSTUB
+10  stub     _IID_IAVISTREAM
+11  stub     _IID_IAVIFILE
+12  stub     _IID_IAVIEDITSTREAM
+13  stub     _IID_IGETFRAME
+14  stub     _CLSID_AVISIMPLEUNMARSHAL
+100 stub     AVIFILEINIT
+101 stub     AVIFILEEXIT
+102 stub     AVIFILEOPEN
+103 stub     AVISTREAMOPENFROMFILE
+104 stub     AVISTREAMCREATE
+105 stub     AVIMAKECOMPRESSEDSTREAM
+106 stub     AVIMAKEFILEFROMSTREAMS
+107 stub     AVIMAKESTREAMFROMCLIPBOARD
+110 stub     AVISTREAMGETFRAME
+111 stub     AVISTREAMGETFRAMECLOSE
+112 stub     AVISTREAMGETFRAMEOPEN
+120 stub     _AVISAVE
+121 stub     AVISAVEV
+122 stub     AVISAVEOPTIONS
+123 stub     AVIBUILDFILTER
+124 stub     AVISAVEOPTIONSFREE
+130 stub     AVISTREAMSTART
+131 stub     AVISTREAMLENGTH
+132 stub     AVISTREAMTIMETOSAMPLE
+133 stub     AVISTREAMSAMPLETOTIME
+140 stub     AVIFILEADDREF
+141 stub     AVIFILERELEASE
+142 stub     AVIFILEINFO
+143 stub     AVIFILEGETSTREAM
+144 stub     AVIFILECREATESTREAM
+146 stub     AVIFILEWRITEDATA
+147 stub     AVIFILEREADDATA
+148 stub     AVIFILEENDRECORD
+160 stub     AVISTREAMADDREF
+161 stub     AVISTREAMRELEASE
+162 stub     AVISTREAMINFO
+163 stub     AVISTREAMFINDSAMPLE
+164 stub     AVISTREAMREADFORMAT
+165 stub     AVISTREAMREADDATA
+166 stub     AVISTREAMWRITEDATA
+167 stub     AVISTREAMREAD
+168 stub     AVISTREAMWRITE
+169 stub     AVISTREAMSETFORMAT
+180 stub     EDITSTREAMCOPY
+181 stub     EDITSTREAMCUT
+182 stub     EDITSTREAMPASTE
+184 stub     CREATEEDITABLESTREAM
+185 stub     AVIPUTFILEONCLIPBOARD
+187 stub     AVIGETFROMCLIPBOARD
+188 stub     AVICLEARCLIPBOARD
+190 stub     EDITSTREAMCLONE
+191 stub     EDITSTREAMSETNAME
+192 stub     EDITSTREAMSETINFO
+200 stub     AVISTREAMBEGINSTREAMING
+201 stub     AVISTREAMENDSTREAMING
diff --git a/if1632/builtin.c b/if1632/builtin.c
index c20ca16..be10b52 100644
--- a/if1632/builtin.c
+++ b/if1632/builtin.c
@@ -46,9 +46,11 @@
 
 /* 16-bit DLLs */
 
+extern const WIN16_DESCRIPTOR AVIFILE_Descriptor;
 extern const WIN16_DESCRIPTOR COMMDLG_Descriptor;
 extern const WIN16_DESCRIPTOR COMPOBJ_Descriptor;
 extern const WIN16_DESCRIPTOR DDEML_Descriptor;
+extern const WIN16_DESCRIPTOR DISPLAY_Descriptor;
 extern const WIN16_DESCRIPTOR GDI_Descriptor;
 extern const WIN16_DESCRIPTOR KERNEL_Descriptor;
 extern const WIN16_DESCRIPTOR KEYBOARD_Descriptor;
@@ -92,8 +94,10 @@
     { &USER_Descriptor,     DLL_FLAG_ALWAYS_USED },
     { &GDI_Descriptor,      DLL_FLAG_ALWAYS_USED },
     { &SYSTEM_Descriptor,   DLL_FLAG_ALWAYS_USED },
+    { &DISPLAY_Descriptor,  DLL_FLAG_ALWAYS_USED },
     { &WPROCS_Descriptor,   DLL_FLAG_ALWAYS_USED },
     { &WINDEBUG_Descriptor, DLL_FLAG_NOT_USED },
+    { &AVIFILE_Descriptor,  DLL_FLAG_NOT_USED },
     { &COMMDLG_Descriptor,  DLL_FLAG_NOT_USED },
     { &COMPOBJ_Descriptor,  DLL_FLAG_NOT_USED },
     { &DDEML_Descriptor,    DLL_FLAG_NOT_USED },
@@ -159,10 +163,10 @@
     /* Allocate the code segment */
 
     pSegTable = NE_SEG_TABLE( pModule );
-    pSegTable->selector = GLOBAL_CreateBlock( GMEM_FIXED, descr->code_start,
+    pSegTable->hSeg = GLOBAL_CreateBlock( GMEM_FIXED, descr->code_start,
                                               pSegTable->minsize, hModule,
                                               TRUE, TRUE, FALSE, NULL );
-    if (!pSegTable->selector) return 0;
+    if (!pSegTable->hSeg) return 0;
     pSegTable++;
 
     /* Allocate the data segment */
@@ -170,13 +174,14 @@
     minsize = pSegTable->minsize ? pSegTable->minsize : 0x10000;
     minsize += pModule->heap_size;
     if (minsize > 0x10000) minsize = 0x10000;
-    pSegTable->selector = GLOBAL_Alloc( GMEM_FIXED, minsize,
+    pSegTable->hSeg = GLOBAL_Alloc( GMEM_FIXED, minsize,
                                         hModule, FALSE, FALSE, FALSE );
-    if (!pSegTable->selector) return 0;
-    if (pSegTable->minsize) memcpy( GlobalLock16( pSegTable->selector ),
+    if (!pSegTable->hSeg) return 0;
+    if (pSegTable->minsize) memcpy( GlobalLock16( pSegTable->hSeg ),
                                     descr->data_start, pSegTable->minsize);
     if (pModule->heap_size)
-        LocalInit( pSegTable->selector, pSegTable->minsize, minsize );
+        LocalInit( GlobalHandleToSel(pSegTable->hSeg),
+		pSegTable->minsize, minsize );
 
     NE_RegisterModule( pModule );
     return hModule;
@@ -207,9 +212,9 @@
     /* Set the USER and GDI heap selectors */
 
     pModule      = NE_GetPtr( GetModuleHandle16( "USER" ));
-    USER_HeapSel = (NE_SEG_TABLE( pModule ) + pModule->dgroup - 1)->selector;
+    USER_HeapSel = pModule ? GlobalHandleToSel((NE_SEG_TABLE( pModule ) + pModule->dgroup - 1)->hSeg) : 0;
     pModule      = NE_GetPtr( GetModuleHandle16( "GDI" ));
-    GDI_HeapSel  = (NE_SEG_TABLE( pModule ) + pModule->dgroup - 1)->selector;
+    GDI_HeapSel  = pModule ? GlobalHandleToSel((NE_SEG_TABLE( pModule ) + pModule->dgroup - 1)->hSeg) : 0;
 
     /* Initialize KERNEL.178 (__WINFLAGS) with the correct flags value */
 
@@ -254,7 +259,7 @@
         FARPROC16 proc = NE_GetEntryPoint( hModule,
                                            FIRST_INTERRUPT_ORDINAL + vector );
         assert(proc);
-        INT_SetHandler( vector, proc );
+        INT_SetPMHandler( vector, proc );
     }
 
     SNOOP16_Init();
diff --git a/if1632/display.spec b/if1632/display.spec
new file mode 100644
index 0000000..97657d8
--- /dev/null
+++ b/if1632/display.spec
@@ -0,0 +1,35 @@
+name	display
+type	win16
+
+1   stub BitBlt
+2   stub ColorInfo
+3   stub Control
+4   stub Disable
+5   stub Enable
+6   stub EnumFonts
+7   stub EnumObj
+8   stub Output
+9   stub Pixel
+10  stub RealizeObject
+11  stub StrBlt
+12  stub ScanLR
+13  stub DeviceMode
+14  stub ExtTextOut
+15  stub GetCharWidth
+16  stub DeviceBitmap
+17  stub FastBorder
+18  stub SetAttribute
+19  stub DeviceBitmapBits
+20  stub CreateBitmap
+21  stub DIBScreenBlt
+90  stub Do_Polylines
+91  stub Do_Scanlines
+92  stub SaveScreenBitmap
+101 pascal16 Inquire(ptr) DisplayInquire
+102 pascal16 SetCursor(ptr) DisplaySetCursor
+103 pascal16 MoveCursor(word word) DisplayMoveCursor
+140 stub CheckCursor
+500 pascal16 UserRepaintDisable(word) UserRepaintDisable
+600 stub InkReady
+601 stub GetLPDevice
+
diff --git a/if1632/dummy.c b/if1632/dummy.c
index d81a159..c5f12e2 100644
--- a/if1632/dummy.c
+++ b/if1632/dummy.c
@@ -31,7 +31,6 @@
 long WINAPI stub_GDI_556(void) { FIXME(relay, "stub\n"); return 0; }
 long WINAPI stub_GDI_558(void) { FIXME(relay, "stub\n"); return 0; }
 long WINAPI stub_GDI_569(void) { FIXME(relay, "stub\n"); return 0; }
-long WINAPI stub_KERNEL_450(void) { FIXME(relay, "stub\n"); return 0; }
 long WINAPI stub_USER_489(void) { FIXME(relay, "stub\n"); return 0; }
 long WINAPI stub_USER_490(void) { FIXME(relay, "stub\n"); return 0; }
 long WINAPI stub_USER_492(void) { FIXME(relay, "stub\n"); return 0; }
@@ -53,4 +52,3 @@
 long WINAPI stub_USER_920(void) { FIXME(relay, "stub\n"); return 0; }
 long WINAPI stub_USER_922(void) { FIXME(relay, "stub\n"); return 0; }
 long WINAPI stub_USER_923(void) { FIXME(relay, "stub\n"); return 0; }
-long WINAPI stub_KERNEL_700(void) { FIXME(relay, "stub\n"); return 1; }
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index 8fdcc88..b200bda 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -117,8 +117,8 @@
 106 pascal SetBitmapBits(word long ptr) SetBitmapBits16
 117 pascal SetDCOrg(word s_word s_word) SetDCOrg
 119 pascal16 AddFontResource(str) AddFontResource16
-#121 pascal Death
-#122 pascal ReSurRection
+121 stub Death
+122 stub ReSurRection
 123 pascal16 PlayMetaFile(word word) PlayMetaFile16
 124 pascal16 GetMetaFile(str) GetMetaFile16
 125 pascal16 CreateMetaFile(str) CreateMetaFile16
@@ -161,7 +161,7 @@
 191 pascal   GetDCHook(word ptr) THUNK_GetDCHook
 192 pascal16 SetHookFlags(word word) SetHookFlags
 193 stub SetBoundsRect
-194 stub GetBoundsRect
+194 pascal16 GetBoundsRect(word ptr word) GetBoundsRect16
 195 stub SelectBitmap
 196 pascal16 SetMetaFileBitsBetter(word) SetMetaFileBitsBetter
 201 stub DMBITBLT
@@ -289,7 +289,7 @@
 460 stub GDITASKTERMINATION
 461 pascal16 SetObjectOwner(word word) SetObjectOwner16
 462 pascal16 IsGDIObject(word) IsGDIObject
-463 stub MAKEOBJECTPRIVATE
+463 pascal16 MakeObjectPrivate(word word) MakeObjectPrivate
 464 stub FIXUPBOGUSPUBLISHERMETAFILE
 465 pascal16 RectVisible(word ptr) RectVisible16
 466 pascal16 RectInRegion(word ptr) RectInRegion16
@@ -315,7 +315,7 @@
 485 pascal16 ScaleWindowExtEx(word s_word s_word s_word s_word ptr)
              ScaleWindowExtEx16
 486 pascal16 GetAspectRatioFilterEx(word ptr) GetAspectRatioFilterEx16
-489 pascal16 CreateDIBSection(word ptr word ptr word long) CreateDIBSection16
+489 pascal16 CreateDIBSection(word ptr word ptr long long) CreateDIBSection16
 490 stub CloseEnhMetafile
 491 stub CopyEnhMetafile
 492 stub CreateEnhMetafile
@@ -371,10 +371,10 @@
 556 pascal16 GDI_556() stub_GDI_556
 558 pascal16 GDI_558() stub_GDI_558
 569 pascal16 GDI_569() stub_GDI_569
-602 stub SetDIBColorTable
-603 stub GetDIBColorTable
+602 pascal16 SetDIBColorTable(word word word ptr) SetDIBColorTable16
+603 pascal16 GetDIBColorTable(word word word ptr) GetDIBColorTable16
 604 stub SetSolidBrush
-605 stub SysDeleteObject
+605 pascal16 SysDeleteObject(word) DeleteObject16    # ???
 606 stub SetMagicColors
 607 stub GetRegionData
 608 stub ExtCreateRegion
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index f15d568..8b161f8 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -2,6 +2,9 @@
 type	win16
 file	krnl386.exe
 
+# 1-207 are the basic functions, those are (with minor variations)
+# present in win31, win95 and nt351
+
 1   stub FatalExit
 2   stub ExitKernel
 3   pascal GetVersion() GetVersion16
@@ -102,7 +105,7 @@
 101 stub NoHookDosCall
 102 register DOS3Call() DOS3Call
 103 register NetBIOSCall() NetBIOSCall
-104 stub GetCodeInfo
+104 pascal16 GetCodeInfo(segptr ptr) GetCodeInfo
 105 pascal16 GetExeVersion() GetExeVersion
 106 pascal SetSwapAreaSize(word) SetSwapAreaSize16
 107 pascal16 SetErrorMode(word) SetErrorMode16
@@ -207,26 +210,32 @@
 205 stub CVWBreak
 206 pascal16 AllocSelectorArray(word) AllocSelectorArray
 207 pascal16 IsDBCSLeadByte(word) IsDBCSLeadByte16
-208 stub KERNEL_208
-209 stub KERNEL_209
-210 stub KERNEL_210
-211 stub KERNEL_211
-213 stub KERNEL_213
-214 stub KERNEL_214
-216 pascal   RegEnumKey(long long ptr long) RegEnumKey16
-217 pascal   RegOpenKey(long str ptr) RegOpenKey16
-218 pascal   RegCreateKey(long str ptr) RegCreateKey16
-219 pascal   RegDeleteKey(long str) RegDeleteKey16
-220 pascal   RegCloseKey(long) RegCloseKey
-221 pascal   RegSetValue(long str long ptr long) RegSetValue16
-222 pascal   RegDeleteValue(long str) RegDeleteValue16
-223 pascal   RegEnumValue(long long ptr ptr ptr ptr ptr ptr) RegEnumValue16
-224 pascal   RegQueryValue(long str ptr ptr) RegQueryValue16
-225 pascal   RegQueryValueEx(long str ptr ptr ptr ptr) RegQueryValueEx16
-226 pascal   RegSetValueEx(long str long long ptr long) RegSetValueEx16
-227 pascal   RegFlushKey(long) RegFlushKey
+
+
+# 208-237 are Win95 extensions; a few of those are also present in WinNT
+
+208 pascal K208(word long long long) Local32Init
+209 pascal K209(long long word long) Local32Alloc
+210 pascal K210(long long word long long) Local32ReAlloc
+211 pascal K211(long long word) Local32Free
+213 pascal K213(long long word word) Local32Translate
+214 pascal K214(long long word) Local32Size
+215 pascal K215(long word) Local32ValidHandle  # Win95 only -- CONFLICT!
+#215 stub WOWShouldWeSayWin95                  # WinNT only -- CONFLICT!
+216 pascal RegEnumKey(long long ptr long) RegEnumKey16                    # Both 95/NT
+217 pascal RegOpenKey(long str ptr) RegOpenKey16                          # Both 95/NT
+218 pascal RegCreateKey(long str ptr) RegCreateKey16
+219 pascal RegDeleteKey(long str) RegDeleteKey16
+220 pascal RegCloseKey(long) RegCloseKey                                  # Both 95/NT
+221 pascal RegSetValue(long str long ptr long) RegSetValue16
+222 pascal RegDeleteValue(long str) RegDeleteValue16
+223 pascal RegEnumValue(long long ptr ptr ptr ptr ptr ptr) RegEnumValue16 # Both 95/NT
+224 pascal RegQueryValue(long str ptr ptr) RegQueryValue16
+225 pascal RegQueryValueEx(long str ptr ptr ptr ptr) RegQueryValueEx16
+226 pascal RegSetValueEx(long str long long ptr long) RegSetValueEx16
+227 pascal RegFlushKey(long) RegFlushKey
 228 stub K228
-229 stub K229
+229 pascal16 K229(long) Local32GetSegment
 230 pascal GlobalSmartPageLock(word) GlobalPageLock #?
 231 stub GlobalSmartPageUnlock
 232 stub RegLoadKey
@@ -234,9 +243,19 @@
 234 stub RegSaveKey
 235 stub InvalidateNlsCache
 236 stub GetProductName
-237 stub KERNEL_237
-262 stub KERNEL_262
-263 stub KERNEL_263
+237 stub K237
+
+
+# 262-274 are WinNT extensions; those are not present in Win95
+
+262 stub WOWWaitForMsgAndEvent
+263 stub WOWMsgBox
+273 stub K273
+274 stub GetShortPathName
+
+
+# 310-356 are again shared between all versions
+
 310 pascal16 LocalHandleDelta(word) LocalHandleDelta
 311 pascal GetSetKernelDOSProc(ptr) GetSetKernelDOSProc
 314 stub DebugDefineSegment
@@ -245,12 +264,11 @@
 318 stub FatalExitHook
 319 stub FlushCachedFileHandle
 320 pascal16 IsTask(word) IsTask
-321 stub KERNEL_321
 323 return IsRomModule 2 0
 324 pascal16 LogError(word ptr) LogError
 325 pascal16 LogParamError(word ptr ptr) LogParamError
 326 return IsRomFile 2 0
-327 stub KERNEL_327
+327 register K327() LogParamErrorRegs
 328 stub _DebugOutput
 329 pascal16 K329(str word) DebugFillBuffer
 332 long THHOOK(0 0 0 0 0 0 0 0)
@@ -258,11 +276,11 @@
 335 pascal16 IsBadWritePtr(segptr word) IsBadWritePtr16
 336 pascal16 IsBadCodePtr(segptr) IsBadCodePtr16
 337 pascal16 IsBadStringPtr(segptr word) IsBadStringPtr16
-338 stub HasGPHandler
+338 pascal16 HasGPHandler(segptr) HasGPHandler
 339 pascal16 DiagQuery() DiagQuery
 340 pascal16 DiagOutput(str) DiagOutput
 341 pascal ToolHelpHook(ptr) ToolHelpHook
-342 stub __GP
+342 word __GP(0 0 0 0)
 343 stub RegisterWinOldApHook
 344 stub GetWinOldApHooks
 345 pascal16 IsSharedSelector(word) IsSharedSelector
@@ -271,22 +289,40 @@
 348 pascal16 hmemcpy(ptr ptr long) hmemcpy
 349 pascal   _hread(word segptr long) WIN16_hread
 350 pascal   _hwrite(word ptr long) _hwrite16
-#351 BUNNY_351
+351 stub BUNNY_351
 352 pascal   lstrcatn(segstr str word) lstrcatn16
 353 pascal   lstrcpyn(segptr str word) lstrcpyn16
 354 pascal   GetAppCompatFlags(word) GetAppCompatFlags16
 355 pascal16 GetWinDebugInfo(ptr word) GetWinDebugInfo
 356 pascal16 SetWinDebugInfo(ptr) SetWinDebugInfo
+
+
+# 357-365 are present in Win95 only
+# Note that from here on most of the Win95-only functions are exported 
+# ordinal-only; the names given here are mostly guesses :-)
+
 357 pascal MapSL(segptr) MapSL
 358 pascal MapLS(long) MapLS
 359 pascal UnMapLS(segptr) UnMapLS
 360 pascal16 OpenFileEx(str ptr word) OpenFile16
-#361 PIGLET_361
+361 return PIGLET_361 0 0
+362 stub ThunkTerminateProcess
 365 stub KERNEL_365
+
+
+# 403-404 are common to all versions
+
 403 pascal16 FarSetOwner(word word) FarSetOwner
 404 pascal16 FarGetOwner(word) FarGetOwner
+
+
+# 406-494 are present only in Win95
+
 406 stub WritePrivateProfileStruct
 407 stub GetPrivateProfileStruct
+408 stub KERNEL_408
+409 stub KERNEL_409
+410 stub CreateProcessFromWinExec
 411 pascal   GetCurrentDirectory(long ptr) GetCurrentDirectory16
 412 pascal16 SetCurrentDirectory(ptr) SetCurrentDirectory16
 413 pascal16 FindFirstFile(ptr ptr) FindFirstFile16
@@ -299,37 +335,76 @@
 420 pascal   GetFileAttributes(ptr) GetFileAttributes16
 421 pascal16 SetFileAttributes(ptr long) SetFileAttributes16
 422 pascal16 GetDiskFreeSpace(ptr ptr ptr ptr ptr) GetDiskFreeSpace16 
+423 stub LogApiThk
 431 pascal16 IsPeFormat(str word) IsPeFormat
 432 stub FileTimeToLocalFileTime
 434 stub KERNEL_434
-435 stub KERNEL_435
-439 stub KERNEL_439
-440 stub KERNEL_440
-444 stub KERNEL_444
-445 stub KERNEL_445
-446 stub KERNEL_446
+435 stub GetTaskFlags
+436 stub _ConfirmSysLevel
+437 stub _CheckNotSysLevel
+438 stub _CreateSysLevel
+439 stub _EnterSysLevel
+440 stub _LeaveSysLevel
+441 pascal CreateThread16(ptr long segptr segptr long ptr) THUNK_CreateThread16
+442 pascal VWin32_EventCreate() VWin32_EventCreate
+443 pascal VWin32_EventDestroy(long) VWin32_EventDestroy
+444 stub KERNEL_444     # Local32 ???
+445 stub KERNEL_445     # Local32 ???
+446 stub KERNEL_446     # Local32 ???
 447 stub KERNEL_447
+448 stub KERNEL_448
 449 pascal GetpWin16Lock() GetpWin16Lock16
-450 pascal16 KERNEL_450() stub_KERNEL_450
-452 stub KERNEL_452
-453 stub KERNEL_453
+450 pascal VWin32_EventWait(long) VWin32_EventWait
+451 pascal VWin32_EventSet(long) VWin32_EventSet
+452 pascal LoadLibrary32(str) LoadLibrary32A
+453 pascal GetProcAddress32(long str) GetProcAddress32
 454 equate __FLATCS 0   # initialized by BUILTIN_Init()
 455 equate __FLATDS 0   # initialized by BUILTIN_Init()
-471 pascal KERNEL_471() _KERNEL_471
-472 register KERNEL_472() _KERNEL_472
-473 stub KERNEL_473
-475 register KERNEL_475() _KERNEL_475
-480 stub KERNEL_480
-481 stub KERNEL_481
-482 pascal LoadLibrary32(str) LoadLibrary32A
+456 pascal DefResourceHandler(word word word) NE_DefResourceHandler
+457 pascal CreateW32Event(long long) WIN16_CreateEvent
+458 pascal SetW32Event(long) SetEvent
+459 pascal ResetW32Event(long) ResetEvent
+460 pascal WaitForSingleObject(long long) WIN16_WaitForSingleObject
+461 pascal WaitForMultipleObjects(long ptr long long) WIN16_WaitForMultipleObjects
+462 pascal GetCurrentThreadId() GetCurrentThreadId
+463 pascal SetThreadQueue(long word) SetThreadQueue
+464 pascal GetThreadQueue(long) GetThreadQueue
+465 stub NukeProcess
+466 stub ExitProcess
+467 stub WOACreateConsole
+468 stub WOASpawnConApp
+469 stub WOAGimmeTitle
+470 stub WOADestroyConsole
+471 pascal GetCurrentProcessId() GetCurrentProcessId
+472 register MapHInstLS() WIN16_MapHInstLS
+473 register MapHInstSL() WIN16_MapHInstSL
+474 pascal CloseW32Handle(long) CloseHandle
+475 register GetTEBSelectorFS() GetTEBSelectorFS
+476 pascal ConvertToGlobalHandle(long) ConvertToGlobalHandle
+477 stub WOAFullScreen
+478 stub WOATerminateProcess
+479 pascal KERNEL_479(long) VWin32_EventSet  # ???
+480 pascal16 _EnterWin16Lock() SYSLEVEL_EnterWin16Lock
+481 pascal16 _LeaveWin16Lock() SYSLEVEL_LeaveWin16Lock
+482 pascal LoadSystemLibrary32(str) LoadLibrary32A   # FIXME!
+483 pascal GetModuleFileName32(long str long) GetModuleFileName32A
+484 pascal SetProcessDWORD(long s_word long) SetProcessDword
 485 pascal GetProcessDWORD(long s_word) GetProcessDword
-486 stub KERNEL_486
+486 pascal FreeLibrary32(long) FreeLibrary32
+487 stub MapProcessHandle
+488 pascal GetModuleHandle32(str) GetModuleHandle32A
+489 stub KERNEL_489  # VWin32_BoostWithDecay
+490 stub KERNEL_490
 491 stub RegisterServiceProcess
+492 stub WOAAbort
+493 stub UTInit
+494 stub KERNEL_494
 
-# Those stubs can be found in WindowNT3.51 krnl386.exe. Some are used by Win95
-# too, some seem to specify different functions in Win95... Ugh.
+
+# 500-544 are WinNT extensions; some are also available in Win95
+
 500 pascal WOW16Call(word word word) WOW16Call
-501 stub KDDBGOUT
+501 stub KDDBGOUT                                               # Both NT/95 (?)
 502 stub WOWGETNEXTVDMCOMMAND
 503 stub WOWREGISTERSHELLWINDOWHANDLE
 504 stub WOWLOADMODULE
@@ -340,14 +415,14 @@
 509 stub WOWKILLREMOTETASK
 511 stub WOWKILLREMOTETASK
 512 stub WOWQUERYDEBUG
-513 pascal   LoadLibraryEx32W(ptr long long) LoadLibraryEx32W16
-514 pascal16 FreeLibrary32W(long) FreeLibrary32
-515 pascal   GetProcAddress32W(long str) GetProcAddress32
-516 pascal GetVDMPointer32W(segptr long) GetVDMPointer32W
-517 pascal CallProc32W() WIN16_CallProc32W
-518 pascal CallProcEx32W() WIN16_CallProcEx32W 
+513 pascal   LoadLibraryEx32W(ptr long long) LoadLibraryEx32W16 # Both NT/95
+514 pascal16 FreeLibrary32W(long) FreeLibrary32                 # Both NT/95
+515 pascal   GetProcAddress32W(long str) GetProcAddress32       # Both NT/95
+516 pascal   GetVDMPointer32W(segptr long) GetVDMPointer32W     # Both NT/95
+517 pascal   CallProc32W() WIN16_CallProc32W                    # Both NT/95
+518 pascal   CallProcEx32W() WIN16_CallProcEx32W                # Both NT/95
 519 stub EXITKERNELTHUNK
-# the __MOD_ variables are WORD datareferences.
+# the __MOD_ variables are WORD datareferences, the current values are invented.
 520 equate __MOD_KERNEL 4200
 521 equate __MOD_DKERNEL 4201
 522 equate __MOD_USER 4203
@@ -361,25 +436,83 @@
 530 equate __MOD_TOOLHELP 4211
 531 equate __MOD_MMEDIA 4212
 532 equate __MOD_COMMDLG 4213
-540 stub KERNEL_540
 541 stub WOWSETEXITONLASTAPP
 544 stub WOWSETCOMPATHANDLE
 
-600 stub KERNEL_600
-601 stub KERNEL_601
-604 stub KERNEL_604
-605 stub KERNEL_605
-606 stub KERNEL_606
-607 pascal KERNEL_607(long long long) _KERNEL_607
-608 pascal KERNEL_608(long long long) _KERNEL_608
-611 pascal KERNEL_611(long long) _KERNEL_611
-612 stub KERNEL_612
-613 stub KERNEL_613
-614 stub KERNEL_614
-619 pascal KERNEL_619(word long long) _KERNEL_619
-621 stub KERNEL_621
+
+# 531-568 are Win95-only extensions.
+# NOTE: Ordinals 531,532,541 clash with the WinNT extensions given above! Argh!
+
+#531 stub ConvertClipboardHandleLS
+#532 stub ConvertClipboardHandleSL
+533 stub ConvertDDEHandleLS
+534 stub ConvertDDEHandleSL
+535 pascal VWin32_BoostThreadGroup(long long) VWin32_BoostThreadGroup
+536 pascal VWin32_BoostThreadStatic(long long) VWin32_BoostThreadStatic
+537 stub KERNEL_537
+538 stub ThunkTheTemplateHandle
+540 stub KERNEL_540
+#541 stub KERNEL_541
+542 stub KERNEL_542
+543 stub KERNEL_543
+560 stub KERNEL_560  # (thunklet)  # InitThunkletHandler
+561 stub KERNEL_561  # (thunklet)  # AllocLSThunklet
+562 stub KERNEL_562  # (thunklet)  # AllocSLThunklet
+563 stub KERNEL_563  # (thunklet)  # FindSLThunklet
+564 stub KERNEL_564  # (thunklet)  # FindLSThunklet
+565 stub KERNEL_565  # (thunklet)  # AllocLSThunklet_Special
+566 stub KERNEL_566  # (thunklet)  # AllocSLThunklet_Special
+567 stub KERNEL_567  # (thunklet)  # AllocLSThunkletEx
+568 stub KERNEL_568  # (thunklet)  # AllocSLThunkletEx
+
+
+# 600-653 are Win95 only
+
+600 stub KERNEL_600  # AllocSelector (?)
+601 stub KERNEL_601  # FreeSelector (?)
+602 stub GetCurrentHInstanceDS
+603 stub KERNEL_603  # OutputDebugString (?)
+604 stub KERNEL_604  # (cbclient) # Thunk_CBClient
+605 stub KERNEL_605  # (thunklet) # AllocSLThunklet
+606 stub KERNEL_606  # (thunklet) # AllocLSThunklet
+607 pascal KERNEL_607(long long long) _KERNEL_607  # AllocLSThunklet_Systhunk
+608 pascal KERNEL_608(long long long) _KERNEL_608  # AllocSLThunklet_Systhunk
+609 stub KERNEL_609  # (thunklet) # FindSLThunklet
+610 stub KERNEL_610  # (thunklet) # FindLSThunklet
+611 pascal16 KERNEL_611(long long) _KERNEL_611  # FreeThunklet
+612 pascal16 KERNEL_612(ptr) _KERNEL_612  # IsSLThunklet
+613 stub KERNEL_613  # (cbclient)
+614 stub KERNEL_614  # (cbclient)
+615 stub KERNEL_615  # (cbclient)
+616 stub KERNEL_616  # (cbclient)
+617 stub KERNEL_617  # (cbclient)
+618 stub KERNEL_618  # (cbclient)
+619 pascal16 RegisterCBClient(word long long) RegisterCBClient
+620 stub KERNEL_620  # (cbclient)
+621 stub KERNEL_621  # (cbclient)
+622 stub UnRegisterCBClient
+623 pascal16 InitCBClient(long) InitCBClient
+624 pascal SetFastQueue(long long) SetFastQueue
+625 pascal GetFastQueue() GetFastQueue
+626 stub SmashEnvironment
 627 stub IsBadFlatReadWritePtr
 630 register C16ThkSL() C16ThkSL
 631 register C16ThkSL01() C16ThkSL01
 651 pascal ThunkConnect16(str str word long ptr str word) ThunkConnect16
-700 pascal KERNEL_700() stub_KERNEL_700
+652 stub IsThreadId
+653 stub OkWithKernelToChangeUsers
+
+
+# 700-704 are Win95 only
+
+700 pascal SSInit() SSInit
+701 stub SSOnBigStack
+702 stub SSCall
+703 stub CallProc32WFix
+704 stub SSConfirmSmallStack
+
+
+# Win95 krnl386.exe also exports ordinals 802-864,
+# however, those seem to be only callback stubs that are
+# never called directly by other modules ...
+
diff --git a/if1632/keyboard.spec b/if1632/keyboard.spec
index 50e9960..189c59e 100644
--- a/if1632/keyboard.spec
+++ b/if1632/keyboard.spec
@@ -1,9 +1,9 @@
 name	keyboard
 type	win16
 
-#1	pascal	Inquire
-#2	pascal	Enable
-#3	pascal	Disable
+1   pascal16 Inquire(ptr) KeyboardInquire
+2   pascal16 Enable(segptr ptr) KeyboardEnable
+3   pascal16 Disable() KeyboardDisable
 4   pascal16 ToAscii(word word ptr ptr word) ToAscii16
 5   pascal16 AnsiToOem(str ptr) AnsiToOem16
 6   pascal16 OemToAnsi(str ptr) OemToAnsi16
diff --git a/if1632/mmsystem.spec b/if1632/mmsystem.spec
index d13ae12..d70126c 100644
--- a/if1632/mmsystem.spec
+++ b/if1632/mmsystem.spec
@@ -49,7 +49,7 @@
 301    pascal  midiInGetNumDevs() midiInGetNumDevs16
 302    pascal  midiInGetDevCaps(word ptr word) midiInGetDevCaps16
 303    pascal  midiInGetErrorText(word ptr word) midiInGetErrorText16
-304    pascal  midiInOpen(ptr word ptr long long long) midiInOpen16
+304    pascal  midiInOpen(ptr word long long long) midiInOpen16
 305    pascal  midiInClose(word) midiInClose16
 306    pascal  midiInPrepareHeader(word ptr word) midiInPrepareHeader16
 307    pascal  midiInUnprepareHeader(word ptr word) midiInUnprepareHeader16
@@ -155,7 +155,7 @@
 1213   pascal  mmioWrite(word ptr long) mmioWrite16
 1214   pascal  mmioSeek(word long word) mmioSeek16
 1215   pascal  mmioGetInfo(word ptr word) mmioGetInfo16
-1216   pascal  MMIOSETINFO(word ptr word) mmioSetInfo
+1216   pascal  MMIOSETINFO(word ptr word) mmioSetInfo16
 1217   pascal  MMIOSETBUFFER(word ptr long word) mmioSetBuffer
 1218   pascal  mmioFlush(word word) mmioFlush16
 1219   pascal  mmioAdvance(word ptr word) mmioAdvance16
diff --git a/if1632/mouse.spec b/if1632/mouse.spec
index fa5dac8..379f3e5 100644
--- a/if1632/mouse.spec
+++ b/if1632/mouse.spec
@@ -1,9 +1,9 @@
 name	mouse
 type	win16
 
-1 stub INQUIRE
-2 stub ENABLE
-3 stub DISABLE
+1 pascal16 Inquire(ptr) MouseInquire
+2 pascal16 Enable(segptr) MouseEnable
+3 pascal16 Disable() MouseDisable
 4 stub MOUSEGETINTVECT
 5 stub GETSETMOUSEDATA
 #Control Panel thinks this is implemented if it is available
diff --git a/if1632/relay.c b/if1632/relay.c
index 2d5e33e..ee7af27 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -425,6 +425,7 @@
 	DWORD *args, ret;
         VA_LIST16 valist;
 	int i;
+	int aix;
 	dbg_decl_str(relay, 1024);
 
         VA_START16( valist );
@@ -434,17 +435,23 @@
 	dsprintf(relay, "CallProc32W(%ld,%ld,%p, Ex%d args[",nrofargs,argconvmask,proc32,Ex);
 	args = (DWORD*)HEAP_xalloc( GetProcessHeap(), 0,
                                     sizeof(DWORD)*nrofargs );
+	/* CallProcEx doesn't need its args reversed */
 	for (i=0;i<nrofargs;i++) {
+		if (Ex) {
+		   aix = i;
+		} else {
+		   aix = nrofargs - i - 1;
+		}
 		if (argconvmask & (1<<i))
                 {
                     SEGPTR ptr = VA_ARG16( valist, SEGPTR );
-                    args[nrofargs-i-1] = (DWORD)PTR_SEG_TO_LIN(ptr);
+                    args[aix] = (DWORD)PTR_SEG_TO_LIN(ptr);
                     dsprintf(relay,"%08lx(%p),",ptr,PTR_SEG_TO_LIN(ptr));
 		}
                 else
                 {
-                    args[nrofargs-i-1] = VA_ARG16( valist, DWORD );
-                    dsprintf(relay,"%ld,",args[nrofargs-i-1]);
+                    args[aix] = VA_ARG16( valist, DWORD );
+                    dsprintf(relay,"%ld,",args[aix]);
 		}
 	}
 	dsprintf(relay,"])");
diff --git a/if1632/shell.spec b/if1632/shell.spec
index f8a99b2..eaddc95 100644
--- a/if1632/shell.spec
+++ b/if1632/shell.spec
@@ -32,7 +32,7 @@
 102 pascal16 RegisterShellHook(word word) RegisterShellHook
 103 pascal   ShellHookProc(word word long) ShellHookProc
 
-#  157 RESTARTDIALOG
+157 stub RESTARTDIALOG
 #  166 PICKICONDLG
 
 262 pascal16 DriveType(long) GetDriveType16
diff --git a/if1632/thunk.c b/if1632/thunk.c
index 39d5b1d..f1f60d0 100644
--- a/if1632/thunk.c
+++ b/if1632/thunk.c
@@ -566,6 +566,28 @@
     return defSignalProc16;
 }
 
+/***********************************************************************
+ *           THUNK_CreateThread16   (KERNEL.441)
+ */
+static DWORD CALLBACK THUNK_StartThread16( LPVOID threadArgs )
+{
+    FARPROC16 start = ((FARPROC16 *)threadArgs)[0];
+    DWORD     param = ((DWORD *)threadArgs)[1];
+    HeapFree( GetProcessHeap(), 0, threadArgs );
+
+    return CallTo16_long_l( start, param );
+}
+HANDLE32 WINAPI THUNK_CreateThread16( SECURITY_ATTRIBUTES *sa, DWORD stack,
+                                      FARPROC16 start, SEGPTR param,
+                                      DWORD flags, LPDWORD id )
+{
+    DWORD *threadArgs = HeapAlloc( GetProcessHeap(), 0, 2*sizeof(DWORD) );
+    if (!threadArgs) return INVALID_HANDLE_VALUE32;
+    threadArgs[0] = (DWORD)start;
+    threadArgs[1] = (DWORD)param;
+
+    return CreateThread( sa, stack, THUNK_StartThread16, threadArgs, flags, id );
+}
 
 /***********************************************************************
  *           THUNK_WOWCallback16Ex	(WOW32.3)(KERNEL32.55)
@@ -783,7 +805,7 @@
 
     *x++ = 0xB8; *((WORD *)x)++ = ds;
     *x++ = 0x8E; *x++ = 0xC0;
-    *x++ = 0x60; *x++ = 0x0F; *x++ = 0xB7; *x++ = 0xC9;
+    *x++ = 0x66; *x++ = 0x0F; *x++ = 0xB7; *x++ = 0xC9;
     *x++ = 0x67; *x++ = 0x66; *x++ = 0x26; *x++ = 0x8B;
                  *x++ = 0x91; *((DWORD *)x)++ = EDX_reg(context);
 
diff --git a/if1632/user.spec b/if1632/user.spec
index 66a3bb5..a91fa00 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -431,7 +431,7 @@
 473 pascal   AnsiPrev(segptr segptr) AnsiPrev16
 475 pascal16 SetScrollInfo(word s_word ptr word) SetScrollInfo16
 476 pascal16 GetScrollInfo(word s_word ptr) GetScrollInfo16
-477 stub GetKeyboardLayoutName
+477 pascal16 GetKeyboardLayoutName(ptr) GetKeyboardLayoutName16
 478 stub LoadKeyboardLayout
 479 stub MenuItemFromPoint
 480 stub GetUserLocalObjType
diff --git a/if1632/winaspi.spec b/if1632/winaspi.spec
index ab2d77b..01af0f8 100644
--- a/if1632/winaspi.spec
+++ b/if1632/winaspi.spec
@@ -4,5 +4,5 @@
 1	pascal16 GetASPISupportInfo() GetASPISupportInfo16
 2	pascal16 SendASPICommand(segptr) SendASPICommand16
 3       stub INSERTINASPICHAIN
-4	pascal GETASPIDLLVERSION() GetASPIDLLVersion
+4	pascal GETASPIDLLVERSION() GetASPIDLLVersion16
 5	stub ___EXPORTEDSTUB
diff --git a/if1632/wprocs.spec b/if1632/wprocs.spec
index 3695a74..eb9aa4b 100644
--- a/if1632/wprocs.spec
+++ b/if1632/wprocs.spec
@@ -281,9 +281,12 @@
 #
 #400+VXD_ID register <VxD handler>() <VxD handler>
 #
+401 register VXD_VMM() VXD_VMM
 405 register VXD_Timer() VXD_Timer
 414 register VXD_Comm() VXD_Comm
 #415 register VXD_Printer() VXD_Printer
 423 register VXD_Shell() VXD_Shell
 433 register VXD_PageFile() VXD_PageFile
 445 register VXD_Win32s() VXD_Win32s
+451 register VXD_ConfigMG() VXD_ConfigMG
+1490 register VXD_TimerAPI() VXD_TimerAPI
diff --git a/include/acconfig.h b/include/acconfig.h
index f0287ea..66ece2f 100644
--- a/include/acconfig.h
+++ b/include/acconfig.h
@@ -24,6 +24,9 @@
 /* Define if X libraries are not reentrant (compiled without -D_REENTRANT).  */
 #undef NO_REENTRANT_X11
 
+/* Define if libc is not reentrant  */
+#undef NO_REENTRANT_LIBC
+
 /* Define if all debug messages are to be compiled out */
 #undef NO_DEBUG_MSGS
 
diff --git a/include/animate.h b/include/animate.h
index 8867a9f..665fc62 100644
--- a/include/animate.h
+++ b/include/animate.h
@@ -10,7 +10,8 @@
 
 typedef struct tagANIMATE_INFO
 {
-    DWORD dwDummy;
+    LPVOID  lpAvi;   /* pointer to avi data */
+    HFILE32 hFile;   /* handle to avi file */
 } ANIMATE_INFO;
 
 
diff --git a/include/aspi.h b/include/aspi.h
index 9ceafd9..e19d390 100644
--- a/include/aspi.h
+++ b/include/aspi.h
@@ -1,173 +1,118 @@
+/* ASPI definitions used for both WNASPI16 and WNASPI32 */
+
 #if !defined(ASPI_H)
 #define ASPI_H
 
 #pragma pack(1)
 
-#define SS_PENDING	0x00
-#define SS_COMP		0x01
-#define SS_ABORTED	0x02
-#define SS_ERR		0x04
-#define SS_OLD_MANAGE	0xe1
-#define SS_ILLEGAL_MODE	0xe2
-#define SS_NO_ASPI	0xe3
-#define SS_FAILED_INIT	0xe4
-#define SS_INVALID_HA	0x81
-#define SS_INVALID_SRB	0xe0
-#define SS_ASPI_IS_BUSY	0xe5
-#define SS_BUFFER_TO_BIG	0xe6
+#define SS_PENDING      0x00
+#define SS_COMP         0x01
+#define SS_ABORTED      0x02
+#define SS_ERR          0x04
+#define SS_OLD_MANAGE   0xe1
+#define SS_ILLEGAL_MODE 0xe2
+#define SS_NO_ASPI      0xe3
+#define SS_FAILED_INIT  0xe4
+#define SS_INVALID_HA   0x81
+#define SS_INVALID_SRB  0xe0
+#define SS_ASPI_IS_BUSY 0xe5
+#define SS_BUFFER_TO_BIG        0xe6
 
-#define SC_HA_INQUIRY		0x00
-#define SC_GET_DEV_TYPE 	0x01
-#define SC_EXEC_SCSI_CMD	0x02
-#define SC_ABORT_SRB		0x03
-#define SC_RESET_DEV		0x04
+#define SC_HA_INQUIRY           0x00
+#define SC_GET_DEV_TYPE         0x01
+#define SC_EXEC_SCSI_CMD        0x02
+#define SC_ABORT_SRB            0x03
+#define SC_RESET_DEV            0x04
+
 
 /* Host adapter status codes */
-#define HASTAT_OK		0x00
-#define HASTAT_SEL_TO		0x11
-#define HASTAT_DO_DU		0x12
-#define HASTAT_BUS_FREE		0x13
-#define HASTAT_PHASE_ERR	0x14
+#define HASTAT_OK               0x00
+#define HASTAT_SEL_TO           0x11
+#define HASTAT_DO_DU            0x12
+#define HASTAT_BUS_FREE         0x13
+#define HASTAT_PHASE_ERR        0x14
 
 /* Target status codes */
-#define STATUS_GOOD		0x00
-#define STATUS_CHKCOND		0x02
-#define STATUS_BUSY		0x08
-#define STATUS_RESCONF		0x18
+#define STATUS_GOOD             0x00
+#define STATUS_CHKCOND          0x02
+#define STATUS_BUSY             0x08
+#define STATUS_RESCONF          0x18
+
+#ifdef linux
+
+/* This is a duplicate of the sg_header from /usr/src/linux/include/scsi/sg.h
+ * kernel 2.0.30
+ * This will probably break at some point, but for those who don't have
+ * kernels installed, I think this should still work.
+ *
+ */
+
+struct sg_header
+ {
+  int pack_len;    /* length of incoming packet <4096 (including header) */
+  int reply_len;   /* maximum length <4096 of expected reply */
+  int pack_id;     /* id number of packet */
+  int result;      /* 0==ok, otherwise refer to errno codes */
+  unsigned int twelve_byte:1; /* Force 12 byte command length for group 6 & 7
+commands  */
+  unsigned int other_flags:31;                  /* for future use */
+  unsigned char sense_buffer[16]; /* used only by reads */
+  /* command follows then data for command */
+ };
+
+#define SCSI_OFF sizeof(struct sg_header)
+#endif
+
+#define ASPI_POSTING(prb) (prb->SRB_Flags & 0x1)
+
+#define HOST_TO_TARGET(prb) (((prb->SRB_Flags>>3) & 0x3) == 0x2)
+#define TARGET_TO_HOST(prb) (((prb->SRB_Flags>>3) & 0x3) == 0x1)
+#define NO_DATA_TRANSFERED(prb) (((prb->SRB_Flags>>3) & 0x3) == 0x3)
+
+#define SRB_ENABLE_RESIDUAL_COUNT 0x4
+#define SRB_EVENT_NOTIFY 0x40 /* Enable ASPI event notification */
+
+#define INQUIRY_VENDOR          8
+
+#define MUSTEK_SCSI_AREA_AND_WINDOWS 0x04
+#define MUSTEK_SCSI_READ_SCANNED_DATA 0x08
+#define MUSTEK_SCSI_GET_IMAGE_STATUS 0x0f
+#define MUSTEK_SCSI_ADF_AND_BACKTRACE 0x10
+#define MUSTEK_SCSI_CCD_DISTANCE 0x11
+#define MUSTEK_SCSI_START_STOP 0x1b
+
+#define CMD_TEST_UNIT_READY 0x00
+#define CMD_REQUEST_SENSE 0x03
+#define CMD_INQUIRY 0x12
+
+/* scanner commands - just for debug */
+#define CMD_SCAN_GET_DATA_BUFFER_STATUS 0x34
+#define CMD_SCAN_GET_WINDOW 0x25
+#define CMD_SCAN_OBJECT_POSITION 0x31
+#define CMD_SCAN_READ 0x28
+#define CMD_SCAN_RELEASE_UNIT 0x17
+#define CMD_SCAN_RESERVE_UNIT 0x16
+#define CMD_SCAN_SCAN 0x1b
+#define CMD_SCAN_SEND 0x2a
+#define CMD_SCAN_CHANGE_DEFINITION 0x40
+
+#define INQURIY_CMDLEN 6
+#define INQURIY_REPLY_LEN 96
+#define INQUIRY_VENDOR 8
+
+#define SENSE_BUFFER(prb) (&prb->CDBByte[prb->SRB_CDBLen])
 
 
-typedef union SRB16 * LPSRB16;
-
-struct SRB_HaInquiry16 {
-  BYTE	SRB_cmd;
-  BYTE	SRB_Status;
-  BYTE	SRB_HaId;
-  BYTE	SRB_Flags;
-  WORD	SRB_55AASignature;
-  WORD	SRB_ExtBufferSize;
-  BYTE	HA_Count;
-  BYTE	HA_SCSI_ID;
-  BYTE	HA_ManagerId[16];
-  BYTE	HA_Identifier[16];
-  BYTE	HA_Unique[16];
-  BYTE	HA_ExtBuffer[4];
-} WINE_PACKED;
-
-typedef struct SRB_HaInquiry16 SRB_HaInquiry16;
-
-struct SRB_ExecSCSICmd16 {
-  BYTE        SRB_Cmd;                /* ASPI command code	      (W)  */
-  BYTE        SRB_Status;             /* ASPI command status byte     (R)  */
-  BYTE        SRB_HaId;               /* ASPI host adapter number     (W)  */
-  BYTE        SRB_Flags;              /* ASPI request flags	      (W)  */
-  DWORD       SRB_Hdr_Rsvd;           /* Reserved, MUST = 0	      (-)  */
-  BYTE        SRB_Target;             /* Target's SCSI ID	      (W)  */
-  BYTE        SRB_Lun;                /* Target's LUN number	      (W)  */
-  DWORD       SRB_BufLen;             /* Data Allocation LengthPG     (W/R)*/
-  BYTE        SRB_SenseLen;           /* Sense Allocation Length      (W)  */
-  SEGPTR      SRB_BufPointer;         /* Data Buffer Pointer	      (W)  */
-  DWORD       SRB_Rsvd1;              /* Reserved, MUST = 0	      (-/W)*/
-  BYTE        SRB_CDBLen;             /* CDB Length = 6		      (W)  */
-  BYTE        SRB_HaStat;             /* Host Adapter Status	      (R)  */
-  BYTE        SRB_TargStat;           /* Target Status		      (R)  */
-  FARPROC16   SRB_PostProc;	      /* Post routine		      (W)  */
-  BYTE        SRB_Rsvd2[34];          /* Reserved, MUST = 0                */
-  BYTE		CDBByte[0];	      /* SCSI CBD - variable length   (W)  */
-  /* variable example for 6 byte cbd
-   * BYTE        CDBByte[6];             * SCSI CDB                    (W) *
-   * BYTE        SenseArea6[SENSE_LEN];  * Request Sense buffer 	(R) *
-   */
-} WINE_PACKED ;
-
-typedef struct SRB_ExecSCSICmd16 SRB_ExecSCSICmd16;
-
-struct SRB_ExecSCSICmd32 {
-  BYTE        SRB_Cmd;            /* ASPI command code = SC_EXEC_SCSI_CMD */
-  BYTE        SRB_Status;         /* ASPI command status byte */
-  BYTE        SRB_HaId;           /* ASPI host adapter number */
-  BYTE        SRB_Flags;          /* ASPI request flags */
-  DWORD       SRB_Hdr_Rsvd;       /* Reserved */
-  BYTE        SRB_Target;         /* Target's SCSI ID */
-  BYTE        SRB_Lun;            /* Target's LUN number */
-  WORD        SRB_Rsvd1;          /* Reserved for Alignment */
-  DWORD       SRB_BufLen;         /* Data Allocation Length */
-  BYTE        *SRB_BufPointer;    /* Data Buffer Point */
-  BYTE        SRB_SenseLen;       /* Sense Allocation Length */
-  BYTE        SRB_CDBLen;         /* CDB Length */
-  BYTE        SRB_HaStat;         /* Host Adapter Status */
-  BYTE        SRB_TargStat;       /* Target Status */
-  void        (*SRB_PostProc)();  /* Post routine */
-  void        *SRB_Rsvd2;         /* Reserved */
-  BYTE        SRB_Rsvd3[16];      /* Reserved for expansion */
-  BYTE        CDBByte[16];        /* SCSI CDB */
-  BYTE        SenseArea[0];       /* Request sense buffer - var length */
+/* Just a container for seeing what devices are open */
+struct ASPI_DEVICE_INFO {
+    struct ASPI_DEVICE_INFO *   next;
+    int                         fd;
+    int                         hostId;
+    int                         target;
+    int                         lun;
 };
 
-typedef struct SRB_ExecSCSICmd32 SRB_ExecSCSICmd32;
-
-struct SRB_Abort16 {
-  BYTE        SRB_Cmd;            /* ASPI command code = SC_ABORT_SRB */
-  BYTE        SRB_Status;         /* ASPI command status byte */
-  BYTE        SRB_HaId;           /* ASPI host adapter number */
-  BYTE        SRB_Flags;          /* ASPI request flags */
-  DWORD       SRB_Hdr_Rsvd;       /* Reserved, MUST = 0 */
-  LPSRB16     SRB_ToAbort;        /* Pointer to SRB to abort */
-} WINE_PACKED;
-
-typedef struct SRB_Abort16 SRB_Abort16;
-
-struct SRB_BusDeviceReset16 {
-  BYTE        SRB_Cmd;            /* ASPI command code = SC_RESET_DEV */
-  BYTE        SRB_Status;         /* ASPI command status byte */
-  BYTE        SRB_HaId;           /* ASPI host adapter number */
-  BYTE        SRB_Flags;          /* ASPI request flags */
-  DWORD       SRB_Hdr_Rsvd;       /* Reserved, MUST = 0 */
-  BYTE        SRB_Target;         /* Target's SCSI ID */
-  BYTE        SRB_Lun;            /* Target's LUN number */
-  BYTE        SRB_ResetRsvd1[14]; /* Reserved, MUST = 0 */
-  BYTE        SRB_HaStat;         /* Host Adapter Status */
-  BYTE        SRB_TargStat;       /* Target Status */
-  SEGPTR      SRB_PostProc;       /* Post routine */
-  BYTE        SRB_ResetRsvd2[34]; /* Reserved, MUST = 0 */
-} WINE_PACKED;
-
-typedef struct SRB_BusDeviceReset16 SRB_BusDeviceReset16;
-
-struct SRB_GDEVBlock16 {
-  BYTE        SRB_Cmd;            /* ASPI command code = SC_GET_DEV_TYPE */
-  BYTE        SRB_Status;         /* ASPI command status byte */
-  BYTE        SRB_HaId;           /* ASPI host adapter number */
-  BYTE        SRB_Flags;          /* ASPI request flags */
-  DWORD       SRB_Hdr_Rsvd;       /* Reserved, MUST = 0 */
-  BYTE        SRB_Target;         /* Target's SCSI ID */
-  BYTE        SRB_Lun;            /* Target's LUN number */
-  BYTE        SRB_DeviceType;     /* Target's peripheral device type */
-} WINE_PACKED;
-
-typedef struct SRB_GDEVBlock16 SRB_GDEVBlock16;
-
-
-
-struct SRB_Common16 {
-  BYTE	SRB_cmd;
-};
-
-
-typedef struct SRB_Common16 SRB_Common16;
-
-
-union SRB16 {
-  SRB_Common16		common;
-  SRB_HaInquiry16	inquiry;
-  SRB_ExecSCSICmd16	cmd;
-  SRB_Abort16		abort;
-  SRB_BusDeviceReset16	reset;
-  SRB_GDEVBlock16	devtype;
-};
-
-typedef union SRB16 SRB16;
-
-
-
+typedef struct ASPI_DEVICE_INFO ASPI_DEVICE_INFO;
+static ASPI_DEVICE_INFO *ASPI_open_devices = NULL;
 
 #endif
diff --git a/include/authors.h b/include/authors.h
index 8481837..e930c97 100644
--- a/include/authors.h
+++ b/include/authors.h
@@ -30,6 +30,7 @@
     "Carsten Fallesen",
     "Paul Falstad",
     "David Faure",
+    "Wesley Filardo",
     "Claus Fischer",
     "Olaf Flebbe",
     "Chad Fraleigh",
@@ -47,6 +48,7 @@
     "Jochen Hoenicke",
     "Onno Hovers",
     "Jeffrey Hsu",
+    "Peter Hunnisett",
     "Miguel de Icaza",
     "Jukka Iivonen",
     "Lee Jaekil",
@@ -89,6 +91,7 @@
     "Dimitrie O. Paun",
     "Jim Peterson",
     "Robert Pouliot",
+    "Petter Reinholdtsen",
     "Keith Reynolds",
     "Slaven Rezic",
     "John Richardson",
diff --git a/include/commctrl.h b/include/commctrl.h
index 4d41405..cf72b0c 100644
--- a/include/commctrl.h
+++ b/include/commctrl.h
@@ -415,26 +415,27 @@
 #define HDM_GETITEMCOUNT        (HDM_FIRST+0)
 #define HDM_INSERTITEM32A       (HDM_FIRST+1)
 #define HDM_INSERTITEM32W       (HDM_FIRST+10)
-#define HDM_INSERTITEM WINELIB_NAME_AW(HDM_INSERTITEM)
+#define HDM_INSERTITEM		WINELIB_NAME_AW(HDM_INSERTITEM)
 #define HDM_DELETEITEM          (HDM_FIRST+2)
 #define HDM_GETITEM32A          (HDM_FIRST+3)
 #define HDM_GETITEM32W          (HDM_FIRST+11)
-#define HDM_GETITEM WINELIB_NAME_AW(HDM_GETITEM)
+#define HDM_GETITEM		WINELIB_NAME_AW(HDM_GETITEM)
 #define HDM_SETITEM32A          (HDM_FIRST+4)
 #define HDM_SETITEM32W          (HDM_FIRST+12)
-#define HDM_SETITEM WINELIB_NAME_AW(HDM_SETITEM)
+#define HDM_SETITEM		WINELIB_NAME_AW(HDM_SETITEM)
 #define HDM_LAYOUT              (HDM_FIRST+5)
 #define HDM_HITTEST             (HDM_FIRST+6)
 #define HDM_GETITEMRECT         (HDM_FIRST+7)
 #define HDM_SETIMAGELIST        (HDM_FIRST+8)
 #define HDM_GETIMAGELIST        (HDM_FIRST+9)
 
-
 #define HDM_ORDERTOINDEX        (HDM_FIRST+15)
 #define HDM_CREATEDRAGIMAGE     (HDM_FIRST+16)
 #define HDM_GETORDERARRAY       (HDM_FIRST+17)
 #define HDM_SETORDERARRAY       (HDM_FIRST+18)
 #define HDM_SETHOTDIVIDER       (HDM_FIRST+19)
+#define HDM_GETUNICODEFORMAT    CCM_GETUNICODEFORMAT
+#define HDM_SETUNICODEFORMAT    CCM_SETUNICODEFORMAT
 
 #define HDN_FIRST               (0U-300U)
 #define HDN_LAST                (0U-399U)
@@ -468,7 +469,6 @@
 #define HDN_BEGINDRACK          (HDN_FIRST-10)
 #define HDN_ENDDRACK            (HDN_FIRST-11)
 
-
 typedef struct _HD_LAYOUT
 {
     RECT32      *prc;
@@ -477,7 +477,7 @@
 
 #define HD_LAYOUT   HDLAYOUT
 
-typedef struct _HD_ITEMA
+typedef struct _HD_ITEM32A
 {
     UINT32    mask;
     INT32     cxy;
@@ -490,7 +490,7 @@
     INT32     iOrder;
 } HDITEM32A, *LPHDITEM32A;
 
-typedef struct _HD_ITEMW
+typedef struct _HD_ITEM32W
 {
     UINT32    mask;
     INT32     cxy;
@@ -519,48 +519,91 @@
 
 #define HD_HITTESTINFO   HDHITTESTINFO
 
-typedef struct tagNMHEADERA
+typedef struct tagNMHEADER32A
 {
     NMHDR     hdr;
     INT32     iItem;
     INT32     iButton;
     HDITEM32A *pitem;
-} NMHEADERA, *LPNMHEADERA;
+} NMHEADER32A, *LPNMHEADER32A;
 
-#ifndef __WINE__
+typedef struct tagNMHEADER32W
+{
+    NMHDR     hdr;
+    INT32     iItem;
+    INT32     iButton;
+    HDITEM32W *pitem;
+} NMHEADER32W, *LPNMHEADER32W;
+
+#define NMHEADER		WINELIB_NAME_AW(NMHEADER)
+#define LPNMHEADER		WINELIB_NAME_AW(LPNMHEADER)
+
+typedef struct tagNMHDDISPINFO32A
+{
+    NMHDR     hdr;
+    INT32     iItem;
+    UINT32    mask;
+    LPSTR     pszText;
+    INT32     cchTextMax;
+    INT32     iImage;
+    LPARAM    lParam;
+} NMHDDISPINFO32A, *LPNMHDDISPINFO32A;
+
+typedef struct tagNMHDDISPINFO32W
+{
+    NMHDR     hdr;
+    INT32     iItem;
+    UINT32    mask;
+    LPWSTR    pszText;
+    INT32     cchTextMax;
+    INT32     iImage;
+    LPARAM    lParam;
+} NMHDDISPINFO32W, *LPNMHDDISPINFO32W;
+
+#define NMHDDISPINFO		WINELIB_NAME_AW(NMHDDISPINFO)
+#define LPNMHDDISPINFO		WINELIB_NAME_AW(LPNMHDDISPINFO)
+
 #define Header_GetItemCount(hwndHD) \
-  (INT32)SNDMSG((hwndHD),HDM_GETITEMCOUNT,0,0L)
-#define Header_InsertItem(hwndHD,i,phdi) \
-  (INT32)SNDMSG((hwndHD),HDM_INSERTITEM,(WPARAM32)(INT32)(i),(LPARAM)(const HDITEM *)(phdi))
+  (INT32)SendMessage32A((hwndHD),HDM_GETITEMCOUNT,0,0L)
+#define Header_InsertItem32A(hwndHD,i,phdi) \
+  (INT32)SendMessage32A((hwndHD),HDM_INSERTITEM32A,(WPARAM32)(INT32)(i),(LPARAM)(const HDITEM32A*)(phdi))
+#define Header_InsertItem32W(hwndHD,i,phdi) \
+  (INT32)SendMessage32W((hwndHD),HDM_INSERTITEM32W,(WPARAM32)(INT32)(i),(LPARAM)(const HDITEM32W*)(phdi))
+#define Header_InsertItem WINELIB_NAME_AW(Header_InsertItem)
 #define Header_DeleteItem(hwndHD,i) \
-  (BOOL32)SNDMSG((hwndHD),HDM_DELETEITEM,(WPARAM32)(INT32)(i),0L)
-#define Header_GetItem(hwndHD,i,phdi) \
-  (BOOL32)SNDMSG((hwndHD),HDM_GETITEM,(WPARAM32)(INT32)(i),(LPARAM)(HDITEM *)(phdi))
-#define Header_SetItem(hwndHD,i,phdi) \
-  (BOOL32)SNDMSG((hwndHD),HDM_SETITEM,(WPARAM32)(INT32)(i),(LPARAM)(const HDITEM *)(phdi))
+  (BOOL32)SendMessage32A((hwndHD),HDM_DELETEITEM,(WPARAM32)(INT32)(i),0L)
+#define Header_GetItem32A(hwndHD,i,phdi) \
+  (BOOL32)SendMessage32A((hwndHD),HDM_GETITEM32A,(WPARAM32)(INT32)(i),(LPARAM)(HDITEM32A*)(phdi))
+#define Header_GetItem32W(hwndHD,i,phdi) \
+  (BOOL32)SendMessage32W((hwndHD),HDM_GETITEM32W,(WPARAM32)(INT32)(i),(LPARAM)(HDITEM32W*)(phdi))
+#define Header_GetItem WINELIB_NAME_AW(Header_GetItem)
+#define Header_SetItem32A(hwndHD,i,phdi) \
+  (BOOL32)SendMessage32A((hwndHD),HDM_SETITEM32A,(WPARAM32)(INT32)(i),(LPARAM)(const HDITEM32A*)(phdi))
+#define Header_SetItem32W(hwndHD,i,phdi) \
+  (BOOL32)SendMessage32W((hwndHD),HDM_SETITEM32W,(WPARAM32)(INT32)(i),(LPARAM)(const HDITEM32W*)(phdi))
+#define Header_SetItem WINELIB_NAME_AW(Header_SetItem)
 #define Header_Layout(hwndHD,playout) \
-  (BOOL32)SNDMSG((hwndHD),HDM_LAYOUT,0,(LPARAM)(LPHDLAYOUT)(playout))
+  (BOOL32)SendMessage32A((hwndHD),HDM_LAYOUT,0,(LPARAM)(LPHDLAYOUT)(playout))
 #define Header_GetItemRect(hwnd,iItem,lprc) \
-  (BOOL32)SNDMSG((hwnd),HDM_GETITEMRECT,(WPARAM32)iItem,(LPARAM)lprc)
+  (BOOL32)SendMessage32A((hwnd),HDM_GETITEMRECT,(WPARAM32)iItem,(LPARAM)lprc)
 #define Header_SetImageList(hwnd,himl) \
-  (HIMAGELIST)SNDMSG((hwnd),HDM_SETIMAGELIST,0,(LPARAM)himl)
+  (HIMAGELIST)SendMessage32A((hwnd),HDM_SETIMAGELIST,0,(LPARAM)himl)
 #define Header_GetImageList(hwnd) \
-  (HIMAGELIST)SNDMSG((hwnd),HDM_GETIMAGELIST,0,0)
+  (HIMAGELIST)SendMessage32A((hwnd),HDM_GETIMAGELIST,0,0)
 #define Header_OrderToIndex(hwnd,i) \
-  (INT32)SNDMSG((hwnd),HDM_ORDERTOINDEX,(WPARAM32)i,0)
+  (INT32)SendMessage32A((hwnd),HDM_ORDERTOINDEX,(WPARAM32)i,0)
 #define Header_CreateDragImage(hwnd,i) \
-  (HIMAGELIST)SNDMSG((hwnd),HDM_CREATEDRAGIMAGE,(WPARAM32)i,0)
+  (HIMAGELIST)SendMessage32A((hwnd),HDM_CREATEDRAGIMAGE,(WPARAM32)i,0)
 #define Header_GetOrderArray(hwnd,iCount,lpi) \
-  (BOOL32)SNDMSG((hwnd),HDM_GETORDERARRAY,(WPARAM32)iCount,(LPARAM)lpi)
+  (BOOL32)SendMessage32A((hwnd),HDM_GETORDERARRAY,(WPARAM32)iCount,(LPARAM)lpi)
 #define Header_SetOrderArray(hwnd,iCount,lpi) \
-  (BOOL32)SNDMSG((hwnd),HDM_SETORDERARRAY,(WPARAM32)iCount,(LPARAM)lpi)
+  (BOOL32)SendMessage32A((hwnd),HDM_SETORDERARRAY,(WPARAM32)iCount,(LPARAM)lpi)
 #define Header_SetHotDivider(hwnd,fPos,dw) \
-  (INT32)SNDMSG((hwnd),HDM_SETHOTDIVIDER,(WPARAM32)fPos,(LPARAM)dw)
+  (INT32)SendMessage32A((hwnd),HDM_SETHOTDIVIDER,(WPARAM32)fPos,(LPARAM)dw)
 #define Header_SetUnicodeFormat(hwnd,fUnicode) \
-  (BOOL32)SNDMSG((hwnd),HDM_SETUNICODEFORMAT,(WPARAM32)(fUnicode),0)
+  (BOOL32)SendMessage32A((hwnd),HDM_SETUNICODEFORMAT,(WPARAM32)(fUnicode),0)
 #define Header_GetUnicodeFormat(hwnd) \
-  (BOOL32)SNDMSG((hwnd),HDM_GETUNICODEFORMAT,0,0)
-#endif /* #ifndef __WINE__ */
+  (BOOL32)SendMessage32A((hwnd),HDM_GETUNICODEFORMAT,0,0)
 
 
 /* Toolbar */
@@ -602,7 +645,8 @@
 #define TBIF_LPARAM             0x00000010
 #define TBIF_COMMAND            0x00000020
 #define TBIF_SIZE               0x00000040
- 
+
+#define TBBF_LARGE		0x0001 
 
 #define TB_ENABLEBUTTON          (WM_USER+1)
 #define TB_CHECKBUTTON           (WM_USER+2)
@@ -1342,6 +1386,330 @@
 #define TVN_FIRST               (0U-400U)
 #define TVN_LAST                (0U-499U)
 
+#define TVN_SELCHANGING         (TVN_FIRST-1)
+#define TVN_SELCHANGED          (TVN_FIRST-2)
+#define TVN_GETDISPINFO         (TVN_FIRST-3)
+#define TVN_SETDISPINFO         (TVN_FIRST-4)
+#define TVN_ITEMEXPANDING       (TVN_FIRST-5)
+#define TVN_ITEMEXPANDED        (TVN_FIRST-6)
+#define TVN_BEGINDRAG           (TVN_FIRST-7)
+#define TVN_BEGINRDRAG          (TVN_FIRST-8)
+#define TVN_DELETEITEM          (TVN_FIRST-9)
+#define TVN_BEGINLABELEDIT      (TVN_FIRST-10)
+#define TVN_ENDLABELEDIT        (TVN_FIRST-11)
+#define TVN_KEYDOWN             (TVN_FIRST-12)
+#define TVN_GETINFOTIPA         (TVN_FIRST-13)
+#define TVN_GETINFOTIPW         (TVN_FIRST-14)
+#define TVN_SINGLEEXPAND        (TVN_FIRST-15)
+
+
+#define TVN_SELCHANGINGW        (TVN_FIRST-50)
+#define TVN_SELCHANGEDW         (TVN_FIRST-51)
+#define TVN_GETDISPINFOW        (TVN_FIRST-52)
+#define TVN_SETDISPINFOW        (TVN_FIRST-53)
+#define TVN_ITEMEXPANDINGW      (TVN_FIRST-54)
+#define TVN_ITEMEXPANDEDW       (TVN_FIRST-55)
+#define TVN_BEGINDRAGW          (TVN_FIRST-56)
+#define TVN_BEGINRDRAGW         (TVN_FIRST-57)
+#define TVN_DELETEITEMW         (TVN_FIRST-58)
+#define TVN_BEGINLABELEDITW     (TVN_FIRST-59)
+#define TVN_ENDLABELEDITW       (TVN_FIRST-60)
+
+
+
+#define TVIF_TEXT             0x0001
+#define TVIF_IMAGE            0x0002
+#define TVIF_PARAM            0x0004
+#define TVIF_STATE            0x0008
+#define TVIF_HANDLE           0x0010
+#define TVIF_SELECTEDIMAGE    0x0020
+#define TVIF_CHILDREN         0x0040
+#define TVIF_INTEGRAL         0x0080
+#define TVIF_DI_SETITEM		  0x1000
+
+#define TVI_ROOT              0xffff0000      /* -65536 */
+#define TVI_FIRST             0xffff0001      /* -65535 */
+#define TVI_LAST              0xffff0002      /* -65534 */
+#define TVI_SORT              0xffff0003      /* -65533 */
+
+#define TVIS_FOCUSED          0x0001
+#define TVIS_SELECTED         0x0002
+#define TVIS_CUT              0x0004
+#define TVIS_DROPHILITED      0x0008
+#define TVIS_BOLD             0x0010
+#define TVIS_EXPANDED         0x0020
+#define TVIS_EXPANDEDONCE     0x0040
+#define TVIS_OVERLAYMASK      0x0f00
+#define TVIS_STATEIMAGEMASK   0xf000
+#define TVIS_USERMASK         0xf000
+
+#define TVHT_NOWHERE          0x0001
+#define TVHT_ONITEMICON       0x0002
+#define TVHT_ONITEMLABEL      0x0004
+#define TVHT_ONITEMINDENT     0x0008
+#define TVHT_ONITEMBUTTON     0x0010
+#define TVHT_ONITEMRIGHT      0x0020
+#define TVHT_ONITEMSTATEICON  0x0040
+#define TVHT_ONITEM           0x0046
+#define TVHT_ABOVE            0x0100
+#define TVHT_BELOW            0x0200
+#define TVHT_TORIGHT          0x0400
+#define TVHT_TOLEFT           0x0800
+
+#define TVS_HASBUTTONS        0x0001
+#define TVS_HASLINES          0x0002
+#define TVS_LINESATROOT       0x0004
+#define TVS_EDITLABELS        0x0008
+#define TVS_DISABLEDRAGDROP   0x0010
+#define TVS_SHOWSELALWAYS     0x0020
+#define TVS_RTLREADING        0x0040
+#define TVS_NOTOOLTIPS        0x0080
+#define TVS_CHECKBOXES        0x0100
+#define TVS_TRACKSELECT       0x0200
+#define TVS_SINGLEEXPAND 	  0x0400
+#define TVS_INFOTIP      	  0x0800
+#define TVS_FULLROWSELECT	  0x1000
+#define TVS_NOSCROLL     	  0x2000
+#define TVS_NONEVENHEIGHT	  0x4000
+
+#define TVS_SHAREDIMAGELISTS  0x0000
+#define TVS_PRIVATEIMAGELISTS 0x0400
+
+
+#define TVE_COLLAPSE          0x0001
+#define TVE_EXPAND            0x0002
+#define TVE_TOGGLE            0x0003
+#define TVE_EXPANDPARTIAL     0x4000
+#define TVE_COLLAPSERESET     0x8000
+
+#define TVGN_ROOT             0
+#define TVGN_NEXT             1
+#define TVGN_PREVIOUS         2
+#define TVGN_PARENT           3
+#define TVGN_CHILD            4
+#define TVGN_FIRSTVISIBLE     5
+#define TVGN_NEXTVISIBLE      6
+#define TVGN_PREVIOUSVISIBLE  7
+#define TVGN_DROPHILITE       8
+#define TVGN_CARET            9
+#define TVGN_LASTVISIBLE      10
+
+#define TVC_UNKNOWN           0x00
+#define TVC_BYMOUSE           0x01
+#define TVC_BYKEYBOARD        0x02
+
+
+typedef HANDLE32 HTREEITEM;
+
+typedef struct {
+      UINT32 mask;
+      HTREEITEM hItem;
+      UINT32 state;
+      UINT32 stateMask;
+      LPSTR pszText;
+      int cchTextMax;
+      int iImage;
+      int iSelectedImage;
+      int cChildren;
+      LPARAM lParam;
+} TV_ITEM, *LPTVITEM;
+
+typedef struct {
+      UINT32 mask;
+      HTREEITEM hItem;
+      UINT32 state;
+      UINT32 stateMask;
+      LPSTR pszText;
+      int cchTextMax;
+      int iImage;
+      int iSelectedImage;
+      int cChildren;
+      LPARAM lParam;
+      int iIntegral;
+} TV_ITEMEX, *LPTVITEMEX;
+
+#define TVITEM TV_ITEM
+
+
+
+typedef struct tagTVINSERTSTRUCT {
+        HTREEITEM hParent;
+        HTREEITEM hInsertAfter;
+        TV_ITEM item;
+} TVINSERTSTRUCT, *LPTVINSERTSTRUCT;
+
+typedef struct tagNMTREEVIEW {
+	NMHDR	hdr;
+	UINT32	action;
+	TVITEM	itemOld;
+	TVITEM	itemNew;
+	POINT32	ptDrag;
+} NMTREEVIEW, *LPNMTREEVIEW;
+
+typedef struct tagTVDISPINFO {
+	NMHDR	hdr;
+	TVITEM	item;
+} NMTVDISPINFO, *LPNMTVDISPINFO;
+
+
+
+typedef struct tagTVHITTESTINFO {
+        POINT32 pt;
+        UINT32 flags;
+        HTREEITEM hItem;
+} TVHITTESTINFO, *LPTVHITTESTINFO;
+
+
+#define TreeView_InsertItem(hwndHD, phdi) \
+  (INT32)SendMessage32A((hwnd), TVM_INSERTITEM, 0, \
+                            (LPARAM)(LPTV_INSERTSTRUCT)(phdi))
+#define TreeView_DeleteItem(hwnd, hItem) \
+  (BOOL32)SendMessage32A((hwnd), TVM_DELETEITEM, 0, (LPARAM)(HTREEITEM)(hItem))
+#define TreeView_DeleteAllItems(hwnd) \
+  (BOOL32)SendMessage32A((hwnd), TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT)
+#define TreeView_Expand(hwnd, hitem, code) \
+ (BOOL32)SendMessage32A((hwnd), TVM_EXPAND, (WPARAM)code, \
+	(LPARAM)(HTREEITEM)(hitem))
+
+#define TreeView_GetItemRect(hwnd, hitem, prc, code) \
+ (*(HTREEITEM *)prc = (hitem), (BOOL)SendMessage32A((hwnd), \
+			TVM_GETITEMRECT, (WPARAM32)(code), (LPARAM)(RECT *)(prc)))
+
+#define TreeView_GetCount(hwnd) \
+    (UINT32)SendMessage32A((hwnd), TVM_GETCOUNT, 0, 0)
+#define TreeView_GetIndent(hwnd) \
+    (UINT32)SendMessage32A((hwnd), TVM_GETINDENT, 0, 0)
+#define TreeView_SetIndent(hwnd, indent) \
+    (BOOL32)SendMessage32A((hwnd), TVM_SETINDENT, (WPARAM)indent, 0)
+
+#define TreeView_GetImageList(hwnd, iImage) \
+    (HIMAGELIST)SendMessage32A((hwnd), TVM_GETIMAGELIST, iImage, 0)
+
+#define TreeView_SetImageList(hwnd, himl, iImage) \
+    (HIMAGELIST)SendMessage32A((hwnd), TVM_SETIMAGELIST, iImage, \
+ (LPARAM)(UINT32)(HIMAGELIST)(himl))
+
+#define TreeView_GetNextItem(hwnd, hitem, code) \
+    (HTREEITEM)SendMessage32A((hwnd), TVM_GETNEXTITEM, (WPARAM)code,\
+(LPARAM)(HTREEITEM) (hitem))
+
+#define TreeView_GetChild(hwnd, hitem) \
+	 	 TreeView_GetNextItem(hwnd, hitem , TVGN_CHILD)
+#define TreeView_GetNextSibling(hwnd, hitem) \
+		TreeView_GetNextItem(hwnd, hitem , TVGN_NEXT)
+#define TreeView_GetPrevSibling(hwnd, hitem) \
+		TreeView_GetNextItem(hwnd, hitem , TVGN_PREVIOUS)
+#define TreeView_GetParent(hwnd, hitem) \
+		TreeView_GetNextItem(hwnd, hitem , TVGN_PARENT)
+#define TreeView_GetFirstVisible(hwnd)  \
+		TreeView_GetNextItem(hwnd, NULL, TVGN_FIRSTVISIBLE)
+#define TreeView_GetLastVisible(hwnd)   \
+		TreeView_GetNextItem(hwnd, NULL, TVGN_LASTVISIBLE)
+#define TreeView_GetNextVisible(hwnd, hitem) \
+		TreeView_GetNextItem(hwnd, hitem , TVGN_NEXTVISIBLE)
+#define TreeView_GetPrevVisible(hwnd, hitem) \
+		TreeView_GetNextItem(hwnd, hitem , TVGN_PREVIOUSVISIBLE)
+#define TreeView_GetSelection(hwnd) \
+		TreeView_GetNextItem(hwnd, NULL, TVGN_CARET)
+#define TreeView_GetDropHilight(hwnd) \
+		TreeView_GetNextItem(hwnd, NULL, TVGN_DROPHILITE)
+#define TreeView_GetRoot(hwnd) \
+		TreeView_GetNextItem(hwnd, NULL, TVGN_ROOT)
+#define TreeView_GetLastVisible(hwnd) \
+		TreeView_GetNextItem(hwnd, NULL, TVGN_LASTVISIBLE)
+
+
+#define TreeView_Select(hwnd, hitem, code) \
+ (UINT32)SendMessage32A((hwnd), TVM_SELECTITEM, (WPARAM)code, \
+(LPARAM)(UINT32)(hitem))
+
+
+#define TreeView_SelectItem(hwnd, hitem) \
+		TreeView_Select(hwnd, hitem, TVGN_CARET)
+#define TreeView_SelectDropTarget(hwnd, hitem) \
+        	TreeView_Select(hwnd, hitem, TVGN_DROPHILITE)
+/* FIXME
+#define TreeView_SelectSetFirstVisible(hwnd, hitem)  \ 
+		TreeView_Select(hwnd, hitem, TVGN_FIRSTVISIBLE)
+*/
+
+#define TreeView_GetItem(hwnd, pitem) \
+ (BOOL32)SendMessage32A((hwnd), TVM_GETITEM, 0, (LPARAM) (TV_ITEM *)(pitem))
+
+#define TreeView_SetItem(hwnd, pitem) \
+ (BOOL32)SendMessage32A((hwnd), TVM_SETITEM, 0, (LPARAM)(const TV_ITEM *)(pitem)) 
+
+#define TreeView_EditLabel(hwnd, hitem) \
+    (HWND)SendMessage32A((hwnd), TVM_EDITLABEL, 0, (LPARAM)(HTREEITEM)(hitem))
+
+
+#define TreeView_GetEditControl(hwnd) \
+    (HWND)SendMessage32A((hwnd), TVM_GETEDITCONTROL, 0, 0)
+
+#define TreeView_GetVisibleCount(hwnd) \
+    (UINT32)SendMessage32A((hwnd), TVM_GETVISIBLECOUNT, 0, 0)
+
+#define TreeView_HitTest(hwnd, lpht) \
+    (HTREEITEM)SendMessage32A((hwnd), TVM_HITTEST, 0,\
+(LPARAM)(LPTV_HITTESTINFO)(lpht))
+
+#define TreeView_CreateDragImage(hwnd, hitem) \
+    (HIMAGELIST)SendMessage32A((hwnd), TVM_CREATEDRAGIMAGE, 0,\
+(LPARAM)(HTREEITEM)(hitem))
+
+#define TreeView_SortChildren(hwnd, hitem, recurse) \
+    (BOOL)SendMessage32A((hwnd), TVM_SORTCHILDREN, (WPARAM)recurse,\
+(LPARAM)(HTREEITEM)(hitem))
+
+#define TreeView_EnsureVisible(hwnd, hitem) \
+    (BOOL)SendMessage32A((hwnd), TVM_ENSUREVISIBLE, 0, (LPARAM)(UINT32)(hitem))
+
+#define TreeView_SortChildrenCB(hwnd, psort, recurse) \
+    (BOOL)SendMessage32A((hwnd), TVM_SORTCHILDRENCB, (WPARAM)recurse, \
+    (LPARAM)(LPTV_SORTCB)(psort))
+
+#define TreeView_EndEditLabelNow(hwnd, fCancel) \
+    (BOOL)SendMessage32A((hwnd), TVM_ENDEDITLABELNOW, (WPARAM)fCancel, 0)
+
+#define TreeView_GetISearchString(hwndTV, lpsz) \
+    (BOOL)SendMessage32A((hwndTV), TVM_GETISEARCHSTRING, 0, \
+							(LPARAM)(LPTSTR)lpsz)
+
+#define TreeView_SetItemHeight(hwnd,  iHeight) \
+    (INT32)SendMessage32A((hwnd), TVM_SETITEMHEIGHT, (WPARAM)iHeight, 0)
+#define TreeView_GetItemHeight(hwnd) \
+    (INT32)SendMessage32A((hwnd), TVM_GETITEMHEIGHT, 0, 0)
+
+#define TreeView_SetBkColor(hwnd, clr) \
+    (COLORREF)SendMessage32A((hwnd), TVM_SETBKCOLOR, 0, (LPARAM)clr)
+
+#define TreeView_SetTextColor(hwnd, clr) \
+    (COLORREF)SendMessage32A((hwnd), TVM_SETTEXTCOLOR, 0, (LPARAM)clr)
+
+#define TreeView_GetBkColor(hwnd) \
+    (COLORREF)SendMessage32A((hwnd), TVM_GETBKCOLOR, 0, 0)
+
+#define TreeView_GetTextColor(hwnd) \
+    (COLORREF)SendMessage32A((hwnd), TVM_GETTEXTCOLOR, 0, 0)
+
+#define TreeView_SetScrollTime(hwnd, uTime) \
+    (UINT32)SendMessage32A((hwnd), TVM_SETSCROLLTIME, uTime, 0)
+
+#define TreeView_GetScrollTime(hwnd) \
+    (UINT32)SendMessage32A((hwnd), TVM_GETSCROLLTIME, 0, 0)
+
+#define TreeView_SetInsertMarkColor(hwnd, clr) \
+    (COLORREF)SendMessage32A((hwnd), TVM_SETINSERTMARKCOLOR, 0, (LPARAM)clr)
+#define TreeView_GetInsertMarkColor(hwnd) \
+    (COLORREF)SendMessage32A((hwnd), TVM_GETINSERTMARKCOLOR, 0, 0)
+
+
+
+
+
+
+
+
 
 /* Listview control */
 
@@ -1456,14 +1824,63 @@
 #define LVM_INSERTCOLUMN        WINELIB_NAME_AW(LVM_INSERTCOLUMN)
 #define LVM_DELETECOLUMN        (LVM_FIRST+28)
 #define LVM_GETCOLUMNWIDTH      (LVM_FIRST+29)
-#define LVM_GETHEADER           (LVM_FIRST+30)
+#define LVM_SETCOLUMNWIDTH      (LVM_FIRST+30)
+#define LVM_GETHEADER           (LVM_FIRST+31)
 
+#define LVM_CREATEDRAGIMAGE     (LVM_FIRST+33)
+#define LVM_GETVIEWRECT         (LVM_FIRST+34)
+#define LVM_GETTEXTCOLOR        (LVM_FIRST+35)
+#define LVM_SETTEXTCOLOR        (LVM_FIRST+36)
+#define LVM_GETTEXTBKCOLOR      (LVM_FIRST+37)
+#define LVM_SETTEXTBKCOLOR      (LVM_FIRST+38)
+#define LVM_GETTOPINDEX         (LVM_FIRST+39)
+#define LVM_GETCOUNTPERPAGE     (LVM_FIRST+40)
+#define LVM_GETORIGIN           (LVM_FIRST+41)
+#define LVM_UPDATE              (LVM_FIRST+42)
+#define LVM_SETITEMSTATE        (LVM_FIRST+43)
+#define LVM_GETITEMSTATE        (LVM_FIRST+44)
+#define LVM_GETITEMTEXT32A      (LVM_FIRST+45)
+#define LVM_GETITEMTEXT32W      (LVM_FIRST+115)
+#define LVM_GETITEMTEXT         WINELIB_NAME_AW(LVM_GETITEMTEXT)
+#define LVM_SETITEMTEXT32A      (LVM_FIRST+46)
+#define LVM_SETITEMTEXT32W      (LVM_FIRST+116)
+#define LVM_SETITEMTEXT         WINELIB_NAME_AW(LVM_SETITEMTEXT)
+#define LVM_SETITEMCOUNT        (LVM_FIRST+47)
 #define LVM_SORTITEMS           (LVM_FIRST+48)
+#define LVM_SETITEMPOSITION32   (LVM_FIRST+49)
 #define LVM_GETSELECTEDCOUNT    (LVM_FIRST+50)
-
+#define LVM_GETITEMSPACING      (LVM_FIRST+51)
+#define LVM_GETISEARCHSTRING32A (LVM_FIRST+52)
+#define LVM_GETISEARCHSTRING32W (LVM_FIRST+117)
+#define LVM_GETISEARCHSTRING    WINELIB_NAME_AW(LVM_GETISEARCHSTRING)
+#define LVM_SETICONSPACING      (LVM_FIRST+53)
 #define LVM_SETEXTENDEDLISTVIEWSTYLE (LVM_FIRST+54)
 #define LVM_GETEXTENDEDLISTVIEWSTYLE (LVM_FIRST+55)
+#define LVM_GETSUBITEMRECT      (LVM_FIRST+56)
+#define LVM_SUBITEMHITTEST      (LVM_FIRST+57)
+#define LVM_SETCOLUMNORDERARRAY (LVM_FIRST+58)
+#define LVM_GETCOLUMNORDERARRAY (LVM_FIRST+59)
+#define LVM_SETHOTITEM          (LVM_FIRST+60)
+#define LVM_GETHOTITEM          (LVM_FIRST+61)
+#define LVM_SETHOTCURSOR        (LVM_FIRST+62)
+#define LVM_GETHOTCURSOR        (LVM_FIRST+63)
+#define LVM_APPROXIMATEVIEWRECT (LVM_FIRST+64)
+#define LVM_SETWORKAREAS        (LVM_FIRST+65)
+#define LVM_GETSELECTIONMARK    (LVM_FIRST+66)
+#define LVM_SETSELECTIONMARK    (LVM_FIRST+67)
+#define LVM_SETBKIMAGE32A       (LVM_FIRST+68)
+#define LVM_SETBKIMAGE32W       (LVM_FIRST+138)
+#define LVM_SETBKIMAGE          WINELIB_NAME_AW(LVM_SETBKIMAGE)
+#define LVM_GETBKIMAGE32A       (LVM_FIRST+69)
+#define LVM_GETBKIMAGE32W       (LVM_FIRST+139)
+#define LVM_GETBKIMAGE          WINELIB_NAME_AW(LVM_GETBKIMAGE)
+#define LVM_GETWORKAREAS        (LVM_FIRST+70)
+#define LVM_SETHOVERTIME        (LVM_FIRST+71)
+#define LVM_GETHOVERTIME        (LVM_FIRST+72)
+#define LVM_GETNUMBEROFWORKAREAS (LVM_FIRST+73)
+#define LVM_SETTOOLTIPS         (LVM_FIRST+74)
 
+#define LVM_GETTOOLTIPS         (LVM_FIRST+78)
 
 #define LVN_FIRST               (0U-100U)
 #define LVN_LAST                (0U-199U)
@@ -1747,22 +2164,29 @@
 #define ACN_START               1
 #define ACN_STOP                2
 
-#ifndef __WINE__
-#define Animate_Create(hwndP,id,dwStyle,hInstance) \
-    CreateWindow(ANIMATE_CLASS,NULL,dwStyle,0,0,0,0,hwndP,(HMENU32)(id),hInstance,NULL)
-#define Animate_Open(hwnd,szName) \
-    (BOOL32)SNDMSG(hwnd,ACM_OPEN,0,(LPARAM)(LPTSTR)(szName))
-#define Animate_OpenEx(hwnd,hInst,szName) \
-    (BOOL32)SNDMSG(hwnd,ACM_OPEN,(WPARAM32)hInst,(LPARAM)(LPTSTR)(szName))
+#define Animate_Create32A(hwndP,id,dwStyle,hInstance) \
+    CreateWindow32A(ANIMATE_CLASS32A,NULL,dwStyle,0,0,0,0,hwndP,(HMENU32)(id),hInstance,NULL)
+#define Animate_Create32W(hwndP,id,dwStyle,hInstance) \
+    CreateWindow32W(ANIMATE_CLASS32W,NULL,dwStyle,0,0,0,0,hwndP,(HMENU32)(id),hInstance,NULL)
+#define Animate_Create WINELIB_NAME_AW(Animate_Create)
+#define Animate_Open32A(hwnd,szName) \
+    (BOOL32)SendMessage32A(hwnd,ACM_OPEN32A,0,(LPARAM)(LPSTR)(szName))
+#define Animate_Open32W(hwnd,szName) \
+    (BOOL32)SendMessage32W(hwnd,ACM_OPEN32W,0,(LPARAM)(LPWSTR)(szName))
+#define Animate_Open WINELIB_NAME_AW(Animate_Open)
+#define Animate_OpenEx32A(hwnd,hInst,szName) \
+    (BOOL32)SendMessage32A(hwnd,ACM_OPEN32A,(WPARAM32)hInst,(LPARAM)(LPSTR)(szName))
+#define Animate_OpenEx32W(hwnd,hInst,szName) \
+    (BOOL32)SendMessage32W(hwnd,ACM_OPEN32W,(WPARAM32)hInst,(LPARAM)(LPWSTR)(szName))
+#define Animate_OpenEx WINELIB_NAME_AW(Animate_OpenEx)
 #define Animate_Play(hwnd,from,to,rep) \
-    (BOOL32)SNDMSG(hwnd,ACM_PLAY,(WPARAM32)(UINT32)(rep),(LPARAM)MAKELONG(from,to))
+    (BOOL32)SendMessage32A(hwnd,ACM_PLAY,(WPARAM32)(UINT32)(rep),(LPARAM)MAKELONG(from,to))
 #define Animate_Stop(hwnd) \
-    (BOOL32)SNDMSG(hwnd,ACM_STOP,0,0)
+    (BOOL32)SendMessage32A(hwnd,ACM_STOP,0,0)
 #define Animate_Close(hwnd) \
-    Animate_Open(hwnd,NULL)
+    (BOOL32)SendMessage32A(hwnd,ACM_OPEN32A,0,0)
 #define Animate_Seek(hwnd,frame) \
-    Animate_Play(hwnd,frame,frame,1)
-#endif  /* __WINE__ */
+    (BOOL32)SendMessage32A(hwnd,ACM_PLAY,1,(LPARAM)MAKELONG(frame,frame))
 
 
 
@@ -1778,6 +2202,14 @@
 DWORD  WINAPI COMCTL32_GetSize (LPVOID lpMem);
 
 
+INT32  WINAPI Str_GetPtr32A (LPCSTR lpSrc, LPSTR lpDest, INT32 nMaxLen);
+BOOL32 WINAPI Str_SetPtr32A (LPSTR *lppDest, LPCSTR lpSrc);
+INT32  WINAPI Str_GetPtr32W (LPCWSTR lpSrc, LPWSTR lpDest, INT32 nMaxLen);
+BOOL32 WINAPI Str_SetPtr32W (LPWSTR *lppDest, LPCWSTR lpSrc);
+#define Str_GetPtr WINELIB_NAME_AW(Str_GetPtr)
+#define Str_SetPtr WINELIB_NAME_AW(Str_SetPtr)
+
+
 /* Dynamic Storage Array */
 
 typedef struct _DSA
diff --git a/include/config.h.in b/include/config.h.in
index 73fc304..0fb133b 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -36,6 +36,9 @@
 /* Define if X libraries are not reentrant (compiled without -D_REENTRANT).  */
 #undef NO_REENTRANT_X11
 
+/* Define if libc is not reentrant  */
+#undef NO_REENTRANT_LIBC
+
 /* Define if all debug messages are to be compiled out */
 #undef NO_DEBUG_MSGS
 
@@ -161,3 +164,6 @@
 
 /* Define if you have the w library (-lw).  */
 #undef HAVE_LIBW
+
+/* Define if you have the xpg4 library (-lxpg4).  */
+#undef HAVE_LIBXPG4
diff --git a/include/ddraw.h b/include/ddraw.h
index db87666..9c20ee6 100644
--- a/include/ddraw.h
+++ b/include/ddraw.h
@@ -431,6 +431,14 @@
 #define DDCAPS2_CANFLIPODDEVEN		0x00002000
 #define DDCAPS2_CANBOBHARDWARE		0x00004000
 
+
+/* Set/Get Colour Key Flags */
+#define DDCKEY_COLORSPACE  0x00000001  /* Struct is ingle colour space */
+#define DDCKEY_DESTBLT     0x00000002  /* To be used as dest for blt */
+#define DDCKEY_DESTOVERLAY 0x00000004  /* To be used as dest for CK overlays */
+#define DDCKEY_SRCBLT      0x00000008  /* To be used as src for blt */
+#define DDCKEY_SRCOVERLAY  0x00000010  /* To be used as src for CK overlays */
+
 typedef struct _DDCOLORKEY
 {
 	DWORD	dwColorSpaceLowValue;/* low boundary of color space that is to
@@ -876,6 +884,7 @@
 struct _common_directdrawdata {
     DWORD			depth;
     DWORD			height,width;	/* SetDisplayMode */
+    HWND32                      mainWindow;     /* SetCooperativeLevel */
 };
 
 struct _dga_directdrawdata {
diff --git a/include/debug.h b/include/debug.h
index 971d472..2d279ac 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -59,32 +59,32 @@
 #define dbch_hotkey 51
 #define dbch_icon 52
 #define dbch_imagelist 53
-#define dbch_int 54
-#define dbch_int10 55
-#define dbch_int21 56
-#define dbch_int31 57
-#define dbch_key 58
-#define dbch_keyboard 59
-#define dbch_ldt 60
-#define dbch_listbox 61
-#define dbch_listview 62
-#define dbch_local 63
-#define dbch_mci 64
-#define dbch_mcianim 65
-#define dbch_mciwave 66
-#define dbch_mdi 67
-#define dbch_menu 68
-#define dbch_message 69
-#define dbch_metafile 70
-#define dbch_midi 71
-#define dbch_mmaux 72
-#define dbch_mmio 73
-#define dbch_mmsys 74
-#define dbch_mmtime 75
-#define dbch_module 76
-#define dbch_mpr 77
-#define dbch_msg 78
-#define dbch_msvideo 79
+#define dbch_imm 54
+#define dbch_int 55
+#define dbch_int10 56
+#define dbch_int21 57
+#define dbch_int31 58
+#define dbch_key 59
+#define dbch_keyboard 60
+#define dbch_ldt 61
+#define dbch_listbox 62
+#define dbch_listview 63
+#define dbch_local 64
+#define dbch_mci 65
+#define dbch_mcianim 66
+#define dbch_mciwave 67
+#define dbch_mdi 68
+#define dbch_menu 69
+#define dbch_message 70
+#define dbch_metafile 71
+#define dbch_midi 72
+#define dbch_mmaux 73
+#define dbch_mmio 74
+#define dbch_mmsys 75
+#define dbch_mmtime 76
+#define dbch_module 77
+#define dbch_mpr 78
+#define dbch_msg 79
 #define dbch_nonclient 80
 #define dbch_ntdll 81
 #define dbch_ole 82
@@ -96,54 +96,55 @@
 #define dbch_profile 88
 #define dbch_progress 89
 #define dbch_prop 90
-#define dbch_psdrv 91
-#define dbch_rebar 92
-#define dbch_reg 93
-#define dbch_region 94
-#define dbch_relay 95
-#define dbch_resource 96
-#define dbch_s 97
-#define dbch_scroll 98
-#define dbch_security 99
-#define dbch_segment 100
-#define dbch_selector 101
-#define dbch_sem 102
-#define dbch_sendmsg 103
-#define dbch_shell 104
-#define dbch_shm 105
-#define dbch_snoop 106
-#define dbch_sound 107
-#define dbch_static 108
-#define dbch_statusbar 109
-#define dbch_stress 110
-#define dbch_string 111
-#define dbch_syscolor 112
-#define dbch_system 113
-#define dbch_tab 114
-#define dbch_task 115
-#define dbch_text 116
-#define dbch_thread 117
-#define dbch_thunk 118
-#define dbch_timer 119
-#define dbch_toolbar 120
-#define dbch_toolhelp 121
-#define dbch_tooltips 122
-#define dbch_trackbar 123
-#define dbch_treeview 124
-#define dbch_tweak 125
-#define dbch_uitools 126
-#define dbch_updown 127
-#define dbch_ver 128
-#define dbch_virtual 129
-#define dbch_vxd 130
-#define dbch_win 131
-#define dbch_win16drv 132
-#define dbch_win32 133
-#define dbch_wing 134
-#define dbch_winsock 135
-#define dbch_wnet 136
-#define dbch_x11 137
-#define dbch_x11drv 138
+#define dbch_psapi 91
+#define dbch_psdrv 92
+#define dbch_rebar 93
+#define dbch_reg 94
+#define dbch_region 95
+#define dbch_relay 96
+#define dbch_resource 97
+#define dbch_s 98
+#define dbch_scroll 99
+#define dbch_security 100
+#define dbch_segment 101
+#define dbch_selector 102
+#define dbch_sem 103
+#define dbch_sendmsg 104
+#define dbch_shell 105
+#define dbch_shm 106
+#define dbch_snoop 107
+#define dbch_sound 108
+#define dbch_static 109
+#define dbch_statusbar 110
+#define dbch_stress 111
+#define dbch_string 112
+#define dbch_syscolor 113
+#define dbch_system 114
+#define dbch_tab 115
+#define dbch_task 116
+#define dbch_text 117
+#define dbch_thread 118
+#define dbch_thunk 119
+#define dbch_timer 120
+#define dbch_toolbar 121
+#define dbch_toolhelp 122
+#define dbch_tooltips 123
+#define dbch_trackbar 124
+#define dbch_treeview 125
+#define dbch_tweak 126
+#define dbch_uitools 127
+#define dbch_updown 128
+#define dbch_ver 129
+#define dbch_virtual 130
+#define dbch_vxd 131
+#define dbch_win 132
+#define dbch_win16drv 133
+#define dbch_win32 134
+#define dbch_wing 135
+#define dbch_winsock 136
+#define dbch_wnet 137
+#define dbch_x11 138
+#define dbch_x11drv 139
 /* Definitions for classes identifiers */
 #define dbcl_fixme 0
 #define dbcl_err 1
diff --git a/include/debugdefs.h b/include/debugdefs.h
index 7ff6fd7..104fbb0 100644
--- a/include/debugdefs.h
+++ b/include/debugdefs.h
@@ -4,7 +4,7 @@
 #include "debugtools.h"
 #endif
 
-#define DEBUG_CHANNEL_COUNT 139
+#define DEBUG_CHANNEL_COUNT 140
 #ifdef DEBUG_RUNTIME
 short debug_msg_enabled[][DEBUG_CLASS_COUNT] = {
 {1, 1, 0, 0},
@@ -146,6 +146,7 @@
 {1, 1, 0, 0},
 {1, 1, 0, 0},
 {1, 1, 0, 0},
+{1, 1, 0, 0},
 };
 const char* debug_ch_name[] = {
 "1",
@@ -202,6 +203,7 @@
 "hotkey",
 "icon",
 "imagelist",
+"imm",
 "int",
 "int10",
 "int21",
@@ -227,7 +229,6 @@
 "module",
 "mpr",
 "msg",
-"msvideo",
 "nonclient",
 "ntdll",
 "ole",
@@ -239,6 +240,7 @@
 "profile",
 "progress",
 "prop",
+"psapi",
 "psdrv",
 "rebar",
 "reg",
diff --git a/include/debugger.h b/include/debugger.h
index 866634d..90d45a8 100644
--- a/include/debugger.h
+++ b/include/debugger.h
@@ -11,6 +11,7 @@
 #include "selectors.h"
 #include "sig_context.h"
 #include "pe_image.h"
+#include "miscemu.h"
 
 #define STEP_FLAG 0x100 /* single step flag */
 
@@ -85,13 +86,20 @@
 typedef struct wine_locals WineLocals;
 
 
+#define DBG_V86_MODULE(seg) ((seg)>>16)
+#define IS_SELECTOR_V86(seg) DBG_V86_MODULE(seg)
+
 #define DBG_FIX_ADDR_SEG(addr,default) { \
       if ((addr)->seg == 0xffffffff) (addr)->seg = (default); \
+      if (!IS_SELECTOR_V86((addr)->seg)) \
       if (IS_SELECTOR_SYSTEM((addr)->seg)) (addr)->seg = 0; }
 
 #define DBG_ADDR_TO_LIN(addr) \
+    (IS_SELECTOR_V86((addr)->seg) \
+      ? (char*)(DOSMEM_MemoryBase(DBG_V86_MODULE((addr)->seg)) + \
+         ((((addr)->seg)&0xFFFF)<<4)+(addr)->off) : \
     (IS_SELECTOR_SYSTEM((addr)->seg) ? (char *)(addr)->off \
-      : (char *)PTR_SEG_OFF_TO_LIN((addr)->seg,(addr)->off))
+      : (char *)PTR_SEG_OFF_TO_LIN((addr)->seg,(addr)->off)))
 
 #define DBG_CHECK_READ_PTR(addr,len) \
     (!DEBUG_IsBadReadPtr((addr),(len)) || \
@@ -310,6 +318,7 @@
 extern void DEBUG_Disassemble( const DBG_ADDR *, const DBG_ADDR*, int offset );
 
   /* debugger/dbg.y */
+extern void ctx_debug( int signal, CONTEXT *regs );
 extern void wine_debug( int signal, SIGCONTEXT *regs );
 
 #endif  /* __WINE_DEBUGGER_H */
diff --git a/include/debugtools.h b/include/debugtools.h
index 40fcb1e..7b6356b 100644
--- a/include/debugtools.h
+++ b/include/debugtools.h
@@ -37,8 +37,8 @@
 #define DPRINTF(format, args...) fprintf(stddeb, format, ## args)
 
 #define DPRINTF_(cl, ch, format, args...) \
-  if(!DEBUGGING(cl, ch)) ; \
-  else DPRINTF(# cl ":" # ch ":%s " format, __FUNCTION__ , ## args)
+  do {if(!DEBUGGING(cl, ch)) ; \
+  else DPRINTF(# cl ":" # ch ":%s " format, __FUNCTION__ , ## args); } while (0)
 
 /* use configure to allow user to compile out debugging messages */
 
diff --git a/include/dosexe.h b/include/dosexe.h
index 3eb82f5..04d9ffb 100644
--- a/include/dosexe.h
+++ b/include/dosexe.h
@@ -16,6 +16,7 @@
  LPVOID img;
  unsigned img_ofs;
  WORD psp_seg,load_seg;
+ WORD dpmi_seg,dpmi_sel,dpmi_flag;
  HMODULE16 hModule;
  struct vm86plus_struct VM86;
  int fn, state;
diff --git a/include/dplay.h b/include/dplay.h
index f9d649e..d9a1147 100644
--- a/include/dplay.h
+++ b/include/dplay.h
@@ -2,9 +2,9 @@
 #ifndef __WINE_DPLAY_H
 #define __WINE_DPLAY_H
 
-#include "mmsystem.h"
+#pragma pack(1)
 
-/* Return Values */
+/* Return Values for Direct Play */
 #define _FACDP  0x877
 #define MAKE_DPHRESULT( code )    MAKE_HRESULT( 1, _FACDP, code )
 
@@ -34,8 +34,8 @@
 #define DPERR_NONAMESERVERFOUND         MAKE_DPHRESULT( 200 )
 #define DPERR_NOPLAYERS                 MAKE_DPHRESULT( 210 )
 #define DPERR_NOSESSIONS                MAKE_DPHRESULT( 220 )
-#define DPERR_PENDING                                   E_PENDING
-#define DPERR_SENDTOOBIG                                MAKE_DPHRESULT( 230 )
+#define DPERR_PENDING                   E_PENDING
+#define DPERR_SENDTOOBIG                MAKE_DPHRESULT( 230 )
 #define DPERR_TIMEOUT                   MAKE_DPHRESULT( 240 )
 #define DPERR_UNAVAILABLE               MAKE_DPHRESULT( 250 )
 #define DPERR_UNSUPPORTED               E_NOTIMPL
@@ -107,11 +107,7 @@
 /* GUID for Modem service provider {44EAA760-CB68-11cf-9C4E-00A0C905425E} */
 DEFINE_GUID(DPSPGUID_MODEM, 0x44eaa760, 0xcb68, 0x11cf, 0x9c, 0x4e, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
 
-
-#pragma pack(1)
-
-/* Direct Play */
-typedef struct IDirectPlay        IDirectPlay, *LPDIRECTPLAY;
+typedef struct IDirectPlay IDirectPlay, *LPDIRECTPLAY;
 
 /* Direct Play 2 */
 typedef struct IDirectPlay2       IDirectPlay2, *LPDIRECTPLAY2;
@@ -154,60 +150,110 @@
 {
     DWORD   dwSize;             
     DWORD   dwFlags;            /* Not used must be 0 */
-    union playerShortName       /* Player's Handle? */
+
+    union /*playerShortName */      /* Player's Handle? */
     {                           
         LPWSTR  lpszShortName;  
         LPSTR   lpszShortNameA; 
-    };
-    union playerLongName        /* Player's formal/real name */
+    }psn;
+
+    union /*playerLongName */       /* Player's formal/real name */
     {                         
         LPWSTR  lpszLongName;  
         LPSTR   lpszLongNameA;  
-    };
+    }pln;
 
 } DPNAME, *LPDPNAME;
 
+#define DPLONGNAMELEN     52
+#define DPSHORTNAMELEN    20
+#define DPSESSIONNAMELEN  32
+#define DPPASSWORDLEN     16
+#define DPUSERRESERVED    16
+
+typedef struct tagDPSESSIONDESC
+{
+    DWORD   dwSize;
+    GUID    guidSession;
+    DWORD   dwSession;
+    DWORD   dwMaxPlayers;
+    DWORD   dwCurrentPlayers;
+    DWORD   dwFlags;
+    char    szSessionName[ DPSESSIONNAMELEN ];
+    char    szUserField[ DPUSERRESERVED ];
+    DWORD   dwReserved1;
+    char    szPassword[ DPPASSWORDLEN ];
+    DWORD   dwReserved2;
+    DWORD   dwUser1;
+    DWORD   dwUser2;
+    DWORD   dwUser3;
+    DWORD   dwUser4;
+} DPSESSIONDESC, *LPDPSESSIONDESC;
+
 typedef struct tagDPSESSIONDESC2
 {
     DWORD   dwSize;             
     DWORD   dwFlags;           
     GUID    guidInstance;      
-    GUID    guidApplication;   
+    GUID    guidApplication;   /* GUID of the DP application, GUID_NULL if
+                                * all applications! */
                                
     DWORD   dwMaxPlayers;      
-    DWORD   dwCurrentPlayers;  
+    DWORD   dwCurrentPlayers;   /* (read only value) */
 
-    union sessionName
+    union  /* Session name */
     {                             
         LPWSTR  lpszSessionName;  
         LPSTR   lpszSessionNameA; 
-    };
+    }sess;
 
-    union optnlSessionPasswd
+    union  /* Optional password */
     {                           
         LPWSTR  lpszPassword;   
         LPSTR   lpszPasswordA;  
-    };
+    }pass;
 
     DWORD   dwReserved1;       
     DWORD   dwReserved2;
-    DWORD   dwUser1;          
+
+    DWORD   dwUser1;        /* For use by the application */  
     DWORD   dwUser2;
     DWORD   dwUser3;
     DWORD   dwUser4;
 } DPSESSIONDESC2, *LPDPSESSIONDESC2;
+typedef const DPSESSIONDESC2* LPCDPSESSIONDESC2;
+
+#define DPOPEN_JOIN                     0x00000001
+#define DPOPEN_CREATE                   0x00000002
+#define DPOPEN_RETURNSTATUS             DPENUMSESSIONS_RETURNSTATUS
+
+#define DPSESSION_NEWPLAYERSDISABLED    0x00000001
+#define DPSESSION_MIGRATEHOST           0x00000004
+#define DPSESSION_NOMESSAGEID           0x00000008
+#define DPSESSION_JOINDISABLED          0x00000020
+#define DPSESSION_KEEPALIVE             0x00000040
+#define DPSESSION_NODATAMESSAGES        0x00000080
+#define DPSESSION_SECURESERVER          0x00000100
+#define DPSESSION_PRIVATE               0x00000200
+#define DPSESSION_PASSWORDREQUIRED      0x00000400
+#define DPSESSION_MULTICASTSERVER       0x00000800
+#define DPSESSION_CLIENTSERVER          0x00001000
 
 typedef struct tagDPLCONNECTION
 {
     DWORD               dwSize;          
     DWORD               dwFlags;          
-    LPDPSESSIONDESC2    lpSessionDesc;   
-    LPDPNAME            lpPlayerName;    
-    GUID                guidSP;          
-    LPVOID              lpAddress;       
-    DWORD               dwAddressSize;  
+    LPDPSESSIONDESC2    lpSessionDesc;  /* Ptr to session desc to use for connect */  
+    LPDPNAME            lpPlayerName;   /* Ptr to player name structure */
+    GUID                guidSP;         /* GUID of Service Provider to use */ 
+    LPVOID              lpAddress;      /* Ptr to Address of Service Provider to use */
+    DWORD               dwAddressSize;  /* Size of address data */
 } DPLCONNECTION, *LPDPLCONNECTION;
 
+/* DPLCONNECTION flags (for dwFlags) */
+#define DPLCONNECTION_CREATESESSION DPOPEN_CREATE
+#define DPLCONNECTION_JOINSESSION   DPOPEN_JOIN
+
 typedef struct tagDPLAPPINFO
 {
     DWORD       dwSize;            
@@ -230,6 +276,62 @@
 } DPCOMPOUNDADDRESSELEMENT, *LPDPCOMPOUNDADDRESSELEMENT;
 typedef const DPCOMPOUNDADDRESSELEMENT *LPCDPCOMPOUNDADDRESSELEMENT;
 
+typedef struct tagDPCHAT
+{
+    DWORD               dwSize;
+    DWORD               dwFlags;
+    union
+    {                          // Message string
+        LPWSTR  lpszMessage;   // Unicode
+        LPSTR   lpszMessageA;  // ANSI
+    }msgstr;
+} DPCHAT, *LPDPCHAT;
+
+typedef struct tagDPSECURITYDESC
+{
+    DWORD dwSize;                   // Size of structure
+    DWORD dwFlags;                  // Not used. Must be zero.
+    union
+    {                               // SSPI provider name
+        LPWSTR  lpszSSPIProvider;   // Unicode
+        LPSTR   lpszSSPIProviderA;  // ANSI
+    }sspi;
+    union
+    {                               // CAPI provider name
+        LPWSTR lpszCAPIProvider;    // Unicode
+        LPSTR  lpszCAPIProviderA;   // ANSI
+    }capi;
+    DWORD dwCAPIProviderType;       // Crypto Service Provider type
+    DWORD dwEncryptionAlgorithm;    // Encryption Algorithm type
+} DPSECURITYDESC, *LPDPSECURITYDESC;
+
+typedef const DPSECURITYDESC *LPCDPSECURITYDESC;
+
+typedef struct tagDPCREDENTIALS
+{
+    DWORD dwSize;               // Size of structure
+    DWORD dwFlags;              // Not used. Must be zero.
+    union
+    {                           // User name of the account
+        LPWSTR  lpszUsername;   // Unicode
+        LPSTR   lpszUsernameA;  // ANSI
+    }name;
+    union
+    {                           // Password of the account
+        LPWSTR  lpszPassword;   // Unicode
+        LPSTR   lpszPasswordA;  // ANSI
+    }pass;
+    union
+    {                           // Domain name of the account
+        LPWSTR  lpszDomain;     // Unicode
+        LPSTR   lpszDomainA;    // ANSI
+    }domain;
+} DPCREDENTIALS, *LPDPCREDENTIALS;
+
+typedef const DPCREDENTIALS *LPCDPCREDENTIALS;
+
+
+
 typedef BOOL32 (CALLBACK* LPDPENUMDPCALLBACKW)(
     LPGUID      lpguidSP,
     LPWSTR      lpSPName,
@@ -255,9 +357,16 @@
     DWORD       dwFlags,
     LPVOID      lpContext);
 
+typedef BOOL32 (CALLBACK* LPDPENUMSESSIONSCALLBACK)(
+    LPDPSESSIONDESC lpDPSessionDesc,
+    LPVOID      lpContext,
+    LPDWORD     lpdwTimeOut,
+    DWORD       dwFlags);
+
+
 extern HRESULT WINAPI DirectPlayEnumerateA( LPDPENUMDPCALLBACKA, LPVOID );
 extern HRESULT WINAPI DirectPlayEnumerateW( LPDPENUMDPCALLBACKW, LPVOID );
-extern HRESULT WINAPI DirectPlayCreate( LPGUID lpGUID, LPDIRECTPLAY *lplpDP, IUnknown *pUnk);
+extern HRESULT WINAPI DirectPlayCreate( LPGUID lpGUID, LPDIRECTPLAY2 *lplpDP, IUnknown *pUnk);
 
 
 /* Direct Play Lobby 1 */
@@ -268,8 +377,8 @@
 typedef struct IDirectPlayLobby2    IDirectPlayLobby2, *LPDIRECTPLAYLOBBY2;
 typedef struct IDirectPlayLobby2    IDirectPlayLobby2A, *LPDIRECTPLAYLOBBY2A;
 
-extern HRESULT WINAPI DirectPlayLobbyCreateW(LPGUID, LPDIRECTPLAYLOBBY2 *, IUnknown *, LPVOID, DWORD );
-extern HRESULT WINAPI DirectPlayLobbyCreateA(LPGUID, LPDIRECTPLAYLOBBY2A *, IUnknown *, LPVOID, DWORD );
+extern HRESULT WINAPI DirectPlayLobbyCreateW(LPGUID, LPDIRECTPLAYLOBBY *, IUnknown *, LPVOID, DWORD );
+extern HRESULT WINAPI DirectPlayLobbyCreateA(LPGUID, LPDIRECTPLAYLOBBYA *, IUnknown *, LPVOID, DWORD );
 
 
 
@@ -277,17 +386,31 @@
     REFGUID         guidDataType,
     DWORD           dwDataSize,
     LPCVOID         lpData,
-    LPVOID          lpContext);
+    LPVOID          lpContext );
 
 typedef BOOL32 (CALLBACK* LPDPLENUMADDRESSTYPESCALLBACK)(
     REFGUID         guidDataType,
     LPVOID          lpContext,
-    DWORD           dwFlags);
+    DWORD           dwFlags );
 
 typedef BOOL32 (CALLBACK* LPDPLENUMLOCALAPPLICATIONSCALLBACK)(
     LPCDPLAPPINFO   lpAppInfo,
     LPVOID          lpContext,
-    DWORD           dwFlags);
+    DWORD           dwFlags );
+
+typedef BOOL32 (CALLBACK* LPDPENUMPLAYERSCALLBACK2)(
+    DPID            dpId,
+    DWORD           dwPlayerType,
+    LPCDPNAME       lpName,
+    DWORD           dwFlags,
+    LPVOID          lpContext );
+
+typedef BOOL32 (CALLBACK* LPDPENUMSESSIONSCALLBACK2)(
+    LPCDPSESSIONDESC2   lpThisSD,
+    LPDWORD             lpdwTimeOut,
+    DWORD               dwFlags,
+    LPVOID              lpContext );
+
 
 
 #define STDMETHOD(xfn) HRESULT (CALLBACK *fn##xfn)
@@ -296,36 +419,334 @@
 #define FAR
 #define THIS_ THIS,
 
-#define THIS LPDIRECTPLAYLOBBY2 this
-typedef struct tagLPDIRECTPLAYLOBBY2_VTABLE {
+#define THIS LPDIRECTPLAY2 this
+typedef struct tagLPDIRECTPLAY2_VTABLE
+{
+    /*** IUnknown methods ***/
+    STDMETHOD(QueryInterface)       (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef)        (THIS)  PURE;
+    STDMETHOD_(ULONG,Release)       (THIS) PURE;
+
+    /*** IDirectPlay2 methods ***/
+    STDMETHOD(AddPlayerToGroup)     (THIS_ DPID, DPID) PURE;
+    STDMETHOD(Close)                (THIS) PURE;
+    STDMETHOD(CreateGroup)          (THIS_ LPDPID,LPDPNAME,LPVOID,DWORD,DWORD) PURE;
+    STDMETHOD(CreatePlayer)         (THIS_ LPDPID,LPDPNAME,HANDLE32,LPVOID,DWORD,DWORD) PURE;
+    STDMETHOD(DeletePlayerFromGroup)(THIS_ DPID,DPID) PURE;
+    STDMETHOD(DestroyGroup)         (THIS_ DPID) PURE;
+    STDMETHOD(DestroyPlayer)        (THIS_ DPID) PURE;
+    STDMETHOD(EnumGroupPlayers)     (THIS_ DPID,LPGUID,LPDPENUMPLAYERSCALLBACK2,LPVOID,DWORD) PURE;
+    STDMETHOD(EnumGroups)           (THIS_ LPGUID,LPDPENUMPLAYERSCALLBACK2,LPVOID,DWORD) PURE;
+    STDMETHOD(EnumPlayers)          (THIS_ LPGUID,LPDPENUMPLAYERSCALLBACK2,LPVOID,DWORD) PURE;
+    STDMETHOD(EnumSessions)         (THIS_ LPDPSESSIONDESC2,DWORD,LPDPENUMSESSIONSCALLBACK2,LPVOID,DWORD) PURE;
+    STDMETHOD(GetCaps)              (THIS_ LPDPCAPS,DWORD) PURE;
+    STDMETHOD(GetGroupData)         (THIS_ DPID,LPVOID,LPDWORD,DWORD) PURE;
+    STDMETHOD(GetGroupName)         (THIS_ DPID,LPVOID,LPDWORD) PURE;
+    STDMETHOD(GetMessageCount)      (THIS_ DPID, LPDWORD) PURE;
+    STDMETHOD(GetPlayerAddress)     (THIS_ DPID,LPVOID,LPDWORD) PURE;
+    STDMETHOD(GetPlayerCaps)        (THIS_ DPID,LPDPCAPS,DWORD) PURE;
+    STDMETHOD(GetPlayerData)        (THIS_ DPID,LPVOID,LPDWORD,DWORD) PURE;
+    STDMETHOD(GetPlayerName)        (THIS_ DPID,LPVOID,LPDWORD) PURE;
+    STDMETHOD(GetSessionDesc)       (THIS_ LPVOID,LPDWORD) PURE;
+    STDMETHOD(Initialize)           (THIS_ LPGUID) PURE;
+    STDMETHOD(Open)                 (THIS_ LPDPSESSIONDESC2,DWORD) PURE;
+    STDMETHOD(Receive)              (THIS_ LPDPID,LPDPID,DWORD,LPVOID,LPDWORD) PURE;
+    STDMETHOD(Send)                 (THIS_ DPID, DPID, DWORD, LPVOID, DWORD) PURE;
+    STDMETHOD(SetGroupData)         (THIS_ DPID,LPVOID,DWORD,DWORD) PURE;
+    STDMETHOD(SetGroupName)         (THIS_ DPID,LPDPNAME,DWORD) PURE;
+    STDMETHOD(SetPlayerData)        (THIS_ DPID,LPVOID,DWORD,DWORD) PURE;
+    STDMETHOD(SetPlayerName)        (THIS_ DPID,LPDPNAME,DWORD) PURE;
+    STDMETHOD(SetSessionDesc)       (THIS_ LPDPSESSIONDESC2,DWORD) PURE;
+} DIRECTPLAY2_VTABLE, *LPDIRECTPLAY2_VTABLE;
+#undef THIS
+
+#define THIS LPDIRECTPLAY3 this
+typedef struct tagLPDIRECTPLAY3_VTABLE
+{
+    /*** IUnknown methods ***/
+    STDMETHOD(QueryInterface)       (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef)        (THIS)  PURE;
+    STDMETHOD_(ULONG,Release)       (THIS) PURE;
+
+    /*** IDirectPlay2 methods ***/
+    STDMETHOD(AddPlayerToGroup)     (THIS_ DPID, DPID) PURE;
+    STDMETHOD(Close)                (THIS) PURE;
+    STDMETHOD(CreateGroup)          (THIS_ LPDPID,LPDPNAME,LPVOID,DWORD,DWORD) PURE;
+    STDMETHOD(CreatePlayer)         (THIS_ LPDPID,LPDPNAME,HANDLE32,LPVOID,DWORD,DWORD) PURE;
+    STDMETHOD(DeletePlayerFromGroup)(THIS_ DPID,DPID) PURE;
+    STDMETHOD(DestroyGroup)         (THIS_ DPID) PURE;
+    STDMETHOD(DestroyPlayer)        (THIS_ DPID) PURE;
+    STDMETHOD(EnumGroupPlayers)     (THIS_ DPID,LPGUID,LPDPENUMPLAYERSCALLBACK2,LPVOID,DWORD) PURE;
+    STDMETHOD(EnumGroups)           (THIS_ LPGUID,LPDPENUMPLAYERSCALLBACK2,LPVOID,DWORD) PURE;
+    STDMETHOD(EnumPlayers)          (THIS_ LPGUID,LPDPENUMPLAYERSCALLBACK2,LPVOID,DWORD) PURE;
+    STDMETHOD(EnumSessions)         (THIS_ LPDPSESSIONDESC2,DWORD,LPDPENUMSESSIONSCALLBACK2,LPVOID,DWORD) PURE;
+    STDMETHOD(GetCaps)              (THIS_ LPDPCAPS,DWORD) PURE;
+    STDMETHOD(GetGroupData)         (THIS_ DPID,LPVOID,LPDWORD,DWORD) PURE;
+    STDMETHOD(GetGroupName)         (THIS_ DPID,LPVOID,LPDWORD) PURE;
+    STDMETHOD(GetMessageCount)      (THIS_ DPID, LPDWORD) PURE;
+    STDMETHOD(GetPlayerAddress)     (THIS_ DPID,LPVOID,LPDWORD) PURE;
+    STDMETHOD(GetPlayerCaps)        (THIS_ DPID,LPDPCAPS,DWORD) PURE;
+    STDMETHOD(GetPlayerData)        (THIS_ DPID,LPVOID,LPDWORD,DWORD) PURE;
+    STDMETHOD(GetPlayerName)        (THIS_ DPID,LPVOID,LPDWORD) PURE;
+    STDMETHOD(GetSessionDesc)       (THIS_ LPVOID,LPDWORD) PURE;
+    STDMETHOD(Initialize)           (THIS_ LPGUID) PURE;
+    STDMETHOD(Open)                 (THIS_ LPDPSESSIONDESC2,DWORD) PURE;
+    STDMETHOD(Receive)              (THIS_ LPDPID,LPDPID,DWORD,LPVOID,LPDWORD) PURE;
+    STDMETHOD(Send)                 (THIS_ DPID, DPID, DWORD, LPVOID, DWORD) PURE;
+    STDMETHOD(SetGroupData)         (THIS_ DPID,LPVOID,DWORD,DWORD) PURE;
+    STDMETHOD(SetGroupName)         (THIS_ DPID,LPDPNAME,DWORD) PURE;
+    STDMETHOD(SetPlayerData)        (THIS_ DPID,LPVOID,DWORD,DWORD) PURE;
+    STDMETHOD(SetPlayerName)        (THIS_ DPID,LPDPNAME,DWORD) PURE;
+    STDMETHOD(SetSessionDesc)       (THIS_ LPDPSESSIONDESC2,DWORD) PURE;
+
+    /*** IDirectPlay3 methods ***/
+    STDMETHOD(AddGroupToGroup)            (THIS_ DPID, DPID) PURE;
+    STDMETHOD(CreateGroupInGroup)         (THIS_ DPID,LPDPID,LPDPNAME,LPVOID,DWORD,DWORD) PURE;
+    STDMETHOD(DeleteGroupFromGroup)       (THIS_ DPID,DPID) PURE;
+    STDMETHOD(EnumConnections)            (THIS_ LPCGUID,LPDPENUMCONNECTIONSCALLBACK,LPVOID,DWORD) PURE;
+    STDMETHOD(EnumGroupsInGroup)          (THIS_ DPID,LPGUID,LPDPENUMPLAYERSCALLBACK2,LPVOID,DWORD) PURE;
+    STDMETHOD(GetGroupConnectionSettings) (THIS_ DWORD, DPID, LPVOID, LPDWORD) PURE;
+    STDMETHOD(InitializeConnection)       (THIS_ LPVOID,DWORD) PURE;
+    STDMETHOD(SecureOpen)                 (THIS_ LPCDPSESSIONDESC2,DWORD,LPCDPSECURITYDESC,LPCDPCREDENTIALS) PURE;
+    STDMETHOD(SendChatMessage)            (THIS_ DPID,DPID,DWORD,LPDPCHAT);
+    STDMETHOD(SetGroupConnectionSettings) (THIS_ DWORD,DPID,LPDPLCONNECTION) PURE;
+    STDMETHOD(StartSession)               (THIS_ DWORD,DPID);
+    STDMETHOD(GetGroupFlags)              (THIS_ DPID,LPDWORD);
+    STDMETHOD(GetGroupParent)             (THIS_ DPID,LPDPID);
+    STDMETHOD(GetPlayerAccount)           (THIS_ DPID, DWORD, LPVOID, LPDWORD) PURE;
+    STDMETHOD(GetPlayerFlags)             (THIS_ DPID,LPDWORD);
+} DIRECTPLAY3_VTABLE, *LPDIRECTPLAY3_VTABLE;
+#undef THIS
+
+
+/**********************************************************************************
+ *
+ * Macros for a nicer interface to DirectPlay 
+ *
+ **********************************************************************************/
+
+/* COM Interface */
+#define IDirectPlay_QueryInterface(p,a,b)           (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectPlay_AddRef(p)                       (p)->lpVtbl->AddRef(p)
+#define IDirectPlay_Release(p)                      (p)->lpVtbl->Release(p)
+
+#define IDirectPlay2_QueryInterface(p,a,b)          (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectPlay2_AddRef(p)                      (p)->lpVtbl->AddRef(p)
+#define IDirectPlay2_Release(p)                     (p)->lpVtbl->Release(p)
+
+#define IDirectPlay3_QueryInterface(p,a,b)          (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectPlay3_AddRef(p)                      (p)->lpVtbl->AddRef(p)
+#define IDirectPlay3_Release(p)                     (p)->lpVtbl->Release(p)
+
+/* Direct Play 1&2 Interface */
+#define IDirectPlay_AddPlayerToGroup(p,a,b)         (p)->lpVtbl->AddPlayerToGroup(p,a,b)
+#define IDirectPlay_Close(p)                        (p)->lpVtbl->Close(p)
+#define IDirectPlay_CreateGroup(p,a,b,c)            (p)->lpVtbl->CreateGroup(p,a,b,c)
+#define IDirectPlay_CreatePlayer(p,a,b,c,d)         (p)->lpVtbl->CreatePlayer(p,a,b,c,d)
+#define IDirectPlay_DeletePlayerFromGroup(p,a,b)    (p)->lpVtbl->DeletePlayerFromGroup(p,a,b)
+#define IDirectPlay_DestroyGroup(p,a)               (p)->lpVtbl->DestroyGroup(p,a)
+#define IDirectPlay_DestroyPlayer(p,a)              (p)->lpVtbl->DestroyPlayer(p,a)
+#define IDirectPlay_EnableNewPlayers(p,a)           (p)->lpVtbl->EnableNewPlayers(p,a)
+#define IDirectPlay_EnumGroupPlayers(p,a,b,c,d)     (p)->lpVtbl->EnumGroupPlayers(p,a,b,c,d)
+#define IDirectPlay_EnumGroups(p,a,b,c,d)           (p)->lpVtbl->EnumGroups(p,a,b,c,d)
+#define IDirectPlay_EnumPlayers(p,a,b,c,d)          (p)->lpVtbl->EnumPlayers(p,a,b,c,d)
+#define IDirectPlay_EnumSessions(p,a,b,c,d,e)       (p)->lpVtbl->EnumSessions(p,a,b,c,d,e)
+#define IDirectPlay_GetCaps(p,a)                    (p)->lpVtbl->GetCaps(p,a)
+#define IDirectPlay_GetMessageCount(p,a,b)          (p)->lpVtbl->GetMessageCount(p,a,b)
+#define IDirectPlay_GetPlayerCaps(p,a,b)            (p)->lpVtbl->GetPlayerCaps(p,a,b)
+#define IDirectPlay_GetPlayerName(p,a,b,c,d,e)      (p)->lpVtbl->GetPlayerName(p,a,b,c,d,e)
+#define IDirectPlay_Initialize(p,a)                 (p)->lpVtbl->Initialize(p,a)
+#define IDirectPlay_Open(p,a)                       (p)->lpVtbl->Open(p,a)
+#define IDirectPlay_Receive(p,a,b,c,d,e)            (p)->lpVtbl->Receive(p,a,b,c,d,e)
+#define IDirectPlay_SaveSession(p,a)                (p)->lpVtbl->SaveSession(p,a)
+#define IDirectPlay_Send(p,a,b,c,d,e)               (p)->lpVtbl->Send(p,a,b,c,d,e)
+#define IDirectPlay_SetPlayerName(p,a,b,c)          (p)->lpVtbl->SetPlayerName(p,a,b,c)
+
+#define IDirectPlay2_AddPlayerToGroup(p,a,b)        (p)->lpVtbl->AddPlayerToGroup(p,a,b)
+#define IDirectPlay2_Close(p)                       (p)->lpVtbl->Close(p)
+#define IDirectPlay2_CreateGroup(p,a,b,c,d,e)       (p)->lpVtbl->CreateGroup(p,a,b,c,d,e)
+#define IDirectPlay2_CreatePlayer(p,a,b,c,d,e,f)    (p)->lpVtbl->CreatePlayer(p,a,b,c,d,e,f)
+#define IDirectPlay2_DeletePlayerFromGroup(p,a,b)   (p)->lpVtbl->DeletePlayerFromGroup(p,a,b)
+#define IDirectPlay2_DestroyGroup(p,a)              (p)->lpVtbl->DestroyGroup(p,a)
+#define IDirectPlay2_DestroyPlayer(p,a)             (p)->lpVtbl->DestroyPlayer(p,a)
+#define IDirectPlay2_EnumGroupPlayers(p,a,b,c,d,e)  (p)->lpVtbl->EnumGroupPlayers(p,a,b,c,d,e)
+#define IDirectPlay2_EnumGroups(p,a,b,c,d)          (p)->lpVtbl->EnumGroups(p,a,b,c,d)
+#define IDirectPlay2_EnumPlayers(p,a,b,c,d)         (p)->lpVtbl->EnumPlayers(p,a,b,c,d)
+#define IDirectPlay2_EnumSessions(p,a,b,c,d,e)      (p)->lpVtbl->EnumSessions(p,a,b,c,d,e)
+#define IDirectPlay2_GetCaps(p,a,b)                 (p)->lpVtbl->GetCaps(p,a,b)
+#define IDirectPlay2_GetMessageCount(p,a,b)         (p)->lpVtbl->GetMessageCount(p,a,b)
+#define IDirectPlay2_GetGroupData(p,a,b,c,d)        (p)->lpVtbl->GetGroupData(p,a,b,c,d)
+#define IDirectPlay2_GetGroupName(p,a,b,c)          (p)->lpVtbl->GetGroupName(p,a,b,c)
+#define IDirectPlay2_GetPlayerAddress(p,a,b,c)      (p)->lpVtbl->GetPlayerAddress(p,a,b,c)
+#define IDirectPlay2_GetPlayerCaps(p,a,b,c)         (p)->lpVtbl->GetPlayerCaps(p,a,b,c)
+#define IDirectPlay2_GetPlayerData(p,a,b,c,d)       (p)->lpVtbl->GetPlayerData(p,a,b,c,d)
+#define IDirectPlay2_GetPlayerName(p,a,b,c)         (p)->lpVtbl->GetPlayerName(p,a,b,c)
+#define IDirectPlay2_GetSessionDesc(p,a,b)          (p)->lpVtbl->GetSessionDesc(p,a,b)
+#define IDirectPlay2_Initialize(p,a)                (p)->lpVtbl->Initialize(p,a)
+#define IDirectPlay2_Open(p,a,b)                    (p)->lpVtbl->Open(p,a,b)
+#define IDirectPlay2_Receive(p,a,b,c,d,e)           (p)->lpVtbl->Receive(p,a,b,c,d,e)
+#define IDirectPlay2_Send(p,a,b,c,d,e)              (p)->lpVtbl->Send(p,a,b,c,d,e)
+#define IDirectPlay2_SetGroupData(p,a,b,c,d)        (p)->lpVtbl->SetGroupData(p,a,b,c,d)
+#define IDirectPlay2_SetGroupName(p,a,b,c)          (p)->lpVtbl->SetGroupName(p,a,b,c)
+#define IDirectPlay2_SetPlayerData(p,a,b,c,d)       (p)->lpVtbl->SetPlayerData(p,a,b,c,d)
+#define IDirectPlay2_SetPlayerName(p,a,b,c)         (p)->lpVtbl->SetPlayerName(p,a,b,c)
+#define IDirectPlay2_SetSessionDesc(p,a,b)          (p)->lpVtbl->SetSessionDesc(p,a,b)
+
+#define IDirectPlay3_AddPlayerToGroup(p,a,b)        (p)->lpVtbl->AddPlayerToGroup(p,a,b)
+#define IDirectPlay3_Close(p)                       (p)->lpVtbl->Close(p)
+#define IDirectPlay3_CreateGroup(p,a,b,c,d,e)       (p)->lpVtbl->CreateGroup(p,a,b,c,d,e)
+#define IDirectPlay3_CreatePlayer(p,a,b,c,d,e,f)    (p)->lpVtbl->CreatePlayer(p,a,b,c,d,e,f)
+#define IDirectPlay3_DeletePlayerFromGroup(p,a,b)   (p)->lpVtbl->DeletePlayerFromGroup(p,a,b)
+#define IDirectPlay3_DestroyGroup(p,a)              (p)->lpVtbl->DestroyGroup(p,a)
+#define IDirectPlay3_DestroyPlayer(p,a)             (p)->lpVtbl->DestroyPlayer(p,a)
+#define IDirectPlay3_EnumGroupPlayers(p,a,b,c,d,e)  (p)->lpVtbl->EnumGroupPlayers(p,a,b,c,d,e)
+#define IDirectPlay3_EnumGroups(p,a,b,c,d)          (p)->lpVtbl->EnumGroups(p,a,b,c,d)
+#define IDirectPlay3_EnumPlayers(p,a,b,c,d)         (p)->lpVtbl->EnumPlayers(p,a,b,c,d)
+#define IDirectPlay3_EnumSessions(p,a,b,c,d,e)      (p)->lpVtbl->EnumSessions(p,a,b,c,d,e)
+#define IDirectPlay3_GetCaps(p,a,b)                 (p)->lpVtbl->GetCaps(p,a,b)
+#define IDirectPlay3_GetMessageCount(p,a,b)         (p)->lpVtbl->GetMessageCount(p,a,b)
+#define IDirectPlay3_GetGroupData(p,a,b,c,d)        (p)->lpVtbl->GetGroupData(p,a,b,c,d)
+#define IDirectPlay3_GetGroupName(p,a,b,c)          (p)->lpVtbl->GetGroupName(p,a,b,c)
+#define IDirectPlay3_GetPlayerAddress(p,a,b,c)      (p)->lpVtbl->GetPlayerAddress(p,a,b,c)
+#define IDirectPlay3_GetPlayerCaps(p,a,b,c)         (p)->lpVtbl->GetPlayerCaps(p,a,b,c)
+#define IDirectPlay3_GetPlayerData(p,a,b,c,d)       (p)->lpVtbl->GetPlayerData(p,a,b,c,d)
+#define IDirectPlay3_GetPlayerName(p,a,b,c)         (p)->lpVtbl->GetPlayerName(p,a,b,c)
+#define IDirectPlay3_GetSessionDesc(p,a,b)          (p)->lpVtbl->GetSessionDesc(p,a,b)
+#define IDirectPlay3_Initialize(p,a)                (p)->lpVtbl->Initialize(p,a)
+#define IDirectPlay3_Open(p,a,b)                    (p)->lpVtbl->Open(p,a,b)
+#define IDirectPlay3_Receive(p,a,b,c,d,e)           (p)->lpVtbl->Receive(p,a,b,c,d,e)
+#define IDirectPlay3_Send(p,a,b,c,d,e)              (p)->lpVtbl->Send(p,a,b,c,d,e)
+#define IDirectPlay3_SetGroupData(p,a,b,c,d)        (p)->lpVtbl->SetGroupData(p,a,b,c,d)
+#define IDirectPlay3_SetGroupName(p,a,b,c)          (p)->lpVtbl->SetGroupName(p,a,b,c)
+#define IDirectPlay3_SetPlayerData(p,a,b,c,d)       (p)->lpVtbl->SetPlayerData(p,a,b,c,d)
+#define IDirectPlay3_SetPlayerName(p,a,b,c)         (p)->lpVtbl->SetPlayerName(p,a,b,c)
+#define IDirectPlay3_SetSessionDesc(p,a,b)          (p)->lpVtbl->SetSessionDesc(p,a,b)
+
+
+/* Direct Play 3 Interface. */
+
+#define IDirectPlay3_AddGroupToGroup(p,a,b)             (p)->lpVtbl->AddGroupToGroup(p,a,b)
+#define IDirectPlay3_CreateGroupInGroup(p,a,b,c,d,e,f) (p)->lpVtbl->CreateGroupInGroup(p,a,b,c,d,e,f)
+#define IDirectPlay3_DeleteGroupFromGroup(p,a,b)        (p)->lpVtbl->DeleteGroupFromGroup(p,a,b)
+#define IDirectPlay3_EnumConnections(p,a,b,c,d)         (p)->lpVtbl->EnumConnections(p,a,b,c,d)
+#define IDirectPlay3_EnumGroupsInGroup(p,a,b,c,d,e) (p)->lpVtbl->EnumGroupsInGroup(p,a,b,c,d,e)
+#define IDirectPlay3_GetGroupConnectionSettings(p,a,b,c,d) (p)->lpVtbl->GetGroupConnectionSettings(p,a,b,c,d)
+#define IDirectPlay3_InitializeConnection(p,a,b)        (p)->lpVtbl->InitializeConnection(p,a,b)
+#define IDirectPlay3_SecureOpen(p,a,b,c,d)          (p)->lpVtbl->SecureOpen(p,a,b,c,d)
+#define IDirectPlay3_SendChatMessage(p,a,b,c,d)     (p)->lpVtbl->SendChatMessage(p,a,b,c,d)
+#define IDirectPlay3_SetGroupConnectionSettings(p,a,b,c) (p)->lpVtbl->SetGroupConnectionSettings(p,a,b,c)
+#define IDirectPlay3_StartSession(p,a,b)            (p)->lpVtbl->StartSession(p,a,b)
+#define IDirectPlay3_GetGroupFlags(p,a,b)           (p)->lpVtbl->GetGroupFlags(p,a,b)
+#define IDirectPlay3_GetGroupParent(p,a,b)          (p)->lpVtbl->GetGroupParent(p,a,b)
+#define IDirectPlay3_GetPlayerAccount(p,a,b,c,d)    (p)->lpVtbl->GetPlayerAccount(p,a,b,c,d)
+#define IDirectPlay3_GetPlayerFlags(p,a,b)          (p)->lpVtbl->GetPlayerFlags(p,a,b)
+
+
+/****************************************************************************
+ *
+ * DIRECT PLAY LOBBY VIRTUAL TABLE DEFINITIONS 
+ *
+ ****************************************************************************/
+
+
+#define THIS LPDIRECTPLAYLOBBY this
+typedef struct tagLPDIRECTPLAYLOBBY_VTABLE 
+{
     /*  IUnknown Methods "Inherited Methods" */
     STDMETHOD(QueryInterface)       (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
-    STDMETHOD_(ULONG,AddRef)        (THIS) PURE;
+    STDMETHOD_(ULONG,AddRef)        (THIS)  PURE;
     STDMETHOD_(ULONG,Release)       (THIS) PURE;
 
     /*  IDirectPlayLobby Methods */
-    STDMETHOD(Connect)              (THIS_ DWORD, LPDIRECTPLAY2 *, IUnknown *) PURE;
-    STDMETHOD(CreateAddress)        (THIS_ REFGUID, REFGUID, LPCVOID, DWORD, LPVOID, LPDWORD) PURE;
-    STDMETHOD(EnumAddress)          (THIS_ LPDPENUMADDRESSCALLBACK, LPCVOID, DWORD, LPVOID) PURE;
-    STDMETHOD(EnumAddressTypes)     (THIS_ LPDPLENUMADDRESSTYPESCALLBACK, REFGUID, LPVOID, DWORD) PURE;
-    STDMETHOD(EnumLocalApplications)(THIS_ LPDPLENUMLOCALAPPLICATIONSCALLBACK, LPVOID, DWORD) PURE;
-    STDMETHOD(GetConnectionSettings)(THIS_ DWORD, LPVOID, LPDWORD) PURE;
-    STDMETHOD(ReceiveLobbyMessage)  (THIS_ DWORD, DWORD, LPDWORD, LPVOID, LPDWORD) PURE;
-    STDMETHOD(RunApplication)       (THIS_ DWORD, LPDWORD, LPDPLCONNECTION, HANDLE32) PURE;
-    STDMETHOD(SendLobbyMessage)     (THIS_ DWORD, DWORD, LPVOID, DWORD) PURE;
-    STDMETHOD(SetConnectionSettings)(THIS_ DWORD, DWORD, LPDPLCONNECTION) PURE;
+    STDMETHOD(Connect)              (THIS_ DWORD, LPDIRECTPLAY *, IUnknown *) PURE;                       
+    STDMETHOD(CreateAddress)        (THIS_ REFGUID, REFGUID, LPCVOID, DWORD, LPVOID, LPDWORD) PURE;       
+    STDMETHOD(EnumAddress)          (THIS_ LPDPENUMADDRESSCALLBACK, LPCVOID, DWORD, LPVOID) PURE;         
+    STDMETHOD(EnumAddressTypes)     (THIS_ LPDPLENUMADDRESSTYPESCALLBACK, REFGUID, LPVOID, DWORD) PURE;   
+    STDMETHOD(EnumLocalApplications)(THIS_ LPDPLENUMLOCALAPPLICATIONSCALLBACK, LPVOID, DWORD) PURE;       
+    STDMETHOD(GetConnectionSettings)(THIS_ DWORD, LPVOID, LPDWORD) PURE;                                  
+    STDMETHOD(ReceiveLobbyMessage)  (THIS_ DWORD, DWORD, LPDWORD, LPVOID, LPDWORD) PURE;                  
+    STDMETHOD(RunApplication)       (THIS_ DWORD, LPDWORD, LPDPLCONNECTION, HANDLE32) PURE;               
+    STDMETHOD(SendLobbyMessage)     (THIS_ DWORD, DWORD, LPVOID, DWORD) PURE;                             
+    STDMETHOD(SetConnectionSettings)(THIS_ DWORD, DWORD, LPDPLCONNECTION) PURE;                           
+    STDMETHOD(SetLobbyMessageEvent) (THIS_ DWORD, DWORD, HANDLE32) PURE;
+
+
+} DIRECTPLAYLOBBY_VTABLE, *LPDIRECTPLAYLOBBY_VTABLE;
+#undef THIS
+
+#define THIS LPDIRECTPLAYLOBBY2 this
+typedef struct tagLPDIRECTPLAYLOBBY2_VTABLE 
+{
+    /*  IUnknown Methods "Inherited Methods" */
+    STDMETHOD(QueryInterface)       (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef)        (THIS)  PURE;
+    STDMETHOD_(ULONG,Release)       (THIS) PURE;
+
+    /*  IDirectPlayLobby Methods */
+    STDMETHOD(Connect)              (THIS_ DWORD, LPDIRECTPLAY2 *, IUnknown *) PURE;                       
+    STDMETHOD(CreateAddress)        (THIS_ REFGUID, REFGUID, LPCVOID, DWORD, LPVOID, LPDWORD) PURE;       
+    STDMETHOD(EnumAddress)          (THIS_ LPDPENUMADDRESSCALLBACK, LPCVOID, DWORD, LPVOID) PURE;         
+    STDMETHOD(EnumAddressTypes)     (THIS_ LPDPLENUMADDRESSTYPESCALLBACK, REFGUID, LPVOID, DWORD) PURE;   
+    STDMETHOD(EnumLocalApplications)(THIS_ LPDPLENUMLOCALAPPLICATIONSCALLBACK, LPVOID, DWORD) PURE;       
+    STDMETHOD(GetConnectionSettings)(THIS_ DWORD, LPVOID, LPDWORD) PURE;                                  
+    STDMETHOD(ReceiveLobbyMessage)  (THIS_ DWORD, DWORD, LPDWORD, LPVOID, LPDWORD) PURE;                  
+    STDMETHOD(RunApplication)       (THIS_ DWORD, LPDWORD, LPDPLCONNECTION, HANDLE32) PURE;               
+    STDMETHOD(SendLobbyMessage)     (THIS_ DWORD, DWORD, LPVOID, DWORD) PURE;                             
+    STDMETHOD(SetConnectionSettings)(THIS_ DWORD, DWORD, LPDPLCONNECTION) PURE;                           
     STDMETHOD(SetLobbyMessageEvent) (THIS_ DWORD, DWORD, HANDLE32) PURE;
 
     /*  IDirectPlayLobby2 Methods */
     STDMETHOD(CreateCompoundAddress)(THIS_ LPCDPCOMPOUNDADDRESSELEMENT, DWORD, LPVOID, LPDWORD) PURE;
 
 } DIRECTPLAYLOBBY2_VTABLE, *LPDIRECTPLAYLOBBY2_VTABLE;
+#undef THIS
 
-/* Is this right? How does one know? */
-struct IDirectPlayLobby2 {
-    LPDIRECTPLAYLOBBY2_VTABLE lpvtbl;
-    DWORD                     ref;
-};
+/**********************************************************************************
+ *
+ * Macros for a nicer interface to DirectPlayLobby
+ *
+ **********************************************************************************/
+
+/* COM Interface */
+
+#define IDirectPlayLobby_QueryInterface(p,a,b)              (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectPlayLobby_AddRef(p)                          (p)->lpVtbl->AddRef(p)
+#define IDirectPlayLobby_Release(p)                         (p)->lpVtbl->Release(p)
+
+#define IDirectPlayLobby2_QueryInterface(p,a,b)             (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectPlayLobby2_AddRef(p)                         (p)->lpVtbl->AddRef(p)
+#define IDirectPlayLobby2_Release(p)                        (p)->lpVtbl->Release(p)
+
+/* Direct Play Lobby 1 */
+
+#define IDirectPlayLobby_Connect(p,a,b,c)                   (p)->lpVtbl->Connect(p,a,b,c)
+#define IDirectPlayLobby_CreateAddress(p,a,b,c,d,e,f)       (p)->lpVtbl->CreateAddress(p,a,b,c,d,e,f)
+#define IDirectPlayLobby_EnumAddress(p,a,b,c,d)             (p)->lpVtbl->EnumAddress(p,a,b,c,d)
+#define IDirectPlayLobby_EnumAddressTypes(p,a,b,c,d)        (p)->lpVtbl->EnumAddressTypes(p,a,b,c,d)
+#define IDirectPlayLobby_EnumLocalApplications(p,a,b,c)     (p)->lpVtbl->EnumLocalApplications(p,a,b,c)
+#define IDirectPlayLobby_GetConnectionSettings(p,a,b,c)     (p)->lpVtbl->GetConnectionSettings(p,a,b,c)
+#define IDirectPlayLobby_ReceiveLobbyMessage(p,a,b,c,d,e)   (p)->lpVtbl->ReceiveLobbyMessage(p,a,b,c,d,e)
+#define IDirectPlayLobby_RunApplication(p,a,b,c,d)          (p)->lpVtbl->RunApplication(p,a,b,c,d)
+#define IDirectPlayLobby_SendLobbyMessage(p,a,b,c,d)        (p)->lpVtbl->SendLobbyMessage(p,a,b,c,d)
+#define IDirectPlayLobby_SetConnectionSettings(p,a,b,c)     (p)->lpVtbl->SetConnectionSettings(p,a,b,c)
+#define IDirectPlayLobby_SetLobbyMessageEvent(p,a,b,c)      (p)->lpVtbl->SetLobbyMessageEvent(p,a,b,c)
+
+#define IDirectPlayLobby2_Connect(p,a,b,c)                  (p)->lpVtbl->Connect(p,a,b,c)
+#define IDirectPlayLobby2_CreateAddress(p,a,b,c,d,e,f)      (p)->lpVtbl->CreateAddress(p,a,b,c,d,e,f)
+#define IDirectPlayLobby2_EnumAddress(p,a,b,c,d)            (p)->lpVtbl->EnumAddress(p,a,b,c,d)
+#define IDirectPlayLobby2_EnumAddressTypes(p,a,b,c,d)       (p)->lpVtbl->EnumAddressTypes(p,a,b,c,d)
+#define IDirectPlayLobby2_EnumLocalApplications(p,a,b,c)    (p)->lpVtbl->EnumLocalApplications(p,a,b,c)
+#define IDirectPlayLobby2_GetConnectionSettings(p,a,b,c)    (p)->lpVtbl->GetConnectionSettings(p,a,b,c)
+#define IDirectPlayLobby2_ReceiveLobbyMessage(p,a,b,c,d,e)  (p)->lpVtbl->ReceiveLobbyMessage(p,a,b,c,d,e)
+#define IDirectPlayLobby2_RunApplication(p,a,b,c,d)         (p)->lpVtbl->RunApplication(p,a,b,c,d)
+#define IDirectPlayLobby2_SendLobbyMessage(p,a,b,c,d)       (p)->lpVtbl->SendLobbyMessage(p,a,b,c,d)
+#define IDirectPlayLobby2_SetConnectionSettings(p,a,b,c)    (p)->lpVtbl->SetConnectionSettings(p,a,b,c)
+#define IDirectPlayLobby2_SetLobbyMessageEvent(p,a,b,c)     (p)->lpVtbl->SetLobbyMessageEvent(p,a,b,c)
+
+
+/* Direct Play Lobby 2 */
+
+#define IDirectPlayLobby2_CreateCompoundAddress(p,a,b,c,d)   (p)->lpVtbl->CreateCompoundAddress(p,a,b,c,d)
 
 #pragma pack(4)
 
diff --git a/include/file.h b/include/file.h
index eb54708..b8fdff4 100644
--- a/include/file.h
+++ b/include/file.h
@@ -47,6 +47,8 @@
 (((handle)==0) ? GetStdHandle(STD_INPUT_HANDLE) : \
  ((handle)==1) ? GetStdHandle(STD_OUTPUT_HANDLE) : \
  ((handle)==2) ? GetStdHandle(STD_ERROR_HANDLE) : \
+ ((handle)==3) ? GetStdHandle(STD_ERROR_HANDLE) : \
+ ((handle)==4) ? GetStdHandle(STD_ERROR_HANDLE) : \
  ((handle)>=0x400) ? handle : \
  (handle)-5)
 
diff --git a/include/global.h b/include/global.h
index 775f31e..06074ee 100644
--- a/include/global.h
+++ b/include/global.h
@@ -22,6 +22,7 @@
                                      BOOL16 is32Bit, BOOL16 isReadOnly,
                                      SHMDATA *shmdata);
 extern BOOL16 GLOBAL_FreeBlock( HGLOBAL16 handle );
+extern BOOL16 GLOBAL_MoveBlock( HGLOBAL16 handle, const void *ptr, DWORD size );
 extern HGLOBAL16 GLOBAL_Alloc( WORD flags, DWORD size, HGLOBAL16 hOwner,
                                BOOL16 isCode, BOOL16 is32Bit,
                                BOOL16 isReadOnly );
diff --git a/include/header.h b/include/header.h
index 298f67b..0ab962a 100644
--- a/include/header.h
+++ b/include/header.h
@@ -10,11 +10,9 @@
 
 typedef struct 
 {
-    UINT32    mask;
     INT32     cxy;
     HBITMAP32 hbm;
     LPSTR     pszText;
-    INT32     cchTextMax;
     INT32     fmt;
     LPARAM    lParam;
     INT32     iImage;
diff --git a/include/imm.h b/include/imm.h
index 5b40a6b..31ee343 100644
--- a/include/imm.h
+++ b/include/imm.h
@@ -5,8 +5,10 @@
 #ifndef __WINE_IMM_H
 #define __WINE_IMM_H
 
-typedef DWORD HIMC32;
-typedef DWORD HIMCC32;
+#include "wintypes.h"
+
+typedef HANDLE32 HIMC32;
+typedef HANDLE32 HIMCC32;
 
 typedef HKL32 *LPHKL32;
 
diff --git a/include/k32obj.h b/include/k32obj.h
index 0e1dad3..b0e8633 100644
--- a/include/k32obj.h
+++ b/include/k32obj.h
@@ -62,8 +62,8 @@
 extern BOOL32 K32OBJ_IsValid( K32OBJ *ptr, K32OBJ_TYPE type );
 extern BOOL32 K32OBJ_AddName( K32OBJ *obj, LPCSTR name );
 extern K32OBJ *K32OBJ_Create( K32OBJ_TYPE type, DWORD size, LPCSTR name,
-                              DWORD access, SECURITY_ATTRIBUTES *sa,
-                              HANDLE32 *handle );
+                              int server_handle, DWORD access,
+                              SECURITY_ATTRIBUTES *sa, HANDLE32 *handle );
 extern K32OBJ *K32OBJ_FindName( LPCSTR name );
 extern K32OBJ *K32OBJ_FindNameType( LPCSTR name, K32OBJ_TYPE type );
 
diff --git a/include/listview.h b/include/listview.h
index 10795e7..869c798 100644
--- a/include/listview.h
+++ b/include/listview.h
@@ -16,23 +16,26 @@
     LPARAM lParam;
     INT32  iIndent;
 
-    HDSA   hdsaItem;
 } LISTVIEW_ITEM;
 
 
 typedef struct tagLISTVIEW_INFO
 {
     COLORREF   clrBk;
+    COLORREF   clrText;
+    COLORREF   clrTextBk;
     HIMAGELIST himlNormal;
     HIMAGELIST himlSmall;
     HIMAGELIST himlState;
     INT32      nItemCount;
+    INT32      nColumnCount;
     HWND32     hwndHeader;
     HFONT32    hDefaultFont;
     HFONT32    hFont;
     RECT32     rcList;       /* "client" area of the list (without header) */
+    BOOL32     bFocus;
 
-    HDSA       hdsaItems;
+    HDPA       hdpaItems;
 
 } LISTVIEW_INFO;
 
diff --git a/include/miscemu.h b/include/miscemu.h
index 9c2b26a..a9cb741 100644
--- a/include/miscemu.h
+++ b/include/miscemu.h
@@ -30,8 +30,12 @@
 extern UINT32 DOSMEM_MapLinearToDos(LPVOID); /* linear Wine to DOS */
 
 /* msdos/interrupts.c */
-extern FARPROC16 INT_GetHandler( BYTE intnum );
-extern void INT_SetHandler( BYTE intnum, FARPROC16 handler );
+extern FARPROC16 INT_GetPMHandler( BYTE intnum );
+extern void INT_SetPMHandler( BYTE intnum, FARPROC16 handler );
+extern FARPROC16 INT_GetRMHandler( BYTE intnum );
+extern void INT_SetRMHandler( BYTE intnum, FARPROC16 handler );
+extern FARPROC16 INT_CtxGetHandler( CONTEXT *context, BYTE intnum );
+extern void INT_CtxSetHandler( CONTEXT *context, BYTE intnum, FARPROC16 handler );
 extern int INT_RealModeInterrupt( BYTE intnum, PCONTEXT context );
 
 /* msdos/ioports.c */
@@ -39,6 +43,9 @@
 extern DWORD IO_inport( int port, int count );
 extern void IO_outport( int port, int count, DWORD value );
 
+/* msdos/int10.c */
+extern void WINAPI INT_Int10Handler(CONTEXT*);
+
 /* msdos/int1a.c */
 extern DWORD INT1A_GetTicksSinceMidnight(void);
 extern void WINAPI INT_Int1aHandler(CONTEXT*);
@@ -46,9 +53,15 @@
 /* msdos/int20.c */
 extern void WINAPI INT_Int20Handler(CONTEXT*);
 
+/* msdos/int25.c */
+extern void WINAPI INT_Int25Handler(CONTEXT*);
+
 /* msdos/int2f.c */
 extern void WINAPI INT_Int2fHandler(CONTEXT*);
 
+/* msdos/int31.c */
+extern void WINAPI INT_Int31Handler(CONTEXT*);
+
 /* loader/signal.c */
 extern BOOL32 SIGNAL_Init(void);
 extern void SIGNAL_SetHandler( int sig, void (*func)(), int flags );
diff --git a/include/mmsystem.h b/include/mmsystem.h
index 1e10215..bf34f17 100644
--- a/include/mmsystem.h
+++ b/include/mmsystem.h
@@ -2759,6 +2759,7 @@
 	HMIDI16		hMidi;
 	DWORD		dwCallback;
 	DWORD		dwInstance;
+	UINT16	wDevID;
 } MIDIOPENDESC, *LPMIDIOPENDESC;
 
 typedef struct {
diff --git a/include/module.h b/include/module.h
index bc0e25f..96ca217 100644
--- a/include/module.h
+++ b/include/module.h
@@ -63,7 +63,8 @@
     WORD      size;      /* Segment size on disk */
     WORD      flags;     /* Segment flags */
     WORD      minsize;   /* Min. size of segment in memory */
-    HANDLE16  selector;  /* Selector of segment in memory */
+    HANDLE16  hSeg;      /* Selector or handle (selector - 1) */
+                         /* of segment in memory */
 } SEGTABLEENTRY;
 
 
@@ -143,6 +144,7 @@
 extern HMODULE32 MODULE_CreateDummyModule( const OFSTRUCT *ofs );
 extern FARPROC16 MODULE_GetWndProcEntry16( const char *name );
 extern FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE32 hmodule, LPCSTR name );
+extern SEGPTR WINAPI HasGPHandler( SEGPTR address );
 
 /* loader/ne/module.c */
 extern NE_MODULE *NE_GetPtr( HMODULE16 hModule );
diff --git a/include/multimedia.h b/include/multimedia.h
index d2dcc9c..843228d 100644
--- a/include/multimedia.h
+++ b/include/multimedia.h
@@ -29,7 +29,11 @@
 
 #include <sys/errno.h>
 
+#ifdef HAVE_OSS
+#define MIDI_SEQ "/dev/sequencer"
+#else
 #define MIDI_DEV "/dev/midi"
+#endif
 
 #ifdef SOUND_VERSION
 #define IOCTL(a,b,c)		ioctl(a,b,&c)
@@ -38,40 +42,53 @@
 #endif
 
 typedef struct {
+#ifndef HAVE_OSS
 	int		unixdev;
+#endif
 	int		state;
 	DWORD		bufsize;
-	MIDIOPENDESC	midiDesc;
+	LPMIDIOPENDESC	midiDesc;
 	WORD		wFlags;
 	LPMIDIHDR 	lpQueueHdr;
 	DWORD		dwTotalPlayed;
+#ifdef HAVE_OSS
+	unsigned char	incoming[3];
+	unsigned char	incPrev;
+	char		incLen;
+	DWORD		startTime;
+#endif
 } LINUX_MIDIIN;
 
 typedef struct {
+#ifndef HAVE_OSS
 	int		unixdev;
+#endif
 	int		state;
 	DWORD		bufsize;
-	MIDIOPENDESC	midiDesc;
+	LPMIDIOPENDESC	midiDesc;
 	WORD		wFlags;
 	LPMIDIHDR 	lpQueueHdr;
 	DWORD		dwTotalPlayed;
+#ifdef HAVE_OSS
+	void*		lpExtra;	 	/* according to port type (MIDI, FM...), extra data when needed */
+#endif
 } LINUX_MIDIOUT;
 
 typedef struct {
-	int	nUseCount;          /* Incremented for each shared open */
-	BOOL16	fShareable;         /* TRUE if first open was shareable */
-	WORD	wNotifyDeviceID;    /* MCI device ID with a pending notification */
-	HANDLE16 hCallback;         /* Callback handle for pending notification */
-	HMMIO16	hFile;	            /* mmio file handle open as Element		*/
-	DWORD	dwBeginData;
-	DWORD	dwTotalLen;
-	WORD	wFormat;
-	WORD	nTracks;
-	WORD	nTempo;
+	int		nUseCount;          	/* Incremented for each shared open */
+	BOOL16		fShareable;         	/* TRUE if first open was shareable */
+	WORD		wNotifyDeviceID;    	/* MCI device ID with a pending notification */
+	HANDLE16 	hCallback;         	/* Callback handle for pending notification */
+	HMMIO16		hFile;	            	/* mmio file handle open as Element		*/
+	DWORD		dwBeginData;
+	DWORD		dwTotalLen;
+	WORD		wFormat;
+	WORD		nTracks;
+	WORD		nTempo;
 	MCI_OPEN_PARMS16 openParms;
 /* 	MIDIHDR	MidiHdr; */
 	HLOCAL16	hMidiHdr;
-	WORD	dwStatus;
+	WORD		dwStatus;
 } LINUX_MCIMIDI;
 
 /* function prototypes */
diff --git a/include/multimon.h b/include/multimon.h
new file mode 100644
index 0000000..82f26e6
--- /dev/null
+++ b/include/multimon.h
@@ -0,0 +1,65 @@
+/*
+ * Multimonitor APIs
+ *
+ * Copyright 1998 Turchanov Sergey
+ */
+
+#ifndef __WINE_MULTIMON_H
+#define __WINE_MULTIMON_H
+
+#define MONITOR_DEFAULTTONULL       0x00000000
+#define MONITOR_DEFAULTTOPRIMARY    0x00000001
+#define MONITOR_DEFAULTTONEAREST    0x00000002
+
+#define HMONITOR HANDLE32 
+
+HMONITOR WINAPI MonitorFromPoint(POINT32 pt, DWORD dwFlags);
+
+HMONITOR WINAPI MonitorFromRect(LPRECT32 lprc, DWORD dwFlags);
+
+HMONITOR WINAPI MonitorFromWindow(HWND32 hwnd, DWORD dwFlags);
+
+#define MONITORINFOF_PRIMARY        0x00000001
+
+#ifndef CCHDEVICENAME
+#define CCHDEVICENAME 32
+#endif
+
+typedef struct tagMONITORINFO
+{
+    DWORD   cbSize;
+    RECT32  rcMonitor;
+    RECT32  rcWork;
+    DWORD   dwFlags;
+} MONITORINFO, *LPMONITORINFO;
+
+typedef struct tagMONITORINFOEX32A
+{
+    MONITORINFO dummy;
+    CHAR        szDevice[CCHDEVICENAME];
+} MONITORINFOEX32A, *LPMONITORINFOEX32A;
+
+typedef struct tagMONITORINFOEX32W
+{
+    MONITORINFO dummy;
+    WCHAR       szDevice[CCHDEVICENAME];
+} MONITORINFOEX32W, *LPMONITORINFOEX32W;
+
+DECL_WINELIB_TYPE_AW (MONITOINFOEX)
+DECL_WINELIB_TYPE_AW (LPMONITORINFOEXW)
+
+BOOL32 WINAPI GetMonitorInfo32A(HMONITOR hMonitor, LPMONITORINFO lpmi);
+BOOL32 WINAPI GetMonitorInfo32W(HMONITOR hMonitor, LPMONITORINFO lpmi);
+
+#define GetMonitorInfo WINELIB_NAME_AW(GetMonitorInfo)
+
+typedef BOOL32 (CALLBACK* MONITORENUMPROC)(HMONITOR, HDC32, LPRECT32, LPARAM);
+
+BOOL32 WINAPI EnumDisplayMonitors(
+    HDC32             hdc,
+    LPRECT32         lprcClip,
+    MONITORENUMPROC lpfnEnum,
+    LPARAM          dwData);
+    
+#endif __WINE_MULTIMON_H
+
diff --git a/include/oledlg.h b/include/oledlg.h
index 1b937fc..1b7ce5b 100644
--- a/include/oledlg.h
+++ b/include/oledlg.h
@@ -10,32 +10,32 @@
 #define OLEUI_OK      1 /* OK button pressed */ 
 #define OLEUI_CANCEL  2 /* Cancel button pressed */
 
-typedef void *LPOLEUIINSERTOBJECTA; /* FIXME: stub */
-typedef void *LPOLEUIINSERTOBJECTW; /* FIXME: stub */
+typedef void *LPOLEUIINSERTOBJECT32A; /* FIXME: stub */
+typedef void *LPOLEUIINSERTOBJECT32W; /* FIXME: stub */
 
-typedef void *LPOLEUIPASTESPECIALA;  /* FIXME: stub */
-typedef void *LPOLEUIPASTESPECIALW;  /* FIXME: stub */
+typedef void *LPOLEUIPASTESPECIAL32A;  /* FIXME: stub */
+typedef void *LPOLEUIPASTESPECIAL32W;  /* FIXME: stub */
 
-typedef void *LPOLEUIEDITLINKSA;  /* FIXME: stub */
-typedef void *LPOLEUIEDITLINKSW;  /* FIXME: stub */
+typedef void *LPOLEUIEDITLINKS32A;  /* FIXME: stub */
+typedef void *LPOLEUIEDITLINKS32W;  /* FIXME: stub */
 
-typedef void *LPOLEUICHANGEICONA; /* FIXME: stub */
-typedef void *LPOLEUICHANGEICONW; /* FIXME: stub */
+typedef void *LPOLEUICHANGEICON32A; /* FIXME: stub */
+typedef void *LPOLEUICHANGEICON32W; /* FIXME: stub */
 
-typedef void *LPOLEUICONVERTA; /* FIXME: stub */
-typedef void *LPOLEUICONVERTW; /* FIXME: stub */
+typedef void *LPOLEUICONVERT32A; /* FIXME: stub */
+typedef void *LPOLEUICONVERT32W; /* FIXME: stub */
 
-typedef void *LPOLEUIBUSYA; /* FIXME: stub */
-typedef void *LPOLEUIBUSYW; /* FIXME: stub */
+typedef void *LPOLEUIBUSY32A; /* FIXME: stub */
+typedef void *LPOLEUIBUSY32W; /* FIXME: stub */
 
-typedef void *LPOLEUILINKCONTAINERA; /* FIXME: stub */
-typedef void *LPOLEUILINKCONTAINERW; /* FIXME: stub */
+typedef void *LPOLEUILINKCONTAINER32A; /* FIXME: stub */
+typedef void *LPOLEUILINKCONTAINER32W; /* FIXME: stub */
 
-typedef void *LPOLEUIOBJECTPROPSA; /* FIXME: stub */
-typedef void *LPOLEUIOBJECTPROPSW; /* FIXME: stub */
+typedef void *LPOLEUIOBJECTPROPS32A; /* FIXME: stub */
+typedef void *LPOLEUIOBJECTPROPS32W; /* FIXME: stub */
 
-typedef void *LPOLEUICHANGESOURCEA; /* FIXME: stub */
-typedef void *LPOLEUICHANGESOURCEW; /* FIXME: stub */
+typedef void *LPOLEUICHANGESOURCE32A; /* FIXME: stub */
+typedef void *LPOLEUICHANGESOURCE32W; /* FIXME: stub */
 
 #endif  /* __WINE_OLEDLG_H */
 
diff --git a/include/options.h b/include/options.h
index 2b9fceb..8f047ab 100644
--- a/include/options.h
+++ b/include/options.h
@@ -10,6 +10,10 @@
 #include "wintypes.h"
 
   /* Supported languages */
+  /* When adding a new language look at ole/ole2nls.c 
+   * for the LANG_Xx name to choose, and uncomment there
+   * the proper case line
+   */
 typedef enum
 {
     LANG_En,  /* English */
@@ -19,14 +23,14 @@
     LANG_Fr,  /* French */
     LANG_Fi,  /* Finnish */
     LANG_Da,  /* Danish */
-    LANG_Cz,  /* Czech */
+    LANG_Cs,  /* Czech */
     LANG_Eo,  /* Esperanto */
     LANG_It,  /* Italian */
     LANG_Ko,  /* Korean */
     LANG_Hu,  /* Hungarian */
     LANG_Pl,  /* Polish */
-    LANG_Po,  /* Portuguese */
-    LANG_Sw,  /* Swedish */
+    LANG_Pt,  /* Portuguese */
+    LANG_Sv,  /* Swedish */
     LANG_Ca   /* Catalan */
 } WINE_LANGUAGE;
 
@@ -64,6 +68,7 @@
     WINE_LANGUAGE language; /* Current language */
     int    managed;	    /* Managed windows */
     int    perfectGraphics; /* Favor correctness over speed for graphics */
+    char * configFileName;  /* Command line config file */
 };
 
 extern struct options Options;
@@ -71,6 +76,7 @@
 /* Profile functions */
 
 extern int PROFILE_LoadWineIni(void);
+extern void PROFILE_UsageWineIni(void);
 extern int PROFILE_GetWineIniString( const char *section, const char *key_name,
                                      const char *def, char *buffer, int len );
 extern int PROFILE_GetWineIniInt( const char *section, const char *key_name,
diff --git a/include/psapi.h b/include/psapi.h
new file mode 100644
index 0000000..fd4ff94
--- /dev/null
+++ b/include/psapi.h
@@ -0,0 +1,33 @@
+/*
+ *      psapi.h        -       Declarations for PSAPI
+ */
+
+#ifndef __WINE_PSAPI_H
+#define __WINE_PSAPI_H
+
+typedef struct _MODULEINFO32 {
+  LPVOID lpBaseOfDll;
+  DWORD SizeOfImage;
+  LPVOID EntryPoint;
+} MODULEINFO32, *LPMODULEINFO32;
+
+typedef struct _PROCESS_MEMORY_COUNTERS32 {  
+  DWORD cb;    
+  DWORD PageFaultCount;
+  DWORD PeakWorkingSetSize;
+  DWORD WorkingSetSize;
+  DWORD QuotaPeakPagedPoolUsage;
+  DWORD QuotaPagedPoolUsage;
+  DWORD QuotaPeakNonPagedPoolUsage;  
+  DWORD QuotaNonPagedPoolUsage;
+  DWORD PagefileUsage;    
+  DWORD PeakPagefileUsage;
+} PROCESS_MEMORY_COUNTERS32;
+typedef PROCESS_MEMORY_COUNTERS32 *PPROCESS_MEMORY_COUNTERS32;
+
+typedef struct _PSAPI_WS_WATCH_INFORMATION32 {
+  LPVOID FaultingPc;
+  LPVOID FaultingVa;
+} PSAPI_WS_WATCH_INFORMATION32, *PPSAPI_WS_WATCH_INFORMATION32;
+
+#endif  /* __WINE_PSAPI_H */
diff --git a/include/server.h b/include/server.h
index 30e09ac..e93cea7 100644
--- a/include/server.h
+++ b/include/server.h
@@ -152,9 +152,105 @@
 #define SELECT_ALERTABLE 4
 #define SELECT_TIMEOUT   8
 
+
+/* Create an event */
+struct create_event_request
+{
+    int          manual_reset;  /* manual reset event */
+    int          initial_state; /* initial state of the event */
+    int          inherit;       /* inherit flag */
+    /* char name[] */
+};
+struct create_event_reply
+{
+    int          handle;        /* handle to the event */
+};
+
+/* Event operation */
+struct event_op_request
+{
+    int           handle;       /* handle to event */
+    int           op;           /* event operation (see below) */
+};
+enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT };
+
+
+/* Create a mutex */
+struct create_mutex_request
+{
+    int          owned;         /* initially owned? */
+    int          inherit;       /* inherit flag */
+    /* char name[] */
+};
+struct create_mutex_reply
+{
+    int          handle;        /* handle to the mutex */
+};
+
+
+/* Release a mutex */
+struct release_mutex_request
+{
+    int          handle;        /* handle to the mutex */
+};
+
+
+/* Create a semaphore */
+struct create_semaphore_request
+{
+    unsigned int initial;       /* initial count */
+    unsigned int max;           /* maximum count */
+    int          inherit;       /* inherit flag */
+    /* char name[] */
+};
+struct create_semaphore_reply
+{
+    int          handle;        /* handle to the semaphore */
+};
+
+
+/* Release a semaphore */
+struct release_semaphore_request
+{
+    int          handle;        /* handle to the semaphore */
+    unsigned int count;         /* count to add to semaphore */
+};
+struct release_semaphore_reply
+{
+    unsigned int prev_count;    /* previous semaphore count */
+};
+
+/* Open a named object (event, mutex, semaphore) */
+struct open_named_obj_request
+{
+    int          type;         /* object type (see below) */
+    unsigned int access;       /* wanted access rights */
+    int          inherit;      /* inherit flag */
+    /* char name[] */
+};
+enum open_named_obj { OPEN_EVENT, OPEN_MUTEX, OPEN_SEMAPHORE };
+
+struct open_named_obj_reply
+{
+    int          handle;        /* handle to the object */
+};
+
+
 /* client-side functions */
 
 #ifndef __WINE_SERVER__
+
+/* client communication functions */
+enum request;
+#define CHECK_LEN(len,wanted) \
+  if ((len) == (wanted)) ; \
+  else CLIENT_ProtocolError( __FUNCTION__ ": len %d != %d\n", (len), (wanted) );
+extern void CLIENT_ProtocolError( const char *err, ... );
+extern void CLIENT_SendRequest( enum request req, int pass_fd,
+                                int n, ... /* arg_1, len_1, etc. */ );
+extern unsigned int CLIENT_WaitReply( int *len, int *passed_fd,
+                                      int n, ... /* arg_1, len_1, etc. */ );
+
 struct _THDB;
 extern int CLIENT_NewThread( struct _THDB *thdb, int *thandle, int *phandle );
 extern int CLIENT_InitThread(void);
diff --git a/include/server/object.h b/include/server/object.h
index 5268061..a968dda 100644
--- a/include/server/object.h
+++ b/include/server/object.h
@@ -12,6 +12,7 @@
 #endif
 
 #include <sys/time.h>
+#include "server.h"
 #include "server/request.h"
 
 /* kernel objects */
@@ -37,12 +38,16 @@
     struct object_name       *name;
 };
 
-extern void init_object( struct object *obj, const struct object_ops *ops,
-                         const char *name );
+extern void *mem_alloc( size_t size );  /* malloc wrapper */
+extern struct object *create_named_object( const char *name, const struct object_ops *ops,
+                                           size_t size );
+extern int init_object( struct object *obj, const struct object_ops *ops,
+                        const char *name );
 /* grab/release_object can take any pointer, but you better make sure */
 /* that the thing pointed to starts with a struct object... */
 extern struct object *grab_object( void *obj );
 extern void release_object( void *obj );
+extern struct object *find_object( const char *name );
 
 /* request handlers */
 
@@ -97,6 +102,31 @@
                                       unsigned int access, const struct object_ops *ops );
 extern int duplicate_handle( struct process *src, int src_handle, struct process *dst,
                              int dst_handle, unsigned int access, int inherit, int options );
+extern int open_object( const char *name, const struct object_ops *ops,
+                        unsigned int access, int inherit );
+
+/* event functions */
+
+extern struct object *create_event( const char *name, int manual_reset, int initial_state );
+extern int open_event( unsigned int access, int inherit, const char *name );
+extern int pulse_event( int handle );
+extern int set_event( int handle );
+extern int reset_event( int handle );
+
+
+/* mutex functions */
+
+extern struct object *create_mutex( const char *name, int owned );
+extern int open_mutex( unsigned int access, int inherit, const char *name );
+extern int release_mutex( int handle );
+extern void abandon_mutexes( struct thread *thread );
+
+
+/* semaphore functions */
+
+extern struct object *create_semaphore( const char *name, unsigned int initial, unsigned int max );
+extern int open_semaphore( unsigned int access, int inherit, const char *name );
+extern int release_semaphore( int handle, unsigned int count, unsigned int *prev_count );
 
 extern int debug_level;
 
diff --git a/include/server/request.h b/include/server/request.h
index b882ebc..2dc80a5 100644
--- a/include/server/request.h
+++ b/include/server/request.h
@@ -15,6 +15,13 @@
     REQ_DUP_HANDLE,
     REQ_OPEN_PROCESS,
     REQ_SELECT,
+    REQ_CREATE_EVENT,
+    REQ_EVENT_OP,
+    REQ_CREATE_MUTEX,
+    REQ_RELEASE_MUTEX,
+    REQ_CREATE_SEMAPHORE,
+    REQ_RELEASE_SEMAPHORE,
+    REQ_OPEN_NAMED_OBJ,
     REQ_NB_REQUESTS
 };
 
@@ -33,6 +40,13 @@
 DECL_HANDLER(dup_handle);
 DECL_HANDLER(open_process);
 DECL_HANDLER(select);
+DECL_HANDLER(create_event);
+DECL_HANDLER(event_op);
+DECL_HANDLER(create_mutex);
+DECL_HANDLER(release_mutex);
+DECL_HANDLER(create_semaphore);
+DECL_HANDLER(release_semaphore);
+DECL_HANDLER(open_named_obj);
 
 static const struct handler {
     void       (*handler)();
@@ -48,6 +62,13 @@
     { (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) },
+    { (void(*)())req_create_event, sizeof(struct create_event_request) },
+    { (void(*)())req_event_op, sizeof(struct event_op_request) },
+    { (void(*)())req_create_mutex, sizeof(struct create_mutex_request) },
+    { (void(*)())req_release_mutex, sizeof(struct release_mutex_request) },
+    { (void(*)())req_create_semaphore, sizeof(struct create_semaphore_request) },
+    { (void(*)())req_release_semaphore, sizeof(struct release_semaphore_request) },
+    { (void(*)())req_open_named_obj, sizeof(struct open_named_obj_request) },
 };
 #endif  /* WANT_REQUEST_HANDLERS */
 
diff --git a/include/server/thread.h b/include/server/thread.h
index 7f7df8d..c9c373a 100644
--- a/include/server/thread.h
+++ b/include/server/thread.h
@@ -17,6 +17,7 @@
 
 struct process;
 struct thread_wait;
+struct mutex;
 
 enum run_state { STARTING, RUNNING, TERMINATED };
 
@@ -28,6 +29,7 @@
     struct thread      *proc_next; /* per-process thread list */
     struct thread      *proc_prev;
     struct process     *process;
+    struct mutex       *mutex;     /* list of currently owned mutexes */
     struct thread_wait *wait;      /* current wait condition if sleeping */
     int                 error;     /* current error code */
     enum run_state      state;     /* running state */
@@ -57,6 +59,7 @@
                       int flags, int timeout );
 extern void wake_up( struct object *obj, int max );
 
+#define GET_ERROR()     (current->error)
 #define SET_ERROR(err)  (current->error = (err))
 #define CLEAR_ERROR()   (current->error = 0)
 
diff --git a/include/shell.h b/include/shell.h
index 3475ca4..f4fd676 100644
--- a/include/shell.h
+++ b/include/shell.h
@@ -224,7 +224,7 @@
 *  string and path functions
 */
 LPSTR WINAPI PathAddBackslash(LPSTR path);	
-LPSTR WINAPI PathCombine(LPSTR target,LPSTR x1,LPSTR x2);
+LPSTR WINAPI PathCombine(LPSTR szDest, LPCSTR lpszDir, LPCSTR lpszFile);
 LPSTR WINAPI PathRemoveBlanks(LPSTR str);
 LPSTR WINAPI PathFindFilename(LPSTR fn);
 /****************************************************************************
diff --git a/include/shlobj.h b/include/shlobj.h
index fd4599d..050f54a 100644
--- a/include/shlobj.h
+++ b/include/shlobj.h
@@ -30,15 +30,40 @@
 typedef struct tagSHELLEXTINIT	*LPSHELLEXTINIT,IShellExtInit;
 typedef struct tagENUMIDLIST	*LPENUMIDLIST,	IEnumIDList;
 typedef struct tagSHELLFOLDER	*LPSHELLFOLDER,	IShellFolder;
-typedef struct tagSHELLVIEW		*LPSHELLVIEW,	IShellView;
+typedef struct tagSHELLVIEW	*LPSHELLVIEW,	IShellView;
 typedef struct tagSHELLBROWSER	*LPSHELLBROWSER,IShellBrowser;
-
-typedef struct IDataObject		IDataObject,	*LPDATAOBJECT;
-
+typedef struct tagDATAOBJECT	*LPDATAOBJECT,	IDataObject;
+typedef struct tagSHELLICON	*LPSHELLICON,	IShellIcon;
+typedef struct tagDOCKINGWINDOWFRAME	*LPDOCKINGWINDOWFRAME,	IDockingWindowFrame;
+typedef struct tagSERVICEPROVIDER	*LPSERVICEPROVIDER,	IServiceProvider;
+typedef struct tagCOMMDLGBROWSER	*LPCOMMDLGBROWSER,	ICommDlgBrowser;
+typedef struct tagENUMFORMATETC	*LPENUMFORMATETC,	IEnumFORMATETC;
+ 
+typedef struct IAdviseSink		IAdviseSink,	*LPIADVISESINK;
+typedef struct IEnumSTATDATA		IEnumSTATDATA,	*LPENUMSTATDATA;
 /****************************************************************************
 *  SHELL ID
 */
-/* shell32 classids */
+/* strange Objects */
+DEFINE_SHLGUID(IID_IEnumUnknown,	0x00000100L, 0, 0);
+DEFINE_SHLGUID(IID_IEnumString,		0x00000101L, 0, 0);
+DEFINE_SHLGUID(IID_IEnumMoniker,	0x00000102L, 0, 0);
+DEFINE_SHLGUID(IID_IEnumFORMATETC,	0x00000103L, 0, 0);
+DEFINE_SHLGUID(IID_IEnumOLEVERB,	0x00000104L, 0, 0);
+DEFINE_SHLGUID(IID_IEnumSTATDATA,	0x00000105L, 0, 0);
+
+DEFINE_SHLGUID(IID_IPersistStream,	0x00000109L, 0, 0);
+DEFINE_SHLGUID(IID_IPersistStorage,	0x0000010AL, 0, 0);
+DEFINE_SHLGUID(IID_IPersistFile,	0x0000010BL, 0, 0);
+DEFINE_SHLGUID(IID_IPersist,		0x0000010CL, 0, 0);
+DEFINE_SHLGUID(IID_IViewObject,		0x0000010DL, 0, 0);
+DEFINE_SHLGUID(IID_IDataObject,		0x0000010EL, 0, 0);
+
+DEFINE_GUID (IID_IServiceProvider,	0x6D5140C1L, 0x7436, 0x11CE, 0x80, 0x34, 0x00, 0xAA, 0x00, 0x60, 0x09, 0xFA);
+DEFINE_GUID (IID_IDockingWindow,	0x012dd920L, 0x7B26, 0x11D0, 0x8C, 0xA9, 0x00, 0xA0, 0xC9, 0x2D, 0xBF, 0xE8);
+DEFINE_GUID (IID_IDockingWindowSite,	0x2A342FC2L, 0x7B26, 0x11D0, 0x8C, 0xA9, 0x00, 0xA0, 0xC9, 0x2D, 0xBF, 0xE8);
+DEFINE_GUID (IID_IDockingWindowFrame,	0x47D2657AL, 0x7B27, 0x11D0, 0x8C, 0xA9, 0x00, 0xA0, 0xC9, 0x2D, 0xBF, 0xE8);
+
 DEFINE_SHLGUID(CLSID_ShellDesktop,      0x00021400L, 0, 0);
 DEFINE_SHLGUID(CLSID_ShellLink,         0x00021401L, 0, 0);
 /* shell32 formatids */
@@ -51,6 +76,7 @@
  /* shell32interface ids */
 DEFINE_SHLGUID(IID_INewShortcutHookA,   0x000214E1L, 0, 0);
 DEFINE_SHLGUID(IID_IShellBrowser,       0x000214E2L, 0, 0);
+#define SID_SShellBrowser IID_IShellBrowser
 DEFINE_SHLGUID(IID_IShellView,          0x000214E3L, 0, 0);
 DEFINE_SHLGUID(IID_IContextMenu,        0x000214E4L, 0, 0);
 DEFINE_SHLGUID(IID_IShellIcon,          0x000214E5L, 0, 0);
@@ -95,6 +121,12 @@
  */
 #define THIS LPCONTEXTMENU this
 
+/* default menu items*/
+#define IDM_EXPLORE  0
+#define IDM_OPEN     1
+#define IDM_RENAME   2
+#define IDM_LAST     IDM_RENAME
+
 /* QueryContextMenu uFlags */
 #define CMF_NORMAL              0x00000000
 #define CMF_DEFAULTONLY         0x00000001
@@ -205,6 +237,100 @@
 
 #undef THIS
 /*****************************************************************************
+ * IData structures
+ */
+typedef struct
+{	DWORD tdSize;
+	WORD tdDriverNameOffset;
+	WORD tdDeviceNameOffset;
+	WORD tdPortNameOffset;
+	WORD tdExtDevmodeOffset;
+	BYTE tdData[ 1 ];
+}   DVTARGETDEVICE32;
+
+typedef WORD CLIPFORMAT32, *LPCLIPFORMAT32;
+
+typedef struct 
+{	DWORD tymed;
+	union 
+	{ HBITMAP32 hBitmap;
+	  /*HMETAFILEPICT32 hMetaFilePict;*/
+	  /*HENHMETAFILE32 hEnhMetaFile;*/
+	  HGLOBAL32 hGlobal;
+	  LPOLESTR32 lpszFileName;
+	  IStream32 *pstm;
+	  IStorage32 *pstg;
+        } u;
+	IUnknown *pUnkForRelease;
+} STGMEDIUM32;   
+ 
+typedef struct 
+{	CLIPFORMAT32 cfFormat;
+	DVTARGETDEVICE32 *ptd;
+	DWORD dwAspect;
+	LONG lindex;
+	DWORD tymed;
+} FORMATETC32, *LPFORMATETC32;
+
+/*****************************************************************************
+ * IEnumFORMATETC interface
+ */
+#define THIS LPENUMFORMATETC this
+
+typedef struct IEnumFORMATETC_VTable 
+{    /* IUnknown methods */
+	STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+	STDMETHOD_(ULONG,AddRef) (THIS) PURE;
+	STDMETHOD_(ULONG,Release) (THIS) PURE;
+
+	/* IEnumFORMATETC methods */
+	STDMETHOD (Next)(THIS_ ULONG celt, FORMATETC32 *rgelt, ULONG *pceltFethed) PURE;
+	STDMETHOD (Skip)(THIS_ ULONG celt) PURE;
+	STDMETHOD (Reset)(THIS) PURE;
+	STDMETHOD (Clone)(THIS_ IEnumFORMATETC ** ppenum) PURE;
+} IEnumFORMATETC_VTable,*LPENUMFORMATETC_VTABLE;
+
+struct tagENUMFORMATETC
+{	LPENUMFORMATETC_VTABLE	lpvtbl;
+	DWORD			 ref;
+        UINT32	posFmt;
+        UINT32	countFmt;
+        LPFORMATETC32 pFmt;
+};
+
+#undef THIS
+
+/*****************************************************************************
+ * IDataObject interface
+ */
+#define THIS LPDATAOBJECT this
+
+typedef struct IDataObject_VTable 
+{	/*** IUnknown methods ***/
+	STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+	STDMETHOD_(ULONG,AddRef) (THIS) PURE;
+	STDMETHOD_(ULONG,Release) (THIS) PURE;
+
+	STDMETHOD (GetData )(THIS_ LPFORMATETC32 pformatetcIn, STGMEDIUM32 *pmedium) PURE;
+	STDMETHOD (GetDataHere)(THIS_ LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium) PURE;
+        STDMETHOD (QueryGetData)(THIS_ LPFORMATETC32 pformatetc) PURE;
+        STDMETHOD (GetCanonicalFormatEtc)(THIS_ LPFORMATETC32 pformatectIn, LPFORMATETC32 pformatetcOut) PURE;
+        STDMETHOD (SetData)(THIS_ LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium, BOOL32 fRelease) PURE;
+        STDMETHOD (EnumFormatEtc)(THIS_ DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc) PURE;
+        STDMETHOD (DAdvise )(THIS_ LPFORMATETC32 *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection) PURE;
+        STDMETHOD (DUnadvise)(THIS_ DWORD dwConnection) PURE;
+        STDMETHOD (EnumDAdvise)(THIS_ IEnumSTATDATA **ppenumAdvise) PURE;
+} IDataObject_VTable,*LPDATAOBJECT_VTABLE;
+
+struct tagDATAOBJECT
+{	LPDATAOBJECT_VTABLE	lpvtbl;
+	DWORD			 ref;
+};
+
+#undef THIS
+
+
+/*****************************************************************************
  * IShellExtInit interface
  */
 #define THIS LPSHELLEXTINIT this
@@ -402,19 +528,50 @@
 };
 
 extern LPSHELLFOLDER pdesktopfolder;
+
+/************************
+* Shellfolder API
+*/
+DWORD WINAPI SHGetDesktopFolder(LPSHELLFOLDER *);
 #undef THIS
 
 /************************************************************************
 * IShellBrowser interface
 */
 #define THIS LPSHELLBROWSER this
+/* targets for GetWindow/SendControlMsg */
+#define FCW_STATUS		0x0001
+#define FCW_TOOLBAR		0x0002
+#define FCW_TREE		0x0003
+#define FCW_INTERNETBAR		0x0006
+#define FCW_PROGRESS		0x0008
 
-#define FCW_STATUS      0x0001
-#define FCW_TOOLBAR     0x0002
-#define FCW_TREE        0x0003
-#define FCW_INTERNETBAR 0x0006
-#define FCW_PROGRESS    0x0008
+/* wFlags for BrowseObject*/
+#define SBSP_DEFBROWSER		0x0000
+#define SBSP_SAMEBROWSER	0x0001
+#define SBSP_NEWBROWSER		0x0002
 
+#define SBSP_DEFMODE		0x0000
+#define SBSP_OPENMODE		0x0010
+#define SBSP_EXPLOREMODE	0x0020
+
+#define SBSP_ABSOLUTE		0x0000
+#define SBSP_RELATIVE		0x1000
+#define SBSP_PARENT		0x2000
+#define SBSP_NAVIGATEBACK	0x4000
+#define SBSP_NAVIGATEFORWARD	0x8000
+
+#define SBSP_ALLOW_AUTONAVIGATE		0x10000
+
+#define SBSP_INITIATEDBYHLINKFRAME	0x80000000
+#define SBSP_REDIRECT			0x40000000
+#define SBSP_WRITENOHISTORY		0x08000000
+
+/* uFlage for SetToolbarItems */
+#define FCT_MERGE       0x0001
+#define FCT_CONFIGABLE  0x0002
+#define FCT_ADDTOEND    0x0004
+ 
 typedef struct IShellBrowser_VTable 
 {    // *** IUnknown methods ***
     STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
@@ -536,7 +693,7 @@
     STDMETHOD(SaveViewState)(THIS) PURE;
     STDMETHOD(SelectItem)(THIS_ LPCITEMIDLIST pidlItem, UINT32 uFlags) PURE;
     STDMETHOD(GetItemObject)(THIS_ UINT32 uItem, REFIID riid,LPVOID *ppv) PURE;
-} IShellView_VTable,*LPSHELLVIEW_VTABLE;;
+} IShellView_VTable,*LPSHELLVIEW_VTABLE;
 
 struct tagSHELLVIEW 
 { LPSHELLVIEW_VTABLE lpvtbl;
@@ -544,6 +701,7 @@
   LPITEMIDLIST       mpidl;
   LPSHELLFOLDER      pSFParent;
   LPSHELLBROWSER     pShellBrowser;
+  LPCOMMDLGBROWSER   pCommDlgBrowser;
   HWND32             hWnd;
   HWND32             hWndList;
   FOLDERSETTINGS     FolderSettings;
@@ -553,10 +711,37 @@
 };
 
 typedef GUID SHELLVIEWID;
-#define SV_CLASS_NAME   ("ShellViewClass")
+#define SV_CLASS_NAME   ("SHELLDLL_DefView")
 
 #undef THIS
+/****************************************************************************
+ * ICommDlgBrowser interface
+ */
+#define THIS LPCOMMDLGBROWSER this
 
+/* for OnStateChange*/
+#define CDBOSC_SETFOCUS     0x00000000
+#define CDBOSC_KILLFOCUS    0x00000001
+#define CDBOSC_SELCHANGE    0x00000002
+#define CDBOSC_RENAME       0x00000003
+
+typedef struct ICommDlgBrowser_VTable
+{   /* IUnknown methods */
+    STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef) (THIS)  PURE;
+    STDMETHOD_(ULONG,Release) (THIS) PURE;
+
+    /* ICommDlgBrowser methods */
+    STDMETHOD(OnDefaultCommand) (THIS_  LPSHELLVIEW ppshv) PURE;
+    STDMETHOD(OnStateChange) (THIS_ LPSHELLVIEW ppshv, ULONG uChange) PURE;
+    STDMETHOD(IncludeObject) (THIS_ LPSHELLVIEW ppshv, LPCITEMIDLIST pidl) PURE;
+} ICommDlgBrowser_VTable,*LPCOMMDLGBROWSER_VTABLE;
+
+struct tagCOMMDLGBROWSER
+{ LPCOMMDLGBROWSER_VTABLE lpvtbl;
+  DWORD			     ref;
+};
+#undef THIS
 /****************************************************************************
  * IShellLink interface
  */
@@ -666,7 +851,7 @@
  */
 
 #define THIS LPSHELLICON this
-typedef struct IShellIcon IShellIcon,*LPSHELLICON;
+
 typedef struct IShellIcon_VTable
 { /*** IUnknown methods ***/
   STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
@@ -677,24 +862,73 @@
   STDMETHOD(GetIconOf)(THIS_ LPCITEMIDLIST pidl, UINT32 flags, LPINT32 lpIconIndex) PURE;
 } IShellIcon_VTable,*LPSHELLICON_VTABLE;
 
-struct IShellIcon
+struct tagSHELLICON
 { LPSHELLICON_VTABLE lpvtbl;
   DWORD ref;
 };
 #undef THIS
+/****************************************************************************
+ * IDockingWindowFrame interface
+ */
+#define THIS LPDOCKINGWINDOWFRAME this
 
+#define DWFRF_NORMAL		0x0000  /* femove toolbar flags*/
+#define DWFRF_DELETECONFIGDATA	0x0001
+#define DWFAF_HIDDEN		0x0001   /* add tolbar*/
 
+typedef struct IDockingWindowFrame_VTable
+{   STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef) (THIS)  PURE;
+    STDMETHOD_(ULONG,Release) (THIS) PURE;
+
+    /*** IOleWindow methods ***/
+    STDMETHOD(GetWindow) (THIS_ HWND32 * lphwnd) PURE;
+    STDMETHOD(ContextSensitiveHelp) (THIS_ BOOL32 fEnterMode) PURE;
+
+    /*** IDockingWindowFrame methods ***/
+    STDMETHOD(AddToolbar) (THIS_ IUnknown* punkSrc, LPCWSTR pwszItem, DWORD dwAddFlags) PURE;
+    STDMETHOD(RemoveToolbar) (THIS_ IUnknown* punkSrc, DWORD dwRemoveFlags) PURE;
+    STDMETHOD(FindToolbar) (THIS_ LPCWSTR pwszItem, REFIID riid, LPVOID* ppvObj) PURE;
+} IDockingWindowFrame_VTable, *LPDOCKINGWINDOWFRAME_VTABLE;
+
+struct tagDOCKINGWINDOWFRAME
+{ LPDOCKINGWINDOWFRAME_VTABLE lpvtbl;
+  DWORD ref;
+};
+
+#undef THIS
+/****************************************************************************
+ * IServiceProvider interface
+ */
+#define THIS LPSERVICEPROVIDER this
+
+typedef struct IServiceProvider_VTable
+{	/*** IUnknown methods ***/
+	STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+	STDMETHOD_(ULONG,AddRef) (THIS)  PURE;
+	STDMETHOD_(ULONG,Release) (THIS) PURE;
+
+	STDMETHOD(QueryService)(THIS_ REFGUID guidService, REFIID riid, void **ppvObject);
+} IServiceProvider_VTable, *LPSERVICEPROVIDER_VTABLE;
+
+struct tagSERVICEPROVIDER
+{	LPSERVICEPROVIDER_VTABLE lpvtbl;
+	DWORD ref;
+};           
 /****************************************************************************
  * 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);
+extern LPDATAOBJECT	IDataObject_Constructor();
+extern LPENUMFORMATETC	IEnumFORMATETC_Constructor(UINT32, const FORMATETC32 []);
+
+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);
+extern LPEXTRACTICON	IExtractIcon_Constructor(LPITEMIDLIST);
 #endif
 /****************************************************************************
  * Shell Execute API
diff --git a/include/sysmetrics.h b/include/sysmetrics.h
index 101f317..bfb6cf3 100644
--- a/include/sysmetrics.h
+++ b/include/sysmetrics.h
@@ -129,6 +129,13 @@
 #define SYSMETRICS_MIDEASTENABLED       sysMetrics[SM_MIDEASTENABLED]       /* 74 */
 #define SYSMETRICS_MOUSEWHEELPRESENT    sysMetrics[SM_MOUSEWHEELPRESENT]    /* 75 */
 
+#define SYSMETRICS_CXVIRTUALSCREEN	sysMetrics[SM_CXVIRTUALSCREEN]	    /* 77 */
+#define SYSMETRICS_CYVIRTUALSCREEN	sysMetrics[SM_CYVIRTUALSCREEN]	    /* 77 */
+#define SYSMETRICS_YVIRTUALSCREEN	sysMetrics[SM_YVIRTUALSCREEN]	    /* 78 */
+#define SYSMETRICS_XVIRTUALSCREEN	sysMetrics[SM_XVIRTUALSCREEN]	    /* 79 */
+#define SYSMETRICS_CMONITORS		sysMetrics[SM_CMONITORS]	    /* 81 */
+#define SYSMETRICS_SAMEDISPLAYFORMAT	sysMetrics[SM_SAMEDISPLAYFORMAT]    /* 82 */
+
 extern void SYSMETRICS_Init(void);  /* sysmetrics.c */
 extern short sysMetrics[SM_CMETRICS+1];
 
diff --git a/include/thread.h b/include/thread.h
index 22e62bf..60c4220 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -7,12 +7,29 @@
 #ifndef __WINE_THREAD_H
 #define __WINE_THREAD_H
 
+#include "config.h"
 #include "k32obj.h"
 #include "windows.h"
 #include "winbase.h"
 #include "winnt.h"
 #include "selectors.h"  /* for SET_FS */
 
+#ifdef linux
+#define HAVE_CLONE_SYSCALL
+#endif
+
+/* This is what we will use on *BSD, once threads using rfork() get
+ * implemented:
+ *
+ * #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
+ * #define HAVE_RFORK
+ * #endif
+ */
+
+#if (defined(HAVE_CLONE_SYSCALL) || defined(HAVE_RFORK)) && !defined(NO_REENTRANT_LIBC)
+#define USE_THREADS
+#endif
+
 struct _PDB32;
 
 /* Thread exception block */
@@ -133,6 +150,7 @@
                             LPTHREAD_START_ROUTINE start_addr, LPVOID param );
 extern THDB *THREAD_Current(void);
 extern BOOL32 THREAD_IsWin16( THDB *thdb );
+extern THDB *THREAD_IdToTHDB( DWORD id );
 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 1f4f443..3560067 100644
--- a/include/toolbar.h
+++ b/include/toolbar.h
@@ -53,6 +53,7 @@
     BOOL32     bTransparent;    /* background transparency flag */
     BOOL32     bAutoSize;       /* auto size deadlock indicator */
     DWORD      dwExStyle;       /* extended toolbar style */
+    DWORD      dwDTFlags;       /* DrawText flags */
 
     COLORREF   clrInsertMark;   /* insert mark color */
     RECT32     rcBound;         /* bounding rectangle */
diff --git a/include/tooltips.h b/include/tooltips.h
index d0d0c72..c38e94c 100644
--- a/include/tooltips.h
+++ b/include/tooltips.h
@@ -30,25 +30,26 @@
 
 typedef struct tagTOOLTIPS_INFO
 {
-    CHAR        szTipText[INFOTIPSIZE];
-    BOOL32      bActive;
-    BOOL32      bTrackActive;
-    UINT32      uNumTools;
-    COLORREF    clrBk;
-    COLORREF    clrText;
-    HFONT32     hFont;
-    INT32       xTrackPos;
-    INT32       yTrackPos;
-    INT32       nMaxTipWidth;
-    INT32       nTool;
-    INT32       nOldTool;
-    INT32       nCurrentTool;
-    INT32       nTrackTool;
-    INT32       nAutomaticTime;
-    INT32       nReshowTime;
-    INT32       nAutoPopTime;
-    INT32       nInitialTime;
-    RECT32      rcMargin;
+    CHAR       szTipText[INFOTIPSIZE];
+    BOOL32     bActive;
+    BOOL32     bTrackActive;
+    UINT32     uNumTools;
+    COLORREF   clrBk;
+    COLORREF   clrText;
+    HFONT32    hFont;
+    INT32      xTrackPos;
+    INT32      yTrackPos;
+    INT32      nMaxTipWidth;
+    INT32      nTool;
+    INT32      nOldTool;
+    INT32      nCurrentTool;
+    INT32      nTrackTool;
+    INT32      nAutomaticTime;
+    INT32      nReshowTime;
+    INT32      nAutoPopTime;
+    INT32      nInitialTime;
+    RECT32     rcMargin;
+
     TTTOOL_INFO *tools;
 } TOOLTIPS_INFO;
 
diff --git a/include/trackbar.h b/include/trackbar.h
index f9ee1e8..3da5a65 100644
--- a/include/trackbar.h
+++ b/include/trackbar.h
@@ -18,13 +18,17 @@
     INT32  nPos;
     UINT32 uThumbLen;
     UINT32 uNumTics;
+	UINT32  uTicFreq;
     HWND32 hwndToolTip;
     HWND32 hwndBuddyLA;
     HWND32 hwndBuddyRB;
     INT32  fLocation;
-
+	COLORREF clrBk;
+	
+	INT32  flags;
     BOOL32 bFocus;
     RECT32 rcChannel;
+    RECT32 rcSelection;
     RECT32 rcThumb;
     LPLONG tics;
 } TRACKBAR_INFO;
diff --git a/include/treeview.h b/include/treeview.h
index 0c315d4..2e19fae 100644
--- a/include/treeview.h
+++ b/include/treeview.h
@@ -2,19 +2,79 @@
  * Treeview class extra info
  *
  * Copyright 1998 Eric Kohl
+ * Copyright 1998 Alex Priem
  */
 
 #ifndef __WINE_TREEVIEW_H
 #define __WINE_TREEVIEW_H
 
+#define MINIMUM_INDENT 10
+
+
+#define TVITEM_ALLOC	16
+#define TV_REFRESH_TIMER 1	
+#define TV_EDIT_TIMER    2
+#define TV_REFRESH_TIMER_SET 1  
+#define TV_EDIT_TIMER_SET 2  
+#define TV_REFRESH_DELAY 100     /* 100 ms delay between two refreshes */
+#define TV_DEFAULTITEMHEIGHT 15
+
+/* internal structures */
+
+typedef struct {
+    UINT32 mask;
+    HTREEITEM hItem;
+    UINT32 state;
+    UINT32 stateMask;
+    LPSTR pszText;
+    int cchTextMax;
+    int iImage;
+    int iSelectedImage;
+    int cChildren;
+    LPARAM lParam;
+    int iIntegral;
+	int clrText;
+	
+	int parent;	    /* handle to parent or 0 if at root*/
+	int firstChild;     /* handle to first child or 0 if no child*/
+	int sibling;        /* handle to next item in list, 0 if last */
+	int upsibling;      /* handle to previous item in list, 0 if first */
+	int visible;
+        RECT32 rect;
+	RECT32 text;
+} TREEVIEW_ITEM;
+
+
+#define TV_HSCROLL 	0x01    /* treeview too large to fit in window */
+#define TV_VSCROLL 	0x02	/* (horizontal/vertical) */
+
 typedef struct tagTREEVIEW_INFO
 {
-    COLORREF clrBk;
+    UINT32	uInternalStatus;		
+    UINT32  uNumItems;	/* number of valid TREEVIEW_ITEMs */
+    UINT32	uNumPtrsAlloced; 
+    UINT32	uMaxHandle;	/* needed for delete_item */
+    HTREEITEM 	TopRootItem;	/* handle to first item in treeview */
+
+	UINT32	uItemHeight;		/* item height, -1 for default item height */
+	UINT32 	uRealItemHeight;	/* real item height in pixels */
+	UINT32	uVisibleHeight;	    /* visible height of treeview in pixels */
+    UINT32	uTotalHeight;		/* total height of treeview in pixels */
+    UINT32	uIndent;		/* indentation in pixels */
+    HTREEITEM	selectedItem;   /* handle to selected item or 0 if none */
+    HTREEITEM   firstVisible;	/* handle to first visible item */
+    HTREEITEM   dropItem;	/* handle to item selected by drag cursor */
+    INT32	cx,cy;		/* current x/y place in list */
+    COLORREF clrBk;		
     COLORREF clrText;
+    HFONT32     hFont;
 
-    HIMAGELIST himlNormal;
+    HIMAGELIST himlNormal;	
     HIMAGELIST himlState;
-
+    TREEVIEW_ITEM *items;	/* itemlist */
+    INT32	*freeList;	/* bitmap indicating which elements are valid */
+				/* 1=valid, 0=free; 	*/
+				/* size of list= uNumPtrsAlloced/32 */
 
 } TREEVIEW_INFO;
 
diff --git a/include/tweak.h b/include/tweak.h
index 06bffee..b9c39c7 100644
--- a/include/tweak.h
+++ b/include/tweak.h
@@ -11,13 +11,17 @@
 
 #include "wintypes.h"
 
+typedef enum
+{
+    WIN31_LOOK,
+    WIN95_LOOK,
+    WIN98_LOOK
+} WINE_LOOK;
+
+
 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);
-void  TWEAK_DrawMenuSeparatorVert95(HDC32, UINT32, UINT32, UINT32);
-extern int  TWEAK_Win95Look;
-extern int  TWEAK_WineInitialized;
+
+extern WINE_LOOK TWEAK_WineLook;
 
 #endif /* __WINE_TWEAK_H */
diff --git a/include/version.h b/include/version.h
index 0062e05..49e51e5 100644
--- a/include/version.h
+++ b/include/version.h
@@ -1 +1 @@
-#define WINE_RELEASE_INFO "Wine release 980913"
+#define WINE_RELEASE_INFO "Wine release 980927"
diff --git a/include/vfw.h b/include/vfw.h
new file mode 100644
index 0000000..8500da8
--- /dev/null
+++ b/include/vfw.h
@@ -0,0 +1,272 @@
+#ifndef __WINE_VFW_H
+#define __WINE_VFW_H
+
+#include <wintypes.h>
+#include <driver.h>
+
+#define VFWAPI	WINAPI
+#define VFWAPIV	WINAPIV
+
+DWORD VFWAPI VideoForWindowsVersion(void);
+
+#ifndef aviTWOCC
+#define aviTWOCC(ch0, ch1) ((WORD)(BYTE)(ch0) | ((WORD)(BYTE)(ch1) << 8))
+#endif
+
+#define ICTYPE_VIDEO	mmioFOURCC('v', 'i', 'd', 'c')
+#define ICTYPE_AUDIO	mmioFOURCC('a', 'u', 'd', 'c')
+
+
+/* Installable Compressor M? */
+
+/* HIC32 struct (same layout as Win95 one) */
+typedef struct tagWINE_HIC {
+	DWORD		magic;		/* 00: 'Smag' */
+	HANDLE32	curthread;	/* 04: */
+	DWORD		type;		/* 08: */
+	DWORD		handler;	/* 0C: */
+	HDRVR32		hdrv;		/* 10: */
+	DWORD		private;	/* 14: private data passed to drv */
+	FARPROC32	driverproc;	/* 18: */
+	DWORD		x1;		/* 1c: name? */
+	WORD		x2;		/* 20: */
+	DWORD		x3;		/* 22: */
+					/* 26: */
+} WINE_HIC;
+
+/* error return codes */
+#define	ICERR_OK		0
+#define	ICERR_DONTDRAW		1
+#define	ICERR_NEWPALETTE	2
+#define	ICERR_GOTOKEYFRAME	3
+#define	ICERR_STOPDRAWING	4
+
+#define	ICERR_UNSUPPORTED	-1
+#define	ICERR_BADFORMAT		-2
+#define	ICERR_MEMORY		-3
+#define	ICERR_INTERNAL		-4
+#define	ICERR_BADFLAGS		-5
+#define	ICERR_BADPARAM		-6
+#define	ICERR_BADSIZE		-7
+#define	ICERR_BADHANDLE		-8
+#define	ICERR_CANTUPDATE	-9
+#define	ICERR_ABORT		-10
+#define	ICERR_ERROR		-100
+#define	ICERR_BADBITDEPTH	-200
+#define	ICERR_BADIMAGESIZE	-201
+
+#define	ICERR_CUSTOM		-400
+
+/* ICM Messages */
+#define	ICM_USER		(DRV_USER+0x0000)
+
+/* ICM driver message range */
+#define	ICM_RESERVED_LOW	(DRV_USER+0x1000)
+#define	ICM_RESERVED_HIGH	(DRV_USER+0x2000)
+#define	ICM_RESERVED		ICM_RESERVED_LOW
+
+#define	ICM_GETSTATE		(ICM_RESERVED+0)
+#define	ICM_SETSTATE		(ICM_RESERVED+1)
+#define	ICM_GETINFO		(ICM_RESERVED+2)
+
+#define	ICM_CONFIGURE		(ICM_RESERVED+10)
+#define	ICM_ABOUT		(ICM_RESERVED+11)
+/* */
+
+#define	ICM_GETDEFAULTQUALITY	(ICM_RESERVED+30)
+#define	ICM_GETQUALITY		(ICM_RESERVED+31)
+#define	ICM_SETQUALITY		(ICM_RESERVED+32)
+
+#define	ICM_SET			(ICM_RESERVED+40)
+#define	ICM_GET			(ICM_RESERVED+41)
+
+/* 2 constant FOURCC codes */
+#define ICM_FRAMERATE		mmioFOURCC('F','r','m','R')
+#define ICM_KEYFRAMERATE	mmioFOURCC('K','e','y','R')
+
+#define	ICM_COMPRESS_GET_FORMAT		(ICM_USER+4)
+#define	ICM_COMPRESS_GET_SIZE		(ICM_USER+5)
+#define	ICM_COMPRESS_QUERY		(ICM_USER+6)
+#define	ICM_COMPRESS_BEGIN		(ICM_USER+7)
+#define	ICM_COMPRESS			(ICM_USER+8)
+#define	ICM_COMPRESS_END		(ICM_USER+9)
+
+#define	ICM_DECOMPRESS_GET_FORMAT	(ICM_USER+10)
+#define	ICM_DECOMPRESS_QUERY		(ICM_USER+11)
+#define	ICM_DECOMPRESS_BEGIN		(ICM_USER+12)
+#define	ICM_DECOMPRESS			(ICM_USER+13)
+#define	ICM_DECOMPRESS_END		(ICM_USER+14)
+#define	ICM_DECOMPRESS_SET_PALETTE	(ICM_USER+29)
+#define	ICM_DECOMPRESS_GET_PALETTE	(ICM_USER+30)
+
+#define	ICM_DRAW_QUERY			(ICM_USER+31)
+#define	ICM_DRAW_BEGIN			(ICM_USER+15)
+#define	ICM_DRAW_GET_PALETTE		(ICM_USER+16)
+#define	ICM_DRAW_START			(ICM_USER+18)
+#define	ICM_DRAW_STOP			(ICM_USER+19)
+#define	ICM_DRAW_END			(ICM_USER+21)
+#define	ICM_DRAW_GETTIME		(ICM_USER+32)
+#define	ICM_DRAW			(ICM_USER+33)
+#define	ICM_DRAW_WINDOW			(ICM_USER+34)
+#define	ICM_DRAW_SETTIME		(ICM_USER+35)
+#define	ICM_DRAW_REALIZE		(ICM_USER+36)
+#define	ICM_DRAW_FLUSH			(ICM_USER+37)
+#define	ICM_DRAW_RENDERBUFFER		(ICM_USER+38)
+
+#define	ICM_DRAW_START_PLAY		(ICM_USER+39)
+#define	ICM_DRAW_STOP_PLAY		(ICM_USER+40)
+
+#define	ICM_DRAW_SUGGESTFORMAT		(ICM_USER+50)
+#define	ICM_DRAW_CHANGEPALETTE		(ICM_USER+51)
+
+#define	ICM_GETBUFFERSWANTED		(ICM_USER+41)
+
+#define	ICM_GETDEFAULTKEYFRAMERATE	(ICM_USER+42)
+
+#define	ICM_DECOMPRESSEX_BEGIN		(ICM_USER+60)
+#define	ICM_DECOMPRESSEX_QUERY		(ICM_USER+61)
+#define	ICM_DECOMPRESSEX		(ICM_USER+62)
+#define	ICM_DECOMPRESSEX_END		(ICM_USER+63)
+
+#define	ICM_COMPRESS_FRAMES_INFO	(ICM_USER+70)
+#define	ICM_SET_STATUS_PROC		(ICM_USER+72)
+
+/* structs */
+
+typedef struct {
+	DWORD	dwSize;		/* 00: size */
+	DWORD	fccType;	/* 04: type 'vidc' usually */
+	DWORD	fccHandler;	/* 08: */
+	DWORD	dwVersion;	/* 0c: version of compman opening you */
+	DWORD	dwFlags;	/* 10: LOWORD is type specific */
+	LRESULT	dwError;	/* 14: */
+	LPVOID	pV1Reserved;	/* 18: */
+	LPVOID	pV2Reserved;	/* 1c: */
+	DWORD	dnDevNode;	/* 20: */
+				/* 24: */
+} ICOPEN,*LPICOPEN;
+
+/* Values for dwFlags of ICOpen() */
+#define	ICMODE_COMPRESS		1
+#define	ICMODE_DECOMPRESS	2
+#define	ICMODE_FASTDECOMPRESS	3
+#define	ICMODE_QUERY		4
+#define	ICMODE_FASTCOMPRESS	5
+#define	ICMODE_DRAW		8
+
+/* quality flags */
+#define ICQUALITY_LOW       0
+#define ICQUALITY_HIGH      10000
+#define ICQUALITY_DEFAULT   -1
+
+typedef struct {
+	DWORD	dwSize;		/* 00: */
+	DWORD	fccType;	/* 04:compressor type     'vidc' 'audc' */
+	DWORD	fccHandler;	/* 08:compressor sub-type 'rle ' 'jpeg' 'pcm '*/
+	DWORD	dwFlags;	/* 0c:flags LOWORD is type specific */
+	DWORD	dwVersion;	/* 10:version of the driver */
+	DWORD	dwVersionICM;	/* 14:version of the ICM used */
+	/*
+	 * under Win32, the driver always returns UNICODE strings.
+	 */
+	WCHAR	szName[16];		/* 18:short name */
+	WCHAR	szDescription[128];	/* 38:long name */
+	WCHAR	szDriver[128];		/* 138:driver that contains compressor*/
+					/* 238: */
+} ICINFO32;
+
+
+/* Flags for the <dwFlags> field of the <ICINFO> structure. */
+#define	VIDCF_QUALITY		0x0001  /* supports quality */
+#define	VIDCF_CRUNCH		0x0002  /* supports crunching to a frame size */
+#define	VIDCF_TEMPORAL		0x0004  /* supports inter-frame compress */
+#define	VIDCF_COMPRESSFRAMES	0x0008  /* wants the compress all frames message */
+#define	VIDCF_DRAW		0x0010  /* supports drawing */
+#define	VIDCF_FASTTEMPORALC	0x0020  /* does not need prev frame on compress */
+#define	VIDCF_FASTTEMPORALD	0x0080  /* does not need prev frame on decompress */
+#define	VIDCF_QUALITYTIME	0x0040  /* supports temporal quality */
+
+#define	VIDCF_FASTTEMPORAL	(VIDCF_FASTTEMPORALC|VIDCF_FASTTEMPORALD)
+
+
+/* function shortcuts */
+/* ICM_ABOUT */
+#define ICMF_ABOUT_QUERY         0x00000001
+
+#define ICQueryAbout(hic) \
+	(ICSendMessage(hic,ICM_ABOUT,(DWORD)-1,ICMF_ABOUT_QUERY)==ICERR_OK)
+
+#define ICAbout(hic, hwnd) \
+	ICSendMessage(hic,ICM_ABOUT,(DWORD)(UINT)(hwnd),0)
+
+/* ICM_CONFIGURE */
+#define ICMF_CONFIGURE_QUERY	0x00000001
+#define ICQueryConfigure(hic) \
+	(ICSendMessage(hic,ICM_CONFIGURE,(DWORD)-1,ICMF_CONFIGURE_QUERY)==ICERR_OK)
+
+#define ICConfigure(hic,hwnd) \
+	ICSendMessage(hic,ICM_CONFIGURE,(DWORD)(UINT)(hwnd),0)
+
+/* Decompression stuff */
+#define ICDECOMPRESS_HURRYUP		0x80000000	/* don't draw just buffer (hurry up!) */
+#define ICDECOMPRESS_UPDATE		0x40000000	/* don't draw just update screen */
+#define ICDECOMPRESS_PREROL		0x20000000	/* this frame is before real start */
+#define ICDECOMPRESS_NULLFRAME		0x10000000	/* repeat last frame */
+#define ICDECOMPRESS_NOTKEYFRAME	0x08000000	/* this frame is not a key frame */
+
+typedef struct {
+    DWORD		dwFlags;	/* flags (from AVI index...) */
+    LPBITMAPINFOHEADER	lpbiInput;	/* BITMAPINFO of compressed data */
+    LPVOID		lpInput;	/* compressed data */
+    LPBITMAPINFOHEADER	lpbiOutput;	/* DIB to decompress to */
+    LPVOID		lpOutput;
+    DWORD		ckid;		/* ckid from AVI file */
+} ICDECOMPRESS;
+
+typedef struct {
+    DWORD		dwFlags;
+    LPBITMAPINFOHEADER	lpbiSrc;
+    LPVOID		lpSrc;
+    LPBITMAPINFOHEADER	lpbiDst;
+    LPVOID		lpDst;
+
+    /* changed for ICM_DECOMPRESSEX */
+    INT32		xDst;       /* destination rectangle */
+    INT32		yDst;
+    INT32		dxDst;
+    INT32		dyDst;
+
+    INT32		xSrc;       /* source rectangle */
+    INT32		ySrc;
+    INT32		dxSrc;
+    INT32		dySrc;
+} ICDECOMPRESSEX;
+
+#define ICDRAW_QUERY        0x00000001L   // test for support
+#define ICDRAW_FULLSCREEN   0x00000002L   // draw to full screen
+#define ICDRAW_HDC          0x00000004L   // draw to a HDC/HWND
+
+
+BOOL32	VFWAPI	ICInfo32(DWORD fccType, DWORD fccHandler, ICINFO32 * lpicinfo);
+LRESULT	VFWAPI	ICGetInfo32(HIC32 hic,ICINFO32 *picinfo, DWORD cb);
+HIC32	VFWAPI	ICOpen32(DWORD fccType, DWORD fccHandler, UINT32 wMode);
+LRESULT	VFWAPI	ICSendMessage32(HIC32 hic, UINT32 msg, DWORD dw1, DWORD dw2);
+DWORD	VFWAPIV	ICDrawBegin32(
+        HIC32			hic,
+        DWORD			dwFlags,/* flags */
+        HPALETTE32		hpal,	/* palette to draw with */
+        HWND32			hwnd,	/* window to draw to */
+        HDC32			hdc,	/* HDC to draw to */
+        INT32			xDst,	/* destination rectangle */
+        INT32			yDst,
+        INT32			dxDst,
+        INT32			dyDst,
+        LPBITMAPINFOHEADER	lpbi,	/* format of frame to draw */
+        INT32			xSrc,	/* source rectangle */
+        INT32			ySrc,
+        INT32			dxSrc,
+        INT32			dySrc,
+        DWORD			dwRate,	/* frames/second = (dwRate/dwScale) */
+        DWORD			dwScale);
+
+#endif
diff --git a/include/winaspi.h b/include/winaspi.h
new file mode 100644
index 0000000..081df68
--- /dev/null
+++ b/include/winaspi.h
@@ -0,0 +1,100 @@
+#if !defined(WINASPI_H)
+#define WINASPI_H
+
+#pragma pack(1)
+
+#define ASPI_DOS        1
+#define ASPI_WIN16      2
+
+typedef union SRB16 * LPSRB16;
+
+typedef struct tagSRB_HaInquiry16 {
+  BYTE	SRB_Cmd;
+  BYTE	SRB_Status;
+  BYTE	SRB_HaId;
+  BYTE	SRB_Flags;
+  WORD	SRB_55AASignature;
+  WORD	SRB_ExtBufferSize;
+  BYTE	HA_Count;
+  BYTE	HA_SCSI_ID;
+  BYTE	HA_ManagerId[16];
+  BYTE	HA_Identifier[16];
+  BYTE	HA_Unique[16];
+  BYTE	HA_ExtBuffer[4];
+} SRB_HaInquiry16 WINE_PACKED;
+
+typedef struct tagSRB_ExecSCSICmd16 {
+  BYTE        SRB_Cmd;                /* ASPI command code	      (W)  */
+  BYTE        SRB_Status;             /* ASPI command status byte     (R)  */
+  BYTE        SRB_HaId;               /* ASPI host adapter number     (W)  */
+  BYTE        SRB_Flags;              /* ASPI request flags	      (W)  */
+  DWORD       SRB_Hdr_Rsvd;           /* Reserved, MUST = 0	      (-)  */
+  BYTE        SRB_Target;             /* Target's SCSI ID	      (W)  */
+  BYTE        SRB_Lun;                /* Target's LUN number	      (W)  */
+  DWORD       SRB_BufLen;             /* Data Allocation LengthPG     (W/R)*/
+  BYTE        SRB_SenseLen;           /* Sense Allocation Length      (W)  */
+  SEGPTR      SRB_BufPointer;         /* Data Buffer Pointer	      (W)  */
+  DWORD       SRB_Rsvd1;              /* Reserved, MUST = 0	      (-/W)*/
+  BYTE        SRB_CDBLen;             /* CDB Length = 6		      (W)  */
+  BYTE        SRB_HaStat;             /* Host Adapter Status	      (R)  */
+  BYTE        SRB_TargStat;           /* Target Status		      (R)  */
+  FARPROC16   SRB_PostProc;	      /* Post routine		      (W)  */
+  BYTE        SRB_Rsvd2[34];          /* Reserved, MUST = 0                */
+  BYTE		CDBByte[0];	      /* SCSI CBD - variable length   (W)  */
+  /* variable example for 6 byte cbd
+   * BYTE        CDBByte[6];             * SCSI CDB                    (W) *
+   * BYTE        SenseArea6[SENSE_LEN];  * Request Sense buffer 	(R) *
+   */
+} SRB_ExecSCSICmd16 WINE_PACKED;
+
+typedef struct tagSRB_Abort16 {
+  BYTE        SRB_Cmd;            /* ASPI command code = SC_ABORT_SRB */
+  BYTE        SRB_Status;         /* ASPI command status byte */
+  BYTE        SRB_HaId;           /* ASPI host adapter number */
+  BYTE        SRB_Flags;          /* ASPI request flags */
+  DWORD       SRB_Hdr_Rsvd;       /* Reserved, MUST = 0 */
+  LPSRB16     SRB_ToAbort;        /* Pointer to SRB to abort */
+} SRB_Abort16 WINE_PACKED;
+
+typedef struct tagSRB_BusDeviceReset16 {
+  BYTE        SRB_Cmd;            /* ASPI command code = SC_RESET_DEV */
+  BYTE        SRB_Status;         /* ASPI command status byte */
+  BYTE        SRB_HaId;           /* ASPI host adapter number */
+  BYTE        SRB_Flags;          /* ASPI request flags */
+  DWORD       SRB_Hdr_Rsvd;       /* Reserved, MUST = 0 */
+  BYTE        SRB_Target;         /* Target's SCSI ID */
+  BYTE        SRB_Lun;            /* Target's LUN number */
+  BYTE        SRB_ResetRsvd1[14]; /* Reserved, MUST = 0 */
+  BYTE        SRB_HaStat;         /* Host Adapter Status */
+  BYTE        SRB_TargStat;       /* Target Status */
+  SEGPTR      SRB_PostProc;       /* Post routine */
+  BYTE        SRB_ResetRsvd2[34]; /* Reserved, MUST = 0 */
+} SRB_BusDeviceReset16 WINE_PACKED;
+
+typedef struct tagSRB_GDEVBlock16 {
+  BYTE        SRB_Cmd;            /* ASPI command code = SC_GET_DEV_TYPE */
+  BYTE        SRB_Status;         /* ASPI command status byte */
+  BYTE        SRB_HaId;           /* ASPI host adapter number */
+  BYTE        SRB_Flags;          /* ASPI request flags */
+  DWORD       SRB_Hdr_Rsvd;       /* Reserved, MUST = 0 */
+  BYTE        SRB_Target;         /* Target's SCSI ID */
+  BYTE        SRB_Lun;            /* Target's LUN number */
+  BYTE        SRB_DeviceType;     /* Target's peripheral device type */
+} SRB_GDEVBlock16 WINE_PACKED;
+
+typedef struct tagSRB_Common16 {
+  BYTE	SRB_Cmd;
+} SRB_Common16;
+
+union SRB16 {
+  SRB_Common16		common;
+  SRB_HaInquiry16	inquiry;
+  SRB_ExecSCSICmd16	cmd;
+  SRB_Abort16		abort;
+  SRB_BusDeviceReset16	reset;
+  SRB_GDEVBlock16	devtype;
+};
+
+typedef union SRB16 SRB16;
+
+#endif
diff --git a/include/winbase.h b/include/winbase.h
index 16938f2..47878fe 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -189,6 +189,8 @@
 void      WINAPI InitializeCriticalSection(CRITICAL_SECTION *lpCrit);
 void      WINAPI LeaveCriticalSection(CRITICAL_SECTION *lpCrit);
 HANDLE32  WINAPI OpenProcess(DWORD access, BOOL32 inherit, DWORD id);
+BOOL32    WINAPI GetProcessWorkingSetSize(HANDLE32,LPDWORD,LPDWORD);
+BOOL32    WINAPI SetProcessWorkingSetSize(HANDLE32,DWORD,DWORD);
 void      WINAPI RaiseException(DWORD,DWORD,DWORD,const LPDWORD);
 BOOL32    WINAPI TerminateProcess(HANDLE32,DWORD);
 BOOL32    WINAPI TerminateThread(HANDLE32,DWORD);
diff --git a/include/windows.h b/include/windows.h
index 8765e68..af54d71 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -1053,6 +1053,7 @@
 #define COLOR_BTNTEXT		   18
 #define COLOR_INACTIVECAPTIONTEXT  19
 #define COLOR_BTNHIGHLIGHT         20
+/* win95 colors */
 #define COLOR_3DDKSHADOW           21
 #define COLOR_3DLIGHT              22
 #define COLOR_INFOTEXT             23
@@ -1063,6 +1064,11 @@
 #define COLOR_3DHIGHLIGHT          COLOR_BTNHIGHLIGHT
 #define COLOR_3DHILIGHT            COLOR_BTNHIGHLIGHT
 #define COLOR_BTNHILIGHT           COLOR_BTNHIGHLIGHT
+/* win98 colors */
+#define COLOR_ALTERNATEBTNFACE         25  /* undocumented, constant's name unknown */
+#define COLOR_HOTLIGHT                 26
+#define COLOR_GRADIENTACTIVECAPTION    27
+#define COLOR_GRADIENTINACTIVECAPTION  28
 
   /* WM_CTLCOLOR values */
 #define CTLCOLOR_MSGBOX             0
@@ -1077,6 +1083,15 @@
 #define ICM_ON    2
 #define ICM_QUERY 3
 
+  /* Bounds Accumulation APIs */
+#define DCB_RESET       0x0001
+#define DCB_ACCUMULATE  0x0002
+#define DCB_DIRTY       DCB_ACCUMULATE
+#define DCB_SET         (DCB_RESET | DCB_ACCUMULATE)
+#define DCB_ENABLE      0x0004
+#define DCB_DISABLE     0x0008
+
+
   /* Bitmaps */
 
 typedef struct
@@ -2050,8 +2065,14 @@
 #define SM_SLOWMACHINE	      73
 #define SM_MIDEASTENABLED     74
 #define SM_MOUSEWHEELPRESENT  75
+#define SM_XVIRTUALSCREEN     76
+#define SM_YVIRTUALSCREEN     77
+#define SM_CXVIRTUALSCREEN    78
+#define SM_CYVIRTUALSCREEN    79
+#define SM_CMONITORS          80
+#define SM_SAMEDISPLAYFORMAT  81
+#define SM_CMETRICS           83
 
-#define SM_CMETRICS           76
 
   /* Device-independent bitmaps */
 
@@ -6293,6 +6314,15 @@
     DWORD dwPlatformID;
 } DLLVERSIONINFO;
 
+typedef struct _SEGINFO {
+    UINT16    offSegment;
+    UINT16    cbSegment;
+    UINT16    flags;
+    UINT16    cbAlloc;
+    HGLOBAL16 h;
+    UINT16    alignShift;
+    UINT16    reserved[2];
+} SEGINFO;
 
 
 #pragma pack(4)
@@ -6338,7 +6368,7 @@
 INT16       WINAPI GetCommError(INT16,LPCOMSTAT);
 UINT16      WINAPI GetCommEventMask(INT16,UINT16);
 HBRUSH16    WINAPI GetControlBrush(HWND16,HDC16,UINT16);
-VOID        WINAPI GetCodeInfo(FARPROC16,LPVOID);
+VOID        WINAPI GetCodeInfo(FARPROC16,SEGINFO*);
 HFONT16     WINAPI GetCurLogFont(HDC16);
 HANDLE16    WINAPI GetCurrentPDB(void);
 DWORD       WINAPI GetCurrentPosition(HDC16);
@@ -6515,6 +6545,9 @@
 BOOL32      WINAPI DisableThreadLibraryCalls(HMODULE32);
 BOOL32      WINAPI DosDateTimeToFileTime(WORD,WORD,LPFILETIME);
 BOOL32      WINAPI DuplicateHandle(HANDLE32,HANDLE32,HANDLE32,HANDLE32*,DWORD,BOOL32,DWORD);
+BOOL32      WINAPI EnumDateFormats32A(DATEFMT_ENUMPROC32A lpDateFmtEnumProc, LCID Locale, DWORD dwFlags);
+BOOL32      WINAPI EnumDateFormats32W(DATEFMT_ENUMPROC32W lpDateFmtEnumProc, LCID Locale, DWORD dwFlags);
+#define     EnumDateFormats WINELIB_NAME_AW(EnumDateFormats)
 INT32       WINAPI EnumPropsEx32A(HWND32,PROPENUMPROCEX32A,LPARAM);
 INT32       WINAPI EnumPropsEx32W(HWND32,PROPENUMPROCEX32W,LPARAM);
 #define     EnumPropsEx WINELIB_NAME_AW(EnumPropsEx)
@@ -6538,6 +6571,9 @@
 BOOL32      WINAPI EnumSystemLocales32W(LOCALE_ENUMPROC32W,DWORD);
 #define     EnumSystemLocales WINELIB_NAME_AW(EnumSystemLocales)
 BOOL32      WINAPI EnumThreadWindows(DWORD,WNDENUMPROC32,LPARAM);
+BOOL32      WINAPI EnumTimeFormats32A(TIMEFMT_ENUMPROC32A lpTimeFmtEnumProc, LCID Locale, DWORD dwFlags);
+BOOL32      WINAPI EnumTimeFormats32W(TIMEFMT_ENUMPROC32W lpTimeFmtEnumProc, LCID Locale, DWORD dwFlags);
+#define     EnumTimeFormats WINELIB_NAME_AW(EnumTimeFormats)
 VOID        WINAPI ExitProcess(DWORD);
 VOID        WINAPI ExitThread(DWORD);
 BOOL32      WINAPI ExitWindowsEx(UINT32,DWORD);
@@ -7197,7 +7233,7 @@
 HBRUSH32    WINAPI CreateDIBPatternBrush32(HGLOBAL32,UINT32);
 #define     CreateDIBPatternBrush WINELIB_NAME(CreateDIBPatternBrush)
 HBITMAP16   WINAPI CreateDIBSection16 (HDC16, BITMAPINFO *, UINT16,
-				       LPVOID **, HANDLE16, DWORD offset);
+				       LPVOID **, HANDLE32, DWORD offset);
 HBITMAP32   WINAPI CreateDIBSection32 (HDC32, BITMAPINFO *, UINT32,
 				       LPVOID **, HANDLE32, DWORD offset);
 #define     CreateDIBSection WINELIB_NAME(CreateDIBSection)
@@ -7651,6 +7687,9 @@
 INT16       WINAPI GetBkMode16(HDC16);
 INT32       WINAPI GetBkMode32(HDC32);
 #define     GetBkMode WINELIB_NAME(GetBkMode)
+UINT16      WINAPI GetBoundsRect16(HDC16,LPRECT16,UINT16);
+UINT32      WINAPI GetBoundsRect32(HDC32,LPRECT32,UINT32);
+#define     GetBoundsRect WINELIB_NAME(GetBoundsRect)
 HWND16      WINAPI GetCapture16(void);
 HWND32      WINAPI GetCapture32(void);
 #define     GetCapture WINELIB_NAME(GetCapture)
@@ -7833,6 +7872,10 @@
 INT32       WINAPI GetKeyNameText32A(LONG,LPSTR,INT32);
 INT32       WINAPI GetKeyNameText32W(LONG,LPWSTR,INT32);
 #define     GetKeyNameText WINELIB_NAME_AW(GetKeyNameText)
+INT16       WINAPI GetKeyboardLayoutName16(LPSTR);
+INT32       WINAPI GetKeyboardLayoutName32A(LPSTR);
+INT32       WINAPI GetKeyboardLayoutName32W(LPWSTR);
+#define     GetKeyboardLayoutName WINELIB_NAME_AW(GetKeyboardLayoutName)
 WORD        WINAPI GetKeyState16(INT16);
 WORD        WINAPI GetKeyState32(INT32);
 #define     GetKeyState WINELIB_NAME(GetKeyState)
@@ -8126,7 +8169,7 @@
 BOOL32      WINAPI GetWindowPlacement32(HWND32,LPWINDOWPLACEMENT32);
 #define     GetWindowPlacement WINELIB_NAME(GetWindowPlacement)
 void        WINAPI GetWindowRect16(HWND16,LPRECT16);
-void        WINAPI GetWindowRect32(HWND32,LPRECT32);
+BOOL32      WINAPI GetWindowRect32(HWND32,LPRECT32);
 #define     GetWindowRect WINELIB_NAME(GetWindowRect)
 INT16       WINAPI GetWindowRgn16(HWND16,HRGN16);
 INT32       WINAPI GetWindowRgn32(HWND32,HRGN32);
@@ -8781,6 +8824,9 @@
 INT16       WINAPI SetBkMode16(HDC16,INT16);
 INT32       WINAPI SetBkMode32(HDC32,INT32);
 #define     SetBkMode WINELIB_NAME(SetBkMode)
+UINT16      WINAPI SetBoundsRect16(HDC16,LPRECT16,UINT16);
+UINT32      WINAPI SetBoundsRect32(HDC32,LPRECT32,UINT32);
+#define     SetBoundsRect WINELIB_NAME(SetBoundsRect)
 HWND16      WINAPI SetCapture16(HWND16);
 HWND32      WINAPI SetCapture32(HWND32);
 #define     SetCapture WINELIB_NAME(SetCapture)
diff --git a/include/winerror.h b/include/winerror.h
index 1d368fb..309617c 100644
--- a/include/winerror.h
+++ b/include/winerror.h
@@ -71,6 +71,7 @@
 #define ERROR_NO_NETWORK            1222
 #define ERROR_ALREADY_INITIALIZED   1247
 #define ERROR_PRIVILEGE_NOT_HELD    1314
+#define ERROR_INVALID_WINDOW_HANDLE 1400
 #define ERROR_CANNOT_FIND_WND_CLASS 1407
 #define ERROR_WINDOW_OF_OTHER_THREAD 1408
 #define ERROR_CLASS_ALREADY_EXISTS  1410
diff --git a/include/winnls.h b/include/winnls.h
index 5024998..cecb141 100644
--- a/include/winnls.h
+++ b/include/winnls.h
@@ -194,7 +194,7 @@
 #define SUBLANG_DEFAULT                  0x01    /* user default */
 #define SUBLANG_SYS_DEFAULT              0x02    /* system default */
 
-#define SUBLANG_ARABIC                   0x01
+#define SUBLANG_ARABIC_SAUDI_ARABIA      0x01
 #define SUBLANG_ARABIC_IRAQ              0x02
 #define SUBLANG_ARABIC_EGYPT             0x03
 #define SUBLANG_ARABIC_LIBYA             0x04
@@ -203,18 +203,19 @@
 #define SUBLANG_ARABIC_TUNISIA           0x07
 #define SUBLANG_ARABIC_OMAN              0x08
 #define SUBLANG_ARABIC_YEMEN             0x09
-#define SUBLANG_ARABIC_SYRIA             0x10
-#define SUBLANG_ARABIC_JORDAN            0x11
-#define SUBLANG_ARABIC_LEBANON           0x12
-#define SUBLANG_ARABIC_KUWAIT            0x13
-#define SUBLANG_ARABIC_UAE               0x14
-#define SUBLANG_ARABIC_BAHRAIN           0x15
-#define SUBLANG_ARABIC_QATAR             0x16
+#define SUBLANG_ARABIC_SYRIA             0x0a
+#define SUBLANG_ARABIC_JORDAN            0x0b
+#define SUBLANG_ARABIC_LEBANON           0x0c
+#define SUBLANG_ARABIC_KUWAIT            0x0d
+#define SUBLANG_ARABIC_UAE               0x0e
+#define SUBLANG_ARABIC_BAHRAIN           0x0f
+#define SUBLANG_ARABIC_QATAR             0x10
 #define SUBLANG_CHINESE_TRADITIONAL      0x01
 #define SUBLANG_CHINESE_SIMPLIFIED       0x02
 #define SUBLANG_CHINESE_HONGKONG         0x03
 #define SUBLANG_CHINESE_SINGAPORE        0x04
-#define SUBLANG_DUTCH                    0x01
+#define SUBLANG_CHINESE_MACAU            0x05
+#define SUBLANG_DUTCH_NETHERLANDS        0x01
 #define SUBLANG_DUTCH_BELGIAN            0x02
 #define SUBLANG_ENGLISH_US               0x01
 #define SUBLANG_ENGLISH_UK               0x02
@@ -225,40 +226,49 @@
 #define SUBLANG_ENGLISH_SAFRICA          0x07
 #define SUBLANG_ENGLISH_JAMAICA          0x08
 #define SUBLANG_ENGLISH_CARRIBEAN        0x09
-#define SUBLANG_FRENCH                   0x01
+#define SUBLANG_ENGLISH_BELIZE           0x0a
+#define SUBLANG_ENGLISH_TRINIDAD         0x0b
+#define SUBLANG_ENGLISH_ZIMBABWE         0x0c
+#define SUBLANG_ENGLISH_PHILIPPINES      0x0d
+#define SUBLANG_FRENCH_FRANCE            0x01
 #define SUBLANG_FRENCH_BELGIAN           0x02
 #define SUBLANG_FRENCH_CANADIAN          0x03
 #define SUBLANG_FRENCH_SWISS             0x04
 #define SUBLANG_FRENCH_LUXEMBOURG        0x05
-#define SUBLANG_GERMAN                   0x01
+#define SUBLANG_FRENCH_MONACO            0x06
+#define SUBLANG_GERMAN_GERMANY           0x01
 #define SUBLANG_GERMAN_SWISS             0x02
 #define SUBLANG_GERMAN_AUSTRIAN          0x03
 #define SUBLANG_GERMAN_LUXEMBOURG        0x04
 #define SUBLANG_GERMAN_LIECHTENSTEIN     0x05
-#define SUBLANG_ITALIAN                  0x01
+#define SUBLANG_ITALIAN_ITALIA           0x01
 #define SUBLANG_ITALIAN_SWISS            0x02
-#define SUBLANG_KOREAN                   0x01
+#define SUBLANG_KOREAN_WANSUNG           0x01
 #define SUBLANG_KOREAN_JOHAB             0x02
 #define SUBLANG_NORWEGIAN_BOKMAL         0x01
 #define SUBLANG_NORWEGIAN_NYNORSK        0x02
-#define SUBLANG_PORTUGUESE               0x02
+#define SUBLANG_PORTUGUESE_PORTUGAL      0x02
 #define SUBLANG_PORTUGUESE_BRAZILIAN     0x01
-#define SUBLANG_SPANISH                  0x01
+#define SUBLANG_SPANISH_SPAIN_TRAD       0x01
 #define SUBLANG_SPANISH_MEXICAN          0x02
-#define SUBLANG_SPANISH_MODERN           0x03
+#define SUBLANG_SPANISH_SPAIN_MODERN     0x03
 #define SUBLANG_SPANISH_GUATEMALA        0x04
 #define SUBLANG_SPANISH_COSTARICA        0x05
 #define SUBLANG_SPANISH_PANAMA           0x06
 #define SUBLANG_SPANISH_DOMINICAN        0x07
 #define SUBLANG_SPANISH_VENEZUELA        0x08
 #define SUBLANG_SPANISH_COLOMBIA         0x09
-#define SUBLANG_SPANISH_PERU             0x10
-#define SUBLANG_SPANISH_ARGENTINA        0x11
-#define SUBLANG_SPANISH_ECUADOR          0x12
-#define SUBLANG_SPANISH_CHILE            0x13
-#define SUBLANG_SPANISH_URUGUAY          0x14
-#define SUBLANG_SPANISH_PARAGUAY         0x15
-#define SUBLANG_SPANISH_BOLIVIA          0x16
+#define SUBLANG_SPANISH_PERU             0x0a
+#define SUBLANG_SPANISH_ARGENTINA        0x0b
+#define SUBLANG_SPANISH_ECUADOR          0x0c
+#define SUBLANG_SPANISH_CHILE            0x0d
+#define SUBLANG_SPANISH_URUGUAY          0x0e
+#define SUBLANG_SPANISH_PARAGUAY         0x0f
+#define SUBLANG_SPANISH_BOLIVIA          0x10
+#define SUBLANG_SPANISH_HONDURAS         0x11
+#define SUBLANG_SPANISH_NICARAGUA        0x12
+#define SUBLANG_SPANISH_PUERTO_RICO      0x13
+
 
 /* Sort definitions */
 #define SORT_DEFAULT                     0x0
diff --git a/include/wintypes.h b/include/wintypes.h
index 895676d..e3d4596 100644
--- a/include/wintypes.h
+++ b/include/wintypes.h
@@ -169,10 +169,14 @@
 DECLARE_HANDLE(HWAVEOUT);
 DECLARE_HANDLE(HWND);
 DECLARE_HANDLE(HKL);
+DECLARE_HANDLE(HIC);
 #undef DECLARE_HANDLE
 
 /* Callback function pointers types */
 
+typedef BOOL32 (CALLBACK* DATEFMT_ENUMPROC32A)(LPSTR);
+typedef BOOL32 (CALLBACK* DATEFMT_ENUMPROC32W)(LPWSTR);
+DECL_WINELIB_TYPE_AW(DATEFMT_ENUMPROC)
 typedef LRESULT (CALLBACK *DLGPROC16)(HWND16,UINT16,WPARAM16,LPARAM);
 typedef LRESULT (CALLBACK *DLGPROC32)(HWND32,UINT32,WPARAM32,LPARAM);
 DECL_WINELIB_TYPE(DLGPROC)
@@ -205,6 +209,9 @@
 typedef BOOL32  (CALLBACK *PROPENUMPROCEX32A)(HWND32,LPCSTR,HANDLE32,LPARAM);
 typedef BOOL32  (CALLBACK *PROPENUMPROCEX32W)(HWND32,LPCWSTR,HANDLE32,LPARAM);
 DECL_WINELIB_TYPE_AW(PROPENUMPROCEX)
+typedef BOOL32 (CALLBACK* TIMEFMT_ENUMPROC32A)(LPSTR);
+typedef BOOL32 (CALLBACK* TIMEFMT_ENUMPROC32W)(LPWSTR);
+DECL_WINELIB_TYPE_AW(TIMEFMT_ENUMPROC)
 typedef VOID    (CALLBACK *TIMERPROC16)(HWND16,UINT16,UINT16,DWORD);
 typedef VOID    (CALLBACK *TIMERPROC32)(HWND32,UINT32,UINT32,DWORD);
 DECL_WINELIB_TYPE(TIMERPROC)
diff --git a/include/winversion.h b/include/winversion.h
new file mode 100644
index 0000000..df6047b
--- /dev/null
+++ b/include/winversion.h
@@ -0,0 +1,16 @@
+#ifndef __WINE_WINVERSION_H
+#define __WINE_WINVERSION_H
+
+typedef enum
+{
+    WIN31, /* Windows 3.1 */
+    WIN95,   /* Windows 95 */
+    NT351,   /* Windows NT 3.51 */
+    NT40,    /* Windows NT 4.0 */  
+    NB_WINDOWS_VERSIONS
+} WINDOWS_VERSION;
+
+extern WINDOWS_VERSION VERSION_GetVersion(); 
+extern char *VERSION_GetVersionName(); 
+
+#endif  /* __WINE_WINVERSION_H */
diff --git a/include/wnaspi32.h b/include/wnaspi32.h
new file mode 100644
index 0000000..b62a633
--- /dev/null
+++ b/include/wnaspi32.h
@@ -0,0 +1,96 @@
+#if !defined(WNASPI32_H)
+#define WNASPI32_H
+
+#pragma pack(1)
+
+typedef union SRB32 * LPSRB32;
+
+typedef struct tagSRB_HaInquiry32 {
+ BYTE  SRB_Cmd;                 /* ASPI command code = SC_HA_INQUIRY */
+ BYTE  SRB_Status;              /* ASPI command status byte */
+ BYTE  SRB_HaId;                /* ASPI host adapter number */
+ BYTE  SRB_Flags;               /* ASPI request flags */
+ DWORD  SRB_Hdr_Rsvd;           /* Reserved, MUST = 0 */
+ BYTE  HA_Count;                /* Number of host adapters present */
+ BYTE  HA_SCSI_ID;              /* SCSI ID of host adapter */
+ BYTE  HA_ManagerId[16];        /* String describing the manager */
+ BYTE  HA_Identifier[16];       /* String describing the host adapter */
+ BYTE  HA_Unique[16];           /* Host Adapter Unique parameters */
+ WORD  HA_Rsvd1;
+} SRB_HaInquiry32 WINE_PACKED;
+
+typedef struct tagSRB_ExecSCSICmd32 {
+  BYTE        SRB_Cmd;            /* ASPI command code = SC_EXEC_SCSI_CMD */
+  BYTE        SRB_Status;         /* ASPI command status byte */
+  BYTE        SRB_HaId;           /* ASPI host adapter number */
+  BYTE        SRB_Flags;          /* ASPI request flags */
+  DWORD       SRB_Hdr_Rsvd;       /* Reserved */
+  BYTE        SRB_Target;         /* Target's SCSI ID */
+  BYTE        SRB_Lun;            /* Target's LUN number */
+  WORD        SRB_Rsvd1;          /* Reserved for Alignment */
+  DWORD       SRB_BufLen;         /* Data Allocation Length */
+  BYTE        *SRB_BufPointer;    /* Data Buffer Point */
+  BYTE        SRB_SenseLen;       /* Sense Allocation Length */
+  BYTE        SRB_CDBLen;         /* CDB Length */
+  BYTE        SRB_HaStat;         /* Host Adapter Status */
+  BYTE        SRB_TargStat;       /* Target Status */
+  void        (*SRB_PostProc)();  /* Post routine */
+  void        *SRB_Rsvd2;         /* Reserved */
+  BYTE        SRB_Rsvd3[16];      /* Reserved for expansion */
+  BYTE        CDBByte[16];        /* SCSI CDB */
+  BYTE        SenseArea[0];       /* Request sense buffer - var length */
+} SRB_ExecSCSICmd32 WINE_PACKED;
+
+typedef struct tagSRB_Abort32 {
+  BYTE        SRB_Cmd;            /* ASPI command code = SC_ABORT_SRB */
+  BYTE        SRB_Status;         /* ASPI command status byte */
+  BYTE        SRB_HaId;           /* ASPI host adapter number */
+  BYTE        SRB_Flags;          /* Reserved */
+  DWORD       SRB_Hdr_Rsvd;       /* Reserved, MUST = 0 */
+  LPSRB32     SRB_ToAbort;        /* Pointer to SRB to abort */
+} SRB_Abort32 WINE_PACKED;
+
+typedef struct tagSRB_BusDeviceReset32 {
+ BYTE         SRB_Cmd;                  /* ASPI command code = SC_RESET_DEV */
+ BYTE         SRB_Status;               /* ASPI command status byte */
+ BYTE         SRB_HaId;                 /* ASPI host adapter number */
+ BYTE         SRB_Flags;                /* Reserved */
+ DWORD        SRB_Hdr_Rsvd;             /* Reserved */
+ BYTE         SRB_Target;               /* Target's SCSI ID */
+ BYTE         SRB_Lun;                  /* Target's LUN number */
+ BYTE         SRB_Rsvd1[12];            /* Reserved for Alignment */
+ BYTE         SRB_HaStat;               /* Host Adapter Status */
+ BYTE         SRB_TargStat;             /* Target Status */
+ void         (*SRB_PostProc)();        /* Post routine */
+ void         *SRB_Rsvd2;               /* Reserved */
+ BYTE         SRB_Rsvd3[32];            /* Reserved */
+} SRB_BusDeviceReset32 WINE_PACKED;
+
+typedef struct tagSRB_GDEVBlock32 {
+ BYTE  SRB_Cmd;                 /* ASPI command code = SC_GET_DEV_TYPE */
+ BYTE  SRB_Status;              /* ASPI command status byte */
+ BYTE  SRB_HaId;                /* ASPI host adapter number */
+ BYTE  SRB_Flags;               /* Reserved */
+ DWORD  SRB_Hdr_Rsvd;           /* Reserved */
+ BYTE  SRB_Target;              /* Target's SCSI ID */
+ BYTE  SRB_Lun;                 /* Target's LUN number */
+ BYTE  SRB_DeviceType;          /* Target's peripheral device type */
+ BYTE  SRB_Rsvd1;
+} SRB_GDEVBlock32 WINE_PACKED;
+
+typedef struct tagSRB_Common32 {
+  BYTE  SRB_Cmd;
+} SRB_Common32;
+
+union SRB32 {
+  SRB_Common32          common;
+  SRB_HaInquiry32       inquiry;
+  SRB_ExecSCSICmd32     cmd;
+  SRB_Abort32           abort;
+  SRB_BusDeviceReset32  reset;
+  SRB_GDEVBlock32       devtype;
+};
+
+typedef union SRB32 SRB32;
+
+#endif
diff --git a/loader/dos/Makefile.in b/loader/dos/Makefile.in
index 257425d..20f7f9f 100644
--- a/loader/dos/Makefile.in
+++ b/loader/dos/Makefile.in
@@ -14,7 +14,7 @@
 all: $(MODULE).o $(PROGRAMS)
 
 dosmod: dosmod.c
-	$(CC) $(ALLCFLAGS) -o dosmod dosmod.c
+	$(CC) $(ALLCFLAGS) -o dosmod $(SRCDIR)/dosmod.c
 
 @MAKE_RULES@
 
diff --git a/loader/dos/dosvm.c b/loader/dos/dosvm.c
index 9b4abb8..2223a08 100644
--- a/loader/dos/dosvm.c
+++ b/loader/dos/dosvm.c
@@ -91,8 +91,9 @@
   case VM86_SIGNAL:
    printf("Trapped signal\n");
    ret=-1; break;
-  case VM86_UNKNOWN:
+  case VM86_UNKNOWN: /* unhandled GPF */
    DOSVM_Dump(lpDosTask);
+   ctx_debug(SIGSEGV,&context);
    break;
   case VM86_INTx:
    TRACE(int,"DOS EXE calls INT %02x with AX=%04lx\n",VM86_ARG(lpDosTask->fn),context.Eax);
@@ -102,7 +103,8 @@
   case VM86_PICRETURN:
    printf("Trapped due to pending PIC request\n"); break;
   case VM86_TRAP:
-   printf("Trapped debug request\n"); break;
+   ctx_debug(SIGTRAP,&context);
+   break;
   default:
    DOSVM_Dump(lpDosTask);
  }
diff --git a/loader/dos/module.c b/loader/dos/module.c
index 2494135..c0f7e85 100644
--- a/loader/dos/module.c
+++ b/loader/dos/module.c
@@ -19,12 +19,14 @@
 #include "winbase.h"
 #include "module.h"
 #include "task.h"
+#include "selectors.h"
 #include "file.h"
 #include "ldt.h"
 #include "process.h"
 #include "miscemu.h"
 #include "debug.h"
 #include "dosexe.h"
+#include "options.h"
 
 #ifdef MZ_SUPPORTED
 
@@ -36,35 +38,12 @@
 #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
 #define START_OFFSET 0
 #define PSP_SIZE 0x10
 
 #define SEG16(ptr,seg) ((LPVOID)((BYTE*)ptr+((DWORD)(seg)<<4)))
 #define SEGPTR16(ptr,segptr) ((LPVOID)((BYTE*)ptr+((DWORD)SELECTOROF(segptr)<<4)+OFFSETOF(segptr)))
 
-#define STUB(x) (0x90CF00CD|(x<<8)) /* INT x; IRET; NOP */
-
-static void MZ_InitSystem( LPVOID lpImage )
-{
- SEGPTR*isr=lpImage;
- DWORD*stub=SEG16(lpImage,STUB_SEGMENT);
- int x;
- 
- /* initialize ISR table to make it point to INT stubs in BIOSSEG;
-    Linux only sends INTs performed from or destined to BIOSSEG at us,
-    if the int_revectored table is empty.
-    This allows DOS programs to hook interrupts, as well as use their
-    familiar retf tricks to call them... */
- /* (note that the hooking might not actually work since DOS3Call stuff
-     isn't fully integrated with the DOS VM yet...) */
- TRACE(module,"Initializing interrupt vector table\n");
- for (x=0; x<256; x++) isr[x]=PTR_SEG_OFF_TO_SEGPTR(STUB_SEGMENT,x*4);
- TRACE(module,"Initializing interrupt stub table\n");
- for (x=0; x<256; x++) stub[x]=STUB(x);
-}
-
 static void MZ_InitPSP( LPVOID lpPSP, LPCSTR cmdline, LPCSTR env )
 {
  PDB*psp=lpPSP;
@@ -87,6 +66,36 @@
  /* FIXME: integrate the PDB stuff from Wine (loader/task.c) */
 }
 
+static char enter_pm[]={
+ 0x50,           /* pushw %ax */
+ 0x52,           /* pushw %dx */
+ 0x55,           /* pushw %bp */
+ 0x89,0xE5,      /* movw %sp,%bp */
+/* get return CS */
+ 0x8B,0x56,0x08, /* movw 8(%bp),%dx */
+/* just call int 31 here to get into protected mode... */
+/* it'll check whether it was called from dpmi_seg... */
+ 0xCD,0x31,      /* int 0x31 */
+/* fixup our stack; return address will be lost, but we won't worry quite yet */
+ 0x8E,0xD0,      /* movw %ax,%ss */
+ 0x89,0xEC,      /* movw %bp,%sp */
+/* set return CS */
+ 0x89,0x56,0x08, /* movw %dx,8(%bp) */
+ 0x5D,           /* popw %bp */
+ 0x5A,           /* popw %dx */
+ 0x58,           /* popw %ax */
+ 0xCB            /* retf */
+};
+
+static void MZ_InitDPMI( LPDOSTASK lpDosTask )
+{
+ LPBYTE start=DOSMEM_GetBlock(lpDosTask->hModule,sizeof(enter_pm),&(lpDosTask->dpmi_seg));
+ 
+ lpDosTask->dpmi_sel = SELECTOR_AllocBlock( start, sizeof(enter_pm), SEGMENT_CODE, FALSE, TRUE );
+
+ memcpy(start,enter_pm,sizeof(enter_pm));
+}
+
 int MZ_InitMemory( LPDOSTASK lpDosTask, NE_MODULE *pModule )
 {
  int x;
@@ -118,10 +127,9 @@
  pModule->dos_image=lpDosTask->img;
 
  /* initialize the memory */
- MZ_InitSystem(lpDosTask->img);
  TRACE(module,"Initializing DOS memory structures\n");
- /* FIXME: make DOSMEM_Init copy static dosmem memory into newly allocated shared memory */
  DOSMEM_Init(lpDosTask->hModule);
+ MZ_InitDPMI(lpDosTask);
  return 32;
 }
 
@@ -195,7 +203,18 @@
   }
  }
 
+ /* initialize module variables */
+ pModule->cs=lpDosTask->load_seg+mz_header.e_cs;
+ pModule->ip=mz_header.e_ip;
+ pModule->ss=lpDosTask->load_seg+mz_header.e_ss;
+ pModule->sp=mz_header.e_sp;
+ pModule->self_loading_sel=lpDosTask->psp_seg;
+
+ TRACE(module,"entry point: %04x:%04x\n",pModule->cs,pModule->ip);
+
  /* initialize vm86 struct */
+ /* note: this may be moved soon, to be able to remove VM86 from lpDosTask
+    (got tired of all those compiler warnings, and don't like the system dependency) */
  memset(&lpDosTask->VM86,0,sizeof(lpDosTask->VM86));
  lpDosTask->VM86.regs.cs=lpDosTask->load_seg+mz_header.e_cs;
  lpDosTask->VM86.regs.eip=mz_header.e_ip;
@@ -210,7 +229,6 @@
 
 int MZ_InitTask( LPDOSTASK lpDosTask )
 {
- extern char * DEBUG_argv0;
  int read_fd[2],write_fd[2];
  pid_t child;
  char *fname,*farg,arg[16],fproc[64],path[256],*fpath;
@@ -250,9 +268,13 @@
     if ((errno==EINTR)||(errno==EAGAIN)) continue;
     /* failure */
     ERR(module,"dosmod has failed to initialize\n");
+    if (lpDosTask->mm_name[0]!=0) unlink(lpDosTask->mm_name);
     return 0;
    }
   } while (0);
+  /* the child has now mmaped the temp file, it's now safe to unlink.
+   * do it here to avoid leaving a mess in /tmp if/when Wine crashes... */
+  if (lpDosTask->mm_name[0]!=0) unlink(lpDosTask->mm_name);
   /* all systems are now go */
  } else {
   /* child process */
@@ -266,7 +288,7 @@
   /* hmm, they didn't install properly */
   execl("loader/dos/dosmod",fname,farg,NULL);
   /* last resort, try to find it through argv[0] */
-  fpath=strrchr(strcpy(path,DEBUG_argv0),'/');
+  fpath=strrchr(strcpy(path,Options.argv0),'/');
   if (fpath) {
    strcpy(fpath,"/loader/dos/dosmod");
    execl(path,fname,farg,NULL);
@@ -323,11 +345,6 @@
    return err;
   }
   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 */
@@ -351,6 +368,8 @@
  close(lpDosTask->read_pipe);
  close(lpDosTask->write_pipe);
  kill(lpDosTask->task,SIGTERM);
+ if (lpDosTask->dpmi_sel)
+  UnMapLS(PTR_SEG_OFF_TO_SEGPTR(lpDosTask->dpmi_sel,0));
 }
 
 int MZ_RunModule( LPDOSTASK lpDosTask )
diff --git a/loader/module.c b/loader/module.c
index 1bbe11a..1a4764a 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -456,12 +456,35 @@
 
     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);
+    else {
+        char	*ptr;
+        int	len;
+
+	/* Take care off .exes with spaces in their names */
+	ptr = strchr(lpCommandLine, ' ');
+	do {
+	    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");
+	    fprintf(stderr,"looking for: %s\n",name);
+	    if (GetFileAttributes32A(name)!=-1)
+	    	break;
+	    /* if there is a space and no file found yet, include the word
+	     * up to the next space too. If there is no next space, just
+	     * use the first word.
+	     */
+	    if (ptr) {
+	    	ptr = strchr(ptr+1, ' ');
+	    } else {
+	        ptr = strchr(lpCommandLine, ' ');
+		len = (ptr? ptr-lpCommandLine : strlen(lpCommandLine)) + 1;
+		if (len > sizeof(name) - 4) len = sizeof(name) - 4;
+		lstrcpyn32A(name, lpCommandLine, len);
+		break;
+	    }
+	} while (1);
     }
 
     if (!strchr(name, '\\') && !strchr(name, '.'))
@@ -613,14 +636,22 @@
         DWORD size		/* [in] size of filenamebuffer */
 ) {                   
     WINE_MODREF *wm = MODULE32_LookupHMODULE(PROCESS_Current(),hModule);
+    char *p;
 
     if (!wm) /* can happen on start up or the like */
     	return 0;
 
     /* FIXME: we should probably get a real long name, but wm->longname
      * is currently a UNIX filename!
+     * Use the module name to at least get the long version of the filename.
      */
     lstrcpyn32A( lpFileName, wm->shortname, size );
+    if ( (p = strrchr( lpFileName, '\\' )) ) {
+      p++;
+      size -= (p-lpFileName);
+      lstrcpyn32A( p, wm->modname, size);
+    }
+       
     TRACE(module, "%s\n", lpFileName );
     return strlen(lpFileName);
 }                   
@@ -704,7 +735,7 @@
  */
 BOOL32 WINAPI FreeLibrary32(HINSTANCE32 hLibModule)
 {
-    FIXME(module,"(%08x): stub\n", hLibModule);
+    FIXME(module,"(0x%08x): stub\n", hLibModule);
     return TRUE;  /* FIXME */
 }
 
@@ -1008,3 +1039,44 @@
     if (!wm || (wm->type != MODULE32_PE)) return (LPIMAGE_NT_HEADERS)0;
     return PE_HEADER(wm->module);
 }
+
+
+/***************************************************************************
+ *              HasGPHandler                    (KERNEL.338)
+ */
+
+#pragma pack(1)
+typedef struct _GPHANDLERDEF
+{
+    WORD selector;
+    WORD rangeStart;
+    WORD rangeEnd;
+    WORD handler;
+} GPHANDLERDEF;
+#pragma pack(4)
+
+SEGPTR WINAPI HasGPHandler( SEGPTR address )
+{
+    HMODULE16 hModule;
+    SEGPTR gpPtr;
+    GPHANDLERDEF *gpHandler;
+   
+    if (    (hModule = FarGetOwner( SELECTOROF(address) )) != 0
+         && (gpPtr = (SEGPTR)WIN32_GetProcAddress16( hModule, "__GP" )) != 0
+         && !IsBadReadPtr16( gpPtr, sizeof(GPHANDLERDEF) )
+         && (gpHandler = PTR_SEG_TO_LIN( gpPtr )) != NULL )
+    {
+        while (gpHandler->selector)
+        {
+            if (    SELECTOROF(address) == gpHandler->selector
+                 && OFFSETOF(address)   >= gpHandler->rangeStart
+                 && OFFSETOF(address)   <  gpHandler->rangeEnd  )
+                return PTR_SEG_OFF_TO_SEGPTR( gpHandler->selector,
+                                              gpHandler->handler );
+            gpHandler++;
+        }
+    }
+
+    return 0;
+}
+
diff --git a/loader/ne/module.c b/loader/ne/module.c
index fb3b168..3e193ac 100644
--- a/loader/ne/module.c
+++ b/loader/ne/module.c
@@ -83,9 +83,9 @@
     DUMP( "Segment table:\n" );
     pSeg = NE_SEG_TABLE( pModule );
     for (i = 0; i < pModule->seg_count; i++, pSeg++)
-        DUMP( "%02x: pos=%d size=%d flags=%04x minsize=%d sel=%04x\n",
+        DUMP( "%02x: pos=%d size=%d flags=%04x minsize=%d hSeg=%04x\n",
 	      i + 1, pSeg->filepos, pSeg->size, pSeg->flags,
-	      pSeg->minsize, pSeg->selector );
+	      pSeg->minsize, pSeg->hSeg );
 
       /* Dump the resource table */
     DUMP( "---\n" );
@@ -332,7 +332,7 @@
     }
 
     if (sel == 0xfe) sel = 0xffff;  /* constant entry */
-    else sel = (WORD)(DWORD)NE_SEG_TABLE(pModule)[sel-1].selector;
+    else sel = GlobalHandleToSel(NE_SEG_TABLE(pModule)[sel-1].hSeg);
     if (sel==0xffff)
 	return (FARPROC16)PTR_SEG_OFF_TO_SEGPTR( sel, offset );
     if (!fnSNOOP16_GetProcAddress16)
@@ -1170,3 +1170,17 @@
 REGS_ENTRYPOINT(MapHInstSL) {
 	EAX_reg(context) = MapHModuleSL(EAX_reg(context));
 }
+
+/***************************************************************************
+ *		WIN16_MapHInstLS		(KERNEL.472)
+ */
+VOID WINAPI WIN16_MapHInstLS( CONTEXT *context ) {
+	EAX_reg(context) = MapHModuleLS(EAX_reg(context));
+}
+
+/***************************************************************************
+ *		WIN16_MapHInstSL		(KERNEL.473)
+ */
+VOID WINAPI WIN16_MapHInstSL( CONTEXT *context ) {
+	EAX_reg(context) = MapHModuleSL(EAX_reg(context));
+}
diff --git a/loader/ne/segment.c b/loader/ne/segment.c
index 8215c30..31c8522 100644
--- a/loader/ne/segment.c
+++ b/loader/ne/segment.c
@@ -27,6 +27,7 @@
 #include "debug.h"
 #include "xmalloc.h"
 
+#define SEL(x) GlobalHandleToSel(x)
 
 /***********************************************************************
  *           NE_GetRelocAddrName
@@ -73,27 +74,27 @@
     if (!pSeg->filepos) return TRUE;  /* No file image, just return */
 	
     fd = NE_OpenFile( pModule );
-    TRACE(module, "Loading segment %d, selector=%04x, flags=%04x\n",
-                    segnum, pSeg->selector, pSeg->flags );
+    TRACE(module, "Loading segment %d, hSeg=%04x, flags=%04x\n",
+                    segnum, pSeg->hSeg, pSeg->flags );
     lseek( fd, pSeg->filepos << pModule->alignment, SEEK_SET );
     if (pSeg->size) size = pSeg->size;
     else if (pSeg->minsize) size = pSeg->minsize;
     else size = 0x10000;
-    mem = GlobalLock16(pSeg->selector);
+    mem = GlobalLock16(pSeg->hSeg);
     if (pModule->flags & NE_FFLAGS_SELFLOAD && segnum > 1)
     {
  	/* Implement self loading segments */
  	SELFLOADHEADER *selfloadheader;
         STACK16FRAME *stack16Top;
         DWORD oldstack;
- 	WORD oldselector, newselector;
+ 	WORD old_hSeg, new_hSeg;
         THDB *thdb = THREAD_Current();
         HFILE32 hf = FILE_DupUnixHandle( fd );
 
  	selfloadheader = (SELFLOADHEADER *)
- 		PTR_SEG_OFF_TO_LIN(pSegTable->selector,0);
+ 		PTR_SEG_OFF_TO_LIN(SEL(pSegTable->hSeg),0);
  	oldstack = thdb->cur_stack;
- 	oldselector = pSeg->selector;
+ 	old_hSeg = pSeg->hSeg;
  	thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR(pModule->self_loading_sel,
                                                  0xff00 - sizeof(*stack16Top));
         stack16Top = (STACK16FRAME *)PTR_SEG_TO_LIN(thdb->cur_stack);
@@ -107,27 +108,27 @@
         stack16Top->cs = 0;
 	TRACE(dll,"CallLoadAppSegProc(hmodule=0x%04x,hf=0x%04x,segnum=%d\n",
 		pModule->self,hf,segnum );
- 	newselector = Callbacks->CallLoadAppSegProc(selfloadheader->LoadAppSeg,
+ 	new_hSeg = Callbacks->CallLoadAppSegProc(selfloadheader->LoadAppSeg,
                                                     pModule->self,
                                                     HFILE32_TO_HFILE16(hf),
                                                     segnum );
-	TRACE(dll,"Ret CallLoadAppSegProc: selector = 0x%04x\n",newselector);
+	TRACE(dll,"Ret CallLoadAppSegProc: hSeg = 0x%04x\n",new_hSeg);
         _lclose32( hf );
- 	if (newselector != oldselector) {
+ 	if (SEL(new_hSeg) != SEL(old_hSeg)) {
  	  /* Self loaders like creating their own selectors; 
  	   * they love asking for trouble to Wine developers
  	   */
  	  if (segnum == pModule->dgroup) {
- 	    memcpy(PTR_SEG_OFF_TO_LIN(oldselector,0),
- 		   PTR_SEG_OFF_TO_LIN(newselector,0), 
+ 	    memcpy(PTR_SEG_OFF_TO_LIN(SEL(old_hSeg),0),
+ 		   PTR_SEG_OFF_TO_LIN(SEL(new_hSeg),0), 
  		   pSeg->minsize ? pSeg->minsize : 0x10000);
- 	    FreeSelector(newselector);
- 	    pSeg->selector = oldselector;
- 	    TRACE(module, "New selector allocated for dgroup segment:Old=%d,New=%d\n", 
-                oldselector, newselector);
+ 	    FreeSelector(SEL(new_hSeg));
+ 	    pSeg->hSeg = old_hSeg;
+ 	    TRACE(module, "New hSeg allocated for dgroup segment:Old=%d,New=%d\n", 
+                old_hSeg, new_hSeg);
  	  } else {
- 	    FreeSelector(pSeg->selector);
- 	    pSeg->selector = newselector;
+ 	    FreeSelector(SEL(pSeg->hSeg));
+ 	    pSeg->hSeg = new_hSeg;
  	  }
  	} 
  	
@@ -166,14 +167,14 @@
     read( fd, &count, sizeof(count) );
     if (!count) return TRUE;
 
-    TRACE(fixup, "Fixups for %.*s, segment %d, selector %04x\n",
+    TRACE(fixup, "Fixups for %.*s, segment %d, hSeg %04x\n",
                    *((BYTE *)pModule + pModule->name_table),
                    (char *)pModule + pModule->name_table + 1,
-                   segnum, pSeg->selector );
-    TRACE(segment, "Fixups for %.*s, segment %d, selector %04x\n",
+                   segnum, pSeg->hSeg );
+    TRACE(segment, "Fixups for %.*s, segment %d, hSeg %04x\n",
                    *((BYTE *)pModule + pModule->name_table),
                    (char *)pModule + pModule->name_table + 1,
-                   segnum, pSeg->selector );
+                   segnum, pSeg->hSeg );
 
     reloc_entries = (struct relocation_entry_s *)xmalloc(count * sizeof(struct relocation_entry_s));
     if (read( fd, reloc_entries, count * sizeof(struct relocation_entry_s)) !=
@@ -268,7 +269,7 @@
 	    }
 	    else
 	    {
-                address = (FARPROC16)PTR_SEG_OFF_TO_SEGPTR( pSegTable[rep->target1-1].selector, rep->target2 );
+                address = (FARPROC16)PTR_SEG_OFF_TO_SEGPTR( SEL(pSegTable[rep->target1-1].hSeg), rep->target2 );
 	    }
 	    
 	    TRACE( fixup,"%d: %04x:%04x %s\n", 
@@ -306,7 +307,7 @@
 
         if (additive)
         {
-            sp = PTR_SEG_OFF_TO_LIN( pSeg->selector, offset );
+            sp = PTR_SEG_OFF_TO_LIN( SEL(pSeg->hSeg), offset );
             TRACE( fixup,"    %04x:%04x\n", offset, *sp );
             switch (rep->address_type & 0x7f)
             {
@@ -335,7 +336,7 @@
         {
             do
             {
-                sp = PTR_SEG_OFF_TO_LIN( pSeg->selector, offset );
+                sp = PTR_SEG_OFF_TO_LIN( SEL(pSeg->hSeg), offset );
                 next_offset = *sp;
                 TRACE( fixup,"    %04x:%04x\n", offset, *sp );
                 switch (rep->address_type & 0x7f)
@@ -356,7 +357,7 @@
                     goto unknown;
                 }
                 if (next_offset == offset) break;  /* avoid infinite loop */
-                if (next_offset >= GlobalSize16(pSeg->selector)) break;
+                if (next_offset >= GlobalSize16(pSeg->hSeg)) break;
                 offset = next_offset;
             } while (offset != 0xffff);
         }
@@ -392,14 +393,14 @@
         THDB *thdb = THREAD_Current();
         HMODULE16 hselfload = GetModuleHandle16("WPROCS");
         DWORD oldstack;
-        WORD saved_dgroup = pSegTable[pModule->dgroup - 1].selector;
+        WORD saved_hSeg = pSegTable[pModule->dgroup - 1].hSeg;
 
         TRACE(module, "%.*s is a self-loading module!\n",
 		     *((BYTE*)pModule + pModule->name_table),
 		     (char *)pModule + pModule->name_table + 1);
         if (!NE_LoadSegment( pModule, 1 )) return FALSE;
         selfloadheader = (SELFLOADHEADER *)
-                          PTR_SEG_OFF_TO_LIN(pSegTable->selector, 0);
+                          PTR_SEG_OFF_TO_LIN(SEL(pSegTable->hSeg), 0);
         selfloadheader->EntryAddrProc = NE_GetEntryPoint(hselfload,27);
         selfloadheader->MyAlloc  = NE_GetEntryPoint(hselfload,28);
         selfloadheader->SetOwner = NE_GetEntryPoint(GetModuleHandle16("KERNEL"),403);
@@ -425,8 +426,8 @@
                                    HFILE32_TO_HFILE16(hf));
 	TRACE(dll,"Return from CallBootAppProc\n");
         _lclose32(hf);
-        /* some BootApp procs overwrite the selector of dgroup */
-        pSegTable[pModule->dgroup - 1].selector = saved_dgroup;
+        /* some BootApp procs overwrite the segment handle of dgroup */
+        pSegTable[pModule->dgroup - 1].hSeg = saved_hSeg;
         thdb->cur_stack = oldstack;
 
 	/* FIXME
@@ -460,7 +461,7 @@
 
     pSegTable = NE_SEG_TABLE(pModule);
     if (pModule->flags & NE_FFLAGS_SINGLEDATA)
-        dgroup = pSegTable[pModule->dgroup-1].selector;
+        dgroup = SEL(pSegTable[pModule->dgroup-1].hSeg);
 
     TRACE(module, "(%04x)\n", pModule->self );
     p = (BYTE *)pModule + pModule->entry_table;
@@ -491,10 +492,10 @@
 	     */
 	    if (sel == 0xff) { /* moveable */
 		dsprintf(module, "(%02x) o %04x", p[3], *(WORD *)(p+4) );
-		fixup_ptr = (char *)GET_SEL_BASE(pSegTable[p[3]-1].selector) + *(WORD *)(p + 4);
+		fixup_ptr = (char *)GET_SEL_BASE(SEL(pSegTable[p[3]-1].hSeg)) + *(WORD *)(p + 4);
 	    } else { /* fixed */
 		dsprintf(module, "offset %04x", *(WORD *)(p+1) );
-		fixup_ptr = (char *)GET_SEL_BASE(pSegTable[sel-1].selector) + 
+		fixup_ptr = (char *)GET_SEL_BASE(SEL(pSegTable[sel-1].hSeg)) + 
 		  *(WORD *)(p + 1);
 	    }
 	    TRACE(module, "%s Signature: %02x %02x %02x,ff %x\n",
@@ -564,7 +565,7 @@
     else  /* DATA SINGLE DLL */
     {
 	if (pModule->dgroup) {
-            *ds   = pSegTable[pModule->dgroup-1].selector;
+            *ds   = SEL(pSegTable[pModule->dgroup-1].hSeg);
             *heap = pModule->heap_size;
 	}
 	else /* hmm, DLL has no dgroup,
@@ -625,7 +626,7 @@
     DS_reg(&context)  = ds;
     ES_reg(&context)  = ds;   /* who knows ... */
 
-    CS_reg(&context)  = pSegTable[pModule->cs-1].selector;
+    CS_reg(&context)  = SEL(pSegTable[pModule->cs-1].hSeg);
     EIP_reg(&context) = pModule->ip;
     EBP_reg(&context) = OFFSETOF(THREAD_Current()->cur_stack)
                           + (WORD)&((STACK16FRAME*)0)->bp;
@@ -733,13 +734,13 @@
     }
 
     pSegment = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
-    if (prev) *prev = pSegment->selector;
+    if (prev) *prev = SEL(pSegment->hSeg);
 
       /* if it's a library, create a new instance only the first time */
-    if (pSegment->selector)
+    if (pSegment->hSeg)
     {
-        if (pModule->flags & NE_FFLAGS_LIBMODULE) return pSegment->selector;
-        if (lib_only) return pSegment->selector;
+        if (pModule->flags & NE_FFLAGS_LIBMODULE) return SEL(pSegment->hSeg);
+        if (lib_only) return SEL(pSegment->hSeg);
     }
 
     minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
@@ -748,7 +749,7 @@
     hNewInstance = GLOBAL_Alloc( GMEM_ZEROINIT | GMEM_FIXED, minsize,
                                  pModule->self, FALSE, FALSE, FALSE );
     if (!hNewInstance) return 0;
-    pSegment->selector = hNewInstance;
+    pSegment->hSeg = hNewInstance;
     pSegment->flags |= NE_SEGFLAGS_ALLOCATED;
     return hNewInstance;
 }
@@ -775,7 +776,7 @@
 static WORD NE_Ne2MemFlags(WORD flags)
 { 
     WORD memflags = 0;
-#if 0
+#if 1
     if (flags & NE_SEGFLAGS_DISCARDABLE) 
       memflags |= GMEM_DISCARDABLE;
     if (flags & NE_SEGFLAGS_MOVEABLE || 
@@ -788,8 +789,8 @@
     memflags |= GMEM_ZEROINIT;
 #else
     memflags = GMEM_ZEROINIT | GMEM_FIXED;
-    return memflags;
 #endif
+    return memflags;
 }
 
 /***********************************************************************
@@ -820,12 +821,12 @@
         if (i == pModule->ss) minsize += pModule->stack_size;
 	/* The DGROUP is allocated by NE_CreateInstance */
         if (i == pModule->dgroup) continue;
-        pSegment->selector = GLOBAL_Alloc( NE_Ne2MemFlags(pSegment->flags),
+        pSegment->hSeg = GLOBAL_Alloc( NE_Ne2MemFlags(pSegment->flags),
                                       minsize, pModule->self,
                                       !(pSegment->flags & NE_SEGFLAGS_DATA),
                                       FALSE,
                             FALSE /*pSegment->flags & NE_SEGFLAGS_READONLY*/ );
-        if (!pSegment->selector) return FALSE;
+        if (!pSegment->hSeg) return FALSE;
 	pSegment->flags |= NE_SEGFLAGS_ALLOCATED;
     }
 
diff --git a/loader/pe_image.c b/loader/pe_image.c
index dd26b2b..942e5a3 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -474,8 +474,12 @@
  */
 static HMODULE32 PE_LoadImage( HFILE32 hFile )
 {
-    HMODULE32 hModule;
-    HANDLE32 mapping;
+    HMODULE32	hModule;
+    HANDLE32	mapping;
+    int		i,rawsize = 0;
+    IMAGE_SECTION_HEADER	*pe_sec;
+    BY_HANDLE_FILE_INFORMATION	bhfi;
+
 
     /* map the PE file somewhere */
     mapping = CreateFileMapping32A( hFile, NULL, PAGE_READONLY | SEC_COMMIT,
@@ -519,6 +523,24 @@
         }
         goto error;
     }
+    /* find out how large this executeable should be */
+    pe_sec = PE_SECTIONS(hModule);
+    for (i=0;i<PE_HEADER(hModule)->FileHeader.NumberOfSections;i++) {
+    	if (pe_sec[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
+	    continue;
+	if (pe_sec[i].PointerToRawData+pe_sec[i].SizeOfRawData > rawsize)
+	    rawsize = pe_sec[i].PointerToRawData+pe_sec[i].SizeOfRawData;
+    }
+    if (GetFileInformationByHandle(hFile,&bhfi)) {
+    	/* FIXME: 64 bit */
+    	if (bhfi.nFileSizeLow < rawsize) {
+	    ERR(win32,"PE module is too small (header: %d, filesize: %d), probably truncated download?\n",rawsize,bhfi.nFileSizeLow);
+	    goto error;
+	}
+    }
+    /* Else ... Hmm, we have opened it, so we should be able to get info?
+     * Anyway, don't care in this case
+     */
     return hModule;
 
 error:
diff --git a/loader/resource.c b/loader/resource.c
index 6d11b55..a873076 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -34,13 +34,13 @@
  */
 HANDLE32 WINAPI FindResource32A( HMODULE32 hModule, LPCSTR name, LPCSTR type)
 {
-    return FindResourceEx32A(hModule,name,type,WINE_LanguageId);
+    return FindResourceEx32A(hModule,type,name,WINE_LanguageId);
 }
 
 /**********************************************************************
  *	    FindResourceEx32A    (KERNEL32.129)
  */
-HANDLE32 WINAPI FindResourceEx32A( HMODULE32 hModule, LPCSTR name, LPCSTR type,
+HANDLE32 WINAPI FindResourceEx32A( HMODULE32 hModule, LPCSTR type, LPCSTR name,
 				   WORD lang
 ) {
     LPWSTR xname,xtype;
@@ -54,7 +54,7 @@
         xtype = HEAP_strdupAtoW( GetProcessHeap(), 0, type);
     else
         xtype = (LPWSTR)type;
-    ret = FindResourceEx32W( hModule, xname, xtype, lang );
+    ret = FindResourceEx32W( hModule, xtype, xname, lang );
     if (HIWORD((DWORD)name)) HeapFree( GetProcessHeap(), 0, xname );
     if (HIWORD((DWORD)type)) HeapFree( GetProcessHeap(), 0, xtype );
     return ret;
@@ -64,14 +64,14 @@
 /**********************************************************************
  *	    FindResourceEx32W    (KERNEL32.130)
  */
-HRSRC32 WINAPI FindResourceEx32W( HMODULE32 hModule, LPCWSTR name,
-                                  LPCWSTR type, WORD lang )
+HRSRC32 WINAPI FindResourceEx32W( HMODULE32 hModule, LPCWSTR type,
+                                  LPCWSTR name, WORD lang )
 {	HRSRC32 ret;
     WINE_MODREF	*wm = MODULE32_LookupHMODULE(PROCESS_Current(),hModule);
     HRSRC32	hrsrc;
 
-    TRACE(resource, "module=%08x type=%s name=%s\n",
-	  hModule,
+    TRACE(resource, "module=%08x(%s) type=%s name=%s\n",
+	  hModule, wm->modname,
 	  debugres_w (type),
 	  debugres_w (name));
 
@@ -85,7 +85,7 @@
 	case MODULE32_PE:
 	    ret =  PE_FindResourceEx32W(wm,name,type,lang);
         if ( ret==0 )
-          ERR(resource,"(0x%08lx(%s),%s not found!\n",hModule,wm->modname,debugres_w (name));
+          ERR(resource,"(0x%08x(%s),%s not found!\n",hModule,wm->modname,debugres_w (name));
 	    return ret;
 	default:
 	    ERR(module,"unknown module type %d\n",wm->type);
@@ -101,7 +101,7 @@
  */
 HRSRC32 WINAPI FindResource32W(HINSTANCE32 hModule, LPCWSTR name, LPCWSTR type)
 {
-    return FindResourceEx32W(hModule,name,type,WINE_LanguageId);
+    return FindResourceEx32W(hModule,type,name,WINE_LanguageId);
 }
 
 
@@ -457,7 +457,7 @@
     }
     FreeResource16( hmem );
 
-    TRACE(resource,"'%s' copied !\n", buffer);
+    TRACE(resource,"'%s' loaded !\n", buffer);
     return i;
 }
 
@@ -507,7 +507,7 @@
 #endif
     }
 
-    TRACE(resource,"'%s' copied !\n", (char *)buffer);
+    TRACE(resource,"%s loaded !\n", debugstr_w(buffer));
     return i;
 }
 
@@ -582,7 +582,7 @@
     TRACE(resource, "instance = %08lx, id = %08lx, buffer = %p, length = %ld\n", (DWORD)instance, (DWORD)id, buffer, (DWORD)buflen);
 
     /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/
-    hrsrc = FindResourceEx32W(instance,(LPWSTR)1,RT_MESSAGELIST32W,lang);
+    hrsrc = FindResourceEx32W(instance,RT_MESSAGELIST32W,(LPWSTR)1,lang);
     if (!hrsrc) return 0;
     hmem = LoadResource32( instance, hrsrc );
     if (!hmem) return 0;
diff --git a/loader/task.c b/loader/task.c
index df06353..e55207e 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -290,8 +290,8 @@
         CONTEXT context;
 
         memset( &context, 0, sizeof(context) );
-        CS_reg(&context)  = pSegTable[pModule->cs - 1].selector;
-        DS_reg(&context)  = pSegTable[pModule->dgroup - 1].selector;
+        CS_reg(&context)  = GlobalHandleToSel(pSegTable[pModule->cs - 1].hSeg);
+        DS_reg(&context)  = GlobalHandleToSel(pSegTable[pModule->dgroup - 1].hSeg);
         ES_reg(&context)  = pTask->hPDB;
         EIP_reg(&context) = pModule->ip;
         EBX_reg(&context) = pModule->stack_size;
@@ -383,9 +383,9 @@
     pTask->pdb.dispatcher[0] = 0x9a;  /* ljmp */
     PUT_DWORD(&pTask->pdb.dispatcher[1], (DWORD)NE_GetEntryPoint(
            GetModuleHandle16("KERNEL"), 102 ));  /* KERNEL.102 is DOS3Call() */
-    pTask->pdb.savedint22 = INT_GetHandler( 0x22 );
-    pTask->pdb.savedint23 = INT_GetHandler( 0x23 );
-    pTask->pdb.savedint24 = INT_GetHandler( 0x24 );
+    pTask->pdb.savedint22 = INT_GetPMHandler( 0x22 );
+    pTask->pdb.savedint23 = INT_GetPMHandler( 0x23 );
+    pTask->pdb.savedint24 = INT_GetPMHandler( 0x24 );
     pTask->pdb.fileHandlesPtr =
         PTR_SEG_OFF_TO_SEGPTR( GlobalHandleToSel(pTask->hPDB),
                                (int)&((PDB *)0)->fileHandles );
@@ -1091,6 +1091,53 @@
     return handle;
 }
 
+/**********************************************************************
+ *	    GetCodeInfo    (KERNEL.104)
+ */
+VOID WINAPI GetCodeInfo( FARPROC16 proc, SEGINFO *segInfo )
+{
+    BYTE *thunk = (BYTE *)PTR_SEG_TO_LIN( proc );
+    NE_MODULE *pModule = NULL;
+    SEGTABLEENTRY *pSeg = NULL;
+    WORD segNr;
+
+    /* proc is either a thunk, or else a pair of module handle
+       and segment number. In the first case, we also need to
+       extract module and segment number. */
+
+    if ((thunk[0] == 0xb8) && (thunk[3] == 0xea))
+    {
+        WORD selector = thunk[6] + (thunk[7] << 8);
+        pModule = NE_GetPtr( GlobalHandle16( selector ) );
+        pSeg = pModule? NE_SEG_TABLE( pModule ) : NULL;
+
+        if ( pModule )
+            for ( segNr = 0; segNr < pModule->seg_count; segNr++, pSeg++ )
+                if ( GlobalHandleToSel(pSeg->hSeg) == selector )
+                    break;
+
+        if ( pModule && segNr >= pModule->seg_count )
+            pSeg = NULL;
+    }
+    else
+    {
+        pModule = NE_GetPtr( HIWORD( proc ) );
+        segNr   = LOWORD( proc );
+
+        if ( pModule && segNr < pModule->seg_count )
+            pSeg = NE_SEG_TABLE( pModule ) + segNr;
+    }
+
+    /* fill in segment information */
+
+    segInfo->offSegment = pSeg? pSeg->filepos : 0;
+    segInfo->cbSegment  = pSeg? pSeg->size : 0;
+    segInfo->flags      = pSeg? pSeg->flags : 0;
+    segInfo->cbAlloc    = pSeg? pSeg->minsize : 0;
+    segInfo->h          = pSeg? pSeg->hSeg : 0;
+    segInfo->alignShift = pModule? pModule->alignment : 0;
+}
+
 
 /**********************************************************************
  *          DefineHandleTable16    (KERNEL.94)
@@ -1133,6 +1180,56 @@
     return pTask->hQueue;
 }
 
+/***********************************************************************
+ *           SetThreadQueue  (KERNEL.463)
+ */
+HQUEUE16 WINAPI SetThreadQueue( DWORD thread, HQUEUE16 hQueue )
+{
+    THDB *thdb = THREAD_IdToTHDB( thread );
+    HQUEUE16 oldQueue = thdb? thdb->teb.queue : 0;
+
+    if ( thdb )
+    {
+        thdb->teb.queue = hQueue;
+
+        if ( GetTaskQueue( thdb->process->task ) == oldQueue )
+            SetTaskQueue( thdb->process->task, hQueue );
+    }
+
+    return oldQueue;
+}
+
+/***********************************************************************
+ *           GetThreadQueue  (KERNEL.464)
+ */
+HQUEUE16 WINAPI GetThreadQueue( DWORD thread )
+{
+    THDB *thdb = THREAD_IdToTHDB( thread );
+    return (HQUEUE16)(thdb? thdb->teb.queue : 0);
+}
+
+/***********************************************************************
+ *           SetFastQueue  (KERNEL.624)
+ */
+VOID WINAPI SetFastQueue( DWORD thread, HANDLE32 hQueue )
+{
+    THDB *thdb = THREAD_IdToTHDB( thread );
+    if ( thdb ) thdb->teb.queue = (HQUEUE16) hQueue;
+}
+
+/***********************************************************************
+ *           GetFastQueue  (KERNEL.625)
+ */
+HANDLE32 WINAPI GetFastQueue( void )
+{
+    THDB *thdb = THREAD_Current();
+    if (!thdb) return 0;
+
+    if (!(thdb->teb.queue))
+        FIXME( task, "(): should initialize thread-local queue, expect failure!\n" );
+
+    return (HANDLE32)thdb->teb.queue;
+}
 
 /***********************************************************************
  *           SwitchStackTo   (KERNEL.108)
diff --git a/memory/global.c b/memory/global.c
index fd8bb5b..799eb9f 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -3,6 +3,7 @@
  *
  * Copyright 1995 Alexandre Julliard
  */
+/* 0xffff sometimes seems to mean: CURRENT_DS */
 
 #include <sys/types.h>
 #include <stdlib.h>
@@ -173,6 +174,30 @@
     return TRUE;
 }
 
+/***********************************************************************
+ *           GLOBAL_MoveBlock
+ */
+BOOL16 GLOBAL_MoveBlock( HGLOBAL16 handle, const void *ptr, DWORD size )
+{
+    WORD sel;
+    GLOBALARENA *pArena;
+
+    if (!handle) return TRUE;
+    sel = GlobalHandleToSel( handle ); 
+    if (!VALID_HANDLE(sel))
+    	return FALSE;
+    pArena = GET_ARENA_PTR(sel);
+    if (pArena->selCount != 1)
+        return FALSE;
+
+    pArena->base = (DWORD)ptr;
+    pArena->size = size;
+
+    SELECTOR_MoveBlock( sel, ptr );
+    SetSelectorLimit( sel, size-1 );
+
+    return TRUE;
+}
 
 /***********************************************************************
  *           GLOBAL_Alloc
diff --git a/memory/heap.c b/memory/heap.c
index 3bcc396..05dc8fa 100644
--- a/memory/heap.c
+++ b/memory/heap.c
@@ -2,6 +2,7 @@
  * Win32 heap functions
  *
  * Copyright 1996 Alexandre Julliard
+ * Copyright 1998 Ulrich Weigand
  */
 
 #include <assert.h>
@@ -9,6 +10,7 @@
 #include <string.h>
 #include "windows.h"
 #include "selectors.h"
+#include "global.h"
 #include "winbase.h"
 #include "winerror.h"
 #include "winnt.h"
@@ -426,17 +428,104 @@
     }
 }
 
+/***********************************************************************
+ *           HEAP_InitSubHeap
+ */
+static BOOL32 HEAP_InitSubHeap( HEAP *heap, LPVOID address, DWORD flags,
+                                DWORD commitSize, DWORD totalSize )
+{
+    SUBHEAP *subheap = (SUBHEAP *)address;
+    WORD selector = 0;
+    FREE_LIST_ENTRY *pEntry;
+    int i;
+
+    /* Commit memory */
+
+    if (!VirtualAlloc(address, commitSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE))
+    {
+        WARN(heap, "Could not commit %08lx bytes for sub-heap %08lx\n",
+                   commitSize, (DWORD)address );
+        return FALSE;
+    }
+
+    /* Allocate a selector if needed */
+
+    if (flags & HEAP_WINE_SEGPTR)
+    {
+        selector = SELECTOR_AllocBlock( address, totalSize,
+                     (flags & HEAP_WINE_CODESEG) ? SEGMENT_CODE : SEGMENT_DATA,
+                     (flags & HEAP_WINE_CODESEG) != 0, FALSE );
+        if (!selector)
+        {
+            WARN(heap, "Could not allocate selector\n" );
+            return FALSE;
+        }
+    }
+
+    /* Fill the sub-heap structure */
+
+    subheap->heap       = heap;
+    subheap->selector   = selector;
+    subheap->size       = totalSize;
+    subheap->commitSize = commitSize;
+    subheap->magic      = SUBHEAP_MAGIC;
+
+    if ( subheap != (SUBHEAP *)heap )
+    {
+        /* If this is a secondary subheap, insert it into list */
+
+        subheap->headerSize = sizeof(SUBHEAP);
+        subheap->next       = heap->subheap.next;
+        heap->subheap.next  = subheap;
+    }
+    else
+    {
+        /* If this is a primary subheap, initialize main heap */
+
+        subheap->headerSize = sizeof(HEAP);
+        subheap->next       = NULL;
+        heap->next          = NULL;
+        heap->flags         = flags;
+        heap->magic         = HEAP_MAGIC;
+
+        /* Build the free lists */
+
+        for (i = 0, pEntry = heap->freeList; i < HEAP_NB_FREE_LISTS; i++, pEntry++)
+        {
+            pEntry->size           = HEAP_freeListSizes[i];
+            pEntry->arena.size     = 0 | ARENA_FLAG_FREE;
+            pEntry->arena.next     = i < HEAP_NB_FREE_LISTS-1 ?
+                         &heap->freeList[i+1].arena : &heap->freeList[0].arena;
+            pEntry->arena.prev     = i ? &heap->freeList[i-1].arena : 
+                                   &heap->freeList[HEAP_NB_FREE_LISTS-1].arena;
+            pEntry->arena.threadId = 0;
+            pEntry->arena.magic    = ARENA_FREE_MAGIC;
+        }
+
+        /* Initialize critical section */
+
+        InitializeCriticalSection( &heap->critSection );
+        if (!SystemHeap) HEAP_SystemLock = &heap->critSection;
+    }
+ 
+    /* Create the first free block */
+
+    HEAP_CreateFreeBlock( subheap, (LPBYTE)subheap + subheap->headerSize, 
+                          subheap->size - subheap->headerSize );
+
+    return TRUE;
+}
 
 /***********************************************************************
  *           HEAP_CreateSubHeap
  *
  * Create a sub-heap of the given size.
+ * If heap == NULL, creates a main heap.
  */
-static SUBHEAP *HEAP_CreateSubHeap( DWORD flags, DWORD commitSize,
-                                    DWORD totalSize )
+static SUBHEAP *HEAP_CreateSubHeap( HEAP *heap, DWORD flags, 
+                                    DWORD commitSize, DWORD totalSize )
 {
-    SUBHEAP *subheap;
-    WORD selector = 0;
+    LPVOID address;
 
     /* Round-up sizes on a 64K boundary */
 
@@ -454,46 +543,24 @@
 
     /* Allocate the memory block */
 
-    if (!(subheap = VirtualAlloc( NULL, totalSize,
+    if (!(address = VirtualAlloc( NULL, totalSize,
                                   MEM_RESERVE, PAGE_EXECUTE_READWRITE )))
     {
         WARN(heap, "Could not VirtualAlloc %08lx bytes\n",
                  totalSize );
         return NULL;
     }
-    if (!VirtualAlloc(subheap, commitSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE))
+
+    /* Initialize subheap */
+
+    if (!HEAP_InitSubHeap( heap? heap : (HEAP *)address, 
+                           address, flags, commitSize, totalSize ))
     {
-        WARN(heap, "Could not commit %08lx bytes for sub-heap %08lx\n",
-                 commitSize, (DWORD)subheap );
-        VirtualFree( subheap, 0, MEM_RELEASE );
+        VirtualFree( address, 0, MEM_RELEASE );
         return NULL;
     }
 
-    /* Allocate a selector if needed */
-
-    if (flags & HEAP_WINE_SEGPTR)
-    {
-        selector = SELECTOR_AllocBlock( subheap, totalSize,
-                     (flags & HEAP_WINE_CODESEG) ? SEGMENT_CODE : SEGMENT_DATA,
-                     (flags & HEAP_WINE_CODESEG) != 0, FALSE );
-        if (!selector)
-        {
-            WARN(heap, "Could not allocate selector\n" );
-            VirtualFree( subheap, 0, MEM_RELEASE );
-            return NULL;
-        }
-    }
-
-    /* Fill the sub-heap structure */
-
-    subheap->size       = totalSize;
-    subheap->commitSize = commitSize;
-    subheap->headerSize = sizeof(*subheap);
-    subheap->next       = NULL;
-    subheap->heap       = NULL;
-    subheap->magic      = SUBHEAP_MAGIC;
-    subheap->selector   = selector;
-    return subheap;
+    return (SUBHEAP *)address;
 }
 
 
@@ -538,20 +605,13 @@
         return NULL;
     }
     size += sizeof(SUBHEAP) + sizeof(ARENA_FREE);
-    if (!(subheap = HEAP_CreateSubHeap( heap->flags, size,
+    if (!(subheap = HEAP_CreateSubHeap( heap, heap->flags, size,
                                         MAX( HEAP_DEF_SIZE, size ) )))
         return NULL;
 
-    /* Insert the new sub-heap in the list */
-
-    subheap->heap = heap;
-    subheap->next = heap->subheap.next;
-    heap->subheap.next = subheap;
-    size = subheap->size;
     TRACE(heap, "created new sub-heap %08lx of %08lx bytes for heap %08lx\n",
-                  (DWORD)subheap, size, (DWORD)heap );
+                (DWORD)subheap, size, (DWORD)heap );
 
-    HEAP_CreateFreeBlock( subheap, subheap + 1, size - sizeof(*subheap) );
     *ppSubHeap = subheap;
     return (ARENA_FREE *)(subheap + 1);
 }
@@ -809,10 +869,7 @@
                 DWORD initialSize, /* [in] Initial heap size */
                 DWORD maxSize      /* [in] Maximum heap size */
 ) {
-    int i;
-    HEAP *heap;
     SUBHEAP *subheap;
-    FREE_LIST_ENTRY *pEntry;
 
     /* Allocate the heap block */
 
@@ -821,50 +878,15 @@
         maxSize = HEAP_DEF_SIZE;
         flags |= HEAP_GROWABLE;
     }
-    if (!(subheap = HEAP_CreateSubHeap( flags, initialSize, maxSize )))
+    if (!(subheap = HEAP_CreateSubHeap( NULL, flags, initialSize, maxSize )))
     {
         SetLastError( ERROR_OUTOFMEMORY );
         return 0;
     }
 
-    /* Fill the heap structure */
-
-    heap = (HEAP *)subheap;
-    subheap->heap       = heap;
-    subheap->headerSize = sizeof(HEAP);
-    heap->next          = NULL;
-    heap->flags         = flags;
-    heap->magic         = HEAP_MAGIC;
-
-    /* Build the free lists */
-
-    for (i = 0, pEntry = heap->freeList; i < HEAP_NB_FREE_LISTS; i++, pEntry++)
-    {
-        pEntry->size           = HEAP_freeListSizes[i];
-        pEntry->arena.size     = 0 | ARENA_FLAG_FREE;
-        pEntry->arena.next     = i < HEAP_NB_FREE_LISTS-1 ?
-                         &heap->freeList[i+1].arena : &heap->freeList[0].arena;
-        pEntry->arena.prev     = i ? &heap->freeList[i-1].arena : 
-                                   &heap->freeList[HEAP_NB_FREE_LISTS-1].arena;
-        pEntry->arena.threadId = 0;
-        pEntry->arena.magic    = ARENA_FREE_MAGIC;
-    }
-
-    /* Create the first free block */
-
-    HEAP_CreateFreeBlock( subheap, heap + 1, subheap->size - sizeof(*heap) );
-
-    /* Initialize critical section */
-
-    InitializeCriticalSection( &heap->critSection );
-    if (!SystemHeap) HEAP_SystemLock = &heap->critSection;
-
-    /* We are done */
-
-    return (HANDLE32)heap;
+    return (HANDLE32)subheap;
 }
 
-
 /***********************************************************************
  *           HeapDestroy   (KERNEL32.337)
  * RETURNS
@@ -1354,3 +1376,453 @@
     lstrcpyWtoA( ret, str );
     return ret;
 }
+
+
+
+/***********************************************************************
+ * 32-bit local heap functions (Win95; undocumented)
+ */
+
+#define HTABLE_SIZE      0x10000
+#define HTABLE_PAGESIZE  0x1000
+#define HTABLE_NPAGES    (HTABLE_SIZE / HTABLE_PAGESIZE)
+
+#pragma pack(1)
+typedef struct _LOCAL32HEADER
+{
+    WORD     freeListFirst[HTABLE_NPAGES];
+    WORD     freeListSize[HTABLE_NPAGES];
+    WORD     freeListLast[HTABLE_NPAGES];
+
+    DWORD    selectorTableOffset;
+    WORD     selectorTableSize;
+    WORD     selectorDelta;
+
+    DWORD    segment;
+    LPBYTE   base;
+
+    DWORD    limit;
+    DWORD    flags;
+
+    DWORD    magic;
+    HANDLE32 heap;
+
+} LOCAL32HEADER;
+#pragma pack(4)
+
+#define LOCAL32_MAGIC    ((DWORD)('L' | ('H'<<8) | ('3'<<16) | ('2'<<24)))
+
+/***********************************************************************
+ *           Local32Init   (KERNEL.208)
+ */
+HANDLE32 WINAPI Local32Init( WORD segment, DWORD tableSize,
+                             DWORD heapSize, DWORD flags )
+{
+    DWORD totSize, segSize = 0;
+    LPBYTE base;
+    LOCAL32HEADER *header;
+    HEAP *heap;
+    WORD *selectorTable;
+    WORD selectorEven, selectorOdd;
+    int i, nrBlocks;
+
+    /* Determine new heap size */
+
+    if ( segment )
+        if ( (segSize = GetSelectorLimit( segment )) == 0 )
+            return 0;
+        else
+            segSize++;
+
+    if ( heapSize == -1L )
+        heapSize = 1024L*1024L;   /* FIXME */
+
+    heapSize = (heapSize + 0xffff) & 0xffff0000;
+    segSize  = (segSize  + 0x0fff) & 0xfffff000;
+    totSize  = segSize + HTABLE_SIZE + heapSize;
+
+
+    /* Allocate memory and initialize heap */
+
+    if ( !(base = VirtualAlloc( NULL, totSize, MEM_RESERVE, PAGE_READWRITE )) )
+        return 0;
+
+    if ( !VirtualAlloc( base, segSize + HTABLE_PAGESIZE, 
+                        MEM_COMMIT, PAGE_READWRITE ) )
+    {
+        VirtualFree( base, 0, MEM_RELEASE );
+        return 0;
+    }
+
+    heap = (HEAP *)(base + segSize + HTABLE_SIZE);
+    if ( !HEAP_InitSubHeap( heap, (LPVOID)heap, 0, 0x10000, heapSize ) )
+    {
+        VirtualFree( base, 0, MEM_RELEASE );
+        return 0;
+    }
+
+
+    /* Set up header and handle table */
+    
+    header = (LOCAL32HEADER *)(base + segSize);
+    header->base    = base;
+    header->limit   = HTABLE_PAGESIZE-1;
+    header->flags   = 0;
+    header->magic   = LOCAL32_MAGIC;
+    header->heap    = (HANDLE32)heap;
+
+    header->freeListFirst[0] = sizeof(LOCAL32HEADER);
+    header->freeListLast[0]  = HTABLE_PAGESIZE - 4;
+    header->freeListSize[0]  = (HTABLE_PAGESIZE - sizeof(LOCAL32HEADER)) / 4;
+
+    for (i = header->freeListFirst[0]; i < header->freeListLast[0]; i += 4)
+        *(DWORD *)((LPBYTE)header + i) = i+4;
+
+    header->freeListFirst[1] = 0xffff;
+
+
+    /* Set up selector table */
+  
+    nrBlocks      = (totSize + 0x7fff) >> 15; 
+    selectorTable = (LPWORD) HeapAlloc( header->heap,  0, nrBlocks * 2 );
+    selectorEven  = SELECTOR_AllocBlock( base, totSize, 
+                                         SEGMENT_DATA, FALSE, FALSE );
+    selectorOdd   = SELECTOR_AllocBlock( base + 0x8000, totSize - 0x8000, 
+                                         SEGMENT_DATA, FALSE, FALSE );
+    
+    if ( !selectorTable || !selectorEven || !selectorOdd )
+    {
+        if ( selectorTable ) HeapFree( header->heap, 0, selectorTable );
+        if ( selectorEven  ) SELECTOR_FreeBlock( selectorEven, totSize >> 16 );
+        if ( selectorOdd   ) SELECTOR_FreeBlock( selectorOdd, (totSize-0x8000) >> 16 );
+        HeapDestroy( header->heap );
+        VirtualFree( base, 0, MEM_RELEASE );
+        return 0;
+    }
+
+    header->selectorTableOffset = (LPBYTE)selectorTable - header->base;
+    header->selectorTableSize   = nrBlocks * 4;  /* ??? Win95 does it this way! */
+    header->selectorDelta       = selectorEven - selectorOdd;
+    header->segment             = segment? segment : selectorEven;
+
+    for (i = 0; i < nrBlocks; i++)
+        selectorTable[i] = (i & 1)? selectorOdd  + ((i >> 1) << __AHSHIFT)
+                                  : selectorEven + ((i >> 1) << __AHSHIFT);
+
+    /* Move old segment */
+
+    if ( segment )
+    {
+        /* FIXME: This is somewhat ugly and relies on implementation
+                  details about 16-bit global memory handles ... */
+
+        LPBYTE oldBase = (LPBYTE)GetSelectorBase( segment );
+        memcpy( base, oldBase, segSize );
+        GLOBAL_MoveBlock( segment, base, totSize );
+        HeapFree( SystemHeap, 0, oldBase );
+    }
+    
+    return (HANDLE32)header;
+}
+
+/***********************************************************************
+ *           Local32_SearchHandle
+ */
+static LPDWORD Local32_SearchHandle( LOCAL32HEADER *header, DWORD addr )
+{
+    LPDWORD handle;
+
+    for ( handle = (LPDWORD)((LPBYTE)header + sizeof(LOCAL32HEADER));
+          handle < (LPDWORD)((LPBYTE)header + header->limit);
+          handle++)
+    {
+        if (*handle == addr)
+            return handle;
+    }
+
+    return NULL;
+}
+
+/***********************************************************************
+ *           Local32_ToHandle
+ */
+static VOID Local32_ToHandle( LOCAL32HEADER *header, INT16 type, 
+                              DWORD addr, LPDWORD *handle, LPBYTE *ptr )
+{
+    *handle = NULL;
+    *ptr    = NULL;
+
+    switch (type)
+    {
+        case -2:    /* 16:16 pointer, no handles */
+            *ptr    = PTR_SEG_TO_LIN( addr );
+            *handle = (LPDWORD)*ptr;
+            break;
+
+        case -1:    /* 32-bit offset, no handles */
+            *ptr    = header->base + addr;
+            *handle = (LPDWORD)*ptr;
+            break;
+
+        case 0:     /* handle */
+            if (    addr >= sizeof(LOCAL32HEADER) 
+                 && addr <  header->limit && !(addr & 3) 
+                 && *(LPDWORD)((LPBYTE)header + addr) >= HTABLE_SIZE )
+            {
+                *handle = (LPDWORD)((LPBYTE)header + addr);
+                *ptr    = header->base + **handle;
+            }
+            break;
+
+        case 1:     /* 16:16 pointer */
+            *ptr    = PTR_SEG_TO_LIN( addr );
+            *handle = Local32_SearchHandle( header, *ptr - header->base );
+            break;
+
+        case 2:     /* 32-bit offset */
+            *ptr    = header->base + addr;
+            *handle = Local32_SearchHandle( header, *ptr - header->base );
+            break;
+    }
+}
+
+/***********************************************************************
+ *           Local32_FromHandle
+ */
+static VOID Local32_FromHandle( LOCAL32HEADER *header, INT16 type, 
+                                DWORD *addr, LPDWORD handle, LPBYTE ptr )
+{
+    switch (type)
+    {
+        case -2:    /* 16:16 pointer */
+        case  1:
+        {
+            WORD *selTable = (LPWORD)(header->base + header->selectorTableOffset);
+            DWORD offset   = (LPBYTE)ptr - header->base;
+            *addr = MAKELONG( offset & 0x7fff, selTable[offset >> 15] ); 
+        }
+        break;
+
+        case -1:    /* 32-bit offset */
+        case  2:
+            *addr = ptr - header->base;
+            break;
+
+        case  0:    /* handle */
+            *addr = (LPBYTE)handle - (LPBYTE)header;
+            break;
+    }
+}
+
+/***********************************************************************
+ *           Local32Alloc   (KERNEL.209)
+ */
+DWORD WINAPI Local32Alloc( HANDLE32 heap, DWORD size, INT16 type, DWORD flags )
+{
+    LOCAL32HEADER *header = (LOCAL32HEADER *)heap;
+    LPDWORD handle;
+    LPBYTE ptr;
+    DWORD addr;
+
+    /* Allocate memory */
+    ptr = HeapAlloc( header->heap, 
+                     (flags & LMEM_MOVEABLE)? HEAP_ZERO_MEMORY : 0, size );
+    if (!ptr) return 0;
+
+
+    /* Allocate handle if requested */
+    if (type >= 0)
+    {
+        int page, i;
+
+        /* Find first page of handle table with free slots */
+        for (page = 0; page < HTABLE_NPAGES; page++)
+            if (header->freeListFirst[page] != 0)
+                break;
+        if (page == HTABLE_NPAGES)
+        {
+            WARN( heap, "Out of handles!\n" );
+            HeapFree( header->heap, 0, ptr );
+            return 0;
+        }
+
+        /* If virgin page, initialize it */
+        if (header->freeListFirst[page] == 0xffff)
+        {
+            if ( !VirtualAlloc( (LPBYTE)header + (page << 12), 
+                                0x1000, MEM_COMMIT, PAGE_READWRITE ) )
+            {
+                WARN( heap, "Cannot grow handle table!\n" );
+                HeapFree( header->heap, 0, ptr );
+                return 0;
+            }
+            
+            header->limit += HTABLE_PAGESIZE;
+
+            header->freeListFirst[page] = 0;
+            header->freeListLast[page]  = HTABLE_PAGESIZE - 4;
+            header->freeListSize[page]  = HTABLE_PAGESIZE / 4;
+           
+            for (i = 0; i < HTABLE_PAGESIZE; i += 4)
+                *(DWORD *)((LPBYTE)header + i) = i+4;
+
+            if (page < 31) 
+                header->freeListFirst[page+1] = 0xffff;
+        }
+
+        /* Allocate handle slot from page */
+        handle = (LPDWORD)((LPBYTE)header + header->freeListFirst[page]);
+        if (--header->freeListSize[page] == 0)
+            header->freeListFirst[page] = header->freeListLast[page] = 0;
+        else
+            header->freeListFirst[page] = *handle;
+
+        /* Store 32-bit offset in handle slot */
+        *handle = ptr - header->base;
+    }
+    else
+    {
+        handle = (LPDWORD)ptr;
+        header->flags |= 1;
+    }
+
+
+    /* Convert handle to requested output type */
+    Local32_FromHandle( header, type, &addr, handle, ptr );
+    return addr;
+}
+
+/***********************************************************************
+ *           Local32ReAlloc   (KERNEL.210)
+ */
+DWORD WINAPI Local32ReAlloc( HANDLE32 heap, DWORD addr, INT16 type,
+                             DWORD size, DWORD flags )
+{
+    LOCAL32HEADER *header = (LOCAL32HEADER *)heap;
+    LPDWORD handle;
+    LPBYTE ptr;
+
+    if (!addr)
+        return Local32Alloc( heap, size, type, flags );
+
+    /* Retrieve handle and pointer */
+    Local32_ToHandle( header, type, addr, &handle, &ptr );
+    if (!handle) return FALSE;
+
+    /* Reallocate memory block */
+    ptr = HeapReAlloc( header->heap, 
+                       (flags & LMEM_MOVEABLE)? HEAP_ZERO_MEMORY : 0, 
+                       ptr, size );
+    if (!ptr) return 0;
+
+    /* Modify handle */
+    if (type >= 0)
+        *handle = ptr - header->base;
+    else
+        handle = (LPDWORD)ptr;
+
+    /* Convert handle to requested output type */
+    Local32_FromHandle( header, type, &addr, handle, ptr );
+    return addr;
+}
+
+/***********************************************************************
+ *           Local32Free   (KERNEL.211)
+ */
+BOOL32 WINAPI Local32Free( HANDLE32 heap, DWORD addr, INT16 type )
+{
+    LOCAL32HEADER *header = (LOCAL32HEADER *)heap;
+    LPDWORD handle;
+    LPBYTE ptr;
+
+    /* Retrieve handle and pointer */
+    Local32_ToHandle( header, type, addr, &handle, &ptr );
+    if (!handle) return FALSE;
+
+    /* Free handle if necessary */
+    if (type >= 0)
+    {
+        int offset = (LPBYTE)handle - (LPBYTE)header;
+        int page   = offset >> 12;
+
+        /* Return handle slot to page free list */
+        if (header->freeListSize[page]++ == 0)
+            header->freeListFirst[page] = header->freeListLast[page]  = offset;
+        else
+            *(LPDWORD)((LPBYTE)header + header->freeListLast[page]) = offset,
+            header->freeListLast[page] = *handle;
+
+        *handle = 0;
+
+        /* Shrink handle table when possible */
+        while (page > 0 && header->freeListSize[page] == HTABLE_PAGESIZE / 4)
+        {
+            if ( VirtualFree( (LPBYTE)header + 
+                              (header->limit & ~(HTABLE_PAGESIZE-1)),
+                              HTABLE_PAGESIZE, MEM_DECOMMIT ) )
+                break;
+
+            header->limit -= HTABLE_PAGESIZE;
+            header->freeListFirst[page] = -1;
+            page--;
+        }
+    }
+
+    /* Free memory */
+    return HeapFree( header->heap, 0, ptr );
+}
+
+/***********************************************************************
+ *           Local32Translate   (KERNEL.213)
+ */
+DWORD WINAPI Local32Translate( HANDLE32 heap, DWORD addr, INT16 type1, INT16 type2 )
+{
+    LOCAL32HEADER *header = (LOCAL32HEADER *)heap;
+    LPDWORD handle;
+    LPBYTE ptr;
+
+    Local32_ToHandle( header, type1, addr, &handle, &ptr );
+    if (!handle) return 0;
+
+    Local32_FromHandle( header, type2, &addr, handle, ptr );
+    return addr;
+}
+
+/***********************************************************************
+ *           Local32Size   (KERNEL.214)
+ */
+DWORD WINAPI Local32Size( HANDLE32 heap, DWORD addr, INT16 type )
+{
+    LOCAL32HEADER *header = (LOCAL32HEADER *)heap;
+    LPDWORD handle;
+    LPBYTE ptr;
+
+    Local32_ToHandle( header, type, addr, &handle, &ptr );
+    if (!handle) return 0;
+
+    return HeapSize( header->heap, 0, ptr );
+}
+
+/***********************************************************************
+ *           Local32ValidHandle   (KERNEL.215)
+ */
+BOOL32 WINAPI Local32ValidHandle( HANDLE32 heap, WORD addr )
+{
+    LOCAL32HEADER *header = (LOCAL32HEADER *)heap;
+    LPDWORD handle;
+    LPBYTE ptr;
+
+    Local32_ToHandle( header, 0, addr, &handle, &ptr );
+    return handle != NULL;
+}
+
+/***********************************************************************
+ *           Local32GetSegment   (KERNEL.229)
+ */
+WORD WINAPI Local32GetSegment( HANDLE32 heap )
+{
+    LOCAL32HEADER *header = (LOCAL32HEADER *)heap;
+    return header->segment;
+}
+
+
diff --git a/memory/local.c b/memory/local.c
index 5e4192c..9d8fe87 100644
--- a/memory/local.c
+++ b/memory/local.c
@@ -345,7 +345,8 @@
 	if ((pModule = NE_GetPtr( selector )))
 	{
 	    SEGTABLEENTRY *pSeg = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
-	    if (pModule->dgroup && (pSeg->selector == selector)) {
+	    if (pModule->dgroup && (GlobalHandleToSel(pSeg->hSeg) == selector))
+	    {
 		/* We can't just use the simple method of using the value
                  * of minsize + stacksize, since there are programs that
                  * resize the data segment before calling InitTask(). So,
@@ -1602,7 +1603,8 @@
     WORD ds;
 
     if (!(pModule = NE_GetPtr( module ))) return 0;
-    ds = (NE_SEG_TABLE( pModule ) + pModule->dgroup - 1)->selector;
+    ds =
+    GlobalHandleToSel((NE_SEG_TABLE( pModule ) + pModule->dgroup - 1)->hSeg);
     return MAKELONG( LOCAL_CountFree( ds ), LOCAL_HeapSize( ds ) );
 }
 
diff --git a/memory/selector.c b/memory/selector.c
index 859cc6a..16bddc6 100644
--- a/memory/selector.c
+++ b/memory/selector.c
@@ -406,7 +406,7 @@
     if (IS_SELECTOR_FREE(sel)) return TRUE;
     LDT_GetEntry( SELECTOR_TO_ENTRY(sel), &entry );
     if (entry.type != SEGMENT_CODE) return TRUE;
-    if (OFFSETOF(lpfn) > entry.limit) return TRUE;
+    if (OFFSETOF(lpfn) > GET_SEL_LIMIT(sel)) return TRUE;
     return FALSE;
 }
 
@@ -425,7 +425,7 @@
     LDT_GetEntry( SELECTOR_TO_ENTRY(sel), &entry );
     if ((entry.type == SEGMENT_CODE) && entry.read_only) return TRUE;
     if (strlen(PTR_SEG_TO_LIN(ptr)) < size) size = strlen(PTR_SEG_TO_LIN(ptr));
-    if (OFFSETOF(ptr) + size - 1 > entry.limit) return TRUE;
+    if (OFFSETOF(ptr) + size - 1 > GET_SEL_LIMIT(sel)) return TRUE;
     return FALSE;
 }
 
@@ -443,7 +443,7 @@
     if (IS_SELECTOR_FREE(sel)) return TRUE;
     LDT_GetEntry( SELECTOR_TO_ENTRY(sel), &entry );
     if ((entry.type == SEGMENT_CODE) && entry.read_only) return TRUE;
-    if (OFFSETOF(ptr) + size - 1 > entry.limit) return TRUE;
+    if (OFFSETOF(ptr) + size - 1 > GET_SEL_LIMIT(sel)) return TRUE;
     return FALSE;
 }
 
@@ -461,7 +461,7 @@
     if (IS_SELECTOR_FREE(sel)) return TRUE;
     LDT_GetEntry( SELECTOR_TO_ENTRY(sel), &entry );
     if ((entry.type == SEGMENT_CODE) || entry.read_only) return TRUE;
-    if (OFFSETOF(ptr) + size - 1 > entry.limit) return TRUE;
+    if (OFFSETOF(ptr) + size - 1 > GET_SEL_LIMIT(sel)) return TRUE;
     return FALSE;
 }
 
diff --git a/memory/virtual.c b/memory/virtual.c
index 3b4e94f..58aa32a 100644
--- a/memory/virtual.c
+++ b/memory/virtual.c
@@ -6,6 +6,7 @@
 
 #include <assert.h>
 #include <errno.h>
+#include <sys/errno.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -310,8 +311,10 @@
 ) {
     if (protect) {
     	*protect = VIRTUAL_Win32Flags[vprot & 0x0f];
-    	if (vprot & VPROT_GUARD) *protect |= PAGE_GUARD;
+/*    	if (vprot & VPROT_GUARD) *protect |= PAGE_GUARD;*/
     	if (vprot & VPROT_NOCACHE) *protect |= PAGE_NOCACHE;
+
+    	if (vprot & VPROT_GUARD) *protect = PAGE_NOACCESS;
     }
 
     if (state) *state = (vprot & VPROT_COMMITTED) ? MEM_COMMIT : MEM_RESERVE;
diff --git a/misc/Makefile.in b/misc/Makefile.in
index bc5f783..2ab8f54 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -6,7 +6,6 @@
 MODULE    = misc
 
 C_SRCS = \
-	aspi.c \
 	callback.c \
 	comm.c \
 	commdlg.c \
diff --git a/misc/aspi.c b/misc/aspi.c
deleted file mode 100644
index e4592a9..0000000
--- a/misc/aspi.c
+++ /dev/null
@@ -1,516 +0,0 @@
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <ldt.h>
-#include <memory.h>
-#include <unistd.h>
-#include <callback.h>
-#include "windows.h"
-#include "aspi.h"
-#include "options.h"
-#include "heap.h"
-#include "debug.h"
-#include "selectors.h"
-#include "module.h"
-#include "miscemu.h"
-
-
-/* FIXME!
- * 1) Residual byte length reporting not handled
- * 2) Make this code re-entrant for multithreading
- * 3) Only linux supported so far
- */
-
-#ifdef linux
-
-/* This is a duplicate of the sg_header from /usr/src/linux/include/scsi/sg.h
- * kernel 2.0.30
- * This will probably break at some point, but for those who don't have
- * kernels installed, I think this should still work.
- *
- */
-
-struct sg_header
- {
-  int pack_len;    /* length of incoming packet <4096 (including header) */
-  int reply_len;   /* maximum length <4096 of expected reply */
-  int pack_id;     /* id number of packet */
-  int result;      /* 0==ok, otherwise refer to errno codes */
-  unsigned int twelve_byte:1; /* Force 12 byte command length for group 6 & 7 commands  */
-  unsigned int other_flags:31;			/* for future use */
-  unsigned char sense_buffer[16]; /* used only by reads */
-  /* command follows then data for command */
- };
-
-#define SCSI_OFF sizeof(struct sg_header)
-#endif
-
-#define ASPI_POSTING(prb) (prb->SRB_Flags & 0x1)
-
-#define HOST_TO_TARGET(prb) (((prb->SRB_Flags>>3) & 0x3) == 0x2)
-#define TARGET_TO_HOST(prb) (((prb->SRB_Flags>>3) & 0x3) == 0x1)
-#define NO_DATA_TRANSFERED(prb) (((prb->SRB_Flags>>3) & 0x3) == 0x3)
-
-#define SRB_ENABLE_RESIDUAL_COUNT 0x4
-
-#define INQUIRY_VENDOR		8
-
-#define MUSTEK_SCSI_AREA_AND_WINDOWS 0x04
-#define MUSTEK_SCSI_READ_SCANNED_DATA 0x08
-#define MUSTEK_SCSI_GET_IMAGE_STATUS 0x0f
-#define MUSTEK_SCSI_ADF_AND_BACKTRACE 0x10
-#define MUSTEK_SCSI_CCD_DISTANCE 0x11
-#define MUSTEK_SCSI_START_STOP 0x1b
-
-#define CMD_TEST_UNIT_READY 0x00
-#define CMD_REQUEST_SENSE 0x03
-#define CMD_INQUIRY 0x12
-
-/* scanner commands - just for debug */
-#define CMD_SCAN_GET_DATA_BUFFER_STATUS 0x34
-#define CMD_SCAN_GET_WINDOW 0x25
-#define CMD_SCAN_OBJECT_POSITION 0x31
-#define CMD_SCAN_READ 0x28
-#define CMD_SCAN_RELEASE_UNIT 0x17
-#define CMD_SCAN_RESERVE_UNIT 0x16
-#define CMD_SCAN_SCAN 0x1b
-#define CMD_SCAN_SEND 0x2a
-#define CMD_SCAN_CHANGE_DEFINITION 0x40
-
-#define INQURIY_CMDLEN 6
-#define INQURIY_REPLY_LEN 96
-#define INQUIRY_VENDOR 8
-
-#define SENSE_BUFFER(prb) (&prb->CDBByte[prb->SRB_CDBLen])
-
-
-/* Just a container for seeing what devices are open */
-struct ASPI_DEVICE_INFO {
-    struct ASPI_DEVICE_INFO *	next;
-    int				fd;
-    int				hostId;
-    int				target;
-    int				lun;
-};
-
-typedef struct ASPI_DEVICE_INFO ASPI_DEVICE_INFO;
-static ASPI_DEVICE_INFO *ASPI_open_devices = NULL;
-
-static BOOL16 DOSASPI = FALSE;
-
-#ifdef linux
-static int
-ASPI_OpenDevice16(SRB_ExecSCSICmd16 *prb)
-{
-    int	fd;
-    char	idstr[20];
-    char	device_str[50];
-    ASPI_DEVICE_INFO *curr;
-
-    /* search list of devices to see if we've opened it already.
-     * There is not an explicit open/close in ASPI land, so hopefully
-     * keeping a device open won't be a problem.
-     */
-
-    for (curr = ASPI_open_devices; curr; curr = curr->next) {
-	if (curr->hostId == prb->SRB_HaId &&
-	    curr->target == prb->SRB_Target &&
-	    curr->lun == prb->SRB_Lun) {
-	    return curr->fd;
-	}
-    }
-
-    /* device wasn't cached, go ahead and open it */
-    sprintf(idstr, "scsi c%1dt%1dd%1d", prb->SRB_HaId, prb->SRB_Target, prb->SRB_Lun);
-
-    if (!PROFILE_GetWineIniString(idstr, "Device", "", device_str, sizeof(device_str))) {
-	TRACE(aspi, "Trying to open unlisted scsi device %s\n", idstr);
-	return -1;
-    }
-
-    TRACE(aspi, "Opening device %s=%s\n", idstr, device_str);
-
-    fd = open(device_str, O_RDWR);
-    if (fd == -1) {
-	int save_error = errno;
-	WARN(aspi, "Error opening device errno=%d\n", save_error);
-	return -1;
-    }
-
-    /* device is now open */
-    curr = HeapAlloc( SystemHeap, 0, sizeof(ASPI_DEVICE_INFO) );
-    curr->fd = fd;
-    curr->hostId = prb->SRB_HaId;
-    curr->target = prb->SRB_Target;
-    curr->lun = prb->SRB_Lun;
-
-    /* insert new record at beginning of open device list */
-    curr->next = ASPI_open_devices;
-    ASPI_open_devices = curr;
-    return fd;
-}
-
-
-static void
-ASPI_DebugPrintCmd16(SRB_ExecSCSICmd16 *prb)
-{
-  BYTE	cmd;
-  int	i;
-  BYTE *cdb;
-  BYTE *lpBuf;
-  dbg_decl_str(aspi, 512);
-
-  if ((DOSASPI) && (prb->SRB_BufPointer)) /* translate real mode address */
-    lpBuf = (BYTE *)DOSMEM_MapRealToLinear((UINT32)prb->SRB_BufPointer);
-  else
-    lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
-
-  switch (prb->CDBByte[0]) {
-  case CMD_INQUIRY:
-    TRACE(aspi, "{\n");
-    TRACE(aspi, "\tEVPD: %d\n", prb->CDBByte[1] & 1);
-    TRACE(aspi, "\tLUN: %d\n", (prb->CDBByte[1] & 0xc) >> 1);
-    TRACE(aspi, "\tPAGE CODE: %d\n", prb->CDBByte[2]);
-    TRACE(aspi, "\tALLOCATION LENGTH: %d\n", prb->CDBByte[4]);
-    TRACE(aspi, "\tCONTROL: %d\n", prb->CDBByte[5]);
-    TRACE(aspi, "}\n");
-    break;
-  case CMD_SCAN_SCAN:
-    TRACE(aspi, "Transfer Length: %d\n", prb->CDBByte[4]);
-    break;
-  }
-
-  TRACE(aspi, "Host Adapter: %d\n", prb->SRB_HaId);
-  TRACE(aspi, "Flags: %d\n", prb->SRB_Flags);
-  if (TARGET_TO_HOST(prb)) {
-    TRACE(aspi, "\tData transfer: Target to host. Length checked.\n");
-  }
-  else if (HOST_TO_TARGET(prb)) {
-    TRACE(aspi, "\tData transfer: Host to target. Length checked.\n");
-  }
-  else if (NO_DATA_TRANSFERED(prb)) {
-    TRACE(aspi, "\tData transfer: none\n");
-  }
-  else {
-    WARN(aspi, "\tTransfer by scsi cmd. Length not checked\n");
-  }
-
-  TRACE(aspi, "\tResidual byte length reporting %s\n", prb->SRB_Flags & 0x4 ? "enabled" : "disabled");
-  TRACE(aspi, "\tLinking %s\n", prb->SRB_Flags & 0x2 ? "enabled" : "disabled");
-  TRACE(aspi, "\tPosting %s\n", prb->SRB_Flags & 0x1 ? "enabled" : "disabled");
-  TRACE(aspi, "Target: %d\n", prb->SRB_Target);
-  TRACE(aspi, "Lun: %d\n", prb->SRB_Lun);
-  TRACE(aspi, "BufLen: %ld\n", prb->SRB_BufLen);
-  TRACE(aspi, "SenseLen: %d\n", prb->SRB_SenseLen);
-  TRACE(aspi, "BufPtr: %lx (%p)\n", prb->SRB_BufPointer, lpBuf);
-  TRACE(aspi, "LinkPointer %lx\n", prb->SRB_Rsvd1);
-  TRACE(aspi, "CDB Length: %d\n", prb->SRB_CDBLen);
-  TRACE(aspi, "POST Proc: %lx\n", (DWORD) prb->SRB_PostProc);
-  cdb = &prb->CDBByte[0];
-  cmd = prb->CDBByte[0];
-  for (i = 0; i < prb->SRB_CDBLen; i++) {
-    if (i != 0) dsprintf(aspi, ",");
-    dsprintf(aspi, "%02x", *cdb++);
-  }
-  TRACE(aspi, "CDB buffer[%s]\n", dbg_str(aspi));
-}
-
-static void
-PrintSenseArea16(SRB_ExecSCSICmd16 *prb)
-{
-  int	i;
-  BYTE *cdb;
-  dbg_decl_str(aspi, 512);
-
-  cdb = &prb->CDBByte[0];
-  for (i = 0; i < prb->SRB_SenseLen; i++) {
-    if (i) dsprintf(aspi, ",");
-    dsprintf(aspi, "%02x", *cdb++);
-  }
-  TRACE(aspi, "SenseArea[%s]\n", dbg_str(aspi));
-}
-
-static void
-ASPI_DebugPrintResult16(SRB_ExecSCSICmd16 *prb)
-{
-  BYTE *lpBuf;
-
-  if ((DOSASPI) && (prb->SRB_BufPointer)) /* translate real mode address */
-    lpBuf = (BYTE *)DOSMEM_MapRealToLinear((UINT32)prb->SRB_BufPointer);
-  else
-    lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
-
-  switch (prb->CDBByte[0]) {
-  case CMD_INQUIRY:
-    TRACE(aspi, "Vendor: %s\n", lpBuf + INQUIRY_VENDOR);
-    break;
-  case CMD_TEST_UNIT_READY:
-    PrintSenseArea16(prb);
-    break;
-  }
-}
-
-static WORD
-ASPI_ExecScsiCmd16(SRB_ExecSCSICmd16 *prb, SEGPTR segptr_prb)
-{
-  struct sg_header *sg_hd, *sg_reply_hdr;
-  int	status;
-  BYTE *lpBuf;
-  int	in_len, out_len;
-  int	error_code = 0;
-  int	fd;
-
-  ASPI_DebugPrintCmd16(prb);
-
-  fd = ASPI_OpenDevice16(prb);
-  if (fd == -1) {
-      WARN(aspi, "ASPI_ExecScsiCmd16 failed: could not open device.\n");
-      prb->SRB_Status = SS_ERR;
-      return SS_ERR;
-  }
-
-  sg_hd = NULL;
-  sg_reply_hdr = NULL;
-
-  prb->SRB_Status = SS_PENDING;
-  if ((DOSASPI) && (prb->SRB_BufPointer)) /* translate real mode address */
-    lpBuf = (BYTE *)DOSMEM_MapRealToLinear((UINT32)prb->SRB_BufPointer);
-  else
-    lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
-
-  if (!prb->SRB_CDBLen) {
-      WARN(aspi, "ASPI_ExecScsiCmd16 failed: prb->SRB_CDBLen = 0.\n");
-      prb->SRB_Status = SS_ERR;
-      return SS_ERR;
-  }
-
-  /* build up sg_header + scsi cmd */
-  if (HOST_TO_TARGET(prb)) {
-    /* send header, command, and then data */
-    in_len = SCSI_OFF + prb->SRB_CDBLen + prb->SRB_BufLen;
-    sg_hd = (struct sg_header *) malloc(in_len);
-    memset(sg_hd, 0, SCSI_OFF);
-    memcpy(sg_hd + 1, &prb->CDBByte[0], prb->SRB_CDBLen);
-    if (prb->SRB_BufLen) {
-      memcpy(((BYTE *) sg_hd) + SCSI_OFF + prb->SRB_CDBLen, lpBuf, prb->SRB_BufLen);
-    }
-  }
-  else {
-    /* send header and command - no data */
-    in_len = SCSI_OFF + prb->SRB_CDBLen;
-    sg_hd = (struct sg_header *) malloc(in_len);
-    memset(sg_hd, 0, SCSI_OFF);
-    memcpy(sg_hd + 1, &prb->CDBByte[0], prb->SRB_CDBLen);
-  }
-
-  if (TARGET_TO_HOST(prb)) {
-    out_len = SCSI_OFF + prb->SRB_BufLen;
-    sg_reply_hdr = (struct sg_header *) malloc(out_len);
-    memset(sg_reply_hdr, 0, SCSI_OFF);
-    sg_hd->reply_len = out_len;
-  }
-  else {
-    out_len = SCSI_OFF;
-    sg_reply_hdr = (struct sg_header *) malloc(out_len);
-    memset(sg_reply_hdr, 0, SCSI_OFF);
-    sg_hd->reply_len = out_len;
-  }
-
-  status = write(fd, sg_hd, in_len);
-  if (status < 0 || status != in_len) {
-      int myerror = errno;
-
-    WARN(aspi, "Not enough bytes written to scsi device bytes=%d .. %d\n", in_len, status);
-    if (status < 0) {
-	if (myerror == ENOMEM) {
-	    MSG("ASPI: Linux generic scsi driver\n  You probably need to re-compile your kernel with a larger SG_BIG_BUFF value (sg.h)\n  Suggest 130560\n");
-	}
-	WARN(aspi, "errno: = %d\n", myerror);
-    }
-    goto error_exit;
-  }
-
-  status = read(fd, sg_reply_hdr, out_len);
-  if (status < 0 || status != out_len) {
-    WARN(aspi, "not enough bytes read from scsi device%d\n", status);
-    goto error_exit;
-  }
-
-  if (sg_reply_hdr->result != 0) {
-    error_code = sg_reply_hdr->result;
-    WARN(aspi, "reply header error (%d)\n", sg_reply_hdr->result);
-    goto error_exit;
-  }
-
-  if (TARGET_TO_HOST(prb) && prb->SRB_BufLen) {
-    memcpy(lpBuf, sg_reply_hdr + 1, prb->SRB_BufLen);
-  }
-
-  /* copy in sense buffer to amount that is available in client */
-  if (prb->SRB_SenseLen) {
-    int sense_len = prb->SRB_SenseLen;
-    if (prb->SRB_SenseLen > 16)
-      sense_len = 16;
-    memcpy(SENSE_BUFFER(prb), &sg_reply_hdr->sense_buffer[0], sense_len);
-  }
-
-
-  prb->SRB_Status = SS_COMP;
-  prb->SRB_HaStat = HASTAT_OK;
-  prb->SRB_TargStat = STATUS_GOOD;
-
-  /* now do  posting */
-
-  if (ASPI_POSTING(prb) && prb->SRB_PostProc) {
-    TRACE(aspi, "Post Routine (%lx) called\n", (DWORD) prb->SRB_PostProc);
-    Callbacks->CallASPIPostProc(prb->SRB_PostProc, segptr_prb);
-  }
-
-  free(sg_reply_hdr);
-  free(sg_hd);
-  ASPI_DebugPrintResult16(prb);
-  return SS_COMP;
-  
-error_exit:
-  if (error_code == EBUSY) {
-      prb->SRB_Status = SS_ASPI_IS_BUSY;
-      TRACE(aspi, "Device busy\n");
-  }
-  else {
-      WARN(aspi, "ASPI_GenericHandleScsiCmd failed\n");
-      prb->SRB_Status = SS_ERR;
-  }
-
-  /* I'm not sure exactly error codes work here
-   * We probably should set prb->SRB_TargStat, SRB_HaStat ?
-   */
-  WARN(aspi, "ASPI_GenericHandleScsiCmd: error_exit\n");
-  free(sg_reply_hdr);
-  free(sg_hd);
-  return prb->SRB_Status;
-}
-#endif
-
-/***********************************************************************
- *             GetASPISupportInfo16   (WINASPI.1)
- */
-
-WORD WINAPI GetASPISupportInfo16()
-{
-#ifdef linux
-    TRACE(aspi, "GETASPISupportInfo\n");
-    /* high byte SS_COMP - low byte number of host adapters.
-     * FIXME!!! The number of host adapters is incorrect.
-     * I'm not sure how to determine this under linux etc.
-     */
-    return ((SS_COMP << 8) | 0x1);
-#else
-    return ((SS_COMP << 8) | 0x0);
-#endif
-}
-
-/***********************************************************************
- *             SendASPICommand16   (WINASPI.2)
- */
-
-WORD WINAPI SendASPICommand16(SEGPTR segptr_srb)
-{
-#ifdef linux
-  LPSRB16 lpSRB = PTR_SEG_TO_LIN(segptr_srb);
-
-  switch (lpSRB->common.SRB_cmd) {
-  case SC_HA_INQUIRY:
-    lpSRB->inquiry.SRB_Status = 0x1;           /* completed successfully */
-    lpSRB->inquiry.SRB_HaId = 1;               /* bogus value */
-    lpSRB->inquiry.HA_Count = 1;               /* not always */
-    lpSRB->inquiry.HA_SCSI_ID = 7;             /* not always ID 7 */
-    strcat(lpSRB->inquiry.HA_ManagerId, "Wine ASPI"); /* max 15 chars */
-    lpSRB->inquiry.SRB_55AASignature = 0x55aa; /* correct ??? */
-    lpSRB->inquiry.SRB_ExtBufferSize = 0x2000; /* bogus value */
-    FIXME(aspi, "ASPI: Partially implemented SC_HA_INQUIRY\n");
-    break;
-  case SC_GET_DEV_TYPE:
-    FIXME(aspi, "Not implemented SC_GET_DEV_TYPE\n");
-    break;
-  case SC_EXEC_SCSI_CMD:
-    return ASPI_ExecScsiCmd16(&lpSRB->cmd, segptr_srb);
-    break;
-  case SC_RESET_DEV:
-    FIXME(aspi, "Not implemented SC_RESET_DEV\n");
-    break;
-  default:
-    WARN(aspi, "Unknown command %d\n", lpSRB->common.SRB_cmd);
-  }
-  return SS_INVALID_SRB;
-#else
-  return SS_INVALID_SRB;
-#endif
-}
-
-/***********************************************************************
- *             GetASPIDLLVersion   (WINASPI.4)
- */
-
-DWORD WINAPI GetASPIDLLVersion()
-{
-#ifdef linux
-	return (DWORD)2;
-#else
-	return (DWORD)0;
-#endif
-}
-
-
-void WINAPI ASPI_DOS_func(DWORD srb)
-{
-       LPSRB16 lpSRB = (LPSRB16)DOSMEM_MapRealToLinear(srb);
-       SEGPTR spSRB = MapLS(lpSRB);
-
-       TRACE(aspi, "DOSASPI: function #%d\n", lpSRB->common.SRB_cmd);
-       DOSASPI = TRUE;
-       SendASPICommand16(spSRB);
-       DOSASPI = FALSE;
-       UnMapLS(spSRB);
-}
-
-
-/* returns a real mode call address to ASPI_DOS_func() */
-void ASPI_DOS_HandleInt(CONTEXT *context)
-{
-#ifdef linux
-       FARPROC16 DOS_func;
-       DWORD dos;
-       LPBYTE dosptr;
-
-       DOS_func = MODULE_GetWndProcEntry16("ASPI_DOS_func");
-       dos = GlobalDOSAlloc(5);
-       dosptr = (BYTE *)PTR_SEG_OFF_TO_LIN(LOWORD(dos), 0);
-       *dosptr++ = 0xea; /* ljmp */
-       *(FARPROC16 *)dosptr = DOS_func;
-
-       *(DWORD *)PTR_SEG_OFF_TO_LIN(DS_reg(context), DX_reg(context))
-               = MAKELONG(0, HIWORD(dos)); /* real mode address */
-       RESET_CFLAG(context);
-       AX_reg(context) = CX_reg(context);
-#else
-       SET_CFLAG(context);
-#endif
-}
-
-/*******************************************************************
- *     GetASPI32SupportInfo		[WNASPI32.0]
- *
- * Checks if the ASPI subsystem is initialized correctly.
- *
- * RETURNS
- *    HIWORD: 0.
- *    HIBYTE of LOWORD: status (SS_COMP or SS_FAILED_INIT)
- *    LOBYTE of LOWORD: # of host adapters.  
- */
-DWORD WINAPI GetASPI32SupportInfo()
-{
-    return (SS_COMP << 8) | 1; /* FIXME: get # of host adapters installed */
-}
-
diff --git a/misc/commdlg.c b/misc/commdlg.c
index 007f473..cd31a46 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -1448,7 +1448,7 @@
  */
 BOOL32 WINAPI PrintDlg32A( LPPRINTDLG32A printdlg )
 {
-    FIXME(commdlg, "empty stub\n" );
+    FIXME(commdlg, "(%p): stub\n",printdlg);
     /* Altough returning FALSE is theoricaly the right thing
      * most programs check for a printer at startup, and if
      * none is found popup PrintDlg32A(), if it fails the program
diff --git a/misc/crtdll.c b/misc/crtdll.c
index 85e99de..62eda7d 100644
--- a/misc/crtdll.c
+++ b/misc/crtdll.c
@@ -161,7 +161,7 @@
  */
 INT32 __cdecl CRTDLL__findnext(DWORD hand,struct find_t* x2)
 {
-  FIXME(crtdll, ":(%d,%p): stub\n",hand,x2);
+  FIXME(crtdll, ":(%ld,%p): stub\n",hand,x2);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -1929,3 +1929,9 @@
 	}
 	return 0;
 }
+/*********************************************************************
+ *                  __dllonexit           (CRTDLL.25)
+ */
+VOID __cdecl CRTDLL__dllonexit ()
+{	FIXME(crtdll,"stub\n");
+ }
diff --git a/misc/ddeml.c b/misc/ddeml.c
index 069b1fc..9916ae1 100644
--- a/misc/ddeml.c
+++ b/misc/ddeml.c
@@ -55,11 +55,14 @@
 UINT32 WINAPI DdeInitialize32W( LPDWORD pidInst, PFNCALLBACK32 pfnCallback,
                                 DWORD afCmd, DWORD ulRes )
 {
-    FIXME(ddeml, "(%p,%p,%ld,%ld): stub\n",pidInst,pfnCallback,afCmd,ulRes);
+    FIXME(ddeml, "(%p,%p,0x%lx,%ld): stub\n",pidInst,pfnCallback,afCmd,ulRes);
 
     if(pidInst)
       *pidInst = 0;
 
+    if( ulRes )
+        ERR(dde, "Reserved value not zero?  What does this mean?\n");
+
     return DMLERR_NO_ERROR;
 }
 
@@ -184,7 +187,8 @@
 HCONV WINAPI DdeConnect32( DWORD idInst, HSZ hszService, HSZ hszTopic,
                            LPCONVCONTEXT32 pCC )
 {
-    FIXME( ddeml, "(...): stub\n");
+    FIXME(ddeml, "(0x%lx,%ld,%ld,%p): stub\n",idInst,hszService,hszTopic,
+          pCC);
     return 0;
 }
 
@@ -202,16 +206,19 @@
  */
 BOOL16 WINAPI DdeSetUserHandle( HCONV hConv, DWORD id, DWORD hUser )
 {
-    FIXME( ddeml, "empty stub\n" );
+    FIXME( ddeml, "(%ld,%ld,%ld): stub\n",hConv,id, hUser );
     return 0;
 }
 
 /*****************************************************************
  *            DdeCreateDataHandle (DDEML.14)
  */
-HDDEDATA WINAPI DdeCreateDataHandle( DWORD idInst, LPBYTE pSrc, DWORD cb, DWORD cbOff, HSZ hszItem, UINT16 wFmt, UINT16 afCmd )
+HDDEDATA WINAPI DdeCreateDataHandle( DWORD idInst, LPBYTE pSrc, DWORD cb, 
+                                     DWORD cbOff, HSZ hszItem, UINT16 wFmt, 
+                                     UINT16 afCmd )
 {
-    FIXME( ddeml, "empty stub\n" );
+    FIXME( ddeml, "(%ld,%p,%ld,%ld,%ld,%d,%d): stub\n",idInst,pSrc,cb,cbOff,
+           hszItem, wFmt, afCmd );
     return 0;
 }
 
diff --git a/misc/error.c b/misc/error.c
index 4f32d0b..248fd2f 100644
--- a/misc/error.c
+++ b/misc/error.c
@@ -8,6 +8,7 @@
 #include <string.h>
 
 #include "windows.h"
+#include "stackframe.h"
 #include "debug.h"
 
 #define ErrorString(manifest) { manifest, # manifest }
@@ -153,3 +154,34 @@
 	 */
 	MSG("(%s, %p, %p)\n", GetParamErrorString(uErr), lpfn, lpvParam);
 }
+
+/***********************************************************************
+*	LogParamErrorRegs (KERNEL.327)
+*/
+void WINAPI LogParamErrorRegs( CONTEXT *context )
+{
+	UINT16 uErr = BX_reg( context );
+        FARPROC16 lpfn = (FARPROC16)PTR_SEG_OFF_TO_SEGPTR( CS_reg(context),
+                                                           EIP_reg(context) );
+        LPVOID lpvParam = (LPVOID)MAKELONG( AX_reg( context ), 
+                                            CX_reg( context ) );
+	
+	LogParamError( uErr, lpfn, lpvParam );
+
+	if (!(uErr & ERR_WARNING))
+	{
+		/* Abort current procedure: Unwind stack frame and jump
+		   to error handler (location at [bp-2]) */
+
+		WORD *stack = PTR_SEG_OFF_TO_LIN( SS_reg( context ), 
+						  BP_reg( context ));
+		SP_reg( context ) = BP_reg( context ) - 2;
+		BP_reg( context ) = stack[0] & 0xfffe;
+
+		IP_reg( context ) = stack[-1];
+
+		EAX_reg( context ) = ECX_reg( context ) = EDX_reg( context ) = 0;
+		ES_reg( context) = 0;
+	}
+}
+
diff --git a/misc/imm.c b/misc/imm.c
index 579477d..9c20ae3 100644
--- a/misc/imm.c
+++ b/misc/imm.c
@@ -5,532 +5,712 @@
  */
 
 #include "windows.h"
+#include "winerror.h"
 #include "wintypes.h"
+#include "debug.h"
+#include "winversion.h"
 #include "imm.h"
 
 /***********************************************************************
  *           ImmAssociateContext32 (IMM32.1)
  */
-
 HIMC32 WINAPI ImmAssociateContext32(HWND32 hWnd, HIMC32 hIMC)
 {
-	return NULL;
+  FIXME(imm, "(0x%08x, 0x%08x): stub\n",hWnd,hIMC);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return NULL;
 }
 
 /***********************************************************************
  *           ImmConfigureIME32A (IMM32.2)
  */
-
-BOOL32 WINAPI ImmConfigureIME32A(HKL32 hKL, HWND32 hWnd, DWORD dwMode, LPVOID lpData)
+BOOL32 WINAPI ImmConfigureIME32A(
+  HKL32 hKL, HWND32 hWnd, DWORD dwMode, LPVOID lpData)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, 0x%08x, %ld, %p): stub\n",
+    hKL, hWnd, dwMode, lpData
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmConfigureIME32W (IMM32.3)
  */
-
-BOOL32 WINAPI ImmConfigureIME32W(HKL32 hKL, HWND32 hWnd, DWORD dwMode, LPVOID lpData)
+BOOL32 WINAPI ImmConfigureIME32W(
+  HKL32 hKL, HWND32 hWnd, DWORD dwMode, LPVOID lpData)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, 0x%08x, %ld, %p): stub\n",
+    hKL, hWnd, dwMode, lpData
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmCreateContext32 (IMM32.4)
  */
-
 HIMC32 WINAPI ImmCreateContext32()
 {
-	return NULL;
+  FIXME(imm, "(): stub\n");
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return NULL;
 }
 
 /***********************************************************************
  *           ImmDestroyContext32 (IMM32.7)
  */
-
 BOOL32 WINAPI ImmDestroyContext32(HIMC32 hIMC)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x): stub\n",hIMC);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
-
 /***********************************************************************
  *           ImmEnumRegisterWord32A (IMM32.10)
  */
-
 UINT32 WINAPI ImmEnumRegisterWord32A(
-    HKL32 hKL, REGISTERWORDENUMPROCA lpfnEnumProc, 
-	LPCSTR lpszReading, DWORD dwStyle, 
-	LPCSTR lpszRegister, LPVOID lpData)
+  HKL32 hKL, REGISTERWORDENUMPROCA lpfnEnumProc,
+  LPCSTR lpszReading, DWORD dwStyle,
+  LPCSTR lpszRegister, LPVOID lpData)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, %p, %s, %ld, %s, %p): stub\n",
+    hKL, lpfnEnumProc, 
+    debugstr_a(lpszReading), dwStyle,
+    debugstr_a(lpszRegister), lpData
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 /***********************************************************************
  *           ImmEnumRegisterWord32W (IMM32.11)
  */
-
 UINT32 WINAPI ImmEnumRegisterWord32W(
-    HKL32 hKL, REGISTERWORDENUMPROCW lpfnEnumProc,
-	LPCWSTR lpszReading, DWORD dwStyle, 
-	LPCWSTR lpszRegister, LPVOID lpData)
+  HKL32 hKL, REGISTERWORDENUMPROCW lpfnEnumProc,
+  LPCWSTR lpszReading, DWORD dwStyle,
+  LPCWSTR lpszRegister, LPVOID lpData)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, %p, %s, %ld, %s, %p): stub\n",
+    hKL, lpfnEnumProc, 
+    debugstr_w(lpszReading), dwStyle,
+    debugstr_w(lpszRegister), lpData
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 /***********************************************************************
  *           ImmEscape32A (IMM32.12)
  */
-
-LRESULT WINAPI ImmEscape32A(HKL32 hKL, HIMC32 hIMC, UINT32 uEscape, LPVOID lpData)
+LRESULT WINAPI ImmEscape32A(
+  HKL32 hKL, HIMC32 hIMC, 
+  UINT32 uEscape, LPVOID lpData)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, 0x%08x, %d, %p): stub\n",
+    hKL, hIMC, uEscape, lpData
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 /***********************************************************************
  *           ImmEscape32W (IMM32.13)
  */
-
-LRESULT WINAPI ImmEscape32W(HKL32 hKL, HIMC32 hIMC, UINT32 uEscape, LPVOID lpData)
+LRESULT WINAPI ImmEscape32W(
+  HKL32 hKL, HIMC32 hIMC,
+  UINT32 uEscape, LPVOID lpData)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, 0x%08x, %d, %p): stub\n",
+    hKL, hIMC, uEscape, lpData
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 /***********************************************************************
  *           ImmGetCandidateList32A (IMM32.15)
  */
-
-DWORD WINAPI ImmGetCandidateList32A(HIMC32 hIMC, DWORD deIndex, LPCANDIDATELIST lpCandList, DWORD dwBufLen)
+DWORD WINAPI ImmGetCandidateList32A(
+  HIMC32 hIMC, DWORD deIndex, 
+  LPCANDIDATELIST lpCandList, DWORD dwBufLen)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, %ld, %p, %ld): stub\n",
+    hIMC, deIndex,
+    lpCandList, dwBufLen
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 /***********************************************************************
  *           ImmGetCandidateListCount32A (IMM32.16)
  */
-
-DWORD WINAPI ImmGetCandidateListCount32A(HIMC32 hIMC, LPDWORD lpdwListCount)
+DWORD WINAPI ImmGetCandidateListCount32A(
+  HIMC32 hIMC, LPDWORD lpdwListCount)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, %p): stub\n", hIMC, lpdwListCount);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 /***********************************************************************
  *           ImmGetCandidateListCount32W (IMM32.17)
  */
-
-DWORD WINAPI ImmGetCandidateListCount32W(HIMC32 hIMC, LPDWORD lpdwListCount)
+DWORD WINAPI ImmGetCandidateListCount32W(
+  HIMC32 hIMC, LPDWORD lpdwListCount)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, %p): stub\n", hIMC, lpdwListCount);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 /***********************************************************************
  *           ImmGetCandidateList32W (IMM32.18)
  */
-
-DWORD WINAPI ImmGetCandidateList32W(HIMC32 hIMC, DWORD deIndex, LPCANDIDATELIST lpCandList, DWORD dwBufLen)
+DWORD WINAPI ImmGetCandidateList32W(
+  HIMC32 hIMC, DWORD deIndex, 
+  LPCANDIDATELIST lpCandList, DWORD dwBufLen)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, %ld, %p, %ld): stub\n",
+    hIMC, deIndex,
+    lpCandList, dwBufLen
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 /***********************************************************************
  *           ImmGetCandidateWindow32 (IMM32.19)
  */
-
-BOOL32 WINAPI ImmGetCandidateWindow32(HIMC32 hIMC, DWORD dwBufLen, LPCANDIDATEFORM lpCandidate)
+BOOL32 WINAPI ImmGetCandidateWindow32(
+  HIMC32 hIMC, DWORD dwBufLen, LPCANDIDATEFORM lpCandidate)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %ld, %p): stub\n", hIMC, dwBufLen, lpCandidate);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmGetCompositionFont32A (IMM32.20)
  */
-
 BOOL32 WINAPI ImmGetCompositionFont32A(HIMC32 hIMC, LPLOGFONT32A lplf)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %p): stub\n", hIMC, lplf);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmGetCompositionFont32W (IMM32.21)
  */
-
 BOOL32 WINAPI ImmGetCompositionFont32W(HIMC32 hIMC, LPLOGFONT32W lplf)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %p): stub\n", hIMC, lplf);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmGetCompositionString32A (IMM32.22)
  */
-
-LONG WINAPI ImmGetCompositionString32A(HIMC32 hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
+LONG WINAPI ImmGetCompositionString32A(
+  HIMC32 hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, %ld, %p, %ld): stub\n",
+    hIMC, dwIndex, lpBuf, dwBufLen
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  switch(VERSION_GetVersion())
+    {
+    default:
+      FIXME(imm, "%s not supported",VERSION_GetVersionName());
+    case WIN95:
+      return 0xffffffff;
+    case NT40:
+      return 0;
+    }
 }
 
 /***********************************************************************
  *           ImmGetCompositionString32W (IMM32.23)
  */
-
-LONG WINAPI ImmGetCompositionString32W(HIMC32 hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
+LONG WINAPI ImmGetCompositionString32W(
+  HIMC32 hIMC, DWORD dwIndex, 
+  LPVOID lpBuf, DWORD dwBufLen)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, %ld, %p, %ld): stub\n",
+    hIMC, dwIndex, lpBuf, dwBufLen
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  switch(VERSION_GetVersion())
+    {
+    default:
+      FIXME(imm, "%s not supported",VERSION_GetVersionName());
+    case WIN95:
+      return 0xffffffff;
+    case NT40:
+      return 0;
+    }
 }
 
 /***********************************************************************
  *           ImmGetCompositionWindow32 (IMM32.24)
  */
-
 BOOL32 WINAPI ImmGetCompositionWindow32(HIMC32 hIMC, LPCOMPOSITIONFORM lpCompForm)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, %p): stub\n", hIMC, lpCompForm);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 /***********************************************************************
  *           ImmGetContext32 (IMM32.25)
  */
-
 HIMC32 WINAPI ImmGetContext32(HWND32 hWnd)
 {
-	return NULL;
+  FIXME(imm, "(0x%08x): stub\n", hWnd);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return NULL;
 }
 
 /***********************************************************************
  *           ImmGetConversionList32A (IMM32.26)
  */
-
 DWORD WINAPI ImmGetConversionList32A(
-	HKL32 hKL, HIMC32 hIMC,
-	LPCSTR pSrc, LPCANDIDATELIST lpDst,
-	DWORD dwBufLen, UINT32 uFlag)
+  HKL32 hKL, HIMC32 hIMC,
+  LPCSTR pSrc, LPCANDIDATELIST lpDst,
+  DWORD dwBufLen, UINT32 uFlag)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, 0x%08x, %s, %p, %ld, %d): stub\n",
+    hKL, hIMC, debugstr_a(pSrc), lpDst, dwBufLen, uFlag
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 /***********************************************************************
  *           ImmGetConversionList32W (IMM32.27)
  */
-
 DWORD WINAPI ImmGetConversionList32W(
-	HKL32 hKL, HIMC32 hIMC,
-	LPCWSTR pSrc, LPCANDIDATELIST lpDst,
-	DWORD dwBufLen, UINT32 uFlag)
+  HKL32 hKL, HIMC32 hIMC,
+  LPCWSTR pSrc, LPCANDIDATELIST lpDst,
+  DWORD dwBufLen, UINT32 uFlag)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, 0x%08x, %s, %p, %ld, %d): stub\n",
+    hKL, hIMC, debugstr_w(pSrc), lpDst, dwBufLen, uFlag
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 /***********************************************************************
  *           ImmGetConversionStatus32 (IMM32.28)
  */
-
 BOOL32 WINAPI ImmGetConversionStatus32(
-	HIMC32 hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
+  HIMC32 hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %p, %p): stub\n",
+    hIMC, lpfdwConversion, lpfdwSentence
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmGetDefaultIMEWnd32 (IMM32.29)
  */
-
 HWND32 WINAPI ImmGetDefaultIMEWnd32(HWND32 hWnd)
 {
-	return NULL;
+  FIXME(imm, "(0x%08x): stub\n", hWnd);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return NULL;
 }
 
 /***********************************************************************
  *           ImmGetDescription32A (IMM32.30)
  */
-
-UINT32 WINAPI ImmGetDescription32A(HKL32 hKL, LPSTR lpszDescription, UINT32 uBufLen)
+UINT32 WINAPI ImmGetDescription32A(
+  HKL32 hKL, LPSTR lpszDescription, UINT32 uBufLen)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, %s, %d): stub\n",
+    hKL, debugstr_a(lpszDescription), uBufLen
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 /***********************************************************************
  *           ImmGetDescription32W (IMM32.31)
  */
-
 UINT32 WINAPI ImmGetDescription32W(HKL32 hKL, LPWSTR lpszDescription, UINT32 uBufLen)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, %s, %d): stub\n",
+    hKL, debugstr_w(lpszDescription), uBufLen
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 /***********************************************************************
  *           ImmGetGuideLine32A (IMM32.32)
  */
-
-DWORD WINAPI ImmGetGuideLine32A(HIMC32 hIMC, DWORD dwIndex, LPSTR lpBuf, DWORD dwBufLen)
+DWORD WINAPI ImmGetGuideLine32A(
+  HIMC32 hIMC, DWORD dwIndex, LPSTR lpBuf, DWORD dwBufLen)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, %ld, %s, %ld): stub\n",
+    hIMC, dwIndex, debugstr_a(lpBuf), dwBufLen
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 /***********************************************************************
  *           ImmGetGuideLine32W (IMM32.33)
  */
-
 DWORD WINAPI ImmGetGuideLine32W(HIMC32 hIMC, DWORD dwIndex, LPWSTR lpBuf, DWORD dwBufLen)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, %ld, %s, %ld): stub\n",
+    hIMC, dwIndex, debugstr_w(lpBuf), dwBufLen
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 /***********************************************************************
  *           ImmGetIMEFileName32A (IMM32.38)
  */
-
-UINT32 WINAPI ImmGetIMEFileName32A(HKL32 hKL, LPSTR lpszFileName, UINT32 uBufLen)
+UINT32 WINAPI ImmGetIMEFileName32A(
+  HKL32 hKL, LPSTR lpszFileName, UINT32 uBufLen)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, %s, %d): stub\n",
+    hKL, debugstr_a(lpszFileName), uBufLen
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 /***********************************************************************
  *           ImmGetIMEFileName32W (IMM32.39)
  */
-
-UINT32 WINAPI ImmGetIMEFileName32W(HKL32 hKL, LPWSTR lpszFileName, UINT32 uBufLen)
+UINT32 WINAPI ImmGetIMEFileName32W(
+  HKL32 hKL, LPWSTR lpszFileName, UINT32 uBufLen)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, %s, %d): stub\n",
+    hKL, debugstr_w(lpszFileName), uBufLen
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 /***********************************************************************
  *           ImmGetOpenStatus32 (IMM32.40)
  */
-
 BOOL32 WINAPI ImmGetOpenStatus32(HIMC32 hIMC)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x): stub\n", hIMC);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmGetProperty32 (IMM32.41)
  */
-
 DWORD WINAPI ImmGetProperty32(HKL32 hKL, DWORD fdwIndex)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, %ld): stub\n", hKL, fdwIndex);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 /***********************************************************************
  *           ImmGetRegisterWordStyle32A (IMM32.42)
  */
-
-UINT32 WINAPI ImmGetRegisterWordStyle32A(HKL32 hKL, UINT32 nItem, LPSTYLEBUFA lpStyleBuf)
+UINT32 WINAPI ImmGetRegisterWordStyle32A(
+  HKL32 hKL, UINT32 nItem, LPSTYLEBUFA lpStyleBuf)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 /***********************************************************************
  *           ImmGetRegisterWordStyle32W (IMM32.43)
  */
-
-UINT32 WINAPI ImmGetRegisterWordStyle32W(HKL32 hKL, UINT32 nItem, LPSTYLEBUFW lpStyleBuf)
+UINT32 WINAPI ImmGetRegisterWordStyle32W(
+  HKL32 hKL, UINT32 nItem, LPSTYLEBUFW lpStyleBuf)
 {
-	return 0;
+  FIXME(imm, "(0x%08x, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 /***********************************************************************
  *           ImmGetStatusWindowPos32 (IMM32.44)
  */
-
 BOOL32 WINAPI ImmGetStatusWindowPos32(HIMC32 hIMC, LPPOINT32 lpptPos)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %p): stub\n", hIMC, lpptPos);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmGetVirtualKey32 (IMM32.45)
  */
-
 UINT32 WINAPI ImmGetVirtualKey32(HWND32 hWnd)
 {
-	return 0;
+  FIXME(imm, "(0x%08x): stub\n", hWnd);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  switch(VERSION_GetVersion())
+    {
+    default:
+      FIXME(imm, "%s not supported", VERSION_GetVersionName());
+    case WIN95:
+      return VK_PROCESSKEY;
+    case NT40:
+      return 0;
+    }
 }
 
 /***********************************************************************
  *           ImmInstallIME32A (IMM32.46)
  */
-
-HKL32 WINAPI ImmInstallIME32A(LPCSTR lpszIMEFileName, LPCSTR lpszLayoutText)
+HKL32 WINAPI ImmInstallIME32A(
+  LPCSTR lpszIMEFileName, LPCSTR lpszLayoutText)
 {
-	return NULL;
+  FIXME(imm, "(%s, %s): stub\n",
+    debugstr_a(lpszIMEFileName), debugstr_a(lpszLayoutText)
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return NULL;
 }
 
 /***********************************************************************
  *           ImmInstallIME32W (IMM32.47)
  */
-
-HKL32 WINAPI ImmInstallIME32W(LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
+HKL32 WINAPI ImmInstallIME32W(
+  LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
 {
-	return NULL;
+  FIXME(imm, "(%s, %s): stub\n",
+    debugstr_w(lpszIMEFileName), debugstr_w(lpszLayoutText)
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return NULL;
 }
 
 /***********************************************************************
  *           ImmIsIME32 (IMM32.48)
  */
-
 BOOL32 WINAPI ImmIsIME32(HKL32 hKL)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x): stub\n", hKL);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmIsUIMessage32A (IMM32.49)
  */
-
-BOOL32 WINAPI ImmIsUIMessage32A(HWND32 hWndIME, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
+BOOL32 WINAPI ImmIsUIMessage32A(
+  HWND32 hWndIME, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %d, %d, %ld): stub\n",
+    hWndIME, msg, wParam, lParam
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmIsUIMessage32W (IMM32.50)
  */
-
-BOOL32 WINAPI ImmIsUIMessage32W(HWND32 hWndIME, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
+BOOL32 WINAPI ImmIsUIMessage32W(
+  HWND32 hWndIME, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %d, %d, %ld): stub\n",
+    hWndIME, msg, wParam, lParam
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmNotifyIME32 (IMM32.53)
  */
-
-BOOL32 WINAPI ImmNotifyIME32(HIMC32 hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
+BOOL32 WINAPI ImmNotifyIME32(
+  HIMC32 hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %ld, %ld, %ld): stub\n",
+    hIMC, dwAction, dwIndex, dwValue
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmRegisterWord32A (IMM32.55)
  */
-
-BOOL32 WINAPI ImmRegisterWord32A(HKL32 hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszRegister)
+BOOL32 WINAPI ImmRegisterWord32A(
+  HKL32 hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszRegister)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %s, %ld, %s): stub\n",
+    hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszRegister)
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmRegisterWord32W (IMM32.56)
  */
-
-BOOL32 WINAPI ImmRegisterWord32W(HKL32 hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszRegister)
+BOOL32 WINAPI ImmRegisterWord32W(
+  HKL32 hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszRegister)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %s, %ld, %s): stub\n",
+    hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszRegister)
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmReleaseContext32 (IMM32.57)
  */
-
 BOOL32 WINAPI ImmReleaseContext32(HWND32 hWnd, HIMC32 hIMC)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, 0x%08x): stub\n", hWnd, hIMC);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmSetCandidateWindow32 (IMM32.58)
  */
-
-BOOL32 WINAPI ImmSetCandidateWindow32 (HIMC32 hIMC, LPCANDIDATEFORM lpCandidate)
+BOOL32 WINAPI ImmSetCandidateWindow32(
+  HIMC32 hIMC, LPCANDIDATEFORM lpCandidate)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %p): stub\n", hIMC, lpCandidate);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmSetCompositionFont32A (IMM32.59)
  */
-
 BOOL32 WINAPI ImmSetCompositionFont32A(HIMC32 hIMC, LPLOGFONT32A lplf)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %p): stub\n", hIMC, lplf);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmSetCompositionFont32W (IMM32.60)
  */
-
 BOOL32 WINAPI ImmSetCompositionFont32W(HIMC32 hIMC, LPLOGFONT32W lplf)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %p): stub\n", hIMC, lplf);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmSetCompositionString32A (IMM32.61)
  */
-
 BOOL32 WINAPI ImmSetCompositionString32A(
-	HIMC32 hIMC, DWORD dwIndex, 
-	LPCVOID lpComp, DWORD dwCompLen, 
-	LPCVOID lpRead, DWORD dwReadLen)
+  HIMC32 hIMC, DWORD dwIndex, 
+  LPCVOID lpComp, DWORD dwCompLen, 
+  LPCVOID lpRead, DWORD dwReadLen)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %ld, %p, %ld, %p, %ld): stub\n",
+    hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmSetCompositionString32W (IMM32.62)
  */
-
 BOOL32 WINAPI ImmSetCompositionString32W(
 	HIMC32 hIMC, DWORD dwIndex,
 	LPCVOID lpComp, DWORD dwCompLen,
 	LPCVOID lpRead, DWORD dwReadLen)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %ld, %p, %ld, %p, %ld): stub\n",
+    hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmSetCompositionWindow32 (IMM32.63)
  */
-
-BOOL32 WINAPI ImmSetCompositionWindow32(HIMC32 hIMC, LPCOMPOSITIONFORM lpCompForm)
+BOOL32 WINAPI ImmSetCompositionWindow32(
+  HIMC32 hIMC, LPCOMPOSITIONFORM lpCompForm)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %p): stub\n", hIMC, lpCompForm);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmSetConversionStatus32 (IMM32.64)
  */
-
-BOOL32 WINAPI ImmSetConversionStatus32(HIMC32 hIMC, DWORD fdwConversion, DWORD fdwSentence)
+BOOL32 WINAPI ImmSetConversionStatus32(
+  HIMC32 hIMC, DWORD fdwConversion, DWORD fdwSentence)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %ld, %ld): stub\n",
+    hIMC, fdwConversion, fdwSentence
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmSetOpenStatus32 (IMM32.66)
  */
-
 BOOL32 WINAPI ImmSetOpenStatus32(HIMC32 hIMC, BOOL32 fOpen)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %d): stub\n", hIMC, fOpen);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmSetStatusWindowPos32 (IMM32.67)
  */
-
 BOOL32 WINAPI ImmSetStatusWindowPos32(HIMC32 hIMC, LPPOINT32 lpptPos)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %p): stub\n", hIMC, lpptPos);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
-
 /***********************************************************************
  *           ImmSimulateHotKey32 (IMM32.69)
  */
-
 BOOL32 WINAPI ImmSimulateHotKey32(HWND32 hWnd, DWORD dwHotKeyID)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %ld): stub\n", hWnd, dwHotKeyID);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
  *           ImmUnregisterWord32A (IMM32.72)
  */
-
-BOOL32 WINAPI ImmUnregisterWord32A(HKL32 hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszUnregister)
+BOOL32 WINAPI ImmUnregisterWord32A(
+  HKL32 hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszUnregister)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %s, %ld, %s): stub\n",
+    hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszUnregister)
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
@@ -539,8 +719,12 @@
  *     I haven't been able to find the ordinal for this function,
  *     This means it can't be called from outside the DLL.
  */
-
-BOOL32 WINAPI ImmUnregisterWord32W(HKL32 hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszUnregister)
+BOOL32 WINAPI ImmUnregisterWord32W(
+  HKL32 hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszUnregister)
 {
-	return FALSE;
+  FIXME(imm, "(0x%08x, %s, %ld, %s): stub\n",
+    hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszUnregister)
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
diff --git a/misc/lstr.c b/misc/lstr.c
index b2b4ae0..c121ad4 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -668,7 +668,7 @@
 	if (nSize && talloced<nSize) {
 		target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize);
 	}
-    TRACE(resource,"-- %s\n",target);
+    TRACE(resource,"-- %s\n",debugstr_a(target));
 	if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
 		/* nSize is the MINIMUM size */
 		*((LPVOID*)lpBuffer) = (LPVOID)LocalAlloc32(GMEM_ZEROINIT,talloced);
diff --git a/misc/main.c b/misc/main.c
index 0925f5d..830f984 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -33,24 +33,32 @@
 #include "xmalloc.h"
 #include "version.h"
 
+/* when adding new languages look at ole/ole2nls.c 
+ * for proper iso name and Windows code (add 0x0400 
+ * to the code listed there)
+ */
 const WINE_LANGUAGE_DEF Languages[] =
 {
     {"En",0x0409},	/* LANG_En */
     {"Es",0x040A},	/* LANG_Es */
     {"De",0x0407},	/* LANG_De */
     {"No",0x0414},	/* LANG_No */
-    {"Fr",0x0400},	/* LANG_Fr */
+    {"Fr",0x040C},	/* LANG_Fr */
     {"Fi",0x040B},	/* LANG_Fi */
     {"Da",0x0406},	/* LANG_Da */
-    {"Cz",0x0405},	/* LANG_Cz */
-    {"Eo",0x0425},	/* LANG_Eo */
+    {"Cs",0x0405},	/* LANG_Cs */
+    {"Eo",0x048f},	/* LANG_Eo */
     {"It",0x0410},	/* LANG_It */
     {"Ko",0x0412},	/* LANG_Ko */
-    {"Hu",0x0436},	/* LANG_Hu */
+    {"Hu",0x040e},	/* LANG_Hu */
     {"Pl",0x0415},	/* LANG_Pl */
-    {"Po",0x0416},	/* LANG_Po */
-    {"Sw",0x0417},	/* LANG_Sw */
-    {"Ca",0x0426},	/* LANG_Ca */
+    {"Pt",0x0416},	/* LANG_Pt */
+    {"Sv",0x041d},	/* LANG_Sv */
+    {"Ca",0x0403},	/* LANG_Ca */
+/* for compatibility whith non-iso names previously used */
+    {"Sw",0x041d},      /* LANG_Sv */
+    {"Cz",0x0405},      /* LANG_Cs */
+    {"Po",0x0416},      /* LANG_Pt */
     {NULL,0}
 };
 
@@ -86,7 +94,8 @@
     LANG_En,
 #endif
     FALSE,          /* Managed windows */
-    FALSE           /* Perfect graphics */
+    FALSE,          /* Perfect graphics */
+    NULL            /* Alternate config file name */
 };
 
 
@@ -109,7 +118,8 @@
     { "-failreadonly",  ".failreadonly",    XrmoptionNoArg,  (caddr_t)"on" },
     { "-mode",          ".mode",            XrmoptionSepArg, (caddr_t)NULL },
     { "-managed",       ".managed",         XrmoptionNoArg,  (caddr_t)"off"},
-    { "-winver",        ".winver",          XrmoptionSepArg, (caddr_t)NULL }
+    { "-winver",        ".winver",          XrmoptionSepArg, (caddr_t)NULL },
+    { "-config",        ".config",          XrmoptionSepArg, (caddr_t)NULL }
 };
 
 #define NB_OPTIONS  (sizeof(optionsTable) / sizeof(optionsTable[0]))
@@ -120,6 +130,7 @@
   "\n" \
   "Options:\n" \
   "    -backingstore   Turn on backing store\n" \
+  "    -config name    Specify config file to use\n" \
   "    -debug          Enter debugger before starting application\n" \
   "    -debugmsg name  Turn debugging-messages on or off\n" \
   "    -depth n        Change the depth to use for multiple-depth screens\n" \
@@ -130,7 +141,7 @@
   "    -fixedmap       Use a \"standard\" color map\n" \
   "    -help           Show this help message\n" \
   "    -iconic         Start as an icon\n" \
-  "    -language xx    Set the language (one of En,Es,De,No,Fr,Fi,Da,Cz,Eo,It,Ko,\n                    Hu,Pl,Po,Sw,Ca)\n" \
+  "    -language xx    Set the language (one of Ca,Cs,Da,De,En,Eo,Es,Fi,Fr,Hu,It,\n                    Ko,No,Pl,Pt,Sv)\n" \
   "    -managed        Allow the window manager to manage created windows\n" \
   "    -mode mode      Start Wine in a particular mode (standard or enhanced)\n" \
   "    -name name      Set the application name\n" \
@@ -502,6 +513,8 @@
 
       if (MAIN_GetResource( db, ".winver", &value))
           VERSION_ParseVersion( (char*)value.addr );
+      if (MAIN_GetResource( db, ".config", &value))
+         Options.configFileName = xstrdup((char *)value.addr);
 }
 
 
@@ -1189,6 +1202,6 @@
 */
 FARPROC16 WINAPI FileCDR(FARPROC16 x)
 {
-	FIXME(file,"(%8x): stub\n", (int) x);
+	FIXME(file,"(0x%8x): stub\n", (int) x);
 	return (FARPROC16)TRUE;
 }
diff --git a/misc/ntdll.c b/misc/ntdll.c
index 48188aa..5c91328 100644
--- a/misc/ntdll.c
+++ b/misc/ntdll.c
@@ -624,7 +624,7 @@
  */
 DWORD WINAPI NtQueryObject( DWORD x1, DWORD x2 ,DWORD x3, DWORD x4, DWORD x5 )
 {
-    FIXME(ntdll,"(%lx,%lx,%lx,%lx,%lx): stub\n",x1,x2,x3,x4,x5);
+    FIXME(ntdll,"(0x%lx,%lx,%lx,%lx,%lx): stub\n",x1,x2,x3,x4,x5);
     return 0;
 }
 
diff --git a/misc/printdrv.c b/misc/printdrv.c
index a2146e5..bb9e2d1 100644
--- a/misc/printdrv.c
+++ b/misc/printdrv.c
@@ -237,11 +237,12 @@
 BOOL32 WINAPI OpenPrinter32A(LPSTR lpPrinterName,HANDLE32 *phPrinter,
 			     LPPRINTER_DEFAULTS32A pDefault)
 {
-    FIXME(print,"(%s,%p,%p):stub.\n",
-	    lpPrinterName, phPrinter, pDefault);
+    FIXME(print,"(%s,%p,%p):stub\n",debugstr_a(lpPrinterName), phPrinter,
+          pDefault);
     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     return FALSE;
 }
+
 BOOL32  WINAPI EnumPrinters32A(DWORD dwType, LPSTR lpszName,
 			       DWORD dwLevel, LPBYTE lpbPrinters,
 			       DWORD cbBuf, LPDWORD lpdwNeeded,
@@ -264,7 +265,8 @@
 BOOL32 WINAPI
 DeletePrinterDriver32A (LPSTR pName, LPSTR pEnvironment, LPSTR pDriverName)
 {
-    FIXME(print, "(%s,%s,%s):stub!\n", pName, pEnvironment, pDriverName);
+    FIXME(print,"(%s,%s,%s):stub\n",debugstr_a(pName),debugstr_a(pEnvironment),
+          debugstr_a(pDriverName));
     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     return FALSE;
 }
@@ -273,7 +275,8 @@
 BOOL32 WINAPI
 DeleteMonitor32A (LPSTR pName, LPSTR pEnvironment, LPSTR pMonitorName)
 {
-    FIXME(print, "(%s,%s,%s):stub!\n", pName, pEnvironment, pMonitorName);
+    FIXME(print,"(%s,%s,%s):stub\n",debugstr_a(pName),debugstr_a(pEnvironment),
+          debugstr_a(pMonitorName));
     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     return FALSE;
 }
@@ -282,7 +285,8 @@
 BOOL32 WINAPI
 DeletePort32A (LPSTR pName, HWND32 hWnd, LPSTR pPortName)
 {
-    FIXME(print, "(%s,0x%08x,%s):stub!\n", pName, hWnd, pPortName);
+    FIXME(print,"(%s,0x%08x,%s):stub\n",debugstr_a(pName),hWnd,
+          debugstr_a(pPortName));
     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     return FALSE;
 }
diff --git a/misc/registry.c b/misc/registry.c
index b0b81a8..67ac246 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -23,6 +23,7 @@
 #include <unistd.h>
 #include <ctype.h>
 #include <errno.h>
+#include <sys/errno.h>
 #include <sys/types.h>
 #include <sys/fcntl.h>
 #include <sys/stat.h>
diff --git a/misc/tweak.c b/misc/tweak.c
index 952e141..9ce44e0 100644
--- a/misc/tweak.c
+++ b/misc/tweak.c
@@ -21,102 +21,22 @@
  *   Revision history
  *        03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
  *             Original implementation.
- *
  *        05-Aug-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
  *             Removed some unused code.
+ *        22-Sep-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ *             Removed more unused code.
  *
  *****************************************************************************/
 
-#include <malloc.h>
-#include "ts_xlib.h"
 #include <string.h>
-#include "dc.h"
-#include "debug.h"
-#include "graphics.h"
-#include "options.h"
-#include "stackframe.h"
-#include "tweak.h"
 #include "windows.h"
-
-
-/* Parameters for controls/menu.c */
-extern UINT32  MENU_BarItemTopNudge;
-extern UINT32  MENU_BarItemLeftNudge;
-extern UINT32  MENU_ItemTopNudge;
-extern UINT32  MENU_ItemLeftNudge;
-extern UINT32  MENU_HighlightTopNudge;
-extern UINT32  MENU_HighlightLeftNudge;
-extern UINT32  MENU_HighlightBottomNudge;
-extern UINT32  MENU_HighlightRightNudge;
-
+#include "tweak.h"
+#include "options.h"
+#include "debug.h"
 
 /* General options */
-#if defined(WIN_95_LOOK)
-int  TWEAK_Win95Look = 1;
-#else
-int  TWEAK_Win95Look = 0;
-#endif
 
-int  TWEAK_WineInitialized = 0;
-
-
-/******************************************************************************
- *
- *   int  TWEAK_MenuInit()
- * 
- *   Initializes the Win95 tweaks to the menu code.  See controls/menu.c.
- *   Return value indicates success (non-zero) or failure.
- *
- *   Revision history
- *        06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
- *             Original implementation.
- *
- *****************************************************************************/
-
-static int  TWEAK_MenuInit()
-{
-    MENU_BarItemTopNudge =
-	PROFILE_GetWineIniInt("Tweak.Layout", "MenuBarItemTopNudge", 0);
-    MENU_BarItemLeftNudge =
-	PROFILE_GetWineIniInt("Tweak.Layout", "MenuBarItemLeftNudge", 0);
-    MENU_ItemTopNudge =
-	PROFILE_GetWineIniInt("Tweak.Layout", "MenuItemTopNudge", 0);
-    MENU_ItemLeftNudge =
-	PROFILE_GetWineIniInt("Tweak.Layout", "MenuItemLeftNudge", 0);
-    MENU_HighlightTopNudge =
-	PROFILE_GetWineIniInt("Tweak.Layout", "MenuHighlightTopNudge", 0);
-    MENU_HighlightLeftNudge =
-	PROFILE_GetWineIniInt("Tweak.Layout", "MenuHighlightLeftNudge", 0);
-    MENU_HighlightBottomNudge =
-	PROFILE_GetWineIniInt("Tweak.Layout", "MenuHighlightBottomNudge", 0);
-    MENU_HighlightRightNudge =
-	PROFILE_GetWineIniInt("Tweak.Layout", "MenuHighlightRightNudge", 0);
-
-    return 1;
-}
-
-
-/******************************************************************************
- *
- *   int  TWEAK_VarInit()
- *
- *   Initializes the miscellaneous variables which are used in the tweak
- *   routines.  Return value is non-zero on success.
- *
- *   Revision history
- *        07-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
- *             Original implementation.
- *
- *****************************************************************************/
-
-static int  TWEAK_VarInit()
-{
-    TWEAK_Win95Look = PROFILE_GetWineIniBool("Tweak.Layout", "Win95Look", 0);
-
-    TRACE(tweak, "Using %s look and feel.\n",
-		 TWEAK_Win95Look ? "Win95" : "Win3.1");
-    return 1;
-}
+WINE_LOOK TWEAK_WineLook = WIN31_LOOK;
 
 
 /******************************************************************************
@@ -129,13 +49,50 @@
  *   Revision history
  *        05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
  *             Original implementation.
+ *        22-Sep-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ *             Removed unused code and added Win98 option.
  *
  *****************************************************************************/
 
-int  TWEAK_Init()
+int TWEAK_Init (void)
 {
-    TWEAK_VarInit();
-    TWEAK_MenuInit();
+    char szIniString[80];
+
+    PROFILE_GetWineIniString ("Tweak.Layout", "Win95Look", "TestString",
+			      szIniString, 80);
+    if (strncmp (szIniString, "TestString", 10)) {
+	if (PROFILE_GetWineIniBool ("Tweak.Layout", "Win95Look", 0)) {
+	    TWEAK_WineLook = WIN95_LOOK;
+	    TRACE (tweak, "Using Win95 look and feel.\n");
+	}
+	else {
+	    TWEAK_WineLook = WIN31_LOOK;
+	    TRACE (tweak, "Using Win3.1 look and feel.\n");
+	}
+	ERR (tweak,
+	     "Replace \"Win95Look\" by \"WineLook\" in your \"wine.ini\"!\n");
+    }
+
+    PROFILE_GetWineIniString ("Tweak.Layout", "WineLook", "Win31",
+			      szIniString, 80);
+
+    if (!strncasecmp (szIniString, "Win31", 5)) {
+	TWEAK_WineLook = WIN31_LOOK;
+	TRACE (tweak, "Using Win3.1 look and feel.\n");
+    }
+    else if (!strncasecmp (szIniString, "Win95", 5)) {
+	TWEAK_WineLook = WIN95_LOOK;
+	TRACE (tweak, "Using Win95 look and feel.\n");
+    }
+    else if (!strncasecmp (szIniString, "Win98", 5)) {
+	TWEAK_WineLook = WIN98_LOOK;
+	TRACE (tweak, "Using Win98 look and feel.\n");
+    }
+    else {
+	TWEAK_WineLook = WIN31_LOOK;
+	TRACE (tweak, "Using Win3.1 look and feel.\n");
+    }
+
     return 1;
 }
 
@@ -156,247 +113,3 @@
 {
     return 1;
 }
-
-
-/******************************************************************************
- *
- *     Tweak graphic subsystem.
- *
- *****************************************************************************/
-
-/******************************************************************************
- *
- *   void  TWEAK_DrawReliefRect95(
- *      HDC32  hdc,               // Device context on which to draw
- *      RECT32 const  *rect )     // Rectangle to use
- *
- *   Draws the double-bordered Win95-style relief rectangle.
- *
- *   Bugs
- *        There are some checks missing from this function.  Perhaps the
- *        SelectObject32 calls should be examined?  Hasn't failed on me (yet).
- *
- *        Should I really be calling X functions directly from here?  It is
- *        an optimization, but should I be optimizing alpha code?  Probably
- *        not.
- *
- *   Revision history
- *        08-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
- *             Original implementation.
- *
- *****************************************************************************/
-
-void  TWEAK_DrawReliefRect95(
-    HDC32  hdc,
-    RECT32 const  *rect )
-{
-    DC  *dc;
-    HPEN32  prevpen;
-
-    if((dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC))) {
-
-	/* Draw the top/left lines first */
-	prevpen = SelectObject32(hdc, GetSysColorPen32(COLOR_3DLIGHT));
-	DC_SetupGCForPen(dc);
-	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top,
-		  rect->right - 1, rect->top);
-	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top,
-		  rect->left, rect->bottom - 1);
-
-	SelectObject32(hdc, GetSysColorPen32(COLOR_3DHIGHLIGHT));
-	DC_SetupGCForPen(dc);
-	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
-		  rect->top + 1, rect->right - 2, rect->top + 1);
-	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
-		  rect->top + 1, rect->left + 1, rect->bottom - 2);
-
-
-	/* Now the bottom/right lines */
-	SelectObject32(hdc, GetSysColorPen32(COLOR_3DDKSHADOW));
-	DC_SetupGCForPen(dc);
-	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left,
-		  rect->bottom - 1, rect->right - 1, rect->bottom - 1);
-	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 1,
-		  rect->top, rect->right - 1, rect->bottom - 1);
-
-	SelectObject32(hdc, GetSysColorPen32(COLOR_3DSHADOW));
-	DC_SetupGCForPen(dc);
-	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
-		  rect->bottom - 2, rect->right - 2, rect->bottom - 2);
-	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 2,
-		  rect->top + 1, rect->right - 2, rect->bottom - 2);
-	
-	SelectObject32(hdc, prevpen);
-    }
-
-    return;
-}
-
-
-/******************************************************************************
- *
- *   void  TWEAK_DrawRevReliefRect95(
- *      HDC32  hdc,               // Device context on which to draw
- *      RECT32 const  *rect )     // Rectangle to use
- *
- *   Draws the double-bordered Win95-style relief rectangle.
- *
- *   Bugs
- *        There are some checks missing from this function.  Perhaps the
- *        SelectObject32 calls should be examined?  Hasn't failed on me (yet).
- *
- *        Should I really be calling X functions directly from here?  It is
- *        an optimization, but should I be optimizing alpha code?  Probably
- *        not.
- *
- *   Revision history
- *        08-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
- *             Original implementation.
- *
- *****************************************************************************/
-
-void  TWEAK_DrawRevReliefRect95(
-    HDC32  hdc,
-    RECT32 const  *rect )
-{
-    DC  *dc;
-    HPEN32  prevpen;
-
-    if((dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC))) {
-
-	/* Draw the top/left lines first */
-	prevpen = SelectObject32(hdc, GetSysColorPen32(COLOR_3DSHADOW));
-	DC_SetupGCForPen(dc);
-	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top,
-		  rect->right - 1, rect->top);
-	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top,
-		  rect->left, rect->bottom - 1);
-
-	SelectObject32(hdc, GetSysColorPen32(COLOR_3DDKSHADOW));
-	DC_SetupGCForPen(dc);
-	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
-		  rect->top + 1, rect->right - 2, rect->top + 1);
-	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
-		  rect->top + 1, rect->left + 1, rect->bottom - 2);
-
-
-	/* Now the bottom/right lines */
-	SelectObject32(hdc, GetSysColorPen32(COLOR_3DHIGHLIGHT));
-	DC_SetupGCForPen(dc);
-	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left,
-		  rect->bottom - 1, rect->right - 1, rect->bottom - 1);
-	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 1,
-		  rect->top, rect->right - 1, rect->bottom - 1);
-
-	SelectObject32(hdc, GetSysColorPen32(COLOR_3DLIGHT));
-	DC_SetupGCForPen(dc);
-	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
-		  rect->bottom - 2, rect->right - 2, rect->bottom - 2);
-	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 2,
-		  rect->top + 1, rect->right - 2, rect->bottom - 2);
-	
-	SelectObject32(hdc, prevpen);
-    }
-
-    return;
-}
-
-
-
-/******************************************************************************
- *
- *   void  TWEAK_DrawMenuSeparatorHoriz95(
- *      HDC32  hdc,               // Device context on which to draw
- *      UINT32  xc1,              // Left x-coordinate
- *      UINT32  yc,               // Y-coordinate of the LOWER line
- *      UINT32  xc2 )             // Right x-coordinate
- *
- *   Draws a horizontal menu separator bar Win 95 style.
- *
- *   Bugs
- *        Same as those for DrawReliefRect95.
- *
- *   Revision history
- *        08-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
- *             Original implementation.
- *        11-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
- *             Changed name from DrawMenuSeparator95
- *
- *****************************************************************************/
-
-void  TWEAK_DrawMenuSeparatorHoriz95(
-    HDC32  hdc,
-    UINT32  xc1,
-    UINT32  yc,
-    UINT32  xc2 )
-{
-    DC  *dc;
-    HPEN32  prevpen;
-
-    if((dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC))) {
-
-	/* Draw the top line */
-	prevpen = SelectObject32(hdc, GetSysColorPen32(COLOR_3DSHADOW));
-	DC_SetupGCForPen(dc);
-	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc1, yc - 1, xc2,
-		  yc - 1);
-
-	/* And the bottom line */
-	SelectObject32(hdc, GetSysColorPen32(COLOR_3DHIGHLIGHT));
-	DC_SetupGCForPen(dc);
-	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc1, yc, xc2, yc);
-
-	SelectObject32(hdc, prevpen);
-    }
-
-    return;
-}
-
-
-/******************************************************************************
- *
- *   void  TWEAK_DrawMenuSeparatorVert95(
- *      HDC32  hdc,               // Device context on which to draw
- *      UINT32  xc,               // X-coordinate of the RIGHT line
- *      UINT32  yc1,              // top Y-coordinate
- *      UINT32  yc2 )             // bottom Y-coordinate
- *
- *   Draws a vertical menu separator bar Win 95 style.
- *
- *   Bugs
- *        Same as those for DrawReliefRect95.
- *
- *   Revision history
- *        11-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
- *             Original implementation.
- *
- *****************************************************************************/
-
-void  TWEAK_DrawMenuSeparatorVert95(
-    HDC32  hdc,
-    UINT32  xc,
-    UINT32  yc1,
-    UINT32  yc2 )
-{
-    DC  *dc;
-    HPEN32  prevpen;
-
-    if((dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC))) {
-
-	/* Draw the top line */
-	prevpen = SelectObject32(hdc, GetSysColorPen32(COLOR_3DSHADOW));
-	DC_SetupGCForPen(dc);
-	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc, yc1, xc,
-		  yc2);
-
-	/* And the bottom line */
-	SelectObject32(hdc, GetSysColorPen32(COLOR_3DHIGHLIGHT));
-	DC_SetupGCForPen(dc);
-	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc + 1, yc1, xc + 1,
-		  yc2);
-
-	SelectObject32(hdc, prevpen);
-    }
-
-    return;
-}
diff --git a/misc/version.c b/misc/version.c
index 181588f..45c1486 100644
--- a/misc/version.c
+++ b/misc/version.c
@@ -3,6 +3,7 @@
  *
  * Copyright 1997 Alexandre Julliard
  * Copyright 1997 Marcus Meissner
+ * Copyright 1998 Patrik Stridvall
  */
 
 #include <string.h>
@@ -12,15 +13,7 @@
 #include "options.h"
 #include "debug.h"
 #include "ole.h"
-
-typedef enum
-{
-    WIN31, /* Windows 3.1 */
-    WIN95, /* Windows 95 */
-    NT351, /* Windows NT 3.51 */
-    NT40,  /* Windows NT 4.0 */
-    NB_VERSIONS
-} VERSION;
+#include "winversion.h"
 
 typedef struct
 {
@@ -31,7 +24,7 @@
 
 
 /* FIXME: compare values below with original and fix */
-static const VERSION_DATA VersionData[NB_VERSIONS] =
+static const VERSION_DATA VersionData[NB_WINDOWS_VERSIONS] =
 {
     /* WIN31 */
     {
@@ -71,7 +64,7 @@
     }
 };
 
-static const char *VersionNames[NB_VERSIONS] =
+static const char *VersionNames[NB_WINDOWS_VERSIONS] =
 {
     "win31",
     "win95",
@@ -81,7 +74,7 @@
 
 /* the current version has not been autodetected but forced via cmdline */
 static BOOL32 versionForced = FALSE;
-static VERSION defaultVersion = WIN31;
+static WINDOWS_VERSION defaultVersion = WIN31;
 
 
 /**********************************************************************
@@ -90,27 +83,27 @@
 void VERSION_ParseVersion( char *arg )
 {
     int i;
-    for (i = 0; i < NB_VERSIONS; i++)
+    for (i = 0; i < NB_WINDOWS_VERSIONS; i++)
     {
         if (!strcmp( VersionNames[i], arg ))
         {
-            defaultVersion = (VERSION)i;
+            defaultVersion = (WINDOWS_VERSION)i;
             versionForced = TRUE;
             return;
         }
     }
     MSG("Invalid winver value '%s' specified.\n", arg );
     MSG("Valid versions are:" );
-    for (i = 0; i < NB_VERSIONS; i++)
+    for (i = 0; i < NB_WINDOWS_VERSIONS; i++)
         MSG(" '%s'%c", VersionNames[i],
-	    (i == NB_VERSIONS - 1) ? '\n' : ',' );
+	    (i == NB_WINDOWS_VERSIONS - 1) ? '\n' : ',' );
 }
 
 
 /**********************************************************************
- *         VERSION_get_version
+ *         VERSION_GetVersion
  */
-static VERSION VERSION_GetVersion(void)
+WINDOWS_VERSION VERSION_GetVersion(void)
 {
     LPIMAGE_NT_HEADERS peheader;	
 
@@ -143,12 +136,34 @@
 }
 
 
+/**********************************************************************
+ *         VERSION_GetVersionName
+ */
+char *VERSION_GetVersionName()
+{
+  WINDOWS_VERSION ver = VERSION_GetVersion();
+  switch(ver)
+    {
+    case WIN31:
+      return "Windows 3.1";
+    case WIN95:  
+      return "Windows 95";
+    case NT351:
+      return "Windows NT 3.51";
+    case NT40:
+      return "Windows NT 4.0";
+    default:
+      FIXME(ver,"Windows version %d not named",ver);
+      return "Windows <Unknown>";
+    }
+}
+
 /***********************************************************************
  *         GetVersion16   (KERNEL.3)
  */
 LONG WINAPI GetVersion16(void)
 {
-    VERSION ver = VERSION_GetVersion();
+    WINDOWS_VERSION ver = VERSION_GetVersion();
     return VersionData[ver].getVersion16;
 }
 
@@ -158,7 +173,7 @@
  */
 LONG WINAPI GetVersion32(void)
 {
-    VERSION ver = VERSION_GetVersion();
+    WINDOWS_VERSION ver = VERSION_GetVersion();
     return VersionData[ver].getVersion32;
 }
 
@@ -168,7 +183,7 @@
  */
 BOOL16 WINAPI GetVersionEx16(OSVERSIONINFO16 *v)
 {
-    VERSION ver = VERSION_GetVersion();
+    WINDOWS_VERSION ver = VERSION_GetVersion();
     if (v->dwOSVersionInfoSize != sizeof(OSVERSIONINFO16))
     {
         WARN(ver,"wrong OSVERSIONINFO size from app");
@@ -188,7 +203,7 @@
  */
 BOOL32 WINAPI GetVersionEx32A(OSVERSIONINFO32A *v)
 {
-    VERSION ver = VERSION_GetVersion();
+    WINDOWS_VERSION ver = VERSION_GetVersion();
     if (v->dwOSVersionInfoSize != sizeof(OSVERSIONINFO32A))
     {
         WARN(ver,"wrong OSVERSIONINFO size from app");
@@ -208,7 +223,8 @@
  */
 BOOL32 WINAPI GetVersionEx32W(OSVERSIONINFO32W *v)
 {
-    VERSION ver = VERSION_GetVersion();
+    WINDOWS_VERSION ver = VERSION_GetVersion();
+
     if (v->dwOSVersionInfoSize!=sizeof(OSVERSIONINFO32W))
     {
         WARN(ver,"wrong OSVERSIONINFO size from app");
@@ -319,7 +335,7 @@
 void WINAPI DiagOutput(LPCSTR str)
 {
         /* FIXME */
-	DPRINTF("DIAGOUTPUT:%s\n",str);
+	DPRINTF("DIAGOUTPUT:%s\n", debugstr_a(str));
 }
 
 /***********************************************************************
@@ -327,7 +343,7 @@
  */
 UINT32 WINAPI OaBuildVersion()
 {
-    VERSION ver = VERSION_GetVersion();
+    WINDOWS_VERSION ver = VERSION_GetVersion();
 
     switch(VersionData[ver].getVersion32)
     {
diff --git a/misc/winsock.c b/misc/winsock.c
index b328794..0fb8a1a 100644
--- a/misc/winsock.c
+++ b/misc/winsock.c
@@ -41,6 +41,7 @@
 #include <ctype.h>
 #include <fcntl.h>
 #include <errno.h>
+#include <sys/errno.h>
 #include <netdb.h>
 #include <unistd.h>
 
diff --git a/miscemu/instr.c b/miscemu/instr.c
index 41eaa5b..91d42b5 100644
--- a/miscemu/instr.c
+++ b/miscemu/instr.c
@@ -7,6 +7,7 @@
 #include "windows.h"
 #include "ldt.h"
 #include "global.h"
+#include "module.h"
 #include "miscemu.h"
 #include "sig_context.h"
 #include "debug.h"
@@ -295,6 +296,7 @@
 BOOL32 INSTR_EmulateInstruction( SIGCONTEXT *context )
 {
     int prefix, segprefix, prefixlen, len, repX, long_op, long_addr;
+    SEGPTR gpHandler;
     BYTE *instr;
 
     /* Check for page-fault */
@@ -573,7 +575,7 @@
             }
             else
             {
-                FARPROC16 addr = INT_GetHandler( instr[1] );
+                FARPROC16 addr = INT_GetPMHandler( instr[1] );
                 WORD *stack = (WORD *)STACK_PTR( context );
                 /* Push the flags and return address on the stack */
                 *(--stack) = FL_sig(context);
@@ -657,6 +659,23 @@
   	    EIP_sig(context) += prefixlen + 1;
             return TRUE;
     }
+
+
+    /* Check for Win16 __GP handler */
+    gpHandler = HasGPHandler( PTR_SEG_OFF_TO_SEGPTR( CS_sig(context),
+                                                     EIP_sig(context) ) );
+    if (gpHandler)
+    {
+        WORD *stack = (WORD *)STACK_PTR( context );
+        *--stack = CS_sig(context);
+        *--stack = EIP_sig(context);
+        STACK_sig(context) -= 2*sizeof(WORD);
+
+        CS_sig(context) = SELECTOROF( gpHandler );
+        EIP_sig(context) = OFFSETOF( gpHandler );
+        return TRUE;
+    }
+
     MSG("Unexpected Windows program segfault"
                     " - opcode = %x\n", *instr);
     return FALSE;  /* Unable to emulate it */
diff --git a/msdos/dosmem.c b/msdos/dosmem.c
index 85ee94d..267b6a4 100644
--- a/msdos/dosmem.c
+++ b/msdos/dosmem.c
@@ -102,13 +102,13 @@
   unsigned      free;
 } dosmem_info;
 
-static dosmem_entry* 	root_block = NULL;
-static dosmem_info*	info_block = NULL;
-
 #define NEXT_BLOCK(block) \
         (dosmem_entry*)(((char*)(block)) + \
 	 sizeof(dosmem_entry) + ((block)->size & DM_BLOCK_MASK))
 
+#define VM_STUB(x) (0x90CF00CD|(x<<8)) /* INT x; IRET; NOP */
+#define VM_STUB_SEGMENT 0xf000         /* BIOS segment */
+
 /***********************************************************************
  *           DOSMEM_MemoryBase
  *
@@ -125,7 +125,7 @@
     else
         return DOSMEM_dosmem;
 }
-                                                            
+
 /***********************************************************************
  *           DOSMEM_MemoryTop
  *
@@ -135,7 +135,51 @@
 {
     return DOSMEM_MemoryBase(hModule)+0x9FFFC; /* 640K */
 }
-                                                            
+
+/***********************************************************************
+ *           DOSMEM_InfoBlock
+ *
+ * Gets the DOS memory info block.
+ */
+static dosmem_info *DOSMEM_InfoBlock(HMODULE16 hModule)
+{
+    return (dosmem_info*)(DOSMEM_MemoryBase(hModule)+0x10000); /* 64K */
+}
+
+/***********************************************************************
+ *           DOSMEM_RootBlock
+ *
+ * Gets the DOS memory root block.
+ */
+static dosmem_entry *DOSMEM_RootBlock(HMODULE16 hModule)
+{
+    /* first block has to be paragraph-aligned */
+    return (dosmem_entry*)(((char*)DOSMEM_InfoBlock(hModule)) +
+                           ((((sizeof(dosmem_info) + 0xf) & ~0xf) - sizeof(dosmem_entry))));
+}
+
+/***********************************************************************
+ *           DOSMEM_FillIsrTable
+ *
+ * Fill the interrupt table with fake BIOS calls to BIOSSEG (0xf000).
+ *
+ * NOTES:
+ * Linux normally only traps INTs performed from or destined to BIOSSEG
+ * for us to handle, if the int_revectored table is empty. Filling the
+ * interrupt table with calls to INT stubs in BIOSSEG allows DOS programs
+ * to hook interrupts, as well as use their familiar retf tricks to call
+ * them, AND let Wine handle any unhooked interrupts transparently.
+ */
+static void DOSMEM_FillIsrTable(HMODULE16 hModule)
+{
+    SEGPTR *isr = (SEGPTR*)DOSMEM_MemoryBase(hModule);
+    DWORD *stub = (DWORD*)((char*)isr + (VM_STUB_SEGMENT << 4));
+    int x;
+ 
+    for (x=0; x<256; x++) isr[x]=PTR_SEG_OFF_TO_SEGPTR(VM_STUB_SEGMENT,x*4);
+    for (x=0; x<256; x++) stub[x]=VM_STUB(x);
+} 
+
 /***********************************************************************
  *           DOSMEM_FillBiosSegment
  *
@@ -252,16 +296,10 @@
    /* Low 64Kb are reserved for DOS/BIOS so the useable area starts at
     * 1000:0000 and ends at 9FFF:FFEF. */
 
-    char*               dosmem = DOSMEM_MemoryBase(hModule);
+    dosmem_info*        info_block = DOSMEM_InfoBlock(hModule);
+    dosmem_entry*       root_block = DOSMEM_RootBlock(hModule);
     dosmem_entry*       dm;
 
-    /* FIXME: these static variables can't cope with several DOS heaps */
-    info_block = (dosmem_info*)( dosmem + 0x10000 );
-
-    /* first block has to be paragraph-aligned relative to the DOSMEM_dosmem */
-
-    root_block = (dosmem_entry*)( dosmem + 0x10000 +
-                 ((((sizeof(dosmem_info) + 0xf) & ~0xf) - sizeof(dosmem_entry))));
     root_block->size = DOSMEM_MemoryTop(hModule) - (((char*)root_block) + sizeof(dosmem_entry));
 
     info_block->blocks = 0;
@@ -299,13 +337,22 @@
         }
         DOSMEM_BiosSeg = GLOBAL_CreateBlock(GMEM_FIXED,DOSMEM_dosmem+0x400,0x100,
                                         0, FALSE, FALSE, FALSE, NULL );
+        DOSMEM_FillIsrTable(0);
         DOSMEM_FillBiosSegment();
         DOSMEM_InitMemory(0);
         DOSMEM_InitCollateTable();
         DOSMEM_InitErrorTable();
     }
     else
+    {
+#if 0
+        DOSMEM_FillIsrTable(hModule);
         DOSMEM_InitMemory(hModule);
+#else
+        /* bootstrap the new V86 task with a copy of the "system" memory */
+        memcpy(DOSMEM_MemoryBase(hModule), DOSMEM_dosmem, 0x100000);
+#endif
+    }
     return TRUE;
 }
 
@@ -329,13 +376,14 @@
 {
    UINT32  	 blocksize;
    char         *block = NULL;
+   dosmem_info  *info_block = DOSMEM_InfoBlock(hModule);
    dosmem_entry *dm;
 #ifdef __DOSMEM_DEBUG_
    dosmem_entry *prev = NULL;
 #endif
  
    if( size > info_block->free ) return NULL;
-   dm = root_block;
+   dm = DOSMEM_RootBlock(hModule);
 
    while (dm && dm->size != DM_BLOCK_TERMINAL)
    {
@@ -399,7 +447,9 @@
  */
 BOOL32 DOSMEM_FreeBlock(HMODULE16 hModule, void* ptr)
 {
-   if( ptr >= (void*)(((char*)root_block) + sizeof(dosmem_entry)) &&
+   dosmem_info  *info_block = DOSMEM_InfoBlock(hModule);
+
+   if( ptr >= (void*)(((char*)DOSMEM_RootBlock(hModule)) + sizeof(dosmem_entry)) &&
        ptr < (void*)DOSMEM_MemoryTop(hModule) && !((((char*)ptr)
                   - DOSMEM_MemoryBase(hModule)) & 0xf) )
    {
@@ -427,8 +477,9 @@
 LPVOID DOSMEM_ResizeBlock(HMODULE16 hModule, void* ptr, UINT32 size, UINT16* pseg)
 {
    char         *block = NULL;
+   dosmem_info  *info_block = DOSMEM_InfoBlock(hModule);
 
-   if( ptr >= (void*)(((char*)root_block) + sizeof(dosmem_entry)) &&
+   if( ptr >= (void*)(((char*)DOSMEM_RootBlock(hModule)) + sizeof(dosmem_entry)) &&
        ptr < (void*)DOSMEM_MemoryTop(hModule) && !((((char*)ptr)
                   - DOSMEM_MemoryBase(hModule)) & 0xf) )
    {
@@ -491,7 +542,7 @@
    UINT32  	 blocksize, available = 0;
    dosmem_entry *dm;
    
-   dm = root_block;
+   dm = DOSMEM_RootBlock(hModule);
 
    while (dm && dm->size != DM_BLOCK_TERMINAL)
    {
diff --git a/msdos/dpmi.c b/msdos/dpmi.c
index 48ae756..66fb5bb 100644
--- a/msdos/dpmi.c
+++ b/msdos/dpmi.c
@@ -14,6 +14,8 @@
 #include "miscemu.h"
 #include "drive.h"
 #include "msdos.h"
+#include "task.h"
+#include "dosexe.h"
 #include "toolhelp.h"
 #include "debug.h"
 #include "selectors.h"
@@ -189,7 +191,7 @@
     INT_GetRealModeContext( call, &realmode_ctx );
 
     RESET_CFLAG(context);
-    if (INT_RealModeInterrupt( BL_reg(context), context ))
+    if (INT_RealModeInterrupt( BL_reg(context), &realmode_ctx ))
       SET_CFLAG(context);
     if (EFL_reg(context)&1) {
       FIXME(int31,"%02x: EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n",
@@ -326,6 +328,44 @@
     }
 }
 
+#ifdef MZ_SUPPORTED
+/* (see loader/dos/module.c, function MZ_InitDPMI) */
+
+static void StartPM( CONTEXT *context, LPDOSTASK lpDosTask )
+{
+    char *base = DOSMEM_MemoryBase(0);
+    UINT16 cs, ss, ds, es;
+    CONTEXT pm_ctx;
+
+    RESET_CFLAG(context);
+    lpDosTask->dpmi_flag = AX_reg(context);
+/* our mode switch wrapper have placed the desired CS into DX */
+    cs = SELECTOR_AllocBlock( base + (DWORD)(DX_reg(context)<<4), 0x10000, SEGMENT_CODE, FALSE, FALSE );
+    ss = SELECTOR_AllocBlock( base + (DWORD)(SS_reg(context)<<4), 0x10000, SEGMENT_DATA, FALSE, FALSE );
+    ds = SELECTOR_AllocBlock( base + (DWORD)(DS_reg(context)<<4), 0x10000, SEGMENT_DATA, FALSE, FALSE );
+    es = SELECTOR_AllocBlock( base + (DWORD)(lpDosTask->psp_seg<<4), 0x100, SEGMENT_DATA, FALSE, FALSE );
+
+    pm_ctx = *context;
+    CS_reg(&pm_ctx) = lpDosTask->dpmi_sel;
+/* our mode switch wrapper expects the new CS in DX, and the new SS in AX */
+    AX_reg(&pm_ctx) = ss;
+    DX_reg(&pm_ctx) = cs;
+    DS_reg(&pm_ctx) = ds;
+    ES_reg(&pm_ctx) = es;
+    FS_reg(&pm_ctx) = 0;
+    GS_reg(&pm_ctx) = 0;
+
+    TRACE(int31,"DOS program is now entering protected mode\n");
+    Callbacks->CallRegisterShortProc(&pm_ctx, 0);
+
+    /* in the current state of affairs, we won't ever actually return here... */
+
+    UnMapLS(PTR_SEG_OFF_TO_SEGPTR(es,0));
+    UnMapLS(PTR_SEG_OFF_TO_SEGPTR(ds,0));
+    UnMapLS(PTR_SEG_OFF_TO_SEGPTR(ss,0));
+    UnMapLS(PTR_SEG_OFF_TO_SEGPTR(cs,0));
+}
+#endif
 
 /**********************************************************************
  *	    INT_Int31Handler
@@ -347,6 +387,23 @@
     DWORD dw;
     BYTE *ptr;
 
+    TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
+    NE_MODULE *pModule = pTask ? NE_GetPtr( pTask->hModule ) : NULL;
+
+    GlobalUnlock16( GetCurrentTask() );
+
+#ifdef MZ_SUPPORTED
+    if (ISV86(context) && pModule && pModule->lpDosTask) {
+        /* Called from real mode, check if it's our wrapper */
+        TRACE(int31,"called from real mode\n");
+        if (CS_reg(context)==pModule->lpDosTask->dpmi_seg) {
+            /* This is the protected mode switch */
+            StartPM(context,pModule->lpDosTask);
+            return;
+        }
+    }
+#endif
+
     RESET_CFLAG(context);
     switch(AX_reg(context))
     {
@@ -503,7 +560,7 @@
         break;
     case 0x0204:  /* Get protected mode interrupt vector */
     	TRACE(int31,"get protected mode interrupt handler (0x%02x), stub!\n",BL_reg(context));
-	dw = (DWORD)INT_GetHandler( BL_reg(context) );
+	dw = (DWORD)INT_GetPMHandler( BL_reg(context) );
 	CX_reg(context) = HIWORD(dw);
 	DX_reg(context) = LOWORD(dw);
 	break;
@@ -511,9 +568,9 @@
     case 0x0205:  /* Set protected mode interrupt vector */
     	TRACE(int31,"set protected mode interrupt handler (0x%02x,%p), stub!\n",
             BL_reg(context),PTR_SEG_OFF_TO_LIN(CX_reg(context),DX_reg(context)));
-	INT_SetHandler( BL_reg(context),
-                        (FARPROC16)PTR_SEG_OFF_TO_SEGPTR( CX_reg(context),
-                                                          DX_reg(context) ));
+	INT_SetPMHandler( BL_reg(context),
+                          (FARPROC16)PTR_SEG_OFF_TO_SEGPTR( CX_reg(context),
+                                                            DX_reg(context) ));
 	break;
 
     case 0x0300:  /* Simulate real mode interrupt */
diff --git a/msdos/int21.c b/msdos/int21.c
index a17b630..55e19a8 100644
--- a/msdos/int21.c
+++ b/msdos/int21.c
@@ -817,12 +817,12 @@
 
 static void DeleteFileFCB( CONTEXT *context )
 {
-    FIXME(int21, "(%p): not implemented yet\n", context);
+    FIXME(int21, "(%p): stub\n", context);
 }
 
 static void RenameFileFCB( CONTEXT *context )
 {
-    FIXME(int21, "(%p): not implemented yet\n", context);
+    FIXME(int21, "(%p): stub\n", context);
 }
 
 
@@ -895,19 +895,18 @@
      }
 }
 
-static void INT21_SetCurrentPSP(CONTEXT *context)
+static void INT21_SetCurrentPSP(WORD psp)
 {
-/* FIXME - What is this MZ stuff and what if it isn't supported?? */
 #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)
-        pModule->lpDosTask->psp_seg = BX_reg(context);
-#else
-    FIXME(int21, "MZ Not Supported.\n");
+        pModule->lpDosTask->psp_seg = psp;
+    else
 #endif
+        ERR(int21, "Cannot change PSP for non-DOS task!\n");
 }
     
 static WORD INT21_GetCurrentPSP()
@@ -1165,7 +1164,7 @@
         break;
 		
     case 0x25: /* SET INTERRUPT VECTOR */
-        INT_SetHandler( AL_reg(context),
+        INT_CtxSetHandler( context, AL_reg(context),
                         (FARPROC16)PTR_SEG_OFF_TO_SEGPTR( DS_reg(context),
                                                           DX_reg(context)));
         break;
@@ -1271,7 +1270,7 @@
     case 0x35: /* GET INTERRUPT VECTOR */
         TRACE(int21,"GET INTERRUPT VECTOR 0x%02x\n",AL_reg(context));
         {
-            FARPROC16 addr = INT_GetHandler( AL_reg(context) );
+            FARPROC16 addr = INT_CtxGetHandler( context, AL_reg(context) );
             ES_reg(context) = SELECTOROF(addr);
             BX_reg(context) = OFFSETOF(addr);
         }
@@ -1360,10 +1359,17 @@
         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( BX_reg(context),
-                                    CTX_SEG_OFF_TO_LIN(context, DS_reg(context),
-                                                                DX_reg(context) ),
-                                    CX_reg(context) );
+            LONG result;
+            if (ISV86(context))
+                result = _hread16( BX_reg(context),
+                                   CTX_SEG_OFF_TO_LIN(context, DS_reg(context),
+                                                               DX_reg(context) ),
+                                   CX_reg(context) );
+            else
+                result = WIN16_hread( BX_reg(context),
+                                      PTR_SEG_OFF_TO_SEGPTR( DS_reg(context),
+                                                             DX_reg(context) ),
+                                      CX_reg(context) );
             if (result == -1) bSetDOSExtendedError = TRUE;
             else AX_reg(context) = (WORD)result;
         }
@@ -1548,6 +1554,10 @@
 	    }
             break;
 	    }
+
+        case 0xe0:  /* Sun PC-NFS API */
+            /* not installed */
+            break;
                 
         default:
             INT_BARF( context, 0x21 );
@@ -1671,9 +1681,8 @@
         else AX_reg(context) = 0;  /* OK */
         break;
     case 0x50: /* SET CURRENT PROCESS ID (SET PSP ADDRESS) */
-        TRACE(int21, "SET CURRENT PROCESS ID (GET PSP ADDRESS)\n");
-        /* FIXME: Is this right? */
-        INT21_SetCurrentPSP(context);
+        TRACE(int21, "SET CURRENT PROCESS ID (SET PSP ADDRESS)\n");
+        INT21_SetCurrentPSP(BX_reg(context));
         break;
     case 0x51: /* GET PSP ADDRESS */
         TRACE(int21,"GET CURRENT PROCESS ID (GET PSP ADDRESS)\n");
@@ -1715,7 +1724,7 @@
                 FILETIME filetime;
                 TRACE(int21,"GET FILE DATE AND TIME for handle %d\n",
 		      BX_reg(context));
-                if (!GetFileTime( BX_reg(context), NULL, NULL, &filetime ))
+                if (!GetFileTime( HFILE16_TO_HFILE32(BX_reg(context)), NULL, NULL, &filetime ))
 		     bSetDOSExtendedError = TRUE;
                 else FileTimeToDosDateTime( &filetime, &DX_reg(context),
                                             &CX_reg(context) );
@@ -2106,6 +2115,7 @@
 
 FARPROC16 WINAPI GetSetKernelDOSProc(FARPROC16 DosProc)
 {
-	FIXME(int21, "(DosProc=%08x);\n", (UINT32)DosProc);
+	FIXME(int21, "(DosProc=0x%08x): stub\n", (UINT32)DosProc);
 	return NULL;
 }
+
diff --git a/msdos/int2f.c b/msdos/int2f.c
index 0559fff..7a88d80 100644
--- a/msdos/int2f.c
+++ b/msdos/int2f.c
@@ -11,6 +11,8 @@
 #include "msdos.h"
 #include "miscemu.h"
 #include "module.h"
+#include "task.h"
+#include "dosexe.h"
 /* #define DEBUG_INT */
 #include "debug.h"
 
@@ -34,6 +36,21 @@
         AL_reg(context) = 0xff; /* share is installed */
         break;
 
+    case 0x11:  /* Network Redirector / IFSFUNC */
+        switch (AL_reg(context))
+        {
+        case 0x00:  /* Install check */
+            /* not installed */
+            break;
+        case 0x80:  /* Enhanced services - Install check */
+            /* not installed */
+            break;
+        default:
+	    INT_BARF( context, 0x2f );
+            break;
+        }
+        break;
+
     case 0x12:
         switch (AL_reg(context))
         {
@@ -131,16 +148,49 @@
             /* return nothing -> NetWare not installed */
             break;
         default:
-            SET_CFLAG(context);
+	    INT_BARF( context, 0x2f );
             break;
         }
         break;
     case 0xb7:  /* append */
         AL_reg(context) = 0; /* not installed */
         break;
+    case 0xb8:  /* network */
+        switch (AL_reg(context))
+        {
+        case 0x00:  /* Install check */
+            /* not installed */
+            break;
+        default:
+	    INT_BARF( context, 0x2f );
+            break;
+        }
+        break;
     case 0xbd:  /* some Novell network install check ??? */
         AX_reg(context) = 0xa5a5; /* pretend to have Novell IPX installed */
 	break;
+    case 0xbf:  /* REDIRIFS.EXE */
+        switch (AL_reg(context))
+        {
+        case 0x00:  /* Install check */
+            /* not installed */
+            break;
+        default:
+	    INT_BARF( context, 0x2f );
+            break;
+        }
+        break;
+    case 0xd7:  /* Banyan Vines */
+        switch (AL_reg(context))
+        {
+        case 0x01:  /* Install check - Get Int Number */
+            /* not installed */
+            break;
+        default:
+	    INT_BARF( context, 0x2f );
+            break;
+        }
+        break;
     case 0xfa:  /* Watcom debugger check, returns 0x666 if installed */
         break;
     default:
@@ -200,10 +250,8 @@
                                         VXD_BASE + BX_reg(context) );
         if (!addr)  /* not supported */
         {
-	    WARN(int,"Application attempted to access VxD %04x\n",
+	    ERR(int,"Accessing unknown VxD %04x - Expect a failure now.\n",
                      BX_reg(context) );
-	    WARN(int,"This device is not known to Wine.");
-	    WARN(int,"Expect a failure now\n");
         }
 	ES_reg(context) = SELECTOROF(addr);
 	DI_reg(context) = OFFSETOF(addr);
@@ -213,21 +261,28 @@
         AX_reg(context) = 0;  /* Running under DPMI */
         break;
 
-    /* FIXME: is this right?  Specs say that this should only be callable
-       in real (v86) mode which we never enter.  */
-    /* FIXME: we do now, and this breaks pkunzip */
     case 0x87: /* DPMI installation check */
+#if 1   /* DPMI still breaks pkunzip */
         if (ISV86(context)) break; /* so bail out for now if in v86 mode */
+#endif
         {
+            TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
+            NE_MODULE *pModule = pTask ? NE_GetPtr( pTask->hModule ) : NULL;
 	    SYSTEM_INFO si;
 
+            GlobalUnlock16( GetCurrentTask() );
 	    GetSystemInfo(&si);
 	    AX_reg(context) = 0x0000; /* DPMI Installed */
             BX_reg(context) = 0x0001; /* 32bits available */
             CL_reg(context) = si.wProcessorLevel;
             DX_reg(context) = 0x005a; /* DPMI major/minor 0.90 */
             SI_reg(context) = 0;      /* # of para. of DOS extended private data */
-            ES_reg(context) = 0;      /* ES:DI is DPMI switch entry point */
+#ifdef MZ_SUPPORTED                   /* ES:DI is DPMI switch entry point */
+            if (pModule && pModule->lpDosTask)
+                ES_reg(context) = pModule->lpDosTask->dpmi_seg;
+            else
+#endif
+                ES_reg(context) = 0;
             DI_reg(context) = 0;
             break;
         }
diff --git a/msdos/interrupts.c b/msdos/interrupts.c
index 79c7144..a44a4ca 100644
--- a/msdos/interrupts.c
+++ b/msdos/interrupts.c
@@ -18,26 +18,80 @@
 
 
 /**********************************************************************
- *	    INT_GetHandler
+ *	    INT_GetPMHandler
  *
- * Return the interrupt vector for a given interrupt.
+ * Return the protected mode interrupt vector for a given interrupt.
  */
-FARPROC16 INT_GetHandler( BYTE intnum )
+FARPROC16 INT_GetPMHandler( BYTE intnum )
 {
     return INT_Vectors[intnum];
 }
 
 
 /**********************************************************************
- *	    INT_SetHandler
+ *	    INT_SetPMHandler
+ *
+ * Set the protected mode interrupt handler for a given interrupt.
+ */
+void INT_SetPMHandler( BYTE intnum, FARPROC16 handler )
+{
+    TRACE(int, "Set protected mode interrupt vector %02x <- %04x:%04x\n",
+                 intnum, HIWORD(handler), LOWORD(handler) );
+    INT_Vectors[intnum] = handler;
+}
+
+
+/**********************************************************************
+ *	    INT_GetRMHandler
+ *
+ * Return the real mode interrupt vector for a given interrupt.
+ */
+FARPROC16 INT_GetRMHandler( BYTE intnum )
+{
+    return ((FARPROC16*)DOSMEM_MemoryBase(0))[intnum];
+}
+
+
+/**********************************************************************
+ *	    INT_SetRMHandler
+ *
+ * Set the real mode interrupt handler for a given interrupt.
+ */
+void INT_SetRMHandler( BYTE intnum, FARPROC16 handler )
+{
+    TRACE(int, "Set real mode interrupt vector %02x <- %04x:%04x\n",
+                 intnum, HIWORD(handler), LOWORD(handler) );
+    ((FARPROC16*)DOSMEM_MemoryBase(0))[intnum] = handler;
+}
+
+
+/**********************************************************************
+ *	    INT_CtxGetHandler
+ *
+ * Return the interrupt vector for a given interrupt.
+ */
+FARPROC16 INT_CtxGetHandler( CONTEXT *context, BYTE intnum )
+{
+    if (ISV86(context))
+        return ((FARPROC16*)V86BASE(context))[intnum];
+    else
+        return INT_GetPMHandler(intnum);
+}
+
+
+/**********************************************************************
+ *	    INT_CtxSetHandler
  *
  * Set the interrupt handler for a given interrupt.
  */
-void INT_SetHandler( BYTE intnum, FARPROC16 handler )
+void INT_CtxSetHandler( CONTEXT *context, BYTE intnum, FARPROC16 handler )
 {
-    TRACE(int, "Set interrupt vector %02x <- %04x:%04x\n",
-                 intnum, HIWORD(handler), LOWORD(handler) );
-    INT_Vectors[intnum] = handler;
+    if (ISV86(context)) {
+        TRACE(int, "Set real mode interrupt vector %02x <- %04x:%04x\n",
+                     intnum, HIWORD(handler), LOWORD(handler) );
+        ((FARPROC16*)V86BASE(context))[intnum] = handler;
+    } else
+        INT_SetPMHandler(intnum, handler);
 }
 
 
@@ -63,10 +117,17 @@
         case 0x21:
             DOS3Call(context);
             break;
+        case 0x25:
+            INT_Int25Handler(context);
+            break;
         case 0x2f:
             INT_Int2fHandler(context);
             break;
+        case 0x31:
+            INT_Int31Handler(context);
+            break;
         default:
+            FIXME(int, "Unknown Interrupt in DOS mode: 0x%x\n", intnum);
             return 1;
     }
     return 0;
diff --git a/msdos/vxd.c b/msdos/vxd.c
index caac7a3..011c117 100644
--- a/msdos/vxd.c
+++ b/msdos/vxd.c
@@ -34,6 +34,27 @@
 }
 
 /***********************************************************************
+ *           VXD_VMM
+ */
+void VXD_VMM ( CONTEXT *context )
+{
+    unsigned service = AX_reg(context);
+
+    TRACE(vxd,"[%04x] VMM  \n", (UINT16)service);
+
+    switch(service)
+    {
+    case 0x0000: /* version */
+        AX_reg(context) = VXD_WinVersion();
+        RESET_CFLAG(context);
+        break;
+
+    default:
+        VXD_BARF( context, "VMM" );
+    }
+}
+
+/***********************************************************************
  *           VXD_PageFile
  */
 void WINAPI VXD_PageFile( CONTEXT *context )
@@ -199,6 +220,61 @@
 }
 
 /***********************************************************************
+ *           VXD_TimerAPI
+ */
+void VXD_TimerAPI ( CONTEXT *context )
+{
+    static DWORD clockTicks = 0;
+    static WORD clockTickSelector = 0;
+
+    unsigned service = AX_reg(context);
+
+    TRACE(vxd,"[%04x] TimerAPI  \n", (UINT16)service);
+
+    switch(service)
+    {
+    case 0x0000: /* version */
+        AX_reg(context) = VXD_WinVersion();
+        RESET_CFLAG(context);
+        break;
+
+    case 0x0009: /* get system time selector */
+        FIXME(vxd, "Get_System_Time_Selector: this clock doesn't tick!\n");
+
+        if ( !clockTickSelector )
+            clockTickSelector = SELECTOR_AllocBlock( &clockTicks, sizeof(DWORD), 
+                                                     SEGMENT_DATA, FALSE, TRUE );
+        AX_reg(context) = clockTickSelector;
+        RESET_CFLAG(context);
+        break;
+
+    default:
+        VXD_BARF( context, "VTDAPI" );
+    }
+}
+
+/***********************************************************************
+ *           VXD_ConfigMG
+ */
+void VXD_ConfigMG ( CONTEXT *context )
+{
+    unsigned service = AX_reg(context);
+
+    TRACE(vxd,"[%04x] ConfigMG  \n", (UINT16)service);
+
+    switch(service)
+    {
+    case 0x0000: /* version */
+        AX_reg(context) = VXD_WinVersion();
+        RESET_CFLAG(context);
+        break;
+
+    default:
+        VXD_BARF( context, "CONFIGMG" );
+    }
+}
+
+/***********************************************************************
  *           VXD_Win32s
  *
  * This is an implementation of the services of the Win32s VxD.
diff --git a/multimedia/Makefile.in b/multimedia/Makefile.in
index 8762d25..25e2312 100644
--- a/multimedia/Makefile.in
+++ b/multimedia/Makefile.in
@@ -15,6 +15,7 @@
 	mcicda.c \
 	mcistring.c \
 	midi.c \
+	midipatch.c \
 	mixer.c \
 	mmaux.c \
 	mmio.c \
diff --git a/multimedia/dplay.c b/multimedia/dplay.c
index eef3542..e7316f8 100644
--- a/multimedia/dplay.c
+++ b/multimedia/dplay.c
@@ -1,72 +1,555 @@
-/* Direct Play 3 and Direct Play Lobby 1 Implementation
- * Presently only the Lobby skeleton is implemented.                    
+/* Direct Play 3 and Direct Play Lobby 2 Implementation
  *
  * Copyright 1998 - Peter Hunnisett
  *
+ * <presently under construction - contact hunnise@nortel.ca>
+ *
  */
-#include "windows.h"
-#include "heap.h"
-#include "wintypes.h"
-#include "winerror.h"
 #include "interfaces.h"
-#include "mmsystem.h"
-#include "dplay.h"
+#include "heap.h"
+#include "winerror.h"
 #include "debug.h"
 #include "winnt.h"
 #include "winreg.h"
+#include "compobj.h"
+#include "dplay.h"
+
+#include "thread.h"
+#include <sys/queue.h>
+
+#define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID)))
+#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2)
+#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2)
+
+struct IDirectPlayLobby {
+    LPDIRECTPLAYLOBBY_VTABLE lpVtbl;
+    ULONG                    ref;
+    LPDPLCONNECTION          lpSession;
+};
+
+struct IDirectPlayLobby2 {
+    LPDIRECTPLAYLOBBY2_VTABLE lpVtbl;
+    ULONG                     ref;
+    LPDPLCONNECTION           lpSession;
+};
 
 
-static HRESULT WINAPI IDirectPlayLobby_QueryInterface
+/* Forward declarations of virtual tables */
+static DIRECTPLAYLOBBY_VTABLE  directPlayLobbyAVT;
+static DIRECTPLAYLOBBY_VTABLE  directPlayLobbyWVT;
+static DIRECTPLAYLOBBY2_VTABLE directPlayLobby2AVT;
+static DIRECTPLAYLOBBY2_VTABLE directPlayLobby2WVT;
+
+struct IDirectPlay2 {
+  LPDIRECTPLAY2_VTABLE lpVtbl;
+  ULONG                ref;
+};
+
+struct IDirectPlay3 {
+  LPDIRECTPLAY3_VTABLE lpVtbl;
+  ULONG                ref;
+};
+
+
+static DIRECTPLAY2_VTABLE directPlay2AVT;
+static DIRECTPLAY2_VTABLE directPlay2WVT;
+static DIRECTPLAY3_VTABLE directPlay3AVT;
+static DIRECTPLAY3_VTABLE directPlay3WVT;
+
+/* Routine to delete the entire DPLCONNECTION tree. Works for both unicode and ascii. */
+void deleteDPConnection( LPDPLCONNECTION* ptrToDelete )
+{
+ 
+  /* This is most definitely wrong. We're not even keeping dwCurrentPlayers over this */
+   LPDPLCONNECTION toDelete = *ptrToDelete;
+
+   FIXME( dplay, "incomplete.\n" );
+
+   if( !toDelete )
+     return;
+    
+   /* Clear out DPSESSIONDESC2 */
+   if( toDelete->lpSessionDesc )
+   {
+     if( toDelete->lpSessionDesc->sess.lpszSessionName )
+       HeapFree( GetProcessHeap(), 0, toDelete->lpSessionDesc->sess.lpszSessionName );
+
+     if( toDelete->lpSessionDesc->pass.lpszPassword ) 
+       HeapFree( GetProcessHeap(), 0, toDelete->lpSessionDesc->pass.lpszPassword ); 
+
+     if( toDelete->lpSessionDesc );  
+       HeapFree( GetProcessHeap(), 0, toDelete->lpSessionDesc ); 
+   }
+
+   /* Clear out LPDPNAME */
+   if( toDelete->lpPlayerName )
+   { 
+     if( toDelete->lpPlayerName->psn.lpszShortName )
+       HeapFree( GetProcessHeap(), 0, toDelete->lpPlayerName->psn.lpszShortName );
+
+     if( toDelete->lpPlayerName->pln.lpszLongName ) 
+       HeapFree( GetProcessHeap(), 0, toDelete->lpPlayerName->pln.lpszLongName );
+
+     if( toDelete->lpPlayerName ) 
+       HeapFree( GetProcessHeap(), 0, toDelete->lpPlayerName );
+   }
+
+   /* Clear out lpAddress. TO DO...Once we actually copy it. */
+
+   /* Clear out DPLCONNECTION */
+   HeapFree( GetProcessHeap(), 0, toDelete );
+
+   toDelete = NULL;
+}
+
+
+#if 0
+/* Routine which copies and allocates all the store required for the DPLCONNECTION struct. */
+void rebuildDPConnectionW( LPDPLCONNECTION dest, LPDPLCONNECTION src )
+{
+ 
+  /* Need to delete everything that already exists first */
+  FIXME( dplay, "function is incomplete.\n" ); 
+
+  if( !src )
+  {
+    /* Nothing to copy...hmmm...*/
+    ERR( dplay, "nothing to copy\n" );
+    return;
+  }
+
+  /* Copy DPLCONNECTION struct. If dest isn't NULL then we have a DPLCONNECTION
+     struct but that's it
+   */
+  if( dest == NULL )
+  {
+    dest = HeapAlloc( GetProcessHeap(), 0, sizeof( *src ) );
+  }
+  memcpy( dest, src, sizeof( *src ) );
+
+  /* Copy LPDPSESSIONDESC2 struct */
+  if( src->lpSessionDesc )
+  {
+    dest->lpSessionDesc = HeapAlloc( GetProcessHeap(), 0,
+                                     sizeof( *(src->lpSessionDesc) ) );
+
+    memcpy( dest->lpSessionDesc, src->lpSessionDesc,
+            sizeof( *(src->lpSessionDesc) ) ); 
+
+    if( src->lpSessionDesc )
+    { 
+      /* Hmmm...do we have to assume the system heap? */ 
+      dest->lpSessionDesc->sess.lpszSessionName = HEAP_strdupW( GetProcessHeap(), 0,
+                                                                src->lpSessionDesc->sess.lpszSessionName );
+    }
+
+    if( src->lpSessionDesc->pass.lpszPassword )
+    {
+      dest->lpSessionDesc->pass.lpszPassword = HEAP_strdupW( GetProcessHeap(), 0,
+                                                             src->lpSessionDesc->pass.lpszPassword );
+    }
+    dest->lpSessionDesc->dwReserved1 = src->lpSessionDesc->dwReserved2 = 0;
+  }
+
+  /* Copy DPNAME struct */	
+  if( src->lpPlayerName )
+  {
+    dest->lpPlayerName = HeapAlloc( GetProcessHeap(), 0, sizeof( *(src->lpPlayerName) ) ); 
+    memcpy( dest->lpPlayerName, src->lpPlayerName, sizeof( *(src->lpPlayerName) ) ); 
+
+    if( src->lpPlayerName->psn.lpszShortName )
+    { 
+      dest->lpPlayerName->psn.lpszShortName = HEAP_strdupW( GetProcessHeap(), 0,
+                                                            src->lpPlayerName->psn.lpszShortName );
+    }
+ 
+    if( src->lpPlayerName->pln.lpszLongName )
+    {
+      dest->lpPlayerName->pln.lpszLongName = HEAP_strdupW( GetProcessHeap(), 0,
+                                                           src->lpPlayerName->pln.lpszLongName );
+    }
+  }
+
+  /* Copy Address of Service Provider -TBD */
+  if( src->lpAddress ) 
+  {
+    /* What do we do here? */ 
+  } 
+
+}
+
+#endif
+
+/* Routine called when starting up the server thread */
+DWORD DPLobby_Spawn_Server( LPVOID startData )
+{
+  DPSESSIONDESC2* lpSession = (DPSESSIONDESC2*) startData;
+  DWORD sessionDwFlags = lpSession->dwFlags;
+ 
+  TRACE( dplay, "spawing thread for lpConn=%p dwFlags=%08lx\n", lpSession, sessionDwFlags );
+  FIXME( dplay, "thread needs something to do\n" ); 
+
+/*for(;;)*/
+  {
+     
+    /* Check out the connection flags to determine what to do. Ensure we have 
+       no leftover bits in this structure */
+    if( sessionDwFlags & DPSESSION_CLIENTSERVER )
+    {
+       /* This indicates that the application which is requesting the creation
+        * of this session is going to be the server (application/player)
+        */ 
+       if( sessionDwFlags & DPSESSION_SECURESERVER )
+       {
+         sessionDwFlags &= ~DPSESSION_SECURESERVER; 
+       }
+       sessionDwFlags &= ~DPSESSION_CLIENTSERVER;  
+    }
+
+    if( sessionDwFlags & DPSESSION_JOINDISABLED )
+    {
+       sessionDwFlags &= ~DPSESSION_JOINDISABLED; 
+    } 
+
+    if( sessionDwFlags & DPSESSION_KEEPALIVE )
+    {
+       sessionDwFlags &= ~DPSESSION_KEEPALIVE;
+    }
+
+    if( sessionDwFlags & DPSESSION_MIGRATEHOST )
+    {
+       sessionDwFlags &= ~DPSESSION_MIGRATEHOST;
+    }
+
+    if( sessionDwFlags & DPSESSION_MULTICASTSERVER )
+    {
+       sessionDwFlags &= ~DPSESSION_MULTICASTSERVER;
+    }
+
+    if( sessionDwFlags & DPSESSION_NEWPLAYERSDISABLED )
+    {
+       sessionDwFlags &= ~DPSESSION_NEWPLAYERSDISABLED; 
+    }
+
+    if( sessionDwFlags & DPSESSION_NODATAMESSAGES )
+    {
+       sessionDwFlags &= ~DPSESSION_NODATAMESSAGES; 
+    } 
+
+    if( sessionDwFlags & DPSESSION_NOMESSAGEID )
+    {
+       sessionDwFlags &= ~DPSESSION_NOMESSAGEID;
+    }
+
+    if( sessionDwFlags & DPSESSION_PASSWORDREQUIRED )
+    {
+       sessionDwFlags &= ~DPSESSION_PASSWORDREQUIRED;
+    }
+
+  }
+
+  ExitThread(0);
+  return 0; 
+}
+
+
+/*********************************************************
+ *
+ * Direct Play and Direct Play Lobby Interface Implementation 
+ * 
+ *********************************************************/ 
+
+/* The COM interface for upversioning an interface
+ * We've been given a GUID (riid) and we need to replace the present
+ * interface with that of the requested interface.
+ *
+ * Snip from some Microsoft document:
+ * There are four requirements for implementations of QueryInterface (In these
+ * cases, "must succeed" means "must succeed barring catastrophic failure."):
+ *
+ *  * The set of interfaces accessible on an object through
+ *    IUnknown::QueryInterface must be static, not dynamic. This means that
+ *    if a call to QueryInterface for a pointer to a specified interface
+ *    succeeds the first time, it must succeed again, and if it fails the
+ *    first time, it must fail on all subsequent queries.
+ *  * It must be symmetric ~W if a client holds a pointer to an interface on
+ *    an object, and queries for that interface, the call must succeed.
+ *  * It must be reflexive ~W if a client holding a pointer to one interface
+ *    queries successfully for another, a query through the obtained pointer
+ *    for the first interface must succeed.
+ *  * It must be transitive ~W if a client holding a pointer to one interface
+ *    queries successfully for a second, and through that pointer queries
+ *    successfully for a third interface, a query for the first interface
+ *    through the pointer for the third interface must succeed.
+ *
+ *  As you can see, this interface doesn't qualify but will most likely
+ *  be good enough for the time being.
+ */
+static HRESULT WINAPI IDirectPlayLobbyA_QueryInterface
+( LPDIRECTPLAYLOBBYA this,
+  REFIID riid,
+  LPVOID* ppvObj )
+{
+  return DPERR_OUTOFMEMORY; 
+}
+
+static HRESULT WINAPI IDirectPlayLobbyW_QueryInterface
+( LPDIRECTPLAYLOBBY this,
+  REFIID riid,
+  LPVOID* ppvObj )
+{
+  return DPERR_OUTOFMEMORY;
+}
+
+static HRESULT WINAPI IDirectPlayLobby2A_QueryInterface
+( LPDIRECTPLAYLOBBY2A this,
+  REFIID riid,
+  LPVOID* ppvObj )
+{
+  /* Compare riids. We know this object is a direct play lobby 2A object.
+     If we are asking about the same type of interface we're fine.
+   */
+  if( IsEqualGUID( &IID_IUnknown, riid )  ||
+      IsEqualGUID( &IID_IDirectPlayLobby2A, riid )
+    )
+  {
+    this->lpVtbl->fnAddRef( this );
+    *ppvObj = this;
+    return S_OK;
+  }
+  /* They're requesting a unicode version of the interface */
+  else if( IsEqualGUID( &IID_IDirectPlayLobby2, riid ) )
+  {
+     LPDIRECTPLAYLOBBY2 lpDpL = (LPDIRECTPLAYLOBBY2)(*ppvObj);
+
+     lpDpL = (LPDIRECTPLAYLOBBY2)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                             sizeof( IDirectPlayLobby2 ) );
+
+    if( !lpDpL )
+    {
+      return E_NOINTERFACE;
+    }
+
+    lpDpL->lpVtbl = &directPlayLobby2WVT;
+    lpDpL->ref    = 1;
+
+    return S_OK;
+  }
+
+  /* Unexpected interface request! */ 
+  *ppvObj = NULL;
+  return E_NOINTERFACE; 
+};
+
+static HRESULT WINAPI IDirectPlayLobby2W_QueryInterface
 ( LPDIRECTPLAYLOBBY2 this,
   REFIID riid,
   LPVOID* ppvObj )
 {
-  FIXME( dplay, ":stub\n");
-  return DPERR_OUTOFMEMORY;
-}
 
-static ULONG WINAPI IDirectPlayLobby_AddRef
-( LPDIRECTPLAYLOBBY2 this )
+  /* Compare riids. We know this object is a direct play lobby 2 object.
+     If we are asking about the same type of interface we're fine.
+   */
+  if( IsEqualGUID( &IID_IUnknown, riid ) ||
+      IsEqualGUID( &IID_IDirectPlayLobby2, riid ) 
+    )
+  {
+    this->lpVtbl->fnAddRef( this );
+    *ppvObj = this;
+    return S_OK;
+  }
+  else if( IsEqualGUID( &IID_IDirectPlayLobby2A, riid ) )
+  {
+     LPDIRECTPLAYLOBBY2A lpDpL = (LPDIRECTPLAYLOBBY2A)(*ppvObj);
+
+     lpDpL = (LPDIRECTPLAYLOBBY2A)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                             sizeof( IDirectPlayLobby2A ) );
+
+    if( !lpDpL )
+    {
+      return E_NOINTERFACE;
+    }
+
+    lpDpL->lpVtbl = &directPlayLobby2AVT;
+    lpDpL->ref    = 1;
+
+    return S_OK;
+  }
+
+  /* Unexpected interface request! */
+  *ppvObj = NULL;
+  return E_NOINTERFACE;
+
+};
+
+/* 
+ * Simple procedure. Just increment the reference count to this
+ * structure and return the new reference count.
+ */
+static ULONG WINAPI IDirectPlayLobbyA_AddRef
+( LPDIRECTPLAYLOBBYA this )
 {
   ++(this->ref);
-  TRACE( dplay," ref count now %ld\n", this->ref );
+  TRACE( dplay,"ref count now %lu\n", this->ref );
   return (this->ref);
 }
+static ULONG WINAPI IDirectPlayLobbyW_AddRef
+( LPDIRECTPLAYLOBBY this )
+{
+  return IDirectPlayLobbyA_AddRef( (LPDIRECTPLAYLOBBY) this );
+}
 
-static ULONG WINAPI IDirectPlayLobby_Release
+static ULONG WINAPI IDirectPlayLobby2A_AddRef
+( LPDIRECTPLAYLOBBY2A this )
+{
+  return IDirectPlayLobbyA_AddRef( (LPDIRECTPLAYLOBBY) this );
+};
+
+static ULONG WINAPI IDirectPlayLobby2W_AddRef
 ( LPDIRECTPLAYLOBBY2 this )
 {
+  return IDirectPlayLobbyA_AddRef( (LPDIRECTPLAYLOBBY) this );
+};
+
+
+/*
+ * Simple COM procedure. Decrease the reference count to this object.
+ * If the object no longer has any reference counts, free up the associated
+ * memory.
+ */
+static ULONG WINAPI IDirectPlayLobbyA_Release
+( LPDIRECTPLAYLOBBYA this )
+{
+  TRACE( dplay, "ref count decremeneted from %lu\n", this->ref );
+
   this->ref--;
 
-  TRACE( dplay, " ref count now %ld\n", this->ref );
-  
   /* Deallocate if this is the last reference to the object */
   if( !(this->ref) )
   {
-    HeapFree( GetProcessHeap(), 0, this ); 
-    return 0;
+    deleteDPConnection( this->lpSession );
+    HeapFree( GetProcessHeap(), 0, this );
+    return S_OK;
   }
 
   return this->ref;
+
 }
+static ULONG WINAPI IDirectPlayLobbyW_Release
+( LPDIRECTPLAYLOBBY this )
+{
+  return IDirectPlayLobbyA_Release( (LPDIRECTPLAYLOBBYA) this );
+}
+static ULONG WINAPI IDirectPlayLobby2A_Release
+( LPDIRECTPLAYLOBBY2A this )
+{
+  return IDirectPlayLobbyA_Release( (LPDIRECTPLAYLOBBYA) this );
+};
+
+static ULONG WINAPI IDirectPlayLobby2W_Release
+( LPDIRECTPLAYLOBBY2 this )
+{
+  return IDirectPlayLobbyA_Release( (LPDIRECTPLAYLOBBYA) this );
+};
+
 
 /********************************************************************
  * 
  * Connects an application to the session specified by the DPLCONNECTION
  * structure currently stored with the DirectPlayLobby object.
  *
- * Returns a IDirectPlay2 or IDirectPlay2A interface.
+ * Returns a IDirectPlay interface.
  *
  */
-static HRESULT WINAPI IDirectPlayLobby_Connect
-( LPDIRECTPLAYLOBBY2 this,
+static HRESULT WINAPI IDirectPlayLobbyA_Connect
+( LPDIRECTPLAYLOBBYA this,
   DWORD dwFlags,
-  LPDIRECTPLAY2* lplpDP,
+  LPDIRECTPLAY* lplpDP,
   IUnknown* pUnk)
 {
-  FIXME( dplay, ":stub\n");
+  FIXME( dplay, ": dwFlags=%08lx %p %p stub\n", dwFlags, lplpDP, pUnk );
   return DPERR_OUTOFMEMORY;
-}
+};
+
+static HRESULT WINAPI IDirectPlayLobby2A_Connect
+( LPDIRECTPLAYLOBBY2A this,
+  DWORD dwFlags,
+  LPDIRECTPLAY* lplpDP,
+  IUnknown* pUnk)
+{
+  return IDirectPlayLobbyA_Connect( (LPDIRECTPLAYLOBBYA)this, dwFlags, lplpDP, pUnk );
+};
+
+static HRESULT WINAPI IDirectPlayLobbyW_Connect
+( LPDIRECTPLAYLOBBY this,
+  DWORD dwFlags,
+  LPDIRECTPLAY* lplpDP,
+  IUnknown* pUnk)
+{
+  LPDIRECTPLAY2A directPlay2A;
+  LPDIRECTPLAY2  directPlay2W;
+  HRESULT        createRC;
+
+  FIXME( dplay, ": dwFlags=%08lx %p %p stub\n", dwFlags, lplpDP, pUnk );
+
+#if 0
+
+  /* See dpbuild_4301.txt */
+  /* Create the direct play 2 W interface */
+  if( ( ( createRC = DirectPlayCreate( NULL, &directPlay2A, pUnk ) ) != DP_OK ) ||
+      ( ( createRC = directPlay2A->lpVtbl->fnQueryInterface
+           ( directPlay2A, IID_IDirectPlay2, &directPlay2W ) ) != DP_OK )
+    )
+  {
+     ERR( dplay, "error creating Direct Play 2 (W) interface. Return Code = %d.\n", createRC );
+     return createRC;
+  }
+
+  /* All the stuff below this is WRONG! */
+  if( this->lpSession->dwFlags == DPLCONNECTION_CREATESESSION )
+  {
+    DWORD threadIdSink;
+
+    /* Spawn a thread to deal with all of this and to handle the incomming requests */
+    threadIdSink = CreateThread( NULL, 0, &DPLobby_Spawn_Server,
+                                (LPVOID)this->lpSession->lpConn->lpSessionDesc, 0, &threadIdSink );  
+
+  }
+  else if ( this->lpSession->dwFlags == DPLCONNECTION_JOINSESSION ) 
+  {
+    /* Let's search for a matching session */
+    FIXME( dplay, "joining session not yet supported.\n");
+    return DPERR_OUTOFMEMORY;
+  }
+  else /* Unknown type of connection request */
+  {
+     ERR( dplay, ": Unknown connection request lpConn->dwFlags=%08lx\n",
+          lpConn->dwFlags ); 
+
+     return DPERR_OUTOFMEMORY;
+  }
+
+  /* This does the work of the following methods...
+     IDirectPlay3::InitializeConnection,
+     IDirectPlay3::EnumSessions,
+     IDirectPlay3::Open
+   */
+  
+
+#endif
+
+  return DP_OK;
+
+};
+
+static HRESULT WINAPI IDirectPlayLobby2W_Connect
+( LPDIRECTPLAYLOBBY2 this,
+  DWORD dwFlags,
+  LPDIRECTPLAY* lplpDP,
+  IUnknown* pUnk)
+{
+  return IDirectPlayLobbyW_Connect( (LPDIRECTPLAYLOBBY)this, dwFlags, lplpDP, pUnk ); 
+};
 
 /********************************************************************
  *
@@ -77,8 +560,21 @@
  * interpret as a network address.
  *
  */
-static HRESULT WINAPI IDirectPlayLobby_CreateAddress
-( LPDIRECTPLAYLOBBY2 this,
+static HRESULT WINAPI IDirectPlayLobbyA_CreateAddress
+( LPDIRECTPLAYLOBBY this,
+  REFGUID guidSP,
+  REFGUID guidDataType,
+  LPCVOID lpData,
+  DWORD dwDataSize,
+  LPVOID lpAddress,
+  LPDWORD lpdwAddressSize )
+{
+  FIXME( dplay, ":stub\n");
+  return DPERR_OUTOFMEMORY;
+};
+
+static HRESULT WINAPI IDirectPlayLobby2A_CreateAddress
+( LPDIRECTPLAYLOBBY2A this,
   REFGUID guidSP,
   REFGUID guidDataType,
   LPCVOID lpData, 
@@ -86,9 +582,37 @@
   LPVOID lpAddress, 
   LPDWORD lpdwAddressSize )
 {
+  return IDirectPlayLobbyA_CreateAddress( (LPDIRECTPLAYLOBBY)this, guidSP, guidDataType,
+                                           lpData, dwDataSize, lpAddress, lpdwAddressSize ); 
+};
+
+static HRESULT WINAPI IDirectPlayLobbyW_CreateAddress
+( LPDIRECTPLAYLOBBY this,
+  REFGUID guidSP,
+  REFGUID guidDataType,
+  LPCVOID lpData,
+  DWORD dwDataSize,
+  LPVOID lpAddress,
+  LPDWORD lpdwAddressSize )
+{
   FIXME( dplay, ":stub\n");
   return DPERR_OUTOFMEMORY;
-}
+};
+
+
+static HRESULT WINAPI IDirectPlayLobby2W_CreateAddress
+( LPDIRECTPLAYLOBBY2 this,
+  REFGUID guidSP,
+  REFGUID guidDataType,
+  LPCVOID lpData,
+  DWORD dwDataSize,
+  LPVOID lpAddress,
+  LPDWORD lpdwAddressSize )
+{
+  return IDirectPlayLobbyW_CreateAddress( (LPDIRECTPLAYLOBBY)this, guidSP, guidDataType, 
+                                          lpData, dwDataSize, lpAddress, lpdwAddressSize );
+};
+
 
 /********************************************************************
  *
@@ -96,16 +620,50 @@
  * given callback function, with lpContext, for each of the chunks.
  *
  */
-static HRESULT WINAPI IDirectPlayLobby_EnumAddress
-( LPDIRECTPLAYLOBBY2 this,
+static HRESULT WINAPI IDirectPlayLobbyA_EnumAddress
+( LPDIRECTPLAYLOBBYA this,
+  LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
+  LPCVOID lpAddress,
+  DWORD dwAddressSize,
+  LPVOID lpContext )
+{
+  FIXME( dplay, ":stub\n");
+  return DPERR_OUTOFMEMORY;
+};
+
+static HRESULT WINAPI IDirectPlayLobby2A_EnumAddress
+( LPDIRECTPLAYLOBBY2A this,
   LPDPENUMADDRESSCALLBACK lpEnumAddressCallback, 
   LPCVOID lpAddress,
   DWORD dwAddressSize, 
   LPVOID lpContext )
 {
+  return IDirectPlayLobbyA_EnumAddress( (LPDIRECTPLAYLOBBYA)this, lpEnumAddressCallback,
+                                        lpAddress, dwAddressSize, lpContext );
+};
+
+static HRESULT WINAPI IDirectPlayLobbyW_EnumAddress
+( LPDIRECTPLAYLOBBY this,
+  LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
+  LPCVOID lpAddress,
+  DWORD dwAddressSize,
+  LPVOID lpContext )
+{
   FIXME( dplay, ":stub\n");
   return DPERR_OUTOFMEMORY;
-}
+};
+
+static HRESULT WINAPI IDirectPlayLobby2W_EnumAddress
+( LPDIRECTPLAYLOBBY2 this,
+  LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
+  LPCVOID lpAddress,
+  DWORD dwAddressSize,
+  LPVOID lpContext )
+{
+  return IDirectPlayLobbyW_EnumAddress( (LPDIRECTPLAYLOBBY)this, lpEnumAddressCallback,
+                                        lpAddress, dwAddressSize, lpContext );
+};
+
 
 /********************************************************************
  *
@@ -113,16 +671,50 @@
  * build the DirectPlay Address.
  *
  */
-static HRESULT WINAPI IDirectPlayLobby_EnumAddressTypes
-( LPDIRECTPLAYLOBBY2 this,
+static HRESULT WINAPI IDirectPlayLobbyA_EnumAddressTypes
+( LPDIRECTPLAYLOBBYA this,
   LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
-  REFGUID guidSP, 
+  REFGUID guidSP,
   LPVOID lpContext,
   DWORD dwFlags )
 {
   FIXME( dplay, ":stub\n");
   return DPERR_OUTOFMEMORY;
-}
+};
+
+static HRESULT WINAPI IDirectPlayLobby2A_EnumAddressTypes
+( LPDIRECTPLAYLOBBY2A this,
+  LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
+  REFGUID guidSP, 
+  LPVOID lpContext,
+  DWORD dwFlags )
+{
+  return IDirectPlayLobbyA_EnumAddressTypes( (LPDIRECTPLAYLOBBYA)this, lpEnumAddressTypeCallback,
+                                             guidSP, lpContext, dwFlags );
+};
+
+static HRESULT WINAPI IDirectPlayLobbyW_EnumAddressTypes
+( LPDIRECTPLAYLOBBY this,
+  LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
+  REFGUID guidSP,
+  LPVOID lpContext,
+  DWORD dwFlags )
+{
+  FIXME( dplay, ":stub\n");
+  return DPERR_OUTOFMEMORY;
+};
+
+static HRESULT WINAPI IDirectPlayLobby2W_EnumAddressTypes
+( LPDIRECTPLAYLOBBY2 this,
+  LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
+  REFGUID guidSP,
+  LPVOID lpContext,
+  DWORD dwFlags )
+{
+  return IDirectPlayLobbyW_EnumAddressTypes( (LPDIRECTPLAYLOBBY)this, lpEnumAddressTypeCallback,
+                                             guidSP, lpContext, dwFlags );
+};
+
 
 /********************************************************************
  *
@@ -130,15 +722,46 @@
  * invoking the callback function with lpContext.
  *
  */
-static HRESULT WINAPI IDirectPlayLobby_EnumLocalApplications
-( LPDIRECTPLAYLOBBY2 this,
+static HRESULT WINAPI IDirectPlayLobbyW_EnumLocalApplications
+( LPDIRECTPLAYLOBBY this,
   LPDPLENUMLOCALAPPLICATIONSCALLBACK a,
   LPVOID lpContext,
   DWORD dwFlags )
 {
   FIXME( dplay, ":stub\n");
   return DPERR_OUTOFMEMORY;
-}
+};
+
+static HRESULT WINAPI IDirectPlayLobby2W_EnumLocalApplications
+( LPDIRECTPLAYLOBBY2 this,
+  LPDPLENUMLOCALAPPLICATIONSCALLBACK a,
+  LPVOID lpContext,
+  DWORD dwFlags )
+{
+  return IDirectPlayLobbyW_EnumLocalApplications( (LPDIRECTPLAYLOBBY)this, a,
+                                                  lpContext, dwFlags ); 
+};
+
+static HRESULT WINAPI IDirectPlayLobbyA_EnumLocalApplications
+( LPDIRECTPLAYLOBBYA this,
+  LPDPLENUMLOCALAPPLICATIONSCALLBACK a,
+  LPVOID lpContext,
+  DWORD dwFlags )
+{
+  FIXME( dplay, ":stub\n");
+  return DPERR_OUTOFMEMORY;
+};
+
+static HRESULT WINAPI IDirectPlayLobby2A_EnumLocalApplications
+( LPDIRECTPLAYLOBBY2A this,
+  LPDPLENUMLOCALAPPLICATIONSCALLBACK a,
+  LPVOID lpContext,
+  DWORD dwFlags )
+{
+  return IDirectPlayLobbyA_EnumLocalApplications( (LPDIRECTPLAYLOBBYA)this, a,
+                                                  lpContext, dwFlags ); 
+};
+
 
 /********************************************************************
  *
@@ -150,16 +773,58 @@
  *        the data structure to be allocated by our caller which can then
  *        call this procedure/method again with a valid data pointer.
  */
-static HRESULT WINAPI IDirectPlayLobby_GetConnectionSettings
-( LPDIRECTPLAYLOBBY2 this,
-  DWORD dwAppID, 
+static HRESULT WINAPI IDirectPlayLobbyA_GetConnectionSettings
+( LPDIRECTPLAYLOBBYA this,
+  DWORD dwAppID,
   LPVOID lpData,
   LPDWORD lpdwDataSize )
 {
-  LPDPLCONNECTION lpConnectionSettings;
+  FIXME( dplay, ": semi stub %p %08lx %p %p \n", this, dwAppID, lpData, lpdwDataSize );
+ 
+  /* Application is requesting us to give the required size */
+  if ( !lpData )
+  {
+    /* Let's check the size of the buffer that the application has allocated */
+    if( *lpdwDataSize >= sizeof( DPLCONNECTION ) )
+    {
+      return DP_OK;
+    }
+    else
+    {
+      *lpdwDataSize = sizeof( DPLCONNECTION );
+      return DPERR_BUFFERTOOSMALL;
+    }
+  }
 
+  /* Fill in the fields - let them just use the ptrs */
+  if( ((LPDPLCONNECTION)lpData)->lpSessionDesc )
+  {
+    
+  }
+  memcpy( lpData, this->lpSession, sizeof( *(this->lpSession) ) );
+
+  return DP_OK;
+}
+
+static HRESULT WINAPI IDirectPlayLobby2A_GetConnectionSettings
+( LPDIRECTPLAYLOBBY2A this,
+  DWORD dwAppID,
+  LPVOID lpData,
+  LPDWORD lpdwDataSize )
+{
+  return IDirectPlayLobbyA_GetConnectionSettings( (LPDIRECTPLAYLOBBYA)this,
+                                                  dwAppID, lpData, lpdwDataSize ); 
+}
+
+static HRESULT WINAPI IDirectPlayLobbyW_GetConnectionSettings
+( LPDIRECTPLAYLOBBY this,
+  DWORD dwAppID,
+  LPVOID lpData,
+  LPDWORD lpdwDataSize )
+{
   FIXME( dplay, ":semi stub %p %08lx %p %p \n", this, dwAppID, lpData, lpdwDataSize );
 
+  /* Application is requesting us to give the required size */ 
   if ( !lpData )
   {
     /* Let's check the size of the buffer that the application has allocated */
@@ -174,12 +839,20 @@
     }
   }
 
-  /* Ok we assume that we've been given a buffer that is large enough for our needs */
-  lpConnectionSettings = ( LPDPLCONNECTION ) lpData; 
+  /* Fill in the fields - let them just use the ptrs */
+  memcpy( lpData, this->lpSession, sizeof( *(this->lpSession) ) );
 
-  /* Fill in the fields */
+  return DP_OK;
+};
 
-  return DPERR_NOTLOBBIED;
+static HRESULT WINAPI IDirectPlayLobby2W_GetConnectionSettings
+( LPDIRECTPLAYLOBBY2 this,
+  DWORD dwAppID,
+  LPVOID lpData,
+  LPDWORD lpdwDataSize )
+{
+  return IDirectPlayLobbyW_GetConnectionSettings( (LPDIRECTPLAYLOBBY)this,
+                                                  dwAppID, lpData, lpdwDataSize );
 }
 
 /********************************************************************
@@ -188,8 +861,8 @@
  * application. All messages are queued until received.
  *
  */
-static HRESULT WINAPI IDirectPlayLobby_ReceiveLobbyMessage
-( LPDIRECTPLAYLOBBY2 this,
+static HRESULT WINAPI IDirectPlayLobbyA_ReceiveLobbyMessage
+( LPDIRECTPLAYLOBBYA this,
   DWORD dwFlags,
   DWORD dwAppID,
   LPDWORD lpdwMessageFlags,
@@ -199,7 +872,45 @@
   FIXME( dplay, ":stub %p %08lx %08lx %p %p %p\n", this, dwFlags, dwAppID, lpdwMessageFlags, lpData,
          lpdwDataSize );
   return DPERR_OUTOFMEMORY;
-}
+};
+
+static HRESULT WINAPI IDirectPlayLobby2A_ReceiveLobbyMessage
+( LPDIRECTPLAYLOBBY2A this,
+  DWORD dwFlags,
+  DWORD dwAppID,
+  LPDWORD lpdwMessageFlags,
+  LPVOID lpData,
+  LPDWORD lpdwDataSize )
+{
+  return IDirectPlayLobbyA_ReceiveLobbyMessage( (LPDIRECTPLAYLOBBYA)this, dwFlags, dwAppID,
+                                                 lpdwMessageFlags, lpData, lpdwDataSize );
+};
+
+
+static HRESULT WINAPI IDirectPlayLobbyW_ReceiveLobbyMessage
+( LPDIRECTPLAYLOBBY this,
+  DWORD dwFlags,
+  DWORD dwAppID,
+  LPDWORD lpdwMessageFlags,
+  LPVOID lpData,
+  LPDWORD lpdwDataSize )
+{
+  FIXME( dplay, ":stub %p %08lx %08lx %p %p %p\n", this, dwFlags, dwAppID, lpdwMessageFlags, lpData,
+         lpdwDataSize );
+  return DPERR_OUTOFMEMORY;
+};
+
+static HRESULT WINAPI IDirectPlayLobby2W_ReceiveLobbyMessage
+( LPDIRECTPLAYLOBBY2 this,
+  DWORD dwFlags,
+  DWORD dwAppID,
+  LPDWORD lpdwMessageFlags,
+  LPVOID lpData,
+  LPDWORD lpdwDataSize )
+{
+  return IDirectPlayLobbyW_ReceiveLobbyMessage( (LPDIRECTPLAYLOBBY)this, dwFlags, dwAppID,
+                                                 lpdwMessageFlags, lpData, lpdwDataSize );
+};
 
 /********************************************************************
  *
@@ -207,8 +918,8 @@
  * connect to a session.
  *
  */
-static HRESULT WINAPI IDirectPlayLobby_RunApplication
-( LPDIRECTPLAYLOBBY2 this,
+static HRESULT WINAPI IDirectPlayLobbyA_RunApplication
+( LPDIRECTPLAYLOBBYA this,
   DWORD dwFlags,
   LPDWORD lpdwAppID,
   LPDPLCONNECTION lpConn,
@@ -216,7 +927,41 @@
 {
   FIXME( dplay, ":stub\n");
   return DPERR_OUTOFMEMORY;
-}
+};
+
+static HRESULT WINAPI IDirectPlayLobby2A_RunApplication
+( LPDIRECTPLAYLOBBY2A this,
+  DWORD dwFlags,
+  LPDWORD lpdwAppID,
+  LPDPLCONNECTION lpConn,
+  HANDLE32 hReceiveEvent )
+{
+  return IDirectPlayLobbyA_RunApplication( (LPDIRECTPLAYLOBBYA)this, dwFlags,
+                                           lpdwAppID, lpConn, hReceiveEvent );
+};
+
+static HRESULT WINAPI IDirectPlayLobbyW_RunApplication
+( LPDIRECTPLAYLOBBY this,
+  DWORD dwFlags,
+  LPDWORD lpdwAppID,
+  LPDPLCONNECTION lpConn,
+  HANDLE32 hReceiveEvent )
+{
+  FIXME( dplay, ":stub\n");
+  return DPERR_OUTOFMEMORY;
+};
+
+static HRESULT WINAPI IDirectPlayLobby2W_RunApplication
+( LPDIRECTPLAYLOBBY2 this,
+  DWORD dwFlags,
+  LPDWORD lpdwAppID,
+  LPDPLCONNECTION lpConn,
+  HANDLE32 hReceiveEvent )
+{
+  return IDirectPlayLobbyW_RunApplication( (LPDIRECTPLAYLOBBY)this, dwFlags,
+                                           lpdwAppID, lpConn, hReceiveEvent );
+};
+
 
 /********************************************************************
  *
@@ -224,8 +969,8 @@
  * All messages are queued until received.
  *
  */
-static HRESULT WINAPI IDirectPlayLobby_SendLobbyMessage
-( LPDIRECTPLAYLOBBY2 this,
+static HRESULT WINAPI IDirectPlayLobbyA_SendLobbyMessage
+( LPDIRECTPLAYLOBBYA this,
   DWORD dwFlags,
   DWORD dwAppID,
   LPVOID lpData,
@@ -233,7 +978,41 @@
 {
   FIXME( dplay, ":stub\n");
   return DPERR_OUTOFMEMORY;
-}
+};
+
+static HRESULT WINAPI IDirectPlayLobby2A_SendLobbyMessage
+( LPDIRECTPLAYLOBBY2A this,
+  DWORD dwFlags,
+  DWORD dwAppID,
+  LPVOID lpData,
+  DWORD dwDataSize )
+{
+  return IDirectPlayLobbyA_SendLobbyMessage( (LPDIRECTPLAYLOBBYA)this, dwFlags, 
+                                             dwAppID, lpData, dwDataSize ); 
+};
+
+
+static HRESULT WINAPI IDirectPlayLobbyW_SendLobbyMessage
+( LPDIRECTPLAYLOBBY this,
+  DWORD dwFlags,
+  DWORD dwAppID,
+  LPVOID lpData,
+  DWORD dwDataSize )
+{
+  FIXME( dplay, ":stub\n");
+  return DPERR_OUTOFMEMORY;
+};
+
+static HRESULT WINAPI IDirectPlayLobby2W_SendLobbyMessage
+( LPDIRECTPLAYLOBBY2 this,
+  DWORD dwFlags,
+  DWORD dwAppID,
+  LPVOID lpData,
+  DWORD dwDataSize )
+{
+  return IDirectPlayLobbyW_SendLobbyMessage( (LPDIRECTPLAYLOBBY)this, dwFlags,
+                                              dwAppID, lpData, dwDataSize );
+};
 
 /********************************************************************
  *
@@ -241,46 +1020,141 @@
  * needed to start and connect an application.
  *
  */
-static HRESULT WINAPI IDirectPlayLobby_SetConnectionSettings
+static HRESULT WINAPI IDirectPlayLobbyW_SetConnectionSettings
+( LPDIRECTPLAYLOBBY this,
+  DWORD dwFlags,
+  DWORD dwAppID,
+  LPDPLCONNECTION lpConn )
+{
+  FIXME( dplay, ": this=%p, dwFlags=%08lx, dwAppId=%08lx, lpConn=%p: semi stub\n",
+         this, dwFlags, dwAppID, lpConn );
+
+  /* Paramater check */
+  if( dwFlags || !this || !lpConn )
+  {
+    ERR( dplay, "invalid parameters.\n");
+    return DPERR_INVALIDPARAMS;
+  }
+
+  /* See if there is a connection associated with this request.
+   * dwAppID == 0 indicates that this request isn't associated with a connection.
+   */
+  if( dwAppID )
+  {
+     FIXME( dplay, ": Connection dwAppID=%08lx given. Not implemented yet.\n",
+            dwAppID );
+
+     /* Need to add a check for this application Id...*/
+     return DPERR_NOTLOBBIED;
+  }
+
+  if(  lpConn->dwSize != sizeof(DPLCONNECTION) )
+  {
+    ERR( dplay, ": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n", 
+         lpConn->dwSize, sizeof( DPLCONNECTION ) );
+    return DPERR_INVALIDPARAMS;
+  }
+
+  /* Need to investigate the lpConn->lpSessionDesc to figure out
+   * what type of session we need to join/create.
+   */
+  if(  (!lpConn->lpSessionDesc ) || 
+       ( lpConn->lpSessionDesc->dwSize != sizeof( DPSESSIONDESC2 ) )
+    )
+  {
+    ERR( dplay, "DPSESSIONDESC passed in? Size=%08lx vs. expected=%ul bytes\n",
+         lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) );
+    return DPERR_INVALIDPARAMS;
+  }
+
+  /* Need to actually store the stuff here */
+
+  return DPERR_OUTOFMEMORY;
+};
+
+static HRESULT WINAPI IDirectPlayLobby2W_SetConnectionSettings
 ( LPDIRECTPLAYLOBBY2 this,
   DWORD dwFlags,
   DWORD dwAppID,
   LPDPLCONNECTION lpConn )
 {
+  return IDirectPlayLobbyW_SetConnectionSettings( (LPDIRECTPLAYLOBBY)this, 
+                                                  dwFlags, dwAppID, lpConn );
+}
+
+static HRESULT WINAPI IDirectPlayLobbyA_SetConnectionSettings
+( LPDIRECTPLAYLOBBYA this,
+  DWORD dwFlags,
+  DWORD dwAppID,
+  LPDPLCONNECTION lpConn )
+{
   FIXME( dplay, ": this=%p, dwFlags=%08lx, dwAppId=%08lx, lpConn=%p: stub\n",
          this, dwFlags, dwAppID, lpConn );
-
-  /* Paramater check */
-  if( dwFlags || !this || !lpConn )
-  {
-    return DPERR_INVALIDPARAMS;
-  }
-
-  if( !( lpConn->dwSize == sizeof(DPLCONNECTION) ) )
-  {
-    /* Is this the right return code? */
-    return DPERR_INVALIDPARAMS;
-  }
-
   return DPERR_OUTOFMEMORY;
 }
 
+static HRESULT WINAPI IDirectPlayLobby2A_SetConnectionSettings
+( LPDIRECTPLAYLOBBY2A this,
+  DWORD dwFlags,
+  DWORD dwAppID,
+  LPDPLCONNECTION lpConn )
+{
+  return IDirectPlayLobbyA_SetConnectionSettings( (LPDIRECTPLAYLOBBYA)this,
+                                                  dwFlags, dwAppID, lpConn );
+};
+
 /********************************************************************
  *
  * Registers an event that will be set when a lobby message is received.
  *
  */
-static HRESULT WINAPI IDirectPlayLobby_SetLobbyMessageEvent
-( LPDIRECTPLAYLOBBY2 this,
+static HRESULT WINAPI IDirectPlayLobbyA_SetLobbyMessageEvent
+( LPDIRECTPLAYLOBBYA this,
   DWORD dwFlags,
   DWORD dwAppID,
   HANDLE32 hReceiveEvent )
 {
   FIXME( dplay, ":stub\n");
   return DPERR_OUTOFMEMORY;
-}
+};
 
-static HRESULT WINAPI IDirectPlayLobby_CreateCompoundAddress
+static HRESULT WINAPI IDirectPlayLobby2A_SetLobbyMessageEvent
+( LPDIRECTPLAYLOBBY2A this,
+  DWORD dwFlags,
+  DWORD dwAppID,
+  HANDLE32 hReceiveEvent )
+{
+  return IDirectPlayLobbyA_SetLobbyMessageEvent( (LPDIRECTPLAYLOBBYA)this, dwFlags,
+                                                 dwAppID, hReceiveEvent ); 
+};
+
+static HRESULT WINAPI IDirectPlayLobbyW_SetLobbyMessageEvent
+( LPDIRECTPLAYLOBBY this,
+  DWORD dwFlags,
+  DWORD dwAppID,
+  HANDLE32 hReceiveEvent )
+{
+  FIXME( dplay, ":stub\n");
+  return DPERR_OUTOFMEMORY;
+};
+
+static HRESULT WINAPI IDirectPlayLobby2W_SetLobbyMessageEvent
+( LPDIRECTPLAYLOBBY2 this,
+  DWORD dwFlags,
+  DWORD dwAppID,
+  HANDLE32 hReceiveEvent )
+{
+  return IDirectPlayLobbyW_SetLobbyMessageEvent( (LPDIRECTPLAYLOBBY)this, dwFlags,
+                                                 dwAppID, hReceiveEvent ); 
+};
+
+
+/********************************************************************
+ *
+ * Registers an event that will be set when a lobby message is received.
+ *
+ */
+static HRESULT WINAPI IDirectPlayLobby2W_CreateCompoundAddress
 ( LPDIRECTPLAYLOBBY2 this,
   LPCDPCOMPOUNDADDRESSELEMENT lpElements,
   DWORD dwElementCount,
@@ -289,25 +1163,93 @@
 {
   FIXME( dplay, ":stub\n");
   return DPERR_OUTOFMEMORY;
-}
+};
 
-/* Direct Play Lobby 2 Virtual Table for methods */
-static struct tagLPDIRECTPLAYLOBBY2_VTABLE lobby2VT = {
-  IDirectPlayLobby_QueryInterface,
-  IDirectPlayLobby_AddRef, 
-  IDirectPlayLobby_Release,
-  IDirectPlayLobby_Connect,
-  IDirectPlayLobby_CreateAddress,
-  IDirectPlayLobby_EnumAddress,
-  IDirectPlayLobby_EnumAddressTypes,
-  IDirectPlayLobby_EnumLocalApplications,
-  IDirectPlayLobby_GetConnectionSettings,
-  IDirectPlayLobby_ReceiveLobbyMessage,
-  IDirectPlayLobby_RunApplication,
-  IDirectPlayLobby_SendLobbyMessage,
-  IDirectPlayLobby_SetConnectionSettings,
-  IDirectPlayLobby_SetLobbyMessageEvent,
-  IDirectPlayLobby_CreateCompoundAddress
+static HRESULT WINAPI IDirectPlayLobby2A_CreateCompoundAddress
+( LPDIRECTPLAYLOBBY2A this,
+  LPCDPCOMPOUNDADDRESSELEMENT lpElements,
+  DWORD dwElementCount,
+  LPVOID lpAddress,
+  LPDWORD lpdwAddressSize )
+{
+  FIXME( dplay, ":stub\n");
+  return DPERR_OUTOFMEMORY;
+};
+
+
+/* Direct Play Lobby 1 (ascii) Virtual Table for methods */
+static struct tagLPDIRECTPLAYLOBBY_VTABLE directPlayLobbyAVT = {
+  IDirectPlayLobbyA_QueryInterface,
+  IDirectPlayLobbyA_AddRef,
+  IDirectPlayLobbyA_Release,
+  IDirectPlayLobbyA_Connect,
+  IDirectPlayLobbyA_CreateAddress,
+  IDirectPlayLobbyA_EnumAddress,
+  IDirectPlayLobbyA_EnumAddressTypes,
+  IDirectPlayLobbyA_EnumLocalApplications,
+  IDirectPlayLobbyA_GetConnectionSettings,
+  IDirectPlayLobbyA_ReceiveLobbyMessage,
+  IDirectPlayLobbyA_RunApplication,
+  IDirectPlayLobbyA_SendLobbyMessage,
+  IDirectPlayLobbyA_SetConnectionSettings,
+  IDirectPlayLobbyA_SetLobbyMessageEvent
+};
+
+/* Direct Play Lobby 1 (unicode) Virtual Table for methods */
+static struct tagLPDIRECTPLAYLOBBY_VTABLE directPlayLobbyWVT = {
+  IDirectPlayLobbyW_QueryInterface,
+  IDirectPlayLobbyW_AddRef,
+  IDirectPlayLobbyW_Release,
+  IDirectPlayLobbyW_Connect,
+  IDirectPlayLobbyW_CreateAddress, 
+  IDirectPlayLobbyW_EnumAddress,
+  IDirectPlayLobbyW_EnumAddressTypes,
+  IDirectPlayLobbyW_EnumLocalApplications,
+  IDirectPlayLobbyW_GetConnectionSettings,
+  IDirectPlayLobbyW_ReceiveLobbyMessage,
+  IDirectPlayLobbyW_RunApplication,
+  IDirectPlayLobbyW_SendLobbyMessage,
+  IDirectPlayLobbyW_SetConnectionSettings,
+  IDirectPlayLobbyW_SetLobbyMessageEvent
+};
+
+
+/* Direct Play Lobby 2 (ascii) Virtual Table for methods */
+static struct tagLPDIRECTPLAYLOBBY2_VTABLE directPlayLobby2AVT = {
+  IDirectPlayLobby2A_QueryInterface,
+  IDirectPlayLobby2A_AddRef,
+  IDirectPlayLobby2A_Release,
+  IDirectPlayLobby2A_Connect,
+  IDirectPlayLobby2A_CreateAddress,
+  IDirectPlayLobby2A_EnumAddress,
+  IDirectPlayLobby2A_EnumAddressTypes,
+  IDirectPlayLobby2A_EnumLocalApplications,
+  IDirectPlayLobby2A_GetConnectionSettings,
+  IDirectPlayLobby2A_ReceiveLobbyMessage,
+  IDirectPlayLobby2A_RunApplication,
+  IDirectPlayLobby2A_SendLobbyMessage,
+  IDirectPlayLobby2A_SetConnectionSettings,
+  IDirectPlayLobby2A_SetLobbyMessageEvent,
+  IDirectPlayLobby2A_CreateCompoundAddress 
+};
+
+/* Direct Play Lobby 2 (unicode) Virtual Table for methods */
+static struct tagLPDIRECTPLAYLOBBY2_VTABLE directPlayLobby2WVT = {
+  IDirectPlayLobby2W_QueryInterface,
+  IDirectPlayLobby2W_AddRef, 
+  IDirectPlayLobby2W_Release,
+  IDirectPlayLobby2W_Connect,
+  IDirectPlayLobby2W_CreateAddress,
+  IDirectPlayLobby2W_EnumAddress,
+  IDirectPlayLobby2W_EnumAddressTypes,
+  IDirectPlayLobby2W_EnumLocalApplications,
+  IDirectPlayLobby2W_GetConnectionSettings,
+  IDirectPlayLobby2W_ReceiveLobbyMessage,
+  IDirectPlayLobby2W_RunApplication,
+  IDirectPlayLobby2W_SendLobbyMessage,
+  IDirectPlayLobby2W_SetConnectionSettings,
+  IDirectPlayLobby2W_SetLobbyMessageEvent,
+  IDirectPlayLobby2W_CreateCompoundAddress
 };
 
 /***************************************************************************
@@ -315,7 +1257,7 @@
  *
  */
 HRESULT WINAPI DirectPlayLobbyCreateA( LPGUID lpGUIDDSP,
-                                       LPDIRECTPLAYLOBBY2A *lplpDPL,
+                                       LPDIRECTPLAYLOBBYA *lplpDPL,
                                        IUnknown *lpUnk, 
                                        LPVOID lpData,
                                        DWORD dwDataSize )
@@ -332,18 +1274,26 @@
      return DPERR_INVALIDPARAMS;
   }
 
-  *lplpDPL = (LPDIRECTPLAYLOBBY2A)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                            sizeof( IDirectPlayLobby2A ) );
+  /* Yes...really we should bre returning a lobby 1 object */
+  *lplpDPL = (LPDIRECTPLAYLOBBYA)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                            sizeof( IDirectPlayLobbyA ) );
 
   if( ! (*lplpDPL) )
   {
      return DPERR_OUTOFMEMORY;
   }
 
-  (*lplpDPL)->lpvtbl = &lobby2VT;
+  (*lplpDPL)->lpVtbl = &directPlayLobbyAVT;
   (*lplpDPL)->ref    = 1;
 
-  /* Still some stuff to do here */
+  (*lplpDPL)->lpSession = (LPDPLCONNECTION)HeapAlloc( GetProcessHeap(),
+                                                      HEAP_ZERO_MEMORY,
+                                                      sizeof( DPLCONNECTION ) );
+  (*lplpDPL)->lpSession->dwSize = sizeof( DPLCONNECTION );
+
+  (*lplpDPL)->lpSession->lpSessionDesc = (LPDPSESSIONDESC2)HeapAlloc(
+          GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( DPSESSIONDESC2 ) );
+  (*lplpDPL)->lpSession->lpSessionDesc->dwSize = sizeof( DPSESSIONDESC2 ); 
 
   return DP_OK;
 }
@@ -353,7 +1303,7 @@
  *
  */
 HRESULT WINAPI DirectPlayLobbyCreateW( LPGUID lpGUIDDSP, 
-                                       LPDIRECTPLAYLOBBY2 *lplpDPL,
+                                       LPDIRECTPLAYLOBBY *lplpDPL,
                                        IUnknown *lpUnk,
                                        LPVOID lpData, 
                                        DWORD dwDataSize )
@@ -367,20 +1317,31 @@
   if ( lpGUIDDSP || lpUnk || lpData || dwDataSize )
   {
      *lplpDPL = NULL;
+     ERR( dplay, "Bad parameters!\n" );
      return DPERR_INVALIDPARAMS;
   }
 
-  *lplpDPL = (LPDIRECTPLAYLOBBY2)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                           sizeof( IDirectPlayLobby2 ) );
+  /* Yes...really we should bre returning a lobby 1 object */
+  *lplpDPL = (LPDIRECTPLAYLOBBY)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                           sizeof( IDirectPlayLobby ) );
 
   if( !*lplpDPL)
   {
      return DPERR_OUTOFMEMORY;
   }
 
-  (*lplpDPL)->lpvtbl = &lobby2VT;
+  (*lplpDPL)->lpVtbl = &directPlayLobbyWVT;
   (*lplpDPL)->ref    = 1;
 
+
+  (*lplpDPL)->lpSession = (LPDPLCONNECTION)HeapAlloc( GetProcessHeap(), 
+                                                      HEAP_ZERO_MEMORY,
+                                                      sizeof( DPLCONNECTION ) );
+  (*lplpDPL)->lpSession->dwSize = sizeof( DPLCONNECTION );
+  (*lplpDPL)->lpSession->lpSessionDesc = (LPDPSESSIONDESC2)HeapAlloc(
+          GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( DPSESSIONDESC2 ) );
+  (*lplpDPL)->lpSession->lpSessionDesc->dwSize = sizeof( DPSESSIONDESC2 ); 
+
   return DP_OK;
 
 }
@@ -499,7 +1460,7 @@
 
   return DP_OK;
 
-}
+};
 
 /***************************************************************************
  *  DirectPlayEnumerateW (DPLAYX.3)
@@ -512,17 +1473,40 @@
 
   return DPERR_OUTOFMEMORY; 
 
-}
+};
 
 /***************************************************************************
  *  DirectPlayCreate (DPLAYX.1) (DPLAY.1)
  *
  */
 HRESULT WINAPI DirectPlayCreate
-( LPGUID lpGUID, LPDIRECTPLAY *lplpDP, IUnknown *pUnk)
+( LPGUID lpGUID, LPDIRECTPLAY2 *lplpDP, IUnknown *pUnk)
 {
 
   FIXME( dplay, ":stub\n");
   return DPERR_OUTOFMEMORY;
 
-}
+  TRACE(dplay,"\n" );
+
+  if( pUnk != NULL )
+  {
+    /* Hmmm...wonder what this means! */
+    ERR(dplay, "What does a NULL here mean?\n" ); 
+    return DPERR_OUTOFMEMORY;
+  }
+
+  *lplpDP = (LPDIRECTPLAY)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                     sizeof( **lplpDP ) );
+
+  if( !*lplpDP )
+  {
+     return DPERR_OUTOFMEMORY;
+  }
+
+  (*lplpDP)->lpVtbl = &directPlay2AVT;
+  (*lplpDP)->ref    = 1;
+
+  return DP_OK;
+
+};
+
diff --git a/multimedia/init.c b/multimedia/init.c
index 7d138c8..0e3e0b0 100644
--- a/multimedia/init.c
+++ b/multimedia/init.c
@@ -1,3 +1,5 @@
+/* -*- tab-width: 8; c-basic-offset: 4 -*- */
+
 /*
  * Initialization procedures for multimedia
  *
@@ -15,8 +17,13 @@
 
 #ifdef HAVE_OSS
 
-extern int MODM_NUMDEVS;
-extern LPMIDIOUTCAPS16 midiDevices[MAX_MIDIOUTDRV];
+extern int 		MODM_NUMDEVS;
+extern int		MODM_NUMFMSYNTHDEVS;
+extern int		MODM_NUMMIDIDEVS;
+extern LPMIDIOUTCAPS16	midiOutDevices[MAX_MIDIOUTDRV];
+
+extern int		MIDM_NUMDEVS;
+extern LPMIDIINCAPS16	midiInDevices [MAX_MIDIINDRV];
 
 #endif
 
@@ -29,23 +36,25 @@
 #ifdef HAVE_OSS
 int unixToWindowsDeviceType(int type)
 {
-  /* MOD_MIDIPORT     output port 
-   * MOD_SYNTH        generic internal synth 
-   * MOD_SQSYNTH      square wave internal synth 
-   * MOD_FMSYNTH      FM internal synth 
-   * MOD_MAPPER       MIDI mapper
-   */
-
-  /* FIXME Is this really the correct equivalence from UNIX to Windows Sound type */
-
-  switch (type) {
-  case SYNTH_TYPE_FM:     return MOD_FMSYNTH;
-  case SYNTH_TYPE_SAMPLE: return MOD_SYNTH;
-  case SYNTH_TYPE_MIDI:   return MOD_MIDIPORT;
-  default:
-    ERR(midi, "Cannot determine the type of this midi device. Assuming FM Synth\n");
-    return MOD_FMSYNTH;
-  }
+    /* MOD_MIDIPORT     output port 
+     * MOD_SYNTH        generic internal synth 
+     * MOD_SQSYNTH      square wave internal synth 
+     * MOD_FMSYNTH      FM internal synth 
+     * MOD_MAPPER       MIDI mapper
+     */
+    
+    /* FIXME Is this really the correct equivalence from UNIX to 
+       Windows Sound type */
+    
+    switch (type) {
+    case SYNTH_TYPE_FM:     return MOD_FMSYNTH;
+    case SYNTH_TYPE_SAMPLE: return MOD_SYNTH;
+    case SYNTH_TYPE_MIDI:   return MOD_MIDIPORT;
+    default:
+	ERR(midi, "Cannot determine the type of this midi device. "
+	    "Assuming FM Synth\n");
+	return MOD_FMSYNTH;
+    }
 }
 #endif
 
@@ -55,135 +64,186 @@
  * Initializes the MIDI devices information variables
  *
  */
-BOOL32 MULTIMEDIA_Init (void)
+BOOL32 MULTIMEDIA_Init(void)
 {
 #ifdef HAVE_OSS
-  int i, status, numsynthdevs=255, nummididevs=255;
-  struct synth_info sinfo;
-  struct midi_info minfo;
-  int fd;        /* file descriptor for MIDI_DEV */
-
-  TRACE (midi, "Initializing the MIDI variables.\n");
-  /* try to open device */
-  fd = open(MIDI_DEV, O_WRONLY);
-  if (fd == -1) {
-    TRACE (midi, "No soundcards founds: unable to open `%s'.\n", MIDI_DEV);
-    return TRUE;
-  }
-
-  /* find how many Synth devices are there in the system */
-  status = ioctl(fd, SNDCTL_SEQ_NRSYNTHS, &numsynthdevs);
-
-  if (numsynthdevs > MAX_MIDIOUTDRV) {
-    ERR (midi, "MAX_MIDIOUTDRV was enough for the number of devices. Some FM devices will not be available.\n");
-    numsynthdevs = MAX_MIDIOUTDRV;
-  }
-  
-  if (status == -1) {
-    ERR (midi, "ioctl failed.\n");
-    close(fd);
-    return TRUE;
-  }
-
-  for (i = 0 ; i < numsynthdevs ; i++) {
-    LPMIDIOUTCAPS16 tmplpCaps;
-
-    sinfo.device = i;
-    status = ioctl(fd, SNDCTL_SYNTH_INFO, &sinfo);
-    if (status == -1) {
-      ERR(midi, "ioctl failed.\n");
-      close(fd);
-      return TRUE;
+    int 		i, status, numsynthdevs = 255, nummididevs = 255;
+    struct synth_info 	sinfo;
+    struct midi_info 	minfo;
+    int 		fd;        /* file descriptor for MIDI_SEQ */
+    
+    TRACE(midi, "Initializing the MIDI variables.\n");
+    
+    /* try to open device */
+    /* FIXME: should use function midiOpenSeq() in midi.c */
+    fd = open(MIDI_SEQ, O_WRONLY);
+    if (fd == -1) {
+	TRACE(midi, "No sequencer found: unable to open `%s'.\n", MIDI_SEQ);
+	return TRUE;
     }
-
-    tmplpCaps = xmalloc (sizeof (MIDIOUTCAPS16));
-    /* We also have the information sinfo.synth_subtype, not used here
-     */
     
-    /* Manufac ID. We do not have access to this with soundcard.h
-     * Does not seem to be a problem, because in mmsystem.h only
-     * Microsoft's ID is listed.
-     */
-    tmplpCaps->wMid = 0x00FF; 
-    tmplpCaps->wPid = 0x0001; 	/* FIXME Product ID  */
-    tmplpCaps->vDriverVersion = 0x001; /* Product Version. We simply say "1" */
-    strcpy(tmplpCaps->szPname, sinfo.name);
-
-    tmplpCaps->wTechnology = unixToWindowsDeviceType (sinfo.synth_type);
-    tmplpCaps->wVoices     = sinfo.nr_voices;
-
-    /* FIXME Is it possible to know the maximum
-     * number of simultaneous notes of a soundcard ?
-     * I beleive we don't have this information, but
-     * it's probably equal or more than wVoices
-     */
-    tmplpCaps->wNotes      = sinfo.nr_voices;  
-
-    /* FIXME Do we have this information?
-     * Assuming the soundcards can handle
-     * MIDICAPS_VOLUME and MIDICAPS_LRVOLUME but
-     * not MIDICAPS_CACHE.
-     */
-    tmplpCaps->dwSupport   = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME;
+    /* find how many Synth devices are there in the system */
+    status = ioctl(fd, SNDCTL_SEQ_NRSYNTHS, &numsynthdevs);
     
-    midiDevices[i] = tmplpCaps;
-    
-    TRACE(midi,"techn = %d voices=%d notes = %d support = %ld\n",tmplpCaps->wTechnology,tmplpCaps->wVoices,tmplpCaps->wNotes,tmplpCaps->dwSupport);
-  }
-  
-  /* find how many MIDI devices are there in the system */
-  status = ioctl(fd, SNDCTL_SEQ_NRMIDIS, &nummididevs);
-  if (status == -1) {
-    ERR(midi, "ioctl failed.\n");
-    close(fd);
-    return TRUE;
-  }
-
-  if (numsynthdevs + nummididevs > MAX_MIDIOUTDRV) {
-    ERR(midi, "MAX_MIDIOUTDRV was enough for the number of devices. Some MIDI devices will not be available.\n");
-    nummididevs = MAX_MIDIOUTDRV - numsynthdevs;
-  }
-
-  /* windows does not seem to diferentiate Synth from MIDI devices */
-  MODM_NUMDEVS = numsynthdevs + nummididevs;
-  
-  for (i = 0 ; i < nummididevs ; i++) {
-    LPMIDIOUTCAPS16 tmplpCaps;
-
-    minfo.device = i;
-    status = ioctl(fd, SNDCTL_MIDI_INFO, &minfo);
     if (status == -1) {
-      ERR(midi, "ioctl failed.\n");
-      close(fd);
-      return TRUE;
+	ERR(midi, "ioctl for nr synth failed.\n");
+	close(fd);
+	return TRUE;
     }
-
-    tmplpCaps = xmalloc (sizeof (MIDIOUTCAPS16));
-    /* This whole part is somewhat obscure to me. I'll keep trying to dig
-       info about it. If you happen to know, please tell us. The very descritive
-       minfo.dev_type was not used here.
-     */
-    tmplpCaps->wMid = 0x00FF; 	/* Manufac ID. We do not have access to this with soundcard.h
-				   Does not seem to be a problem, because in mmsystem.h only
-				   Microsoft's ID is listed */
-    tmplpCaps->wPid = 0x0001; 	/* FIXME Product ID */
-    tmplpCaps->vDriverVersion = 0x001; /* Product Version. We simply say "1" */
-    strcpy(tmplpCaps->szPname, minfo.name);
-
-    tmplpCaps->wTechnology =  MOD_MIDIPORT; /* FIXME Is this right? */
-    tmplpCaps->wVoices     = 16;            /* Does it make any difference? */
-    tmplpCaps->wNotes      = 16;            /* Does it make any difference? */
-    tmplpCaps->dwSupport   = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME; /* FIXME Does it make any difference? */
-
-    midiDevices[numsynthdevs + i] = tmplpCaps;
-
-    TRACE(midi,"techn = %d voices=%d notes = %d support = %ld\n",tmplpCaps->wTechnology,tmplpCaps->wVoices,tmplpCaps->wNotes,tmplpCaps->dwSupport);
-  }
-  
-  /* close file and exit */
-  close(fd);
-
+    
+    if (numsynthdevs > MAX_MIDIOUTDRV) {
+	ERR(midi, "MAX_MIDIOUTDRV was enough for the number of devices. "
+	    "Some FM devices will not be available.\n");
+	numsynthdevs = MAX_MIDIOUTDRV;
+    }
+    
+    for (i = 0; i < numsynthdevs; i++) {
+	LPMIDIOUTCAPS16 tmplpCaps;
+	
+	sinfo.device = i;
+	status = ioctl(fd, SNDCTL_SYNTH_INFO, &sinfo);
+	if (status == -1) {
+	    ERR(midi, "ioctl for synth info failed.\n");
+	    close(fd);
+	    return TRUE;
+	}
+	
+	tmplpCaps = xmalloc(sizeof(MIDIOUTCAPS16));
+	/* We also have the information sinfo.synth_subtype, not used here
+	 */
+	
+	/* Manufac ID. We do not have access to this with soundcard.h
+	 * Does not seem to be a problem, because in mmsystem.h only
+	 * Microsoft's ID is listed.
+	 */
+	tmplpCaps->wMid = 0x00FF; 
+	tmplpCaps->wPid = 0x0001; 	/* FIXME Product ID  */
+	/* Product Version. We simply say "1" */
+	tmplpCaps->vDriverVersion = 0x001; 
+	strcpy(tmplpCaps->szPname, sinfo.name);
+	
+	tmplpCaps->wTechnology = unixToWindowsDeviceType(sinfo.synth_type);
+	tmplpCaps->wVoices     = sinfo.nr_voices;
+	
+	/* FIXME Is it possible to know the maximum
+	 * number of simultaneous notes of a soundcard ?
+	 * I believe we don't have this information, but
+	 * it's probably equal or more than wVoices
+	 */
+	tmplpCaps->wNotes      = sinfo.nr_voices;  
+	
+	/* FIXME Do we have this information?
+	 * Assuming the soundcards can handle
+	 * MIDICAPS_VOLUME and MIDICAPS_LRVOLUME but
+	 * not MIDICAPS_CACHE.
+	 */
+	tmplpCaps->dwSupport   = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME;
+	
+	midiOutDevices[i] = tmplpCaps;
+	
+	if (sinfo.capabilities & SYNTH_CAP_INPUT) {
+	    FIXME(midi, "Synthetizer support MIDI in. Not supported yet (please report)\n");
+	}
+	
+	TRACE(midi, "name='%s', techn=%d voices=%d notes=%d support=%ld\n", 
+	      tmplpCaps->szPname, tmplpCaps->wTechnology,
+	      tmplpCaps->wVoices, tmplpCaps->wNotes, tmplpCaps->dwSupport);
+	TRACE(midi,"OSS info: synth subtype=%d capa=%Xh\n", 
+	      sinfo.synth_subtype, sinfo.capabilities);
+    }
+    
+    /* find how many MIDI devices are there in the system */
+    status = ioctl(fd, SNDCTL_SEQ_NRMIDIS, &nummididevs);
+    if (status == -1) {
+	ERR(midi, "ioctl on nr midi failed.\n");
+	return TRUE;
+    }
+    
+    /* FIXME: the two restrictions below could be loosen in some cases */
+    if (numsynthdevs + nummididevs > MAX_MIDIOUTDRV) {
+	ERR(midi, "MAX_MIDIOUTDRV was not enough for the number of devices. "
+	    "Some MIDI devices will not be available.\n");
+	nummididevs = MAX_MIDIOUTDRV - numsynthdevs;
+    }
+    
+    if (nummididevs > MAX_MIDIINDRV) {
+	ERR(midi, "MAX_MIDIINDRV was not enough for the number of devices. "
+	    "Some MIDI devices will not be available.\n");
+	nummididevs = MAX_MIDIINDRV;
+    }
+    
+    for (i = 0; i < nummididevs; i++) {
+	LPMIDIOUTCAPS16 tmplpOutCaps;
+	LPMIDIINCAPS16  tmplpInCaps;
+	
+	minfo.device = i;
+	status = ioctl(fd, SNDCTL_MIDI_INFO, &minfo);
+	if (status == -1) {
+	    ERR(midi, "ioctl on midi info failed.\n");
+	    close(fd);
+	    return TRUE;
+	}
+	
+	tmplpOutCaps = xmalloc(sizeof(MIDIOUTCAPS16));
+	/* This whole part is somewhat obscure to me. I'll keep trying to dig
+	   info about it. If you happen to know, please tell us. The very 
+	   descritive minfo.dev_type was not used here.
+	*/
+	/* Manufac ID. We do not have access to this with soundcard.h
+	   Does not seem to be a problem, because in mmsystem.h only
+	   Microsoft's ID is listed */
+	tmplpOutCaps->wMid = 0x00FF; 	
+	tmplpOutCaps->wPid = 0x0001; 	/* FIXME Product ID */
+	/* Product Version. We simply say "1" */
+	tmplpOutCaps->vDriverVersion = 0x001; 
+	strcpy(tmplpOutCaps->szPname, minfo.name);
+	
+	tmplpOutCaps->wTechnology = MOD_MIDIPORT; /* FIXME Is this right? */
+	/* Does it make any difference? */
+	tmplpOutCaps->wVoices     = 16;            
+	/* Does it make any difference? */
+	tmplpOutCaps->wNotes      = 16;
+	/* FIXME Does it make any difference? */
+	tmplpOutCaps->dwSupport   = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME; 
+	
+	midiOutDevices[numsynthdevs + i] = tmplpOutCaps;
+	
+	tmplpInCaps = xmalloc(sizeof(MIDIOUTCAPS16));
+	/* This whole part is somewhat obscure to me. I'll keep trying to dig
+	   info about it. If you happen to know, please tell us. The very 
+	   descritive minfo.dev_type was not used here.
+	*/
+	/* Manufac ID. We do not have access to this with soundcard.h
+	   Does not seem to be a problem, because in mmsystem.h only
+	   Microsoft's ID is listed */
+	tmplpInCaps->wMid = 0x00FF; 	
+	tmplpInCaps->wPid = 0x0001; 	/* FIXME Product ID */
+	/* Product Version. We simply say "1" */
+	tmplpInCaps->vDriverVersion = 0x001; 
+	strcpy(tmplpInCaps->szPname, minfo.name);
+	
+	/* FIXME : could we get better information than that ? */
+	tmplpInCaps->dwSupport   = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME; 
+	
+	midiInDevices[i] = tmplpInCaps;
+	
+	TRACE(midi,"name='%s' techn=%d voices=%d notes=%d support=%ld\n",
+	      tmplpOutCaps->szPname, tmplpOutCaps->wTechnology, tmplpOutCaps->wVoices,
+	      tmplpOutCaps->wNotes, tmplpOutCaps->dwSupport);
+	TRACE(midi,"OSS info: midi dev-type=%d, capa=%d\n", 
+	      minfo.dev_type, minfo.capabilities);
+    }
+    
+    /* windows does not seem to differentiate Synth from MIDI devices */
+    MODM_NUMFMSYNTHDEVS = numsynthdevs;
+    MODM_NUMMIDIDEVS    = nummididevs;
+    MODM_NUMDEVS        = numsynthdevs + nummididevs;
+    
+    MIDM_NUMDEVS        = nummididevs;
+    
+    /* close file and exit */
+    close(fd);	
 #endif /* HAVE_OSS */
-  
-  return TRUE;
+    
+    return TRUE;
 }
diff --git a/multimedia/midi.c b/multimedia/midi.c
index c7cae5a..3200e9e 100644
--- a/multimedia/midi.c
+++ b/multimedia/midi.c
@@ -1,15 +1,23 @@
+/* -*- tab-width: 8; c-basic-offset: 4 -*- */
+
 /*
  * Sample MIDI Wine Driver for Linux
  *
  * Copyright 1994 Martin Ayotte
  */
 
+/* 
+ * Eric POUECH : 98/7 changes for making this MIDI driver work on OSS
+ * current support is limited to MIDI ports of OSS systems
+ */
+
 #include <errno.h>
 #include <string.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <sys/ioctl.h>
 #include "windows.h"
 #include "ldt.h"
 #include "multimedia.h"
@@ -18,294 +26,327 @@
 #include "mmsystem.h"
 #include "xmalloc.h"
 #include "debug.h"
+#include "callback.h"
+#include "options.h"
 
-static LINUX_MIDIIN	MidiInDev[MAX_MIDIINDRV];
+static LINUX_MIDIIN	MidiInDev [MAX_MIDIINDRV ];
 static LINUX_MIDIOUT	MidiOutDev[MAX_MIDIOUTDRV];
 static LINUX_MCIMIDI	MCIMidiDev[MAX_MCIMIDIDRV];
 
-/* this is the total number of MIDI devices found */
-int MODM_NUMDEVS = 0;
+/* this is the total number of MIDI out devices found */
+int 	MODM_NUMDEVS = 0;				
+/* this is the number of FM synthetizers (index from 0 to 
+   NUMFMSYNTHDEVS - 1) */
+int	MODM_NUMFMSYNTHDEVS = 0;	
+/* this is the number of Midi ports (index from NUMFMSYNTHDEVS to 
+   NUMFMSYNTHDEVS + NUMMIDIDEVS - 1) */
+int	MODM_NUMMIDIDEVS = 0;		
+
+/* this is the total number of MIDI out devices found */
+int 	MIDM_NUMDEVS = 0;				
+
+#ifdef HAVE_OSS
+static	int		midiSeqFD = -1;
+static	int		numOpenMidiSeq = 0;
+static	UINT32		midiInTimerID = 0;
+static	int		numStartedMidiIn = 0;
+#endif /* HAVE_OSS */
 
 /* this structure holds pointers with information for each MIDI
- * device found.
+ * out device found.
  */
-LPMIDIOUTCAPS16 midiDevices[MAX_MIDIOUTDRV];
+LPMIDIOUTCAPS16 midiOutDevices[MAX_MIDIOUTDRV];
+
+/* this structure holds pointers with information for each MIDI
+ * in device found.
+ */
+LPMIDIINCAPS16  midiInDevices [MAX_MIDIINDRV];
+
+/* 
+ * FIXME : all tests on device ID for midXXX and modYYY are made against 
+ * MAX_MIDIxxDRV (when they are made) but should be done against the actual
+ * number of midi devices found...
+ * check also when HAVE_OSS is defined that midiDesc is not NULL
+ */
 
 /**************************************************************************
  * 			MIDI_NotifyClient			[internal]
  */
 static DWORD MIDI_NotifyClient(UINT16 wDevID, WORD wMsg, 
-				DWORD dwParam1, DWORD dwParam2)
+			       DWORD dwParam1, DWORD dwParam2)
 {
-	TRACE(midi,"wDevID = %04X wMsg = %d dwParm1 = %04lX dwParam2 = %04lX\n",wDevID, wMsg, dwParam1, dwParam2);
-
-	switch (wMsg) {
-	case MOM_OPEN:
-	case MOM_CLOSE:
-	case MOM_DONE:
-	  if (wDevID > MAX_MIDIOUTDRV) return MCIERR_INTERNAL;
-	  
-	  if (MidiOutDev[wDevID].wFlags != DCB_NULL && !DriverCallback(
-		MidiOutDev[wDevID].midiDesc.dwCallback, 
-		MidiOutDev[wDevID].wFlags, 
-		MidiOutDev[wDevID].midiDesc.hMidi, 
-                wMsg, 
-		MidiOutDev[wDevID].midiDesc.dwInstance, 
-                dwParam1, 
-                dwParam2)) {
-	    WARN(midi,"can't notify client !\n");
-	    return MMSYSERR_NOERROR;
-	  }
-	  break;
-
-	case MIM_OPEN:
-	case MIM_CLOSE:
-	  if (wDevID > MAX_MIDIINDRV) return MCIERR_INTERNAL;
-	  
-	if (MidiInDev[wDevID].wFlags != DCB_NULL && !DriverCallback(
-		MidiInDev[wDevID].midiDesc.dwCallback, MidiInDev[wDevID].wFlags, 
-		MidiInDev[wDevID].midiDesc.hMidi, wMsg, 
-		MidiInDev[wDevID].midiDesc.dwInstance, dwParam1, dwParam2)) {
-	    WARN(mciwave,"can't notify client !\n");
-		return MMSYSERR_NOERROR;
-		}
-	  break;
-	}
-        return 0;
+    DWORD 		dwCallBack;
+    UINT16 		uFlags;
+    HANDLE16 		hDev;
+    DWORD 		dwInstance;
+    
+    TRACE(midi,"wDevID = %04X wMsg = %d dwParm1 = %04lX dwParam2 = %04lX\n", 
+	  wDevID, wMsg, dwParam1, dwParam2);
+    
+    switch (wMsg) {
+    case MOM_OPEN:
+    case MOM_CLOSE:
+    case MOM_DONE:
+	if (wDevID > MAX_MIDIOUTDRV) 
+	    return MCIERR_INTERNAL;
+	
+	dwCallBack = MidiOutDev[wDevID].midiDesc->dwCallback;
+	uFlags = MidiOutDev[wDevID].wFlags;
+	hDev = MidiOutDev[wDevID].midiDesc->hMidi;
+	dwInstance = MidiOutDev[wDevID].midiDesc->dwInstance;
+	break;
+	
+    case MIM_OPEN:
+    case MIM_CLOSE:
+    case MIM_DATA:
+    case MIM_ERROR:
+	if (wDevID > MAX_MIDIINDRV) 
+	    return MCIERR_INTERNAL;
+	
+	dwCallBack = MidiInDev[wDevID].midiDesc->dwCallback;
+	uFlags = MidiInDev[wDevID].wFlags;
+	hDev = MidiInDev[wDevID].midiDesc->hMidi;
+	dwInstance = MidiInDev[wDevID].midiDesc->dwInstance;
+	break;
+    default:
+	WARN(midi, "Unsupported MSW-MIDI message %u\n", wMsg);
+	return MCIERR_INTERNAL;
+    }
+    
+    return DriverCallback(dwCallBack, uFlags, hDev, wMsg, dwInstance, dwParam1, dwParam2) ?
+	0 : MCIERR_INTERNAL;
 }
 
-
 /**************************************************************************
  * 				MIDI_ReadByte			[internal]	
  */
 static DWORD MIDI_ReadByte(UINT16 wDevID, BYTE *lpbyt)
 {
-	if (lpbyt != NULL) {
-		if (mmioRead32(MCIMidiDev[wDevID].hFile, (HPSTR)lpbyt,
-			(long) sizeof(BYTE)) == (long) sizeof(BYTE)) {
-			return 0;
-		}
+    if (lpbyt != NULL) {
+	if (mmioRead32(MCIMidiDev[wDevID].hFile, (HPSTR)lpbyt,
+		       (long) sizeof(BYTE)) == (long) sizeof(BYTE)) {
+	    return 0;
 	}
-	WARN(midi, "error reading wDevID=%04X\n", wDevID);
-	return MCIERR_INTERNAL;
-
+    }
+    WARN(midi, "error reading wDevID=%04X\n", wDevID);
+    return MCIERR_INTERNAL;
+    
 }
 
-
 /**************************************************************************
  * 				MIDI_ReadWord			[internal]	
  */
 static DWORD MIDI_ReadWord(UINT16 wDevID, LPWORD lpw)
 {
-	BYTE	hibyte, lobyte;
-	if (lpw != NULL) {
-		if (MIDI_ReadByte(wDevID, &hibyte) == 0) {
-			if (MIDI_ReadByte(wDevID, &lobyte) == 0) {
-				*lpw = ((WORD)hibyte << 8) + lobyte;
-				return 0;
-			}
-		}
-	}
-	WARN(midi, "error reading wDevID=%04X\n", wDevID);
-	return MCIERR_INTERNAL;
-}
+    BYTE	hibyte, lobyte;
 
+    if (lpw != NULL) {
+	if (MIDI_ReadByte(wDevID, &hibyte) == 0) {
+	    if (MIDI_ReadByte(wDevID, &lobyte) == 0) {
+		*lpw = ((WORD)hibyte << 8) + lobyte;
+		return 0;
+	    }
+	}
+    }
+    WARN(midi, "error reading wDevID=%04X\n", wDevID);
+    return MCIERR_INTERNAL;
+}
 
 /**************************************************************************
  * 				MIDI_ReadLong			[internal]	
  */
 static DWORD MIDI_ReadLong(UINT16 wDevID, LPDWORD lpdw)
 {
-	WORD	hiword, loword;
-	if (lpdw != NULL) {
-		if (MIDI_ReadWord(wDevID, &hiword) == 0) {
-			if (MIDI_ReadWord(wDevID, &loword) == 0) {
-				*lpdw = MAKELONG(loword, hiword);
-				return 0;
-			}
-		}
-	}
-	WARN(midi, "error reading wDevID=%04X\n", wDevID);
-	return MCIERR_INTERNAL;
-}
+    WORD	hiword, loword;
 
+    if (lpdw != NULL) {
+	if (MIDI_ReadWord(wDevID, &hiword) == 0) {
+	    if (MIDI_ReadWord(wDevID, &loword) == 0) {
+		*lpdw = MAKELONG(loword, hiword);
+		return 0;
+	    }
+	}
+    }
+    WARN(midi, "error reading wDevID=%04X\n", wDevID);
+    return MCIERR_INTERNAL;
+}
 
 /**************************************************************************
  *  				MIDI_ReadVaryLen		[internal]	
  */
 static DWORD MIDI_ReadVaryLen(UINT16 wDevID, LPDWORD lpdw)
 {
-	BYTE	byte;
-	DWORD	value;
-	if (lpdw == NULL) return MCIERR_INTERNAL;
-	if (MIDI_ReadByte(wDevID, &byte) != 0) {
-		WARN(midi, "error reading wDevID=%04X\n", wDevID);
-		return MCIERR_INTERNAL;
-	}
-	value = (DWORD)(byte & 0x7F);
-	while (byte & 0x80) {
-		if (MIDI_ReadByte(wDevID, &byte) != 0) {
-			WARN(midi, "error reading wDevID=%04X\n", wDevID);
-			return MCIERR_INTERNAL;
-		}
-		value = (value << 7) + (byte & 0x7F);
-	}
-	*lpdw = value;
-/*
-	TRACE(midi, "val=%08lX \n", value);
-*/
-	return 0;
-}
+    BYTE	byte;
+    DWORD	value;
 
+    if (lpdw == NULL) return MCIERR_INTERNAL;
+    if (MIDI_ReadByte(wDevID, &byte) != 0) {
+	WARN(midi, "error reading wDevID=%04X\n", wDevID);
+	return MCIERR_INTERNAL;
+    }
+    value = (DWORD)(byte & 0x7F);
+    while (byte & 0x80) {
+	if (MIDI_ReadByte(wDevID, &byte) != 0) {
+	    WARN(midi, "error reading wDevID=%04X\n", wDevID);
+	    return MCIERR_INTERNAL;
+	}
+	value = (value << 7) + (byte & 0x7F);
+    }
+    *lpdw = value;
+    /*
+      TRACE(midi, "val=%08lX \n", value);
+    */
+    return 0;
+}
 
 /**************************************************************************
  * 				MIDI_ReadMThd			[internal]	
  */
 static DWORD MIDI_ReadMThd(UINT16 wDevID, DWORD dwOffset)
 {
-	DWORD	toberead;
-	FOURCC	fourcc;
-	TRACE(midi, "(%04X, %08lX);\n", wDevID, dwOffset);
-	if (mmioSeek32(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
-		WARN(midi, "can't seek at %08lX begin of 'MThd' \n", dwOffset);
-		return MCIERR_INTERNAL;
-	}
-	if (mmioRead32(MCIMidiDev[wDevID].hFile, (HPSTR)&fourcc,
-		(long) sizeof(FOURCC)) != (long) sizeof(FOURCC))
-		return MCIERR_INTERNAL;
-	if (MIDI_ReadLong(wDevID, &toberead) != 0)
-		return MCIERR_INTERNAL;
-	if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].wFormat) != 0)
-		return MCIERR_INTERNAL;
-	if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].nTracks) != 0)
-		return MCIERR_INTERNAL;
-	if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].nTempo) != 0)
-		return MCIERR_INTERNAL;
-	TRACE(midi, "toberead=%08lX, wFormat=%04X nTracks=%04X nTempo=%04X\n",
-		toberead, MCIMidiDev[wDevID].wFormat,
-		MCIMidiDev[wDevID].nTracks,
-		MCIMidiDev[wDevID].nTempo);
-	toberead -= 3 * sizeof(WORD);
-/*
-		ntrks = read16bit ();
-		Mf_division = division = read16bit ();
-*/
-	return 0;
-}
+    DWORD	toberead;
+    FOURCC	fourcc;
 
+    TRACE(midi, "(%04X, %08lX);\n", wDevID, dwOffset);
+    if (mmioSeek32(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
+	WARN(midi, "can't seek at %08lX begin of 'MThd' \n", dwOffset);
+	return MCIERR_INTERNAL;
+    }
+    if (mmioRead32(MCIMidiDev[wDevID].hFile, (HPSTR)&fourcc,
+		   (long) sizeof(FOURCC)) != (long) sizeof(FOURCC))
+	return MCIERR_INTERNAL;
+    if (MIDI_ReadLong(wDevID, &toberead) != 0)
+	return MCIERR_INTERNAL;
+    if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].wFormat) != 0)
+	return MCIERR_INTERNAL;
+    if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].nTracks) != 0)
+	return MCIERR_INTERNAL;
+    if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].nTempo) != 0)
+	return MCIERR_INTERNAL;
+    TRACE(midi, "toberead=%08lX, wFormat=%04X nTracks=%04X nTempo=%04X\n",
+	  toberead, MCIMidiDev[wDevID].wFormat,
+	  MCIMidiDev[wDevID].nTracks,
+	  MCIMidiDev[wDevID].nTempo);
+    toberead -= 3 * sizeof(WORD);
+    /*
+      ntrks = read16bit ();
+      Mf_division = division = read16bit ();
+    */
+    return 0;
+}
 
 static DWORD MIDI_ReadMTrk(UINT16 wDevID, DWORD dwOffset)
 {
-	DWORD	toberead;
-	FOURCC	fourcc;
-	if (mmioSeek32(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
-		WARN(midi, "can't seek at %08lX begin of 'MThd' \n", dwOffset);
-		}
-	if (mmioRead32(MCIMidiDev[wDevID].hFile, (HPSTR)&fourcc,
-		(long) sizeof(FOURCC)) != (long) sizeof(FOURCC)) {
-		return MCIERR_INTERNAL;
-		}
-	if (MIDI_ReadLong(wDevID, &toberead) != 0) {
-		return MCIERR_INTERNAL;
-		}
-	TRACE(midi, "toberead=%08lX\n", toberead);
-	toberead -= 3 * sizeof(WORD);
-	MCIMidiDev[wDevID].dwTotalLen = toberead;
-	return 0;
-}
+    DWORD	toberead;
+    FOURCC	fourcc;
 
+    if (mmioSeek32(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
+	WARN(midi, "can't seek at %08lX begin of 'MThd' \n", dwOffset);
+    }
+    if (mmioRead32(MCIMidiDev[wDevID].hFile, (HPSTR)&fourcc,
+		   (long) sizeof(FOURCC)) != (long) sizeof(FOURCC)) {
+	return MCIERR_INTERNAL;
+    }
+    if (MIDI_ReadLong(wDevID, &toberead) != 0) {
+	return MCIERR_INTERNAL;
+    }
+    TRACE(midi, "toberead=%08lX\n", toberead);
+    toberead -= 3 * sizeof(WORD);
+    MCIMidiDev[wDevID].dwTotalLen = toberead;
+    return 0;
+}
 
 /**************************************************************************
  * 				MIDI_mciOpen			[internal]	
  */
 static DWORD MIDI_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS16 lpParms)
 {
-	MIDIOPENDESC 	MidiDesc;
-	DWORD		dwRet;
-	DWORD		dwOffset;
-	LPSTR		lpstrElementName;
-	char		str[128];
-
-	TRACE(midi, "(%08lX, %p)\n", dwFlags, lpParms);
-	if (lpParms == NULL) return MCIERR_INTERNAL;
-
-	if (MCIMidiDev[wDevID].nUseCount > 0) {
-		/* The driver already open on this channel */
-		/* If the driver was opened shareable before and this open specifies */
-		/* shareable then increment the use count */
-		if (MCIMidiDev[wDevID].fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
-			++MCIMidiDev[wDevID].nUseCount;
-		else
-			return MCIERR_MUST_USE_SHAREABLE;
-	} else {
-		MCIMidiDev[wDevID].nUseCount = 1;
-		MCIMidiDev[wDevID].fShareable = dwFlags & MCI_OPEN_SHAREABLE;
-		MCIMidiDev[wDevID].hMidiHdr = USER_HEAP_ALLOC(sizeof(MIDIHDR));
+    MIDIOPENDESC 	MidiDesc;
+    DWORD		dwRet;
+    DWORD		dwOffset;
+    LPSTR		lpstrElementName;
+    char		str[128];
+    
+    TRACE(midi, "(%08lX, %p)\n", dwFlags, lpParms);
+    if (lpParms == NULL) return MCIERR_INTERNAL;
+    
+    if (MCIMidiDev[wDevID].nUseCount > 0) {
+	/* The driver already open on this channel */
+	/* If the driver was opened shareable before and this open specifies */
+	/* shareable then increment the use count */
+	if (MCIMidiDev[wDevID].fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
+	    ++MCIMidiDev[wDevID].nUseCount;
+	else
+	    return MCIERR_MUST_USE_SHAREABLE;
+    } else {
+	MCIMidiDev[wDevID].nUseCount = 1;
+	MCIMidiDev[wDevID].fShareable = dwFlags & MCI_OPEN_SHAREABLE;
+	MCIMidiDev[wDevID].hMidiHdr = USER_HEAP_ALLOC(sizeof(MIDIHDR));
+    }
+    
+    TRACE(midi, "wDevID=%04X\n", wDevID);
+    /*	lpParms->wDeviceID = wDevID;*/
+    TRACE(midi, "lpParms->wDevID=%04X\n", lpParms->wDeviceID);
+    TRACE(midi, "before OPEN_ELEMENT\n");
+    if (dwFlags & MCI_OPEN_ELEMENT) {
+	lpstrElementName = (LPSTR)PTR_SEG_TO_LIN(lpParms->lpstrElementName);
+	TRACE(midi, "MCI_OPEN_ELEMENT '%s' !\n", lpstrElementName);
+	if (strlen(lpstrElementName) > 0) {
+	    strcpy(str, lpstrElementName);
+	    CharUpper32A(str);
+	    MCIMidiDev[wDevID].hFile = mmioOpen16(str, NULL, 
+						  MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_EXCLUSIVE);
+	    if (MCIMidiDev[wDevID].hFile == 0) {
+		WARN(midi, "can't find file='%s' !\n", str);
+		return MCIERR_FILE_NOT_FOUND;
+	    }
+	} else 
+	    MCIMidiDev[wDevID].hFile = 0;
+    }
+    TRACE(midi, "hFile=%u\n", MCIMidiDev[wDevID].hFile);
+    memcpy(&MCIMidiDev[wDevID].openParms, lpParms, sizeof(MCI_OPEN_PARMS16));
+    MCIMidiDev[wDevID].wNotifyDeviceID = lpParms->wDeviceID;
+    MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
+    MCIMidiDev[wDevID].dwBeginData = 0;
+    MCIMidiDev[wDevID].dwTotalLen = 0;
+    MidiDesc.hMidi = 0;
+    if (MCIMidiDev[wDevID].hFile != 0) {
+	MMCKINFO	ckMainRIFF;
+	if (mmioDescend(MCIMidiDev[wDevID].hFile, &ckMainRIFF, NULL, 0) != 0) {
+	    return MCIERR_INTERNAL;
 	}
-
-	TRACE(midi, "wDevID=%04X\n", wDevID);
-/*	lpParms->wDeviceID = wDevID;*/
-	TRACE(midi, "lpParms->wDevID=%04X\n", lpParms->wDeviceID);
-	TRACE(midi, "before OPEN_ELEMENT\n");
-	if (dwFlags & MCI_OPEN_ELEMENT) {
-		lpstrElementName = (LPSTR)PTR_SEG_TO_LIN(lpParms->lpstrElementName);
-		TRACE(midi, "MCI_OPEN_ELEMENT '%s' !\n", lpstrElementName);
-		if (strlen(lpstrElementName) > 0) {
-			strcpy(str, lpstrElementName);
-			CharUpper32A(str);
-			MCIMidiDev[wDevID].hFile = mmioOpen16(str, NULL, 
-				MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_EXCLUSIVE);
-			if (MCIMidiDev[wDevID].hFile == 0) {
-				WARN(midi, "can't find file='%s' !\n", str);
-				return MCIERR_FILE_NOT_FOUND;
-			}
-		} else 
-			MCIMidiDev[wDevID].hFile = 0;
+	TRACE(midi,"ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
+	      (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
+	      ckMainRIFF.cksize);
+	dwOffset = 0;
+	if (ckMainRIFF.ckid == mmioFOURCC('R', 'M', 'I', 'D')) {
+	    TRACE(midi, "is a 'RMID' file \n");
+	    dwOffset = ckMainRIFF.dwDataOffset;
 	}
-	TRACE(midi, "hFile=%u\n", MCIMidiDev[wDevID].hFile);
-	memcpy(&MCIMidiDev[wDevID].openParms, lpParms, sizeof(MCI_OPEN_PARMS16));
-	MCIMidiDev[wDevID].wNotifyDeviceID = lpParms->wDeviceID;
-	MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
-	MCIMidiDev[wDevID].dwBeginData = 0;
-	MCIMidiDev[wDevID].dwTotalLen = 0;
-	MidiDesc.hMidi = 0;
-	if (MCIMidiDev[wDevID].hFile != 0) {
-		MMCKINFO	ckMainRIFF;
-		if (mmioDescend(MCIMidiDev[wDevID].hFile, &ckMainRIFF, NULL, 0) != 0) {
-			return MCIERR_INTERNAL;
-		}
-		TRACE(midi,"ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
-				(LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
-				ckMainRIFF.cksize);
-		dwOffset = 0;
-		if (ckMainRIFF.ckid == mmioFOURCC('R', 'M', 'I', 'D')) {
-			TRACE(midi, "is a 'RMID' file \n");
-			dwOffset = ckMainRIFF.dwDataOffset;
-		}
-		if (ckMainRIFF.ckid != mmioFOURCC('M', 'T', 'h', 'd')) {
-			WARN(midi, "unknown format !\n");
-			return MCIERR_INTERNAL;
-		}
-		if (MIDI_ReadMThd(wDevID, dwOffset) != 0) {
-			WARN(midi, "can't read 'MThd' header \n");
-			return MCIERR_INTERNAL;
-		}
-		dwOffset = mmioSeek32(MCIMidiDev[wDevID].hFile, 0, SEEK_CUR);
-		if (MIDI_ReadMTrk(wDevID, dwOffset) != 0) {
-			WARN(midi, "can't read 'MTrk' header \n");
-			return MCIERR_INTERNAL;
-		}
-		dwOffset = mmioSeek32(MCIMidiDev[wDevID].hFile, 0, SEEK_CUR);
-		MCIMidiDev[wDevID].dwBeginData = dwOffset;
-		TRACE(midi, "Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
-				(LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
-				ckMainRIFF.cksize);
+	if (ckMainRIFF.ckid != mmioFOURCC('M', 'T', 'h', 'd')) {
+	    WARN(midi, "unknown format !\n");
+	    return MCIERR_INTERNAL;
 	}
-
-	dwRet = modMessage(wDevID, MODM_OPEN, 0, (DWORD)&MidiDesc, CALLBACK_NULL);
-/*	dwRet = midMessage(wDevID, MIDM_OPEN, 0, (DWORD)&MidiDesc, CALLBACK_NULL);*/
-
-	return 0;
+	if (MIDI_ReadMThd(wDevID, dwOffset) != 0) {
+	    WARN(midi, "can't read 'MThd' header \n");
+	    return MCIERR_INTERNAL;
+	}
+	dwOffset = mmioSeek32(MCIMidiDev[wDevID].hFile, 0, SEEK_CUR);
+	if (MIDI_ReadMTrk(wDevID, dwOffset) != 0) {
+	    WARN(midi, "can't read 'MTrk' header \n");
+	    return MCIERR_INTERNAL;
+	}
+	dwOffset = mmioSeek32(MCIMidiDev[wDevID].hFile, 0, SEEK_CUR);
+	MCIMidiDev[wDevID].dwBeginData = dwOffset;
+	TRACE(midi, "Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
+	      (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
+	      ckMainRIFF.cksize);
+    }
+    
+    dwRet = modMessage(wDevID, MODM_OPEN, 0, (DWORD)&MidiDesc, CALLBACK_NULL);
+    /*	dwRet = midMessage(wDevID, MIDM_OPEN, 0, (DWORD)&MidiDesc, CALLBACK_NULL);*/
+    
+    return 0;
 }
 
 /**************************************************************************
@@ -313,458 +354,677 @@
  */
 static DWORD MIDI_mciStop(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
-	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
-	if (lpParms == NULL) return MCIERR_INTERNAL;
-	MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
-	TRACE(midi, "MCIMidiDev[wDevID].dwStatus=%p %d\n",
-			&MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
-	return 0;
+    TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
+    if (lpParms == NULL) return MCIERR_INTERNAL;
+    MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
+    TRACE(midi, "MCIMidiDev[wDevID].dwStatus=%p %d\n",
+	  &MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
+    return 0;
 }
 
-
 /**************************************************************************
- * 				MIDI_mciClose		[internal]
+ * 				MIDI_mciClose			[internal]
  */
 static DWORD MIDI_mciClose(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
 {
-	DWORD		dwRet;
-
-	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwParam, lpParms);
-	if (MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
-		MIDI_mciStop(wDevID, MCI_WAIT, lpParms);
-		}
-	MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
-	MCIMidiDev[wDevID].nUseCount--;
-	if (MCIMidiDev[wDevID].nUseCount == 0) {
-		if (MCIMidiDev[wDevID].hFile != 0) {
-			mmioClose32(MCIMidiDev[wDevID].hFile, 0);
-			MCIMidiDev[wDevID].hFile = 0;
-			TRACE(midi, "hFile closed !\n");
-		}
-		USER_HEAP_FREE(MCIMidiDev[wDevID].hMidiHdr);
-		dwRet = modMessage(wDevID, MODM_CLOSE, 0, 0L, 0L);
-		if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
-/*
-		dwRet = midMessage(wDevID, MIDM_CLOSE, 0, 0L, 0L);
-		if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
-*/
-		}
-	return 0;
+    DWORD		dwRet;
+    
+    TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwParam, lpParms);
+    if (MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
+	MIDI_mciStop(wDevID, MCI_WAIT, lpParms);
+    }
+    MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
+    MCIMidiDev[wDevID].nUseCount--;
+    if (MCIMidiDev[wDevID].nUseCount == 0) {
+	if (MCIMidiDev[wDevID].hFile != 0) {
+	    mmioClose32(MCIMidiDev[wDevID].hFile, 0);
+	    MCIMidiDev[wDevID].hFile = 0;
+	    TRACE(midi, "hFile closed !\n");
+	}
+	USER_HEAP_FREE(MCIMidiDev[wDevID].hMidiHdr);
+	dwRet = modMessage(wDevID, MODM_CLOSE, 0, 0L, 0L);
+	if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
+	/*
+	  dwRet = midMessage(wDevID, MIDM_CLOSE, 0, 0L, 0L);
+	  if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
+	*/
+    }
+    return 0;
 }
 
-
 /**************************************************************************
- * 				MIDI_mciPlay		[internal]
+ * 				MIDI_mciPlay			[internal]
  */
 static DWORD MIDI_mciPlay(UINT16 wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
 {
-	int		count,start,end;
-	LPMIDIHDR	lpMidiHdr;
-	DWORD		dwData,dwRet;
-	LPWORD		ptr;
-
-	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
-	if (MCIMidiDev[wDevID].hFile == 0) {
-		WARN(midi, "can't find file='%08lx' !\n", 
-				(DWORD)MCIMidiDev[wDevID].openParms.lpstrElementName);
-		return MCIERR_FILE_NOT_FOUND;
-	}
-	start = 1; 		end = 99999;
-	if (dwFlags & MCI_FROM) {
-		start = lpParms->dwFrom; 
-		TRACE(midi, "MCI_FROM=%d \n", start);
-	}
-	if (dwFlags & MCI_TO) {
-		end = lpParms->dwTo;
-		TRACE(midi, "MCI_TO=%d \n", end);
-	}
+    int			count,start,end;
+    LPMIDIHDR		lpMidiHdr;
+    DWORD		dwData,dwRet;
+    LPWORD		ptr;
+    
+    TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
+    if (MCIMidiDev[wDevID].hFile == 0) {
+	WARN(midi, "can't find file='%08lx' !\n", 
+	     (DWORD)MCIMidiDev[wDevID].openParms.lpstrElementName);
+	return MCIERR_FILE_NOT_FOUND;
+    }
+    start = 1; 		end = 99999;
+    if (dwFlags & MCI_FROM) {
+	start = lpParms->dwFrom; 
+	TRACE(midi, "MCI_FROM=%d \n", start);
+    }
+    if (dwFlags & MCI_TO) {
+	end = lpParms->dwTo;
+	TRACE(midi, "MCI_TO=%d \n", end);
+    }
 #if 0
-	if (dwFlags & MCI_NOTIFY) {
-		TRACE(midi, "MCI_NOTIFY %08lX !\n", lpParms->dwCallback);
-		switch(fork()) {
-		case -1:
-			WARN(midi, "Can't 'fork' process !\n");
-			break;
-		case 0:
-			TRACE(midi, "process started ! play in background ...\n");
-			break;
-		default:
-			TRACE(midi, "process started ! return to caller...\n");
-			return 0;
-		}
+    if (dwFlags & MCI_NOTIFY) {
+	TRACE(midi, "MCI_NOTIFY %08lX !\n", lpParms->dwCallback);
+	switch(fork()) {
+	case -1:
+	    WARN(midi, "Can't 'fork' process !\n");
+	    break;
+	case 0:
+	    TRACE(midi, "process started ! play in background ...\n");
+	    break;
+	default:
+	    TRACE(midi, "process started ! return to caller...\n");
+	    return 0;
 	}
+    }
 #endif
-
-	lpMidiHdr = USER_HEAP_LIN_ADDR(MCIMidiDev[wDevID].hMidiHdr);
-
-	lpMidiHdr->lpData = (LPSTR)xmalloc(1200);
-	if (lpMidiHdr->lpData == NULL) return MCIERR_INTERNAL;
-	lpMidiHdr->dwBufferLength = 1024;
-	lpMidiHdr->dwUser = 0L;
-	lpMidiHdr->dwFlags = 0L;
-	dwRet = modMessage(wDevID, MODM_PREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
-
-/*	TRACE(midi, "after MODM_PREPARE \n"); */
-
-	MCIMidiDev[wDevID].dwStatus = MCI_MODE_PLAY;
-	while(MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
-		TRACE(midi, "MCIMidiDev[wDevID].dwStatus=%p %d\n",
-			&MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
-
-		ptr = (LPWORD)lpMidiHdr->lpData;
-		for (count = 0; count < lpMidiHdr->dwBufferLength; count++) {
-			if (MIDI_ReadVaryLen(wDevID, &dwData) != 0) break;
-			*ptr = LOWORD(dwData);
-		}
-/*
-		count = mmioRead32(MCIMidiDev[wDevID].hFile, lpMidiHdr->lpData, lpMidiHdr->dwBufferLength);
-*/
-		TRACE(midi, "after read count = %d\n",count);
-
-		if (count < 1) break;
-		lpMidiHdr->dwBytesRecorded = count;
-		TRACE(midi, "before MODM_LONGDATA lpMidiHdr=%p dwBytesRecorded=%lu\n",
-					lpMidiHdr, lpMidiHdr->dwBytesRecorded);
-		dwRet = modMessage(wDevID, MODM_LONGDATA, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
-		if (dwRet != MMSYSERR_NOERROR) {
-		  switch (dwRet) {
-		  case MMSYSERR_NOTENABLED:
-		    return MCIERR_DEVICE_NOT_READY;
-		    
-		  case MIDIERR_NODEVICE:
-		    return MCIERR_INVALID_DEVICE_ID;
-
-		  case MIDIERR_UNPREPARED:
-		    return MCIERR_DRIVER_INTERNAL;
-
-		  case MIDIERR_STILLPLAYING:
-		    return MCIERR_SEQ_PORT_INUSE;
-
-		  case MMSYSERR_INVALPARAM:
-		    return MCIERR_CANNOT_LOAD_DRIVER;
-		  
-		  default:
-		    return MCIERR_DRIVER;
-		  }	
-		}
-	      }
-	dwRet = modMessage(wDevID, MODM_UNPREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
-	if (lpMidiHdr->lpData != NULL) {
-		free(lpMidiHdr->lpData);
-		lpMidiHdr->lpData = NULL;
+    
+    lpMidiHdr = USER_HEAP_LIN_ADDR(MCIMidiDev[wDevID].hMidiHdr);
+    
+    lpMidiHdr->lpData = (LPSTR)xmalloc(1200);
+    if (lpMidiHdr->lpData == NULL) return MCIERR_INTERNAL;
+    lpMidiHdr->dwBufferLength = 1024;
+    lpMidiHdr->dwUser = 0L;
+    lpMidiHdr->dwFlags = 0L;
+    dwRet = modMessage(wDevID, MODM_PREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
+    
+    /*	TRACE(midi, "after MODM_PREPARE \n"); */
+    
+    MCIMidiDev[wDevID].dwStatus = MCI_MODE_PLAY;
+    while(MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
+	TRACE(midi, "MCIMidiDev[wDevID].dwStatus=%p %d\n",
+	      &MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
+	
+	ptr = (LPWORD)lpMidiHdr->lpData;
+	for (count = 0; count < lpMidiHdr->dwBufferLength; count++) {
+	    if (MIDI_ReadVaryLen(wDevID, &dwData) != 0) break;
+	    *ptr = LOWORD(dwData);
 	}
-	MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
-	if (dwFlags & MCI_NOTIFY) {
-		TRACE(midi, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
-		mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback), 
+	/*
+	  count = mmioRead32(MCIMidiDev[wDevID].hFile, lpMidiHdr->lpData, lpMidiHdr->dwBufferLength);
+	*/
+	TRACE(midi, "after read count = %d\n",count);
+	
+	if (count < 1) break;
+	lpMidiHdr->dwBytesRecorded = count;
+	TRACE(midi, "before MODM_LONGDATA lpMidiHdr=%p dwBytesRecorded=%lu\n",
+	      lpMidiHdr, lpMidiHdr->dwBytesRecorded);
+	dwRet = modMessage(wDevID, MODM_LONGDATA, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
+	if (dwRet != MMSYSERR_NOERROR) {
+	    switch (dwRet) {
+	    case MMSYSERR_NOTENABLED:
+		return MCIERR_DEVICE_NOT_READY;
+		
+	    case MIDIERR_NODEVICE:
+		return MCIERR_INVALID_DEVICE_ID;
+		
+	    case MIDIERR_UNPREPARED:
+		return MCIERR_DRIVER_INTERNAL;
+		
+	    case MIDIERR_STILLPLAYING:
+		return MCIERR_SEQ_PORT_INUSE;
+		
+	    case MMSYSERR_INVALPARAM:
+		return MCIERR_CANNOT_LOAD_DRIVER;
+		
+	    default:
+		return MCIERR_DRIVER;
+	    }	
+	}
+    }
+    dwRet = modMessage(wDevID, MODM_UNPREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
+    if (lpMidiHdr->lpData != NULL) {
+	free(lpMidiHdr->lpData);
+	lpMidiHdr->lpData = NULL;
+    }
+    MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
+    if (dwFlags & MCI_NOTIFY) {
+	TRACE(midi, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
+	mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback), 
 			MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
-	}
-	return 0;
-      }
-
+    }
+    return 0;
+}
 
 /**************************************************************************
  * 				MIDI_mciRecord			[internal]
  */
 static DWORD MIDI_mciRecord(UINT16 wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms)
 {
-	int			start, end;
-	LPMIDIHDR	lpMidiHdr;
-	DWORD		dwRet;
-
-	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
-	if (MCIMidiDev[wDevID].hFile == 0) {
-		WARN(midi, "can't find file='%08lx' !\n", 
-			(DWORD)MCIMidiDev[wDevID].openParms.lpstrElementName);
-		return MCIERR_FILE_NOT_FOUND;
-	}
-	start = 1; 		end = 99999;
-	if (dwFlags & MCI_FROM) {
-		start = lpParms->dwFrom; 
-		TRACE(midi, "MCI_FROM=%d \n", start);
-	}
-	if (dwFlags & MCI_TO) {
-		end = lpParms->dwTo;
-		TRACE(midi, "MCI_TO=%d \n", end);
-	}
-	lpMidiHdr = USER_HEAP_LIN_ADDR(MCIMidiDev[wDevID].hMidiHdr);
-	lpMidiHdr->lpData = (LPSTR) xmalloc(1200);
-	lpMidiHdr->dwBufferLength = 1024;
-	lpMidiHdr->dwUser = 0L;
-	lpMidiHdr->dwFlags = 0L;
-	dwRet = midMessage(wDevID, MIDM_PREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
-	TRACE(midi, "after MIDM_PREPARE \n");
-	MCIMidiDev[wDevID].dwStatus = MCI_MODE_RECORD;
-	while(MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
-		TRACE(midi, "MCIMidiDev[wDevID].dwStatus=%p %d\n",
-			&MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
-		lpMidiHdr->dwBytesRecorded = 0;
-		dwRet = midMessage(wDevID, MIDM_START, 0, 0L, 0L);
-		TRACE(midi, "after MIDM_START lpMidiHdr=%p dwBytesRecorded=%lu\n",
-					lpMidiHdr, lpMidiHdr->dwBytesRecorded);
-		if (lpMidiHdr->dwBytesRecorded == 0) break;
-	}
-	TRACE(midi, "before MIDM_UNPREPARE \n");
-	dwRet = midMessage(wDevID, MIDM_UNPREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
-	TRACE(midi, "after MIDM_UNPREPARE \n");
-	if (lpMidiHdr->lpData != NULL) {
-		free(lpMidiHdr->lpData);
-		lpMidiHdr->lpData = NULL;
-	}
-	MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
-	if (dwFlags & MCI_NOTIFY) {
-		TRACE(midi, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
-		mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback), 
+    int			start, end;
+    LPMIDIHDR		lpMidiHdr;
+    DWORD		dwRet;
+    
+    TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
+    if (MCIMidiDev[wDevID].hFile == 0) {
+	WARN(midi, "can't find file='%08lx' !\n", 
+	     (DWORD)MCIMidiDev[wDevID].openParms.lpstrElementName);
+	return MCIERR_FILE_NOT_FOUND;
+    }
+    start = 1; 		end = 99999;
+    if (dwFlags & MCI_FROM) {
+	start = lpParms->dwFrom; 
+	TRACE(midi, "MCI_FROM=%d \n", start);
+    }
+    if (dwFlags & MCI_TO) {
+	end = lpParms->dwTo;
+	TRACE(midi, "MCI_TO=%d \n", end);
+    }
+    lpMidiHdr = USER_HEAP_LIN_ADDR(MCIMidiDev[wDevID].hMidiHdr);
+    lpMidiHdr->lpData = (LPSTR) xmalloc(1200);
+    lpMidiHdr->dwBufferLength = 1024;
+    lpMidiHdr->dwUser = 0L;
+    lpMidiHdr->dwFlags = 0L;
+    dwRet = midMessage(wDevID, MIDM_PREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
+    TRACE(midi, "after MIDM_PREPARE \n");
+    MCIMidiDev[wDevID].dwStatus = MCI_MODE_RECORD;
+    while(MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
+	TRACE(midi, "MCIMidiDev[wDevID].dwStatus=%p %d\n",
+	      &MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
+	lpMidiHdr->dwBytesRecorded = 0;
+	dwRet = midMessage(wDevID, MIDM_START, 0, 0L, 0L);
+	TRACE(midi, "after MIDM_START lpMidiHdr=%p dwBytesRecorded=%lu\n",
+	      lpMidiHdr, lpMidiHdr->dwBytesRecorded);
+	if (lpMidiHdr->dwBytesRecorded == 0) break;
+    }
+    TRACE(midi, "before MIDM_UNPREPARE \n");
+    dwRet = midMessage(wDevID, MIDM_UNPREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
+    TRACE(midi, "after MIDM_UNPREPARE \n");
+    if (lpMidiHdr->lpData != NULL) {
+	free(lpMidiHdr->lpData);
+	lpMidiHdr->lpData = NULL;
+    }
+    MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
+    if (dwFlags & MCI_NOTIFY) {
+	TRACE(midi, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
+	mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback), 
 			MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
-	}
-	return 0;
+    }
+    return 0;
 }
 
-
 /**************************************************************************
  * 				MIDI_mciPause			[internal]
  */
 static DWORD MIDI_mciPause(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
-	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
-	if (lpParms == NULL) return MCIERR_INTERNAL;
-	return 0;
+    TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
+    if (lpParms == NULL) return MCIERR_INTERNAL;
+    return 0;
 }
 
-
 /**************************************************************************
  * 				MIDI_mciResume			[internal]
  */
 static DWORD MIDI_mciResume(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
-	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
-	if (lpParms == NULL) return MCIERR_INTERNAL;
-	return 0;
+    TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
+    if (lpParms == NULL) return MCIERR_INTERNAL;
+    return 0;
 }
 
-
 /**************************************************************************
  * 				MIDI_mciSet			[internal]
  */
 static DWORD MIDI_mciSet(UINT16 wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
 {
-	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
-	if (lpParms == NULL) return MCIERR_INTERNAL;
-	TRACE(midi, "dwTimeFormat=%08lX\n", lpParms->dwTimeFormat);
-	TRACE(midi, "dwAudio=%08lX\n", lpParms->dwAudio);
-	if (dwFlags & MCI_SET_TIME_FORMAT) {
-		switch (lpParms->dwTimeFormat) {
-		case MCI_FORMAT_MILLISECONDS:
-			TRACE(midi, "MCI_FORMAT_MILLISECONDS !\n");
-			break;
-		case MCI_FORMAT_BYTES:
-			TRACE(midi, "MCI_FORMAT_BYTES !\n");
-			break;
-		case MCI_FORMAT_SAMPLES:
-			TRACE(midi, "MCI_FORMAT_SAMPLES !\n");
-			break;
-		default:
-			WARN(midi, "bad time format !\n");
-			return MCIERR_BAD_TIME_FORMAT;
-		}
+    TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
+    if (lpParms == NULL) return MCIERR_INTERNAL;
+    TRACE(midi, "dwTimeFormat=%08lX\n", lpParms->dwTimeFormat);
+    TRACE(midi, "dwAudio=%08lX\n", lpParms->dwAudio);
+    if (dwFlags & MCI_SET_TIME_FORMAT) {
+	switch (lpParms->dwTimeFormat) {
+	case MCI_FORMAT_MILLISECONDS:
+	    TRACE(midi, "MCI_FORMAT_MILLISECONDS !\n");
+	    break;
+	case MCI_FORMAT_BYTES:
+	    TRACE(midi, "MCI_FORMAT_BYTES !\n");
+	    break;
+	case MCI_FORMAT_SAMPLES:
+	    TRACE(midi, "MCI_FORMAT_SAMPLES !\n");
+	    break;
+	default:
+	    WARN(midi, "bad time format !\n");
+	    return MCIERR_BAD_TIME_FORMAT;
 	}
-	if (dwFlags & MCI_SET_VIDEO) return MCIERR_UNSUPPORTED_FUNCTION;
-	if (dwFlags & MCI_SET_DOOR_OPEN) return MCIERR_UNSUPPORTED_FUNCTION;
-	if (dwFlags & MCI_SET_DOOR_CLOSED) return MCIERR_UNSUPPORTED_FUNCTION;
-	if (dwFlags & MCI_SET_AUDIO)
-		TRACE(midi, "MCI_SET_AUDIO !\n");
-	if (dwFlags && MCI_SET_ON) {
-		TRACE(midi, "MCI_SET_ON !\n");
-		if (dwFlags && MCI_SET_AUDIO_LEFT)
-			TRACE(midi, "MCI_SET_AUDIO_LEFT !\n");
-		if (dwFlags && MCI_SET_AUDIO_RIGHT)
-			TRACE(midi, "MCI_SET_AUDIO_RIGHT !\n");
-	}
-	if (dwFlags & MCI_SET_OFF)
-		TRACE(midi, "MCI_SET_OFF !\n");
-	if (dwFlags & MCI_SEQ_SET_MASTER)
-		TRACE(midi, "MCI_SEQ_SET_MASTER !\n");
-	if (dwFlags & MCI_SEQ_SET_SLAVE)
-		TRACE(midi, "MCI_SEQ_SET_SLAVE !\n");
-	if (dwFlags & MCI_SEQ_SET_OFFSET)
-		TRACE(midi, "MCI_SEQ_SET_OFFSET !\n");
-	if (dwFlags & MCI_SEQ_SET_PORT)
-		TRACE(midi, "MCI_SEQ_SET_PORT !\n");
-	if (dwFlags & MCI_SEQ_SET_TEMPO)
-		TRACE(midi, "MCI_SEQ_SET_TEMPO !\n");
- 	return 0;
+    }
+    if (dwFlags & MCI_SET_VIDEO) return MCIERR_UNSUPPORTED_FUNCTION;
+    if (dwFlags & MCI_SET_DOOR_OPEN) return MCIERR_UNSUPPORTED_FUNCTION;
+    if (dwFlags & MCI_SET_DOOR_CLOSED) return MCIERR_UNSUPPORTED_FUNCTION;
+    if (dwFlags & MCI_SET_AUDIO)
+	TRACE(midi, "MCI_SET_AUDIO !\n");
+    if (dwFlags && MCI_SET_ON) {
+	TRACE(midi, "MCI_SET_ON !\n");
+	if (dwFlags && MCI_SET_AUDIO_LEFT)
+	    TRACE(midi, "MCI_SET_AUDIO_LEFT !\n");
+	if (dwFlags && MCI_SET_AUDIO_RIGHT)
+	    TRACE(midi, "MCI_SET_AUDIO_RIGHT !\n");
+    }
+    if (dwFlags & MCI_SET_OFF)
+	TRACE(midi, "MCI_SET_OFF !\n");
+    if (dwFlags & MCI_SEQ_SET_MASTER)
+	TRACE(midi, "MCI_SEQ_SET_MASTER !\n");
+    if (dwFlags & MCI_SEQ_SET_SLAVE)
+	TRACE(midi, "MCI_SEQ_SET_SLAVE !\n");
+    if (dwFlags & MCI_SEQ_SET_OFFSET)
+	TRACE(midi, "MCI_SEQ_SET_OFFSET !\n");
+    if (dwFlags & MCI_SEQ_SET_PORT)
+	TRACE(midi, "MCI_SEQ_SET_PORT !\n");
+    if (dwFlags & MCI_SEQ_SET_TEMPO)
+	TRACE(midi, "MCI_SEQ_SET_TEMPO !\n");
+    return 0;
 }
 
-
 /**************************************************************************
- * 				MIDI_mciStatus		[internal]
+ * 				MIDI_mciStatus			[internal]
  */
 static DWORD MIDI_mciStatus(UINT16 wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
 {
-	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
-	if (lpParms == NULL) return MCIERR_INTERNAL;
-	if (dwFlags & MCI_STATUS_ITEM) {
-		switch(lpParms->dwItem) {
-		case MCI_STATUS_CURRENT_TRACK:
-			lpParms->dwReturn = 1;
-			break;
-		case MCI_STATUS_LENGTH:
-			lpParms->dwReturn = 5555;
-			if (dwFlags & MCI_TRACK) {
-				lpParms->dwTrack = 1;
-				lpParms->dwReturn = 2222;
-			}
-			break;
-		case MCI_STATUS_MODE:
-			lpParms->dwReturn = MCI_MODE_STOP;
-			break;
-		case MCI_STATUS_MEDIA_PRESENT:
-			TRACE(midi, "MCI_STATUS_MEDIA_PRESENT !\n");
-			lpParms->dwReturn = TRUE;
-			break;
-		case MCI_STATUS_NUMBER_OF_TRACKS:
-			lpParms->dwReturn = 1;
-			break;
-		case MCI_STATUS_POSITION:
-			lpParms->dwReturn = 3333;
-			if (dwFlags & MCI_STATUS_START)
-				lpParms->dwItem = 1;
-			if (dwFlags & MCI_TRACK) {
-				lpParms->dwTrack = 1;
-				lpParms->dwReturn = 777;
-			}
-			break;
-		case MCI_STATUS_READY:
-			TRACE(midi, "MCI_STATUS_READY !\n");
-			lpParms->dwReturn = TRUE;
-			break;
-		case MCI_STATUS_TIME_FORMAT:
-			TRACE(midi, "MCI_STATUS_TIME_FORMAT !\n");
-			lpParms->dwReturn = MCI_FORMAT_MILLISECONDS;
-			break;
-		case MCI_SEQ_STATUS_DIVTYPE:
-			TRACE(midi, "MCI_SEQ_STATUS_DIVTYPE !\n");
-			lpParms->dwReturn = 0;
-			break;
-		case MCI_SEQ_STATUS_MASTER:
-			TRACE(midi, "MCI_SEQ_STATUS_MASTER !\n");
-			lpParms->dwReturn = 0;
-			break;
-		case MCI_SEQ_STATUS_SLAVE:
-			TRACE(midi, "MCI_SEQ_STATUS_SLAVE !\n");
-			lpParms->dwReturn = 0;
-			break;
-		case MCI_SEQ_STATUS_OFFSET:
-			TRACE(midi, "MCI_SEQ_STATUS_OFFSET !\n");
-			lpParms->dwReturn = 0;
-			break;
-		case MCI_SEQ_STATUS_PORT:
-			TRACE(midi, "MCI_SEQ_STATUS_PORT !\n");
-			lpParms->dwReturn = 0;
-			break;
-		case MCI_SEQ_STATUS_TEMPO:
-			TRACE(midi, "MCI_SEQ_STATUS_TEMPO !\n");
-			lpParms->dwReturn = 0;
-			break;
-		default:
-			WARN(midi, "unknowm command %08lX !\n", lpParms->dwItem);
-			return MCIERR_UNRECOGNIZED_COMMAND;
-		}
+    TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
+    if (lpParms == NULL) return MCIERR_INTERNAL;
+    if (dwFlags & MCI_STATUS_ITEM) {
+	switch(lpParms->dwItem) {
+	case MCI_STATUS_CURRENT_TRACK:
+	    lpParms->dwReturn = 1;
+	    break;
+	case MCI_STATUS_LENGTH:
+	    lpParms->dwReturn = 5555;
+	    if (dwFlags & MCI_TRACK) {
+		lpParms->dwTrack = 1;
+		lpParms->dwReturn = 2222;
+	    }
+	    break;
+	case MCI_STATUS_MODE:
+	    lpParms->dwReturn = MCI_MODE_STOP;
+	    break;
+	case MCI_STATUS_MEDIA_PRESENT:
+	    TRACE(midi, "MCI_STATUS_MEDIA_PRESENT !\n");
+	    lpParms->dwReturn = TRUE;
+	    break;
+	case MCI_STATUS_NUMBER_OF_TRACKS:
+	    lpParms->dwReturn = 1;
+	    break;
+	case MCI_STATUS_POSITION:
+	    lpParms->dwReturn = 3333;
+	    if (dwFlags & MCI_STATUS_START)
+		lpParms->dwItem = 1;
+	    if (dwFlags & MCI_TRACK) {
+		lpParms->dwTrack = 1;
+		lpParms->dwReturn = 777;
+	    }
+	    break;
+	case MCI_STATUS_READY:
+	    TRACE(midi, "MCI_STATUS_READY !\n");
+	    lpParms->dwReturn = TRUE;
+	    break;
+	case MCI_STATUS_TIME_FORMAT:
+	    TRACE(midi, "MCI_STATUS_TIME_FORMAT !\n");
+	    lpParms->dwReturn = MCI_FORMAT_MILLISECONDS;
+	    break;
+	case MCI_SEQ_STATUS_DIVTYPE:
+	    TRACE(midi, "MCI_SEQ_STATUS_DIVTYPE !\n");
+	    lpParms->dwReturn = 0;
+	    break;
+	case MCI_SEQ_STATUS_MASTER:
+	    TRACE(midi, "MCI_SEQ_STATUS_MASTER !\n");
+	    lpParms->dwReturn = 0;
+	    break;
+	case MCI_SEQ_STATUS_SLAVE:
+	    TRACE(midi, "MCI_SEQ_STATUS_SLAVE !\n");
+	    lpParms->dwReturn = 0;
+	    break;
+	case MCI_SEQ_STATUS_OFFSET:
+	    TRACE(midi, "MCI_SEQ_STATUS_OFFSET !\n");
+	    lpParms->dwReturn = 0;
+	    break;
+	case MCI_SEQ_STATUS_PORT:
+	    TRACE(midi, "MCI_SEQ_STATUS_PORT !\n");
+	    lpParms->dwReturn = 0;
+	    break;
+	case MCI_SEQ_STATUS_TEMPO:
+	    TRACE(midi, "MCI_SEQ_STATUS_TEMPO !\n");
+	    lpParms->dwReturn = 0;
+	    break;
+	default:
+	    WARN(midi, "unknowm command %08lX !\n", lpParms->dwItem);
+	    return MCIERR_UNRECOGNIZED_COMMAND;
 	}
-	if (dwFlags & MCI_NOTIFY) {
-		TRACE(midi, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
-		mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback), 
+    }
+    if (dwFlags & MCI_NOTIFY) {
+	TRACE(midi, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
+	mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback), 
 			MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
-	}
- 	return 0;
+    }
+    return 0;
 }
 
 /**************************************************************************
  * 				MIDI_mciGetDevCaps		[internal]
  */
 static DWORD MIDI_mciGetDevCaps(UINT16 wDevID, DWORD dwFlags, 
-					LPMCI_GETDEVCAPS_PARMS lpParms)
+				LPMCI_GETDEVCAPS_PARMS lpParms)
 {
-	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
-	if (lpParms == NULL) return MCIERR_INTERNAL;
-	if (dwFlags & MCI_GETDEVCAPS_ITEM) {
-		switch(lpParms->dwItem) {
-		case MCI_GETDEVCAPS_CAN_RECORD:
-			lpParms->dwReturn = TRUE;
-			break;
-		case MCI_GETDEVCAPS_HAS_AUDIO:
-			lpParms->dwReturn = TRUE;
-			break;
-		case MCI_GETDEVCAPS_HAS_VIDEO:
-			lpParms->dwReturn = FALSE;
-			break;
-		case MCI_GETDEVCAPS_DEVICE_TYPE:
-			lpParms->dwReturn = MCI_DEVTYPE_SEQUENCER;
-			break;
-		case MCI_GETDEVCAPS_USES_FILES:
-			lpParms->dwReturn = TRUE;
-			break;
-		case MCI_GETDEVCAPS_COMPOUND_DEVICE:
-			lpParms->dwReturn = TRUE;
-			break;
-		case MCI_GETDEVCAPS_CAN_EJECT:
-			lpParms->dwReturn = FALSE;
-			break;
-		case MCI_GETDEVCAPS_CAN_PLAY:
-			lpParms->dwReturn = TRUE;
-			break;
-		case MCI_GETDEVCAPS_CAN_SAVE:
-			lpParms->dwReturn = FALSE;
-			break;
-		default:
-			return MCIERR_UNRECOGNIZED_COMMAND;
-		}
+    TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
+    if (lpParms == NULL) return MCIERR_INTERNAL;
+    if (dwFlags & MCI_GETDEVCAPS_ITEM) {
+	switch(lpParms->dwItem) {
+	case MCI_GETDEVCAPS_CAN_RECORD:
+	    lpParms->dwReturn = TRUE;
+	    break;
+	case MCI_GETDEVCAPS_HAS_AUDIO:
+	    lpParms->dwReturn = TRUE;
+	    break;
+	case MCI_GETDEVCAPS_HAS_VIDEO:
+	    lpParms->dwReturn = FALSE;
+	    break;
+	case MCI_GETDEVCAPS_DEVICE_TYPE:
+	    lpParms->dwReturn = MCI_DEVTYPE_SEQUENCER;
+	    break;
+	case MCI_GETDEVCAPS_USES_FILES:
+	    lpParms->dwReturn = TRUE;
+	    break;
+	case MCI_GETDEVCAPS_COMPOUND_DEVICE:
+	    lpParms->dwReturn = TRUE;
+	    break;
+	case MCI_GETDEVCAPS_CAN_EJECT:
+	    lpParms->dwReturn = FALSE;
+	    break;
+	case MCI_GETDEVCAPS_CAN_PLAY:
+	    lpParms->dwReturn = TRUE;
+	    break;
+	case MCI_GETDEVCAPS_CAN_SAVE:
+	    lpParms->dwReturn = FALSE;
+	    break;
+	default:
+	    return MCIERR_UNRECOGNIZED_COMMAND;
 	}
- 	return 0;
+    }
+    return 0;
 }
 
-
 /**************************************************************************
  * 				MIDI_mciInfo			[internal]
  */
 static DWORD MIDI_mciInfo(UINT16 wDevID, DWORD dwFlags, LPMCI_INFO_PARMS16 lpParms)
 {
-	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
-	if (lpParms == NULL) return MCIERR_INTERNAL;
-	lpParms->lpstrReturn = NULL;
-	switch(dwFlags) {
-	case MCI_INFO_PRODUCT:
-		lpParms->lpstrReturn = "Linux Sound System 0.5";
-		break;
-	case MCI_INFO_FILE:
-		lpParms->lpstrReturn = "FileName";
-		break;
-	default:
-		return MCIERR_UNRECOGNIZED_COMMAND;
-	}
-	if (lpParms->lpstrReturn != NULL)
-		lpParms->dwRetSize = strlen(lpParms->lpstrReturn);
-	else
-		lpParms->dwRetSize = 0;
- 	return 0;
+    TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
+    if (lpParms == NULL) return MCIERR_INTERNAL;
+    lpParms->lpstrReturn = NULL;
+    switch(dwFlags) {
+    case MCI_INFO_PRODUCT:
+	lpParms->lpstrReturn = "Linux Sound System 0.5";
+	break;
+    case MCI_INFO_FILE:
+	lpParms->lpstrReturn = "FileName";
+	break;
+    default:
+	return MCIERR_UNRECOGNIZED_COMMAND;
+    }
+    if (lpParms->lpstrReturn != NULL)
+	lpParms->dwRetSize = strlen(lpParms->lpstrReturn);
+    else
+	lpParms->dwRetSize = 0;
+    return 0;
 }
 
-
 /*-----------------------------------------------------------------------*/
 
+#ifdef HAVE_OSS
+/**************************************************************************
+ * 			midiOpenSeq				[internal]
+ */
+static int midiOpenSeq(void)
+{
+    if (numOpenMidiSeq == 0) {
+	midiSeqFD = open(MIDI_SEQ, O_RDWR, 0);
+	if (midiSeqFD == -1) {
+	    ERR(midi, "can't open '%s' ! (%d)\n", MIDI_SEQ, errno);
+	    return -1;
+	}
+	if (fcntl(midiSeqFD, F_SETFL, O_NONBLOCK) < 0) {
+	    WARN(midi, "can't set sequencer fd to non blocking (%d)\n", errno);
+	    close(midiSeqFD);
+	    midiSeqFD = -1;
+	    return -1;
+	}
+	ioctl(midiSeqFD, SNDCTL_SEQ_RESET);
+    }
+    numOpenMidiSeq++;
+    return 0;
+}
+
+/**************************************************************************
+ * 			midiCloseSeq				[internal]
+ */
+static int midiCloseSeq(void)
+{
+    if (--numOpenMidiSeq == 0) {
+	close(midiSeqFD);
+	midiSeqFD = -1;
+    }
+    return 0;
+}
+
+/* FIXME: this is a bad idea, it's even not static... */
+SEQ_DEFINEBUF(1024);
+
+/* FIXME: this is not reentrant, not static - because of global variable 
+ * _seqbuf and al. */
+/**************************************************************************
+ * 			seqbuf_dump				[internal]
+ */
+void seqbuf_dump(void)
+{
+    if (_seqbufptr) {
+	if (write(midiSeqFD, _seqbuf, _seqbufptr) == -1) {
+	    WARN(midi, "Can't write data to sequencer (%d/%d)!\n", 
+		 midiSeqFD, errno);
+	}
+	/* FIXME:
+	 *	in any case buffer is lost so that if many errors occur the buffer 
+	 * will not overrun 
+	 */
+	_seqbufptr = 0;
+    }
+}
+#endif /* HAVE_OSS */
+
+#ifdef HAVE_OSS
+
+static void midReceiveChar(WORD wDevID, unsigned char value, DWORD dwTime)
+{
+    DWORD		toSend = 0;
+    
+    TRACE(midi, "Adding %02xh to %d[%d]\n",
+	  value, wDevID, MidiInDev[wDevID].incLen);
+    
+    if (wDevID >= MAX_MIDIINDRV) {
+	WARN(midi, "bad devID\n");
+	return;
+    }
+    if (MidiInDev[wDevID].state == 0) {
+	TRACE(midi, "input not started, thrown away\n");
+	return;
+    }
+    
+    if (MidiInDev[wDevID].state & 2) { /* system exclusive */
+	LPMIDIHDR	ptr = MidiInDev[wDevID].lpQueueHdr;
+	WORD 			sbfb = FALSE;
+	
+	if (ptr) {
+	    ((LPSTR)(ptr->reserved))[ptr->dwBytesRecorded++] = value;
+	    if (ptr->dwBytesRecorded == ptr->dwBufferLength) {
+		sbfb = TRUE;
+	    } 
+	}
+	if (value == 0xF7) { /* then end */
+	    MidiInDev[wDevID].state &= ~2;
+	    sbfb = TRUE;
+	}
+	if (sbfb && ptr != NULL) {
+	    ptr = MidiInDev[wDevID].lpQueueHdr;
+	    ptr->dwFlags &= ~MHDR_INQUEUE;
+	    ptr->dwFlags |= MHDR_DONE;
+	    MidiInDev[wDevID].lpQueueHdr = (LPMIDIHDR)ptr->lpNext;
+	    if (MIDI_NotifyClient(wDevID, MIM_LONGDATA, (DWORD)ptr, dwTime) != MMSYSERR_NOERROR) {
+		WARN(midi, "Couldn't notify client\n");
+	    }
+	}
+	return;
+    }
+    
+#define IS_CMD(_x)	(((_x) & 0x80) == 0x80)
+#define IS_SYS_CMD(_x)	(((_x) & 0xF0) == 0xF0)
+    
+    if (!IS_CMD(value) && MidiInDev[wDevID].incLen == 0) { /* try to reuse old cmd */
+	if (IS_CMD(MidiInDev[wDevID].incPrev) && !IS_SYS_CMD(MidiInDev[wDevID].incPrev)) {
+	    MidiInDev[wDevID].incoming[0] = MidiInDev[wDevID].incPrev;
+	    MidiInDev[wDevID].incLen = 1;
+	    TRACE(midi, "Reusing old command %02xh\n", MidiInDev[wDevID].incPrev);
+	} else {
+	    FIXME(midi, "error for midi-in, should generate MIM_ERROR notification:"
+		  " prev=%02Xh, incLen=%02Xh\n", 
+		  MidiInDev[wDevID].incPrev, MidiInDev[wDevID].incLen);
+	    return;
+	}
+    }
+    MidiInDev[wDevID].incoming[(int)(MidiInDev[wDevID].incLen++)] = value;
+    if (MidiInDev[wDevID].incLen == 1 && !IS_SYS_CMD(MidiInDev[wDevID].incoming[0])) {
+	/* store new cmd, just in case */
+	MidiInDev[wDevID].incPrev = MidiInDev[wDevID].incoming[0];
+    }
+    
+#undef IS_CMD(_x)
+#undef IS_SYS_CMD(_x)
+    
+    switch (MidiInDev[wDevID].incoming[0] & 0xF0) {
+    case MIDI_NOTEOFF:
+    case MIDI_NOTEON:
+    case MIDI_KEY_PRESSURE:
+    case MIDI_CTL_CHANGE:
+    case MIDI_PITCH_BEND:
+	if (MidiInDev[wDevID].incLen == 3) {
+	    toSend = (MidiInDev[wDevID].incoming[2] << 16) | 
+		(MidiInDev[wDevID].incoming[1] <<  8) |
+		(MidiInDev[wDevID].incoming[0] <<  0);
+	}
+	break;
+    case MIDI_PGM_CHANGE:
+    case MIDI_CHN_PRESSURE:
+	if (MidiInDev[wDevID].incLen == 2) {
+	    toSend = (MidiInDev[wDevID].incoming[1] <<  8) |
+		(MidiInDev[wDevID].incoming[0] <<  0);
+	}
+	break;
+    case MIDI_SYSTEM_PREFIX:
+	if (MidiInDev[wDevID].incoming[0] == 0xF0) {
+	    MidiInDev[wDevID].state |= 2;
+	    MidiInDev[wDevID].incLen = 0;
+	} else {		
+	    if (MidiInDev[wDevID].incLen == 1) {
+		toSend = (MidiInDev[wDevID].incoming[0] <<  0);
+	    }
+	}
+	break;
+    default:
+	WARN(midi, "This shouldn't happen (%02X)\n", MidiInDev[wDevID].incoming[0]);
+    }
+    if (toSend != 0) {
+	TRACE(midi, "Sending event %08lx\n", toSend);
+	MidiInDev[wDevID].incLen =	0;
+	dwTime -= MidiInDev[wDevID].startTime;
+	if (MIDI_NotifyClient(wDevID, MIM_DATA, toSend, dwTime) != MMSYSERR_NOERROR) {
+	    WARN(midi, "Couldn't notify client\n");
+	}
+    }
+}
+
+static VOID midTimeCallback(HWND32 hwnd, UINT32 msg, UINT32 id, DWORD dwTime)
+{
+    unsigned	char		buffer[256];
+    int					len, idx;
+    
+    TRACE(midi, "(%04X, %d, %d, %lu)\n", hwnd, msg, id, dwTime);
+    
+    len = read(midiSeqFD, buffer, sizeof(buffer));
+    
+    if ((len % 4) != 0) {
+	WARN(midi, "bad length %d (%d)\n", len, errno);
+	return;
+    }
+    
+    for (idx = 0; idx < len; ) {
+	if (buffer[idx] & 0x80) {
+	    TRACE(midi, 
+		  "reading<8> %02x %02x %02x %02x %02x %02x %02x %02x\n", 
+		  buffer[idx + 0], buffer[idx + 1], 
+		  buffer[idx + 2], buffer[idx + 3], 
+		  buffer[idx + 4], buffer[idx + 5], 
+		  buffer[idx + 6], buffer[idx + 7]);
+	    idx += 8;
+	} else {
+	    switch (buffer[idx + 0]) {
+	    case SEQ_WAIT:
+	    case SEQ_ECHO:
+		break;
+	    case SEQ_MIDIPUTC:
+		midReceiveChar(buffer[idx + 2], buffer[idx + 1], dwTime);
+		break;
+	    default:
+		TRACE(midi, "Unsupported event %d\n", buffer[idx + 0]);
+		break;
+	    }
+	    idx += 4;
+	}				
+    }
+}
+#endif /* HAVE_OSS */
 
 /**************************************************************************
  * 				midGetDevCaps			[internal]
  */
 static DWORD midGetDevCaps(WORD wDevID, LPMIDIINCAPS16 lpCaps, DWORD dwSize)
 {
-	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpCaps, dwSize);
-	lpCaps->wMid = 0x00FF; 	        /* Manufac ID */
-	lpCaps->wPid = 0x0001; 	        /* Product ID */
-	lpCaps->vDriverVersion = 0x001; /* Product Version */
-	strcpy(lpCaps->szPname, "Linux MIDIIN Driver");
-
-	return MMSYSERR_NOERROR;
+    LPMIDIINCAPS16	tmplpCaps;
+    
+    TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpCaps, dwSize);
+    
+    if (wDevID >= MIDM_NUMDEVS) {
+	return MMSYSERR_BADDEVICEID;
+    }
+    if (lpCaps == NULL) {
+	return MMSYSERR_INVALPARAM;
+    }
+    
+    tmplpCaps = midiInDevices[wDevID];
+    lpCaps->wMid = tmplpCaps->wMid;  
+    lpCaps->wPid = tmplpCaps->wPid;  
+    lpCaps->vDriverVersion = tmplpCaps->vDriverVersion;  
+    strcpy(lpCaps->szPname, tmplpCaps->szPname);    
+    if (dwSize == sizeof(MIDIINCAPS16)) { 
+	/* we should run win 95, so make use of dwSupport */
+	lpCaps->dwSupport = tmplpCaps->dwSupport;
+    } else if (dwSize != sizeof(MIDIINCAPS16) - sizeof(DWORD)) {
+	TRACE(midi, "bad size for lpCaps\n");
+	return MMSYSERR_INVALPARAM;
+    }
+    
+    return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
@@ -772,46 +1032,85 @@
  */
 static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
 {
-	int		midi;
-	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
-	if (lpDesc == NULL) {
-		WARN(midi, "Invalid Parameter !\n");
-		return MMSYSERR_INVALPARAM;
+    TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
+    
+    if (lpDesc == NULL) {
+	WARN(midi, "Invalid Parameter !\n");
+	return MMSYSERR_INVALPARAM;
+    }
+    /* FIXME :
+     *	how to check that content of lpDesc is correct ?
+     */
+    if (wDevID >= MAX_MIDIINDRV) {
+	WARN(midi,"wDevID too large (%u) !\n", wDevID);
+	return MMSYSERR_BADDEVICEID;
+    }
+    if (MidiInDev[wDevID].midiDesc != 0) {
+	WARN(midi, "device already open !\n");
+	return MMSYSERR_ALLOCATED;
+    }
+    if ((dwFlags & ~CALLBACK_TYPEMASK) != 0) { 
+	FIXME(midi, "No support for MIDI_IO_STATUS in dwFlags\n");
+	return MMSYSERR_INVALFLAG;
+    }
+    
+#ifdef HAVE_OSS
+    if (midiOpenSeq() < 0) {
+	return MMSYSERR_ERROR;
+    }
+    
+    if (numStartedMidiIn++ == 0) {
+	midiInTimerID = SetTimer32(0, 0, 250, midTimeCallback);
+	if (!midiInTimerID) {
+	    numStartedMidiIn = 0;
+	    WARN(midi, "Couldn't start timer for midi-in\n");
+	    midiCloseSeq();
+	    return MMSYSERR_ERROR;
 	}
-	if (wDevID >= MAX_MIDIINDRV) {
-		TRACE(midi,"MAX_MIDIINDRV reached !\n");
-		return MMSYSERR_ALLOCATED;
-	}
+	TRACE(midi, "Starting timer (%u) for midi-in\n", midiInTimerID);
+    }
+#else /* HAVE_OSS */
+    {
+	int		midi = open(MIDI_DEV, O_WRONLY, 0);
+	
 	MidiInDev[wDevID].unixdev = 0;
-	midi = open (MIDI_DEV, O_RDONLY, 0);
 	if (midi == -1) {
-		WARN(midi,"can't open !\n");
-		return MMSYSERR_NOTENABLED;
+	    WARN(midi,"can't open '%s' (%d)!\n", MIDI_DEV, errno);			
+	    return MMSYSERR_ALLOCATED;
 	}
-	MidiInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
-	switch(MidiInDev[wDevID].wFlags) {
-		case DCB_NULL:
-			TRACE(midi,"CALLBACK_NULL !\n");
-			break;
-		case DCB_WINDOW:
-			TRACE(midi, "CALLBACK_WINDOW !\n");
-			break;
-		case DCB_TASK:
-			TRACE(midi, "CALLBACK_TASK !\n");
-			break;
-		case DCB_FUNCTION:
-			TRACE(midi, "CALLBACK_FUNCTION !\n");
-			break;
-	}
-	MidiInDev[wDevID].lpQueueHdr = NULL;
 	MidiInDev[wDevID].unixdev = midi;
-	MidiInDev[wDevID].dwTotalPlayed = 0;
-	MidiInDev[wDevID].bufsize = 0x3FFF;
-	if (MIDI_NotifyClient(wDevID, MIM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
-		WARN(midi,"can't notify client !\n");
-		return MMSYSERR_INVALPARAM;
-	}
-	return MMSYSERR_NOERROR;
+    }
+#endif /* HAVE_OSS */
+    
+    MidiInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
+    switch(MidiInDev[wDevID].wFlags) {
+    case DCB_NULL:
+	TRACE(midi,"CALLBACK_NULL !\n");
+	break;
+    case DCB_WINDOW:
+	TRACE(midi, "CALLBACK_WINDOW !\n");
+	break;
+    case DCB_TASK:
+	TRACE(midi, "CALLBACK_TASK !\n");
+	break;
+    case DCB_FUNCTION:
+	TRACE(midi, "CALLBACK_FUNCTION (%08lX)!\n", lpDesc->dwCallback);
+	break;
+    }
+    MidiInDev[wDevID].lpQueueHdr = NULL;
+    MidiInDev[wDevID].dwTotalPlayed = 0;
+    MidiInDev[wDevID].bufsize = 0x3FFF;
+    MidiInDev[wDevID].midiDesc = lpDesc;
+    MidiInDev[wDevID].state = 0;
+#ifdef HAVE_OSS
+    MidiInDev[wDevID].incLen = 0;
+    MidiInDev[wDevID].startTime = 0;
+#endif /* HAVE_OSS */
+    if (MIDI_NotifyClient(wDevID, MIM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
+	WARN(midi,"can't notify client !\n");
+	return MMSYSERR_INVALPARAM;
+    }
+    return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
@@ -819,28 +1118,76 @@
  */
 static DWORD midClose(WORD wDevID)
 {
-	TRACE(midi, "(%04X);\n", wDevID);
-	if (MidiInDev[wDevID].unixdev == 0) {
-		WARN(midi,"can't close !\n");
-		return MMSYSERR_NOTENABLED;
-	}
-	close(MidiInDev[wDevID].unixdev);
-	MidiInDev[wDevID].unixdev = 0;
-	MidiInDev[wDevID].bufsize = 0;
-	if (MIDI_NotifyClient(wDevID, MIM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
-		WARN(midi,"can't notify client !\n");
-		return MMSYSERR_INVALPARAM;
-	}
-	return MMSYSERR_NOERROR;
+    int		ret = MMSYSERR_NOERROR;
+    
+    TRACE(midi, "(%04X);\n", wDevID);
+    
+    if (wDevID >= MAX_MIDIINDRV) {
+	WARN(midi,"wDevID too bif (%u) !\n", wDevID);
+	return MMSYSERR_BADDEVICEID;
+    }
+    if (MidiInDev[wDevID].midiDesc == 0) {
+	WARN(midi, "device not opened !\n");
+	return MMSYSERR_ERROR;
+    }
+    if (MidiInDev[wDevID].lpQueueHdr != 0) {
+	return MIDIERR_STILLPLAYING;
+    }
+    
+#ifdef HAVE_OSS
+    if (midiSeqFD == -1) {
+	WARN(midi,"ooops !\n");
+	return MMSYSERR_ERROR;
+    }
+    if (--numStartedMidiIn == 0) {
+	TRACE(midi, "Stopping timer for midi-in\n");
+	if (!KillTimer32(0, midiInTimerID)) {
+	    WARN(midi, "Couldn't stop timer for midi-in\n");
+	}			
+	midiInTimerID = 0;
+    }
+    midiCloseSeq();
+#else /* HAVE_OSS */
+    if (MidiInDev[wDevID].unixdev == 0) {
+	WARN(midi,"ooops !\n");
+	return MMSYSERR_ERROR;
+    }
+    close(MidiInDev[wDevID].unixdev);
+    MidiInDev[wDevID].unixdev = 0;
+#endif /* HAVE_OSS */
+    MidiInDev[wDevID].bufsize = 0;
+    if (MIDI_NotifyClient(wDevID, MIM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
+	WARN(midi,"can't notify client !\n");
+	ret = MMSYSERR_INVALPARAM;
+    }
+    MidiInDev[wDevID].midiDesc = 0;
+    return ret;
 }
 
 /**************************************************************************
- * 				midAddBuffer		[internal]
+ * 				midAddBuffer			[internal]
  */
 static DWORD midAddBuffer(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
 {
-	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
-	return MMSYSERR_NOTENABLED;
+    TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
+    
+    if (lpMidiHdr == NULL)	return MMSYSERR_INVALPARAM;
+    if (sizeof(MIDIHDR) != dwSize) return MMSYSERR_INVALPARAM;
+    if (lpMidiHdr->dwBufferLength == 0) return MMSYSERR_INVALPARAM;
+    if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING;
+    if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) return MIDIERR_UNPREPARED;
+    
+    if (MidiInDev[wDevID].lpQueueHdr == 0) {
+	MidiInDev[wDevID].lpQueueHdr = lpMidiHdr;
+    } else {
+	LPMIDIHDR	ptr;
+	
+	for (ptr = MidiInDev[wDevID].lpQueueHdr; 
+	     ptr->lpNext != 0; 
+	     ptr = (LPMIDIHDR)ptr->lpNext);
+	ptr->lpNext = (struct midihdr_tag*)lpMidiHdr;
+    }
+    return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
@@ -848,8 +1195,18 @@
  */
 static DWORD midPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
 {
-	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
-	return MMSYSERR_NOTENABLED;
+    TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
+    
+    if (dwSize != sizeof(MIDIHDR) || lpMidiHdr == 0 || 
+	lpMidiHdr->lpData == 0 || lpMidiHdr->dwFlags != 0 || 
+	lpMidiHdr->dwBufferLength >= 0x10000ul)
+	return MMSYSERR_INVALPARAM;
+    
+    lpMidiHdr->lpNext = 0;
+    lpMidiHdr->dwFlags |= MHDR_PREPARED;
+    lpMidiHdr->dwBytesRecorded = 0;
+    
+    return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
@@ -857,8 +1214,18 @@
  */
 static DWORD midUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
 {
-	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
-	return MMSYSERR_NOTENABLED;
+    TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
+    
+    if (dwSize != sizeof(MIDIHDR) || lpMidiHdr == 0 || 
+	lpMidiHdr->lpData == 0 || lpMidiHdr->dwBufferLength >= 0x10000ul)
+	return MMSYSERR_INVALPARAM;
+    
+    if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) return MIDIERR_UNPREPARED;
+    if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING;
+    
+    lpMidiHdr->dwFlags &= ~MHDR_PREPARED;
+    
+    return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
@@ -866,8 +1233,21 @@
  */
 static DWORD midReset(WORD wDevID)
 {
-	TRACE(midi, "(%04X);\n", wDevID);
-	return MMSYSERR_NOTENABLED;
+    DWORD		dwTime = GetTickCount();
+    
+    TRACE(midi, "(%04X);\n", wDevID);
+    
+    while (MidiInDev[wDevID].lpQueueHdr) {
+	MidiInDev[wDevID].lpQueueHdr->dwFlags &= ~MHDR_INQUEUE;
+	MidiInDev[wDevID].lpQueueHdr->dwFlags |= MHDR_DONE;
+	if (MIDI_NotifyClient(wDevID, MIM_LONGDATA, 
+			      (DWORD)MidiInDev[wDevID].lpQueueHdr, dwTime) != MMSYSERR_NOERROR) {
+	    WARN(midi, "Couldn't notify client\n");
+	}
+	MidiInDev[wDevID].lpQueueHdr = (LPMIDIHDR)MidiInDev[wDevID].lpQueueHdr->lpNext;
+    }
+    
+    return MMSYSERR_NOERROR;
 }
 
 
@@ -876,88 +1256,229 @@
  */
 static DWORD midStart(WORD wDevID)
 {
-	TRACE(midi, "(%04X);\n", wDevID);
-	return MMSYSERR_NOTENABLED;
+    TRACE(midi, "(%04X);\n", wDevID);
+    
+    /* FIXME : should test value of wDevID */
+    
+#ifdef HAVE_OSS
+    MidiInDev[wDevID].state = 1;
+    MidiInDev[wDevID].startTime = GetTickCount();
+    return MMSYSERR_NOERROR;
+#else
+    return MMSYSERR_NOTENABLED;
+#endif /* HAVE_OSS */
 }
 
-
 /**************************************************************************
  *			midStop					[internal]
  */
 static DWORD midStop(WORD wDevID)
 {
-	TRACE(midi, "(%04X);\n", wDevID);
-	return MMSYSERR_NOTENABLED;
+    TRACE(midi, "(%04X);\n", wDevID);
+    
+    /* FIXME : should test value of wDevID */
+    
+#ifdef HAVE_OSS
+    MidiInDev[wDevID].state = 0;
+    return MMSYSERR_NOERROR;
+#else /* HAVE_OSS */
+    return MMSYSERR_NOTENABLED;
+#endif /* HAVE_OSS */
 }
 
-
 /**************************************************************************
  * 			midMessage				[sample driver]
  */
 DWORD WINAPI midMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
-					DWORD dwParam1, DWORD dwParam2)
+			DWORD dwParam1, DWORD dwParam2)
 {
-	TRACE(midi, "(%04X, %04X, %08lX, %08lX, %08lX);\n", 
-			wDevID, wMsg, dwUser, dwParam1, dwParam2);
-	switch(wMsg) {
-	case MIDM_OPEN:
-		return midOpen(wDevID,(LPMIDIOPENDESC)dwParam1, dwParam2);
-	case MIDM_CLOSE:
-		return midClose(wDevID);
-	case MIDM_ADDBUFFER:
-		return midAddBuffer(wDevID,(LPMIDIHDR)dwParam1, dwParam2);
-	case MIDM_PREPARE:
-		return midPrepare(wDevID,(LPMIDIHDR)dwParam1, dwParam2);
-	case MIDM_UNPREPARE:
-		return midUnprepare(wDevID,(LPMIDIHDR)dwParam1, dwParam2);
-	case MIDM_GETDEVCAPS:
-		return midGetDevCaps(wDevID,(LPMIDIINCAPS16)dwParam1,dwParam2);
-	case MIDM_GETNUMDEVS:
-		return 0;
-	case MIDM_RESET:
-		return midReset(wDevID);
-	case MIDM_START:
-		return midStart(wDevID);
-	case MIDM_STOP:
-		return midStop(wDevID);
-	}
-	return MMSYSERR_NOTSUPPORTED;
+    TRACE(midi, "(%04X, %04X, %08lX, %08lX, %08lX);\n", 
+	  wDevID, wMsg, dwUser, dwParam1, dwParam2);
+    switch(wMsg) {
+    case MIDM_OPEN:
+	return midOpen(wDevID,(LPMIDIOPENDESC)dwParam1, dwParam2);
+    case MIDM_CLOSE:
+	return midClose(wDevID);
+    case MIDM_ADDBUFFER:
+	return midAddBuffer(wDevID,(LPMIDIHDR)dwParam1, dwParam2);
+    case MIDM_PREPARE:
+	return midPrepare(wDevID,(LPMIDIHDR)dwParam1, dwParam2);
+    case MIDM_UNPREPARE:
+	return midUnprepare(wDevID,(LPMIDIHDR)dwParam1, dwParam2);
+    case MIDM_GETDEVCAPS:
+	return midGetDevCaps(wDevID,(LPMIDIINCAPS16)dwParam1,dwParam2);
+    case MIDM_GETNUMDEVS:
+	return MIDM_NUMDEVS; 
+    case MIDM_RESET:
+	return midReset(wDevID);
+    case MIDM_START:
+	return midStart(wDevID);
+    case MIDM_STOP:
+	return midStop(wDevID);
+    default:
+	TRACE(midi, "Unsupported message\n");
+    }
+    return MMSYSERR_NOTSUPPORTED;
 }
 
 /*-----------------------------------------------------------------------*/
 
+#ifdef HAVE_OSS
+
+typedef struct sVoice {
+    int			note;			/* 0 means not used */
+    int			channel;
+    unsigned		cntMark : 30,
+	                status : 2;
+#define sVS_UNUSED	0
+#define sVS_PLAYING	1
+#define sVS_SUSTAINED	2
+} sVoice;
+
+typedef struct sChannel {
+    int			program;
+    
+    int			bender;
+    int			benderRange;
+    /* controlers */
+    int			bank;		/* CTL_BANK_SELECT */
+    int			volume;		/* CTL_MAIN_VOLUME */
+    int			balance;	/* CTL_BALANCE     */
+    int			expression;	/* CTL_EXPRESSION  */
+    int			sustain;	/* CTL_SUSTAIN     */
+    
+    unsigned char	nrgPmtMSB;	/* Non register Parameters */
+    unsigned char	nrgPmtLSB;
+    unsigned char	regPmtMSB;	/* Non register Parameters */
+    unsigned char	regPmtLSB;
+} sChannel;
+
+typedef struct sFMextra {
+    unsigned		counter;
+    int			drumSetMask;
+    sChannel		channel[16];	/* MIDI has only 16 channels */
+    sVoice		voice[1];	/* dyn allocated according to sound card */
+    /* do not append fields below voice[1] since the size of this structure 
+     * depends on the number of available voices on the FM synth...
+     */
+} sFMextra;
+
+extern	unsigned char midiFMInstrumentPatches[16 * 128];
+extern	unsigned char midiFMDrumsPatches     [16 * 128];
+
+/**************************************************************************
+ * 			modFMLoad				[internal]
+ */
+static int modFMLoad(int dev)
+{
+    int				i;
+    struct sbi_instrument	sbi;
+    
+    sbi.device = dev;
+    sbi.key = FM_PATCH;
+    
+    memset(sbi.operators + 16, 0, 16);
+    for (i = 0; i < 128; i++) {
+	sbi.channel = i;
+	memcpy(sbi.operators, midiFMInstrumentPatches + i * 16, 16);
+	
+	if (write(midiSeqFD, (char*)&sbi, sizeof(sbi)) == -1) {
+	    WARN(midi, "Couldn't write patch for instrument %d (%d)!\n", sbi.channel, errno);
+	    return -1;
+	}
+    } 
+    for (i = 0; i < 128; i++) {
+	sbi.channel = 128 + i;
+	memcpy(sbi.operators, midiFMDrumsPatches + i * 16, 16);
+	
+	if (write(midiSeqFD, (char*)&sbi, sizeof(sbi)) == -1) {
+	    WARN(midi, "Couldn't write patch for drum %d (%d)!\n", sbi.channel, errno);
+	    return -1;
+	}
+    } 
+    return 0;
+}
+
+/**************************************************************************
+ * 			modFMReset				[internal]
+ */
+static	void modFMReset(WORD wDevID)
+{
+    sFMextra*	extra   = (sFMextra*)MidiOutDev[wDevID].lpExtra;
+    sVoice* 	voice   = extra->voice;
+    sChannel*	channel = extra->channel;
+    int		i;
+    
+    for (i = 0; i < midiOutDevices[wDevID]->wVoices; i++) {
+	if (voice[i].status != sVS_UNUSED) {
+	    SEQ_STOP_NOTE(wDevID, i, voice[i].note, 64);
+	}
+	SEQ_KEY_PRESSURE(wDevID, i, 127, 0);
+	SEQ_CONTROL(wDevID, i, SEQ_VOLMODE, VOL_METHOD_LINEAR);
+	voice[i].note = 0;
+	voice[i].channel = -1;
+	voice[i].cntMark = 0;
+	voice[i].status = sVS_UNUSED;
+    }
+    for (i = 0; i < 16; i++) {
+	channel[i].program = 0;
+	channel[i].bender = 8192;
+	channel[i].benderRange = 2;
+	channel[i].bank = 0;
+	channel[i].volume = 127;
+	channel[i].balance = 64;
+	channel[i].expression = 0;	
+	channel[i].sustain = 0;	
+    }
+    extra->counter = 0;
+    extra->drumSetMask = 1 << 9; /* channel 10 is normally drums, sometimes 16 also */
+    SEQ_DUMPBUF();
+}
+
+#define		IS_DRUM_CHANNEL(_xtra, _chn)	((_xtra)->drumSetMask & (1 << (_chn)))
+
+#endif /* HAVE_OSS */
+
 /**************************************************************************
  * 				modGetDevCaps			[internal]
  */
-static DWORD modGetDevCaps(WORD wDevID, LPMIDIOUTCAPS16 lpCaps, DWORD dwSize)
+static DWORD modGetDevCaps(WORD wDevID, LPMIDIOUTCAPS16 lpCaps, 
+			   DWORD dwSize)
 {
-  LPMIDIOUTCAPS16 tmplpCaps;
-
-	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpCaps, dwSize);
-  if (wDevID == (WORD) MIDI_MAPPER) { 
+    TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpCaps, dwSize);
+    if (wDevID == (WORD) MIDI_MAPPER) { 
 	lpCaps->wMid = 0x00FF; 	/* Manufac ID */
 	lpCaps->wPid = 0x0001; 	/* Product ID */
 	lpCaps->vDriverVersion = 0x001; /* Product Version */
-    strcpy(lpCaps->szPname, "MIDI Maper (not functional yet)");
-    lpCaps->wTechnology = MOD_FMSYNTH; /* FIXME Does it make any difference ? */
-    lpCaps->wVoices     = 14;       /* FIXME */
-    lpCaps->wNotes      = 14;       /* FIXME */
-    lpCaps->dwSupport   = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME; /* FIXME Does it make any difference ? */
-  } else {
-    /* FIXME There is a way to do it so easily, but I'm too
-     * sleepy to think and I want to test
-*/
-    tmplpCaps = midiDevices [wDevID];
-    lpCaps->wMid = tmplpCaps->wMid;  
-    lpCaps->wPid = tmplpCaps->wPid;  
-    lpCaps->vDriverVersion = tmplpCaps->vDriverVersion;  
-    strcpy(lpCaps->szPname, tmplpCaps->szPname);    
-    lpCaps->wTechnology = tmplpCaps->wTechnology;
-    lpCaps->wVoices = tmplpCaps->wVoices;  
-    lpCaps->wNotes = tmplpCaps->wNotes;  
-    lpCaps->dwSupport = tmplpCaps->dwSupport;  
-  }
-	return MMSYSERR_NOERROR;
+	strcpy(lpCaps->szPname, "MIDI Mapper (not functional yet)");
+	/* FIXME Does it make any difference ? */
+	lpCaps->wTechnology = MOD_FMSYNTH; 
+	lpCaps->wVoices     = 14;       /* FIXME */
+	lpCaps->wNotes      = 14;       /* FIXME */
+	/* FIXME Does it make any difference ? */
+	lpCaps->dwSupport   = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME; 
+    } else {
+	LPMIDIOUTCAPS16	tmplpCaps;
+	
+	if (wDevID >= MODM_NUMDEVS) {
+	    TRACE(midi, "MAX_MIDIOUTDRV reached !\n");
+	    return MMSYSERR_BADDEVICEID;
+	}
+	/* FIXME There is a way to do it so easily, but I'm too
+	 * sleepy to think and I want to test
+	 */
+	
+	tmplpCaps = midiOutDevices[wDevID];
+	lpCaps->wMid = tmplpCaps->wMid;  
+	lpCaps->wPid = tmplpCaps->wPid;  
+	lpCaps->vDriverVersion = tmplpCaps->vDriverVersion;  
+	strcpy(lpCaps->szPname, tmplpCaps->szPname);    
+	lpCaps->wTechnology = tmplpCaps->wTechnology;
+	lpCaps->wVoices = tmplpCaps->wVoices;  
+	lpCaps->wNotes = tmplpCaps->wNotes;  
+	lpCaps->dwSupport = tmplpCaps->dwSupport;
+    }
+    return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
@@ -965,48 +1486,101 @@
  */
 static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
 {
-	int		midi;
-
-	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
-	if (lpDesc == NULL) {
-		WARN(midi, "Invalid Parameter !\n");
-		return MMSYSERR_INVALPARAM;
+    TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
+    if (lpDesc == NULL) {
+	WARN(midi, "Invalid Parameter !\n");
+	return MMSYSERR_INVALPARAM;
+    }
+    if (wDevID >= MAX_MIDIOUTDRV) {
+	TRACE(midi,"MAX_MIDIOUTDRV reached !\n");
+	return MMSYSERR_BADDEVICEID;
+    }
+    if (MidiOutDev[wDevID].midiDesc != 0) {
+	WARN(midi, "device already open !\n");
+	return MMSYSERR_ALLOCATED;
+    }
+    if ((dwFlags & ~CALLBACK_TYPEMASK) != 0) { 
+	WARN(midi, "bad dwFlags\n");
+	return MMSYSERR_INVALFLAG;
+    }
+    
+#ifdef HAVE_OSS
+    MidiOutDev[wDevID].lpExtra = 0;
+    
+    switch (midiOutDevices[wDevID]->wTechnology) {
+    case MOD_FMSYNTH:
+	{
+	    void*	extra = xmalloc(sizeof(struct sFMextra) + 
+					sizeof(struct sVoice) * 
+					(midiOutDevices[wDevID]->wVoices - 1));
+	    
+	    if (extra == 0) {
+		WARN(midi, "can't alloc extra data !\n");
+		return MMSYSERR_NOMEM;
+	    }
+	    MidiOutDev[wDevID].lpExtra = extra;
+	    if (midiOpenSeq() < 0) {
+		MidiOutDev[wDevID].lpExtra = 0;
+		free(extra);
+		return MMSYSERR_ERROR;
+	    }
+	    if (modFMLoad(wDevID) < 0) {
+		midiCloseSeq();
+		MidiOutDev[wDevID].lpExtra = 0;
+		free(extra);
+		return MMSYSERR_ERROR;
+	    }
+	    modFMReset(wDevID);
 	}
-	if (wDevID>= MAX_MIDIOUTDRV) {
-		TRACE(midi,"MAX_MIDIOUTDRV reached !\n");
-		return MMSYSERR_ALLOCATED; /* FIXME isn't MMSYSERR_BADDEVICEID the right answer ? */
+	break;
+    case MOD_MIDIPORT:
+	if (midiOpenSeq() < 0) {
+	    return MMSYSERR_ALLOCATED;
 	}
+	break;
+    default:
+	WARN(midi,"Technology not supported (yet) %d !\n", 
+	     midiOutDevices[wDevID]->wTechnology);
+	return MMSYSERR_NOTENABLED;
+    }
+#else /* HAVE_OSS */
+    {	
+	int	midi = open (MIDI_DEV, O_WRONLY, 0);
 	MidiOutDev[wDevID].unixdev = 0;
-	midi = open (MIDI_DEV, O_WRONLY, 0);
 	if (midi == -1) {
-		WARN(midi, "can't open !\n");
-		return MMSYSERR_NOTENABLED;
+	    WARN(midi, "can't open !\n");
+	    return MMSYSERR_ALLOCATED;
 	}
-	MidiOutDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
-	switch(MidiOutDev[wDevID].wFlags) {
-	case DCB_NULL:
-		TRACE(midi,"CALLBACK_NULL !\n");
-		break;
-	case DCB_WINDOW:
-		TRACE(midi, "CALLBACK_WINDOW !\n");
-		break;
-	case DCB_TASK:
-		TRACE(midi, "CALLBACK_TASK !\n");
-		break;
-	case DCB_FUNCTION:
-		TRACE(midi, "CALLBACK_FUNCTION !\n");
-		break;
-	}
-	MidiOutDev[wDevID].lpQueueHdr = NULL;
 	MidiOutDev[wDevID].unixdev = midi;
-	MidiOutDev[wDevID].dwTotalPlayed = 0;
-	MidiOutDev[wDevID].bufsize = 0x3FFF;
-	if (MIDI_NotifyClient(wDevID, MOM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
-		WARN(midi,"can't notify client !\n");
-		return MMSYSERR_INVALPARAM;
-	}
-	TRACE(midi, "Succesful unixdev=%d !\n", midi);
-	return MMSYSERR_NOERROR;
+    }
+#endif /* HAVE_OSS */	
+    
+    MidiOutDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
+    switch(MidiOutDev[wDevID].wFlags) {
+    case DCB_NULL:
+	TRACE(midi,"CALLBACK_NULL !\n");
+	break;
+    case DCB_WINDOW:
+	TRACE(midi, "CALLBACK_WINDOW !\n");
+	break;
+    case DCB_TASK:
+	TRACE(midi, "CALLBACK_TASK !\n");
+	break;
+    case DCB_FUNCTION:
+	TRACE(midi, "CALLBACK_FUNCTION !\n");
+	break;
+    }
+    MidiOutDev[wDevID].lpQueueHdr = NULL;
+    MidiOutDev[wDevID].dwTotalPlayed = 0;
+    MidiOutDev[wDevID].bufsize = 0x3FFF;
+    MidiOutDev[wDevID].midiDesc = lpDesc;
+    
+    if (MIDI_NotifyClient(wDevID, MOM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
+	WARN(midi,"can't notify client !\n");
+	return MMSYSERR_INVALPARAM;
+    }
+    TRACE(midi, "Succesful !\n");
+    return MMSYSERR_NOERROR;
 }
 
 
@@ -1015,19 +1589,54 @@
  */
 static DWORD modClose(WORD wDevID)
 {
-	TRACE(midi, "(%04X);\n", wDevID);
-	if (MidiOutDev[wDevID].unixdev == 0) {
-		WARN(midi,"can't close !\n");
-		return MMSYSERR_NOTENABLED;
-	}
-	close(MidiOutDev[wDevID].unixdev);
-	MidiOutDev[wDevID].unixdev = 0;
-	MidiOutDev[wDevID].bufsize = 0;
-	if (MIDI_NotifyClient(wDevID, MOM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
-		WARN(midi,"can't notify client !\n");
-		return MMSYSERR_INVALPARAM;
-	}
-	return MMSYSERR_NOERROR;
+    int	ret = MMSYSERR_NOERROR;
+
+    TRACE(midi, "(%04X);\n", wDevID);
+    
+    if (MidiOutDev[wDevID].midiDesc == 0) {
+	WARN(midi, "device not opened !\n");
+	return MMSYSERR_ERROR;
+    }
+    /* FIXME: should test that no pending buffer is still in the queue for
+     * playing */
+    
+#ifdef HAVE_OSS	
+    if (midiSeqFD == -1) {
+	WARN(midi,"can't close !\n");
+	return MMSYSERR_ERROR;
+    }
+    
+    switch (midiOutDevices[wDevID]->wTechnology) {
+    case MOD_FMSYNTH:
+    case MOD_MIDIPORT:
+	midiCloseSeq();
+	break;
+    default:
+	WARN(midi,"Technology not supported (yet) %d !\n", 
+	     midiOutDevices[wDevID]->wTechnology);
+	return MMSYSERR_NOTENABLED;
+    }
+    
+    if (MidiOutDev[wDevID].lpExtra != 0) {
+	free(MidiOutDev[wDevID].lpExtra);
+	MidiOutDev[wDevID].lpExtra = 0;
+    }
+#else
+    if (MidiOutDev[wDevID].unixdev == 0) {
+	WARN(midi,"can't close !\n");
+	return MMSYSERR_NOTENABLED;
+    }
+    close(MidiOutDev[wDevID].unixdev);
+    MidiOutDev[wDevID].unixdev = 0;
+#endif /* HAVE_OSS */
+    
+    MidiOutDev[wDevID].bufsize = 0;
+    if (MIDI_NotifyClient(wDevID, MOM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
+	WARN(midi,"can't notify client !\n");
+	ret = MMSYSERR_INVALPARAM;
+    }
+    MidiOutDev[wDevID].midiDesc = 0;
+    return ret;
 }
 
 /**************************************************************************
@@ -1035,19 +1644,298 @@
  */
 static DWORD modData(WORD wDevID, DWORD dwParam)
 {
-	WORD	event;
-
-	TRACE(midi, "(%04X, %08lX);\n", wDevID, dwParam);
-	if (MidiOutDev[wDevID].unixdev == 0) {
-        	WARN(midi,"can't play !\n");
+    WORD	evt = LOBYTE(LOWORD(dwParam));
+    WORD	d1  = HIBYTE(LOWORD(dwParam));
+    WORD	d2  = LOBYTE(HIWORD(dwParam));
+    
+    TRACE(midi, "(%04X, %08lX);\n", wDevID, dwParam);
+    
+#ifdef HAVE_OSS
+    if (midiSeqFD == -1) {
+	WARN(midi,"can't play !\n");
+	return MIDIERR_NODEVICE;
+    }
+    switch (midiOutDevices[wDevID]->wTechnology) {
+    case MOD_FMSYNTH:
+	/* FIXME:
+	 *	- chorus depth controller is not used
+	 */
+	{
+	    sFMextra*	extra   = (sFMextra*)MidiOutDev[wDevID].lpExtra;
+	    sVoice* 	voice   = extra->voice;
+	    sChannel*	channel = extra->channel;
+	    int		chn = (evt & 0x0F);
+	    int		i, nv;
+	    
+	    switch (evt & 0xF0) {
+	    case MIDI_NOTEOFF:
+		for (i = 0; i < midiOutDevices[wDevID]->wVoices; i++) {
+				/* don't stop sustained notes */
+		    if (voice[i].status == sVS_PLAYING && voice[i].channel == chn && voice[i].note == d1) {
+			voice[i].status = sVS_UNUSED;
+			SEQ_STOP_NOTE(wDevID, i, d1, d2);
+		    }
+		}
+		break;	
+	    case MIDI_NOTEON:
+		if (d2 == 0) { /* note off if velocity == 0 */
+		    for (i = 0; i < midiOutDevices[wDevID]->wVoices; i++) {
+			/* don't stop sustained notes */
+			if (voice[i].status == sVS_PLAYING && voice[i].channel == chn && voice[i].note == d1) {
+			    voice[i].status = sVS_UNUSED;
+			    SEQ_STOP_NOTE(wDevID, i, d1, 64);
+			}
+		    }
+		    break;
+		}
+		/* finding out in this order :
+		 *	- an empty voice
+		 *	- if replaying the same note on the same channel
+		 *	- the older voice (LRU)
+		 */
+		for (i = nv = 0; i < midiOutDevices[wDevID]->wVoices; i++) {
+		    if (voice[i].status == sVS_UNUSED || 
+			(voice[i].note == d1 && voice[i].channel == chn)) {
+			nv = i;
+			break;
+		    }
+		    if (voice[i].cntMark < voice[0].cntMark) {
+			nv = i;
+		    }
+		}
+		TRACE(midi, 
+		      "playing on voice=%d, pgm=%d, pan=0x%02X, vol=0x%02X, "
+		      "bender=0x%02X, note=0x%02X, vel=0x%02X\n", 
+		      nv, channel[chn].program, 
+		      channel[chn].balance, 
+		      channel[chn].volume, 
+		      channel[chn].bender, d1, d2);
+		
+		SEQ_SET_PATCH(wDevID, nv, IS_DRUM_CHANNEL(extra, chn) ? 
+			      (128 + d1) : channel[chn].program);
+		SEQ_BENDER_RANGE(wDevID, nv, channel[chn].benderRange * 100);
+		SEQ_BENDER(wDevID, nv, channel[chn].bender);
+		SEQ_CONTROL(wDevID, nv, CTL_PAN, channel[chn].balance);
+		SEQ_CONTROL(wDevID, nv, CTL_EXPRESSION, channel[chn].expression);
+#if 0	
+		/* FIXME: does not really seem to work on my SB card and
+		 * screws everything up... so lay it down
+		 */
+		SEQ_CONTROL(wDevID, nv, CTL_MAIN_VOLUME, channel[chn].volume);
+#endif	
+		SEQ_START_NOTE(wDevID, nv, d1, d2);
+		voice[nv].status = channel[chn].sustain ? sVS_SUSTAINED : sVS_PLAYING;
+		voice[nv].note = d1;
+		voice[nv].channel = chn;
+		voice[nv].cntMark = extra->counter++;
+		break;
+	    case MIDI_KEY_PRESSURE:
+		for (i = 0; i < midiOutDevices[wDevID]->wVoices; i++) {
+		    if (voice[i].status != sVS_UNUSED && voice[i].channel == chn && voice[i].note == d1) {
+			SEQ_KEY_PRESSURE(wDevID, i, d1, d2);
+		    }
+		}
+		break;
+	    case MIDI_CTL_CHANGE:
+		switch (d1) {
+		case CTL_BANK_SELECT:	channel[chn].bank = d2;		break;
+		case CTL_MAIN_VOLUME:	channel[chn].volume = d2;	break;
+		case CTL_PAN:		channel[chn].balance = d2;	break;
+		case CTL_EXPRESSION:	channel[chn].expression = d2;	break;
+		case CTL_SUSTAIN:	channel[chn].sustain = d2;
+		    if (d2) {
+			for (i = 0; i < midiOutDevices[wDevID]->wVoices; i++) {
+			    if (voice[i].status == sVS_PLAYING && voice[i].channel == chn) {
+				voice[i].status = sVS_SUSTAINED;
+			    }
+			}
+		    } else {
+			for (i = 0; i < midiOutDevices[wDevID]->wVoices; i++) {
+			    if (voice[i].status == sVS_SUSTAINED && voice[i].channel == chn) {
+				voice[i].status = sVS_UNUSED;
+				SEQ_STOP_NOTE(wDevID, i, voice[i].note, 64);
+			    }
+			}
+		    }
+		    break;
+		case CTL_NONREG_PARM_NUM_LSB:	channel[chn].nrgPmtLSB = d2;	break;
+		case CTL_NONREG_PARM_NUM_MSB:	channel[chn].nrgPmtMSB = d2;	break;
+		case CTL_REGIST_PARM_NUM_LSB:	channel[chn].regPmtLSB = d2;	break;
+		case CTL_REGIST_PARM_NUM_MSB:	channel[chn].regPmtMSB = d2;	break;
+		    
+		case CTL_DATA_ENTRY:
+		    switch ((channel[chn].regPmtMSB << 8) | channel[chn].regPmtLSB) {
+		    case 0x0000: 
+			if (channel[chn].benderRange != d2) {
+			    channel[chn].benderRange = d2;
+			    for (i = 0; i < midiOutDevices[wDevID]->wVoices; i++) {
+				if (voice[i].channel == chn) {
+				    SEQ_BENDER_RANGE(wDevID, i, channel[chn].benderRange);
+				}
+			    }
+			}
+			break;
+			
+		    case 0x7F7F:
+			channel[chn].benderRange = 2;
+			for (i = 0; i < midiOutDevices[wDevID]->wVoices; i++) {
+			    if (voice[i].channel == chn) {
+				SEQ_BENDER_RANGE(wDevID, i, channel[chn].benderRange);
+			    }
+			}
+			break;
+		    default:
+			TRACE(midi, "Data entry: regPmt=0x%02x%02x, nrgPmt=0x%02x%02x with %x\n",
+			      channel[chn].regPmtMSB, channel[chn].regPmtLSB,
+			      channel[chn].nrgPmtMSB, channel[chn].nrgPmtLSB,
+			      d2);
+			break;
+		    }
+		    break;
+		    
+		case 0x78: /* all sounds off */
+		    for (i = 0; i < midiOutDevices[wDevID]->wVoices; i++) {
+			if (voice[i].status != sVS_UNUSED && voice[i].channel == chn) {
+			    voice[i].status = sVS_UNUSED;
+			    SEQ_STOP_NOTE(wDevID, i, voice[i].note, 0);
+			}
+		    }
+		    break;
+		case 0x7B: /* all notes off */
+		    for (i = 0; i < midiOutDevices[wDevID]->wVoices; i++) {
+			if (voice[i].status == sVS_PLAYING && voice[i].channel == chn) {
+			    voice[i].status = sVS_UNUSED;
+			    SEQ_STOP_NOTE(wDevID, i, voice[i].note, 0);
+			}
+		    }
+		    break;	
+		default:
+		    TRACE(midi, "Dropping MIDI control event 0x%02x(%02x) on channel %d\n", 
+			  d1, d2, chn);
+		    break;
+		}
+		break;
+	    case MIDI_PGM_CHANGE:
+		channel[chn].program = d1;
+		break;
+	    case MIDI_CHN_PRESSURE:
+		for (i = 0; i < midiOutDevices[wDevID]->wVoices; i++) {
+		    if (voice[i].status != sVS_UNUSED && voice[i].channel == chn) {
+			SEQ_KEY_PRESSURE(wDevID, i, voice[i].note, d1);
+		    }
+		}
+		break;
+	    case MIDI_PITCH_BEND:
+		channel[chn].bender = (d2 << 7) + d1;
+		for (i = 0; i < midiOutDevices[wDevID]->wVoices; i++) {
+		    if (voice[i].channel == chn) {
+			SEQ_BENDER(wDevID, i, channel[chn].bender);
+		    }
+		}
+		break;
+	    case MIDI_SYSTEM_PREFIX:
+		switch (evt & 0x0F) {
+		case 0x0F: 	/* Reset */
+		    modFMReset(wDevID);
+		    break; 
+		default:
+		    WARN(midi, 
+			 "Unsupported (yet) system event %02x\n", 
+			 evt & 0x0F);
+		}
+		break;
+	    default:	
+		WARN(midi, "Internal error, shouldn't happen\n");
+		return MMSYSERR_NOTENABLED;
+	    }
+	}
+	break;
+    case MOD_MIDIPORT:
+	{
+	    int	dev = wDevID - MODM_NUMFMSYNTHDEVS;
+	    if (dev < 0) {
+		WARN(midi, "Internal error on devID (%u) !\n", wDevID);
 		return MIDIERR_NODEVICE;
+	    }
+	    
+	    switch (evt & 0xF0) {
+	    case MIDI_NOTEOFF:
+	    case MIDI_NOTEON:
+	    case MIDI_KEY_PRESSURE:
+	    case MIDI_CTL_CHANGE:
+	    case MIDI_PITCH_BEND:
+		SEQ_MIDIOUT(dev, evt);	
+		SEQ_MIDIOUT(dev, d1);	
+		SEQ_MIDIOUT(dev, d2); 	
+		break;
+	    case MIDI_PGM_CHANGE:
+	    case MIDI_CHN_PRESSURE:
+		SEQ_MIDIOUT(dev, evt);	
+		SEQ_MIDIOUT(dev, d1);										
+		break;	
+	    case MIDI_SYSTEM_PREFIX:
+		switch (evt & 0x0F) {
+		case 0x00:	/* System Exclusive, don't do it on modData, 
+				 * should require modLongData*/
+		case 0x01:	/* Undefined */
+		case 0x04:	/* Undefined. */
+		case 0x05:	/* Undefined. */
+		case 0x07:	/* End of Exclusive. */
+		case 0x09:	/* Undefined. */
+		case 0x0D:	/* Undefined. */
+		    break;
+		case 0x06:	/* Tune Request */
+		case 0x08:	/* Timing Clock. */
+		case 0x0A:	/* Start. */
+		case 0x0B:	/* Continue */
+		case 0x0C:	/* Stop */
+		case 0x0E: 	/* Active Sensing. */
+		    SEQ_MIDIOUT(dev, evt);	
+		    break;
+		case 0x0F: 	/* Reset */
+				/* SEQ_MIDIOUT(dev, evt);
+				   this other way may be better */
+		    SEQ_MIDIOUT(dev, MIDI_SYSTEM_PREFIX);
+		    SEQ_MIDIOUT(dev, 0x7e);
+		    SEQ_MIDIOUT(dev, 0x7f);
+		    SEQ_MIDIOUT(dev, 0x09);
+		    SEQ_MIDIOUT(dev, 0x01);
+		    SEQ_MIDIOUT(dev, 0xf7);
+		    break;
+		case 0x03:	/* Song Select. */
+		    SEQ_MIDIOUT(dev, evt);	
+		    SEQ_MIDIOUT(dev, d1);	  									
+		case 0x02:	/* Song Position Pointer. */
+		    SEQ_MIDIOUT(dev, evt);	
+		    SEQ_MIDIOUT(dev, d1);
+		    SEQ_MIDIOUT(dev, d2);
+		}
+		break;
+	    }
 	}
-	event = LOWORD(dwParam);
-	if (write (MidiOutDev[wDevID].unixdev, 
-		&event, sizeof(WORD)) != sizeof(WORD)) {
-		WARN(midi, "error writting unixdev !\n");
-	}
+	break;
+    default:
+	WARN(midi, "Technology not supported (yet) %d !\n", 
+	     midiOutDevices[wDevID]->wTechnology);
 	return MMSYSERR_NOTENABLED;
+    }
+    
+    SEQ_DUMPBUF();
+    TRACE(midi, "done\n");
+#else
+    if (MidiOutDev[wDevID].unixdev == 0) {
+	WARN(midi,"can't play !\n");
+	return MIDIERR_NODEVICE;
+    }
+    {
+	WORD	event = LOWORD(dwParam);
+	if (write (MidiOutDev[wDevID].unixdev, 
+		   &event, sizeof(event)) != sizeof(WORD)) {
+	    WARN(midi, "error writting unixdev !\n");
+	}
+    }
+#endif /* HAVE_OSS */
+    return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
@@ -1055,51 +1943,96 @@
  */
 static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
 {
-	int		count;
-	LPWORD	ptr;
-	int     en;
-
-	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
-	if (MidiOutDev[wDevID].unixdev == 0) {
-        WARN(midi,"can't play !\n");
-		return MIDIERR_NODEVICE;
-		}
-	if (lpMidiHdr->lpData == NULL) return MIDIERR_UNPREPARED;
-	if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) return MIDIERR_UNPREPARED;
-	if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING;
-	lpMidiHdr->dwFlags &= ~MHDR_DONE;
-	lpMidiHdr->dwFlags |= MHDR_INQUEUE;
-	TRACE(midi, "dwBytesRecorded %lu !\n", lpMidiHdr->dwBytesRecorded);
-	TRACE(midi, "                 %02X %02X %02X %02X\n",
-		     lpMidiHdr->lpData[0], lpMidiHdr->lpData[1],
-		     lpMidiHdr->lpData[2], lpMidiHdr->lpData[3]);
-/*
-	count = write (MidiOutDev[wDevID].unixdev, 
-		lpMidiHdr->lpData, lpMidiHdr->dwBytesRecorded);
-*/
-	ptr = (LPWORD)lpMidiHdr->lpData;
-	for (count = 0; count < lpMidiHdr->dwBytesRecorded; count++) {
-		if (write (MidiOutDev[wDevID].unixdev, ptr, 
-			sizeof(WORD)) != sizeof(WORD)) break;
-		ptr++;
+    int		count;
+    
+    TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
+    
+#ifdef HAVE_OSS
+    if (midiSeqFD == -1) {
+	WARN(midi,"can't play !\n");
+	return MIDIERR_NODEVICE;
+    }
+#else /* HAVE_OSS */
+    if (MidiOutDev[wDevID].unixdev == 0) {
+	WARN(midi,"can't play !\n");
+	return MIDIERR_NODEVICE;
+    }
+#endif /* HAVE_OSS */
+    
+    if (lpMidiHdr->lpData == NULL) 
+	return MIDIERR_UNPREPARED;
+    if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) 
+	return MIDIERR_UNPREPARED;
+    if (lpMidiHdr->dwFlags & MHDR_INQUEUE) 
+	return MIDIERR_STILLPLAYING;
+    lpMidiHdr->dwFlags &= ~MHDR_DONE;
+    lpMidiHdr->dwFlags |= MHDR_INQUEUE;
+    TRACE(midi, "dwBytesRecorded %lu !\n", lpMidiHdr->dwBytesRecorded);
+    TRACE(midi, "                 %02X %02X %02X %02X\n",
+	  ((LPBYTE)(lpMidiHdr->reserved))[0],
+	  ((LPBYTE)(lpMidiHdr->reserved))[1],
+	  ((LPBYTE)(lpMidiHdr->reserved))[2],
+	  ((LPBYTE)(lpMidiHdr->reserved))[3]);
+#ifdef HAVE_OSS
+    switch (midiOutDevices[wDevID]->wTechnology) {
+    case MOD_FMSYNTH:
+	/* FIXME: I don't think there is much to do here */
+	break;
+    case MOD_MIDIPORT:
+	if (((LPBYTE)lpMidiHdr->reserved)[0] != 0xF0) {
+	    /* Send end of System Exclusive */
+	    SEQ_MIDIOUT(wDevID - MODM_NUMFMSYNTHDEVS, 0xF0);
+	    TRACE(midi, "Adding missing 0xF0 marker at the begining of "
+		  "system exclusive byte stream\n");
 	}
-
+	for (count = 0; count < lpMidiHdr->dwBytesRecorded; count++) {
+	    SEQ_MIDIOUT(wDevID - MODM_NUMFMSYNTHDEVS, 
+			((LPBYTE)lpMidiHdr->reserved)[count]);	
+	}
+	if (((LPBYTE)lpMidiHdr->reserved)[count - 1] != 0xF7) {
+	    /* Send end of System Exclusive */
+	    SEQ_MIDIOUT(wDevID - MODM_NUMFMSYNTHDEVS, 0xF7);
+	    TRACE(midi, "Adding missing 0xF7 marker at the end of "
+		  "system exclusive byte stream\n");
+	}
+	SEQ_DUMPBUF();
+	break;
+    default:
+	WARN(midi, "Technology not supported (yet) %d !\n", 
+	     midiOutDevices[wDevID]->wTechnology);
+	return MMSYSERR_NOTENABLED;
+    }
+#else /* HAVE_OSS */
+    {
+	LPWORD	ptr = (LPWORD)lpMidiHdr->reserved;
+	int		en;
+	
+	for (count = 0; count < lpMidiHdr->dwBytesRecorded; count++) {
+	    if (write(MidiOutDev[wDevID].unixdev, 
+		      ptr, sizeof(WORD)) != sizeof(WORD)) 
+		break;
+	    ptr++;
+	}
+	
 	en = errno;
 	TRACE(midi, "after write count = %d\n",count);
 	if (count != lpMidiHdr->dwBytesRecorded) {
-		WARN(midi, "error writting unixdev #%d ! (%d != %ld)\n",
-			     MidiOutDev[wDevID].unixdev, count, 
-			     lpMidiHdr->dwBytesRecorded);
-		TRACE(midi, "\terrno = %d error = %s\n",en,strerror(en));
-		return MMSYSERR_NOTENABLED;
+	    WARN(midi, "error writting unixdev #%d ! (%d != %ld)\n",
+		 MidiOutDev[wDevID].unixdev, count, 
+		 lpMidiHdr->dwBytesRecorded);
+	    TRACE(midi, "\terrno = %d error = %s\n",en,strerror(en));
+	    return MMSYSERR_NOTENABLED;
 	}
-	lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
-	lpMidiHdr->dwFlags |= MHDR_DONE;
-	if (MIDI_NotifyClient(wDevID, MOM_DONE, 0L, 0L) != MMSYSERR_NOERROR) {
-		WARN(midi,"can't notify client !\n");
-		return MMSYSERR_INVALPARAM;
-	}
-	return MMSYSERR_NOERROR;
+    }
+#endif /* HAVE_OSS */
+    
+    lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
+    lpMidiHdr->dwFlags |= MHDR_DONE;
+    if (MIDI_NotifyClient(wDevID, MOM_DONE, (DWORD)lpMidiHdr, 0L) != MMSYSERR_NOERROR) {
+	WARN(midi,"can't notify client !\n");
+	return MMSYSERR_INVALPARAM;
+    }
+    return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
@@ -1107,21 +2040,28 @@
  */
 static DWORD modPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
 {
-	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
-	if (MidiOutDev[wDevID].unixdev == 0) {
-		WARN(midi,"can't prepare !\n");
-		return MMSYSERR_NOTENABLED;
-	}
-	if (MidiOutDev[wDevID].lpQueueHdr != NULL) {
-		TRACE(midi,"already prepare !\n");
-		return MMSYSERR_NOTENABLED;
-	}
-	MidiOutDev[wDevID].dwTotalPlayed = 0;
-	MidiOutDev[wDevID].lpQueueHdr = PTR_SEG_TO_LIN(lpMidiHdr);
-	if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING;
-	lpMidiHdr->dwFlags |= MHDR_PREPARED;
-	lpMidiHdr->dwFlags &= ~MHDR_DONE;
-	return MMSYSERR_NOERROR;
+    TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
+    
+#ifdef HAVE_OSS
+    if (midiSeqFD == -1) {
+	WARN(midi,"can't prepare !\n");
+	return MMSYSERR_NOTENABLED;
+    }
+#else /* HAVE_OSS */
+    if (MidiOutDev[wDevID].unixdev == 0) {
+	WARN(midi,"can't prepare !\n");
+	return MMSYSERR_NOTENABLED;
+    }
+#endif /* HAVE_OSS */
+    if (dwSize != sizeof(MIDIHDR) || lpMidiHdr == 0 || 
+	lpMidiHdr->lpData == 0 || lpMidiHdr->dwFlags != 0 || 
+	lpMidiHdr->dwBufferLength >= 0x10000ul)
+	return MMSYSERR_INVALPARAM;
+    
+    lpMidiHdr->lpNext = 0;
+    lpMidiHdr->dwFlags |= MHDR_PREPARED;
+    lpMidiHdr->dwFlags &= ~MHDR_DONE;
+    return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
@@ -1129,12 +2069,24 @@
  */
 static DWORD modUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
 {
-	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
-	if (MidiOutDev[wDevID].unixdev == 0) {
-		WARN(midi,"can't unprepare !\n");
-		return MMSYSERR_NOTENABLED;
-	}
-	return MMSYSERR_NOERROR;
+    TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
+#ifdef HAVE_OSS
+    if (midiSeqFD == -1) {
+	WARN(midi,"can't unprepare !\n");
+	return MMSYSERR_NOTENABLED;
+    }
+#else /* HAVE_OSS */
+    if (MidiOutDev[wDevID].unixdev == 0) {
+	WARN(midi,"can't unprepare !\n");
+	return MMSYSERR_NOTENABLED;
+    }
+#endif /* HAVE_OSS */
+    if (dwSize != sizeof(MIDIHDR) || lpMidiHdr == 0)
+	return MMSYSERR_INVALPARAM;
+    if (lpMidiHdr->dwFlags & MHDR_INQUEUE)
+	return MIDIERR_STILLPLAYING;
+    lpMidiHdr->dwFlags &= ~MHDR_PREPARED;
+    return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
@@ -1142,102 +2094,106 @@
  */
 static DWORD modReset(WORD wDevID)
 {
-	TRACE(midi, "(%04X);\n", wDevID);
-	return MMSYSERR_NOTENABLED;
+    TRACE(midi, "(%04X);\n", wDevID);
+    /* FIXME: this function should :
+     *	turn off every note, remove sustain on all channels
+     *	remove any pending buffers
+     */
+    return MMSYSERR_NOTENABLED;
 }
 
-
 /**************************************************************************
  * 				modMessage			[sample driver]
  */
 DWORD WINAPI modMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
-					DWORD dwParam1, DWORD dwParam2)
+			DWORD dwParam1, DWORD dwParam2)
 {
-	TRACE(midi, "(%04X, %04X, %08lX, %08lX, %08lX);\n", 
-			wDevID, wMsg, dwUser, dwParam1, dwParam2);
-	switch(wMsg) {
-	case MODM_OPEN:
-		return modOpen(wDevID, (LPMIDIOPENDESC)dwParam1, dwParam2);
-	case MODM_CLOSE:
-		return modClose(wDevID);
-	case MODM_DATA:
-		return modData(wDevID, dwParam1);
-	case MODM_LONGDATA:
-		return modLongData(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
-	case MODM_PREPARE:
-		return modPrepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
-	case MODM_UNPREPARE:
-		return modUnprepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
-	case MODM_GETDEVCAPS:
-		return modGetDevCaps(wDevID,(LPMIDIOUTCAPS16)dwParam1,dwParam2);
-	case MODM_GETNUMDEVS:
-		return MODM_NUMDEVS;
-	case MODM_GETVOLUME:
-		return 0;
-	case MODM_SETVOLUME:
-		return 0;
-	case MODM_RESET:
-		return modReset(wDevID);
-	}
-	return MMSYSERR_NOTSUPPORTED;
+    TRACE(midi, "(%04X, %04X, %08lX, %08lX, %08lX);\n", 
+	  wDevID, wMsg, dwUser, dwParam1, dwParam2);
+    switch(wMsg) {
+    case MODM_OPEN:
+	return modOpen(wDevID, (LPMIDIOPENDESC)dwParam1, dwParam2);
+    case MODM_CLOSE:
+	return modClose(wDevID);
+    case MODM_DATA:
+	return modData(wDevID, dwParam1);
+    case MODM_LONGDATA:
+	return modLongData(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
+    case MODM_PREPARE:
+	return modPrepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
+    case MODM_UNPREPARE:
+	return modUnprepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
+    case MODM_GETDEVCAPS:
+	return modGetDevCaps(wDevID,(LPMIDIOUTCAPS16)dwParam1,dwParam2);
+    case MODM_GETNUMDEVS:
+	return MODM_NUMDEVS;
+    case MODM_GETVOLUME:
+	return 0;
+    case MODM_SETVOLUME:
+	return 0;
+    case MODM_RESET:
+	return modReset(wDevID);
+    default:
+	TRACE(midi, "Unsupported message\n");
+    }
+    return MMSYSERR_NOTSUPPORTED;
 }
 
-
 /**************************************************************************
  * 				MIDI_DriverProc		[sample driver]
  */
 LONG MIDI_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
 		     DWORD dwParam1, DWORD dwParam2)
 {
-	switch(wMsg) {
-	case DRV_LOAD:
-		return 1;
-	case DRV_FREE:
-		return 1;
-	case DRV_OPEN:
-		return 1;
-	case DRV_CLOSE:
-		return 1;
-	case DRV_ENABLE:
-		return 1;
-	case DRV_DISABLE:
-		return 1;
-	case DRV_QUERYCONFIGURE:
-		return 1;
-	case DRV_CONFIGURE:
-		MessageBox16(0, "Sample Midi Linux Driver !", 
-			     "MMLinux Driver", MB_OK);
-		return 1;
-	case DRV_INSTALL:
-		return DRVCNF_RESTART;
-	case DRV_REMOVE:
-		return DRVCNF_RESTART;
-	case MCI_OPEN_DRIVER:
-	case MCI_OPEN:
-		return MIDI_mciOpen(dwDevID, dwParam1, (LPMCI_OPEN_PARMS16)PTR_SEG_TO_LIN(dwParam2));
-	case MCI_CLOSE_DRIVER:
-	case MCI_CLOSE:
-		return MIDI_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
-	case MCI_PLAY:
-		return MIDI_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)PTR_SEG_TO_LIN(dwParam2));
-	case MCI_RECORD:
-		return MIDI_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)PTR_SEG_TO_LIN(dwParam2));
-	case MCI_STOP:
-		return MIDI_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
-	case MCI_SET:
-		return MIDI_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)PTR_SEG_TO_LIN(dwParam2));
-	case MCI_PAUSE:
-		return MIDI_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
-	case MCI_RESUME:
-		return MIDI_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
-	case MCI_STATUS:
-		return MIDI_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)PTR_SEG_TO_LIN(dwParam2));
-	case MCI_GETDEVCAPS:
-		return MIDI_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)PTR_SEG_TO_LIN(dwParam2));
-	case MCI_INFO:
-		return MIDI_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS16)PTR_SEG_TO_LIN(dwParam2));
-	default:
-		return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
-	}
+    switch(wMsg) {
+    case DRV_LOAD:
+	return 1;
+    case DRV_FREE:
+	return 1;
+    case DRV_OPEN:
+	return 1;
+    case DRV_CLOSE:
+	return 1;
+    case DRV_ENABLE:
+	return 1;
+    case DRV_DISABLE:
+	return 1;
+    case DRV_QUERYCONFIGURE:
+	return 1;
+    case DRV_CONFIGURE:
+	MessageBox16(0, "Sample Midi Linux Driver !", 
+		     "MMLinux Driver", MB_OK);
+	return 1;
+    case DRV_INSTALL:
+	return DRVCNF_RESTART;
+    case DRV_REMOVE:
+	return DRVCNF_RESTART;
+    case MCI_OPEN_DRIVER:
+    case MCI_OPEN:
+	return MIDI_mciOpen(dwDevID, dwParam1, (LPMCI_OPEN_PARMS16)PTR_SEG_TO_LIN(dwParam2));
+    case MCI_CLOSE_DRIVER:
+    case MCI_CLOSE:
+	return MIDI_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
+    case MCI_PLAY:
+	return MIDI_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)PTR_SEG_TO_LIN(dwParam2));
+    case MCI_RECORD:
+	return MIDI_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)PTR_SEG_TO_LIN(dwParam2));
+    case MCI_STOP:
+	return MIDI_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
+    case MCI_SET:
+	return MIDI_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)PTR_SEG_TO_LIN(dwParam2));
+    case MCI_PAUSE:
+	return MIDI_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
+    case MCI_RESUME:
+	return MIDI_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
+    case MCI_STATUS:
+	return MIDI_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)PTR_SEG_TO_LIN(dwParam2));
+    case MCI_GETDEVCAPS:
+	return MIDI_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)PTR_SEG_TO_LIN(dwParam2));
+    case MCI_INFO:
+	return MIDI_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS16)PTR_SEG_TO_LIN(dwParam2));
+    default:
+	return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
+    }
 }
 /*-----------------------------------------------------------------------*/
diff --git a/multimedia/midipatch.c b/multimedia/midipatch.c
new file mode 100644
index 0000000..a2e5d27
--- /dev/null
+++ b/multimedia/midipatch.c
@@ -0,0 +1,276 @@
+/* -*- tab-width: 8; c-basic-offset: 4 -*- */
+
+/*
+ * FM patches for wine MIDI driver
+ *
+ */
+
+/* 
+ * Eric POUECH : MIDI FM patches for GM instruments
+ */
+
+#define	NOT_DEFINED	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+
+unsigned char midiFMInstrumentPatches[128 * 16] = {
+/*   0 Acoustic Grand Piano             */ 0x21, 0x11, 0x4c, 0x00, 0xf1, 0xf2, 0x63, 0x72, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*   1 Bright Acoustic Piano            */ 0x01, 0x11, 0x4f, 0x00, 0xf1, 0xd2, 0x53, 0x74, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*   2 Electric Grand Piano             */ 0x01, 0x01, 0x4f, 0x04, 0xf1, 0xd2, 0x50, 0x7c, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*   3 Honky-Tonk Piano                 */ 0x81, 0x13, 0x9d, 0x00, 0xf2, 0xf2, 0x51, 0xf1, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*   4 Rhodes Piano                     */ 0x01, 0x01, 0x4f, 0x04, 0xf1, 0xd2, 0x50, 0x7c, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*   5 Chorused Piano                   */ 0x01, 0x11, 0x4d, 0x00, 0xf1, 0xd2, 0x60, 0x7b, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*   6 Harpsichord                      */ 0x32, 0x16, 0x87, 0x80, 0xa1, 0x7d, 0x10, 0x33, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*   7 Clavinet                         */ 0x13, 0x08, 0x80, 0x00, 0xfb, 0xe8, 0xff, 0xff, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*   8 Celesta                          */ 0x14, 0x04, 0x07, 0x00, 0x93, 0xb6, 0x73, 0x62, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*   9 Glockenspiel                     */ 0x07, 0x12, 0x4f, 0x00, 0xf2, 0xf2, 0x60, 0x72, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  10 Music Box                        */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  11 Vibraphone                       */ 0x44, 0x60, 0x53, 0x80, 0xf5, 0xfd, 0x33, 0x25, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  12 Marimba                          */ 0x05, 0x01, 0x4e, 0x00, 0xda, 0xf9, 0x25, 0x15, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  13 Xylophone                        */ 0x11, 0x31, 0x2d, 0x00, 0xc8, 0xf5, 0x2f, 0xf5, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  14 Tubular Bells                    */ 0x03, 0x17, 0x4f, 0x03, 0xf1, 0xf2, 0x53, 0x74, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  15 Dulcimer                         */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  16 Hammond Organ                    */ 0x72, 0x71, 0xcd, 0x80, 0x91, 0x91, 0x2a, 0x2a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  17 Percussive Organ                 */ 0x0c, 0x00, 0x00, 0x00, 0xf8, 0xd6, 0xb5, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  18 Rock Organ                       */ 0x72, 0x70, 0xce, 0x80, 0x9f, 0x94, 0x12, 0x11, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  19 Church Organ                     */ 0xa5, 0xb1, 0xd2, 0x80, 0x81, 0xf1, 0x03, 0x05, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  20 Reed Organ                       */ 0x3e, 0xb1, 0x29, 0x80, 0xfb, 0xa0, 0xf0, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  21 Accordion                        */ 0x24, 0x31, 0x4f, 0x00, 0xf2, 0x52, 0x0b, 0x0b, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  22 Harmonica                        */ 0x22, 0xf2, 0x8f, 0x40, 0x41, 0x61, 0x03, 0x05, 0x02, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  23 Tango Accordion                  */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  24 Acoustic Nylon Guitar            */ 0x01, 0x01, 0x11, 0x00, 0xf2, 0xf5, 0x1f, 0x88, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  25 Acoustic Steel Guitar            */ 0x01, 0xa1, 0x46, 0x03, 0xf1, 0x31, 0x83, 0x86, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  26 Electric Jazz Guitar             */ 0x03, 0x11, 0x5e, 0x00, 0x85, 0xd2, 0x51, 0x71, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  27 Electric Clean Guitar            */ 0x32, 0x16, 0x87, 0x80, 0xa1, 0x7d, 0x10, 0x33, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  28 Electric Muted Guitar            */ 0x13, 0x11, 0x96, 0x80, 0xff, 0xff, 0x21, 0x03, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  29 Overdriven Guitar                */ 0x07, 0x14, 0x8f, 0x80, 0x82, 0x82, 0x7d, 0x7d, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  30 Distortion Guitar                */ 0x05, 0x01, 0x8f, 0x80, 0xda, 0xf9, 0x15, 0x14, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  31 Guitar Harmonics                 */ 0xc3, 0x01, 0x05, 0x0d, 0x91, 0xf1, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  32 Acoustic Bass                    */ 0x21, 0x01, 0x2a, 0x00, 0xf2, 0xf5, 0x1f, 0x88, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  33 Electric Bass Fingered           */ 0x01, 0x21, 0x15, 0x80, 0x25, 0x65, 0x2f, 0x6c, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  34 Electric Bass Picked             */ 0x01, 0x01, 0x1d, 0x00, 0xf2, 0xf5, 0xef, 0x78, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  35 Fretless Bass                    */ 0x30, 0x21, 0x1e, 0x00, 0xf2, 0xf5, 0xef, 0x78, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  36 Slap Bass 1                      */ 0x20, 0x21, 0x40, 0x00, 0x7b, 0x75, 0x04, 0x72, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  37 Slap Bass 2                      */ 0x20, 0x21, 0x40, 0x00, 0x7b, 0xf5, 0x04, 0x72, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  38 Synth Bass 1                     */ 0x41, 0x91, 0x83, 0x00, 0x65, 0x32, 0x05, 0x74, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  39 Synth Bass 2                     */ 0x30, 0xb1, 0x88, 0x80, 0xd5, 0x61, 0x19, 0x1b, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  40 Violin                           */ 0x72, 0x62, 0x1c, 0x05, 0x51, 0x52, 0x03, 0x13, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  41 Viola                            */ 0x70, 0x71, 0xd0, 0x80, 0x52, 0x31, 0x11, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  42 Cello                            */ 0x70, 0x71, 0xc5, 0x80, 0x52, 0x31, 0x11, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  43 Contrabass                       */ 0x01, 0x00, 0x00, 0x00, 0x94, 0x83, 0xb6, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  44 Tremolo Strings                  */ 0x71, 0xa1, 0x8b, 0x40, 0x71, 0x42, 0x11, 0x15, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  45 Pizzicato Strings                */ 0xf2, 0xe1, 0x40, 0x80, 0xf5, 0xfd, 0xa8, 0xad, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  46 Orchestral Harp                  */ 0x21, 0x11, 0x11, 0x00, 0xa3, 0xc4, 0x43, 0x22, 0x02, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  47 Timpani                          */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  48 String Ensemble 1                */ 0xe1, 0x21, 0x4f, 0x00, 0xc1, 0x32, 0xd3, 0x74, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  49 String Ensemble 2                */ 0xe1, 0x21, 0x4f, 0x00, 0xb1, 0x12, 0xd3, 0x74, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  50 Synth Strings 1                  */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  51 Synth Strings 2                  */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  52 Choir Aahs                       */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  53 Voice oohs                       */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  54 Synth Voice                      */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  55 Orchestra Hit                    */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  56 Trumpet                          */ 0x31, 0xa1, 0x1c, 0x80, 0x41, 0x92, 0x0b, 0x3b, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  57 Trombone                         */ 0x21, 0xa1, 0x18, 0x80, 0x53, 0x52, 0x1d, 0x3b, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  58 Tuba                             */ 0x21, 0x21, 0x19, 0x80, 0x43, 0x85, 0x8c, 0x2f, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  59 Muted Trumpet                    */ 0x31, 0xa1, 0x1c, 0x80, 0x41, 0x92, 0x0b, 0x3b, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  60 French Horn                      */ 0x21, 0x21, 0x9f, 0x80, 0x53, 0xaa, 0x5a, 0x1a, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  61 Brass Section                    */ 0x21, 0x21, 0x16, 0x00, 0x71, 0x81, 0xae, 0x9e, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  62 Synth Brass 1                    */ 0x61, 0x60, 0x1c, 0x00, 0x71, 0x81, 0xae, 0x2e, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  63 Synth Brass 2                    */ 0x21, 0x21, 0x8e, 0x80, 0xbb, 0x90, 0x29, 0x0a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  64 Soprano Sax                      */ 0x01, 0x12, 0x4f, 0x00, 0x71, 0x52, 0x53, 0x7c, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  65 Alto Sax                         */ 0x01, 0x13, 0x4f, 0x00, 0x71, 0x62, 0x53, 0x84, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  66 Tenor Sax                        */ 0x01, 0x13, 0x8d, 0x00, 0x51, 0x52, 0x53, 0x7c, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  67 Baritone Sax                     */ 0x01, 0x12, 0x4f, 0x00, 0x71, 0x22, 0x53, 0x7c, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  68 Oboe                             */ 0x71, 0x62, 0xc5, 0x05, 0x6e, 0x8b, 0x17, 0x0e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  69 English Horn                     */ 0xe1, 0xe4, 0x23, 0x00, 0x71, 0x82, 0xae, 0x9e, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  70 Bassoon                          */ 0x30, 0xb1, 0xcd, 0x80, 0xd5, 0x61, 0x19, 0x1b, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  71 Clarinet                         */ 0x32, 0xa1, 0x1c, 0x80, 0x51, 0x82, 0x15, 0x45, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  72 Piccolo                          */ 0xe4, 0xe4, 0x0f, 0x00, 0x70, 0x60, 0x0f, 0x9f, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  73 Flute                            */ 0xe1, 0x61, 0x27, 0x80, 0x53, 0x53, 0x8a, 0x57, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  74 Recorder                         */ 0x61, 0x61, 0x27, 0x80, 0x74, 0x65, 0x8f, 0x2a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  75 Pan Flute                        */ 0xe0, 0xa1, 0xec, 0x00, 0x6e, 0x65, 0x8f, 0x2a, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  76 Bottle Blow                      */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  77 Shakuhashi                       */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  78 Whistle                          */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  79 Ocarina                          */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  80 Synth lead 1 - Sq wave lead      */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  81 Synth lead 2 - Sawtooth Wave     */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  82 Synth lead 3 - Caliope lead      */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  83 Synth lead 4 - Chiff lead        */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  84 Synth lead 5 - Charang           */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  85 Synth lead 6 - Solo Synth Voice  */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  86 Synth lead 7 - Bright Saw Wave   */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  87 Synth lead 8 - Brass and Lead    */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  88 Synth pad 1 - Fantasia Pad       */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  89 Synth pad 2 - Warm Pad           */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  90 Synth pad 3 - Poly Synth Pad     */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  91 Synth pad 4 - Space Voice Pad    */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  92 Synth pad 5 - Bowed Glass Pad    */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  93 Synth pad 6 - Metal Pad          */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  94 Synth pad 7 - Halo Pad           */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  95 Synth pad 8 - Sweep Pad          */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  96 Synth SFX 1 - Ice Rain           */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  97 Synth SFX 2 - Soundtrack         */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  98 Synth SFX 3 - Crystal            */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*  99 Synth SFX 4 - Athmosphere        */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 100 Synth SFX 5 - Brightness         */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 101 Synth SFX 6 - Goblin             */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 102 Synth SFX 7 - Echo drops         */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 103 Synth SFX 8 - Star Theme         */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 104 Sitar                            */ 0x01, 0x08, 0x40, 0x00, 0xf2, 0xf2, 0x54, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 105 Banjo                            */ 0x31, 0x16, 0x87, 0x80, 0xa1, 0x7d, 0x11, 0x43, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 106 Shamisen                         */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 107 Koto                             */ 0x0e, 0x02, 0x40, 0x00, 0x09, 0xf7, 0x53, 0x94, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 108 Kalimba                          */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 109 Bagpipe                          */ 0x31, 0x22, 0x43, 0x05, 0x6e, 0x8b, 0x17, 0x0c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 110 Fiddle                           */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 111 Shanai                           */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 112 Tinkle Bell                      */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 113 Agogo                            */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 114 Steel Drums                      */ 0x00, 0x00, 0x0b, 0x00, 0xa8, 0xd6, 0x4c, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 115 Woodblock                        */ 0x02, 0x11, 0x4f, 0x00, 0x71, 0x52, 0x53, 0x7c, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 116 Taiko Drum                       */ 0x12, 0x02, 0x0b, 0x00, 0x95, 0xd4, 0x4c, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 117 Melodic Tom                      */ 0x01, 0x02, 0x00, 0x00, 0xfa, 0xda, 0xbf, 0xbf, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 118 Synth Drum                       */ 0x06, 0x00, 0x00, 0x00, 0xf0, 0xf6, 0xf0, 0xb4, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 119 Reverse Cymbal                   */ 0x64, 0x03, 0x00, 0x40, 0xb2, 0x97, 0x82, 0xd4, 0x02, 0x01, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 120 Guitar Fret Noise                */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 121 Breath Noise                     */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 122 Seashore                         */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 123 Bird Tweet                       */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 124 Telephone Ring                   */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 125 Helicopter                       */ 0xf0, 0xe2, 0x00, 0xc0, 0x1e, 0x11, 0x11, 0x11, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 126 Applause                         */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/* 127 Gunshot                          */ 0x0c, 0x50, 0x00, 0x21, 0xf8, 0x09, 0xb6, 0x04, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 
+};
+
+unsigned char midiFMDrumsPatches[16 * 128] = {
+/*     1 Not defined					*/ NOT_DEFINED
+/*     2 Not defined					*/ NOT_DEFINED
+/*     3 Not defined					*/ NOT_DEFINED
+/*     4 Not defined					*/ NOT_DEFINED
+/*     5 Not defined					*/ NOT_DEFINED
+/*     6 Not defined					*/ NOT_DEFINED
+/*     7 Not defined					*/ NOT_DEFINED
+/*     8 Not defined					*/ NOT_DEFINED
+/*     9 Not defined					*/ NOT_DEFINED
+/*    10 Not defined					*/ NOT_DEFINED
+/*    11 Not defined					*/ NOT_DEFINED
+/*    12 Not defined					*/ NOT_DEFINED
+/*    13 Not defined					*/ NOT_DEFINED
+/*    14 Not defined					*/ NOT_DEFINED
+/*    15 Not defined					*/ NOT_DEFINED
+/*    16 Not defined					*/ NOT_DEFINED
+/*    17 Not defined					*/ NOT_DEFINED
+/*    18 Not defined					*/ NOT_DEFINED
+/*    19 Not defined					*/ NOT_DEFINED
+/*    20 Not defined					*/ NOT_DEFINED
+/*    21 Not defined					*/ NOT_DEFINED
+/*    22 Not defined					*/ NOT_DEFINED
+/*    23 Not defined					*/ NOT_DEFINED
+/*    24 Not defined					*/ NOT_DEFINED
+/*    25 Not defined					*/ NOT_DEFINED
+/*    26 Not defined					*/ NOT_DEFINED
+/*    27 Not defined					*/ NOT_DEFINED
+/*    28 Not defined					*/ NOT_DEFINED
+/*    29 Not defined					*/ NOT_DEFINED
+/*    30 Not defined					*/ NOT_DEFINED
+/*    31 Not defined					*/ NOT_DEFINED
+/*    32 Not defined					*/ NOT_DEFINED
+/*    33 Not defined					*/ NOT_DEFINED
+/*    34 Not defined					*/ NOT_DEFINED
+/*    35 Acoustic Bass Drum      */ 0x00, 0x00, 0x0d, 0x00, 0xe8, 0xa5, 0xef, 0xff, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*    36 Bass Drum 1             */ 0x00, 0x00, 0x0b, 0x00, 0xa8, 0xd6, 0x4c, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+/*    37 Side Stick              */ NOT_DEFINED
+/*    38 Acoustic Snare          */ 0x2e, 0x02, 0x0a, 0x1b, 0xff, 0xf6, 0x0f, 0x4a, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, /* snare    */
+/*    39 Hand Clap               */ NOT_DEFINED
+/*    40 Electric Snare          */ 0x0c, 0xd0, 0x00, 0x00, 0xc7, 0x70, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* rksnare  */
+/*    41 Low Floor Tom           */ NOT_DEFINED
+/*    42 Closed Hi-Hat           */ 0x64, 0x03, 0x02, 0x40, 0xb2, 0x97, 0xa2, 0xd4, 0x02, 0x01, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, /* cymbal   */
+/*    43 High Floor Tom          */ NOT_DEFINED
+/*    44 Pedal Hi-Hat            */ NOT_DEFINED
+/*    45 Low Tom                 */ 0x01, 0x02, 0x00, 0x00, 0xfa, 0xda, 0xbf, 0xbf, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, /* tom      */
+/*    46 Open Hi-Hat             */ NOT_DEFINED
+/*    47 Low-Mid Tom             */ 0x02, 0x30, 0x00, 0x00, 0xc8, 0xe0, 0x97, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* tom2     */
+/*    48 Hi-Mid Tom              */ NOT_DEFINED
+/*    49 Crash Cymbal 1          */ NOT_DEFINED
+/*    50 High Tom                */ NOT_DEFINED
+/*    51 Ride Cymbal 1           */ 0x64, 0x03, 0x00, 0x40, 0xb2, 0x97, 0x82, 0xd4, 0x02, 0x01, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, /* bcymbal  */ 
+/*    52 Chinese Cymbal          */ NOT_DEFINED
+/*    53 Ride Bell               */ NOT_DEFINED
+/*    54 Tambourine              */ NOT_DEFINED
+/*    55 Splash Cymbal           */ NOT_DEFINED
+/*    56 Cowbell                 */ NOT_DEFINED
+/*    57 Crash Cymbal 2          */ NOT_DEFINED
+/*    58 Vibrasl						*/ NOT_DEFINED
+/*    59 Ride Cymbal					*/ NOT_DEFINED
+/*    60 Hi Bon						*/ NOT_DEFINED
+/*    61 Low Bon						*/ NOT_DEFINED
+/*    62 Mute Hi Con					*/ NOT_DEFINED
+/*    63 Open Hi Con					*/ NOT_DEFINED
+/*    64 Low Con						*/ NOT_DEFINED
+/*    65 High Timba					*/ NOT_DEFINED
+/*    66 Low Timba					*/ NOT_DEFINED
+/*    67 High Ago						*/ NOT_DEFINED
+/*    68 Low Ago						*/ NOT_DEFINED
+/*    69 Caba							*/ NOT_DEFINED
+/*    70 Marac							*/ NOT_DEFINED
+/*    71 Short Whist					*/ NOT_DEFINED
+/*    72 Long Whist					*/ NOT_DEFINED
+/*    73 Short Gui					*/ NOT_DEFINED
+/*    74 Long Gui						*/ NOT_DEFINED
+/*    75 Clav							*/ 0x13, 0x08, 0x80, 0x00, 0xfb, 0xe8, 0xff, 0xff, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, /* claves   */
+/*    76 Hi Wood Blo					*/ NOT_DEFINED
+/*    77 Low Wood Blo				*/ NOT_DEFINED
+/*    78 Mute Cui						*/ NOT_DEFINED
+/*    79 Open Cui						*/ NOT_DEFINED
+/*    80 Mute Triang					*/ NOT_DEFINED
+/*    81 Open Triang					*/ 0x26, 0x1e, 0x03, 0x00, 0xe0, 0xff, 0xf0, 0x31, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, /* triangle */
+/*    82 Not defined					*/ NOT_DEFINED
+/*    83 Not defined					*/ NOT_DEFINED
+/*    84 Not defined					*/ NOT_DEFINED
+/*    85 Not defined					*/ NOT_DEFINED
+/*    86 Not defined					*/ NOT_DEFINED
+/*    87 Not defined					*/ NOT_DEFINED
+/*    88 Not defined					*/ NOT_DEFINED
+/*    89 Not defined					*/ NOT_DEFINED
+/*    90 Not defined					*/ NOT_DEFINED
+/*    91 Not defined					*/ NOT_DEFINED
+/*    92 Not defined					*/ NOT_DEFINED
+/*    93 Not defined					*/ NOT_DEFINED
+/*    94 Not defined					*/ NOT_DEFINED
+/*    95 Not defined					*/ NOT_DEFINED
+/*    96 Not defined					*/ NOT_DEFINED
+/*    97 Not defined					*/ NOT_DEFINED
+/*    98 Not defined					*/ NOT_DEFINED
+/*    99 Not defined					*/ NOT_DEFINED
+/*   100 Not defined					*/ NOT_DEFINED
+/*   101 Not defined					*/ NOT_DEFINED
+/*   102 Not defined					*/ NOT_DEFINED
+/*   103 Not defined					*/ NOT_DEFINED
+/*   104 Not defined					*/ NOT_DEFINED
+/*   105 Not defined					*/ NOT_DEFINED
+/*   106 Not defined					*/ NOT_DEFINED
+/*   107 Not defined					*/ NOT_DEFINED
+/*   108 Not defined					*/ NOT_DEFINED
+/*   109 Not defined					*/ NOT_DEFINED
+/*   110 Not defined					*/ NOT_DEFINED
+/*   111 Not defined					*/ NOT_DEFINED
+/*   112 Not defined					*/ NOT_DEFINED
+/*   113 Not defined					*/ NOT_DEFINED
+/*   114 Not defined					*/ NOT_DEFINED
+/*   115 Not defined					*/ NOT_DEFINED
+/*   116 Not defined					*/ NOT_DEFINED
+/*   117 Not defined					*/ NOT_DEFINED
+/*   118 Not defined					*/ NOT_DEFINED
+/*   119 Not defined					*/ NOT_DEFINED
+/*   120 Not defined					*/ NOT_DEFINED
+/*   121 Not defined					*/ NOT_DEFINED
+/*   122 Not defined					*/ NOT_DEFINED
+/*   123 Not defined					*/ NOT_DEFINED
+/*   124 Not defined					*/ NOT_DEFINED
+/*   125 Not defined					*/ NOT_DEFINED
+/*   126 Not defined					*/ NOT_DEFINED
+/*   127 Not defined					*/ NOT_DEFINED
+/*   128 Not defined					*/ NOT_DEFINED
+};
+ 
+
diff --git a/multimedia/mmio.c b/multimedia/mmio.c
index 8443ca1..44866de 100644
--- a/multimedia/mmio.c
+++ b/multimedia/mmio.c
@@ -599,9 +599,24 @@
 }
 
 /**************************************************************************
-* 				mmioSetInfo    		[MMSYSTEM.1216]
-*/
-UINT16 WINAPI mmioSetInfo(HMMIO16 hmmio, const MMIOINFO16 * lpmmioinfo, UINT16 uFlags)
+ * 				mmioSetInfo    		[MMSYSTEM.1216]
+ */
+UINT16 WINAPI mmioSetInfo16(HMMIO16 hmmio, const MMIOINFO16 * lpmmioinfo, UINT16 uFlags)
+{
+	LPMMIOINFO16	lpmminfo;
+	TRACE(mmio, "mmioSetInfo\n");
+	lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
+	if (lpmminfo == NULL) return 0;
+	lpmminfo->pchNext	= lpmmioinfo->pchNext;
+	lpmminfo->pchEndRead	= lpmmioinfo->pchEndRead;
+	GlobalUnlock16(hmmio);
+	return 0;
+}
+
+/**************************************************************************
+ * 				mmioSetInfo    		[WINMM.130]
+ */
+UINT32 WINAPI mmioSetInfo32(HMMIO32 hmmio, const MMIOINFO32 * lpmmioinfo, UINT32 uFlags)
 {
 	LPMMIOINFO16	lpmminfo;
 	TRACE(mmio, "mmioSetInfo\n");
diff --git a/multimedia/mmsystem.c b/multimedia/mmsystem.c
index deffa1a..3e2f7b3 100644
--- a/multimedia/mmsystem.c
+++ b/multimedia/mmsystem.c
@@ -1,3 +1,5 @@
+/* -*- tab-width: 8; c-basic-offset: 4 -*- */
+
 /*
  * MMSYTEM functions
  *
@@ -65,8 +67,9 @@
 /**************************************************************************
  * 				MMSYSTEM_DevIDToIndex	[internal]
  */
-int MMSYSTEM_DevIDToIndex(UINT16 wDevID) {
-	return wDevID - MMSYSTEM_MAGIC;
+int MMSYSTEM_DevIDToIndex(UINT16 wDevID) 
+{
+    return wDevID - MMSYSTEM_MAGIC;
 }
 
 /**************************************************************************
@@ -74,21 +77,23 @@
  */
 UINT16 MMSYSTEM_FirstDevID(void)
 {
-	return MMSYSTEM_MAGIC;
+    return MMSYSTEM_MAGIC;
 }
 
 /**************************************************************************
  * 				MMSYSTEM_NextDevId	[internal]
  */
-UINT16 MMSYSTEM_NextDevID(UINT16 wDevID) {
-	return wDevID + 1;
+UINT16 MMSYSTEM_NextDevID(UINT16 wDevID) 
+{
+    return wDevID + 1;
 }
 
 /**************************************************************************
  * 				MMSYSTEM_DevIdValid	[internal]
  */
-BOOL32 MMSYSTEM_DevIDValid(UINT16 wDevID) {
-	return wDevID >= 0x0F00 && wDevID < (0x0F00 + MAXMCIDRIVERS);
+BOOL32 MMSYSTEM_DevIDValid(UINT16 wDevID) 
+{
+    return wDevID >= 0x0F00 && wDevID < (0x0F00 + MAXMCIDRIVERS);
 }
 
 /**************************************************************************
@@ -97,25 +102,25 @@
 int WINAPI MMSYSTEM_WEP(HINSTANCE16 hInstance, WORD wDataSeg,
                         WORD cbHeapSize, LPSTR lpCmdLine)
 {
-	FIXME(mmsys, "STUB: Unloading MMSystem DLL ... hInst=%04X \n",
-	      hInstance);
-	return(TRUE);
+    FIXME(mmsys, "STUB: Unloading MMSystem DLL ... hInst=%04X \n",
+	  hInstance);
+    return(TRUE);
 }
 
-void
-MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16,LPMMTIME32 mmt32) {
-	mmt16->wType = mmt32->wType;
-	/* layout of rest is the same for 32/16 */
-	memcpy(&(mmt32->u),&(mmt16->u),sizeof(mmt16->u));
+void MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16,LPMMTIME32 mmt32) 
+{
+    mmt16->wType = mmt32->wType;
+    /* layout of rest is the same for 32/16 */
+    memcpy(&(mmt32->u),&(mmt16->u),sizeof(mmt16->u));
 }
 
-void
-MMSYSTEM_MMTIME16to32(LPMMTIME32 mmt32,LPMMTIME16 mmt16) {
-	mmt32->wType = mmt16->wType;
-	/* layout of rest is the same for 32/16,
-	 * Note: mmt16->u is 2 bytes smaller than mmt32->u
-	 */
-	memcpy(&(mmt16->u),&(mmt32->u),sizeof(mmt16->u));
+void MMSYSTEM_MMTIME16to32(LPMMTIME32 mmt32,LPMMTIME16 mmt16) 
+{
+    mmt32->wType = mmt16->wType;
+    /* layout of rest is the same for 32/16,
+     * Note: mmt16->u is 2 bytes smaller than mmt32->u
+     */
+    memcpy(&(mmt16->u),&(mmt32->u),sizeof(mmt16->u));
 }
 
 HANDLE32	PlaySound_hThread = 0;
@@ -444,7 +449,7 @@
  */
 UINT32 WINAPI mmsystemGetVersion32()
 {
-	return mmsystemGetVersion16();
+    return mmsystemGetVersion16();
 }
 
 /**************************************************************************
@@ -453,57 +458,58 @@
  */
 UINT16 WINAPI mmsystemGetVersion16()
 {
-	TRACE(mmsys, "3.10 (Win95?)\n");
-	return 0x030a;
+    TRACE(mmsys, "3.10 (Win95?)\n");
+    return 0x030a;
 }
 
 /**************************************************************************
-* 				DriverProc	[MMSYSTEM.6]
-*/
+ * 				DriverProc	[MMSYSTEM.6]
+ */
 LRESULT WINAPI DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
                           DWORD dwParam1, DWORD dwParam2)
 {
-	return DrvDefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
+    return DrvDefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
 }
 
 /**************************************************************************
-* 				DriverCallback	[MMSYSTEM.31]
-*/
+ * 				DriverCallback	[MMSYSTEM.31]
+ */
 BOOL16 WINAPI DriverCallback(DWORD dwCallBack, UINT16 uFlags, HANDLE16 hDev, 
                              WORD wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
 {
-	LPWAVEOPENDESC	lpDesc;
-
-	TRACE(mmsys, "(%08lX, %04X, %04X, %04X, %08lX, %08lX, %08lX); !\n",
-		dwCallBack, uFlags, hDev, wMsg, dwUser, dwParam1, dwParam2);
-	switch(uFlags & DCB_TYPEMASK) {
-		case DCB_NULL:
-			TRACE(mmsys, "CALLBACK_NULL !\n");
-			break;
-		case DCB_WINDOW:
-			TRACE(mmsys, "CALLBACK_WINDOW = %04lX handle = %04X!\n",dwCallBack,hDev);
-			if (!IsWindow32(dwCallBack)) return FALSE;
-			lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hDev);
-			if (lpDesc == NULL) return FALSE;
-
-			PostMessage16((HWND16)dwCallBack, wMsg, hDev, dwParam1);
-			break;
-		case DCB_TASK:
-			TRACE(mmsys, "CALLBACK_TASK !\n");
-			return FALSE;
-		case DCB_FUNCTION:
-			TRACE(mmsys, "CALLBACK_FUNCTION !\n");
-			Callbacks->CallDriverCallback( (FARPROC16)dwCallBack,
-                                                       hDev, wMsg, dwUser,
-                                                       dwParam1, dwParam2 );
-			break;
-		case DCB_FUNC32:
-			TRACE(mmsys, "CALLBACK_FUNCTION !\n");
-			((LPDRVCALLBACK32)dwCallBack)( hDev, wMsg, dwUser,
-                                                       dwParam1, dwParam2 );
-			break;
-		}
-	return TRUE;
+    TRACE(mmsys, "(%08lX, %04X, %04X, %04X, %08lX, %08lX, %08lX); !\n",
+	  dwCallBack, uFlags, hDev, wMsg, dwUser, dwParam1, dwParam2);
+    switch(uFlags & DCB_TYPEMASK) {
+    case DCB_NULL:
+	TRACE(mmsys, "CALLBACK_NULL !\n");
+	break;
+    case DCB_WINDOW:
+	TRACE(mmsys, "CALLBACK_WINDOW = %04lX handle = %04X!\n",
+	      dwCallBack,hDev);
+	if (!IsWindow32(dwCallBack) || USER_HEAP_LIN_ADDR(hDev) == NULL)
+	    return FALSE;
+	
+	PostMessage16((HWND16)dwCallBack, wMsg, hDev, dwParam1);
+	break;
+    case DCB_TASK:
+	TRACE(mmsys, "CALLBACK_TASK !\n");
+	return FALSE;
+    case DCB_FUNCTION:
+	TRACE(mmsys, "CALLBACK_FUNCTION !\n");
+	Callbacks->CallDriverCallback( (FARPROC16)dwCallBack,
+				       hDev, wMsg, dwUser,
+				       dwParam1, dwParam2 );
+	break;
+    case DCB_FUNC32:
+	TRACE(mmsys, "CALLBACK_FUNCTION !\n");
+	((LPDRVCALLBACK32)dwCallBack)( hDev, wMsg, dwUser,
+				       dwParam1, dwParam2 );
+	break;
+    default:
+	WARN(mmsys, "Unknown callback type\n");
+	break;
+    }
+    return TRUE;
 }
 
 /**************************************************************************
@@ -514,17 +520,17 @@
  * FIXME: also fix dwInstance passing to mixMessage 
  */
 static UINT32 _get_mixerID_from_handle(HMIXEROBJ32 hmix,DWORD dwFlags) {
-	/* FIXME: Check dwFlags for MIXER_OBJECTF_xxxx entries and modify hmix 
-	 * accordingly. For now we always use mixerdevice 0. 
-	 */
-	return 0;
+    /* FIXME: Check dwFlags for MIXER_OBJECTF_xxxx entries and modify hmix 
+     * accordingly. For now we always use mixerdevice 0. 
+     */
+    return 0;
 }
 /**************************************************************************
  * 				mixerGetNumDevs		[WINMM.108]
  */
 UINT32 WINAPI mixerGetNumDevs32() 
 {
-	return mixerGetNumDevs16();
+    return mixerGetNumDevs16();
 }
 
 /**************************************************************************
@@ -532,11 +538,11 @@
  */
 UINT16 WINAPI mixerGetNumDevs16() 
 {
-	UINT16	count;
-
-	count = mixMessage(0,MXDM_GETNUMDEVS,0L,0L,0L);
-	TRACE(mmaux,"mixerGetNumDevs returns %d\n",count);
-	return count;
+    UINT16	count;
+    
+    count = mixMessage(0,MXDM_GETNUMDEVS,0L,0L,0L);
+    TRACE(mmaux,"mixerGetNumDevs returns %d\n",count);
+    return count;
 }
 
 /**************************************************************************
@@ -544,32 +550,32 @@
  */
 UINT32 WINAPI mixerGetDevCaps32W(UINT32 devid,LPMIXERCAPS32W mixcaps,UINT32 size) 
 {
-	MIXERCAPS16	mic16;
-	UINT32	ret = mixerGetDevCaps16(devid,&mic16,sizeof(mic16));
-
-	mixcaps->wMid = mic16.wMid;
-	mixcaps->wPid = mic16.wPid;
-	mixcaps->vDriverVersion = mic16.vDriverVersion;
-	lstrcpyAtoW(mixcaps->szPname,mic16.szPname);
-	mixcaps->fdwSupport = mic16.fdwSupport;
-	mixcaps->cDestinations = mic16.cDestinations;
-	return ret;
+    MIXERCAPS16	mic16;
+    UINT32	ret = mixerGetDevCaps16(devid,&mic16,sizeof(mic16));
+    
+    mixcaps->wMid = mic16.wMid;
+    mixcaps->wPid = mic16.wPid;
+    mixcaps->vDriverVersion = mic16.vDriverVersion;
+    lstrcpyAtoW(mixcaps->szPname,mic16.szPname);
+    mixcaps->fdwSupport = mic16.fdwSupport;
+    mixcaps->cDestinations = mic16.cDestinations;
+    return ret;
 }
 /**************************************************************************
  * 				mixerGetDevCaps		[WINMM.101]
  */
 UINT32 WINAPI mixerGetDevCaps32A(UINT32 devid,LPMIXERCAPS32A mixcaps,UINT32 size) 
 {
-	MIXERCAPS16	mic16;
-	UINT32	ret = mixerGetDevCaps16(devid,&mic16,sizeof(mic16));
-
-	mixcaps->wMid = mic16.wMid;
-	mixcaps->wPid = mic16.wPid;
-	mixcaps->vDriverVersion = mic16.vDriverVersion;
-	strcpy(mixcaps->szPname,mic16.szPname);
-	mixcaps->fdwSupport = mic16.fdwSupport;
-	mixcaps->cDestinations = mic16.cDestinations;
-	return ret;
+    MIXERCAPS16	mic16;
+    UINT32	ret = mixerGetDevCaps16(devid,&mic16,sizeof(mic16));
+    
+    mixcaps->wMid = mic16.wMid;
+    mixcaps->wPid = mic16.wPid;
+    mixcaps->vDriverVersion = mic16.vDriverVersion;
+    strcpy(mixcaps->szPname,mic16.szPname);
+    mixcaps->fdwSupport = mic16.fdwSupport;
+    mixcaps->cDestinations = mic16.cDestinations;
+    return ret;
 }
 
 /**************************************************************************
@@ -577,261 +583,278 @@
  */
 UINT16 WINAPI mixerGetDevCaps16(UINT16 devid,LPMIXERCAPS16 mixcaps,UINT16 size) 
 {
-	FIXME(mmsys,"should this be a fixme?\n");
-	return mixMessage(devid,MXDM_GETDEVCAPS,0L,(DWORD)mixcaps,(DWORD)size);
+    FIXME(mmsys,"should this be a fixme?\n");
+    return mixMessage(devid,MXDM_GETDEVCAPS,0L,(DWORD)mixcaps,(DWORD)size);
 }
 
 /**************************************************************************
  * 				mixerOpen		[WINMM.110]
  */
 UINT32 WINAPI mixerOpen32(LPHMIXER32 lphmix,UINT32 uDeviceID,DWORD dwCallback,
-DWORD dwInstance,DWORD fdwOpen) 
+			  DWORD dwInstance,DWORD fdwOpen) 
 {
-	HMIXER16	hmix16;
-	UINT32		ret;
-
-	FIXME(mmsys,"(%p,%d,%08lx,%08lx,%08lx): semi stub?\n",
-	      lphmix,uDeviceID,dwCallback,dwInstance,fdwOpen);
-	ret = mixerOpen16(&hmix16,uDeviceID,dwCallback,dwInstance,fdwOpen);
-	if (lphmix) *lphmix = hmix16;
-	return ret;
+    HMIXER16	hmix16;
+    UINT32	ret;
+    
+    FIXME(mmsys,"(%p,%d,%08lx,%08lx,%08lx): semi stub?\n",
+	  lphmix,uDeviceID,dwCallback,dwInstance,fdwOpen);
+    ret = mixerOpen16(&hmix16,uDeviceID,dwCallback,dwInstance,fdwOpen);
+    if (lphmix) *lphmix = hmix16;
+    return ret;
 }
 
 /**************************************************************************
  * 				mixerOpen
  */
 UINT16 WINAPI mixerOpen16(LPHMIXER16 lphmix,UINT16 uDeviceID,DWORD dwCallback,
-DWORD dwInstance,DWORD fdwOpen) 
+			  DWORD dwInstance,DWORD fdwOpen) 
 {
-	HMIXER16	hmix;
-	LPMIXEROPENDESC	lpmod;
-	BOOL32		mapperflag = (uDeviceID==0);
-	DWORD		dwRet;
-
-	TRACE(mmsys,"(%p,%d,%08lx,%08lx,%08lx)\n",
-	      lphmix,uDeviceID,dwCallback,dwInstance,fdwOpen);
-	hmix = USER_HEAP_ALLOC(sizeof(MIXEROPENDESC));
-	if (lphmix) *lphmix = hmix;
-	lpmod = (LPMIXEROPENDESC)USER_HEAP_LIN_ADDR(hmix);
-	lpmod->hmx = hmix;
-	lpmod->dwCallback = dwCallback;
-	lpmod->dwInstance = dwInstance;
-	if (uDeviceID >= MAXMIXERDRIVERS)
-		uDeviceID = 0;
-	while(uDeviceID < MAXMIXERDRIVERS) {
-		dwRet=mixMessage(uDeviceID,MXDM_OPEN,dwInstance,(DWORD)lpmod,fdwOpen);
-		if (dwRet == MMSYSERR_NOERROR) break;
-		if (!mapperflag) break;
-		uDeviceID++;
-	}
-	lpmod->uDeviceID = uDeviceID;
-	return dwRet;
+    HMIXER16		hmix;
+    LPMIXEROPENDESC	lpmod;
+    BOOL32		mapperflag = (uDeviceID==0);
+    DWORD		dwRet;
+    
+    TRACE(mmsys,"(%p,%d,%08lx,%08lx,%08lx)\n",
+	  lphmix,uDeviceID,dwCallback,dwInstance,fdwOpen);
+    hmix = USER_HEAP_ALLOC(sizeof(MIXEROPENDESC));
+    if (lphmix) *lphmix = hmix;
+    lpmod = (LPMIXEROPENDESC)USER_HEAP_LIN_ADDR(hmix);
+    lpmod->hmx = hmix;
+    lpmod->dwCallback = dwCallback;
+    lpmod->dwInstance = dwInstance;
+    if (uDeviceID >= MAXMIXERDRIVERS)
+	uDeviceID = 0;
+    while(uDeviceID < MAXMIXERDRIVERS) {
+	dwRet=mixMessage(uDeviceID,MXDM_OPEN,dwInstance,(DWORD)lpmod,fdwOpen);
+	if (dwRet == MMSYSERR_NOERROR) break;
+	if (!mapperflag) break;
+	uDeviceID++;
+    }
+    lpmod->uDeviceID = uDeviceID;
+    return dwRet;
 }
 
 /**************************************************************************
  * 				mixerClose		[WINMM.98]
  */
-UINT32 WINAPI mixerClose32(HMIXER32 hmix) {
-	return mixerClose16(hmix);
+UINT32 WINAPI mixerClose32(HMIXER32 hmix) 
+{
+    return mixerClose16(hmix);
 }
 
 /**************************************************************************
  * 				mixerClose
  */
-UINT16 WINAPI mixerClose16(HMIXER16 hmix) {
-	LPMIXEROPENDESC	lpmod;
-
-	FIXME(mmsys,"(%04x): semi-stub?\n",hmix);
-	lpmod = (LPMIXEROPENDESC)USER_HEAP_LIN_ADDR(hmix);
-	return mixMessage(lpmod->uDeviceID,MXDM_CLOSE,lpmod->dwInstance,0L,0L);
+UINT16 WINAPI mixerClose16(HMIXER16 hmix) 
+{
+    LPMIXEROPENDESC	lpmod;
+    
+    FIXME(mmsys,"(%04x): semi-stub?\n",hmix);
+    lpmod = (LPMIXEROPENDESC)USER_HEAP_LIN_ADDR(hmix);
+    return mixMessage(lpmod->uDeviceID,MXDM_CLOSE,lpmod->dwInstance,0L,0L);
 }
 
 /**************************************************************************
  * 				mixerGetID		[WINMM.103]
  */
-UINT32 WINAPI mixerGetID32(HMIXEROBJ32 hmix,LPUINT32 lpid,DWORD fdwID) {
-	UINT16	xid;
+UINT32 WINAPI mixerGetID32(HMIXEROBJ32 hmix,LPUINT32 lpid,DWORD fdwID) 
+{
+    UINT16	xid;    
+    UINT32	ret = mixerGetID16(hmix,&xid,fdwID);
 
-	UINT32	ret = mixerGetID16(hmix,&xid,fdwID);
-	if (*lpid) *lpid = xid;
-	return ret;
+    if (*lpid) *lpid = xid;
+    return ret;
 }
 
 /**************************************************************************
  * 				mixerGetID
  */
-UINT16 WINAPI mixerGetID16(HMIXEROBJ16 hmix,LPUINT16 lpid,DWORD fdwID) {
-	FIXME(mmsys,"(%04x): semi-stub\n",hmix);
-	return _get_mixerID_from_handle(hmix,fdwID);
+UINT16 WINAPI mixerGetID16(HMIXEROBJ16 hmix,LPUINT16 lpid,DWORD fdwID) 
+{
+    FIXME(mmsys,"(%04x): semi-stub\n",hmix);
+    return _get_mixerID_from_handle(hmix,fdwID);
 }
 
 /**************************************************************************
  * 				mixerGetControlDetailsA	[WINMM.99]
  */
-UINT32 WINAPI mixerGetControlDetails32A(HMIXEROBJ32 hmix,LPMIXERCONTROLDETAILS32 lpmcd,DWORD fdwDetails) {
-	FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpmcd,fdwDetails);
-	return MMSYSERR_NOTENABLED;
+UINT32 WINAPI mixerGetControlDetails32A(HMIXEROBJ32 hmix,LPMIXERCONTROLDETAILS32 lpmcd,DWORD fdwDetails) 
+{
+    FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpmcd,fdwDetails);
+    return MMSYSERR_NOTENABLED;
 }
 
 /**************************************************************************
  * 				mixerGetControlDetailsW	[WINMM.100]
  */
-UINT32 WINAPI mixerGetControlDetails32W(HMIXEROBJ32 hmix,LPMIXERCONTROLDETAILS32 lpmcd,DWORD fdwDetails) {
-	FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",	hmix,lpmcd,fdwDetails);
-	return MMSYSERR_NOTENABLED;
+UINT32 WINAPI mixerGetControlDetails32W(HMIXEROBJ32 hmix,LPMIXERCONTROLDETAILS32 lpmcd,DWORD fdwDetails) 
+{
+    FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",	hmix,lpmcd,fdwDetails);
+    return MMSYSERR_NOTENABLED;
 }
 
 /**************************************************************************
  * 				mixerGetControlDetails	[MMSYSTEM.808]
  */
-UINT16 WINAPI mixerGetControlDetails16(HMIXEROBJ16 hmix,LPMIXERCONTROLDETAILS16 lpmcd,DWORD fdwDetails) {
-	FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpmcd,fdwDetails);
-	return MMSYSERR_NOTENABLED;
+UINT16 WINAPI mixerGetControlDetails16(HMIXEROBJ16 hmix,LPMIXERCONTROLDETAILS16 lpmcd,DWORD fdwDetails) 
+{
+    FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpmcd,fdwDetails);
+    return MMSYSERR_NOTENABLED;
 }
 
 /**************************************************************************
  * 				mixerGetLineControlsA	[WINMM.104]
  */
-UINT32 WINAPI mixerGetLineControls32A(HMIXEROBJ32 hmix,LPMIXERLINECONTROLS32A lpmlc,DWORD fdwControls) {
-	FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpmlc,fdwControls);
-	return MMSYSERR_NOTENABLED;
+UINT32 WINAPI mixerGetLineControls32A(HMIXEROBJ32 hmix,LPMIXERLINECONTROLS32A lpmlc,DWORD fdwControls) 
+{
+    FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpmlc,fdwControls);
+    return MMSYSERR_NOTENABLED;
 }
 
 /**************************************************************************
  * 				mixerGetLineControlsW	[WINMM.105]
  */
-UINT32 WINAPI mixerGetLineControls32W(HMIXEROBJ32 hmix,LPMIXERLINECONTROLS32W lpmlc,DWORD fdwControls) {
-	FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpmlc,fdwControls);
-	return MMSYSERR_NOTENABLED;
+UINT32 WINAPI mixerGetLineControls32W(HMIXEROBJ32 hmix,LPMIXERLINECONTROLS32W lpmlc,DWORD fdwControls) 
+{
+    FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpmlc,fdwControls);
+    return MMSYSERR_NOTENABLED;
 }
 
 /**************************************************************************
  * 				mixerGetLineControls	[MMSYSTEM.807]
  */
-UINT16 WINAPI mixerGetLineControls16(HMIXEROBJ16 hmix,LPMIXERLINECONTROLS16 lpmlc,DWORD fdwControls) {
-	FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpmlc,fdwControls);
-	return MMSYSERR_NOTENABLED;
+UINT16 WINAPI mixerGetLineControls16(HMIXEROBJ16 hmix,LPMIXERLINECONTROLS16 lpmlc,DWORD fdwControls) 
+{
+    FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpmlc,fdwControls);
+    return MMSYSERR_NOTENABLED;
 }
 
 /**************************************************************************
  * 				mixerGetLineInfoA	[WINMM.106]
  */
-UINT32 WINAPI mixerGetLineInfo32A(HMIXEROBJ32 hmix,LPMIXERLINE32A lpml,DWORD fdwInfo) {
-	MIXERLINE16	ml16;
-	UINT32		ret;
-
-	ml16.dwDestination = lpml->dwDestination;
-	FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpml,fdwInfo);
-	ret = mixerGetLineInfo16(hmix,&ml16,fdwInfo);
-	lpml->cbStruct = sizeof(*lpml);
-	lpml->dwSource = ml16.dwSource;
-	lpml->dwLineID = ml16.dwLineID;
-	lpml->fdwLine = ml16.fdwLine;
-	lpml->dwUser = ml16.dwUser;
-	lpml->dwComponentType = ml16.dwComponentType;
-	lpml->cChannels = ml16.cChannels;
-	lpml->cConnections = ml16.cConnections;
-	lpml->cControls = ml16.cControls;
-	strcpy(lpml->szShortName,ml16.szShortName);
-	strcpy(lpml->szName,ml16.szName);
-	lpml->Target.dwType = ml16.Target.dwType;
-	lpml->Target.dwDeviceID = ml16.Target.dwDeviceID;
-	lpml->Target.wMid = ml16.Target.wMid;
-	lpml->Target.wPid = ml16.Target.wPid;
-	lpml->Target.vDriverVersion = ml16.Target.vDriverVersion;
-	strcpy(lpml->Target.szPname,ml16.Target.szPname);
-	return ret;
+UINT32 WINAPI mixerGetLineInfo32A(HMIXEROBJ32 hmix,LPMIXERLINE32A lpml,DWORD fdwInfo) 
+{
+    MIXERLINE16		ml16;
+    UINT32		ret;
+    
+    ml16.dwDestination = lpml->dwDestination;
+    FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpml,fdwInfo);
+    ret = mixerGetLineInfo16(hmix,&ml16,fdwInfo);
+    lpml->cbStruct = sizeof(*lpml);
+    lpml->dwSource = ml16.dwSource;
+    lpml->dwLineID = ml16.dwLineID;
+    lpml->fdwLine = ml16.fdwLine;
+    lpml->dwUser = ml16.dwUser;
+    lpml->dwComponentType = ml16.dwComponentType;
+    lpml->cChannels = ml16.cChannels;
+    lpml->cConnections = ml16.cConnections;
+    lpml->cControls = ml16.cControls;
+    strcpy(lpml->szShortName,ml16.szShortName);
+    strcpy(lpml->szName,ml16.szName);
+    lpml->Target.dwType = ml16.Target.dwType;
+    lpml->Target.dwDeviceID = ml16.Target.dwDeviceID;
+    lpml->Target.wMid = ml16.Target.wMid;
+    lpml->Target.wPid = ml16.Target.wPid;
+    lpml->Target.vDriverVersion = ml16.Target.vDriverVersion;
+    strcpy(lpml->Target.szPname,ml16.Target.szPname);
+    return ret;
 }
 
 /**************************************************************************
  * 				mixerGetLineInfoW	[WINMM.107]
  */
-UINT32 WINAPI mixerGetLineInfo32W(HMIXEROBJ32 hmix,LPMIXERLINE32W lpml,DWORD fdwInfo) {
-	MIXERLINE16	ml16;
-	UINT32		ret;
-
-	ml16.dwDestination = lpml->dwDestination;
-	FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpml,fdwInfo);
-	ret = mixerGetLineInfo16(hmix,&ml16,fdwInfo);
-	lpml->cbStruct = sizeof(*lpml);
-	lpml->dwSource = ml16.dwSource;
-	lpml->dwLineID = ml16.dwLineID;
-	lpml->fdwLine = ml16.fdwLine;
-	lpml->dwUser = ml16.dwUser;
-	lpml->dwComponentType = ml16.dwComponentType;
-	lpml->cChannels = ml16.cChannels;
-	lpml->cConnections = ml16.cConnections;
-	lpml->cControls = ml16.cControls;
-	lstrcpyAtoW(lpml->szShortName,ml16.szShortName);
-	lstrcpyAtoW(lpml->szName,ml16.szName);
-	lpml->Target.dwType = ml16.Target.dwType;
-	lpml->Target.dwDeviceID = ml16.Target.dwDeviceID;
-	lpml->Target.wMid = ml16.Target.wMid;
-	lpml->Target.wPid = ml16.Target.wPid;
-	lpml->Target.vDriverVersion = ml16.Target.vDriverVersion;
-	/*lstrcpyAtoW(lpml->Target.szPname,ml16.Target.szPname);*/
-	return ret;
+UINT32 WINAPI mixerGetLineInfo32W(HMIXEROBJ32 hmix,LPMIXERLINE32W lpml,DWORD fdwInfo) 
+{
+    MIXERLINE16		ml16;
+    UINT32		ret;
+    
+    ml16.dwDestination = lpml->dwDestination;
+    FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpml,fdwInfo);
+    ret = mixerGetLineInfo16(hmix,&ml16,fdwInfo);
+    lpml->cbStruct = sizeof(*lpml);
+    lpml->dwSource = ml16.dwSource;
+    lpml->dwLineID = ml16.dwLineID;
+    lpml->fdwLine = ml16.fdwLine;
+    lpml->dwUser = ml16.dwUser;
+    lpml->dwComponentType = ml16.dwComponentType;
+    lpml->cChannels = ml16.cChannels;
+    lpml->cConnections = ml16.cConnections;
+    lpml->cControls = ml16.cControls;
+    lstrcpyAtoW(lpml->szShortName,ml16.szShortName);
+    lstrcpyAtoW(lpml->szName,ml16.szName);
+    lpml->Target.dwType = ml16.Target.dwType;
+    lpml->Target.dwDeviceID = ml16.Target.dwDeviceID;
+    lpml->Target.wMid = ml16.Target.wMid;
+    lpml->Target.wPid = ml16.Target.wPid;
+    lpml->Target.vDriverVersion = ml16.Target.vDriverVersion;
+    /*lstrcpyAtoW(lpml->Target.szPname,ml16.Target.szPname);*/
+    return ret;
 }
 
 /**************************************************************************
  * 				mixerGetLineInfo	[MMSYSTEM.805]
  */
-UINT16 WINAPI mixerGetLineInfo16(HMIXEROBJ16 hmix,LPMIXERLINE16 lpml,DWORD fdwInfo) {
-	UINT16 devid =  _get_mixerID_from_handle(hmix,fdwInfo);
-
-	FIXME(mmsys,"(%04x,%p[line %08lx],%08lx) - semi-stub?\n",
-	      hmix,lpml,lpml->dwDestination,fdwInfo);
-	return mixMessage(devid,MXDM_GETLINEINFO,0,(DWORD)lpml,fdwInfo);
+UINT16 WINAPI mixerGetLineInfo16(HMIXEROBJ16 hmix,LPMIXERLINE16 lpml,DWORD fdwInfo) 
+{
+    UINT16 devid =  _get_mixerID_from_handle(hmix,fdwInfo);
+    
+    FIXME(mmsys,"(%04x,%p[line %08lx],%08lx) - semi-stub?\n",
+	  hmix,lpml,lpml->dwDestination,fdwInfo);
+    return mixMessage(devid,MXDM_GETLINEINFO,0,(DWORD)lpml,fdwInfo);
 }
 
 /**************************************************************************
  * 				mixerSetControlDetails	[WINMM.111]
  */
-UINT32 WINAPI mixerSetControlDetails32(HMIXEROBJ32 hmix,LPMIXERCONTROLDETAILS32 lpmcd,DWORD fdwDetails) {
-	FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpmcd,fdwDetails);
-	return MMSYSERR_NOTENABLED;
+UINT32 WINAPI mixerSetControlDetails32(HMIXEROBJ32 hmix,LPMIXERCONTROLDETAILS32 lpmcd,DWORD fdwDetails) 
+{
+    FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpmcd,fdwDetails);
+    return MMSYSERR_NOTENABLED;
 }
 
 /**************************************************************************
  * 				mixerSetControlDetails	[MMSYSTEM.809]
  */
-UINT16 WINAPI mixerSetControlDetails16(HMIXEROBJ16 hmix,LPMIXERCONTROLDETAILS16 lpmcd,DWORD fdwDetails) {
-	FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpmcd,fdwDetails);
-	return MMSYSERR_NOTENABLED;
+UINT16 WINAPI mixerSetControlDetails16(HMIXEROBJ16 hmix,LPMIXERCONTROLDETAILS16 lpmcd,DWORD fdwDetails) 
+{
+    FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpmcd,fdwDetails);
+    return MMSYSERR_NOTENABLED;
 }
 
 /**************************************************************************
  * 				mixerMessage		[WINMM.109]
  */
-UINT32 WINAPI mixerMessage32(HMIXER32 hmix,UINT32 uMsg,DWORD dwParam1,DWORD dwParam2) {
-	LPMIXEROPENDESC	lpmod;
-	UINT16	uDeviceID;
-
-	lpmod = (LPMIXEROPENDESC)USER_HEAP_LIN_ADDR(hmix);
-	if (lpmod)
-		uDeviceID = lpmod->uDeviceID;
-	else
-		uDeviceID = 0;
-	FIXME(mmsys,"(%04lx,%d,%08lx,%08lx): semi-stub?\n",
-	      (DWORD)hmix,uMsg,dwParam1,dwParam2);
-	return mixMessage(uDeviceID,uMsg,0L,dwParam1,dwParam2);
+UINT32 WINAPI mixerMessage32(HMIXER32 hmix,UINT32 uMsg,DWORD dwParam1,DWORD dwParam2) 
+{
+    LPMIXEROPENDESC	lpmod;
+    UINT16		uDeviceID;
+    
+    lpmod = (LPMIXEROPENDESC)USER_HEAP_LIN_ADDR(hmix);
+    if (lpmod)
+	uDeviceID = lpmod->uDeviceID;
+    else
+	uDeviceID = 0;
+    FIXME(mmsys,"(%04lx,%d,%08lx,%08lx): semi-stub?\n",
+	  (DWORD)hmix,uMsg,dwParam1,dwParam2);
+    return mixMessage(uDeviceID,uMsg,0L,dwParam1,dwParam2);
 }
 
 /**************************************************************************
  * 				mixerMessage		[MMSYSTEM.804]
  */
-UINT16 WINAPI mixerMessage16(HMIXER16 hmix,UINT16 uMsg,DWORD dwParam1,DWORD dwParam2) {
-	LPMIXEROPENDESC	lpmod;
-	UINT16	uDeviceID;
-
-	lpmod = (LPMIXEROPENDESC)USER_HEAP_LIN_ADDR(hmix);
-	if (lpmod)
-		uDeviceID = lpmod->uDeviceID;
-	else
-		uDeviceID = 0;
-	FIXME(mmsys,"(%04x,%d,%08lx,%08lx) - semi-stub?\n",
-	      hmix,uMsg,dwParam1,dwParam2);
-	return mixMessage(uDeviceID,uMsg,0L,dwParam1,dwParam2);
+UINT16 WINAPI mixerMessage16(HMIXER16 hmix,UINT16 uMsg,DWORD dwParam1,DWORD dwParam2) 
+{
+    LPMIXEROPENDESC	lpmod;
+    UINT16		uDeviceID;
+    
+    lpmod = (LPMIXEROPENDESC)USER_HEAP_LIN_ADDR(hmix);
+    if (lpmod)
+	uDeviceID = lpmod->uDeviceID;
+    else
+	uDeviceID = 0;
+    FIXME(mmsys,"(%04x,%d,%08lx,%08lx) - semi-stub?\n",
+	  hmix,uMsg,dwParam1,dwParam2);
+    return mixMessage(uDeviceID,uMsg,0L,dwParam1,dwParam2);
 }
 
 /**************************************************************************
@@ -839,7 +862,7 @@
  */
 UINT32 WINAPI auxGetNumDevs32()
 {
-	return auxGetNumDevs16();
+    return auxGetNumDevs16();
 }
 
 /**************************************************************************
@@ -847,11 +870,11 @@
  */
 UINT16 WINAPI auxGetNumDevs16()
 {
-	UINT16	count = 0;
-	TRACE(mmsys, "auxGetNumDevs !\n");
-	count += auxMessage(0, AUXDM_GETNUMDEVS, 0L, 0L, 0L);
-	TRACE(mmsys, "auxGetNumDevs return %u \n", count);
-	return count;
+    UINT16	count = 0;
+    TRACE(mmsys, "auxGetNumDevs !\n");
+    count += auxMessage(0, AUXDM_GETNUMDEVS, 0L, 0L, 0L);
+    TRACE(mmsys, "auxGetNumDevs return %u \n", count);
+    return count;
 }
 
 /**************************************************************************
@@ -859,16 +882,16 @@
  */
 UINT32 WINAPI auxGetDevCaps32W(UINT32 uDeviceID,LPAUXCAPS32W lpCaps,UINT32 uSize)
 {
-	AUXCAPS16	ac16;
-	UINT32	ret = auxGetDevCaps16(uDeviceID,&ac16,sizeof(ac16));
-
-	lpCaps->wMid = ac16.wMid;
-	lpCaps->wPid = ac16.wPid;
-	lpCaps->vDriverVersion = ac16.vDriverVersion;
-	lstrcpyAtoW(lpCaps->szPname,ac16.szPname);
-	lpCaps->wTechnology = ac16.wTechnology;
-	lpCaps->dwSupport = ac16.dwSupport;
-	return ret;
+    AUXCAPS16	ac16;
+    UINT32	ret = auxGetDevCaps16(uDeviceID,&ac16,sizeof(ac16));
+    
+    lpCaps->wMid = ac16.wMid;
+    lpCaps->wPid = ac16.wPid;
+    lpCaps->vDriverVersion = ac16.vDriverVersion;
+    lstrcpyAtoW(lpCaps->szPname,ac16.szPname);
+    lpCaps->wTechnology = ac16.wTechnology;
+    lpCaps->dwSupport = ac16.dwSupport;
+    return ret;
 }
 
 /**************************************************************************
@@ -876,16 +899,16 @@
  */
 UINT32 WINAPI auxGetDevCaps32A(UINT32 uDeviceID,LPAUXCAPS32A lpCaps,UINT32 uSize)
 {
-	AUXCAPS16	ac16;
-	UINT32	ret = auxGetDevCaps16(uDeviceID,&ac16,sizeof(ac16));
-
-	lpCaps->wMid = ac16.wMid;
-	lpCaps->wPid = ac16.wPid;
-	lpCaps->vDriverVersion = ac16.vDriverVersion;
-	strcpy(lpCaps->szPname,ac16.szPname);
-	lpCaps->wTechnology = ac16.wTechnology;
-	lpCaps->dwSupport = ac16.dwSupport;
-	return ret;
+    AUXCAPS16	ac16;
+    UINT32	ret = auxGetDevCaps16(uDeviceID,&ac16,sizeof(ac16));
+    
+    lpCaps->wMid = ac16.wMid;
+    lpCaps->wPid = ac16.wPid;
+    lpCaps->vDriverVersion = ac16.vDriverVersion;
+    strcpy(lpCaps->szPname,ac16.szPname);
+    lpCaps->wTechnology = ac16.wTechnology;
+    lpCaps->dwSupport = ac16.dwSupport;
+    return ret;
 }
 
 /**************************************************************************
@@ -893,10 +916,10 @@
  */
 UINT16 WINAPI auxGetDevCaps16(UINT16 uDeviceID,LPAUXCAPS16 lpCaps, UINT16 uSize)
 {
-	TRACE(mmsys, "(%04X, %p, %d) !\n", 
-					uDeviceID, lpCaps, uSize);
-	return auxMessage(uDeviceID, AUXDM_GETDEVCAPS,
-				0L, (DWORD)lpCaps, (DWORD)uSize);
+    TRACE(mmsys, "(%04X, %p, %d) !\n", 
+	  uDeviceID, lpCaps, uSize);
+    return auxMessage(uDeviceID, AUXDM_GETDEVCAPS,
+		      0L, (DWORD)lpCaps, (DWORD)uSize);
 }
 
 /**************************************************************************
@@ -904,7 +927,7 @@
  */
 UINT32 WINAPI auxGetVolume32(UINT32 uDeviceID, DWORD * lpdwVolume)
 {
-	return auxGetVolume16(uDeviceID,lpdwVolume);
+    return auxGetVolume16(uDeviceID,lpdwVolume);
 }
 
 /**************************************************************************
@@ -912,8 +935,8 @@
  */
 UINT16 WINAPI auxGetVolume16(UINT16 uDeviceID, DWORD * lpdwVolume)
 {
-	TRACE(mmsys, "(%04X, %p) !\n", uDeviceID, lpdwVolume);
-	return auxMessage(uDeviceID, AUXDM_GETVOLUME, 0L, (DWORD)lpdwVolume, 0L);
+    TRACE(mmsys, "(%04X, %p) !\n", uDeviceID, lpdwVolume);
+    return auxMessage(uDeviceID, AUXDM_GETVOLUME, 0L, (DWORD)lpdwVolume, 0L);
 }
 
 /**************************************************************************
@@ -921,7 +944,7 @@
  */
 UINT32 WINAPI auxSetVolume32(UINT32 uDeviceID, DWORD dwVolume)
 {
-	return auxSetVolume16(uDeviceID,dwVolume);
+    return auxSetVolume16(uDeviceID,dwVolume);
 }
 
 /**************************************************************************
@@ -929,8 +952,8 @@
  */
 UINT16 WINAPI auxSetVolume16(UINT16 uDeviceID, DWORD dwVolume)
 {
-	TRACE(mmsys, "(%04X, %08lX) !\n", uDeviceID, dwVolume);
-	return auxMessage(uDeviceID, AUXDM_SETVOLUME, 0L, dwVolume, 0L);
+    TRACE(mmsys, "(%04X, %08lX) !\n", uDeviceID, dwVolume);
+    return auxMessage(uDeviceID, AUXDM_SETVOLUME, 0L, dwVolume, 0L);
 }
 
 /**************************************************************************
@@ -938,20 +961,20 @@
  */
 DWORD WINAPI auxOutMessage32(UINT32 uDeviceID,UINT32 uMessage,DWORD dw1,DWORD dw2)
 {
-	switch (uMessage) {
-	case AUXDM_GETNUMDEVS:
-	case AUXDM_GETVOLUME:
-	case AUXDM_SETVOLUME:
-		/* no argument conversion needed */
-		break;
-	case AUXDM_GETDEVCAPS:
-		return auxGetDevCaps32A(uDeviceID,(LPAUXCAPS32A)dw1,dw2);
-	default:
-		ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
-		    uDeviceID,uMessage,dw1,dw2);
-		break;
-	}
-	return auxMessage(uDeviceID,uMessage,0L,dw1,dw2);
+    switch (uMessage) {
+    case AUXDM_GETNUMDEVS:
+    case AUXDM_GETVOLUME:
+    case AUXDM_SETVOLUME:
+	/* no argument conversion needed */
+	break;
+    case AUXDM_GETDEVCAPS:
+	return auxGetDevCaps32A(uDeviceID,(LPAUXCAPS32A)dw1,dw2);
+    default:
+	ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
+	    uDeviceID,uMessage,dw1,dw2);
+	break;
+    }
+    return auxMessage(uDeviceID,uMessage,0L,dw1,dw2);
 }
 
 /**************************************************************************
@@ -959,23 +982,23 @@
  */
 DWORD WINAPI auxOutMessage16(UINT16 uDeviceID, UINT16 uMessage, DWORD dw1, DWORD dw2)
 {
-	TRACE(mmsys, "(%04X, %04X, %08lX, %08lX)\n", 
-				uDeviceID, uMessage, dw1, dw2);
-	switch (uMessage) {
-	case AUXDM_GETNUMDEVS:
-	case AUXDM_SETVOLUME:
-		/* no argument conversion needed */
-		break;
-	case AUXDM_GETVOLUME:
-		return auxGetVolume16(uDeviceID,(LPDWORD)PTR_SEG_TO_LIN(dw1));
-	case AUXDM_GETDEVCAPS:
-		return auxGetDevCaps16(uDeviceID,(LPAUXCAPS16)PTR_SEG_TO_LIN(dw1),dw2);
-	default:
-		ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
-		    uDeviceID,uMessage,dw1,dw2);
-		break;
-	}
-	return auxMessage(uDeviceID, uMessage, 0L, dw1, dw2);
+    TRACE(mmsys, "(%04X, %04X, %08lX, %08lX)\n", 
+	  uDeviceID, uMessage, dw1, dw2);
+    switch (uMessage) {
+    case AUXDM_GETNUMDEVS:
+    case AUXDM_SETVOLUME:
+	/* no argument conversion needed */
+	break;
+    case AUXDM_GETVOLUME:
+	return auxGetVolume16(uDeviceID,(LPDWORD)PTR_SEG_TO_LIN(dw1));
+    case AUXDM_GETDEVCAPS:
+	return auxGetDevCaps16(uDeviceID,(LPAUXCAPS16)PTR_SEG_TO_LIN(dw1),dw2);
+    default:
+	ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
+	    uDeviceID,uMessage,dw1,dw2);
+	break;
+    }
+    return auxMessage(uDeviceID, uMessage, 0L, dw1, dw2);
 }
 
 /**************************************************************************
@@ -983,12 +1006,12 @@
  */
 BOOL32 WINAPI mciGetErrorString32W(DWORD wError,LPWSTR lpstrBuffer,UINT32 uLength)
 {
-	LPSTR	bufstr = HeapAlloc(GetProcessHeap(),0,uLength);
-	BOOL32	ret = mciGetErrorString32A(wError,bufstr,uLength);
-
-	lstrcpyAtoW(lpstrBuffer,bufstr);
-	HeapFree(GetProcessHeap(),0,bufstr);
-	return ret;
+    LPSTR	bufstr = HeapAlloc(GetProcessHeap(),0,uLength);
+    BOOL32	ret = mciGetErrorString32A(wError,bufstr,uLength);
+    
+    lstrcpyAtoW(lpstrBuffer,bufstr);
+    HeapFree(GetProcessHeap(),0,bufstr);
+    return ret;
 }
 
 /**************************************************************************
@@ -996,7 +1019,7 @@
  */
 BOOL32 WINAPI mciGetErrorString32A(DWORD wError,LPSTR lpstrBuffer,UINT32 uLength)
 {
-	return mciGetErrorString16(wError,lpstrBuffer,uLength);
+    return mciGetErrorString16(wError,lpstrBuffer,uLength);
 }
 
 /**************************************************************************
@@ -1004,275 +1027,275 @@
  */
 BOOL16 WINAPI mciGetErrorString16(DWORD wError,LPSTR lpstrBuffer,UINT16 uLength)
 {
-	LPSTR	msgptr;
-	TRACE(mmsys, "(%08lX, %p, %d);\n", 
-	       wError, lpstrBuffer, uLength);
-	if ((lpstrBuffer == NULL) || (uLength < 1)) return(FALSE);
-	lpstrBuffer[0] = '\0';
-	switch(wError) {
-		case MCIERR_INVALID_DEVICE_ID:
-			msgptr = "Invalid MCI device ID. Use the ID returned when opening the MCI device.";
-			break;
-		case MCIERR_UNRECOGNIZED_KEYWORD:
-			msgptr = "The driver cannot recognize the specified command parameter.";
-			break;
-		case MCIERR_UNRECOGNIZED_COMMAND:
-			msgptr = "The driver cannot recognize the specified command.";
-			break;
-		case MCIERR_HARDWARE:
-			msgptr = "There is a problem with your media device. Make sure it is working correctly or contact the device manufacturer.";
-			break;
-		case MCIERR_INVALID_DEVICE_NAME:
-			msgptr = "The specified device is not open or is not recognized by MCI.";
-			break;
-		case MCIERR_OUT_OF_MEMORY:
-			msgptr = "Not enough memory available for this task. \nQuit one or more applications to increase available memory, and then try again.";
-			break;
-		case MCIERR_DEVICE_OPEN:
-			msgptr = "The device name is already being used as an alias by this application. Use a unique alias.";
-			break;
-		case MCIERR_CANNOT_LOAD_DRIVER:
-			msgptr = "There is an undetectable problem in loading the specified device driver.";
-			break;
-		case MCIERR_MISSING_COMMAND_STRING:
-			msgptr = "No command was specified.";
-			break;
-		case MCIERR_PARAM_OVERFLOW:
-			msgptr = "The output string was to large to fit in the return buffer. Increase the size of the buffer.";
-			break;
-		case MCIERR_MISSING_STRING_ARGUMENT:
-			msgptr = "The specified command requires a character-string parameter. Please provide one.";
-			break;
-		case MCIERR_BAD_INTEGER:
-			msgptr = "The specified integer is invalid for this command.";
-			break;
-		case MCIERR_PARSER_INTERNAL:
-			msgptr = "The device driver returned an invalid return type. Check with the device manufacturer about obtaining a new driver.";
-			break;
-		case MCIERR_DRIVER_INTERNAL:
-			msgptr = "There is a problem with the device driver. Check with the device manufacturer about obtaining a new driver.";
-			break;
-		case MCIERR_MISSING_PARAMETER:
-			msgptr = "The specified command requires a parameter. Please supply one.";
-			break;
-		case MCIERR_UNSUPPORTED_FUNCTION:
-			msgptr = "The MCI device you are using does not support the specified command.";
-			break;
-		case MCIERR_FILE_NOT_FOUND:
-			msgptr = "Cannot find the specified file. Make sure the path and filename are correct.";
-			break;
-		case MCIERR_DEVICE_NOT_READY:
-			msgptr = "The device driver is not ready.";
-			break;
-		case MCIERR_INTERNAL:
-			msgptr = "A problem occurred in initializing MCI. Try restarting Windows.";
-			break;
-		case MCIERR_DRIVER:
-			msgptr = "There is a problem with the device driver. The driver has closed. Cannot access error.";
-			break;
-		case MCIERR_CANNOT_USE_ALL:
-			msgptr = "Cannot use 'all' as the device name with the specified command.";
-			break;
-		case MCIERR_MULTIPLE:
-			msgptr = "Errors occurred in more than one device. Specify each command and device separately to determine which devices caused the error";
-			break;
-		case MCIERR_EXTENSION_NOT_FOUND:
-			msgptr = "Cannot determine the device type from the given filename extension.";
-			break;
-		case MCIERR_OUTOFRANGE:
-			msgptr = "The specified parameter is out of range for the specified command.";
-			break;
-		case MCIERR_FLAGS_NOT_COMPATIBLE:
-			msgptr = "The specified parameters cannot be used together.";
-			break;
-		case MCIERR_FILE_NOT_SAVED:
-			msgptr = "Cannot save the specified file. Make sure you have enough disk space or are still connected to the network.";
-			break;
-		case MCIERR_DEVICE_TYPE_REQUIRED:
-			msgptr = "Cannot find the specified device. Make sure it is installed or that the device name is spelled correctly.";
-			break;
-		case MCIERR_DEVICE_LOCKED:
-			msgptr = "The specified device is now being closed. Wait a few seconds, and then try again.";
-			break;
-		case MCIERR_DUPLICATE_ALIAS:
-			msgptr = "The specified alias is already being used in this application. Use a unique alias.";
-			break;
-		case MCIERR_BAD_CONSTANT:
-			msgptr = "The specified parameter is invalid for this command.";
-			break;
-		case MCIERR_MUST_USE_SHAREABLE:
-			msgptr = "The device driver is already in use. To share it, use the 'shareable' parameter with each 'open' command.";
-			break;
-		case MCIERR_MISSING_DEVICE_NAME:
-			msgptr = "The specified command requires an alias, file, driver, or device name. Please supply one.";
-			break;
-		case MCIERR_BAD_TIME_FORMAT:
-			msgptr = "The specified value for the time format is invalid. Refer to the MCI documentation for valid formats.";
-			break;
-		case MCIERR_NO_CLOSING_QUOTE:
-			msgptr = "A closing double-quotation mark is missing from the parameter value. Please supply one.";
-			break;
-		case MCIERR_DUPLICATE_FLAGS:
-			msgptr = "A parameter or value was specified twice. Only specify it once.";
-			break;
-		case MCIERR_INVALID_FILE:
-			msgptr = "The specified file cannot be played on the specified MCI device. The file may be corrupt, or not in the correct format.";
-			break;
-		case MCIERR_NULL_PARAMETER_BLOCK:
-			msgptr = "A null parameter block was passed to MCI.";
-			break;
-		case MCIERR_UNNAMED_RESOURCE:
-			msgptr = "Cannot save an unnamed file. Supply a filename.";
-			break;
-		case MCIERR_NEW_REQUIRES_ALIAS:
-			msgptr = "You must specify an alias when using the 'new' parameter.";
-			break;
-		case MCIERR_NOTIFY_ON_AUTO_OPEN:
-			msgptr = "Cannot use the 'notify' flag with auto-opened devices.";
-			break;
-		case MCIERR_NO_ELEMENT_ALLOWED:
-			msgptr = "Cannot use a filename with the specified device.";
-			break;
-		case MCIERR_NONAPPLICABLE_FUNCTION:
-			msgptr = "Cannot carry out the commands in the order specified. Correct the command sequence, and then try again.";
-			break;
-		case MCIERR_ILLEGAL_FOR_AUTO_OPEN:
-			msgptr = "Cannot carry out the specified command on an auto-opened device. Wait until the device is closed, and then try again.";
-			break;
-		case MCIERR_FILENAME_REQUIRED:
-			msgptr = "The filename is invalid. Make sure the filename is not longer than 8 characters, followed by a period and an extension.";
-			break;
-		case MCIERR_EXTRA_CHARACTERS:
-			msgptr = "Cannot specify extra characters after a string enclosed in quotation marks.";
-			break;
-		case MCIERR_DEVICE_NOT_INSTALLED:
-			msgptr = "The specified device is not installed on the system. Use the Drivers option in Control Panel to install the device.";
-			break;
-		case MCIERR_GET_CD:
-			msgptr = "Cannot access the specified file or MCI device. Try changing directories or restarting your computer.";
-			break;
-		case MCIERR_SET_CD:
-			msgptr = "Cannot access the specified file or MCI device because the application cannot change directories.";
-			break;
-		case MCIERR_SET_DRIVE:
-			msgptr = "Cannot access specified file or MCI device because the application cannot change drives.";
-			break;
-		case MCIERR_DEVICE_LENGTH:
-			msgptr = "Specify a device or driver name that is less than 79 characters.";
-			break;
-		case MCIERR_DEVICE_ORD_LENGTH:
-			msgptr = "Specify a device or driver name that is less than 69 characters.";
-			break;
-		case MCIERR_NO_INTEGER:
-			msgptr = "The specified command requires an integer parameter. Please provide one.";
-			break;
-		case MCIERR_WAVE_OUTPUTSINUSE:
-			msgptr = "All wave devices that can play files in the current format are in use. Wait until a wave device is free, and then try again.";
-			break;
-		case MCIERR_WAVE_SETOUTPUTINUSE:
-			msgptr = "Cannot set the current wave device for play back because it is in use. Wait until the device is free, and then try again.";
-			break;
-		case MCIERR_WAVE_INPUTSINUSE:
-			msgptr = "All wave devices that can record files in the current format are in use. Wait until a wave device is free, and then try again.";
-			break;
-		case MCIERR_WAVE_SETINPUTINUSE:
-			msgptr = "Cannot set the current wave device for recording because it is in use. Wait until the device is free, and then try again.";
-			break;
-		case MCIERR_WAVE_OUTPUTUNSPECIFIED:
-			msgptr = "Any compatible waveform playback device may be used.";
-			break;
-		case MCIERR_WAVE_INPUTUNSPECIFIED:
-			msgptr = "Any compatible waveform recording device may be used.";
-			break;
-		case MCIERR_WAVE_OUTPUTSUNSUITABLE:
-			msgptr = "No wave device that can play files in the current format is installed. Use the Drivers option to install the wave device.";
-			break;
-		case MCIERR_WAVE_SETOUTPUTUNSUITABLE:
-			msgptr = "The device you are trying to play to cannot recognize the current file format.";
-			break;
-		case MCIERR_WAVE_INPUTSUNSUITABLE:
-			msgptr = "No wave device that can record files in the current format is installed. Use the Drivers option to install the wave device.";
-			break;
-		case MCIERR_WAVE_SETINPUTUNSUITABLE:
-			msgptr = "The device you are trying to record from cannot recognize the current file format.";
-			break;
-		case MCIERR_NO_WINDOW:
-			msgptr = "There is no display window.";
-			break;
-		case MCIERR_CREATEWINDOW:
-			msgptr = "Could not create or use window.";
-			break;
-		case MCIERR_FILE_READ:
-			msgptr = "Cannot read the specified file. Make sure the file is still present, or check your disk or network connection.";
-			break;
-		case MCIERR_FILE_WRITE:
-			msgptr = "Cannot write to the specified file. Make sure you have enough disk space or are still connected to the network.";
-			break;
-		case MCIERR_SEQ_DIV_INCOMPATIBLE:
-			msgptr = "The time formats of the \"song pointer\" and SMPTE are mutually exclusive. You can't use them together.";
-			break;
-		case MCIERR_SEQ_NOMIDIPRESENT:
-			msgptr = "The system has no installed MIDI devices. Use the Drivers option from the Control Panel to install a MIDI driver.";
-			break;
-		case MCIERR_SEQ_PORT_INUSE:
-			msgptr = "The specified MIDI port is already in use. Wait until it is free; the try again.";
-			break;
-		case MCIERR_SEQ_PORT_MAPNODEVICE:
-			msgptr = "The current MIDI Mapper setup refers to a MIDI device that is not installed on the system. Use the MIDI Mapper option from the Control Panel to edit the setup.";
-			break;
-		case MCIERR_SEQ_PORT_MISCERROR:
-			msgptr = "An error occurred with the specified port.";
-			break;
-		case MCIERR_SEQ_PORT_NONEXISTENT:
-			msgptr = "The specified MIDI device is not installed on the system. Use the Drivers option from the Control Panel to install a MIDI device.";
-			break;
-		case MCIERR_SEQ_PORTUNSPECIFIED:
-			msgptr = "The system doesnot have a current MIDI port specified.";
-			break;
-		case MCIERR_SEQ_TIMER:
-			msgptr = "All multimedia timers are being used by other applications. Quit one of these applications; then, try again.";
-			break;
-
-/* 
-msg# 513 : vcr
-msg# 514 : videodisc
-msg# 515 : overlay
-msg# 516 : cdaudio
-msg# 517 : dat
-msg# 518 : scanner
-msg# 519 : animation
-msg# 520 : digitalvideo
-msg# 521 : other
-msg# 522 : waveaudio
-msg# 523 : sequencer
-msg# 524 : not ready
-msg# 525 : stopped
-msg# 526 : playing
-msg# 527 : recording
-msg# 528 : seeking
-msg# 529 : paused
-msg# 530 : open
-msg# 531 : false
-msg# 532 : true
-msg# 533 : milliseconds
-msg# 534 : hms
-msg# 535 : msf
-msg# 536 : frames
-msg# 537 : smpte 24
-msg# 538 : smpte 25
-msg# 539 : smpte 30
-msg# 540 : smpte 30 drop
-msg# 541 : bytes
-msg# 542 : samples
-msg# 543 : tmsf
-*/
-		default:
-			msgptr = "Unknown MCI Error !\n";
-			break;
-	}
-        lstrcpyn32A(lpstrBuffer, msgptr, uLength);
-	TRACE(mmsys, "msg = %s;\n", msgptr);
-	return TRUE;
+    LPSTR	msgptr;
+    TRACE(mmsys, "(%08lX, %p, %d);\n", 
+	  wError, lpstrBuffer, uLength);
+    if ((lpstrBuffer == NULL) || (uLength < 1)) return(FALSE);
+    lpstrBuffer[0] = '\0';
+    switch(wError) {
+    case MCIERR_INVALID_DEVICE_ID:
+	msgptr = "Invalid MCI device ID. Use the ID returned when opening the MCI device.";
+	break;
+    case MCIERR_UNRECOGNIZED_KEYWORD:
+	msgptr = "The driver cannot recognize the specified command parameter.";
+	break;
+    case MCIERR_UNRECOGNIZED_COMMAND:
+	msgptr = "The driver cannot recognize the specified command.";
+	break;
+    case MCIERR_HARDWARE:
+	msgptr = "There is a problem with your media device. Make sure it is working correctly or contact the device manufacturer.";
+	break;
+    case MCIERR_INVALID_DEVICE_NAME:
+	msgptr = "The specified device is not open or is not recognized by MCI.";
+	break;
+    case MCIERR_OUT_OF_MEMORY:
+	msgptr = "Not enough memory available for this task. \nQuit one or more applications to increase available memory, and then try again.";
+	break;
+    case MCIERR_DEVICE_OPEN:
+	msgptr = "The device name is already being used as an alias by this application. Use a unique alias.";
+	break;
+    case MCIERR_CANNOT_LOAD_DRIVER:
+	msgptr = "There is an undetectable problem in loading the specified device driver.";
+	break;
+    case MCIERR_MISSING_COMMAND_STRING:
+	msgptr = "No command was specified.";
+	break;
+    case MCIERR_PARAM_OVERFLOW:
+	msgptr = "The output string was to large to fit in the return buffer. Increase the size of the buffer.";
+	break;
+    case MCIERR_MISSING_STRING_ARGUMENT:
+	msgptr = "The specified command requires a character-string parameter. Please provide one.";
+	break;
+    case MCIERR_BAD_INTEGER:
+	msgptr = "The specified integer is invalid for this command.";
+	break;
+    case MCIERR_PARSER_INTERNAL:
+	msgptr = "The device driver returned an invalid return type. Check with the device manufacturer about obtaining a new driver.";
+	break;
+    case MCIERR_DRIVER_INTERNAL:
+	msgptr = "There is a problem with the device driver. Check with the device manufacturer about obtaining a new driver.";
+	break;
+    case MCIERR_MISSING_PARAMETER:
+	msgptr = "The specified command requires a parameter. Please supply one.";
+	break;
+    case MCIERR_UNSUPPORTED_FUNCTION:
+	msgptr = "The MCI device you are using does not support the specified command.";
+	break;
+    case MCIERR_FILE_NOT_FOUND:
+	msgptr = "Cannot find the specified file. Make sure the path and filename are correct.";
+	break;
+    case MCIERR_DEVICE_NOT_READY:
+	msgptr = "The device driver is not ready.";
+	break;
+    case MCIERR_INTERNAL:
+	msgptr = "A problem occurred in initializing MCI. Try restarting Windows.";
+	break;
+    case MCIERR_DRIVER:
+	msgptr = "There is a problem with the device driver. The driver has closed. Cannot access error.";
+	break;
+    case MCIERR_CANNOT_USE_ALL:
+	msgptr = "Cannot use 'all' as the device name with the specified command.";
+	break;
+    case MCIERR_MULTIPLE:
+	msgptr = "Errors occurred in more than one device. Specify each command and device separately to determine which devices caused the error";
+	break;
+    case MCIERR_EXTENSION_NOT_FOUND:
+	msgptr = "Cannot determine the device type from the given filename extension.";
+	break;
+    case MCIERR_OUTOFRANGE:
+	msgptr = "The specified parameter is out of range for the specified command.";
+	break;
+    case MCIERR_FLAGS_NOT_COMPATIBLE:
+	msgptr = "The specified parameters cannot be used together.";
+	break;
+    case MCIERR_FILE_NOT_SAVED:
+	msgptr = "Cannot save the specified file. Make sure you have enough disk space or are still connected to the network.";
+	break;
+    case MCIERR_DEVICE_TYPE_REQUIRED:
+	msgptr = "Cannot find the specified device. Make sure it is installed or that the device name is spelled correctly.";
+	break;
+    case MCIERR_DEVICE_LOCKED:
+	msgptr = "The specified device is now being closed. Wait a few seconds, and then try again.";
+	break;
+    case MCIERR_DUPLICATE_ALIAS:
+	msgptr = "The specified alias is already being used in this application. Use a unique alias.";
+	break;
+    case MCIERR_BAD_CONSTANT:
+	msgptr = "The specified parameter is invalid for this command.";
+	break;
+    case MCIERR_MUST_USE_SHAREABLE:
+	msgptr = "The device driver is already in use. To share it, use the 'shareable' parameter with each 'open' command.";
+	break;
+    case MCIERR_MISSING_DEVICE_NAME:
+	msgptr = "The specified command requires an alias, file, driver, or device name. Please supply one.";
+	break;
+    case MCIERR_BAD_TIME_FORMAT:
+	msgptr = "The specified value for the time format is invalid. Refer to the MCI documentation for valid formats.";
+	break;
+    case MCIERR_NO_CLOSING_QUOTE:
+	msgptr = "A closing double-quotation mark is missing from the parameter value. Please supply one.";
+	break;
+    case MCIERR_DUPLICATE_FLAGS:
+	msgptr = "A parameter or value was specified twice. Only specify it once.";
+	break;
+    case MCIERR_INVALID_FILE:
+	msgptr = "The specified file cannot be played on the specified MCI device. The file may be corrupt, or not in the correct format.";
+	break;
+    case MCIERR_NULL_PARAMETER_BLOCK:
+	msgptr = "A null parameter block was passed to MCI.";
+	break;
+    case MCIERR_UNNAMED_RESOURCE:
+	msgptr = "Cannot save an unnamed file. Supply a filename.";
+	break;
+    case MCIERR_NEW_REQUIRES_ALIAS:
+	msgptr = "You must specify an alias when using the 'new' parameter.";
+	break;
+    case MCIERR_NOTIFY_ON_AUTO_OPEN:
+	msgptr = "Cannot use the 'notify' flag with auto-opened devices.";
+	break;
+    case MCIERR_NO_ELEMENT_ALLOWED:
+	msgptr = "Cannot use a filename with the specified device.";
+	break;
+    case MCIERR_NONAPPLICABLE_FUNCTION:
+	msgptr = "Cannot carry out the commands in the order specified. Correct the command sequence, and then try again.";
+	break;
+    case MCIERR_ILLEGAL_FOR_AUTO_OPEN:
+	msgptr = "Cannot carry out the specified command on an auto-opened device. Wait until the device is closed, and then try again.";
+	break;
+    case MCIERR_FILENAME_REQUIRED:
+	msgptr = "The filename is invalid. Make sure the filename is not longer than 8 characters, followed by a period and an extension.";
+	break;
+    case MCIERR_EXTRA_CHARACTERS:
+	msgptr = "Cannot specify extra characters after a string enclosed in quotation marks.";
+	break;
+    case MCIERR_DEVICE_NOT_INSTALLED:
+	msgptr = "The specified device is not installed on the system. Use the Drivers option in Control Panel to install the device.";
+	break;
+    case MCIERR_GET_CD:
+	msgptr = "Cannot access the specified file or MCI device. Try changing directories or restarting your computer.";
+	break;
+    case MCIERR_SET_CD:
+	msgptr = "Cannot access the specified file or MCI device because the application cannot change directories.";
+	break;
+    case MCIERR_SET_DRIVE:
+	msgptr = "Cannot access specified file or MCI device because the application cannot change drives.";
+	break;
+    case MCIERR_DEVICE_LENGTH:
+	msgptr = "Specify a device or driver name that is less than 79 characters.";
+	break;
+    case MCIERR_DEVICE_ORD_LENGTH:
+	msgptr = "Specify a device or driver name that is less than 69 characters.";
+	break;
+    case MCIERR_NO_INTEGER:
+	msgptr = "The specified command requires an integer parameter. Please provide one.";
+	break;
+    case MCIERR_WAVE_OUTPUTSINUSE:
+	msgptr = "All wave devices that can play files in the current format are in use. Wait until a wave device is free, and then try again.";
+	break;
+    case MCIERR_WAVE_SETOUTPUTINUSE:
+	msgptr = "Cannot set the current wave device for play back because it is in use. Wait until the device is free, and then try again.";
+	break;
+    case MCIERR_WAVE_INPUTSINUSE:
+	msgptr = "All wave devices that can record files in the current format are in use. Wait until a wave device is free, and then try again.";
+	break;
+    case MCIERR_WAVE_SETINPUTINUSE:
+	msgptr = "Cannot set the current wave device for recording because it is in use. Wait until the device is free, and then try again.";
+	break;
+    case MCIERR_WAVE_OUTPUTUNSPECIFIED:
+	msgptr = "Any compatible waveform playback device may be used.";
+	break;
+    case MCIERR_WAVE_INPUTUNSPECIFIED:
+	msgptr = "Any compatible waveform recording device may be used.";
+	break;
+    case MCIERR_WAVE_OUTPUTSUNSUITABLE:
+	msgptr = "No wave device that can play files in the current format is installed. Use the Drivers option to install the wave device.";
+	break;
+    case MCIERR_WAVE_SETOUTPUTUNSUITABLE:
+	msgptr = "The device you are trying to play to cannot recognize the current file format.";
+	break;
+    case MCIERR_WAVE_INPUTSUNSUITABLE:
+	msgptr = "No wave device that can record files in the current format is installed. Use the Drivers option to install the wave device.";
+	break;
+    case MCIERR_WAVE_SETINPUTUNSUITABLE:
+	msgptr = "The device you are trying to record from cannot recognize the current file format.";
+	break;
+    case MCIERR_NO_WINDOW:
+	msgptr = "There is no display window.";
+	break;
+    case MCIERR_CREATEWINDOW:
+	msgptr = "Could not create or use window.";
+	break;
+    case MCIERR_FILE_READ:
+	msgptr = "Cannot read the specified file. Make sure the file is still present, or check your disk or network connection.";
+	break;
+    case MCIERR_FILE_WRITE:
+	msgptr = "Cannot write to the specified file. Make sure you have enough disk space or are still connected to the network.";
+	break;
+    case MCIERR_SEQ_DIV_INCOMPATIBLE:
+	msgptr = "The time formats of the \"song pointer\" and SMPTE are mutually exclusive. You can't use them together.";
+	break;
+    case MCIERR_SEQ_NOMIDIPRESENT:
+	msgptr = "The system has no installed MIDI devices. Use the Drivers option from the Control Panel to install a MIDI driver.";
+	break;
+    case MCIERR_SEQ_PORT_INUSE:
+	msgptr = "The specified MIDI port is already in use. Wait until it is free; the try again.";
+	break;
+    case MCIERR_SEQ_PORT_MAPNODEVICE:
+	msgptr = "The current MIDI Mapper setup refers to a MIDI device that is not installed on the system. Use the MIDI Mapper option from the Control Panel to edit the setup.";
+	break;
+    case MCIERR_SEQ_PORT_MISCERROR:
+	msgptr = "An error occurred with the specified port.";
+	break;
+    case MCIERR_SEQ_PORT_NONEXISTENT:
+	msgptr = "The specified MIDI device is not installed on the system. Use the Drivers option from the Control Panel to install a MIDI device.";
+	break;
+    case MCIERR_SEQ_PORTUNSPECIFIED:
+	msgptr = "The system doesnot have a current MIDI port specified.";
+	break;
+    case MCIERR_SEQ_TIMER:
+	msgptr = "All multimedia timers are being used by other applications. Quit one of these applications; then, try again.";
+	break;
+	
+	/* 
+	   msg# 513 : vcr
+	   msg# 514 : videodisc
+	   msg# 515 : overlay
+	   msg# 516 : cdaudio
+	   msg# 517 : dat
+	   msg# 518 : scanner
+	   msg# 519 : animation
+	   msg# 520 : digitalvideo
+	   msg# 521 : other
+	   msg# 522 : waveaudio
+	   msg# 523 : sequencer
+	   msg# 524 : not ready
+	   msg# 525 : stopped
+	   msg# 526 : playing
+	   msg# 527 : recording
+	   msg# 528 : seeking
+	   msg# 529 : paused
+	   msg# 530 : open
+	   msg# 531 : false
+	   msg# 532 : true
+	   msg# 533 : milliseconds
+	   msg# 534 : hms
+	   msg# 535 : msf
+	   msg# 536 : frames
+	   msg# 537 : smpte 24
+	   msg# 538 : smpte 25
+	   msg# 539 : smpte 30
+	   msg# 540 : smpte 30 drop
+	   msg# 541 : bytes
+	   msg# 542 : samples
+	   msg# 543 : tmsf
+	*/
+    default:
+	msgptr = "Unknown MCI Error !\n";
+	break;
+    }
+    lstrcpyn32A(lpstrBuffer, msgptr, uLength);
+    TRACE(mmsys, "msg = %s;\n", msgptr);
+    return TRUE;
 }
 
 
@@ -1281,12 +1304,12 @@
  */
 BOOL16 WINAPI mciDriverNotify(HWND16 hWndCallBack, UINT16 wDevID, UINT16 wStatus)
 {
-	TRACE(mmsys, "(%04X, %u, %04X)\n", hWndCallBack, wDevID, wStatus);
-	if (!IsWindow32(hWndCallBack)) return FALSE;
-	TRACE(mmsys, "before PostMessage\n");
-	PostMessage16( hWndCallBack, MM_MCINOTIFY, wStatus, 
-                       MAKELONG(wDevID, 0));
-	return TRUE;
+    TRACE(mmsys, "(%04X, %u, %04X)\n", hWndCallBack, wDevID, wStatus);
+    if (!IsWindow32(hWndCallBack)) return FALSE;
+    TRACE(mmsys, "before PostMessage\n");
+    PostMessage16( hWndCallBack, MM_MCINOTIFY, wStatus, 
+		   MAKELONG(wDevID, 0));
+    return TRUE;
 }
 
 /**************************************************************************
@@ -1295,186 +1318,177 @@
 
 DWORD mciOpen(DWORD dwParam, LPMCI_OPEN_PARMS16 lp16Parms)
 {
-	char	str[128];
-	LPMCI_OPEN_PARMS16 lpParms;
-	UINT16	uDevTyp = 0;
-	UINT16	wDevID = MMSYSTEM_FirstDevID();
-	DWORD dwret;
-
-	lpParms = PTR_SEG_TO_LIN(lp16Parms);
-	TRACE(mmsys, "(%08lX, %p (%p))\n", dwParam, lp16Parms, lpParms);
-	if (lp16Parms == NULL) return MCIERR_INTERNAL;
-
-	while(GetDrv(wDevID)->modp.wType != 0) {
-		wDevID = MMSYSTEM_NextDevID(wDevID);
-		if (!MMSYSTEM_DevIDValid(wDevID)) {
-			TRACE(mmsys, "MAXMCIDRIVERS reached !\n");
-			return MCIERR_INTERNAL;
-		}
+    char		str[128];
+    LPMCI_OPEN_PARMS16	lpParms;
+    UINT16		uDevTyp = 0;
+    UINT16		wDevID = MMSYSTEM_FirstDevID();
+    DWORD 		dwret;
+    
+    lpParms = PTR_SEG_TO_LIN(lp16Parms);
+    TRACE(mmsys, "(%08lX, %p (%p))\n", dwParam, lp16Parms, lpParms);
+    if (lp16Parms == NULL) return MCIERR_INTERNAL;
+    
+    while(GetDrv(wDevID)->modp.wType != 0) {
+	wDevID = MMSYSTEM_NextDevID(wDevID);
+	if (!MMSYSTEM_DevIDValid(wDevID)) {
+	    TRACE(mmsys, "MAXMCIDRIVERS reached !\n");
+	    return MCIERR_INTERNAL;
 	}
-	TRACE(mmsys, "wDevID=%04X \n", wDevID);
-	memcpy(GetOpenDrv(wDevID),lpParms,sizeof(*lpParms));
-
-	if (dwParam & MCI_OPEN_ELEMENT) {
-		char	*s,*t;
-
-		TRACE(mmsys,"lpstrElementName='%s'\n",
-			(char*)PTR_SEG_TO_LIN(lpParms->lpstrElementName)
-		);
-		s=(char*)PTR_SEG_TO_LIN(lpParms->lpstrElementName);
-		t=strrchr(s,'.');
-		if (t) {
-			GetProfileString32A("mci extensions",t+1,"*",str,sizeof(str));
-			CharUpper32A(str);
-			TRACE(mmsys, "str = %s \n", str);
-			if (strcmp(str, "CDAUDIO") == 0) {
-				uDevTyp = MCI_DEVTYPE_CD_AUDIO;
-			} else
-			if (strcmp(str, "WAVEAUDIO") == 0) {
-				uDevTyp = MCI_DEVTYPE_WAVEFORM_AUDIO;
-			} else
-			if (strcmp(str, "SEQUENCER") == 0)	{
-				uDevTyp = MCI_DEVTYPE_SEQUENCER;
-			} else
-			if (strcmp(str, "ANIMATION1") == 0) {
-				uDevTyp = MCI_DEVTYPE_ANIMATION;
-			} else
-			if (strcmp(str, "AVIVIDEO") == 0) {
-				uDevTyp = MCI_DEVTYPE_DIGITAL_VIDEO;
-			} else 
-			if (strcmp(str,"*") == 0) {
-				TRACE(mmsys,"No [mci extensions] entry for %s found.\n",t);
-				return MCIERR_EXTENSION_NOT_FOUND;
+    }
+    TRACE(mmsys, "wDevID=%04X \n", wDevID);
+    memcpy(GetOpenDrv(wDevID),lpParms,sizeof(*lpParms));
+    
+    if (dwParam & MCI_OPEN_ELEMENT) {
+	char	*s,*t;
+	
+	TRACE(mmsys,"lpstrElementName='%s'\n",
+	      (char*)PTR_SEG_TO_LIN(lpParms->lpstrElementName)
+	      );
+	s=(char*)PTR_SEG_TO_LIN(lpParms->lpstrElementName);
+	t=strrchr(s,'.');
+	if (t) {
+	    GetProfileString32A("mci extensions",t+1,"*",str,sizeof(str));
+	    CharUpper32A(str);
+	    TRACE(mmsys, "str = %s \n", str);
+	    if (strcmp(str, "CDAUDIO") == 0) {
+		uDevTyp = MCI_DEVTYPE_CD_AUDIO;
+	    } else if (strcmp(str, "WAVEAUDIO") == 0) {
+		uDevTyp = MCI_DEVTYPE_WAVEFORM_AUDIO;
+	    } else if (strcmp(str, "SEQUENCER") == 0)	{
+		uDevTyp = MCI_DEVTYPE_SEQUENCER;
+	    } else if (strcmp(str, "ANIMATION1") == 0) {
+		uDevTyp = MCI_DEVTYPE_ANIMATION;
+	    } else if (strcmp(str, "AVIVIDEO") == 0) {
+		uDevTyp = MCI_DEVTYPE_DIGITAL_VIDEO;
+	    } else if (strcmp(str,"*") == 0) {
+		TRACE(mmsys,"No [mci extensions] entry for %s found.\n",t);
+		return MCIERR_EXTENSION_NOT_FOUND;
 #if testing16
-			} else  {
-				HDRVR16 hdrv = OpenDriver(str,"mci",NULL);
-				if (hdrv) {
-					HMODULE16	hmod;
-
-					hmod = GetDriverModuleHandle(hdrv);
-					GetDrv(wDevID)->hdrv = hdrv;
-					GetDrv(wDevID)->driverproc = GetProcAddress16(hmod,SEGPTR_GET(SEGPTR_STRDUP("DRIVERPROC")));
-					uDevTyp = MCI_DEVTYPE_OTHER;
-				} else {
-					FIXME(mmsys, "[mci extensions] entry %s for %s not supported.\n",str,t);
-					return MCIERR_DEVICE_NOT_INSTALLED;
-				}
-#endif
-			}
-		} else
-			return MCIERR_EXTENSION_NOT_FOUND;
-	}
-
-	if (dwParam & MCI_OPEN_ALIAS) {
-		TRACE(mmsys, "Alias='%s' !\n",
-			(char*)PTR_SEG_TO_LIN(lpParms->lpstrAlias));
-                GetOpenDrv(wDevID)->lpstrAlias = (LPSTR)SEGPTR_GET(
-                    SEGPTR_STRDUP((char*)PTR_SEG_TO_LIN(lpParms->lpstrAlias)));
-		/* mplayer does allocate alias to CDAUDIO */
-	}
-	if (dwParam & MCI_OPEN_TYPE) {
-		if (dwParam & MCI_OPEN_TYPE_ID) {
-			TRACE(mmsys, "Dev=%08lx!\n", (DWORD)lpParms->lpstrDeviceType);
-			uDevTyp = LOWORD((DWORD)lpParms->lpstrDeviceType);
- 			GetOpenDrv(wDevID)->lpstrDeviceType=(LPSTR)lpParms->lpstrDeviceType;
+	    } else  {
+		HDRVR16 hdrv = OpenDriver(str,"mci",NULL);
+		if (hdrv) {
+		    HMODULE16	hmod;
+		    
+		    hmod = GetDriverModuleHandle(hdrv);
+		    GetDrv(wDevID)->hdrv = hdrv;
+		    GetDrv(wDevID)->driverproc = GetProcAddress16(hmod,SEGPTR_GET(SEGPTR_STRDUP("DRIVERPROC")));
+		    uDevTyp = MCI_DEVTYPE_OTHER;
 		} else {
-			if (lpParms->lpstrDeviceType == NULL) return MCIERR_INTERNAL;
-			TRACE(mmsys, "Dev='%s' !\n",
-                              (char*)PTR_SEG_TO_LIN(lpParms->lpstrDeviceType));
-                        GetOpenDrv(wDevID)->lpstrDeviceType=(LPSTR)SEGPTR_GET(
-              SEGPTR_STRDUP((char*)PTR_SEG_TO_LIN(lpParms->lpstrDeviceType)));
-			strcpy(str, PTR_SEG_TO_LIN(lpParms->lpstrDeviceType));
-			CharUpper32A(str);
-			if (strcmp(str, "CDAUDIO") == 0) {
-				uDevTyp = MCI_DEVTYPE_CD_AUDIO;
-			} else
-			if (strcmp(str, "WAVEAUDIO") == 0) {
-				uDevTyp = MCI_DEVTYPE_WAVEFORM_AUDIO;
-			} else
-			if (strcmp(str, "SEQUENCER") == 0)	{
-				uDevTyp = MCI_DEVTYPE_SEQUENCER;
-			} else
-			if (strcmp(str, "ANIMATION1") == 0) {
-				uDevTyp = MCI_DEVTYPE_ANIMATION;
-			} else
-			if (strcmp(str, "AVIVIDEO") == 0) {
-				uDevTyp = MCI_DEVTYPE_DIGITAL_VIDEO;
-			} else {
-#if testing16
-				HDRVR16 hdrv;
-				TRACE(mmsys,"trying to load driver...\n");
-				hdrv = OpenDriver(str,"mci",NULL);
-				if (hdrv) {
-					HMODULE16	hmod;
-
-					hmod = GetDriverModuleHandle(hdrv);
-					GetDrv(wDevID)->hdrv = hdrv;
-					GetDrv(wDevID)->driverproc = GetProcAddress16(hmod,SEGPTR_GET(SEGPTR_STRDUP("DRIVERPROC")));
-					uDevTyp = MCI_DEVTYPE_OTHER;
-				} else
-#endif
-					return MCIERR_DEVICE_NOT_INSTALLED;
-			}
+		    FIXME(mmsys, "[mci extensions] entry %s for %s not supported.\n",str,t);
+		    return MCIERR_DEVICE_NOT_INSTALLED;
 		}
-	}
-	GetDrv(wDevID)->modp.wType = uDevTyp;
-	GetDrv(wDevID)->modp.wDeviceID = 0;  /* FIXME? for multiple devices */
-	lpParms->wDeviceID = wDevID;
-	TRACE(mmsys, "mcidev=%d, uDevTyp=%04X wDeviceID=%04X !\n", 
-				wDevID, uDevTyp, lpParms->wDeviceID);
-	switch(uDevTyp)
-        {
-        case MCI_DEVTYPE_CD_AUDIO:
-	  dwret = CDAUDIO_DriverProc( 0, 0, MCI_OPEN_DRIVER,
-				     dwParam, (DWORD)lp16Parms);
-	  break;
-        case MCI_DEVTYPE_WAVEFORM_AUDIO:
-	  dwret =  WAVE_DriverProc( 0, 0, MCI_OPEN_DRIVER, 
-				   dwParam, (DWORD)lp16Parms);
-	  break;
-	case MCI_DEVTYPE_SEQUENCER:
-	  dwret = MIDI_DriverProc( 0, 0, MCI_OPEN_DRIVER, 
-				  dwParam, (DWORD)lp16Parms);
-	  break;
-        case MCI_DEVTYPE_ANIMATION:
-	  dwret = ANIM_DriverProc( 0, 0, MCI_OPEN_DRIVER, 
-				  dwParam, (DWORD)lp16Parms);
-	  break;
-        case MCI_DEVTYPE_DIGITAL_VIDEO:
-	  TRACE(mmsys, "No DIGITAL_VIDEO yet !\n");
-	  return MCIERR_DEVICE_NOT_INSTALLED;
-        default:
-#if testing16
-	  dwret = Callbacks->CallDriverProc(GetDrv(wDevID)->driverproc,0,GetDrv(wDevID)->hdrv,MCI_OPEN_DRIVER,dwParam,(DWORD)lp16Parms);
-	  WARN(mmsys, "Invalid Device Name '%08lx' !\n", (DWORD)lpParms->lpstrDeviceType);
 #endif
-	  return MCIERR_INVALID_DEVICE_NAME;
-        }
-
-
-	if (dwParam&MCI_NOTIFY)
-	  mciDriverNotify(lpParms->dwCallback,wDevID,
-			  (dwret==0?MCI_NOTIFY_SUCCESSFUL:MCI_NOTIFY_FAILURE));
-
-	/* only handled devices fall through */
-	TRACE(mmsys, "wDevID = %04X wDeviceID = %d dwret = %ld\n",wDevID, lpParms->wDeviceID, dwret);
-	return dwret;
+	    }
+	} else
+	    return MCIERR_EXTENSION_NOT_FOUND;
+    }
+    
+    if (dwParam & MCI_OPEN_ALIAS) {
+	TRACE(mmsys, "Alias='%s' !\n",
+	      (char*)PTR_SEG_TO_LIN(lpParms->lpstrAlias));
+	GetOpenDrv(wDevID)->lpstrAlias = (LPSTR)SEGPTR_GET(SEGPTR_STRDUP((char*)PTR_SEG_TO_LIN(lpParms->lpstrAlias)));
+	/* mplayer does allocate alias to CDAUDIO */
+    }
+    if (dwParam & MCI_OPEN_TYPE) {
+	if (dwParam & MCI_OPEN_TYPE_ID) {
+	    TRACE(mmsys, "Dev=%08lx!\n", (DWORD)lpParms->lpstrDeviceType);
+	    uDevTyp = LOWORD((DWORD)lpParms->lpstrDeviceType);
+	    GetOpenDrv(wDevID)->lpstrDeviceType=(LPSTR)lpParms->lpstrDeviceType;
+	} else {
+	    if (lpParms->lpstrDeviceType == NULL) return MCIERR_INTERNAL;
+	    TRACE(mmsys, "Dev='%s' !\n",
+		  (char*)PTR_SEG_TO_LIN(lpParms->lpstrDeviceType));
+	    GetOpenDrv(wDevID)->lpstrDeviceType=(LPSTR)SEGPTR_GET(
+								  SEGPTR_STRDUP((char*)PTR_SEG_TO_LIN(lpParms->lpstrDeviceType)));
+	    strcpy(str, PTR_SEG_TO_LIN(lpParms->lpstrDeviceType));
+	    CharUpper32A(str);
+	    if (strcmp(str, "CDAUDIO") == 0) {
+		uDevTyp = MCI_DEVTYPE_CD_AUDIO;
+	    } else if (strcmp(str, "WAVEAUDIO") == 0) {
+		uDevTyp = MCI_DEVTYPE_WAVEFORM_AUDIO;
+	    } else if (strcmp(str, "SEQUENCER") == 0)	{
+		uDevTyp = MCI_DEVTYPE_SEQUENCER;
+	    } else if (strcmp(str, "ANIMATION1") == 0) {
+		uDevTyp = MCI_DEVTYPE_ANIMATION;
+	    } else if (strcmp(str, "AVIVIDEO") == 0) {
+		uDevTyp = MCI_DEVTYPE_DIGITAL_VIDEO;
+	    } else {
+#if testing16
+		HDRVR16 hdrv;
+		TRACE(mmsys,"trying to load driver...\n");
+		hdrv = OpenDriver(str,"mci",NULL);
+		if (hdrv) {
+		    HMODULE16	hmod;
+		    
+		    hmod = GetDriverModuleHandle(hdrv);
+		    GetDrv(wDevID)->hdrv = hdrv;
+		    GetDrv(wDevID)->driverproc = GetProcAddress16(hmod,SEGPTR_GET(SEGPTR_STRDUP("DRIVERPROC")));
+		    uDevTyp = MCI_DEVTYPE_OTHER;
+		} else
+#endif
+		    return MCIERR_DEVICE_NOT_INSTALLED;
+	    }
+	}
+    }
+    GetDrv(wDevID)->modp.wType = uDevTyp;
+    GetDrv(wDevID)->modp.wDeviceID = 0;  /* FIXME? for multiple devices */
+    lpParms->wDeviceID = wDevID;
+    TRACE(mmsys, "mcidev=%d, uDevTyp=%04X wDeviceID=%04X !\n", 
+	  wDevID, uDevTyp, lpParms->wDeviceID);
+    switch(uDevTyp) {
+    case MCI_DEVTYPE_CD_AUDIO:
+	dwret = CDAUDIO_DriverProc( 0, 0, MCI_OPEN_DRIVER,
+				    dwParam, (DWORD)lp16Parms);
+	break;
+    case MCI_DEVTYPE_WAVEFORM_AUDIO:
+	dwret =  WAVE_DriverProc( 0, 0, MCI_OPEN_DRIVER, 
+				  dwParam, (DWORD)lp16Parms);
+	break;
+    case MCI_DEVTYPE_SEQUENCER:
+	dwret = MIDI_DriverProc( 0, 0, MCI_OPEN_DRIVER, 
+				 dwParam, (DWORD)lp16Parms);
+	break;
+    case MCI_DEVTYPE_ANIMATION:
+	dwret = ANIM_DriverProc( 0, 0, MCI_OPEN_DRIVER, 
+				 dwParam, (DWORD)lp16Parms);
+	break;
+    case MCI_DEVTYPE_DIGITAL_VIDEO:
+	TRACE(mmsys, "No DIGITAL_VIDEO yet !\n");
+	return MCIERR_DEVICE_NOT_INSTALLED;
+    default:
+#if testing16
+	dwret = Callbacks->CallDriverProc(GetDrv(wDevID)->driverproc,0,GetDrv(wDevID)->hdrv,MCI_OPEN_DRIVER,dwParam,(DWORD)lp16Parms);
+	WARN(mmsys, "Invalid Device Name '%08lx' !\n", (DWORD)lpParms->lpstrDeviceType);
+#endif
+	return MCIERR_INVALID_DEVICE_NAME;
+    }
+    
+    
+    if (dwParam&MCI_NOTIFY)
+	mciDriverNotify(lpParms->dwCallback,wDevID,
+			(dwret==0?MCI_NOTIFY_SUCCESSFUL:MCI_NOTIFY_FAILURE));
+    
+    /* only handled devices fall through */
+    TRACE(mmsys, "wDevID = %04X wDeviceID = %d dwret = %ld\n",wDevID, lpParms->wDeviceID, dwret);
+    return dwret;
 }
 
 /**************************************************************************
  * 			mciGetDriverData			[MMSYSTEM.708]
  */
-DWORD WINAPI mciGetDriverData16(HDRVR16 hdrv) {
-        FIXME(mmsys,"(%04x): stub!\n",hdrv);
-	return 0x42;
+DWORD WINAPI mciGetDriverData16(HDRVR16 hdrv) 
+{
+    FIXME(mmsys,"(%04x): stub!\n",hdrv);
+    return 0x42;
 }
 
 /**************************************************************************
  * 			mciSetDriverData			[MMSYSTEM.707]
  */
-DWORD WINAPI mciSetDriverData16(HDRVR16 hdrv,DWORD data) {
-	FIXME(mmsys,"(%04x,%08lx): stub!\n",hdrv,data);
-	return 0;
+DWORD WINAPI mciSetDriverData16(HDRVR16 hdrv,DWORD data) 
+{
+    FIXME(mmsys,"(%04x,%08lx): stub!\n",hdrv,data);
+    return 0;
 }
 
 /**************************************************************************
@@ -1482,46 +1496,49 @@
  */
 DWORD mciClose(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
 {
-	DWORD	dwRet = MCIERR_INTERNAL;
-
-	TRACE(mmsys, "(%04x, %08lX, %p)\n", wDevID, dwParam, lpParms);
-	if(wDevID==MCI_ALL_DEVICE_ID) {
-	  FIXME(mmsys, "unhandled MCI_ALL_DEVICE_ID\n");
-	  return MCIERR_CANNOT_USE_ALL;
-	}
-	switch(GetDrv(wDevID)->modp.wType) {
-	case MCI_DEVTYPE_CD_AUDIO:
-		dwRet = CDAUDIO_DriverProc(GetDrv(wDevID)->modp.wDeviceID,0,
+    DWORD	dwRet = MCIERR_INTERNAL;
+    
+    TRACE(mmsys, "(%04x, %08lX, %p)\n", wDevID, dwParam, lpParms);
+    if(wDevID==MCI_ALL_DEVICE_ID) {
+	FIXME(mmsys, "unhandled MCI_ALL_DEVICE_ID\n");
+	return MCIERR_CANNOT_USE_ALL;
+    }
+    switch(GetDrv(wDevID)->modp.wType) {
+    case MCI_DEVTYPE_CD_AUDIO:
+	dwRet = CDAUDIO_DriverProc(GetDrv(wDevID)->modp.wDeviceID,0,
 				   MCI_CLOSE, dwParam, (DWORD)lpParms);
-		break;
-	case MCI_DEVTYPE_WAVEFORM_AUDIO:
-		dwRet = WAVE_DriverProc(GetDrv(wDevID)->modp.wDeviceID, 0, 
-					MCI_CLOSE, dwParam,
-					(DWORD)lpParms);
-		break;
-	case MCI_DEVTYPE_SEQUENCER:
-		dwRet = MIDI_DriverProc(GetDrv(wDevID)->modp.wDeviceID, 0, 
-					MCI_CLOSE, dwParam,
-					(DWORD)lpParms);
-		break;
+	break;
+    case MCI_DEVTYPE_WAVEFORM_AUDIO:
+	dwRet = WAVE_DriverProc(GetDrv(wDevID)->modp.wDeviceID, 0, 
+				MCI_CLOSE, dwParam,
+				(DWORD)lpParms);
+	break;
+    case MCI_DEVTYPE_SEQUENCER:
+	dwRet = MIDI_DriverProc(GetDrv(wDevID)->modp.wDeviceID, 0, 
+				MCI_CLOSE, dwParam,
+				(DWORD)lpParms);
+	break;
 	/*
-	case MCI_DEVTYPE_ANIMATION:
-		dwRet = ANIM_DriverProc(GetDrv(wDevID)->modp.wDeviceID, 0, 
-					MCI_CLOSE, dwParam,
-					(DWORD)lpParms);
-		break;
-	 */
-	default:
-		dwRet = Callbacks->CallDriverProc(GetDrv(wDevID)->driverproc,GetDrv(wDevID)->modp.wDeviceID,GetDrv(wDevID)->hdrv,MCI_CLOSE,dwParam,(DWORD)lpParms);
-	}
-	GetDrv(wDevID)->modp.wType = 0;
-
-	if (dwParam&MCI_NOTIFY)
-	  mciDriverNotify(lpParms->dwCallback,wDevID,
-			  (dwRet==0?MCI_NOTIFY_SUCCESSFUL:MCI_NOTIFY_FAILURE));
-
-	TRACE(mmsys, "returns %ld\n",dwRet);
-	return dwRet;
+	  case MCI_DEVTYPE_ANIMATION:
+	  dwRet = ANIM_DriverProc(GetDrv(wDevID)->modp.wDeviceID, 0, 
+	  MCI_CLOSE, dwParam,
+	  (DWORD)lpParms);
+	  break;
+	*/
+    default:
+	dwRet = Callbacks->CallDriverProc(GetDrv(wDevID)->driverproc,
+					  GetDrv(wDevID)->modp.wDeviceID,
+					  GetDrv(wDevID)->hdrv,MCI_CLOSE,dwParam,
+					  (DWORD)lpParms);
+    }
+    GetDrv(wDevID)->modp.wType = 0;
+    
+    if (dwParam&MCI_NOTIFY)
+	mciDriverNotify(lpParms->dwCallback,wDevID,
+			(dwRet==0?MCI_NOTIFY_SUCCESSFUL:MCI_NOTIFY_FAILURE));
+    
+    TRACE(mmsys, "returns %ld\n",dwRet);
+    return dwRet;
 }
 
 
@@ -1530,47 +1547,48 @@
  */
 DWORD mciSysInfo(DWORD dwFlags, LPMCI_SYSINFO_PARMS16 lpParms)
 {
-	int	len;
-	LPSTR	ptr;
-	LPSTR	lpstrReturn;
-	DWORD	*lpdwRet;
-	LPSTR	SysFile = "SYSTEM.INI";
-	TRACE(mci, "(%08lX, %08lX)\n", dwFlags, (DWORD)lpParms);
-	lpstrReturn = PTR_SEG_TO_LIN(lpParms->lpstrReturn);
-	switch(dwFlags) {
-	case MCI_SYSINFO_QUANTITY:
-		TRACE(mci, "MCI_SYSINFO_QUANTITY \n");
-		lpdwRet = (DWORD *)lpstrReturn;
-		*(lpdwRet) = InstalledCount;
-		return 0;
-	case MCI_SYSINFO_INSTALLNAME:
-		TRACE(mci, "MCI_SYSINFO_INSTALLNAME \n");
-		if (lpInstallNames == NULL) {
-			InstalledCount = 0;
-			InstalledListLen = 0;
-			ptr = lpInstallNames = xmalloc(2048);
-			GetPrivateProfileString32A("mci", NULL, "", lpInstallNames, 2000, SysFile);
-			while(strlen(ptr) > 0) {
-				TRACE(mci, "---> '%s' \n", ptr);
-				len = strlen(ptr) + 1;
-				ptr += len;
-				InstalledListLen += len;
-				InstalledCount++;
-			}
-		}
-		if (lpParms->dwRetSize < InstalledListLen)
-			lstrcpyn32A(lpstrReturn, lpInstallNames, lpParms->dwRetSize - 1);
-		else
-			strcpy(lpstrReturn, lpInstallNames);
-		return 0;
-	case MCI_SYSINFO_NAME:
-		TRACE(mci, "MCI_SYSINFO_NAME \n");
-		return 0;
-	case MCI_SYSINFO_OPEN:
-		TRACE(mci, "MCI_SYSINFO_OPEN \n");
-		return 0;
+    int		len;
+    LPSTR	ptr;
+    LPSTR	lpstrReturn;
+    DWORD	*lpdwRet;
+    LPSTR	SysFile = "SYSTEM.INI";
+    
+    TRACE(mci, "(%08lX, %08lX)\n", dwFlags, (DWORD)lpParms);
+    lpstrReturn = PTR_SEG_TO_LIN(lpParms->lpstrReturn);
+    switch(dwFlags) {
+    case MCI_SYSINFO_QUANTITY:
+	TRACE(mci, "MCI_SYSINFO_QUANTITY \n");
+	lpdwRet = (DWORD *)lpstrReturn;
+	*(lpdwRet) = InstalledCount;
+	return 0;
+    case MCI_SYSINFO_INSTALLNAME:
+	TRACE(mci, "MCI_SYSINFO_INSTALLNAME \n");
+	if (lpInstallNames == NULL) {
+	    InstalledCount = 0;
+	    InstalledListLen = 0;
+	    ptr = lpInstallNames = xmalloc(2048);
+	    GetPrivateProfileString32A("mci", NULL, "", lpInstallNames, 2000, SysFile);
+	    while(strlen(ptr) > 0) {
+		TRACE(mci, "---> '%s' \n", ptr);
+		len = strlen(ptr) + 1;
+		ptr += len;
+		InstalledListLen += len;
+		InstalledCount++;
+	    }
 	}
-	return MMSYSERR_INVALPARAM;
+	if (lpParms->dwRetSize < InstalledListLen)
+	    lstrcpyn32A(lpstrReturn, lpInstallNames, lpParms->dwRetSize - 1);
+	else
+	    strcpy(lpstrReturn, lpInstallNames);
+	return 0;
+    case MCI_SYSINFO_NAME:
+	TRACE(mci, "MCI_SYSINFO_NAME \n");
+	return 0;
+    case MCI_SYSINFO_OPEN:
+	TRACE(mci, "MCI_SYSINFO_OPEN \n");
+	return 0;
+    }
+    return MMSYSERR_INVALPARAM;
 }
 
 /**************************************************************************
@@ -1578,133 +1596,134 @@
  */
 UINT16 WINAPI mciLoadCommandResource16(HANDLE16 hinst,LPCSTR resname,UINT16 type)
 {
-      char            buf[200];
-      OFSTRUCT        ofs;
-      HANDLE16        xhinst;
-      HRSRC16         hrsrc;
-      HGLOBAL16       hmem;
-      LPSTR           segstr;
-      SEGPTR          xmem;
-      LPBYTE          lmem;
-      static UINT16   mcidevtype = 0;
-
-      FIXME(mmsys,"(%04x,%s,%d): stub!\n",hinst,resname,type);
-      if (!lstrcmpi32A(resname,"core")) {
-              FIXME(mmsys,"(...,\"core\",...), have to use internal tables... (not there yet)\n");
-              return 0;
-      }
-      /* if file exists "resname.mci", then load resource "resname" from it
-       * otherwise directly from driver
-       */
-      strcpy(buf,resname);
-      strcat(buf,".mci");
-      if (OpenFile32(buf,&ofs,OF_EXIST)!=HFILE_ERROR32) {
-              xhinst = LoadLibrary16(buf);
-              if (xhinst >32)
-                      hinst = xhinst;
-      } /* else use passed hinst */
-      segstr = SEGPTR_STRDUP(resname);
-      hrsrc = FindResource16(hinst,SEGPTR_GET(segstr),type);
-      SEGPTR_FREE(segstr);
-      if (!hrsrc) {
-              WARN(mmsys,"no special commandlist found in resource\n");
-              return MCI_NO_COMMAND_TABLE;
-      }
-      hmem = LoadResource16(hinst,hrsrc);
-      if (!hmem) {
-              WARN(mmsys,"couldn't load resource??\n");
-              return MCI_NO_COMMAND_TABLE;
-      }
-      xmem = WIN16_LockResource16(hmem);
-      if (!xmem) {
-              WARN(mmsys,"couldn't lock resource??\n");
-              FreeResource16(hmem);
-              return MCI_NO_COMMAND_TABLE;
-      }
-      lmem = PTR_SEG_TO_LIN(xmem);
-      TRACE(mmsys,"first resource entry is %s\n",(char*)lmem);
-      /* parse resource, register stuff, return unique id */
-      return ++mcidevtype;
+    char            buf[200];
+    OFSTRUCT        ofs;
+    HANDLE16        xhinst;
+    HRSRC16         hrsrc;
+    HGLOBAL16       hmem;
+    LPSTR           segstr;
+    SEGPTR          xmem;
+    LPBYTE          lmem;
+    static UINT16   mcidevtype = 0;
+    
+    FIXME(mmsys,"(%04x,%s,%d): stub!\n",hinst,resname,type);
+    if (!lstrcmpi32A(resname,"core")) {
+	FIXME(mmsys,"(...,\"core\",...), have to use internal tables... (not there yet)\n");
+	return 0;
+    }
+    /* if file exists "resname.mci", then load resource "resname" from it
+     * otherwise directly from driver
+     */
+    strcpy(buf,resname);
+    strcat(buf,".mci");
+    if (OpenFile32(buf,&ofs,OF_EXIST)!=HFILE_ERROR32) {
+	xhinst = LoadLibrary16(buf);
+	if (xhinst >32)
+	    hinst = xhinst;
+    } /* else use passed hinst */
+    segstr = SEGPTR_STRDUP(resname);
+    hrsrc = FindResource16(hinst,SEGPTR_GET(segstr),type);
+    SEGPTR_FREE(segstr);
+    if (!hrsrc) {
+	WARN(mmsys,"no special commandlist found in resource\n");
+	return MCI_NO_COMMAND_TABLE;
+    }
+    hmem = LoadResource16(hinst,hrsrc);
+    if (!hmem) {
+	WARN(mmsys,"couldn't load resource??\n");
+	return MCI_NO_COMMAND_TABLE;
+    }
+    xmem = WIN16_LockResource16(hmem);
+    if (!xmem) {
+	WARN(mmsys,"couldn't lock resource??\n");
+	FreeResource16(hmem);
+	return MCI_NO_COMMAND_TABLE;
+    }
+    lmem = PTR_SEG_TO_LIN(xmem);
+    TRACE(mmsys,"first resource entry is %s\n",(char*)lmem);
+    /* parse resource, register stuff, return unique id */
+    return ++mcidevtype;
 }
 
 
 /**************************************************************************
  * 			mciSound				[internal]
  *  not used anymore ??
-
-DWORD mciSound(UINT16 wDevID, DWORD dwParam, LPMCI_SOUND_PARMS lpParms)
-{
-	if (lpParms == NULL) return MCIERR_INTERNAL;
-	if (dwParam & MCI_SOUND_NAME)
-		TRACE(mci, "file='%s' !\n", lpParms->lpstrSoundName);
-	return MCIERR_INVALID_DEVICE_ID;
-}
+ 
+ DWORD mciSound(UINT16 wDevID, DWORD dwParam, LPMCI_SOUND_PARMS lpParms)
+ {
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ if (dwParam & MCI_SOUND_NAME)
+ TRACE(mci, "file='%s' !\n", lpParms->lpstrSoundName);
+ return MCIERR_INVALID_DEVICE_ID;
+ }
  *
  */
 
 static const char *_mciCommandToString(UINT16 wMsg)
 {
-	static char buffer[100];
-
+    static char buffer[100];
+    
 #define CASE(s) case (s): return #s
-
-	switch (wMsg) {
-		CASE(MCI_OPEN);
-		CASE(MCI_CLOSE);
-		CASE(MCI_ESCAPE);
-		CASE(MCI_PLAY);
-		CASE(MCI_SEEK);
-		CASE(MCI_STOP);
-		CASE(MCI_PAUSE);
-		CASE(MCI_INFO);
-		CASE(MCI_GETDEVCAPS);
-		CASE(MCI_SPIN);
-		CASE(MCI_SET);
-		CASE(MCI_STEP);
-		CASE(MCI_RECORD);
-		CASE(MCI_SYSINFO);
-		CASE(MCI_BREAK);
-		CASE(MCI_SAVE);
-		CASE(MCI_STATUS);
-		CASE(MCI_CUE);
-		CASE(MCI_REALIZE);
-		CASE(MCI_WINDOW);
-		CASE(MCI_PUT);
-		CASE(MCI_WHERE);
-		CASE(MCI_FREEZE);
-		CASE(MCI_UNFREEZE);
-		CASE(MCI_LOAD);
-		CASE(MCI_CUT);
-		CASE(MCI_COPY);
-		CASE(MCI_PASTE);
-		CASE(MCI_UPDATE);
-		CASE(MCI_RESUME);
-		CASE(MCI_DELETE);
-		default:
-			sprintf(buffer, "%04X", wMsg);
-			return buffer;
-
-	}
+    
+    switch (wMsg) {
+	CASE(MCI_OPEN);
+	CASE(MCI_CLOSE);
+	CASE(MCI_ESCAPE);
+	CASE(MCI_PLAY);
+	CASE(MCI_SEEK);
+	CASE(MCI_STOP);
+	CASE(MCI_PAUSE);
+	CASE(MCI_INFO);
+	CASE(MCI_GETDEVCAPS);
+	CASE(MCI_SPIN);
+	CASE(MCI_SET);
+	CASE(MCI_STEP);
+	CASE(MCI_RECORD);
+	CASE(MCI_SYSINFO);
+	CASE(MCI_BREAK);
+	CASE(MCI_SAVE);
+	CASE(MCI_STATUS);
+	CASE(MCI_CUE);
+	CASE(MCI_REALIZE);
+	CASE(MCI_WINDOW);
+	CASE(MCI_PUT);
+	CASE(MCI_WHERE);
+	CASE(MCI_FREEZE);
+	CASE(MCI_UNFREEZE);
+	CASE(MCI_LOAD);
+	CASE(MCI_CUT);
+	CASE(MCI_COPY);
+	CASE(MCI_PASTE);
+	CASE(MCI_UPDATE);
+	CASE(MCI_RESUME);
+	CASE(MCI_DELETE);
+    default:
+	sprintf(buffer, "%04X", wMsg);
+	return buffer;
+	
+    }
 }
 
 /**************************************************************************
  * 				mciSendCommandA			[WINMM.49]
  */
 DWORD WINAPI mciSendCommand32A(UINT32 wDevID, UINT32 wMsg, DWORD dwParam1,
-                            DWORD dwParam2)
+			       DWORD dwParam2)
 {
-    FIXME(mmsys,"(%08x,%s,%08lx,%08lx): stub!\n",
+    FIXME(mmsys,"(0x%08x,%s,%08lx,%08lx): stub \n",
 	  wDevID,_mciCommandToString(wMsg),dwParam1,dwParam2);
     switch (wMsg) {
-    case MCI_OPEN: {
-    	LPMCI_OPEN_PARMS32A	lpmop = (LPMCI_OPEN_PARMS32A)dwParam2;
-    	TRACE(mmsys,"	MCI_OPEN(%s,%s,%s)\n",
-	      (dwParam1&MCI_OPEN_TYPE)   ?lpmop->lpstrDeviceType:"<null>",
-	      (dwParam1&MCI_OPEN_ELEMENT)?(HIWORD(lpmop->lpstrElementName)?lpmop->lpstrElementName:"<id>"):"<null>",
-	      (dwParam1&MCI_OPEN_ALIAS)  ?lpmop->lpstrAlias:"<null>"
-	);
-	break;
-    }
+    case MCI_OPEN: 
+	{
+	    LPMCI_OPEN_PARMS32A	lpmop = (LPMCI_OPEN_PARMS32A)dwParam2;
+	    TRACE(mmsys,"	MCI_OPEN(%s,%s,%s)\n",
+		  (dwParam1&MCI_OPEN_TYPE)   ?lpmop->lpstrDeviceType:"<null>",
+		  (dwParam1&MCI_OPEN_ELEMENT)?(HIWORD(lpmop->lpstrElementName)?lpmop->lpstrElementName:"<id>"):"<null>",
+		  (dwParam1&MCI_OPEN_ALIAS)  ?lpmop->lpstrAlias:"<null>"
+		  );
+	    break;
+	}
     }
     return 0x1; /* !ok */
 }
@@ -1716,77 +1735,78 @@
 {
     HDRVR16 hDrv = 0;
     TRACE(mci, "(%04X, %s, %08lX, %08lX)\n", 
-                wDevID, _mciCommandToString(wMsg), dwParam1, dwParam2);
-    switch(wMsg)
-    {
+	  wDevID, _mciCommandToString(wMsg), dwParam1, dwParam2);
+    switch(wMsg) {
     case MCI_OPEN:
-        return mciOpen(dwParam1, (LPMCI_OPEN_PARMS16)dwParam2);
+	return mciOpen(dwParam1, (LPMCI_OPEN_PARMS16)dwParam2);
     case MCI_CLOSE:
-        return mciClose( wDevID, dwParam1,
-                         (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
+	return mciClose( wDevID, dwParam1,
+			 (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
     case MCI_SYSINFO:
-        return mciSysInfo( dwParam1,
-                           (LPMCI_SYSINFO_PARMS16)PTR_SEG_TO_LIN(dwParam2));
+	return mciSysInfo( dwParam1,
+			   (LPMCI_SYSINFO_PARMS16)PTR_SEG_TO_LIN(dwParam2));
     default:
-        switch(GetDrv(wDevID)->modp.wType)
-        {
-        case MCI_DEVTYPE_CD_AUDIO:
-            return CDAUDIO_DriverProc(GetDrv(wDevID)->modp.wDeviceID, hDrv, 
-                                      wMsg, dwParam1, dwParam2);
-        case MCI_DEVTYPE_WAVEFORM_AUDIO:
-            return WAVE_DriverProc(GetDrv(wDevID)->modp.wDeviceID, hDrv, 
-                                   wMsg, dwParam1, dwParam2);
-        case MCI_DEVTYPE_SEQUENCER:
-            return MIDI_DriverProc(GetDrv(wDevID)->modp.wDeviceID, hDrv, 
-                                   wMsg, dwParam1, dwParam2);
-	/*
-        case MCI_DEVTYPE_ANIMATION:
-            return ANIM_DriverProc(GetDrv(wDevID)->modp.wDeviceID, hDrv, 
-                                   wMsg, dwParam1, dwParam2);
- 	 */
-        default:
-	    return Callbacks->CallDriverProc(GetDrv(wDevID)->driverproc,GetDrv(wDevID)->modp.wDeviceID,GetDrv(wDevID)->hdrv,MCI_CLOSE,dwParam1,dwParam2);
-
-            WARN(mci, "unknown device type=%04X !\n", 
-			 GetDrv(wDevID)->modp.wType);
-        }
+	switch(GetDrv(wDevID)->modp.wType) {
+	case MCI_DEVTYPE_CD_AUDIO:
+	    return CDAUDIO_DriverProc(GetDrv(wDevID)->modp.wDeviceID, hDrv, 
+				      wMsg, dwParam1, dwParam2);
+	case MCI_DEVTYPE_WAVEFORM_AUDIO:
+	    return WAVE_DriverProc(GetDrv(wDevID)->modp.wDeviceID, hDrv, 
+				   wMsg, dwParam1, dwParam2);
+	case MCI_DEVTYPE_SEQUENCER:
+	    return MIDI_DriverProc(GetDrv(wDevID)->modp.wDeviceID, hDrv, 
+				   wMsg, dwParam1, dwParam2);
+	    /*
+	      case MCI_DEVTYPE_ANIMATION:
+	      return ANIM_DriverProc(GetDrv(wDevID)->modp.wDeviceID, hDrv, 
+	      wMsg, dwParam1, dwParam2);
+	    */
+	default:
+	    return Callbacks->CallDriverProc(GetDrv(wDevID)->driverproc,
+					     GetDrv(wDevID)->modp.wDeviceID,
+					     GetDrv(wDevID)->hdrv,
+					     MCI_CLOSE,dwParam1,dwParam2);
+	    
+	    WARN(mci, "unknown device type=%04X !\n", 
+		 GetDrv(wDevID)->modp.wType);
+	}
     }
     return MMSYSERR_INVALPARAM;
 }
 
 /**************************************************************************
-* 				mciGetDeviceID	       	[MMSYSTEM.703]
-*/
+ * 				mciGetDeviceID	       	[MMSYSTEM.703]
+ */
 UINT16 WINAPI mciGetDeviceID (LPCSTR lpstrName)
 {
     UINT16 wDevID;
-
+    
     TRACE(mci, "(\"%s\")\n", lpstrName);
     if (lpstrName && !lstrcmpi32A(lpstrName, "ALL"))
-        return MCI_ALL_DEVICE_ID;
-
+	return MCI_ALL_DEVICE_ID;
+    
     if (!lpstrName)
 	return 0;
-
+    
     wDevID = MMSYSTEM_FirstDevID();
     while(MMSYSTEM_DevIDValid(wDevID) && GetDrv(wDevID)->modp.wType) {
 	if (GetOpenDrv(wDevID)->lpstrDeviceType && 
-            strcmp(PTR_SEG_TO_LIN(GetOpenDrv(wDevID)->lpstrDeviceType), lpstrName) == 0)
+	    strcmp(PTR_SEG_TO_LIN(GetOpenDrv(wDevID)->lpstrDeviceType), lpstrName) == 0)
 	    return wDevID;
-
+	
 	if (GetOpenDrv(wDevID)->lpstrAlias && 
-            strcmp(PTR_SEG_TO_LIN(GetOpenDrv(wDevID)->lpstrAlias), lpstrName) == 0)
+	    strcmp(PTR_SEG_TO_LIN(GetOpenDrv(wDevID)->lpstrAlias), lpstrName) == 0)
 	    return wDevID;
-
+	
 	wDevID = MMSYSTEM_NextDevID(wDevID);
     }
-
+    
     return 0;
 }
 
 /**************************************************************************
-* 				mciSetYieldProc		[MMSYSTEM.714]
-*/
+ * 				mciSetYieldProc		[MMSYSTEM.714]
+ */
 BOOL16 WINAPI mciSetYieldProc (UINT16 uDeviceID, 
                                YIELDPROC fpYieldProc, DWORD dwYieldData)
 {
@@ -1794,24 +1814,24 @@
 }
 
 /**************************************************************************
-* 				mciGetDeviceIDFromElementID	[MMSYSTEM.715]
-*/
+ * 				mciGetDeviceIDFromElementID	[MMSYSTEM.715]
+ */
 UINT16 WINAPI mciGetDeviceIDFromElementID(DWORD dwElementID, LPCSTR lpstrType)
 {
     return 0;
 }
 
 /**************************************************************************
-* 				mciGetYieldProc		[MMSYSTEM.716]
-*/
+ * 				mciGetYieldProc		[MMSYSTEM.716]
+ */
 YIELDPROC WINAPI mciGetYieldProc(UINT16 uDeviceID, DWORD * lpdwYieldData)
 {
     return NULL;
 }
 
 /**************************************************************************
-* 				mciGetCreatorTask	[MMSYSTEM.717]
-*/
+ * 				mciGetCreatorTask	[MMSYSTEM.717]
+ */
 HTASK16 WINAPI mciGetCreatorTask(UINT16 uDeviceID)
 {
     return 0;
@@ -1822,18 +1842,18 @@
  */
 UINT32 WINAPI midiOutGetNumDevs32(void)
 {
-	return midiOutGetNumDevs16();
+    return midiOutGetNumDevs16();
 }
 /**************************************************************************
  * 				midiOutGetNumDevs	[MMSYSTEM.201]
  */
 UINT16 WINAPI midiOutGetNumDevs16(void)
 {
-	UINT16	count = 0;
-	TRACE(mmsys, "midiOutGetNumDevs\n");
-	count += modMessage(0, MODM_GETNUMDEVS, 0L, 0L, 0L);
-	TRACE(mmsys, "midiOutGetNumDevs return %u \n", count);
-	return count;
+    UINT16	count = 0;
+    TRACE(mmsys, "midiOutGetNumDevs\n");
+    count += modMessage(0, MODM_GETNUMDEVS, 0L, 0L, 0L);
+    TRACE(mmsys, "midiOutGetNumDevs return %u \n", count);
+    return count;
 }
 
 /**************************************************************************
@@ -1841,40 +1861,40 @@
  */
 UINT32 WINAPI midiOutGetDevCaps32W(UINT32 uDeviceID,LPMIDIOUTCAPS32W lpCaps, UINT32 uSize)
 {
-	MIDIOUTCAPS16	moc16;
-	UINT32		ret;
-
-	ret = midiOutGetDevCaps16(uDeviceID,&moc16,sizeof(moc16));
-	lpCaps->wMid		= moc16.wMid;
-	lpCaps->wPid		= moc16.wPid;
-	lpCaps->vDriverVersion	= moc16.vDriverVersion;
-	lstrcpyAtoW(lpCaps->szPname,moc16.szPname);
-	lpCaps->wTechnology	= moc16.wTechnology;
-	lpCaps->wVoices		= moc16.wVoices;
-	lpCaps->wNotes		= moc16.wNotes;
-	lpCaps->wChannelMask	= moc16.wChannelMask;
-	lpCaps->dwSupport	= moc16.dwSupport;
-	return ret;
+    MIDIOUTCAPS16	moc16;
+    UINT32		ret;
+    
+    ret = midiOutGetDevCaps16(uDeviceID,&moc16,sizeof(moc16));
+    lpCaps->wMid		= moc16.wMid;
+    lpCaps->wPid		= moc16.wPid;
+    lpCaps->vDriverVersion	= moc16.vDriverVersion;
+    lstrcpyAtoW(lpCaps->szPname,moc16.szPname);
+    lpCaps->wTechnology	= moc16.wTechnology;
+    lpCaps->wVoices		= moc16.wVoices;
+    lpCaps->wNotes		= moc16.wNotes;
+    lpCaps->wChannelMask	= moc16.wChannelMask;
+    lpCaps->dwSupport	= moc16.dwSupport;
+    return ret;
 }
 /**************************************************************************
  * 				midiOutGetDevCapsA	[WINMM.75]
  */
 UINT32 WINAPI midiOutGetDevCaps32A(UINT32 uDeviceID,LPMIDIOUTCAPS32A lpCaps, UINT32 uSize)
 {
-	MIDIOUTCAPS16	moc16;
-	UINT32		ret;
-
-	ret = midiOutGetDevCaps16(uDeviceID,&moc16,sizeof(moc16));
-	lpCaps->wMid		= moc16.wMid;
-	lpCaps->wPid		= moc16.wPid;
-	lpCaps->vDriverVersion	= moc16.vDriverVersion;
-	strcpy(lpCaps->szPname,moc16.szPname);
-	lpCaps->wTechnology	= moc16.wTechnology;
-	lpCaps->wVoices		= moc16.wVoices;
-	lpCaps->wNotes		= moc16.wNotes;
-	lpCaps->wChannelMask	= moc16.wChannelMask;
-	lpCaps->dwSupport	= moc16.dwSupport;
-	return ret;
+    MIDIOUTCAPS16	moc16;
+    UINT32		ret;
+    
+    ret = midiOutGetDevCaps16(uDeviceID,&moc16,sizeof(moc16));
+    lpCaps->wMid		= moc16.wMid;
+    lpCaps->wPid		= moc16.wPid;
+    lpCaps->vDriverVersion	= moc16.vDriverVersion;
+    strcpy(lpCaps->szPname,moc16.szPname);
+    lpCaps->wTechnology	= moc16.wTechnology;
+    lpCaps->wVoices		= moc16.wVoices;
+    lpCaps->wNotes		= moc16.wNotes;
+    lpCaps->wChannelMask	= moc16.wChannelMask;
+    lpCaps->dwSupport	= moc16.dwSupport;
+    return ret;
 }
 
 /**************************************************************************
@@ -1882,8 +1902,8 @@
  */
 UINT16 WINAPI midiOutGetDevCaps16(UINT16 uDeviceID,LPMIDIOUTCAPS16 lpCaps, UINT16 uSize)
 {
-	TRACE(mmsys, "midiOutGetDevCaps\n");
-	return modMessage(uDeviceID,MODM_GETDEVCAPS,0,(DWORD)lpCaps,uSize);
+    TRACE(mmsys, "midiOutGetDevCaps\n");
+    return modMessage(uDeviceID,MODM_GETDEVCAPS,0,(DWORD)lpCaps,uSize);
 }
 
 /**************************************************************************
@@ -1891,8 +1911,8 @@
  */
 UINT32 WINAPI midiOutGetErrorText32A(UINT32 uError, LPSTR lpText, UINT32 uSize)
 {
-	TRACE(mmsys, "midiOutGetErrorText\n");
-	return midiGetErrorText(uError, lpText, uSize);
+    TRACE(mmsys, "midiOutGetErrorText\n");
+    return midiGetErrorText(uError, lpText, uSize);
 }
 
 /**************************************************************************
@@ -1900,22 +1920,23 @@
  */
 UINT32 WINAPI midiOutGetErrorText32W(UINT32 uError, LPWSTR lpText, UINT32 uSize)
 {
-	LPSTR	xstr = HeapAlloc(GetProcessHeap(),0,uSize);
-	UINT32	ret;
-
-	TRACE(mmsys, "midiOutGetErrorText\n");
-	ret = midiGetErrorText(uError, xstr, uSize);
-	lstrcpyAtoW(lpText,xstr);
-	HeapFree(GetProcessHeap(),0,xstr);
-	return ret;
+    LPSTR	xstr = HeapAlloc(GetProcessHeap(),0,uSize);
+    UINT32	ret;
+    
+    TRACE(mmsys, "midiOutGetErrorText\n");
+    ret = midiGetErrorText(uError, xstr, uSize);
+    lstrcpyAtoW(lpText,xstr);
+    HeapFree(GetProcessHeap(),0,xstr);
+    return ret;
 }
+
 /**************************************************************************
  * 				midiOutGetErrorText 	[MMSYSTEM.203]
  */
 UINT16 WINAPI midiOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
 {
-        TRACE(mmsys, "midiOutGetErrorText\n");
-	return midiGetErrorText(uError, lpText, uSize);
+    TRACE(mmsys, "midiOutGetErrorText\n");
+    return midiGetErrorText(uError, lpText, uSize);
 }
 
 /**************************************************************************
@@ -1923,44 +1944,44 @@
  */
 UINT16 WINAPI midiGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize)
 {
-	LPSTR	msgptr;
-	if ((lpText == NULL) || (uSize < 1)) return(FALSE);
-	lpText[0] = '\0';
-	switch(uError) {
-		case MIDIERR_UNPREPARED:
-			msgptr = "The MIDI header was not prepared. Use the Prepare function to prepare the header, and then try again.";
-			break;
-		case MIDIERR_STILLPLAYING:
-			msgptr = "Cannot perform this operation while media data is still playing. Reset the device, or wait until the data is finished playing.";
-			break;
-		case MIDIERR_NOMAP:
-			msgptr = "A MIDI map was not found. There may be a problem with the driver, or the MIDIMAP.CFG file may be corrupt or missing.";
-			break;
-		case MIDIERR_NOTREADY:
-			msgptr = "The port is transmitting data to the device. Wait until the data has been transmitted, and then try again.";
-			break;
-		case MIDIERR_NODEVICE:
-			msgptr = "The current MIDI Mapper setup refers to a MIDI device that is not installed on the system. Use MIDI Mapper to edit the setup.";
-			break;
-		case MIDIERR_INVALIDSETUP:
-			msgptr = "The current MIDI setup is damaged. Copy the original MIDIMAP.CFG file to the Windows SYSTEM directory, and then try again.";
-			break;
-/*
-msg# 336 : Cannot use the song-pointer time format and the SMPTE time-format together.
-msg# 337 : The specified MIDI device is already in use. Wait until it is free, and then try again.
-msg# 338 : The specified MIDI device is not installed on the system. Use the Drivers option in Control Panel to install the driver.
-msg# 339 : The current MIDI Mapper setup refers to a MIDI device that is not installed on the system. Use MIDI Mapper to edit the setup.
-msg# 340 : An error occurred using the specified port.
-msg# 341 : All multimedia timers are being used by other applications. Quit one of these applications, and then try again.
-msg# 342 : There is no current MIDI port.
-msg# 343 : There are no MIDI devices installed on the system. Use the Drivers option in Control Panel to install the driver.
-*/
-		default:
-			msgptr = "Unknown MIDI Error !\n";
-			break;
-		}
-	lstrcpyn32A(lpText, msgptr, uSize);
-	return TRUE;
+    LPSTR	msgptr;
+    if ((lpText == NULL) || (uSize < 1)) return(FALSE);
+    lpText[0] = '\0';
+    switch(uError) {
+    case MIDIERR_UNPREPARED:
+	msgptr = "The MIDI header was not prepared. Use the Prepare function to prepare the header, and then try again.";
+	break;
+    case MIDIERR_STILLPLAYING:
+	msgptr = "Cannot perform this operation while media data is still playing. Reset the device, or wait until the data is finished playing.";
+	break;
+    case MIDIERR_NOMAP:
+	msgptr = "A MIDI map was not found. There may be a problem with the driver, or the MIDIMAP.CFG file may be corrupt or missing.";
+	break;
+    case MIDIERR_NOTREADY:
+	msgptr = "The port is transmitting data to the device. Wait until the data has been transmitted, and then try again.";
+	break;
+    case MIDIERR_NODEVICE:
+	msgptr = "The current MIDI Mapper setup refers to a MIDI device that is not installed on the system. Use MIDI Mapper to edit the setup.";
+	break;
+    case MIDIERR_INVALIDSETUP:
+	msgptr = "The current MIDI setup is damaged. Copy the original MIDIMAP.CFG file to the Windows SYSTEM directory, and then try again.";
+	break;
+	/*
+	  msg# 336 : Cannot use the song-pointer time format and the SMPTE time-format together.
+	  msg# 337 : The specified MIDI device is already in use. Wait until it is free, and then try again.
+	  msg# 338 : The specified MIDI device is not installed on the system. Use the Drivers option in Control Panel to install the driver.
+	  msg# 339 : The current MIDI Mapper setup refers to a MIDI device that is not installed on the system. Use MIDI Mapper to edit the setup.
+	  msg# 340 : An error occurred using the specified port.
+	  msg# 341 : All multimedia timers are being used by other applications. Quit one of these applications, and then try again.
+	  msg# 342 : There is no current MIDI port.
+	  msg# 343 : There are no MIDI devices installed on the system. Use the Drivers option in Control Panel to install the driver.
+	*/
+    default:
+	msgptr = "Unknown MIDI Error !\n";
+	break;
+    }
+    lstrcpyn32A(lpText, msgptr, uSize);
+    return TRUE;
 }
 
 /**************************************************************************
@@ -1969,49 +1990,54 @@
 UINT32 WINAPI midiOutOpen32(HMIDIOUT32 * lphMidiOut, UINT32 uDeviceID,
                             DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
 {
-	HMIDIOUT16	hmo16;
-	UINT32		ret;
-
-	ret = midiOutOpen16(&hmo16,uDeviceID,dwCallback,dwInstance,
-			    CALLBACK32CONV(dwFlags));
-	if (lphMidiOut) *lphMidiOut = hmo16;
-	return ret;
+    HMIDIOUT16	hmo16;
+    UINT32	ret;
+    
+    ret = midiOutOpen16(&hmo16,uDeviceID,dwCallback,dwInstance,
+			CALLBACK32CONV(dwFlags));
+    if (lphMidiOut) *lphMidiOut = hmo16;
+    return ret;
 }
+
 /**************************************************************************
  * 				midiOutOpen    		[MMSYSTEM.204]
  */
 UINT16 WINAPI midiOutOpen16(HMIDIOUT16 * lphMidiOut, UINT16 uDeviceID,
                             DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
 {
-	HMIDI16	hMidiOut;
-	LPMIDIOPENDESC	lpDesc;
-	DWORD	dwRet = 0;
-	BOOL32	bMapperFlg = FALSE;
-	if (lphMidiOut != NULL) *lphMidiOut = 0;
-	TRACE(mmsys, "(%p, %d, %08lX, %08lX, %08lX);\n", 
-		lphMidiOut, uDeviceID, dwCallback, dwInstance, dwFlags);
-	if (uDeviceID == (UINT16)MIDI_MAPPER) {
-		TRACE(mmsys, "MIDI_MAPPER mode requested !\n");
-		bMapperFlg = TRUE;
-		uDeviceID = 0;
-	}
-	hMidiOut = USER_HEAP_ALLOC(sizeof(MIDIOPENDESC));
-	if (lphMidiOut != NULL) *lphMidiOut = hMidiOut;
-	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
-	if (lpDesc == NULL)
-		return MMSYSERR_NOMEM;
-	lpDesc->hMidi = hMidiOut;
-	lpDesc->dwCallback = dwCallback;
-	lpDesc->dwInstance = dwInstance;
-	while(uDeviceID < MAXMIDIDRIVERS) {
-		dwRet = modMessage(uDeviceID, MODM_OPEN, 
-			lpDesc->dwInstance, (DWORD)lpDesc, 0L);
-		if (dwRet == MMSYSERR_NOERROR) break;
-		if (!bMapperFlg) break;
-		uDeviceID++;
-		TRACE(mmsys, "MIDI_MAPPER mode ! try next driver...\n");
-	}
-	return dwRet;
+    HMIDI16			hMidiOut;
+    LPMIDIOPENDESC		lpDesc;
+    DWORD			dwRet = 0;
+    BOOL32			bMapperFlg = FALSE;
+    
+    if (lphMidiOut != NULL) *lphMidiOut = 0;
+    TRACE(mmsys, "(%p, %d, %08lX, %08lX, %08lX);\n", 
+	  lphMidiOut, uDeviceID, dwCallback, dwInstance, dwFlags);
+    if (uDeviceID == (UINT16)MIDI_MAPPER) {
+	TRACE(mmsys, "MIDI_MAPPER mode requested !\n");
+	bMapperFlg = TRUE;
+	uDeviceID = 0;
+    }
+    hMidiOut = USER_HEAP_ALLOC(sizeof(MIDIOPENDESC));
+    if (lphMidiOut != NULL) 
+	*lphMidiOut = hMidiOut;
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
+    if (lpDesc == NULL)
+	return MMSYSERR_NOMEM;
+    lpDesc->hMidi = hMidiOut;
+    lpDesc->dwCallback = dwCallback;
+    lpDesc->dwInstance = dwInstance;
+    
+    while(uDeviceID < MAXMIDIDRIVERS) {
+	dwRet = modMessage(uDeviceID, MODM_OPEN, 
+			   lpDesc->dwInstance, (DWORD)lpDesc, dwFlags);
+	if (dwRet == MMSYSERR_NOERROR) break;
+	if (!bMapperFlg) break;
+	uDeviceID++;
+	TRACE(mmsys, "MIDI_MAPPER mode ! try next driver...\n");
+    }
+    lpDesc->wDevID = uDeviceID;
+    return dwRet;
 }
 
 /**************************************************************************
@@ -2019,7 +2045,7 @@
  */
 UINT32 WINAPI midiOutClose32(HMIDIOUT32 hMidiOut)
 {
-	return midiOutClose16(hMidiOut);
+    return midiOutClose16(hMidiOut);
 }
 
 /**************************************************************************
@@ -2027,11 +2053,11 @@
  */
 UINT16 WINAPI midiOutClose16(HMIDIOUT16 hMidiOut)
 {
-	LPMIDIOPENDESC	lpDesc;
-	TRACE(mmsys, "(%04X)\n", hMidiOut);
-	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return modMessage(0, MODM_CLOSE, lpDesc->dwInstance, 0L, 0L);
+    LPMIDIOPENDESC	lpDesc;
+    TRACE(mmsys, "(%04X)\n", hMidiOut);
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    return modMessage(lpDesc->wDevID, MODM_CLOSE, lpDesc->dwInstance, 0L, 0L);
 }
 
 /**************************************************************************
@@ -2040,7 +2066,14 @@
 UINT32 WINAPI midiOutPrepareHeader32(HMIDIOUT32 hMidiOut,
                                      MIDIHDR * lpMidiOutHdr, UINT32 uSize)
 {
-	return midiOutPrepareHeader16(hMidiOut,lpMidiOutHdr,uSize);
+    LPMIDIOPENDESC	lpDesc;
+    TRACE(mmsys, "(%04X, %p, %d)\n", 
+	  hMidiOut, lpMidiOutHdr, uSize);
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    lpMidiOutHdr->reserved = (DWORD)lpMidiOutHdr->lpData;
+    return modMessage(lpDesc->wDevID, MODM_PREPARE, lpDesc->dwInstance, 
+		      (DWORD)lpMidiOutHdr, (DWORD)uSize);
 }
 
 /**************************************************************************
@@ -2049,13 +2082,14 @@
 UINT16 WINAPI midiOutPrepareHeader16(HMIDIOUT16 hMidiOut,
                                      MIDIHDR * lpMidiOutHdr, UINT16 uSize)
 {
-	LPMIDIOPENDESC	lpDesc;
-	TRACE(mmsys, "(%04X, %p, %d)\n", 
-					hMidiOut, lpMidiOutHdr, uSize);
-	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return modMessage(0, MODM_PREPARE, lpDesc->dwInstance, 
-			  (DWORD)lpMidiOutHdr, (DWORD)uSize);
+    LPMIDIOPENDESC	lpDesc;
+    TRACE(mmsys, "(%04X, %p, %d)\n", 
+	  hMidiOut, lpMidiOutHdr, uSize);
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    lpMidiOutHdr->reserved = (DWORD)PTR_SEG_TO_LIN(lpMidiOutHdr->lpData);
+    return modMessage(lpDesc->wDevID, MODM_PREPARE, lpDesc->dwInstance, 
+		      (DWORD)lpMidiOutHdr, (DWORD)uSize);
 }
 
 /**************************************************************************
@@ -2064,21 +2098,22 @@
 UINT32 WINAPI midiOutUnprepareHeader32(HMIDIOUT32 hMidiOut,
                                        MIDIHDR * lpMidiOutHdr, UINT32 uSize)
 {
-	return midiOutUnprepareHeader16(hMidiOut,lpMidiOutHdr,uSize);
+    return midiOutUnprepareHeader16(hMidiOut,lpMidiOutHdr,uSize);
 }
+
 /**************************************************************************
  * 				midiOutUnprepareHeader	[MMSYSTEM.207]
  */
 UINT16 WINAPI midiOutUnprepareHeader16(HMIDIOUT16 hMidiOut,
-                                     MIDIHDR * lpMidiOutHdr, UINT16 uSize)
+				       MIDIHDR * lpMidiOutHdr, UINT16 uSize)
 {
-	LPMIDIOPENDESC	lpDesc;
-	TRACE(mmsys, "(%04X, %p, %d)\n", 
-					hMidiOut, lpMidiOutHdr, uSize);
-	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return modMessage(0, MODM_UNPREPARE, lpDesc->dwInstance, 
-						(DWORD)lpMidiOutHdr, (DWORD)uSize);
+    LPMIDIOPENDESC	lpDesc;
+    TRACE(mmsys, "(%04X, %p, %d)\n", 
+	  hMidiOut, lpMidiOutHdr, uSize);
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    return modMessage(lpDesc->wDevID, MODM_UNPREPARE, lpDesc->dwInstance, 
+		      (DWORD)lpMidiOutHdr, (DWORD)uSize);
 }
 
 /**************************************************************************
@@ -2086,18 +2121,19 @@
  */
 UINT32 WINAPI midiOutShortMsg32(HMIDIOUT32 hMidiOut, DWORD dwMsg)
 {
-	return midiOutShortMsg16(hMidiOut,dwMsg);
+    return midiOutShortMsg16(hMidiOut,dwMsg);
 }
+
 /**************************************************************************
  * 				midiOutShortMsg		[MMSYSTEM.208]
  */
 UINT16 WINAPI midiOutShortMsg16(HMIDIOUT16 hMidiOut, DWORD dwMsg)
 {
-	LPMIDIOPENDESC	lpDesc;
-	TRACE(mmsys, "(%04X, %08lX)\n", hMidiOut, dwMsg);
-	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return modMessage(0, MODM_DATA, lpDesc->dwInstance, dwMsg, 0L);
+    LPMIDIOPENDESC	lpDesc;
+    TRACE(mmsys, "(%04X, %08lX)\n", hMidiOut, dwMsg);
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    return modMessage(lpDesc->wDevID, MODM_DATA, lpDesc->dwInstance, dwMsg, 0L);
 }
 
 /**************************************************************************
@@ -2106,7 +2142,7 @@
 UINT32 WINAPI midiOutLongMsg32(HMIDIOUT32 hMidiOut,
                                MIDIHDR * lpMidiOutHdr, UINT32 uSize)
 {
-	return midiOutLongMsg16(hMidiOut,lpMidiOutHdr,uSize);
+    return midiOutLongMsg16(hMidiOut,lpMidiOutHdr,uSize);
 }
 
 /**************************************************************************
@@ -2115,13 +2151,13 @@
 UINT16 WINAPI midiOutLongMsg16(HMIDIOUT16 hMidiOut,
                                MIDIHDR * lpMidiOutHdr, UINT16 uSize)
 {
-	LPMIDIOPENDESC	lpDesc;
-	TRACE(mmsys, "(%04X, %p, %d)\n", 
-				hMidiOut, lpMidiOutHdr, uSize);
-	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return modMessage(0, MODM_LONGDATA, lpDesc->dwInstance, 
-						(DWORD)lpMidiOutHdr, (DWORD)uSize);
+    LPMIDIOPENDESC	lpDesc;
+    TRACE(mmsys, "(%04X, %p, %d)\n", 
+	  hMidiOut, lpMidiOutHdr, uSize);
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    return modMessage(lpDesc->wDevID, MODM_LONGDATA, lpDesc->dwInstance, 
+		      (DWORD)lpMidiOutHdr, (DWORD)uSize);
 }
 
 /**************************************************************************
@@ -2129,7 +2165,7 @@
  */
 UINT32 WINAPI midiOutReset32(HMIDIOUT32 hMidiOut)
 {
-	return midiOutReset16(hMidiOut);
+    return midiOutReset16(hMidiOut);
 }
 
 /**************************************************************************
@@ -2137,11 +2173,11 @@
  */
 UINT16 WINAPI midiOutReset16(HMIDIOUT16 hMidiOut)
 {
-	LPMIDIOPENDESC	lpDesc;
-	TRACE(mmsys, "(%04X)\n", hMidiOut);
-	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return modMessage(0, MODM_RESET, lpDesc->dwInstance, 0L, 0L);
+    LPMIDIOPENDESC	lpDesc;
+    TRACE(mmsys, "(%04X)\n", hMidiOut);
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    return modMessage(lpDesc->wDevID, MODM_RESET, lpDesc->dwInstance, 0L, 0L);
 }
 
 /**************************************************************************
@@ -2149,15 +2185,15 @@
  */
 UINT32 WINAPI midiOutGetVolume32(UINT32 uDeviceID, DWORD * lpdwVolume)
 {
-	return midiOutGetVolume16(uDeviceID,lpdwVolume);
+    return midiOutGetVolume16(uDeviceID,lpdwVolume);
 }
 /**************************************************************************
  * 				midiOutGetVolume	[MMSYSTEM.211]
  */
 UINT16 WINAPI midiOutGetVolume16(UINT16 uDeviceID, DWORD * lpdwVolume)
 {
-	TRACE(mmsys, "(%04X, %p);\n", uDeviceID, lpdwVolume);
-	return modMessage(uDeviceID, MODM_GETVOLUME, 0L, (DWORD)lpdwVolume, 0L);
+    TRACE(mmsys, "(%04X, %p);\n", uDeviceID, lpdwVolume);
+    return modMessage(uDeviceID, MODM_GETVOLUME, 0L, (DWORD)lpdwVolume, 0L);
 }
 
 /**************************************************************************
@@ -2165,7 +2201,7 @@
  */
 UINT32 WINAPI midiOutSetVolume32(UINT32 uDeviceID, DWORD dwVolume)
 {
-	return midiOutSetVolume16(uDeviceID,dwVolume);
+    return midiOutSetVolume16(uDeviceID,dwVolume);
 }
 
 /**************************************************************************
@@ -2173,8 +2209,8 @@
  */
 UINT16 WINAPI midiOutSetVolume16(UINT16 uDeviceID, DWORD dwVolume)
 {
-	TRACE(mmsys, "(%04X, %08lX);\n", uDeviceID, dwVolume);
-	return modMessage(uDeviceID, MODM_SETVOLUME, 0L, dwVolume, 0L);
+    TRACE(mmsys, "(%04X, %08lX);\n", uDeviceID, dwVolume);
+    return modMessage(uDeviceID, MODM_SETVOLUME, 0L, dwVolume, 0L);
 }
 
 /**************************************************************************
@@ -2183,7 +2219,7 @@
 UINT32 WINAPI midiOutCachePatches32(HMIDIOUT32 hMidiOut, UINT32 uBank,
                                     WORD * lpwPatchArray, UINT32 uFlags)
 {
-	return midiOutCachePatches16(hMidiOut,uBank,lpwPatchArray,uFlags);
+    return midiOutCachePatches16(hMidiOut,uBank,lpwPatchArray,uFlags);
 }
 
 /**************************************************************************
@@ -2192,9 +2228,9 @@
 UINT16 WINAPI midiOutCachePatches16(HMIDIOUT16 hMidiOut, UINT16 uBank,
                                     WORD * lpwPatchArray, UINT16 uFlags)
 {
-        /* not really necessary to support this */
-	FIXME(mmsys, "not supported yet\n");
-	return MMSYSERR_NOTSUPPORTED;
+    /* not really necessary to support this */
+    FIXME(mmsys, "not supported yet\n");
+    return MMSYSERR_NOTSUPPORTED;
 }
 
 /**************************************************************************
@@ -2203,7 +2239,7 @@
 UINT32 WINAPI midiOutCacheDrumPatches32(HMIDIOUT32 hMidiOut, UINT32 uPatch,
                                         WORD * lpwKeyArray, UINT32 uFlags)
 {
-	return midiOutCacheDrumPatches16(hMidiOut,uPatch,lpwKeyArray,uFlags);
+    return midiOutCacheDrumPatches16(hMidiOut,uPatch,lpwKeyArray,uFlags);
 }
 
 /**************************************************************************
@@ -2212,8 +2248,8 @@
 UINT16 WINAPI midiOutCacheDrumPatches16(HMIDIOUT16 hMidiOut, UINT16 uPatch,
                                         WORD * lpwKeyArray, UINT16 uFlags)
 {
-	FIXME(mmsys, "not supported yet\n");
-	return MMSYSERR_NOTSUPPORTED;
+    FIXME(mmsys, "not supported yet\n");
+    return MMSYSERR_NOTSUPPORTED;
 }
 
 /**************************************************************************
@@ -2221,12 +2257,12 @@
  */
 UINT32 WINAPI midiOutGetID32(HMIDIOUT32 hMidiOut, UINT32 * lpuDeviceID)
 {
-	UINT16	xid;
-	UINT32	ret;
-
-	ret = midiOutGetID16(hMidiOut,&xid);
-	*lpuDeviceID = xid;
-	return ret;
+    UINT16	xid;
+    UINT32	ret;
+    
+    ret = midiOutGetID16(hMidiOut,&xid);
+    *lpuDeviceID = xid;
+    return ret;
 }
 
 /**************************************************************************
@@ -2234,8 +2270,8 @@
  */
 UINT16 WINAPI midiOutGetID16(HMIDIOUT16 hMidiOut, UINT16 * lpuDeviceID)
 {
-	TRACE(mmsys, "midiOutGetID\n");
-	return 0;
+    TRACE(mmsys, "midiOutGetID\n");
+    return 0;
 }
 
 /**************************************************************************
@@ -2244,34 +2280,34 @@
 DWORD WINAPI midiOutMessage32(HMIDIOUT32 hMidiOut, UINT32 uMessage, 
                               DWORD dwParam1, DWORD dwParam2)
 {
-	LPMIDIOPENDESC	lpDesc;
-
-	TRACE(mmsys, "(%04X, %04X, %08lX, %08lX)\n", 
-			hMidiOut, uMessage, dwParam1, dwParam2);
-	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	switch (uMessage) {
-	case MODM_OPEN:
-		FIXME(mmsys,"can't handle MODM_OPEN!\n");
-		return 0;
-	case MODM_GETDEVCAPS:
-		return midiOutGetDevCaps32A(hMidiOut,(LPMIDIOUTCAPS32A)dwParam1,dwParam2);
-	case MODM_GETNUMDEVS:
-	case MODM_RESET:
-	case MODM_CLOSE:
-	case MODM_GETVOLUME:
-	case MODM_SETVOLUME:
-	case MODM_LONGDATA:
-	case MODM_PREPARE:
-	case MODM_UNPREPARE:
-		/* no argument conversion needed */
-		break;
-	default:
-	        ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
-		    hMidiOut,uMessage,dwParam1,dwParam2);
-		break;
-	}
-	return modMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
+    LPMIDIOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X, %04X, %08lX, %08lX)\n", 
+	  hMidiOut, uMessage, dwParam1, dwParam2);
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    switch (uMessage) {
+    case MODM_OPEN:
+	FIXME(mmsys,"can't handle MODM_OPEN!\n");
+	return 0;
+    case MODM_GETDEVCAPS:
+	return midiOutGetDevCaps32A(hMidiOut,(LPMIDIOUTCAPS32A)dwParam1,dwParam2);
+    case MODM_GETNUMDEVS:
+    case MODM_RESET:
+    case MODM_CLOSE:
+    case MODM_GETVOLUME:
+    case MODM_SETVOLUME:
+    case MODM_LONGDATA:
+    case MODM_PREPARE:
+    case MODM_UNPREPARE:
+	/* no argument conversion needed */
+	break;
+    default:
+	ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
+	    hMidiOut,uMessage,dwParam1,dwParam2);
+	break;
+    }
+    return modMessage(lpDesc->wDevID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
 }
 
 /**************************************************************************
@@ -2280,36 +2316,36 @@
 DWORD WINAPI midiOutMessage16(HMIDIOUT16 hMidiOut, UINT16 uMessage, 
                               DWORD dwParam1, DWORD dwParam2)
 {
-	LPMIDIOPENDESC	lpDesc;
-
-	TRACE(mmsys, "(%04X, %04X, %08lX, %08lX)\n", 
-			hMidiOut, uMessage, dwParam1, dwParam2);
-	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	switch (uMessage) {
-	case MODM_OPEN:
-		FIXME(mmsys,"can't handle MODM_OPEN!\n");
-		return 0;
-	case MODM_GETNUMDEVS:
-	case MODM_RESET:
-	case MODM_CLOSE:
-	case MODM_SETVOLUME:
-		/* no argument conversion needed */
-		break;
-	case MODM_GETVOLUME:
-		return midiOutGetVolume16(hMidiOut,(LPDWORD)PTR_SEG_TO_LIN(dwParam1));
-	case MODM_LONGDATA:
-		return midiOutLongMsg16(hMidiOut,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
-	case MODM_PREPARE:
-		return midiOutPrepareHeader16(hMidiOut,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
-	case MODM_UNPREPARE:
-		return midiOutUnprepareHeader16(hMidiOut,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
-	default:
-		ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
-		    hMidiOut,uMessage,dwParam1,dwParam2);
-		break;
-	}
-	return modMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
+    LPMIDIOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X, %04X, %08lX, %08lX)\n", 
+	  hMidiOut, uMessage, dwParam1, dwParam2);
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    switch (uMessage) {
+    case MODM_OPEN:
+	FIXME(mmsys,"can't handle MODM_OPEN!\n");
+	return 0;
+    case MODM_GETNUMDEVS:
+    case MODM_RESET:
+    case MODM_CLOSE:
+    case MODM_SETVOLUME:
+	/* no argument conversion needed */
+	break;
+    case MODM_GETVOLUME:
+	return midiOutGetVolume16(hMidiOut,(LPDWORD)PTR_SEG_TO_LIN(dwParam1));
+    case MODM_LONGDATA:
+	return midiOutLongMsg16(hMidiOut,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+    case MODM_PREPARE:
+	return midiOutPrepareHeader16(hMidiOut,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+    case MODM_UNPREPARE:
+	return midiOutUnprepareHeader16(hMidiOut,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+    default:
+	ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
+	    hMidiOut,uMessage,dwParam1,dwParam2);
+	break;
+    }
+    return modMessage(lpDesc->wDevID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
 }
 
 /**************************************************************************
@@ -2317,7 +2353,7 @@
  */
 UINT32 WINAPI midiInGetNumDevs32(void)
 {
-	return midiInGetNumDevs16();
+    return midiInGetNumDevs16();
 }
 
 /**************************************************************************
@@ -2325,11 +2361,11 @@
  */
 UINT16 WINAPI midiInGetNumDevs16(void)
 {
-	UINT16	count = 0;
-	TRACE(mmsys, "midiInGetNumDevs\n");
-	count += midMessage(0, MIDM_GETNUMDEVS, 0L, 0L, 0L);
-	TRACE(mmsys, "midiInGetNumDevs return %u \n", count);
-	return count;
+    UINT16	count = 0;
+    TRACE(mmsys, "midiInGetNumDevs\n");
+    count += midMessage(0, MIDM_GETNUMDEVS, 0L, 0L, 0L);
+    TRACE(mmsys, "midiInGetNumDevs return %u \n", count);
+    return count;
 }
 
 /**************************************************************************
@@ -2338,15 +2374,15 @@
 UINT32 WINAPI midiInGetDevCaps32W(UINT32 uDeviceID,
                                   LPMIDIINCAPS32W lpCaps, UINT32 uSize)
 {
-	MIDIINCAPS16	mic16;
-	UINT32		ret = midiInGetDevCaps16(uDeviceID,&mic16,uSize);
-
-	lpCaps->wMid = mic16.wMid;
-	lpCaps->wPid = mic16.wPid;
-	lpCaps->vDriverVersion = mic16.vDriverVersion;
-	lstrcpyAtoW(lpCaps->szPname,mic16.szPname);
-	lpCaps->dwSupport = mic16.dwSupport;
-	return ret;
+    MIDIINCAPS16	mic16;
+    UINT32		ret = midiInGetDevCaps16(uDeviceID,&mic16,uSize);
+    
+    lpCaps->wMid = mic16.wMid;
+    lpCaps->wPid = mic16.wPid;
+    lpCaps->vDriverVersion = mic16.vDriverVersion;
+    lstrcpyAtoW(lpCaps->szPname,mic16.szPname);
+    lpCaps->dwSupport = mic16.dwSupport;
+    return ret;
 }
 
 /**************************************************************************
@@ -2355,25 +2391,25 @@
 UINT32 WINAPI midiInGetDevCaps32A(UINT32 uDeviceID,
                                   LPMIDIINCAPS32A lpCaps, UINT32 uSize)
 {
-	MIDIINCAPS16	mic16;
-	UINT32		ret = midiInGetDevCaps16(uDeviceID,&mic16,uSize);
-
-	lpCaps->wMid = mic16.wMid;
-	lpCaps->wPid = mic16.wPid;
-	lpCaps->vDriverVersion = mic16.vDriverVersion;
-	strcpy(lpCaps->szPname,mic16.szPname);
-	lpCaps->dwSupport = mic16.dwSupport;
-	return ret;
+    MIDIINCAPS16	mic16;
+    UINT32		ret = midiInGetDevCaps16(uDeviceID,&mic16,uSize);
+    
+    lpCaps->wMid = mic16.wMid;
+    lpCaps->wPid = mic16.wPid;
+    lpCaps->vDriverVersion = mic16.vDriverVersion;
+    strcpy(lpCaps->szPname,mic16.szPname);
+    lpCaps->dwSupport = mic16.dwSupport;
+    return ret;
 }
 
 /**************************************************************************
  * 				midiInGetDevCaps	[MMSYSTEM.302]
  */
 UINT16 WINAPI midiInGetDevCaps16(UINT16 uDeviceID,
-                               LPMIDIINCAPS16 lpCaps, UINT16 uSize)
+				 LPMIDIINCAPS16 lpCaps, UINT16 uSize)
 {
-	TRACE(mmsys, "midiInGetDevCaps\n");
-	return midMessage(uDeviceID,MIDM_GETDEVCAPS,0,(DWORD)lpCaps,uSize);;
+    TRACE(mmsys, "midiInGetDevCaps\n");
+    return midMessage(uDeviceID,MIDM_GETDEVCAPS,0,(DWORD)lpCaps,uSize);;
 }
 
 /**************************************************************************
@@ -2381,18 +2417,18 @@
  */
 UINT32 WINAPI midiInGetErrorText32W(UINT32 uError, LPWSTR lpText, UINT32 uSize)
 {
-	LPSTR	xstr = HeapAlloc(GetProcessHeap(),0,uSize);
-	UINT32	ret = midiInGetErrorText16(uError,xstr,uSize);
-	lstrcpyAtoW(lpText,xstr);
-	HeapFree(GetProcessHeap(),0,xstr);
-	return ret;
+    LPSTR	xstr = HeapAlloc(GetProcessHeap(),0,uSize);
+    UINT32	ret = midiInGetErrorText16(uError,xstr,uSize);
+    lstrcpyAtoW(lpText,xstr);
+    HeapFree(GetProcessHeap(),0,xstr);
+    return ret;
 }
 /**************************************************************************
  * 				midiInGetErrorText 		[WINMM.61]
  */
 UINT32 WINAPI midiInGetErrorText32A(UINT32 uError, LPSTR lpText, UINT32 uSize)
 {
-	return midiInGetErrorText16(uError,lpText,uSize);
+    return midiInGetErrorText16(uError,lpText,uSize);
 }
 
 /**************************************************************************
@@ -2400,8 +2436,8 @@
  */
 UINT16 WINAPI midiInGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
 {
-	TRACE(mmsys, "midiInGetErrorText\n");
-	return (midiGetErrorText(uError, lpText, uSize));
+    TRACE(mmsys, "midiInGetErrorText\n");
+    return (midiGetErrorText(uError, lpText, uSize));
 }
 
 /**************************************************************************
@@ -2410,10 +2446,12 @@
 UINT32 WINAPI midiInOpen32(HMIDIIN32 * lphMidiIn, UINT32 uDeviceID,
                            DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
 {
-	HMIDIIN16	xhmid16;
-	UINT32 ret = midiInOpen16(&xhmid16,uDeviceID,dwCallback,dwInstance,dwFlags);
-	if (lphMidiIn) *lphMidiIn = xhmid16;
-	return ret;
+    HMIDIIN16	xhmid16;
+    UINT32 		ret = midiInOpen16(&xhmid16,uDeviceID,dwCallback,dwInstance,
+					   CALLBACK32CONV(dwFlags));
+    if (lphMidiIn) 
+	*lphMidiIn = xhmid16;
+    return ret;
 }
 
 /**************************************************************************
@@ -2422,35 +2460,42 @@
 UINT16 WINAPI midiInOpen16(HMIDIIN16 * lphMidiIn, UINT16 uDeviceID,
                            DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
 {
-	HMIDI16	hMidiIn;
-	LPMIDIOPENDESC	lpDesc;
-	DWORD	dwRet = 0;
-	BOOL32	bMapperFlg = FALSE;
-
-	if (lphMidiIn != NULL) *lphMidiIn = 0;
-	TRACE(mmsys, "(%p, %d, %08lX, %08lX, %08lX);\n", 
-		lphMidiIn, uDeviceID, dwCallback, dwInstance, dwFlags);
-	if (uDeviceID == (UINT16)MIDI_MAPPER) {
-		TRACE(mmsys, "MIDI_MAPPER mode requested !\n");
-		bMapperFlg = TRUE;
-		uDeviceID = 0;
-	}
-	hMidiIn = USER_HEAP_ALLOC(sizeof(MIDIOPENDESC));
-	if (lphMidiIn != NULL) *lphMidiIn = hMidiIn;
-	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
-	if (lpDesc == NULL) return MMSYSERR_NOMEM;
-	lpDesc->hMidi = hMidiIn;
-	lpDesc->dwCallback = dwCallback;
-	lpDesc->dwInstance = dwInstance;
-	while(uDeviceID < MAXMIDIDRIVERS) {
-		dwRet = midMessage(uDeviceID, MIDM_OPEN, 
-			lpDesc->dwInstance, (DWORD)lpDesc, 0L);
-		if (dwRet == MMSYSERR_NOERROR) break;
-		if (!bMapperFlg) break;
-		uDeviceID++;
-		TRACE(mmsys, "MIDI_MAPPER mode ! try next driver...\n");
-	}
-	return dwRet;
+    HMIDI16			hMidiIn;
+    LPMIDIOPENDESC		lpDesc;
+    DWORD			dwRet = 0;
+    BOOL32			bMapperFlg = FALSE;
+    
+    if (lphMidiIn != NULL) 
+	*lphMidiIn = 0;
+    TRACE(mmsys, "(%p, %d, %08lX, %08lX, %08lX);\n", 
+	  lphMidiIn, uDeviceID, dwCallback, dwInstance, dwFlags);
+    if (uDeviceID == (UINT16)MIDI_MAPPER) {
+	TRACE(mmsys, "MIDI_MAPPER mode requested !\n");
+	bMapperFlg = TRUE;
+	uDeviceID = 0;
+    }
+    hMidiIn = USER_HEAP_ALLOC(sizeof(MIDIOPENDESC));
+    if (lphMidiIn != NULL) 
+	*lphMidiIn = hMidiIn;
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
+    if (lpDesc == NULL) 
+	return MMSYSERR_NOMEM;
+    lpDesc->hMidi = hMidiIn;
+    lpDesc->dwCallback = dwCallback;
+    lpDesc->dwInstance = dwInstance;
+    
+    while (uDeviceID < MAXMIDIDRIVERS) {
+	dwRet = midMessage(uDeviceID, MIDM_OPEN, 
+			   lpDesc->dwInstance, (DWORD)lpDesc, dwFlags);
+	if (dwRet == MMSYSERR_NOERROR) 
+	    break;
+	if (!bMapperFlg) 
+	    break;
+	uDeviceID++;
+	TRACE(mmsys, "MIDI_MAPPER mode ! try next driver...\n");
+    }
+    lpDesc->wDevID = uDeviceID;
+    return dwRet;
 }
 
 /**************************************************************************
@@ -2458,7 +2503,7 @@
  */
 UINT32 WINAPI midiInClose32(HMIDIIN32 hMidiIn)
 {
-	return midiInClose16(hMidiIn);
+    return midiInClose16(hMidiIn);
 }
 
 /**************************************************************************
@@ -2466,11 +2511,11 @@
  */
 UINT16 WINAPI midiInClose16(HMIDIIN16 hMidiIn)
 {
-	LPMIDIOPENDESC	lpDesc;
-	TRACE(mmsys, "(%04X)\n", hMidiIn);
-	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return midMessage(0, MIDM_CLOSE, lpDesc->dwInstance, 0L, 0L);
+    LPMIDIOPENDESC	lpDesc;
+    TRACE(mmsys, "(%04X)\n", hMidiIn);
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    return midMessage(lpDesc->wDevID, MIDM_CLOSE, lpDesc->dwInstance, 0L, 0L);
 }
 
 /**************************************************************************
@@ -2479,7 +2524,15 @@
 UINT32 WINAPI midiInPrepareHeader32(HMIDIIN32 hMidiIn,
                                     MIDIHDR * lpMidiInHdr, UINT32 uSize)
 {
-	return midiInPrepareHeader16(hMidiIn,lpMidiInHdr,uSize);
+    LPMIDIOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X, %p, %d)\n", 
+	  hMidiIn, lpMidiInHdr, uSize);
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    lpMidiInHdr->reserved = (DWORD)lpMidiInHdr->lpData;
+    return midMessage(lpDesc->wDevID, MIDM_PREPARE, lpDesc->dwInstance, 
+		      (DWORD)lpMidiInHdr, (DWORD)uSize);
 }
 
 /**************************************************************************
@@ -2488,13 +2541,15 @@
 UINT16 WINAPI midiInPrepareHeader16(HMIDIIN16 hMidiIn,
                                     MIDIHDR * lpMidiInHdr, UINT16 uSize)
 {
-	LPMIDIOPENDESC	lpDesc;
-	TRACE(mmsys, "(%04X, %p, %d)\n", 
-					hMidiIn, lpMidiInHdr, uSize);
-	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return midMessage(0, MIDM_PREPARE, lpDesc->dwInstance, 
-						(DWORD)lpMidiInHdr, (DWORD)uSize);
+    LPMIDIOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X, %p, %d)\n", 
+	  hMidiIn, lpMidiInHdr, uSize);
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    lpMidiInHdr->reserved = (DWORD)PTR_SEG_TO_LIN(lpMidiInHdr->lpData);
+    return midMessage(lpDesc->wDevID, MIDM_PREPARE, lpDesc->dwInstance, 
+		      (DWORD)lpMidiInHdr, (DWORD)uSize);
 }
 
 /**************************************************************************
@@ -2503,7 +2558,7 @@
 UINT32 WINAPI midiInUnprepareHeader32(HMIDIIN32 hMidiIn,
                                       MIDIHDR * lpMidiInHdr, UINT32 uSize)
 {
-	return midiInUnprepareHeader16(hMidiIn,lpMidiInHdr,uSize);
+    return midiInUnprepareHeader16(hMidiIn,lpMidiInHdr,uSize);
 }
 
 /**************************************************************************
@@ -2512,13 +2567,13 @@
 UINT16 WINAPI midiInUnprepareHeader16(HMIDIIN16 hMidiIn,
                                       MIDIHDR * lpMidiInHdr, UINT16 uSize)
 {
-	LPMIDIOPENDESC	lpDesc;
-	TRACE(mmsys, "(%04X, %p, %d)\n", 
-					hMidiIn, lpMidiInHdr, uSize);
-	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return midMessage(0, MIDM_UNPREPARE, lpDesc->dwInstance, 
-						(DWORD)lpMidiInHdr, (DWORD)uSize);
+    LPMIDIOPENDESC	lpDesc;
+    TRACE(mmsys, "(%04X, %p, %d)\n", 
+	  hMidiIn, lpMidiInHdr, uSize);
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    return midMessage(lpDesc->wDevID, MIDM_UNPREPARE, lpDesc->dwInstance, 
+		      (DWORD)lpMidiInHdr, (DWORD)uSize);
 }
 
 /**************************************************************************
@@ -2527,7 +2582,7 @@
 UINT32 WINAPI midiInAddBuffer32(HMIDIIN32 hMidiIn,
                                 MIDIHDR * lpMidiInHdr, UINT32 uSize)
 {
-	return midiInAddBuffer16(hMidiIn,lpMidiInHdr,uSize);
+    return midiInAddBuffer16(hMidiIn,lpMidiInHdr,uSize);
 }
 
 /**************************************************************************
@@ -2536,8 +2591,8 @@
 UINT16 WINAPI midiInAddBuffer16(HMIDIIN16 hMidiIn,
                                 MIDIHDR * lpMidiInHdr, UINT16 uSize)
 {
-	TRACE(mmsys, "midiInAddBuffer\n");
-	return 0;
+    TRACE(mmsys, "midiInAddBuffer\n");
+    return 0;
 }
 
 /**************************************************************************
@@ -2545,7 +2600,7 @@
  */
 UINT32 WINAPI midiInStart32(HMIDIIN32 hMidiIn)
 {
-	return midiInStart16(hMidiIn);
+    return midiInStart16(hMidiIn);
 }
 
 /**************************************************************************
@@ -2553,8 +2608,13 @@
  */
 UINT16 WINAPI midiInStart16(HMIDIIN16 hMidiIn)
 {
-	TRACE(mmsys, "midiInStart\n");
-	return 0;
+    LPMIDIOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X)\n", hMidiIn);
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
+    if (lpDesc == NULL) 
+	return MMSYSERR_INVALHANDLE;
+    return midMessage(lpDesc->wDevID, MIDM_START, lpDesc->dwInstance, 0L, 0L);
 }
 
 /**************************************************************************
@@ -2562,7 +2622,7 @@
  */
 UINT32 WINAPI midiInStop32(HMIDIIN32 hMidiIn)
 {
-	return midiInStop16(hMidiIn);
+    return midiInStop16(hMidiIn);
 }
 
 /**************************************************************************
@@ -2570,8 +2630,13 @@
  */
 UINT16 WINAPI midiInStop16(HMIDIIN16 hMidiIn)
 {
-	TRACE(mmsys, "midiInStop\n");
-	return 0;
+    LPMIDIOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X)\n", hMidiIn);
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
+    if (lpDesc == NULL) 
+	return MMSYSERR_INVALHANDLE;
+    return midMessage(lpDesc->wDevID, MIDM_STOP, lpDesc->dwInstance, 0L, 0L);
 }
 
 /**************************************************************************
@@ -2579,7 +2644,7 @@
  */
 UINT32 WINAPI midiInReset32(HMIDIIN32 hMidiIn)
 {
-	return midiInReset16(hMidiIn);
+    return midiInReset16(hMidiIn);
 }
 
 /**************************************************************************
@@ -2587,26 +2652,49 @@
  */
 UINT16 WINAPI midiInReset16(HMIDIIN16 hMidiIn)
 {
-	TRACE(mmsys, "midiInReset\n");
-	return 0;
+    LPMIDIOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X)\n", hMidiIn);
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
+    if (lpDesc == NULL) 
+	return MMSYSERR_INVALHANDLE;
+    return midMessage(lpDesc->wDevID, MIDM_RESET, lpDesc->dwInstance, 0L, 0L);
 }
 
 /**************************************************************************
  * 				midiInGetID			[WINMM.63]
  */
-UINT32 WINAPI midiInGetID32(HMIDIIN32 hMidiIn, UINT32 * lpuDeviceID)
+UINT32 WINAPI midiInGetID32(HMIDIIN32 hMidiIn, UINT32* lpuDeviceID)
 {
-	TRACE(mmsys, "midiInGetID\n");
-	return 0;
+    LPMIDIOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X, %p)\n", hMidiIn, lpuDeviceID);
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
+    if (lpDesc == NULL) 
+	return MMSYSERR_INVALHANDLE;
+    if (lpuDeviceID == NULL) 
+	return MMSYSERR_INVALPARAM;
+    *lpuDeviceID = lpDesc->wDevID;
+    
+    return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
  * 				midiInGetID			[MMSYSTEM.312]
  */
-UINT16 WINAPI midiInGetID16(HMIDIIN16 hMidiIn, UINT16 * lpuDeviceID)
+UINT16 WINAPI midiInGetID16(HMIDIIN16 hMidiIn, UINT16* lpuDeviceID)
 {
-	TRACE(mmsys, "midiInGetID\n");
-	return 0;
+    LPMIDIOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X, %p)\n", hMidiIn, lpuDeviceID);
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
+    if (lpDesc == NULL) 
+	return MMSYSERR_INVALHANDLE;
+    if (lpuDeviceID == NULL) 
+	return MMSYSERR_INVALPARAM;
+    *lpuDeviceID = lpDesc->wDevID;
+    
+    return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
@@ -2615,36 +2703,39 @@
 DWORD WINAPI midiInMessage32(HMIDIIN32 hMidiIn, UINT32 uMessage, 
                              DWORD dwParam1, DWORD dwParam2)
 {
-	LPMIDIOPENDESC	lpDesc;
-	TRACE(mmsys, "(%04X, %04X, %08lX, %08lX)\n", 
-			hMidiIn, uMessage, dwParam1, dwParam2);
-	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	switch (uMessage) {
-	case MIDM_OPEN:
-		FIXME(mmsys,"can't handle MIDM_OPEN!\n");
-		return 0;
-	case MIDM_GETDEVCAPS:
-		return midiInGetDevCaps32A(hMidiIn,(LPMIDIINCAPS32A)dwParam1,dwParam2);
-	case MIDM_GETNUMDEVS:
-	case MIDM_RESET:
-	case MIDM_STOP:
-	case MIDM_START:
-	case MIDM_CLOSE:
-		/* no argument conversion needed */
-		break;
-	case MIDM_PREPARE:
-		return midiInPrepareHeader32(hMidiIn,(LPMIDIHDR)dwParam1,dwParam2);
-	case MIDM_UNPREPARE:
-		return midiInUnprepareHeader32(hMidiIn,(LPMIDIHDR)dwParam1,dwParam2);
-	case MIDM_ADDBUFFER:
-		return midiInAddBuffer32(hMidiIn,(LPMIDIHDR)dwParam1,dwParam2);
-	default:
-		ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
-		    hMidiIn,uMessage,dwParam1,dwParam2);
-		break;
-	}
-	return midMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
+    LPMIDIOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X, %04X, %08lX, %08lX)\n", 
+	  hMidiIn, uMessage, dwParam1, dwParam2);
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
+    if (lpDesc == NULL) 
+	return MMSYSERR_INVALHANDLE;
+    
+    switch (uMessage) {
+    case MIDM_OPEN:
+	FIXME(mmsys,"can't handle MIDM_OPEN!\n");
+	return 0;
+    case MIDM_GETDEVCAPS:
+	return midiInGetDevCaps32A(hMidiIn,(LPMIDIINCAPS32A)dwParam1,dwParam2);
+    case MIDM_GETNUMDEVS:
+    case MIDM_RESET:
+    case MIDM_STOP:
+    case MIDM_START:
+    case MIDM_CLOSE:
+	/* no argument conversion needed */
+	break;
+    case MIDM_PREPARE:
+	return midiInPrepareHeader32(hMidiIn,(LPMIDIHDR)dwParam1,dwParam2);
+    case MIDM_UNPREPARE:
+	return midiInUnprepareHeader32(hMidiIn,(LPMIDIHDR)dwParam1,dwParam2);
+    case MIDM_ADDBUFFER:
+	return midiInAddBuffer32(hMidiIn,(LPMIDIHDR)dwParam1,dwParam2);
+    default:
+	ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
+	    hMidiIn,uMessage,dwParam1,dwParam2);
+	break;
+    }
+    return midMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
 }
 
 /**************************************************************************
@@ -2653,36 +2744,36 @@
 DWORD WINAPI midiInMessage16(HMIDIIN16 hMidiIn, UINT16 uMessage, 
                              DWORD dwParam1, DWORD dwParam2)
 {
-	LPMIDIOPENDESC	lpDesc;
-	TRACE(mmsys, "(%04X, %04X, %08lX, %08lX)\n", 
-			hMidiIn, uMessage, dwParam1, dwParam2);
-	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	switch (uMessage) {
-	case MIDM_OPEN:
-		WARN(mmsys,"can't handle MIDM_OPEN!\n");
-		return 0;
-	case MIDM_GETDEVCAPS:
-		return midiInGetDevCaps16(hMidiIn,(LPMIDIINCAPS16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
-	case MIDM_GETNUMDEVS:
-	case MIDM_RESET:
-	case MIDM_STOP:
-	case MIDM_START:
-	case MIDM_CLOSE:
-		/* no argument conversion needed */
-		break;
-	case MIDM_PREPARE:
-		return midiInPrepareHeader16(hMidiIn,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
-	case MIDM_UNPREPARE:
-		return midiInUnprepareHeader16(hMidiIn,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
-	case MIDM_ADDBUFFER:
-		return midiInAddBuffer16(hMidiIn,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
-	default:
-		ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
-		    hMidiIn,uMessage,dwParam1,dwParam2);
-		break;
-	}
-	return midMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
+    LPMIDIOPENDESC	lpDesc;
+    TRACE(mmsys, "(%04X, %04X, %08lX, %08lX)\n", 
+	  hMidiIn, uMessage, dwParam1, dwParam2);
+    lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    switch (uMessage) {
+    case MIDM_OPEN:
+	WARN(mmsys,"can't handle MIDM_OPEN!\n");
+	return 0;
+    case MIDM_GETDEVCAPS:
+	return midiInGetDevCaps16(hMidiIn,(LPMIDIINCAPS16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+    case MIDM_GETNUMDEVS:
+    case MIDM_RESET:
+    case MIDM_STOP:
+    case MIDM_START:
+    case MIDM_CLOSE:
+	/* no argument conversion needed */
+	break;
+    case MIDM_PREPARE:
+	return midiInPrepareHeader16(hMidiIn,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+    case MIDM_UNPREPARE:
+	return midiInUnprepareHeader16(hMidiIn,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+    case MIDM_ADDBUFFER:
+	return midiInAddBuffer16(hMidiIn,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+    default:
+	ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
+	    hMidiIn,uMessage,dwParam1,dwParam2);
+	break;
+    }
+    return midMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
 }
 
 
@@ -2690,7 +2781,7 @@
  * 				waveOutGetNumDevs		[MMSYSTEM.401]
  */
 UINT32 WINAPI waveOutGetNumDevs32() {
-	return waveOutGetNumDevs16();
+    return waveOutGetNumDevs16();
 }
 
 /**************************************************************************
@@ -2698,61 +2789,61 @@
  */
 UINT16 WINAPI waveOutGetNumDevs16()
 {
-	UINT16	count = 0;
-	TRACE(mmsys, "waveOutGetNumDevs\n");
-	count += wodMessage( MMSYSTEM_FirstDevID(), WODM_GETNUMDEVS, 0L, 0L, 0L);
-	TRACE(mmsys, "waveOutGetNumDevs return %u \n", count);
-	return count;
+    UINT16	count = 0;
+    TRACE(mmsys, "waveOutGetNumDevs\n");
+    count += wodMessage( MMSYSTEM_FirstDevID(), WODM_GETNUMDEVS, 0L, 0L, 0L);
+    TRACE(mmsys, "waveOutGetNumDevs return %u \n", count);
+    return count;
 }
 
 /**************************************************************************
  * 				waveOutGetDevCaps		[MMSYSTEM.402]
  */
 UINT16 WINAPI waveOutGetDevCaps16(UINT16 uDeviceID, WAVEOUTCAPS16 * lpCaps,
-                                UINT16 uSize)
+				  UINT16 uSize)
 {
-	if (uDeviceID > waveOutGetNumDevs16() - 1) return MMSYSERR_BADDEVICEID;
-	if (uDeviceID == (UINT16)WAVE_MAPPER) return MMSYSERR_BADDEVICEID; /* FIXME: do we have a wave mapper ? */
-	TRACE(mmsys, "waveOutGetDevCaps\n");
-	return wodMessage(uDeviceID, WODM_GETDEVCAPS, 0L, (DWORD)lpCaps, uSize);
+    if (uDeviceID > waveOutGetNumDevs16() - 1) return MMSYSERR_BADDEVICEID;
+    if (uDeviceID == (UINT16)WAVE_MAPPER) return MMSYSERR_BADDEVICEID; /* FIXME: do we have a wave mapper ? */
+    TRACE(mmsys, "waveOutGetDevCaps\n");
+    return wodMessage(uDeviceID, WODM_GETDEVCAPS, 0L, (DWORD)lpCaps, uSize);
 }
 
 /**************************************************************************
  * 				waveOutGetDevCapsA		[WINMM.162]
  */
 UINT32 WINAPI waveOutGetDevCaps32A(UINT32 uDeviceID, LPWAVEOUTCAPS32A lpCaps,
-                                UINT32 uSize)
+				   UINT32 uSize)
 {
-	WAVEOUTCAPS16	woc16;
-	UINT16 ret = waveOutGetDevCaps16(uDeviceID,&woc16,sizeof(woc16));
-	
-	lpCaps->wMid = woc16.wMid;
-	lpCaps->wPid = woc16.wPid;
-	lpCaps->vDriverVersion = woc16.vDriverVersion;
-	strcpy(lpCaps->szPname,woc16.szPname);
-	lpCaps->dwFormats = woc16.dwFormats;
-	lpCaps->wChannels = woc16.wChannels;
-	lpCaps->dwSupport = woc16.dwSupport;
-	return ret;
+    WAVEOUTCAPS16	woc16;
+    UINT16 ret = waveOutGetDevCaps16(uDeviceID,&woc16,sizeof(woc16));
+    
+    lpCaps->wMid = woc16.wMid;
+    lpCaps->wPid = woc16.wPid;
+    lpCaps->vDriverVersion = woc16.vDriverVersion;
+    strcpy(lpCaps->szPname,woc16.szPname);
+    lpCaps->dwFormats = woc16.dwFormats;
+    lpCaps->wChannels = woc16.wChannels;
+    lpCaps->dwSupport = woc16.dwSupport;
+    return ret;
 }
 
 /**************************************************************************
  * 				waveOutGetDevCapsW		[WINMM.163]
  */
 UINT32 WINAPI waveOutGetDevCaps32W(UINT32 uDeviceID, LPWAVEOUTCAPS32W lpCaps,
-                                UINT32 uSize)
+				   UINT32 uSize)
 {
-	WAVEOUTCAPS16	woc16;
-	UINT32 ret = waveOutGetDevCaps16(uDeviceID,&woc16,sizeof(woc16));
-
-	lpCaps->wMid = woc16.wMid;
-	lpCaps->wPid = woc16.wPid;
-	lpCaps->vDriverVersion = woc16.vDriverVersion;
-	lstrcpyAtoW(lpCaps->szPname,woc16.szPname);
-	lpCaps->dwFormats = woc16.dwFormats;
-	lpCaps->wChannels = woc16.wChannels;
-	lpCaps->dwSupport = woc16.dwSupport;
-	return ret;
+    WAVEOUTCAPS16	woc16;
+    UINT32 ret = waveOutGetDevCaps16(uDeviceID,&woc16,sizeof(woc16));
+    
+    lpCaps->wMid = woc16.wMid;
+    lpCaps->wPid = woc16.wPid;
+    lpCaps->vDriverVersion = woc16.vDriverVersion;
+    lstrcpyAtoW(lpCaps->szPname,woc16.szPname);
+    lpCaps->dwFormats = woc16.dwFormats;
+    lpCaps->wChannels = woc16.wChannels;
+    lpCaps->dwSupport = woc16.dwSupport;
+    return ret;
 }
 
 /**************************************************************************
@@ -2760,8 +2851,8 @@
  */
 UINT16 WINAPI waveOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
 {
-	TRACE(mmsys, "waveOutGetErrorText\n");
-	return(waveGetErrorText(uError, lpText, uSize));
+    TRACE(mmsys, "waveOutGetErrorText\n");
+    return(waveGetErrorText(uError, lpText, uSize));
 }
 
 /**************************************************************************
@@ -2769,7 +2860,7 @@
  */
 UINT32 WINAPI waveOutGetErrorText32A(UINT32 uError, LPSTR lpText, UINT32 uSize)
 {
-	return(waveOutGetErrorText16(uError, lpText, uSize));
+    return(waveOutGetErrorText16(uError, lpText, uSize));
 }
 
 /**************************************************************************
@@ -2777,12 +2868,12 @@
  */
 UINT32 WINAPI waveOutGetErrorText32W(UINT32 uError, LPWSTR lpText, UINT32 uSize)
 {
-	LPSTR	xstr = HeapAlloc(GetProcessHeap(),0,uSize);
-	UINT32	ret = waveOutGetErrorText32A(uError, xstr, uSize);
-	
-	lstrcpyAtoW(lpText,xstr);
-	HeapFree(GetProcessHeap(),0,xstr);
-	return ret;
+    LPSTR	xstr = HeapAlloc(GetProcessHeap(),0,uSize);
+    UINT32	ret = waveOutGetErrorText32A(uError, xstr, uSize);
+    
+    lstrcpyAtoW(lpText,xstr);
+    HeapFree(GetProcessHeap(),0,xstr);
+    return ret;
 }
 
 
@@ -2791,66 +2882,66 @@
  */
 static UINT16 waveGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize)
 {
-	LPSTR	msgptr;
-	TRACE(mmsys, "(%04X, %p, %d);\n", 
-	       uError, lpText, uSize);
-	if ((lpText == NULL) || (uSize < 1)) return(FALSE);
-	lpText[0] = '\0';
-	switch(uError) {
-		case MMSYSERR_NOERROR:
-			msgptr = "The specified command was carried out.";
-			break;
-		case MMSYSERR_ERROR:
-			msgptr = "Undefined external error.";
-			break;
-		case MMSYSERR_BADDEVICEID:
-			msgptr = "A device ID has been used that is out of range for your system.";
-			break;
-		case MMSYSERR_NOTENABLED:
-			msgptr = "The driver was not enabled.";
-			break;
-		case MMSYSERR_ALLOCATED:
-			msgptr = "The specified device is already in use. Wait until it is free, and then try again.";
-			break;
-		case MMSYSERR_INVALHANDLE:
-			msgptr = "The specified device handle is invalid.";
-			break;
-		case MMSYSERR_NODRIVER:
-			msgptr = "There is no driver installed on your system !\n";
-			break;
-		case MMSYSERR_NOMEM:
-			msgptr = "Not enough memory available for this task. Quit one or more applications to increase available memory, and then try again.";
-			break;
-		case MMSYSERR_NOTSUPPORTED:
-			msgptr = "This function is not supported. Use the Capabilities function to determine which functions and messages the driver supports.";
-			break;
-		case MMSYSERR_BADERRNUM:
-			msgptr = "An error number was specified that is not defined in the system.";
-			break;
-		case MMSYSERR_INVALFLAG:
-			msgptr = "An invalid flag was passed to a system function.";
-			break;
-		case MMSYSERR_INVALPARAM:
-			msgptr = "An invalid parameter was passed to a system function.";
-			break;
-		case WAVERR_BADFORMAT:
-			msgptr = "The specified format is not supported or cannot be translated. Use the Capabilities function to determine the supported formats";
-			break;
-		case WAVERR_STILLPLAYING:
-			msgptr = "Cannot perform this operation while media data is still playing. Reset the device, or wait until the data is finished playing.";
-			break;
-		case WAVERR_UNPREPARED:
-			msgptr = "The wave header was not prepared. Use the Prepare function to prepare the header, and then try again.";
-			break;
-		case WAVERR_SYNC:
-			msgptr = "Cannot open the device without using the WAVE_ALLOWSYNC flag. Use the flag, and then try again.";
-			break;
-		default:
-			msgptr = "Unknown MMSYSTEM Error !\n";
-			break;
-		}
-	lstrcpyn32A(lpText, msgptr, uSize);
-	return TRUE;
+    LPSTR	msgptr;
+    TRACE(mmsys, "(%04X, %p, %d);\n", 
+	  uError, lpText, uSize);
+    if ((lpText == NULL) || (uSize < 1)) return(FALSE);
+    lpText[0] = '\0';
+    switch(uError) {
+    case MMSYSERR_NOERROR:
+	msgptr = "The specified command was carried out.";
+	break;
+    case MMSYSERR_ERROR:
+	msgptr = "Undefined external error.";
+	break;
+    case MMSYSERR_BADDEVICEID:
+	msgptr = "A device ID has been used that is out of range for your system.";
+	break;
+    case MMSYSERR_NOTENABLED:
+	msgptr = "The driver was not enabled.";
+	break;
+    case MMSYSERR_ALLOCATED:
+	msgptr = "The specified device is already in use. Wait until it is free, and then try again.";
+	break;
+    case MMSYSERR_INVALHANDLE:
+	msgptr = "The specified device handle is invalid.";
+	break;
+    case MMSYSERR_NODRIVER:
+	msgptr = "There is no driver installed on your system !\n";
+	break;
+    case MMSYSERR_NOMEM:
+	msgptr = "Not enough memory available for this task. Quit one or more applications to increase available memory, and then try again.";
+	break;
+    case MMSYSERR_NOTSUPPORTED:
+	msgptr = "This function is not supported. Use the Capabilities function to determine which functions and messages the driver supports.";
+	break;
+    case MMSYSERR_BADERRNUM:
+	msgptr = "An error number was specified that is not defined in the system.";
+	break;
+    case MMSYSERR_INVALFLAG:
+	msgptr = "An invalid flag was passed to a system function.";
+	break;
+    case MMSYSERR_INVALPARAM:
+	msgptr = "An invalid parameter was passed to a system function.";
+	break;
+    case WAVERR_BADFORMAT:
+	msgptr = "The specified format is not supported or cannot be translated. Use the Capabilities function to determine the supported formats";
+	break;
+    case WAVERR_STILLPLAYING:
+	msgptr = "Cannot perform this operation while media data is still playing. Reset the device, or wait until the data is finished playing.";
+	break;
+    case WAVERR_UNPREPARED:
+	msgptr = "The wave header was not prepared. Use the Prepare function to prepare the header, and then try again.";
+	break;
+    case WAVERR_SYNC:
+	msgptr = "Cannot open the device without using the WAVE_ALLOWSYNC flag. Use the flag, and then try again.";
+	break;
+    default:
+	msgptr = "Unknown MMSYSTEM Error !\n";
+	break;
+    }
+    lstrcpyn32A(lpText, msgptr, uSize);
+    return TRUE;
 }
 
 /**************************************************************************
@@ -2861,11 +2952,12 @@
                             const LPWAVEFORMATEX lpFormat, DWORD dwCallback,
                             DWORD dwInstance, DWORD dwFlags)
 {
-	HWAVEOUT16	hwo16;
-	UINT32	ret=waveOutOpen16(&hwo16,uDeviceID,lpFormat,dwCallback,dwInstance,
-				  CALLBACK32CONV(dwFlags));
-	if (lphWaveOut) *lphWaveOut=hwo16;
-	return ret;
+    HWAVEOUT16	hwo16;
+    UINT32	ret = waveOutOpen16(&hwo16,uDeviceID,lpFormat,dwCallback,dwInstance,
+				    CALLBACK32CONV(dwFlags));
+
+    if (lphWaveOut) *lphWaveOut=hwo16;
+    return ret;
 }
 /**************************************************************************
  *			waveOutOpen			[MMSYSTEM.404]
@@ -2874,46 +2966,46 @@
                             const LPWAVEFORMATEX lpFormat, DWORD dwCallback,
                             DWORD dwInstance, DWORD dwFlags)
 {
-	HWAVEOUT16	hWaveOut;
-	LPWAVEOPENDESC	lpDesc;
-	DWORD		dwRet = 0;
-	BOOL32		bMapperFlg = FALSE;
-
-	TRACE(mmsys, "(%p, %d, %p, %08lX, %08lX, %08lX);\n", 
-		lphWaveOut, uDeviceID, lpFormat, dwCallback, dwInstance, dwFlags);
-	if (dwFlags & WAVE_FORMAT_QUERY)
-		TRACE(mmsys, "WAVE_FORMAT_QUERY requested !\n");
-	if (uDeviceID == (UINT16)WAVE_MAPPER) {
-		TRACE(mmsys, "WAVE_MAPPER mode requested !\n");
-		bMapperFlg = TRUE;
-		uDeviceID = 0;
-	}
-	if (lpFormat == NULL) return WAVERR_BADFORMAT;
-
-	hWaveOut = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
-	if (lphWaveOut != NULL) *lphWaveOut = hWaveOut;
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
-	if (lpDesc == NULL) return MMSYSERR_NOMEM;
-	lpDesc->hWave = hWaveOut;
-	lpDesc->lpFormat = (LPWAVEFORMAT)lpFormat;  /* should the struct be copied iso pointer? */
-	lpDesc->dwCallBack = dwCallback;
-	lpDesc->dwInstance = dwInstance;
-	if (uDeviceID >= MAXWAVEDRIVERS)
-		uDeviceID = 0;
-	while(uDeviceID < MAXWAVEDRIVERS) {
-		dwRet = wodMessage(uDeviceID, WODM_OPEN, 
-			lpDesc->dwInstance, (DWORD)lpDesc, dwFlags);
-		if (dwRet == MMSYSERR_NOERROR) break;
-		if (!bMapperFlg) break;
-		uDeviceID++;
-		TRACE(mmsys, "WAVE_MAPPER mode ! try next driver...\n");
-	}
-	lpDesc->uDeviceID = uDeviceID;  /* save physical Device ID */
-	if (dwFlags & WAVE_FORMAT_QUERY) {
-		TRACE(mmsys, "End of WAVE_FORMAT_QUERY !\n");
-		dwRet = waveOutClose32(hWaveOut);
-	}
-	return dwRet;
+    HWAVEOUT16	hWaveOut;
+    LPWAVEOPENDESC	lpDesc;
+    DWORD		dwRet = 0;
+    BOOL32		bMapperFlg = FALSE;
+    
+    TRACE(mmsys, "(%p, %d, %p, %08lX, %08lX, %08lX);\n", 
+	  lphWaveOut, uDeviceID, lpFormat, dwCallback, dwInstance, dwFlags);
+    if (dwFlags & WAVE_FORMAT_QUERY)
+	TRACE(mmsys, "WAVE_FORMAT_QUERY requested !\n");
+    if (uDeviceID == (UINT16)WAVE_MAPPER) {
+	TRACE(mmsys, "WAVE_MAPPER mode requested !\n");
+	bMapperFlg = TRUE;
+	uDeviceID = 0;
+    }
+    if (lpFormat == NULL) return WAVERR_BADFORMAT;
+    
+    hWaveOut = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
+    if (lphWaveOut != NULL) *lphWaveOut = hWaveOut;
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+    if (lpDesc == NULL) return MMSYSERR_NOMEM;
+    lpDesc->hWave = hWaveOut;
+    lpDesc->lpFormat = (LPWAVEFORMAT)lpFormat;  /* should the struct be copied iso pointer? */
+    lpDesc->dwCallBack = dwCallback;
+    lpDesc->dwInstance = dwInstance;
+    if (uDeviceID >= MAXWAVEDRIVERS)
+	uDeviceID = 0;
+    while(uDeviceID < MAXWAVEDRIVERS) {
+	dwRet = wodMessage(uDeviceID, WODM_OPEN, 
+			   lpDesc->dwInstance, (DWORD)lpDesc, dwFlags);
+	if (dwRet == MMSYSERR_NOERROR) break;
+	if (!bMapperFlg) break;
+	uDeviceID++;
+	TRACE(mmsys, "WAVE_MAPPER mode ! try next driver...\n");
+    }
+    lpDesc->uDeviceID = uDeviceID;  /* save physical Device ID */
+    if (dwFlags & WAVE_FORMAT_QUERY) {
+	TRACE(mmsys, "End of WAVE_FORMAT_QUERY !\n");
+	dwRet = waveOutClose32(hWaveOut);
+    }
+    return dwRet;
 }
 
 /**************************************************************************
@@ -2921,35 +3013,35 @@
  */
 UINT32 WINAPI waveOutClose32(HWAVEOUT32 hWaveOut)
 {
-	return waveOutClose16(hWaveOut);
+    return waveOutClose16(hWaveOut);
 }
 /**************************************************************************
  * 				waveOutClose		[MMSYSTEM.405]
  */
 UINT16 WINAPI waveOutClose16(HWAVEOUT16 hWaveOut)
 {
-	LPWAVEOPENDESC	lpDesc;
-
-	TRACE(mmsys, "(%04X)\n", hWaveOut);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage( lpDesc->uDeviceID, WODM_CLOSE, lpDesc->dwInstance, 0L, 0L);
+    LPWAVEOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X)\n", hWaveOut);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    return wodMessage( lpDesc->uDeviceID, WODM_CLOSE, lpDesc->dwInstance, 0L, 0L);
 }
 
 /**************************************************************************
  * 				waveOutPrepareHeader	[WINMM.175]
  */
 UINT32 WINAPI waveOutPrepareHeader32(HWAVEOUT32 hWaveOut,
-                                   WAVEHDR * lpWaveOutHdr, UINT32 uSize)
+				     WAVEHDR * lpWaveOutHdr, UINT32 uSize)
 {
-	LPWAVEOPENDESC	lpDesc;
-
-	TRACE(mmsys, "(%04X, %p, %u);\n", 
-					hWaveOut, lpWaveOutHdr, uSize);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage( lpDesc->uDeviceID, WODM_PREPARE, lpDesc->dwInstance, 
-			   (DWORD)lpWaveOutHdr,uSize);
+    LPWAVEOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X, %p, %u);\n", 
+	  hWaveOut, lpWaveOutHdr, uSize);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    return wodMessage( lpDesc->uDeviceID, WODM_PREPARE, lpDesc->dwInstance, 
+		       (DWORD)lpWaveOutHdr,uSize);
 }
 /**************************************************************************
  * 				waveOutPrepareHeader	[MMSYSTEM.406]
@@ -2957,19 +3049,19 @@
 UINT16 WINAPI waveOutPrepareHeader16(HWAVEOUT16 hWaveOut,
                                      WAVEHDR * lpWaveOutHdr, UINT16 uSize)
 {
-	LPWAVEOPENDESC	lpDesc;
-	LPBYTE		saveddata = lpWaveOutHdr->lpData;
-	UINT16		ret;
-
-	TRACE(mmsys, "(%04X, %p, %u);\n", 
-					hWaveOut, lpWaveOutHdr, uSize);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	lpWaveOutHdr->lpData = PTR_SEG_TO_LIN(lpWaveOutHdr->lpData);
-	ret = wodMessage( lpDesc->uDeviceID, WODM_PREPARE, lpDesc->dwInstance, 
-			   (DWORD)lpWaveOutHdr,uSize);
-	lpWaveOutHdr->lpData = saveddata;
-	return ret;
+    LPWAVEOPENDESC	lpDesc;
+    LPBYTE		saveddata = lpWaveOutHdr->lpData;
+    UINT16		ret;
+    
+    TRACE(mmsys, "(%04X, %p, %u);\n", 
+	  hWaveOut, lpWaveOutHdr, uSize);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    lpWaveOutHdr->lpData = PTR_SEG_TO_LIN(lpWaveOutHdr->lpData);
+    ret = wodMessage( lpDesc->uDeviceID, WODM_PREPARE, lpDesc->dwInstance, 
+		      (DWORD)lpWaveOutHdr,uSize);
+    lpWaveOutHdr->lpData = saveddata;
+    return ret;
 }
 
 /**************************************************************************
@@ -2978,34 +3070,34 @@
 UINT32 WINAPI waveOutUnprepareHeader32(HWAVEOUT32 hWaveOut,
                                        WAVEHDR * lpWaveOutHdr, UINT32 uSize)
 {
-	LPWAVEOPENDESC	lpDesc;
-
-	TRACE(mmsys, "(%04X, %p, %u);\n", 
-						hWaveOut, lpWaveOutHdr, uSize);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage(lpDesc->uDeviceID,WODM_UNPREPARE,lpDesc->dwInstance, 
-					(DWORD)lpWaveOutHdr, uSize);
+    LPWAVEOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X, %p, %u);\n", 
+	  hWaveOut, lpWaveOutHdr, uSize);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    return wodMessage(lpDesc->uDeviceID,WODM_UNPREPARE,lpDesc->dwInstance, 
+		      (DWORD)lpWaveOutHdr, uSize);
 }
 /**************************************************************************
  * 				waveOutUnprepareHeader	[MMSYSTEM.407]
  */
 UINT16 WINAPI waveOutUnprepareHeader16(HWAVEOUT16 hWaveOut,
-                                     WAVEHDR * lpWaveOutHdr, UINT16 uSize)
+				       WAVEHDR * lpWaveOutHdr, UINT16 uSize)
 {
-	LPWAVEOPENDESC	lpDesc;
-	LPBYTE		saveddata = lpWaveOutHdr->lpData;
-	UINT16		ret;
-
-	TRACE(mmsys, "(%04X, %p, %u);\n", 
-						hWaveOut, lpWaveOutHdr, uSize);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	lpWaveOutHdr->lpData = PTR_SEG_TO_LIN(lpWaveOutHdr->lpData);
-	ret = wodMessage(lpDesc->uDeviceID,WODM_UNPREPARE,lpDesc->dwInstance, 
-			  (DWORD)lpWaveOutHdr, uSize);
-	lpWaveOutHdr->lpData = saveddata;
-	return ret;
+    LPWAVEOPENDESC	lpDesc;
+    LPBYTE		saveddata = lpWaveOutHdr->lpData;
+    UINT16		ret;
+    
+    TRACE(mmsys, "(%04X, %p, %u);\n", 
+	  hWaveOut, lpWaveOutHdr, uSize);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    lpWaveOutHdr->lpData = PTR_SEG_TO_LIN(lpWaveOutHdr->lpData);
+    ret = wodMessage(lpDesc->uDeviceID,WODM_UNPREPARE,lpDesc->dwInstance, 
+		     (DWORD)lpWaveOutHdr, uSize);
+    lpWaveOutHdr->lpData = saveddata;
+    return ret;
 }
 
 /**************************************************************************
@@ -3014,30 +3106,30 @@
 UINT32 WINAPI waveOutWrite32(HWAVEOUT32 hWaveOut, WAVEHDR * lpWaveOutHdr,
                              UINT32 uSize)
 {
-	LPWAVEOPENDESC	lpDesc;
-	TRACE(mmsys, "(%04X, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	lpWaveOutHdr->reserved = (DWORD)lpWaveOutHdr->lpData;
-	return wodMessage( lpDesc->uDeviceID, WODM_WRITE, lpDesc->dwInstance, (DWORD)lpWaveOutHdr, uSize);
+    LPWAVEOPENDESC	lpDesc;
+    TRACE(mmsys, "(%04X, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    lpWaveOutHdr->reserved = (DWORD)lpWaveOutHdr->lpData;
+    return wodMessage( lpDesc->uDeviceID, WODM_WRITE, lpDesc->dwInstance, (DWORD)lpWaveOutHdr, uSize);
 }
 /**************************************************************************
  * 				waveOutWrite		[MMSYSTEM.408]
  */
 UINT16 WINAPI waveOutWrite16(HWAVEOUT16 hWaveOut, WAVEHDR * lpWaveOutHdr,
-                           UINT16 uSize)
+			     UINT16 uSize)
 {
-	LPWAVEOPENDESC	lpDesc;
-	UINT16		ret;
-
-	TRACE(mmsys, "(%04X, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	lpWaveOutHdr->reserved=(DWORD)lpWaveOutHdr->lpData;/*save original ptr*/
-	lpWaveOutHdr->lpData = PTR_SEG_TO_LIN(lpWaveOutHdr->lpData);
-	ret = wodMessage( lpDesc->uDeviceID, WODM_WRITE, lpDesc->dwInstance, (DWORD)lpWaveOutHdr, uSize);
-	lpWaveOutHdr->lpData = (LPBYTE)lpWaveOutHdr->reserved;
-	return ret;
+    LPWAVEOPENDESC	lpDesc;
+    UINT16		ret;
+    
+    TRACE(mmsys, "(%04X, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    lpWaveOutHdr->reserved=(DWORD)lpWaveOutHdr->lpData;/*save original ptr*/
+    lpWaveOutHdr->lpData = PTR_SEG_TO_LIN(lpWaveOutHdr->lpData);
+    ret = wodMessage( lpDesc->uDeviceID, WODM_WRITE, lpDesc->dwInstance, (DWORD)lpWaveOutHdr, uSize);
+    lpWaveOutHdr->lpData = (LPBYTE)lpWaveOutHdr->reserved;
+    return ret;
 }
 
 /**************************************************************************
@@ -3045,7 +3137,7 @@
  */
 UINT32 WINAPI waveOutPause32(HWAVEOUT32 hWaveOut)
 {
-	return waveOutPause16(hWaveOut);
+    return waveOutPause16(hWaveOut);
 }
 
 /**************************************************************************
@@ -3053,12 +3145,12 @@
  */
 UINT16 WINAPI waveOutPause16(HWAVEOUT16 hWaveOut)
 {
-	LPWAVEOPENDESC	lpDesc;
-
-	TRACE(mmsys, "(%04X)\n", hWaveOut);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage( lpDesc->uDeviceID, WODM_PAUSE, lpDesc->dwInstance, 0L, 0L);
+    LPWAVEOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X)\n", hWaveOut);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    return wodMessage( lpDesc->uDeviceID, WODM_PAUSE, lpDesc->dwInstance, 0L, 0L);
 }
 
 /**************************************************************************
@@ -3066,19 +3158,20 @@
  */
 UINT32 WINAPI waveOutRestart32(HWAVEOUT32 hWaveOut)
 {
-	return waveOutRestart16(hWaveOut);
+    return waveOutRestart16(hWaveOut);
 }
+
 /**************************************************************************
  * 				waveOutRestart		[MMSYSTEM.410]
  */
 UINT16 WINAPI waveOutRestart16(HWAVEOUT16 hWaveOut)
 {
-	LPWAVEOPENDESC	lpDesc;
-
-	TRACE(mmsys, "(%04X)\n", hWaveOut);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage( lpDesc->uDeviceID, WODM_RESTART, lpDesc->dwInstance, 0L, 0L);
+    LPWAVEOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X)\n", hWaveOut);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    return wodMessage( lpDesc->uDeviceID, WODM_RESTART, lpDesc->dwInstance, 0L, 0L);
 }
 
 /**************************************************************************
@@ -3086,7 +3179,7 @@
  */
 UINT32 WINAPI waveOutReset32(HWAVEOUT32 hWaveOut)
 {
-	return waveOutReset16(hWaveOut);
+    return waveOutReset16(hWaveOut);
 }
 
 /**************************************************************************
@@ -3094,11 +3187,11 @@
  */
 UINT16 WINAPI waveOutReset16(HWAVEOUT16 hWaveOut)
 {
-	LPWAVEOPENDESC	lpDesc;
-	TRACE(mmsys, "(%04X)\n", hWaveOut);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage( lpDesc->uDeviceID, WODM_RESET, lpDesc->dwInstance, 0L, 0L);
+    LPWAVEOPENDESC	lpDesc;
+    TRACE(mmsys, "(%04X)\n", hWaveOut);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    return wodMessage( lpDesc->uDeviceID, WODM_RESET, lpDesc->dwInstance, 0L, 0L);
 }
 
 /**************************************************************************
@@ -3107,13 +3200,13 @@
 UINT32 WINAPI waveOutGetPosition32(HWAVEOUT32 hWaveOut, LPMMTIME32 lpTime,
                                    UINT32 uSize)
 {
-	MMTIME16	mmt16;
-	UINT32 ret;
-	
-	mmt16.wType = lpTime->wType;
-	ret = waveOutGetPosition16(hWaveOut,&mmt16,sizeof(mmt16));
-	MMSYSTEM_MMTIME16to32(lpTime,&mmt16);
-	return ret;
+    MMTIME16	mmt16;
+    UINT32 ret;
+    
+    mmt16.wType = lpTime->wType;
+    ret = waveOutGetPosition16(hWaveOut,&mmt16,sizeof(mmt16));
+    MMSYSTEM_MMTIME16to32(lpTime,&mmt16);
+    return ret;
 }
 /**************************************************************************
  * 				waveOutGetPosition	[MMSYSTEM.412]
@@ -3121,12 +3214,12 @@
 UINT16 WINAPI waveOutGetPosition16(HWAVEOUT16 hWaveOut,LPMMTIME16 lpTime,
                                    UINT16 uSize)
 {
-	LPWAVEOPENDESC	lpDesc;
-	TRACE(mmsys, "(%04X, %p, %u);\n", hWaveOut, lpTime, uSize);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage( lpDesc->uDeviceID, WODM_GETPOS, lpDesc->dwInstance, 
-							(DWORD)lpTime, (DWORD)uSize);
+    LPWAVEOPENDESC	lpDesc;
+    TRACE(mmsys, "(%04X, %p, %u);\n", hWaveOut, lpTime, uSize);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    return wodMessage( lpDesc->uDeviceID, WODM_GETPOS, lpDesc->dwInstance, 
+		       (DWORD)lpTime, (DWORD)uSize);
 }
 
 #define WAVEOUT_SHORTCUT_1(xx,XX,atype) \
@@ -3148,7 +3241,7 @@
 WAVEOUT_SHORTCUT_1(SetPitch,SETPITCH,DWORD)
 WAVEOUT_SHORTCUT_1(GetPlaybackRate,GETPLAYBACKRATE,DWORD*)
 WAVEOUT_SHORTCUT_1(SetPlaybackRate,SETPLAYBACKRATE,DWORD)
-
+    
 #define WAVEOUT_SHORTCUT_2(xx,XX,atype) \
 	UINT32 WINAPI waveOut##xx##32(UINT32 devid, atype x)		\
 {									\
@@ -3159,26 +3252,26 @@
 	TRACE(mmsys, "waveOut"#xx"(%04X, %08lx);\n", devid,(DWORD)x);	\
 	return wodMessage(devid, WODM_##XX, 0L,	(DWORD)x, 0L);		\
 }
-	
-
+    
+    
 WAVEOUT_SHORTCUT_2(GetVolume,GETVOLUME,DWORD*)
 WAVEOUT_SHORTCUT_2(SetVolume,SETVOLUME,DWORD)
-
-
+    
+    
 /**************************************************************************
  * 				waveOutBreakLoop 	[MMSYSTEM.419]
  */
 UINT32 WINAPI waveOutBreakLoop32(HWAVEOUT32 hWaveOut)
 {
-	return waveOutBreakLoop16(hWaveOut);
+    return waveOutBreakLoop16(hWaveOut);
 }
 /**************************************************************************
  * 				waveOutBreakLoop 	[MMSYSTEM.419]
  */
 UINT16 WINAPI waveOutBreakLoop16(HWAVEOUT16 hWaveOut)
 {
-	TRACE(mmsys, "(%04X)\n", hWaveOut);
-	return MMSYSERR_INVALHANDLE;
+    TRACE(mmsys, "(%04X)\n", hWaveOut);
+    return MMSYSERR_INVALHANDLE;
 }
 
 /**************************************************************************
@@ -3186,26 +3279,26 @@
  */
 UINT32 WINAPI waveOutGetID32(HWAVEOUT32 hWaveOut, UINT32 * lpuDeviceID)
 {
-	LPWAVEOPENDESC	lpDesc;
-	TRACE(mmsys, "(%04X, %p);\n", hWaveOut, lpuDeviceID);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
-	*lpuDeviceID = lpDesc->uDeviceID;
-        return 0;
+    LPWAVEOPENDESC	lpDesc;
+    TRACE(mmsys, "(%04X, %p);\n", hWaveOut, lpuDeviceID);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
+    *lpuDeviceID = lpDesc->uDeviceID;
+    return 0;
 }
 /**************************************************************************
  * 				waveOutGetID	 	[MMSYSTEM.420]
  */
 UINT16 WINAPI waveOutGetID16(HWAVEOUT16 hWaveOut, UINT16 * lpuDeviceID)
 {
-	LPWAVEOPENDESC	lpDesc;
-	TRACE(mmsys, "(%04X, %p);\n", hWaveOut, lpuDeviceID);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
-	*lpuDeviceID = lpDesc->uDeviceID;
-        return 0;
+    LPWAVEOPENDESC	lpDesc;
+    TRACE(mmsys, "(%04X, %p);\n", hWaveOut, lpuDeviceID);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
+    *lpuDeviceID = lpDesc->uDeviceID;
+    return 0;
 }
 
 /**************************************************************************
@@ -3214,41 +3307,41 @@
 DWORD WINAPI waveOutMessage32(HWAVEOUT32 hWaveOut, UINT32 uMessage, 
                               DWORD dwParam1, DWORD dwParam2)
 {
-	LPWAVEOPENDESC	lpDesc;
-
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	switch (uMessage) {
-	case WODM_GETNUMDEVS:
-	case WODM_GETPOS:
-	case WODM_GETVOLUME:
-	case WODM_GETPITCH:
-	case WODM_GETPLAYBACKRATE:
-	case WODM_SETVOLUME:
-	case WODM_SETPITCH:
-	case WODM_SETPLAYBACKRATE:
-	case WODM_RESET:
-	case WODM_PAUSE:
-	case WODM_PREPARE:
-	case WODM_UNPREPARE:
-	case WODM_STOP:
-	case WODM_CLOSE:
-		/* no argument conversion needed */
-		break;
-	case WODM_WRITE:
-		return waveOutWrite32(hWaveOut,(LPWAVEHDR)dwParam1,dwParam2);
-	case WODM_GETDEVCAPS:
-		/* FIXME: UNICODE/ANSI? */
-		return waveOutGetDevCaps32A(hWaveOut,(LPWAVEOUTCAPS32A)dwParam1,dwParam2);
-	case WODM_OPEN:
-		FIXME(mmsys,"can't handle WODM_OPEN, please report.\n");
-		break;
-	default:
-		ERR(mmsys,"(0x%04x,0x%04x,%08lx,%08lx): unhandled message\n",
-		    hWaveOut,uMessage,dwParam1,dwParam2);
-		break;
-	}
-	return wodMessage( lpDesc->uDeviceID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
+    LPWAVEOPENDESC	lpDesc;
+    
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    switch (uMessage) {
+    case WODM_GETNUMDEVS:
+    case WODM_GETPOS:
+    case WODM_GETVOLUME:
+    case WODM_GETPITCH:
+    case WODM_GETPLAYBACKRATE:
+    case WODM_SETVOLUME:
+    case WODM_SETPITCH:
+    case WODM_SETPLAYBACKRATE:
+    case WODM_RESET:
+    case WODM_PAUSE:
+    case WODM_PREPARE:
+    case WODM_UNPREPARE:
+    case WODM_STOP:
+    case WODM_CLOSE:
+	/* no argument conversion needed */
+	break;
+    case WODM_WRITE:
+	return waveOutWrite32(hWaveOut,(LPWAVEHDR)dwParam1,dwParam2);
+    case WODM_GETDEVCAPS:
+	/* FIXME: UNICODE/ANSI? */
+	return waveOutGetDevCaps32A(hWaveOut,(LPWAVEOUTCAPS32A)dwParam1,dwParam2);
+    case WODM_OPEN:
+	FIXME(mmsys,"can't handle WODM_OPEN, please report.\n");
+	break;
+    default:
+	ERR(mmsys,"(0x%04x,0x%04x,%08lx,%08lx): unhandled message\n",
+	    hWaveOut,uMessage,dwParam1,dwParam2);
+	break;
+    }
+    return wodMessage( lpDesc->uDeviceID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
 }
 
 /**************************************************************************
@@ -3257,45 +3350,45 @@
 DWORD WINAPI waveOutMessage16(HWAVEOUT16 hWaveOut, UINT16 uMessage, 
                               DWORD dwParam1, DWORD dwParam2)
 {
-	LPWAVEOPENDESC	lpDesc;
-
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	switch (uMessage) {
-	case WODM_GETNUMDEVS:
-	case WODM_SETVOLUME:
-	case WODM_SETPITCH:
-	case WODM_SETPLAYBACKRATE:
-	case WODM_RESET:
-	case WODM_PAUSE:
-	case WODM_STOP:
-	case WODM_CLOSE:
-		/* no argument conversion needed */
-		break;
-	case WODM_GETPOS:
-		return waveOutGetPosition16(hWaveOut,(LPMMTIME16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
-	case WODM_GETVOLUME:
-		return waveOutGetVolume16(hWaveOut,(LPDWORD)PTR_SEG_TO_LIN(dwParam1));
-	case WODM_GETPITCH:
-		return waveOutGetPitch16(hWaveOut,(LPDWORD)PTR_SEG_TO_LIN(dwParam1));
-	case WODM_GETPLAYBACKRATE:
-		return waveOutGetPlaybackRate16(hWaveOut,(LPDWORD)PTR_SEG_TO_LIN(dwParam1));
-	case WODM_GETDEVCAPS:
-		return waveOutGetDevCaps16(hWaveOut,(LPWAVEOUTCAPS16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
-	case WODM_PREPARE:
-		return waveOutPrepareHeader16(hWaveOut,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
-	case WODM_UNPREPARE:
-		return waveOutUnprepareHeader16(hWaveOut,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
-	case WODM_WRITE:
-		return waveOutWrite16(hWaveOut,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
-	case WODM_OPEN:
-		FIXME(mmsys,"can't handle WODM_OPEN, please report.\n");
-		break;
-	default:
-		ERR(mmsys,"(0x%04x,0x%04x,%08lx,%08lx): unhandled message\n",
-		    hWaveOut,uMessage,dwParam1,dwParam2);
-	}
-	return wodMessage( lpDesc->uDeviceID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
+    LPWAVEOPENDESC	lpDesc;
+    
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    switch (uMessage) {
+    case WODM_GETNUMDEVS:
+    case WODM_SETVOLUME:
+    case WODM_SETPITCH:
+    case WODM_SETPLAYBACKRATE:
+    case WODM_RESET:
+    case WODM_PAUSE:
+    case WODM_STOP:
+    case WODM_CLOSE:
+	/* no argument conversion needed */
+	break;
+    case WODM_GETPOS:
+	return waveOutGetPosition16(hWaveOut,(LPMMTIME16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+    case WODM_GETVOLUME:
+	return waveOutGetVolume16(hWaveOut,(LPDWORD)PTR_SEG_TO_LIN(dwParam1));
+    case WODM_GETPITCH:
+	return waveOutGetPitch16(hWaveOut,(LPDWORD)PTR_SEG_TO_LIN(dwParam1));
+    case WODM_GETPLAYBACKRATE:
+	return waveOutGetPlaybackRate16(hWaveOut,(LPDWORD)PTR_SEG_TO_LIN(dwParam1));
+    case WODM_GETDEVCAPS:
+	return waveOutGetDevCaps16(hWaveOut,(LPWAVEOUTCAPS16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+    case WODM_PREPARE:
+	return waveOutPrepareHeader16(hWaveOut,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+    case WODM_UNPREPARE:
+	return waveOutUnprepareHeader16(hWaveOut,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+    case WODM_WRITE:
+	return waveOutWrite16(hWaveOut,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+    case WODM_OPEN:
+	FIXME(mmsys,"can't handle WODM_OPEN, please report.\n");
+	break;
+    default:
+	ERR(mmsys,"(0x%04x,0x%04x,%08lx,%08lx): unhandled message\n",
+	    hWaveOut,uMessage,dwParam1,dwParam2);
+    }
+    return wodMessage( lpDesc->uDeviceID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
 }
 
 /**************************************************************************
@@ -3303,7 +3396,7 @@
  */
 UINT32 WINAPI waveInGetNumDevs32()
 {
-	return waveInGetNumDevs16();
+    return waveInGetNumDevs16();
 }
 
 /**************************************************************************
@@ -3311,11 +3404,11 @@
  */
 UINT16 WINAPI waveInGetNumDevs16()
 {
-	UINT16	count = 0;
-	TRACE(mmsys, "waveInGetNumDevs\n");
-	count += widMessage(0, WIDM_GETNUMDEVS, 0L, 0L, 0L);
-	TRACE(mmsys, "waveInGetNumDevs return %u \n", count);
-	return count;
+    UINT16	count = 0;
+    TRACE(mmsys, "waveInGetNumDevs\n");
+    count += widMessage(0, WIDM_GETNUMDEVS, 0L, 0L, 0L);
+    TRACE(mmsys, "waveInGetNumDevs return %u \n", count);
+    return count;
 }
 
 /**************************************************************************
@@ -3323,41 +3416,41 @@
  */
 UINT32 WINAPI waveInGetDevCaps32W(UINT32 uDeviceID, LPWAVEINCAPS32W lpCaps, UINT32 uSize)
 {
-	WAVEINCAPS16	wic16;
-	UINT32	ret = waveInGetDevCaps16(uDeviceID,&wic16,uSize);
-
-	lpCaps->wMid = wic16.wMid;
-	lpCaps->wPid = wic16.wPid;
-	lpCaps->vDriverVersion = wic16.vDriverVersion;
-	lstrcpyAtoW(lpCaps->szPname,wic16.szPname);
-	lpCaps->dwFormats = wic16.dwFormats;
-	lpCaps->wChannels = wic16.wChannels;
-
-	return ret;
+    WAVEINCAPS16	wic16;
+    UINT32	ret = waveInGetDevCaps16(uDeviceID,&wic16,uSize);
+    
+    lpCaps->wMid = wic16.wMid;
+    lpCaps->wPid = wic16.wPid;
+    lpCaps->vDriverVersion = wic16.vDriverVersion;
+    lstrcpyAtoW(lpCaps->szPname,wic16.szPname);
+    lpCaps->dwFormats = wic16.dwFormats;
+    lpCaps->wChannels = wic16.wChannels;
+    
+    return ret;
 }
 /**************************************************************************
  * 				waveInGetDevCapsA 		[WINMM.146]
  */
 UINT32 WINAPI waveInGetDevCaps32A(UINT32 uDeviceID, LPWAVEINCAPS32A lpCaps, UINT32 uSize)
 {
-	WAVEINCAPS16	wic16;
-	UINT32	ret = waveInGetDevCaps16(uDeviceID,&wic16,uSize);
-	
-	lpCaps->wMid = wic16.wMid;
-	lpCaps->wPid = wic16.wPid;
-	lpCaps->vDriverVersion = wic16.vDriverVersion;
-	strcpy(lpCaps->szPname,wic16.szPname);
-	lpCaps->dwFormats = wic16.dwFormats;
-	lpCaps->wChannels = wic16.wChannels;
-	return ret;
+    WAVEINCAPS16	wic16;
+    UINT32	ret = waveInGetDevCaps16(uDeviceID,&wic16,uSize);
+    
+    lpCaps->wMid = wic16.wMid;
+    lpCaps->wPid = wic16.wPid;
+    lpCaps->vDriverVersion = wic16.vDriverVersion;
+    strcpy(lpCaps->szPname,wic16.szPname);
+    lpCaps->dwFormats = wic16.dwFormats;
+    lpCaps->wChannels = wic16.wChannels;
+    return ret;
 }
 /**************************************************************************
  * 				waveInGetDevCaps 		[MMSYSTEM.502]
  */
 UINT16 WINAPI waveInGetDevCaps16(UINT16 uDeviceID, LPWAVEINCAPS16 lpCaps, UINT16 uSize)
 {
-	TRACE(mmsys, "waveInGetDevCaps\n");
-	return widMessage(uDeviceID, WIDM_GETDEVCAPS, 0L, (DWORD)lpCaps, uSize);
+    TRACE(mmsys, "waveInGetDevCaps\n");
+    return widMessage(uDeviceID, WIDM_GETDEVCAPS, 0L, (DWORD)lpCaps, uSize);
 }
 
 /**************************************************************************
@@ -3365,8 +3458,8 @@
  */
 UINT32 WINAPI waveInGetErrorText32A(UINT32 uError, LPSTR lpText, UINT32 uSize)
 {
-   TRACE(mmsys, "waveInGetErrorText\n");
-   return(waveGetErrorText(uError, lpText, uSize));
+    TRACE(mmsys, "waveInGetErrorText\n");
+    return(waveGetErrorText(uError, lpText, uSize));
 }
 
 /**************************************************************************
@@ -3374,12 +3467,12 @@
  */
 UINT32 WINAPI waveInGetErrorText32W(UINT32 uError, LPWSTR lpText, UINT32 uSize)
 {
-	LPSTR txt = HeapAlloc(GetProcessHeap(),0,uSize);
-	UINT32	ret = waveGetErrorText(uError, txt, uSize);
-
-	lstrcpyAtoW(lpText,txt);
-	HeapFree(GetProcessHeap(),0,txt);
-	return ret;
+    LPSTR txt = HeapAlloc(GetProcessHeap(),0,uSize);
+    UINT32	ret = waveGetErrorText(uError, txt, uSize);
+    
+    lstrcpyAtoW(lpText,txt);
+    HeapFree(GetProcessHeap(),0,txt);
+    return ret;
 }
 
 /**************************************************************************
@@ -3387,8 +3480,8 @@
  */
 UINT16 WINAPI waveInGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
 {
-   TRACE(mmsys, "waveInGetErrorText\n");
-   return(waveGetErrorText(uError, lpText, uSize));
+    TRACE(mmsys, "waveInGetErrorText\n");
+    return(waveGetErrorText(uError, lpText, uSize));
 }
 
 
@@ -3399,10 +3492,11 @@
                            const LPWAVEFORMAT lpFormat, DWORD dwCallback,
                            DWORD dwInstance, DWORD dwFlags)
 {
-	HWAVEIN16	hwin16;
-	UINT32	ret=waveInOpen16(&hwin16,uDeviceID,lpFormat,dwCallback,dwInstance,dwFlags);
-	if (lphWaveIn) *lphWaveIn = hwin16;
-	return ret;
+    HWAVEIN16	hwin16;
+    UINT32	ret = waveInOpen16(&hwin16,uDeviceID,lpFormat,dwCallback,dwInstance,
+				 CALLBACK32CONV(dwFlags));
+    if (lphWaveIn) *lphWaveIn = hwin16;
+    return ret;
 }
 
 /**************************************************************************
@@ -3412,42 +3506,42 @@
                            const LPWAVEFORMAT lpFormat, DWORD dwCallback,
                            DWORD dwInstance, DWORD dwFlags)
 {
-	HWAVEIN16 hWaveIn;
-	LPWAVEOPENDESC	lpDesc;
-	DWORD	dwRet = 0;
-	BOOL32	bMapperFlg = FALSE;
-	TRACE(mmsys, "(%p, %d, %p, %08lX, %08lX, %08lX);\n", 
-		lphWaveIn, uDeviceID, lpFormat, dwCallback, dwInstance, dwFlags);
-	if (dwFlags & WAVE_FORMAT_QUERY)
-		TRACE(mmsys, "WAVE_FORMAT_QUERY requested !\n");
-	if (uDeviceID == (UINT16)WAVE_MAPPER) {
-		TRACE(mmsys, "WAVE_MAPPER mode requested !\n");
-		bMapperFlg = TRUE;
-		uDeviceID = 0;
-	}
-	if (lpFormat == NULL) return WAVERR_BADFORMAT;
-	hWaveIn = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
-	if (lphWaveIn != NULL) *lphWaveIn = hWaveIn;
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
-	if (lpDesc == NULL) return MMSYSERR_NOMEM;
-	lpDesc->hWave = hWaveIn;
-	lpDesc->lpFormat = lpFormat;
-	lpDesc->dwCallBack = dwCallback;
-	lpDesc->dwInstance = dwInstance;
-	while(uDeviceID < MAXWAVEDRIVERS) {
-		dwRet = widMessage(uDeviceID, WIDM_OPEN, 
-			lpDesc->dwInstance, (DWORD)lpDesc, 0L);
-		if (dwRet == MMSYSERR_NOERROR) break;
-		if (!bMapperFlg) break;
-		uDeviceID++;
-		TRACE(mmsys, "WAVE_MAPPER mode ! try next driver...\n");
-	}
-	lpDesc->uDeviceID = uDeviceID;
-	if (dwFlags & WAVE_FORMAT_QUERY) {
-		TRACE(mmsys, "End of WAVE_FORMAT_QUERY !\n");
-		dwRet = waveInClose16(hWaveIn);
-	}
-	return dwRet;
+    HWAVEIN16 hWaveIn;
+    LPWAVEOPENDESC	lpDesc;
+    DWORD	dwRet = 0;
+    BOOL32	bMapperFlg = FALSE;
+    TRACE(mmsys, "(%p, %d, %p, %08lX, %08lX, %08lX);\n", 
+	  lphWaveIn, uDeviceID, lpFormat, dwCallback, dwInstance, dwFlags);
+    if (dwFlags & WAVE_FORMAT_QUERY)
+	TRACE(mmsys, "WAVE_FORMAT_QUERY requested !\n");
+    if (uDeviceID == (UINT16)WAVE_MAPPER) {
+	TRACE(mmsys, "WAVE_MAPPER mode requested !\n");
+	bMapperFlg = TRUE;
+	uDeviceID = 0;
+    }
+    if (lpFormat == NULL) return WAVERR_BADFORMAT;
+    hWaveIn = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
+    if (lphWaveIn != NULL) *lphWaveIn = hWaveIn;
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
+    if (lpDesc == NULL) return MMSYSERR_NOMEM;
+    lpDesc->hWave = hWaveIn;
+    lpDesc->lpFormat = lpFormat;
+    lpDesc->dwCallBack = dwCallback;
+    lpDesc->dwInstance = dwInstance;
+    while(uDeviceID < MAXWAVEDRIVERS) {
+	dwRet = widMessage(uDeviceID, WIDM_OPEN, 
+			   lpDesc->dwInstance, (DWORD)lpDesc, 0L);
+	if (dwRet == MMSYSERR_NOERROR) break;
+	if (!bMapperFlg) break;
+	uDeviceID++;
+	TRACE(mmsys, "WAVE_MAPPER mode ! try next driver...\n");
+    }
+    lpDesc->uDeviceID = uDeviceID;
+    if (dwFlags & WAVE_FORMAT_QUERY) {
+	TRACE(mmsys, "End of WAVE_FORMAT_QUERY !\n");
+	dwRet = waveInClose16(hWaveIn);
+    }
+    return dwRet;
 }
 
 /**************************************************************************
@@ -3455,68 +3549,68 @@
  */
 UINT32 WINAPI waveInClose32(HWAVEIN32 hWaveIn)
 {
-	return waveInClose16(hWaveIn);
+    return waveInClose16(hWaveIn);
 }
 /**************************************************************************
  * 				waveInClose			[MMSYSTEM.505]
  */
 UINT16 WINAPI waveInClose16(HWAVEIN16 hWaveIn)
 {
-	LPWAVEOPENDESC	lpDesc;
-
-	TRACE(mmsys, "(%04X)\n", hWaveIn);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return widMessage(lpDesc->uDeviceID, WIDM_CLOSE, lpDesc->dwInstance, 0L, 0L);
+    LPWAVEOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X)\n", hWaveIn);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    return widMessage(lpDesc->uDeviceID, WIDM_CLOSE, lpDesc->dwInstance, 0L, 0L);
 }
 
 /**************************************************************************
  * 				waveInPrepareHeader		[WINMM.155]
  */
 UINT32 WINAPI waveInPrepareHeader32(HWAVEIN32 hWaveIn,
-                                  WAVEHDR * lpWaveInHdr, UINT32 uSize)
+				    WAVEHDR * lpWaveInHdr, UINT32 uSize)
 {
-	LPWAVEOPENDESC	lpDesc;
-
-	TRACE(mmsys, "(%04X, %p, %u);\n", 
-					hWaveIn, lpWaveInHdr, uSize);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
-	lpWaveInHdr = lpWaveInHdr;
-	lpWaveInHdr->lpNext = NULL;
-    	lpWaveInHdr->dwBytesRecorded = 0;
-	TRACE(mmsys, "lpData=%p size=%lu \n", 
-		lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
-	return widMessage(lpDesc->uDeviceID,WIDM_PREPARE,lpDesc->dwInstance, 
-			  (DWORD)lpWaveInHdr, uSize);
+    LPWAVEOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X, %p, %u);\n", 
+	  hWaveIn, lpWaveInHdr, uSize);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
+    lpWaveInHdr = lpWaveInHdr;
+    lpWaveInHdr->lpNext = NULL;
+    lpWaveInHdr->dwBytesRecorded = 0;
+    TRACE(mmsys, "lpData=%p size=%lu \n", 
+	  lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
+    return widMessage(lpDesc->uDeviceID,WIDM_PREPARE,lpDesc->dwInstance, 
+		      (DWORD)lpWaveInHdr, uSize);
 }
 /**************************************************************************
  * 				waveInPrepareHeader		[MMSYSTEM.506]
  */
 UINT16 WINAPI waveInPrepareHeader16(HWAVEIN16 hWaveIn,
-                                  WAVEHDR * lpWaveInHdr, UINT16 uSize)
+				    WAVEHDR * lpWaveInHdr, UINT16 uSize)
 {
-	LPWAVEOPENDESC	lpDesc;
-	LPBYTE		saveddata = lpWaveInHdr->lpData;
-	UINT16		ret;
-
-	TRACE(mmsys, "(%04X, %p, %u);\n", 
-					hWaveIn, lpWaveInHdr, uSize);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
-	lpWaveInHdr = lpWaveInHdr;
-	lpWaveInHdr->lpNext = NULL;
-    	lpWaveInHdr->dwBytesRecorded = 0;
-
-	TRACE(mmsys, "lpData=%p size=%lu \n", 
-		lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
-	lpWaveInHdr->lpData = PTR_SEG_TO_LIN(lpWaveInHdr->lpData);
-	ret = widMessage(lpDesc->uDeviceID,WIDM_PREPARE,lpDesc->dwInstance, 
-			  (DWORD)lpWaveInHdr,uSize);
-	lpWaveInHdr->lpData = saveddata;
-	return ret;
+    LPWAVEOPENDESC	lpDesc;
+    LPBYTE		saveddata = lpWaveInHdr->lpData;
+    UINT16		ret;
+    
+    TRACE(mmsys, "(%04X, %p, %u);\n", 
+	  hWaveIn, lpWaveInHdr, uSize);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
+    lpWaveInHdr = lpWaveInHdr;
+    lpWaveInHdr->lpNext = NULL;
+    lpWaveInHdr->dwBytesRecorded = 0;
+    
+    TRACE(mmsys, "lpData=%p size=%lu \n", 
+	  lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
+    lpWaveInHdr->lpData = PTR_SEG_TO_LIN(lpWaveInHdr->lpData);
+    ret = widMessage(lpDesc->uDeviceID,WIDM_PREPARE,lpDesc->dwInstance, 
+		     (DWORD)lpWaveInHdr,uSize);
+    lpWaveInHdr->lpData = saveddata;
+    return ret;
 }
 
 
@@ -3526,18 +3620,18 @@
 UINT32 WINAPI waveInUnprepareHeader32(HWAVEIN32 hWaveIn,
                                       WAVEHDR * lpWaveInHdr, UINT32 uSize)
 {
-	LPWAVEOPENDESC	lpDesc;
-
-	TRACE(mmsys, "(%04X, %p, %u);\n", 
-						hWaveIn, lpWaveInHdr, uSize);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
-	/*USER_HEAP_FREE(HIWORD((DWORD)lpWaveInHdr->lpData)); FIXME */
-	lpWaveInHdr->lpData = NULL;
-	lpWaveInHdr->lpNext = NULL;
-	return widMessage(lpDesc->uDeviceID,WIDM_UNPREPARE,lpDesc->dwInstance, 
-			  (DWORD)lpWaveInHdr, uSize);
+    LPWAVEOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X, %p, %u);\n", 
+	  hWaveIn, lpWaveInHdr, uSize);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
+    /*USER_HEAP_FREE(HIWORD((DWORD)lpWaveInHdr->lpData)); FIXME */
+    lpWaveInHdr->lpData = NULL;
+    lpWaveInHdr->lpNext = NULL;
+    return widMessage(lpDesc->uDeviceID,WIDM_UNPREPARE,lpDesc->dwInstance, 
+		      (DWORD)lpWaveInHdr, uSize);
 }
 /**************************************************************************
  * 				waveInUnprepareHeader	[MMSYSTEM.507]
@@ -3545,18 +3639,18 @@
 UINT16 WINAPI waveInUnprepareHeader16(HWAVEIN16 hWaveIn,
                                       WAVEHDR * lpWaveInHdr, UINT16 uSize)
 {
-	LPWAVEOPENDESC	lpDesc;
-
-	TRACE(mmsys, "(%04X, %p, %u);\n", 
-						hWaveIn, lpWaveInHdr, uSize);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
-	/*USER_HEAP_FREE(HIWORD((DWORD)lpWaveInHdr->lpData)); FIXME */
-	lpWaveInHdr->lpData = NULL;
-	lpWaveInHdr->lpNext = NULL;
-	return widMessage(lpDesc->uDeviceID,WIDM_UNPREPARE,lpDesc->dwInstance, 
-			  (DWORD)lpWaveInHdr, uSize);
+    LPWAVEOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X, %p, %u);\n", 
+	  hWaveIn, lpWaveInHdr, uSize);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
+    /*USER_HEAP_FREE(HIWORD((DWORD)lpWaveInHdr->lpData)); FIXME */
+    lpWaveInHdr->lpData = NULL;
+    lpWaveInHdr->lpNext = NULL;
+    return widMessage(lpDesc->uDeviceID,WIDM_UNPREPARE,lpDesc->dwInstance, 
+		      (DWORD)lpWaveInHdr, uSize);
 }
 
 /**************************************************************************
@@ -3565,19 +3659,19 @@
 UINT32 WINAPI waveInAddBuffer32(HWAVEIN32 hWaveIn,
                                 WAVEHDR * lpWaveInHdr, UINT32 uSize)
 {
-	LPWAVEOPENDESC	lpDesc;
-
-	TRACE(mmsys, "(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
-	lpWaveInHdr->lpNext = NULL;
-	lpWaveInHdr->dwBytesRecorded = 0;
-	TRACE(mmsys, "lpData=%p size=%lu \n", 
-		lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
-	return widMessage(lpDesc->uDeviceID, WIDM_ADDBUFFER, lpDesc->dwInstance,
-								(DWORD)lpWaveInHdr, uSize);
-	
+    LPWAVEOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
+    lpWaveInHdr->lpNext = NULL;
+    lpWaveInHdr->dwBytesRecorded = 0;
+    TRACE(mmsys, "lpData=%p size=%lu \n", 
+	  lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
+    return widMessage(lpDesc->uDeviceID, WIDM_ADDBUFFER, lpDesc->dwInstance,
+		      (DWORD)lpWaveInHdr, uSize);
+    
 }
 
 /**************************************************************************
@@ -3586,22 +3680,22 @@
 UINT16 WINAPI waveInAddBuffer16(HWAVEIN16 hWaveIn,
                                 WAVEHDR * lpWaveInHdr, UINT16 uSize)
 {
-	LPWAVEOPENDESC	lpDesc;
-	UINT16		ret;
-
-	TRACE(mmsys, "(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
-	lpWaveInHdr->lpNext = NULL;
-	lpWaveInHdr->dwBytesRecorded = 0;
-	lpWaveInHdr->lpData = PTR_SEG_TO_LIN(lpWaveInHdr->lpData);
-	TRACE(mmsys, "lpData=%p size=%lu \n", 
-		lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
-	ret = widMessage(lpDesc->uDeviceID, WIDM_ADDBUFFER, lpDesc->dwInstance,
-			  (DWORD)lpWaveInHdr, uSize);
-	/*lpWaveInHdr->lpData = saveddata;*/
-	return ret;
+    LPWAVEOPENDESC	lpDesc;
+    UINT16		ret;
+    
+    TRACE(mmsys, "(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
+    lpWaveInHdr->lpNext = NULL;
+    lpWaveInHdr->dwBytesRecorded = 0;
+    lpWaveInHdr->lpData = PTR_SEG_TO_LIN(lpWaveInHdr->lpData);
+    TRACE(mmsys, "lpData=%p size=%lu \n", 
+	  lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
+    ret = widMessage(lpDesc->uDeviceID, WIDM_ADDBUFFER, lpDesc->dwInstance,
+		     (DWORD)lpWaveInHdr, uSize);
+    /*lpWaveInHdr->lpData = saveddata;*/
+    return ret;
 }
 
 /**************************************************************************
@@ -3609,7 +3703,7 @@
  */
 UINT32 WINAPI waveInStart32(HWAVEIN32 hWaveIn)
 {
-	return waveInStart16(hWaveIn);
+    return waveInStart16(hWaveIn);
 }
 
 /**************************************************************************
@@ -3617,12 +3711,12 @@
  */
 UINT16 WINAPI waveInStart16(HWAVEIN16 hWaveIn)
 {
-	LPWAVEOPENDESC	lpDesc;
-
-	TRACE(mmsys, "(%04X)\n", hWaveIn);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return widMessage(lpDesc->uDeviceID,WIDM_START,lpDesc->dwInstance,0,0);
+    LPWAVEOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X)\n", hWaveIn);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    return widMessage(lpDesc->uDeviceID,WIDM_START,lpDesc->dwInstance,0,0);
 }
 
 /**************************************************************************
@@ -3630,7 +3724,7 @@
  */
 UINT32 WINAPI waveInStop32(HWAVEIN32 hWaveIn)
 {
-	return waveInStop16(hWaveIn);
+    return waveInStop16(hWaveIn);
 }
 
 /**************************************************************************
@@ -3638,12 +3732,12 @@
  */
 UINT16 WINAPI waveInStop16(HWAVEIN16 hWaveIn)
 {
-	LPWAVEOPENDESC	lpDesc;
-
-	TRACE(mmsys, "(%04X)\n", hWaveIn);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return widMessage(lpDesc->uDeviceID, WIDM_STOP, lpDesc->dwInstance, 0L, 0L);
+    LPWAVEOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X)\n", hWaveIn);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    return widMessage(lpDesc->uDeviceID, WIDM_STOP, lpDesc->dwInstance, 0L, 0L);
 }
 
 /**************************************************************************
@@ -3651,7 +3745,7 @@
  */
 UINT32 WINAPI waveInReset32(HWAVEIN32 hWaveIn)
 {
-	return waveInReset16(hWaveIn);
+    return waveInReset16(hWaveIn);
 }
 
 /**************************************************************************
@@ -3659,12 +3753,12 @@
  */
 UINT16 WINAPI waveInReset16(HWAVEIN16 hWaveIn)
 {
-	LPWAVEOPENDESC	lpDesc;
-
-	TRACE(mmsys, "(%04X)\n", hWaveIn);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return widMessage(lpDesc->uDeviceID,WIDM_RESET,lpDesc->dwInstance,0,0);
+    LPWAVEOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X)\n", hWaveIn);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    return widMessage(lpDesc->uDeviceID,WIDM_RESET,lpDesc->dwInstance,0,0);
 }
 
 /**************************************************************************
@@ -3673,11 +3767,11 @@
 UINT32 WINAPI waveInGetPosition32(HWAVEIN32 hWaveIn, LPMMTIME32 lpTime,
                                   UINT32 uSize)
 {
-	MMTIME16 mmt16;
-	UINT32	ret = waveInGetPosition16(hWaveIn,&mmt16,uSize);
-
-	MMSYSTEM_MMTIME16to32(lpTime,&mmt16);
-	return ret;
+    MMTIME16	mmt16;
+    UINT32	ret = waveInGetPosition16(hWaveIn,&mmt16,uSize);
+    
+    MMSYSTEM_MMTIME16to32(lpTime,&mmt16);
+    return ret;
 }
 
 /**************************************************************************
@@ -3686,13 +3780,13 @@
 UINT16 WINAPI waveInGetPosition16(HWAVEIN16 hWaveIn,LPMMTIME16 lpTime,
                                   UINT16 uSize)
 {
-	LPWAVEOPENDESC	lpDesc;
-
-	TRACE(mmsys, "(%04X, %p, %u);\n", hWaveIn, lpTime, uSize);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return widMessage(lpDesc->uDeviceID, WIDM_GETPOS, lpDesc->dwInstance,
-			  (DWORD)lpTime, (DWORD)uSize);
+    LPWAVEOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "(%04X, %p, %u);\n", hWaveIn, lpTime, uSize);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    return widMessage(lpDesc->uDeviceID, WIDM_GETPOS, lpDesc->dwInstance,
+		      (DWORD)lpTime, (DWORD)uSize);
 }
 
 /**************************************************************************
@@ -3700,14 +3794,14 @@
  */
 UINT32 WINAPI waveInGetID32(HWAVEIN32 hWaveIn, UINT32 * lpuDeviceID)
 {
-	LPWAVEOPENDESC	lpDesc;
-
-	TRACE(mmsys, "waveInGetID\n");
-	if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	*lpuDeviceID = lpDesc->uDeviceID;
-	return 0;
+    LPWAVEOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "waveInGetID\n");
+    if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    *lpuDeviceID = lpDesc->uDeviceID;
+    return 0;
 }
 
 
@@ -3716,14 +3810,14 @@
  */
 UINT16 WINAPI waveInGetID16(HWAVEIN16 hWaveIn, UINT16 * lpuDeviceID)
 {
-	LPWAVEOPENDESC	lpDesc;
-
-	TRACE(mmsys, "waveInGetID\n");
-	if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	*lpuDeviceID = lpDesc->uDeviceID;
-	return 0;
+    LPWAVEOPENDESC	lpDesc;
+    
+    TRACE(mmsys, "waveInGetID\n");
+    if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    *lpuDeviceID = lpDesc->uDeviceID;
+    return 0;
 }
 
 /**************************************************************************
@@ -3732,37 +3826,37 @@
 DWORD WINAPI waveInMessage32(HWAVEIN32 hWaveIn, UINT32 uMessage,
                              DWORD dwParam1, DWORD dwParam2)
 {
-	LPWAVEOPENDESC	lpDesc;
-
-	FIXME(mmsys, "(%04X, %04X, %08lX, %08lX),FIXME!\n", 
-	      hWaveIn, uMessage, dwParam1, dwParam2);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	switch (uMessage) {
-	case WIDM_OPEN:
-		FIXME(mmsys, "cannot handle WIDM_OPEN, please report.\n");
-		break;
-	case WIDM_GETNUMDEVS:
-	case WIDM_GETPOS:
-	case WIDM_CLOSE:
-	case WIDM_STOP :
-	case WIDM_RESET:
-	case WIDM_START:
-	case WIDM_PREPARE:
-	case WIDM_UNPREPARE:
-	case WIDM_ADDBUFFER:
-	case WIDM_PAUSE:
-		/* no argument conversion needed */
-		break;
-	case WIDM_GETDEVCAPS:
-		/*FIXME: ANSI/UNICODE */
-		return waveInGetDevCaps32A(hWaveIn,(LPWAVEINCAPS32A)dwParam1,dwParam2);
-	default:
-		ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
-		    hWaveIn,uMessage,dwParam1,dwParam2);
-		break;
-	}
-	return widMessage(lpDesc->uDeviceID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
+    LPWAVEOPENDESC	lpDesc;
+    
+    FIXME(mmsys, "(%04X, %04X, %08lX, %08lX),FIXME!\n", 
+	  hWaveIn, uMessage, dwParam1, dwParam2);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    switch (uMessage) {
+    case WIDM_OPEN:
+	FIXME(mmsys, "cannot handle WIDM_OPEN, please report.\n");
+	break;
+    case WIDM_GETNUMDEVS:
+    case WIDM_GETPOS:
+    case WIDM_CLOSE:
+    case WIDM_STOP :
+    case WIDM_RESET:
+    case WIDM_START:
+    case WIDM_PREPARE:
+    case WIDM_UNPREPARE:
+    case WIDM_ADDBUFFER:
+    case WIDM_PAUSE:
+	/* no argument conversion needed */
+	break;
+    case WIDM_GETDEVCAPS:
+	/*FIXME: ANSI/UNICODE */
+	return waveInGetDevCaps32A(hWaveIn,(LPWAVEINCAPS32A)dwParam1,dwParam2);
+    default:
+	ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
+	    hWaveIn,uMessage,dwParam1,dwParam2);
+	break;
+    }
+    return widMessage(lpDesc->uDeviceID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
 }
 
 /**************************************************************************
@@ -3771,40 +3865,40 @@
 DWORD WINAPI waveInMessage16(HWAVEIN16 hWaveIn, UINT16 uMessage,
                              DWORD dwParam1, DWORD dwParam2)
 {
-	LPWAVEOPENDESC	lpDesc;
-
-	FIXME(mmsys, "(%04X, %04X, %08lX, %08lX),FIXME!\n", 
-	      hWaveIn, uMessage, dwParam1, dwParam2);
-	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
-	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	switch (uMessage) {
-	case WIDM_OPEN:
-		FIXME(mmsys,"cannot handle WIDM_OPEN, please report.\n");
-		break;
-	case WIDM_GETNUMDEVS:
-	case WIDM_CLOSE:
-	case WIDM_STOP :
-	case WIDM_RESET:
-	case WIDM_START:
-	case WIDM_PAUSE:
-		/* no argument conversion needed */
-		break;
-	case WIDM_GETDEVCAPS:
-		return waveInGetDevCaps16(hWaveIn,(LPWAVEINCAPS16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
-	case WIDM_GETPOS:
-		return waveInGetPosition16(hWaveIn,(LPMMTIME16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
-	case WIDM_PREPARE:
-		return waveInPrepareHeader16(hWaveIn,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
-	case WIDM_UNPREPARE:
-		return waveInUnprepareHeader16(hWaveIn,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
-	case WIDM_ADDBUFFER:
-		return waveInAddBuffer16(hWaveIn,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
-	default:
-		ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
-		    hWaveIn,uMessage,dwParam1,dwParam2);
-		break;
-	}
-	return widMessage(lpDesc->uDeviceID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
+    LPWAVEOPENDESC	lpDesc;
+    
+    FIXME(mmsys, "(%04X, %04X, %08lX, %08lX),FIXME!\n", 
+	  hWaveIn, uMessage, dwParam1, dwParam2);
+    lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
+    if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+    switch (uMessage) {
+    case WIDM_OPEN:
+	FIXME(mmsys,"cannot handle WIDM_OPEN, please report.\n");
+	break;
+    case WIDM_GETNUMDEVS:
+    case WIDM_CLOSE:
+    case WIDM_STOP :
+    case WIDM_RESET:
+    case WIDM_START:
+    case WIDM_PAUSE:
+	/* no argument conversion needed */
+	break;
+    case WIDM_GETDEVCAPS:
+	return waveInGetDevCaps16(hWaveIn,(LPWAVEINCAPS16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+    case WIDM_GETPOS:
+	return waveInGetPosition16(hWaveIn,(LPMMTIME16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+    case WIDM_PREPARE:
+	return waveInPrepareHeader16(hWaveIn,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+    case WIDM_UNPREPARE:
+	return waveInUnprepareHeader16(hWaveIn,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+    case WIDM_ADDBUFFER:
+	return waveInAddBuffer16(hWaveIn,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
+    default:
+	ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
+	    hWaveIn,uMessage,dwParam1,dwParam2);
+	break;
+    }
+    return widMessage(lpDesc->uDeviceID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
 }
 
 /**************************************************************************
@@ -3812,8 +3906,8 @@
  */
 HDRVR16 WINAPI DrvOpen(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam)
 {
-	TRACE(mmsys,"('%s','%s',%08lX);\n",lpDriverName,lpSectionName,lParam);
-	return OpenDriver16(lpDriverName, lpSectionName, lParam);
+    TRACE(mmsys,"('%s','%s',%08lX);\n",lpDriverName,lpSectionName,lParam);
+    return OpenDriver16(lpDriverName, lpSectionName, lParam);
 }
 
 
@@ -3822,8 +3916,8 @@
  */
 LRESULT WINAPI DrvClose(HDRVR16 hDrvr, LPARAM lParam1, LPARAM lParam2)
 {
-	TRACE(mmsys, "(%04X, %08lX, %08lX);\n", hDrvr, lParam1, lParam2);
-	return CloseDriver16(hDrvr, lParam1, lParam2);
+    TRACE(mmsys, "(%04X, %08lX, %08lX);\n", hDrvr, lParam1, lParam2);
+    return CloseDriver16(hDrvr, lParam1, lParam2);
 }
 
 
@@ -3833,11 +3927,11 @@
 LRESULT WINAPI DrvSendMessage(HDRVR16 hDriver, WORD msg, LPARAM lParam1,
                               LPARAM lParam2)
 {
-	DWORD 	dwDriverID = 0;
-	FIXME(mmsys, "(%04X, %04X, %08lX, %08lX);\n",
-					hDriver, msg, lParam1, lParam2);
-	/* FIXME: wrong ... */
-	return CDAUDIO_DriverProc(dwDriverID, hDriver, msg, lParam1, lParam2);
+    DWORD 	dwDriverID = 0;
+    FIXME(mmsys, "(%04X, %04X, %08lX, %08lX);\n",
+	  hDriver, msg, lParam1, lParam2);
+    /* FIXME: wrong ... */
+    return CDAUDIO_DriverProc(dwDriverID, hDriver, msg, lParam1, lParam2);
 }
 
 /**************************************************************************
@@ -3845,7 +3939,7 @@
  */
 HANDLE16 WINAPI DrvGetModuleHandle16(HDRVR16 hDrvr)
 {
-        return GetDriverModuleHandle16(hDrvr);
+    return GetDriverModuleHandle16(hDrvr);
 }
 
 /**************************************************************************
@@ -3854,32 +3948,32 @@
 LRESULT WINAPI DrvDefDriverProc(DWORD dwDriverID, HDRVR16 hDriv, WORD wMsg, 
                                 DWORD dwParam1, DWORD dwParam2)
 {
-	return DefDriverProc(dwDriverID, hDriv, wMsg, dwParam1, dwParam2);
+    return DefDriverProc(dwDriverID, hDriv, wMsg, dwParam1, dwParam2);
 }
 
 /**************************************************************************
  * 				mmThreadCreate		[MMSYSTEM.1120]
  */
 LRESULT WINAPI mmThreadCreate16(LPVOID x1, LPWORD x2, DWORD x3, DWORD x4) {
-	FIXME(mmsys,"(%p,%p,%08lx,%08lx): stub!\n",x1,x2,x3,x4);
-	*x2 = 0xbabe;
-	return 0;
+    FIXME(mmsys,"(%p,%p,%08lx,%08lx): stub!\n",x1,x2,x3,x4);
+    *x2 = 0xbabe;
+    return 0;
 }
 
 /**************************************************************************
  * 				mmThreadGetTask		[MMSYSTEM.1125]
  */
 LRESULT WINAPI mmThreadGetTask16(WORD hnd) {
-	FIXME(mmsys,"(%04x): stub!\n",hnd);
-	return GetCurrentTask();
+    FIXME(mmsys,"(%04x): stub!\n",hnd);
+    return GetCurrentTask();
 }
 
 /**************************************************************************
  * 				mmThreadSignal		[MMSYSTEM.1121]
  */
 LRESULT WINAPI mmThreadSignal16(WORD hnd) {
-	FIXME(mmsys,"(%04x): stub!\n",hnd);
-	return 0;
+    FIXME(mmsys,"(%04x): stub!\n",hnd);
+    return 0;
 }
 
 /**************************************************************************
@@ -3892,24 +3986,24 @@
     WORD sel1, sel2;
     LOADPARAMS *lp;
     HINSTANCE16 ret, handle;
-
+    
     TRACE(mmsys,"(%p,%p,%08lx);\n",lphnd,hMmTask,x2);
     cmdline = (LPSTR)HeapAlloc(GetProcessHeap(), 0, 0x0d);
     cmdline[0] = 0x0d;
     (DWORD)cmdline[1] = (DWORD)lphnd;
     (DWORD)cmdline[5] = x2;
     (DWORD)cmdline[9] = 0;
-
+    
     sel1 = SELECTOR_AllocBlock(cmdline, 0x0d, SEGMENT_DATA, FALSE, FALSE);
     sel2 = SELECTOR_AllocBlock(&showCmd, sizeof(showCmd),
-		SEGMENT_DATA, FALSE, FALSE);
-
+			       SEGMENT_DATA, FALSE, FALSE);
+    
     lp = (LOADPARAMS *)HeapAlloc(GetProcessHeap(), 0, sizeof(LOADPARAMS));
     lp->hEnvironment = 0;
     lp->cmdLine = PTR_SEG_OFF_TO_SEGPTR(sel1, 0);
     lp->showCmd = PTR_SEG_OFF_TO_SEGPTR(sel2, 0);
     lp->reserved = 0;
-
+    
     ret = LoadModule16("c:\\windows\\mmtask.tsk", lp);
     if (ret < 32) {
 	if (ret)
@@ -3924,29 +4018,31 @@
     }
     if (hMmTask)
 	*(HINSTANCE16 *)PTR_SEG_TO_LIN(hMmTask) = handle;
-
+    
     UnMapLS(PTR_SEG_OFF_TO_SEGPTR(sel2, 0));
     UnMapLS(PTR_SEG_OFF_TO_SEGPTR(sel1, 0));
-
+    
     HeapFree(GetProcessHeap(), 0, lp);
     HeapFree(GetProcessHeap(), 0, cmdline);
-
+    
     return ret;
 }
 
 /**************************************************************************
  * 				mmTaskSignal		[MMSYSTEM.903]
  */
-LRESULT WINAPI mmTaskSignal16(HTASK16 ht) {
-	TRACE(mmsys,"(%04x);\n",ht);
-	return PostAppMessage16(ht,WM_USER,0,0);
+LRESULT WINAPI mmTaskSignal16(HTASK16 ht) 
+{
+    TRACE(mmsys,"(%04x);\n",ht);
+    return PostAppMessage16(ht,WM_USER,0,0);
 }
 
 /**************************************************************************
  * 				mciDriverYield		[MMSYSTEM.710]
  */
-LRESULT WINAPI mciDriverYield16(HANDLE16 hnd) {
-	FIXME(mmsys,"(%04x): stub!\n",hnd);
-	return 0;
+LRESULT WINAPI mciDriverYield16(HANDLE16 hnd) 
+{
+    FIXME(mmsys,"(%04x): stub!\n",hnd);
+    return 0;
 }
 
diff --git a/multimedia/msvideo.c b/multimedia/msvideo.c
index 387f85b..bbd2ea0 100644
--- a/multimedia/msvideo.c
+++ b/multimedia/msvideo.c
@@ -1,21 +1,153 @@
-/*
- * MSVIDEO procedures
- *
- * Copyright 1998 Luiz Otavio L. Zorzella
+/*				   
+ * Copyright 1998 Marcus Meissner
  */
+#include <stdio.h>
 
 #include "windows.h"
+#include "driver.h"
+#include "mmsystem.h"
+#include "ole2.h"
+#include "vfw.h"
 #include "debug.h"
 
-/***********************************************************************
- *           VideoForWindowsVersion     [MSVIDEO.2]
+/****************************************************************************
+ *		VideoForWindowsVersion		[MSVFW32.2][MSVIDEO.2]
+ * Returns the version in major.minor form.
+ * In Windows95 this returns 0x040003b6 (4.950)
  */
-DWORD WINAPI VideoForWindowsVersion ()
-{
+DWORD WINAPI
+VideoForWindowsVersion(void) {
+	return 0x040003B6; /* 4.950 */
+}
 
-  FIXME (msvideo, "(void): stub\n");
+/* system.ini: [drivers32] */
 
-  /* What should be returned? */
-  return 1;
-  
+/**************************************************************************
+ *		ICInfo				[MSVFW32.33]
+ * Get information about an installable compressor. Return TRUE if there
+ * is one.
+ */
+BOOL32 WINAPI
+ICInfo32(
+	DWORD fccType,		/* [in] type of compressor ('vidc') */
+	DWORD fccHandler,	/* [in] <n>th compressor */
+	ICINFO32 *lpicinfo	/* [out] information about compressor */
+) {
+	char	type[5],buf[2000];
+
+	memcpy(type,&fccType,4);type[4]=0;
+	TRACE(mmsys,"(%s,%ld,%p).\n",type,fccHandler,lpicinfo);
+	/* does OpenDriver/CloseDriver */
+	lpicinfo->dwSize = sizeof(ICINFO32);
+	lpicinfo->fccType = fccType;
+	lpicinfo->dwFlags = 0;
+	if (GetPrivateProfileString32A("drivers32",NULL,NULL,buf,2000,"system.ini")) {
+		char *s = buf;
+		while (*s) {
+			if (!lstrncmpi32A(type,s,4)) {
+				if(!fccHandler--) {
+					lpicinfo->fccHandler = mmioStringToFOURCC32A(s+5,0);
+					return TRUE;
+				}
+			}
+			s=s+lstrlen32A(s)+1; /* either next char or \0 */
+		}
+	}
+	return FALSE;
+}
+
+/**************************************************************************
+ *		ICOpen				[MSVFW32.37]
+ * Opens an installable compressor. Return special handle.
+ */
+HIC32 WINAPI
+ICOpen32(DWORD fccType,DWORD fccHandler,UINT32 wMode) {
+	char		type[5],handler[5],codecname[20];
+	ICOPEN		icopen;
+	HDRVR32		hdrv;
+	WINE_HIC	*whic;
+
+	memcpy(type,&fccType,4);type[4]=0;
+	memcpy(handler,&fccHandler,4);handler[4]=0;
+	TRACE(mmsys,"(%s,%s,0x%08lx)\n",type,handler,(DWORD)wMode);
+	sprintf(codecname,"%s.%s",type,handler);
+	hdrv=OpenDriver32A(codecname,"drivers32",0);
+	if (!hdrv)
+		return 0;
+	whic = HeapAlloc(GetProcessHeap(),0,sizeof(WINE_HIC));
+	whic->hdrv	= hdrv;
+	whic->driverproc= GetProcAddress32(GetDriverModuleHandle32(hdrv),"DriverProc");
+	/* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the 
+	 * same layout as ICOPEN
+	 */
+	icopen.fccType		= fccType;
+	icopen.fccHandler	= fccHandler;
+	icopen.dwSize		= sizeof(ICOPEN);
+	/* FIXME: fill out rest too... */
+	whic->private	= whic->driverproc(0,hdrv,DRV_OPEN,0,&icopen);
+	return (HIC32)whic;
+}
+
+LRESULT WINAPI
+ICGetInfo32(HIC32 hic,ICINFO32 *picinfo,DWORD cb) {
+	LRESULT		ret;
+	WINE_HIC	*whic = (WINE_HIC*)hic;
+
+	TRACE(mmsys,"(0x%08lx,%p,%ld)\n",(DWORD)hic,picinfo,cb);
+	ret = ICSendMessage32(whic,ICM_GETINFO,(DWORD)picinfo,cb);
+	TRACE(mmsys,"	-> 0x%08lx\n",ret);
+	return ret;
+}
+
+
+HIC32 WINAPI
+ICLocate(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
+	 LPBITMAPINFOHEADER lpbiOut, WORD wFlags
+) {
+	FIXME(mmsys,"stub!\n");
+	return 0;
+}
+
+LRESULT VFWAPI
+ICSendMessage32(HIC32 hic,UINT32 msg,DWORD lParam1,DWORD lParam2) {
+	LRESULT		ret;
+	WINE_HIC	*whic = (WINE_HIC*)hic;
+
+	switch (msg) {
+	case ICM_GETINFO:
+		FIXME(mmsys,"(0x%08lx,ICM_GETINFO,0x%08lx,0x%08lx)\n",(DWORD)hic,lParam1,lParam2);
+		break;
+	default:
+		FIXME(mmsys,"(0x%08lx,0x%08lx,0x%08lx,0x%08lx)\n",(DWORD)hic,(DWORD)msg,lParam1,lParam2);
+	}
+	ret = whic->driverproc(whic->private,whic->hdrv,msg,lParam1,lParam2);
+	FIXME(mmsys,"	-> 0x%08lx\n",ret);
+	return ret;
+}
+
+
+DWORD	VFWAPIV	ICDrawBegin32(
+        HIC32			hic,
+        DWORD			dwFlags,/* flags */
+        HPALETTE32		hpal,	/* palette to draw with */
+        HWND32			hwnd,	/* window to draw to */
+        HDC32			hdc,	/* HDC to draw to */
+        INT32			xDst,	/* destination rectangle */
+        INT32			yDst,
+        INT32			dxDst,
+        INT32			dyDst,
+        LPBITMAPINFOHEADER	lpbi,	/* format of frame to draw */
+        INT32			xSrc,	/* source rectangle */
+        INT32			ySrc,
+        INT32			dxSrc,
+        INT32			dySrc,
+        DWORD			dwRate,	/* frames/second = (dwRate/dwScale) */
+        DWORD			dwScale) {
+		return 0;
+}
+
+HANDLE32 /* HDRAWDIB */ WINAPI
+DrawDibOpen32() {
+	FIXME(mmsys,"stub!\n");
+	return 0;
 }
diff --git a/multimedia/time.c b/multimedia/time.c
index 7426605..b4b6eb0 100644
--- a/multimedia/time.c
+++ b/multimedia/time.c
@@ -1,3 +1,5 @@
+/* -*- tab-width: 8; c-basic-offset: 4 -*- */
+
 /*
  * MMSYTEM time functions
  *
@@ -6,6 +8,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 #include "windows.h"
 #include "win.h"
 #include "ldt.h"
@@ -16,33 +19,34 @@
 #include "mmsystem.h"
 #include "debug.h"
 #include "xmalloc.h"
+#include "options.h"
 
-static BOOL32 mmTimeStarted = FALSE;
+#define USE_FAKE_MM_TIMERS
+
 static MMTIME16 mmSysTimeMS;
 static MMTIME16 mmSysTimeSMPTE;
 
-/* this is used to avoid infinite loop in timeGetTime, because
-   of the faked multimedia timers, and will desappear as soon as
-   the timers are implemented correctly.
- */
-static int time_called=0;
-
 typedef struct tagTIMERENTRY {
-    UINT32	wDelay;
-    UINT32	wResol;
-    FARPROC16 lpFunc;
-    HINSTANCE32	hInstance;
-    DWORD	dwUser;
-    UINT32	wFlags;
-    UINT32	wTimerID;
-    UINT32	wCurTime;
-    UINT32	iswin32;
-    struct tagTIMERENTRY *Next;
-    DWORD	triggertime;
+    UINT32			wDelay;
+    UINT32			wResol;
+    FARPROC16 			lpFunc;
+    HINSTANCE32			hInstance;
+    DWORD			dwUser;
+    UINT32			wFlags;
+    UINT32			wTimerID;
+    UINT32			wCurTime;
+    UINT32			isWin32;
+    struct tagTIMERENTRY*	Next;
 } TIMERENTRY, *LPTIMERENTRY;
 
 static LPTIMERENTRY lpTimerList = NULL;
 
+#ifdef USE_FAKE_MM_TIMERS
+static DWORD dwLastCBTick = 0;
+static BOOL32 bUseFakeTimers = FALSE;
+static WORD wInCallBackLoop = 0;
+#endif
+
 /*
  * FIXME
  * We're using "1" as the mininum resolution to the timer,
@@ -52,46 +56,34 @@
 #define MMSYSTIME_MININTERVAL (1)
 #define MMSYSTIME_MAXINTERVAL (65535)
 
-
-/**************************************************************************
- *           check_MMtimers
- */
-static VOID check_MMtimers()
+static	void	TIME_TriggerCallBack(LPTIMERENTRY lpTimer, DWORD dwCurrent)
 {
-    LPTIMERENTRY lpTimer = lpTimerList;
-    DWORD	curtick = GetTickCount();
-
-    while (lpTimer != NULL) {
-    	if (lpTimer->triggertime <= curtick) {
-	    lpTimer->wCurTime = lpTimer->wDelay;
-
-	    if (lpTimer->lpFunc != (FARPROC16) NULL) {
-		TRACE(mmtime, "before CallBack16 !\n");
-		TRACE(mmtime, "lpFunc=%p wTimerID=%04X dwUser=%08lX !\n",
-			lpTimer->lpFunc, lpTimer->wTimerID, lpTimer->dwUser);
-		TRACE(mmtime, "hInstance=%04X !\n", lpTimer->hInstance);
-
-
-/*        - TimeProc callback that is called here is something strange, under Windows 3.1x it is called 
- *          during interrupt time,  is allowed to execute very limited number of API calls (like
- *	    PostMessage), and must reside in DLL (therefore uses stack of active application). So I 
- *          guess current implementation via SetTimer has to be improved upon.		
- */
- 		if (lpTimer->iswin32)
-			lpTimer->lpFunc(lpTimer->wTimerID,0,lpTimer->dwUser,0,0);
-		else
-			Callbacks->CallTimeFuncProc(lpTimer->lpFunc,
-						    lpTimer->wTimerID,0,
-						    lpTimer->dwUser,0,0
-			);
-
-		TRACE(mmtime, "after CallBack16 !\n");
-	    }
-	    if (lpTimer->wFlags & TIME_ONESHOT)
-		timeKillEvent32(lpTimer->wTimerID);
-	}
-	lpTimer = lpTimer->Next;
+    lpTimer->wCurTime = lpTimer->wDelay;
+    
+    if (lpTimer->lpFunc != (FARPROC16) NULL) {
+	TRACE(mmtime, "before CallBack16 (%lu)!\n", dwCurrent);
+	TRACE(mmtime, "lpFunc=%p wTimerID=%04X dwUser=%08lX !\n",
+	      lpTimer->lpFunc, lpTimer->wTimerID, lpTimer->dwUser);
+	TRACE(mmtime, "hInstance=%04X !\n", lpTimer->hInstance);
+	
+	
+	/* - TimeProc callback that is called here is something strange, under Windows 3.1x it is called 
+	 * 		during interrupt time,  is allowed to execute very limited number of API calls (like
+	 *	    	PostMessage), and must reside in DLL (therefore uses stack of active application). So I 
+	 *       guess current implementation via SetTimer has to be improved upon.		
+	 */
+	if (lpTimer->isWin32)
+	    lpTimer->lpFunc(lpTimer->wTimerID,0,lpTimer->dwUser,0,0);
+	else
+	    Callbacks->CallTimeFuncProc(lpTimer->lpFunc,
+					lpTimer->wTimerID,0,
+					lpTimer->dwUser,0,0);
+	
+	TRACE(mmtime, "after CallBack16 !\n");
+	fflush(stdout);
     }
+    if (lpTimer->wFlags & TIME_ONESHOT)
+	timeKillEvent32(lpTimer->wTimerID);
 }
 
 /**************************************************************************
@@ -100,49 +92,27 @@
 static VOID TIME_MMSysTimeCallback( HWND32 hwnd, UINT32 msg,
                                     UINT32 id, DWORD dwTime )
 {
-    LPTIMERENTRY lpTimer = lpTimerList;
+    LPTIMERENTRY lpTimer;
+    
     mmSysTimeMS.u.ms += MMSYSTIME_MININTERVAL;
     mmSysTimeSMPTE.u.smpte.frame++;
-    while (lpTimer != NULL) {
-	lpTimer->wCurTime--;
-	if (lpTimer->wCurTime == 0) {
-	    lpTimer->wCurTime = lpTimer->wDelay;
+    
+#ifdef USE_FAKE_MM_TIMERS
+    if (bUseFakeTimers)
+	dwLastCBTick = GetTickCount();
 
-	    if (lpTimer->lpFunc != (FARPROC16) NULL) {
-		TRACE(mmtime, "before CallBack16 !\n");
-		TRACE(mmtime, "lpFunc=%p wTimerID=%04X dwUser=%08lX !\n",
-			lpTimer->lpFunc, lpTimer->wTimerID, lpTimer->dwUser);
-		TRACE(mmtime, "hInstance=%04X !\n", lpTimer->hInstance);
-
-/* This is wrong (lpFunc is NULL all the time)
-
-   	        lpFunc = MODULE_GetEntryPoint( lpTimer->hInstance,
-                         MODULE_GetOrdinal(lpTimer->hInstance,"TimerCallBack" ));
-		TRACE(mmtime, "lpFunc=%08lx !\n", lpFunc);
-*/
-
-
-/*        - TimeProc callback that is called here is something strange, under Windows 3.1x it is called 
- *          during interrupt time,  is allowed to execute very limited number of API calls (like
- *	    PostMessage), and must reside in DLL (therefore uses stack of active application). So I 
- *          guess current implementation via SetTimer has to be improved upon.		
- */
- 		if (lpTimer->iswin32)
-			lpTimer->lpFunc(lpTimer->wTimerID,0,lpTimer->dwUser,0,0);
-		else
-			Callbacks->CallTimeFuncProc(lpTimer->lpFunc,
-						    lpTimer->wTimerID,0,
-						    lpTimer->dwUser,0,0
-			);
-
-		TRACE(mmtime, "after CallBack16 !\n");
-		fflush(stdout);
+    if (!wInCallBackLoop++)
+#endif
+	for (lpTimer = lpTimerList; lpTimer != NULL; lpTimer = lpTimer->Next) {
+	    if (lpTimer->wCurTime < MMSYSTIME_MININTERVAL) {
+		TIME_TriggerCallBack(lpTimer, dwTime);			
+	    } else {
+		lpTimer->wCurTime -= MMSYSTIME_MININTERVAL;
 	    }
-	    if (lpTimer->wFlags & TIME_ONESHOT)
-		timeKillEvent32(lpTimer->wTimerID);
 	}
-	lpTimer = lpTimer->Next;
-    }
+#ifdef USE_FAKE_MM_TIMERS
+    wInCallBackLoop--;
+#endif
 }
 
 /**************************************************************************
@@ -150,6 +120,8 @@
  */
 static void StartMMTime()
 {
+    static BOOL32 	mmTimeStarted = FALSE;
+    
     if (!mmTimeStarted) {
 	mmTimeStarted = TRUE;
 	mmSysTimeMS.wType = TIME_MS;
@@ -161,7 +133,13 @@
 	mmSysTimeSMPTE.u.smpte.frame = 0;
 	mmSysTimeSMPTE.u.smpte.fps = 0;
 	mmSysTimeSMPTE.u.smpte.dummy = 0;
-	SetTimer32( 0, 1, MMSYSTIME_MININTERVAL, TIME_MMSysTimeCallback );
+	SetTimer32( 0, 0, MMSYSTIME_MININTERVAL, TIME_MMSysTimeCallback );
+#ifdef USE_FAKE_MM_TIMERS
+	bUseFakeTimers = PROFILE_GetWineIniBool("options", "MMFakeTimers", TRUE);
+	TRACE(mmtime, "FakeTimer=%c\n", bUseFakeTimers ? 'Y' : 'N');
+	if (bUseFakeTimers)
+	    dwLastCBTick = GetTickCount();
+#endif
     }
 }
 
@@ -171,8 +149,7 @@
 MMRESULT32 WINAPI timeGetSystemTime32(LPMMTIME32 lpTime, UINT32 wSize)
 {
     TRACE(mmsys, "(%p, %u);\n", lpTime, wSize);
-    if (!mmTimeStarted)
-	StartMMTime();
+    StartMMTime();
     lpTime->wType = TIME_MS;
     lpTime->u.ms = mmSysTimeMS.u.ms;
     return 0;
@@ -184,13 +161,47 @@
 MMRESULT16 WINAPI timeGetSystemTime16(LPMMTIME16 lpTime, UINT16 wSize)
 {
     TRACE(mmsys, "(%p, %u);\n", lpTime, wSize);
-    if (!mmTimeStarted)
-	StartMMTime();
+    StartMMTime();
     lpTime->wType = TIME_MS;
     lpTime->u.ms = mmSysTimeMS.u.ms;
     return 0;
 }
 
+static	WORD	timeSetEventInternal(UINT32 wDelay,UINT32 wResol,
+				     FARPROC16 lpFunc,DWORD dwUser,
+				     UINT32 wFlags, UINT16 isWin32)
+{
+    WORD 		wNewID = 0;
+    LPTIMERENTRY	lpNewTimer;
+    LPTIMERENTRY	lpTimer = lpTimerList;
+    
+    TRACE(mmtime, "(%u, %u, %p, %08lX, %04X);\n",
+	  wDelay, wResol, lpFunc, dwUser, wFlags);
+    StartMMTime();
+    lpNewTimer = (LPTIMERENTRY)xmalloc(sizeof(TIMERENTRY));
+    if (lpNewTimer == NULL)
+	return 0;
+    while (lpTimer != NULL) {
+	wNewID = MAX(wNewID, lpTimer->wTimerID);
+	lpTimer = lpTimer->Next;
+    }
+    
+    lpNewTimer->Next = lpTimerList;
+    lpTimerList = lpNewTimer;
+    lpNewTimer->wTimerID = wNewID + 1;
+    lpNewTimer->wCurTime = wDelay;
+    lpNewTimer->wDelay = wDelay;
+    lpNewTimer->wResol = wResol;
+    lpNewTimer->lpFunc = lpFunc;
+    lpNewTimer->isWin32 = isWin32;
+    lpNewTimer->hInstance = GetTaskDS();
+    TRACE(mmtime, "hInstance=%04X !\n", lpNewTimer->hInstance);
+    TRACE(mmtime, "lpFunc=%p !\n", isWin32 ? lpFunc : PTR_SEG_TO_LIN(lpFunc));
+    lpNewTimer->dwUser = dwUser;
+    lpNewTimer->wFlags = wFlags;
+    return lpNewTimer->wTimerID;
+}
+
 /**************************************************************************
  * 				timeSetEvent		[MMSYSTEM.602]
  */
@@ -198,38 +209,8 @@
 				 LPTIMECALLBACK32 lpFunc,DWORD dwUser,
 				 UINT32 wFlags)
 {
-    WORD wNewID = 0;
-    LPTIMERENTRY lpNewTimer;
-    LPTIMERENTRY lpTimer = lpTimerList;
-
-    TRACE(mmtime, "(%u, %u, %p, %08lX, %04X);\n",
-		  wDelay, wResol, lpFunc, dwUser, wFlags);
-    if (!mmTimeStarted)
-	StartMMTime();
-    lpNewTimer = (LPTIMERENTRY)xmalloc(sizeof(TIMERENTRY));
-    if (lpNewTimer == NULL)
-	return 0;
-    while (lpTimer != NULL) {
-	wNewID = MAX(wNewID, lpTimer->wTimerID);
-	lpTimer = lpTimer->Next;
-    }
-
-    lpNewTimer->Next = lpTimerList;
-    lpTimerList = lpNewTimer;
-    lpNewTimer->wTimerID = wNewID + 1;
-    lpNewTimer->wCurTime = wDelay;
-    lpNewTimer->triggertime = wDelay+GetTickCount();
-    lpNewTimer->wDelay = wDelay;
-    lpNewTimer->wResol = wResol;
-    lpNewTimer->lpFunc = (FARPROC16) lpFunc;
-    lpNewTimer->iswin32 = 1;
-    lpNewTimer->hInstance = GetTaskDS();
-	TRACE(mmtime, "hInstance=%04X !\n", lpNewTimer->hInstance);
-	TRACE(mmtime, "lpFunc=%p !\n", 
-				lpFunc);
-    lpNewTimer->dwUser = dwUser;
-    lpNewTimer->wFlags = wFlags;
-    return lpNewTimer->wTimerID;
+    return timeSetEventInternal(wDelay, wResol, (FARPROC16)lpFunc, 
+				dwUser, wFlags, 1);
 }
 
 /**************************************************************************
@@ -239,37 +220,8 @@
 				 LPTIMECALLBACK16 lpFunc,DWORD dwUser,
 				 UINT16 wFlags)
 {
-    WORD wNewID = 0;
-    LPTIMERENTRY lpNewTimer;
-    LPTIMERENTRY lpTimer = lpTimerList;
-    TRACE(mmtime, "(%u, %u, %p, %08lX, %04X);\n",
-		  wDelay, wResol, lpFunc, dwUser, wFlags);
-    if (!mmTimeStarted)
-	StartMMTime();
-    lpNewTimer = (LPTIMERENTRY)xmalloc(sizeof(TIMERENTRY));
-    if (lpNewTimer == NULL)
-	return 0;
-    while (lpTimer != NULL) {
-	wNewID = MAX(wNewID, lpTimer->wTimerID);
-	lpTimer = lpTimer->Next;
-    }
-
-    lpNewTimer->Next = lpTimerList;
-    lpTimerList = lpNewTimer;
-    lpNewTimer->wTimerID = wNewID + 1;
-    lpNewTimer->wCurTime = wDelay;
-    lpNewTimer->wDelay = wDelay;
-    lpNewTimer->triggertime = wDelay+GetTickCount();
-    lpNewTimer->wResol = wResol;
-    lpNewTimer->lpFunc = (FARPROC16) lpFunc;
-    lpNewTimer->iswin32 = 0;
-    lpNewTimer->hInstance = GetTaskDS();
-	TRACE(mmtime, "hInstance=%04X !\n", lpNewTimer->hInstance);
-	TRACE(mmtime, "(lpFunc)=%p !\n", 
-				PTR_SEG_TO_LIN(lpFunc));
-    lpNewTimer->dwUser = dwUser;
-    lpNewTimer->wFlags = wFlags;
-    return lpNewTimer->wTimerID;
+    return timeSetEventInternal(wDelay, wResol, (FARPROC16)lpFunc, 
+				dwUser, wFlags, 0);
 }
 
 /**************************************************************************
@@ -277,15 +229,16 @@
  */
 MMRESULT32 WINAPI timeKillEvent32(UINT32 wID)
 {
-    LPTIMERENTRY xlptimer,*lpTimer = &lpTimerList;
-    while (*lpTimer) {
+    LPTIMERENTRY*	lpTimer;
+    
+    for (lpTimer = &lpTimerList; *lpTimer; lpTimer = &((*lpTimer)->Next)) {
 	if (wID == (*lpTimer)->wTimerID) {
-	    xlptimer = (*lpTimer)->Next;
+	    LPTIMERENTRY xlptimer = (*lpTimer)->Next;
+	    
 	    free(*lpTimer);
 	    *lpTimer = xlptimer;
 	    return TRUE;
 	}
-	lpTimer = &((*lpTimer)->Next);
     }
     return 0;
 }
@@ -304,8 +257,7 @@
 MMRESULT32 WINAPI timeGetDevCaps32(LPTIMECAPS32 lpCaps,UINT32 wSize)
 {
     TRACE(mmtime, "(%p, %u) !\n", lpCaps, wSize);
-    if (!mmTimeStarted)
-	StartMMTime();
+    StartMMTime();
     lpCaps->wPeriodMin = MMSYSTIME_MININTERVAL;
     lpCaps->wPeriodMax = MMSYSTIME_MAXINTERVAL;
     return 0;
@@ -317,8 +269,7 @@
 MMRESULT16 WINAPI timeGetDevCaps16(LPTIMECAPS16 lpCaps, UINT16 wSize)
 {
     TRACE(mmtime, "(%p, %u) !\n", lpCaps, wSize);
-    if (!mmTimeStarted)
-	StartMMTime();
+    StartMMTime();
     lpCaps->wPeriodMin = MMSYSTIME_MININTERVAL;
     lpCaps->wPeriodMax = MMSYSTIME_MAXINTERVAL;
     return 0;
@@ -330,10 +281,9 @@
 MMRESULT32 WINAPI timeBeginPeriod32(UINT32 wPeriod)
 {
     TRACE(mmtime, "(%u) !\n", wPeriod);
-    if (!mmTimeStarted)
-	StartMMTime();
+    StartMMTime();
     if (wPeriod < MMSYSTIME_MININTERVAL || wPeriod > MMSYSTIME_MAXINTERVAL) 
-        return TIMERR_NOCANDO;
+	return TIMERR_NOCANDO;
     return 0;
 }
 /**************************************************************************
@@ -342,10 +292,9 @@
 MMRESULT16 WINAPI timeBeginPeriod16(UINT16 wPeriod)
 {
     TRACE(mmtime, "(%u) !\n", wPeriod);
-    if (!mmTimeStarted)
-	StartMMTime();
+    StartMMTime();
     if (wPeriod < MMSYSTIME_MININTERVAL || wPeriod > MMSYSTIME_MAXINTERVAL) 
-        return TIMERR_NOCANDO;
+	return TIMERR_NOCANDO;
     return 0;
 }
 
@@ -355,8 +304,9 @@
 MMRESULT32 WINAPI timeEndPeriod32(UINT32 wPeriod)
 {
     TRACE(mmtime, "(%u) !\n", wPeriod);
+    StartMMTime();
     if (wPeriod < MMSYSTIME_MININTERVAL || wPeriod > MMSYSTIME_MAXINTERVAL) 
-        return TIMERR_NOCANDO;
+	return TIMERR_NOCANDO;
     return 0;
 }
 
@@ -367,7 +317,7 @@
 {
     TRACE(mmtime, "(%u) !\n", wPeriod);
     if (wPeriod < MMSYSTIME_MININTERVAL || wPeriod > MMSYSTIME_MAXINTERVAL) 
-        return TIMERR_NOCANDO;
+	return TIMERR_NOCANDO;
     return 0;
 }
 
@@ -376,37 +326,38 @@
  */
 DWORD WINAPI timeGetTime()
 {
-  /* FIXME all this function should have to be is
-       long result;
-       struct timeval time;
-       TRACE(mmtime,"timeGetTime(); !\n");
-       gettimeofday(&time, 0);
-       result = (((long)time.tv_sec * (long)1000) + ((long)time.tv_usec / (long)1000));
-
-     but the multimedia timers are not implemented correctly, so all the rest
-     is a workaround to fake them.
-       
-   */  
-    static DWORD lasttick=0;
-    DWORD	newtick;
-
-    TRACE(mmtime, "!\n");
-    if (!mmTimeStarted)
-	StartMMTime();
-    newtick = GetTickCount();
-    mmSysTimeMS.u.ms+=newtick-lasttick; /* FIXME: faked timer */
-    if (newtick!=lasttick)
-
-    if (!time_called) { /* to avoid infinite recursion if timeGetTime is called
-			   inside check_MMtimers
-			 */
-      time_called++;
-    	check_MMtimers();
-      time_called--;
-    }    //check_MMtimers();
-    lasttick = newtick;
-    TRACE(mmtime, "Time = %ld\n",mmSysTimeMS.u.ms);
-
-
-    return mmSysTimeMS.u.ms;
+    DWORD	dwNewTick = GetTickCount();
+    
+#ifdef USE_FAKE_MM_TIMERS
+    if (bUseFakeTimers) {
+	if (wInCallBackLoop++) { 
+	    DWORD		dwDelta;
+	    
+	    StartMMTime();
+	    
+	    if (dwNewTick < dwLastCBTick) {
+		ERR(mmtime, "dwNewTick(%lu) < dwLastCBTick(%lu)\n", dwNewTick, dwLastCBTick);
+	    }
+	    dwDelta = dwNewTick - dwLastCBTick;
+	    if (dwDelta > MMSYSTIME_MININTERVAL) {
+		LPTIMERENTRY lpTimer;
+		
+		mmSysTimeMS.u.ms += dwDelta; /* FIXME: faked timer */
+		dwLastCBTick = dwNewTick;
+		for (lpTimer = lpTimerList; lpTimer != NULL; lpTimer = lpTimer->Next) {
+		    if (lpTimer->wCurTime < dwDelta) {
+			TIME_TriggerCallBack(lpTimer, dwNewTick);
+		    } else {
+			lpTimer->wCurTime -= dwDelta;
+		    }
+		}
+		dwNewTick = mmSysTimeMS.u.ms;
+	    }
+	}
+	wInCallBackLoop--;
+    }
+#endif
+    TRACE(mmtime, "Time = %ld\n", dwNewTick);
+    
+    return dwNewTick;
 }
diff --git a/objects/bitmap.c b/objects/bitmap.c
index 2480f27..2da4374 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -868,8 +868,25 @@
 {
     if (bmp->dib)
     {
-	FIXME(bitmap, "not implemented for DIBs\n");
-	return 0;
+        if ( count <= sizeof(BITMAP16) )
+        {
+            BITMAP32 *bmp32 = &bmp->dib->dibSection.dsBm;
+	    BITMAP16 bmp16;
+	    bmp16.bmType       = bmp32->bmType;
+	    bmp16.bmWidth      = bmp32->bmWidth;
+	    bmp16.bmHeight     = bmp32->bmHeight;
+	    bmp16.bmWidthBytes = bmp32->bmWidthBytes;
+	    bmp16.bmPlanes     = bmp32->bmPlanes;
+	    bmp16.bmBitsPixel  = bmp32->bmBitsPixel;
+	    bmp16.bmBits       = NULL;
+	    memcpy( buffer, &bmp16, count );
+	    return count;
+        }
+        else
+        {
+	    FIXME(bitmap, "not implemented for DIBs: count %d\n", count);
+	    return 0;
+        }
     }
     else
     {
diff --git a/objects/clipping.c b/objects/clipping.c
index 78b3d79..3f3ad30 100644
--- a/objects/clipping.c
+++ b/objects/clipping.c
@@ -83,6 +83,15 @@
     return retval;
 }
 
+/******************************************************************************
+ *		ExtSelectClipRgn	[GDI32.97]
+ */
+INT32 WINAPI ExtSelectClipRgn( HDC32 hdc, HRGN32 hrgn, INT32 fnMode )
+{
+    if (fnMode != RGN_COPY)
+        FIXME(clipping, "Unimplemented mode: %d\n", fnMode); 
+    return SelectClipRgn32( hdc, hrgn );
+}
 
 /***********************************************************************
  *           SelectVisRgn    (GDI.105)
diff --git a/objects/dc.c b/objects/dc.c
index b1ad95e..a787475 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -1506,3 +1506,13 @@
 /*FIXME    Need to to whatever GetColorSpace actually does */
     return 0;
 }
+
+/***********************************************************************
+ *           GetBoundsRect16    (GDI.194)
+ */
+UINT16 WINAPI GetBoundsRect16(HDC16 hdc, LPRECT16 rect, UINT16 flags)
+{
+    FIXME(dc, "(): stub\n");
+    return DCB_RESET;   /* bounding rectangle always empty */
+}
+
diff --git a/objects/dib.c b/objects/dib.c
index 3b1a81a..9552381 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -1381,6 +1381,15 @@
 }
 
 /***********************************************************************
+ *           SetDIBColorTable16    (GDI.602)
+ */
+UINT16 WINAPI SetDIBColorTable16( HDC16 hdc, UINT16 startpos, UINT16 entries,
+				  RGBQUAD *colors )
+{
+    return SetDIBColorTable32( hdc, startpos, entries, colors );
+}
+
+/***********************************************************************
  *           SetDIBColorTable32    (GDI32.311)
  */
 UINT32 WINAPI SetDIBColorTable32( HDC32 hdc, UINT32 startpos, UINT32 entries,
@@ -1424,6 +1433,15 @@
 }
 
 /***********************************************************************
+ *           GetDIBColorTable16    (GDI.603)
+ */
+UINT16 WINAPI GetDIBColorTable16( HDC16 hdc, UINT16 startpos, UINT16 entries,
+				  RGBQUAD *colors )
+{
+    return GetDIBColorTable32( hdc, startpos, entries, colors );
+}
+
+/***********************************************************************
  *           GetDIBColorTable32    (GDI32.169)
  */
 UINT32 WINAPI GetDIBColorTable32( HDC32 hdc, UINT32 startpos, UINT32 entries,
@@ -1949,7 +1967,7 @@
  *           CreateDIBSection16    (GDI.489)
  */
 HBITMAP16 WINAPI CreateDIBSection16 (HDC16 hdc, BITMAPINFO *bmi, UINT16 usage,
-				     LPVOID **bits, HANDLE16 section,
+				     LPVOID **bits, HANDLE32 section,
 				     DWORD offset)
 {
     return CreateDIBSection32(hdc, bmi, usage, bits, section, offset);
diff --git a/objects/font.c b/objects/font.c
index 95575b4..d3c1c79 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -1028,9 +1028,8 @@
  */
 DWORD WINAPI SetMapperFlags32( HDC32 hDC, DWORD dwFlag )
 {
-    FIXME(font, "(%04x, %08lX) -- Empty Stub !\n",
-		  hDC, dwFlag);
-    return 0L;
+    FIXME(font, "(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
+    return 0;
 }
 
 /***********************************************************************
@@ -1101,7 +1100,7 @@
                                 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
                                 LPVOID lpBuffer, const MAT2 *lpmat2 )
 {
-    FIXME(font,"(%04x, '%c', %04x, %p, %ld, %p, %p): empty stub!\n",
+    FIXME(font,"(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
 	  hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
     return (DWORD)-1; /* failure */
 }
@@ -1114,7 +1113,7 @@
                                  LPGLYPHMETRICS32 lpgm, DWORD cbBuffer,
                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
 {
-    FIXME(font,"(%04x, '%c', %04x, %p, %ld, %p, %p): empty stub!\n",
+    FIXME(font,"(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
 	  hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
     return (DWORD)-1; /* failure */
 }
@@ -1126,7 +1125,7 @@
                                  LPGLYPHMETRICS32 lpgm, DWORD cbBuffer,
                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
 {
-    FIXME(font,"(%04x, '%c', %04x, %p, %ld, %p, %p): empty stub!\n",
+    FIXME(font,"(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
 	  hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
     return (DWORD)-1; /* failure */
 }
@@ -1154,7 +1153,7 @@
      * enumbered with EnumFonts/EnumFontFamilies
      * lpszCurrentPath can be NULL
      */
-    FIXME(font,"(%ld,%s,%s,%s): empty stub\n",
+    FIXME(font,"(%ld,%s,%s,%s): stub\n",
 	  fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
     return FALSE; /* create failed */
 }
@@ -1167,7 +1166,7 @@
                                              LPCWSTR lpszFontFile,
                                              LPCWSTR lpszCurrentPath )
 {
-    FIXME(font,"(%ld,%p,%p,%p): empty stub\n",
+    FIXME(font,"(%ld,%p,%p,%p): stub\n",
 	  fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
     return FALSE; /* create failed */
 }
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index ca12959..c680ff0 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -788,20 +788,56 @@
  */
 BOOL16 WINAPI IsGDIObject( HGDIOBJ16 handle )
 {
+    UINT16 magic = 0;
+
     if (handle >= FIRST_STOCK_HANDLE ) 
-	return TRUE;
+    {
+        switch (handle)
+        {
+        case STOCK_WHITE_BRUSH:
+        case STOCK_LTGRAY_BRUSH:
+        case STOCK_GRAY_BRUSH:
+        case STOCK_DKGRAY_BRUSH:
+        case STOCK_BLACK_BRUSH:
+        case STOCK_HOLLOW_BRUSH:
+            magic = BRUSH_MAGIC;
+            break;
+
+        case STOCK_WHITE_PEN:
+        case STOCK_BLACK_PEN:
+        case STOCK_NULL_PEN :
+            magic = PEN_MAGIC;
+            break;
+
+        case STOCK_OEM_FIXED_FONT:
+        case STOCK_ANSI_FIXED_FONT:
+        case STOCK_ANSI_VAR_FONT:
+        case STOCK_SYSTEM_FONT:
+        case STOCK_DEVICE_DEFAULT_FONT:
+        case STOCK_SYSTEM_FIXED_FONT:
+        case STOCK_DEFAULT_GUI_FONT:
+            magic = FONT_MAGIC;
+            break;
+
+        case STOCK_DEFAULT_PALETTE:
+            magic = PALETTE_MAGIC;
+            break;
+        }
+    }
     else
     {
 	GDIOBJHDR *object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
 	if (object)
 	{
-	    UINT16 magic = object->wMagic;
+	    magic = object->wMagic;
 	    GDI_HEAP_UNLOCK( handle );
-	    if (magic >= PEN_MAGIC && magic <= METAFILE_DC_MAGIC)
-		return magic - PEN_MAGIC + 1;
 	}
     }
-    return FALSE;
+
+    if (magic >= PEN_MAGIC && magic <= METAFILE_DC_MAGIC)
+        return magic - PEN_MAGIC + 1;
+    else
+        return FALSE;
 }
 
 
@@ -823,6 +859,15 @@
 }
 
 /***********************************************************************
+ *           MakeObjectPrivate    (GDI.463)
+ */
+void WINAPI MakeObjectPrivate( HGDIOBJ16 handle, BOOL16 private )
+{
+    /* FIXME */
+}
+
+
+/***********************************************************************
  *           GdiFlush    (GDI32.128)
  */
 BOOL32 WINAPI GdiFlush(void)
diff --git a/objects/oembitmap.c b/objects/oembitmap.c
index 6a016ce..e9e9e9e 100644
--- a/objects/oembitmap.c
+++ b/objects/oembitmap.c
@@ -534,21 +534,7 @@
  */
 BOOL32 OBM_Init()
 {
-    if(TWEAK_Win95Look) {
-	OBM_Pixmaps_Data[OBM_ZOOMD - OBM_FIRST].data = obm_zoomd_95;
-	OBM_Pixmaps_Data[OBM_REDUCED - OBM_FIRST].data = obm_reduced_95;
-	OBM_Pixmaps_Data[OBM_ZOOM - OBM_FIRST].data = obm_zoom_95;
-	OBM_Pixmaps_Data[OBM_REDUCE - OBM_FIRST].data = obm_reduce_95;
-	OBM_Pixmaps_Data[OBM_CLOSE - OBM_FIRST].data = obm_close_95;
-        OBM_Pixmaps_Data[OBM_RESTORE - OBM_FIRST].data = obm_restore_95;
-        OBM_Pixmaps_Data[OBM_RESTORED - OBM_FIRST].data = obm_restored_95;
-
-        OBM_Icons_Data[OIC_HAND - OIC_FIRST] = oic_hand_95;
-        OBM_Icons_Data[OIC_QUES - OIC_FIRST] = oic_ques_95;
-        OBM_Icons_Data[OIC_BANG - OIC_FIRST] = oic_bang_95;
-        OBM_Icons_Data[OIC_NOTE - OIC_FIRST] = oic_note_95;
-    }
-    else {
+    if (TWEAK_WineLook == WIN31_LOOK) {
 	OBM_Pixmaps_Data[OBM_ZOOMD - OBM_FIRST].data = obm_zoomd;
 	OBM_Pixmaps_Data[OBM_REDUCED - OBM_FIRST].data = obm_reduced;
 	OBM_Pixmaps_Data[OBM_ZOOM - OBM_FIRST].data = obm_zoom;
@@ -562,6 +548,20 @@
         OBM_Icons_Data[OIC_BANG - OIC_FIRST] = oic_bang;
         OBM_Icons_Data[OIC_NOTE - OIC_FIRST] = oic_note;
     }
+    else {
+	OBM_Pixmaps_Data[OBM_ZOOMD - OBM_FIRST].data = obm_zoomd_95;
+	OBM_Pixmaps_Data[OBM_REDUCED - OBM_FIRST].data = obm_reduced_95;
+	OBM_Pixmaps_Data[OBM_ZOOM - OBM_FIRST].data = obm_zoom_95;
+	OBM_Pixmaps_Data[OBM_REDUCE - OBM_FIRST].data = obm_reduce_95;
+	OBM_Pixmaps_Data[OBM_CLOSE - OBM_FIRST].data = obm_close_95;
+        OBM_Pixmaps_Data[OBM_RESTORE - OBM_FIRST].data = obm_restore_95;
+        OBM_Pixmaps_Data[OBM_RESTORED - OBM_FIRST].data = obm_restored_95;
+
+        OBM_Icons_Data[OIC_HAND - OIC_FIRST] = oic_hand_95;
+        OBM_Icons_Data[OIC_QUES - OIC_FIRST] = oic_ques_95;
+        OBM_Icons_Data[OIC_BANG - OIC_FIRST] = oic_bang_95;
+        OBM_Icons_Data[OIC_NOTE - OIC_FIRST] = oic_note_95;
+    }
 
     return 1;
 }
diff --git a/objects/palette.c b/objects/palette.c
index b48b7c8..d5ae9ee 100644
--- a/objects/palette.c
+++ b/objects/palette.c
@@ -18,6 +18,9 @@
 #include "xmalloc.h"
 #include "debug.h"
 
+FARPROC32 pfnSelectPalette = NULL;
+FARPROC32 pfnRealizePalette = NULL;
+
 static UINT32 SystemPaletteUse = SYSPAL_STATIC;  /* currently not considered */
 
 static HPALETTE16 hPrimaryPalette = 0; /* used for WM_PALETTECHANGED */
@@ -125,7 +128,7 @@
 HPALETTE32 WINAPI CreateHalftonePalette(
     HDC32 hdc) /* [in] Handle to device context */
 {
-    FIXME(palette,"(%x): stub\n", hdc);
+    FIXME(palette,"(0x%x): stub\n", hdc);
     return (HPALETTE32)NULL;
 }
 
diff --git a/objects/text.c b/objects/text.c
index 08e80d3..ac31641 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -323,7 +323,11 @@
                      LPRECT32 rect, UINT32 flags, LPDRAWTEXTPARAMS dtp )
 {
     TRACE(text,"(%d,'%s',%d,%p,0x%08x,%p)\n",hdc,str,count,rect,flags,dtp);
-    FIXME(text,"ignores extended functionality\n");
+    if(dtp) {
+        FIXME(text,"Ignores params:%d,%d,%d,%d,%d\n",dtp->cbSize,
+                   dtp->iTabLength,dtp->iLeftMargin,dtp->iRightMargin,
+                   dtp->uiLengthDrawn);
+    }
     return DrawText32A(hdc,str,count,rect,flags);
 }
 
diff --git a/ole/compobj.c b/ole/compobj.c
index 30d0869..cf85b72 100644
--- a/ole/compobj.c
+++ b/ole/compobj.c
@@ -24,6 +24,8 @@
 #include "dsound.h"
 #include "dinput.h"
 #include "d3d.h"
+#include "dplay.h"
+
 
 LPMALLOC16 currentMalloc16=NULL;
 LPMALLOC32 currentMalloc32=NULL;
diff --git a/ole/nls/afk.nls b/ole/nls/afk.nls
index b67bf44..d4d1e25 100644
--- a/ole/nls/afk.nls
+++ b/ole/nls/afk.nls
@@ -3,17 +3,17 @@
  *      Afrikaans (South Africa)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0436")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
-/* LOCVAL(LOCALE_SENGLANGUAGE,"") */
+LOCVAL(LOCALE_SENGLANGUAGE,"Afrikaans")
 LOCVAL(LOCALE_SABBREVLANGNAME,"afk")
 LOCVAL(LOCALE_SNATIVELANGNAME,"Afrikaans")
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"South Africa")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"ZAF")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Suid Afrika")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0436")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/ara.nls b/ole/nls/ara.nls
index a3ac9d4..70d2cf2 100644
--- a/ole/nls/ara.nls
+++ b/ole/nls/ara.nls
@@ -3,17 +3,17 @@
  *      Arabic (Saudi Arabia)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0401")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
-/* LOCVAL(LOCALE_SENGLANGUAGE,"") */
+LOCVAL(LOCALE_SENGLANGUAGE,"Arabic (Saudi Arabia)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"ara")
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"Saudi Arabia")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0401")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/arb.nls b/ole/nls/arb.nls
index 5499d8a..845b441 100644
--- a/ole/nls/arb.nls
+++ b/ole/nls/arb.nls
@@ -3,17 +3,17 @@
  *      Arabic (Lebanon)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x3001")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
-/* LOCVAL(LOCALE_SENGLANGUAGE,"") */
+LOCVAL(LOCALE_SENGLANGUAGE,"Arabic (Lebanon)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"arl")
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"Lebanon")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0401")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/are.nls b/ole/nls/are.nls
index 5fd1478..c1c64fc 100644
--- a/ole/nls/are.nls
+++ b/ole/nls/are.nls
@@ -3,17 +3,17 @@
  *      Arabic (Egypt)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0c01")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
-/* LOCVAL(LOCALE_SENGLANGUAGE,"") */
+LOCVAL(LOCALE_SENGLANGUAGE,"Arabic (Egypt)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"are")
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"Egypt")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0401")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/arg.nls b/ole/nls/arg.nls
index a6aaf14..cb3d063 100644
--- a/ole/nls/arg.nls
+++ b/ole/nls/arg.nls
@@ -3,17 +3,17 @@
  *      Arabic (Algeria)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x1401")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
-/* LOCVAL(LOCALE_SENGLANGUAGE,"") */
+LOCVAL(LOCALE_SENGLANGUAGE,"Arabic (Algeria)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"ars")
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"Algeria")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0401")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/ari.nls b/ole/nls/ari.nls
index f77c6bb..c27c090 100644
--- a/ole/nls/ari.nls
+++ b/ole/nls/ari.nls
@@ -1,19 +1,19 @@
 /*
  *	OLE2NLS library
- *      Arabic
+ *      Arabic (Iraq)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0801")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
-/* LOCVAL(LOCALE_SENGLANGUAGE,"") */
+LOCVAL(LOCALE_SENGLANGUAGE,"Arabic (Iraq)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"ari")
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"Iraq")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0401")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/ark.nls b/ole/nls/ark.nls
index f265b49..4789d91 100644
--- a/ole/nls/ark.nls
+++ b/ole/nls/ark.nls
@@ -3,17 +3,17 @@
  *      Arabic (Kuwait)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x3401")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
-/* LOCVAL(LOCALE_SENGLANGUAGE,"") */
+LOCVAL(LOCALE_SENGLANGUAGE,"Arabic (Kuwait)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"ark")
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"Kuwait")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"KWT")
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0401")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/arm.nls b/ole/nls/arm.nls
index 45f17d2..2599213 100644
--- a/ole/nls/arm.nls
+++ b/ole/nls/arm.nls
@@ -3,17 +3,17 @@
  *      Arabic (Marocco)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x1801")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
-/* LOCVAL(LOCALE_SENGLANGUAGE,"") */
+LOCVAL(LOCALE_SENGLANGUAGE,"Arabic (Marocco)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"ars")
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"Marocco")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0401")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/aro.nls b/ole/nls/aro.nls
index eeaf67d..56fce7c 100644
--- a/ole/nls/aro.nls
+++ b/ole/nls/aro.nls
@@ -3,17 +3,17 @@
  *      Arabic (Oman)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x2001")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
-/* LOCVAL(LOCALE_SENGLANGUAGE,"") */
+LOCVAL(LOCALE_SENGLANGUAGE,"Arabic (Oman)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"ars")
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"Oman")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0401")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/arq.nls b/ole/nls/arq.nls
index 5e5020c..11c51d0 100644
--- a/ole/nls/arq.nls
+++ b/ole/nls/arq.nls
@@ -3,17 +3,17 @@
  *      Arabic (Quatar)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x4001")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
-/* LOCVAL(LOCALE_SENGLANGUAGE,"") */
+LOCVAL(LOCALE_SENGLANGUAGE,"Arabic (Quatar)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"arq")
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"Quatar")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0401")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/ars.nls b/ole/nls/ars.nls
index 4fcbb35..efeb921 100644
--- a/ole/nls/ars.nls
+++ b/ole/nls/ars.nls
@@ -3,17 +3,17 @@
  *      Arabic (Syria)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x2801")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
-/* LOCVAL(LOCALE_SENGLANGUAGE,"") */
+LOCVAL(LOCALE_SENGLANGUAGE,"Arabic (Syria)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"ars")
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"Syria")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0401")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/art.nls b/ole/nls/art.nls
index 73eb885..22e7009 100644
--- a/ole/nls/art.nls
+++ b/ole/nls/art.nls
@@ -1,19 +1,19 @@
 /*
  *	OLE2NLS library
- *      Arabic (Tunesia)
+ *      Arabic (Tunisia)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x1c01")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
-/* LOCVAL(LOCALE_SENGLANGUAGE,"") */
+LOCVAL(LOCALE_SENGLANGUAGE,"Arabic (Tunisia)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"art")
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"Tunisia")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"TUN")
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0401")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/aru.nls b/ole/nls/aru.nls
index db2c50e..b31f2de 100644
--- a/ole/nls/aru.nls
+++ b/ole/nls/aru.nls
@@ -1,19 +1,19 @@
 /*
  *	OLE2NLS library
- *      Arabic (aru)
+ *      Arabic (UAE)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x3801")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
-/* LOCVAL(LOCALE_SENGLANGUAGE,"") */
+LOCVAL(LOCALE_SENGLANGUAGE,"Arabic (United Arab Emirates)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"aru")
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"United Arab Emirates")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0401")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/bel.nls b/ole/nls/bel.nls
index 328c2ab..a414195 100644
--- a/ole/nls/bel.nls
+++ b/ole/nls/bel.nls
@@ -3,17 +3,17 @@
  *      Belarusian
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0423")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
-/* LOCVAL(LOCALE_SENGLANGUAGE,"") */
+LOCVAL(LOCALE_SENGLANGUAGE,"Belarussian")
 /* LOCVAL(LOCALE_SABBREVLANGNAME,"") */
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"Belaruss")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"bel")
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0423")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/bgr.nls b/ole/nls/bgr.nls
index aaaad3b..f1100ae 100644
--- a/ole/nls/bgr.nls
+++ b/ole/nls/bgr.nls
@@ -3,17 +3,17 @@
  *      Bulgaria
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0402")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
 LOCVAL(LOCALE_SENGLANGUAGE,"Bulgarian")
 LOCVAL(LOCALE_SABBREVLANGNAME,"bgr")
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"Bulgaria")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"bgr")
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0402")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/cat.nls b/ole/nls/cat.nls
index 8415610..a627a9a 100644
--- a/ole/nls/cat.nls
+++ b/ole/nls/cat.nls
@@ -3,7 +3,7 @@
  *      Catalan
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0403")
 LOCVAL(LOCALE_SLANGUAGE,"Català")
 LOCVAL(LOCALE_SENGLANGUAGE,"Catalan")
 LOCVAL(LOCALE_SABBREVLANGNAME,"cat")
@@ -13,8 +13,8 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Spain")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"ESP")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Espanya")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
-/* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0403")
+LOCVAL(LOCALE_IDEFAULTCOUNTRY,"34")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
 /* LOCVAL(LOCALE_SLIST,"") */
@@ -38,14 +38,14 @@
 LOCVAL(LOCALE_SDATE,"/")
 LOCVAL(LOCALE_STIME,":")
 LOCVAL(LOCALE_SSHORTDATE,"dd/MM/yyyy")
-LOCVAL(LOCALE_SLONGDATE,"ddd d MMMM yyyy") */
+LOCVAL(LOCALE_SLONGDATE,"ddd d MMMM yyyy")
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 LOCVAL(LOCALE_S1159, "")
diff --git a/ole/nls/cht.nls b/ole/nls/cht.nls
index 9dafd4d..fd5b875 100644
--- a/ole/nls/cht.nls
+++ b/ole/nls/cht.nls
@@ -3,17 +3,17 @@
  *      Chinese (Taiwan)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0404")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
-/* LOCVAL(LOCALE_SENGLANGUAGE,"Chinese (Taiwan)") */
+LOCVAL(LOCALE_SENGLANGUAGE,"Chinese (Taiwan)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"cht")
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"China (Taiwan)")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0404")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/cze.nls b/ole/nls/cze.nls
index 40bf38d..e47e932 100644
--- a/ole/nls/cze.nls
+++ b/ole/nls/cze.nls
@@ -4,7 +4,7 @@
  *	(Czech strings in iso-8859-2)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0405")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
 LOCVAL(LOCALE_SENGLANGUAGE,"Czech")
 LOCVAL(LOCALE_SABBREVLANGNAME,"cze")
@@ -14,7 +14,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Czech Republic")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Èeská Republika")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0405")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"42")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"895")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -43,10 +43,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 LOCVAL(LOCALE_S1159, "")
diff --git a/ole/nls/dan.nls b/ole/nls/dan.nls
index 6baefff..e0ebc2f 100644
--- a/ole/nls/dan.nls
+++ b/ole/nls/dan.nls
@@ -3,7 +3,7 @@
  *      Denmark
  */
 
-LOCVAL(LOCALE_ILANGUAGE,"6")
+LOCVAL(LOCALE_ILANGUAGE,"0x0406")
 LOCVAL(LOCALE_SLANGUAGE,"Dansk")
 LOCVAL(LOCALE_SENGLANGUAGE,"Danish")
 LOCVAL(LOCALE_SABBREVLANGNAME,"dan")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Denmark")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"DK")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Danmark")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE,"6")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0406")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"45")
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
diff --git a/ole/nls/dea.nls b/ole/nls/dea.nls
index 35c3eb0..f662189 100644
--- a/ole/nls/dea.nls
+++ b/ole/nls/dea.nls
@@ -3,9 +3,9 @@
  *      Austria
  */
  
-LOCVAL(LOCALE_ILANGUAGE,"9")
+LOCVAL(LOCALE_ILANGUAGE,"0x0c07")
 LOCVAL(LOCALE_SLANGUAGE,"Deutsch")
-LOCVAL(LOCALE_SENGLANGUAGE,"German")
+LOCVAL(LOCALE_SENGLANGUAGE,"German (Austria)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"dea")
 LOCVAL(LOCALE_SNATIVELANGNAME,"Österreich")
 LOCVAL(LOCALE_ICOUNTRY,"41")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Austria")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"ATS")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Österreich")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE,"9")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0407")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"41")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"851")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
diff --git a/ole/nls/dec.nls b/ole/nls/dec.nls
index ed2b0a0..83397b1 100644
--- a/ole/nls/dec.nls
+++ b/ole/nls/dec.nls
@@ -3,7 +3,7 @@
  *      Fuerstentum Liechtenstein
  */
  
-LOCVAL(LOCALE_ILANGUAGE,"9")
+LOCVAL(LOCALE_ILANGUAGE,"0x1407")
 LOCVAL(LOCALE_SLANGUAGE,"Deutsch")
 LOCVAL(LOCALE_SENGLANGUAGE,"German")
 LOCVAL(LOCALE_SABBREVLANGNAME,"dec")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Liechtenstein")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"LIE")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Liechtenstein")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE,"9")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0407")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"41")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"851")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
diff --git a/ole/nls/del.nls b/ole/nls/del.nls
index 70307a6..9252932 100644
--- a/ole/nls/del.nls
+++ b/ole/nls/del.nls
@@ -3,7 +3,7 @@
  *      Luxembourg (German)
  */
 
-LOCVAL(LOCALE_ILANGUAGE,"9")
+LOCVAL(LOCALE_ILANGUAGE,"0x1007")
 LOCVAL(LOCALE_SLANGUAGE,"Deutsch")
 LOCVAL(LOCALE_SENGLANGUAGE,"German")
 LOCVAL(LOCALE_SABBREVLANGNAME,"deu")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Luxemburg")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"LUX")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Luxembourg")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE,"9")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0407")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"49")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"851")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
diff --git a/ole/nls/des.nls b/ole/nls/des.nls
index 61e5ae7..0a7dd0a 100644
--- a/ole/nls/des.nls
+++ b/ole/nls/des.nls
@@ -3,7 +3,7 @@
  *      Switzerland (German)
  */
  
-LOCVAL(LOCALE_ILANGUAGE,"9")
+LOCVAL(LOCALE_ILANGUAGE,"0x0807")
 LOCVAL(LOCALE_SLANGUAGE,"Deutsch")
 LOCVAL(LOCALE_SENGLANGUAGE,"German")
 LOCVAL(LOCALE_SABBREVLANGNAME,"des")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Switzerland")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"Sg")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Schweiz")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE,"9")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0807")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"41")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"851")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
diff --git a/ole/nls/deu.nls b/ole/nls/deu.nls
index 7b99de7..901f539 100644
--- a/ole/nls/deu.nls
+++ b/ole/nls/deu.nls
@@ -3,7 +3,7 @@
  *      Germany
  */
 
-LOCVAL(LOCALE_ILANGUAGE,"9")
+LOCVAL(LOCALE_ILANGUAGE,"0x0407")
 LOCVAL(LOCALE_SLANGUAGE,"Deutsch")
 LOCVAL(LOCALE_SENGLANGUAGE,"German")
 LOCVAL(LOCALE_SABBREVLANGNAME,"deu")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Germany")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"De")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Deutschland")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE,"9")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0407")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"49")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"851")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
diff --git a/ole/nls/empty.nls b/ole/nls/empty.nls
index 7648569..646628a 100644
--- a/ole/nls/empty.nls
+++ b/ole/nls/empty.nls
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+/* LOCVAL(LOCALE_ITIME,"1") */
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+/* LOCVAL(LOCALE_ITLZERO,"1") */
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/ena.nls b/ole/nls/ena.nls
index f3fa01a..8213205 100644
--- a/ole/nls/ena.nls
+++ b/ole/nls/ena.nls
@@ -3,7 +3,7 @@
  *      Australia
  */
 
-LOCVAL(LOCALE_ILANGUAGE, "0809")
+LOCVAL(LOCALE_ILANGUAGE, "0x0c09")
 LOCVAL(LOCALE_SLANGUAGE, "English (Australia)")
 LOCVAL(LOCALE_SENGLANGUAGE, "English")
 LOCVAL(LOCALE_SABBREVLANGNAME, "ena")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY, "Australia")
 LOCVAL(LOCALE_SABBREVCTRYNAME, "AUS")
 LOCVAL(LOCALE_SNATIVECTRYNAME, "Australia")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0809")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0x0409")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY, "44")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE, "850")
 LOCVAL(LOCALE_IDEFAULTANSICODEPAGE, "1252")
diff --git a/ole/nls/enb.nls b/ole/nls/enb.nls
index f1b59b1..74b05bd 100644
--- a/ole/nls/enb.nls
+++ b/ole/nls/enb.nls
@@ -3,7 +3,7 @@
  *      Caribbean
  */
 
-LOCVAL(LOCALE_ILANGUAGE, "0809")
+LOCVAL(LOCALE_ILANGUAGE, "0x2409")
 LOCVAL(LOCALE_SLANGUAGE, "English (Caribbean)")
 LOCVAL(LOCALE_SENGLANGUAGE, "English")
 LOCVAL(LOCALE_SABBREVLANGNAME, "enb")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY, "Caribbean")
 LOCVAL(LOCALE_SABBREVCTRYNAME, "CAR")
 LOCVAL(LOCALE_SNATIVECTRYNAME, "Carribean")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0809")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0x2409")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY, "44")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE, "850")
 LOCVAL(LOCALE_IDEFAULTANSICODEPAGE, "1252")
diff --git a/ole/nls/enc.nls b/ole/nls/enc.nls
index 9d92ee3..18766d6 100644
--- a/ole/nls/enc.nls
+++ b/ole/nls/enc.nls
@@ -3,7 +3,7 @@
  *      Canada (English)
  */
 
-LOCVAL(LOCALE_ILANGUAGE, "0409")
+LOCVAL(LOCALE_ILANGUAGE, "0x1009")
 LOCVAL(LOCALE_SLANGUAGE, "English (Canada)")
 LOCVAL(LOCALE_SENGLANGUAGE, "English")
 LOCVAL(LOCALE_SABBREVLANGNAME, "enc")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY, "Canada")
 LOCVAL(LOCALE_SABBREVCTRYNAME, "CAN")
 LOCVAL(LOCALE_SNATIVECTRYNAME, "Canada")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0409")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0x0409")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY, "1")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE, "437")
 LOCVAL(LOCALE_IDEFAULTANSICODEPAGE, "1252")
diff --git a/ole/nls/eng.nls b/ole/nls/eng.nls
index 8bd2987..7cc7c87 100644
--- a/ole/nls/eng.nls
+++ b/ole/nls/eng.nls
@@ -3,7 +3,7 @@
  *      United Kingdom
  */
 
-LOCVAL(LOCALE_ILANGUAGE, "0809")
+LOCVAL(LOCALE_ILANGUAGE, "0x0809")
 LOCVAL(LOCALE_SLANGUAGE, "English (United Kingdom)")
 LOCVAL(LOCALE_SENGLANGUAGE, "English")
 LOCVAL(LOCALE_SABBREVLANGNAME, "eng")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY, "United Kingdom")
 LOCVAL(LOCALE_SABBREVCTRYNAME, "GBR")
 LOCVAL(LOCALE_SNATIVECTRYNAME, "United Kingdom")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0809")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0x0409")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY, "44")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE, "850")
 LOCVAL(LOCALE_IDEFAULTANSICODEPAGE, "1252")
diff --git a/ole/nls/enj.nls b/ole/nls/enj.nls
index aef13b7..fa34797 100644
--- a/ole/nls/enj.nls
+++ b/ole/nls/enj.nls
@@ -3,7 +3,7 @@
  *      Jamaica
  */
 
-LOCVAL(LOCALE_ILANGUAGE, "0809")
+LOCVAL(LOCALE_ILANGUAGE, "0x2009")
 LOCVAL(LOCALE_SLANGUAGE, "English (Jamaica)")
 LOCVAL(LOCALE_SENGLANGUAGE, "English")
 LOCVAL(LOCALE_SABBREVLANGNAME, "enj")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY, "Jamaica")
 LOCVAL(LOCALE_SABBREVCTRYNAME, "JAM")
 LOCVAL(LOCALE_SNATIVECTRYNAME, "Jamaica")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0809")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0x0409")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY, "44")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE, "850")
 LOCVAL(LOCALE_IDEFAULTANSICODEPAGE, "1252")
diff --git a/ole/nls/enl.nls b/ole/nls/enl.nls
index 802814a..21c9a0b 100644
--- a/ole/nls/enl.nls
+++ b/ole/nls/enl.nls
@@ -3,17 +3,17 @@
  *      English Belize
  */
 
-LOCVAL(LOCALE_ILANGUAGE, "0409")
-LOCVAL(LOCALE_SLANGUAGE, "English (United States)")
+LOCVAL(LOCALE_ILANGUAGE, "0x2809")
+LOCVAL(LOCALE_SLANGUAGE, "English (Belize)")
 LOCVAL(LOCALE_SENGLANGUAGE, "English")
 LOCVAL(LOCALE_SABBREVLANGNAME, "enl")
 LOCVAL(LOCALE_SNATIVELANGNAME, "English")
 LOCVAL(LOCALE_ICOUNTRY, "1")
-LOCVAL(LOCALE_SCOUNTRY, "United States")
-LOCVAL(LOCALE_SENGCOUNTRY, "United States")
-LOCVAL(LOCALE_SABBREVCTRYNAME, "USA")
-LOCVAL(LOCALE_SNATIVECTRYNAME, "United States")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0409")
+LOCVAL(LOCALE_SCOUNTRY, "Belize")
+LOCVAL(LOCALE_SENGCOUNTRY, "Belize")
+/* LOCVAL(LOCALE_SABBREVCTRYNAME, "") */
+LOCVAL(LOCALE_SNATIVECTRYNAME, "Belize")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0x0409")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY, "1")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE, "437")
 LOCVAL(LOCALE_IDEFAULTANSICODEPAGE, "1252")
diff --git a/ole/nls/ens.nls b/ole/nls/ens.nls
index 07a8e8c..361a110 100644
--- a/ole/nls/ens.nls
+++ b/ole/nls/ens.nls
@@ -3,7 +3,7 @@
  *      South Africa (English)
  */
 
-LOCVAL(LOCALE_ILANGUAGE, "0809")
+LOCVAL(LOCALE_ILANGUAGE, "0x1c09")
 LOCVAL(LOCALE_SLANGUAGE, "English (South Africa)")
 LOCVAL(LOCALE_SENGLANGUAGE, "English")
 LOCVAL(LOCALE_SABBREVLANGNAME, "ens")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY, "South Africa")
 LOCVAL(LOCALE_SABBREVCTRYNAME, "ZAF")
 LOCVAL(LOCALE_SNATIVECTRYNAME, "South Africa")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0809")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0x0409")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY, "44")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE, "850")
 LOCVAL(LOCALE_IDEFAULTANSICODEPAGE, "1252")
diff --git a/ole/nls/ent.nls b/ole/nls/ent.nls
index 4b9ec63..d6821ab 100644
--- a/ole/nls/ent.nls
+++ b/ole/nls/ent.nls
@@ -3,17 +3,17 @@
  *      Trinidad & Tobago
  */
 
-LOCVAL(LOCALE_ILANGUAGE, "0409")
+LOCVAL(LOCALE_ILANGUAGE, "0x2c09")
 LOCVAL(LOCALE_SLANGUAGE, "English (Trinidad & Tobago)")
 LOCVAL(LOCALE_SENGLANGUAGE, "English")
 LOCVAL(LOCALE_SABBREVLANGNAME, "ent")
 LOCVAL(LOCALE_SNATIVELANGNAME, "English")
-LOCVAL(LOCALE_ICOUNTRY, "1")
+/* LOCVAL(LOCALE_ICOUNTRY, "") */
 LOCVAL(LOCALE_SCOUNTRY, "Trinidad & Tobago")
 LOCVAL(LOCALE_SENGCOUNTRY, "Trinidad & Tobago")
-LOCVAL(LOCALE_SABBREVCTRYNAME, "USA")
-LOCVAL(LOCALE_SNATIVECTRYNAME, "United States")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0409")
+/* LOCVAL(LOCALE_SABBREVCTRYNAME, "") */
+LOCVAL(LOCALE_SNATIVECTRYNAME, "Trinidad & Tobago")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0x2c09")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY, "1")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE, "437")
 LOCVAL(LOCALE_IDEFAULTANSICODEPAGE, "1252")
diff --git a/ole/nls/enu.nls b/ole/nls/enu.nls
index 718f2f3..6441364 100644
--- a/ole/nls/enu.nls
+++ b/ole/nls/enu.nls
@@ -3,7 +3,7 @@
  *      United States
  */
 
-LOCVAL(LOCALE_ILANGUAGE, "0409")
+LOCVAL(LOCALE_ILANGUAGE, "0x0409")
 LOCVAL(LOCALE_SLANGUAGE, "English (United States)")
 LOCVAL(LOCALE_SENGLANGUAGE, "English")
 LOCVAL(LOCALE_SABBREVLANGNAME, "enu")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY, "United States")
 LOCVAL(LOCALE_SABBREVCTRYNAME, "USA")
 LOCVAL(LOCALE_SNATIVECTRYNAME, "United States")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0409")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0x0409")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY, "1")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE, "437")
 LOCVAL(LOCALE_IDEFAULTANSICODEPAGE, "1252")
diff --git a/ole/nls/enz.nls b/ole/nls/enz.nls
index 869b79b..5cffe1d 100644
--- a/ole/nls/enz.nls
+++ b/ole/nls/enz.nls
@@ -3,17 +3,17 @@
  *      New Zealand
  */
 
-LOCVAL(LOCALE_ILANGUAGE, "0809")
+LOCVAL(LOCALE_ILANGUAGE, "0x1409")
 LOCVAL(LOCALE_SLANGUAGE, "English (New Zealand)")
 LOCVAL(LOCALE_SENGLANGUAGE, "English")
 LOCVAL(LOCALE_SABBREVLANGNAME, "enz")
 LOCVAL(LOCALE_SNATIVELANGNAME, "English")
-LOCVAL(LOCALE_ICOUNTRY, "44")
+/* LOCVAL(LOCALE_ICOUNTRY, "") */
 LOCVAL(LOCALE_SCOUNTRY, "New Zealand")
 LOCVAL(LOCALE_SENGCOUNTRY, "New Zealand")
 LOCVAL(LOCALE_SABBREVCTRYNAME, "NZL")
 LOCVAL(LOCALE_SNATIVECTRYNAME, "New Zealand")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0809")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0x0409")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY, "44")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE, "850")
 LOCVAL(LOCALE_IDEFAULTANSICODEPAGE, "1252")
diff --git a/ole/nls/esa.nls b/ole/nls/esa.nls
index a416866..67a0cb9 100644
--- a/ole/nls/esa.nls
+++ b/ole/nls/esa.nls
@@ -3,7 +3,7 @@
  *      Spanish (Panama)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x180a")
 LOCVAL(LOCALE_SLANGUAGE,"Español")
 LOCVAL(LOCALE_SENGLANGUAGE,"Spanish")
 LOCVAL(LOCALE_SABBREVLANGNAME,"esa")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Panama")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"PAN")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Panamá")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/esb.nls b/ole/nls/esb.nls
index eae2283..55559e3 100644
--- a/ole/nls/esb.nls
+++ b/ole/nls/esb.nls
@@ -3,7 +3,7 @@
  *      Spanish (Bolivia)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x400a")
 LOCVAL(LOCALE_SLANGUAGE,"Español")
 LOCVAL(LOCALE_SENGLANGUAGE,"Spanish")
 LOCVAL(LOCALE_SABBREVLANGNAME,"esb")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Bolivia")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"BOL")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Bolivia")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/esc.nls b/ole/nls/esc.nls
index 48ac4fc..931d0b6 100644
--- a/ole/nls/esc.nls
+++ b/ole/nls/esc.nls
@@ -3,7 +3,7 @@
  *      Spanish (Costa Rica)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x140a")
 LOCVAL(LOCALE_SLANGUAGE,"Español")
 LOCVAL(LOCALE_SENGLANGUAGE,"Spanish")
 LOCVAL(LOCALE_SABBREVLANGNAME,"esa")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Costa Rica")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"CRI")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Costa Rica")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x140a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 LOCVAL(LOCALE_S1159, "AM")
diff --git a/ole/nls/esd.nls b/ole/nls/esd.nls
index 4036141..8ad1815 100644
--- a/ole/nls/esd.nls
+++ b/ole/nls/esd.nls
@@ -3,7 +3,7 @@
  *      Spanish (Dominican Republic)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x1c0a")
 LOCVAL(LOCALE_SLANGUAGE,"Español")
 LOCVAL(LOCALE_SENGLANGUAGE,"Spanish")
 LOCVAL(LOCALE_SABBREVLANGNAME,"esd")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Dominican Republic")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"DMA")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"República Dominicana")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/ese.nls b/ole/nls/ese.nls
index 97cb092..13d9bbb 100644
--- a/ole/nls/ese.nls
+++ b/ole/nls/ese.nls
@@ -3,7 +3,7 @@
  *      Spanish (El Salvador)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x440a")
 LOCVAL(LOCALE_SLANGUAGE,"Español")
 LOCVAL(LOCALE_SENGLANGUAGE,"Spanish")
 LOCVAL(LOCALE_SABBREVLANGNAME,"ese")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"El Salvador")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"SVD")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"El Salvador")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/esf.nls b/ole/nls/esf.nls
index 2784196..1261ce1 100644
--- a/ole/nls/esf.nls
+++ b/ole/nls/esf.nls
@@ -3,7 +3,7 @@
  *      Spanish (Ecuador)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x300a")
 LOCVAL(LOCALE_SLANGUAGE,"Español")
 LOCVAL(LOCALE_SENGLANGUAGE,"Spanish")
 LOCVAL(LOCALE_SABBREVLANGNAME,"esf")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Ecuador")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"ECU")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Ecuador")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/esg.nls b/ole/nls/esg.nls
index 073c588..6f40e94 100644
--- a/ole/nls/esg.nls
+++ b/ole/nls/esg.nls
@@ -3,7 +3,7 @@
  *      Spanish (Guatemala)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x100a")
 LOCVAL(LOCALE_SLANGUAGE,"Español")
 LOCVAL(LOCALE_SENGLANGUAGE,"Spanish")
 LOCVAL(LOCALE_SABBREVLANGNAME,"esg")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Guatemala")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"GTM")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Guatemala")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/esh.nls b/ole/nls/esh.nls
index 46adb1c..5ccd144 100644
--- a/ole/nls/esh.nls
+++ b/ole/nls/esh.nls
@@ -3,7 +3,7 @@
  *      Spanish (Honduras)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x480a")
 LOCVAL(LOCALE_SLANGUAGE,"Español")
 LOCVAL(LOCALE_SENGLANGUAGE,"Spanish")
 LOCVAL(LOCALE_SABBREVLANGNAME,"esh")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Honduras")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"HND")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Honduras")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
@@ -43,10 +43,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/esi.nls b/ole/nls/esi.nls
index 0ca82d3..9f8c68e 100644
--- a/ole/nls/esi.nls
+++ b/ole/nls/esi.nls
@@ -3,7 +3,7 @@
  *      Spanish (Nicaragua)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x4c0a")
 LOCVAL(LOCALE_SLANGUAGE,"Español")
 LOCVAL(LOCALE_SENGLANGUAGE,"Spanish")
 LOCVAL(LOCALE_SABBREVLANGNAME,"esi")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Nicaragua")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"NIC")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Nicaragua")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/esl.nls b/ole/nls/esl.nls
index 2f9339a..f3a0eb1 100644
--- a/ole/nls/esl.nls
+++ b/ole/nls/esl.nls
@@ -3,19 +3,19 @@
  *      Spanish (Chile)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
-LOCVAL(LOCALE_SLANGUAGE,"Spanish (Chile)")
-LOCVAL(LOCALE_SENGLANGUAGE,"Spanish")
+LOCVAL(LOCALE_ILANGUAGE,"0x340a")
+LOCVAL(LOCALE_SLANGUAGE,"Español (Chile)")
+LOCVAL(LOCALE_SENGLANGUAGE,"Spanish (Chile)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"esl")
-LOCVAL(LOCALE_SNATIVELANGNAME,"Espa€ol")
+LOCVAL(LOCALE_SNATIVELANGNAME,"Español")
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
-/* LOCVAL(LOCALE_SCOUNTRY,"") */
+LOCVAL(LOCALE_SCOUNTRY,"Chile")
 LOCVAL(LOCALE_SENGCOUNTRY,"Chile")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"CHL")
-/* LOCVAL(LOCALE_SNATIVECTRYNAME,"Chile") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_SNATIVECTRYNAME,"Chile")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
-/* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
+LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
 /* LOCVAL(LOCALE_SLIST,"") */
 /* LOCVAL(LOCALE_IMEASURE,"") */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
@@ -57,21 +57,21 @@
 
 LOCVAL(LOCALE_SDAYNAME1,"lunes")
 LOCVAL(LOCALE_SDAYNAME2,"martes")
-LOCVAL(LOCALE_SDAYNAME3,"mi?rcoles")
+LOCVAL(LOCALE_SDAYNAME3,"miércoles")
 LOCVAL(LOCALE_SDAYNAME4,"jueves")
 LOCVAL(LOCALE_SDAYNAME5,"viernes")
-LOCVAL(LOCALE_SDAYNAME6,"s?abado")
+LOCVAL(LOCALE_SDAYNAME6,"sábado")
 LOCVAL(LOCALE_SDAYNAME7,"domingo")
 
-/* LOCVAL(LOCALE_SABBREVDAYNAME1,"lun") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME2,"mar") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME3,"mi?") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME4,"jue") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME5,"vie") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME6,"") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME7,"") */
+LOCVAL(LOCALE_SABBREVDAYNAME1,"lun")
+LOCVAL(LOCALE_SABBREVDAYNAME2,"mar")
+LOCVAL(LOCALE_SABBREVDAYNAME3,"mié")
+LOCVAL(LOCALE_SABBREVDAYNAME4,"jue")
+LOCVAL(LOCALE_SABBREVDAYNAME5,"vie")
+LOCVAL(LOCALE_SABBREVDAYNAME6,"sáb")
+LOCVAL(LOCALE_SABBREVDAYNAME7,"dom")
 
-/* LOCVAL(LOCALE_SMONTHNAME1,"") */
+LOCVAL(LOCALE_SMONTHNAME1,"enero")
 LOCVAL(LOCALE_SMONTHNAME2,"febrero")
 LOCVAL(LOCALE_SMONTHNAME3,"marzo")
 LOCVAL(LOCALE_SMONTHNAME4,"abril")
@@ -99,8 +99,8 @@
 LOCVAL(LOCALE_SABBREVMONTHNAME12,"dic")
 LOCVAL(LOCALE_SABBREVMONTHNAME13,"")
 
-/* LOCVAL(LOCALE_SPOSITIVESIGN, "") */
-/* LOCVAL(LOCALE_SNEGATIVESIGN, "") */
+LOCVAL(LOCALE_SPOSITIVESIGN, "")
+LOCVAL(LOCALE_SNEGATIVESIGN, "-")
 /* LOCVAL(LOCALE_IPOSSIGNPOSN, "") */
 /* LOCVAL(LOCALE_INEGSIGNPOSN, "") */
 /* LOCVAL(LOCALE_IPOSSYMPRECEDES, "") */
diff --git a/ole/nls/esm.nls b/ole/nls/esm.nls
index 6990594..f7dfde4 100644
--- a/ole/nls/esm.nls
+++ b/ole/nls/esm.nls
@@ -3,7 +3,7 @@
  *      Mexico
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x080a")
 LOCVAL(LOCALE_SLANGUAGE,"Español (Mexico)")
 LOCVAL(LOCALE_SENGLANGUAGE,"Spanish (Mexico)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"esm")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Mexico")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"Mx")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Mexico")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/esn.nls b/ole/nls/esn.nls
index 680f048..bd1b090 100644
--- a/ole/nls/esn.nls
+++ b/ole/nls/esn.nls
@@ -3,17 +3,17 @@
  *      Spanish (Modern Sort)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0c0a")
 LOCVAL(LOCALE_SLANGUAGE,"Español")
 LOCVAL(LOCALE_SENGLANGUAGE,"Spanish - Modern Sort")
 LOCVAL(LOCALE_SABBREVLANGNAME,"esn")
 LOCVAL(LOCALE_SNATIVELANGNAME,"Español (Moderno)")
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
-/* LOCVAL(LOCALE_SCOUNTRY,"") */
+LOCVAL(LOCALE_SCOUNTRY,"España")
 LOCVAL(LOCALE_SENGCOUNTRY,"Spain")
-LOCVAL(LOCALE_SABBREVCTRYNAME,"Es")
+LOCVAL(LOCALE_SABBREVCTRYNAME,"ESP")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"España")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/eso.nls b/ole/nls/eso.nls
index 8780105..1bfe0f0 100644
--- a/ole/nls/eso.nls
+++ b/ole/nls/eso.nls
@@ -3,17 +3,17 @@
  *      Spanish (Colombia)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
-/* LOCVAL(LOCALE_SLANGUAGE,"") */
-LOCVAL(LOCALE_SENGLANGUAGE,"Spanish")
+LOCVAL(LOCALE_ILANGUAGE,"0x240a")
+LOCVAL(LOCALE_SLANGUAGE,"Español (Colombia)")
+LOCVAL(LOCALE_SENGLANGUAGE,"Spanish (Colombia)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"esg")
-LOCVAL(LOCALE_SNATIVELANGNAME,"Espa€ol")
+LOCVAL(LOCALE_SNATIVELANGNAME,"Español")
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 LOCVAL(LOCALE_SCOUNTRY,"Colombia")
 LOCVAL(LOCALE_SENGCOUNTRY,"Colombia")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"COL")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Colombia")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
@@ -57,21 +57,21 @@
 
 LOCVAL(LOCALE_SDAYNAME1,"lunes")
 LOCVAL(LOCALE_SDAYNAME2,"martes")
-LOCVAL(LOCALE_SDAYNAME3,"mi?rcoles")
+LOCVAL(LOCALE_SDAYNAME3,"miércoles")
 LOCVAL(LOCALE_SDAYNAME4,"jueves")
 LOCVAL(LOCALE_SDAYNAME5,"viernes")
-LOCVAL(LOCALE_SDAYNAME6,"s?abado")
+LOCVAL(LOCALE_SDAYNAME6,"sábado")
 LOCVAL(LOCALE_SDAYNAME7,"domingo")
 
-/* LOCVAL(LOCALE_SABBREVDAYNAME1,"lun") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME2,"mar") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME3,"mi?") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME4,"jue") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME5,"vie") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME6,"") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME7,"") */
+LOCVAL(LOCALE_SABBREVDAYNAME1,"lun")
+LOCVAL(LOCALE_SABBREVDAYNAME2,"mar")
+LOCVAL(LOCALE_SABBREVDAYNAME3,"mié")
+LOCVAL(LOCALE_SABBREVDAYNAME4,"jue")
+LOCVAL(LOCALE_SABBREVDAYNAME5,"vie")
+LOCVAL(LOCALE_SABBREVDAYNAME6,"sáb")
+LOCVAL(LOCALE_SABBREVDAYNAME7,"dom")
 
-/* LOCVAL(LOCALE_SMONTHNAME1,"") */
+LOCVAL(LOCALE_SMONTHNAME1,"enero")
 LOCVAL(LOCALE_SMONTHNAME2,"febrero")
 LOCVAL(LOCALE_SMONTHNAME3,"marzo")
 LOCVAL(LOCALE_SMONTHNAME4,"abril")
@@ -99,8 +99,8 @@
 LOCVAL(LOCALE_SABBREVMONTHNAME12,"dic")
 LOCVAL(LOCALE_SABBREVMONTHNAME13,"")
 
-/* LOCVAL(LOCALE_SPOSITIVESIGN, "") */
-/* LOCVAL(LOCALE_SNEGATIVESIGN, "") */
+LOCVAL(LOCALE_SPOSITIVESIGN, "")
+LOCVAL(LOCALE_SNEGATIVESIGN, "-")
 /* LOCVAL(LOCALE_IPOSSIGNPOSN, "") */
 /* LOCVAL(LOCALE_INEGSIGNPOSN, "") */
 /* LOCVAL(LOCALE_IPOSSYMPRECEDES, "") */
@@ -108,4 +108,3 @@
 /* LOCVAL(LOCALE_INEGSYMPRECEDES, "") */
 /* LOCVAL(LOCALE_INEGSEPBYSPACE, "") */
 
-/* calendario gregoriano */
diff --git a/ole/nls/esp.nls b/ole/nls/esp.nls
index dbbc0f3..87b59da 100644
--- a/ole/nls/esp.nls
+++ b/ole/nls/esp.nls
@@ -3,7 +3,7 @@
  *      Spanish (Traditional Sort)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x040a")
 LOCVAL(LOCALE_SLANGUAGE,"Español")
 LOCVAL(LOCALE_SENGLANGUAGE,"Spanish - Traditional Sort")
 LOCVAL(LOCALE_SABBREVLANGNAME,"esp")
@@ -11,9 +11,9 @@
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 LOCVAL(LOCALE_SCOUNTRY,"España")
 LOCVAL(LOCALE_SENGCOUNTRY,"Spain")
-LOCVAL(LOCALE_SABBREVCTRYNAME,"Es")
+LOCVAL(LOCALE_SABBREVCTRYNAME,"ESP")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"España")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/esperanto.nls b/ole/nls/esperanto.nls
index 6611a3c..58cd801 100644
--- a/ole/nls/esperanto.nls
+++ b/ole/nls/esperanto.nls
@@ -5,9 +5,13 @@
  *      Esperanto seems not to be supported by Windows
  *
  *      TODO: ISO numerical ID for language ?
+ *
+ *	I choose 0x8f for esperanto language as it is high enough
+ *	not to be attributed to another language in the immediate
+ *	future (as of 19980901 the last official languageID is 0x51)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"9") */
+LOCVAL(LOCALE_ILANGUAGE,"0x048f")
 LOCVAL(LOCALE_SLANGUAGE,"Esperanto")
 LOCVAL(LOCALE_SENGLANGUAGE,"Esperanto")
 /* LOCVAL(LOCALE_SABBREVLANGNAME,"deu") */
@@ -17,7 +21,7 @@
 /* LOCVAL(LOCALE_SENGCOUNTRY,"") */
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") ISO ID of lang TODO */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x048f") /* ISO ID of lang TODO */
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"3") /* is this right? TODO */
 LOCVAL(LOCALE_IDEFAULTANSICODEPAGE,"3") /* is this right? TODO */
diff --git a/ole/nls/esr.nls b/ole/nls/esr.nls
index 36027af..5a756dd 100644
--- a/ole/nls/esr.nls
+++ b/ole/nls/esr.nls
@@ -3,17 +3,17 @@
  *      Spanish (Peru)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
-/* LOCVAL(LOCALE_SLANGUAGE,"") */
-LOCVAL(LOCALE_SENGLANGUAGE,"Spanish")
+LOCVAL(LOCALE_ILANGUAGE,"0x280a")
+LOCVAL(LOCALE_SLANGUAGE,"Español (Perú)")
+LOCVAL(LOCALE_SENGLANGUAGE,"Spanish (Peru)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"esf")
-LOCVAL(LOCALE_SNATIVELANGNAME,"Espa€ol")
+LOCVAL(LOCALE_SNATIVELANGNAME,"Español")
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
-LOCVAL(LOCALE_SCOUNTRY,"Peru")
+LOCVAL(LOCALE_SCOUNTRY,"Perú")
 LOCVAL(LOCALE_SENGCOUNTRY,"Peru")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"PER")
-LOCVAL(LOCALE_SNATIVECTRYNAME,"Peru")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_SNATIVECTRYNAME,"Perú")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
@@ -57,21 +57,21 @@
 
 LOCVAL(LOCALE_SDAYNAME1,"lunes")
 LOCVAL(LOCALE_SDAYNAME2,"martes")
-LOCVAL(LOCALE_SDAYNAME3,"mi?rcoles")
+LOCVAL(LOCALE_SDAYNAME3,"miércoles")
 LOCVAL(LOCALE_SDAYNAME4,"jueves")
 LOCVAL(LOCALE_SDAYNAME5,"viernes")
-LOCVAL(LOCALE_SDAYNAME6,"s?abado")
+LOCVAL(LOCALE_SDAYNAME6,"sábado")
 LOCVAL(LOCALE_SDAYNAME7,"domingo")
 
-/* LOCVAL(LOCALE_SABBREVDAYNAME1,"lun") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME2,"mar") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME3,"mi?") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME4,"jue") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME5,"vie") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME6,"") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME7,"") */
+LOCVAL(LOCALE_SABBREVDAYNAME1,"lun")
+LOCVAL(LOCALE_SABBREVDAYNAME2,"mar")
+LOCVAL(LOCALE_SABBREVDAYNAME3,"mié")
+LOCVAL(LOCALE_SABBREVDAYNAME4,"jue")
+LOCVAL(LOCALE_SABBREVDAYNAME5,"vie")
+LOCVAL(LOCALE_SABBREVDAYNAME6,"sáb")
+LOCVAL(LOCALE_SABBREVDAYNAME7,"dom")
 
-/* LOCVAL(LOCALE_SMONTHNAME1,"") */
+LOCVAL(LOCALE_SMONTHNAME1,"enero")
 LOCVAL(LOCALE_SMONTHNAME2,"febrero")
 LOCVAL(LOCALE_SMONTHNAME3,"marzo")
 LOCVAL(LOCALE_SMONTHNAME4,"abril")
@@ -99,8 +99,8 @@
 LOCVAL(LOCALE_SABBREVMONTHNAME12,"dic")
 LOCVAL(LOCALE_SABBREVMONTHNAME13,"")
 
-/* LOCVAL(LOCALE_SPOSITIVESIGN, "") */
-/* LOCVAL(LOCALE_SNEGATIVESIGN, "") */
+LOCVAL(LOCALE_SPOSITIVESIGN, "")
+LOCVAL(LOCALE_SNEGATIVESIGN, "-")
 /* LOCVAL(LOCALE_IPOSSIGNPOSN, "") */
 /* LOCVAL(LOCALE_INEGSIGNPOSN, "") */
 /* LOCVAL(LOCALE_IPOSSYMPRECEDES, "") */
@@ -108,4 +108,3 @@
 /* LOCVAL(LOCALE_INEGSYMPRECEDES, "") */
 /* LOCVAL(LOCALE_INEGSEPBYSPACE, "") */
 
-/* calendario gregoriano */
diff --git a/ole/nls/ess.nls b/ole/nls/ess.nls
index 6bea781..545a32a 100644
--- a/ole/nls/ess.nls
+++ b/ole/nls/ess.nls
@@ -1,19 +1,19 @@
 /*
  *	OLE2NLS library
- *      Spanish (Argentinia)
+ *      Spanish (Argentina)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
-/* LOCVAL(LOCALE_SLANGUAGE,"") */
-LOCVAL(LOCALE_SENGLANGUAGE,"Spanish")
+LOCVAL(LOCALE_ILANGUAGE,"0x2c0a")
+LOCVAL(LOCALE_SLANGUAGE,"Español (Argentina)")
+LOCVAL(LOCALE_SENGLANGUAGE,"Spanish (Argentina)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"esg")
-LOCVAL(LOCALE_SNATIVELANGNAME,"Espa€ol")
+LOCVAL(LOCALE_SNATIVELANGNAME,"Español")
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
-LOCVAL(LOCALE_SCOUNTRY,"Argentinia")
-LOCVAL(LOCALE_SENGCOUNTRY,"Argentinia")
+LOCVAL(LOCALE_SCOUNTRY,"Argentina")
+LOCVAL(LOCALE_SENGCOUNTRY,"Argentina")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"ARG")
-LOCVAL(LOCALE_SNATIVECTRYNAME,"Argentinia")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_SNATIVECTRYNAME,"Argentina")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 LOCVAL(LOCALE_S1159, "AM")
@@ -57,21 +57,21 @@
 
 LOCVAL(LOCALE_SDAYNAME1,"lunes")
 LOCVAL(LOCALE_SDAYNAME2,"martes")
-LOCVAL(LOCALE_SDAYNAME3,"mi?rcoles")
+LOCVAL(LOCALE_SDAYNAME3,"miércoles")
 LOCVAL(LOCALE_SDAYNAME4,"jueves")
 LOCVAL(LOCALE_SDAYNAME5,"viernes")
-LOCVAL(LOCALE_SDAYNAME6,"s?abado")
+LOCVAL(LOCALE_SDAYNAME6,"sábado")
 LOCVAL(LOCALE_SDAYNAME7,"domingo")
 
-/* LOCVAL(LOCALE_SABBREVDAYNAME1,"lun") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME2,"mar") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME3,"mi?") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME4,"jue") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME5,"vie") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME6,"") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME7,"") */
+LOCVAL(LOCALE_SABBREVDAYNAME1,"lun")
+LOCVAL(LOCALE_SABBREVDAYNAME2,"mar")
+LOCVAL(LOCALE_SABBREVDAYNAME3,"mié")
+LOCVAL(LOCALE_SABBREVDAYNAME4,"jue")
+LOCVAL(LOCALE_SABBREVDAYNAME5,"vie")
+LOCVAL(LOCALE_SABBREVDAYNAME6,"sáb")
+LOCVAL(LOCALE_SABBREVDAYNAME7,"dom")
 
-/* LOCVAL(LOCALE_SMONTHNAME1,"") */
+LOCVAL(LOCALE_SMONTHNAME1,"enero")
 LOCVAL(LOCALE_SMONTHNAME2,"febrero")
 LOCVAL(LOCALE_SMONTHNAME3,"marzo")
 LOCVAL(LOCALE_SMONTHNAME4,"abril")
@@ -99,8 +99,8 @@
 LOCVAL(LOCALE_SABBREVMONTHNAME12,"dic")
 LOCVAL(LOCALE_SABBREVMONTHNAME13,"")
 
-/* LOCVAL(LOCALE_SPOSITIVESIGN, "") */
-/* LOCVAL(LOCALE_SNEGATIVESIGN, "") */
+LOCVAL(LOCALE_SPOSITIVESIGN, "")
+LOCVAL(LOCALE_SNEGATIVESIGN, "-")
 /* LOCVAL(LOCALE_IPOSSIGNPOSN, "") */
 /* LOCVAL(LOCALE_INEGSIGNPOSN, "") */
 /* LOCVAL(LOCALE_IPOSSYMPRECEDES, "") */
@@ -108,4 +108,3 @@
 /* LOCVAL(LOCALE_INEGSYMPRECEDES, "") */
 /* LOCVAL(LOCALE_INEGSEPBYSPACE, "") */
 
-/* calendario gregoriano */
diff --git a/ole/nls/est.nls b/ole/nls/est.nls
index 7a29465..fd0b491 100644
--- a/ole/nls/est.nls
+++ b/ole/nls/est.nls
@@ -3,7 +3,7 @@
  *      Estonia
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0425")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
 LOCVAL(LOCALE_SENGLANGUAGE,"Estonian")
 LOCVAL(LOCALE_SABBREVLANGNAME,"est")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Estonia")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"Ee")
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0425")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/esu.nls b/ole/nls/esu.nls
index 50e9dff..6901bc4 100644
--- a/ole/nls/esu.nls
+++ b/ole/nls/esu.nls
@@ -3,7 +3,7 @@
  *      Spanish (Puerto Rico)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x500a")
 LOCVAL(LOCALE_SLANGUAGE,"Español (Puerto Rico)")
 LOCVAL(LOCALE_SENGLANGUAGE,"Spanish (Puerto Rico)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"esu")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Puerto Rico")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Puerto Rico")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/esv.nls b/ole/nls/esv.nls
index dac639e..c469bbf 100644
--- a/ole/nls/esv.nls
+++ b/ole/nls/esv.nls
@@ -3,19 +3,19 @@
  *      Spanish (Venezuela)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
-/* LOCVAL(LOCALE_SLANGUAGE,"") */
-LOCVAL(LOCALE_SENGLANGUAGE,"Spanish")
+LOCVAL(LOCALE_ILANGUAGE,"0x200a")
+LOCVAL(LOCALE_SLANGUAGE,"Español (Venezuela)")
+LOCVAL(LOCALE_SENGLANGUAGE,"Spanish (Venezuela)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"esv")
-LOCVAL(LOCALE_SNATIVELANGNAME,"Espa€ol")
+LOCVAL(LOCALE_SNATIVELANGNAME,"Español (Venezuela)")
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 LOCVAL(LOCALE_SCOUNTRY,"Venezuela")
 LOCVAL(LOCALE_SENGCOUNTRY,"Venezuela")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"VEN")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Venezuela")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
-/* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
+LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
 /* LOCVAL(LOCALE_SLIST,"") */
 /* LOCVAL(LOCALE_IMEASURE,"") */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
@@ -57,21 +57,21 @@
 
 LOCVAL(LOCALE_SDAYNAME1,"lunes")
 LOCVAL(LOCALE_SDAYNAME2,"martes")
-LOCVAL(LOCALE_SDAYNAME3,"mi?rcoles")
+LOCVAL(LOCALE_SDAYNAME3,"miércoles")
 LOCVAL(LOCALE_SDAYNAME4,"jueves")
 LOCVAL(LOCALE_SDAYNAME5,"viernes")
-LOCVAL(LOCALE_SDAYNAME6,"s?abado")
+LOCVAL(LOCALE_SDAYNAME6,"sábado")
 LOCVAL(LOCALE_SDAYNAME7,"domingo")
 
-/* LOCVAL(LOCALE_SABBREVDAYNAME1,"lun") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME2,"mar") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME3,"mi?") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME4,"jue") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME5,"vie") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME6,"") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME7,"") */
+LOCVAL(LOCALE_SABBREVDAYNAME1,"lun")
+LOCVAL(LOCALE_SABBREVDAYNAME2,"mar")
+LOCVAL(LOCALE_SABBREVDAYNAME3,"mié")
+LOCVAL(LOCALE_SABBREVDAYNAME4,"jue")
+LOCVAL(LOCALE_SABBREVDAYNAME5,"vie")
+LOCVAL(LOCALE_SABBREVDAYNAME6,"sáb")
+LOCVAL(LOCALE_SABBREVDAYNAME7,"dom")
 
-/* LOCVAL(LOCALE_SMONTHNAME1,"") */
+LOCVAL(LOCALE_SMONTHNAME1,"enero")
 LOCVAL(LOCALE_SMONTHNAME2,"febrero")
 LOCVAL(LOCALE_SMONTHNAME3,"marzo")
 LOCVAL(LOCALE_SMONTHNAME4,"abril")
@@ -99,8 +99,8 @@
 LOCVAL(LOCALE_SABBREVMONTHNAME12,"dic")
 LOCVAL(LOCALE_SABBREVMONTHNAME13,"")
 
-/* LOCVAL(LOCALE_SPOSITIVESIGN, "") */
-/* LOCVAL(LOCALE_SNEGATIVESIGN, "") */
+LOCVAL(LOCALE_SPOSITIVESIGN, "")
+LOCVAL(LOCALE_SNEGATIVESIGN, "-")
 /* LOCVAL(LOCALE_IPOSSIGNPOSN, "") */
 /* LOCVAL(LOCALE_INEGSIGNPOSN, "") */
 /* LOCVAL(LOCALE_IPOSSYMPRECEDES, "") */
@@ -108,4 +108,3 @@
 /* LOCVAL(LOCALE_INEGSYMPRECEDES, "") */
 /* LOCVAL(LOCALE_INEGSEPBYSPACE, "") */
 
-/* calendario gregoriano */
diff --git a/ole/nls/esy.nls b/ole/nls/esy.nls
index 2f8b9ac..998dc60 100644
--- a/ole/nls/esy.nls
+++ b/ole/nls/esy.nls
@@ -3,17 +3,17 @@
  *      Spanish (Uruguay)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
-LOCVAL(LOCALE_SLANGUAGE,"Espa€ol")
-LOCVAL(LOCALE_SENGLANGUAGE,"Spanish")
+LOCVAL(LOCALE_ILANGUAGE,"0x380a")
+LOCVAL(LOCALE_SLANGUAGE,"Español (Uruguay)")
+LOCVAL(LOCALE_SENGLANGUAGE,"Spanish (Uruguay)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"esy")
-LOCVAL(LOCALE_SNATIVELANGNAME,"Uruguay")
-/* LOCVAL(LOCALE_ICOUNTRY,"") */
-/* LOCVAL(LOCALE_SCOUNTRY,"") */
+LOCVAL(LOCALE_SNATIVELANGNAME,"Español (Uruguay)")
+LOCVAL(LOCALE_ICOUNTRY,"598")
+LOCVAL(LOCALE_SCOUNTRY,"Uruguay")
 LOCVAL(LOCALE_SENGCOUNTRY,"Uruguay")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"URY")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Uruguay")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x380a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -26,8 +26,8 @@
 /* LOCVAL(LOCALE_ILZERO,"1") */
 /* LOCVAL(LOCALE_INEGNUMBER) */
 LOCVAL(LOCALE_SNATIVEDIGITS, "0123456789")
-LOCVAL(LOCALE_SCURRENCY,"NU$")
-LOCVAL(LOCALE_SINTLSYMBOL, "UYU")
+LOCVAL(LOCALE_SCURRENCY,"U$S")
+LOCVAL(LOCALE_SINTLSYMBOL, "UYP")
 /* LOCVAL(LOCALE_SMONDECIMALSEP,",") */
 /* LOCVAL(LOCALE_SMONTHOUSANDSEP,".") */
 LOCVAL(LOCALE_SMONGROUPING,"3;0")
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
@@ -57,19 +57,19 @@
 
 LOCVAL(LOCALE_SDAYNAME1,"lunes")
 LOCVAL(LOCALE_SDAYNAME2,"martes")
-LOCVAL(LOCALE_SDAYNAME3,"mi?rcoles")
+LOCVAL(LOCALE_SDAYNAME3,"miércoles")
 LOCVAL(LOCALE_SDAYNAME4,"jueves")
 LOCVAL(LOCALE_SDAYNAME5,"viernes")
-LOCVAL(LOCALE_SDAYNAME6,"s?abado")
+LOCVAL(LOCALE_SDAYNAME6,"sábado")
 LOCVAL(LOCALE_SDAYNAME7,"domingo")
 
-/* LOCVAL(LOCALE_SABBREVDAYNAME1,"lun") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME2,"mar") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME3,"mi?") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME4,"jue") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME5,"vie") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME6,"") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME7,"") */
+LOCVAL(LOCALE_SABBREVDAYNAME1,"lun")
+LOCVAL(LOCALE_SABBREVDAYNAME2,"mar")
+LOCVAL(LOCALE_SABBREVDAYNAME3,"mié")
+LOCVAL(LOCALE_SABBREVDAYNAME4,"jue")
+LOCVAL(LOCALE_SABBREVDAYNAME5,"vie")
+LOCVAL(LOCALE_SABBREVDAYNAME6,"sáb")
+LOCVAL(LOCALE_SABBREVDAYNAME7,"dom")
 
 LOCVAL(LOCALE_SMONTHNAME1,"enero")
 LOCVAL(LOCALE_SMONTHNAME2,"febrero")
@@ -99,8 +99,8 @@
 LOCVAL(LOCALE_SABBREVMONTHNAME12,"dic")
 LOCVAL(LOCALE_SABBREVMONTHNAME13,"")
 
-/* LOCVAL(LOCALE_SPOSITIVESIGN, "") */
-/* LOCVAL(LOCALE_SNEGATIVESIGN, "") */
+LOCVAL(LOCALE_SPOSITIVESIGN, "")
+LOCVAL(LOCALE_SNEGATIVESIGN, "-")
 /* LOCVAL(LOCALE_IPOSSIGNPOSN, "") */
 /* LOCVAL(LOCALE_INEGSIGNPOSN, "") */
 /* LOCVAL(LOCALE_IPOSSYMPRECEDES, "") */
@@ -108,4 +108,3 @@
 /* LOCVAL(LOCALE_INEGSYMPRECEDES, "") */
 /* LOCVAL(LOCALE_INEGSEPBYSPACE, "") */
 
-/* calendario gregoriano */
diff --git a/ole/nls/esz.nls b/ole/nls/esz.nls
index 01ad318..8f6fb4f 100644
--- a/ole/nls/esz.nls
+++ b/ole/nls/esz.nls
@@ -3,19 +3,20 @@
  *      Spanish (Paraguay)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
-/* LOCVAL(LOCALE_SLANGUAGE,"") */
-LOCVAL(LOCALE_SENGLANGUAGE,"Spanish")
+
+LOCVAL(LOCALE_ILANGUAGE,"0x3c0a")
+LOCVAL(LOCALE_SLANGUAGE,"Español (Paraguay)")
+LOCVAL(LOCALE_SENGLANGUAGE,"Spanish (Paraguay)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"esz")
-LOCVAL(LOCALE_SNATIVELANGNAME,"Paraguay")
+LOCVAL(LOCALE_SNATIVELANGNAME,"Español (Paraguay)")
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
-/* LOCVAL(LOCALE_SCOUNTRY,"") */
+LOCVAL(LOCALE_SCOUNTRY,"Paraguay")
 LOCVAL(LOCALE_SENGCOUNTRY,"Paraguay")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"PRY")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Paraguay")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
-/* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
+LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
 /* LOCVAL(LOCALE_SLIST,"") */
 /* LOCVAL(LOCALE_IMEASURE,"") */
@@ -42,10 +43,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
@@ -57,19 +58,19 @@
 
 LOCVAL(LOCALE_SDAYNAME1,"lunes")
 LOCVAL(LOCALE_SDAYNAME2,"martes")
-LOCVAL(LOCALE_SDAYNAME3,"mi?rcoles")
+LOCVAL(LOCALE_SDAYNAME3,"miércoles")
 LOCVAL(LOCALE_SDAYNAME4,"jueves")
 LOCVAL(LOCALE_SDAYNAME5,"viernes")
-LOCVAL(LOCALE_SDAYNAME6,"s?abado")
+LOCVAL(LOCALE_SDAYNAME6,"sábado")
 LOCVAL(LOCALE_SDAYNAME7,"domingo")
 
-/* LOCVAL(LOCALE_SABBREVDAYNAME1,"lun") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME2,"mar") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME3,"mi?") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME4,"jue") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME5,"vie") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME6,"") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME7,"") */
+LOCVAL(LOCALE_SABBREVDAYNAME1,"lun")
+LOCVAL(LOCALE_SABBREVDAYNAME2,"mar")
+LOCVAL(LOCALE_SABBREVDAYNAME3,"mié")
+LOCVAL(LOCALE_SABBREVDAYNAME4,"jue")
+LOCVAL(LOCALE_SABBREVDAYNAME5,"vie")
+LOCVAL(LOCALE_SABBREVDAYNAME6,"sáb")
+LOCVAL(LOCALE_SABBREVDAYNAME7,"dom")
 
 LOCVAL(LOCALE_SMONTHNAME1,"enero")
 LOCVAL(LOCALE_SMONTHNAME2,"febrero")
@@ -99,8 +100,8 @@
 LOCVAL(LOCALE_SABBREVMONTHNAME12,"dic")
 LOCVAL(LOCALE_SABBREVMONTHNAME13,"")
 
-/* LOCVAL(LOCALE_SPOSITIVESIGN, "") */
-/* LOCVAL(LOCALE_SNEGATIVESIGN, "") */
+LOCVAL(LOCALE_SPOSITIVESIGN, "")
+LOCVAL(LOCALE_SNEGATIVESIGN, "-")
 /* LOCVAL(LOCALE_IPOSSIGNPOSN, "") */
 /* LOCVAL(LOCALE_INEGSIGNPOSN, "") */
 /* LOCVAL(LOCALE_IPOSSYMPRECEDES, "") */
@@ -108,4 +109,3 @@
 /* LOCVAL(LOCALE_INEGSYMPRECEDES, "") */
 /* LOCVAL(LOCALE_INEGSEPBYSPACE, "") */
 
-/* calendario gregoriano */
diff --git a/ole/nls/euq.nls b/ole/nls/euq.nls
index c6639fe..cc9397c 100644
--- a/ole/nls/euq.nls
+++ b/ole/nls/euq.nls
@@ -3,7 +3,7 @@
  *      Basque
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x04d2")
 LOCVAL(LOCALE_SLANGUAGE,"Euskara")
 LOCVAL(LOCALE_SENGLANGUAGE,"Basque")
 LOCVAL(LOCALE_SABBREVLANGNAME,"euq")
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
@@ -63,13 +63,13 @@
 LOCVAL(LOCALE_SDAYNAME6,"larunbata")
 LOCVAL(LOCALE_SDAYNAME7,"igandea")
 
-/* LOCVAL(LOCALE_SABBREVDAYNAME1,"lun") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME2,"mar") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME3,"mi?") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME4,"jue") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME5,"vie") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME6,"") */
-/* LOCVAL(LOCALE_SABBREVDAYNAME7,"") */
+LOCVAL(LOCALE_SABBREVDAYNAME1,"leh")
+LOCVAL(LOCALE_SABBREVDAYNAME2,"art")
+LOCVAL(LOCALE_SABBREVDAYNAME3,"azk")
+LOCVAL(LOCALE_SABBREVDAYNAME4,"teg")
+LOCVAL(LOCALE_SABBREVDAYNAME5,"tir")
+LOCVAL(LOCALE_SABBREVDAYNAME6,"lar")
+LOCVAL(LOCALE_SABBREVDAYNAME7,"iga")
 
 LOCVAL(LOCALE_SMONTHNAME1,"urtarrila")
 LOCVAL(LOCALE_SMONTHNAME2,"otsaila")
diff --git a/ole/nls/fin.nls b/ole/nls/fin.nls
index 6cd954c..1aed8df 100644
--- a/ole/nls/fin.nls
+++ b/ole/nls/fin.nls
@@ -3,17 +3,17 @@
  *      Finland
  */
  
-LOCVAL(LOCALE_ILANGUAGE,"11")
+LOCVAL(LOCALE_ILANGUAGE,"0x040b")
 LOCVAL(LOCALE_SLANGUAGE,"Suomi")
 LOCVAL(LOCALE_SENGLANGUAGE,"Finnish")
 LOCVAL(LOCALE_SABBREVLANGNAME,"fin")
 LOCVAL(LOCALE_SNATIVELANGNAME,"suomi")
-LOCVAL(LOCALE_ICOUNTRY,"49")
+LOCVAL(LOCALE_ICOUNTRY,"358")
 LOCVAL(LOCALE_SCOUNTRY,"Suomi")
 LOCVAL(LOCALE_SENGCOUNTRY,"Finland")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"Fin")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Suomi")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE,"11")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040b")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"358")
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
diff --git a/ole/nls/fos.nls b/ole/nls/fos.nls
index 1ece8c6..597513d 100644
--- a/ole/nls/fos.nls
+++ b/ole/nls/fos.nls
@@ -3,17 +3,17 @@
  *      Faroe Islands
  */
 
-LOCVAL(LOCALE_ILANGUAGE,"9")
-LOCVAL(LOCALE_SLANGUAGE,"")
+LOCVAL(LOCALE_ILANGUAGE,"0x0438")
+/* LOCVAL(LOCALE_SLANGUAGE,"") */
 LOCVAL(LOCALE_SENGLANGUAGE,"Faroese")
 LOCVAL(LOCALE_SABBREVLANGNAME,"fos")
-LOCVAL(LOCALE_SNATIVELANGNAME,"f?royskt")
+LOCVAL(LOCALE_SNATIVELANGNAME,"færoyskt")
 LOCVAL(LOCALE_ICOUNTRY,"298")
 LOCVAL(LOCALE_SCOUNTRY,"")
 LOCVAL(LOCALE_SENGCOUNTRY,"Faroe Islands")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"FRS")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Froyar")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"9") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0438")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"40") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE,"851") */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
diff --git a/ole/nls/fra.nls b/ole/nls/fra.nls
index eb41c07..bdf5167 100644
--- a/ole/nls/fra.nls
+++ b/ole/nls/fra.nls
@@ -3,7 +3,7 @@
  *      France
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x040c")
 LOCVAL(LOCALE_SLANGUAGE,"Français")
 LOCVAL(LOCALE_SENGLANGUAGE,"French")
 LOCVAL(LOCALE_SABBREVLANGNAME,"fra")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"France")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"FRA")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"France")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040c")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 LOCVAL(LOCALE_S1159, "")
diff --git a/ole/nls/frb.nls b/ole/nls/frb.nls
index dbbd7b6..32c176d 100644
--- a/ole/nls/frb.nls
+++ b/ole/nls/frb.nls
@@ -3,7 +3,7 @@
  *      Belgium
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x080c")
 LOCVAL(LOCALE_SLANGUAGE,"Français (Belgique)")
 LOCVAL(LOCALE_SENGLANGUAGE,"French (Belgium)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"frb")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Belgium")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"BEL")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Belgique")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040c")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 LOCVAL(LOCALE_S1159, "")
diff --git a/ole/nls/frc.nls b/ole/nls/frc.nls
index ffcdd46..b208820 100644
--- a/ole/nls/frc.nls
+++ b/ole/nls/frc.nls
@@ -3,9 +3,9 @@
  *      Canada (French)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
-/* LOCVAL(LOCALE_SLANGUAGE,"") */
-LOCVAL(LOCALE_SENGLANGUAGE,"French")
+LOCVAL(LOCALE_ILANGUAGE,"0x0c0c")
+LOCVAL(LOCALE_SLANGUAGE,"Français (Canada)")
+LOCVAL(LOCALE_SENGLANGUAGE,"French (Canada)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"frc")
 LOCVAL(LOCALE_SNATIVELANGNAME,"français")
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Canada")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"CAN")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Canada")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040c")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/frl.nls b/ole/nls/frl.nls
index b857123..191effb 100644
--- a/ole/nls/frl.nls
+++ b/ole/nls/frl.nls
@@ -3,9 +3,9 @@
  *      Luxemburg (French)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
-LOCVAL(LOCALE_SLANGUAGE,"Français")
-LOCVAL(LOCALE_SENGLANGUAGE,"French")
+LOCVAL(LOCALE_ILANGUAGE,"0x140c")
+LOCVAL(LOCALE_SLANGUAGE,"Français (Luxembourg)")
+LOCVAL(LOCALE_SENGLANGUAGE,"French (Luxembourg)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"frl")
 LOCVAL(LOCALE_SNATIVELANGNAME,"français")
 LOCVAL(LOCALE_ICOUNTRY,"352")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Luxemburg")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"LUX")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Luxembourg")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040c")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/frs.nls b/ole/nls/frs.nls
index a96a020..7bb7e17 100644
--- a/ole/nls/frs.nls
+++ b/ole/nls/frs.nls
@@ -3,7 +3,7 @@
  *      Switzerland (French)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x100c")
 LOCVAL(LOCALE_SLANGUAGE,"Français (Suisse)")
 LOCVAL(LOCALE_SENGLANGUAGE,"French (Switzerland)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"frs")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Switzerland")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Suisse")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040c")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/grc.nls b/ole/nls/grc.nls
index 54f81aa..35714a6 100644
--- a/ole/nls/grc.nls
+++ b/ole/nls/grc.nls
@@ -4,7 +4,7 @@
  *	(Greek strings in iso-8859-7)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0408")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
 LOCVAL(LOCALE_SENGLANGUAGE,"Greek")
 LOCVAL(LOCALE_SABBREVLANGNAME,"grc")
@@ -14,7 +14,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Greece")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0408")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -43,10 +43,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/hrv.nls b/ole/nls/hrv.nls
index b9f42e8..aac8a9d 100644
--- a/ole/nls/hrv.nls
+++ b/ole/nls/hrv.nls
@@ -4,7 +4,7 @@
  *	(Croatian strings in iso-8859-2)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x041a")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
 LOCVAL(LOCALE_SENGLANGUAGE,"Croatian")
 LOCVAL(LOCALE_SABBREVLANGNAME,"hrv")
@@ -14,7 +14,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Croatia")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"HRV")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Hrvatska")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x041a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -43,10 +43,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
@@ -79,12 +79,12 @@
 LOCVAL(LOCALE_SMONTHNAME5,"maj")
 LOCVAL(LOCALE_SMONTHNAME6,"jun")
 LOCVAL(LOCALE_SMONTHNAME7,"jul")
-LOCVAL(LOCALE_SMONTHNAME7,"august")
+LOCVAL(LOCALE_SMONTHNAME8,"august")
 LOCVAL(LOCALE_SMONTHNAME9,"septembar")
 LOCVAL(LOCALE_SMONTHNAME10,"oktobar")
 LOCVAL(LOCALE_SMONTHNAME11,"novembar")
 LOCVAL(LOCALE_SMONTHNAME12,"decembar")
-LOCVAL(LOCALE_SMONTHNAME12,"")
+LOCVAL(LOCALE_SMONTHNAME13,"")
 
 LOCVAL(LOCALE_SABBREVMONTHNAME1,"jan")
 LOCVAL(LOCALE_SABBREVMONTHNAME2,"feb")
diff --git a/ole/nls/hun.nls b/ole/nls/hun.nls
index 9bec0b7..5483d03 100644
--- a/ole/nls/hun.nls
+++ b/ole/nls/hun.nls
@@ -4,7 +4,7 @@
  *	(Hungarian strings in iso-8859-2)
  */
 
-LOCVAL(LOCALE_ILANGUAGE,"9")
+LOCVAL(LOCALE_ILANGUAGE,"0x040e")
 LOCVAL(LOCALE_SLANGUAGE,"Magyar")
 LOCVAL(LOCALE_SENGLANGUAGE,"Hungarian")
 LOCVAL(LOCALE_SABBREVLANGNAME,"hun")
@@ -14,7 +14,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Hungary")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"Hu")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Magyarország")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE,"9")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040e")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"36")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"852")
 LOCVAL(LOCALE_IDEFAULTANSICODEPAGE,"852")
diff --git a/ole/nls/ind.nls b/ole/nls/ind.nls
index 7c9610f..26b269a 100644
--- a/ole/nls/ind.nls
+++ b/ole/nls/ind.nls
@@ -3,7 +3,7 @@
  *      Indonesia (Bahasa)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0421")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
 /* LOCVAL(LOCALE_SENGLANGUAGE,"") */
 LOCVAL(LOCALE_SABBREVLANGNAME,"ind")
@@ -13,7 +13,7 @@
 /* LOCVAL(LOCALE_SENGCOUNTRY,"") */
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0421")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/irl.nls b/ole/nls/irl.nls
index f7b1266..a10f0df 100644
--- a/ole/nls/irl.nls
+++ b/ole/nls/irl.nls
@@ -3,8 +3,8 @@
  *      Ireland
  */
 
-LOCVAL(LOCALE_ILANGUAGE, "0409")
-LOCVAL(LOCALE_SLANGUAGE, "English")
+LOCVAL(LOCALE_ILANGUAGE, "0x1809")
+LOCVAL(LOCALE_SLANGUAGE, "English (Ireland)")
 LOCVAL(LOCALE_SENGLANGUAGE, "English")
 LOCVAL(LOCALE_SABBREVLANGNAME, "irl")
 LOCVAL(LOCALE_SNATIVELANGNAME, "English")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY, "Ireland")
 LOCVAL(LOCALE_SABBREVCTRYNAME, "IRL")
 LOCVAL(LOCALE_SNATIVECTRYNAME, "Eire")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0409")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0x0409")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY, "353")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE, "437")
 LOCVAL(LOCALE_IDEFAULTANSICODEPAGE, "1252")
diff --git a/ole/nls/isl.nls b/ole/nls/isl.nls
index 2c75620..1cdc48f 100644
--- a/ole/nls/isl.nls
+++ b/ole/nls/isl.nls
@@ -4,7 +4,7 @@
  *	(Icelandic strings in iso-8859-1)
  */
 
-LOCVAL(LOCALE_ILANGUAGE,"9")
+LOCVAL(LOCALE_ILANGUAGE,"0x040f")
 LOCVAL(LOCALE_SLANGUAGE,"Íslensk")
 LOCVAL(LOCALE_SENGLANGUAGE,"Icelandic")
 LOCVAL(LOCALE_SABBREVLANGNAME,"isl")
@@ -14,9 +14,9 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Iceland")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"Is")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Ísland")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"9") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x040f")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"354")
-/* LOCVAL(LOCALE_IDEFAULTCODEPAGE,"851") */
+LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
 LOCVAL(LOCALE_SLIST,";")
 LOCVAL(LOCALE_IMEASURE,"0")
diff --git a/ole/nls/ita.nls b/ole/nls/ita.nls
index c878be3..1ffe527 100644
--- a/ole/nls/ita.nls
+++ b/ole/nls/ita.nls
@@ -3,7 +3,7 @@
  *      Italy
  */
 
-LOCVAL(LOCALE_ILANGUAGE,"9")
+LOCVAL(LOCALE_ILANGUAGE,"0x410")
 LOCVAL(LOCALE_SLANGUAGE,"Italiano")
 LOCVAL(LOCALE_SENGLANGUAGE,"Italian")
 LOCVAL(LOCALE_SABBREVLANGNAME,"ita")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Italy")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"ITL")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Italia")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE,"9")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x410")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"39")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
diff --git a/ole/nls/its.nls b/ole/nls/its.nls
index 764dcfd..37047fb 100644
--- a/ole/nls/its.nls
+++ b/ole/nls/its.nls
@@ -3,7 +3,7 @@
  *      Switzerland (Italiano)
  */
 
-LOCVAL(LOCALE_ILANGUAGE,"9")
+LOCVAL(LOCALE_ILANGUAGE,"0x0810")
 LOCVAL(LOCALE_SLANGUAGE,"Italiano")
 LOCVAL(LOCALE_SENGLANGUAGE,"Italian")
 LOCVAL(LOCALE_SABBREVLANGNAME,"its")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Switzerand")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"CHE")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Svizzera")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE,"9")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0410")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"41")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
diff --git a/ole/nls/jpn.nls b/ole/nls/jpn.nls
index 0226808..7a22596 100644
--- a/ole/nls/jpn.nls
+++ b/ole/nls/jpn.nls
@@ -4,7 +4,7 @@
  *	(Japanese strings in EUC-JP)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0411")
 LOCVAL(LOCALE_SLANGUAGE,"ÆüËܸì")
 LOCVAL(LOCALE_SENGLANGUAGE,"Japanese")
 LOCVAL(LOCALE_SABBREVLANGNAME,"jpn")
@@ -14,7 +14,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Japan")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"JPN")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"ÆüËÜ")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0411")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"81")
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -43,10 +43,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/koj.nls b/ole/nls/koj.nls
index 4de9210..4cbc6a4 100644
--- a/ole/nls/koj.nls
+++ b/ole/nls/koj.nls
@@ -3,14 +3,14 @@
  *      Korean (Johab)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0812")
 LOCVAL(LOCALE_SLANGUAGE,"Korean (Johab)") 
 LOCVAL(LOCALE_SENGLANGUAGE,"Korean")
 LOCVAL(LOCALE_SABBREVLANGNAME,"koj")
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"Korea")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"KOR")
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
 /* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/kor.nls b/ole/nls/kor.nls
index 0644f00..535c0f1 100644
--- a/ole/nls/kor.nls
+++ b/ole/nls/kor.nls
@@ -4,7 +4,7 @@
  *      string using codepage 949
  */
  
-LOCVAL(LOCALE_ILANGUAGE,"18")
+LOCVAL(LOCALE_ILANGUAGE,"0x0412")
 LOCVAL(LOCALE_SLANGUAGE,"\307\321\261\271\276\356")
 LOCVAL(LOCALE_SENGLANGUAGE,"Korean")
 LOCVAL(LOCALE_SABBREVLANGNAME,"kor")
@@ -14,7 +14,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Korea (South)")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"KOR")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"\264\353\307\321\271\316\261\271")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE,"18")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0412")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"82")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"949")
 LOCVAL(LOCALE_IDEFAULTANSICODEPAGE,"949")
diff --git a/ole/nls/lth.nls b/ole/nls/lth.nls
index aaf5aeb..c1ab69e 100644
--- a/ole/nls/lth.nls
+++ b/ole/nls/lth.nls
@@ -4,7 +4,7 @@
  *	(Lithuanian strings in BALTIC charset)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0427")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
 LOCVAL(LOCALE_SENGLANGUAGE,"Lithuanian")
 LOCVAL(LOCALE_SABBREVLANGNAME,"lth")
@@ -14,7 +14,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Lithuania")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0427")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -43,10 +43,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/lvi.nls b/ole/nls/lvi.nls
index 3a0a1b6..4829ba6 100644
--- a/ole/nls/lvi.nls
+++ b/ole/nls/lvi.nls
@@ -4,7 +4,7 @@
  *	(Latvian strings in BALTIC charset)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0426")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
 LOCVAL(LOCALE_SENGLANGUAGE,"Latvian")
 LOCVAL(LOCALE_SABBREVLANGNAME,"lvi")
@@ -14,7 +14,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Latvia")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0426")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -43,10 +43,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/nlb.nls b/ole/nls/nlb.nls
index 10f9393..9e13235 100644
--- a/ole/nls/nlb.nls
+++ b/ole/nls/nlb.nls
@@ -3,9 +3,9 @@
  *      Dutch (Belgium)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
-LOCVAL(LOCALE_SLANGUAGE,"Nederlands")
-LOCVAL(LOCALE_SENGLANGUAGE,"Dutch")
+LOCVAL(LOCALE_ILANGUAGE,"0x0813")
+LOCVAL(LOCALE_SLANGUAGE,"Nederlands (België)")
+LOCVAL(LOCALE_SENGLANGUAGE,"Dutch (Belgium)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"nlb")
 LOCVAL(LOCALE_SNATIVELANGNAME,"Nederlands")
 LOCVAL(LOCALE_ICOUNTRY,"32")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Belgium")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"BEL")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"België")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0413")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"32")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/nld.nls b/ole/nls/nld.nls
index 109c645..0f600ef 100644
--- a/ole/nls/nld.nls
+++ b/ole/nls/nld.nls
@@ -3,7 +3,7 @@
  *      Dutch (Netherlands)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0413")
 LOCVAL(LOCALE_SLANGUAGE,"Nederlands")
 LOCVAL(LOCALE_SENGLANGUAGE,"Dutch")
 LOCVAL(LOCALE_SABBREVLANGNAME,"nld")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Netherlands")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"NLD")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Nederland")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0413")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"31")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/nls.nls b/ole/nls/nls.nls
index 6da7b87..6ac1e95 100644
--- a/ole/nls/nls.nls
+++ b/ole/nls/nls.nls
@@ -13,7 +13,7 @@
 /* LOCVAL(LOCALE_SENGCOUNTRY,"") */
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0413")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/non.nls b/ole/nls/non.nls
index 8b41d64..6ce9501 100644
--- a/ole/nls/non.nls
+++ b/ole/nls/non.nls
@@ -3,17 +3,17 @@
  *      Norway (Nynorsk)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0814")
 LOCVAL(LOCALE_SLANGUAGE,"Norwegian (Nynorsk)")
 LOCVAL(LOCALE_SENGLANGUAGE,"Norwegian")
 LOCVAL(LOCALE_SABBREVLANGNAME,"non")
 LOCVAL(LOCALE_SNATIVELANGNAME,"nynorsk")
 LOCVAL(LOCALE_ICOUNTRY,"47")
-/ LOCVAL(LOCALE_SCOUNTRY,"") */
+LOCVAL(LOCALE_SCOUNTRY,"Noreg")
 LOCVAL(LOCALE_SENGCOUNTRY,"Norway")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"NOR")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Noreg")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0814")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"47")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/nor.nls b/ole/nls/nor.nls
index f2355b1..5ebf266 100644
--- a/ole/nls/nor.nls
+++ b/ole/nls/nor.nls
@@ -4,7 +4,7 @@
  *	(Norwegian strings in iso-8859-1)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0414")
 LOCVAL(LOCALE_SLANGUAGE,"Norsk (Bokmål)")
 LOCVAL(LOCALE_SENGLANGUAGE,"Norwegian (Bokmaal)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"nor")
@@ -14,7 +14,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Norway")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"NOR")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Norge")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0414")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"47")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -43,10 +43,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/plk.nls b/ole/nls/plk.nls
index 9ce6f28..db7f747 100644
--- a/ole/nls/plk.nls
+++ b/ole/nls/plk.nls
@@ -4,7 +4,7 @@
  *	(Polish strings in iso-8859-2)
  */
         
-LOCVAL(LOCALE_ILANGUAGE,"9")
+LOCVAL(LOCALE_ILANGUAGE,"0x0415")
 LOCVAL(LOCALE_SLANGUAGE,"Polski")
 LOCVAL(LOCALE_SENGLANGUAGE,"Polish")
 LOCVAL(LOCALE_SABBREVLANGNAME, "plk")
@@ -14,7 +14,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Poland")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"PLZ")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Polska")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE,"9")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0415")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"49")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"1252")
 LOCVAL(LOCALE_IDEFAULTANSICODEPAGE,"1252")
diff --git a/ole/nls/ptb.nls b/ole/nls/ptb.nls
index 899116c..6c66668 100644
--- a/ole/nls/ptb.nls
+++ b/ole/nls/ptb.nls
@@ -3,7 +3,7 @@
  *      Brazil
  */
 
-LOCVAL(LOCALE_ILANGUAGE, "0416")
+LOCVAL(LOCALE_ILANGUAGE, "0x0416")
 LOCVAL(LOCALE_SLANGUAGE, "Portugu\352s (Brasil)")
 LOCVAL(LOCALE_SENGLANGUAGE, "Protuguese")
 LOCVAL(LOCALE_SABBREVLANGNAME, "ptb")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY, "Brazil")
 LOCVAL(LOCALE_SABBREVCTRYNAME, "BRA")
 LOCVAL(LOCALE_SNATIVECTRYNAME, "Brasil")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0409")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0x0416")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY, "55")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE, "850")
 LOCVAL(LOCALE_IDEFAULTANSICODEPAGE, "1252")
diff --git a/ole/nls/ptg.nls b/ole/nls/ptg.nls
index 98fa2e2..e15c26c 100644
--- a/ole/nls/ptg.nls
+++ b/ole/nls/ptg.nls
@@ -3,7 +3,7 @@
  *      Portugal
  */
 
-LOCVAL(LOCALE_ILANGUAGE, "0416")
+LOCVAL(LOCALE_ILANGUAGE, "0x0816")
 LOCVAL(LOCALE_SLANGUAGE, "Portugu\352s")
 LOCVAL(LOCALE_SENGLANGUAGE, "Protuguese")
 LOCVAL(LOCALE_SABBREVLANGNAME, "ptg")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY, "Portugal")
 LOCVAL(LOCALE_SABBREVCTRYNAME, "PTG")
 LOCVAL(LOCALE_SNATIVECTRYNAME, "Portugal")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0409")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0x0416")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY, "351")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE, "850")
 LOCVAL(LOCALE_IDEFAULTANSICODEPAGE, "1252")
diff --git a/ole/nls/rom.nls b/ole/nls/rom.nls
index a85d2cb..8eba4f1 100644
--- a/ole/nls/rom.nls
+++ b/ole/nls/rom.nls
@@ -4,7 +4,7 @@
  *	(Romanian strings in iso-8859-2)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0418")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
 LOCVAL(LOCALE_SENGLANGUAGE,"Romanian")
 LOCVAL(LOCALE_SABBREVLANGNAME,"rom")
@@ -14,7 +14,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Romania")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"ROM")
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0418")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"40")
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -43,10 +43,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/rus.nls b/ole/nls/rus.nls
index d5c2f63..e37d9aa 100644
--- a/ole/nls/rus.nls
+++ b/ole/nls/rus.nls
@@ -4,7 +4,7 @@
  *	(russian strings in koi8-r)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0419")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
 LOCVAL(LOCALE_SENGLANGUAGE,"Russian")
 LOCVAL(LOCALE_SABBREVLANGNAME,"rus")
@@ -43,10 +43,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/sky.nls b/ole/nls/sky.nls
index 90f7e05..9800f2f 100644
--- a/ole/nls/sky.nls
+++ b/ole/nls/sky.nls
@@ -4,7 +4,7 @@
  *	(Slovakian strings in iso-8859-2)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x041b")
 LOCVAL(LOCALE_SLANGUAGE,"Slovenèina")
 LOCVAL(LOCALE_SENGLANGUAGE,"Slovak")
 LOCVAL(LOCALE_SABBREVLANGNAME,"sky")
@@ -14,7 +14,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Slovakia")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Slovenská Republika")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x041b")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"895")
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -43,10 +43,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/slv.nls b/ole/nls/slv.nls
index dba39d9..e7e7311 100644
--- a/ole/nls/slv.nls
+++ b/ole/nls/slv.nls
@@ -4,7 +4,7 @@
  *	(Slovenian strings in iso-8859-2)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0424")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
 LOCVAL(LOCALE_SENGLANGUAGE,"Slovenian")
 LOCVAL(LOCALE_SABBREVLANGNAME,"slv")
@@ -14,7 +14,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Slovenia")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0424")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -43,10 +43,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/sqi.nls b/ole/nls/sqi.nls
index 411c719..e150f0c 100644
--- a/ole/nls/sqi.nls
+++ b/ole/nls/sqi.nls
@@ -3,17 +3,17 @@
  *      Albania
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x041c")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
 LOCVAL(LOCALE_SENGLANGUAGE,"Albanian")
 LOCVAL(LOCALE_SABBREVLANGNAME,"sqi")
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"Shqip?ria") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"Albania")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x041c")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/srb.nls b/ole/nls/srb.nls
index 16fd09e..aa75443 100644
--- a/ole/nls/srb.nls
+++ b/ole/nls/srb.nls
@@ -3,17 +3,17 @@
  *      Serbia
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0c1a")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
-/* LOCVAL(LOCALE_SENGLANGUAGE,"") */
+LOCVAL(LOCALE_SENGLANGUAGE,"Serbian (cyrillic)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"srb")
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"Yugoslavia")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0c1a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/srl.nls b/ole/nls/srl.nls
index ae4bb7d..8ba76af 100644
--- a/ole/nls/srl.nls
+++ b/ole/nls/srl.nls
@@ -3,17 +3,17 @@
  *      Serbian (Latin)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x081a")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
-/* LOCVAL(LOCALE_SENGLANGUAGE,"") */
+LOCVAL(LOCALE_SENGLANGUAGE,"Serbian (latin)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"srl")
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"Yugoslavia")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x081a")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/sve.nls b/ole/nls/sve.nls
index c076730..3d1d49f 100644
--- a/ole/nls/sve.nls
+++ b/ole/nls/sve.nls
@@ -3,7 +3,7 @@
  *      Sweden
  */
 
-LOCVAL(LOCALE_ILANGUAGE,"1d")
+LOCVAL(LOCALE_ILANGUAGE,"0x041d")
 LOCVAL(LOCALE_SLANGUAGE,"Svenska")
 LOCVAL(LOCALE_SENGLANGUAGE,"Swedish")
 LOCVAL(LOCALE_SABBREVLANGNAME,"sve")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Sweden")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"SVE")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Sverige")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE,"1d")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x041d")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"45")
 LOCVAL(LOCALE_IDEFAULTCODEPAGE,"850")
 LOCVAL(LOCALE_IDEFAULTANSICODEPAGE,"1252")
diff --git a/ole/nls/svf.nls b/ole/nls/svf.nls
index c517775..b0fa18d 100644
--- a/ole/nls/svf.nls
+++ b/ole/nls/svf.nls
@@ -3,7 +3,7 @@
  *      Finland (Swedish)
  */
 
-LOCVAL(LOCALE_ILANGUAGE,"1d")
+LOCVAL(LOCALE_ILANGUAGE,"0x081d")
 LOCVAL(LOCALE_SLANGUAGE,"Svenska")
 LOCVAL(LOCALE_SENGLANGUAGE,"Swedish (Finland)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"sve")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Finland")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"FIN")
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Finland")
-LOCVAL(LOCALE_IDEFAULTLANGUAGE,"1d")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x081d")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"45")
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
diff --git a/ole/nls/trk.nls b/ole/nls/trk.nls
index c1ceced..23dd65c 100644
--- a/ole/nls/trk.nls
+++ b/ole/nls/trk.nls
@@ -4,7 +4,7 @@
  *	(Turkish strings in iso-8859-9)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x041f")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
 LOCVAL(LOCALE_SENGLANGUAGE,"Turkish")
 LOCVAL(LOCALE_SABBREVLANGNAME,"trk")
@@ -14,7 +14,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Turkey")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Türkiye")
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x041f")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -43,10 +43,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/ukr.nls b/ole/nls/ukr.nls
index d2c27f3..68a7dce 100644
--- a/ole/nls/ukr.nls
+++ b/ole/nls/ukr.nls
@@ -3,7 +3,7 @@
  *      Ukrainian
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0422")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
 LOCVAL(LOCALE_SENGLANGUAGE,"Ukrainian")
 LOCVAL(LOCALE_SABBREVLANGNAME,"ukr")
@@ -13,7 +13,7 @@
 LOCVAL(LOCALE_SENGCOUNTRY,"Ukrainia")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0422")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/zhh.nls b/ole/nls/zhh.nls
index 65c8c63..582ac3b 100644
--- a/ole/nls/zhh.nls
+++ b/ole/nls/zhh.nls
@@ -3,17 +3,17 @@
  *      Chinese (Hong Kong)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0c04")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
 LOCVAL(LOCALE_SENGLANGUAGE,"Chinese (Hong Kong)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"zhh")
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"Hong Kong")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0404")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/nls/zhi.nls b/ole/nls/zhi.nls
index f427ef4..61275a7 100644
--- a/ole/nls/zhi.nls
+++ b/ole/nls/zhi.nls
@@ -3,17 +3,17 @@
  *      Chinese (Singapore)
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x1004")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
 LOCVAL(LOCALE_SENGLANGUAGE,"Chinese (Singapore)")
 LOCVAL(LOCALE_SABBREVLANGNAME,"zhi")
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"Singapore")
 LOCVAL(LOCALE_SABBREVCTRYNAME,"SGP")
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0404")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 LOCVAL(LOCALE_S1159, "AM")
diff --git a/ole/nls/zhs.nls b/ole/nls/zhs.nls
index 89fb2fe..87b273b 100644
--- a/ole/nls/zhs.nls
+++ b/ole/nls/zhs.nls
@@ -3,17 +3,17 @@
  *      People's republic of China
  */
 
-/* LOCVAL(LOCALE_ILANGUAGE,"") */
+LOCVAL(LOCALE_ILANGUAGE,"0x0804")
 /* LOCVAL(LOCALE_SLANGUAGE,"") */
-/* LOCVAL(LOCALE_SENGLANGUAGE,"People's republic of China") */
+/* LOCVAL(LOCALE_SENGLANGUAGE,"Chinese (People's republic of China") */
 LOCVAL(LOCALE_SABBREVLANGNAME,"zhs")
 /* LOCVAL(LOCALE_SNATIVELANGNAME,"") */
 /* LOCVAL(LOCALE_ICOUNTRY,"") */
 /* LOCVAL(LOCALE_SCOUNTRY,"") */
-/* LOCVAL(LOCALE_SENGCOUNTRY,"") */
+LOCVAL(LOCALE_SENGCOUNTRY,"People's republic of China")
 /* LOCVAL(LOCALE_SABBREVCTRYNAME,"") */
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"") */
-/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"") */
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"0x0404")
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"") */
 /* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
 /* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
@@ -42,10 +42,10 @@
 /* LOCVAL(LOCALE_STIMEFORMAT) */
 /* LOCVAL(LOCALE_IDATE,"1") */
 /* LOCVAL(LOCALE_ILDATE) */
-/* LOCVAL(LOCALE_ITIME,"1")
+LOCVAL(LOCALE_ITIME,"1")
 /* LOCVAL(LOCALE_ITIMEMARKPOSN) */
 /* LOCVAL(LOCALE_ICENTURY) */
-/* LOCVAL(LOCALE_ITLZERO,"1")
+LOCVAL(LOCALE_ITLZERO,"1")
 /* LOCVAL(LOCALE_IDAYLZERO) */
 /* LOCVAL(LOCALE_IMONLZERO) */
 /* LOCVAL(LOCALE_S1159, "") */
diff --git a/ole/ole2nls.c b/ole/ole2nls.c
index 4d97329b..a0ff37d 100644
--- a/ole/ole2nls.c
+++ b/ole/ole2nls.c
@@ -133,7 +133,161 @@
 	LCID		langid;
 	const char	*langname;
 } languages[]={
-	{0x0401,"Arabisch"},
+	{0x0401,"Arabic (Saudi Arabia)"},
+	{0x0801,"Arabic (Iraq)"},
+	{0x0c01,"Arabic (Egypt)"},
+	{0x1001,"Arabic (Libya)"},
+	{0x1401,"Arabic (Algeria)"},
+	{0x1801,"Arabic (Morocco)"},
+	{0x1c01,"Arabic (Tunisia)"},
+	{0x2001,"Arabic (Oman)"},
+	{0x2401,"Arabic (Yemen)"},
+	{0x2801,"Arabic (Syria)"},
+	{0x2c01,"Arabic (Jordan)"},
+	{0x3001,"Arabic (Lebanon)"},
+	{0x3401,"Arabic (Kuwait)"},
+	{0x3801,"Arabic (United Arab Emirates)"},
+	{0x3c01,"Arabic (Bahrain)"},
+	{0x4001,"Arabic (Qatar)"},
+	{0x0402,"Bulgarian"},
+	{0x0403,"Catalan"},
+	{0x0404,"Chinese (Taiwan)"},
+	{0x0804,"Chinese (People's Republic of China)"},
+	{0x0c04,"Chinese (Hong Kong)"},
+	{0x1004,"Chinese (Singapore)"},
+	{0x1404,"Chinese (Macau)"},
+	{0x0405,"Czech"},
+	{0x0406,"Danish"},
+	{0x0407,"German (Germany)"},
+	{0x0807,"German (Switzerland)"},
+	{0x0c07,"German (Austria)"},
+	{0x1007,"German (Luxembourg)"},
+	{0x1407,"German (Liechtenstein)"},
+	{0x0408,"Greek"},
+	{0x0409,"English (United States)"},
+	{0x0809,"English (United Kingdom)"},
+	{0x0c09,"English (Australia)"},
+	{0x1009,"English (Canada)"},
+	{0x1409,"English (New Zealand)"},
+	{0x1809,"English (Ireland)"},
+	{0x1c09,"English (South Africa)"},
+	{0x2009,"English (Jamaica)"},
+	{0x2409,"English (Caribbean)"},
+	{0x2809,"English (Belize)"},
+	{0x2c09,"English (Trinidad)"},
+	{0x3009,"English (Zimbabwe)"},
+	{0x3409,"English (Philippines)"},
+	{0x040a,"Spanish (Spain, traditional sorting)"},
+	{0x080a,"Spanish (Mexico)"},
+	{0x0c0a,"Spanish (Spain, international sorting)"},
+	{0x100a,"Spanish (Guatemala)"},
+	{0x140a,"Spanish (Costa Rica)"},
+	{0x180a,"Spanish (Panama)"},
+	{0x1c0a,"Spanish (Dominican Republic)"},
+	{0x200a,"Spanish (Venezuela)"},
+	{0x240a,"Spanish (Colombia)"},
+	{0x280a,"Spanish (Peru)"},
+	{0x2c0a,"Spanish (Argentina)"},
+	{0x300a,"Spanish (Ecuador)"},
+	{0x340a,"Spanish (Chile)"},
+	{0x380a,"Spanish (Uruguay)"},
+	{0x3c0a,"Spanish (Paraguay)"},
+	{0x400a,"Spanish (Bolivia)"},
+	{0x440a,"Spanish (El Salvador)"},
+	{0x480a,"Spanish (Honduras)"},
+	{0x4c0a,"Spanish (Nicaragua)"},
+	{0x500a,"Spanish (Puerto Rico)"},
+	{0x040b,"Finnish"},
+	{0x040c,"French (France)"},
+	{0x080c,"French (Belgium)"},
+	{0x0c0c,"French (Canada)"},
+	{0x100c,"French (Switzerland)"},
+	{0x140c,"French (Luxembourg)"},
+	{0x180c,"French (Monaco)"},
+	{0x040d,"Hebrew"},
+	{0x040e,"Hungarian"},
+	{0x040f,"Icelandic"},
+	{0x0410,"Italian (Italy)"},
+	{0x0810,"Italian (Switzerland)"},
+	{0x0411,"Japanese"},
+	{0x0412,"Korean (Wansung)"},
+	{0x0812,"Korean (Johab)"},
+	{0x0413,"Dutch (Netherlands)"},
+	{0x0813,"Dutch (Belgium)"},
+	{0x0414,"Norwegian (Bokmal)"},
+	{0x0814,"Norwegian (Nynorsk)"},
+	{0x0415,"Polish"},
+	{0x0416,"Portuguese (Brazil)"},
+	{0x0816,"Portuguese (Portugal)"},
+	{0x0417,"Rhaeto Romanic"},
+	{0x0418,"Romanian"},
+	{0x0818,"Moldavian"},
+	{0x0419,"Russian (Russia)"},
+	{0x0819,"Russian (Moldavia)"},
+	{0x041a,"Croatian"},
+	{0x081a,"Serbian (latin)"},
+	{0x0c1a,"Serbian (cyrillic)"},
+	{0x041b,"Slovak"},
+	{0x041c,"Albanian"},
+	{0x041d,"Swedish (Sweden)"},
+	{0x081d,"Swedish (Finland)"},
+	{0x041e,"Thai"},
+	{0x041f,"Turkish"},
+	{0x0420,"Urdu"},
+	{0x0421,"Indonesian"},
+	{0x0422,"Ukrainian"},
+	{0x0423,"Belarusian"},
+	{0x0424,"Slovene"},
+	{0x0425,"Estonian"},
+	{0x0426,"Latvian"},
+	{0x0427,"Lithuanian (modern)"},
+	{0x0827,"Lithuanian (classic)"},
+	{0x0428,"Maori"},
+	{0x0429,"Farsi"},
+	{0x042a,"Vietnamese"},
+	{0x042b,"Armenian"},
+	{0x042c,"Azeri (latin)"},
+	{0x082c,"Azeri (cyrillic)"},
+	{0x042d,"Basque"},
+	{0x042e,"Sorbian"},
+	{0x042f,"Macedonian"},
+	{0x0430,"Sutu"},
+	{0x0431,"Tsonga"},
+	{0x0432,"Tswana"},
+	{0x0433,"Venda"},
+	{0x0434,"Xhosa"},
+	{0x0435,"Zulu"},
+	{0x0436,"Afrikaans"},
+	{0x0437,"Georgian"},
+	{0x0438,"Faeroese"},
+	{0x0439,"Hindi"},
+	{0x043a,"Maltese"},
+	{0x043b,"Saami"},
+	{0x043c,"Irish gaelic"},
+	{0x083c,"Scottish gaelic"},
+	{0x043e,"Malay (Malaysia)"},
+	{0x083e,"Malay (Brunei Darussalam)"},
+	{0x043f,"Kazak"},
+	{0x0441,"Swahili"},
+	{0x0443,"Uzbek (latin)"},
+	{0x0843,"Uzbek (cyrillic)"},
+	{0x0444,"Tatar"},
+	{0x0445,"Bengali"},
+	{0x0446,"Punjabi"},
+	{0x0447,"Gujarati"},
+	{0x0448,"Oriya"},
+	{0x0449,"Tamil"},
+	{0x044a,"Telugu"},
+	{0x044b,"Kannada"},
+	{0x044c,"Malayalam"},
+	{0x044d,"Assamese"},
+	{0x044e,"Marathi"},
+	{0x044f,"Sanskrit"},
+	{0x0457,"Konkani"},
+	{0x048f,"Esperanto"}, /* Non official */
+	{0x0000,"Unknown"}
+    }, languages_de[]={
+	{0x0401,"Arabic"},
 	{0x0402,"Bulgarisch"},
 	{0x0403,"Katalanisch"},
 	{0x0404,"Traditionales Chinesisch"},
@@ -163,7 +317,7 @@
 	{0x041C,"Albanisch"},
 	{0x041D,"Schwedisch"},
 	{0x041E,"Thai"},
-	{0x041F,"T|rkisch"},
+	{0x041F,"Türkisch"},
 	{0x0420,"Urdu"},
 	{0x0421,"Bahasa"},
 	{0x0804,"Vereinfachtes Chinesisch"},
@@ -187,36 +341,87 @@
 LCID WINAPI GetUserDefaultLCID()
 {
 /* Default sorting, neutral sublanguage */
+/* language names following ISO 639 (rfc 1766) */
     switch(Options.language)
     {
+ /* case LANG_Ar: return 0x01; */      /* Arabic */
  /* case LANG_Bu: return 0x02; */      /* Bulgarian */
- /* case LANG_Ch: return 0x04; */      /* Chinese */
-    case LANG_Cz: return 0x05;         /* Czech */
+    case LANG_Ca: return 0x03;         /* Catalan */
+ /* case LANG_Zh: return 0x04; */      /* Chinese */
+    case LANG_Cs: return 0x05;         /* Czech */
     case LANG_Da: return 0x06;         /* Danish */
     case LANG_De: return 0x07;         /* German */
- /* case LANG_Gr: return 0x08; */      /* Greek */
+ /* case LANG_El: return 0x08; */      /* Greek */
     case LANG_En: return 0x09;         /* English */
     case LANG_Es: return 0x0a;         /* Spanish */
     case LANG_Fi: return 0x0b;         /* Finnish */
     case LANG_Fr: return 0x0c;         /* French */
+ /* case LANG_Iw: return 0x0d; */      /* Hebrew */
     case LANG_Hu: return 0x0e;         /* Hungarian */
  /* case LANG_Ic: return 0x0f; */      /* Icelandic */
     case LANG_It: return 0x10;         /* Italian */
- /* case LANG_Jp: return 0x11; */      /* Japanese */
+ /* case LANG_Ja: return 0x11; */      /* Japanese */
     case LANG_Ko: return 0x12;         /* Korean */
- /* case LANG_Du: return 0x13; */      /* Dutch */
+ /* case LANG_Nl: return 0x13; */      /* Dutch */
     case LANG_No: return 0x14;         /* Norwegian */
     case LANG_Pl: return 0x15;         /* Polish */
-    case LANG_Po: return 0x16;         /* Portuguese */
+    case LANG_Pt: return 0x16;         /* Portuguese */
+ /* case LANG_Rm: return 0x17; */      /* Rhaeto-romance */   
  /* case LANG_Ro: return 0x18; */      /* Romanian */
  /* case LANG_Ru: return 0x19; */      /* Russian */
- /* case LANG_Cr: return 0x1a; */      /* Croatian */
- /* case LANG_Sl: return 0x1b; */      /* Slovak */
-    case LANG_Sw: return 0x1d;         /* Swedish */
- /* case LANG_Tu: return 0x1f; */      /* Turkish */
- /* case LANG_Sv: return 0x24; */      /* Slovenian */
-    case LANG_Eo: return 0x25;         /* Esperanto (not official) */
-    case LANG_Ca: return 0x26;         /* Catalan */
+ /* case LANG_Hr: return 0x1a; */      /* Croatian */
+ /* case LANG_Sk: return 0x1b; */      /* Slovak */
+ /* case LANG_Sq: return 0x1c; */      /* Albanian */
+    case LANG_Sv: return 0x1d;         /* Swedish */
+ /* case LANG_Th: return 0x1e; */      /* Thai */
+ /* case LANG_Tr: return 0x1f; */      /* Turkish */
+ /* case LANG_Ur: return 0x20; */      /* Urdu */
+ /* case LANG_In: return 0x21; */      /* Indonesian */
+ /* case LANG_Uk: return 0x22; */      /* Ukrainian */
+ /* case LANG_Be: return 0x23; */      /* Belarusian */
+ /* case LANG_Sl: return 0x24; */      /* Slovenian */
+ /* case LANG_Et: return 0x25; */      /* Estonian */
+ /* case LANG_Lv: return 0x26; */      /* Latvian */
+ /* case LANG_Lt: return 0x27; */      /* Lithuanian */
+ /* case LANG_Mi: return 0x28; */      /* Maori */
+ /* case LANG_Fa: return 0x29; */      /* Farsi */
+ /* case LANG_Vi: return 0x2a; */      /* Vietnamese */
+ /* case LANG_Hy: return 0x2b; */      /* Armenian */
+ /* case LANG_Az: return 0x2c; */      /* Azeri */
+ /* case LANG_Eu: return 0x2d; */      /* Basque */
+ /* case LANG_??: return 0x2e; */      /* Sorbian */
+ /* case LANG_Mk: return 0x2f; */      /* Macedonian */
+ /* case LANG_??: return 0x30; */      /* Sutu */
+ /* case LANG_Ts: return 0x31; */      /* Tsonga */
+ /* case LANG_??: return 0x32; */      /* Tswana */
+ /* case LANG_??: return 0x33; */      /* Venda */
+ /* case LANG_Xh: return 0x34; */      /* Xhosa */
+ /* case LANG_Zu: return 0x35; */      /* Zulu */
+ /* case LANG_Af: return 0x36; */      /* Afrikaans */
+ /* case LANG_Ka: return 0x37; */      /* Georgian */
+ /* case LANG_Fo: return 0x38; */      /* Faeroese */
+ /* case LANG_Hi: return 0x39; */      /* Hindi */
+ /* case LANG_Mt: return 0x3a; */      /* Maltese */
+ /* case LANG_??: return 0x3b; */      /* Saami */
+ /* case LANG_Ga: return 0x3c; */      /* Gaelic */
+ /* case LANG_Ms: return 0x3e; */      /* Malay */
+ /* case LANG_Kk: return 0x3f; */      /* Kazakh */
+ /* case LANG_Sw: return 0x41; */      /* Swahili */
+ /* case LANG_Uz: return 0x43; */      /* Uzbek */
+ /* case LANG_Tt: return 0x44; */      /* Tatar */
+ /* case LANG_Bn: return 0x45; */      /* Bengali */
+ /* case LANG_Pa: return 0x46; */      /* Punjabi */
+ /* case LANG_Gu: return 0x47; */      /* Gujarati */
+ /* case LANG_Or: return 0x48; */      /* Oriya */
+ /* case LANG_Ta: return 0x49; */      /* Tamil */
+ /* case LANG_Te: return 0x4a; */      /* Telugu */
+ /* case LANG_Kn: return 0x4b; */      /* Kannada */
+ /* case LANG_Ml: return 0x4c; */      /* Malayalam */
+ /* case LANG_As: return 0x4d; */      /* Assamese */
+ /* case LANG_Mr: return 0x4e; */      /* Marathi */
+ /* case LANG_Sa: return 0x4f; */      /* Sanskrit */
+ /* case LANG_??: return 0x57; */      /* Konkani */
+    case LANG_Eo: return 0x8f;         /* Esperanto (not official number) */
 
     default:
 	return 0x00;                   /* Neutral language */
@@ -362,19 +567,19 @@
 	}
     break;  /* LANG(Pl) */
 
-    case LANG_Po:
+    case LANG_Pt:
     	switch (LCType) {
 #include "nls/ptb.nls"
 	default: found=0;break;
 	}
-    break; /* LANG(Po) */
+    break; /* LANG(Pt) */
 
-    case LANG_Sw:
+    case LANG_Sv:
     	switch (LCType) {
 #include "nls/sve.nls"
 	default: found=0;break;
 	}
-    break; /* LANG(Sw) */
+    break; /* LANG(Sv) */
 
 /*Insert other languages here*/
 
@@ -2553,6 +2758,91 @@
    
 }
 
+/**************************************************************************
+ *              EnumDateFormats32A	(KERNEL32.198)
+ */
+BOOL32 WINAPI EnumDateFormats32A(
+  DATEFMT_ENUMPROC32A lpDateFmtEnumProc, LCID Locale,  DWORD dwFlags)
+{
+  FIXME(ole, "Only US English supported\n");
+
+  if(!lpDateFmtEnumProc)
+    {
+      SetLastError(ERROR_INVALID_PARAMETER);
+      return FALSE;
+    }
+
+  switch(dwFlags)
+    {
+      case DATE_SHORTDATE:
+	if(!(*lpDateFmtEnumProc)("M/d/yy")) return TRUE;
+	if(!(*lpDateFmtEnumProc)("M/d/yyyy")) return TRUE;
+	if(!(*lpDateFmtEnumProc)("MM/dd/yy")) return TRUE;
+	if(!(*lpDateFmtEnumProc)("MM/dd/yyyy")) return TRUE;
+	if(!(*lpDateFmtEnumProc)("yy/MM/dd")) return TRUE;
+	if(!(*lpDateFmtEnumProc)("dd-MMM-yy")) return TRUE;
+	return TRUE;
+      case DATE_LONGDATE:
+        if(!(*lpDateFmtEnumProc)("dddd, MMMM dd, yyyy")) return TRUE;
+        if(!(*lpDateFmtEnumProc)("MMMM dd, yyyy")) return TRUE;
+        if(!(*lpDateFmtEnumProc)("dddd, dd MMMM, yyyy")) return TRUE;
+        if(!(*lpDateFmtEnumProc)("dd MMMM, yyyy")) return TRUE;
+	return TRUE;
+      default:
+	FIXME(ole, "Unknown date format (%ld)\n", dwFlags); 
+	SetLastError(ERROR_INVALID_PARAMETER);
+	return FALSE;
+    }
+}
+
+/**************************************************************************
+ *              EnumDateFormats32W	(KERNEL32.199)
+ */
+BOOL32 WINAPI EnumDateFormats32W(
+  DATEFMT_ENUMPROC32W lpDateFmtEnumProc, LCID Locale, DWORD dwFlags)
+{
+  FIXME(ole, "(%p, %ld, %ld): stub\n", lpDateFmtEnumProc, Locale, dwFlags);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+/**************************************************************************
+ *              EnumTimeFormats32A	(KERNEL32.210)
+ */
+BOOL32 WINAPI EnumTimeFormats32A(
+  TIMEFMT_ENUMPROC32A lpTimeFmtEnumProc, LCID Locale, DWORD dwFlags)
+{
+  FIXME(ole, "Only US English supported\n");
+
+  if(!lpTimeFmtEnumProc)
+    {
+      SetLastError(ERROR_INVALID_PARAMETER);
+      return FALSE;
+    }
+
+  if(dwFlags)
+    {
+      FIXME(ole, "Unknown time format (%ld)\n", dwFlags); 
+    }
+  
+  if(!(*lpTimeFmtEnumProc)("h:mm:ss tt")) return TRUE;
+  if(!(*lpTimeFmtEnumProc)("hh:mm:ss tt")) return TRUE;
+  if(!(*lpTimeFmtEnumProc)("H:mm:ss")) return TRUE;
+  if(!(*lpTimeFmtEnumProc)("HH:mm:ss")) return TRUE;
+
+  return TRUE;
+}
+
+/**************************************************************************
+ *              EnumTimeFormats32W	(KERNEL32.211)
+ */
+BOOL32 WINAPI EnumTimeFormats32W(
+  TIMEFMT_ENUMPROC32W lpTimeFmtEnumProc, LCID Locale, DWORD dwFlags)
+{
+  FIXME(ole, "(%p,%ld,%ld): stub", lpTimeFmtEnumProc, Locale, dwFlags);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
 
 /**************************************************************************
  *              GetNumberFormat32A	(KERNEL32.355)
diff --git a/ole/oledlg.c b/ole/oledlg.c
index 51d6051..8b010f2 100644
--- a/ole/oledlg.c
+++ b/ole/oledlg.c
@@ -15,16 +15,15 @@
 /***********************************************************************
  *           OleUIAddVerbMenu32A (OLEDLG.1)
  */
-
 BOOL32 WINAPI OleUIAddVerbMenu32A(
-    LPOLEOBJECT lpOleObj, LPCSTR lpszShortType,
-    HMENU32 hMenu, UINT32 uPos, UINT32 uIDVerbMin, UINT32 uIDVerbMax,
-    BOOL32 bAddConvert, UINT32 idConvert, HMENU32 *lphMenu)
+  LPOLEOBJECT lpOleObj, LPCSTR lpszShortType,
+  HMENU32 hMenu, UINT32 uPos, UINT32 uIDVerbMin, UINT32 uIDVerbMax,
+  BOOL32 bAddConvert, UINT32 idConvert, HMENU32 *lphMenu)
 {
-  FIXME(ole,"(%p,%s,0x%08x,%d,%d,%d,%d,%d,%p): stub\n",
-	lpOleObj, lpszShortType,
-        hMenu, uPos, uIDVerbMin, uIDVerbMax,
-        bAddConvert, idConvert, lphMenu
+  FIXME(ole, "(%p, %s, 0x%08x, %d, %d, %d, %d, %d, %p): stub\n",
+    lpOleObj, debugstr_a(lpszShortType),
+    hMenu, uPos, uIDVerbMin, uIDVerbMax,
+    bAddConvert, idConvert, lphMenu
   );
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
@@ -33,16 +32,15 @@
 /***********************************************************************
  *           OleUIAddVerbMenu32W (OLEDLG.14)
  */
-
 BOOL32 WINAPI OleUIAddVerbMenu32W(
-    LPOLEOBJECT lpOleObj, LPCWSTR lpszShortType,
-    HMENU32 hMenu, UINT32 uPos, UINT32 uIDVerbMin, UINT32 uIDVerbMax,
-    BOOL32 bAddConvert, UINT32 idConvert, HMENU32 *lphMenu)
+  LPOLEOBJECT lpOleObj, LPCWSTR lpszShortType,
+  HMENU32 hMenu, UINT32 uPos, UINT32 uIDVerbMin, UINT32 uIDVerbMax,
+  BOOL32 bAddConvert, UINT32 idConvert, HMENU32 *lphMenu)
 {
-  FIXME(ole,"(%p,%s,0x%08x,%d,%d,%d,%d,%d,%p): stub\n",
-	lpOleObj, lpszShortType,
-        hMenu, uPos, uIDVerbMin, uIDVerbMax,
-        bAddConvert, idConvert, lphMenu
+  FIXME(ole, "(%p, %s, 0x%08x, %d, %d, %d, %d, %d, %p): stub\n",
+    lpOleObj, debugstr_w(lpszShortType),
+    hMenu, uPos, uIDVerbMin, uIDVerbMax,
+    bAddConvert, idConvert, lphMenu
   );
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
@@ -51,11 +49,12 @@
 /***********************************************************************
  *           OleUICanConvertOrActivateAs32 (OLEDLG.2)
  */
-
 BOOL32 WINAPI OleUICanConvertOrActivateAs32(
     REFCLSID rClsid, BOOL32 fIsLinkedObject, WORD wFormat)
 {
-  FIXME(ole,"stub\n");
+  FIXME(ole, "(%p, %d, %hd): stub\n",
+    rClsid, fIsLinkedObject, wFormat
+  );
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -63,10 +62,9 @@
 /***********************************************************************
  *           OleUIInsertObject32A (OLEDLG.3)
  */
-
-UINT32 WINAPI OleUIInsertObject32A(LPOLEUIINSERTOBJECTA lpOleUIInsertObject)
+UINT32 WINAPI OleUIInsertObject32A(LPOLEUIINSERTOBJECT32A lpOleUIInsertObject)
 {
-  FIXME(ole,"(%p): stub\n",lpOleUIInsertObject);
+  FIXME(ole, "(%p): stub\n", lpOleUIInsertObject);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return OLEUI_FALSE;
 }
@@ -74,10 +72,9 @@
 /***********************************************************************
  *           OleUIInsertObject32W (OLEDLG.20)
  */
-
-UINT32 WINAPI OleUIInsertObject32W(LPOLEUIINSERTOBJECTW lpOleUIInsertObject)
+UINT32 WINAPI OleUIInsertObject32W(LPOLEUIINSERTOBJECT32W lpOleUIInsertObject)
 {
-  FIXME(ole,"(%p): stub\n",lpOleUIInsertObject);
+  FIXME(ole, "(%p): stub\n", lpOleUIInsertObject);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return OLEUI_FALSE;
 }
@@ -85,10 +82,9 @@
 /***********************************************************************
  *           OleUIPasteSpecial32A (OLEDLG.4)
  */
-
-UINT32 WINAPI OleUIPasteSpecial32A(LPOLEUIPASTESPECIALA lpOleUIPasteSpecial)
+UINT32 WINAPI OleUIPasteSpecial32A(LPOLEUIPASTESPECIAL32A lpOleUIPasteSpecial)
 {
-  FIXME(ole,"(%p): stub\n",lpOleUIPasteSpecial);
+  FIXME(ole, "(%p): stub\n", lpOleUIPasteSpecial);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return OLEUI_FALSE;
 }
@@ -96,10 +92,9 @@
 /***********************************************************************
  *           OleUIPasteSpecial32W (OLEDLG.22)
  */
-
-UINT32 WINAPI OleUIPasteSpecial32W(LPOLEUIPASTESPECIALW lpOleUIPasteSpecial)
+UINT32 WINAPI OleUIPasteSpecial32W(LPOLEUIPASTESPECIAL32W lpOleUIPasteSpecial)
 {
-  FIXME(ole,"(%p): stub\n",lpOleUIPasteSpecial);
+  FIXME(ole, "(%p): stub\n", lpOleUIPasteSpecial);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return OLEUI_FALSE;
 }
@@ -107,10 +102,9 @@
 /***********************************************************************
  *           OleUIEditLinks32A (OLEDLG.5)
  */
-
-UINT32 WINAPI OleUIEditLinks32A(LPOLEUIEDITLINKSA lpOleUIEditLinks)
+UINT32 WINAPI OleUIEditLinks32A(LPOLEUIEDITLINKS32A lpOleUIEditLinks)
 {
-  FIXME(ole,"(%p): stub\n",lpOleUIEditLinks);
+  FIXME(ole, "(%p): stub\n", lpOleUIEditLinks);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return OLEUI_FALSE;
 }
@@ -118,10 +112,9 @@
 /***********************************************************************
  *           OleUIEditLinks32W (OLEDLG.19)
  */
-
-UINT32 WINAPI OleUIEditLinks32W(LPOLEUIEDITLINKSW lpOleUIEditLinks)
+UINT32 WINAPI OleUIEditLinks32W(LPOLEUIEDITLINKS32W lpOleUIEditLinks)
 {
-  FIXME(ole,"(%p): stub\n",lpOleUIEditLinks);
+  FIXME(ole, "(%p): stub\n", lpOleUIEditLinks);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return OLEUI_FALSE;
 }
@@ -129,10 +122,10 @@
 /***********************************************************************
  *           OleUIChangeIcon32A (OLEDLG.6)
  */
-
-UINT32 WINAPI OleUIChangeIcon32A(LPOLEUICHANGEICONA lpOleUIChangeIcon)
+UINT32 WINAPI OleUIChangeIcon32A(
+  LPOLEUICHANGEICON32A lpOleUIChangeIcon)
 {
-  FIXME(ole,"(%p): stub\n",lpOleUIChangeIcon);
+  FIXME(ole, "(%p): stub\n", lpOleUIChangeIcon);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return OLEUI_FALSE;
 }
@@ -140,10 +133,10 @@
 /***********************************************************************
  *           OleUIChangeIcon32W (OLEDLG.16)
  */
-
-UINT32 WINAPI OleUIChangeIcon32W(LPOLEUICHANGEICONW lpOleUIChangeIcon)
+UINT32 WINAPI OleUIChangeIcon32W(
+  LPOLEUICHANGEICON32W lpOleUIChangeIcon)
 {
-  FIXME(ole,"(%p): stub\n",lpOleUIChangeIcon);
+  FIXME(ole, "(%p): stub\n", lpOleUIChangeIcon);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return OLEUI_FALSE;
 }
@@ -151,10 +144,9 @@
 /***********************************************************************
  *           OleUIConvert32A (OLEDLG.7)
  */
-
-UINT32 WINAPI OleUIConvert32A(LPOLEUICONVERTA lpOleUIConvert)
+UINT32 WINAPI OleUIConvert32A(LPOLEUICONVERT32A lpOleUIConvert)
 {
-  FIXME(ole,"(%p): stub\n",lpOleUIConvert);
+  FIXME(ole, "(%p): stub\n", lpOleUIConvert);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return OLEUI_FALSE;
 }
@@ -162,10 +154,9 @@
 /***********************************************************************
  *           OleUIConvert32W (OLEDLG.18)
  */
-
-UINT32 WINAPI OleUIConvert32W(LPOLEUICONVERTW lpOleUIConvert)
+UINT32 WINAPI OleUIConvert32W(LPOLEUICONVERT32W lpOleUIConvert)
 {
-  FIXME(ole,"(%p): stub\n",lpOleUIConvert);
+  FIXME(ole, "(%p): stub\n", lpOleUIConvert);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return OLEUI_FALSE;
 }
@@ -173,10 +164,9 @@
 /***********************************************************************
  *           OleUIBusy32A (OLEDLG.8)
  */
-
-UINT32 WINAPI OleUIBusy32A(LPOLEUIBUSYA lpOleUIBusy)
+UINT32 WINAPI OleUIBusy32A(LPOLEUIBUSY32A lpOleUIBusy)
 {
-  FIXME(ole,"(%p): stub\n",lpOleUIBusy);
+  FIXME(ole, "(%p): stub\n", lpOleUIBusy);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return OLEUI_FALSE;
 }
@@ -184,10 +174,9 @@
 /***********************************************************************
  *           OleUIBusy32W (OLEDLG.15)
  */
-
-UINT32 WINAPI OleUIBusy32W(LPOLEUIBUSYW lpOleUIBusy)
+UINT32 WINAPI OleUIBusy32W(LPOLEUIBUSY32W lpOleUIBusy)
 {
-  FIXME(ole,"(%p): stub\n",lpOleUIBusy);
+  FIXME(ole, "(%p): stub\n", lpOleUIBusy);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return OLEUI_FALSE;
 }
@@ -195,13 +184,13 @@
 /***********************************************************************
  *           OleUIUpdateLinks32A (OLEDLG.9)
  */
-
 BOOL32 WINAPI OleUIUpdateLinks32A(
-    LPOLEUILINKCONTAINERA lpOleUILinkCntr,
-    HWND32 hwndParent, LPSTR lpszTitle, INT32 cLinks)
+  LPOLEUILINKCONTAINER32A lpOleUILinkCntr,
+  HWND32 hwndParent, LPSTR lpszTitle, INT32 cLinks)
 {
-  FIXME(ole,"(%p,0x%08x,%s,%d): stub\n",
-	lpOleUILinkCntr,hwndParent,lpszTitle, cLinks);
+  FIXME(ole,"(%p, 0x%08x, %s, %d): stub\n",
+    lpOleUILinkCntr, hwndParent, debugstr_a(lpszTitle), cLinks
+  );
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -212,12 +201,13 @@
  *     I haven't been able to find the ordinal for this function,
  *     This means it can't be called from outside the DLL.
  */
-
 BOOL32 WINAPI OleUIUpdateLinks32W(
-    LPOLEUILINKCONTAINERW lpOleUILinkCntr,
-    HWND32 hwndParent, LPWSTR lpszTitle, INT32 cLinks)
+  LPOLEUILINKCONTAINER32W lpOleUILinkCntr,
+  HWND32 hwndParent, LPWSTR lpszTitle, INT32 cLinks)
 {
-  FIXME(ole,"(%p,0x%08x,%s,%d): stub\n",lpOleUILinkCntr,hwndParent,lpszTitle, cLinks);
+  FIXME(ole, "(%p, 0x%08x, %s, %d): stub\n",
+    lpOleUILinkCntr, hwndParent, debugstr_w(lpszTitle), cLinks
+  );
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -225,10 +215,10 @@
 /***********************************************************************
  *           OleUIPromptUser32A (OLEDLG.10)
  */
-
-INT32 __cdecl OleUIPromptUser32A(INT32 nTemplate, HWND32 hwndParent, ...)
+INT32 __cdecl OleUIPromptUser32A(
+  INT32 nTemplate, HWND32 hwndParent, ...)
 {
-  FIXME(ole,"(%d,0x%08x,...): stub\n",nTemplate,hwndParent);
+  FIXME(ole, "(%d, 0x%08x, ...): stub\n", nTemplate, hwndParent);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return OLEUI_FALSE;
 }
@@ -236,10 +226,10 @@
 /***********************************************************************
  *           OleUIPromptUser32W (OLEDLG.13)
  */
-
-INT32 __cdecl OleUIPromptUser32W(INT32 nTemplate, HWND32 hwndParent, ...)
+INT32 __cdecl OleUIPromptUser32W(
+  INT32 nTemplate, HWND32 hwndParent, ...)
 {
-  FIXME(ole,"(%d,0x%08x,...): stub\n",nTemplate,hwndParent);
+  FIXME(ole, "(%d, 0x%08x, ...): stub\n", nTemplate, hwndParent);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return OLEUI_FALSE;
 }
@@ -247,10 +237,10 @@
 /***********************************************************************
  *           OleUIObjectProperties32A (OLEDLG.11)
  */
-
-UINT32 WINAPI OleUIObjectProperties32A(LPOLEUIOBJECTPROPSA lpOleUIObjectProps)
+UINT32 WINAPI OleUIObjectProperties32A(
+  LPOLEUIOBJECTPROPS32A lpOleUIObjectProps)
 {
-  FIXME(ole,"(%p): stub\n",lpOleUIObjectProps);
+  FIXME(ole, "(%p): stub\n", lpOleUIObjectProps);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return OLEUI_FALSE;
 }
@@ -258,10 +248,10 @@
 /***********************************************************************
  *           OleUIObjectProperties32W (OLEDLG.21)
  */
-
-UINT32 WINAPI OleUIObjectProperties32W(LPOLEUIOBJECTPROPSW lpOleUIObjectProps)
+UINT32 WINAPI OleUIObjectProperties32W(
+  LPOLEUIOBJECTPROPS32W lpOleUIObjectProps)
 {
-  FIXME(ole,"(%p): stub\n",lpOleUIObjectProps);
+  FIXME(ole, "(%p): stub\n", lpOleUIObjectProps);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return OLEUI_FALSE;
 }
@@ -269,10 +259,10 @@
 /***********************************************************************
  *           OleUIChangeSource32A (OLEDLG.12)
  */
-
-UINT32 OleUIChangeSource32A(LPOLEUICHANGESOURCEA lpOleUIChangeSource)
+UINT32 WINAPI OleUIChangeSource32A(
+  LPOLEUICHANGESOURCE32A lpOleUIChangeSource)
 {
-  FIXME(ole,"(%p): stub\n",lpOleUIChangeSource);
+  FIXME(ole, "(%p): stub\n", lpOleUIChangeSource);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return OLEUI_FALSE;
 }
@@ -280,10 +270,10 @@
 /***********************************************************************
  *           OleUIChangeSource32W (OLEDLG.17)
  */
-
-UINT32 OleUIChangeSource32W(LPOLEUICHANGESOURCEW lpOleUIChangeSource)
+UINT32 WINAPI OleUIChangeSource32W(
+  LPOLEUICHANGESOURCE32W lpOleUIChangeSource)
 {
-  FIXME(ole,"(%p): stub\n",lpOleUIChangeSource);
+  FIXME(ole, "(%p): stub\n", lpOleUIChangeSource);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return OLEUI_FALSE;
 }
diff --git a/programs/Makefile.in b/programs/Makefile.in
index 686f5b3..3d498e7 100644
--- a/programs/Makefile.in
+++ b/programs/Makefile.in
@@ -1,5 +1,6 @@
 SUBDIRS = \
 	clock \
+	control \
 	notepad \
 	progman \
 	regtest \
diff --git a/programs/control/Makefile.in b/programs/control/Makefile.in
new file mode 100644
index 0000000..07c4118
--- /dev/null
+++ b/programs/control/Makefile.in
@@ -0,0 +1,27 @@
+DEFS      = -DWINELIB
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+MODULE    = none
+PROGRAMS  = control
+ALL_LIBS  = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS)
+
+C_SRCS = control.c
+
+all: $(PROGRAMS)
+
+@MAKE_RULES@
+
+control: $(OBJS)
+	$(CC) -o control $(OBJS) $(LDOPTIONS) $(ALL_LIBS)
+
+install: dummy
+	$(INSTALL_PROGRAM) control $(bindir)/control
+
+uninstall: dummy
+	$(RM) $(bindir)/control
+
+dummy:
+
+### Dependencies:
diff --git a/programs/control/control.c b/programs/control/control.c
new file mode 100644
index 0000000..ddee0b1
--- /dev/null
+++ b/programs/control/control.c
@@ -0,0 +1,53 @@
+/* 
+ *   Control
+ *   Copyright (C) 1998 by Marcel Baur <mbaur@g26.ethz.ch>
+ *   To be distributed under the Wine license
+ */
+
+#include <win.h>
+#include <shell.h>
+#include "params.h"
+
+void launch(char what[255])
+{ 
+  HINSTANCE hChild;
+  char szArgs[255];
+
+  lstrcpy(szArgs, szEXEC_ARGS);
+  strcat(szArgs, what);
+
+  hChild = ShellExecute((HWND)0, 0, szEXEC_PREFIX, szArgs, "", SW_SHOWNORMAL);
+  exit(0);
+}
+
+int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, CHAR *szParam, INT argc) 
+{
+
+  char szParams[255];
+  lstrcpy(szParams, szParam);
+  CharUpper(szParams);
+
+  switch (argc) {
+    case 0:  /* no parameters - pop up whole "Control Panel" by default */
+             launch("");
+             break;
+
+    case 1:  /* check for optional parameter */
+             if (strcmp(szParams,szP_DESKTOP)      ==0) launch(szC_DESKTOP);
+             if (strcmp(szParams,szP_COLOR)        ==0) launch(szC_COLOR);
+             if (strcmp(szParams,szP_DATETIME)     ==0) launch(szC_DATETIME);
+             if (strcmp(szParams,szP_DESKTOP)      ==0) launch(szC_DESKTOP);
+             if (strcmp(szParams,szP_INTERNATIONAL)==0) launch(szC_INTERNATIONAL);
+             if (strcmp(szParams,szP_KEYBOARD)     ==0) launch(szC_KEYBOARD);
+             if (strcmp(szParams,szP_MOUSE)        ==0) launch(szC_MOUSE);
+             if (strcmp(szParams,szP_PORTS)        ==0) launch(szC_PORTS);
+             if (strcmp(szParams,szP_PRINTERS)     ==0) launch(szC_PRINTERS);
+
+             /* couldn't recognize desired panel, going default mode */
+             launch("");
+             break;
+
+    default: printf("Syntax error.");
+  }
+  return 0;  
+}
diff --git a/programs/control/cpl_list b/programs/control/cpl_list
new file mode 100644
index 0000000..a4dc938
--- /dev/null
+++ b/programs/control/cpl_list
@@ -0,0 +1,66 @@
+
+Alphabetical List of Windows 95 Control Panels
+----------------------------------------------
+
+Filename       Description
+
+APPWIZ.CPL     Software Properties
+DESK.CPL       Desktop Properties
+               ,,0 - Background Properties
+               ,,1 - Screen Saver Properties
+               ,,2 - Color Properties
+INETCPL.CPL    Internet Properties (does not take arguments)
+INTL.CPL       Internation Country/Timezone Properties
+               ,,0 - Country-specific settings
+               ,,1 - Numbers
+               ,,2 - Currency
+               ,,3 - Clock
+               ,,4 - Date
+JOY.CPL        Joystick Properties
+MAIN.CPL       @0   - Mouse Buttons Properties 
+               @1   - Keyboard Speed Properties
+               @1,1 - Keyboard Language Properties
+               @1,2 - Keyboard General Properties
+               @2   - Printer
+               @3   - Fonts
+               @4   - Energy
+MMSYS.CPL      Multimedia Properties
+               ,,0  - Audio
+               ,,1  - Video
+               ,,2  - MIDI
+               ,,3  - Audio CD
+               ,,4  - Extended (Multimedia drivers)
+MODEM.CPL      Modem Properties (does not take parameters)
+MSWEBCPL.CPL   Personal WebServer Properties (comes with Win95 4.0B) 
+               (does not take parameters)
+NETCPL.CPL     Network (does not take parameters)
+PASSWORD.CPL   Password Properties (does not take parameters)
+SYSDM.CPL      System Properties
+               ,,0 - Generic
+               ,,1 - Device Manager
+               ,,2 - Hardware Profiles
+               ,,3 - Advanced Features
+TELEPHON.CPL   Telephone Properties (renamed to TELEPHON.CP$ if not installed)
+               (does not take parameters)
+TIMEDATE.CPL   Time/Date Properties
+               ,,0 - Date and Time
+               ,,1 - Timezone
+               ,,m - summer/wintertime notification
+                     (issued by kernel32.dll on windows startup)
+
+
+
+Alphabetical List of alien CPLs / rundll commands
+-------------------------------------------------
+
+    command: amovie.ocx,RunDll
+description: run ActiveMovie Viewer
+
+    command: deskcp16.dll,QUICKRES_RUNDLLENTRY
+description: show SVGA display manager in task bar
+
+    command: shell32.dll,SHHelpShortcuts_RunDLL PrintersFolder
+description: show "Printers" Explorer Window
+
+(add your alien commands here)
+
diff --git a/programs/control/lccmake.bat b/programs/control/lccmake.bat
new file mode 100644
index 0000000..f92de02
--- /dev/null
+++ b/programs/control/lccmake.bat
@@ -0,0 +1,19 @@
+@ECHO OFF

+rem

+rem   this is a quick and dirty batch file to recompile control.exe

+rem   in a native windows environment using LCC. You may want to edit 

+rem   the following line, which should point to your LCC base directory:

+rem 

+

+set LCCDIR=C:\LCC

+

+rem   ---------------------------------------------------

+rem    it's safe not to change anything behind this line

+rem   ---------------------------------------------------

+

+if exist control.obj del control.obj

+%LCCDIR%\bin\lcc.exe -g2 -I%LCCDIR%\include\ -DWIN32 control.c

+%LCCDIR%\bin\lcclnk.exe -o control2.exe control.obj %LCCDIR%\lib\shell32.lib

+if exist control.obj del control.obj

+

+:EXIT

diff --git a/programs/control/params.h b/programs/control/params.h
new file mode 100644
index 0000000..0d48661
--- /dev/null
+++ b/programs/control/params.h
@@ -0,0 +1,32 @@
+/* 
+ *   Control
+ *   Copyright (C) 1998 by Marcel Baur <mbaur@g26.ethz.ch>
+ *   To be distributed under the Wine license
+ */
+
+/* alphabetical list of recognized optional command line parameters */
+
+#define szP_COLOR          "COLOR"
+#define szP_DATETIME       "DATE/TIME"
+#define szP_DESKTOP        "DESKTOP"
+#define szP_INTERNATIONAL  "INTERNATIONAL"
+#define szP_KEYBOARD       "KEYBOARD"
+#define szP_MOUSE          "MOUSE"
+#define szP_PORTS          "PORTS"
+#define szP_PRINTERS       "PRINTERS"
+
+
+/* alphabetical list of appropriate commands to execute */
+
+#define szEXEC_PREFIX      "rundll32.exe"
+#define szEXEC_ARGS        "Shell32.dll,Control_RunDLL "
+
+#define szC_COLOR          "desk.cpl,,2"
+#define szC_DATETIME       "datetime.cpl"
+#define szC_DESKTOP        "desk.cpl"
+#define szC_FONTS          "main.cpl @3"
+#define szC_INTERNATIONAL  "intl.cpl"
+#define szC_KEYBOARD       "main.cpl @1"
+#define szC_MOUSE          "main.cpl"
+#define szC_PORTS          "sysdm.cpl,,1"
+#define szC_PRINTERS       "main.cpl @2"
diff --git a/relay32/Makefile.in b/relay32/Makefile.in
index 9d87194..b3bfa74 100644
--- a/relay32/Makefile.in
+++ b/relay32/Makefile.in
@@ -29,6 +29,7 @@
 	olecli32.spec \
 	oledlg.spec \
 	olesvr32.spec \
+	psapi.spec \
 	rasapi32.spec \
 	shell32.spec \
 	tapi32.spec \
diff --git a/relay32/builtin32.c b/relay32/builtin32.c
index 18081a9..42ffd0b 100644
--- a/relay32/builtin32.c
+++ b/relay32/builtin32.c
@@ -51,6 +51,7 @@
 extern const BUILTIN32_DESCRIPTOR OLECLI32_Descriptor;
 extern const BUILTIN32_DESCRIPTOR OLEDLG_Descriptor;
 extern const BUILTIN32_DESCRIPTOR OLESVR32_Descriptor;
+extern const BUILTIN32_DESCRIPTOR PSAPI_Descriptor;
 extern const BUILTIN32_DESCRIPTOR RASAPI32_Descriptor;
 extern const BUILTIN32_DESCRIPTOR SHELL32_Descriptor;
 extern const BUILTIN32_DESCRIPTOR TAPI32_Descriptor;
@@ -88,6 +89,7 @@
     { &OLECLI32_Descriptor, FALSE },
     { &OLEDLG_Descriptor,   FALSE },
     { &OLESVR32_Descriptor, FALSE },
+    { &PSAPI_Descriptor,    FALSE },
     { &RASAPI32_Descriptor, FALSE },
     { &SHELL32_Descriptor,  TRUE  },
     { &TAPI32_Descriptor,   FALSE },
diff --git a/relay32/comctl32.spec b/relay32/comctl32.spec
index e1f35e5..16df38e 100644
--- a/relay32/comctl32.spec
+++ b/relay32/comctl32.spec
@@ -16,7 +16,7 @@
   8 stdcall CreateMappedBitmap(long long long ptr long) CreateMappedBitmap
   9 stub COMCTL32_9
  10 stub COMCTL32_10
- 11 stub COMCTL32_11
+ 11 stdcall COMCTL32_11(long long long long long long) COMCTL32_11
  12 stub Cctl1632_ThunkData32
  13 stub MakeDragList
  14 stub LBItemFromPt
@@ -94,24 +94,24 @@
  86 stub UninitializeFlatSB
  87 stub _TrackMouseEvent
 
-151 stdcall CreateMRUListA(long) CreateMRUList32A
-152 stub FreeMRUList@4
+151 stdcall CreateMRUListA(ptr) CreateMRUList32A
+152 stdcall FreeMRUList(long) FreeMRUList32A
 153 stub AddMRUStringA@8
 154 stub EnumMRUListA@16
 155 stub FindMRUStringA@12
 156 stub DelMRUString@8
-157 stub COMCTL32_157
+157 stdcall COMCTL32_157(ptr long long long) CreateMRUListEx32A
 
 163 stub CreatePage
 164 stub CreateProxyPage
 
-167 stub AddMRUData@12
-169 stub FindMRUData@16
+167 stdcall AddMRUData(long long long) AddMRUData
+169 stdcall FindMRUData(long long long long) FindMRUData
 
-233 stub Str_GetPtrA
-234 stdcall Str_SetPtrA(long long) COMCTL32_Str_SetPtrA
-235 stub Str_GetPtrW
-236 stub Str_SetPtrW
+233 stdcall Str_GetPtrA(str str long) Str_GetPtr32A
+234 stdcall Str_SetPtrA(str str) Str_SetPtr32A
+235 stdcall Str_GetPtrW(wstr wstr long) Str_GetPtr32W
+236 stdcall Str_SetPtrW(wstr wstr) Str_SetPtr32W
 
 320 stdcall DSA_Create(long long) DSA_Create
 321 stdcall DSA_Destroy(ptr) DSA_Destroy
@@ -168,10 +168,10 @@
 382 stub SmoothScrollWindow@4
 383 stub DoReaderMode@4
 384 stub SetPathWordBreakProc@8
-385 stub COMCTL32_385
-386 stub COMCTL32_386
-387 stub COMCTL32_387
-388 stub COMCTL32_388
+385 stdcall COMCTL32_385(long long long) COMCTL32_385
+386 stdcall COMCTL32_386(long long long) COMCTL32_386
+387 stdcall COMCTL32_387(long long long) COMCTL32_387
+388 stdcall COMCTL32_388(long long long) COMCTL32_388
 389 stub COMCTL32_389
 390 stub COMCTL32_390
 
diff --git a/relay32/crtdll.spec b/relay32/crtdll.spec
index 8d15fc7..99f967b 100644
--- a/relay32/crtdll.spec
+++ b/relay32/crtdll.spec
@@ -26,7 +26,7 @@
  22 cdecl __GetMainArgs(ptr ptr ptr long) CRTDLL__GetMainArgs
  23 extern __argc_dll CRTDLL_argc_dll
  24 extern __argv_dll CRTDLL_argv_dll
- 25 stub __dllonexit
+ 25 cdecl __dllonexit() CRTDLL__dllonexit
  26 stub __doserrno
  27 stub __fpecode
  28 stub __isascii
diff --git a/relay32/gdi32.spec b/relay32/gdi32.spec
index 8f31000..3cb7727 100644
--- a/relay32/gdi32.spec
+++ b/relay32/gdi32.spec
@@ -98,7 +98,7 @@
  94 stdcall ExtCreateRegion(ptr long ptr) ExtCreateRegion
  95 stdcall ExtEscape(long long long ptr long ptr) ExtEscape32
  96 stdcall ExtFloodFill(long long long long long) ExtFloodFill32
- 97 stub ExtSelectClipRgn
+ 97 stdcall ExtSelectClipRgn(long long long) ExtSelectClipRgn
  98 stdcall ExtTextOutA(long long long long ptr str long ptr) ExtTextOut32A
  99 stdcall ExtTextOutW(long long long long ptr wstr long ptr) ExtTextOut32W
 100 stdcall FillPath(long) FillPath32
@@ -389,3 +389,6 @@
 384 stub UpdateICMRegKeyW
 385 stub gdiPlaySpoolStream
 386 stdcall SetObjectOwner(long long) SetObjectOwner32
+387 stub UpdateICMRegKey
+388 extern pfnRealizePalette pfnRealizePalette
+389 extern pfnSelectPalette pfnSelectPalette
diff --git a/relay32/kernel32.spec b/relay32/kernel32.spec
index 7e11ef5..92d225e 100644
--- a/relay32/kernel32.spec
+++ b/relay32/kernel32.spec
@@ -212,8 +212,8 @@
 195 stdcall EnterCriticalSection(ptr) EnterCriticalSection
 196 stub EnumCalendarInfoA
 197 stub EnumCalendarInfoW
-198 stub EnumDateFormatsA
-199 stub EnumDateFormatsW
+198 stdcall EnumDateFormatsA(ptr long long) EnumDateFormats32A
+199 stdcall EnumDateFormatsW(ptr long long) EnumDateFormats32W
 200 stdcall EnumResourceLanguagesA(long str str ptr long) EnumResourceLanguages32A
 201 stdcall EnumResourceLanguagesW(long wstr wstr ptr long) EnumResourceLanguages32W
 202 stdcall EnumResourceNamesA(long str ptr long) EnumResourceNames32A
@@ -224,8 +224,8 @@
 207 stdcall EnumSystemCodePagesW(ptr long) EnumSystemCodePages32W
 208 stdcall EnumSystemLocalesA(ptr long) EnumSystemLocales32A
 209 stdcall EnumSystemLocalesW(ptr long) EnumSystemLocales32W
-210 stub EnumTimeFormatsA
-211 stub EnumTimeFormatsW
+210 stdcall EnumTimeFormatsA(ptr long long) EnumTimeFormats32A
+211 stdcall EnumTimeFormatsW(ptr long long) EnumTimeFormats32W
 212 stub EraseTape
 213 stdcall EscapeCommFunction(long long) EscapeCommFunction32
 214 stdcall ExitProcess(long) ExitProcess
diff --git a/relay32/msvfw32.spec b/relay32/msvfw32.spec
index 1f75461..e829577 100644
--- a/relay32/msvfw32.spec
+++ b/relay32/msvfw32.spec
@@ -1,7 +1,7 @@
 name	msvfw32
 type	win32
 
-  2 stub    VideoForWindowsVersion
+  2 stdcall VideoForWindowsVersion() VideoForWindowsVersion
   3 stub    DrawDibBegin
   4 stub    DrawDibChangePalette
   5 stub    DrawDibClose
@@ -9,7 +9,7 @@
   7 stub    DrawDibEnd
   8 stub    DrawDibGetBuffer
   9 stub    DrawDibGetPalette
- 10 stub    DrawDibOpen
+ 10 stdcall DrawDibOpen() DrawDibOpen32
  11 stub    DrawDibProfileDisplay
  12 stub    DrawDibRealize
  13 stub    DrawDibSetPalette
@@ -27,19 +27,19 @@
  25 stub    ICCompressorFree
  26 stub    ICDecompress
  27 stub    ICDraw
- 28 stub    ICDrawBegin
+ 28 stdcall ICDrawBegin(long long long long long long long long long ptr long long long long long long) ICDrawBegin32
  29 stub    ICGetDisplayFormat
- 30 stub    ICGetInfo
+ 30 stdcall ICGetInfo(long ptr long) ICGetInfo32
  31 stub    ICImageCompress
  32 stub    ICImageDecompress
- 33 stub    ICInfo
+ 33 stdcall ICInfo(long long ptr) ICInfo32
  34 stub    ICInstall
  35 stub    ICLocate
  36 stub    ICMThunk32
- 37 stub    ICOpen
+ 37 stdcall ICOpen(long long long) ICOpen32
  38 stub    ICOpenFunction
  39 stub    ICRemove
- 40 stub    ICSendMessage
+ 40 stdcall ICSendMessage(long long long long) ICSendMessage32
  41 stub    ICSeqCompressFrame
  42 stub    ICSeqCompressFrameEnd
  43 stub    ICSeqCompressFrameStart
diff --git a/relay32/psapi.spec b/relay32/psapi.spec
new file mode 100644
index 0000000..59b31db
--- /dev/null
+++ b/relay32/psapi.spec
@@ -0,0 +1,21 @@
+name    psapi
+type    win32
+
+  1 stub EmptyWorkingSet
+  2 stub EnumDeviceDrivers
+  3 stub EnumProcessModules
+  4 stub EnumProcesses
+  5 stub GetDeviceDriverBaseNameA
+  6 stub GetDeviceDriverBaseNameW
+  7 stub GetDeviceDriverFileNameA
+  8 stub GetDeviceDriverFileNameW
+  9 stub GetMappedFileNameA
+ 10 stub GetMappedFileNameW
+ 11 stub GetModuleBaseNameA
+ 12 stub GetModuleBaseNameW
+ 13 stub GetModuleFileNameExA
+ 14 stub GetModuleFileNameExW
+ 15 stub GetModuleInformation
+ 16 stub GetProcessMemoryInfo
+ 17 stub GetWsChanges
+ 18 stub InitializeProcessForWsWatch
diff --git a/relay32/shell32.spec b/relay32/shell32.spec
index d7fd6d0..c416eeb 100644
--- a/relay32/shell32.spec
+++ b/relay32/shell32.spec
@@ -24,12 +24,12 @@
   16 stdcall ILFindLastID(ptr) ILFindLastID
   17 stdcall ILRemoveLastID@4(ptr) ILRemoveLastID
   18 stdcall ILClone(ptr) ILClone
-  19 stub ILCloneFirst@4
+  19 stdcall ILCloneFirst (ptr) ILCloneFirst
   20 stub ILGlobalClone@4
-  21 stub ILIsEqual@8
+  21 stdcall ILIsEqual (ptr ptr) ILIsEqual
   22 stdcall Control_RunDLL(long long long long) Control_RunDLL # exported by name
   23 stub ILIsParent@12
-  24 stub ILFindChild@8
+  24 stdcall ILFindChild (long long) ILFindChild
   25 stdcall ILCombine(ptr ptr) ILCombine
   26 stub ILLoadFromStream@8
   27 stub ILSaveToStream@8
@@ -48,10 +48,10 @@
   40 stub PathIsRelative
   41 stub Control_RunDLLA   # exported by name
   42 stub Control_RunDLLW   # exported by name
-  43 stub PathIsExe
+  43 stdcall PathIsExe (ptr) PathIsExe
   44 stub DoEnvironmentSubstA   # exported by name
   45 stdcall PathFileExists(str) PathFileExists
-  46 stub PathMatchSpec
+  46 stdcall PathMatchSpec (str str) PathMatchSpec
   47 stub PathMakeUniqueName
   48 stub PathSetDlgItemPath
   49 stub PathQualify
@@ -100,7 +100,7 @@
   92 stub PathGetShortPath
   93 stub Win32CreateDirectory
   94 stub Win32RemoveDirectory
-  95 stub SHLogILFromFSIL
+  95 stdcall SHLogILFromFSIL (ptr) SHLogILFromFSIL
   96 stub StrRetToStrN
   97 stub SHWaitForFileToOpen
   98 stub SHGetRealIDL
@@ -162,7 +162,7 @@
  154 stub ILAppend
  155 stdcall ILFree(ptr) ILFree
  156 stub ILGlobalFree
- 157 stub ILCreateFromPath
+ 157 stdcall ILCreateFromPath (ptr) ILCreateFromPath
  158 stdcall PathGetExtension(str long long) PathGetExtension
  159 stub PathIsDirectory
  160 stub SHNetConnectionDialog
diff --git a/relay32/user32.spec b/relay32/user32.spec
index 57a215d..9e8788b 100644
--- a/relay32/user32.spec
+++ b/relay32/user32.spec
@@ -252,8 +252,8 @@
 249 stdcall GetKeyState(long) GetKeyState32
 250 stdcall GetKeyboardLayout(long) GetKeyboardLayout
 251 stdcall GetKeyboardLayoutList(long ptr) GetKeyboardLayoutList
-252 stub GetKeyboardLayoutNameA
-253 stub GetKeyboardLayoutNameW
+252 stdcall GetKeyboardLayoutNameA(ptr) GetKeyboardLayoutName32A
+253 stdcall GetKeyboardLayoutNameW(ptr) GetKeyboardLayoutName32W
 254 stdcall GetKeyboardState(ptr) GetKeyboardState
 255 stdcall GetKeyboardType(long) GetKeyboardType32
 256 stdcall GetLastActivePopup(long) GetLastActivePopup32
@@ -608,7 +608,9 @@
 604 stub ChangeDisplaySettingsA
 605 stub ChangeDisplaySettingsW
 606 stdcall SetWindowText(long str) SetWindowText32A
-607 stub GetMonitorInfoA
-608 stub MonitorFromWindow
-609 stub MonitorFromRect
-610 stub MonitorFromPoint
+607 stdcall GetMonitorInfoA(long ptr) GetMonitorInfo32A
+608 stdcall GetMonitorInfoW(long ptr) GetMonitorInfo32W
+609 stdcall MonitorFromWindow(long long) MonitorFromPoint
+610 stdcall MonitorFromRect(ptr long) MonitorFromRect
+611 stdcall MonitorFromPoint(ptr long) MonitorFromPoint
+612 stdcall EnumDisplayMonitors(long ptr ptr long) EnumDisplayMonitors
diff --git a/relay32/winmm.spec b/relay32/winmm.spec
index 98d51cc..f3716b9 100644
--- a/relay32/winmm.spec
+++ b/relay32/winmm.spec
@@ -130,7 +130,7 @@
 127 stdcall mmioSeek(long long long) mmioSeek32
 128 stub mmioSendMessage
 129 stub mmioSetBuffer
-130 stub mmioSetInfo
+130 stdcall mmioSetInfo(long ptr long) mmioSetInfo32
 131 stdcall mmioStringToFOURCCA(str long) mmioStringToFOURCC32A
 132 stdcall mmioStringToFOURCCW(wstr long) mmioStringToFOURCC32W
 133 stub mmioWrite
diff --git a/relay32/wnaspi32.spec b/relay32/wnaspi32.spec
index 77f30f1..3f4e847 100644
--- a/relay32/wnaspi32.spec
+++ b/relay32/wnaspi32.spec
@@ -1,6 +1,6 @@
 name	wnaspi32
 type	win32
 
-0 stdcall GetASPI32SupportInfo() GetASPI32SupportInfo
-1 stub SendASPI32Command
+0 stdcall GetASPI32SupportInfo() GetASPI32SupportInfo32
+1 stdcall SendASPI32Command(ptr) SendASPI32Command32
 3 stub GetASPI32DLLVersion
diff --git a/scheduler/client.c b/scheduler/client.c
index e39d82d..1e7aa44 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -15,8 +15,8 @@
 
 #include "process.h"
 #include "thread.h"
-#include "server.h"
 #include "server/request.h"
+#include "server.h"
 #include "winerror.h"
 
 /* Some versions of glibc don't define this */
@@ -24,14 +24,11 @@
 #define SCM_RIGHTS 1
 #endif
 
-#define CHECK_LEN(len,wanted) \
-  if ((len) == (wanted)) ; \
-  else CLIENT_ProtocolError( __FUNCTION__ ": len %d != %d\n", (len), (wanted) );
 
 /***********************************************************************
  *           CLIENT_ProtocolError
  */
-static void CLIENT_ProtocolError( const char *err, ... )
+void CLIENT_ProtocolError( const char *err, ... )
 {
     THDB *thdb = THREAD_Current();
     va_list args;
@@ -96,8 +93,8 @@
  *
  * Send a request to the server.
  */
-static void CLIENT_SendRequest( enum request req, int pass_fd,
-                                int n, ... /* arg_1, len_1, etc. */ )
+void CLIENT_SendRequest( enum request req, int pass_fd,
+                         int n, ... /* arg_1, len_1, etc. */ )
 {
     struct iovec vec[16];
     va_list args;
@@ -198,8 +195,8 @@
  *
  * Wait for a reply from the server.
  */
-static unsigned int CLIENT_WaitReply( int *len, int *passed_fd,
-                                      int n, ... /* arg_1, len_1, etc. */ )
+unsigned int CLIENT_WaitReply( int *len, int *passed_fd,
+                               int n, ... /* arg_1, len_1, etc. */ )
 {
     struct iovec vec[16];
     va_list args;
@@ -454,4 +451,3 @@
     CHECK_LEN( len, sizeof(reply) );
     return reply.signaled;
 }
-
diff --git a/scheduler/event.c b/scheduler/event.c
index 1ca9d16..650bf6e 100644
--- a/scheduler/event.c
+++ b/scheduler/event.c
@@ -11,6 +11,9 @@
 #include "process.h"
 #include "thread.h"
 #include "heap.h"
+#include "syslevel.h"
+#include "server/request.h"
+#include "server.h"
 
 typedef struct
 {
@@ -83,12 +86,24 @@
 HANDLE32 WINAPI CreateEvent32A( SECURITY_ATTRIBUTES *sa, BOOL32 manual_reset,
                                 BOOL32 initial_state, LPCSTR name )
 {
+    struct create_event_request req;
+    struct create_event_reply reply;
+    int len = name ? strlen(name) + 1 : 0;
     HANDLE32 handle;
     EVENT *event;
 
+    req.manual_reset = manual_reset;
+    req.initial_state = initial_state;
+    req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
+
+    CLIENT_SendRequest( REQ_CREATE_EVENT, -1, 2, &req, sizeof(req), name, len );
+    CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
+    CHECK_LEN( len, sizeof(reply) );
+    if (reply.handle == -1) return NULL;
+
     SYSTEM_LOCK();
-    event = (EVENT *)K32OBJ_Create( K32OBJ_EVENT, sizeof(*event),
-                                    name, EVENT_ALL_ACCESS, sa, &handle );
+    event = (EVENT *)K32OBJ_Create( K32OBJ_EVENT, sizeof(*event), name,
+                                    reply.handle, EVENT_ALL_ACCESS, sa, &handle );
     if (event)
     {
         /* Finish initializing it */
@@ -114,6 +129,14 @@
     return ret;
 }
 
+/***********************************************************************
+ *           WIN16_CreateEvent    (KERNEL.457)
+ */
+HANDLE32 WINAPI WIN16_CreateEvent( BOOL32 manual_reset, BOOL32 initial_state )
+{
+    return CreateEvent32A( NULL, manual_reset, initial_state, NULL );
+}
+
 
 /***********************************************************************
  *           OpenEvent32A    (KERNEL32.536)
@@ -150,14 +173,23 @@
  */
 BOOL32 WINAPI PulseEvent( HANDLE32 handle )
 {
+    struct event_op_request req;
     EVENT *event;
     SYSTEM_LOCK();
     if (!(event = (EVENT *)HANDLE_GetObjPtr(PROCESS_Current(), handle,
-                                            K32OBJ_EVENT, EVENT_MODIFY_STATE, NULL)))
+                                            K32OBJ_EVENT, EVENT_MODIFY_STATE,
+                                            &req.handle )))
     {
         SYSTEM_UNLOCK();
         return FALSE;
     }
+    if (req.handle != -1)
+    {
+        SYSTEM_UNLOCK();
+        req.op = PULSE_EVENT;
+        CLIENT_SendRequest( REQ_EVENT_OP, -1, 1, &req, sizeof(req) );
+        return !CLIENT_WaitReply( NULL, NULL, 0 );
+    }
     event->signaled = TRUE;
     SYNC_WakeUp( &event->wait_queue, event->manual_reset ? INFINITE32 : 1 );
     event->signaled = FALSE;
@@ -172,14 +204,23 @@
  */
 BOOL32 WINAPI SetEvent( HANDLE32 handle )
 {
+    struct event_op_request req;
     EVENT *event;
     SYSTEM_LOCK();
     if (!(event = (EVENT *)HANDLE_GetObjPtr(PROCESS_Current(), handle,
-                                            K32OBJ_EVENT, EVENT_MODIFY_STATE, NULL)))
+                                            K32OBJ_EVENT, EVENT_MODIFY_STATE,
+                                            &req.handle )))
     {
         SYSTEM_UNLOCK();
         return FALSE;
     }
+    if (req.handle != -1)
+    {
+        SYSTEM_UNLOCK();
+        req.op = SET_EVENT;
+        CLIENT_SendRequest( REQ_EVENT_OP, -1, 1, &req, sizeof(req) );
+        return !CLIENT_WaitReply( NULL, NULL, 0 );
+    }
     event->signaled = TRUE;
     SYNC_WakeUp( &event->wait_queue, event->manual_reset ? INFINITE32 : 1 );
     K32OBJ_DecCount( &event->header );
@@ -193,14 +234,23 @@
  */
 BOOL32 WINAPI ResetEvent( HANDLE32 handle )
 {
+    struct event_op_request req;
     EVENT *event;
     SYSTEM_LOCK();
     if (!(event = (EVENT *)HANDLE_GetObjPtr(PROCESS_Current(), handle,
-                                            K32OBJ_EVENT, EVENT_MODIFY_STATE, NULL)))
+                                            K32OBJ_EVENT, EVENT_MODIFY_STATE,
+                                            &req.handle )))
     {
         SYSTEM_UNLOCK();
         return FALSE;
     }
+    if (req.handle != -1)
+    {
+        SYSTEM_UNLOCK();
+        req.op = RESET_EVENT;
+        CLIENT_SendRequest( REQ_EVENT_OP, -1, 1, &req, sizeof(req) );
+        return !CLIENT_WaitReply( NULL, NULL, 0 );
+    }
     event->signaled = FALSE;
     K32OBJ_DecCount( &event->header );
     SYSTEM_UNLOCK();
@@ -272,3 +322,48 @@
     obj->type = K32OBJ_UNKNOWN;
     HeapFree( SystemHeap, 0, event );
 }
+
+
+
+
+/***********************************************************************
+ * NOTE: The Win95 VWin32_Event routines given below are really low-level
+ *       routines implemented directly by VWin32. The user-mode libraries
+ *       implement Win32 synchronisation routines on top of these low-level
+ *       primitives. We do it the other way around here :-)
+ */
+
+/***********************************************************************
+ *       VWin32_EventCreate	(KERNEL.442)
+ */
+HANDLE32 WINAPI VWin32_EventCreate(VOID)
+{
+    return CreateEvent32A( NULL, FALSE, 0, NULL );
+}
+
+/***********************************************************************
+ *       VWin32_EventDestroy	(KERNEL.443)
+ */
+VOID WINAPI VWin32_EventDestroy(HANDLE32 event)
+{
+    CloseHandle( event );
+}
+
+/***********************************************************************
+ *       VWin32_EventWait	(KERNEL.450) 
+ */
+VOID WINAPI VWin32_EventWait(HANDLE32 event)
+{
+    SYSLEVEL_ReleaseWin16Lock();
+    WaitForSingleObject( event, INFINITE32 );
+    SYSLEVEL_RestoreWin16Lock();
+}
+
+/***********************************************************************
+ *       VWin32_EventSet	(KERNEL.451)
+ */
+VOID WINAPI VWin32_EventSet(HANDLE32 event)
+{
+    SetEvent( event );
+}
+
diff --git a/scheduler/handle.c b/scheduler/handle.c
index 0f5bdc0..3dfd03a 100644
--- a/scheduler/handle.c
+++ b/scheduler/handle.c
@@ -163,23 +163,23 @@
                      handle, entry->access, access );
         ptr = entry->ptr;
         if (server_handle) *server_handle = entry->server;
-        if (ptr && ((type == K32OBJ_UNKNOWN) || (ptr->type == type)))
-            K32OBJ_IncCount( ptr );
-        else
-            ptr = NULL;
     }
     else if (handle == CURRENT_THREAD_PSEUDOHANDLE)
     {
        ptr = (K32OBJ *)THREAD_Current();
        if (server_handle) *server_handle = CURRENT_THREAD_PSEUDOHANDLE;
-       K32OBJ_IncCount( ptr );
     }
     else if (handle == CURRENT_PROCESS_PSEUDOHANDLE)
     {
        ptr = (K32OBJ *)PROCESS_Current();
        if (server_handle) *server_handle = CURRENT_PROCESS_PSEUDOHANDLE;
-       K32OBJ_IncCount( ptr );
     }
+
+    if (ptr && ((type == K32OBJ_UNKNOWN) || (ptr->type == type)))
+        K32OBJ_IncCount( ptr );
+    else
+        ptr = NULL;
+
     SYSTEM_UNLOCK();
     if (!ptr) SetLastError( ERROR_INVALID_HANDLE );
     return ptr;
diff --git a/scheduler/k32obj.c b/scheduler/k32obj.c
index aebca61..7eaab60 100644
--- a/scheduler/k32obj.c
+++ b/scheduler/k32obj.c
@@ -164,7 +164,7 @@
  * Returns NULL if there was an error _or_ if the object already existed.
  * The refcount of the object must be decremented once it is initialized.
  */
-K32OBJ *K32OBJ_Create( K32OBJ_TYPE type, DWORD size, LPCSTR name,
+K32OBJ *K32OBJ_Create( K32OBJ_TYPE type, DWORD size, LPCSTR name, int server_handle,
                        DWORD access, SECURITY_ATTRIBUTES *sa, HANDLE32 *handle)
 {
     BOOL32 inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
@@ -177,12 +177,13 @@
         if (obj->type == type)
         {
             SetLastError( ERROR_ALREADY_EXISTS );
-            *handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, -1 );
+            *handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, server_handle );
         }
         else
         {
             SetLastError( ERROR_DUP_NAME );
             *handle = INVALID_HANDLE_VALUE32;
+            if (server_handle != -1) CLIENT_CloseHandle( server_handle );
         }
         K32OBJ_DecCount( obj );
         return NULL;
@@ -195,6 +196,7 @@
     {
         SYSTEM_UNLOCK();
         *handle = INVALID_HANDLE_VALUE32;
+        if (server_handle != -1) CLIENT_CloseHandle( server_handle );
         return NULL;
     }
     obj->type     = type;
@@ -209,12 +211,13 @@
         HeapFree( SystemHeap, 0, obj );
         SYSTEM_UNLOCK();
         *handle = INVALID_HANDLE_VALUE32;
+        if (server_handle != -1) CLIENT_CloseHandle( server_handle );
         return NULL;
     }
 
     /* Allocate a handle */
 
-    *handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, -1 );
+    *handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, server_handle );
     SYSTEM_UNLOCK();
     return obj;
 }
diff --git a/scheduler/mutex.c b/scheduler/mutex.c
index 084fae0..4a32e15 100644
--- a/scheduler/mutex.c
+++ b/scheduler/mutex.c
@@ -11,6 +11,8 @@
 #include "process.h"
 #include "thread.h"
 #include "heap.h"
+#include "server/request.h"
+#include "server.h"
 
 typedef struct _MUTEX
 {
@@ -81,12 +83,24 @@
 HANDLE32 WINAPI CreateMutex32A( SECURITY_ATTRIBUTES *sa, BOOL32 owner,
                                 LPCSTR name )
 {
+    struct create_mutex_request req;
+    struct create_mutex_reply reply;
+    int len = name ? strlen(name) + 1 : 0;
     HANDLE32 handle;
     MUTEX *mutex;
 
+    req.owned   = owner;
+    req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
+
+    CLIENT_SendRequest( REQ_CREATE_MUTEX, -1, 2, &req, sizeof(req), name, len );
+    CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
+    CHECK_LEN( len, sizeof(reply) );
+    if (reply.handle == -1) return NULL;
+
     SYSTEM_LOCK();
     mutex = (MUTEX *)K32OBJ_Create( K32OBJ_MUTEX, sizeof(*mutex),
-                                    name, MUTEX_ALL_ACCESS, sa, &handle );
+                                    name, reply.handle, MUTEX_ALL_ACCESS,
+                                    sa, &handle );
     if (mutex)
     {
         /* Finish initializing it */
@@ -165,14 +179,22 @@
  */
 BOOL32 WINAPI ReleaseMutex( HANDLE32 handle )
 {
+    struct release_mutex_request req;
     MUTEX *mutex;
     SYSTEM_LOCK();
     if (!(mutex = (MUTEX *)HANDLE_GetObjPtr(PROCESS_Current(), handle,
-                                            K32OBJ_MUTEX, MUTEX_MODIFY_STATE, NULL)))
+                                            K32OBJ_MUTEX, MUTEX_MODIFY_STATE,
+                                            &req.handle )))
     {
         SYSTEM_UNLOCK();
         return FALSE;
     }
+    if (req.handle != -1)
+    {
+        SYSTEM_UNLOCK();
+        CLIENT_SendRequest( REQ_RELEASE_MUTEX, -1, 1, &req, sizeof(req) );
+        return !CLIENT_WaitReply( NULL, NULL, 0 );
+    }
     if (!mutex->count || (mutex->owner != GetCurrentThreadId()))
     {
         SYSTEM_UNLOCK();
diff --git a/scheduler/process.c b/scheduler/process.c
index adaf782..4ffcd1f 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -649,12 +649,24 @@
 }
 
 /***********************************************************************
- *           SetProcessWorkingSetSize    (KERNEL32)
+ *		SetProcessWorkingSetSize	[KERNEL32.662]
+ * Sets the min/max working set sizes for a specified process.
+ *
+ * PARAMS
+ *    hProcess [I] Handle to the process of interest
+ *    minset   [I] Specifies minimum working set size
+ *    maxset   [I] Specifies maximum working set size
+ *
+ * RETURNS  STD
  */
 BOOL32 WINAPI SetProcessWorkingSetSize(HANDLE32 hProcess,DWORD minset,
                                        DWORD maxset)
 {
-    FIXME(process,"(0x%08x,%ld,%ld): stub\n",hProcess,minset,maxset);
+    FIXME(process,"(0x%08x,%ld,%ld): stub - harmless\n",hProcess,minset,maxset);
+    if(( minset == -1) && (maxset == -1)) {
+        /* Trim the working set to zero */
+        /* Swap the process out of physical RAM */
+    }
     return TRUE;
 }
 
diff --git a/scheduler/semaphore.c b/scheduler/semaphore.c
index 626150e..7c71a10 100644
--- a/scheduler/semaphore.c
+++ b/scheduler/semaphore.c
@@ -11,6 +11,8 @@
 #include "process.h"
 #include "thread.h"
 #include "heap.h"
+#include "server/request.h"
+#include "server.h"
 
 typedef struct
 {
@@ -44,6 +46,9 @@
 HANDLE32 WINAPI CreateSemaphore32A( SECURITY_ATTRIBUTES *sa, LONG initial,
                                     LONG max, LPCSTR name )
 {
+    struct create_semaphore_request req;
+    struct create_semaphore_reply reply;
+    int len = name ? strlen(name) + 1 : 0;
     HANDLE32 handle;
     SEMAPHORE *sem;
 
@@ -55,9 +60,19 @@
         return INVALID_HANDLE_VALUE32;
     }
 
+    req.initial = (unsigned int)initial;
+    req.max     = (unsigned int)max;
+    req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
+
+    CLIENT_SendRequest( REQ_CREATE_SEMAPHORE, -1, 2, &req, sizeof(req), name, len );
+    CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
+    CHECK_LEN( len, sizeof(reply) );
+    if (reply.handle == -1) return NULL;
+
     SYSTEM_LOCK();
     sem = (SEMAPHORE *)K32OBJ_Create( K32OBJ_SEMAPHORE, sizeof(*sem),
-                                      name, SEMAPHORE_ALL_ACCESS, sa, &handle);
+                                      name, reply.handle, SEMAPHORE_ALL_ACCESS,
+                                      sa, &handle);
     if (sem)
     {
         /* Finish initializing it */
@@ -119,16 +134,35 @@
  */
 BOOL32 WINAPI ReleaseSemaphore( HANDLE32 handle, LONG count, LONG *previous )
 {
+    struct release_semaphore_request req;
     SEMAPHORE *sem;
 
+    if (count < 0)
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return FALSE;
+    }
     SYSTEM_LOCK();
     if (!(sem = (SEMAPHORE *)HANDLE_GetObjPtr( PROCESS_Current(), handle,
                                                K32OBJ_SEMAPHORE,
-                                               SEMAPHORE_MODIFY_STATE, NULL )))
+                                               SEMAPHORE_MODIFY_STATE, &req.handle )))
     {
         SYSTEM_UNLOCK();
         return FALSE;
     }
+    if (req.handle != -1)
+    {
+        struct release_semaphore_reply reply;
+        int len;
+
+        SYSTEM_UNLOCK();
+        req.count = (unsigned int)count;
+        CLIENT_SendRequest( REQ_RELEASE_SEMAPHORE, -1, 1, &req, sizeof(req) );
+        if (CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) )) return FALSE;
+        CHECK_LEN( len, sizeof(reply) );
+        if (previous) *previous = reply.prev_count;
+        return TRUE;
+    }
     if (previous) *previous = sem->count;
     if (sem->count + count > sem->max)
     {
diff --git a/scheduler/synchro.c b/scheduler/synchro.c
index 4ed9a25..f7ba381 100644
--- a/scheduler/synchro.c
+++ b/scheduler/synchro.c
@@ -13,6 +13,7 @@
 #include "process.h"
 #include "thread.h"
 #include "winerror.h"
+#include "syslevel.h"
 #include "server.h"
 #include "debug.h"
 
@@ -398,3 +399,34 @@
 {
     return SYNC_DoWait( count, handles, wait_all, timeout, alertable, FALSE );
 }
+
+
+/***********************************************************************
+ *           WIN16_WaitForSingleObject   (KERNEL.460)
+ */
+DWORD WINAPI WIN16_WaitForSingleObject( HANDLE32 handle, DWORD timeout )
+{
+    DWORD retval;
+
+    SYSLEVEL_ReleaseWin16Lock();
+    retval = WaitForSingleObject( handle, timeout );
+    SYSLEVEL_RestoreWin16Lock();
+
+    return retval;
+}
+
+/***********************************************************************
+ *           WIN16_WaitForMultipleObjects   (KERNEL.461)
+ */
+DWORD WINAPI WIN16_WaitForMultipleObjects( DWORD count, const HANDLE32 *handles,
+                                           BOOL32 wait_all, DWORD timeout )
+{
+    DWORD retval;
+
+    SYSLEVEL_ReleaseWin16Lock();
+    retval = WaitForMultipleObjects( count, handles, wait_all, timeout );
+    SYSLEVEL_RestoreWin16Lock();
+
+    return retval;
+}
+
diff --git a/scheduler/sysdeps.c b/scheduler/sysdeps.c
index 9ec3b7a..f883f12 100644
--- a/scheduler/sysdeps.c
+++ b/scheduler/sysdeps.c
@@ -22,7 +22,7 @@
 /* Xlib critical section (FIXME: does not belong here) */
 CRITICAL_SECTION X11DRV_CritSection = { 0, };
 
-#ifdef __linux__
+#ifdef HAVE_CLONE_SYSCALL
 # ifdef HAVE_SCHED_H
 #  include <sched.h>
 # endif
@@ -35,10 +35,10 @@
 /* If we didn't get the flags, we probably didn't get the prototype either */
 extern int clone( int (*fn)(void *arg), void *stack, int flags, void *arg );
 # endif  /* CLONE_VM */
-#endif  /* __linux__ */
+#endif  /* HAVE_CLONE_SYSCALL */
 
 
-#ifdef __linux__
+#ifdef USE_THREADS
 /***********************************************************************
  *           __errno_location
  *
@@ -84,7 +84,7 @@
     SET_FS( thdb->teb_sel );
     THREAD_Start( thdb );
 }
-#endif  /* __linux__ */
+#endif  /* USE_THREADS */
 
 
 /***********************************************************************
@@ -95,15 +95,23 @@
  */
 int SYSDEPS_SpawnThread( THDB *thread )
 {
-#ifdef __linux__
+#ifdef USE_THREADS
+
+#ifdef HAVE_CLONE_SYSCALL
     if (clone( (int (*)(void *))SYSDEPS_StartThread, thread->teb.stack_top,
                CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, thread ) < 0)
         return -1;
     /* FIXME: close the child socket in the parent process */
 /*    close( thread->socket );*/
-#else
+#endif
+
+#ifdef HAVE_RFORK
+    FIXME(thread, "Threads using rfork() not implemented\n" );
+#endif
+
+#else  /* !USE_THREADS */
     FIXME(thread, "CreateThread: stub\n" );
-#endif  /* __linux__ */
+#endif  /* USE_THREADS */
     return 0;
 }
 
diff --git a/scheduler/thread.c b/scheduler/thread.c
index b836b9c..3a0ff97 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -83,6 +83,33 @@
     }
 }
 
+/***********************************************************************
+ *           THREAD_IdToTHDB
+ *
+ * Convert a thread id to a THDB, making sure it is valid.
+ */
+THDB *THREAD_IdToTHDB( DWORD id )
+{
+    THDB *thdb;
+
+    if (!id) return THREAD_Current();
+    thdb = THREAD_ID_TO_THDB( id );
+    if (!K32OBJ_IsValid( &thdb->header, K32OBJ_THREAD ))
+    {
+        /* Allow task handles to be used; convert to main thread */
+        if ( IsTask( id ) )
+        {
+            TDB *pTask = (TDB *)GlobalLock16( id );
+            if (pTask) return pTask->thdb;
+        }
+        
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return NULL;
+    }
+    return thdb;
+}
+
+
 
 /***********************************************************************
  *           THREAD_AddQueue
@@ -361,7 +388,7 @@
                            THREAD_ALL_ACCESS, inherit, server_handle );
     if (handle == INVALID_HANDLE_VALUE32) goto error;
     if (SYSDEPS_SpawnThread( thread ) == -1) goto error;
-    *id = THDB_TO_THREAD_ID( thread );
+    if (id) *id = THDB_TO_THREAD_ID( thread );
     return handle;
 
 error:
@@ -882,3 +909,19 @@
     return ret;
 }
 
+/**********************************************************************
+ * VWin32_BoostThreadGroup [KERNEL.535]
+ */
+VOID WINAPI VWin32_BoostThreadGroup( DWORD threadId, INT32 boost )
+{
+    FIXME(thread, "(0x%08lx,%d): stub\n", threadId, boost);
+}
+
+/**********************************************************************
+ * VWin32_BoostThreadStatic [KERNEL.536]
+ */
+VOID WINAPI VWin32_BoostThreadStatic( DWORD threadId, INT32 boost )
+{
+    FIXME(thread, "(0x%08lx,%d): stub\n", threadId, boost);
+}
+
diff --git a/server/Makefile.in b/server/Makefile.in
index 01b67f1..7ec46f8 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -6,9 +6,12 @@
 MODULE    = server
 
 C_SRCS = \
+	event.c \
+	mutex.c \
 	object.c \
 	process.c \
 	request.c \
+	semaphore.c \
 	socket.c \
 	thread.c \
 	trace.c
diff --git a/server/event.c b/server/event.c
new file mode 100644
index 0000000..ef9dd76
--- /dev/null
+++ b/server/event.c
@@ -0,0 +1,125 @@
+/*
+ * Server-side event management
+ *
+ * Copyright (C) 1998 Alexandre Julliard
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "winerror.h"
+#include "winnt.h"
+#include "server/thread.h"
+
+struct event
+{
+    struct object  obj;             /* object header */
+    int            manual_reset;    /* is it a manual reset event? */
+    int            signaled;        /* event has been signaled */
+};
+
+static void dump_event( struct object *obj, int verbose );
+static int event_signaled( struct object *obj, struct thread *thread );
+static int event_satisfied( struct object *obj, struct thread *thread );
+static void destroy_event( struct object *obj );
+
+static const struct object_ops event_ops =
+{
+    dump_event,
+    event_signaled,
+    event_satisfied,
+    destroy_event
+};
+
+
+struct object *create_event( const char *name, int manual_reset, int initial_state )
+{
+    struct event *event;
+
+    if (!(event = (struct event *)create_named_object( name, &event_ops, sizeof(*event) )))
+        return NULL;
+    if (GET_ERROR() != ERROR_ALREADY_EXISTS)
+    {
+        /* initialize it if it didn't already exist */
+        event->manual_reset = manual_reset;
+        event->signaled     = initial_state;
+    }
+    return &event->obj;
+}
+
+int open_event( unsigned int access, int inherit, const char *name )
+{
+    return open_object( name, &event_ops, access, inherit );
+}
+
+int pulse_event( int handle )
+{
+    struct event *event;
+
+    if (!(event = (struct event *)get_handle_obj( current->process, handle,
+                                                  EVENT_MODIFY_STATE, &event_ops )))
+        return 0;
+    event->signaled = 1;
+    /* wake up all waiters if manual reset, a single one otherwise */
+    wake_up( &event->obj, !event->manual_reset );
+    event->signaled = 0;
+    release_object( event );
+    return 1;
+}
+
+int set_event( int handle )
+{
+    struct event *event;
+
+    if (!(event = (struct event *)get_handle_obj( current->process, handle,
+                                                  EVENT_MODIFY_STATE, &event_ops )))
+        return 0;
+    event->signaled = 1;
+    /* wake up all waiters if manual reset, a single one otherwise */
+    wake_up( &event->obj, !event->manual_reset );
+    release_object( event );
+    return 1;
+}
+
+int reset_event( int handle )
+{
+    struct event *event;
+
+    if (!(event = (struct event *)get_handle_obj( current->process, handle,
+                                                  EVENT_MODIFY_STATE, &event_ops )))
+        return 0;
+    event->signaled = 0;
+    release_object( event );
+    return 1;
+}
+
+static void dump_event( struct object *obj, int verbose )
+{
+    struct event *event = (struct event *)obj;
+    assert( obj->ops == &event_ops );
+    printf( "Event manual=%d signaled=%d\n", event->manual_reset, event->signaled );
+}
+
+static int event_signaled( struct object *obj, struct thread *thread )
+{
+    struct event *event = (struct event *)obj;
+    assert( obj->ops == &event_ops );
+    return event->signaled;
+}
+
+static int event_satisfied( struct object *obj, struct thread *thread )
+{
+    struct event *event = (struct event *)obj;
+    assert( obj->ops == &event_ops );
+    /* Reset if it's an auto-reset event */
+    if (!event->manual_reset) event->signaled = 0;
+    return 0;  /* Not abandoned */
+}
+
+static void destroy_event( struct object *obj )
+{
+    struct event *event = (struct event *)obj;
+    assert( obj->ops == &event_ops );
+    free( event );
+}
diff --git a/server/mutex.c b/server/mutex.c
new file mode 100644
index 0000000..df5fc9f
--- /dev/null
+++ b/server/mutex.c
@@ -0,0 +1,142 @@
+/*
+ * Server-side mutex management
+ *
+ * Copyright (C) 1998 Alexandre Julliard
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "winerror.h"
+#include "winnt.h"
+#include "server/thread.h"
+
+struct mutex
+{
+    struct object  obj;             /* object header */
+    struct thread *owner;           /* mutex owner */
+    unsigned int   count;           /* recursion count */
+    int            abandoned;       /* has it been abandoned? */
+    struct mutex  *next;
+    struct mutex  *prev;
+};
+
+static void dump_mutex( struct object *obj, int verbose );
+static int mutex_signaled( struct object *obj, struct thread *thread );
+static int mutex_satisfied( struct object *obj, struct thread *thread );
+static void destroy_mutex( struct object *obj );
+
+static const struct object_ops mutex_ops =
+{
+    dump_mutex,
+    mutex_signaled,
+    mutex_satisfied,
+    destroy_mutex
+};
+
+
+struct object *create_mutex( const char *name, int owned )
+{
+    struct mutex *mutex;
+
+    if (!(mutex = (struct mutex *)create_named_object( name, &mutex_ops, sizeof(*mutex) )))
+        return NULL;
+    if (GET_ERROR() != ERROR_ALREADY_EXISTS)
+    {
+        /* initialize it if it didn't already exist */
+        mutex->count = 0;
+        mutex->owner = NULL;
+        mutex->abandoned = 0;
+        mutex->next = mutex->prev = NULL;
+        if (owned) mutex_satisfied( &mutex->obj, current );
+    }
+    return &mutex->obj;
+}
+
+int open_mutex( unsigned int access, int inherit, const char *name )
+{
+    return open_object( name, &mutex_ops, access, inherit );
+}
+
+/* release a mutex once the recursion count is 0 */
+static void do_release( struct mutex *mutex, struct thread *thread )
+{
+    assert( !mutex->count );
+    /* remove the mutex from the thread list of owned mutexes */
+    if (mutex->next) mutex->next->prev = mutex->prev;
+    if (mutex->prev) mutex->prev->next = mutex->next;
+    else thread->mutex = mutex->next;
+    mutex->owner = NULL;
+    mutex->next = mutex->prev = NULL;
+    wake_up( &mutex->obj, 0 );
+}
+
+int release_mutex( int handle )
+{
+    struct mutex *mutex;
+
+    if (!(mutex = (struct mutex *)get_handle_obj( current->process, handle,
+                                                  MUTEX_MODIFY_STATE, &mutex_ops )))
+        return 0;
+    if (!mutex->count || (mutex->owner != current))
+    {
+        SET_ERROR( ERROR_NOT_OWNER );
+        return 0;
+    }
+    if (!--mutex->count) do_release( mutex, current );
+    release_object( mutex );
+    return 1;
+}
+
+void abandon_mutexes( struct thread *thread )
+{
+    while (thread->mutex)
+    {
+        struct mutex *mutex = thread->mutex;
+        assert( mutex->owner == thread );
+        mutex->count = 0;
+        mutex->abandoned = 1;
+        do_release( mutex, thread );
+    }
+}
+
+static void dump_mutex( struct object *obj, int verbose )
+{
+    struct mutex *mutex = (struct mutex *)obj;
+    assert( obj->ops == &mutex_ops );
+    printf( "Mutex count=%u owner=%p\n", mutex->count, mutex->owner );
+}
+
+static int mutex_signaled( struct object *obj, struct thread *thread )
+{
+    struct mutex *mutex = (struct mutex *)obj;
+    assert( obj->ops == &mutex_ops );
+    return (!mutex->count || (mutex->owner == thread));
+}
+
+static int mutex_satisfied( struct object *obj, struct thread *thread )
+{
+    struct mutex *mutex = (struct mutex *)obj;
+    assert( obj->ops == &mutex_ops );
+    assert( !mutex->count || (mutex->owner == thread) );
+
+    if (!mutex->count++)  /* FIXME: avoid wrap-around */
+    {
+        assert( !mutex->owner );
+        mutex->owner = thread;
+        mutex->prev  = NULL;
+        if ((mutex->next = thread->mutex)) mutex->next->prev = mutex;
+        thread->mutex = mutex;
+    }
+    if (!mutex->abandoned) return 0;
+    mutex->abandoned = 0;
+    return 1;
+}
+
+static void destroy_mutex( struct object *obj )
+{
+    struct mutex *mutex = (struct mutex *)obj;
+    assert( obj->ops == &mutex_ops );
+    free( mutex );
+}
diff --git a/server/object.c b/server/object.c
index c05a310..82f1182 100644
--- a/server/object.c
+++ b/server/object.c
@@ -10,9 +10,9 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "winerror.h"
 #include "server.h"
-
-#include "server/object.h"
+#include "server/thread.h"
 
 int debug_level = 0;
 
@@ -30,6 +30,16 @@
 
 /*****************************************************************/
 
+void *mem_alloc( size_t size )
+{
+    void *ptr = malloc( size );
+    if (ptr) memset( ptr, 0x55, size );
+    else if (current) SET_ERROR( ERROR_OUTOFMEMORY );
+    return ptr;
+}
+
+/*****************************************************************/
+
 static int get_name_hash( const char *name )
 {
     int hash = 0;
@@ -43,7 +53,7 @@
     int hash = get_name_hash( name );
     int len = strlen( name );
 
-    if (!(ptr = (struct object_name *)malloc( sizeof(*ptr) + len )))
+    if (!(ptr = (struct object_name *)mem_alloc( sizeof(*ptr) + len )))
         return NULL;
     ptr->next = names[hash];
     ptr->obj  = obj;
@@ -64,15 +74,40 @@
 }
 
 /* initialize an already allocated object */
-void init_object( struct object *obj, const struct object_ops *ops,
-                  const char *name )
+/* return 1 if OK, 0 on error */
+int init_object( struct object *obj, const struct object_ops *ops,
+                 const char *name )
 {
     obj->refcount = 1;
     obj->ops      = ops;
     obj->head     = NULL;
     obj->tail     = NULL;
     if (!name) obj->name = NULL;
-    else obj->name = add_name( obj, name );
+    else if (!(obj->name = add_name( obj, name ))) return 0;
+    return 1;
+}
+
+struct object *create_named_object( const char *name, const struct object_ops *ops, size_t size )
+{
+    struct object *obj;
+    if ((obj = find_object( name )))
+    {
+        if (obj->ops == ops)
+        {
+            SET_ERROR( ERROR_ALREADY_EXISTS );
+            return obj;
+        }
+        SET_ERROR( ERROR_INVALID_HANDLE );
+        return NULL;
+    }
+    if (!(obj = mem_alloc( size ))) return NULL;
+    if (!init_object( obj, ops, name ))
+    {
+        free( obj );
+        return NULL;
+    }
+    CLEAR_ERROR();
+    return obj;
 }
 
 /* grab an object (i.e. increment its refcount) and return the object */
@@ -102,10 +137,10 @@
 /* find an object by its name; the refcount is incremented */
 struct object *find_object( const char *name )
 {
-    int hash = get_name_hash( name );
-    struct object_name *ptr = names[hash];
+    struct object_name *ptr;
+    if (!name) return NULL;
+    ptr = names[ get_name_hash( name ) ];
     while (ptr && strcmp( ptr->name, name )) ptr = ptr->next;
     if (!ptr) return NULL;
-    grab_object( ptr->obj );
-    return ptr->obj;
+    return grab_object( ptr->obj );
 }
diff --git a/server/process.c b/server/process.c
index 06d3d63..3fc73fe 100644
--- a/server/process.c
+++ b/server/process.c
@@ -74,7 +74,7 @@
 {
     struct process *process;
 
-    if (!(process = malloc( sizeof(*process) ))) return NULL;
+    if (!(process = mem_alloc( sizeof(*process) ))) return NULL;
 
     if (!copy_handle_table( process, current ? current->process : NULL ))
     {
@@ -219,7 +219,7 @@
     count *= 2;
     if (!(new_entries = realloc( process->entries, count * sizeof(struct handle_entry) )))
     {
-        SET_ERROR( ERROR_NOT_ENOUGH_MEMORY );
+        SET_ERROR( ERROR_OUTOFMEMORY );
         return 0;
     }
     process->handle_count = count;
@@ -344,7 +344,7 @@
         last  = parent->handle_last;
     }
 
-    if (!(ptr = malloc( count * sizeof(struct handle_entry)))) return 0;
+    if (!(ptr = mem_alloc( count * sizeof(struct handle_entry)))) return 0;
     process->entries      = ptr;
     process->handle_count = count;
     process->handle_last  = last;
@@ -438,6 +438,20 @@
     return alloc_specific_handle( dst, entry->ptr, dst_handle, access, inherit );
 }
 
+/* open a new handle to an existing object */
+int open_object( const char *name, const struct object_ops *ops,
+                 unsigned int access, int inherit )
+{
+    struct object *obj = find_object( name );
+    if (!obj) return -1;  /* FIXME: set error code */
+    if (ops && obj->ops != ops)
+    {
+        release_object( obj );
+        return -1;  /* FIXME: set error code */
+    }
+    return alloc_handle( current->process, obj, access, inherit );
+}
+
 /* dump a handle table on stdout */
 void dump_handles( struct process *process )
 {
diff --git a/server/request.c b/server/request.c
index e481d76..6ce5b35 100644
--- a/server/request.c
+++ b/server/request.c
@@ -19,7 +19,12 @@
 #include "server/request.h"
 #include "server/thread.h"
 
-
+/* check that the string is NULL-terminated and that the len is correct */
+#define CHECK_STRING(func,str,len) \
+  do { if (((str)[(len)-1] || strlen(str) != (len)-1)) \
+         fatal_protocol_error( "%s: invalid string '.*s'\n", (func), (len), (str) ); \
+     } while(0)
+ 
 struct thread *current = NULL;  /* thread handling the current request */
 
 /* complain about a protocol error and terminate the client connection */
@@ -107,8 +112,8 @@
     if (!(new_thread = create_thread( new_fd, req->pid, &reply.thandle,
                                       &reply.phandle )))
     {
-        err = ERROR_NOT_ENOUGH_MEMORY;
         close( new_fd );
+        err = ERROR_OUTOFMEMORY;
         goto done;
     }
     reply.tid = new_thread;
@@ -139,11 +144,7 @@
     }
     current->state    = RUNNING;
     current->unix_pid = req->unix_pid;
-    if (!(current->name = malloc( len + 1 )))
-    {
-        SET_ERROR( ERROR_NOT_ENOUGH_MEMORY );
-        goto done;
-    }
+    if (!(current->name = mem_alloc( len + 1 ))) goto done;
     memcpy( current->name, data, len );
     current->name[len] = '\0';
     CLEAR_ERROR();
@@ -256,3 +257,118 @@
                               len, req->count );
     sleep_on( current, req->count, (int *)data, req->flags, req->timeout );
 }
+
+/* create an event */
+DECL_HANDLER(create_event)
+{
+    struct create_event_reply reply = { -1 };
+    struct object *obj;
+    char *name = (char *)data;
+    if (!len) name = NULL;
+    else CHECK_STRING( "create_event", name, len );
+
+    obj = create_event( name, req->manual_reset, req->initial_state );
+    if (obj)
+    {
+        reply.handle = alloc_handle( current->process, obj, EVENT_ALL_ACCESS, req->inherit );
+        release_object( obj );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* do an event operation */
+DECL_HANDLER(event_op)
+{
+    switch(req->op)
+    {
+    case PULSE_EVENT:
+        pulse_event( req->handle );
+        break;
+    case SET_EVENT:
+        set_event( req->handle );
+        break;
+    case RESET_EVENT:
+        reset_event( req->handle );
+        break;
+    default:
+        fatal_protocol_error( "event_op: invalid operation %d\n", req->op );
+    }
+    send_reply( current, -1, 0 );
+}
+
+/* create a mutex */
+DECL_HANDLER(create_mutex)
+{
+    struct create_mutex_reply reply = { -1 };
+    struct object *obj;
+    char *name = (char *)data;
+    if (!len) name = NULL;
+    else CHECK_STRING( "create_mutex", name, len );
+
+    obj = create_mutex( name, req->owned );
+    if (obj)
+    {
+        reply.handle = alloc_handle( current->process, obj, MUTEX_ALL_ACCESS, req->inherit );
+        release_object( obj );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* release a mutex */
+DECL_HANDLER(release_mutex)
+{
+    if (release_mutex( req->handle )) CLEAR_ERROR();
+    send_reply( current, -1, 0 );
+}
+
+/* create a semaphore */
+DECL_HANDLER(create_semaphore)
+{
+    struct create_semaphore_reply reply = { -1 };
+    struct object *obj;
+    char *name = (char *)data;
+    if (!len) name = NULL;
+    else CHECK_STRING( "create_semaphore", name, len );
+
+    obj = create_semaphore( name, req->initial, req->max );
+    if (obj)
+    {
+        reply.handle = alloc_handle( current->process, obj, SEMAPHORE_ALL_ACCESS, req->inherit );
+        release_object( obj );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* release a semaphore */
+DECL_HANDLER(release_semaphore)
+{
+    struct release_semaphore_reply reply;
+    if (release_semaphore( req->handle, req->count, &reply.prev_count )) CLEAR_ERROR();
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* open a handle to a named object (event, mutex, semaphore) */
+DECL_HANDLER(open_named_obj)
+{
+    struct open_named_obj_reply reply;
+    char *name = (char *)data;
+    if (!len) name = NULL;
+    else CHECK_STRING( "open_named_obj", name, len );
+
+    switch(req->type)
+    {
+    case OPEN_EVENT:
+        reply.handle = open_event( req->access, req->inherit, name );
+        break;
+    case OPEN_MUTEX:
+        reply.handle = open_mutex( req->access, req->inherit, name );
+        break;
+    case OPEN_SEMAPHORE:
+        reply.handle = open_semaphore( req->access, req->inherit, name );
+        break;
+    default:
+        fatal_protocol_error( "open_named_obj: invalid type %d\n", req->type );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
diff --git a/server/semaphore.c b/server/semaphore.c
new file mode 100644
index 0000000..9cdedb9
--- /dev/null
+++ b/server/semaphore.c
@@ -0,0 +1,118 @@
+/*
+ * Server-side semaphore management
+ *
+ * Copyright (C) 1998 Alexandre Julliard
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "winerror.h"
+#include "winnt.h"
+#include "server/thread.h"
+
+struct semaphore
+{
+    struct object  obj;    /* object header */
+    unsigned int   count;  /* current count */
+    unsigned int   max;    /* maximum possible count */
+};
+
+static void dump_semaphore( struct object *obj, int verbose );
+static int semaphore_signaled( struct object *obj, struct thread *thread );
+static int semaphore_satisfied( struct object *obj, struct thread *thread );
+static void destroy_semaphore( struct object *obj );
+
+static const struct object_ops semaphore_ops =
+{
+    dump_semaphore,
+    semaphore_signaled,
+    semaphore_satisfied,
+    destroy_semaphore
+};
+
+
+struct object *create_semaphore( const char *name, unsigned int initial, unsigned int max )
+{
+    struct semaphore *sem;
+
+    if (!max || (initial > max))
+    {
+        SET_ERROR( ERROR_INVALID_PARAMETER );
+        return NULL;
+    }
+    if (!(sem = (struct semaphore *)create_named_object( name, &semaphore_ops, sizeof(*sem) )))
+        return NULL;
+    if (GET_ERROR() != ERROR_ALREADY_EXISTS)
+    {
+        /* initialize it if it didn't already exist */
+        sem->count = initial;
+        sem->max   = max;
+    }
+    return &sem->obj;
+}
+
+int open_semaphore( unsigned int access, int inherit, const char *name )
+{
+    return open_object( name, &semaphore_ops, access, inherit );
+}
+
+int release_semaphore( int handle, unsigned int count, unsigned int *prev_count )
+{
+    struct semaphore *sem;
+
+    if (!(sem = (struct semaphore *)get_handle_obj( current->process, handle,
+                                                    SEMAPHORE_MODIFY_STATE, &semaphore_ops )))
+        return 0;
+
+    *prev_count = sem->count;
+    if (sem->count + count < sem->count || sem->count + count > sem->max)
+    {
+        SET_ERROR( ERROR_TOO_MANY_POSTS );
+        return 0;
+    }
+    if (sem->count)
+    {
+        /* there cannot be any thread waiting if the count is != 0 */
+        assert( !sem->obj.head );
+        sem->count += count;
+    }
+    else
+    {
+        sem->count = count;
+        wake_up( &sem->obj, count );
+    }
+    release_object( sem );
+    return 1;
+}
+
+static void dump_semaphore( struct object *obj, int verbose )
+{
+    struct semaphore *sem = (struct semaphore *)obj;
+    assert( obj->ops == &semaphore_ops );
+    printf( "Semaphore count=%d max=%d\n", sem->count, sem->max );
+}
+
+static int semaphore_signaled( struct object *obj, struct thread *thread )
+{
+    struct semaphore *sem = (struct semaphore *)obj;
+    assert( obj->ops == &semaphore_ops );
+    return (sem->count > 0);
+}
+
+static int semaphore_satisfied( struct object *obj, struct thread *thread )
+{
+    struct semaphore *sem = (struct semaphore *)obj;
+    assert( obj->ops == &semaphore_ops );
+    assert( sem->count );
+    sem->count--;
+    return 0;  /* not abandoned */
+}
+
+static void destroy_semaphore( struct object *obj )
+{
+    struct semaphore *sem = (struct semaphore *)obj;
+    assert( obj->ops == &semaphore_ops );
+    free( sem );
+}
diff --git a/server/socket.c b/server/socket.c
index fd85741..1302467 100644
--- a/server/socket.c
+++ b/server/socket.c
@@ -279,7 +279,12 @@
     while (nb_clients)
     {
         fd_set read = read_set, write = write_set;
-
+#if 0
+        printf( "select: " );
+        for (i = 0; i <= max_fd; i++) printf( "%c", FD_ISSET( i, &read_set ) ? 'r' :
+                                                    (FD_ISSET( i, &write_set ) ? 'w' : '-') );
+        printf( "\n" );
+#endif
         if (timeout_head)
         {
             struct timeval tv, now;
diff --git a/server/thread.c b/server/thread.c
index e250cc8..fff2079 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -64,7 +64,7 @@
     struct thread *thread;
     struct process *process;
 
-    if (!(thread = malloc( sizeof(*thread) ))) return NULL;
+    if (!(thread = mem_alloc( sizeof(*thread) ))) return NULL;
 
     if (pid) process = get_process_from_id( pid );
     else process = create_process();
@@ -79,6 +79,7 @@
     thread->process   = process;
     thread->unix_pid  = 0;  /* not known yet */
     thread->name      = NULL;
+    thread->mutex     = NULL;
     thread->wait      = NULL;
     thread->error     = 0;
     thread->state     = STARTING;
@@ -250,11 +251,7 @@
         SET_ERROR( ERROR_INVALID_PARAMETER );
         return 0;
     }
-    if (!(wait = malloc( sizeof(*wait) + (count-1) * sizeof(*entry) )))
-    {
-        SET_ERROR( ERROR_OUTOFMEMORY );
-        return 0;
-    }
+    if (!(wait = mem_alloc( sizeof(*wait) + (count-1) * sizeof(*entry) ))) return 0;
     thread->wait  = wait;
     wait->count   = count;
     wait->flags   = flags;
@@ -396,6 +393,7 @@
 /* kill a thread on the spot */
 void kill_thread( struct thread *thread, int exit_code )
 {
+    if (thread->state == TERMINATED) return;  /* already killed */
     if (thread->unix_pid) kill( thread->unix_pid, SIGTERM );
     remove_client( thread->client_fd, exit_code ); /* this will call thread_killed */
 }
@@ -406,6 +404,7 @@
     thread->state = TERMINATED;
     thread->exit_code = exit_code;
     if (thread->wait) end_wait( thread );
+    abandon_mutexes( 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 a9158ce..0850fd5 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -103,6 +103,75 @@
     printf( " signaled=%d", req->signaled );
 }
 
+static void dump_create_event_request( struct create_event_request *req )
+{
+    printf( " manual_reset=%d,", req->manual_reset );
+    printf( " initial_state=%d,", req->initial_state );
+    printf( " inherit=%d", req->inherit );
+}
+
+static void dump_create_event_reply( struct create_event_reply *req )
+{
+    printf( " handle=%d", req->handle );
+}
+
+static void dump_event_op_request( struct event_op_request *req )
+{
+    printf( " handle=%d,", req->handle );
+    printf( " op=%d", req->op );
+}
+
+static void dump_create_mutex_request( struct create_mutex_request *req )
+{
+    printf( " owned=%d,", req->owned );
+    printf( " inherit=%d", req->inherit );
+}
+
+static void dump_create_mutex_reply( struct create_mutex_reply *req )
+{
+    printf( " handle=%d", req->handle );
+}
+
+static void dump_release_mutex_request( struct release_mutex_request *req )
+{
+    printf( " handle=%d", req->handle );
+}
+
+static void dump_create_semaphore_request( struct create_semaphore_request *req )
+{
+    printf( " initial=%08x,", req->initial );
+    printf( " max=%08x,", req->max );
+    printf( " inherit=%d", req->inherit );
+}
+
+static void dump_create_semaphore_reply( struct create_semaphore_reply *req )
+{
+    printf( " handle=%d", req->handle );
+}
+
+static void dump_release_semaphore_request( struct release_semaphore_request *req )
+{
+    printf( " handle=%d,", req->handle );
+    printf( " count=%08x", req->count );
+}
+
+static void dump_release_semaphore_reply( struct release_semaphore_reply *req )
+{
+    printf( " prev_count=%08x", req->prev_count );
+}
+
+static void dump_open_named_obj_request( struct open_named_obj_request *req )
+{
+    printf( " type=%d,", req->type );
+    printf( " access=%08x,", req->access );
+    printf( " inherit=%d", req->inherit );
+}
+
+static void dump_open_named_obj_reply( struct open_named_obj_reply *req )
+{
+    printf( " handle=%d", req->handle );
+}
+
 struct dumper
 {
     void (*dump_req)();
@@ -142,6 +211,27 @@
     { (void(*)())dump_select_request,
       (void(*)())dump_select_reply,
       sizeof(struct select_request) },
+    { (void(*)())dump_create_event_request,
+      (void(*)())dump_create_event_reply,
+      sizeof(struct create_event_request) },
+    { (void(*)())dump_event_op_request,
+      (void(*)())0,
+      sizeof(struct event_op_request) },
+    { (void(*)())dump_create_mutex_request,
+      (void(*)())dump_create_mutex_reply,
+      sizeof(struct create_mutex_request) },
+    { (void(*)())dump_release_mutex_request,
+      (void(*)())0,
+      sizeof(struct release_mutex_request) },
+    { (void(*)())dump_create_semaphore_request,
+      (void(*)())dump_create_semaphore_reply,
+      sizeof(struct create_semaphore_request) },
+    { (void(*)())dump_release_semaphore_request,
+      (void(*)())dump_release_semaphore_reply,
+      sizeof(struct release_semaphore_request) },
+    { (void(*)())dump_open_named_obj_request,
+      (void(*)())dump_open_named_obj_reply,
+      sizeof(struct open_named_obj_request) },
 };
 
 static const char * const req_names[REQ_NB_REQUESTS] =
@@ -156,6 +246,13 @@
     "dup_handle",
     "open_process",
     "select",
+    "create_event",
+    "event_op",
+    "create_mutex",
+    "release_mutex",
+    "create_semaphore",
+    "release_semaphore",
+    "open_named_obj",
 };
 
 void trace_request( enum request req, void *data, int len, int fd )
diff --git a/tools/build.c b/tools/build.c
index 47d7ebd..f7b3885 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -862,7 +862,7 @@
     pSegment->size = max_code_offset;
     pSegment->flags = 0;
     pSegment->minsize = max_code_offset;
-    pSegment->selector = 0;
+    pSegment->hSeg = 0;
     pSegment++;
 
     pModule->dgroup_entry = (int)pSegment - (int)pModule;
@@ -870,7 +870,7 @@
     pSegment->size = max_data_offset;
     pSegment->flags = NE_SEGFLAGS_DATA;
     pSegment->minsize = max_data_offset;
-    pSegment->selector = 0;
+    pSegment->hSeg = 0;
     pSegment++;
 
       /* Resource table */
@@ -1656,7 +1656,7 @@
         fprintf( outfile, "\tmovl " PREFIX "ldt_copy(%%eax),%%eax\n" );
         fprintf( outfile, "\tmovl %%eax,-24(%%ebp)\n" );
         /* Add the offset */
-        fprintf( outfile, "\tleal -20(%%ebp),%%eax\n" );
+        fprintf( outfile, "\tleal -16(%%ebp),%%eax\n" );
         fprintf( outfile, "\taddl %%eax,-24(%%ebp)\n" );
     }
 
diff --git a/tools/fnt2bdf.c b/tools/fnt2bdf.c
index f678e85..9337127 100644
--- a/tools/fnt2bdf.c
+++ b/tools/fnt2bdf.c
@@ -351,14 +351,14 @@
 	/* Microsoft just had to invent its own charsets! */
 
 	case ANSI_CHARSET: 	fputs("ansi-0\n", fs); break;
-	case GREEK_CHARSET: 	fputs("cp125-3\n", fs); break;
-	case TURKISH_CHARSET: 	fputs("cp125-4\n", fs); break;
-	case HEBREW_CHARSET: 	fputs("cp125-5\n", fs); break;
-	case ARABIC_CHARSET: 	fputs("cp125-6\n", fs); break;
-	case BALTIC_CHARSET: 	fputs("cp125-7\n", fs); break;
-	case RUSSIAN_CHARSET: 	fputs("cp125-1\n", fs); break;
-	case EE_CHARSET: 	fputs("cp125-0\n", fs); break; 
-	case SYMBOL_CHARSET: 	fputs("misc-fontspecific\n", fs); break;
+	case GREEK_CHARSET: 	fputs("microsoft-cp1253\n", fs); break;
+	case TURKISH_CHARSET: 	fputs("microsoft-cp1254\n", fs); break;
+	case HEBREW_CHARSET: 	fputs("microsoft-cp1255\n", fs); break;
+	case ARABIC_CHARSET: 	fputs("microsoft-cp1256\n", fs); break;
+	case BALTIC_CHARSET: 	fputs("microsoft-cp1257\n", fs); break;
+	case RUSSIAN_CHARSET: 	fputs("microsoft-cp1251\n", fs); break;
+	case EE_CHARSET: 	fputs("microsoft-cp1250\n", fs); break; 
+	case SYMBOL_CHARSET: 	fputs("microsoft-symbol\n", fs); break;
 	case SHIFTJIS_CHARSET: 	fputs("jisx0208.1983-0\n", fs); break;
 	case DEFAULT_CHARSET:	fputs("iso8859-1\n", fs); break;
 
diff --git a/tools/testrun b/tools/testrun
index 7a52af2..665cbe2 100755
--- a/tools/testrun
+++ b/tools/testrun
@@ -96,15 +96,33 @@
 sub kill_subprocesses {
 	local($killedalready,%parentof,%kids,$changed,%cmdline);
 
-	# FIXME: Linux ps dependend...
+	# FIXME: substitute ps command that shows PID,PPID and COMMAND
+	# On Linux' latest procps this is "ps aulc"
 	#
-	open(PSAUX,"ps --format pid,ppid,comm|");
+	open(PSAUX,"ps aulc|");
 	# lookup all processes, remember their parents and cmdlines.
 	%parentof=();
-	while (<PSAUX>) {
-		if (/\s*(\d*)\s*(\d*)\s*(\S*)/) {
-			$parentof{$1}=$2;
-			$cmdline{$1}=$3;
+	$xline = <PSAUX>; # fmtline 
+	@psformat = split(/\s\s*/,$xline);
+
+	psline: while (<PSAUX>) {
+		chop;
+		@psline = split(/\s\s*/);
+		$pid=0;
+		for ($i=0;$i<=$#psformat;$i++) {
+			if ($psformat[$i] =~ /COMMAND/) {
+				die unless $pid;
+				$cmdline{$pid}=$psline[$i];
+				break;
+			}
+			if ($psformat[$i] =~ /PPID/ ) {
+				$parentof{$pid} = $psline[$i];
+				next;
+			}
+			if ($psformat[$i] =~ /PID/ ) {
+				$pid = $psline[$i];
+				next;
+			}
 		}
 	}
 	close(PSAUX);
diff --git a/win32/advapi.c b/win32/advapi.c
index 9110af8..656a601 100644
--- a/win32/advapi.c
+++ b/win32/advapi.c
@@ -162,7 +162,7 @@
 HANDLE32 WINAPI OpenSCManager32W( LPCWSTR lpMachineName, LPCWSTR lpDatabaseName,
                                   DWORD dwDesiredAccess )
 {
-    FIXME(advapi,"(%s,%s,%08lx): stub\n", debugstr_w(lpMachineName), 
+    FIXME(advapi,"(%s,%s,0x%08lx): stub\n", debugstr_w(lpMachineName), 
           debugstr_w(lpDatabaseName), dwDesiredAccess);
     return 1;
 }
diff --git a/win32/console.c b/win32/console.c
index 0c24ff6..88fd412 100644
--- a/win32/console.c
+++ b/win32/console.c
@@ -14,6 +14,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
+#include <sys/errno.h>
 #include <signal.h>
 #include <assert.h>
 #include "windows.h"
@@ -526,7 +527,7 @@
  */
 BOOL32 WINAPI SetConsoleMode( HANDLE32 hcon, DWORD mode )
 {
-    FIXME(console,"(%08x,%08lx): stub\n",hcon,mode);
+    FIXME(console,"(0x%08x,0x%08lx): stub\n",hcon,mode);
     return TRUE;
 }
 
diff --git a/win32/file.c b/win32/file.c
index 243c06d..e08475d 100644
--- a/win32/file.c
+++ b/win32/file.c
@@ -5,6 +5,7 @@
  */
 
 #include <errno.h>
+#include <sys/errno.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/types.h>
diff --git a/win32/kernel32.c b/win32/kernel32.c
index 1be5f93..160435e 100644
--- a/win32/kernel32.c
+++ b/win32/kernel32.c
@@ -356,7 +356,7 @@
 
     CONTEXT context16;
     DWORD i, argsize;
-    LPBYTE newstack;
+    LPBYTE newstack, oldstack;
     THDB *thdb = THREAD_Current();
 
     memcpy(&context16,context,sizeof(context16));
@@ -368,15 +368,17 @@
 
     argsize  = EBP_reg(context)-ESP_reg(context)-0x44;
     newstack = ((LPBYTE)THREAD_STACK16(thdb))-argsize;
+    oldstack = (LPBYTE)ESP_reg(context)+4;
 
-    memcpy( newstack, (LPBYTE)ESP_reg(context)+4, argsize );
+    memcpy( newstack, oldstack, argsize );
 
     for (i = 0; i < 32; i++)	/* NOTE: What about > 32 arguments? */
 	if (mapESPrelative & (1 << i))
 	{
 	    SEGPTR *arg = (SEGPTR *)(newstack + 2*i);
 	    *arg = PTR_SEG_OFF_TO_SEGPTR(SELECTOROF(thdb->cur_stack), 
-					 *(LPBYTE *)arg - newstack);
+                                         OFFSETOF(thdb->cur_stack) - argsize
+					 + (*(LPBYTE *)arg - oldstack));
 	}
 
     EAX_reg(context) = Callbacks->CallRegisterShortProc( &context16, argsize );
@@ -821,6 +823,16 @@
 }
 
 /**********************************************************************
+ *           SSInit		KERNEL.700
+ * RETURNS
+ *	TRUE for success.
+ */
+BOOL32 WINAPI SSInit()
+{
+    return TRUE;
+}
+
+/**********************************************************************
  *           SSOnBigStack	KERNEL32.87
  * Check if thunking is initialized (ss selector set up etc.)
  * We do that differently, so just return TRUE.
@@ -896,10 +908,19 @@
 }
 
 /**********************************************************************
- * 		KERNEL_619		(KERNEL)
+ * 		InitCBClient		(KERNEL.623)
+ */
+WORD WINAPI InitCBClient(DWORD x)
+{
+    FIXME(thunk,"(0x%08lx): stub\n",x);
+    return TRUE;
+}
+
+/**********************************************************************
+ * 		RegisterCBClient	(KERNEL.619)
  * Seems to store y and z depending on x in some internal lists...
  */
-WORD WINAPI _KERNEL_619(WORD x,DWORD y,DWORD z)
+WORD WINAPI RegisterCBClient(WORD x,DWORD y,DWORD z)
 {
     FIXME(thunk,"(0x%04x,0x%08lx,0x%08lx): stub\n",x,y,z);
     return x;
@@ -955,6 +976,17 @@
 }
 
 /**********************************************************************
+ * 		KERNEL_612		(KERNEL)
+ */
+BOOL16 WINAPI _KERNEL_612(LPBYTE target)
+{
+    return    target[ 0] == 0x66 && target[ 1] == 0x68 
+           && target[ 6] == 0x66 && target[ 2] == 0x68
+           && target[12] == 0x66 && target[13] == 0x58 
+           && target[14] == 0xCB;
+}
+
+/**********************************************************************
  *			AllocSLCallback		(KERNEL32)
  *
  * Win95 uses some structchains for callbacks. It allocates them
@@ -1019,39 +1051,10 @@
 
 
 /**********************************************************************
- * 		KERNEL_471		(KERNEL.471)
- * RETURNS
- * 	Seems to return the uncrypted current process pointer. [Not 100% sure].
- */
-LPVOID WINAPI
-_KERNEL_471() {
-	return PROCESS_Current();
-}
-
-/**********************************************************************
- * 		KERNEL_472		(KERNEL.472)
- * something like GetCurrenthInstance.
- * RETURNS
- *	the hInstance
- */
-VOID WINAPI
-_KERNEL_472(CONTEXT *context) {
-	FIXME(win32,"(0x%08lx): stub\n",EAX_reg(context));
-	if (!EAX_reg(context)) {
-		TDB *pTask = (TDB*)GlobalLock16(GetCurrentTask());
-		AX_reg(context)=pTask->hInstance;
-		return;
-	}
-	if (!HIWORD(EAX_reg(context)))
-		return; /* returns the passed value */
-	/* hmm ... fixme */
-}
-
-/**********************************************************************
- * 		KERNEL_475		(KERNEL.475)
+ * 		GetTEBSelectorFS	(KERNEL.475)
  * 	Set the 16-bit %fs to the 32-bit %fs (current TEB selector)
  */
-VOID WINAPI _KERNEL_475(CONTEXT *context) 
+VOID WINAPI GetTEBSelectorFS( CONTEXT *context ) 
 {
     GET_FS( FS_reg(context) );
 }
diff --git a/win32/ordinals.c b/win32/ordinals.c
index 5b7427a..97209df 100644
--- a/win32/ordinals.c
+++ b/win32/ordinals.c
@@ -26,7 +26,7 @@
 
 
 /***********************************************************************
- *           GetProcessDword    (KERNEL32.18)
+ *           GetProcessDword    (KERNEL32.18) (KERNEL.485)
  * 'Of course you cannot directly access Windows internal structures'
  */
 DWORD WINAPI GetProcessDword(DWORD processid,DWORD action)
@@ -99,6 +99,26 @@
 }
 
 /***********************************************************************
+ *           SetProcessDword    (KERNEL.484)
+ * 'Of course you cannot directly access Windows internal structures'
+ */
+VOID WINAPI SetProcessDword(DWORD processid,DWORD action,DWORD value)
+{
+	PDB32	*process = processid? PROCESS_IdToPDB( processid )
+                                    : PROCESS_Current();
+
+	action+=56;
+	TRACE(win32,"(%ld,%ld+0x38)\n",processid,action);
+	if (!process || action>56) return;
+
+	switch (action) {
+	default:
+		FIXME(win32,"Unknown offset (%ld)\n",action);
+                break;
+	}
+}
+
+/***********************************************************************
  *		GetWin16DOSEnv			(KERNEL32.34)
  * Returns some internal value.... probably the default environment database?
  */
diff --git a/win32/process.c b/win32/process.c
index 2e06bb4..f18817d 100644
--- a/win32/process.c
+++ b/win32/process.c
@@ -62,14 +62,49 @@
  *  ContinueDebugEvent [KERNEL32.146]
  */
 BOOL32 WINAPI ContinueDebugEvent(DWORD pid,DWORD tid,DWORD contstatus) {
-    FIXME(win32,"(%ld,%ld,%ld): stub\n",pid,tid,contstatus);
+    FIXME(win32,"(0x%lx,%ld,%ld): stub\n",pid,tid,contstatus);
 	return TRUE;
 }
 
 /*********************************************************************
+ *      Process_ClockTimeToFileTime
+ *      (olorin@fandra.org, 20-Sep-1998)
+ *      Converts clock_t into FILETIME.
+ *      Used by GetProcessTime.
+ *      Differences to UnixTimeToFileTime:
+ *          1) Divided by CLK_TCK
+ *          2) Time is relative. There is no 'starting date', so there is 
+ *             no need in offset correction, like in UnixTimeToFileTime
+ *      FIXME: This function should be moved to a more appropriate .c file
+ *      FIXME: On floating point operations, it is assumed that
+ *             floating values are truncated on convertion to integer.
+ */
+void Process_ClockTimeToFileTime( clock_t unix_time, LPFILETIME filetime )
+{
+    double td = (unix_time*10000000.0)/CLK_TCK;
+    /* Yes, double, because long int might overflow here. */
+#if (SIZEOF_LONG_LONG >= 8)
+    unsigned long long t = td;
+    filetime->dwLowDateTime  = (UINT32) t;
+    filetime->dwHighDateTime = (UINT32) (t >> 32);
+#else
+    double divider = 1. * (1 << 16) * (1 << 16);
+    filetime->dwHighDateTime = (UINT32) (td / divider);
+    filetime->dwLowDateTime  = (UINT32) (td - filetime->dwHighDateTime*divider);
+    /* using floor() produces wierd results, better leave this as it is 
+     * ( with (UINT32) convertion )
+     */
+#endif
+}
+
+/*********************************************************************
  *	GetProcessTimes				[KERNEL32.262]
  *
- * FIXME: implement this better ...
+ * FIXME: lpCreationTime, lpExitTime are NOT INITIALIZED.
+ * olorin@fandra.org: Would be nice to substract the cpu time,
+ *                    used by Wine at startup.
+ *                    Also, there is a need to separate times
+ *                    used by different applications.
  */
 BOOL32 WINAPI GetProcessTimes(
 	HANDLE32 hprocess,LPFILETIME lpCreationTime,LPFILETIME lpExitTime,
@@ -78,8 +113,8 @@
 	struct tms tms;
 
 	times(&tms);
-	DOSFS_UnixTimeToFileTime(tms.tms_utime,lpUserTime,0);
-	DOSFS_UnixTimeToFileTime(tms.tms_stime,lpKernelTime,0);
+        Process_ClockTimeToFileTime(tms.tms_utime,lpUserTime);
+        Process_ClockTimeToFileTime(tms.tms_stime,lpKernelTime);
 	return TRUE;
 }
 
diff --git a/win32/security.c b/win32/security.c
index 96a9496..8b10607 100644
--- a/win32/security.c
+++ b/win32/security.c
@@ -66,7 +66,7 @@
  *           GetSidLengthRequired  (ADVAPI.63)
  */
 DWORD WINAPI GetSidLengthRequired (BYTE nSubAuthorityCount) {
-    return sizeof (SID) + (nSubAuthorityCount - 1 * sizeof (DWORD));
+    return sizeof (SID) + (nSubAuthorityCount - 1) * sizeof (DWORD);
 }
 
 /***********************************************************************
@@ -124,7 +124,7 @@
 BOOL32 WINAPI InitializeSecurityDescriptor( SECURITY_DESCRIPTOR *pDescr,
                                             DWORD revision )
 {
-    FIXME(security, "(%p,%#lx): empty stub\n", pDescr, revision);
+    FIXME(security, "(%p,%#lx): stub\n", pDescr, revision);
     return TRUE;
 }
 
diff --git a/windows/Makefile.in b/windows/Makefile.in
index 6feb7a3..c2738c5 100644
--- a/windows/Makefile.in
+++ b/windows/Makefile.in
@@ -23,6 +23,7 @@
 	mdi.c \
 	message.c \
 	msgbox.c \
+	multimon.c \
 	nonclient.c \
 	painting.c \
 	property.c \
diff --git a/windows/clipboard.c b/windows/clipboard.c
index 8b0a51d..aa1f298 100644
--- a/windows/clipboard.c
+++ b/windows/clipboard.c
@@ -803,8 +803,7 @@
 {
     BOOL32 bRet = 0;
 
-    FIXME(clipboard, "(%04x, %04x) - stub?\n", 
-		      hWnd, hWndNext);
+    FIXME(clipboard, "(0x%04x, 0x%04x): stub?\n", hWnd, hWndNext);
 
     if( hWndViewer )
 	bRet = !SendMessage16( hWndViewer, WM_CHANGECBCHAIN,
diff --git a/windows/defdlg.c b/windows/defdlg.c
index ede0e09..16239e5 100644
--- a/windows/defdlg.c
+++ b/windows/defdlg.c
@@ -233,7 +233,7 @@
 /***********************************************************************
  *           DEFDLG_Epilog
  */
-static LRESULT DEFDLG_Epilog(DIALOGINFO* dlgInfo, UINT32 msg, BOOL16 fResult)
+static LRESULT DEFDLG_Epilog(DIALOGINFO* dlgInfo, UINT32 msg, BOOL32 fResult)
 {
     /* see SDK 3.1 */
 
@@ -253,7 +253,7 @@
                              LPARAM lParam )
 {
     DIALOGINFO * dlgInfo;
-    BOOL16 result = FALSE;
+    BOOL32 result = FALSE;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
     
     if (!wndPtr) return 0;
@@ -261,7 +261,7 @@
     dlgInfo->msgResult = 0;
 
     if (dlgInfo->dlgProc) 	/* Call dialog procedure */
-	result = (BOOL16)CallWindowProc16( (WNDPROC16)dlgInfo->dlgProc,
+	result = CallWindowProc16( (WNDPROC16)dlgInfo->dlgProc,
                                            hwnd, msg, wParam, lParam );
 
     /* Check if window was destroyed by dialog procedure */
@@ -308,7 +308,7 @@
                               WPARAM32 wParam, LPARAM lParam )
 {
     DIALOGINFO * dlgInfo;
-    BOOL16 result = FALSE;
+    BOOL32 result = FALSE;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
     
     if (!wndPtr) return 0;
@@ -316,7 +316,7 @@
     dlgInfo->msgResult = 0;
 
     if (dlgInfo->dlgProc)       /* Call dialog procedure */
-        result = (BOOL16)CallWindowProc32A( (WNDPROC32)dlgInfo->dlgProc,
+        result = CallWindowProc32A( (WNDPROC32)dlgInfo->dlgProc,
                                             hwnd, msg, wParam, lParam );
 
     /* Check if window was destroyed by dialog procedure */
@@ -363,7 +363,7 @@
                               LPARAM lParam )
 {
     DIALOGINFO * dlgInfo;
-    BOOL16 result = FALSE;
+    BOOL32 result = FALSE;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
     
     if (!wndPtr) return 0;
@@ -371,7 +371,7 @@
     dlgInfo->msgResult = 0;
 
     if (dlgInfo->dlgProc)       /* Call dialog procedure */
-        result = (BOOL16)CallWindowProc32W( (WNDPROC32)dlgInfo->dlgProc,
+        result = CallWindowProc32W( (WNDPROC32)dlgInfo->dlgProc,
                                             hwnd, msg, wParam, lParam );
 
     /* Check if window was destroyed by dialog procedure */
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 46117e7..cfc8683 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -86,7 +86,7 @@
 
     SetTextColor32( hDC, GetSysColor32(COLOR_WINDOWTEXT));
 
-    if (TWEAK_Win95Look) {
+    if (TWEAK_WineLook > WIN31_LOOK) {
 	if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX))
 	    SetBkColor32( hDC, GetSysColor32(COLOR_WINDOW) );
 	else {
@@ -107,7 +107,7 @@
 {
     BOOL32 bVisible = wndPtr->dwStyle & WS_VISIBLE;
 
-TRACE(win,"%04x %i\n", wndPtr->hwndSelf, (wParam!=0) );
+    TRACE(win,"%04x %i\n", wndPtr->hwndSelf, (wParam!=0) );
 
     if( wParam )
     {
@@ -153,7 +153,7 @@
 
     case WM_RBUTTONDOWN:
     case WM_NCRBUTTONDOWN:
-        if ((wndPtr->flags & WIN_ISWIN32) || TWEAK_Win95Look)
+        if ((wndPtr->flags & WIN_ISWIN32) || (TWEAK_WineLook > WIN31_LOOK))
         {
 	    ClientToScreen16(wndPtr->hwndSelf, (LPPOINT16)&lParam);
             SendMessage32A( wndPtr->hwndSelf, WM_CONTEXTMENU,
diff --git a/windows/dialog.c b/windows/dialog.c
index 691813e..49f42ce 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -5,11 +5,10 @@
  */
 
 #include <ctype.h>
-#include <errno.h>
+#include <sys/errno.h>
 #include <limits.h>
 #include <stdlib.h>
 #include <string.h>
-#include <errno.h>
 #include "windows.h"
 #include "dialog.h"
 #include "drive.h"
diff --git a/windows/keyboard.c b/windows/keyboard.c
index 5422700..9e7696a 100644
--- a/windows/keyboard.c
+++ b/windows/keyboard.c
@@ -1052,6 +1052,36 @@
 }
 
 /****************************************************************************
+ *	GetKeyboardLayoutName32A   (USER32.252)
+ */
+INT32 WINAPI GetKeyboardLayoutName32A(LPSTR pwszKLID)
+{
+	return GetKeyboardLayoutName16(pwszKLID);
+}
+
+/****************************************************************************
+ *	GetKeyboardLayoutName32W   (USER32.253)
+ */
+INT32 WINAPI GetKeyboardLayoutName32W(LPWSTR pwszKLID)
+{
+	LPSTR buf = HEAP_xalloc( GetProcessHeap(), 0, strlen("00000409")+1);
+	int res = GetKeyboardLayoutName32A(buf);
+	lstrcpyAtoW(pwszKLID,buf);
+	HeapFree( GetProcessHeap(), 0, buf );
+	return res;
+}
+
+/****************************************************************************
+ *	GetKeyboardLayoutName16   (USER.477)
+ */
+INT16 WINAPI GetKeyboardLayoutName16(LPSTR pwszKLID)
+{
+	FIXME(keyboard,"always returns primary U.S. English layout\n");
+	strcpy(pwszKLID,"00000409");
+	return 1;
+}
+
+/****************************************************************************
  *	GetKeyNameText32A   (USER32.247)
  */
 INT32 WINAPI GetKeyNameText32A(LONG lParam, LPSTR lpBuffer, INT32 nSize)
@@ -1304,9 +1334,7 @@
  *           RegisterHotKey			(USER32.433)
  */
 BOOL32 WINAPI RegisterHotKey(HWND32 hwnd,INT32 id,UINT32 modifiers,UINT32 vk) {
-	FIXME(keyboard,"(%08x,%d,%08x,%d): stub\n",
-		hwnd,id,modifiers,vk
-	);
+	FIXME(keyboard,"(0x%08x,%d,0x%08x,%d): stub\n",hwnd,id,modifiers,vk);
 	return TRUE;
 }
 
@@ -1314,6 +1342,140 @@
  *           UnregisterHotKey			(USER32.565)
  */
 BOOL32 WINAPI UnregisterHotKey(HWND32 hwnd,INT32 id) {
-	FIXME(keyboard,"(%08x,%d): stub\n",hwnd,id);
+	FIXME(keyboard,"(0x%08x,%d): stub\n",hwnd,id);
 	return TRUE;
 }
+
+/***********************************************************************
+ *           KeyboardInquire			(KEYBOARD.1)
+ */
+
+#pragma pack(1)
+typedef struct _KBINFO
+{
+    BYTE Begin_First_Range;
+    BYTE End_First_Range;
+    BYTE Begin_Second_Range;
+    BYTE End_Second_Range;
+    WORD StateSize;
+} KBINFO;
+#pragma pack(4)
+
+WORD WINAPI KeyboardInquire(KBINFO *kbInfo) 
+{
+    kbInfo->Begin_First_Range = 0;
+    kbInfo->End_First_Range = 0;
+    kbInfo->Begin_Second_Range = 0;
+    kbInfo->End_Second_Range = 0;
+    kbInfo->StateSize = 16; 
+
+    return sizeof(KBINFO);
+}
+
+/***********************************************************************
+ *           KeyboardEnable			(KEYBOARD.2)
+ */
+VOID WINAPI KeyboardEnable(FARPROC16 eventProc, LPBYTE lpKeyState)
+{
+    FIXME(keyboard, "(%08lx,%08lx): stub\n", 
+                    (DWORD)eventProc, (DWORD)lpKeyState);
+}
+
+/***********************************************************************
+ *           KeyboardDisable			(KEYBOARD.3)
+ */
+VOID WINAPI KeyboardDisable(VOID)
+{
+    FIXME(keyboard, "(): stub\n");
+}
+
+/***********************************************************************
+ *           MouseInquire			(MOUSE.1)
+ */
+
+#pragma pack(1)
+typedef struct _MOUSEINFO
+{
+    BYTE msExist;
+    BYTE msRelative;
+    WORD msNumButtons;
+    WORD msRate;
+    WORD msXThreshold;
+    WORD msYThreshold;
+    WORD msXRes;
+    WORD msYRes;
+    WORD msMouseCommPort;
+} MOUSEINFO;
+#pragma pack(4)
+
+WORD WINAPI MouseInquire(MOUSEINFO *mouseInfo) 
+{
+    mouseInfo->msExist = TRUE;
+    mouseInfo->msRelative = FALSE;
+    mouseInfo->msNumButtons = 2;
+    mouseInfo->msRate = 34;  /* the DDK says so ... */
+    mouseInfo->msMouseCommPort = 0;
+
+    return sizeof(MOUSEINFO);
+}
+
+/***********************************************************************
+ *           MouseEnable			(MOUSE.2)
+ */
+VOID WINAPI MouseEnable(FARPROC16 eventProc)
+{
+    FIXME(keyboard, "(%08lx): stub\n", (DWORD)eventProc);
+}
+
+/***********************************************************************
+ *           MouseDisable			(MOUSE.3)
+ */
+VOID WINAPI MouseDisable(VOID)
+{
+    FIXME(keyboard, "(): stub\n");
+}
+
+/***********************************************************************
+ *           DisplayInquire			(DISPLAY.101)
+ */
+
+#pragma pack(1)
+typedef struct _CURSORINFO
+{
+    WORD wXMickeys;
+    WORD wYMickeys;
+} CURSORINFO;
+#pragma pack(4)
+
+WORD WINAPI DisplayInquire(CURSORINFO *cursorInfo) 
+{
+    cursorInfo->wXMickeys = 1;
+    cursorInfo->wYMickeys = 1;
+
+    return sizeof(CURSORINFO);
+}
+
+/***********************************************************************
+ *           DisplaySetCursor			(DISPLAY.102)
+ */
+VOID WINAPI DisplaySetCursor( LPVOID cursorShape )
+{
+    FIXME(keyboard, "(%p): stub\n", cursorShape );
+}
+
+/***********************************************************************
+ *           DisplayMoveCursor			(DISPLAY.103)
+ */
+VOID WINAPI DisplayMoveCursor( WORD wAbsX, WORD wAbsY )
+{
+    FIXME(keyboard, "(%d,%d): stub\n", wAbsX, wAbsY );
+}
+
+/***********************************************************************
+ *           UserRepaintDisable			(DISPLAY.103)
+ */
+VOID WINAPI UserRepaintDisable( BOOL16 disable )
+{
+    FIXME(keyboard, "(%d): stub\n", disable);
+}
+
diff --git a/windows/message.c b/windows/message.c
index ea6c848..92189da 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -1899,21 +1899,41 @@
 
 /***********************************************************************
  *           SendNotifyMessageA    (USER32.460)
+ * FIXME
+ *  The message sended with PostMessage has to be put in the queue
+ *  with a higher priority as the other "Posted" messages.
+ *  QUEUE_AddMsg has to be modifyed.
  */
 LONG WINAPI SendNotifyMessage32A(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam)
-{
-	FIXME(msg,"(%04x,%08lx,%08lx,%08lx): stub!\n",
-	      hwnd,(long)msg,(long)wParam,lParam
-	);
-	return 0;
+{	BOOL32 ret = TRUE;
+	FIXME(msg,"(%04x,%08x,%08x,%08lx) not complete\n",
+	      hwnd, msg, wParam, lParam);
+	      
+	if ( GetCurrentThreadId() == GetWindowThreadProcessId ( hwnd, NULL))
+	{	ret=SendMessage32A ( hwnd, msg, wParam, lParam );
+	}
+	else
+	{	PostMessage32A ( hwnd, msg, wParam, lParam );
+	}
+	return ret;
 }
-
+/***********************************************************************
+ *           SendMessageCallBack32A
+ * FIXME: It's like PostMessage. The callback gets called when the message
+ * is processed. We have to modify the message processing for a exact
+ * implementation...
+ */
 BOOL32 WINAPI SendMessageCallBack32A(
 	HWND32 hWnd,UINT32 Msg,WPARAM32 wParam,LPARAM lParam,
-	/*SENDASYNCPROC*/FARPROC32 lpResultCallBack,DWORD dwData
-) {
+	FARPROC32 lpResultCallBack,DWORD dwData)
+{	
 	FIXME(msg,"(0x%04x,0x%04x,0x%08x,0x%08lx,%p,0x%08lx),stub!\n",
-		hWnd,Msg,wParam,lParam,lpResultCallBack,dwData
-	);
-	return FALSE;
+		hWnd,Msg,wParam,lParam,lpResultCallBack,dwData);
+	if ( hWnd == HWND_BROADCAST)
+	{	PostMessage32A( hWnd, Msg, wParam, lParam);
+		FIXME(msg,"Broadcast: Callback will not be called!\n");
+		return TRUE;
+	}
+	(lpResultCallBack)( hWnd, Msg, dwData, SendMessage32A ( hWnd, Msg, wParam, lParam ));
+		return TRUE;
 }
diff --git a/windows/msgbox.c b/windows/msgbox.c
index 831865f..0b74905 100644
--- a/windows/msgbox.c
+++ b/windows/msgbox.c
@@ -13,6 +13,7 @@
 #include "task.h"
 #include "debug.h"
 #include "debugstr.h"
+#include "tweak.h"
 
 /**************************************************************************
  *           MSGBOX_DlgProc
@@ -22,6 +23,7 @@
 static LRESULT CALLBACK MSGBOX_DlgProc( HWND32 hwnd, UINT32 message,
                                         WPARAM32 wParam, LPARAM lParam )
 {
+  static HFONT32 hFont = 0;
   LPMSGBOXPARAMS32A lpmb;
 
   RECT32 rect, textrect;
@@ -34,6 +36,18 @@
   switch(message) {
    case WM_INITDIALOG:
     lpmb = (LPMSGBOXPARAMS32A)lParam;
+    if (TWEAK_WineLook >= WIN95_LOOK) {
+	NONCLIENTMETRICS32A nclm;
+	INT32 i;
+	nclm.cbSize = sizeof(NONCLIENTMETRICS32A);
+	SystemParametersInfo32A (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
+	hFont = CreateFontIndirect32A (&nclm.lfMessageFont);
+        /* set button font */
+	for (i=1; i < 8; i++)
+	    SendDlgItemMessage32A (hwnd, i, WM_SETFONT, (WPARAM32)hFont, 0);
+        /* set text font */
+	SendDlgItemMessage32A (hwnd, 100, WM_SETFONT, (WPARAM32)hFont, 0);
+    }
     if (lpmb->lpszCaption) SetWindowText32A(hwnd, lpmb->lpszCaption);
     SetWindowText32A(GetDlgItem32(hwnd, 100), lpmb->lpszText);
     /* Hide not selected buttons */
@@ -166,9 +180,12 @@
      case IDIGNORE:
      case IDYES:
      case IDNO:
+      if ((TWEAK_WineLook > WIN31_LOOK) && hFont)
+        DeleteObject32 (hFont);
       EndDialog32(hwnd, wParam);
       break;
     }
+
    default:
      /* Ok. Ignore all the other messages */
      TRACE (dialog, "Message number %i is being ignored.\n", message);
@@ -190,6 +207,10 @@
 
 /**************************************************************************
  *           MessageBox32A   (USER32.391)
+ *
+ * NOTES
+ *   The WARN is here to help debug erroneous MessageBoxes
+ *   Use: -debugmsg warn+dialog,+relay
  */
 INT32 WINAPI MessageBox32A(HWND32 hWnd, LPCSTR text, LPCSTR title, UINT32 type)
 {
diff --git a/windows/multimon.c b/windows/multimon.c
new file mode 100644
index 0000000..e7a9ffa
--- /dev/null
+++ b/windows/multimon.c
@@ -0,0 +1,159 @@
+/*
+ * Multimonitor APIs
+ *
+ * Copyright 1998 Turchanov Sergey
+ */
+
+#include "windows.h"
+#include "multimon.h"
+
+
+#define xPRIMARY_MONITOR ((HMONITOR)0x12340042)
+
+HMONITOR WINAPI MonitorFromPoint(POINT32 ptScreenCoords, DWORD dwFlags)
+{
+    if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
+        ((ptScreenCoords.x >= 0) &&
+        (ptScreenCoords.x < GetSystemMetrics32(SM_CXSCREEN)) &&
+        (ptScreenCoords.y >= 0) &&
+        (ptScreenCoords.y < GetSystemMetrics32(SM_CYSCREEN))))
+    {
+        return xPRIMARY_MONITOR;
+    }
+        return NULL;
+}
+
+HMONITOR WINAPI MonitorFromRect(LPRECT32 lprcScreenCoords, DWORD dwFlags)
+{
+    if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
+        ((lprcScreenCoords->right > 0) &&
+        (lprcScreenCoords->bottom > 0) &&
+        (lprcScreenCoords->left < GetSystemMetrics32(SM_CXSCREEN)) &&
+        (lprcScreenCoords->top < GetSystemMetrics32(SM_CYSCREEN))))
+    {
+        return xPRIMARY_MONITOR;
+    }
+    return NULL;
+}
+
+HMONITOR WINAPI MonitorFromWindow(HWND32 hWnd, DWORD dwFlags)
+{
+    WINDOWPLACEMENT32 wp;
+
+    if (dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST))
+        return xPRIMARY_MONITOR;
+
+    if (IsIconic32(hWnd) ? 
+            GetWindowPlacement32(hWnd, &wp) : 
+            GetWindowRect32(hWnd, &wp.rcNormalPosition)) {
+
+        return MonitorFromRect(&wp.rcNormalPosition, dwFlags);
+    }
+
+    return NULL;
+}
+
+BOOL32 WINAPI GetMonitorInfo32A(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
+{
+    RECT32 rcWork;
+
+    if ((hMonitor == xPRIMARY_MONITOR) &&
+        lpMonitorInfo &&
+        (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
+        SystemParametersInfo32A(SPI_GETWORKAREA, 0, &rcWork, 0))
+    {
+        lpMonitorInfo->rcMonitor.left = 0;
+        lpMonitorInfo->rcMonitor.top  = 0;
+        lpMonitorInfo->rcMonitor.right  = GetSystemMetrics32(SM_CXSCREEN);
+        lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics32(SM_CYSCREEN);
+        lpMonitorInfo->rcWork = rcWork;
+        lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
+	
+	if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX32A))
+            lstrcpy32A(((MONITORINFOEX32A*)lpMonitorInfo)->szDevice, "DISPLAY");
+
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+BOOL32 WINAPI GetMonitorInfo32W(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
+{
+    RECT32 rcWork;
+
+    if ((hMonitor == xPRIMARY_MONITOR) &&
+        lpMonitorInfo &&
+        (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
+        SystemParametersInfo32W(SPI_GETWORKAREA, 0, &rcWork, 0))
+    {
+        lpMonitorInfo->rcMonitor.left = 0;
+        lpMonitorInfo->rcMonitor.top  = 0;
+        lpMonitorInfo->rcMonitor.right  = GetSystemMetrics32(SM_CXSCREEN);
+        lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics32(SM_CYSCREEN);
+        lpMonitorInfo->rcWork = rcWork;
+        lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
+
+        if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX32W))
+            lstrcpy32W(((MONITORINFOEX32W*)lpMonitorInfo)->szDevice, "D\0I\0S\0P\0L\0A\0Y\0\0");
+
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+BOOL32 WINAPI EnumDisplayMonitors(
+        HDC32             hdcOptionalForPainting,
+        LPRECT32         lprcEnumMonitorsThatIntersect,
+        MONITORENUMPROC lpfnEnumProc,
+        LPARAM          dwData)
+{
+    RECT32 rcLimit;
+
+    if (!lpfnEnumProc)
+        return FALSE;
+
+    rcLimit.left   = 0;
+    rcLimit.top    = 0;
+    rcLimit.right  = GetSystemMetrics32(SM_CXSCREEN);
+    rcLimit.bottom = GetSystemMetrics32(SM_CYSCREEN);
+
+    if (hdcOptionalForPainting)
+    {
+        RECT32    rcClip;
+        POINT32   ptOrg;
+
+        switch (GetClipBox32(hdcOptionalForPainting, &rcClip))
+        {
+        default:
+            if (!GetDCOrgEx(hdcOptionalForPainting, &ptOrg))
+                return FALSE;
+
+            OffsetRect32(&rcLimit, -ptOrg.x, -ptOrg.y);
+            if (IntersectRect32(&rcLimit, &rcLimit, &rcClip) &&
+                (!lprcEnumMonitorsThatIntersect ||
+                     IntersectRect32(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect))) {
+
+                break;
+            }
+            //fall thru
+        case NULLREGION:
+             return TRUE;
+        case ERROR:
+             return FALSE;
+        }
+    } else {
+        if (    lprcEnumMonitorsThatIntersect &&
+                !IntersectRect32(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect)) {
+
+            return TRUE;
+        }
+    }
+
+    return lpfnEnumProc(
+            xPRIMARY_MONITOR,
+            hdcOptionalForPainting,
+            &rcLimit,
+            dwData);
+}
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 82d779a..b5dbbcf 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -75,7 +75,7 @@
 static void NC_AdjustRect( LPRECT16 rect, DWORD style, BOOL32 menu,
                            DWORD exStyle )
 {
-    if(TWEAK_Win95Look)
+    if (TWEAK_WineLook > WIN31_LOOK)
 	ERR(nonclient, "Called in Win95 mode. Aiee! Please report this.\n" );
 
     if(style & WS_ICONIC) return;
@@ -217,13 +217,16 @@
 
 
 /***********************************************************************
- *           DrawCaptionTempA    (USER32.599)
+ * DrawCaptionTempA [USER32.599]
+ *
  */
-DWORD WINAPI DrawCaptionTemp32A(HWND32 hwnd,HDC32 hdc,LPRECT32 rect,
-    HFONT32 hfont,DWORD x1,LPCSTR str,DWORD x2)
+DWORD WINAPI
+DrawCaptionTemp32A (HWND32 hwnd, HDC32 hdc, LPRECT32 rect,
+		    HFONT32 hfont,DWORD x1,LPCSTR str,DWORD x2)
 {
-    FIXME(nonclient,"(%08x,%08x,%p,%08x,%08lx,\"%s\",%08lx): stub\n",
-        hwnd,hdc,rect,hfont,x1,str,x2);
+    FIXME (nonclient, "(%08x,%08x,%p,%08x,%08x,\"%s\",%08x): stub\n",
+	   hwnd, hdc, rect, hfont, x1, str, x2);
+
     return 0;
 }
 
@@ -265,12 +268,12 @@
                       rect->left, rect->top, rect->right, rect->bottom,
                       style, menu, exStyle );
 
-    if(TWEAK_Win95Look) {
+    if (TWEAK_WineLook == WIN31_LOOK)
+	NC_AdjustRect( rect, style, menu, exStyle );
+    else {
 	NC_AdjustRectOuter95( rect, style, menu, exStyle );
 	NC_AdjustRectInner95( rect, style, exStyle );
     }
-    else
-	NC_AdjustRect( rect, style, menu, exStyle );
 
     return TRUE;
 }
@@ -306,10 +309,10 @@
     if (pWnd->class->style & CS_HREDRAW) result |= WVR_HREDRAW;
 
     if( !( pWnd->dwStyle & WS_MINIMIZE ) ) {
-	if(TWEAK_Win95Look)
-	    NC_AdjustRectOuter95( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
-	else
+	if (TWEAK_WineLook == WIN31_LOOK)
 	    NC_AdjustRect( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
+	else
+	    NC_AdjustRectOuter95( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
 
 	winRect->left   -= tmpRect.left;
 	winRect->top    -= tmpRect.top;
@@ -329,7 +332,7 @@
 				       -tmpRect.left, -tmpRect.top ) + 1;
 	}
 
-	if (TWEAK_Win95Look) {
+	if (TWEAK_WineLook > WIN31_LOOK) {
 	    SetRect16 (&tmpRect, 0, 0, 0, 0);
 	    NC_AdjustRectInner95 (&tmpRect, pWnd->dwStyle, pWnd->dwExStyle);
 	    winRect->left   -= tmpRect.left;
@@ -359,7 +362,7 @@
 
     if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) return;
 
-      /* Remove frame from rectangle */
+    /* Remove frame from rectangle */
     if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
     {
 	InflateRect32( rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME);
@@ -397,7 +400,7 @@
 
     if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) return;
 
-      /* Remove frame from rectangle */
+    /* Remove frame from rectangle */
     if (HAS_FIXEDFRAME (wndPtr->dwStyle, wndPtr->dwExStyle ))
     {
 	InflateRect32( rect, -SYSMETRICS_CXFIXEDFRAME, -SYSMETRICS_CYFIXEDFRAME);
@@ -708,17 +711,17 @@
  * Handle a WM_NCHITTEST message. Called from DefWindowProc().
  */
 LONG
-NC_HandleNCHitTest( HWND32 hwnd , POINT16 pt)
+NC_HandleNCHitTest (HWND32 hwnd , POINT16 pt)
 {
-    WND* wndPtr = WIN_FindWndPtr( hwnd );
+    WND *wndPtr = WIN_FindWndPtr (hwnd);
 
     if (!wndPtr)
 	return HTERROR;
 
-    if(TWEAK_Win95Look)
-	return NC_DoNCHitTest95 (wndPtr, pt);
-    else
+    if (TWEAK_WineLook == WIN31_LOOK)
         return NC_DoNCHitTest (wndPtr, pt);
+    else
+	return NC_DoNCHitTest95 (wndPtr, pt);
 }
 
 
@@ -990,8 +993,8 @@
 {
     INT32 width, height;
 
-    if(TWEAK_Win95Look)
-	ERR(nonclient, "Called in Win95 mode. Aiee! Please report this.\n" );
+    if (TWEAK_WineLook != WIN31_LOOK)
+	ERR (nonclient, "Called in Win95 mode. Aiee! Please report this.\n" );
 
     if (dlgFrame)
     {
@@ -1545,10 +1548,10 @@
     {
 	if( wndPtr->dwStyle & WS_MINIMIZE )
 	    WINPOS_RedrawIconTitle( hwnd );
-	else if(TWEAK_Win95Look)
-	    NC_DoNCPaint95( wndPtr, clip, FALSE );
-	else
+	else if (TWEAK_WineLook == WIN31_LOOK)
 	    NC_DoNCPaint( wndPtr, clip, FALSE );
+	else
+	    NC_DoNCPaint95( wndPtr, clip, FALSE );
     }
     return 0;
 }
@@ -1573,10 +1576,10 @@
 
 	if( wndPtr->dwStyle & WS_MINIMIZE ) 
 	    WINPOS_RedrawIconTitle( wndPtr->hwndSelf );
-	else if( TWEAK_Win95Look )
-	    NC_DoNCPaint95( wndPtr, (HRGN32)1, FALSE );
-	else
+	else if (TWEAK_WineLook == WIN31_LOOK)
 	    NC_DoNCPaint( wndPtr, (HRGN32)1, FALSE );
+	else
+	    NC_DoNCPaint95( wndPtr, (HRGN32)1, FALSE );
     }
     return TRUE;
 }
@@ -1646,21 +1649,21 @@
 	  GetWindowRect32( wndPtr->hwndSelf, rect );
       else
       {
-          if(TWEAK_Win95Look)
-              NC_GetInsideRect95( wndPtr->hwndSelf, rect );
-          else
+          if (TWEAK_WineLook == WIN31_LOOK)
               NC_GetInsideRect( wndPtr->hwndSelf, rect );
+          else
+              NC_GetInsideRect95( wndPtr->hwndSelf, rect );
   	  OffsetRect32( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
   	  if (wndPtr->dwStyle & WS_CHILD)
      	      ClientToScreen32( wndPtr->parent->hwndSelf, (POINT32 *)rect );
-          if(TWEAK_Win95Look) {
-            rect->right = rect->left + sysMetrics[SM_CYCAPTION] - 1;
-            rect->bottom = rect->top + sysMetrics[SM_CYCAPTION] - 1;
-	  }
-	  else {
+          if (TWEAK_WineLook == WIN31_LOOK) {
             rect->right = rect->left + SYSMETRICS_CXSIZE;
             rect->bottom = rect->top + SYSMETRICS_CYSIZE;
 	  }
+	  else {
+            rect->right = rect->left + sysMetrics[SM_CYCAPTION] - 1;
+            rect->bottom = rect->top + sysMetrics[SM_CYCAPTION] - 1;
+	  }
       }
       return TRUE;
   }
@@ -1684,10 +1687,10 @@
     {
 	  /* Move pointer at the center of the caption */
 	RECT32 rect;
-        if(TWEAK_Win95Look)
-            NC_GetInsideRect95( wndPtr->hwndSelf, &rect );
-        else
+        if (TWEAK_WineLook == WIN31_LOOK)
             NC_GetInsideRect( wndPtr->hwndSelf, &rect );
+        else
+            NC_GetInsideRect95( wndPtr->hwndSelf, &rect );
 	if (wndPtr->dwStyle & WS_SYSMENU)
 	    rect.left += SYSMETRICS_CXSIZE + 1;
 	if (wndPtr->dwStyle & WS_MINIMIZEBOX)
@@ -1761,7 +1764,7 @@
  *
  * Perform SC_MOVE and SC_SIZE commands.
  */
-static void NC_DoSizeMove( HWND32 hwnd, WORD wParam, POINT16 pt )
+static void NC_DoSizeMove( HWND32 hwnd, WORD wParam )
 {
     MSG16 msg;
     RECT32 sizingRect, mouseRect;
@@ -1769,12 +1772,15 @@
     LONG hittest = (LONG)(wParam & 0x0f);
     HCURSOR16 hDragCursor = 0, hOldCursor = 0;
     POINT32 minTrack, maxTrack;
-    POINT16 capturePoint = pt;
+    POINT16 capturePoint, pt;
     WND *     wndPtr = WIN_FindWndPtr( hwnd );
     BOOL32    thickframe = HAS_THICKFRAME( wndPtr->dwStyle );
     BOOL32    iconic = wndPtr->dwStyle & WS_MINIMIZE;
     BOOL32    moved = FALSE;
 
+    GetCursorPos16 (&pt);
+    capturePoint = pt;
+
     if (IsZoomed32(hwnd) || !IsWindowVisible32(hwnd) ||
         (wndPtr->flags & WIN_MANAGED)) return;
 
@@ -1999,9 +2005,11 @@
 
     SetCapture32( hwnd );
     if (wParam == HTMINBUTTON)
-	paintButton = (TWEAK_Win95Look) ? &NC_DrawMinButton95 : &NC_DrawMinButton;
+	paintButton =
+	    (TWEAK_WineLook == WIN31_LOOK) ? &NC_DrawMinButton : &NC_DrawMinButton95;
     else
-	paintButton = (TWEAK_Win95Look) ? &NC_DrawMaxButton95 : &NC_DrawMaxButton;
+	paintButton =
+	    (TWEAK_WineLook == WIN31_LOOK) ? &NC_DrawMaxButton : &NC_DrawMaxButton95;
 
     (*paintButton)( hwnd, hdc, TRUE );
 
@@ -2145,10 +2153,10 @@
 	     if( !(pWnd->dwStyle & WS_MINIMIZE) )
 	     {
 		HDC32 hDC = GetWindowDC32(hwnd);
-		if( TWEAK_Win95Look)
-		    NC_DrawSysButton95( hwnd, hDC, TRUE );
-		else
+		if (TWEAK_WineLook == WIN31_LOOK)
 		    NC_DrawSysButton( hwnd, hDC, TRUE );
+		else
+		    NC_DrawSysButton95( hwnd, hDC, TRUE );
 		ReleaseDC32( hwnd, hDC );
 	     }
 	     SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
@@ -2173,7 +2181,7 @@
 	break;
 
     case HTCLOSE:
-	if (TWEAK_Win95Look)
+	if (TWEAK_WineLook >= WIN95_LOOK)
 	    NC_TrackCloseButton95 (hwnd, wParam);
 	break;
 
@@ -2263,7 +2271,7 @@
     {
     case SC_SIZE:
     case SC_MOVE:
-	NC_DoSizeMove( hwnd, wParam, pt );
+	NC_DoSizeMove( hwnd, wParam );
 	break;
 
     case SC_MINIMIZE:
@@ -2309,7 +2317,7 @@
     case SC_ARRANGE:
     case SC_NEXTWINDOW:
     case SC_PREVWINDOW:
- 	/* FIXME: unimplemented */
+ 	FIXME (nonclient, "unimplemented!\n");
         break;
     }
     return 0;
diff --git a/windows/syscolor.c b/windows/syscolor.c
index c3c10b3..d8db19c 100644
--- a/windows/syscolor.c
+++ b/windows/syscolor.c
@@ -39,7 +39,11 @@
     "3DDarkShadow", "32 32 32",      /* COLOR_3DDKSHADOW          */
     "3DLight", "192 192 192",        /* COLOR_3DLIGHT             */
     "InfoText", "0 0 0",             /* COLOR_INFOTEXT            */
-    "InfoBackground", "255 255 192"  /* COLOR_INFOBK              */
+    "InfoBackground", "255 255 192", /* COLOR_INFOBK              */
+    "AlternateButtonFace", "184 180 184",  /* COLOR_ALTERNATEBTNFACE */
+    "HotTrackingColor", "0 0 255",         /* COLOR_HOTLIGHT */
+    "GradientActiveTitle", "16 132 208",   /* COLOR_GRADIENTACTIVECAPTION */
+    "GradientInactiveTitle", "184 180 184" /* COLOR_GRADIENTINACTIVECAPTION */
 };
 
 static const char * const DefSysColors95[] =
@@ -68,11 +72,15 @@
     "3DDarkShadow", "0 0 0",         /* COLOR_3DDKSHADOW          */
     "3DLight", "223 223 223",        /* COLOR_3DLIGHT             */
     "InfoText", "0 0 0",             /* COLOR_INFOTEXT            */
-    "InfoBackground", "255 255 192"  /* COLOR_INFOBK              */
+    "InfoBackground", "255 255 192", /* COLOR_INFOBK              */
+    "AlternateButtonFace", "184 180 184",  /* COLOR_ALTERNATEBTNFACE */
+    "HotTrackingColor", "0 0 255",         /* COLOR_HOTLIGHT */
+    "GradientActiveTitle", "16 132 208",   /* COLOR_GRADIENTACTIVECAPTION */
+    "GradientInactiveTitle", "184 180 184" /* COLOR_GRADIENTINACTIVECAPTION */
 };
 
 
-#define NUM_SYS_COLORS     (COLOR_INFOBK+1)
+#define NUM_SYS_COLORS     (COLOR_GRADIENTINACTIVECAPTION+1)
 
 static COLORREF SysColors[NUM_SYS_COLORS];
 static HBRUSH32 SysColorBrushes[NUM_SYS_COLORS];
@@ -104,8 +112,8 @@
     const char * const *p;
     char buffer[100];
 
-    for (i = 0, p = TWEAK_Win95Look ? DefSysColors95 : DefSysColors;
-	 i < NUM_SYS_COLORS; i++, p += 2)
+    p = (TWEAK_WineLook == WIN31_LOOK) ? DefSysColors : DefSysColors95;
+    for (i = 0; i < NUM_SYS_COLORS; i++, p += 2)
     {
 	GetProfileString32A( "colors", p[0], p[1], buffer, 100 );
 	if (sscanf( buffer, " %d %d %d", &r, &g, &b ) != 3) r = g = b = 0;
diff --git a/windows/sysmetrics.c b/windows/sysmetrics.c
index 4411e0c..7acd305 100644
--- a/windows/sysmetrics.c
+++ b/windows/sysmetrics.c
@@ -27,7 +27,7 @@
     sysMetrics[SM_CXVSCROLL] =
 	PROFILE_GetWineIniInt("Tweak.Layout", "ScrollBarWidth", 16) + 1;
     sysMetrics[SM_CYHSCROLL] = sysMetrics[SM_CXVSCROLL];
-    if (TWEAK_Win95Look)
+    if (TWEAK_WineLook > WIN31_LOOK)
 	sysMetrics[SM_CYCAPTION] =
 	    PROFILE_GetWineIniInt("Tweak.Layout", "CaptionHeight", 19);
     else
@@ -37,13 +37,13 @@
     sysMetrics[SM_CYBORDER] = sysMetrics[SM_CXBORDER];
     sysMetrics[SM_CXDLGFRAME] =
 	PROFILE_GetWineIniInt("Tweak.Layout", "DialogFrameWidth",
-			      TWEAK_Win95Look ? 3 : 4);
+			      (TWEAK_WineLook > WIN31_LOOK) ? 3 : 4);
     sysMetrics[SM_CYDLGFRAME] = sysMetrics[SM_CXDLGFRAME];
     sysMetrics[SM_CYVTHUMB] = sysMetrics[SM_CXVSCROLL] - 1;
     sysMetrics[SM_CXHTHUMB] = sysMetrics[SM_CYVTHUMB];
     sysMetrics[SM_CXICON] = 32;
     sysMetrics[SM_CYICON] = 32;
-    if (TWEAK_Win95Look)
+    if (TWEAK_WineLook > WIN31_LOOK)
 	sysMetrics[SM_CYMENU] =
 	    PROFILE_GetWineIniInt("Tweak.Layout", "MenuHeight", 19);
     else
@@ -68,8 +68,8 @@
     sysMetrics[SM_RESERVED4] = 0;
 
     /* FIXME: The following two are calculated, but how? */
-    sysMetrics[SM_CXMIN] = TWEAK_Win95Look ? 112 : 100;
-    sysMetrics[SM_CYMIN] = TWEAK_Win95Look ? 27 : 28;
+    sysMetrics[SM_CXMIN] = (TWEAK_WineLook > WIN31_LOOK) ? 112 : 100;
+    sysMetrics[SM_CYMIN] = (TWEAK_WineLook > WIN31_LOOK) ? 27 : 28;
 
     sysMetrics[SM_CXSIZE] = sysMetrics[SM_CYCAPTION] - 2;
     sysMetrics[SM_CYSIZE] = sysMetrics[SM_CXSIZE];
@@ -139,6 +139,13 @@
     sysMetrics[SM_MIDEASTENABLED] = 0;
 
     sysMetrics[SM_MOUSEWHEELPRESENT] = 0;
+    
+    sysMetrics[SM_CXVIRTUALSCREEN] = sysMetrics[SM_CXSCREEN];
+    sysMetrics[SM_CYVIRTUALSCREEN] = sysMetrics[SM_CYSCREEN];
+    sysMetrics[SM_XVIRTUALSCREEN] = 0;
+    sysMetrics[SM_YVIRTUALSCREEN] = 0;
+    sysMetrics[SM_CMONITORS] = 1;
+    sysMetrics[SM_SAMEDISPLAYFORMAT] = 1;
     sysMetrics[SM_CMETRICS] = SM_CMETRICS;
 }
 
@@ -148,8 +155,7 @@
  */
 INT16 WINAPI GetSystemMetrics16( INT16 index )
 {
-    if ((index < 0) || (index > SM_CMETRICS)) return 0;
-    else return sysMetrics[index];    
+    return (INT16)GetSystemMetrics32(index);
 }
 
 
diff --git a/windows/user.c b/windows/user.c
index 46bfd5b..a54d34d 100644
--- a/windows/user.c
+++ b/windows/user.c
@@ -143,7 +143,7 @@
 
     /* Hack: restore the divide-by-zero handler */
     /* FIXME: should set a USER-specific handler that displays a msg box */
-    INT_SetHandler( 0, INT_GetHandler( 0xff ) );
+    INT_SetPMHandler( 0, INT_GetPMHandler( 0xff ) );
 
       /* Create task message queue */
     queueSize = GetProfileInt32A( "windows", "DefaultQueueSize", 8 );
diff --git a/windows/win.c b/windows/win.c
index 575457b..a7dfa12 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -1554,6 +1554,12 @@
  *	     WIN_SetWindowLong
  *
  * Helper function for SetWindowLong().
+ *
+ * 0 is the failure code. However, in the case of failure SetLastError
+ * must be set to distinguish between a 0 return value and a failure.
+ *
+ * FIXME: The error values for SetLastError may not be right. Can
+ *        someone check with the real thing?
  */
 static LONG WIN_SetWindowLong( HWND32 hwnd, INT32 offset, LONG newval,
                                WINDOWPROCTYPE type )
@@ -1563,12 +1569,23 @@
     STYLESTRUCT style;
     
     TRACE(win,"%x=%p %x %lx %x\n",hwnd, wndPtr, offset, newval, type);
-    if (!wndPtr) return 0;
+
+    if (!wndPtr)
+    {
+       /* Is this the right error? */
+       SetLastError( ERROR_INVALID_WINDOW_HANDLE );
+       return 0;
+    }
+
     if (offset >= 0)
     {
         if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
         {
             WARN( win, "Invalid offset %d\n", offset );
+
+            /* Is this the right error? */
+            SetLastError( ERROR_OUTOFMEMORY );
+
             return 0;
         }
         ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
@@ -1594,32 +1611,36 @@
 						type, WIN_PROC_WINDOW );
 		return retval;
 	case GWL_STYLE:
-		if (wndPtr->flags & WIN_ISWIN32)
-		{	style.styleOld = wndPtr->dwStyle;
-			newval &= ~(WS_VISIBLE | WS_CHILD);	/* Some bits can't be changed this way */
-			style.styleNew = newval | (style.styleOld & (WS_VISIBLE | WS_CHILD));
+	       	style.styleOld = wndPtr->dwStyle;
+		newval &= ~(WS_VISIBLE | WS_CHILD);	/* Some bits can't be changed this way */
+		style.styleNew = newval | (style.styleOld & (WS_VISIBLE | WS_CHILD));
 
+		if (wndPtr->flags & WIN_ISWIN32)
 			SendMessage32A(hwnd,WM_STYLECHANGING,GWL_STYLE,(LPARAM)&style);
-			wndPtr->dwStyle = style.styleNew;
+		wndPtr->dwStyle = style.styleNew;
+		if (wndPtr->flags & WIN_ISWIN32)
 			SendMessage32A(hwnd,WM_STYLECHANGED,GWL_STYLE,(LPARAM)&style);
-			UpdateWindow32(hwnd);
-			return style.styleOld;
-		}
+		return style.styleOld;
+		    
         case GWL_USERDATA: 
 		ptr = &wndPtr->userdata; 
 		break;
         case GWL_EXSTYLE:  
+	        style.styleOld = wndPtr->dwExStyle;
+		style.styleNew = newval;
 		if (wndPtr->flags & WIN_ISWIN32)
-		{	style.styleOld = wndPtr->dwExStyle;
-			style.styleNew = newval;
 			SendMessage32A(hwnd,WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&style);
-			wndPtr->dwExStyle = newval;
+		wndPtr->dwExStyle = newval;
+		if (wndPtr->flags & WIN_ISWIN32)
 			SendMessage32A(hwnd,WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&style);
-			UpdateWindow32(hwnd);
-			return style.styleOld;
-		}
+		return style.styleOld;
+
 	default:
             WARN( win, "Invalid offset %d\n", offset );
+
+            /* Don't think this is right error but it should do */
+            SetLastError( ERROR_OUTOFMEMORY );
+
             return 0;
     }
     retval = *ptr;
diff --git a/windows/winpos.c b/windows/winpos.c
index d1bbd21..2c3de3f 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -223,14 +223,15 @@
 /***********************************************************************
  *           GetWindowRect32   (USER32.308)
  */
-void WINAPI GetWindowRect32( HWND32 hwnd, LPRECT32 rect ) 
+BOOL32 WINAPI GetWindowRect32( HWND32 hwnd, LPRECT32 rect ) 
 {
     WND * wndPtr = WIN_FindWndPtr( hwnd ); 
-    if (!wndPtr) return;
+    if (!wndPtr) return FALSE;
     
     *rect = wndPtr->rectWindow;
     if (wndPtr->dwStyle & WS_CHILD)
 	MapWindowPoints32( wndPtr->parent->hwndSelf, 0, (POINT32 *)rect, 2 );
+    return TRUE;
 }
 
 
diff --git a/windows/winproc.c b/windows/winproc.c
index c813860..cb8e9f1 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -13,6 +13,7 @@
 #include "win.h"
 #include "winproc.h"
 #include "debug.h"
+#include "spy.h"
 
 /* Window procedure 16-to-32-bit thunk,
  * see BuildSpec16Files() in tools/build.c */
@@ -113,8 +114,8 @@
 static LRESULT WINPROC_CallWndProc32( WNDPROC32 proc, HWND32 hwnd, UINT32 msg,
                                       WPARAM32 wParam, LPARAM lParam )
 {
-    TRACE(relay, "(wndproc=%p,hwnd=%08x,msg=%08x,wp=%08x,lp=%08lx)\n",
-                   proc, hwnd, msg, wParam, lParam );
+    TRACE(relay, "(wndproc=%p,hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
+                   proc, hwnd, SPY_GetMsgName(msg), wParam, lParam );
     return proc( hwnd, msg, wParam, lParam );
 }
 
@@ -441,7 +442,7 @@
     case WM_PAINTCLIPBOARD:
     case WM_SIZECLIPBOARD:
     case WM_WININICHANGE:
-        TRACE(msg, "message %04x needs translation\n", msg );
+        TRACE(msg, "message %s needs translation\n", SPY_GetMsgName(msg) );
         return -1;
     default:  /* No translation needed */
         return 0;
diff --git a/wine.ini b/wine.ini
index 32f0b71..60beafb 100644
--- a/wine.ini
+++ b/wine.ini
@@ -76,4 +76,5 @@
 Exclude=WM_SIZE;WM_TIMER;
 
 [Tweak.Layout]
-;Win95Look=true
+;; WineLook=xxx  (supported styles are 'Win31'(default), 'Win95', 'Win98')
+;WineLook=Win95