Release 961215

Sun Dec 15 16:18:15 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [graphics/x11drv/bitblt.c]
	Fixed BITBLT_StretchImage for partially covered or inverted
	bitmaps.

	* [objects/dib.c]
	Fixed the upside-down bitmap problem.

Sat Dec 14 02:49:57 1996  Thomas Sandford <t.d.g.sandford@prds-grn.demon.co.uk>

	* [if1632/user32.spec]
	IsMenu and RemoveMenu added (use existing Win16 functions).

	* [include/windows.h]
	Corrections to BITMAPINFOHEADER structure.

	* [loader/module.c] [if1632/kernel32.spec]
	New function GetModuleFileName32A (heavily based on original
	Win16 version).

	* [loader/pe_image.c]
	Hack to allow files with short PE header to be loaded (e.g.
	COMDLG32.DLL from Win32s).

	* [misc/winsock_async.c]
	#if out EIDRM case (not present in FreeBSD).

	* [tools/build.c]
	Remove trailing comments from .s files generated by build
	as these break assembly when not run through pre-processor.

	* [windows/graphics.c] [if1632/gdi32.spec]
	New function Polyline32 - based on original Polyline. Needs
	metafile support adding still.

Fri Dec 13 13:04:06 1996  Bruce Milner <Bruce.Milner@genetics.utah.edu>

	* [win32/findfile.c] [if1632/kernel.spec]
	FindFirstFile32A(): Use dos current directory for drive prefixes.
	FindNextFile32A(): Fill in file attribute information.
	Implement FindFirstFile16, FindNextFile16, FindClose16.

	* [files/drive.c]
	GetCurrentDirectory32A - Fix problem with null 3rd character in
	string.

Tue Dec 10 14:49:07 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [windows/painting.c][windows/message.c]
	Don't use linked lists to call SendMessage(), for it might destroy
 	the current listentry.

	* [misc/registry.c]
	Fixed temporary file saving (rename doesn't work across
	partitions).

	* [files/*.c]
	GetFullPathName*,GetDriveType32A fixed, CreateDirectoryEx*,
	GetVolumeInformation32W fixed.

	* [win32/process.c][if1632/kernel.spec][if1632/kernel32.spec]
	LoadLibrary* updated to new naming std., *32W added.

	* [win32/console.c] [include/wincon.h]
	Additions for NT commandline executables.

	* [if1632/advapi32.spec][if1632/kernel32.spec][win32/init.c]	
	GetUserName32W added, GetComputerName32W added,
	GetStartupInfo32W added, GetSystemInfo updated to NT standard.

	* [windows/msgbox.c][misc/shell.c][windows/graphics.c]
	MessageBox32W, ShellAbout32W, CommandLineToArgvW, Polygon32 added.

	* [misc/crtdll.c][include/crtdll.h][if1632/crtdll.spec][misc/ntdll.c]
	  [if1632/ntdll.spec]
	Lot of new unicode functions added (needed for NT).

	* [loader/pe_image.c]
	NtCurrentTeb added.

Tue Dec 10 22:39:33 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [windows/keyboard.c]
	Rewrote function TranslateAccelerator().

Mon Dec  9 14:52:13 1996  Slaven Rezic  <eserte@cs.tu-berlin.de>

	* [windows/defwnd.c] 
	DEFWND_SetText(): Set icon name.

Sun Dec  8 23:30:00 1996  Alex Korobka <alex@trantor.pharm.sunysb.edu>

	* [loader/signal.c] [misc/winsock.c] [misc/winsock_async.c]
	  [if1632/winsock.spec]
	IPC resource cleanup, bugfixes.

	* [windows/dialog.c] [windows/defdlg.c]
	More DefDlgProc() fixes.

Sun Dec  8 14:01:42 1996  Vadim Strizhevsky  <striv@ms.com>

	* [misc/clipboard.c] [objects/font.c] [win32/init.c]
 	  [win32/newfns.c] [windows/graphics.c]
	Added a few WIN32 functions which needed to run some win32
	accessories. Clock should now work almost as well as 16 bit version.
	Add: RegisterClipboardFormat32W GetTextExtentExPoint32*
	     GetModuleHandleW, DisableThreadLibraryCalls (empty stub),
	     Polygon32
	Fix: Polygon16 possible memory leak on error return.
diff --git a/ANNOUNCE b/ANNOUNCE
index a1d8978..835a25a 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,13 +1,12 @@
-This is release 961208 of Wine, the MS Windows emulator.  This is still a
+This is release 961215 of Wine, the MS Windows emulator.  This is still a
 developer's only release.  There are many bugs and many unimplemented API
 features.  Most applications still do not work correctly.
 
 Patches should be submitted to "julliard@lrc.epfl.ch".  Please don't
 forget to include a ChangeLog entry.
 
-WHAT'S NEW with Wine-961208: (see ChangeLog for details)
-	- Win32 hooks.
-	- fnt2bdf font conversion tool.
+WHAT'S NEW with Wine-961215: (see ChangeLog for details)
+	- Tons of new Win32 stuff.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -16,10 +15,10 @@
 the release is available at the ftp sites.  The sources will be available
 from the following locations:
 
-  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-961208.tar.gz
-  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-961208.tar.gz
-  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-961208.tar.gz
-  ftp://aris.com/pub/linux/ALPHA/Wine/development/Wine-961208.tar.gz
+  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-961215.tar.gz
+  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-961215.tar.gz
+  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-961215.tar.gz
+  ftp://aris.com/pub/linux/ALPHA/Wine/development/Wine-961215.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/BUGS b/BUGS
index 46fba4c..0379d01 100644
--- a/BUGS
+++ b/BUGS
@@ -5,7 +5,7 @@
 add new entries and, more importantly, remove those for the 
 bugs you fixed ;-)
 ------------------------------------------------------------
-As of Dec 1 1996 -
+As of Dec 15 1996 -
 
 General:
 
@@ -15,10 +15,19 @@
  * Font mapping is too generic. No soft font loading, no rotated 
    text support. [alex@amadeus.pharm.sunysb.edu]
 
- * No thread support in Win32 code. 
+ * No thread/process/kernel-object support in Win32 code. 
 
  * Very alpha printing code. [john@division.co.uk]
 
+ * No OLE and OLE32 support (including OLE interfaces etc.).
+
+ * No MS Video support (perhaps interface with xanim).
+
+ * No COMDLG32 support. (Needed badly, the Windows95 comdlg32.dll
+   doesn't work with WINE.)
+
+ * No COMMCTRL/COMCTL32 support.
+
  * No icon titles.
 	- Windows uses a special window class to display icon titles.
 	  Handles to these title windows are stored in the icon window
@@ -29,9 +38,6 @@
  * Simple OLE actions were working in October release, got
    broken in November (in Winword "Insert Object" now results in 
    segfault right after the call to LoadModule()).
- * Write and other applications have problems with displaying partially
-   obscured bitmaps. 
- * Asynchronous Winsock services sometimes produce zombie processes.
  * AllocCSToDSAlias() shouldn't alloc alias for the same segment multiple
    times.
  * ScrollWindowEx() is outdated.
diff --git a/ChangeLog b/ChangeLog
index fbff2bf..f94bb28 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,116 @@
 ----------------------------------------------------------------------
+Sun Dec 15 16:18:15 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>
+
+	* [graphics/x11drv/bitblt.c]
+	Fixed BITBLT_StretchImage for partially covered or inverted
+	bitmaps.
+
+	* [objects/dib.c]
+	Fixed the upside-down bitmap problem.
+
+Sat Dec 14 02:49:57 1996  Thomas Sandford <t.d.g.sandford@prds-grn.demon.co.uk>
+
+	* [if1632/user32.spec]
+	IsMenu and RemoveMenu added (use existing Win16 functions).
+
+	* [include/windows.h]
+	Corrections to BITMAPINFOHEADER structure.
+
+	* [loader/module.c] [if1632/kernel32.spec]
+	New function GetModuleFileName32A (heavily based on original
+	Win16 version).
+
+	* [loader/pe_image.c]
+	Hack to allow files with short PE header to be loaded (e.g.
+	COMDLG32.DLL from Win32s).
+
+	* [misc/winsock_async.c]
+	#if out EIDRM case (not present in FreeBSD).
+
+	* [tools/build.c]
+	Remove trailing comments from .s files generated by build
+	as these break assembly when not run through pre-processor.
+
+	* [windows/graphics.c] [if1632/gdi32.spec]
+	New function Polyline32 - based on original Polyline. Needs
+	metafile support adding still.
+
+Fri Dec 13 13:04:06 1996  Bruce Milner <Bruce.Milner@genetics.utah.edu>
+
+	* [win32/findfile.c] [if1632/kernel.spec]
+	FindFirstFile32A(): Use dos current directory for drive prefixes.
+	FindNextFile32A(): Fill in file attribute information.
+	Implement FindFirstFile16, FindNextFile16, FindClose16.
+
+	* [files/drive.c]
+	GetCurrentDirectory32A - Fix problem with null 3rd character in
+	string.
+
+Tue Dec 10 14:49:07 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
+
+	* [windows/painting.c][windows/message.c]
+	Don't use linked lists to call SendMessage(), for it might destroy
+ 	the current listentry.
+
+	* [misc/registry.c]
+	Fixed temporary file saving (rename doesn't work across
+	partitions).
+
+	* [files/*.c]
+	GetFullPathName*,GetDriveType32A fixed, CreateDirectoryEx*,
+	GetVolumeInformation32W fixed.
+
+	* [win32/process.c][if1632/kernel.spec][if1632/kernel32.spec]
+	LoadLibrary* updated to new naming std., *32W added.
+
+	* [win32/console.c] [include/wincon.h]
+	Additions for NT commandline executables.
+
+	* [if1632/advapi32.spec][if1632/kernel32.spec][win32/init.c]	
+	GetUserName32W added, GetComputerName32W added,
+	GetStartupInfo32W added, GetSystemInfo updated to NT standard.
+
+	* [windows/msgbox.c][misc/shell.c][windows/graphics.c]
+	MessageBox32W, ShellAbout32W, CommandLineToArgvW, Polygon32 added.
+
+	* [misc/crtdll.c][include/crtdll.h][if1632/crtdll.spec][misc/ntdll.c]
+	  [if1632/ntdll.spec]
+	Lot of new unicode functions added (needed for NT).
+
+	* [loader/pe_image.c]
+	NtCurrentTeb added.
+
+Tue Dec 10 22:39:33 1996  Albrecht Kleine  <kleine@ak.sax.de>
+
+	* [windows/keyboard.c]
+	Rewrote function TranslateAccelerator().
+
+Mon Dec  9 14:52:13 1996  Slaven Rezic  <eserte@cs.tu-berlin.de>
+
+	* [windows/defwnd.c] 
+	DEFWND_SetText(): Set icon name.
+
+Sun Dec  8 23:30:00 1996  Alex Korobka <alex@trantor.pharm.sunysb.edu>
+
+	* [loader/signal.c] [misc/winsock.c] [misc/winsock_async.c]
+	  [if1632/winsock.spec]
+	IPC resource cleanup, bugfixes.
+
+	* [windows/dialog.c] [windows/defdlg.c]
+	More DefDlgProc() fixes.
+
+Sun Dec  8 14:01:42 1996  Vadim Strizhevsky  <striv@ms.com>
+
+	* [misc/clipboard.c] [objects/font.c] [win32/init.c]
+ 	  [win32/newfns.c] [windows/graphics.c]
+	Added a few WIN32 functions which needed to run some win32
+	accessories. Clock should now work almost as well as 16 bit version.
+	Add: RegisterClipboardFormat32W GetTextExtentExPoint32*
+	     GetModuleHandleW, DisableThreadLibraryCalls (empty stub),
+	     Polygon32
+	Fix: Polygon16 possible memory leak on error return.
+
+----------------------------------------------------------------------
 Sun Dec  8 14:51:57 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>
 
 	* [configure.in]
diff --git a/controls/edit.c b/controls/edit.c
index 66baa58..54aecd4 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -483,11 +483,6 @@
 		lResult = EDIT_WM_VScroll(wndPtr, wParam, lParam);
 		break;
 	default:
-                /* Some programs pass messages obtained through
-                 * RegisterWindowMessage() (>= 0xc000); we just ignore them
-                 */
-		if ((msg >= WM_USER) && (msg < 0xc000))
-			fprintf(stdnimp, "edit: undocumented message %d >= WM_USER, please report.\n", msg);
 		lResult = DefWindowProc16(hwnd, msg, wParam, lParam);
 		break;
 	}
diff --git a/controls/listbox.c b/controls/listbox.c
index a39048b..ceed8b2 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -1204,8 +1204,8 @@
             INT32 last  = MAX( descr->focus_item, descr->anchor_item );
             if (first > 0)
                 LISTBOX_SelectItemRange( wnd, descr, 0, first - 1, FALSE );
-            LISTBOX_SelectItemRange( wnd, descr, first, last, TRUE );
             LISTBOX_SelectItemRange( wnd, descr, last + 1, -1, FALSE );
+            LISTBOX_SelectItemRange( wnd, descr, first, last, TRUE );
         }
     }
     else if (!(descr->style & LBS_MULTIPLESEL) && (descr->selected_item != -1))
diff --git a/debugger/info.c b/debugger/info.c
index 36e5cab..57d8d27 100644
--- a/debugger/info.c
+++ b/debugger/info.c
@@ -98,23 +98,25 @@
     static const char * const helptext[] =
 {
 "The commands accepted by the Wine debugger are a small subset",
-"of the commands that gdb would accept.  The commands currently",
-"are:\n",
+"of the commands that gdb would accept.",
+"The commands currently are:",
 "  break [*<addr>]                      delete break bpnum",
 "  disable bpnum                        enable bpnum",
 "  help                                 quit",
-"  x <addr>                             cont",
+"  bt                                   cont",
 "  step                                 next",
-"  mode [16,32]                         print <expr>",
+"  x <addr>                             print <expr>",
 "  set <reg> = <expr>                   set *<addr> = <expr>",
-"  walk [wnd] <expr>			 dump [wnd, queue] <expr>",
-"  info [reg,stack,break,segments]      bt",
 "  symbolfile <filename>                define <identifier> <addr>",
-"  list <addr> ",
-"",
+"  list <addr>\n",
+
+"Wine-specific commands:",
+"  mode [16,32]                         walk [wnd,class,queue] <handle>",
+"  info [reg,stack,break,segments]      info [wnd, queue] <handle>\n",
+
 "The 'x' command accepts repeat counts and formats (including 'i') in the",
-"same way that gdb does.",
-"",
+"same way that gdb does.\n",
+
 " The following are examples of legal expressions:",
 " $eax     $eax+0x3   0x1000   ($eip + 256)  *$eax   *($esp + 3)",
 " Also, a nm format symbol table can be read from a file using the",
diff --git a/files/dos_fs.c b/files/dos_fs.c
index f07a117..237139e 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -892,14 +892,39 @@
 {
 	dprintf_file(stddeb,"GetFullPathNameA(%s)\n",fn);
 	/* FIXME */
-        if (buf)
-        {
+        if (buf) {
             lstrcpyn32A(buf,fn,buflen);
-            if (lastpart) *lastpart = strrchr(buf,'\\');
+            if (lastpart) {
+		*lastpart = strrchr(buf,'\\');
+		if (!*lastpart) *lastpart=buf;
+	    }
 	}
 	return strlen(fn);
 }
 
+/***********************************************************************
+ *           GetFullPathName32W   (KERNEL32.273)
+ */
+DWORD GetFullPathName32W(LPCWSTR fn,DWORD buflen,LPWSTR buf,LPWSTR *lastpart) {
+	LPWSTR  x;
+
+	dprintf_file(stddeb,"GetFullPathNameW(%p)\n",fn);
+	/* FIXME */
+	if (buf) {
+		lstrcpyn32W(buf,fn,buflen);
+		if (lastpart) {
+			x = buf+lstrlen32W(buf)-1;
+			while (x>=buf && *x!='\\')
+			x--;
+			if (x>=buf)
+				*lastpart=x;
+			else
+				*lastpart=buf;
+		}
+	}
+	return lstrlen32W(fn);
+}
+
 
 /***********************************************************************
  *           DosDateTimeToFileTime   (KERNEL32.76)
diff --git a/files/drive.c b/files/drive.c
index 8a5bf5a..74b3672 100644
--- a/files/drive.c
+++ b/files/drive.c
@@ -603,7 +603,7 @@
 UINT32 GetDriveType32A( LPCSTR root )
 {
     dprintf_dosfs( stddeb, "GetDriveType32A(%s)\n", root );
-    if ((root[1] != ':') || (root[2] != '\\'))
+    if (root[1] != ':')
     {
         fprintf( stderr, "GetDriveType32A: invalid root '%s'\n", root );
         return DRIVE_DOESNOTEXIST;
@@ -657,9 +657,9 @@
         *buf = '\0';
         return 0;
     }
-    lstrcpyn32A( buf, pref, 3 );
+    lstrcpyn32A( buf, pref, MIN( 4, buflen ) );
     if (buflen) buf[0] += DRIVE_GetCurrentDrive();
-    if (buflen >= 3) lstrcpyn32A( buf + 3, s, buflen - 3 );
+    if (buflen > 3) lstrcpyn32A( buf + 3, s, buflen - 3 );
     return strlen(s) + 3; /* length of WHOLE current directory */
 }
 
@@ -682,7 +682,7 @@
 /***********************************************************************
  *           SetCurrentDirectory   (KERNEL.412)
  */
-BOOL32 SetCurrentDirectory( LPCSTR dir )
+BOOL16 SetCurrentDirectory16( LPCSTR dir )
 {
     if (dir[0] && (dir[1]==':'))
     {
@@ -698,6 +698,30 @@
     return DRIVE_Chdir( DRIVE_GetCurrentDrive(), dir );
 }
 
+/***********************************************************************
+ *           SetCurrentDirectory32A   (KERNEL32.479)
+ */
+BOOL32 SetCurrentDirectory32A( LPCSTR dir )
+{
+    /* FIXME: Unauthorized Windows 95 mentions that SetCurrentDirectory 
+     * may change drive and current directory for there is no drive based
+     * currentdir table?
+     */
+    return SetCurrentDirectory16(dir);
+}
+
+/***********************************************************************
+ *           SetCurrentDirectory32W   (KERNEL32.480)
+ */
+BOOL32 SetCurrentDirectory32W( LPCWSTR dirW)
+{
+    LPSTR dir = STRING32_DupUniToAnsi(dirW);
+    BOOL32  res = SetCurrentDirectory32A(dir);
+    
+    free(dir);
+    return res;
+}
+
 
 /***********************************************************************
  *           GetLogicalDriveStrings32A   (KERNEL32.231)
@@ -807,19 +831,19 @@
                                 DWORD *serial, DWORD *filename_len,
                                 DWORD *flags, LPWSTR fsname, DWORD fsname_len)
 {
-    LPSTR xroot    = STRING32_DupUniToAnsi(root);
-    LPSTR xvolname = (char*)xmalloc( label_len );
-    LPSTR xfsname  = (char*)xmalloc( fsname_len );
+    LPSTR xroot    = root?STRING32_DupUniToAnsi(root):NULL;
+    LPSTR xvolname = label?(char*)xmalloc( label_len ):NULL;
+    LPSTR xfsname  = fsname?(char*)xmalloc( fsname_len ):NULL;
     BOOL32 ret = GetVolumeInformation32A( xroot, xvolname, label_len, serial,
                                           filename_len, flags, xfsname,
                                           fsname_len );
     if (ret)
     {
-        STRING32_AnsiToUni( label, xvolname );
-        STRING32_AnsiToUni( fsname, xfsname );
+        if (label) STRING32_AnsiToUni( label, xvolname );
+        if (fsname) STRING32_AnsiToUni( fsname, xfsname );
     }
-    free(xroot);
-    free(xvolname);
-    free(xfsname);
+    if (xroot) free(xroot);
+    if (xvolname) free(xvolname);
+    if (xfsname) free(xfsname);
     return ret;
 }
diff --git a/files/file.c b/files/file.c
index 45ac9f0..fa3177e 100644
--- a/files/file.c
+++ b/files/file.c
@@ -737,7 +737,7 @@
 
     if (GetCurrentTask())
     {
-        GetModuleFileName( GetCurrentTask(), ofs->szPathName, len );
+        GetModuleFileName16( GetCurrentTask(), ofs->szPathName, len );
         if ((p = strrchr( ofs->szPathName, '\\' )))
         {
             strcpy( p + 1, name );
@@ -863,7 +863,7 @@
 
     /* Try the path of the current executable */
     if (GetCurrentTask()) {
-	GetModuleFileName(GetCurrentTask(),testpath,len);
+	GetModuleFileName16(GetCurrentTask(),testpath,len);
 	if ((p=strrchr(testpath,'\\'))) {
             strcpy(p+1,name);
             if ((unixName=DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE)))
@@ -1334,6 +1334,23 @@
     return ret;
 }
 
+/***********************************************************************
+ *           CreateDirectoryEx32A   (KERNEL32.40)
+ */
+BOOL32 CreateDirectoryEx32A( LPCSTR template, LPCSTR path,
+                             LPSECURITY_ATTRIBUTES lpsecattribs)
+{
+    return CreateDirectory32A(path,lpsecattribs);
+}
+
+/***********************************************************************
+ *           CreateDirectoryEx32W   (KERNEL32.41)
+ */
+BOOL32 CreateDirectoryEx32W( LPCWSTR template, LPCWSTR path,
+                             LPSECURITY_ATTRIBUTES lpsecattribs)
+{
+    return CreateDirectory32W(path,lpsecattribs);
+}
 
 /***********************************************************************
  *           RemoveDirectory16   (KERNEL)
diff --git a/graphics/win16drv/init.c b/graphics/win16drv/init.c
index 4b0d8b7..10ab2b6 100644
--- a/graphics/win16drv/init.c
+++ b/graphics/win16drv/init.c
@@ -32,7 +32,7 @@
 #endif
 
 static BOOL32 WIN16DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device,
-                                 LPCSTR output, const DEVMODE* initData );
+                                 LPCSTR output, const DEVMODE16* initData );
 static INT32 WIN16DRV_Escape( DC *dc, INT32 nEscape, INT32 cbInput, 
                               SEGPTR lpInData, SEGPTR lpOutData );
 
@@ -284,7 +284,7 @@
         char *drvName = malloc(strlen(pszDriver)+5);
         strcpy(drvName, pszDriver);
         strcat(drvName, ".DRV");
-        hInst = LoadLibrary(drvName);
+        hInst = LoadLibrary16(drvName);
     }
     dprintf_win16drv(stddeb, "Loaded the library\n");
 
@@ -611,7 +611,7 @@
 
 
 BOOL32 WIN16DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device, LPCSTR output,
-                          const DEVMODE* initData )
+                          const DEVMODE16* initData )
 {
     LOADED_PRINTER_DRIVER *pLPD;
     WORD wRet;
@@ -1146,7 +1146,7 @@
 
     dprintf_win16drv(stddeb, "WriteDialog: %04x %04x \"%s\"\n", hJob,  cchMsg, lpMsg);
 
-    nRet = MessageBox(NULL, lpMsg, "Printing Error", MB_OKCANCEL);
+    nRet = MessageBox16(0, lpMsg, "Printing Error", MB_OKCANCEL);
     return nRet;
 }
 
diff --git a/graphics/wing.c b/graphics/wing.c
index 3bae489..697b5b9 100644
--- a/graphics/wing.c
+++ b/graphics/wing.c
@@ -4,41 +4,86 @@
  * Started by Robert Pouliot <krynos@clic.net>
  */
 
-#include "gdi.h"
+#include <X11/Xlib.h>
+#include <X11/extensions/XShm.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
 #include "windows.h"
+#include "bitmap.h"
+#include "dc.h"
+#include "gdi.h"
+#include "xmalloc.h"
 #include "stddebug.h"
 #include "debug.h"
 
+typedef enum WING_DITHER_TYPE
+{
+  WING_DISPERSED_4x4, WING_DISPERSED_8x8, WING_CLUSTERED_4x4
+} WING_DITHER_TYPE;
+
+static int	__WinGOK = -1;
+
+/* 
+ * WinG DIB bitmaps can be selected into DC and then scribbled upon
+ * by GDI functions. They can also be changed directly. This gives us 
+ * three choices 
+ *	- use original WinG 16-bit DLL
+ *		requires working 16-bit driver interface
+ * 	- implement DIB graphics driver from scratch
+ *		see wing.zip size
+ *	- use shared pixmaps
+ *		won't work with some videocards and/or videomodes
+ * 961208 - AK
+ */
+
+static BITMAPINFOHEADER __bmpiWinG = { 0, 1, -1, 1, 8, BI_RGB, 1, 0, 0, 0, 0 };
+
+static void __initWinG()
+{
+  if( __WinGOK < 0 )
+  {
+    Status s = XShmQueryExtension(display);
+    if( s )
+    {
+      int i = XShmPixmapFormat(display);
+      if( i == ZPixmap && screenDepth == 8 ) 
+      {
+        __WinGOK = True;
+	return;
+      }
+    } 
+    fprintf(stdnimp,"WinG: no joy.\n");
+    __WinGOK = False;
+  }
+}
+
 /***********************************************************************
- *          WingCreateDC16	(WING.1001)
+ *          WinGCreateDC16	(WING.1001)
  */
 HDC16 WinGCreateDC16(void)
 {
-	/* FIXME: Probably wrong... */
-	return CreateDC("DISPLAY", NULL, NULL, NULL);
-}
+  __initWinG();
 
+  if( __WinGOK > 0 )
+	return CreateCompatibleDC(NULL);
+  return (HDC16)NULL;
+}
 
 /***********************************************************************
  *  WinGRecommendDIBFormat16    (WING.1002)
  */
 BOOL16 WinGRecommendDIBFormat16(BITMAPINFO *fmt)
 {
-	HDC16 i=GetDC16(0);
+  fprintf(stdnimp,"WinGRecommendDIBFormat()\n");
 
-	fmt->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
-	fmt->bmiHeader.biWidth=0;
-	fmt->bmiHeader.biHeight=1; /* The important part */
-	fmt->bmiHeader.biPlanes=GetDeviceCaps(i, PLANES);
-	fmt->bmiHeader.biBitCount=GetDeviceCaps(i, BITSPIXEL);
-	fmt->bmiHeader.biCompression=BI_RGB;
-	fmt->bmiHeader.biSizeImage=0;
-	fmt->bmiHeader.biXPelsPerMeter=1000/25.4*GetDeviceCaps(i,LOGPIXELSX);
-	fmt->bmiHeader.biYPelsPerMeter=1000/25.4*GetDeviceCaps(i,LOGPIXELSY);
-	fmt->bmiHeader.biClrUsed=0;
-	fmt->bmiHeader.biClrImportant=0;
-	ReleaseDC16(0, i);
-	return 1;
+  if( __WinGOK > 0 && fmt )
+  {
+    memcpy(&fmt->bmiHeader, &__bmpiWinG, sizeof(BITMAPINFOHEADER));
+    return TRUE;
+  }
+  return FALSE;
 }
 
 /***********************************************************************
@@ -46,72 +91,172 @@
  */
 HBITMAP16 WinGCreateBitmap16(HDC16 winDC, BITMAPINFO *header, void **bits)
 {
-        fprintf(stdnimp,"WinGCreateBitmap: almost empty stub! (expect failure)\n");
-	/* Assume RGB color */
-	if(bits==NULL)
-		return CreateDIBitmap(winDC, header, 0, bits, header, 0);
-	else
-		return CreateDIBitmap(winDC, header, 1, bits, header, 0);
-	return 0;
+  fprintf(stdnimp,"WinGCreateBitmap: empty stub! (expect failure)\n");
+  if( __WinGOK > 0 && header )
+  {
+    BITMAPINFOHEADER* bmpi = &header->bmiHeader;
+
+    fprintf(stdnimp,"bytes\t=%i\nplanes\t=%i\nbpp\t=%i\nx\t=%i\ny\t=%i\nrle\t=0x%08x\nsize\t=%i\n",
+     (int)bmpi->biSize, bmpi->biPlanes, bmpi->biBitCount,
+     (int)bmpi->biWidth, (int)bmpi->biHeight, (unsigned)bmpi->biCompression, (int)bmpi->biSizeImage);
+
+#ifdef PRELIMINARY_WING16_SUPPORT
+    if( bmpi->biPlanes == __bmpiWinG.biPlanes && bmpi->biBitCount == __bmpiWinG.biBitCount &&
+	bmpi->biCompression == __bmpiWinG.biCompression && (int)bmpi->biHeight < 0 &&
+	bmpi->biWidth )
+    {
+	unsigned bytes = (bmpi->biWidth + bmpi->biWidth % 2)*(-bmpi->biHeight) * bmpi->biBitCount/8;
+	int	 key = shmget(IPC_PRIVATE, bytes, IPC_CREAT | 0x01FF);
+
+	if( key )
+	{
+	    /* Create the BITMAPOBJ 
+	     *
+	     * FIXME: A facility to manage shared memory structures
+	     * which would clean up when Wine crashes. Perhaps a part of 
+	     * IPC code can be adapted. Otherwise this code leaves a lot
+	     * of junk in shared memory. 
+	     */
+
+	    HBITMAP16 hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC );
+	    if (hbitmap)
+	    {
+	      __ShmBitmapCtl* p = (__ShmBitmapCtl*)xmalloc(sizeof(__ShmBitmapCtl));
+		BITMAPOBJ* 	 bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_LIN_ADDR( hbitmap );
+
+		bmpObjPtr->size.cx = 0;
+		bmpObjPtr->size.cy = 0;
+		bmpObjPtr->bitmap.bmType = 0;
+		bmpObjPtr->bitmap.bmWidth = (INT16)abs(bmpi->biWidth);
+		bmpObjPtr->bitmap.bmHeight = -(INT16)bmpi->biHeight;
+		bmpObjPtr->bitmap.bmPlanes = (BYTE)bmpi->biPlanes;
+		bmpObjPtr->bitmap.bmBitsPixel = (BYTE)bmpi->biBitCount;
+		bmpObjPtr->bitmap.bmWidthBytes = 
+		  (INT16)BITMAP_WIDTH_BYTES( bmpObjPtr->bitmap.bmWidth, bmpi->biBitCount );
+		bmpObjPtr->bitmap.bmBits = (SEGPTR)p;
+
+		p->si.shmid = key;
+		p->si.shmaddr = shmat(key, NULL, 0);
+		p->si.readOnly = False;
+
+		if( p->si.shmaddr )
+		{
+		    WORD	sel = 0;
+
+		    XShmAttach(display, &p->si);
+		    bmpObjPtr->pixmap = XShmCreatePixmap(display, rootWindow, 
+				  p->si.shmaddr, &p->si, bmpObjPtr->bitmap.bmWidth, 
+				  bmpObjPtr->bitmap.bmHeight, bmpi->biBitCount );
+		    if( bmpObjPtr->pixmap )
+		    {
+			WORD s; 
+			if( (sel = AllocSelectorArray( (bytes + 0xFFFF) >> 16 )) )
+			{
+			    DWORD	base = (DWORD)p->si.shmaddr, l;
+
+			    SetSelectorBase( sel, base );
+			    SetSelectorLimit( sel, bytes );
+			    s = sel;
+			    for( l = 0x10000; l < bytes ; )
+			    {
+			       s += __AHINCR;
+			       SetSelectorBase( s, base + l );
+			       l += 0x10000;
+			       SetSelectorLimit( s, (l < bytes)?0xFFFF:bytes%0x10000);
+			    }
+			    p->bits = MAKELONG(0, sel);
+			} 
+			else XFreePixmap( display, bmpObjPtr->pixmap );
+		    }
+		    if( !sel )
+		    {
+		      shmdt( p->si.shmaddr );
+		      p->si.shmaddr = NULL;
+		    }
+		} 
+		if( !p->si.shmaddr )
+		{
+		    GDI_FreeObject( hbitmap );
+		    hbitmap = 0;
+		}
+	    }
+	    return hbitmap;
+	}
+    }
+#endif
+  }
+  return 0;
 }
 
 /***********************************************************************
- *  WinGGetDIBPointer16   (WING.1004)
+ *  WinGGetDIBPointer   (WING.1004)
  */
-void* WinGGetDIBPointer16(HBITMAP16 bmap, BITMAPINFO *header)
+SEGPTR WinGGetDIBPointer16(HBITMAP16 hWinGBitmap, BITMAPINFO* bmpi)
 {
-        fprintf(stdnimp,"WinGGetDIBPointer16: empty stub!\n");
-	return NULL;
+#ifdef PRELIMINARY_WING16_SUPPORT
+  BITMAPOBJ*	bmp = (BITMAPOBJ *) GDI_GetObjPtr( hWinGBitmap, BITMAP_MAGIC );
+
+  if( bmp )
+  {
+    __ShmBitmapCtl* p = (__ShmBitmapCtl*)bmp->bitmap.bmBits;
+    if( p )
+    {
+      if( bmpi ) memcpy( bmpi, &__bmpiWinG, sizeof(BITMAPINFOHEADER));
+      return p->bits;
+    }
+  }
+#endif
+  return (SEGPTR)NULL;
+}
+
+/***********************************************************************
+ *  WinGSetDIBColorTable   (WING.1004)
+ */
+UINT16 WinGSetDIBColorTable16(HDC16 hWinGDC, UINT16 start, UINT16 num, RGBQUAD* pColor)
+{
+        fprintf(stdnimp,"WinGSetDIBColorTable: empty stub!\n");
+        return num;
 }
 
 /***********************************************************************
  *  WinGGetDIBColorTable16   (WING.1005)
  */
-UINT16 WinGGetDIBColorTable16(HDC16 winDC, UINT16 start, UINT16 numentry, 
+UINT16 WinGGetDIBColorTable16(HDC16 winDC, UINT16 start, UINT16 numentry,
                             RGBQUAD* colors)
 {
-	return GetPaletteEntries(winDC, start, numentry, colors);
+	fprintf(stdnimp,"WinGGetDIBColorTable: empty stub!\n");
+	return 0;
 }
 
 /***********************************************************************
- *  WinGSetDIBColorTable16   (WING.1006)
- */
-UINT16 WinGSetDIBColorTable16(HDC16 winDC, UINT16 start, UINT16 numentry,
-                              RGBQUAD* colors)
-{
-	return SetPaletteEntries(winDC, start, numentry, colors);
-}
-
-
-/***********************************************************************
  *  WinGCreateHalfTonePalette16   (WING.1007)
  */
 HPALETTE16 WinGCreateHalfTonePalette16(void)
 {
-        fprintf(stdnimp,"WinGCreateHalfTonePalette16: empty stub!\n");
+        fprintf(stdnimp,"WinGCreateHalfTonePalette: empty stub!\n");
 	return 0;
 }
 
 /***********************************************************************
  *  WinGCreateHalfToneBrush16   (WING.1008)
  */
-HPALETTE16 WinGCreateHalfToneBrush16(HDC16 winDC, COLORREF col, INT16 dithertype)
+HPALETTE16 WinGCreateHalfToneBrush16(HDC16 winDC, COLORREF col, WING_DITHER_TYPE type)
 {
-        fprintf(stdnimp,"WinGCreateHalfToneBrush16: empty stub!\n");
+        fprintf(stdnimp,"WinGCreateHalfToneBrush: empty stub!\n");
 	return 0;
 }
 
 /***********************************************************************
  *  WinGStretchBlt16   (WING.1009)
  */
-BOOL16 WinGStretchBlt16(HDC16 destDC, INT16 xDest, INT16 yDest, INT16 widDest, 
-                        INT16 heiDest, HDC16 srcDC, INT16 xSrc, INT16 ySrc, 
-			INT16 widSrc, INT16 heiSrc)
+BOOL16 WinGStretchBlt16(HDC16 destDC, INT16 xDest, INT16 yDest, INT16 widDest,
+                        INT16 heiDest, HDC16 srcDC, INT16 xSrc, INT16 ySrc,
+                        INT16 widSrc, INT16 heiSrc)
 {
 
-	return StretchBlt16(destDC, xDest, yDest, widDest, heiDest, srcDC, xSrc, ySrc, widSrc, heiSrc, SRCCOPY);
+        return StretchBlt16(destDC, xDest, yDest, widDest, heiDest, srcDC, xSrc, ySrc, widSrc, heiSrc, SRCCOPY);
 /*        fprintf(stdnimp,"WinGStretchBlt16: empty stub!\n");*/
-/*	return 0; */
+/*      return 0; */
 }
 
 /***********************************************************************
@@ -120,8 +265,26 @@
 BOOL16 WinGBitBlt16(HDC16 destDC, INT16 xDest, INT16 yDest, INT16 widDest,
                     INT16 heiDest, HDC16 srcDC, INT16 xSrc, INT16 ySrc)
 {
-	return BitBlt16(destDC, xDest, yDest, widDest, heiDest, srcDC, xSrc, ySrc, SRCCOPY);
-/*        fprintf(stdnimp,"WinGBitBlt16: empty stub!\n");*/
-/*	return 0;*/
+    /* destDC is a display DC, srcDC is a memory DC */
+
+    DC *dcDst, *dcSrc;
+
+    if (!(dcDst = (DC *)GDI_GetObjPtr( destDC, DC_MAGIC ))) return FALSE;
+    if (!(dcSrc = (DC *) GDI_GetObjPtr( srcDC, DC_MAGIC ))) return FALSE;
+
+    if (dcDst->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion( dcDst );
+
+    xSrc    = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc );
+    ySrc    = dcSrc->w.DCOrgY + YLPTODP( dcSrc, ySrc );
+    xDest   = dcDst->w.DCOrgX + XLPTODP( dcDst, xDest );
+    yDest   = dcDst->w.DCOrgY + YLPTODP( dcDst, yDest );
+    widDest = widDest * dcDst->w.VportExtX / dcDst->w.WndExtX;
+    heiDest = heiDest * dcDst->w.VportExtY / dcDst->w.WndExtY;
+
+    XSetFunction( display, dcDst->u.x.gc, GXcopy );
+    XCopyArea( display, dcSrc->u.x.drawable,
+               dcDst->u.x.drawable, dcDst->u.x.gc,
+               xSrc, ySrc, widDest, heiDest, xDest, yDest );
+    return TRUE;
 }
 
diff --git a/graphics/x11drv/bitblt.c b/graphics/x11drv/bitblt.c
index d037d13..2b0fe3e 100644
--- a/graphics/x11drv/bitblt.c
+++ b/graphics/x11drv/bitblt.c
@@ -4,6 +4,7 @@
  * Copyright 1993, 1994  Alexandre Julliard
  */
 
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <X11/Xlib.h>
@@ -35,6 +36,9 @@
 
 #define MAX_OP_LEN  6  /* Longest opcode + 1 for the terminating 0 */
 
+#define SWAP_INT32(i1,i2) \
+    do { INT32 __t = *(i1); *(i1) = *(i2); *(i2) = __t; } while(0)
+
 extern void CLIPPING_UpdateGCRegion(DC* );
 
 static const unsigned char BITBLT_Opcodes[256][MAX_OP_LEN] =
