Release 950522

Sun May 21 12:30:30 1995  Alexandre Julliard  (julliard@sunsite.unc.edu)

	* [debugger/hash.c] [debugger/info.c]
	Added support for symbolic segmented addresses. Add symbols for all
	built-in API entry points.

	* [if1632/relay.c] [include/dlls.h]
	Removed dll_table structure, as we now use the built-in module
	structures.

	* [if1632/relay.c] [loader/main.c]
	Removed winestat option, as it was no longer very meaningful.

	* [include/stackframe.h]
	New macro MAKE_SEGPTR that creates a segmented pointer to a local
	variable on the 32-bit stack.

	* [loader/module.c]
	Added support for multiple instances of an application.
	Implemented LoadModule() and FreeModule().

	* [loader/ne_image.c] [loader/task.c]
	Moved initialisation of built-in DLLs to InitTask().

	* [memory/global.c]
	Implemented discardable blocks.

	* [misc/file.c]
	Search path of current executable in OpenFile().
	Fixed bug with searching in Windows path.

	* [misc/lstr.c]
	Hard-coded translation tables for Ansi<->Oem.

	* [misc/user.c]
	Moved some global initializations to InitApp(), because they need
	a task context to be performed.

	* [objects/dc.c]
	Handle R2_BLACK and R2_WHITE specially so that they work correctly
	with palette displays.

	* [tools/build.c]
	Suppressed generation of the C file for DLL specs, because it's no
	longer needed. Output all the assembly code directly to stdout.
	Some changes to integrate Win32 support from Martin von	Loewis. 

	* [windows/msgbox.c]
	Moved message box code from misc/ to windows/.

Mon May 15 23:40:04 1995  Martin Ayotte (wine@trgcorp.mksinfo.qc.ca)

	* [misc/audio.c] [misc/mcicda.c] [misc/mcianim.c] [misc/midi.c]
	  [misc/mmaux.c] [misc/mmsystem.c]
	Modify code & use pointers conversion macros.
	Make cdaudio & wave devices work again (only using some applets).

	* [misc/profile.c]
	Change getc() to fgetc() where needed.

Mon May 15 22:10:56 1995  Martin von Loewis  <loewis@informatik.hu-berlin.de>

	* [if1632/Imakefile]
	added entries for the new files gdi32.spec, kernel32.spec,
	user32.spec, shell32.spec and winprocs32.spec.

	* [if1632/commdlg.spec][if1632/kernel.spec][if1632/shell.spec]
	  [if1632/storage.spec][if1632/system.spec][if1632/user.spec]
	ChooseFont, RESERVED5, InternalExtractIcon: Marked as stubs
	ExtractAssociatedIcon, DoEnvironmentSubst, DumpIcon:
		stub implementations provided 
	marked storage.dll,storege.sys functions as stubs

	* [include/pe_image.h]
	Added structures WIN32_builtin and  WIN32_function

	* [include/peexe.h]
	PE_Import_Directory: renamed reserved fields to 
		TimeDate, Forwarder, Thunk_List

	* [include/winerror.h]
	New file.

	* [loader/main.c]
	called RELAY32_Init

	* [loader/pe_image.c]
	xmmap: map BSS anonymous
	dump_imports: renamed to fixup_imports, do the fixup of imported
	              symbols
	PE_LoadImage: pass raw data size to xmmap

	* [loader/resource.c]
	DumpIcon: new function

	* [misc/kernel32.c]
	New file.

	* [misc/main.c]
	make stdout and stderr unbuffered

	* [misc/shell.c]
	DoEnvironmentSubst: new function

	* [objects/font.c]
	FONT_MatchFont: try oblique if there is no italic

	* [rc/Imakefile][rc/parser.l]
	yywrap: new function
	Don't link with libfl.a on Linux

	* [tools/build.c]
	Added keywords stdcall, subsystem, base
	GenerateForWin32: new function
	BuildSpecFiles: call GenerateForWin32 if subsystem is win32

Mon May 15 10:38:14 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
        
        * [controls/listbox.c] [controls/combo.c] [windows/defwnd.c]
	Minor fixes.
	
	* [misc/message.c] [misc/main.c] [rc/sysres*.rc] [include/texts.h]
	Rewrote message box handling.
	
	* [windows/dialog.c]
	Dialogs should be invisible until after WM_INITDIALOG is seent.
	Don't switch to invisible dialog items on a TAB keypress.
	
	* [windows/mdi.c]
	Send WM_NCPAINT message in MDIRestoreChild().
	
	* [windows/painting.c]
	Fixed typo (&& -> &).
	
	* [windows/message.c] [if1632/user.spec]
	Implemented PostAppMessage().
	
	* [windows/event.c]
	SetCapture(0) should act like ReleaseCapture().

Tue May  9 11:55:52 1995     Eddie C. Dost             (ecd@dressler.de)

	* [Imakefile]
	Changed CDEBUGFLAGS for systems running __ELF__ (temporarily)
	Added ASFLAGS to exported variables.

	* [debugger/readline/Imakefile]
	Moved defines for libreadline from DEFINES to EXTRA_DEFINES

	* [memory/local.c] [miscemu/int21.c]
	Added some more debugging outputs.

Mon May  8 00:55:27 MET DST 1995	  Dag Asheim (dash@ifi.uio.no)

	* [misc/message.c]
	Fixed a "FIXME" concerning norwegian translation.

Sun May  7 23:25:23 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
        
	* [*/*]
        Removed warnings in a couple of files and deleted some obsolete code.

        * [controls/listbox.c]
        Cleanup, speed improvements & lots of bug fixes.

        * [controls/combo.c]
	Mostly rewritten. This is still very buggy, but not quite as bad as 
	before.

        * [include/commdlg.h] [misc/commdlg.c]
        Removed the need for sysres.dll. Small bug fixes.
	
        * [objects/oembitmap.c] [include/bitmaps/<many>] [include/windows.h]
          [loader/library.c] [loader/main.c] [rc/sysres*.rc]
        Removed sysres.dll and replaced the remaining bitmaps/icons with
        XPM equivalents.

        * [misc/message.c] [windows/nonclient.c] [misc/main.c]
          [if1632/winprocs.spec]
        "About Wine..." now brings up a standard ShellAbout() window with
        the Wine icon and the list of contributors.
	
	* [misc/shell.c]
	Fixed ShellAbout()/AboutDialogProc() to show the right icon.

	* [windows/event.c]
	Small hack for non-alphanumeric keys: Dont't send the ascii value in
	the WM_KEYDOWN message, but some unused code instead. Should be done
	properly by sending different codes for each key. The edit control
	used to get a VK_DELETE message each time the user typed '.'.

	* [windows/class.c]
	Removed a check for CS_GLOBALCLASS in CLASS_FindClassByName().
	This used to be no problem, but breaks Resource Workshop in 950403.
	
	* [objects/dib.c]
	New diagnostic for a bug I've been encountering. If it shows up,
	please report it.

Sun May  7 23:11:18 EDT 1995  William Magro (wmagro@tc.cornell.edu)

	* [objects/color.c]
	Handle situation when 'dc' exists, but palette mapping
	does not.  (Fixes kidpix2 demo.)

Sun May  7 03:32:00 1995  Charles M. Hannum  (mycroft@mit.edu)

	* [loader/ldt.c]
	LDT_Print: Only show the number of entries that the kernel
	returned. Make this work for NetBSD.

Fri May  5 02:53:26 1995  Charles M. Hannum  (mycroft@mit.edu)

	* [debugger/dbg.y] [include/wine.h] [loader/signal.c]
	Modify cs and ds selector values for NetBSD-current.

	* [debugger/debug.l]
	$sp, $esp: Use RN_ESP_AT_SIGNAL rather than RN_ESP.

	* [debugger/regpos.h]
	Modify sigcontext format for NetBSD-current.
	SC_ESP: Use RN_ESP_AT_SIGNAL rather than RN_ESP.

	* [include/ldt.h]
	SELECTOR_TO_ENTRY: Explicitly clear the top half of the selector
	value, since only 16 bits of it may have been saved.

	* [misc/winsocket.c]
	Set structure packing with `#pragma pack' to accomodate
	other/older compilers.

Tue May  2 18:15:01 1995 Paal Beyer (beyer@idt.unit.no)
	
	* [misc/commdlg.c]
	Fixed path-names so when changing directory the listboxes
	changes too.
	
	* [debugger/dbg.y debugger/debug.l wine.ini]
	Added SymbolTableFile to wine.ini so symbols can be read
	without standing in the directory containing wine.sym.
	Added the possibility to specify full name of wine.sym from
	the debugger prompt.
diff --git a/ANNOUNCE b/ANNOUNCE
index 4b746f9..03f377e 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,14 +1,15 @@
-This is release 950430 of Wine the MS Windows emulator.  This is still a
+This is release 950522 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.
 
 Patches should be submitted to "wine-new@amscons.com".  Please don't forget
 to include a ChangeLog entry.  I'll make a new release every other Sunday.
 
-WHAT'S NEW with Wine-950430: (see ChangeLog for details)
-	- Preliminary multitasking support.
-	- Better DOS drives support.
-	- Stubs for DDEML library.
+WHAT'S NEW with Wine-950522: (see ChangeLog for details)
+	- Preliminary Win32 support.
+	- Multimedia code works better.
+	- Better message boxes, listboxes and combos.
+	- SYSRES.DLL is no longer needed.
 	- 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:
 
-    sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950430.tar.gz
-    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950430.tar.gz
-    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-950430.tar.gz
-    ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950430.tar.gz
+    sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950522.tar.gz
+    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950522.tar.gz
+    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-950522.tar.gz
+    ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950522.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/ChangeLog b/ChangeLog
index 784fd76..fb55ccd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,248 @@
 ----------------------------------------------------------------------
+Sun May 21 12:30:30 1995  Alexandre Julliard  (julliard@sunsite.unc.edu)
+
+	* [debugger/hash.c] [debugger/info.c]
+	Added support for symbolic segmented addresses. Add symbols for all
+	built-in API entry points.
+
+	* [if1632/relay.c] [include/dlls.h]
+	Removed dll_table structure, as we now use the built-in module
+	structures.
+
+	* [if1632/relay.c] [loader/main.c]
+	Removed winestat option, as it was no longer very meaningful.
+
+	* [include/stackframe.h]
+	New macro MAKE_SEGPTR that creates a segmented pointer to a local
+	variable on the 32-bit stack.
+
+	* [loader/module.c]
+	Added support for multiple instances of an application.
+	Implemented LoadModule() and FreeModule().
+
+	* [loader/ne_image.c] [loader/task.c]
+	Moved initialisation of built-in DLLs to InitTask().
+
+	* [memory/global.c]
+	Implemented discardable blocks.
+
+	* [misc/file.c]
+	Search path of current executable in OpenFile().
+	Fixed bug with searching in Windows path.
+
+	* [misc/lstr.c]
+	Hard-coded translation tables for Ansi<->Oem.
+
+	* [misc/user.c]
+	Moved some global initializations to InitApp(), because they need
+	a task context to be performed.
+
+	* [objects/dc.c]
+	Handle R2_BLACK and R2_WHITE specially so that they work correctly
+	with palette displays.
+
+	* [tools/build.c]
+	Suppressed generation of the C file for DLL specs, because it's no
+	longer needed. Output all the assembly code directly to stdout.
+	Some changes to integrate Win32 support from Martin von	Loewis. 
+
+	* [windows/msgbox.c]
+	Moved message box code from misc/ to windows/.
+
+Mon May 15 23:40:04 1995  Martin Ayotte (wine@trgcorp.mksinfo.qc.ca)
+
+	* [misc/audio.c] [misc/mcicda.c] [misc/mcianim.c] [misc/midi.c]
+	  [misc/mmaux.c] [misc/mmsystem.c]
+	Modify code & use pointers conversion macros.
+	Make cdaudio & wave devices work again (only using some applets).
+
+	* [misc/profile.c]
+	Change getc() to fgetc() where needed.
+
+Mon May 15 22:10:56 1995  Martin von Loewis  <loewis@informatik.hu-berlin.de>
+
+	* [if1632/Imakefile]
+	added entries for the new files gdi32.spec, kernel32.spec,
+	user32.spec, shell32.spec and winprocs32.spec.
+
+	* [if1632/commdlg.spec][if1632/kernel.spec][if1632/shell.spec]
+	  [if1632/storage.spec][if1632/system.spec][if1632/user.spec]
+	ChooseFont, RESERVED5, InternalExtractIcon: Marked as stubs
+	ExtractAssociatedIcon, DoEnvironmentSubst, DumpIcon:
+		stub implementations provided 
+	marked storage.dll,storege.sys functions as stubs
+
+	* [include/pe_image.h]
+	Added structures WIN32_builtin and  WIN32_function
+
+	* [include/peexe.h]
+	PE_Import_Directory: renamed reserved fields to 
+		TimeDate, Forwarder, Thunk_List
+
+	* [include/winerror.h]
+	New file.
+
+	* [loader/main.c]
+	called RELAY32_Init
+
+	* [loader/pe_image.c]
+	xmmap: map BSS anonymous
+	dump_imports: renamed to fixup_imports, do the fixup of imported
+	              symbols
+	PE_LoadImage: pass raw data size to xmmap
+
+	* [loader/resource.c]
+	DumpIcon: new function
+
+	* [misc/kernel32.c]
+	New file.
+
+	* [misc/main.c]
+	make stdout and stderr unbuffered
+
+	* [misc/shell.c]
+	DoEnvironmentSubst: new function
+
+	* [objects/font.c]
+	FONT_MatchFont: try oblique if there is no italic
+
+	* [rc/Imakefile][rc/parser.l]
+	yywrap: new function
+	Don't link with libfl.a on Linux
+
+	* [tools/build.c]
+	Added keywords stdcall, subsystem, base
+	GenerateForWin32: new function
+	BuildSpecFiles: call GenerateForWin32 if subsystem is win32
+
+Mon May 15 10:38:14 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+        
+        * [controls/listbox.c] [controls/combo.c] [windows/defwnd.c]
+	Minor fixes.
+	
+	* [misc/message.c] [misc/main.c] [rc/sysres*.rc] [include/texts.h]
+	Rewrote message box handling.
+	
+	* [windows/dialog.c]
+	Dialogs should be invisible until after WM_INITDIALOG is seent.
+	Don't switch to invisible dialog items on a TAB keypress.
+	
+	* [windows/mdi.c]
+	Send WM_NCPAINT message in MDIRestoreChild().
+	
+	* [windows/painting.c]
+	Fixed typo (&& -> &).
+	
+	* [windows/message.c] [if1632/user.spec]
+	Implemented PostAppMessage().
+	
+	* [windows/event.c]
+	SetCapture(0) should act like ReleaseCapture().
+
+Tue May  9 11:55:52 1995     Eddie C. Dost             (ecd@dressler.de)
+
+	* [Imakefile]
+	Changed CDEBUGFLAGS for systems running __ELF__ (temporarily)
+	Added ASFLAGS to exported variables.
+
+	* [debugger/readline/Imakefile]
+	Moved defines for libreadline from DEFINES to EXTRA_DEFINES
+
+	* [memory/local.c] [miscemu/int21.c]
+	Added some more debugging outputs.
+
+Mon May  8 00:55:27 MET DST 1995	  Dag Asheim (dash@ifi.uio.no)
+
+	* [misc/message.c]
+	Fixed a "FIXME" concerning norwegian translation.
+
+Sun May  7 23:25:23 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+        
+	* [*/*]
+        Removed warnings in a couple of files and deleted some obsolete code.
+
+        * [controls/listbox.c]
+        Cleanup, speed improvements & lots of bug fixes.
+
+        * [controls/combo.c]
+	Mostly rewritten. This is still very buggy, but not quite as bad as 
+	before.
+
+        * [include/commdlg.h] [misc/commdlg.c]
+        Removed the need for sysres.dll. Small bug fixes.
+	
+        * [objects/oembitmap.c] [include/bitmaps/<many>] [include/windows.h]
+          [loader/library.c] [loader/main.c] [rc/sysres*.rc]
+        Removed sysres.dll and replaced the remaining bitmaps/icons with
+        XPM equivalents.
+
+        * [misc/message.c] [windows/nonclient.c] [misc/main.c]
+          [if1632/winprocs.spec]
+        "About Wine..." now brings up a standard ShellAbout() window with
+        the Wine icon and the list of contributors.
+	
+	* [misc/shell.c]
+	Fixed ShellAbout()/AboutDialogProc() to show the right icon.
+
+	* [windows/event.c]
+	Small hack for non-alphanumeric keys: Dont't send the ascii value in
+	the WM_KEYDOWN message, but some unused code instead. Should be done
+	properly by sending different codes for each key. The edit control
+	used to get a VK_DELETE message each time the user typed '.'.
+
+	* [windows/class.c]
+	Removed a check for CS_GLOBALCLASS in CLASS_FindClassByName().
+	This used to be no problem, but breaks Resource Workshop in 950403.
+	
+	* [objects/dib.c]
+	New diagnostic for a bug I've been encountering. If it shows up,
+	please report it.
+
+Sun May  7 23:11:18 EDT 1995  William Magro (wmagro@tc.cornell.edu)
+
+	* [objects/color.c]
+	Handle situation when 'dc' exists, but palette mapping
+	does not.  (Fixes kidpix2 demo.)
+
+Sun May  7 03:32:00 1995  Charles M. Hannum  (mycroft@mit.edu)
+
+	* [loader/ldt.c]
+	LDT_Print: Only show the number of entries that the kernel
+	returned. Make this work for NetBSD.
+
+Fri May  5 02:53:26 1995  Charles M. Hannum  (mycroft@mit.edu)
+
+	* [debugger/dbg.y] [include/wine.h] [loader/signal.c]
+	Modify cs and ds selector values for NetBSD-current.
+
+	* [debugger/debug.l]
+	$sp, $esp: Use RN_ESP_AT_SIGNAL rather than RN_ESP.
+
+	* [debugger/regpos.h]
+	Modify sigcontext format for NetBSD-current.
+	SC_ESP: Use RN_ESP_AT_SIGNAL rather than RN_ESP.
+
+	* [include/ldt.h]
+	SELECTOR_TO_ENTRY: Explicitly clear the top half of the selector
+	value, since only 16 bits of it may have been saved.
+
+	* [misc/winsocket.c]
+	Set structure packing with `#pragma pack' to accomodate
+	other/older compilers.
+
+Tue May  2 18:15:01 1995 Paal Beyer (beyer@idt.unit.no)
+	
+	* [misc/commdlg.c]
+	Fixed path-names so when changing directory the listboxes
+	changes too.
+	
+	* [debugger/dbg.y debugger/debug.l wine.ini]
+	Added SymbolTableFile to wine.ini so symbols can be read
+	without standing in the directory containing wine.sym.
+	Added the possibility to specify full name of wine.sym from
+	the debugger prompt.
+
+----------------------------------------------------------------------
 Sat Apr 29 20:42:01 1995  Alexandre Julliard  (julliard@sunsite.unc.edu)
 
 	* [controls/static.c]
diff --git a/Imakefile b/Imakefile
index 33ee887..492798d 100644
--- a/Imakefile
+++ b/Imakefile
@@ -6,9 +6,11 @@
 CC = gcc -D__FreeBSD__
 #endif
 
-DEFINES = AutoDefines -DUSE_READLINE -DWINESTAT
+DEFINES = AutoDefines -DUSE_READLINE
 #ifdef __ELF__
-CDEBUGFLAGS = -O2 -Wall -static
+LD = /usr/i486-linuxaout/bin/ld -m i386linux
+CDEBUGFLAGS = -O2 -Wall -b i486-linuxaout
+ASFLAGS = -b i486-linuxaout
 #else
 CDEBUGFLAGS = -O2 -Wall
 #endif
@@ -26,7 +28,7 @@
 
 #define IHaveSubdirs
 #define	PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)' 'CC=$(CC)' 'MAKE=$(MAKE)'\
-			'DEFINES=$(DEFINES)' 'LD=$(LD)'
+			'DEFINES=$(DEFINES)' 'LD=$(LD)' 'ASFLAGS=$(ASFLAGS)'
 
 COMMONSUBDIRS = \
 	controls \
diff --git a/README b/README
index a007111..f9ca019 100644
--- a/README
+++ b/README
@@ -82,10 +82,11 @@
 
 Used to specify the path which will be used to find executables and DLL's.
 
-format: systemresources = <filename>
-default: c:\temp
+format: symboltablefile = <filename>
+default: wine.sym
 
-Used to specify the name of sysres.dll, a dll which is used by Wine itself.
+Used to specify the path and file name of the symbol table used by the
+built-in debugger.
 
 * [serialports]
 
diff --git a/README.OEMANSI b/README.OEMANSI
deleted file mode 100644
index c27b49d..0000000
--- a/README.OEMANSI
+++ /dev/null
@@ -1,29 +0,0 @@
-
-In this directory you might find my implemantation of the Windows
-String.  The patch lstr.patch includes whats needed for the following
-functions:
-lstrcat,lstrcmp,lstrcmpi,lstrcpy,lstrcpyn,lstrlen,AnsiUpper,AnsiLower,
-IsCharAlpha,IsCharAlphanumeric,IsCharUpper,IsCharLower,AnsiUpperBuff,
-AnsiLowerBuff,AnsiNext,AnsiPrev. Simply apply the patch to Wine.0.4.1
-and remake.
-
-
-Also there should be the files oem2ansi.trl and ansi2oem.trl that
-define how to translate between ansi and oem codepage 861 I believe
-they call it. These files where created by the Windows program
-oemansi.exe which is also included. To get the oem<->ansi translations
-right for your part of the world just run oemansi under Windows not
-Wine and oemansi will create oem2ansi and ansi2oem for your locale
-that is if your Windows/Dos is set up correctly. Move the .trl files
-into the directory from where you run wine. If Wine does not find the
-*.trl in the current directory AnsiToOem and OemToAnsi will be
-passive.
-
-Shortcomings/Bugs: 
-Some functions depend upon libc functions like toupper, tolower and
-isalpha that, as far as I know, are totally without support for NLS
-and ISO 8859-1.  Default Ansi<->OEM translations when *.trl files are
-not found are missing.
-
-
-NOTE: Please don't run oemansi.exe under wine.
diff --git a/controls/button.c b/controls/button.c
index c21d222..63fae08 100644
--- a/controls/button.c
+++ b/controls/button.c
@@ -3,19 +3,15 @@
  * Copyright (C) 1993 Johannes Ruscheinski
  * Copyright (C) 1993 David Metcalfe
  * Copyright (C) 1994 Alexandre Julliard
-
-static char Copyright1[] = "Copyright Johannes Ruscheinski, 1993";
-static char Copyright2[] = "Copyright David Metcalfe, 1993";
-static char Copyright3[] = "Copyright Alexandre Julliard, 1994";
-*/
+ */
 
 #include "win.h"
 #include "user.h"
 #include "syscolor.h"
 #include "graphics.h"
 #include "button.h"
-#include "stddebug.h"
-#include "debug.h"
+#include "stackframe.h"
+
 extern void DEFWND_SetText( HWND hwnd, LPSTR text );  /* windows/defwnd.c */
 
 static void PB_Paint( HWND hWnd, HDC hDC, WORD action );
@@ -477,26 +473,20 @@
 
 static void OB_Paint( HWND hWnd, HDC hDC, WORD action )
 {
-    HANDLE	hDis;
-    LPDRAWITEMSTRUCT lpdis;
+    DRAWITEMSTRUCT dis;
     WND *wndPtr = WIN_FindWndPtr( hWnd );
     BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;
 
-    if (!(hDis = USER_HEAP_ALLOC( sizeof(DRAWITEMSTRUCT) ))) return;
-    lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_LIN_ADDR(hDis);
-    lpdis->CtlType    = ODT_BUTTON;
-    lpdis->CtlID      = wndPtr->wIDmenu;
-    lpdis->itemID     = 0;
-    lpdis->itemAction = action;
-    lpdis->itemState  = (infoPtr->state & BUTTON_HASFOCUS) ? ODS_FOCUS : 0 |
+    dis.CtlType    = ODT_BUTTON;
+    dis.CtlID      = wndPtr->wIDmenu;
+    dis.itemID     = 0;
+    dis.itemAction = action;
+    dis.itemState  = (infoPtr->state & BUTTON_HASFOCUS) ? ODS_FOCUS : 0 |
                      (infoPtr->state & BUTTON_HIGHLIGHTED) ? ODS_SELECTED : 0 |
                      (wndPtr->dwStyle & WS_DISABLED) ? ODS_DISABLED : 0;
-    lpdis->hwndItem   = hWnd;
-    lpdis->hDC        = hDC;
-    GetClientRect( hWnd, &lpdis->rcItem );
-    lpdis->itemData   = 0;
-    SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, USER_HEAP_SEG_ADDR(hDis) );
-    USER_HEAP_FREE(hDis);
+    dis.hwndItem   = hWnd;
+    dis.hDC        = hDC;
+    GetClientRect( hWnd, &dis.rcItem );
+    dis.itemData   = 0;
+    SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, MAKE_SEGPTR(&dis) );
 }
-
-
diff --git a/controls/combo.c b/controls/combo.c
index f61d8e4..34111d7 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -1,10 +1,10 @@
 /*
- * Interface code to COMBOBOX widget
- *
- * Copyright  Martin Ayotte, 1993
- *
-static char Copyright[] = "Copyright Martin Ayotte, 1993";
-*/
+ * Combo controls
+ * 
+ * Copyright 1993 Martin Ayotte
+ * Copyright 1995 Bernd Schmidt
+ * 
+ */
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -12,6 +12,7 @@
 #include <sys/stat.h>
 
 #include "windows.h"
+#include "sysmetrics.h"
 #include "combo.h"
 #include "user.h"
 #include "win.h"
@@ -19,498 +20,1010 @@
 /* #define DEBUG_COMBO */
 #include "debug.h"
 #include "graphics.h"
+#include "listbox.h"
+#include "dos_fs.h"
 
-HBITMAP hComboBit = 0;
+ /*
+  * Note: Combos are probably implemented in a different way by Windows.
+  * Using a message spy for Windows, you can see some undocumented
+  * messages being passed between ComboBox and ComboLBox.
+  * I hope no programs rely on the implementation of combos.
+  */
 
-LPHEADCOMBO ComboGetStorageHeader(HWND hwnd);
-int CreateComboStruct(HWND hwnd);
-void ComboBoxStaticOwnerDraw(HWND hWnd, LPHEADCOMBO lphc);
+static LONG CBNCCreate( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBCreate( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBGetDlgCode( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBDestroy( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBPaint( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBKeyDown( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBChar( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBSetFont( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBSetRedraw( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBLButtonDown( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBSetFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBKillFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBResetContent( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBDir( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBAddString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBGetLBText( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBInsertString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBDeleteString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBFindString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBGetCount( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBGetCurSel( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBGetItemData( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBGetItemHeight( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBGetLBTextLen( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBSelectString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBSetItemData( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBSetCurSel( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBSetItemHeight( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBShowDropDown( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+
+static LONG CBLCreate( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBLGetDlgCode( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBLKeyDown( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBLChar( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBLPaint( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBLKillFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBLActivate( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBLLButtonDown( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBLLButtonUp( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBLMouseMove( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG CBLVScroll( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+
+typedef struct {
+  WORD   message;
+  LONG  (*handler)(HWND, WORD, WPARAM, LPARAM);
+} msg_tbl;
+
+static msg_tbl combo_tbl[] = {
+  {WM_NCCREATE, CBNCCreate},
+  {WM_CREATE, CBCreate},
+  {WM_DESTROY, CBDestroy},
+  {WM_GETDLGCODE, CBGetDlgCode},
+  {WM_KEYDOWN, CBKeyDown},
+  {WM_CHAR, CBChar},
+  {WM_SETFONT, CBSetFont},
+  {WM_SETREDRAW, CBSetRedraw},
+  {WM_PAINT, CBPaint},
+  {WM_LBUTTONDOWN, CBLButtonDown},
+  {WM_SETFOCUS, CBSetFocus},
+  {WM_KILLFOCUS, CBKillFocus},
+  {CB_RESETCONTENT, CBResetContent},
+  {CB_DIR, CBDir},
+  {CB_ADDSTRING, CBAddString},
+  {CB_INSERTSTRING, CBInsertString},
+  {CB_DELETESTRING, CBDeleteString},
+  {CB_FINDSTRING, CBFindString},
+  {CB_GETCOUNT, CBGetCount},
+  {CB_GETCURSEL, CBGetCurSel},
+  {CB_GETITEMDATA, CBGetItemData},
+  {CB_GETITEMHEIGHT, CBGetItemHeight},
+  {CB_GETLBTEXT, CBGetLBText},
+  {CB_GETLBTEXTLEN, CBGetLBTextLen},
+  {CB_SELECTSTRING, CBSelectString},
+  {CB_SETITEMDATA, CBSetItemData},
+  {CB_SETCURSEL, CBSetCurSel},
+  {CB_SETITEMHEIGHT, CBSetItemHeight},
+  {CB_SHOWDROPDOWN, CBShowDropDown}
+    
+};
+
+static msg_tbl clbox_tbl[] = {
+  {WM_CREATE, CBLCreate},
+  {WM_GETDLGCODE, CBLGetDlgCode},
+  {WM_KEYDOWN, CBLKeyDown},
+  {WM_CHAR, CBLChar},
+  {WM_PAINT, CBLPaint},
+  {WM_KILLFOCUS, CBLKillFocus},
+  {WM_ACTIVATE, CBLActivate},
+  {WM_LBUTTONDOWN, CBLLButtonDown},
+  {WM_LBUTTONUP, CBLLButtonUp},
+  {WM_MOUSEMOVE, CBLMouseMove},
+  {WM_VSCROLL, CBLVScroll}
+};
+
+static HBITMAP hComboBit = 0;
+static WORD CBitHeight, CBitWidth;
+
+static int COMBO_Init()
+{
+  BITMAP bm;
+  
+  dprintf_combo(stddeb, "COMBO_Init\n");
+  hComboBit = LoadBitmap(0, MAKEINTRESOURCE(OBM_COMBO));
+  GetObject(hComboBit, sizeof(BITMAP), (LPSTR)&bm);
+  CBitHeight = bm.bmHeight;
+  CBitWidth = bm.bmWidth;
+  return 0;
+}
+
+LPHEADCOMBO ComboGetStorageHeader(HWND hwnd)
+{
+  return (LPHEADCOMBO)GetWindowLong(hwnd,4);
+}
+
+LPHEADLIST ComboGetListHeader(HWND hwnd)
+{
+  return (LPHEADLIST)GetWindowLong(hwnd,0);
+}
+
+int CreateComboStruct(HWND hwnd, LONG style)
+{
+  LPHEADCOMBO lphc;
+
+  lphc = (LPHEADCOMBO)malloc(sizeof(HEADCOMBO));
+  SetWindowLong(hwnd,4,(LONG)lphc);
+  lphc->hWndEdit = 0;
+  lphc->hWndLBox = 0;
+  lphc->dwState = 0;
+  lphc->LastSel = -1;
+  lphc->dwStyle = style;
+  lphc->DropDownVisible = FALSE;
+  return TRUE;
+}
+
+void ComboUpdateWindow(HWND hwnd, LPHEADLIST lphl, LPHEADCOMBO lphc, BOOL repaint)
+{
+  SetScrollRange(lphc->hWndLBox, SB_VERT, 0, ListMaxFirstVisible(lphl), TRUE);
+  if (repaint && lphl->bRedrawFlag) {
+    InvalidateRect(hwnd, NULL, TRUE);
+  }
+}
+
+/***********************************************************************
+ *           CBNCCreate
+ */
+static LONG CBNCCreate(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  CREATESTRUCT *createStruct;
+
+  if (!hComboBit) COMBO_Init();
+
+  createStruct = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam);
+  createStruct->style &= ~(WS_VSCROLL | WS_HSCROLL);
+  SetWindowLong(hwnd, GWL_STYLE, createStruct->style);
+
+  dprintf_combo(stddeb,"ComboBox WM_NCCREATE!\n");
+  return DefWindowProc(hwnd, message, wParam, lParam);
+
+}
+
+/***********************************************************************
+ *           CBCreate
+ */
+static LONG CBCreate(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST   lphl;
+  LPHEADCOMBO  lphc;
+  LONG         style = 0;
+  LONG         cstyle = GetWindowLong(hwnd,GWL_STYLE);
+  RECT         rect,lboxrect;
+
+  /* translate combo into listbox styles */
+  if (cstyle & CBS_OWNERDRAWFIXED) style |= LBS_OWNERDRAWFIXED;
+  if (cstyle & CBS_OWNERDRAWVARIABLE) style |= LBS_OWNERDRAWVARIABLE;
+  if (cstyle & CBS_SORT) style |= LBS_SORT;
+  if (cstyle & CBS_HASSTRINGS) style |= LBS_HASSTRINGS;
+  style |= LBS_NOTIFY;
+  CreateListBoxStruct(hwnd, ODT_COMBOBOX, style, GetParent(hwnd));
+  CreateComboStruct(hwnd,cstyle);
+  lphl = ComboGetListHeader(hwnd);
+  lphc = ComboGetStorageHeader(hwnd);
+
+  GetClientRect(hwnd,&rect);
+  GetWindowRect(hwnd,&lboxrect);
+  /* FIXME: combos with edit controls are broken. */
+  switch(cstyle & 3) {
+   case CBS_SIMPLE:            /* edit control, list always visible  */
+    dprintf_combo(stddeb,"CBS_SIMPLE\n");
+    SetRectEmpty(&lphc->RectButton);
+    lphc->LBoxTop = lphl->StdItemHeight;
+    lphc->hWndEdit = CreateWindow("EDIT", "", 
+				  WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT,
+				  0, 0, rect.right, lphl->StdItemHeight,
+				  hwnd, 1, GetWindowWord(hwnd,GWW_HINSTANCE), 0L);
+    break;
+   case CBS_DROPDOWN:          /* edit control, dropdown listbox     */
+    dprintf_combo(stddeb,"CBS_DROPDOWN\n");
+    lphc->RectButton = rect;
+    lphc->RectButton.left = lphc->RectButton.right - 6 - CBitWidth;
+    lphc->RectButton.bottom = lphc->RectButton.top + lphl->StdItemHeight;
+    lphc->LBoxTop = lphl->StdItemHeight;
+    SetWindowPos(hwnd, 0, 0, 0, rect.right - rect.left + 2*SYSMETRICS_CXBORDER,
+		 lphl->StdItemHeight + 2*SYSMETRICS_CYBORDER,
+		 SWP_NOMOVE | SWP_NOZORDER);
+    lphc->hWndEdit = CreateWindow("EDIT", "",
+				  WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT,
+				  0, 0, lphc->RectButton.left, lphl->StdItemHeight,
+				  hwnd, 1, GetWindowWord(hwnd,GWW_HINSTANCE), 0L);
+    break;
+   case CBS_DROPDOWNLIST:      /* static control, downdown listbox   */
+    dprintf_combo(stddeb,"CBS_DROPDOWNLIST\n");
+    lphc->RectButton = rect;
+    lphc->RectButton.left = lphc->RectButton.right - 6 - CBitWidth;
+    lphc->RectButton.bottom = lphc->RectButton.top + lphl->StdItemHeight;
+    lphc->LBoxTop = lphl->StdItemHeight;
+    SetWindowPos(hwnd, 0, 0, 0, rect.right - rect.left + 2*SYSMETRICS_CXBORDER,
+		 lphl->StdItemHeight + 2*SYSMETRICS_CYBORDER,
+		 SWP_NOMOVE | SWP_NOZORDER);
+    break;
+  }
+  lboxrect.top += lphc->LBoxTop;
+  /* FIXME: WinSight says these should be CHILD windows with the TOPMOST flag
+   * set. Wine doesn't support TOPMOST, and simply setting the WS_CHILD
+   * flag doesn't work. */
+  lphc->hWndLBox = CreateWindow("COMBOLBOX", "", 
+				WS_POPUP | WS_BORDER | WS_VSCROLL,
+				lboxrect.left, lboxrect.top,
+				lboxrect.right - lboxrect.left, 
+				lboxrect.bottom - lboxrect.top,
+				0, 0, GetWindowWord(hwnd,GWW_HINSTANCE),
+				(SEGPTR)MAKELONG(hwnd, hwnd));
+  ShowWindow(lphc->hWndLBox, SW_HIDE);
+  dprintf_combo(stddeb,"Combo Creation LBox=%X!\n", lphc->hWndLBox);
+  return 0;
+}
+
+/***********************************************************************
+ *           CBDestroy
+ */
+static LONG CBDestroy(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST lphl = ComboGetListHeader(hwnd);
+
+  ListBoxResetContent(lphl);
+  DestroyListBoxStruct(lphl);
+  dprintf_combo(stddeb,"Combo WM_DESTROY %p !\n", lphl);
+  return 0;
+}
+
+/***********************************************************************
+ *           CBPaint
+ */
+static LONG CBPaint(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST lphl = ComboGetListHeader(hwnd);
+  LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
+  LPLISTSTRUCT lpls;
+  PAINTSTRUCT  ps;
+  HBRUSH hBrush;
+  HFONT  hOldFont;
+  HDC  hdc;
+  RECT rect;
+  int height;
+  
+  hdc = BeginPaint(hwnd, &ps);
+
+  if (hComboBit != 0) {
+    GRAPH_DrawReliefRect(hdc, &lphc->RectButton, 2, 2, FALSE);
+    GRAPH_DrawBitmap(hdc, hComboBit,
+		     lphc->RectButton.left + 3,lphc->RectButton.top + 2,
+		     0, 0, CBitWidth, CBitHeight );
+  }
+  if (!IsWindowVisible(hwnd) || !lphl->bRedrawFlag 
+      || (lphc->dwStyle & 3) != CBS_DROPDOWNLIST) 
+  {
+    /* we don't want to draw an entry when there is an edit control */
+    EndPaint(hwnd, &ps);
+    return 0;
+  }
+
+  hOldFont = SelectObject(hdc, lphl->hFont);
+
+  hBrush = SendMessage(lphl->hParent, WM_CTLCOLOR, hdc,
+		       MAKELONG(hwnd, CTLCOLOR_LISTBOX));
+  if (hBrush == 0) hBrush = GetStockObject(WHITE_BRUSH);
+
+  GetClientRect(hwnd, &rect);
+  rect.right -= (lphc->RectButton.right - lphc->RectButton.left);
+  FillRect(hdc, &rect, hBrush);
+
+  lpls = ListBoxGetItem(lphl,lphl->ItemFocused);
+  if (lpls != NULL) {  
+    height = lpls->mis.itemHeight;
+    rect.bottom = rect.top + height;
+
+    if (OWNER_DRAWN(lphl)) {
+      ListBoxDrawItem (hwnd, lphl, hdc, lpls, &rect, ODA_DRAWENTIRE, 0);
+    } else {
+      ListBoxDrawItem (hwnd, lphl, hdc, lpls, &rect, ODA_DRAWENTIRE, 0);
+    }
+    if (GetFocus() == hwnd)
+    ListBoxDrawItem (hwnd,lphl, hdc, lpls, &rect, ODA_FOCUS, ODS_FOCUS);
+  }
+  SelectObject(hdc,hOldFont);
+  EndPaint(hwnd, &ps);
+  return 0;
+}
+
+/***********************************************************************
+ *           CBGetDlgCode
+ */
+static LONG CBGetDlgCode(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  return DLGC_WANTARROWS | DLGC_WANTCHARS;
+}
+
+/***********************************************************************
+ *           CBLButtonDown
+ */
+static LONG CBLButtonDown(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
+  SendMessage(hwnd,CB_SHOWDROPDOWN,!lphc->DropDownVisible,0);
+  return 0;
+}
+
+/***********************************************************************
+ *           CBKeyDown
+ */
+static LONG CBKeyDown(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST lphl = ComboGetListHeader(hwnd);
+  WORD       newFocused = lphl->ItemFocused;
+
+  switch(wParam) {
+  case VK_HOME:
+    newFocused = 0;
+    break;
+  case VK_END:
+    newFocused = lphl->ItemsCount - 1;
+    break;
+  case VK_UP:
+    if (newFocused > 0) newFocused--;
+    break;
+  case VK_DOWN:
+    newFocused++;
+    break;
+  default:
+    return 0;
+  }
+
+  if (newFocused >= lphl->ItemsCount)
+    newFocused = lphl->ItemsCount - 1;
+  
+  ListBoxSetCurSel(lphl, newFocused);
+  ListBoxSendNotification(lphl, hwnd, CBN_SELCHANGE);
+
+  lphl->ItemFocused = newFocused;
+  ListBoxScrollToFocus(lphl);
+/*  SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);*/
+  InvalidateRect(hwnd, NULL, TRUE);
+
+  return 0;
+}
+
+/***********************************************************************
+ *           CBChar
+ */
+static LONG CBChar(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST lphl = ComboGetListHeader(hwnd);
+  WORD       newFocused;
+
+  newFocused = ListBoxFindNextMatch(lphl, wParam);
+  if (newFocused == (WORD)LB_ERR) return 0;
+
+  if (newFocused >= lphl->ItemsCount)
+    newFocused = lphl->ItemsCount - 1;
+  
+  ListBoxSetCurSel(lphl, newFocused);
+  ListBoxSendNotification(lphl, hwnd, CBN_SELCHANGE);
+  lphl->ItemFocused = newFocused;
+  ListBoxScrollToFocus(lphl);
+  
+/*  SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);*/
+  InvalidateRect(hwnd, NULL, TRUE);
+
+  return 0;
+}
+
+/***********************************************************************
+ *           CBKillFocus
+ */
+static LONG CBKillFocus(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  return 0;
+}
+
+/***********************************************************************
+ *           CBSetFocus
+ */
+static LONG CBSetFocus(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  return 0;
+}
+
+/***********************************************************************
+ *           CBResetContent
+ */
+static LONG CBResetContent(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST lphl = ComboGetListHeader(hwnd);
+  LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
+
+  ListBoxResetContent(lphl);
+  ComboUpdateWindow(hwnd, lphl, lphc, TRUE);
+  return 0;
+}
+
+/***********************************************************************
+ *           CBDir
+ */
+static LONG CBDir(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  WORD wRet;
+  LPHEADLIST lphl = ComboGetListHeader(hwnd);
+  LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
+
+  wRet = ListBoxDirectory(lphl, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam));
+  ComboUpdateWindow(hwnd, lphl, lphc, TRUE);
+  return wRet;
+}
+
+/***********************************************************************
+ *           CBInsertString
+ */
+static LONG CBInsertString(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  WORD  wRet;
+  LPHEADLIST lphl = ComboGetListHeader(hwnd);
+  LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
+
+  if (HasStrings(lphl))
+    wRet = ListBoxInsertString(lphl, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam));
+  else
+    wRet = ListBoxInsertString(lphl, wParam, (LPSTR)lParam);
+
+  ComboUpdateWindow(hwnd, lphl, lphc, TRUE);
+  return wRet;
+}
+
+/***********************************************************************
+ *           CBAddString
+ */
+static LONG CBAddString(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  WORD  wRet;
+  LPHEADLIST lphl = ComboGetListHeader(hwnd);
+  LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
+
+  if (HasStrings(lphl))
+    wRet = ListBoxAddString(lphl, (LPSTR)PTR_SEG_TO_LIN(lParam));
+  else
+    wRet = ListBoxAddString(lphl, (LPSTR)lParam);
+
+  ComboUpdateWindow(hwnd, lphl, lphc, TRUE);
+  return wRet;
+}
+
+/***********************************************************************
+ *           CBDeleteString
+ */
+static LONG CBDeleteString(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST lphl = ComboGetListHeader(hwnd);
+  LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
+  LONG lRet = ListBoxDeleteString(lphl,wParam);
+  
+  ComboUpdateWindow(hwnd, lphl, lphc, TRUE);
+  return lRet;
+}
+
+/***********************************************************************
+ *           CBSelectString
+ */
+static LONG CBSelectString(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST lphl = ComboGetListHeader(hwnd);
+  WORD  wRet;
+
+  wRet = ListBoxFindString(lphl, wParam, lParam);
+
+  /* XXX add functionality here */
+
+  return 0;
+}
+
+/***********************************************************************
+ *           CBFindString
+ */
+static LONG CBFindString(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST lphl = ComboGetListHeader(hwnd);
+  return ListBoxFindString(lphl, wParam, lParam);
+}
+
+/***********************************************************************
+ *           CBGetCount
+ */
+static LONG CBGetCount(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST lphl = ComboGetListHeader(hwnd);
+  return lphl->ItemsCount;
+}
+
+/***********************************************************************
+ *           CBSetCurSel
+ */
+static LONG CBSetCurSel(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST lphl = ComboGetListHeader(hwnd);
+  WORD  wRet;
+
+  wRet = ListBoxSetCurSel(lphl, wParam);
+
+/*  SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);*/
+  InvalidateRect(hwnd, NULL, TRUE);
+
+  return wRet;
+}
+
+/***********************************************************************
+ *           CBGetCurSel
+ */
+static LONG CBGetCurSel(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST lphl = ComboGetListHeader(hwnd);
+  return lphl->ItemFocused;
+}
+
+/***********************************************************************
+ *           CBGetItemHeight
+ */
+static LONG CBGetItemHeight(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST lphl = ComboGetListHeader(hwnd);
+  LPLISTSTRUCT lpls = ListBoxGetItem (lphl, wParam);
+
+  if (lpls == NULL) return LB_ERR;
+  return lpls->mis.itemHeight;
+}
+
+/***********************************************************************
+ *           CBSetItemHeight
+ */
+static LONG CBSetItemHeight(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST lphl = ComboGetListHeader(hwnd);
+  return ListBoxSetItemHeight(lphl, wParam, lParam);
+}
+
+/***********************************************************************
+ *           CBSetRedraw
+ */
+static LONG CBSetRedraw(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST lphl = ComboGetListHeader(hwnd);
+  lphl->bRedrawFlag = wParam;
+  return 0;
+}
+
+/***********************************************************************
+ *           CBSetFont
+ */
+static LONG CBSetFont(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST  lphl = ComboGetListHeader(hwnd);
+
+  if (wParam == 0)
+    lphl->hFont = GetStockObject(SYSTEM_FONT);
+  else
+    lphl->hFont = wParam;
+
+  return 0;
+}
+
+/***********************************************************************
+ *           CBGetLBTextLen
+ */
+static LONG CBGetLBTextLen(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST   lphl = ComboGetListHeader(hwnd);
+  LPLISTSTRUCT lpls = ListBoxGetItem(lphl,wParam);
+
+  if (lpls == NULL || !HasStrings(lphl)) return LB_ERR;
+  return strlen(lpls->itemText);
+}
+
+/***********************************************************************
+ *           CBGetLBText
+ */
+static LONG CBGetLBText(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST lphl = ComboGetListHeader(hwnd);
+  return ListBoxGetText(lphl, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam));
+}
+
+/***********************************************************************
+ *           CBGetItemData
+ */
+static LONG CBGetItemData(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST lphl = ComboGetListHeader(hwnd);
+  return ListBoxGetItemData(lphl, wParam);
+}
+
+/***********************************************************************
+ *           CBSetItemData
+ */
+static LONG CBSetItemData(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST lphl = ComboGetListHeader(hwnd);
+  return ListBoxSetItemData(lphl, wParam, lParam);
+}
+
+/***********************************************************************
+ *           CBShowDropDown
+ */
+static LONG CBShowDropDown(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
+  RECT rect;
+  
+  if (lphc->dwStyle & 3 == CBS_SIMPLE) return LB_ERR;
+  
+  wParam = !!wParam;
+  if (wParam != lphc->DropDownVisible) {
+    lphc->DropDownVisible = wParam;
+    GetWindowRect(hwnd,&rect);
+    SetWindowPos(lphc->hWndLBox, 0, rect.left, rect.top+lphc->LBoxTop, 0, 0,
+		 SWP_NOSIZE | (wParam ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
+    if (!wParam) SetFocus(hwnd);
+  }
+  return 0;
+}
 
 
 /***********************************************************************
  *           ComboWndProc
  */
-LONG ComboBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-{    
-	RECT	rect;
-	int		y, count;
-	int		width, height;
-	WND  	*wndPtr;
-	LPHEADCOMBO lphc;
-	HDC		hDC;
-	BITMAP	bm;
-	PAINTSTRUCT paintstruct;
-	LPDRAWITEMSTRUCT lpdis;
-	DWORD       dwStyle;
-        HANDLE hStr;
+LONG ComboBoxWndProc(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  int idx = 0;
+  int table_size = sizeof (combo_tbl) / sizeof (msg_tbl);
 
-	switch(message) {
-		case WM_CREATE:
-			wndPtr = WIN_FindWndPtr(hwnd);
-			if (wndPtr == NULL) return 0;
-			dprintf_combo(stddeb,"Combo WM_CREATE %d !\n", hwnd);
-			if (hComboBit == (HBITMAP)NULL) 
-			hComboBit = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_COMBO));
-			GetObject(hComboBit, sizeof(BITMAP), (LPSTR)&bm);
-			wndPtr->dwStyle &= 0xFFFFFFFFL ^ (WS_VSCROLL | WS_HSCROLL);
-			GetWindowRect(hwnd, &rect);
-			width = rect.right - rect.left;
-			height = rect.bottom - rect.top;
-			if (height < bm.bmHeight) height = bm.bmHeight;
-/*			SetWindowPos(hwnd, 0, 0, 0, width + bm.bmHeight, bm.bmHeight, 
-									SWP_NOMOVE | SWP_NOZORDER); */
-			SetWindowPos(hwnd, 0, 0, 0, width, bm.bmHeight, 
-								SWP_NOMOVE | SWP_NOZORDER); 
-			CreateComboStruct(hwnd);
-			lphc = ComboGetStorageHeader(hwnd);
-			if (lphc == NULL) return 0;
-/*			SetRect(&lphc->RectEdit, 0, 0, width - 2, bm.bmHeight); */
-			SetRect(&lphc->RectEdit, 0, 0, width - bm.bmHeight, bm.bmHeight);
-			if (wndPtr->dwStyle & CBS_DROPDOWNLIST) {
-				if ((wndPtr->dwStyle & CBS_OWNERDRAWFIXED) == CBS_OWNERDRAWFIXED ||
-					(wndPtr->dwStyle & CBS_OWNERDRAWVARIABLE) == CBS_OWNERDRAWVARIABLE)
-					lphc->hWndEdit = 0;
-				else
-					lphc->hWndEdit = CreateWindow("STATIC", "",
-						WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT,
-						0, 0, width - bm.bmHeight, bm.bmHeight,
-						hwnd, 1, wndPtr->hInstance, 0L);
-				}
-			else {
-/*				lphc->hWndEdit = CreateWindow("EDIT", "", */
-				lphc->hWndEdit = CreateWindow("STATIC", "",
-					WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT,
-					0, 0, width - bm.bmHeight, bm.bmHeight,
-					hwnd, 1, wndPtr->hInstance, 0L);
-				}
-			dwStyle = WS_POPUP | WS_BORDER | WS_VSCROLL | LBS_NOTIFY;
-			if ((wndPtr->dwStyle & CBS_HASSTRINGS) == CBS_HASSTRINGS)
-				dwStyle |= LBS_HASSTRINGS;
-			if ((wndPtr->dwStyle & CBS_SORT) == CBS_SORT)
-				dwStyle |= LBS_SORT;
-			if ((wndPtr->dwStyle & CBS_OWNERDRAWFIXED) == CBS_OWNERDRAWFIXED)
-				dwStyle |= LBS_OWNERDRAWFIXED;
-			if ((wndPtr->dwStyle & CBS_OWNERDRAWVARIABLE) == CBS_OWNERDRAWVARIABLE)
-				dwStyle |= LBS_OWNERDRAWVARIABLE;
-			lphc->hWndLBox = CreateWindow("LISTBOX", "", dwStyle,
-				rect.left, rect.top + bm.bmHeight,
-				width, height, wndPtr->hwndParent, 0,
-				wndPtr->hInstance, (SEGPTR)MAKELONG(0, hwnd));
-			ShowWindow(lphc->hWndLBox, SW_HIDE);
-			dprintf_combo(stddeb,"Combo Creation LBox=%X!\n", lphc->hWndLBox);
-			return 0;
-    case WM_DESTROY:
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == 0) return 0;
-/*
-		if (lphc->hWndEdit != 0) DestroyWindow(lphc->hWndEdit);
-*/
-		DestroyWindow(lphc->hWndLBox);
-		free(lphc);
-/*
-		*((LPHEADCOMBO *)&wndPtr->wExtra[1]) = 0; 
-		printf("Combo WM_DESTROY after clearing wExtra !\n");
-*/
-		dprintf_combo(stddeb,"Combo WM_DESTROY %p !\n", lphc);
-		return DefWindowProc( hwnd, message, wParam, lParam );
-	case WM_SHOWWINDOW:
-		dprintf_combo(stddeb,"ComboBox WM_SHOWWINDOW hWnd=%04X !\n", 
-			      hwnd);
-		if (!(wParam == 0 && lParam == 0L)) {
-			InvalidateRect(hwnd, NULL, TRUE);
-			}
-	    break;
-	
-    case WM_COMMAND:
-		wndPtr = WIN_FindWndPtr(hwnd);
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL || wndPtr == NULL) return 0;
-		if (LOWORD(lParam) == lphc->hWndLBox) {
-                    hStr = USER_HEAP_ALLOC( 256 );
-			switch(HIWORD(lParam)) {
-				case LBN_SELCHANGE:
-					lphc->dwState = lphc->dwState & (CB_SHOWDROPDOWN ^ 0xFFFFFFFFL);
-					ShowWindow(lphc->hWndLBox, SW_HIDE);
-					y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
-					if (y != LB_ERR) {
-						SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
-						if (lphc->hWndEdit != 0) 
-							SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
-						else {
-							InvalidateRect(hwnd, NULL, TRUE);
-							UpdateWindow(hwnd);
-							}
-						}
-					SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
-										MAKELONG(hwnd, CBN_SELCHANGE));
-					break;
-				case LBN_DBLCLK:
-					SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
-										MAKELONG(hwnd, CBN_DBLCLK));
-					break;
-	        	}
-                    USER_HEAP_FREE( hStr );
-            }
-		break;
-    case WM_LBUTTONDOWN:
-		dprintf_combo(stddeb,"Combo WM_LBUTTONDOWN wParam=%x lParam=%lX !\n", wParam, lParam);
-		GetClientRect(hwnd, &rect);
-		rect.left = rect.right - (rect.bottom - rect.top); 
-		hDC = GetDC(hwnd);
-		InflateRect(&rect, -1, -1);
-		GRAPH_DrawReliefRect(hDC, &rect, 1, 1, TRUE);
-		ReleaseDC(hwnd, hDC);
-		wndPtr = WIN_FindWndPtr(hwnd);
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-		lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN;
-		if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) {
-		    ShowWindow(lphc->hWndLBox, SW_SHOW);
-		    SetFocus(lphc->hWndLBox);
-			}
-		else {
-			dprintf_combo(stddeb,"before Combo Restore Focus !\n");
-			SetFocus(lphc->hWndEdit);
-			dprintf_combo(stddeb,"before Combo List Hide !\n");
-			ShowWindow(lphc->hWndLBox, SW_HIDE);
-			dprintf_combo(stddeb,"before Combo List GetCurSel !\n");
-			y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
-			if (y != LB_ERR) {
-                                hStr = USER_HEAP_ALLOC( 256 );
-				dprintf_combo(stddeb,"before Combo List GetText !\n");
-				SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
-				SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
-                                USER_HEAP_FREE( hStr );
-				}
-			dprintf_combo(stddeb,"End of Combo List Hide !\n");
-			}
-		break;
-    case WM_LBUTTONUP:
-		dprintf_combo(stddeb,"Combo WM_LBUTTONUP wParam=%x lParam=%lX !\n", wParam, lParam);
-		GetClientRect(hwnd, &rect);
-		rect.left = rect.right - (rect.bottom - rect.top); 
-		hDC = GetDC(hwnd);
-		InflateRect(&rect, -1, -1);
-		GRAPH_DrawReliefRect(hDC, &rect, 1, 1, FALSE);
-		ReleaseDC(hwnd, hDC);
-		break;
-   case WM_KEYDOWN:
-		wndPtr = WIN_FindWndPtr(hwnd);
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL || wndPtr == NULL) return 0;
-		y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
-		count = SendMessage(lphc->hWndLBox, LB_GETCOUNT, 0, 0L);
-		dprintf_combo(stddeb,"COMBOBOX // GetKeyState(VK_MENU)=%d\n", GetKeyState(VK_MENU));
-		if (GetKeyState(VK_MENU) < 0) {
-			lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN;
-			if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) {
-				GetWindowRect(hwnd, &rect);
-				SetWindowPos(lphc->hWndLBox, 0, rect.left, rect.bottom, 0, 0, 
-									SWP_NOREDRAW | SWP_NOSIZE); 
-				SetWindowPos(lphc->hWndLBox, 0, 0, 0, 0, 0, SWP_SHOWWINDOW | 
-									SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); 
-			    SetFocus(lphc->hWndLBox);
-				}
-			else {
-				ShowWindow(lphc->hWndLBox, SW_HIDE);
-				y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
-				if (y != LB_ERR) {
-                                        hStr = USER_HEAP_ALLOC( 256 );
-					SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
-					if (lphc->hWndEdit != 0) 
-						SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
-                                        USER_HEAP_FREE( hStr );
-					}
-				}
-		    }
-		else {
-		    switch(wParam) {
-				case VK_HOME:
-				    y = 0;
-					break;
-				case VK_END:
-				    y = count - 1;
-				    break;
-				case VK_UP:
-				    y--;
-				    break;
-				case VK_DOWN:
-				    y++;
-				    break;
-				}
-			if (y < 0) y = 0;
-			if (y >= count) y = count - 1;
-			lphc->LastSel = y;
-			SendMessage(lphc->hWndLBox, LB_SETCURSEL, y, 0L);
-                        hStr = USER_HEAP_ALLOC( 256 );
-			SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
-			if (lphc->hWndEdit != 0) 
-				SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
-			SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
-			MAKELONG(hwnd, CBN_SELCHANGE));
-                        USER_HEAP_FREE( hStr );
-			}
-		break;
-    case WM_MEASUREITEM:
-	dprintf_combo(stddeb,"ComboBoxWndProc WM_MEASUREITEM !\n");
-    	return(SendMessage(GetParent(hwnd), WM_MEASUREITEM, wParam, lParam));
-    case WM_CTLCOLOR:
-    	return(SendMessage(GetParent(hwnd), WM_CTLCOLOR, wParam, lParam));
-	case WM_SETREDRAW:
-		dprintf_combo(stddeb,"ComboBoxWndProc WM_SETREDRAW hWnd=%04X w=%04X !\n", hwnd, wParam);
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-		lphc->bRedrawFlag = wParam;
-		break;
-    case WM_DRAWITEM:
-		dprintf_combo(stddeb,"ComboBoxWndProc // WM_DRAWITEM w=%04X l=%08lX\n", wParam, lParam);
-		wndPtr = WIN_FindWndPtr(hwnd);
-		if (wndPtr == NULL) break;
-		lpdis = (LPDRAWITEMSTRUCT)PTR_SEG_TO_LIN(lParam);
-		if (lpdis == NULL) break;
-		lpdis->CtlType = ODT_COMBOBOX;
-		lpdis->CtlID = wndPtr->wIDmenu;
-		return(SendMessage(GetParent(hwnd), WM_DRAWITEM, wParam, lParam));
-    case WM_PAINT:
-		GetClientRect(hwnd, &rect);
-		hDC = BeginPaint(hwnd, &paintstruct);
-		if (hComboBit != 0) {
-			GetObject(hComboBit, sizeof(BITMAP), (LPSTR)&bm);
-                        GRAPH_DrawBitmap( hDC, hComboBit,
-                                          rect.right - bm.bmWidth, 0,
-                                          0, 0, bm.bmWidth, bm.bmHeight );
-			}
-		EndPaint(hwnd, &paintstruct);
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-		if (lphc->hWndEdit != 0) {
-			InvalidateRect(lphc->hWndEdit, NULL, TRUE);
-			UpdateWindow(lphc->hWndEdit);
-			}
-		else {
-			ComboBoxStaticOwnerDraw(hwnd, lphc);
-			}
-		if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) {
-			InvalidateRect(lphc->hWndLBox, NULL, TRUE);
-			UpdateWindow(lphc->hWndLBox);
-			}
-		break;
-	case WM_SETFOCUS:
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-		if (lphc->hWndEdit != 0) 
-			SetFocus(lphc->hWndEdit);
-		break;
-	case WM_KILLFOCUS:
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-		ShowWindow(lphc->hWndLBox, SW_HIDE);
-		y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
-		if (y != LB_ERR) {
-                        hStr = USER_HEAP_ALLOC( 256 );
-			SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
-			if (lphc->hWndEdit != 0) 
-				SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
-                        USER_HEAP_FREE( hStr );
-			}
-		break;
-	case CB_ADDSTRING:
-		dprintf_combo(stddeb,"CB_ADDSTRING '%s' !\n", (LPSTR)PTR_SEG_TO_LIN(lParam));
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-		return(SendMessage(lphc->hWndLBox, LB_ADDSTRING, wParam, lParam));
-    case CB_GETLBTEXT:
-		dprintf_combo(stddeb,"CB_GETLBTEXT #%u !\n", wParam);
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-		return(SendMessage(lphc->hWndLBox, LB_GETTEXT, wParam, lParam));
-    case CB_GETLBTEXTLEN:
-		dprintf_combo(stddeb,"CB_GETLBTEXTLEN !\n");
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-		return(SendMessage(lphc->hWndLBox, LB_GETTEXTLEN, wParam, lParam));
-    case CB_INSERTSTRING:
-		dprintf_combo(stddeb,"CB_INSERTSTRING '%s' !\n",(LPSTR)PTR_SEG_TO_LIN(lParam));
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-		return(SendMessage(lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam));
-	case CB_DELETESTRING:
-		dprintf_combo(stddeb,"CB_DELETESTRING #%u !\n", wParam);
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-		return(SendMessage(lphc->hWndLBox, LB_DELETESTRING, wParam, 0L));
-	case CB_RESETCONTENT:
-		dprintf_combo(stddeb,"CB_RESETCONTENT !\n");
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-		return(SendMessage(lphc->hWndLBox, LB_RESETCONTENT, 0, 0L));
-    case CB_DIR:
-		dprintf_combo(stddeb,"ComboBox CB_DIR !\n");
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-		return(SendMessage(lphc->hWndLBox, LB_DIR, wParam, lParam));
-	case CB_FINDSTRING:
-		lphc = ComboGetStorageHeader(hwnd);
-		return(SendMessage(lphc->hWndLBox, LB_FINDSTRING, wParam, lParam));
-	case CB_GETCOUNT:
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-		return(SendMessage(lphc->hWndLBox, LB_GETCOUNT, 0, 0L));
-	case CB_GETCURSEL:
-		dprintf_combo(stddeb,"ComboBox CB_GETCURSEL !\n");
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-		return(SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L));
-    case CB_SETCURSEL:
-		dprintf_combo(stddeb,"ComboBox CB_SETCURSEL wParam=%X !\n", wParam);
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-		return(SendMessage(lphc->hWndLBox, LB_SETCURSEL, wParam, 0L));
-	case CB_GETEDITSEL:
-		dprintf_combo(stddeb,"ComboBox CB_GETEDITSEL !\n");
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-/*		if (lphc->hWndEdit != 0)
-			return(SendMessage(lphc->hWndEdit, EM_GETSEL, 0, 0L)); */
-		break;
-	case CB_SETEDITSEL:
-		dprintf_combo(stddeb,"ComboBox CB_SETEDITSEL lParam=%lX !\n", 
-			      lParam);
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-/*		if (lphc->hWndEdit != 0)
-			return(SendMessage(lphc->hWndEdit, EM_SETSEL, 0, lParam)); */
-		break;
-	case CB_SELECTSTRING:
-		dprintf_combo(stddeb,"ComboBox CB_SELECTSTRING !\n");
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-		break;
-	case CB_SHOWDROPDOWN:
-		dprintf_combo(stddeb,"ComboBox CB_SHOWDROPDOWN !\n");
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-		wndPtr = WIN_FindWndPtr(hwnd);
-		lphc->dwState = lphc->dwState | CB_SHOWDROPDOWN;
-		if (wParam != 0) {
-			GetWindowRect(hwnd, &rect);
-			SetWindowPos(lphc->hWndLBox, 0, rect.left, rect.bottom, 0, 0, 
-								SWP_NOREDRAW | SWP_NOSIZE); 
-			SetWindowPos(lphc->hWndLBox, 0, 0, 0, 0, 0, SWP_SHOWWINDOW | 
-								SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); 
-			}
-		else {
-			lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN;
-			ShowWindow(lphc->hWndLBox, SW_HIDE);
-			SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
-									MAKELONG(hwnd, CBN_DROPDOWN));
-		}
-		break;
-    case CB_GETITEMDATA:
-		dprintf_combo(stddeb,"ComboBox CB_GETITEMDATA wParam=%X !\n", wParam);
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-		return(SendMessage(lphc->hWndLBox, LB_GETITEMDATA, wParam, 0L));
-        break;
-    case CB_SETITEMDATA:
-		dprintf_combo(stddeb,"ComboBox CB_SETITEMDATA wParam=%04X lParam=%08lX!\n", wParam, lParam);
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-		return(SendMessage(lphc->hWndLBox, LB_SETITEMDATA, wParam, lParam));
-        break;
-    case CB_LIMITTEXT:
-		dprintf_combo(stddeb,"ComboBox CB_LIMITTEXT !\n");
-		lphc = ComboGetStorageHeader(hwnd);
-		if (lphc == NULL) return 0;
-/*		if (lphc->hWndEdit != 0) 
-	        return(SendMessage(lphc->hWndEdit, EM_LIMITTEXT, wParam, 0L)); */
-        break;
-
-    default:
-		return DefWindowProc( hwnd, message, wParam, lParam );
+  while (idx < table_size) {
+    if (message == combo_tbl[idx].message) {
+      return (*(combo_tbl[idx].handler))(hwnd, message, wParam, lParam);
     }
-return 0;
+    idx++;
+  }
+  return DefWindowProc (hwnd, message, wParam, lParam);
 }
 
+/*--------------------------------------------------------------------*/
+/* ComboLBox code starts here */
 
-
-LPHEADCOMBO ComboGetStorageHeader(HWND hwnd)
+HWND CLBoxGetCombo(HWND hwnd)
 {
-	WND  *wndPtr;
-	LPHEADCOMBO lphc;
-	wndPtr = WIN_FindWndPtr(hwnd);
-	if (wndPtr == 0) {
-		fprintf(stderr,"Bad Window handle on ComboBox !\n");
-		return 0;
-		}
-	lphc = *((LPHEADCOMBO *)&wndPtr->wExtra[1]);
-	return lphc;
+  return GetWindowWord(hwnd,0);
 }
 
-
-
-int CreateComboStruct(HWND hwnd)
+LPHEADLIST CLBoxGetListHeader(HWND hwnd)
 {
-	WND  *wndPtr;
-	LPHEADCOMBO lphc;
-	wndPtr = WIN_FindWndPtr(hwnd);
-	if (wndPtr == 0) {
-		fprintf(stderr,"Bad Window handle on ComboBox !\n");
-		return 0;
-		}
-	lphc = (LPHEADCOMBO)malloc(sizeof(HEADCOMBO));
-	*((LPHEADCOMBO *)&wndPtr->wExtra[1]) = lphc;
-	lphc->hWndEdit = 0;
-	lphc->hWndLBox = 0;
-	lphc->dwState = 0;
-	lphc->LastSel = -1;
-	return TRUE;
+  return ComboGetListHeader(CLBoxGetCombo(hwnd));
 }
 
-
-void ComboBoxStaticOwnerDraw(HWND hWnd, LPHEADCOMBO lphc)
+/***********************************************************************
+ *           CBLCreate
+ */
+static LONG CBLCreate( HWND hwnd, WORD message, WORD wParam, LONG lParam )
 {
-	HDC     hDC;
-	HBRUSH  hBrush;
-	short   y;
-	LPSTR   ptr = NULL;
-	HANDLE  hTemp;
-	WND       *wndPtr;
-	LPDRAWITEMSTRUCT lpdis;
-	dprintf_combo(stddeb,"ComboBoxStaticOwnerDraw(%04X, %p) !\n", hWnd, lphc);
-	y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
-	if (y != LB_ERR) {
-		ptr = (LPSTR)SendMessage(lphc->hWndLBox, LB_GETITEMDATA, y, 0L);
-		}
-	hDC = GetDC(hWnd);
-	hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
-						MAKELONG(hWnd, CTLCOLOR_STATIC)); 
-	if (hBrush == (HBRUSH)NULL)  hBrush = GetStockObject(WHITE_BRUSH);
-	wndPtr = WIN_FindWndPtr(hWnd);
-	if (wndPtr == NULL) return;
-	hTemp = USER_HEAP_ALLOC( sizeof(DRAWITEMSTRUCT) );
-	lpdis = (LPDRAWITEMSTRUCT) USER_HEAP_LIN_ADDR(hTemp);
-	if (lpdis == NULL) {
-		printf("ComboBox Ownerdraw // Error allocating DRAWITEMSTRUCT !\n");
-                ReleaseDC( hWnd, hDC );
-		return;
-		}
-	FillRect(hDC, &lphc->RectEdit, hBrush);
-	lpdis->hDC = hDC;
-	if (y != LB_ERR) lpdis->itemID = y - 1;
-	CopyRect(&lpdis->rcItem, &lphc->RectEdit);
-	lpdis->itemData = (DWORD)ptr;
-	lpdis->itemAction = ODA_DRAWENTIRE;
-	lpdis->CtlType = ODT_COMBOBOX;
-	lpdis->CtlID = wndPtr->wIDmenu;
-	SendMessage(GetParent(hWnd), WM_DRAWITEM, y,USER_HEAP_SEG_ADDR(hTemp));
-	USER_HEAP_FREE(hTemp);
-	ReleaseDC(hWnd, hDC);
+  CREATESTRUCT *createStruct = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam);
+  SetWindowWord(hwnd,0,LOWORD(createStruct->lpCreateParams));
+  return 0;
 }
 
+/***********************************************************************
+ *           CBLGetDlgCode
+ */
+static LONG CBLGetDlgCode( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+{
+  return DLGC_WANTARROWS | DLGC_WANTCHARS;
+}
+
+/***********************************************************************
+ *           CBLKeyDown
+ */
+static LONG CBLKeyDown( HWND hwnd, WORD message, WORD wParam, LONG lParam ) 
+{
+  LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
+  WORD newFocused = lphl->ItemFocused;
+
+  switch(wParam) {
+  case VK_HOME:
+    newFocused = 0;
+    break;
+  case VK_END:
+    newFocused = lphl->ItemsCount - 1;
+    break;
+  case VK_UP:
+    if (newFocused > 0) newFocused--;
+    break;
+  case VK_DOWN:
+    newFocused++;
+    break;
+  case VK_PRIOR:
+    if (newFocused > lphl->ItemsVisible) {
+      newFocused -= lphl->ItemsVisible;
+    } else {
+      newFocused = 0;
+    }
+    break;
+  case VK_NEXT:
+    newFocused += lphl->ItemsVisible;
+    break;
+  default:
+    return 0;
+  }
+
+  if (newFocused >= lphl->ItemsCount)
+    newFocused = lphl->ItemsCount - 1;
+  
+  ListBoxSetCurSel(lphl, newFocused);
+  ListBoxSendNotification(lphl, hwnd, CBN_SELCHANGE);
+
+  lphl->ItemFocused = newFocused;
+  ListBoxScrollToFocus(lphl);
+  SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+  InvalidateRect(hwnd, NULL, TRUE);  
+  return 0;
+}
+
+/***********************************************************************
+ *           CBLChar
+ */
+static LONG CBLChar( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+{
+  return 0;
+}
+
+/***********************************************************************
+ *           CBLPaint
+ */
+static LONG CBLPaint( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+{
+  LPHEADLIST   lphl = CLBoxGetListHeader(hwnd);
+  LPLISTSTRUCT lpls;
+  PAINTSTRUCT  ps;
+  HBRUSH       hBrush;
+  HFONT        hOldFont;
+  HDC 	hdc;
+  RECT 	rect;
+  int   i, top, height;
+
+  top = 0;
+  hdc = BeginPaint( hwnd, &ps );
+
+  if (!IsWindowVisible(hwnd) || !lphl->bRedrawFlag) {
+    EndPaint(hwnd, &ps);
+    return 0;
+  }
+
+  hOldFont = SelectObject(hdc, lphl->hFont);
+  hBrush = SendMessage(lphl->hParent, WM_CTLCOLOR, hdc,
+		       MAKELONG(hwnd, CTLCOLOR_LISTBOX));
+
+  if (hBrush == 0) hBrush = GetStockObject(WHITE_BRUSH);
+
+  GetClientRect(hwnd, &rect);
+  FillRect(hdc, &rect, hBrush);
+
+  lpls = lphl->lpFirst;
+
+  lphl->ItemsVisible = 0;
+  for(i = 0; i < lphl->ItemsCount; i++) {
+    if (lpls == NULL) break;
+
+    if (i >= lphl->FirstVisible) {
+      height = lpls->mis.itemHeight;
+
+      if (top > rect.bottom) break;
+      lpls->itemRect.top    = top;
+      lpls->itemRect.bottom = top + height;
+      lpls->itemRect.left   = rect.left;
+      lpls->itemRect.right  = rect.right;
+
+      dprintf_listbox(stddeb,"drawing item: %d %d %d %d %d\n",rect.left,top,rect.right,top+height,lpls->itemState);
+      if (OWNER_DRAWN(lphl)) {
+	ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_DRAWENTIRE, 0);
+	if (lpls->itemState)
+	  ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_SELECT, ODS_SELECTED);
+      } else {
+	ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_DRAWENTIRE, 
+			 lpls->itemState);
+      }
+      if ((lphl->ItemFocused == i) && GetFocus() == hwnd)
+	ListBoxDrawItem (hwnd,lphl, hdc, lpls, &lpls->itemRect, ODA_FOCUS, ODS_FOCUS);
+
+      top += height;
+      lphl->ItemsVisible++;
+    }
+
+    lpls = lpls->lpNext;
+  }
+  SelectObject(hdc,hOldFont);
+  EndPaint( hwnd, &ps );
+  return 0;
+
+}
+
+/***********************************************************************
+ *           CBLKillFocus
+ */
+static LONG CBLKillFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+{
+/*  SendMessage(CLBoxGetCombo(hwnd),CB_SHOWDROPDOWN,0,0);*/
+  return 0;
+}
+
+/***********************************************************************
+ *           CBLActivate
+ */
+static LONG CBLActivate( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+{
+  if (wParam == WA_INACTIVE)
+    SendMessage(CLBoxGetCombo(hwnd),CB_SHOWDROPDOWN,0,0);
+  return 0;
+}
+
+/***********************************************************************
+ *           CBLLButtonDown
+ */
+static LONG CBLLButtonDown( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+{
+  LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
+  WORD       wRet;
+  int        y;
+  RECT       rectsel;
+
+  SetFocus(hwnd);
+  SetCapture(hwnd);
+
+  lphl->PrevFocused = lphl->ItemFocused;
+
+  y = ListBoxFindMouse(lphl, LOWORD(lParam), HIWORD(lParam));
+  if (y == -1)
+    return 0;
+
+  ListBoxSetCurSel(lphl, y);
+  ListBoxGetItemRect(lphl, y, &rectsel);
+
+  InvalidateRect(hwnd, NULL, TRUE);
+  return 0;
+}
+
+/***********************************************************************
+ *           CBLLButtonUp
+ */
+static LONG CBLLButtonUp( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+{
+  LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
+
+  if (GetCapture() == hwnd) ReleaseCapture();
+
+  if (lphl->PrevFocused != lphl->ItemFocused) {
+    SendMessage(CLBoxGetCombo(hwnd),CB_SETCURSEL,lphl->ItemFocused,0);
+    ListBoxSendNotification(lphl, CLBoxGetCombo(hwnd), CBN_SELCHANGE);
+  }
+  SendMessage(CLBoxGetCombo(hwnd),CB_SHOWDROPDOWN,0,0);
+
+  return 0;
+}
+
+/***********************************************************************
+ *           CBLMouseMove
+ */
+static LONG CBLMouseMove( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+{
+  LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
+  int  y;
+  WORD wRet;
+  RECT rect, rectsel;   /* XXX Broken */
+
+  if ((wParam & MK_LBUTTON) != 0) {
+    y = SHIWORD(lParam);
+    if (y < 0) {
+      if (lphl->FirstVisible > 0) {
+	lphl->FirstVisible--;
+	SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+	InvalidateRect(hwnd, NULL, TRUE);
+	return 0;
+      }
+    }
+    GetClientRect(hwnd, &rect);
+    if (y >= rect.bottom) {
+      if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) {
+	lphl->FirstVisible++;
+	SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+	InvalidateRect(hwnd, NULL, TRUE);
+	return 0;
+      }
+    }
+    if ((y > 0) && (y < (rect.bottom - 4))) {
+      if ((y < rectsel.top) || (y > rectsel.bottom)) {
+	wRet = ListBoxFindMouse(lphl, LOWORD(lParam), HIWORD(lParam));
+	if (wRet == lphl->ItemFocused) return 0;
+	ListBoxSetCurSel(lphl, wRet);
+	ListBoxGetItemRect(lphl, wRet, &rectsel);
+	InvalidateRect(hwnd, NULL, TRUE);
+      }
+    }
+  }
+
+  return 0;
+}
+
+/***********************************************************************
+ *           CBLVScroll
+ */
+static LONG CBLVScroll( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+{
+  LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
+  int  y;
+
+  y = lphl->FirstVisible;
+
+  switch(wParam) {
+  case SB_LINEUP:
+    if (lphl->FirstVisible > 0)
+      lphl->FirstVisible--;
+    break;
+
+  case SB_LINEDOWN:
+    lphl->FirstVisible++;
+    break;
+
+  case SB_PAGEUP:
+    if (lphl->FirstVisible > lphl->ItemsVisible) {
+      lphl->FirstVisible -= lphl->ItemsVisible;
+    } else {
+      lphl->FirstVisible = 0;
+    }
+    break;
+
+  case SB_PAGEDOWN:
+    lphl->FirstVisible += lphl->ItemsVisible;
+    break;
+
+  case SB_THUMBTRACK:
+    lphl->FirstVisible = LOWORD(lParam);
+    break;
+  }
+
+  if (lphl->FirstVisible > ListMaxFirstVisible(lphl))
+    lphl->FirstVisible = ListMaxFirstVisible(lphl);
+
+  if (y != lphl->FirstVisible) {
+    SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+    InvalidateRect(hwnd, NULL, TRUE);
+  }
+
+  return 0;
+}
+
+/***********************************************************************
+ *           ComboLBoxWndProc
+ */
+LONG ComboLBoxWndProc(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  int idx = 0;
+  int table_size = sizeof (clbox_tbl) / sizeof (msg_tbl);
+
+  while (idx < table_size) {
+    if (message == clbox_tbl[idx].message) {
+      return (*(clbox_tbl[idx].handler))(hwnd, message, wParam, lParam);
+    }
+    idx++;
+  }
+  return DefWindowProc (hwnd, message, wParam, lParam);
+}
 
 /************************************************************************
- * 					DlgDirSelectComboBox	[USER.194]
+ * 			       	DlgDirSelectComboBox	[USER.194]
  */
 BOOL DlgDirSelectComboBox(HWND hDlg, LPSTR lpStr, int nIDLBox)
 {
@@ -523,19 +1036,48 @@
 /************************************************************************
  * 					DlgDirListComboBox     [USER.195]
  */
-int DlgDirListComboBox(HWND hDlg, SEGPTR lpPathSpec, 
-	int nIDLBox, int nIDStat, WORD wType)
+int DlgDirListComboBox(HWND hDlg, SEGPTR PathSpec,
+		       int nIDLBox, int nIDStat, WORD wType)
 {
-	HWND		hWnd;
-	LPHEADCOMBO lphc;
-	dprintf_combo(stddeb,"DlgDirListComboBox(%04X, '%s', %d, %d, %04X) \n",
-			hDlg, (char *)PTR_SEG_TO_LIN(lpPathSpec), nIDLBox, nIDStat, wType);
-	hWnd = GetDlgItem(hDlg, nIDLBox);
-	lphc = ComboGetStorageHeader(hWnd);
-	if (lphc == NULL) return 0;
-	SendMessage(lphc->hWndLBox, LB_RESETCONTENT, 0, 0L);
-	return SendMessage(lphc->hWndLBox, LB_DIR, wType, (DWORD)lpPathSpec);
+  HWND	hWnd;
+  int ret;
+  LPSTR lpPathSpec = PTR_SEG_TO_LIN(PathSpec);
+  
+  dprintf_combo(stddeb,"DlgDirListComboBox(%04X, '%s', %d, %d, %04X) \n",
+		  hDlg, lpPathSpec, nIDLBox, nIDStat, wType);
+  if (nIDLBox) {
+    LPHEADLIST lphl;
+    LPHEADCOMBO lphc;
+    hWnd = GetDlgItem(hDlg, nIDLBox);
+    lphl = ComboGetListHeader(hWnd);
+    lphc = ComboGetStorageHeader(hWnd);
+    ListBoxResetContent(lphl);
+    ret = ListBoxDirectory(lphl, wType, lpPathSpec);
+    ComboUpdateWindow(hWnd, lphl, lphc, TRUE);
+  } else {
+    ret = 0;
+  }
+  if (nIDStat) {
+      int drive;
+      HANDLE hTemp;
+      char *temp;
+      drive = DOS_GetDefaultDrive();
+      hTemp = USER_HEAP_ALLOC( 256 );
+      temp = (char *) USER_HEAP_LIN_ADDR( hTemp );
+      strcpy( temp+3, DOS_GetCurrentDir(drive) );
+      if( temp[3] == '\\' ) {
+	temp[1] = 'A'+drive;
+	temp[2] = ':';
+	SendDlgItemMessage( hDlg, nIDStat, WM_SETTEXT, 0,
+                            USER_HEAP_SEG_ADDR(hTemp) + 1 );
+      } else {
+	temp[0] = 'A'+drive;
+	temp[1] = ':';
+	temp[2] = '\\';
+	SendDlgItemMessage( hDlg, nIDStat, WM_SETTEXT, 0,
+                            USER_HEAP_SEG_ADDR(hTemp) );
+      }
+      USER_HEAP_FREE( hTemp );
+  } 
+  return ret;
 }
-
-
-
diff --git a/controls/desktop.c b/controls/desktop.c
index 9ba78b4..096092e 100644
--- a/controls/desktop.c
+++ b/controls/desktop.c
@@ -114,31 +114,6 @@
 
 
 /***********************************************************************
- *           DESKTOP_Init
- *
- * Initialize the desktop window private information.
- */
-BOOL DESKTOP_Init()
-{
-    HWND hwnd = GetDesktopWindow();
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-    DESKTOPINFO *infoPtr = (DESKTOPINFO *)wndPtr->wExtra;
-
-    infoPtr->hbrushPattern = 0;
-    infoPtr->hbitmapWallPaper = 0;
-    SetDeskPattern();
-    SetDeskWallPaper( (LPSTR)-1 );
-    if (rootWindow != DefaultRootWindow(display))
-    {
-        HDC hdc = GetDC( hwnd );
-        DESKTOP_DoEraseBkgnd( hwnd, hdc, infoPtr );
-        ReleaseDC( hwnd, hdc );
-    }
-    return TRUE;
-}
-
-
-/***********************************************************************
  *           DesktopWndProc
  *
  * Window procedure for the desktop window.
diff --git a/controls/listbox.c b/controls/listbox.c
index d20e568..75b1a37 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -1,18 +1,21 @@
 /*
- * Interface code to listbox widgets
- *
+ * Listbox controls
+ * 
  * Copyright  Martin Ayotte, 1993
  * Copyright  Constantine Sapuntzakis, 1995
- *
-static char Copyright[] = "Copyright Martin Ayotte, 1993";
-*/
+ * 
+ */
+
+ /*
+  * TODO: 
+  * - check if multi-column listboxes work
+  * - implement more messages and styles
+  */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
 #include "windows.h"
 #include "user.h"
 #include "win.h"
@@ -22,43 +25,6 @@
 #include "stddebug.h"
 #include "debug.h"
 
-#define GMEM_ZEROINIT 0x0040
-
-LPLISTSTRUCT ListBoxGetItem (HWND hwnd, UINT uIndex);
-int ListBoxScrolltoFocus(HWND hwnd);
-LPHEADLIST ListBoxGetWindowAndStorage(HWND hwnd, WND **wndPtr);
-LPHEADLIST ListBoxGetStorageHeader(HWND hwnd);
-void RepaintListBox(HWND hwnd);
-int ListBoxFindMouse(HWND hwnd, int X, int Y);
-int CreateListBoxStruct(HWND hwnd);
-void ListBoxAskMeasure(WND *wndPtr, LPHEADLIST lphl, LPLISTSTRUCT lpls);
-int ListBoxAddString(HWND hwnd, LPSTR newstr);
-int ListBoxInsertString(HWND hwnd, UINT uIndex, LPSTR newstr);
-int ListBoxGetText(HWND hwnd, UINT uIndex, LPSTR OutStr, BOOL bItemData);
-int ListBoxSetItemData(HWND hwnd, UINT uIndex, DWORD ItemData);
-int ListBoxDeleteString(HWND hwnd, UINT uIndex);
-int ListBoxFindString(HWND hwnd, UINT nFirst, LPSTR MatchStr);
-int ListBoxResetContent(HWND hwnd);
-int ListBoxSetCurSel(HWND hwnd, WORD wIndex);
-int ListBoxSetSel(HWND hwnd, WORD wIndex, WORD state);
-int ListBoxGetSel(HWND hwnd, WORD wIndex);
-int ListBoxDirectory(HWND hwnd, UINT attrib, LPSTR filespec);
-int ListBoxGetItemRect(HWND hwnd, WORD wIndex, LPRECT rect);
-int ListBoxSetItemHeight(HWND hwnd, WORD wIndex, long height);
-int ListBoxDefaultItem(HWND hwnd, WND *wndPtr, 
-	LPHEADLIST lphl, LPLISTSTRUCT lpls);
-int ListBoxFindNextMatch(HWND hwnd, WORD wChar);
-int ListMaxFirstVisible(LPHEADLIST lphl);
-void ListBoxSendNotification(HWND hwnd, WORD code);
-
-#define OWNER_DRAWN(wndPtr) \
-  ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) ||  \
-   (wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE))
-
-#define HasStrings(wndPtr) (  \
-  (! OWNER_DRAWN (wndPtr)) || \
-  (wndPtr->dwStyle & LBS_HASSTRINGS))
-
 #if 0
 #define LIST_HEAP_ALLOC(lphl,f,size) ((int)HEAP_Alloc(&lphl->Heap,f,size) & 0xffff)
 #define LIST_HEAP_FREE(lphl,handle) (HEAP_Free(&lphl->Heap,LIST_HEAP_ADDR(lphl,handle)))
@@ -76,52 +42,52 @@
 
 /* Design notes go here */
 
-LONG LBCreate( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBGetDlgCode( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBDestroy( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBVScroll( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBHScroll( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBLButtonDown( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBLButtonUp( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBRButtonUp( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBMouseMove( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBKeyDown( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBSetFont( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBSetRedraw( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBPaint( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBSetFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBKillFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBResetContent( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBDir( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBAddString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBGetText( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBInsertString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBDeleteString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBFindString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBGetCaretIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBGetCount( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBGetCurSel( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBGetHorizontalExtent(HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBGetItemData( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBGetItemHeight( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBGetItemRect( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBGetSel( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBGetSelCount( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBGetSelItems( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBGetTextLen( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBGetTopIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBSelectString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBSelItemRange( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBSetCaretIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBSetColumnWidth( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBSetHorizontalExtent(HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBSetItemData( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBSetTabStops( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBSetCurSel( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBSetSel( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBSetTopIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-LONG LBSetItemHeight( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-
+static LONG LBCreate( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBGetDlgCode( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBDestroy( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBVScroll( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBHScroll( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBLButtonDown( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBLButtonUp( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBRButtonUp( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBMouseMove( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBKeyDown( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBChar( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBSetFont( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBSetRedraw( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBPaint( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBSetFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBKillFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBResetContent( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBDir( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBAddString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBGetText( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBInsertString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBDeleteString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBFindString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBGetCaretIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBGetCount( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBGetCurSel( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBGetHorizontalExtent(HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBGetItemData( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBGetItemHeight( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBGetItemRect( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBGetSel( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBGetSelCount( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBGetSelItems( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBGetTextLen( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBGetTopIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBSelectString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBSelItemRange( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBSetCaretIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBSetColumnWidth( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBSetHorizontalExtent(HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBSetItemData( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBSetTabStops( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBSetCurSel( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBSetSel( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBSetTopIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+static LONG LBSetItemHeight( HWND hwnd, WORD message, WORD wParam, LONG lParam );
 
 typedef struct {
   WORD   message;
@@ -140,6 +106,7 @@
   {WM_LBUTTONDBLCLK, LBRButtonUp},
   {WM_MOUSEMOVE, LBMouseMove},
   {WM_KEYDOWN, LBKeyDown},
+  {WM_CHAR, LBChar},
   {WM_SETFONT, LBSetFont},
   {WM_SETREDRAW, LBSetRedraw},
   {WM_PAINT, LBPaint},
@@ -177,144 +144,732 @@
   {LB_SETITEMHEIGHT, LBSetItemHeight}
 };
 
-/***********************************************************************
- *           LBCreate
- */
-LONG LBCreate( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+BOOL OWNER_DRAWN(LPHEADLIST lphl)
 {
-  LPHEADLIST  lphl;
-  CREATESTRUCT *createStruct;
-  WND          *wndPtr;
-
-  CreateListBoxStruct(hwnd);
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-
-  dprintf_listbox(stddeb,"ListBox WM_CREATE %p !\n", lphl);
-
-  if (lphl == NULL) return 0;
-
-  createStruct = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam);
-
-  if (HIWORD(createStruct->lpCreateParams) != 0)
-    lphl->hWndLogicParent = (HWND)HIWORD(createStruct->lpCreateParams);
-  else
-    lphl->hWndLogicParent = GetParent(hwnd);
-
-  lphl->hFont = GetStockObject(SYSTEM_FONT);
-  lphl->ColumnsWidth = wndPtr->rectClient.right - wndPtr->rectClient.left;
-
-  SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), TRUE);
-  SetScrollRange(hwnd, SB_HORZ, 1, 1, TRUE);
-
-  return 0;
+  return lphl->dwStyle & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE);
 }
 
-int CreateListBoxStruct(HWND hwnd)
-
+BOOL HasStrings(LPHEADLIST lphl)
 {
-  WND  *wndPtr;
-  LPHEADLIST lphl;
+  return (lphl->dwStyle & LBS_HASSTRINGS) || !OWNER_DRAWN(lphl);
+}
 
-  wndPtr = WIN_FindWndPtr(hwnd);
-
-  lphl = (LPHEADLIST)malloc(sizeof(HEADLIST));
-  *((LPHEADLIST *)&wndPtr->wExtra[1]) = lphl;
-
+static void ListBoxInitialize(LPHEADLIST lphl)
+{
   lphl->lpFirst        = NULL;
   lphl->ItemsCount     = 0;
   lphl->ItemsVisible   = 0;
-  lphl->FirstVisible   = 1;
+  lphl->FirstVisible   = 0;
   lphl->ColumnsVisible = 1;
   lphl->ItemsPerColumn = 0;
-  lphl->StdItemHeight  = 15;
   lphl->ItemFocused    = -1;
   lphl->PrevFocused    = -1;
-  lphl->DrawCtlType    = ODT_LISTBOX;
+}
+
+void CreateListBoxStruct(HWND hwnd, WORD CtlType, LONG styles, HWND parent)
+{
+  LPHEADLIST lphl;
+
+  lphl = (LPHEADLIST)malloc(sizeof(HEADLIST));
+  SetWindowLong(hwnd, 0, (LONG)lphl);
+  if (lphl == NULL) {
+    fprintf(stderr,"malloc failed in CreateListBoxStruct()\n");
+    exit(1); /* Things won't get better */
+  }
+
+  ListBoxInitialize(lphl);
+  lphl->DrawCtlType    = CtlType;
+  lphl->CtlID          = GetWindowWord(hwnd,GWW_ID);
   lphl->bRedrawFlag    = TRUE;
   lphl->iNumStops      = 0;
   lphl->TabStops       = NULL;
+  lphl->hFont          = GetStockObject(SYSTEM_FONT);
+  lphl->hParent        = parent;
+  lphl->StdItemHeight  = 15; /* FIXME: should get the font height */
+  lphl->dwStyle        = styles;
 
-  if (OWNER_DRAWN(wndPtr)) 
+  if (OWNER_DRAWN(lphl)) {
+    LISTSTRUCT dummyls;
+    
     lphl->hDrawItemStruct = USER_HEAP_ALLOC(sizeof(DRAWITEMSTRUCT));
-  else
+    lphl->needMeasure = TRUE;
+    dummyls.mis.CtlType    = lphl->DrawCtlType;
+    dummyls.mis.CtlID      = lphl->CtlID;
+    dummyls.mis.itemID     = -1;
+    dummyls.mis.itemWidth  = 0; /* ignored */
+    dummyls.mis.itemData   = 0;
+
+    ListBoxAskMeasure(lphl,&dummyls);
+  } else {
     lphl->hDrawItemStruct = 0;
+  }
 
 #if 0
   HeapHandle = GlobalAlloc(GMEM_FIXED, LIST_HEAP_SIZE);
   HeapBase = GlobalLock(HeapHandle);
   HEAP_Init(&lphl->Heap, HeapBase, LIST_HEAP_SIZE);
 #endif
-  return TRUE;
 }
 
-
-/***********************************************************************
- *           LBDestroy
- */
-LONG LBDestroy( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+void DestroyListBoxStruct(LPHEADLIST lphl)
 {
-  LPHEADLIST lphl;
-  WND        *wndPtr;
-
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-
-  if (lphl == NULL) return 0;
-  ListBoxResetContent(hwnd);
-
   if (lphl->hDrawItemStruct)
     USER_HEAP_FREE(lphl->hDrawItemStruct);
 
   /* XXX need to free lphl->Heap */
   free(lphl);
-  *((LPHEADLIST *)&wndPtr->wExtra[1]) = 0;
-  dprintf_listbox(stddeb,"ListBox WM_DESTROY %p !\n", lphl);
-  return 0;
 }
 
+static LPHEADLIST ListBoxGetStorageHeader(HWND hwnd)
+{
+    return (LPHEADLIST)GetWindowLong(hwnd,0);
+}
+
+/* Send notification "code" as part of a WM_COMMAND-message if hwnd
+   has the LBS_NOTIFY style */
+void ListBoxSendNotification(LPHEADLIST lphl, HWND hwnd, WORD code)
+{
+  if (lphl->dwStyle & LBS_NOTIFY)
+    SendMessage(lphl->hParent, WM_COMMAND,
+		lphl->CtlID, MAKELONG(hwnd, code));
+}
+
+
 /* get the maximum value of lphl->FirstVisible */
 int ListMaxFirstVisible(LPHEADLIST lphl)
 {
-    int m = lphl->ItemsCount-lphl->ItemsVisible+1;
-    return (m < 1) ? 1 : m;
+    int m = lphl->ItemsCount-lphl->ItemsVisible;
+    return (m < 0) ? 0 : m;
 }
 
 
+void ListBoxUpdateWindow(HWND hwnd, LPHEADLIST lphl, BOOL repaint)
+{
+  SetScrollRange(hwnd, SB_VERT, 0, ListMaxFirstVisible(lphl), TRUE);
+  if (lphl->ItemsPerColumn != 0) {
+    SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible /
+		   lphl->ItemsPerColumn + 1, TRUE);
+  }
+  if (repaint && lphl->bRedrawFlag) {
+    InvalidateRect(hwnd, NULL, TRUE);
+  }
+}
+
+/* Returns: 0 if nothing needs to be changed */
+/*          1 if FirstVisible changed */
+
+int ListBoxScrollToFocus(LPHEADLIST lphl)
+{
+  short       end;
+
+  if (lphl->ItemsCount == 0) return 0;
+  if (lphl->ItemFocused == -1) return 0;
+
+  end = lphl->FirstVisible + lphl->ItemsVisible - 1;
+
+  if (lphl->ItemFocused < lphl->FirstVisible ) {
+    lphl->FirstVisible = lphl->ItemFocused;
+    return 1;
+  } else {
+    if (lphl->ItemFocused > end) {
+      WORD maxFirstVisible = ListMaxFirstVisible(lphl);
+
+      lphl->FirstVisible = lphl->ItemFocused;
+      
+      if (lphl->FirstVisible > maxFirstVisible) {
+	lphl->FirstVisible = maxFirstVisible;
+      }
+      return 1;
+    }
+  } 
+  return 0;
+}
+
+
+LPLISTSTRUCT ListBoxGetItem(LPHEADLIST lphl, UINT uIndex)
+{
+  LPLISTSTRUCT lpls;
+  UINT         Count = 0;
+
+  if (uIndex >= lphl->ItemsCount) return NULL;
+
+  lpls = lphl->lpFirst;
+  while (Count++ < uIndex) lpls = lpls->lpNext;
+  return lpls;
+}
+
+
+void ListBoxDrawItem (HWND hwnd, LPHEADLIST lphl, HDC hdc, LPLISTSTRUCT lpls, 
+		      RECT *rect, WORD itemAction, WORD itemState)
+{
+  if (OWNER_DRAWN(lphl)) {
+    DRAWITEMSTRUCT   *dis = USER_HEAP_LIN_ADDR(lphl->hDrawItemStruct);
+
+    dis->CtlID    = lpls->mis.CtlID;
+    dis->CtlType  = lpls->mis.CtlType;
+    dis->itemID   = lpls->mis.itemID;
+    dis->hDC      = hdc;
+    dis->hwndItem = hwnd;
+    dis->itemData = lpls->mis.itemData;
+    dis->itemAction = itemAction;
+    dis->itemState  = itemState;
+    dis->rcItem     = *rect;
+    SendMessage(lphl->hParent, WM_DRAWITEM,
+		0, (LPARAM)USER_HEAP_SEG_ADDR(lphl->hDrawItemStruct));
+  } else {
+    if (itemAction == ODA_DRAWENTIRE || itemAction == ODA_SELECT) {
+      int 	OldBkMode;
+      DWORD 	dwOldTextColor = 0;
+
+      OldBkMode = SetBkMode(hdc, TRANSPARENT);
+
+      if (itemState != 0) {
+	dwOldTextColor = SetTextColor(hdc, 0x00FFFFFFL);
+	FillRect(hdc, rect, GetStockObject(BLACK_BRUSH));
+      }
+
+      if (lphl->dwStyle & LBS_USETABSTOPS) {
+	TabbedTextOut(hdc, rect->left + 5, rect->top + 2, 
+		      (char *)lpls->itemText, strlen((char *)lpls->itemText), 
+		      lphl->iNumStops, lphl->TabStops, 0);
+      } else {
+	TextOut(hdc, rect->left + 5, rect->top + 2,
+		(char *)lpls->itemText, strlen((char *)lpls->itemText));
+      }
+
+      if (itemState != 0) {
+	SetTextColor(hdc, dwOldTextColor);
+      }
+      
+      SetBkMode(hdc, OldBkMode);
+    } else DrawFocusRect(hdc, rect);
+  }
+
+  return;
+}
+
+
+int ListBoxFindMouse(LPHEADLIST lphl, int X, int Y)
+{
+  LPLISTSTRUCT lpls = lphl->lpFirst;
+  int          i, j;
+  POINT        point;
+  
+  point.x = X; point.y = Y;
+  if (lphl->ItemsCount == 0) return LB_ERR;
+
+  for(i = 0; i < lphl->FirstVisible; i++) {
+    if (lpls == NULL) return LB_ERR;
+    lpls = lpls->lpNext;
+  }
+  for(j = 0; j < lphl->ItemsVisible; i++, j++) {
+    if (lpls == NULL) return LB_ERR;
+    if (PtInRect(&lpls->itemRect,point)) {
+      return i;
+    }
+    lpls = lpls->lpNext;
+  }
+  dprintf_listbox(stddeb,"ListBoxFindMouse: not found\n");
+  return LB_ERR;
+}
+
+
+void ListBoxAskMeasure(LPHEADLIST lphl, LPLISTSTRUCT lpls)  
+{
+  HANDLE hTemp = USER_HEAP_ALLOC( sizeof(MEASUREITEMSTRUCT) );
+  MEASUREITEMSTRUCT *lpmeasure = (MEASUREITEMSTRUCT *) USER_HEAP_LIN_ADDR(hTemp);
+
+  if (lpmeasure == NULL) {
+    fprintf(stderr,"ListBoxAskMeasure() out of memory !\n");
+    return;
+  }
+ 
+  *lpmeasure = lpls->mis;
+  lpmeasure->itemHeight = lphl->StdItemHeight;
+  SendMessage(lphl->hParent, WM_MEASUREITEM,
+	      0, USER_HEAP_SEG_ADDR(hTemp));
+
+  if (lphl->dwStyle & LBS_OWNERDRAWFIXED) {
+    lphl->StdItemHeight = lpmeasure->itemHeight;
+    lphl->needMeasure = FALSE;
+  }
+
+  USER_HEAP_FREE(hTemp);			
+}
+
+
+LPLISTSTRUCT ListBoxCreateItem(LPHEADLIST lphl, int id)
+{
+  LPLISTSTRUCT lplsnew = (LPLISTSTRUCT)malloc(sizeof(LISTSTRUCT));
+
+  if (lplsnew == NULL) return NULL;
+  
+  lplsnew->itemState      = 0;
+  lplsnew->mis.CtlType    = lphl->DrawCtlType;
+  lplsnew->mis.CtlID      = lphl->CtlID;
+  lplsnew->mis.itemID     = id;
+  lplsnew->mis.itemHeight = lphl->StdItemHeight;
+  lplsnew->mis.itemWidth  = 0; /* ignored */
+  lplsnew->mis.itemData   = 0;
+  SetRect(&lplsnew->itemRect, 0, 0, 0, 0);
+
+  return lplsnew;
+}
+
+
+int ListBoxInsertString(LPHEADLIST lphl, UINT uIndex, LPSTR newstr)
+{
+  LPLISTSTRUCT *lppls, lplsnew;
+  HANDLE       hStr;
+  LPSTR	str;
+  UINT	Count;
+    
+  dprintf_listbox(stddeb,"ListBoxInsertString(%d, %p);\n", uIndex, newstr);
+    
+  if (uIndex == (UINT)-1)
+    uIndex = lphl->ItemsCount;
+
+  lppls = &lphl->lpFirst;
+  for(Count = 0; Count < uIndex; Count++) {
+    if (*lppls == NULL) return LB_ERR;
+    lppls = (LPLISTSTRUCT *) &(*lppls)->lpNext;
+  }
+    
+  lplsnew = ListBoxCreateItem(lphl, Count);
+  
+  if (lplsnew == NULL) {
+    printf("ListBoxInsertString() out of memory !\n");
+    return LB_ERRSPACE;
+  }
+
+  lplsnew->lpNext = *lppls;
+  *lppls = lplsnew;
+  lphl->ItemsCount++;
+  
+  hStr = 0;
+  if (HasStrings(lphl)) {
+    hStr = LIST_HEAP_ALLOC(lphl, GMEM_MOVEABLE, strlen(newstr) + 1);
+    str = (LPSTR)LIST_HEAP_ADDR(lphl, hStr);
+    if (str == NULL) return LB_ERRSPACE;
+    strcpy(str, newstr);
+    lplsnew->itemText = str;
+    /* I'm not so sure about the next one */
+    lplsnew->mis.itemData = LIST_HEAP_SEG_ADDR(lphl,hStr); 
+  } else {
+    lplsnew->itemText = NULL;
+    lplsnew->mis.itemData = (DWORD)newstr;
+  }
+
+  lplsnew->mis.itemID = lphl->ItemsCount;
+  lplsnew->hData = hStr;
+ 
+  if (lphl->needMeasure) {
+    ListBoxAskMeasure(lphl, lplsnew);
+  }
+
+  dprintf_listbox(stddeb,"ListBoxInsertString // count=%d\n", lphl->ItemsCount);
+  return uIndex;
+}
+
+
+int ListBoxAddString(LPHEADLIST lphl, LPSTR newstr)
+{
+    UINT pos = (UINT) -1;
+    
+    if (HasStrings(lphl) && (lphl->dwStyle & LBS_SORT)) {
+	LPLISTSTRUCT lpls = lphl->lpFirst;
+	for (pos = 0; lpls != NULL; lpls = lpls->lpNext, pos++)
+	    if (strcmp(lpls->itemText, newstr) >= 0)
+		break;
+    }
+    return ListBoxInsertString(lphl, pos, newstr);
+}
+
+
+int ListBoxGetText(LPHEADLIST lphl, UINT uIndex, LPSTR OutStr)
+{
+  LPLISTSTRUCT lpls;
+
+  if (!OutStr) {
+    dprintf_listbox(stddeb, "ListBoxGetText // OutStr==NULL\n");
+    return 0;
+  }
+
+  lpls = ListBoxGetItem (lphl, uIndex);
+  if (lpls == NULL) return LB_ERR;
+
+  if (!HasStrings(lphl)) {
+    *((long *)OutStr) = lpls->mis.itemData;
+    return 4;
+  }
+	
+  strcpy(OutStr, lpls->itemText);
+  return strlen(OutStr);
+}
+
+
+DWORD ListBoxGetItemData(LPHEADLIST lphl, UINT uIndex)
+{
+  LPLISTSTRUCT lpls;
+
+  lpls = ListBoxGetItem (lphl, uIndex);
+  if (lpls == NULL) return LB_ERR;
+  return lpls->mis.itemData;
+}
+
+
+int ListBoxSetItemData(LPHEADLIST lphl, UINT uIndex, DWORD ItemData)
+{
+  LPLISTSTRUCT lpls = ListBoxGetItem(lphl, uIndex);
+
+  if (lpls == NULL) return LB_ERR;
+  lpls->mis.itemData = ItemData;
+  return 1;
+}
+
+
+int ListBoxDeleteString(LPHEADLIST lphl, UINT uIndex)
+{
+  LPLISTSTRUCT lpls;
+  UINT	Count;
+
+  if (uIndex >= lphl->ItemsCount) return LB_ERR;
+
+  lpls = lphl->lpFirst;
+  if (lpls == NULL) return LB_ERR;
+
+  if (uIndex == 0)
+    lphl->lpFirst = lpls->lpNext;
+  else {
+    LPLISTSTRUCT lpls2 = NULL;
+    for(Count = 0; Count < uIndex; Count++) {
+      if (lpls->lpNext == NULL) return LB_ERR;
+
+      lpls2 = lpls;
+      lpls = (LPLISTSTRUCT)lpls->lpNext;
+    }
+    lpls2->lpNext = (LPLISTSTRUCT)lpls->lpNext;
+  }
+
+  lphl->ItemsCount--;
+
+  if (lpls->hData != 0) LIST_HEAP_FREE(lphl, lpls->hData);
+  free(lpls);
+  
+  return lphl->ItemsCount;
+}
+
+
+int ListBoxFindString(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr)
+{
+  LPLISTSTRUCT lpls;
+  UINT	       Count;
+  UINT         First = nFirst + 1;
+  LPSTR        lpMatchStr = (LPSTR)MatchStr;
+
+  if (First > lphl->ItemsCount) return LB_ERR;
+
+  if (HasStrings(lphl)) lpMatchStr = PTR_SEG_TO_LIN(MatchStr);
+  
+  lpls = ListBoxGetItem(lphl, First);
+  Count = 0;
+  while(lpls != NULL) {
+    if (HasStrings(lphl)) {
+      if (strstr(lpls->itemText, lpMatchStr) == lpls->itemText) return Count;
+    } else if (lphl->dwStyle & LBS_SORT) {
+      /* XXX Do a compare item */
+    }
+    else
+      if (lpls->mis.itemData == (DWORD)lpMatchStr) return Count;
+
+    lpls = lpls->lpNext;
+    Count++;
+  }
+
+  /* Start over at top */
+  Count = 0;
+  lpls = lphl->lpFirst;
+
+  while (Count < First) {
+    if (HasStrings(lphl)) {
+      if (strstr(lpls->itemText, lpMatchStr) == lpls->itemText) return Count;
+    } else if (lphl->dwStyle & LBS_SORT) {
+      /* XXX Do a compare item */
+    } else {
+      if (lpls->mis.itemData == (DWORD)lpMatchStr) return Count;
+    }
+    lpls = lpls->lpNext;
+    Count++;
+  }
+
+  return LB_ERR;
+}
+
+
+int ListBoxResetContent(LPHEADLIST lphl)
+{
+    LPLISTSTRUCT lpls;
+    int i;
+
+    if (lphl->ItemsCount == 0) return 0;
+
+    dprintf_listbox(stddeb, "ListBoxResetContent // ItemCount = %d\n",
+	lphl->ItemsCount);
+
+    for(i = 0; i < lphl->ItemsCount; i++) {
+      lpls = lphl->lpFirst;
+      if (lpls == NULL) return LB_ERR;
+      
+      lphl->lpFirst = lpls->lpNext;
+      if (lpls->hData != 0) LIST_HEAP_FREE(lphl, lpls->hData);
+      free(lpls);
+    }
+    ListBoxInitialize(lphl);
+
+    return TRUE;
+}
+
+
+int ListBoxSetCurSel(LPHEADLIST lphl, WORD wIndex)
+{
+  LPLISTSTRUCT lpls;
+
+  if (lphl->dwStyle & LBS_MULTIPLESEL) return 0;
+
+  if (lphl->ItemFocused != -1) {
+    lpls = ListBoxGetItem(lphl, lphl->ItemFocused);
+    if (lpls == 0) return LB_ERR;
+    lpls->itemState = 0;
+  }
+
+  if (wIndex != (UINT)-1) {
+    lphl->ItemFocused = wIndex;
+    lpls = ListBoxGetItem(lphl, wIndex);
+    if (lpls == 0) return LB_ERR;
+    lpls->itemState = ODS_SELECTED | ODS_FOCUS;
+
+    return 0;
+  }
+
+  return LB_ERR;
+}
+
+
+int ListBoxSetSel(LPHEADLIST lphl, WORD wIndex, WORD state)
+{
+  LPLISTSTRUCT lpls;
+
+  if (!(lphl->dwStyle & LBS_MULTIPLESEL)) return 0;
+
+  if (wIndex == (UINT)-1) {
+    for (lpls = lphl->lpFirst; lpls != NULL; lpls = lpls->lpNext) {
+      lpls->itemState = state;
+    }
+    return 0;
+  }
+
+  if (wIndex >= lphl->ItemsCount) return LB_ERR;
+
+  lpls = ListBoxGetItem(lphl, wIndex);
+  lpls->itemState = state;
+
+  return 0;
+}
+
+
+int ListBoxGetSel(LPHEADLIST lphl, WORD wIndex)
+{
+  LPLISTSTRUCT lpls = ListBoxGetItem(lphl, wIndex);
+
+  if (lpls == NULL) return LB_ERR;
+  return lpls->itemState;
+}
+
+
+int ListBoxDirectory(LPHEADLIST lphl, UINT attrib, LPSTR filespec)
+{
+  struct dosdirent *dp, *dp_old;
+  char temp[256];
+  int   drive;
+  LPSTR tstr;
+
+  dprintf_listbox(stddeb,"ListBoxDirectory: %s, %4x\n",filespec,attrib);
+
+  if (strchr(filespec, '\\') || strchr(filespec, ':')) {
+    drive = DOS_GetDefaultDrive();
+    if (filespec[1] == ':') {
+      drive = toupper(filespec[0]) - 'A';
+      filespec += 2;
+    }
+    strcpy(temp,filespec);
+    tstr = strrchr(temp, '\\');
+    if (tstr == NULL)
+      DOS_SetDefaultDrive( drive );
+    else {
+      *tstr = 0;
+      filespec = tstr + 1;
+      if (!DOS_ChangeDir( drive, temp )) return 0;
+      DOS_SetDefaultDrive( drive );
+    }
+    dprintf_listbox(stddeb,"Changing directory to %c:%s, filemask is %s\n",
+		    drive+'A', temp, filespec);
+  }
+
+  if ((dp = (struct dosdirent *)DOS_opendir(filespec)) ==NULL) return 0;
+  dp_old = dp;
+  while ((dp = (struct dosdirent *)DOS_readdir(dp))) {
+    if (!dp->inuse) break;
+    dprintf_listbox(stddeb, "ListBoxDirectory %p '%s' !\n", dp->filename, 
+		    dp->filename);
+    if (dp->attribute & FA_DIREC) {
+      if (attrib & DDL_DIRECTORY && strcmp(dp->filename, ".") != 0) {
+	sprintf(temp, "[%s]", dp->filename);
+	if (ListBoxAddString(lphl, temp) == LB_ERR) break;
+      }
+    } 
+    else {
+      if (attrib & DDL_EXCLUSIVE) {
+	if (attrib & (DDL_READWRITE | DDL_READONLY | DDL_HIDDEN | DDL_SYSTEM)) {
+	  if (ListBoxAddString(lphl, dp->filename) == LB_ERR) break;
+	}
+      } else {
+	if (ListBoxAddString(lphl, dp->filename) == LB_ERR) break;
+      }
+    }
+  }
+  DOS_closedir(dp_old);
+  
+  if (attrib & DDL_DRIVES) {
+    int x;
+    for (x = 0; x != MAX_DOS_DRIVES ; x++) {
+      if (DOS_ValidDrive(x)) {
+	sprintf(temp, "[-%c-]", 'a'+x);
+	if (ListBoxInsertString(lphl, (UINT)-1, temp) == LB_ERR) break;
+      }		
+    }
+  }
+  return 1;
+}
+
+
+int ListBoxGetItemRect(LPHEADLIST lphl, WORD wIndex, LPRECT lprect)
+{
+  LPLISTSTRUCT lpls = ListBoxGetItem(lphl,wIndex);
+
+  if (lpls == NULL) return LB_ERR;
+  *lprect = lpls->itemRect;
+  return 0;
+}
+
+
+int ListBoxSetItemHeight(LPHEADLIST lphl, WORD wIndex, long height)
+{
+  LPLISTSTRUCT lpls;
+
+  if (!(lphl->dwStyle & LBS_OWNERDRAWVARIABLE)) {
+    lphl->StdItemHeight = (short)height;
+    return 0;
+  }
+  
+  lpls = ListBoxGetItem(lphl, wIndex);
+  if (lpls == NULL) return LB_ERR;
+  
+  lpls->mis.itemHeight = height;
+  return 0;
+}
+
+
+int ListBoxFindNextMatch(LPHEADLIST lphl, WORD wChar)
+{
+  LPLISTSTRUCT lpls;
+  UINT	       count,first;
+
+  if ((char)wChar < ' ') return LB_ERR;
+  if (!HasStrings(lphl)) return LB_ERR;
+
+  lpls = lphl->lpFirst;
+  
+  for (count = 0; lpls != NULL; lpls = lpls->lpNext, count++) {
+    if (tolower(*lpls->itemText) == tolower((char)wChar)) break;
+  }
+  if (lpls == NULL) return LB_ERR;
+  first = count;
+  for(; lpls != NULL; lpls = lpls->lpNext, count++) {
+    if (*lpls->itemText != (char)wChar) 
+      break;
+    if (count > lphl->ItemFocused)
+      return count;
+  }
+  return first;
+}
+
+/***********************************************************************
+ *           LBCreate
+ */
+static LONG LBCreate(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST   lphl;
+  RECT rect;
+
+  CreateListBoxStruct(hwnd, ODT_LISTBOX, GetWindowLong(hwnd,GWL_STYLE), GetParent(hwnd));
+  lphl = ListBoxGetStorageHeader(hwnd);
+  dprintf_listbox(stddeb,"ListBox WM_CREATE %p !\n", lphl);
+
+  GetClientRect(hwnd,&rect);
+  lphl->ColumnsWidth = rect.right - rect.left;
+
+  SetScrollRange(hwnd, SB_VERT, 0, ListMaxFirstVisible(lphl), TRUE);
+  SetScrollRange(hwnd, SB_HORZ, 1, 1, TRUE);
+
+  return 0;
+}
+
+/***********************************************************************
+ *           LBDestroy
+ */
+static LONG LBDestroy(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
+
+  ListBoxResetContent(lphl);
+
+  DestroyListBoxStruct(lphl);
+  dprintf_listbox(stddeb,"ListBox WM_DESTROY %p !\n", lphl);
+  return 0;
+}
+
 /***********************************************************************
  *           LBVScroll
  */
-LONG LBVScroll( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBVScroll(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  LPHEADLIST lphl;
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   int  y;
 
   dprintf_listbox(stddeb,"ListBox WM_VSCROLL w=%04X l=%08lX !\n",
 		  wParam, lParam);
-  lphl = ListBoxGetStorageHeader(hwnd);
-  if (lphl == NULL) return 0;
   y = lphl->FirstVisible;
 
   switch(wParam) {
   case SB_LINEUP:
-    if (lphl->FirstVisible > 1)	
+    if (lphl->FirstVisible > 0)
       lphl->FirstVisible--;
     break;
 
   case SB_LINEDOWN:
-    if (lphl->FirstVisible < ListMaxFirstVisible(lphl))
-      lphl->FirstVisible++;
+    lphl->FirstVisible++;
     break;
 
   case SB_PAGEUP:
-    if (lphl->FirstVisible > 1)  
+    if (lphl->FirstVisible > lphl->ItemsVisible) {
       lphl->FirstVisible -= lphl->ItemsVisible;
+    } else {
+      lphl->FirstVisible = 0;
+    }
     break;
 
   case SB_PAGEDOWN:
-    if (lphl->FirstVisible < ListMaxFirstVisible(lphl))  
-      lphl->FirstVisible += lphl->ItemsVisible;
+    lphl->FirstVisible += lphl->ItemsVisible;
     break;
 
   case SB_THUMBTRACK:
@@ -322,14 +877,12 @@
     break;
   }
 
-  if (lphl->FirstVisible < 1)    lphl->FirstVisible = 1;
   if (lphl->FirstVisible > ListMaxFirstVisible(lphl))
     lphl->FirstVisible = ListMaxFirstVisible(lphl);
 
   if (y != lphl->FirstVisible) {
     SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
     InvalidateRect(hwnd, NULL, TRUE);
-    UpdateWindow(hwnd);
   }
   return 0;
 }
@@ -337,8 +890,7 @@
 /***********************************************************************
  *           LBHScroll
  */
-LONG LBHScroll( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBHScroll(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl;
   int        y;
@@ -346,34 +898,37 @@
   dprintf_listbox(stddeb,"ListBox WM_HSCROLL w=%04X l=%08lX !\n",
 		  wParam, lParam);
   lphl = ListBoxGetStorageHeader(hwnd);
-  if (lphl == NULL) return 0;
   y = lphl->FirstVisible;
   switch(wParam) {
   case SB_LINEUP:
-    if (lphl->FirstVisible > 1)
+    if (lphl->FirstVisible > lphl->ItemsPerColumn) {
       lphl->FirstVisible -= lphl->ItemsPerColumn;
+    } else {
+      lphl->FirstVisible = 0;
+    }
     break;
   case SB_LINEDOWN:
-    if (lphl->FirstVisible < ListMaxFirstVisible(lphl))
-      lphl->FirstVisible += lphl->ItemsPerColumn;
+    lphl->FirstVisible += lphl->ItemsPerColumn;
     break;
   case SB_PAGEUP:
-    if (lphl->FirstVisible > 1 && lphl->ItemsPerColumn != 0)  
-      lphl->FirstVisible -= lphl->ItemsVisible /
-	lphl->ItemsPerColumn * lphl->ItemsPerColumn;
+    if (lphl->ItemsPerColumn != 0) {
+      int lbsub = lphl->ItemsVisible / lphl->ItemsPerColumn * lphl->ItemsPerColumn;
+      if (lphl->FirstVisible > lbsub) {
+	lphl->FirstVisible -= lbsub;
+      } else {
+	lphl->FirstVisible = 0;
+      }
+    }
     break;
   case SB_PAGEDOWN:
-    if (lphl->FirstVisible < ListMaxFirstVisible(lphl) &&
-	lphl->ItemsPerColumn != 0)  
+    if (lphl->ItemsPerColumn != 0)
       lphl->FirstVisible += lphl->ItemsVisible /
 	lphl->ItemsPerColumn * lphl->ItemsPerColumn;
     break;
   case SB_THUMBTRACK:
-    lphl->FirstVisible = lphl->ItemsPerColumn * 
-      (LOWORD(lParam) - 1) + 1;
+    lphl->FirstVisible = lphl->ItemsPerColumn * LOWORD(lParam);
     break;
   } 
-  if (lphl->FirstVisible < 1) lphl->FirstVisible = 1;
   if (lphl->FirstVisible > ListMaxFirstVisible(lphl))
     lphl->FirstVisible = ListMaxFirstVisible(lphl);
 
@@ -384,7 +939,6 @@
       SetScrollPos(hwnd, SB_HORZ, lphl->FirstVisible / 
 		   lphl->ItemsPerColumn + 1, TRUE);
       InvalidateRect(hwnd, NULL, TRUE);
-      UpdateWindow(hwnd);
     }
   }
   return 0;
@@ -393,11 +947,9 @@
 /***********************************************************************
  *           LBLButtonDown
  */
-LONG LBLButtonDown( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBLButtonDown(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  LPHEADLIST lphl;
-  WND        *wndPtr;
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   WORD       wRet;
   int        y;
   RECT       rectsel;
@@ -405,30 +957,25 @@
   SetFocus(hwnd);
   SetCapture(hwnd);
 
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-  if (lphl == NULL) return 0;
-
   lphl->PrevFocused = lphl->ItemFocused;
 
-  y = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam));
-  if (y==-1)
+  y = ListBoxFindMouse(lphl, LOWORD(lParam), HIWORD(lParam));
+  if (y == -1)
     return 0;
 
-  if (wndPtr->dwStyle & LBS_MULTIPLESEL) {
+  if (lphl->dwStyle & LBS_MULTIPLESEL) {
     lphl->ItemFocused = y;
-    wRet = ListBoxGetSel(hwnd, y);
-    ListBoxSetSel(hwnd, y, !wRet);
+    wRet = ListBoxGetSel(lphl, y);
+    ListBoxSetSel(lphl, y, !wRet);
+  } else {
+    ListBoxSetCurSel(lphl, y);
   }
-  else
-    ListBoxSetCurSel(hwnd, y);
+  if (lphl->dwStyle & LBS_MULTIPLESEL)
+    ListBoxSendNotification(lphl, hwnd, LBN_SELCHANGE);
 
-  if (wndPtr->dwStyle & LBS_MULTIPLESEL)
-    ListBoxSendNotification( hwnd, LBN_SELCHANGE );
-
-  ListBoxGetItemRect(hwnd, y, &rectsel);
+  ListBoxGetItemRect(lphl, y, &rectsel);
 
   InvalidateRect(hwnd, NULL, TRUE);
-  UpdateWindow(hwnd);
 
   return 0;
 }
@@ -436,18 +983,14 @@
 /***********************************************************************
  *           LBLButtonUp
  */
-LONG LBLButtonUp( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBLButtonUp(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  LPHEADLIST lphl;
-  WND        *wndPtr;
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
 
   if (GetCapture() == hwnd) ReleaseCapture();
 
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-  if (lphl == NULL) return 0;
   if (lphl->PrevFocused != lphl->ItemFocused)
-    ListBoxSendNotification( hwnd, LBN_SELCHANGE );
+    ListBoxSendNotification(lphl, hwnd, LBN_SELCHANGE);
 
   return 0;
 }
@@ -455,15 +998,11 @@
 /***********************************************************************
  *           LBRButtonUp
  */
-LONG LBRButtonUp( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBRButtonUp(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  LPHEADLIST lphl;
-  WND        *wndPtr;
-  
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-  if (lphl == NULL) return 0;
-  SendMessage(lphl->hWndLogicParent, WM_COMMAND, wndPtr->wIDmenu,
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
+
+  SendMessage(lphl->hParent, WM_COMMAND, GetWindowWord(hwnd,GWW_ID),
 		MAKELONG(hwnd, LBN_DBLCLK));
 
   return 0;
@@ -472,50 +1011,47 @@
 /***********************************************************************
  *           LBMouseMove
  */
-LONG LBMouseMove( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBMouseMove(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  LPHEADLIST  lphl;
-  WND        *wndPtr;
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   int  y;
-  WORD        wRet;
-  RECT        rect, rectsel;   /* XXX Broken */
+  WORD wRet;
+  RECT rect, rectsel;   /* XXX Broken */
 
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-  if (lphl == NULL) return 0;
+  dprintf_listbox(stddeb,"LBMouseMove %d %d\n",SLOWORD(lParam),SHIWORD(lParam));
   if ((wParam & MK_LBUTTON) != 0) {
-    y = HIWORD(lParam);
-    if (y < 4) {
-      if (lphl->FirstVisible > 1) {
+    y = SHIWORD(lParam);
+    if (y < 0) {
+      if (lphl->FirstVisible > 0) {
 	lphl->FirstVisible--;
 	SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
 	InvalidateRect(hwnd, NULL, TRUE);
-	UpdateWindow(hwnd);
 	return 0;
       }
     }
     GetClientRect(hwnd, &rect);
-    if (y > (rect.bottom - 4)) {
+    if (y >= rect.bottom) {
       if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) {
 	lphl->FirstVisible++;
 	SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
 	InvalidateRect(hwnd, NULL, TRUE);
-	UpdateWindow(hwnd);
 	return 0;
       }
     }
     if ((y > 0) && (y < (rect.bottom - 4))) {
       if ((y < rectsel.top) || (y > rectsel.bottom)) {
-	wRet = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam));
-	if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
-	  lphl->ItemFocused = wRet;
-	  ListBoxSendNotification(hwnd, LBN_SELCHANGE);
+	wRet = ListBoxFindMouse(lphl, LOWORD(lParam), HIWORD(lParam));
+	if (wRet == lphl->ItemFocused)  {
+	  return 0;
 	}
-	else
-	  ListBoxSetCurSel(hwnd, wRet);
-	ListBoxGetItemRect(hwnd, wRet, &rectsel);
+	if (lphl->dwStyle & LBS_MULTIPLESEL) {
+	  lphl->ItemFocused = wRet;
+	  ListBoxSendNotification(lphl, hwnd, LBN_SELCHANGE);
+	} else {
+	  ListBoxSetCurSel(lphl, wRet);
+	}
+	ListBoxGetItemRect(lphl, wRet, &rectsel);
 	InvalidateRect(hwnd, NULL, TRUE);
-	UpdateWindow(hwnd);
       }
     }
   }
@@ -526,85 +1062,97 @@
 /***********************************************************************
  *           LBKeyDown
  */
-LONG LBKeyDown( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBKeyDown(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  LPHEADLIST  lphl;
-  WND        *wndPtr;
-  HWND        hWndCtl;
-  WORD        wRet;
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
+  WORD       newFocused = lphl->ItemFocused;
 
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-  if (lphl == NULL) return 0;
-  switch(wParam) {
-  case VK_TAB:
-    hWndCtl = GetNextDlgTabItem(lphl->hWndLogicParent,
-				hwnd, !(GetKeyState(VK_SHIFT) < 0));
-    SetFocus(hWndCtl);
-    if(debugging_listbox){
-      if ((GetKeyState(VK_SHIFT) < 0))
-	dprintf_listbox(stddeb,"ListBox PreviousDlgTabItem %04X !\n", hWndCtl);
-      else
-	dprintf_listbox(stddeb,"ListBox NextDlgTabItem %04X !\n", hWndCtl);
+  if (wParam == VK_SPACE) {
+    if (lphl->dwStyle & LBS_MULTIPLESEL) {
+      WORD wRet = ListBoxGetSel(lphl, lphl->ItemFocused);
+      ListBoxSetSel(lphl, lphl->ItemFocused, !wRet);
     }
-    break;
+    return 0;
+  }
+  switch(wParam) {
   case VK_HOME:
-    lphl->ItemFocused = 0;
+    newFocused = 0;
     break;
   case VK_END:
-    lphl->ItemFocused = lphl->ItemsCount - 1;
+    newFocused = lphl->ItemsCount - 1;
     break;
   case VK_LEFT:
-    if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) {
-      lphl->ItemFocused -= lphl->ItemsPerColumn;
+    if (lphl->dwStyle & LBS_MULTICOLUMN) {
+      if (newFocused >= lphl->ItemsPerColumn) {
+	newFocused -= lphl->ItemsPerColumn;
+      } else {
+	newFocused = 0;
+      }
     }
     break;
   case VK_UP:
-    lphl->ItemFocused--;
+    if (newFocused > 0) newFocused--;
     break;
   case VK_RIGHT:
-    if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) {
-      lphl->ItemFocused += lphl->ItemsPerColumn;
+    if (lphl->dwStyle & LBS_MULTICOLUMN) {
+      newFocused += lphl->ItemsPerColumn;
     }
     break;
   case VK_DOWN:
-    lphl->ItemFocused++;
+    newFocused++;
     break;
   case VK_PRIOR:
-    lphl->ItemFocused -= lphl->ItemsVisible;
+    if (newFocused > lphl->ItemsVisible) {
+      newFocused -= lphl->ItemsVisible;
+    } else {
+      newFocused = 0;
+    }
     break;
   case VK_NEXT:
-    lphl->ItemFocused += lphl->ItemsVisible;
-    break;
-  case VK_SPACE:
-    wRet = ListBoxGetSel(hwnd, lphl->ItemFocused);
-    ListBoxSetSel(hwnd, lphl->ItemFocused, !wRet);
+    newFocused += lphl->ItemsVisible;
     break;
   default:
-    ListBoxFindNextMatch(hwnd, wParam);
     return 0;
   }
 
-  if (lphl->ItemFocused < 0) lphl->ItemFocused = 0;
-  if (lphl->ItemFocused >= lphl->ItemsCount)
-    lphl->ItemFocused = lphl->ItemsCount - 1;
-
-  if (lphl->ItemsVisible != 0)
-    lphl->FirstVisible = lphl->ItemFocused / lphl->ItemsVisible * 
-      lphl->ItemsVisible + 1;
-
-  if (lphl->FirstVisible < 1) lphl->FirstVisible = 1;
-  if (lphl->FirstVisible > ListMaxFirstVisible(lphl))
-    lphl->FirstVisible = ListMaxFirstVisible(lphl);
-
-  if ((wndPtr->dwStyle & LBS_MULTIPLESEL) != LBS_MULTIPLESEL) {
-    ListBoxSetCurSel(hwnd, lphl->ItemFocused);
-    ListBoxSendNotification(hwnd, LBN_SELCHANGE);
+  if (newFocused >= lphl->ItemsCount)
+    newFocused = lphl->ItemsCount - 1;
+  
+  if (!(lphl->dwStyle & LBS_MULTIPLESEL)) {
+    ListBoxSetCurSel(lphl, newFocused);
+    ListBoxSendNotification(lphl, hwnd, LBN_SELCHANGE);
   }
 
+  lphl->ItemFocused = newFocused;
+  ListBoxScrollToFocus(lphl); 
   SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
   InvalidateRect(hwnd, NULL, TRUE);
-  UpdateWindow(hwnd);
+
+  return 0;
+}
+
+/***********************************************************************
+ *           LBChar
+ */
+static LONG LBChar(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
+  WORD       newFocused;
+
+  newFocused = ListBoxFindNextMatch(lphl, wParam);
+  if (newFocused == (WORD)LB_ERR) return 0;
+
+  if (newFocused >= lphl->ItemsCount)
+    newFocused = lphl->ItemsCount - 1;
+  if (!(lphl->dwStyle & LBS_MULTIPLESEL)) {
+    ListBoxSetCurSel(lphl, newFocused);
+    ListBoxSendNotification(lphl, hwnd, LBN_SELCHANGE);
+  }
+
+  lphl->ItemFocused = newFocused;
+  ListBoxScrollToFocus(lphl);
+  SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+  InvalidateRect(hwnd, NULL, TRUE);
 
   return 0;
 }
@@ -612,15 +1160,11 @@
 /***********************************************************************
  *           LBSetRedraw
  */
-LONG LBSetRedraw( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBSetRedraw(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  LPHEADLIST  lphl;
-  WND        *wndPtr;
+  LPHEADLIST  lphl = ListBoxGetStorageHeader(hwnd);
 
   dprintf_listbox(stddeb,"ListBox WM_SETREDRAW hWnd=%04X w=%04X !\n", hwnd, wParam);
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-  if (lphl == NULL) return 0;
   lphl->bRedrawFlag = wParam;
 
   return 0;
@@ -629,15 +1173,9 @@
 /***********************************************************************
  *           LBSetFont
  */
-
-LONG LBSetFont( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBSetFont(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  LPHEADLIST  lphl;
-  WND        *wndPtr;
-
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-  if (lphl == NULL) return 0;
+  LPHEADLIST  lphl = ListBoxGetStorageHeader(hwnd);
 
   if (wParam == 0)
     lphl->hFont = GetStockObject(SYSTEM_FONT);
@@ -650,24 +1188,98 @@
 /***********************************************************************
  *           LBPaint
  */
-LONG LBPaint( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBPaint(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  RepaintListBox(hwnd);
+  LPHEADLIST   lphl = ListBoxGetStorageHeader(hwnd);
+  LPLISTSTRUCT lpls;
+  PAINTSTRUCT  ps;
+  HBRUSH       hBrush;
+  HFONT        hOldFont;
+  HDC 	hdc;
+  RECT 	rect;
+  int   i, top, height, maxwidth, ipc;
+
+  top = 0;
+  hdc = BeginPaint( hwnd, &ps );
+
+  if (!IsWindowVisible(hwnd) || !lphl->bRedrawFlag) {
+    EndPaint(hwnd, &ps);
+    return 0;
+  }
+
+  hOldFont = SelectObject(hdc, lphl->hFont);
+
+  hBrush = SendMessage(lphl->hParent, WM_CTLCOLOR, hdc,
+		       MAKELONG(hwnd, CTLCOLOR_LISTBOX));
+
+  if (hBrush == 0) hBrush = GetStockObject(WHITE_BRUSH);
+
+  GetClientRect(hwnd, &rect);
+  FillRect(hdc, &rect, hBrush);
+
+  maxwidth = rect.right;
+  if (lphl->dwStyle & LBS_MULTICOLUMN) {
+    rect.right = lphl->ColumnsWidth;
+  }
+  lpls = lphl->lpFirst;
+
+  lphl->ItemsVisible = 0;
+  lphl->ItemsPerColumn = ipc = 0;
+
+  for(i = 0; i < lphl->ItemsCount; i++) {
+    if (lpls == NULL) break;
+
+    if (i >= lphl->FirstVisible) {
+      height = lpls->mis.itemHeight;
+
+      if (top > rect.bottom) {
+	if (lphl->dwStyle & LBS_MULTICOLUMN) {
+	  lphl->ItemsPerColumn = max(lphl->ItemsPerColumn, ipc);
+	  ipc = 0;
+	  top = 0;
+	  rect.left += lphl->ColumnsWidth;
+	  rect.right += lphl->ColumnsWidth;
+	  if (rect.left > maxwidth) break;
+	} else {
+	  break;
+	}
+      }
+
+      lpls->itemRect.top    = top;
+      lpls->itemRect.bottom = top + height;
+      lpls->itemRect.left   = rect.left;
+      lpls->itemRect.right  = rect.right;
+
+      dprintf_listbox(stddeb,"drawing item: %d %d %d %d %d\n",rect.left,top,rect.right,top+height,lpls->itemState);
+      if (OWNER_DRAWN(lphl)) {
+	ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_DRAWENTIRE, 0);
+	if (lpls->itemState)
+	  ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_SELECT, ODS_SELECTED);
+      } else {
+	ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_DRAWENTIRE, 
+			 lpls->itemState);
+      }
+      if ((lphl->ItemFocused == i) && GetFocus() == hwnd)
+	ListBoxDrawItem (hwnd,lphl, hdc, lpls, &lpls->itemRect, ODA_FOCUS, ODS_FOCUS);
+
+      top += height;
+      lphl->ItemsVisible++;
+      ipc++;
+    }
+
+    lpls = lpls->lpNext;
+  }
+  SelectObject(hdc,hOldFont);
+  EndPaint( hwnd, &ps );
   return 0;
 }
 
 /***********************************************************************
  *           LBSetFocus
  */
-LONG LBSetFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBSetFocus(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  LPHEADLIST lphl;
-  WND       *wndPtr;
-
   dprintf_listbox(stddeb,"ListBox WM_SETFOCUS !\n");
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
 
   return 0;
 }
@@ -675,13 +1287,11 @@
 /***********************************************************************
  *           LBKillFocus
  */
-LONG LBKillFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBKillFocus(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
   dprintf_listbox(stddeb,"ListBox WM_KILLFOCUS !\n");
 
   InvalidateRect(hwnd, NULL, TRUE);
-  UpdateWindow(hwnd);
   
   return 0;
 }
@@ -689,61 +1299,57 @@
 /***********************************************************************
  *           LBResetContent
  */
-LONG LBResetContent( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBResetContent(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  dprintf_listbox(stddeb,"ListBox LB_RESETCONTENT !\n");
-  ListBoxResetContent(hwnd);
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
 
+  dprintf_listbox(stddeb,"ListBox LB_RESETCONTENT !\n");
+  ListBoxResetContent(lphl);
+  ListBoxUpdateWindow(hwnd, lphl, TRUE);
   return 0;
 }
 
 /***********************************************************************
  *           LBDir
  */
-LONG LBDir( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBDir(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
   WORD   wRet;
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   dprintf_listbox(stddeb,"ListBox LB_DIR !\n");
 
-  wRet = ListBoxDirectory(hwnd, wParam,
-			  (LPSTR)PTR_SEG_TO_LIN(lParam));
-  InvalidateRect(hwnd, NULL, TRUE);
-  UpdateWindow(hwnd);
+  wRet = ListBoxDirectory(lphl, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam));
+  ListBoxUpdateWindow(hwnd, lphl, TRUE);
   return wRet;
 }
 
 /***********************************************************************
  *           LBAddString
  */
-LONG LBAddString( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBAddString(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
   WORD  wRet;
-  WND  *wndPtr;
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
 
-  wndPtr = WIN_FindWndPtr(hwnd);
-
-  if (HasStrings(wndPtr))
-    wRet = ListBoxAddString(hwnd, (LPSTR)PTR_SEG_TO_LIN(lParam));
+  if (HasStrings(lphl))
+    wRet = ListBoxAddString(lphl, (LPSTR)PTR_SEG_TO_LIN(lParam));
   else
-    wRet = ListBoxAddString(hwnd, (LPSTR)lParam);
+    wRet = ListBoxAddString(lphl, (LPSTR)lParam);
 
+  ListBoxUpdateWindow(hwnd,lphl,TRUE);
   return wRet;
 }
 
 /***********************************************************************
  *           LBGetText
  */
-LONG LBGetText( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBGetText(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
   LONG   wRet;
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
 
   dprintf_listbox(stddeb, "LB_GETTEXT  wParam=%d\n",wParam);
-  wRet = ListBoxGetText(hwnd, wParam,
-			(LPSTR)PTR_SEG_TO_LIN(lParam), FALSE);
+  wRet = ListBoxGetText(lphl, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam));
 
   return wRet;
 }
@@ -751,60 +1357,54 @@
 /***********************************************************************
  *           LBInsertString
  */
-LONG LBInsertString( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBInsertString(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
   WORD  wRet;
-  WND  *wndPtr;
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
 
-  wndPtr = WIN_FindWndPtr(hwnd);
-
-  if (HasStrings(wndPtr))
-    wRet = ListBoxInsertString(hwnd, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam));
+  if (HasStrings(lphl))
+    wRet = ListBoxInsertString(lphl, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam));
   else
-    wRet = ListBoxInsertString(hwnd, wParam, (LPSTR)lParam);
+    wRet = ListBoxInsertString(lphl, wParam, (LPSTR)lParam);
 
+  ListBoxUpdateWindow(hwnd,lphl,TRUE);
   return wRet;
 }
 
 /***********************************************************************
  *           LBDeleteString
- */    
-LONG LBDeleteString( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+ */
+static LONG LBDeleteString(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  return ListBoxDeleteString(hwnd, wParam); 
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
+  LONG lRet = ListBoxDeleteString(lphl,wParam);
+  
+  ListBoxUpdateWindow(hwnd,lphl,TRUE);
+  return lRet;
 }
 
 /***********************************************************************
  *           LBFindString
  */
-LONG LBFindString( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBFindString(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  return ListBoxFindString(hwnd, wParam,
-			   (LPSTR)PTR_SEG_TO_LIN(lParam));
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
+  return ListBoxFindString(lphl, wParam, lParam);
 }
 
 /***********************************************************************
  *           LBGetCaretIndex
  */
-LONG LBGetCaretIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBGetCaretIndex(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  LPHEADLIST  lphl;
-
-  lphl = ListBoxGetStorageHeader(hwnd);
-  if (lphl == NULL) return LB_ERR;
-
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   return lphl->ItemFocused;
 }
 
 /***********************************************************************
  *           LBGetCount
  */
-LONG LBGetCount( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBGetCount(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
   LPHEADLIST  lphl;
 
@@ -815,8 +1415,7 @@
 /***********************************************************************
  *           LBGetCurSel
  */
-LONG LBGetCurSel( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBGetCurSel(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
   LPHEADLIST  lphl;
 
@@ -829,73 +1428,56 @@
 /***********************************************************************
  *           LBGetHorizontalExtent
  */
-LONG LBGetHorizontalExtent( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBGetHorizontalExtent(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {    
   return 0;
 }
 
 /***********************************************************************
- *           LBGetItemData
- */
-LONG LBGetItemData( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
-{
-    dprintf_listbox(stddeb, "LB_GETITEMDATA wParam=%x\n", wParam);
-    return ListBoxGetText(hwnd, wParam,
-			  (LPSTR)PTR_SEG_TO_LIN(lParam), TRUE);
-}
-
-/***********************************************************************
  *           LBGetItemHeight
  */
-LONG LBGetItemHeight( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBGetItemHeight(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  RECT   rect;
-
-  ListBoxGetItemRect(hwnd, wParam, &rect);
-  return (rect.bottom - rect.top);
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
+  LPLISTSTRUCT lpls = ListBoxGetItem (lphl, wParam);
+  
+  if (lpls == NULL) return LB_ERR;
+  return lpls->mis.itemHeight;
 }
 
 /***********************************************************************
  *           LBGetItemRect
  */
-LONG LBGetItemRect( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBGetItemRect(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  return ListBoxGetItemRect (hwnd, wParam, PTR_SEG_TO_LIN(lParam));
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
+  return ListBoxGetItemRect(lphl, wParam, PTR_SEG_TO_LIN(lParam));
 }
 
 /***********************************************************************
  *           LBGetSel
  */
-LONG LBGetSel( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBGetSel(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  return ListBoxGetSel (hwnd, wParam);
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
+  return ListBoxGetSel(lphl, wParam);
 }
 
 /***********************************************************************
  *           LBGetSelCount
  */
-LONG LBGetSelCount( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBGetSelCount(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  LPHEADLIST   lphl;
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   LPLISTSTRUCT lpls;
   int          cnt = 0;
-  WND        *wndPtr;
 
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-  if (lphl == NULL) return LB_ERR;
-
-  if (!(wndPtr->dwStyle & LBS_MULTIPLESEL)) return LB_ERR;
+  if (!(lphl->dwStyle & LBS_MULTIPLESEL)) return LB_ERR;
 
   lpls = lphl->lpFirst;
 
   while (lpls != NULL) {
-    if (lpls->dis.itemState > 0) cnt++;
+    if (lpls->itemState > 0) cnt++;
 
     lpls = lpls->lpNext;
   }
@@ -906,19 +1488,14 @@
 /***********************************************************************
  *           LBGetSelItems
  */
-LONG LBGetSelItems( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBGetSelItems(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  LPHEADLIST   lphl;
+  LPHEADLIST  lphl = ListBoxGetStorageHeader(hwnd);
   LPLISTSTRUCT lpls;
-  int          cnt, idx;
-  WND         *wndPtr;
-  int         *lpItems = PTR_SEG_TO_LIN(lParam);
+  int cnt, idx;
+  int *lpItems = PTR_SEG_TO_LIN(lParam);
 
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-  if (lphl == NULL) return LB_ERR;
-
-  if (!(wndPtr->dwStyle & LBS_MULTIPLESEL)) return LB_ERR;
+  if (!(lphl->dwStyle & LBS_MULTIPLESEL)) return LB_ERR;
 
   if (wParam == 0) return 0;
 
@@ -926,7 +1503,7 @@
   cnt = 0; idx = 0;
 
   while (lpls != NULL) {
-    if (lpls->dis.itemState > 0) lpItems[cnt++] = idx;
+    if (lpls->itemState > 0) lpItems[cnt++] = idx;
 
     if (cnt == wParam) break;
     idx++;
@@ -939,65 +1516,43 @@
 /***********************************************************************
  *           LBGetTextLen
  */
-LONG LBGetTextLen( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBGetTextLen(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  LPHEADLIST   lphl;
-  LPLISTSTRUCT lpls;
-  WND         *wndPtr;
-  int          cnt = 0;
+  LPHEADLIST   lphl = ListBoxGetStorageHeader(hwnd);
+  LPLISTSTRUCT lpls = ListBoxGetItem(lphl,wParam);
 
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-  if (lphl == NULL) return LB_ERR;
-
-  if (!HasStrings(wndPtr)) return LB_ERR;
-
-  if (wParam >= lphl->ItemsCount) return LB_ERR;
-    
-  lpls = lphl->lpFirst;
-
-  while (cnt++ < wParam) lpls = lpls->lpNext;
-  
+  if (lpls == NULL || !HasStrings(lphl)) return LB_ERR;
   return strlen(lpls->itemText);
 }
 
 /***********************************************************************
  *           LBGetDlgCode
  */
-LONG LBGetDlgCode( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBGetDlgCode(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  return DLGC_WANTALLKEYS;
+  return DLGC_WANTARROWS | DLGC_WANTCHARS;
 }
 
 /***********************************************************************
  *           LBGetTopIndex
  */
-LONG LBGetTopIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBGetTopIndex(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  LPHEADLIST lphl;
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
 
-  lphl = ListBoxGetStorageHeader(hwnd);
-  if (lphl == NULL) return LB_ERR;
-
-  return (lphl->FirstVisible - 1);
+  return lphl->FirstVisible;
 }
 
 
 /***********************************************************************
  *           LBSelectString
  */
-LONG LBSelectString( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBSelectString(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  WND  *wndPtr;
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   WORD  wRet;
 
-  wndPtr = WIN_FindWndPtr(hwnd);
-
-  wRet = ListBoxFindString(hwnd, wParam,
-			   (LPSTR)PTR_SEG_TO_LIN(lParam));
+  wRet = ListBoxFindString(lphl, wParam, lParam);
 
   /* XXX add functionality here */
 
@@ -1007,21 +1562,16 @@
 /***********************************************************************
  *           LBSelItemRange
  */
-LONG LBSelItemRange( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBSelItemRange(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  LPHEADLIST   lphl;
+  LPHEADLIST   lphl = ListBoxGetStorageHeader(hwnd);
   LPLISTSTRUCT lpls;
-  WND         *wndPtr;
   WORD         cnt;
   WORD         first = LOWORD(lParam);
   WORD         last = HIWORD(lParam);
   BOOL         select = wParam;
 
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-  if (lphl == NULL) return LB_ERR;
-
-  if (!(wndPtr->dwStyle & LBS_MULTIPLESEL)) return LB_ERR;
+  if (!(lphl->dwStyle & LBS_MULTIPLESEL)) return LB_ERR;
 
   if (first >= lphl->ItemsCount ||
       last >= lphl->ItemsCount) return LB_ERR;
@@ -1031,7 +1581,7 @@
 
   while (lpls != NULL) {
     if (cnt++ >= first)
-      lpls->dis.itemState = select ? ODS_SELECTED : 0;
+      lpls->itemState = select ? ODS_SELECTED : 0;
 
     if (cnt > last)
       break;
@@ -1045,66 +1595,64 @@
 /***********************************************************************
  *           LBSetCaretIndex
  */
-LONG LBSetCaretIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBSetCaretIndex(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  LPHEADLIST   lphl;
-  WND         *wndPtr;
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
 
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-  if (lphl == NULL) return LB_ERR;
-
-  if (!(wndPtr->dwStyle & LBS_MULTIPLESEL)) return 0;
+  if (!(lphl->dwStyle & LBS_MULTIPLESEL)) return 0;
   if (wParam >= lphl->ItemsCount) return LB_ERR;
 
   lphl->ItemFocused = wParam;
-  ListBoxScrolltoFocus (hwnd);
+  ListBoxScrollToFocus (lphl);
 
   SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
   InvalidateRect(hwnd, NULL, TRUE);
-  UpdateWindow(hwnd);
   return 0;
 }
 
 /***********************************************************************
  *           LBSetColumnWidth
  */
-LONG LBSetColumnWidth( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBSetColumnWidth(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  LPHEADLIST   lphl;
-
-  lphl = ListBoxGetStorageHeader(hwnd);
-  if (lphl == NULL) return LB_ERR;
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   lphl->ColumnsWidth = wParam;
-
+  InvalidateRect(hwnd,NULL,TRUE);
   return 0;
 }
 
 /***********************************************************************
  *           LBSetHorizontalExtent
  */
-LONG LBSetHorizontalExtent( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBSetHorizontalExtent(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
   return 0;
 }
 
 /***********************************************************************
+ *           LBGetItemData
+ */
+static LONG LBGetItemData(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
+  dprintf_listbox(stddeb, "LB_GETITEMDATA wParam=%x\n", wParam);
+  return ListBoxGetItemData(lphl, wParam);
+}
+
+/***********************************************************************
  *           LBSetItemData
  */
-LONG LBSetItemData( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBSetItemData(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   dprintf_listbox(stddeb, "LB_SETITEMDATA  wParam=%x  lParam=%lx\n", wParam, lParam);
-  return ListBoxSetItemData(hwnd, wParam, lParam);
+  return ListBoxSetItemData(lphl, wParam, lParam);
 }
 
 /***********************************************************************
  *           LBSetTabStops
  */
-LONG LBSetTabStops( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBSetTabStops(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
   LPHEADLIST  lphl;
 
@@ -1128,23 +1676,18 @@
 /***********************************************************************
  *           LBSetCurSel
  */
-LONG LBSetCurSel( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBSetCurSel(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  LPHEADLIST  lphl;
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   WORD  wRet;
 
-  lphl = ListBoxGetStorageHeader(hwnd);
-  if (lphl == NULL) return LB_ERR; 
-
   dprintf_listbox(stddeb,"ListBox LB_SETCURSEL wParam=%x !\n", 
 		  wParam);
 
-  wRet = ListBoxSetCurSel(hwnd, wParam);
+  wRet = ListBoxSetCurSel(lphl, wParam);
 
   SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
   InvalidateRect(hwnd, NULL, TRUE);
-  UpdateWindow(hwnd);
 
   return wRet;
 }
@@ -1152,16 +1695,15 @@
 /***********************************************************************
  *           LBSetSel
  */
-LONG LBSetSel( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBSetSel(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   WORD wRet;
 
   dprintf_listbox(stddeb,"ListBox LB_SETSEL wParam=%x lParam=%lX !\n", wParam, lParam);
 
-  wRet = ListBoxSetSel(hwnd, LOWORD(lParam), wParam);
+  wRet = ListBoxSetSel(lphl, LOWORD(lParam), wParam);
   InvalidateRect(hwnd, NULL, TRUE);
-  UpdateWindow(hwnd);
 
   return wRet;
 }
@@ -1169,19 +1711,16 @@
 /***********************************************************************
  *           LBSetTopIndex
  */
-LONG LBSetTopIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+static LONG LBSetTopIndex(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  LPHEADLIST lphl;
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
 
   dprintf_listbox(stddeb,"ListBox LB_SETTOPINDEX wParam=%x !\n",
 		  wParam);
-  lphl = ListBoxGetStorageHeader(hwnd);
   lphl->FirstVisible = wParam;
   SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
 
   InvalidateRect(hwnd, NULL, TRUE);
-  UpdateWindow(hwnd);
 
   return 0;
 }
@@ -1189,23 +1728,21 @@
 /***********************************************************************
  *           LBSetItemHeight
  */
-LONG LBSetItemHeight( HWND hwnd, WORD message, WORD wParam, LONG lParam)
-
+static LONG LBSetItemHeight(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  WORD  wRet;
-
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
+  WORD wRet;
+  
   dprintf_listbox(stddeb,"ListBox LB_SETITEMHEIGHT wParam=%x lParam=%lX !\n", wParam, lParam);
-  wRet = ListBoxSetItemHeight(hwnd, wParam, lParam);
+  wRet = ListBoxSetItemHeight(lphl, wParam, lParam);
+  InvalidateRect(hwnd,NULL,TRUE);
   return wRet;
 }
 
-
 /***********************************************************************
  *           ListBoxWndProc 
  */
-
-LONG ListBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-
+LONG ListBoxWndProc(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 { 
   int idx = 0;
   int table_size = sizeof (methods) / sizeof (msg_tbl);
@@ -1219,860 +1756,6 @@
   return DefWindowProc (hwnd, message, wParam, lParam);
 }
 
-
-LPLISTSTRUCT ListBoxGetItem(HWND hwnd, UINT uIndex)
-
-{
-  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
-  LPLISTSTRUCT lpls;
-  UINT         Count = 0;
-
-  if (uIndex >= lphl->ItemsCount) return NULL;
-
-  lpls = lphl->lpFirst;
-
-  while (Count++ < uIndex) lpls = lpls->lpNext;
-
-  return lpls;
-}
-
- 
-LPHEADLIST ListBoxGetWindowAndStorage(HWND hwnd, WND **wndPtr)
-{
-    WND  *Ptr;
-    LPHEADLIST lphl;
-    *(wndPtr) = Ptr = WIN_FindWndPtr(hwnd);
-    lphl = *((LPHEADLIST *)&Ptr->wExtra[1]);
-    return lphl;
-}
-
-
-LPHEADLIST ListBoxGetStorageHeader(HWND hwnd)
-{
-    WND  *wndPtr;
-    LPHEADLIST lphl;
-    wndPtr = WIN_FindWndPtr(hwnd);
-    lphl = *((LPHEADLIST *)&wndPtr->wExtra[1]);
-    return lphl;
-}
-
-
-void ListBoxDrawItem (HWND hwnd, HDC hdc, LPLISTSTRUCT lpls,
-		      WORD itemAction, WORD itemState)
-
-{
-  LPHEADLIST  lphl;
-  WND        *wndPtr;
-
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-
-  if (OWNER_DRAWN(wndPtr)) {
-    DRAWITEMSTRUCT   *dis = USER_HEAP_LIN_ADDR(lphl->hDrawItemStruct);
-
-    memcpy (dis, &lpls->dis, sizeof(DRAWITEMSTRUCT));
-
-    dis->CtlType  = ODT_LISTBOX;
-    dis->hDC      = hdc;
-
-    if ((!dis->CtlID) && lphl->hWndLogicParent) {
-      WND   *ParentWndPtr;
-
-      ParentWndPtr = WIN_FindWndPtr(lphl->hWndLogicParent);
-      dis->CtlID   = ParentWndPtr->wIDmenu;
-    }
-
-    if (HasStrings(wndPtr)) dis->itemData = LIST_HEAP_SEG_ADDR(lpls,lpls->hData);
-   
-    dis->itemAction = itemAction;
-    dis->itemState  = itemState;
-
-    SendMessage(lphl->hWndLogicParent, WM_DRAWITEM, 
-		0, (LPARAM)USER_HEAP_SEG_ADDR(lphl->hDrawItemStruct));
-  } else {
-
-    if (itemAction == ODA_DRAWENTIRE ||
-	itemAction == ODA_SELECT) {
-      int 	OldBkMode;
-      DWORD 	dwOldTextColor;
-
-      OldBkMode = SetBkMode(hdc, TRANSPARENT);
-
-      if (itemState != 0) {
-	dwOldTextColor = SetTextColor(hdc, 0x00FFFFFFL);
-	FillRect(hdc, &lpls->dis.rcItem, GetStockObject(BLACK_BRUSH));
-      }
-
-      if (wndPtr->dwStyle & LBS_USETABSTOPS)
-	TabbedTextOut(hdc, lpls->dis.rcItem.left + 5, 
-		      lpls->dis.rcItem.top + 2, 
-		      (char *)lpls->itemText, 
-		      strlen((char *)lpls->itemText), lphl->iNumStops,
-		      lphl->TabStops, 0);
-      else
-	TextOut(hdc, lpls->dis.rcItem.left + 5, lpls->dis.rcItem.top + 2, 
-		(char *)lpls->itemText, strlen((char *)lpls->itemText));
-
-      if (itemState != 0) {
-	SetTextColor(hdc, dwOldTextColor);
-      }
-      
-      SetBkMode(hdc, OldBkMode);
-    } else DrawFocusRect(hdc, &lpls->dis.rcItem);
-  }
-
-  return;
-}
-
-void RepaintListBox(HWND hwnd)
-
-{
-  WND 	*wndPtr;
-  LPHEADLIST  lphl;
-  LPLISTSTRUCT lpls;
-  PAINTSTRUCT ps;
-  HBRUSH 	hBrush;
-
-  HDC 	hdc;
-  RECT 	rect;
-  int   i, top, height, maxwidth, ipc;
-
-  top = 0;
-
-  hdc = BeginPaint( hwnd, &ps );
-
-  if (!IsWindowVisible(hwnd)) {
-    EndPaint( hwnd, &ps );
-    return;
-  }
-
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-  if (lphl == NULL) goto EndOfPaint;
-  if (!lphl->bRedrawFlag) goto EndOfPaint;
-
-  SelectObject(hdc, lphl->hFont);
-
-  hBrush = SendMessage(lphl->hWndLogicParent, WM_CTLCOLOR, (WORD)hdc,
-		       MAKELONG(hwnd, CTLCOLOR_LISTBOX));
-
-  if (hBrush == (HBRUSH)NULL)  hBrush = GetStockObject(WHITE_BRUSH);
-
-  GetClientRect(hwnd, &rect);
-  FillRect(hdc, &rect, hBrush);
-
-  maxwidth = rect.right;
-  rect.right = lphl->ColumnsWidth;
-
-  if (lphl->ItemsCount == 0) goto EndOfPaint;
-
-  lpls = lphl->lpFirst;
-
-  lphl->ItemsVisible = 0;
-  lphl->ItemsPerColumn = ipc = 0;
-
-  for(i = 0; i < lphl->ItemsCount; i++) {
-    if (lpls == NULL) goto EndOfPaint;
-
-    if (i >= lphl->FirstVisible - 1) {
-      height = lpls->dis.rcItem.bottom - lpls->dis.rcItem.top;
-
-      if (top > rect.bottom) {
-	if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) {
-	  lphl->ItemsPerColumn = max(lphl->ItemsPerColumn, ipc);
-	  ipc = 0;
-	  top = 0;
-	  rect.left += lphl->ColumnsWidth;
-	  rect.right += lphl->ColumnsWidth;
-	  if (rect.left > maxwidth) break;
-	}
-	else 
-	  break;
-      }
-
-      lpls->dis.rcItem.top    = top;
-      lpls->dis.rcItem.bottom = top + height;
-      lpls->dis.rcItem.left   = rect.left;
-      lpls->dis.rcItem.right  = rect.right;
-
-      if (OWNER_DRAWN(wndPtr)) {
-	ListBoxDrawItem (hwnd, hdc, lpls, ODA_DRAWENTIRE, 0);
-	if (lpls->dis.itemState)
-	  ListBoxDrawItem (hwnd, hdc, lpls, ODA_SELECT, ODS_SELECTED);
-      }
-      else 
-	ListBoxDrawItem (hwnd, hdc, lpls, ODA_DRAWENTIRE, lpls->dis.itemState);
-
-      if ((lphl->ItemFocused == i) && GetFocus() == hwnd)
-	ListBoxDrawItem (hwnd, hdc, lpls, ODA_FOCUS, ODS_FOCUS);
-
-      top += height;
-      lphl->ItemsVisible++;
-      ipc++;
-    }
-
-    lpls = lpls->lpNext;
-  }
- EndOfPaint:
-  EndPaint( hwnd, &ps );
-}
-
-int ListBoxFindMouse(HWND hwnd, int X, int Y)
-
-{
-  WND 		*wndPtr;
-  LPHEADLIST 		lphl;
-  LPLISTSTRUCT	lpls;
-  RECT 		rect;
-  int                 i, h, h2, w, w2;
-
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-
-  if (lphl == NULL) return LB_ERR;
-  if (lphl->ItemsCount == 0) return LB_ERR;
-
-  lpls = lphl->lpFirst;
-  if (lpls == NULL) return LB_ERR;
-  GetClientRect(hwnd, &rect);
-  h = w2 = 0;
-  w = lphl->ColumnsWidth;
-
-  for(i = 1; i <= lphl->ItemsCount; i++) {
-    if (i >= lphl->FirstVisible) {
-      h2 = h;
-      h += lpls->dis.rcItem.bottom - lpls->dis.rcItem.top;
-      if ((Y > h2) && (Y < h) &&
-	  (X > w2) && (X < w)) return(i - 1);
-      if (h > rect.bottom) {
-	if ((wndPtr->dwStyle & LBS_MULTICOLUMN) != LBS_MULTICOLUMN) return LB_ERR;
-	h = 0;
-	w2 = w;
-	w += lphl->ColumnsWidth;
-	if (w2 > rect.right) return LB_ERR;
-      }
-    }
-    if (lpls->lpNext == NULL) return LB_ERR;
-    lpls = (LPLISTSTRUCT)lpls->lpNext;
-  }
-  return(LB_ERR);
-}
-
-void ListBoxAskMeasure(WND *wndPtr, LPHEADLIST lphl, LPLISTSTRUCT lpls)  
-
-{
-  MEASUREITEMSTRUCT 	*lpmeasure;
-
-  HANDLE hTemp = USER_HEAP_ALLOC( sizeof(MEASUREITEMSTRUCT) );
-
-  lpmeasure = (MEASUREITEMSTRUCT *) USER_HEAP_LIN_ADDR(hTemp);
-
-  if (lpmeasure == NULL) {
-    fprintf(stderr,"ListBoxAskMeasure() // Bad allocation of Measure struct !\n");
-    return;
-  }
- 
-  lpmeasure->CtlType    = ODT_LISTBOX;
-  lpmeasure->CtlID      = wndPtr->wIDmenu;
-  lpmeasure->itemID     = lpls->dis.itemID;
-  lpmeasure->itemWidth  = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
-  lpmeasure->itemHeight = 0;
-
-  if (HasStrings(wndPtr))
-    lpmeasure->itemData = LIST_HEAP_SEG_ADDR(lpls,lpls->hData);
-  else
-    lpmeasure->itemData = lpls->dis.itemData;
-
-  SendMessage(lphl->hWndLogicParent, WM_MEASUREITEM,
-	      0, USER_HEAP_SEG_ADDR(hTemp));
-
-  if (wndPtr->dwStyle & LBS_OWNERDRAWFIXED) {
-    lphl->StdItemHeight = lpmeasure->itemHeight;
-  }
-
-  lpls->dis.rcItem.right  = lpls->dis.rcItem.left + lpmeasure->itemWidth;
-  lpls->dis.rcItem.bottom = lpls->dis.rcItem.top + lpmeasure->itemHeight;
-  USER_HEAP_FREE(hTemp);			
-}
-
-
-int ListBoxAddString(HWND hwnd, LPSTR newstr)
-{
-    LPHEADLIST	lphl;
-    UINT	pos = (UINT) -1;
-    WND		*wndPtr;
-    
-    lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-    if (lphl == NULL) return LB_ERR;
-
-    if (HasStrings(wndPtr) && (wndPtr->dwStyle & LBS_SORT)) {
-	LPLISTSTRUCT lpls = lphl->lpFirst;
-	for (pos = 0; lpls; lpls = lpls->lpNext, pos++)
-	    if (strcmp(lpls->itemText, newstr) >= 0)
-		break;
-    }
-    return ListBoxInsertString(hwnd, pos, newstr);
-}
-
-int ListBoxInsertString(HWND hwnd, UINT uIndex, LPSTR newstr)
-
-{
-  WND  	       *wndPtr;
-  LPHEADLIST 	lphl;
-  LPLISTSTRUCT *lppls, lplsnew;
-  HANDLE 	hItem;
-  HANDLE 	hStr;
-  LPSTR	str;
-  UINT	Count;
-    
-  dprintf_listbox(stddeb,"ListBoxInsertString(%04X, %d, %p);\n", 
-		  hwnd, uIndex, newstr);
-    
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-  if (lphl == NULL) return LB_ERR;
-    
-  if (uIndex == (UINT)-1)
-    uIndex = lphl->ItemsCount;
-
-  if (uIndex > lphl->ItemsCount) return LB_ERR;
-
-  lppls = (LPLISTSTRUCT *) &lphl->lpFirst;
-    
-  for(Count = 0; Count < uIndex; Count++) {
-    if (*lppls == NULL) return LB_ERR;
-    lppls = (LPLISTSTRUCT *) &(*lppls)->lpNext;
-  }
-    
-  hItem = LIST_HEAP_ALLOC(lphl, GMEM_MOVEABLE, sizeof(LISTSTRUCT));
-  lplsnew = (LPLISTSTRUCT) LIST_HEAP_ADDR(lphl, hItem);
-
-  if (lplsnew == NULL) {
-    printf("ListBoxInsertString() // Bad allocation of new item !\n");
-    return LB_ERRSPACE;
-  }
-
-  ListBoxDefaultItem(hwnd, wndPtr, lphl, lplsnew);
-  lplsnew->hMem = hItem;
-  lplsnew->lpNext = *lppls;
-  *lppls = lplsnew;
-  lphl->ItemsCount++;
-  hStr = 0;
-
-  if (HasStrings(wndPtr)) {
-    hStr = LIST_HEAP_ALLOC(lphl, GMEM_MOVEABLE, strlen(newstr) + 1);
-    str = (LPSTR)LIST_HEAP_ADDR(lphl, hStr);
-    if (str == NULL) return LB_ERRSPACE;
-    strcpy(str, newstr);
-    newstr = str;
-    lplsnew->itemText = str;
-    dprintf_listbox(stddeb,"ListBoxInsertString // LBS_HASSTRINGS after strcpy '%s'\n", str);
-  } else {
-    lplsnew->itemText = NULL;
-    lplsnew->dis.itemData = (DWORD)newstr;
-  }
-
-  lplsnew->dis.itemID = lphl->ItemsCount;
-  lplsnew->hData = hStr;
- 
-  if ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) && (lphl->ItemsCount == 1)) {
-    ListBoxAskMeasure(wndPtr, lphl, lplsnew);
-  }
-
-  if (wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE)
-    ListBoxAskMeasure(wndPtr, lphl, lplsnew);   
-
-  SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), 
-		 (lphl->FirstVisible != 1 && lphl->bRedrawFlag));
-
-  if (lphl->ItemsPerColumn != 0)
-    SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / 
-		   lphl->ItemsPerColumn + 1,
-		   (lphl->FirstVisible != 1 && lphl->bRedrawFlag));
-
-  if ((lphl->FirstVisible <= uIndex) &&
-      ((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) {
-    InvalidateRect(hwnd, NULL, TRUE);
-    UpdateWindow(hwnd);
-  }
-
-  dprintf_listbox(stddeb,"ListBoxInsertString // count=%d\n", lphl->ItemsCount);
-  return uIndex;
-}
-
-
-int ListBoxGetText(HWND hwnd, UINT uIndex, LPSTR OutStr, BOOL bItemData)
-
-{
-  WND  	*wndPtr;
-  LPLISTSTRUCT lpls;
-
-  wndPtr = WIN_FindWndPtr(hwnd);
-
-  if (!OutStr && !bItemData) {
-    dprintf_listbox(stddeb, "ListBoxGetText // OutStr==NULL\n");
-    return 0;
-  }
-
-  if (!bItemData) *OutStr=0;
-
-  if ((lpls = ListBoxGetItem (hwnd, uIndex)) == NULL) 
-    return LB_ERR;
-
-  if (bItemData)
-    return lpls->dis.itemData;
-
-  if (!HasStrings(wndPtr)) {
-    *((long *)OutStr) = lpls->dis.itemData;
-    return 4;
-  }
-	
-  strcpy(OutStr, lpls->itemText);
-  return strlen(OutStr);
-}
-
-int ListBoxSetItemData(HWND hwnd, UINT uIndex, DWORD ItemData)
-
-{
-  LPLISTSTRUCT lpls;
-
-  if ((lpls = ListBoxGetItem(hwnd, uIndex)) == NULL)
-    return LB_ERR;
-
-  lpls->dis.itemData = ItemData;
-  return 1;
-}
-
-
-int ListBoxDeleteString(HWND hwnd, UINT uIndex)
-
-{
-  WND  	*wndPtr;
-  LPHEADLIST 	lphl;
-  LPLISTSTRUCT lpls, lpls2;
-  UINT	Count;
-
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-  if (lphl == NULL) return LB_ERR;
-
-  if (uIndex >= lphl->ItemsCount) return LB_ERR;
-
-  lpls = lphl->lpFirst;
-  if (lpls == NULL) return LB_ERR;
-
-  if( uIndex == 0 )
-    lphl->lpFirst = lpls->lpNext;
-  else {
-    for(Count = 0; Count < uIndex; Count++) {
-      if (lpls->lpNext == NULL) return LB_ERR;
-
-      lpls2 = lpls;
-      lpls = (LPLISTSTRUCT)lpls->lpNext;
-    }
-    lpls2->lpNext = (LPLISTSTRUCT)lpls->lpNext;
-  }
-
-  lphl->ItemsCount--;
-
-  if (lpls->hData != 0) LIST_HEAP_FREE(lphl, lpls->hData);
-  if (lpls->hMem != 0) LIST_HEAP_FREE(lphl, lpls->hMem);
-
-  SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), TRUE);
-  if (lphl->ItemsPerColumn != 0)
-    SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / 
-		   lphl->ItemsPerColumn + 1, TRUE);
-
-  if ((lphl->FirstVisible <= uIndex) &&
-      ((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) {
-    InvalidateRect(hwnd, NULL, TRUE);
-    UpdateWindow(hwnd);
-  }
-
-  return lphl->ItemsCount;
-}
-
-
-int ListBoxFindString(HWND hwnd, UINT nFirst, LPSTR MatchStr)
-{
-  WND          *wndPtr;
-  LPHEADLIST   lphl;
-  LPLISTSTRUCT lpls;
-  UINT	       Count;
-  UINT         First = nFirst + 1;
-
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-
-  if (lphl == NULL) return LB_ERR;
-
-  if (First > lphl->ItemsCount) return LB_ERR;
- 
-  lpls = ListBoxGetItem(hwnd, First);
-  Count = 0;
-  while(lpls != NULL) {
-    if (HasStrings(wndPtr)) {
-      if (strstr(lpls->itemText, MatchStr) == lpls->itemText) return Count;
-    } else if (wndPtr->dwStyle & LBS_SORT) {
-      /* XXX Do a compare item */
-    }
-    else
-      if (lpls->dis.itemData == (DWORD)MatchStr) return Count;
-
-    lpls = lpls->lpNext;
-    Count++;
-  }
-
-  /* Start over at top */
-  Count = 0;
-  lpls = lphl->lpFirst;
-
-  while (Count < First) {
-    if (HasStrings(wndPtr)) {
-      if (strstr(lpls->itemText, MatchStr) == lpls->itemText) return Count;
-    } else if (wndPtr->dwStyle & LBS_SORT) {
-      /* XXX Do a compare item */
-    }
-    else
-      if (lpls->dis.itemData == (DWORD)MatchStr) return Count;
-
-    lpls = lpls->lpNext;
-    Count++;
-  }
-
-  return LB_ERR;
-}
-
-
-int ListBoxResetContent(HWND hwnd)
-{
-    WND  *wndPtr;
-    LPHEADLIST 	lphl;
-    LPLISTSTRUCT lpls;
-    UINT	i;
-
-    lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-    if (lphl == NULL) return LB_ERR;
-
-    if (lphl->ItemsCount == 0) return 0;
-
-    lpls = lphl->lpFirst;
-
-    dprintf_listbox(stddeb, "ListBoxResetContent // ItemCount = %d\n",
-	lphl->ItemsCount);
-
-    for(i = 0; i < lphl->ItemsCount; i++) {
-      LPLISTSTRUCT lpls2;
-
-      if (lpls == NULL) return LB_ERR;
-
-      lpls2 = lpls->lpNext;
-
-      if (i != 0) {
-	dprintf_listbox(stddeb,"ResetContent #%u\n", i);
-	if (lpls->hData != 0 && lpls->hData != lpls->hMem)
-	  LIST_HEAP_FREE(lphl, lpls->hData);
-
-	if (lpls->hMem != 0) LIST_HEAP_FREE(lphl, lpls->hMem);
-      }  
-
-      lpls = lpls2;
-    }
-
-    lphl->lpFirst      = NULL;
-    lphl->FirstVisible = 1;
-    lphl->ItemsCount   = 0;
-    lphl->ItemFocused  = -1;
-    lphl->PrevFocused  = -1;
-
-    SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), TRUE);
-
-    if (lphl->ItemsPerColumn != 0)
-	SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / 
-	    lphl->ItemsPerColumn + 1, TRUE);
-
-    InvalidateRect(hwnd, NULL, TRUE);
-    UpdateWindow(hwnd);
-
-    return TRUE;
-}
-
-
-int ListBoxSetCurSel(HWND hwnd, WORD wIndex)
-
-{
-  WND  *wndPtr;
-  LPHEADLIST 	lphl;
-  LPLISTSTRUCT lpls;
-
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-  if (lphl == NULL) return LB_ERR;
-
-  if (wndPtr->dwStyle & LBS_MULTIPLESEL) return 0;
-
-  if (lphl->ItemFocused != -1) {
-    lpls = ListBoxGetItem(hwnd, lphl->ItemFocused);
-    if (lpls == 0) return LB_ERR;
-    lpls->dis.itemState = 0;
-  }
-
-  if (wIndex != (UINT)-1) {
-    lphl->ItemFocused = wIndex;
-    lpls = ListBoxGetItem(hwnd, wIndex);
-    if (lpls == 0) return LB_ERR;
-    lpls->dis.itemState = ODS_SELECTED | ODS_FOCUS;
-
-    return 0;
-  }
-
-  return LB_ERR;
-}
-
-int ListBoxSetSel(HWND hwnd, WORD wIndex, WORD state)
-
-{
-  LPHEADLIST 	lphl;
-  LPLISTSTRUCT lpls;
-  WND         *wndPtr;
-
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-  if (lphl == NULL) return LB_ERR;
-
-  if (!(wndPtr->dwStyle & LBS_MULTIPLESEL)) return 0;
-
-  if (wIndex == (UINT)-1) {
-    lpls = lphl->lpFirst;
-
-    while (lpls != NULL) {
-      lpls->dis.itemState = state;
-      lpls = lpls->lpNext;
-    }
-
-    return 0;
-  }
-
-  if (wIndex >= lphl->ItemsCount) return LB_ERR;
-
-  lpls = ListBoxGetItem(hwnd, wIndex);
-  lpls->dis.itemState = state;
-
-  return 0;
-}
-
-
-int ListBoxGetSel(HWND hwnd, WORD wIndex)
-{
-  LPLISTSTRUCT lpls;
-
-  if ((lpls = ListBoxGetItem(hwnd, wIndex)) == NULL) return LB_ERR;
-
-  return lpls->dis.itemState;
-}
-
-
-int ListBoxDirectory(HWND hwnd, UINT attrib, LPSTR filespec)
-{
-  struct dosdirent *dp, *dp_old;
-  int	x, wRet = LB_OKAY;
-  BOOL  OldFlag;
-  char 	temp[256];
-  LPHEADLIST 	lphl;
-  int   drive;
-  LPSTR tstr;
-
-  dprintf_listbox(stddeb,"ListBoxDirectory: %s, %4x\n",filespec,attrib);
-
-  if( strchr( filespec, '\\' ) || strchr( filespec, ':' ) ) {
-    drive = DOS_GetDefaultDrive();
-    if( filespec[1] == ':' ) {
-      drive = toupper(filespec[0]) - 'A';
-      filespec += 2;
-    }
-    strcpy(temp,filespec);
-    tstr = strrchr(temp, '\\');
-    if( tstr == NULL ) 
-      DOS_SetDefaultDrive( drive );
-    else {
-      *tstr = 0;
-      filespec = tstr + 1;
-      DOS_ChangeDir( drive, temp );
-      if (!DOS_ChangeDir( drive, temp )) return 0;
-    }
-    dprintf_listbox(stddeb,"Changing directory to %c:%s, filemask is %s\n",
-		    drive+'A', temp, filespec );
-  }
-  lphl = ListBoxGetStorageHeader(hwnd);
-  if (lphl == NULL) return LB_ERR;
-  if ((dp = (struct dosdirent *)DOS_opendir(filespec)) ==NULL) return 0;
-  dp_old = dp;
-  OldFlag = lphl->bRedrawFlag;
-  lphl->bRedrawFlag = FALSE;
-  while ((dp = (struct dosdirent *)DOS_readdir(dp))) {
-    if (!dp->inuse) break;
-    dprintf_listbox( stddeb, "ListBoxDirectory %p '%s' !\n", dp->filename, 
-		    dp->filename);
-    if (dp->attribute & FA_DIREC) {
-      if (attrib & DDL_DIRECTORY && strcmp(dp->filename, ".") != 0) {
-	sprintf(temp, "[%s]", dp->filename);
-	if ( (wRet = ListBoxAddString(hwnd, temp)) == LB_ERR) break;
-      }
-    } 
-    else {
-      if (attrib & DDL_EXCLUSIVE) {
-	if (attrib & (DDL_READWRITE | DDL_READONLY | DDL_HIDDEN |
-		      DDL_SYSTEM) )
-	  if ( (wRet = ListBoxAddString(hwnd, dp->filename)) 
-	      == LB_ERR) break;
-      } 
-      else {
-	if ( (wRet = ListBoxAddString(hwnd, dp->filename)) 
-	    == LB_ERR) break;
-      }
-    }
-  }
-  DOS_closedir(dp_old);
-  
-  if (attrib & DDL_DRIVES) {
-    for (x=0;x!=MAX_DOS_DRIVES;x++) {
-      if (DOS_ValidDrive(x)) {
-	sprintf(temp, "[-%c-]", 'a'+x);
-	if((wRet = ListBoxInsertString(hwnd, (UINT)-1, temp)) == LB_ERR) break;
-      }		
-    }
-  }
-  lphl->bRedrawFlag = OldFlag;
-  if (OldFlag) {
-    InvalidateRect(hwnd, NULL, TRUE);
-    UpdateWindow(hwnd);
-  }
-  dprintf_listbox(stddeb,"End of ListBoxDirectory !\n");
-  return 1;  /* FIXME: Should be 0 if "filespec" is invalid */
-}
-
-
-int ListBoxGetItemRect(HWND hwnd, WORD wIndex, LPRECT lprect)
-
-{
-  LPLISTSTRUCT lpls;
-
-  if ((lpls = ListBoxGetItem(hwnd, wIndex)) == NULL) return LB_ERR;
-
-  *(lprect) = lpls->dis.rcItem;
-
-  return 0;
-}
-
-
-int ListBoxSetItemHeight(HWND hwnd, WORD wIndex, long height)
-
-{
-  LPHEADLIST    lphl;
-  WND          *wndPtr;
-  LPLISTSTRUCT  lpls;
-
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-  if (lphl == NULL) return LB_ERR;
-
-  if (!(wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE)) {
-    lphl->StdItemHeight = (short)height;
-    InvalidateRect(hwnd, NULL, TRUE);
-    UpdateWindow(hwnd);
-
-    return 0;
-  }
-
-  if ((lpls = ListBoxGetItem(hwnd, wIndex)) == NULL) return LB_ERR;
-  
-  lpls->dis.rcItem.bottom = lpls->dis.rcItem.top + (short)height;
-  InvalidateRect(hwnd, NULL, TRUE);
-  UpdateWindow(hwnd);
-
-  return 0;
-}
-
-int ListBoxDefaultItem(HWND hwnd, WND *wndPtr, 
-	LPHEADLIST lphl, LPLISTSTRUCT lpls)
-
-{
-  RECT	rect;
-
-  if (wndPtr == NULL || lphl == NULL || lpls == NULL) {
-    fprintf(stderr,"ListBoxDefaultItem() // Bad Pointers !\n");
-    return FALSE;
-  }
-
-  GetClientRect(hwnd, &rect);
-  SetRect(&lpls->dis.rcItem, 0, 0, rect.right, lphl->StdItemHeight);
-
-  lpls->dis.CtlType    = lphl->DrawCtlType;
-  lpls->dis.CtlID      = wndPtr->wIDmenu;
-  lpls->dis.itemID     = 0;
-  lpls->dis.itemAction = 0;
-  lpls->dis.itemState  = 0;
-  lpls->dis.hwndItem   = hwnd;
-  lpls->dis.hDC        = 0;
-  lpls->dis.itemData   = 0;
-
-  return TRUE;
-}
-
-
-
-int ListBoxFindNextMatch(HWND hwnd, WORD wChar)
-
-{
-  WND  	        *wndPtr;
-  LPHEADLIST 	lphl;
-  LPLISTSTRUCT  lpls;
-  UINT	        Count;
-
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-  if (lphl == NULL) return LB_ERR;
-  lpls = lphl->lpFirst;
-  if (lpls == NULL) return LB_ERR;
-  if (wChar < ' ') return LB_ERR;
-
-  if (!HasStrings(wndPtr)) return LB_ERR;
-
-  Count = 0;
-  while(lpls != NULL) {
-    if (Count > lphl->ItemFocused) {
-      if (*(lpls->itemText) == (char)wChar) {
-	if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
-	  lphl->ItemFocused = Count;
-	  ListBoxScrolltoFocus(hwnd);
-	}
-	else {
-	  ListBoxSetCurSel(hwnd, Count);
-	}
-	SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
-	InvalidateRect(hwnd, NULL, TRUE);
-	UpdateWindow(hwnd);
-	return Count;
-      }
-    }
-    lpls = (LPLISTSTRUCT)lpls->lpNext;
-    Count++;
-  }
-  Count = 0;
-  lpls = lphl->lpFirst;
-  while(lpls != NULL) {
-    if (*(lpls->itemText) == (char)wChar) {
-      if (Count == lphl->ItemFocused)    return LB_ERR;
-
-      if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
-	lphl->ItemFocused = Count;
-	ListBoxScrolltoFocus(hwnd);
-      }
-      else {
-	ListBoxSetCurSel(hwnd, Count);
-      }
-      SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
-      InvalidateRect(hwnd, NULL, TRUE);
-      UpdateWindow(hwnd);
-      return Count;
-    }
-    lpls = lpls->lpNext;
-    Count++;
-  }
-  return LB_ERR;
-}
-
-
 /************************************************************************
  * 		      	DlgDirSelect			[USER.99]
  */
@@ -2087,12 +1770,12 @@
 
   hwnd = GetDlgItem(hDlg, nIDLBox);
   lphl = ListBoxGetStorageHeader(hwnd);
-  if( lphl->ItemFocused == -1 ) {
-    dprintf_listbox( stddeb, "Nothing selected!\n" );
+  if(lphl->ItemFocused == -1) {
+    dprintf_listbox(stddeb, "Nothing selected!\n");
     return FALSE;
   }
-  ListBoxGetText(hwnd, lphl->ItemFocused, (LPSTR)s, FALSE);
-  dprintf_listbox( stddeb, "Selection is %s\n", s );
+  ListBoxGetText(lphl, lphl->ItemFocused, s);
+  dprintf_listbox(stddeb, "Selection is %s\n", s);
   if( s[0] == '[' ) {
     if( s[1] == '-' ) {
       strncpy( lpStr, s+2, strlen(s)-4 );    /* device name */
@@ -2106,8 +1789,7 @@
     }
     dprintf_listbox( stddeb, "Returning %s\n", lpStr );
     return TRUE;
-  }
-  else {
+  } else {
     strcpy( lpStr, s );                     /* file name */
     dprintf_listbox( stddeb, "Returning %s\n", lpStr );
     return FALSE;
@@ -2116,27 +1798,27 @@
 
 
 /************************************************************************
- * 			   DlgDirList				[USER.100]
+ * 			   DlgDirList		       	[USER.100]
  */
 int DlgDirList(HWND hDlg, LPSTR lpPathSpec, 
-	int nIDLBox, int nIDStat, WORD wType)
+	       int nIDLBox, int nIDStat, WORD wType)
 {
   HWND	hWnd;
   int ret;
+  
   dprintf_listbox(stddeb,"DlgDirList(%04X, '%s', %d, %d, %04X) \n",
 		  hDlg, lpPathSpec, nIDLBox, nIDStat, wType);
-  if (nIDLBox)
+  if (nIDLBox)  {
+    LPHEADLIST lphl;
     hWnd = GetDlgItem(hDlg, nIDLBox);
-  else
-    hWnd = 0;
-  if (hWnd)
-    ListBoxResetContent(hWnd);
-  if (hWnd)
-    ret=ListBoxDirectory(hWnd, wType, lpPathSpec);
-  else
-    ret=0;
-  if (nIDStat)
-    {
+    lphl = ListBoxGetStorageHeader(hWnd);
+    ListBoxResetContent(lphl);
+    ret = ListBoxDirectory(lphl, wType, lpPathSpec);
+    ListBoxUpdateWindow(hWnd, lphl, TRUE);
+  } else {
+    ret = 0;
+  }
+  if (nIDStat) {
       int drive;
       HANDLE hTemp;
       char *temp;
@@ -2149,8 +1831,7 @@
 	temp[2] = ':';
 	SendDlgItemMessage( hDlg, nIDStat, WM_SETTEXT, 0,
                             USER_HEAP_SEG_ADDR(hTemp) + 1 );
-      }
-      else {
+      } else {
 	temp[0] = 'A'+drive;
 	temp[1] = ':';
 	temp[2] = '\\';
@@ -2158,53 +1839,6 @@
                             USER_HEAP_SEG_ADDR(hTemp) );
       }
       USER_HEAP_FREE( hTemp );
-    } 
+  } 
   return ret;
 }
-
-
-/* Returns: 0 if nothing needs to be changed */
-/*          1 if FirstVisible changed */
-
-int ListBoxScrolltoFocus(HWND hwnd)
-
-{
-  WND  *wndPtr;
-  LPHEADLIST  lphl;
-  short       end;
-
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-
-  if (lphl->ItemsCount == 0) return 0;
-  if (lphl->ItemFocused == -1) return 0;
-
-  end = lphl->FirstVisible + lphl->ItemsVisible - 2;
-
-  if (lphl->ItemFocused < lphl->FirstVisible - 1) {
-    lphl->FirstVisible = lphl->ItemFocused + 1;
-  }
-  else if (lphl->ItemFocused > end) {
-    UINT maxFirstVisible = ListMaxFirstVisible(lphl);
-
-    lphl->FirstVisible = lphl->ItemFocused;
-
-    if (lphl->FirstVisible > maxFirstVisible) {
-      lphl->FirstVisible = maxFirstVisible;
-    }
-  } else return 0;
-
-  return 1;
-}
-
-/* Send notification "code" as part of a WM_COMMAND-message if hwnd
-   has the LBS_NOTIFY style */
-void ListBoxSendNotification(HWND hwnd, WORD code)
-{
-  WND  *wndPtr;
-  LPHEADLIST  lphl;
-  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-
-  if (wndPtr && (wndPtr->dwStyle & LBS_NOTIFY))
-    SendMessage(lphl->hWndLogicParent, WM_COMMAND,
-		wndPtr->wIDmenu, MAKELONG(hwnd, code));
-}
diff --git a/controls/menu.c b/controls/menu.c
index be7df27..01a040c 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -21,7 +21,6 @@
 #include "menu.h"
 #include "user.h"
 #include "win.h"
-#include "library.h"
 #include "message.h"
 #include "graphics.h"
 #include "stddebug.h"
@@ -667,7 +666,7 @@
 	menu->FocusedItem = NO_SELECTED_ITEM;
     }
     SendMessage( hwndOwner, WM_INITMENUPOPUP, hmenu,
-		 MAKELONG( id, (menu->wFlags & MF_POPUP) ? 1 : 0 ));
+		 MAKELONG( id, (menu->wFlags & MF_SYSMENU) ? 1 : 0 ));
     MENU_PopupMenuCalcSize( menu, hwndOwner );
     if (!menu->hWnd)
     {
@@ -740,7 +739,7 @@
 			       !(lppop->wFlags & MF_POPUP) );
 	    dprintf_menu(stddeb,"Sending WM_MENUSELECT %04x %04x\n", items[lppop->FocusedItem].item_id,items[lppop->FocusedItem].item_flags);
 	    SendMessage(lppop->hWnd, WM_MENUSELECT, items[lppop->FocusedItem].item_id,
-		       MAKELONG( hmenu, items[lppop->FocusedItem].item_flags));
+		       MAKELONG( items[lppop->FocusedItem].item_flags | MF_MOUSESELECT, hmenu));
 	}
     }
     ReleaseDC( lppop->hWnd, hdc );
diff --git a/controls/widgets.c b/controls/widgets.c
index a2f17a9..f816c76 100644
--- a/controls/widgets.c
+++ b/controls/widgets.c
@@ -2,9 +2,7 @@
  * Windows widgets (built-in window classes)
  *
  * Copyright 1993 Alexandre Julliard
-
-static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
-*/
+ */
 
 #include "win.h"
 #include "button.h"
@@ -15,6 +13,7 @@
 #include "gdi.h"
 #include "user.h"
 #include "selectors.h"
+#include "stackframe.h"
 
 
 static WNDCLASS WIDGETS_BuiltinClasses[] =
@@ -27,8 +26,10 @@
       sizeof(SCROLLINFO), 0, 0, 0, 0, NULL, "SCROLLBAR" },
     { CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, (WNDPROC)"ListBoxWndProc", 0,
       8, 0, 0, 0, 0, NULL, "LISTBOX" },
-    { CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, (WNDPROC)"ComboBoxWndProc", 0,
+    { CS_GLOBALCLASS | CS_PARENTDC, (WNDPROC)"ComboBoxWndProc", 0,
       8, 0, 0, 0, 0, NULL, "COMBOBOX" },
+    { CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, (WNDPROC)"ComboLBoxWndProc", 0,
+      8, 0, 0, 0, 0, NULL, "COMBOLBOX" },
     { CS_GLOBALCLASS, (WNDPROC)"EditWndProc", 0,
       sizeof(WORD), 0, 0, 0, 0, NULL, "EDIT" },
     { CS_GLOBALCLASS | CS_SAVEBITS, (WNDPROC)"PopupMenuWndProc", 0,
@@ -53,20 +54,16 @@
 BOOL WIDGETS_Init(void)
 {
     int i;
-    HANDLE hName;
-    char *name;
+    char name[20];
     WNDCLASS *class = WIDGETS_BuiltinClasses;
 
-    if (!(hName = USER_HEAP_ALLOC( 20 ))) return FALSE;
-    name = USER_HEAP_LIN_ADDR( hName );
     for (i = 0; i < NB_BUILTIN_CLASSES; i++, class++)
     {
         strcpy( name, class->lpszClassName );
-        class->lpszClassName = (LPSTR)USER_HEAP_SEG_ADDR( hName );
+        class->lpszClassName = (LPSTR)MAKE_SEGPTR(name);
 	class->hCursor = LoadCursor( 0, IDC_ARROW );
         class->lpfnWndProc = GetWndProcEntry16( (char *)class->lpfnWndProc );
 	if (!RegisterClass( class )) return FALSE;
     }
-    USER_HEAP_FREE( hName );
     return TRUE;
 }
diff --git a/debugger/db_disasm.c b/debugger/db_disasm.c
index 568a933..fe64594 100644
--- a/debugger/db_disasm.c
+++ b/debugger/db_disasm.c
@@ -74,6 +74,8 @@
 #include "db_disasm.h"
 #include "ldt.h"
 
+extern void print_address(unsigned int addr, FILE * outfile, int addrlen);
+
 /*
  * Switch to disassemble 16-bit code.
  */
@@ -1016,7 +1018,6 @@
 
 static void db_task_printsym(unsigned int addr, int size)
 {
-    extern void print_address(unsigned int addr, FILE * outfile, int addrlen);
     switch(size)
     {
     case BYTE:
@@ -1486,7 +1487,10 @@
 			get_value_inc(imm, loc, 4, FALSE); /* offset */
 		    }
 		    get_value_inc(imm2, loc, 2, FALSE);	/* segment */
-		    fprintf(stderr,"$%d,%d", imm2, imm);
+                    if (short_addr)
+                        print_address( (imm2 << 16) | imm, stderr, 16 );
+                    else
+                        fprintf(stderr,"$0x%x,0x%08x", imm2, imm);
 		    break;
 	    }
 	}
diff --git a/debugger/dbg.y b/debugger/dbg.y
index 54d5992..cf7a3d2 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -11,6 +11,8 @@
 #include <stdio.h>
 #include <signal.h>
 #include "ldt.h"
+#include "windows.h"
+#include "wine.h"
 
 #define YYSTYPE int
 
@@ -41,6 +43,7 @@
 %token SET
 %token MODE
 %token PRINT
+%token FILE_IDENTIFIER
 %token IDENTIFIER
 %token NO_SYMBOL
 %token SYMBOLFILE
@@ -61,8 +64,8 @@
 	| CONT '\n'        { return 0; }
 	| 'c' '\n'         { return 0; }
 	| ABORT '\n'       { kill(getpid(), SIGABRT); }
-	| SYMBOLFILE IDENTIFIER '\n' { read_symboltable($2); }
-	| DEFINE IDENTIFIER expr '\n'  { add_hash($2, $3); }
+ 	| SYMBOLFILE FILE_IDENTIFIER '\n' { read_symboltable($2); }
+	| DEFINE IDENTIFIER expr '\n'  { add_hash($2, 0, $3); }
 	| MODE NUM	   { mode_command($2); }
 	| ENABLE NUM	   { enable_break($2); }
 	| DISABLE NUM	   { disable_break($2); }
@@ -151,6 +154,7 @@
 wine_debug(int signal, int * regs)
 {
 	static int dummy_regs[32];
+	char SymbolTableFile[256];
 #ifdef YYDEBUG
 	yydebug = 0;
 #endif
@@ -158,34 +162,23 @@
 	yyin = stdin;
 	regval = regs ? regs : dummy_regs;
 
-#ifdef linux        
-	if((SC_CS & 7) != 7) {
+	if (SC_CS == WINE_CODE_SELECTOR)
+        {
 		dbg_mask = 0xffffffff;
 		dbg_mode = 32;
-	} else {
+	} else
+        {
 		dbg_mask = 0xffff;
 		dbg_mode = 16;
 	}
-#endif
-#ifdef __NetBSD__
-	if(SC_CS == 0x1f) {
-		dbg_mask = 0xffffffff;
-		dbg_mode = 32;
-	} else {
-		dbg_mask = 0xffff;
-		dbg_mode = 16;
-	}
-#endif
 	fprintf(stderr,"In %d bit mode.\n", dbg_mode);
 
-	/* This is intended to read the entry points from the Windows image, and
-	   insert them in the hash table.  It does not work yet, so it is commented out. */
-	if(dbg_mode == 32 && !loaded_symbols){
+	if(dbg_mode == 32 && !loaded_symbols)
+        {
 		loaded_symbols++;
-		read_symboltable("wine.sym");
-#if 0
-		load_entrypoints();
-#endif
+		GetPrivateProfileString("wine", "SymbolTableFile", "wine.sym",
+			SymbolTableFile, sizeof(SymbolTableFile), WINE_INI);
+		read_symboltable(SymbolTableFile);
 	}
 
 	/* Remove the breakpoints from memory... */
diff --git a/debugger/debug.l b/debugger/debug.l
index 3a1a92e..18a6b5a 100644
--- a/debugger/debug.l
+++ b/debugger/debug.l
@@ -29,6 +29,7 @@
 HEXDIGIT [0-9a-fA-F]
 
 IDENTIFIER [_a-zA-Z\.~][_a-zA-Z0-9\.~]*
+FILE_IDENTIFIER [_a-zA-Z\.~/][_a-zA-Z\.~/]*
 
 %%
 
@@ -61,9 +62,9 @@
 		}
 
 $pc		{ yylval = RN_EIP; return REG;}
-$sp		{ yylval = RN_ESP; return REG;}
+$sp		{ yylval = RN_ESP_AT_SIGNAL; return REG;}
 $eip		{ yylval = RN_EIP; return REG;}
-$esp		{ yylval = RN_ESP; return REG;}
+$esp		{ yylval = RN_ESP_AT_SIGNAL; return REG;}
 $ebp		{ yylval = RN_EBP; return REG;}
 $eax		{ yylval = RN_EAX; return REG;}
 $ebx		{ yylval = RN_EBX; return REG;}
@@ -119,6 +120,10 @@
 	          return IDENTIFIER;
 	         }
 
+{FILE_IDENTIFIER} {yylval = (int) make_symbol(yytext); 
+	          return FILE_IDENTIFIER;
+	         }
+
 [ \t]+        /* Eat up whitespace */
 
 .		{ if(syntax_error == 0) {
@@ -203,7 +208,7 @@
 static int next_symbol;
 
 char * make_symbol(char * symbol){
-	return local_symbols[next_symbol++] = strdup(symbol);
+        return local_symbols[next_symbol++] = strdup(symbol);
 }
 
 void
diff --git a/debugger/hash.c b/debugger/hash.c
index 26d822b..4dd93ad 100644
--- a/debugger/hash.c
+++ b/debugger/hash.c
@@ -10,12 +10,13 @@
 #include <string.h>
 #include <sys/types.h>
 #include <neexe.h>
+#include "module.h"
 #include "selectors.h"
-#include <wine.h>
-#include <dlls.h>
+#include "wine.h"
 
 struct  name_hash{
 	struct name_hash * next;
+        unsigned short segment;
 	unsigned int * address;
 	char * name;
 };
@@ -36,11 +37,13 @@
 }
 
 
-void add_hash(char * name, unsigned int * address){
+void add_hash(char * name, unsigned short segment, unsigned int * address)
+{
 	struct name_hash  * new;
 	int hash;
 
 	new = (struct  name_hash *) malloc(sizeof(struct name_hash));
+        new->segment = segment;
 	new->address = address;
 	new->name = strdup(name);
 	new->next = NULL;
@@ -51,7 +54,8 @@
 	name_hash_table[hash] = new;
 }
 
-unsigned int * find_hash(char * name){
+unsigned int * find_hash(char * name)
+{
 	char buffer[256];
 	struct name_hash  * nh;
 
@@ -72,7 +76,8 @@
 
 static char name_buffer[256];
 
-char * find_nearest_symbol(unsigned int * address){
+char * find_nearest_symbol(unsigned int segment, unsigned int * address)
+{
 	struct name_hash * nearest;
 	struct name_hash start;
 	struct name_hash  * nh;
@@ -83,8 +88,9 @@
 	
 	for(i=0; i<NR_NAME_HASH; i++) {
 		for(nh = name_hash_table[i]; nh; nh = nh->next)
-			if(nh->address <= address && nh->address > nearest->address)
-				nearest = nh;
+			if (nh->segment == segment &&
+                            nh->address <= address &&
+                            nh->address > nearest->address) nearest = nh;
 	};
 	if((unsigned int) nearest->address == 0) return NULL;
 
@@ -136,7 +142,7 @@
 		};
 		
 		nargs = sscanf(buffer, "%x %c %s", &addr, &type, name);
-		add_hash(name, (unsigned int *) addr);
+		add_hash(name, 0, (unsigned int *) addr);
       };
       fclose(symbolfile);
 }
@@ -147,33 +153,40 @@
  * tables correctly 
  */
 
-void
-load_entrypoints(){
-	char buffer[256];
-	char * cpnt;
-	int j, ordinal, len;
-	unsigned int address;
+void load_entrypoints( HMODULE hModule )
+{
+    char buffer[256];
+    unsigned char *cpnt, *name;
+    NE_MODULE *pModule;
+    unsigned int address;
 
-#if 0
-	struct w_files * wpnt;
-	for(wpnt = wine_files; wpnt; wpnt = wpnt->next){
-		cpnt  = wpnt->ne->nrname_table;
-		while(1==1){
-			if( ((int) cpnt)  - ((int)wpnt->ne->nrname_table) >  
-			   wpnt->ne->ne_header->nrname_tab_length)  break;
-			len = *cpnt++;
-			strncpy(buffer, cpnt, len);
-			buffer[len] = 0;
-			ordinal =  *((unsigned short *)  (cpnt +  len));
-			j = GetEntryPointFromOrdinal(wpnt, ordinal);		
-			address  = j & 0xffff;
-			j = j >> 16;
-			address |= wpnt->ne->selector_table[j] << 16;
-			fprintf(stderr,"%s -> %x\n", buffer, address);
-			add_hash(buffer, (unsigned int *) address);
-			cpnt += len + 2;
-		};
-	};
-	return;
-#endif
+    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return;
+    name = (unsigned char *)pModule + pModule->name_table;
+
+      /* First search the resident names */
+
+    cpnt = (unsigned char *)pModule + pModule->name_table;
+    while (*cpnt)
+    {
+        cpnt += *cpnt + 1 + sizeof(WORD);
+        sprintf( buffer, "%*.*s.%*.*s", *name, *name, name + 1,
+                 *cpnt, *cpnt, cpnt + 1 );
+        address = MODULE_GetEntryPoint( hModule, *(WORD *)(cpnt + *cpnt + 1) );
+        if (address)
+            add_hash(buffer, address >> 16, (unsigned int*)(address & 0xffff));
+    }
+
+      /* Now search the non-resident names table */
+
+    if (!pModule->nrname_handle) return;  /* No non-resident table */
+    cpnt = (char *)GlobalLock( pModule->nrname_handle );
+    while (*cpnt)
+    {
+        cpnt += *cpnt + 1 + sizeof(WORD);
+        sprintf( buffer, "%*.*s.%*.*s", *name, *name, name + 1,
+                 *cpnt, *cpnt, cpnt + 1 );
+        address = MODULE_GetEntryPoint( hModule, *(WORD *)(cpnt + *cpnt + 1) );
+        if (address)
+            add_hash(buffer, address >> 16, (unsigned int*)(address & 0xffff));
+    }
 }
diff --git a/debugger/info.c b/debugger/info.c
index 8166310..b31eeae 100644
--- a/debugger/info.c
+++ b/debugger/info.c
@@ -21,15 +21,22 @@
 
 void print_address(unsigned int addr, FILE * outfile, int addrlen)
 {
+    extern char * find_nearest_symbol(unsigned short, unsigned int *);
+    char *name;
+
     if (addrlen == 16)
     {
-        fprintf( outfile, "%4.4x:%4.4x", addr >> 16, addr & 0xffff );
+        name = find_nearest_symbol( addr >> 16,
+                                    (unsigned int *)(addr & 0xffff) );
+        if (name)
+            fprintf( outfile, "0x%4.4x:0x%4.4x (%s)",
+                     addr >> 16, addr & 0xffff, name );
+        else
+            fprintf( outfile, "0x%4.4x:0x%4.4x", addr >> 16, addr & 0xffff );
     }
     else
     {
-        extern char * find_nearest_symbol(unsigned int *);
-
-        char * name = find_nearest_symbol((unsigned int *) addr);
+        name = find_nearest_symbol(0, (unsigned int *) addr);
 	if(name)
 		fprintf(outfile,"0x%8.8x(%s)", addr, name);
 	else
diff --git a/debugger/readline/Imakefile b/debugger/readline/Imakefile
index f780bd6..aebd03a 100644
--- a/debugger/readline/Imakefile
+++ b/debugger/readline/Imakefile
@@ -4,7 +4,7 @@
 
 YACC = yacc -b dbg -d
 
-DEFINES	= -DANSI_ARROWS -DHAVE_TCGETATTR -DHIDE -DUSE_DIRENT -DSYS_UNIX
+EXTRA_DEFINES= -DANSI_ARROWS -DHAVE_TCGETATTR -DHIDE -DUSE_DIRENT -DSYS_UNIX
 
 SRCS = \
 	complete.c \
diff --git a/debugger/regpos.h b/debugger/regpos.h
index 39d4b5e..e4068e1 100644
--- a/debugger/regpos.h
+++ b/debugger/regpos.h
@@ -25,7 +25,28 @@
 #define  RN_CR2			21
 #endif
 
-#if defined(__NetBSD__) || defined(__FreeBSD__)
+#ifdef __NetBSD__
+/* Register numbers */
+#define  RN_GS			0
+#define  RN_FS			1
+#define  RN_ES			2
+#define  RN_DS			3
+#define  RN_EDI  		4
+#define  RN_ESI			5
+#define  RN_EBP			6
+#define  RN_EBX			7
+#define  RN_EDX			8
+#define  RN_ECX			9
+#define  RN_EAX			10
+#define  RN_EIP			11
+#define  RN_CS			12
+#define  RN_EFLAGS		13
+#define  RN_ESP_AT_SIGNAL	14
+#define  RN_SS			15
+#define  RN_OLDMASK		17
+#endif
+
+#ifdef __FreeBSD__
 #define  RN_OLDMASK		1
 /* Register numbers */
 #define  RN_ESP			2
@@ -43,7 +64,7 @@
 #define  RN_EDX			14
 #define  RN_ECX			15
 #define  RN_EAX			16
-/* NetBSD doesn't context switch gs or fs */
+/* FreeBSD doesn't save gs or fs */
 #define  SC_GS			0x27
 #define  SC_FS			0x27
 #endif
@@ -54,12 +75,15 @@
 #define  I387			regval[RN_I387]
 #define  CR2			regval[RN_CR2]
 #endif
+#ifdef __NetBSD__
+#define  SC_GS			regval[RN_GS]
+#define  SC_FS			regval[RN_FS]
+#endif
 #define  SC_ES			regval[RN_ES]
 #define  SC_DS			regval[RN_DS]
 #define  SC_EDI(dbg_mask)  	(regval[RN_EDI] & dbg_mask)
 #define  SC_ESI(dbg_mask)	(regval[RN_ESI] & dbg_mask)
 #define  SC_EBP(dbg_mask)	(regval[RN_EBP] & dbg_mask)
-#define  SC_ESP(dbg_mask)	(regval[RN_ESP] & dbg_mask)
 #define  SC_EBX(dbg_mask)	(regval[RN_EBX] & dbg_mask)
 #define  SC_EDX(dbg_mask)	(regval[RN_EDX] & dbg_mask)
 #define  SC_ECX(dbg_mask)	(regval[RN_ECX] & dbg_mask)
@@ -77,6 +101,6 @@
 #define  SC_EIP(dbg_mask)	(regval[RN_EIP] & dbg_mask)
 #define  SC_CS			regval[RN_CS]
 #define  SC_EFLAGS		regval[RN_EFLAGS]
-#define  ESP_AT_SIGNAL		regval[RN_ESP_AT_SIGNAL]
+#define  SC_ESP(dbg_mask)	(regval[RN_ESP_AT_SIGNAL] & dbg_mask)
 #define  SC_SS			regval[RN_SS]
 #define  OLDMASK		regval[RN_OLDMASK]
diff --git a/if1632/Imakefile b/if1632/Imakefile
index b3790ae..6e32cab 100644
--- a/if1632/Imakefile
+++ b/if1632/Imakefile
@@ -5,87 +5,105 @@
 
 SRCS = \
 	callback.c \
-	relay.c
+	relay.c \
+	relay32.c
 
 #ifdef WINELIB
 CALLOBJS =
-DLLS =
+DLLS16 =
+DLLS32 =
 #else
 CALLOBJS = \
 	call16.o \
 	call32.o
-DLLS = \
-	commdlg \
-	compobj \
-	ddeml \
-	gdi \
-	kernel \
-	keyboard \
-	mmsystem \
-	mouse \
-	ole2 \
-	ole2conv \
-	ole2disp \
-	ole2nls \
-	ole2prox \
-	olecli \
-	olesvr \
-	shell \
-	sound \
-	storage \
-	stress \
-	system \
-	toolhelp \
-	user \
-	win87em \
-	winprocs \
-	winsock
+DLLS16 = \
+	commdlg.spec \
+	compobj.spec \
+	ddeml.spec \
+	gdi.spec \
+	kernel.spec \
+	keyboard.spec \
+	mmsystem.spec \
+	mouse.spec \
+	ole2.spec \
+	ole2conv.spec \
+	ole2disp.spec \
+	ole2nls.spec \
+	ole2prox.spec \
+	olecli.spec \
+	olesvr.spec \
+	shell.spec \
+	sound.spec \
+	storage.spec \
+	stress.spec \
+	system.spec \
+	toolhelp.spec \
+	user.spec \
+	win87em.spec \
+	winprocs.spec \
+	winsock.spec
+DLLS32 = \
+	gdi32.spec \
+	kernel32.spec \
+	shell32.spec \
+	user32.spec \
+	winprocs32.spec
 #endif
 
-OBJS = $(SRCS:.c=.o) $(CALLOBJS) $(DLLS:%=dll_%.o) $(DLLS:%=tab_%.o)
+OBJS = $(SRCS:.c=.o) $(CALLOBJS) $(DLLS16:.spec=.o) $(DLLS32:.spec=.o)
 
 BUILD = $(TOP)/tools/build
 
-#define MakeDllFromSpec(name)					@@\
-Concat(dll_,name.S) Concat(tab_,name.c): name.spec $(BUILD)	@@\
-	$(BUILD) -spec name.spec				@@\
+#define MakeDll16FromSpec(name)			@@\
+name.S : name.spec $(BUILD)			@@\
+	$(BUILD) -spec16 name.spec > name.S	@@\
+
+#define MakeDll32FromSpec(name)			@@\
+name.c : name.spec $(BUILD)			@@\
+	$(BUILD) -spec32 name.spec > name.c	@@\
 
 /*
  * If you add a new spec file, copy one of these lines
  */
-MakeDllFromSpec(commdlg)
-MakeDllFromSpec(compobj)
-MakeDllFromSpec(ddeml)
-MakeDllFromSpec(gdi)
-MakeDllFromSpec(kernel)
-MakeDllFromSpec(keyboard)
-MakeDllFromSpec(shell)
-MakeDllFromSpec(mmsystem)
-MakeDllFromSpec(mouse)
-MakeDllFromSpec(ole2)
-MakeDllFromSpec(ole2conv)
-MakeDllFromSpec(ole2disp)
-MakeDllFromSpec(ole2nls)
-MakeDllFromSpec(ole2prox)
-MakeDllFromSpec(olecli)
-MakeDllFromSpec(olesvr)
-MakeDllFromSpec(sound)
-MakeDllFromSpec(storage)
-MakeDllFromSpec(stress)
-MakeDllFromSpec(system)
-MakeDllFromSpec(toolhelp)
-MakeDllFromSpec(user)
-MakeDllFromSpec(win87em)
-MakeDllFromSpec(winprocs)
-MakeDllFromSpec(winsock)
+MakeDll16FromSpec(commdlg)
+MakeDll16FromSpec(compobj)
+MakeDll16FromSpec(ddeml)
+MakeDll16FromSpec(gdi)
+MakeDll16FromSpec(kernel)
+MakeDll16FromSpec(keyboard)
+MakeDll16FromSpec(shell)
+MakeDll16FromSpec(mmsystem)
+MakeDll16FromSpec(mouse)
+MakeDll16FromSpec(ole2)
+MakeDll16FromSpec(ole2conv)
+MakeDll16FromSpec(ole2disp)
+MakeDll16FromSpec(ole2nls)
+MakeDll16FromSpec(ole2prox)
+MakeDll16FromSpec(olecli)
+MakeDll16FromSpec(olesvr)
+MakeDll16FromSpec(sound)
+MakeDll16FromSpec(storage)
+MakeDll16FromSpec(stress)
+MakeDll16FromSpec(system)
+MakeDll16FromSpec(toolhelp)
+MakeDll16FromSpec(user)
+MakeDll16FromSpec(win87em)
+MakeDll16FromSpec(winprocs)
+MakeDll16FromSpec(winsock)
+
+MakeDll32FromSpec(gdi32)
+MakeDll32FromSpec(kernel32)
+MakeDll32FromSpec(shell32)
+MakeDll32FromSpec(user32)
+MakeDll32FromSpec(winprocs32)
 
 WineRelocatableTarget($(MODULE),,$(OBJS))
 DependTarget()
 
 #ifndef WINELIB
 
-call32.S: $(BUILD) $(DLLS:%=dll_%.S)
-	$(BUILD) -call32 `cat $(DLLS:%=dll_%.S) | grep CallTo32_ | sed 's/.*CallTo32_\(.*\)/\1/' | sort | uniq` > call32.S
+call32.S: $(BUILD) $(DLLS16:.spec=.S)
+	$(BUILD) -call32 `cat $(DLLS16:.spec=.S) | grep CallTo32_ | sed 's/.*CallTo32_\(.*\)/\1/' | sort | uniq` > call32.S
 
 call16.S: $(BUILD) $(TOP)/include/callback.h
 	$(BUILD) -call16 `cat $(TOP)/include/callback.h | grep "extern.*CallTo16_" | sed 's/.*CallTo16_\(.*\)(.*/\1/' | sort | uniq` > call16.S
@@ -97,4 +115,4 @@
 install::
 
 clean::
-	$(RM) dll_* tab_* call32.S call16.S
+	$(RM) $(DLLS16:.spec=.S) $(DLLS32:.spec=.c) call32.S call16.S
diff --git a/if1632/commdlg.spec b/if1632/commdlg.spec
index ab78653..127e064 100644
--- a/if1632/commdlg.spec
+++ b/if1632/commdlg.spec
@@ -12,7 +12,7 @@
  12   pascal  REPLACETEXT(ptr) ReplaceText
  13   pascal  FINDTEXTDLGPROC(word word word long) FindTextDlgProc
  14   pascal  REPLACETEXTDLGPROC(word word word long) ReplaceTextDlgProc
-# 15   pascal  CHOOSEFONT exported, shared data
+ 15   stub  ChooseFont
 # 16   pascal  FORMATCHARDLGPROC exported, shared data
 # 18   pascal  FONTSTYLEENUMPROC exported, shared data
 # 19   pascal  FONTFAMILYENUMPROC exported, shared data
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index a514fc6..598d289 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -234,6 +234,7 @@
 368 stub ResizePalette
 370 pascal16 GetNearestPaletteIndex(word long) GetNearestPaletteIndex
 372 pascal16 ExtFloodFill(word s_word s_word long word) ExtFloodFill
+374 pascal16 GetSystemPaletteUse(word) GetSystemPaletteUse
 375 pascal16 GetSystemPaletteEntries(word word word ptr)
              GetSystemPaletteEntries
 376 stub ResetDC
@@ -252,7 +253,8 @@
 410 stub ISVALIDMETAFILE
 411 pascal16 GetCurLogFont(word) GetCurLogFont
 412 stub IsDCCurrentPalette
-439 stub StretchDIBits
+439 pascal16 StretchDIBits (word s_word s_word word word word word
+                               word word ptr ptr word long) StretchDIBits
 440 pascal16 SetDIBits(word word word word ptr ptr word) SetDIBits
 441 pascal16 GetDIBits(word word word word ptr ptr word) GetDIBits
 442 pascal16 CreateDIBitmap(word ptr long ptr ptr word) CreateDIBitmap
diff --git a/if1632/gdi32.spec b/if1632/gdi32.spec
new file mode 100644
index 0000000..1e5b1f4
--- /dev/null
+++ b/if1632/gdi32.spec
@@ -0,0 +1,366 @@
+name	gdi32
+base	1
+
+0000 stub AbortDoc
+0001 stub AbortPath
+0002 stub AddFontResourceA
+0003 stub AddFontResourceTracking
+0004 stub AddFontResourceW
+0005 stub AngleArc
+0006 stub AnimatePalette
+0007 stub Arc
+0008 stub ArcTo
+0009 stub BeginPath
+0010 stub BitBlt
+0011 stub CancelDC
+0012 stub CheckColorsInGamut
+0013 stub ChoosePixelFormat
+0014 stub Chord
+0015 stub CloseEnhMetaFile
+0016 stub CloseFigure
+0017 stub CloseMetaFile
+0018 stub ColorMatchToTarget
+0019 stub CombineRgn
+0020 stub CombineTransform
+0021 stub CopyEnhMetaFileA
+0022 stub CopyEnhMetaFileW
+0023 stub CopyMetaFileA
+0024 stub CopyMetaFileW
+0025 stub CreateBitmap
+0026 stub CreateBitmapIndirect
+0027 stub CreateBrushIndirect
+0028 stub CreateColorSpaceA
+0029 stub CreateColorSpaceW
+0030 stub CreateCompatibleBitmap
+0031 stub CreateCompatibleDC
+0032 stub CreateDCA
+0033 stub CreateDCW
+0034 stub CreateDIBPatternBrush
+0035 stub CreateDIBPatternBrushPt
+0036 stub CreateDIBSection
+0037 stub CreateDIBitmap
+0038 stub CreateDiscardableBitmap
+0039 stub CreateEllipticRgn
+0040 stub CreateEllipticRgnIndirect
+0041 stub CreateEnhMetaFileA
+0042 stub CreateEnhMetaFileW
+0043 stub CreateFontA
+0044 stub CreateFontIndirectA
+0045 stub CreateFontIndirectW
+0046 stub CreateFontW
+0047 stub CreateHalftonePalette
+0048 stub CreateHatchBrush
+0049 stub CreateICA
+0050 stub CreateICW
+0051 stub CreateMetaFileA
+0052 stub CreateMetaFileW
+0053 stub CreatePalette
+0054 stub CreatePatternBrush
+0055 stub CreatePen
+0056 stub CreatePenIndirect
+0057 stub CreatePolyPolygonRgn
+0058 stub CreatePolygonRgn
+0059 stub CreateRectRgn
+0060 stub CreateRectRgnIndirect
+0061 stub CreateRoundRectRgn
+0062 stub CreateScalableFontResourceA
+0063 stub CreateScalableFontResourceW
+0064 stub CreateSolidBrush
+0065 stub DPtoLP
+0066 stub DeleteColorSpace
+0067 stub DeleteDC
+0068 stub DeleteEnhMetaFile
+0069 stub DeleteMetaFile
+0070 stub DeleteObject
+0071 stub DescribePixelFormat
+0072 stub DeviceCapabilitiesExA
+0073 stub DeviceCapabilitiesExW
+0074 stub DrawEscape
+0075 stub Ellipse
+0076 stub EndDoc
+0077 stub EndPage
+0078 stub EndPath
+0079 stub EnumEnhMetaFile
+0080 stub EnumFontFamiliesA
+0081 stub EnumFontFamiliesExA
+0082 stub EnumFontFamiliesExW
+0083 stub EnumFontFamiliesW
+0084 stub EnumFontsA
+0085 stub EnumFontsW
+0086 stub EnumICMProfilesA
+0087 stub EnumICMProfilesW
+0088 stub EnumMetaFile
+0089 stub EnumObjects
+0090 stub EqualRgn
+0091 stub Escape
+0092 stub ExcludeClipRect
+0093 stub ExtCreatePen
+0094 stub ExtCreateRegion
+0095 stub ExtEscape
+0096 stub ExtFloodFill
+0097 stub ExtSelectClipRgn
+0098 stub ExtTextOutA
+0099 stub ExtTextOutW
+0100 stub FillPath
+0101 stub FillRgn
+0102 stub FixBrushOrgEx
+0103 stub FlattenPath
+0104 stub FloodFill
+0105 stub FrameRgn
+0106 stub FreeImageColorMatcher
+0107 stub GdiAssociateObject
+0108 stub GdiCleanCacheDC
+0109 stub GdiComment
+0110 stub GdiConvertAndCheckDC
+0111 stub GdiConvertBitmap
+0112 stub GdiConvertBrush
+0113 stub GdiConvertDC
+0114 stub GdiConvertEnhMetaFile
+0115 stub GdiConvertFont
+0116 stub GdiConvertMetaFilePict
+0117 stub GdiConvertPalette
+0118 stub GdiConvertRegion
+0119 stub GdiCreateLocalBitmap
+0120 stub GdiCreateLocalBrush
+0121 stub GdiCreateLocalEnhMetaFile
+0122 stub GdiCreateLocalFont
+0123 stub GdiCreateLocalMetaFilePict
+0124 stub GdiCreateLocalPalette
+0125 stub GdiCreateLocalRegion
+0126 stub GdiDeleteLocalDC
+0127 stub GdiDeleteLocalObject
+0128 stub GdiFlush
+0129 stub GdiGetBatchLimit
+0130 stub GdiGetLocalBrush
+0131 stub GdiGetLocalDC
+0132 stub GdiGetLocalFont
+0133 stub GdiIsMetaFileDC
+0134 stub GdiPlayDCScript
+0135 stub GdiPlayJournal
+0136 stub GdiPlayScript
+0137 stub GdiReleaseLocalDC
+0138 stub GdiSetAttrs
+0139 stub GdiSetBatchLimit
+0140 stub GdiSetServerAttr
+0141 stub GetArcDirection
+0142 stub GetAspectRatioFilterEx
+0143 stub GetBitmapBits
+0144 stub GetBitmapDimensionEx
+0145 stub GetBkColor
+0146 stub GetBkMode
+0147 stub GetBoundsRect
+0148 stub GetBrushOrgEx
+0149 stub GetCharABCWidthsA
+0150 stub GetCharABCWidthsFloatA
+0151 stub GetCharABCWidthsFloatW
+0152 stub GetCharABCWidthsW
+0153 stub GetCharWidth32A
+0154 stub GetCharWidth32W
+0155 stub GetCharWidthA
+0156 stub GetCharWidthFloatA
+0157 stub GetCharWidthFloatW
+0158 stub GetCharWidthW
+0159 stub GetCharWidthWOW
+0160 stub GetCharacterPlacementA
+0161 stub GetCharacterPlacementW
+0162 stub GetClipBox
+0163 stub GetClipRgn
+0164 stub GetColorAdjustment
+0165 stub GetColorSpace
+0166 stub GetCurrentObject
+0167 stub GetCurrentPositionEx
+0168 stub GetDCOrgEx
+0169 stub GetDIBColorTable
+0170 stub GetDIBits
+0171 stub GetDeviceCaps
+0172 stub GetDeviceGammaRamp
+0173 stub GetETM
+0174 stub GetEnhMetaFileA
+0175 stub GetEnhMetaFileBits
+0176 stub GetEnhMetaFileDescriptionA
+0177 stub GetEnhMetaFileDescriptionW
+0178 stub GetEnhMetaFileHeader
+0179 stub GetEnhMetaFilePaletteEntries
+0180 stub GetEnhMetaFileW
+0181 stub GetFontData
+0182 stub GetFontLanguageInfo
+0183 stub GetFontResourceInfo
+0184 stub GetFontResourceInfoW
+0185 stub GetGlyphOutline
+0186 stub GetGlyphOutlineA
+0187 stub GetGlyphOutlineW
+0188 stub GetGraphicsMode
+0189 stub GetICMProfileA
+0190 stub GetICMProfileW
+0191 stub GetKerningPairs
+0192 stub GetKerningPairsA
+0193 stub GetKerningPairsW
+0194 stub GetLogColorSpaceA
+0195 stub GetLogColorSpaceW
+0196 stub GetMapMode
+0197 stub GetMetaFileA
+0198 stub GetMetaFileBitsEx
+0199 stub GetMetaFileW
+0200 stub GetMetaRgn
+0201 stub GetMiterLimit
+0202 stub GetNearestColor
+0203 stub GetNearestPaletteIndex
+0204 stub GetObjectA
+0205 stub GetObjectType
+0206 stub GetObjectW
+0207 stub GetOutlineTextMetricsA
+0208 stub GetOutlineTextMetricsW
+0209 stub GetPaletteEntries
+0210 stub GetPath
+0211 stub GetPixel
+0212 stub GetPixelFormat
+0213 stub GetPolyFillMode
+0214 stub GetROP2
+0215 stub GetRandomRgn
+0216 stub GetRasterizerCaps
+0217 stub GetRegionData
+0218 stub GetRelAbs
+0219 stub GetRgnBox
+0220 stub GetStockObject
+0221 stub GetStretchBltMode
+0222 stub GetSystemPaletteEntries
+0223 stub GetSystemPaletteUse
+0224 stub GetTextAlign
+0225 stub GetTextCharacterExtra
+0226 stub GetTextCharset
+0227 stub GetTextColor
+0228 stub GetTextExtentExPointA
+0229 stub GetTextExtentExPointW
+0230 stub GetTextExtentPoint32A
+0231 stub GetTextExtentPoint32W
+0232 stub GetTextExtentPointA
+0233 stub GetTextExtentPointW
+0234 stub GetTextFaceA
+0235 stub GetTextFaceW
+0236 stub GetTextMetricsA
+0237 stub GetTextMetricsW
+0238 stub GetTransform
+0239 stub GetViewportExtEx
+0240 stub GetViewportOrgEx
+0241 stub GetWinMetaFileBits
+0242 stub GetWindowExtEx
+0243 stub GetWindowOrgEx
+0244 stub GetWorldTransform
+0245 stub IntersectClipRect
+0246 stub InvertRgn
+0247 stub LPtoDP
+0248 stub LineDDA
+0249 stub LineTo
+0250 stub LoadImageColorMatcherA
+0251 stub LoadImageColorMatcherW
+0252 stub MaskBlt
+0253 stub ModifyWorldTransform
+0254 stub MoveToEx
+0255 stub OffsetClipRgn
+0256 stub OffsetRgn
+0257 stub OffsetViewportOrgEx
+0258 stub OffsetWindowOrgEx
+0259 stub PaintRgn
+0260 stub PatBlt
+0261 stub PathToRegion
+0262 stub Pie
+0263 stub PlayEnhMetaFile
+0264 stub PlayEnhMetaFileRecord
+0265 stub PlayMetaFile
+0266 stub PlayMetaFileRecord
+0267 stub PlgBlt
+0268 stub PolyBezier
+0269 stub PolyBezierTo
+0270 stub PolyDraw
+0271 stub PolyPolygon
+0272 stub PolyPolyline
+0273 stub PolyTextOutA
+0274 stub PolyTextOutW
+0275 stub Polygon
+0276 stub Polyline
+0277 stub PolylineTo
+0278 stub PtInRegion
+0279 stub PtVisible
+0280 stub RealizePalette
+0281 stub RectInRegion
+0282 stub RectVisible
+0283 stub Rectangle
+0284 stub RemoveFontResourceA
+0285 stub RemoveFontResourceTracking
+0286 stub RemoveFontResourceW
+0287 stub ResetDCA
+0288 stub ResetDCW
+0289 stub ResizePalette
+0290 stub RestoreDC
+0291 stub RoundRect
+0292 stub SaveDC
+0293 stub ScaleViewportExtEx
+0294 stub ScaleWindowExtEx
+0295 stub SelectBrushLocal
+0296 stub SelectClipPath
+0297 stub SelectClipRgn
+0298 stub SelectFontLocal
+0299 stub SelectObject
+0300 stub SelectPalette
+0301 stub SetAbortProc
+0302 stub SetArcDirection
+0303 stub SetBitmapBits
+0304 stub SetBitmapDimensionEx
+0305 stub SetBkColor
+0306 stub SetBkMode
+0307 stub SetBoundsRect
+0308 stub SetBrushOrgEx
+0309 stub SetColorAdjustment
+0310 stub SetColorSpace
+0311 stub SetDIBColorTable
+0312 stub SetDIBits
+0313 stub SetDIBitsToDevice
+0314 stub SetDeviceGammaRamp
+0315 stub SetEnhMetaFileBits
+0316 stub SetFontEnumeration
+0317 stub SetGraphicsMode
+0318 stub SetICMMode
+0319 stub SetICMProfileA
+0320 stub SetICMProfileW
+0321 stub SetMapMode
+0322 stub SetMapperFlags
+0323 stub SetMetaFileBitsEx
+0324 stub SetMetaRgn
+0325 stub SetMiterLimit
+0326 stub SetPaletteEntries
+0327 stub SetPixel
+0328 stub SetPixelFormat
+0329 stub SetPixelV
+0330 stub SetPolyFillMode
+0331 stub SetROP2
+0332 stub SetRectRgn
+0333 stub SetRelAbs
+0334 stub SetStretchBltMode
+0335 stub SetSystemPaletteUse
+0336 stub SetTextAlign
+0337 stub SetTextCharacterExtra
+0338 stub SetTextColor
+0339 stub SetTextJustification
+0340 stub SetViewportExtEx
+0341 stub SetViewportOrgEx
+0342 stub SetVirtualResolution
+0343 stub SetWinMetaFileBits
+0344 stub SetWindowExtEx
+0345 stub SetWindowOrgEx
+0346 stub SetWorldTransform
+0347 stub StartDocA
+0348 stub StartDocW
+0349 stub StartPage
+0350 stub StretchBlt
+0351 stub StretchDIBits
+0352 stub StrokeAndFillPath
+0353 stub StrokePath
+0354 stub SwapBuffers
+0355 stub TextOutA
+0356 stub TextOutW
+0357 stub UnloadNetworkFonts
+0358 stub UnrealizeObject
+0359 stub UpdateColors
+0360 stub WidenPath
+0361 stub pstackConnect
+
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index 89081f4..7ca626c 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -41,7 +41,7 @@
 41  return EnableDos 0 0
 42  return DisableDos 0 0
 45  pascal16 LoadModule(ptr ptr) LoadModule
-46  pascal16 FreeModule(word) FreeLibrary
+46  pascal16 FreeModule(word) FreeModule
 47  pascal16 GetModuleHandle(ptr) GetModuleHandle
 48  pascal16 GetModuleUsage(word) GetModuleUsage
 49  pascal16 GetModuleFileName(word ptr s_word) GetModuleFileName
@@ -82,11 +82,11 @@
 84  pascal _llseek(word long word) _llseek
 85  pascal16 _lopen(ptr word) _lopen
 86  pascal16 _lwrite(word ptr word) _lwrite
-#87 RESERVED5
+87 	stub RESERVED5
 88  pascal lstrcpy(segptr segptr) lstrcpy
 89  pascal lstrcat(segptr segptr) lstrcat
 90  pascal16 lstrlen(ptr) lstrlen
-91  register InitTask() KERNEL_InitTask
+91  register InitTask() InitTask
 92  pascal16 GetTempDrive(byte) GetTempDrive
 93  pascal16 GetCodeHandle(segptr) GetCodeHandle
 94  stub DefineHandleTable
@@ -161,29 +161,29 @@
 170 pascal16 AllocCStoDSAlias(word) AllocCStoDSAlias
 171 pascal16 AllocDStoCSAlias(word) AllocDStoCSAlias
 172 pascal16 AllocAlias(word) AllocCStoDSAlias
-#173 __ROMBIOS
-#174 __A000H
+173 equate __ROMBIOS 0
+174 equate __A000H 0
 175 pascal16 AllocSelector(word) AllocSelector
 176 pascal16 FreeSelector(word) FreeSelector
 177 pascal16 PrestoChangoSelector(word word) PrestoChangoSelector
 178 equate __WINFLAGS 0x413
-#179 __D000H
+179 equate __D000H 0
 180 pascal16 LongPtrAdd(long long) LongPtrAdd
-#181 __B000H
-#182 __B800H
-#183 __0000H
+181 equate __B000H 0
+182 equate __B800H 0
+183 equate __0000H 0
 184 pascal GlobalDOSAlloc(long) GlobalDOSAlloc
 185 pascal16 GlobalDOSFree(word) GlobalDOSFree
 186 pascal GetSelectorBase(word) GetSelectorBase
 187 pascal16 SetSelectorBase(word long) SetSelectorBase
 188 pascal GetSelectorLimit(word) GetSelectorLimit
 189 pascal16 SetSelectorLimit(word long) SetSelectorLimit
-#190 __E000H
+190 equate __E000H 0
 191 pascal16 GlobalPageLock(word) GlobalPageLock
 192 pascal16 GlobalPageUnlock(word) GlobalPageUnlock
-#193 __0040H
-#194 __F000H
-#195 __C000H
+193 equate __0040H 0
+194 equate __F000H 0
+195 equate __C000H 0
 196 pascal16 SelectorAccessRights(word word word) SelectorAccessRights
 197 pascal16 GlobalFix(word) GlobalFix
 198 pascal16 GlobalUnfix(word) GlobalUnfix
diff --git a/if1632/kernel32.spec b/if1632/kernel32.spec
new file mode 100644
index 0000000..9f0ceee
--- /dev/null
+++ b/if1632/kernel32.spec
@@ -0,0 +1,620 @@
+name	kernel32
+base	1
+
+0000 stub AddAtomA
+0001 stub AddAtomW
+0002 stub AddConsoleAliasA
+0003 stub AddConsoleAliasW
+0004 stub AllocConsole
+0005 stub AreFileApisANSI
+0006 stub BackupRead
+0007 stub BackupSeek
+0008 stub BackupWrite
+0009 stub BaseAttachCompleteThunk
+0010 stub BasepDebugDump
+0011 stub Beep
+0012 stub BeginUpdateResourceA
+0013 stub BeginUpdateResourceW
+0014 stub BuildCommDCBA
+0015 stub BuildCommDCBAndTimeoutsA
+0016 stub BuildCommDCBAndTimeoutsW
+0017 stub BuildCommDCBW
+0018 stub CallNamedPipeA
+0019 stub CallNamedPipeW
+0020 stub ClearCommBreak
+0021 stub ClearCommError
+0022 stub CloseConsoleHandle
+0023 stub CloseHandle
+0024 stub CloseProfileUserMapping
+0025 stub CmdBatNotification
+0026 stub CommConfigDialogA
+0027 stub CommConfigDialogW
+0028 stub CompareFileTime
+0029 stub CompareStringA
+0030 stub CompareStringW
+0031 stub ConnectNamedPipe
+0032 stub ConsoleMenuControl
+0033 stub ConsoleSubst
+0034 stub ContinueDebugEvent
+0035 stub ConvertDefaultLocale
+0036 stub CopyFileA
+0037 stub CopyFileW
+0038 stub CreateConsoleScreenBuffer
+0039 stub CreateDirectoryA
+0040 stub CreateDirectoryExA
+0041 stub CreateDirectoryExW
+0042 stub CreateDirectoryW
+0043 stub CreateEventA
+0044 stub CreateEventW
+0045 stub CreateFileA
+0046 stub CreateFileMappingA
+0047 stub CreateFileMappingW
+0048 stub CreateFileW
+0049 stub CreateIoCompletionPort
+0050 stub CreateMailslotA
+0051 stub CreateMailslotW
+0052 stub CreateMutexA
+0053 stub CreateMutexW
+0054 stub CreateNamedPipeA
+0055 stub CreateNamedPipeW
+0056 stub CreatePipe
+0057 stub CreateProcessA
+0058 stub CreateProcessW
+0059 stub CreateRemoteThread
+0060 stub CreateSemaphoreA
+0061 stub CreateSemaphoreW
+0062 stub CreateTapePartition
+0063 stub CreateThread
+0064 stub CreateVirtualBuffer
+0065 stub DebugActiveProcess
+0066 stub DebugBreak
+0067 stub DefineDosDeviceA
+0068 stub DefineDosDeviceW
+0069 stub DeleteAtom
+0070 stub DeleteCriticalSection
+0071 stub DeleteFileA
+0072 stub DeleteFileW
+0073 stub DeviceIoControl
+0074 stub DisableThreadLibraryCalls
+0075 stub DisconnectNamedPipe
+0076 stub DosDateTimeToFileTime
+0077 stub DuplicateConsoleHandle
+0078 stub DuplicateHandle
+0079 stub EndUpdateResourceA
+0080 stub EndUpdateResourceW
+0081 stub EnterCriticalSection
+0082 stub EnumCalendarInfoA
+0083 stub EnumCalendarInfoW
+0084 stub EnumDateFormatsA
+0085 stub EnumDateFormatsW
+0086 stub EnumResourceLanguagesA
+0087 stub EnumResourceLanguagesW
+0088 stub EnumResourceNamesA
+0089 stub EnumResourceNamesW
+0090 stub EnumResourceTypesA
+0091 stub EnumResourceTypesW
+0092 stub EnumSystemCodePagesA
+0093 stub EnumSystemCodePagesW
+0094 stub EnumSystemLocalesA
+0095 stub EnumSystemLocalesW
+0096 stub EnumTimeFormatsA
+0097 stub EnumTimeFormatsW
+0098 stub EraseTape
+0099 stub EscapeCommFunction
+0100 stub ExitProcess
+0101 stub ExitThread
+0102 stub ExitVDM
+0103 stub ExpandEnvironmentStringsA
+0104 stub ExpandEnvironmentStringsW
+0105 stub ExpungeConsoleCommandHistoryA
+0106 stub ExpungeConsoleCommandHistoryW
+0107 stub ExtendVirtualBuffer
+0108 stub FatalAppExitA
+0109 stub FatalAppExitW
+0110 stub FatalExit
+0111 stub FileTimeToDosDateTime
+0112 stub FileTimeToLocalFileTime
+0113 stub FileTimeToSystemTime
+0114 stub FillConsoleOutputAttribute
+0115 stub FillConsoleOutputCharacterA
+0116 stub FillConsoleOutputCharacterW
+0117 stub FindAtomA
+0118 stub FindAtomW
+0119 stub FindClose
+0120 stub FindCloseChangeNotification
+0121 stub FindFirstChangeNotificationA
+0122 stub FindFirstChangeNotificationW
+0123 stub FindFirstFileA
+0124 stub FindFirstFileW
+0125 stub FindNextChangeNotification
+0126 stub FindNextFileA
+0127 stub FindNextFileW
+0128 stub FindResourceA
+0129 stub FindResourceExA
+0130 stub FindResourceExW
+0131 stub FindResourceW
+0132 stub FlushConsoleInputBuffer
+0133 stub FlushFileBuffers
+0134 stub FlushInstructionCache
+0135 stub FlushViewOfFile
+0136 stub FoldStringA
+0137 stub FoldStringW
+0138 stub FormatMessageA
+0139 stub FormatMessageW
+0140 stub FreeConsole
+0141 stub FreeEnvironmentStringsA
+0142 stub FreeEnvironmentStringsW
+0143 stub FreeLibrary
+0144 stub FreeLibraryAndExitThread
+0145 stub FreeResource
+0146 stub FreeVirtualBuffer
+0147 stub GenerateConsoleCtrlEvent
+0148 stub GetACP
+0149 stub GetAtomNameA
+0150 stub GetAtomNameW
+0151 stub GetBinaryType
+0152 stub GetBinaryTypeA
+0153 stub GetBinaryTypeW
+0154 stub GetCPInfo
+0155 stub GetCommConfig
+0156 stub GetCommMask
+0157 stub GetCommModemStatus
+0158 stub GetCommProperties
+0159 stub GetCommState
+0160 stub GetCommTimeouts
+0161	stdcall GetCommandLineA()	GetCommandLineA
+0162 stub GetCommandLineW
+0163 stub GetCompressedFileSizeA
+0164 stub GetCompressedFileSizeW
+0165 stub GetComputerNameA
+0166 stub GetComputerNameW
+0167 stub GetConsoleAliasA
+0168 stub GetConsoleAliasExesA
+0169 stub GetConsoleAliasExesLengthA
+0170 stub GetConsoleAliasExesLengthW
+0171 stub GetConsoleAliasExesW
+0172 stub GetConsoleAliasW
+0173 stub GetConsoleAliasesA
+0174 stub GetConsoleAliasesLengthA
+0175 stub GetConsoleAliasesLengthW
+0176 stub GetConsoleAliasesW
+0177 stub GetConsoleCP
+0178 stub GetConsoleCommandHistoryA
+0179 stub GetConsoleCommandHistoryLengthA
+0180 stub GetConsoleCommandHistoryLengthW
+0181 stub GetConsoleCommandHistoryW
+0182 stub GetConsoleCursorInfo
+0183 stub GetConsoleDisplayMode
+0184 stub GetConsoleFontInfo
+0185 stub GetConsoleFontSize
+0186 stub GetConsoleHardwareState
+0187 stub GetConsoleInputWaitHandle
+0188 stub GetConsoleMode
+0189 stub GetConsoleOutputCP
+0190 stub GetConsoleScreenBufferInfo
+0191 stub GetConsoleTitleA
+0192 stub GetConsoleTitleW
+0193 stub GetCurrencyFormatA
+0194 stub GetCurrencyFormatW
+0195 stub GetCurrentConsoleFont
+0196 stub GetCurrentDirectoryA
+0197 stub GetCurrentDirectoryW
+0198 stub GetCurrentProcess
+0199 stub GetCurrentProcessId
+0200 stub GetCurrentThread
+0201	stdcall GetCurrentThreadId()	GetCurrentThreadId
+0202 stub GetDateFormatA
+0203 stub GetDateFormatW
+0204 stub GetDefaultCommConfigA
+0205 stub GetDefaultCommConfigW
+0206 stub GetDiskFreeSpaceA
+0207 stub GetDiskFreeSpaceW
+0208 stub GetDriveTypeA
+0209 stub GetDriveTypeW
+0210	stdcall GetEnvironmentStrings()	GetEnvironmentStrings
+0211 stub GetEnvironmentStringsA
+0212 stub GetEnvironmentStringsW
+0213 stub GetEnvironmentVariableA
+0214 stub GetEnvironmentVariableW
+0215 stub GetExitCodeProcess
+0216 stub GetExitCodeThread
+0217 stub GetFileAttributesA
+0218 stub GetFileAttributesW
+0219 stub GetFileInformationByHandle
+0220 stub GetFileSize
+0221 stub GetFileTime
+0222 stub GetFileType
+0223 stub GetFullPathNameA
+0224 stub GetFullPathNameW
+0225 stub GetHandleInformation
+0226 stub GetLargestConsoleWindowSize
+0227 stub GetLastError
+0228 stub GetLocalTime
+0229 stub GetLocaleInfoA
+0230 stub GetLocaleInfoW
+0231 stub GetLogicalDriveStringsA
+0232 stub GetLogicalDriveStringsW
+0233 stub GetLogicalDrives
+0234 stub GetMailslotInfo
+0235	return GetModuleFileNameA 12 0
+0236 stub GetModuleFileNameW
+0237	stdcall GetModuleHandleA(ptr)	GetModuleHandle
+0238 stub GetModuleHandleW
+0239 stub GetNamedPipeHandleStateA
+0240 stub GetNamedPipeHandleStateW
+0241 stub GetNamedPipeInfo
+0242 stub GetNextVDMCommand
+0243 stub GetNumberFormatA
+0244 stub GetNumberFormatW
+0245 stub GetNumberOfConsoleFonts
+0246 stub GetNumberOfConsoleInputEvents
+0247 stub GetNumberOfConsoleMouseButtons
+0248 stub GetOEMCP
+0249 stub GetOverlappedResult
+0250 stub GetPriorityClass
+0251 stub GetPrivateProfileIntA
+0252 stub GetPrivateProfileIntW
+0253 stub GetPrivateProfileSectionA
+0254 stub GetPrivateProfileSectionW
+0255 stub GetPrivateProfileStringA
+0256 stub GetPrivateProfileStringW
+0257 stub GetProcAddress
+0258 stub GetProcessAffinityMask
+0259	return GetProcessHeap 0 0
+0260 stub GetProcessHeaps
+0261 stub GetProcessShutdownParameters
+0262 stub GetProcessTimes
+0263 stub GetProcessWorkingSetSize
+0264 stub GetProfileIntA
+0265 stub GetProfileIntW
+0266 stub GetProfileSectionA
+0267 stub GetProfileSectionW
+0268 stub GetProfileStringA
+0269 stub GetProfileStringW
+0270 stub GetQueuedCompletionStatus
+0271 stub GetShortPathNameA
+0272 stub GetShortPathNameW
+0273	return GetStartupInfoA 4 0
+0274 stub GetStartupInfoW
+0275	stdcall GetStdHandle(long)	GetStdHandle
+0276 stub GetStringTypeA
+0277 stub GetStringTypeExA
+0278 stub GetStringTypeExW
+0279 stub GetStringTypeW
+0280 stub GetSystemDefaultLCID
+0281 stub GetSystemDefaultLangID
+0282 stub GetSystemDirectoryA
+0283 stub GetSystemDirectoryW
+0284 stub GetSystemInfo
+0285 stub GetSystemTime
+0286 stub GetSystemTimeAdjustment
+0287 stub GetTapeParameters
+0288 stub GetTapePosition
+0289 stub GetTapeStatus
+0290 stub GetTempFileNameA
+0291 stub GetTempFileNameW
+0292 stub GetTempPathA
+0293 stub GetTempPathW
+0294	stdcall GetThreadContext(long ptr)	GetThreadContext
+0295 stub GetThreadLocale
+0296 stub GetThreadPriority
+0297 stub GetThreadSelectorEntry
+0298 stub GetThreadTimes
+0299 stub GetTickCount
+0300 stub GetTimeFormatA
+0301 stub GetTimeFormatW
+0302 stub GetTimeZoneInformation
+0303 stub GetUserDefaultLCID
+0304 stub GetUserDefaultLangID
+0305 stub GetVDMCurrentDirectories
+#Use Win 3.1 GetVersion for now
+0306	stdcall GetVersion()	GetVersion
+0307 stub GetVersionExA
+0308 stub GetVersionExW
+0309 stub GetVolumeInformationA
+0310 stub GetVolumeInformationW
+0311 stub GetWindowsDirectoryA
+0312 stub GetWindowsDirectoryW
+0313 stub GlobalAddAtomA
+0314 stub GlobalAddAtomW
+0315	stdcall GlobalAlloc(long long)	GlobalAlloc32
+0316 stub GlobalCompact
+0317 stub GlobalDeleteAtom
+0318 stub GlobalFindAtomA
+0319 stub GlobalFindAtomW
+0320 stub GlobalFix
+0321 stub GlobalFlags
+0322 stub GlobalFree
+0323 stub GlobalGetAtomNameA
+0324 stub GlobalGetAtomNameW
+0325 stub GlobalHandle
+0326 stub GlobalLock
+0327 stub GlobalMemoryStatus
+0328 stub GlobalReAlloc
+0329 stub GlobalSize
+0330 stub GlobalUnWire
+0331 stub GlobalUnfix
+0332 stub GlobalUnlock
+0333 stub GlobalWire
+0334 stub HeapAlloc
+0335 stub HeapCompact
+0336 stub HeapCreate
+0337 stub HeapDestroy
+0338 stub HeapFree
+0339 stub HeapLock
+0340 stub HeapReAlloc
+0341 stub HeapSize
+0342 stub HeapUnlock
+0343 stub HeapValidate
+0344 stub HeapWalk
+0345 stub InitAtomTable
+0346 stub InitializeCriticalSection
+0347 stub InterlockedDecrement
+0348 stub InterlockedExchange
+0349 stub InterlockedIncrement
+0350 stub InvalidateConsoleDIBits
+0351 stub IsBadCodePtr
+0352 stub IsBadHugeReadPtr
+0353 stub IsBadHugeWritePtr
+0354 stub IsBadReadPtr
+0355 stub IsBadStringPtrA
+0356 stub IsBadStringPtrW
+0357 stub IsBadWritePtr
+0358 stub IsDBCSLeadByte
+0359 stub IsDBCSLeadByteEx
+0360 stub IsValidCodePage
+0361 stub IsValidLocale
+0362 stub LCMapStringA
+0363 stub LCMapStringW
+0364 stub LeaveCriticalSection
+0365 stub LoadLibraryA
+0366 stub LoadLibraryExA
+0367 stub LoadLibraryExW
+0368 stub LoadLibraryW
+0369 stub LoadModule
+0370 stub LoadResource
+0371	stdcall LocalAlloc(long long)	GlobalAlloc32
+0372 stub LocalCompact
+0373 stub LocalFileTimeToFileTime
+0374 stub LocalFlags
+0375 stub LocalFree
+0376 stub LocalHandle
+0377 stub LocalLock
+0378 stub LocalReAlloc
+0379 stub LocalShrink
+0380 stub LocalSize
+0381 stub LocalUnlock
+0382 stub LockFile
+0383 stub LockFileEx
+0384 stub LockResource
+0385 stub MapViewOfFile
+0386 stub MapViewOfFileEx
+0387 stub MoveFileA
+0388 stub MoveFileExA
+0389 stub MoveFileExW
+0390 stub MoveFileW
+0391 stub MulDiv
+0392 stub MultiByteToWideChar
+0393 stub OpenConsoleW
+0394 stub OpenEventA
+0395 stub OpenEventW
+0396 stub OpenFile
+0397 stub OpenFileMappingA
+0398 stub OpenFileMappingW
+0399 stub OpenMutexA
+0400 stub OpenMutexW
+0401 stub OpenProcess
+0402 stub OpenProfileUserMapping
+0403 stub OpenSemaphoreA
+0404 stub OpenSemaphoreW
+0405 stub OutputDebugStringA
+0406 stub OutputDebugStringW
+0407 stub PeekConsoleInputA
+0408 stub PeekConsoleInputW
+0409 stub PeekNamedPipe
+0410 stub PrepareTape
+0411 stub PulseEvent
+0412 stub PurgeComm
+0413 stub QueryDosDeviceA
+0414 stub QueryDosDeviceW
+0415 stub QueryPerformanceCounter
+0416 stub QueryPerformanceFrequency
+0417 stub QueryWin31IniFilesMappedToRegistry
+0418 stub RaiseException
+0419 stub ReadConsoleA
+0420 stub ReadConsoleInputA
+0421 stub ReadConsoleInputW
+0422 stub ReadConsoleOutputA
+0423 stub ReadConsoleOutputAttribute
+0424 stub ReadConsoleOutputCharacterA
+0425 stub ReadConsoleOutputCharacterW
+0426 stub ReadConsoleOutputW
+0427 stub ReadConsoleW
+0428 stub ReadFile
+0429 stub ReadFileEx
+0430 stub ReadProcessMemory
+0431 stub RegisterConsoleVDM
+0432 stub RegisterWaitForInputIdle
+0433 stub RegisterWowBaseHandlers
+0434 stub RegisterWowExec
+0435 stub ReleaseMutex
+0436 stub ReleaseSemaphore
+0437 stub RemoveDirectoryA
+0438 stub RemoveDirectoryW
+0439 stub ResetEvent
+0440 stub ResumeThread
+0441 stub RtlFillMemory
+0442 stub RtlMoveMemory
+0443 stub RtlUnwind
+0444 stub RtlZeroMemory
+0445 stub ScrollConsoleScreenBufferA
+0446 stub ScrollConsoleScreenBufferW
+0447 stub SearchPathA
+0448 stub SearchPathW
+0449 stub SetCommBreak
+0450 stub SetCommConfig
+0451 stub SetCommMask
+0452 stub SetCommState
+0453 stub SetCommTimeouts
+0454 stub SetComputerNameA
+0455 stub SetComputerNameW
+0456 stub SetConsoleActiveScreenBuffer
+0457 stub SetConsoleCP
+0458 stub SetConsoleCommandHistoryMode
+0459 stub SetConsoleCtrlHandler
+0460 stub SetConsoleCursor
+0461 stub SetConsoleCursorInfo
+0462 stub SetConsoleCursorPosition
+0463 stub SetConsoleDisplayMode
+0464 stub SetConsoleFont
+0465 stub SetConsoleHardwareState
+0466 stub SetConsoleKeyShortcuts
+0467 stub SetConsoleMaximumWindowSize
+0468 stub SetConsoleMenuClose
+0469 stub SetConsoleMode
+0470 stub SetConsoleNumberOfCommandsA
+0471 stub SetConsoleNumberOfCommandsW
+0472 stub SetConsoleOutputCP
+0473 stub SetConsolePalette
+0474 stub SetConsoleScreenBufferSize
+0475 stub SetConsoleTextAttribute
+0476 stub SetConsoleTitleA
+0477 stub SetConsoleTitleW
+0478 stub SetConsoleWindowInfo
+0479 stub SetCurrentDirectoryA
+0480 stub SetCurrentDirectoryW
+0481 stub SetDefaultCommConfigA
+0482 stub SetDefaultCommConfigW
+0483 stub SetEndOfFile
+0484 stub SetEnvironmentVariableA
+0485 stub SetEnvironmentVariableW
+0486 stub SetErrorMode
+0487 stub SetEvent
+0488 stub SetFileApisToANSI
+0489 stub SetFileApisToOEM
+0490 stub SetFileAttributesA
+0491 stub SetFileAttributesW
+0492 stub SetFilePointer
+0493 stub SetFileTime
+0494 stub SetHandleCount
+0495 stub SetHandleInformation
+0496 stub SetLastConsoleEventActive
+0497 stub SetLastError
+0498 stub SetLocalTime
+0499 stub SetLocaleInfoA
+0500 stub SetLocaleInfoW
+0501 stub SetMailslotInfo
+0502 stub SetNamedPipeHandleState
+0503 stub SetPriorityClass
+0504 stub SetProcessShutdownParameters
+0505 stub SetProcessWorkingSetSize
+0506 stub SetStdHandle
+0507 stub SetSystemTime
+0508 stub SetSystemTimeAdjustment
+0509 stub SetTapeParameters
+0510 stub SetTapePosition
+0511 stub SetThreadAffinityMask
+0512 stub SetThreadContext
+0513 stub SetThreadLocale
+0514 stub SetThreadPriority
+0515 stub SetTimeZoneInformation
+0516 stub SetUnhandledExceptionFilter
+0517 stub SetVDMCurrentDirectories
+0518 stub SetVolumeLabelA
+0519 stub SetVolumeLabelW
+0520 stub SetupComm
+0521 stub ShowConsoleCursor
+0522 stub SizeofResource
+0523 stub Sleep
+0524 stub SleepEx
+0525 stub SuspendThread
+0526 stub SystemTimeToFileTime
+0527 stub SystemTimeToTzSpecificLocalTime
+0528 stub TerminateProcess
+0529 stub TerminateThread
+0530 stub TlsAlloc
+0531 stub TlsFree
+0532 stub TlsGetValue
+0533 stub TlsSetValue
+0534 stub TransactNamedPipe
+0535 stub TransmitCommChar
+0536 stub TrimVirtualBuffer
+0537 stub UnhandledExceptionFilter
+0538 stub UnlockFile
+0539 stub UnlockFileEx
+0540 stub UnmapViewOfFile
+0541 stub UpdateResourceA
+0542 stub UpdateResourceW
+0543 stub VDMConsoleOperation
+0544 stub VDMOperationStarted
+0545 stub VerLanguageNameA
+0546 stub VerLanguageNameW
+0547 stub VerifyConsoleIoHandle
+0548 stub VirtualAlloc
+0549 stub VirtualBufferExceptionHandler
+0550 stub VirtualFree
+0551 stub VirtualLock
+0552 stub VirtualProtect
+0553 stub VirtualProtectEx
+0554 stub VirtualQuery
+0555 stub VirtualQueryEx
+0556 stub VirtualUnlock
+0557 stub WaitCommEvent
+0558 stub WaitForDebugEvent
+0559 stub WaitForMultipleObjects
+0560 stub WaitForMultipleObjectsEx
+0561 stub WaitForSingleObject
+0562 stub WaitForSingleObjectEx
+0563 stub WaitNamedPipeA
+0564 stub WaitNamedPipeW
+0565 stub WideCharToMultiByte
+0566 stub WinExec
+0567 stub WriteConsoleA
+0568 stub WriteConsoleInputA
+0569 stub WriteConsoleInputVDMA
+0570 stub WriteConsoleInputVDMW
+0571 stub WriteConsoleInputW
+0572 stub WriteConsoleOutputA
+0573 stub WriteConsoleOutputAttribute
+0574 stub WriteConsoleOutputCharacterA
+0575 stub WriteConsoleOutputCharacterW
+0576 stub WriteConsoleOutputW
+0577 stub WriteConsoleW
+0578 stub WriteFile
+0579 stub WriteFileEx
+0580 stub WritePrivateProfileSectionA
+0581 stub WritePrivateProfileSectionW
+0582 stub WritePrivateProfileStringA
+0583 stub WritePrivateProfileStringW
+0584 stub WriteProcessMemory
+0585 stub WriteProfileSectionA
+0586 stub WriteProfileSectionW
+0587 stub WriteProfileStringA
+0588 stub WriteProfileStringW
+0589 stub WriteTapemark
+0590 stub _hread
+0591 stub _hwrite
+0592 stub _lclose
+0593 stub _lcreat
+0594 stub _llseek
+0595 stub _lopen
+0596 stub _lread
+0597 stub _lwrite
+0598 stub lstrcat
+0599 stub lstrcatA
+0600 stub lstrcatW
+0601 stub lstrcmp
+0602 stub lstrcmpA
+0603 stub lstrcmpW
+0604 stub lstrcmpi
+0605 stub lstrcmpiA
+0606 stub lstrcmpiW
+0607 stub lstrcpy
+0608 stub lstrcpyA
+0609 stub lstrcpyW
+0610 stub lstrcpyn
+0611 stub lstrcpynA
+0612 stub lstrcpynW
+0613 stub lstrlen
+0614 stub lstrlenA
+0615 stub lstrlenW
diff --git a/if1632/mmsystem.spec b/if1632/mmsystem.spec
index 8e03c21..d4e0b28 100644
--- a/if1632/mmsystem.spec
+++ b/if1632/mmsystem.spec
@@ -1,7 +1,7 @@
 name	mmsystem
 id	10
 
-1      pascal  MMSYSTEM_WEP(word word word ptr) MMSYSTEM_WEP
+#1      pascal  MMSYSTEM_WEP(word word word ptr) MMSYSTEM_WEP
 2      pascal  SNDPLAYSOUND(ptr word) sndPlaySound
 5      pascal  MMSYSTEMGETVERSION() mmsystemGetVersion
 6      pascal  DriverProc(long word word long long) DriverProc
@@ -20,51 +20,51 @@
 107    pascal  JOYSETTHRESHOLD(word word) JoySetThreshold
 109    pascal  JOYSETCALIBRATION(word) JoySetCalibration
 201    pascal  MIDIOUTGETNUMDEVS() midiOutGetNumDevs
-202    pascal  MIDIOUTGETDEVCAPS(word ptr word) midiOutGetDevCaps
+202    pascal  MIDIOUTGETDEVCAPS(word segptr word) midiOutGetDevCaps
 203    pascal  MIDIOUTGETERRORTEXT(word ptr word) midiOutGetErrorText
 204    pascal  MIDIOUTOPEN(ptr word ptr long long long) midiOutOpen
 205    pascal  MIDIOUTCLOSE(word) midiOutClose
-206    pascal  MIDIOUTPREPAREHEADER(word ptr word) midiOutPrepareHeader
-207    pascal  MIDIOUTUNPREPAREHEADER(word ptr word) midiOutUnprepareHeader
+206    pascal  MIDIOUTPREPAREHEADER(word segptr word) midiOutPrepareHeader
+207    pascal  MIDIOUTUNPREPAREHEADER(word segptr word) midiOutUnprepareHeader
 208    pascal  MIDIOUTSHORTMSG(word long) midiOutShortMsg
 209    pascal  MIDIOUTLONGMSG(word ptr word) midiOutLongMsg
 210    pascal  MIDIOUTRESET(word) midiOutReset
-211    pascal  MIDIOUTGETVOLUME(word ptr) midiOutGetVolume
+211    pascal  MIDIOUTGETVOLUME(word segptr) midiOutGetVolume
 212    pascal  MIDIOUTSETVOLUME(word long) midiOutSetVolume
 215    pascal  MIDIOUTGETID(word ptr) midiOutGetID
 216    pascal  MIDIOUTMESSAGE(word word long long) midiOutMessage
 301    pascal  MIDIINGETNUMDEVS() midiInGetNumDevs
-302    pascal  MIDIINGETDEVCAPS(word ptr word) midiInGetDevCaps
+302    pascal  MIDIINGETDEVCAPS(word segptr word) midiInGetDevCaps
 303    pascal  MIDIINGETERRORTEXT(word ptr word) midiInGetErrorText
 304    pascal  MIDIINOPEN(ptr word ptr long long long) midiInOpen
 305    pascal  MIDIINCLOSE(word) midiInClose
-306    pascal  MIDIINPREPAREHEADER(word ptr word) midiInPrepareHeader
-307    pascal  MIDIINUNPREPAREHEADER(word ptr word) midiInUnprepareHeader
+306    pascal  MIDIINPREPAREHEADER(word segptr word) midiInPrepareHeader
+307    pascal  MIDIINUNPREPAREHEADER(word segptr word) midiInUnprepareHeader
 309    pascal  MIDIINSTART(word) midiInStart
 310    pascal  MIDIINSTOP(word) midiInStop
 311    pascal  MIDIINRESET(word) midiInReset
 312    pascal  MIDIINGETID(word ptr) midiInGetID
 313    pascal  MIDIINMESSAGE(word word long long) midiInMessage
 350    pascal  AUXGETNUMDEVS() auxGetNumDevs
-351    pascal  AUXGETDEVCAPS(word ptr word) auxGetDevCaps
-352    pascal  AUXGETVOLUME(word ptr) auxGetVolume
+351    pascal  AUXGETDEVCAPS(word segptr word) auxGetDevCaps
+352    pascal  AUXGETVOLUME(word segptr) auxGetVolume
 353    pascal  AUXSETVOLUME(word long) auxSetVolume
 354    pascal  AUXOUTMESSAGE(word word long long) auxOutMessage
 401    pascal  WAVEOUTGETNUMDEVS() waveOutGetNumDevs
-402    pascal  WAVEOUTGETDEVCAPS(word ptr word) waveOutGetDevCaps
+402    pascal  WAVEOUTGETDEVCAPS(word segptr word) waveOutGetDevCaps
 403    pascal  WAVEOUTGETERRORTEXT(word ptr word) waveOutGetErrorText
 404    pascal  WAVEOUTOPEN(ptr word ptr long long long) waveOutOpen
 405    pascal  WAVEOUTCLOSE(word) waveOutClose
-406    pascal  WAVEOUTPREPAREHEADER(word ptr word) waveOutPrepareHeader
-407    pascal  WAVEOUTUNPREPAREHEADER(word ptr word) waveOutUnprepareHeader
-408    pascal  WAVEOUTWRITE(word ptr word) waveOutWrite
+406    pascal  WAVEOUTPREPAREHEADER(word segptr word) waveOutPrepareHeader
+407    pascal  WAVEOUTUNPREPAREHEADER(word segptr word) waveOutUnprepareHeader
+408    pascal  WAVEOUTWRITE(word segptr word) waveOutWrite
 409    pascal  WAVEOUTPAUSE(word) waveOutPause
 410    pascal  WAVEOUTRESTART(word) waveOutRestart
 411    pascal  WAVEOUTRESET(word) waveOutReset
-412    pascal  WAVEOUTGETPOSITION(word ptr word) waveOutGetPosition
+412    pascal  WAVEOUTGETPOSITION(word segptr word) waveOutGetPosition
 413    pascal  WAVEOUTGETPITCH(word ptr) waveOutGetPitch
 414    pascal  WAVEOUTSETPITCH(word long) waveOutSetPitch
-415    pascal  WAVEOUTGETVOLUME(word ptr) waveOutGetVolume
+415    pascal  WAVEOUTGETVOLUME(word segptr) waveOutGetVolume
 416    pascal  WAVEOUTSETVOLUME(word long) waveOutSetVolume
 417    pascal  WAVEOUTGETPLAYBACKRATE(word ptr) waveOutGetPlaybackRate
 418    pascal  WAVEOUTSETPLAYBACKRATE(word long) waveOutSetPlaybackRate
@@ -72,17 +72,17 @@
 420    pascal  WAVEOUTGETID(word ptr) waveOutGetID
 421    pascal  WAVEOUTMESSAGE(word word long long) waveOutMessage
 501    pascal  WAVEINGETNUMDEVS() waveInGetNumDevs
-502    pascal  WAVEINGETDEVCAPS(word ptr word) waveInGetDevCaps
+502    pascal  WAVEINGETDEVCAPS(word segptr word) waveInGetDevCaps
 503    pascal  WAVEINGETERRORTEXT(word ptr word) waveInGetErrorText
 504    pascal  WAVEINOPEN(ptr word ptr long long long) waveInOpen
 505    pascal  WAVEINCLOSE(word) waveInClose
-506    pascal  WAVEINPREPAREHEADER(word ptr word) waveInPrepareHeader
-507    pascal  WAVEINUNPREPAREHEADER(word ptr word) waveInUnprepareHeader
-508    pascal  WAVEINADDBUFFER(word ptr word) waveInAddBuffer
+506    pascal  WAVEINPREPAREHEADER(word segptr word) waveInPrepareHeader
+507    pascal  WAVEINUNPREPAREHEADER(word segptr word) waveInUnprepareHeader
+508    pascal  WAVEINADDBUFFER(word segptr word) waveInAddBuffer
 509    pascal  WAVEINSTART(word) waveInStart
 510    pascal  WAVEINSTOP(word) waveInStop
 511    pascal  WAVEINRESET(word) waveInReset
-512    pascal  WAVEINGETPOSITION(word ptr word) waveInGetPosition
+512    pascal  WAVEINGETPOSITION(word segptr word) waveInGetPosition
 513    pascal  WAVEINGETID(word ptr) waveInGetID
 514    pascal  WAVEINMESSAGE(word word long long) waveInMessage
 601    pascal  timeGetSystemTime(ptr word) timeGetSystemTime
diff --git a/if1632/relay.c b/if1632/relay.c
index 0a3ccf5..5049827 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -1,31 +1,14 @@
 /*
-static char RCSId[] = "$Id: relay.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
-static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
-*/
+ * Copyright 1993 Robert J. Amstadt
+ * Copyright 1995 Alexandre Julliard
+ */
 
 #include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#ifdef linux
-#include <linux/unistd.h>
-#include <linux/head.h>
-#include <linux/ldt.h>
-#endif
 
-#include "ldt.h"
-
-#include "neexe.h"
-#include "prototypes.h"
 #include "dlls.h"
-#include "options.h"
-#include "selectors.h"
+#include "global.h"
+#include "module.h"
 #include "stackframe.h"
-#include "wine.h"
 #include "stddebug.h"
 /* #define DEBUG_RELAY */
 #include "debug.h"
@@ -35,41 +18,39 @@
 dprintf_relay
 #endif
 
-#ifdef WINELIB
-#define WineLibSkip(x) 0
-#else
-#define WineLibSkip(x) x
-#endif
+#define DLL_ENTRY(name) \
+  { #name, name##_Code_Start, name##_Data_Start, \
+    name##_Module_Start, name##_Module_End, TRUE, 0 }
 
-struct dll_name_table_entry_s dll_builtin_table[N_BUILTINS] =
+struct dll_table_s dll_builtin_table[N_BUILTINS] =
 {
-    { "KERNEL",   WineLibSkip(&KERNEL_table), 1 },
-    { "USER",     WineLibSkip(&USER_table), 1 },
-    { "GDI",      WineLibSkip(&GDI_table), 1 },
-    { "WIN87EM",  WineLibSkip(&WIN87EM_table), 1 },
-    { "SHELL",    WineLibSkip(&SHELL_table), 1 },
-    { "SOUND",    WineLibSkip(&SOUND_table), 1 },
-    { "KEYBOARD", WineLibSkip(&KEYBOARD_table), 1 },
-    { "WINSOCK",  WineLibSkip(&WINSOCK_table), 1 },
-    { "STRESS",   WineLibSkip(&STRESS_table), 1 },
-    { "MMSYSTEM", WineLibSkip(&MMSYSTEM_table), 1 },
-    { "SYSTEM",   WineLibSkip(&SYSTEM_table), 1 },
-    { "TOOLHELP", WineLibSkip(&TOOLHELP_table), 1 },
-    { "MOUSE",    WineLibSkip(&MOUSE_table), 1 },
-    { "COMMDLG",  WineLibSkip(&COMMDLG_table), 1 },
-    { "OLE2",     WineLibSkip(&OLE2_table), 1 },
-    { "OLE2CONV", WineLibSkip(&OLE2CONV_table), 1 },
-    { "OLE2DISP", WineLibSkip(&OLE2DISP_table), 1 },
-    { "OLE2NLS",  WineLibSkip(&OLE2NLS_table), 1 },
-    { "OLE2PROX", WineLibSkip(&OLE2PROX_table), 1 },
-    { "OLECLI",   WineLibSkip(&OLECLI_table), 1 },
-    { "OLESVR",   WineLibSkip(&OLESVR_table), 1 },
-    { "COMPOBJ",  WineLibSkip(&COMPOBJ_table), 1 },
-    { "STORAGE",  WineLibSkip(&STORAGE_table), 1 },
-    { "WINPROCS", WineLibSkip(&WINPROCS_table), 1 },
-    { "DDEML",    WineLibSkip(&DDEML_table), 1 }
-    
+    DLL_ENTRY(KERNEL),
+    DLL_ENTRY(USER),
+    DLL_ENTRY(GDI),
+    DLL_ENTRY(WIN87EM),
+    DLL_ENTRY(SHELL),
+    DLL_ENTRY(SOUND),
+    DLL_ENTRY(KEYBOARD),
+    DLL_ENTRY(WINSOCK),
+    DLL_ENTRY(STRESS),
+    DLL_ENTRY(MMSYSTEM),
+    DLL_ENTRY(SYSTEM),
+    DLL_ENTRY(TOOLHELP),
+    DLL_ENTRY(MOUSE),
+    DLL_ENTRY(COMMDLG),
+    DLL_ENTRY(OLE2),
+    DLL_ENTRY(OLE2CONV),
+    DLL_ENTRY(OLE2DISP),
+    DLL_ENTRY(OLE2NLS),
+    DLL_ENTRY(OLE2PROX),
+    DLL_ENTRY(OLECLI),
+    DLL_ENTRY(OLESVR),
+    DLL_ENTRY(COMPOBJ),
+    DLL_ENTRY(STORAGE),
+    DLL_ENTRY(WINPROCS),
+    DLL_ENTRY(DDEML)
 };
+
 /* don't forget to increase N_BUILTINS in dlls.h if you add a dll */
 
   /* Saved 16-bit stack */
@@ -78,7 +59,7 @@
 
   /* Saved 32-bit stack */
 DWORD IF1632_Saved32_esp = 0;
-
+SEGPTR IF1632_Stack32_base = 0;
 
 /***********************************************************************
  *           RELAY_Init
@@ -93,9 +74,9 @@
     extern void CALL16_Ret_word(), CALL16_Ret_long();
     extern DWORD CALL16_RetAddr_word, CALL16_RetAddr_long;
 
-    codesel = SELECTOR_AllocBlock( (void *)CALL16_Start,
+    codesel = GLOBAL_CreateBlock( GMEM_FIXED, (void *)CALL16_Start,
                                    (int)CALL16_End - (int)CALL16_Start,
-                                   SEGMENT_CODE, TRUE, FALSE );
+                                   0, TRUE, TRUE, FALSE );
     if (!codesel) return FALSE;
 
       /* Patch the return addresses for CallTo16 routines */
@@ -109,21 +90,24 @@
 }
 
 
-#ifndef WINELIB
-
+/***********************************************************************
+ *           RELAY_DebugCall32
+ */
 void RELAY_DebugCall32( char *args )
 {
     STACK16FRAME *frame;
-    char *args16;
+    struct dll_table_s *table;
+    char *args16, *name;
     int i;
 
     if (!debugging_relay) return;
 
     frame = CURRENT_STACK16;
-    printf( "Call %s.%d: %s(",
-            dll_builtin_table[frame->dll_id-1].dll_name,
-            frame->ordinal_number,
-            dll_builtin_table[frame->dll_id-1].table->dll_table[frame->ordinal_number].export_name );
+    table = &dll_builtin_table[frame->dll_id-1];
+    name  = MODULE_GetEntryPointName( table->hModule, frame->ordinal_number );
+    printf( "Call %s.%d: %*.*s(",
+            table->name, frame->ordinal_number, *name, *name, name + 1 );
+
     args16 = (char *)frame->args;
     for (i = 0; i < strlen(args); i++)
     {
@@ -165,30 +149,41 @@
 }
 
 
+/***********************************************************************
+ *           RELAY_DebugReturn
+ */
 void RELAY_DebugReturn( int short_ret, int ret_val )
 {
     STACK16FRAME *frame;
+    struct dll_table_s *table;
+    char *name;
 
     if (!debugging_relay) return;
 
     frame = CURRENT_STACK16;
-    printf( "Ret  %s.%d: %s() ",
-            dll_builtin_table[frame->dll_id-1].dll_name,
-            frame->ordinal_number,
-            dll_builtin_table[frame->dll_id-1].table->dll_table[frame->ordinal_number].export_name );
+    table = &dll_builtin_table[frame->dll_id-1];
+    name  = MODULE_GetEntryPointName( table->hModule, frame->ordinal_number );
+    printf( "Ret  %s.%d: %*.*s() ",
+            table->name, frame->ordinal_number, *name, *name, name + 1 );
     if (short_ret) printf( "retval=0x%04x\n", ret_val & 0xffff );
     else printf( "retval=0x%08x\n", ret_val );
 }
 
 
+/***********************************************************************
+ *           RELAY_Unimplemented
+ *
+ * This function is called for unimplemented entry points (declared
+ * as 'stub' in the spec file).
+ */
 void RELAY_Unimplemented(void)
 {
     STACK16FRAME *frame = CURRENT_STACK16;
+    struct dll_table_s *table = &dll_builtin_table[frame->dll_id-1];
+    char *name = MODULE_GetEntryPointName( table->hModule, frame->ordinal_number );
 
-    fprintf( stderr, "No handler for routine %s.%d (%s)\n",
-             dll_builtin_table[frame->dll_id-1].dll_name,
-             frame->ordinal_number,
-             dll_builtin_table[frame->dll_id-1].table->dll_table[frame->ordinal_number].export_name );
+    fprintf( stderr, "No handler for routine %s.%d (%*.*s)\n",
+             table->name, frame->ordinal_number, *name, *name, name + 1 );
     exit(1);
 }
 
@@ -214,83 +209,3 @@
     while (nbargs--) printf( ",0x%x", *stack++ );
     printf( ")\n" );
 }
-
-#endif  /* WINELIB */
-
-/**********************************************************************
- *					FindDLLTable
- */
-struct dll_table_s *
-FindDLLTable(char *dll_name)
-{
-    int i;
-
-    for (i = 0; i < N_BUILTINS; i++)
-	if (strcasecmp(dll_builtin_table[i].dll_name, dll_name) == 0
-	  && dll_builtin_table[i].dll_is_used)
-	    return dll_builtin_table[i].table;
-    return NULL;
-}
-
-/**********************************************************************
- *					FindOrdinalFromName
- */
-int
-FindOrdinalFromName(struct dll_table_entry_s *dll_table, char *func_name)
-{
-    int i, limit;
-
-    for (i = 0; i < N_BUILTINS; i++)
-	if (dll_table == dll_builtin_table[i].table->dll_table)
-	    break;
-    
-    if (i == N_BUILTINS)
-	return 0;
-
-    limit = dll_builtin_table[i].table->dll_table_length;
-    for (i = 0; i < limit; i++)
-	if (strcasecmp(dll_table[i].export_name, func_name) == 0)
-	    return i;
-    
-    return 0;
-}
-
-#ifndef WINELIB
-#ifdef WINESTAT
-void winestat(){
-	int i, j;
-	double perc;
-	int used, implemented;
-	int tused, timplemented;
-	struct dll_table_entry_s *table;
-
-	tused = 0;
-	timplemented = 0;
-    for (i = 0; i < N_BUILTINS; i++) {
-	    table = dll_builtin_table[i].table->dll_table;
-	    used = 0;
-	    implemented = 0;
-	    for(j=0; j < dll_builtin_table[i].table->dll_table_length; j++) {
-		    if(table[j].used){
-			    used++;
-			    if (table[j].export_name[0]) implemented++;
-			    else 
-				    printf("%s.%d not implemented\n",
-					   dll_builtin_table[i].dll_name,
-					   j);
-		    };
-	    };
-	    tused += used;
-	    timplemented += implemented;
-	    if(used)
-		    perc = implemented * 100.00 / used;
-	    else
-		    perc = 0.0;
-	    if (used)
-		    printf("%s: %d of %d (%3.1f %%)\n", dll_builtin_table[i].dll_name, implemented, used, perc);
-    };
-	perc = timplemented * 100.00 / tused;
-	printf("TOTAL: %d of %d winapi functions implemented (%3.1f %%)\n",timplemented, tused, perc);
-}
-#endif /* WINESTAT */
-#endif /* !WINELIB */
diff --git a/if1632/relay32.c b/if1632/relay32.c
new file mode 100644
index 0000000..960d739
--- /dev/null
+++ b/if1632/relay32.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright 1995 Martin von Loewis
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include "windows.h"
+#include "dlls.h"
+#include "pe_image.h"
+#include "stddebug.h"
+/* #define DEBUG_RELAY */
+#include "debug.h"
+
+WIN32_builtin	*WIN32_builtin_list;
+
+int RELAY32_Init(void)
+{
+#ifndef WINELIB
+	/* Add a call for each DLL */
+	GDI32_Init();
+	KERNEL32_Init();
+	SHELL32_Init();
+	USER32_Init();
+	WINPROCS32_Init();
+#endif
+	/* Why should it fail, anyways? */
+	return 1;
+}
+
+WIN32_builtin *RELAY32_GetBuiltinDLL(char *name)
+{
+	WIN32_builtin *it;
+	for(it=WIN32_builtin_list;it;it=it->next)
+	if(strcmp(name,it->name)==0)
+		return it;
+	return NULL;
+}
+
+void RELAY32_Unimplemented(char *dll, int item)
+{
+	WIN32_builtin *Dll;
+	fprintf( stderr, "No handler for routine %s.%d", dll, item);
+	Dll=RELAY32_GetBuiltinDLL(dll);
+	if(Dll && Dll->functions[item].name)
+		fprintf(stderr, "(%s?)\n", Dll->functions[item].name);
+	else
+		fprintf(stderr, "\n");
+	fflush(stderr);
+	exit(1);
+}
+
+void *RELAY32_GetEntryPoint(char *dll_name, char *item, int hint)
+{
+	WIN32_builtin *dll;
+	int i;
+	dprintf_module(stddeb, "Looking for %s in %s, hint %x\n",
+		item ? item: "(no name)", dll_name, hint);
+	dll=RELAY32_GetBuiltinDLL(dll_name);
+	if(!dll)return 0;
+	/* import by ordinal */
+	if(!item){
+		if(hint && hint<dll->size)return dll->functions[hint].definition;
+		return 0;
+	}
+	/* hint is correct */
+	if(hint && hint<dll->size && 
+		dll->functions[hint].name &&
+		strcmp(item,dll->functions[hint].name)==0)
+		return dll->functions[hint].definition;
+	/* hint is incorrect, search for name */
+	for(i=1;i<dll->size;i++)
+		if(strcmp(item,dll->functions[i].name)==0)
+			return dll->functions[i].definition;
+	/* function at hint has no name (unimplemented) */
+	if(hint && hint<dll->size && !dll->functions[hint].name)
+	{
+		dll->functions[hint].name=strdup(item);
+		dprintf_module(stddeb, "Returning unimplemented function %s.%d\n",
+			dll_name,hint);
+		return dll->functions[hint].definition;
+	}
+	printf("Not found\n");
+	return 0;
+}
+
+void RELAY32_DebugEnter(char *dll,char *name)
+{
+	dprintf_relay(stddeb, "Entering %s.%s\n",dll,name);
+}
+
+LONG RELAY32_CallWindowProc( WNDPROC func, int hwnd, int message,
+             int wParam, int lParam )
+{
+	int ret;
+	SpyMessage(hwnd, message, wParam, lParam);
+	__asm__ (
+		"push %1;"
+		"push %2;"
+		"push %3;"
+		"push %4;"
+		"call %5;"
+		: "=a" (ret)
+		: "g" (lParam), "g" (wParam), "g" (message), "g" (hwnd), "g" (func)
+	);
+	return ret;
+}
diff --git a/if1632/shell.spec b/if1632/shell.spec
index cab447f..b00a5c4 100644
--- a/if1632/shell.spec
+++ b/if1632/shell.spec
@@ -22,6 +22,9 @@
  22 pascal ShellAbout(word ptr ptr word) ShellAbout
  33 pascal AboutDlgProc(word word word long) AboutDlgProc
  34 pascal ExtractIcon(word ptr s_word) ExtractIcon
+ 36 pascal ExtractAssociatedIcon(word ptr ptr) ExtractAssociatedIcon
+ 37 pascal DoEnvironmentSubst(ptr word word) DoEnvironmentSubst
+ 39 stub InternalExtractIcon
 102 pascal RegisterShellHook(ptr) RegisterShellHook
 103 pascal ShellHookProc() ShellHookProc
 
diff --git a/if1632/shell32.spec b/if1632/shell32.spec
new file mode 100644
index 0000000..1ce2e8a
--- /dev/null
+++ b/if1632/shell32.spec
@@ -0,0 +1,87 @@
+name	shell32
+base	1
+
+0000 stub CheckEscapesA
+0001 stub CheckEscapesW
+0002 stub CommandLineToArgvW
+0003 stub DoEnvironmentSubstA
+0004 stub DoEnvironmentSubstW
+0005 stub DragAcceptFiles
+0006 stub DragFinish
+0007 stub DragQueryFileA
+0008 stub DragQueryFileAorW
+0009 stub DragQueryFileW
+0010 stub DragQueryPoint
+0011 stub DuplicateIcon
+0012 stub ExtractAssociatedIconA
+0013 stub ExtractAssociatedIconExA
+0014 stub ExtractAssociatedIconExW
+0015 stub ExtractAssociatedIconW
+0016 stub ExtractIconA
+0017 stub ExtractIconResInfoA
+0018 stub ExtractIconResInfoW
+0019 stub ExtractIconW
+0020 stub ExtractVersionResource16W
+0021 stub FindExeDlgProc
+0022 stub FindExecutableA
+0023 stub FindExecutableW
+0024 stub FreeIconList
+0025 stub InternalExtractIconListA
+0026 stub InternalExtractIconListW
+0027 stub RealShellExecuteA
+0028 stub RealShellExecuteExA
+0029 stub RealShellExecuteExW
+0030 stub RealShellExecuteW
+0031 stub RegenerateUserEnvironment
+0032 stub RegisterShellHook
+0033 stub SheChangeDirA
+0034 stub SheChangeDirExA
+0035 stub SheChangeDirExW
+0036 stub SheChangeDirW
+0037 stub SheConvertPathW
+0038 stub SheFullPathA
+0039 stub SheFullPathW
+0040 stub SheGetCurDrive
+0041 stub SheGetDirA
+0042 stub SheGetDirExW
+0043 stub SheGetDirW
+0044 stub SheGetPathOffsetW
+0045 stub SheRemoveQuotesA
+0046 stub SheRemoveQuotesW
+0047 stub SheSetCurDrive
+0048 stub SheShortenPathA
+0049 stub SheShortenPathW
+0050 stub ShellAboutA
+0051 stub ShellAboutW
+0052 stub ShellExecuteA
+0053 stub ShellExecuteW
+0054 stub ShellHookProc
+0055 stub StrChrA
+0056 stub StrChrIA
+0057 stub StrChrIW
+0058 stub StrChrW
+0059 stub StrCmpNA
+0060 stub StrCmpNIA
+0061 stub StrCmpNIW
+0062 stub StrCmpNW
+0063 stub StrCpyNA
+0064 stub StrCpyNW
+0065 stub StrNCmpA
+0066 stub StrNCmpIA
+0067 stub StrNCmpIW
+0068 stub StrNCmpW
+0069 stub StrNCpyA
+0070 stub StrNCpyW
+0071 stub StrRChrA
+0072 stub StrRChrIA
+0073 stub StrRChrIW
+0074 stub StrRChrW
+0075 stub StrRStrA
+0076 stub StrRStrIA
+0077 stub StrRStrIW
+0078 stub StrRStrW
+0079 stub StrStrA
+0080 stub StrStrIA
+0081 stub StrStrIW
+0082 stub StrStrW
+0083 stub WOWShellExecute
diff --git a/if1632/storage.spec b/if1632/storage.spec
index d6d59c7..08efdc3 100644
--- a/if1632/storage.spec
+++ b/if1632/storage.spec
@@ -1,13 +1,13 @@
 name	storage
 id	23
  
-#1 STGCREATEDOCFILE
-#2 STGCREATEDOCFILEONILOCKBYTES
-#3 STGOPENSTORAGE
-#4 STGOPENSTORAGEONILOCKBYTES
-#5 STGISSTORAGEFILE
-#6 STGISSTORAGEILOCKBYTES
-#7 STGSETTIMES
+1 stub StgCreateDocFile
+2 stub StgCreateDocFileOnILockBytes
+3 stub StgOpenStorage
+4 stub StgOpenStorageOnILockBytes
+5 stub StgIsStorageFile
+6 stub StgIsStorageILockBytes
+7 stub StgSetTimes
 #8 WEP
 #9 ___EXPORTEDSTUB
-#103 DLLGETCLASSOBJECT
+103 stub DllGetClassObject
diff --git a/if1632/system.spec b/if1632/system.spec
index 6adb534..4edc485 100644
--- a/if1632/system.spec
+++ b/if1632/system.spec
@@ -1,4 +1,13 @@
 name	system
 id	11
 
+1 stub InquireSystem
+2 stub CreateSystemTimer
+3 stub KillSystemTimer
+4 stub EnableSystemTimers
+5 stub DisableSystemTimers
 6 pascal GetSystemmsecCount() GetTickCount
+7 stub Get80x87SaveSize
+8 stub Save80x87State
+9 stub Restore80x87State
+#20 stub A20_Proc
diff --git a/if1632/user.spec b/if1632/user.spec
index 969eb14..e69390c 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -114,7 +114,7 @@
 113 pascal TranslateMessage(ptr) TranslateMessage
 114 pascal DispatchMessage(ptr) DispatchMessage
 115 stub ReplyMessage
-116 stub PostAppMessage
+116 pascal PostAppMessage(word word word long) PostAppMessage
 118 pascal RegisterWindowMessage(ptr) RegisterWindowMessage
 119 pascal GetMessagePos() GetMessagePos
 120 pascal GetMessageTime() GetMessageTime
@@ -372,7 +372,7 @@
 456 stub LoadIconHandler
 457 pascal DestroyIcon(word) DestroyIcon
 458 pascal DestroyCursor(word) DestroyCursor
-459 stub DumpIcon
+459 pascal DumpIcon(ptr ptr ptr ptr) DumpIcon
 460 pascal GetInternalWindowPos(word ptr ptr) GetInternalWindowPos
 461 pascal SetInternalWindowPos(word word ptr ptr) SetInternalWindowPos
 462 stub CalcChildScroll
diff --git a/if1632/user32.spec b/if1632/user32.spec
new file mode 100644
index 0000000..4b80bf0
--- /dev/null
+++ b/if1632/user32.spec
@@ -0,0 +1,591 @@
+name	user32
+base	1
+
+0000 stub ActivateKeyboardLayout
+0001 stub AdjustWindowRect
+0002 stub AdjustWindowRectEx
+0003 stub AnyPopup
+0004 stub AppendMenuA
+0005 stub AppendMenuW
+0006 stub ArrangeIconicWindows
+0007 stub AttachThreadInput
+0008 stub BeginDeferWindowPos
+0009 stub BeginPaint
+0010 stub BringWindowToTop
+0011 stub BroadcastSystemMessage
+0012 stub CalcChildScroll
+0013 stub CallMsgFilter
+0014 stub CallMsgFilterA
+0015 stub CallMsgFilterW
+0016 stub CallNextHookEx
+0017 stub CallWindowProcA
+0018 stub CallWindowProcW
+0019 stub CascadeChildWindows
+0020 stub CascadeWindows
+0021 stub ChangeClipboardChain
+0022 stub ChangeMenuA
+0023 stub ChangeMenuW
+0024 stub CharLowerA
+0025 stub CharLowerBuffA
+0026 stub CharLowerBuffW
+0027 stub CharLowerW
+0028 stub CharNextA
+0029 stub CharNextExA
+0030 stub CharNextExW
+0031 stub CharNextW
+0032 stub CharPrevA
+0033 stub CharPrevExA
+0034 stub CharPrevExW
+0035 stub CharPrevW
+0036 stub CharToOemA
+0037 stub CharToOemBuffA
+0038 stub CharToOemBuffW
+0039 stub CharToOemW
+0040 stub CharUpperA
+0041 stub CharUpperBuffA
+0042 stub CharUpperBuffW
+0043 stub CharUpperW
+0044 stub CheckDlgButton
+0045 stub CheckMenuItem
+0046 stub CheckMenuRadioItem
+0047 stub CheckRadioButton
+0048 stub ChildWindowFromPoint
+0049 stub ChildWindowFromPointEx
+0050 stub ClientThreadConnect
+0051 stub ClientToScreen
+0052 stub ClipCursor
+0053 stub CloseClipboard
+0054 stub CloseDesktop
+0055 stub CloseWindow
+0056 stub CloseWindowStation
+0057 stub CopyAcceleratorTableA
+0058 stub CopyAcceleratorTableW
+0059 stub CopyIcon
+0060 stub CopyImage
+0061 stub CopyRect
+0062 stub CountClipboardFormats
+0063 stub CreateAcceleratorTableA
+0064 stub CreateAcceleratorTableW
+0065 stub CreateCaret
+0066 stub CreateCursor
+0067 stub CreateDesktopA
+0068 stub CreateDesktopW
+0069 stub CreateDialogIndirectParamA
+0070 stub CreateDialogIndirectParamAorW
+0071 stub CreateDialogIndirectParamW
+0072 stub CreateDialogParamA
+0073 stub CreateDialogParamW
+0074 stub CreateIcon
+0075 stub CreateIconFromResource
+0076 stub CreateIconFromResourceEx
+0077 stub CreateIconIndirect
+0078 stub CreateMDIWindowA
+0079 stub CreateMDIWindowW
+0080 stub CreateMenu
+0081 stub CreatePopupMenu
+0082 stub CreateWindowExA
+0083 stub CreateWindowExW
+0084 stub CreateWindowStationA
+0085 stub CreateWindowStationW
+0086 stub DdeAbandonTransaction
+0087 stub DdeAccessData
+0088 stub DdeAddData
+0089 stub DdeClientTransaction
+0090 stub DdeCmpStringHandles
+0091 stub DdeConnect
+0092 stub DdeConnectList
+0093 stub DdeCreateDataHandle
+0094 stub DdeCreateStringHandleA
+0095 stub DdeCreateStringHandleW
+0096 stub DdeDisconnect
+0097 stub DdeDisconnectList
+0098 stub DdeEnableCallback
+0099 stub DdeFreeDataHandle
+0100 stub DdeFreeStringHandle
+0101 stub DdeGetData
+0102 stub DdeGetLastError
+0103 stub DdeGetQualityOfService
+0104 stub DdeImpersonateClient
+0105 stub DdeInitializeA
+0106 stub DdeInitializeW
+0107 stub DdeKeepStringHandle
+0108 stub DdeNameService
+0109 stub DdePostAdvise
+0110 stub DdeQueryConvInfo
+0111 stub DdeQueryNextServer
+0112 stub DdeQueryStringA
+0113 stub DdeQueryStringW
+0114 stub DdeReconnect
+0115 stub DdeSetQualityOfService
+0116 stub DdeSetUserHandle
+0117 stub DdeUnaccessData
+0118 stub DdeUninitialize
+0119 stub DefDlgProcA
+0120 stub DefDlgProcW
+0121 stub DefFrameProcA
+0122 stub DefFrameProcW
+0123 stub DefMDIChildProcA
+0124 stub DefMDIChildProcW
+0125 stub DefWindowProcA
+0126 stub DefWindowProcW
+0127 stub DeferWindowPos
+0128 stub DeleteMenu
+0129 stub DestroyAcceleratorTable
+0130 stub DestroyCaret
+0131 stub DestroyCursor
+0132 stub DestroyIcon
+0133 stub DestroyMenu
+0134 stub DestroyWindow
+0135 stub DialogBoxIndirectParamA
+0136 stub DialogBoxIndirectParamAorW
+0137 stub DialogBoxIndirectParamW
+0138 stub DialogBoxParamA
+0139 stub DialogBoxParamW
+0140 stub DispatchMessageA
+0141 stub DispatchMessageW
+0142 stub DlgDirListA
+0143 stub DlgDirListComboBoxA
+0144 stub DlgDirListComboBoxW
+0145 stub DlgDirListW
+0146 stub DlgDirSelectComboBoxExA
+0147 stub DlgDirSelectComboBoxExW
+0148 stub DlgDirSelectExA
+0149 stub DlgDirSelectExW
+0150 stub DragDetect
+0151 stub DragObject
+0152 stub DrawAnimatedRects
+0153 stub DrawCaption
+0154 stub DrawEdge
+0155 stub DrawFocusRect
+0156 stub DrawFrame
+0157 stub DrawFrameControl
+0158 stub DrawIcon
+0159 stub DrawIconEx
+0160 stub DrawMenuBar
+0161 stub DrawStateA
+0162 stub DrawStateW
+0163 stub DrawTextA
+0164 stub DrawTextExA
+0165 stub DrawTextExW
+0166 stub DrawTextW
+0167 stub EditWndProc
+0168 stub EmptyClipboard
+0169 stub EnableMenuItem
+0170 stub EnableScrollBar
+0171 stub EnableWindow
+0172 stub EndDeferWindowPos
+0173 stub EndDialog
+0174 stub EndMenu
+0175 stub EndPaint
+0176 stub EndTask
+0177 stub EnumChildWindows
+0178 stub EnumClipboardFormats
+0179 stub EnumDesktopsA
+0180 stub EnumDesktopsW
+0181 stub EnumDisplayDeviceModesA
+0182 stub EnumDisplayDeviceModesW
+0183 stub EnumDisplayDevicesA
+0184 stub EnumDisplayDevicesW
+0185 stub EnumPropsA
+0186 stub EnumPropsExA
+0187 stub EnumPropsExW
+0188 stub EnumPropsW
+0189 stub EnumThreadWindows
+0190 stub EnumWindowStationsA
+0191 stub EnumWindowStationsW
+0192 stub EnumWindows
+0193 stub EqualRect
+0194 stub ExcludeUpdateRgn
+0195 stub ExitWindowsEx
+0196 stub FillRect
+0197 stub FindWindowA
+0198 stub FindWindowExA
+0199 stub FindWindowExW
+0200 stub FindWindowW
+0201 stub FlashWindow
+0202 stub FrameRect
+0203 stub FreeDDElParam
+0204 stub GetActiveWindow
+0205 stub GetAppCompatFlags
+0206 stub GetAsyncKeyState
+0207 stub GetCapture
+0208 stub GetCaretBlinkTime
+0209 stub GetCaretPos
+0210 stub GetClassInfoA
+0211 stub GetClassInfoExA
+0212 stub GetClassInfoExW
+0213 stub GetClassInfoW
+0214 stub GetClassLongA
+0215 stub GetClassLongW
+0216 stub GetClassNameA
+0217 stub GetClassNameW
+0218 stub GetClassWord
+0219 stub GetClientRect
+0220 stub GetClipCursor
+0221 stub GetClipboardData
+0222 stub GetClipboardFormatNameA
+0223 stub GetClipboardFormatNameW
+0224 stub GetClipboardOwner
+0225 stub GetClipboardViewer
+0226 stub GetCursor
+0227 stub GetCursorInfo
+0228 stub GetCursorPos
+0229 stub GetDC
+0230 stub GetDCEx
+0231 stub GetDesktopWindow
+0232 stub GetDialogBaseUnits
+0233 stub GetDlgCtrlID
+0234 stub GetDlgItem
+0235 stub GetDlgItemInt
+0236 stub GetDlgItemTextA
+0237 stub GetDlgItemTextW
+0238 stub GetDoubleClickTime
+0239 stub GetFocus
+0240 stub GetForegroundWindow
+0241 stub GetIconInfo
+0242 stub GetInputDesktop
+0243 stub GetInputState
+0244 stub GetInternalWindowPos
+0245 stub GetKBCodePage
+0246 stub GetKeyNameTextA
+0247 stub GetKeyNameTextW
+0248 stub GetKeyState
+0249 stub GetKeyboardLayout
+0250 stub GetKeyboardLayoutList
+0251 stub GetKeyboardLayoutNameA
+0252 stub GetKeyboardLayoutNameW
+0253 stub GetKeyboardState
+0254 stub GetKeyboardType
+0255 stub GetLastActivePopup
+0256 stub GetMenu
+0257 stub GetMenuCheckMarkDimensions
+0258 stub GetMenuContextHelpId
+0259 stub GetMenuDefaultItem
+0260 stub GetMenuIndex
+0261 stub GetMenuItemCount
+0262 stub GetMenuItemID
+0263 stub GetMenuItemInfoA
+0264 stub GetMenuItemInfoW
+0265 stub GetMenuItemRect
+0266 stub GetMenuState
+0267 stub GetMenuStringA
+0268 stub GetMenuStringW
+0269 stub GetMessageA
+0270 stub GetMessageExtraInfo
+0271 stub GetMessagePos
+0272 stub GetMessageTime
+0273 stub GetMessageW
+0274 stub GetNextDlgGroupItem
+0275 stub GetNextDlgTabItem
+0276 stub GetOpenClipboardWindow
+0277 stub GetParent
+0278 stub GetPriorityClipboardFormat
+0279 stub GetProcessWindowStation
+0280 stub GetPropA
+0281 stub GetPropW
+0282 stub GetQueueStatus
+0283 stub GetScrollInfo
+0284 stub GetScrollPos
+0285 stub GetScrollRange
+0286 stub GetShellWindow
+0287 stub GetSubMenu
+0288 stub GetSysColor
+0289 stub GetSysColorBrush
+0290 stub GetSystemMenu
+0291 stub GetSystemMetrics
+0292 stub GetTabbedTextExtentA
+0293 stub GetTabbedTextExtentW
+0294 stub GetThreadDesktop
+0295 stub GetTopWindow
+0296 stub GetUpdateRect
+0297 stub GetUpdateRgn
+0298 stub GetUserObjectInformationA
+0299 stub GetUserObjectInformationW
+0300 stub GetUserObjectSecurity
+0301 stub GetWindow
+0302 stub GetWindowContextHelpId
+0303 stub GetWindowDC
+0304 stub GetWindowLongA
+0305 stub GetWindowLongW
+0306 stub GetWindowPlacement
+0307 stub GetWindowRect
+0308 stub GetWindowTextA
+0309 stub GetWindowTextLengthA
+0310 stub GetWindowTextLengthW
+0311 stub GetWindowTextW
+0312 stub GetWindowThreadProcessId
+0313 stub GetWindowWord
+0314 stub GrayStringA
+0315 stub GrayStringW
+0316 stub HideCaret
+0317 stub HiliteMenuItem
+0318 stub ImpersonateDdeClientWindow
+0319 stub InSendMessage
+0320 stub InflateRect
+0321 stub InsertMenuA
+0322 stub InsertMenuItemA
+0323 stub InsertMenuItemW
+0324 stub InsertMenuW
+0325 stub InternalGetWindowText
+0326 stub IntersectRect
+0327 stub InvalidateRect
+0328 stub InvalidateRgn
+0329 stub InvertRect
+0330 stub IsCharAlphaA
+0331 stub IsCharAlphaNumericA
+0332 stub IsCharAlphaNumericW
+0333 stub IsCharAlphaW
+0334 stub IsCharLowerA
+0335 stub IsCharLowerW
+0336 stub IsCharUpperA
+0337 stub IsCharUpperW
+0338 stub IsChild
+0339 stub IsClipboardFormatAvailable
+0340 stub IsDialogMessage
+0341 stub IsDialogMessageA
+0342 stub IsDialogMessageW
+0343 stub IsDlgButtonChecked
+0344 stub IsIconic
+0345 stub IsMenu
+0346 stub IsRectEmpty
+0347 stub IsWindow
+0348 stub IsWindowEnabled
+0349 stub IsWindowUnicode
+0350 stub IsWindowVisible
+0351 stub IsZoomed
+0352 stub KillSystemTimer
+0353 stub KillTimer
+0354 stub LoadAcceleratorsA
+0355 stub LoadAcceleratorsW
+0356 stub LoadBitmapA
+0357 stub LoadBitmapW
+0358 stub LoadCursorA
+0359 stub LoadCursorFromFileA
+0360 stub LoadCursorFromFileW
+0361 stub LoadCursorW
+0362 stub LoadIconA
+0363 stub LoadIconW
+0364 stub LoadImageA
+0365 stub LoadImageW
+0366 stub LoadKeyboardLayoutA
+0367 stub LoadKeyboardLayoutW
+0368 stub LoadLocalFonts
+0369 stub LoadMenuA
+0370 stub LoadMenuIndirectA
+0371 stub LoadMenuIndirectW
+0372 stub LoadMenuW
+0373 stub LoadRemoteFonts
+0374 stub LoadStringA
+0375 stub LoadStringW
+0376 stub LockWindowStation
+0377 stub LockWindowUpdate
+0378 stub LookupIconIdFromDirectory
+0379 stub LookupIconIdFromDirectoryEx
+0380 stub MBToWCSEx
+0381 stub MapDialogRect
+0382 stub MapVirtualKeyA
+0383 stub MapVirtualKeyExA
+0384 stub MapVirtualKeyW
+0385 stub MapWindowPoints
+0386 stub MenuItemFromPoint
+0387 stub MenuWindowProcA
+0388 stub MenuWindowProcW
+0389 stub MessageBeep
+0390	stdcall MessageBoxA(long ptr ptr long)	MessageBox
+0391 stub MessageBoxExA
+0392 stub MessageBoxExW
+0393 stub MessageBoxIndirectA
+0394 stub MessageBoxIndirectW
+0395 stub MessageBoxW
+0396 stub ModifyMenuA
+0397 stub ModifyMenuW
+0398 stub MoveWindow
+0399 stub MsgWaitForMultipleObjects
+0400 stub OemKeyScan
+0401 stub OemToCharA
+0402 stub OemToCharBuffA
+0403 stub OemToCharBuffW
+0404 stub OemToCharW
+0405 stub OffsetRect
+0406 stub OpenClipboard
+0407 stub OpenDesktopA
+0408 stub OpenDesktopW
+0409 stub OpenIcon
+0410 stub OpenInputDesktop
+0411 stub OpenWindowStationA
+0412 stub OpenWindowStationW
+0413 stub PackDDElParam
+0414 stub PaintDesktop
+0415 stub PeekMessageA
+0416 stub PeekMessageW
+0417 stub PlaySoundEvent
+0418 stub PostMessageA
+0419 stub PostMessageW
+0420 stub PostQuitMessage
+0421 stub PostThreadMessageA
+0422 stub PostThreadMessageW
+0423 stub PtInRect
+0424 stub QuerySendMessage
+0425 stub RedrawWindow
+0426 stub RegisterClassA
+0427 stub RegisterClassExA
+0428 stub RegisterClassExW
+0429 stub RegisterClassW
+0430 stub RegisterClipboardFormatA
+0431 stub RegisterClipboardFormatW
+0432 stub RegisterHotKey
+0433 stub RegisterLogonProcess
+0434 stub RegisterSystemThread
+0435 stub RegisterTasklist
+0436 stub RegisterWindowMessageA
+0437 stub RegisterWindowMessageW
+0438 stub ReleaseCapture
+0439 stub ReleaseDC
+0440 stub RemoveMenu
+0441 stub RemovePropA
+0442 stub RemovePropW
+0443 stub ReplyMessage
+0444 stub ResetDisplay
+0445 stub ReuseDDElParam
+0446 stub ScreenToClient
+0447 stub ScrollChildren
+0448 stub ScrollDC
+0449 stub ScrollWindow
+0450 stub ScrollWindowEx
+0451 stub SendDlgItemMessageA
+0452 stub SendDlgItemMessageW
+0453 stub SendMessageA
+0454 stub SendMessageCallbackA
+0455 stub SendMessageCallbackW
+0456 stub SendMessageTimeoutA
+0457 stub SendMessageTimeoutW
+0458 stub SendMessageW
+0459 stub SendNotifyMessageA
+0460 stub SendNotifyMessageW
+0461 stub ServerSetFunctionPointers
+0462 stub SetActiveWindow
+0463 stub SetCapture
+0464 stub SetCaretBlinkTime
+0465 stub SetCaretPos
+0466 stub SetClassLongA
+0467 stub SetClassLongW
+0468 stub SetClassWord
+0469 stub SetClipboardData
+0470 stub SetClipboardViewer
+0471 stub SetCursor
+0472 stub SetCursorContents
+0473 stub SetCursorPos
+0474 stub SetDebugErrorLevel
+0475 stub SetDeskWallpaper
+0476 stub SetDlgItemInt
+0477 stub SetDlgItemTextA
+0478 stub SetDlgItemTextW
+0479 stub SetDoubleClickTime
+0480 stub SetFocus
+0481 stub SetForegroundWindow
+0482 stub SetInternalWindowPos
+0483 stub SetKeyboardState
+0484 stub SetLastErrorEx
+0485 stub SetLogonNotifyWindow
+0486 stub SetMenu
+0487 stub SetMenuContextHelpId
+0488 stub SetMenuDefaultItem
+0489 stub SetMenuItemBitmaps
+0490 stub SetMenuItemInfoA
+0491 stub SetMenuItemInfoW
+0492 stub SetMessageExtraInfo
+0493 stub SetMessageQueue
+0494 stub SetParent
+0495 stub SetProcessWindowStation
+0496 stub SetPropA
+0497 stub SetPropW
+0498 stub SetRect
+0499 stub SetRectEmpty
+0500 stub SetScrollInfo
+0501 stub SetScrollPos
+0502 stub SetScrollRange
+0503 stub SetShellWindow
+0504 stub SetSysColors
+0505 stub SetSysColorsTemp
+0506 stub SetSystemCursor
+0507 stub SetSystemMenu
+0508 stub SetSystemTimer
+0509 stub SetThreadDesktop
+0510 stub SetTimer
+0511 stub SetUserObjectInformationA
+0512 stub SetUserObjectInformationW
+0513 stub SetUserObjectSecurity
+0514 stub SetWindowContextHelpId
+0515 stub SetWindowFullScreenState
+0516 stub SetWindowLongA
+0517 stub SetWindowLongW
+0518 stub SetWindowPlacement
+0519 stub SetWindowPos
+0520 stub SetWindowStationUser
+0521 stub SetWindowTextA
+0522 stub SetWindowTextW
+0523 stub SetWindowWord
+0524 stub SetWindowsHookA
+0525 stub SetWindowsHookExA
+0526 stub SetWindowsHookExW
+0527 stub SetWindowsHookW
+0528 stub ShowCaret
+0529 stub ShowCursor
+0530 stub ShowOwnedPopups
+0531 stub ShowScrollBar
+0532 stub ShowStartGlass
+0533 stub ShowWindow
+0534 stub ShowWindowAsync
+0535 stub SubtractRect
+0536 stub SwapMouseButton
+0537 stub SwitchDesktop
+0538 stub SwitchToThisWindow
+0539 stub SystemParametersInfoA
+0540 stub SystemParametersInfoW
+0541 stub TabbedTextOutA
+0542 stub TabbedTextOutW
+0543 stub TileChildWindows
+0544 stub TileWindows
+0545 stub ToAscii
+0546 stub ToAsciiEx
+0547 stub ToUnicode
+0548 stub TrackPopupMenu
+0549 stub TrackPopupMenuEx
+0550 stub TranslateAccelerator
+0551 stub TranslateAcceleratorA
+0552 stub TranslateAcceleratorW
+0553 stub TranslateCharsetInfo
+0554 stub TranslateMDISysAccel
+0555 stub TranslateMessage
+0556 stub UnhookWindowsHook
+0557 stub UnhookWindowsHookEx
+0558 stub UnionRect
+0559 stub UnloadKeyboardLayout
+0560 stub UnlockWindowStation
+0561 stub UnpackDDElParam
+0562 stub UnregisterClassA
+0563 stub UnregisterClassW
+0564 stub UnregisterHotKey
+0565 stub UpdatePerUserSystemParameters
+0566 stub UpdateWindow
+0567 stub UserClientDllInitialize
+0568 stub UserRealizePalette
+0569 stub UserRegisterWowHandlers
+0570 stub ValidateRect
+0571 stub ValidateRgn
+0572 stub VkKeyScanA
+0573 stub VkKeyScanExA
+0574 stub VkKeyScanExW
+0575 stub VkKeyScanW
+0576 stub WaitForInputIdle
+0577 stub WaitMessage
+0578 stub WinHelpA
+0579 stub WinHelpW
+0580 stub WindowFromDC
+0581 stub WindowFromPoint
+0582 stub keybd_event
+0583 stub mouse_event
+0584 stub wsprintfA
+0585 stub wsprintfW
+0586 stub wvsprintfA
+0587 stub wvsprintfW
diff --git a/if1632/winprocs.spec b/if1632/winprocs.spec
index a1c54f6..16240c4 100644
--- a/if1632/winprocs.spec
+++ b/if1632/winprocs.spec
@@ -22,6 +22,6 @@
 19 pascal PrintSetupDlgProc(word word word long) PrintSetupDlgProc
 20 pascal PrintDlgProc(word word word long) PrintDlgProc
 21 pascal AboutDlgProc(word word word long) AboutDlgProc
-22 pascal AboutWine_Proc(word word word long) AboutWine_Proc
+22 pascal ComboLBoxWndProc(word word word long) ComboLBoxWndProc
 23 pascal16 CARET_Callback(word word word long) CARET_Callback
 24 pascal16 TASK_Reschedule() TASK_Reschedule
diff --git a/if1632/winprocs32.spec b/if1632/winprocs32.spec
new file mode 100644
index 0000000..9789e8a
--- /dev/null
+++ b/if1632/winprocs32.spec
@@ -0,0 +1,25 @@
+name	winprocs32
+
+1  stdcall ButtonWndProc(long long long long) ButtonWndProc
+2  stdcall StaticWndProc(long long long long) StaticWndProc
+3  stdcall ScrollBarWndProc(long long long long) ScrollBarWndProc
+4  stdcall ListBoxWndProc(long long long long) ListBoxWndProc
+5  stdcall ComboBoxWndProc(long long long long) ComboBoxWndProc
+6  stdcall EditWndProc(long long long long) EditWndProc
+7  stdcall PopupMenuWndProc(long long long long) PopupMenuWndProc
+8  stdcall DesktopWndProc(long long long long) DesktopWndProc
+9  stdcall DefDlgProc(long long long long) DefDlgProc
+10 stdcall MDIClientWndProc(long long long long) MDIClientWndProc
+11 stdcall DefWindowProc(long long long long) DefWindowProc
+12 stdcall DefMDIChildProc(long long long long) DefMDIChildProc
+13 stdcall SystemMessageBoxProc(long long long long) SystemMessageBoxProc
+14 stdcall FileOpenDlgProc(long long long long) FileOpenDlgProc
+15 stdcall FileSaveDlgProc(long long long long) FileSaveDlgProc
+16 stdcall ColorDlgProc(long long long long) ColorDlgProc
+17 stdcall FindTextDlgProc(long long long long) FindTextDlgProc
+18 stdcall ReplaceTextDlgProc(long long long long) ReplaceTextDlgProc
+19 stdcall PrintSetupDlgProc(long long long long) PrintSetupDlgProc
+20 stdcall PrintDlgProc(long long long long) PrintDlgProc
+21 stdcall AboutDlgProc(long long long long) AboutDlgProc
+22 stdcall ComboLBoxWndProc(long long long long) ComboLBoxWndProc
+23 stdcall CARET_Callback(long long long long) CARET_Callback
diff --git a/include/bitmaps/obm_cdrom b/include/bitmaps/obm_cdrom
new file mode 100644
index 0000000..b61230c
--- /dev/null
+++ b/include/bitmaps/obm_cdrom
@@ -0,0 +1,23 @@
+/* XPM */
+static char * obm_cdrom[] = {
+"20 15 5 1",
+" 	s white c white",
+".	s black c black",
+"X	s ltgray c #c0c0c0",
+"o	s dkgray c #808080",
+"O	s red c red",
+"                    ",
+"                    ",
+" .................. ",
+" .XXXXXXXXXXXXXXXo. ",
+" .XXXXXXXXXXXXXXXo. ",
+" .XoooooooooooooXo. ",
+" .Xo.XXXXXXXXX.oXo. ",
+" .Xoo..XXXXX..ooXo. ",
+" .XXXXX.....XXXXXo. ",
+" .X.XOOXXXXXXX..Xo. ",
+" .X.XOOXXXXXXX..Xo. ",
+" .oooooooooooooooo. ",
+" .................. ",
+"                    ",
+"                    "};
diff --git a/include/bitmaps/obm_drive b/include/bitmaps/obm_drive
new file mode 100644
index 0000000..2991dc6
--- /dev/null
+++ b/include/bitmaps/obm_drive
@@ -0,0 +1,23 @@
+/* XPM */
+static char * obm_drive[] = {
+"20 15 5 1",
+" 	s white c white",
+".	s black c black",
+"X	s ltgray c #c0c0c0",
+"o	s dkgray c #808080",
+"O	s red c red",
+"                    ",
+"                    ",
+" .................. ",
+" .XXXXXXXXXXXXXXXo. ",
+" .XXXXXXXXXXXXXXXo. ",
+" .XXX.........XXXo. ",
+" .X.............Xo. ",
+" .XXX.........XXXo. ",
+" .XXXXXXXXXXXXXXXo. ",
+" .XXXOOXXXXX..XXXo. ",
+" .XXXOOXXXXX..XXXo. ",
+" .oooooooooooooooo. ",
+" .................. ",
+"                    ",
+"                    "};
diff --git a/include/bitmaps/obm_folder b/include/bitmaps/obm_folder
new file mode 100644
index 0000000..92c84ed
--- /dev/null
+++ b/include/bitmaps/obm_folder
@@ -0,0 +1,22 @@
+/* XPM */
+static char * obm_folder[] = {
+"20 15 4 1",
+" 	s white c white",
+".	s black c black",
+"X	s foldercol c #00bfbf",
+"o	s cyan c cyan",
+"                    ",
+"    ....            ",
+"   .XXXX.           ",
+"  ..............    ",
+"  .XoXoXoXoXoXoX.   ",
+"  .oXoXoXoXoXoXo.   ",
+"  .XoXoXoXoXoXoX.   ",
+"  .oXoXoXoXoXoXo.   ",
+"  .XoXoXoXoXoXoX.   ",
+"  .oXoXoXoXoXoXo.   ",
+"  .XoXoXoXoXoXoX.   ",
+"  .oXoXoXoXoXoXo.   ",
+"   ..............   ",
+"                    ",
+"                    "};
diff --git a/include/bitmaps/obm_folder2 b/include/bitmaps/obm_folder2
new file mode 100644
index 0000000..4b9946b
--- /dev/null
+++ b/include/bitmaps/obm_folder2
@@ -0,0 +1,21 @@
+/* XPM */
+static char * obm_folder2[] = {
+"20 15 3 1",
+" 	s white c white",
+".	s black c black",
+"X	s foldercol c #00bfbf",
+"                    ",
+"                    ",
+"    ...             ",
+"   ..X..            ",
+"  ..X.X........     ",
+"  .X.X.X.X.X.X..    ",
+"  ..X.X.X.X.X.X.    ",
+"  .X.X............  ",
+"  ..X.X.XXXXXXXXXX. ",
+"  .X.X.XXXXXXXXXXX. ",
+"  ..X.XXXXXXXXXXX.  ",
+"  .X.XXXXXXXXXXX.   ",
+"  ..XXXXXXXXXXX.    ",
+"  .............     ",
+"                    "};
diff --git a/include/bitmaps/obm_harddisk b/include/bitmaps/obm_harddisk
new file mode 100644
index 0000000..fab0d02
--- /dev/null
+++ b/include/bitmaps/obm_harddisk
@@ -0,0 +1,23 @@
+/* XPM */
+static char * obm_harddisk[] = {
+"20 15 5 1",
+" 	s white c white",
+".	s black c black",
+"X	s ltgray c #c0c0c0",
+"o	s dkgray c #808080",
+"O	s green c green",
+"                    ",
+"                    ",
+" .................. ",
+" .XXXXXXXXXXXXXXXo. ",
+" .XXXXXXXXXXXXXXXo. ",
+" .XXXXXXXXXXXXXXXo. ",
+" .XXXXXXXXXXXXXXXo. ",
+" .XXXXXXXXXXXXXXXo. ",
+" .oooooooooooooooo. ",
+" .XXXXXXXXXXXOOXXo. ",
+" .XXXXXXXXXXXOOXXo. ",
+" .oooooooooooooooo. ",
+" .................. ",
+"                    ",
+"                    "};
diff --git a/include/bitmaps/oic_landscape b/include/bitmaps/oic_landscape
new file mode 100644
index 0000000..d5e2b0b
--- /dev/null
+++ b/include/bitmaps/oic_landscape
@@ -0,0 +1,41 @@
+/* XPM */
+static char * oic_landscape[] = {
+"32 32 6 1",
+" 	s None	c None",
+".	s black c black",
+"X	s ltgray c #c0c0c0",
+"o	s white c white",
+"O	s dkgray c #808080",
+"+	s blue c blue",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+" ......................         ",
+" .XXXXXXXXXXXXXXXXXXXX..        ",
+" .X.....XXXXXXXXXXXXXX.o.       ",
+" .XX.XXX.XXXXXXXXXXXXX.oo.      ",
+" .XX.XXX.XXXXXXXXXXXXX.ooo.     ",
+" .XX....XXXXXXXXXXXXXX.oooo.    ",
+" .XX.XXX.XXXXXXXXXXXXX.......   ",
+" .XX.XXX.XXXXXXXXXXXXXXXXXXX.O  ",
+" .X.....XXXXXXXXXXXXXXXXXXXX.O  ",
+" .XXXXXXXXXXXXXXXXXXXXXXXXXX.O  ",
+" .XXX++X+X++X+++X++X+++X+X+X.O  ",
+" .XXXXXXXXXXXXXXXXXXXXXXXXXX.O  ",
+" .X+X+X++X++X++X+X++X++X+X+X.O  ",
+" .XXXXXXXXXXXXXXXXXXXXXXXXXX.O  ",
+" .X+++X+++X+X++X++X+X++X+++X.O  ",
+" .XXXXXXXXXXXXXXXXXXXXXXXXXX.O  ",
+" .X++X+X+++X++++X++X++X++++X.O  ",
+" .XXXXXXXXXXXXXXXXXXXXXXXXXX.O  ",
+" ............................O  ",
+"  OOOOOOOOOOOOOOOOOOOOOOOOOOOO  ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                "};
diff --git a/include/bitmaps/oic_portrait b/include/bitmaps/oic_portrait
new file mode 100644
index 0000000..e4c3565
--- /dev/null
+++ b/include/bitmaps/oic_portrait
@@ -0,0 +1,41 @@
+/* XPM */
+static char * oic_portrait[] = {
+"32 32 6 1",
+" 	s None	c None",
+".	s black c black",
+"X	s ltgray c #c0c0c0",
+"o	s white c white",
+"O	s dkgray c #808080",
+"+	s blue c blue",
+"   ...................          ",
+"   .XXXXXXXXXXXXXXXXX..         ",
+"   .X.....XXXXXXXXXXX.o.        ",
+"   .XX.XXX.XXXXXXXXXX.oo.       ",
+"   .XX.XXX.XXXXXXXXXX.ooo.      ",
+"   .XX....XXXXXXXXXXX.oooo.     ",
+"   .XX.XXX.XXXXXXXXXX.......    ",
+"   .XX.XXX.XXXXXXXXXXXXXXXX.O   ",
+"   .X.....XXXXXXXXXXXXXXXXX.O   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXX.O   ",
+"   .XXX++X+X++X+X+X+++X+X+X.O   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXX.O   ",
+"   .X+X+X++X++X+X++X++X+X+X.O   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXX.O   ",
+"   .X+++X+++X+X++X+X++X+++X.O   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXX.O   ",
+"   .X++X+X+++X++X+X++X++++X.O   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXX.O   ",
+"   .X+X+X++X+X++X++X+X++X+X.O   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXX.O   ",
+"   .X+X+X++X++X+X++X++X+X+X.O   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXX.O   ",
+"   .X+++X+++X+X++X+X++X+++X.O   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXX.O   ",
+"   .X++X+X+++X++X+X++X++++X.O   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXX.O   ",
+"   .X+X+X++X+X++X++X+X++X+X.O   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXX.O   ",
+"   .X+++X++X+X+X+X+X++X+X+X.O   ",
+"   .XXXXXXXXXXXXXXXXXXXXXXX.O   ",
+"   .........................O   ",
+"   .OOOOOOOOOOOOOOOOOOOOOOOOO   "};
diff --git a/include/bitmaps/oic_wineicon b/include/bitmaps/oic_wineicon
new file mode 100644
index 0000000..a2d8b5c
--- /dev/null
+++ b/include/bitmaps/oic_wineicon
@@ -0,0 +1,43 @@
+/* XPM */
+static char * oic_wineicon[] = {
+"32 32 8 1",
+" 	s None	c None",
+".	s cyan c cyan",
+"X	s purple c #800080",
+"o	s black c black",
+"O	s white c white",
+"+	s dkyellow c #808000",
+"@	s yellow c yellow",
+"#	s red c red",
+"        .  .     .   .   . XX   ",
+"              .           XX    ",
+"          .        .    XXXX    ",
+"       .       .       . XXXX   ",
+"       oo.ooooooo.oooooooXX     ",
+"  oooooOOOOO.OOOOOO.OOOOXXooooo ",
+"   oOOOo.ooooooooooooooXXoOOOo  ",
+"    oOOO++@@@.@@@@@@.@@XXOOOo   ",
+"     o+++@@@@@@@@@@@@@XX+++o    ",
+"      o++++++++++++++XX+++o     ",
+"       o+++++++++++++XX++o      ",
+"        o+++++++++++XX++o       ",
+"         o++++++++++XX+o        ",
+"          o+++++##+XX+o         ",
+"           o+++####X+o          ",
+"            o+++##XXo           ",
+"             oo+++oo            ",
+"               ooo              ",
+"               oOo              ",
+"               oOo              ",
+"               oOo              ",
+"               oOo              ",
+"               oOo              ",
+"               oOo              ",
+"               oOo              ",
+"               oOo              ",
+"           oooooOooooo          ",
+"      oooooOOOoOOOoOOOooooo     ",
+"     oOOOOOOOoOOOOOoOOOOOOOo    ",
+"     oOOOOOOOOOOOOOOOOOOOOOo    ",
+"      oooooOOOOOOOOOOOooooo     ",
+"           ooooooooooo          "};
diff --git a/include/combo.h b/include/combo.h
index 4b0d444..cf301f0 100644
--- a/include/combo.h
+++ b/include/combo.h
@@ -3,15 +3,15 @@
  */
 
 
-typedef struct tagHEADCOMBO {
-    DWORD	dwStyle;
-    DWORD	dwState;
-    HWND	hWndEdit;
-    HWND	hWndLBox;
-	short	LastSel;
-	RECT	RectEdit;
-	BOOL	bRedrawFlag;
-} HEADCOMBO;
-typedef HEADCOMBO FAR* LPHEADCOMBO;
-
-
+typedef struct {
+  DWORD dwStyle;
+  DWORD dwState;
+  HWND  hWndEdit;
+  HWND  hWndLBox;
+  WORD  LBoxTop;
+  BOOL  DropDownVisible;
+  short LastSel;
+  RECT  RectEdit;
+  RECT  RectButton;
+  BOOL  bRedrawFlag;
+} HEADCOMBO,*LPHEADCOMBO;
diff --git a/include/commdlg.h b/include/commdlg.h
index 95eefb6..2161a6c 100644
--- a/include/commdlg.h
+++ b/include/commdlg.h
@@ -281,20 +281,14 @@
 *                 COMMDLG Resources placed in Wine SYSRES.DLL		    *
 ************************************************************************/
 
-#define OBM_FOLDER			32520
-#define OBM_FOLDER2			32521
-#define OBM_FLOPPY			32522
-#define OBM_HDISK			32523
-#define OBM_CDROM			32524
-
-#define OPENFILEDLG				3
-#define SAVEFILEDLG				4
-#define PRINTDLG				5
+#define OPENFILEDLG    			3
+#define SAVEFILEDLG    			4
+#define PRINTDLG	       		5
 #define PRINTSETUPDLG			6
-#define FONTDLG					7
-#define COLORDLG				8
-#define FINDDLG					9
-#define REPLACEDLG				10
+#define FONTDLG		       		7
+#define COLORDLG	       		8
+#define FINDDLG		       		9
+#define REPLACEDLG	       		10
 
 
 
diff --git a/include/dialog.h b/include/dialog.h
index ca1f418..02bf8d0 100644
--- a/include/dialog.h
+++ b/include/dialog.h
@@ -11,8 +11,11 @@
 
 extern BOOL DIALOG_Init(void);
 extern HWND DIALOG_GetFirstTabItem( HWND hwndDlg );
-extern int DialogBoxIndirectPtr( HINSTANCE hInst, LPCSTR dlgTemplate,
-                          HWND owner, WNDPROC dlgProc);
+extern int DialogBoxIndirectPtr(HINSTANCE hInst, LPCSTR dlgTemplate,
+				HWND owner, WNDPROC dlgProc);
+extern int DialogBoxIndirectParamPtr(HINSTANCE hInst, LPCSTR dlgTemplate,
+				     HWND owner, WNDPROC dlgProc, 
+				     LPARAM param);
 
 #ifndef WINELIB
 #pragma pack(1)
diff --git a/include/dlls.h b/include/dlls.h
index 681d821..813220b 100644
--- a/include/dlls.h
+++ b/include/dlls.h
@@ -12,9 +12,6 @@
 #define MAX_NAME_LENGTH		64
 
 
-struct ne_data {
-    struct ne_header_s *ne_header;
-};
 
 struct pe_data {
 	struct pe_header_s *pe_header;
@@ -36,7 +33,6 @@
     HANDLE hModule;
     int initialised;
     struct mz_header_s *mz_header;
-    struct ne_data *ne;
     struct pe_data *pe;
 };
 
@@ -45,64 +41,52 @@
 #define DLL	0
 #define EXE	1
 
-struct dll_table_entry_s
-{
-    /*
-     * 16->32 bit interface data
-     */
-    char *export_name;
-#ifdef WINESTAT
-    int used;			/* Number of times this function referenced */
-#endif
-};
 
 struct dll_table_s
 {
-    struct dll_table_entry_s *dll_table;
-    int dll_table_length;
-    int dll_number;
-    BYTE *code_start;    /* 32-bit address of DLL code */
-    BYTE *data_start;    /* 32-bit address of DLL data */
-    BYTE *module_start;  /* 32-bit address of the module data */
-    BYTE *module_end;
-    HMODULE hModule;
+    char *  name;          /* DLL name */
+    BYTE *  code_start;    /* 32-bit address of DLL code */
+    BYTE *  data_start;    /* 32-bit address of DLL data */
+    BYTE *  module_start;  /* 32-bit address of the module data */
+    BYTE *  module_end;
+    BOOL    used;          /* use MS provided if FALSE */
+    HMODULE hModule;       /* module created for this DLL */
 };
 
-struct dll_name_table_entry_s
-{
-    char *dll_name;
-    struct dll_table_s *table;
-    int dll_is_used;   /* use MS provided if set to zero */
-};
+#define DECLARE_DLL(name) \
+extern BYTE name##_Code_Start[]; \
+extern BYTE name##_Data_Start[]; \
+extern BYTE name##_Module_Start[]; \
+extern BYTE name##_Module_End[];
 
-extern struct dll_table_s KERNEL_table;
-extern struct dll_table_s USER_table;
-extern struct dll_table_s GDI_table;
-extern struct dll_table_s WIN87EM_table;
-extern struct dll_table_s MMSYSTEM_table;
-extern struct dll_table_s SHELL_table;
-extern struct dll_table_s SOUND_table;
-extern struct dll_table_s KEYBOARD_table;
-extern struct dll_table_s WINSOCK_table;
-extern struct dll_table_s STRESS_table;
-extern struct dll_table_s SYSTEM_table;
-extern struct dll_table_s TOOLHELP_table;
-extern struct dll_table_s MOUSE_table;
-extern struct dll_table_s COMMDLG_table;
-extern struct dll_table_s OLE2_table;
-extern struct dll_table_s OLE2CONV_table;
-extern struct dll_table_s OLE2DISP_table;
-extern struct dll_table_s OLE2NLS_table;
-extern struct dll_table_s OLE2PROX_table;
-extern struct dll_table_s OLECLI_table;
-extern struct dll_table_s OLESVR_table;
-extern struct dll_table_s COMPOBJ_table;
-extern struct dll_table_s STORAGE_table;
-extern struct dll_table_s WINPROCS_table;
-extern struct dll_table_s DDEML_table;
+DECLARE_DLL(KERNEL)
+DECLARE_DLL(USER)
+DECLARE_DLL(GDI)
+DECLARE_DLL(WIN87EM)
+DECLARE_DLL(MMSYSTEM)
+DECLARE_DLL(SHELL)
+DECLARE_DLL(SOUND)
+DECLARE_DLL(KEYBOARD)
+DECLARE_DLL(WINSOCK)
+DECLARE_DLL(STRESS)
+DECLARE_DLL(SYSTEM)
+DECLARE_DLL(TOOLHELP)
+DECLARE_DLL(MOUSE)
+DECLARE_DLL(COMMDLG)
+DECLARE_DLL(OLE2)
+DECLARE_DLL(OLE2CONV)
+DECLARE_DLL(OLE2DISP)
+DECLARE_DLL(OLE2NLS)
+DECLARE_DLL(OLE2PROX)
+DECLARE_DLL(OLECLI)
+DECLARE_DLL(OLESVR)
+DECLARE_DLL(COMPOBJ)
+DECLARE_DLL(STORAGE)
+DECLARE_DLL(WINPROCS)
+DECLARE_DLL(DDEML)
 
 #define N_BUILTINS	25
 
+extern struct dll_table_s dll_builtin_table[];
+
 #endif /* DLLS_H */
-
-
diff --git a/include/dos_fs.h b/include/dos_fs.h
index d0b2492..01a458c 100644
--- a/include/dos_fs.h
+++ b/include/dos_fs.h
@@ -32,6 +32,7 @@
 extern void DOS_ExpandToFullPath(char *filename, int drive);
 extern void DOS_ExpandToFullUnixPath(char *filename);
 extern char *DOS_GetRedirectedDir(int drive);
+extern void errno_to_doserr(void);
 
 extern char WindowsPath[256];
 
diff --git a/include/if1632.h b/include/if1632.h
deleted file mode 100644
index 96726dd..0000000
--- a/include/if1632.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef __WINE_IF1632_H
-#define __WINE_IF1632_H
-
-#include <wintypes.h>
-
-extern int CallToInit16(unsigned long csip, unsigned long sssp, 
-			unsigned short ds);
-extern int CallTo16cx(unsigned long csip, unsigned long dscx);
-extern int CallToDllEntry(unsigned long csip, unsigned long dscx, unsigned short di);
-extern void winestat(void);
-extern struct dll_table_s *FindDLLTable(char *dll_name);
-extern int FindOrdinalFromName(struct dll_table_entry_s *dll_table, char *func_name);
-extern int ReturnArg(int arg);
-
-extern BOOL RELAY_Init(void);
-
-#endif /* __WINE_IF1632_H */
diff --git a/include/ldt.h b/include/ldt.h
index 6fa19aa..db9d37f 100644
--- a/include/ldt.h
+++ b/include/ldt.h
@@ -45,7 +45,7 @@
 #define __AHSHIFT  3
 #define __AHINCR   (1 << __AHSHIFT)
 
-#define SELECTOR_TO_ENTRY(sel)  ((int)(sel) >> __AHSHIFT)
+#define SELECTOR_TO_ENTRY(sel)  (((int)(sel) & 0xffff) >> __AHSHIFT)
 #define ENTRY_TO_SELECTOR(i)    ((i) ? (((int)(i) << __AHSHIFT) | 7) : 0)
 #define IS_LDT_ENTRY_FREE(i)    (!(ldt_copy[(i)].base || ldt_copy[(i)].limit))
 #define IS_SELECTOR_FREE(sel)   (IS_LDT_ENTRY_FREE(SELECTOR_TO_ENTRY(sel)))
diff --git a/include/library.h b/include/library.h
deleted file mode 100644
index e161d66..0000000
--- a/include/library.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef __WINE_LIBRARY_H
-#define __WINE_LIBRARY_H
-
-extern HINSTANCE hInstMain;
-extern HINSTANCE hSysRes;
-extern struct w_files *GetFileInfo(unsigned short instance);
-extern int IsDLLLoaded(char *name);
-extern void InitDLL(struct w_files *wpnt);
-extern void InitializeLoadedDLLs(struct w_files *wpnt);
-extern HINSTANCE LoadImage(char *module, int filetype, int change_dir);
-
-extern struct dll_name_table_entry_s dll_builtin_table[];
-
-#endif /* __WINE_LIBRARY_H */
diff --git a/include/listbox.h b/include/listbox.h
index 307a74e..f3ab26f 100644
--- a/include/listbox.h
+++ b/include/listbox.h
@@ -1,39 +1,70 @@
 /*
- *   List Box definitions
+ *   Listbox definitions
  */
 
-
 typedef struct tagLISTSTRUCT {
-	DRAWITEMSTRUCT 	dis;
-	HANDLE		hMem;
+        MEASUREITEMSTRUCT mis;
+        UINT            itemState;
+        RECT            itemRect;
 	HANDLE		hData;
-	char		*itemText;
+	char            *itemText;
 	struct tagLISTSTRUCT *lpNext;
-} LISTSTRUCT;
-typedef LISTSTRUCT FAR* LPLISTSTRUCT;
+} LISTSTRUCT, *LPLISTSTRUCT;
 
-
-typedef struct tagHEADLIST {
-	UINT	FirstVisible;
-	UINT	ItemsCount;
-	short	ItemsVisible;
-	short	ColumnsVisible;
-	short	ItemsPerColumn;
-	short	ItemFocused;
-	short	PrevFocused;
-	short 	StdItemHeight;
-	short	ColumnsWidth;
-	short	DrawCtlType;
-	void	*lpFirst;
-	DWORD	dwStyle;
-	HWND	hWndLogicParent;
-	HFONT	hFont;
-	BOOL	bRedrawFlag;
+typedef struct {
+	WORD    FirstVisible;
+	WORD    ItemsCount;
+	WORD    ItemsVisible;
+	WORD    ColumnsVisible;
+	WORD    ItemsPerColumn;
+	short   ItemFocused;
+	short   PrevFocused;
+	WORD    StdItemHeight;
+	WORD    ColumnsWidth;
+	WORD    DrawCtlType;
+        WORD    CtlID;
+	LPLISTSTRUCT lpFirst;
+	DWORD   dwStyle;
+	HWND    hParent;
+	HFONT   hFont;
+	BOOL    bRedrawFlag;
 	WORD    iNumStops;
 	LPINT   TabStops;
 	HANDLE  hDrawItemStruct;
-/*	MDESC	*Heap; */
-} HEADLIST;
-typedef HEADLIST FAR* LPHEADLIST;
+        BOOL    needMeasure;
+/*	MDESC   *Heap; */
+} HEADLIST,*LPHEADLIST;
 
+/* shared code between listbox and combo controls */
+extern void CreateListBoxStruct(HWND hwnd, WORD CtlType, LONG styles, HWND parent);
+extern void DestroyListBoxStruct(LPHEADLIST lphl);
 
+extern void ListBoxSendNotification(LPHEADLIST lphl,HWND hwnd, WORD code);
+
+extern BOOL OWNER_DRAWN(LPHEADLIST lphl);
+extern BOOL HasStrings(LPHEADLIST lphl);
+
+extern LPLISTSTRUCT ListBoxGetItem(LPHEADLIST lphl, UINT uIndex);
+extern int ListMaxFirstVisible(LPHEADLIST lphl);
+extern int ListBoxScrollToFocus(LPHEADLIST lphl);
+extern int ListBoxAddString(LPHEADLIST lphl, LPSTR newstr);
+extern int ListBoxInsertString(LPHEADLIST lphl, UINT uIndex, LPSTR newstr);
+extern int ListBoxGetText(LPHEADLIST lphl, UINT uIndex, LPSTR OutStr);
+extern DWORD ListBoxGetItemData(LPHEADLIST lphl, UINT uIndex);
+extern int ListBoxSetItemData(LPHEADLIST lphl, UINT uIndex, DWORD ItemData);
+extern int ListBoxDeleteString(LPHEADLIST lphl, UINT uIndex);
+extern int ListBoxFindString(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr);
+extern int ListBoxResetContent(LPHEADLIST lphl);
+extern int ListBoxSetCurSel(LPHEADLIST lphl, WORD wIndex);
+extern int ListBoxSetSel(LPHEADLIST lphl, WORD wIndex, WORD state);
+extern int ListBoxGetSel(LPHEADLIST lphl, WORD wIndex);
+extern int ListBoxDirectory(LPHEADLIST lphl, UINT attrib, LPSTR filespec);
+extern int ListBoxGetItemRect(LPHEADLIST lphl, WORD wIndex, LPRECT rect);
+extern int ListBoxSetItemHeight(LPHEADLIST lphl, WORD wIndex, long height);
+extern int ListBoxFindNextMatch(LPHEADLIST lphl, WORD wChar);
+
+extern void ListBoxDrawItem (HWND hwnd, LPHEADLIST lphl, HDC hdc,
+			     LPLISTSTRUCT lpls, RECT *rect, WORD itemAction,
+			     WORD itemState);
+extern int ListBoxFindMouse(LPHEADLIST lphl, int X, int Y);
+extern void ListBoxAskMeasure(LPHEADLIST lphl, LPLISTSTRUCT lpls);
diff --git a/include/mmsystem.h b/include/mmsystem.h
index 815f431..3607e5c 100644
--- a/include/mmsystem.h
+++ b/include/mmsystem.h
@@ -232,11 +232,11 @@
 
 /* general format structure common to all formats */
 typedef struct {
-    WORD    wFormatTag;        /* format type */
-    WORD    nChannels;         /* number of channels (i.e. mono, stereo, etc.) */
-    DWORD   nSamplesPerSec;    /* sample rate */
-    DWORD   nAvgBytesPerSec;   /* for buffer estimation */
-    WORD    nBlockAlign;       /* block size of data */
+    WORD    wFormatTag;						/* format type */
+    WORD    nChannels; 						/* number of channels */
+    DWORD   nSamplesPerSec WINE_PACKED;		/* sample rate */
+    DWORD   nAvgBytesPerSec WINE_PACKED;	/* for buffer estimation */
+    WORD    nBlockAlign; 					/* block size of data */
 } WAVEFORMAT;
 typedef WAVEFORMAT FAR  *LPWAVEFORMAT;
 
diff --git a/include/module.h b/include/module.h
index d3973a0..58a3061 100644
--- a/include/module.h
+++ b/include/module.h
@@ -44,7 +44,7 @@
     WORD    truetype;         /* Set to 2 if TrueType font */
     BYTE    os_flags;         /* Operating system flags */
     BYTE    misc_flags;       /* Misc. flags */
-    WORD    reserved;         /* Same value as import_table */
+    HANDLE  dlls_to_init;     /* List of DLLs to initialize */
     HANDLE  nrname_handle;    /* Handle to non-resident name table in memory */
     WORD    min_swap_area;    /* Min. swap area size */
     WORD    expected_version; /* Expected Windows version */
@@ -71,6 +71,14 @@
     WORD    selector;  /* Selector of segment in memory */
 } SEGTABLEENTRY;
 
+  /* Parameters for LoadModule() */
+typedef struct
+{
+    HANDLE hEnvironment;  /* Environment segment */
+    SEGPTR cmdLine;       /* Command-line */
+    SEGPTR showCmd;       /* Code for ShowWindow() */
+    SEGPTR reserved;
+} LOADPARAMS;
 
 #define NE_SEG_TABLE(pModule) \
     ((SEGTABLEENTRY *)((char *)(pModule) + (pModule)->seg_table))
@@ -87,6 +95,11 @@
 extern LPSTR MODULE_GetModuleName( HMODULE hModule );
 extern WORD MODULE_GetOrdinal( HMODULE hModule, char *name );
 extern DWORD MODULE_GetEntryPoint( HMODULE hModule, WORD ordinal );
-extern void MODULE_FixupPrologs( HMODULE hModule );
+extern BOOL MODULE_SetEntryPoint( HMODULE hModule, WORD ordinal, WORD offset );
+extern LPSTR MODULE_GetEntryPointName( HMODULE hModule, WORD ordinal );
+
+extern BOOL NE_LoadSegment( HMODULE hModule, WORD segnum );
+extern void NE_FixupPrologs( HMODULE hModule );
+extern void NE_InitializeDLLs( HMODULE hModule );
 
 #endif  /* _WINE_MODULE_H */
diff --git a/include/ne_image.h b/include/ne_image.h
deleted file mode 100644
index b4d3ea7..0000000
--- a/include/ne_image.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __WINE_NE_IMAGE_H
-#define __WINE_NE_IMAGE_H
-
-extern int NE_FixupSegment(struct w_files *wpnt, int segment_num);
-extern int NE_unloadImage(struct w_files *wpnt);
-extern int NE_StartProgram( HMODULE hModule );
-extern BOOL NE_InitDLL( HMODULE hModule );
-extern HINSTANCE NE_LoadImage(struct w_files *wpnt);
-
-#endif /* __WINE_NE_IMAGE_H */
diff --git a/include/options.h b/include/options.h
index 095fa88..80b8a73 100644
--- a/include/options.h
+++ b/include/options.h
@@ -19,6 +19,7 @@
     int    debug;
     int    allowReadOnly;   /* Opening a read only file will succeed even
 			       if write access is requested */
+    int    enhanced;        /* Start Wine in enhanced mode */ 
 };
 
 extern struct options Options;
diff --git a/include/pe_image.h b/include/pe_image.h
index 5259603..d7fceee 100644
--- a/include/pe_image.h
+++ b/include/pe_image.h
@@ -7,4 +7,18 @@
 extern HINSTANCE PE_LoadImage(struct w_files *wpnt);
 extern void my_wcstombs(char * result, u_short * source, int len);
 
+typedef struct _WIN32_function{
+    char *name;
+    void *definition;
+} WIN32_function;
+
+typedef struct _WIN32_builtin{
+    char *name;
+    WIN32_function *functions;
+    int size;
+    struct _WIN32_builtin *next;
+} WIN32_builtin;
+
+extern WIN32_builtin *WIN32_builtin_list;
+
 #endif /* __WINE_PE_IMAGE_H */
diff --git a/include/peexe.h b/include/peexe.h
index d5ce342..6f54811 100644
--- a/include/peexe.h
+++ b/include/peexe.h
@@ -138,9 +138,10 @@
 struct PE_Import_Directory
 {
   u_int Import_List;
-  u_int reserved[2];
+  u_int TimeDate;
+  u_int Forwarder;
   u_int ModuleName;
-  u_int reserved1;
+  u_int Thunk_List;
 };
 
 struct pe_import_name
diff --git a/include/prototypes.h b/include/prototypes.h
index 9fa03da..b2288c6 100644
--- a/include/prototypes.h
+++ b/include/prototypes.h
@@ -8,8 +8,6 @@
 
 #include <sys/types.h>
 
-#include "neexe.h"
-#include "msdos.h"
 #include "windows.h"
 
 #ifndef WINELIB
@@ -26,20 +24,11 @@
 
 /* loader/wine.c */
 
-extern void myerror(const char *s);
-
-extern char *GetFilenameFromInstance(unsigned short instance);
-extern HINSTANCE LoadImage(char *modulename, int filetype, int change_dir);
 extern int _WinMain(int argc, char **argv);
-extern void InitializeLoadedDLLs();
 
 /* misc/spy.c */
 
 extern void SpyInit(void);
 
-/* controls/widget.c */
-
-extern BOOL WIDGETS_Init(void);
-
 #endif /* WINELIB */
 #endif /* _WINE_PROTOTYPES_H */
diff --git a/include/selectors.h b/include/selectors.h
index 9f7ef80..83a5309 100644
--- a/include/selectors.h
+++ b/include/selectors.h
@@ -16,16 +16,8 @@
                                    enum seg_type type, BOOL is32bit,
                                    BOOL readonly );
 
-#include "dlls.h"
-
 extern void CreateSelectors(void);
 
-extern unsigned int GetEntryDLLName(char *dll_name, char *function,
-                                    WORD *sel, WORD *offset);
-extern unsigned int GetEntryDLLOrdinal(char *dll_name, int ordinal,
-                                       WORD *sel, WORD *offset);
-extern void InitSelectors(void);
-
 extern WNDPROC GetWndProcEntry16( char *name );
 
 #endif /* __WINE_SELECTORS_H */
diff --git a/include/stackframe.h b/include/stackframe.h
index a6a9ac7..8196461 100644
--- a/include/stackframe.h
+++ b/include/stackframe.h
@@ -54,11 +54,17 @@
 
   /* Saved 32-bit stack */
 extern DWORD IF1632_Saved32_esp;
-
+extern SEGPTR IF1632_Stack32_base;
 
 #define CURRENT_STACK16 \
     ((STACK16FRAME *)PTR_SEG_OFF_TO_LIN(IF1632_Saved16_ss,IF1632_Saved16_sp))
 
 #define CURRENT_DS   (CURRENT_STACK16->ds)
 
+  /* Make a segmented pointer from a pointer to a variable located */
+  /* on the 32-bit stack for the current task. */
+#define MAKE_SEGPTR(ptr) \
+     ((SEGPTR)IF1632_Stack32_base + \
+      ((DWORD)(ptr) - (DWORD)PTR_SEG_TO_LIN(IF1632_Stack32_base)))
+
 #endif /* WINE_STACKFRAME_H */
diff --git a/include/task.h b/include/task.h
index a69fea7..e78f6d5 100644
--- a/include/task.h
+++ b/include/task.h
@@ -58,13 +58,13 @@
     BYTE    unused1;
     HGLOBAL hStack32;                   /* Handle to 32-bit stack */
     WORD    hSelf;                      /* Selector of this TDB */
-    WORD    unused3;
+    HANDLE  hPrevInstance;              /* Previous instance of the module */
     DWORD   esp;                        /* 32-bit stack pointer */
     WORD    ctrlword8087;               /* 80x87 control word */
     WORD    flags;                      /* Task flags */
     WORD    error_flags;                /* Error handling flags */
     WORD    version;                    /* Expected Windows version */
-    HANDLE  hInstance;                  /* Instance handle  for this task */
+    HANDLE  hInstance;                  /* Instance handle for this task */
     HMODULE hModule;                    /* Module handle */
     HANDLE  hQueue;                     /* Selector of task message queue */
     HTASK   hParent;                    /* Selector of TDB of parent task */
@@ -85,7 +85,7 @@
     DWORD   dta WINE_PACKED;            /* Current DTA */
     BYTE    curdrive;                   /* Current drive */
     BYTE    curdir[65];                 /* Current directory */
-    WORD    unused5;
+    WORD    nCmdShow;                   /* cmdShow parameter to WinMain */
     HTASK   hYieldTo;                   /* Next task to schedule */
     DWORD   dlls_to_init;               /* Ptr to list of DLL to initialize */
     HANDLE  hCSAlias;                   /* Code segment alias for this TDB */
@@ -108,6 +108,10 @@
 #pragma pack(4)
 #endif
 
+extern HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance,
+                              HANDLE hPrevInstance, HANDLE hEnvironment,
+                              char *cmdLine, WORD cmdShow );
+
   /* TASK_Reschedule() 16-bit entry point */
 extern FARPROC RELAY_RescheduleProcAddr;
 
diff --git a/include/texts.h b/include/texts.h
deleted file mode 100644
index 343b399..0000000
--- a/include/texts.h
+++ /dev/null
@@ -1,26 +0,0 @@
-
-/*
- * texts.h - String constants are read from Xresources/app-defaults
- * (c) 1994 Jochen Hein ( Hein@Student.TU-Clausthal.de )
- */
-
-/*
- * Type-description for buttons
- */
-
-typedef struct tButtonDesc {
-  char *Label;              /* Label of the Button */
-  char Hotkey;               /* Hotkey to press this Button */
-} ButtonDesc;
-
-typedef struct tButtonTexts {
-  ButtonDesc Yes;
-  ButtonDesc No;
-  ButtonDesc Ok;
-  ButtonDesc Cancel;
-  ButtonDesc Abort;
-  ButtonDesc Retry;
-  ButtonDesc Ignore;
-} ButtonTexts;
-
-
diff --git a/include/windows.h b/include/windows.h
index f74aa3e..76ec59d 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -3,7 +3,7 @@
 #ifndef WINDOWS_H
 #define WINDOWS_H
 
-#include <wintypes.h>
+#include "wintypes.h"
 
 #ifndef WINELIB
 #pragma pack(1)
@@ -48,8 +48,6 @@
 
   /* Window classes */
 
-typedef LONG (*WNDPROC)(HWND, UINT, WPARAM, LPARAM);
-
 typedef struct {
 	WORD	style;
 	WNDPROC	lpfnWndProc WINE_PACKED;
@@ -700,6 +698,10 @@
 #define TT_AVAILABLE        0x0001
 #define TT_ENABLED          0x0002
 
+/* Get/SetSystemPaletteUse() values */
+#define SYSPAL_STATIC   1
+#define SYSPAL_NOSTATIC 2
+
 typedef struct tagPALETTEENTRY
 {
 	BYTE peRed, peGreen, peBlue, peFlags;
@@ -1313,6 +1315,12 @@
 #define OBM_RGARROWI        32735
 #define OBM_LFARROWI        32734
 
+#define OBM_FOLDER          32733
+#define OBM_FOLDER2         32732
+#define OBM_FLOPPY          32731
+#define OBM_HDISK           32730
+#define OBM_CDROM           32729
+
 #define OBM_OLD_CLOSE       32767
 #define OBM_SIZE            32766
 #define OBM_OLD_UPARROW     32765
@@ -1346,6 +1354,9 @@
 #define OIC_QUES            32514
 #define OIC_BANG            32515
 #define OIC_NOTE            32516
+#define OIC_PORTRAIT        32517
+#define OIC_LANDSCAPE       32518
+#define OIC_WINEICON        32519
 
   /* Stock GDI objects for GetStockObject() */
 
@@ -2131,6 +2142,8 @@
 #define GMEM_DDESHARE       0x2000
 #define GMEM_NOTIFY         0x4000
 #define GMEM_LOWER          GMEM_NOT_BANKED
+#define GMEM_DISCARDED      0x4000
+#define GMEM_LOCKCOUNT      0x00ff
 
 #define GHND                (GMEM_MOVEABLE | GMEM_ZEROINIT)
 #define GPTR                (GMEM_FIXED | GMEM_ZEROINIT)
@@ -2310,20 +2323,20 @@
 
 
 #define F(ret,name) ret name(void);
-#define Fa(ret,name,t1,a1) ret name(t1 a1);
-#define Fb(ret,name,t1,a1,t2,a2) ret name(t1 a1,t2 a2);
-#define Fc(ret,name,t1,a1,t2,a2,t3,a3) ret name(t1 a1,t2 a2,t3 a3);
-#define Fd(ret,name,t1,a1,t2,a2,t3,a3,t4,a4) ret name(t1 a1,t2 a2,t3 a3,t4 a4);
-#define Fe(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5) ret name( t1 a1,t2 a2,t3 a3,t4 a4,t5 a5);
-#define Ff(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6) ret name(t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6);
-#define Fg(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7) ret name( t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7);
-#define Fh(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8) ret name(t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8);
-#define Fi(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9) ret name(t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9);
-#define Fj(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10) ret name(t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10);
-#define Fk(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11) ret name (t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10,t11 a11);
-#define Fl(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11,t12,a12) ret name(t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10,t11 a11,t12 a12);
-#define Fm(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11,t12,a12,t13,a13) ret name(t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10,t11 a11,t12 a12,t13 a13);
-#define Fn(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11,t12,a12,t13,a13,t14,a14) ret name(t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10,t11 a11,t12 a12,t13 a13,t14 a14);
+#define Fa(ret,name,t1,a1) ret name(t1);
+#define Fb(ret,name,t1,a1,t2,a2) ret name(t1,t2);
+#define Fc(ret,name,t1,a1,t2,a2,t3,a3) ret name(t1,t2,t3);
+#define Fd(ret,name,t1,a1,t2,a2,t3,a3,t4,a4) ret name(t1,t2,t3,t4);
+#define Fe(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5) ret name(t1,t2,t3,t4,t5);
+#define Ff(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6) ret name(t1,t2,t3,t4,t5,t6);
+#define Fg(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7) ret name(t1,t2,t3,t4,t5,t6,t7);
+#define Fh(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8) ret name(t1,t2,t3,t4,t5,t6,t7,t8);
+#define Fi(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9) ret name(t1,t2,t3,t4,t5,t6,t7,t8,t9);
+#define Fj(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10) ret name(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10);
+#define Fk(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11) ret name(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11);
+#define Fl(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11,t12,a12) ret name(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12);
+#define Fm(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11,t12,a12,t13,a13) ret name(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13);
+#define Fn(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11,t12,a12,t13,a13,t14,a14) ret name(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14);
 
 int wsprintf(LPSTR a,LPSTR b,...);
 
@@ -2459,7 +2472,7 @@
 Fa(HANDLE,GetModuleHandle,LPCSTR,a)
 Fa(HANDLE,GetStockObject,int,a)
 Fa(HANDLE,GetWindowTask,HWND,a)
-Fa(HANDLE,LoadLibrary,LPSTR,a)
+Fa(HANDLE,LoadLibrary,LPCSTR,a)
 Fa(HANDLE,LocalFree,HANDLE,a)
 Fa(HANDLE,LocalHandle,WORD,a)
 Fa(HANDLE,SetMetaFileBits,HANDLE,a)
@@ -2528,6 +2541,7 @@
 Fa(WORD,GetROP2,HDC,a)
 Fa(WORD,GetRelAbs,HDC,a)
 Fa(WORD,GetStretchBltMode,HDC,a)
+Fa(WORD,GetSystemPaletteUse,HDC,a)
 Fa(WORD,GetTextAlign,HDC,a)
 Fa(WORD,GlobalDOSFree,WORD,a)
 Fa(WORD,GlobalFlags,HGLOBAL,a)
@@ -2644,7 +2658,7 @@
 Fb(HANDLE,CopyMetaFile,HANDLE,a,LPSTR,b)
 Fb(HANDLE,GetProp,HWND,a,SEGPTR,b)
 Fb(HANDLE,LoadAccelerators,HANDLE,a,SEGPTR,b)
-Fb(HANDLE,LoadModule,LPSTR,a,LPVOID,b)
+Fb(HANDLE,LoadModule,LPCSTR,a,LPVOID,b)
 Fb(HANDLE,LoadResource,HANDLE,a,HANDLE,b)
 Fb(HANDLE,LocalAlloc,WORD,a,WORD,b)
 Fb(HANDLE,RemoveProp,HWND,a,SEGPTR,b)
@@ -2689,7 +2703,6 @@
 Fb(WORD,GetMenuItemID,HMENU,a,int,b)
 Fb(WORD,GetNearestPaletteIndex,HPALETTE,a,DWORD,b)
 Fb(WORD,GetSystemDirectory,LPSTR,a,WORD,b)
-Fb(WORD,GetSystemPaletteUse,HDC,a,WORD,b)
 Fb(WORD,GetWindowWord,HWND,a,short,b)
 Fb(WORD,GetWindowsDirectory,LPSTR,a,WORD,b)
 Fb(WORD,IsDlgButtonChecked,HWND,a,WORD,b)
@@ -2803,6 +2816,8 @@
 Fc(INT,OpenFile,LPSTR,a,LPOFSTRUCT,b,WORD,c)
 Fc(INT,_lread,INT,a,LPSTR,b,WORD,c)
 Fc(INT,_lwrite,INT,a,LPSTR,b,WORD,c)
+Fc(LONG,_hread,INT,a,LPSTR,b,LONG,c)
+Fc(LONG,_hwrite,INT,a,LPSTR,b,LONG,c)
 Fc(LONG,GetBitmapBits,HBITMAP,a,LONG,b,LPSTR,c)
 Fc(LONG,SetBitmapBits,HBITMAP,a,LONG,b,LPSTR,c)
 Fc(LONG,SetClassLong,HWND,a,short,b,LONG,c)
@@ -2980,7 +2995,7 @@
 Fi(BOOL,GrayString,HDC,a,HBRUSH,b,FARPROC,gsprc,LPARAM,lParam,INT,cch,INT,x,INT,y,INT,cx,INT,cy)
 Fi(BOOL,Pie,HDC,a,int,xLeft,int,yTop,int,xRight,int,yBottom,int,xStart,int,yStart,int,xEnd,int,yEnd)
 Fk(BOOL,StretchBlt,HDC,a,short,b,short,c,short,d,short,e,HDC,f,short,g,short,h,short,i,short,j,DWORD,k)
-Fk(HWND,CreateWindow,LPSTR,szAppName,LPSTR,Label,DWORD,ol,short,x,short,y,short,w,short,h,HWND,d,HMENU,e,,HANDLE i,SEGPTR,g)
+Fk(HWND,CreateWindow,LPSTR,a,LPSTR,b,DWORD,c,short,d,short,e,short,f,short,g,HWND,h,HMENU,i,HANDLE,j,SEGPTR,k)
 Fl(HWND,CreateWindowEx,DWORD,a,LPSTR,b,LPSTR,c,DWORD,d,short,e,short,f,short,g,short,h,HWND,i,HMENU,j,HANDLE,k,SEGPTR,l)
 Fl(int,SetDIBitsToDevice,HDC,a,short,b,short,c,WORD,d,WORD,e,WORD,f,WORD,g,WORD,h,WORD,i,LPSTR,j,LPBITMAPINFO,k,WORD,l)
 Fm(int,StretchDIBits,HDC,a,WORD,b,WORD,c,WORD,d,WORD,e,WORD,f,WORD,g,WORD,h,WORD,i,LPSTR,j,LPBITMAPINFO,k,WORD,l,DWORD,m)
diff --git a/include/wine.h b/include/wine.h
index 101f50e..5dee98a 100644
--- a/include/wine.h
+++ b/include/wine.h
@@ -36,7 +36,15 @@
 #define WINE_CODE_SELECTOR 0x23
 #endif  /* linux */
 
-#if defined(__NetBSD__) || defined(__FreeBSD__)
+#ifdef __NetBSD__
+#include <signal.h>
+#define sigcontext_struct sigcontext
+#define HZ 100
+#define WINE_DATA_SELECTOR 0x1f
+#define WINE_CODE_SELECTOR 0x17
+#endif
+
+#ifdef __FreeBSD__
 #include <signal.h>
 #define sigcontext_struct sigcontext
 #define HZ 100
diff --git a/include/winerror.h b/include/winerror.h
new file mode 100644
index 0000000..e1c1dbf
--- /dev/null
+++ b/include/winerror.h
@@ -0,0 +1,2 @@
+extern int WIN32_LastError;
+#define	ERROR_CALL_NOT_IMPLEMENTED	120
diff --git a/include/wintypes.h b/include/wintypes.h
index ade3d57..e63f97a 100644
--- a/include/wintypes.h
+++ b/include/wintypes.h
@@ -25,8 +25,10 @@
 typedef void *LPVOID;
 #ifdef WINELIB
 typedef long (*FARPROC)();
+typedef LONG (*WNDPROC)(WORD,WORD,WORD,LONG);
 #else
 typedef SEGPTR FARPROC;
+typedef SEGPTR WNDPROC;
 #endif
 typedef FARPROC DLGPROC;
 typedef int CATCHBUF[9];
@@ -69,9 +71,8 @@
 #define WINAPI              PASCAL
 #define CALLBACK            PASCAL
 
-#ifndef NULL
-#define NULL (0)
-#endif
+#undef NULL
+#define NULL 0
 
 #ifdef WINELIB
 #define WINE_PACKED
@@ -85,6 +86,9 @@
 #define LOWORD(l)           ((WORD)(DWORD)(l))
 #define HIWORD(l)           ((WORD)((DWORD)(l) >> 16))
 
+#define SLOWORD(l)           ((INT)(LONG)(l))
+#define SHIWORD(l)           ((INT)((LONG)(l) >> 16))
+
 #define MAKELONG(low, high) ((LONG)(((WORD)(low)) | \
 				    (((DWORD)((WORD)(high))) << 16)))
 
diff --git a/loader/Imakefile b/loader/Imakefile
index b3863a6..9c15c28 100644
--- a/loader/Imakefile
+++ b/loader/Imakefile
@@ -13,7 +13,6 @@
 	pe_resource.c \
 	selector.c \
 	signal.c \
-	library.c \
 	resource.c \
 	task.c 
 
diff --git a/loader/ldt.c b/loader/ldt.c
index 3654f2e..73e1260 100644
--- a/loader/ldt.c
+++ b/loader/ldt.c
@@ -180,12 +180,17 @@
     }
 #else  /* WINELIB */
 
-#ifdef linux
     long buffer[2*LDT_SIZE];
     ldt_entry content;
+    int n;
 
-    modify_ldt( 0, buffer, sizeof(buffer) );
-    for (i = 0; i < LDT_SIZE; i++)
+#ifdef linux
+    n = modify_ldt( 0, buffer, sizeof(buffer) ) / 8;
+#endif  /* linux */
+#if defined(__NetBSD__) || defined(__FreeBSD__)
+    n = i386_get_ldt( 0, (union descriptor *)buffer, LDT_SIZE );
+#endif  /* __NetBSD__ || __FreeBSD__ */
+    for (i = 0; i < n; i++)
     {
         LDT_BytesToEntry( &buffer[2*i], &content );
         if (content.base || content.limit)
@@ -197,25 +202,5 @@
                     content.type );
         }
     }
-#endif  /* linux */
-
-#if defined(__NetBSD__) || defined(__FreeBSD__)
-    long buffer[2*LDT_SIZE];
-    ldt_entry content;
-
-    i386_get_ldt( 0, (union descriptor *)buffer, LDT_SIZE );
-    for (i = 0; i < LDT_SIZE; i++)
-    {
-        LDT_BytesToEntry( buffer[2*i], &content );
-        if (content.base || content.limit)
-        {
-            fprintf( stderr, "%04x: sel=%04x base=%08lx limit=%05lx %s type=%d\n",
-                    i, ENTRY_TO_SELECTOR(i),
-                    content.base, content.limit,
-                    content.limit_in_pages ? "(pages)" : "(bytes)",
-                    content.type );
-        }
-    }
-#endif  /* __NetBSD__ || __FreeBSD__ */
 #endif  /* WINELIB */
 }
diff --git a/loader/library.c b/loader/library.c
deleted file mode 100644
index e303bbb..0000000
--- a/loader/library.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- *        Module & Library functions
-static char Copyright[] = "Copyright 1993, 1994 Martin Ayotte, Robert J. Amstadt, Erik Bos";
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include "neexe.h"
-#include "dlls.h"
-#include "if1632.h"
-#include "wineopts.h"
-#include "arch.h"
-#include "options.h"
-#include "dos_fs.h"
-#include "windows.h"
-#include "task.h"
-#include "toolhelp.h"
-#include "selectors.h"
-#include "prototypes.h"
-#include "library.h"
-#include "ne_image.h"
-#include "pe_image.h"
-#include "module.h"
-#include "stddebug.h"
-#include "debug.h"
-
-struct w_files *wine_files = NULL;
-static char *DLL_Extensions[] = { "dll", NULL };
-static char *EXE_Extensions[] = { "exe", NULL };
-
-#define IS_BUILTIN_DLL(handle) ((handle >> 8) == 0xff) 
-
-/**********************************************************************/
-
-void ExtractDLLName(char *libname, char *temp)
-{
-    int i;
-    
-    strcpy(temp, libname);
-    if (strchr(temp, '\\') || strchr(temp, '/'))
-	for (i = strlen(temp) - 1; i ; i--) 
-		if (temp[i] == '\\' || temp[i] == '/') {
-			strcpy(temp, temp + i + 1);
-			break;
-		}
-    for (i = strlen(temp) - 1; i ; i--) 
-	if (temp[i] == '.') {
-		temp[i] = 0;
-		break;
-	}
-}
-
-struct w_files *GetFileInfo(unsigned short instance)
-{
-    register struct w_files *w = wine_files;
-
-    while (w && w->hinstance != instance)
-	w = w->next;
-    
-    return w;
-}
-/*
-int IsDLLLoaded(char *name)
-{
-	struct w_files *wpnt;
-
-	if(FindDLLTable(name))
-		return 1;
-
-	for(wpnt = wine_files; wpnt; wpnt = wpnt->next)
-		if(strcmp(wpnt->name, name) == 0 )
-			return 1;
-
-	return 0;
-}
-*/
-void InitDLL(struct w_files *wpnt)
-{
-	if (wpnt->ne) 
-		NE_InitDLL(wpnt->hModule);
-	else
-		PE_InitDLL(wpnt);
-}
-
-void InitializeLoadedDLLs(struct w_files *wpnt)
-{
-    static flagReadyToRun = 0;
-    struct w_files *final_wpnt;
-
-    dprintf_module(stddeb,"InitializeLoadedDLLs(%p)\n", wpnt);
-
-    if (wpnt == NULL)
-    {
-	flagReadyToRun = 1;
-	dprintf_module(stddeb,"Initializing DLLs\n");
-    }
-    
-    if (!flagReadyToRun)
-	return;
-
-#if 1
-    if (wpnt != NULL)
-	dprintf_module(stddeb,"Initializing %s\n", wpnt->name);
-#endif
-
-    /*
-     * Initialize libraries
-     */
-    if (!wpnt)
-    {
-	wpnt = wine_files;
-	final_wpnt = NULL;
-    }
-    else
-    {
-	final_wpnt = wpnt->next;
-    }
-    
-    for( ; wpnt != final_wpnt; wpnt = wpnt->next)
-	InitDLL(wpnt);
-}
-
-/**********************************************************************
- *			LoadImage
- * Load one executable into memory
- */
-HINSTANCE LoadImage(char *module, int filetype, int change_dir)
-{
-    HINSTANCE handle;
-    struct w_files *wpnt, *wpnt1;
-    char buffer[256], header[2], modulename[64], *fullname;
-
-    ExtractDLLName(module, modulename);
-    dprintf_module(stddeb,"LoadImage [%s]\n", module);
-    /* built-in one ? */
-    if (FindDLLTable(modulename)) {
-	return GetModuleHandle(modulename);
-    }
-    
-    /* already loaded ? */
-    for (wpnt = wine_files ; wpnt ; wpnt = wpnt->next)  {
-      if (strcasecmp(wpnt->name, modulename) == 0 && filetype == wpnt->type) {
-	return wpnt->hinstance;
-      }
-    }
-
-    /*
-     * search file
-     */
-    fullname = DOS_FindFile(buffer, sizeof(buffer), module, 
-			(filetype == EXE ? EXE_Extensions : DLL_Extensions), 
-			WindowsPath);
-    if (fullname == NULL)
-    {
-    	fprintf(stderr, "LoadImage: I can't find %s.dll | %s.exe !\n",
-		module, module);
-	return 2;
-    }
-
-    fullname = DOS_GetDosFileName(fullname);
-    
-    dprintf_module(stddeb,"LoadImage: loading %s (%s)\n           [%s]\n", 
-	    module, buffer, fullname);
-
-    if (change_dir && fullname)
-    {
-	char dirname[256];
-	char *p;
-
-	strcpy(dirname, fullname);
-	p = strrchr(dirname, '\\');
-	*p = '\0';
-
-	DOS_SetDefaultDrive(dirname[0] - 'A');
-	DOS_ChangeDir(dirname[0] - 'A', dirname + 2);
-    }
-
-    /* First allocate a spot to store the info we collect, and add it to
-     * our linked list if we could load the file.
-     */
-
-    wpnt = (struct w_files *) malloc(sizeof(struct w_files));
-
-    /*
-     * Open file for reading.
-     */
-    wpnt->fd = open(buffer, O_RDONLY);
-    if (wpnt->fd < 0)
-	return 2;
-
-    /* 
-     * Establish header pointers.
-     */
-    wpnt->filename = strdup(buffer);
-    wpnt->name = strdup(modulename);
-    wpnt->type = filetype;
-    wpnt->initialised = FALSE;
-
-    /* read mz header */
-    wpnt->mz_header = (struct mz_header_s *) malloc(sizeof(struct mz_header_s));;
-    lseek(wpnt->fd, 0, SEEK_SET);
-    if (read(wpnt->fd, wpnt->mz_header, sizeof(struct mz_header_s)) !=
-	sizeof(struct mz_header_s))
-    {
-	fprintf(stderr, "Unable to read MZ header from file '%s'\n", buffer);
-        exit(1);
-    }
-
-      /* This field is ignored according to "Windows Internals", p.242 */
-#if 0
-    if (wpnt->mz_header->must_be_0x40 != 0x40)
-	myerror("This is not a Windows program");
-#endif
-
-    /* read first two bytes to determine filetype */
-    lseek(wpnt->fd, wpnt->mz_header->ne_offset, SEEK_SET);
-    read(wpnt->fd, &header, sizeof(header));
-
-    handle = 0;
-
-    /* 
-     * Stick this file into the list of loaded files so we don't try to reload
-     * it again if another module references this module.  Do this before
-     * calling NE_LoadImage because we might get back here before NE_loadImage
-     * returns.
-     */
-    if(wine_files == NULL)
-       wine_files = wpnt;
-    else {
-	 wpnt1 = wine_files;
-	 while(wpnt1->next)
-	    wpnt1 = wpnt1->next;
-	 wpnt1->next = wpnt;
-    }
-    wpnt->next = NULL;
-
-    if (header[0] == 'N' && header[1] == 'E')
-    	handle = NE_LoadImage(wpnt);
-    if (header[0] == 'P' && header[1] == 'E')
-        handle = PE_LoadImage(wpnt);
-    wpnt->hinstance = handle;
-
-    if (handle > 32) {
-	return handle;
-    } else {
-	fprintf(stderr, "wine: (%s) unknown fileformat !\n", wpnt->filename);
-
-	/* Remove this module from the list of loaded modules */
-	if (wine_files == wpnt)
-	    wine_files = NULL;
-	else
-	    wpnt1->next = NULL;
-	close(wpnt->fd);
-	free(wpnt->filename);
-	free(wpnt->name);
-	free(wpnt);
-
-	return 14;
-    }
-}
-
-/**********************************************************************
- *				LoadLibrary	[KERNEL.95]
- */
-HANDLE LoadLibrary(LPSTR libname)
-{
-	HANDLE h;
-	
-        dprintf_module(stddeb,"LoadLibrary: (%08x) %s\n",(int)libname,libname);
-
-	if ((h = LoadImage(libname, DLL, 0)) < 32)
-		return h;
-
-	if (!IS_BUILTIN_DLL(h))
-		InitDLL(GetFileInfo(h));
-	
-	return h;
-}
-
-/**********************************************************************
- *				FreeLibrary	[KERNEL.96]
- */
-void FreeLibrary(HANDLE hLib)
-{
-	dprintf_module(stddeb,"FreeLibrary(%04X);\n", hLib);
-
-	/* built-in dll ? */
-	if (IS_BUILTIN_DLL(hLib) || hLib == 0 || hLib == hSysRes) 
-	    	return;
-
-/*
-	while (lpMod != NULL) {
-		if (lpMod->hInst == hLib) {
-			if (lpMod->Count == 1) {
-				wpnt = GetFileInfo(hLib);
-				if (wpnt->ne)
-					NE_UnloadImage(wpnt);
-				else
-					PE_UnloadImage(wpnt);
-				if (hLib != (HANDLE)NULL) GlobalFree(hLib);
-				if (lpMod->ModuleName != NULL) free(lpMod->ModuleName);
-				if (lpMod->FileName != NULL) free(lpMod->FileName);
-				GlobalFree(lpMod->hModule);
-				dprintf_module(stddeb,"FreeLibrary // freed !\n");
-				return;
-				}
-			lpMod->Count--;
-			dprintf_module(stddeb,"FreeLibrary // Count decremented !\n");
-			return;
-			}
-		lpMod = lpMod->lpNextModule;
-		}
-*/
-}
-
-
-/***********************************************************************
- *           GetProcAddress   (KERNEL.50)
- */
-FARPROC GetProcAddress( HANDLE hModule, SEGPTR name )
-{
-    WORD ordinal;
-    SEGPTR ret;
-
-    if (!hModule) hModule = GetCurrentTask();
-    hModule = GetExePtr( hModule );
-
-    if (HIWORD(name) != 0)
-    {
-        ordinal = MODULE_GetOrdinal( hModule, (LPSTR)PTR_SEG_TO_LIN(name) );
-        dprintf_module( stddeb, "GetProcAddress: %04x '%s'\n",
-                        hModule, (LPSTR)PTR_SEG_TO_LIN(name) );
-    }
-    else
-    {
-        ordinal = LOWORD(name);
-        dprintf_module( stddeb, "GetProcAddress: %04x %04x\n",
-                        hModule, ordinal );
-    }
-    if (!ordinal) return (FARPROC)0;
-
-    ret = MODULE_GetEntryPoint( hModule, ordinal );
-
-    dprintf_module( stddeb, "GetProcAddress: returning %08lx\n", ret );
-    return (FARPROC)ret;
-}
diff --git a/loader/main.c b/loader/main.c
index ce712ae..3ace9d3 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -13,44 +13,23 @@
 #include "neexe.h"
 #include "dos_fs.h"
 #include "dlls.h"
-#include "library.h"
 #include "windows.h"
 #include "wineopts.h"
 #include "wine.h"
 #include "task.h"
-#include "prototypes.h"
 #include "options.h"
-#include "if1632.h"
-#include "ne_image.h"
 #include "pe_image.h"
 #include "stddebug.h"
 #include "debug.h"
 
-char **Argv;
-int Argc;
-HINSTANCE hSysRes, hInstMain;
-unsigned short WIN_StackSize;
-
-/**********************************************************************
- *					myerror
- */
-void
-myerror(const char *s)
-{
-    if (s == NULL)
-	perror("wine");
-    else
-	fprintf(stderr, "wine: %s\n", s);
-
-    exit(1);
-}
-
 
 /***********************************************************************
  *           Main initialisation routine
  */
 int MAIN_Init(void)
 {
+    extern BOOL RELAY_Init(void);
+
     int queueSize;
 
     SpyInit();
@@ -58,6 +37,9 @@
       /* Initialize relay code */
     if (!RELAY_Init()) return 0;
 
+      /* Initialize Win32 relay code */
+    if (!RELAY32_Init()) return 0;
+
       /* Create built-in modules */
     if (!MODULE_Init()) return 0;
 
@@ -67,6 +49,12 @@
       /* Initialize the DOS file system */
     DOS_InitFS();
 
+      /* Create DOS environment */
+    CreateSelectors();
+
+      /* Initialize signal handling */
+    init_wine_signals();
+
       /* Initialize communications */
     COMM_Init();
 
@@ -91,19 +79,12 @@
       /* Create the DCEs */
     DCE_Init();
     
-      /* Initialize built-in window classes */
-    if (!WIDGETS_Init()) return 0;
-
       /* Initialize dialog manager */
     if (!DIALOG_Init()) return 0;
 
       /* Initialize menus */
     if (!MENU_Init()) return 0;
 
-      /* Create desktop window */
-    if (!WIN_CreateDesktopWindow()) return 0;
-    if (!DESKTOP_Init()) return 0;
-
       /* Create system message queue */
     queueSize = GetProfileInt( "windows", "TypeAhead", 120 );
     if (!MSG_CreateSysMsgQueue( queueSize )) return 0;
@@ -118,70 +99,20 @@
  */
 int _WinMain(int argc, char **argv)
 {
-    char *p, filename[256];
     int i;
 
-    struct w_files *wpnt;
-#ifdef WINESTAT
-    char * cp;
-#endif
-
     if (!MAIN_Init()) return 0;
 
-	Argc = argc - 1;
-	Argv = argv + 1;
-
-	if (strchr(Argv[0], '\\') || strchr(Argv[0],'/')) {
-            for (p = Argv[0] + strlen(Argv[0]); *p != '\\' && *p !='/'; p--)
-		/* NOTHING */;
-		
-	    strncpy(filename, Argv[0], p - Argv[0]);
-	    filename[p - Argv[0]] = '\0';
-	    strcat(WindowsPath, ";");
-	    if (strchr(filename, '/'))
-		    strcat(WindowsPath, DOS_GetDosFileName(filename));
-	    else
-	    	    strcat(WindowsPath, filename);
-	}
-
-	for (i = 0; i < Argc; i++)
+    for (i = 1; i < argc; i++)
+    {
+        if (WinExec( argv[i], SW_SHOWNORMAL ) < 32)
         {
-            if ((hInstMain = LoadImage(Argv[i], EXE, 1)) < 32) {
-		fprintf(stderr, "wine: can't load %s!.\n", Argv[i]);
-		exit(1);
-            }
+            fprintf(stderr, "wine: can't exec '%s'.\n", argv[i]);
+            exit(1);
         }
+    }
 
-	GetPrivateProfileString("wine", "SystemResources", "sysres.dll", 
-				filename, sizeof(filename), WINE_INI);
-
-	hSysRes = LoadImage(filename, DLL, 0);
-	if (hSysRes < 32) {
-		fprintf(stderr, "wine: can't load %s!.\n", filename);
-		exit(1);
-	} else
- 	    dprintf_dll(stddeb,"System Resources Loaded // hSysRes='%04X'\n",
-			hSysRes);
-	
-
-#ifdef WINESTAT
-    cp = strrchr(argv[0], '/');
-    if(!cp) cp = argv[0];
-	else cp++;
-    if(strcmp(cp,"winestat") == 0) {
-	    winestat();
-	    exit(0);
-    };
-#endif
-
-    /*
-     * Initialize signal handling.
-     */
-    init_wine_signals();
-        
-    wpnt = GetFileInfo(hInstMain);
-    if (Options.debug)
-	wine_debug(0, NULL);
+    if (Options.debug) wine_debug(0, NULL);
 
     Yield();  /* Start the first task */
     fprintf( stderr, "WinMain: Should never happen: returned from Yield()\n" );
diff --git a/loader/module.c b/loader/module.c
index 7ea2944..c4af5bf 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -12,20 +12,19 @@
 #include <unistd.h>
 #include "windows.h"
 #include "dlls.h"
+#include "dos_fs.h"
 #include "global.h"
 #include "ldt.h"
 #include "module.h"
 #include "neexe.h"
+#include "stackframe.h"
+#include "task.h"
 #include "toolhelp.h"
 #include "stddebug.h"
 /* #define DEBUG_MODULE */
 #include "debug.h"
 
 
-extern BYTE KERNEL_Module_Start[], KERNEL_Module_End[];
-
-extern struct dll_name_table_entry_s dll_builtin_table[];
-
 static HMODULE hFirstModule = 0;
 
 
@@ -36,18 +35,20 @@
  */
 BOOL MODULE_Init(void)
 {
+    extern void load_entrypoints( HMODULE );
+
     HMODULE hModule;
     NE_MODULE *pModule;
     SEGTABLEENTRY *pSegTable;
     struct dll_table_s *table;
+    char *dosmem;
     int i;
 
       /* Create the built-in modules */
 
-    for (i = 0; i < N_BUILTINS; i++)
+    for (i = 0, table = dll_builtin_table; i < N_BUILTINS; i++, table++)
     {
-        if (!dll_builtin_table[i].dll_is_used) continue;
-        table = dll_builtin_table[i].table;
+        if (!table->used) continue;
 
         hModule = GLOBAL_CreateBlock( GMEM_MOVEABLE, table->module_start,
                                       table->module_end - table->module_start,
@@ -58,7 +59,7 @@
         table->hModule = hModule;
 
         dprintf_module( stddeb, "Built-in %s: hmodule=%04x\n",
-                        dll_builtin_table[i].dll_name, hModule );
+                        table->name, hModule );
 
           /* Allocate the code segment */
 
@@ -81,7 +82,51 @@
 
         pModule->next = hFirstModule;
         hFirstModule = hModule;
+        load_entrypoints( hModule );
     }
+
+      /* Initialize some KERNEL exported values */
+
+    if (!(hModule = GetModuleHandle( "KERNEL" ))) return TRUE;
+
+      /* KERNEL.178: __WINFLAGS */
+    MODULE_SetEntryPoint( hModule, 178, GetWinFlags() );
+
+    /* Allocate 7 64k segments for 0000, A000, B000, C000, D000, E000, F000. */
+
+    dosmem = malloc( 0x70000 );
+
+    MODULE_SetEntryPoint( hModule, 183,  /* KERNEL.183: __0000H */
+                          GLOBAL_CreateBlock( GMEM_FIXED, dosmem,
+                                     0x10000, hModule, FALSE, FALSE, FALSE ) );
+    MODULE_SetEntryPoint( hModule, 193,  /* KERNEL.193: __0040H */
+                          GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x400,
+                                     0x100, hModule, FALSE, FALSE, FALSE ) );
+    MODULE_SetEntryPoint( hModule, 174,  /* KERNEL.174: __A000H */
+                          GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x10000,
+                                     0x10000, hModule, FALSE, FALSE, FALSE ) );
+    MODULE_SetEntryPoint( hModule, 181,  /* KERNEL.181: __B000H */
+                          GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x20000,
+                                     0x10000, hModule, FALSE, FALSE, FALSE ) );
+    MODULE_SetEntryPoint( hModule, 182,  /* KERNEL.182: __B800H */
+                          GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x28000,
+                                     0x10000, hModule, FALSE, FALSE, FALSE ) );
+    MODULE_SetEntryPoint( hModule, 195,  /* KERNEL.195: __C000H */
+                          GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x30000,
+                                     0x10000, hModule, FALSE, FALSE, FALSE ) );
+    MODULE_SetEntryPoint( hModule, 179,  /* KERNEL.179: __D000H */
+                          GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x40000,
+                                     0x10000, hModule, FALSE, FALSE, FALSE ) );
+    MODULE_SetEntryPoint( hModule, 190,  /* KERNEL.190: __E000H */
+                          GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x50000,
+                                     0x10000, hModule, FALSE, FALSE, FALSE ) );
+    MODULE_SetEntryPoint( hModule, 173,  /* KERNEL.173: __ROMBIOS */
+                          GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x60000,
+                                     0x10000, hModule, FALSE, FALSE, FALSE ) );
+    MODULE_SetEntryPoint( hModule, 194,  /* KERNEL.194: __F000H */
+                          GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x60000,
+                                     0x10000, hModule, FALSE, FALSE, FALSE ) );
+
     return TRUE;
 }
 
@@ -237,7 +282,7 @@
     close( cachedfd );
     hCachedModule = hModule;
     name = ((LOADEDFILEINFO*)((char*)pModule + pModule->fileinfo))->filename;
-    cachedfd = open( name /* DOS_GetUnixFileName( name ) */, O_RDONLY );
+    cachedfd = open( DOS_GetUnixFileName( name ), O_RDONLY );
     dprintf_module( stddeb, "MODULE_OpenFile: opened '%s' -> %d\n",
                     name, cachedfd );
     return cachedfd;
@@ -263,7 +308,9 @@
         {
             /* FIXME: this is needed because heap growing is not implemented */
             pModule->heap_size = 0x10000 - minsize;
+            /* For tasks, the DGROUP is allocated by MODULE_MakeNewInstance */
             minsize = 0x10000;
+            if (!(pModule->flags & NE_FFLAGS_LIBMODULE)) continue;
         }
         pSegment->selector = GLOBAL_Alloc( GMEM_ZEROINIT | GMEM_FIXED,
                                       minsize, hModule,
@@ -282,7 +329,7 @@
 /***********************************************************************
  *           MODULE_LoadExeHeader
  */
-HMODULE MODULE_LoadExeHeader( int fd, char *filename )
+HMODULE MODULE_LoadExeHeader( int fd, OFSTRUCT *ofs )
 {
     struct mz_header_s mz_header;
     struct ne_header_s ne_header;
@@ -316,7 +363,7 @@
 
     size = sizeof(NE_MODULE) +
              /* loaded file info */
-           sizeof(LOADEDFILEINFO) + strlen(filename) +
+           sizeof(LOADEDFILEINFO) + strlen(ofs->szPathName) +
              /* segment table */
            ne_header.n_segment_tab * sizeof(SEGTABLEENTRY) +
              /* resource table */
@@ -335,6 +382,7 @@
     FarSetOwner( hModule, hModule );
     pModule = (NE_MODULE *)GlobalLock( hModule );
     memcpy( pModule, &ne_header, sizeof(NE_MODULE) );
+    pModule->count = 0;
     pData = (BYTE *)(pModule + 1);
 
     /* Read the fast-load area */
@@ -359,12 +407,12 @@
     /* Store the filename information */
 
     pModule->fileinfo = (int)pData - (int)pModule;
-    ((LOADEDFILEINFO*)pData)->length = sizeof(LOADEDFILEINFO)+strlen(filename);
+    ((LOADEDFILEINFO*)pData)->length = sizeof(LOADEDFILEINFO)+strlen(ofs->szPathName);
     ((LOADEDFILEINFO*)pData)->fixed_media = TRUE;
     ((LOADEDFILEINFO*)pData)->error = 0;
     ((LOADEDFILEINFO*)pData)->date = 0;
     ((LOADEDFILEINFO*)pData)->time = 0;
-    strcpy( ((LOADEDFILEINFO*)pData)->filename, filename );
+    strcpy( ((LOADEDFILEINFO*)pData)->filename, ofs->szPathName );
     pData += ((LOADEDFILEINFO*)pData)->length--;
 
     /* Get the segment table */
@@ -451,6 +499,17 @@
     }
     else pModule->nrname_handle = 0;
 
+    /* Allocate a segment for the implicitly-loaded DLLs */
+
+    if (pModule->modref_count)
+    {
+        pModule->dlls_to_init = GLOBAL_Alloc(GMEM_ZEROINIT,
+                                    (pModule->modref_count+1)*sizeof(HMODULE),
+                                    hModule, FALSE, FALSE, FALSE );
+        if (!pModule->dlls_to_init) return 11;  /* invalid exe */
+    }
+    else pModule->dlls_to_init = 0;
+
     if (debugging_module) MODULE_PrintModule( hModule );
     pModule->next = hFirstModule;
     hFirstModule = hModule;
@@ -459,6 +518,62 @@
 
 
 /***********************************************************************
+ *           MODULE_MakeNewInstance
+ *
+ * Create a new instance of the specified module.
+ */
+HINSTANCE MODULE_MakeNewInstance( HMODULE hModule, LOADPARAMS *params )
+{
+    NE_MODULE *pModule;
+    SEGTABLEENTRY *pSegment;
+    HINSTANCE hNewInstance, hPrevInstance;
+    int minsize;
+
+    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
+    if (!pModule->dgroup) return hModule;  /* No DGROUP -> return the module */
+
+    pSegment = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
+    hPrevInstance = pSegment->selector;
+
+      /* Don't create a new instance if it's a library */
+
+    if (pModule->flags & NE_FFLAGS_LIBMODULE) return hPrevInstance;
+    if (params == (LOADPARAMS*)-1) return hPrevInstance;
+
+      /* Allocate the new data segment */
+
+    minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
+    if (pModule->ss == pModule->dgroup) minsize += pModule->stack_size;
+    minsize += pModule->heap_size;
+    hNewInstance = GLOBAL_Alloc( GMEM_ZEROINIT | GMEM_FIXED,
+                                 minsize, hModule, FALSE, FALSE, FALSE );
+    if (!hNewInstance) return 0;
+    pSegment->selector = hNewInstance;
+    NE_LoadSegment( hModule, pModule->dgroup );
+
+      /* Create a new task for this instance */
+    if (!TASK_CreateTask( hModule, hNewInstance, hPrevInstance,
+                          params->hEnvironment,
+                          (LPSTR)PTR_SEG_TO_LIN( params->cmdLine ),
+                          *((WORD *)PTR_SEG_TO_LIN(params->showCmd)+1) ))
+    {
+        GlobalFree( hNewInstance );
+        return 0;
+    }
+
+      /* Initialize the local heap */
+
+    if (pModule->heap_size)
+    {
+        WORD heapstart = pSegment->minsize;
+        if (pModule->ss == pModule->dgroup) heapstart += pModule->stack_size;
+        LocalInit( hNewInstance, heapstart, heapstart + pModule->heap_size );
+    }
+    return hNewInstance;
+}
+
+
+/***********************************************************************
  *           MODULE_GetOrdinal
  *
  * Lookup the ordinal for a given name.
@@ -538,8 +653,6 @@
 
     if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
 
-    dprintf_module( stddeb, "MODULE_GetEntryPoint(%04x,%d)\n",
-                    hModule, ordinal );
     p = (BYTE *)pModule + pModule->entry_table;
     while (*p && (curOrdinal + *p <= ordinal))
     {
@@ -552,16 +665,11 @@
             default:   p += 2 + *p * 3; break;  /* fixed */
         }
     }
-    if (!*p)
-    {
-        dprintf_module( stddeb, "  Not found (last=%d)\n", curOrdinal-1 );
-        return 0;
-    }
+    if (!*p) return 0;
 
     switch(p[1])
     {
         case 0:  /* unused */
-            dprintf_module( stddeb, "  Found, but entry is unused\n" );
             return 0;
         case 0xff:  /* moveable */
             p += 2 + 6 * (ordinal - curOrdinal);
@@ -575,8 +683,6 @@
             break;
     }
 
-    dprintf_module( stddeb, "  Found, logical addr = %04x:%04x\n",
-                    sel, offset );
     if (sel == 0xfe) sel = 0xffff;  /* constant entry */
     else sel = NE_SEG_TABLE(pModule)[sel-1].selector;
     return MAKELONG( offset, sel );
@@ -584,6 +690,87 @@
 
 
 /***********************************************************************
+ *           MODULE_SetEntryPoint
+ *
+ * Change the value of an entry point. Use with caution!
+ * It can only change the offset value, not the selector.
+ */
+BOOL MODULE_SetEntryPoint( HMODULE hModule, WORD ordinal, WORD offset )
+{
+    NE_MODULE *pModule;
+    WORD curOrdinal = 1;
+    BYTE *p;
+
+    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return FALSE;
+
+    p = (BYTE *)pModule + pModule->entry_table;
+    while (*p && (curOrdinal + *p <= ordinal))
+    {
+          /* Skipping this bundle */
+        curOrdinal += *p;
+        switch(p[1])
+        {
+            case 0:    p += 2; break;  /* unused */
+            case 0xff: p += 2 + *p * 6; break;  /* moveable */
+            default:   p += 2 + *p * 3; break;  /* fixed */
+        }
+    }
+    if (!*p) return FALSE;
+
+    switch(p[1])
+    {
+        case 0:  /* unused */
+            return FALSE;
+        case 0xff:  /* moveable */
+            p += 2 + 6 * (ordinal - curOrdinal);
+            *(WORD *)(p + 4) = offset;
+            break;
+        default:  /* fixed */
+            p += 2 + 3 * (ordinal - curOrdinal);
+            *(WORD *)(p + 1) = offset;
+            break;
+    }
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           MODULE_GetEntryPointName
+ *
+ * Return the entry point name for a given ordinal.
+ * Used only by relay debugging.
+ * Warning: returned pointer is to a Pascal-type string.
+ */
+LPSTR MODULE_GetEntryPointName( HMODULE hModule, WORD ordinal )
+{
+    register char *cpnt;
+    NE_MODULE *pModule;
+
+    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
+
+      /* First search the resident names */
+
+    cpnt = (char *)pModule + pModule->name_table;
+    while (*cpnt)
+    {
+        cpnt += *cpnt + 1 + sizeof(WORD);
+        if (*(WORD *)(cpnt + *cpnt + 1) == ordinal) return cpnt;
+    }
+
+      /* Now search the non-resident names table */
+
+    if (!pModule->nrname_handle) return 0;  /* No non-resident table */
+    cpnt = (char *)GlobalLock( pModule->nrname_handle );
+    while (*cpnt)
+    {
+        cpnt += *cpnt + 1 + sizeof(WORD);
+        if (*(WORD *)(cpnt + *cpnt + 1) == ordinal) return cpnt;
+    }
+    return NULL;
+}
+
+
+/***********************************************************************
  *           MODULE_GetModuleName
  */
 LPSTR MODULE_GetModuleName( HMODULE hModule )
@@ -602,10 +789,208 @@
 
 
 /**********************************************************************
+ *	    MODULE_FindModule
+ *
+ * Find a module from a path name.
+ */
+HMODULE MODULE_FindModule( LPCSTR path )
+{
+    HMODULE hModule = hFirstModule;
+    LPCSTR filename, dotptr, modulepath, modulename;
+    BYTE len, *name_table;
+
+    if (!(filename = strrchr( path, '\\' ))) filename = path;
+    if ((dotptr = strrchr( filename, '.' )) != NULL)
+        len = (BYTE)(dotptr - filename);
+    else len = strlen( filename );
+
+    while(hModule)
+    {
+        NE_MODULE *pModule = (NE_MODULE *)GlobalLock( hModule );
+        if (!pModule) break;
+        modulepath = ((LOADEDFILEINFO*)((char*)pModule + pModule->fileinfo))->filename;
+        if (!(modulename = strrchr( modulepath, '\\' )))
+            modulename = modulepath;
+        if (!strcasecmp( modulename, filename )) return hModule;
+
+        name_table = (BYTE *)pModule + pModule->name_table;
+        if ((*name_table == len) && !strncasecmp(filename, name_table+1, len))
+            return hModule;
+        hModule = pModule->next;
+    }
+    return 0;
+}
+
+
+/**********************************************************************
+ *	    MODULE_FreeModule
+ *
+ * Remove a module from memory.
+ */
+static void MODULE_FreeModule( HMODULE hModule )
+{
+    HMODULE *hPrevModule;
+    NE_MODULE *pModule;
+    SEGTABLEENTRY *pSegment;
+    WORD *pModRef;
+    int i;
+
+    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return;
+
+    /* FIXME: should call the exit code for the library here */
+
+      /* Remove it from the linked list */
+
+    hPrevModule = &hFirstModule;
+    while (*hPrevModule && (*hPrevModule != hModule))
+    {
+        hPrevModule = &((NE_MODULE *)GlobalLock( *hPrevModule ))->next;
+    }
+    if (*hPrevModule) *hPrevModule = pModule->next;
+
+      /* Free all the segments */
+
+    pSegment = NE_SEG_TABLE( pModule );
+    for (i = 1; i <= pModule->seg_count; i++, pSegment++)
+    {
+        GlobalFree( pSegment->selector );
+    }
+
+      /* Free the referenced modules */
+
+    pModRef = NE_MODULE_TABLE( pModule );
+    for (i = 0; i < pModule->modref_count; i++, pModRef++)
+    {
+        FreeModule( *pModRef );
+    }
+
+      /* Free the module storage */
+
+    if (pModule->nrname_handle) GlobalFree( pModule->nrname_handle );
+    if (pModule->dlls_to_init) GlobalFree( pModule->dlls_to_init );
+    GlobalFree( hModule );
+}
+
+
+/**********************************************************************
  *	    LoadModule    (KERNEL.45)
  */
-HINSTANCE MODULE_LoadModule( LPCSTR name, LPVOID paramBlock )
+HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock )
 {
+    HMODULE hModule;
+    HANDLE hInstance;
+    NE_MODULE *pModule;
+    WORD *pModRef, *pDLLs;
+    int i, fd;
+
+    hModule = MODULE_FindModule( name );
+    if (!hModule)  /* We have to load the module */
+    {
+        OFSTRUCT ofs;
+        if (strchr( name, '/' )) name = DOS_GetDosFileName( name );
+        if ((fd = OpenFile( name, &ofs, OF_READ )) == -1)
+            return 2;  /* File not found */
+
+          /* Create the module structure */
+
+        if ((hModule = MODULE_LoadExeHeader( fd, &ofs )) < 32)
+        {
+            close( fd );
+            fprintf( stderr, "LoadModule: can't load '%s', error=%d\n",
+                     name, hModule );
+            return hModule;
+        }
+        pModule = (NE_MODULE *)GlobalLock( hModule );
+
+          /* Allocate the segments for this module */
+
+        MODULE_CreateSegments( hModule );
+
+          /* Load the referenced DLLs */
+
+        pModRef = (WORD *)((char *)pModule + pModule->modref_table);
+        pDLLs = (WORD *)GlobalLock( pModule->dlls_to_init );
+        for (i = 0; i < pModule->modref_count; i++, pModRef++)
+        {
+            char buffer[256];
+            BYTE *pstr = (BYTE *)pModule + pModule->import_table + *pModRef;
+            memcpy( buffer, pstr + 1, *pstr );
+            strcpy( buffer + *pstr, ".dll" );
+            dprintf_module( stddeb, "Loading '%s'\n", buffer );
+            if (!(*pModRef = MODULE_FindModule( buffer )))
+            {
+                /* If the DLL is not loaded yet, load it and store */
+                /* its handle in the list of DLLs to initialize.   */
+                HMODULE hDLL;
+
+                if ((hDLL = LoadModule( buffer, (LPVOID)-1 )) == 2)  /* file not found */
+                {
+                    char *p;
+
+                    /* Try with prepending the path of the current module */
+                    GetModuleFileName( hModule, buffer, 256 );
+                    if (!(p = strrchr( buffer, '\\' ))) p = buffer;
+                    memcpy( p + 1, pstr + 1, *pstr );
+                    strcpy( p + 1 + *pstr, ".dll" );
+                    hDLL = LoadModule( buffer, (LPVOID)-1 );
+                }
+                if (hDLL < 32)
+                {
+                    fprintf( stderr, "Could not load '%s' required by '%s', error = %d\n",
+                             buffer, name, hDLL );
+                    return 2;  /* file not found */
+                }
+                *pModRef = GetExePtr( hDLL );
+                *pDLLs++ = *pModRef;
+            }
+            else  /* Increment the reference count of the DLL */
+            {
+                NE_MODULE *pOldDLL = (NE_MODULE *)GlobalLock( *pModRef );
+                if (pOldDLL) pOldDLL->count++;
+            }
+        }
+
+          /* Load the segments (except the DGROUP) */
+
+        for (i = 1; i <= pModule->seg_count; i++)
+            if (i != pModule->dgroup) NE_LoadSegment( hModule, i );
+
+          /* Create an instance for this module */
+
+        hInstance = MODULE_MakeNewInstance( hModule, (LOADPARAMS*)paramBlock );
+
+          /* Fixup the functions prologs */
+
+        NE_FixupPrologs( hModule );
+
+          /* Make sure the usage count is 1 on the first loading of  */
+          /* the module, even if it contains circular DLL references */
+
+        pModule->count = 1;
+    }
+    else
+    {
+        pModule = (NE_MODULE *)GlobalLock( hModule );
+        hInstance = MODULE_MakeNewInstance( hModule, (LOADPARAMS*)paramBlock );
+        pModule->count++;
+    }
+
+    return hInstance;
+}
+
+
+/**********************************************************************
+ *	    FreeModule    (KERNEL.46)
+ */
+BOOL FreeModule( HANDLE hModule )
+{
+    NE_MODULE *pModule;
+
+    hModule = GetExePtr( hModule );  /* In case we were passed an hInstance */
+    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return FALSE;
+
+    if (--pModule->count == 0) MODULE_FreeModule( hModule );
+    return TRUE;
 }
 
 
@@ -614,21 +999,15 @@
  */
 HMODULE GetModuleHandle( LPCSTR name )
 {
-    char buffer[16];
-    BYTE len;
-    HMODULE hModule;
+    BYTE len = strlen(name);
+    HMODULE hModule = hFirstModule;
 
-    strncpy( buffer, name, 15 );
-    buffer[15] = '\0';
-    len = strlen(buffer);
-    AnsiUpper( buffer );
-
-    hModule = hFirstModule;
     while( hModule )
     {
         NE_MODULE *pModule = (NE_MODULE *)GlobalLock( hModule );
         char *pname = (char *)pModule + pModule->name_table;
-        if (((BYTE)*pname == len) && !memcmp( pname+1, buffer, len )) break;
+        if (((BYTE)*pname == len) && !strncasecmp( pname+1, name, len ))
+            break;
         hModule = pModule->next;
     }
     dprintf_module( stddeb, "GetModuleHandle('%s'): returning %04x\n",
@@ -669,6 +1048,122 @@
 }
 
 
+/***********************************************************************
+ *           LoadLibrary   (KERNEL.95)
+ */
+HANDLE LoadLibrary( LPCSTR libname )
+{
+    HANDLE handle;
+
+    dprintf_module( stddeb, "LoadLibrary: (%08x) %s\n", (int)libname, libname);
+    handle = LoadModule( libname, (LPVOID)-1 );
+    if (handle == 2)  /* file not found */
+    {
+        char buffer[256];
+        strcpy( buffer, libname );
+        strcat( buffer, ".dll" );
+        handle = LoadModule( buffer, (LPVOID)-1 );
+    }
+    if (handle >= 32) NE_InitializeDLLs( handle );
+    return handle;
+}
+
+
+/***********************************************************************
+ *           FreeLibrary   (KERNEL.96)
+ */
+void FreeLibrary( HANDLE handle )
+{
+    dprintf_module( stddeb,"FreeLibrary: %04x\n", handle );
+    FreeModule( handle );
+}
+
+
+/***********************************************************************
+ *           WinExec   (KERNEL.166)
+ */
+HANDLE WinExec( LPSTR lpCmdLine, WORD nCmdShow )
+{
+    LOADPARAMS params;
+    HLOCAL cmdShowHandle, cmdLineHandle;
+    HANDLE handle;
+    WORD *cmdShowPtr;
+    char *p, *cmdline, filename[256];
+
+    if (!(cmdShowHandle = GlobalAlloc( 0, 2 * sizeof(WORD) ))) return 0;
+    if (!(cmdLineHandle = GlobalAlloc( 0, 256 ))) return 0;
+
+      /* Store nCmdShow */
+
+    cmdShowPtr = (WORD *)GlobalLock( cmdShowHandle );
+    cmdShowPtr[0] = 2;
+    cmdShowPtr[1] = nCmdShow;
+
+      /* Build the filename and command-line */
+
+    cmdline = (char *)GlobalLock( cmdLineHandle );
+    strncpy( filename, lpCmdLine, 256 );
+    filename[255] = '\0';
+    for (p = filename; *p && (*p != ' ') && (*p != '\t'); p++);
+    if (*p)
+    {
+        strncpy( cmdline, p + 1, 128 );
+        cmdline[127] = '\0';
+    }
+    else cmdline[0] = '\0';
+    *p = '\0';
+
+      /* Now load the executable file */
+
+    params.hEnvironment = SELECTOROF( GetDOSEnvironment() );
+    params.cmdLine  = WIN16_GlobalLock( cmdLineHandle );
+    params.showCmd  = WIN16_GlobalLock( cmdShowHandle );
+    params.reserved = 0;
+    handle = LoadModule( filename, &params );
+    if (handle == 2)  /* file not found */
+    {
+        strcat( filename, ".exe" );
+        handle = LoadModule( filename, &params );
+    }
+
+    GlobalFree( cmdShowHandle );
+    GlobalFree( cmdLineHandle );
+    return handle;
+}
+
+
+/***********************************************************************
+ *           GetProcAddress   (KERNEL.50)
+ */
+FARPROC GetProcAddress( HANDLE hModule, SEGPTR name )
+{
+    WORD ordinal;
+    SEGPTR ret;
+
+    if (!hModule) hModule = GetCurrentTask();
+    hModule = GetExePtr( hModule );
+
+    if (HIWORD(name) != 0)
+    {
+        ordinal = MODULE_GetOrdinal( hModule, (LPSTR)PTR_SEG_TO_LIN(name) );
+        dprintf_module( stddeb, "GetProcAddress: %04x '%s'\n",
+                        hModule, (LPSTR)PTR_SEG_TO_LIN(name) );
+    }
+    else
+    {
+        ordinal = LOWORD(name);
+        dprintf_module( stddeb, "GetProcAddress: %04x %04x\n",
+                        hModule, ordinal );
+    }
+    if (!ordinal) return (FARPROC)0;
+
+    ret = MODULE_GetEntryPoint( hModule, ordinal );
+
+    dprintf_module( stddeb, "GetProcAddress: returning %08lx\n", ret );
+    return (FARPROC)ret;
+}
+
+
 /**********************************************************************
  *	    ModuleFirst    (TOOLHELP.59)
  */
diff --git a/loader/ne_image.c b/loader/ne_image.c
index 92e37f5..1a14ef2 100644
--- a/loader/ne_image.c
+++ b/loader/ne_image.c
@@ -18,12 +18,8 @@
 #include "dlls.h"
 #include "windows.h"
 #include "arch.h"
-#include "library.h"
-#include "if1632.h"
 #include "selectors.h"
 #include "callback.h"
-#include "ne_image.h"
-#include "prototypes.h"
 #include "module.h"
 #include "stackframe.h"
 #include "stddebug.h"
@@ -33,7 +29,7 @@
 /***********************************************************************
  *           NE_LoadSegment
  */
-static BOOL NE_LoadSegment( HMODULE hModule, WORD segnum )
+BOOL NE_LoadSegment( HMODULE hModule, WORD segnum )
 {
     NE_MODULE *pModule;
     SEGTABLEENTRY *pSegTable, *pSeg;
@@ -42,9 +38,9 @@
     DWORD address;
     int fd;
     struct relocation_entry_s *rep, *reloc_entries;
-    char *dll_name, *func_name;
+    BYTE *func_name;
 
-    char buffer[100], buffer2[100];
+    char buffer[100];
     int ordinal, additive;
     unsigned short *sp;
 
@@ -66,6 +62,12 @@
     read( fd, &count, sizeof(count) );
     if (!count) return TRUE;
 
+    dprintf_fixup( stddeb, "Fixups for %*.*s, segment %d, selector %04x\n",
+                   *((BYTE *)pModule + pModule->name_table),
+                   *((BYTE *)pModule + pModule->name_table),
+                   (char *)pModule + pModule->name_table + 1,
+                   segnum, pSeg->selector );
+
     reloc_entries = (struct relocation_entry_s *)malloc(count * sizeof(struct relocation_entry_s));
     if (read( fd, reloc_entries, count * sizeof(struct relocation_entry_s)) !=
             count * sizeof(struct relocation_entry_s))
@@ -93,42 +95,62 @@
 	{
 	  case NE_RELTYPE_ORDINAL:
             module = pModuleTable[rep->target1-1];
-            dll_name = (char *)pModule + pModule->import_table + module;
-            memcpy( buffer, dll_name+1, *dll_name );
-            buffer[*dll_name] = '\0';
-            dll_name = buffer;
-            module = GetModuleHandle( dll_name );
-
 	    ordinal = rep->target2;
             address = MODULE_GetEntryPoint( module, ordinal );
-            if (!address) fprintf( stderr, "Warning: no handler for %s.%d, setting to 0:0\n",
-                                  dll_name, ordinal );
-
-	    dprintf_fixup(stddeb,"%d: %s.%d: %04x:%04x\n", i + 1, 
-                        dll_name, ordinal, HIWORD(address), LOWORD(address) );
+            if (!address)
+            {
+                NE_MODULE *pTarget = (NE_MODULE *)GlobalLock( module );
+                if (!pTarget)
+                    fprintf( stderr, "Module not found: %04x, reference %d of module %*.*s\n",
+                             module, rep->target1, 
+                             *((BYTE *)pModule + pModule->name_table),
+                             *((BYTE *)pModule + pModule->name_table),
+                             (char *)pModule + pModule->name_table + 1 );
+                else
+                    fprintf( stderr, "Warning: no handler for %*.*s.%d, setting to 0:0\n",
+                            *((BYTE *)pTarget + pTarget->name_table),
+                            *((BYTE *)pTarget + pTarget->name_table),
+                            (char *)pTarget + pTarget->name_table + 1,
+                            ordinal );
+            }
+            if (debugging_fixup)
+            {
+                NE_MODULE *pTarget = (NE_MODULE *)GlobalLock( module );
+                fprintf( stddeb,"%d: %*.*s.%d=%04x:%04x\n", i + 1, 
+                         *((BYTE *)pTarget + pTarget->name_table),
+                         *((BYTE *)pTarget + pTarget->name_table),
+                         (char *)pTarget + pTarget->name_table + 1,
+                         ordinal, HIWORD(address), LOWORD(address) );
+            }
 	    break;
 	    
 	  case NE_RELTYPE_NAME:
             module = pModuleTable[rep->target1-1];
-            dll_name = (char *)pModule + pModule->import_table + module;
-            memcpy( buffer, dll_name+1, *dll_name );
-            buffer[*dll_name] = '\0';
-            dll_name = buffer;
-            module = GetModuleHandle( dll_name );
-
             func_name = (char *)pModule + pModule->import_table + rep->target2;
-            memcpy( buffer2, func_name+1, *func_name );
-            buffer2[*func_name] = '\0';
-            func_name = buffer2;
+            memcpy( buffer, func_name+1, *func_name );
+            buffer[*func_name] = '\0';
+            func_name = buffer;
             ordinal = MODULE_GetOrdinal( module, func_name );
 
             address = MODULE_GetEntryPoint( module, ordinal );
 
-            if (!address) fprintf( stderr, "Warning: no handler for %s.%s, setting to 0:0\n",
-                                  dll_name, func_name );
-
-            dprintf_fixup(stddeb,"%d: %s.%s: %04x:%04x\n", i + 1, 
-                       dll_name, func_name, HIWORD(address), LOWORD(address) );
+            if (!address)
+            {
+                NE_MODULE *pTarget = (NE_MODULE *)GlobalLock( module );
+                fprintf( stderr, "Warning: no handler for %*.*s.%s, setting to 0:0\n",
+                        *((BYTE *)pTarget + pTarget->name_table),
+                        *((BYTE *)pTarget + pTarget->name_table),
+                        (char *)pTarget + pTarget->name_table + 1, func_name );
+            }
+            if (debugging_fixup)
+            {
+                NE_MODULE *pTarget = (NE_MODULE *)GlobalLock( module );
+                fprintf( stddeb,"%d: %*.*s.%s=%04x:%04x\n", i + 1, 
+                         *((BYTE *)pTarget + pTarget->name_table),
+                         *((BYTE *)pTarget + pTarget->name_table),
+                         (char *)pTarget + pTarget->name_table + 1,
+                         func_name, HIWORD(address), LOWORD(address) );
+            }
 	    break;
 	    
 	  case NE_RELTYPE_INTERNAL:
@@ -173,17 +195,6 @@
 	    return FALSE;
 	}
 
-        /* I'm not sure why a DLL entry point fixup could be additive.
-           Old code used to ignore additive if the target is a built-in
-           DLL. This doesn't seem to work for __AHSHIFT */
-#if 0
-        if (additive && FindDLLTable(dll_name) != NULL)
-            dprintf_fixup(stddeb,"Additive for builtin???\n"
-                          "%d: ADDR TYPE %d, TYPE %d, OFFSET %04x, "
-                          "TARGET %04x %04x\n",
-                          i+1, rep->address_type, rep->relocation_type,
-                          rep->offset, rep->target1, rep->target2);
-#endif
 	offset  = rep->offset;
 
 	switch (rep->address_type)
@@ -263,7 +274,7 @@
  *
  * Fixup the exported functions prologs.
  */
-static void NE_FixupPrologs( HMODULE hModule )
+void NE_FixupPrologs( HMODULE hModule )
 {
     NE_MODULE *pModule;
     SEGTABLEENTRY *pSegTable;
@@ -333,15 +344,12 @@
 }
 
 
-int NE_unloadImage(struct w_files *wpnt)
-{
-	dprintf_fixup(stdnimp, "NEunloadImage() called!\n");
-	/* free resources, image */
-	return 1;
-}
-
-
-BOOL NE_InitDLL( HMODULE hModule )
+/***********************************************************************
+ *           NE_InitDLL
+ *
+ * Call the DLL initialization code
+ */
+static BOOL NE_InitDLL( HMODULE hModule )
 {
     int cs_reg, ds_reg, ip_reg, cx_reg, di_reg, bp_reg;
     NE_MODULE *pModule;
@@ -383,7 +391,7 @@
     cs_reg = pSegTable[pModule->cs-1].selector;
     ip_reg = pModule->ip;
     di_reg = ds_reg ? ds_reg : hModule;
-    bp_reg = IF1632_Saved16_sp + (&((STACK16FRAME*)1)->bp - 1);
+    bp_reg = IF1632_Saved16_sp + ((WORD)&((STACK16FRAME*)1)->bp - 1);
 
     pModule->cs = 0;  /* Don't initialize it twice */
     dprintf_dll( stddeb, "Calling LibMain, cs:ip=%04x:%04x ds=%04x di=%04x cx=%04x\n", 
@@ -394,92 +402,23 @@
 }
 
 
-/**********************************************************************
- *			NE_LoadImage
- * Load one NE format executable into memory
+/***********************************************************************
+ *           NE_InitializeDLLs
+ *
+ * Initialize the loaded DLLs.
  */
-HINSTANCE NE_LoadImage(struct w_files *wpnt)
+void NE_InitializeDLLs( HMODULE hModule )
 {
     NE_MODULE *pModule;
-    SEGTABLEENTRY *pSegTable;
-    WORD *pModRef;
-    unsigned int read_size, status, segment;
-    int i;
-    char cmdLine[256];
-    extern int Argc;
-    extern char **Argv;
+    WORD *pDLL;
 
-    wpnt->ne = malloc(sizeof(struct ne_data));
-    wpnt->ne->ne_header = malloc(sizeof(struct ne_header_s));
-
-    lseek(wpnt->fd, wpnt->mz_header->ne_offset, SEEK_SET);
-    if (read(wpnt->fd, wpnt->ne->ne_header, sizeof(struct ne_header_s)) 
-	!= sizeof(struct ne_header_s))
-	myerror("Unable to read NE header from file");
-
-    wpnt->hModule = MODULE_LoadExeHeader( wpnt->fd, wpnt->filename );
-    pModule = (NE_MODULE *)GlobalLock( wpnt->hModule );
-    pSegTable = NE_SEG_TABLE(pModule);
-
-      /* Create the module segments */
-
-    MODULE_CreateSegments( wpnt->hModule );
-#ifndef WINELIB
-    /*
-     * Create segment selectors.
-     */
-    CreateSelectors();
-
-    if (pModule->dgroup)
-        wpnt->hinstance = NE_SEG_TABLE(pModule)[pModule->dgroup-1].selector;
-    else
-        wpnt->hinstance = wpnt->hModule;
-#endif
-
-      /* Create a task for this module */
-
-    cmdLine[0] = '\0';
-    for (i = 1; i < Argc; i++)
+    pModule = (NE_MODULE *)GlobalLock( hModule );
+    if (!pModule->dlls_to_init) return;
+    for (pDLL = (WORD *)GlobalLock( pModule->dlls_to_init ); *pDLL; pDLL++)
     {
-        strcat( cmdLine, Argv[i] );
-        strcat( cmdLine, " " );
+        NE_InitDLL( *pDLL );
+        NE_InitializeDLLs( *pDLL );
     }
-    if (!(pModule->flags & NE_FFLAGS_LIBMODULE))
-        TASK_CreateTask( wpnt->hModule, SELECTOROF( GetDOSEnvironment() ),
-                         GetCurrentTask(), cmdLine );
-
-    /*
-     * Now load any DLLs that  this module refers to.
-     */
-    pModRef = (WORD *)((char *)pModule + pModule->modref_table);
-    for (i = 0; i < pModule->modref_count; i++, pModRef++)
-    {
-        char buffer[80];
-        char *pstr = (char *)pModule + pModule->import_table + *pModRef;
-        memcpy( buffer, pstr + 1, *pstr );
-        buffer[*pstr] = '\0';
-        dprintf_module( stddeb, "Loading '%s'\n", buffer );
-        LoadImage( buffer, DLL, 0 );
-    }
-
-    /* fixup references */
-
-    for (i = 1; i <= pModule->seg_count; i++)
-        NE_LoadSegment( wpnt->hModule, i );
-
-    NE_FixupPrologs( wpnt->hModule );
-    InitializeLoadedDLLs(wpnt);
-
-
-      /* Initialize the local heap */
-
-    if (pModule->dgroup)
-    {
-        int start = pSegTable[pModule->dgroup-1].minsize;
-        if (pModule->ss == pModule->dgroup) start += pModule->stack_size;
-        LocalInit( pSegTable[pModule->dgroup-1].selector,
-                   start, start + pModule->heap_size );
-    }
-
-    return(wpnt->hinstance);
+    GlobalFree( pModule->dlls_to_init );
+    pModule->dlls_to_init = 0;
 }
diff --git a/loader/ne_resource.c b/loader/ne_resource.c
index e3e4428..76f30b8 100644
--- a/loader/ne_resource.c
+++ b/loader/ne_resource.c
@@ -204,8 +204,10 @@
                                        pTypeInfo->count * sizeof(NE_NAMEINFO));
         }
     }
-    fprintf( stderr, "FindResource(%04x,%08lx,%08lx): Not found.\n",
-             hModule, typeId, resId );
+    fprintf( stderr, "FindResource('%*.*s',%08lx,%08lx): Not found.\n",
+             *((BYTE *)pModule + pModule->name_table),
+             *((BYTE *)pModule + pModule->name_table),
+             (char *)pModule + pModule->name_table + 1, typeId, resId );
     return 0;
 }
 
diff --git a/loader/pe_image.c b/loader/pe_image.c
index 9dcad50..ee1b119 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -21,6 +21,8 @@
 
 #define MAP_ANONYMOUS	0x20
 
+struct w_files *wine_files = NULL;
+
 unsigned int load_addr;
 
 void my_wcstombs(char * result, u_short * source, int len)
@@ -34,10 +36,15 @@
   };
 }
 
-char * xmmap(char * vaddr, unsigned int v_size, int prot, int flags, 
-	     int fd, unsigned int file_offset)
+char * xmmap(char * vaddr, unsigned int v_size, unsigned int r_size,
+	int prot, int flags, int fd, unsigned int file_offset)
 {
   char * result;
+  /* .bss has no associated storage in the PE file */
+  if(r_size)
+    v_size=r_size;
+  else
+    flags |= MAP_ANON;
   result = mmap(vaddr, v_size, prot, flags, fd, file_offset);
   if((unsigned int) result != 0xffffffff) return result;
 
@@ -79,9 +86,10 @@
     }
 }
 
-void dump_imports(struct PE_Import_Directory *pe_imports)
+void fixup_imports(struct PE_Import_Directory *pe_imports)
 { 
   struct PE_Import_Directory * pe_imp;
+  int fixup_failed=0;
 
  /* OK, now dump the import list */
   printf("\nDumping imports list\n");
@@ -90,7 +98,7 @@
     {
       char * Module;
       struct pe_import_name * pe_name;
-      unsigned int * import_list;
+      unsigned int * import_list, *thunk_list;
       char * c;
 
       Module = ((char *) load_addr) + pe_imp->ModuleName;
@@ -100,15 +108,32 @@
 
       import_list = (unsigned int *) 
 	(((unsigned int) load_addr) + pe_imp->Import_List);
+	  thunk_list = (unsigned int *)
+	  (((unsigned int) load_addr) + pe_imp->Thunk_List);
+
 
       while(*import_list)
 	{
 	  pe_name = (struct pe_import_name *) ((int) load_addr + *import_list);
+	  if((unsigned)pe_name & 0x80000000)
+	  {
+	  	fprintf(stderr,"Import by ordinal not supported\n");
+		exit(0);
+	  }
 	  printf("--- %s %s.%d\n", pe_name->Name, Module, pe_name->Hint);
+	  *thunk_list=RELAY32_GetEntryPoint(Module,pe_name->Name,pe_name->Hint);
+	  if(!*thunk_list)
+	  {
+	  	fprintf(stderr,"No implementation for %s.%d\n",Module, pe_name->Hint);
+		fixup_failed=1;
+	  }
+
 	  import_list++;
+	  thunk_list++;
 	}
       pe_imp++;
     };
+	if(fixup_failed)exit(1);
 }
 
 static void dump_table(struct w_files *wpnt)
@@ -155,19 +180,28 @@
 			wpnt->pe->pe_header->coff.NumberOfSections);
 
 	load_addr = wpnt->pe->pe_header->opt_coff.BaseOfImage;
+	printf("Load addr is %x\n",load_addr);
 	dump_table(wpnt);
 
 	for(i=0; i < wpnt->pe->pe_header->coff.NumberOfSections; i++)
 	{
 	if(!load_addr) {
-		result = xmmap((char *)0, wpnt->pe->pe_seg[i].Size_Of_Raw_Data, 7,
+		result = xmmap((char *)0, wpnt->pe->pe_seg[i].Virtual_Size,
+			wpnt->pe->pe_seg[i].Size_Of_Raw_Data, 7,
 			MAP_PRIVATE, wpnt->fd, wpnt->pe->pe_seg[i].PointerToRawData);
 		load_addr = (unsigned int) result -  wpnt->pe->pe_seg[i].Virtual_Address;
 	} else {
 		result = xmmap((char *) load_addr + wpnt->pe->pe_seg[i].Virtual_Address, 
+			  wpnt->pe->pe_seg[i].Virtual_Size,
 		      wpnt->pe->pe_seg[i].Size_Of_Raw_Data, 7, MAP_PRIVATE | MAP_FIXED, 
 		      wpnt->fd, wpnt->pe->pe_seg[i].PointerToRawData);
 	}
+	if(result==-1){
+		fprintf(stderr,"Could not load section %x to desired address %x\n",
+			i, load_addr+wpnt->pe->pe_seg[i].Virtual_Address);
+		fprintf(stderr,"Need to implement relocations now\n");
+		exit(0);
+	}
 
 	if(strcmp(wpnt->pe->pe_seg[i].Name, ".idata") == 0)
 		wpnt->pe->pe_import = (struct PE_Import_Directory *) result;
@@ -184,7 +218,7 @@
 	    }
 	}
 
-	if(wpnt->pe->pe_import) dump_imports(wpnt->pe->pe_import);
+	if(wpnt->pe->pe_import) fixup_imports(wpnt->pe->pe_import);
 	if(wpnt->pe->pe_export) dump_exports(wpnt->pe->pe_export);
   
 	wpnt->hinstance = 0x8000;
diff --git a/loader/resource.c b/loader/resource.c
index cfc7dbd..adbfc80 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -22,7 +22,6 @@
 #include "dlls.h"
 #include "module.h"
 #include "resource.h"
-#include "library.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -458,6 +457,17 @@
     GlobalFree(hIcon);
     return TRUE;
 }
+
+/**********************************************************************
+ *          DumpIcon [USER.459]
+ */
+DWORD DumpIcon(void* cursorIconInfo, WORD FAR *lpLen, LPSTR FAR *lpXorBits,
+	LPSTR FAR *lpAndMask)
+{
+	dprintf_resource(stdnimp,"DumpIcon: Empty Stub!!!\n");
+	return 0;
+}
+
 
 /**********************************************************************
  *			LoadAccelerators	[USER.177]
diff --git a/loader/selector.c b/loader/selector.c
index f54605a..d04e4f1 100644
--- a/loader/selector.c
+++ b/loader/selector.c
@@ -34,7 +34,6 @@
 #include "global.h"
 #include "dlls.h"
 #include "neexe.h"
-#include "if1632.h"
 #include "prototypes.h"
 #include "module.h"
 #include "stddebug.h"
@@ -49,135 +48,18 @@
 
 extern char WindowsPath[256];
 
-extern char **Argv;
-extern int Argc;
 extern char **environ;
 
 
-/**********************************************************************
- *  Check whether pseudo-functions like __0040H for direct memory
- *  access are referenced and return 1 if so.
- *  FIXME: Reading and writing to the returned selectors has no effect
- *         (e.g. reading from the Bios data segment (esp. clock!) )
- */
-
-unsigned int GetMemoryReference( char *dll_name, char *function,
-                                 WORD *sel, WORD *offset )
-{
-  static HANDLE memory_handles[ 10 ] = { 0,0,0,0,0,0,0,0,0,0 };
-  static char *memory_names[ 10 ] = { "segment 0xA000",
-					"segment 0xB000",
-					"segment 0xB800",
-					"Bios-Rom",
-					"segment 0xD000",
-					"segment 0x0000",
-					"segment 0xE000",
-					"segment 0xF000",
-					"segment 0xC000",
-					"Bios data segment" };
-  short nr;
-
-  if( strcasecmp( dll_name, "KERNEL" ) ) 
-    return 0;
-
-  if( HIWORD( function ) ) {
-    if( ( *function != '_' ) || ( *(function+1) != '_' ) )
-      return 0;
-    if( !strcasecmp( function, "__A000H" ) ) nr = 0;
-    else if( !strcasecmp( function, "__B000H" ) ) nr = 1;
-    else if( !strcasecmp( function, "__B800H" ) ) nr = 2;
-    else if( !strcasecmp( function, "__ROMBIOS" ) ) nr = 3;
-    else if( !strcasecmp( function, "__D000H" ) ) nr = 4;
-    else if( !strcasecmp( function, "__0000H" ) ) nr = 5;
-    else if( !strcasecmp( function, "__E000H" ) ) nr = 6;
-    else if( !strcasecmp( function, "__F000H" ) ) nr = 7;
-    else if( !strcasecmp( function, "__C000H" ) ) nr = 8;
-    else if( !strcasecmp( function, "__0040H" ) ) nr = 9;
-     else
-      return 0;
-  }
-  else {
-    switch( LOWORD( function ) ) {
-    case 174: nr = 0; break;
-    case 181: nr = 1; break;
-    case 182: nr = 2; break;
-    case 173: nr = 3; break;
-    case 179: nr = 4; break;
-    case 183: nr = 5; break;
-    case 190: nr = 6; break;
-    case 194: nr = 7; break;
-    case 195: nr = 8; break;
-    case 193: nr = 9; break;
-    default: return 0;
-    }
-  }
-  
-  if( !memory_handles[ nr ] ) {
-    fprintf( stderr, "Warning: Direct access to %s!\n", memory_names[ nr ] );
-    memory_handles[ nr ] = GlobalAlloc( GMEM_FIXED, 65535 );
-  }
-  *sel = *offset = memory_handles[ nr ];
-  return 1;
-}
- 
-
-
-unsigned int GetEntryDLLName( char * dll_name, char * function,
-                              WORD* sel, WORD *offset )
-{
-    HMODULE hModule;
-    struct dll_table_s *dll_table;
-    int ordinal, addr;
-
-    if( GetMemoryReference( dll_name, function, sel, offset ) )
-        return 0;
-
-    hModule = GetModuleHandle( dll_name );
-    ordinal = MODULE_GetOrdinal( hModule, function );
-    if (!ordinal) return 1;
-    addr = MODULE_GetEntryPoint( hModule, ordinal );
-    if (!addr) return 1;
-#ifdef WINESTAT
-    if ((dll_table = FindDLLTable(dll_name)) != NULL)
-    {
-        dll_table->dll_table[ordinal].used++;
-    }
-#endif
-    *offset = LOWORD(addr);
-    *sel    = HIWORD(addr);
-    return 0;
-}
-
-
-unsigned int GetEntryDLLOrdinal( char * dll_name, int ordinal,
-                                 WORD *sel, WORD *offset )
-{
-    HMODULE hModule;
-    struct dll_table_s *dll_table;
-    int addr;
-
-    if( GetMemoryReference( dll_name, (char*)ordinal, sel, offset ) )
-        return 0;
-
-    hModule = GetModuleHandle( dll_name );
-    addr = MODULE_GetEntryPoint( hModule, ordinal );
-    if (!addr) return 1;
-#ifdef WINESTAT
-    if ((dll_table = FindDLLTable(dll_name)) != NULL)
-        dll_table->dll_table[ordinal].used++;
-#endif
-    *offset = LOWORD(addr);
-    *sel    = HIWORD(addr);
-    return 0;
-}
-
 
 WNDPROC GetWndProcEntry16( char *name )
 {
-    WORD sel, offset;
+    WORD ordinal;
+    static HMODULE hModule = 0;
 
-    GetEntryDLLName( "WINPROCS", name, &sel, &offset );
-    return (WNDPROC) MAKELONG( offset, sel );
+    if (!hModule) hModule = GetModuleHandle( "WINPROCS" );
+    ordinal = MODULE_GetOrdinal( hModule, name );
+    return MODULE_GetEntryPoint( hModule, ordinal );
 }
 
 
diff --git a/loader/signal.c b/loader/signal.c
index c6943de..b395d41 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -114,24 +114,26 @@
     if(signal == SIGTRAP) {
       scp->sc_eip--;
       goto oops;
-    };
-
-    if((scp->sc_cs & 7) != 7)
-    {
+    }
 #endif
-#if defined(__NetBSD__) || defined(__FreeBSD__)
+#ifdef __NetBSD__
+/*         set_es(0x1f); set_ds(0x1f); */
+    if(signal != SIGBUS && signal != SIGSEGV && signal != SIGTRAP) 
+	exit(1);
+#endif
+#ifdef __FreeBSD__
 /*         set_es(0x27); set_ds(0x27); */
     if(signal != SIGBUS && signal != SIGSEGV && signal != SIGTRAP) 
 	exit(1);
-    if(scp->sc_cs == 0x1f)
-    {
 #endif
+    if (scp->sc_cs == WINE_CODE_SELECTOR)
+    {
 	fprintf(stderr,
 		"Segmentation fault in Wine program (%x:%lx)."
 		"  Please debug\n",
 		scp->sc_cs, scp->sc_eip);
 	goto oops;
-    };
+    }
 
     /*  Now take a look at the actual instruction where the program
 	bombed */
diff --git a/loader/task.c b/loader/task.c
index 7f26131..33d53de 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -20,10 +20,12 @@
 #include "stddebug.h"
 #include "debug.h"
 
+  /* Min. number of thunks allocated when creating a new segment */
+#define MIN_THUNKS  32
 
-#define MIN_THUNKS  32  /* Min. thunks allocated when creating a new segment */
-
-#define STACK32_SIZE 0x10000  /* 32-bit stack size for each task */
+  /* 32-bit stack size for each task */
+  /* Must not be greater than 64k, or MAKE_SEGPTR won't work */
+#define STACK32_SIZE 0x10000
 
 
 static HTASK hFirstTask = 0;
@@ -194,7 +196,6 @@
     TDB *pTask = (TDB *)GlobalLock( hCurrentTask );
     NE_MODULE *pModule = (NE_MODULE *)GlobalLock( pTask->hModule );
     SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
-    extern unsigned short WIN_StackSize;
 
     /* Registers at initialization must be:
      * ax   zero
@@ -209,20 +210,17 @@
      * sp   top of the stack
      */
 
-    WIN_StackSize = pModule->stack_size;
-
     cs_reg = pSegTable[pModule->cs - 1].selector;
     ip_reg = pModule->ip;
     ds_reg = pSegTable[pModule->dgroup - 1].selector;
     IF1632_Saved16_ss = pTask->ss;
     IF1632_Saved16_sp = pTask->sp;
-/*    dprintf_task( stddeb, "Starting main program: cs:ip=%04x:%04x ds=%04x ss:sp=%04x:%04x\n",
+    dprintf_task( stddeb, "Starting main program: cs:ip=%04x:%04x ds=%04x ss:sp=%04x:%04x\n",
                  cs_reg, ip_reg, ds_reg,
                  IF1632_Saved16_ss, IF1632_Saved16_sp);
-*/
     CallTo16_regs_( (FARPROC)(cs_reg << 16 | ip_reg), ds_reg,
                    pTask->hPDB /*es*/, 0 /*bp*/, 0 /*ax*/,
-                   WIN_StackSize /*bx*/, pModule->heap_size /*cx*/,
+                   pModule->stack_size /*bx*/, pModule->heap_size /*cx*/,
                    0 /*dx*/, 0 /*si*/, ds_reg /*di*/ );
     /* This should never return */
     fprintf( stderr, "TASK_CallToStart: Main program returned!\n" );
@@ -233,8 +231,8 @@
 /***********************************************************************
  *           TASK_CreateTask
  */
-HTASK TASK_CreateTask( HMODULE hModule, HANDLE hEnvironment,
-                       HTASK hTaskParent, char *cmdLine )
+HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance,
+                       HANDLE hEnvironment, char *cmdLine, WORD cmdShow )
 {
     HTASK hTask;
     TDB *pTask;
@@ -258,15 +256,17 @@
 
       /* Fill the task structure */
 
-    pTask->nEvents   = 1;  /* So the task can be started */
-    pTask->hSelf     = hTask;
-    pTask->flags     = 0;
-    pTask->version   = pModule->expected_version;
-    pTask->hInstance = NE_SEG_TABLE(pModule)[pModule->dgroup-1].selector,
-    pTask->hModule   = hModule;
-    pTask->hParent   = hTaskParent;
-    pTask->curdrive  = 'C' - 'A' + 0x80;
-    pTask->magic     = TDB_MAGIC;
+    pTask->nEvents       = 1;  /* So the task can be started */
+    pTask->hSelf         = hTask;
+    pTask->flags         = 0;
+    pTask->version       = pModule->expected_version;
+    pTask->hInstance     = hInstance;
+    pTask->hPrevInstance = hPrevInstance;
+    pTask->hModule       = hModule;
+    pTask->hParent       = hCurrentTask;
+    pTask->curdrive      = 'C' - 'A' + 0x80;
+    pTask->magic         = TDB_MAGIC;
+    pTask->nCmdShow      = cmdShow;
     strcpy( pTask->curdir, "WINDOWS" );
 
       /* Create the thunks block */
@@ -338,7 +338,7 @@
 
       /* Create the 16-bit stack frame */
 
-    pTask->ss = pSegTable[pModule->ss - 1].selector;
+    pTask->ss = hInstance;
     pTask->sp = (pModule->sp != 0) ? pModule->sp :
                 pSegTable[pModule->ss-1].minsize + pModule->stack_size;
     stack16Top = (char *)PTR_SEG_OFF_TO_LIN( pTask->ss, pTask->sp );
@@ -384,6 +384,10 @@
 
     if (!(pTask = (TDB *)GlobalLock( hTask ))) return;
 
+      /* Free the task module */
+
+    FreeModule( pTask->hModule );
+
       /* Free all memory used by this task (including the 32-bit stack, */
       /* the environment block and the thunk segments). */
 
@@ -394,7 +398,9 @@
     GLOBAL_FreeBlock( pTask->hCSAlias );
     GLOBAL_FreeBlock( pTask->hPDB );
 
-    GlobalFree( hTask );  /* Free the task structure */
+      /* Free the task structure itself */
+
+    GlobalFree( hTask );
 }
 
 
@@ -501,9 +507,42 @@
       /* Switch to the new stack */
 
     hCurrentTask = hTask;
-    IF1632_Saved16_ss  = pNewTask->ss;
-    IF1632_Saved16_sp  = pNewTask->sp;
-    IF1632_Saved32_esp = pNewTask->esp;
+    IF1632_Saved16_ss   = pNewTask->ss;
+    IF1632_Saved16_sp   = pNewTask->sp;
+    IF1632_Saved32_esp  = pNewTask->esp;
+    IF1632_Stack32_base = WIN16_GlobalLock( pNewTask->hStack32 );
+}
+
+
+/***********************************************************************
+ *           InitTask  (KERNEL.91)
+ */
+void InitTask( struct sigcontext_struct context )
+{
+    TDB *pTask;
+    NE_MODULE *pModule;
+
+    context.sc_eax = 0;
+    if (!(pTask = (TDB *)GlobalLock( hCurrentTask ))) return;
+    if (!(pModule = (NE_MODULE *)GlobalLock( pTask->hModule ))) return;
+
+    NE_InitializeDLLs( pTask->hModule );
+
+    /* Registers on return are:
+     * ax     1 if OK, 0 on error
+     * cx     stack limit in bytes
+     * dx     cmdShow parameter
+     * si     instance handle of the previous instance
+     * di     instance handle of the new task
+     * es:bx  pointer to command-line inside PSP
+     */
+    context.sc_eax = 1;
+    context.sc_ebx = 0x81;
+    context.sc_ecx = pModule->stack_size;
+    context.sc_edx = pTask->nCmdShow;
+    context.sc_esi = pTask->hPrevInstance;
+    context.sc_edi = pTask->hInstance;
+    context.sc_es  = pTask->hPDB;
 }
 
 
@@ -650,7 +689,8 @@
     else
         handle = GlobalHandle( HIWORD(proc) );
 
-    printf( "STUB: GetCodeHandle(%p) returning %04x\n", proc, handle );
+    printf( "STUB: GetCodeHandle(%08lx) returning %04x\n",
+            (DWORD)proc, handle );
     return handle;
 }
 
diff --git a/memory/global.c b/memory/global.c
index 32a19f0..7a0a144 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -7,6 +7,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include "windows.h"
+#include "global.h"
 #include "toolhelp.h"
 #include "selectors.h"
 #include "stackframe.h"
@@ -17,7 +18,7 @@
 typedef struct
 {
     DWORD    base;           /* Base address  */
-    DWORD    size;           /* Size in bytes */
+    DWORD    size;           /* Size in bytes (0 indicates a free block) */
     HGLOBAL  handle;         /* Handle for this block */
     HGLOBAL  hOwner;         /* Owner of this block */
     BYTE     lockCount;      /* Count of GlobalFix() calls */
@@ -27,6 +28,7 @@
 } GLOBALARENA;
 
   /* Flags definitions */
+#define GA_MOVEABLE     0x02  /* same as GMEM_MOVEABLE */
 #define GA_DGROUP       0x04
 #define GA_DISCARDABLE  0x08
 
@@ -45,14 +47,16 @@
  */
 static GLOBALARENA *GLOBAL_GetArena( WORD sel, WORD selcount )
 {
-    if (((sel >> __AHSHIFT) + selcount) >= globalArenaSize)
+    if (((sel >> __AHSHIFT) + selcount) > globalArenaSize)
     {
+        int newsize = ((sel >> __AHSHIFT) + selcount + 0xff) & ~0xff;
         GLOBALARENA *pNewArena = realloc( pGlobalArena,
-                               (globalArenaSize + 256) * sizeof(GLOBALARENA) );
+                                          newsize * sizeof(GLOBALARENA) );
         if (!pNewArena) return 0;
         pGlobalArena = pNewArena;
-        memset( pGlobalArena + globalArenaSize, 0, 256 * sizeof(GLOBALARENA) );
-        globalArenaSize += 256;
+        memset( pGlobalArena + globalArenaSize, 0,
+                (newsize - globalArenaSize) * sizeof(GLOBALARENA) );
+        globalArenaSize = newsize;
     }
     return pGlobalArena + (sel >> __AHSHIFT);
 }
@@ -91,7 +95,7 @@
     pArena->hOwner = hOwner;
     pArena->lockCount = 0;
     pArena->pageLockCount = 0;
-    pArena->flags = flags & 0xff;
+    pArena->flags = flags & GA_MOVEABLE;
     if (flags & GMEM_DISCARDABLE) pArena->flags |= GA_DISCARDABLE;
     if (!isCode) pArena->flags |= GA_DGROUP;
     pArena->selCount = selcount;
@@ -188,19 +192,29 @@
     if (!handle) return 0;
     pArena = GET_ARENA_PTR( handle );
 
+      /* Discard the block if requested */
+
+    if ((size == 0) && (flags & GMEM_MOVEABLE))
+    {
+        if (!(pArena->flags & GA_MOVEABLE) ||
+            !(pArena->flags & GA_DISCARDABLE) ||
+            (pArena->lockCount > 0) || (pArena->pageLockCount > 0)) return 0;
+        free( (void *)pArena->base );
+        pArena->base = 0;
+    }
+
       /* Fixup the size */
 
-    if (size >= 0x00ff0000-0x0f) return 0;  /* No allocation > 16Mb-64Kb */
-    if (size == 0) size = 0x10;
-    else size = (size + 0x0f) & ~0x0f;
+    if (size > GLOBAL_MAX_ALLOC_SIZE - 0x20) return 0;
+    if (size == 0) size = 0x20;
+    else size = (size + 0x1f) & ~0x1f;
 
       /* Change the flags */
 
     if (flags & GMEM_MODIFY)
     {
           /* Change the flags, leaving GA_DGROUP alone */
-        pArena->flags = (pArena->flags & GA_DGROUP) |
-                           (flags & ~GA_DGROUP);
+        pArena->flags = (pArena->flags & GA_DGROUP) | (flags & GA_MOVEABLE);
         if (flags & GMEM_DISCARDABLE) pArena->flags |= GA_DISCARDABLE;
         return handle;
     }
@@ -245,7 +259,7 @@
     pNewArena->base = (DWORD)ptr;
     pNewArena->size = GET_SEL_LIMIT(sel) + 1;
     pNewArena->selCount = selcount;
-    pNewArena->handle = (pNewArena->flags & GMEM_MOVEABLE) ? sel - 1 : sel;
+    pNewArena->handle = (pNewArena->flags & GA_MOVEABLE) ? sel - 1 : sel;
 
     if (selcount > 1)  /* clear the next arena blocks */
         memset( pNewArena + 1, 0, (selcount - 1) * sizeof(GLOBALARENA) );
@@ -281,6 +295,7 @@
     dprintf_global( stddeb, "WIN16_GlobalLock(%04x) -> %08lx\n",
                     handle, MAKELONG( 0, GlobalHandleToSel(handle)) );
     if (!handle) return 0;
+    if (!GET_ARENA_PTR(handle)->base) return (SEGPTR)0;
     return (SEGPTR)MAKELONG( 0, GlobalHandleToSel(handle) );
 }
 
@@ -339,7 +354,8 @@
     dprintf_global( stddeb, "GlobalFlags: %04x\n", handle );
     pArena = GET_ARENA_PTR(handle);
     return pArena->lockCount |
-           ((pArena->flags & GA_DISCARDABLE) ? GMEM_DISCARDABLE : 0);
+           ((pArena->flags & GA_DISCARDABLE) ? GMEM_DISCARDABLE : 0) |
+           ((pArena->base == 0) ? GMEM_DISCARDED : 0);
 }
 
 
@@ -632,3 +648,14 @@
 {
     return TRUE;
 }
+
+/***********************************************************************
+ *               GlobalAlloc32
+ * implements    GlobalAlloc        (KERNEL32.316)
+ *               LocalAlloc         (KERNEL32.372)
+ */
+void *GlobalAlloc32(int flags,int size)
+{
+    dprintf_global(stddeb,"GlobalAlloc32(%x,%x)\n",flags,size);
+    return malloc(size);
+}
diff --git a/memory/local.c b/memory/local.c
index c7d5231..134c1bf 100644
--- a/memory/local.c
+++ b/memory/local.c
@@ -243,6 +243,11 @@
         LOCALARENA *pArena = ARENA_PTR(ptr,arena);
         printf( "  %04x: prev=%04x next=%04x type=%d\n", arena,
                 pArena->prev & ~3, pArena->next, pArena->prev & 3 );
+        if (arena == pInfo->first)
+	{
+            printf( "        size=%d free_prev=%04x free_next=%04x\n",
+                    pArena->size, pArena->free_prev, pArena->free_next );
+	}
         if ((pArena->prev & 3) == LOCAL_ARENA_FREE)
         {
             printf( "        size=%d free_prev=%04x free_next=%04x\n",
@@ -377,6 +382,7 @@
       /* Find a suitable free block */
 
     if (!(pInfo = LOCAL_GetHeap( ds ))) {
+      dprintf_local( stddeb, "LocalAlloc: Heap not found\n");
       LOCAL_PrintHeap(ds);
       return 0;
     }
@@ -387,7 +393,8 @@
     for (;;)
     {
         if (arena == pArena->free_next) {
-	  LOCAL_PrintHeap(ds);
+	  fprintf(stderr, "Local heap full\n");
+	  if (debugging_local) LOCAL_PrintHeap(ds);
           return 0;  /* not found */
 	}
         arena = pArena->free_next;
@@ -629,6 +636,8 @@
  */
 WORD LocalCompact( WORD minfree )
 {
+    dprintf_local( stddeb, "LocalCompact: %04x\n", minfree );
+    return 0;
 }
 
 
@@ -637,6 +646,8 @@
  */
 FARPROC LocalNotify( FARPROC func )
 {
+    dprintf_local( stddeb, "LocalNotify: %08lx\n", func );
+    return 0;
 }
 
 
@@ -645,6 +656,8 @@
  */
 WORD LocalShrink( HLOCAL handle, WORD newsize )
 {
+    dprintf_local( stddeb, "LocalShrink: %04x %04x\n", handle, newsize );
+    return 0;
 }
 
 
@@ -662,6 +675,7 @@
  */
 void LocalCountFree()
 {
+    dprintf_local( stddeb, "LocalCountFree:\n" );
 }
 
 
@@ -670,6 +684,7 @@
  */
 WORD LocalHeapSize()
 {
+    dprintf_local( stddeb, "LocalHeapSize:\n" );
     return LOCAL_HeapSize( CURRENT_DS );
 }
 
@@ -679,6 +694,8 @@
  */
 WORD LocalHandleDelta( WORD delta )
 {
+    dprintf_local( stddeb, "LocalHandleDelta: %04x\n", delta );
+    return 0;
 }
 
 
diff --git a/memory/selector.c b/memory/selector.c
index 60556c2..367aae2 100644
--- a/memory/selector.c
+++ b/memory/selector.c
@@ -13,7 +13,7 @@
 
 ldt_copy_entry ldt_copy[LDT_SIZE] = { {0,0}, };
 
-#define FIRST_LDT_ENTRY_TO_ALLOC  4
+#define FIRST_LDT_ENTRY_TO_ALLOC  6
 
 
 /***********************************************************************
diff --git a/misc/Imakefile b/misc/Imakefile
index 5c32ba5..36b097a 100644
--- a/misc/Imakefile
+++ b/misc/Imakefile
@@ -14,12 +14,12 @@
 	escape.c \
 	file.c \
 	keyboard.c \
+	kernel32.c \
 	lstr.c \
 	main.c \
 	ole2nls.c \
 	olecli.c \
 	olesvr.c \
-	message.c \
 	network.c \
 	profile.c \
 	rect.c \
diff --git a/misc/commdlg.c b/misc/commdlg.c
index 356835f..d9a0f31 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -11,10 +11,10 @@
 #include "win.h"
 #include "user.h"
 #include "message.h"
-#include "library.h"
 #include "commdlg.h"
 #include "dlgs.h"
 #include "selectors.h"
+#include "../rc/sysres.h"
 
 #define OPENFILEDLG2			11
 #define SAVEFILEDLG2			12
@@ -57,11 +57,11 @@
  */
 static BOOL FileDlg_Init()
 {
-  if (!hFolder) hFolder = LoadBitmap(hSysRes, MAKEINTRESOURCE(OBM_FOLDER));
-  if (!hFolder2) hFolder2 = LoadBitmap(hSysRes, MAKEINTRESOURCE(OBM_FOLDER2));
-  if (!hFloppy) hFloppy = LoadBitmap(hSysRes, MAKEINTRESOURCE(OBM_FLOPPY));
-  if (!hHDisk) hHDisk = LoadBitmap(hSysRes, MAKEINTRESOURCE(OBM_HDISK));
-  if (!hCDRom) hCDRom = LoadBitmap(hSysRes, MAKEINTRESOURCE(OBM_CDROM));
+  if (!hFolder) hFolder = LoadBitmap(0, MAKEINTRESOURCE(OBM_FOLDER));
+  if (!hFolder2) hFolder2 = LoadBitmap(0, MAKEINTRESOURCE(OBM_FOLDER2));
+  if (!hFloppy) hFloppy = LoadBitmap(0, MAKEINTRESOURCE(OBM_FLOPPY));
+  if (!hHDisk) hHDisk = LoadBitmap(0, MAKEINTRESOURCE(OBM_HDISK));
+  if (!hCDRom) hCDRom = LoadBitmap(0, MAKEINTRESOURCE(OBM_CDROM));
   if (hFolder == 0 || hFolder2 == 0 || hFloppy == 0 || 
       hHDisk == 0 || hCDRom == 0)
   fprintf(stderr, "FileDlg_Init // Error loading bitmaps !");
@@ -69,6 +69,36 @@
 }
 
 /***********************************************************************
+ *                              OpenDlg_FixDirName              [internal]
+ */
+void OpenDlg_FixDirName(LPSTR dirname)
+{
+  char temp[512];
+  char* strp1;
+  char* strp2;
+
+  strp1=dirname;
+  if( dirname[1] != ':'){
+    temp[0]=(char)((char)DOS_GetDefaultDrive()+'A');
+    temp[1]=':';
+    temp[2]='\\';
+    temp[3]= '\0';
+    strcat(temp, DOS_GetCurrentDir(DOS_GetDefaultDrive()));
+    if(dirname[0]=='.' && dirname[1]=='.') {
+      strp2 = strrchr(temp, '\\');
+      if (strp2 != NULL){
+	*strp2='\0';
+	strp1+=2;
+      }
+    }
+    strcat(temp, "\\");
+    strcat(temp, strp1);
+    strcpy(dirname, temp);
+  } 
+}
+  
+
+/***********************************************************************
  * 				OpenDlg_ScanDir			[internal]
  */
 static BOOL OpenDlg_ScanDir(HWND hWnd, LPSTR newPath)
@@ -77,13 +107,14 @@
   static LPSTR  str  = NULL;
   static SEGPTR str16 = 0;
   LPSTR strp;
-  
+
+  OpenDlg_FixDirName(newPath);
   if (str == NULL)  {
     hStr = GlobalAlloc(0,512);
     str = GlobalLock(hStr);
     str16 = WIN16_GlobalLock(hStr);
   }
-  
+
   strcpy(str,newPath);
   DlgDirList(hWnd, str, lst1, 0, 0x0000);
   strp = strrchr(str,'\\');
@@ -96,37 +127,27 @@
   } else strp++;
   strcpy(str,strp);
   SendDlgItemMessage(hWnd,edt1,WM_SETTEXT, 0, str16);
-  strcpy(str,newPath);
-  *strp = 0;
-  strcat(str,"*.*");
+  strcpy(str,"*.*");
   DlgDirList(hWnd, str, lst2, stc1, 0x8010);
   
   return TRUE;
 }
 
-
-
 /***********************************************************************
  * 				OpenDlg_GetFileType		[internal]
  */
-LPSTR OpenDlg_GetFileType(LPCSTR types, WORD index)
+static LPSTR OpenDlg_GetFileType(LPCSTR types, WORD index)
 {
 	int		n;
 	int		i = 1;
 	LPSTR 	ptr = (LPSTR) types;
 	if	(ptr == NULL) return NULL;
 	while((n = strlen(ptr)) != 0) {
-#ifdef DEBUG_OPENDLG
-		printf("OpenDlg_GetFileType // file type '%s' !\n", ptr);
-#endif
 		ptr += ++n;
-#ifdef DEBUG_OPENDLG
-		printf("OpenDlg_GetFileType // file spec '%s' !\n", ptr);
-#endif
 		if (i++ == index) return ptr;
 		n = strlen(ptr);
 		ptr += ++n;
-		}
+	}
 	return NULL;
 }
 
@@ -135,45 +156,45 @@
  */
 BOOL GetOpenFileName(LPOPENFILENAME lpofn)
 {
-	HANDLE		hDlgTmpl;
-	HANDLE		hResInfo;
-	HINSTANCE	hInst;
-	WND 		*wndPtr;
-	BOOL		bRet;
-
-        if (lpofn == NULL) return FALSE;
-	if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE) {
-		hDlgTmpl = lpofn->hInstance;
-	} else {
-		if (lpofn->Flags & OFN_ENABLETEMPLATE) {
-			hInst = lpofn->hInstance;
-			hResInfo = FindResource(hInst,
-				lpofn->lpTemplateName, RT_DIALOG);
-		} else {
-			hInst = hSysRes;
-			hResInfo = FindResource(hInst, MAKEINTRESOURCE(OPENFILEDLG2), RT_DIALOG);
-		}
-		if (hResInfo == 0) {
-			CommDlgLastError = CDERR_FINDRESFAILURE;
-			return FALSE;
-		}
-		printf("GetOpenFileName // apres FindResource hResInfo=%04X!\n", hResInfo);
-		hDlgTmpl = LoadResource(hInst, hResInfo);
-       	}
-	if (hDlgTmpl == 0) {
-		CommDlgLastError = CDERR_LOADRESFAILURE;
-		return FALSE;
-	}
-	printf("GetOpenFileName // apres LoadResource hDlgTmpl=%04X!\n", hDlgTmpl);
-        wndPtr = WIN_FindWndPtr(lpofn->hwndOwner);
-	bRet = DialogBoxIndirectParam(wndPtr->hInstance, hDlgTmpl,
-                                      lpofn->hwndOwner,
-                                      GetWndProcEntry16("FileOpenDlgProc"),
-                                      (DWORD)lpofn); 
-
-	printf("GetOpenFileName // return lpstrFile='%s' !\n", 
-	       (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
-	return bRet;
+  HANDLE    hDlgTmpl;
+  HANDLE    hResInfo;
+  HINSTANCE hInst;
+  BOOL 	    bRet;
+  LPCSTR    dlgTemplate;
+  
+  if (lpofn == NULL) return FALSE;
+  if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE) {
+    dlgTemplate = GlobalLock(lpofn->hInstance);
+    if (!dlgTemplate) {
+      CommDlgLastError = CDERR_LOADRESFAILURE;
+      return FALSE;
+    }
+  } else {
+    if (lpofn->Flags & OFN_ENABLETEMPLATE) {
+      hInst = lpofn->hInstance;
+      hResInfo = FindResource(hInst, lpofn->lpTemplateName, RT_DIALOG);
+      if (hResInfo == 0) {
+	CommDlgLastError = CDERR_FINDRESFAILURE;
+	return FALSE;
+      }
+      hDlgTmpl = LoadResource(hInst, hResInfo);
+      if (hDlgTmpl == 0) {
+	CommDlgLastError = CDERR_LOADRESFAILURE;
+	return FALSE;
+      }
+      dlgTemplate = GlobalLock(hDlgTmpl);
+    } else {
+      dlgTemplate = sysres_DIALOG_3;
+    }
+  }
+  hInst = GetWindowWord(lpofn->hwndOwner, GWW_HINSTANCE);
+  bRet = DialogBoxIndirectParamPtr(hInst, dlgTemplate, lpofn->hwndOwner,
+				   GetWndProcEntry16("FileOpenDlgProc"),
+				   (DWORD)lpofn); 
+  
+  printf("GetOpenFileName // return lpstrFile='%s' !\n", 
+	 (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
+  return bRet;
 }
 
 
@@ -182,42 +203,44 @@
  */
 BOOL GetSaveFileName(LPOPENFILENAME lpofn)
 {
-        HANDLE	        hDlgTmpl;
-        HANDLE	        hResInfo;
-        HINSTANCE       hInst;
-        WND 	        *wndPtr;
-        BOOL	        bRet;
-
-        if (lpofn == NULL) return FALSE;
-	if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE) {
-		hDlgTmpl = lpofn->hInstance;
-	} else {
-		if (lpofn->Flags & OFN_ENABLETEMPLATE) {
-			hInst = lpofn->hInstance;
-                        hResInfo = FindResource(hInst, lpofn->lpTemplateName,
-						RT_DIALOG);
-		} else {
-			hInst = hSysRes;
-			hResInfo = FindResource(hInst, MAKEINTRESOURCE(SAVEFILEDLG2), RT_DIALOG);
-		}
-		if (hResInfo == 0) {
-			CommDlgLastError = CDERR_FINDRESFAILURE;
-			return FALSE;
-		}
-		hDlgTmpl = LoadResource(hInst, hResInfo);
-	}
-	if (hDlgTmpl == 0) {
-		CommDlgLastError = CDERR_LOADRESFAILURE;
-		return FALSE;
-	}
-        wndPtr = WIN_FindWndPtr(lpofn->hwndOwner);
-	bRet = DialogBoxIndirectParam(wndPtr->hInstance, hDlgTmpl, 
-                                      lpofn->hwndOwner,
-                                      GetWndProcEntry16("FileSaveDlgProc"),
-                                      (DWORD)lpofn );
-	printf("GetSaveFileName // return lpstrFile='%s' !\n", 
-	       (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
-	return bRet;
+  HANDLE    hDlgTmpl;
+  HANDLE    hResInfo;
+  HINSTANCE hInst;
+  BOOL	    bRet;
+  LPCSTR    dlgTemplate;
+  
+  if (lpofn == NULL) return FALSE;
+  if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE) {
+    dlgTemplate = GlobalLock(lpofn->hInstance);
+    if (!dlgTemplate) {
+      CommDlgLastError = CDERR_LOADRESFAILURE;
+      return FALSE;
+    }
+  } else {
+    if (lpofn->Flags & OFN_ENABLETEMPLATE) {
+      hInst = lpofn->hInstance;
+      hResInfo = FindResource(hInst, lpofn->lpTemplateName, RT_DIALOG);
+      if (hResInfo == 0) {
+	CommDlgLastError = CDERR_FINDRESFAILURE;
+	return FALSE;
+      }
+      hDlgTmpl = LoadResource(hInst, hResInfo);
+      if (hDlgTmpl == 0) {
+	CommDlgLastError = CDERR_LOADRESFAILURE;
+	return FALSE;
+      }
+      dlgTemplate = GlobalLock(hDlgTmpl);
+    } else {
+      dlgTemplate = sysres_DIALOG_4; /* SAVEFILEDIALOG */
+    }
+  }
+  hInst = GetWindowWord(lpofn->hwndOwner, GWW_HINSTANCE);
+  bRet = DialogBoxIndirectParamPtr(hInst, dlgTemplate, lpofn->hwndOwner,
+				   GetWndProcEntry16("FileSaveDlgProc"),
+				   (DWORD)lpofn); 
+  printf("GetSaveFileName // return lpstrFile='%s' !\n", 
+	 (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
+  return bRet;
 }
 
 
@@ -228,13 +251,10 @@
 {
         WND     *wndPtr;
 	BOOL	bRet;
-
         wndPtr = WIN_FindWndPtr(lpChCol->hwndOwner);
-	bRet = DialogBoxParam( wndPtr->hInstance,
-                               MAKEINTRESOURCE(COLORDLG), 
-                               lpChCol->hwndOwner,
-                               GetWndProcEntry16("ColorDlgProc"), 
-                               (DWORD)lpChCol);
+	bRet = DialogBoxIndirectParamPtr(wndPtr->hInstance, sysres_DIALOG_8,
+		lpChCol->hwndOwner, GetWndProcEntry16("ColorDlgProc"), 
+		(DWORD)lpChCol);
 	return bRet;
 }
 
@@ -459,13 +479,11 @@
 #endif
       break;
      case IDOK:
-      SendDlgItemMessage(hWnd, edt1, WM_GETTEXT, 0, str16);
-      printf("OK: str %s\n",str);
+      SendDlgItemMessage(hWnd, edt1, WM_GETTEXT, 511, str16);
       if (COMMDLG_IsPathName(str)) {
 	OpenDlg_ScanDir(hWnd, str);
       } else  {	
 	ShowWindow(hWnd, SW_HIDE); 
-	printf("FileOpenDlgProc // IDOK str='%s'\n", str);
 	strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFile), str);
 	lpofn->nFileOffset = 0;
 	lpofn->nFileExtension = strlen(PTR_SEG_TO_LIN(lpofn->lpstrFile)) - 3;
@@ -723,7 +741,7 @@
 #endif
       break;
      case IDOK:
-      SendDlgItemMessage(hWnd, edt1, WM_GETTEXT, 0, str16);
+      SendDlgItemMessage(hWnd, edt1, WM_GETTEXT, 511, str16);
       if (COMMDLG_IsPathName(str)) {
 	OpenDlg_ScanDir(hWnd, str);
       } else  {	
@@ -797,26 +815,16 @@
  */
 BOOL FindText(LPFINDREPLACE lpFind)
 {
-	HANDLE	hDlgTmpl;
-	HANDLE	hResInfo;
-    WND 	*wndPtr;
-	BOOL	bRet;
-	hResInfo = FindResource(hSysRes, MAKEINTRESOURCE(FINDDLG), RT_DIALOG);
-	if (hResInfo == 0) {
-		CommDlgLastError = CDERR_FINDRESFAILURE;
-		return FALSE;
-		}
-	hDlgTmpl = LoadResource(hSysRes, hResInfo);
-	if (hDlgTmpl == 0) {
-		CommDlgLastError = CDERR_LOADRESFAILURE;
-		return FALSE;
-		}
-    wndPtr = WIN_FindWndPtr(lpFind->hwndOwner);
-	bRet = DialogBoxIndirectParam(wndPtr->hInstance, hDlgTmpl,
-                                      lpFind->hwndOwner,
-                                      GetWndProcEntry16("FindTextDlgProc"),
-                                      (DWORD)lpFind);
-	return bRet;
+  WND    *wndPtr;
+  BOOL   bRet;
+  LPCSTR lpTemplate;
+  
+  lpTemplate = sysres_DIALOG_9;
+  wndPtr = WIN_FindWndPtr(lpFind->hwndOwner);
+  bRet = DialogBoxIndirectParamPtr(wndPtr->hInstance, lpTemplate,
+				lpFind->hwndOwner, GetWndProcEntry16("FindTextDlgProc"),
+				(DWORD)lpFind);
+  return bRet;
 }
 
 
@@ -825,26 +833,16 @@
  */
 BOOL ReplaceText(LPFINDREPLACE lpFind)
 {
-	HANDLE	hDlgTmpl;
-	HANDLE	hResInfo;
-    WND 	*wndPtr;
-	BOOL	bRet;
-	hResInfo = FindResource(hSysRes, MAKEINTRESOURCE(REPLACEDLG), RT_DIALOG);
-	if (hResInfo == 0) {
-		CommDlgLastError = CDERR_FINDRESFAILURE;
-		return FALSE;
-		}
-	hDlgTmpl = LoadResource(hSysRes, hResInfo);
-	if (hDlgTmpl == 0) {
-		CommDlgLastError = CDERR_LOADRESFAILURE;
-		return FALSE;
-		}
-    wndPtr = WIN_FindWndPtr(lpFind->hwndOwner);
-	bRet = DialogBoxIndirectParam(wndPtr->hInstance, hDlgTmpl,
-                                      lpFind->hwndOwner,
-                                      GetWndProcEntry16("ReplaceTextDlgProc"),
-                                      (DWORD)lpFind);
-	return bRet;
+  WND    *wndPtr;
+  BOOL   bRet;
+  LPCSTR lpTemplate;
+
+  lpTemplate = sysres_DIALOG_10;
+  wndPtr = WIN_FindWndPtr(lpFind->hwndOwner);
+  bRet = DialogBoxIndirectParamPtr(wndPtr->hInstance, lpTemplate,
+				   lpFind->hwndOwner, GetWndProcEntry16("ReplaceTextDlgProc"),
+				   (DWORD)lpFind);
+  return bRet;
 }
 
 
@@ -853,24 +851,24 @@
  */
 BOOL FindTextDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam)
 {
-	switch (wMsg) {
-		case WM_INITDIALOG:
-			printf("FindTextDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
-			ShowWindow(hWnd, SW_SHOWNORMAL);
-			return (TRUE);
-
-		case WM_COMMAND:
-			switch (wParam) {
-				case IDOK:
-					EndDialog(hWnd, TRUE);
-					return(TRUE);
-				case IDCANCEL:
-					EndDialog(hWnd, FALSE);
-					return(TRUE);
-				}
-			return(FALSE);
-		}
-	return FALSE;
+  switch (wMsg) {
+   case WM_INITDIALOG:
+    printf("FindTextDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
+    ShowWindow(hWnd, SW_SHOWNORMAL);
+    return (TRUE);
+    
+   case WM_COMMAND:
+    switch (wParam) {
+     case IDOK:
+      EndDialog(hWnd, TRUE);
+      return(TRUE);
+     case IDCANCEL:
+      EndDialog(hWnd, FALSE);
+      return(TRUE);
+    }
+    return(FALSE);
+  }
+  return FALSE;
 }
 
 
@@ -879,24 +877,24 @@
  */
 BOOL ReplaceTextDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam)
 {
-	switch (wMsg) {
-		case WM_INITDIALOG:
-			printf("ReplaceTextDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
-			ShowWindow(hWnd, SW_SHOWNORMAL);
-			return (TRUE);
-
-		case WM_COMMAND:
-			switch (wParam) {
-				case IDOK:
-					EndDialog(hWnd, TRUE);
-					return(TRUE);
-				case IDCANCEL:
-					EndDialog(hWnd, FALSE);
-					return(TRUE);
-				}
-			return(FALSE);
-		}
-	return FALSE;
+  switch (wMsg) {
+   case WM_INITDIALOG:
+    printf("ReplaceTextDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
+    ShowWindow(hWnd, SW_SHOWNORMAL);
+    return (TRUE);
+    
+   case WM_COMMAND:
+    switch (wParam) {
+     case IDOK:
+      EndDialog(hWnd, TRUE);
+      return(TRUE);
+     case IDCANCEL:
+      EndDialog(hWnd, FALSE);
+      return(TRUE);
+    }
+    return(FALSE);
+  }
+  return FALSE;
 }
 
 
@@ -905,36 +903,26 @@
  */
 BOOL PrintDlg(LPPRINTDLG lpPrint)
 {
-	HANDLE	hDlgTmpl;
-	HANDLE	hResInfo;
-    WND 	*wndPtr;
-	BOOL	bRet;
-	printf("PrintDlg(%p) // Flags=%08lX\n", lpPrint, lpPrint->Flags);
-	if (lpPrint->Flags & PD_PRINTSETUP)
-		hResInfo = FindResource(hSysRes, MAKEINTRESOURCE(PRINTSETUPDLG), RT_DIALOG);
-	else
-		hResInfo = FindResource(hSysRes, MAKEINTRESOURCE(PRINTDLG), RT_DIALOG);
-	if (hResInfo == 0) {
-		CommDlgLastError = CDERR_FINDRESFAILURE;
-		return FALSE;
-		}
-	hDlgTmpl = LoadResource(hSysRes, hResInfo);
-	if (hDlgTmpl == 0) {
-		CommDlgLastError = CDERR_LOADRESFAILURE;
-		return FALSE;
-		}
-    wndPtr = WIN_FindWndPtr(lpPrint->hwndOwner);
-	if (lpPrint->Flags & PD_PRINTSETUP)
-            bRet = DialogBoxIndirectParam(wndPtr->hInstance, hDlgTmpl,
-                                          lpPrint->hwndOwner,
-                                          GetWndProcEntry16("PrintSetupDlgProc"),
-                                          (DWORD)lpPrint);
-	else
-            bRet = DialogBoxIndirectParam(wndPtr->hInstance, hDlgTmpl,
-                                          lpPrint->hwndOwner,
-                                          GetWndProcEntry16("PrintDlgProc"),
-                                          (DWORD)lpPrint);
-	return bRet;
+  WND    *wndPtr;
+  BOOL   bRet;
+  LPCSTR lpTemplate;
+  
+  printf("PrintDlg(%p) // Flags=%08lX\n", lpPrint, lpPrint->Flags);
+  if (lpPrint->Flags & PD_PRINTSETUP)  {
+    lpTemplate = sysres_DIALOG_6;
+  } else  {
+    lpTemplate = sysres_DIALOG_5;
+  }
+  wndPtr = WIN_FindWndPtr(lpPrint->hwndOwner);
+  if (lpPrint->Flags & PD_PRINTSETUP)
+  bRet = DialogBoxIndirectParamPtr(wndPtr->hInstance, lpTemplate,
+				   lpPrint->hwndOwner, GetWndProcEntry16("PrintSetupDlgProc"),
+				   (DWORD)lpPrint);
+  else
+  bRet = DialogBoxIndirectParamPtr(wndPtr->hInstance, lpTemplate,
+				   lpPrint->hwndOwner, GetWndProcEntry16("PrintDlgProc"),
+				   (DWORD)lpPrint);
+  return bRet;
 }
 
 
@@ -943,24 +931,24 @@
  */
 BOOL PrintDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam)
 {
-	switch (wMsg) {
-		case WM_INITDIALOG:
-			printf("PrintDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
-			ShowWindow(hWnd, SW_SHOWNORMAL);
-			return (TRUE);
-
-		case WM_COMMAND:
-			switch (wParam) {
-				case IDOK:
-					EndDialog(hWnd, TRUE);
-					return(TRUE);
-				case IDCANCEL:
-					EndDialog(hWnd, FALSE);
-					return(TRUE);
-				}
-			return(FALSE);
-		}
-	return FALSE;
+  switch (wMsg) {
+   case WM_INITDIALOG:
+    printf("PrintDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
+    ShowWindow(hWnd, SW_SHOWNORMAL);
+    return (TRUE);
+    
+   case WM_COMMAND:
+    switch (wParam) {
+     case IDOK:
+      EndDialog(hWnd, TRUE);
+      return(TRUE);
+     case IDCANCEL:
+      EndDialog(hWnd, FALSE);
+      return(TRUE);
+    }
+    return(FALSE);
+  }
+  return FALSE;
 }
 
 
@@ -969,24 +957,24 @@
  */
 BOOL PrintSetupDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam)
 {
-	switch (wMsg) {
-		case WM_INITDIALOG:
-			printf("PrintSetupDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
-			ShowWindow(hWnd, SW_SHOWNORMAL);
-			return (TRUE);
-
-		case WM_COMMAND:
-			switch (wParam) {
-				case IDOK:
-					EndDialog(hWnd, TRUE);
-					return(TRUE);
-				case IDCANCEL:
-					EndDialog(hWnd, FALSE);
-					return(TRUE);
-				}
-			return(FALSE);
-		}
-	return FALSE;
+  switch (wMsg) {
+   case WM_INITDIALOG:
+    printf("PrintSetupDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
+    ShowWindow(hWnd, SW_SHOWNORMAL);
+    return (TRUE);
+    
+   case WM_COMMAND:
+    switch (wParam) {
+     case IDOK:
+      EndDialog(hWnd, TRUE);
+      return(TRUE);
+     case IDCANCEL:
+      EndDialog(hWnd, FALSE);
+      return(TRUE);
+    }
+    return(FALSE);
+  }
+  return FALSE;
 }
 
 
@@ -1004,7 +992,7 @@
  */
 int GetFileTitle(LPCSTR lpFile, LPSTR lpTitle, UINT cbBuf)
 {
-	int		i, len;
+	int    	i, len;
 	printf("GetFileTitle(%p %p %d); \n", lpFile, lpTitle, cbBuf);
 	if (lpFile == NULL || lpTitle == NULL) return -1;
 	len = strlen(lpFile);
@@ -1015,13 +1003,11 @@
 	len--;
 	if (lpFile[len] == '/' || lpFile[len] == '\\' || lpFile[len] == ':') return -1;
 	for (i = len; i >= 0; i--) {
-		if (lpFile[i] == '/' || 
-			lpFile[i] == '\\' || 
-			lpFile[i] == ':') {
-			i++;
-			break;
-			}
-		}
+	  if (lpFile[i] == '/' ||  lpFile[i] == '\\' ||  lpFile[i] == ':') {
+	    i++;
+	    break;
+	  }
+	}
 	printf("\n---> '%s' ", &lpFile[i]);
 	len = min(cbBuf, strlen(&lpFile[i]) + 1);
 	strncpy(lpTitle, &lpFile[i], len + 1);
diff --git a/misc/exec.c b/misc/exec.c
index e10cb21..ad55c1c 100644
--- a/misc/exec.c
+++ b/misc/exec.c
@@ -11,10 +11,7 @@
 #include "prototypes.h"
 #include "dlls.h"
 #include "windows.h"
-#include "if1632.h"
 #include "callback.h"
-#include "library.h"
-#include "ne_image.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -33,88 +30,6 @@
 #define HELP_MULTIKEY     0x0201
 #define HELP_SETWINPOS    0x0203
 
-typedef struct {
-	WORD	wEnvSeg;
-	LPSTR	lpCmdLine;
-	LPVOID	lpCmdShow;
-	DWORD	dwReserved;
-	} PARAMBLOCK;
-
-typedef BOOL (CALLBACK * LPFNWINMAIN)(HANDLE, HANDLE, LPSTR, int);
-
-
-/**********************************************************************
- *				LoadModule	[KERNEL.45]
- */
-HANDLE LoadModule(LPSTR modulefile, LPVOID lpParamBlk)
-{
-	PARAMBLOCK  *pblk = lpParamBlk;
-	WORD 	*lpCmdShow;
-    	dprintf_exec(stddeb,"LoadModule '%s' %p\n", modulefile, lpParamBlk);
-	if (lpParamBlk == NULL) return 0;
-	lpCmdShow = (WORD *)pblk->lpCmdShow;
-	return WinExec(pblk->lpCmdLine, lpCmdShow[1]);
-}
-
-
-/**********************************************************************
- *				WinExec		[KERNEL.166]
- */
-WORD WinExec(LPSTR lpCmdLine, WORD nCmdShow)
-{
-	int 		c = 0;
-	int 		x, x2;
-	char 		*ArgV[20];
-	HINSTANCE	hInst = 0;
-	HANDLE		hTask = 0;
-    	dprintf_exec(stddeb,"WinExec('%s', %04X)\n", lpCmdLine, nCmdShow);
-/*	ArgV[0] = "wine";
-	c = 1; */
-	for (x = x2 = 0; x < strlen(lpCmdLine) + 1; x++) {
-		if ((lpCmdLine[x] == ' ') || (lpCmdLine[x] == '\0')) {
-			ArgV[c] = (char *)malloc(x - x2 + 1);
-			strncpy(ArgV[c], &lpCmdLine[x2], x - x2);
-			ArgV[c][x - x2] = '\0';
-			c++;   x2 = x + 1;
-			}							  
-		}  
-	ArgV[c] = NULL;
-    for (c = 0; ArgV[c] != NULL; c++) 
-	dprintf_exec(stddeb,"--> '%s' \n", ArgV[c]);
-
-        if ((hInst = LoadImage(ArgV[0], EXE, 1)) == (HINSTANCE) NULL ) {
-            fprintf(stderr, "wine: can't find %s!.\n", ArgV[0]);
-        }
-#if 0
-	switch(fork()) {
-		case -1:
-            fprintf(stderr,"Can't 'fork' process !\n");
-			break;
-		case 0:
-			if ((hInst = LoadImage(ArgV[0], EXE, 1)) == (HINSTANCE) NULL ) {
-				fprintf(stderr, "wine: can't find %s!.\n", ArgV[0]);
-                		fprintf(stderr,"Child process died !\n");
-				exit(1);
-				}
-			StartNewTask(hInst); 
-/*			hTask = CreateNewTask(0);
-            		dprintf_exec(stddeb,
-				"WinExec // New Task hTask=%04X !\n", hTask);
-			execvp(ArgV[0], ArgV); */
-
-            		fprintf(stderr,"Child process died !\n");
-			exit(1);
-		default:
-            		dprintf_exec(stddeb,
-			"WinExec (Main process stay alive) hTask=%04X !\n", 
-			hTask);
-			break;         
-		}
-#endif
-	for (c = 0; ArgV[c] != NULL; c++) 	free(ArgV[c]);
-	return hTask;
-}
-
 
 /**********************************************************************
  *				ExitWindows		[USER.7]
diff --git a/misc/file.c b/misc/file.c
index c71673a..31c2cfc 100644
--- a/misc/file.c
+++ b/misc/file.c
@@ -42,13 +42,19 @@
 {
   int  handle;
   char *UnixFileName;
+  int mode = 0;
 
   dprintf_file(stddeb, "_lopen: open('%s', %X);\n", lpPathName, iReadWrite);
   if ((UnixFileName = DOS_GetUnixFileName(lpPathName)) == NULL)
   	return HFILE_ERROR;
-  iReadWrite &= 0x000F;
-  handle =  open (UnixFileName, iReadWrite);
-  if( ( handle == -1 ) && Options.allowReadOnly )
+  switch(iReadWrite & 3)
+  {
+  case OF_READ:      mode = O_RDONLY; break;
+  case OF_WRITE:     mode = O_WRONLY; break;
+  case OF_READWRITE: mode = O_RDWR; break;
+  }
+  handle = open( UnixFileName, mode );
+  if (( handle == -1 ) && Options.allowReadOnly)
     handle = open( UnixFileName, O_RDONLY );
 
   dprintf_file(stddeb, "_lopen: open: %s (handle %d)\n", UnixFileName, handle);
@@ -112,17 +118,14 @@
  **************************************************************************/
 INT OpenFile (LPSTR lpFileName, LPOFSTRUCT ofs, WORD wStyle)
 {
-#ifdef WINELIB
-    dprintf_file(stdnimp, "OpenFile: not implemented\n");
-#else
-    char                      filename[MAX_PATH+1];
-    int                       action;
-    struct stat               s;
-    struct tm                 *now;
-    int                       res;
-    int                       verify_time;
+    char         filename[MAX_PATH+1];
+    int          action;
+    struct stat  s;
+    struct tm   *now;
+    int          res, handle;
+    int          verify_time;
   
-    dprintf_file(stddeb,"Openfile(%s,<struct>,%d) ",lpFileName,wStyle);
+    dprintf_file(stddeb,"Openfile(%s,<struct>,%d)\n",lpFileName,wStyle);
   
     action = wStyle & 0xff00;
   
@@ -131,31 +134,29 @@
        handle it first */
 
     if (action & OF_CREATE)
-      {
-      int handle;
-      char *unixfilename;
+    {
+        char *unixfilename;
 
-      if (!(action & OF_REOPEN))
-        strcpy(ofs->szPathName, lpFileName);
-      ofs->cBytes = sizeof(OFSTRUCT);
-      ofs->fFixedDisk = FALSE;
-      ofs->nErrCode = 0;
-      *((int*)ofs->reserved) = 0;
+        if (!(action & OF_REOPEN)) strcpy(ofs->szPathName, lpFileName);
+        ofs->cBytes = sizeof(OFSTRUCT);
+        ofs->fFixedDisk = FALSE;
+        ofs->nErrCode = 0;
+        *((int*)ofs->reserved) = 0;
 
-      if ((unixfilename = DOS_GetUnixFileName (ofs->szPathName)) == NULL)
-      {
-        errno_to_doserr();
-	ofs->nErrCode = ExtendedError;
-        return -1;
-      }
-      handle = open (unixfilename, (wStyle & 0x0003) | O_CREAT, 0x666);
-      if (handle == -1)
-      {
-	errno_to_doserr();
-	ofs->nErrCode = ExtendedError;
-      }   
-      return handle;
-      }
+        if ((unixfilename = DOS_GetUnixFileName (ofs->szPathName)) == NULL)
+        {
+            errno_to_doserr();
+            ofs->nErrCode = ExtendedError;
+            return -1;
+        }
+        handle = open (unixfilename, (wStyle & 0x0003) | O_CREAT, 0x666);
+        if (handle == -1)
+        {
+            errno_to_doserr();
+            ofs->nErrCode = ExtendedError;
+        }   
+        return handle;
+    }
 
 
     /* If path isn't given, try to find the file. */
@@ -166,27 +167,53 @@
 	      index(lpFileName,':')))
 	while(1)
 	{
-	  char temp[MAX_PATH+1];
+          char temp[MAX_PATH+1];
+          /* Try current directory */
 	  strcpy (filename, lpFileName);
 	  if ( (!stat(DOS_GetUnixFileName(filename), &s)) && (S_ISREG(s.st_mode)) )
 	    break;
+
+          /* Try Windows directory */
+
 	  GetWindowsDirectory (filename,MAX_PATH);
 	  if ((!filename[0])||(filename[strlen(filename)-1]!='\\'))
             strcat(filename, "\\");
 	  strcat (filename, lpFileName);
 	  if ( (!stat(DOS_GetUnixFileName(filename), &s)) && (S_ISREG(s.st_mode)) )
 	    break;
+
+          /* Try Windows system directory */
+
 	  GetSystemDirectory (filename,MAX_PATH);
 	  if ((!filename[0])||(filename[strlen(filename)-1]!='\\'))
  	    strcat(filename, "\\");
 	  strcat (filename, lpFileName);
 	  if ( (!stat(DOS_GetUnixFileName(filename), &s)) && (S_ISREG(s.st_mode)) )
 	    break;
-	  if (!DOS_FindFile(temp,MAX_PATH,lpFileName,NULL,WindowsPath))
-	    {
+
+          /* Try the path of the current executable */
+
+          if (GetCurrentTask())
+          {
+              char *p;
+              GetModuleFileName( GetCurrentTask(), filename, MAX_PATH );
+              if ((p = strrchr( filename, '\\' )))
+              {
+                  p[1] = '\0';
+                  strcat( filename, lpFileName );
+                  if ((!stat(DOS_GetUnixFileName(filename), &s)) &&
+                      (S_ISREG(s.st_mode)) )
+                      break;
+              }
+          }
+
+          /* Try all directories in path */
+
+	  if (DOS_FindFile(temp,MAX_PATH,lpFileName,NULL,WindowsPath))
+          {
 	      strcpy(filename, DOS_GetDosFileName(temp));
 	      break;
-	    }
+          }
 	  strcpy (filename, lpFileName);
 	  break;
 	}
@@ -235,47 +262,15 @@
     if (action & OF_EXIST)
       return 0;
     
-   /* Now we are actually going to open the file. According to Microsoft's
-       Knowledge Basis, this is done by calling int 21h, ax=3dh. */    
-
-#if 0
-    AX = 0x3d00;
-    AL = (AL & 0x0f) | (wStyle & 0x70); /* Handle OF_SHARE_xxx etc. */
-    AL = (AL & 0xf0) | (wStyle & 0x03); /* Handle OF_READ etc. */
-    DS = SELECTOROF(ofs->szPathName);
-    DX = OFFSETOF(ofs->szPathName);
-  
-    OpenExistingFile (context);
-
-    if (EFL & 0x00000001)     /* Cflag */
+    if ((handle = _lopen( ofs->szPathName, wStyle )) == -1)
     {
-      ofs->nErrCode = AL;
-      return -1;
-      }
-
-    return AX;
-#endif
-      /* FIXME: Quick hack to get it to work without calling DOS  --AJ */
-    {
-        int mode, handle;
-        switch(wStyle & 3)
-        {
-            case 0: mode = O_RDONLY; break;
-            case 1: mode = O_WRONLY; break;
-            default: mode = O_RDWR; break;
-        }
-        if ((handle = open(DOS_GetUnixFileName(ofs->szPathName), mode)) == -1)
-        {
-            ofs->nErrCode = 2;  /* not found */
-            return -1;
-        }
-          /* don't bother with locking for now */
-
-        return handle;
+        ofs->nErrCode = 2;  /* not found */
+        return -1;
     }
-#endif /*WINELIB*/
+    return handle;
 }
 
+
 /**************************************************************************
  SetHandleCount
 
@@ -358,7 +353,8 @@
 BYTE GetTempDrive(BYTE chDriveLetter)
 {
     dprintf_file(stddeb,"GetTempDrive (%d)\n",chDriveLetter);
-	return('C');
+    if (TempDirectory[1] == ':') return TempDirectory[0];
+    else return 'C';
 }
 
 /***************************************************************************
@@ -437,14 +433,14 @@
 /***************************************************************************
  _hread
  ***************************************************************************/
-long _hread(int hf, void FAR *hpvBuffer, long cbBuffer)
+LONG _hread(INT hf, LPSTR hpvBuffer, LONG cbBuffer)
 {
 	return read(hf, hpvBuffer, cbBuffer);
 }
 /***************************************************************************
  _hwrite
  ***************************************************************************/
-long _hwrite(int hf, const void FAR *hpvBuffer, long cbBuffer)
+LONG _hwrite(INT hf, const LPSTR hpvBuffer, LONG cbBuffer)
 {
 	return write(hf, hpvBuffer, cbBuffer);
 }
diff --git a/misc/kernel32.c b/misc/kernel32.c
new file mode 100644
index 0000000..0be2b09
--- /dev/null
+++ b/misc/kernel32.c
@@ -0,0 +1,61 @@
+/*
+ * Win32 kernel functions
+ *
+ * Copyright 1995 Martin von Loewis
+ */
+
+/* This file contains only wrappers to existing Wine functions or trivial
+   stubs. 'Real' implementations go into context specific files */
+
+#include "windows.h"
+#include "winerror.h"
+
+int WIN32_LastError;
+
+/***********************************************************************
+ *           GetCommandLineA      (KERNEL32.161)
+ */
+LPSTR GetCommandLineA(void)
+{
+	return 0;
+}
+
+/***********************************************************************
+ *           GetCurrentThreadId   (KERNEL32.200)
+ */
+
+int GetCurrentThreadId(void)
+{
+	return getpid();
+}
+
+
+/***********************************************************************
+ *           GetEnvironmentStrings    (KERNEL32.210)
+ */
+LPSTR GetEnvironmentStrings(void)
+{
+	return 0;
+}
+
+/***********************************************************************
+ *           GetStdHandle             (KERNEL32.276)
+ */
+HANDLE GetStdHandle(DWORD nStdHandle)
+{
+	switch(nStdHandle)
+	{
+		case -10/*STD_INPUT_HANDLE*/:return 0;
+		case -11/*STD_OUTPUT_HANDLE*/:return 1;
+		case -12/*STD_ERROR_HANDLE*/:return 2;
+	}
+	return -1;
+}
+
+/***********************************************************************
+ *           GetThreadContext         (KERNEL32.294)
+ */
+BOOL GetThreadContext(HANDLE hThread, void *lpContext)
+{
+	return FALSE;
+}
diff --git a/misc/lstr.c b/misc/lstr.c
index 9d7be42..7ba113e 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -1,13 +1,13 @@
 /*
-static char Copyright[] = "Copyright  Yngvi Sigurjonsson (yngvi@hafro.is), 1993";
-*/
+ * String functions
+ *
+ * Copyright 1993 Yngvi Sigurjonsson (yngvi@hafro.is)
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
 
 #include "ldt.h"
 #include "windows.h"
@@ -17,6 +17,44 @@
 #define ToUpper(c)	toupper(c)
 #define ToLower(c)	tolower(c)
 
+
+static const BYTE Oem2Ansi[256] =
+"\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\244"
+"\020\021\022\023\266\247\026\027\030\031\032\033\034\035\036\037"
+"\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057"
+"\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077"
+"\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117"
+"\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137"
+"\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157"
+"\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177"
+"\307\374\351\342\344\340\345\347\352\353\350\357\356\354\304\305"
+"\311\346\306\364\366\362\373\371\377\326\334\242\243\245\120\203"
+"\341\355\363\372\361\321\252\272\277\137\254\275\274\241\253\273"
+"\137\137\137\246\246\246\246\053\053\246\246\053\053\053\053\053"
+"\053\055\055\053\055\053\246\246\053\053\055\055\246\055\053\055"
+"\055\055\055\053\053\053\053\053\053\053\053\137\137\246\137\137"
+"\137\337\137\266\137\137\265\137\137\137\137\137\137\137\137\137"
+"\137\261\137\137\137\137\367\137\260\225\267\137\156\262\137\137";
+
+static const BYTE Ansi2Oem[256] =
+"\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017"
+"\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+"\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057"
+"\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077"
+"\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117"
+"\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137"
+"\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157"
+"\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177"
+"\200\201\054\237\054\137\375\374\210\045\123\074\117\215\216\217"
+"\220\140\047\042\042\371\055\137\230\231\163\076\157\235\236\131"
+"\040\255\233\234\017\235\335\025\042\143\246\256\252\055\162\137"
+"\370\361\375\063\047\346\024\372\054\061\247\257\254\253\137\250"
+"\101\101\101\101\216\217\222\200\105\220\105\105\111\111\111\111"
+"\104\245\117\117\117\117\231\170\117\125\125\125\232\131\137\341"
+"\205\240\203\141\204\206\221\207\212\202\210\211\215\241\214\213"
+"\144\244\225\242\223\157\224\366\157\227\243\226\201\171\137\230";
+
+
 /* Funny to divide them between user and kernel. */
 
 /* KERNEL.89 */
@@ -191,36 +229,10 @@
     return (current==start)?start:current-1;
 }
 
-BYTE Oem2Ansi[256], Ansi2Oem[256];
-
-void InitOemAnsiTranslations(void)
-{
-  static int inited=0; /* should called called in some init function*/
-  int transfile,i;
-  if(inited) return;
-  if((transfile=open("oem2ansi.trl",O_RDONLY))){
-    read(transfile,Oem2Ansi,256);
-    close(transfile);
-  }
-  else {  /* sets up passive translations if it does not find the file */
-    for(i=0;i<256;i++)  /* Needs some fixing */
-      Oem2Ansi[i]=i;  
-  }
-  if((transfile=open("ansi2oem.trl",O_RDONLY))){
-    read(transfile,Ansi2Oem,256);
-    close(transfile);
-  }
-  else {  /* sets up passive translations if it does not find the file */
-    for(i=0;i<256;i++)  /* Needs some fixing */
-      Ansi2Oem[i]=i;  
-  }
-  inited=1;
-}
 
 /* AnsiToOem Keyboard.5 */
 INT AnsiToOem(LPSTR lpAnsiStr, LPSTR lpOemStr)   /* why is this int ??? */
 {
-  InitOemAnsiTranslations(); /* should called called in some init function*/
   while(*lpAnsiStr){
     *lpOemStr++=Ansi2Oem[(unsigned char)(*lpAnsiStr++)];
   }
@@ -231,7 +243,6 @@
 /* OemToAnsi Keyboard.6 */
 BOOL OemToAnsi(LPSTR lpOemStr, LPSTR lpAnsiStr)   /* why is this BOOL ???? */
 {
-  InitOemAnsiTranslations(); /* should called called in some init function*/
   while(*lpOemStr){
     *lpAnsiStr++=Oem2Ansi[(unsigned char)(*lpOemStr++)];
   }
@@ -243,7 +254,6 @@
 void AnsiToOemBuff(LPSTR lpAnsiStr, LPSTR lpOemStr, INT nLength)
 {
   int i;
-  InitOemAnsiTranslations(); /* should called called in some init function*/
   for(i=0;i<nLength;i++)
     lpOemStr[i]=Ansi2Oem[(unsigned char)(lpAnsiStr[i])];
 }
@@ -252,7 +262,6 @@
 void OemToAnsiBuff(LPSTR lpOemStr, LPSTR lpAnsiStr, INT nLength)
 {
   int i;
-  InitOemAnsiTranslations(); /* should called called in some init function*/
   for(i=0;i<nLength;i++)
     lpAnsiStr[i]=Oem2Ansi[(unsigned char)(lpOemStr[i])];
 }
diff --git a/misc/main.c b/misc/main.c
index 0d2dc23..c174132 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -25,17 +25,12 @@
 #include "options.h"
 #include "desktop.h"
 #include "prototypes.h"
-#include "texts.h"
-#include "library.h"
 #include "dlls.h"
-#include "if1632.h"
 #define DEBUG_DEFINE_VARIABLES
 #include "stddebug.h"
 #include "debug.h"
 
-extern ButtonTexts ButtonText;
-
-static const char people[] = "Wine is available thanks to the work of "\
+const char people[] = "Wine is available thanks to the work of "\
 "Bob Amstadt, Dag Asheim, Martin Ayotte, Ross Biro, Erik Bos, Fons Botman, "\
 "John Brezak, Andrew Bulhak, John Burton, Paul Falstad, Olaf Flebbe, "\
 "Peter Galbavy, Cameron Heide, Jeffrey Hsu, Miguel de Icaza, "\
@@ -50,13 +45,12 @@
 #define WINE_CLASS    "Wine"    /* Class name for resources */
 
 typedef struct tagENVENTRY {
-	LPSTR				Name;
-	LPSTR				Value;
-	WORD				wSize;
-	struct tagENVENTRY	*Prev;
-	struct tagENVENTRY	*Next;
-	} ENVENTRY;
-typedef ENVENTRY *LPENVENTRY;
+  LPSTR	       	        Name;
+  LPSTR	       	        Value;
+  WORD	       	        wSize;
+  struct tagENVENTRY    *Prev;
+  struct tagENVENTRY    *Next;
+} ENVENTRY, *LPENVENTRY;
 
 LPENVENTRY	lpEnvList = NULL;
 
@@ -77,7 +71,8 @@
     FALSE,          /* backing store */
     SW_SHOWNORMAL,  /* cmdShow */
     FALSE,
-    FALSE           /* AllowReadOnly */
+    FALSE,          /* AllowReadOnly */
+    FALSE           /* Enhanced mode */
 };
 
 
@@ -95,7 +90,8 @@
     { "-debug",         ".debug",           XrmoptionNoArg,  (caddr_t)"on" },
     { "-debugmsg",      ".debugmsg",        XrmoptionSepArg, (caddr_t)NULL },
     { "-dll",           ".dll",             XrmoptionSepArg, (caddr_t)NULL },
-    { "-allowreadonly", ".allowreadonly",   XrmoptionNoArg,  (caddr_t)"on" }
+    { "-allowreadonly", ".allowreadonly",   XrmoptionNoArg,  (caddr_t)"on" },
+    { "-enhanced",      ".enhanced",        XrmoptionNoArg,  (caddr_t)"off"}
 };
 
 #define NB_OPTIONS  (sizeof(optionsTable) / sizeof(optionsTable[0]))
@@ -114,10 +110,10 @@
   "    -synchronous    Turn on synchronous display mode\n" \
   "    -backingstore   Turn on backing store\n" \
   "    -spy file       Turn on message spying to the specified file\n" \
-  "    -relaydbg       Obsolete. Use -debugmsg +relay instead\n" \
   "    -debugmsg name  Turn debugging-messages on or off\n" \
   "    -dll name       Enable or disable built-in DLLs\n" \
-  "    -allowreadonly  Read only files may be opened in write mode\n"
+  "    -allowreadonly  Read only files may be opened in write mode\n" \
+  "    -enhanced       Start wine in enhanced mode\n"
 
 
 
@@ -179,53 +175,6 @@
 
 
 /***********************************************************************
- *           MAIN_GetButtonText
- *
- * Fetch the value of resource 'name' using the correct instance name.
- * 'name' must begin with '.' or '*'
- *
- * The address of the string got from the XResoure is stored in Button.Label.
- * The corresponding hotkey is taken from this string.
- */
-
-static void MAIN_GetButtonText( XrmDatabase db, char *name, ButtonDesc *Button)
-{
-    XrmValue value;
-    char *i;
-
-    if (MAIN_GetResource( db, name, &value))
-      {
-       Button->Label = value.addr;
-       i = strchr(Button->Label,'&');
-       if ( i == NULL )
-         Button->Hotkey = '\0';
-       else if ( i++ == '\0' )
-         Button->Hotkey = '\0';
-       else
-         Button->Hotkey = *i;
-      }
-    Button->Hotkey = toupper(Button->Hotkey);
-}
-
-/***********************************************************************
- *           MAIN_GetAllButtonTexts
- *
- * Read all Button-labels from X11-resources if they exist.
- */
-
-static void MAIN_GetAllButtonTexts(XrmDatabase db)
-{
-  MAIN_GetButtonText(db, ".YesLabel",    &ButtonText.Yes);
-  MAIN_GetButtonText(db, ".NoLabel",     &ButtonText.No);
-  MAIN_GetButtonText(db, ".OkLabel",     &ButtonText.Ok);
-  MAIN_GetButtonText(db, ".CancelLabel", &ButtonText.Cancel);
-  MAIN_GetButtonText(db, ".AbortLabel",  &ButtonText.Abort);
-  MAIN_GetButtonText(db, ".RetryLabel",  &ButtonText.Retry);
-  MAIN_GetButtonText(db, ".IgnoreLabel", &ButtonText.Ignore);
-  MAIN_GetButtonText(db, ".CancelLabel", &ButtonText.Cancel);
-}
-
-/***********************************************************************
  *                    ParseDebugOptions
  *
  *  Turns specific debug messages on or off, according to "options".
@@ -294,9 +243,9 @@
       l=strchr(options,',')-options;
     else l=strlen(options);
     for (i=0;i<N_BUILTINS;i++)
-         if (!strncasecmp(options+1,dll_builtin_table[i].dll_name,l-1))
+         if (!strncasecmp(options+1,dll_builtin_table[i].name,l-1))
            {
-             dll_builtin_table[i].dll_is_used=(*options=='+');
+             dll_builtin_table[i].used = (*options=='+');
              break;
            }
     if (i==N_BUILTINS)
@@ -360,6 +309,8 @@
 	Options.debug = TRUE;
     if (MAIN_GetResource( db, ".allowreadonly", &value ))
         Options.allowReadOnly = TRUE;
+    if (MAIN_GetResource( db, ".enhanced", &value ))
+        Options.enhanced = TRUE;
     if (MAIN_GetResource( db, ".spy", &value))
 	Options.spyFilename = value.addr;
     if (MAIN_GetResource( db, ".depth", &value))
@@ -403,14 +354,11 @@
          fprintf(stderr,"Example: -dll -ole2    Do not use emulated OLE2.DLL\n");
          fprintf(stderr,"Available DLLs\n");
          for(i=0;i<N_BUILTINS;i++)
-               fprintf(stderr,"%-9s%c",dll_builtin_table[i].dll_name,
+               fprintf(stderr,"%-9s%c",dll_builtin_table[i].name,
                        (((i+2)%8==0)?'\n':' '));
          fprintf(stderr,"\n\n");
          exit(1);
        }
-
-/*    MAIN_GetAllButtonTexts(db); */
- 
 }
 
 
@@ -531,6 +479,9 @@
     int depth_count, i;
     int *depth_list;
 
+	setbuf(stdout,NULL);
+	setbuf(stderr,NULL);
+
     setlocale(LC_CTYPE,"");
 
     XrmInitialize();
@@ -607,7 +558,10 @@
  */
 LONG GetWinFlags(void)
 {
-	return (WF_STANDARD | WF_CPU286 | WF_PMODE | WF_80x87);
+  if (Options.enhanced)
+    return (WF_STANDARD | WF_ENHANCED | WF_CPU286 | WF_PMODE | WF_80x87);
+  else
+    return (WF_STANDARD | WF_CPU286 | WF_PMODE | WF_80x87);
 }
 
 /***********************************************************************
diff --git a/misc/message.c b/misc/message.c
deleted file mode 100644
index 7d23f7e..0000000
--- a/misc/message.c
+++ /dev/null
@@ -1,476 +0,0 @@
-/*
- * 'Wine' MessageBox function handling
- *
- * Copyright 1993 Martin Ayotte
- *
-static char Copyright[] = "Copyright Martin Ayotte, 1993";
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <windows.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include "library.h"
-#include "win.h"
-#include "texts.h"
-#include "user.h"
-#include "selectors.h"
-#include "stddebug.h"
-/* #define DEBUG_MSGBOX */
-#include "debug.h"
-
-
-/*
- * Defaults for button-texts
- */
-
-ButtonTexts ButtonText = {    /* FIXME: Norwegian Translation missing */
-#if #LANG(De)
-  { "&Ja",     'J' },
-  { "&Nein",   'N' },
-  { "&Ok",     'O' },
-  { "&Abbruch",'A' },
-  { "&Abbruch",'A' },
-  { "&Wiederholen", 'W' },
-  { "&Ignorieren", 'I' }
-#else
-  { "&Yes",    'Y' },
-  { "&No",     'N' },
-  { "&Ok",     'O' },
-  { "&Cancel", 'C' },
-  { "&Abort",  'A' },
-  { "&Retry",  'R' },
-  { "&Ignore", 'I' }
-#endif
-};
-
-extern HBITMAP hUpArrow;
-
-typedef struct tagMSGBOX {
-    LPSTR	Title;
-    LPSTR	Str;
-    WORD	wType;
-    WORD	wRetVal;
-    BOOL	ActiveFlg;
-    HWND	hWndYes;
-    HWND	hWndNo;
-    HWND	hWndCancel;
-    HICON	hIcon;
-    RECT	rectIcon;
-    RECT	rectStr;
-} MSGBOX;
-typedef MSGBOX FAR* LPMSGBOX;
-
-LONG SystemMessageBoxProc(HWND hwnd, WORD message, WORD wParam, LONG lParam);
-
-/**************************************************************************
- *			MessageBox  [USER.1]
- */
-
-int MessageBox(HWND hWnd, LPSTR str, LPSTR title, WORD type)
-{
-	HWND    	hDlg, hWndOld;
-	WND	    	*wndPtr;
-	WNDCLASS  	wndClass;
-	MSG*	    	msg;
-        LPMSGBOX 	lpmb;
-        HANDLE          hClassName, hMsg;
-	DWORD		dwStyle;
-	HINSTANCE	hInst;
-	int			nRet;
-
-        if (title == NULL)
-		title = "Error";
-	wndPtr = WIN_FindWndPtr(hWnd);
-	if (wndPtr == NULL) {
-		hInst = hSysRes;
-		dprintf_msgbox(stddeb,"MessageBox(NULL, str='%s', title='%s', %04X)\n", 
-			str, title, type);
-		}
-	else {
-		hInst = wndPtr->hInstance;
-		dprintf_msgbox(stddeb,"MessageBox(%04X, str='%s', title='%s', %04X)\n", 
-			hWnd, str, title, type);
-		}
-    lpmb = (LPMSGBOX) malloc(sizeof(MSGBOX));
-	memset(lpmb, 0, sizeof(MSGBOX));
-/*	lpmb->Title = title;*/
-	lpmb->Title = (LPSTR) malloc(strlen(title) + 1);
-	strcpy(lpmb->Title, title);
-/*	lpmb->Str = str;*/
-	if (str && *str)
-	{
-		lpmb->Str = (LPSTR) malloc(strlen(str) + 1);
-		strcpy(lpmb->Str, str);
-	}
-	else
-	{
-		lpmb->Str = (LPSTR) malloc(8);
-		strcpy(lpmb->Str, "Message");
-	}
-	lpmb->wType = type;
-	lpmb->ActiveFlg = TRUE;
-	wndClass.style           = CS_HREDRAW | CS_VREDRAW ;
-	wndClass.lpfnWndProc     = GetWndProcEntry16("SystemMessageBoxProc");
-	wndClass.cbClsExtra      = 0;
-	wndClass.cbWndExtra      = 4;
-	wndClass.hInstance       = hInst;
-	wndClass.hIcon           = (HICON)NULL;
-	wndClass.hCursor         = LoadCursor((HANDLE)NULL, IDC_ARROW); 
-	wndClass.hbrBackground   = GetStockObject(WHITE_BRUSH);
-	wndClass.lpszMenuName    = NULL;
-        hClassName = USER_HEAP_ALLOC( 20 );
-        strcpy( USER_HEAP_LIN_ADDR( hClassName ), "MESSAGEBOX" );
-        hMsg = USER_HEAP_ALLOC( sizeof(MSG) );
-        msg = (MSG *) USER_HEAP_LIN_ADDR( hMsg );
-	wndClass.lpszClassName = (LPSTR)USER_HEAP_SEG_ADDR( hClassName );
-	dprintf_msgbox(stddeb, "MessageBox // before RegisterClass, '%s' '%s' !\n", str, title);
-	if (!RegisterClass(&wndClass)) {
-		printf("Unable to Register class 'MESSAGEBOX' !\n");
-		if (lpmb != NULL) free(lpmb);
-		return 0;
-		}
-        USER_HEAP_FREE( hClassName );
-	dwStyle = WS_POPUP | WS_DLGFRAME | WS_VISIBLE;
-	if ((type & (MB_SYSTEMMODAL | MB_TASKMODAL)) == 0) dwStyle |= WS_CAPTION;
-	hWndOld = GetFocus();
-	hDlg = CreateWindow("MESSAGEBOX", lpmb->Title, dwStyle, 100, 150, 400, 160,
-				(HWND)NULL, (HMENU)NULL, hInst, (SEGPTR)lpmb);
-	if (hDlg == 0) {
-		printf("Unable to create 'MESSAGEBOX' window !\n");
-		if (lpmb != NULL) free(lpmb);
-		return 0;
-		}
-	dprintf_msgbox(stddeb, "MessageBox // before Msg Loop !\n");
-	while(TRUE) {
-		if (!lpmb->ActiveFlg) break;
-		if (!GetMessage( USER_HEAP_SEG_ADDR(hMsg),
-                                 (HWND)NULL, 0, 0)) break;
-		TranslateMessage(msg);
-		if ((type & (MB_SYSTEMMODAL | MB_TASKMODAL)) != 0 &&
-			msg->hwnd != hDlg) {
-			switch(msg->message) {
-				case WM_KEYDOWN:
-				case WM_LBUTTONDOWN:
-				case WM_MBUTTONDOWN:
-				case WM_RBUTTONDOWN:
-					MessageBeep(0);
-					break;
-				}
-			}
-		DispatchMessage(msg);
-		}
-        USER_HEAP_FREE(hMsg);
-	SetFocus(hWndOld);
-	nRet = lpmb->wRetVal;
-	if (lpmb != NULL) free(lpmb);
-	if (!UnregisterClass("MESSAGEBOX", hInst)) return 0;
-	dprintf_msgbox(stddeb, "MessageBox return %04X !\n", nRet);
-	return(nRet);
-}
-
-
-LPMSGBOX MsgBoxGetStorageHeader(HWND hwnd)
-{
-    WND  *wndPtr;
-    LPMSGBOX lpmb;
-    wndPtr = WIN_FindWndPtr(hwnd);
-    if (wndPtr == 0) {
-    	printf("Bad Window handle on MessageBox !\n");
-    	return 0;
-    	}
-    lpmb = *((LPMSGBOX *)wndPtr->wExtra);
-    return lpmb;
-}
-
-
-
-
-LONG SystemMessageBoxProc(HWND hWnd, WORD message, WORD wParam, LONG lParam)
-{
-	WND	    	*wndPtr;
-	CREATESTRUCT *createStruct;
-	PAINTSTRUCT	ps;
-	HDC			hDC;
-	DWORD		OldTextColor;
-	RECT		rect;
-	LPMSGBOX	lpmb;
-
-	switch(message) {
-	case WM_CREATE:
-		dprintf_msgbox(stddeb, "MessageBox WM_CREATE hWnd=%04X !\n", hWnd);
-		wndPtr = WIN_FindWndPtr(hWnd);
-		createStruct = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam);
-		lpmb = (LPMSGBOX)createStruct->lpCreateParams;
-		if (lpmb == NULL) break;
-		*((LPMSGBOX *)wndPtr->wExtra) = lpmb;
-		dprintf_msgbox(stddeb, "MessageBox WM_CREATE title='%s' str='%s' !\n", 
-									lpmb->Title, lpmb->Str);
-		GetClientRect(hWnd, &rect);
-		CopyRect(&lpmb->rectStr, &rect);
-		lpmb->rectStr.bottom -= 32;
-		switch(lpmb->wType & MB_TYPEMASK) {
-		case MB_OK :
-		        lpmb->hWndYes = CreateWindow("BUTTON", ButtonText.Ok.Label,
-				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
-				rect.right / 2 - 30, rect.bottom - 25, 
-				60, 18, hWnd, IDOK, wndPtr->hInstance, 0L);
-			break;
-		case MB_OKCANCEL :
-			lpmb->hWndYes = CreateWindow("BUTTON", ButtonText.Ok.Label,
-				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
-				rect.right / 2 - 65, rect.bottom - 25, 
-				60, 18, hWnd, IDOK, wndPtr->hInstance, 0L);
-			lpmb->hWndCancel = CreateWindow("BUTTON", ButtonText.Cancel.Label,
-				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
-				rect.right / 2 + 5, rect.bottom - 25, 
-				60, 18, hWnd, IDCANCEL, wndPtr->hInstance, 0L);
-			break;
-		case MB_ABORTRETRYIGNORE :
-			lpmb->hWndYes = CreateWindow("BUTTON", ButtonText.Retry.Label,
-				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
-				rect.right / 2 - 100, rect.bottom - 25, 
-				60, 18, hWnd, IDRETRY, wndPtr->hInstance, 0L);
-			lpmb->hWndNo = CreateWindow("BUTTON", ButtonText.Ignore.Label,
-				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
-				rect.right / 2 - 30, rect.bottom - 25, 
-				60, 18, hWnd, IDIGNORE, wndPtr->hInstance, 0L);
-			lpmb->hWndCancel = CreateWindow("BUTTON", ButtonText.Abort.Label,
-				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
-				rect.right / 2 + 40, rect.bottom - 25, 
-				60, 18, hWnd, IDABORT, wndPtr->hInstance, 0L);
-			break;
-		case MB_YESNO :
-			lpmb->hWndYes = CreateWindow("BUTTON", ButtonText.Yes.Label,
-				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
-				rect.right / 2 - 65, rect.bottom - 25, 
-				60, 18, hWnd, IDYES, wndPtr->hInstance, 0L);
-			lpmb->hWndNo = CreateWindow("BUTTON", ButtonText.No.Label,
-				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
-				rect.right / 2 + 5, rect.bottom - 25, 
-				60, 18, hWnd, IDNO, wndPtr->hInstance, 0L);
-			break;
-		case MB_YESNOCANCEL :
-			lpmb->hWndYes = CreateWindow("BUTTON", ButtonText.Yes.Label,
-				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
-				rect.right / 2 - 100, rect.bottom - 25, 
-				60, 18, hWnd, IDYES, wndPtr->hInstance, 0L);
-			lpmb->hWndNo = CreateWindow("BUTTON", ButtonText.No.Label,
-				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
-				rect.right / 2 - 30, rect.bottom - 25, 
-				60, 18, hWnd, IDNO, wndPtr->hInstance, 0L);
-			lpmb->hWndCancel = CreateWindow("BUTTON", ButtonText.Cancel.Label,
-				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
-				rect.right / 2 + 40, rect.bottom - 25, 
-				60, 18, hWnd, IDCANCEL, wndPtr->hInstance, 0L);
-			break;
-		}
-	    switch(lpmb->wType & MB_ICONMASK) {
-		case MB_ICONEXCLAMATION:
-			printf("MsgBox LoadIcon Exclamation !\n");
-			lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_EXCLAMATION);
-			break;
-		case MB_ICONQUESTION:
-			printf("MsgBox LoadIcon Question !\n");
-			lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_QUESTION);
-			break;
-		case MB_ICONASTERISK:
-			printf("MsgBox LoadIcon Asterisk !\n");
-			lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_ASTERISK);
-			break;
-		case MB_ICONHAND:
-			printf("MsgBox LoadIcon Hand !\n");
-			lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_HAND);
-			break;
-			}
-	    if (lpmb->hIcon != (HICON)NULL) {
-			SetRect(&lpmb->rectIcon, 16,
-			lpmb->rectStr.bottom / 2 - 16, 48,
-			lpmb->rectStr.bottom / 2 + 16);
-			lpmb->rectStr.left += 64;
-			}
-	    break;
-	case WM_SHOWWINDOW:
-		dprintf_msgbox(stddeb, "MessageBox WM_SHOWWINDOW hWnd=%04X !\n", hWnd);
-		if (!(wParam == 0 && lParam == 0L)) {
-			InvalidateRect(hWnd, NULL, TRUE);
-			}
-	    break;
-	case WM_PAINT:
-		dprintf_msgbox(stddeb, "MessageBox WM_PAINT hWnd=%04X !\n", hWnd);
-		lpmb = MsgBoxGetStorageHeader(hWnd);
-		if (lpmb == NULL) break;
-		if (!lpmb->ActiveFlg) break;
-		hDC = BeginPaint(hWnd, &ps);
-		if (hDC == 0) {
-			printf("MessageBox WM_PAINT // BeginPaint returned BAD hDC !\n");
-			break;
-			}
-		GetClientRect(hWnd, &rect);
-		FillRect(hDC, &rect, GetStockObject(WHITE_BRUSH));
-		CopyRect(&rect, &lpmb->rectStr);
-		OldTextColor = SetTextColor(hDC, 0x00000000);
-		if (lpmb->hIcon) 
-			DrawIcon(hDC, lpmb->rectIcon.left,
-				lpmb->rectIcon.top, lpmb->hIcon);
-		DrawText(hDC, lpmb->Str, -1, &rect, 
-			DT_CALCRECT | DT_LEFT | DT_VCENTER | DT_WORDBREAK);
-		rect.top = lpmb->rectStr.bottom / 2 - rect.bottom / 2;
-		rect.bottom = lpmb->rectStr.bottom / 2 + rect.bottom / 2;
-		DrawText(hDC, lpmb->Str, -1, &rect, DT_LEFT | DT_VCENTER | DT_WORDBREAK);
-		SetTextColor(hDC, OldTextColor);
-		EndPaint(hWnd, &ps);
-		dprintf_msgbox(stddeb, "MessageBox End of WM_PAINT !\n");
-		break;
-	case WM_DESTROY:
-	    dprintf_msgbox(stddeb, "MessageBox WM_DESTROY !\n");
-	    ReleaseCapture();
-	    lpmb = MsgBoxGetStorageHeader(hWnd);
-		if (lpmb == NULL) break;
-	    if (lpmb->hIcon) DestroyIcon(lpmb->hIcon);
-	    if (lpmb->hWndYes) DestroyWindow(lpmb->hWndYes);
-	    if (lpmb->hWndNo) DestroyWindow(lpmb->hWndNo);
-	    if (lpmb->hWndCancel) DestroyWindow(lpmb->hWndCancel);
-	    dprintf_msgbox(stddeb, "MessageBox WM_DESTROY end !\n");
-	    lpmb->ActiveFlg = FALSE;
-	    break;
-	case WM_COMMAND:
-	    lpmb = MsgBoxGetStorageHeader(hWnd);
-		if (lpmb == NULL) break;
-	    if (wParam < IDOK || wParam > IDNO) return(0);
-	    lpmb->wRetVal = wParam;
-	    dprintf_msgbox(stddeb, "MessageBox sending WM_CLOSE !\n");
-	    PostMessage(hWnd, WM_CLOSE, 0, 0L);
-	    break;
-	case WM_CHAR:
-	    lpmb = MsgBoxGetStorageHeader(hWnd);
-/*          if (wParam >= 'a' || wParam <= 'z') wParam -= 'a' - 'A'; */
-		wParam = toupper(wParam);
-	    if (wParam == ButtonText.Yes.Hotkey)
-                lpmb->wRetVal = IDYES;
-            else if (wParam == ButtonText.Ok.Hotkey)
-                lpmb->wRetVal = IDOK;
-            else if (wParam == ButtonText.Retry.Hotkey)
-                lpmb->wRetVal = IDRETRY;
-            else if (wParam == ButtonText.Abort.Hotkey)
-                lpmb->wRetVal = IDABORT;
-            else if (wParam == ButtonText.No.Hotkey)
-                lpmb->wRetVal = IDNO;
-            else if (wParam == ButtonText.Ignore.Hotkey)
-                 lpmb->wRetVal = IDIGNORE;
-            else if ((wParam == ButtonText.Ok.Hotkey) || (wParam == VK_ESCAPE))
-                lpmb->wRetVal = IDCANCEL;
-	    else
-		return 0;
-		if (lpmb == NULL) break;
-		ShowWindow(hWnd, SW_HIDE);
-		PostMessage(hWnd, WM_CLOSE, 0, 0L);
-		break;
-	default:
-	    return DefWindowProc(hWnd, message, wParam, lParam );
-    }
-return(0);
-}
-
-
-
-/*************************************************************************
- *			"About Wine..." Dialog Box
- */
-BOOL FAR PASCAL AboutWine_Proc(HWND hDlg, WORD msg, WORD wParam, LONG lParam)
-{
-    HDC  	hDC;
-    HDC		hMemDC;
-    PAINTSTRUCT ps;
-    RECT 	rect;
-    BITMAP	bm;
-    OFSTRUCT	ofstruct;
-    HBITMAP     hbmpOld;
-    static LPSTR	ptr;
-    static char 	str[256];
-    static HBITMAP	hBitMap = 0;
-    static BOOL		CreditMode;
-    static HANDLE	hFile = 0;
-    switch (msg) {
-    case WM_INITDIALOG:
-	CreditMode = FALSE;
-	strcpy(str, "WINELOGO");
-	hBitMap = LoadBitmap((HINSTANCE)NULL, (LPSTR)str);
-
-	strcpy(str, "LICENSE");
-	printf("str = '%s'\n", str);
-	hFile = OpenFile((LPSTR)str, &ofstruct, OF_READ);
-	ptr = (LPSTR)malloc(2048);
-	lseek(hFile, 0L, SEEK_SET);
-	_lread(hFile, ptr, 2000L);
-	close(hFile);
-	return TRUE;
-    case WM_PAINT:
-	hDC = BeginPaint(hDlg, &ps);
-	GetClientRect(hDlg, &rect);
-	if (CreditMode) {
-	    FillRect(hDC, &rect, GetStockObject(WHITE_BRUSH));
-	    InflateRect(&rect, -8, -8);
-	    DrawText(hDC, ptr, -1, &rect, DT_LEFT | DT_WORDBREAK);
-	    EndPaint(hDlg, &ps);
-	    return TRUE;
-	    }
-	FillRect(hDC, &rect, GetStockObject(GRAY_BRUSH));
-	InflateRect(&rect, -3, -3);
-	FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
-	InflateRect(&rect, -10, -10);
-	hMemDC = CreateCompatibleDC(hDC);
-	hbmpOld = SelectObject(hMemDC, hBitMap);
-	GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
-	BitBlt(hDC, rect.left, rect.top, bm.bmWidth, bm.bmHeight, 
-					hMemDC, 0, 0, SRCCOPY);
-        SelectObject( hMemDC, hbmpOld );
-	DeleteDC(hMemDC);
-	EndPaint(hDlg, &ps);
-	return TRUE;
-    case WM_COMMAND:
-	switch (wParam)
-	    {
-	    case IDYES:
-		if (!CreditMode) {
-		    SetWindowPos(hDlg, (HWND)NULL, 0, 0, 640, 480, 
-				SWP_NOMOVE | SWP_NOZORDER);
-		    }
-		else {
-		    SetWindowPos(hDlg, (HWND)NULL, 0, 0, 320, 250, 
-				SWP_NOMOVE | SWP_NOZORDER);
-		    }
-		CreditMode = !CreditMode;
-		ShowWindow(GetDlgItem(hDlg, IDYES), CreditMode ? SW_HIDE : SW_SHOW);
-		ShowWindow(GetDlgItem(hDlg, IDOK), CreditMode ? SW_HIDE : SW_SHOW);
-		InvalidateRect(hDlg, (LPRECT)NULL, TRUE);
-		UpdateWindow(hDlg);
-		return TRUE;
-	    case IDCANCEL:
-	    case IDOK:
-                if (hBitMap != 0 ) DeleteObject(hBitMap);
-		if (ptr != NULL) free(ptr);
-		EndDialog(hDlg, TRUE);
-		return TRUE;
-	    default:
-		return TRUE;
-	    }
-    }
-return FALSE;
-}
-
-
-/**************************************************************************
- *			FatalAppExit  [USER.137]
- */
-
-void FatalAppExit(WORD wAction, LPSTR str)
-{
-MessageBox((HWND)NULL, str, NULL, MB_SYSTEMMODAL | MB_OK);
-exit(1);
-}
diff --git a/misc/profile.c b/misc/profile.c
index 9796d49..a1bce12 100644
--- a/misc/profile.c
+++ b/misc/profile.c
@@ -106,7 +106,7 @@
 
 
     state = FirstBrace;
-    while ((c = getc (f)) != EOF){
+    while ((c = fgetc (f)) != EOF){
 	if (c == '\r')		/* Ignore Carriage Return */
 	    continue;
 	
@@ -188,7 +188,7 @@
 	    
 	} /* switch */
 	
-    } /* while ((c = getc (f)) != EOF) */
+    } /* while ((c = fgetc (f)) != EOF) */
     return SecHeader;
 }
 
diff --git a/misc/shell.c b/misc/shell.c
index f6a8db6..bab7b02 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -6,11 +6,12 @@
 #include <string.h>
 #include <unistd.h>
 #include "windows.h"
-#include "library.h"
 #include "shell.h"
 #include "neexe.h"
 #include "selectors.h"
 #include "../rc/sysres.h"
+#include "dlgs.h"
+#include "dialog.h"
 #include "stddebug.h"
 /* #define DEBUG_REG */
 #include "debug.h"
@@ -312,7 +313,7 @@
  */
 void DragAcceptFiles(HWND hWnd, BOOL b)
 {
-	dprintf_reg(stdnimp, "DragAcceptFiles : Empty Stub !!!\n");
+	fprintf(stdnimp, "DragAcceptFiles : Empty Stub !!!\n");
 }
 
 
@@ -321,7 +322,7 @@
  */
 void DragQueryFile(HDROP h, UINT u, LPSTR u2, UINT u3)
 {
-	dprintf_reg(stdnimp, "DragQueryFile : Empty Stub !!!\n");
+	fprintf(stdnimp, "DragQueryFile : Empty Stub !!!\n");
 
 }
 
@@ -331,8 +332,7 @@
  */
 void DragFinish(HDROP h)
 {
-	dprintf_reg(stdnimp, "DragFinish : Empty Stub !!!\n");
-
+	fprintf(stdnimp, "DragFinish : Empty Stub !!!\n");
 }
 
 
@@ -341,7 +341,7 @@
  */
 BOOL DragQueryPoint(HDROP h, POINT FAR *p)
 {
-	dprintf_reg(stdnimp, "DragQueryPoinyt : Empty Stub !!!\n");
+	fprintf(stdnimp, "DragQueryPoint : Empty Stub !!!\n");
         return FALSE;
 }
 
@@ -351,12 +351,14 @@
  */
 HINSTANCE ShellExecute(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, int iShowCmd)
 {
-	dprintf_reg(stdnimp, "ShellExecute // hWnd=%04X\n", hWnd);
-	dprintf_reg(stdnimp, "ShellExecute // lpOperation='%s'\n", lpOperation);
-	dprintf_reg(stdnimp, "ShellExecute // lpFile='%s'\n", lpFile);
-	dprintf_reg(stdnimp, "ShellExecute // lpParameters='%s'\n", lpParameters);
-	dprintf_reg(stdnimp, "ShellExecute // lpDirectory='%s'\n", lpDirectory);
-	dprintf_reg(stdnimp, "ShellExecute // iShowCmd=%04X\n", iShowCmd);
+        fprintf(stdnimp, "ShellExecute: empty stub\n");
+        return 2;
+	fprintf(stdnimp, "ShellExecute // hWnd=%04X\n", hWnd);  
+	fprintf(stdnimp, "ShellExecute // lpOperation='%s'\n", lpOperation);
+	fprintf(stdnimp, "ShellExecute // lpFile='%s'\n", lpFile);
+	fprintf(stdnimp, "ShellExecute // lpParameters='%s'\n", lpParameters);
+	fprintf(stdnimp, "ShellExecute // lpDirectory='%s'\n", lpDirectory);
+	fprintf(stdnimp, "ShellExecute // iShowCmd=%04X\n", iShowCmd);
 	return 2; /* file not found */
 }
 
@@ -366,58 +368,57 @@
  */
 HINSTANCE FindExecutable(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult)
 {
-	dprintf_reg(stdnimp, "FindExecutable : Empty Stub !!!\n");
+	fprintf(stdnimp, "FindExecutable : Empty Stub !!!\n");
         return 0;
 }
 
-char AppName[256], AppMisc[256];
-INT AboutDlgProc(HWND hWnd, WORD msg, WORD wParam, LONG lParam);
-
-/*************************************************************************
- *				ShellAbout		[SHELL.22]
- */
-INT ShellAbout(HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon)
-{
-/*	fprintf(stderr, "ShellAbout ! (%s, %s)\n", szApp, szOtherStuff);*/
-
-	if (szApp)
-		strcpy(AppName, szApp);
-	else
-		*AppName = 0;
-
-	if (szOtherStuff)
-		strcpy(AppMisc, szOtherStuff);
-	else
-		*AppMisc = 0;
-
-	return DialogBoxIndirectPtr( GetWindowWord(hWnd, GWW_HINSTANCE),
-                                     sysres_DIALOG_SHELL_ABOUT_MSGBOX,
-                                     hWnd, GetWndProcEntry16("AboutDlgProc"));
-}
-
+static char AppName[512], AppMisc[512];
 
 /*************************************************************************
  *				AboutDlgProc		[SHELL.33]
  */
 INT AboutDlgProc(HWND hWnd, WORD msg, WORD wParam, LONG lParam)
 {
-	char temp[256];
+  switch(msg) {
+   case WM_INITDIALOG:
+    SendDlgItemMessage(hWnd,stc1,STM_SETICON,LOWORD(lParam),0);
+    SetWindowText(hWnd, AppName);
+    SetWindowText(GetDlgItem(hWnd,100), AppMisc);
+    return 1;
+    
+   case WM_COMMAND:
+    switch (wParam) {
+     case IDOK:
+      EndDialog(hWnd, TRUE);
+      return TRUE;
+    }
+    break;
+  }
+  return FALSE;
+}
 
-	switch(msg) {
-        case WM_INITDIALOG:
-		sprintf(temp, "About %s", AppName);
-		SetWindowText(hWnd, temp);
-                SetWindowText(GetDlgItem(hWnd,100), AppMisc );
-		break;
-
-        case WM_COMMAND:
-		switch (wParam) {
-		case IDOK:
-			EndDialog(hWnd, TRUE);
-			return TRUE;
-		}
-	}
-	return FALSE;
+/*************************************************************************
+ *				ShellAbout		[SHELL.22]
+ */
+INT ShellAbout(HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon)
+{
+  if (szApp) {
+    sprintf(AppName, "About %s", szApp);
+  } else  {
+    *AppName = 0;
+  }
+  if (szOtherStuff) {
+    strcpy(AppMisc, szOtherStuff);
+  } else {
+    *AppMisc = 0;
+  }
+  if (!hIcon) {
+    hIcon = LoadIcon(0,MAKEINTRESOURCE(OIC_WINEICON));
+  }
+  return DialogBoxIndirectParamPtr(GetWindowWord(hWnd, GWW_HINSTANCE),
+				   sysres_DIALOG_SHELL_ABOUT_MSGBOX,
+				   hWnd, GetWndProcEntry16("AboutDlgProc"),
+				   hIcon);
 }
 
 /*************************************************************************
@@ -425,24 +426,23 @@
  */
 HICON ExtractIcon(HINSTANCE hInst, LPCSTR lpszExeFileName, UINT nIconIndex)
 {
-	int		count;
 	HICON	hIcon = 0;
 	HINSTANCE hInst2 = hInst;
 	dprintf_reg(stddeb, "ExtractIcon(%04X, '%s', %d\n", 
 			hInst, lpszExeFileName, nIconIndex);
 	if (lpszExeFileName != NULL) {
 		hInst2 = LoadLibrary(lpszExeFileName);
-		}
+	}
 	if (hInst2 != 0 && nIconIndex == (UINT)-1) {
 #if 0
 		count = GetRsrcCount(hInst2, NE_RSCTYPE_GROUP_ICON);
 		dprintf_reg(stddeb, "ExtractIcon // '%s' has %d icons !\n", lpszExeFileName, count);
 		return (HICON)count;
 #endif
-		}
+	}
 	if (hInst2 != hInst && hInst2 != 0) {
 		FreeLibrary(hInst2);
-		}
+	}
 	return hIcon;
 }
 
@@ -452,8 +452,20 @@
  */
 HICON ExtractAssociatedIcon(HINSTANCE hInst,LPSTR lpIconPath, LPWORD lpiIcon)
 {
-	dprintf_reg(stdnimp, "ExtractAssociatedIcon : Empty Stub !!!\n");
-        return 0;
+    dprintf_reg(stdnimp, "ExtractAssociatedIcon : Empty Stub !!!\n");
+    return 0;
+}
+
+/*************************************************************************
+ *              DoEnvironmentSubst      [SHELL.37]
+ * I couldn't find any reference, so even the number of bytes on the
+ * stack might be wrong
+ */
+WORD DoEnvironmentSubst(LPSTR a,WORD b,WORD c)
+{
+    printf(stderr, "DoEnvironmentSubst: Unknown argument count\n");
+    dprintf_reg(stdnimp, "DoEnvironmentSubst %x %x %x\n",a,b,c);
+    return 0;
 }
 
 /*************************************************************************
diff --git a/misc/spy.c b/misc/spy.c
index f121b18..524392c 100644
--- a/misc/spy.c
+++ b/misc/spy.c
@@ -156,10 +156,12 @@
     "WM_INITMENU",              /* 0x0116 */
     "WM_INITMENUPOPUP",         /* 0x0117 */
     "WM_SYSTIMER",		/* 0x0118 */
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL,
+    "WM_MENUSELECT",            /* 0x011f */
 
-    /* 0x0120 */
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    "WM_MENUCHAR",              /* 0x0120 */
+    "WM_ENTERIDLE",             /* 0x0121 */
+    NULL, NULL, NULL, NULL, NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
     /* 0x0130 */
@@ -227,16 +229,23 @@
     NULL, NULL, NULL, NULL, NULL, NULL,
 
     "WM_PARENTNOTIFY",		/* 0x0210 */
-
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    "WM_ENTERMENULOOP",         /* 0x0211 */
+    "WM_EXITMENULOOP",          /* 0x0212 */
+    NULL, NULL, NULL, NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
-    /* 0x0220 */
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    "WM_MDICREATE",             /* 0x0220 */
+    "WM_MDIDESTROY",            /* 0x0221 */
+    "WM_MDIACTIVATE",           /* 0x0222 */
+    "WM_MDIRESTORE",            /* 0x0223 */
+    "WM_MDINEXT",               /* 0x0224 */
+    "WM_MDIMAXIMIZE",           /* 0x0225 */
+    "WM_MDITILE",               /* 0x0226 */
+    "WM_MDICASCADE",            /* 0x0227 */
+    "WM_MDIICONARRANGE",        /* 0x0228 */
+    "WM_MDIGETACTIVE",          /* 0x0229 */
 
-    
-    NULL,			/* 0x0230 */
+    "WM_MDISETMENU",            /* 0x0230 */
     "WM_ENTERSIZEMOVE",		/* 0x0231 */
     "WM_EXITSIZEMOVE"		/* 0x0232 */
 };
diff --git a/misc/user.c b/misc/user.c
index e68f443..d9bf1d8 100644
--- a/misc/user.c
+++ b/misc/user.c
@@ -92,16 +92,27 @@
  */
 int USER_InitApp(int hInstance)
 {
+    extern BOOL WIDGETS_Init(void);
+
+    static int firstTask = 1;
     int queueSize;
 
+    if (firstTask)
+    {
+        /* Perform global initialisations that need a task context */
+
+          /* Initialize built-in window classes */
+        if (!WIDGETS_Init()) return 0;
+
+          /* Create desktop window */
+        if (!WIN_CreateDesktopWindow()) return 0;
+
+        firstTask = 0;
+    }
+
       /* Create task message queue */
     queueSize = GetProfileInt( "windows", "DefaultQueueSize", 8 );
     if (!SetMessageQueue( queueSize )) return 0;
 
-#ifndef WINELIB
-    /* Initialize DLLs */
-    InitializeLoadedDLLs(NULL);
-#endif
-        
     return 1;
 }
diff --git a/misc/winsocket.c b/misc/winsocket.c
index 551ac41..ee95375 100644
--- a/misc/winsocket.c
+++ b/misc/winsocket.c
@@ -36,6 +36,9 @@
 	WORD	wMsg;
 	LONG	lParam;
 };
+
+#pragma pack(1)
+
 #define IPC_PACKET_SIZE (sizeof(struct ipc_packet) - sizeof(long))
 #define MTYPE 0xb0b0eb05
 #define WINE_PACKED __attribute__ ((packed))
@@ -82,6 +85,8 @@
 };
 static struct WinSockHeap *heap;
 
+#pragma pack(4)
+
 #define dump_sockaddr(a) \
 	fprintf(stderr, "sockaddr_in: family %d, address %s, port %d\n", \
 			((struct sockaddr_in *)a)->sin_family, \
diff --git a/miscemu/Imakefile b/miscemu/Imakefile
index be64a27..11e3840 100644
--- a/miscemu/Imakefile
+++ b/miscemu/Imakefile
@@ -15,8 +15,7 @@
 	int2a.c \
 	int2f.c \
 	int31.c \
-	ioports.c \
-	kernel.c
+	ioports.c
 
 OBJS = $(SRCS:.c=.o)
 
diff --git a/miscemu/int21.c b/miscemu/int21.c
index 44cb0ce..e4bb91f 100644
--- a/miscemu/int21.c
+++ b/miscemu/int21.c
@@ -291,6 +291,8 @@
 		Error (InvalidHandle, EL_Unknown, EC_Unknown);
 		AX = InvalidHandle;
 		SetCflag;
+        	dprintf_int(stddeb,
+			"int21: read (%d, void *, 0x%x) = EBADF\n", BX, CX);
 		return;
 	}
 
@@ -300,9 +302,14 @@
 		Error (0,0,0);
 		AX = 1;
 		ResetCflag;
+        	dprintf_int(stddeb,
+			"int21: read (%d, void *, 0x%x) = EOF\n", BX, CX);
 		return;
 	} else {
 		size = read(BX, ptr, CX);
+        	dprintf_int(stddeb,
+			"int21: read (%d, void *, 0x%x) = 0x%x\n",
+			BX, CX, size);
 		if (size == -1) {
 			errno_to_doserr();
 			AL = ExtendedError;
@@ -372,6 +379,10 @@
 			break;
 		}
         status = lseek(BX, (CX << 16) + DX, fileoffset);
+
+	dprintf_int (stddeb, "int21: seek (%d, 0x%x, %d) = 0x%lx\n",
+			BX, (CX << 16) + DX, AL, status);
+
 	if (status == -1) {
 		errno_to_doserr();
 		AL = ExtendedError;			SetCflag;
@@ -386,6 +397,9 @@
 
 static void ioctlGetDeviceInfo(struct sigcontext_struct *context)
 {
+
+	dprintf_int (stddeb, "int21: ioctl (%d, GetDeviceInfo)\n", BX);
+
 	switch (BX) {
 		case 0:
 		case 1:
@@ -467,7 +481,7 @@
 	ltime = time(NULL);
 	now = localtime(&ltime);
 
-	CX = now->tm_year + 1900;
+	CX = now->tm_year + 1900 - 1980;
 	DX = ((now->tm_mon + 1) << 8) | now->tm_mday;
 	AX = now->tm_wday;
 }
@@ -537,6 +551,8 @@
                                O_RDONLY );
             if( handle == -1 )
             {
+		dprintf_int (stddeb, "int21: open (%s, %d) = -1\n",
+			DOS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS,DX)), mode);
                 errno_to_doserr();
                 AL = ExtendedError;
                 SetCflag;
@@ -544,6 +560,9 @@
             }
 	}		
 
+	dprintf_int (stddeb, "int21: open (%s, %d) = %d\n",
+		DOS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS,DX)), mode, handle);
+
         switch (AX & 0x0070)
 	{
 	  case 0x00:    /* compatability mode */
@@ -602,6 +621,8 @@
 
 static void CloseFile(struct sigcontext_struct *context)
 {
+	dprintf_int (stddeb, "int21: close (%d)\n", BX);
+
 	if (close(BX) == -1) {
 		errno_to_doserr();
 		AL = ExtendedError;
@@ -1166,12 +1187,16 @@
   if ((S_IWRITE & s.st_mode) != S_IWRITE)
     cx|=0x01;
 
+  dprintf_int (stddeb, "int21: GetFileAttributes (%s) = 0x%x\n",
+		filename, cx);
+
   ECX = (ECX & 0xffff0000) | cx;
   ResetCflag;
   Error (0,0,0); 
 }
 
 
+extern void LOCAL_PrintHeap (WORD ds);
 
 /************************************************************************/
 
@@ -1282,6 +1307,7 @@
             {
                 TDB *pTask = (TDB *)GlobalLock( GetCurrentTask() );
                 pTask->dta = MAKELONG( DX, DS );
+                dprintf_int(stddeb, "int21: Set DTA: %08lx\n", pTask->dta);
             }
             break;
 
@@ -1701,6 +1727,10 @@
 	    return 1;
 	}
     }
+    dprintf_int(stddeb,"ret21: AX %04x, BX %04x, CX %04x, DX %04x, "
+           "SI %04x, DI %04x, DS %04x, ES %04x EFL %08lx\n",
+           AX, BX, CX, DX, SI, DI, DS, ES, EFL);
+
     return 1;
 }
 
diff --git a/miscemu/int25.c b/miscemu/int25.c
index ea568e3..3fb25a7 100644
--- a/miscemu/int25.c
+++ b/miscemu/int25.c
@@ -6,6 +6,7 @@
 #include "ldt.h"
 #include "wine.h"
 #include "miscemu.h"
+#include "dos_fs.h"
 #include "stddebug.h"
 /* #define DEBUG_INT */
 #include "debug.h"
diff --git a/miscemu/int26.c b/miscemu/int26.c
index 046c6bd..de0aecf 100644
--- a/miscemu/int26.c
+++ b/miscemu/int26.c
@@ -5,6 +5,7 @@
 #include "ldt.h"
 #include "wine.h"
 #include "miscemu.h"
+#include "dos_fs.h"
 #include "stddebug.h"
 /* #define DEBUG_INT */
 #include "debug.h"
diff --git a/miscemu/kernel.c b/miscemu/kernel.c
deleted file mode 100644
index 8dac7ee..0000000
--- a/miscemu/kernel.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-static char RCSId[] = "$Id: kernel.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
-static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "prototypes.h"
-#include "options.h"
-#include "wine.h"
-#include "stddebug.h"
-#include "debug.h"
-
-extern unsigned short WIN_StackSize;
-
-/**********************************************************************
- *					KERNEL_InitTask
- */
-void KERNEL_InitTask( struct sigcontext_struct context )
-{
-    context.sc_eax = 1;
-    context.sc_ebx = 0x81;
-    context.sc_ecx = WIN_StackSize;
-    context.sc_edx = Options.cmdShow;
-    context.sc_edi = 0;
-    context.sc_edi = context.sc_ds;
-}
-
diff --git a/multimedia/audio.c b/multimedia/audio.c
index de3c8ad..2a5faa4 100644
--- a/multimedia/audio.c
+++ b/multimedia/audio.c
@@ -1,4 +1,4 @@
-/*
+/*				   
  * Sample Wine Driver for Linux
  *
  * Copyright 1994 Martin Ayotte
@@ -23,6 +23,7 @@
 #include "driver.h"
 #include "mmsystem.h"
 #include "ldt.h"
+#include "stackframe.h"
 
 #ifdef linux
 #include <linux/soundcard.h>
@@ -82,7 +83,7 @@
 static LINUX_MCIWAVE	MCIWavDev[MAX_MCIWAVDRV];
 #endif
 
-DWORD WAVE_mciOpen(DWORD dwFlags, LPMCI_WAVE_OPEN_PARMS lpParms);
+DWORD WAVE_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_PARMS lpParms);
 DWORD WAVE_mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms);
 DWORD WAVE_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms);
 DWORD WAVE_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms);
@@ -130,6 +131,8 @@
 						DWORD dwParam1, DWORD dwParam2)
 {
 #ifdef linux
+	dprintf_mciwave(stddeb,"WAVE_DriverProc(%08lX, %04X, %04X, %08lX, %08lX)\n", 
+		dwDevID, hDriv, wMsg, dwParam1, dwParam2);
 	switch(wMsg) {
 		case DRV_LOAD:
 			return (LRESULT)1L;
@@ -155,7 +158,7 @@
 			return (LRESULT)DRVCNF_RESTART;
 		case MCI_OPEN_DRIVER:
 		case MCI_OPEN:
-			return WAVE_mciOpen(dwParam1, (LPMCI_WAVE_OPEN_PARMS)PTR_SEG_TO_LIN(dwParam2));
+			return WAVE_mciOpen(dwDevID, dwParam1, (LPMCI_WAVE_OPEN_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_CLOSE_DRIVER:
 		case MCI_CLOSE:
 			return WAVE_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
@@ -187,18 +190,21 @@
 
 /**************************************************************************
 * 				WAVE_mciOpen	*/
-DWORD WAVE_mciOpen(DWORD dwFlags, LPMCI_WAVE_OPEN_PARMS lpParms)
+DWORD WAVE_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_PARMS lpParms)
 {
 #ifdef linux
-	UINT 		wDevID;
+	HANDLE		hFormat;
 	LPPCMWAVEFORMAT	lpWaveFormat;
-	WAVEOPENDESC 	WaveDesc;
+	HANDLE		hDesc;
+	LPWAVEOPENDESC 	lpDesc;
+	LPSTR		lpstrElementName;
 	DWORD		dwRet;
 	char		str[128];
 
-	dprintf_mciwave(stddeb,"WAVE_mciOpen(%08lX, %p)\n", dwFlags, lpParms);
+	dprintf_mciwave(stddeb,"WAVE_mciOpen(%04X, %08lX, %p)\n", 
+				wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
-	wDevID = lpParms->wDeviceID;
+	dprintf_mciwave(stddeb,"WAVE_mciOpen // wDevID=%04X\n", wDevID);
 	if (MCIWavDev[wDevID].nUseCount > 0) {
 		/* The driver already open on this channel */
 		/* If the driver was opened shareable before and this open specifies */
@@ -212,12 +218,19 @@
 		MCIWavDev[wDevID].nUseCount = 1;
 		MCIWavDev[wDevID].fShareable = dwFlags & MCI_OPEN_SHAREABLE;
 		}
-    if (dwFlags & MCI_OPEN_ELEMENT) {
-        dprintf_mciwave(stddeb,"WAVE_mciOpen // MCI_OPEN_ELEMENT '%s' !\n",
-								lpParms->lpstrElementName);
+	dprintf_mciwave(stddeb,"WAVE_mciOpen // before setting lParams->wDeviceID // winstack=%p ds=%04X ss=%04X sp=%04X\n",
+		(BYTE *)CURRENT_STACK16->args, 
+		CURRENT_STACK16->ds, IF1632_Saved16_ss, IF1632_Saved16_sp);
+	lpParms->wDeviceID = wDevID;
+	dprintf_mciwave(stddeb,"WAVE_mciOpen // wDevID=%04X\n", wDevID);
+	dprintf_mciwave(stddeb,"WAVE_mciOpen // before OPEN_ELEMENT\n");
+	if (dwFlags & MCI_OPEN_ELEMENT) {
+		lpstrElementName = (LPSTR)PTR_SEG_TO_LIN(lpParms->lpstrElementName);
+		dprintf_mciwave(stddeb,"WAVE_mciOpen // MCI_OPEN_ELEMENT '%s' !\n",
+						lpstrElementName);
 /*		printf("WAVE_mciOpen // cdw='%s'\n", DOS_GetCurrentDir(DOS_GetDefaultDrive())); */
-		if (strlen(lpParms->lpstrElementName) > 0) {
-			strcpy(str, lpParms->lpstrElementName);
+		if (strlen(lpstrElementName) > 0) {
+			strcpy(str, lpstrElementName);
 			AnsiUpper(str);
 			MCIWavDev[wDevID].hFile = mmioOpen(str, NULL, 
 				MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_EXCLUSIVE);
@@ -233,14 +246,17 @@
 	memcpy(&MCIWavDev[wDevID].openParms, lpParms, sizeof(MCI_WAVE_OPEN_PARMS));
 	MCIWavDev[wDevID].wNotifyDeviceID = lpParms->wDeviceID;
 	lpWaveFormat = &MCIWavDev[wDevID].WaveFormat;
-	WaveDesc.hWave = 0;
-	WaveDesc.lpFormat = (LPWAVEFORMAT)lpWaveFormat;
+	hDesc = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hDesc);
+	lpDesc->hWave = 0;
+/*
 	lpWaveFormat->wf.wFormatTag = WAVE_FORMAT_PCM;
 	lpWaveFormat->wBitsPerSample = 8;
 	lpWaveFormat->wf.nChannels = 1;
 	lpWaveFormat->wf.nSamplesPerSec = 11025;
 	lpWaveFormat->wf.nAvgBytesPerSec = 11025;
 	lpWaveFormat->wf.nBlockAlign = 1;
+*/
 	if (MCIWavDev[wDevID].hFile != 0) {
 		MMCKINFO	mmckInfo;
 		MMCKINFO	ckMainRIFF;
@@ -282,8 +298,14 @@
 		}
 	lpWaveFormat->wf.nAvgBytesPerSec = 
 		lpWaveFormat->wf.nSamplesPerSec * lpWaveFormat->wf.nBlockAlign;
-	dwRet = wodMessage(0, WODM_OPEN, 0, (DWORD)&WaveDesc, CALLBACK_NULL);
-	dwRet = widMessage(0, WIDM_OPEN, 0, (DWORD)&WaveDesc, CALLBACK_NULL);
+	hFormat = USER_HEAP_ALLOC(sizeof(PCMWAVEFORMAT));
+	lpDesc->lpFormat = (LPWAVEFORMAT) USER_HEAP_LIN_ADDR(hFormat);
+	memcpy(lpDesc->lpFormat, lpWaveFormat, sizeof(PCMWAVEFORMAT));
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_SEG_ADDR(hDesc);
+	dwRet = wodMessage(0, WODM_OPEN, 0, (DWORD)lpDesc, CALLBACK_NULL);
+	dwRet = widMessage(0, WIDM_OPEN, 0, (DWORD)lpDesc, CALLBACK_NULL);
+	USER_HEAP_FREE(hFormat);
+	USER_HEAP_FREE(hDesc);
 	return 0;
 #else
 	return MMSYSERR_NOTENABLED;
@@ -323,10 +345,13 @@
 DWORD WAVE_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
 {
 #ifdef linux
-	int			count;
-	int			start, end;
+	int				start, end;
+	LONG			bufsize, count;
+	HANDLE			hData;
+	HANDLE			hWaveHdr;
 	LPWAVEHDR		lpWaveHdr;
-	DWORD		dwRet;
+	LPWAVEHDR		lp16WaveHdr;
+	DWORD			dwRet;
 	dprintf_mciwave(stddeb,
 		 "WAVE_mciPlay(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (MCIWavDev[wDevID].hFile == 0) {
@@ -361,29 +386,38 @@
 			}
 		}
 /**/
+	bufsize = 64000;
 	lpWaveHdr = &MCIWavDev[wDevID].WaveHdr;
-	lpWaveHdr->lpData = (LPSTR) malloc(64000);
-	lpWaveHdr->dwBufferLength = 32000;
+	hData = GlobalAlloc(GMEM_MOVEABLE, bufsize);
+	lpWaveHdr->lpData = (LPSTR) WIN16_GlobalLock(hData);
 	lpWaveHdr->dwUser = 0L;
 	lpWaveHdr->dwFlags = 0L;
 	lpWaveHdr->dwLoops = 0L;
-	dwRet = wodMessage(0, WODM_PREPARE, 0, (DWORD)lpWaveHdr, sizeof(WAVEHDR));
-/*	printf("WAVE_mciPlay // after WODM_PREPARE \n"); */
+	hWaveHdr = USER_HEAP_ALLOC(sizeof(WAVEHDR));
+	lp16WaveHdr = (LPWAVEHDR) USER_HEAP_SEG_ADDR(hWaveHdr);
+	memcpy(PTR_SEG_TO_LIN(lp16WaveHdr), lpWaveHdr, sizeof(WAVEHDR));
+	lpWaveHdr = PTR_SEG_TO_LIN(lp16WaveHdr);
+	dwRet = wodMessage(0, WODM_PREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
 	while(TRUE) {
-		count = mmioRead(MCIWavDev[wDevID].hFile, lpWaveHdr->lpData, lpWaveHdr->dwBufferLength);
+		count = mmioRead(MCIWavDev[wDevID].hFile, 
+			PTR_SEG_TO_LIN(lpWaveHdr->lpData), bufsize);
+		dprintf_mciwave(stddeb,"WAVE_mciPlay // mmioRead bufsize=%ld count=%ld\n", bufsize, count);
 		if (count < 1) break;
-		lpWaveHdr->dwBytesRecorded = count;
-		dprintf_mciwave(stddeb,"WAVE_mciPlay // before WODM_WRITE lpWaveHdr=%p dwBytesRecorded=%lu\n",
-					lpWaveHdr, lpWaveHdr->dwBytesRecorded);
-		dwRet = wodMessage(0, WODM_WRITE, 0, (DWORD)lpWaveHdr, sizeof(WAVEHDR));
+		lpWaveHdr->dwBufferLength = count;
+/*		lpWaveHdr->dwBytesRecorded = count; */
+		dprintf_mciwave(stddeb,"WAVE_mciPlay // before WODM_WRITE lpWaveHdr=%p dwBufferLength=%lu dwBytesRecorded=%lu\n",
+				lpWaveHdr, lpWaveHdr->dwBufferLength, lpWaveHdr->dwBytesRecorded);
+		dwRet = wodMessage(0, WODM_WRITE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
 		}
-	dwRet = wodMessage(0, WODM_UNPREPARE, 0, (DWORD)lpWaveHdr, sizeof(WAVEHDR));
+	dwRet = wodMessage(0, WODM_UNPREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
 	if (lpWaveHdr->lpData != NULL) {
-		free(lpWaveHdr->lpData);
+		GlobalUnlock(hData);
+		GlobalFree(hData);
 		lpWaveHdr->lpData = NULL;
 		}
+	USER_HEAP_FREE(hWaveHdr);
 	if (dwFlags & MCI_NOTIFY) {
-	  dprintf_mciwave(stddeb,"WAVE_mciPlay // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
+		dprintf_mciwave(stddeb,"WAVE_mciPlay // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
 		mciDriverNotify((HWND)LOWORD(lpParms->dwCallback), 
 			MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
 		exit(0);
@@ -401,8 +435,12 @@
 DWORD WAVE_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms)
 {
 #ifdef linux
-	int			start, end;
+	int				start, end;
+	LONG			bufsize;
+	HANDLE			hData;
+	HANDLE			hWaveHdr;
 	LPWAVEHDR		lpWaveHdr;
+	LPWAVEHDR		lp16WaveHdr;
 	DWORD			dwRet;
 
 	dprintf_mciwave(stddeb,
@@ -422,13 +460,19 @@
 		end = lpParms->dwTo;
 		dprintf_mciwave(stddeb,"WAVE_mciRecord // MCI_TO=%d \n", end);
 		}
+	bufsize = 64000;
 	lpWaveHdr = &MCIWavDev[wDevID].WaveHdr;
-	lpWaveHdr->lpData = (LPSTR) malloc(64000);
-	lpWaveHdr->dwBufferLength = 32000;
+	hData = GlobalAlloc(GMEM_MOVEABLE, bufsize);
+	lpWaveHdr->lpData = (LPSTR) WIN16_GlobalLock(hData);
+	lpWaveHdr->dwBufferLength = bufsize;
 	lpWaveHdr->dwUser = 0L;
 	lpWaveHdr->dwFlags = 0L;
 	lpWaveHdr->dwLoops = 0L;
-	dwRet = widMessage(0, WIDM_PREPARE, 0, (DWORD)lpWaveHdr, sizeof(WAVEHDR));
+	hWaveHdr = USER_HEAP_ALLOC(sizeof(WAVEHDR));
+	lp16WaveHdr = (LPWAVEHDR) USER_HEAP_SEG_ADDR(hWaveHdr);
+	memcpy(PTR_SEG_TO_LIN(lp16WaveHdr), lpWaveHdr, sizeof(WAVEHDR));
+	lpWaveHdr = PTR_SEG_TO_LIN(lp16WaveHdr);
+	dwRet = widMessage(0, WIDM_PREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
     dprintf_mciwave(stddeb,"WAVE_mciRecord // after WIDM_PREPARE \n");
 	while(TRUE) {
 		lpWaveHdr->dwBytesRecorded = 0;
@@ -439,12 +483,14 @@
 		if (lpWaveHdr->dwBytesRecorded == 0) break;
 		}
 	dprintf_mciwave(stddeb,"WAVE_mciRecord // before WIDM_UNPREPARE \n");
-	dwRet = widMessage(0, WIDM_UNPREPARE, 0, (DWORD)lpWaveHdr, sizeof(WAVEHDR));
+	dwRet = widMessage(0, WIDM_UNPREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
 	dprintf_mciwave(stddeb,"WAVE_mciRecord // after WIDM_UNPREPARE \n");
 	if (lpWaveHdr->lpData != NULL) {
-		free(lpWaveHdr->lpData);
+		GlobalUnlock(hData);
+		GlobalFree(hData);
 		lpWaveHdr->lpData = NULL;
 		}
+	USER_HEAP_FREE(hWaveHdr);
 	if (dwFlags & MCI_NOTIFY) {
 	  dprintf_mciwave(stddeb,"WAVE_mciRecord // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
 		mciDriverNotify((HWND)LOWORD(lpParms->dwCallback), 
@@ -463,8 +509,8 @@
 DWORD WAVE_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
 #ifdef linux
-        dprintf_mciwave(stddeb,
-		 "WAVE_mciStop(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
+	dprintf_mciwave(stddeb,
+		"WAVE_mciStop(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	return 0;
 #else
@@ -479,7 +525,7 @@
 DWORD WAVE_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
 #ifdef linux
-        dprintf_mciwave(stddeb,
+	dprintf_mciwave(stddeb,
 		"WAVE_mciPause(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	return 0;
@@ -495,7 +541,7 @@
 DWORD WAVE_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
 #ifdef linux
-        dprintf_mciwave(stddeb,
+	dprintf_mciwave(stddeb,
 		"WAVE_mciResume(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	return 0;
@@ -511,8 +557,8 @@
 DWORD WAVE_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
 {
 #ifdef linux
-        dprintf_mciwave(stddeb,
-		  "WAVE_mciSet(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
+	dprintf_mciwave(stddeb,
+		"WAVE_mciSet(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	dprintf_mciwave(stddeb,
 		 "WAVE_mciSet // dwTimeFormat=%08lX\n", lpParms->dwTimeFormat);
@@ -521,20 +567,16 @@
 	if (dwFlags & MCI_SET_TIME_FORMAT) {
 		switch (lpParms->dwTimeFormat) {
 			case MCI_FORMAT_MILLISECONDS:
-		                dprintf_mciwave(stddeb,
-				 "WAVE_mciSet // MCI_FORMAT_MILLISECONDS !\n");
+				dprintf_mciwave(stddeb,	"WAVE_mciSet // MCI_FORMAT_MILLISECONDS !\n");
 				break;
 			case MCI_FORMAT_BYTES:
-				dprintf_mciwave(stddeb,
-				 "WAVE_mciSet // MCI_FORMAT_BYTES !\n");
+				dprintf_mciwave(stddeb, "WAVE_mciSet // MCI_FORMAT_BYTES !\n");
 				break;
 			case MCI_FORMAT_SAMPLES:
-				dprintf_mciwave(stddeb,
-				 "WAVE_mciSet // MCI_FORMAT_SAMPLES !\n");
+				dprintf_mciwave(stddeb,	"WAVE_mciSet // MCI_FORMAT_SAMPLES !\n");
 				break;
 			default:
-				fprintf(stderr,
-				 "WAVE_mciSet // bad time format !\n");
+				fprintf(stderr,	"WAVE_mciSet // bad time format !\n");
 				return MCIERR_BAD_TIME_FORMAT;
 			}
 		}
@@ -588,7 +630,7 @@
 DWORD WAVE_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
 {
 #ifdef linux
-        dprintf_mciwave(stddeb,
+	dprintf_mciwave(stddeb,
 		"WAVE_mciStatus(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	if (dwFlags & MCI_STATUS_ITEM) {
@@ -673,7 +715,7 @@
 			}
 		}
 	if (dwFlags & MCI_NOTIFY) {
-  	        dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
+		dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
 		mciDriverNotify((HWND)LOWORD(lpParms->dwCallback), 
 			MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
 		}
@@ -690,8 +732,8 @@
 					LPMCI_GETDEVCAPS_PARMS lpParms)
 {
 #ifdef linux
-        dprintf_mciwave(stddeb,
-	    "WAVE_mciGetDevCaps(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
+	dprintf_mciwave(stddeb,
+		"WAVE_mciGetDevCaps(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	if (dwFlags & MCI_GETDEVCAPS_ITEM) {
 		switch(lpParms->dwItem) {
@@ -744,7 +786,7 @@
 DWORD WAVE_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms)
 {
 #ifdef linux
-        dprintf_mciwave(stddeb,
+	dprintf_mciwave(stddeb,
 		"WAVE_mciInfo(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	lpParms->lpstrReturn = NULL;
@@ -857,48 +899,45 @@
 	int			smplrate;
 	int			samplesize;
 	int			dsp_stereo;
-        LPWAVEFORMAT lpFormat;
+	LPWAVEFORMAT lpFormat;
 
 	dprintf_mciwave(stddeb,
-		     "wodOpen(%u, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
+		"wodOpen(%u, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
 	if (lpDesc == NULL) {
-	        fprintf(stderr,"Linux 'wodOpen' // Invalid Parameter !\n");
+		fprintf(stderr,"Linux 'wodOpen' // Invalid Parameter !\n");
 		return MMSYSERR_INVALPARAM;
 		}
 	if (wDevID >= MAX_WAVOUTDRV) {
-	        fprintf(stderr,"Linux 'wodOpen' // MAX_WAVOUTDRV reached !\n");
+		fprintf(stderr,"Linux 'wodOpen' // MAX_WAVOUTDRV reached !\n");
 		return MMSYSERR_ALLOCATED;
 		}
 	WOutDev[wDevID].unixdev = 0;
 	audio = open (SOUND_DEV, O_WRONLY, 0);
 	if (audio == -1) {
-                fprintf(stderr,"Linux 'wodOpen' // can't open !\n");
+		fprintf(stderr,"Linux 'wodOpen' // can't open !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	IOCTL(audio, SNDCTL_DSP_GETBLKSIZE, abuf_size);
 	if (abuf_size < 4096 || abuf_size > 65536) {
 		if (abuf_size == -1)
-		  fprintf(stderr,"Linux 'wodOpen' // IOCTL can't 'SNDCTL_DSP_GETBLKSIZE' !\n");
+			fprintf(stderr,"Linux 'wodOpen' // IOCTL can't 'SNDCTL_DSP_GETBLKSIZE' !\n");
 		else
-		  fprintf(stderr,"Linux 'wodOpen' // SNDCTL_DSP_GETBLKSIZE Invalid bufsize !\n");
+			fprintf(stderr,"Linux 'wodOpen' // SNDCTL_DSP_GETBLKSIZE Invalid bufsize !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	WOutDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
 	switch(WOutDev[wDevID].wFlags) {
 		case DCB_NULL:
-	                fprintf(stderr,"Linux 'wodOpen' // CALLBACK_NULL !\n");
+			dprintf_mciwave(stddeb,	"Linux 'wodOpen' // CALLBACK_NULL !\n");
 			break;
 		case DCB_WINDOW:
-			dprintf_mciwave(stddeb,
-				   "Linux 'wodOpen' // CALLBACK_WINDOW !\n");
+			dprintf_mciwave(stddeb,	"Linux 'wodOpen' // CALLBACK_WINDOW !\n");
 			break;
 		case DCB_TASK:
-			dprintf_mciwave(stddeb,
-				   "Linux 'wodOpen' // CALLBACK_TASK !\n");
+			dprintf_mciwave(stddeb,	"Linux 'wodOpen' // CALLBACK_TASK !\n");
 			break;
 		case DCB_FUNCTION:
-			dprintf_mciwave(stddeb,
-				   "Linux 'wodOpen' // CALLBACK_FUNCTION !\n");
+			dprintf_mciwave(stddeb,	"Linux 'wodOpen' // CALLBACK_FUNCTION !\n");
 			break;
 		}
 	WOutDev[wDevID].lpQueueHdr = NULL;
@@ -906,15 +945,22 @@
 	WOutDev[wDevID].dwTotalPlayed = 0;
 	WOutDev[wDevID].bufsize = abuf_size;
 	memcpy(&WOutDev[wDevID].waveDesc, lpDesc, sizeof(WAVEOPENDESC));
-        lpFormat = (LPWAVEFORMAT)PTR_SEG_TO_LIN(lpDesc->lpFormat);
+/*	lpFormat = (LPWAVEFORMAT) PTR_SEG_TO_LIN(lpDesc->lpFormat); */
+	lpFormat = lpDesc->lpFormat;
 	if (lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
-	        fprintf(stderr,"Linux 'wodOpen' // Bad format %04X !\n",
-						lpFormat->wFormatTag);
+		fprintf(stderr,"Linux 'wodOpen' // Bad format %04X !\n",
+				lpFormat->wFormatTag);
+		fprintf(stderr,"Linux 'wodOpen' // Bad nChannels %d !\n",
+				lpFormat->nChannels);
+		fprintf(stderr,"Linux 'wodOpen' // Bad nSamplesPerSec %ld !\n",
+				lpFormat->nSamplesPerSec);
 		return WAVERR_BADFORMAT;
 		}
 	memcpy(&WOutDev[wDevID].Format, lpFormat, sizeof(PCMWAVEFORMAT));
 	if (WOutDev[wDevID].Format.wf.nChannels == 0) return WAVERR_BADFORMAT;
 	if (WOutDev[wDevID].Format.wf.nSamplesPerSec == 0) return WAVERR_BADFORMAT;
+	dprintf_mciwave(stddeb,"Linux 'wodOpen' // wBitsPerSample=%u !\n",
+				WOutDev[wDevID].Format.wBitsPerSample);
 	if (WOutDev[wDevID].Format.wBitsPerSample == 0) {
 		WOutDev[wDevID].Format.wBitsPerSample = 8 *
 		(WOutDev[wDevID].Format.wf.nAvgBytesPerSec /
@@ -929,12 +975,14 @@
 	IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo);
 	dprintf_mciwave(stddeb,"Linux 'wodOpen' // wBitsPerSample=%u !\n",
 				WOutDev[wDevID].Format.wBitsPerSample);
+	dprintf_mciwave(stddeb,"Linux 'wodOpen' // nAvgBytesPerSec=%lu !\n",
+				WOutDev[wDevID].Format.wf.nAvgBytesPerSec);
 	dprintf_mciwave(stddeb,"Linux 'wodOpen' // nSamplesPerSec=%lu !\n",
 				WOutDev[wDevID].Format.wf.nSamplesPerSec);
 	dprintf_mciwave(stddeb,"Linux 'wodOpen' // nChannels=%u !\n",
 				WOutDev[wDevID].Format.wf.nChannels);
 	if (WAVE_NotifyClient(wDevID, WOM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
-	        fprintf(stderr,"Linux 'wodOpen' // can't notify client !\n");
+		fprintf(stderr,"Linux 'wodOpen' // can't notify client !\n");
 		return MMSYSERR_INVALPARAM;
 		}
 	return MMSYSERR_NOERROR;
@@ -949,16 +997,16 @@
 DWORD wodClose(WORD wDevID)
 {
 #ifdef linux
-        dprintf_mciwave(stddeb,"wodClose(%u);\n", wDevID);
+	dprintf_mciwave(stddeb,"wodClose(%u);\n", wDevID);
 	if (WOutDev[wDevID].unixdev == 0) {
-	        fprintf(stderr,"Linux 'wodClose' // can't close !\n");
+		fprintf(stderr,"Linux 'wodClose' // can't close !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	close(WOutDev[wDevID].unixdev);
 	WOutDev[wDevID].unixdev = 0;
 	WOutDev[wDevID].bufsize = 0;
 	if (WAVE_NotifyClient(wDevID, WOM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
-                fprintf(stderr,"Linux 'wodClose' // can't notify client !\n");
+		fprintf(stderr,"Linux 'wodClose' // can't notify client !\n");
 		return MMSYSERR_INVALPARAM;
 		}
 	return MMSYSERR_NOERROR;
@@ -973,7 +1021,9 @@
 DWORD wodWrite(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
 #ifdef linux
-        dprintf_mciwave(stddeb,"wodWrite(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
+	int		count;
+	LPSTR	lpData;
+	dprintf_mciwave(stddeb,"wodWrite(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
 	if (WOutDev[wDevID].unixdev == 0) {
         fprintf(stderr,"Linux 'wodWrite' // can't play !\n");
 		return MMSYSERR_NOTENABLED;
@@ -983,16 +1033,23 @@
 	if (lpWaveHdr->dwFlags & WHDR_INQUEUE) return WAVERR_STILLPLAYING;
 	lpWaveHdr->dwFlags &= ~WHDR_DONE;
 	lpWaveHdr->dwFlags |= WHDR_INQUEUE;
-        dprintf_mciwave(stddeb,
-	   "wodWrite() // dwBytesRecorded %lu !\n", lpWaveHdr->dwBytesRecorded);
-	if (write (WOutDev[wDevID].unixdev, lpWaveHdr->lpData, 
-		lpWaveHdr->dwBytesRecorded) != lpWaveHdr->dwBytesRecorded) {
+	dprintf_mciwave(stddeb,
+		"wodWrite() // dwBufferLength %lu !\n", lpWaveHdr->dwBufferLength);
+	dprintf_mciwave(stddeb,
+		"wodWrite() // WOutDev[%u].unixdev %u !\n", wDevID, WOutDev[wDevID].unixdev);
+	lpData = PTR_SEG_TO_LIN(lpWaveHdr->lpData);
+	count = write (WOutDev[wDevID].unixdev, lpData, lpWaveHdr->dwBufferLength);
+	dprintf_mciwave(stddeb,
+		"wodWrite() // write returned count %u !\n", count);
+	if (count != lpWaveHdr->dwBufferLength) {
+		fprintf(stderr,"Linux 'wodWrite' // error writting !\n");
 		return MMSYSERR_NOTENABLED;
 		}
+	WOutDev[wDevID].dwTotalPlayed += count;
 	lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
 	lpWaveHdr->dwFlags |= WHDR_DONE;
 	if (WAVE_NotifyClient(wDevID, WOM_DONE, 0L, 0L) != MMSYSERR_NOERROR) {
-                fprintf(stderr,"Linux 'wodWrite' // can't notify client !\n");
+		fprintf(stderr,"Linux 'wodWrite' // can't notify client !\n");
 		return MMSYSERR_INVALPARAM;
 		}
 	return MMSYSERR_NOERROR;
@@ -1007,14 +1064,14 @@
 DWORD wodPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
 #ifdef linux
-        dprintf_mciwave(stddeb,
-		  "wodPrepare(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
+	dprintf_mciwave(stddeb,
+		"wodPrepare(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
 	if (WOutDev[wDevID].unixdev == 0) {
-                fprintf(stderr,"Linux 'wodPrepare' // can't prepare !\n");
+		fprintf(stderr,"Linux 'wodPrepare' // can't prepare !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	if (WOutDev[wDevID].lpQueueHdr != NULL) {
-                fprintf(stderr,"Linux 'wodPrepare' // already prepare !\n");
+		fprintf(stderr,"Linux 'wodPrepare' // already prepare !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	WOutDev[wDevID].dwTotalPlayed = 0;
@@ -1034,10 +1091,10 @@
 DWORD wodUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
 #ifdef linux
-        dprintf_mciwave(stddeb,
+	dprintf_mciwave(stddeb,
 		"wodUnprepare(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
 	if (WOutDev[wDevID].unixdev == 0) {
-        fprintf(stderr,"Linux 'wodUnprepare' // can't unprepare !\n");
+		fprintf(stderr,"Linux 'wodUnprepare' // can't unprepare !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	return MMSYSERR_NOERROR;
@@ -1052,9 +1109,9 @@
 DWORD wodRestart(WORD wDevID)
 {
 #ifdef linux
-        dprintf_mciwave(stddeb,"wodRestart(%u);\n", wDevID);
+	dprintf_mciwave(stddeb,"wodRestart(%u);\n", wDevID);
 	if (WOutDev[wDevID].unixdev == 0) {
-                fprintf(stderr,"Linux 'wodRestart' // can't restart !\n");
+		fprintf(stderr,"Linux 'wodRestart' // can't restart !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	return MMSYSERR_NOERROR;
@@ -1071,7 +1128,7 @@
 #ifdef linux
     dprintf_mciwave(stddeb,"wodReset(%u);\n", wDevID);
 	if (WOutDev[wDevID].unixdev == 0) {
-                fprintf(stderr,"Linux 'wodReset' // can't reset !\n");
+		fprintf(stderr,"Linux 'wodReset' // can't reset !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	return MMSYSERR_NOERROR;
@@ -1090,7 +1147,7 @@
 	int		time;
 	dprintf_mciwave(stddeb,"wodGetPosition(%u, %p, %lu);\n", wDevID, lpTime, uSize);
 	if (WOutDev[wDevID].unixdev == 0) {
-                fprintf(stderr,"Linux 'wodGetPosition' // can't get pos !\n");
+		fprintf(stderr,"Linux 'wodGetPosition' // can't get pos !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	if (lpTime == NULL)	return MMSYSERR_INVALPARAM;
@@ -1101,6 +1158,10 @@
 			dprintf_mciwave(stddeb,"wodGetPosition // TIME_BYTES=%lu\n", lpTime->u.cb);
 			break;
 		case TIME_SAMPLES:
+			dprintf_mciwave(stddeb,"wodGetPosition // dwTotalPlayed=%lu\n", 
+					WOutDev[wDevID].dwTotalPlayed);
+			dprintf_mciwave(stddeb,"wodGetPosition // wBitsPerSample=%u\n", 
+					WOutDev[wDevID].Format.wBitsPerSample);
 			lpTime->u.sample = WOutDev[wDevID].dwTotalPlayed * 8 /
 						WOutDev[wDevID].Format.wBitsPerSample;
 			dprintf_mciwave(stddeb,"wodGetPosition // TIME_SAMPLES=%lu\n", lpTime->u.sample);
@@ -1144,13 +1205,9 @@
 {
 #ifdef linux
 	int 	mixer;
-	int		volume;
+	int		volume, left, right;
 	dprintf_mciwave(stddeb,"wodGetVolume(%u, %p);\n", wDevID, lpdwVol);
 	if (lpdwVol == NULL) return MMSYSERR_NOTENABLED;
-	if (WOutDev[wDevID].unixdev == 0) {
-		fprintf(stderr,"Linux 'wodGetVolume' // can't read volume !\n");
-		return MMSYSERR_NOTENABLED;
-		}
 	if ((mixer = open("/dev/mixer", O_RDONLY)) < 0) {
 		fprintf(stderr, "Linux 'wodGetVolume' // mixer device not available !\n");
 		return MMSYSERR_NOTENABLED;
@@ -1160,7 +1217,10 @@
 		return MMSYSERR_NOTENABLED;
 		}
 	close(mixer);
-	*lpdwVol = MAKELONG(volume, volume);
+	left = volume & 0x7F;
+	right = (volume >> 8) & 0x7F;
+	printf("Linux 'AUX_GetVolume' // left=%d right=%d !\n", left, right);
+	*lpdwVol = MAKELONG(left << 9, right << 9);
 	return MMSYSERR_NOERROR;
 #else
 	return MMSYSERR_NOTENABLED;
@@ -1177,11 +1237,8 @@
 	int 	mixer;
 	int		volume;
 	dprintf_mciwave(stddeb,"wodSetVolume(%u, %08lX);\n", wDevID, dwParam);
-	volume = LOWORD(dwParam);
-	if (WOutDev[wDevID].unixdev == 0) {
-		fprintf(stderr,"Linux 'wodSetVolume' // can't set volume !\n");
-		return MMSYSERR_NOTENABLED;
-		}
+	volume = (LOWORD(dwParam) >> 9 & 0x7F) + 
+		((HIWORD(dwParam) >> 9  & 0x7F) << 8);
 	if ((mixer = open("/dev/mixer", O_WRONLY)) < 0) {
 		fprintf(stderr,	"Linux 'wodSetVolume' // mixer device not available !\n");
 		return MMSYSERR_NOTENABLED;
@@ -1204,7 +1261,7 @@
 DWORD wodMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
 					DWORD dwParam1, DWORD dwParam2)
 {
-        dprintf_mciwave(stddeb,"wodMessage(%u, %04X, %08lX, %08lX, %08lX);\n",
+	dprintf_mciwave(stddeb,"wodMessage(%u, %04X, %08lX, %08lX, %08lX);\n",
 			wDevID, wMsg, dwUser, dwParam1, dwParam2);
 	switch(wMsg) {
 		case WODM_OPEN:
@@ -1243,6 +1300,8 @@
 			return wodRestart(wDevID);
 		case WODM_RESET:
 			return wodReset(wDevID);
+		default:
+			fprintf(stderr,"wodMessage // unknown message !\n");
 		}
 	return MMSYSERR_NOTSUPPORTED;
 }
@@ -1262,7 +1321,7 @@
 	int		dsp_stereo = 1;
 	int		bytespersmpl;
 	dprintf_mciwave(stddeb,
-		  "widGetDevCaps(%u, %p, %lu);\n", wDevID, lpCaps, dwSize);
+		"widGetDevCaps(%u, %p, %lu);\n", wDevID, lpCaps, dwSize);
 	if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
 	audio = open (SOUND_DEV, O_RDONLY, 0);
 	if (audio == -1) return MMSYSERR_NOTENABLED;
@@ -1307,7 +1366,7 @@
 		}
 	close(audio);
 	dprintf_mciwave(stddeb,
-		 "widGetDevCaps // dwFormats = %08lX\n", lpCaps->dwFormats);
+		"widGetDevCaps // dwFormats = %08lX\n", lpCaps->dwFormats);
 	return MMSYSERR_NOERROR;
 #else
 	return MMSYSERR_NOTENABLED;
@@ -1326,48 +1385,43 @@
 	int			smplrate;
 	int			samplesize;
 	int			dsp_stereo;
-        LPWAVEFORMAT  lpFormat;
-	dprintf_mciwave(stddeb,
-		 "widOpen(%u, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
+	LPWAVEFORMAT  lpFormat;
+	dprintf_mciwave(stddeb, "widOpen(%u, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
 	if (lpDesc == NULL) {
-                fprintf(stderr,"Linux 'widOpen' // Invalid Parameter !\n");
+		fprintf(stderr,"Linux 'widOpen' // Invalid Parameter !\n");
 		return MMSYSERR_INVALPARAM;
 		}
 	if (wDevID >= MAX_WAVINDRV) {
-                fprintf(stderr,"Linux 'widOpen' // MAX_WAVINDRV reached !\n");
+		fprintf(stderr,"Linux 'widOpen' // MAX_WAVINDRV reached !\n");
 		return MMSYSERR_ALLOCATED;
 		}
 	WInDev[wDevID].unixdev = 0;
 	audio = open (SOUND_DEV, O_RDONLY, 0);
 	if (audio == -1) {
-                fprintf(stderr,"Linux 'widOpen' // can't open !\n");
+		fprintf(stderr,"Linux 'widOpen' // can't open !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	IOCTL(audio, SNDCTL_DSP_GETBLKSIZE, abuf_size);
 	if (abuf_size < 4096 || abuf_size > 65536) {
 		if (abuf_size == -1)
-		  fprintf(stderr,"Linux 'widOpen' // IOCTL can't 'SNDCTL_DSP_GETBLKSIZE' !\n");
+			fprintf(stderr,"Linux 'widOpen' // IOCTL can't 'SNDCTL_DSP_GETBLKSIZE' !\n");
 		else
-		  fprintf(stderr,"Linux 'widOpen' // SNDCTL_DSP_GETBLKSIZE Invalid bufsize !\n");
+			fprintf(stderr,"Linux 'widOpen' // SNDCTL_DSP_GETBLKSIZE Invalid bufsize !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	WInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
 	switch(WInDev[wDevID].wFlags) {
 		case DCB_NULL:
-	                dprintf_mciwave(stddeb,
-			      "Linux 'widOpen' // CALLBACK_NULL !\n");
+			dprintf_mciwave(stddeb,	"Linux 'widOpen' // CALLBACK_NULL !\n");
 			break;
 		case DCB_WINDOW:
-			dprintf_mciwave(stddeb,
-			      "Linux 'widOpen' // CALLBACK_WINDOW !\n");
+			dprintf_mciwave(stddeb, "Linux 'widOpen' // CALLBACK_WINDOW !\n");
 			break;
 		case DCB_TASK:
-			dprintf_mciwave(stddeb,
-			      "Linux 'widOpen' // CALLBACK_TASK !\n");
+			dprintf_mciwave(stddeb,	"Linux 'widOpen' // CALLBACK_TASK !\n");
 			break;
 		case DCB_FUNCTION:
-			dprintf_mciwave(stddeb,
-			      "Linux 'widOpen' // CALLBACK_FUNCTION !\n");
+			dprintf_mciwave(stddeb,	"Linux 'widOpen' // CALLBACK_FUNCTION !\n");
 			break;
 		}
 	WInDev[wDevID].lpQueueHdr = NULL;
@@ -1375,10 +1429,10 @@
 	WInDev[wDevID].bufsize = abuf_size;
 	WInDev[wDevID].dwTotalRecorded = 0;
 	memcpy(&WInDev[wDevID].waveDesc, lpDesc, sizeof(WAVEOPENDESC));
-        lpFormat = (LPWAVEFORMAT)PTR_SEG_TO_LIN(lpDesc->lpFormat);
+        lpFormat = lpDesc->lpFormat;
 	if (lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
-	        fprintf(stderr,"Linux 'widOpen' // Bad format %04X !\n",
-						lpFormat->wFormatTag);
+		fprintf(stderr,"Linux 'widOpen' // Bad format %04X !\n",
+					lpFormat->wFormatTag);
 		return WAVERR_BADFORMAT;
 		}
 	memcpy(&WInDev[wDevID].Format, lpFormat, sizeof(PCMWAVEFORMAT));
@@ -1406,7 +1460,7 @@
 	dprintf_mciwave(stddeb,"Linux 'widOpen' // nAvgBytesPerSec=%lu\n",
 			WInDev[wDevID].Format.wf.nAvgBytesPerSec); 
 	if (WAVE_NotifyClient(wDevID, WIM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
-	        fprintf(stderr,"Linux 'widOpen' // can't notify client !\n");
+		fprintf(stderr,"Linux 'widOpen' // can't notify client !\n");
 		return MMSYSERR_INVALPARAM;
 		}
 	return MMSYSERR_NOERROR;
@@ -1421,16 +1475,16 @@
 DWORD widClose(WORD wDevID)
 {
 #ifdef linux
-        dprintf_mciwave(stddeb,"widClose(%u);\n", wDevID);
+	dprintf_mciwave(stddeb,"widClose(%u);\n", wDevID);
 	if (WInDev[wDevID].unixdev == 0) {
-                fprintf(stderr,"Linux 'widClose' // can't close !\n");
+		fprintf(stderr,"Linux 'widClose' // can't close !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	close(WInDev[wDevID].unixdev);
 	WInDev[wDevID].unixdev = 0;
 	WInDev[wDevID].bufsize = 0;
 	if (WAVE_NotifyClient(wDevID, WIM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
-                fprintf(stderr,"Linux 'widClose' // can't notify client !\n");
+		fprintf(stderr,"Linux 'widClose' // can't notify client !\n");
 		return MMSYSERR_INVALPARAM;
 		}
 	return MMSYSERR_NOERROR;
@@ -1448,30 +1502,30 @@
 	int			count	= 1;
 	LPWAVEHDR 	lpWIHdr;
 	dprintf_mciwave(stddeb,
-	       "widAddBuffer(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
+		"widAddBuffer(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
 	if (WInDev[wDevID].unixdev == 0) {
-	        fprintf(stderr,"Linux 'widAddBuffer' // can't do it !\n");
+		fprintf(stderr,"Linux 'widAddBuffer' // can't do it !\n");
 		return MMSYSERR_NOTENABLED;
 		}
-	if (WInDev[wDevID].lpQueueHdr == NULL || 
-		!(lpWaveHdr->dwFlags & WHDR_PREPARED)) {
-	        fprintf(stderr,
-		       "Linux 'widAddBuffer' // never been prepared !\n");
+	if (!(lpWaveHdr->dwFlags & WHDR_PREPARED)) {
+		fprintf(stderr,	"Linux 'widAddBuffer' // never been prepared !\n");
 		return WAVERR_UNPREPARED;
 		}
-	if ((lpWaveHdr->dwFlags & WHDR_INQUEUE) &&
-		(WInDev[wDevID].lpQueueHdr != lpWaveHdr)) {
-		/* except if it's the one just prepared ... */
-	        fprintf(stderr,
-			"Linux 'widAddBuffer' // header already in use !\n");
+	if (lpWaveHdr->dwFlags & WHDR_INQUEUE) {
+		fprintf(stderr,	"Linux 'widAddBuffer' // header already in use !\n");
 		return WAVERR_STILLPLAYING;
 		}
 	lpWaveHdr->dwFlags |= WHDR_PREPARED;
 	lpWaveHdr->dwFlags |= WHDR_INQUEUE;
 	lpWaveHdr->dwFlags &= ~WHDR_DONE;
 	lpWaveHdr->dwBytesRecorded = 0;
-	/* added to the queue, except if it's the one just prepared ... */
-	if (WInDev[wDevID].lpQueueHdr != lpWaveHdr) {
+	if (WInDev[wDevID].lpQueueHdr == NULL) {
+		/* begin the queue with a first header ... */
+		WInDev[wDevID].lpQueueHdr = lpWaveHdr;
+		WInDev[wDevID].dwTotalRecorded = 0;
+		}
+	else {
+		/* added to the queue, except if it's the one just prepared ... */
 		lpWIHdr = WInDev[wDevID].lpQueueHdr;
 		while (lpWIHdr->lpNext != NULL) {
 			lpWIHdr = lpWIHdr->lpNext;
@@ -1481,7 +1535,7 @@
 		count++;
 		}
 	dprintf_mciwave(stddeb,
-	      "widAddBuffer // buffer added ! (now %u in queue)\n", count);
+		"widAddBuffer // buffer added ! (now %u in queue)\n", count);
 	return MMSYSERR_NOERROR;
 #else
 	return MMSYSERR_NOTENABLED;
@@ -1497,18 +1551,16 @@
 	dprintf_mciwave(stddeb,
 		"widPrepare(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
 	if (WInDev[wDevID].unixdev == 0) {
-	        fprintf(stderr,"Linux 'widPrepare' // can't prepare !\n");
+		fprintf(stderr,"Linux 'widPrepare' // can't prepare !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	if (WInDev[wDevID].lpQueueHdr != NULL) {
-                fprintf(stderr,"Linux 'widPrepare' // already prepare !\n");
+		fprintf(stderr,"Linux 'widPrepare' // already prepare !\n");
 		return WAVERR_BADFORMAT;
 		}
-	WInDev[wDevID].dwTotalRecorded = 0;
-	WInDev[wDevID].lpQueueHdr = lpWaveHdr;
 	if (lpWaveHdr->dwFlags & WHDR_INQUEUE) return WAVERR_STILLPLAYING;
 	lpWaveHdr->dwFlags |= WHDR_PREPARED;
-	lpWaveHdr->dwFlags |= WHDR_INQUEUE;
+	lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
 	lpWaveHdr->dwFlags &= ~WHDR_DONE;
 	lpWaveHdr->dwBytesRecorded = 0;
 	dprintf_mciwave(stddeb,"Linux 'widPrepare' // header prepared !\n");
@@ -1527,7 +1579,7 @@
 	dprintf_mciwave(stddeb,
 		"widUnprepare(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
 	if (WInDev[wDevID].unixdev == 0) {
-                fprintf(stderr,"Linux 'widUnprepare' // can't unprepare !\n");
+		fprintf(stderr,"Linux 'widUnprepare' // can't unprepare !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	lpWaveHdr->dwFlags &= ~WHDR_PREPARED;
@@ -1535,7 +1587,7 @@
 	lpWaveHdr->dwFlags |= WHDR_DONE;
 	WInDev[wDevID].lpQueueHdr = NULL;
 	dprintf_mciwave(stddeb,
-		  "Linux 'widUnprepare' // all headers unprepared !\n");
+		"Linux 'widUnprepare' // all headers unprepared !\n");
 	return MMSYSERR_NOERROR;
 #else
 	return MMSYSERR_NOTENABLED;
@@ -1552,32 +1604,31 @@
 	LPWAVEHDR 	lpWIHdr;
 	dprintf_mciwave(stddeb,"widStart(%u);\n", wDevID);
 	if (WInDev[wDevID].unixdev == 0) {
-	        fprintf(stderr,
-		       "Linux 'widStart' // can't start recording !\n");
+		fprintf(stderr,	"Linux 'widStart' // can't start recording !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	if (WInDev[wDevID].lpQueueHdr == NULL || 
 		WInDev[wDevID].lpQueueHdr->lpData == NULL) {
-	        fprintf(stderr,"Linux 'widStart' // never been prepared !\n");
+		fprintf(stderr,"Linux 'widStart' // never been prepared !\n");
 		return WAVERR_UNPREPARED;
 		}
 	lpWIHdr = WInDev[wDevID].lpQueueHdr;
 	while(lpWIHdr != NULL) {
 		lpWIHdr->dwBufferLength &= 0xFFFF;
-                dprintf_mciwave(stddeb,
-		        "widStart // recording buf#%u=%p size=%lu \n",
+		dprintf_mciwave(stddeb,
+			"widStart // recording buf#%u=%p size=%lu \n",
 			count, lpWIHdr->lpData, lpWIHdr->dwBufferLength);
 		fflush(stddeb);
-		read (WInDev[wDevID].unixdev, lpWIHdr->lpData,
-						      lpWIHdr->dwBufferLength);
+		read (WInDev[wDevID].unixdev, 
+			PTR_SEG_TO_LIN(lpWIHdr->lpData),
+			lpWIHdr->dwBufferLength);
 		lpWIHdr->dwBytesRecorded = lpWIHdr->dwBufferLength;
 		WInDev[wDevID].dwTotalRecorded += lpWIHdr->dwBytesRecorded;
 		lpWIHdr->dwFlags &= ~WHDR_INQUEUE;
 		lpWIHdr->dwFlags |= WHDR_DONE;
 		if (WAVE_NotifyClient(wDevID, WIM_DATA, (DWORD)lpWIHdr, 0L) != 
 			MMSYSERR_NOERROR) {
-		        fprintf(stderr,
-			     "Linux 'widStart' // can't notify client !\n");
+			fprintf(stderr,	"Linux 'widStart' // can't notify client !\n");
 			return MMSYSERR_INVALPARAM;
 			}
 		lpWIHdr = lpWIHdr->lpNext;
@@ -1597,9 +1648,9 @@
 DWORD widStop(WORD wDevID)
 {
 #ifdef linux
-        dprintf_mciwave(stddeb,"widStop(%u);\n", wDevID);
+	dprintf_mciwave(stddeb,"widStop(%u);\n", wDevID);
 	if (WInDev[wDevID].unixdev == 0) {
-                fprintf(stderr,"Linux 'widStop' // can't stop !\n");
+		fprintf(stderr,"Linux 'widStop' // can't stop !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	return MMSYSERR_NOERROR;
@@ -1614,9 +1665,9 @@
 DWORD widReset(WORD wDevID)
 {
 #ifdef linux
-        dprintf_mciwave(stddeb,"widReset(%u);\n", wDevID);
+	dprintf_mciwave(stddeb,"widReset(%u);\n", wDevID);
 	if (WInDev[wDevID].unixdev == 0) {
-                fprintf(stderr,"Linux 'widReset' // can't reset !\n");
+		fprintf(stderr,"Linux 'widReset' // can't reset !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	return MMSYSERR_NOERROR;
@@ -1632,10 +1683,10 @@
 {
 #ifdef linux
 	int		time;
-        dprintf_mciwave(stddeb,
+	dprintf_mciwave(stddeb,
 		"widGetPosition(%u, %p, %lu);\n", wDevID, lpTime, uSize);
 	if (WInDev[wDevID].unixdev == 0) {
-                fprintf(stderr,"Linux 'widGetPosition' // can't get pos !\n");
+		fprintf(stderr,"Linux 'widGetPosition' // can't get pos !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	if (lpTime == NULL)	return MMSYSERR_INVALPARAM;
@@ -1702,7 +1753,7 @@
 DWORD widMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
 					DWORD dwParam1, DWORD dwParam2)
 {
-        dprintf_mciwave(stddeb,"widMessage(%u, %04X, %08lX, %08lX, %08lX);\n",
+	dprintf_mciwave(stddeb,"widMessage(%u, %04X, %08lX, %08lX, %08lX);\n",
 			wDevID, wMsg, dwUser, dwParam1, dwParam2);
 	switch(wMsg) {
 		case WIDM_OPEN:
@@ -1727,6 +1778,8 @@
 			return widStart(wDevID);
 		case WIDM_STOP:
 			return widStop(wDevID);
+		default:
+			fprintf(stderr,"widMessage // unknown message !\n");
 		}
 	return MMSYSERR_NOTSUPPORTED;
 }
diff --git a/multimedia/mcianim.c b/multimedia/mcianim.c
index 5b764e5..ebe1bbc 100644
--- a/multimedia/mcianim.c
+++ b/multimedia/mcianim.c
@@ -62,13 +62,14 @@
 /**************************************************************************
 * 				ANIM_mciOpen			[internal]
 */
-DWORD ANIM_mciOpen(DWORD dwFlags, LPMCI_OPEN_PARMS lpParms)
+DWORD ANIM_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS lpParms)
 {
 #ifdef linux
-	UINT	wDevID;
-	dprintf_mcianim(stddeb,"ANIM_mciOpen(%08lX, %p);\n", dwFlags, lpParms);
+	LPSTR		lpstrElementName;
+	char		str[128];
+	dprintf_mcianim(stddeb,"ANIM_mciOpen(%04X, %08lX, %p);\n", 
+					wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
-	wDevID = lpParms->wDeviceID;
 	if (AnimDev[wDevID].nUseCount > 0) {
 		/* The driver already open on this channel */
 		/* If the driver was opened shareable before and this open specifies */
@@ -82,10 +83,17 @@
 		AnimDev[wDevID].nUseCount = 1;
 		AnimDev[wDevID].fShareable = dwFlags & MCI_OPEN_SHAREABLE;
 		}
+	dprintf_mcianim(stddeb,"ANIM_mciOpen // wDevID=%04X\n", wDevID);
+	lpParms->wDeviceID = wDevID;
+	dprintf_mcianim(stddeb,"ANIM_mciOpen // lpParms->wDevID=%04X\n", lpParms->wDeviceID);
     if (dwFlags & MCI_OPEN_ELEMENT) {
-        dprintf_mcianim(stddeb,"ANIM_mciOpen // MCI_OPEN_ELEMENT !\n");
-        printf("ANIM_mciOpen // MCI_OPEN_ELEMENT !\n");
-/*		return MCIERR_NO_ELEMENT_ALLOWED; */
+		lpstrElementName = (LPSTR)PTR_SEG_TO_LIN(lpParms->lpstrElementName);
+		dprintf_mcianim(stddeb,"ANIM_mciOpen // MCI_OPEN_ELEMENT '%s' !\n",
+						lpstrElementName);
+		if (strlen(lpstrElementName) > 0) {
+			strcpy(str, lpstrElementName);
+			AnsiUpper(str);
+			}
 		}
 	memcpy(&AnimDev[wDevID].openParms, lpParms, sizeof(MCI_OPEN_PARMS));
 	AnimDev[wDevID].wNotifyDeviceID = lpParms->wDeviceID;
@@ -618,12 +626,13 @@
 		case DRV_OPEN:
 		case MCI_OPEN_DRIVER:
 		case MCI_OPEN:
-			return ANIM_mciOpen(dwParam1, (LPMCI_OPEN_PARMS)dwParam2); 
+			return ANIM_mciOpen(dwDevID, dwParam1, 
+					(LPMCI_OPEN_PARMS)PTR_SEG_TO_LIN(dwParam2)); 
 		case DRV_CLOSE:
 		case MCI_CLOSE_DRIVER:
 		case MCI_CLOSE:
 			return ANIM_mciClose(dwDevID, dwParam1, 
-					(LPMCI_GENERIC_PARMS)dwParam2);
+					(LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case DRV_ENABLE:
 			return (LRESULT)1L;
 		case DRV_DISABLE:
@@ -640,31 +649,31 @@
 			return (LRESULT)DRVCNF_RESTART;
 		case MCI_GETDEVCAPS:
 			return ANIM_mciGetDevCaps(dwDevID, dwParam1, 
-					(LPMCI_GETDEVCAPS_PARMS)dwParam2);
+					(LPMCI_GETDEVCAPS_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_INFO:
 			return ANIM_mciInfo(dwDevID, dwParam1, 
-						(LPMCI_INFO_PARMS)dwParam2);
+						(LPMCI_INFO_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_STATUS:
 			return ANIM_mciStatus(dwDevID, dwParam1, 
-						(LPMCI_STATUS_PARMS)dwParam2);
+						(LPMCI_STATUS_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_SET:
 			return ANIM_mciSet(dwDevID, dwParam1, 
-						(LPMCI_SET_PARMS)dwParam2);
+						(LPMCI_SET_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_PLAY:
 			return ANIM_mciPlay(dwDevID, dwParam1, 
-						(LPMCI_PLAY_PARMS)dwParam2);
+						(LPMCI_PLAY_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_STOP:
 			return ANIM_mciStop(dwDevID, dwParam1, 
-					(LPMCI_GENERIC_PARMS)dwParam2);
+					(LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_PAUSE:
 			return ANIM_mciPause(dwDevID, dwParam1, 
-					(LPMCI_GENERIC_PARMS)dwParam2);
+					(LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_RESUME:
 			return ANIM_mciResume(dwDevID, dwParam1, 
-					(LPMCI_GENERIC_PARMS)dwParam2);
+					(LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_SEEK:
 			return ANIM_mciSeek(dwDevID, dwParam1, 
-					(LPMCI_SEEK_PARMS)dwParam2);
+					(LPMCI_SEEK_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		default:
 			return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
 		}
diff --git a/multimedia/mcicda.c b/multimedia/mcicda.c
index f60163d..6e00345 100644
--- a/multimedia/mcicda.c
+++ b/multimedia/mcicda.c
@@ -81,12 +81,11 @@
 /**************************************************************************
 * 				CDAUDIO_mciOpen			[internal]
 */
-DWORD CDAUDIO_mciOpen(DWORD dwFlags, LPMCI_OPEN_PARMS lpParms)
+DWORD CDAUDIO_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS lpParms)
 {
 #ifdef linux
-	UINT	wDevID;
-    	dprintf_cdaudio(stddeb,"CDAUDIO_mciOpen(%08lX, %p);\n", 
-		dwFlags, lpParms);
+    	dprintf_cdaudio(stddeb,"CDAUDIO_mciOpen(%04X, %08lX, %p);\n", 
+					wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	wDevID = lpParms->wDeviceID;
 	if (CDADev[wDevID].nUseCount > 0) {
@@ -103,14 +102,14 @@
 		CDADev[wDevID].fShareable = dwFlags & MCI_OPEN_SHAREABLE;
 		}
     if (dwFlags & MCI_OPEN_ELEMENT) {
-        dprintf_cdaudio(stddeb,"CDAUDIO_mciOpen // MCI_OPEN_ELEMENT !\n");
+		dprintf_cdaudio(stddeb,"CDAUDIO_mciOpen // MCI_OPEN_ELEMENT !\n");
 /*		return MCIERR_NO_ELEMENT_ALLOWED; */
 		}
 	memcpy(&CDADev[wDevID].openParms, lpParms, sizeof(MCI_OPEN_PARMS));
 	CDADev[wDevID].wNotifyDeviceID = lpParms->wDeviceID;
 	CDADev[wDevID].unixdev = open (CDAUDIO_DEV, O_RDONLY, 0);
 	if (CDADev[wDevID].unixdev == -1) {
-        fprintf(stderr,"CDAUDIO_mciOpen // can't open '%s' !\n", CDAUDIO_DEV);
+		fprintf(stderr,"CDAUDIO_mciOpen // can't open '%s' !\n", CDAUDIO_DEV);
 		return MCIERR_HARDWARE;
 		}
 	CDADev[wDevID].mode = 0;
@@ -122,7 +121,7 @@
 	CDADev[wDevID].lpdwTrackLen = NULL;
 	CDADev[wDevID].lpdwTrackPos = NULL;
 	if (!CDAUDIO_GetTracksInfo(wDevID)) {
-        fprintf(stderr,"CDAUDIO_mciOpen // error reading TracksInfo !\n");
+		fprintf(stderr,"CDAUDIO_mciOpen // error reading TracksInfo !\n");
 /*		return MCIERR_INTERNAL; */
 		}
 	if (dwFlags & MCI_NOTIFY) {
@@ -267,8 +266,8 @@
 						}
 					}
 				if (dwFlags & MCI_TRACK) {
-                    			dprintf_cdaudio(stddeb,"CDAUDIO_mciStatus // MCI_TRACK #%lu LENGTH=??? !\n",
-														lpParms->dwTrack);
+					dprintf_cdaudio(stddeb,"CDAUDIO_mciStatus // MCI_TRACK #%lu LENGTH=??? !\n",
+							lpParms->dwTrack);
 					if (lpParms->dwTrack > CDADev[wDevID].nTracks)
 						return MCIERR_OUTOFRANGE;
 					lpParms->dwReturn = CDADev[wDevID].lpdwTrackLen[lpParms->dwTrack];
@@ -514,7 +513,8 @@
 			entry.cdte_addr.msf.minute + entry.cdte_addr.msf.second) + 
 			entry.cdte_addr.msf.frame;
 		if (i == 0) {
-			CDADev[wDevID].dwFirstOffset = last_start = start;
+			last_start = start;
+			CDADev[wDevID].dwFirstOffset = start;
             		dprintf_cdaudio(stddeb,
 				"CDAUDIO_GetTracksInfo // dwFirstOffset=%u\n", 
 				start);
@@ -648,8 +648,10 @@
         	dprintf_cdaudio(stddeb,
 			"CDAUDIO_mciPlay // MCI_NOTIFY_SUCCESSFUL %08lX !\n", 
 			lpParms->dwCallback);
+/*
 		mciDriverNotify((HWND)LOWORD(lpParms->dwCallback), 
 			CDADev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
+*/
 		}
 	return 0;
 #else
@@ -845,7 +847,7 @@
 		case DRV_OPEN:
 		case MCI_OPEN_DRIVER:
 		case MCI_OPEN:
-			return CDAUDIO_mciOpen(dwParam1, (LPMCI_OPEN_PARMS)dwParam2); 
+			return CDAUDIO_mciOpen(dwDevID, dwParam1, (LPMCI_OPEN_PARMS)dwParam2); 
 		case DRV_CLOSE:
 		case MCI_CLOSE_DRIVER:
 		case MCI_CLOSE:
@@ -867,31 +869,31 @@
 			return (LRESULT)DRVCNF_RESTART;
 		case MCI_GETDEVCAPS:
 			return CDAUDIO_mciGetDevCaps(dwDevID, dwParam1, 
-					(LPMCI_GETDEVCAPS_PARMS)dwParam2);
+				(LPMCI_GETDEVCAPS_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_INFO:
 			return CDAUDIO_mciInfo(dwDevID, dwParam1, 
-						(LPMCI_INFO_PARMS)dwParam2);
+				(LPMCI_INFO_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_STATUS:
 			return CDAUDIO_mciStatus(dwDevID, dwParam1, 
-						(LPMCI_STATUS_PARMS)dwParam2);
+				(LPMCI_STATUS_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_SET:
 			return CDAUDIO_mciSet(dwDevID, dwParam1, 
-						(LPMCI_SET_PARMS)dwParam2);
+				(LPMCI_SET_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_PLAY:
 			return CDAUDIO_mciPlay(dwDevID, dwParam1, 
-						(LPMCI_PLAY_PARMS)dwParam2);
+				(LPMCI_PLAY_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_STOP:
 			return CDAUDIO_mciStop(dwDevID, dwParam1, 
-					(LPMCI_GENERIC_PARMS)dwParam2);
+				(LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_PAUSE:
 			return CDAUDIO_mciPause(dwDevID, dwParam1, 
-					(LPMCI_GENERIC_PARMS)dwParam2);
+				(LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_RESUME:
 			return CDAUDIO_mciResume(dwDevID, dwParam1, 
-					(LPMCI_GENERIC_PARMS)dwParam2);
+				(LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_SEEK:
 			return CDAUDIO_mciSeek(dwDevID, dwParam1, 
-					(LPMCI_SEEK_PARMS)dwParam2);
+				(LPMCI_SEEK_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_SET_DOOR_OPEN:
             		dprintf_cdaudio(stddeb,
 				"CDAUDIO_DriverProc // MCI_SET_DOOR_OPEN !\n");
diff --git a/multimedia/midi.c b/multimedia/midi.c
index 01ef172..be27086 100644
--- a/multimedia/midi.c
+++ b/multimedia/midi.c
@@ -83,7 +83,7 @@
 static LINUX_MCIMIDI	MCIMidiDev[MAX_MCIMIDIDRV];
 #endif
 
-DWORD MIDI_mciOpen(DWORD dwFlags, LPMCI_OPEN_PARMS lpParms);
+DWORD MIDI_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS lpParms);
 DWORD MIDI_mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms);
 DWORD MIDI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms);
 DWORD MIDI_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms);
@@ -160,7 +160,7 @@
 			return (LRESULT)DRVCNF_RESTART;
 		case MCI_OPEN_DRIVER:
 		case MCI_OPEN:
-			return MIDI_mciOpen(dwParam1, (LPMCI_OPEN_PARMS)PTR_SEG_TO_LIN(dwParam2));
+			return MIDI_mciOpen(dwDevID, dwParam1, (LPMCI_OPEN_PARMS)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));
@@ -352,18 +352,17 @@
 /**************************************************************************
 * 				MIDI_mciOpen			[internal]	
 */
-DWORD MIDI_mciOpen(DWORD dwFlags, LPMCI_OPEN_PARMS lpParms)
+DWORD MIDI_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS lpParms)
 {
 #ifdef linux
-	UINT 		wDevID;
 	MIDIOPENDESC 	MidiDesc;
 	DWORD		dwRet;
 	DWORD		dwOffset;
+	LPSTR		lpstrElementName;
 	char		str[128];
 
 	dprintf_midi( stddeb, "MIDI_mciOpen(%08lX, %p)\n", dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
-	wDevID = lpParms->wDeviceID;
 	if (MCIMidiDev[wDevID].nUseCount > 0) {
 		/* The driver already open on this channel */
 		/* If the driver was opened shareable before and this open specifies */
@@ -377,12 +376,16 @@
 		MCIMidiDev[wDevID].nUseCount = 1;
 		MCIMidiDev[wDevID].fShareable = dwFlags & MCI_OPEN_SHAREABLE;
 		}
+	dprintf_midi(stddeb,"MIDI_mciOpen // wDevID=%04X\n", wDevID);
+	lpParms->wDeviceID = wDevID;
+	dprintf_midi(stddeb,"MIDI_mciOpen // lpParms->wDevID=%04X\n", lpParms->wDeviceID);
+	dprintf_midi(stddeb,"MIDI_mciOpen // before OPEN_ELEMENT\n");
     if (dwFlags & MCI_OPEN_ELEMENT) {
-		printf("MIDI_mciOpen // MCI_OPEN_ELEMENT '%s' !\n", 
-								lpParms->lpstrElementName);
+		lpstrElementName = (LPSTR)PTR_SEG_TO_LIN(lpParms->lpstrElementName);
+		dprintf_midi( stddeb, "MIDI_mciOpen // MCI_OPEN_ELEMENT '%s' !\n", lpstrElementName);
 /*		printf("MIDI_mciOpen // cdw='%s'\n", DOS_GetCurrentDir(DOS_GetDefaultDrive())); */
-		if (strlen(lpParms->lpstrElementName) > 0) {
-			strcpy(str, lpParms->lpstrElementName);
+		if (strlen(lpstrElementName) > 0) {
+			strcpy(str, lpstrElementName);
 			AnsiUpper(str);
 			MCIMidiDev[wDevID].hFile = mmioOpen(str, NULL, 
 				MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_EXCLUSIVE);
@@ -1095,7 +1098,7 @@
 		case MIDM_GETDEVCAPS:
 			return midGetDevCaps(wDevID, (LPMIDIINCAPS)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case MIDM_GETNUMDEVS:
-			return 1L;
+			return 0L;
 		case MIDM_RESET:
 			return midReset(wDevID);
 		case MIDM_START:
diff --git a/multimedia/mmaux.c b/multimedia/mmaux.c
index 78b9bf1..05a1a0b 100644
--- a/multimedia/mmaux.c
+++ b/multimedia/mmaux.c
@@ -37,6 +37,8 @@
 #endif
 
 
+static int	NumDev = 6;
+
 /*-----------------------------------------------------------------------*/
 
 
@@ -118,7 +120,7 @@
 {
 #ifdef linux
 	int 	mixer;
-	int		volume;
+	int		volume, left, right;
 	int		cmd;
 	printf("AUX_GetVolume(%u, %p);\n", wDevID, lpdwVol);
 	if (lpdwVol == NULL) return MMSYSERR_NOTENABLED;
@@ -148,17 +150,22 @@
 			cmd = SOUND_MIXER_READ_MIC;
 			break;
 		case 5:
-		default:
 			printf("Linux 'AUX_GetVolume' // SOUND_MIXER_READ_VOLUME !\n");
 			cmd = SOUND_MIXER_READ_VOLUME;
 			break;
+		default:
+			fprintf(stderr, "Linux 'AUX_GetVolume' // invalid device id=%d !\n", wDevID);
+			return MMSYSERR_NOTENABLED;
 		}
     if (ioctl(mixer, cmd, &volume) == -1) {
 		printf("Linux 'AUX_GetVolume' // unable read mixer !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	close(mixer);
-	*lpdwVol = MAKELONG(volume, volume);
+	left = volume & 0x7F;
+	right = (volume >> 8) & 0x7F;
+	printf("Linux 'AUX_GetVolume' // left=%d right=%d !\n", left, right);
+	*lpdwVol = MAKELONG(left << 9, right << 9);
 	return MMSYSERR_NOERROR;
 #else
 	return MMSYSERR_NOTENABLED;
@@ -174,8 +181,9 @@
 	int 	mixer;
 	int		volume;
 	int		cmd;
-	printf("AUX_SetVolume(%u, %08lX);\n", wDevID, dwParam);
-	volume = LOWORD(dwParam);
+	printf("AUX_SetVolume(%u (%04X), %08lX);\n", wDevID, wDevID, dwParam);
+	volume = (LOWORD(dwParam) >> 9 & 0x7F) + 
+		((HIWORD(dwParam) >> 9  & 0x7F) << 8);
 	if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
 		printf("Linux 'AUX_SetVolume' // mixer device not available !\n");
 		return MMSYSERR_NOTENABLED;
@@ -202,10 +210,12 @@
 			cmd = SOUND_MIXER_WRITE_MIC;
 			break;
 		case 5:
-		default:
 			printf("Linux 'AUX_SetVolume' // SOUND_MIXER_WRITE_VOLUME !\n");
 			cmd = SOUND_MIXER_WRITE_VOLUME;
 			break;
+		default:
+			fprintf(stderr, "Linux 'AUX_SetVolume' // invalid device id=%d !\n", wDevID);
+			return MMSYSERR_NOTENABLED;
 		}
     if (ioctl(mixer, cmd, &volume) == -1) {
 		printf("Linux 'AUX_SetVolume' // unable set mixer !\n");
@@ -229,14 +239,17 @@
 			wDevID, wMsg, dwUser, dwParam1, dwParam2);
 	switch(wMsg) {
 		case AUXDM_GETDEVCAPS:
-			return AUX_GetDevCaps(wDevID, (LPAUXCAPS)dwParam1, dwParam2);
+			return AUX_GetDevCaps(wDevID, 
+				(LPAUXCAPS)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case AUXDM_GETNUMDEVS:
-			printf("AUX_GetNumDevs();\n");
-			return 1L;
+			printf("AUX_GetNumDevs() return %d;\n", NumDev);
+			return NumDev;
 		case AUXDM_GETVOLUME:
-			return AUX_GetVolume(wDevID, (LPDWORD)dwParam1);
+			return AUX_GetVolume(wDevID, (LPDWORD)PTR_SEG_TO_LIN(dwParam1));
 		case AUXDM_SETVOLUME:
 			return AUX_SetVolume(wDevID, dwParam1);
+		default:
+			fprintf(stderr,"auxMessage // unknown message !\n");
 		}
 	return MMSYSERR_NOTSUPPORTED;
 }
diff --git a/multimedia/mmsystem.c b/multimedia/mmsystem.c
index e2af222..ce8642f 100644
--- a/multimedia/mmsystem.c
+++ b/multimedia/mmsystem.c
@@ -7,6 +7,7 @@
 */
 #ifndef WINELIB
 
+#include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -27,6 +28,9 @@
 /* #undef  DEBUG_MMIO   */
 #include "debug.h"
 
+static int	InstalledCount;
+static int	InstalledListLen;
+static LPSTR	lpInstallNames = NULL;
 
 static BOOL		mmTimeStarted = FALSE;
 static MMTIME	mmSysTimeMS;
@@ -81,10 +85,16 @@
 	HMMIO			hmmio;
 	MMCKINFO		mmckInfo;
 	MMCKINFO		ckMainRIFF;
+	HANDLE			hFormat;
 	PCMWAVEFORMAT 	pcmWaveFormat;
 	int				count;
-	WAVEHDR			WaveHdr;
-	WAVEOPENDESC 	WaveDesc;
+	int				bufsize;
+	HANDLE			hDesc;
+	LPWAVEOPENDESC 	lpWaveDesc;
+	HANDLE			hWaveHdr;
+	LPWAVEHDR		lpWaveHdr;
+	LPWAVEHDR		lp16WaveHdr;
+	HANDLE			hData;
 	DWORD			dwRet;
 	char			str[128];
 	LPSTR			ptr;
@@ -122,46 +132,67 @@
 			(LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType,
 			mmckInfo.cksize);
 	if (mmioRead(hmmio, (HPSTR) &pcmWaveFormat,
-	    (long) sizeof(PCMWAVEFORMAT)) != (long) sizeof(PCMWAVEFORMAT)) goto ErrSND;
+		(long) sizeof(PCMWAVEFORMAT)) != (long) sizeof(PCMWAVEFORMAT)) goto ErrSND;
+
+	printf("sndPlaySound // wFormatTag=%04X !\n", pcmWaveFormat.wf.wFormatTag);
+	printf("sndPlaySound // nChannels=%d \n", pcmWaveFormat.wf.nChannels);
+	printf("sndPlaySound // nSamplesPerSec=%ld\n", pcmWaveFormat.wf.nSamplesPerSec);
+	printf("sndPlaySound // nAvgBytesPerSec=%ld\n", pcmWaveFormat.wf.nAvgBytesPerSec);
+	printf("sndPlaySound // nBlockAlign=%d \n", pcmWaveFormat.wf.nBlockAlign);
+	printf("sndPlaySound // wBitsPerSample=%u !\n", pcmWaveFormat.wBitsPerSample);
+
 	mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
 	if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) != 0) goto ErrSND;
 	printf("sndPlaySound // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
 			(LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType,
 			mmckInfo.cksize);
-	WaveDesc.hWave = 0;
-	WaveDesc.lpFormat = (LPWAVEFORMAT)&pcmWaveFormat;
-	pcmWaveFormat.wf.wFormatTag = WAVE_FORMAT_PCM;
-/*	pcmWaveFormat.wBitsPerSample = 8;
-	pcmWaveFormat.wf.nChannels = 1;
-	pcmWaveFormat.wf.nSamplesPerSec = 11025; 
-	pcmWaveFormat.wf.nBlockAlign = 1; */
+	hDesc = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
+	lpWaveDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hDesc);
+	lpWaveDesc->hWave = 0;
 	pcmWaveFormat.wf.nAvgBytesPerSec = 
 		pcmWaveFormat.wf.nSamplesPerSec * pcmWaveFormat.wf.nBlockAlign;
-	dwRet = wodMessage(0, WODM_OPEN, 0, (DWORD)&WaveDesc, CALLBACK_NULL);
+	hFormat = USER_HEAP_ALLOC(sizeof(PCMWAVEFORMAT));
+	lpWaveDesc->lpFormat = (LPWAVEFORMAT) USER_HEAP_LIN_ADDR(hFormat);
+	memcpy(lpWaveDesc->lpFormat, &pcmWaveFormat, sizeof(PCMWAVEFORMAT));
+	lpWaveDesc = (LPWAVEOPENDESC) USER_HEAP_SEG_ADDR(hDesc);
+	dwRet = wodMessage(0, WODM_OPEN, 0, (DWORD)lpWaveDesc, CALLBACK_NULL);
 	if (dwRet != MMSYSERR_NOERROR) {
 		printf("sndPlaySound // can't open WaveOut device !\n");
 		goto ErrSND;
 		}
-	WaveHdr.lpData = (LPSTR) malloc(64000);
-	WaveHdr.dwBufferLength = 32000;
-	WaveHdr.dwUser = 0L;
-	WaveHdr.dwFlags = 0L;
-	WaveHdr.dwLoops = 0L;
-	dwRet = wodMessage(0, WODM_PREPARE, 0, (DWORD)&WaveHdr, sizeof(WAVEHDR));
+	USER_HEAP_FREE(hFormat);
+	hWaveHdr = USER_HEAP_ALLOC(sizeof(WAVEHDR));
+	lpWaveHdr = (LPWAVEHDR) USER_HEAP_LIN_ADDR(hWaveHdr);
+	lp16WaveHdr = (LPWAVEHDR) USER_HEAP_SEG_ADDR(hWaveHdr);
+	bufsize = 64000;
+	hData = GlobalAlloc(GMEM_MOVEABLE, bufsize);
+	lpWaveHdr->lpData = (LPSTR) WIN16_GlobalLock(hData);
+	lpWaveHdr->dwBufferLength = bufsize;
+	lpWaveHdr->dwUser = 0L;
+	lpWaveHdr->dwFlags = 0L;
+	lpWaveHdr->dwLoops = 0L;
+	dwRet = wodMessage(0, WODM_PREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
 	if (dwRet != MMSYSERR_NOERROR) {
 		printf("sndPlaySound // can't prepare WaveOut device !\n");
-		free(WaveHdr.lpData);
+		GlobalUnlock(hData);
+		GlobalFree(hData);
+		USER_HEAP_FREE(hDesc);
+		USER_HEAP_FREE(hWaveHdr);
 		goto ErrSND;
 		}
 	while(TRUE) {
-		count = mmioRead(hmmio, WaveHdr.lpData, WaveHdr.dwBufferLength);
+		count = mmioRead(hmmio, PTR_SEG_TO_LIN(lpWaveHdr->lpData), bufsize);
 		if (count < 1) break;
-		WaveHdr.dwBytesRecorded = count;
-		wodMessage(0, WODM_WRITE, 0, (DWORD)&WaveHdr, sizeof(WAVEHDR));
+		lpWaveHdr->dwBufferLength = count;
+/*		lpWaveHdr->dwBytesRecorded = count; */
+		wodMessage(0, WODM_WRITE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
 		}
-	wodMessage(0, WODM_UNPREPARE, 0, (DWORD)&WaveHdr, sizeof(WAVEHDR));
+	wodMessage(0, WODM_UNPREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
 	wodMessage(0, WODM_CLOSE, 0, 0L, 0L);
-	free(WaveHdr.lpData);
+	GlobalUnlock(hData);
+	GlobalFree(hData);
+	USER_HEAP_FREE(hDesc);
+	USER_HEAP_FREE(hWaveHdr);
 	if (hmmio != 0)   mmioClose(hmmio, 0);
 	return TRUE;
 }
@@ -596,7 +627,7 @@
 msg# 543 : tmsf
 */
 		default:
-			msgptr = "Unkown MCI Error !\n";
+			msgptr = "Unknown MCI Error !\n";
 			break;
 		}
 	maxbuf = min(uLength - 1, strlen(msgptr));
@@ -613,6 +644,7 @@
 {
 	printf("mciDriverNotify(%04X, %u, %04X)\n", hWndCallBack, wDevID, wStatus);
 	if (!IsWindow(hWndCallBack)) return FALSE;
+	printf("mciDriverNotify // before PostMessage\n");
 	PostMessage(hWndCallBack, MM_MCINOTIFY, wStatus, 
 			MAKELONG(mciDrv[wDevID].wDeviceID, 0));
 	return TRUE;
@@ -621,75 +653,87 @@
 /**************************************************************************
 * 				mciOpen					[internal]
 */
-DWORD mciOpen(DWORD dwParam, LPMCI_OPEN_PARMS lpParms)
+DWORD mciOpen(DWORD dwParam, LPMCI_OPEN_PARMS lp16Parms)
 {
 	char	str[128];
-	DWORD	dwDevTyp = 0;
-	UINT	wDevID = 1;
-	printf("mciOpen(%08lX, %p)\n", dwParam, lpParms);
-	if (lpParms == NULL) return MCIERR_INTERNAL;
+	LPMCI_OPEN_PARMS lpParms;
+	UINT	uDevTyp = 0;
+	UINT	wDevID = 0;
+	lpParms = PTR_SEG_TO_LIN(lp16Parms);
+	printf("mciOpen(%08lX, %p (%p))\n", dwParam, lp16Parms, lpParms);
+	if (lp16Parms == NULL) return MCIERR_INTERNAL;
 	while(mciDrv[wDevID].wType != 0) {
 		if (++wDevID >= MAXMCIDRIVERS) {
 			printf("MCI_OPEN // MAXMCIDRIVERS reached !\n");
 			return MCIERR_INTERNAL;
 			}
 		}
+	printf("mciOpen // wDevID=%d \n", wDevID);
+	if (dwParam & MCI_OPEN_ALIAS) {
+		printf("MCI_OPEN // Alias='%s' !\n",
+			(char*)PTR_SEG_TO_LIN(lpParms->lpstrAlias));
+		uDevTyp = MCI_DEVTYPE_WAVEFORM_AUDIO;
+ 		}
 	if (dwParam & MCI_OPEN_TYPE) {
-		if (lpParms->lpstrDeviceType == NULL) return MCIERR_INTERNAL;
 		if (dwParam & MCI_OPEN_TYPE_ID) {
 			printf("MCI_OPEN // Dev=%p !\n", lpParms->lpstrDeviceType);
-			dwDevTyp = (DWORD)lpParms->lpstrDeviceType;
+			uDevTyp = LOWORD((DWORD)lpParms->lpstrDeviceType);
 			}
 		else {
+			if (lpParms->lpstrDeviceType == NULL) return MCIERR_INTERNAL;
 			printf("MCI_OPEN // Dev='%s' !\n",
                               (char*)PTR_SEG_TO_LIN(lpParms->lpstrDeviceType));
 			strcpy(str, PTR_SEG_TO_LIN(lpParms->lpstrDeviceType));
 			AnsiUpper(str);
 			if (strcmp(str, "CDAUDIO") == 0) {
-				dwDevTyp = MCI_DEVTYPE_CD_AUDIO;
+				uDevTyp = MCI_DEVTYPE_CD_AUDIO;
 				}
 			else
 			if (strcmp(str, "WAVEAUDIO") == 0) {
-				dwDevTyp = MCI_DEVTYPE_WAVEFORM_AUDIO;
+				uDevTyp = MCI_DEVTYPE_WAVEFORM_AUDIO;
 				}
 			else
 			if (strcmp(str, "SEQUENCER") == 0)	{
-				dwDevTyp = MCI_DEVTYPE_SEQUENCER;
+				uDevTyp = MCI_DEVTYPE_SEQUENCER;
 				}
 			else
 			if (strcmp(str, "ANIMATION1") == 0) {
-				dwDevTyp = MCI_DEVTYPE_ANIMATION;
+				uDevTyp = MCI_DEVTYPE_ANIMATION;
+				}
+			else
+			if (strcmp(str, "AVIVIDEO") == 0) {
+				uDevTyp = MCI_DEVTYPE_DIGITAL_VIDEO;
 				}
 			}
-		mciDrv[wDevID].wType = dwDevTyp;
-		mciDrv[wDevID].wDeviceID = 1;
-		lpParms->wDeviceID = wDevID;
-		printf("MCI_OPEN // wDeviceID=%04X !\n", lpParms->wDeviceID);
-		switch(dwDevTyp) {
-			case MCI_DEVTYPE_CD_AUDIO:
+		}
+	mciDrv[wDevID].wType = uDevTyp;
+	mciDrv[wDevID].wDeviceID = wDevID;
+	lpParms->wDeviceID = wDevID;
+	printf("MCI_OPEN // mcidev=%d, uDevTyp=%04X wDeviceID=%04X !\n", 
+				wDevID, uDevTyp, lpParms->wDeviceID);
+	switch(uDevTyp) {
+		case MCI_DEVTYPE_CD_AUDIO:
 #ifdef WINELIB
-		    WINELIB_UNIMP ("CDAUDIO_DriverProc");
+			WINELIB_UNIMP ("CDAUDIO_DriverProc");
 #else
-				return CDAUDIO_DriverProc(0, 0, MCI_OPEN_DRIVER,
-
-									dwParam, (DWORD)lpParms);
+			return CDAUDIO_DriverProc(0, 0, MCI_OPEN_DRIVER,
+							dwParam, (DWORD)lp16Parms);
 #endif
 		case MCI_DEVTYPE_WAVEFORM_AUDIO:
-				return WAVE_DriverProc(0, 0, MCI_OPEN_DRIVER, 
-									dwParam, (DWORD)lpParms);
-			case MCI_DEVTYPE_SEQUENCER:
-				return MIDI_DriverProc(0, 0, MCI_OPEN_DRIVER, 
-									dwParam, (DWORD)lpParms);
-			case MCI_DEVTYPE_ANIMATION:
-				return ANIM_DriverProc(0, 0, MCI_OPEN_DRIVER, 
-									dwParam, (DWORD)lpParms);
-			case MCI_DEVTYPE_DIGITAL_VIDEO:
-				printf("MCI_OPEN // No DIGITAL_VIDEO yet !\n");
-				return MCIERR_DEVICE_NOT_INSTALLED;
-			default:
-				printf("MCI_OPEN // Invalid Device Name '%p' !\n", lpParms->lpstrDeviceType);
-				return MCIERR_INVALID_DEVICE_NAME;
-			}
+			return WAVE_DriverProc(0, 0, MCI_OPEN_DRIVER, 
+								dwParam, (DWORD)lp16Parms);
+		case MCI_DEVTYPE_SEQUENCER:
+			return MIDI_DriverProc(0, 0, MCI_OPEN_DRIVER, 
+								dwParam, (DWORD)lp16Parms);
+		case MCI_DEVTYPE_ANIMATION:
+			return ANIM_DriverProc(0, 0, MCI_OPEN_DRIVER, 
+								dwParam, (DWORD)lp16Parms);
+		case MCI_DEVTYPE_DIGITAL_VIDEO:
+			printf("MCI_OPEN // No DIGITAL_VIDEO yet !\n");
+			return MCIERR_DEVICE_NOT_INSTALLED;
+		default:
+			printf("MCI_OPEN // Invalid Device Name '%p' !\n", lpParms->lpstrDeviceType);
+			return MCIERR_INVALID_DEVICE_NAME;
 		}
 	return MCIERR_INTERNAL;
 }
@@ -722,7 +766,7 @@
 						MCI_CLOSE, dwParam, (DWORD)lpParms);
 			break;
 		default:
-			printf("mciClose() // unknown type=%04X !\n", mciDrv[wDevID].wType);
+			printf("mciClose() // unknown device type=%04X !\n", mciDrv[wDevID].wType);
 		}
 	mciDrv[wDevID].wType = 0;
 	return dwRet;
@@ -732,6 +776,56 @@
 /**************************************************************************
 * 				mciSound				[internal]
 */
+DWORD mciSysInfo(DWORD dwFlags, LPMCI_SYSINFO_PARMS lpParms)
+{
+	int	len;
+	LPSTR	ptr;
+	LPSTR	lpstrReturn;
+	DWORD	*lpdwRet;
+	LPSTR	SysFile = "SYSTEM.INI";
+	dprintf_mci(stddeb, "mciSysInfo(%08lX, %08lX)\n", dwFlags, (DWORD)lpParms);
+	lpstrReturn = PTR_SEG_TO_LIN(lpParms->lpstrReturn);
+	switch(dwFlags) {
+		case MCI_SYSINFO_QUANTITY:
+			dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_QUANTITY \n");
+			lpdwRet = (DWORD *)lpstrReturn;
+			*(lpdwRet) = InstalledCount;		
+			return 0;
+		case MCI_SYSINFO_INSTALLNAME:
+			dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_INSTALLNAME \n");
+			if (lpInstallNames == NULL) {
+				InstalledCount = 0;
+				InstalledListLen = 0;
+				ptr = lpInstallNames = malloc(2048);
+				GetPrivateProfileString("mci", NULL, "", lpInstallNames, 2000, SysFile);
+				while(strlen(ptr) > 0) {
+					printf("---> '%s' \n", ptr);
+					len = strlen(ptr) + 1;
+					ptr += len;
+					InstalledListLen += len;
+					InstalledCount++;
+					}
+				}
+			if (lpParms->dwRetSize < InstalledListLen) {
+				strncpy(lpstrReturn, lpInstallNames, lpParms->dwRetSize - 2);
+				lpstrReturn[lpParms->dwRetSize - 1] = '\0';
+				}
+			else
+				strcpy(lpstrReturn, lpInstallNames);
+			return 0;
+		case MCI_SYSINFO_NAME:
+			dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_NAME \n");
+			return 0;
+		case MCI_SYSINFO_OPEN:
+			dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_OPEN \n");
+			return 0;
+		}
+	return MMSYSERR_INVALPARAM;
+}
+
+/**************************************************************************
+* 				mciSound				[internal]
+*/
 DWORD mciSound(UINT wDevID, DWORD dwParam, LPMCI_SOUND_PARMS lpParms)
 {
 	if (lpParms == NULL) return MCIERR_INTERNAL;
@@ -752,9 +846,11 @@
 					wDevID, wMsg, dwParam1, dwParam2);
 	switch(wMsg) {
 		case MCI_OPEN:
-			return mciOpen(dwParam1, (LPMCI_OPEN_PARMS)PTR_SEG_TO_LIN(dwParam2));
+			return mciOpen(dwParam1, (LPMCI_OPEN_PARMS)dwParam2);
 		case MCI_CLOSE:
 			return mciClose(wDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
+		case MCI_SYSINFO:
+			return mciSysInfo(dwParam1, (LPMCI_SYSINFO_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		default:
 			switch(mciDrv[wDevID].wType) {
 				case MCI_DEVTYPE_CD_AUDIO:
@@ -773,7 +869,7 @@
 					return ANIM_DriverProc(mciDrv[wDevID].wDeviceID, hDrv, 
 											wMsg, dwParam1, dwParam2);
 				default:
-					printf("mciSendCommand() // unknown type=%04X !\n", 
+					printf("mciSendCommand() // unknown device type=%04X !\n", 
 											mciDrv[wDevID].wType);
 				}
 		}
@@ -911,7 +1007,7 @@
 msg# 343 : There are no MIDI devices installed on the system. Use the Drivers option in Control Panel to install the driver.
 */
 		default:
-			msgptr = "Unkown MIDI Error !\n";
+			msgptr = "Unknown MIDI Error !\n";
 			break;
 		}
 	maxbuf = min(uSize - 1, strlen(msgptr));
@@ -928,6 +1024,7 @@
 {
 	HMIDI	hMidiOut;
 	LPMIDIOPENDESC	lpDesc;
+	LPMIDIOPENDESC	lp16Desc;
 	DWORD	dwRet = 0;
 	BOOL	bMapperFlg = FALSE;
 	if (lphMidiOut != NULL) *lphMidiOut = 0;
@@ -938,16 +1035,17 @@
 		bMapperFlg = TRUE;
 		uDeviceID = 0;
 		}
-	hMidiOut = GlobalAlloc(GMEM_MOVEABLE, sizeof(MIDIOPENDESC));
+	hMidiOut = USER_HEAP_ALLOC(sizeof(MIDIOPENDESC));
 	if (lphMidiOut != NULL) *lphMidiOut = hMidiOut;
-	lpDesc = (LPMIDIOPENDESC) GlobalLock(hMidiOut);
+	lp16Desc = (LPMIDIOPENDESC) USER_HEAP_SEG_ADDR(hMidiOut);
+	lpDesc = (LPMIDIOPENDESC) PTR_SEG_TO_LIN(lp16Desc);
 	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);
+			lpDesc->dwInstance, (DWORD)lp16Desc, 0L);
 		if (dwRet == MMSYSERR_NOERROR) break;
 		if (!bMapperFlg) break;
 		uDeviceID++;
@@ -963,7 +1061,7 @@
 {
 	LPMIDIOPENDESC	lpDesc;
 	printf("midiOutClose(%04X)\n", hMidiOut);
-	lpDesc = (LPMIDIOPENDESC) GlobalLock(hMidiOut);
+	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return modMessage(0, MODM_CLOSE, lpDesc->dwInstance, 0L, 0L);
 }
@@ -977,7 +1075,7 @@
 	LPMIDIOPENDESC	lpDesc;
 	printf("midiOutPrepareHeader(%04X, %p, %d)\n", 
 					hMidiOut, lpMidiOutHdr, uSize);
-	lpDesc = (LPMIDIOPENDESC) GlobalLock(hMidiOut);
+	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return modMessage(0, MODM_PREPARE, lpDesc->dwInstance, 
 						(DWORD)lpMidiOutHdr, (DWORD)uSize);
@@ -992,7 +1090,7 @@
 	LPMIDIOPENDESC	lpDesc;
 	printf("midiOutUnprepareHeader(%04X, %p, %d)\n", 
 					hMidiOut, lpMidiOutHdr, uSize);
-	lpDesc = (LPMIDIOPENDESC) GlobalLock(hMidiOut);
+	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return modMessage(0, MODM_UNPREPARE, lpDesc->dwInstance, 
 						(DWORD)lpMidiOutHdr, (DWORD)uSize);
@@ -1005,7 +1103,7 @@
 {
 	LPMIDIOPENDESC	lpDesc;
 	printf("midiOutShortMsg(%04X, %08lX)\n", hMidiOut, dwMsg);
-	lpDesc = (LPMIDIOPENDESC) GlobalLock(hMidiOut);
+	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return modMessage(0, MODM_DATA, lpDesc->dwInstance, dwMsg, 0L);
 }
@@ -1019,7 +1117,7 @@
 	LPMIDIOPENDESC	lpDesc;
 	printf("midiOutLongMsg(%04X, %p, %d)\n", 
 				hMidiOut, lpMidiOutHdr, uSize);
-	lpDesc = (LPMIDIOPENDESC) GlobalLock(hMidiOut);
+	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return modMessage(0, MODM_LONGDATA, lpDesc->dwInstance, 
 						(DWORD)lpMidiOutHdr, (DWORD)uSize);
@@ -1030,8 +1128,11 @@
 */
 UINT WINAPI midiOutReset(HMIDIOUT hMidiOut)
 {
-	printf("midiOutReset\n");
-	return 0;
+	LPMIDIOPENDESC	lpDesc;
+	printf("midiOutReset(%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);
 }
 
 /**************************************************************************
@@ -1039,7 +1140,8 @@
 */
 UINT WINAPI midiOutGetVolume(UINT uDeviceID, DWORD FAR* lpdwVolume)
 {
-	printf("midiOutGetVolume\n");
+	printf("midiOutGetVolume(%04X, %p);\n", uDeviceID, lpdwVolume);
+	return modMessage(uDeviceID, MODM_GETVOLUME, 0L, (DWORD)lpdwVolume, 0L);
 	return 0;
 }
 
@@ -1048,7 +1150,8 @@
 */
 UINT WINAPI midiOutSetVolume(UINT uDeviceID, DWORD dwVolume)
 {
-	printf("midiOutSetVolume\n");
+	printf("midiOutSetVolume(%04X, %08lX);\n", uDeviceID, dwVolume);
+	return modMessage(uDeviceID, MODM_SETVOLUME, 0L, dwVolume, 0L);
 	return 0;
 }
 
@@ -1090,7 +1193,7 @@
 	LPMIDIOPENDESC	lpDesc;
 	printf("midiOutMessage(%04X, %04X, %08lX, %08lX)\n", 
 			hMidiOut, uMessage, dwParam1, dwParam2);
-	lpDesc = (LPMIDIOPENDESC) GlobalLock(hMidiOut);
+	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return modMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
 	return 0;
@@ -1101,8 +1204,11 @@
 */
 UINT WINAPI midiInGetNumDevs(void)
 {
+	UINT	count = 0;
 	printf("midiInGetNumDevs\n");
-	return 0;
+	count += midMessage(0, MIDM_GETNUMDEVS, 0L, 0L, 0L);
+	printf("midiInGetNumDevs return %u \n", count);
+	return count;
 }
 
 /**************************************************************************
@@ -1132,6 +1238,7 @@
 {
 	HMIDI	hMidiIn;
 	LPMIDIOPENDESC	lpDesc;
+	LPMIDIOPENDESC	lp16Desc;
 	DWORD	dwRet = 0;
 	BOOL	bMapperFlg = FALSE;
 	if (lphMidiIn != NULL) *lphMidiIn = 0;
@@ -1142,9 +1249,10 @@
 		bMapperFlg = TRUE;
 		uDeviceID = 0;
 		}
-	hMidiIn = GlobalAlloc(GMEM_MOVEABLE, sizeof(MIDIOPENDESC));
+	hMidiIn = USER_HEAP_ALLOC(sizeof(MIDIOPENDESC));
 	if (lphMidiIn != NULL) *lphMidiIn = hMidiIn;
-	lpDesc = (LPMIDIOPENDESC) GlobalLock(hMidiIn);
+	lp16Desc = (LPMIDIOPENDESC) USER_HEAP_SEG_ADDR(hMidiIn);
+	lpDesc = (LPMIDIOPENDESC) PTR_SEG_TO_LIN(lp16Desc);
 	if (lpDesc == NULL) return MMSYSERR_NOMEM;
 	lpDesc->hMidi = hMidiIn;
 	lpDesc->dwCallback = dwCallback;
@@ -1167,7 +1275,7 @@
 {
 	LPMIDIOPENDESC	lpDesc;
 	printf("midiInClose(%04X)\n", hMidiIn);
-	lpDesc = (LPMIDIOPENDESC) GlobalLock(hMidiIn);
+	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return midMessage(0, MIDM_CLOSE, lpDesc->dwInstance, 0L, 0L);
 }
@@ -1181,7 +1289,7 @@
 	LPMIDIOPENDESC	lpDesc;
 	printf("midiInPrepareHeader(%04X, %p, %d)\n", 
 					hMidiIn, lpMidiInHdr, uSize);
-	lpDesc = (LPMIDIOPENDESC) GlobalLock(hMidiIn);
+	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return midMessage(0, MIDM_PREPARE, lpDesc->dwInstance, 
 						(DWORD)lpMidiInHdr, (DWORD)uSize);
@@ -1196,7 +1304,7 @@
 	LPMIDIOPENDESC	lpDesc;
 	printf("midiInUnprepareHeader(%04X, %p, %d)\n", 
 					hMidiIn, lpMidiInHdr, uSize);
-	lpDesc = (LPMIDIOPENDESC) GlobalLock(hMidiIn);
+	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return midMessage(0, MIDM_UNPREPARE, lpDesc->dwInstance, 
 						(DWORD)lpMidiInHdr, (DWORD)uSize);
@@ -1257,7 +1365,7 @@
 	LPMIDIOPENDESC	lpDesc;
 	printf("midiInMessage(%04X, %04X, %08lX, %08lX)\n", 
 			hMidiIn, uMessage, dwParam1, dwParam2);
-	lpDesc = (LPMIDIOPENDESC) GlobalLock(hMidiIn);
+	lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return midMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
 }
@@ -1354,7 +1462,7 @@
 			msgptr = "Cannot open the device without using the WAVE_ALLOWSYNC flag. Use the flag, and then try again.";
 			break;
 		default:
-			msgptr = "Unkown MMSYSTEM Error !\n";
+			msgptr = "Unknown MMSYSTEM Error !\n";
 			break;
 		}
 	maxbuf = min(uSize - 1, strlen(msgptr));
@@ -1371,6 +1479,7 @@
 {
 	HWAVE	hWaveOut;
 	LPWAVEOPENDESC	lpDesc;
+	LPWAVEOPENDESC	lp16Desc;
 	DWORD	dwRet = 0;
 	BOOL	bMapperFlg = FALSE;
 	printf("waveOutOpen(%p, %d, %p, %08lX, %08lX, %08lX);\n", 
@@ -1384,9 +1493,10 @@
 		uDeviceID = 0;
 		}
 	if (lpFormat == NULL) return WAVERR_BADFORMAT;
-	hWaveOut = GlobalAlloc(GMEM_MOVEABLE, sizeof(WAVEOPENDESC));
+	hWaveOut = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
 	if (lphWaveOut != NULL) *lphWaveOut = hWaveOut;
-	lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveOut);
+	lp16Desc = (LPWAVEOPENDESC) USER_HEAP_SEG_ADDR(hWaveOut);
+	lpDesc = (LPWAVEOPENDESC) PTR_SEG_TO_LIN(lp16Desc);
 	if (lpDesc == NULL) return MMSYSERR_NOMEM;
 	lpDesc->hWave = hWaveOut;
 	lpDesc->lpFormat = lpFormat;
@@ -1394,7 +1504,7 @@
 	lpDesc->dwInstance = dwInstance;
 	while(uDeviceID < MAXWAVEDRIVERS) {
 		dwRet = wodMessage(uDeviceID, WODM_OPEN, 
-			lpDesc->dwInstance, (DWORD)lpDesc, 0L);
+			lpDesc->dwInstance, (DWORD)lp16Desc, 0L);
 		if (dwRet == MMSYSERR_NOERROR) break;
 		if (!bMapperFlg) break;
 		uDeviceID++;
@@ -1414,7 +1524,7 @@
 {
 	LPWAVEOPENDESC	lpDesc;
 	printf("waveOutClose(%04X)\n", hWaveOut);
-	lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveOut);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return wodMessage(0, WODM_CLOSE, lpDesc->dwInstance, 0L, 0L);
 }
@@ -1428,7 +1538,7 @@
 	LPWAVEOPENDESC	lpDesc;
 	printf("waveOutPrepareHeader(%04X, %p, %u);\n", 
 					hWaveOut, lpWaveOutHdr, uSize);
-	lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveOut);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return wodMessage(0, WODM_PREPARE, lpDesc->dwInstance, 
 							(DWORD)lpWaveOutHdr, uSize);
@@ -1443,9 +1553,9 @@
 	LPWAVEOPENDESC	lpDesc;
 	printf("waveOutUnprepareHeader(%04X, %p, %u);\n", 
 						hWaveOut, lpWaveOutHdr, uSize);
-	lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveOut);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
-	return wodMessage(0, WODM_PREPARE, lpDesc->dwInstance, 
+	return wodMessage(0, WODM_UNPREPARE, lpDesc->dwInstance, 
 							(DWORD)lpWaveOutHdr, uSize);
 }
 
@@ -1456,7 +1566,7 @@
 {
 	LPWAVEOPENDESC	lpDesc;
 	printf("waveOutWrite(%04X, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
-	lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveOut);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return wodMessage(0, WODM_WRITE, lpDesc->dwInstance, 
 							(DWORD)lpWaveOutHdr, uSize);
@@ -1467,8 +1577,11 @@
 */
 UINT WINAPI waveOutPause(HWAVEOUT hWaveOut)
 {
+	LPWAVEOPENDESC	lpDesc;
 	printf("waveOutPause(%04X)\n", hWaveOut);
-	return MMSYSERR_INVALHANDLE;
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	return wodMessage(0, WODM_PAUSE, lpDesc->dwInstance, 0L, 0L);
 }
 
 /**************************************************************************
@@ -1476,8 +1589,11 @@
 */
 UINT WINAPI waveOutRestart(HWAVEOUT hWaveOut)
 {
+	LPWAVEOPENDESC	lpDesc;
 	printf("waveOutRestart(%04X)\n", hWaveOut);
-	return MMSYSERR_INVALHANDLE;
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	return wodMessage(0, WODM_RESTART, lpDesc->dwInstance, 0L, 0L);
 }
 
 /**************************************************************************
@@ -1485,8 +1601,11 @@
 */
 UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
 {
+	LPWAVEOPENDESC	lpDesc;
 	printf("waveOutReset(%04X)\n", hWaveOut);
-	return MMSYSERR_INVALHANDLE;
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	return wodMessage(0, WODM_RESET, lpDesc->dwInstance, 0L, 0L);
 }
 
 /**************************************************************************
@@ -1496,7 +1615,7 @@
 {
 	LPWAVEOPENDESC	lpDesc;
 	printf("waveOutGetPosition(%04X, %p, %u);\n", hWaveOut, lpTime, uSize);
-	lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveOut);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return wodMessage(0, WODM_GETPOS, lpDesc->dwInstance, 
 							(DWORD)lpTime, (DWORD)uSize);
@@ -1507,8 +1626,12 @@
 */
 UINT WINAPI waveOutGetPitch(HWAVEOUT hWaveOut, DWORD FAR* lpdwPitch)
 {
-	printf("waveOutGetPitch\n");
-	return MMSYSERR_INVALHANDLE;
+	LPWAVEOPENDESC	lpDesc;
+	printf("waveOutGetPitch(%04X, %p);\n", hWaveOut, lpdwPitch);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	return wodMessage(0, WODM_GETPITCH, lpDesc->dwInstance, 
+								(DWORD)lpdwPitch, 0L);
 }
 
 /**************************************************************************
@@ -1516,8 +1639,11 @@
 */
 UINT WINAPI waveOutSetPitch(HWAVEOUT hWaveOut, DWORD dwPitch)
 {
-	printf("waveOutSetPitch\n");
-	return MMSYSERR_INVALHANDLE;
+	LPWAVEOPENDESC	lpDesc;
+	printf("waveOutSetPitch(%04X, %08lX);\n", hWaveOut, dwPitch);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	return wodMessage(0, WODM_SETPITCH, lpDesc->dwInstance, (DWORD)dwPitch, 0L);
 }
 
 /**************************************************************************
@@ -1525,8 +1651,8 @@
 */
 UINT WINAPI waveOutGetVolume(UINT uDeviceID, DWORD FAR* lpdwVolume)
 {
-	printf("waveOutGetVolume\n");
-	return MMSYSERR_INVALHANDLE;
+	printf("waveOutGetVolume(%04X, %p);\n", uDeviceID, lpdwVolume);
+	return wodMessage(uDeviceID, WODM_GETVOLUME, 0L, (DWORD)lpdwVolume, 0L);
 }
 
 /**************************************************************************
@@ -1534,8 +1660,8 @@
 */
 UINT WINAPI waveOutSetVolume(UINT uDeviceID, DWORD dwVolume)
 {
-	printf("waveOutSetVolume\n");
-	return MMSYSERR_INVALHANDLE;
+	printf("waveOutSetVolume(%04X, %08lX);\n", uDeviceID, dwVolume);
+	return wodMessage(uDeviceID, WODM_SETVOLUME, 0L, dwVolume, 0L);
 }
 
 /**************************************************************************
@@ -1543,8 +1669,12 @@
 */
 UINT WINAPI waveOutGetPlaybackRate(HWAVEOUT hWaveOut, DWORD FAR* lpdwRate)
 {
-	printf("waveOutGetPlaybackRate\n");
-	return MMSYSERR_INVALHANDLE;
+	LPWAVEOPENDESC	lpDesc;
+	printf("waveOutGetPlaybackRate(%04X, %p);\n", hWaveOut, lpdwRate);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	return wodMessage(0, WODM_GETPLAYBACKRATE, lpDesc->dwInstance, 
+								(DWORD)lpdwRate, 0L);
 }
 
 /**************************************************************************
@@ -1552,8 +1682,12 @@
 */
 UINT WINAPI waveOutSetPlaybackRate(HWAVEOUT hWaveOut, DWORD dwRate)
 {
-	printf("waveOutSetPlaybackRate\n");
-	return MMSYSERR_INVALHANDLE;
+	LPWAVEOPENDESC	lpDesc;
+	printf("waveOutSetPlaybackRate(%04X, %08lX);\n", hWaveOut, dwRate);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
+	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+	return wodMessage(0, WODM_SETPLAYBACKRATE, 
+		lpDesc->dwInstance, (DWORD)dwRate, 0L);
 }
 
 /**************************************************************************
@@ -1570,8 +1704,15 @@
 */
 UINT WINAPI waveOutGetID(HWAVEOUT hWaveOut, UINT FAR* lpuDeviceID)
 {
-	printf("waveOutGetID\n");
-	return MMSYSERR_INVALHANDLE;
+	LPWAVEOPENDESC	lpDesc;
+	printf("waveOutGetID(%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 = lpParms->wDeviceID; 
+*/
+	return 0;
 }
 
 /**************************************************************************
@@ -1583,7 +1724,7 @@
 	LPWAVEOPENDESC	lpDesc;
 	printf("waveOutMessage(%04X, %04X, %08lX, %08lX)\n", 
 			hWaveOut, uMessage, dwParam1, dwParam2);
-	lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveOut);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return wodMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
 }
@@ -1629,6 +1770,7 @@
 {
 	HWAVE	hWaveIn;
 	LPWAVEOPENDESC	lpDesc;
+	LPWAVEOPENDESC	lp16Desc;
 	DWORD	dwRet = 0;
 	BOOL	bMapperFlg = FALSE;
 	printf("waveInOpen(%p, %d, %p, %08lX, %08lX, %08lX);\n", 
@@ -1642,9 +1784,10 @@
 		uDeviceID = 0;
 		}
 	if (lpFormat == NULL) return WAVERR_BADFORMAT;
-	hWaveIn = GlobalAlloc(GMEM_MOVEABLE, sizeof(WAVEOPENDESC));
+	hWaveIn = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
 	if (lphWaveIn != NULL) *lphWaveIn = hWaveIn;
-	lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveIn);
+	lp16Desc = (LPWAVEOPENDESC) USER_HEAP_SEG_ADDR(hWaveIn);
+	lpDesc = (LPWAVEOPENDESC) PTR_SEG_TO_LIN(lp16Desc);
 	if (lpDesc == NULL) return MMSYSERR_NOMEM;
 	lpDesc->hWave = hWaveIn;
 	lpDesc->lpFormat = lpFormat;
@@ -1652,7 +1795,7 @@
 	lpDesc->dwInstance = dwInstance;
 	while(uDeviceID < MAXWAVEDRIVERS) {
 		dwRet = widMessage(uDeviceID, WIDM_OPEN, 
-			lpDesc->dwInstance, (DWORD)lpDesc, 0L);
+			lpDesc->dwInstance, (DWORD)lp16Desc, 0L);
 		if (dwRet == MMSYSERR_NOERROR) break;
 		if (!bMapperFlg) break;
 		uDeviceID++;
@@ -1673,7 +1816,7 @@
 {
 	LPWAVEOPENDESC	lpDesc;
 	printf("waveInClose(%04X)\n", hWaveIn);
-	lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveIn);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return widMessage(0, WIDM_CLOSE, lpDesc->dwInstance, 0L, 0L);
 }
@@ -1686,15 +1829,17 @@
     WAVEHDR FAR* lpWaveInHdr, UINT uSize)
 {
 	LPWAVEOPENDESC	lpDesc;
+	LPWAVEHDR 		lp32WaveInHdr;
 	printf("waveInPrepareHeader(%04X, %p, %u);\n", 
 					hWaveIn, lpWaveInHdr, uSize);
-	lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveIn);
+	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;
+	lp32WaveInHdr = PTR_SEG_TO_LIN(lpWaveInHdr);
+	lp32WaveInHdr->lpNext = NULL;
+    lp32WaveInHdr->dwBytesRecorded = 0;
 	printf("waveInPrepareHeader // lpData=%p size=%lu \n", 
-		lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
+		lp32WaveInHdr->lpData, lp32WaveInHdr->dwBufferLength);
 	return widMessage(0, WIDM_PREPARE, lpDesc->dwInstance, 
 							(DWORD)lpWaveInHdr, uSize);
 }
@@ -1707,15 +1852,17 @@
     WAVEHDR FAR* lpWaveInHdr, UINT uSize)
 {
 	LPWAVEOPENDESC	lpDesc;
+	LPWAVEHDR 		lp32WaveInHdr;
 	printf("waveInUnprepareHeader(%04X, %p, %u);\n", 
 						hWaveIn, lpWaveInHdr, uSize);
-	lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveIn);
+	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));
-	lpWaveInHdr->lpData = NULL;
-	lpWaveInHdr->lpNext = NULL;
-	return widMessage(0, WIDM_PREPARE, lpDesc->dwInstance, 
+	lp32WaveInHdr = PTR_SEG_TO_LIN(lpWaveInHdr);
+	USER_HEAP_FREE(HIWORD((DWORD)lp32WaveInHdr->lpData));
+	lp32WaveInHdr->lpData = NULL;
+	lp32WaveInHdr->lpNext = NULL;
+	return widMessage(0, WIDM_UNPREPARE, lpDesc->dwInstance, 
 							(DWORD)lpWaveInHdr, uSize);
 }
 
@@ -1727,14 +1874,16 @@
     WAVEHDR FAR* lpWaveInHdr, UINT uSize)
 {
 	LPWAVEOPENDESC	lpDesc;
+	LPWAVEHDR 		lp32WaveInHdr;
 	printf("waveInAddBuffer(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
-	lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveIn);
+	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;
+	lp32WaveInHdr = PTR_SEG_TO_LIN(lpWaveInHdr);
+	lp32WaveInHdr->lpNext = NULL;
+    lp32WaveInHdr->dwBytesRecorded = 0;
 	printf("waveInAddBuffer // lpData=%p size=%lu \n", 
-		lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
+		lp32WaveInHdr->lpData, lp32WaveInHdr->dwBufferLength);
 	return widMessage(0, WIDM_ADDBUFFER, lpDesc->dwInstance,
 								(DWORD)lpWaveInHdr, uSize);
 }
@@ -1747,7 +1896,7 @@
 {
 	LPWAVEOPENDESC	lpDesc;
 	printf("waveInStart(%04X)\n", hWaveIn);
-	lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveIn);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return widMessage(0, WIDM_START, lpDesc->dwInstance, 0L, 0L);
 }
@@ -1760,7 +1909,7 @@
 {
 	LPWAVEOPENDESC	lpDesc;
 	printf("waveInStop(%04X)\n", hWaveIn);
-	lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveIn);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return widMessage(0, WIDM_STOP, lpDesc->dwInstance, 0L, 0L);
 }
@@ -1773,7 +1922,7 @@
 {
 	LPWAVEOPENDESC	lpDesc;
 	printf("waveInReset(%04X)\n", hWaveIn);
-	lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveIn);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return widMessage(0, WIDM_RESET, lpDesc->dwInstance, 0L, 0L);
 }
@@ -1786,7 +1935,7 @@
 {
 	LPWAVEOPENDESC	lpDesc;
 	printf("waveInGetPosition(%04X, %p, %u);\n", hWaveIn, lpTime, uSize);
-	lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveIn);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return widMessage(0, WIDM_GETPOS, lpDesc->dwInstance,
 							(DWORD)lpTime, (DWORD)uSize);
@@ -1813,7 +1962,7 @@
 	LPWAVEOPENDESC	lpDesc;
 	printf("waveInMessage(%04X, %04X, %08lX, %08lX)\n", 
 			hWaveIn, uMessage, dwParam1, dwParam2);
-	lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveIn);
+	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	return widMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
 }
@@ -1831,7 +1980,7 @@
 		lpTimer->wCurTime--;
 		if (lpTimer->wCurTime == 0) {
 			lpTimer->wCurTime = lpTimer->wDelay;
-			if (lpTimer->lpFunc != NULL) {
+			if (lpTimer->lpFunc != (FARPROC)NULL) {
 				dprintf_mmtime(stddeb,"MMSysTimeCallback // before CallBack16 !\n");
                                 CallTimeFuncProc( lpTimer->lpFunc,
                                                   lpTimer->wTimerID, 0,
@@ -1979,7 +2128,7 @@
 HMMIO WINAPI mmioOpen(LPSTR szFileName, MMIOINFO FAR* lpmmioinfo, DWORD dwOpenFlags)
 {
 	int		hFile;
-	HANDLE	hmmio;
+	HANDLE		hmmio;
 	OFSTRUCT	ofs;
 	LPMMIOINFO	lpmminfo;
 	printf("mmioOpen('%s', %p, %08lX);\n", szFileName, lpmmioinfo, dwOpenFlags);
@@ -1992,6 +2141,7 @@
 	lpmminfo->hmmio = hmmio;
 	lpmminfo->dwReserved2 = MAKELONG(hFile, 0);
 	GlobalUnlock(hmmio);
+	printf("mmioOpen // return hmmio=%04X\n", hmmio);
 	return (HMMIO)hmmio;
 }
 
@@ -2019,13 +2169,14 @@
 */
 LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
 {
-	int		count;
+	LONG		count;
 	LPMMIOINFO	lpmminfo;
 	dprintf_mmio(stddeb, "mmioRead(%04X, %p, %ld);\n", hmmio, pch, cch);
 	lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
 	if (lpmminfo == NULL) return 0;
-	count = _lread(LOWORD(lpmminfo->dwReserved2), pch, cch);
+	count = read(LOWORD(lpmminfo->dwReserved2), pch, cch);
 	GlobalUnlock(hmmio);
+	dprintf_mmio(stddeb, "mmioRead // count=%ld\n", count);
 	return count;
 }
 
@@ -2036,7 +2187,7 @@
 */
 LONG WINAPI mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch)
 {
-	int		count;
+	LONG		count;
 	LPMMIOINFO	lpmminfo;
 	printf("mmioWrite(%04X, %p, %ld);\n", hmmio, pch, cch);
 	lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
@@ -2097,7 +2248,7 @@
 UINT WINAPI mmioSetBuffer(HMMIO hmmio, LPSTR pchBuffer, 
 						LONG cchBuffer, UINT uFlags)
 {
-	printf("mmioSetBuffer\n");
+	printf("mmioSetBuffer // empty stub \n");
 	return 0;
 }
 
@@ -2125,7 +2276,7 @@
 	lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
 	if (lpmminfo == NULL) return 0;
 	if (uFlags == MMIO_READ) {
-		count = _lread(LOWORD(lpmminfo->dwReserved2), 
+		count = read(LOWORD(lpmminfo->dwReserved2), 
 			lpmmioinfo->pchBuffer, lpmmioinfo->cchBuffer);
 		}
 	if (uFlags == MMIO_WRITE) {
@@ -2143,7 +2294,7 @@
 */
 FOURCC WINAPI mmioStringToFOURCC(LPCSTR sz, UINT uFlags)
 {
-	printf("mmioStringToFOURCC\n");
+	printf("mmioStringToFOURCC // empty stub \n");
 	return 0;
 }
 
@@ -2153,7 +2304,7 @@
 LPMMIOPROC WINAPI mmioInstallIOProc(FOURCC fccIOProc, 
 				LPMMIOPROC pIOProc, DWORD dwFlags)
 {
-	printf("mmioInstallIOProc\n");
+	printf("mmioInstallIOProc // empty stub \n");
 	return 0;
 }
 
@@ -2163,7 +2314,7 @@
 LRESULT WINAPI mmioSendMessage(HMMIO hmmio, UINT uMessage,
 					    LPARAM lParam1, LPARAM lParam2)
 {
-	printf("mmioSendMessage\n");
+	printf("mmioSendMessage // empty stub \n");
 	return 0;
 }
 
@@ -2181,7 +2332,9 @@
 	lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
 	if (lpmminfo == NULL) return 0;
 	dwfcc = lpck->ckid;
+	dprintf_mmio(stddeb, "mmioDescend // dwfcc=%08lX\n", dwfcc);
 	dwOldPos = _llseek(LOWORD(lpmminfo->dwReserved2), 0, SEEK_CUR);
+	dprintf_mmio(stddeb, "mmioDescend // dwOldPos=%ld\n", dwOldPos);
 	if (lpckParent != NULL) {
 		dprintf_mmio(stddeb, "mmioDescend // seek inside parent at %ld !\n", lpckParent->dwDataOffset);
 		dwOldPos = _llseek(LOWORD(lpmminfo->dwReserved2), 
@@ -2191,7 +2344,7 @@
 		(uFlags & MMIO_FINDLIST)) {
 		dprintf_mmio(stddeb, "mmioDescend // MMIO_FINDxxxx dwfcc=%08lX !\n", dwfcc);
 		while (TRUE) {
-			if (_lread(LOWORD(lpmminfo->dwReserved2), (LPSTR)lpck, 
+			if (read(LOWORD(lpmminfo->dwReserved2), (LPSTR)lpck, 
 					sizeof(MMCKINFO)) < sizeof(MMCKINFO)) {
 				_llseek(LOWORD(lpmminfo->dwReserved2), dwOldPos, SEEK_SET);
 				GlobalUnlock(hmmio);
@@ -2207,19 +2360,19 @@
 			}
 		}
 	else {
-		if (_lread(LOWORD(lpmminfo->dwReserved2), (LPSTR)lpck, 
+		if (read(LOWORD(lpmminfo->dwReserved2), (LPSTR)lpck, 
 				sizeof(MMCKINFO)) < sizeof(MMCKINFO)) {
 			_llseek(LOWORD(lpmminfo->dwReserved2), dwOldPos, SEEK_SET);
 			GlobalUnlock(hmmio);
 			return MMIOERR_CHUNKNOTFOUND;
 			}
 		}
-	GlobalUnlock(hmmio);
 	lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
 	if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) 
 		lpck->dwDataOffset += sizeof(DWORD);
 	lpmminfo->lDiskOffset = _llseek(LOWORD(lpmminfo->dwReserved2), 
 									lpck->dwDataOffset, SEEK_SET);
+	GlobalUnlock(hmmio);
 	dprintf_mmio(stddeb, "mmioDescend // lpck->ckid=%08lX lpck->cksize=%ld !\n", 
 								lpck->ckid, lpck->cksize);
 	printf("mmioDescend // lpck->fccType=%08lX !\n", lpck->fccType);
@@ -2231,7 +2384,7 @@
 */
 UINT WINAPI mmioAscend(HMMIO hmmio, MMCKINFO FAR* lpck, UINT uFlags)
 {
-	printf("mmioAscend\n");
+	printf("mmioAscend // empty stub !\n");
 	return 0;
 }
 
@@ -2240,7 +2393,7 @@
 */
 UINT WINAPI mmioCreateChunk(HMMIO hmmio, MMCKINFO FAR* lpck, UINT uFlags)
 {
-	printf("mmioCreateChunk\n");
+	printf("mmioCreateChunk // empty stub \n");
 	return 0;
 }
 
@@ -2251,7 +2404,7 @@
 UINT WINAPI mmioRename(LPCSTR szFileName, LPCSTR szNewFileName,
      MMIOINFO FAR* lpmmioinfo, DWORD dwRenameFlags)
 {
-	printf("mmioRename('%s', '%s', %p, %08lX);\n",
+	printf("mmioRename('%s', '%s', %p, %08lX); // empty stub \n",
 			szFileName, szNewFileName, lpmmioinfo, dwRenameFlags);
 	return 0;
 }
diff --git a/objects/bitmap.c b/objects/bitmap.c
index 0783036..e394ccb 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -13,6 +13,7 @@
 #include "arch.h"
 #include "dc.h"
 #include "bitmap.h"
+#include "prototypes.h"
 #include "stddebug.h"
 /* #define DEBUG_GDI    */
 /* #define DEBUG_BITMAP */
diff --git a/objects/color.c b/objects/color.c
index b455e49..c10a6c0 100644
--- a/objects/color.c
+++ b/objects/color.c
@@ -279,7 +279,7 @@
         else index = 0;
 	break;
     }
-    if (dc)
+    if (dc&&dc->u.x.pal.mappingSize)
     {
         if (index >= dc->u.x.pal.mappingSize) return 0;
         mapping = (WORD *) GDI_HEAP_LIN_ADDR( dc->u.x.pal.hMapping );
diff --git a/objects/dc.c b/objects/dc.c
index 243aae9..92bf252 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -260,8 +260,19 @@
     XGCValues val;
 
     if (dc->u.x.pen.style == PS_NULL) return FALSE;
-    val.function   = DC_XROPfunction[dc->w.ROPmode-1];
-    val.foreground = dc->u.x.pen.pixel;
+
+    if ((screenDepth <= 8) &&  /* FIXME: Should check for palette instead */
+        ((dc->w.ROPmode == R2_BLACK) || (dc->w.ROPmode == R2_WHITE)))
+    {
+        val.function   = GXcopy;
+        val.foreground = COLOR_ToPhysical( NULL, (dc->w.ROPmode == R2_BLACK) ?
+                                               RGB(0,0,0) : RGB(255,255,255) );
+    }
+    else
+    {
+        val.function   = DC_XROPfunction[dc->w.ROPmode-1];
+        val.foreground = dc->u.x.pen.pixel;
+    }
     val.background = dc->w.backgroundPixel;
     val.fill_style = FillSolid;
     if ((dc->u.x.pen.style!=PS_SOLID) && (dc->u.x.pen.style!=PS_INSIDEFRAME))
diff --git a/objects/dib.c b/objects/dib.c
index bb5388c..b8d7313 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -12,6 +12,7 @@
 #include "bitmap.h"
 #include "palette.h"
 #include "icon.h"
+#include "stackframe.h"
 #include "stddebug.h"
 #include "color.h"
 #include "debug.h"
@@ -514,15 +515,36 @@
 	break;
     }
     if (colorMapping) free(colorMapping);
-
-    XPutImage( display, drawable, gc, bmpImage, xSrc, ySrc,
-	       xDest, yDest, width, height );
+    {
+      WORD saved_ds = CURRENT_DS;
+      XPutImage( display, drawable, gc, bmpImage, xSrc, ySrc,
+		xDest, yDest, width, height );
+      if (saved_ds != CURRENT_DS) {
+	fprintf(stderr,"Uh oh. XPutImage clobbered the 16 bit stack.\n"
+		"Please report: %s compression, %d bitplanes!!\n",
+		info->bmiHeader.biCompression ? "" : "no", 
+		info->bmiHeader.biBitCount);
+      }
+    }
     XDestroyImage( bmpImage );
     return lines;
 }
 
 
 /***********************************************************************
+ *           StretchDIBits    	(GDI.439)
+ */
+int StretchDIBits( HDC hdc, 
+	WORD xDest, WORD yDest, WORD wDestWidth, WORD wDestHeight,
+	WORD xSrc, WORD ySrc, WORD wSrcWidth, WORD wSrcHeight,
+	LPSTR bits, LPBITMAPINFO info, WORD wUsage, DWORD dwRop )
+{
+	printf("StretchDIBits // call SetDIBitsToDevice for now !!!!\n");
+	return SetDIBitsToDevice(hdc, xDest, yDest, wDestWidth, wDestHeight,
+		xSrc, ySrc, 1, 1, bits, info, wUsage);
+}
+
+/***********************************************************************
  *           SetDIBits    (GDI.440)
  */
 int SetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines,
@@ -580,6 +602,7 @@
 }
 
 
+
 /***********************************************************************
  *           GetDIBits    (GDI.441)
  */
diff --git a/objects/font.c b/objects/font.c
index cae64d1..b6bcaaa 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -178,7 +178,11 @@
             height -= 10;		
             if (height < 10) {
                 dprintf_font(stddeb,"*** No match for %s\n", pattern );
-                return NULL;
+				if(slant == 'i')
+					/* try oblique if no italic font */
+					slant = 'o';
+				else
+                	return NULL;
             }
     }
     dprintf_font(stddeb,"        Found '%s'\n", *names );
@@ -694,9 +698,9 @@
   int          nRet;
   int          i;
   
-  dprintf_font(stddeb,"EnumFonts(%04X, %p='%s', %p, %p)\n", 
-	       hDC, lpFaceName, lpFaceName, lpEnumFunc, lpData);
-  if (lpEnumFunc == NULL) return 0;
+  dprintf_font(stddeb,"EnumFonts(%04X, %p='%s', %08lx, %p)\n", 
+	       hDC, lpFaceName, lpFaceName, (LONG)lpEnumFunc, lpData);
+  if (lpEnumFunc == 0) return 0;
   hLog = GDI_HEAP_ALLOC( sizeof(LOGFONT) + LF_FACESIZE );
   lpLogFont = (LPLOGFONT) GDI_HEAP_LIN_ADDR(hLog);
   if (lpLogFont == NULL) {
@@ -763,9 +767,9 @@
   int	       	nRet;
   int	       	i;
   
-  dprintf_font(stddeb,"EnumFontFamilies(%04X, %p, %p, %p)\n", 
+  dprintf_font(stddeb,"EnumFontFamilies(%04X, %p, %08lx, %p)\n",
 	       hDC, lpszFamily, lpEnumFunc, lpData);
-  if (lpEnumFunc == NULL) return 0;
+  if (lpEnumFunc == 0) return 0;
   hLog = GDI_HEAP_ALLOC( sizeof(ENUMLOGFONT) );
   lpEnumLogFont = (LPENUMLOGFONT) GDI_HEAP_LIN_ADDR(hLog);
   if (lpEnumLogFont == NULL) {
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index ed86582..c34a379 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -199,45 +199,27 @@
 BOOL GDI_AppendToPenBrushList(HANDLE hNewObj)
 {
 	HANDLE	 	*lphObj;
-	int			i = 1;
+	int	       	i = 1;
 	if (hNewObj == 0) return FALSE;
 	if (lpPenBrushList == NULL) {
 		lpPenBrushList = malloc(MAX_OBJ * sizeof(HANDLE));
 		lpPenBrushList[0] = 0;
 		dprintf_gdi(stddeb,"GDI_AppendToPenBrushList() lpPenBrushList allocated !\n");
-		}
+	}
 	for (lphObj = lpPenBrushList; i < MAX_OBJ; i++) {
 		if (*lphObj == 0) {
 			*lphObj = hNewObj;
 			*(lphObj + 1) = 0;
 			dprintf_gdi(stddeb,"GDI_AppendToPenBrushList(%04X) appended (count=%d)\n", hNewObj, i);
 			return TRUE;
-			}
-		lphObj++;
 		}
+		lphObj++;
+	}
 	return FALSE;
 }
 
 
 /***********************************************************************
- *           GDI_FindPrevObject
- *
- * Return the GDI object whose hNext field points to obj.
- */
-HANDLE GDI_FindPrevObject( HANDLE first, HANDLE obj )
-{
-    HANDLE handle;
-        
-    for (handle = first; handle && (handle != obj); )
-    {
-	GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR( handle );
-	handle = header->hNext;
-    }
-    return handle;
-}
-
-
-/***********************************************************************
  *           GDI_AllocObject
  */
 HANDLE GDI_AllocObject( WORD size, WORD magic )
@@ -250,9 +232,9 @@
     obj->hNext   = 0;
     obj->wMagic  = magic;
     obj->dwCount = ++count;
-	if (magic == PEN_MAGIC || magic == BRUSH_MAGIC) {
-		GDI_AppendToPenBrushList(handle);
-		}
+    if (magic == PEN_MAGIC || magic == BRUSH_MAGIC) {
+      GDI_AppendToPenBrushList(handle);
+    }
     return handle;
 }
 
@@ -429,110 +411,106 @@
  */
 int EnumObjects(HDC hDC, int nObjType, FARPROC lpEnumFunc, LPSTR lpData)
 {
-/*    HANDLE 		handle;
-    DC 			*dc;*/
-	HANDLE		*lphObj;
-	GDIOBJHDR 	*header;
-	WORD  		wMagic;
-	LPSTR		lpLog;  	/* Point to a LOGBRUSH or LOGPEN struct */
-	HANDLE 		hLog;
-	int			i, nRet;
-	if (lpEnumFunc == NULL) {
-		fprintf(stderr,"EnumObjects // Bad EnumProc callback address !\n");
-		return 0;
-		}
-	switch (nObjType) {
-		case OBJ_PEN:
-			wMagic = PEN_MAGIC;
-			dprintf_gdi(stddeb,"EnumObjects(%04X, OBJ_PEN, %p, %p);\n", 
-									hDC, lpEnumFunc, lpData);
-			hLog = GDI_HEAP_ALLOC( sizeof(LOGPEN) );
-			lpLog = (LPSTR) GDI_HEAP_LIN_ADDR(hLog);
-			if (lpLog == NULL) {
-				fprintf(stderr,"EnumObjects // Unable to alloc LOGPEN struct !\n");
-				return 0;
-				}
-			break;
-		case OBJ_BRUSH:
-			wMagic = BRUSH_MAGIC;
-			dprintf_gdi(stddeb,"EnumObjects(%04X, OBJ_BRUSH, %p, %p);\n", 
-									hDC, lpEnumFunc, lpData);
-			hLog = GDI_HEAP_ALLOC( sizeof(LOGBRUSH) );
-			lpLog = (LPSTR) GDI_HEAP_LIN_ADDR(hLog);
-			if (lpLog == NULL) {
-				fprintf(stderr,"EnumObjects // Unable to alloc LOGBRUSH struct !\n");
-				return 0;
-				}
-			break;
-		default:
-			fprintf(stderr,"EnumObjects(%04X, %04X, %p, %p); // Unknown OBJ type !\n", 
-						hDC, nObjType, lpEnumFunc, lpData);
-			return 0;
-		}
+  /*    HANDLE 		handle;
+   DC 			*dc;*/
+  HANDLE       	*lphObj;
+  GDIOBJHDR 	*header;
+  WORD         	wMagic;
+  LPSTR		lpLog;  	/* Point to a LOGBRUSH or LOGPEN struct */
+  HANDLE       	hLog;
+  int	       	i, nRet = 0;
+  
+  if (lpEnumFunc == NULL) {
+    fprintf(stderr,"EnumObjects // Bad EnumProc callback address !\n");
+    return 0;
+  }
+  switch (nObjType) {
+   case OBJ_PEN:
+    wMagic = PEN_MAGIC;
+    dprintf_gdi(stddeb,"EnumObjects(%04X, OBJ_PEN, %08lx, %p);\n",
+		hDC, (LONG)lpEnumFunc, lpData);
+    hLog = GDI_HEAP_ALLOC( sizeof(LOGPEN) );
+    lpLog = (LPSTR) GDI_HEAP_LIN_ADDR(hLog);
+    if (lpLog == NULL) {
+      fprintf(stderr,"EnumObjects // Unable to alloc LOGPEN struct !\n");
+      return 0;
+    }
+    break;
+   case OBJ_BRUSH:
+    wMagic = BRUSH_MAGIC;
+    dprintf_gdi(stddeb,"EnumObjects(%04X, OBJ_BRUSH, %08lx, %p);\n",
+		hDC, (LONG)lpEnumFunc, lpData);
+    hLog = GDI_HEAP_ALLOC( sizeof(LOGBRUSH) );
+    lpLog = (LPSTR) GDI_HEAP_LIN_ADDR(hLog);
+    if (lpLog == NULL) {
+      fprintf(stderr,"EnumObjects // Unable to alloc LOGBRUSH struct !\n");
+      return 0;
+    }
+    break;
+   default:
+    fprintf(stderr,"EnumObjects(%04X, %04X, %08lx, %p); // Unknown OBJ type !\n", 
+	    hDC, nObjType, (LONG)lpEnumFunc, lpData);
+    return 0;
+  }
 #ifdef notdef  /* FIXME: stock object ptr won't work in callback */
-	dprintf_gdi(stddeb,"EnumObjects // Stock Objects first !\n");
-	for (i = 0; i < NB_STOCK_OBJECTS; i++) {
-		header = StockObjects[i];
-		if (header->wMagic == wMagic) {
-			PEN_GetObject( (PENOBJ *)header, sizeof(LOGPEN), lpLog);
-			BRUSH_GetObject( (BRUSHOBJ *)header, sizeof(LOGBRUSH),lpLog);
-			dprintf_gdi(stddeb,"EnumObjects // StockObj lpLog=%p lpData=%p\n", lpLog, lpData);
-			if (header->wMagic == BRUSH_MAGIC) {
-				dprintf_gdi(stddeb,"EnumObjects // StockBrush lbStyle=%04X\n", ((LPLOGBRUSH)lpLog)->lbStyle);
-				dprintf_gdi(stddeb,"EnumObjects // StockBrush lbColor=%08lX\n", ((LPLOGBRUSH)lpLog)->lbColor);
-				dprintf_gdi(stddeb,"EnumObjects // StockBrush lbHatch=%04X\n", ((LPLOGBRUSH)lpLog)->lbHatch);
-				}
-			if (header->wMagic == PEN_MAGIC) {
-				dprintf_gdi(stddeb,"EnumObjects // StockPen lopnStyle=%04X\n", ((LPLOGPEN)lpLog)->lopnStyle);
-				dprintf_gdi(stddeb,"EnumObjects // StockPen lopnWidth=%d\n", ((LPLOGPEN)lpLog)->lopnWidth.x);
-				dprintf_gdi(stddeb,"EnumObjects // StockPen lopnColor=%08lX\n", ((LPLOGPEN)lpLog)->lopnColor);
-				}
-			nRet = CallEnumObjectsProc( lpEnumFunc,
-                                                    GDI_HEAP_SEG_ADDR(hLog),
-                                                    (int)lpData );
-			dprintf_gdi(stddeb,"EnumObjects // after Callback!\n");
-			if (nRet == 0) {
-				GDI_HEAP_FREE(hLog);
-				dprintf_gdi(stddeb,"EnumObjects // EnumEnd requested by application !\n");
-				return 0;
-				}
-			}
-		}
-#endif  /* notdef */
-
-	if (lpPenBrushList == NULL) return 0;
-	dprintf_gdi(stddeb,"EnumObjects // Now DC owned objects %p !\n", header);
-	for (lphObj = lpPenBrushList; *lphObj != 0; ) {
-		dprintf_gdi(stddeb,"EnumObjects // *lphObj=%04X\n", *lphObj);
-		header = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR(*lphObj++);
-		if (header->wMagic == wMagic) {
-			dprintf_gdi(stddeb,"EnumObjects // DC_Obj lpLog=%p lpData=%p\n", lpLog, lpData);
-			if (header->wMagic == BRUSH_MAGIC) {
-				BRUSH_GetObject( (BRUSHOBJ *)header, sizeof(LOGBRUSH), lpLog);
-				dprintf_gdi(stddeb,"EnumObjects // DC_Brush lbStyle=%04X\n", ((LPLOGBRUSH)lpLog)->lbStyle);
-				dprintf_gdi(stddeb,"EnumObjects // DC_Brush lbColor=%08lX\n", ((LPLOGBRUSH)lpLog)->lbColor);
-				dprintf_gdi(stddeb,"EnumObjects // DC_Brush lbHatch=%04X\n", ((LPLOGBRUSH)lpLog)->lbHatch);
-				}
-			if (header->wMagic == PEN_MAGIC) {
-				PEN_GetObject( (PENOBJ *)header, sizeof(LOGPEN), lpLog);
-				dprintf_gdi(stddeb,"EnumObjects // DC_Pen lopnStyle=%04X\n", ((LPLOGPEN)lpLog)->lopnStyle);
-				dprintf_gdi(stddeb,"EnumObjects // DC_Pen lopnWidth=%d\n", ((LPLOGPEN)lpLog)->lopnWidth.x);
-				dprintf_gdi(stddeb,"EnumObjects // DC_Pen lopnColor=%08lX\n", ((LPLOGPEN)lpLog)->lopnColor);
-				}
-			nRet = CallEnumObjectsProc( lpEnumFunc,
-                                                    GDI_HEAP_SEG_ADDR(hLog),
-                                                    (int)lpData );
-			dprintf_gdi(stddeb,"EnumObjects // after Callback!\n");
-			if (nRet == 0) {
-				GDI_HEAP_FREE(hLog);
-				dprintf_gdi(stddeb,"EnumObjects // EnumEnd requested by application !\n");
-				return 0;
-				}
-			}
-		}
+  dprintf_gdi(stddeb,"EnumObjects // Stock Objects first !\n");
+  for (i = 0; i < NB_STOCK_OBJECTS; i++) {
+    header = StockObjects[i];
+    if (header->wMagic == wMagic) {
+      PEN_GetObject( (PENOBJ *)header, sizeof(LOGPEN), lpLog);
+      BRUSH_GetObject( (BRUSHOBJ *)header, sizeof(LOGBRUSH),lpLog);
+      dprintf_gdi(stddeb,"EnumObjects // StockObj lpLog=%p lpData=%p\n", lpLog, lpData);
+      if (header->wMagic == BRUSH_MAGIC) {
+	dprintf_gdi(stddeb,"EnumObjects // StockBrush lbStyle=%04X\n", ((LPLOGBRUSH)lpLog)->lbStyle);
+	dprintf_gdi(stddeb,"EnumObjects // StockBrush lbColor=%08lX\n", ((LPLOGBRUSH)lpLog)->lbColor);
+	dprintf_gdi(stddeb,"EnumObjects // StockBrush lbHatch=%04X\n", ((LPLOGBRUSH)lpLog)->lbHatch);
+      }
+      if (header->wMagic == PEN_MAGIC) {
+	dprintf_gdi(stddeb,"EnumObjects // StockPen lopnStyle=%04X\n", ((LPLOGPEN)lpLog)->lopnStyle);
+	dprintf_gdi(stddeb,"EnumObjects // StockPen lopnWidth=%d\n", ((LPLOGPEN)lpLog)->lopnWidth.x);
+	dprintf_gdi(stddeb,"EnumObjects // StockPen lopnColor=%08lX\n", ((LPLOGPEN)lpLog)->lopnColor);
+      }
+      nRet = CallEnumObjectsProc( lpEnumFunc,
+				 GDI_HEAP_SEG_ADDR(hLog),
+				 (int)lpData );
+      dprintf_gdi(stddeb,"EnumObjects // after Callback!\n");
+      if (nRet == 0) {
 	GDI_HEAP_FREE(hLog);
-	dprintf_gdi(stddeb,"EnumObjects // End of enumeration !\n");
+	dprintf_gdi(stddeb,"EnumObjects // EnumEnd requested by application !\n");
 	return 0;
+      }
+    }
+  }
+  dprintf_gdi(stddeb,"EnumObjects // Now DC owned objects %p !\n", header);
+#endif  /* notdef */
+  
+  if (lpPenBrushList == NULL) return 0;
+  for (lphObj = lpPenBrushList; *lphObj != 0; ) {
+    dprintf_gdi(stddeb,"EnumObjects // *lphObj=%04X\n", *lphObj);
+    header = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR(*lphObj++);
+    if (header->wMagic == wMagic) {
+      dprintf_gdi(stddeb,"EnumObjects // DC_Obj lpLog=%p lpData=%p\n", lpLog, lpData);
+      if (header->wMagic == BRUSH_MAGIC) {
+	BRUSH_GetObject( (BRUSHOBJ *)header, sizeof(LOGBRUSH), lpLog);
+	dprintf_gdi(stddeb,"EnumObjects // DC_Brush lbStyle=%04X\n", ((LPLOGBRUSH)lpLog)->lbStyle);
+	dprintf_gdi(stddeb,"EnumObjects // DC_Brush lbColor=%08lX\n", ((LPLOGBRUSH)lpLog)->lbColor);
+	dprintf_gdi(stddeb,"EnumObjects // DC_Brush lbHatch=%04X\n", ((LPLOGBRUSH)lpLog)->lbHatch);
+      }
+      if (header->wMagic == PEN_MAGIC) {
+	PEN_GetObject( (PENOBJ *)header, sizeof(LOGPEN), lpLog);
+	dprintf_gdi(stddeb,"EnumObjects // DC_Pen lopnStyle=%04X\n", ((LPLOGPEN)lpLog)->lopnStyle);
+	dprintf_gdi(stddeb,"EnumObjects // DC_Pen lopnWidth=%d\n", ((LPLOGPEN)lpLog)->lopnWidth.x);
+	dprintf_gdi(stddeb,"EnumObjects // DC_Pen lopnColor=%08lX\n", ((LPLOGPEN)lpLog)->lopnColor);
+      }
+      nRet = CallEnumObjectsProc(lpEnumFunc, GDI_HEAP_SEG_ADDR(hLog),
+				 (LONG)lpData);
+      if (nRet == 0)
+        break;
+    }
+  }
+  GDI_HEAP_FREE(hLog);
+  dprintf_gdi(stddeb,"EnumObjects // End of enumeration !\n");
+  return nRet;
 }
 
 /***********************************************************************
diff --git a/objects/oembitmap.c b/objects/oembitmap.c
index 381bec6..87093f6 100644
--- a/objects/oembitmap.c
+++ b/objects/oembitmap.c
@@ -18,6 +18,11 @@
 
 
   /* Include OEM pixmaps */
+#include "bitmaps/obm_cdrom"
+#include "bitmaps/obm_harddisk"
+#include "bitmaps/obm_drive"
+#include "bitmaps/obm_folder2"
+#include "bitmaps/obm_folder"
 #include "bitmaps/obm_lfarrowi"
 #include "bitmaps/obm_rgarrowi"
 #include "bitmaps/obm_dnarrowi"
@@ -53,7 +58,7 @@
 #include "bitmaps/obm_size"
 #include "bitmaps/obm_old_close"
 
-#define OBM_FIRST  OBM_LFARROWI    /* First OEM bitmap */
+#define OBM_FIRST  OBM_CDROM      /* First OEM bitmap */
 #define OBM_LAST   OBM_OLD_CLOSE   /* Last OEM bitmap */
 
 static const struct
@@ -61,6 +66,11 @@
     char** data;   /* Pointer to bitmap data */
     BOOL   color;  /* Is it a color bitmap?  */
 } OBM_Pixmaps_Data[OBM_LAST-OBM_FIRST+1] = {
+    { obm_cdrom, TRUE },        /* OBM_CDROM    */
+    { obm_harddisk, TRUE },     /* OBM_HARDDISK */
+    { obm_drive, TRUE },        /* OBM_DRIVE    */
+    { obm_folder2, TRUE },      /* OBM_FOLDER2  */
+    { obm_folder, TRUE },       /* OBM_FOLDER   */
     { obm_lfarrowi, TRUE },     /* OBM_LFARROWI */
     { obm_rgarrowi, TRUE },     /* OBM_RGARROWI */
     { obm_dnarrowi, TRUE },     /* OBM_DNARROWI */
@@ -104,9 +114,12 @@
 #include "bitmaps/oic_ques"
 #include "bitmaps/oic_bang"
 #include "bitmaps/oic_note"
+#include "bitmaps/oic_portrait"
+#include "bitmaps/oic_landscape"
+#include "bitmaps/oic_wineicon"
 
 #define OIC_FIRST  OIC_SAMPLE      /* First OEM icon */
-#define OIC_LAST   OIC_NOTE        /* Last OEM icon */
+#define OIC_LAST   OIC_WINEICON   /* Last OEM icon */
 
 static char **OBM_Icons_Data[OIC_LAST-OIC_FIRST+1] =
 {
@@ -114,7 +127,10 @@
     oic_hand,      /* OIC_HAND */
     oic_ques,      /* OIC_QUES */
     oic_bang,      /* OIC_BANG */
-    oic_note       /* OIC_NOTE */
+    oic_note,      /* OIC_NOTE */
+    oic_portrait,  /* OIC_PORTRAIT */
+    oic_landscape, /* OIC_LANDSCAPE */
+    oic_wineicon   /* OIC_WINEICON */
 };
 
 
@@ -137,6 +153,12 @@
     { "green",            RGB(0,255,0) },
     { "blue",             RGB(0,0,255) },
     { "yellow",           RGB(255,255,0) },
+    { "cyan",             RGB(0,255,255) },    
+    { "dkyellow",         RGB(128,128,0) },
+    { "purple",           RGB(128,0,128) },
+    { "ltgray",           RGB(192,192,192) },
+    { "dkgray",           RGB(128,128,128) },
+    { "foldercol",        RGB(0,191,191) },
     { "button_face",      PALETTEINDEX(COLOR_BTNFACE) },
     { "button_shadow",    PALETTEINDEX(COLOR_BTNSHADOW) },
     { "button_highlight", PALETTEINDEX(COLOR_BTNHIGHLIGHT) },
diff --git a/objects/palette.c b/objects/palette.c
index bee05d5..80b64c4 100644
--- a/objects/palette.c
+++ b/objects/palette.c
@@ -80,6 +80,17 @@
 
 
 /***********************************************************************
+ *           GetSystemPaletteUse    (GDI.374)
+ */
+WORD GetSystemPaletteUse( HDC hdc )
+{
+	printf("GetSystemPaletteUse(%04X) // empty stub !!!\n", hdc);
+	/* Assuming there is remaining system colors ... */
+	return SYSPAL_STATIC;
+}
+
+
+/***********************************************************************
  *           GetSystemPaletteEntries    (GDI.375)
  */
 WORD GetSystemPaletteEntries( HDC hdc, WORD start, WORD count,
diff --git a/rc/Imakefile b/rc/Imakefile
index 424addb..56f9e14 100644
--- a/rc/Imakefile
+++ b/rc/Imakefile
@@ -46,9 +46,6 @@
 #if defined(i386BsdArchitecture) || defined(i386FreeBsd) || defined(FreeBSDArchitecture)
 LOCAL_LIBRARIES = -ll
 #endif
-#ifdef LinuxArchitecture
-LOCAL_LIBRARIES = -lfl
-#endif
 
 NormalProgramTarget(winerc,$(OBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),)
 
diff --git a/rc/parser.l b/rc/parser.l
index 338a13f..3add2b5 100644
--- a/rc/parser.l
+++ b/rc/parser.l
@@ -73,3 +73,9 @@
 \'[^']*\'   yylval.str=strdup(yytext+1);return SINGLE_QUOTED;
 [ \t\n\r]		;
 .			return yytext[0];
+%%
+
+#ifndef yywrap
+int yywrap(void) { return 1; }
+#endif
+
diff --git a/rc/sysres.rc b/rc/sysres.rc
index 674df65..2ca57c8 100644
--- a/rc/sysres.rc
+++ b/rc/sysres.rc
@@ -15,36 +15,19 @@
  MENUITEM "&About WINE ...", 61761
 }
 
-
-2 DIALOG LOADONCALL MOVEABLE DISCARDABLE 80, 80, 150, 170
-STYLE WS_POPUP | WS_VISIBLE | WS_DLGFRAME
-{
- PUSHBUTTON "Credit & License", 6, 30, 150, 40, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "Cancel", 2, 60, 250, 40, 14, WS_GROUP | WS_TABSTOP
- DEFPUSHBUTTON "Ok", 1, 80, 150, 40, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
-}
-
-
-STOP_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 80, 80, 150, 75
-STYLE WS_POPUP | WS_VISIBLE | WS_DLGFRAME
-{
- ICON "SYSIDI_HAND", -1, 16, 16, 0, 0
-}
-
-
-QUESTION_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 80, 80, 150, 75
-STYLE WS_POPUP | WS_VISIBLE | WS_DLGFRAME
-{
- ICON "SYSIDI_QUESTION", -1, 16, 16, 0, 0
-}
-
-
-EXCLAMATION_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 80, 80, 150, 75
-STYLE WS_POPUP | WS_VISIBLE | WS_DLGFRAME
-{
- ICON "SYSIDI_EXCLAMATION", -1, 16, 16, 0, 0
-}
-
+MSGBOX DIALOG 100, 80, 216, 168
+STYLE DS_SYSMODAL | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+BEGIN
+        ICON "", 1088, 8, 20, 16, 16, WS_CHILD | WS_VISIBLE
+        LTEXT "", 100, 32, 4, 176, 48, WS_CHILD | WS_VISIBLE | WS_GROUP
+        PUSHBUTTON "&Ok", 1, 16, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Cancel", 2, 64, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Abort", 3, 112, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Retry", 4, 160, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Ignore", 5, 208, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Yes", 6, 256, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&No", 7, 304, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+END
 
 SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 50, 44, 213, 149
 STYLE DS_LOCALEDIT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
@@ -54,7 +37,7 @@
  DEFPUSHBUTTON "OK", 1, 86, 130, 40, 14
  CONTROL "", -1, "STATIC", SS_BLACKFRAME | WS_CHILD | WS_VISIBLE | WS_DISABLED, 4, 35, 205, 90
  LTEXT "Text", 100, 11, 40, 190, 80, SS_NOPREFIX | WS_GROUP
- ICON "WINEICON", -1, 185, 10, 18, 20
+ ICON "", 1088, 185, 10, 18, 20
 }
 
 
diff --git a/rc/sysres_De.rc b/rc/sysres_De.rc
index 03852bc..00bb498 100644
--- a/rc/sysres_De.rc
+++ b/rc/sysres_De.rc
@@ -13,36 +13,19 @@
  MENUITEM "&Über WINE ...", 61761
 }
 
-
-2 DIALOG LOADONCALL MOVEABLE DISCARDABLE 80, 80, 150, 170
-STYLE WS_POPUP | WS_VISIBLE | WS_DLGFRAME
-{
- PUSHBUTTON "Kredit & Lizenz", 6, 30, 150, 40, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "Abbruch", 2, 60, 250, 40, 14, WS_GROUP | WS_TABSTOP
- DEFPUSHBUTTON "Ok", 1, 80, 150, 40, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
-}
-
-
-STOP_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 80, 80, 150, 75
-STYLE WS_POPUP | WS_VISIBLE | WS_DLGFRAME
-{
- ICON "SYSIDI_HAND", -1, 16, 16, 0, 0
-}
-
-
-QUESTION_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 80, 80, 150, 75
-STYLE WS_POPUP | WS_VISIBLE | WS_DLGFRAME
-{
- ICON "SYSIDI_QUESTION", -1, 16, 16, 0, 0
-}
-
-
-EXCLAMATION_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 80, 80, 150, 75
-STYLE WS_POPUP | WS_VISIBLE | WS_DLGFRAME
-{
- ICON "SYSIDI_EXCLAMATION", -1, 16, 16, 0, 0
-}
-
+MSGBOX DIALOG 100, 80, 216, 168
+STYLE DS_SYSMODAL | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+BEGIN
+        ICON "", 1088, 8, 20, 16, 16, WS_CHILD | WS_VISIBLE
+        LTEXT "", 100, 32, 4, 176, 48, WS_CHILD | WS_VISIBLE | WS_GROUP
+        PUSHBUTTON "&Ok", 1, 16, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Abbruch", 2, 64, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Abbruch", 3, 112, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Wiederholen", 4, 160, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Ignorieren", 5, 208, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Ja", 6, 256, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Nein", 7, 304, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+END
 
 SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 50, 44, 213, 149
 STYLE DS_LOCALEDIT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
@@ -52,7 +35,7 @@
  DEFPUSHBUTTON "OK", 1, 86, 130, 40, 14
  CONTROL "", -1, "STATIC", SS_BLACKFRAME | WS_CHILD | WS_VISIBLE | WS_DISABLED, 4, 35, 205, 90
  LTEXT "Text", 100, 11, 40, 190, 80, SS_NOPREFIX | WS_GROUP
- ICON "WINEICON", -1, 185, 10, 18, 20
+ ICON "", 1088, 185, 10, 18, 20
 }
 
 
diff --git a/rc/sysres_No.rc b/rc/sysres_No.rc
index afa2b58..ee189b2 100644
--- a/rc/sysres_No.rc
+++ b/rc/sysres_No.rc
@@ -13,36 +13,19 @@
  MENUITEM "&Om WINE ...", 61761
 }
 
-
-2 DIALOG LOADONCALL MOVEABLE DISCARDABLE 80, 80, 150, 170
-STYLE WS_POPUP | WS_VISIBLE | WS_DLGFRAME
-{
- PUSHBUTTON "Lisens osv.", 6, 30, 150, 40, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "Avbryt", 2, 60, 250, 40, 14, WS_GROUP | WS_TABSTOP
- DEFPUSHBUTTON "Ok", 1, 80, 150, 40, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
-}
-
-
-STOP_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 80, 80, 150, 75
-STYLE WS_POPUP | WS_VISIBLE | WS_DLGFRAME
-{
- ICON "SYSIDI_HAND", -1, 16, 16, 0, 0
-}
-
-
-QUESTION_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 80, 80, 150, 75
-STYLE WS_POPUP | WS_VISIBLE | WS_DLGFRAME
-{
- ICON "SYSIDI_QUESTION", -1, 16, 16, 0, 0
-}
-
-
-EXCLAMATION_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 80, 80, 150, 75
-STYLE WS_POPUP | WS_VISIBLE | WS_DLGFRAME
-{
- ICON "SYSIDI_EXCLAMATION", -1, 16, 16, 0, 0
-}
-
+MSGBOX DIALOG 100, 80, 216, 168
+STYLE DS_SYSMODAL | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+BEGIN
+        ICON "", 1088, 8, 20, 16, 16, WS_CHILD | WS_VISIBLE
+        LTEXT "", 100, 32, 4, 176, 48, WS_CHILD | WS_VISIBLE | WS_GROUP
+        PUSHBUTTON "&Ok", 1, 16, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Avbryt", 2, 64, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Avbryt", 3, 112, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Gjenta", 4, 160, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Ignorer", 5, 208, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Ja", 6, 256, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Nei", 7, 304, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+END
 
 SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 50, 44, 213, 149
 STYLE DS_LOCALEDIT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
@@ -52,7 +35,7 @@
  DEFPUSHBUTTON "OK", 1, 86, 130, 40, 14
  CONTROL "", -1, "STATIC", SS_BLACKFRAME | WS_CHILD | WS_VISIBLE | WS_DISABLED, 4, 35, 205, 90
  LTEXT "Tekst", 100, 11, 40, 190, 80, SS_NOPREFIX | WS_GROUP
- ICON "WINEICON", -1, 185, 10, 18, 20
+ ICON "", 1088, 185, 10, 18, 20
 }
 
 
diff --git a/toolkit/sup.c b/toolkit/sup.c
index f22343c..ef95120 100644
--- a/toolkit/sup.c
+++ b/toolkit/sup.c
@@ -5,8 +5,6 @@
 #include "wine.h"
 #include "arch.h"
 
-/* HANDLE hSysRes = 1; */
-
 LONG CallWindowProc (WNDPROC func, HWND hwnd, WORD message,
 		     WORD wParam, LONG lParam)
 {
diff --git a/toolkit/winmain.c b/toolkit/winmain.c
index a5718ca..41da3ae 100644
--- a/toolkit/winmain.c
+++ b/toolkit/winmain.c
@@ -4,22 +4,12 @@
 #include "windows.h"
 #include "wine.h"
 
-extern HINSTANCE hSysRes;
-
 _WinMain (int argc, char *argv [])
 {
     int ret_val;
     char filename [4096], *module_name, *resource_file;
     HANDLE hTaskMain, hInstance;
     
-    GetPrivateProfileString("wine", "SystemResources", "sysres.dll", 
-			    filename, sizeof(filename), WINE_INI);
-    hSysRes = LoadImage(filename);
-    if (hSysRes == (HINSTANCE)NULL)
-	printf("Error Loading System Resources !!!\n");
-    else
-	printf("System Resources Loaded // hSysRes='%04X'\n", hSysRes);
-
     if ((module_name = strchr (argv [0], '/')) == NULL){
 	printf ("Error: Can't determine base name for resource loading\n");
 	return 0;
@@ -31,7 +21,7 @@
 
     hInstance = LoadImage (resource_file, 0, 0);
     
-    USER_InitApp (hSysRes);
+    USER_InitApp( hInstance );
     hTaskMain = CreateNewTask (1); /* This is not correct */
     ret_val = WinMain (hInstance,	/* hInstance */
 		       0,		/* hPrevInstance */
diff --git a/tools/build.c b/tools/build.c
index ef0b2b6..b79dc51 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -1,6 +1,7 @@
 /*
  * Copyright 1993 Robert J. Amstadt
  * Copyright 1995 Alexandre Julliard
+ * Copyright 1995 Martin von Loewis
  */
 
 #include <stdio.h>
@@ -28,6 +29,7 @@
 #define TYPE_ABS         7
 #define TYPE_RETURN      8
 #define TYPE_STUB        9
+#define TYPE_STDCALL    10
 
 #define MAX_ORDINALS	1299
 
@@ -67,6 +69,7 @@
 char UpperDLLName[80];
 int Limit = 0;
 int DLLId;
+int Base = 0;
 FILE *SpecFp;
 
 char *ParseBuffer = NULL;
@@ -410,7 +413,9 @@
     else if (strcmp(token, "pascal16") == 0)
 	return ParseExportFunction(ordinal, TYPE_PASCAL_16);
     else if (strcmp(token, "register") == 0)
-	return ParseExportFunction(ordinal, TYPE_REGISTER);
+        return ParseExportFunction(ordinal, TYPE_REGISTER);
+    else if (strcmp(token, "stdcall") == 0)
+        return ParseExportFunction(ordinal, TYPE_STDCALL);
     else if (strcmp(token, "equate") == 0)
 	return ParseEquate(ordinal);
     else if (strcmp(token, "return") == 0)
@@ -451,6 +456,17 @@
 	    
 	    DLLId = atoi(token);
 	}
+	else if (strcmp(token, "base") == 0)
+	{
+		token = GetToken();
+		if (!IsNumberString(token))
+		{
+		fprintf(stderr, "%d: Expected number after base\n", Line);
+		exit(1);
+		}
+
+		Base = atoi(token);
+	}
 	else if (IsNumberString(token))
 	{
 	    int ordinal;
@@ -472,27 +488,25 @@
 }
 
 
-static int OutputVariableCode(FILE *fp, char *storage, ORDDEF *odp)
+static int OutputVariableCode( char *storage, ORDDEF *odp )
 {
     ORDVARDEF *vdp;
     int i;
 
     vdp = odp->additional_data;
-    fprintf( fp, "\t.data\n" );
+    printf( "\t.data\n" );
     for (i = 0; i < vdp->n_values; i++)
     {
 	if ((i & 7) == 0)
-	    fprintf(fp, "\t%s\t", storage);
+	    printf( "\t%s\t", storage);
 	    
-	fprintf(fp, "%d", vdp->values[i]);
+	printf( "%d", vdp->values[i]);
 	
-	if ((i & 7) == 7 || i == vdp->n_values - 1)
-	    fprintf(fp, "\n");
-	else
-	    fprintf(fp, ", ");
+	if ((i & 7) == 7 || i == vdp->n_values - 1) printf( "\n");
+	else printf( ", ");
     }
-    fprintf(fp, "\n");
-    fprintf( fp, "\t.text\n" );
+    printf( "\n");
+    printf( "\t.text\n" );
     return vdp->n_values;
 }
 
@@ -503,7 +517,7 @@
  * Build the in-memory representation of the module, and dump it
  * as a byte stream into the assembly code.
  */
-static void BuildModule( FILE *fp, int max_code_offset, int max_data_offset )
+static void BuildModule( int max_code_offset, int max_data_offset )
 {
     ORDDEF *odp;
     int i, size;
@@ -549,7 +563,7 @@
     pModule->truetype = 0;
     pModule->os_flags = NE_OSFLAGS_WINDOWS;
     pModule->misc_flags = 0;
-    pModule->reserved = 0;
+    pModule->dlls_to_init  = 0;
     pModule->nrname_handle = 0;
     pModule->min_swap_area = 0;
     pModule->expected_version = 0x030a;
@@ -677,28 +691,151 @@
 
       /* Dump the module content */
 
-    fprintf( fp, "\t.data\n" );
-    fprintf( fp, "\t.globl " PREFIX "%s_Module_Start\n", UpperDLLName );
-    fprintf( fp, PREFIX "%s_Module_Start:\n", UpperDLLName );
+    printf( "\t.data\n" );
+    printf( "\t.globl " PREFIX "%s_Module_Start\n", UpperDLLName );
+    printf( PREFIX "%s_Module_Start:\n", UpperDLLName );
     size = (int)pstr - (int)pModule;
     for (i = 0, pstr = buffer; i < size; i++, pstr++)
     {
-        if (!(i & 7)) fprintf( fp, "\t.byte " );
-        fprintf( fp, "%d%c", *pstr, ((i & 7) != 7) ? ',' : '\n' );
+        if (!(i & 7)) printf( "\t.byte " );
+        printf( "%d%c", *pstr, ((i & 7) != 7) ? ',' : '\n' );
     }
-    if (i & 7) fprintf( fp, "0\n" );
-    fprintf( fp, "\t.globl " PREFIX "%s_Module_End\n", UpperDLLName );
-    fprintf( fp, PREFIX "%s_Module_End:\n", UpperDLLName );
+    if (i & 7) printf( "0\n" );
+    printf( "\t.globl " PREFIX "%s_Module_End\n", UpperDLLName );
+    printf( PREFIX "%s_Module_End:\n", UpperDLLName );
 }
 
 
-static void BuildSpecFiles( char *specname)
+static void BuildSpec32Files( char *specname )
 {
     ORDDEF *odp;
     ORDFUNCDEF *fdp;
     ORDRETDEF *rdp;
-    FILE *fp;
-    char filename[80];
+    int i;
+
+    SpecFp = fopen( specname, "r");
+    if (SpecFp == NULL)
+    {
+	fprintf(stderr, "Could not open specification file, '%s'\n", specname);
+	exit(1);
+    }
+
+    ParseTopLevel();
+
+    printf( "/* File generated automatically, do not edit! */\n" );
+    printf( "#include <sys/types.h>\n");
+    printf( "#include \"dlls.h\"\n");
+    printf( "#include \"pe_image.h\"\n");
+    printf( "#include \"winerror.h\"\n");
+    printf( "#include \"stddebug.h\"\n");
+    printf( "#include \"debug.h\"\n");
+    printf( "\nextern int RELAY32_Unimplemented();\n\n" );
+
+    odp = OrdinalDefinitions;
+    for (i = 0; i <= Limit; i++, odp++)
+    {
+        int argno,argc;
+        fdp = odp->additional_data;
+        rdp = odp->additional_data;
+
+        switch (odp->type)
+        {
+        case TYPE_INVALID:
+        case TYPE_STUB:
+            printf( "int %s_%d()\n{\n\t", UpperDLLName, i);
+            printf( "RELAY32_Unimplemented(\"%s\",%d);\n", UpperDLLName, i);
+            printf( "\t/*NOTREACHED*/\n\treturn 0;\n}\n\n");
+            break;
+        case TYPE_STDCALL:
+            argc=strlen(fdp->arg_types);
+            printf( "void %s_%d(", UpperDLLName, i);
+            for(argno=0;argno<argc;argno++)
+            {
+                switch(fdp->arg_types[argno])
+                {
+                case 'p': printf( "void *");break;
+                case 'l': printf( "int ");break;
+                default:
+                    fprintf(stderr, "Not supported argument type %c\n",
+                            fdp->arg_types[argno]);
+                    exit(1);
+                }
+                putchar( 'a'+argno );
+                if (argno!=argc-1) putchar( ',' );
+            }
+            printf( ")\n{\n" );
+            printf( "\textern int %s();\n", fdp->internal_name );
+            printf( "\tdprintf_relay(stddeb,\"Entering %%s.%%s(");
+            for (argno=0;argno<argc;argno++) printf( "%%x ");
+            printf( ")\\n\", \"%s\", \"%s\"", UpperDLLName, odp->export_name);
+            for(argno=0;argno<argc;argno++) printf( ",%c", 'a'+argno);
+            printf( ");\n\t%s(", fdp->internal_name );
+            for(argno=0;argno<argc;argno++)
+            {
+                putchar('a'+argno);
+                if (argno!=argc-1) putchar(',');
+            }
+            printf( ");\n\t__asm__ __volatile__(\"movl %%ebp,%%esp;"
+                    "popl %%ebp;ret $%d\");\n}\n\n",
+                    4*argc);
+            break;
+        case TYPE_RETURN:
+            printf( "void %s_%d()\n{\n\t", UpperDLLName, i);
+            printf( "RELAY32_DebugEnter(\"%s\",\"%s\");\n\t",
+                   UpperDLLName, odp->export_name);
+            printf( "WIN32_LastError=ERROR_CALL_NOT_IMPLEMENTED;\n");
+            printf( "\t__asm__ __volatile__ (\"movl %d,%%eax\");\n", 
+                   rdp->ret_value);
+            printf( "\t__asm__ __volatile__ (\"movl %%ebp,%%esp;popl %%ebp;"
+                    "ret $%d\");\n}\n\n", rdp->arg_size);
+            break;
+        default:
+            fprintf(stderr,"build: function type %d not available for Win32\n",
+                    odp->type);
+            break;
+        }
+    }
+
+    printf( "static WIN32_function functions[%d+1]={\n", Limit);
+
+    odp = OrdinalDefinitions;
+    for (i = 0; i <= Limit; i++, odp++)
+    {
+        fdp = odp->additional_data;
+        rdp = odp->additional_data;
+
+        switch (odp->type)
+        {
+        case TYPE_INVALID:
+            printf( "{0,%s_%d},\n",UpperDLLName, i);
+            break;
+        case TYPE_RETURN:
+        case TYPE_STDCALL:
+        case TYPE_STUB:
+            printf( "{\"%s\",%s_%d},\n", odp->export_name, UpperDLLName, i);
+            break;
+        default:
+            fprintf(stderr, "build: implementation error: missing %d\n",
+                    odp->type);
+            exit(1);
+        }
+    }
+    printf("};\n\n");
+
+    printf( "static WIN32_builtin dll={\"%s\",functions,%d,0};\n",
+            UpperDLLName, Limit);
+
+    printf( "void %s_Init(void)\n{\n",UpperDLLName);
+    printf( "\tdll.next=WIN32_builtin_list;\n");
+    printf( "\tWIN32_builtin_list=&dll;\n}");
+}
+
+
+static void BuildSpec16Files( char *specname )
+{
+    ORDDEF *odp;
+    ORDFUNCDEF *fdp;
+    ORDRETDEF *rdp;
     int i;
     int code_offset, data_offset;
 
@@ -711,17 +848,15 @@
 
     ParseTopLevel();
 
-    sprintf(filename, "dll_%s.S", LowerDLLName);
-    fp = fopen(filename, "w");
-    fprintf( fp, "/* File generated automatically; do not edit! */\n" );
-    fprintf( fp, "\t.data\n" );
-    fprintf( fp, "\t.globl " PREFIX "%s_Data_Start\n", UpperDLLName );
-    fprintf( fp, PREFIX "%s_Data_Start:\n", UpperDLLName );
-    fprintf( fp, "\t.word 0,0,0,0,0,0,0,0\n" );
+    printf( "/* File generated automatically; do not edit! */\n" );
+    printf( "\t.data\n" );
+    printf( "\t.globl " PREFIX "%s_Data_Start\n", UpperDLLName );
+    printf( PREFIX "%s_Data_Start:\n", UpperDLLName );
+    printf( "\t.word 0,0,0,0,0,0,0,0\n" );
     data_offset = 16;
-    fprintf( fp, "\t.text\n" );
-    fprintf( fp, "\t.globl " PREFIX "%s_Code_Start\n", UpperDLLName );
-    fprintf( fp, PREFIX "%s_Code_Start:\n", UpperDLLName );
+    printf( "\t.text\n" );
+    printf( "\t.globl " PREFIX "%s_Code_Start\n", UpperDLLName );
+    printf( PREFIX "%s_Code_Start:\n", UpperDLLName );
     code_offset = 0;
 
     odp = OrdinalDefinitions;
@@ -741,32 +876,32 @@
             break;
 
           case TYPE_BYTE:
-            fprintf( fp, "/* %s.%d */\n", UpperDLLName, i);
+            printf( "/* %s.%d */\n", UpperDLLName, i);
             odp->offset = data_offset;
-            data_offset += OutputVariableCode(fp, ".byte", odp);
+            data_offset += OutputVariableCode( ".byte", odp);
             break;
 
           case TYPE_WORD:
-            fprintf( fp, "/* %s.%d */\n", UpperDLLName, i);
+            printf( "/* %s.%d */\n", UpperDLLName, i);
             odp->offset = data_offset;
-            data_offset += 2 * OutputVariableCode(fp, ".word", odp);
+            data_offset += 2 * OutputVariableCode( ".word", odp);
             break;
 
           case TYPE_LONG:
-            fprintf( fp, "/* %s.%d */\n", UpperDLLName, i);
+            printf( "/* %s.%d */\n", UpperDLLName, i);
             odp->offset = data_offset;
-            data_offset += 4 * OutputVariableCode(fp, ".long", odp);
+            data_offset += 4 * OutputVariableCode( ".long", odp);
             break;
 
           case TYPE_RETURN:
-            fprintf( fp, "/* %s.%d */\n", UpperDLLName, i);
-            fprintf( fp, "\tmovw $%d,%%ax\n", rdp->ret_value & 0xffff );
-            fprintf( fp, "\tmovw $%d,%%dx\n", (rdp->ret_value >> 16) & 0xffff);
-            fprintf(fp, "\t.byte 0x66\n");
+            printf( "/* %s.%d */\n", UpperDLLName, i);
+            printf( "\tmovw $%d,%%ax\n", rdp->ret_value & 0xffff );
+            printf( "\tmovw $%d,%%dx\n", (rdp->ret_value >> 16) & 0xffff);
+            printf( "\t.byte 0x66\n");
             if (rdp->arg_size != 0)
-                fprintf(fp, "\tlret $%d\n", rdp->arg_size);
+                printf( "\tlret $%d\n", rdp->arg_size);
             else
-                fprintf(fp, "\tlret\n");
+                printf( "\tlret\n");
             odp->offset = code_offset;
             code_offset += 10;  /* Assembly code is 10 bytes long */
             if (rdp->arg_size != 0) code_offset += 2;
@@ -776,17 +911,22 @@
           case TYPE_PASCAL:
           case TYPE_PASCAL_16:
           case TYPE_STUB:
-            fprintf( fp, "/* %s.%d */\n", UpperDLLName, i);
-            fprintf(fp, "\tpushw %%bp\n" );
-            fprintf(fp, "\tpushl $0x%08x\n", (DLLId << 16) | i);
-            fprintf(fp, "\tpushl $" PREFIX "%s\n", fdp->internal_name );
-            fprintf(fp, "\tljmp $0x%04x, $" PREFIX "CallTo32_%s_%s\n\n",
-                        WINE_CODE_SELECTOR,
-                        (odp->type == TYPE_REGISTER) ? "regs" :
-                        (odp->type == TYPE_PASCAL) ? "long" : "word",
-                        fdp->arg_types );
+            printf( "/* %s.%d */\n", UpperDLLName, i);
+            printf( "\tpushw %%bp\n" );
+            printf( "\tpushl $0x%08x\n", (DLLId << 16) | i);
+            printf( "\tpushl $" PREFIX "%s\n", fdp->internal_name );
+            printf( "\tljmp $0x%04x, $" PREFIX "CallTo32_%s_%s\n\n",
+                    WINE_CODE_SELECTOR,
+                    (odp->type == TYPE_REGISTER) ? "regs" :
+                    (odp->type == TYPE_PASCAL) ? "long" : "word",
+                    fdp->arg_types );
+            printf( "\tnop\n" );
+            printf( "\tnop\n" );
+            printf( "\tnop\n" );
+            printf( "\tnop\n" );
+            printf( "\tnop\n" );
             odp->offset = code_offset;
-            code_offset += 19;  /* Assembly code is 19 bytes long */
+            code_offset += 24;  /* Assembly code is 24 bytes long */
             break;
 		
           default:
@@ -797,74 +937,11 @@
 
     if (!code_offset)  /* Make sure the code segment is not empty */
     {
-        fprintf( fp, "\t.byte 0\n" );
+        printf( "\t.byte 0\n" );
         code_offset++;
     }
 
-    BuildModule( fp, code_offset, data_offset );
-
-    fclose(fp);
-
-    sprintf(filename, "tab_%s.c", LowerDLLName);
-    fp = fopen(filename, "w");
-
-    fprintf( fp, "/* File generated automatically; do not edit! */\n\n" );
-    fprintf( fp, "#include \"dlls.h\"\n\n" );
-    fprintf( fp, "static struct dll_table_entry_s %s_table_entries[%d] =\n{\n",
-                 UpperDLLName, Limit + 1);
-    odp = OrdinalDefinitions;
-    for (i = 0; i <= Limit; i++, odp++)
-    {
-        int selector = 0;
-
-	switch (odp->type)
-	{
-        case TYPE_INVALID:
-            selector = 0;  /* Invalid selector */
-            break;
-
-        case TYPE_PASCAL:
-        case TYPE_PASCAL_16:
-        case TYPE_REGISTER:
-        case TYPE_RETURN:
-        case TYPE_STUB:
-            selector = 1;  /* Code selector */
-            break;
-
-        case TYPE_BYTE:
-        case TYPE_WORD:
-        case TYPE_LONG:
-            selector = 2;  /* Data selector */
-            break;
-
-        case TYPE_ABS:
-            selector = 0xff;  /* Constant selector */
-            break;
-        }
-
-/*         fprintf(fp, "    { %d, %d, ", selector, odp->offset ); */
-        fprintf( fp, "    { " );
-        fprintf(fp, "\"%s\" ", odp->export_name);
-#ifdef WINESTAT
-        fprintf(fp, ",0 ");
-#endif	    
-        fprintf(fp, "}, \n");
-    }
-
-    fprintf(fp, "};\n\n");
-
-    fprintf( fp, "extern BYTE %s_Code_Start[];\n", UpperDLLName );
-    fprintf( fp, "extern BYTE %s_Data_Start[];\n", UpperDLLName );
-    fprintf( fp, "extern BYTE %s_Module_Start[];\n", UpperDLLName );
-    fprintf( fp, "extern BYTE %s_Module_End[];\n\n", UpperDLLName );
-    fprintf( fp, "struct dll_table_s %s_table =\n{\n", UpperDLLName );
-    fprintf( fp, "  %s_table_entries, %d, %d,\n",
-             UpperDLLName, Limit + 1, DLLId );
-    fprintf( fp, "  %s_Code_Start, %s_Data_Start,\n",
-             UpperDLLName, UpperDLLName );
-    fprintf( fp, "  %s_Module_Start, %s_Module_End\n};\n",
-             UpperDLLName, UpperDLLName );
-    fclose(fp);
+    BuildModule( code_offset, data_offset );
 }
 
 
@@ -1410,9 +1487,13 @@
 
     if (argc <= 2) usage();
 
-    if (!strcmp( argv[1], "-spec" ))
+    if (!strcmp( argv[1], "-spec16" ))
     {
-        for (i = 2; i < argc; i++) BuildSpecFiles( argv[i] );
+        for (i = 2; i < argc; i++) BuildSpec16Files( argv[i] );
+    }
+    else if (!strcmp( argv[1], "-spec32" ))
+    {
+        for (i = 2; i < argc; i++) BuildSpec32Files( argv[i] );
     }
     else if (!strcmp( argv[1], "-call32" ))  /* 32-bit callbacks */
     {
diff --git a/windows/Imakefile b/windows/Imakefile
index 47e6796..973215f 100644
--- a/windows/Imakefile
+++ b/windows/Imakefile
@@ -18,6 +18,7 @@
 	mapping.c \
 	mdi.c \
 	message.c \
+	msgbox.c \
 	nonclient.c \
 	painting.c \
 	property.c \
diff --git a/windows/class.c b/windows/class.c
index 6ce7cc6..a589ae2 100644
--- a/windows/class.c
+++ b/windows/class.c
@@ -55,7 +55,12 @@
     for (class = firstClass; (class); class = classPtr->hNext)
     {
         classPtr = (CLASS *) USER_HEAP_LIN_ADDR(class);
-        if (!(classPtr->wc.style & CS_GLOBALCLASS)) continue;
+#if 0
+      /* This breaks Borland's Resource Workshop: A DLL creates a class,
+       * and the main program tries to use it, but passes a different
+       * hInstance */
+      if (!(classPtr->wc.style & CS_GLOBALCLASS)) continue;
+#endif
         if (classPtr->atomName == atom)
         {
             if (ptr) *ptr = classPtr;
@@ -93,9 +98,9 @@
     int classExtra;
     char *name = PTR_SEG_TO_LIN( class->lpszClassName );
 
-    dprintf_class(stddeb, "RegisterClass: wndproc=%p hinst=%d name='%s' background %x\n", 
-	    class->lpfnWndProc, class->hInstance, name, class->hbrBackground );
-
+    dprintf_class(stddeb, "RegisterClass: wndproc=%08lx hinst=%d name='%s' background %04x\n",
+	    (DWORD)class->lpfnWndProc, class->hInstance, name, class->hbrBackground );
+    dprintf_class(stddeb, "               style %04x\n",class->style);
       /* Check if a class with this name already exists */
 
     prevClass = CLASS_FindClassByName( name, class->hInstance, &prevClassPtr );
diff --git a/windows/cursor.c b/windows/cursor.c
index 509fbf4..f9e976e 100644
--- a/windows/cursor.c
+++ b/windows/cursor.c
@@ -15,7 +15,6 @@
 #include "windows.h"
 #include "win.h"
 #include "gdi.h"
-#include "library.h"
 #include "neexe.h"
 #include "wine.h"
 #include "cursor.h"
@@ -61,7 +60,7 @@
     CURSORDESCRIP *lpcurdesc;
     CURSORALLOC	  *lpcur;
     HDC 	hdc;
-    int i, image_size;
+    int i;
     unsigned char *cp1,*cp2;
     dprintf_resource(stddeb,"LoadCursor: instance = %04x, name = %08lx\n",
 	   instance, cursor_name);
@@ -145,7 +144,6 @@
 	}
     lpcurdesc = (CURSORDESCRIP *)(lp + 3);
 #if 0
-    dprintf_cursor(stddeb,"LoadCursor / image_size=%d\n", image_size);
     dprintf_cursor(stddeb,"LoadCursor / curReserved=%X\n", *lp);
     dprintf_cursor(stddeb,"LoadCursor / curResourceType=%X\n", *(lp + 1));
     dprintf_cursor(stddeb,"LoadCursor / curResourceCount=%X\n", *(lp + 2));
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 7417429..b1c95e6 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -44,7 +44,6 @@
  */
 LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam )
 {
-    MEASUREITEMSTRUCT *measure;
     CLASS * classPtr;
     LPSTR textPtr;
     int len;
@@ -233,26 +232,7 @@
 	break;
 
     case WM_SYSKEYUP:
-		break;    	
-    case WM_MEASUREITEM:
-		measure = (MEASUREITEMSTRUCT *)PTR_SEG_TO_LIN(lParam);
-		switch(measure->CtlType) {
-			case ODT_BUTTON:
-				break;
-			case ODT_COMBOBOX:
-				measure->itemHeight = 10;
-/*				printf("defwndproc WM_MEASUREITEM // ODT_COMBOBOX !\n");*/
-				break;
-			case ODT_LISTBOX:
-				measure->itemHeight = 10;
-/*				printf("defwndproc WM_MEASUREITEM // ODT_LISTBOX !\n");*/
-				break;
-			case ODT_MENU:
-				break;
-			default:
-				break;
-			}
-    	break;    	
+		break;
     }
     return 0;
 }
diff --git a/windows/dialog.c b/windows/dialog.c
index aef8c7c..d7c7926 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -13,6 +13,7 @@
 #include "dialog.h"
 #include "win.h"
 #include "ldt.h"
+#include "stackframe.h"
 #include "user.h"
 #include "message.h"
 #include "stddebug.h"
@@ -191,8 +192,8 @@
     HGLOBAL hmem;
     LPCSTR data;
 
-    dprintf_dialog(stddeb, "CreateDialogParam: %d,%08lx,%d,%p,%ld\n",
-	    hInst, dlgTemplate, owner, dlgProc, param );
+    dprintf_dialog(stddeb, "CreateDialogParam: %d,%08lx,%d,%08lx,%ld\n",
+	    hInst, dlgTemplate, owner, (DWORD)dlgProc, param );
      
     if (!(hRsrc = FindResource( hInst, dlgTemplate, RT_DIALOG ))) return 0;
     if (!(hmem = LoadResource( hInst, hRsrc ))) return 0;
@@ -251,11 +252,11 @@
 	  break;
       default:
           {
-                /* Need to copy the menu name to a 16-bit area */
-              HANDLE handle = USER_HEAP_ALLOC( strlen(template.menuName)+1 );
-              strcpy( USER_HEAP_LIN_ADDR( handle ), template.menuName );
-              hMenu = LoadMenu( hInst, USER_HEAP_SEG_ADDR( handle ) );
-              USER_HEAP_FREE( handle );
+                /* Need to copy the menu name to a 16-bit accessible area */
+              char name[256];
+              strncpy( name, template.menuName, 255 );
+              name[255] = '\0';
+              hMenu = LoadMenu( hInst, MAKE_SEGPTR(name) );
           }
 	  break;
     }
@@ -298,7 +299,7 @@
     AdjustWindowRectEx( &rect, template.header->style, hMenu, exStyle );
 
     hwnd = CreateWindowEx( exStyle, template.className, template.caption,
-			   template.header->style,
+			   template.header->style & ~WS_VISIBLE,
 			   rect.left + template.header->x * xUnit / 4,
 			   rect.top + template.header->y * yUnit / 8,
 			   rect.right - rect.left, rect.bottom - rect.top,
@@ -397,7 +398,7 @@
 	SendMessage( hwnd, WM_SETFONT, dlgInfo->hUserFont, 0 );
     if (SendMessage( hwnd, WM_INITDIALOG, dlgInfo->hwndFocus, param ))
 	SetFocus( dlgInfo->hwndFocus );
-
+    ShowWindow(hwnd, SW_SHOW);
     return hwnd;
 }
 
@@ -459,8 +460,8 @@
 {
     HWND hwnd;
     
-    dprintf_dialog(stddeb, "DialogBoxParam: %d,%08lx,%d,%p,%ld\n",
-	    hInst, dlgTemplate, owner, dlgProc, param );
+    dprintf_dialog(stddeb, "DialogBoxParam: %d,%08lx,%d,%08lx,%ld\n",
+	    hInst, dlgTemplate, owner, (DWORD)dlgProc, param );
     hwnd = CreateDialogParam( hInst, dlgTemplate, owner, dlgProc, param );
     if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
     return -1;
@@ -690,14 +691,11 @@
  */
 void SetDlgItemInt( HWND hwnd, WORD id, WORD value, BOOL fSigned )
 {
-    HANDLE hText = USER_HEAP_ALLOC( 10 );
-    char * str = (char *) USER_HEAP_LIN_ADDR( hText );
+    char str[20];
 
-    if (fSigned) sprintf( str, "%d", value );
+    if (fSigned) sprintf( str, "%d", (int)value );
     else sprintf( str, "%u", value );
-    SendDlgItemMessage( hwnd, id, WM_SETTEXT, 0,
-                        USER_HEAP_SEG_ADDR(hText) );
-    USER_HEAP_FREE( hText );
+    SendDlgItemMessage( hwnd, id, WM_SETTEXT, 0, MAKE_SEGPTR(str) );
 }
 
 
@@ -706,18 +704,11 @@
  */
 WORD GetDlgItemInt( HWND hwnd, WORD id, BOOL * translated, BOOL fSigned )
 {
-    int len;
-    HANDLE hText;
+    char str[30];
     long result = 0;
-    char * str;
     
     if (translated) *translated = FALSE;
-    if (!(len = SendDlgItemMessage( hwnd, id, WM_GETTEXTLENGTH, 0, 0 )))
-	return 0;
-    if (!(hText = USER_HEAP_ALLOC( len+1 ))) return 0;
-    str = (char *) USER_HEAP_LIN_ADDR( hText );
-    if (SendDlgItemMessage( hwnd, id, WM_GETTEXT, len+1,
-                            USER_HEAP_SEG_ADDR(hText) ))
+    if (SendDlgItemMessage( hwnd, id, WM_GETTEXT, 30, MAKE_SEGPTR(str) ))
     {
 	char * endptr;
 	result = strtol( str, &endptr, 10 );
@@ -735,7 +726,6 @@
 	    }
 	}
     }
-    USER_HEAP_FREE( hText );
     return (WORD)result;
 }
 
@@ -888,7 +878,7 @@
 	if (!hwnd) hwnd = dlgPtr->hwndChild;
 	if (hwnd == hwndCtrl) break;
 	wndPtr = WIN_FindWndPtr( hwnd );
-	if (wndPtr->dwStyle & WS_TABSTOP)
+	if ((wndPtr->dwStyle & WS_TABSTOP) && (wndPtr->dwStyle & WS_VISIBLE))
 	{
 	    hwndLast = hwnd;
 	    if (!fPrevious) break;
diff --git a/windows/event.c b/windows/event.c
index 63bb4e2..05c21ce 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -1,11 +1,11 @@
 /*
  * X events handling functions
- *
+ * 
  * Copyright 1993 Alexandre Julliard
- *
-static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
-*/
+ * 
+ */
 
+#include <ctype.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <X11/Xlib.h>
@@ -322,10 +322,10 @@
     }
     else if (key_type == 0)                        /* character key */
     {
-	if (key >= 0x61 && key <= 0x7A)
-	    vkey = key - 0x20;                 /* convert lower to uppercase */
+	if (isalnum(key))
+	    vkey = toupper(key);                 /* convert lower to uppercase */
 	else
-	    vkey = key;
+	    vkey = 0xbe;
     }
 
     if (event->type == KeyPress)
@@ -527,6 +527,11 @@
     Window win;
     HWND old_capture_wnd = captureWnd;
 
+    if (!hwnd)
+    {
+        ReleaseCapture();
+        return old_capture_wnd;
+    }
     if (!(win = WIN_GetXWindow( hwnd ))) return 0;
     if (XGrabPointer(display, win, False, 
                      ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
diff --git a/windows/mdi.c b/windows/mdi.c
index b03a2e1..53d35f4 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -58,6 +58,19 @@
     }
 }
 
+
+/**********************************************************************
+ *					MDIIconArrange
+ */
+WORD
+MDIIconArrange(HWND parent)
+{
+  return ArrangeIconicWindows(parent);		/* Any reason why the    */
+						/* existing icon arrange */
+						/* can't be used here?	 */
+						/* -DRP			 */
+}
+
 /**********************************************************************
  *					MDICreateChild
  */
@@ -66,12 +79,19 @@
 {
     MDICREATESTRUCT *cs = (MDICREATESTRUCT *)PTR_SEG_TO_LIN(lParam);
     HWND hwnd;
+    int spacing;
 
     /*
      * Create child window
      */
     cs->style &= (WS_MINIMIZE | WS_MAXIMIZE | WS_HSCROLL | WS_VSCROLL);
-    
+
+				/* The child windows should probably  */
+				/* stagger, shouldn't they? -DRP      */
+    spacing = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME);
+    cs->x = ci->nActiveChildren * spacing;  
+    cs->y = ci->nActiveChildren * spacing;
+
     hwnd = CreateWindowEx(0, PTR_SEG_TO_LIN(cs->szClass),
                           PTR_SEG_TO_LIN(cs->szTitle), 
 			  WS_CHILD | WS_BORDER | WS_CAPTION | WS_CLIPSIBLINGS |
@@ -293,6 +313,7 @@
 
     ShowWindow(child, SW_RESTORE);		/* display the window */
     MDIBringChildToTop(parent, child, FALSE, FALSE);
+    SendMessage(GetParent(parent), WM_NCPAINT, 0, 0);
 
     return 0;
 }
@@ -612,8 +633,7 @@
 		((LONG) ci->flagChildMaximized << 16));
 
       case WM_MDIICONARRANGE:
-	/* return MDIIconArrange(...) */
-	break;
+	return MDIIconArrange(hwnd);
 	
       case WM_MDIMAXIMIZE:
 	return MDIMaximizeChild(hwnd, wParam, ci);
diff --git a/windows/message.c b/windows/message.c
index 4d18594..c219424 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -4,11 +4,6 @@
  * Copyright 1993, 1994 Alexandre Julliard
  */
 
-/*
- * This code assumes that there is only one Windows task (hence
- * one message queue).
- */
-
 #include <stdlib.h>
 #include <sys/time.h>
 #include <sys/types.h>
@@ -861,27 +856,27 @@
     WND 	*wndPtr;
 
     if (hwnd == HWND_BROADCAST) {
-	    dprintf_msg(stddeb,"PostMessage // HWND_BROADCAST !\n");
-	    hwnd = GetTopWindow(GetDesktopWindow());
-	    while (hwnd) {
-	        if (!(wndPtr = WIN_FindWndPtr(hwnd))) break;
-			if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION) {
-				dprintf_msg(stddeb,"BROADCAST Message to hWnd=%04X m=%04X w=%04X l=%08lX !\n", 
-							hwnd, message, wParam, lParam);
-				PostMessage(hwnd, message, wParam, lParam);
-				}
-/*				{
-				char	str[128];
-				GetWindowText(hwnd, str, sizeof(str));
-				dprintf_msg(stddeb, "BROADCAST GetWindowText()='%s' !\n", str); 
-				}*/
-			hwnd = wndPtr->hwndNext;
-			}
-		dprintf_msg(stddeb,"PostMessage // End of HWND_BROADCAST !\n");
-		return TRUE;
-		}
+      dprintf_msg(stddeb,"PostMessage // HWND_BROADCAST !\n");
+      hwnd = GetTopWindow(GetDesktopWindow());
+      while (hwnd) {
+	if (!(wndPtr = WIN_FindWndPtr(hwnd))) break;
+	if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION) {
+	  dprintf_msg(stddeb,"BROADCAST Message to hWnd=%04X m=%04X w=%04X l=%08lX !\n",
+		      hwnd, message, wParam, lParam);
+	  PostMessage(hwnd, message, wParam, lParam);
+	}
+	/*{
+	  char	str[128];
+	  GetWindowText(hwnd, str, sizeof(str));
+	  dprintf_msg(stddeb, "BROADCAST GetWindowText()='%s' !\n", str); 
+	}*/
+	hwnd = wndPtr->hwndNext;
+      }
+      dprintf_msg(stddeb,"PostMessage // End of HWND_BROADCAST !\n");
+      return TRUE;
+    }
 
-	wndPtr = WIN_FindWndPtr( hwnd );
+    wndPtr = WIN_FindWndPtr( hwnd );
     if (!wndPtr || !wndPtr->hmemTaskQ) return FALSE;
     msg.hwnd    = hwnd;
     msg.message = message;
@@ -894,6 +889,25 @@
     return MSG_AddMsg( wndPtr->hmemTaskQ, &msg, 0 );
 }
 
+/***********************************************************************
+ *           PostAppMessage   (USER.116)
+ */
+BOOL PostAppMessage( HTASK hTask, WORD message, WORD wParam, LONG lParam )
+{
+    MSG 	msg;
+
+    if (GetTaskQueue(hTask) == 0) return FALSE;
+    msg.hwnd    = 0;
+    msg.message = message;
+    msg.wParam  = wParam;
+    msg.lParam  = lParam;
+    msg.time    = GetTickCount();
+    msg.pt.x    = 0;
+    msg.pt.y    = 0;
+
+    return MSG_AddMsg( GetTaskQueue(hTask), &msg, 0 );
+}
+
 
 /***********************************************************************
  *           SendMessage   (USER.111)
diff --git a/windows/msgbox.c b/windows/msgbox.c
new file mode 100644
index 0000000..8e4aec4
--- /dev/null
+++ b/windows/msgbox.c
@@ -0,0 +1,196 @@
+/*
+ * Message boxes
+ *
+ * Copyright 1995 Bernd Schmidt
+ *
+ */
+
+#include "windows.h"
+#include "dlgs.h"
+#include "dialog.h"
+#include "selectors.h"
+#include "../rc/sysres.h"
+#include "task.h"
+
+typedef struct {
+  LPSTR	title;
+  LPSTR text;
+  WORD  type;
+} MSGBOX, *LPMSGBOX;
+
+LONG SystemMessageBoxProc(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+{
+  LPMSGBOX lpmb;
+  RECT rect, textrect;
+  HWND hItem;
+  HDC hdc;
+  LONG lRet;
+  int i, buttons, bwidth, bheight, theight, wwidth, bpos;
+  int borheight, iheight, tiheight;
+  
+  switch(message) {
+   case WM_INITDIALOG:
+    lpmb = (LPMSGBOX)lParam;
+    if (lpmb->title != NULL) {
+      SetWindowText(hwnd, lpmb->title);
+    }
+    SetWindowText(GetDlgItem(hwnd, 100), lpmb->text);
+    /* Hide not selected buttons */
+    switch(lpmb->type & MB_TYPEMASK) {
+     case MB_OK:
+      ShowWindow(GetDlgItem(hwnd, 2), SW_HIDE);
+      /* fall through */
+     case MB_OKCANCEL:
+      ShowWindow(GetDlgItem(hwnd, 3), SW_HIDE);
+      ShowWindow(GetDlgItem(hwnd, 4), SW_HIDE);
+      ShowWindow(GetDlgItem(hwnd, 5), SW_HIDE);
+      ShowWindow(GetDlgItem(hwnd, 6), SW_HIDE);
+      ShowWindow(GetDlgItem(hwnd, 7), SW_HIDE);
+      break;
+     case MB_ABORTRETRYIGNORE:
+      ShowWindow(GetDlgItem(hwnd, 1), SW_HIDE);
+      ShowWindow(GetDlgItem(hwnd, 2), SW_HIDE);
+      ShowWindow(GetDlgItem(hwnd, 6), SW_HIDE);
+      ShowWindow(GetDlgItem(hwnd, 7), SW_HIDE);
+      break;
+     case MB_YESNO:
+      ShowWindow(GetDlgItem(hwnd, 2), SW_HIDE);
+      /* fall through */
+     case MB_YESNOCANCEL:
+      ShowWindow(GetDlgItem(hwnd, 1), SW_HIDE);
+      ShowWindow(GetDlgItem(hwnd, 3), SW_HIDE);
+      ShowWindow(GetDlgItem(hwnd, 4), SW_HIDE);
+      ShowWindow(GetDlgItem(hwnd, 5), SW_HIDE);
+      break;
+    }
+    /* Set the icon */
+    switch(lpmb->type & MB_ICONMASK) {
+     case MB_ICONEXCLAMATION:
+      SendDlgItemMessage(hwnd, stc1, STM_SETICON, LoadIcon(0, IDI_EXCLAMATION), 0);
+      break;
+     case MB_ICONQUESTION:
+      SendDlgItemMessage(hwnd, stc1, STM_SETICON, LoadIcon(0, IDI_QUESTION), 0);
+      break;
+     case MB_ICONASTERISK:
+      SendDlgItemMessage(hwnd, stc1, STM_SETICON, LoadIcon(0, IDI_ASTERISK), 0);
+      break;
+     case MB_ICONHAND:
+      SendDlgItemMessage(hwnd, stc1, STM_SETICON, LoadIcon(0, IDI_HAND), 0);
+      break;
+    }
+    
+    /* Position everything */
+    GetWindowRect(hwnd, &rect);
+    borheight = rect.bottom - rect.top;
+    wwidth = rect.right - rect.left;
+    GetClientRect(hwnd, &rect);
+    borheight -= rect.bottom - rect.top;
+
+    /* Get the icon height */
+    GetWindowRect(GetDlgItem(hwnd, 1088), &rect);
+    iheight = rect.bottom - rect.top;
+    
+    /* Get the number of visible buttons and their width */
+    GetWindowRect(GetDlgItem(hwnd, 2), &rect);
+    bheight = rect.bottom - rect.top;
+    bwidth = rect.left;
+    GetWindowRect(GetDlgItem(hwnd, 1), &rect);
+    bwidth -= rect.left;
+    for (buttons = 0, i = 1; i < 8; i++) {
+      hItem = GetDlgItem(hwnd, i);
+      if (GetWindowLong(hItem, GWL_STYLE) & WS_VISIBLE) {
+	buttons++;
+      }
+    }
+    
+    /* Get the text size */
+    hItem = GetDlgItem(hwnd, 100);
+    GetWindowRect(hItem, &textrect);
+    MapWindowPoints(0, hwnd, (LPPOINT)&textrect, 2);
+    
+    GetClientRect(hItem, &rect);
+    hdc = GetDC(hItem);
+    lRet = DrawText(hdc, lpmb->text, -1, &rect,
+		    DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK | DT_CALCRECT);
+    theight = rect.bottom  - rect.top;
+    tiheight = 16 + max(iheight, theight);
+    ReleaseDC(hItem, hdc);
+    
+    /* Position the text */
+    SetWindowPos(hItem, 0, textrect.left, (tiheight - theight) / 2, 
+		 rect.right - rect.left, theight,
+		 SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
+    
+    /* Position the icon */
+    hItem = GetDlgItem(hwnd, 1088);
+    GetWindowRect(hItem, &rect);
+    MapWindowPoints(0, hwnd, (LPPOINT)&rect, 2);
+    SetWindowPos(hItem, 0, rect.left, (tiheight - iheight) / 2, 0, 0,
+		 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
+    
+    /* Resize the window */
+    SetWindowPos(hwnd, 0, 0, 0, wwidth, 8 + tiheight + bheight + borheight,
+		 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
+    
+    /* Position the buttons */
+    bpos = (wwidth - bwidth * buttons) / 2;
+    GetWindowRect(GetDlgItem(hwnd, 1), &rect);
+    for (buttons = i = 0; i < 7; i++) {
+      /* some arithmetic to get the right order for YesNoCancel windows */
+      hItem = GetDlgItem(hwnd, (i + 5) % 7 + 1);
+      if (GetWindowLong(hItem, GWL_STYLE) & WS_VISIBLE) {
+	if (buttons++ == ((lpmb->type & MB_DEFMASK) >> 8)) {
+	  SetFocus(hItem);
+	  SendMessage(hItem, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE);
+	}
+	SetWindowPos(hItem, 0, bpos, tiheight, 0, 0,
+		     SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
+	bpos += bwidth;
+      }
+    }
+    return 0;
+    break;
+    
+   case WM_COMMAND:
+    switch (wParam) {
+     case IDOK:
+     case IDCANCEL:
+     case IDABORT:
+     case IDRETRY:
+     case IDIGNORE:
+     case IDYES:
+     case IDNO:
+      EndDialog(hwnd, wParam);
+      break;
+    }
+    break;
+  }
+  return 0;
+}
+
+/**************************************************************************
+ *			MessageBox  [USER.1]
+ */
+
+int MessageBox(HWND hWnd, LPSTR text, LPSTR title, WORD type)
+{
+  MSGBOX mbox;
+
+  mbox.title = title;
+  mbox.text  = text;
+  mbox.type  = type;
+  return DialogBoxIndirectParamPtr(GetWindowWord(hWnd, GWW_HINSTANCE),
+				   sysres_DIALOG_MSGBOX, hWnd,
+				   GetWndProcEntry16("SystemMessageBoxProc"),
+				   (LONG)&mbox);
+}
+
+/**************************************************************************
+ *			FatalAppExit  [USER.137]
+ */
+
+void FatalAppExit(WORD wAction, LPSTR str)
+{
+  MessageBox(0, str, NULL, MB_SYSTEMMODAL | MB_OK);
+  TASK_KillCurrentTask(0);
+}
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 9604d35..8af8dd3 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -12,7 +12,6 @@
 #include "user.h"
 #include "dialog.h"
 #include "syscolor.h"
-#include "library.h"
 #include "menu.h"
 #include "winpos.h"
 #include "scroll.h"
@@ -33,7 +32,6 @@
 static HBITMAP hbitmapRestoreD = 0;
 
 #define SC_ABOUTWINE    	(SC_SCREENSAVE+1)
-extern BOOL AboutWine_Proc( HWND hDlg, WORD msg, WORD wParam, LONG lParam );
 
   /* Some useful macros */
 #define HAS_DLGFRAME(style,exStyle) \
@@ -1312,7 +1310,7 @@
 	break;
 
     case SC_TASKLIST:
-	/* WinExec( "taskman.exe", SW_SHOWNORMAL ); */
+	WinExec( "taskman.exe", SW_SHOWNORMAL ); 
 	break;
 
     case SC_HOTKEY:
@@ -1320,9 +1318,9 @@
 
     case SC_SCREENSAVE:
 	if (wParam == SC_ABOUTWINE)
-	{   extern char sysres_DIALOG_2[];
-	    DialogBoxIndirectPtr( wndPtr->hInstance, sysres_DIALOG_2,
-		       hwnd, GetWndProcEntry16("AboutWine_Proc") );
+	{   
+	  extern const char people[];
+	  ShellAbout(hwnd,"WINE",people,0);
         }
 	break;
     }
diff --git a/windows/painting.c b/windows/painting.c
index 782626c..774081a 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -250,7 +250,7 @@
       /* Recursively process children */
 
     if (!(flags & RDW_NOCHILDREN) &&
-	((flags && RDW_ALLCHILDREN) || !(wndPtr->dwStyle & WS_CLIPCHILDREN)))
+	((flags & RDW_ALLCHILDREN) || !(wndPtr->dwStyle & WS_CLIPCHILDREN)))
     {
 	if (hrgnUpdate)
 	{
diff --git a/windows/property.c b/windows/property.c
index dfffc0b..f3e88ba 100644
--- a/windows/property.c
+++ b/windows/property.c
@@ -119,7 +119,7 @@
     HANDLE hProp;
     WND *wndPtr;
 
-    dprintf_prop( stddeb, "EnumProps: %04x %p\n", hwnd, func );
+    dprintf_prop( stddeb, "EnumProps: %04x %08lx\n", hwnd, (LONG)func );
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
     hProp = wndPtr->hProp;
     while (hProp)
diff --git a/windows/timer.c b/windows/timer.c
index 0d1b0af..96fff6a 100644
--- a/windows/timer.c
+++ b/windows/timer.c
@@ -213,7 +213,7 @@
  */
 WORD SetTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc )
 {
-    dprintf_timer(stddeb, "SetTimer: %d %d %d %p\n", hwnd, id, timeout, proc );
+    dprintf_timer(stddeb, "SetTimer: %d %d %d %08lx\n", hwnd, id, timeout, (LONG)proc );
     return TIMER_SetTimer( hwnd, id, timeout, proc, FALSE );
 }
 
@@ -223,8 +223,8 @@
  */
 WORD SetSystemTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc )
 {
-    dprintf_timer(stddeb, "SetSystemTimer: %d %d %d %p\n", 
-		  hwnd, id, timeout, proc );
+    dprintf_timer(stddeb, "SetSystemTimer: %d %d %d %08lx\n", 
+		  hwnd, id, timeout, (LONG)proc );
     return TIMER_SetTimer( hwnd, id, timeout, proc, TRUE );
 }
 
diff --git a/windows/win.c b/windows/win.c
index fc63ae8..29dc18a 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -215,6 +215,7 @@
     WND *wndPtr;
     HCLASS hclass;
     CLASS *classPtr;
+    HDC hdc;
 
     if (!(hclass = CLASS_FindClassByName( DESKTOP_CLASS_NAME, 0, &classPtr )))
 	return FALSE;
@@ -256,6 +257,12 @@
     wndPtr->hSysMenu          = 0;
     wndPtr->hProp	      = 0;
     EVENT_RegisterWindow( wndPtr->window, hwndDesktop );
+    SendMessage( hwndDesktop, WM_NCCREATE, 0, 0 );
+    if ((hdc = GetDC( hwndDesktop )) != 0)
+    {
+        SendMessage( hwndDesktop, WM_ERASEBKGND, hdc, 0 );
+        ReleaseDC( hwndDesktop, hdc );
+    }
     return TRUE;
 }
 
@@ -283,8 +290,8 @@
     CLASS *classPtr;
     WND *wndPtr;
     POINT maxSize, maxPos, minTrack, maxTrack;
-    CREATESTRUCT *createStruct;
-    HANDLE hcreateStruct, hwinName, hclassName;
+    CREATESTRUCT createStruct;
+    HANDLE hwinName, hclassName;
     int wmcreate;
     XSetWindowAttributes win_attr;
 
@@ -453,35 +460,32 @@
 
       /* Send the WM_CREATE message */
 
-    hcreateStruct = USER_HEAP_ALLOC( sizeof(CREATESTRUCT) );
     hclassName = USER_HEAP_ALLOC( strlen(className)+1 );
     strcpy( USER_HEAP_LIN_ADDR(hclassName), className );
-    createStruct = (CREATESTRUCT *) USER_HEAP_LIN_ADDR( hcreateStruct );
-    createStruct->lpCreateParams = (LPSTR)data;
-    createStruct->hInstance      = instance;
-    createStruct->hMenu          = menu;
-    createStruct->hwndParent     = parent;
-    createStruct->cx             = width;
-    createStruct->cy             = height;
-    createStruct->x              = x;
-    createStruct->y              = y;
-    createStruct->style          = style;
-    createStruct->lpszClass      = (LPSTR)USER_HEAP_SEG_ADDR(hclassName);
-    createStruct->dwExStyle      = 0;
+    createStruct.lpCreateParams = (LPSTR)data;
+    createStruct.hInstance      = instance;
+    createStruct.hMenu          = menu;
+    createStruct.hwndParent     = parent;
+    createStruct.cx             = width;
+    createStruct.cy             = height;
+    createStruct.x              = x;
+    createStruct.y              = y;
+    createStruct.style          = style;
+    createStruct.lpszClass      = (LPSTR)USER_HEAP_SEG_ADDR(hclassName);
+    createStruct.dwExStyle      = 0;
     if (windowName)
     {
         hwinName = USER_HEAP_ALLOC( strlen(windowName)+1 );
         strcpy( USER_HEAP_LIN_ADDR(hwinName), windowName );
-        createStruct->lpszName = (LPSTR)USER_HEAP_SEG_ADDR(hwinName);
+        createStruct.lpszName = (LPSTR)USER_HEAP_SEG_ADDR(hwinName);
     }
     else
     {
         hwinName = 0;
-        createStruct->lpszName = NULL;
+        createStruct.lpszName = NULL;
     }
 
-    wmcreate = SendMessage( hwnd, WM_NCCREATE, 0,
-                            USER_HEAP_SEG_ADDR(hcreateStruct) );
+    wmcreate = SendMessage( hwnd, WM_NCCREATE, 0, MAKE_SEGPTR(&createStruct) );
     if (!wmcreate) {
 		dprintf_win(stddeb,"CreateWindowEx: WM_NCCREATE return 0\n");
 		wmcreate = -1;
@@ -490,11 +494,9 @@
     {
 	WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
 			       NULL, NULL, NULL, &wndPtr->rectClient );
-	wmcreate = SendMessage( hwnd, WM_CREATE, 0,
-                                USER_HEAP_SEG_ADDR(hcreateStruct) );
+	wmcreate = SendMessage(hwnd, WM_CREATE, 0, MAKE_SEGPTR(&createStruct));
     }
 
-    USER_HEAP_FREE( hcreateStruct );
     USER_HEAP_FREE( hclassName );
     if (hwinName) USER_HEAP_FREE( hwinName );
 
diff --git a/windows/winpos.c b/windows/winpos.c
index b1f7139..bab8113 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -8,6 +8,7 @@
 #include "user.h"
 #include "win.h"
 #include "message.h"
+#include "stackframe.h"
 #include "winpos.h"
 #include "nonclient.h"
 #include "stddebug.h"
@@ -599,23 +600,19 @@
 			    RECT *oldWindowRect, RECT *oldClientRect,
 			    WINDOWPOS *winpos, RECT *newClientRect )
 {
-    NCCALCSIZE_PARAMS *params;
-    HANDLE hparams;
+    NCCALCSIZE_PARAMS params;
     LONG result;
 
-    if (!(hparams = USER_HEAP_ALLOC( sizeof(*params) ))) return 0;
-    params = (NCCALCSIZE_PARAMS *) USER_HEAP_LIN_ADDR( hparams );
-    params->rgrc[0] = *newWindowRect;
+    params.rgrc[0] = *newWindowRect;
     if (calcValidRect)
     {
-	params->rgrc[1] = *oldWindowRect;
-	params->rgrc[2] = *oldClientRect;
-	params->lppos = winpos;
+	params.rgrc[1] = *oldWindowRect;
+	params.rgrc[2] = *oldClientRect;
+	params.lppos = winpos;
     }
     result = SendMessage( hwnd, WM_NCCALCSIZE, calcValidRect,
-                          USER_HEAP_SEG_ADDR(hparams) );
-    *newClientRect = params->rgrc[0];
-    USER_HEAP_FREE( hparams );
+                          MAKE_SEGPTR( &params ) );
+    *newClientRect = params.rgrc[0];
     return result;
 }
 
@@ -763,8 +760,7 @@
 BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y,
 		   INT cx, INT cy, WORD flags )
 {
-    HLOCAL hWinPos;
-    WINDOWPOS *winpos;
+    WINDOWPOS winpos;
     WND *wndPtr;
     RECT newWindowRect, newClientRect;
     int result;
@@ -805,67 +801,63 @@
     if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM) &&
 	(GetParent(hwnd) != GetParent(hwndInsertAfter))) return FALSE;
 
-      /* Allocate the WINDOWPOS structure */
+      /* Fill the WINDOWPOS structure */
 
-    hWinPos = USER_HEAP_ALLOC( sizeof(WINDOWPOS) );
-    if (!hWinPos) return FALSE;
-    winpos = USER_HEAP_LIN_ADDR( hWinPos );
-    winpos->hwnd = hwnd;
-    winpos->hwndInsertAfter = hwndInsertAfter;
-    winpos->x = x;
-    winpos->y = y;
-    winpos->cx = cx;
-    winpos->cy = cy;
-    winpos->flags = flags;
+    winpos.hwnd = hwnd;
+    winpos.hwndInsertAfter = hwndInsertAfter;
+    winpos.x = x;
+    winpos.y = y;
+    winpos.cx = cx;
+    winpos.cy = cy;
+    winpos.flags = flags;
     
       /* Send WM_WINDOWPOSCHANGING message */
 
     if (!(flags & SWP_NOSENDCHANGING))
-	SendMessage( hwnd, WM_WINDOWPOSCHANGING, 0,
-                     USER_HEAP_SEG_ADDR(hWinPos) );
+	SendMessage( hwnd, WM_WINDOWPOSCHANGING, 0, MAKE_SEGPTR(&winpos) );
 
       /* Calculate new position and size */
 
     newWindowRect = wndPtr->rectWindow;
     newClientRect = wndPtr->rectClient;
 
-    if (!(winpos->flags & SWP_NOSIZE))
+    if (!(winpos.flags & SWP_NOSIZE))
     {
-        newWindowRect.right  = newWindowRect.left + winpos->cx;
-        newWindowRect.bottom = newWindowRect.top + winpos->cy;
+        newWindowRect.right  = newWindowRect.left + winpos.cx;
+        newWindowRect.bottom = newWindowRect.top + winpos.cy;
     }
-    if (!(winpos->flags & SWP_NOMOVE))
+    if (!(winpos.flags & SWP_NOMOVE))
     {
-        newWindowRect.left    = winpos->x;
-        newWindowRect.top     = winpos->y;
-        newWindowRect.right  += winpos->x - wndPtr->rectWindow.left;
-        newWindowRect.bottom += winpos->y - wndPtr->rectWindow.top;
+        newWindowRect.left    = winpos.x;
+        newWindowRect.top     = winpos.y;
+        newWindowRect.right  += winpos.x - wndPtr->rectWindow.left;
+        newWindowRect.bottom += winpos.y - wndPtr->rectWindow.top;
     }
 
       /* Reposition window in Z order */
 
-    if (!(winpos->flags & SWP_NOZORDER))
+    if (!(winpos.flags & SWP_NOZORDER))
     {
         if (wndPtr->window)
         {
-            WIN_UnlinkWindow( winpos->hwnd );
-            WIN_LinkWindow( winpos->hwnd, hwndInsertAfter );
+            WIN_UnlinkWindow( winpos.hwnd );
+            WIN_LinkWindow( winpos.hwnd, hwndInsertAfter );
         }
-        else WINPOS_MoveWindowZOrder( winpos->hwnd, hwndInsertAfter );
+        else WINPOS_MoveWindowZOrder( winpos.hwnd, hwndInsertAfter );
     }
 
       /* Send WM_NCCALCSIZE message to get new client area */
 
-    result = WINPOS_SendNCCalcSize( winpos->hwnd, TRUE, &newWindowRect,
+    result = WINPOS_SendNCCalcSize( winpos.hwnd, TRUE, &newWindowRect,
 				    &wndPtr->rectWindow, &wndPtr->rectClient,
-				    winpos, &newClientRect );
+				    &winpos, &newClientRect );
     /* ....  Should handle result here */
 
       /* Perform the moving and resizing */
 
     if (wndPtr->window)
     {
-        WINPOS_SetXWindowPos( winpos );
+        WINPOS_SetXWindowPos( &winpos );
         wndPtr->rectWindow = newWindowRect;
         wndPtr->rectClient = newClientRect;
     }
@@ -889,7 +881,7 @@
             if ((oldWindowRect.left != wndPtr->rectWindow.left) ||
                 (oldWindowRect.top != wndPtr->rectWindow.top))
             {
-                RedrawWindow( winpos->hwnd, NULL, 0, RDW_INVALIDATE |
+                RedrawWindow( winpos.hwnd, NULL, 0, RDW_INVALIDATE |
                               RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE );
             }
             DeleteObject( hrgn1 );
@@ -908,7 +900,7 @@
         else
         {
             if (!(flags & SWP_NOREDRAW))
-                RedrawWindow( winpos->hwnd, NULL, 0,
+                RedrawWindow( winpos.hwnd, NULL, 0,
                               RDW_INVALIDATE | RDW_FRAME | RDW_ERASE );
         }
     }
@@ -926,16 +918,16 @@
                               RDW_INVALIDATE | RDW_FRAME |
                               RDW_ALLCHILDREN | RDW_ERASE );
         }
-        if ((winpos->hwnd == GetFocus()) || IsChild(winpos->hwnd, GetFocus()))
-            SetFocus( GetParent(winpos->hwnd) );  /* Revert focus to parent */
-	if (winpos->hwnd == hwndActive)
+        if ((winpos.hwnd == GetFocus()) || IsChild(winpos.hwnd, GetFocus()))
+            SetFocus( GetParent(winpos.hwnd) );  /* Revert focus to parent */
+	if (winpos.hwnd == hwndActive)
 	{
 	      /* Activate previously active window if possible */
 	    HWND newActive = wndPtr->hwndPrevActive;
-	    if (!IsWindow(newActive) || (newActive == winpos->hwnd))
+	    if (!IsWindow(newActive) || (newActive == winpos.hwnd))
 	    {
 		newActive = GetTopWindow(GetDesktopWindow());
-		if (newActive == winpos->hwnd) newActive = wndPtr->hwndNext;
+		if (newActive == winpos.hwnd) newActive = wndPtr->hwndNext;
 	    }	    
 	    WINPOS_ChangeActiveWindow( newActive, FALSE );
 	}
@@ -946,14 +938,14 @@
     if (!(flags & SWP_NOACTIVATE))
     {
 	if (!(wndPtr->dwStyle & WS_CHILD))
-	    WINPOS_ChangeActiveWindow( winpos->hwnd, FALSE );
+	    WINPOS_ChangeActiveWindow( winpos.hwnd, FALSE );
     }
     
       /* Repaint the window */
 
     if (wndPtr->window) MSG_Synchronize();  /* Wait for all expose events */
     if ((flags & SWP_FRAMECHANGED) && !(flags & SWP_NOREDRAW))
-        RedrawWindow( winpos->hwnd, NULL, 0,
+        RedrawWindow( winpos.hwnd, NULL, 0,
                       RDW_INVALIDATE | RDW_FRAME | RDW_ERASE );
     if (!(flags & SWP_DEFERERASE))
         RedrawWindow( wndPtr->hwndParent, NULL, 0,
@@ -961,11 +953,10 @@
 
       /* And last, send the WM_WINDOWPOSCHANGED message */
 
-    if (!(winpos->flags & SWP_NOSENDCHANGING))
-        SendMessage( winpos->hwnd, WM_WINDOWPOSCHANGED, 0,
-                     USER_HEAP_SEG_ADDR(hWinPos) );
+    if (!(winpos.flags & SWP_NOSENDCHANGING))
+        SendMessage( winpos.hwnd, WM_WINDOWPOSCHANGED,
+                     0, MAKE_SEGPTR(&winpos) );
 
-    USER_HEAP_FREE( hWinPos );
     return TRUE;
 }
 
diff --git a/wine.ini b/wine.ini
index b9139b8..6ad81d0 100644
--- a/wine.ini
+++ b/wine.ini
@@ -11,6 +11,7 @@
 System=c:\windows\system

 Temp=c:\temp

 Path=c:\windows;c:\windows\system;e:\;e:\test;f:\

+SymbolTableFile=./wine.sym

 

 [fonts]

 system=bitstream-courier