@@ -522,9 +526,9 @@
  */
 static void BITBLT_StretchRow( int *rowSrc, int *rowDst,
                                INT32 startDst, INT32 widthDst,
-                               INT32 xinc, WORD mode )
+                               INT32 xinc, INT32 xoff, WORD mode )
 {
-    register INT32 xsrc = xinc * startDst;
+    register INT32 xsrc = xinc * startDst + xoff;
     rowDst += startDst;
     switch(mode)
     {
@@ -551,9 +555,9 @@
  */
 static void BITBLT_ShrinkRow( int *rowSrc, int *rowDst,
                               INT32 startSrc, INT32 widthSrc,
-                              INT32 xinc, WORD mode )
+                              INT32 xinc, INT32 xoff, WORD mode )
 {
-    register INT32 xdst = xinc * startSrc;
+    register INT32 xdst = xinc * startSrc + xoff;
     rowSrc += startSrc;
     switch(mode)
     {
@@ -584,6 +588,9 @@
 {
     register INT32 i;
 
+    assert( (row >= 0) && (row < image->height) );
+    assert( (start >= 0) && (width <= image->width) );
+
     pdata += swap ? start+width-1 : start;
     if (image->depth == depthDst)  /* color -> color */
     {
@@ -636,7 +643,8 @@
                                  int foreground, int background, WORD mode )
 {
     int *rowSrc, *rowDst, *pixel;
-    INT32 xinc, yinc, ysrc, ydst;
+    char *pdata;
+    INT32 xinc, xoff, yinc, ysrc, ydst;
     register INT32 x, y;
     BOOL32 hstretch, vstretch, hswap, vswap;
 
@@ -646,9 +654,6 @@
     heightSrc = abs(heightSrc);
     widthDst  = abs(widthDst);
     heightDst = abs(heightDst);
-    
-    dprintf_bitblt( stddeb, "BITBLT_StretchImage: %dx%d -> %dx%d (mode=%d,h=%d,v=%d)\n",
-                widthSrc, heightSrc, widthDst, heightDst, mode, hswap, vswap );
 
     if (!(rowSrc = (int *)malloc( (widthSrc+widthDst)*sizeof(int) ))) return;
     rowDst = rowSrc + widthSrc;
@@ -664,43 +669,115 @@
     hstretch = (widthSrc < widthDst);
     vstretch = (heightSrc < heightDst);
 
-    xinc = hstretch ? ((int)widthSrc << 16) / widthDst :
-                      ((int)widthDst << 16) / widthSrc;
+    if (hstretch)
+    {
+        xinc = ((int)widthSrc << 16) / widthDst;
+        xoff = ((widthSrc << 16) - (xinc * widthDst)) / 2;
+    }
+    else
+    {
+        xinc = ((int)widthDst << 16) / widthSrc;
+        xoff = ((widthDst << 16) - (xinc * widthSrc)) / 2;
+    }
 
     if (vstretch)
     {
         yinc = ((int)heightSrc << 16) / heightDst;
         ydst = visRectDst->top;
-        ysrc = yinc * ydst + (vswap ? heightSrc<<16 : 0);
+        if (vswap)
+        {
+            ysrc = yinc * (heightDst - ydst - 1);
+            yinc = -yinc;
+        }
+        else
+            ysrc = yinc * ydst;
+
+        for ( ; (ydst < visRectDst->bottom); ysrc += yinc, ydst++)
+        {
+            if (((ysrc >> 16) < visRectSrc->top) ||
+                ((ysrc >> 16) >= visRectSrc->bottom)) continue;
+
+            /* Retrieve a source row */
+            BITBLT_GetRow( srcImage, rowSrc, (ysrc >> 16) - visRectSrc->top,
+                           hswap ? widthSrc - visRectSrc->right
+                                 : visRectSrc->left,
+                           visRectSrc->right - visRectSrc->left,
+                           dstImage->depth, foreground, background, hswap );
+
+            /* Stretch or shrink it */
+            if (hstretch)
+                BITBLT_StretchRow( rowSrc, rowDst, visRectDst->left,
+                                   visRectDst->right - visRectDst->left,
+                                   xinc, xoff, mode );
+            else BITBLT_ShrinkRow( rowSrc, rowDst,
+                                   hswap ? widthSrc - visRectSrc->right
+                                         : visRectSrc->left,
+                                   visRectSrc->right - visRectSrc->left,
+                                   xinc, xoff, mode );
+
+            /* Store the destination row */
+            pixel = rowDst + visRectDst->right - 1;
+            y = ydst - visRectDst->top;
+            for (x = visRectDst->right-visRectDst->left-1; x >= 0; x--)
+                XPutPixel( dstImage, x, y, *pixel-- );
+            if (mode != STRETCH_DELETESCANS)
+                memset( rowDst, (mode == STRETCH_ANDSCANS) ? 0xff : 0x00,
+                        widthDst*sizeof(int) );
+
+            /* Make copies of the destination row */
+
+            pdata = dstImage->data + dstImage->bytes_per_line * y;
+            while (((ysrc + yinc) >> 16 == ysrc >> 16) &&
+                   (ydst < visRectDst->bottom-1))
+            {
+                memcpy( pdata + dstImage->bytes_per_line, pdata,
+                        dstImage->bytes_per_line );
+                pdata += dstImage->bytes_per_line;
+                ysrc += yinc;
+                ydst++;
+            }
+        }        
     }
-    else
+    else  /* Shrinking */
     {
         yinc = ((int)heightDst << 16) / heightSrc;
         ysrc = visRectSrc->top;
-        ydst = yinc * ysrc - (vswap ? (heightDst-1)<<16 : 0);
-    }
-
-    while(vstretch ? (ydst < visRectDst->bottom) : (ysrc < visRectSrc->bottom))
-    {
-          /* Retrieve a source row */
-        BITBLT_GetRow( srcImage, rowSrc, vstretch ? ysrc >> 16 : ysrc,
-                       visRectSrc->left, visRectSrc->right - visRectSrc->left,
-                       dstImage->depth, foreground, background, hswap );
-
-          /* Stretch or shrink it */
-        if (hstretch)
-            BITBLT_StretchRow( rowSrc, rowDst, visRectDst->left +
-			       (hswap ? widthDst : 0),
-                               visRectDst->right-visRectDst->left, xinc, mode);
-        else BITBLT_ShrinkRow( rowSrc, rowDst, visRectSrc->left,
-                               visRectSrc->right-visRectSrc->left, xinc, mode);
-
-          /* When shrinking, merge several source rows into the destination */
-        if (!vstretch)
+        ydst = ((heightDst << 16) - (yinc * heightSrc)) / 2;
+        if (vswap)
         {
+            ydst += yinc * (heightSrc - ysrc - 1);
+            yinc = -yinc;
+        }
+        else
+            ydst += yinc * ysrc;
+
+        for( ; (ysrc < visRectSrc->bottom); ydst += yinc, ysrc++)
+        {
+            if (((ydst >> 16) < visRectDst->top) ||
+                ((ydst >> 16) >= visRectDst->bottom)) continue;
+
+            /* Retrieve a source row */
+            BITBLT_GetRow( srcImage, rowSrc, ysrc - visRectSrc->top,
+                           hswap ? widthSrc - visRectSrc->right
+                                 : visRectSrc->left,
+                           visRectSrc->right - visRectSrc->left,
+                           dstImage->depth, foreground, background, hswap );
+
+            /* Stretch or shrink it */
+            if (hstretch)
+                BITBLT_StretchRow( rowSrc, rowDst, visRectDst->left,
+                                   visRectDst->right - visRectDst->left,
+                                   xinc, xoff, mode );
+            else BITBLT_ShrinkRow( rowSrc, rowDst,
+                                   hswap ? widthSrc - visRectSrc->right
+                                         : visRectSrc->left,
+                                   visRectSrc->right - visRectSrc->left,
+                                   xinc, xoff, mode );
+
+            /* Merge several source rows into the destination */
             if (mode == STRETCH_DELETESCANS)
             {
-                  /* Simply skip the overlapping rows */
+                /* Simply skip the overlapping rows */
                 while (((ydst + yinc) >> 16 == ydst >> 16) &&
                        (ysrc < visRectSrc->bottom-1))
                 {
@@ -710,59 +787,18 @@
             }
             else if (((ydst + yinc) >> 16 == ydst >> 16) &&
                      (ysrc < visRectSrc->bottom-1))
-            {
-                ydst += yinc;
-                ysrc++;
                 continue;  /* Restart loop for next overlapping row */
-            }
-        }
         
-          /* Store the destination row */
-
-        pixel = rowDst + visRectDst->right - 1 + (hswap ? widthDst : 0);
-        if (vswap)
-            y = visRectDst->bottom - (vstretch ? ydst : ydst >> 16);
-        else
-            y = (vstretch ? ydst : ydst >> 16) - visRectDst->top;
-        for (x = visRectDst->right-visRectDst->left-1; x >= 0; x--)
-            XPutPixel( dstImage, x, y, *pixel-- );
-        if (mode != STRETCH_DELETESCANS)
-            memset( rowDst, (mode == STRETCH_ANDSCANS) ? 0xff : 0x00,
-                    widthDst*sizeof(int) );
-
-          /* If stretching, make copies of the destination row */
-
-        if (vstretch)
-        {
-            char *pdata = dstImage->data + dstImage->bytes_per_line * y;
-            while (((ysrc + yinc) >> 16 == ysrc >> 16) &&
-                   (ydst < visRectDst->bottom-1))
-            {
-                if (vswap)
-                {
-                    memcpy( pdata - dstImage->bytes_per_line, pdata,
-                            dstImage->bytes_per_line );
-                    pdata -= dstImage->bytes_per_line;
-                }
-                else
-                {
-                    memcpy( pdata + dstImage->bytes_per_line, pdata,
-                            dstImage->bytes_per_line );
-                    pdata += dstImage->bytes_per_line;
-                }
-                ysrc += yinc;
-                ydst++;
-            }
-            ysrc += yinc;
-            ydst++;
-        }
-        else
-        {
-            ydst += yinc;
-            ysrc++;
+            /* Store the destination row */
+            pixel = rowDst + visRectDst->right - 1;
+            y = (ydst >> 16) - visRectDst->top;
+            for (x = visRectDst->right-visRectDst->left-1; x >= 0; x--)
+                XPutPixel( dstImage, x, y, *pixel-- );
+            if (mode != STRETCH_DELETESCANS)
+                memset( rowDst, (mode == STRETCH_ANDSCANS) ? 0xff : 0x00,
+                        widthDst*sizeof(int) );
         }
     }        
-
     free( rowSrc );
 }
 
@@ -785,8 +821,14 @@
 
     RECT32 rectSrc = *visRectSrc;
     RECT32 rectDst = *visRectDst;
+
+    if (widthSrc < 0) xSrc += widthSrc;
+    if (widthDst < 0) xDst += widthDst;
+    if (heightSrc < 0) ySrc += heightSrc;
+    if (heightDst < 0) yDst += heightDst;
     OffsetRect32( &rectSrc, -xSrc, -ySrc );
     OffsetRect32( &rectDst, -xDst, -yDst );
+
     /* FIXME: avoid BadMatch errors */
     imageSrc = XGetImage( display, dcSrc->u.x.drawable,
                           visRectSrc->left, visRectSrc->top,
@@ -985,55 +1027,59 @@
                                        INT32 widthSrc, INT32 heightSrc,
                                        RECT32 *visRectSrc, RECT32 *visRectDst )
 {
-    RECT32 tmpRect, clipRect;
-
-    if (widthSrc < 0)  { widthSrc = -widthSrc; xSrc -= widthSrc; }
-    if (widthDst < 0)  { widthDst = -widthDst; xDst -= widthDst; }
-    if (heightSrc < 0) { heightSrc = -heightSrc; ySrc -= heightSrc; }
-    if (heightDst < 0) { heightDst = -heightDst; yDst -= heightDst; }
+    RECT32 rect, clipRect;
 
       /* Get the destination visible rectangle */
 
-    SetRect32( &tmpRect, xDst, yDst, xDst + widthDst, yDst + heightDst );
+    SetRect32( &rect, xDst, yDst, xDst + widthDst, yDst + heightDst );
+    if (widthDst < 0) SWAP_INT32( &rect.left, &rect.right );
+    if (heightDst < 0) SWAP_INT32( &rect.top, &rect.bottom );
     GetRgnBox32( dcDst->w.hGCClipRgn, &clipRect );
     OffsetRect32( &clipRect, dcDst->w.DCOrgX, dcDst->w.DCOrgY );
-    if (!IntersectRect32( visRectDst, &tmpRect, &clipRect )) return FALSE;
+    if (!IntersectRect32( visRectDst, &rect, &clipRect )) return FALSE;
 
       /* Get the source visible rectangle */
 
     if (!dcSrc) return TRUE;
-    SetRect32( &tmpRect, xSrc, ySrc, xSrc + widthSrc, ySrc + heightSrc );
+    SetRect32( &rect, xSrc, ySrc, xSrc + widthSrc, ySrc + heightSrc );
+    if (widthSrc < 0) SWAP_INT32( &rect.left, &rect.right );
+    if (heightSrc < 0) SWAP_INT32( &rect.top, &rect.bottom );
     /* Apparently the clip region is only for output, so use hVisRgn here */
     GetRgnBox32( dcSrc->w.hVisRgn, &clipRect );
     OffsetRect32( &clipRect, dcSrc->w.DCOrgX, dcSrc->w.DCOrgY );
-    if (!IntersectRect32( visRectSrc, &tmpRect, &clipRect )) return FALSE;
+    if (!IntersectRect32( visRectSrc, &rect, &clipRect )) return FALSE;
 
       /* Intersect the rectangles */
 
     if ((widthSrc == widthDst) && (heightSrc == heightDst)) /* no stretching */
     {
         OffsetRect32( visRectSrc, xDst - xSrc, yDst - ySrc );
-        if (!IntersectRect32( &tmpRect, visRectSrc, visRectDst )) return FALSE;
-        *visRectSrc = *visRectDst = tmpRect;
+        if (!IntersectRect32( &rect, visRectSrc, visRectDst )) return FALSE;
+        *visRectSrc = *visRectDst = rect;
         OffsetRect32( visRectSrc, xSrc - xDst, ySrc - yDst );
     }
     else  /* stretching */
     {
-        visRectSrc->left = xDst + (visRectSrc->left-xSrc)*widthDst/widthSrc;
-        visRectSrc->top = yDst + (visRectSrc->top-ySrc)*heightDst/heightSrc;
-        visRectSrc->right = xDst +
-                            ((visRectSrc->right-xSrc) * widthDst) / widthSrc;
-        visRectSrc->bottom = yDst +
-                         ((visRectSrc->bottom-ySrc) * heightDst) / heightSrc;
-        if (!IntersectRect32( &tmpRect, visRectSrc, visRectDst )) return FALSE;
-        *visRectSrc = *visRectDst = tmpRect;
-        visRectSrc->left = xSrc + (visRectSrc->left-xDst)*widthSrc/widthDst;
-        visRectSrc->top = ySrc + (visRectSrc->top-yDst)*heightSrc/heightDst;
-        visRectSrc->right = xSrc +
-                            ((visRectSrc->right-xDst) * widthSrc) / widthDst;
-        visRectSrc->bottom = ySrc +
-                         ((visRectSrc->bottom-yDst) * heightSrc) / heightDst;
-        if (IsRectEmpty32( visRectSrc )) return FALSE;
+        /* Map source rectangle into destination coordinates */
+        rect.left = xDst + (visRectSrc->left - xSrc)*widthDst/widthSrc;
+        rect.top = yDst + (visRectSrc->top - ySrc)*heightDst/heightSrc;
+        rect.right = xDst + ((visRectSrc->right - xSrc)*widthDst)/widthSrc;
+        rect.bottom = yDst + ((visRectSrc->bottom - ySrc)*heightDst)/heightSrc;
+        if (rect.left > rect.right) SWAP_INT32( &rect.left, &rect.right );
+        if (rect.top > rect.bottom) SWAP_INT32( &rect.top, &rect.bottom );
+        InflateRect32( &rect, 1, 1 );  /* Avoid rounding errors */
+        if (!IntersectRect32( visRectDst, &rect, visRectDst )) return FALSE;
+
+        /* Map destination rectangle back to source coordinates */
+        rect = *visRectDst;
+        rect.left = xSrc + (visRectDst->left - xDst)*widthSrc/widthDst;
+        rect.top = ySrc + (visRectDst->top - yDst)*heightSrc/heightDst;
+        rect.right = xSrc + ((visRectDst->right - xDst)*widthSrc)/widthDst;
+        rect.bottom = ySrc + ((visRectDst->bottom - yDst)*heightSrc)/heightDst;
+        if (rect.left > rect.right) SWAP_INT32( &rect.left, &rect.right );
+        if (rect.top > rect.bottom) SWAP_INT32( &rect.top, &rect.bottom );
+        InflateRect32( &rect, 1, 1 );  /* Avoid rounding errors */
+        if (!IntersectRect32( visRectSrc, &rect, visRectSrc )) return FALSE;
     }
     return TRUE;
 }
diff --git a/graphics/x11drv/init.c b/graphics/x11drv/init.c
index 4841c2b..e56b3d9 100644
--- a/graphics/x11drv/init.c
+++ b/graphics/x11drv/init.c
@@ -11,7 +11,7 @@
 
 
 static BOOL32 X11DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device,
-                               LPCSTR output, const DEVMODE* initData );
+                               LPCSTR output, const DEVMODE16* initData );
 static BOOL32 X11DRV_DeleteDC( DC *dc );
 
 static const DC_FUNCTIONS X11DRV_Funcs =
@@ -96,7 +96,7 @@
  *	     X11DRV_CreateDC
  */
 static BOOL32 X11DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device,
-                               LPCSTR output, const DEVMODE* initData )
+                               LPCSTR output, const DEVMODE16* initData )
 {
     X11DRV_PDEVICE *physDev;
 
diff --git a/if1632/advapi32.spec b/if1632/advapi32.spec
index 5647acb..9ce2f08 100644
--- a/if1632/advapi32.spec
+++ b/if1632/advapi32.spec
@@ -69,13 +69,13 @@
 0064 stub GetSidSubAuthority
 0065 stub GetSidSubAuthorityCount
 0066 stub GetTokenInformation
-0067 stdcall  GetUserNameA(ptr ptr) GetUserNameA
-0068 stub GetUserNameW
+0067 stdcall GetUserNameA(ptr ptr) GetUserName32A
+0068 stdcall GetUserNameW(ptr ptr) GetUserName32W
 0069 stub ImpersonateLoggedOnUser
 0070 stub ImpersonateNamedPipeClient
 0071 stub ImpersonateSelf
 0072 stub InitializeAcl
-0073 stub InitializeSecurityDescriptor
+0073 return InitializeSecurityDescriptor 8 1
 0074 stub InitializeSid
 0075 stub InitiateSystemShutdownA
 0076 stub InitiateSystemShutdownW
diff --git a/if1632/crtdll.spec b/if1632/crtdll.spec
index bf709fb..728ea41 100644
--- a/if1632/crtdll.spec
+++ b/if1632/crtdll.spec
@@ -3,8 +3,8 @@
 type	win32
 base	1
 
-001 stub ??2@YAPAXI@Z
-002 stub ??3@YAXPAX@Z
+001 cdecl ??2@YAPAXI@Z(long) CRTDLL_malloc
+002 cdecl ??3@YAXPAX@Z(long) CRTDLL_free
 003 stub ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z
 004 stub _CIacos
 005 stub _CIasin
@@ -324,13 +324,13 @@
 319 stub _vsnwprintf
 320 stub _wcsdup
 321 stub _wcsicmp
-322 stub _wcsicoll
-323 stub _wcslwr
+322 cdecl _wcsicoll(ptr ptr) CRTDLL__wcsicoll
+323 cdecl _wcslwr(ptr) CRTDLL__wcslwr
 324 stub _wcsnicmp
 325 stub _wcsnset
 326 stub _wcsrev
 327 stub _wcsset
-328 stub _wcsupr
+328 cdecl _wcsupr(ptr) CRTDLL__wcsupr
 329 extern _winmajor_dll CRTDLL_winmajor_dll
 330 extern _winminor_dll CRTDLL_winminor_dll
 331 extern _winver_dll CRTDLL_winver_dll
@@ -455,7 +455,7 @@
 450 stub rewind
 451 stub scanf
 452 stub setbuf
-453 stub setlocale
+453 cdecl setlocale(long ptr) CRTDLL_setlocale
 454 stub setvbuf
 455 stub signal
 456 cdecl sin(long) CRTDLL_sin
@@ -463,7 +463,7 @@
 458 cdecl sprintf() CRTDLL_sprintf
 459 cdecl sqrt(long) CRTDLL_sqrt
 460 cdecl srand(long) CRTDLL_srand
-461 stub sscanf
+461 cdecl sscanf() CRTDLL_sscanf
 462 cdecl strcat(ptr ptr) strcat
 463 cdecl strchr(ptr long) strchr
 464 cdecl strcmp(ptr ptr) strcmp
@@ -485,7 +485,7 @@
 480 cdecl strtol(ptr ptr long) strtol
 481 cdecl strtoul(ptr ptr long) strtoul
 482 cdecl strxfrm(ptr ptr long) strxfrm
-483 stub swprintf
+483 cdecl swprintf() CRTDLL_swprintf
 484 stub swscanf
 485 stub system
 486 cdecl tan(long) CRTDLL_tan
@@ -496,7 +496,7 @@
 491 cdecl tolower(long) CRTDLL_tolower
 492 cdecl toupper(long) CRTDLL_toupper
 493 stub towlower
-494 stub towupper
+494 cdecl towupper(long) CRTDLL_towupper
 495 stub ungetc
 496 stub ungetwc
 497 stub vfprintf
@@ -505,21 +505,21 @@
 500 cdecl vsprintf() CRTDLL_vsprintf
 501 stub vswprintf
 502 stub vwprintf
-503 stub wcscat
-504 stub wcschr
+503 cdecl wcscat(ptr ptr) lstrcat32W
+504 cdecl wcschr(ptr long) CRTDLL_wcschr
 505 stub wcscmp
-506 stub wcscoll
-507 stub wcscpy
+506 cdecl wcscoll(ptr ptr) CRTDLL_wcscoll
+507 cdecl wcscpy(ptr ptr) lstrcpy32W
 508 stub wcscspn
 509 stub wcsftime
-510 stub wcslen
-511 stub wcsncat
-512 stub wcsncmp
-513 stub wcsncpy
+510 cdecl wcslen(ptr) lstrlen32W
+511 cdecl wcsncat(ptr ptr long) lstrcatn32W
+512 cdecl wcsncmp(ptr ptr long) lstrncmp32W
+513 cdecl wcsncpy(ptr ptr long) lstrcpyn32W
 514 stub wcspbrk
-515 stub wcsrchr
-516 stub wcsspn
-517 stub wcsstr
+515 cdecl wcsrchr(ptr long) CRTDLL_wcsrchr
+516 cdecl wcsspn(ptr ptr) CRTDLL_wcsspn
+517 cdecl wcsstr(ptr ptr) CRTDLL_wcsstr
 518 stub wcstod
 519 stub wcstok
 520 stub wcstol
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index 55654d2..9e97789 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -59,7 +59,7 @@
 50  pascal16 CreateBrushIndirect(ptr) CreateBrushIndirect16
 51  pascal16 CreateCompatibleBitmap(word word word) CreateCompatibleBitmap
 52  pascal16 CreateCompatibleDC(word) CreateCompatibleDC
-53  pascal16 CreateDC(ptr ptr ptr ptr) CreateDC
+53  pascal16 CreateDC(ptr ptr ptr ptr) CreateDC16
 54  pascal16 CreateEllipticRgn(s_word s_word s_word s_word) CreateEllipticRgn16
 55  pascal16 CreateEllipticRgnIndirect(ptr) CreateEllipticRgnIndirect16
 56  pascal16 CreateFont(s_word s_word s_word s_word s_word word word word
@@ -98,7 +98,7 @@
 89  pascal16 GetTextCharacterExtra(word) GetTextCharacterExtra
 90  pascal GetTextColor(word) GetTextColor
 91  pascal GetTextExtent(word ptr s_word) GetTextExtent
-92  pascal16 GetTextFace(word s_word ptr) GetTextFace
+92  pascal16 GetTextFace(word s_word ptr) GetTextFace16
 93  pascal16 GetTextMetrics(word ptr) GetTextMetrics16
 94  pascal GetViewportExt(word) GetViewportExt
 95  pascal GetViewportOrg(word) GetViewportOrg
diff --git a/if1632/gdi32.spec b/if1632/gdi32.spec
index d013da5..7e41277 100644
--- a/if1632/gdi32.spec
+++ b/if1632/gdi32.spec
@@ -34,8 +34,8 @@
 0029 stub CreateColorSpaceW
 0030 stdcall CreateCompatibleBitmap(long long long) CreateCompatibleBitmap
 0031 stdcall CreateCompatibleDC(long) CreateCompatibleDC
-0032 stub CreateDCA
-0033 stub CreateDCW
+0032 stdcall CreateDCA(ptr ptr ptr ptr) CreateDC32A
+0033 stdcall CreateDCW(ptr ptr ptr ptr) CreateDC32W
 0034 stdcall CreateDIBPatternBrush(long long) CreateDIBPatternBrush32
 0035 stub CreateDIBPatternBrushPt
 0036 stub CreateDIBSection
@@ -94,9 +94,9 @@
 0086 stub EnumICMProfilesA
 0087 stub EnumICMProfilesW
 0088 stub EnumMetaFile
-0089 stdcall EnumObjects(long long ptr long) EnumObjects32
+0089 stdcall EnumObjects(long long ptr long) THUNK_EnumObjects32
 0090 stdcall EqualRgn(long long) EqualRgn32
-0091 stub Escape
+0091 stdcall Escape(long long long ptr ptr) Escape
 0092 stdcall ExcludeClipRect(long long long long long) ExcludeClipRect32
 0093 stub ExtCreatePen
 0094 stub ExtCreateRegion
@@ -158,9 +158,9 @@
 0150 stub GetCharABCWidthsFloatA
 0151 stub GetCharABCWidthsFloatW
 0152 stub GetCharABCWidthsW
-0153 stub GetCharWidth32A
+0153 stdcall GetCharWidth32A(long long long long) GetCharWidth
 0154 stub GetCharWidth32W
-0155 stub GetCharWidthA
+0155 stdcall GetCharWidthA(long long long long) GetCharWidth
 0156 stub GetCharWidthFloatA
 0157 stub GetCharWidthFloatW
 0158 stub GetCharWidthW
@@ -233,14 +233,14 @@
 0225 stub GetTextCharacterExtra
 0226 stub GetTextCharset
 0227 stdcall GetTextColor(long) GetTextColor
-0228 stub GetTextExtentExPointA
-0229 stub GetTextExtentExPointW
+0228 stdcall GetTextExtentExPointA(long ptr long long ptr ptr ptr) GetTextExtentExPoint32A
+0229 stdcall GetTextExtentExPointW(long ptr long long ptr ptr ptr) GetTextExtentExPoint32W
 0230 stdcall GetTextExtentPoint32A(long ptr long ptr) GetTextExtentPoint32A
 0231 stdcall GetTextExtentPoint32W(long ptr long ptr) GetTextExtentPoint32W
 0232 stdcall GetTextExtentPointA(long ptr long ptr) GetTextExtentPoint32ABuggy
 0233 stdcall GetTextExtentPointW(long ptr long ptr) GetTextExtentPoint32WBuggy
-0234 stdcall GetTextFaceA(long long ptr) GetTextFace
-0235 stub GetTextFaceW
+0234 stdcall GetTextFaceA(long long ptr) GetTextFace32A
+0235 stdcall GetTextFaceW(long long ptr) GetTextFace32W
 0236 stdcall GetTextMetricsA(long ptr) GetTextMetrics32A
 0237 stdcall GetTextMetricsW(long ptr) GetTextMetrics32W
 0238 stub GetTransform
@@ -280,8 +280,8 @@
 0272 stub PolyPolyline
 0273 stub PolyTextOutA
 0274 stub PolyTextOutW
-0275 stub Polygon
-0276 stub Polyline
+0275 stdcall Polygon(long ptr long) Polygon32
+0276 stdcall Polyline(long ptr long) Polyline32
 0277 stub PolylineTo
 0278 stdcall PtInRegion(long long long) PtInRegion32
 0279 stdcall PtVisible(long long long) PtVisible32
@@ -342,7 +342,7 @@
 0333 stub SetRelAbs
 0334 stdcall SetStretchBltMode(long long) SetStretchBltMode
 0335 stub SetSystemPaletteUse
-0336 stub SetTextAlign
+0336 stdcall SetTextAlign(long long) SetTextAlign
 0337 stub SetTextCharacterExtra
 0338 stdcall SetTextColor(long long) SetTextColor
 0339 stub SetTextJustification
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index eb3fd29..7d335ba 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -45,7 +45,7 @@
 46  pascal16 FreeModule(word) FreeModule16
 47  pascal16 GetModuleHandle(segptr) WIN16_GetModuleHandle
 48  pascal16 GetModuleUsage(word) GetModuleUsage
-49  pascal16 GetModuleFileName(word ptr s_word) GetModuleFileName
+49  pascal16 GetModuleFileName(word ptr s_word) GetModuleFileName16
 50  pascal GetProcAddress(word segptr) GetProcAddress16
 51  pascal MakeProcInstance(segptr word) MakeProcInstance16
 52  pascal16 FreeProcInstance(segptr) FreeProcInstance16
@@ -91,7 +91,7 @@
 92  pascal   GetTempDrive(byte) WIN16_GetTempDrive
 93  pascal16 GetCodeHandle(segptr) GetCodeHandle
 94  stub DefineHandleTable
-95  pascal16 LoadLibrary(ptr) LoadLibrary
+95  pascal16 LoadLibrary(ptr) LoadLibrary16
 96  pascal16 FreeLibrary(word) FreeLibrary
 97  pascal16 GetTempFileName(byte ptr word ptr) GetTempFileName16
 98  return GetLastDiskChange 0 0
@@ -271,10 +271,10 @@
 406 stub WritePrivateProfileStruct
 407 stub GetPrivateProfileStruct
 411 pascal   GetCurrentDirectory(long ptr) GetCurrentDirectory16
-412 pascal16 SetCurrentDirectory(ptr) SetCurrentDirectory
-413 stub FindFirstFile
-414 stub FindNextFile
-415 stub FindClose
+412 pascal16 SetCurrentDirectory(ptr) SetCurrentDirectory16
+413 pascal16 FindFirstFile(ptr ptr) FindFirstFile16
+414 pascal16 FindNextFile(word ptr) FindNextFile16
+415 pascal16 FindClose(word) FindClose16
 416 stub WritePrivateProfileSection
 417 stub WriteProfileSection
 418 stub GetPrivateProfileSection
diff --git a/if1632/kernel32.spec b/if1632/kernel32.spec
index 9c7501e..68d060c 100644
--- a/if1632/kernel32.spec
+++ b/if1632/kernel32.spec
@@ -7,7 +7,7 @@
 0002 stub AddConsoleAliasA
 0003 stub AddConsoleAliasW
 0004 stub AllocConsole
-0005 stub AreFileApisANSI
+0005 stdcall AreFileApisANSI() AreFileApisANSI
 0006 stub BackupRead
 0007 stub BackupSeek
 0008 stub BackupWrite
@@ -38,12 +38,12 @@
 0033 stub ConsoleSubst
 0034 stub ContinueDebugEvent
 0035 stub ConvertDefaultLocale
-0036 stub CopyFileA
+0036 stdcall CopyFileA(ptr ptr long) CopyFile32A
 0037 stub CopyFileW
 0038 stub CreateConsoleScreenBuffer
 0039 stdcall CreateDirectoryA(ptr ptr) CreateDirectory32A
-0040 stub CreateDirectoryExA
-0041 stub CreateDirectoryExW
+0040 stdcall CreateDirectoryExA(ptr ptr ptr) CreateDirectoryEx32A
+0041 stdcall CreateDirectoryExW(ptr ptr ptr) CreateDirectoryEx32W
 0042 stdcall CreateDirectoryW(ptr ptr) CreateDirectory32W
 0043 	stdcall CreateEventA(ptr long long ptr) CreateEventA
 0044 stub CreateEventW
@@ -76,7 +76,7 @@
 0071 stdcall DeleteFileA(ptr) DeleteFile32A
 0072 stdcall DeleteFileW(ptr) DeleteFile32W
 0073 stub DeviceIoControl
-0074 stub DisableThreadLibraryCalls
+0074 stdcall DisableThreadLibraryCalls(long) DisableThreadLibraryCalls
 0075 stub DisconnectNamedPipe
 0076 stdcall DosDateTimeToFileTime(long long ptr) DosDateTimeToFileTime
 0077 stub DuplicateConsoleHandle
@@ -141,7 +141,7 @@
 0136 stub FoldStringA
 0137 stub FoldStringW
 0138 stdcall FormatMessageA() WIN32_FormatMessage32A
-0139 stub FormatMessageW
+0139 stdcall FormatMessageW() WIN32_FormatMessage32W
 0140 stub FreeConsole
 0141 stdcall FreeEnvironmentStringsA(ptr)	FreeEnvironmentStringsA
 0142 stdcall FreeEnvironmentStringsW(ptr)	FreeEnvironmentStringsW
@@ -167,8 +167,8 @@
 0162 stdcall GetCommandLineW() GetCommandLine32W
 0163 stub GetCompressedFileSizeA
 0164 stub GetCompressedFileSizeW
-0165 stub GetComputerNameA
-0166 stub GetComputerNameW
+0165 stdcall GetComputerNameA(ptr ptr) GetComputerName32A
+0166 stdcall GetComputerNameW(ptr ptr) GetComputerName32W
 0167 stub GetConsoleAliasA
 0168 stub GetConsoleAliasExesA
 0169 stub GetConsoleAliasExesLengthA
@@ -179,7 +179,7 @@
 0174 stub GetConsoleAliasesLengthA
 0175 stub GetConsoleAliasesLengthW
 0176 stub GetConsoleAliasesW
-0177 stub GetConsoleCP
+0177 stdcall GetConsoleCP() GetConsoleCP
 0178 stub GetConsoleCommandHistoryA
 0179 stub GetConsoleCommandHistoryLengthA
 0180 stub GetConsoleCommandHistoryLengthW
@@ -190,11 +190,11 @@
 0185 stub GetConsoleFontSize
 0186 stub GetConsoleHardwareState
 0187 stub GetConsoleInputWaitHandle
-0188 stub GetConsoleMode
-0189 stub GetConsoleOutputCP
+0188 stdcall GetConsoleMode(long ptr) GetConsoleMode
+0189 stdcall GetConsoleOutputCP() GetConsoleOutputCP
 0190 stdcall GetConsoleScreenBufferInfo(long ptr) GetConsoleScreenBufferInfo
-0191 stub GetConsoleTitleA
-0192 stub GetConsoleTitleW
+0191 stdcall GetConsoleTitleA(ptr long) GetConsoleTitle32A
+0192 stdcall GetConsoleTitleW(ptr long) GetConsoleTitle32W
 0193 stub GetCurrencyFormatA
 0194 stub GetCurrencyFormatW
 0195 stub GetCurrentConsoleFont
@@ -214,9 +214,9 @@
 0209 stdcall GetDriveTypeW(ptr) GetDriveType32W
 0210	stdcall GetEnvironmentStrings()	GetEnvironmentStrings
 0211 stub GetEnvironmentStringsA
-0212 	stdcall GetEnvironmentStringsW()		GetEnvironmentStringsW
-0213    stdcall GetEnvironmentVariableA(ptr ptr long) GetEnvironmentVariableA
-0214 stub GetEnvironmentVariableW
+0212 stdcall GetEnvironmentStringsW() GetEnvironmentStringsW
+0213 stdcall GetEnvironmentVariableA(ptr ptr long) GetEnvironmentVariable32A
+0214 stdcall GetEnvironmentVariableW(ptr ptr long) GetEnvironmentVariable32W
 0215 stub GetExitCodeProcess
 0216 stub GetExitCodeThread
 0217 stdcall GetFileAttributesA(ptr) GetFileAttributes32A
@@ -226,7 +226,7 @@
 0221 stdcall GetFileTime(long ptr ptr ptr) GetFileTime
 0222 stdcall GetFileType(long) GetFileType
 0223 stdcall GetFullPathNameA(ptr long ptr ptr) GetFullPathName32A
-0224 stub GetFullPathNameW
+0224 stdcall GetFullPathNameW(ptr long ptr ptr) GetFullPathName32W
 0225 stub GetHandleInformation
 0226 stdcall GetLargestConsoleWindowSize(long) GetLargestConsoleWindowSize
 0227 stdcall GetLastError() GetLastError
@@ -237,10 +237,10 @@
 0232 stdcall GetLogicalDriveStringsW(long ptr) GetLogicalDriveStrings32W
 0233 stdcall GetLogicalDrives() GetLogicalDrives
 0234 stub GetMailslotInfo
-0235 stdcall GetModuleFileNameA(long ptr long) GetModuleFileName
-0236 stub GetModuleFileNameW
-0237	stdcall GetModuleHandleA(ptr)	WIN32_GetModuleHandle
-0238 stub GetModuleHandleW
+0235 stdcall GetModuleFileNameA(long ptr long) GetModuleFileName32A
+0236 stdcall GetModuleFileNameW(long ptr long) GetModuleFileName32W
+0237 stdcall GetModuleHandleA(ptr) WIN32_GetModuleHandleA
+0238 stdcall GetModuleHandleW(ptr) WIN32_GetModuleHandleW
 0239 stub GetNamedPipeHandleStateA
 0240 stub GetNamedPipeHandleStateW
 0241 stub GetNamedPipeInfo
@@ -275,9 +275,9 @@
 0270 stub GetQueuedCompletionStatus
 0271 stdcall GetShortPathNameA(ptr ptr long) GetShortPathName32A
 0272 stdcall GetShortPathNameW(ptr ptr long) GetShortPathName32W
-0273 stdcall GetStartupInfoA(ptr) GetStartupInfoA
-0274 stub GetStartupInfoW
-0275	stdcall GetStdHandle(long)	GetStdHandle
+0273 stdcall GetStartupInfoA(ptr) GetStartupInfo32A
+0274 stdcall GetStartupInfoW(ptr) GetStartupInfo32W
+0275 stdcall GetStdHandle(long)	GetStdHandle
 0276 stub GetStringTypeA
 0277 stub GetStringTypeExA
 0278 stub GetStringTypeExW
@@ -367,10 +367,10 @@
 0362 stub LCMapStringA
 0363 stub LCMapStringW
 0364 stdcall LeaveCriticalSection(ptr)	LeaveCriticalSection
-0365	stdcall LoadLibraryA(long)		LoadLibraryA
+0365 stdcall LoadLibraryA(ptr) LoadLibrary32A
 0366 stub LoadLibraryExA
 0367 stub LoadLibraryExW
-0368 stub LoadLibraryW
+0368 stdcall LoadLibraryW(ptr) LoadLibrary32W
 0369 stub LoadModule
 0370 stdcall LoadResource(long long) LoadResource32
 0371 stdcall LocalAlloc(long long) LocalAlloc32
@@ -384,7 +384,7 @@
 0379 stdcall LocalShrink(long long) LocalShrink32
 0380 stdcall LocalSize(long) LocalSize32
 0381 stdcall LocalUnlock(long) LocalUnlock32
-0382 stub LockFile
+0382 stdcall LockFile(long long long long long) LockFile
 0383 stub LockFileEx
 0384 stdcall LockResource(long) LockResource32
 0385 stdcall MapViewOfFile(long long long long long) MapViewOfFile
@@ -421,7 +421,7 @@
 0416 stub QueryPerformanceFrequency
 0417 stub QueryWin31IniFilesMappedToRegistry
 0418 stdcall RaiseException(long long long ptr) RaiseException
-0419 stub ReadConsoleA
+0419 stdcall ReadConsoleA(long ptr long ptr ptr) ReadConsole32A
 0420 stub ReadConsoleInputA
 0421 stub ReadConsoleInputW
 0422 stub ReadConsoleOutputA
@@ -429,7 +429,7 @@
 0424 stub ReadConsoleOutputCharacterA
 0425 stub ReadConsoleOutputCharacterW
 0426 stub ReadConsoleOutputW
-0427 stub ReadConsoleW
+0427 stdcall ReadConsoleW(long ptr long ptr ptr) ReadConsole32W
 0428 stdcall ReadFile(long ptr long ptr ptr) ReadFile
 0429 stub ReadFileEx
 0430 stub ReadProcessMemory
@@ -471,18 +471,18 @@
 0466 stub SetConsoleKeyShortcuts
 0467 stub SetConsoleMaximumWindowSize
 0468 stub SetConsoleMenuClose
-0469 stub SetConsoleMode
+0469 stdcall SetConsoleMode(long long) 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
+0476 stdcall SetConsoleTitleA(ptr) SetConsoleTitle32A
+0477 stdcall SetConsoleTitleW(ptr) SetConsoleTitle32W
 0478 stub SetConsoleWindowInfo
-0479 stdcall SetCurrentDirectoryA(ptr) SetCurrentDirectory
-0480 stub SetCurrentDirectoryW
+0479 stdcall SetCurrentDirectoryA(ptr) SetCurrentDirectory32A
+0480 stdcall SetCurrentDirectoryW(ptr) SetCurrentDirectory32W
 0481 stub SetDefaultCommConfigA
 0482 stub SetDefaultCommConfigW
 0483 stdcall SetEndOfFile(long) SetEndOfFile
@@ -490,8 +490,8 @@
 0485 stdcall SetEnvironmentVariableW(ptr ptr) SetEnvironmentVariable32W
 0486 stdcall SetErrorMode(long) SetErrorMode
 0487 	stdcall	SetEvent(long) SetEvent
-0488 stub SetFileApisToANSI
-0489 stub SetFileApisToOEM
+0488 stdcall SetFileApisToANSI() SetFileApisToANSI
+0489 stdcall SetFileApisToOEM() SetFileApisToOEM
 0490 stdcall SetFileAttributesA(ptr long) SetFileAttributes32A
 0491 stdcall SetFileAttributesW(ptr long) SetFileAttributes32W
 0492 stdcall SetFilePointer(long long ptr long) SetFilePointer
@@ -539,8 +539,8 @@
 0534 stub TransactNamedPipe
 0535 stdcall TransmitCommChar(long long) TransmitCommChar32
 0536 stub TrimVirtualBuffer
-0537    stdcall UnhandledExceptionFilter(ptr) UnhandledExceptionFilter
-0538 stub UnlockFile
+0537 stdcall UnhandledExceptionFilter(ptr) UnhandledExceptionFilter
+0538 stdcall UnlockFile(long long long long long) UnlockFile
 0539 stub UnlockFileEx
 0540 stdcall UnmapViewOfFile(ptr) UnmapViewOfFile
 0541 stub UpdateResourceA
@@ -569,7 +569,7 @@
 0564 stub WaitNamedPipeW
 0565 stdcall WideCharToMultiByte(long long ptr long ptr long ptr ptr)	WideCharToMultiByte
 0566 stdcall WinExec(ptr long) WinExec
-0567 stub WriteConsoleA
+0567 stdcall WriteConsoleA(long ptr long ptr ptr) WriteConsole32A
 0568 stub WriteConsoleInputA
 0569 stub WriteConsoleInputVDMA
 0570 stub WriteConsoleInputVDMW
@@ -579,7 +579,7 @@
 0574 stub WriteConsoleOutputCharacterA
 0575 stub WriteConsoleOutputCharacterW
 0576 stub WriteConsoleOutputW
-0577 stub WriteConsoleW
+0577 stdcall WriteConsoleW(long ptr long ptr ptr) WriteConsole32W
 0578 stdcall WriteFile(long ptr long ptr ptr) WriteFile
 0579 stub WriteFileEx
 0580 stub WritePrivateProfileSectionA
@@ -649,3 +649,10 @@
 0643 stub MapSLFix
 0644 stub UnMapSLFixArray
 0645 stub dprintf
+0646 stub CreateToolhelp32Snapshot
+0647 stub Module32First
+0648 stub Module32Next
+0649 stub Process32First
+0650 stub Process32Next
+0651 stub Thread32First
+0652 stub Thread32Next
diff --git a/if1632/keyboard.spec b/if1632/keyboard.spec
index bf3ba43..d88895c 100644
--- a/if1632/keyboard.spec
+++ b/if1632/keyboard.spec
@@ -16,7 +16,7 @@
 130 pascal16 GetKeyboardType(byte) GetKeyboardType
 131 pascal16 MapVirtualKey(word word) MapVirtualKey
 132 pascal16 GetKbCodePage() GetKbCodePage
-133 pascal16 GetKeyNameText(long ptr word) GetKeyNameText
+133 pascal16 GetKeyNameText(long ptr word) GetKeyNameText16
 134 pascal16 AnsiToOemBuff(ptr ptr word) AnsiToOemBuff
 135 pascal16 OemToAnsiBuff(ptr ptr word) OemToAnsiBuff
 #136	pascal	EnableKbSysReq
diff --git a/if1632/ntdll.spec b/if1632/ntdll.spec
index 5835922..6fc3482 100644
--- a/if1632/ntdll.spec
+++ b/if1632/ntdll.spec
@@ -90,7 +90,7 @@
 086 stub NtCreateThread
 087 stub NtCreateTimer
 088 stub NtCreateToken
-089 stub NtCurrentTeb
+089 register NtCurrentTeb() NtCurrentTeb
 090 stub NtDelayExecution
 091 stub NtDeleteFile
 092 stub NtDeleteKey
@@ -303,7 +303,7 @@
 299 stub RtlCopyLuid
 300 stub RtlCopyLuidAndAttributesArray
 301 stub RtlCopySecurityDescriptor
-302 stub RtlCopySid
+302 stdcall RtlCopySid(long ptr ptr) RtlCopySid
 303 stub RtlCopySidAndAttributesArray
 304 stub RtlCopyString
 305 stub RtlCopyUnicodeString
@@ -411,7 +411,7 @@
 407 stub RtlInitializeGenericTable
 408 stub RtlInitializeRXact
 409 stub RtlInitializeResource
-410 stub RtlInitializeSid
+410 stdcall RtlInitializeSid(ptr ptr long) RtlInitializeSid
 411 stub RtlInsertElementGenericTable
 412 stub RtlIntegerToChar
 413 stub RtlIntegerToUnicodeString
@@ -428,7 +428,7 @@
 424 stub RtlLargeIntegerSubtract
 425 stub RtlLargeIntegerToChar
 426 stub RtlLeaveCriticalSection
-427 stub RtlLengthRequiredSid
+427 stdcall RtlLengthRequiredSid(long) RtlLengthRequiredSid
 428 stub RtlLengthSecurityDescriptor
 429 stub RtlLengthSid
 430 stub RtlLocalTimeToSystemTime
@@ -442,14 +442,14 @@
 438 stub RtlNewInstanceSecurityObject
 439 stub RtlNewSecurityGrantedAccess
 440 stub RtlNewSecurityObject
-441 stub RtlNormalizeProcessParams
+441 stdcall RtlNormalizeProcessParams(ptr) RtlNormalizeProcessParams
 442 stub RtlNtStatusToDosError
 443 stub RtlNumberGenericTableElements
 444 stub RtlNumberOfClearBits
 445 stub RtlNumberOfSetBits
 446 stub RtlOemStringToUnicodeSize
 447 stub RtlOemStringToUnicodeString
-448 stub RtlOemToUnicodeN
+448 stdcall RtlOemToUnicodeN(ptr long ptr ptr long) RtlOemToUnicodeN
 449 stub RtlOpenCurrentUser
 450 stub RtlPcToFileHeader
 451 stub RtlPrefixString
@@ -497,8 +497,8 @@
 493 stub RtlSizeHeap
 494 stub RtlSplay
 495 stub RtlStartRXact
-496 stub RtlSubAuthorityCountSid
-497 stub RtlSubAuthoritySid
+496 stdcall RtlSubAuthorityCountSid(ptr) RtlSubAuthorityCountSid
+497 stdcall RtlSubAuthoritySid(ptr long) RtlSubAuthoritySid
 498 stub RtlSubtreePredecessor
 499 stub RtlSubtreeSuccessor
 500 stub RtlSystemTimeToLocalTime
@@ -512,11 +512,11 @@
 508 stub RtlUnicodeStringToCountedOemString
 509 stub RtlUnicodeStringToInteger
 510 stub RtlUnicodeStringToOemSize
-511 stub RtlUnicodeStringToOemString
+511 stdcall RtlUnicodeStringToOemString(ptr ptr long) RtlUnicodeStringToOemString
 512 stub RtlUnicodeToCustomCPN
 513 stub RtlUnicodeToMultiByteN
 514 stub RtlUnicodeToMultiByteSize
-515 stub RtlUnicodeToOemN
+515 stdcall RtlUnicodeToOemN(ptr long ptr ptr long) RtlUnicodeToOemN
 516 stub RtlUniform
 517 stub RtlUnlockHeap
 518 stub RtlUnwind
@@ -907,16 +907,16 @@
 903 stub memchr
 904 stub memcmp
 905 stub memcpy
-906 stub memmove
+906 stdcall memmove(ptr ptr long) memmove
 907 stub memset
 908 stub pow
 909 stub qsort
 910 stub sin
-911 stub sprintf
+911 stdcall sprintf() CRTDLL_sprintf
 912 stub sqrt
-913 stub sscanf
+913 stdcall sscanf() CRTDLL_sscanf
 914 stub strcat
-915 stub strchr
+915 stdcall strchr(ptr long) strchr
 916 stub strcmp
 917 stub strcpy
 918 stub strcspn
@@ -925,7 +925,7 @@
 921 stub strncmp
 922 stub strncpy
 923 stub strpbrk
-924 stub strrchr
+924 stdcall strrchr(ptr long) strrchr
 925 stub strspn
 926 stub strstr
 927 stub swprintf
diff --git a/if1632/ole32.spec b/if1632/ole32.spec
index d6ff57b..838a9d2 100644
--- a/if1632/ole32.spec
+++ b/if1632/ole32.spec
@@ -132,7 +132,7 @@
 127 stub OleSetContainedObject
 128 stub OleSetMenuDescriptor
 129 stub OleTranslateAccelerator
-130 stub OleUninitialize
+130 return OleUninitialize 0 0
 131 stub OpenOrCreateStream
 132 stub ProgIDFromCLSID
 133 stub ReadClassStg
diff --git a/if1632/shell32.spec b/if1632/shell32.spec
index 4b513b4..9977d78 100644
--- a/if1632/shell32.spec
+++ b/if1632/shell32.spec
@@ -4,7 +4,7 @@
 
 0000 stub CheckEscapesA
 0001 stub CheckEscapesW
-0002 stub CommandLineToArgvW
+0002 stdcall CommandLineToArgvW(ptr ptr) CommandLineToArgvW
 0003 stub Control_FillCache_RunDLL
 0004 stub Control_RunDLL
 0005 stub DllGetClassObject
@@ -85,7 +85,7 @@
 0080 stub SheShortenPathA
 0081 stub SheShortenPathW
 0082 stdcall ShellAboutA(long ptr ptr long) ShellAbout
-0083 stub ShellAboutW
+0083 stdcall ShellAboutW(long ptr ptr long) ShellAbout32W
 0084 stdcall ShellExecuteA(long ptr ptr ptr ptr long) ShellExecute
 0085 stub ShellExecuteEx
 0086 stub ShellExecuteExA
diff --git a/if1632/thunk.c b/if1632/thunk.c
index 5da3982..168f2eb 100644
--- a/if1632/thunk.c
+++ b/if1632/thunk.c
@@ -105,7 +105,7 @@
 INT32 THUNK_EnumObjects32( HDC32 hdc, INT32 nObjType,
                            GOBJENUMPROC32 func, LPARAM lParam )
 {
-    DECL_THUNK( thunk, func, CallTo32_4 );
+    DECL_THUNK( thunk, func, CallTo32_2 );
     return EnumObjects32( hdc, nObjType, (GOBJENUMPROC32)&thunk, lParam );
 }
 
diff --git a/if1632/user.spec b/if1632/user.spec
index 91a3792..c97fdc9 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -2,7 +2,7 @@
 type	win16
 heap	65520
 
-1   pascal16 MessageBox(word ptr ptr word) MessageBox
+1   pascal16 MessageBox(word ptr ptr word) MessageBox16
 2   stub OldExitWindows
 3   stub EnableOEMLayer
 4   stub DisableOEMLayer
@@ -37,7 +37,7 @@
 35  pascal16 IsWindowEnabled(word) IsWindowEnabled
 36  pascal16 GetWindowText(word segptr word) GetWindowText16
 37  pascal16 SetWindowText(word segptr) SetWindowText16
-38  pascal16 GetWindowTextLength(word) GetWindowTextLength
+38  pascal16 GetWindowTextLength(word) GetWindowTextLength16
 39  pascal16 BeginPaint(word ptr) BeginPaint16
 40  pascal16 EndPaint(word ptr) EndPaint16
 41  pascal16 CreateWindow(ptr ptr long s_word s_word s_word s_word
@@ -144,7 +144,7 @@
 142 pascal16 GetClipboardData(word) GetClipboardData
 143 pascal16 CountClipboardFormats() CountClipboardFormats
 144 pascal16 EnumClipboardFormats(word) EnumClipboardFormats
-145 pascal16 RegisterClipboardFormat(ptr) RegisterClipboardFormat
+145 pascal16 RegisterClipboardFormat(ptr) RegisterClipboardFormat16
 146 pascal16 GetClipboardFormatName(word ptr s_word) GetClipboardFormatName
 147 pascal16 SetClipboardViewer(word) SetClipboardViewer
 148 pascal16 GetClipboardViewer() GetClipboardViewer
@@ -423,7 +423,7 @@
 480 stub GetUserLocalObjType
 #481 HARDWARE_EVENT
 482 pascal16 EnableScrollBar(word word word) EnableScrollBar16
-483 pascal16 SystemParametersInfo(word word ptr word) SystemParametersInfo
+483 pascal16 SystemParametersInfo(word word ptr word) SystemParametersInfo16
 #484 __GP
 # Stubs for Hebrew version
 489 pascal16 USER_489() stub_USER_489
diff --git a/if1632/user32.spec b/if1632/user32.spec
index 75b8b0f..a0cb5c4 100644
--- a/if1632/user32.spec
+++ b/if1632/user32.spec
@@ -349,7 +349,7 @@
 0342 stub IsDialogMessageW
 0343 stdcall IsDlgButtonChecked(long long) IsDlgButtonChecked
 0344 stdcall IsIconic(long) IsIconic
-0345 stub IsMenu
+0345 stdcall IsMenu(long) IsMenu
 0346 stdcall IsRectEmpty(ptr) IsRectEmpty32
 0347 stdcall IsWindow(long) IsWindow
 0348 stdcall IsWindowEnabled(long) IsWindowEnabled
@@ -394,12 +394,12 @@
 0387 stub MenuWindowProcA
 0388 stub MenuWindowProcW
 0389 stdcall MessageBeep(long) MessageBeep
-0390	stdcall MessageBoxA(long ptr ptr long)	MessageBox
+0390 stdcall MessageBoxA(long ptr ptr long) MessageBox32A
 0391 stub MessageBoxExA
 0392 stub MessageBoxExW
 0393 stub MessageBoxIndirectA
 0394 stub MessageBoxIndirectW
-0395 stub MessageBoxW
+0395 stdcall MessageBoxW(long ptr ptr long) MessageBox32W
 0396 stdcall ModifyMenuA(long long long long ptr) ModifyMenu32A
 0397 stdcall ModifyMenuW(long long long long ptr) ModifyMenu32W
 0398 stdcall MoveWindow(long long long long long long) MoveWindow
@@ -434,8 +434,8 @@
 0427 stdcall RegisterClassExA(ptr) RegisterClassEx32A
 0428 stdcall RegisterClassExW(ptr) RegisterClassEx32W
 0429 stdcall RegisterClassW(ptr) RegisterClass32W
-0430 stdcall RegisterClipboardFormatA(ptr) RegisterClipboardFormat
-0431 stub RegisterClipboardFormatW
+0430 stdcall RegisterClipboardFormatA(ptr) RegisterClipboardFormat32A
+0431 stdcall RegisterClipboardFormatW(ptr) RegisterClipboardFormat32W
 0432 stub RegisterHotKey
 0433 stub RegisterLogonProcess
 0434 stub RegisterSystemThread
@@ -444,7 +444,7 @@
 0437 stdcall RegisterWindowMessageW(ptr) RegisterWindowMessage32W
 0438 stdcall ReleaseCapture() ReleaseCapture
 0439 stdcall ReleaseDC(long long) ReleaseDC32
-0440 stub RemoveMenu
+0440 stdcall RemoveMenu(long long long) RemoveMenu
 0441 stdcall RemovePropA(long ptr) RemoveProp32A
 0442 stdcall RemovePropW(long ptr) RemoveProp32W
 0443 stub ReplyMessage
@@ -543,8 +543,8 @@
 0536 stdcall SwapMouseButton(long) SwapMouseButton
 0537 stub SwitchDesktop
 0538 stub SwitchToThisWindow
-0539 	stdcall SystemParametersInfoA(long long ptr long) SystemParametersInfo
-0540 stub SystemParametersInfoW
+0539 stdcall SystemParametersInfoA(long long ptr long) SystemParametersInfo32A
+0540 stdcall SystemParametersInfoW(long long ptr long) SystemParametersInfo32W
 0541 stub TabbedTextOutA
 0542 stub TabbedTextOutW
 0543 stub TileChildWindows
diff --git a/if1632/winsock.spec b/if1632/winsock.spec
index 24d2fc0..fea16ef 100644
--- a/if1632/winsock.spec
+++ b/if1632/winsock.spec
@@ -25,7 +25,7 @@
 17  pascal16 recvfrom(word ptr word word ptr ptr) WINSOCK_recvfrom
 18  pascal16 select(word ptr ptr ptr ptr) WINSOCK_select
 19  pascal16 send(word ptr word word) WINSOCK_send
-20  pascal16 sendto(word ptr word word ptr ptr) WINSOCK_sendto
+20  pascal16 sendto(word ptr word word ptr word) WINSOCK_sendto
 21  pascal16 setsockopt(word word word ptr word) WINSOCK_setsockopt
 22  pascal16 shutdown(word word) WINSOCK_shutdown
 23  pascal16 socket(word word word) WINSOCK_socket
diff --git a/if1632/wsock32.spec b/if1632/wsock32.spec
index 7d5a520..8503c3d 100644
--- a/if1632/wsock32.spec
+++ b/if1632/wsock32.spec
@@ -26,12 +26,12 @@
 022 stub shutdown
 023 stub socket
 051 stdcall gethostbyaddr(ptr long long) gethostbyaddr
-052 stub gethostbyname
+052 stdcall gethostbyname(ptr) gethostbyname
 053 stub getprotobyname
 054 stub getprotobynumber
 055 stdcall getservbyname(ptr ptr) getservbyname
 056 stub getservbyport
-057 stub gethostname
+057 stdcall gethostname(ptr long) gethostname
 101 stub WSAAsyncSelect
 102 stub WSAAsyncGetHostByAddr
 103 stub WSAAsyncGetHostByName
diff --git a/include/bitmap.h b/include/bitmap.h
index 45cbad7..a27edc3 100644
--- a/include/bitmap.h
+++ b/include/bitmap.h
@@ -7,8 +7,19 @@
 #ifndef __WINE_BITMAP_H
 #define __WINE_BITMAP_H
 
+#include <X11/extensions/XShm.h>
 #include "gdi.h"
 
+#ifdef PRELIMINARY_WING16_SUPPORT
+
+typedef struct
+{
+  XShmSegmentInfo	si;
+  SEGPTR		bits;
+} __ShmBitmapCtl;
+
+#endif
+
   /* GDI logical bitmap object */
 typedef struct
 {
diff --git a/include/crtdll.h b/include/crtdll.h
new file mode 100644
index 0000000..beb87cc
--- /dev/null
+++ b/include/crtdll.h
@@ -0,0 +1,13 @@
+#ifndef _WINE_CRTDLL_H
+#define _WINE_CRTDLL_H
+
+#define CRTDLL_LC_ALL		0
+#define CRTDLL_LC_COLLATE	1
+#define CRTDLL_LC_CTYPE		2
+#define CRTDLL_LC_MONETARY	3
+#define CRTDLL_LC_NUMERIC	4
+#define CRTDLL_LC_TIME		5
+#define CRTDLL_LC_MIN		LC_ALL
+#define CRTDLL_LC_MAX		LC_TIME
+
+#endif
diff --git a/include/gdi.h b/include/gdi.h
index f4289fd..066bd02 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -148,7 +148,7 @@
     BOOL32     (*pArc)(DC*,INT32,INT32,INT32,INT32,INT32,INT32,INT32,INT32);
     BOOL32     (*pBitBlt)(DC*,INT32,INT32,INT32,INT32,DC*,INT32,INT32,DWORD);
     BOOL32     (*pChord)(DC*,INT32,INT32,INT32,INT32,INT32,INT32,INT32,INT32);
-    BOOL32     (*pCreateDC)(DC*,LPCSTR,LPCSTR,LPCSTR,const DEVMODE*);
+    BOOL32     (*pCreateDC)(DC*,LPCSTR,LPCSTR,LPCSTR,const DEVMODE16*);
     BOOL32     (*pDeleteDC)(DC*);
     BOOL32     (*pDeleteObject)(HGDIOBJ16);
     BOOL32     (*pEllipse)(DC*,INT32,INT32,INT32,INT32);
diff --git a/include/task.h b/include/task.h
index b12250f..04c48ba 100644
--- a/include/task.h
+++ b/include/task.h
@@ -103,7 +103,7 @@
   /* TDB flags */
 #define TDBF_WINOLDAP   0x0001
 #define TDBF_OS2APP     0x0008
-#define TDBF_WIN32S     0x0010
+#define TDBF_WIN32      0x0010
 
 #pragma pack(4)
 
diff --git a/include/wincon.h b/include/wincon.h
index c295bf7..0eb84a9 100644
--- a/include/wincon.h
+++ b/include/wincon.h
@@ -7,11 +7,20 @@
 #define CTRL_LOGOFF_EVENT 5
 #define CTRL_SHUTDOWN_EVENT 6
 
+/* Console Mode flags */
+#define ENABLE_PROCESSED_INPUT	0x01
+#define ENABLE_LINE_INPUT	0x02
+#define ENABLE_ECHO_INPUT	0x04
+#define ENABLE_WINDOW_INPUT	0x08
+#define ENABLE_MOUSE_INPUT	0x10
+
+#define ENABLE_PROCESSED_OUTPUT 0x01
+#define ENABLE_WRAP_AT_EOL_OUTPUT 0x02
+
+
 typedef BOOL32 HANDLER_ROUTINE(WORD);
 
-/*
- * Attributes flags:
- */
+/* Attributes flags: */
 
 #define FOREGROUND_BLUE      0x0001 /* text color contains blue. */
 #define FOREGROUND_GREEN     0x0002 /* text color contains green. */
@@ -47,211 +56,3 @@
 
 
 #endif  /* __WINE_WINCON_H */
-
-#if 0
-#ifndef _WINCON_H_
-#define _WINCON_H_
-
-#ifdef UNICODE
-#define FillConsoleOutputCharacter FillConsoleOutputCharacterW
-#define GetConsoleTitle GetConsoleTitleW
-#define PeekConsoleInput PeekConsoleInputW
-#define ReadConsole ReadConsoleW
-#define ReadConsoleInput ReadConsoleInputW
-#define ReadConsoleOutput ReadConsoleOutputW
-#define ReadConsoleOutputCharacter ReadConsoleOutputCharacterW
-#define ScrollConsoleScreenBuffer ScrollConsoleScreenBufferW
-#define SetConsoleTitle SetConsoleTitleW
-#define WriteConsole WriteConsoleW
-#define WriteConsoleInput WriteConsoleInputW
-#define WriteConsoleOutput WriteConsoleOutputW
-#define WriteConsoleOutputCharacter WriteConsoleOutputCharacterW
-#else
-#define FillConsoleOutputCharacter FillConsoleOutputCharacterA
-#define GetConsoleTitle GetConsoleTitleA
-#define PeekConsoleInput PeekConsoleInputA
-#define ReadConsole ReadConsoleA
-#define ReadConsoleInput ReadConsoleInputA
-#define ReadConsoleOutput ReadConsoleOutputA
-#define ReadConsoleOutputCharacter ReadConsoleOutputCharacterA
-#define ScrollConsoleScreenBuffer ScrollConsoleScreenBufferA
-#define SetConsoleTitle SetConsoleTitleA
-#define WriteConsole WriteConsoleA
-#define WriteConsoleInput WriteConsoleInputA
-#define WriteConsoleOutput WriteConsoleOutputA
-#define WriteConsoleOutputCharacter WriteConsoleOutputCharacterA
-#endif
-
-
-
-#if 0
-
-
-
-#define RIGHT_ALT_PRESSED 0x1
-#define LEFT_ALT_PRESSED 0x2
-#define RIGHT_CTRL_PRESSED 0x4
-#define LEFT_CTRL_PRESSED 0x8
-#define SHIFT_PRESSED 0x10
-#define NUMLOCK_ON 0x20
-#define SCROLLLOCK_ON 0x40
-#define CAPSLOCK_ON 0x80
-#define ENHANCED_KEY 0x100
-
-typedef struct
-  {
-    COORD dwMousePosition;
-    DWORD dwButtonState;
-    DWORD dwControlKeyState;
-    DWORD dwEventFlags;
-  }
-MOUSE_EVENT_RECORD;
-
-#define CONSOLE_TEXTMODE_BUFFER 1
-
-
-#define FROM_LEFT_1ST_BUTTON_PRESSED 0x0001
-#define RIGHTMOST_BUTTON_PRESSED 0x0002
-#define FROM_LEFT_2ND_BUTTON_PRESSED 0x0004
-#define FROM_LEFT_3RD_BUTTON_PRESSED 0x0008
-#define FROM_LEFT_4TH_BUTTON_PRESSED 0x0010
-
-
-
-
-#define MOUSE_MOVED 0x0001
-#define DOUBLE_CLICK 0x0002
-
-typedef struct
-  {
-    COORD size;
-  }
-WINDOW_BUFFER_SIZE_RECORD;
-
-typedef struct
-  {
-    UINT dwCommandId;
-  }
-MENU_EVENT_RECORD;
-
-typedef struct
-  {
-    BOOL bSetFocus;
-  }
-FOCUS_EVENT_RECORD;
-
-typedef struct
-  {
-    WORD EventType;
-    union
-      {
-	KEY_EVENT_RECORD KeyEvent;
-	MOUSE_EVENT_RECORD MouseEvent;
-	WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
-	MENU_EVENT_RECORD MenuEvent;
-	FOCUS_EVENT_RECORD FocusEvent;
-      }
-    Event;
-  }
-INPUT_RECORD;
-
-#define KEY_EVENT 0x1
-#define MOUSE_EVENT 0x2
-#define WINDOW_BUFFER_SIZE_EVENT 0x4
-#define MENU_EVENT 0x8
-#define FOCUS_EVENT 0x10
-
-typedef struct
-  {
-    union
-      {
-	WCHAR UnicodeChar;
-	CHAR AsciiChar;
-      }
-    Char;
-    WORD Attributes;
-  }
-CHAR_INFO;
-
-typedef struct
-  {
-    DWORD size;
-    BOOL bVisible;
-  }
-CONSOLE_CURSOR_INFO;
-
-#endif
-
-
-#if 0
-
-#define ENABLE_PROCESSED_INPUT 0x01
-#define ENABLE_LINE_INPUT 0x02
-#define ENABLE_ECHO_INPUT 0x04
-#define ENABLE_WINDOW_INPUT 0x08
-#define ENABLE_MOUSE_INPUT 0x10
-
-#define ENABLE_PROCESSED_OUTPUT 0x01
-#define ENABLE_WRAP_AT_EOL_OUTPUT 0x02
-
-
-BOOL AllocConsole (VOID);
-
-
-HANDLE CreateConsoleScreenBuffer (DWORD access, DWORD mode,
-                                  CONST SECURITY_ATTRIBUTES * lattr,
-                                  DWORD flags, VOID * ptr);
-BOOL FillConsoleOutputAttribute (HANDLE h, WORD attr, DWORD len,
-                                 COORD co, DWORD * done);
-BOOL FillConsoleOutputCharacterA (HANDLE h, CHAR c, DWORD len,
-                                  COORD co, DWORD * done);
-BOOL FlushBuffer (HANDLE h);
-BOOL FreeConsole (VOID);
-BOOL GenerateConsoleCtrlEvent (DWORD  ev,    DWORD group);
-UINT GetConsoleCP (VOID);
-BOOL GetConsoleCursorInfo (HANDLE h, CONSOLE_CURSOR_INFO *info);
-BOOL GetConsoleMode (HANDLE h, DWORD * mode);
-UINT GetConsoleOutputCP (VOID);
-BOOL GetConsoleScreenBufferInfo (HANDLE h, CONSOLE_SCREEN_BUFFER_INFO * ptr);
-DWORD GetConsoleTitleA (LPSTR str, DWORD len);
-COORD GetLargestConsoleWindowSize (HANDLE h);
-BOOL GetNumberOfConsoleInputEvents (HANDLE h, DWORD * n);
-BOOL GetNumberOfConsoleMouseButtons (DWORD * n);
-BOOL PeekConsoleInputA (HANDLE h, INPUT_RECORD * ptr, DWORD len, DWORD * done);
-BOOL ReadConsoleA (HANDLE h, VOID * ptr, DWORD len, DWORD * done, VOID * res);
-BOOL ReadConsoleInputA (HANDLE h, INPUT_RECORD * ptr, DWORD len, DWORD * done);
-BOOL ReadConsoleOutputA (HANDLE h, CHAR_INFO * ptr, COORD size,
-                         COORD fred, SMALL_RECT * reg);
-BOOL ReadConsoleOutputAttribute (HANDLE h, WORD * attr, DWORD len,
-                                 COORD rc, DWORD * done);
-BOOL ReadConsoleOutputCharacterA (HANDLE h, LPSTR c, DWORD len,
-                                  COORD rc, DWORD * done);
-BOOL ScrollConsoleScreenBufferA (HANDLE h, CONST SMALL_RECT * sr,
-                                 CONST SMALL_RECT * cr, COORD cpos,
-                                 CONST CHAR_INFO * i);
-BOOL SetConsoleActiveScreenBuffer (HANDLE h);
-BOOL SetConsoleCP (UINT i);
-BOOL SetConsoleCtrlHandler (HANDLER_ROUTINE * func,  BOOL a);
-BOOL SetConsoleCursorInfo (HANDLE h,  CONST CONSOLE_CURSOR_INFO * info);
-BOOL SetConsoleCursorPosition (HANDLE h, COORD pos);
-BOOL SetConsoleMode (HANDLE h, DWORD mode);
-BOOL SetConsoleOutputCP (UINT i);
-BOOL SetConsoleScreenBufferSize (HANDLE h, COORD size);
-BOOL SetConsoleTextAttribute (HANDLE h, WORD attrs);
-BOOL SetConsoleTitleA (const char * str);
-BOOL SetConsoleWindowInfo (HANDLE h, BOOL abs, CONST SMALL_RECT * wnd);
-BOOL WriteConsoleA (HANDLE h, CONST VOID *   ptr, DWORD slen,
-                    DWORD * done, VOID * res);
-BOOL WriteConsoleInputA (HANDLE	h, CONST INPUT_RECORD * ptr,
-                         DWORD len, DWORD * done);
-BOOL WriteConsoleOutputA (HANDLE  h, CONST CHAR_INFO * ptr,
-                          COORD size, COORD fred, 
-                          SMALL_RECT* where);
-BOOL WriteConsoleOutputAttribute (HANDLE h, CONST WORD *attr, DWORD len,
-                                  COORD co, DWORD * done);
-BOOL WriteConsoleOutputCharacterA (HANDLE h, const char * c, DWORD len,
-                                   COORD co, DWORD * done);
-#endif
-#endif
-
-#endif /* 0 */
diff --git a/include/windows.h b/include/windows.h
index 6571cc0..1bac570 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -1547,14 +1547,14 @@
 typedef struct
 {
     DWORD 	biSize;
-    DWORD 	biWidth;
-    DWORD 	biHeight;
+    LONG  	biWidth;
+    LONG  	biHeight;
     WORD 	biPlanes;
     WORD 	biBitCount;
     DWORD 	biCompression;
     DWORD 	biSizeImage;
-    DWORD 	biXPelsPerMeter;
-    DWORD 	biYPelsPerMeter;
+    LONG  	biXPelsPerMeter;
+    LONG  	biYPelsPerMeter;
     DWORD 	biClrUsed;
     DWORD 	biClrImportant;
 } BITMAPINFOHEADER, *LPBITMAPINFOHEADER;
@@ -1913,39 +1913,96 @@
 
 /* SystemParametersInfo */
 
-#define	SPI_GETBEEP			1
-#define	SPI_SETBEEP			2
-#define	SPI_GETMOUSE			3
-#define	SPI_SETMOUSE			4
-#define	SPI_GETBORDER			5
-#define	SPI_SETBORDER			6
-#define	SPI_GETKEYBOARDSPEED		10
-#define	SPI_SETKEYBOARDSPEED		11
-#define	SPI_LANGDRIVER			12
-#define SPI_ICONHORIZONTALSPACING	13
-#define SPI_GETSCREENSAVETIMEOUT	14
-#define SPI_SETSCREENSAVETIMEOUT	15
-#define SPI_GETSCREENSAVEACTIVE		16
-#define SPI_SETSCREENSAVEACTIVE		17
-#define SPI_GETGRIDGRANULARITY		18
-#define SPI_SETGRIDGRANULARITY		19
-#define SPI_SETDESKWALLPAPER		20
-#define SPI_SETDESKPATTERN		21
-#define SPI_GETKEYBOARDDELAY		22
-#define SPI_SETKEYBOARDDELAY		23
-#define SPI_ICONVERTICALSPACING		24
-#define SPI_GETICONTITLEWRAP		25
-#define SPI_SETICONTITLEWRAP		26
-#define SPI_GETMENUDROPALIGNMENT	27
-#define SPI_SETMENUDROPALIGNMENT	28
-#define SPI_SETDOUBLECLKWIDTH		29
-#define SPI_SETDOUBLECLKHEIGHT		30
-#define SPI_GETICONTITLELOGFONT		31
-#define SPI_SETDOUBLECLICKTIME		32
-#define SPI_SETMOUSEBUTTONSWAP		33
-#define SPI_SETICONTITLELOGFONT		34
-#define SPI_GETFASTTASKSWITCH		35
-#define SPI_SETFASTTASKSWITCH		36
+#define SPI_GETBEEP               1
+#define SPI_SETBEEP               2
+#define SPI_GETMOUSE              3
+#define SPI_SETMOUSE              4
+#define SPI_GETBORDER             5
+#define SPI_SETBORDER             6
+#define SPI_GETKEYBOARDSPEED      10
+#define SPI_SETKEYBOARDSPEED      11
+#define SPI_LANGDRIVER            12
+#define SPI_ICONHORIZONTALSPACING 13
+#define SPI_GETSCREENSAVETIMEOUT  14
+#define SPI_SETSCREENSAVETIMEOUT  15
+#define SPI_GETSCREENSAVEACTIVE   16
+#define SPI_SETSCREENSAVEACTIVE   17
+#define SPI_GETGRIDGRANULARITY    18
+#define SPI_SETGRIDGRANULARITY    19
+#define SPI_SETDESKWALLPAPER      20
+#define SPI_SETDESKPATTERN        21
+#define SPI_GETKEYBOARDDELAY      22
+#define SPI_SETKEYBOARDDELAY      23
+#define SPI_ICONVERTICALSPACING   24
+#define SPI_GETICONTITLEWRAP      25
+#define SPI_SETICONTITLEWRAP      26
+#define SPI_GETMENUDROPALIGNMENT  27
+#define SPI_SETMENUDROPALIGNMENT  28
+#define SPI_SETDOUBLECLKWIDTH     29
+#define SPI_SETDOUBLECLKHEIGHT    30
+#define SPI_GETICONTITLELOGFONT   31
+#define SPI_SETDOUBLECLICKTIME    32
+#define SPI_SETMOUSEBUTTONSWAP    33
+#define SPI_SETICONTITLELOGFONT   34
+#define SPI_GETFASTTASKSWITCH     35
+#define SPI_SETFASTTASKSWITCH     36
+#define SPI_SETDRAGFULLWINDOWS    37
+#define SPI_GETDRAGFULLWINDOWS    38
+#define SPI_GETNONCLIENTMETRICS   41
+#define SPI_SETNONCLIENTMETRICS   42
+#define SPI_GETMINIMIZEDMETRICS   43
+#define SPI_SETMINIMIZEDMETRICS   44
+#define SPI_GETICONMETRICS        45
+#define SPI_SETICONMETRICS        46
+#define SPI_SETWORKAREA           47
+#define SPI_GETWORKAREA           48
+#define SPI_SETPENWINDOWS         49
+#define SPI_GETFILTERKEYS         50
+#define SPI_SETFILTERKEYS         51
+#define SPI_GETTOGGLEKEYS         52
+#define SPI_SETTOGGLEKEYS         53
+#define SPI_GETMOUSEKEYS          54
+#define SPI_SETMOUSEKEYS          55
+#define SPI_GETSHOWSOUNDS         56
+#define SPI_SETSHOWSOUNDS         57
+#define SPI_GETSTICKYKEYS         58
+#define SPI_SETSTICKYKEYS         59
+#define SPI_GETACCESSTIMEOUT      60
+#define SPI_SETACCESSTIMEOUT      61
+#define SPI_GETSERIALKEYS         62
+#define SPI_SETSERIALKEYS         63
+#define SPI_GETSOUNDSENTRY        64
+#define SPI_SETSOUNDSENTRY        65
+#define SPI_GETHIGHCONTRAST       66
+#define SPI_SETHIGHCONTRAST       67
+#define SPI_GETKEYBOARDPREF       68
+#define SPI_SETKEYBOARDPREF       69
+#define SPI_GETSCREENREADER       70
+#define SPI_SETSCREENREADER       71
+#define SPI_GETANIMATION          72
+#define SPI_SETANIMATION          73
+#define SPI_GETFONTSMOOTHING      74
+#define SPI_SETFONTSMOOTHING      75
+#define SPI_SETDRAGWIDTH          76
+#define SPI_SETDRAGHEIGHT         77
+#define SPI_SETHANDHELD           78
+#define SPI_GETLOWPOWERTIMEOUT    79
+#define SPI_GETPOWEROFFTIMEOUT    80
+#define SPI_SETLOWPOWERTIMEOUT    81
+#define SPI_SETPOWEROFFTIMEOUT    82
+#define SPI_GETLOWPOWERACTIVE     83
+#define SPI_GETPOWEROFFACTIVE     84
+#define SPI_SETLOWPOWERACTIVE     85
+#define SPI_SETPOWEROFFACTIVE     86
+#define SPI_SETCURSORS            87
+#define SPI_SETICONS              88
+#define SPI_GETDEFAULTINPUTLANG   89
+#define SPI_SETDEFAULTINPUTLANG   90
+#define SPI_SETLANGTOGGLE         91
+#define SPI_GETWINDOWSEXTENSION   92
+#define SPI_SETMOUSETRAILS        93
+#define SPI_GETMOUSETRAILS        94
+#define SPI_SCREENSAVERRUNNING    97
 
 /* SystemParametersInfo flags */
 
@@ -2657,7 +2714,7 @@
 #define SS_LEFTNOWORDWRAP   0x0000000CL
 #define SS_NOPREFIX         0x00000080L
 
-/* Static Control Mesages */
+/* Static Control Messages */
 #define STM_SETICON         (WM_USER+0)
 #define STM_GETICON         (WM_USER+1)
 
@@ -3703,7 +3760,38 @@
         HANDLE32 hStdInput;
         HANDLE32 hStdOutput;
         HANDLE32 hStdError;
-} STARTUPINFO, *LPSTARTUPINFO;
+} STARTUPINFO32A, *LPSTARTUPINFO32A;
+
+typedef struct {
+        DWORD cb;
+        LPWSTR lpReserved;
+        LPWSTR lpDesktop;
+        LPWSTR lpTitle;
+        DWORD dwX;
+        DWORD dwY;
+        DWORD dwXSize;
+        DWORD dwYSize;
+        DWORD dwXCountChars;
+        DWORD dwYCountChars;
+        DWORD dwFillAttribute;
+        DWORD dwFlags;
+        WORD wShowWindow;
+        WORD cbReserved2;
+        BYTE *lpReserved2;
+        HANDLE32 hStdInput;
+        HANDLE32 hStdOutput;
+        HANDLE32 hStdError;
+} STARTUPINFO32W, *LPSTARTUPINFO32W;
+
+DECL_WINELIB_TYPE_AW(STARTUPINFO);
+DECL_WINELIB_TYPE_AW(LPSTARTUPINFO);
+
+typedef struct {
+	HANDLE32	hProcess;
+	HANDLE32	hThread;
+	DWORD		dwProcessId;
+	DWORD		dwThreadId;
+} PROCESS_INFORMATION,*LPPROCESS_INFORMATION;
 
 typedef struct {
         LONG Bias;
@@ -3814,34 +3902,113 @@
 #define HELP_MULTIKEY       0x0201
 #define HELP_SETWINPOS      0x0203
 
-typedef struct {
-        CHAR   dmDeviceName[32];
-        WORD   dmSpecVersion;
-        WORD   dmDriverVersion;
-        WORD   dmSize;
-        WORD   dmDriverExtra;
-        DWORD  dmFields;
-        short  dmOrientation;
-        short  dmPaperSize;
-        short  dmPaperLength;
-        short  dmPaperWidth;
-        short  dmScale;
-        short  dmCopies;
-        short  dmDefaultSource;
-        short  dmPrintQuality;
-        short  dmColor;
-        short  dmDuplex;
-        short  dmYResolution;
-        short  dmTTOption;
-        short  dmCollate;
-        CHAR   dmFormName[32];
-        WORD   dmUnusedPadding;
-        WORD   dmBitsPerPel;
-        DWORD  dmPelsWidth;
-        DWORD  dmPelsHeight;
-        DWORD  dmDisplayFlags;
-        DWORD  dmDisplayFrequency;
-} DEVMODE;
+#define CCHDEVICENAME 32
+#define CCHFORMNAME   32
+
+typedef struct
+{
+    BYTE   dmDeviceName[CCHDEVICENAME];
+    WORD   dmSpecVersion;
+    WORD   dmDriverVersion;
+    WORD   dmSize;
+    WORD   dmDriverExtra;
+    DWORD  dmFields;
+    INT16  dmOrientation;
+    INT16  dmPaperSize;
+    INT16  dmPaperLength;
+    INT16  dmPaperWidth;
+    INT16  dmScale;
+    INT16  dmCopies;
+    INT16  dmDefaultSource;
+    INT16  dmPrintQuality;
+    INT16  dmColor;
+    INT16  dmDuplex;
+    INT16  dmYResolution;
+    INT16  dmTTOption;
+    INT16  dmCollate;
+    BYTE   dmFormName[CCHFORMNAME];
+    WORD   dmUnusedPadding;
+    WORD   dmBitsPerPel;
+    DWORD  dmPelsWidth;
+    DWORD  dmPelsHeight;
+    DWORD  dmDisplayFlags;
+    DWORD  dmDisplayFrequency;
+} DEVMODE16, *LPDEVMODE16;
+
+typedef struct
+{
+    BYTE   dmDeviceName[CCHDEVICENAME];
+    WORD   dmSpecVersion;
+    WORD   dmDriverVersion;
+    WORD   dmSize;
+    WORD   dmDriverExtra;
+    DWORD  dmFields;
+    INT16  dmOrientation;
+    INT16  dmPaperSize;
+    INT16  dmPaperLength;
+    INT16  dmPaperWidth;
+    INT16  dmScale;
+    INT16  dmCopies;
+    INT16  dmDefaultSource;
+    INT16  dmPrintQuality;
+    INT16  dmColor;
+    INT16  dmDuplex;
+    INT16  dmYResolution;
+    INT16  dmTTOption;
+    INT16  dmCollate;
+    BYTE   dmFormName[CCHFORMNAME];
+    WORD   dmLogPixels;
+    DWORD  dmBitsPerPel;
+    DWORD  dmPelsWidth;
+    DWORD  dmPelsHeight;
+    DWORD  dmDisplayFlags;
+    DWORD  dmDisplayFrequency;
+    DWORD  dmICMMethod;
+    DWORD  dmICMIntent;
+    DWORD  dmMediaType;
+    DWORD  dmDitherType;
+    DWORD  dmReserved1;
+    DWORD  dmReserved2;
+} DEVMODE32A, *LPDEVMODE32A;
+
+typedef struct
+{
+    WCHAR  dmDeviceName[CCHDEVICENAME];
+    WORD   dmSpecVersion;
+    WORD   dmDriverVersion;
+    WORD   dmSize;
+    WORD   dmDriverExtra;
+    DWORD  dmFields;
+    INT16  dmOrientation;
+    INT16  dmPaperSize;
+    INT16  dmPaperLength;
+    INT16  dmPaperWidth;
+    INT16  dmScale;
+    INT16  dmCopies;
+    INT16  dmDefaultSource;
+    INT16  dmPrintQuality;
+    INT16  dmColor;
+    INT16  dmDuplex;
+    INT16  dmYResolution;
+    INT16  dmTTOption;
+    INT16  dmCollate;
+    WCHAR  dmFormName[CCHFORMNAME];
+    WORD   dmLogPixels;
+    DWORD  dmBitsPerPel;
+    DWORD  dmPelsWidth;
+    DWORD  dmPelsHeight;
+    DWORD  dmDisplayFlags;
+    DWORD  dmDisplayFrequency;
+    DWORD  dmICMMethod;
+    DWORD  dmICMIntent;
+    DWORD  dmMediaType;
+    DWORD  dmDitherType;
+    DWORD  dmReserved1;
+    DWORD  dmReserved2;
+} DEVMODE32W, *LPDEVMODE32W;
+
+DECL_WINELIB_TYPE_AW(DEVMODE);
+DECL_WINELIB_TYPE_AW(LPDEVMODE);
 
 typedef struct _SYSTEM_POWER_STATUS
 {
@@ -3924,17 +4091,98 @@
 
 typedef struct tagSYSTEM_INFO
 {
-    DWORD   dwOemId;
-    DWORD   dwPageSize;
-    LPVOID  lpMinimumApplicationAddress;
-    LPVOID  lpMaximumApplicationAddress;
-    DWORD   dwActiveProcessorMask;
-    DWORD   dwNumberOfProcessors;
-    DWORD   dwProcessorType;
-    DWORD   dwAllocationGranularity;
-    DWORD   dwReserved;
+    union {
+    	DWORD	dwOemId;
+	struct {
+		WORD wProcessorArchitecture;
+		WORD wReserved;
+	} x;
+    } u;
+    DWORD	dwPageSize;
+    LPVOID	lpMinimumApplicationAddress;
+    LPVOID	lpMaximumApplicationAddress;
+    DWORD	dwActiveProcessorMask;
+    DWORD	dwNumberOfProcessors;
+    DWORD	dwProcessorType;
+    DWORD	dwAllocationGranularity;
+    WORD	wProcessorLevel;
+    WORD	wProcessorRevision;
 } SYSTEM_INFO, *LPSYSTEM_INFO;
 
+/* u.x.wProcessorArchitecture (NT) */
+#define	PROCESSOR_ARCHITECTURE_INTEL	0
+#define	PROCESSOR_ARCHITECTURE_MIPS	1
+#define	PROCESSOR_ARCHITECTURE_ALPHA	2
+#define	PROCESSOR_ARCHITECTURE_PPC	3
+#define	PROCESSOR_ARCHITECTURE_UNKNOWN	0xFFFF
+
+/* dwProcessorType */
+#define	PROCESSOR_INTEL_386	386
+#define	PROCESSOR_INTEL_486	486
+#define	PROCESSOR_INTEL_PENTIUM	586
+#define	PROCESSOR_MIPS_R4000	4000
+#define	PROCESSOR_ALPHA_21064	21064
+
+/* service main function prototype */
+typedef VOID (*LPSERVICE_MAIN_FUNCTION32A)(DWORD,LPSTR);
+typedef VOID (*LPSERVICE_MAIN_FUNCTION32W)(DWORD,LPWSTR);
+DECL_WINELIB_TYPE_AW(LPSERVICE_MAIN_FUNCTION);
+
+/* service start table */
+typedef struct
+{
+    LPSTR			lpServiceName;
+    LPSERVICE_MAIN_FUNCTION32A	lpServiceProc;
+} *LPSERVICE_TABLE_ENTRY32A, SERVICE_TABLE_ENTRY32A;
+
+typedef struct
+{
+    LPWSTR			lpServiceName;
+    LPSERVICE_MAIN_FUNCTION32W	lpServiceProc;
+} *LPSERVICE_TABLE_ENTRY32W, SERVICE_TABLE_ENTRY32W;
+
+DECL_WINELIB_TYPE_AW(SERVICE_TABLE_ENTRY);
+DECL_WINELIB_TYPE_AW(LPSERVICE_TABLE_ENTRY);
+
+/* Security Ids of NT */
+
+typedef struct {
+	BYTE	Value[6];
+} SID_IDENTIFIER_AUTHORITY,*LPSID_IDENTIFIER_AUTHORITY;
+
+typedef struct _SID {
+	BYTE	Revision;
+	BYTE	SubAuthorityCount;
+	SID_IDENTIFIER_AUTHORITY	IdentifierAuthority;
+	DWORD	SubAuthority[1];	/* more than one */
+} SID,*LPSID;
+
+#define	SID_REVISION			(1)	/* Current revision */
+#define	SID_MAX_SUB_AUTHORITIES		(15)	/* current max subauths */
+#define	SID_RECOMMENDED_SUB_AUTHORITIES	(1)	/* recommended subauths */
+
+/* NT lowlevel Strings (handled by Rtl* functions in NTDLL)
+ * If they are zero terminated, Length does not include the terminating 0.
+ */
+
+typedef struct _STRING {
+	UINT16	Length;
+	UINT16	MaximumLength;
+	LPSTR	Buffer;
+} STRING,*LPSTRING,ANSI_STRING,*LPANSI_STRING;
+
+typedef struct _CSTRING {
+	UINT16	Length;
+	UINT16	MaximumLength;
+	LPCSTR	Buffer;
+} CSTRING,*LPCSTRING;
+
+typedef struct _UNICODE_STRING {
+	UINT16	Length;		/* bytes ? */
+	UINT16	MaximumLength;	/* bytes ? */
+	LPWSTR	Buffer;
+} UNICODE_STRING,*LPUNICODE_STRING;
+
 #pragma pack(4)
 
 /* Declarations for functions that exist only in Win16 */
@@ -3943,6 +4191,8 @@
 WORD       AllocDStoCSAlias(WORD);
 WORD       AllocSelector(WORD);
 WORD       AllocSelectorArray(WORD);
+LPSTR      AnsiLower(LPSTR);
+LPSTR      AnsiUpper(LPSTR);
 INT16      Catch(LPCATCHBUF);
 WORD       ChangeSelector(WORD,WORD);
 INT16      CloseComm(INT16);
@@ -4107,6 +4357,9 @@
 BOOL32     MoveFile32W(LPCWSTR,LPCWSTR);
 #define    MoveFile WINELIB_NAME_AW(MoveFile)
 BOOL32     QueryPerformanceCounter(LPLARGE_INTEGER);
+BOOL32     ReadConsole32A(HANDLE32,LPVOID,DWORD,LPDWORD,LPVOID);
+BOOL32     ReadConsole32W(HANDLE32,LPVOID,DWORD,LPDWORD,LPVOID);
+#define    ReadConsole WINELIB_NAME_AW(ReadConsole)
 BOOL32     ReadFile(HFILE,LPVOID,DWORD,LPDWORD,LPOVERLAPPED);
 DWORD      RegCreateKeyEx32A(HKEY,LPCSTR,DWORD,LPSTR,DWORD,REGSAM,
                              LPSECURITY_ATTRIBUTES,LPHKEY,LPDWORD);
@@ -4133,6 +4386,9 @@
 BOOL32     SetBrushOrgEx(HDC32,INT32,INT32,LPPOINT32);
 BOOL32     SetCommMask(INT32,DWORD);
 BOOL32     SetCommTimeouts(INT32,LPCOMMTIMEOUTS);
+BOOL32     SetConsoleTitle32A(LPCSTR);
+BOOL32     SetConsoleTitle32W(LPCWSTR);
+#define    SetConsoleTitle WINELIB_NAME_AW(SetConsoleTitle)
 BOOL32     SetEndOfFile(HFILE);
 DWORD      SetFilePointer(HFILE,LONG,LPLONG,DWORD);
 BOOL32     SetFileTime(HFILE,LPFILETIME,LPFILETIME,LPFILETIME);
@@ -4143,6 +4399,9 @@
 BOOL32     SystemTimeToFileTime(LPSYSTEMTIME,LPFILETIME);
 LPVOID     VirtualAlloc(LPVOID,DWORD,DWORD,DWORD);
 BOOL32     VirtualFree(LPVOID,DWORD,DWORD);
+BOOL32     WriteConsole32A(HANDLE32,LPVOID,DWORD,LPDWORD,LPVOID);
+BOOL32     WriteConsole32W(HANDLE32,LPVOID,DWORD,LPDWORD,LPVOID);
+#define    WriteConsole WINELIB_NAME_AW(WriteConsole)
 BOOL32     WriteFile(HFILE,LPVOID,DWORD,LPDWORD,LPOVERLAPPED);
 
 
@@ -4316,6 +4575,10 @@
 HBRUSH16   CreateBrushIndirect16(const LOGBRUSH16*);
 HBRUSH32   CreateBrushIndirect32(const LOGBRUSH32*);
 #define    CreateBrushIndirect WINELIB_NAME(CreateBrushIndirect)
+HDC16      CreateDC16(LPCSTR,LPCSTR,LPCSTR,const DEVMODE16*);
+HDC32      CreateDC32A(LPCSTR,LPCSTR,LPCSTR,const DEVMODE32A*);
+HDC32      CreateDC32W(LPCWSTR,LPCWSTR,LPCWSTR,const DEVMODE32W*);
+#define    CreateDC WINELIB_NAME_AW(CreateDC)
 HWND16     CreateDialog16(HINSTANCE16,SEGPTR,HWND16,DLGPROC16);
 #define    CreateDialog32A(inst,ptr,hwnd,dlg) \
            CreateDialogParam32A(inst,ptr,hwnd,dlg,0)
@@ -4343,6 +4606,9 @@
 BOOL32     CreateDirectory32A(LPCSTR,LPSECURITY_ATTRIBUTES);
 BOOL32     CreateDirectory32W(LPCWSTR,LPSECURITY_ATTRIBUTES);
 #define    CreateDirectory WINELIB_NAME_AW(CreateDirectory)
+BOOL32     CreateDirectoryEx32A(LPCSTR,LPCSTR,LPSECURITY_ATTRIBUTES);
+BOOL32     CreateDirectoryEx32W(LPCWSTR,LPCWSTR,LPSECURITY_ATTRIBUTES);
+#define    CreateDirectoryEx WINELIB_NAME_AW(CreateDirectoryEx)
 HRGN16     CreateEllipticRgn16(INT16,INT16,INT16,INT16);
 HRGN32     CreateEllipticRgn32(INT32,INT32,INT32,INT32);
 #define    CreateEllipticRgn WINELIB_NAME(CreateEllipticRgn)
@@ -4690,9 +4956,17 @@
 UINT16     GetInternalWindowPos16(HWND16,LPRECT16,LPPOINT16);
 UINT32     GetInternalWindowPos32(HWND32,LPRECT32,LPPOINT32);
 #define    GetInternalWindowPos WINELIB_NAME(GetInternalWindowPos)
+INT16      GetKeyNameText16(LONG,LPSTR,INT16);
+INT32      GetKeyNameText32A(LONG,LPSTR,INT32);
+INT32      GetKeyNameText32W(LONG,LPWSTR,INT32);
+#define    GetKeyNameText WINELIB_NAME_AW(GetKeyNameText)
 UINT32     GetLogicalDriveStrings32A(UINT32,LPSTR);
 UINT32     GetLogicalDriveStrings32W(UINT32,LPWSTR);
 #define    GetLogicalDriveStrings WINELIB_NAME_AW(GetLogicalDriveStrings)
+INT16      GetModuleFileName16(HINSTANCE16,LPSTR,INT16);
+DWORD      GetModuleFileName32A(HMODULE32,LPSTR,DWORD);
+DWORD      GetModuleFileName32W(HMODULE32,LPWSTR,DWORD);
+#define    GetModuleFileName WINELIB_NAME_AW(GetModuleFileName)
 HWND16     GetNextDlgGroupItem16(HWND16,HWND16,BOOL16);
 HWND32     GetNextDlgGroupItem32(HWND32,HWND32,BOOL32);
 #define    GetNextDlgGroupItem WINELIB_NAME(GetNextDlgGroupItem)
@@ -4768,6 +5042,10 @@
 BOOL32     GetTextExtentPoint32A(HDC32,LPCSTR,INT32,LPSIZE32);
 BOOL32     GetTextExtentPoint32W(HDC32,LPCWSTR,INT32,LPSIZE32);
 #define    GetTextExtentPoint WINELIB_NAME_AW(GetTextExtentPoint)
+INT16      GetTextFace16(HDC16,INT16,LPSTR);
+INT32      GetTextFace32A(HDC32,INT32,LPSTR);
+INT32      GetTextFace32W(HDC32,INT32,LPWSTR);
+#define    GetTextFace WINELIB_NAME_AW(GetTextFace)
 BOOL16     GetTextMetrics16(HDC16,LPTEXTMETRIC16);
 BOOL32     GetTextMetrics32A(HDC32,LPTEXTMETRIC32A);
 BOOL32     GetTextMetrics32W(HDC32,LPTEXTMETRIC32W);
@@ -4817,6 +5095,10 @@
 INT32      GetWindowText32A(HWND32,LPSTR,INT32);
 INT32      GetWindowText32W(HWND32,LPWSTR,INT32);
 #define    GetWindowText WINELIB_NAME_AW(GetWindowText)
+INT16      GetWindowTextLength16(HWND16);
+INT32      GetWindowTextLength32A(HWND32);
+INT32      GetWindowTextLength32W(HWND32);
+#define    GetWindowTextLength WINELIB_NAME_AW(GetWindowTextLength)
 ATOM       GlobalAddAtom16(SEGPTR);
 ATOM       GlobalAddAtom32A(LPCSTR);
 ATOM       GlobalAddAtom32W(LPCWSTR);
@@ -4951,6 +5233,10 @@
 HICON32    LoadIcon32A(HINSTANCE32,LPCSTR);
 HICON32    LoadIcon32W(HINSTANCE32,LPCWSTR);
 #define    LoadIcon WINELIB_NAME_AW(LoadIcon)
+HINSTANCE16 LoadLibrary16(LPCSTR);
+HINSTANCE32 LoadLibrary32A(LPCSTR);
+HINSTANCE32 LoadLibrary32W(LPCWSTR);
+#define    LoadLibrary WINELIB_NAME_AW(LoadLibrary)
 HMENU16    LoadMenu16(HINSTANCE16,SEGPTR);
 HMENU32    LoadMenu32A(HINSTANCE32,LPCSTR);
 HMENU32    LoadMenu32W(HINSTANCE32,LPCWSTR);
@@ -5014,6 +5300,10 @@
 void       MapWindowPoints16(HWND16,HWND16,LPPOINT16,UINT16);
 void       MapWindowPoints32(HWND32,HWND32,LPPOINT32,UINT32);
 #define    MapWindowPoints WINELIB_NAME(MapWindowPoints)
+INT16      MessageBox16(HWND16,LPCSTR,LPCSTR,UINT16);
+INT32      MessageBox32A(HWND32,LPCSTR,LPCSTR,UINT32);
+INT32      MessageBox32W(HWND32,LPCWSTR,LPCWSTR,UINT32);
+#define    MessageBox WINELIB_NAME_AW(MessageBox)
 BOOL16     ModifyMenu16(HMENU16,UINT16,UINT16,UINT16,SEGPTR);
 BOOL32     ModifyMenu32A(HMENU32,UINT32,UINT32,UINT32,LPCSTR);
 BOOL32     ModifyMenu32W(HMENU32,UINT32,UINT32,UINT32,LPCWSTR);
@@ -5122,6 +5412,10 @@
 ATOM       RegisterClassEx32A(const WNDCLASSEX32A *);
 ATOM       RegisterClassEx32W(const WNDCLASSEX32W *);
 #define    RegisterClassEx WINELIB_NAME_AW(RegisterClassEx)
+UINT16     RegisterClipboardFormat16(LPCSTR);
+UINT32     RegisterClipboardFormat32A(LPCSTR);
+UINT32     RegisterClipboardFormat32W(LPCWSTR);
+#define    RegisterClipboardFormat WINELIB_NAME_AW(RegisterClipboardFormat)
 WORD       RegisterWindowMessage16(SEGPTR);
 WORD       RegisterWindowMessage32A(LPCSTR);
 WORD       RegisterWindowMessage32W(LPCWSTR);
@@ -5314,6 +5608,10 @@
 BOOL16     SubtractRect16(LPRECT16,const RECT16*,const RECT16*);
 BOOL32     SubtractRect32(LPRECT32,const RECT32*,const RECT32*);
 #define    SubtractRect WINELIB_NAME(SubtractRect)
+BOOL16     SystemParametersInfo16(UINT16,UINT16,LPVOID,UINT16);
+BOOL32     SystemParametersInfo32A(UINT32,UINT32,LPVOID,UINT32);
+BOOL32     SystemParametersInfo32W(UINT32,UINT32,LPVOID,UINT32);
+#define    SystemParametersInfo WINELIB_NAME_AW(SystemParametersInfo)
 BOOL16     TextOut16(HDC16,INT16,INT16,LPCSTR,INT16);
 BOOL32     TextOut32A(HDC32,INT32,INT32,LPCSTR,INT32);
 BOOL32     TextOut32W(HDC32,INT32,INT32,LPCWSTR,INT32);
@@ -5471,13 +5769,11 @@
 ATOM       AddAtom(SEGPTR);
 INT        AddFontResource(LPCSTR);
 BOOL       AnimatePalette(HPALETTE16,UINT,UINT,LPPALETTEENTRY);
-LPSTR      AnsiLower(LPSTR);
 UINT       AnsiLowerBuff(LPSTR,UINT);
 SEGPTR     AnsiNext(SEGPTR);
 SEGPTR     AnsiPrev(SEGPTR,SEGPTR);
 INT        AnsiToOem(LPCSTR,LPSTR);
 void       AnsiToOemBuff(LPCSTR,LPSTR,UINT);
-LPSTR      AnsiUpper(LPSTR);
 UINT       AnsiUpperBuff(LPSTR,UINT);
 BOOL       AnyPopup(void);
 UINT       ArrangeIconicWindows(HWND);
@@ -5497,9 +5793,8 @@
 HDC16      CreateCompatibleDC(HDC16);
 HCURSOR16  CreateCursor(HINSTANCE16,INT,INT,INT,INT,const BYTE*,const BYTE*);
 HGLOBAL16  CreateCursorIconIndirect(HINSTANCE16,CURSORICONINFO*,const BYTE*,const BYTE*);
-HDC16      CreateDC(LPCSTR,LPCSTR,LPCSTR,const DEVMODE*);
 HBITMAP16  CreateDIBitmap(HDC16,BITMAPINFOHEADER*,DWORD,LPVOID,BITMAPINFO*,UINT);
-HDC16      CreateIC(LPCSTR,LPCSTR,LPCSTR,const DEVMODE*);
+HDC16      CreateIC(LPCSTR,LPCSTR,LPCSTR,const DEVMODE16*);
 HICON16    CreateIcon(HINSTANCE16,INT,INT,BYTE,BYTE,const BYTE*,const BYTE*);
 HMENU16    CreateMenu(void);
 HPALETTE16 CreatePalette(const LOGPALETTE*);
@@ -5566,7 +5861,6 @@
 BOOL       GetInputState(void);
 int        GetKBCodePage(void);
 int        GetKerningPairs(HDC16,int,LPKERNINGPAIR16);
-int        GetKeyNameText(LONG,LPSTR,int);
 INT        GetKeyState(INT);
 void       GetKeyboardState(BYTE*);
 int        GetKeyboardType(int);
@@ -5584,7 +5878,6 @@
 LONG       GetMessageTime(void);
 HMETAFILE16 GetMetaFile(LPSTR);
 HGLOBAL16  GetMetaFileBits(HMETAFILE16);
-INT16      GetModuleFileName(HINSTANCE16,LPSTR,INT16);
 HMODULE16  GetModuleHandle(LPCSTR);
 INT16      GetModuleUsage(HINSTANCE16);
 DWORD      GetNearestColor(HDC16,DWORD);
@@ -5610,7 +5903,6 @@
 short      GetTextCharacterExtra(HDC16);
 COLORREF   GetTextColor(HDC16);
 DWORD      GetTextExtent(HDC16,LPCSTR,short);
-INT        GetTextFace(HDC16,INT,LPSTR);
 LPINT16    GetThresholdEvent(void);
 int        GetThresholdStatus(void);
 HWND       GetTopWindow(HWND);
@@ -5621,7 +5913,6 @@
 HWND       GetWindow(HWND,WORD);
 DWORD      GetWindowExt(HDC16);
 DWORD      GetWindowOrg(HDC16);
-int        GetWindowTextLength(HWND);
 ATOM       GlobalDeleteAtom(ATOM);
 void       GlobalFix(HGLOBAL16);
 BOOL16     GlobalUnWire(HGLOBAL16);
@@ -5643,13 +5934,11 @@
 BOOL       IsWindowEnabled(HWND);
 BOOL       IsWindowVisible(HWND);
 BOOL       IsZoomed(HWND);
-HINSTANCE16 LoadLibrary(LPCSTR);
 HINSTANCE16 LoadModule(LPCSTR,LPVOID);
 FARPROC16  LocalNotify(FARPROC16);
 HMENU16    LookupMenuHandle(HMENU16,INT);
 WORD       MapVirtualKey(WORD,WORD);
 void       MessageBeep(WORD);
-int        MessageBox(HWND,LPCSTR,LPCSTR,WORD);
 BOOL       MoveWindow(HWND,short,short,short,short,BOOL);
 DWORD      OemKeyScan(WORD);
 BOOL       OemToAnsi(LPCSTR,LPSTR);
@@ -5671,7 +5960,6 @@
 void       ProfStart(void);
 void       ProfStop(void);
 WORD       RealizeDefaultPalette(HDC16);
-WORD       RegisterClipboardFormat(LPCSTR);
 BOOL       RemoveFontResource(LPSTR);
 BOOL       RemoveMenu(HMENU16,UINT,UINT);
 void       ReplyMessage(LRESULT);
@@ -5734,7 +6022,6 @@
 BOOL       SwapMouseButton(BOOL);
 void       SwapRecording(WORD);
 int        SyncAllVoices(void);
-BOOL       SystemParametersInfo(UINT,UINT,LPVOID,UINT);
 LONG       TabbedTextOut(HDC16,short,short,LPSTR,short,short,LPINT16,short);
 int        ToAscii(WORD,WORD,LPSTR,LPVOID,WORD);
 INT16      TranslateAccelerator(HWND,HACCEL16,LPMSG16);
diff --git a/include/winsock.h b/include/winsock.h
index ca7bcaf..0dfe7a3 100644
--- a/include/winsock.h
+++ b/include/winsock.h
@@ -433,7 +433,7 @@
   struct __aop *next, *prev;
   int           fd[2];				/* pipe */
   int   (*aop_control)(struct __aop*, int);	/* SIGIO handler */
-  pid_t         pid;			/* child process pid */
+  pid_t         pid;				/* child process pid */
 
   /* custom data */
 
@@ -443,7 +443,6 @@
   unsigned	flags;
   SEGPTR	buffer_base;
   int           buflen;
-  char*         init;			/* parameter data - length is in the async_ctl */
 } ws_async_op;
 
 #define WSMSG_ASYNC_SELECT      0x0000001
@@ -462,8 +461,8 @@
 {
   long          mtype;          /* WSMSG_... */
 
-  UINT32        lParam;
-  UINT16        wParam;         /* socket handle */
+  UINT32        lParam;		/* WS_FD_... event */
+  UINT16        wParam;         /* socket handle - used only for MTYPE_CLIENT messages */
 } ipc_packet;
 
 #define MTYPE_PARENT_SIZE \
@@ -476,7 +475,7 @@
 {
   int                   fd;
   unsigned              flags;
-  ws_async_op*          p_aop;
+  ws_async_op*          p_aop;	/* AsyncSelect() handler */
 } ws_socket;
 
 typedef struct
@@ -486,6 +485,7 @@
   int           lEvent;
   int           lLength;
   char*		buffer;
+  char*		init;
   ipc_packet    ip;
 } ws_async_ctl;
 
@@ -500,15 +500,17 @@
 
   unsigned		flags;
   int			errno;
-  int			num_startup;
-  int                   num_async_rq;
-  int                   last_free;
-  ws_socket             sock[WS_MAX_SOCKETS_PER_THREAD];
-  int			buflen;
-  char*			buffer;
+  INT16			num_startup;
+  INT16			num_async_rq;
+  INT16			last_free;
+  UINT16		buflen;
+  char*			buffer;			/* allocated from SEGPTR heap */
+  char*			dbuffer;		/* buffer for dummies (32 bytes) */
+
+  ws_socket		sock[WS_MAX_SOCKETS_PER_THREAD];
   FARPROC16		blocking_hook;
-  HTASK16               tid;    /* owning thread id - better switch
-                                 * to TLS when it gets fixed */
+  HTASK16               tid;    		/* owning thread id - better switch
+                                 		 * to TLS when it gets fixed */
 } WSINFO, *LPWSINFO;
 
 int WS_dup_he(LPWSINFO pwsi, struct hostent* p_he, int flag);
@@ -527,6 +529,7 @@
 void WINSOCK_unlink_async_op(ws_async_op* p_aop);
 void WINSOCK_cancel_async_op(HTASK16 tid);
 void WINSOCK_do_async_select(void);
+void WINSOCK_Shutdown(void);
 
 UINT16 wsaErrno(void);
 UINT16 wsaHerrno(void);
diff --git a/loader/module.c b/loader/module.c
index 3866137..ed35931 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -1075,7 +1075,7 @@
                     char *p;
 
                     /* Try with prepending the path of the current module */
-                    GetModuleFileName( hModule, buffer, sizeof(buffer) );
+                    GetModuleFileName16( hModule, buffer, sizeof(buffer) );
                     if (!(p = strrchr( buffer, '\\' ))) p = buffer;
                     memcpy( p + 1, pstr + 1, *pstr );
                     strcpy( p + 1 + *pstr, ".dll" );
@@ -1284,9 +1284,9 @@
 
 
 /**********************************************************************
- *	    GetModuleFileName    (KERNEL.49)
+ *	    GetModuleFileName16    (KERNEL.49)
  */
-INT16 GetModuleFileName( HINSTANCE16 hModule, LPSTR lpFileName, INT16 nSize )
+INT16 GetModuleFileName16( HINSTANCE16 hModule, LPSTR lpFileName, INT16 nSize )
 {
     NE_MODULE *pModule;
 
@@ -1294,10 +1294,44 @@
     hModule = GetExePtr( hModule );  /* In case we were passed an hInstance */
     if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
     lstrcpyn32A( lpFileName, NE_MODULE_NAME(pModule), nSize );
-    dprintf_module( stddeb, "GetModuleFilename: %s\n", lpFileName );
+    dprintf_module( stddeb, "GetModuleFileName16: %s\n", lpFileName );
     return strlen(lpFileName);
 }
 
+
+/***********************************************************************
+ *              GetModuleFileName32A      (KERNEL32.235)
+ */
+DWORD GetModuleFileName32A( HMODULE32 hModule, LPSTR lpFileName, DWORD size )
+{                   
+    NE_MODULE *pModule;
+           
+    if (!hModule)
+    {
+        TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
+        hModule = pTask->hInstance;
+    }
+    hModule = GetExePtr( hModule );  /* In case we were passed an hInstance */
+    if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
+    lstrcpyn32A( lpFileName, NE_MODULE_NAME(pModule), size );
+    dprintf_module( stddeb, "GetModuleFileName32A: %s\n", lpFileName );
+    return strlen(lpFileName);
+}                   
+ 
+
+/***********************************************************************
+ *              GetModuleFileName32W      (KERNEL32.236)
+ */
+DWORD GetModuleFileName32W( HMODULE32 hModule, LPWSTR lpFileName, DWORD size )
+{
+    LPSTR fnA = (char*)HeapAlloc( GetProcessHeap(), 0, size );
+    DWORD res = GetModuleFileName32A( hModule, fnA, size );
+    lstrcpynAtoW( lpFileName, fnA, size );
+    HeapFree( GetProcessHeap(), 0, fnA );
+    return res;
+}
+
+
 /**********************************************************************
  *	    GetModuleName    (KERNEL.27)
  */
@@ -1314,7 +1348,7 @@
 /***********************************************************************
  *           LoadLibrary   (KERNEL.95)
  */
-HINSTANCE16 LoadLibrary( LPCSTR libname )
+HINSTANCE16 LoadLibrary16( LPCSTR libname )
 {
     HINSTANCE16 handle;
 
diff --git a/loader/pe_image.c b/loader/pe_image.c
index 370b926..a99e627 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -194,7 +194,7 @@
 	    char *p, buffer[256];
 
 	    /* Try with prepending the path of the current module */
-	    GetModuleFileName (hModule, buffer, sizeof (buffer));
+	    GetModuleFileName16 (hModule, buffer, sizeof (buffer));
 	    if (!(p = strrchr (buffer, '\\')))
 		p = buffer;
 	    strcpy (p + 1, name);
@@ -389,6 +389,16 @@
 	lseek( fd, offset, SEEK_SET);
 	read( fd, pe->pe_header, sizeof(struct pe_header_s));
 
+/* FIXME: this is a *horrible* hack to make COMDLG32.DLL load OK. The
+problem needs to be fixed properly at some stage */
+
+	if (pe->pe_header->opt_coff.NumberOfRvaAndSizes != 16) {
+		printf("Short PE Header!!!\n");
+		lseek( fd, -(16 - pe->pe_header->opt_coff.NumberOfRvaAndSizes) * sizeof (struct Directory), SEEK_CUR);
+	}
+
+/* horrible hack ends !!! */
+
 	/* read sections */
 	pe->pe_seg = xmalloc(sizeof(struct pe_segment_table) * 
 				   pe->pe_header->coff.NumberOfSections);
@@ -627,14 +637,22 @@
 
 typedef struct _TEB
 {
-    void        *Except;
-    void        *stack;
-    int	        dummy1[4];
-    struct _TEB *TEBDSAlias;
-    int	        dummy2[2];
-    int	        taskid;
+    void        *Except;	/* 00 */
+    void        *stack;		/* 04 */
+    int	        dummy1[4];	/* 08 */
+    struct _TEB *TEBDSAlias;	/* 18 */
+    int	        dummy2[2];	/* 1C */
+    int	        taskid;		/* 24 */
+    int		dummy3[2];	/* 28 */
+    LPBYTE	process;	/* 30 */ /* points to current process struct */
 } TEB;
 
+/* the current process structure. Only the processheap is of interest (off 0x18) */
+struct {
+	DWORD		dummy[6];
+	HANDLE32	procheap; /* 18: Process Heap */
+} dummyprocess;
+
 void PE_InitTEB(int hTEB)
 {
     TDB *pTask;
@@ -646,6 +664,14 @@
     pTEB->Except = (void *)(-1); 
     pTEB->TEBDSAlias = pTEB;
     pTEB->taskid = getpid();
+
+    dummyprocess.procheap = GetProcessHeap();
+    pTEB->process = &dummyprocess;
+}
+
+VOID
+NtCurrentTeb(CONTEXT *context) {
+	context->Eax = GlobalLock16(LOWORD(context->SegFs));
 }
 
 void PE_InitializeDLLs(HMODULE16 hModule)
diff --git a/loader/resource.c b/loader/resource.c
index cf7cc0b..200406f 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -505,57 +505,6 @@
 
 
 /**********************************************************************
- *			TranslateAccelerator 	[USER.178]
- */
-INT16 TranslateAccelerator(HWND hWnd, HACCEL16 hAccel, LPMSG16 msg)
-{
-    ACCELHEADER	*lpAccelTbl;
-    int 	i;
-    
-    if (hAccel == 0 || msg == NULL) return 0;
-    if (msg->message != WM_KEYDOWN &&
-    	msg->message != WM_KEYUP &&
-	msg->message != WM_SYSKEYDOWN &&
-	msg->message != WM_SYSKEYUP &&
-    	msg->message != WM_CHAR) return 0;
-
-    dprintf_accel(stddeb, "TranslateAccelerators hAccel=%04x !\n", hAccel);
-
-    lpAccelTbl = (LPACCELHEADER)GlobalLock16(hAccel);
-    for (i = 0; i < lpAccelTbl->wCount; i++) {
-	if(lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) {
-	    if(msg->wParam == lpAccelTbl->tbl[i].wEvent &&
-	       (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)) {
-		INT mask = 0;
-
-		if(GetKeyState(VK_SHIFT) & 0x8000) mask |= SHIFT_ACCEL;
-		if(GetKeyState(VK_CONTROL) & 0x8000) mask |= CONTROL_ACCEL;
-		if(GetKeyState(VK_MENU) & 0x8000) mask |= ALT_ACCEL;
-		if(mask == (lpAccelTbl->tbl[i].type &
-			    (SHIFT_ACCEL | CONTROL_ACCEL | ALT_ACCEL))) {
-		    SendMessage16(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval,
-				0x00010000L);
-		    GlobalUnlock16(hAccel);
-		    return 1;
-	        }
-		if (msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP)
-		    return 1;
-	    }
-	}
-	else {
-	    if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
-		msg->message == WM_CHAR) {
-		SendMessage16(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
-		GlobalUnlock16(hAccel);
-		return 1;
-		}
-	    }
-	}
-    GlobalUnlock16(hAccel);
-    return 0;
-}
-
-/**********************************************************************
  *					LoadString16
  */
 INT16
diff --git a/loader/signal.c b/loader/signal.c
index d9238e3..a693c7d 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -9,6 +9,8 @@
 
 #include <sys/time.h>
 #include <sys/timeb.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 
 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__svr4__) || defined(_SCO_DS)
 #ifndef _SCO_DS
@@ -21,8 +23,10 @@
 
 #include "debugger.h"
 #include "miscemu.h"
+#include "options.h"
 #include "registers.h"
 #include "win.h"
+#include "winsock.h"
 
 #if !defined(BSD4_4) || defined(linux) || defined(__FreeBSD__)
 char * cstack[4096];
@@ -68,6 +72,45 @@
     DOSMEM_Tick();
 }
 
+/**********************************************************************
+ *              SIGNAL_break
+ * 
+ * Handle Ctrl-C and such
+ */
+#ifdef linux
+static void SIGNAL_break(int signal, SIGCONTEXT context_struct)
+{
+    SIGCONTEXT *context = &context_struct;
+#elif defined(__svr4__) || defined(_SCO_DS)
+static void SIGNAL_break(int signal, void *siginfo, SIGCONTEXT *context)
+{
+#else
+static void SIGNAL_break(int signal, int code, SIGCONTEXT *context)
+{
+#endif
+    if (Options.debug) wine_debug( signal, context );  /* Enter our debugger */
+    exit(0);
+}
+
+/**********************************************************************
+ *              SIGNAL_child
+ * 
+ * wait4 terminated child processes
+ */
+#ifdef linux
+static void SIGNAL_child(int signal, SIGCONTEXT context_struct)
+{
+    SIGCONTEXT *context = &context_struct;
+#elif defined(__svr4__) || defined(_SCO_DS)
+static void SIGNAL_child(int signal, void *siginfo, SIGCONTEXT *context)
+{
+#else
+static void SIGNAL_child(int signal, int code, SIGCONTEXT *context)
+{
+#endif
+   wait4( 0, NULL, WNOHANG, NULL);
+}
+
 
 /**********************************************************************
  *		SIGNAL_trap
@@ -206,6 +249,8 @@
 #endif  /* __svr4__ || _SCO_DS */
     
     SIGNAL_SetHandler( SIGALRM, (void (*)())wine_timer, 1);
+    SIGNAL_SetHandler( SIGINT,  (void (*)())SIGNAL_break, 1);
+    SIGNAL_SetHandler( SIGCHLD, (void (*)())SIGNAL_child, 1);
     SIGNAL_SetHandler( SIGSEGV, (void (*)())SIGNAL_fault, 1);
     SIGNAL_SetHandler( SIGILL,  (void (*)())SIGNAL_fault, 1);
     SIGNAL_SetHandler( SIGFPE,  (void (*)())SIGNAL_fault, 1);
diff --git a/loader/task.c b/loader/task.c
index 824e2d5..1795097 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -351,6 +351,7 @@
 static void TASK_CallToStart(void)
 {
     int cs_reg, ds_reg, fs_reg, ip_reg;
+    int exit_code = 1;
     TDB *pTask = (TDB *)GlobalLock16( hCurrentTask );
     NE_MODULE *pModule = MODULE_GetPtr( pTask->hModule );
     SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
@@ -372,8 +373,9 @@
         PE_InitTEB( fs_reg );
         __asm__ __volatile__("movw %w0,%%fs"::"r" (fs_reg));
         PE_InitializeDLLs( pTask->hModule );
-        CallTaskStart32( (FARPROC32)(pModule->pe_module->load_addr + 
+        exit_code = CallTaskStart32((FARPROC32)(pModule->pe_module->load_addr + 
                 pModule->pe_module->pe_header->opt_coff.AddressOfEntryPoint) );
+        TASK_KillCurrentTask( exit_code );
     }
     else
     {
@@ -402,11 +404,10 @@
                         pTask->hPDB /*es*/, 0 /*bp*/, 0 /*ax*/,
                         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" );
+        TASK_KillCurrentTask( 1 );
     }
-
-    /* This should never return */
-    fprintf( stderr, "TASK_CallToStart: Main program returned!\n" );
-    TASK_KillCurrentTask( 1 );
 }
 #endif
 
@@ -461,7 +462,7 @@
 
       /* Get current directory */
     
-    GetModuleFileName( hModule, filename, sizeof(filename) );
+    GetModuleFileName16( hModule, filename, sizeof(filename) );
     name = strrchr(filename, '\\');
     if (name) *(name+1) = 0;
 
@@ -470,6 +471,10 @@
     pTask->nEvents       = 1;  /* So the task can be started */
     pTask->hSelf         = hTask;
     pTask->flags         = 0;
+
+    if (pModule->flags & NE_FFLAGS_WIN32)
+    	pTask->flags 	|= TDBF_WIN32;
+
     pTask->version       = pModule->expected_version;
     pTask->hInstance     = hInstance;
     pTask->hPrevInstance = hPrevInstance;
diff --git a/memory/global.c b/memory/global.c
index 876c6c9..747d64c 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -587,7 +587,10 @@
  */
 DWORD GetFreeSpace( UINT16 wFlags )
 {
-    return GLOBAL_MAX_ALLOC_SIZE;
+    MEMORYSTATUS	ms;
+
+    GlobalMemoryStatus( &ms );
+    return ms.dwAvailVirtual;
 }
 
 
diff --git a/misc/Makefile.in b/misc/Makefile.in
index e21b133..6e34b27 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -20,6 +20,7 @@
 	main.c \
 	mpr.c \
 	network.c \
+	ntdll.c \
 	ole2.c \
 	ole2disp.c \
 	ole2nls.c \
diff --git a/misc/clipboard.c b/misc/clipboard.c
index ad09ada..47304e3 100644
--- a/misc/clipboard.c
+++ b/misc/clipboard.c
@@ -22,6 +22,7 @@
 #include "xmalloc.h"
 #include "stddebug.h"
 #include "debug.h"
+#include "string32.h"
 
 #define  CF_REGFORMATBASE 	0xC000
 
@@ -525,9 +526,9 @@
 
 
 /**************************************************************************
- *			RegisterClipboardFormat	[USER.145]
+ *            RegisterClipboardFormat16  (USER.145)
  */
-WORD RegisterClipboardFormat(LPCSTR FormatName)
+UINT16 RegisterClipboardFormat16( LPCSTR FormatName )
 {
     LPCLIPFORMAT lpNewFormat; 
     LPCLIPFORMAT lpFormat = ClipFormats; 
@@ -571,6 +572,28 @@
 
 
 /**************************************************************************
+ *            RegisterClipboardFormat32A   (USER32.430)
+ */
+UINT32 RegisterClipboardFormat32A( LPCSTR formatName )
+{
+    return RegisterClipboardFormat16( formatName );
+}
+
+
+/**************************************************************************
+ *            RegisterClipboardFormat32W   (USER32.431)
+ */
+UINT32 RegisterClipboardFormat32W( LPCWSTR formatName )
+{
+    LPSTR aFormat;
+    UINT32 ret;
+    aFormat = STRING32_DupUniToAnsi(formatName);
+    ret = RegisterClipboardFormat32A(aFormat);
+    free(aFormat);
+    return ret;
+}
+
+/**************************************************************************
  *			GetClipboardFormatName	[USER.146]
  */
 int GetClipboardFormatName(WORD wFormat, LPSTR retStr, short maxlen)
diff --git a/misc/commdlg.c b/misc/commdlg.c
index fddf5a9..7e06077 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -2767,7 +2767,7 @@
                    char buffer[80];
 	           sprintf(buffer,"Select a font size between %d and %d points.",
                            lpcf->nSizeMin,lpcf->nSizeMax);
-	           MessageBox(hDlg,buffer,NULL,MB_OK);
+	           MessageBox16(hDlg,buffer,NULL,MB_OK);
 	          } 
 		  return(TRUE);
 	case IDCANCEL:EndDialog(hDlg, FALSE);
diff --git a/misc/crtdll.c b/misc/crtdll.c
index 66b0549..5a35026 100644
--- a/misc/crtdll.c
+++ b/misc/crtdll.c
@@ -21,6 +21,8 @@
 #include "module.h"
 #include "xmalloc.h"
 #include "heap.h"
+#include "crtdll.h"
+#include "string32.h"
 
 UINT32 CRTDLL_argc_dll;         /* CRTDLL.23 */
 LPSTR *CRTDLL_argv_dll;         /* CRTDLL.24 */
@@ -575,6 +577,14 @@
     return vsprintf((char *)args[0],(char *)args[1],args+2);
 }
 
+/*********************************************************************
+ *                  vsprintf      (CRTDLL.500) (NTDLL.913)
+ */
+int CRTDLL_sscanf(DWORD *args)
+{
+    return vsscanf((char *)args[0],(char *)args[1],args+2);
+}
+
 
 /*********************************************************************
  *                  _mbscpy       (CRTDLL.200)
@@ -596,9 +606,9 @@
 /*********************************************************************
  *                  _strupr       (CRTDLL.300)
  */
-CHAR* CRTDLL__strupr(CHAR *x)
+LPSTR CRTDLL__strupr(LPSTR x)
 {
-	CHAR	*y=x;
+	LPSTR	y=x;
 
 	while (*y) {
 		*y=toupper(*y);
@@ -608,6 +618,35 @@
 }
 
 /*********************************************************************
+ *                  _wcsupr       (CRTDLL.328)
+ */
+LPWSTR CRTDLL__wcsupr(LPWSTR x)
+{
+	LPWSTR	y=x;
+
+	while (*y) {
+		*y=toupper(*y);
+		y++;
+	}
+	return x;
+}
+
+/*********************************************************************
+ *                  _wcslwr       (CRTDLL.323)
+ */
+LPWSTR CRTDLL__wcslwr(LPWSTR x)
+{
+	LPWSTR	y=x;
+
+	while (*y) {
+		*y=tolower(*y);
+		y++;
+	}
+	return x;
+}
+
+
+/*********************************************************************
  *                  malloc        (CRTDLL.427)
  */
 VOID* CRTDLL_malloc(DWORD size)
@@ -655,3 +694,126 @@
     dprintf_crtdll(stdnimp,"fclose(%p)\n",x);
     return 0;
 }
+
+/*********************************************************************
+ *                  setlocale           (CRTDLL.453)
+ */
+LPSTR CRTDLL_setlocale(INT32 category,LPCSTR locale)
+{
+	LPSTR categorystr;
+
+	switch (category) {
+	case CRTDLL_LC_ALL: categorystr="LC_ALL";break;
+	case CRTDLL_LC_COLLATE: categorystr="LC_COLLATE";break;
+	case CRTDLL_LC_CTYPE: categorystr="LC_CTYPE";break;
+	case CRTDLL_LC_MONETARY: categorystr="LC_MONETARY";break;
+	case CRTDLL_LC_NUMERIC: categorystr="LC_NUMERIC";break;
+	case CRTDLL_LC_TIME: categorystr="LC_TIME";break;
+	default: categorystr = "UNKNOWN?";break;
+	}
+	fprintf(stderr,"CRTDLL.setlocale(%s,%s),stub!\n",categorystr,locale);
+	return "C";
+}
+
+/*********************************************************************
+ *                  wcsspn           (CRTDLL.516)
+ */
+INT32 CRTDLL_wcsspn(LPWSTR str,LPWSTR accept)
+{
+	LPWSTR	s,t;
+
+	s=str;
+	do {
+		t=accept;
+		while (*t) { if (*t==*s) break;t++;}
+		if (!*t) break;
+		s++;
+	} while (*s);
+	return s-str; /* nr of wchars */
+}
+
+/*********************************************************************
+ *                  wcschr           (CRTDLL.504)
+ */
+LPWSTR CRTDLL_wcschr(LPWSTR str,WCHAR xchar)
+{
+	LPWSTR	s;
+
+	s=str;
+	do {
+		if (*s==xchar)
+			return s;
+	} while (*s++);
+	return NULL;
+}
+
+/*********************************************************************
+ *                  towupper           (CRTDLL.494)
+ */
+WCHAR CRTDLL_towupper(WCHAR x)
+{
+    return (WCHAR)toupper((CHAR)x);
+}
+
+/*********************************************************************
+ *                  swprintf           (CRTDLL.483)
+ */
+DWORD CRTDLL_swprintf(DWORD *args)
+{
+    return WIN32_wsprintf32W(args);
+}
+
+/*********************************************************************
+ *                  _wcsicoll           (CRTDLL.322)
+ */
+DWORD CRTDLL__wcsicoll(LPWSTR a1,LPWSTR a2)
+{
+    /* FIXME: handle collates */
+    return lstrcmpi32W(a1,a2);
+}
+
+/*********************************************************************
+ *                  wcscoll           (CRTDLL.506)
+ */
+DWORD CRTDLL_wcscoll(LPWSTR a1,LPWSTR a2)
+{
+    /* FIXME: handle collates */
+    return lstrcmp32W(a1,a2);
+}
+
+/*********************************************************************
+ *                  wcsstr           (CRTDLL.517)
+ */
+LPWSTR CRTDLL_wcsstr(LPWSTR s,LPWSTR b)
+{
+	LPWSTR	x,y,c;
+
+	x=s;
+	while (*x) {
+		if (*x==*b) {
+			y=x;c=b;
+			while (*y && *c && *y==*c) { c++;y++; }
+			if (!*c)
+				return x;
+		}
+		x++;
+	}
+	return NULL;
+}
+
+/*********************************************************************
+ *                  wcsrchr           (CRTDLL.515)
+ */
+LPWSTR CRTDLL_wcsrchr(LPWSTR str,WCHAR xchar)
+{
+	LPWSTR	s;
+
+	s=str+lstrlen32W(str);
+	do {
+		if (*s==xchar)
+			return s;
+		s--;
+	} while (s>=str);
+	return NULL;
+}
+
diff --git a/misc/driver.c b/misc/driver.c
index c0a23b0..82a6414 100644
--- a/misc/driver.c
+++ b/misc/driver.c
@@ -232,8 +232,8 @@
 	return (LRESULT)0L;
 
       case DRV_CONFIGURE:
-	MessageBox( (HWND)NULL, "Driver isn't configurable !", 
-		    "Wine Driver", MB_OK );
+	MessageBox16( (HWND)NULL, "Driver isn't configurable !", 
+                      "Wine Driver", MB_OK );
 	return (LRESULT)0L;
 
       case DRV_INSTALL:
diff --git a/misc/keyboard.c b/misc/keyboard.c
index cf0cbbe..4b5638c 100644
--- a/misc/keyboard.c
+++ b/misc/keyboard.c
@@ -12,6 +12,7 @@
 #include "stddebug.h"
 /* #define DEBUG_KEYBOARD */
 #include "debug.h"
+#include "xmalloc.h"
 
 
 struct KeyTableEntry {
@@ -217,6 +218,12 @@
 	return -1;
 }
 
+WORD VkKeyScan32W(WORD cChar)
+{
+	/* lower part of cChar is used anyway */
+	return VkKeyScan(cChar);
+}
+
 int GetKeyboardType(int nTypeFlag)
 {
   dprintf_keyboard(stddeb,"GetKeyboardType(%d)\n",nTypeFlag);
@@ -277,7 +284,31 @@
 	return 850;
 }
 
-int GetKeyNameText(LONG lParam, LPSTR lpBuffer, int nSize)
+/****************************************************************************
+ *	GetKeyNameText32W   (USER32.247)
+ */
+INT32 GetKeyNameText32W(LONG lParam, LPWSTR lpBuffer, INT32 nSize)
+{
+	LPSTR buf = xmalloc(nSize);
+	int	res = GetKeyNameText32A(lParam,buf,nSize);
+
+	lstrcpynAtoW(lpBuffer,buf,nSize);
+	free(buf);
+	return res;
+}
+
+/****************************************************************************
+ *	GetKeyNameText32A   (USER32.246)
+ */
+INT32 GetKeyNameText32A(LONG lParam, LPSTR lpBuffer, INT32 nSize)
+{
+	return GetKeyNameText16(lParam,lpBuffer,nSize);
+}
+
+/****************************************************************************
+ *	GetKeyNameText16   (KEYBOARD.133)
+ */
+INT16 GetKeyNameText16(LONG lParam, LPSTR lpBuffer, INT16 nSize)
 {
 	int i;
 	
diff --git a/misc/lstr.c b/misc/lstr.c
index 33b65d8..ece2f03 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -819,3 +819,193 @@
 		xargs
 	);
 }
+
+DWORD
+FormatMessage32W(
+	DWORD	dwFlags,
+	LPCVOID	lpSource,
+	DWORD	dwMessageId,
+	DWORD	dwLanguageId,
+	LPWSTR	lpBuffer,
+	DWORD	nSize,
+	LPDWORD	args /* va_list *args */
+) {
+	LPSTR	target,t;
+	DWORD	talloced;
+	LPSTR	from,f;
+	DWORD	width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
+	DWORD	nolinefeed = 0;
+
+	dprintf_resource(stddeb,
+		"FormatMessage32A(0x%lx,%p,%ld,0x%lx,%p,%ld,%p)\n",
+		dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args
+	);
+	if (width) 
+		fprintf(stdnimp,"	- line wrapping not supported.\n");
+	from = NULL;
+	if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
+		from = STRING32_DupUniToAnsi((LPWSTR)lpSource);
+	if (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM) {
+		/* gather information from system message tables ... */
+		fprintf(stdnimp,"	- FORMAT_MESSAGE_FROM_SYSTEM not implemented.\n");
+	}
+	if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE) {
+		INT32	bufsize;
+
+		dwMessageId &= 0xFFFF;
+		bufsize=LoadMessage32A(0,dwMessageId,dwLanguageId,NULL,100);
+		if (bufsize) {
+			from = (char*)xmalloc(bufsize+1);
+			LoadMessage32A(0,dwMessageId,dwLanguageId,from,bufsize+1);
+		}
+	}
+	target	= (char*)xmalloc(100);
+	t	= target;
+	talloced= 100;
+	*t	= 0;
+
+#define ADD_TO_T(c) \
+	*t++=c;\
+	if (t-target == talloced) {\
+		target	= (char*)xrealloc(target,talloced*2);\
+		t	= target+talloced;\
+		talloced*=2;\
+	}
+
+	if (from) {
+		f=from;
+		while (*f) {
+			if (*f=='%') {
+				int	insertnr;
+				char	*fmtstr,*sprintfbuf,*x;
+				DWORD	*argliststart;
+
+				fmtstr = NULL;
+				f++;
+				if (!*f) {
+					ADD_TO_T('%');
+					continue;
+				}
+				switch (*f) {
+				case '1':case '2':case '3':case '4':case '5':
+				case '6':case '7':case '8':case '9':
+					insertnr=*f-'0';
+					switch (f[1]) {
+					case '0':case '1':case '2':case '3':
+					case '4':case '5':case '6':case '7':
+					case '8':case '9':
+						f++;
+						insertnr=insertnr*10+*f-'0';
+						f++;
+						break;
+					default:
+						f++;
+						break;
+					}
+					if (*f=='!') {
+						f++;
+						if (NULL!=(x=strchr(f,'!'))) {
+							*x='\0';
+							fmtstr=(char*)xmalloc(strlen(f)+2);
+							sprintf(fmtstr,"%%%s",f);
+							f=x+1;
+						}
+					} else
+						fmtstr=strdup("%s");
+					if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY)
+						argliststart=args+insertnr-1;
+					else
+						/* FIXME: not sure that this is
+						 * correct for unix-c-varargs.
+						 */
+						argliststart=((DWORD*)&args)+insertnr-1;
+
+					if (fmtstr[strlen(fmtstr)]=='s') {
+						DWORD	xarr[3];
+
+						xarr[0]=(DWORD)STRING32_DupUniToAnsi((LPWSTR)(*(argliststart+0)));
+						/* possible invalid pointers */
+						xarr[1]=*(argliststart+1);
+						xarr[2]=*(argliststart+2);
+						sprintfbuf=(char*)xmalloc(lstrlen32W((LPWSTR)argliststart[0])*2+1);
+						vsprintf(sprintfbuf,fmtstr,xarr);
+					} else {
+						sprintfbuf=(char*)xmalloc(100);
+						vsprintf(sprintfbuf,fmtstr,argliststart);
+					}
+					x=sprintfbuf;
+					while (*x) {
+						ADD_TO_T(*x++);
+					}
+					free(sprintfbuf);
+					free(fmtstr);
+					break;
+				case '0':
+					nolinefeed=1;
+					f++;
+					break;
+				default:ADD_TO_T(*f++)
+					break;
+
+				}
+			} else {
+				ADD_TO_T(*f++)
+			}
+		}
+		*t='\0';
+	}
+	if (!nolinefeed && t[-1]!='\n')
+		ADD_TO_T('\n');
+	talloced = strlen(target)+1;
+	if (nSize && talloced<nSize)
+		target = (char*)xrealloc(target,nSize);
+	if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
+		/* nSize is the MINIMUM size */
+		*((LPVOID*)lpBuffer) = (LPVOID)LocalAlloc32(GMEM_ZEROINIT,talloced*2+2);
+		lstrcpynAtoW(*(LPWSTR*)lpBuffer,target,talloced);
+	} else
+		lstrcpynAtoW(lpBuffer,target,nSize);
+	free(target);
+	if (from) free(from);
+	return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ? 
+			lstrlen32W(*(LPWSTR*)lpBuffer):
+			lstrlen32W(lpBuffer);
+}
+
+/***********************************************************************
+ *           FormatMessageA   (KERNEL32.138) Emulator Version
+ */
+DWORD
+WIN32_FormatMessage32W(DWORD *args) {
+	DWORD	dwFlags		= args[0];
+	LPCVOID	lpSource	= (LPCVOID)args[1];
+	DWORD	dwMessageId	= args[2];
+	DWORD	dwLanguageId	= args[3];
+	LPWSTR	lpBuffer	= (LPWSTR)args[4];
+	DWORD	nSize		= args[5];
+	DWORD	*xargs;
+
+	/* convert possible varargs to an argument array look-a-like */
+
+	if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY) {
+		xargs=(DWORD*)args[6];
+	} else {
+		/* args[6] is a pointer to a pointer to the start of 
+		 * a list of arguments.
+		 */
+		if (args[6])
+			xargs=(DWORD*)(((DWORD*)args[6])[0]);
+		else
+			xargs=NULL;
+		dwFlags|=FORMAT_MESSAGE_ARGUMENT_ARRAY;
+	}
+	return FormatMessage32W(
+		dwFlags,
+		lpSource,
+		dwMessageId,
+		dwLanguageId,
+		lpBuffer,
+		nSize,
+		xargs
+	);
+}
diff --git a/misc/main.c b/misc/main.c
index 9d558f1..dfda8c5 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -602,7 +602,7 @@
 static void called_at_exit(void)
 {
     MAIN_RestoreSetup();
-    WSACleanup();
+    WINSOCK_Shutdown();
 }
 
 /***********************************************************************
@@ -879,8 +879,8 @@
 {
     int rc;
 
-    rc = SetEnvironment(lpName, lpValue, strlen(lpValue) + 1);
-    return (rc > 0) ? 1 : 0;
+    rc = SetEnvironment(lpName, lpValue, lpValue?(strlen(lpValue)+1):0);
+    return (rc>0)?TRUE:FALSE;
 }
 
 
@@ -889,15 +889,13 @@
  */
 BOOL32 SetEnvironmentVariable32W( LPCWSTR lpName, LPCWSTR lpValue )
 {
-    LPSTR lpAName, lpAValue;
-    BOOL ret;
+    LPSTR lpNameA = STRING32_DupUniToAnsi(lpName);
+    LPSTR lpValueA = lpValue?STRING32_DupUniToAnsi(lpValue):NULL;
+    BOOL32 ret = SetEnvironmentVariable32A(lpNameA,lpValueA);
 
-    lpAName = STRING32_DupUniToAnsi( lpName );
-    lpAValue = STRING32_DupUniToAnsi ( lpValue );
-    ret = SetEnvironment(lpAName, lpAValue, strlen(lpAValue) + 1);
-    free (lpAName);
-    free (lpAValue);
-    return (ret > 0) ? 1 : 0;    
+    free (lpNameA);
+    if (lpValue) free (lpValueA);
+    return ret;
 }
 
 
@@ -926,14 +924,29 @@
 }
 
 /***********************************************************************
- *      GetEnvironmentVariableA (KERNEL32.213)
+ *      GetEnvironmentVariable32A   (KERNEL32.213)
  */
-DWORD GetEnvironmentVariableA(LPSTR lpName, LPSTR lpValue, DWORD size)
+DWORD GetEnvironmentVariable32A( LPSTR lpName, LPSTR lpValue, DWORD size )
 {
     return GetEnvironment(lpName, lpValue, size);
 }
 
 /***********************************************************************
+ *      GetEnvironmentVariable32W   (KERNEL32.214)
+ */
+DWORD GetEnvironmentVariable32W( LPWSTR nameW, LPWSTR valW, DWORD size )
+{
+    LPSTR	name = nameW?STRING32_DupUniToAnsi(nameW):NULL;
+    LPSTR	val = valW?(LPSTR)xmalloc(size*2):NULL;
+    DWORD	res = GetEnvironment(name,val,size);
+
+    if (name) free(name);
+    if (val) lstrcpynAtoW(valW,val,size);
+    if (val) free(val);
+    return res;
+}
+
+/***********************************************************************
  *      GetEnvironmentStrings (KERNEL32.210)
  */
 LPVOID GetEnvironmentStrings(void)
@@ -1047,9 +1060,20 @@
 }
 
 /***********************************************************************
- *	SystemParametersInfo (USER.483)
+ *	SystemParametersInfo32A   (USER32.539)
  */
-BOOL SystemParametersInfo (UINT uAction, UINT uParam, LPVOID lpvParam, UINT fuWinIni)
+BOOL32 SystemParametersInfo32A( UINT32 uAction, UINT32 uParam,
+                                LPVOID lpvParam, UINT32 fuWinIni )
+{
+    return SystemParametersInfo16(uAction,uParam,lpvParam,fuWinIni);
+}
+
+
+/***********************************************************************
+ *	SystemParametersInfo16   (USER.483)
+ */
+BOOL16 SystemParametersInfo16( UINT16 uAction, UINT16 uParam,
+                               LPVOID lpvParam, UINT16 fuWinIni )
 {
 	int timeout, temp;
 	char buffer[256];
@@ -1160,7 +1184,7 @@
 			break;
 
 		case SPI_SETDESKPATTERN:
-			if ((INT) uParam == -1) {
+			if ((INT16)uParam == -1) {
 				GetProfileString32A("Desktop", "Pattern", 
 						"170 85 170 85 170 85 170 85", 
 						buffer, sizeof(buffer) );
@@ -1195,17 +1219,80 @@
 		case SPI_SETFASTTASKSWITCH:
 		case SPI_SETKEYBOARDDELAY:
 		case SPI_SETKEYBOARDSPEED:
-			fprintf(stderr, "SystemParametersInfo: option %d ignored.\n", uParam);
+			fprintf(stderr, "SystemParametersInfo: option %d ignored.\n", uAction);
 			break;
 
+                case SPI_GETWORKAREA:
+                    SetRect16( (RECT16 *)lpvParam, 0, 0,
+                               GetSystemMetrics( SM_CXSCREEN ),
+                               GetSystemMetrics( SM_CYSCREEN ) );
+                    break;
+
 		default:
-			fprintf(stderr, "SystemParametersInfo: unknown option %d.\n", uParam);
+			fprintf(stderr, "SystemParametersInfo: unknown option %d.\n", uAction);
 			break;
 	}
 	return 1;
 }
 
 /***********************************************************************
+ *	SystemParametersInfo32W   (USER32.540)
+ */
+BOOL32 SystemParametersInfo32W( UINT32 uAction, UINT32 uParam,
+                                LPVOID lpvParam, UINT32 fuWinIni )
+{
+    char buffer[256];
+
+    switch (uAction)
+    {
+    case SPI_SETDESKWALLPAPER:
+        if (lpvParam)
+        {
+            lstrcpynWtoA(buffer,(LPWSTR)lpvParam,sizeof(buffer));
+            return SetDeskWallPaper32(buffer);
+        }
+        return SetDeskWallPaper32(NULL);
+
+    case SPI_SETDESKPATTERN:
+        if ((INT) uParam == -1)
+        {
+            GetProfileString32A("Desktop", "Pattern", 
+                                "170 85 170 85 170 85 170 85", 
+                                buffer, sizeof(buffer) );
+            return (DESKTOP_SetPattern((LPSTR) buffer));
+        }
+        if (lpvParam)
+        {
+            lstrcpynWtoA(buffer,(LPWSTR)lpvParam,sizeof(buffer));
+            return DESKTOP_SetPattern(buffer);
+        }
+        return DESKTOP_SetPattern(NULL);
+
+    case SPI_GETICONTITLELOGFONT:
+        {
+            /* FIXME GetProfileString32A( "?", "?", "?" ) */
+            LPLOGFONT32W lpLogFont = (LPLOGFONT32W)lpvParam;
+            lpLogFont->lfHeight = 10;
+            lpLogFont->lfWidth = 0;
+            lpLogFont->lfEscapement = lpLogFont->lfOrientation = 0;
+            lpLogFont->lfWeight = FW_NORMAL;
+            lpLogFont->lfItalic = lpLogFont->lfStrikeOut = lpLogFont->lfUnderline = FALSE;
+            lpLogFont->lfCharSet = ANSI_CHARSET;
+            lpLogFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
+            lpLogFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
+            lpLogFont->lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;
+        }
+        break;
+
+    default:
+        return SystemParametersInfo32A(uAction,uParam,lpvParam,fuWinIni);
+	
+    }
+    return TRUE;
+}
+
+
+/***********************************************************************
 *	COPY (GDI.250)
 */
 void Copy(LPVOID lpSource, LPVOID lpDest, WORD nBytes)
diff --git a/misc/ntdll.c b/misc/ntdll.c
new file mode 100644
index 0000000..7f43d32
--- /dev/null
+++ b/misc/ntdll.c
@@ -0,0 +1,131 @@
+/*
+ * NT basis DLL
+ * 
+ * Copyright 1996 Marcus Meissner
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <ctype.h>
+#include <math.h>
+#include "win.h"
+#include "windows.h"
+#include "stddebug.h"
+#include "debug.h"
+#include "module.h"
+#include "xmalloc.h"
+#include "heap.h"
+
+/**************************************************************************
+ *                 RtlLengthRequiredSid			[NTDLL]
+ */
+DWORD
+RtlLengthRequiredSid(DWORD nrofsubauths) {
+	return sizeof(DWORD)*nrofsubauths+sizeof(SID);
+}
+
+/**************************************************************************
+ *                 RtlNormalizeProcessParams		[NTDLL]
+ */
+LPVOID
+RtlNormalizeProcessParams(LPVOID x)
+{
+    fprintf(stdnimp,"RtlNormalizeProcessParams(%p), stub.\n",x);
+    return x;
+}
+
+/**************************************************************************
+ *                 RtlInitializeSid			[NTDLL]
+ */
+DWORD
+RtlInitializeSid(LPSID lpsid,LPSID_IDENTIFIER_AUTHORITY lpsidauth,DWORD c) {
+	BYTE	a = c&0xff;
+
+	if (a>=SID_MAX_SUB_AUTHORITIES)
+		return a;
+	lpsid->SubAuthorityCount = a;
+	lpsid->Revision		 = SID_REVISION;
+	memcpy(&(lpsid->IdentifierAuthority),lpsidauth,sizeof(SID_IDENTIFIER_AUTHORITY));
+	return 0;
+}
+
+/**************************************************************************
+ *                 RtlSubAuthoritySid			[NTDLL]
+ */
+LPDWORD
+RtlSubAuthoritySid(LPSID lpsid,DWORD nr) {
+	return &(lpsid->SubAuthority[nr]);
+}
+
+/**************************************************************************
+ *                 RtlSubAuthorityCountSid		[NTDLL]
+ */
+LPBYTE
+RtlSubAuthorityCountSid(LPSID lpsid) {
+	return ((LPBYTE)lpsid)+1;
+}
+
+/**************************************************************************
+ *                 RtlCopySid				[NTDLL]
+ */
+DWORD
+RtlCopySid(DWORD len,LPSID to,LPSID from) {
+	if (len<(from->SubAuthorityCount*4+8))
+		return 0xC0000023;
+	memmove(to,from,from->SubAuthorityCount*4+8);
+	return 0;
+}
+
+/**************************************************************************
+ *                 RtlOemToUnicodeN			[NTDLL]
+ */
+DWORD /* NTSTATUS */
+RtlOemToUnicodeN(LPWSTR unistr,DWORD unilen,LPDWORD reslen,LPSTR oemstr,DWORD oemlen) {
+	DWORD	len;
+	LPWSTR	x;
+
+	len = oemlen;
+	if (unilen/2 < len)
+		len = unilen/2;
+	x=(LPWSTR)xmalloc((len+1)*sizeof(WCHAR));
+	lstrcpynAtoW(x,oemstr,len+1);
+	memcpy(unistr,x,len*2);
+	if (reslen) *reslen = len*2;
+	return 0;
+}
+
+/**************************************************************************
+ *                 RtlUnicodeToOemN			[NTDLL]
+ */
+DWORD /* NTSTATUS */
+RtlUnicodeToOemN(LPSTR oemstr,DWORD oemlen,LPDWORD reslen,LPWSTR unistr,DWORD unilen) {
+	DWORD	len;
+	LPSTR	x;
+
+	len = oemlen;
+	if (unilen/2 < len)
+		len = unilen/2;
+	x=(LPSTR)xmalloc(len+1);
+	lstrcpynWtoA(x,unistr,len+1);
+	memcpy(oemstr,x,len);
+	if (reslen) *reslen = len;
+	return 0;
+}
+
+/**************************************************************************
+ *                 RtlUnicodeStringToOemString		[NTDLL]
+ */
+DWORD /* NTSTATUS */
+RtlUnicodeStringToOemString(LPUNICODE_STRING uni,LPANSI_STRING oem,BOOL32 alloc)
+{
+	if (alloc) {
+		oem->Buffer = (LPSTR)xmalloc(uni->Length/2)+1;
+		oem->MaximumLength = uni->Length/2+1;
+	}
+	oem->Length = uni->Length/2;
+	lstrcpynWtoA(oem->Buffer,uni->Buffer,uni->Length/2+1);
+	return 0;
+}
diff --git a/misc/registry.c b/misc/registry.c
index 90c001a..e208349 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -503,7 +503,8 @@
 	pwd=getpwuid(getuid());
 	if (pwd!=NULL && pwd->pw_dir!=NULL)
         {
-                char *tmp = tmpnam(NULL);
+                char *tmp;
+
 		fn=(char*)xmalloc( strlen(pwd->pw_dir) + strlen(WINE_PREFIX) +
                                    strlen(SAVE_CURRENT_USER) + 2 );
 		strcpy(fn,pwd->pw_dir);
@@ -511,12 +512,28 @@
 		/* create the directory. don't care about errorcodes. */
 		mkdir(fn,0755); /* drwxr-xr-x */
 		strcat(fn,"/"SAVE_CURRENT_USER);
-		if (_savereg(key_current_user,tmp,all)) rename(tmp,fn);
+		tmp = (char*)xmalloc(strlen(fn)+strlen(".tmp")+1);
+		strcpy(tmp,fn);strcat(tmp,".tmp");
+		if (_savereg(key_current_user,tmp,all)) {
+			if (-1==rename(tmp,fn)) {
+				perror("rename tmp registry");
+				unlink(tmp);
+			}
+		}
+		free(tmp);
 		free(fn);
 		fn=(char*)xmalloc(strlen(pwd->pw_dir)+strlen(WINE_PREFIX)+strlen(SAVE_LOCAL_MACHINE)+2);
 		strcpy(fn,pwd->pw_dir);
 		strcat(fn,WINE_PREFIX"/"SAVE_LOCAL_MACHINE);
-		if (_savereg(key_local_machine,tmp,all)) rename(tmp,fn);
+		tmp = (char*)xmalloc(strlen(fn)+strlen(".tmp")+1);
+		strcpy(tmp,fn);strcat(tmp,".tmp");
+		if (_savereg(key_local_machine,tmp,all)) {
+			if (-1==rename(tmp,fn)) {
+				perror("rename tmp registry");
+				unlink(tmp);
+			}
+		}
+		free(tmp);
 		free(fn);
 	} else
 		fprintf(stderr,"SHELL_SaveRegistry:failed to get homedirectory of UID %d.\n",getuid());
@@ -1639,7 +1656,7 @@
 	i 	= 0;
 	while ((i<wpc) && (wps[i][0]=='\0')) i++;
 	lpxkey	= lpNextKey;
-	while (i<wpc) {
+	while (wps[i]) {
 		lpxkey=lpNextKey->nextsub;
 		while (lpxkey) {
 			if (!lstrcmp32W(wps[i],lpxkey->keyname))
diff --git a/misc/shell.c b/misc/shell.c
index 2f9cc8b..263b9d8 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -407,6 +407,33 @@
 }
 
 /*************************************************************************
+ *				ShellAbout32W		[SHELL32.83]
+ */
+INT32 ShellAbout32W(HWND32 hWnd, LPCWSTR szApp, LPCWSTR szOtherStuff, HICON16 hIcon)
+{
+    HGLOBAL16 handle;
+    BOOL bRet;
+
+    if (szApp) lstrcpynWtoA(AppName, szApp, sizeof(AppName));
+    else *AppName = 0;
+    AppName[sizeof(AppName)-1]=0;
+
+    if (szOtherStuff) lstrcpynWtoA(AppMisc, szOtherStuff, sizeof(AppMisc));
+    else *AppMisc = 0;
+    AppMisc[sizeof(AppMisc)-1]=0;
+
+    if (!hIcon) hIcon = LoadIcon16(0,MAKEINTRESOURCE(OIC_WINEICON));
+    handle = SYSRES_LoadResource( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX );
+    if (!handle) return FALSE;
+    bRet = DialogBoxIndirectParam16( WIN_GetWindowInstance( hWnd ),
+                                     handle, hWnd,
+                                     (DLGPROC16)MODULE_GetWndProcEntry16("AboutDlgProc"), 
+                                     (LPARAM)hIcon );
+    SYSRES_FreeResource( handle );
+    return bRet;
+}
+
+/*************************************************************************
  *				SHELL_GetResourceTable
  *
  * FIXME: Implement GetPEResourceTable in w32sys.c and call it here.
@@ -691,7 +718,7 @@
 	else
 	  *lpiIcon = 6;   /* generic icon - found nothing */
 
-        GetModuleFileName(hInst, lpIconPath, 0x80);
+        GetModuleFileName16(hInst, lpIconPath, 0x80);
 	hIcon = LoadIcon16( hInst, MAKEINTRESOURCE(*lpiIcon));
       }
 
@@ -837,3 +864,50 @@
 	);
 	return TRUE;
 }
+
+/*************************************************************************
+ *				CommandLineToArgvW	[SHELL32.2]
+ */
+LPWSTR*
+CommandLineToArgvW(LPWSTR cmdline,LPDWORD numargs) {
+	LPWSTR	*argv,s,t;
+	int	i;
+
+	cmdline = (LPWSTR)STRING32_strdupW(cmdline); /* to get writeable copy */
+	s=cmdline;i=0;
+	while (*s) {
+		/* space */
+		if (*s==0x0020) {
+			i++;
+			s++;
+			while (*s && *s==0x0020)
+				s++;
+			continue;
+		}
+		s++;
+	}
+	argv=(LPWSTR*)xmalloc(sizeof(LPWSTR)*(i+1));
+	s=t=cmdline;
+	i=0;
+	while (*s) {
+		if (*s==0x0020) {
+			*s=0;
+			argv[i++]=(LPWSTR)STRING32_strdupW(t);
+			*s=0x0020;
+			while (*s && *s==0x0020)
+				s++;
+			if (*s)
+				t=s+1;
+			else
+				t=s;
+			continue;
+		}
+		s++;
+	}
+	if (*t)
+		argv[i++]=(LPWSTR)STRING32_strdupW(t);
+	free(cmdline);
+	argv[i]=NULL;
+	*numargs=i;
+	return argv;
+}
diff --git a/misc/ver.c b/misc/ver.c
index c53ba85..3ee1fcd 100644
--- a/misc/ver.c
+++ b/misc/ver.c
@@ -674,8 +674,8 @@
 	dprintf_ver(stddeb,"VerQueryValue16(%p,%s,%p,%d)\n",
 		block,subblock,buffer,*buflen
 	);
-	s=(char*)xmalloc(strlen("VS_VERSION_INFO")+strlen(subblock)+1);
-	strcpy(s,"VS_VERSION_INFO");strcat(s,subblock);
+	s=(char*)xmalloc(strlen("VS_VERSION_INFO\\")+strlen(subblock)+1);
+	strcpy(s,"VS_VERSION_INFO\\");strcat(s,subblock);
 	b=_find_data(block,s);
 	if (b==NULL) {
 		*buflen=0;
@@ -701,8 +701,8 @@
 	dprintf_ver(stddeb,"VerQueryValue32A(%p,%s,%p,%d)\n",
 		block,subblock,buffer,*buflen
 	);
-	s=(char*)xmalloc(strlen("VS_VERSION_INFO")+strlen(subblock)+1);
-	strcpy(s,"VS_VERSION_INFO");strcat(s,subblock);
+	s=(char*)xmalloc(strlen("VS_VERSION_INFO\\")+strlen(subblock)+1);
+	strcpy(s,"VS_VERSION_INFO\\");strcat(s,subblock);
 	b=_find_data(block,s);
 	if (b==NULL) {
 		*buflen=0;
@@ -730,8 +730,8 @@
 	char		*s,*sb;
 
 	sb=strdupW2A(subblock);
-	s=(char*)xmalloc(strlen("VS_VERSION_INFO")+strlen(sb)+1);
-	strcpy(s,"VS_VERSION_INFO");strcat(s,sb);
+	s=(char*)xmalloc(strlen("VS_VERSION_INFO\\")+strlen(sb)+1);
+	strcpy(s,"VS_VERSION_INFO\\");strcat(s,sb);
 	b=_find_data(block,s);
 	if (b==NULL) {
 		*buflen=0;
diff --git a/misc/winsock.c b/misc/winsock.c
index 1ec7004..e26e84f 100644
--- a/misc/winsock.c
+++ b/misc/winsock.c
@@ -88,7 +88,7 @@
 static void fixup_wspe(struct ws_protoent* p_wspe, SEGPTR base);
 static void fixup_wsse(struct ws_servent* p_wsse, SEGPTR base);
 
-static int delete_async_op(ws_socket*);
+static int cancel_async_select(ws_socket*);
 
 static void convert_sockopt(INT16 *level, INT16 *optname)
 {
@@ -203,8 +203,8 @@
 	    ws_socket *pws = (ws_socket*)WS_HANDLE2PTR(ws->fd_array[i]);
 	    int fd = pws->fd;
 
-	    if( _check_ws(pwsi, pws) && FD_ISSET(fd, fds) ) 
-	    { 
+	    if( _check_ws(pwsi, pws) && FD_ISSET(fd, fds) )
+	    {
 		/* if error, move to errorfds */
 		if (errorfds && (FD_ISSET(fd, errorfds) || sock_error_p(fd)))
 		    FD_SET(fd, errorfds);
@@ -230,8 +230,8 @@
 	    ws_socket *pws = (ws_socket *)WS_HANDLE2PTR(ws->fd_array[i]);
 
 	    if (_check_ws(pwsi, pws) && (FD_ISSET(pws->fd, fds)
-					 || FD_ISSET(pws->fd, errorfds)))
-	      ws->fd_array[j++] = ws->fd_array[i];
+                                         || FD_ISSET(pws->fd, errorfds)))
+	    ws->fd_array[j++] = ws->fd_array[i];
 	}
 	ws->fd_count = j;
     }
@@ -298,6 +298,14 @@
   return(0);
 }
 
+void WINSOCK_Shutdown()
+{
+  if( async_qid != -1 )
+    if( msgctl(async_qid, IPC_RMID, NULL) == -1 )
+          fprintf(stderr,"failed to delete WS message queue.\n");
+    else async_qid = -1;
+}
+
 INT16 WSACleanup(void)
 {
   LPWSINFO      pwsi = wsi_find(GetCurrentTask());
@@ -316,11 +324,7 @@
       SIGNAL_MaskAsyncEvents( FALSE );
 
       wsi_unlink(pwsi);
-      if( _wsi_list == NULL && async_qid != -1 )
-        if( msgctl(async_qid, IPC_RMID, NULL) == -1 )
-        { 
-          fprintf(stderr,"failed to delete WS message queue.\n");
-        } else async_qid = -1;
+      if( _wsi_list == NULL ) WINSOCK_Shutdown();
 
       if( pwsi->flags & WSI_BLOCKINGCALL )
 	  dprintf_winsock(stddeb,"\tinside blocking call!\n");
@@ -330,13 +334,14 @@
       for(i = 0, j = 0, n = 0; i < WS_MAX_SOCKETS_PER_THREAD; i++)
 	if( pwsi->sock[i].fd != -1 )
 	{ 
-	  n += delete_async_op(&pwsi->sock[i]);
+	  n += cancel_async_select(&pwsi->sock[i]);
           close(pwsi->sock[i].fd); j++; 
         }
       if( j ) 
 	  dprintf_winsock(stddeb,"\tclosed %i sockets, killed %i async selects!\n", j, n);
 
       if( pwsi->buffer ) SEGPTR_FREE(pwsi->buffer);
+      if( pwsi->dbuffer ) SEGPTR_FREE(pwsi->dbuffer);
       WS_FREE(pwsi);
       return 0;
   }
@@ -468,12 +473,12 @@
   { 
     int		fd = pws->fd;
 
-    delete_async_op(pws);
-    pws->p_aop = NULL; pws->fd = -1;
+    cancel_async_select(pws);
+    pws->fd = -1;
     pws->flags = (unsigned)pwsi->last_free;
     pwsi->last_free = pws - &pwsi->sock[0];
-    if (close(fd) < 0) pwsi->errno = (errno == EBADF) ? WSAENOTSOCK : wsaErrno();
-    else return 0;
+    if (close(fd) == 0) return 0;
+    pwsi->errno = (errno == EBADF) ? WSAENOTSOCK : wsaErrno();
   }
   return SOCKET_ERROR;
 }
@@ -579,18 +584,28 @@
 
 SEGPTR WINSOCK_inet_ntoa(struct in_addr in)
 {
+  /* use "buffer for dummies" here because some applications have 
+   * propensity to decode addresses in ws_hostent structure without 
+   * saving them first...
+   */
+
   LPWSINFO      pwsi = wsi_find(GetCurrentTask());
-  char*		s = inet_ntoa(in);
 
   if( pwsi )
   {
-    if( s == NULL ) { pwsi->errno = wsaErrno(); return NULL; }
-    if( _check_buffer( pwsi, 32 ) )
-    { 
-      strncpy(pwsi->buffer, s, 32 );
-      return SEGPTR_GET(pwsi->buffer); 
+    char*	s = inet_ntoa(in);
+    if( s ) 
+    {
+	if( pwsi->dbuffer == NULL )
+	    if((pwsi->dbuffer = (char*) SEGPTR_ALLOC(32)) == NULL )
+	    {
+		pwsi->errno = WSAENOBUFS;
+		return (SEGPTR)NULL;
+	    }
+	strncpy(pwsi->dbuffer, s, 32 );
+	return SEGPTR_GET(pwsi->dbuffer); 
     }
-    pwsi->errno = WSAENOBUFS;
+    pwsi->errno = wsaErrno();
   }
   return (SEGPTR)NULL;
 }
@@ -683,7 +698,8 @@
   if( _check_ws(pwsi, pws) )
   {
     int length, fromlen32 = *fromlen16;
-    if ((length = recvfrom(pws->fd, buf, len, flags, from, &fromlen32)) >= 0) 
+
+    if ((length = recvfrom(pws->fd, buf, len, flags, from, &fromlen32)) >= 0 );
     {   
       *fromlen16 = fromlen32; 
        notify_client(pws, WS_FD_READ);
@@ -719,7 +735,7 @@
 	  {
 	    fd_set_update(pwsi, &readfds, ws_readfds, &errorfds);
 	    fd_set_update(pwsi, &writefds, ws_writefds, &errorfds);
- 	    fd_set_update_except(pwsi, &exceptfds, ws_exceptfds, &errorfds);
+	    fd_set_update_except(pwsi, &exceptfds, ws_exceptfds, &errorfds);
 	  }
 	  return highfd; 
      }
@@ -807,8 +823,8 @@
 			   (unsigned)pwsi, s, how );
   if( _check_ws(pwsi, pws) )
   {
-    pws->flags  = WS_FD_INACTIVE;
-    delete_async_op(pws);
+    pws->flags |= WS_FD_INACTIVE;
+    cancel_async_select(pws);
 
     if (shutdown(pws->fd, how) == 0) return 0;
     pwsi->errno = wsaErrno();
@@ -862,14 +878,13 @@
     {
         ws_socket*      pnew = wsi_alloc_socket(pwsi, sock);
 
-/*	printf("created %04x (%i)\n", sock, (UINT16)WS_PTR2HANDLE(pnew));
- */
+	dprintf_winsock(stddeb,"\tcreated %04x (handle %i)\n", sock, (UINT16)WS_PTR2HANDLE(pnew));
+
         if( pnew ) return (SOCKET16)WS_PTR2HANDLE(pnew);
-        else
 	{
-	    close(sock);
-	    pwsi->errno = WSAENOBUFS;
-	    return INVALID_SOCKET;
+          close(sock);
+          pwsi->errno = WSAENOBUFS;
+          return INVALID_SOCKET;
 	}
     }
 
@@ -1044,7 +1059,7 @@
 
   read(p_aop->fd[0], &lLength, sizeof(unsigned));
   if( LOWORD(lLength) )
-    if( LOWORD(lLength) <= p_aop->buflen )
+    if( (int)LOWORD(lLength) <= p_aop->buflen )
     {
       char* buffer = (char*)PTR_SEG_TO_LIN(p_aop->buffer_base);
       read(p_aop->fd[0], buffer, LOWORD(lLength));
@@ -1089,7 +1104,7 @@
 
       if( pipe(async_ctl.ws_aop->fd) == 0 )
       {
-	async_ctl.ws_aop->init = (char*)init;
+	async_ctl.init = (char*)init;
 	async_ctl.lLength = len;
 	async_ctl.lEvent = type;
 
@@ -1130,6 +1145,7 @@
 		     case WSMSG_ASYNC_SERVBYNAME:
 			WS_do_async_getserv(pwsi,flag);
 		   }
+		   _exit(0); /* skip atexit()'ed cleanup */
                  }
       }
       WS_FREE(async_ctl.ws_aop);
@@ -1241,7 +1257,7 @@
     if( WINSOCK_check_async_op(p_aop) )
     {
   	kill(p_aop->pid, SIGKILL); 
-	waitpid(p_aop->pid, NULL, 0);
+	waitpid(p_aop->pid, NULL, 0); /* just in case */
 	close(p_aop->fd[0]);
 	WINSOCK_unlink_async_op(p_aop);
 	WS_FREE(p_aop);
@@ -1253,14 +1269,15 @@
 
 /* ----- asynchronous select() */
 
-int delete_async_op(ws_socket* pws)
+int cancel_async_select(ws_socket* pws)
 {
   if( pws->p_aop )
   {
     kill(pws->p_aop->pid, SIGKILL);
     waitpid(pws->p_aop->pid, NULL, 0);
-    WS_FREE(pws->p_aop); return 1;
-    pws->flags &= WS_FD_INTERNAL;
+    WS_FREE(pws->p_aop); 
+    pws->p_aop = NULL;
+    return 1;
   }
   return 0;
 }
@@ -1312,7 +1329,7 @@
 	else
 	{
 	    perror("AsyncSelect(parent)"); 
-	    delete_async_op(pws);
+	    cancel_async_select(pws);
 	    pws->flags &= WS_FD_INTERNAL;
 	    return 0;
 	}
@@ -1327,11 +1344,9 @@
 {
     ws_async_op*        p_aop;
 
-    if( delete_async_op(pws) )  /* delete old async handler if any */
-    {
-      pws->p_aop = NULL;
+    if( cancel_async_select(pws) )  /* delete old async handler if any */
       pws->flags &= WS_FD_INTERNAL;
-    }
+
     if( lEvent == 0 ) return 0;
 
     /* setup async handler - some data may be redundant */
@@ -1529,6 +1544,7 @@
        p_to->h_name = (SEGPTR)(p_base + (p_name - pwsi->buffer));
        p_to->h_aliases = (SEGPTR)(p_base + (p_aliases - pwsi->buffer));
        p_to->h_addr_list = (SEGPTR)(p_base + (p_addr - pwsi->buffer));
+
        return (size + sizeof(struct ws_hostent) - sizeof(struct hostent)); }
    }
    return size;
diff --git a/misc/winsock_async.c b/misc/winsock_async.c
index 6596b5f..c97588b 100644
--- a/misc/winsock_async.c
+++ b/misc/winsock_async.c
@@ -21,7 +21,7 @@
 
 #define __WS_ASYNC_DEBUG	0
 
-static int		_async_io_max_fd = 0;
+static int		__async_io_max_fd = 0;
 static fd_set		__async_io_fdset;
 static ws_async_op*	__async_op_list = NULL;
 
@@ -80,8 +80,8 @@
   __async_op_list = p_aop;
 
   FD_SET(p_aop->fd[0], &__async_io_fdset);
-  if( p_aop->fd[0] > _async_io_max_fd ) 
-		     _async_io_max_fd = p_aop->fd[0];
+  if( p_aop->fd[0] > __async_io_max_fd ) 
+		     __async_io_max_fd = p_aop->fd[0];
 }
 
 void WINSOCK_unlink_async_op(ws_async_op* p_aop)
@@ -91,8 +91,8 @@
   { p_aop->prev->next = p_aop->next;
     if( p_aop->next ) p_aop->next->prev = p_aop->prev; }
   FD_CLR(p_aop->fd[0], &__async_io_fdset); 
-  if( p_aop->fd[0] == _async_io_max_fd )
-		      _async_io_max_fd--;
+  if( p_aop->fd[0] == __async_io_max_fd )
+		      __async_io_max_fd--;
 }
 
 /* ----------------------------------- SIGIO handler -
@@ -112,7 +112,7 @@
  check_set = __async_io_fdset;
  bzero(&timeout,sizeof(timeout));
 
- while( select(_async_io_max_fd + 1,
+ while( select(__async_io_max_fd + 1,
               &check_set, NULL, NULL, &timeout) > 0)
  {
    for( p_aop = __async_op_list;
@@ -123,7 +123,7 @@
 	      if( p_aop->pid ) 
 	      { 
 		kill(p_aop->pid, SIGKILL);
-		waitpid(p_aop->pid, NULL, 0);  
+		waitpid(p_aop->pid, NULL, WNOHANG);
 	      }
 	      WINSOCK_unlink_async_op( p_aop );
 	  }
@@ -188,7 +188,9 @@
                                MTYPE_CLIENT_SIZE, 0) == -1 )
      {
        if( errno == EINTR ) continue;
+#ifdef EIDRM
        else if( errno == EIDRM ) _exit(0);
+#endif
        else 
        { 
 	 perror("AsyncSelect(child)"); 
@@ -240,8 +242,9 @@
 void WINSOCK_do_async_select()
 {
   sigset_t    sig_block;
-  int	      bytes;
+  int	      sock_type, bytes;
 
+  getsockopt(async_ctl.ws_sock->fd, SOL_SOCKET, SO_TYPE, &sock_type, &bytes);
   setup_sig_sets(&sig_block);
   setup_fd_sets();
 
@@ -249,6 +252,8 @@
   {
     int		val;
 
+    if( sock_type != SOCK_STREAM )
+        async_ctl.lEvent &= ~(WS_FD_ACCEPT | WS_FD_CONNECT);
     sigprocmask( SIG_UNBLOCK, &sig_block, NULL); 
 
 #if __WS_ASYNC_DEBUG
@@ -337,12 +342,21 @@
 	  if( async_ctl.lEvent & (WS_FD_READ | WS_FD_CLOSE) )
 	    if( FD_ISSET(async_ctl.ws_sock->fd, &fd_read) )
 	    {
-	      if( ioctl( async_ctl.ws_sock->fd, FIONREAD, (char*)&bytes) != -1 )
+	      int 	ok = 0;
+
+	      if( sock_type == SOCK_RAW ) ok = 1;
+	      else if( ioctl( async_ctl.ws_sock->fd, FIONREAD, (char*)&bytes) == -1 )
 	      {
-	        if( bytes )	/* got data */
-	        {
+		  async_ctl.ip.lParam = WSAMAKESELECTREPLY( WS_FD_READ, wsaErrno() );
+		  FD_CLR( async_ctl.ws_sock->fd, &fd_read );
+		  bytes = 0;
+	      }
+
+	      if( bytes || ok )	/* got data */
+	      {
 #if __WS_ASYNC_DEBUG
-		  printf("\t%i bytes pending\n", bytes );
+		  if( ok ) printf("\traw/datagram read pending\n");
+		  else printf("\t%i bytes pending\n", bytes );
 #endif
 		  if( async_ctl.lEvent & WS_FD_READ )
 		  {
@@ -358,9 +372,9 @@
 			  sigprocmask( SIG_BLOCK, &sig_block, NULL);
 		       }
 		       else continue;
-	        }
-	        else		/* 0 bytes to read */
-	        {
+	      }
+	      else		/* 0 bytes to read */
+	      {
 		  val = read( async_ctl.ws_sock->fd, (char*)&bytes, 4);
 	          if( errno == EWOULDBLOCK || errno == EINTR ) 
 		  { 
@@ -379,9 +393,7 @@
 		  }
 		  async_ctl.lEvent &= ~(WS_FD_CLOSE | WS_FD_READ); /* one-shot */
 		  FD_ZERO(&fd_read); FD_ZERO(&fd_write); 
-	        }
 	      }
-	      else async_ctl.ip.lParam = WSAMAKESELECTREPLY( WS_FD_READ, wsaErrno() );
 
 	      notify_parent( WSMSG_ASYNC_SELECT );
 	  }
@@ -430,8 +442,8 @@
 
   close(async_ctl.ws_aop->fd[0]);
   p_he = (flag & WSMSG_ASYNC_HOSTBYNAME)
-	 ? gethostbyname(async_ctl.ws_aop->init)
-	 : gethostbyaddr(async_ctl.ws_aop->init,
+	 ? gethostbyname(async_ctl.init)
+	 : gethostbyaddr(async_ctl.init,
 		 	 async_ctl.lLength, async_ctl.lEvent);
   if( p_he ) size = WS_dup_he(pwsi, p_he, WS_DUP_SEGPTR | WS_DUP_OFFSET );
   if( size )
@@ -441,7 +453,6 @@
      notify_parent( flag );
   }
   else _async_fail();
-  _exit(0);
 }
 
 void WS_do_async_getproto(LPWSINFO pwsi, unsigned flag )
@@ -451,7 +462,7 @@
 
   close(async_ctl.ws_aop->fd[0]);
   p_pe = (flag & WSMSG_ASYNC_PROTOBYNAME)
-	 ? getprotobyname(async_ctl.ws_aop->init)
+	 ? getprotobyname(async_ctl.init)
 	 : getprotobynumber(async_ctl.lEvent);
   if( p_pe ) size = WS_dup_pe(pwsi, p_pe, WS_DUP_SEGPTR | WS_DUP_OFFSET );
   if( size )
@@ -461,7 +472,6 @@
      notify_parent( flag );
   } 
   else _async_fail();
-  _exit(0);
 }
 
 void WS_do_async_getserv(LPWSINFO pwsi, unsigned flag )
@@ -471,8 +481,8 @@
 
   close(async_ctl.ws_aop->fd[0]);
   p_se = (flag & WSMSG_ASYNC_SERVBYNAME)
-	 ? getservbyname(async_ctl.ws_aop->init, async_ctl.buffer)
-	 : getservbyport(async_ctl.lEvent, async_ctl.ws_aop->init);
+	 ? getservbyname(async_ctl.init, async_ctl.buffer)
+	 : getservbyport(async_ctl.lEvent, async_ctl.init);
   if( p_se ) size = WS_dup_se(pwsi, p_se, WS_DUP_SEGPTR | WS_DUP_OFFSET );
   if( size )
   {
@@ -481,6 +491,5 @@
      notify_parent( flag );
   }
   else _async_fail();
-  _exit(0);
 }
 
diff --git a/miscemu/dpmi.c b/miscemu/dpmi.c
index 77a3285..1f8daa4 100644
--- a/miscemu/dpmi.c
+++ b/miscemu/dpmi.c
@@ -14,6 +14,7 @@
 #include "miscemu.h"
 #include "drive.h"
 #include "msdos.h"
+#include "toolhelp.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -366,11 +367,18 @@
         break;
 
     case 0x0500:  /* Get free memory information */
-        ptr = (BYTE *)PTR_SEG_OFF_TO_LIN( ES_reg(context), DI_reg(context) );
-        *(DWORD *)ptr = 0x00ff0000; /* Largest block available */
-        memset( ptr + 4, 0xff, 0x2c );  /* No other information supported */
-        break;
+        {
+            MEMMANINFO mmi;
 
+            mmi.dwSize = sizeof(mmi);
+            MemManInfo(&mmi);
+            ptr = (BYTE *)PTR_SEG_OFF_TO_LIN(ES_reg(context),DI_reg(context));
+            /* the layout is just the same as MEMMANINFO, but without
+             * the dwSize entry.
+             */
+            memcpy(ptr,((char*)&mmi)+4,sizeof(mmi)-4);
+            break;
+        }
     case 0x0501:  /* Allocate memory block */
         if (!(ptr = (BYTE *)HeapAlloc( SystemHeap, 0,MAKELONG( CX_reg(context),
                                                            BX_reg(context) ))))
diff --git a/multimedia/audio.c b/multimedia/audio.c
index f92a6b7..b71b1d2 100644
--- a/multimedia/audio.c
+++ b/multimedia/audio.c
@@ -1603,7 +1603,7 @@
 		case DRV_QUERYCONFIGURE:
 			return 1;
 		case DRV_CONFIGURE:
-			MessageBox((HWND)NULL, "Sample MultiMedia Linux Driver !", 
+			MessageBox16((HWND)NULL, "Sample MultiMedia Linux Driver !", 
 								"MMLinux Driver", MB_OK);
 			return 1;
 		case DRV_INSTALL:
diff --git a/multimedia/mcianim.c b/multimedia/mcianim.c
index 3620d74..ef0262d 100644
--- a/multimedia/mcianim.c
+++ b/multimedia/mcianim.c
@@ -631,7 +631,7 @@
 		case DRV_QUERYCONFIGURE:
 			return 1;
 		case DRV_CONFIGURE:
-			MessageBox((HWND)NULL, "Sample MultiMedia Linux Driver !", 
+			MessageBox16((HWND)NULL, "Sample MultiMedia Linux Driver !", 
 								"MMLinux Driver", MB_OK);
 			return 1;
 		case DRV_INSTALL:
diff --git a/multimedia/mcicda.c b/multimedia/mcicda.c
index 7562e5e..bbc0ce3 100644
--- a/multimedia/mcicda.c
+++ b/multimedia/mcicda.c
@@ -1047,7 +1047,7 @@
 		case DRV_QUERYCONFIGURE:
 			return 1;
 		case DRV_CONFIGURE:
-			MessageBox((HWND)NULL, "Sample MultiMedia Linux Driver !", 
+			MessageBox16((HWND)NULL, "Sample MultiMedia Linux Driver !", 
 								"MMLinux Driver", MB_OK);
 			return 1;
 		case DRV_INSTALL:
diff --git a/multimedia/midi.c b/multimedia/midi.c
index b86c933..df4065f 100644
--- a/multimedia/midi.c
+++ b/multimedia/midi.c
@@ -1289,8 +1289,8 @@
 		case DRV_QUERYCONFIGURE:
 			return 1;
 		case DRV_CONFIGURE:
-			MessageBox(0, "Sample Midi Linux Driver !", 
-								"MMLinux Driver", MB_OK);
+			MessageBox16(0, "Sample Midi Linux Driver !", 
+                                     "MMLinux Driver", MB_OK);
 			return 1;
 		case DRV_INSTALL:
 			return DRVCNF_RESTART;
diff --git a/objects/bitmap.c b/objects/bitmap.c
index 8d3d57c..0c535f5 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -17,6 +17,12 @@
 #include "stddebug.h"
 #include "debug.h"
 
+#ifdef PRELIMINARY_WING16_SUPPORT
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif
+
   /* GCs used for B&W and color bitmap operations */
 GC BITMAP_monoGC = 0, BITMAP_colorGC = 0;
 
@@ -378,9 +384,27 @@
 /***********************************************************************
  *           BITMAP_DeleteObject
  */
-BOOL32 BITMAP_DeleteObject( HBITMAP16 hbitmap, BITMAPOBJ * bitmap )
+BOOL32 BITMAP_DeleteObject( HBITMAP16 hbitmap, BITMAPOBJ * bmp )
 {
-    XFreePixmap( display, bitmap->pixmap );
+#ifdef PRELIMINARY_WING16_SUPPORT
+    if( bmp->bitmap.bmBits )
+ 	XShmDetach( display, (XShmSegmentInfo*)bmp->bitmap.bmBits );
+#endif
+
+    XFreePixmap( display, bmp->pixmap );
+#ifdef PRELIMINARY_WING16_SUPPORT
+    if( bmp->bitmap.bmBits )
+    {
+    __ShmBitmapCtl* p = (__ShmBitmapCtl*)bmp->bitmap.bmBits;
+      WORD          sel = HIWORD(p->bits);
+      unsigned long l, limit = GetSelectorLimit(sel);
+
+      for( l = 0; l < limit; l += 0x10000, sel += __AHINCR )
+	   FreeSelector(sel);
+      shmctl(p->si.shmid, IPC_RMID, NULL); 
+      shmdt(p->si.shmaddr);  /* already marked for destruction */
+    }
+#endif
     return GDI_FreeObject( hbitmap );
 }
 
diff --git a/objects/dc.c b/objects/dc.c
index 70c0355..0d05d11 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -15,6 +15,7 @@
 #include "debug.h"
 #include "font.h"
 #include "xmalloc.h"
+#include "string32.h"
 
 extern void CLIPPING_UpdateGCRegion( DC * dc );     /* objects/clipping.c */
 
@@ -512,9 +513,10 @@
 
 
 /***********************************************************************
- *           CreateDC    (GDI.53)
+ *           CreateDC16    (GDI.53)
  */
-HDC16 CreateDC( LPCSTR driver, LPCSTR device, LPCSTR output, const DEVMODE* initData )
+HDC16 CreateDC16( LPCSTR driver, LPCSTR device, LPCSTR output,
+                  const DEVMODE16 *initData )
 {
     DC * dc;
     const DC_FUNCTIONS *funcs;
@@ -540,12 +542,42 @@
 
 
 /***********************************************************************
+ *           CreateDC32A    (GDI32.)
+ */
+HDC32 CreateDC32A( LPCSTR driver, LPCSTR device, LPCSTR output,
+                   const DEVMODE32A *initData )
+{
+    return CreateDC16( driver, device, output, (const DEVMODE16 *)initData );
+}
+
+
+/***********************************************************************
+ *           CreateDC32W    (GDI32.)
+ */
+HDC32 CreateDC32W( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
+                   const DEVMODE32W *initData )
+{ 
+    LPSTR driverA = driver?STRING32_DupUniToAnsi(driver):NULL;
+    LPSTR deviceA = device?STRING32_DupUniToAnsi(device):NULL;
+    LPSTR outputA = output?STRING32_DupUniToAnsi(output):NULL;
+    HDC32 res;
+
+    res = CreateDC16( driverA, deviceA, outputA, (const DEVMODE16 *)initData );
+    if (driverA) free(driverA);
+    if (deviceA) free(deviceA);
+    if (outputA) free(outputA);
+    return res;
+}
+
+
+/***********************************************************************
  *           CreateIC    (GDI.153)
  */
-HDC16 CreateIC( LPCSTR driver, LPCSTR device, LPCSTR output, const DEVMODE* initData )
+HDC16 CreateIC( LPCSTR driver, LPCSTR device, LPCSTR output,
+                const DEVMODE16* initData )
 {
       /* Nothing special yet for ICs */
-    return CreateDC( driver, device, output, initData );
+    return CreateDC16( driver, device, output, initData );
 }
 
 
diff --git a/objects/dib.c b/objects/dib.c
index 9ca8edf..7f37367 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -686,7 +686,8 @@
                                 dc, lines, bmp->bitmap.bmBitsPixel,
                                 bits, width, bpp, info,
                                 coloruse, bmp->pixmap, BITMAP_GC(bmp), 0, 0, 0,
-                                startscan, bmp->bitmap.bmWidth, lines );
+                                height - startscan - lines,
+                                bmp->bitmap.bmWidth, lines );
 }
 
 
diff --git a/objects/font.c b/objects/font.c
index 784cb2f..40f12a2 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -799,11 +799,18 @@
     return 1;
 }
 
+/***********************************************************************
+ *           GetTextFace16    (GDI.92)
+ */
+INT16 GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
+{
+	return GetTextFace32A(hdc,count,name);
+}
 
 /***********************************************************************
- *           GetTextFace    (GDI.92)
+ *           GetTextFace32A    (GDI32.234)
  */
-INT GetTextFace( HDC16 hdc, INT count, LPSTR name )
+INT32 GetTextFace32A( HDC32 hdc, INT32 count, LPSTR name )
 {
     FONTOBJ *font;
 
@@ -815,6 +822,19 @@
     return strlen(name);
 }
 
+/***********************************************************************
+ *           GetTextFace32W    (GDI32.235)
+ */
+INT32 GetTextFace32W( HDC32 hdc, INT32 count, LPWSTR name )
+{
+    LPSTR nameA = (LPSTR)xmalloc(count);
+    INT32 res = GetTextFace32A(hdc,count,nameA);
+
+    lstrcpynAtoW(name,nameA,count);
+    free(nameA);
+    return res;
+}
+
 
 /***********************************************************************
  *           GetTextExtent    (GDI.91)
@@ -884,7 +904,7 @@
 BOOL32 GetTextExtentPoint32ABuggy( HDC32 hdc, LPCSTR str, INT32 count,
 				   LPSIZE32 size )
 {
-    fprintf( stderr, "GetTextExtentPoint32ABuggy: not bug compatible.\n" );
+    dprintf_font( stddeb, "GetTextExtentPoint32ABuggy: not bug compatible.\n");
     return GetTextExtentPoint32A( hdc, str, count, size );
 }
 
@@ -894,12 +914,67 @@
 BOOL32 GetTextExtentPoint32WBuggy( HDC32 hdc, LPCWSTR str, INT32 count,
 				   LPSIZE32 size )
 {
-    fprintf( stderr, "GetTextExtentPoint32WBuggy: not bug compatible.\n" );
+    dprintf_font( stddeb, "GetTextExtentPoint32WBuggy: not bug compatible.\n");
     return GetTextExtentPoint32W( hdc, str, count, size );
 }
 
 
 /***********************************************************************
+ *           GetTextExtentExPoint32A    (GDI32.228)
+ */
+BOOL32 GetTextExtentExPoint32A( HDC32 hdc, LPCSTR str, INT32 count,
+                                INT32 maxExt,LPINT32 lpnFit, LPINT32 alpDx,
+                                LPSIZE32 size )
+{
+  int index;
+  SIZE32 tSize;
+  int nFit=0;
+  int extent=0;
+  DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+  if (!dc)
+    {
+      if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
+	return FALSE;
+    }
+  if (!dc->funcs->pGetTextExtentPoint) return FALSE;
+
+  size->cx=0; size->cy=0;
+  for(index=0;index<count;index++)
+    {
+      if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) return FALSE;
+      if(extent+tSize.cx<maxExt)
+	{
+	  extent+=tSize.cx;
+	  nFit++;
+	  str++;
+	  if(alpDx) alpDx[index]=extent;
+	  if(tSize.cy > size->cy) size->cy=tSize.cy;
+	}
+      else break;
+    }
+  size->cx=extent;
+  *lpnFit=nFit;
+  dprintf_font(stddeb,"GetTextExtentExPoint32A(%08x '%.*s' %d) returning %d %d %d\n",
+               hdc,count,str,maxExt,nFit, size->cx,size->cy);
+  return TRUE;
+}
+
+/***********************************************************************
+ *           GetTextExtentExPoint32W    (GDI32.229)
+ */
+
+BOOL32 GetTextExtentExPoint32W( HDC32 hdc, LPCWSTR str, INT32 count,
+                                INT32 maxExt, LPINT32 lpnFit, LPINT32 alpDx,
+                                LPSIZE32 size )
+{
+    char *p = STRING32_DupUniToAnsi( str );
+    BOOL32 ret = GetTextExtentExPoint32A( hdc, p, count, maxExt,
+					lpnFit, alpDx, size);
+    free( p );
+    return ret;
+}
+
+/***********************************************************************
  *           GetTextMetrics16    (GDI.93)
  */
 BOOL16 GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
diff --git a/programs/progman/grpfile.c b/programs/progman/grpfile.c
index 1e292a0..5e8b5b2 100644
--- a/programs/progman/grpfile.c
+++ b/programs/progman/grpfile.c
@@ -172,6 +172,14 @@
   if (lpszName >= buffer + size) return(0);
 
   /* unknown bytes 24 - 31 ignored */ 
+  /*
+    Unknown bytes should be:
+    wLogPixelsX = GET_SHORT(buffer, 24);
+    wLogPixelsY = GET_SHORT(buffer, 26);
+    byBitsPerPixel = byte at 28;
+    byPlanes     = byte at 29;
+    wReserved   = GET_SHORT(buffer, 30);
+    */
 
   hGroup = GROUP_AddGroup(lpszName, lpszGrpFile, nCmdShow, x, y,
 			  width, height, iconx, icony,
diff --git a/programs/winhelp/macro.lex.l b/programs/winhelp/macro.lex.l
index ef246e1..f0d1498 100644
--- a/programs/winhelp/macro.lex.l
+++ b/programs/winhelp/macro.lex.l
@@ -144,7 +144,7 @@
 			    {
 			      BEGIN INITIAL;
 			      *strptr++ = '\0';
-			      return STRING;
+			      return tSTRING;
 			    }
 			}
 
diff --git a/programs/winhelp/macro.yacc.y b/programs/winhelp/macro.yacc.y
index c88983c..ceb125f 100644
--- a/programs/winhelp/macro.yacc.y
+++ b/programs/winhelp/macro.yacc.y
@@ -44,7 +44,7 @@
 %token							NOT
 %token 							IF_THEN
 %token 							IF_THEN_ELSE
-%token <string>	 					STRING
+%token <string>	 					tSTRING
 %token <integer> 					INTEGER
 %token <bool_function_string>				BOOL_FUNCTION_STRING
 %token <bool_function_void>				BOOL_FUNCTION_VOID
@@ -91,49 +91,49 @@
 			'(' ')'
 			{if (! skip) (*$1)();} |
 		VOID_FUNCTION_STRING
-			'(' STRING ')'
+			'(' tSTRING ')'
 			{if (! skip) (*$1)($3);} |
 		VOID_FUNCTION_2STRING
-			'(' STRING ',' STRING ')'
+			'(' tSTRING ',' tSTRING ')'
 			{if (! skip) (*$1)($3, $5);} |
 		VOID_FUNCTION_2STRING_UINT
-			'(' STRING ',' STRING ',' INTEGER ')'
+			'(' tSTRING ',' tSTRING ',' INTEGER ')'
 			{if (! skip) (*$1)($3, $5, $7);} |
 		VOID_FUNCTION_2STRING_UINT_STRING
-			'(' STRING ',' STRING ',' INTEGER ',' STRING ')'
+			'(' tSTRING ',' tSTRING ',' INTEGER ',' tSTRING ')'
 			{if (! skip) (*$1)($3, $5, $7, $9);} |
 		VOID_FUNCTION_2STRING_2UINT_2STRING
-			'(' STRING ',' STRING ',' INTEGER ',' INTEGER ',' STRING ',' STRING ')'
+			'(' tSTRING ',' tSTRING ',' INTEGER ',' INTEGER ',' tSTRING ',' tSTRING ')'
 			{if (! skip) (*$1)($3, $5, $7, $9, $11, $13);} |
 		VOID_FUNCTION_2STRING_WPARAM_LPARAM_STRING
-			'(' STRING ',' STRING ',' INTEGER ',' INTEGER ',' STRING ')'
+			'(' tSTRING ',' tSTRING ',' INTEGER ',' INTEGER ',' tSTRING ')'
 			{if (! skip) (*$1)($3, $5, $7, $9, $11);} |
 		VOID_FUNCTION_3STRING
-			'(' STRING ',' STRING ',' STRING ')'
+			'(' tSTRING ',' tSTRING ',' tSTRING ')'
 			{if (! skip) (*$1)($3, $5, $7);} |
 		VOID_FUNCTION_3STRING_2UINT
-			'(' STRING ',' STRING ',' STRING ',' INTEGER ',' INTEGER ')'
+			'(' tSTRING ',' tSTRING ',' tSTRING ',' INTEGER ',' INTEGER ')'
 			{if (! skip) (*$1)($3, $5, $7, $9, $11);} |
 		VOID_FUNCTION_4STRING
-			'(' STRING ',' STRING ',' STRING ',' STRING ')'
+			'(' tSTRING ',' tSTRING ',' tSTRING ',' tSTRING ')'
 			{if (! skip) (*$1)($3, $5, $7, $9);} |
 		VOID_FUNCTION_4STRING_UINT
-			'(' STRING ',' STRING ',' STRING ',' STRING ',' INTEGER')'
+			'(' tSTRING ',' tSTRING ',' tSTRING ',' tSTRING ',' INTEGER')'
 			{if (! skip) (*$1)($3, $5, $7, $9, $11);} |
 		VOID_FUNCTION_4STRING_2UINT
-			'(' STRING ',' STRING ',' STRING ',' STRING ',' INTEGER ',' INTEGER')'
+			'(' tSTRING ',' tSTRING ',' tSTRING ',' tSTRING ',' INTEGER ',' INTEGER')'
 			{if (! skip) (*$1)($3, $5, $7, $9, $11, $13);} |
 		VOID_FUNCTION_STRING_UINT
-			'(' STRING ',' INTEGER ')'
+			'(' tSTRING ',' INTEGER ')'
 			{if (! skip) (*$1)($3, $5);} |
 		VOID_FUNCTION_STRING_UINT_STRING
-			'(' STRING ',' INTEGER ',' STRING ')'
+			'(' tSTRING ',' INTEGER ',' tSTRING ')'
 			{if (! skip) (*$1)($3, $5, $7);} |
 		VOID_FUNCTION_STRING_UINT_2STRING
-			'(' STRING ',' INTEGER ',' STRING ',' STRING ')'
+			'(' tSTRING ',' INTEGER ',' tSTRING ',' tSTRING ')'
 			{if (! skip) (*$1)($3, $5, $7, $9);} |
 		VOID_FUNCTION_STRING_WPARAM_LPARAM
-			'(' STRING ',' INTEGER ',' INTEGER ')'
+			'(' tSTRING ',' INTEGER ',' INTEGER ')'
 			{if (! skip) (*$1)($3, $5, $7);} |
 		VOID_FUNCTION_UINT
 			'(' INTEGER ')'
@@ -142,25 +142,25 @@
 			'(' INTEGER ',' INTEGER ')'
 			{if (! skip) (*$1)($3, $5);} |
 		VOID_FUNCTION_2UINT_STRING
-			'(' INTEGER ',' INTEGER ',' STRING ')'
+			'(' INTEGER ',' INTEGER ',' tSTRING ')'
 			{if (! skip) (*$1)($3, $5, $7);} |
 		VOID_FUNCTION_3UINT
 			'(' INTEGER ',' INTEGER ',' INTEGER ')'
 			{if (! skip) (*$1)($3, $5, $7);} |
 		VOID_FUNCTION_2INT_3UINT_STRING
-			'(' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ',' STRING ')'
+			'(' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ',' tSTRING ')'
 			{if (! skip) (*$1)($3, $5, $7, $9, $11, $13);} |
 		VOID_FUNCTION_FILE_WIN
 			'(' file_win ')'
 			{if (! skip) (*$1)(filename, windowname);} |
 		VOID_FUNCTION_FILE_WIN_STRING
-			'(' file_win ',' STRING ')'
+			'(' file_win ',' tSTRING ')'
 			{if (! skip) (*$1)(filename, windowname, $5);} |
 		VOID_FUNCTION_FILE_WIN_UINT
 			'(' file_win ',' INTEGER ')'
 			{if (! skip) (*$1)(filename, windowname, $5);} ;
 
-file_win:	STRING
+file_win:	tSTRING
                 {
 		  filename = windowname = $1;
 		  while (*windowname && *windowname != '>') windowname++;
@@ -168,6 +168,6 @@
 		} ;
 
 bool_macro:     NOT '(' bool_macro ')' {$$ = ! $3;} |
-		STRING {$$ = MACRO_IsMark($1);} |
+		tSTRING {$$ = MACRO_IsMark($1);} |
 		BOOL_FUNCTION_VOID '(' ')' {$$ = (*$1)();} |
-		BOOL_FUNCTION_STRING '(' STRING ')' {$$ = (*$1)($3);} ;
+		BOOL_FUNCTION_STRING '(' tSTRING ')' {$$ = (*$1)($3);} ;
diff --git a/rc/parser.l b/rc/parser.l
index baec1b8..bfca5ce 100644
--- a/rc/parser.l
+++ b/rc/parser.l
@@ -62,7 +62,7 @@
 SCROLLBAR	return SCROLLBAR;
 SHIFT		return SHIFT;
 SEPARATOR	return SEPARATOR;
-STRING		return STRING;
+STRING		return tSTRING;
 STRINGTABLE	return STRINGTABLE;
 STYLE		return STYLE;
 VERSIONINFO	return VERSIONINFO;
@@ -72,7 +72,7 @@
 [+-]?[0-9]+	yylval.num=atoi(yytext);return NUMBER;
 0x[0-9A-Fa-f]+L?	yylval.num=strtoul(yytext,0,16);return NUMBER;
 [A-Za-z][A-Za-z_0-9]*	yylval.str=strdup(yytext);return IDENT;
-\"[^"]*\"	yylval.str=parse_c_string(yytext);return STRING;
+\"[^"]*\"	yylval.str=parse_c_string(yytext);return tSTRING;
 \'[^']*\'   yylval.str=strdup(yytext+1);return SINGLE_QUOTED;
 \n                      { line_number++; }
 [ \t\r]                 ;
diff --git a/rc/parser.y b/rc/parser.y
index 17781ec..53f6bf5 100644
--- a/rc/parser.y
+++ b/rc/parser.y
@@ -20,14 +20,14 @@
 	struct rc_style *style;
 }
 %token <num> NUMBER
-%token <str> STRING SINGLE_QUOTED IDENT
+%token <str> tSTRING SINGLE_QUOTED IDENT
 %token ACCELERATORS ALT ASCII tBEGIN tBITMAP CAPTION CHECKBOX CHECKED 
 %token CLASS COMBOBOX CONTROL CTEXT CURSOR DEFPUSHBUTTON DIALOG 
 %token DISCARDABLE EDITTEXT tEND FIXED FONT GRAYED GROUPBOX HELP ICON 
 %token IDENT INACTIVE LISTBOX LTEXT MENU MENUBARBREAK MENUBREAK MENUITEM 
 %token MOVEABLE LOADONCALL NOINVERT NOT NOT_SUPPORTED POPUP PRELOAD 
 %token PURE PUSHBUTTON RADIOBUTTON RCDATA RTEXT SCROLLBAR SHIFT SEPARATOR 
-%token SINGLE_QUOTED STRING STRINGTABLE STYLE VERSIONINFO VIRTKEY
+%token SINGLE_QUOTED tSTRING STRINGTABLE STYLE VERSIONINFO VIRTKEY
 %type <res> resource_file resource resources resource_definition accelerators
 %type <res> events bitmap cursor dialog dlg_attributes controls 
 %type <res> generic_control labeled_control control_desc font icon 
@@ -76,7 +76,7 @@
 /* the events are collected in a gen_res, as the accelerator resource is just
    an array of events */
 events:		{$$=new_res();}
-		| STRING ',' NUMBER acc_options  events 
+		| tSTRING ',' NUMBER acc_options  events 
 			{$$=add_string_accelerator($1,$3,$4,$5);}
 		| NUMBER ',' NUMBER ',' ASCII acc_options  events 
 			{$$=add_ascii_accelerator($1,$3,$6,$7);}
@@ -88,14 +88,14 @@
 		| ',' SHIFT acc_options	   {$$=$3|4;}
 		| ',' CONTROL acc_options  {$$=$3|8;}
 
-bitmap:		tBITMAP load_and_memoption STRING {$$=make_bitmap(load_file($3));}
+bitmap:		tBITMAP load_and_memoption tSTRING {$$=make_bitmap(load_file($3));}
 		| tBITMAP load_and_memoption raw_data {$$=make_bitmap($3);}
 
 /* load and memory options are ignored */
 load_and_memoption:	| lamo load_and_memoption
 lamo:	PRELOAD | LOADONCALL | FIXED | MOVEABLE | DISCARDABLE | PURE
 
-cursor:		CURSOR load_and_memoption STRING {$$=make_cursor(load_file($3));}
+cursor:		CURSOR load_and_memoption tSTRING {$$=make_cursor(load_file($3));}
 		|CURSOR load_and_memoption raw_data {$$=make_cursor($3);}
 
 dialog:		DIALOG load_and_memoption NUMBER ',' NUMBER ',' NUMBER ',' NUMBER 
@@ -106,13 +106,13 @@
 dlg_attributes:	{$$=new_dialog();}
 		| STYLE style dlg_attributes 
 		  {$$=dialog_style($2,$3);}
-		| CAPTION STRING dlg_attributes
+		| CAPTION tSTRING dlg_attributes
 		  {$$=dialog_caption($2,$3);}
-		| FONT NUMBER ',' STRING dlg_attributes 
+		| FONT NUMBER ',' tSTRING dlg_attributes 
 		  {$$=dialog_font($2,$4,$5);}
-		| CLASS STRING dlg_attributes
+		| CLASS tSTRING dlg_attributes
 		  {$$=dialog_class($2,$3);}
-		| MENU STRING dlg_attributes
+		| MENU tSTRING dlg_attributes
 		  {$$=dialog_menu($2,$3);}
 
 /* the controls are collected into a gen_res, and finally the dialog header 
@@ -133,7 +133,7 @@
 		| GROUPBOX labeled_control controls 
 		  {$$=add_control(CT_BUTTON, BS_GROUPBOX, $2, $3);}
 		/*special treatment for icons, as the extent is optional*/
-		| ICON STRING ',' NUMBER ',' NUMBER ',' NUMBER iconinfo controls
+		| ICON tSTRING ',' NUMBER ',' NUMBER ',' NUMBER iconinfo controls
 		  {$$=add_icon($2, $4, $6, $8, $9, $10);}
 		| LISTBOX control_desc controls 
 		  {$$=add_control(CT_LISTBOX, 0, $2, $3);}
@@ -149,7 +149,7 @@
 		  {$$=add_control(CT_SCROLLBAR, 0, $2, $3);}
 
 
-labeled_control: STRING ',' control_desc {$$=label_control_desc($1,$3);}
+labeled_control: tSTRING ',' control_desc {$$=label_control_desc($1,$3);}
 control_desc:	NUMBER ',' NUMBER ',' NUMBER ',' NUMBER ',' NUMBER optional_style 
 		{$$=create_control_desc($1,$3,$5,$7,$9,$10);}
 
@@ -162,24 +162,24 @@
 		| ',' NUMBER ',' NUMBER optional_style
         {$$=create_control_desc(0,0,0,$2,$4,$5);}
 
-generic_control:	STRING ',' NUMBER ',' STRING ',' style ',' NUMBER
+generic_control:	tSTRING ',' NUMBER ',' tSTRING ',' style ',' NUMBER
 		',' NUMBER ',' NUMBER ',' NUMBER
 		{$$=create_generic_control($1,$3,$5,$7,$9,$11,$13,$15);}
 
-font:		FONT load_and_memoption STRING {$$=make_font(load_file($3));}
+font:		FONT load_and_memoption tSTRING {$$=make_font(load_file($3));}
 
-icon:		ICON load_and_memoption STRING {$$=make_icon(load_file($3));}
+icon:		ICON load_and_memoption tSTRING {$$=make_icon(load_file($3));}
 		| ICON load_and_memoption raw_data {$$=make_icon($3);}
 
 menu:		MENU load_and_memoption menu_body {$$=make_menu($3);}
 /* menu items are collected in a gen_res and prefixed with the menu header*/
 menu_body:	tBEGIN item_definitions tEND {$$=$2;}
 item_definitions:	{$$=new_res();}
-		| MENUITEM STRING ',' NUMBER item_options item_definitions
+		| MENUITEM tSTRING ',' NUMBER item_options item_definitions
 		  {$$=add_menuitem($2,$4,$5,$6);}
 		| MENUITEM SEPARATOR item_definitions
 		  {$$=add_menuitem("",0,0,$3);}
-		| POPUP STRING item_options menu_body item_definitions
+		| POPUP tSTRING item_options menu_body item_definitions
 		  {$$=add_popup($2,$3,$4,$5);}
 item_options:	{$$=0;}
 		| ',' CHECKED item_options {$$=$3|MF_CHECKED;}
@@ -200,7 +200,7 @@
 stringtable:	STRINGTABLE load_and_memoption tBEGIN strings tEND
 			{$$=$4;}
 strings:	{$$=0;}|
-		NUMBER STRING strings {$$=0;add_str_tbl_elm($1,$2);}
+		NUMBER tSTRING strings {$$=0;add_str_tbl_elm($1,$2);}
 
 versioninfo:	VERSIONINFO NOT_SUPPORTED {$$=0;}
 
diff --git a/tools/build.c b/tools/build.c
index 2381002..bcb2697 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -1194,7 +1194,7 @@
             fprintf( outfile, "\tpushw %%bp\n" );
             fprintf( outfile, "\tpushl $" PREFIX "%s\n",odp->u.func.link_name);
             /* FreeBSD does not understand lcall, so do it the hard way */
-            fprintf( outfile, "\t.byte 0x9a /*lcall*/\n" );
+            fprintf( outfile, "\t.byte 0x9a\n" );
             fprintf( outfile, "\t.long " PREFIX "CallFrom16_%s_%s\n",
                      (odp->type == TYPE_REGISTER) ? "regs" :
                      (odp->type == TYPE_PASCAL) ? "long" : "word",
diff --git a/win32/advapi.c b/win32/advapi.c
index 4b37d55..c43ef5b 100644
--- a/win32/advapi.c
+++ b/win32/advapi.c
@@ -11,23 +11,65 @@
 #include "advapi32.h"
 #include "stddebug.h"
 #include "debug.h"
+#include "xmalloc.h"
 
 /***********************************************************************
- *           GetUserNameA   [ADVAPI32.67]
+ *           StartServiceCtrlDispatcherA   [ADVAPI32.196]
  */
-
-BOOL GetUserNameA(LPSTR lpszName, LPDWORD lpSize)
+BOOL32
+StartServiceCtrlDispatcher32A(LPSERVICE_TABLE_ENTRY32A servent)
 {
-  size_t len;
-  char *name;
+	fprintf(stderr,"StartServiceCtrlDispatcherA(%p (%s)), STUB.\n",
+		servent,
+		servent->lpServiceName
+	);
+	return TRUE;
+}
 
-  name=getlogin();
-  len = name ? strlen(name) : 0;
-  if (!len || !lpSize || len > *lpSize) {
-    if (lpszName) *lpszName = 0;
-    return 0;
-  }
-  *lpSize=len;
-  strcpy(lpszName, name);
-  return 1;
+/***********************************************************************
+ *           StartServiceCtrlDispatcherW   [ADVAPI32.197]
+ */
+BOOL32
+StartServiceCtrlDispatcher32W(LPSERVICE_TABLE_ENTRY32W servent)
+{
+	char	buffer[200];
+
+	lstrcpynWtoA(buffer,servent->lpServiceName,200);
+	fprintf(stderr,"StartServiceCtrlDispatcherA(%p (%s)), STUB.\n",
+		servent,
+		buffer
+	);
+	return TRUE;
+}
+
+
+/***********************************************************************
+ *           OpenProcessToken   [ADVAPI32.197]
+ */
+BOOL32
+OpenProcessToken(HANDLE32 process,DWORD desiredaccess,HANDLE32 *thandle)
+{
+	fprintf(stdnimp,"OpenProcessToken(%08lx,%08lx,%p),stub!\n",
+		process,desiredaccess,thandle
+	);
+	return TRUE;
+}
+
+/***********************************************************************
+ *           LookupPrivilegeValueA   [ADVAPI32.90]
+ */
+BOOL32
+LookupPrivilegeValue32A(LPCSTR system,LPCSTR name,LPVOID bla)
+{
+	fprintf(stdnimp,"LookupPrivilegeValue32A(%s,%s,%p),stub\n",
+		system,name,bla
+	);
+	return TRUE;
+}
+BOOL32
+AdjustTokenPrivileges(HANDLE32 TokenHandle,BOOL32 DisableAllPrivileges,
+	LPVOID NewState,DWORD BufferLength,LPVOID PreviousState,
+	LPDWORD ReturnLength )
+{
+	return TRUE;
 }
diff --git a/win32/console.c b/win32/console.c
index ec866f5..8fb2f66 100644
--- a/win32/console.c
+++ b/win32/console.c
@@ -5,9 +5,12 @@
  */
 
 #include <stdio.h>
+#include <malloc.h>
 #include "windows.h"
 #include "winerror.h"
 #include "wincon.h"
+#include "string32.h"
+#include "xmalloc.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -51,11 +54,155 @@
 /***********************************************************************
  *            GetLargestConsoleWindowSize   (KERNEL32.226)
  */
-COORD GetLargestConsoleWindowSize( HANDLE32 hConsoleOutput )
+DWORD GetLargestConsoleWindowSize( HANDLE32 hConsoleOutput )
 {
-    return dummyinfo.dwMaximumWindowSize;
+    return (DWORD)MAKELONG(dummyinfo.dwMaximumWindowSize.x,dummyinfo.dwMaximumWindowSize.y);
 }
 
+/***********************************************************************
+ *            GetConsoleCP   (KERNEL32.226)
+ */
+UINT32 GetConsoleCP(VOID)
+{
+    return GetACP();
+}
 
+/***********************************************************************
+ *            GetConsoleOutputCP   (KERNEL32.189)
+ */
+UINT32 GetConsoleOutputCP(VOID)
+{
+    return GetConsoleCP();
+}
 
+/***********************************************************************
+ *            GetConsoleMode   (KERNEL32.188)
+ */
+BOOL32 GetConsoleMode(HANDLE32 hcon,LPDWORD mode)
+{
+	*mode = 	ENABLE_PROCESSED_INPUT	|
+			ENABLE_LINE_INPUT	|
+			ENABLE_ECHO_INPUT	|
+			ENABLE_WINDOW_INPUT	|
+			ENABLE_MOUSE_INPUT;
+	return TRUE;
+}
 
+/***********************************************************************
+ *            SetConsoleMode   (KERNEL32.188)
+ */
+BOOL32 SetConsoleMode(HANDLE32 hcon,DWORD mode)
+{
+    fprintf(stdnimp,"SetConsoleMode(%08lx,%08lx)\n",hcon,mode);
+    return TRUE;
+}
+
+/***********************************************************************
+ *            GetConsoleTitleA   (KERNEL32.191)
+ */
+DWORD GetConsoleTitle32A(LPSTR title,DWORD size)
+{
+    lstrcpyn32A(title,"Console",size);
+    return strlen("Console");
+}
+
+/***********************************************************************
+ *            GetConsoleTitleW   (KERNEL32.192)
+ */
+DWORD GetConsoleTitle32W(LPWSTR title,DWORD size)
+{
+    lstrcpynAtoW(title,"Console",size);
+    return strlen("Console");
+}
+
+/***********************************************************************
+ *            WriteConsoleA   (KERNEL32.567)
+ */
+BOOL32 WriteConsole32A(
+	HANDLE32 hConsoleOutput,
+	LPVOID lpBuffer,
+	DWORD nNumberOfCharsToWrite,
+	LPDWORD lpNumberOfCharsWritten,
+	LPVOID lpReserved )
+{
+	LPSTR	buf = (LPSTR)xmalloc(nNumberOfCharsToWrite+1);
+
+	lstrcpyn32A(buf,lpBuffer,nNumberOfCharsToWrite);
+	buf[nNumberOfCharsToWrite]=0;
+	fprintf(stderr,"%s",buf);
+	free(buf);
+	*lpNumberOfCharsWritten=nNumberOfCharsToWrite;
+	return TRUE;
+}
+
+/***********************************************************************
+ *            WriteConsoleW   (KERNEL32.577)
+ */
+BOOL32 WriteConsole32W(
+	HANDLE32 hConsoleOutput,
+	LPVOID lpBuffer,
+	DWORD nNumberOfCharsToWrite,
+	LPDWORD lpNumberOfCharsWritten,
+	LPVOID lpReserved )
+{
+	LPSTR	buf = (LPSTR)xmalloc(2*nNumberOfCharsToWrite+1);
+
+	lstrcpynWtoA(buf,lpBuffer,nNumberOfCharsToWrite);
+	buf[nNumberOfCharsToWrite]=0;
+	fprintf(stderr,"%s",buf);
+	free(buf);
+	*lpNumberOfCharsWritten=nNumberOfCharsToWrite;
+	return TRUE;
+}
+
+/***********************************************************************
+ *            ReadConsoleA   (KERNEL32.419)
+ */
+BOOL32 ReadConsole32A(
+	HANDLE32 hConsoleInput,
+	LPVOID lpBuffer,
+	DWORD nNumberOfCharsToRead,
+	LPDWORD lpNumberOfCharsRead,
+	LPVOID lpReserved )
+{
+	fgets(lpBuffer,nNumberOfCharsToRead,stdin);
+	*lpNumberOfCharsRead = strlen(lpBuffer);
+	return TRUE;
+}
+
+/***********************************************************************
+ *            ReadConsoleW   (KERNEL32.427)
+ */
+BOOL32 ReadConsole32W(
+	HANDLE32 hConsoleInput,
+	LPVOID lpBuffer,
+	DWORD nNumberOfCharsToRead,
+	LPDWORD lpNumberOfCharsRead,
+	LPVOID lpReserved )
+{
+	LPSTR	buf = (LPSTR)xmalloc(nNumberOfCharsToRead);
+
+	fgets(buf,nNumberOfCharsToRead,stdin);
+	lstrcpynAtoW(lpBuffer,buf,nNumberOfCharsToRead);
+	*lpNumberOfCharsRead = strlen(buf);
+	return TRUE;
+}
+
+/***********************************************************************
+ *            SetConsoleTitleA   (KERNEL32.476)
+ */
+BOOL32 SetConsoleTitle32A(LPCSTR title)
+{
+    fprintf(stderr,"SetConsoleTitle(%s)\n",title);
+    return TRUE;
+}
+/***********************************************************************
+ *            SetConsoleTitleW   (KERNEL32.477)
+ */
+BOOL32 SetConsoleTitle32W(LPCWSTR title)
+{
+    LPSTR titleA = STRING32_DupUniToAnsi(title);
+    fprintf(stderr,"SetConsoleTitle(%s)\n",titleA);
+    free(titleA);
+    return TRUE;
+}
diff --git a/win32/cursoricon32.c b/win32/cursoricon32.c
index c87a784..14a34bd 100644
--- a/win32/cursoricon32.c
+++ b/win32/cursoricon32.c
@@ -26,11 +26,11 @@
 #include <string.h>
 #include <stdlib.h>
 #include "windows.h"
-#include "bitmap.h"
 #include "callback.h"
 #include "cursoricon.h"
 #include "sysmetrics.h"
 #include "win.h"
+#include "bitmap.h"
 #include "struct32.h"
 #include "string32.h"
 #include "stddebug.h"
diff --git a/win32/file.c b/win32/file.c
index e60bc61..bb74b48 100644
--- a/win32/file.c
+++ b/win32/file.c
@@ -558,3 +558,80 @@
 	free(afn2);
 	return res;
 }
+
+VOID SetFileApisToOEM()
+{
+    fprintf(stdnimp,"SetFileApisToOEM(),stub!\n");
+}
+
+VOID SetFileApisToANSI()
+{
+    fprintf(stdnimp,"SetFileApisToANSI(),stub!\n");
+}
+
+BOOL32 AreFileApisANSI()
+{
+    fprintf(stdnimp,"AreFileApisANSI(),stub!\n");
+    return TRUE;
+}
+
+
+BOOL32 CopyFile32A(LPCSTR sourcefn,LPCSTR destfn,BOOL32 failifexists)
+{
+	OFSTRUCT	of;
+	HFILE		hf1,hf2;
+	char		buffer[2048];
+	int		res,lastread,curlen;
+
+	fprintf(stddeb,"CopyFile: %s -> %s\n",sourcefn,destfn);
+	hf1 = OpenFile(sourcefn,&of,OF_READ);
+	if (hf1==HFILE_ERROR)
+		return TRUE;
+	if (failifexists) {
+		hf2 = OpenFile(sourcefn,&of,OF_WRITE);
+		if (hf2 != HFILE_ERROR)
+			return FALSE;
+		_lclose(hf2);
+	}
+	hf2 = OpenFile(sourcefn,&of,OF_WRITE);
+	if (hf2 == HFILE_ERROR)
+		return FALSE;
+	curlen = 0;
+	while ((lastread=_lread16(hf1,buffer,sizeof(buffer)))>0) {
+		curlen=0;
+		while (curlen<lastread) {
+			int	res;
+
+			res=_lwrite16(hf2,buffer+curlen,lastread-curlen);
+			if (res<=0) break;
+			curlen+=res;
+		}
+	}
+	_lclose(hf1);
+	_lclose(hf2);
+	return res>0;
+}
+
+BOOL32
+LockFile(
+	HFILE hFile,DWORD dwFileOffsetLow,DWORD dwFileOffsetHigh,
+	DWORD nNumberOfBytesToLockLow,DWORD nNumberOfBytesToLockHigh )
+{
+	fprintf(stdnimp,"LockFile(%d,0x%08lx%08lx,0x%08lx%08lx),stub!\n",
+		hFile,dwFileOffsetHigh,dwFileOffsetLow,
+		nNumberOfBytesToLockHigh,nNumberOfBytesToLockLow
+	);
+	return TRUE;
+}
+
+BOOL32
+UnlockFile(
+	HFILE hFile,DWORD dwFileOffsetLow,DWORD dwFileOffsetHigh,
+	DWORD nNumberOfBytesToUnlockLow,DWORD nNumberOfBytesToUnlockHigh )
+{
+	fprintf(stdnimp,"UnlockFile(%d,0x%08lx%08lx,0x%08lx%08lx),stub!\n",
+		hFile,dwFileOffsetHigh,dwFileOffsetLow,
+		nNumberOfBytesToUnlockHigh,nNumberOfBytesToUnlockLow
+	);
+	return TRUE;
+}
diff --git a/win32/findfile.c b/win32/findfile.c
index 011070e..0c6618a 100644
--- a/win32/findfile.c
+++ b/win32/findfile.c
@@ -3,12 +3,20 @@
 #include <string.h>
 #include <ctype.h>
 #include <malloc.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <unistd.h>
 #include "xmalloc.h"
 #include "windows.h"
 #include "winerror.h"
 #include "dos_fs.h"
 #include "heap.h"
 #include "string32.h"
+#include "drive.h"
+#include "stddebug.h"
+#include "debug.h"
+
+
 
 #define PATH_LEN 260
 
@@ -16,23 +24,33 @@
     DIR *	dir;
     char mask[PATH_LEN];
     char path[PATH_LEN];
+    char unixpath[PATH_LEN];
 };
 
 typedef struct FindFileContext32 FindFileContext32;
 
 const char *DOSFS_Hash(const char *, int, int);
 
-/* example D:\*.dbs */
+/* TODO/FIXME
+ * 1) Check volume information to see if long file names supported
+ * and do separate wildcard matching if so. Win95 has extended wildcard
+ * matching - It can have wildcards like '*foo*'. These can match both
+ * the long file name and the short file name.
+ * 2) These file functions may be called from an interrupt
+ *    Interrupt 21h Function 714Eh	FindFirstFile
+ *    Interrupt 21h Function 714Fh	FindNextFile
+ *    Interrupt 21h Function 71A1h	FindClose
+ */
 
 static BOOL32 MatchWildCard(LPCSTR file, LPCSTR mask)
 {
     int	len;
 
-    /* We should check volume information to see if long filenames possible.
-     */
-
     len = strlen(file);
 
+    if (strcmp(mask, "*.*") == 0)
+      return TRUE;
+
     while (*file) {
 	if (*mask == '*') {
 	    if (*(mask+1)) {
@@ -54,6 +72,48 @@
     return (TRUE);
 }
 
+/* Functionality is same as GetFileInformationByHandle, but the structures
+ * it fills out are different. This needs to be kept the same as the above
+ * mentioned function.
+ */
+
+
+static BOOL32 FINDFILE_GetFileInfo(const char *filename,
+				   LPWIN32_FIND_DATA32A finfo)
+{
+  struct stat file_stat;
+
+  if (stat(filename, &file_stat) == -1) {
+    SetLastError(ErrnoToLastError(errno));
+    return FALSE;
+  }
+  finfo->dwFileAttributes = 0;
+  if (file_stat.st_mode & S_IFREG)
+    finfo->dwFileAttributes |= FILE_ATTRIBUTE_NORMAL;
+  if (file_stat.st_mode & S_IFDIR)
+    finfo->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
+  if ((file_stat.st_mode & S_IRUSR) == 0)
+    finfo->dwFileAttributes |= FILE_ATTRIBUTE_READONLY;
+
+  /* Translate the file times.  Use the last modification time
+   * for both the creation time and write time.
+   */
+  DOSFS_UnixTimeToFileTime(file_stat.st_mtime, &(finfo->ftCreationTime));
+  DOSFS_UnixTimeToFileTime(file_stat.st_mtime, &(finfo->ftLastWriteTime));
+  DOSFS_UnixTimeToFileTime(file_stat.st_atime, &(finfo->ftLastAccessTime));
+
+  finfo->nFileSizeLow = file_stat.st_size;
+
+  /* Zero out currently unused fields.
+   */
+  finfo->nFileSizeHigh = 0;
+  finfo->dwReserved0 = 0;
+  finfo->dwReserved1 = 0;
+  return TRUE;
+
+}
+
+
 /*************************************************************************
  *              FindNextFile32A             (KERNEL32.126)
  */
@@ -62,6 +122,7 @@
     FindFileContext32 *context;
     struct dirent *dirent;
     char  dosname[14];
+    char  fullfilename[PATH_LEN];
 
     memset(data, 0, sizeof(WIN32_FIND_DATA32A));
     context = (FindFileContext32 *) handle;
@@ -71,17 +132,24 @@
 	    strcmp(dirent->d_name, ".") == 0)
 	    continue;
 
-	strcpy(dosname, DOSFS_Hash(dirent->d_name, FALSE, FALSE));
+	lstrcpy32A(dosname, DOSFS_Hash(dirent->d_name, FALSE, FALSE));
 
 	if (MatchWildCard(dirent->d_name, context->mask)) {
-	    /* Full file name - is this a long file name?
-	     * If it is, we should probably use the dirent
-	     * instead of the dos hashed name.
-	     */
-	    strcpy(data->cFileName, dosname);
+	    /* fill in file information */
+	    lstrcpy32A(fullfilename, context->unixpath);
+	    if (context->unixpath[strlen(context->unixpath)-1] != '/')
+	      strcat(fullfilename, "/");
+	    strcat(fullfilename, dirent->d_name);
+            FINDFILE_GetFileInfo(fullfilename, data);
+
+	    /* long file name */
+	    lstrcpy32A(data->cFileName, dirent->d_name);
 
 	    /* file name expressed in 8.3 format */
-	    strcpy(data->cAlternateFileName, dosname);
+	    lstrcpy32A(data->cAlternateFileName, dosname);
+
+	    dprintf_file(stddeb, "FindNextFile32A: %s (%s)\n",
+			 data->cFileName, data->cAlternateFileName);
 	    return (TRUE);
 	}
     }
@@ -95,6 +163,7 @@
 BOOL32 FindNextFile32W(HANDLE32 handle, LPWIN32_FIND_DATA32W data)
 {
     WIN32_FIND_DATA32A	adata;
+    BOOL32	res;
 
     adata.dwFileAttributes	= data->dwFileAttributes;
     adata.ftCreationTime	= data->ftCreationTime;
@@ -106,25 +175,72 @@
     adata.dwReserved1		= data->dwReserved1;
     STRING32_UniToAnsi(adata.cFileName,data->cFileName);
     STRING32_UniToAnsi(adata.cAlternateFileName,data->cAlternateFileName);
-    return FindNextFile32A(handle,&adata);
+    res=FindNextFile32A(handle,&adata);
+    if (res) {
+	    data->dwFileAttributes 	= adata.dwFileAttributes;
+	    data->ftCreationTime	= adata.ftCreationTime;
+	    data->ftLastAccessTime	= adata.ftLastAccessTime;
+	    data->ftLastWriteTime	= adata.ftLastWriteTime;
+	    data->nFileSizeHigh		= adata.nFileSizeHigh;
+	    data->nFileSizeLow		= adata.nFileSizeLow;
+	    data->dwReserved0		= adata.dwReserved0; 
+	    data->dwReserved1		= adata.dwReserved1;
+	    STRING32_AnsiToUni(data->cFileName,adata.cFileName);
+	    STRING32_AnsiToUni(data->cAlternateFileName,adata.cAlternateFileName);
+    }
+    return res;
 }
 
 /*************************************************************************
  *              FindFirstFile32A             (KERNEL32.123)
  */
 
-HANDLE32 FindFirstFile32A(LPCSTR lpfilename, 
+HANDLE32 FindFirstFile32A(LPCSTR lpfilename_in, 
 			  LPWIN32_FIND_DATA32A lpFindFileData)
 {
     const char *unixpath;
     char *slash, *p;
     FindFileContext32 *context;
+    char	lpfilename[PATH_LEN];
+    INT32	len;
 
     context = HeapAlloc(SystemHeap, 0, sizeof(FindFileContext32));
     if (!context)
 	return (INVALID_HANDLE_VALUE);
 
+    /* These type of cases
+     * A;\*.*
+     * A;stuff\*.*
+     * *.*
+     * \stuff\*.*
+     */
+    lstrcpy32A(lpfilename, lpfilename_in);
+    if (lpfilename[1] != ':' &&
+	lpfilename[0] != '\\') {
+      /* drive and root path are not set */
+      len = GetCurrentDirectory32A(PATH_LEN, lpfilename);
+      if (lpfilename[len-1] != '\\')
+	strcat(lpfilename, "\\");
+      strcat(lpfilename, lpfilename_in);
+    }
+    else if (lpfilename[1] != ':') {
+      /* drive not set, but path is rooted */
+      memmove(&lpfilename[2], lpfilename, strlen(lpfilename));
+      lpfilename[0] = DRIVE_GetCurrentDrive();
+      lpfilename[1] = ':';
+    }
+    else if (lpfilename[1] == ':' &&
+	     lpfilename[2] != '\\') {
+      /* drive is set, but not root path */
+      lstrcpy32A(lpfilename, DRIVE_GetDosCwd(lpfilename[0]));
+      strcat(lpfilename, lpfilename_in);
+    }
+
+    dprintf_file(stddeb, "FindFirstFile32A: %s -> %s .\n",
+		 lpfilename_in, lpfilename);
+
     slash = strrchr(lpfilename, '\\');
+
     if (slash) {
 	lstrcpyn32A(context->path, lpfilename, slash - lpfilename + 1);
 	context->path[slash - lpfilename + 1] = '\0';
@@ -137,11 +253,13 @@
 	lstrcpy32A(context->mask, slash+1);
     }
     else {
-	context->path[0] = '\0';
-	unixpath = ".";
-	lstrcpy32A(context->mask, lpfilename);
+      /* shouldn't really get here now */
+      context->path[0] = '\0';
+      unixpath = ".";
+      lstrcpy32A(context->mask, lpfilename);
     }
 
+    lstrcpy32A(context->unixpath, unixpath);
     context->dir = opendir(unixpath);
     if (!context->dir) {
 	/* FIXME: SetLastError(??) */
@@ -167,17 +285,19 @@
     LPSTR		afn = STRING32_DupUniToAnsi(filename);
     HANDLE32		res;
 
-    adata.dwFileAttributes	= data->dwFileAttributes;
-    adata.ftCreationTime	= data->ftCreationTime;
-    adata.ftLastAccessTime	= data->ftLastAccessTime;
-    adata.ftLastWriteTime	= data->ftLastWriteTime;
-    adata.nFileSizeHigh		= data->nFileSizeHigh;
-    adata.nFileSizeLow		= data->nFileSizeLow;
-    adata.dwReserved0		= data->dwReserved0;
-    adata.dwReserved1		= data->dwReserved1;
-    STRING32_UniToAnsi(adata.cFileName,data->cFileName);
-    STRING32_UniToAnsi(adata.cAlternateFileName,data->cAlternateFileName);
     res=FindFirstFile32A(afn,&adata);
+    if (res) {
+	data->dwFileAttributes 	= adata.dwFileAttributes;
+	data->ftCreationTime	= adata.ftCreationTime;
+	data->ftLastAccessTime	= adata.ftLastAccessTime;
+	data->ftLastWriteTime	= adata.ftLastWriteTime;
+	data->nFileSizeHigh	= adata.nFileSizeHigh;
+	data->nFileSizeLow	= adata.nFileSizeLow;
+	data->dwReserved0	= adata.dwReserved0; 
+	data->dwReserved1	= adata.dwReserved1;
+	STRING32_AnsiToUni(data->cFileName,adata.cFileName);
+	STRING32_AnsiToUni(data->cAlternateFileName,adata.cAlternateFileName);
+    }
     free(afn);
     return res;
 }
@@ -201,3 +321,71 @@
     HeapFree(SystemHeap, 0, context);
     return (TRUE);
 }
+
+/* 16 bit versions of find functions */
+/*************************************************************************
+ *              FindFirstFile16             (KERNEL.413)
+ */
+
+HANDLE16
+FindFirstFile16(LPCSTR lpFileName, LPVOID lpdata)
+{
+  WIN32_FIND_DATA32A	*findData = (WIN32_FIND_DATA32A *) lpdata;
+  HANDLE32 h32;
+  HGLOBAL16 h16;
+  HANDLE32 *ptr;
+
+  /* get a handle to the real pointer */
+
+
+  h32 = FindFirstFile32A(lpFileName, findData);
+  if (h32 > 0) {
+    h16 = GlobalAlloc16(0, sizeof(h32));
+    ptr = GlobalLock16(h16);
+    *ptr = h32;
+    return (h16);
+  }
+  else
+    return ((HANDLE16) h32);
+}
+
+/*************************************************************************
+ *              FindNextFile16             (KERNEL.414)
+ */
+
+BOOL16
+FindNextFile16(HANDLE16 handle, LPVOID lpdata)
+{
+  WIN32_FIND_DATA32A	*findData = (WIN32_FIND_DATA32A *) lpdata;
+  HANDLE32 *lph32;
+  
+  lph32 = GlobalLock16(handle);
+  if (FindNextFile32A(*lph32, findData)) {
+    return TRUE;
+  }
+  else
+    return FALSE;
+}
+
+/*************************************************************************
+ *              FindClose16             (KERNEL.415)
+ */
+
+BOOL16
+FindClose16(HANDLE16 handle)
+{
+  HANDLE32 *lph32;
+  BOOL16 ret;
+
+  if (handle == (HANDLE16) INVALID_HANDLE_VALUE) {
+    SetLastError(ERROR_INVALID_HANDLE);
+    return FALSE;
+  }
+
+  lph32 = GlobalLock16(handle);
+  ret = FindClose32(*lph32);
+  GlobalFree16(handle);
+  return (ret);
+}
+
+
diff --git a/win32/init.c b/win32/init.c
index 8585a93..b61ac47 100644
--- a/win32/init.c
+++ b/win32/init.c
@@ -13,8 +13,11 @@
 #include "except.h"
 #include "task.h"
 #include "stddebug.h"
+#include "string32.h"
 #define DEBUG_WIN32
 #include "debug.h"
+#include "string32.h"
+#include "xmalloc.h"
   
 /* The global error value
  */
@@ -25,14 +28,10 @@
  */
 BOOL CloseHandle(KERNEL_OBJECT *handle)
 {
-    if(ValidateKernelObject(handle) != 0)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return 0;
-    }
-
     if (handle<0x1000) /* FIXME: hack */
     	return CloseFileHandle(handle);
+    if (handle==0xFFFFFFFF)
+    	return FALSE;
     switch(handle->magic)
     {
         case KERNEL_OBJECT_UNUSED:
@@ -57,11 +56,11 @@
 /***********************************************************************
  *              GetModuleHandle         (KERNEL32.237)
  */
-HMODULE32 WIN32_GetModuleHandle(char *module)
+HMODULE32 WIN32_GetModuleHandleA(char *module)
 {
     HMODULE32 hModule;
 
-    dprintf_win32(stddeb, "GetModuleHandle: %s\n", module ? module : "NULL");
+    dprintf_win32(stddeb, "GetModuleHandleA: %s\n", module ? module : "NULL");
 /* Freecell uses the result of GetModuleHandleA(0) as the hInstance in
 all calls to e.g. CreateWindowEx. */
     if (module == NULL) {
@@ -69,17 +68,29 @@
 	hModule = pTask->hInstance;
     } else
 	hModule = GetModuleHandle(module);
-    dprintf_win32(stddeb, "GetModuleHandle: returning %d\n", hModule );
+    dprintf_win32(stddeb, "GetModuleHandleA: returning %d\n", hModule );
     return hModule;
 }
 
+HMODULE32 WIN32_GetModuleHandleW(LPCWSTR module)
+{
+  HMODULE32 hModule;
+  LPSTR     modulea;
+  if(module==NULL) return WIN32_GetModuleHandleA(NULL);
+  modulea=STRING32_DupUniToAnsi(module);
+  hModule = WIN32_GetModuleHandleA(modulea);
+  free(modulea);
+  return hModule;
+}
+
+
 /***********************************************************************
  *              GetStartupInfoA         (KERNEL32.273)
  */
-VOID GetStartupInfoA(LPSTARTUPINFO lpStartupInfo)
+VOID GetStartupInfo32A(LPSTARTUPINFO32A lpStartupInfo)
 {
-    lpStartupInfo->cb = sizeof(STARTUPINFO);
-    lpStartupInfo->lpReserved = NULL;
+    lpStartupInfo->cb = sizeof(STARTUPINFO32A);
+    lpStartupInfo->lpReserved = "<Reserved>";
     lpStartupInfo->lpDesktop = "Desktop";
     lpStartupInfo->lpTitle = "Title";
 
@@ -91,23 +102,57 @@
 }
 
 /***********************************************************************
+ *              GetStartupInfoW         (KERNEL32.274)
+ */
+VOID GetStartupInfo32W(LPSTARTUPINFO32W lpStartupInfo)
+{
+    lpStartupInfo->cb = sizeof(STARTUPINFO32W);
+    lpStartupInfo->lpReserved = STRING32_DupAnsiToUni("<Reserved>");
+    lpStartupInfo->lpDesktop = STRING32_DupAnsiToUni("Desktop");
+    lpStartupInfo->lpTitle = STRING32_DupAnsiToUni("Title");
+
+    lpStartupInfo->cbReserved2 = 0;
+    lpStartupInfo->lpReserved2 = NULL; /* must be NULL for VC runtime */
+    lpStartupInfo->hStdInput  = (HANDLE32)0;
+    lpStartupInfo->hStdOutput = (HANDLE32)1;
+    lpStartupInfo->hStdError  = (HANDLE32)2;
+}
+
+/***********************************************************************
  *              GetStartupInfoA         (KERNEL32.284)
- * FIXME: perhaps supply better values.
+ * FIXME: perhaps supply better values. 
+ *        add other architectures for WINELIB.
  */
 VOID
 GetSystemInfo(LPSYSTEM_INFO si) {
-    si->dwOemId		= 0x12345678;
-    si->dwPageSize	= 4096; /* 4K */
-    si->lpMinimumApplicationAddress = 0x40000000;
-    si->lpMaximumApplicationAddress = 0x80000000;
-    si->dwActiveProcessorMask       = 1;
-    si->dwNumberOfProcessors        = 1;
+    WORD cpu;
+    
+    si->u.x.wProcessorArchitecture	= PROCESSOR_ARCHITECTURE_INTEL;
+
+    si->dwPageSize			= 4096; /* 4K */
+    si->lpMinimumApplicationAddress	= 0x40000000;
+    si->lpMaximumApplicationAddress	= 0x80000000;
+    si->dwActiveProcessorMask		= 1;
+    si->dwNumberOfProcessors		= 1;
 #ifdef WINELIB
-    si->dwProcessorType             = 3;
+    /* FIXME: perhaps check compilation defines ... */
+    si->dwProcessorType			= PROCESSOR_INTEL_386;
+    cpu = 3;
 #else
-    si->dwProcessorType             = runtime_cpu();
+    cpu = runtime_cpu();
+    switch (cpu) {
+    case 4: si->dwProcessorType		= PROCESSOR_INTEL_486;
+	    break;
+    case 5: si->dwProcessorType		= PROCESSOR_INTEL_PENTIUM;
+	    break;
+    case 3:
+    default: si->dwProcessorType	= PROCESSOR_INTEL_386;
+	    break;
+    }
 #endif
-    si->dwAllocationGranularity     = 8; /* hmm? */
+    si->dwAllocationGranularity		= 8; /* hmm? */
+    si->wProcessorLevel			= cpu;
+    si->wProcessorRevision		= 0; /* FIXME, see SDK */
 }
 
 /* Initialize whatever internal data structures we need.
@@ -122,3 +167,63 @@
 #endif
     return 1;
 }
+
+/***********************************************************************
+ *              GetComputerNameA         (KERNEL32.165)
+ */
+BOOL32
+GetComputerName32A(LPSTR name,LPDWORD size) {
+	if (-1==gethostname(name,*size))
+		return FALSE;
+	*size = lstrlen32A(name);
+	return TRUE;
+}
+
+/***********************************************************************
+ *              GetComputerNameW         (KERNEL32.166)
+ */
+BOOL32
+GetComputerName32W(LPWSTR name,LPDWORD size) {
+	LPSTR	nameA = (LPSTR)xmalloc(*size);
+
+	if (!GetComputerName32A(nameA,size)) {
+		free(nameA);
+		return FALSE;
+	}
+	lstrcpynAtoW(name,nameA,*size);
+	free(nameA);
+	/* FIXME : size correct? */
+	return TRUE;
+}
+
+/***********************************************************************
+ *           GetUserNameA   [ADVAPI32.67]
+ */
+BOOL32 GetUserName32A(LPSTR lpszName, LPDWORD lpSize)
+{
+  size_t len;
+  char *name;
+
+  name=getlogin();
+  len = name ? strlen(name) : 0;
+  if (!len || !lpSize || len > *lpSize) {
+    if (lpszName) *lpszName = 0;
+    return 0;
+  }
+  *lpSize=len;
+  strcpy(lpszName, name);
+  return 1;
+}
+
+/***********************************************************************
+ *           GetUserNameW   [ADVAPI32.68]
+ */
+BOOL32 GetUserName32W(LPWSTR lpszName, LPDWORD lpSize)
+{
+	LPSTR name = (LPSTR)xmalloc(*lpSize);
+	DWORD	size = *lpSize;
+	BOOL32 res = GetUserName32A(name,lpSize);
+
+	lstrcpynAtoW(lpszName,name,size);
+	return res;
+}
diff --git a/win32/newfns.c b/win32/newfns.c
index 29f779f..cab11b9 100644
--- a/win32/newfns.c
+++ b/win32/newfns.c
@@ -33,3 +33,20 @@
 	counter->HighPart	= 0;
 	return TRUE;
 }
+
+DWORD
+GetWindowThreadProcessId(HWND32 hwnd,LPDWORD processid) {
+	fprintf(stdnimp,"GetWindowThreadProcessId(%04lx,%p),stub\n",hwnd,processid);
+	return 0;
+}
+
+/****************************************************************************
+ *		DisableThreadLibraryCalls (KERNEL32.74)
+ */
+BOOL32
+DisableThreadLibraryCalls(HMODULE32 hModule) {
+	/* FIXME: stub for now */
+    fprintf(stdnimp, "DisableThreadLibraryCalls Stub called!\n");
+    return TRUE;
+}
+
diff --git a/win32/process.c b/win32/process.c
index 30c23f4..50a0283 100644
--- a/win32/process.c
+++ b/win32/process.c
@@ -100,7 +100,7 @@
  * copied from LoadLibrary
  * This does not currently support built-in libraries
  */
-HINSTANCE32 LoadLibraryA(char *libname)
+HINSTANCE32 LoadLibrary32A(LPCSTR libname)
 {
 	HINSTANCE32 handle;
 	dprintf_module( stddeb, "LoadLibrary: (%08x) %s\n", (int)libname, libname);
@@ -120,6 +120,20 @@
 }
 
 /***********************************************************************
+ *           LoadLibrary32W         (KERNEL32.368)
+ */
+HINSTANCE32 LoadLibrary32W(LPCWSTR libnameW)
+{
+	LPSTR libnameA = STRING32_DupUniToAnsi(libnameW);
+	HINSTANCE32 ret;
+
+	ret = LoadLibrary32A(libnameA);
+	free(libnameA);
+	return ret;
+
+}
+
+/***********************************************************************
  *           FreeLibrary
  */
 BOOL FreeLibrary32(HINSTANCE32 hLibModule)
diff --git a/win32/user32.c b/win32/user32.c
index afb5bce..3880aeb 100644
--- a/win32/user32.c
+++ b/win32/user32.c
@@ -46,6 +46,16 @@
 }
 
 /***********************************************************************
+ *          IsDialogMessage32W     (USER32.342)
+ */
+BOOL IsDialogMessage32W(DWORD hwnd, MSG32* lpmsg)
+{
+	MSG16 msg;
+	STRUCT32_MSG32to16(lpmsg, &msg);
+	return IsDialogMessage(hwnd, &msg);
+}
+
+/***********************************************************************
  *         DispatchMessageA       (USER32.140)
  */
 LONG USER32_DispatchMessageA(MSG32* lpmsg)
diff --git a/windows/dce.c b/windows/dce.c
index 1f03832..98bbe81 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -39,7 +39,7 @@
 {
     DCE * dce;
     if (!(dce = HeapAlloc( SystemHeap, 0, sizeof(DCE) ))) return NULL;
-    if (!(dce->hDC = CreateDC( "DISPLAY", NULL, NULL, NULL )))
+    if (!(dce->hDC = CreateDC16( "DISPLAY", NULL, NULL, NULL )))
     {
         HeapFree( SystemHeap, 0, dce );
 	return 0;
diff --git a/windows/defdlg.c b/windows/defdlg.c
index 99e2a1f..2c6e1e9 100644
--- a/windows/defdlg.c
+++ b/windows/defdlg.c
@@ -118,9 +118,6 @@
 
     switch(msg)
     {
-	case WM_INITDIALOG:
-	    return 0;
-
         case WM_ERASEBKGND:
 	    FillWindow( hwnd, hwnd, (HDC16)wParam, (HBRUSH16)CTLCOLOR_DLG );
 	    return 1;
@@ -152,6 +149,7 @@
             /* Delete window procedure */
             WINPROC_FreeProc( dlgInfo->dlgProc );
             dlgInfo->dlgProc = (HWINDOWPROC)0;
+	    dlgInfo->fEnd    = TRUE;	/* just in case */
 
 	      /* Window clean-up */
 	    return DefWindowProc32A( hwnd, msg, wParam, lParam );
@@ -194,6 +192,9 @@
             }
             return 0;
 
+	case WM_GETFONT: 
+	    return dlgInfo->hUserFont;
+
         case WM_CLOSE:
             EndDialog( hwnd, TRUE );
             DestroyWindow( hwnd );
@@ -202,6 +203,21 @@
     return 0;
 }
 
+/***********************************************************************
+ *           DEFDLG_Signoff
+ */
+static LRESULT DEFDLG_Signoff(DIALOGINFO* dlgInfo, UINT32 msg, BOOL16 fResult)
+{
+    /* see SDK 3.1 */
+
+    if ((msg >= WM_CTLCOLORMSGBOX && msg <= WM_CTLCOLORSTATIC) ||
+	 msg == WM_CTLCOLOR || msg == WM_COMPAREITEM ||
+         msg == WM_VKEYTOITEM || msg == WM_CHARTOITEM ||
+         msg == WM_QUERYDRAGICON || msg == WM_INITDIALOG)
+        return fResult; 
+
+    return dlgInfo->msgResult;
+}
 
 /***********************************************************************
  *           DefDlgProc16   (USER.308)
@@ -214,38 +230,43 @@
     
     if (!wndPtr) return 0;
     dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
-
     dlgInfo->msgResult = 0;
-    if (dlgInfo->dlgProc)
-    {
-	  /* Call dialog procedure */
+
+    if (dlgInfo->dlgProc) 	/* Call dialog procedure */
 	result = (BOOL16)CallWindowProc16( (WNDPROC16)dlgInfo->dlgProc,
                                            hwnd, msg, wParam, lParam );
 
-        /* Check if window was destroyed by dialog procedure */
+    /* Check if window was destroyed by dialog procedure */
 
-	if (!IsWindow( hwnd )) return result;
-	else if( result ) return dlgInfo->msgResult;
-    }
-    
-    switch(msg)
+    if( !result && IsWindow(hwnd))
     {
-	case WM_INITDIALOG:
-        case WM_ERASEBKGND:
-	case WM_NCDESTROY:
-	case WM_SHOWWINDOW:
-	case WM_ACTIVATE:
-	case WM_SETFOCUS:
-        case DM_SETDEFID:
-        case DM_GETDEFID:
-	case WM_NEXTDLGCTL:
-        case WM_CLOSE:
-            return DEFDLG_Proc( (HWND32)hwnd, msg, (WPARAM32)wParam,
-                                lParam, dlgInfo );
+        /* callback didn't process this message */
 
-	default:
-	    return DefWindowProc16( hwnd, msg, wParam, lParam );
-    }
+        switch(msg)
+        {
+            case WM_ERASEBKGND:
+            case WM_SHOWWINDOW:
+            case WM_ACTIVATE:
+            case WM_SETFOCUS:
+            case DM_SETDEFID:
+            case DM_GETDEFID:
+            case WM_NEXTDLGCTL:
+            case WM_GETFONT:
+            case WM_CLOSE:
+            case WM_NCDESTROY:
+                return DEFDLG_Proc( (HWND32)hwnd, msg, 
+                                    (WPARAM32)wParam, lParam, dlgInfo );
+            case WM_INITDIALOG:
+            case WM_VKEYTOITEM:
+            case WM_COMPAREITEM:
+            case WM_CHARTOITEM:
+                break;
+
+            default:
+                return DefWindowProc16( hwnd, msg, wParam, lParam );
+        }
+    }   
+    return DEFDLG_Signoff(dlgInfo, msg, result);
 }
 
 
@@ -260,37 +281,43 @@
     
     if (!wndPtr) return 0;
     dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
-
     dlgInfo->msgResult = 0;
-    if (dlgInfo->dlgProc)
-    {
-	  /* Call dialog procedure */
-	result = (BOOL16)CallWindowProc32A( (WNDPROC32)dlgInfo->dlgProc,
+
+    if (dlgInfo->dlgProc)       /* Call dialog procedure */
+        result = (BOOL16)CallWindowProc32A( (WNDPROC32)dlgInfo->dlgProc,
                                             hwnd, msg, wParam, lParam );
 
-        /* Check if window was destroyed by dialog procedure */
+    /* Check if window was destroyed by dialog procedure */
 
-        if (!IsWindow( hwnd )) return result;
-        else if( result ) return dlgInfo->msgResult;
-    }
-    
-    switch(msg)
+    if( !result && IsWindow(hwnd))
     {
-	case WM_INITDIALOG:
-        case WM_ERASEBKGND:
-	case WM_NCDESTROY:
-	case WM_SHOWWINDOW:
-	case WM_ACTIVATE:
-	case WM_SETFOCUS:
-        case DM_SETDEFID:
-        case DM_GETDEFID:
-	case WM_NEXTDLGCTL:
-        case WM_CLOSE:
-            return DEFDLG_Proc( hwnd, msg, wParam, lParam, dlgInfo );
+        /* callback didn't process this message */
 
-	default:
-	    return DefWindowProc32A( hwnd, msg, wParam, lParam );
+        switch(msg)
+        {
+            case WM_ERASEBKGND:
+            case WM_SHOWWINDOW:
+            case WM_ACTIVATE:
+            case WM_SETFOCUS:
+            case DM_SETDEFID:
+            case DM_GETDEFID:
+            case WM_NEXTDLGCTL:
+            case WM_GETFONT:
+            case WM_CLOSE:
+            case WM_NCDESTROY:
+                 return DEFDLG_Proc( (HWND32)hwnd, msg,
+                                     (WPARAM32)wParam, lParam, dlgInfo );
+            case WM_INITDIALOG:
+            case WM_VKEYTOITEM:
+            case WM_COMPAREITEM:
+            case WM_CHARTOITEM:
+                 break;
+
+            default:
+                 return DefWindowProc32A( hwnd, msg, wParam, lParam );
+        }
     }
+    return DEFDLG_Signoff(dlgInfo, msg, result);
 }
 
 
@@ -305,35 +332,41 @@
     
     if (!wndPtr) return 0;
     dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
-
     dlgInfo->msgResult = 0;
-    if (dlgInfo->dlgProc)
-    {
-	  /* Call dialog procedure */
-	result = (BOOL16)CallWindowProc32W( (WNDPROC32)dlgInfo->dlgProc,
+
+    if (dlgInfo->dlgProc)       /* Call dialog procedure */
+        result = (BOOL16)CallWindowProc32W( (WNDPROC32)dlgInfo->dlgProc,
                                             hwnd, msg, wParam, lParam );
 
-        /* Check if window was destroyed by dialog procedure */
+    /* Check if window was destroyed by dialog procedure */
 
-        if (!IsWindow( hwnd )) return result;
-        else if( result ) return dlgInfo->msgResult;
-    }
-    
-    switch(msg)
+    if( !result && IsWindow(hwnd))
     {
-	case WM_INITDIALOG:
-        case WM_ERASEBKGND:
-	case WM_NCDESTROY:
-	case WM_SHOWWINDOW:
-	case WM_ACTIVATE:
-	case WM_SETFOCUS:
-        case DM_SETDEFID:
-        case DM_GETDEFID:
-	case WM_NEXTDLGCTL:
-        case WM_CLOSE:
-            return DEFDLG_Proc( hwnd, msg, wParam, lParam, dlgInfo );
+        /* callback didn't process this message */
 
-	default:
-	    return DefWindowProc32W( hwnd, msg, wParam, lParam );
+        switch(msg)
+        {
+            case WM_ERASEBKGND:
+            case WM_SHOWWINDOW:
+            case WM_ACTIVATE:
+            case WM_SETFOCUS:
+            case DM_SETDEFID:
+            case DM_GETDEFID:
+            case WM_NEXTDLGCTL:
+            case WM_GETFONT:
+            case WM_CLOSE:
+            case WM_NCDESTROY:
+                 return DEFDLG_Proc( (HWND32)hwnd, msg,
+                                     (WPARAM32)wParam, lParam, dlgInfo );
+            case WM_INITDIALOG:
+            case WM_VKEYTOITEM:
+            case WM_COMPAREITEM:
+            case WM_CHARTOITEM:
+                 break;
+
+            default:
+                 return DefWindowProc32W( hwnd, msg, wParam, lParam );
+        }
     }
+    return DEFDLG_Signoff(dlgInfo, msg, result);
 }
diff --git a/windows/defwnd.c b/windows/defwnd.c
index b201881..8b0da40 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -63,7 +63,11 @@
     if (!text) text = "";
     if (wndPtr->text) HeapFree( SystemHeap, 0, wndPtr->text );
     wndPtr->text = HEAP_strdupA( SystemHeap, 0, text );
-    if (wndPtr->window) XStoreName( display, wndPtr->window, wndPtr->text );
+    if (wndPtr->window)
+    {
+	XStoreName( display, wndPtr->window, wndPtr->text );
+	XSetIconName( display, wndPtr->window, wndPtr->text );
+    }
 }
 
 
diff --git a/windows/dialog.c b/windows/dialog.c
index e1b0946..864495f 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -71,7 +71,7 @@
     
       /* Calculate the dialog base units */
 
-    if (!(hdc = CreateDC( "DISPLAY", NULL, NULL, NULL ))) return FALSE;
+    if (!(hdc = CreateDC16( "DISPLAY", NULL, NULL, NULL ))) return FALSE;
     GetTextMetrics16( hdc, &tm );
     DeleteDC( hdc );
     xBaseUnit = tm.tmAveCharWidth;
@@ -79,7 +79,8 @@
 
       /* Dialog units are based on a proportional system font */
       /* so we adjust them a bit for a fixed font. */
-    if (tm.tmPitchAndFamily & TMPF_FIXED_PITCH) xBaseUnit = xBaseUnit * 5 / 4;
+    if (!(tm.tmPitchAndFamily & TMPF_FIXED_PITCH))
+        xBaseUnit = xBaseUnit * 5 / 4;
 
     dprintf_dialog( stddeb, "DIALOG_Init: base units = %d,%d\n",
                     xBaseUnit, yBaseUnit );
@@ -511,7 +512,7 @@
 	    ReleaseDC32( 0, hdc );
 	    xUnit = tm.tmAveCharWidth;
 	    yUnit = tm.tmHeight;
-            if (tm.tmPitchAndFamily & TMPF_FIXED_PITCH)
+            if (!(tm.tmPitchAndFamily & TMPF_FIXED_PITCH))
                 xBaseUnit = xBaseUnit * 5 / 4;  /* See DIALOG_Init() */
 	}
     }
diff --git a/windows/graphics.c b/windows/graphics.c
index 5003f17..9aedf97 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -969,13 +969,43 @@
 
 
 /**********************************************************************
+ *          Polyline32   (GDI32.276)
+ */
+BOOL32 Polyline32( HDC32 hdc, const LPPOINT32 pt, INT32 count )
+{
+    register int i;
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) 
+    {
+	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
+	if (!dc) return FALSE;
+        fprintf( stderr, "Polyline32: Metafile Polyline not yet supported for Win32\n");
+/* win 16 code was:
+	MF_MetaPoly(dc, META_POLYLINE, pt, count); 
+	return TRUE;
+*/
+	return FALSE;
+    }
+
+    if (DC_SetupGCForPen( dc ))
+	for (i = 0; i < count-1; i ++)
+	    XDrawLine (display, dc->u.x.drawable, dc->u.x.gc,  
+		       dc->w.DCOrgX + XLPTODP(dc, pt [i].x),
+		       dc->w.DCOrgY + YLPTODP(dc, pt [i].y),
+		       dc->w.DCOrgX + XLPTODP(dc, pt [i+1].x),
+		       dc->w.DCOrgY + YLPTODP(dc, pt [i+1].y));
+    return TRUE;
+}
+
+
+/**********************************************************************
  *          Polygon16  (GDI.36)
  */
 BOOL16 Polygon16( HDC16 hdc, LPPOINT16 pt, INT16 count )
 {
     register int i;
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    XPoint *points = (XPoint *) xmalloc (sizeof (XPoint) * (count+1));
+    XPoint *points;
 
     if (!dc) 
     {
@@ -985,6 +1015,50 @@
 	return TRUE;
     }
 
+    points = (XPoint *) xmalloc (sizeof (XPoint) * (count+1));
+    for (i = 0; i < count; i++)
+    {
+	points[i].x = dc->w.DCOrgX + XLPTODP( dc, pt[i].x );
+	points[i].y = dc->w.DCOrgY + YLPTODP( dc, pt[i].y );
+    }
+    points[count] = points[0];
+
+    if (DC_SetupGCForBrush( dc ))
+	XFillPolygon( display, dc->u.x.drawable, dc->u.x.gc,
+		     points, count+1, Complex, CoordModeOrigin);
+
+    if (DC_SetupGCForPen ( dc ))
+	XDrawLines( display, dc->u.x.drawable, dc->u.x.gc,
+		   points, count+1, CoordModeOrigin );
+
+    free( points );
+    return TRUE;
+}
+
+
+/**********************************************************************
+ *          Polygon32  (GDI32.275)
+ *
+ * This a copy of Polygon16 so that conversion of array of
+ * LPPOINT32 to LPPOINT16 is not necessary
+ *
+ */
+BOOL32 Polygon32( HDC32 hdc, LPPOINT32 pt, INT32 count )
+{
+    register int i;
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    XPoint *points;
+
+    if (!dc)
+    {
+	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
+	if (!dc) return FALSE;
+	/* FIXME: MF_MetaPoly expects LPPOINT16 not 32 */
+	/* MF_MetaPoly(dc, META_POLYGON, pt, count); */
+	return TRUE;
+    }
+
+    points = (XPoint *) xmalloc (sizeof (XPoint) * (count+1));
     for (i = 0; i < count; i++)
     {
 	points[i].x = dc->w.DCOrgX + XLPTODP( dc, pt[i].x );
diff --git a/windows/keyboard.c b/windows/keyboard.c
index 10e3ed0..0342cb9 100644
--- a/windows/keyboard.c
+++ b/windows/keyboard.c
@@ -2,11 +2,14 @@
  * Keyboard related functions
  *
  * Copyright 1993 Bob Amstadt
+ * Copyright 1996 Albrecht Kleine 
  */
+
 #include <stdio.h>
 #include <string.h>
 #include "win.h"
 #include "windows.h"
+#include "accel.h"
 #include "debug.h"
 
 extern BOOL MouseButtonsStates[3];
@@ -115,3 +118,147 @@
     dprintf_key(stddeb, "GetAsyncKeyState(%x) -> %x\n", nKey, retval);
     return retval;
 }
+
+
+/**********************************************************************
+ *			TranslateAccelerator 	[USER.178]
+ *
+ * FIXME: should send some WM_INITMENU or/and WM_INITMENUPOPUP  -messages
+ */
+INT16 TranslateAccelerator(HWND hWnd, HACCEL16 hAccel, LPMSG16 msg)
+{
+    ACCELHEADER	*lpAccelTbl;
+    int 	i;
+    BOOL sendmsg;
+    
+    if (hAccel == 0 || msg == NULL) return 0;
+    if (msg->message != WM_KEYDOWN &&
+    	msg->message != WM_KEYUP &&
+	msg->message != WM_SYSKEYDOWN &&
+	msg->message != WM_SYSKEYUP &&
+    	msg->message != WM_CHAR) return 0;
+
+    dprintf_accel(stddeb, "TranslateAccelerators hAccel=%04x, hWnd=%04x,\
+msg->hwnd=%04x, msg->message=%04x\n", hAccel,hWnd,msg->hwnd,msg->message);
+
+    lpAccelTbl = (LPACCELHEADER)GlobalLock16(hAccel);
+    for (sendmsg= i = 0; i < lpAccelTbl->wCount; i++) 
+    {
+     if(msg->wParam == lpAccelTbl->tbl[i].wEvent) 
+     {
+      if (msg->message == WM_CHAR) 
+      {
+        if ( !(lpAccelTbl->tbl[i].type & ALT_ACCEL) && 
+             !(lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) )
+        {
+   	  dprintf_accel(stddeb,"found accel for WM_CHAR: ('%c')",msg->wParam&0xff);
+   	  sendmsg=TRUE;
+   	}  
+      }
+      else
+      {
+       if(lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) 
+       {
+	INT mask = 0;
+        dprintf_accel(stddeb,"found accel for virt_key %04x (scan %04x)",
+  	                       msg->wParam,0xff & HIWORD(msg->lParam));                
+	if(GetKeyState(VK_SHIFT) & 0x8000) mask |= SHIFT_ACCEL;
+	if(GetKeyState(VK_CONTROL) & 0x8000) mask |= CONTROL_ACCEL;
+	if(GetKeyState(VK_MENU) & 0x8000) mask |= ALT_ACCEL;
+	if(mask == (lpAccelTbl->tbl[i].type &
+			    (SHIFT_ACCEL | CONTROL_ACCEL | ALT_ACCEL)))
+          sendmsg=TRUE;			    
+        else
+          dprintf_accel(stddeb,", but incorrect SHIFT/CTRL/ALT-state\n");
+       }
+       else
+       {
+         if (!(msg->lParam & 0x01000000))  /* no special_key */
+         {
+           if ((lpAccelTbl->tbl[i].type & ALT_ACCEL) && (msg->lParam & 0x20000000))
+           {                                                   /* ^^ ALT pressed */
+	    dprintf_accel(stddeb,"found accel for Alt-%c", msg->wParam&0xff);
+	    sendmsg=TRUE;	    
+	   } 
+         } 
+       }
+      } 
+
+      if (sendmsg)      /* found an accelerator, but send a message... ? */
+      {
+        INT16  iSysStat,iStat,mesg=0;
+        HMENU16 hSysMenu,hMenu;
+        
+        if (msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP)
+          mesg=1;
+        else 
+         if (GetCapture16())
+           mesg=2;
+         else
+          if (!IsWindowEnabled(hWnd))
+            mesg=3;
+          else
+          {
+            hMenu=GetMenu(hWnd);
+            hSysMenu=GetSystemMenu(hWnd,FALSE);
+            if (hSysMenu)
+              iSysStat=GetMenuState(hSysMenu,lpAccelTbl->tbl[i].wIDval,MF_BYCOMMAND);
+            else
+              iSysStat=-1;
+            if (hMenu)
+              iStat=GetMenuState(hMenu,lpAccelTbl->tbl[i].wIDval,MF_BYCOMMAND);
+            else
+              iStat=-1;
+            if (iSysStat!=-1)
+            {
+              if (iSysStat & (MF_DISABLED|MF_GRAYED))
+                mesg=4;
+              else
+                mesg=WM_SYSCOMMAND;
+            }
+            else
+            {
+              if (iStat!=-1)
+              {
+                if (IsIconic(hWnd))
+                  mesg=5;
+                else
+                {
+                 if (iStat & (MF_DISABLED|MF_GRAYED))
+                   mesg=6;
+                 else
+                   mesg=WM_COMMAND;  
+                }   
+              }
+              else
+               mesg=WM_COMMAND;  
+            }
+          }
+          if ( mesg==WM_COMMAND || mesg==WM_SYSCOMMAND )
+          {
+              dprintf_accel(stddeb,", sending %s, wParam=%0x\n",
+                  mesg==WM_COMMAND ? "WM_COMMAND" : "WM_SYSCOMMAND",
+                  lpAccelTbl->tbl[i].wIDval);
+	      SendMessage16(hWnd, mesg, lpAccelTbl->tbl[i].wIDval,0x00010000L);
+	  }
+	  else
+	  {
+	   /*  some reasons for NOT sending the WM_{SYS}COMMAND message: 
+	    *   #0: unknown (please report!)
+	    *   #1: for WM_KEYUP,WM_SYKEYUP
+	    *   #2: mouse is captured
+	    *   #3: window is disabled 
+	    *   #4: it's a disabled system menu option
+	    *   #5: it's a menu option, but window is iconic
+	    *   #6: it's a menu option, but disabled
+	    */
+	    dprintf_accel(stddeb,", but won't send WM_{SYS}COMMAND, reason is #%d\n",mesg);
+	  }          
+          GlobalUnlock16(hAccel);
+          return 1;         
+      }
+     }
+    }
+    GlobalUnlock16(hAccel);
+    return 0;
+}
diff --git a/windows/message.c b/windows/message.c
index 05f8ad5..07e4722 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -524,8 +524,10 @@
 
       dprintf_sendmsg(stddeb,"%*ssm: smResult = %08x\n", prevSMRL, "", (unsigned)queue->smResult );
 
-      queue->smResult->lResult = queue->SendMessageReturn;
-      queue->smResult->bPending = FALSE;
+      if (queue->smResult) { /* FIXME, smResult should always be set */
+        queue->smResult->lResult = queue->SendMessageReturn;
+        queue->smResult->bPending = FALSE;
+      }
       queue->wakeBits &= ~QS_SMRESULT;
 
       if( queue->smResult != &qCtrl )
@@ -637,7 +639,7 @@
             msg->message = WM_QUIT;
             msg->wParam  = msgQueue->wExitCode;
             msg->lParam  = 0;
-            if( !peek ) msgQueue->wPostQMsg = 0;
+            if (flags & PM_REMOVE) msgQueue->wPostQMsg = 0;
             break;
         }
     
@@ -902,6 +904,7 @@
 LRESULT SendMessage16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam)
 {
     WND * wndPtr;
+    WND **list, **ppWnd;
     LRESULT ret;
 
 #ifdef CONFIG_IPC
@@ -912,8 +915,11 @@
     if (hwnd == HWND_BROADCAST16)
     {
         dprintf_msg(stddeb,"SendMessage // HWND_BROADCAST !\n");
-        for (wndPtr = WIN_GetDesktop()->child; wndPtr; wndPtr = wndPtr->next)
+        list = WIN_BuildWinArray( WIN_GetDesktop() );
+        for (ppWnd = list; *ppWnd; ppWnd++)
         {
+            wndPtr = *ppWnd;
+            if (!IsWindow(wndPtr->hwndSelf)) continue;
             if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION)
             {
                 dprintf_msg(stddeb,"BROADCAST Message to hWnd=%04x m=%04X w=%04lX l=%08lX !\n",
@@ -921,6 +927,7 @@
                 SendMessage16( wndPtr->hwndSelf, msg, wParam, lParam );
 	    }
         }
+	HeapFree( SystemHeap, 0, list );
         dprintf_msg(stddeb,"SendMessage // End of HWND_BROADCAST !\n");
         return TRUE;
     }
@@ -975,16 +982,20 @@
 LRESULT SendMessage32A(HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
 {
     WND * wndPtr;
+    WND **list, **ppWnd;
     LRESULT ret;
 
     if (hwnd == HWND_BROADCAST32)
     {
-        for (wndPtr = WIN_GetDesktop()->child; wndPtr; wndPtr = wndPtr->next)
+        list = WIN_BuildWinArray( WIN_GetDesktop() );
+        for (ppWnd = list; *ppWnd; ppWnd++)
         {
-            /* FIXME: should use something like EnumWindows here */
+            wndPtr = *ppWnd;
+            if (!IsWindow(wndPtr->hwndSelf)) continue;
             if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION)
                 SendMessage32A( wndPtr->hwndSelf, msg, wParam, lParam );
         }
+	HeapFree( SystemHeap, 0, list );
         return TRUE;
     }
 
@@ -1031,16 +1042,20 @@
 LRESULT SendMessage32W(HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
 {
     WND * wndPtr;
+    WND **list, **ppWnd;
     LRESULT ret;
 
     if (hwnd == HWND_BROADCAST32)
     {
-        for (wndPtr = WIN_GetDesktop()->child; wndPtr; wndPtr = wndPtr->next)
+        list = WIN_BuildWinArray( WIN_GetDesktop() );
+        for (ppWnd = list; *ppWnd; ppWnd++)
         {
-            /* FIXME: should use something like EnumWindows here */
+            wndPtr = *ppWnd;
+            if (!IsWindow(wndPtr->hwndSelf)) continue;
             if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION)
                 SendMessage32W( wndPtr->hwndSelf, msg, wParam, lParam );
         }
+	HeapFree( SystemHeap, 0, list );
         return TRUE;
     }
 
diff --git a/windows/msgbox.c b/windows/msgbox.c
index 8795b8e..6cfb59f 100644
--- a/windows/msgbox.c
+++ b/windows/msgbox.c
@@ -5,12 +5,15 @@
  *
  */
 
+#include <stdio.h>
+#include <malloc.h>
 #include "windows.h"
 #include "dlgs.h"
 #include "module.h"
 #include "win.h"
 #include "resource.h"
 #include "task.h"
+#include "string32.h"
 
 typedef struct {
   LPCSTR title;
@@ -171,10 +174,17 @@
 }
 
 /**************************************************************************
- *			MessageBox  [USER.1]
+ *           MessageBox16   (USER.1)
  */
+INT16 MessageBox16( HWND16 hwnd, LPCSTR text, LPCSTR title, UINT16 type )
+{
+    return MessageBox32A( hwnd, text, title, type );
+}
 
-int MessageBox(HWND hWnd, LPCSTR text, LPCSTR title, WORD type)
+/**************************************************************************
+ *           MessageBox32A   (USER32.390)
+ */
+INT32 MessageBox32A( HWND32 hWnd, LPCSTR text, LPCSTR title, UINT32 type )
 {
     HANDLE16 handle;
     MSGBOX mbox;
@@ -195,11 +205,37 @@
 }
 
 /**************************************************************************
+ *           MessageBox32W   (USER32.395)
+ */
+INT32 MessageBox32W( HWND32 hWnd, LPCWSTR text, LPCWSTR title, UINT32 type )
+{
+    HANDLE16 handle;
+    MSGBOX mbox;
+    int ret;
+
+    mbox.title = title?STRING32_DupUniToAnsi(title):NULL;
+    mbox.text  = text?STRING32_DupUniToAnsi(text):NULL;
+    mbox.type  = type;
+
+    fprintf(stderr,"MessageBox(%s,%s)\n",mbox.text,mbox.title);
+    handle = SYSRES_LoadResource( SYSRES_DIALOG_MSGBOX );
+    if (!handle) return 0;
+    ret = DialogBoxIndirectParam16( WIN_GetWindowInstance(hWnd),
+                                  handle, hWnd,
+                                  MODULE_GetWndProcEntry16("SystemMessageBoxProc"),
+                                  (LONG)&mbox );
+    SYSRES_FreeResource( handle );
+    if (title) free(mbox.title);
+    if (text) free(mbox.text);
+    return ret;
+}
+
+/**************************************************************************
  *			FatalAppExit  [USER.137]
  */
 
 void FatalAppExit(UINT fuAction, LPCSTR str)
 {
-  MessageBox(0, str, NULL, MB_SYSTEMMODAL | MB_OK);
+  MessageBox16(0, str, NULL, MB_SYSTEMMODAL | MB_OK);
   TASK_KillCurrentTask(0);
 }
diff --git a/windows/painting.c b/windows/painting.c
index 43af442..e3dfda3 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -11,6 +11,7 @@
 #include "queue.h"
 #include "gdi.h"
 #include "dce.h"
+#include "heap.h"
 #include "stddebug.h"
 /* #define DEBUG_WIN */
 #include "debug.h"
@@ -251,6 +252,7 @@
     HRGN32 hrgn;
     RECT32 rectClient;
     WND* wndPtr;
+    WND **list, **ppWnd;
 
     if (!hwnd) hwnd = GetDesktopWindow32();
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
@@ -399,16 +401,20 @@
 	{
 	   if (!(hrgn = CreateRectRgn32( 0, 0, 0, 0 ))) return TRUE;
 	   if( !hrgnUpdate )
-	     {
+           {
 	        control |= (RDW_C_DELETEHRGN | RDW_C_USEHRGN);
  	        if( !(hrgnUpdate = CreateRectRgnIndirect32( rectUpdate )) )
                 {
                     DeleteObject32( hrgn );
                     return TRUE;
                 }
-	     }
-           for (wndPtr = wndPtr->child; wndPtr; wndPtr = wndPtr->next)
-	     if( wndPtr->dwStyle & WS_VISIBLE )
+           }
+           list = WIN_BuildWinArray( wndPtr );
+           for (ppWnd = list; *ppWnd; ppWnd++)
+           {
+               wndPtr = *ppWnd;
+               if (!IsWindow(wndPtr->hwndSelf)) continue;
+               if (wndPtr->dwStyle & WS_VISIBLE)
 	       {
                    SetRectRgn( hrgn, wndPtr->rectWindow.left,
                                wndPtr->rectWindow.top,
@@ -421,11 +427,22 @@
                    PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, hrgn, flags,
                                        RDW_C_USEHRGN );
                }
+	   }
+	   HeapFree( SystemHeap, 0, list );
 	   DeleteObject32( hrgn );
 	   if (control & RDW_C_DELETEHRGN) DeleteObject32( hrgnUpdate );
 	}
-	else for (wndPtr = wndPtr->child; wndPtr; wndPtr = wndPtr->next)
-		  PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, 0, flags, 0 );
+        else
+        {
+           list = WIN_BuildWinArray( wndPtr );
+           for (ppWnd = list; *ppWnd; ppWnd++)
+           {
+               wndPtr = *ppWnd;
+               if (IsWindow( wndPtr->hwndSelf ))
+                   PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, 0, flags, 0 );
+	   }
+	   HeapFree( SystemHeap, 0, list );
+	}
 
     }
     return TRUE;
diff --git a/windows/win.c b/windows/win.c
index 56cfa04..05f52b8 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -1607,15 +1607,31 @@
 
 
 /*******************************************************************
- *         GetWindowTextLength    (USER.38)
+ *         GetWindowTextLength16    (USER.38)
  */
-int GetWindowTextLength(HWND hwnd)
+INT16 GetWindowTextLength16( HWND16 hwnd )
 {
-    return (int)SendMessage16(hwnd, WM_GETTEXTLENGTH, 0, 0 );
+    return (INT16)SendMessage16( hwnd, WM_GETTEXTLENGTH, 0, 0 );
 }
 
 
 /*******************************************************************
+ *         GetWindowTextLength32A   (USER32.309)
+ */
+INT32 GetWindowTextLength32A( HWND32 hwnd )
+{
+    return SendMessage32A( hwnd, WM_GETTEXTLENGTH, 0, 0 );
+}
+
+/*******************************************************************
+ *         GetWindowTextLength32W   (USER32.309)
+ */
+INT32 GetWindowTextLength32W( HWND32 hwnd )
+{
+    return SendMessage32W( hwnd, WM_GETTEXTLENGTH, 0, 0 );
+}
+
+/*******************************************************************
  *         IsWindow   (USER.47) (USER32.347)
  */
 BOOL16 IsWindow( HWND32 hwnd )